pybao-cli 1.4.81 → 1.4.82
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/REPL-VOJCD6X6.js +49 -0
- package/dist/{acp-YXMNP56B.js → acp-ASRH57AF.js} +79 -32
- package/dist/acp-ASRH57AF.js.map +7 -0
- package/dist/{agentsValidate-LQFWOCPZ.js → agentsValidate-35AHZXNB.js} +7 -7
- package/dist/ask-TI3ITWN7.js +143 -0
- package/dist/ask-TI3ITWN7.js.map +7 -0
- package/dist/{autoUpdater-DEH233RT.js → autoUpdater-MRK5BD2L.js} +3 -3
- package/dist/{chunk-JVF6KNE3.js → chunk-2AG4BTRV.js} +1 -1
- package/dist/{chunk-PRRYL2E2.js → chunk-2S2V2ZI7.js} +16 -16
- package/dist/{chunk-ZE75JZFY.js → chunk-2WIUQUTU.js} +3 -3
- package/dist/{chunk-5KAIY3II.js → chunk-2YM35XWE.js} +3 -3
- package/dist/{chunk-H44O47XJ.js → chunk-AUGXOUTX.js} +11 -1
- package/dist/chunk-AUGXOUTX.js.map +7 -0
- package/dist/{chunk-FDGIVQNE.js → chunk-AYVB6VUF.js} +1 -1
- package/dist/{chunk-6XINCIUI.js → chunk-DYJD66YF.js} +1 -1
- package/dist/{chunk-EYY3QDKX.js → chunk-DZTZPEPA.js} +2 -2
- package/dist/chunk-F4AXICO7.js +28 -0
- package/dist/chunk-F4AXICO7.js.map +7 -0
- package/dist/{chunk-HNHWG52B.js → chunk-GSAG6WNQ.js} +1 -1
- package/dist/{chunk-CLGB56HY.js → chunk-GUTLXPN6.js} +36 -2
- package/dist/{chunk-CLGB56HY.js.map → chunk-GUTLXPN6.js.map} +2 -2
- package/dist/{chunk-VW3NZKCP.js → chunk-GZT2DWED.js} +1 -1
- package/dist/{chunk-BJMVIICS.js → chunk-HJWUPFGF.js} +4 -4
- package/dist/{chunk-KH3U5BR5.js → chunk-IIVG2SHE.js} +3 -3
- package/dist/{chunk-GS4PRJHV.js → chunk-JQVZNIKI.js} +4 -4
- package/dist/{chunk-MKNRYFQR.js → chunk-JT3RE7UH.js} +6 -22
- package/dist/{chunk-MKNRYFQR.js.map → chunk-JT3RE7UH.js.map} +3 -3
- package/dist/{chunk-4SWM6FWR.js → chunk-KNWW4HGV.js} +2 -2
- package/dist/chunk-LM665HND.js +262 -0
- package/dist/chunk-LM665HND.js.map +7 -0
- package/dist/{chunk-Z73SPR4B.js → chunk-NTL5PKCX.js} +3 -3
- package/dist/{chunk-2NFKKANF.js → chunk-PXPTGNYH.js} +2 -2
- package/dist/{chunk-HIZXCXUG.js → chunk-QUWUFGZF.js} +4 -4
- package/dist/{chunk-BX6HNPWQ.js → chunk-SZEYDC6A.js} +3 -3
- package/dist/{chunk-AB3F7T5N.js → chunk-TWWQYBVK.js} +3 -3
- package/dist/{chunk-UUS77RPP.js → chunk-U265OPSO.js} +1 -1
- package/dist/{chunk-4NNDWUSZ.js → chunk-UBX7JQR2.js} +2 -2
- package/dist/{chunk-4VUECEM6.js → chunk-UXVOYFKL.js} +2 -2
- package/dist/{chunk-37ZXN5M4.js → chunk-VMWEFYQB.js} +1 -1
- package/dist/{chunk-CCF52HVZ.js → chunk-WBBMOYXK.js} +1 -1
- package/dist/{chunk-CCF52HVZ.js.map → chunk-WBBMOYXK.js.map} +1 -1
- package/dist/{chunk-B3NR3UMC.js → chunk-WVYIFMLG.js} +4 -4
- package/dist/chunk-XKYHFZEC.js +68 -0
- package/dist/chunk-XKYHFZEC.js.map +7 -0
- package/dist/{chunk-TVUG5GLX.js → chunk-XOOHCC63.js} +356 -161
- package/dist/chunk-XOOHCC63.js.map +7 -0
- package/dist/{chunk-GMKASRN7.js → chunk-Y5JPSTQ4.js} +1 -1
- package/dist/{chunk-7ANXEZRS.js → chunk-ZW25QNXS.js} +3 -3
- package/dist/{cli-VNT2RTPP.js → cli-ECB4WYUZ.js} +399 -379
- package/dist/cli-ECB4WYUZ.js.map +7 -0
- package/dist/commands-3B77L2SI.js +53 -0
- package/dist/{config-VK55G2IB.js → config-KZHPV37P.js} +4 -4
- package/dist/{context-QHTEENJ6.js → context-ZZI53BPM.js} +6 -6
- package/dist/conversationTracker-SC6NCQHL.js +17 -0
- package/dist/{customCommands-HRHE7ZIM.js → customCommands-MX6OENKO.js} +4 -4
- package/dist/{env-GGYUE5V7.js → env-76WAAGI6.js} +2 -2
- package/dist/{file-KHYC624L.js → file-LCS77XWE.js} +4 -4
- package/dist/index.js +3 -3
- package/dist/{llm-A3S75CLF.js → llm-AR66BS2U.js} +32 -29
- package/dist/{llm-A3S75CLF.js.map → llm-AR66BS2U.js.map} +1 -1
- package/dist/{llmLazy-USVVGSVL.js → llmLazy-5W6E5BCB.js} +1 -1
- package/dist/{loader-JPKYTFFC.js → loader-OWZ3WD2X.js} +4 -4
- package/dist/{lsp-B7QJVI2U.js → lsp-NLPSJYH4.js} +6 -6
- package/dist/{lspAnchor-JJJ2WKI7.js → lspAnchor-MWASWGQD.js} +6 -6
- package/dist/{mcp-YOR7UMEZ.js → mcp-T2UB74Y2.js} +7 -7
- package/dist/{mentionProcessor-5CYA4NR4.js → mentionProcessor-KIBWOHEC.js} +5 -5
- package/dist/{messages-ICKAWGUW.js → messages-6BHCXDWR.js} +5 -1
- package/dist/{model-P33QONA2.js → model-5NDSZPIL.js} +5 -5
- package/dist/{openai-POLCH476.js → openai-7XPWH2G7.js} +6 -5
- package/dist/{outputStyles-EZGCOEE2.js → outputStyles-QUE4ALJQ.js} +4 -4
- package/dist/{pluginRuntime-KJ3YFO2O.js → pluginRuntime-PQ3VZRX7.js} +6 -6
- package/dist/{pluginValidation-MR5GV7PL.js → pluginValidation-RQ34XQY3.js} +6 -6
- package/dist/prompts-5576MRUX.js +55 -0
- package/dist/{pybAgentSessionLoad-TRSWA62U.js → pybAgentSessionLoad-5MWAY2A4.js} +4 -4
- package/dist/{pybAgentSessionResume-3IRNTCVI.js → pybAgentSessionResume-NZGSUGGS.js} +4 -4
- package/dist/{pybAgentStreamJsonSession-5IBYEXS5.js → pybAgentStreamJsonSession-UP4WOINX.js} +3 -3
- package/dist/pybAgentStreamJsonSession-UP4WOINX.js.map +7 -0
- package/dist/{pybHooks-HFAKEYDS.js → pybHooks-HILU7ZB4.js} +4 -4
- package/dist/query-LMPE4HBF.js +57 -0
- package/dist/{registry-LOKL3JBE.js → registry-4MWYBUFA.js} +5 -5
- package/dist/replSessionBridge-EBXNFUAD.js +10 -0
- package/dist/{ripgrep-X4LOQHA7.js → ripgrep-J74GL455.js} +3 -3
- package/dist/{skillMarketplace-UITGQNZD.js → skillMarketplace-ATLDIEEX.js} +3 -3
- package/dist/{state-I7LIGIFJ.js → state-Y2Q4MPY5.js} +2 -2
- package/dist/{theme-RVIXXPSQ.js → theme-3L66ZU5Z.js} +5 -5
- package/dist/{toolPermissionSettings-TALALPH3.js → toolPermissionSettings-PDGMFGN2.js} +6 -6
- package/dist/toolPermissionSettings-PDGMFGN2.js.map +7 -0
- package/dist/tools-45UHHM5S.js +54 -0
- package/dist/tools-45UHHM5S.js.map +7 -0
- package/dist/{userInput-WFPUGJ4L.js → userInput-GBXOUS4W.js} +40 -36
- package/dist/userInput-GBXOUS4W.js.map +7 -0
- package/package.json +1 -1
- package/dist/REPL-WXPYXBW2.js +0 -46
- package/dist/acp-YXMNP56B.js.map +0 -7
- package/dist/ask-CUR6IJ2W.js +0 -129
- package/dist/ask-CUR6IJ2W.js.map +0 -7
- package/dist/chunk-H44O47XJ.js.map +0 -7
- package/dist/chunk-TVUG5GLX.js.map +0 -7
- package/dist/cli-VNT2RTPP.js.map +0 -7
- package/dist/commands-LAZD5O4M.js +0 -50
- package/dist/prompts-P4JU57HZ.js +0 -52
- package/dist/pybAgentStreamJsonSession-5IBYEXS5.js.map +0 -7
- package/dist/query-NHQFKSCC.js +0 -54
- package/dist/tools-HVGZBEHZ.js +0 -51
- package/dist/userInput-WFPUGJ4L.js.map +0 -7
- /package/dist/{REPL-WXPYXBW2.js.map → REPL-VOJCD6X6.js.map} +0 -0
- /package/dist/{agentsValidate-LQFWOCPZ.js.map → agentsValidate-35AHZXNB.js.map} +0 -0
- /package/dist/{autoUpdater-DEH233RT.js.map → autoUpdater-MRK5BD2L.js.map} +0 -0
- /package/dist/{chunk-JVF6KNE3.js.map → chunk-2AG4BTRV.js.map} +0 -0
- /package/dist/{chunk-PRRYL2E2.js.map → chunk-2S2V2ZI7.js.map} +0 -0
- /package/dist/{chunk-ZE75JZFY.js.map → chunk-2WIUQUTU.js.map} +0 -0
- /package/dist/{chunk-5KAIY3II.js.map → chunk-2YM35XWE.js.map} +0 -0
- /package/dist/{chunk-FDGIVQNE.js.map → chunk-AYVB6VUF.js.map} +0 -0
- /package/dist/{chunk-6XINCIUI.js.map → chunk-DYJD66YF.js.map} +0 -0
- /package/dist/{chunk-EYY3QDKX.js.map → chunk-DZTZPEPA.js.map} +0 -0
- /package/dist/{chunk-HNHWG52B.js.map → chunk-GSAG6WNQ.js.map} +0 -0
- /package/dist/{chunk-VW3NZKCP.js.map → chunk-GZT2DWED.js.map} +0 -0
- /package/dist/{chunk-BJMVIICS.js.map → chunk-HJWUPFGF.js.map} +0 -0
- /package/dist/{chunk-KH3U5BR5.js.map → chunk-IIVG2SHE.js.map} +0 -0
- /package/dist/{chunk-GS4PRJHV.js.map → chunk-JQVZNIKI.js.map} +0 -0
- /package/dist/{chunk-4SWM6FWR.js.map → chunk-KNWW4HGV.js.map} +0 -0
- /package/dist/{chunk-Z73SPR4B.js.map → chunk-NTL5PKCX.js.map} +0 -0
- /package/dist/{chunk-2NFKKANF.js.map → chunk-PXPTGNYH.js.map} +0 -0
- /package/dist/{chunk-HIZXCXUG.js.map → chunk-QUWUFGZF.js.map} +0 -0
- /package/dist/{chunk-BX6HNPWQ.js.map → chunk-SZEYDC6A.js.map} +0 -0
- /package/dist/{chunk-AB3F7T5N.js.map → chunk-TWWQYBVK.js.map} +0 -0
- /package/dist/{chunk-UUS77RPP.js.map → chunk-U265OPSO.js.map} +0 -0
- /package/dist/{chunk-4NNDWUSZ.js.map → chunk-UBX7JQR2.js.map} +0 -0
- /package/dist/{chunk-4VUECEM6.js.map → chunk-UXVOYFKL.js.map} +0 -0
- /package/dist/{chunk-37ZXN5M4.js.map → chunk-VMWEFYQB.js.map} +0 -0
- /package/dist/{chunk-B3NR3UMC.js.map → chunk-WVYIFMLG.js.map} +0 -0
- /package/dist/{chunk-GMKASRN7.js.map → chunk-Y5JPSTQ4.js.map} +0 -0
- /package/dist/{chunk-7ANXEZRS.js.map → chunk-ZW25QNXS.js.map} +0 -0
- /package/dist/{commands-LAZD5O4M.js.map → commands-3B77L2SI.js.map} +0 -0
- /package/dist/{config-VK55G2IB.js.map → config-KZHPV37P.js.map} +0 -0
- /package/dist/{context-QHTEENJ6.js.map → context-ZZI53BPM.js.map} +0 -0
- /package/dist/{customCommands-HRHE7ZIM.js.map → conversationTracker-SC6NCQHL.js.map} +0 -0
- /package/dist/{env-GGYUE5V7.js.map → customCommands-MX6OENKO.js.map} +0 -0
- /package/dist/{file-KHYC624L.js.map → env-76WAAGI6.js.map} +0 -0
- /package/dist/{llmLazy-USVVGSVL.js.map → file-LCS77XWE.js.map} +0 -0
- /package/dist/{loader-JPKYTFFC.js.map → llmLazy-5W6E5BCB.js.map} +0 -0
- /package/dist/{lsp-B7QJVI2U.js.map → loader-OWZ3WD2X.js.map} +0 -0
- /package/dist/{mcp-YOR7UMEZ.js.map → lsp-NLPSJYH4.js.map} +0 -0
- /package/dist/{lspAnchor-JJJ2WKI7.js.map → lspAnchor-MWASWGQD.js.map} +0 -0
- /package/dist/{messages-ICKAWGUW.js.map → mcp-T2UB74Y2.js.map} +0 -0
- /package/dist/{mentionProcessor-5CYA4NR4.js.map → mentionProcessor-KIBWOHEC.js.map} +0 -0
- /package/dist/{model-P33QONA2.js.map → messages-6BHCXDWR.js.map} +0 -0
- /package/dist/{openai-POLCH476.js.map → model-5NDSZPIL.js.map} +0 -0
- /package/dist/{outputStyles-EZGCOEE2.js.map → openai-7XPWH2G7.js.map} +0 -0
- /package/dist/{pluginValidation-MR5GV7PL.js.map → outputStyles-QUE4ALJQ.js.map} +0 -0
- /package/dist/{pluginRuntime-KJ3YFO2O.js.map → pluginRuntime-PQ3VZRX7.js.map} +0 -0
- /package/dist/{prompts-P4JU57HZ.js.map → pluginValidation-RQ34XQY3.js.map} +0 -0
- /package/dist/{pybAgentSessionLoad-TRSWA62U.js.map → prompts-5576MRUX.js.map} +0 -0
- /package/dist/{pybAgentSessionResume-3IRNTCVI.js.map → pybAgentSessionLoad-5MWAY2A4.js.map} +0 -0
- /package/dist/{pybHooks-HFAKEYDS.js.map → pybAgentSessionResume-NZGSUGGS.js.map} +0 -0
- /package/dist/{query-NHQFKSCC.js.map → pybHooks-HILU7ZB4.js.map} +0 -0
- /package/dist/{registry-LOKL3JBE.js.map → query-LMPE4HBF.js.map} +0 -0
- /package/dist/{ripgrep-X4LOQHA7.js.map → registry-4MWYBUFA.js.map} +0 -0
- /package/dist/{skillMarketplace-UITGQNZD.js.map → replSessionBridge-EBXNFUAD.js.map} +0 -0
- /package/dist/{state-I7LIGIFJ.js.map → ripgrep-J74GL455.js.map} +0 -0
- /package/dist/{theme-RVIXXPSQ.js.map → skillMarketplace-ATLDIEEX.js.map} +0 -0
- /package/dist/{toolPermissionSettings-TALALPH3.js.map → state-Y2Q4MPY5.js.map} +0 -0
- /package/dist/{tools-HVGZBEHZ.js.map → theme-3L66ZU5Z.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/services/ai/openai.ts"
|
|
4
|
-
"sourcesContent": ["import { OpenAI } from 'openai'\nimport { getGlobalConfig, GlobalConfig } from '@utils/config'\nimport { ProxyAgent, fetch, Response } from 'undici'\nimport { setSessionState, getSessionState } from '@utils/session/sessionState'\nimport {\n debug as debugLogger,\n getCurrentRequest,\n logAPIError,\n} from '@utils/log/debugLogger'\n\nconst RETRY_CONFIG = {\n BASE_DELAY_MS: 1000,\n MAX_DELAY_MS: 32000,\n MAX_SERVER_DELAY_MS: 60000,\n JITTER_FACTOR: 0.1,\n} as const\n\nfunction getRetryDelay(attempt: number, retryAfter?: string | null): number {\n if (retryAfter) {\n const retryAfterMs = parseInt(retryAfter) * 1000\n if (!isNaN(retryAfterMs) && retryAfterMs > 0) {\n return Math.min(retryAfterMs, RETRY_CONFIG.MAX_SERVER_DELAY_MS)\n }\n }\n\n const delay = RETRY_CONFIG.BASE_DELAY_MS * Math.pow(2, attempt - 1)\n const jitter = Math.random() * RETRY_CONFIG.JITTER_FACTOR * delay\n\n return Math.min(delay + jitter, RETRY_CONFIG.MAX_DELAY_MS)\n}\n\nfunction abortableDelay(delayMs: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new Error('Request was aborted'))\n return\n }\n\n const timeoutId = setTimeout(() => {\n resolve()\n }, delayMs)\n\n if (signal) {\n const abortHandler = () => {\n clearTimeout(timeoutId)\n reject(new Error('Request was aborted'))\n }\n signal.addEventListener('abort', abortHandler, { once: true })\n }\n })\n}\n\nenum ModelErrorType {\n MaxLength = '1024',\n MaxCompletionTokens = 'max_completion_tokens',\n TemperatureRestriction = 'temperature_restriction',\n StreamOptions = 'stream_options',\n Citations = 'citations',\n RateLimit = 'rate_limit',\n}\n\nfunction getModelErrorKey(\n baseURL: string,\n model: string,\n type: ModelErrorType,\n): string {\n return `${baseURL}:${model}:${type}`\n}\n\nfunction hasModelError(\n baseURL: string,\n model: string,\n type: ModelErrorType,\n): boolean {\n return !!getSessionState('modelErrors')[\n getModelErrorKey(baseURL, model, type)\n ]\n}\n\nfunction setModelError(\n baseURL: string,\n model: string,\n type: ModelErrorType,\n error: string,\n) {\n setSessionState('modelErrors', {\n [getModelErrorKey(baseURL, model, type)]: error,\n })\n}\n\ntype ErrorDetector = (errMsg: string) => boolean\ntype ErrorFixer = (\n opts: OpenAI.ChatCompletionCreateParams,\n) => Promise<void> | void\ninterface ErrorHandler {\n type: ModelErrorType\n detect: ErrorDetector\n fix: ErrorFixer\n}\n\nconst GPT5_ERROR_HANDLERS: ErrorHandler[] = [\n {\n type: ModelErrorType.MaxCompletionTokens,\n detect: errMsg => {\n const lowerMsg = errMsg.toLowerCase()\n return (\n (lowerMsg.includes(\"unsupported parameter: 'max_tokens'\") &&\n lowerMsg.includes(\"'max_completion_tokens'\")) ||\n (lowerMsg.includes('max_tokens') &&\n lowerMsg.includes('max_completion_tokens')) ||\n (lowerMsg.includes('max_tokens') &&\n lowerMsg.includes('not supported')) ||\n (lowerMsg.includes('max_tokens') &&\n lowerMsg.includes('use max_completion_tokens')) ||\n (lowerMsg.includes('invalid parameter') &&\n lowerMsg.includes('max_tokens')) ||\n (lowerMsg.includes('parameter error') &&\n lowerMsg.includes('max_tokens'))\n )\n },\n fix: async opts => {\n debugLogger.api('GPT5_FIX_MAX_TOKENS', {\n from: opts.max_tokens,\n to: opts.max_tokens,\n })\n if ('max_tokens' in opts) {\n opts.max_completion_tokens = opts.max_tokens\n delete opts.max_tokens\n }\n },\n },\n {\n type: ModelErrorType.TemperatureRestriction,\n detect: errMsg => {\n const lowerMsg = errMsg.toLowerCase()\n return (\n lowerMsg.includes('temperature') &&\n (lowerMsg.includes('only supports') ||\n lowerMsg.includes('must be 1') ||\n lowerMsg.includes('invalid temperature'))\n )\n },\n fix: async opts => {\n debugLogger.api('GPT5_FIX_TEMPERATURE', {\n from: opts.temperature,\n to: 1,\n })\n opts.temperature = 1\n },\n },\n]\n\nconst ERROR_HANDLERS: ErrorHandler[] = [\n {\n type: ModelErrorType.MaxLength,\n detect: errMsg =>\n errMsg.includes('Expected a string with maximum length 1024'),\n fix: async opts => {\n const toolDescriptions = {}\n for (const tool of opts.tools || []) {\n if (tool.function.description.length <= 1024) continue\n let str = ''\n let remainder = ''\n for (let line of tool.function.description.split('\\n')) {\n if (str.length + line.length < 1024) {\n str += line + '\\n'\n } else {\n remainder += line + '\\n'\n }\n }\n\n tool.function.description = str\n toolDescriptions[tool.function.name] = remainder\n }\n if (Object.keys(toolDescriptions).length > 0) {\n let content = '<additional-tool-usage-instructions>\\n\\n'\n for (const [name, description] of Object.entries(toolDescriptions)) {\n content += `<${name}>\\n${description}\\n</${name}>\\n\\n`\n }\n content += '</additional-tool-usage-instructions>'\n\n for (let i = opts.messages.length - 1; i >= 0; i--) {\n if (opts.messages[i].role === 'system') {\n opts.messages.splice(i + 1, 0, {\n role: 'system',\n content,\n })\n break\n }\n }\n }\n },\n },\n {\n type: ModelErrorType.MaxCompletionTokens,\n detect: errMsg => errMsg.includes(\"Use 'max_completion_tokens'\"),\n fix: async opts => {\n opts.max_completion_tokens = opts.max_tokens\n delete opts.max_tokens\n },\n },\n {\n type: ModelErrorType.StreamOptions,\n detect: errMsg => errMsg.includes('stream_options'),\n fix: async opts => {\n delete opts.stream_options\n },\n },\n {\n type: ModelErrorType.Citations,\n detect: errMsg =>\n errMsg.includes('Extra inputs are not permitted') &&\n errMsg.includes('citations'),\n fix: async opts => {\n if (!opts.messages) return\n\n for (const message of opts.messages) {\n if (!message) continue\n\n if (Array.isArray(message.content)) {\n for (const item of message.content) {\n if (item && typeof item === 'object') {\n const itemObj = item as unknown as Record<string, unknown>\n if ('citations' in itemObj) {\n delete itemObj.citations\n }\n }\n }\n } else if (message.content && typeof message.content === 'object') {\n const contentObj = message.content as unknown as Record<\n string,\n unknown\n >\n if ('citations' in contentObj) {\n delete contentObj.citations\n }\n }\n }\n },\n },\n]\n\nfunction isRateLimitError(errMsg: string): boolean {\n if (!errMsg) return false\n const lowerMsg = errMsg.toLowerCase()\n return (\n lowerMsg.includes('rate limit') ||\n lowerMsg.includes('too many requests') ||\n lowerMsg.includes('429')\n )\n}\n\ninterface ModelFeatures {\n usesMaxCompletionTokens: boolean\n supportsResponsesAPI?: boolean\n requiresTemperatureOne?: boolean\n supportsVerbosityControl?: boolean\n supportsCustomTools?: boolean\n supportsAllowedTools?: boolean\n}\n\nconst MODEL_FEATURES: Record<string, ModelFeatures> = {\n o1: { usesMaxCompletionTokens: true },\n 'o1-preview': { usesMaxCompletionTokens: true },\n 'o1-mini': { usesMaxCompletionTokens: true },\n 'o1-pro': { usesMaxCompletionTokens: true },\n 'o3-mini': { usesMaxCompletionTokens: true },\n 'gpt-5': {\n usesMaxCompletionTokens: true,\n supportsResponsesAPI: true,\n requiresTemperatureOne: true,\n supportsVerbosityControl: true,\n supportsCustomTools: true,\n supportsAllowedTools: true,\n },\n 'gpt-5-mini': {\n usesMaxCompletionTokens: true,\n supportsResponsesAPI: true,\n requiresTemperatureOne: true,\n supportsVerbosityControl: true,\n supportsCustomTools: true,\n supportsAllowedTools: true,\n },\n 'gpt-5-nano': {\n usesMaxCompletionTokens: true,\n supportsResponsesAPI: true,\n requiresTemperatureOne: true,\n supportsVerbosityControl: true,\n supportsCustomTools: true,\n supportsAllowedTools: true,\n },\n 'gpt-5-chat-latest': {\n usesMaxCompletionTokens: true,\n supportsResponsesAPI: false,\n requiresTemperatureOne: true,\n supportsVerbosityControl: true,\n },\n}\n\nfunction getModelFeatures(modelName: string): ModelFeatures {\n if (!modelName || typeof modelName !== 'string') {\n return { usesMaxCompletionTokens: false }\n }\n\n if (MODEL_FEATURES[modelName]) {\n return MODEL_FEATURES[modelName]\n }\n\n if (modelName.toLowerCase().includes('gpt-5')) {\n return {\n usesMaxCompletionTokens: true,\n supportsResponsesAPI: true,\n requiresTemperatureOne: true,\n supportsVerbosityControl: true,\n supportsCustomTools: true,\n supportsAllowedTools: true,\n }\n }\n\n for (const [key, features] of Object.entries(MODEL_FEATURES)) {\n if (modelName.includes(key)) {\n return features\n }\n }\n\n return { usesMaxCompletionTokens: false }\n}\n\nfunction applyModelSpecificTransformations(\n opts: OpenAI.ChatCompletionCreateParams,\n): void {\n if (!opts.model || typeof opts.model !== 'string') {\n return\n }\n\n const features = getModelFeatures(opts.model)\n const isGPT5 = opts.model.toLowerCase().includes('gpt-5')\n\n if (isGPT5 || features.usesMaxCompletionTokens) {\n if ('max_tokens' in opts && !('max_completion_tokens' in opts)) {\n debugLogger.api('OPENAI_TRANSFORM_MAX_TOKENS', {\n model: opts.model,\n from: opts.max_tokens,\n })\n opts.max_completion_tokens = opts.max_tokens\n delete opts.max_tokens\n }\n\n if (features.requiresTemperatureOne && 'temperature' in opts) {\n if (opts.temperature !== 1 && opts.temperature !== undefined) {\n debugLogger.api('OPENAI_TRANSFORM_TEMPERATURE', {\n model: opts.model,\n from: opts.temperature,\n to: 1,\n })\n opts.temperature = 1\n }\n }\n\n if (isGPT5) {\n delete opts.frequency_penalty\n delete opts.presence_penalty\n delete opts.logit_bias\n delete opts.user\n\n if (!opts.reasoning_effort && features.supportsVerbosityControl) {\n opts.reasoning_effort = 'medium'\n }\n }\n }\n\n else {\n if (\n features.usesMaxCompletionTokens &&\n 'max_tokens' in opts &&\n !('max_completion_tokens' in opts)\n ) {\n opts.max_completion_tokens = opts.max_tokens\n delete opts.max_tokens\n }\n }\n\n}\n\nasync function applyModelErrorFixes(\n opts: OpenAI.ChatCompletionCreateParams,\n baseURL: string,\n) {\n const isGPT5 = opts.model.startsWith('gpt-5')\n const handlers = isGPT5\n ? [...GPT5_ERROR_HANDLERS, ...ERROR_HANDLERS]\n : ERROR_HANDLERS\n\n for (const handler of handlers) {\n if (hasModelError(baseURL, opts.model, handler.type)) {\n await handler.fix(opts)\n return\n }\n }\n}\n\nasync function tryWithEndpointFallback(\n baseURL: string,\n opts: OpenAI.ChatCompletionCreateParams,\n headers: Record<string, string>,\n provider: string,\n proxy: any,\n signal?: AbortSignal,\n): Promise<{ response: Response; endpoint: string }> {\n const endpointsToTry = []\n\n if (provider === 'minimax') {\n endpointsToTry.push('/text/chatcompletion_v2', '/chat/completions')\n } else {\n endpointsToTry.push('/chat/completions')\n }\n\n let lastError = null\n\n for (const endpoint of endpointsToTry) {\n try {\n const response = await fetch(`${baseURL}${endpoint}`, {\n method: 'POST',\n headers,\n body: JSON.stringify(opts.stream ? { ...opts, stream: true } : opts),\n dispatcher: proxy,\n signal: signal,\n })\n\n if (response.ok) {\n return { response, endpoint }\n }\n\n if (response.status === 404 && endpointsToTry.length > 1) {\n debugLogger.api('OPENAI_ENDPOINT_FALLBACK', {\n endpoint,\n status: 404,\n reason: 'not_found',\n })\n continue\n }\n\n return { response, endpoint }\n } catch (error) {\n lastError = error\n if (endpointsToTry.indexOf(endpoint) < endpointsToTry.length - 1) {\n debugLogger.api('OPENAI_ENDPOINT_FALLBACK', {\n endpoint,\n reason: 'network_error',\n error: error instanceof Error ? error.message : String(error),\n })\n continue\n }\n }\n }\n\n throw lastError || new Error('All endpoints failed')\n}\n\nexport {\n getGPT5CompletionWithProfile,\n getModelFeatures,\n applyModelSpecificTransformations,\n}\n\nexport async function getCompletionWithProfile(\n modelProfile: any,\n opts: OpenAI.ChatCompletionCreateParams,\n attempt: number = 0,\n maxAttempts: number = 10,\n signal?: AbortSignal,\n): Promise<OpenAI.ChatCompletion | AsyncIterable<OpenAI.ChatCompletionChunk>> {\n if (attempt >= maxAttempts) {\n throw new Error('Max attempts reached')\n }\n\n const provider = modelProfile?.provider || 'anthropic'\n const baseURL = modelProfile?.baseURL\n const apiKey = modelProfile?.apiKey\n const proxy = getGlobalConfig().proxy\n ? new ProxyAgent(getGlobalConfig().proxy)\n : undefined\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n\n if (apiKey) {\n if (provider === 'azure') {\n headers['api-key'] = apiKey\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`\n }\n }\n\n applyModelSpecificTransformations(opts)\n await applyModelErrorFixes(opts, baseURL || '')\n\n debugLogger.api('OPENAI_API_CALL_START', {\n endpoint: baseURL || 'DEFAULT_OPENAI',\n model: opts.model,\n provider,\n apiKeyConfigured: !!apiKey,\n apiKeyPrefix: apiKey ? apiKey.substring(0, 8) : null,\n maxTokens: opts.max_tokens,\n temperature: opts.temperature,\n messageCount: opts.messages?.length || 0,\n streamMode: opts.stream,\n timestamp: new Date().toISOString(),\n modelProfileModelName: modelProfile?.modelName,\n modelProfileName: modelProfile?.name,\n })\n\n opts.messages = opts.messages.map(msg => {\n if (msg.role === 'tool') {\n if (Array.isArray(msg.content)) {\n return {\n ...msg,\n content:\n msg.content\n .map(c => c.text || '')\n .filter(Boolean)\n .join('\\n\\n') || '(empty content)',\n }\n } else if (typeof msg.content !== 'string') {\n return {\n ...msg,\n content:\n typeof msg.content === 'undefined'\n ? '(empty content)'\n : JSON.stringify(msg.content),\n }\n }\n }\n return msg\n })\n\n const azureApiVersion = '2024-06-01'\n let endpoint = '/chat/completions'\n\n if (provider === 'azure') {\n endpoint = `/chat/completions?api-version=${azureApiVersion}`\n } else if (provider === 'minimax') {\n endpoint = '/text/chatcompletion_v2'\n }\n\n try {\n if (opts.stream) {\n const isOpenAICompatible = [\n 'minimax',\n 'kimi',\n 'deepseek',\n 'siliconflow',\n 'qwen',\n 'qwen-coding',\n 'glm',\n 'glm-coding',\n 'baidu-qianfan',\n 'openai',\n 'mistral',\n 'xai',\n 'groq',\n 'custom-openai',\n ].includes(provider)\n\n let response: Response\n let usedEndpoint: string\n\n if (isOpenAICompatible && provider !== 'azure') {\n const result = await tryWithEndpointFallback(\n baseURL,\n opts,\n headers,\n provider,\n proxy,\n signal,\n )\n response = result.response\n usedEndpoint = result.endpoint\n } else {\n response = await fetch(`${baseURL}${endpoint}`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ ...opts, stream: true }),\n dispatcher: proxy,\n signal: signal,\n })\n usedEndpoint = endpoint\n }\n\n if (!response.ok) {\n if (signal?.aborted) {\n throw new Error('Request cancelled by user')\n }\n\n try {\n const errorData = await response.json()\n const hasError = (\n data: unknown,\n ): data is { error?: { message?: string }; message?: string } => {\n return typeof data === 'object' && data !== null\n }\n const errorMessage = hasError(errorData)\n ? errorData.error?.message ||\n errorData.message ||\n `HTTP ${response.status}`\n : `HTTP ${response.status}`\n\n const isGPT5 = opts.model.startsWith('gpt-5')\n const handlers = isGPT5\n ? [...GPT5_ERROR_HANDLERS, ...ERROR_HANDLERS]\n : ERROR_HANDLERS\n\n for (const handler of handlers) {\n if (handler.detect(errorMessage)) {\n debugLogger.api('OPENAI_MODEL_ERROR_DETECTED', {\n model: opts.model,\n type: handler.type,\n errorMessage,\n status: response.status,\n })\n\n setModelError(\n baseURL || '',\n opts.model,\n handler.type,\n errorMessage,\n )\n\n await handler.fix(opts)\n debugLogger.api('OPENAI_MODEL_ERROR_FIXED', {\n model: opts.model,\n type: handler.type,\n })\n\n return getCompletionWithProfile(\n modelProfile,\n opts,\n attempt + 1,\n maxAttempts,\n signal,\n )\n }\n }\n\n debugLogger.warn('OPENAI_API_ERROR_UNHANDLED', {\n model: opts.model,\n status: response.status,\n errorMessage,\n })\n\n logAPIError({\n model: opts.model,\n endpoint: `${baseURL}${endpoint}`,\n status: response.status,\n error: errorMessage,\n request: opts,\n response: errorData,\n provider: provider,\n })\n } catch (parseError) {\n debugLogger.warn('OPENAI_API_ERROR_PARSE_FAILED', {\n model: opts.model,\n status: response.status,\n error: parseError instanceof Error ? parseError.message : String(parseError),\n })\n\n logAPIError({\n model: opts.model,\n endpoint: `${baseURL}${endpoint}`,\n status: response.status,\n error: `Could not parse error response: ${parseError.message}`,\n request: opts,\n response: { parseError: parseError.message },\n provider: provider,\n })\n }\n\n const delayMs = getRetryDelay(attempt)\n debugLogger.warn('OPENAI_API_RETRY', {\n model: opts.model,\n status: response.status,\n attempt: attempt + 1,\n maxAttempts,\n delayMs,\n })\n try {\n await abortableDelay(delayMs, signal)\n } catch (error) {\n if (error.message === 'Request was aborted') {\n throw new Error('Request cancelled by user')\n }\n throw error\n }\n return getCompletionWithProfile(\n modelProfile,\n opts,\n attempt + 1,\n maxAttempts,\n signal,\n )\n }\n\n const stream = createStreamProcessor(response.body as any, signal)\n return stream\n }\n\n const isOpenAICompatible = [\n 'minimax',\n 'kimi',\n 'deepseek',\n 'siliconflow',\n 'qwen',\n 'glm',\n 'baidu-qianfan',\n 'openai',\n 'mistral',\n 'xai',\n 'groq',\n 'custom-openai',\n ].includes(provider)\n\n let response: Response\n let usedEndpoint: string\n\n if (isOpenAICompatible && provider !== 'azure') {\n const result = await tryWithEndpointFallback(\n baseURL,\n opts,\n headers,\n provider,\n proxy,\n signal,\n )\n response = result.response\n usedEndpoint = result.endpoint\n } else {\n response = await fetch(`${baseURL}${endpoint}`, {\n method: 'POST',\n headers,\n body: JSON.stringify(opts),\n dispatcher: proxy,\n signal: signal,\n })\n usedEndpoint = endpoint\n }\n\n if (!response.ok) {\n if (signal?.aborted) {\n throw new Error('Request cancelled by user')\n }\n\n try {\n const errorData = await response.json()\n const hasError = (\n data: unknown,\n ): data is { error?: { message?: string }; message?: string } => {\n return typeof data === 'object' && data !== null\n }\n const errorMessage = hasError(errorData)\n ? errorData.error?.message ||\n errorData.message ||\n `HTTP ${response.status}`\n : `HTTP ${response.status}`\n\n const isGPT5 = opts.model.startsWith('gpt-5')\n const handlers = isGPT5\n ? [...GPT5_ERROR_HANDLERS, ...ERROR_HANDLERS]\n : ERROR_HANDLERS\n\n for (const handler of handlers) {\n if (handler.detect(errorMessage)) {\n debugLogger.api('OPENAI_MODEL_ERROR_DETECTED', {\n model: opts.model,\n type: handler.type,\n errorMessage,\n status: response.status,\n })\n\n setModelError(baseURL || '', opts.model, handler.type, errorMessage)\n\n await handler.fix(opts)\n debugLogger.api('OPENAI_MODEL_ERROR_FIXED', {\n model: opts.model,\n type: handler.type,\n })\n\n return getCompletionWithProfile(\n modelProfile,\n opts,\n attempt + 1,\n maxAttempts,\n signal,\n )\n }\n }\n\n debugLogger.warn('OPENAI_API_ERROR_UNHANDLED', {\n model: opts.model,\n status: response.status,\n errorMessage,\n })\n } catch (parseError) {\n debugLogger.warn('OPENAI_API_ERROR_PARSE_FAILED', {\n model: opts.model,\n status: response.status,\n error: parseError instanceof Error ? parseError.message : String(parseError),\n })\n }\n\n const delayMs = getRetryDelay(attempt)\n debugLogger.warn('OPENAI_API_RETRY', {\n model: opts.model,\n status: response.status,\n attempt: attempt + 1,\n maxAttempts,\n delayMs,\n })\n try {\n await abortableDelay(delayMs, signal)\n } catch (error) {\n if (error.message === 'Request was aborted') {\n throw new Error('Request cancelled by user')\n }\n throw error\n }\n return getCompletionWithProfile(\n modelProfile,\n opts,\n attempt + 1,\n maxAttempts,\n signal,\n )\n }\n\n const responseData = (await response.json()) as OpenAI.ChatCompletion\n return responseData\n } catch (error) {\n if (signal?.aborted) {\n throw new Error('Request cancelled by user')\n }\n\n if (attempt < maxAttempts) {\n if (signal?.aborted) {\n throw new Error('Request cancelled by user')\n }\n\n const delayMs = getRetryDelay(attempt)\n debugLogger.warn('OPENAI_NETWORK_RETRY', {\n model: opts.model,\n attempt: attempt + 1,\n maxAttempts,\n delayMs,\n error: error instanceof Error ? error.message : String(error),\n })\n try {\n await abortableDelay(delayMs, signal)\n } catch (error) {\n if (error.message === 'Request was aborted') {\n throw new Error('Request cancelled by user')\n }\n throw error\n }\n return getCompletionWithProfile(\n modelProfile,\n opts,\n attempt + 1,\n maxAttempts,\n signal,\n )\n }\n throw error\n }\n}\n\nexport function createStreamProcessor(\n stream: any,\n signal?: AbortSignal,\n): AsyncGenerator<OpenAI.ChatCompletionChunk, void, unknown> {\n if (!stream) {\n throw new Error('Stream is null or undefined')\n }\n\n return (async function* () {\n const reader = stream.getReader()\n const decoder = new TextDecoder('utf-8')\n let buffer = ''\n\n try {\n while (true) {\n if (signal?.aborted) {\n break\n }\n\n let readResult\n try {\n readResult = await reader.read()\n } catch (e) {\n if (signal?.aborted) {\n break\n }\n debugLogger.warn('OPENAI_STREAM_READ_ERROR', {\n error: e instanceof Error ? e.message : String(e),\n })\n break\n }\n\n const { done, value } = readResult\n if (done) {\n break\n }\n\n const chunk = decoder.decode(value, { stream: true })\n buffer += chunk\n\n let lineEnd = buffer.indexOf('\\n')\n while (lineEnd !== -1) {\n const line = buffer.substring(0, lineEnd).trim()\n buffer = buffer.substring(lineEnd + 1)\n\n if (line === 'data: [DONE]') {\n continue\n }\n\n if (line.startsWith('data: ')) {\n const data = line.slice(6).trim()\n if (!data) continue\n\n try {\n const parsed = JSON.parse(data) as OpenAI.ChatCompletionChunk\n yield parsed\n } catch (e) {\n debugLogger.warn('OPENAI_STREAM_JSON_PARSE_ERROR', {\n data,\n error: e instanceof Error ? e.message : String(e),\n })\n }\n }\n\n lineEnd = buffer.indexOf('\\n')\n }\n }\n\n if (buffer.trim()) {\n const lines = buffer.trim().split('\\n')\n for (const line of lines) {\n if (line.startsWith('data: ') && line !== 'data: [DONE]') {\n const data = line.slice(6).trim()\n if (!data) continue\n\n try {\n const parsed = JSON.parse(data) as OpenAI.ChatCompletionChunk\n yield parsed\n } catch (e) {\n debugLogger.warn('OPENAI_STREAM_FINAL_JSON_PARSE_ERROR', {\n data,\n error: e instanceof Error ? e.message : String(e),\n })\n }\n }\n }\n }\n } catch (e) {\n debugLogger.warn('OPENAI_STREAM_UNEXPECTED_ERROR', {\n error: e instanceof Error ? e.message : String(e),\n })\n } finally {\n try {\n reader.releaseLock()\n } catch (e) {\n debugLogger.warn('OPENAI_STREAM_RELEASE_LOCK_ERROR', {\n error: e instanceof Error ? e.message : String(e),\n })\n }\n }\n })()\n}\n\nexport function streamCompletion(\n stream: any,\n signal?: AbortSignal,\n): AsyncGenerator<OpenAI.ChatCompletionChunk, void, unknown> {\n return createStreamProcessor(stream, signal)\n}\n\nexport async function callGPT5ResponsesAPI(\n modelProfile: any,\n request: any,\n signal?: AbortSignal,\n): Promise<any> {\n const baseURL = modelProfile?.baseURL || 'https://api.openai.com/v1'\n const apiKey = modelProfile?.apiKey\n const proxy = getGlobalConfig().proxy\n ? new ProxyAgent(getGlobalConfig().proxy)\n : undefined\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n }\n\n const responsesParams = request\n\n try {\n const response = await fetch(`${baseURL}/responses`, {\n method: 'POST',\n headers,\n body: JSON.stringify(responsesParams),\n dispatcher: proxy,\n signal: signal,\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n throw new Error(\n `GPT-5 Responses API error: ${response.status} ${response.statusText} - ${errorText}`,\n )\n }\n\n return response\n } catch (error) {\n if (signal?.aborted) {\n throw new Error('Request cancelled by user')\n }\n throw error\n }\n}\n\nfunction convertResponsesAPIToChatCompletion(responsesData: any): any {\n let outputText = responsesData.output_text || ''\n const usage = responsesData.usage || {}\n\n if (responsesData.output && Array.isArray(responsesData.output)) {\n const reasoningItems = responsesData.output.filter(\n item => item.type === 'reasoning' && item.summary,\n )\n const messageItems = responsesData.output.filter(\n item => item.type === 'message',\n )\n\n if (reasoningItems.length > 0 && messageItems.length > 0) {\n const reasoningSummary = reasoningItems\n .map(item => item.summary?.map(s => s.text).join('\\n'))\n .filter(Boolean)\n .join('\\n\\n')\n\n const mainContent = messageItems\n .map(item => item.content?.map(c => c.text).join('\\n'))\n .filter(Boolean)\n .join('\\n\\n')\n\n if (reasoningSummary) {\n outputText = `**\uD83E\uDDE0 Reasoning Process:**\\n${reasoningSummary}\\n\\n**\uD83D\uDCDD Response:**\\n${mainContent}`\n } else {\n outputText = mainContent\n }\n }\n }\n\n return {\n id: responsesData.id || `chatcmpl-${Date.now()}`,\n object: 'chat.completion',\n created: Math.floor(Date.now() / 1000),\n model: responsesData.model || '',\n choices: [\n {\n index: 0,\n message: {\n role: 'assistant',\n content: outputText,\n ...(responsesData.reasoning && {\n reasoning: {\n effort: responsesData.reasoning.effort,\n summary: responsesData.reasoning.summary,\n },\n }),\n },\n finish_reason: responsesData.status === 'completed' ? 'stop' : 'length',\n },\n ],\n usage: {\n prompt_tokens: usage.input_tokens || 0,\n completion_tokens: usage.output_tokens || 0,\n total_tokens: (usage.input_tokens || 0) + (usage.output_tokens || 0),\n prompt_tokens_details: {\n cached_tokens: usage.input_tokens_details?.cached_tokens || 0,\n },\n completion_tokens_details: {\n reasoning_tokens: usage.output_tokens_details?.reasoning_tokens || 0,\n },\n },\n }\n}\n\nasync function getGPT5CompletionWithProfile(\n modelProfile: any,\n opts: OpenAI.ChatCompletionCreateParams,\n attempt: number = 0,\n maxAttempts: number = 10,\n signal?: AbortSignal,\n): Promise<OpenAI.ChatCompletion | AsyncIterable<OpenAI.ChatCompletionChunk>> {\n const features = getModelFeatures(opts.model)\n const isOfficialOpenAI =\n !modelProfile.baseURL || modelProfile.baseURL.includes('api.openai.com')\n\n if (!isOfficialOpenAI) {\n debugLogger.api('GPT5_THIRD_PARTY_PROVIDER', {\n model: opts.model,\n baseURL: modelProfile.baseURL,\n provider: modelProfile.provider,\n supportsResponsesAPI: features.supportsResponsesAPI,\n requestId: getCurrentRequest()?.id,\n })\n\n debugLogger.api('GPT5_PROVIDER_THIRD_PARTY_NOTICE', {\n model: opts.model,\n provider: modelProfile.provider,\n baseURL: modelProfile.baseURL,\n })\n\n if (modelProfile.provider === 'azure') {\n delete opts.reasoning_effort\n } else if (modelProfile.provider === 'custom-openai') {\n debugLogger.api('GPT5_CUSTOM_PROVIDER_OPTIMIZATIONS', {\n model: opts.model,\n provider: modelProfile.provider,\n })\n }\n }\n\n else if (opts.stream) {\n debugLogger.api('GPT5_STREAMING_MODE', {\n model: opts.model,\n baseURL: modelProfile.baseURL || 'official',\n reason: 'responses_api_no_streaming',\n requestId: getCurrentRequest()?.id,\n })\n\n debugLogger.api('GPT5_STREAMING_FALLBACK_TO_CHAT_COMPLETIONS', {\n model: opts.model,\n reason: 'responses_api_no_streaming',\n })\n }\n\n debugLogger.api('USING_CHAT_COMPLETIONS_FOR_GPT5', {\n model: opts.model,\n baseURL: modelProfile.baseURL || 'official',\n provider: modelProfile.provider,\n reason: isOfficialOpenAI ? 'streaming_or_fallback' : 'third_party_provider',\n requestId: getCurrentRequest()?.id,\n })\n\n return await getCompletionWithProfile(\n modelProfile,\n opts,\n attempt,\n maxAttempts,\n signal,\n )\n}\n\nexport async function fetchCustomModels(\n baseURL: string,\n apiKey: string,\n): Promise<any[]> {\n try {\n const hasVersionNumber = /\\/v\\d+/.test(baseURL)\n const cleanBaseURL = baseURL.replace(/\\/+$/, '')\n const modelsURL = hasVersionNumber\n ? `${cleanBaseURL}/models`\n : `${cleanBaseURL}/v1/models`\n\n const response = await fetch(modelsURL, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n })\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\n 'Invalid API key. Please check your API key and try again.',\n )\n } else if (response.status === 403) {\n throw new Error(\n 'API key does not have permission to access models. Please check your API key permissions.',\n )\n } else if (response.status === 404) {\n throw new Error(\n 'API endpoint not found. Please check if the base URL is correct and supports the /models endpoint.',\n )\n } else if (response.status === 429) {\n throw new Error(\n 'Too many requests. Please wait a moment and try again.',\n )\n } else if (response.status >= 500) {\n throw new Error(\n 'API service is temporarily unavailable. Please try again later.',\n )\n } else {\n throw new Error(\n `Unable to connect to API (${response.status}). Please check your base URL, API key, and internet connection.`,\n )\n }\n }\n\n const data = await response.json()\n\n const hasDataArray = (obj: unknown): obj is { data: unknown[] } => {\n return (\n typeof obj === 'object' &&\n obj !== null &&\n 'data' in obj &&\n Array.isArray((obj as any).data)\n )\n }\n\n const hasModelsArray = (obj: unknown): obj is { models: unknown[] } => {\n return (\n typeof obj === 'object' &&\n obj !== null &&\n 'models' in obj &&\n Array.isArray((obj as any).models)\n )\n }\n\n let models = []\n\n if (hasDataArray(data)) {\n models = data.data\n } else if (Array.isArray(data)) {\n models = data\n } else if (hasModelsArray(data)) {\n models = data.models\n } else {\n throw new Error(\n 'API returned unexpected response format. Expected an array of models or an object with a \"data\" or \"models\" array.',\n )\n }\n\n if (!Array.isArray(models)) {\n throw new Error('API response format error: models data is not an array.')\n }\n\n return models\n } catch (error) {\n if (\n error instanceof Error &&\n (error.message.includes('API key') ||\n error.message.includes('API endpoint') ||\n error.message.includes('API service') ||\n error.message.includes('response format'))\n ) {\n throw error\n }\n\n debugLogger.warn('CUSTOM_API_MODELS_FETCH_FAILED', {\n baseURL,\n error: error instanceof Error ? error.message : String(error),\n })\n\n if (error instanceof Error && error.message.includes('fetch')) {\n throw new Error(\n 'Unable to connect to the API. Please check the base URL and your internet connection.',\n )\n }\n\n throw new Error(\n 'Failed to fetch models from custom API. Please check your configuration and try again.',\n )\n }\n}\n", "type SessionState = {\n modelErrors: Record<string, unknown>\n currentError: string | null\n}\n\nconst isDebug =\n process.argv.includes('--debug') ||\n process.argv.includes('-d') ||\n process.env.DEBUG === 'true'\n\nconst sessionState: SessionState = {\n modelErrors: {},\n currentError: null,\n} as const\n\nfunction setSessionState<K extends keyof SessionState>(\n key: K,\n value: SessionState[K],\n): void\nfunction setSessionState(partialState: Partial<SessionState>): void\nfunction setSessionState(\n keyOrState: keyof SessionState | Partial<SessionState>,\n value?: any,\n): void {\n if (typeof keyOrState === 'string') {\n sessionState[keyOrState] = value\n } else {\n Object.assign(sessionState, keyOrState)\n }\n}\n\nfunction getSessionState(): SessionState\nfunction getSessionState<K extends keyof SessionState>(key: K): SessionState[K]\nfunction getSessionState<K extends keyof SessionState>(key?: K) {\n return key === undefined ? sessionState : sessionState[key]\n}\n\nexport type { SessionState }\nexport { setSessionState, getSessionState }\nexport default sessionState\n"],
|
|
5
|
-
"mappings": "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",
|
|
3
|
+
"sources": ["../src/services/ai/openai.ts"],
|
|
4
|
+
"sourcesContent": ["import { OpenAI } from 'openai'\nimport { getGlobalConfig, GlobalConfig } from '@utils/config'\nimport { ProxyAgent, fetch, Response } from 'undici'\nimport { setSessionState, getSessionState } from '@utils/session/sessionState'\nimport {\n debug as debugLogger,\n getCurrentRequest,\n logAPIError,\n} from '@utils/log/debugLogger'\n\nconst RETRY_CONFIG = {\n BASE_DELAY_MS: 1000,\n MAX_DELAY_MS: 32000,\n MAX_SERVER_DELAY_MS: 60000,\n JITTER_FACTOR: 0.1,\n} as const\n\nfunction getRetryDelay(attempt: number, retryAfter?: string | null): number {\n if (retryAfter) {\n const retryAfterMs = parseInt(retryAfter) * 1000\n if (!isNaN(retryAfterMs) && retryAfterMs > 0) {\n return Math.min(retryAfterMs, RETRY_CONFIG.MAX_SERVER_DELAY_MS)\n }\n }\n\n const delay = RETRY_CONFIG.BASE_DELAY_MS * Math.pow(2, attempt - 1)\n const jitter = Math.random() * RETRY_CONFIG.JITTER_FACTOR * delay\n\n return Math.min(delay + jitter, RETRY_CONFIG.MAX_DELAY_MS)\n}\n\nfunction abortableDelay(delayMs: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new Error('Request was aborted'))\n return\n }\n\n const timeoutId = setTimeout(() => {\n resolve()\n }, delayMs)\n\n if (signal) {\n const abortHandler = () => {\n clearTimeout(timeoutId)\n reject(new Error('Request was aborted'))\n }\n signal.addEventListener('abort', abortHandler, { once: true })\n }\n })\n}\n\nenum ModelErrorType {\n MaxLength = '1024',\n MaxCompletionTokens = 'max_completion_tokens',\n TemperatureRestriction = 'temperature_restriction',\n StreamOptions = 'stream_options',\n Citations = 'citations',\n RateLimit = 'rate_limit',\n}\n\nfunction getModelErrorKey(\n baseURL: string,\n model: string,\n type: ModelErrorType,\n): string {\n return `${baseURL}:${model}:${type}`\n}\n\nfunction hasModelError(\n baseURL: string,\n model: string,\n type: ModelErrorType,\n): boolean {\n return !!getSessionState('modelErrors')[\n getModelErrorKey(baseURL, model, type)\n ]\n}\n\nfunction setModelError(\n baseURL: string,\n model: string,\n type: ModelErrorType,\n error: string,\n) {\n setSessionState('modelErrors', {\n [getModelErrorKey(baseURL, model, type)]: error,\n })\n}\n\ntype ErrorDetector = (errMsg: string) => boolean\ntype ErrorFixer = (\n opts: OpenAI.ChatCompletionCreateParams,\n) => Promise<void> | void\ninterface ErrorHandler {\n type: ModelErrorType\n detect: ErrorDetector\n fix: ErrorFixer\n}\n\nconst GPT5_ERROR_HANDLERS: ErrorHandler[] = [\n {\n type: ModelErrorType.MaxCompletionTokens,\n detect: errMsg => {\n const lowerMsg = errMsg.toLowerCase()\n return (\n (lowerMsg.includes(\"unsupported parameter: 'max_tokens'\") &&\n lowerMsg.includes(\"'max_completion_tokens'\")) ||\n (lowerMsg.includes('max_tokens') &&\n lowerMsg.includes('max_completion_tokens')) ||\n (lowerMsg.includes('max_tokens') &&\n lowerMsg.includes('not supported')) ||\n (lowerMsg.includes('max_tokens') &&\n lowerMsg.includes('use max_completion_tokens')) ||\n (lowerMsg.includes('invalid parameter') &&\n lowerMsg.includes('max_tokens')) ||\n (lowerMsg.includes('parameter error') &&\n lowerMsg.includes('max_tokens'))\n )\n },\n fix: async opts => {\n debugLogger.api('GPT5_FIX_MAX_TOKENS', {\n from: opts.max_tokens,\n to: opts.max_tokens,\n })\n if ('max_tokens' in opts) {\n opts.max_completion_tokens = opts.max_tokens\n delete opts.max_tokens\n }\n },\n },\n {\n type: ModelErrorType.TemperatureRestriction,\n detect: errMsg => {\n const lowerMsg = errMsg.toLowerCase()\n return (\n lowerMsg.includes('temperature') &&\n (lowerMsg.includes('only supports') ||\n lowerMsg.includes('must be 1') ||\n lowerMsg.includes('invalid temperature'))\n )\n },\n fix: async opts => {\n debugLogger.api('GPT5_FIX_TEMPERATURE', {\n from: opts.temperature,\n to: 1,\n })\n opts.temperature = 1\n },\n },\n]\n\nconst ERROR_HANDLERS: ErrorHandler[] = [\n {\n type: ModelErrorType.MaxLength,\n detect: errMsg =>\n errMsg.includes('Expected a string with maximum length 1024'),\n fix: async opts => {\n const toolDescriptions = {}\n for (const tool of opts.tools || []) {\n if (tool.function.description.length <= 1024) continue\n let str = ''\n let remainder = ''\n for (let line of tool.function.description.split('\\n')) {\n if (str.length + line.length < 1024) {\n str += line + '\\n'\n } else {\n remainder += line + '\\n'\n }\n }\n\n tool.function.description = str\n toolDescriptions[tool.function.name] = remainder\n }\n if (Object.keys(toolDescriptions).length > 0) {\n let content = '<additional-tool-usage-instructions>\\n\\n'\n for (const [name, description] of Object.entries(toolDescriptions)) {\n content += `<${name}>\\n${description}\\n</${name}>\\n\\n`\n }\n content += '</additional-tool-usage-instructions>'\n\n for (let i = opts.messages.length - 1; i >= 0; i--) {\n if (opts.messages[i].role === 'system') {\n opts.messages.splice(i + 1, 0, {\n role: 'system',\n content,\n })\n break\n }\n }\n }\n },\n },\n {\n type: ModelErrorType.MaxCompletionTokens,\n detect: errMsg => errMsg.includes(\"Use 'max_completion_tokens'\"),\n fix: async opts => {\n opts.max_completion_tokens = opts.max_tokens\n delete opts.max_tokens\n },\n },\n {\n type: ModelErrorType.StreamOptions,\n detect: errMsg => errMsg.includes('stream_options'),\n fix: async opts => {\n delete opts.stream_options\n },\n },\n {\n type: ModelErrorType.Citations,\n detect: errMsg =>\n errMsg.includes('Extra inputs are not permitted') &&\n errMsg.includes('citations'),\n fix: async opts => {\n if (!opts.messages) return\n\n for (const message of opts.messages) {\n if (!message) continue\n\n if (Array.isArray(message.content)) {\n for (const item of message.content) {\n if (item && typeof item === 'object') {\n const itemObj = item as unknown as Record<string, unknown>\n if ('citations' in itemObj) {\n delete itemObj.citations\n }\n }\n }\n } else if (message.content && typeof message.content === 'object') {\n const contentObj = message.content as unknown as Record<\n string,\n unknown\n >\n if ('citations' in contentObj) {\n delete contentObj.citations\n }\n }\n }\n },\n },\n]\n\nfunction isRateLimitError(errMsg: string): boolean {\n if (!errMsg) return false\n const lowerMsg = errMsg.toLowerCase()\n return (\n lowerMsg.includes('rate limit') ||\n lowerMsg.includes('too many requests') ||\n lowerMsg.includes('429')\n )\n}\n\ninterface ModelFeatures {\n usesMaxCompletionTokens: boolean\n supportsResponsesAPI?: boolean\n requiresTemperatureOne?: boolean\n supportsVerbosityControl?: boolean\n supportsCustomTools?: boolean\n supportsAllowedTools?: boolean\n}\n\nconst MODEL_FEATURES: Record<string, ModelFeatures> = {\n o1: { usesMaxCompletionTokens: true },\n 'o1-preview': { usesMaxCompletionTokens: true },\n 'o1-mini': { usesMaxCompletionTokens: true },\n 'o1-pro': { usesMaxCompletionTokens: true },\n 'o3-mini': { usesMaxCompletionTokens: true },\n 'gpt-5': {\n usesMaxCompletionTokens: true,\n supportsResponsesAPI: true,\n requiresTemperatureOne: true,\n supportsVerbosityControl: true,\n supportsCustomTools: true,\n supportsAllowedTools: true,\n },\n 'gpt-5-mini': {\n usesMaxCompletionTokens: true,\n supportsResponsesAPI: true,\n requiresTemperatureOne: true,\n supportsVerbosityControl: true,\n supportsCustomTools: true,\n supportsAllowedTools: true,\n },\n 'gpt-5-nano': {\n usesMaxCompletionTokens: true,\n supportsResponsesAPI: true,\n requiresTemperatureOne: true,\n supportsVerbosityControl: true,\n supportsCustomTools: true,\n supportsAllowedTools: true,\n },\n 'gpt-5-chat-latest': {\n usesMaxCompletionTokens: true,\n supportsResponsesAPI: false,\n requiresTemperatureOne: true,\n supportsVerbosityControl: true,\n },\n}\n\nfunction getModelFeatures(modelName: string): ModelFeatures {\n if (!modelName || typeof modelName !== 'string') {\n return { usesMaxCompletionTokens: false }\n }\n\n if (MODEL_FEATURES[modelName]) {\n return MODEL_FEATURES[modelName]\n }\n\n if (modelName.toLowerCase().includes('gpt-5')) {\n return {\n usesMaxCompletionTokens: true,\n supportsResponsesAPI: true,\n requiresTemperatureOne: true,\n supportsVerbosityControl: true,\n supportsCustomTools: true,\n supportsAllowedTools: true,\n }\n }\n\n for (const [key, features] of Object.entries(MODEL_FEATURES)) {\n if (modelName.includes(key)) {\n return features\n }\n }\n\n return { usesMaxCompletionTokens: false }\n}\n\nfunction applyModelSpecificTransformations(\n opts: OpenAI.ChatCompletionCreateParams,\n): void {\n if (!opts.model || typeof opts.model !== 'string') {\n return\n }\n\n const features = getModelFeatures(opts.model)\n const isGPT5 = opts.model.toLowerCase().includes('gpt-5')\n\n if (isGPT5 || features.usesMaxCompletionTokens) {\n if ('max_tokens' in opts && !('max_completion_tokens' in opts)) {\n debugLogger.api('OPENAI_TRANSFORM_MAX_TOKENS', {\n model: opts.model,\n from: opts.max_tokens,\n })\n opts.max_completion_tokens = opts.max_tokens\n delete opts.max_tokens\n }\n\n if (features.requiresTemperatureOne && 'temperature' in opts) {\n if (opts.temperature !== 1 && opts.temperature !== undefined) {\n debugLogger.api('OPENAI_TRANSFORM_TEMPERATURE', {\n model: opts.model,\n from: opts.temperature,\n to: 1,\n })\n opts.temperature = 1\n }\n }\n\n if (isGPT5) {\n delete opts.frequency_penalty\n delete opts.presence_penalty\n delete opts.logit_bias\n delete opts.user\n\n if (!opts.reasoning_effort && features.supportsVerbosityControl) {\n opts.reasoning_effort = 'medium'\n }\n }\n }\n\n else {\n if (\n features.usesMaxCompletionTokens &&\n 'max_tokens' in opts &&\n !('max_completion_tokens' in opts)\n ) {\n opts.max_completion_tokens = opts.max_tokens\n delete opts.max_tokens\n }\n }\n\n}\n\nasync function applyModelErrorFixes(\n opts: OpenAI.ChatCompletionCreateParams,\n baseURL: string,\n) {\n const isGPT5 = opts.model.startsWith('gpt-5')\n const handlers = isGPT5\n ? [...GPT5_ERROR_HANDLERS, ...ERROR_HANDLERS]\n : ERROR_HANDLERS\n\n for (const handler of handlers) {\n if (hasModelError(baseURL, opts.model, handler.type)) {\n await handler.fix(opts)\n return\n }\n }\n}\n\nasync function tryWithEndpointFallback(\n baseURL: string,\n opts: OpenAI.ChatCompletionCreateParams,\n headers: Record<string, string>,\n provider: string,\n proxy: any,\n signal?: AbortSignal,\n): Promise<{ response: Response; endpoint: string }> {\n const endpointsToTry = []\n\n if (provider === 'minimax') {\n endpointsToTry.push('/text/chatcompletion_v2', '/chat/completions')\n } else {\n endpointsToTry.push('/chat/completions')\n }\n\n let lastError = null\n\n for (const endpoint of endpointsToTry) {\n try {\n const response = await fetch(`${baseURL}${endpoint}`, {\n method: 'POST',\n headers,\n body: JSON.stringify(opts.stream ? { ...opts, stream: true } : opts),\n dispatcher: proxy,\n signal: signal,\n })\n\n if (response.ok) {\n return { response, endpoint }\n }\n\n if (response.status === 404 && endpointsToTry.length > 1) {\n debugLogger.api('OPENAI_ENDPOINT_FALLBACK', {\n endpoint,\n status: 404,\n reason: 'not_found',\n })\n continue\n }\n\n return { response, endpoint }\n } catch (error) {\n lastError = error\n if (endpointsToTry.indexOf(endpoint) < endpointsToTry.length - 1) {\n debugLogger.api('OPENAI_ENDPOINT_FALLBACK', {\n endpoint,\n reason: 'network_error',\n error: error instanceof Error ? error.message : String(error),\n })\n continue\n }\n }\n }\n\n throw lastError || new Error('All endpoints failed')\n}\n\nexport {\n getGPT5CompletionWithProfile,\n getModelFeatures,\n applyModelSpecificTransformations,\n}\n\nexport async function getCompletionWithProfile(\n modelProfile: any,\n opts: OpenAI.ChatCompletionCreateParams,\n attempt: number = 0,\n maxAttempts: number = 10,\n signal?: AbortSignal,\n): Promise<OpenAI.ChatCompletion | AsyncIterable<OpenAI.ChatCompletionChunk>> {\n if (attempt >= maxAttempts) {\n throw new Error('Max attempts reached')\n }\n\n const provider = modelProfile?.provider || 'anthropic'\n const baseURL = modelProfile?.baseURL\n const apiKey = modelProfile?.apiKey\n const proxy = getGlobalConfig().proxy\n ? new ProxyAgent(getGlobalConfig().proxy)\n : undefined\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n }\n\n if (apiKey) {\n if (provider === 'azure') {\n headers['api-key'] = apiKey\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`\n }\n }\n\n applyModelSpecificTransformations(opts)\n await applyModelErrorFixes(opts, baseURL || '')\n\n debugLogger.api('OPENAI_API_CALL_START', {\n endpoint: baseURL || 'DEFAULT_OPENAI',\n model: opts.model,\n provider,\n apiKeyConfigured: !!apiKey,\n apiKeyPrefix: apiKey ? apiKey.substring(0, 8) : null,\n maxTokens: opts.max_tokens,\n temperature: opts.temperature,\n messageCount: opts.messages?.length || 0,\n streamMode: opts.stream,\n timestamp: new Date().toISOString(),\n modelProfileModelName: modelProfile?.modelName,\n modelProfileName: modelProfile?.name,\n })\n\n opts.messages = opts.messages.map(msg => {\n if (msg.role === 'tool') {\n if (Array.isArray(msg.content)) {\n return {\n ...msg,\n content:\n msg.content\n .map(c => c.text || '')\n .filter(Boolean)\n .join('\\n\\n') || '(empty content)',\n }\n } else if (typeof msg.content !== 'string') {\n return {\n ...msg,\n content:\n typeof msg.content === 'undefined'\n ? '(empty content)'\n : JSON.stringify(msg.content),\n }\n }\n }\n return msg\n })\n\n const azureApiVersion = '2024-06-01'\n let endpoint = '/chat/completions'\n\n if (provider === 'azure') {\n endpoint = `/chat/completions?api-version=${azureApiVersion}`\n } else if (provider === 'minimax') {\n endpoint = '/text/chatcompletion_v2'\n }\n\n try {\n if (opts.stream) {\n const isOpenAICompatible = [\n 'minimax',\n 'kimi',\n 'deepseek',\n 'siliconflow',\n 'qwen',\n 'qwen-coding',\n 'glm',\n 'glm-coding',\n 'baidu-qianfan',\n 'openai',\n 'mistral',\n 'xai',\n 'groq',\n 'custom-openai',\n ].includes(provider)\n\n let response: Response\n let usedEndpoint: string\n\n if (isOpenAICompatible && provider !== 'azure') {\n const result = await tryWithEndpointFallback(\n baseURL,\n opts,\n headers,\n provider,\n proxy,\n signal,\n )\n response = result.response\n usedEndpoint = result.endpoint\n } else {\n response = await fetch(`${baseURL}${endpoint}`, {\n method: 'POST',\n headers,\n body: JSON.stringify({ ...opts, stream: true }),\n dispatcher: proxy,\n signal: signal,\n })\n usedEndpoint = endpoint\n }\n\n if (!response.ok) {\n if (signal?.aborted) {\n throw new Error('Request cancelled by user')\n }\n\n try {\n const errorData = await response.json()\n const hasError = (\n data: unknown,\n ): data is { error?: { message?: string }; message?: string } => {\n return typeof data === 'object' && data !== null\n }\n const errorMessage = hasError(errorData)\n ? errorData.error?.message ||\n errorData.message ||\n `HTTP ${response.status}`\n : `HTTP ${response.status}`\n\n const isGPT5 = opts.model.startsWith('gpt-5')\n const handlers = isGPT5\n ? [...GPT5_ERROR_HANDLERS, ...ERROR_HANDLERS]\n : ERROR_HANDLERS\n\n for (const handler of handlers) {\n if (handler.detect(errorMessage)) {\n debugLogger.api('OPENAI_MODEL_ERROR_DETECTED', {\n model: opts.model,\n type: handler.type,\n errorMessage,\n status: response.status,\n })\n\n setModelError(\n baseURL || '',\n opts.model,\n handler.type,\n errorMessage,\n )\n\n await handler.fix(opts)\n debugLogger.api('OPENAI_MODEL_ERROR_FIXED', {\n model: opts.model,\n type: handler.type,\n })\n\n return getCompletionWithProfile(\n modelProfile,\n opts,\n attempt + 1,\n maxAttempts,\n signal,\n )\n }\n }\n\n debugLogger.warn('OPENAI_API_ERROR_UNHANDLED', {\n model: opts.model,\n status: response.status,\n errorMessage,\n })\n\n logAPIError({\n model: opts.model,\n endpoint: `${baseURL}${endpoint}`,\n status: response.status,\n error: errorMessage,\n request: opts,\n response: errorData,\n provider: provider,\n })\n } catch (parseError) {\n debugLogger.warn('OPENAI_API_ERROR_PARSE_FAILED', {\n model: opts.model,\n status: response.status,\n error: parseError instanceof Error ? parseError.message : String(parseError),\n })\n\n logAPIError({\n model: opts.model,\n endpoint: `${baseURL}${endpoint}`,\n status: response.status,\n error: `Could not parse error response: ${parseError.message}`,\n request: opts,\n response: { parseError: parseError.message },\n provider: provider,\n })\n }\n\n const delayMs = getRetryDelay(attempt)\n debugLogger.warn('OPENAI_API_RETRY', {\n model: opts.model,\n status: response.status,\n attempt: attempt + 1,\n maxAttempts,\n delayMs,\n })\n try {\n await abortableDelay(delayMs, signal)\n } catch (error) {\n if (error.message === 'Request was aborted') {\n throw new Error('Request cancelled by user')\n }\n throw error\n }\n return getCompletionWithProfile(\n modelProfile,\n opts,\n attempt + 1,\n maxAttempts,\n signal,\n )\n }\n\n const stream = createStreamProcessor(response.body as any, signal)\n return stream\n }\n\n const isOpenAICompatible = [\n 'minimax',\n 'kimi',\n 'deepseek',\n 'siliconflow',\n 'qwen',\n 'glm',\n 'baidu-qianfan',\n 'openai',\n 'mistral',\n 'xai',\n 'groq',\n 'custom-openai',\n ].includes(provider)\n\n let response: Response\n let usedEndpoint: string\n\n if (isOpenAICompatible && provider !== 'azure') {\n const result = await tryWithEndpointFallback(\n baseURL,\n opts,\n headers,\n provider,\n proxy,\n signal,\n )\n response = result.response\n usedEndpoint = result.endpoint\n } else {\n response = await fetch(`${baseURL}${endpoint}`, {\n method: 'POST',\n headers,\n body: JSON.stringify(opts),\n dispatcher: proxy,\n signal: signal,\n })\n usedEndpoint = endpoint\n }\n\n if (!response.ok) {\n if (signal?.aborted) {\n throw new Error('Request cancelled by user')\n }\n\n try {\n const errorData = await response.json()\n const hasError = (\n data: unknown,\n ): data is { error?: { message?: string }; message?: string } => {\n return typeof data === 'object' && data !== null\n }\n const errorMessage = hasError(errorData)\n ? errorData.error?.message ||\n errorData.message ||\n `HTTP ${response.status}`\n : `HTTP ${response.status}`\n\n const isGPT5 = opts.model.startsWith('gpt-5')\n const handlers = isGPT5\n ? [...GPT5_ERROR_HANDLERS, ...ERROR_HANDLERS]\n : ERROR_HANDLERS\n\n for (const handler of handlers) {\n if (handler.detect(errorMessage)) {\n debugLogger.api('OPENAI_MODEL_ERROR_DETECTED', {\n model: opts.model,\n type: handler.type,\n errorMessage,\n status: response.status,\n })\n\n setModelError(baseURL || '', opts.model, handler.type, errorMessage)\n\n await handler.fix(opts)\n debugLogger.api('OPENAI_MODEL_ERROR_FIXED', {\n model: opts.model,\n type: handler.type,\n })\n\n return getCompletionWithProfile(\n modelProfile,\n opts,\n attempt + 1,\n maxAttempts,\n signal,\n )\n }\n }\n\n debugLogger.warn('OPENAI_API_ERROR_UNHANDLED', {\n model: opts.model,\n status: response.status,\n errorMessage,\n })\n } catch (parseError) {\n debugLogger.warn('OPENAI_API_ERROR_PARSE_FAILED', {\n model: opts.model,\n status: response.status,\n error: parseError instanceof Error ? parseError.message : String(parseError),\n })\n }\n\n const delayMs = getRetryDelay(attempt)\n debugLogger.warn('OPENAI_API_RETRY', {\n model: opts.model,\n status: response.status,\n attempt: attempt + 1,\n maxAttempts,\n delayMs,\n })\n try {\n await abortableDelay(delayMs, signal)\n } catch (error) {\n if (error.message === 'Request was aborted') {\n throw new Error('Request cancelled by user')\n }\n throw error\n }\n return getCompletionWithProfile(\n modelProfile,\n opts,\n attempt + 1,\n maxAttempts,\n signal,\n )\n }\n\n const responseData = (await response.json()) as OpenAI.ChatCompletion\n return responseData\n } catch (error) {\n if (signal?.aborted) {\n throw new Error('Request cancelled by user')\n }\n\n if (attempt < maxAttempts) {\n if (signal?.aborted) {\n throw new Error('Request cancelled by user')\n }\n\n const delayMs = getRetryDelay(attempt)\n debugLogger.warn('OPENAI_NETWORK_RETRY', {\n model: opts.model,\n attempt: attempt + 1,\n maxAttempts,\n delayMs,\n error: error instanceof Error ? error.message : String(error),\n })\n try {\n await abortableDelay(delayMs, signal)\n } catch (error) {\n if (error.message === 'Request was aborted') {\n throw new Error('Request cancelled by user')\n }\n throw error\n }\n return getCompletionWithProfile(\n modelProfile,\n opts,\n attempt + 1,\n maxAttempts,\n signal,\n )\n }\n throw error\n }\n}\n\nexport function createStreamProcessor(\n stream: any,\n signal?: AbortSignal,\n): AsyncGenerator<OpenAI.ChatCompletionChunk, void, unknown> {\n if (!stream) {\n throw new Error('Stream is null or undefined')\n }\n\n return (async function* () {\n const reader = stream.getReader()\n const decoder = new TextDecoder('utf-8')\n let buffer = ''\n\n try {\n while (true) {\n if (signal?.aborted) {\n break\n }\n\n let readResult\n try {\n readResult = await reader.read()\n } catch (e) {\n if (signal?.aborted) {\n break\n }\n debugLogger.warn('OPENAI_STREAM_READ_ERROR', {\n error: e instanceof Error ? e.message : String(e),\n })\n break\n }\n\n const { done, value } = readResult\n if (done) {\n break\n }\n\n const chunk = decoder.decode(value, { stream: true })\n buffer += chunk\n\n let lineEnd = buffer.indexOf('\\n')\n while (lineEnd !== -1) {\n const line = buffer.substring(0, lineEnd).trim()\n buffer = buffer.substring(lineEnd + 1)\n\n if (line === 'data: [DONE]') {\n continue\n }\n\n if (line.startsWith('data: ')) {\n const data = line.slice(6).trim()\n if (!data) continue\n\n try {\n const parsed = JSON.parse(data) as OpenAI.ChatCompletionChunk\n yield parsed\n } catch (e) {\n debugLogger.warn('OPENAI_STREAM_JSON_PARSE_ERROR', {\n data,\n error: e instanceof Error ? e.message : String(e),\n })\n }\n }\n\n lineEnd = buffer.indexOf('\\n')\n }\n }\n\n if (buffer.trim()) {\n const lines = buffer.trim().split('\\n')\n for (const line of lines) {\n if (line.startsWith('data: ') && line !== 'data: [DONE]') {\n const data = line.slice(6).trim()\n if (!data) continue\n\n try {\n const parsed = JSON.parse(data) as OpenAI.ChatCompletionChunk\n yield parsed\n } catch (e) {\n debugLogger.warn('OPENAI_STREAM_FINAL_JSON_PARSE_ERROR', {\n data,\n error: e instanceof Error ? e.message : String(e),\n })\n }\n }\n }\n }\n } catch (e) {\n debugLogger.warn('OPENAI_STREAM_UNEXPECTED_ERROR', {\n error: e instanceof Error ? e.message : String(e),\n })\n } finally {\n try {\n reader.releaseLock()\n } catch (e) {\n debugLogger.warn('OPENAI_STREAM_RELEASE_LOCK_ERROR', {\n error: e instanceof Error ? e.message : String(e),\n })\n }\n }\n })()\n}\n\nexport function streamCompletion(\n stream: any,\n signal?: AbortSignal,\n): AsyncGenerator<OpenAI.ChatCompletionChunk, void, unknown> {\n return createStreamProcessor(stream, signal)\n}\n\nexport async function callGPT5ResponsesAPI(\n modelProfile: any,\n request: any,\n signal?: AbortSignal,\n): Promise<any> {\n const baseURL = modelProfile?.baseURL || 'https://api.openai.com/v1'\n const apiKey = modelProfile?.apiKey\n const proxy = getGlobalConfig().proxy\n ? new ProxyAgent(getGlobalConfig().proxy)\n : undefined\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n }\n\n const responsesParams = request\n\n try {\n const response = await fetch(`${baseURL}/responses`, {\n method: 'POST',\n headers,\n body: JSON.stringify(responsesParams),\n dispatcher: proxy,\n signal: signal,\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n throw new Error(\n `GPT-5 Responses API error: ${response.status} ${response.statusText} - ${errorText}`,\n )\n }\n\n return response\n } catch (error) {\n if (signal?.aborted) {\n throw new Error('Request cancelled by user')\n }\n throw error\n }\n}\n\nfunction convertResponsesAPIToChatCompletion(responsesData: any): any {\n let outputText = responsesData.output_text || ''\n const usage = responsesData.usage || {}\n\n if (responsesData.output && Array.isArray(responsesData.output)) {\n const reasoningItems = responsesData.output.filter(\n item => item.type === 'reasoning' && item.summary,\n )\n const messageItems = responsesData.output.filter(\n item => item.type === 'message',\n )\n\n if (reasoningItems.length > 0 && messageItems.length > 0) {\n const reasoningSummary = reasoningItems\n .map(item => item.summary?.map(s => s.text).join('\\n'))\n .filter(Boolean)\n .join('\\n\\n')\n\n const mainContent = messageItems\n .map(item => item.content?.map(c => c.text).join('\\n'))\n .filter(Boolean)\n .join('\\n\\n')\n\n if (reasoningSummary) {\n outputText = `**\uD83E\uDDE0 Reasoning Process:**\\n${reasoningSummary}\\n\\n**\uD83D\uDCDD Response:**\\n${mainContent}`\n } else {\n outputText = mainContent\n }\n }\n }\n\n return {\n id: responsesData.id || `chatcmpl-${Date.now()}`,\n object: 'chat.completion',\n created: Math.floor(Date.now() / 1000),\n model: responsesData.model || '',\n choices: [\n {\n index: 0,\n message: {\n role: 'assistant',\n content: outputText,\n ...(responsesData.reasoning && {\n reasoning: {\n effort: responsesData.reasoning.effort,\n summary: responsesData.reasoning.summary,\n },\n }),\n },\n finish_reason: responsesData.status === 'completed' ? 'stop' : 'length',\n },\n ],\n usage: {\n prompt_tokens: usage.input_tokens || 0,\n completion_tokens: usage.output_tokens || 0,\n total_tokens: (usage.input_tokens || 0) + (usage.output_tokens || 0),\n prompt_tokens_details: {\n cached_tokens: usage.input_tokens_details?.cached_tokens || 0,\n },\n completion_tokens_details: {\n reasoning_tokens: usage.output_tokens_details?.reasoning_tokens || 0,\n },\n },\n }\n}\n\nasync function getGPT5CompletionWithProfile(\n modelProfile: any,\n opts: OpenAI.ChatCompletionCreateParams,\n attempt: number = 0,\n maxAttempts: number = 10,\n signal?: AbortSignal,\n): Promise<OpenAI.ChatCompletion | AsyncIterable<OpenAI.ChatCompletionChunk>> {\n const features = getModelFeatures(opts.model)\n const isOfficialOpenAI =\n !modelProfile.baseURL || modelProfile.baseURL.includes('api.openai.com')\n\n if (!isOfficialOpenAI) {\n debugLogger.api('GPT5_THIRD_PARTY_PROVIDER', {\n model: opts.model,\n baseURL: modelProfile.baseURL,\n provider: modelProfile.provider,\n supportsResponsesAPI: features.supportsResponsesAPI,\n requestId: getCurrentRequest()?.id,\n })\n\n debugLogger.api('GPT5_PROVIDER_THIRD_PARTY_NOTICE', {\n model: opts.model,\n provider: modelProfile.provider,\n baseURL: modelProfile.baseURL,\n })\n\n if (modelProfile.provider === 'azure') {\n delete opts.reasoning_effort\n } else if (modelProfile.provider === 'custom-openai') {\n debugLogger.api('GPT5_CUSTOM_PROVIDER_OPTIMIZATIONS', {\n model: opts.model,\n provider: modelProfile.provider,\n })\n }\n }\n\n else if (opts.stream) {\n debugLogger.api('GPT5_STREAMING_MODE', {\n model: opts.model,\n baseURL: modelProfile.baseURL || 'official',\n reason: 'responses_api_no_streaming',\n requestId: getCurrentRequest()?.id,\n })\n\n debugLogger.api('GPT5_STREAMING_FALLBACK_TO_CHAT_COMPLETIONS', {\n model: opts.model,\n reason: 'responses_api_no_streaming',\n })\n }\n\n debugLogger.api('USING_CHAT_COMPLETIONS_FOR_GPT5', {\n model: opts.model,\n baseURL: modelProfile.baseURL || 'official',\n provider: modelProfile.provider,\n reason: isOfficialOpenAI ? 'streaming_or_fallback' : 'third_party_provider',\n requestId: getCurrentRequest()?.id,\n })\n\n return await getCompletionWithProfile(\n modelProfile,\n opts,\n attempt,\n maxAttempts,\n signal,\n )\n}\n\nexport async function fetchCustomModels(\n baseURL: string,\n apiKey: string,\n): Promise<any[]> {\n try {\n const hasVersionNumber = /\\/v\\d+/.test(baseURL)\n const cleanBaseURL = baseURL.replace(/\\/+$/, '')\n const modelsURL = hasVersionNumber\n ? `${cleanBaseURL}/models`\n : `${cleanBaseURL}/v1/models`\n\n const response = await fetch(modelsURL, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n })\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\n 'Invalid API key. Please check your API key and try again.',\n )\n } else if (response.status === 403) {\n throw new Error(\n 'API key does not have permission to access models. Please check your API key permissions.',\n )\n } else if (response.status === 404) {\n throw new Error(\n 'API endpoint not found. Please check if the base URL is correct and supports the /models endpoint.',\n )\n } else if (response.status === 429) {\n throw new Error(\n 'Too many requests. Please wait a moment and try again.',\n )\n } else if (response.status >= 500) {\n throw new Error(\n 'API service is temporarily unavailable. Please try again later.',\n )\n } else {\n throw new Error(\n `Unable to connect to API (${response.status}). Please check your base URL, API key, and internet connection.`,\n )\n }\n }\n\n const data = await response.json()\n\n const hasDataArray = (obj: unknown): obj is { data: unknown[] } => {\n return (\n typeof obj === 'object' &&\n obj !== null &&\n 'data' in obj &&\n Array.isArray((obj as any).data)\n )\n }\n\n const hasModelsArray = (obj: unknown): obj is { models: unknown[] } => {\n return (\n typeof obj === 'object' &&\n obj !== null &&\n 'models' in obj &&\n Array.isArray((obj as any).models)\n )\n }\n\n let models = []\n\n if (hasDataArray(data)) {\n models = data.data\n } else if (Array.isArray(data)) {\n models = data\n } else if (hasModelsArray(data)) {\n models = data.models\n } else {\n throw new Error(\n 'API returned unexpected response format. Expected an array of models or an object with a \"data\" or \"models\" array.',\n )\n }\n\n if (!Array.isArray(models)) {\n throw new Error('API response format error: models data is not an array.')\n }\n\n return models\n } catch (error) {\n if (\n error instanceof Error &&\n (error.message.includes('API key') ||\n error.message.includes('API endpoint') ||\n error.message.includes('API service') ||\n error.message.includes('response format'))\n ) {\n throw error\n }\n\n debugLogger.warn('CUSTOM_API_MODELS_FETCH_FAILED', {\n baseURL,\n error: error instanceof Error ? error.message : String(error),\n })\n\n if (error instanceof Error && error.message.includes('fetch')) {\n throw new Error(\n 'Unable to connect to the API. Please check the base URL and your internet connection.',\n )\n }\n\n throw new Error(\n 'Failed to fetch models from custom API. Please check your configuration and try again.',\n )\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["isOpenAICompatible", "response", "usedEndpoint", "error"]
|
|
7
7
|
}
|
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
} from "./chunk-BJSWTHRM.js";
|
|
6
6
|
import {
|
|
7
7
|
debug
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-DYJD66YF.js";
|
|
9
9
|
import {
|
|
10
10
|
getCwd,
|
|
11
11
|
logError,
|
|
12
12
|
resolveXdgDataPath
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-U265OPSO.js";
|
|
14
14
|
|
|
15
15
|
// src/services/plugins/customCommands.ts
|
|
16
16
|
import { existsSync, readFileSync, readdirSync, statSync } from "fs";
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { createRequire as __pybCreateRequire } from "node:module";
|
|
2
|
+
const require = __pybCreateRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
logError
|
|
5
|
+
} from "./chunk-U265OPSO.js";
|
|
6
|
+
|
|
7
|
+
// src/utils/session/conversationMessageState.ts
|
|
8
|
+
function mapFinishReason(rawReason) {
|
|
9
|
+
const reason = String(rawReason ?? "").trim().toLowerCase();
|
|
10
|
+
if (!reason) return "end_turn";
|
|
11
|
+
if (reason === "tool_use" || reason === "tool_calls") return "tool_calls";
|
|
12
|
+
if (reason === "max_tokens" || reason === "length") return "max_tokens";
|
|
13
|
+
if (reason === "pause_turn") return "pause_turn";
|
|
14
|
+
if (reason === "end_turn" || reason === "stop" || reason === "stop_sequence") {
|
|
15
|
+
return "end_turn";
|
|
16
|
+
}
|
|
17
|
+
return "end_turn";
|
|
18
|
+
}
|
|
19
|
+
function isFinishComplete(finish) {
|
|
20
|
+
return finish === "end_turn";
|
|
21
|
+
}
|
|
22
|
+
function isToolResultUserMessage(message) {
|
|
23
|
+
if (!Array.isArray(message.message.content)) return false;
|
|
24
|
+
return message.message.content.some(
|
|
25
|
+
(block) => block && typeof block === "object" && block.type === "tool_result"
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
function findNaturalUserMessageForParent(messages) {
|
|
29
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
30
|
+
const msg = messages[i];
|
|
31
|
+
if (!msg || msg.type !== "user") continue;
|
|
32
|
+
if (isToolResultUserMessage(msg)) continue;
|
|
33
|
+
return msg;
|
|
34
|
+
}
|
|
35
|
+
return void 0;
|
|
36
|
+
}
|
|
37
|
+
function appendFinishState(assistantMessage, state) {
|
|
38
|
+
return {
|
|
39
|
+
...assistantMessage,
|
|
40
|
+
finish: state.finish,
|
|
41
|
+
parentID: state.parentID,
|
|
42
|
+
...typeof state.completedAt === "number" ? { completedAt: state.completedAt } : {}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// src/utils/session/conversationPersistence.ts
|
|
47
|
+
import {
|
|
48
|
+
existsSync,
|
|
49
|
+
mkdirSync,
|
|
50
|
+
readFileSync,
|
|
51
|
+
renameSync,
|
|
52
|
+
unlinkSync,
|
|
53
|
+
writeFileSync
|
|
54
|
+
} from "fs";
|
|
55
|
+
import { join } from "path";
|
|
56
|
+
var PERSISTENCE_VERSION = 1;
|
|
57
|
+
function sanitizeSessionId(sessionId) {
|
|
58
|
+
return sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
59
|
+
}
|
|
60
|
+
function isValidPersistedCompletedQuery(value) {
|
|
61
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
62
|
+
const item = value;
|
|
63
|
+
return typeof item.queryId === "string" && typeof item.userMessageUUID === "string" && typeof item.userQuery === "string" && typeof item.summary === "string" && typeof item.completedAt === "number" && (item.finish === "end_turn" || item.finish === "tool_calls" || item.finish === "max_tokens" || item.finish === "pause_turn");
|
|
64
|
+
}
|
|
65
|
+
function isValidPersistedConversationState(value) {
|
|
66
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
67
|
+
const state = value;
|
|
68
|
+
return typeof state.version === "number" && typeof state.sessionId === "string" && Array.isArray(state.completedQueries) && state.completedQueries.every(isValidPersistedCompletedQuery) && typeof state.lastUpdatedAt === "number";
|
|
69
|
+
}
|
|
70
|
+
var FileSystemConversationPersistence = class {
|
|
71
|
+
constructor(baseDir) {
|
|
72
|
+
this.baseDir = baseDir;
|
|
73
|
+
}
|
|
74
|
+
getFilePath(sessionId) {
|
|
75
|
+
return join(this.baseDir, `${sanitizeSessionId(sessionId)}.json`);
|
|
76
|
+
}
|
|
77
|
+
saveSync(sessionId, state) {
|
|
78
|
+
const filePath = this.getFilePath(sessionId);
|
|
79
|
+
const tempPath = `${filePath}.tmp`;
|
|
80
|
+
try {
|
|
81
|
+
mkdirSync(this.baseDir, { recursive: true });
|
|
82
|
+
writeFileSync(tempPath, JSON.stringify(state, null, 2), "utf8");
|
|
83
|
+
renameSync(tempPath, filePath);
|
|
84
|
+
} catch (error) {
|
|
85
|
+
logError(error);
|
|
86
|
+
try {
|
|
87
|
+
if (existsSync(tempPath)) unlinkSync(tempPath);
|
|
88
|
+
} catch {
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
loadSync(sessionId) {
|
|
93
|
+
const filePath = this.getFilePath(sessionId);
|
|
94
|
+
if (!existsSync(filePath)) return null;
|
|
95
|
+
try {
|
|
96
|
+
const raw = readFileSync(filePath, "utf8");
|
|
97
|
+
const parsed = JSON.parse(raw);
|
|
98
|
+
if (!isValidPersistedConversationState(parsed)) return null;
|
|
99
|
+
return parsed;
|
|
100
|
+
} catch {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
clearSync(sessionId) {
|
|
105
|
+
const filePath = this.getFilePath(sessionId);
|
|
106
|
+
try {
|
|
107
|
+
if (existsSync(filePath)) unlinkSync(filePath);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
logError(error);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
// src/utils/session/conversationTracker.ts
|
|
115
|
+
function extractText(content) {
|
|
116
|
+
if (typeof content === "string") return content.trim();
|
|
117
|
+
if (!Array.isArray(content)) return "";
|
|
118
|
+
return content.filter((block) => block && typeof block === "object" && block.type === "text").map((block) => String(block.text ?? "").trim()).filter(Boolean).join("\n").trim();
|
|
119
|
+
}
|
|
120
|
+
function truncate(text, maxChars) {
|
|
121
|
+
if (text.length <= maxChars) return text;
|
|
122
|
+
return `${text.slice(0, Math.max(0, maxChars - 3))}...`;
|
|
123
|
+
}
|
|
124
|
+
var ConversationTracker = class {
|
|
125
|
+
completedQueries = /* @__PURE__ */ new Map();
|
|
126
|
+
currentQueryId = null;
|
|
127
|
+
persistence;
|
|
128
|
+
sessionId;
|
|
129
|
+
constructor(options) {
|
|
130
|
+
this.persistence = options?.persistence;
|
|
131
|
+
this.sessionId = options?.sessionId;
|
|
132
|
+
}
|
|
133
|
+
startQuery(queryId, userMessage) {
|
|
134
|
+
if (!queryId) return false;
|
|
135
|
+
if (isToolResultUserMessage(userMessage)) return false;
|
|
136
|
+
if (this.completedQueries.has(queryId)) return false;
|
|
137
|
+
if (this.currentQueryId === queryId) return true;
|
|
138
|
+
this.currentQueryId = queryId;
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
completeQuery(queryId, assistantMessage, userMessage) {
|
|
142
|
+
if (!queryId) return false;
|
|
143
|
+
if (this.completedQueries.has(queryId)) return false;
|
|
144
|
+
if (assistantMessage.finish !== "end_turn") return false;
|
|
145
|
+
if (assistantMessage.parentID !== userMessage.uuid) return false;
|
|
146
|
+
const userQuery = extractText(userMessage.message.content);
|
|
147
|
+
const summaryRaw = extractText(assistantMessage.message.content);
|
|
148
|
+
const completedAt = typeof assistantMessage.completedAt === "number" ? assistantMessage.completedAt : Date.now();
|
|
149
|
+
this.completedQueries.set(queryId, {
|
|
150
|
+
queryId,
|
|
151
|
+
userMessageUUID: userMessage.uuid,
|
|
152
|
+
userQuery,
|
|
153
|
+
summary: summaryRaw,
|
|
154
|
+
completedAt,
|
|
155
|
+
finish: assistantMessage.finish
|
|
156
|
+
});
|
|
157
|
+
if (this.currentQueryId === queryId) {
|
|
158
|
+
this.currentQueryId = null;
|
|
159
|
+
}
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
isQueryCompleted(queryId) {
|
|
163
|
+
return this.completedQueries.has(queryId);
|
|
164
|
+
}
|
|
165
|
+
getCurrentQueryId() {
|
|
166
|
+
return this.currentQueryId;
|
|
167
|
+
}
|
|
168
|
+
getCompletedQueries() {
|
|
169
|
+
return Array.from(this.completedQueries.values()).sort(
|
|
170
|
+
(a, b) => a.completedAt - b.completedAt
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
generateConversationSummary(options) {
|
|
174
|
+
const maxEntries = options?.maxEntries ?? 10;
|
|
175
|
+
const maxEntryChars = options?.maxEntryChars ?? 80;
|
|
176
|
+
const maxTotalChars = options?.maxTotalChars ?? 2e3;
|
|
177
|
+
const completed = this.getCompletedQueries();
|
|
178
|
+
if (completed.length === 0) return "";
|
|
179
|
+
const recent = completed.slice(-maxEntries);
|
|
180
|
+
const lines = recent.map((item) => {
|
|
181
|
+
const q = truncate(item.userQuery || "(\u7A7A\u95EE\u9898)", maxEntryChars);
|
|
182
|
+
const a = truncate(item.summary || "(\u7A7A\u56DE\u7B54)", maxEntryChars);
|
|
183
|
+
return `- Q: ${q}
|
|
184
|
+
A: ${a}`;
|
|
185
|
+
});
|
|
186
|
+
const body = `## \u5DF2\u5B8C\u6210\u95EE\u9898\u6458\u8981
|
|
187
|
+
${lines.join("\n")}`;
|
|
188
|
+
if (body.length <= maxTotalChars) return body;
|
|
189
|
+
return truncate(body, maxTotalChars);
|
|
190
|
+
}
|
|
191
|
+
persist() {
|
|
192
|
+
if (!this.persistence || !this.sessionId) return false;
|
|
193
|
+
try {
|
|
194
|
+
const state = {
|
|
195
|
+
version: PERSISTENCE_VERSION,
|
|
196
|
+
sessionId: this.sessionId,
|
|
197
|
+
completedQueries: this.getCompletedQueries().map((item) => ({
|
|
198
|
+
queryId: item.queryId,
|
|
199
|
+
userMessageUUID: item.userMessageUUID,
|
|
200
|
+
userQuery: item.userQuery,
|
|
201
|
+
summary: item.summary,
|
|
202
|
+
completedAt: item.completedAt,
|
|
203
|
+
finish: item.finish
|
|
204
|
+
})),
|
|
205
|
+
lastUpdatedAt: Date.now()
|
|
206
|
+
};
|
|
207
|
+
this.persistence.saveSync(this.sessionId, state);
|
|
208
|
+
return true;
|
|
209
|
+
} catch {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
restore() {
|
|
214
|
+
if (!this.persistence || !this.sessionId) return false;
|
|
215
|
+
try {
|
|
216
|
+
const state = this.persistence.loadSync(this.sessionId);
|
|
217
|
+
if (!state || state.version !== PERSISTENCE_VERSION) {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
this.completedQueries.clear();
|
|
221
|
+
const list = Array.isArray(state.completedQueries) ? state.completedQueries : [];
|
|
222
|
+
for (const item of list) {
|
|
223
|
+
const normalized = {
|
|
224
|
+
queryId: String(item.queryId),
|
|
225
|
+
userMessageUUID: String(item.userMessageUUID),
|
|
226
|
+
userQuery: String(item.userQuery ?? ""),
|
|
227
|
+
summary: String(item.summary ?? ""),
|
|
228
|
+
completedAt: Number(item.completedAt ?? Date.now()),
|
|
229
|
+
finish: item.finish
|
|
230
|
+
};
|
|
231
|
+
this.completedQueries.set(normalized.queryId, normalized);
|
|
232
|
+
}
|
|
233
|
+
this.currentQueryId = null;
|
|
234
|
+
return true;
|
|
235
|
+
} catch {
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
reset() {
|
|
240
|
+
this.completedQueries.clear();
|
|
241
|
+
this.currentQueryId = null;
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
var conversationTracker = new ConversationTracker();
|
|
245
|
+
function getConversationTrackerForContext(context) {
|
|
246
|
+
return context?.conversationTracker ?? new ConversationTracker();
|
|
247
|
+
}
|
|
248
|
+
function resetConversationTrackerForTests() {
|
|
249
|
+
conversationTracker.reset();
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export {
|
|
253
|
+
mapFinishReason,
|
|
254
|
+
isFinishComplete,
|
|
255
|
+
findNaturalUserMessageForParent,
|
|
256
|
+
appendFinishState,
|
|
257
|
+
FileSystemConversationPersistence,
|
|
258
|
+
ConversationTracker,
|
|
259
|
+
conversationTracker,
|
|
260
|
+
getConversationTrackerForContext,
|
|
261
|
+
resetConversationTrackerForTests
|
|
262
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/utils/session/conversationMessageState.ts", "../src/utils/session/conversationPersistence.ts", "../src/utils/session/conversationTracker.ts"],
|
|
4
|
+
"sourcesContent": ["import type { AssistantMessage, Message, UserMessage } from '@query'\n\nexport type ConversationFinishReason =\n | 'end_turn'\n | 'tool_calls'\n | 'max_tokens'\n | 'pause_turn'\n\nexport function mapFinishReason(rawReason?: string | null): ConversationFinishReason {\n const reason = String(rawReason ?? '')\n .trim()\n .toLowerCase()\n if (!reason) return 'end_turn'\n if (reason === 'tool_use' || reason === 'tool_calls') return 'tool_calls'\n if (reason === 'max_tokens' || reason === 'length') return 'max_tokens'\n if (reason === 'pause_turn') return 'pause_turn'\n if (reason === 'end_turn' || reason === 'stop' || reason === 'stop_sequence') {\n return 'end_turn'\n }\n return 'end_turn'\n}\n\nexport function isFinishComplete(finish: ConversationFinishReason): boolean {\n return finish === 'end_turn'\n}\n\nexport function isToolResultUserMessage(message: UserMessage): boolean {\n if (!Array.isArray(message.message.content)) return false\n return message.message.content.some(\n block => block && typeof block === 'object' && (block as any).type === 'tool_result',\n )\n}\n\nexport function findNaturalUserMessageForParent(\n messages: Message[],\n): UserMessage | undefined {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (!msg || msg.type !== 'user') continue\n if (isToolResultUserMessage(msg)) continue\n return msg\n }\n return undefined\n}\n\nexport function appendFinishState(\n assistantMessage: AssistantMessage,\n state: {\n finish: ConversationFinishReason\n parentID: string\n completedAt?: number\n },\n): AssistantMessage {\n return {\n ...assistantMessage,\n finish: state.finish,\n parentID: state.parentID,\n ...(typeof state.completedAt === 'number'\n ? { completedAt: state.completedAt }\n : {}),\n }\n}\n\nexport function isCompactionMessage(message: Message): boolean {\n return (\n message.type === 'assistant' &&\n !!(message as AssistantMessage).compaction &&\n (message as AssistantMessage).compaction?.type === 'compaction'\n )\n}\n\nexport function getCompactedQueryIds(messages: Message[]): string[] {\n for (let i = messages.length - 1; i >= 0; i--) {\n const message = messages[i]\n if (!isCompactionMessage(message)) continue\n const ids = (message as AssistantMessage).compaction?.compactedQueryIds\n if (Array.isArray(ids)) return ids\n }\n return []\n}\n", "import {\n existsSync,\n mkdirSync,\n readFileSync,\n renameSync,\n unlinkSync,\n writeFileSync,\n} from 'fs'\nimport { join } from 'path'\nimport { logError } from '@utils/log'\n\nexport const PERSISTENCE_VERSION = 1\n\nexport type PersistedCompletedQuery = {\n queryId: string\n userMessageUUID: string\n userQuery: string\n summary: string\n completedAt: number\n finish: 'end_turn' | 'tool_calls' | 'max_tokens' | 'pause_turn'\n}\n\nexport type PersistedConversationState = {\n version: number\n sessionId: string\n completedQueries: PersistedCompletedQuery[]\n lastUpdatedAt: number\n}\n\nexport interface ConversationPersistence {\n saveSync(sessionId: string, state: PersistedConversationState): void\n loadSync(sessionId: string): PersistedConversationState | null\n clearSync(sessionId: string): void\n}\n\nfunction sanitizeSessionId(sessionId: string): string {\n return sessionId.replace(/[^a-zA-Z0-9_-]/g, '_')\n}\n\nfunction isValidPersistedCompletedQuery(value: unknown): value is PersistedCompletedQuery {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return false\n const item = value as PersistedCompletedQuery\n return (\n typeof item.queryId === 'string' &&\n typeof item.userMessageUUID === 'string' &&\n typeof item.userQuery === 'string' &&\n typeof item.summary === 'string' &&\n typeof item.completedAt === 'number' &&\n (item.finish === 'end_turn' ||\n item.finish === 'tool_calls' ||\n item.finish === 'max_tokens' ||\n item.finish === 'pause_turn')\n )\n}\n\nfunction isValidPersistedConversationState(\n value: unknown,\n): value is PersistedConversationState {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return false\n const state = value as PersistedConversationState\n return (\n typeof state.version === 'number' &&\n typeof state.sessionId === 'string' &&\n Array.isArray(state.completedQueries) &&\n state.completedQueries.every(isValidPersistedCompletedQuery) &&\n typeof state.lastUpdatedAt === 'number'\n )\n}\n\nexport class FileSystemConversationPersistence implements ConversationPersistence {\n constructor(private readonly baseDir: string) {}\n\n private getFilePath(sessionId: string): string {\n return join(this.baseDir, `${sanitizeSessionId(sessionId)}.json`)\n }\n\n saveSync(sessionId: string, state: PersistedConversationState): void {\n const filePath = this.getFilePath(sessionId)\n const tempPath = `${filePath}.tmp`\n try {\n mkdirSync(this.baseDir, { recursive: true })\n writeFileSync(tempPath, JSON.stringify(state, null, 2), 'utf8')\n renameSync(tempPath, filePath)\n } catch (error) {\n logError(error)\n try {\n if (existsSync(tempPath)) unlinkSync(tempPath)\n } catch {}\n }\n }\n\n loadSync(sessionId: string): PersistedConversationState | null {\n const filePath = this.getFilePath(sessionId)\n if (!existsSync(filePath)) return null\n try {\n const raw = readFileSync(filePath, 'utf8')\n const parsed = JSON.parse(raw) as unknown\n if (!isValidPersistedConversationState(parsed)) return null\n return parsed\n } catch {\n return null\n }\n }\n\n clearSync(sessionId: string): void {\n const filePath = this.getFilePath(sessionId)\n try {\n if (existsSync(filePath)) unlinkSync(filePath)\n } catch (error) {\n logError(error)\n }\n }\n}\n", "import type { AssistantMessage, UserMessage } from '@query'\nimport { isToolResultUserMessage } from './conversationMessageState'\nimport {\n type ConversationPersistence,\n type PersistedCompletedQuery,\n type PersistedConversationState,\n PERSISTENCE_VERSION,\n} from './conversationPersistence'\n\nexport type CompletedQuery = {\n queryId: string\n userMessageUUID: string\n userQuery: string\n summary: string\n completedAt: number\n finish: 'end_turn' | 'tool_calls' | 'max_tokens' | 'pause_turn'\n}\n\ntype SummaryOptions = {\n maxEntries?: number\n maxEntryChars?: number\n maxTotalChars?: number\n}\n\nfunction extractText(content: unknown): string {\n if (typeof content === 'string') return content.trim()\n if (!Array.isArray(content)) return ''\n return content\n .filter(block => block && typeof block === 'object' && (block as any).type === 'text')\n .map(block => String((block as any).text ?? '').trim())\n .filter(Boolean)\n .join('\\n')\n .trim()\n}\n\nfunction truncate(text: string, maxChars: number): string {\n if (text.length <= maxChars) return text\n return `${text.slice(0, Math.max(0, maxChars - 3))}...`\n}\n\nexport class ConversationTracker {\n private completedQueries = new Map<string, CompletedQuery>()\n private currentQueryId: string | null = null\n private readonly persistence?: ConversationPersistence\n private readonly sessionId?: string\n\n constructor(options?: {\n persistence?: ConversationPersistence\n sessionId?: string\n }) {\n this.persistence = options?.persistence\n this.sessionId = options?.sessionId\n }\n\n startQuery(queryId: string, userMessage: UserMessage): boolean {\n if (!queryId) return false\n if (isToolResultUserMessage(userMessage)) return false\n if (this.completedQueries.has(queryId)) return false\n if (this.currentQueryId === queryId) return true\n this.currentQueryId = queryId\n return true\n }\n\n completeQuery(\n queryId: string,\n assistantMessage: AssistantMessage,\n userMessage: UserMessage,\n ): boolean {\n if (!queryId) return false\n if (this.completedQueries.has(queryId)) return false\n if (assistantMessage.finish !== 'end_turn') return false\n if (assistantMessage.parentID !== userMessage.uuid) return false\n\n const userQuery = extractText(userMessage.message.content)\n const summaryRaw = extractText(assistantMessage.message.content)\n const completedAt =\n typeof assistantMessage.completedAt === 'number'\n ? assistantMessage.completedAt\n : Date.now()\n\n this.completedQueries.set(queryId, {\n queryId,\n userMessageUUID: userMessage.uuid,\n userQuery,\n summary: summaryRaw,\n completedAt,\n finish: assistantMessage.finish,\n })\n if (this.currentQueryId === queryId) {\n this.currentQueryId = null\n }\n return true\n }\n\n isQueryCompleted(queryId: string): boolean {\n return this.completedQueries.has(queryId)\n }\n\n getCurrentQueryId(): string | null {\n return this.currentQueryId\n }\n\n getCompletedQueries(): CompletedQuery[] {\n return Array.from(this.completedQueries.values()).sort(\n (a, b) => a.completedAt - b.completedAt,\n )\n }\n\n generateConversationSummary(options?: SummaryOptions): string {\n const maxEntries = options?.maxEntries ?? 10\n const maxEntryChars = options?.maxEntryChars ?? 80\n const maxTotalChars = options?.maxTotalChars ?? 2000\n const completed = this.getCompletedQueries()\n if (completed.length === 0) return ''\n\n const recent = completed.slice(-maxEntries)\n const lines = recent.map(item => {\n const q = truncate(item.userQuery || '(\u7A7A\u95EE\u9898)', maxEntryChars)\n const a = truncate(item.summary || '(\u7A7A\u56DE\u7B54)', maxEntryChars)\n return `- Q: ${q}\\n A: ${a}`\n })\n const body = `## \u5DF2\u5B8C\u6210\u95EE\u9898\u6458\u8981\\n${lines.join('\\n')}`\n if (body.length <= maxTotalChars) return body\n return truncate(body, maxTotalChars)\n }\n\n persist(): boolean {\n if (!this.persistence || !this.sessionId) return false\n try {\n const state: PersistedConversationState = {\n version: PERSISTENCE_VERSION,\n sessionId: this.sessionId,\n completedQueries: this.getCompletedQueries().map(item => ({\n queryId: item.queryId,\n userMessageUUID: item.userMessageUUID,\n userQuery: item.userQuery,\n summary: item.summary,\n completedAt: item.completedAt,\n finish: item.finish,\n })),\n lastUpdatedAt: Date.now(),\n }\n this.persistence.saveSync(this.sessionId, state)\n return true\n } catch {\n return false\n }\n }\n\n restore(): boolean {\n if (!this.persistence || !this.sessionId) return false\n try {\n const state = this.persistence.loadSync(this.sessionId)\n if (!state || state.version !== PERSISTENCE_VERSION) {\n return false\n }\n this.completedQueries.clear()\n const list = Array.isArray(state.completedQueries)\n ? state.completedQueries\n : []\n for (const item of list) {\n const normalized: CompletedQuery = {\n queryId: String(item.queryId),\n userMessageUUID: String(item.userMessageUUID),\n userQuery: String(item.userQuery ?? ''),\n summary: String(item.summary ?? ''),\n completedAt: Number(item.completedAt ?? Date.now()),\n finish: item.finish as PersistedCompletedQuery['finish'],\n }\n this.completedQueries.set(normalized.queryId, normalized)\n }\n this.currentQueryId = null\n return true\n } catch {\n return false\n }\n }\n\n reset(): void {\n this.completedQueries.clear()\n this.currentQueryId = null\n }\n}\n\nexport const conversationTracker = new ConversationTracker()\n\nexport function getConversationTrackerForContext(context?: {\n conversationTracker?: ConversationTracker\n}): ConversationTracker {\n return context?.conversationTracker ?? new ConversationTracker()\n}\n\nexport function resetConversationTrackerForTests(): void {\n conversationTracker.reset()\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -3,13 +3,13 @@ const require = __pybCreateRequire(import.meta.url);
|
|
|
3
3
|
import {
|
|
4
4
|
getGlobalConfig,
|
|
5
5
|
saveGlobalConfig
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-2WIUQUTU.js";
|
|
7
7
|
import {
|
|
8
8
|
debug
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-DYJD66YF.js";
|
|
10
10
|
import {
|
|
11
11
|
logError
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-U265OPSO.js";
|
|
13
13
|
|
|
14
14
|
// src/utils/model/index.ts
|
|
15
15
|
import { memoize } from "lodash-es";
|
|
@@ -2,10 +2,10 @@ import { createRequire as __pybCreateRequire } from "node:module";
|
|
|
2
2
|
const require = __pybCreateRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
debug
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-DYJD66YF.js";
|
|
6
6
|
import {
|
|
7
7
|
logError
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-U265OPSO.js";
|
|
9
9
|
|
|
10
10
|
// src/services/system/systemReminder.ts
|
|
11
11
|
var SystemReminderService = class {
|