Skip to content

chore(deprecate): ContextInjection and compile(injections) - #140

Open
antra-tess wants to merge 4 commits into
mainfrom
chore/deprecate-context-injections
Open

antra-tess wants to merge 4 commits into
mainfrom
chore/deprecate-context-injections

Conversation

@antra-tess

@antra-tess antra-tess commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

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:

  • Prompt caching breaks across activations. The rendered prefix moves at each activation, so prompt caches stop hitting past the old injection slot. On OpenAI Responses/Codex the first call of every activation is a head-only hit.
  • Blocks can split a tool pair. After a mid-activation recompile, the anchor can fall between a tool call and its result.

What this does

Behavior is unchanged: injections are still accepted and placed exactly as before.

  • @deprecated on ContextInjection, 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.
  • @deprecated on CompileResult.systemInjections, which is only populated by system-position injections.
  • A deprecation paragraph in compile()'s doc for the injections parameter: new callers pass undefined.
  • Changelog fragment: changelog.d/deprecate-context-injections.changed.md.

Deliberately not done:

  • No runtime warning in CM. The host warns once per injecting module or MCPL server (agent-framework#218), and CM can't tell which source an injection came from, so a warning here would only duplicate that with less information.
  • No deprecated overload of compile(). Callers pass ContextInjection[] | undefined, and splitting the signature into "with" and "without" overloads would reject that union at compile time.

Tests

npx tsc --noEmit is clean, npm run build succeeds, and npm test passes 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

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>
@greptile-apps

greptile-apps Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 4/5 Tier: apex

[Medium risk] Marks context injection feature as deprecated.

The PR appears safe to merge; the identified documentation corrections are non-blocking.

Summary

The PR documents the deprecation of context injections without changing runtime behavior.

  • Adds deprecation guidance to ContextInjection, compile(), and CompileResult.systemInjections.
  • Adds a changelog fragment explaining the motivation and suggested alternatives.

Reviews (1) · Last reviewed commit: "chore(deprecate): ContextInjection and c..."

@slimepriestess slimepriestess left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
@nissa-seru

Copy link
Copy Markdown
Contributor

@antra-tess We read #​140 against main as it is today, and its claims about what compile() does hold there. We've opened #277 into this branch for a few text points, and one more is in main's README.

  • What holds. We merged this branch onto main at cfd3147f, with no conflicts, and its suite passes 2,405 of 2,405 on Linux with Node 24.22.0. A probe of the deprecation's behaviour claims passes at main and at the merge:

    • injections aren't stored;
    • an afterUser injection moves with each new user message;
    • a beforeUser one, compiled after a tool result, lands between the call and its result;
    • systemInjections is empty without injections.

    The probe is in #​277's description.

  • #​277, into this branch. The deprecation text describes the splice-and-re-anchor of beforeUser and afterUser injections as every injection's. compile() returns system ones in systemInjections without placing them. #​277 says which positions move, says beforeUser in the tool-call sentence, and adds CompileResult.systemInjections to the fragment's list of what's deprecated. It changes comments and the fragment only.

  • main's README. Its quick start was added on October 13, after this branch. It still destructures systemInjections and says that injections passed as compile()'s second argument with position system come back there, with no note that both are deprecated. The wording we'd use there:

    const { messages } = await manager.compile({
      maxTokens: 100_000, // the whole window, the response included
      reserveForResponse: 4_000,
    });
    // `messages` go into a membrane request.

Written by Beth-2389. Abigail-2459 read it.

— Fiona-2757

Ansel-2428 and others added 2 commits October 25, 2026 01:15
…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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants