summaryrefslogtreecommitdiffhomepage
path: root/packages/kernel/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/kernel/src')
-rw-r--r--packages/kernel/src/runtime/dispatch.ts4
-rw-r--r--packages/kernel/src/runtime/run-turn.test.ts65
-rw-r--r--packages/kernel/src/runtime/run-turn.ts3
3 files changed, 72 insertions, 0 deletions
diff --git a/packages/kernel/src/runtime/dispatch.ts b/packages/kernel/src/runtime/dispatch.ts
index e0be1b4..01f0043 100644
--- a/packages/kernel/src/runtime/dispatch.ts
+++ b/packages/kernel/src/runtime/dispatch.ts
@@ -18,6 +18,7 @@ export async function executeToolCall(
turnId: string,
toolSpan?: Span,
cwd?: string,
+ computerId?: string,
): Promise<ToolResult> {
if (tool === undefined) {
return { content: `Unknown tool: ${call.name}`, isError: true };
@@ -34,6 +35,7 @@ export async function executeToolCall(
log: toolSpan?.log ?? createNoopLogger(),
conversationId,
...(cwd !== undefined ? { cwd } : {}),
+ ...(computerId !== undefined ? { computerId } : {}),
};
// Race the tool's execute promise against the abort signal so a tool
// that hangs (ignores ctx.signal, or blocks on something the signal
@@ -74,6 +76,7 @@ export function createStepDispatcher(
turnId: string,
toolSpans: Map<string, Span>,
cwd?: string,
+ computerId?: string,
): StepDispatcher {
let activeCount = 0;
let unsafeRunning = false;
@@ -112,6 +115,7 @@ export function createStepDispatcher(
turnId,
tcSpan,
cwd,
+ computerId,
);
activeCount--;
if (entry.tool?.concurrencySafe === false) unsafeRunning = false;
diff --git a/packages/kernel/src/runtime/run-turn.test.ts b/packages/kernel/src/runtime/run-turn.test.ts
index 0d4c59d..08d3055 100644
--- a/packages/kernel/src/runtime/run-turn.test.ts
+++ b/packages/kernel/src/runtime/run-turn.test.ts
@@ -835,6 +835,71 @@ describe("runTurn", () => {
expect(capturedCwd).toBeUndefined();
});
+ it("forwards computerId from RunTurnInput to ToolExecuteContext", async () => {
+ let capturedComputerId: string | undefined = "SENTINEL_NOT_SET";
+
+ const tool = createFakeTool("computercheck", async (_input, ctx) => {
+ capturedComputerId = ctx.computerId;
+ return { content: "ok" };
+ });
+
+ const provider = createFakeProvider([
+ [
+ { type: "tool-call", toolCallId: "tc1", toolName: "computercheck", input: {} },
+ { type: "finish", reason: "tool-calls" },
+ ],
+ [
+ { type: "text-delta", delta: "done" },
+ { type: "finish", reason: "stop" },
+ ],
+ ]);
+
+ await runTurn({
+ provider,
+ messages: [userMessage],
+ tools: [tool],
+ dispatch: { maxConcurrent: 1, eager: false },
+ conversationId: "tab-test",
+ turnId: "turn-test",
+ emit: () => {},
+ computerId: "ssh-host-alias",
+ });
+
+ expect(capturedComputerId).toBe("ssh-host-alias");
+ });
+
+ it("forwards undefined computerId when RunTurnInput has no computerId", async () => {
+ let capturedComputerId: string | undefined = "SENTINEL_NOT_SET";
+
+ const tool = createFakeTool("computercheck", async (_input, ctx) => {
+ capturedComputerId = ctx.computerId;
+ return { content: "ok" };
+ });
+
+ const provider = createFakeProvider([
+ [
+ { type: "tool-call", toolCallId: "tc1", toolName: "computercheck", input: {} },
+ { type: "finish", reason: "tool-calls" },
+ ],
+ [
+ { type: "text-delta", delta: "done" },
+ { type: "finish", reason: "stop" },
+ ],
+ ]);
+
+ await runTurn({
+ provider,
+ messages: [userMessage],
+ tools: [tool],
+ dispatch: { maxConcurrent: 1, eager: false },
+ conversationId: "tab-test",
+ turnId: "turn-test",
+ emit: () => {},
+ });
+
+ expect(capturedComputerId).toBeUndefined();
+ });
+
it("aggregates usage across multiple steps", async () => {
const provider = createFakeProvider([
[
diff --git a/packages/kernel/src/runtime/run-turn.ts b/packages/kernel/src/runtime/run-turn.ts
index f5d80d3..940c77f 100644
--- a/packages/kernel/src/runtime/run-turn.ts
+++ b/packages/kernel/src/runtime/run-turn.ts
@@ -117,6 +117,7 @@ interface StepContext {
readonly turnSpan: Span | undefined;
readonly toolSpans: Map<string, Span>;
readonly cwd: string | undefined;
+ readonly computerId: string | undefined;
readonly now: (() => number) | undefined;
/** Per-turn provider options (model, systemPrompt, …) threaded to stream(). */
readonly providerOpts: ProviderStreamOptions | undefined;
@@ -295,6 +296,7 @@ async function executeStep(ctx: StepContext): Promise<StepResult> {
ctx.turnId,
ctx.toolSpans,
ctx.cwd,
+ ctx.computerId,
);
const timing: TimingState = {
@@ -522,6 +524,7 @@ export async function runTurn(input: RunTurnInput): Promise<RunTurnResult> {
turnSpan,
toolSpans,
cwd: input.cwd,
+ computerId: input.computerId,
now,
providerOpts: input.providerOpts,
});