Skip to content

Commit 78c6674

Browse files
fix(agents): expose session identity in runtime prompts
Expose session key and stable session id in Runtime prompt metadata for embedded, CLI-backed, and command-generated agent prompts so agents do not infer session identity. Fixes #92453.
1 parent 4c23d1d commit 78c6674

11 files changed

Lines changed: 74 additions & 2 deletions

src/agents/cli-runner/helpers.system-prompt.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,19 @@ describe("buildCliAgentSystemPrompt", () => {
9191
expect(prompt).toContain("CLI-only command guidance.");
9292
expect(prompt).not.toContain("OpenClaw-only command guidance.");
9393
});
94+
95+
it("includes session identity in runtime when provided", () => {
96+
const prompt = buildCliAgentSystemPrompt({
97+
workspaceDir: "/tmp/openclaw",
98+
tools: [],
99+
modelDisplay: "test/model",
100+
agentId: "main",
101+
sessionKey: "agent:main:telegram:direct:peer",
102+
sessionId: "session-123",
103+
});
104+
105+
expect(prompt).toContain("agent=main");
106+
expect(prompt).toContain("session=agent:main:telegram:direct:peer");
107+
expect(prompt).toContain("sessionId=session-123");
108+
});
94109
});

src/agents/cli-runner/helpers.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ export function buildCliAgentSystemPrompt(params: {
128128
skillsPrompt?: string;
129129
modelDisplay: string;
130130
agentId?: string;
131+
sessionKey?: string;
132+
sessionId?: string;
131133
}) {
132134
const runtimeWorkspaceDir = params.cwd?.trim() || params.workspaceDir;
133135
const defaultModelRef = resolveDefaultModelForAgent({
@@ -141,6 +143,8 @@ export function buildCliAgentSystemPrompt(params: {
141143
workspaceDir: runtimeWorkspaceDir,
142144
cwd: runtimeWorkspaceDir,
143145
runtime: {
146+
sessionKey: params.sessionKey,
147+
sessionId: params.sessionId,
144148
host: "openclaw",
145149
os: `${os.type()} ${os.release()}`,
146150
arch: os.arch(),

src/agents/cli-runner/prepare.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,8 @@ export async function prepareCliRunContext(
552552
contextFiles,
553553
modelDisplay,
554554
agentId: sessionAgentId,
555+
sessionKey: params.sessionKey,
556+
sessionId: params.sessionId,
555557
});
556558
const transformedSystemPrompt =
557559
backendResolved.transformSystemPrompt?.({

src/agents/embedded-agent-runner/run/attempt.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1802,6 +1802,8 @@ export async function runEmbeddedAttempt(
18021802
workspaceDir: effectiveWorkspace,
18031803
cwd: effectiveCwd,
18041804
runtime: {
1805+
sessionKey: params.sessionKey,
1806+
sessionId: params.sessionId,
18051807
host: machineName,
18061808
os: `${os.type()} ${os.release()}`,
18071809
arch: os.arch(),

src/agents/embedded-agent-runner/system-prompt.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ export function buildEmbeddedSystemPrompt(params: {
5757
nativeCommandGuidanceLines?: string[];
5858
runtimeInfo: {
5959
agentId?: string;
60+
sessionKey?: string;
61+
sessionId?: string;
6062
host: string;
6163
os: string;
6264
arch: string;

src/agents/system-prompt-params.test.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ function buildParams(params: { config?: OpenClawConfig; workspaceDir?: string; c
3030
});
3131
}
3232

33-
describe("buildSystemPromptParams repo root", () => {
33+
describe("buildSystemPromptParams", () => {
3434
it("detects repo root from workspaceDir", async () => {
3535
const temp = await makeTempDir("workspace");
3636
const repoRoot = path.join(temp, "repo");
@@ -105,4 +105,22 @@ describe("buildSystemPromptParams repo root", () => {
105105

106106
expect(runtimeInfo.repoRoot).toBeUndefined();
107107
});
108+
109+
it("carries session identity into runtime info", () => {
110+
const { runtimeInfo } = buildSystemPromptParams({
111+
agentId: "main",
112+
runtime: {
113+
sessionKey: "agent:main:main",
114+
sessionId: "23ae7fce-3c27-4a51-b58e-d800d8ca091f",
115+
host: "host",
116+
os: "os",
117+
arch: "arch",
118+
node: "node",
119+
model: "model",
120+
},
121+
});
122+
123+
expect(runtimeInfo.sessionKey).toBe("agent:main:main");
124+
expect(runtimeInfo.sessionId).toBe("23ae7fce-3c27-4a51-b58e-d800d8ca091f");
125+
});
108126
});

src/agents/system-prompt-params.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import {
1919

2020
type RuntimeInfoInput = {
2121
agentId?: string;
22+
sessionKey?: string;
23+
sessionId?: string;
2224
host: string;
2325
os: string;
2426
arch: string;

src/agents/system-prompt.test.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1129,11 +1129,13 @@ describe("buildAgentSystemPrompt", () => {
11291129
expect(prompt).not.toContain("capabilities= InlineButtons ,voice,inlinebuttons,Voice");
11301130
});
11311131

1132-
it("includes agent id in runtime when provided", () => {
1132+
it("includes agent and session identity in runtime when provided", () => {
11331133
const prompt = buildAgentSystemPrompt({
11341134
workspaceDir: "/tmp/openclaw",
11351135
runtimeInfo: {
11361136
agentId: "work",
1137+
sessionKey: "agent:main:main",
1138+
sessionId: "23ae7fce-3c27-4a51-b58e-d800d8ca091f",
11371139
host: "host",
11381140
os: "macOS",
11391141
arch: "arm64",
@@ -1143,6 +1145,8 @@ describe("buildAgentSystemPrompt", () => {
11431145
});
11441146

11451147
expect(prompt).toContain("agent=work");
1148+
expect(prompt).toContain("session=agent:main:main");
1149+
expect(prompt).toContain("sessionId=23ae7fce-3c27-4a51-b58e-d800d8ca091f");
11461150
});
11471151

11481152
it("includes reasoning visibility hint", () => {
@@ -1160,6 +1164,8 @@ describe("buildAgentSystemPrompt", () => {
11601164
const line = buildRuntimeLine(
11611165
{
11621166
agentId: "work",
1167+
sessionKey: "agent:main:subagent:runtime-check",
1168+
sessionId: "23ae7fce-3c27-4a51-b58e-d800d8ca091f",
11631169
host: "host",
11641170
repoRoot: "/repo",
11651171
os: "macOS",
@@ -1174,6 +1180,8 @@ describe("buildAgentSystemPrompt", () => {
11741180
);
11751181

11761182
expect(line).toContain("agent=work");
1183+
expect(line).toContain("session=agent:main:subagent:runtime-check");
1184+
expect(line).toContain("sessionId=23ae7fce-3c27-4a51-b58e-d800d8ca091f");
11771185
expect(line).toContain("host=host");
11781186
expect(line).toContain("repo=/repo");
11791187
expect(line).toContain("os=macOS (arm64)");

src/agents/system-prompt.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,8 @@ export function buildAgentSystemPrompt(params: {
709709
nativeCommandGuidanceLines?: string[];
710710
runtimeInfo?: {
711711
agentId?: string;
712+
sessionKey?: string;
713+
sessionId?: string;
712714
host?: string;
713715
os?: string;
714716
arch?: string;
@@ -1349,6 +1351,8 @@ function buildActiveProcessSessionReferenceLines(
13491351
export function buildRuntimeLine(
13501352
runtimeInfo?: {
13511353
agentId?: string;
1354+
sessionKey?: string;
1355+
sessionId?: string;
13521356
host?: string;
13531357
os?: string;
13541358
arch?: string;
@@ -1366,6 +1370,8 @@ export function buildRuntimeLine(
13661370
const normalizedRuntimeCapabilities = normalizePromptCapabilityIds(runtimeCapabilities);
13671371
return `Runtime: ${[
13681372
runtimeInfo?.agentId ? `agent=${runtimeInfo.agentId}` : "",
1373+
runtimeInfo?.sessionKey ? `session=${sanitizeForPromptLiteral(runtimeInfo.sessionKey)}` : "",
1374+
runtimeInfo?.sessionId ? `sessionId=${sanitizeForPromptLiteral(runtimeInfo.sessionId)}` : "",
13691375
runtimeInfo?.host ? `host=${runtimeInfo.host}` : "",
13701376
runtimeInfo?.repoRoot ? `repo=${runtimeInfo.repoRoot}` : "",
13711377
runtimeInfo?.os

src/auto-reply/reply/commands-system-prompt.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
ensureSandboxWorkspaceForSession,
1111
resolveSandboxRuntimeStatus,
1212
} from "../../agents/sandbox.js";
13+
import { buildSystemPromptParams } from "../../agents/system-prompt-params.js";
1314
import { buildAgentSystemPrompt } from "../../agents/system-prompt.js";
1415
import { resolveReusableWorkspaceSkillSnapshot } from "../../skills/runtime/session-snapshot.js";
1516
import { resolveCommandsSystemPromptBundle } from "./commands-system-prompt.js";
@@ -229,6 +230,16 @@ describe("resolveCommandsSystemPromptBundle", () => {
229230
"resolveBootstrapContextForRun",
230231
);
231232
expect(bootstrapParams.sessionId).toBe("target-session");
233+
const runtimeParams = requireFirstArg(
234+
vi.mocked(buildSystemPromptParams),
235+
"buildSystemPromptParams",
236+
);
237+
expect(runtimeParams.runtime).toEqual(
238+
expect.objectContaining({
239+
sessionKey: "agent:target:telegram:direct:target-session",
240+
sessionId: "target-session",
241+
}),
242+
);
232243
const toolParams = requireFirstArg(
233244
vi.mocked(createOpenClawCodingTools),
234245
"createOpenClawCodingTools",

0 commit comments

Comments
 (0)