(calls)
| 193 | if (typeof res?.writeProcessing !== 'function') return work() |
| 194 | const heartbeatMs = Math.max(1, Number(intervalMs) || 15000) |
| 195 | const heartbeat = setInterval(() => { |
| 196 | if (res.headersSent || res.writableEnded || res.destroyed) return |
| 197 | try { |
| 198 | // 102 是临时响应,不会提交最终状态码/响应头。这样既能保持长 thinking |
| 199 | // 连接活跃,又能在门禁耗尽时返回真正的 HTTP 429/503。 |
| 200 | res.writeProcessing() |
| 201 | } catch (_) { |
| 202 | // 某些 HTTP/2/反代适配器不实现临时响应;跳过即可,不能改发 SSE 注释。 |
| 203 | } |
| 204 | }, heartbeatMs) |
| 205 | heartbeat.unref?.() |
| 206 | try { |
| 207 | return await work() |
| 208 | } finally { |
| 209 | clearInterval(heartbeat) |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | const runWithSSEHeartbeat = async (res, work, intervalMs = 15000) => { |
| 214 | const heartbeatMs = Math.max(1, Number(intervalMs) || 15000) |
| 215 | const heartbeat = setInterval(() => { |
| 216 | if (res.writableEnded || res.destroyed) return |
| 217 | try { |
| 218 | // SSE 已经提交 200 响应后,用注释帧保活。注释不会进入 OpenAI delta, |
| 219 | // 但能阻止反代在长 thinking 或纠正 attempt 期间把连接判为空闲。 |
| 220 | res.write(': qwen2api-agent-keepalive\n\n') |
| 221 | if (typeof res.flush === 'function') res.flush() |
| 222 | } catch (_) { |
| 223 | // 客户端断开会由后续流消费/写入路径统一收敛。 |
| 224 | } |
| 225 | }, heartbeatMs) |
| 226 | heartbeat.unref?.() |
| 227 | try { |
| 228 | return await work() |
| 229 | } finally { |
| 230 | clearInterval(heartbeat) |
| 231 | } |
| 232 | } |
| 233 | |
| 234 | const normalizeAgentUsage = (attempt, requestBody, completionText) => { |
| 235 | let usage = { ...(attempt?.totalTokens || {}) } |
| 236 | if (!usage.prompt_tokens && !usage.completion_tokens) { |
| 237 | usage = createUsageObject(requestBody?.messages || [], completionText, null) |
| 238 | } |
| 239 | usage.prompt_tokens = Math.max(0, Number(usage.prompt_tokens) || 0) |
| 240 | usage.completion_tokens = Math.max(0, Number(usage.completion_tokens) || 0) |
| 241 | usage.total_tokens = usage.prompt_tokens + usage.completion_tokens |
| 242 | return usage |
| 243 | } |
| 244 | |
| 245 | const prepareAgentOutput = async (attempt, enableThinking, enableWebSearch, { suppressVisibleText = false } = {}) => { |
| 246 | let reasoning = String(attempt?.reasoning || '') |
| 247 | // 工具调用旁的正文照常交付(OpenAI 允许 content 与 tool_calls 并存):严格门禁下文本 |
| 248 | // 通道的调用到这里 visibleText 必为空白;原生晋升的回合带着调用前的正文过来 —— 除非 |
| 249 | // 门禁判定那段正文混着写坏的文本 [TOOL CALL](suppressVisibleText),那就一个字节不发。 |
| 250 | const visibleText = suppressVisibleText ? '' : String(attempt?.visibleText || '') |
| 251 | let content = attempt?.toolCalls?.length > 0 && !visibleText.trim() ? '' : visibleText |
| 252 |
no outgoing calls
no test coverage detected