refactor: streamline provider interactions and enhance error handling

This commit is contained in:
decolua
2026-01-11 21:45:01 +07:00
parent f302c88dfb
commit f46ff42cb3
21 changed files with 859 additions and 170 deletions
+11 -6
View File
@@ -30,7 +30,9 @@ export function handleBypassRequest(body, model) {
// Check warmup: first message "Warmup"
const firstText = getText(messages[0]?.content);
if (firstText === "Warmup") shouldBypass = true;
if (firstText === "Warmup") {
shouldBypass = true;
}
// Check count pattern: [{"role":"user","content":"count"}]
// if (!shouldBypass &&
@@ -40,10 +42,15 @@ export function handleBypassRequest(body, model) {
// shouldBypass = true;
// }
// Check skip patterns
// Check skip patterns - only check user messages, not system prompt
if (!shouldBypass && SKIP_PATTERNS?.length) {
const allText = messages.map(m => getText(m.content)).join(" ");
shouldBypass = SKIP_PATTERNS.some(p => allText.includes(p));
// Only check user messages, skip system/assistant messages to avoid matching system prompts
const userMessages = messages.filter(m => m.role === "user");
const userText = userMessages.map(m => getText(m.content)).join(" ");
const matchedPattern = SKIP_PATTERNS.find(p => userText.includes(p));
if (matchedPattern) {
shouldBypass = true;
}
}
if (!shouldBypass) return null;
@@ -54,10 +61,8 @@ export function handleBypassRequest(body, model) {
// Create bypass response using translator
if (stream) {
console.log("createStreamingResponse", sourceFormat, model);
return createStreamingResponse(sourceFormat, model);
} else {
console.log("createNonStreamingResponse", sourceFormat, model);
return createNonStreamingResponse(sourceFormat, model);
}
}
+20 -4
View File
@@ -106,18 +106,34 @@ function parseSSELine(line) {
* @returns {string} SSE formatted string
*/
export function formatSSE(data, sourceFormat) {
if (data.done) return "data: [DONE]\n\n";
// Handle null/undefined
if (data === null || data === undefined) {
return "data: null\n\n";
}
if (data && data.done) return "data: [DONE]\n\n";
// OpenAI Responses API format: has event field
if (data.event && data.data) {
if (data && data.event && data.data) {
return `event: ${data.event}\ndata: ${JSON.stringify(data.data)}\n\n`;
}
// Claude format: include event prefix
if (sourceFormat === FORMATS.CLAUDE && data.type) {
if (sourceFormat === FORMATS.CLAUDE && data && data.type) {
// If perf_metrics is null, remove it to avoid serialization issues
if (data.usage && typeof data.usage === 'object' && data.usage.perf_metrics === null) {
const { perf_metrics, ...usageWithoutPerf } = data.usage;
data = { ...data, usage: usageWithoutPerf };
}
return `event: ${data.type}\ndata: ${JSON.stringify(data)}\n\n`;
}
// If perf_metrics is null, remove it to avoid serialization issues
if (data?.usage && typeof data.usage === 'object' && data.usage.perf_metrics === null) {
const { perf_metrics, ...usageWithoutPerf } = data.usage;
data = { ...data, usage: usageWithoutPerf };
}
return `data: ${JSON.stringify(data)}\n\n`;
}
@@ -199,7 +215,7 @@ export function createSSEStream(options = {}) {
const parsed = parseSSELine(trimmed);
if (!parsed) continue;
if (parsed.done) {
if (parsed && parsed.done) {
const output = "data: [DONE]\n\n";
reqLogger?.appendConvertedChunk?.(output);
controller.enqueue(encoder.encode(output));