MCPcopy
hub / github.com/7836246/cursor2api / handleOpenAIStream

Function handleOpenAIStream

src/openai-handler.ts:760–1130  ·  view source on GitHub ↗
(
    res: Response,
    cursorReq: CursorChatRequest,
    body: OpenAIChatRequest,
    anthropicReq: AnthropicRequest,
    log: RequestLogger,
)

Source from the content-addressed store, hash-verified

758// ==================== 流式处理(OpenAI SSE 格式) ====================
759
760async function handleOpenAIStream(
761 res: Response,
762 cursorReq: CursorChatRequest,
763 body: OpenAIChatRequest,
764 anthropicReq: AnthropicRequest,
765 log: RequestLogger,
766): Promise<void> {
767 res.writeHead(200, {
768 'Content-Type': 'text/event-stream',
769 'Cache-Control': 'no-cache',
770 'Connection': 'keep-alive',
771 'X-Accel-Buffering': 'no',
772 });
773
774 const id = chatId();
775 const created = Math.floor(Date.now() / 1000);
776 const model = body.model;
777 const hasTools = (body.tools?.length ?? 0) > 0;
778
779 // 发送 role delta
780 writeOpenAISSE(res, {
781 id, object: 'chat.completion.chunk', created, model,
782 choices: [{
783 index: 0,
784 delta: { role: 'assistant', content: '' },
785 finish_reason: null,
786 }],
787 });
788
789 let fullResponse = '';
790 let sentText = '';
791 let activeCursorReq = cursorReq;
792 let retryCount = 0;
793
794 // 统一缓冲模式:先缓冲全部响应,再检测拒绝和处理
795 const executeStream = async (onTextDelta?: (delta: string) => void) => {
796 fullResponse = '';
797 await sendCursorRequest(activeCursorReq, (event: CursorSSEEvent) => {
798 if (event.type !== 'text-delta' || !event.delta) return;
799 fullResponse += event.delta;
800 onTextDelta?.(event.delta);
801 });
802 };
803
804 try {
805 if (!hasTools && (!body.response_format || body.response_format.type === 'text')) {
806 await handleOpenAIIncrementalTextStream(res, cursorReq, body, anthropicReq, { id, created, model }, log);
807 return;
808 }
809
810 // ★ 混合流式:文本增量 + 工具缓冲(与 Anthropic handler 同一设计)
811 const thinkingEnabled = anthropicReq.thinking?.type === 'enabled';
812 const hybridStreamer = createIncrementalTextStreamer({
813 warmupChars: 300, // ★ 与拒绝检测窗口对齐
814 transform: sanitizeResponse,
815 isBlockedPrefix: (text) => isRefusal(text.substring(0, 300)),
816 });
817 let toolMarkerDetected = false;

Callers 1

Calls 15

isRefusalFunction · 0.90
parseToolCallsFunction · 0.90
chatIdFunction · 0.85
writeOpenAISSEFunction · 0.85
writeOpenAITextDeltaFunction · 0.85
hasLeadingThinkingFunction · 0.85
extractThinkingFunction · 0.85
buildRetryRequestFunction · 0.85

Tested by

no test coverage detected