Skip to content

Python: Fix Bedrock Cohere embeddings when embedding_types is set - #14678

Open
alexcastgonz (pcbeingused333) wants to merge 2 commits into
microsoft:mainfrom
pcbeingused333:fix/bedrock-cohere-embedding-types
Open

alexcastgonz (pcbeingused333) wants to merge 2 commits into
microsoft:mainfrom
pcbeingused333:fix/bedrock-cohere-embedding-types

Conversation

@pcbeingused333

Copy link
Copy Markdown
Contributor

Motivation and Context

BedrockTextEmbedding accepts the Cohere embedding_types option and forwards it in the request body. With it set, Cohere on Bedrock returns the embeddings keyed by type ({"embeddings": {"float": [[...]], "int8": [[...]]}}) instead of a plain list of vectors, and parse_text_embedding_response only accepted a list, so the call failed with ServiceInvalidResponseError: The response from Cohere model does not contain embeddings. even though the request succeeded.

Description

parse_text_embedding_response in bedrock_cohere.py now also accepts the keyed form: it returns the float embedding when that type is present, otherwise the first type in the response. The plain list form and the error for missing or malformed embeddings are unchanged.

Tests (tests/unit/connectors/ai/bedrock/services/test_bedrock_text_embedding_generation.py): typed responses (float only, float plus int8, int8 only) and the plain list through generate_embeddings with embedding_types in the settings, and empty or malformed typed responses still raising ServiceInvalidResponseError. tests/unit/connectors/ai/bedrock: 123 passed; 3 of the new cases fail without the change. Not run against the real Bedrock API.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the SK Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • I didn't break anyone 😄

Disclosure: this change was prepared with an AI coding assistant (Claude) working for the account owner.

When embedding_types is set, Cohere on Bedrock returns the embeddings keyed by type
(a dict) instead of a list of vectors, and parse_text_embedding_response rejected it
with ServiceInvalidResponseError. Return the float embedding when present, otherwise
the first type in the response.
Copilot AI balanced review requested due to automatic review settings October 29, 2026 12:37
@semantic-kernel-automation semantic-kernel-automation Bot added the python Pull requests for the Python Semantic Kernel label Oct 29, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Typed embedding responses can accept malformed vectors or select inconsistent encodings across a batch, potentially causing dimension errors.

2 open issues
What changed in this PR

This PR extends the Python Bedrock Cohere embedding parser to handle responses keyed by embedding type, addressing failures when embedding_types is requested.

Changes:

  • Accept typed responses, preferring float and otherwise selecting the first returned type.
  • Preserve the existing plain-list response path.
  • Add tests for typed embeddings, request forwarding, and empty or malformed typed responses.
File Description
python/​tests/​unit/​connectors/​ai/​bedrock/​services/​test_bedrock_text_embedding_generation.py Adds successful and invalid typed-response test cases.
python/​semantic_kernel/​connectors/​ai/​bedrock/​services/​model_provider/​bedrock_cohere.py Adds extraction of embeddings from type-keyed responses.

Review effort: Balanced

if isinstance(embeddings, dict):
# With `embedding_types` set, the embeddings are keyed by type ({"float": [[...]], "int8": [[...]]}).
# Return the float embedding when it was requested, otherwise the first type in the response.
embeddings = embeddings.get("float") or next(iter(embeddings.values()), None)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed on the current revision. The parser returns 0.1 for {"float": [0.1, 0.2]}, [] for {"float": [[]]}, and [1, 2] for {"int8": [[1, 2]], "float": []}. These cases still need validation before this is ready.

if isinstance(embeddings, dict):
# With `embedding_types` set, the embeddings are keyed by type ({"float": [[...]], "int8": [[...]]}).
# Return the float embedding when it was requested, otherwise the first type in the response.
embeddings = embeddings.get("float") or next(iter(embeddings.values()), None)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed with the current parser: {"int8": [[1, 2]], "binary": [[1]]} returns [1, 2], while reversing those keys returns [1]. Identical requested embedding types can therefore produce different vector dimensions across texts. Selection needs a stable type policy rather than JSON object order.

…priority

Select float by key presence, fall back in a fixed priority (int8, uint8, binary, ubinary) independent of JSON key order, and raise ServiceInvalidResponseError when the selected value is not a non-empty numeric vector.
@pcbeingused333

Copy link
Copy Markdown
Contributor Author

Thanks, both points are addressed in cad9abe. With embedding_types set, the parser now picks the first type present in a fixed order (float, int8, uint8, binary, ubinary) instead of following the JSON key order, so float wins whenever its key is present. It then checks that the selected entry holds a non-empty numeric vector and raises ServiceInvalidResponseError otherwise. New test cases cover key-order independence and the invalid shapes (flat list, empty vector, non-numeric values, empty float next to int8, unknown type only). They fail on the previous commit, and the Bedrock unit suite passes.

This comment was drafted with Claude Code.

This branch was successfully deployed

1 active deployment
github-app-auth — cad9abe5 Deployed Nov 2, 2026 by pcbeingused333 via add_label #29537
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Pull requests for the Python Semantic Kernel

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants