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

Function handleOpenAINonStream

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

Source from the content-addressed store, hash-verified

1132// ==================== 非流式处理 ====================
1133
1134async function handleOpenAINonStream(
1135 res: Response,
1136 cursorReq: CursorChatRequest,
1137 body: OpenAIChatRequest,
1138 anthropicReq: AnthropicRequest,
1139 log: RequestLogger,
1140): Promise<void> {
1141 let activeCursorReq = cursorReq;
1142 let fullText = (await sendCursorRequestFull(activeCursorReq)).text;
1143 const hasTools = (body.tools?.length ?? 0) > 0;
1144
1145 // 日志记录在详细日志中
1146
1147 // ★ Thinking 提取必须在拒绝检测之前 — 否则 thinking 内容中的关键词会触发 isRefusal 误判
1148 const thinkingEnabled = anthropicReq.thinking?.type === 'enabled';
1149 let reasoningContent: string | undefined;
1150 if (hasLeadingThinking(fullText)) {
1151 const { thinkingContent: extracted, strippedText } = extractThinking(fullText);
1152 if (extracted) {
1153 if (thinkingEnabled) {
1154 reasoningContent = extracted;
1155 }
1156 // thinking 剥离记录
1157 fullText = strippedText;
1158 }
1159 }
1160
1161 // 拒绝检测 + 自动重试(在 thinking 提取之后,只检测实际输出内容)
1162 const shouldRetry = () => isRefusal(fullText) && !(hasTools && hasToolCalls(fullText));
1163
1164 if (shouldRetry()) {
1165 for (let attempt = 0; attempt < MAX_REFUSAL_RETRIES; attempt++) {
1166 // 重试记录
1167 const retryBody = buildRetryRequest(anthropicReq, attempt);
1168 const retryCursorReq = await convertToCursorRequest(retryBody);
1169 activeCursorReq = retryCursorReq;
1170 fullText = (await sendCursorRequestFull(activeCursorReq)).text;
1171 // 重试响应也需要先剥离 thinking
1172 if (hasLeadingThinking(fullText)) {
1173 fullText = extractThinking(fullText).strippedText;
1174 }
1175 if (!shouldRetry()) break;
1176 }
1177 if (shouldRetry()) {
1178 if (hasTools) {
1179 // 记录在详细日志
1180 fullText = 'I understand the request. Let me analyze the information and proceed with the appropriate action.';
1181 } else if (isToolCapabilityQuestion(anthropicReq)) {
1182 // 记录在详细日志
1183 fullText = CLAUDE_TOOLS_RESPONSE;
1184 } else {
1185 // 记录在详细日志
1186 fullText = CLAUDE_IDENTITY_RESPONSE;
1187 }
1188 }
1189 }
1190
1191 if (hasTools) {

Callers 1

Calls 15

parseToolCallsFunction · 0.90
isRefusalFunction · 0.90
sendCursorRequestFullFunction · 0.85
hasLeadingThinkingFunction · 0.85
extractThinkingFunction · 0.85
buildRetryRequestFunction · 0.85
convertToCursorRequestFunction · 0.85
isToolCapabilityQuestionFunction · 0.85
sanitizeResponseFunction · 0.85
toolCallIdFunction · 0.85
stripMarkdownJsonWrapperFunction · 0.85

Tested by

no test coverage detected