mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-28 04:30:42 +00:00
Co-authored-by: Onur Solmaz <2453968+osolmaz@users.noreply.github.com>
This commit is contained in:
@@ -16,6 +16,7 @@ vi.mock("../subagent-spawn.js", () => ({
|
||||
|
||||
vi.mock("../acp-spawn.js", () => ({
|
||||
ACP_SPAWN_MODES: ["run", "session"],
|
||||
ACP_SPAWN_STREAM_TARGETS: ["parent"],
|
||||
spawnAcpDirect: (...args: unknown[]) => hoisted.spawnAcpDirectMock(...args),
|
||||
}));
|
||||
|
||||
@@ -94,6 +95,7 @@ describe("sessions_spawn tool", () => {
|
||||
cwd: "/workspace",
|
||||
thread: true,
|
||||
mode: "session",
|
||||
streamTo: "parent",
|
||||
});
|
||||
|
||||
expect(result.details).toMatchObject({
|
||||
@@ -108,6 +110,7 @@ describe("sessions_spawn tool", () => {
|
||||
cwd: "/workspace",
|
||||
thread: true,
|
||||
mode: "session",
|
||||
streamTo: "parent",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
agentSessionKey: "agent:main:main",
|
||||
@@ -165,6 +168,26 @@ describe("sessions_spawn tool", () => {
|
||||
expect(hoisted.spawnSubagentDirectMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('rejects streamTo when runtime is not "acp"', async () => {
|
||||
const tool = createSessionsSpawnTool({
|
||||
agentSessionKey: "agent:main:main",
|
||||
});
|
||||
|
||||
const result = await tool.execute("call-3b", {
|
||||
runtime: "subagent",
|
||||
task: "analyze file",
|
||||
streamTo: "parent",
|
||||
});
|
||||
|
||||
expect(result.details).toMatchObject({
|
||||
status: "error",
|
||||
});
|
||||
const details = result.details as { error?: string };
|
||||
expect(details.error).toContain("streamTo is only supported for runtime=acp");
|
||||
expect(hoisted.spawnAcpDirectMock).not.toHaveBeenCalled();
|
||||
expect(hoisted.spawnSubagentDirectMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("keeps attachment content schema unconstrained for llama.cpp grammar safety", () => {
|
||||
const tool = createSessionsSpawnTool();
|
||||
const schema = tool.parameters as {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Type } from "@sinclair/typebox";
|
||||
import type { GatewayMessageChannel } from "../../utils/message-channel.js";
|
||||
import { ACP_SPAWN_MODES, spawnAcpDirect } from "../acp-spawn.js";
|
||||
import { ACP_SPAWN_MODES, ACP_SPAWN_STREAM_TARGETS, spawnAcpDirect } from "../acp-spawn.js";
|
||||
import { optionalStringEnum } from "../schema/typebox.js";
|
||||
import { SUBAGENT_SPAWN_MODES, spawnSubagentDirect } from "../subagent-spawn.js";
|
||||
import type { AnyAgentTool } from "./common.js";
|
||||
@@ -34,6 +34,7 @@ const SessionsSpawnToolSchema = Type.Object({
|
||||
mode: optionalStringEnum(SUBAGENT_SPAWN_MODES),
|
||||
cleanup: optionalStringEnum(["delete", "keep"] as const),
|
||||
sandbox: optionalStringEnum(SESSIONS_SPAWN_SANDBOX_MODES),
|
||||
streamTo: optionalStringEnum(ACP_SPAWN_STREAM_TARGETS),
|
||||
|
||||
// Inline attachments (snapshot-by-value).
|
||||
// NOTE: Attachment contents are redacted from transcript persistence by sanitizeToolCallInputs.
|
||||
@@ -97,6 +98,7 @@ export function createSessionsSpawnTool(opts?: {
|
||||
const cleanup =
|
||||
params.cleanup === "keep" || params.cleanup === "delete" ? params.cleanup : "keep";
|
||||
const sandbox = params.sandbox === "require" ? "require" : "inherit";
|
||||
const streamTo = params.streamTo === "parent" ? "parent" : undefined;
|
||||
// Back-compat: older callers used timeoutSeconds for this tool.
|
||||
const timeoutSecondsCandidate =
|
||||
typeof params.runTimeoutSeconds === "number"
|
||||
@@ -118,6 +120,13 @@ export function createSessionsSpawnTool(opts?: {
|
||||
}>)
|
||||
: undefined;
|
||||
|
||||
if (streamTo && runtime !== "acp") {
|
||||
return jsonResult({
|
||||
status: "error",
|
||||
error: `streamTo is only supported for runtime=acp; got runtime=${runtime}`,
|
||||
});
|
||||
}
|
||||
|
||||
if (runtime === "acp") {
|
||||
if (Array.isArray(attachments) && attachments.length > 0) {
|
||||
return jsonResult({
|
||||
@@ -135,6 +144,7 @@ export function createSessionsSpawnTool(opts?: {
|
||||
mode: mode && ACP_SPAWN_MODES.includes(mode) ? mode : undefined,
|
||||
thread,
|
||||
sandbox,
|
||||
streamTo,
|
||||
},
|
||||
{
|
||||
agentSessionKey: opts?.agentSessionKey,
|
||||
|
||||
Reference in New Issue
Block a user