fix(session): drop the <context> envelope and project context verbatim

context/message previously defaulted to a <context source="…">…</context>
wrapper. No model is trained on a <context> tag either, and message
framing does not belong on the session surface: the surface projects the
durable log, and a caller that wants a frame formats its own content —
which the one heavy producer (workspace-context) already does with its own
<system-reminder> frame, opting out via 'raw'. The tag only added
machinery — ContextEnvelope plus an envelope field threaded through
InjectOptions, HookContext, the context/message event, and the agent-loop
inject/additionalContexts plumbing.

context/message now projects its content verbatim as a user-role message,
sharing one deriveEventMessage case with user/message and steering/message.
ContextEnvelope and every envelope field are removed; context/message.meta
still carries durable, model-hidden JSON state. Regenerated catalogs and
website API; refreshed the three affected keyless snapshots (envelope field
only; timestamps unchanged).

Broadens and renames the steering Agent Note to cover both envelope
removals as one decision.

Agent Note: .agents/notes/implemented/simplification/2026-07-20-unwrap-injected-content-envelopes.md
This commit is contained in:
Turtle
2026-07-20 16:22:20 +08:00
parent b25b78fd02
commit f593ef5ab5
47 files changed
+230 -266

No files matched your search

@@ -92,7 +92,6 @@ export function apply(ctx: Context, config: Config): void {
if (update !== undefined) {
agent.inject(update.context.content, {
source: update.context.source,
envelope: update.context.envelope,
meta: update.context.meta,
})
applyInstructionVersionUpdates(agent.session, update.versionUpdates, instructionVersions)
@@ -163,6 +163,12 @@ function buildInstructionText(
): string {
const marker = markerText(maxBytes, omitted, truncated)
const body = [marker, style.intro, ...files.map(file => style.section(file))].filter(block => block.length > 0)
// Caller-owned framing: the plugin bakes the complete `<system-reminder>`
// frame into the message content. The session surface projects context
// verbatim and does not wrap it, so any framing must live here in the
// producer's content (the pattern a future `meta`-driven renderer would
// generalize — see the deferred note in
// ../../../../.agents/notes/implemented/simplification/2026-07-20-unwrap-injected-content-envelopes.md).
return [SYSTEM_REMINDER_OPEN, body.join('\n\n'), SYSTEM_REMINDER_CLOSE].join('\n')
}
@@ -61,9 +61,8 @@ export interface ReconciledInstructionContext {
versionUpdates: InstructionVersionUpdate[]
}
/** Plugin-owned raw context with required replay metadata. */
/** Plugin-owned context with required replay metadata. */
export interface WorkspaceHookContext extends HookContext {
envelope: 'raw'
meta: JsonValue
}
@@ -76,7 +75,7 @@ function workspaceContextHook(text: string, changes: WorkspaceInstructionChange[
...change.digest !== undefined ? { digest: change.digest } : {},
}))
const meta: JsonValue = { kind: 'workspace-instructions', version: 1, changes: serializedChanges }
return { content: [{ type: 'text', text }], source: PLUGIN_SOURCE, envelope: 'raw', meta }
return { content: [{ type: 'text', text }], source: PLUGIN_SOURCE, meta }
}
/**