diff --git a/src/agents/embedded-agent-runner/run/attempt-bootstrap-routing.ts b/src/agents/embedded-agent-runner/run/attempt-bootstrap-routing.ts index 3b4e93d91a66..c6444cf531a8 100644 --- a/src/agents/embedded-agent-runner/run/attempt-bootstrap-routing.ts +++ b/src/agents/embedded-agent-runner/run/attempt-bootstrap-routing.ts @@ -33,23 +33,6 @@ type AttemptWorkspaceBootstrapRoutingInput = Omit< bootstrapFiles?: readonly WorkspaceBootstrapFile[]; }; -/** - * Maps a resolved bootstrap mode to concrete prompt destinations. Today only - * full bootstrap enters system context; limited/none intentionally avoid - * runtime-context injection until that path has a separate contract. - */ -export function resolveBootstrapContextTargets(params: { - bootstrapMode: BootstrapMode; -}): Pick< - AttemptBootstrapRouting, - "includeBootstrapInSystemContext" | "includeBootstrapInRuntimeContext" -> { - return { - includeBootstrapInSystemContext: params.bootstrapMode === "full", - includeBootstrapInRuntimeContext: false, - }; -} - function resolveAttemptBootstrapRouting( params: AttemptBootstrapRoutingInput, ): AttemptBootstrapRouting { @@ -66,22 +49,11 @@ function resolveAttemptBootstrapRouting( return { bootstrapMode, - ...resolveBootstrapContextTargets({ bootstrapMode }), + includeBootstrapInSystemContext: bootstrapMode === "full", + includeBootstrapInRuntimeContext: false, }; } -export function hasBootstrapFileContent(files?: readonly WorkspaceBootstrapFile[]): boolean { - return ( - files?.some( - (file) => - file.name === DEFAULT_BOOTSTRAP_FILENAME && - !file.missing && - typeof file.content === "string" && - file.content.trim().length > 0, - ) ?? false - ); -} - /** * Resolves workspace bootstrap routing after checking pending state and * hook-provided bootstrap files. Hook content counts as both pending bootstrap @@ -94,7 +66,14 @@ export async function resolveAttemptWorkspaceBootstrapRouting( const workspaceBootstrapPending = await params.isWorkspaceBootstrapPending( params.resolvedWorkspace, ); - const hasHookBootstrapContent = hasBootstrapFileContent(params.bootstrapFiles); + const hasHookBootstrapContent = + params.bootstrapFiles?.some( + (file) => + file.name === DEFAULT_BOOTSTRAP_FILENAME && + !file.missing && + typeof file.content === "string" && + file.content.trim().length > 0, + ) ?? false; return resolveAttemptBootstrapRouting({ ...params, workspaceBootstrapPending: workspaceBootstrapPending || hasHookBootstrapContent, diff --git a/src/agents/embedded-agent-runner/run/attempt.spawn-workspace.bootstrap-routing.test.ts b/src/agents/embedded-agent-runner/run/attempt.spawn-workspace.bootstrap-routing.test.ts index 793fa3510b8a..75df6d4f8fca 100644 --- a/src/agents/embedded-agent-runner/run/attempt.spawn-workspace.bootstrap-routing.test.ts +++ b/src/agents/embedded-agent-runner/run/attempt.spawn-workspace.bootstrap-routing.test.ts @@ -1,10 +1,6 @@ // Coverage for bootstrap routing across canonical and effective workspaces. import { describe, expect, it, vi } from "vitest"; -import { - hasBootstrapFileContent, - resolveBootstrapContextTargets, - resolveAttemptWorkspaceBootstrapRouting, -} from "./attempt-bootstrap-routing.js"; +import { resolveAttemptWorkspaceBootstrapRouting } from "./attempt-bootstrap-routing.js"; describe("runEmbeddedAttempt bootstrap routing", () => { it("resolves bootstrap pending from the canonical workspace instead of a copied sandbox", async () => { @@ -100,34 +96,27 @@ describe("runEmbeddedAttempt bootstrap routing", () => { expect(routing.includeBootstrapInRuntimeContext).toBe(false); }); - it("does not treat empty hook-provided BOOTSTRAP.md as pending bootstrap context", () => { - expect( - hasBootstrapFileContent([ + it("does not treat empty hook-provided BOOTSTRAP.md as pending bootstrap context", async () => { + const routing = await resolveAttemptWorkspaceBootstrapRouting({ + isWorkspaceBootstrapPending: vi.fn(async () => false), + bootstrapFiles: [ { name: "BOOTSTRAP.md", path: "/tmp/openclaw-workspace/BOOTSTRAP.md", content: " ", missing: false, }, - ]), - ).toBe(false); - }); + ], + trigger: "user", + isPrimaryRun: true, + isCanonicalWorkspace: true, + effectiveWorkspace: "/tmp/openclaw-workspace", + resolvedWorkspace: "/tmp/openclaw-workspace", + hasBootstrapFileAccess: true, + }); - it("keeps BOOTSTRAP.md in Project Context for full bootstrap turns", () => { - expect(resolveBootstrapContextTargets({ bootstrapMode: "full" })).toEqual({ - includeBootstrapInSystemContext: true, - includeBootstrapInRuntimeContext: false, - }); - }); - - it("excludes BOOTSTRAP.md from every context outside full bootstrap turns", () => { - expect(resolveBootstrapContextTargets({ bootstrapMode: "limited" })).toEqual({ - includeBootstrapInSystemContext: false, - includeBootstrapInRuntimeContext: false, - }); - expect(resolveBootstrapContextTargets({ bootstrapMode: "none" })).toEqual({ - includeBootstrapInSystemContext: false, - includeBootstrapInRuntimeContext: false, - }); + expect(routing.bootstrapMode).toBe("none"); + expect(routing.includeBootstrapInSystemContext).toBe(false); + expect(routing.includeBootstrapInRuntimeContext).toBe(false); }); }); diff --git a/src/agents/embedded-agent-runner/run/attempt.test.ts b/src/agents/embedded-agent-runner/run/attempt.test.ts index 691060b07e73..70c972cbb35f 100644 --- a/src/agents/embedded-agent-runner/run/attempt.test.ts +++ b/src/agents/embedded-agent-runner/run/attempt.test.ts @@ -16,7 +16,6 @@ import { resolveEmbeddedAgentBaseStreamFn, resolveEmbeddedAgentStreamFn, } from "../stream-resolution.js"; -import { resolveBootstrapContextTargets } from "./attempt-bootstrap-routing.js"; import { buildContextEnginePromptCacheInfo } from "./attempt.context-engine-helpers.js"; import { buildAfterTurnRuntimeContext, @@ -332,23 +331,6 @@ describe("resolvePromptModeForSession", () => { }); }); -describe("resolveBootstrapContextTargets", () => { - it("keeps BOOTSTRAP.md in system Project Context only for full bootstrap turns", () => { - expect(resolveBootstrapContextTargets({ bootstrapMode: "full" })).toEqual({ - includeBootstrapInSystemContext: true, - includeBootstrapInRuntimeContext: false, - }); - expect(resolveBootstrapContextTargets({ bootstrapMode: "limited" })).toEqual({ - includeBootstrapInSystemContext: false, - includeBootstrapInRuntimeContext: false, - }); - expect(resolveBootstrapContextTargets({ bootstrapMode: "none" })).toEqual({ - includeBootstrapInSystemContext: false, - includeBootstrapInRuntimeContext: false, - }); - }); -}); - describe("shouldWarnOnOrphanedUserRepair", () => { it("warns for user and manual runs", () => { expect(shouldWarnOnOrphanedUserRepair("user")).toBe(true);