Skip to content

Commit 4b10dce

Browse files
committed
Fix anothropic Streaming issue error in parsing json.
1 parent 7e56172 commit 4b10dce

File tree

1 file changed

+42
-23
lines changed

1 file changed

+42
-23
lines changed

src/api/providers/sapaicore.ts

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,48 @@ export function processGeminiStreamChunk(data: any): {
355355
return result
356356
}
357357

358+
/**
359+
* Safely parse JSON with fallback handling for common malformed JSON issues
360+
* Used specifically for SAP AI Core streaming responses
361+
*/
362+
export function parseJsonSafely(str: string): any {
363+
if (!str || typeof str !== "string" || str.trim() === "") {
364+
console.error("Failed to parse JSON safely:", str, new Error("Input must be a non-empty string"))
365+
throw new Error("Input must be a non-empty string")
366+
}
367+
368+
try {
369+
// First try standard JSON parsing
370+
return JSON.parse(str)
371+
} catch (error) {
372+
// If that fails, try to fix common JSON issues safely
373+
try {
374+
let cleaned = str.trim()
375+
cleaned = cleaned.replace(/,(\s*[}\]])/g, "$1")
376+
cleaned = cleaned.replace(/([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)\s*:/g, '$1"$2":')
377+
cleaned = cleaned.replace(/'([^']*?)'/g, '"$1"')
378+
379+
// Remove any trailing commas at the end
380+
cleaned = cleaned.replace(/,\s*$/, "")
381+
return JSON.parse(cleaned)
382+
} catch (secondError) {
383+
// If regex approach fails, try the toStrictJson approach as fallback
384+
// but only for trusted SAP AI Core responses
385+
try {
386+
const obj = new Function("return " + str)()
387+
return JSON.stringify(obj)
388+
} catch (thirdError) {
389+
console.error(
390+
"Failed to parse JSON safely:",
391+
str,
392+
error instanceof Error ? error : new Error("Unknown error"),
393+
)
394+
throw new Error(`Invalid JSON format: ${error instanceof Error ? error.message : "Unknown error"}`)
395+
}
396+
}
397+
}
398+
}
399+
358400
function convertAnthropicMessageToGemini(message: Anthropic.Messages.MessageParam) {
359401
const role = message.role === "assistant" ? "model" : "user"
360402
const parts = []
@@ -420,29 +462,6 @@ export function prepareGeminiRequestPayload(
420462
return payload
421463
}
422464

423-
/**
424-
* Safely parse JSON with fallback handling for common malformed JSON issues
425-
* Used specifically for SAP AI Core streaming responses
426-
*/
427-
export function parseJsonSafely(str: string): any {
428-
try {
429-
// First try standard JSON parsing
430-
return JSON.parse(str)
431-
} catch (error) {
432-
// If that fails, try to fix common JSON issues safely
433-
try {
434-
// Remove trailing commas and fix other common issues
435-
const cleaned = str
436-
.replace(/,(\s*[}\]])/g, "$1") // Remove trailing commas
437-
.replace(/([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)\s*:/g, '$1"$2":') // Quote unquoted keys
438-
return JSON.parse(cleaned)
439-
} catch (secondError) {
440-
console.error("Failed to parse JSON safely:", str, secondError)
441-
throw secondError
442-
}
443-
}
444-
}
445-
446465
export class SapAiCoreHandler extends BaseProvider implements SingleCompletionHandler {
447466
private options: SapAiCoreHandlerOptions
448467
private token?: Token

0 commit comments

Comments
 (0)