From b97da79299ad2a3d1b45040c9e4547cfbd4c8bb4 Mon Sep 17 00:00:00 2001 From: zackmsa777-a11y Date: Fri, 11 Sep 2026 13:34:49 +0300 Subject: [PATCH] refactor(prompt): remove unreachable runtime-only system prompt path (#143314) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What Problem This Solves Remove the audit-found runtime-only system-prompt branch and its unused mutation interface. This is a maintainer-approved refactor, not a Gateway cache fix or a performance improvement. The branch is unreachable through the supported Gateway event ingress paths: completion events receive a nonempty transcript from [`resolveInternalEventTranscriptBody`](https://github.com/openclaw/openclaw/blob/31d03f782230799ea6ceea8b41b6602b29d0da50/src/agents/internal-events.ts#L372), selected by [agent preparation](https://github.com/openclaw/openclaw/blob/31d03f782230799ea6ceea8b41b6602b29d0da50/src/agents/command/prepare.ts#L415), and room events receive an [attributed transcript line](https://github.com/openclaw/openclaw/blob/31d03f782230799ea6ceea8b41b6602b29d0da50/src/auto-reply/reply/prompt-prelude.ts#L212). The removed append required an empty transcript. Persistence suppression also disables runtime-only admission. ## Why This Change Was Made - Remove event-specific system-prompt composition and session mutation from prompt-context assembly. - Remove that stage's unused system-setter callback and update every caller and fixture; preserve the assembly-stage setter used by hooks and model identity. - Remove the unused runtime-event formatter variant and retain one delimiter-only carrier format. - Keep event tail routing, escaping, carrier lifetime, and the byte-stability regression. ## User Impact No user-visible behavior change is expected. The cleanup removes unused mutation paths while preserving supported Gateway event handling. ## Evidence The [real-API comparison](https://github.com/openclaw/openclaw/pull/143314#issuecomment-5632556877) showed no cache regression on main: both main and the original PR head kept instruction bytes equal across normal → completion event → normal, with cached-token counts of 0 → 5,888 → 5,888 in both runs. The regression fixture reaches the removed branch by supplying an empty transcript directly; it is retained as an internal byte-stability guard. All 260 focused runner, context, formatter, truncation, and legacy-stripping tests pass. With the callback-free fixture, the original append implementation fails three event cases by attempting the removed setter; 18 controls pass. All cases pass after the path is removed. Formatting, focused lint, and normal commit hooks pass. This is internal refactor coverage; the live results do not establish a user-visible cache defect. Thanks @zackmsa777-a11y for the original change and review fixes. The follow-up cleanup preserves the contributor's commits and authorship. Related: #143242. Co-authored-by: Ayaan Zaidi --- config/env-var-count-budget.txt | 2 +- .../run/attempt-llm-boundary.ts | 9 ++-- .../run/attempt-prompt-build.ts | 29 ++--------- .../run/attempt-prompt-context.test.ts | 50 ++++++++++++------- .../run/attempt-prompt-phase.ts | 1 - .../attempt.media-hint-cache-boundary.test.ts | 1 - ...mpt.spawn-workspace.context-engine.test.ts | 7 +-- .../run/runtime-context-prompt.test.ts | 2 +- .../run/runtime-context-prompt.ts | 31 ++---------- .../tool-result-truncation.test.ts | 1 - src/agents/harness/selection.test.ts | 3 +- src/agents/internal-runtime-context.test.ts | 3 +- src/agents/internal-runtime-context.ts | 4 +- 13 files changed, 54 insertions(+), 89 deletions(-) diff --git a/config/env-var-count-budget.txt b/config/env-var-count-budget.txt index 178ed3f867e6..4b7dc6a240d1 100644 --- a/config/env-var-count-budget.txt +++ b/config/env-var-count-budget.txt @@ -3,4 +3,4 @@ # Worker bundle installation no longer injects OPENCLAW_STATE_DIR into a remote npm process. # The internal Node-version check no longer contributes a false OPENCLAW_* name. # The next-turn runtime-context preface constant no longer exists as an OPENCLAW_* name. -493 +492 diff --git a/src/agents/embedded-agent-runner/run/attempt-llm-boundary.ts b/src/agents/embedded-agent-runner/run/attempt-llm-boundary.ts index 0be4e19ff784..3ab136163da8 100644 --- a/src/agents/embedded-agent-runner/run/attempt-llm-boundary.ts +++ b/src/agents/embedded-agent-runner/run/attempt-llm-boundary.ts @@ -68,7 +68,7 @@ export function usesEscapedRuntimeContext(sessionVersion?: number): boolean { } /** The model boundary renders producer facts; transcript content remains untouched. */ -export function projectRuntimeContextFragments(fragments: RuntimeContextFragment[]): string { +function projectRuntimeContextFragments(fragments: RuntimeContextFragment[]): string { return fragments .map(({ kind, text }) => { const escaped = escapeInternalRuntimeContextDelimiters(text); @@ -86,10 +86,9 @@ function projectRuntimeContextMessages(messages: AgentMessage[]): AgentMessage[] if (details.success) { return { ...message, - content: buildRuntimeContextMessageContent({ - runtimeContext: projectRuntimeContextFragments(details.data.fragments), - kind: "next-turn", - }), + content: buildRuntimeContextMessageContent( + projectRuntimeContextFragments(details.data.fragments), + ), }; } } diff --git a/src/agents/embedded-agent-runner/run/attempt-prompt-build.ts b/src/agents/embedded-agent-runner/run/attempt-prompt-build.ts index e274a4361289..70399c79159e 100644 --- a/src/agents/embedded-agent-runner/run/attempt-prompt-build.ts +++ b/src/agents/embedded-agent-runner/run/attempt-prompt-build.ts @@ -54,7 +54,6 @@ import { } from "../tool-result-truncation.js"; import { normalizeCurrentPromptTextForLlmBoundary, - projectRuntimeContextFragments, usesEscapedRuntimeContext, normalizeMessagesForCurrentPromptBoundary, } from "./attempt-llm-boundary.js"; @@ -70,7 +69,6 @@ import { pruneProcessedHistoryImages } from "./history-image-prune.js"; import { buildCurrentInboundPrompt, buildRuntimeContextCustomMessage, - buildRuntimeContextMessageContent, resolveRuntimeContextPromptParts, type RuntimeContextCustomMessage, } from "./runtime-context-prompt.js"; @@ -405,7 +403,6 @@ export function prepareEmbeddedAttemptPromptContext(input: { prompt: PromptAssemblyContext; replaceSessionMessages: (messages: AgentMessage[]) => void; sessionAgentId: string; - setActiveSessionSystemPrompt: (systemPrompt: string) => void; systemPromptReport?: SessionSystemPromptReport; systemPromptText: string; toolResultPromptProjectionState: ToolResultPromptProjectionState; @@ -511,25 +508,7 @@ export function prepareEmbeddedAttemptPromptContext(input: { ...(promptForModel !== promptForSession ? { alternateText: promptForModel } : {}), } : undefined; - const runtimeSystemContext = promptSubmission.runtimeOnly - ? buildRuntimeContextMessageContent({ - runtimeContext: escapedProjection - ? projectRuntimeContextFragments(eventFragments) - : (promptSubmission.runtimeContext ?? ""), - kind: "runtime-event", - }) - : undefined; - let systemPromptForHook = input.systemPromptText; - if (promptSubmission.runtimeOnly && runtimeSystemContext) { - const runtimeSystemPrompt = composeSystemPromptWithHookContext({ - baseSystemPrompt: input.systemPromptText, - appendSystemContext: runtimeSystemContext, - }); - if (runtimeSystemPrompt) { - systemPromptForHook = runtimeSystemPrompt; - input.setActiveSessionSystemPrompt(runtimeSystemPrompt); - } - } + const systemPromptForHook = input.systemPromptText; const runtimeFacts = input.isRawModelRun || attempt.operation === "settled-tool-finalization" ? [] @@ -541,7 +520,7 @@ export function prepareEmbeddedAttemptPromptContext(input: { agentId: input.sessionAgentId, }); const contextFragments = promptSubmission.runtimeOnly - ? runtimeFacts + ? [...eventFragments, ...runtimeFacts] : [...fragments, ...runtimeFacts]; const runtimeContextForHook = contextFragments @@ -573,9 +552,7 @@ export function prepareEmbeddedAttemptPromptContext(input: { input.systemPromptReport.currentTurn = { ...(attempt.currentInboundEventKind ? { kind: attempt.currentInboundEventKind } : {}), promptChars: promptForModel.length, - runtimeContextChars: - (runtimeContextForHook?.length ?? 0) + - (promptSubmission.runtimeOnly ? (runtimeSystemContext?.length ?? 0) : 0), + runtimeContextChars: runtimeContextForHook?.length ?? 0, // Hook context reaches only the model, so count the delta beyond the // transcript prompt or downstream context accounting undercounts it. modelOnlyPromptChars: Math.max(0, promptForModel.length - promptForSession.length), diff --git a/src/agents/embedded-agent-runner/run/attempt-prompt-context.test.ts b/src/agents/embedded-agent-runner/run/attempt-prompt-context.test.ts index 2c2c6083145f..133d67c77910 100644 --- a/src/agents/embedded-agent-runner/run/attempt-prompt-context.test.ts +++ b/src/agents/embedded-agent-runner/run/attempt-prompt-context.test.ts @@ -96,7 +96,6 @@ function createInput(options?: { report?: SessionSystemPromptReport; }) { const replaceSessionMessages = vi.fn(); - const setActiveSessionSystemPrompt = vi.fn(); const report = options?.report ?? ({} as SessionSystemPromptReport); return { input: { @@ -111,14 +110,12 @@ function createInput(options?: { prompt: options?.prompt ?? createPrompt(), replaceSessionMessages, sessionAgentId: "agent-1", - setActiveSessionSystemPrompt, systemPromptReport: report, systemPromptText: "Base system prompt", toolResultPromptProjectionState: projectionState, }, replaceSessionMessages, report, - setActiveSessionSystemPrompt, }; } @@ -167,7 +164,6 @@ describe("prepareEmbeddedAttemptPromptContext", () => { ); expect(after.systemPromptForHook).toBe(before.systemPromptForHook); expect(after.promptForSession).toBe(before.promptForSession); - expect(fixture.setActiveSessionSystemPrompt).not.toHaveBeenCalled(); })); it("carries execution-owned processes in id order without elapsed time or output", () => { const fixture = createInput(); @@ -191,7 +187,6 @@ describe("prepareEmbeddedAttemptPromptContext", () => { text: expect.stringContaining("Active exec sessions:"), }); expect(active.promptForSession).toBe("Visible request"); - expect(fixture.setActiveSessionSystemPrompt).not.toHaveBeenCalled(); }); it("carries changed subagent status without rewriting the system prompt", () => { @@ -222,7 +217,6 @@ describe("prepareEmbeddedAttemptPromptContext", () => { expect(completed.runtimeContextMessageForCurrentTurn?.content).toContain( "## Active Subagents\nnone", ); - expect(fixture.setActiveSessionSystemPrompt).not.toHaveBeenCalled(); }); it("carries changed media progress without rewriting the system prompt", () => { @@ -248,7 +242,6 @@ describe("prepareEmbeddedAttemptPromptContext", () => { 'progress_json="Encoding"', ); expect(encoding.runtimeContextMessageForCurrentTurn?.content).not.toContain("Rendering"); - expect(fixture.setActiveSessionSystemPrompt).not.toHaveBeenCalled(); }); it("supersedes retained active facts with explicit empty snapshots", () => { @@ -353,7 +346,6 @@ describe("prepareEmbeddedAttemptPromptContext", () => { modelOnlyPromptChars: 0, }); expect(fixture.replaceSessionMessages).not.toHaveBeenCalled(); - expect(fixture.setActiveSessionSystemPrompt).not.toHaveBeenCalled(); expect(hoisted.reconcileToolResultPromptProjectionState).toHaveBeenCalledWith( messages, projectionState, @@ -443,7 +435,7 @@ describe("prepareEmbeddedAttemptPromptContext", () => { }); it.each([3, 4])( - "keeps version %s runtime-only events in system context with current facts", + "carries version %s runtime-only events in the message tail carrier without rewriting system prompt", (sessionVersion) => { const fixture = createInput({ attempt: createAttempt({ @@ -462,7 +454,9 @@ describe("prepareEmbeddedAttemptPromptContext", () => { fixture.input.capabilityToolNames.add("process"); const result = prepareEmbeddedAttemptPromptContext({ ...fixture.input, sessionVersion }); - expect(result.systemPromptForHook).toContain("OpenClaw runtime event."); + expect(result.systemPromptForHook).toBe("Base system prompt"); + expect(result.systemPromptForHook).not.toContain("OpenClaw runtime event."); + expect(result.systemPromptForHook).not.toContain("Runtime room event"); expect(result.promptSubmission.runtimeOnly).toBe(true); expect(result.promptForSession).toBe( "Room conversation data\n\nContinue the OpenClaw runtime event.", @@ -472,18 +466,40 @@ describe("prepareEmbeddedAttemptPromptContext", () => { expect(result.runtimeContextMessageForCurrentTurn?.content).toContain( "Active exec sessions:\nnone", ); - expect(result.runtimeContextMessageForCurrentTurn?.content).not.toContain( - "Runtime room event", - ); - expect(result.systemPromptForHook).toContain("Runtime room event"); - expect(fixture.setActiveSessionSystemPrompt).toHaveBeenCalledWith( - expect.stringContaining("Runtime room event"), - ); + expect(result.runtimeContextMessageForCurrentTurn?.content).toContain("Runtime room event"); expect(fixture.report.currentTurn?.kind).toBe("room_event"); expect(fixture.report.currentTurn?.runtimeContextChars).toBeGreaterThan(0); }, ); + it("preserves identical system prompt bytes across normal turns and runtime-only event turns", () => { + const fixture = createInput(); + const normalTurn = prepareEmbeddedAttemptPromptContext(fixture.input); + + const runtimeEventFixture = createInput({ + attempt: createAttempt({ + runtimeContextFragments: [ + { kind: "runtime-instruction", text: "Subagent completed task 42" }, + ], + currentInboundEventKind: "room_event", + }), + prompt: createPrompt({ + effectivePrompt: "", + effectiveTranscriptPrompt: "", + }), + }); + const runtimeTurn = prepareEmbeddedAttemptPromptContext(runtimeEventFixture.input); + + const normalTurnAfter = prepareEmbeddedAttemptPromptContext(fixture.input); + + expect(normalTurn.systemPromptForHook).toBe("Base system prompt"); + expect(runtimeTurn.systemPromptForHook).toBe(normalTurn.systemPromptForHook); + expect(normalTurnAfter.systemPromptForHook).toBe(normalTurn.systemPromptForHook); + expect(runtimeTurn.runtimeContextMessageForCurrentTurn?.content).toContain( + "Subagent completed task 42", + ); + }); + it("keeps a pure heartbeat task active while persisting only the poll marker", () => { const taskPrompt = "Check the deployment and report any failures."; const transcriptPrompt = "[OpenClaw heartbeat poll]"; diff --git a/src/agents/embedded-agent-runner/run/attempt-prompt-phase.ts b/src/agents/embedded-agent-runner/run/attempt-prompt-phase.ts index 8b5992354edf..27bdc1ceb29b 100644 --- a/src/agents/embedded-agent-runner/run/attempt-prompt-phase.ts +++ b/src/agents/embedded-agent-runner/run/attempt-prompt-phase.ts @@ -193,7 +193,6 @@ export async function runEmbeddedAttemptPromptPhase( isRawModelRun, ...(preparedUserTurnMessage ? { preparedUserTurnMessage } : {}), sessionAgentId, - setActiveSessionSystemPrompt, ...(systemPromptReport ? { systemPromptReport } : {}), systemPromptText, toolResultPromptProjectionState, diff --git a/src/agents/embedded-agent-runner/run/attempt.media-hint-cache-boundary.test.ts b/src/agents/embedded-agent-runner/run/attempt.media-hint-cache-boundary.test.ts index 1871c62593cf..c35e19ce6613 100644 --- a/src/agents/embedded-agent-runner/run/attempt.media-hint-cache-boundary.test.ts +++ b/src/agents/embedded-agent-runner/run/attempt.media-hint-cache-boundary.test.ts @@ -128,7 +128,6 @@ async function createTurnFixture(systemPromptOverride?: string) { includeBoundaryTimestamp: false, isRawModelRun: false, sessionAgentId: "main", - setActiveSessionSystemPrompt, systemPromptText, toolResultPromptProjectionState: { replacements: new Map(), diff --git a/src/agents/embedded-agent-runner/run/attempt.spawn-workspace.context-engine.test.ts b/src/agents/embedded-agent-runner/run/attempt.spawn-workspace.context-engine.test.ts index 1f526da971c8..e89cae0d3d52 100644 --- a/src/agents/embedded-agent-runner/run/attempt.spawn-workspace.context-engine.test.ts +++ b/src/agents/embedded-agent-runner/run/attempt.spawn-workspace.context-engine.test.ts @@ -1905,7 +1905,7 @@ describe("runEmbeddedAttempt context engine sessionKey forwarding", () => { ); }); - it("submits runtime-only context through system prompt without visible prompt", async () => { + it("submits runtime-only context through the tail carrier without visible prompt", async () => { hoisted.sessionManager.getHeader.mockReturnValue({ version: 4 }); let seenPrompt: string | undefined; let seenModelMessages: unknown[] | undefined; @@ -1963,7 +1963,7 @@ describe("runEmbeddedAttempt context engine sessionKey forwarding", () => { expect(contextCompiled?.data?.prompt).toContain("dynamic hook context"); expect(contextCompiled?.data?.prompt).toContain("internal heartbeat event"); expect(contextCompiled?.data?.prompt).toContain("dynamic hook tail"); - expect(contextCompiled?.data?.systemPrompt).toContain("internal heartbeat event"); + expect(contextCompiled?.data?.systemPrompt).not.toContain("internal heartbeat event"); expect(contextCompiled?.data?.systemPrompt).not.toContain("dynamic hook context"); expect(contextCompiled?.data?.systemPrompt).not.toContain("dynamic hook tail"); }); @@ -2061,7 +2061,8 @@ describe("runEmbeddedAttempt context engine sessionKey forwarding", () => { const trajectoryEvents = await readTrajectoryEvents(tempPaths); const contextCompiled = trajectoryEvents.find((event) => event.type === "context.compiled"); expect(contextCompiled?.data?.prompt).toContain("Hello from the replied message"); - expect(contextCompiled?.data?.systemPrompt).toContain("runtime bare mention event"); + expect(contextCompiled?.data?.prompt).toContain("runtime bare mention event"); + expect(contextCompiled?.data?.systemPrompt).not.toContain("runtime bare mention event"); expect(contextCompiled?.data?.systemPrompt).not.toContain("Hello from the replied message"); expect(contextCompiled?.data?.systemPrompt).not.toContain( "Reply target of current user message:", diff --git a/src/agents/embedded-agent-runner/run/runtime-context-prompt.test.ts b/src/agents/embedded-agent-runner/run/runtime-context-prompt.test.ts index d0ef4cd0dfa6..a3002d45cab1 100644 --- a/src/agents/embedded-agent-runner/run/runtime-context-prompt.test.ts +++ b/src/agents/embedded-agent-runner/run/runtime-context-prompt.test.ts @@ -48,7 +48,7 @@ describe("runtime context prompt submission", () => { ).toEqual({ prompt: "[OpenClaw heartbeat poll]", modelPrompt: "Check the deployment." }); }); - it("requires producer context for runtime-only system context", () => { + it("requires producer context for the runtime-only continuation prompt", () => { const fragments = [ { kind: "runtime-instruction" as const, text: "Continue the background task." }, ]; diff --git a/src/agents/embedded-agent-runner/run/runtime-context-prompt.ts b/src/agents/embedded-agent-runner/run/runtime-context-prompt.ts index f9896851ccac..da5be131e7b2 100644 --- a/src/agents/embedded-agent-runner/run/runtime-context-prompt.ts +++ b/src/agents/embedded-agent-runner/run/runtime-context-prompt.ts @@ -6,8 +6,6 @@ import { INTERNAL_RUNTIME_CONTEXT_BEGIN, INTERNAL_RUNTIME_CONTEXT_END, OPENCLAW_RUNTIME_CONTEXT_CUSTOM_TYPE, - OPENCLAW_RUNTIME_CONTEXT_NOTICE, - OPENCLAW_RUNTIME_EVENT_HEADER, type RuntimeContextFragment, } from "../../internal-runtime-context.js"; import type { CurrentInboundPromptContext } from "./params.js"; @@ -89,22 +87,9 @@ export function resolveRuntimeContextPromptParts(params: { }; } -export function buildRuntimeContextMessageContent(params: { - runtimeContext: string; - kind: "next-turn" | "runtime-event"; -}): string { - // Next-turn carriers carry only the delimited body: the stable system prompt - // explains the markers once, and the delimiters are what hasInternalRuntimeContext - // and the leak strippers key on. Runtime events keep their preface because the - // model receives no user message alongside them. - return [ - ...(params.kind === "runtime-event" - ? [OPENCLAW_RUNTIME_EVENT_HEADER, OPENCLAW_RUNTIME_CONTEXT_NOTICE, ""] - : []), - INTERNAL_RUNTIME_CONTEXT_BEGIN, - params.runtimeContext, - INTERNAL_RUNTIME_CONTEXT_END, - ].join("\n"); +export function buildRuntimeContextMessageContent(runtimeContext: string): string { + // The stable system prompt explains the markers once; leak strippers use the delimiters. + return [INTERNAL_RUNTIME_CONTEXT_BEGIN, runtimeContext, INTERNAL_RUNTIME_CONTEXT_END].join("\n"); } /** Creates a non-displayed custom transcript message for runtime context, if any exists. */ @@ -119,10 +104,7 @@ export function buildRuntimeContextCustomMessage( return { role: "custom", customType: OPENCLAW_RUNTIME_CONTEXT_CUSTOM_TYPE, - content: buildRuntimeContextMessageContent({ - runtimeContext: trimmedRuntimeContext, - kind: "next-turn", - }), + content: buildRuntimeContextMessageContent(trimmedRuntimeContext), display: false, details: { source: "openclaw-runtime-context", @@ -148,10 +130,7 @@ export function prependRuntimeContextForModel( const prepend = (text: string) => text.startsWith(`${INTERNAL_RUNTIME_CONTEXT_BEGIN}\n`) ? `${INTERNAL_RUNTIME_CONTEXT_BEGIN}\n${runtimeContext}\n\n${text.slice(INTERNAL_RUNTIME_CONTEXT_BEGIN.length + 1)}` - : buildRuntimeContextMessageContent({ - runtimeContext: [runtimeContext, text].filter(Boolean).join("\n\n"), - kind: "next-turn", - }); + : buildRuntimeContextMessageContent([runtimeContext, text].filter(Boolean).join("\n\n")); if (carrier?.role !== "user") { return [ ...messages, diff --git a/src/agents/embedded-agent-runner/tool-result-truncation.test.ts b/src/agents/embedded-agent-runner/tool-result-truncation.test.ts index ded86b7b42a0..ae00c651183f 100644 --- a/src/agents/embedded-agent-runner/tool-result-truncation.test.ts +++ b/src/agents/embedded-agent-runner/tool-result-truncation.test.ts @@ -131,7 +131,6 @@ function preparePromptProjectionStateForTest(params: { }, replaceSessionMessages: () => {}, sessionAgentId: "main", - setActiveSessionSystemPrompt: () => {}, systemPromptText: params.raw ? "" : "system", toolResultPromptProjectionState: params.state, }); diff --git a/src/agents/harness/selection.test.ts b/src/agents/harness/selection.test.ts index 398ed33a8f08..e130ba6f3baf 100644 --- a/src/agents/harness/selection.test.ts +++ b/src/agents/harness/selection.test.ts @@ -57,7 +57,6 @@ import { publishCurrentModelGeneration, resetModelGenerationFixtureState, } from "../embedded-agent-runner/model.generation-scope.test-support.js"; -import { projectRuntimeContextFragments } from "../embedded-agent-runner/run/attempt-llm-boundary.js"; import type { EmbeddedRunAttemptParams, EmbeddedRunAttemptResult, @@ -641,7 +640,7 @@ describe("runAgentHarnessAttempt", () => { ...currentInboundContext.fragments, { kind: "heartbeat-outcome", text: expect.stringContaining("ISOLATED_OUTCOME_731") }, ]); - expect(projectRuntimeContextFragments(fragments ?? [])).toContain("ISOLATED_OUTCOME_731"); + expect(JSON.stringify(fragments)).toContain("ISOLATED_OUTCOME_731"); expect(received?.prompt).toBe("hello"); expect(params.currentInboundContext).toEqual(currentInboundContext); expect(currentInboundContext.text).toBe("Current quoted reply"); diff --git a/src/agents/internal-runtime-context.test.ts b/src/agents/internal-runtime-context.test.ts index d472d29411ee..c903c32839c5 100644 --- a/src/agents/internal-runtime-context.test.ts +++ b/src/agents/internal-runtime-context.test.ts @@ -12,7 +12,6 @@ import { INTERNAL_RUNTIME_CONTEXT_END, OPENCLAW_RUNTIME_CONTEXT_CUSTOM_TYPE, OPENCLAW_RUNTIME_CONTEXT_NOTICE, - OPENCLAW_RUNTIME_EVENT_HEADER, relocateCurrentRuntimeContextCarrierToTail, stripInternalRuntimeContext, } from "./internal-runtime-context.js"; @@ -126,7 +125,7 @@ describe("internal runtime context codec", () => { "previous current turn", "OpenClaw runtime context for the immediately preceding user message.", ], - ["runtime event", OPENCLAW_RUNTIME_EVENT_HEADER], + ["runtime event", "OpenClaw runtime event."], ])("detects and strips the %s prompt preface", (_name, header) => { const preface = [header, OPENCLAW_RUNTIME_CONTEXT_NOTICE].join("\n"); const input = [ diff --git a/src/agents/internal-runtime-context.ts b/src/agents/internal-runtime-context.ts index 031048eb9309..761077ffe89f 100644 --- a/src/agents/internal-runtime-context.ts +++ b/src/agents/internal-runtime-context.ts @@ -16,8 +16,6 @@ const ESCAPED_INTERNAL_RUNTIME_CONTEXT_END = "[[OPENCLAW_INTERNAL_CONTEXT_END]]" /** Notice inserted into runtime-generated context blocks. */ export const OPENCLAW_RUNTIME_CONTEXT_NOTICE = "This context is runtime-generated, not user-authored. Keep internal details private."; -/** Header for runtime events passed as prompt context. */ -export const OPENCLAW_RUNTIME_EVENT_HEADER = "OpenClaw runtime event."; /** Custom message type used for structured runtime-context messages. */ export const OPENCLAW_RUNTIME_CONTEXT_CUSTOM_TYPE = "openclaw.runtime-context"; @@ -215,7 +213,7 @@ function stripLegacyInternalRuntimeContext(text: string): string { const RUNTIME_CONTEXT_PROMPT_HEADERS: readonly string[] = [ "OpenClaw runtime context for the active user request in this turn. Do not reply to or describe this context. Use it to continue answering the active user request now. Do not wait for another message.", "OpenClaw runtime context for the immediately preceding user message.", - OPENCLAW_RUNTIME_EVENT_HEADER, + "OpenClaw runtime event.", ]; const RUNTIME_CONTEXT_NOTICE_PATTERN = new RegExp(