@within-7/minto 0.4.0 → 0.4.2
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/Tool.js +7 -0
- package/dist/Tool.js.map +2 -2
- package/dist/commands/agents/AgentsCommand.js +1 -1
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/agents/constants.js +2 -2
- package/dist/commands/agents/constants.js.map +2 -2
- package/dist/commands/clear.js +4 -3
- package/dist/commands/clear.js.map +2 -2
- package/dist/commands/compact.js +2 -2
- package/dist/commands/compact.js.map +1 -1
- package/dist/commands/context.js +3 -1
- package/dist/commands/context.js.map +2 -2
- package/dist/commands/login.js +128 -0
- package/dist/commands/login.js.map +7 -0
- package/dist/commands/memory.js +33 -82
- package/dist/commands/memory.js.map +2 -2
- package/dist/commands/quit.js +3 -1
- package/dist/commands/quit.js.map +2 -2
- package/dist/commands/resume.js +39 -239
- package/dist/commands/resume.js.map +2 -2
- package/dist/commands/tasks.js +1 -1
- package/dist/commands/tasks.js.map +2 -2
- package/dist/commands/terminalSetup.js +6 -2
- package/dist/commands/terminalSetup.js.map +2 -2
- package/dist/commands.js +2 -0
- package/dist/commands.js.map +2 -2
- package/dist/components/AgentDetailView.js +126 -0
- package/dist/components/AgentDetailView.js.map +7 -0
- package/dist/components/AgentThinkingBlock.js +1 -1
- package/dist/components/AgentThinkingBlock.js.map +2 -2
- package/dist/components/AgentViewBanner.js +22 -0
- package/dist/components/AgentViewBanner.js.map +7 -0
- package/dist/components/HeaderBar.js +1 -1
- package/dist/components/HeaderBar.js.map +2 -2
- package/dist/components/Help.js +8 -1
- package/dist/components/Help.js.map +2 -2
- package/dist/components/HotkeyHelpPanel.js +26 -8
- package/dist/components/HotkeyHelpPanel.js.map +2 -2
- package/dist/components/IdleNotificationBar.js +10 -0
- package/dist/components/IdleNotificationBar.js.map +7 -0
- package/dist/components/ModelSelector/ModelSelector.js +55 -20
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/PromptInput.js +186 -115
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/RewindPanel.js +272 -0
- package/dist/components/RewindPanel.js.map +7 -0
- package/dist/components/Spinner.js +10 -21
- package/dist/components/Spinner.js.map +2 -2
- package/dist/components/StreamingTextPreview.js +29 -0
- package/dist/components/StreamingTextPreview.js.map +7 -0
- package/dist/components/SubagentBlock.js +3 -2
- package/dist/components/SubagentBlock.js.map +2 -2
- package/dist/components/SubagentProgress.js +4 -4
- package/dist/components/SubagentProgress.js.map +2 -2
- package/dist/components/TabbedListView/SearchInput.js +1 -1
- package/dist/components/TabbedListView/SearchInput.js.map +2 -2
- package/dist/components/TabbedListView/TabbedListView.js +87 -41
- package/dist/components/TabbedListView/TabbedListView.js.map +2 -2
- package/dist/components/TaskCard.js +4 -4
- package/dist/components/TaskCard.js.map +2 -2
- package/dist/components/TeamMemberPanel.js +107 -0
- package/dist/components/TeamMemberPanel.js.map +7 -0
- package/dist/components/ThinkingSelector.js +84 -0
- package/dist/components/ThinkingSelector.js.map +7 -0
- package/dist/components/TitledDivider.js +26 -0
- package/dist/components/TitledDivider.js.map +7 -0
- package/dist/components/TodoPanel.js +31 -30
- package/dist/components/TodoPanel.js.map +2 -2
- package/dist/components/TokenWarning.js +28 -7
- package/dist/components/TokenWarning.js.map +2 -2
- package/dist/components/messages/AssistantTextMessage.js +5 -2
- package/dist/components/messages/AssistantTextMessage.js.map +2 -2
- package/dist/components/messages/AssistantToolUseMessage.js +9 -1
- package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
- package/dist/components/messages/DefaultToolResultFallback.js +11 -0
- package/dist/components/messages/DefaultToolResultFallback.js.map +7 -0
- package/dist/components/messages/ParallelTasksGroupView.js +14 -6
- package/dist/components/messages/ParallelTasksGroupView.js.map +2 -2
- package/dist/components/messages/TaskInModuleView.js +27 -27
- package/dist/components/messages/TaskInModuleView.js.map +2 -2
- package/dist/components/messages/UserGuidanceMessage.js +26 -0
- package/dist/components/messages/UserGuidanceMessage.js.map +7 -0
- package/dist/components/messages/UserPromptMessage.js +2 -1
- package/dist/components/messages/UserPromptMessage.js.map +2 -2
- package/dist/components/messages/UserTeamNotificationMessage.js +91 -0
- package/dist/components/messages/UserTeamNotificationMessage.js.map +7 -0
- package/dist/components/messages/UserTextMessage.js +8 -0
- package/dist/components/messages/UserTextMessage.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/UserToolRejectMessage.js +4 -2
- package/dist/components/messages/UserToolResultMessage/UserToolRejectMessage.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/UserToolResultMessage.js +18 -1
- package/dist/components/messages/UserToolResultMessage/UserToolResultMessage.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js +12 -1
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js.map +2 -2
- package/dist/components/permissions/PermissionRequest.js +4 -0
- package/dist/components/permissions/PermissionRequest.js.map +2 -2
- package/dist/components/permissions/PlanApprovalRequest.js +164 -0
- package/dist/components/permissions/PlanApprovalRequest.js.map +7 -0
- package/dist/constants/agentTeams.js +17 -0
- package/dist/constants/agentTeams.js.map +7 -0
- package/dist/constants/macros.js +2 -1
- package/dist/constants/macros.js.map +2 -2
- package/dist/constants/prompts/agentPrompt.js +1 -0
- package/dist/constants/prompts/agentPrompt.js.map +2 -2
- package/dist/constants/prompts/autoMemory.js +39 -0
- package/dist/constants/prompts/autoMemory.js.map +7 -0
- package/dist/constants/prompts/codeConventions.js +1 -13
- package/dist/constants/prompts/codeConventions.js.map +2 -2
- package/dist/constants/prompts/doingTasks.js +21 -2
- package/dist/constants/prompts/doingTasks.js.map +2 -2
- package/dist/constants/prompts/envInfo.js +6 -7
- package/dist/constants/prompts/envInfo.js.map +2 -2
- package/dist/constants/prompts/index.js +27 -5
- package/dist/constants/prompts/index.js.map +2 -2
- package/dist/constants/prompts/taskManagement.js +2 -43
- package/dist/constants/prompts/taskManagement.js.map +2 -2
- package/dist/constants/prompts/teamOverlays.js +50 -0
- package/dist/constants/prompts/teamOverlays.js.map +7 -0
- package/dist/constants/prompts/toneAndStyle.js +4 -29
- package/dist/constants/prompts/toneAndStyle.js.map +2 -2
- package/dist/constants/prompts/toolUsagePolicy.js +7 -22
- package/dist/constants/prompts/toolUsagePolicy.js.map +2 -2
- package/dist/constants/toolInputExamples.js +2 -2
- package/dist/constants/toolInputExamples.js.map +2 -2
- package/dist/context.js +39 -6
- package/dist/context.js.map +2 -2
- package/dist/core/backupManager.js +1 -1
- package/dist/core/backupManager.js.map +2 -2
- package/dist/core/permissions/rules/planModeRule.js +1 -1
- package/dist/core/permissions/rules/planModeRule.js.map +1 -1
- package/dist/core/permissions/rules/safeModeRule.js +1 -1
- package/dist/core/permissions/rules/safeModeRule.js.map +1 -1
- package/dist/engine/AgentEngine.js +902 -0
- package/dist/engine/AgentEngine.js.map +7 -0
- package/dist/engine/EngineRegistry.js +89 -0
- package/dist/engine/EngineRegistry.js.map +7 -0
- package/dist/engine/foregroundAdapter.js +191 -0
- package/dist/engine/foregroundAdapter.js.map +7 -0
- package/dist/engine/index.js +15 -0
- package/dist/engine/index.js.map +7 -0
- package/dist/engine/types.js +1 -0
- package/dist/engine/types.js.map +7 -0
- package/dist/entrypoints/cli.js +410 -79
- package/dist/entrypoints/cli.js.map +3 -3
- package/dist/hooks/useAgentEngine.js +129 -0
- package/dist/hooks/useAgentEngine.js.map +7 -0
- package/dist/hooks/useAgentTokenStats.js +0 -16
- package/dist/hooks/useAgentTokenStats.js.map +2 -2
- package/dist/hooks/useCanUseTool.js +47 -2
- package/dist/hooks/useCanUseTool.js.map +2 -2
- package/dist/hooks/useDeferredLoading.js +4 -1
- package/dist/hooks/useDeferredLoading.js.map +2 -2
- package/dist/hooks/useIdleNotifications.js +66 -0
- package/dist/hooks/useIdleNotifications.js.map +7 -0
- package/dist/hooks/useSessionTracking.js +9 -7
- package/dist/hooks/useSessionTracking.js.map +2 -2
- package/dist/hooks/useTeamMembers.js +51 -0
- package/dist/hooks/useTeamMembers.js.map +7 -0
- package/dist/i18n/locales/en.js +77 -12
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +77 -12
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/i18n/types.js.map +1 -1
- package/dist/messages.js.map +2 -2
- package/dist/permissions.js +113 -7
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +135 -37
- package/dist/query.js.map +2 -2
- package/dist/screens/REPL.js +504 -361
- package/dist/screens/REPL.js.map +3 -3
- package/dist/screens/ResumeConversation.js +199 -14
- package/dist/screens/ResumeConversation.js.map +2 -2
- package/dist/services/adapters/base.js.map +1 -1
- package/dist/services/agentTeams/backends/headless.js +108 -0
- package/dist/services/agentTeams/backends/headless.js.map +7 -0
- package/dist/services/agentTeams/backends/inProcess.js +102 -0
- package/dist/services/agentTeams/backends/inProcess.js.map +7 -0
- package/dist/services/agentTeams/backends/resolver.js +18 -0
- package/dist/services/agentTeams/backends/resolver.js.map +7 -0
- package/dist/services/agentTeams/backends/tmux.js +168 -0
- package/dist/services/agentTeams/backends/tmux.js.map +7 -0
- package/dist/services/agentTeams/backends/types.js +1 -0
- package/dist/services/agentTeams/backends/types.js.map +7 -0
- package/dist/services/agentTeams/heartbeat.js +88 -0
- package/dist/services/agentTeams/heartbeat.js.map +7 -0
- package/dist/services/agentTeams/index.js +42 -2
- package/dist/services/agentTeams/index.js.map +2 -2
- package/dist/services/agentTeams/injectionChannel.js +105 -0
- package/dist/services/agentTeams/injectionChannel.js.map +7 -0
- package/dist/services/agentTeams/mailbox.js +410 -30
- package/dist/services/agentTeams/mailbox.js.map +2 -2
- package/dist/services/agentTeams/messageFormatter.js +80 -0
- package/dist/services/agentTeams/messageFormatter.js.map +7 -0
- package/dist/services/agentTeams/permissionDelegation.js +71 -0
- package/dist/services/agentTeams/permissionDelegation.js.map +7 -0
- package/dist/services/agentTeams/teamEvents.js +45 -0
- package/dist/services/agentTeams/teamEvents.js.map +7 -0
- package/dist/services/agentTeams/teamManager.js +251 -34
- package/dist/services/agentTeams/teamManager.js.map +2 -2
- package/dist/services/agentTeams/teamTaskStore.js +290 -61
- package/dist/services/agentTeams/teamTaskStore.js.map +2 -2
- package/dist/services/agentTeams/teammateSpawner.js +99 -18
- package/dist/services/agentTeams/teammateSpawner.js.map +2 -2
- package/dist/services/hookExecutor.js +51 -8
- package/dist/services/hookExecutor.js.map +2 -2
- package/dist/services/llm/anthropicProvider.js +56 -59
- package/dist/services/llm/anthropicProvider.js.map +2 -2
- package/dist/services/llm/dispatch.js +24 -5
- package/dist/services/llm/dispatch.js.map +2 -2
- package/dist/services/llm/openaiProvider.js +115 -136
- package/dist/services/llm/openaiProvider.js.map +3 -3
- package/dist/services/llm/types.js +89 -15
- package/dist/services/llm/types.js.map +2 -2
- package/dist/services/mcpClient.js +80 -4
- package/dist/services/mcpClient.js.map +2 -2
- package/dist/services/mintoAuth.js +299 -0
- package/dist/services/mintoAuth.js.map +7 -0
- package/dist/services/oauth.js +3 -3
- package/dist/services/oauth.js.map +2 -2
- package/dist/services/openai.js +91 -20
- package/dist/services/openai.js.map +2 -2
- package/dist/services/plugins/pluginRuntime.js +11 -5
- package/dist/services/plugins/pluginRuntime.js.map +2 -2
- package/dist/services/plugins/pluginValidation.js +4 -2
- package/dist/services/plugins/pluginValidation.js.map +2 -2
- package/dist/services/sandbox/sandboxController.js +11 -3
- package/dist/services/sandbox/sandboxController.js.map +2 -2
- package/dist/services/sessionMemoryInjector.js +77 -0
- package/dist/services/sessionMemoryInjector.js.map +7 -0
- package/dist/services/systemReminder.js +130 -8
- package/dist/services/systemReminder.js.map +2 -2
- package/dist/services/taskStore.js +199 -8
- package/dist/services/taskStore.js.map +3 -3
- package/dist/services/topicDetector.js +169 -0
- package/dist/services/topicDetector.js.map +7 -0
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +0 -13
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
- package/dist/tools/BashTool/BashTool.js +51 -28
- package/dist/tools/BashTool/BashTool.js.map +2 -2
- package/dist/tools/BashTool/prompt.js +95 -118
- package/dist/tools/BashTool/prompt.js.map +2 -2
- package/dist/tools/BashTool/utils.js +39 -1
- package/dist/tools/BashTool/utils.js.map +2 -2
- package/dist/tools/EnterWorktreeTool/EnterWorktreeTool.js +121 -0
- package/dist/tools/EnterWorktreeTool/EnterWorktreeTool.js.map +7 -0
- package/dist/tools/EnterWorktreeTool/prompt.js +22 -0
- package/dist/tools/EnterWorktreeTool/prompt.js.map +7 -0
- package/dist/tools/FileEditTool/FileEditTool.js +9 -4
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileEditTool/prompt.js +3 -7
- package/dist/tools/FileEditTool/prompt.js.map +2 -2
- package/dist/tools/FileReadTool/FileReadTool.js +125 -3
- package/dist/tools/FileReadTool/FileReadTool.js.map +2 -2
- package/dist/tools/FileReadTool/prompt.js +1 -2
- package/dist/tools/FileReadTool/prompt.js.map +2 -2
- package/dist/tools/FileWriteTool/prompt.js +3 -5
- package/dist/tools/FileWriteTool/prompt.js.map +2 -2
- package/dist/tools/GlobTool/GlobTool.js +3 -2
- package/dist/tools/GlobTool/GlobTool.js.map +2 -2
- package/dist/tools/GrepTool/GrepTool.js +16 -5
- package/dist/tools/GrepTool/GrepTool.js.map +2 -2
- package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +2 -2
- package/dist/tools/MCPSearchTool/MCPSearchTool.js +172 -0
- package/dist/tools/MCPSearchTool/MCPSearchTool.js.map +7 -0
- package/dist/tools/MCPSearchTool/prompt.js +77 -0
- package/dist/tools/MCPSearchTool/prompt.js.map +7 -0
- package/dist/tools/MultiEditTool/prompt.js +4 -7
- package/dist/tools/MultiEditTool/prompt.js.map +2 -2
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js +12 -8
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js +54 -1
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
- package/dist/tools/PlanModeTool/prompt.js +23 -74
- package/dist/tools/PlanModeTool/prompt.js.map +2 -2
- package/dist/tools/SendMessageTool/SendMessageTool.js +341 -0
- package/dist/tools/SendMessageTool/SendMessageTool.js.map +7 -0
- package/dist/tools/SendMessageTool/prompt.js +44 -0
- package/dist/tools/SendMessageTool/prompt.js.map +7 -0
- package/dist/tools/TaskCreateTool/prompt.js +15 -4
- package/dist/tools/TaskCreateTool/prompt.js.map +2 -2
- package/dist/tools/TaskListTool/prompt.js +18 -3
- package/dist/tools/TaskListTool/prompt.js.map +2 -2
- package/dist/tools/TaskOutputTool/prompt.js +4 -3
- package/dist/tools/TaskOutputTool/prompt.js.map +2 -2
- package/dist/tools/TaskTool/TaskTool.js +762 -98
- package/dist/tools/TaskTool/TaskTool.js.map +3 -3
- package/dist/tools/TaskTool/constants.js +8 -2
- package/dist/tools/TaskTool/constants.js.map +2 -2
- package/dist/tools/TaskTool/prompt.js +74 -70
- package/dist/tools/TaskTool/prompt.js.map +2 -2
- package/dist/tools/TaskUpdateTool/TaskUpdateTool.js +15 -1
- package/dist/tools/TaskUpdateTool/TaskUpdateTool.js.map +2 -2
- package/dist/tools/TeamCreateTool/TeamCreateTool.js +129 -0
- package/dist/tools/TeamCreateTool/TeamCreateTool.js.map +7 -0
- package/dist/tools/TeamCreateTool/prompt.js +58 -0
- package/dist/tools/TeamCreateTool/prompt.js.map +7 -0
- package/dist/tools/TeamDeleteTool/TeamDeleteTool.js +151 -0
- package/dist/tools/TeamDeleteTool/TeamDeleteTool.js.map +7 -0
- package/dist/tools/TeamDeleteTool/prompt.js +16 -0
- package/dist/tools/TeamDeleteTool/prompt.js.map +7 -0
- package/dist/tools/URLFetcherTool/URLFetcherTool.js +106 -15
- package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
- package/dist/tools/URLFetcherTool/prompt.js +3 -2
- package/dist/tools/URLFetcherTool/prompt.js.map +2 -2
- package/dist/tools/WebSearchTool/WebSearchTool.js +2 -1
- package/dist/tools/WebSearchTool/WebSearchTool.js.map +2 -2
- package/dist/tools/WebSearchTool/prompt.js +5 -4
- package/dist/tools/WebSearchTool/prompt.js.map +2 -2
- package/dist/tools.js +100 -20
- package/dist/tools.js.map +2 -2
- package/dist/types/PermissionMode.js +35 -6
- package/dist/types/PermissionMode.js.map +2 -2
- package/dist/types/hooks.js +2 -0
- package/dist/types/hooks.js.map +2 -2
- package/dist/types/plugin.js +2 -0
- package/dist/types/plugin.js.map +3 -3
- package/dist/utils/CircuitBreaker.js +15 -9
- package/dist/utils/CircuitBreaker.js.map +2 -2
- package/dist/utils/agentLoader.js +249 -112
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/animationManager.js +40 -3
- package/dist/utils/animationManager.js.map +2 -2
- package/dist/utils/ask.js +7 -6
- package/dist/utils/ask.js.map +2 -2
- package/dist/utils/atomicWrite.js +23 -0
- package/dist/utils/atomicWrite.js.map +7 -0
- package/dist/utils/autoCompactCore.js +73 -56
- package/dist/utils/autoCompactCore.js.map +2 -2
- package/dist/utils/autoMemoryPaths.js +89 -0
- package/dist/utils/autoMemoryPaths.js.map +7 -0
- package/dist/utils/config.js +63 -38
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/configSchema.js +13 -8
- package/dist/utils/configSchema.js.map +2 -2
- package/dist/utils/credentials/index.js +14 -0
- package/dist/utils/credentials/index.js.map +2 -2
- package/dist/utils/dualPath.js +24 -0
- package/dist/utils/dualPath.js.map +7 -0
- package/dist/utils/exit.js +66 -7
- package/dist/utils/exit.js.map +2 -2
- package/dist/utils/externalEditor.js +155 -0
- package/dist/utils/externalEditor.js.map +7 -0
- package/dist/utils/fileLock.js +67 -0
- package/dist/utils/fileLock.js.map +7 -0
- package/dist/utils/format.js +24 -14
- package/dist/utils/format.js.map +2 -2
- package/dist/utils/globalErrorHandler.js +5 -96
- package/dist/utils/globalErrorHandler.js.map +3 -3
- package/dist/utils/groupHandlers/parallelTasksHandler.js +5 -3
- package/dist/utils/groupHandlers/parallelTasksHandler.js.map +2 -2
- package/dist/utils/groupHandlers/taskHandler.js +2 -2
- package/dist/utils/groupHandlers/taskHandler.js.map +2 -2
- package/dist/utils/hookManager.js +64 -6
- package/dist/utils/hookManager.js.map +2 -2
- package/dist/utils/log.js +6 -2
- package/dist/utils/log.js.map +2 -2
- package/dist/utils/markdown.js +237 -19
- package/dist/utils/markdown.js.map +2 -2
- package/dist/utils/messageContextManager.js +18 -5
- package/dist/utils/messageContextManager.js.map +2 -2
- package/dist/utils/messageGroupManager.js +1 -1
- package/dist/utils/messageGroupManager.js.map +2 -2
- package/dist/utils/messages.js +104 -46
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/model.js +2 -2
- package/dist/utils/model.js.map +2 -2
- package/dist/utils/pasteCache.js +8 -4
- package/dist/utils/pasteCache.js.map +2 -2
- package/dist/utils/pluginLoader.js +18 -0
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/secureKeyStorage.js +36 -7
- package/dist/utils/secureKeyStorage.js.map +2 -2
- package/dist/utils/simpleMode.js +7 -0
- package/dist/utils/simpleMode.js.map +7 -0
- package/dist/utils/streamingState.js +11 -1
- package/dist/utils/streamingState.js.map +2 -2
- package/dist/utils/taskDisplayUtils.js +2 -1
- package/dist/utils/taskDisplayUtils.js.map +2 -2
- package/dist/utils/teamConfig.js +2 -2
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/thinking.js +6 -2
- package/dist/utils/thinking.js.map +3 -3
- package/dist/utils/tokenProgress.js +55 -0
- package/dist/utils/tokenProgress.js.map +7 -0
- package/dist/utils/toolRiskClassification.js +26 -17
- package/dist/utils/toolRiskClassification.js.map +2 -2
- package/dist/utils/tooling/toolError.js +12 -0
- package/dist/utils/tooling/toolError.js.map +7 -0
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +10 -8
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/services/llm/openaiProvider.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * OpenAI-compatible provider \u2014 message conversion, streaming, and query path.\n */\nimport { randomUUID } from 'crypto'\nimport { nanoid } from 'nanoid'\n\nimport type { AssistantMessage, UserMessage } from '@query'\nimport { Tool, getToolDescriptionAsync } from '@tool'\nimport type { ToolUseContext } from '@tool'\nimport {\n getGlobalConfig,\n ModelProfile,\n} from '@utils/config'\nimport { isGPT5ModelName as isGPT5Model } from '@utils/config'\nimport {\n createAssistantAPIErrorMessage,\n normalizeContentFromAPI,\n} from '@utils/messages'\nimport {\n debug as debugLogger,\n getCurrentRequest,\n logLLMInteraction,\n logSystemPromptConstruction,\n} from '@utils/debugLogger'\nimport { getModelManager } from '@utils/model'\nimport { zodToJsonSchema } from 'zod-to-json-schema'\nimport { ModelAdapterFactory } from '../modelAdapterFactory'\nimport { UnifiedRequestParams } from '@minto-types/modelCapabilities'\nimport { getCLISyspromptPrefix } from '@constants/prompts'\nimport OpenAI from 'openai'\nimport type { ChatCompletionStream } from 'openai/lib/ChatCompletionStream'\nimport { ContentBlock } from '@anthropic-ai/sdk/resources/messages/messages'\nimport type { TextBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport { setStreamingState } from '@utils/streamingState'\nimport {\n getCompletionWithProfile,\n getGPT5CompletionWithProfile,\n} from '../openai'\nimport { getReasoningEffort } from '@utils/thinking'\nimport { addRetryEventToTranscript } from '@utils/agentTranscripts'\nimport type { TokenTrackingContext } from '@core/tokenStats'\n\nimport { generateMintoContext } from './mintoContext'\nimport { splitSysPromptPrefix } from './anthropicProvider'\nimport {\n API_ERROR_MESSAGE_PREFIX,\n PROMPT_TOO_LONG_ERROR_MESSAGE,\n CREDIT_BALANCE_TOO_LOW_ERROR_MESSAGE,\n INVALID_API_KEY_ERROR_MESSAGE,\n PROMPT_CACHING_ENABLED,\n MAIN_QUERY_TEMPERATURE,\n SONNET_COST_PER_MILLION_INPUT_TOKENS,\n SONNET_COST_PER_MILLION_OUTPUT_TOKENS,\n withRetry,\n getMaxTokensFromProfile,\n getModelInputTokenCostUSD,\n getModelOutputTokenCostUSD,\n addToTotalCost,\n recordTokenUsage,\n logError,\n} from './types'\n\n// \u2500\u2500 OpenAI message conversion \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction convertAnthropicMessagesToOpenAIMessages(\n messages: (UserMessage | AssistantMessage)[],\n): (\n | OpenAI.ChatCompletionMessageParam\n | OpenAI.ChatCompletionToolMessageParam\n)[] {\n const openaiMessages: (\n | OpenAI.ChatCompletionMessageParam\n | OpenAI.ChatCompletionToolMessageParam\n )[] = []\n\n const toolResults: Record<string, OpenAI.ChatCompletionToolMessageParam> = {}\n\n for (const message of messages) {\n let contentBlocks = []\n if (typeof message.message.content === 'string') {\n contentBlocks = [\n {\n type: 'text',\n text: message.message.content,\n },\n ]\n } else if (!Array.isArray(message.message.content)) {\n contentBlocks = [message.message.content]\n } else {\n contentBlocks = message.message.content\n }\n\n for (const block of contentBlocks) {\n if (block.type === 'text') {\n openaiMessages.push({\n role: message.message.role,\n content: block.text,\n })\n } else if (block.type === 'tool_use') {\n openaiMessages.push({\n role: 'assistant',\n content: undefined,\n tool_calls: [\n {\n type: 'function',\n function: {\n name: block.name,\n arguments: JSON.stringify(block.input),\n },\n id: block.id,\n },\n ],\n })\n } else if (block.type === 'tool_result') {\n // Ensure content is always a string for role:tool messages\n let toolContent = block.content\n if (typeof toolContent !== 'string') {\n toolContent = JSON.stringify(toolContent)\n }\n\n toolResults[block.tool_use_id] = {\n role: 'tool',\n content: toolContent,\n tool_call_id: block.tool_use_id,\n }\n }\n }\n }\n\n const finalMessages: (\n | OpenAI.ChatCompletionMessageParam\n | OpenAI.ChatCompletionToolMessageParam\n )[] = []\n\n for (const message of openaiMessages) {\n finalMessages.push(message)\n\n if ('tool_calls' in message && message.tool_calls) {\n for (const toolCall of message.tool_calls) {\n if (toolResults[toolCall.id]) {\n finalMessages.push(toolResults[toolCall.id])\n }\n }\n }\n }\n\n return finalMessages\n}\n\nfunction messageReducer(\n previous: OpenAI.ChatCompletionMessage,\n item: OpenAI.ChatCompletionChunk,\n): OpenAI.ChatCompletionMessage {\n const reduce = (acc: any, delta: OpenAI.ChatCompletionChunk.Choice.Delta) => {\n acc = { ...acc }\n for (const [key, value] of Object.entries(delta)) {\n if (acc[key] === undefined || acc[key] === null) {\n acc[key] = value\n if (Array.isArray(acc[key])) {\n for (const arr of acc[key]) {\n delete arr.index\n }\n }\n } else if (typeof acc[key] === 'string' && typeof value === 'string') {\n acc[key] += value\n } else if (typeof acc[key] === 'number' && typeof value === 'number') {\n acc[key] = value\n } else if (Array.isArray(acc[key]) && Array.isArray(value)) {\n const accArray = acc[key]\n for (let i = 0; i < value.length; i++) {\n const { index: rawIndex, ...chunkTool } = value[i]\n // Default index to 0 when missing (Gemini doesn't include index in tool call deltas)\n const index = rawIndex ?? 0\n if (index - accArray.length > 1) {\n throw new Error(\n `Error: An array has an empty value when tool_calls are constructed. tool_calls: ${accArray}; tool: ${value}`,\n )\n }\n accArray[index] = reduce(accArray[index], chunkTool)\n }\n } else if (typeof acc[key] === 'object' && typeof value === 'object') {\n acc[key] = reduce(acc[key], value)\n }\n }\n return acc\n }\n\n const choice = item.choices?.[0]\n if (!choice) {\n return previous\n }\n return reduce(previous, choice.delta) as OpenAI.ChatCompletionMessage\n}\n\nasync function handleMessageStream(\n stream: ChatCompletionStream,\n signal?: AbortSignal,\n): Promise<OpenAI.ChatCompletion> {\n const streamStartTime = Date.now()\n let ttftMs: number | undefined\n let chunkCount = 0\n let errorCount = 0\n\n debugLogger.api('OPENAI_STREAM_START', {\n streamStartTime: String(streamStartTime),\n })\n\n let message = {} as OpenAI.ChatCompletionMessage\n\n let id, model, created, object, usage\n try {\n for await (const chunk of stream) {\n if (signal?.aborted) {\n debugLogger.flow('OPENAI_STREAM_ABORTED', {\n chunkCount,\n timestamp: Date.now(),\n })\n throw new Error('Request was cancelled')\n }\n\n chunkCount++\n\n try {\n if (!id) {\n id = chunk.id\n debugLogger.api('OPENAI_STREAM_ID_RECEIVED', {\n id,\n chunkNumber: String(chunkCount),\n })\n }\n if (!model) {\n model = chunk.model\n debugLogger.api('OPENAI_STREAM_MODEL_RECEIVED', {\n model,\n chunkNumber: String(chunkCount),\n })\n }\n if (!created) {\n created = chunk.created\n }\n if (!object) {\n object = chunk.object\n }\n if (!usage && chunk.usage) {\n usage = chunk.usage\n setStreamingState({\n inputTokens: chunk.usage.prompt_tokens,\n outputTokens: chunk.usage.completion_tokens,\n })\n }\n\n message = messageReducer(message, chunk)\n\n if (chunk?.choices?.[0]?.delta?.content) {\n if (!ttftMs) {\n ttftMs = Date.now() - streamStartTime\n debugLogger.api('OPENAI_STREAM_FIRST_TOKEN', {\n ttftMs: String(ttftMs),\n chunkNumber: String(chunkCount),\n })\n }\n }\n } catch (chunkError) {\n errorCount++\n debugLogger.error('OPENAI_STREAM_CHUNK_ERROR', {\n chunkNumber: String(chunkCount),\n errorMessage:\n chunkError instanceof Error\n ? chunkError.message\n : String(chunkError),\n errorType:\n chunkError instanceof Error\n ? chunkError.constructor.name\n : typeof chunkError,\n })\n }\n }\n\n debugLogger.api('OPENAI_STREAM_COMPLETE', {\n totalChunks: String(chunkCount),\n errorCount: String(errorCount),\n totalDuration: String(Date.now() - streamStartTime),\n ttftMs: String(ttftMs || 0),\n finalMessageId: id || 'undefined',\n })\n } catch (streamError) {\n debugLogger.error('OPENAI_STREAM_FATAL_ERROR', {\n totalChunks: String(chunkCount),\n errorCount: String(errorCount),\n errorMessage:\n streamError instanceof Error\n ? streamError.message\n : String(streamError),\n errorType:\n streamError instanceof Error\n ? streamError.constructor.name\n : typeof streamError,\n })\n throw streamError\n }\n return {\n id,\n created,\n model,\n object,\n choices: [\n {\n index: 0,\n message,\n finish_reason: 'stop',\n logprobs: undefined,\n },\n ],\n usage,\n }\n}\n\nfunction convertOpenAIResponseToAnthropic(\n response: OpenAI.ChatCompletion,\n _tools?: Tool[],\n) {\n let contentBlocks: ContentBlock[] = []\n const message = response.choices?.[0]?.message\n if (!message) {\n return {\n role: 'assistant',\n content: [],\n stop_reason: response.choices?.[0]?.finish_reason,\n type: 'message',\n usage: response.usage,\n }\n }\n\n if (message?.tool_calls) {\n for (const toolCall of message.tool_calls) {\n const tool = toolCall.function\n const toolName = tool?.name\n let toolArgs = {}\n let parseError: string | null = null\n try {\n toolArgs = tool?.arguments ? JSON.parse(tool.arguments) : {}\n } catch (e) {\n parseError = e instanceof Error ? e.message : String(e)\n debugLogger.warn('TOOL_ARGUMENTS_PARSE_ERROR', {\n toolName,\n rawArguments: tool?.arguments?.substring(0, 200),\n errorMessage: parseError,\n })\n }\n\n if (parseError && Object.keys(toolArgs).length === 0) {\n debugLogger.error('TOOL_CALL_EMPTY_ARGUMENTS', {\n toolName,\n parseError,\n suggestion:\n 'Model may have sent malformed JSON. The tool call will likely fail validation.',\n })\n }\n\n contentBlocks.push({\n type: 'tool_use',\n input: toolArgs,\n name: toolName,\n id: toolCall.id?.length > 0 ? toolCall.id : nanoid(),\n })\n }\n }\n\n if ((message as any).reasoning) {\n contentBlocks.push({\n type: 'thinking',\n thinking: (message as any).reasoning,\n signature: '',\n })\n }\n\n if ((message as any).reasoning_content) {\n contentBlocks.push({\n type: 'thinking',\n thinking: (message as any).reasoning_content,\n signature: '',\n })\n }\n\n if (message.content) {\n contentBlocks.push({\n type: 'text',\n text: message?.content,\n citations: [],\n })\n }\n\n const finalMessage = {\n role: 'assistant',\n content: contentBlocks,\n stop_reason: response.choices?.[0]?.finish_reason,\n type: 'message',\n usage: response.usage,\n }\n\n return finalMessage\n}\n\n// \u2500\u2500 Error helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction getAssistantMessageFromError(error: unknown): AssistantMessage {\n if (error instanceof Error && error.message.includes('prompt is too long')) {\n return createAssistantAPIErrorMessage(PROMPT_TOO_LONG_ERROR_MESSAGE)\n }\n if (\n error instanceof Error &&\n error.message.includes('Your credit balance is too low')\n ) {\n return createAssistantAPIErrorMessage(CREDIT_BALANCE_TOO_LOW_ERROR_MESSAGE)\n }\n if (\n error instanceof Error &&\n error.message.toLowerCase().includes('x-api-key')\n ) {\n return createAssistantAPIErrorMessage(INVALID_API_KEY_ERROR_MESSAGE)\n }\n if (error instanceof Error) {\n if (process.env.NODE_ENV === 'development') {\n debugLogger.error('OPENAI_API_ERROR', {\n message: error.message,\n stack: error.stack,\n })\n }\n return createAssistantAPIErrorMessage(\n `${API_ERROR_MESSAGE_PREFIX}: ${error.message}`,\n )\n }\n return createAssistantAPIErrorMessage(API_ERROR_MESSAGE_PREFIX)\n}\n\n// \u2500\u2500 queryOpenAI \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport async function queryOpenAI(\n messages: (UserMessage | AssistantMessage)[],\n systemPrompt: string[],\n maxThinkingTokens: number,\n tools: Tool[],\n signal: AbortSignal,\n options?: {\n safeMode: boolean\n model: string\n prependCLISysprompt: boolean\n modelProfile?: ModelProfile | null\n toolUseContext?: ToolUseContext\n },\n): Promise<AssistantMessage> {\n const config = getGlobalConfig()\n const modelManager = getModelManager()\n const toolUseContext = options?.toolUseContext\n\n const modelProfile = options?.modelProfile || modelManager.getModel('main')\n let model: string\n\n const currentRequest = getCurrentRequest()\n debugLogger.api('MODEL_CONFIG_OPENAI', {\n modelProfileFound: !!modelProfile,\n modelProfileId: modelProfile?.modelName,\n modelProfileName: modelProfile?.name,\n modelProfileModelName: modelProfile?.modelName,\n modelProfileProvider: modelProfile?.provider,\n modelProfileBaseURL: modelProfile?.baseURL,\n modelProfileApiKeyExists: !!modelProfile?.apiKey,\n optionsModel: options?.model,\n requestId: getCurrentRequest()?.id,\n })\n\n if (modelProfile) {\n model = modelProfile.modelName\n } else {\n model = options?.model || modelProfile?.modelName || ''\n }\n // Prepend system prompt block for easy API identification\n if (options?.prependCLISysprompt) {\n const [firstSyspromptBlock] = splitSysPromptPrefix(systemPrompt)\n systemPrompt = [getCLISyspromptPrefix(), ...systemPrompt]\n }\n\n const system: TextBlockParam[] = splitSysPromptPrefix(systemPrompt).map(\n _ => ({\n ...(PROMPT_CACHING_ENABLED\n ? { cache_control: { type: 'ephemeral' } }\n : {}),\n text: _,\n type: 'text',\n }),\n )\n\n const toolSchemas = await Promise.all(\n tools.map(\n async _ =>\n ({\n type: 'function',\n function: {\n name: _.name,\n description: await getToolDescriptionAsync(_),\n parameters:\n 'inputJSONSchema' in _ && _.inputJSONSchema\n ? _.inputJSONSchema\n : zodToJsonSchema(_.inputSchema),\n },\n }) as OpenAI.ChatCompletionTool,\n ),\n )\n\n const openaiSystem = system.map(\n s =>\n ({\n role: 'system',\n content: s.text,\n }) as OpenAI.ChatCompletionMessageParam,\n )\n\n const openaiMessages = convertAnthropicMessagesToOpenAIMessages(messages)\n const startIncludingRetries = Date.now()\n\n logSystemPromptConstruction({\n basePrompt: systemPrompt.join('\\n'),\n mintoContext: generateMintoContext() || '',\n reminders: [],\n finalPrompt: systemPrompt.join('\\n'),\n })\n\n let start = Date.now()\n let attemptNumber = 0\n let response\n\n try {\n response = await withRetry(\n async attempt => {\n attemptNumber = attempt\n start = Date.now()\n const maxTokens = getMaxTokensFromProfile(modelProfile)\n const isGPT5 = isGPT5Model(model)\n\n // Determine if this model requires temperature to be omitted entirely\n const isReasoningModel =\n isGPT5 ||\n model.startsWith('o3') ||\n model.startsWith('o4-mini') ||\n model === 'o1' ||\n model === 'o1-mini' ||\n model === 'o1-preview'\n\n const opts: OpenAI.ChatCompletionCreateParams = {\n model,\n\n ...(isGPT5\n ? { max_completion_tokens: maxTokens }\n : { max_tokens: maxTokens }),\n messages: [...openaiSystem, ...openaiMessages],\n\n // Reasoning models (GPT-5, o3, o4-mini) require temperature to be omitted\n ...(!isReasoningModel && { temperature: MAIN_QUERY_TEMPERATURE }),\n }\n if (config.stream) {\n ;(opts as OpenAI.ChatCompletionCreateParams).stream = true\n opts.stream_options = {\n include_usage: true,\n }\n }\n\n if (toolSchemas.length > 0) {\n opts.tools = toolSchemas\n opts.tool_choice = 'auto'\n }\n const reasoningEffort = await getReasoningEffort(modelProfile, messages)\n if (reasoningEffort) {\n opts.reasoning_effort = reasoningEffort\n }\n\n if (modelProfile && modelProfile.modelName) {\n debugLogger.api('USING_MODEL_PROFILE_PATH', {\n modelProfileName: modelProfile.modelName,\n modelName: modelProfile.modelName,\n provider: modelProfile.provider,\n baseURL: modelProfile.baseURL,\n apiKeyExists: !!modelProfile.apiKey,\n requestId: getCurrentRequest()?.id,\n })\n\n // Enable new adapter system with environment variable\n const USE_NEW_ADAPTER_SYSTEM =\n process.env.USE_NEW_ADAPTERS !== 'false'\n\n if (USE_NEW_ADAPTER_SYSTEM) {\n // New adapter system\n const adapter = ModelAdapterFactory.createAdapter(modelProfile)\n\n // Build unified request parameters\n const unifiedParams: UnifiedRequestParams = {\n messages: openaiMessages,\n systemPrompt: openaiSystem.map(s => s.content as string),\n tools: tools,\n maxTokens: getMaxTokensFromProfile(modelProfile),\n stream: config.stream,\n reasoningEffort: reasoningEffort as any,\n temperature:\n isGPT5Model(model) ||\n model.startsWith('o3') ||\n model.startsWith('o4-mini')\n ? undefined\n : MAIN_QUERY_TEMPERATURE,\n previousResponseId:\n toolUseContext?.responseState?.previousResponseId,\n verbosity: 'high', // High verbosity for coding tasks\n }\n\n // Create request using adapter\n const request = adapter.createRequest(unifiedParams)\n\n // Determine which API to use\n if (ModelAdapterFactory.shouldUseResponsesAPI(modelProfile)) {\n // Use Responses API for GPT-5 and similar models\n const { callGPT5ResponsesAPI } = await import('../openai')\n const response = await callGPT5ResponsesAPI(\n modelProfile,\n request,\n signal,\n )\n const unifiedResponse = adapter.parseResponse(response)\n\n // Convert unified response back to Anthropic format\n const apiMessage = {\n role: 'assistant' as const,\n content: unifiedResponse.content,\n tool_calls: unifiedResponse.toolCalls,\n usage: {\n prompt_tokens: unifiedResponse.usage.promptTokens,\n completion_tokens: unifiedResponse.usage.completionTokens,\n },\n }\n const assistantMsg: AssistantMessage = {\n type: 'assistant',\n message: apiMessage as any,\n costUSD: 0, // Will be calculated later\n durationMs: Date.now() - start,\n uuid: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}` as any,\n responseId: unifiedResponse.responseId, // For state management\n }\n return assistantMsg\n } else {\n // Use existing Chat Completions flow\n const s = await getCompletionWithProfile(\n modelProfile,\n request,\n 0,\n 10,\n signal,\n )\n let finalResponse\n if (config.stream) {\n finalResponse = await handleMessageStream(\n s as ChatCompletionStream,\n signal,\n )\n } else {\n finalResponse = s\n }\n const r = convertOpenAIResponseToAnthropic(finalResponse, tools)\n return r\n }\n } else {\n // Legacy system (preserved for fallback)\n const completionFunction = isGPT5Model(modelProfile.modelName)\n ? getGPT5CompletionWithProfile\n : getCompletionWithProfile\n const s = await completionFunction(\n modelProfile,\n opts,\n 0,\n 10,\n signal,\n )\n let finalResponse\n if (opts.stream) {\n finalResponse = await handleMessageStream(\n s as ChatCompletionStream,\n signal,\n )\n } else {\n finalResponse = s\n }\n const r = convertOpenAIResponseToAnthropic(finalResponse, tools)\n return r\n }\n } else {\n const errorDetails = {\n modelProfileExists: !!modelProfile,\n modelProfileId: modelProfile?.modelName,\n modelNameExists: !!modelProfile?.modelName,\n requestedModel: model,\n requestId: getCurrentRequest()?.id,\n }\n debugLogger.error('NO_VALID_MODEL_PROFILE', errorDetails)\n throw new Error(\n `No valid ModelProfile available for model: ${model}. Please configure model through /model command. Debug: ${JSON.stringify(errorDetails)}`,\n )\n }\n },\n {\n signal,\n onRetry: toolUseContext?.agentId\n ? ({ attempt, maxRetries, error, delayMs }) => {\n addRetryEventToTranscript(toolUseContext.agentId!, {\n attempt,\n maxRetries,\n errorMessage: error.message,\n delayMs,\n })\n }\n : undefined,\n },\n )\n } catch (error) {\n logError(error)\n return getAssistantMessageFromError(error)\n }\n const durationMs = Date.now() - start\n const durationMsIncludingRetries = Date.now() - startIncludingRetries\n\n const inputTokens = response.usage?.prompt_tokens ?? 0\n const outputTokens = response.usage?.completion_tokens ?? 0\n const cacheReadInputTokens =\n response.usage?.prompt_token_details?.cached_tokens ?? 0\n const cacheCreationInputTokens =\n response.usage?.prompt_token_details?.cached_tokens ?? 0\n\n // Use per-model pricing from models registry, falling back to defaults for unknown models\n const inputCostPerMillion = getModelInputTokenCostUSD(model) * 1_000_000\n const outputCostPerMillion = getModelOutputTokenCostUSD(model) * 1_000_000\n const costUSD =\n (inputTokens / 1_000_000) *\n (inputCostPerMillion || SONNET_COST_PER_MILLION_INPUT_TOKENS) +\n (outputTokens / 1_000_000) *\n (outputCostPerMillion || SONNET_COST_PER_MILLION_OUTPUT_TOKENS) +\n (cacheReadInputTokens / 1_000_000) *\n (inputCostPerMillion || SONNET_COST_PER_MILLION_INPUT_TOKENS) *\n 0.1 +\n (cacheCreationInputTokens / 1_000_000) *\n (inputCostPerMillion || SONNET_COST_PER_MILLION_INPUT_TOKENS)\n\n addToTotalCost(costUSD, durationMsIncludingRetries)\n\n // Record token usage to unified stats manager\n recordTokenUsage(\n {\n inputTokens,\n outputTokens,\n cacheCreationTokens: cacheCreationInputTokens,\n cacheReadTokens: cacheReadInputTokens,\n },\n costUSD,\n model,\n toolUseContext\n ? ({\n agentId: toolUseContext.agentId,\n toolUseId: toolUseContext.toolUseId,\n model,\n } as TokenTrackingContext)\n : undefined,\n )\n\n // Log LLM interaction (OpenAI path)\n logLLMInteraction({\n systemPrompt: systemPrompt.join('\\n'),\n messages: [...openaiSystem, ...openaiMessages],\n response: response,\n usage: {\n inputTokens: inputTokens,\n outputTokens: outputTokens,\n },\n timing: {\n start: start,\n end: Date.now(),\n },\n apiFormat: 'openai',\n })\n\n return {\n message: {\n ...response,\n content: normalizeContentFromAPI(response.content),\n usage: {\n input_tokens: inputTokens,\n output_tokens: outputTokens,\n cache_read_input_tokens: cacheReadInputTokens,\n cache_creation_input_tokens: 0,\n },\n },\n costUSD,\n durationMs,\n type: 'assistant',\n uuid: randomUUID(),\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["response"]
|
|
4
|
+
"sourcesContent": ["/**\n * OpenAI-compatible provider \u2014 message conversion, streaming, and query path.\n */\nimport { randomUUID } from 'crypto'\nimport { nanoid } from 'nanoid'\n\nimport type { AssistantMessage, UserMessage } from '@query'\nimport { Tool, getToolDescriptionAsync } from '@tool'\nimport type { ToolUseContext } from '@tool'\nimport { getGlobalConfig, ModelProfile } from '@utils/config'\nimport { isGPT5ModelName as isGPT5Model } from '@utils/config'\nimport { normalizeContentFromAPI } from '@utils/messages'\nimport {\n debug as debugLogger,\n getCurrentRequest,\n logLLMInteraction,\n logSystemPromptConstruction,\n} from '@utils/debugLogger'\nimport { getModelManager } from '@utils/model'\nimport { zodToJsonSchema } from 'zod-to-json-schema'\nimport { ModelAdapterFactory } from '../modelAdapterFactory'\nimport { UnifiedRequestParams } from '@minto-types/modelCapabilities'\nimport { getCLISyspromptPrefix } from '@constants/prompts'\nimport OpenAI from 'openai'\nimport type { ChatCompletionStream } from 'openai/lib/ChatCompletionStream'\nimport { ContentBlock } from '@anthropic-ai/sdk/resources/messages/messages'\nimport type { TextBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport { setStreamingState, getStreamingState } from '@utils/streamingState'\nimport {\n beginTokenTracking,\n addPreparedChars,\n addReceivedChars,\n setFinalTokens,\n} from '@utils/tokenProgress'\nimport {\n getCompletionWithProfile,\n getGPT5CompletionWithProfile,\n} from '../openai'\nimport { getReasoningEffort } from '@utils/thinking'\nimport { addRetryEventToTranscript } from '@utils/agentTranscripts'\nimport type { TokenTrackingContext } from '@core/tokenStats'\n\nimport { generateMintoContext } from './mintoContext'\nimport { splitSysPromptPrefix } from './anthropicProvider'\nimport {\n PROMPT_CACHING_ENABLED,\n MAIN_QUERY_TEMPERATURE,\n withRetry,\n getMaxTokensFromProfile,\n calculateCostUSD,\n getAssistantMessageFromError,\n addToTotalCost,\n recordTokenUsage,\n logError,\n} from './types'\n\n// \u2500\u2500 OpenAI message conversion \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction convertAnthropicMessagesToOpenAIMessages(\n messages: (UserMessage | AssistantMessage)[],\n): (\n | OpenAI.ChatCompletionMessageParam\n | OpenAI.ChatCompletionToolMessageParam\n)[] {\n const openaiMessages: (\n | OpenAI.ChatCompletionMessageParam\n | OpenAI.ChatCompletionToolMessageParam\n )[] = []\n\n const toolResults: Record<string, OpenAI.ChatCompletionToolMessageParam> = {}\n\n for (const message of messages) {\n let contentBlocks = []\n if (typeof message.message.content === 'string') {\n contentBlocks = [\n {\n type: 'text',\n text: message.message.content,\n },\n ]\n } else if (!Array.isArray(message.message.content)) {\n contentBlocks = [message.message.content]\n } else {\n contentBlocks = message.message.content\n }\n\n for (const block of contentBlocks) {\n if (block.type === 'text') {\n openaiMessages.push({\n role: message.message.role,\n content: block.text,\n })\n } else if (block.type === 'tool_use') {\n openaiMessages.push({\n role: 'assistant',\n content: undefined,\n tool_calls: [\n {\n type: 'function',\n function: {\n name: block.name,\n arguments: JSON.stringify(block.input),\n },\n id: block.id,\n },\n ],\n })\n } else if (block.type === 'tool_result') {\n // Ensure content is always a string for role:tool messages\n let toolContent = block.content\n if (typeof toolContent !== 'string') {\n toolContent = JSON.stringify(toolContent)\n }\n\n toolResults[block.tool_use_id] = {\n role: 'tool',\n content: toolContent,\n tool_call_id: block.tool_use_id,\n }\n }\n }\n }\n\n const finalMessages: (\n | OpenAI.ChatCompletionMessageParam\n | OpenAI.ChatCompletionToolMessageParam\n )[] = []\n\n for (const message of openaiMessages) {\n finalMessages.push(message)\n\n if ('tool_calls' in message && message.tool_calls) {\n for (const toolCall of message.tool_calls) {\n if (toolResults[toolCall.id]) {\n finalMessages.push(toolResults[toolCall.id])\n }\n }\n }\n }\n\n return finalMessages\n}\n\nfunction messageReducer(\n previous: OpenAI.ChatCompletionMessage,\n item: OpenAI.ChatCompletionChunk,\n): OpenAI.ChatCompletionMessage {\n const reduce = (acc: any, delta: OpenAI.ChatCompletionChunk.Choice.Delta) => {\n acc = { ...acc }\n for (const [key, value] of Object.entries(delta)) {\n if (acc[key] === undefined || acc[key] === null) {\n acc[key] = value\n if (Array.isArray(acc[key])) {\n for (const arr of acc[key]) {\n delete arr.index\n }\n }\n } else if (typeof acc[key] === 'string' && typeof value === 'string') {\n acc[key] += value\n } else if (typeof acc[key] === 'number' && typeof value === 'number') {\n acc[key] = value\n } else if (Array.isArray(acc[key]) && Array.isArray(value)) {\n const accArray = acc[key]\n for (let i = 0; i < value.length; i++) {\n const { index: rawIndex, ...chunkTool } = value[i]\n // Default index to 0 when missing (Gemini doesn't include index in tool call deltas)\n const index = rawIndex ?? 0\n if (index - accArray.length > 1) {\n throw new Error(\n `Error: An array has an empty value when tool_calls are constructed. tool_calls: ${accArray}; tool: ${value}`,\n )\n }\n accArray[index] = reduce(accArray[index], chunkTool)\n }\n } else if (typeof acc[key] === 'object' && typeof value === 'object') {\n acc[key] = reduce(acc[key], value)\n }\n }\n return acc\n }\n\n const choice = item.choices?.[0]\n if (!choice) {\n return previous\n }\n return reduce(previous, choice.delta) as OpenAI.ChatCompletionMessage\n}\n\nasync function handleMessageStream(\n stream: ChatCompletionStream,\n signal?: AbortSignal,\n): Promise<OpenAI.ChatCompletion> {\n const streamStartTime = Date.now()\n setStreamingState({ receivedChars: 0 })\n let ttftMs: number | undefined\n let chunkCount = 0\n let errorCount = 0\n\n debugLogger.api('OPENAI_STREAM_START', {\n streamStartTime: String(streamStartTime),\n })\n\n let message = {} as OpenAI.ChatCompletionMessage\n\n let id, model, created, object, usage\n try {\n for await (const chunk of stream) {\n if (signal?.aborted) {\n debugLogger.flow('OPENAI_STREAM_ABORTED', {\n chunkCount,\n timestamp: Date.now(),\n })\n throw new Error('Request was cancelled')\n }\n\n chunkCount++\n\n try {\n if (!id) {\n id = chunk.id\n debugLogger.api('OPENAI_STREAM_ID_RECEIVED', {\n id,\n chunkNumber: String(chunkCount),\n })\n }\n if (!model) {\n model = chunk.model\n debugLogger.api('OPENAI_STREAM_MODEL_RECEIVED', {\n model,\n chunkNumber: String(chunkCount),\n })\n }\n if (!created) {\n created = chunk.created\n }\n if (!object) {\n object = chunk.object\n }\n if (!usage && chunk.usage) {\n usage = chunk.usage\n setFinalTokens({\n input: chunk.usage.prompt_tokens,\n output: chunk.usage.completion_tokens,\n })\n }\n\n message = messageReducer(message, chunk)\n\n if (chunk?.choices?.[0]?.delta?.content) {\n const textChunk = chunk.choices[0].delta.content!\n addReceivedChars(textChunk.length)\n // Append to streaming text buffer for typewriter preview\n const prevText = getStreamingState().streamingText || ''\n setStreamingState({\n streamingText: prevText + textChunk,\n phase: 'generating',\n })\n if (!ttftMs) {\n ttftMs = Date.now() - streamStartTime\n debugLogger.api('OPENAI_STREAM_FIRST_TOKEN', {\n ttftMs: String(ttftMs),\n chunkNumber: String(chunkCount),\n })\n }\n }\n } catch (chunkError) {\n errorCount++\n debugLogger.error('OPENAI_STREAM_CHUNK_ERROR', {\n chunkNumber: String(chunkCount),\n errorMessage:\n chunkError instanceof Error\n ? chunkError.message\n : String(chunkError),\n errorType:\n chunkError instanceof Error\n ? chunkError.constructor.name\n : typeof chunkError,\n })\n }\n }\n\n debugLogger.api('OPENAI_STREAM_COMPLETE', {\n totalChunks: String(chunkCount),\n errorCount: String(errorCount),\n totalDuration: String(Date.now() - streamStartTime),\n ttftMs: String(ttftMs || 0),\n finalMessageId: id || 'undefined',\n })\n } catch (streamError) {\n debugLogger.error('OPENAI_STREAM_FATAL_ERROR', {\n totalChunks: String(chunkCount),\n errorCount: String(errorCount),\n errorMessage:\n streamError instanceof Error\n ? streamError.message\n : String(streamError),\n errorType:\n streamError instanceof Error\n ? streamError.constructor.name\n : typeof streamError,\n })\n throw streamError\n }\n return {\n id,\n created,\n model,\n object,\n choices: [\n {\n index: 0,\n message,\n finish_reason: 'stop',\n logprobs: undefined,\n },\n ],\n usage,\n }\n}\n\nfunction convertOpenAIResponseToAnthropic(\n response: OpenAI.ChatCompletion,\n _tools?: Tool[],\n) {\n let contentBlocks: ContentBlock[] = []\n const message = response.choices?.[0]?.message\n if (!message) {\n return {\n role: 'assistant',\n content: [],\n stop_reason: response.choices?.[0]?.finish_reason,\n type: 'message',\n usage: response.usage,\n }\n }\n\n if (message?.tool_calls) {\n for (const toolCall of message.tool_calls) {\n const tool = toolCall.function\n const toolName = tool?.name\n let toolArgs = {}\n let parseError: string | null = null\n try {\n toolArgs = tool?.arguments ? JSON.parse(tool.arguments) : {}\n } catch (e) {\n parseError = e instanceof Error ? e.message : String(e)\n debugLogger.warn('TOOL_ARGUMENTS_PARSE_ERROR', {\n toolName,\n rawArguments: tool?.arguments?.substring(0, 200),\n errorMessage: parseError,\n })\n }\n\n if (parseError && Object.keys(toolArgs).length === 0) {\n debugLogger.error('TOOL_CALL_EMPTY_ARGUMENTS', {\n toolName,\n parseError,\n suggestion:\n 'Model may have sent malformed JSON. The tool call will likely fail validation.',\n })\n }\n\n contentBlocks.push({\n type: 'tool_use',\n input: toolArgs,\n name: toolName,\n id: toolCall.id?.length > 0 ? toolCall.id : nanoid(),\n })\n }\n }\n\n // Non-standard reasoning/reasoning_content fields from some providers\n // (e.g., DeepSeek, QwQ, GLM) are intentionally ignored \u2014 they cause\n // repetitive thinking display across tool-use turns. The model's actual\n // response comes through standard content/tool_calls fields.\n\n if (message.content) {\n contentBlocks.push({\n type: 'text',\n text: message?.content,\n citations: [],\n })\n }\n\n const finalMessage = {\n role: 'assistant',\n content: contentBlocks,\n stop_reason: response.choices?.[0]?.finish_reason,\n type: 'message',\n usage: response.usage,\n }\n\n return finalMessage\n}\n\n// Error helpers: uses shared getAssistantMessageFromError from types.ts\n\n// \u2500\u2500 queryOpenAI \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport async function queryOpenAI(\n messages: (UserMessage | AssistantMessage)[],\n systemPrompt: string[],\n maxThinkingTokens: number,\n tools: Tool[],\n signal: AbortSignal,\n options?: {\n safeMode: boolean\n model: string\n prependCLISysprompt: boolean\n modelProfile?: ModelProfile | null\n toolUseContext?: ToolUseContext\n },\n): Promise<AssistantMessage> {\n const config = getGlobalConfig()\n const modelManager = getModelManager()\n const toolUseContext = options?.toolUseContext\n\n beginTokenTracking()\n\n const modelProfile = options?.modelProfile || modelManager.getModel('main')\n let model: string\n\n const currentRequest = getCurrentRequest()\n debugLogger.api('MODEL_CONFIG_OPENAI', {\n modelProfileFound: !!modelProfile,\n modelProfileId: modelProfile?.modelName,\n modelProfileName: modelProfile?.name,\n modelProfileModelName: modelProfile?.modelName,\n modelProfileProvider: modelProfile?.provider,\n modelProfileBaseURL: modelProfile?.baseURL,\n modelProfileApiKeyExists: !!modelProfile?.apiKey,\n optionsModel: options?.model,\n requestId: getCurrentRequest()?.id,\n })\n\n if (modelProfile) {\n model = modelProfile.modelName\n } else {\n model = options?.model || modelProfile?.modelName || ''\n }\n // Prepend system prompt block for easy API identification\n if (options?.prependCLISysprompt) {\n systemPrompt = [getCLISyspromptPrefix(), ...systemPrompt]\n }\n\n const system: TextBlockParam[] = splitSysPromptPrefix(systemPrompt).map(\n _ => ({\n ...(PROMPT_CACHING_ENABLED\n ? { cache_control: { type: 'ephemeral' } }\n : {}),\n text: _,\n type: 'text',\n }),\n )\n\n // Track system prompt preparation progress\n addPreparedChars(JSON.stringify(system).length)\n\n const toolSchemas = await Promise.all(\n tools.map(async _ => {\n const schema = {\n type: 'function',\n function: {\n name: _.name,\n description: await getToolDescriptionAsync(_),\n parameters:\n 'inputJSONSchema' in _ && _.inputJSONSchema\n ? _.inputJSONSchema\n : zodToJsonSchema(_.inputSchema),\n },\n } as OpenAI.ChatCompletionTool\n addPreparedChars(JSON.stringify(schema).length)\n return schema\n }),\n )\n\n const openaiSystem = system.map(\n s =>\n ({\n role: 'system',\n content: s.text,\n }) as OpenAI.ChatCompletionMessageParam,\n )\n\n const openaiMessages = convertAnthropicMessagesToOpenAIMessages(messages)\n addPreparedChars(JSON.stringify(openaiMessages).length)\n\n const startIncludingRetries = Date.now()\n\n logSystemPromptConstruction({\n basePrompt: systemPrompt.join('\\n'),\n mintoContext: generateMintoContext() || '',\n reminders: [],\n finalPrompt: systemPrompt.join('\\n'),\n })\n\n let start = Date.now()\n let attemptNumber = 0\n let response\n\n try {\n response = await withRetry(\n async attempt => {\n attemptNumber = attempt\n start = Date.now()\n const maxTokens = getMaxTokensFromProfile(modelProfile)\n const isGPT5 = isGPT5Model(model)\n\n // Determine if this model requires temperature to be omitted entirely\n const isReasoningModel =\n isGPT5 ||\n model.startsWith('o3') ||\n model.startsWith('o4-mini') ||\n model === 'o1' ||\n model === 'o1-mini' ||\n model === 'o1-preview'\n\n const opts: OpenAI.ChatCompletionCreateParams = {\n model,\n\n ...(isGPT5\n ? { max_completion_tokens: maxTokens }\n : { max_tokens: maxTokens }),\n messages: [...openaiSystem, ...openaiMessages],\n\n // Reasoning models (GPT-5, o3, o4-mini) require temperature to be omitted\n ...(!isReasoningModel && { temperature: MAIN_QUERY_TEMPERATURE }),\n }\n if (config.stream) {\n ;(opts as OpenAI.ChatCompletionCreateParams).stream = true\n opts.stream_options = {\n include_usage: true,\n }\n }\n\n if (toolSchemas.length > 0) {\n opts.tools = toolSchemas\n opts.tool_choice = 'auto'\n }\n // Only send reasoning_effort for models that explicitly support it\n // (e.g., o3, o4-mini, GPT-5). Sending it to models like glm-5 or\n // deepseek causes a 400 \"UnsupportedParamsError\" from proxies.\n const reasoningEffort = isReasoningModel\n ? await getReasoningEffort(modelProfile, messages)\n : undefined\n if (reasoningEffort) {\n opts.reasoning_effort = reasoningEffort\n }\n\n if (modelProfile && modelProfile.modelName) {\n debugLogger.api('USING_MODEL_PROFILE_PATH', {\n modelProfileName: modelProfile.modelName,\n modelName: modelProfile.modelName,\n provider: modelProfile.provider,\n baseURL: modelProfile.baseURL,\n apiKeyExists: !!modelProfile.apiKey,\n requestId: getCurrentRequest()?.id,\n })\n\n // Only use adapter system for models that need the Responses API\n // (e.g., GPT-5). For standard Chat Completions models, use opts\n // directly \u2014 opts already has full async tool descriptions and\n // properly formatted messages. The adapter would rebuild these\n // from raw Tool[] objects using sync getToolDescription(), which\n // returns degraded fallback descriptions for async tools.\n if (ModelAdapterFactory.shouldUseResponsesAPI(modelProfile)) {\n const adapter = ModelAdapterFactory.createAdapter(modelProfile)\n\n const unifiedParams: UnifiedRequestParams = {\n messages: openaiMessages,\n systemPrompt: openaiSystem.map(s => s.content as string),\n tools: tools,\n maxTokens: getMaxTokensFromProfile(modelProfile),\n stream: config.stream,\n reasoningEffort: reasoningEffort as any,\n temperature:\n isGPT5Model(model) ||\n model.startsWith('o3') ||\n model.startsWith('o4-mini')\n ? undefined\n : MAIN_QUERY_TEMPERATURE,\n previousResponseId:\n toolUseContext?.responseState?.previousResponseId,\n verbosity: 'high',\n }\n\n const request = adapter.createRequest(unifiedParams)\n\n const { callGPT5ResponsesAPI } = await import('../openai')\n const response = await callGPT5ResponsesAPI(\n modelProfile,\n request,\n signal,\n )\n const unifiedResponse = adapter.parseResponse(response)\n\n const apiMessage = {\n role: 'assistant' as const,\n content: unifiedResponse.content,\n tool_calls: unifiedResponse.toolCalls,\n usage: {\n prompt_tokens: unifiedResponse.usage.promptTokens,\n completion_tokens: unifiedResponse.usage.completionTokens,\n },\n }\n const respDurationMs = Date.now() - start\n const respInputTokens = unifiedResponse.usage.promptTokens\n const respOutputTokens = unifiedResponse.usage.completionTokens\n const respCostUSD = calculateCostUSD({\n model,\n inputTokens: respInputTokens,\n outputTokens: respOutputTokens,\n cacheReadTokens: 0,\n cacheCreationTokens: 0,\n })\n addToTotalCost(respCostUSD, respDurationMs)\n recordTokenUsage(\n {\n inputTokens: respInputTokens,\n outputTokens: respOutputTokens,\n cacheCreationTokens: 0,\n cacheReadTokens: 0,\n },\n respCostUSD,\n model,\n toolUseContext\n ? ({\n agentId: toolUseContext.agentId,\n toolUseId: toolUseContext.toolUseId,\n model,\n } as TokenTrackingContext)\n : undefined,\n )\n logLLMInteraction({\n systemPrompt: systemPrompt.join('\\n'),\n messages: [...openaiSystem, ...openaiMessages],\n response: apiMessage,\n usage: {\n inputTokens: respInputTokens,\n outputTokens: respOutputTokens,\n },\n timing: { start, end: Date.now() },\n apiFormat: 'openai',\n })\n const assistantMsg: AssistantMessage = {\n type: 'assistant',\n message: apiMessage as any,\n costUSD: respCostUSD,\n durationMs: respDurationMs,\n uuid: randomUUID(),\n responseId: unifiedResponse.responseId,\n }\n return assistantMsg\n }\n\n // Chat Completions path \u2014 use pre-built opts with full async\n // tool descriptions, correct messages, and proper streaming config.\n const completionFunction = isGPT5Model(modelProfile.modelName)\n ? getGPT5CompletionWithProfile\n : getCompletionWithProfile\n const s = await completionFunction(modelProfile, opts, 0, 10, signal)\n let finalResponse\n if (opts.stream) {\n finalResponse = await handleMessageStream(\n s as ChatCompletionStream,\n signal,\n )\n } else {\n finalResponse = s\n }\n const r = convertOpenAIResponseToAnthropic(finalResponse, tools)\n return r\n } else {\n const errorDetails = {\n modelProfileExists: !!modelProfile,\n modelProfileId: modelProfile?.modelName,\n modelNameExists: !!modelProfile?.modelName,\n requestedModel: model,\n requestId: getCurrentRequest()?.id,\n }\n debugLogger.error('NO_VALID_MODEL_PROFILE', errorDetails)\n throw new Error(\n `No valid ModelProfile available for model: ${model}. Please configure model through /model command. Debug: ${JSON.stringify(errorDetails)}`,\n )\n }\n },\n {\n signal,\n onRetry: toolUseContext?.agentId\n ? ({ attempt, maxRetries, error, delayMs }) => {\n addRetryEventToTranscript(toolUseContext.agentId!, {\n attempt,\n maxRetries,\n errorMessage: error.message,\n delayMs,\n })\n }\n : undefined,\n },\n )\n } catch (error) {\n logError(error)\n return getAssistantMessageFromError(error, 'OPENAI')\n }\n const durationMs = Date.now() - start\n const durationMsIncludingRetries = Date.now() - startIncludingRetries\n\n const inputTokens = response.usage?.prompt_tokens ?? 0\n const outputTokens = response.usage?.completion_tokens ?? 0\n const cacheReadInputTokens =\n response.usage?.prompt_token_details?.cached_tokens ?? 0\n // OpenAI does not report cache creation tokens separately\n const cacheCreationInputTokens = 0\n\n const costUSD = calculateCostUSD({\n model,\n inputTokens,\n outputTokens,\n cacheReadTokens: cacheReadInputTokens,\n cacheCreationTokens: cacheCreationInputTokens,\n })\n\n addToTotalCost(costUSD, durationMsIncludingRetries)\n\n // Record token usage to unified stats manager\n recordTokenUsage(\n {\n inputTokens,\n outputTokens,\n cacheCreationTokens: cacheCreationInputTokens,\n cacheReadTokens: cacheReadInputTokens,\n },\n costUSD,\n model,\n toolUseContext\n ? ({\n agentId: toolUseContext.agentId,\n toolUseId: toolUseContext.toolUseId,\n model,\n } as TokenTrackingContext)\n : undefined,\n )\n\n // Log LLM interaction (OpenAI path)\n logLLMInteraction({\n systemPrompt: systemPrompt.join('\\n'),\n messages: [...openaiSystem, ...openaiMessages],\n response: response,\n usage: {\n inputTokens: inputTokens,\n outputTokens: outputTokens,\n },\n timing: {\n start: start,\n end: Date.now(),\n },\n apiFormat: 'openai',\n })\n\n return {\n message: {\n ...response,\n content: normalizeContentFromAPI(response.content),\n usage: {\n input_tokens: inputTokens,\n output_tokens: outputTokens,\n cache_read_input_tokens: cacheReadInputTokens,\n cache_creation_input_tokens: 0,\n },\n },\n costUSD,\n durationMs,\n type: 'assistant',\n uuid: randomUUID(),\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["s", "response"]
|
|
7
7
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { randomUUID } from "crypto";
|
|
1
2
|
import { APIConnectionError, APIError } from "@anthropic-ai/sdk";
|
|
2
3
|
import { addToTotalCost } from "../../cost-tracker.js";
|
|
3
4
|
import { recordTokenUsage } from "../../core/tokenStatsManager.js";
|
|
@@ -8,9 +9,7 @@ import {
|
|
|
8
9
|
abortableDelay,
|
|
9
10
|
getRetryDelay as sharedGetRetryDelay
|
|
10
11
|
} from "../../utils/async.js";
|
|
11
|
-
import {
|
|
12
|
-
debug as debugLogger
|
|
13
|
-
} from "../../utils/debugLogger.js";
|
|
12
|
+
import { debug as debugLogger } from "../../utils/debugLogger.js";
|
|
14
13
|
import { setStreamingState } from "../../utils/streamingState.js";
|
|
15
14
|
import { addRetryEventToTranscript } from "../../utils/agentTranscripts.js";
|
|
16
15
|
const API_ERROR_MESSAGE_PREFIX = "API Error";
|
|
@@ -24,7 +23,7 @@ const SONNET_COST_PER_MILLION_OUTPUT_TOKENS = 15;
|
|
|
24
23
|
const SONNET_COST_PER_MILLION_PROMPT_CACHE_WRITE_TOKENS = 3.75;
|
|
25
24
|
const SONNET_COST_PER_MILLION_PROMPT_CACHE_READ_TOKENS = 0.3;
|
|
26
25
|
const MAIN_QUERY_TEMPERATURE = 1;
|
|
27
|
-
const MAX_RETRIES = process.env.USER_TYPE === "SWE_BENCH" ? 100 :
|
|
26
|
+
const MAX_RETRIES = process.env.USER_TYPE === "SWE_BENCH" ? 100 : 5;
|
|
28
27
|
const BASE_DELAY_MS = 500;
|
|
29
28
|
function getMetadata() {
|
|
30
29
|
return {
|
|
@@ -71,7 +70,8 @@ async function withRetry(operation, options = {}) {
|
|
|
71
70
|
phase: "retrying",
|
|
72
71
|
retryCount: attempt,
|
|
73
72
|
maxRetries,
|
|
74
|
-
errorName: error.name
|
|
73
|
+
errorName: error.name,
|
|
74
|
+
retryDelayMs: delayMs
|
|
75
75
|
});
|
|
76
76
|
debugLogger.flow("API_RETRY_ATTEMPT", {
|
|
77
77
|
attempt,
|
|
@@ -111,23 +111,93 @@ async function withRetry(operation, options = {}) {
|
|
|
111
111
|
function getMaxTokensFromProfile(modelProfile) {
|
|
112
112
|
return modelProfile?.maxTokens || 8e3;
|
|
113
113
|
}
|
|
114
|
-
function
|
|
114
|
+
function findModelCostInfo(model) {
|
|
115
115
|
for (const providerModels of Object.values(models)) {
|
|
116
|
-
const modelInfo = providerModels.find(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
116
|
+
const modelInfo = providerModels.find(
|
|
117
|
+
(m) => m.model === model
|
|
118
|
+
);
|
|
119
|
+
if (modelInfo) return modelInfo;
|
|
120
120
|
}
|
|
121
|
+
return void 0;
|
|
122
|
+
}
|
|
123
|
+
function getModelInputTokenCostUSD(model) {
|
|
124
|
+
const info = findModelCostInfo(model);
|
|
125
|
+
if (info?.input_cost_per_token) return info.input_cost_per_token;
|
|
126
|
+
debugLogger.warn("UNKNOWN_MODEL_COST", { model, direction: "input" });
|
|
121
127
|
return 3e-6;
|
|
122
128
|
}
|
|
123
129
|
function getModelOutputTokenCostUSD(model) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
130
|
+
const info = findModelCostInfo(model);
|
|
131
|
+
if (info?.output_cost_per_token) return info.output_cost_per_token;
|
|
132
|
+
debugLogger.warn("UNKNOWN_MODEL_COST", { model, direction: "output" });
|
|
133
|
+
return 15e-6;
|
|
134
|
+
}
|
|
135
|
+
function getModelCacheReadCostUSD(model) {
|
|
136
|
+
const info = findModelCostInfo(model);
|
|
137
|
+
if (info?.cache_read_input_token_cost) return info.cache_read_input_token_cost;
|
|
138
|
+
return getModelInputTokenCostUSD(model) * 0.1;
|
|
139
|
+
}
|
|
140
|
+
function getModelCacheCreationCostUSD(model) {
|
|
141
|
+
const info = findModelCostInfo(model);
|
|
142
|
+
if (info?.cache_creation_input_token_cost !== void 0)
|
|
143
|
+
return info.cache_creation_input_token_cost;
|
|
144
|
+
return getModelInputTokenCostUSD(model) * 1.25;
|
|
145
|
+
}
|
|
146
|
+
function calculateCostUSD(params) {
|
|
147
|
+
return params.inputTokens * getModelInputTokenCostUSD(params.model) + params.outputTokens * getModelOutputTokenCostUSD(params.model) + params.cacheReadTokens * getModelCacheReadCostUSD(params.model) + params.cacheCreationTokens * getModelCacheCreationCostUSD(params.model);
|
|
148
|
+
}
|
|
149
|
+
function createAssistantAPIErrorMessage(content) {
|
|
150
|
+
return {
|
|
151
|
+
type: "assistant",
|
|
152
|
+
costUSD: 0,
|
|
153
|
+
durationMs: 0,
|
|
154
|
+
uuid: randomUUID(),
|
|
155
|
+
isApiErrorMessage: true,
|
|
156
|
+
message: {
|
|
157
|
+
id: randomUUID(),
|
|
158
|
+
model: "<synthetic>",
|
|
159
|
+
role: "assistant",
|
|
160
|
+
stop_reason: "stop_sequence",
|
|
161
|
+
stop_sequence: "",
|
|
162
|
+
type: "message",
|
|
163
|
+
usage: {
|
|
164
|
+
input_tokens: 0,
|
|
165
|
+
output_tokens: 0,
|
|
166
|
+
cache_creation_input_tokens: 0,
|
|
167
|
+
cache_read_input_tokens: 0
|
|
168
|
+
},
|
|
169
|
+
content: [
|
|
170
|
+
{
|
|
171
|
+
type: "text",
|
|
172
|
+
text: content === "" ? NO_CONTENT_MESSAGE : content,
|
|
173
|
+
citations: []
|
|
174
|
+
}
|
|
175
|
+
]
|
|
128
176
|
}
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function getAssistantMessageFromError(error, providerTag = "LLM") {
|
|
180
|
+
if (error instanceof Error && error.message.includes("prompt is too long")) {
|
|
181
|
+
return createAssistantAPIErrorMessage(PROMPT_TOO_LONG_ERROR_MESSAGE);
|
|
129
182
|
}
|
|
130
|
-
|
|
183
|
+
if (error instanceof Error && error.message.includes("Your credit balance is too low")) {
|
|
184
|
+
return createAssistantAPIErrorMessage(CREDIT_BALANCE_TOO_LOW_ERROR_MESSAGE);
|
|
185
|
+
}
|
|
186
|
+
if (error instanceof Error && error.message.toLowerCase().includes("x-api-key")) {
|
|
187
|
+
return createAssistantAPIErrorMessage(INVALID_API_KEY_ERROR_MESSAGE);
|
|
188
|
+
}
|
|
189
|
+
if (error instanceof Error) {
|
|
190
|
+
if (process.env.NODE_ENV === "development") {
|
|
191
|
+
debugLogger.error(`${providerTag}_API_ERROR`, {
|
|
192
|
+
message: error.message,
|
|
193
|
+
stack: error.stack
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
return createAssistantAPIErrorMessage(
|
|
197
|
+
`${API_ERROR_MESSAGE_PREFIX}: ${error.message}`
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
return createAssistantAPIErrorMessage(API_ERROR_MESSAGE_PREFIX);
|
|
131
201
|
}
|
|
132
202
|
export {
|
|
133
203
|
API_ERROR_MESSAGE_PREFIX,
|
|
@@ -144,9 +214,13 @@ export {
|
|
|
144
214
|
SONNET_COST_PER_MILLION_PROMPT_CACHE_WRITE_TOKENS,
|
|
145
215
|
addRetryEventToTranscript,
|
|
146
216
|
addToTotalCost,
|
|
217
|
+
calculateCostUSD,
|
|
147
218
|
debugLogger,
|
|
219
|
+
getAssistantMessageFromError,
|
|
148
220
|
getMaxTokensFromProfile,
|
|
149
221
|
getMetadata,
|
|
222
|
+
getModelCacheCreationCostUSD,
|
|
223
|
+
getModelCacheReadCostUSD,
|
|
150
224
|
getModelInputTokenCostUSD,
|
|
151
225
|
getModelOutputTokenCostUSD,
|
|
152
226
|
logError,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/services/llm/types.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Shared types, constants, and utility functions for LLM providers.\n */\nimport { APIConnectionError, APIError } from '@anthropic-ai/sdk'\n\nimport { addToTotalCost } from '@costTracker'\nimport { recordTokenUsage } from '@core/tokenStatsManager'\nimport type { TokenTrackingContext } from '@core/tokenStats'\nimport models from '@constants/models'\nimport { getOrCreateUserID } from '@utils/config'\nimport { logError, SESSION_ID } from '@utils/log'\nimport {\n abortableDelay,\n getRetryDelay as sharedGetRetryDelay,\n} from '@utils/async'\nimport {\n debug as debugLogger,\n} from '@utils/debugLogger'\nimport { setStreamingState } from '@utils/streamingState'\nimport { addRetryEventToTranscript } from '@utils/agentTranscripts'\n\n// \u2500\u2500 Error message constants \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const API_ERROR_MESSAGE_PREFIX = 'API Error'\nexport const PROMPT_TOO_LONG_ERROR_MESSAGE = 'Prompt is too long'\nexport const CREDIT_BALANCE_TOO_LOW_ERROR_MESSAGE = 'Credit balance is too low'\nexport const INVALID_API_KEY_ERROR_MESSAGE =\n 'Invalid API key \u00B7 Please run /login'\nexport const NO_CONTENT_MESSAGE = '(no content)'\n\n// \u2500\u2500 Cost constants \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst PROMPT_CACHING_ENABLED_VALUE = !process.env.DISABLE_PROMPT_CACHING\nexport { PROMPT_CACHING_ENABLED_VALUE as PROMPT_CACHING_ENABLED }\n\n// @see https://docs.anthropic.com/en/docs/about-claude/models#model-comparison-table\nexport const SONNET_COST_PER_MILLION_INPUT_TOKENS = 3\nexport const SONNET_COST_PER_MILLION_OUTPUT_TOKENS = 15\nexport const SONNET_COST_PER_MILLION_PROMPT_CACHE_WRITE_TOKENS = 3.75\nexport const SONNET_COST_PER_MILLION_PROMPT_CACHE_READ_TOKENS = 0.3\n\nexport const MAIN_QUERY_TEMPERATURE = 1 // to get more variation for binary feedback\n\n// \u2500\u2500 Retry logic \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const MAX_RETRIES = process.env.USER_TYPE === 'SWE_BENCH' ? 100 : 10\nconst BASE_DELAY_MS = 500\n\nexport interface RetryOptions {\n maxRetries?: number\n signal?: AbortSignal\n /** Callback for retry events. If provided, suppresses default debugLogger output. */\n onRetry?: (info: {\n attempt: number\n maxRetries: number\n error: Error\n delayMs: number\n }) => void\n}\n\nexport function getMetadata() {\n return {\n user_id: `${getOrCreateUserID()}_${SESSION_ID}`,\n }\n}\n\n/**\n * Calculate retry delay \u2014 delegates to shared utility with Retry-After header support\n */\nfunction getRetryDelay(\n attempt: number,\n retryAfterHeader?: string | null,\n): number {\n return sharedGetRetryDelay(attempt, retryAfterHeader)\n}\n\nexport function shouldRetry(error: APIError): boolean {\n // Check for overloaded errors first and only retry for SWE_BENCH\n if (error.message?.includes('\"type\":\"overloaded_error\"')) {\n return process.env.USER_TYPE === 'SWE_BENCH'\n }\n\n // Note this is not a standard header.\n const shouldRetryHeader = error.headers?.['x-should-retry']\n\n // If the server explicitly says whether or not to retry, obey.\n if (shouldRetryHeader === 'true') return true\n if (shouldRetryHeader === 'false') return false\n\n if (error instanceof APIConnectionError) {\n return true\n }\n\n if (!error.status) return false\n\n // Retry on request timeouts.\n if (error.status === 408) return true\n\n // Retry on lock timeouts.\n if (error.status === 409) return true\n\n // Retry on rate limits.\n if (error.status === 429) return true\n\n // Retry internal errors.\n if (error.status && error.status >= 500) return true\n\n return false\n}\n\nexport async function withRetry<T>(\n operation: (attempt: number) => Promise<T>,\n options: RetryOptions = {},\n): Promise<T> {\n const maxRetries = options.maxRetries ?? MAX_RETRIES\n let lastError: unknown\n\n for (let attempt = 1; attempt <= maxRetries + 1; attempt++) {\n try {\n return await operation(attempt)\n } catch (error) {\n lastError = error\n // Only retry if the error indicates we should\n if (\n attempt > maxRetries ||\n !(error instanceof APIError) ||\n !shouldRetry(error)\n ) {\n throw error\n }\n\n if (options.signal?.aborted) {\n throw new Error('Request cancelled by user')\n }\n\n // Get retry-after header if available\n const retryAfter = error.headers?.['retry-after'] ?? null\n const delayMs = getRetryDelay(attempt, retryAfter)\n\n // Update streaming state to show retry in UI\n setStreamingState({\n phase: 'retrying',\n retryCount: attempt,\n maxRetries: maxRetries,\n errorName: error.name,\n })\n\n debugLogger.flow('API_RETRY_ATTEMPT', {\n attempt,\n maxRetries,\n errorName: error.name,\n errorMessage: error.message,\n delayMs,\n })\n\n // Use callback if provided, otherwise fallback to debugLogger\n if (options.onRetry) {\n options.onRetry({\n attempt,\n maxRetries,\n error,\n delayMs,\n })\n } else {\n debugLogger.warn('API_RETRY', {\n errorName: error.name,\n errorMessage: error.message,\n delayMs,\n attempt,\n maxRetries,\n })\n }\n\n try {\n await abortableDelay(delayMs, options.signal)\n } catch (delayError) {\n // If aborted during delay, throw the error to stop retrying\n if (delayError.message === 'Request was aborted') {\n throw new Error('Request cancelled by user')\n }\n throw delayError\n }\n }\n }\n\n throw lastError\n}\n\n// \u2500\u2500 Cost utility functions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function getMaxTokensFromProfile(modelProfile: any): number {\n // Use ModelProfile maxTokens or reasonable default\n return modelProfile?.maxTokens || 8000\n}\n\nexport function getModelInputTokenCostUSD(model: string): number {\n // Find the model in the models object\n for (const providerModels of Object.values(models)) {\n const modelInfo = providerModels.find((m: any) => m.model === model)\n if (modelInfo) {\n return modelInfo.input_cost_per_token || 0\n }\n }\n // Default fallback cost for unknown models\n return 0.000003 // Default to Claude 3 Haiku cost\n}\n\nexport function getModelOutputTokenCostUSD(model: string): number {\n // Find the model in the models object\n for (const providerModels of Object.values(models)) {\n const modelInfo = providerModels.find((m: any) => m.model === model)\n if (modelInfo) {\n return modelInfo.output_cost_per_token || 0\n }\n }\n // Default fallback cost for unknown models\n return 0.000015 // Default to Claude 3 Haiku cost\n}\n\n// Re-export commonly used dependencies for other llm modules\nexport {\n addToTotalCost,\n recordTokenUsage,\n type TokenTrackingContext,\n logError,\n debugLogger,\n addRetryEventToTranscript,\n}\n"],
|
|
5
|
-
"mappings": "AAGA,SAAS,oBAAoB,gBAAgB;AAE7C,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AAEjC,OAAO,YAAY;AACnB,SAAS,yBAAyB;AAClC,SAAS,UAAU,kBAAkB;AACrC;AAAA,EACE;AAAA,EACA,iBAAiB;AAAA,OACZ;AACP
|
|
4
|
+
"sourcesContent": ["/**\n * Shared types, constants, and utility functions for LLM providers.\n */\nimport { randomUUID } from 'crypto'\nimport { APIConnectionError, APIError } from '@anthropic-ai/sdk'\n\nimport { addToTotalCost } from '@costTracker'\nimport { recordTokenUsage } from '@core/tokenStatsManager'\nimport type { TokenTrackingContext } from '@core/tokenStats'\nimport models from '@constants/models'\nimport { getOrCreateUserID } from '@utils/config'\nimport { logError, SESSION_ID } from '@utils/log'\nimport {\n abortableDelay,\n getRetryDelay as sharedGetRetryDelay,\n} from '@utils/async'\nimport { debug as debugLogger } from '@utils/debugLogger'\nimport { setStreamingState } from '@utils/streamingState'\nimport { addRetryEventToTranscript } from '@utils/agentTranscripts'\n\n// \u2500\u2500 Error message constants \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const API_ERROR_MESSAGE_PREFIX = 'API Error'\nexport const PROMPT_TOO_LONG_ERROR_MESSAGE = 'Prompt is too long'\nexport const CREDIT_BALANCE_TOO_LOW_ERROR_MESSAGE = 'Credit balance is too low'\nexport const INVALID_API_KEY_ERROR_MESSAGE =\n 'Invalid API key \u00B7 Please run /login'\nexport const NO_CONTENT_MESSAGE = '(no content)'\n\n// \u2500\u2500 Cost constants \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst PROMPT_CACHING_ENABLED_VALUE = !process.env.DISABLE_PROMPT_CACHING\nexport { PROMPT_CACHING_ENABLED_VALUE as PROMPT_CACHING_ENABLED }\n\n// @see https://docs.anthropic.com/en/docs/about-claude/models#model-comparison-table\nexport const SONNET_COST_PER_MILLION_INPUT_TOKENS = 3\nexport const SONNET_COST_PER_MILLION_OUTPUT_TOKENS = 15\nexport const SONNET_COST_PER_MILLION_PROMPT_CACHE_WRITE_TOKENS = 3.75\nexport const SONNET_COST_PER_MILLION_PROMPT_CACHE_READ_TOKENS = 0.3\n\nexport const MAIN_QUERY_TEMPERATURE = 1 // to get more variation for binary feedback\n\n// \u2500\u2500 Retry logic \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const MAX_RETRIES = process.env.USER_TYPE === 'SWE_BENCH' ? 100 : 5\nconst BASE_DELAY_MS = 500\n\nexport interface RetryOptions {\n maxRetries?: number\n signal?: AbortSignal\n /** Callback for retry events. If provided, suppresses default debugLogger output. */\n onRetry?: (info: {\n attempt: number\n maxRetries: number\n error: Error\n delayMs: number\n }) => void\n}\n\nexport function getMetadata() {\n return {\n user_id: `${getOrCreateUserID()}_${SESSION_ID}`,\n }\n}\n\n/**\n * Calculate retry delay \u2014 delegates to shared utility with Retry-After header support\n */\nfunction getRetryDelay(\n attempt: number,\n retryAfterHeader?: string | null,\n): number {\n return sharedGetRetryDelay(attempt, retryAfterHeader)\n}\n\nexport function shouldRetry(error: APIError): boolean {\n // Check for overloaded errors first and only retry for SWE_BENCH\n if (error.message?.includes('\"type\":\"overloaded_error\"')) {\n return process.env.USER_TYPE === 'SWE_BENCH'\n }\n\n // Note this is not a standard header.\n const shouldRetryHeader = error.headers?.['x-should-retry']\n\n // If the server explicitly says whether or not to retry, obey.\n if (shouldRetryHeader === 'true') return true\n if (shouldRetryHeader === 'false') return false\n\n if (error instanceof APIConnectionError) {\n return true\n }\n\n if (!error.status) return false\n\n // Retry on request timeouts.\n if (error.status === 408) return true\n\n // Retry on lock timeouts.\n if (error.status === 409) return true\n\n // Retry on rate limits.\n if (error.status === 429) return true\n\n // Retry internal errors.\n if (error.status && error.status >= 500) return true\n\n return false\n}\n\nexport async function withRetry<T>(\n operation: (attempt: number) => Promise<T>,\n options: RetryOptions = {},\n): Promise<T> {\n const maxRetries = options.maxRetries ?? MAX_RETRIES\n let lastError: unknown\n\n for (let attempt = 1; attempt <= maxRetries + 1; attempt++) {\n try {\n return await operation(attempt)\n } catch (error) {\n lastError = error\n // Only retry if the error indicates we should\n if (\n attempt > maxRetries ||\n !(error instanceof APIError) ||\n !shouldRetry(error)\n ) {\n throw error\n }\n\n if (options.signal?.aborted) {\n throw new Error('Request cancelled by user')\n }\n\n // Get retry-after header if available\n const retryAfter = error.headers?.['retry-after'] ?? null\n const delayMs = getRetryDelay(attempt, retryAfter)\n\n // Update streaming state to show retry in UI\n setStreamingState({\n phase: 'retrying',\n retryCount: attempt,\n maxRetries: maxRetries,\n errorName: error.name,\n retryDelayMs: delayMs,\n })\n\n debugLogger.flow('API_RETRY_ATTEMPT', {\n attempt,\n maxRetries,\n errorName: error.name,\n errorMessage: error.message,\n delayMs,\n })\n\n // Use callback if provided, otherwise fallback to debugLogger\n if (options.onRetry) {\n options.onRetry({\n attempt,\n maxRetries,\n error,\n delayMs,\n })\n } else {\n debugLogger.warn('API_RETRY', {\n errorName: error.name,\n errorMessage: error.message,\n delayMs,\n attempt,\n maxRetries,\n })\n }\n\n try {\n await abortableDelay(delayMs, options.signal)\n } catch (delayError) {\n // If aborted during delay, throw the error to stop retrying\n if (delayError.message === 'Request was aborted') {\n throw new Error('Request cancelled by user')\n }\n throw delayError\n }\n }\n }\n\n throw lastError\n}\n\n// \u2500\u2500 Cost utility functions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function getMaxTokensFromProfile(modelProfile: {\n maxTokens?: number\n}): number {\n // Use ModelProfile maxTokens or reasonable default\n return modelProfile?.maxTokens || 8000\n}\n\n/** Model cost field interface for type-safe lookups */\ninterface ModelCostInfo {\n model?: string\n input_cost_per_token?: number\n output_cost_per_token?: number\n cache_read_input_token_cost?: number\n cache_creation_input_token_cost?: number\n}\n\n/**\n * Look up a model's cost info from the models registry.\n * Returns the first match across all providers, or undefined if not found.\n */\nfunction findModelCostInfo(model: string): ModelCostInfo | undefined {\n for (const providerModels of Object.values(models)) {\n const modelInfo = providerModels.find(\n (m: { model?: string }) => m.model === model,\n )\n if (modelInfo) return modelInfo as ModelCostInfo\n }\n return undefined\n}\n\nexport function getModelInputTokenCostUSD(model: string): number {\n const info = findModelCostInfo(model)\n if (info?.input_cost_per_token) return info.input_cost_per_token\n debugLogger.warn('UNKNOWN_MODEL_COST', { model, direction: 'input' })\n return 0.000003 // Default to Claude Sonnet cost\n}\n\nexport function getModelOutputTokenCostUSD(model: string): number {\n const info = findModelCostInfo(model)\n if (info?.output_cost_per_token) return info.output_cost_per_token\n debugLogger.warn('UNKNOWN_MODEL_COST', { model, direction: 'output' })\n return 0.000015 // Default to Claude Sonnet cost\n}\n\n/**\n * Get per-token cache read cost. Falls back to 10% of input cost if not\n * explicitly defined in the models registry.\n */\nexport function getModelCacheReadCostUSD(model: string): number {\n const info = findModelCostInfo(model)\n if (info?.cache_read_input_token_cost) return info.cache_read_input_token_cost\n // Default: 10% of input cost (Anthropic standard cache pricing)\n return getModelInputTokenCostUSD(model) * 0.1\n}\n\n/**\n * Get per-token cache creation cost. Falls back to 125% of input cost if not\n * explicitly defined in the models registry.\n */\nexport function getModelCacheCreationCostUSD(model: string): number {\n const info = findModelCostInfo(model)\n if (info?.cache_creation_input_token_cost !== undefined)\n return info.cache_creation_input_token_cost\n // Default: 125% of input cost (Anthropic standard cache pricing)\n return getModelInputTokenCostUSD(model) * 1.25\n}\n\n/**\n * Unified cost calculation for all providers.\n * Uses per-token costs from the models registry.\n * Formula: tokens * cost_per_token (all costs are per-token in USD).\n */\nexport function calculateCostUSD(params: {\n model: string\n inputTokens: number\n outputTokens: number\n cacheReadTokens: number\n cacheCreationTokens: number\n}): number {\n return (\n params.inputTokens * getModelInputTokenCostUSD(params.model) +\n params.outputTokens * getModelOutputTokenCostUSD(params.model) +\n params.cacheReadTokens * getModelCacheReadCostUSD(params.model) +\n params.cacheCreationTokens * getModelCacheCreationCostUSD(params.model)\n )\n}\n\n// \u2500\u2500 Shared error handling \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Convert an API error into an AssistantMessage for UI display.\n * Shared between Anthropic and OpenAI providers to avoid duplication.\n */\n// Inline helper to avoid circular dependency with @utils/messages\nfunction createAssistantAPIErrorMessage(\n content: string,\n): import('@query').AssistantMessage {\n return {\n type: 'assistant',\n costUSD: 0,\n durationMs: 0,\n uuid: randomUUID(),\n isApiErrorMessage: true,\n message: {\n id: randomUUID(),\n model: '<synthetic>',\n role: 'assistant' as const,\n stop_reason: 'stop_sequence',\n stop_sequence: '',\n type: 'message',\n usage: {\n input_tokens: 0,\n output_tokens: 0,\n cache_creation_input_tokens: 0,\n cache_read_input_tokens: 0,\n },\n content: [\n {\n type: 'text' as const,\n text: content === '' ? NO_CONTENT_MESSAGE : content,\n citations: [],\n },\n ],\n },\n }\n}\n\nexport function getAssistantMessageFromError(\n error: unknown,\n providerTag: string = 'LLM',\n): import('@query').AssistantMessage {\n if (error instanceof Error && error.message.includes('prompt is too long')) {\n return createAssistantAPIErrorMessage(PROMPT_TOO_LONG_ERROR_MESSAGE)\n }\n if (\n error instanceof Error &&\n error.message.includes('Your credit balance is too low')\n ) {\n return createAssistantAPIErrorMessage(CREDIT_BALANCE_TOO_LOW_ERROR_MESSAGE)\n }\n if (\n error instanceof Error &&\n error.message.toLowerCase().includes('x-api-key')\n ) {\n return createAssistantAPIErrorMessage(INVALID_API_KEY_ERROR_MESSAGE)\n }\n if (error instanceof Error) {\n if (process.env.NODE_ENV === 'development') {\n debugLogger.error(`${providerTag}_API_ERROR`, {\n message: error.message,\n stack: error.stack,\n })\n }\n return createAssistantAPIErrorMessage(\n `${API_ERROR_MESSAGE_PREFIX}: ${error.message}`,\n )\n }\n return createAssistantAPIErrorMessage(API_ERROR_MESSAGE_PREFIX)\n}\n\n// Re-export commonly used dependencies for other llm modules\nexport {\n addToTotalCost,\n recordTokenUsage,\n type TokenTrackingContext,\n logError,\n debugLogger,\n addRetryEventToTranscript,\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
getCurrentProjectConfig,
|
|
5
5
|
saveCurrentProjectConfig,
|
|
6
6
|
getGlobalConfig,
|
|
7
|
+
getMutableGlobalConfig,
|
|
7
8
|
saveGlobalConfig,
|
|
8
9
|
getMcprcConfig,
|
|
9
10
|
addMcprcServerForTesting,
|
|
@@ -35,15 +36,50 @@ const SENSITIVE_ENV_PREFIXES = [
|
|
|
35
36
|
"ANTHROPIC_",
|
|
36
37
|
"OPENAI_",
|
|
37
38
|
"AWS_SECRET",
|
|
39
|
+
"AWS_ACCESS_KEY",
|
|
40
|
+
"AWS_SESSION_TOKEN",
|
|
41
|
+
"AZURE_",
|
|
42
|
+
"GOOGLE_API_KEY",
|
|
43
|
+
"GOOGLE_APPLICATION_CREDENTIALS",
|
|
44
|
+
"HF_TOKEN",
|
|
45
|
+
"REPLICATE_API_TOKEN",
|
|
46
|
+
"HUGGINGFACE_",
|
|
47
|
+
"COHERE_",
|
|
48
|
+
"MISTRAL_",
|
|
49
|
+
"GROQ_",
|
|
50
|
+
"TOGETHER_",
|
|
51
|
+
"FIREWORKS_",
|
|
52
|
+
"PERPLEXITY_",
|
|
53
|
+
"DEEPSEEK_",
|
|
38
54
|
"GITHUB_TOKEN",
|
|
39
55
|
"GH_TOKEN",
|
|
40
56
|
"MINTO_API"
|
|
41
57
|
];
|
|
58
|
+
const SENSITIVE_ENV_SUFFIXES = ["_SECRET", "_PASSWORD", "_TOKEN", "_KEY"];
|
|
59
|
+
const SAFE_SYSTEM_ENV_VARS = /* @__PURE__ */ new Set([
|
|
60
|
+
"HOME",
|
|
61
|
+
"PATH",
|
|
62
|
+
"TERM",
|
|
63
|
+
"SHELL",
|
|
64
|
+
"USER",
|
|
65
|
+
"LANG",
|
|
66
|
+
"EDITOR",
|
|
67
|
+
"DISPLAY",
|
|
68
|
+
"SSH_AUTH_SOCK",
|
|
69
|
+
"GPG_TTY"
|
|
70
|
+
]);
|
|
71
|
+
function isSafeSystemVar(key) {
|
|
72
|
+
return SAFE_SYSTEM_ENV_VARS.has(key) || key.startsWith("XDG_");
|
|
73
|
+
}
|
|
42
74
|
function filterSensitiveEnv(env) {
|
|
43
75
|
return Object.fromEntries(
|
|
44
|
-
Object.entries(env).filter(
|
|
45
|
-
|
|
46
|
-
|
|
76
|
+
Object.entries(env).filter(([k]) => {
|
|
77
|
+
if (isSafeSystemVar(k)) return true;
|
|
78
|
+
if (SENSITIVE_ENV_PREFIXES.some((p) => k.startsWith(p) || k === p))
|
|
79
|
+
return false;
|
|
80
|
+
if (SENSITIVE_ENV_SUFFIXES.some((s) => k.endsWith(s))) return false;
|
|
81
|
+
return true;
|
|
82
|
+
}).filter((e) => e[1] !== void 0)
|
|
47
83
|
);
|
|
48
84
|
}
|
|
49
85
|
const mcpCircuitBreakers = new CircuitBreakerRegistry({
|
|
@@ -108,7 +144,7 @@ function addMcpServer(name, server, scope = "project") {
|
|
|
108
144
|
}
|
|
109
145
|
}
|
|
110
146
|
} else if (scope === "global") {
|
|
111
|
-
const config =
|
|
147
|
+
const config = getMutableGlobalConfig();
|
|
112
148
|
if (!config.mcpServers) {
|
|
113
149
|
config.mcpServers = {};
|
|
114
150
|
}
|
|
@@ -241,6 +277,12 @@ async function connectToServer(name, serverRef) {
|
|
|
241
277
|
});
|
|
242
278
|
await Promise.race([connectPromise, timeoutPromise]);
|
|
243
279
|
if (serverRef.type === "stdio") {
|
|
280
|
+
const childProc = transport._process;
|
|
281
|
+
if (childProc?.pid) {
|
|
282
|
+
const { registerChildPid, unregisterChildPid } = await import("../utils/exit.js");
|
|
283
|
+
registerChildPid(childProc.pid);
|
|
284
|
+
childProc.on?.("exit", () => unregisterChildPid(childProc.pid));
|
|
285
|
+
}
|
|
244
286
|
;
|
|
245
287
|
transport.stderr?.on("data", (data) => {
|
|
246
288
|
const errorText = data.toString().trim();
|
|
@@ -491,6 +533,33 @@ function isLazyMCPEnabled() {
|
|
|
491
533
|
return !!(process.env.MINTO_ENABLE_TOOL_SEARCH || process.env.ENABLE_TOOL_SEARCH);
|
|
492
534
|
}
|
|
493
535
|
const lazySchemaCache = /* @__PURE__ */ new Map();
|
|
536
|
+
const deferredTools = /* @__PURE__ */ new Map();
|
|
537
|
+
const activatedToolNames = /* @__PURE__ */ new Set();
|
|
538
|
+
function getDeferredMCPTools() {
|
|
539
|
+
return deferredTools;
|
|
540
|
+
}
|
|
541
|
+
function activateMCPTool(toolFullName) {
|
|
542
|
+
if (activatedToolNames.has(toolFullName)) {
|
|
543
|
+
return false;
|
|
544
|
+
}
|
|
545
|
+
activatedToolNames.add(toolFullName);
|
|
546
|
+
deferredTools.delete(toolFullName);
|
|
547
|
+
try {
|
|
548
|
+
import("../tools.js").then(({ invalidateToolsCache }) => {
|
|
549
|
+
invalidateToolsCache();
|
|
550
|
+
}).catch(() => {
|
|
551
|
+
});
|
|
552
|
+
} catch {
|
|
553
|
+
}
|
|
554
|
+
return true;
|
|
555
|
+
}
|
|
556
|
+
function isMCPToolActivated(toolFullName) {
|
|
557
|
+
return activatedToolNames.has(toolFullName);
|
|
558
|
+
}
|
|
559
|
+
function clearDeferredState() {
|
|
560
|
+
deferredTools.clear();
|
|
561
|
+
activatedToolNames.clear();
|
|
562
|
+
}
|
|
494
563
|
async function getLazyInputSchema(client, toolName, fullName) {
|
|
495
564
|
if (lazySchemaCache.has(fullName)) {
|
|
496
565
|
return lazySchemaCache.get(fullName);
|
|
@@ -792,6 +861,7 @@ async function refreshMCPConnections() {
|
|
|
792
861
|
getMCPCommands.cache.clear();
|
|
793
862
|
}
|
|
794
863
|
mcpCircuitBreakers.resetAll();
|
|
864
|
+
clearDeferredState();
|
|
795
865
|
try {
|
|
796
866
|
const { invalidateToolsCache } = await import("../tools.js");
|
|
797
867
|
invalidateToolsCache();
|
|
@@ -806,6 +876,7 @@ async function refreshMCPConnections() {
|
|
|
806
876
|
}
|
|
807
877
|
}
|
|
808
878
|
async function shutdownMCPClients() {
|
|
879
|
+
stopHealthCheck();
|
|
809
880
|
if (connectedClients.length === 0) return;
|
|
810
881
|
const oldClients = connectedClients;
|
|
811
882
|
connectedClients = [];
|
|
@@ -892,12 +963,16 @@ async function readMCPResource(uri, serverName) {
|
|
|
892
963
|
return null;
|
|
893
964
|
}
|
|
894
965
|
export {
|
|
966
|
+
activateMCPTool,
|
|
895
967
|
addMcpServer,
|
|
968
|
+
clearDeferredState,
|
|
896
969
|
configureMcpPool,
|
|
897
970
|
ensureConfigScope,
|
|
971
|
+
filterSensitiveEnv,
|
|
898
972
|
getAllCircuitBreakerStats,
|
|
899
973
|
getClients,
|
|
900
974
|
getConnectionHealth,
|
|
975
|
+
getDeferredMCPTools,
|
|
901
976
|
getMCPCommands,
|
|
902
977
|
getMCPTools,
|
|
903
978
|
getMcpPoolConfig,
|
|
@@ -906,6 +981,7 @@ export {
|
|
|
906
981
|
getPoolStats,
|
|
907
982
|
getServerCircuitBreaker,
|
|
908
983
|
getServerHealth,
|
|
984
|
+
isMCPToolActivated,
|
|
909
985
|
listMCPResources,
|
|
910
986
|
listMCPServers,
|
|
911
987
|
parseEnvVars,
|