You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adopt 0104 retrieval id/error and 0103 chunk cap (#256)
* Adopt 0104 retrieval id/error and 0103 chunk cap
0104: the Jina error mapping now maps a bare 400 to
provider_invalid_request instead of the transient provider_unavailable
catch-all, aligning it with the TEI / OpenAI / Cohere mappings and
avoiding a pointless retry of a request that will not succeed. Jina and
Cohere now fold an empty-string response_id to null, since an identifier
that correlates nothing is not a present one (extending 0100's
malformed-id rule to the empty string); the OpenAI embed mapping already
did this. Behavioral at these two edges only; well-formed responses and
non-400 errors are unaffected.
0103: OpenAIEmbeddingProvider accepts an optional, test-only chunk_size
override of its fixed 2048-input cap (validated positive), so the
batch-chunking path can be driven with a small body. Production leaves
it unset and the fixed cap applies, so there is no behavior change; the
count-based chunking rule (no client-side token estimation) is unchanged.
Spec v0.98.0 / v0.99.0 are beyond the current v0.88.0 pin, so both ship
ahead of the pin (unit-tested); the conformance fixtures and the
manifest entries ride the pin bump.
* Note the chunk cap default at the call site
Copy file name to clipboardExpand all lines: CHANGELOG.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -27,6 +27,8 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). The
27
27
- **Cohere `/v2/embed` recognizes `classification` and `clustering`** (proposal 0099, retrieval-provider §8.4, spec v0.94.0). **Breaking for these two values.** `EmbeddingRuntimeConfig.input_type` is an extensible string, and §2 names `classification` and `clustering` as well-known values a mapping may recognize when its backend supports them. Cohere's does, so the mapping now identity-maps both onto the wire instead of rejecting them. Previously either value raised `ProviderInvalidRequest` before the request was sent, so a caller who relied on that rejection as a guard (catching it to fall back to `document`, say) silently changes behavior. `query` / `document` / absent / unrecognized are all unchanged, and `image` stays out: it names an input modality rather than a purpose for embedded text, and `embed()` consumes strings. The widening is deliberately per-mapping and not portable. Jina keeps its closed `{query, document}` set, because its `task` support varies by model version (v3 accepts `classification` but not `clustering`, v4 neither, v5 both) and a provider is bound to a model identifier with no capability registry to consult, so that mapping cannot promise the values and declines them pre-send rather than letting the wire reject them later. Spec v0.94.0 is beyond the current v0.88.0 pin, so this ships ahead of the pin (unit-tested); the `conformance.toml` entry and fixture 033's new cases ride the pin bump.
28
28
- **Cohere `/v2/embed` `embedding_types` merge is now deterministic** (proposal 0099, retrieval-provider §8.4, spec v0.94.0). The mapping manages `embedding_types` as an explicit exception to untouched extras pass-through, because it must request `"float"` for its own response consumer (it reads `embeddings.float`). A caller-supplied `embedding_types` is merged with that mandatory `"float"` rather than replacing it, which was already the behavior; an override that dropped `float` would strip the key the mapping itself reads and fail the call. What changes is the shape of the merged list, which 0099 pins so the outbound body is reproducible and exact-match assertable: `"float"` first, then the caller's precisions in the order supplied, de-duplicated with the first occurrence winning. Previously the caller's precisions came first with `"float"` appended, and a repeated precision was sent twice, so `["int8"]` now yields `["float", "int8"]` rather than `["int8", "float"]`, and `["int8", "uint8", "int8"]` yields `["float", "int8", "uint8"]` rather than passing the duplicate through. The wire is order-insensitive here, so no request semantics change; callers still read their extra precisions off the verbatim response on `raw`. A malformed or empty extra still falls back to `["float"]`.
29
29
- **A malformed LLM usage counter is treated as not reported instead of raising** (proposal 0101, llm-provider §6 / §7 + observability §5.5.3 / §11.2, spec v0.96.0). **Behavioral reversal.** A usage counter present on the wire but not a non-negative integer (a string, a negative, a bool) is now nulled rather than raising `ProviderInvalidResponse`: the completion succeeded, the message is intact, and the verbatim value is preserved on `raw`. The sound counters stand, so a `{"prompt_tokens": -5, "completion_tokens": 1, "total_tokens": 1}` record surfaces as `{null, 1, 1}`; when every counter is malformed the record is `{null, null, null}` (the §6 null-together shape), still a present record so `LlmCompletionEvent.usage` mirrors it rather than going null. The value is never coerced or clamped, since a repaired counter is indistinguishable from a reported one, and `cached_tokens` follows the same rule. Previously any such counter raised `provider_invalid_response`, discarding a sound completion over an accounting figure. The observability surfaces already omit a not-reported counter per field (the OTel `openarmature.llm.usage.*` / `gen_ai.usage.*` span attributes, the token-usage histogram, and the token-budget instruments), so a null counter reaches none of them, and the Langfuse Generation `usage` omits it. Spec v0.96.0 is beyond the current v0.88.0 pin, so this ships ahead of the pin (unit-tested); the conformance fixtures ride the pin bump.
30
+
- **Jina `400` maps to `provider_invalid_request`, and an empty-string retrieval `response_id` is null** (proposal 0104, retrieval-provider §4 / §6 / §8.2, spec v0.99.0). **Behavioral at two edges.** The Jina error enumeration listed only `422`, so a bare `400` fell through to the transient `provider_unavailable` catch-all and invited a pointless retry of a request that will not succeed on retry; it now maps to `provider_invalid_request`, aligning Jina with the TEI / OpenAI / Cohere mappings. Separately, an empty-string `response_id` (`""`) on the Jina and Cohere embed / rerank responses is now treated as absent (`null`) rather than surfaced literally: an identifier that correlates nothing is not a present one, extending 0100's "malformed id is null" rule to the empty string. This deliberately differs from 0097's empty-`document` echo, which stays present, because a document is content while a `response_id` is an identifier. The OpenAI embed mapping already folded `""` to null and is unchanged. Well-formed responses and non-`400` errors are unaffected. Spec v0.99.0 is beyond the current v0.88.0 pin, so this ships ahead of the pin (unit-tested); the conformance fixtures ride the pin bump.
31
+
-**`OpenAIEmbeddingProvider` accepts a test-only `chunk_size` cap override** (proposal 0103, retrieval-provider §8.3 + conformance-adapter §5.14, spec v0.98.0). OpenAI's per-call input cap is a fixed vendor 2048, not construction-configurable like TEI's, so the §8 batch-chunking path could not be driven with a small body. An optional `chunk_size` constructor argument (validated positive; production leaves it unset and the fixed 2048 applies) overrides the cap for tests and the conformance harness, so a fixture can exercise chunk-and-stitch with a handful of inputs. No production behavior changes: `chunk_size` is unset by default, and the count-based chunking rule (no client-side token estimation; an over-token request fails loud as `provider_invalid_request`) is unchanged. Spec v0.98.0 is beyond the current v0.88.0 pin; the §8.3 over-cap fixture 043 and the single-request `raw` assertion ride the pin bump.
0 commit comments