From 422226067a918fc7a38ef77dada62439880bd8a3 Mon Sep 17 00:00:00 2001 From: "altimate-factory[bot]" Date: Fri, 30 Oct 2026 14:55:29 +0000 Subject: [PATCH] fix: automated fix in packages/opencode/src/altimate/telemetry Factory lane: altimate_code. Agent-Authored-By: altimate-factory --- .../src/altimate/telemetry/error-detail.ts | 18 +++++++++ packages/opencode/src/session/prompt.ts | 2 + .../error-fingerprint-requested-abort.test.ts | 40 +++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 packages/opencode/test/telemetry/error-fingerprint-requested-abort.test.ts diff --git a/packages/opencode/src/altimate/telemetry/error-detail.ts b/packages/opencode/src/altimate/telemetry/error-detail.ts index 3d2ef5e78d..349f86c6cc 100644 --- a/packages/opencode/src/altimate/telemetry/error-detail.ts +++ b/packages/opencode/src/altimate/telemetry/error-detail.ts @@ -400,6 +400,24 @@ export function describeToolError(raw: string) { } } +/** + * A running tool that the processor closed because the session's own abort signal fired + * (Stop/Esc, dispose) is a requested cancellation, already recorded as the session's + * "aborted" outcome, not a tool failure. Interruptions the session did not request + * (signal not aborted) and every real tool error are still fingerprinted. + */ +export function isRequestedToolInterruption( + state: { status: string; error?: unknown; metadata?: Record }, + sessionAborted: boolean, +): boolean { + return ( + sessionAborted && + state.status === "error" && + state.error === "Tool execution aborted" && + state.metadata?.interrupted === true + ) +} + export function buildErrorFingerprintEvent( sessionID: string, err: { diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index ecedc18104..6ce93b673c 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -2241,6 +2241,8 @@ export namespace SessionPrompt { lastToolName = part.tool // altimate_change end if (toolChain.length < 50) toolChain.push(part.tool) + // altimate_change — a requested abort closing a running tool is not a tool failure + if (ErrorDetail.isRequestedToolInterruption(part.state, abort.aborted)) continue const isError = part.state?.status === "error" if (isError) { toolErrorCount++ diff --git a/packages/opencode/test/telemetry/error-fingerprint-requested-abort.test.ts b/packages/opencode/test/telemetry/error-fingerprint-requested-abort.test.ts new file mode 100644 index 0000000000..33d921cfda --- /dev/null +++ b/packages/opencode/test/telemetry/error-fingerprint-requested-abort.test.ts @@ -0,0 +1,40 @@ +import { describe, expect, test } from "bun:test" +import { ErrorDetail } from "../../src/altimate/telemetry/error-detail" + +// Shape written by processor.ts interruptedToolPart when a running tool is closed on abort. +const interrupted = { + status: "error", + input: { filePath: "/tmp/x.sql" }, + error: "Tool execution aborted", + metadata: { interrupted: true }, + time: { start: 1, end: 2 }, +} + +describe("error_fingerprint: requested tool interruption", () => { + test("the interrupted-tool error is the reported 'tool aborted' fingerprint", () => { + expect(ErrorDetail.describeToolError(interrupted.error).errorMessage).toBe("tool aborted") + }) + + test("a tool closed by the session's own abort is not a tool failure", () => { + expect(ErrorDetail.isRequestedToolInterruption(interrupted, true)).toBe(true) + }) + + test("an interruption the session did not request is still reported", () => { + expect(ErrorDetail.isRequestedToolInterruption(interrupted, false)).toBe(false) + }) + + test("real tool errors are still reported during an aborted session", () => { + expect( + ErrorDetail.isRequestedToolInterruption( + { status: "error", error: "File not found: /tmp/x.sql", metadata: {} }, + true, + ), + ).toBe(false) + expect( + ErrorDetail.isRequestedToolInterruption({ status: "error", error: "Tool execution aborted", metadata: {} }, true), + ).toBe(false) + expect(ErrorDetail.isRequestedToolInterruption({ status: "completed", metadata: { interrupted: true } }, true)).toBe( + false, + ) + }) +})