Skip to content

Commit 7fb0d45

Browse files
fix(agents): add usage guidance to sessions_spawn tool description (fixes #91814) (#91824)
* fix(agents): add usage guidance to sessions_spawn tool description (fixes #91814) * fix(agents): tighten sessions spawn guidance --------- Co-authored-by: Vincent Koc <[email protected]>
1 parent 8ae1adf commit 7fb0d45

8 files changed

Lines changed: 40 additions & 16 deletions

src/agents/tool-description-presets.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ export function describeSessionsSpawnTool(options?: {
4545
options?.acpAvailable === false
4646
? 'Spawn clean child session; default `runtime="subagent"`.'
4747
: 'Spawn clean child session; default `runtime="subagent"`; set `runtime="acp"` explicitly for ACP.';
48+
const sessionCompletionGuidance =
49+
options?.acpAvailable === false
50+
? "After spawning, do non-overlapping work; run-mode results return, session-mode output stays in thread."
51+
: 'After spawning, do non-overlapping work; run-mode results return, session-mode output stays in thread unless ACP uses `streamTo="parent"`.';
52+
const completionGuidance = options?.threadAvailable
53+
? sessionCompletionGuidance
54+
: "After spawning, do non-overlapping work while run-mode results return.";
4855
const baseDescription = [
4956
runtimeDescription,
5057
options?.threadAvailable
@@ -54,6 +61,9 @@ export function describeSessionsSpawnTool(options?: {
5461
"Native subagents get task in first visible `[Subagent Task]` message.",
5562
'Native only: `context="fork"` only when child needs current transcript; else omit or `isolated`.',
5663
"Use for fresh child-session work.",
64+
"Delegate sidecar/parallel tasks: batch file reads, multi-step searches, data collection.",
65+
"Avoid delegating quick lookups or single-file reads unless policy prefers delegation.",
66+
completionGuidance,
5767
];
5868
if (options?.acpAvailable === false) {
5969
return baseDescription.join(" ");

src/agents/tools/sessions-spawn-tool.test.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,19 @@ describe("sessions_spawn tool", () => {
132132
it("advertises ACP runtime affordances when an ACP backend is loaded", () => {
133133
registerAcpBackendForTest();
134134

135-
const tool = createSessionsSpawnTool();
135+
const tool = createSessionsSpawnTool({
136+
agentChannel: "discord",
137+
agentAccountId: "default",
138+
config: {
139+
channels: {
140+
discord: {
141+
threadBindings: {
142+
spawnSessions: true,
143+
},
144+
},
145+
},
146+
},
147+
});
136148
const schema = tool.parameters as {
137149
properties?: {
138150
runtime?: { enum?: string[] };
@@ -143,6 +155,7 @@ describe("sessions_spawn tool", () => {
143155

144156
expect(tool.displaySummary).toBe("Spawn subagent or ACP session.");
145157
expect(tool.description).toContain('runtime="acp"');
158+
expect(tool.description).toContain('unless ACP uses `streamTo="parent"`');
146159
expect(schema.properties?.runtime?.enum).toEqual(["subagent", "acp"]);
147160
const resumeSessionId = requireSchemaProperty(schema.properties, "resumeSessionId");
148161
const streamTo = requireSchemaProperty(schema.properties, "streamTo");
@@ -259,6 +272,7 @@ describe("sessions_spawn tool", () => {
259272
expect(schema.properties?.thread).toBeUndefined();
260273
expect(schema.properties?.mode?.enum).toEqual(["run"]);
261274
expect(tool.description).not.toContain("thread-bound");
275+
expect(tool.description).not.toContain("session-mode output stays in thread");
262276
});
263277

264278
it("shows thread-bound spawn fields when current channel allows spawnSessions", () => {

test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.discord-group.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1095,7 +1095,7 @@
10951095
},
10961096
{
10971097
"deferLoading": true,
1098-
"description": "Spawn clean child session; default `runtime=\"subagent\"`. `mode=\"run\"` one-shot; `mode=\"session\"` persistent/thread-bound, only when requester channel supports thread bindings. Subagents inherit parent workspace. Native subagents get task in first visible `[Subagent Task]` message. Native only: `context=\"fork\"` only when child needs current transcript; else omit or `isolated`. Use for fresh child-session work.",
1098+
"description": "Spawn clean child session; default `runtime=\"subagent\"`. `mode=\"run\"` one-shot; `mode=\"session\"` persistent/thread-bound, only when requester channel supports thread bindings. Subagents inherit parent workspace. Native subagents get task in first visible `[Subagent Task]` message. Native only: `context=\"fork\"` only when child needs current transcript; else omit or `isolated`. Use for fresh child-session work. Delegate sidecar/parallel tasks: batch file reads, multi-step searches, data collection. Avoid delegating quick lookups or single-file reads unless policy prefers delegation. After spawning, do non-overlapping work; run-mode results return, session-mode output stays in thread.",
10991099
"inputSchema": {
11001100
"properties": {
11011101
"agentId": {

test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.heartbeat-turn.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1131,7 +1131,7 @@
11311131
},
11321132
{
11331133
"deferLoading": true,
1134-
"description": "Spawn clean child session; default `runtime=\"subagent\"`. `mode=\"run\"` one-shot background work. Subagents inherit parent workspace. Native subagents get task in first visible `[Subagent Task]` message. Native only: `context=\"fork\"` only when child needs current transcript; else omit or `isolated`. Use for fresh child-session work.",
1134+
"description": "Spawn clean child session; default `runtime=\"subagent\"`. `mode=\"run\"` one-shot background work. Subagents inherit parent workspace. Native subagents get task in first visible `[Subagent Task]` message. Native only: `context=\"fork\"` only when child needs current transcript; else omit or `isolated`. Use for fresh child-session work. Delegate sidecar/parallel tasks: batch file reads, multi-step searches, data collection. Avoid delegating quick lookups or single-file reads unless policy prefers delegation. After spawning, do non-overlapping work while run-mode results return.",
11351135
"inputSchema": {
11361136
"properties": {
11371137
"agentId": {

test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.telegram-direct.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1095,7 +1095,7 @@
10951095
},
10961096
{
10971097
"deferLoading": true,
1098-
"description": "Spawn clean child session; default `runtime=\"subagent\"`. `mode=\"run\"` one-shot background work. Subagents inherit parent workspace. Native subagents get task in first visible `[Subagent Task]` message. Native only: `context=\"fork\"` only when child needs current transcript; else omit or `isolated`. Use for fresh child-session work.",
1098+
"description": "Spawn clean child session; default `runtime=\"subagent\"`. `mode=\"run\"` one-shot background work. Subagents inherit parent workspace. Native subagents get task in first visible `[Subagent Task]` message. Native only: `context=\"fork\"` only when child needs current transcript; else omit or `isolated`. Use for fresh child-session work. Delegate sidecar/parallel tasks: batch file reads, multi-step searches, data collection. Avoid delegating quick lookups or single-file reads unless policy prefers delegation. After spawning, do non-overlapping work while run-mode results return.",
10991099
"inputSchema": {
11001100
"properties": {
11011101
"agentId": {

test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/discord-group-codex-message-tool.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
223223
"roughTokens": 0
224224
},
225225
"dynamicToolsJson": {
226-
"chars": 44966,
227-
"roughTokens": 11242
226+
"chars": 45244,
227+
"roughTokens": 11311
228228
},
229229
"openClawDeveloperInstructions": {
230230
"chars": 2988,
@@ -235,8 +235,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
235235
"roughTokens": 6925
236236
},
237237
"totalWithDynamicToolsJson": {
238-
"chars": 72668,
239-
"roughTokens": 18167
238+
"chars": 72946,
239+
"roughTokens": 18237
240240
},
241241
"userInputText": {
242242
"chars": 1629,

test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/telegram-direct-codex-message-tool.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
223223
"roughTokens": 0
224224
},
225225
"dynamicToolsJson": {
226-
"chars": 44687,
227-
"roughTokens": 11172
226+
"chars": 44933,
227+
"roughTokens": 11234
228228
},
229229
"openClawDeveloperInstructions": {
230230
"chars": 1964,
@@ -235,8 +235,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
235235
"roughTokens": 6544
236236
},
237237
"totalWithDynamicToolsJson": {
238-
"chars": 70865,
239-
"roughTokens": 17717
238+
"chars": 71111,
239+
"roughTokens": 17778
240240
},
241241
"userInputText": {
242242
"chars": 1129,

test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/telegram-heartbeat-codex-tool.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
224224
"roughTokens": 0
225225
},
226226
"dynamicToolsJson": {
227-
"chars": 45782,
228-
"roughTokens": 11446
227+
"chars": 46028,
228+
"roughTokens": 11507
229229
},
230230
"openClawDeveloperInstructions": {
231231
"chars": 1983,
@@ -236,8 +236,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
236236
"roughTokens": 6780
237237
},
238238
"totalWithDynamicToolsJson": {
239-
"chars": 72903,
240-
"roughTokens": 18226
239+
"chars": 73149,
240+
"roughTokens": 18288
241241
},
242242
"userInputText": {
243243
"chars": 1367,

0 commit comments

Comments
 (0)