feat(server): add inference reliability - tool-shim and loop detectors
- ToolShim recovers XML/JSON tool calls from plain-text model output - detectContentRepeat catches same-content loops - detectToolLoop catches repeated tool invocations - detectDoomLoop combines both detectors
This commit is contained in:
45
apps/server/src/services/inference/tool-shim.ts
Normal file
45
apps/server/src/services/inference/tool-shim.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
// ToolShim — recovers structured tool calls from plain-text model output.
|
||||
// When the model emits tool calls as plain text instead of structured JSON,
|
||||
// this shim attempts to parse and recover them.
|
||||
|
||||
export interface ParsedToolCall {
|
||||
id: string;
|
||||
name: string;
|
||||
arguments: string;
|
||||
}
|
||||
|
||||
const TOOL_CALL_PATTERN = /<tool_call>\s*<name>(.+?)<\/name>\s*<arguments>(.+?)<\/arguments>\s*<\/tool_call>/gs;
|
||||
const JSON_TOOL_PATTERN = /\{\s*"name":\s*"([^"]+)",\s*"arguments":\s*({.+?})\s*\}/gs;
|
||||
|
||||
export function extractToolCalls(text: string): ParsedToolCall[] {
|
||||
const calls: ParsedToolCall[] = [];
|
||||
let match: RegExpExecArray | null;
|
||||
|
||||
// Try XML-style tool calls (common in Qwen output)
|
||||
const xmlRegex = new RegExp(TOOL_CALL_PATTERN);
|
||||
while ((match = xmlRegex.exec(text)) !== null) {
|
||||
calls.push({
|
||||
id: `call_${calls.length}`,
|
||||
name: match[1]!.trim(),
|
||||
arguments: match[2]!.trim(),
|
||||
});
|
||||
}
|
||||
|
||||
if (calls.length > 0) return calls;
|
||||
|
||||
// Try JSON-style tool calls
|
||||
const jsonRegex = new RegExp(JSON_TOOL_PATTERN);
|
||||
while ((match = jsonRegex.exec(text)) !== null) {
|
||||
calls.push({
|
||||
id: `call_${calls.length}`,
|
||||
name: match[1]!.trim(),
|
||||
arguments: match[2]!.trim(),
|
||||
});
|
||||
}
|
||||
|
||||
return calls;
|
||||
}
|
||||
|
||||
export function hasToolCallMarkup(text: string): boolean {
|
||||
return TOOL_CALL_PATTERN.test(text) || JSON_TOOL_PATTERN.test(text);
|
||||
}
|
||||
Reference in New Issue
Block a user