fix: preserve subagent task overrides (#78356)

Co-authored-by: Alex Knight <15041791+amknight@users.noreply.github.com>
This commit is contained in:
Alex Knight
2026-05-06 18:31:01 +10:00
committed by GitHub
parent 0ddbf2e258
commit ff655cb346
3 changed files with 56 additions and 5 deletions

View File

@@ -128,6 +128,7 @@ Docs: https://docs.openclaw.ai
- Control UI/sessions: fire the documented `/new` command and lifecycle hooks only for explicit Control UI session creation, restoring session-memory and custom hook capture without changing SDK parent-session creates. Fixes #76957. Thanks @BunsDev.
- Exec approvals: fall back to a guarded copy when Windows rejects rename-overwrite for `exec-approvals.json`, while preserving symlink, hard-link, and owner-only permission safeguards. Fixes #77785. (#77907) Thanks @Alex-Alaniz and @MilleniumGenAI.
- Slack: preserve Socket Mode SDK error context and structured Slack API fields in reconnect logs, so startup failures no longer collapse to a bare `unknown error`.
- Agents/subagents: preserve the delegated task prompt when a spawned target agent uses `systemPromptOverride`, so `sessions_spawn(mode: "run")` child runs still see their assigned task. Fixes #77950. Thanks @amknight.
- iOS pairing: allow setup-code and manual `ws://` connects for private LAN and `.local` gateways while keeping Tailscale/public routes on `wss://`, and prefer explicit gateway passwords over stale bootstrap tokens in mixed-auth reconnects. Fixes #47887; carries forward #65185. Thanks @draix and @BunsDev.
- Node/Windows: fall back to the Startup-folder launcher when Spanish-localized `schtasks` reports `Acceso denegado`, matching the existing access-denied fallback path. Fixes #77993. Thanks @jackonedev.
- Plugins/diagnostics: make source-only TypeScript package warnings actionable by explaining that missing compiled runtime output is a publisher packaging issue and pointing users to update/reinstall or disable/uninstall the plugin. Fixes #77835. Thanks @googlerest.

View File

@@ -68,6 +68,38 @@ describe("buildAttemptSystemPrompt", () => {
expect(result.systemPrompt).not.toContain("USER.md");
});
it("preserves runtime extra system prompt context when a system prompt override is configured", () => {
const result = buildAttemptSystemPrompt({
isRawModelRun: false,
systemPromptOverrideText: "Custom override prompt.",
transformProviderSystemPrompt,
embeddedSystemPrompt: {
workspaceDir: "/tmp/openclaw",
reasoningTagHint: false,
runtimeInfo: {
host: "test-host",
os: "Darwin",
arch: "arm64",
node: "v22.0.0",
model: "openai/gpt-5.5",
},
tools: [],
modelAliasLines: [],
userTimezone: "UTC",
promptMode: "minimal",
extraSystemPrompt:
"# Subagent Context\n\n## Your Role\n- You were created to handle: RUN_MODE_TASK_77950",
bootstrapMode: "full",
contextFiles: [],
},
providerTransform: baseProviderTransform,
});
expect(result.systemPrompt).toContain("Custom override prompt.");
expect(result.systemPrompt).toContain("## Subagent Context");
expect(result.systemPrompt).toContain("RUN_MODE_TASK_77950");
});
it("omits system prompts for raw model probes", () => {
const result = buildAttemptSystemPrompt({
isRawModelRun: true,

View File

@@ -30,15 +30,33 @@ export type AttemptSystemPrompt = {
systemPromptOverride: (defaultPrompt?: string) => string;
};
function appendRuntimeExtraSystemPrompt(params: {
systemPrompt: string;
extraSystemPrompt?: string;
promptMode?: EmbeddedSystemPromptParams["promptMode"];
}): string {
const extraSystemPrompt = params.extraSystemPrompt?.trim();
if (!extraSystemPrompt || params.promptMode === "none") {
return params.systemPrompt;
}
const contextHeader =
params.promptMode === "minimal" ? "## Subagent Context" : "## Group Chat Context";
return `${params.systemPrompt.trimEnd()}\n\n${contextHeader}\n${extraSystemPrompt}\n`;
}
export function buildAttemptSystemPrompt(
params: BuildAttemptSystemPromptParams,
): AttemptSystemPrompt {
const baseSystemPrompt = params.systemPromptOverrideText
? appendAgentBootstrapSystemPromptSupplement({
systemPrompt: params.systemPromptOverrideText,
bootstrapMode: params.embeddedSystemPrompt.bootstrapMode,
bootstrapTruncationNotice: params.embeddedSystemPrompt.bootstrapTruncationNotice,
contextFiles: params.embeddedSystemPrompt.contextFiles,
? appendRuntimeExtraSystemPrompt({
systemPrompt: appendAgentBootstrapSystemPromptSupplement({
systemPrompt: params.systemPromptOverrideText,
bootstrapMode: params.embeddedSystemPrompt.bootstrapMode,
bootstrapTruncationNotice: params.embeddedSystemPrompt.bootstrapTruncationNotice,
contextFiles: params.embeddedSystemPrompt.contextFiles,
}),
extraSystemPrompt: params.embeddedSystemPrompt.extraSystemPrompt,
promptMode: params.embeddedSystemPrompt.promptMode,
})
: buildEmbeddedSystemPrompt(params.embeddedSystemPrompt);