refactor(retrieval): the completion-report preferences run through the pipeline (milestone 456 step 3, #4905)
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 13s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / integration (push) Successful in 53s
CI & Build / Python tests (push) Successful in 1m45s
CI & Build / Build & push image (push) Successful in 28s
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 13s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / integration (push) Successful in 53s
CI & Build / Python tests (push) Successful in 1m45s
CI & Build / Build & push image (push) Successful in 28s
reply_preferences.completion_preferences was the last hand-written rule search + record_retrieval + record_rule_surfaced triple outside the pipeline. It is now REPORT_PREFERENCE, a RuleArm with kind="preference" over COMPLETION_QUERY, read back as records rather than as lines. - RuleArm gains `kind`. _ranked asks the ranker for that kind and drops anything else on the way out, before the row is logged. - RuleResult gains `shown`, the (score, rule) pairs behind the lines, for callers that return records. - RuleMoment.project_id may be None: logged as given, searched as `project_id or None`. report_preference rows keep their NULL project. - Guards: reply_preferences now has 0 direct rule searches. The registry constant-source example moves from report_preference to preference_slot, the pipeline slot that records through a module constant. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -58,8 +58,8 @@ bar can be wrong forever without a single call looking unusual.
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import time
|
||||
|
||||
from scribe.services import retrieval_pipeline as rp
|
||||
from scribe.services.embeddings import semantic_search_rules
|
||||
from scribe.services.retrieval_surfaces import SURFACES, budget_for, floor_for
|
||||
from scribe.services.retrieval_telemetry import record_retrieval
|
||||
@@ -67,7 +67,7 @@ from scribe.services.rule_usage import record_rule_surfaced
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
SOURCE = "report_preference"
|
||||
SOURCE = rp.REPORT_PREFERENCE.source
|
||||
|
||||
# Written in the vocabulary of the MOMENT, because that is what a trigger is
|
||||
# written in and what this query is scored against. Domain-neutral on purpose
|
||||
@@ -114,34 +114,27 @@ async def completion_preferences(user_id: int, *, project_id: int | None = None)
|
||||
happened, and a lookup that errors must not turn it into a failure.
|
||||
"""
|
||||
try:
|
||||
threshold = await _threshold(user_id)
|
||||
limit = await _limit(user_id)
|
||||
report: dict = {}
|
||||
t0 = time.perf_counter()
|
||||
hits = await semantic_search_rules(
|
||||
user_id, COMPLETION_QUERY, limit=limit, threshold=threshold,
|
||||
kind="preference", report=report, project_id=project_id,
|
||||
)
|
||||
hits = [(score, rule) for score, rule in hits if rule.kind == "preference"]
|
||||
record_retrieval(
|
||||
user_id=user_id, source=SOURCE, query=COMPLETION_QUERY,
|
||||
threshold=threshold, limit=limit, project_id=project_id,
|
||||
is_task=None, results=hits,
|
||||
best_available=report.get("best_available_score"),
|
||||
best_available_id=report.get("best_available_id"),
|
||||
searched=bool(report.get("searched", True)),
|
||||
duration_ms=(time.perf_counter() - t0) * 1000.0,
|
||||
)
|
||||
if not hits:
|
||||
return []
|
||||
# The stages — the kind filter, the unconditional call row, the
|
||||
# fresh-only surfacing rows — are the one pipeline's (milestone 456).
|
||||
# RANKED: this surface chose what it showed, so the name is in
|
||||
# rule_usage.RANKED_SOURCES and its hits count toward pull-through.
|
||||
record_rule_surfaced(
|
||||
user_id=user_id, rule_ids=[rule.id for _s, rule in hits], source=SOURCE,
|
||||
# There is no session ledger here: a completion report is written
|
||||
# once, so nothing it could repeat has been shown before.
|
||||
result = await rp.run_rule_arm(
|
||||
rp.REPORT_PREFERENCE,
|
||||
rp.RuleMoment(
|
||||
user_id=user_id, query=COMPLETION_QUERY, project_id=project_id,
|
||||
),
|
||||
floor=await _threshold(user_id), budget=await _limit(user_id),
|
||||
io=rp.RuleIO(
|
||||
search=semantic_search_rules,
|
||||
record_retrieval=record_retrieval,
|
||||
record_rule_surfaced=record_rule_surfaced,
|
||||
),
|
||||
)
|
||||
return [
|
||||
{"id": rule.id, "title": rule.title, "statement": rule.statement, "kind": "preference"}
|
||||
for _score, rule in hits
|
||||
for _score, rule in result.shown
|
||||
]
|
||||
except Exception: # noqa: BLE001 - a decoration never breaks its payload
|
||||
logger.warning("completion preference lookup failed", exc_info=True)
|
||||
|
||||
Reference in New Issue
Block a user