mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-18 23:27:26 +00:00
fix(agents): land #39247 from @jasonQin6 (subagent workspace inheritance)
Propagate parent workspace directories into spawned subagent runs, keep workspace override internal-only, and add regression tests for forwarding boundaries. Co-authored-by: jasonQin6 <991262382@qq.com>
This commit is contained in:
@@ -110,6 +110,7 @@ export const AgentParamsSchema = Type.Object(
|
||||
idempotencyKey: NonEmptyString,
|
||||
label: Type.Optional(SessionLabelString),
|
||||
spawnedBy: Type.Optional(Type.String()),
|
||||
workspaceDir: Type.Optional(Type.String()),
|
||||
},
|
||||
{ additionalProperties: false },
|
||||
);
|
||||
|
||||
@@ -409,6 +409,39 @@ describe("gateway agent handler", () => {
|
||||
expect(callArgs.bestEffortDeliver).toBe(false);
|
||||
});
|
||||
|
||||
it("only forwards workspaceDir for spawned subagent runs", async () => {
|
||||
primeMainAgentRun();
|
||||
mocks.agentCommand.mockClear();
|
||||
|
||||
await invokeAgent(
|
||||
{
|
||||
message: "normal run",
|
||||
sessionKey: "agent:main:main",
|
||||
workspaceDir: "/tmp/ignored",
|
||||
idempotencyKey: "workspace-ignored",
|
||||
},
|
||||
{ reqId: "workspace-ignored-1" },
|
||||
);
|
||||
await vi.waitFor(() => expect(mocks.agentCommand).toHaveBeenCalled());
|
||||
const normalCall = mocks.agentCommand.mock.calls.at(-1)?.[0] as { workspaceDir?: string };
|
||||
expect(normalCall.workspaceDir).toBeUndefined();
|
||||
mocks.agentCommand.mockClear();
|
||||
|
||||
await invokeAgent(
|
||||
{
|
||||
message: "spawned run",
|
||||
sessionKey: "agent:main:main",
|
||||
spawnedBy: "agent:main:subagent:parent",
|
||||
workspaceDir: "/tmp/inherited",
|
||||
idempotencyKey: "workspace-forwarded",
|
||||
},
|
||||
{ reqId: "workspace-forwarded-1" },
|
||||
);
|
||||
await vi.waitFor(() => expect(mocks.agentCommand).toHaveBeenCalled());
|
||||
const spawnedCall = mocks.agentCommand.mock.calls.at(-1)?.[0] as { workspaceDir?: string };
|
||||
expect(spawnedCall.workspaceDir).toBe("/tmp/inherited");
|
||||
});
|
||||
|
||||
it("keeps origin messageChannel as webchat while delivery channel uses last session channel", async () => {
|
||||
mockMainSessionEntry({
|
||||
sessionId: "existing-session-id",
|
||||
|
||||
@@ -211,6 +211,7 @@ export const agentHandlers: GatewayRequestHandlers = {
|
||||
label?: string;
|
||||
spawnedBy?: string;
|
||||
inputProvenance?: InputProvenance;
|
||||
workspaceDir?: string;
|
||||
};
|
||||
const senderIsOwner = resolveSenderIsOwnerFromClient(client);
|
||||
const cfg = loadConfig();
|
||||
@@ -645,6 +646,8 @@ export const agentHandlers: GatewayRequestHandlers = {
|
||||
extraSystemPrompt: request.extraSystemPrompt,
|
||||
internalEvents: request.internalEvents,
|
||||
inputProvenance,
|
||||
// Internal-only: allow workspace override for spawned subagent runs.
|
||||
workspaceDir: spawnedByValue ? request.workspaceDir : undefined,
|
||||
senderIsOwner,
|
||||
},
|
||||
defaultRuntime,
|
||||
|
||||
Reference in New Issue
Block a user