Repository navigation
chore(deprecate): ContextInjection and compile(injections) - #140
antra-tess wants to merge 4 commits into
Conversation
Injections are never stored: every compile splices them in fresh, re-anchored to the latest user-participant message, so the rendered prefix moves at each activation and prompt caches stop hitting past that point (head-only hits on OpenAI Responses/Codex); after a mid-activation recompile the anchor can also fall between a tool call and its result (anima-research/agent-framework#171). Annotate without changing behavior: @deprecated on ContextInjection and CompileResult.systemInjections, a deprecation paragraph on compile()'s `injections` parameter, and a changelog fragment. No runtime warning here on purpose: the host (agent-framework) warns per injecting source, which CM cannot identify. No overload either — callers pass `ContextInjection[] | undefined`, which a split signature would reject. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
slimepriestess
left a comment
There was a problem hiding this comment.
Reviewed at cc1e7e7. Approve. Both panels: full suite 892/0 at head, and the doc-only claim verified mechanically — against the merge-base the diff is 30 insertions (changelog 11, context-manager.ts 5, types/context.ts 14), and filtering the src lines for anything that isn't a comment leaves nothing. Behavior unchanged by construction, exactly as the body says.
The deprecation's reasoning holds up from the consumer side: the alternative it points to (content stored once at its own position; the system prompt for durable instructions, ordinary messages for changing state) actually exists and matches where the stack is going, and both deliberately-not-done calls are right — the host already warns once per injecting source with more information than CM could have (agent-framework#218), and a split compile() overload would reject the ContextInjection[] | undefined union real callers pass. The cache argument in the body (a fresh splice re-anchored each activation moves the rendered prefix, so prompt caches stop hitting past the slot) is the same prefix-economics lesson running through #128 and #130 this week — injections were the original sin of that class, and this writes the warrant for retiring them.
…njections The deprecation text described the splice-and-re-anchor of beforeUser and afterUser injections as every injection's. compile() never splices or anchors a system-position injection: it returns its content in CompileResult.systemInjections for the caller's system prompt. The ContextInjection doc and compile()'s paragraph now say which positions move, the type doc says where system ones go, and the position field's doc, which said every position goes into the message array, says the same. Only a beforeUser injection can land between a tool call and its result, since afterUser goes after the last user message, which there is the tool result. The type doc and the fragment now say beforeUser. The changelog fragment now names CompileResult.systemInjections among what is deprecated, as its type doc already marks it. Comments and the changelog fragment only; no code changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@antra-tess We read #140 against
Written by Beth-2389. Abigail-2459 read it. — Fiona-2757 |
…stemInjections holds R1-1: the deprecation text gave a reason for beforeUser and afterUser injections only, while the fragment names CompileResult.systemInjections as deprecated too. A system injection isn't stored either: the caller passes it again with every compile and appends its content to the system prompt, so when its content changes the system prompt changes, and the prompt cache misses from there, ahead of every message. The ContextInjection doc, compile()'s paragraph and the fragment now say so. R1-2: systemInjections' doc said "grouped by namespace", but compile() pushes each system injection's content blocks in the order given and keeps no namespace. The doc now says that. The anchor is the latest message whose participant is "user", compared ignoring case, so a named participant such as "Alice" never anchors. The type doc and the fragment now say that in place of "user-participant message", and that the prefix changes each time a newer one arrives rather than at every activation; compile()'s paragraph says the blocks move as newer user messages arrive. Comments and the changelog fragment only; no code changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs(deprecate): say which injection positions move, and name systemInjections
Why
Context injection is being deprecated across the stack (anima-research/agent-framework#171). context-manager is where injections are placed.
compile()splices them in fresh on every call, re-anchored to the latest user-participant message, and stores nothing. As a result:What this does
Behavior is unchanged: injections are still accepted and placed exactly as before.
@deprecatedonContextInjection, explaining the problem and pointing to the alternative: content stored once at its own position. The system prompt is for durable instructions; ordinary messages are for changing state.@deprecatedonCompileResult.systemInjections, which is only populated bysystem-position injections.compile()'s doc for theinjectionsparameter: new callers passundefined.changelog.d/deprecate-context-injections.changed.md.Deliberately not done:
compile(). Callers passContextInjection[] | undefined, and splitting the signature into "with" and "without" overloads would reject that union at compile time.Tests
npx tsc --noEmitis clean,npm run buildsucceeds, andnpm testpasses 892/892. The change is documentation only.Companion PRs
None of them depends on another, so they can merge in any order.
🤖 Generated with Claude Code