fix(session-recovery): detect unavailable_tool errors
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/// <reference types="bun-types" />
|
||||
import { describe, expect, it } from "bun:test"
|
||||
import { detectErrorType, extractMessageIndex } from "./detect-error-type"
|
||||
import { detectErrorType, extractMessageIndex, extractUnavailableToolName } from "./detect-error-type"
|
||||
|
||||
describe("detectErrorType", () => {
|
||||
it("#given a tool_use/tool_result error #when detecting #then returns tool_result_missing", () => {
|
||||
@@ -101,6 +101,45 @@ describe("detectErrorType", () => {
|
||||
//#then
|
||||
expect(result).toBe("tool_result_missing")
|
||||
})
|
||||
|
||||
it("#given a dummy_tool unavailable tool error #when detecting #then returns unavailable_tool", () => {
|
||||
//#given
|
||||
const error = { message: "model tried to call unavailable tool 'invalid'" }
|
||||
|
||||
//#when
|
||||
const result = detectErrorType(error)
|
||||
|
||||
//#then
|
||||
expect(result).toBe("unavailable_tool")
|
||||
})
|
||||
|
||||
it("#given a no such tool error #when detecting #then returns unavailable_tool", () => {
|
||||
//#given
|
||||
const error = { message: "No such tool: grepppp" }
|
||||
|
||||
//#when
|
||||
const result = detectErrorType(error)
|
||||
|
||||
//#then
|
||||
expect(result).toBe("unavailable_tool")
|
||||
})
|
||||
|
||||
it("#given a dummy_tool token in nested error #when detecting #then returns unavailable_tool", () => {
|
||||
//#given
|
||||
const error = {
|
||||
data: {
|
||||
error: {
|
||||
message: "dummy_tool Model tried to call unavailable tool 'invalid'",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
//#when
|
||||
const result = detectErrorType(error)
|
||||
|
||||
//#then
|
||||
expect(result).toBe("unavailable_tool")
|
||||
})
|
||||
})
|
||||
|
||||
describe("extractMessageIndex", () => {
|
||||
@@ -127,3 +166,27 @@ describe("extractMessageIndex", () => {
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe("extractUnavailableToolName", () => {
|
||||
it("#given unavailable tool error with quoted tool name #when extracting #then returns tool name", () => {
|
||||
//#given
|
||||
const error = { message: "model tried to call unavailable tool 'invalid'" }
|
||||
|
||||
//#when
|
||||
const result = extractUnavailableToolName(error)
|
||||
|
||||
//#then
|
||||
expect(result).toBe("invalid")
|
||||
})
|
||||
|
||||
it("#given error without unavailable tool name #when extracting #then returns null", () => {
|
||||
//#given
|
||||
const error = { message: "dummy_tool appeared without tool name" }
|
||||
|
||||
//#when
|
||||
const result = extractUnavailableToolName(error)
|
||||
|
||||
//#then
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -3,6 +3,7 @@ export type RecoveryErrorType =
|
||||
| "thinking_block_order"
|
||||
| "thinking_disabled_violation"
|
||||
| "assistant_prefill_unsupported"
|
||||
| "unavailable_tool"
|
||||
| null
|
||||
|
||||
function getErrorMessage(error: unknown): string {
|
||||
@@ -43,6 +44,16 @@ export function extractMessageIndex(error: unknown): number | null {
|
||||
}
|
||||
}
|
||||
|
||||
export function extractUnavailableToolName(error: unknown): string | null {
|
||||
try {
|
||||
const message = getErrorMessage(error)
|
||||
const match = message.match(/unavailable tool ['"]?([^'".\s]+)['"]?/)
|
||||
return match ? match[1] : null
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export function detectErrorType(error: unknown): RecoveryErrorType {
|
||||
try {
|
||||
const message = getErrorMessage(error)
|
||||
@@ -74,6 +85,16 @@ export function detectErrorType(error: unknown): RecoveryErrorType {
|
||||
return "tool_result_missing"
|
||||
}
|
||||
|
||||
if (
|
||||
message.includes("dummy_tool") ||
|
||||
message.includes("unavailable tool") ||
|
||||
message.includes("model tried to call unavailable") ||
|
||||
message.includes("nosuchtoolarror") ||
|
||||
message.includes("no such tool")
|
||||
) {
|
||||
return "unavailable_tool"
|
||||
}
|
||||
|
||||
return null
|
||||
} catch {
|
||||
return null
|
||||
|
||||
Reference in New Issue
Block a user