Repository navigation
Delegate embedding model discovery to contextual-orchestrator #322
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
a6a1d8f
f0d761a
cbe777c
1a4a825
7b71045
3b2fdcf
1126cfa
f316e0a
a50a530
320cc27
7ae3c16
46b5889
cc80229
1c46eda
ca6f74a
65f23e5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| # 2.20.1 — Provider temperature capability negotiation | ||
|
|
||
| - Compose now pins ContextualWisdomLab/contextual-orchestrator#791 so providers | ||
| that accept only their default sampling temperature can retry the same | ||
| request without the unsupported optional field, alongside the orchestrator's | ||
| embedding-capability selection contract. | ||
| - The pin remains an immutable upstream commit and does not copy provider | ||
| behavior or credentials into LineageWeave. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # 2.20.2 | ||
|
|
||
| - Delegate embedding-model selection to contextual-orchestrator, retain the | ||
| resolved model as database provenance, and keep provider model selectors out | ||
| of the LineageWeave backend process. | ||
| - Discard the legacy embedding selector at the Compose bootstrap so automatic | ||
| capability discovery remains the only model-selection path. | ||
| - Keep the backward-compatible embedding client name aligned with the | ||
| orchestrator client's batch and per-request provenance contract. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,8 +3,8 @@ | |
| from __future__ import annotations | ||
|
|
||
| import hashlib | ||
| from datetime import timedelta | ||
| from dataclasses import dataclass | ||
| from datetime import timedelta | ||
| from typing import Any | ||
|
|
||
| import asyncpg | ||
|
|
@@ -48,7 +48,7 @@ async def post_content_is_complete( | |
| conn: asyncpg.Connection, | ||
| post_id: str, | ||
| *, | ||
| embedding_model_code: str, | ||
| embedding_model_code: str | None, | ||
| require_structure: bool = False, | ||
| ) -> bool: | ||
| """Require configured semantic, structure, and region evidence before ready.""" | ||
|
|
@@ -61,8 +61,35 @@ async def post_content_is_complete( | |
| where unit.post_id = $1 | ||
| ) | ||
| and ( | ||
| $2 = '' | ||
| or ( | ||
| ( | ||
| nullif($2::text, '') is null | ||
| and ( | ||
| not exists( | ||
| select 1 | ||
| from post_content_unit unit | ||
| left join post_content_embedding embedding | ||
| on embedding.post_content_unit_id = unit.post_content_unit_id | ||
| where unit.post_id = $1 | ||
| and embedding.post_content_embedding_id is null | ||
| ) | ||
| and not exists( | ||
| select 1 | ||
| from post_content_unit unit | ||
| join post_content_image image | ||
| on image.post_content_unit_id = unit.post_content_unit_id | ||
| join post_content_image_region region | ||
| on region.post_content_image_id = image.post_content_image_id | ||
| left join post_content_image_region_embedding embedding | ||
| on embedding.post_content_image_region_id = region.post_content_image_region_id | ||
| where unit.post_id = $1 | ||
| and region.description_status_code = 'described' | ||
| and embedding.post_content_image_region_embedding_id is null | ||
| ) | ||
| ) | ||
| ) | ||
| or ( | ||
| nullif($2::text, '') is not null | ||
| and ( | ||
| not exists( | ||
| select 1 | ||
| from post_content_unit unit | ||
|
|
@@ -88,6 +115,7 @@ async def post_content_is_complete( | |
| ) | ||
| ) | ||
| ) | ||
| ) | ||
|
Comment on lines
115
to
+118
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔍 Completeness semantics for empty/absent embedding model changed from 'skip' to 'require' Previously (Refers to this code) Was this helpful? React with 👍 or 👎 to provide feedback.
Comment on lines
115
to
+118
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📝 Info: Completeness now requires embeddings regardless of model The old predicate treated a blank model as complete ( (Refers to this code) Was this helpful? React with 👍 or 👎 to provide feedback. |
||
| and ( | ||
| not $3::boolean | ||
| or not exists( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| # ADR 0124: Orchestrator-owned embedding model discovery and provenance | ||
|
|
||
| - Status: Accepted | ||
| - Date: 2026-08-20 | ||
| - Scope: LineageWeave embedding ingestion and post-content backfill | ||
| - Figma: N/A | ||
|
|
||
| ## Context | ||
|
|
||
| LineageWeave must send embedding work through contextual-orchestrator. The | ||
| orchestrator can select an embedding-capable agent when the request omits a | ||
| model, but LineageWeave still read `LLM_GATEWAY_EMBEDDING_MODEL` and treated a | ||
| local model string as a prerequisite. That made the consumer contradict the | ||
| paper-grounded model boundary in ADR 0076 and the shared agent contract. | ||
|
|
||
| ## Decision | ||
|
|
||
| 1. LineageWeave does not read or expose a provider embedding model selector. | ||
| 2. The embedding request omits `model` when no explicit compatibility value is | ||
| supplied; contextual-orchestrator resolves the capability and returns the | ||
| served model code. | ||
| 3. Every persisted unit or visual-region embedding stores that returned model | ||
| code in the normalized embedding table. If the boundary returns no model | ||
| code, the vector is not persisted as provenance-bearing evidence and the | ||
| ingestion job remains incomplete for retry. | ||
| 4. Completeness checks in automatic mode require an embedding for every | ||
| embeddable unit and described image region, regardless of model code. An | ||
| explicit legacy model code, when supplied by a lower-level caller, retains | ||
| exact-model completeness matching but is not a runtime configuration path. | ||
| 5. The upstream contextual-orchestrator capability-selection contract is a | ||
| dependency of this consumer change. No monkey patch, provider SDK, local | ||
| model ranking, or sentinel model name is permitted. | ||
|
|
||
| ## Consequences | ||
|
|
||
| - Runtime configuration contains only the internal orchestrator boundary; the | ||
| provider credentials remain in `~/.env` at the orchestrator service boundary. | ||
| - Existing rows retain their actual `embedding_model_code`; no backfill uses a | ||
| guessed or synthetic model code. | ||
| - A temporarily incomplete orchestrator response fails closed for evidence, | ||
| while the source body remains available for retry. | ||
|
|
||
| ## References | ||
|
|
||
| ContextualWisdomLab. (2026). *contextual-orchestrator capability selection | ||
| contract* (PR #789). https://github.com/ContextualWisdomLab/contextual-orchestrator/pull/789 | ||
|
|
||
| ContextualWisdomLab. (2026). *ADR 0076: Paper-grounded model policy*. | ||
| `docs/adr/0076-paper-grounded-model-policy.md`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔍 Automatic completeness requires an embedding for every unit, including text-less image units
In automatic mode (
embedding_model_codeempty/None, the only runtime path now),post_content_is_completerequires that everypost_content_unithas apost_content_embedding(thenot exists(... embedding.post_content_embedding_id is null)clause at post_content_queue.py). Image units whose renderedunit_textis empty are never added toembeddablein post_content_persistence.py, so they get no unit embedding, which would keep such a post permanently incomplete and drive the worker to FAILED after retries. This behavior is not newly introduced (the prior exact-model branch imposed the same per-unit requirement while the runtime supplied a configured model), so it is not a regression from this PR — but it is worth confirming that all embeddable units actually receive embeddings under the pinned orchestrator, otherwise ingestion fails closed indefinitely.Was this helpful? React with 👍 or 👎 to provide feedback.