Skip to content

Add retrieval-provider embedding capability#196

Merged
chris-colinsky merged 4 commits into
mainfrom
feature/retrieval-embedding-provider
Jun 28, 2026
Merged

Add retrieval-provider embedding capability#196
chris-colinsky merged 4 commits into
mainfrom
feature/retrieval-embedding-provider

Conversation

@chris-colinsky

Copy link
Copy Markdown
Member

Summary

Adds the embedding surface of the new retrieval-provider capability.

  • New retrieval/ package: the EmbeddingProvider protocol,
    EmbeddingResponse / EmbeddingUsage / EmbeddingRuntimeConfig types,
    input/response validators, and OpenAIEmbeddingProvider (a reference
    implementation posting to an OpenAI-compatible /v1/embeddings).
  • Typed EmbeddingEvent / EmbeddingFailedEvent on the observer event
    union, dispatched on every embed(). The bundled OTel and Langfuse
    observers safely skip them for now; the embedding span and Embedding
    observation are a follow-up.

Conformance fixtures 001-005 pass; the rerank fixtures (006-012) are
deferred until the RerankProvider lands.

Hardening and design

  • Malformed responses (missing, empty, or non-numeric vectors;
    non-permutation indices) raise provider_invalid_response.
  • A trailing /v1 on base_url is rejected (it would double to
    /v1/v1).
  • ready() takes a configurable readiness_probe, defaulting to a
    universal one-input embed so it works against backends without a
    /v1/models catalog (such as TEI's OpenAI surface), with models
    and both opt-ins.

Tests

  • tests/conformance/test_retrieval_provider.py drives the provider
    through httpx.MockTransport (001-005 green).
  • tests/unit/test_retrieval_provider.py covers the base_url guard, the
    readiness modes, and the observers' safe handling of the embedding
    events.

Full conformance + unit suite green (1448 passed), whole-src pyright clean.

Follow-ups (this release)

  • Observability rendering: the OTel embedding span, the Langfuse
    Embedding observation, and fixtures 074-083.
  • Cross-provider cleanups: shared OpenAI HTTP / base_url helpers, the
    event-identity snapshot, and the test MockTransport builder.
  • Docs: a concepts page, a Model Providers entry, and an example.

Add the embedding surface of the new retrieval-provider capability: an
EmbeddingProvider protocol, the EmbeddingResponse / EmbeddingUsage /
EmbeddingRuntimeConfig types, and an OpenAIEmbeddingProvider reference
impl posting to an OpenAI-compatible /v1/embeddings. Typed
EmbeddingEvent / EmbeddingFailedEvent join the observer event union,
dispatched on every embed(); the bundled OTel and Langfuse observers
safely skip them for now (the embedding span and Embedding observation
are a follow-up).

The provider rejects malformed responses (missing, empty, or non-numeric
vectors and non-permutation indices), guards a trailing /v1 on base_url,
and offers a configurable readiness probe defaulting to a universal
one-input embed so it works against backends without a /v1/models
catalog (e.g. TEI's OpenAI surface). Conformance fixtures 001-005 pass;
unit tests cover the guard, the readiness modes, and the observer
safe-handling.

conformance.toml keeps 0059 not-yet; the observability rendering
(074-083), the cross-provider helper cleanups, and the docs are v0.16.0
follow-ups.
Copilot AI review requested due to automatic review settings June 28, 2026 03:23
Comment thread src/openarmature/retrieval/provider.py
Comment thread src/openarmature/retrieval/provider.py

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds the retrieval-provider embedding capability surface to openarmature, including a reference OpenAI-compatible embedding provider, typed embedding observer events, and conformance/unit tests to validate behavior against the spec fixtures.

Changes:

  • Introduces the openarmature.retrieval package with EmbeddingProvider, response/config models, and input/response validation helpers.
  • Adds OpenAIEmbeddingProvider implementing POST /v1/embeddings plus readiness probes (/v1/models and/or embed probe).
  • Extends the observer event union with EmbeddingEvent / EmbeddingFailedEvent, and updates bundled OTel/Langfuse observers to safely ignore them for now; adds tests and conformance harness.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/unit/test_retrieval_provider.py Unit coverage for base_url guard, readiness probe modes, and observer skip behavior for embedding events.
tests/conformance/test_retrieval_provider.py Conformance harness running retrieval-provider fixtures 001–005 against OpenAIEmbeddingProvider via httpx.MockTransport.
src/openarmature/retrieval/response.py Defines EmbeddingResponse, EmbeddingUsage, and EmbeddingRuntimeConfig models.
src/openarmature/retrieval/providers/openai.py Implements the OpenAI-compatible embeddings provider, request/response parsing, readiness probes, and event dispatch.
src/openarmature/retrieval/providers/init.py Exposes bundled retrieval providers.
src/openarmature/retrieval/provider.py Adds the EmbeddingProvider protocol and shared validators for embedding input/response invariants.
src/openarmature/retrieval/init.py Public package exports for the retrieval-provider capability.
src/openarmature/observability/otel/observer.py Updates OTel observer to type-union accept and explicitly ignore embedding events.
src/openarmature/observability/langfuse/observer.py Updates Langfuse observer to type-union accept and explicitly ignore embedding events.
src/openarmature/observability/correlation.py Widens the dispatch event type union to include embedding events (TYPE_CHECKING-only type aliasing).
src/openarmature/graph/observer.py Extends ObserverEvent union with embedding events.
src/openarmature/graph/events.py Adds EmbeddingEvent / EmbeddingFailedEvent dataclasses and exports them.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/openarmature/retrieval/providers/openai.py Outdated
Comment thread src/openarmature/retrieval/providers/openai.py Outdated
Fix the issues from the PR #196 re-review:

- Build the embeddings request body extras-first so a caller's
  undeclared runtime-config extra cannot clobber the bound model or the
  input list.
- Reject non-numeric vector values (JSON strings, bools) and bool usage
  counts strictly rather than coercing them, so a non-numeric vector is
  treated as malformed.
- Dedup the observer event union: correlation and both observers now
  reference the single ObserverEvent alias instead of repeating the
  member list, so a new event widens the contract in one place.
- Move a stray spec section ref out of a docstring into a comment and
  reword em-dash substitutes in docstrings.
- Strengthen the tests: the Langfuse safe-handling test asserts no trace
  is created, and the conformance runner tolerates a fixture without a
  stores_response_in key instead of raising KeyError.
- Refresh the observer dispatch docstrings to point at ObserverEvent
  rather than a hardcoded variant count.
Comment thread src/openarmature/observability/correlation.py
From the PR #196 review:

- _probe_models now raises ProviderInvalidResponse when the /v1/models
  body is not a JSON object or its data field is missing or not a list,
  mirroring _parse_response. A malformed catalog was being degraded to an
  empty list and misreported as a missing model (ProviderInvalidModel);
  that category is now reserved for a well-formed catalog that genuinely
  lacks the bound model. Covered by a new unit test.
- Align the _classify_embedding_http_error docstring with the code: the
  catch-all maps every other status (not just 5xx) to unavailable, the
  same as the sibling classify_http_error.
Copilot AI review requested due to automatic review settings June 28, 2026 16:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Comment thread src/openarmature/graph/observer.py
The Observer protocol docstring example annotated its log_observer with
NodeEvent | MetadataAugmentationEvent, which would be a structural
conformance error now that the protocol delivers the full ObserverEvent
union (embedding, tool, and provider events included). Annotate the
example with ObserverEvent so copied observers type-check.
@chris-colinsky chris-colinsky merged commit e10fc07 into main Jun 28, 2026
6 checks passed
@chris-colinsky chris-colinsky deleted the feature/retrieval-embedding-provider branch June 28, 2026 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants