fix(s31): close 1 review BLOCKER — per-call retriever + run_portfolio forwards semantic_retrieval
This commit is contained in:
parent
969d450b31
commit
fc69285f2c
3 changed files with 231 additions and 57 deletions
|
|
@ -388,16 +388,23 @@ async def run_project(
|
|||
# post-generation into a discarded SessionContext (step 7 below), so a prior verdict could not
|
||||
# reach the next hypothesis. Bundle-driven path with a populated store only; the road path is
|
||||
# untouched (its post-hoc, proposal-keyed retrieval below is unchanged).
|
||||
# S3.1 opt-in: install the hybrid ranker on the RESOLVED store, immediately before the fold it
|
||||
# is meant to affect. Anchoring matters — set at the verdict_dir-conditional resolution above
|
||||
# it would miss every run without an inbox, and set after the fold it would rank nothing that
|
||||
# reaches this prompt. Flag off => store.retriever stays None => StructuralRetriever default.
|
||||
if semantic_retrieval and store is not None:
|
||||
store.retriever = HybridRanker(FakeEmbedder(), similarity, SEMANTIC_WEIGHT_DEFAULT)
|
||||
# S3.1 opt-in: build the hybrid ranker as a LOCAL, then pass it explicitly at each retrieval
|
||||
# this run performs. It is deliberately not assigned to ``store.retriever``: the store is
|
||||
# caller-owned (``run_portfolio`` threads one store across every project, and a library caller
|
||||
# may reuse theirs), so a store-global assignment leaked this run's opt-in into every later use
|
||||
# of that object — including a subsequent run with the flag OFF. Flag off => ranker stays None
|
||||
# => ``retrieve`` falls through to the StructuralRetriever default.
|
||||
ranker = (
|
||||
HybridRanker(FakeEmbedder(), similarity, SEMANTIC_WEIGHT_DEFAULT)
|
||||
if semantic_retrieval
|
||||
else None
|
||||
)
|
||||
|
||||
if bundle_dir is not None and store is not None and store.verdicts:
|
||||
expel_query = bundle_candidate_features(bundle_dir)
|
||||
fewshot = ExpeLContextProvider(store, expel_query, k=top_k).format_fewshot()
|
||||
fewshot = ExpeLContextProvider(
|
||||
store, expel_query, k=top_k, retriever=ranker
|
||||
).format_fewshot()
|
||||
gen_context = f"{fewshot}\n\n{gen_context}"
|
||||
|
||||
# 5. Structured candidate -> blocking validation on the NUMBERS; token bound = the meter.
|
||||
|
|
@ -457,10 +464,10 @@ async def run_project(
|
|||
# is NOT what reaches the prompt.
|
||||
store = store if store is not None else VerdictStore(verdicts=[])
|
||||
features = _features_of(proposal)
|
||||
provider = ExpeLContextProvider(store, features, k=top_k)
|
||||
provider = ExpeLContextProvider(store, features, k=top_k, retriever=ranker)
|
||||
sctx = SessionContext(input_messages=[], instructions=[])
|
||||
await provider.before_run(agent=None, session=None, context=sctx, state={})
|
||||
retrieved = store.retrieve(features, k=top_k) if store.verdicts else []
|
||||
retrieved = store.retrieve(features, k=top_k, retriever=ranker) if store.verdicts else []
|
||||
|
||||
# 8. Layer-2 (out-of-band): capture the durable verdict + persist; B11 notify is a stub.
|
||||
verdict = capture_verdict(features, verdict_input["decision"], verdict_input["rationale"])
|
||||
|
|
@ -571,10 +578,9 @@ async def run_portfolio(
|
|||
projects = {p.id: p for p in load_reference_projects()}
|
||||
ids = list(project_ids) if project_ids is not None else list(projects)
|
||||
store = store if store is not None else VerdictStore(verdicts=[])
|
||||
# S3.1: one shared store is threaded across every project, so installing the hybrid here —
|
||||
# before the loop — covers every project's Step-1 fold in this pass.
|
||||
if semantic_retrieval:
|
||||
store.retriever = HybridRanker(FakeEmbedder(), similarity, SEMANTIC_WEIGHT_DEFAULT)
|
||||
# S3.1: the flag is FORWARDED per project rather than installed on the shared store here. The
|
||||
# store is threaded across every project in the pass (and may be caller-owned), so a pre-loop
|
||||
# assignment outlived the pass; forwarding keeps the opt-in scoped to each run's own retrievals.
|
||||
ledger = ledger if ledger is not None else SavingsLedger(entries=[])
|
||||
goals = goals if goals is not None else GoalConfig()
|
||||
portfolio_baseline_ore = _to_ore(sum(projects[p].total_cost for p in ids if p in projects))
|
||||
|
|
@ -625,6 +631,7 @@ async def run_portfolio(
|
|||
max_rounds=max_rounds,
|
||||
max_tokens=max_tokens,
|
||||
top_k=top_k,
|
||||
semantic_retrieval=semantic_retrieval,
|
||||
meter=meter_factory() if meter_factory is not None else None,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue