Skip to content

Commit 64fe817

Browse files
Validate embedding_types elements before preserving them
The embedding_types merge only checked list-ness and non-emptiness, so a caller extra containing non-string elements (e.g. [{"x": 1}]) was preserved and would be sent as an invalid Cohere wire payload, contradicting the "malformed falls back to [float]" comment. Require a non-empty list of non-empty strings before preserving it; anything else falls back to ["float"].
1 parent f58f3a2 commit 64fe817

2 files changed

Lines changed: 10 additions & 2 deletions

File tree

src/openarmature/retrieval/providers/cohere.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -700,8 +700,12 @@ def _build_request_body(
700700
# only when a caller's embedding_types omits it (§8.4). A malformed /
701701
# empty embedding_types extra falls back to ["float"].
702702
caller_types = request_extras.get("embedding_types")
703-
if isinstance(caller_types, list) and caller_types:
704-
embedding_types = list(cast("list[Any]", caller_types))
703+
if (
704+
isinstance(caller_types, list)
705+
and caller_types
706+
and all(isinstance(t, str) and t for t in cast("list[object]", caller_types))
707+
):
708+
embedding_types = list(cast("list[str]", caller_types))
705709
if "float" not in embedding_types:
706710
embedding_types.append("float")
707711
else:

tests/unit/test_retrieval_provider.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,18 +1184,22 @@ def handler(req: httpx.Request) -> httpx.Response:
11841184

11851185
cfg_both = EmbeddingRuntimeConfig.model_validate({"embedding_types": ["float", "int8"]})
11861186
cfg_int8 = EmbeddingRuntimeConfig.model_validate({"embedding_types": ["int8"]})
1187+
cfg_bad = EmbeddingRuntimeConfig.model_validate({"embedding_types": [{"x": 1}]})
11871188
provider = _cohere_embed_provider(handler)
11881189
# Caller adds int8 alongside float -> both reach the wire (float NOT clobbered).
11891190
await provider.embed(["x"], config=cfg_both)
11901191
# Caller omits float -> "float" is appended (the mapping must read embeddings.float).
11911192
await provider.embed(["x"], config=cfg_int8)
11921193
# No embedding_types extra -> the ["float"] default.
11931194
await provider.embed(["x"])
1195+
# Malformed (non-string elements) -> falls back to ["float"], not sent verbatim.
1196+
await provider.embed(["x"], config=cfg_bad)
11941197
await provider.aclose()
11951198

11961199
assert captured[0]["embedding_types"] == ["float", "int8"]
11971200
assert captured[1]["embedding_types"] == ["int8", "float"]
11981201
assert captured[2]["embedding_types"] == ["float"]
1202+
assert captured[3]["embedding_types"] == ["float"]
11991203

12001204

12011205
async def test_cohere_embed_per_chunk_count_mismatch_raises_despite_matching_total() -> None:

0 commit comments

Comments
 (0)