feat(plugin): auto-inject retrieves on the conversation, not the typed words alone (#4364)
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 11s
CI & Build / integration (push) Successful in 49s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / Python tests (push) Failing after 1m7s
CI & Build / Build & push image (push) Skipped

The prompt hook sent only the operator's message, so a mid-session
follow-up ("yes do that") named nothing a note, lesson or rule could
match. The hook now reads the tail of the last assistant reply from the
transcript and sends it as `ctx`; the notes and rule arms append it to a
short prompt (<= 280 chars), prompt first, capped at 600 chars. No model
tokens: it is embedding input, and the injected menu's budget is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-23 16:05:21 -04:00
co-authored by Claude Opus 5.5
parent a01deeb851
commit 574b27ae74
6 changed files with 188 additions and 4 deletions
+10 -2
View File
@@ -95,6 +95,12 @@ async def autoinject_retrieve():
project_id (opt) — explicit project scope override (ad-hoc/testing).
exclude_ids (opt) — comma-separated note ids already injected this
session; skipped so each note injects at most once.
ctx (opt) — the tail of the last assistant reply (#4364). The
notes AND rule arms append it to a short prompt,
so a follow-up like "yes do that" still names
what it is about — and a rule or lesson arrives
while the work is under way, before the operator
has to call it out.
exclude_rule_ids — comma-separated rule ids already surfaced this
(opt) session. SHARED with /prior-art and /tool-rules on
purpose: one session keeps ONE rule ledger, so a
@@ -125,11 +131,13 @@ async def autoinject_retrieve():
exclude_rule_ids = _int_list(request.args.get("exclude_rule_ids"))
held_rule_ids = _int_list(request.args.get("held_rule_ids"))
ctx = request.args.get("ctx") or ""
rules = await plugin_ctx_svc.build_prompt_rule_hint(
g.user.id, q, project_id=project_id, exclude_rule_ids=exclude_rule_ids, held_rule_ids=held_rule_ids
g.user.id, q, project_id=project_id, exclude_rule_ids=exclude_rule_ids, held_rule_ids=held_rule_ids,
context=ctx,
)
result = await plugin_ctx_svc.build_autoinject_hint(
g.user.id, q, project_id=project_id, exclude_ids=exclude_ids
g.user.id, q, project_id=project_id, exclude_ids=exclude_ids, context=ctx,
)
blocks = [b for b in (rules["context"], result["context"]) if b]
result["context"] = "\n\n".join(blocks)