fix(nodes-tool): add run invoke timeout (PR #433, thanks @sircrumpet)
This commit is contained in:
@@ -40,6 +40,7 @@
|
|||||||
- Tools: add Telegram/WhatsApp reaction tools (with per-provider gating). Thanks @zats for PR #353.
|
- Tools: add Telegram/WhatsApp reaction tools (with per-provider gating). Thanks @zats for PR #353.
|
||||||
- Tools: flatten literal-union schemas for Claude on Vertex AI. Thanks @carlulsoe for PR #409.
|
- Tools: flatten literal-union schemas for Claude on Vertex AI. Thanks @carlulsoe for PR #409.
|
||||||
- Tools: keep tool failure logs concise (no stack traces); full stack only in debug logs.
|
- Tools: keep tool failure logs concise (no stack traces); full stack only in debug logs.
|
||||||
|
- Tools: add nodes tool run invoke-timeout support. Thanks @sircrumpet for PR #433.
|
||||||
- Tools: unify reaction removal semantics across Discord/Slack/Telegram/WhatsApp and allow WhatsApp reaction routing across accounts.
|
- Tools: unify reaction removal semantics across Discord/Slack/Telegram/WhatsApp and allow WhatsApp reaction routing across accounts.
|
||||||
- Android: fix APK output filename renaming after AGP updates. Thanks @Syhids for PR #410.
|
- Android: fix APK output filename renaming after AGP updates. Thanks @Syhids for PR #410.
|
||||||
- Android: rotate camera photos by EXIF orientation. Thanks @fcatuhe for PR #403.
|
- Android: rotate camera photos by EXIF orientation. Thanks @fcatuhe for PR #403.
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ Core actions:
|
|||||||
- `status`, `describe`
|
- `status`, `describe`
|
||||||
- `pending`, `approve`, `reject` (pairing)
|
- `pending`, `approve`, `reject` (pairing)
|
||||||
- `notify` (macOS `system.notify`)
|
- `notify` (macOS `system.notify`)
|
||||||
|
- `run` (macOS `system.run`)
|
||||||
- `camera_snap`, `camera_clip`, `screen_record`
|
- `camera_snap`, `camera_clip`, `screen_record`
|
||||||
- `location_get`
|
- `location_get`
|
||||||
|
|
||||||
|
|||||||
@@ -88,3 +88,49 @@ describe("nodes camera_snap", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("nodes run", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
callGateway.mockReset();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("passes invoke and command timeouts", async () => {
|
||||||
|
callGateway.mockImplementation(async ({ method, params }) => {
|
||||||
|
if (method === "node.list") {
|
||||||
|
return { nodes: [{ nodeId: "mac-1" }] };
|
||||||
|
}
|
||||||
|
if (method === "node.invoke") {
|
||||||
|
expect(params).toMatchObject({
|
||||||
|
nodeId: "mac-1",
|
||||||
|
command: "system.run",
|
||||||
|
timeoutMs: 45_000,
|
||||||
|
params: {
|
||||||
|
command: ["echo", "hi"],
|
||||||
|
cwd: "/tmp",
|
||||||
|
env: { FOO: "bar" },
|
||||||
|
timeoutMs: 12_000,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
payload: { stdout: "", stderr: "", exitCode: 0, success: true },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
throw new Error(`unexpected method: ${String(method)}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
const tool = createClawdbotTools().find(
|
||||||
|
(candidate) => candidate.name === "nodes",
|
||||||
|
);
|
||||||
|
if (!tool) throw new Error("missing nodes tool");
|
||||||
|
|
||||||
|
await tool.execute("call1", {
|
||||||
|
action: "run",
|
||||||
|
node: "mac-1",
|
||||||
|
command: ["echo", "hi"],
|
||||||
|
cwd: "/tmp",
|
||||||
|
env: ["FOO=bar"],
|
||||||
|
commandTimeoutMs: 12_000,
|
||||||
|
invokeTimeoutMs: 45_000,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -158,6 +158,7 @@ const NodesToolSchema = Type.Union([
|
|||||||
cwd: Type.Optional(Type.String()),
|
cwd: Type.Optional(Type.String()),
|
||||||
env: Type.Optional(Type.Array(Type.String())),
|
env: Type.Optional(Type.Array(Type.String())),
|
||||||
commandTimeoutMs: Type.Optional(Type.Number()),
|
commandTimeoutMs: Type.Optional(Type.Number()),
|
||||||
|
invokeTimeoutMs: Type.Optional(Type.Number()),
|
||||||
needsScreenRecording: Type.Optional(Type.Boolean()),
|
needsScreenRecording: Type.Optional(Type.Boolean()),
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
@@ -534,6 +535,11 @@ export function createNodesTool(): AnyAgentTool {
|
|||||||
Number.isFinite(params.commandTimeoutMs)
|
Number.isFinite(params.commandTimeoutMs)
|
||||||
? params.commandTimeoutMs
|
? params.commandTimeoutMs
|
||||||
: undefined;
|
: undefined;
|
||||||
|
const invokeTimeoutMs =
|
||||||
|
typeof params.invokeTimeoutMs === "number" &&
|
||||||
|
Number.isFinite(params.invokeTimeoutMs)
|
||||||
|
? params.invokeTimeoutMs
|
||||||
|
: undefined;
|
||||||
const needsScreenRecording =
|
const needsScreenRecording =
|
||||||
typeof params.needsScreenRecording === "boolean"
|
typeof params.needsScreenRecording === "boolean"
|
||||||
? params.needsScreenRecording
|
? params.needsScreenRecording
|
||||||
@@ -548,6 +554,7 @@ export function createNodesTool(): AnyAgentTool {
|
|||||||
timeoutMs: commandTimeoutMs,
|
timeoutMs: commandTimeoutMs,
|
||||||
needsScreenRecording,
|
needsScreenRecording,
|
||||||
},
|
},
|
||||||
|
timeoutMs: invokeTimeoutMs,
|
||||||
idempotencyKey: crypto.randomUUID(),
|
idempotencyKey: crypto.randomUUID(),
|
||||||
})) as { payload?: unknown };
|
})) as { payload?: unknown };
|
||||||
return jsonResult(raw?.payload ?? {});
|
return jsonResult(raw?.payload ?? {});
|
||||||
|
|||||||
Reference in New Issue
Block a user