claude-sdk-proxy 3.1.1 → 3.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/proxy/server.ts +42 -1
- package/src/proxy/server.ts.bak +1841 -0
package/package.json
CHANGED
package/src/proxy/server.ts
CHANGED
|
@@ -221,7 +221,23 @@ function parseToolUse(text: string): { toolCalls: ToolCall[]; textBefore: string
|
|
|
221
221
|
while ((m = xmlRegex.exec(text)) !== null) {
|
|
222
222
|
if (firstIdx < 0) firstIdx = m.index
|
|
223
223
|
try {
|
|
224
|
-
const
|
|
224
|
+
const raw = m[1]!.trim()
|
|
225
|
+
let p: any
|
|
226
|
+
try { p = JSON.parse(raw) } catch {
|
|
227
|
+
// Repair: models often emit raw newlines in heredocs/multiline commands
|
|
228
|
+
// which are invalid inside JSON strings. Escape them only inside quoted values.
|
|
229
|
+
let fixed = "", inStr = false, esc = false
|
|
230
|
+
for (const ch of raw) {
|
|
231
|
+
if (esc) { fixed += ch; esc = false; continue }
|
|
232
|
+
if (ch === "\\") { esc = true; fixed += ch; continue }
|
|
233
|
+
if (ch === '"') { inStr = !inStr; fixed += ch; continue }
|
|
234
|
+
if (inStr && ch === "\n") { fixed += "\\n"; continue }
|
|
235
|
+
if (inStr && ch === "\r") { fixed += "\\r"; continue }
|
|
236
|
+
if (inStr && ch === "\t") { fixed += "\\t"; continue }
|
|
237
|
+
fixed += ch
|
|
238
|
+
}
|
|
239
|
+
p = JSON.parse(fixed)
|
|
240
|
+
}
|
|
225
241
|
calls.push({
|
|
226
242
|
id: generateId("toolu_"),
|
|
227
243
|
name: String(p.name ?? ""),
|
|
@@ -950,6 +966,18 @@ export function createProxyServer(config: Partial<ProxyConfig> = {}) {
|
|
|
950
966
|
|
|
951
967
|
if (hasTools) {
|
|
952
968
|
const { toolCalls, textBefore } = parseToolUse(fullText)
|
|
969
|
+
// Debug: log when tools were expected but none parsed
|
|
970
|
+
if (toolCalls.length === 0 && fullText.length > 0) {
|
|
971
|
+
logDebug("tool_parse.no_match", {
|
|
972
|
+
reqId,
|
|
973
|
+
outputLen: fullText.length,
|
|
974
|
+
textPreview: fullText.slice(0, 500),
|
|
975
|
+
hasToolUseTag: fullText.includes("<tool_use>"),
|
|
976
|
+
hasFunctionCalls: fullText.includes("<function_calls>"),
|
|
977
|
+
hasInvoke: fullText.includes("<invoke"),
|
|
978
|
+
hasAntmlInvoke: fullText.includes("antml:invoke"),
|
|
979
|
+
})
|
|
980
|
+
}
|
|
953
981
|
const content: any[] = []
|
|
954
982
|
if (textBefore) content.push({ type: "text", text: textBefore })
|
|
955
983
|
for (const tc of toolCalls) content.push({ type: "tool_use", id: tc.id, name: tc.name, input: tc.input })
|
|
@@ -1163,6 +1191,19 @@ export function createProxyServer(config: Partial<ProxyConfig> = {}) {
|
|
|
1163
1191
|
traceStore.phase(reqId, "responding")
|
|
1164
1192
|
const { toolCalls, textBefore } = parseToolUse(fullText)
|
|
1165
1193
|
|
|
1194
|
+
// Debug: log when tools were expected but none parsed
|
|
1195
|
+
if (toolCalls.length === 0 && fullText.length > 0) {
|
|
1196
|
+
logDebug("tool_parse.no_match_stream", {
|
|
1197
|
+
reqId,
|
|
1198
|
+
outputLen: fullText.length,
|
|
1199
|
+
textPreview: fullText.slice(0, 500),
|
|
1200
|
+
hasToolUseTag: fullText.includes("<tool_use>"),
|
|
1201
|
+
hasFunctionCalls: fullText.includes("<function_calls>"),
|
|
1202
|
+
hasInvoke: fullText.includes("<invoke"),
|
|
1203
|
+
hasAntmlInvoke: fullText.includes("antml:invoke"),
|
|
1204
|
+
})
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1166
1207
|
let blockIdx = 0
|
|
1167
1208
|
const textContent = toolCalls.length === 0 ? (fullText || "...") : textBefore
|
|
1168
1209
|
if (textContent) {
|