@within-7/minto 0.4.1 → 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
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/services/mintoAuth.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Minto Login Service\n *\n * Single source of truth for the login domain:\n * - Login API call + Zod validation\n * - LiteLLM model discovery + deduplication\n * - Model auto-configuration via ModelManager\n * - Smart model pointer assignment\n *\n * Security: No account info stored locally. Only LiteLLM API key is persisted\n * via the credential store. Login state is inferred from credential presence.\n */\n\nimport { z } from 'zod'\nimport { MACRO } from '@constants/macros'\nimport { setApiKey, getApiKey, deleteApiKey } from '@utils/credentials/index'\nimport { getModelManager, reloadModelManager } from '@utils/model'\nimport type { ModelPointerType } from '@utils/configSchema'\nimport { t } from '@i18n'\nimport * as readline from 'readline'\n\n// \u2500\u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 MintoLoginResponseSchema = z.object({\n user: z.string(),\n profile: z.object({\n userId: z.string(),\n staff: z.string(),\n email: z.string(),\n permission: z.array(z.string()),\n status: z.string(),\n }),\n model: z.object({\n base_url: z.string(),\n api_key: z.string(),\n qwen_asr_api_key: z.string().optional(),\n }),\n})\n\ntype MintoLoginResponse = z.infer<typeof MintoLoginResponseSchema>\n\nconst LiteLLMModelInfoSchema = z.object({\n model_name: z.string(),\n litellm_params: z.record(z.unknown()).optional().default({}),\n model_info: z\n .object({\n id: z.string().optional(),\n key: z.string().optional(),\n max_tokens: z.number().optional(),\n max_input_tokens: z.number().optional(),\n max_output_tokens: z.number().optional(),\n input_cost_per_token: z.number().optional(),\n output_cost_per_token: z.number().optional(),\n litellm_provider: z.string().optional(),\n mode: z.string().optional(),\n })\n .optional()\n .default({}),\n})\n\ntype LiteLLMModelInfo = z.infer<typeof LiteLLMModelInfoSchema>\n\nconst LiteLLMModelListResponseSchema = z.object({\n data: z.array(LiteLLMModelInfoSchema),\n})\n\nexport interface LoginResult {\n user: string\n modelsConfigured: number\n modelNames: string[]\n aiterVoiceConfigured?: boolean\n}\n\n// \u2500\u2500\u2500 CREDENTIAL_KEY \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 LITELLM_CREDENTIAL_KEY = 'minto-litellm'\n\n// \u2500\u2500\u2500 Core API 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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * POST login request to Minto auth API.\n * Returns parsed + validated response.\n */\nexport async function mintoLogin(\n user: string,\n password: string,\n): Promise<MintoLoginResponse> {\n const url = MACRO.LOGIN_API_URL\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ user, password }),\n })\n\n if (res.status === 401 || res.status === 403) {\n throw new Error(t('commands.login.invalidCredentials'))\n }\n if (!res.ok) {\n throw new Error(\n `${t('commands.login.failed')}: HTTP ${res.status} ${res.statusText}`,\n )\n }\n\n const json = await res.json()\n return MintoLoginResponseSchema.parse(json)\n}\n\n/**\n * Fetch available models from LiteLLM /model/info endpoint.\n */\nexport async function fetchLiteLLMModels(\n baseUrl: string,\n apiKey: string,\n): Promise<LiteLLMModelInfo[]> {\n // Normalize base URL \u2014 strip trailing slash\n const base = baseUrl.replace(/\\/+$/, '')\n const url = `${base}/model/info`\n\n const res = await fetch(url, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n })\n\n if (!res.ok) {\n throw new Error(\n `${t('commands.login.fetchModelsFailed')}: HTTP ${res.status}`,\n )\n }\n\n const json = await res.json()\n const parsed = LiteLLMModelListResponseSchema.parse(json)\n return parsed.data\n}\n\n/**\n * Deduplicate LiteLLM models by base model name.\n * Strips provider/ prefix (e.g., \"openai/gpt-4o\" \u2192 \"gpt-4o\").\n * Keeps the first occurrence per base name.\n */\nexport function deduplicateLiteLLMModels(\n models: LiteLLMModelInfo[],\n): LiteLLMModelInfo[] {\n const seen = new Map<string, LiteLLMModelInfo>()\n\n for (const model of models) {\n const baseName = getBaseModelName(model.model_name)\n if (!seen.has(baseName)) {\n seen.set(baseName, model)\n }\n }\n\n return [...seen.values()]\n}\n\n/**\n * Strip provider prefix from model name.\n * \"openai/gpt-4o\" \u2192 \"gpt-4o\", \"claude-sonnet-4\" \u2192 \"claude-sonnet-4\"\n */\nfunction getBaseModelName(modelName: string): string {\n const slashIdx = modelName.indexOf('/')\n return slashIdx >= 0 ? modelName.slice(slashIdx + 1) : modelName\n}\n\n/**\n * Sort models by total cost (input + output cost per token), cheapest first.\n * Models without pricing info are treated as free (cost = 0).\n */\nexport function sortModelsByCost(\n models: LiteLLMModelInfo[],\n): LiteLLMModelInfo[] {\n return [...models].sort((a, b) => {\n const costA =\n (a.model_info?.input_cost_per_token ?? 0) +\n (a.model_info?.output_cost_per_token ?? 0)\n const costB =\n (b.model_info?.input_cost_per_token ?? 0) +\n (b.model_info?.output_cost_per_token ?? 0)\n return costA - costB\n })\n}\n\n/**\n * Heuristic model pointer assignment.\n * Matches model names to roles based on known patterns.\n * Main model prioritizes cost-effective models (glm-5, qwen-3.5-plus).\n */\nexport function assignModelPointers(\n modelNames: string[],\n): Record<ModelPointerType, string> {\n const find = (...patterns: string[]): string | null => {\n for (const pattern of patterns) {\n const match = modelNames.find(n =>\n n.toLowerCase().includes(pattern.toLowerCase()),\n )\n if (match) return match\n }\n return null\n }\n\n const fallback = modelNames[0] ?? ''\n\n const main =\n find('glm-5', 'qwen-3.5-plus', 'claude-sonnet', 'gpt-4o') ?? fallback\n const task = find('claude-sonnet', 'gpt-4o-mini', 'glm-5') ?? main\n const reasoning = find('o3', 'o1', 'deepseek-r1') ?? main\n const quick = find('gpt-4o-mini', 'claude-haiku', 'qwen-3.5-plus') ?? task\n const compact = quick\n\n return { main, task, reasoning, quick, compact }\n}\n\n// \u2500\u2500\u2500 AiTer Voice Input Configuration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * Configure AiTer voice input when running in AiTer environment.\n * Uses `aiter settings set voiceInput` CLI command.\n */\nasync function configureAiterVoiceInput(\n qwenAsrApiKey: string,\n): Promise<boolean> {\n if (process.env.AITER_TERMINAL !== '1') return false\n\n const { execFile } = await import('child_process')\n const { promisify } = await import('util')\n const execFileAsync = promisify(execFile)\n\n const voiceInputConfig = JSON.stringify({\n enabled: true,\n provider: 'qwen-asr',\n qwenApiKey: qwenAsrApiKey,\n qwenRegion: 'cn',\n })\n\n try {\n await execFileAsync('aiter', [\n 'settings',\n 'set',\n 'voiceInput',\n voiceInputConfig,\n ])\n return true\n } catch {\n return false\n }\n}\n\n// \u2500\u2500\u2500 Full Login Flow \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * Complete login flow:\n * 1. Authenticate via login API\n * 2. Verify account active\n * 3. Store API key securely\n * 4. Clear previously login-configured models (by baseURL match)\n * 5. Fetch + deduplicate LiteLLM models\n * 6. Add model profiles via ModelManager\n * 7. Assign model pointers\n */\nexport async function performLogin(\n user: string,\n password: string,\n onProgress?: (phase: string) => void,\n): Promise<LoginResult> {\n // Phase 1: Login\n onProgress?.(t('commands.login.loggingIn'))\n const loginResponse = await mintoLogin(user, password)\n\n // Phase 2: Check account active\n if (loginResponse.profile.status !== 'active') {\n throw new Error(t('commands.login.inactive'))\n }\n\n // Phase 3: Store API key securely (not account info)\n await setApiKey(LITELLM_CREDENTIAL_KEY, loginResponse.model.api_key)\n\n // Phase 4: Clear previous login-configured models (baseURL match)\n onProgress?.(t('commands.login.configuringModels'))\n const mm = getModelManager()\n const existingModels = mm.getAllConfiguredModels()\n const loginBaseURL = loginResponse.model.base_url.replace(/\\/+$/, '')\n\n for (const model of existingModels) {\n if (model.baseURL && model.baseURL.replace(/\\/+$/, '') === loginBaseURL) {\n mm.removeModel(model.modelName)\n }\n }\n\n // Phase 5: Fetch models from LiteLLM\n onProgress?.(t('commands.login.fetchingModels'))\n let litellmModels: LiteLLMModelInfo[]\n try {\n litellmModels = await fetchLiteLLMModels(\n loginResponse.model.base_url,\n loginResponse.model.api_key,\n )\n } catch (err) {\n // Partial success: logged in but model fetch failed\n return {\n user: loginResponse.user,\n modelsConfigured: 0,\n modelNames: [],\n }\n }\n\n // Phase 6: Deduplicate, sort by cost (cheapest first), and add models\n const deduplicated = sortModelsByCost(deduplicateLiteLLMModels(litellmModels))\n const configuredNames: string[] = []\n\n for (const model of deduplicated) {\n const baseName = getBaseModelName(model.model_name)\n const maxOutputTokens = model.model_info?.max_output_tokens ?? 4096\n const maxInputTokens = model.model_info?.max_input_tokens ?? 128000\n\n try {\n await mm.addModel({\n name: baseName,\n provider: 'custom-openai',\n modelName: baseName,\n baseURL: loginBaseURL,\n apiKey: `encrypted:${LITELLM_CREDENTIAL_KEY}`,\n maxTokens: maxOutputTokens,\n contextLength: maxInputTokens,\n })\n configuredNames.push(baseName)\n } catch {\n // Skip duplicate \u2014 defensive, shouldn't happen after cleanup\n }\n }\n\n // Phase 7: Assign model pointers\n if (configuredNames.length > 0) {\n const pointers = assignModelPointers(configuredNames)\n for (const [pointer, modelName] of Object.entries(pointers)) {\n try {\n mm.setPointer(pointer as ModelPointerType, modelName)\n } catch {\n // Skip if model not found (shouldn't happen)\n }\n }\n }\n\n reloadModelManager()\n\n // Phase 8: Configure AiTer voice input if in AiTer environment\n let aiterVoiceConfigured = false\n if (loginResponse.model.qwen_asr_api_key) {\n aiterVoiceConfigured = await configureAiterVoiceInput(\n loginResponse.model.qwen_asr_api_key,\n )\n }\n\n return {\n user: loginResponse.user,\n modelsConfigured: configuredNames.length,\n modelNames: configuredNames,\n aiterVoiceConfigured,\n }\n}\n\n// \u2500\u2500\u2500 Login Status Check \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * Check if user is logged in (has stored LiteLLM credential).\n */\nexport async function isLoggedIn(): Promise<boolean> {\n const key = await getApiKey(LITELLM_CREDENTIAL_KEY)\n return key !== null\n}\n\n/**\n * Logout: remove stored credential.\n */\nexport async function logout(): Promise<void> {\n await deleteApiKey(LITELLM_CREDENTIAL_KEY)\n}\n\n// \u2500\u2500\u2500 CLI Handler \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 * Handle `minto login` CLI command.\n * Uses readline for interactive input when user/password not provided.\n */\nexport async function handleLoginCLI(\n user?: string,\n password?: string,\n): Promise<void> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n })\n\n const ask = (prompt: string): Promise<string> =>\n new Promise(resolve => rl.question(prompt, resolve))\n\n const askPassword = (prompt: string): Promise<string> =>\n new Promise(resolve => {\n // Mask password input\n process.stdout.write(prompt)\n const stdin = process.stdin\n const wasRaw = stdin.isRaw\n if (stdin.setRawMode) stdin.setRawMode(true)\n stdin.resume()\n\n let pwd = ''\n const onData = (ch: Buffer) => {\n const c = ch.toString('utf8')\n if (c === '\\n' || c === '\\r') {\n if (stdin.setRawMode) stdin.setRawMode(wasRaw ?? false)\n stdin.removeListener('data', onData)\n process.stdout.write('\\n')\n resolve(pwd)\n } else if (c === '\\u0003') {\n // Ctrl-C\n process.exit(1)\n } else if (c === '\\u007f' || c === '\\b') {\n // Backspace\n if (pwd.length > 0) {\n pwd = pwd.slice(0, -1)\n process.stdout.write('\\b \\b')\n }\n } else {\n pwd += c\n process.stdout.write('*')\n }\n }\n stdin.on('data', onData)\n })\n\n try {\n if (!user) {\n user = await ask('Username: ')\n }\n if (!password) {\n password = await askPassword('Password: ')\n }\n\n rl.close()\n\n console.log(`\\n${t('commands.login.loggingIn')}...`)\n\n const result = await performLogin(user, password, phase => {\n console.log(` ${phase}...`)\n })\n\n console.log(`\\n\u2713 ${t('commands.login.success')}`)\n console.log(` User: ${result.user}`)\n console.log(\n ` ${t('commands.login.modelsConfigured')}: ${result.modelsConfigured}`,\n )\n if (result.modelNames.length > 0) {\n console.log(` Models: ${result.modelNames.join(', ')}`)\n }\n if (result.aiterVoiceConfigured) {\n console.log(` AiTer voice input: configured`)\n }\n } catch (err) {\n rl.close()\n console.error(\n `\\n\u2717 ${t('commands.login.failed')}: ${err instanceof Error ? err.message : String(err)}`,\n )\n process.exit(1)\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/services/oauth.js
CHANGED
|
@@ -6,7 +6,7 @@ import { openBrowser } from "../utils/browser.js";
|
|
|
6
6
|
import { logError } from "../utils/log.js";
|
|
7
7
|
import { resetAnthropicClient } from "./claude.js";
|
|
8
8
|
import {
|
|
9
|
-
|
|
9
|
+
getMutableGlobalConfig,
|
|
10
10
|
saveGlobalConfig,
|
|
11
11
|
normalizeApiKeyForConfig
|
|
12
12
|
} from "../utils/config.js";
|
|
@@ -78,7 +78,7 @@ class OAuthService {
|
|
|
78
78
|
emailAddress: account.email_address,
|
|
79
79
|
organizationUuid: organization?.uuid
|
|
80
80
|
};
|
|
81
|
-
const config =
|
|
81
|
+
const config = getMutableGlobalConfig();
|
|
82
82
|
config.oauthAccount = accountInfo;
|
|
83
83
|
saveGlobalConfig(config);
|
|
84
84
|
}
|
|
@@ -222,7 +222,7 @@ async function createAndStoreApiKey(accessToken) {
|
|
|
222
222
|
}
|
|
223
223
|
if (createApiKeyResp.ok && apiKeyData && apiKeyData.raw_key) {
|
|
224
224
|
const apiKey = apiKeyData.raw_key;
|
|
225
|
-
const config =
|
|
225
|
+
const config = getMutableGlobalConfig();
|
|
226
226
|
if (!config.customApiKeyResponses) {
|
|
227
227
|
config.customApiKeyResponses = { approved: [], rejected: [] };
|
|
228
228
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/services/oauth.ts"],
|
|
4
|
-
"sourcesContent": ["import * as crypto from 'crypto'\nimport * as http from 'http'\nimport { IncomingMessage, ServerResponse } from 'http'\nimport * as url from 'url'\n\nimport { OAUTH_CONFIG } from '@constants/oauth'\nimport { openBrowser } from '@utils/browser'\nimport { logError } from '@utils/log'\nimport { resetAnthropicClient } from './claude'\nimport {\n AccountInfo,\n
|
|
5
|
-
"mappings": "AAAA,YAAY,YAAY;AACxB,YAAY,UAAU;AAEtB,YAAY,SAAS;AAErB,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAC5B,SAAS,gBAAgB;AACzB,SAAS,4BAA4B;AACrC;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,gBAAgB,QAAwB;AAC/C,SAAO,OACJ,SAAS,QAAQ,EACjB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,MAAM,EAAE;AACrB;AAEA,SAAS,uBAA+B;AACtC,SAAO,gBAAgB,OAAO,YAAY,EAAE,CAAC;AAC/C;AAEA,eAAe,sBAAsB,UAAmC;AACtE,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,OAAO,QAAQ,OAAO,QAAQ;AACpC,QAAM,SAAS,MAAM,OAAO,OAAO,OAAO,WAAW,IAAI;AACzD,SAAO,gBAAgB,OAAO,KAAK,MAAM,CAAC;AAC5C;AAkBO,MAAM,aAAa;AAAA,EAChB,SAA6B;AAAA,EAC7B;AAAA,EACA,gBAA+B;AAAA,EAC/B,qBAMG;AAAA,EAEX,cAAc;AACZ,SAAK,eAAe,qBAAqB;AAAA,EAC3C;AAAA,EAEQ,iBACN,eACA,OACwC;AACxC,aAAS,QAAQ,UAA2B;AAC1C,YAAM,UAAU,IAAI,IAAI,aAAa,aAAa;AAClD,cAAQ,aAAa,OAAO,aAAa,aAAa,SAAS;AAC/D,cAAQ,aAAa,OAAO,iBAAiB,MAAM;AACnD,cAAQ,aAAa;AAAA,QACnB;AAAA,QACA,WACI,aAAa,sBACb,oBAAoB,aAAa,aAAa;AAAA,MACpD;AACA,cAAQ,aAAa,OAAO,SAAS,aAAa,OAAO,KAAK,GAAG,CAAC;AAClE,cAAQ,aAAa,OAAO,kBAAkB,aAAa;AAC3D,cAAQ,aAAa,OAAO,yBAAyB,MAAM;AAC3D,cAAQ,aAAa,OAAO,SAAS,KAAK;AAC1C,aAAO,QAAQ,SAAS;AAAA,IAC1B;AAEA,WAAO;AAAA,MACL,SAAS,QAAQ,KAAK;AAAA,MACtB,WAAW,QAAQ,IAAI;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,MAAM,eACJ,gBACsB;AACtB,UAAM,gBAAgB,MAAM,sBAAsB,KAAK,YAAY;AACnE,UAAM,QAAQ,gBAAgB,OAAO,YAAY,EAAE,CAAC;AACpD,SAAK,gBAAgB;AACrB,UAAM,EAAE,SAAS,UAAU,IAAI,KAAK,iBAAiB,eAAe,KAAK;AAEzE,UAAM,UAAU,YAAY;AAC1B,YAAM,eAAe,SAAS;AAC9B,YAAM,YAAY,OAAO;AAAA,IAC3B;AAEA,UAAM,EAAE,mBAAmB,kBAAkB,IAAI,MAAM,IAAI,QAGxD,CAAC,SAAS,WAAW;AACtB,WAAK,qBAAqB,EAAE,SAAS,OAAO;AAC5C,WAAK,iBAAiB,OAAO,OAAO;AAAA,IACtC,CAAC;AAGD,UAAM;AAAA,MACJ,cAAc;AAAA,MACd;AAAA,MACA;AAAA,IACF,IAAI,MAAM,KAAK;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,QAAI,SAAS;AACX,YAAM,cAA2B;AAAA,QAC/B,aAAa,QAAQ;AAAA,QACrB,cAAc,QAAQ;AAAA,QACtB,kBAAkB,cAAc;AAAA,MAClC;AACA,YAAM,SAAS,
|
|
4
|
+
"sourcesContent": ["import * as crypto from 'crypto'\nimport * as http from 'http'\nimport { IncomingMessage, ServerResponse } from 'http'\nimport * as url from 'url'\n\nimport { OAUTH_CONFIG } from '@constants/oauth'\nimport { openBrowser } from '@utils/browser'\nimport { logError } from '@utils/log'\nimport { resetAnthropicClient } from './claude'\nimport {\n AccountInfo,\n getMutableGlobalConfig,\n saveGlobalConfig,\n normalizeApiKeyForConfig,\n} from '@utils/config'\n\n// Base64URL encoding function (RFC 4648)\nfunction base64URLEncode(buffer: Buffer): string {\n return buffer\n .toString('base64')\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=/g, '')\n}\n\nfunction generateCodeVerifier(): string {\n return base64URLEncode(crypto.randomBytes(32))\n}\n\nasync function generateCodeChallenge(verifier: string): Promise<string> {\n const encoder = new TextEncoder()\n const data = encoder.encode(verifier)\n const digest = await crypto.subtle.digest('SHA-256', data)\n return base64URLEncode(Buffer.from(digest))\n}\n\ntype OAuthTokenExchangeResponse = {\n access_token: string\n account?: {\n uuid: string\n email_address: string\n }\n organization?: {\n uuid: string\n name: string\n }\n}\n\nexport type OAuthResult = {\n accessToken: string\n}\n\nexport class OAuthService {\n private server: http.Server | null = null\n private codeVerifier: string\n private expectedState: string | null = null\n private pendingCodePromise: {\n resolve: (result: {\n authorizationCode: string\n useManualRedirect: boolean\n }) => void\n reject: (err: Error) => void\n } | null = null\n\n constructor() {\n this.codeVerifier = generateCodeVerifier()\n }\n\n private generateAuthUrls(\n codeChallenge: string,\n state: string,\n ): { autoUrl: string; manualUrl: string } {\n function makeUrl(isManual: boolean): string {\n const authUrl = new URL(OAUTH_CONFIG.AUTHORIZE_URL)\n authUrl.searchParams.append('client_id', OAUTH_CONFIG.CLIENT_ID)\n authUrl.searchParams.append('response_type', 'code')\n authUrl.searchParams.append(\n 'redirect_uri',\n isManual\n ? OAUTH_CONFIG.MANUAL_REDIRECT_URL\n : `http://localhost:${OAUTH_CONFIG.REDIRECT_PORT}/callback`,\n )\n authUrl.searchParams.append('scope', OAUTH_CONFIG.SCOPES.join(' '))\n authUrl.searchParams.append('code_challenge', codeChallenge)\n authUrl.searchParams.append('code_challenge_method', 'S256')\n authUrl.searchParams.append('state', state)\n return authUrl.toString()\n }\n\n return {\n autoUrl: makeUrl(false),\n manualUrl: makeUrl(true),\n }\n }\n\n async startOAuthFlow(\n authURLHandler: (url: string) => Promise<void>,\n ): Promise<OAuthResult> {\n const codeChallenge = await generateCodeChallenge(this.codeVerifier)\n const state = base64URLEncode(crypto.randomBytes(32))\n this.expectedState = state\n const { autoUrl, manualUrl } = this.generateAuthUrls(codeChallenge, state)\n\n const onReady = async () => {\n await authURLHandler(manualUrl)\n await openBrowser(autoUrl)\n }\n\n const { authorizationCode, useManualRedirect } = await new Promise<{\n authorizationCode: string\n useManualRedirect: boolean\n }>((resolve, reject) => {\n this.pendingCodePromise = { resolve, reject }\n this.startLocalServer(state, onReady)\n })\n\n // Exchange code for tokens\n const {\n access_token: accessToken,\n account,\n organization,\n } = await this.exchangeCodeForTokens(\n authorizationCode,\n state,\n useManualRedirect,\n )\n\n // Store account info\n if (account) {\n const accountInfo: AccountInfo = {\n accountUuid: account.uuid,\n emailAddress: account.email_address,\n organizationUuid: organization?.uuid,\n }\n const config = getMutableGlobalConfig()\n config.oauthAccount = accountInfo\n saveGlobalConfig(config)\n }\n\n return { accessToken }\n }\n\n private startLocalServer(state: string, onReady?: () => void): void {\n if (this.server) {\n this.closeServer()\n }\n this.server = http.createServer(\n (req: IncomingMessage, res: ServerResponse) => {\n const parsedUrl = url.parse(req.url || '', true)\n\n if (parsedUrl.pathname === '/callback') {\n const authorizationCode = parsedUrl.query.code as string\n const returnedState = parsedUrl.query.state as string\n\n if (!authorizationCode) {\n res.writeHead(400)\n res.end('Authorization code not found')\n if (this.pendingCodePromise) {\n this.pendingCodePromise.reject(\n new Error('No authorization code received'),\n )\n }\n return\n }\n\n if (returnedState !== state) {\n res.writeHead(400)\n res.end('Invalid state parameter')\n if (this.pendingCodePromise) {\n this.pendingCodePromise.reject(\n new Error('Invalid state parameter'), // Possible CSRF attack\n )\n }\n return\n }\n\n res.writeHead(302, {\n Location: OAUTH_CONFIG.SUCCESS_URL,\n })\n res.end()\n\n this.processCallback({\n authorizationCode,\n state,\n useManualRedirect: false,\n })\n } else {\n res.writeHead(404)\n res.end()\n }\n },\n )\n\n this.server.listen(OAUTH_CONFIG.REDIRECT_PORT, async () => {\n onReady?.()\n })\n\n this.server.on('error', (err: Error) => {\n const portError = err as NodeJS.ErrnoException\n if (portError.code === 'EADDRINUSE') {\n const error = new Error(\n `Port ${OAUTH_CONFIG.REDIRECT_PORT} is already in use. Please ensure no other applications are using this port.`,\n )\n logError(error)\n this.closeServer()\n if (this.pendingCodePromise) {\n this.pendingCodePromise.reject(error)\n }\n return\n } else {\n logError(err)\n this.closeServer()\n if (this.pendingCodePromise) {\n this.pendingCodePromise.reject(err)\n }\n return\n }\n })\n }\n\n private async exchangeCodeForTokens(\n authorizationCode: string,\n state: string,\n useManualRedirect: boolean = false,\n ): Promise<OAuthTokenExchangeResponse> {\n const requestBody = {\n grant_type: 'authorization_code',\n code: authorizationCode,\n redirect_uri: useManualRedirect\n ? OAUTH_CONFIG.MANUAL_REDIRECT_URL\n : `http://localhost:${OAUTH_CONFIG.REDIRECT_PORT}/callback`,\n client_id: OAUTH_CONFIG.CLIENT_ID,\n code_verifier: this.codeVerifier,\n state,\n }\n\n const response = await fetch(OAUTH_CONFIG.TOKEN_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(requestBody),\n signal: AbortSignal.timeout(30_000),\n })\n\n if (!response.ok) {\n throw new Error(`Token exchange failed: ${response.statusText}`)\n }\n\n const data = await response.json()\n return data\n }\n\n processCallback({\n authorizationCode,\n state,\n useManualRedirect,\n }: {\n authorizationCode: string\n state: string\n useManualRedirect: boolean\n }): void {\n this.closeServer()\n\n if (state !== this.expectedState) {\n if (this.pendingCodePromise) {\n this.pendingCodePromise.reject(\n new Error('Invalid state parameter'), // Possible CSRF attack\n )\n this.pendingCodePromise = null\n }\n return\n }\n\n if (this.pendingCodePromise) {\n this.pendingCodePromise.resolve({ authorizationCode, useManualRedirect })\n this.pendingCodePromise = null\n }\n }\n\n private closeServer(): void {\n if (this.server) {\n this.server.close()\n this.server = null\n }\n }\n}\n\nexport async function createAndStoreApiKey(\n accessToken: string,\n): Promise<string | null> {\n try {\n // Call create_api_key endpoint\n const createApiKeyResp = await fetch(OAUTH_CONFIG.API_KEY_URL, {\n method: 'POST',\n headers: { Authorization: `Bearer ${accessToken}` },\n signal: AbortSignal.timeout(30_000),\n })\n\n let apiKeyData\n let errorText = ''\n\n try {\n apiKeyData = await createApiKeyResp.json()\n } catch (_e) {\n // If response is not valid JSON, get as text for error logging\n errorText = await createApiKeyResp.text()\n }\n\n if (createApiKeyResp.ok && apiKeyData && apiKeyData.raw_key) {\n const apiKey = apiKeyData.raw_key\n\n // Store in global config\n const config = getMutableGlobalConfig()\n\n // Note: API key is now managed per model profile\n\n // Add to approved list\n if (!config.customApiKeyResponses) {\n config.customApiKeyResponses = { approved: [], rejected: [] }\n }\n if (!config.customApiKeyResponses.approved) {\n config.customApiKeyResponses.approved = []\n }\n\n const normalizedKey = normalizeApiKeyForConfig(apiKey)\n if (!config.customApiKeyResponses.approved.includes(normalizedKey)) {\n config.customApiKeyResponses.approved.push(normalizedKey)\n }\n\n // Save config\n saveGlobalConfig(config)\n\n // Reset the Anthropic client to force creation with new API key\n resetAnthropicClient()\n\n return apiKey\n }\n\n return null\n } catch (error) {\n throw error\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/services/openai.js
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
logAPIError
|
|
8
8
|
} from "../utils/debugLogger.js";
|
|
9
9
|
import { logError } from "../utils/log.js";
|
|
10
|
+
import { setStreamingState } from "../utils/streamingState.js";
|
|
10
11
|
import {
|
|
11
12
|
abortableDelay,
|
|
12
13
|
getRetryDelay as sharedGetRetryDelay
|
|
@@ -16,6 +17,11 @@ import {
|
|
|
16
17
|
} from "../utils/userFriendlyError.js";
|
|
17
18
|
import { isOpenAICompatibleProvider } from "../constants/providers.js";
|
|
18
19
|
import { getEffectiveCapabilities } from "../constants/providerRegistry.js";
|
|
20
|
+
import { resolveApiKey } from "../utils/config.js";
|
|
21
|
+
async function resolveModelApiKey(modelProfile) {
|
|
22
|
+
if (!modelProfile?.apiKey) return "";
|
|
23
|
+
return await resolveApiKey(modelProfile) ?? modelProfile.apiKey;
|
|
24
|
+
}
|
|
19
25
|
function getRetryDelay(attempt) {
|
|
20
26
|
return sharedGetRetryDelay(attempt);
|
|
21
27
|
}
|
|
@@ -26,6 +32,7 @@ var ModelErrorType = /* @__PURE__ */ ((ModelErrorType2) => {
|
|
|
26
32
|
ModelErrorType2["StreamOptions"] = "stream_options";
|
|
27
33
|
ModelErrorType2["Citations"] = "citations";
|
|
28
34
|
ModelErrorType2["RateLimit"] = "rate_limit";
|
|
35
|
+
ModelErrorType2["UnsupportedParam"] = "unsupported_param";
|
|
29
36
|
return ModelErrorType2;
|
|
30
37
|
})(ModelErrorType || {});
|
|
31
38
|
function getModelErrorKey(baseURL, model, type) {
|
|
@@ -136,6 +143,20 @@ ${description}
|
|
|
136
143
|
delete opts.stream_options;
|
|
137
144
|
}
|
|
138
145
|
},
|
|
146
|
+
{
|
|
147
|
+
type: "unsupported_param" /* UnsupportedParam */,
|
|
148
|
+
detect: (errMsg) => {
|
|
149
|
+
const lower = errMsg.toLowerCase();
|
|
150
|
+
return lower.includes("unsupported") && lower.includes("reasoning_effort") || lower.includes("does not support") && lower.includes("reasoning_effort");
|
|
151
|
+
},
|
|
152
|
+
fix: async (opts) => {
|
|
153
|
+
debugLogger.info("OPENAI_FIX", {
|
|
154
|
+
action: "remove_reasoning_effort",
|
|
155
|
+
model: opts.model
|
|
156
|
+
});
|
|
157
|
+
delete opts.reasoning_effort;
|
|
158
|
+
}
|
|
159
|
+
},
|
|
139
160
|
{
|
|
140
161
|
type: "citations" /* Citations */,
|
|
141
162
|
detect: (errMsg) => errMsg.includes("Extra inputs are not permitted") && errMsg.includes("citations"),
|
|
@@ -311,6 +332,15 @@ async function applyModelErrorFixes(opts, baseURL) {
|
|
|
311
332
|
}
|
|
312
333
|
}
|
|
313
334
|
}
|
|
335
|
+
const API_FETCH_TIMEOUT_MS = parseInt(
|
|
336
|
+
process.env.API_TIMEOUT_MS || String(120 * 1e3),
|
|
337
|
+
10
|
|
338
|
+
);
|
|
339
|
+
function withFetchTimeout(signal) {
|
|
340
|
+
const timeoutSignal = AbortSignal.timeout(API_FETCH_TIMEOUT_MS);
|
|
341
|
+
if (!signal) return timeoutSignal;
|
|
342
|
+
return AbortSignal.any([signal, timeoutSignal]);
|
|
343
|
+
}
|
|
314
344
|
async function tryWithEndpointFallback(baseURL, opts, headers, provider, proxy, signal) {
|
|
315
345
|
const endpointsToTry = [];
|
|
316
346
|
if (provider === "minimax") {
|
|
@@ -319,6 +349,7 @@ async function tryWithEndpointFallback(baseURL, opts, headers, provider, proxy,
|
|
|
319
349
|
endpointsToTry.push("/chat/completions");
|
|
320
350
|
}
|
|
321
351
|
let lastError = null;
|
|
352
|
+
const fetchSignal = withFetchTimeout(signal);
|
|
322
353
|
for (const endpoint of endpointsToTry) {
|
|
323
354
|
try {
|
|
324
355
|
const response = await fetch(`${baseURL}${endpoint}`, {
|
|
@@ -326,8 +357,7 @@ async function tryWithEndpointFallback(baseURL, opts, headers, provider, proxy,
|
|
|
326
357
|
headers,
|
|
327
358
|
body: JSON.stringify(opts.stream ? { ...opts, stream: true } : opts),
|
|
328
359
|
dispatcher: proxy,
|
|
329
|
-
signal
|
|
330
|
-
// 🔧 Connect AbortSignal to fetch call
|
|
360
|
+
signal: fetchSignal
|
|
331
361
|
});
|
|
332
362
|
if (response.ok) {
|
|
333
363
|
return { response, endpoint };
|
|
@@ -355,13 +385,13 @@ async function tryWithEndpointFallback(baseURL, opts, headers, provider, proxy,
|
|
|
355
385
|
}
|
|
356
386
|
throw lastError || new Error("All endpoints failed");
|
|
357
387
|
}
|
|
358
|
-
async function getCompletionWithProfile(modelProfile, opts, attempt = 0, maxAttempts =
|
|
388
|
+
async function getCompletionWithProfile(modelProfile, opts, attempt = 0, maxAttempts = 5, signal) {
|
|
359
389
|
if (attempt >= maxAttempts) {
|
|
360
390
|
throw new Error("Max attempts reached");
|
|
361
391
|
}
|
|
362
392
|
const provider = modelProfile?.provider || "anthropic";
|
|
363
393
|
const baseURL = modelProfile?.baseURL;
|
|
364
|
-
const apiKey = modelProfile
|
|
394
|
+
const apiKey = await resolveModelApiKey(modelProfile);
|
|
365
395
|
const proxy = getGlobalConfig().proxy ? new ProxyAgent(getGlobalConfig().proxy) : void 0;
|
|
366
396
|
const headers = {
|
|
367
397
|
"Content-Type": "application/json"
|
|
@@ -381,7 +411,7 @@ async function getCompletionWithProfile(modelProfile, opts, attempt = 0, maxAtte
|
|
|
381
411
|
model: opts.model,
|
|
382
412
|
provider,
|
|
383
413
|
apiKeyConfigured: !!apiKey,
|
|
384
|
-
apiKeyPrefix: apiKey ? apiKey.substring(0,
|
|
414
|
+
apiKeyPrefix: apiKey ? apiKey.substring(0, 4) + "..." : null,
|
|
385
415
|
maxTokens: opts.max_tokens,
|
|
386
416
|
temperature: opts.temperature,
|
|
387
417
|
messageCount: opts.messages?.length || 0,
|
|
@@ -391,6 +421,17 @@ async function getCompletionWithProfile(modelProfile, opts, attempt = 0, maxAtte
|
|
|
391
421
|
modelProfileName: modelProfile?.name
|
|
392
422
|
});
|
|
393
423
|
opts.messages = opts.messages.map((msg) => {
|
|
424
|
+
if (msg.role === "assistant" && Array.isArray(msg.content)) {
|
|
425
|
+
const filtered = msg.content.filter(
|
|
426
|
+
(block) => block.type !== "thinking" && block.type !== "redacted_thinking"
|
|
427
|
+
);
|
|
428
|
+
if (filtered.length !== msg.content.length) {
|
|
429
|
+
return {
|
|
430
|
+
...msg,
|
|
431
|
+
content: filtered.length > 0 ? filtered : [{ type: "text", text: "" }]
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
}
|
|
394
435
|
if (msg.role === "tool") {
|
|
395
436
|
if (Array.isArray(msg.content)) {
|
|
396
437
|
return {
|
|
@@ -433,8 +474,7 @@ async function getCompletionWithProfile(modelProfile, opts, attempt = 0, maxAtte
|
|
|
433
474
|
headers,
|
|
434
475
|
body: JSON.stringify({ ...opts, stream: true }),
|
|
435
476
|
dispatcher: proxy,
|
|
436
|
-
signal
|
|
437
|
-
// 🔧 CRITICAL FIX: Connect AbortSignal to fetch call
|
|
477
|
+
signal: withFetchTimeout(signal)
|
|
438
478
|
});
|
|
439
479
|
}
|
|
440
480
|
if (!response2.ok) {
|
|
@@ -502,6 +542,13 @@ async function getCompletionWithProfile(modelProfile, opts, attempt = 0, maxAtte
|
|
|
502
542
|
});
|
|
503
543
|
}
|
|
504
544
|
const delayMs = getRetryDelay(attempt);
|
|
545
|
+
setStreamingState({
|
|
546
|
+
phase: "retrying",
|
|
547
|
+
retryCount: attempt + 1,
|
|
548
|
+
maxRetries: maxAttempts,
|
|
549
|
+
errorName: `HTTP ${response2.status}`,
|
|
550
|
+
retryDelayMs: delayMs
|
|
551
|
+
});
|
|
505
552
|
debugLogger.warn("API_RETRY", {
|
|
506
553
|
status: response2.status,
|
|
507
554
|
delayMs,
|
|
@@ -546,8 +593,7 @@ async function getCompletionWithProfile(modelProfile, opts, attempt = 0, maxAtte
|
|
|
546
593
|
headers,
|
|
547
594
|
body: JSON.stringify(opts),
|
|
548
595
|
dispatcher: proxy,
|
|
549
|
-
signal
|
|
550
|
-
// 🔧 CRITICAL FIX: Connect AbortSignal to non-streaming fetch call
|
|
596
|
+
signal: withFetchTimeout(signal)
|
|
551
597
|
});
|
|
552
598
|
}
|
|
553
599
|
if (!response.ok) {
|
|
@@ -592,6 +638,13 @@ async function getCompletionWithProfile(modelProfile, opts, attempt = 0, maxAtte
|
|
|
592
638
|
debugLogger.warn("OPENAI_PARSE_ERROR", { status: response.status });
|
|
593
639
|
}
|
|
594
640
|
const delayMs = getRetryDelay(attempt);
|
|
641
|
+
setStreamingState({
|
|
642
|
+
phase: "retrying",
|
|
643
|
+
retryCount: attempt + 1,
|
|
644
|
+
maxRetries: maxAttempts,
|
|
645
|
+
errorName: `HTTP ${response.status}`,
|
|
646
|
+
retryDelayMs: delayMs
|
|
647
|
+
});
|
|
595
648
|
debugLogger.warn("API_RETRY", {
|
|
596
649
|
status: response.status,
|
|
597
650
|
delayMs,
|
|
@@ -626,6 +679,13 @@ async function getCompletionWithProfile(modelProfile, opts, attempt = 0, maxAtte
|
|
|
626
679
|
throw new Error("Request cancelled by user");
|
|
627
680
|
}
|
|
628
681
|
const delayMs = getRetryDelay(attempt);
|
|
682
|
+
setStreamingState({
|
|
683
|
+
phase: "retrying",
|
|
684
|
+
retryCount: attempt + 1,
|
|
685
|
+
maxRetries: maxAttempts,
|
|
686
|
+
errorName: error instanceof Error ? error.message.slice(0, 30) : "network error",
|
|
687
|
+
retryDelayMs: delayMs
|
|
688
|
+
});
|
|
629
689
|
debugLogger.warn("API_RETRY", {
|
|
630
690
|
error: "network_error",
|
|
631
691
|
delayMs,
|
|
@@ -656,6 +716,10 @@ async function getCompletionWithProfile(modelProfile, opts, attempt = 0, maxAtte
|
|
|
656
716
|
});
|
|
657
717
|
}
|
|
658
718
|
}
|
|
719
|
+
const STREAM_IDLE_TIMEOUT_MS = parseInt(
|
|
720
|
+
process.env.STREAM_IDLE_TIMEOUT_MS || String(120 * 1e3),
|
|
721
|
+
10
|
|
722
|
+
);
|
|
659
723
|
function createStreamProcessor(stream, signal) {
|
|
660
724
|
if (!stream) {
|
|
661
725
|
throw new Error("Stream is null or undefined");
|
|
@@ -671,7 +735,22 @@ function createStreamProcessor(stream, signal) {
|
|
|
671
735
|
}
|
|
672
736
|
let readResult;
|
|
673
737
|
try {
|
|
674
|
-
readResult = await
|
|
738
|
+
readResult = await Promise.race([
|
|
739
|
+
reader.read(),
|
|
740
|
+
new Promise((_, reject) => {
|
|
741
|
+
const timer = setTimeout(
|
|
742
|
+
() => reject(
|
|
743
|
+
new Error(
|
|
744
|
+
`Stream idle timeout: no data received for ${STREAM_IDLE_TIMEOUT_MS / 1e3}s`
|
|
745
|
+
)
|
|
746
|
+
),
|
|
747
|
+
STREAM_IDLE_TIMEOUT_MS
|
|
748
|
+
);
|
|
749
|
+
signal?.addEventListener("abort", () => clearTimeout(timer), {
|
|
750
|
+
once: true
|
|
751
|
+
});
|
|
752
|
+
})
|
|
753
|
+
]);
|
|
675
754
|
} catch (e) {
|
|
676
755
|
if (signal?.aborted) {
|
|
677
756
|
break;
|
|
@@ -742,7 +821,7 @@ function streamCompletion(stream, signal) {
|
|
|
742
821
|
}
|
|
743
822
|
async function callGPT5ResponsesAPI(modelProfile, opts, signal) {
|
|
744
823
|
const baseURL = modelProfile?.baseURL || "https://api.openai.com/v1";
|
|
745
|
-
const apiKey = modelProfile
|
|
824
|
+
const apiKey = await resolveModelApiKey(modelProfile);
|
|
746
825
|
const proxy = getGlobalConfig().proxy ? new ProxyAgent(getGlobalConfig().proxy) : void 0;
|
|
747
826
|
const headers = {
|
|
748
827
|
"Content-Type": "application/json",
|
|
@@ -792,14 +871,6 @@ async function callGPT5ResponsesAPI(modelProfile, opts, signal) {
|
|
|
792
871
|
// Balanced for most coding tasks
|
|
793
872
|
};
|
|
794
873
|
}
|
|
795
|
-
if (!responsesParams.instructions) {
|
|
796
|
-
responsesParams.instructions = `You are an expert programmer working in a terminal-based coding environment. Follow these guidelines:
|
|
797
|
-
- Provide clear, concise code solutions
|
|
798
|
-
- Use proper error handling and validation
|
|
799
|
-
- Follow coding best practices and patterns
|
|
800
|
-
- Explain complex logic when necessary
|
|
801
|
-
- Focus on maintainable, readable code`;
|
|
802
|
-
}
|
|
803
874
|
}
|
|
804
875
|
try {
|
|
805
876
|
const response = await fetch(`${baseURL}/responses`, {
|
|
@@ -883,7 +954,7 @@ ${mainContent}`;
|
|
|
883
954
|
}
|
|
884
955
|
};
|
|
885
956
|
}
|
|
886
|
-
async function getGPT5CompletionWithProfile(modelProfile, opts, attempt = 0, maxAttempts =
|
|
957
|
+
async function getGPT5CompletionWithProfile(modelProfile, opts, attempt = 0, maxAttempts = 5, signal) {
|
|
887
958
|
const features = getModelFeatures(opts.model);
|
|
888
959
|
const isOfficialOpenAI = !modelProfile.baseURL || modelProfile.baseURL.includes("api.openai.com");
|
|
889
960
|
if (features.supportsResponsesAPI && !opts.stream && isOfficialOpenAI) {
|