fix: avoid defaulting internal work to subagents (#151599)

* fix: avoid defaulting internal work to subagents

* test: refresh delegation prompt snapshots

* test: retain reconnect snapshot for superseding history reads
This commit is contained in:
Josh Lehman 2026-10-01 12:15:41 -07:00 • committed by GitHub
parent 2b7937b3b3
commit 4359fb6ca9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 34 additions and 34 deletions

View file

@ -232,7 +232,7 @@ describe("createOpenClawCodingTools availability guidance", () => {
expect(tool?.description).toContain("configured agent (see agents_list);");
expect(tool?.description).toContain("sessions_history");
expect(tool?.description).not.toContain("agents_wait");
expect(tool?.description).not.toContain("subagents");
expect(tool?.description).not.toContain("`subagents`");
expect(tool?.description).toContain("persistent/thread-bound");
expect(tool?.description).toContain("(self: current session only)");
expect(tool?.description).not.toContain('runtime="acp"');
@ -251,7 +251,7 @@ describe("createOpenClawCodingTools availability guidance", () => {
] as AnyAgentTool[]);
expect(tool?.description).toContain(
"Default to a hidden subagent for internal QA, research, coding, review, tests, and parallel work supporting the current task. This includes substantial, bounded API/service investigations that can be handed off with the needed context and capabilities. Omit `visible` or set it false, and report results through the parent.",
"Execute work directly by default. Delegate a bounded, independent task only when parallel execution or an independent review provides a concrete benefit. Keep dependent steps with the same owner. Once delegation is appropriate, use a hidden subagent unless the user needs a separate, independently steerable session. This includes substantial, bounded API/service investigations that can be handed off with the needed context and capabilities. For hidden subagents, omit `visible` or set it false, and report results through the parent.",
);
expect(tool?.description).not.toContain("trial-and-error");
expect(tool?.description).toContain("configured agent (see agents_list);");

View file

@ -987,7 +987,7 @@ describe("system prompt memory and runtime cache boundary", () => {
expect(next.prefix).toBe(first.prefix);
expect(first.prefix).toContain("## Care");
expect(first.prefix).toContain(
"Large work: `sessions_spawn`; follow the accepted completion mode.",
"Execute work directly by default. Delegate a bounded, independent task only when parallel execution or an independent review provides a concrete benefit. Keep dependent steps with the same owner.",
);
expect(first.prefix).not.toContain("## Proactive Sub-Agent Orchestration");
expect(first.suffix).not.toContain("Ultra active");

View file

@ -815,9 +815,9 @@ export function buildAgentSystemPrompt(params: {
: []),
...(hasSessionsSpawn
? [
"Large work: `sessions_spawn`; follow the accepted completion mode.",
'`sessions_spawn`: clean context => `context:"isolated"`; transcript needed => `context:"fork"`.',
"Default to subagents for internal work; use `visible:true` only for a separate session the user requests or needs to revisit and steer independently.",
"Execute work directly by default. Delegate a bounded, independent task only when parallel execution or an independent review provides a concrete benefit. Keep dependent steps with the same owner.",
'`sessions_spawn`: clean context => `context:"isolated"`; transcript needed => `context:"fork"`. Follow the accepted completion mode.',
"Once delegation is appropriate, use a hidden subagent unless the user needs a separate, independently steerable session.",
]
: []),
...(availableTools.has("screen")

View file

@ -95,7 +95,7 @@ describe("sessions_spawn delegation guidance", () => {
it("bounds API investigation handoffs without delegating quick lookups", () => {
const description = describeSessionsSpawnTool();
expect(description).toContain(
"Default to a hidden subagent for internal QA, research, coding, review, tests, and parallel work supporting the current task. This includes substantial, bounded API/service investigations that can be handed off with the needed context and capabilities. Omit `visible` or set it false, and report results through the parent.",
"Execute work directly by default. Delegate a bounded, independent task only when parallel execution or an independent review provides a concrete benefit. Keep dependent steps with the same owner. Once delegation is appropriate, use a hidden subagent unless the user needs a separate, independently steerable session. This includes substantial, bounded API/service investigations that can be handed off with the needed context and capabilities. For hidden subagents, omit `visible` or set it false, and report results through the parent.",
);
expect(description).toContain(
"A PR/report, long runtime, or isolated worktree alone does not justify a sidebar session. A request for a subagent does not request a separate session. No spawn for quick lookup/single read.",

View file

@ -148,7 +148,7 @@ export function describeSessionsSpawnTool(options?: {
? '`mode="run"` one-shot; `mode="session"` persistent/thread-bound only on supporting requester channel.'
: '`mode="run"` one-shot background.',
"`agentId` targets a configured agent; `model` overrides its model; `cleanup` delete|keep hidden child session; `sandbox` inherit|require.",
"Default to a hidden subagent for internal QA, research, coding, review, tests, and parallel work supporting the current task. This includes substantial, bounded API/service investigations that can be handed off with the needed context and capabilities. Omit `visible` or set it false, and report results through the parent.",
"Execute work directly by default. Delegate a bounded, independent task only when parallel execution or an independent review provides a concrete benefit. Keep dependent steps with the same owner. Once delegation is appropriate, use a hidden subagent unless the user needs a separate, independently steerable session. This includes substantial, bounded API/service investigations that can be handed off with the needed context and capabilities. For hidden subagents, omit `visible` or set it false, and report results through the parent.",
'`visible=true`: durable visible session. Use only when the user requests a separate session or needs to revisit and steer the work independently. Shows in web UI sidebar; works without UI: announcing runs report back, progress checkable. `group` places it in a custom sidebar group (a new name creates the group); omission or an empty string leaves it ungrouped. Subagent only; omit `mode` (`mode="run"` is also accepted), `thread`, `thinking`, and `lightContext`; `attachments=[]` and omitted/blank `attachAs.mountPath` are accepted, but nonempty attachment staging is unsupported; inherits the caller tool-policy ceiling; select a registered project with `projectId` or a managed GitHub clone with `projectGitUrl` (mutually exclusive with each other and `cwd`); may check out a git worktree via `worktree`/`worktreeName`/`worktreeBaseRef`. When its accepted result includes `sessionUrl`, channel acknowledgements put the session URL on the first line and `Owner: <label>` on the second line.',
'Omit `placement` or use `{kind:"local"}` for local execution. `{kind:"profile",profileId,os?,machineClass?}` selects a configured cloud profile and requires `visible=true` and `worktree=true`. Cloud placement creates first, dispatches, then starts the task; failures retain the child for inspection, never fall back locally.',
visibilityLine,

View file

@ -2,7 +2,7 @@
"base": "codex-dynamic-tools.telegram-direct.json",
"replace": {
"sessions_spawn": {
"description": "Spawn child session; default `runtime=\"subagent\"`. `mode=\"run\"` one-shot; `mode=\"session\"` persistent/thread-bound only on supporting requester channel. `agentId` targets a configured agent (see agents_list); `model` overrides its model; `cleanup` delete|keep hidden child session; `sandbox` inherit|require. Default to a hidden subagent for internal QA, research, coding, review, tests, and parallel work supporting the current task. This includes substantial, bounded API/service investigations that can be handed off with the needed context and capabilities. Omit `visible` or set it false, and report results through the parent. `visible=true`: durable visible session. Use only when the user requests a separate session or needs to revisit and steer the work independently. Shows in web UI sidebar; works without UI: announcing runs report back, progress checkable. `group` places it in a custom sidebar group (a new name creates the group); omission or an empty string leaves it ungrouped. Subagent only; omit `mode` (`mode=\"run\"` is also accepted), `thread`, `thinking`, and `lightContext`; `attachments=[]` and omitted/blank `attachAs.mountPath` are accepted, but nonempty attachment staging is unsupported; inherits the caller tool-policy ceiling; select a registered project with `projectId` or a managed GitHub clone with `projectGitUrl` (mutually exclusive with each other and `cwd`); may check out a git worktree via `worktree`/`worktreeName`/`worktreeBaseRef`. When its accepted result includes `sessionUrl`, channel acknowledgements put the session URL on the first line and `Owner: <label>` on the second line. Omit `placement` or use `{kind:\"local\"}` for local execution. `{kind:\"profile\",profileId,os?,machineClass?}` selects a configured cloud profile and requires `visible=true` and `worktree=true`. Cloud placement creates first, dispatches, then starts the task; failures retain the child for inspection, never fall back locally. Session listing/addressing obeys `tools.sessions.visibility` (all: all sessions, cross-agent per tools.agentToAgent). Inherits parent workspace. Native task arrives in the child's initial `[Subagent Task]` message. Native: explicit context=\"isolated\" starts clean; context=\"fork\" copies requester transcript and requires the same agent. Omitted context follows configured threadBindings.defaultSpawnContext policy (fork by default) with thread=true; without a thread it is isolated. A PR/report, long runtime, or isolated worktree alone does not justify a sidebar session. A request for a subagent does not request a separate session. No spawn for quick lookup/single read. Check spawns via `subagents`/`sessions_history`. After spawn, do non-overlap work; follow the receipt's completion mode. When diagnosing a missing result from an announcing child, use `subagents` to inspect execution and delivery status. Recover existing results or follow up within the still-authorized task; respect intentional cancellation and never loop-poll.",
"description": "Spawn child session; default `runtime=\"subagent\"`. `mode=\"run\"` one-shot; `mode=\"session\"` persistent/thread-bound only on supporting requester channel. `agentId` targets a configured agent (see agents_list); `model` overrides its model; `cleanup` delete|keep hidden child session; `sandbox` inherit|require. Execute work directly by default. Delegate a bounded, independent task only when parallel execution or an independent review provides a concrete benefit. Keep dependent steps with the same owner. Once delegation is appropriate, use a hidden subagent unless the user needs a separate, independently steerable session. This includes substantial, bounded API/service investigations that can be handed off with the needed context and capabilities. For hidden subagents, omit `visible` or set it false, and report results through the parent. `visible=true`: durable visible session. Use only when the user requests a separate session or needs to revisit and steer the work independently. Shows in web UI sidebar; works without UI: announcing runs report back, progress checkable. `group` places it in a custom sidebar group (a new name creates the group); omission or an empty string leaves it ungrouped. Subagent only; omit `mode` (`mode=\"run\"` is also accepted), `thread`, `thinking`, and `lightContext`; `attachments=[]` and omitted/blank `attachAs.mountPath` are accepted, but nonempty attachment staging is unsupported; inherits the caller tool-policy ceiling; select a registered project with `projectId` or a managed GitHub clone with `projectGitUrl` (mutually exclusive with each other and `cwd`); may check out a git worktree via `worktree`/`worktreeName`/`worktreeBaseRef`. When its accepted result includes `sessionUrl`, channel acknowledgements put the session URL on the first line and `Owner: <label>` on the second line. Omit `placement` or use `{kind:\"local\"}` for local execution. `{kind:\"profile\",profileId,os?,machineClass?}` selects a configured cloud profile and requires `visible=true` and `worktree=true`. Cloud placement creates first, dispatches, then starts the task; failures retain the child for inspection, never fall back locally. Session listing/addressing obeys `tools.sessions.visibility` (all: all sessions, cross-agent per tools.agentToAgent). Inherits parent workspace. Native task arrives in the child's initial `[Subagent Task]` message. Native: explicit context=\"isolated\" starts clean; context=\"fork\" copies requester transcript and requires the same agent. Omitted context follows configured threadBindings.defaultSpawnContext policy (fork by default) with thread=true; without a thread it is isolated. A PR/report, long runtime, or isolated worktree alone does not justify a sidebar session. A request for a subagent does not request a separate session. No spawn for quick lookup/single read. Check spawns via `subagents`/`sessions_history`. After spawn, do non-overlap work; follow the receipt's completion mode. When diagnosing a missing result from an announcing child, use `subagents` to inspect execution and delivery status. Recover existing results or follow up within the still-authorized task; respect intentional cancellation and never loop-poll.",
"inputSchema": {
"properties": {
"agentId": {

View file

@ -155,7 +155,7 @@
"type": "function"
},
{
"description": "Spawn child session; default `runtime=\"subagent\"`. `mode=\"run\"` one-shot background. `agentId` targets a configured agent (see agents_list); `model` overrides its model; `cleanup` delete|keep hidden child session; `sandbox` inherit|require. Default to a hidden subagent for internal QA, research, coding, review, tests, and parallel work supporting the current task. This includes substantial, bounded API/service investigations that can be handed off with the needed context and capabilities. Omit `visible` or set it false, and report results through the parent. `visible=true`: durable visible session. Use only when the user requests a separate session or needs to revisit and steer the work independently. Shows in web UI sidebar; works without UI: announcing runs report back, progress checkable. `group` places it in a custom sidebar group (a new name creates the group); omission or an empty string leaves it ungrouped. Subagent only; omit `mode` (`mode=\"run\"` is also accepted), `thread`, `thinking`, and `lightContext`; `attachments=[]` and omitted/blank `attachAs.mountPath` are accepted, but nonempty attachment staging is unsupported; inherits the caller tool-policy ceiling; select a registered project with `projectId` or a managed GitHub clone with `projectGitUrl` (mutually exclusive with each other and `cwd`); may check out a git worktree via `worktree`/`worktreeName`/`worktreeBaseRef`. When its accepted result includes `sessionUrl`, channel acknowledgements put the session URL on the first line and `Owner: <label>` on the second line. Omit `placement` or use `{kind:\"local\"}` for local execution. `{kind:\"profile\",profileId,os?,machineClass?}` selects a configured cloud profile and requires `visible=true` and `worktree=true`. Cloud placement creates first, dispatches, then starts the task; failures retain the child for inspection, never fall back locally. Session listing/addressing obeys `tools.sessions.visibility` (all: all sessions, cross-agent per tools.agentToAgent). Inherits parent workspace. Native task arrives in the child's initial `[Subagent Task]` message. Native: explicit context=\"isolated\" starts clean; context=\"fork\" copies requester transcript and requires the same agent. Omitted context is isolated. A PR/report, long runtime, or isolated worktree alone does not justify a sidebar session. A request for a subagent does not request a separate session. No spawn for quick lookup/single read. Check spawns via `subagents`/`sessions_history`. After spawn, do non-overlap work; follow the receipt's completion mode. When diagnosing a missing result from an announcing child, use `subagents` to inspect execution and delivery status. Recover existing results or follow up within the still-authorized task; respect intentional cancellation and never loop-poll.",
"description": "Spawn child session; default `runtime=\"subagent\"`. `mode=\"run\"` one-shot background. `agentId` targets a configured agent (see agents_list); `model` overrides its model; `cleanup` delete|keep hidden child session; `sandbox` inherit|require. Execute work directly by default. Delegate a bounded, independent task only when parallel execution or an independent review provides a concrete benefit. Keep dependent steps with the same owner. Once delegation is appropriate, use a hidden subagent unless the user needs a separate, independently steerable session. This includes substantial, bounded API/service investigations that can be handed off with the needed context and capabilities. For hidden subagents, omit `visible` or set it false, and report results through the parent. `visible=true`: durable visible session. Use only when the user requests a separate session or needs to revisit and steer the work independently. Shows in web UI sidebar; works without UI: announcing runs report back, progress checkable. `group` places it in a custom sidebar group (a new name creates the group); omission or an empty string leaves it ungrouped. Subagent only; omit `mode` (`mode=\"run\"` is also accepted), `thread`, `thinking`, and `lightContext`; `attachments=[]` and omitted/blank `attachAs.mountPath` are accepted, but nonempty attachment staging is unsupported; inherits the caller tool-policy ceiling; select a registered project with `projectId` or a managed GitHub clone with `projectGitUrl` (mutually exclusive with each other and `cwd`); may check out a git worktree via `worktree`/`worktreeName`/`worktreeBaseRef`. When its accepted result includes `sessionUrl`, channel acknowledgements put the session URL on the first line and `Owner: <label>` on the second line. Omit `placement` or use `{kind:\"local\"}` for local execution. `{kind:\"profile\",profileId,os?,machineClass?}` selects a configured cloud profile and requires `visible=true` and `worktree=true`. Cloud placement creates first, dispatches, then starts the task; failures retain the child for inspection, never fall back locally. Session listing/addressing obeys `tools.sessions.visibility` (all: all sessions, cross-agent per tools.agentToAgent). Inherits parent workspace. Native task arrives in the child's initial `[Subagent Task]` message. Native: explicit context=\"isolated\" starts clean; context=\"fork\" copies requester transcript and requires the same agent. Omitted context is isolated. A PR/report, long runtime, or isolated worktree alone does not justify a sidebar session. A request for a subagent does not request a separate session. No spawn for quick lookup/single read. Check spawns via `subagents`/`sessions_history`. After spawn, do non-overlap work; follow the receipt's completion mode. When diagnosing a missing result from an announcing child, use `subagents` to inspect execution and delivery status. Recover existing results or follow up within the still-authorized task; respect intentional cancellation and never loop-poll.",
"inputSchema": {
"properties": {
"agentId": {

View file

@ -1,5 +1,5 @@
--- telegram-direct-codex-message-tool.md sha256=e7fb2dabfba9b1137d2d011be8e29e32db33d3222c2a54b3448917dcb38a1c38
+++ discord-group-codex-message-tool.md sha256=2a18fb224fecbf9645c338411ae8020a7edbdc543154870ed512fb635896fff8
--- telegram-direct-codex-message-tool.md sha256=16bbbe32082837639c771e57e2ae78b596fb05e6e83481541974311cfe0c1931
+++ discord-group-codex-message-tool.md sha256=010f57c120aa4a5a2cab61ae49e6d654186f582d3f1b05d4a6888913e2aec3d3
@@ -1,1 +1,1 @@
-# Telegram Direct Codex Message Tool Turn
+# Discord Group Codex Message Tool Turn
@ -32,10 +32,10 @@
- "chars": 1348,
+ "chars": 1347,
@@ -261,2 +261,2 @@
- "chars": 71268,
- "roughTokens": 17817
+ "chars": 71866,
+ "roughTokens": 17967
- "chars": 71481,
- "roughTokens": 17871
+ "chars": 72079,
+ "roughTokens": 18020
@@ -265,2 +265,2 @@
- "chars": 2992,
- "roughTokens": 748
@ -47,10 +47,10 @@
+ "chars": 28695,
+ "roughTokens": 7174
@@ -277,2 +277,2 @@
- "chars": 98648,
- "roughTokens": 24662
+ "chars": 100563,
+ "roughTokens": 25141
- "chars": 98861,
- "roughTokens": 24716
+ "chars": 100776,
+ "roughTokens": 25194
@@ -281,2 +281,2 @@
- "chars": 879,
- "roughTokens": 220

View file

@ -258,8 +258,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
"roughTokens": 0
},
"dynamicToolsJson": {
"chars": 71268,
"roughTokens": 17817
"chars": 71481,
"roughTokens": 17871
},
"openClawDeveloperInstructions": {
"chars": 2992,
@ -274,8 +274,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
"roughTokens": 6845
},
"totalWithDynamicToolsJson": {
"chars": 98648,
"roughTokens": 24662
"chars": 98861,
"roughTokens": 24716
},
"userInputText": {
"chars": 879,

View file

@ -1,5 +1,5 @@
--- telegram-direct-codex-message-tool.md sha256=e7fb2dabfba9b1137d2d011be8e29e32db33d3222c2a54b3448917dcb38a1c38
+++ telegram-heartbeat-codex-tool.md sha256=de18a67e16e7815e818b030a2dc7392b2675fe56bdd16a3e04275d054353da85
--- telegram-direct-codex-message-tool.md sha256=16bbbe32082837639c771e57e2ae78b596fb05e6e83481541974311cfe0c1931
+++ telegram-heartbeat-codex-tool.md sha256=6e678b64f8dba44c5ca841c2d3fe3c1811b9bc800e13793ffc948d7fa0c4c632
@@ -1,1 +1,1 @@
-# Telegram Direct Codex Message Tool Turn
+# Telegram Direct Codex Heartbeat Tool Turn
@ -37,20 +37,20 @@
+ "chars": 1218,
+ "roughTokens": 305
@@ -261,2 +258,2 @@
- "chars": 71268,
- "roughTokens": 17817
+ "chars": 72761,
+ "roughTokens": 18191
- "chars": 71481,
- "roughTokens": 17871
+ "chars": 72974,
+ "roughTokens": 18244
@@ -273,2 +270,2 @@
- "chars": 27378,
- "roughTokens": 6845
+ "chars": 27715,
+ "roughTokens": 6929
@@ -277,2 +274,2 @@
- "chars": 98648,
- "roughTokens": 24662
+ "chars": 100478,
+ "roughTokens": 25120
- "chars": 98861,
- "roughTokens": 24716
+ "chars": 100691,
+ "roughTokens": 25173
@@ -281,2 +278,2 @@
- "chars": 879,
- "roughTokens": 220