From ccca0cac2a1e37b51b69d03dbed8064f905c0f87 Mon Sep 17 00:00:00 2001 From: Victor Vogel Date: Sun, 1 Nov 2026 10:29:02 -0600 Subject: [PATCH] fix(server): record the resolved scheduled-task thread binding in telemetry Co-Authored-By: Claude Opus 5.5 --- .../src/telemetry/ProviderDimensions.test.ts | 13 +++++++++++++ apps/server/src/telemetry/ProviderDimensions.ts | 15 ++++++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/apps/server/src/telemetry/ProviderDimensions.test.ts b/apps/server/src/telemetry/ProviderDimensions.test.ts index d88010f600e35..00e59c11228cb 100644 --- a/apps/server/src/telemetry/ProviderDimensions.test.ts +++ b/apps/server/src/telemetry/ProviderDimensions.test.ts @@ -76,3 +76,16 @@ it("drops input strings outside the schema's literals, since rejected calls are handoffSettings("t3_thread_launch", { workspaceStrategy: { type: "/home/me/secret" } }, {}), ).toEqual({ targetChosen: false, workspace: "root" }); }); + +it("records the binding the saved scheduled task resolved to, and none for failures", () => { + expect(handoffSettings("schedule_task", {}, { boundThreadId: null })).toEqual({ + bindToCurrentThread: false, + }); + expect( + handoffSettings( + "schedule_task", + { bindToCurrentThread: true }, + { _tag: "OrchestratorMcpFailure", code: "invalid_request", message: "Different project." }, + ), + ).toEqual({}); +}); diff --git a/apps/server/src/telemetry/ProviderDimensions.ts b/apps/server/src/telemetry/ProviderDimensions.ts index 4e0447a1e2c44..acdb045e9a00d 100644 --- a/apps/server/src/telemetry/ProviderDimensions.ts +++ b/apps/server/src/telemetry/ProviderDimensions.ts @@ -88,9 +88,9 @@ function callerOrigin(input: { } /** - * Settings the agent chose for a handoff, read only from closed enums and - * booleans in the tool's arguments and result. Prompts, titles, and ids are - * never read. + * Settings for a handoff, recorded only as closed enums and booleans derived + * from the tool's arguments and result. Prompts, titles, and ids are never + * recorded. */ export function handoffSettings(tool: string, args: unknown, result: unknown): Fields { const input = asFields(args); @@ -126,8 +126,13 @@ export function handoffSettings(tool: string, args: unknown, result: unknown): F return defined({ delivery: stringField(output, "delivery") }); case "t3_thread_send_attachments": return { delivery: "auto" }; - case "schedule_task": - return { bindToCurrentThread: input.bindToCurrentThread !== false }; + case "schedule_task": { + // Omitting the input lets the server decide, so read the saved task. + const bound = output.boundThreadId; + return bound === null || typeof bound === "string" + ? { bindToCurrentThread: bound !== null } + : {}; + } default: return {}; }