@shareai-lab/kode 1.1.12 → 1.1.14
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/cli.js +83 -57
- package/dist/ProjectOnboarding.js +99 -0
- package/dist/ProjectOnboarding.js.map +7 -0
- package/dist/Tool.js +1 -0
- package/dist/Tool.js.map +7 -0
- package/dist/commands/agents.js +2087 -0
- package/dist/commands/agents.js.map +7 -0
- package/dist/commands/approvedTools.js +36 -0
- package/dist/commands/approvedTools.js.map +7 -0
- package/dist/commands/bug.js +21 -0
- package/dist/commands/bug.js.map +7 -0
- package/dist/commands/clear.js +37 -0
- package/dist/commands/clear.js.map +7 -0
- package/dist/commands/compact.js +104 -0
- package/dist/commands/compact.js.map +7 -0
- package/dist/commands/config.js +20 -0
- package/dist/commands/config.js.map +7 -0
- package/dist/commands/cost.js +19 -0
- package/dist/commands/cost.js.map +7 -0
- package/dist/commands/ctx_viz.js +152 -0
- package/dist/commands/ctx_viz.js.map +7 -0
- package/dist/commands/doctor.js +25 -0
- package/dist/commands/doctor.js.map +7 -0
- package/dist/commands/help.js +20 -0
- package/dist/commands/help.js.map +7 -0
- package/dist/commands/init.js +38 -0
- package/dist/commands/init.js.map +7 -0
- package/dist/commands/listen.js +37 -0
- package/dist/commands/listen.js.map +7 -0
- package/dist/commands/login.js +37 -0
- package/dist/commands/login.js.map +7 -0
- package/dist/commands/logout.js +33 -0
- package/dist/commands/logout.js.map +7 -0
- package/dist/commands/mcp.js +34 -0
- package/dist/commands/mcp.js.map +7 -0
- package/dist/commands/model.js +41 -0
- package/dist/commands/model.js.map +7 -0
- package/dist/commands/modelstatus.js +21 -0
- package/dist/commands/modelstatus.js.map +7 -0
- package/dist/commands/onboarding.js +36 -0
- package/dist/commands/onboarding.js.map +7 -0
- package/dist/commands/pr_comments.js +61 -0
- package/dist/commands/pr_comments.js.map +7 -0
- package/dist/commands/refreshCommands.js +37 -0
- package/dist/commands/refreshCommands.js.map +7 -0
- package/dist/commands/release-notes.js +30 -0
- package/dist/commands/release-notes.js.map +7 -0
- package/dist/commands/resume.js +35 -0
- package/dist/commands/resume.js.map +7 -0
- package/dist/commands/review.js +51 -0
- package/dist/commands/review.js.map +7 -0
- package/dist/commands/terminalSetup.js +163 -0
- package/dist/commands/terminalSetup.js.map +7 -0
- package/dist/commands.js +84 -0
- package/dist/commands.js.map +7 -0
- package/dist/components/ApproveApiKey.js +74 -0
- package/dist/components/ApproveApiKey.js.map +7 -0
- package/dist/components/AsciiLogo.js +12 -0
- package/dist/components/AsciiLogo.js.map +7 -0
- package/dist/components/AutoUpdater.js +74 -0
- package/dist/components/AutoUpdater.js.map +7 -0
- package/dist/components/Bug.js +147 -0
- package/dist/components/Bug.js.map +7 -0
- package/dist/components/Config.js +166 -0
- package/dist/components/Config.js.map +7 -0
- package/dist/components/ConsoleOAuthFlow.js +188 -0
- package/dist/components/ConsoleOAuthFlow.js.map +7 -0
- package/dist/components/Cost.js +13 -0
- package/dist/components/Cost.js.map +7 -0
- package/dist/components/CostThresholdDialog.js +38 -0
- package/dist/components/CostThresholdDialog.js.map +7 -0
- package/dist/components/CustomSelect/option-map.js +32 -0
- package/dist/components/CustomSelect/option-map.js.map +7 -0
- package/dist/components/CustomSelect/select-option.js +34 -0
- package/dist/components/CustomSelect/select-option.js.map +7 -0
- package/dist/components/CustomSelect/select.js +64 -0
- package/dist/components/CustomSelect/select.js.map +7 -0
- package/dist/components/CustomSelect/theme.js +1 -0
- package/dist/components/CustomSelect/theme.js.map +7 -0
- package/dist/components/CustomSelect/use-select-state.js +220 -0
- package/dist/components/CustomSelect/use-select-state.js.map +7 -0
- package/dist/components/CustomSelect/use-select.js +21 -0
- package/dist/components/CustomSelect/use-select.js.map +7 -0
- package/dist/components/FallbackToolUseRejectedMessage.js +11 -0
- package/dist/components/FallbackToolUseRejectedMessage.js.map +7 -0
- package/dist/components/FileEditToolUpdatedMessage.js +31 -0
- package/dist/components/FileEditToolUpdatedMessage.js.map +7 -0
- package/dist/components/Help.js +41 -0
- package/dist/components/Help.js.map +7 -0
- package/dist/components/HighlightedCode.js +30 -0
- package/dist/components/HighlightedCode.js.map +7 -0
- package/dist/components/InvalidConfigDialog.js +83 -0
- package/dist/components/InvalidConfigDialog.js.map +7 -0
- package/dist/components/Link.js +18 -0
- package/dist/components/Link.js.map +7 -0
- package/dist/components/LogSelector.js +50 -0
- package/dist/components/LogSelector.js.map +7 -0
- package/dist/components/Logo.js +89 -0
- package/dist/components/Logo.js.map +7 -0
- package/dist/components/MCPServerApprovalDialog.js +79 -0
- package/dist/components/MCPServerApprovalDialog.js.map +7 -0
- package/dist/components/MCPServerDialogCopy.js +11 -0
- package/dist/components/MCPServerDialogCopy.js.map +7 -0
- package/dist/components/MCPServerMultiselectDialog.js +80 -0
- package/dist/components/MCPServerMultiselectDialog.js.map +7 -0
- package/dist/components/Message.js +146 -0
- package/dist/components/Message.js.map +7 -0
- package/dist/components/MessageResponse.js +9 -0
- package/dist/components/MessageResponse.js.map +7 -0
- package/dist/components/MessageSelector.js +133 -0
- package/dist/components/MessageSelector.js.map +7 -0
- package/dist/components/ModeIndicator.js +38 -0
- package/dist/components/ModeIndicator.js.map +7 -0
- package/dist/components/ModelConfig.js +208 -0
- package/dist/components/ModelConfig.js.map +7 -0
- package/dist/components/ModelListManager.js +140 -0
- package/dist/components/ModelListManager.js.map +7 -0
- package/dist/components/ModelSelector.js +1985 -0
- package/dist/components/ModelSelector.js.map +7 -0
- package/dist/components/ModelStatusDisplay.js +87 -0
- package/dist/components/ModelStatusDisplay.js.map +7 -0
- package/dist/components/Onboarding.js +153 -0
- package/dist/components/Onboarding.js.map +7 -0
- package/dist/components/PressEnterToContinue.js +10 -0
- package/dist/components/PressEnterToContinue.js.map +7 -0
- package/dist/components/PromptInput.js +501 -0
- package/dist/components/PromptInput.js.map +7 -0
- package/dist/components/SentryErrorBoundary.js +27 -0
- package/dist/components/SentryErrorBoundary.js.map +7 -0
- package/dist/components/Spinner.js +101 -0
- package/dist/components/Spinner.js.map +7 -0
- package/dist/components/StickerRequestForm.js +7 -0
- package/dist/components/StickerRequestForm.js.map +7 -0
- package/dist/components/StructuredDiff.js +148 -0
- package/dist/components/StructuredDiff.js.map +7 -0
- package/dist/components/TextInput.js +100 -0
- package/dist/components/TextInput.js.map +7 -0
- package/dist/components/TodoItem.js +35 -0
- package/dist/components/TodoItem.js.map +7 -0
- package/dist/components/TokenWarning.js +19 -0
- package/dist/components/TokenWarning.js.map +7 -0
- package/dist/components/ToolUseLoader.js +24 -0
- package/dist/components/ToolUseLoader.js.map +7 -0
- package/dist/components/TrustDialog.js +76 -0
- package/dist/components/TrustDialog.js.map +7 -0
- package/dist/components/binary-feedback/BinaryFeedback.js +50 -0
- package/dist/components/binary-feedback/BinaryFeedback.js.map +7 -0
- package/dist/components/binary-feedback/BinaryFeedbackOption.js +94 -0
- package/dist/components/binary-feedback/BinaryFeedbackOption.js.map +7 -0
- package/dist/components/binary-feedback/BinaryFeedbackView.js +139 -0
- package/dist/components/binary-feedback/BinaryFeedbackView.js.map +7 -0
- package/dist/components/binary-feedback/utils.js +161 -0
- package/dist/components/binary-feedback/utils.js.map +7 -0
- package/dist/components/messages/AssistantBashOutputMessage.js +23 -0
- package/dist/components/messages/AssistantBashOutputMessage.js.map +7 -0
- package/dist/components/messages/AssistantLocalCommandOutputMessage.js +36 -0
- package/dist/components/messages/AssistantLocalCommandOutputMessage.js.map +7 -0
- package/dist/components/messages/AssistantRedactedThinkingMessage.js +12 -0
- package/dist/components/messages/AssistantRedactedThinkingMessage.js.map +7 -0
- package/dist/components/messages/AssistantTextMessage.js +78 -0
- package/dist/components/messages/AssistantTextMessage.js.map +7 -0
- package/dist/components/messages/AssistantThinkingMessage.js +27 -0
- package/dist/components/messages/AssistantThinkingMessage.js.map +7 -0
- package/dist/components/messages/AssistantToolUseMessage.js +91 -0
- package/dist/components/messages/AssistantToolUseMessage.js.map +7 -0
- package/dist/components/messages/TaskProgressMessage.js +11 -0
- package/dist/components/messages/TaskProgressMessage.js.map +7 -0
- package/dist/components/messages/TaskToolMessage.js +39 -0
- package/dist/components/messages/TaskToolMessage.js.map +7 -0
- package/dist/components/messages/UserBashInputMessage.js +18 -0
- package/dist/components/messages/UserBashInputMessage.js.map +7 -0
- package/dist/components/messages/UserCommandMessage.js +20 -0
- package/dist/components/messages/UserCommandMessage.js.map +7 -0
- package/dist/components/messages/UserKodingInputMessage.js +18 -0
- package/dist/components/messages/UserKodingInputMessage.js.map +7 -0
- package/dist/components/messages/UserPromptMessage.js +20 -0
- package/dist/components/messages/UserPromptMessage.js.map +7 -0
- package/dist/components/messages/UserTextMessage.js +25 -0
- package/dist/components/messages/UserTextMessage.js.map +7 -0
- package/dist/components/messages/UserToolResultMessage/UserToolCanceledMessage.js +10 -0
- package/dist/components/messages/UserToolResultMessage/UserToolCanceledMessage.js.map +7 -0
- package/dist/components/messages/UserToolResultMessage/UserToolErrorMessage.js +15 -0
- package/dist/components/messages/UserToolResultMessage/UserToolErrorMessage.js.map +7 -0
- package/dist/components/messages/UserToolResultMessage/UserToolRejectMessage.js +25 -0
- package/dist/components/messages/UserToolResultMessage/UserToolRejectMessage.js.map +7 -0
- package/dist/components/messages/UserToolResultMessage/UserToolResultMessage.js +47 -0
- package/dist/components/messages/UserToolResultMessage/UserToolResultMessage.js.map +7 -0
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js +23 -0
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js.map +7 -0
- package/dist/components/messages/UserToolResultMessage/utils.js +42 -0
- package/dist/components/messages/UserToolResultMessage/utils.js.map +7 -0
- package/dist/components/permissions/BashPermissionRequest/BashPermissionRequest.js +112 -0
- package/dist/components/permissions/BashPermissionRequest/BashPermissionRequest.js.map +7 -0
- package/dist/components/permissions/FallbackPermissionRequest.js +131 -0
- package/dist/components/permissions/FallbackPermissionRequest.js.map +7 -0
- package/dist/components/permissions/FileEditPermissionRequest/FileEditPermissionRequest.js +159 -0
- package/dist/components/permissions/FileEditPermissionRequest/FileEditPermissionRequest.js.map +7 -0
- package/dist/components/permissions/FileEditPermissionRequest/FileEditToolDiff.js +58 -0
- package/dist/components/permissions/FileEditPermissionRequest/FileEditToolDiff.js.map +7 -0
- package/dist/components/permissions/FileWritePermissionRequest/FileWritePermissionRequest.js +153 -0
- package/dist/components/permissions/FileWritePermissionRequest/FileWritePermissionRequest.js.map +7 -0
- package/dist/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.js +70 -0
- package/dist/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.js.map +7 -0
- package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js +212 -0
- package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js.map +7 -0
- package/dist/components/permissions/PermissionRequest.js +70 -0
- package/dist/components/permissions/PermissionRequest.js.map +7 -0
- package/dist/components/permissions/PermissionRequestTitle.js +52 -0
- package/dist/components/permissions/PermissionRequestTitle.js.map +7 -0
- package/dist/components/permissions/hooks.js +28 -0
- package/dist/components/permissions/hooks.js.map +7 -0
- package/dist/components/permissions/toolUseOptions.js +46 -0
- package/dist/components/permissions/toolUseOptions.js.map +7 -0
- package/dist/components/permissions/utils.js +21 -0
- package/dist/components/permissions/utils.js.map +7 -0
- package/dist/constants/betas.js +11 -0
- package/dist/constants/betas.js.map +7 -0
- package/dist/constants/claude-asterisk-ascii-art.js +242 -0
- package/dist/constants/claude-asterisk-ascii-art.js.map +7 -0
- package/dist/constants/figures.js +6 -0
- package/dist/constants/figures.js.map +7 -0
- package/dist/constants/keys.js +7 -0
- package/dist/constants/keys.js.map +7 -0
- package/dist/constants/macros.js +13 -0
- package/dist/constants/macros.js.map +7 -0
- package/dist/constants/modelCapabilities.js +154 -0
- package/dist/constants/modelCapabilities.js.map +7 -0
- package/dist/constants/models.js +1029 -0
- package/dist/constants/models.js.map +7 -0
- package/dist/constants/oauth.js +18 -0
- package/dist/constants/oauth.js.map +7 -0
- package/dist/constants/product.js +26 -0
- package/dist/constants/product.js.map +7 -0
- package/dist/constants/prompts.js +168 -0
- package/dist/constants/prompts.js.map +7 -0
- package/dist/constants/releaseNotes.js +9 -0
- package/dist/constants/releaseNotes.js.map +7 -0
- package/dist/context/PermissionContext.js +111 -0
- package/dist/context/PermissionContext.js.map +7 -0
- package/dist/context.js +259 -0
- package/dist/context.js.map +7 -0
- package/dist/cost-tracker.js +76 -0
- package/dist/cost-tracker.js.map +7 -0
- package/dist/entrypoints/cli.js +1101 -0
- package/dist/entrypoints/cli.js.map +7 -0
- package/dist/entrypoints/mcp.js +150 -0
- package/dist/entrypoints/mcp.js.map +7 -0
- package/dist/history.js +25 -0
- package/dist/history.js.map +7 -0
- package/dist/hooks/useApiKeyVerification.js +12 -0
- package/dist/hooks/useApiKeyVerification.js.map +7 -0
- package/dist/hooks/useArrowKeyHistory.js +50 -0
- package/dist/hooks/useArrowKeyHistory.js.map +7 -0
- package/dist/hooks/useCanUseTool.js +112 -0
- package/dist/hooks/useCanUseTool.js.map +7 -0
- package/dist/hooks/useCancelRequest.js +30 -0
- package/dist/hooks/useCancelRequest.js.map +7 -0
- package/dist/hooks/useDoublePress.js +31 -0
- package/dist/hooks/useDoublePress.js.map +7 -0
- package/dist/hooks/useExitOnCtrlCD.js +26 -0
- package/dist/hooks/useExitOnCtrlCD.js.map +7 -0
- package/dist/hooks/useInterval.js +18 -0
- package/dist/hooks/useInterval.js.map +7 -0
- package/dist/hooks/useLogMessages.js +14 -0
- package/dist/hooks/useLogMessages.js.map +7 -0
- package/dist/hooks/useLogStartupTime.js +15 -0
- package/dist/hooks/useLogStartupTime.js.map +7 -0
- package/dist/hooks/useNotifyAfterTimeout.js +42 -0
- package/dist/hooks/useNotifyAfterTimeout.js.map +7 -0
- package/dist/hooks/usePermissionRequestLogging.js +28 -0
- package/dist/hooks/usePermissionRequestLogging.js.map +7 -0
- package/dist/hooks/useTerminalSize.js +38 -0
- package/dist/hooks/useTerminalSize.js.map +7 -0
- package/dist/hooks/useTextInput.js +250 -0
- package/dist/hooks/useTextInput.js.map +7 -0
- package/dist/hooks/useUnifiedCompletion.js +929 -0
- package/dist/hooks/useUnifiedCompletion.js.map +7 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +7 -0
- package/dist/messages.js +33 -0
- package/dist/messages.js.map +7 -0
- package/dist/package.json +1 -0
- package/dist/permissions.js +194 -0
- package/dist/permissions.js.map +7 -0
- package/dist/query.js +492 -0
- package/dist/query.js.map +7 -0
- package/dist/screens/ConfigureNpmPrefix.js +128 -0
- package/dist/screens/ConfigureNpmPrefix.js.map +7 -0
- package/dist/screens/Doctor.js +143 -0
- package/dist/screens/Doctor.js.map +7 -0
- package/dist/screens/LogList.js +55 -0
- package/dist/screens/LogList.js.map +7 -0
- package/dist/screens/REPL.js +596 -0
- package/dist/screens/REPL.js.map +7 -0
- package/dist/screens/ResumeConversation.js +56 -0
- package/dist/screens/ResumeConversation.js.map +7 -0
- package/dist/services/adapters/base.js +29 -0
- package/dist/services/adapters/base.js.map +7 -0
- package/dist/services/adapters/chatCompletions.js +69 -0
- package/dist/services/adapters/chatCompletions.js.map +7 -0
- package/dist/services/adapters/responsesAPI.js +126 -0
- package/dist/services/adapters/responsesAPI.js.map +7 -0
- package/dist/services/browserMocks.js +48 -0
- package/dist/services/browserMocks.js.map +7 -0
- package/dist/services/claude.js +1605 -0
- package/dist/services/claude.js.map +7 -0
- package/dist/services/customCommands.js +359 -0
- package/dist/services/customCommands.js.map +7 -0
- package/dist/services/fileFreshness.js +280 -0
- package/dist/services/fileFreshness.js.map +7 -0
- package/dist/services/gpt5ConnectionTest.js +248 -0
- package/dist/services/gpt5ConnectionTest.js.map +7 -0
- package/dist/services/mcpClient.js +435 -0
- package/dist/services/mcpClient.js.map +7 -0
- package/dist/services/mcpServerApproval.js +55 -0
- package/dist/services/mcpServerApproval.js.map +7 -0
- package/dist/services/mentionProcessor.js +200 -0
- package/dist/services/mentionProcessor.js.map +7 -0
- package/dist/services/modelAdapterFactory.js +47 -0
- package/dist/services/modelAdapterFactory.js.map +7 -0
- package/dist/services/notifier.js +35 -0
- package/dist/services/notifier.js.map +7 -0
- package/dist/services/oauth.js +259 -0
- package/dist/services/oauth.js.map +7 -0
- package/dist/services/openai.js +998 -0
- package/dist/services/openai.js.map +7 -0
- package/dist/services/responseStateManager.js +68 -0
- package/dist/services/responseStateManager.js.map +7 -0
- package/dist/services/sentry.js +9 -0
- package/dist/services/sentry.js.map +7 -0
- package/dist/services/statsig.js +112 -0
- package/dist/services/statsig.js.map +7 -0
- package/dist/services/statsigStorage.js +75 -0
- package/dist/services/statsigStorage.js.map +7 -0
- package/dist/services/systemReminder.js +353 -0
- package/dist/services/systemReminder.js.map +7 -0
- package/dist/services/vcr.js +133 -0
- package/dist/services/vcr.js.map +7 -0
- package/dist/test/testAdapters.js +88 -0
- package/dist/test/testAdapters.js.map +1 -0
- package/dist/tools/ArchitectTool/ArchitectTool.js +119 -0
- package/dist/tools/ArchitectTool/ArchitectTool.js.map +7 -0
- package/dist/tools/ArchitectTool/prompt.js +18 -0
- package/dist/tools/ArchitectTool/prompt.js.map +7 -0
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +423 -0
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +7 -0
- package/dist/tools/BashTool/BashTool.js +188 -0
- package/dist/tools/BashTool/BashTool.js.map +7 -0
- package/dist/tools/BashTool/BashToolResultMessage.js +21 -0
- package/dist/tools/BashTool/BashToolResultMessage.js.map +7 -0
- package/dist/tools/BashTool/OutputLine.js +30 -0
- package/dist/tools/BashTool/OutputLine.js.map +7 -0
- package/dist/tools/BashTool/prompt.js +179 -0
- package/dist/tools/BashTool/prompt.js.map +7 -0
- package/dist/tools/BashTool/utils.js +51 -0
- package/dist/tools/BashTool/utils.js.map +7 -0
- package/dist/tools/FileEditTool/FileEditTool.js +228 -0
- package/dist/tools/FileEditTool/FileEditTool.js.map +7 -0
- package/dist/tools/FileEditTool/prompt.js +54 -0
- package/dist/tools/FileEditTool/prompt.js.map +7 -0
- package/dist/tools/FileEditTool/utils.js +42 -0
- package/dist/tools/FileEditTool/utils.js.map +7 -0
- package/dist/tools/FileReadTool/FileReadTool.js +272 -0
- package/dist/tools/FileReadTool/FileReadTool.js.map +7 -0
- package/dist/tools/FileReadTool/prompt.js +10 -0
- package/dist/tools/FileReadTool/prompt.js.map +7 -0
- package/dist/tools/FileWriteTool/FileWriteTool.js +204 -0
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +7 -0
- package/dist/tools/FileWriteTool/prompt.js +14 -0
- package/dist/tools/FileWriteTool/prompt.js.map +7 -0
- package/dist/tools/GlobTool/GlobTool.js +88 -0
- package/dist/tools/GlobTool/GlobTool.js.map +7 -0
- package/dist/tools/GlobTool/prompt.js +12 -0
- package/dist/tools/GlobTool/prompt.js.map +7 -0
- package/dist/tools/GrepTool/GrepTool.js +107 -0
- package/dist/tools/GrepTool/GrepTool.js.map +7 -0
- package/dist/tools/GrepTool/prompt.js +15 -0
- package/dist/tools/GrepTool/prompt.js.map +7 -0
- package/dist/tools/MCPTool/MCPTool.js +90 -0
- package/dist/tools/MCPTool/MCPTool.js.map +7 -0
- package/dist/tools/MCPTool/prompt.js +7 -0
- package/dist/tools/MCPTool/prompt.js.map +7 -0
- package/dist/tools/MemoryReadTool/MemoryReadTool.js +103 -0
- package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +7 -0
- package/dist/tools/MemoryReadTool/prompt.js +7 -0
- package/dist/tools/MemoryReadTool/prompt.js.map +7 -0
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +77 -0
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +7 -0
- package/dist/tools/MemoryWriteTool/prompt.js +7 -0
- package/dist/tools/MemoryWriteTool/prompt.js.map +7 -0
- package/dist/tools/MultiEditTool/MultiEditTool.js +293 -0
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +7 -0
- package/dist/tools/MultiEditTool/prompt.js +48 -0
- package/dist/tools/MultiEditTool/prompt.js.map +7 -0
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +238 -0
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +7 -0
- package/dist/tools/NotebookEditTool/prompt.js +7 -0
- package/dist/tools/NotebookEditTool/prompt.js.map +7 -0
- package/dist/tools/NotebookReadTool/NotebookReadTool.js +212 -0
- package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +7 -0
- package/dist/tools/NotebookReadTool/prompt.js +7 -0
- package/dist/tools/NotebookReadTool/prompt.js.map +7 -0
- package/dist/tools/StickerRequestTool/StickerRequestTool.js +86 -0
- package/dist/tools/StickerRequestTool/StickerRequestTool.js.map +7 -0
- package/dist/tools/StickerRequestTool/prompt.js +23 -0
- package/dist/tools/StickerRequestTool/prompt.js.map +7 -0
- package/dist/tools/TaskTool/TaskTool.js +308 -0
- package/dist/tools/TaskTool/TaskTool.js.map +7 -0
- package/dist/tools/TaskTool/constants.js +5 -0
- package/dist/tools/TaskTool/constants.js.map +7 -0
- package/dist/tools/TaskTool/prompt.js +82 -0
- package/dist/tools/TaskTool/prompt.js.map +7 -0
- package/dist/tools/ThinkTool/ThinkTool.js +48 -0
- package/dist/tools/ThinkTool/ThinkTool.js.map +7 -0
- package/dist/tools/ThinkTool/prompt.js +16 -0
- package/dist/tools/ThinkTool/prompt.js.map +7 -0
- package/dist/tools/TodoWriteTool/TodoWriteTool.js +216 -0
- package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +7 -0
- package/dist/tools/TodoWriteTool/prompt.js +66 -0
- package/dist/tools/TodoWriteTool/prompt.js.map +7 -0
- package/dist/tools/URLFetcherTool/URLFetcherTool.js +137 -0
- package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +7 -0
- package/dist/tools/URLFetcherTool/cache.js +45 -0
- package/dist/tools/URLFetcherTool/cache.js.map +7 -0
- package/dist/tools/URLFetcherTool/htmlToMarkdown.js +42 -0
- package/dist/tools/URLFetcherTool/htmlToMarkdown.js.map +7 -0
- package/dist/tools/URLFetcherTool/prompt.js +22 -0
- package/dist/tools/URLFetcherTool/prompt.js.map +7 -0
- package/dist/tools/WebSearchTool/WebSearchTool.js +86 -0
- package/dist/tools/WebSearchTool/WebSearchTool.js.map +7 -0
- package/dist/tools/WebSearchTool/prompt.js +17 -0
- package/dist/tools/WebSearchTool/prompt.js.map +7 -0
- package/dist/tools/WebSearchTool/searchProviders.js +48 -0
- package/dist/tools/WebSearchTool/searchProviders.js.map +7 -0
- package/dist/tools/lsTool/lsTool.js +201 -0
- package/dist/tools/lsTool/lsTool.js.map +7 -0
- package/dist/tools/lsTool/prompt.js +5 -0
- package/dist/tools/lsTool/prompt.js.map +7 -0
- package/dist/tools.js +64 -0
- package/dist/tools.js.map +7 -0
- package/dist/types/PermissionMode.js +82 -0
- package/dist/types/PermissionMode.js.map +7 -0
- package/dist/types/RequestContext.js +47 -0
- package/dist/types/RequestContext.js.map +7 -0
- package/dist/types/common.d.js +1 -0
- package/dist/types/common.d.js.map +7 -0
- package/dist/types/conversation.js +1 -0
- package/dist/types/conversation.js.map +7 -0
- package/dist/types/logs.js +1 -0
- package/dist/types/logs.js.map +7 -0
- package/dist/types/modelCapabilities.js +1 -0
- package/dist/types/modelCapabilities.js.map +7 -0
- package/dist/types/notebook.js +1 -0
- package/dist/types/notebook.js.map +7 -0
- package/dist/utils/Cursor.js +313 -0
- package/dist/utils/Cursor.js.map +7 -0
- package/dist/utils/PersistentShell.js +382 -0
- package/dist/utils/PersistentShell.js.map +7 -0
- package/dist/utils/advancedFuzzyMatcher.js +206 -0
- package/dist/utils/advancedFuzzyMatcher.js.map +7 -0
- package/dist/utils/agentLoader.js +199 -0
- package/dist/utils/agentLoader.js.map +7 -0
- package/dist/utils/agentStorage.js +59 -0
- package/dist/utils/agentStorage.js.map +7 -0
- package/dist/utils/array.js +7 -0
- package/dist/utils/array.js.map +7 -0
- package/dist/utils/ask.js +77 -0
- package/dist/utils/ask.js.map +7 -0
- package/dist/utils/auth.js +11 -0
- package/dist/utils/auth.js.map +7 -0
- package/dist/utils/autoCompactCore.js +149 -0
- package/dist/utils/autoCompactCore.js.map +7 -0
- package/dist/utils/autoUpdater.js +362 -0
- package/dist/utils/autoUpdater.js.map +7 -0
- package/dist/utils/betas.js +21 -0
- package/dist/utils/betas.js.map +7 -0
- package/dist/utils/browser.js +15 -0
- package/dist/utils/browser.js.map +7 -0
- package/dist/utils/cleanup.js +54 -0
- package/dist/utils/cleanup.js.map +7 -0
- package/dist/utils/commands.js +207 -0
- package/dist/utils/commands.js.map +7 -0
- package/dist/utils/commonUnixCommands.js +687 -0
- package/dist/utils/commonUnixCommands.js.map +7 -0
- package/dist/utils/config.js +655 -0
- package/dist/utils/config.js.map +7 -0
- package/dist/utils/conversationRecovery.js +35 -0
- package/dist/utils/conversationRecovery.js.map +7 -0
- package/dist/utils/debugLogger.js +891 -0
- package/dist/utils/debugLogger.js.map +7 -0
- package/dist/utils/diff.js +32 -0
- package/dist/utils/diff.js.map +7 -0
- package/dist/utils/env.js +44 -0
- package/dist/utils/env.js.map +7 -0
- package/dist/utils/errors.js +23 -0
- package/dist/utils/errors.js.map +7 -0
- package/dist/utils/exampleCommands.js +80 -0
- package/dist/utils/exampleCommands.js.map +7 -0
- package/dist/utils/execFileNoThrow.js +44 -0
- package/dist/utils/execFileNoThrow.js.map +7 -0
- package/dist/utils/expertChatStorage.js +78 -0
- package/dist/utils/expertChatStorage.js.map +7 -0
- package/dist/utils/file.js +282 -0
- package/dist/utils/file.js.map +7 -0
- package/dist/utils/fileRecoveryCore.js +41 -0
- package/dist/utils/fileRecoveryCore.js.map +7 -0
- package/dist/utils/format.js +41 -0
- package/dist/utils/format.js.map +7 -0
- package/dist/utils/fuzzyMatcher.js +252 -0
- package/dist/utils/fuzzyMatcher.js.map +7 -0
- package/dist/utils/generators.js +46 -0
- package/dist/utils/generators.js.map +7 -0
- package/dist/utils/git.js +83 -0
- package/dist/utils/git.js.map +7 -0
- package/dist/utils/globalLogger.js +54 -0
- package/dist/utils/globalLogger.js.map +7 -0
- package/dist/utils/http.js +7 -0
- package/dist/utils/http.js.map +7 -0
- package/dist/utils/imagePaste.js +29 -0
- package/dist/utils/imagePaste.js.map +7 -0
- package/dist/utils/json.js +16 -0
- package/dist/utils/json.js.map +7 -0
- package/dist/utils/log.js +298 -0
- package/dist/utils/log.js.map +7 -0
- package/dist/utils/markdown.js +187 -0
- package/dist/utils/markdown.js.map +7 -0
- package/dist/utils/messageContextManager.js +195 -0
- package/dist/utils/messageContextManager.js.map +7 -0
- package/dist/utils/messages.js +633 -0
- package/dist/utils/messages.js.map +7 -0
- package/dist/utils/model.js +687 -0
- package/dist/utils/model.js.map +7 -0
- package/dist/utils/permissions/filesystem.js +80 -0
- package/dist/utils/permissions/filesystem.js.map +7 -0
- package/dist/utils/responseState.js +20 -0
- package/dist/utils/responseState.js.map +7 -0
- package/dist/utils/ripgrep.js +131 -0
- package/dist/utils/ripgrep.js.map +7 -0
- package/dist/utils/secureFile.js +483 -0
- package/dist/utils/secureFile.js.map +7 -0
- package/dist/utils/sessionState.js +31 -0
- package/dist/utils/sessionState.js.map +7 -0
- package/dist/utils/state.js +24 -0
- package/dist/utils/state.js.map +7 -0
- package/dist/utils/style.js +31 -0
- package/dist/utils/style.js.map +7 -0
- package/dist/utils/terminal.js +43 -0
- package/dist/utils/terminal.js.map +7 -0
- package/dist/utils/theme.js +102 -0
- package/dist/utils/theme.js.map +7 -0
- package/dist/utils/thinking.js +103 -0
- package/dist/utils/thinking.js.map +7 -0
- package/dist/utils/todoStorage.js +291 -0
- package/dist/utils/todoStorage.js.map +7 -0
- package/dist/utils/tokens.js +30 -0
- package/dist/utils/tokens.js.map +7 -0
- package/dist/utils/toolExecutionController.js +109 -0
- package/dist/utils/toolExecutionController.js.map +7 -0
- package/dist/utils/unaryLogging.js +14 -0
- package/dist/utils/unaryLogging.js.map +7 -0
- package/dist/utils/user.js +40 -0
- package/dist/utils/user.js.map +7 -0
- package/dist/utils/validate.js +132 -0
- package/dist/utils/validate.js.map +7 -0
- package/dist/yoga.wasm +0 -0
- package/package.json +28 -7
- package/src/Tool.ts +4 -3
- package/src/commands/agents.tsx +10 -4
- package/src/components/messages/AssistantToolUseMessage.tsx +5 -6
- package/src/constants/macros.ts +5 -2
- package/src/entrypoints/cli.tsx +38 -19
- package/src/entrypoints/mcp.ts +1 -2
- package/src/hooks/useDoublePress.ts +0 -1
- package/src/hooks/useTextInput.ts +4 -5
- package/src/hooks/useUnifiedCompletion.ts +2 -2
- package/src/index.ts +34 -0
- package/src/query.ts +13 -8
- package/src/screens/Doctor.tsx +1 -1
- package/src/screens/REPL.tsx +13 -9
- package/src/services/openai.ts +25 -4
- package/src/tools/ArchitectTool/ArchitectTool.tsx +18 -5
- package/src/tools/AskExpertModelTool/AskExpertModelTool.tsx +21 -14
- package/src/tools/FileEditTool/FileEditTool.tsx +6 -2
- package/src/tools/FileWriteTool/FileWriteTool.tsx +7 -3
- package/src/tools/MultiEditTool/MultiEditTool.tsx +26 -4
- package/src/tools/NotebookReadTool/NotebookReadTool.tsx +1 -1
- package/src/tools/StickerRequestTool/StickerRequestTool.tsx +28 -14
- package/src/tools/TaskTool/TaskTool.tsx +8 -36
- package/src/types/common.d.ts +2 -0
- package/src/utils/generators.ts +1 -1
- package/src/utils/messageContextManager.ts +5 -0
- package/src/utils/messages.tsx +8 -2
- package/src/utils/thinking.ts +1 -1
|
@@ -0,0 +1,1605 @@
|
|
|
1
|
+
import "@anthropic-ai/sdk/shims/node";
|
|
2
|
+
import Anthropic, { APIConnectionError, APIError } from "@anthropic-ai/sdk";
|
|
3
|
+
import { AnthropicBedrock } from "@anthropic-ai/bedrock-sdk";
|
|
4
|
+
import { AnthropicVertex } from "@anthropic-ai/vertex-sdk";
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import { createHash, randomUUID } from "crypto";
|
|
7
|
+
import "dotenv/config";
|
|
8
|
+
import { addToTotalCost } from "../cost-tracker.js";
|
|
9
|
+
import models from "../constants/models.js";
|
|
10
|
+
import {
|
|
11
|
+
getAnthropicApiKey,
|
|
12
|
+
getOrCreateUserID,
|
|
13
|
+
getGlobalConfig
|
|
14
|
+
} from "../utils/config.js";
|
|
15
|
+
import { getProjectDocs } from "../context.js";
|
|
16
|
+
import { logError, SESSION_ID } from "../utils/log.js";
|
|
17
|
+
import { USER_AGENT } from "../utils/http.js";
|
|
18
|
+
import {
|
|
19
|
+
createAssistantAPIErrorMessage,
|
|
20
|
+
normalizeContentFromAPI
|
|
21
|
+
} from "../utils/messages.js";
|
|
22
|
+
import { logEvent } from "./statsig.js";
|
|
23
|
+
import { withVCR } from "./vcr.js";
|
|
24
|
+
import {
|
|
25
|
+
debug as debugLogger,
|
|
26
|
+
markPhase,
|
|
27
|
+
getCurrentRequest,
|
|
28
|
+
logLLMInteraction,
|
|
29
|
+
logSystemPromptConstruction,
|
|
30
|
+
logErrorWithDiagnosis
|
|
31
|
+
} from "../utils/debugLogger.js";
|
|
32
|
+
import { getModelManager } from "../utils/model.js";
|
|
33
|
+
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
34
|
+
import { ModelAdapterFactory } from "./modelAdapterFactory.js";
|
|
35
|
+
import { responseStateManager, getConversationId } from "./responseStateManager.js";
|
|
36
|
+
import { USE_BEDROCK, USE_VERTEX } from "../utils/model.js";
|
|
37
|
+
import { getCLISyspromptPrefix } from "../constants/prompts.js";
|
|
38
|
+
import { getVertexRegionForModel } from "../utils/model.js";
|
|
39
|
+
import { nanoid } from "nanoid";
|
|
40
|
+
import { getCompletionWithProfile, getGPT5CompletionWithProfile } from "./openai.js";
|
|
41
|
+
import { getReasoningEffort } from "../utils/thinking.js";
|
|
42
|
+
import { generateSystemReminders } from "./systemReminder.js";
|
|
43
|
+
function isGPT5Model(modelName) {
|
|
44
|
+
return modelName.startsWith("gpt-5");
|
|
45
|
+
}
|
|
46
|
+
function getModelConfigForDebug(model) {
|
|
47
|
+
const config = getGlobalConfig();
|
|
48
|
+
const modelManager = getModelManager();
|
|
49
|
+
const modelProfile = modelManager.getModel("main");
|
|
50
|
+
let apiKeyStatus = "missing";
|
|
51
|
+
let baseURL;
|
|
52
|
+
let maxTokens;
|
|
53
|
+
let reasoningEffort;
|
|
54
|
+
if (modelProfile) {
|
|
55
|
+
apiKeyStatus = modelProfile.apiKey ? "configured" : "missing";
|
|
56
|
+
baseURL = modelProfile.baseURL;
|
|
57
|
+
maxTokens = modelProfile.maxTokens;
|
|
58
|
+
reasoningEffort = modelProfile.reasoningEffort;
|
|
59
|
+
} else {
|
|
60
|
+
apiKeyStatus = "missing";
|
|
61
|
+
maxTokens = void 0;
|
|
62
|
+
reasoningEffort = void 0;
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
modelName: model,
|
|
66
|
+
provider: modelProfile?.provider || config.primaryProvider || "anthropic",
|
|
67
|
+
apiKeyStatus,
|
|
68
|
+
baseURL,
|
|
69
|
+
maxTokens,
|
|
70
|
+
reasoningEffort,
|
|
71
|
+
isStream: config.stream || false,
|
|
72
|
+
temperature: MAIN_QUERY_TEMPERATURE
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
class KodeContextManager {
|
|
76
|
+
static instance;
|
|
77
|
+
projectDocsCache = "";
|
|
78
|
+
cacheInitialized = false;
|
|
79
|
+
initPromise = null;
|
|
80
|
+
constructor() {
|
|
81
|
+
}
|
|
82
|
+
static getInstance() {
|
|
83
|
+
if (!KodeContextManager.instance) {
|
|
84
|
+
KodeContextManager.instance = new KodeContextManager();
|
|
85
|
+
}
|
|
86
|
+
return KodeContextManager.instance;
|
|
87
|
+
}
|
|
88
|
+
async initialize() {
|
|
89
|
+
if (this.cacheInitialized) return;
|
|
90
|
+
if (this.initPromise) {
|
|
91
|
+
return this.initPromise;
|
|
92
|
+
}
|
|
93
|
+
this.initPromise = this.loadProjectDocs();
|
|
94
|
+
await this.initPromise;
|
|
95
|
+
}
|
|
96
|
+
async loadProjectDocs() {
|
|
97
|
+
try {
|
|
98
|
+
const projectDocs = await getProjectDocs();
|
|
99
|
+
this.projectDocsCache = projectDocs || "";
|
|
100
|
+
this.cacheInitialized = true;
|
|
101
|
+
if (process.env.NODE_ENV === "development") {
|
|
102
|
+
console.log(
|
|
103
|
+
`[KodeContext] Loaded ${this.projectDocsCache.length} characters from project docs`
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.warn("[KodeContext] Failed to load project docs:", error);
|
|
108
|
+
this.projectDocsCache = "";
|
|
109
|
+
this.cacheInitialized = true;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
getKodeContext() {
|
|
113
|
+
if (!this.cacheInitialized) {
|
|
114
|
+
this.initialize().catch(console.warn);
|
|
115
|
+
return "";
|
|
116
|
+
}
|
|
117
|
+
return this.projectDocsCache;
|
|
118
|
+
}
|
|
119
|
+
async refreshCache() {
|
|
120
|
+
this.cacheInitialized = false;
|
|
121
|
+
this.initPromise = null;
|
|
122
|
+
await this.initialize();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const kodeContextManager = KodeContextManager.getInstance();
|
|
126
|
+
kodeContextManager.initialize().catch(console.warn);
|
|
127
|
+
const generateKodeContext = () => {
|
|
128
|
+
return kodeContextManager.getKodeContext();
|
|
129
|
+
};
|
|
130
|
+
const refreshKodeContext = async () => {
|
|
131
|
+
await kodeContextManager.refreshCache();
|
|
132
|
+
};
|
|
133
|
+
const API_ERROR_MESSAGE_PREFIX = "API Error";
|
|
134
|
+
const PROMPT_TOO_LONG_ERROR_MESSAGE = "Prompt is too long";
|
|
135
|
+
const CREDIT_BALANCE_TOO_LOW_ERROR_MESSAGE = "Credit balance is too low";
|
|
136
|
+
const INVALID_API_KEY_ERROR_MESSAGE = "Invalid API key \xB7 Please run /login";
|
|
137
|
+
const NO_CONTENT_MESSAGE = "(no content)";
|
|
138
|
+
const PROMPT_CACHING_ENABLED = !process.env.DISABLE_PROMPT_CACHING;
|
|
139
|
+
const HAIKU_COST_PER_MILLION_INPUT_TOKENS = 0.8;
|
|
140
|
+
const HAIKU_COST_PER_MILLION_OUTPUT_TOKENS = 4;
|
|
141
|
+
const HAIKU_COST_PER_MILLION_PROMPT_CACHE_WRITE_TOKENS = 1;
|
|
142
|
+
const HAIKU_COST_PER_MILLION_PROMPT_CACHE_READ_TOKENS = 0.08;
|
|
143
|
+
const SONNET_COST_PER_MILLION_INPUT_TOKENS = 3;
|
|
144
|
+
const SONNET_COST_PER_MILLION_OUTPUT_TOKENS = 15;
|
|
145
|
+
const SONNET_COST_PER_MILLION_PROMPT_CACHE_WRITE_TOKENS = 3.75;
|
|
146
|
+
const SONNET_COST_PER_MILLION_PROMPT_CACHE_READ_TOKENS = 0.3;
|
|
147
|
+
const MAIN_QUERY_TEMPERATURE = 1;
|
|
148
|
+
function getMetadata() {
|
|
149
|
+
return {
|
|
150
|
+
user_id: `${getOrCreateUserID()}_${SESSION_ID}`
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
const MAX_RETRIES = process.env.USER_TYPE === "SWE_BENCH" ? 100 : 10;
|
|
154
|
+
const BASE_DELAY_MS = 500;
|
|
155
|
+
function abortableDelay(delayMs, signal) {
|
|
156
|
+
return new Promise((resolve, reject) => {
|
|
157
|
+
if (signal?.aborted) {
|
|
158
|
+
reject(new Error("Request was aborted"));
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const timeoutId = setTimeout(() => {
|
|
162
|
+
resolve();
|
|
163
|
+
}, delayMs);
|
|
164
|
+
if (signal) {
|
|
165
|
+
const abortHandler = () => {
|
|
166
|
+
clearTimeout(timeoutId);
|
|
167
|
+
reject(new Error("Request was aborted"));
|
|
168
|
+
};
|
|
169
|
+
signal.addEventListener("abort", abortHandler, { once: true });
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
function getRetryDelay(attempt, retryAfterHeader) {
|
|
174
|
+
if (retryAfterHeader) {
|
|
175
|
+
const seconds = parseInt(retryAfterHeader, 10);
|
|
176
|
+
if (!isNaN(seconds)) {
|
|
177
|
+
return seconds * 1e3;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return Math.min(BASE_DELAY_MS * Math.pow(2, attempt - 1), 32e3);
|
|
181
|
+
}
|
|
182
|
+
function shouldRetry(error) {
|
|
183
|
+
if (error.message?.includes('"type":"overloaded_error"')) {
|
|
184
|
+
return process.env.USER_TYPE === "SWE_BENCH";
|
|
185
|
+
}
|
|
186
|
+
const shouldRetryHeader = error.headers?.["x-should-retry"];
|
|
187
|
+
if (shouldRetryHeader === "true") return true;
|
|
188
|
+
if (shouldRetryHeader === "false") return false;
|
|
189
|
+
if (error instanceof APIConnectionError) {
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
if (!error.status) return false;
|
|
193
|
+
if (error.status === 408) return true;
|
|
194
|
+
if (error.status === 409) return true;
|
|
195
|
+
if (error.status === 429) return true;
|
|
196
|
+
if (error.status && error.status >= 500) return true;
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
async function withRetry(operation, options = {}) {
|
|
200
|
+
const maxRetries = options.maxRetries ?? MAX_RETRIES;
|
|
201
|
+
let lastError;
|
|
202
|
+
for (let attempt = 1; attempt <= maxRetries + 1; attempt++) {
|
|
203
|
+
try {
|
|
204
|
+
return await operation(attempt);
|
|
205
|
+
} catch (error) {
|
|
206
|
+
lastError = error;
|
|
207
|
+
if (attempt > maxRetries || !(error instanceof APIError) || !shouldRetry(error)) {
|
|
208
|
+
throw error;
|
|
209
|
+
}
|
|
210
|
+
if (options.signal?.aborted) {
|
|
211
|
+
throw new Error("Request cancelled by user");
|
|
212
|
+
}
|
|
213
|
+
const retryAfter = error.headers?.["retry-after"] ?? null;
|
|
214
|
+
const delayMs = getRetryDelay(attempt, retryAfter);
|
|
215
|
+
console.log(
|
|
216
|
+
` \u23BF ${chalk.red(`API ${error.name} (${error.message}) \xB7 Retrying in ${Math.round(delayMs / 1e3)} seconds\u2026 (attempt ${attempt}/${maxRetries})`)}`
|
|
217
|
+
);
|
|
218
|
+
logEvent("tengu_api_retry", {
|
|
219
|
+
attempt: String(attempt),
|
|
220
|
+
delayMs: String(delayMs),
|
|
221
|
+
error: error.message,
|
|
222
|
+
status: String(error.status),
|
|
223
|
+
provider: USE_BEDROCK ? "bedrock" : USE_VERTEX ? "vertex" : "1p"
|
|
224
|
+
});
|
|
225
|
+
try {
|
|
226
|
+
await abortableDelay(delayMs, options.signal);
|
|
227
|
+
} catch (delayError) {
|
|
228
|
+
if (delayError.message === "Request was aborted") {
|
|
229
|
+
throw new Error("Request cancelled by user");
|
|
230
|
+
}
|
|
231
|
+
throw delayError;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
throw lastError;
|
|
236
|
+
}
|
|
237
|
+
async function fetchAnthropicModels(baseURL, apiKey) {
|
|
238
|
+
try {
|
|
239
|
+
const modelsURL = baseURL ? `${baseURL.replace(/\/+$/, "")}/v1/models` : "https://api.anthropic.com/v1/models";
|
|
240
|
+
const response = await fetch(modelsURL, {
|
|
241
|
+
method: "GET",
|
|
242
|
+
headers: {
|
|
243
|
+
"x-api-key": apiKey,
|
|
244
|
+
"anthropic-version": "2023-06-01",
|
|
245
|
+
"User-Agent": USER_AGENT
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
if (!response.ok) {
|
|
249
|
+
if (response.status === 401) {
|
|
250
|
+
throw new Error(
|
|
251
|
+
"Invalid API key. Please check your Anthropic API key and try again."
|
|
252
|
+
);
|
|
253
|
+
} else if (response.status === 403) {
|
|
254
|
+
throw new Error(
|
|
255
|
+
"API key does not have permission to access models. Please check your API key permissions."
|
|
256
|
+
);
|
|
257
|
+
} else if (response.status === 429) {
|
|
258
|
+
throw new Error(
|
|
259
|
+
"Too many requests. Please wait a moment and try again."
|
|
260
|
+
);
|
|
261
|
+
} else if (response.status >= 500) {
|
|
262
|
+
throw new Error(
|
|
263
|
+
"Anthropic service is temporarily unavailable. Please try again later."
|
|
264
|
+
);
|
|
265
|
+
} else {
|
|
266
|
+
throw new Error(
|
|
267
|
+
`Unable to connect to Anthropic API (${response.status}). Please check your internet connection and API key.`
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
const data = await response.json();
|
|
272
|
+
return data.data || [];
|
|
273
|
+
} catch (error) {
|
|
274
|
+
if (error instanceof Error && error.message.includes("API key") || error instanceof Error && error.message.includes("Anthropic")) {
|
|
275
|
+
throw error;
|
|
276
|
+
}
|
|
277
|
+
console.error("Failed to fetch Anthropic models:", error);
|
|
278
|
+
throw new Error(
|
|
279
|
+
"Unable to connect to Anthropic API. Please check your internet connection and try again."
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
async function verifyApiKey(apiKey, baseURL, provider) {
|
|
284
|
+
if (!apiKey) {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
if (provider && provider !== "anthropic") {
|
|
288
|
+
try {
|
|
289
|
+
const headers = {
|
|
290
|
+
Authorization: `Bearer ${apiKey}`,
|
|
291
|
+
"Content-Type": "application/json"
|
|
292
|
+
};
|
|
293
|
+
if (!baseURL) {
|
|
294
|
+
console.warn(
|
|
295
|
+
"No baseURL provided for non-Anthropic provider verification"
|
|
296
|
+
);
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
const modelsURL = `${baseURL.replace(/\/+$/, "")}/models`;
|
|
300
|
+
const response = await fetch(modelsURL, {
|
|
301
|
+
method: "GET",
|
|
302
|
+
headers
|
|
303
|
+
});
|
|
304
|
+
return response.ok;
|
|
305
|
+
} catch (error) {
|
|
306
|
+
console.warn("API verification failed for non-Anthropic provider:", error);
|
|
307
|
+
return false;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
const clientConfig = {
|
|
311
|
+
apiKey,
|
|
312
|
+
dangerouslyAllowBrowser: true,
|
|
313
|
+
maxRetries: 3,
|
|
314
|
+
defaultHeaders: {
|
|
315
|
+
"User-Agent": USER_AGENT
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
if (baseURL && (provider === "anthropic" || provider === "bigdream" || provider === "opendev")) {
|
|
319
|
+
clientConfig.baseURL = baseURL;
|
|
320
|
+
}
|
|
321
|
+
const anthropic = new Anthropic(clientConfig);
|
|
322
|
+
try {
|
|
323
|
+
await withRetry(
|
|
324
|
+
async () => {
|
|
325
|
+
const model = "claude-sonnet-4-20250514";
|
|
326
|
+
const messages = [{ role: "user", content: "test" }];
|
|
327
|
+
await anthropic.messages.create({
|
|
328
|
+
model,
|
|
329
|
+
max_tokens: 1e3,
|
|
330
|
+
// Simple test token limit for API verification
|
|
331
|
+
messages,
|
|
332
|
+
temperature: 0,
|
|
333
|
+
metadata: getMetadata()
|
|
334
|
+
});
|
|
335
|
+
return true;
|
|
336
|
+
},
|
|
337
|
+
{ maxRetries: 2 }
|
|
338
|
+
// Use fewer retries for API key verification
|
|
339
|
+
);
|
|
340
|
+
return true;
|
|
341
|
+
} catch (error) {
|
|
342
|
+
logError(error);
|
|
343
|
+
if (error instanceof Error && error.message.includes(
|
|
344
|
+
'{"type":"error","error":{"type":"authentication_error","message":"invalid x-api-key"}}'
|
|
345
|
+
)) {
|
|
346
|
+
return false;
|
|
347
|
+
}
|
|
348
|
+
throw error;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
function convertAnthropicMessagesToOpenAIMessages(messages) {
|
|
352
|
+
const openaiMessages = [];
|
|
353
|
+
const toolResults = {};
|
|
354
|
+
for (const message of messages) {
|
|
355
|
+
let contentBlocks = [];
|
|
356
|
+
if (typeof message.message.content === "string") {
|
|
357
|
+
contentBlocks = [
|
|
358
|
+
{
|
|
359
|
+
type: "text",
|
|
360
|
+
text: message.message.content
|
|
361
|
+
}
|
|
362
|
+
];
|
|
363
|
+
} else if (!Array.isArray(message.message.content)) {
|
|
364
|
+
contentBlocks = [message.message.content];
|
|
365
|
+
} else {
|
|
366
|
+
contentBlocks = message.message.content;
|
|
367
|
+
}
|
|
368
|
+
for (const block of contentBlocks) {
|
|
369
|
+
if (block.type === "text") {
|
|
370
|
+
openaiMessages.push({
|
|
371
|
+
role: message.message.role,
|
|
372
|
+
content: block.text
|
|
373
|
+
});
|
|
374
|
+
} else if (block.type === "tool_use") {
|
|
375
|
+
openaiMessages.push({
|
|
376
|
+
role: "assistant",
|
|
377
|
+
content: void 0,
|
|
378
|
+
tool_calls: [
|
|
379
|
+
{
|
|
380
|
+
type: "function",
|
|
381
|
+
function: {
|
|
382
|
+
name: block.name,
|
|
383
|
+
arguments: JSON.stringify(block.input)
|
|
384
|
+
},
|
|
385
|
+
id: block.id
|
|
386
|
+
}
|
|
387
|
+
]
|
|
388
|
+
});
|
|
389
|
+
} else if (block.type === "tool_result") {
|
|
390
|
+
let toolContent = block.content;
|
|
391
|
+
if (typeof toolContent !== "string") {
|
|
392
|
+
toolContent = JSON.stringify(toolContent);
|
|
393
|
+
}
|
|
394
|
+
toolResults[block.tool_use_id] = {
|
|
395
|
+
role: "tool",
|
|
396
|
+
content: toolContent,
|
|
397
|
+
tool_call_id: block.tool_use_id
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
const finalMessages = [];
|
|
403
|
+
for (const message of openaiMessages) {
|
|
404
|
+
finalMessages.push(message);
|
|
405
|
+
if ("tool_calls" in message && message.tool_calls) {
|
|
406
|
+
for (const toolCall of message.tool_calls) {
|
|
407
|
+
if (toolResults[toolCall.id]) {
|
|
408
|
+
finalMessages.push(toolResults[toolCall.id]);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
return finalMessages;
|
|
414
|
+
}
|
|
415
|
+
function messageReducer(previous, item) {
|
|
416
|
+
const reduce = (acc, delta) => {
|
|
417
|
+
acc = { ...acc };
|
|
418
|
+
for (const [key, value] of Object.entries(delta)) {
|
|
419
|
+
if (acc[key] === void 0 || acc[key] === null) {
|
|
420
|
+
acc[key] = value;
|
|
421
|
+
if (Array.isArray(acc[key])) {
|
|
422
|
+
for (const arr of acc[key]) {
|
|
423
|
+
delete arr.index;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
} else if (typeof acc[key] === "string" && typeof value === "string") {
|
|
427
|
+
acc[key] += value;
|
|
428
|
+
} else if (typeof acc[key] === "number" && typeof value === "number") {
|
|
429
|
+
acc[key] = value;
|
|
430
|
+
} else if (Array.isArray(acc[key]) && Array.isArray(value)) {
|
|
431
|
+
const accArray = acc[key];
|
|
432
|
+
for (let i = 0; i < value.length; i++) {
|
|
433
|
+
const { index, ...chunkTool } = value[i];
|
|
434
|
+
if (index - accArray.length > 1) {
|
|
435
|
+
throw new Error(
|
|
436
|
+
`Error: An array has an empty value when tool_calls are constructed. tool_calls: ${accArray}; tool: ${value}`
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
accArray[index] = reduce(accArray[index], chunkTool);
|
|
440
|
+
}
|
|
441
|
+
} else if (typeof acc[key] === "object" && typeof value === "object") {
|
|
442
|
+
acc[key] = reduce(acc[key], value);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
return acc;
|
|
446
|
+
};
|
|
447
|
+
const choice = item.choices?.[0];
|
|
448
|
+
if (!choice) {
|
|
449
|
+
return previous;
|
|
450
|
+
}
|
|
451
|
+
return reduce(previous, choice.delta);
|
|
452
|
+
}
|
|
453
|
+
async function handleMessageStream(stream, signal) {
|
|
454
|
+
const streamStartTime = Date.now();
|
|
455
|
+
let ttftMs;
|
|
456
|
+
let chunkCount = 0;
|
|
457
|
+
let errorCount = 0;
|
|
458
|
+
debugLogger.api("OPENAI_STREAM_START", {
|
|
459
|
+
streamStartTime: String(streamStartTime)
|
|
460
|
+
});
|
|
461
|
+
let message = {};
|
|
462
|
+
let id, model, created, object, usage;
|
|
463
|
+
try {
|
|
464
|
+
for await (const chunk of stream) {
|
|
465
|
+
if (signal?.aborted) {
|
|
466
|
+
debugLogger.flow("OPENAI_STREAM_ABORTED", {
|
|
467
|
+
chunkCount,
|
|
468
|
+
timestamp: Date.now()
|
|
469
|
+
});
|
|
470
|
+
throw new Error("Request was cancelled");
|
|
471
|
+
}
|
|
472
|
+
chunkCount++;
|
|
473
|
+
try {
|
|
474
|
+
if (!id) {
|
|
475
|
+
id = chunk.id;
|
|
476
|
+
debugLogger.api("OPENAI_STREAM_ID_RECEIVED", {
|
|
477
|
+
id,
|
|
478
|
+
chunkNumber: String(chunkCount)
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
if (!model) {
|
|
482
|
+
model = chunk.model;
|
|
483
|
+
debugLogger.api("OPENAI_STREAM_MODEL_RECEIVED", {
|
|
484
|
+
model,
|
|
485
|
+
chunkNumber: String(chunkCount)
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
if (!created) {
|
|
489
|
+
created = chunk.created;
|
|
490
|
+
}
|
|
491
|
+
if (!object) {
|
|
492
|
+
object = chunk.object;
|
|
493
|
+
}
|
|
494
|
+
if (!usage) {
|
|
495
|
+
usage = chunk.usage;
|
|
496
|
+
}
|
|
497
|
+
message = messageReducer(message, chunk);
|
|
498
|
+
if (chunk?.choices?.[0]?.delta?.content) {
|
|
499
|
+
if (!ttftMs) {
|
|
500
|
+
ttftMs = Date.now() - streamStartTime;
|
|
501
|
+
debugLogger.api("OPENAI_STREAM_FIRST_TOKEN", {
|
|
502
|
+
ttftMs: String(ttftMs),
|
|
503
|
+
chunkNumber: String(chunkCount)
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
} catch (chunkError) {
|
|
508
|
+
errorCount++;
|
|
509
|
+
debugLogger.error("OPENAI_STREAM_CHUNK_ERROR", {
|
|
510
|
+
chunkNumber: String(chunkCount),
|
|
511
|
+
errorMessage: chunkError instanceof Error ? chunkError.message : String(chunkError),
|
|
512
|
+
errorType: chunkError instanceof Error ? chunkError.constructor.name : typeof chunkError
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
debugLogger.api("OPENAI_STREAM_COMPLETE", {
|
|
517
|
+
totalChunks: String(chunkCount),
|
|
518
|
+
errorCount: String(errorCount),
|
|
519
|
+
totalDuration: String(Date.now() - streamStartTime),
|
|
520
|
+
ttftMs: String(ttftMs || 0),
|
|
521
|
+
finalMessageId: id || "undefined"
|
|
522
|
+
});
|
|
523
|
+
} catch (streamError) {
|
|
524
|
+
debugLogger.error("OPENAI_STREAM_FATAL_ERROR", {
|
|
525
|
+
totalChunks: String(chunkCount),
|
|
526
|
+
errorCount: String(errorCount),
|
|
527
|
+
errorMessage: streamError instanceof Error ? streamError.message : String(streamError),
|
|
528
|
+
errorType: streamError instanceof Error ? streamError.constructor.name : typeof streamError
|
|
529
|
+
});
|
|
530
|
+
throw streamError;
|
|
531
|
+
}
|
|
532
|
+
return {
|
|
533
|
+
id,
|
|
534
|
+
created,
|
|
535
|
+
model,
|
|
536
|
+
object,
|
|
537
|
+
choices: [
|
|
538
|
+
{
|
|
539
|
+
index: 0,
|
|
540
|
+
message,
|
|
541
|
+
finish_reason: "stop",
|
|
542
|
+
logprobs: void 0
|
|
543
|
+
}
|
|
544
|
+
],
|
|
545
|
+
usage
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
function convertOpenAIResponseToAnthropic(response, tools) {
|
|
549
|
+
let contentBlocks = [];
|
|
550
|
+
const message = response.choices?.[0]?.message;
|
|
551
|
+
if (!message) {
|
|
552
|
+
logEvent("weird_response", {
|
|
553
|
+
response: JSON.stringify(response)
|
|
554
|
+
});
|
|
555
|
+
return {
|
|
556
|
+
role: "assistant",
|
|
557
|
+
content: [],
|
|
558
|
+
stop_reason: response.choices?.[0]?.finish_reason,
|
|
559
|
+
type: "message",
|
|
560
|
+
usage: response.usage
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
if (message?.tool_calls) {
|
|
564
|
+
for (const toolCall of message.tool_calls) {
|
|
565
|
+
const tool = toolCall.function;
|
|
566
|
+
const toolName = tool?.name;
|
|
567
|
+
let toolArgs = {};
|
|
568
|
+
try {
|
|
569
|
+
toolArgs = tool?.arguments ? JSON.parse(tool.arguments) : {};
|
|
570
|
+
} catch (e) {
|
|
571
|
+
}
|
|
572
|
+
contentBlocks.push({
|
|
573
|
+
type: "tool_use",
|
|
574
|
+
input: toolArgs,
|
|
575
|
+
name: toolName,
|
|
576
|
+
id: toolCall.id?.length > 0 ? toolCall.id : nanoid()
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
if (message.reasoning) {
|
|
581
|
+
contentBlocks.push({
|
|
582
|
+
type: "thinking",
|
|
583
|
+
thinking: message.reasoning,
|
|
584
|
+
signature: ""
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
if (message.reasoning_content) {
|
|
588
|
+
contentBlocks.push({
|
|
589
|
+
type: "thinking",
|
|
590
|
+
thinking: message.reasoning_content,
|
|
591
|
+
signature: ""
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
if (message.content) {
|
|
595
|
+
contentBlocks.push({
|
|
596
|
+
type: "text",
|
|
597
|
+
text: message?.content,
|
|
598
|
+
citations: []
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
const finalMessage = {
|
|
602
|
+
role: "assistant",
|
|
603
|
+
content: contentBlocks,
|
|
604
|
+
stop_reason: response.choices?.[0]?.finish_reason,
|
|
605
|
+
type: "message",
|
|
606
|
+
usage: response.usage
|
|
607
|
+
};
|
|
608
|
+
return finalMessage;
|
|
609
|
+
}
|
|
610
|
+
let anthropicClient = null;
|
|
611
|
+
function getAnthropicClient(model) {
|
|
612
|
+
const config = getGlobalConfig();
|
|
613
|
+
const provider = config.primaryProvider;
|
|
614
|
+
if (anthropicClient && provider) {
|
|
615
|
+
anthropicClient = null;
|
|
616
|
+
}
|
|
617
|
+
if (anthropicClient) {
|
|
618
|
+
return anthropicClient;
|
|
619
|
+
}
|
|
620
|
+
const region = getVertexRegionForModel(model);
|
|
621
|
+
const defaultHeaders = {
|
|
622
|
+
"x-app": "cli",
|
|
623
|
+
"User-Agent": USER_AGENT
|
|
624
|
+
};
|
|
625
|
+
if (process.env.ANTHROPIC_AUTH_TOKEN) {
|
|
626
|
+
defaultHeaders["Authorization"] = `Bearer ${process.env.ANTHROPIC_AUTH_TOKEN}`;
|
|
627
|
+
}
|
|
628
|
+
const ARGS = {
|
|
629
|
+
defaultHeaders,
|
|
630
|
+
maxRetries: 0,
|
|
631
|
+
// Disabled auto-retry in favor of manual implementation
|
|
632
|
+
timeout: parseInt(process.env.API_TIMEOUT_MS || String(60 * 1e3), 10)
|
|
633
|
+
};
|
|
634
|
+
if (USE_BEDROCK) {
|
|
635
|
+
const client = new AnthropicBedrock(ARGS);
|
|
636
|
+
anthropicClient = client;
|
|
637
|
+
return client;
|
|
638
|
+
}
|
|
639
|
+
if (USE_VERTEX) {
|
|
640
|
+
const vertexArgs = {
|
|
641
|
+
...ARGS,
|
|
642
|
+
region: region || process.env.CLOUD_ML_REGION || "us-east5"
|
|
643
|
+
};
|
|
644
|
+
const client = new AnthropicVertex(vertexArgs);
|
|
645
|
+
anthropicClient = client;
|
|
646
|
+
return client;
|
|
647
|
+
}
|
|
648
|
+
const modelManager = getModelManager();
|
|
649
|
+
const modelProfile = modelManager.getModel("main");
|
|
650
|
+
let apiKey;
|
|
651
|
+
let baseURL;
|
|
652
|
+
if (modelProfile) {
|
|
653
|
+
apiKey = modelProfile.apiKey || "";
|
|
654
|
+
baseURL = modelProfile.baseURL;
|
|
655
|
+
} else {
|
|
656
|
+
apiKey = getAnthropicApiKey();
|
|
657
|
+
baseURL = void 0;
|
|
658
|
+
}
|
|
659
|
+
if (process.env.USER_TYPE === "ant" && !apiKey && provider === "anthropic") {
|
|
660
|
+
console.error(
|
|
661
|
+
chalk.red(
|
|
662
|
+
"[ANT-ONLY] Please set the ANTHROPIC_API_KEY environment variable to use the CLI. To create a new key, go to https://console.anthropic.com/settings/keys."
|
|
663
|
+
)
|
|
664
|
+
);
|
|
665
|
+
}
|
|
666
|
+
const clientConfig = {
|
|
667
|
+
apiKey,
|
|
668
|
+
dangerouslyAllowBrowser: true,
|
|
669
|
+
...ARGS,
|
|
670
|
+
...baseURL && { baseURL }
|
|
671
|
+
// Use baseURL directly, SDK will handle API versioning
|
|
672
|
+
};
|
|
673
|
+
anthropicClient = new Anthropic(clientConfig);
|
|
674
|
+
return anthropicClient;
|
|
675
|
+
}
|
|
676
|
+
function resetAnthropicClient() {
|
|
677
|
+
anthropicClient = null;
|
|
678
|
+
}
|
|
679
|
+
function applyCacheControlWithLimits(systemBlocks, messageParams) {
|
|
680
|
+
if (!PROMPT_CACHING_ENABLED) {
|
|
681
|
+
return { systemBlocks, messageParams };
|
|
682
|
+
}
|
|
683
|
+
const maxCacheBlocks = 4;
|
|
684
|
+
let usedCacheBlocks = 0;
|
|
685
|
+
const processedSystemBlocks = systemBlocks.map((block, index) => {
|
|
686
|
+
if (usedCacheBlocks < maxCacheBlocks && block.text.length > 1e3) {
|
|
687
|
+
usedCacheBlocks++;
|
|
688
|
+
return {
|
|
689
|
+
...block,
|
|
690
|
+
cache_control: { type: "ephemeral" }
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
const { cache_control, ...blockWithoutCache } = block;
|
|
694
|
+
return blockWithoutCache;
|
|
695
|
+
});
|
|
696
|
+
const processedMessageParams = messageParams.map((message, messageIndex) => {
|
|
697
|
+
if (Array.isArray(message.content)) {
|
|
698
|
+
const processedContent = message.content.map((contentBlock, blockIndex) => {
|
|
699
|
+
const shouldCache = usedCacheBlocks < maxCacheBlocks && contentBlock.type === "text" && typeof contentBlock.text === "string" && // Long documents (over 2000 characters)
|
|
700
|
+
(contentBlock.text.length > 2e3 || // Last content block of the last message (may be important context)
|
|
701
|
+
messageIndex === messageParams.length - 1 && blockIndex === message.content.length - 1 && contentBlock.text.length > 500);
|
|
702
|
+
if (shouldCache) {
|
|
703
|
+
usedCacheBlocks++;
|
|
704
|
+
return {
|
|
705
|
+
...contentBlock,
|
|
706
|
+
cache_control: { type: "ephemeral" }
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
const { cache_control, ...blockWithoutCache } = contentBlock;
|
|
710
|
+
return blockWithoutCache;
|
|
711
|
+
});
|
|
712
|
+
return {
|
|
713
|
+
...message,
|
|
714
|
+
content: processedContent
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
return message;
|
|
718
|
+
});
|
|
719
|
+
return {
|
|
720
|
+
systemBlocks: processedSystemBlocks,
|
|
721
|
+
messageParams: processedMessageParams
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
function userMessageToMessageParam(message, addCache = false) {
|
|
725
|
+
if (addCache) {
|
|
726
|
+
if (typeof message.message.content === "string") {
|
|
727
|
+
return {
|
|
728
|
+
role: "user",
|
|
729
|
+
content: [
|
|
730
|
+
{
|
|
731
|
+
type: "text",
|
|
732
|
+
text: message.message.content
|
|
733
|
+
}
|
|
734
|
+
]
|
|
735
|
+
};
|
|
736
|
+
} else {
|
|
737
|
+
return {
|
|
738
|
+
role: "user",
|
|
739
|
+
content: message.message.content.map((_) => ({ ..._ }))
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
return {
|
|
744
|
+
role: "user",
|
|
745
|
+
content: message.message.content
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
function assistantMessageToMessageParam(message, addCache = false) {
|
|
749
|
+
if (addCache) {
|
|
750
|
+
if (typeof message.message.content === "string") {
|
|
751
|
+
return {
|
|
752
|
+
role: "assistant",
|
|
753
|
+
content: [
|
|
754
|
+
{
|
|
755
|
+
type: "text",
|
|
756
|
+
text: message.message.content
|
|
757
|
+
}
|
|
758
|
+
]
|
|
759
|
+
};
|
|
760
|
+
} else {
|
|
761
|
+
return {
|
|
762
|
+
role: "assistant",
|
|
763
|
+
content: message.message.content.map((_) => ({ ..._ }))
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
return {
|
|
768
|
+
role: "assistant",
|
|
769
|
+
content: message.message.content
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
function splitSysPromptPrefix(systemPrompt) {
|
|
773
|
+
const systemPromptFirstBlock = systemPrompt[0] || "";
|
|
774
|
+
const systemPromptRest = systemPrompt.slice(1);
|
|
775
|
+
return [systemPromptFirstBlock, systemPromptRest.join("\n")].filter(Boolean);
|
|
776
|
+
}
|
|
777
|
+
async function queryLLM(messages, systemPrompt, maxThinkingTokens, tools, signal, options) {
|
|
778
|
+
const modelManager = getModelManager();
|
|
779
|
+
const modelResolution = modelManager.resolveModelWithInfo(options.model);
|
|
780
|
+
if (!modelResolution.success || !modelResolution.profile) {
|
|
781
|
+
throw new Error(
|
|
782
|
+
modelResolution.error || `Failed to resolve model: ${options.model}`
|
|
783
|
+
);
|
|
784
|
+
}
|
|
785
|
+
const modelProfile = modelResolution.profile;
|
|
786
|
+
const resolvedModel = modelProfile.modelName;
|
|
787
|
+
const toolUseContext = options.toolUseContext;
|
|
788
|
+
if (toolUseContext && !toolUseContext.responseState) {
|
|
789
|
+
const conversationId = getConversationId(toolUseContext.agentId, toolUseContext.messageId);
|
|
790
|
+
const previousResponseId = responseStateManager.getPreviousResponseId(conversationId);
|
|
791
|
+
toolUseContext.responseState = {
|
|
792
|
+
previousResponseId,
|
|
793
|
+
conversationId
|
|
794
|
+
};
|
|
795
|
+
}
|
|
796
|
+
debugLogger.api("MODEL_RESOLVED", {
|
|
797
|
+
inputParam: options.model,
|
|
798
|
+
resolvedModelName: resolvedModel,
|
|
799
|
+
provider: modelProfile.provider,
|
|
800
|
+
isPointer: ["main", "task", "reasoning", "quick"].includes(options.model),
|
|
801
|
+
hasResponseState: !!toolUseContext?.responseState,
|
|
802
|
+
conversationId: toolUseContext?.responseState?.conversationId,
|
|
803
|
+
requestId: getCurrentRequest()?.id
|
|
804
|
+
});
|
|
805
|
+
const currentRequest = getCurrentRequest();
|
|
806
|
+
debugLogger.api("LLM_REQUEST_START", {
|
|
807
|
+
messageCount: messages.length,
|
|
808
|
+
systemPromptLength: systemPrompt.join(" ").length,
|
|
809
|
+
toolCount: tools.length,
|
|
810
|
+
model: resolvedModel,
|
|
811
|
+
originalModelParam: options.model,
|
|
812
|
+
requestId: getCurrentRequest()?.id
|
|
813
|
+
});
|
|
814
|
+
markPhase("LLM_CALL");
|
|
815
|
+
try {
|
|
816
|
+
const result = await withVCR(
|
|
817
|
+
messages,
|
|
818
|
+
() => queryLLMWithPromptCaching(
|
|
819
|
+
messages,
|
|
820
|
+
systemPrompt,
|
|
821
|
+
maxThinkingTokens,
|
|
822
|
+
tools,
|
|
823
|
+
signal,
|
|
824
|
+
{ ...options, model: resolvedModel, modelProfile, toolUseContext }
|
|
825
|
+
// Pass resolved ModelProfile and toolUseContext
|
|
826
|
+
)
|
|
827
|
+
);
|
|
828
|
+
debugLogger.api("LLM_REQUEST_SUCCESS", {
|
|
829
|
+
costUSD: result.costUSD,
|
|
830
|
+
durationMs: result.durationMs,
|
|
831
|
+
responseLength: result.message.content?.length || 0,
|
|
832
|
+
requestId: getCurrentRequest()?.id
|
|
833
|
+
});
|
|
834
|
+
if (toolUseContext?.responseState?.conversationId && result.responseId) {
|
|
835
|
+
responseStateManager.setPreviousResponseId(
|
|
836
|
+
toolUseContext.responseState.conversationId,
|
|
837
|
+
result.responseId
|
|
838
|
+
);
|
|
839
|
+
debugLogger.api("RESPONSE_STATE_UPDATED", {
|
|
840
|
+
conversationId: toolUseContext.responseState.conversationId,
|
|
841
|
+
responseId: result.responseId,
|
|
842
|
+
requestId: getCurrentRequest()?.id
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
return result;
|
|
846
|
+
} catch (error) {
|
|
847
|
+
logErrorWithDiagnosis(
|
|
848
|
+
error,
|
|
849
|
+
{
|
|
850
|
+
messageCount: messages.length,
|
|
851
|
+
systemPromptLength: systemPrompt.join(" ").length,
|
|
852
|
+
model: options.model,
|
|
853
|
+
toolCount: tools.length,
|
|
854
|
+
phase: "LLM_CALL"
|
|
855
|
+
},
|
|
856
|
+
currentRequest?.id
|
|
857
|
+
);
|
|
858
|
+
throw error;
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
function formatSystemPromptWithContext(systemPrompt, context, agentId, skipContextReminders = false) {
|
|
862
|
+
const enhancedPrompt = [...systemPrompt];
|
|
863
|
+
let reminders = "";
|
|
864
|
+
const modelManager = getModelManager();
|
|
865
|
+
const modelProfile = modelManager.getModel("main");
|
|
866
|
+
if (modelProfile && isGPT5Model(modelProfile.modelName)) {
|
|
867
|
+
const persistencePrompts = [
|
|
868
|
+
"\n# Agent Persistence for Long-Running Coding Tasks",
|
|
869
|
+
"You are working on a coding project that may involve multiple steps and iterations. Please maintain context and continuity throughout the session:",
|
|
870
|
+
"- Remember architectural decisions and design patterns established earlier",
|
|
871
|
+
"- Keep track of file modifications and their relationships",
|
|
872
|
+
"- Maintain awareness of the overall project structure and goals",
|
|
873
|
+
"- Reference previous implementations when making related changes",
|
|
874
|
+
"- Ensure consistency with existing code style and conventions",
|
|
875
|
+
"- Build incrementally on previous work rather than starting from scratch"
|
|
876
|
+
];
|
|
877
|
+
enhancedPrompt.push(...persistencePrompts);
|
|
878
|
+
}
|
|
879
|
+
const hasContext = Object.entries(context).length > 0;
|
|
880
|
+
if (hasContext) {
|
|
881
|
+
if (!skipContextReminders) {
|
|
882
|
+
const kodeContext = generateKodeContext();
|
|
883
|
+
if (kodeContext) {
|
|
884
|
+
enhancedPrompt.push("\n---\n# \u9879\u76EE\u4E0A\u4E0B\u6587\n");
|
|
885
|
+
enhancedPrompt.push(kodeContext);
|
|
886
|
+
enhancedPrompt.push("\n---\n");
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
const reminderMessages = generateSystemReminders(hasContext, agentId);
|
|
890
|
+
if (reminderMessages.length > 0) {
|
|
891
|
+
reminders = reminderMessages.map((r) => r.content).join("\n") + "\n";
|
|
892
|
+
}
|
|
893
|
+
enhancedPrompt.push(
|
|
894
|
+
`
|
|
895
|
+
As you answer the user's questions, you can use the following context:
|
|
896
|
+
`
|
|
897
|
+
);
|
|
898
|
+
const filteredContext = Object.fromEntries(
|
|
899
|
+
Object.entries(context).filter(
|
|
900
|
+
([key]) => key !== "projectDocs" && key !== "userDocs"
|
|
901
|
+
)
|
|
902
|
+
);
|
|
903
|
+
enhancedPrompt.push(
|
|
904
|
+
...Object.entries(filteredContext).map(
|
|
905
|
+
([key, value]) => `<context name="${key}">${value}</context>`
|
|
906
|
+
)
|
|
907
|
+
);
|
|
908
|
+
}
|
|
909
|
+
return { systemPrompt: enhancedPrompt, reminders };
|
|
910
|
+
}
|
|
911
|
+
async function queryLLMWithPromptCaching(messages, systemPrompt, maxThinkingTokens, tools, signal, options) {
|
|
912
|
+
const config = getGlobalConfig();
|
|
913
|
+
const modelManager = getModelManager();
|
|
914
|
+
const toolUseContext = options.toolUseContext;
|
|
915
|
+
const modelProfile = options.modelProfile || modelManager.getModel("main");
|
|
916
|
+
let provider;
|
|
917
|
+
if (modelProfile) {
|
|
918
|
+
provider = modelProfile.provider || config.primaryProvider || "anthropic";
|
|
919
|
+
} else {
|
|
920
|
+
provider = config.primaryProvider || "anthropic";
|
|
921
|
+
}
|
|
922
|
+
if (provider === "anthropic" || provider === "bigdream" || provider === "opendev") {
|
|
923
|
+
return queryAnthropicNative(
|
|
924
|
+
messages,
|
|
925
|
+
systemPrompt,
|
|
926
|
+
maxThinkingTokens,
|
|
927
|
+
tools,
|
|
928
|
+
signal,
|
|
929
|
+
{ ...options, modelProfile, toolUseContext }
|
|
930
|
+
);
|
|
931
|
+
}
|
|
932
|
+
return queryOpenAI(messages, systemPrompt, maxThinkingTokens, tools, signal, {
|
|
933
|
+
...options,
|
|
934
|
+
modelProfile,
|
|
935
|
+
toolUseContext
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
async function queryAnthropicNative(messages, systemPrompt, maxThinkingTokens, tools, signal, options) {
|
|
939
|
+
const config = getGlobalConfig();
|
|
940
|
+
const modelManager = getModelManager();
|
|
941
|
+
const toolUseContext = options?.toolUseContext;
|
|
942
|
+
const modelProfile = options?.modelProfile || modelManager.getModel("main");
|
|
943
|
+
let anthropic;
|
|
944
|
+
let model;
|
|
945
|
+
let provider;
|
|
946
|
+
debugLogger.api("MODEL_CONFIG_ANTHROPIC", {
|
|
947
|
+
modelProfileFound: !!modelProfile,
|
|
948
|
+
modelProfileId: modelProfile?.modelName,
|
|
949
|
+
modelProfileName: modelProfile?.name,
|
|
950
|
+
modelProfileModelName: modelProfile?.modelName,
|
|
951
|
+
modelProfileProvider: modelProfile?.provider,
|
|
952
|
+
modelProfileBaseURL: modelProfile?.baseURL,
|
|
953
|
+
modelProfileApiKeyExists: !!modelProfile?.apiKey,
|
|
954
|
+
optionsModel: options?.model,
|
|
955
|
+
requestId: getCurrentRequest()?.id
|
|
956
|
+
});
|
|
957
|
+
if (modelProfile) {
|
|
958
|
+
model = modelProfile.modelName;
|
|
959
|
+
provider = modelProfile.provider || config.primaryProvider || "anthropic";
|
|
960
|
+
if (modelProfile.provider === "anthropic" || modelProfile.provider === "bigdream" || modelProfile.provider === "opendev") {
|
|
961
|
+
const clientConfig = {
|
|
962
|
+
apiKey: modelProfile.apiKey,
|
|
963
|
+
dangerouslyAllowBrowser: true,
|
|
964
|
+
maxRetries: 0,
|
|
965
|
+
timeout: parseInt(process.env.API_TIMEOUT_MS || String(60 * 1e3), 10),
|
|
966
|
+
defaultHeaders: {
|
|
967
|
+
"x-app": "cli",
|
|
968
|
+
"User-Agent": USER_AGENT
|
|
969
|
+
}
|
|
970
|
+
};
|
|
971
|
+
if (modelProfile.baseURL) {
|
|
972
|
+
clientConfig.baseURL = modelProfile.baseURL;
|
|
973
|
+
}
|
|
974
|
+
anthropic = new Anthropic(clientConfig);
|
|
975
|
+
} else {
|
|
976
|
+
anthropic = getAnthropicClient(model);
|
|
977
|
+
}
|
|
978
|
+
} else {
|
|
979
|
+
const errorDetails = {
|
|
980
|
+
modelProfileExists: !!modelProfile,
|
|
981
|
+
modelProfileModelName: modelProfile?.modelName,
|
|
982
|
+
requestedModel: options?.model,
|
|
983
|
+
requestId: getCurrentRequest()?.id
|
|
984
|
+
};
|
|
985
|
+
debugLogger.error("ANTHROPIC_FALLBACK_ERROR", errorDetails);
|
|
986
|
+
throw new Error(
|
|
987
|
+
`No valid ModelProfile available for Anthropic provider. Please configure model through /model command. Debug: ${JSON.stringify(errorDetails)}`
|
|
988
|
+
);
|
|
989
|
+
}
|
|
990
|
+
if (options?.prependCLISysprompt) {
|
|
991
|
+
const [firstSyspromptBlock] = splitSysPromptPrefix(systemPrompt);
|
|
992
|
+
logEvent("tengu_sysprompt_block", {
|
|
993
|
+
snippet: firstSyspromptBlock?.slice(0, 20),
|
|
994
|
+
length: String(firstSyspromptBlock?.length ?? 0),
|
|
995
|
+
hash: firstSyspromptBlock ? createHash("sha256").update(firstSyspromptBlock).digest("hex") : ""
|
|
996
|
+
});
|
|
997
|
+
systemPrompt = [getCLISyspromptPrefix(), ...systemPrompt];
|
|
998
|
+
}
|
|
999
|
+
const system = splitSysPromptPrefix(systemPrompt).map(
|
|
1000
|
+
(_) => ({
|
|
1001
|
+
text: _,
|
|
1002
|
+
type: "text"
|
|
1003
|
+
})
|
|
1004
|
+
);
|
|
1005
|
+
const toolSchemas = await Promise.all(
|
|
1006
|
+
tools.map(
|
|
1007
|
+
async (tool) => ({
|
|
1008
|
+
name: tool.name,
|
|
1009
|
+
description: typeof tool.description === "function" ? await tool.description() : tool.description,
|
|
1010
|
+
input_schema: zodToJsonSchema(tool.inputSchema)
|
|
1011
|
+
})
|
|
1012
|
+
)
|
|
1013
|
+
);
|
|
1014
|
+
const anthropicMessages = addCacheBreakpoints(messages);
|
|
1015
|
+
const { systemBlocks: processedSystem, messageParams: processedMessages } = applyCacheControlWithLimits(system, anthropicMessages);
|
|
1016
|
+
const startIncludingRetries = Date.now();
|
|
1017
|
+
logSystemPromptConstruction({
|
|
1018
|
+
basePrompt: systemPrompt.join("\n"),
|
|
1019
|
+
kodeContext: generateKodeContext() || "",
|
|
1020
|
+
reminders: [],
|
|
1021
|
+
// 这里可以从 generateSystemReminders 获取
|
|
1022
|
+
finalPrompt: systemPrompt.join("\n")
|
|
1023
|
+
});
|
|
1024
|
+
let start = Date.now();
|
|
1025
|
+
let attemptNumber = 0;
|
|
1026
|
+
let response;
|
|
1027
|
+
try {
|
|
1028
|
+
response = await withRetry(async (attempt) => {
|
|
1029
|
+
attemptNumber = attempt;
|
|
1030
|
+
start = Date.now();
|
|
1031
|
+
const params = {
|
|
1032
|
+
model,
|
|
1033
|
+
max_tokens: getMaxTokensFromProfile(modelProfile),
|
|
1034
|
+
messages: processedMessages,
|
|
1035
|
+
system: processedSystem,
|
|
1036
|
+
tools: toolSchemas.length > 0 ? toolSchemas : void 0,
|
|
1037
|
+
tool_choice: toolSchemas.length > 0 ? { type: "auto" } : void 0
|
|
1038
|
+
};
|
|
1039
|
+
if (maxThinkingTokens > 0) {
|
|
1040
|
+
;
|
|
1041
|
+
params.extra_headers = {
|
|
1042
|
+
"anthropic-beta": "max-tokens-3-5-sonnet-2024-07-15"
|
|
1043
|
+
};
|
|
1044
|
+
params.thinking = { max_tokens: maxThinkingTokens };
|
|
1045
|
+
}
|
|
1046
|
+
debugLogger.api("ANTHROPIC_API_CALL_START_STREAMING", {
|
|
1047
|
+
endpoint: modelProfile?.baseURL || "DEFAULT_ANTHROPIC",
|
|
1048
|
+
model,
|
|
1049
|
+
provider,
|
|
1050
|
+
apiKeyConfigured: !!modelProfile?.apiKey,
|
|
1051
|
+
apiKeyPrefix: modelProfile?.apiKey ? modelProfile.apiKey.substring(0, 8) : null,
|
|
1052
|
+
maxTokens: params.max_tokens,
|
|
1053
|
+
temperature: MAIN_QUERY_TEMPERATURE,
|
|
1054
|
+
params,
|
|
1055
|
+
messageCount: params.messages?.length || 0,
|
|
1056
|
+
streamMode: true,
|
|
1057
|
+
toolsCount: toolSchemas.length,
|
|
1058
|
+
thinkingTokens: maxThinkingTokens,
|
|
1059
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1060
|
+
modelProfileId: modelProfile?.modelName,
|
|
1061
|
+
modelProfileName: modelProfile?.name
|
|
1062
|
+
});
|
|
1063
|
+
if (config.stream) {
|
|
1064
|
+
const stream = await anthropic.beta.messages.create({
|
|
1065
|
+
...params,
|
|
1066
|
+
stream: true
|
|
1067
|
+
}, {
|
|
1068
|
+
signal
|
|
1069
|
+
// ← CRITICAL: Connect the AbortSignal to API call
|
|
1070
|
+
});
|
|
1071
|
+
let finalResponse = null;
|
|
1072
|
+
let messageStartEvent = null;
|
|
1073
|
+
const contentBlocks = [];
|
|
1074
|
+
const inputJSONBuffers = /* @__PURE__ */ new Map();
|
|
1075
|
+
let usage = null;
|
|
1076
|
+
let stopReason = null;
|
|
1077
|
+
let stopSequence = null;
|
|
1078
|
+
for await (const event of stream) {
|
|
1079
|
+
if (signal.aborted) {
|
|
1080
|
+
debugLogger.flow("STREAM_ABORTED", {
|
|
1081
|
+
eventType: event.type,
|
|
1082
|
+
timestamp: Date.now()
|
|
1083
|
+
});
|
|
1084
|
+
throw new Error("Request was cancelled");
|
|
1085
|
+
}
|
|
1086
|
+
switch (event.type) {
|
|
1087
|
+
case "message_start":
|
|
1088
|
+
messageStartEvent = event;
|
|
1089
|
+
finalResponse = {
|
|
1090
|
+
...event.message,
|
|
1091
|
+
content: []
|
|
1092
|
+
// Will be populated from content blocks
|
|
1093
|
+
};
|
|
1094
|
+
break;
|
|
1095
|
+
case "content_block_start":
|
|
1096
|
+
contentBlocks[event.index] = { ...event.content_block };
|
|
1097
|
+
if (event.content_block.type === "tool_use") {
|
|
1098
|
+
inputJSONBuffers.set(event.index, "");
|
|
1099
|
+
}
|
|
1100
|
+
break;
|
|
1101
|
+
case "content_block_delta":
|
|
1102
|
+
const blockIndex = event.index;
|
|
1103
|
+
if (!contentBlocks[blockIndex]) {
|
|
1104
|
+
contentBlocks[blockIndex] = {
|
|
1105
|
+
type: event.delta.type === "text_delta" ? "text" : "tool_use",
|
|
1106
|
+
text: event.delta.type === "text_delta" ? "" : void 0
|
|
1107
|
+
};
|
|
1108
|
+
if (event.delta.type === "input_json_delta") {
|
|
1109
|
+
inputJSONBuffers.set(blockIndex, "");
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
if (event.delta.type === "text_delta") {
|
|
1113
|
+
contentBlocks[blockIndex].text += event.delta.text;
|
|
1114
|
+
} else if (event.delta.type === "input_json_delta") {
|
|
1115
|
+
const currentBuffer = inputJSONBuffers.get(blockIndex) || "";
|
|
1116
|
+
inputJSONBuffers.set(blockIndex, currentBuffer + event.delta.partial_json);
|
|
1117
|
+
}
|
|
1118
|
+
break;
|
|
1119
|
+
case "message_delta":
|
|
1120
|
+
if (event.delta.stop_reason) stopReason = event.delta.stop_reason;
|
|
1121
|
+
if (event.delta.stop_sequence) stopSequence = event.delta.stop_sequence;
|
|
1122
|
+
if (event.usage) usage = { ...usage, ...event.usage };
|
|
1123
|
+
break;
|
|
1124
|
+
case "content_block_stop":
|
|
1125
|
+
const stopIndex = event.index;
|
|
1126
|
+
const block = contentBlocks[stopIndex];
|
|
1127
|
+
if (block?.type === "tool_use" && inputJSONBuffers.has(stopIndex)) {
|
|
1128
|
+
const jsonStr = inputJSONBuffers.get(stopIndex);
|
|
1129
|
+
if (jsonStr) {
|
|
1130
|
+
try {
|
|
1131
|
+
block.input = JSON.parse(jsonStr);
|
|
1132
|
+
} catch (error) {
|
|
1133
|
+
debugLogger.error("JSON_PARSE_ERROR", {
|
|
1134
|
+
blockIndex: stopIndex,
|
|
1135
|
+
jsonStr,
|
|
1136
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1137
|
+
});
|
|
1138
|
+
block.input = {};
|
|
1139
|
+
}
|
|
1140
|
+
inputJSONBuffers.delete(stopIndex);
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
break;
|
|
1144
|
+
case "message_stop":
|
|
1145
|
+
inputJSONBuffers.clear();
|
|
1146
|
+
break;
|
|
1147
|
+
}
|
|
1148
|
+
if (event.type === "message_stop") {
|
|
1149
|
+
break;
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
if (!finalResponse || !messageStartEvent) {
|
|
1153
|
+
throw new Error("Stream ended without proper message structure");
|
|
1154
|
+
}
|
|
1155
|
+
finalResponse = {
|
|
1156
|
+
...messageStartEvent.message,
|
|
1157
|
+
content: contentBlocks.filter(Boolean),
|
|
1158
|
+
stop_reason: stopReason,
|
|
1159
|
+
stop_sequence: stopSequence,
|
|
1160
|
+
usage: {
|
|
1161
|
+
...messageStartEvent.message.usage,
|
|
1162
|
+
...usage
|
|
1163
|
+
}
|
|
1164
|
+
};
|
|
1165
|
+
return finalResponse;
|
|
1166
|
+
} else {
|
|
1167
|
+
debugLogger.api("ANTHROPIC_API_CALL_START_NON_STREAMING", {
|
|
1168
|
+
endpoint: modelProfile?.baseURL || "DEFAULT_ANTHROPIC",
|
|
1169
|
+
model,
|
|
1170
|
+
provider,
|
|
1171
|
+
apiKeyConfigured: !!modelProfile?.apiKey,
|
|
1172
|
+
apiKeyPrefix: modelProfile?.apiKey ? modelProfile.apiKey.substring(0, 8) : null,
|
|
1173
|
+
maxTokens: params.max_tokens,
|
|
1174
|
+
temperature: MAIN_QUERY_TEMPERATURE,
|
|
1175
|
+
messageCount: params.messages?.length || 0,
|
|
1176
|
+
streamMode: false,
|
|
1177
|
+
toolsCount: toolSchemas.length,
|
|
1178
|
+
thinkingTokens: maxThinkingTokens,
|
|
1179
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1180
|
+
modelProfileId: modelProfile?.modelName,
|
|
1181
|
+
modelProfileName: modelProfile?.name
|
|
1182
|
+
});
|
|
1183
|
+
return await anthropic.beta.messages.create(params, {
|
|
1184
|
+
signal
|
|
1185
|
+
// ← CRITICAL: Connect the AbortSignal to API call
|
|
1186
|
+
});
|
|
1187
|
+
}
|
|
1188
|
+
}, { signal });
|
|
1189
|
+
debugLogger.api("ANTHROPIC_API_CALL_SUCCESS", {
|
|
1190
|
+
content: response.content
|
|
1191
|
+
});
|
|
1192
|
+
const ttftMs = start - Date.now();
|
|
1193
|
+
const durationMs = Date.now() - startIncludingRetries;
|
|
1194
|
+
const content = response.content.map((block) => {
|
|
1195
|
+
if (block.type === "text") {
|
|
1196
|
+
return {
|
|
1197
|
+
type: "text",
|
|
1198
|
+
text: block.text
|
|
1199
|
+
};
|
|
1200
|
+
} else if (block.type === "tool_use") {
|
|
1201
|
+
return {
|
|
1202
|
+
type: "tool_use",
|
|
1203
|
+
id: block.id,
|
|
1204
|
+
name: block.name,
|
|
1205
|
+
input: block.input
|
|
1206
|
+
};
|
|
1207
|
+
}
|
|
1208
|
+
return block;
|
|
1209
|
+
});
|
|
1210
|
+
const assistantMessage = {
|
|
1211
|
+
message: {
|
|
1212
|
+
id: response.id,
|
|
1213
|
+
content,
|
|
1214
|
+
model: response.model,
|
|
1215
|
+
role: "assistant",
|
|
1216
|
+
stop_reason: response.stop_reason,
|
|
1217
|
+
stop_sequence: response.stop_sequence,
|
|
1218
|
+
type: "message",
|
|
1219
|
+
usage: response.usage
|
|
1220
|
+
},
|
|
1221
|
+
type: "assistant",
|
|
1222
|
+
uuid: nanoid(),
|
|
1223
|
+
durationMs,
|
|
1224
|
+
costUSD: 0
|
|
1225
|
+
// Will be calculated below
|
|
1226
|
+
};
|
|
1227
|
+
const systemMessages = system.map((block) => ({
|
|
1228
|
+
role: "system",
|
|
1229
|
+
content: block.text
|
|
1230
|
+
}));
|
|
1231
|
+
logLLMInteraction({
|
|
1232
|
+
systemPrompt: systemPrompt.join("\n"),
|
|
1233
|
+
messages: [...systemMessages, ...anthropicMessages],
|
|
1234
|
+
response,
|
|
1235
|
+
usage: response.usage ? {
|
|
1236
|
+
inputTokens: response.usage.input_tokens,
|
|
1237
|
+
outputTokens: response.usage.output_tokens
|
|
1238
|
+
} : void 0,
|
|
1239
|
+
timing: {
|
|
1240
|
+
start,
|
|
1241
|
+
end: Date.now()
|
|
1242
|
+
},
|
|
1243
|
+
apiFormat: "anthropic"
|
|
1244
|
+
});
|
|
1245
|
+
const inputTokens = response.usage.input_tokens;
|
|
1246
|
+
const outputTokens = response.usage.output_tokens;
|
|
1247
|
+
const cacheCreationInputTokens = response.usage.cache_creation_input_tokens ?? 0;
|
|
1248
|
+
const cacheReadInputTokens = response.usage.cache_read_input_tokens ?? 0;
|
|
1249
|
+
const costUSD = inputTokens / 1e6 * getModelInputTokenCostUSD(model) + outputTokens / 1e6 * getModelOutputTokenCostUSD(model) + cacheCreationInputTokens / 1e6 * getModelInputTokenCostUSD(model) + cacheReadInputTokens / 1e6 * (getModelInputTokenCostUSD(model) * 0.1);
|
|
1250
|
+
assistantMessage.costUSD = costUSD;
|
|
1251
|
+
addToTotalCost(costUSD, durationMs);
|
|
1252
|
+
logEvent("api_response_anthropic_native", {
|
|
1253
|
+
model,
|
|
1254
|
+
input_tokens: String(inputTokens),
|
|
1255
|
+
output_tokens: String(outputTokens),
|
|
1256
|
+
cache_creation_input_tokens: String(cacheCreationInputTokens),
|
|
1257
|
+
cache_read_input_tokens: String(cacheReadInputTokens),
|
|
1258
|
+
cost_usd: String(costUSD),
|
|
1259
|
+
duration_ms: String(durationMs),
|
|
1260
|
+
ttft_ms: String(ttftMs),
|
|
1261
|
+
attempt_number: String(attemptNumber)
|
|
1262
|
+
});
|
|
1263
|
+
return assistantMessage;
|
|
1264
|
+
} catch (error) {
|
|
1265
|
+
return getAssistantMessageFromError(error);
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
function getAssistantMessageFromError(error) {
|
|
1269
|
+
if (error instanceof Error && error.message.includes("prompt is too long")) {
|
|
1270
|
+
return createAssistantAPIErrorMessage(PROMPT_TOO_LONG_ERROR_MESSAGE);
|
|
1271
|
+
}
|
|
1272
|
+
if (error instanceof Error && error.message.includes("Your credit balance is too low")) {
|
|
1273
|
+
return createAssistantAPIErrorMessage(CREDIT_BALANCE_TOO_LOW_ERROR_MESSAGE);
|
|
1274
|
+
}
|
|
1275
|
+
if (error instanceof Error && error.message.toLowerCase().includes("x-api-key")) {
|
|
1276
|
+
return createAssistantAPIErrorMessage(INVALID_API_KEY_ERROR_MESSAGE);
|
|
1277
|
+
}
|
|
1278
|
+
if (error instanceof Error) {
|
|
1279
|
+
if (process.env.NODE_ENV === "development") {
|
|
1280
|
+
console.log(error);
|
|
1281
|
+
}
|
|
1282
|
+
return createAssistantAPIErrorMessage(
|
|
1283
|
+
`${API_ERROR_MESSAGE_PREFIX}: ${error.message}`
|
|
1284
|
+
);
|
|
1285
|
+
}
|
|
1286
|
+
return createAssistantAPIErrorMessage(API_ERROR_MESSAGE_PREFIX);
|
|
1287
|
+
}
|
|
1288
|
+
function addCacheBreakpoints(messages) {
|
|
1289
|
+
return messages.map((msg, index) => {
|
|
1290
|
+
return msg.type === "user" ? userMessageToMessageParam(msg, index > messages.length - 3) : assistantMessageToMessageParam(msg, index > messages.length - 3);
|
|
1291
|
+
});
|
|
1292
|
+
}
|
|
1293
|
+
async function queryOpenAI(messages, systemPrompt, maxThinkingTokens, tools, signal, options) {
|
|
1294
|
+
const config = getGlobalConfig();
|
|
1295
|
+
const modelManager = getModelManager();
|
|
1296
|
+
const toolUseContext = options?.toolUseContext;
|
|
1297
|
+
const modelProfile = options?.modelProfile || modelManager.getModel("main");
|
|
1298
|
+
let model;
|
|
1299
|
+
const currentRequest = getCurrentRequest();
|
|
1300
|
+
debugLogger.api("MODEL_CONFIG_OPENAI", {
|
|
1301
|
+
modelProfileFound: !!modelProfile,
|
|
1302
|
+
modelProfileId: modelProfile?.modelName,
|
|
1303
|
+
modelProfileName: modelProfile?.name,
|
|
1304
|
+
modelProfileModelName: modelProfile?.modelName,
|
|
1305
|
+
modelProfileProvider: modelProfile?.provider,
|
|
1306
|
+
modelProfileBaseURL: modelProfile?.baseURL,
|
|
1307
|
+
modelProfileApiKeyExists: !!modelProfile?.apiKey,
|
|
1308
|
+
optionsModel: options?.model,
|
|
1309
|
+
requestId: getCurrentRequest()?.id
|
|
1310
|
+
});
|
|
1311
|
+
if (modelProfile) {
|
|
1312
|
+
model = modelProfile.modelName;
|
|
1313
|
+
} else {
|
|
1314
|
+
model = options?.model || modelProfile?.modelName || "";
|
|
1315
|
+
}
|
|
1316
|
+
if (options?.prependCLISysprompt) {
|
|
1317
|
+
const [firstSyspromptBlock] = splitSysPromptPrefix(systemPrompt);
|
|
1318
|
+
logEvent("tengu_sysprompt_block", {
|
|
1319
|
+
snippet: firstSyspromptBlock?.slice(0, 20),
|
|
1320
|
+
length: String(firstSyspromptBlock?.length ?? 0),
|
|
1321
|
+
hash: firstSyspromptBlock ? createHash("sha256").update(firstSyspromptBlock).digest("hex") : ""
|
|
1322
|
+
});
|
|
1323
|
+
systemPrompt = [getCLISyspromptPrefix() + systemPrompt];
|
|
1324
|
+
}
|
|
1325
|
+
const system = splitSysPromptPrefix(systemPrompt).map(
|
|
1326
|
+
(_) => ({
|
|
1327
|
+
...PROMPT_CACHING_ENABLED ? { cache_control: { type: "ephemeral" } } : {},
|
|
1328
|
+
text: _,
|
|
1329
|
+
type: "text"
|
|
1330
|
+
})
|
|
1331
|
+
);
|
|
1332
|
+
const toolSchemas = await Promise.all(
|
|
1333
|
+
tools.map(
|
|
1334
|
+
async (_) => ({
|
|
1335
|
+
type: "function",
|
|
1336
|
+
function: {
|
|
1337
|
+
name: _.name,
|
|
1338
|
+
description: await _.prompt({
|
|
1339
|
+
safeMode: options?.safeMode
|
|
1340
|
+
}),
|
|
1341
|
+
// Use tool's JSON schema directly if provided, otherwise convert Zod schema
|
|
1342
|
+
parameters: "inputJSONSchema" in _ && _.inputJSONSchema ? _.inputJSONSchema : zodToJsonSchema(_.inputSchema)
|
|
1343
|
+
}
|
|
1344
|
+
})
|
|
1345
|
+
)
|
|
1346
|
+
);
|
|
1347
|
+
const openaiSystem = system.map(
|
|
1348
|
+
(s) => ({
|
|
1349
|
+
role: "system",
|
|
1350
|
+
content: s.text
|
|
1351
|
+
})
|
|
1352
|
+
);
|
|
1353
|
+
const openaiMessages = convertAnthropicMessagesToOpenAIMessages(messages);
|
|
1354
|
+
const startIncludingRetries = Date.now();
|
|
1355
|
+
logSystemPromptConstruction({
|
|
1356
|
+
basePrompt: systemPrompt.join("\n"),
|
|
1357
|
+
kodeContext: generateKodeContext() || "",
|
|
1358
|
+
reminders: [],
|
|
1359
|
+
// 这里可以从 generateSystemReminders 获取
|
|
1360
|
+
finalPrompt: systemPrompt.join("\n")
|
|
1361
|
+
});
|
|
1362
|
+
let start = Date.now();
|
|
1363
|
+
let attemptNumber = 0;
|
|
1364
|
+
let response;
|
|
1365
|
+
try {
|
|
1366
|
+
response = await withRetry(async (attempt) => {
|
|
1367
|
+
attemptNumber = attempt;
|
|
1368
|
+
start = Date.now();
|
|
1369
|
+
const maxTokens = getMaxTokensFromProfile(modelProfile);
|
|
1370
|
+
const isGPT5 = isGPT5Model(model);
|
|
1371
|
+
const opts = {
|
|
1372
|
+
model,
|
|
1373
|
+
...isGPT5 ? { max_completion_tokens: maxTokens } : { max_tokens: maxTokens },
|
|
1374
|
+
messages: [...openaiSystem, ...openaiMessages],
|
|
1375
|
+
temperature: isGPT5 ? 1 : MAIN_QUERY_TEMPERATURE
|
|
1376
|
+
};
|
|
1377
|
+
if (config.stream) {
|
|
1378
|
+
;
|
|
1379
|
+
opts.stream = true;
|
|
1380
|
+
opts.stream_options = {
|
|
1381
|
+
include_usage: true
|
|
1382
|
+
};
|
|
1383
|
+
}
|
|
1384
|
+
if (toolSchemas.length > 0) {
|
|
1385
|
+
opts.tools = toolSchemas;
|
|
1386
|
+
opts.tool_choice = "auto";
|
|
1387
|
+
}
|
|
1388
|
+
const reasoningEffort = await getReasoningEffort(modelProfile, messages);
|
|
1389
|
+
if (reasoningEffort) {
|
|
1390
|
+
logEvent("debug_reasoning_effort", {
|
|
1391
|
+
effort: reasoningEffort
|
|
1392
|
+
});
|
|
1393
|
+
opts.reasoning_effort = reasoningEffort;
|
|
1394
|
+
}
|
|
1395
|
+
if (modelProfile && modelProfile.modelName) {
|
|
1396
|
+
debugLogger.api("USING_MODEL_PROFILE_PATH", {
|
|
1397
|
+
modelProfileName: modelProfile.modelName,
|
|
1398
|
+
modelName: modelProfile.modelName,
|
|
1399
|
+
provider: modelProfile.provider,
|
|
1400
|
+
baseURL: modelProfile.baseURL,
|
|
1401
|
+
apiKeyExists: !!modelProfile.apiKey,
|
|
1402
|
+
requestId: getCurrentRequest()?.id
|
|
1403
|
+
});
|
|
1404
|
+
const USE_NEW_ADAPTER_SYSTEM = process.env.USE_NEW_ADAPTERS !== "false";
|
|
1405
|
+
if (USE_NEW_ADAPTER_SYSTEM) {
|
|
1406
|
+
const adapter = ModelAdapterFactory.createAdapter(modelProfile);
|
|
1407
|
+
const unifiedParams = {
|
|
1408
|
+
messages: openaiMessages,
|
|
1409
|
+
systemPrompt: openaiSystem.map((s) => s.content),
|
|
1410
|
+
tools,
|
|
1411
|
+
maxTokens: getMaxTokensFromProfile(modelProfile),
|
|
1412
|
+
stream: config.stream,
|
|
1413
|
+
reasoningEffort,
|
|
1414
|
+
temperature: isGPT5Model(model) ? 1 : MAIN_QUERY_TEMPERATURE,
|
|
1415
|
+
previousResponseId: toolUseContext?.responseState?.previousResponseId,
|
|
1416
|
+
verbosity: "high"
|
|
1417
|
+
// High verbosity for coding tasks
|
|
1418
|
+
};
|
|
1419
|
+
const request = adapter.createRequest(unifiedParams);
|
|
1420
|
+
if (ModelAdapterFactory.shouldUseResponsesAPI(modelProfile)) {
|
|
1421
|
+
const { callGPT5ResponsesAPI } = await import("./openai.js");
|
|
1422
|
+
const response2 = await callGPT5ResponsesAPI(modelProfile, request, signal);
|
|
1423
|
+
const unifiedResponse = adapter.parseResponse(response2);
|
|
1424
|
+
const apiMessage = {
|
|
1425
|
+
role: "assistant",
|
|
1426
|
+
content: unifiedResponse.content,
|
|
1427
|
+
tool_calls: unifiedResponse.toolCalls,
|
|
1428
|
+
usage: {
|
|
1429
|
+
prompt_tokens: unifiedResponse.usage.promptTokens,
|
|
1430
|
+
completion_tokens: unifiedResponse.usage.completionTokens
|
|
1431
|
+
}
|
|
1432
|
+
};
|
|
1433
|
+
const assistantMsg = {
|
|
1434
|
+
type: "assistant",
|
|
1435
|
+
message: apiMessage,
|
|
1436
|
+
costUSD: 0,
|
|
1437
|
+
// Will be calculated later
|
|
1438
|
+
durationMs: Date.now() - start,
|
|
1439
|
+
uuid: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
1440
|
+
responseId: unifiedResponse.responseId
|
|
1441
|
+
// For state management
|
|
1442
|
+
};
|
|
1443
|
+
return assistantMsg;
|
|
1444
|
+
} else {
|
|
1445
|
+
const s = await getCompletionWithProfile(modelProfile, request, 0, 10, signal);
|
|
1446
|
+
let finalResponse;
|
|
1447
|
+
if (config.stream) {
|
|
1448
|
+
finalResponse = await handleMessageStream(s, signal);
|
|
1449
|
+
} else {
|
|
1450
|
+
finalResponse = s;
|
|
1451
|
+
}
|
|
1452
|
+
const r = convertOpenAIResponseToAnthropic(finalResponse, tools);
|
|
1453
|
+
return r;
|
|
1454
|
+
}
|
|
1455
|
+
} else {
|
|
1456
|
+
const completionFunction = isGPT5Model(modelProfile.modelName) ? getGPT5CompletionWithProfile : getCompletionWithProfile;
|
|
1457
|
+
const s = await completionFunction(modelProfile, opts, 0, 10, signal);
|
|
1458
|
+
let finalResponse;
|
|
1459
|
+
if (opts.stream) {
|
|
1460
|
+
finalResponse = await handleMessageStream(s, signal);
|
|
1461
|
+
} else {
|
|
1462
|
+
finalResponse = s;
|
|
1463
|
+
}
|
|
1464
|
+
const r = convertOpenAIResponseToAnthropic(finalResponse, tools);
|
|
1465
|
+
return r;
|
|
1466
|
+
}
|
|
1467
|
+
} else {
|
|
1468
|
+
debugLogger.api("USING_LEGACY_PATH", {
|
|
1469
|
+
modelProfileExists: !!modelProfile,
|
|
1470
|
+
modelProfileId: modelProfile?.modelName,
|
|
1471
|
+
modelNameExists: !!modelProfile?.modelName,
|
|
1472
|
+
fallbackModel: "main",
|
|
1473
|
+
actualModel: model,
|
|
1474
|
+
requestId: getCurrentRequest()?.id
|
|
1475
|
+
});
|
|
1476
|
+
const errorDetails = {
|
|
1477
|
+
modelProfileExists: !!modelProfile,
|
|
1478
|
+
modelProfileId: modelProfile?.modelName,
|
|
1479
|
+
modelNameExists: !!modelProfile?.modelName,
|
|
1480
|
+
requestedModel: model,
|
|
1481
|
+
requestId: getCurrentRequest()?.id
|
|
1482
|
+
};
|
|
1483
|
+
debugLogger.error("NO_VALID_MODEL_PROFILE", errorDetails);
|
|
1484
|
+
throw new Error(
|
|
1485
|
+
`No valid ModelProfile available for model: ${model}. Please configure model through /model command. Debug: ${JSON.stringify(errorDetails)}`
|
|
1486
|
+
);
|
|
1487
|
+
}
|
|
1488
|
+
}, { signal });
|
|
1489
|
+
} catch (error) {
|
|
1490
|
+
logError(error);
|
|
1491
|
+
return getAssistantMessageFromError(error);
|
|
1492
|
+
}
|
|
1493
|
+
const durationMs = Date.now() - start;
|
|
1494
|
+
const durationMsIncludingRetries = Date.now() - startIncludingRetries;
|
|
1495
|
+
const inputTokens = response.usage?.prompt_tokens ?? 0;
|
|
1496
|
+
const outputTokens = response.usage?.completion_tokens ?? 0;
|
|
1497
|
+
const cacheReadInputTokens = response.usage?.prompt_token_details?.cached_tokens ?? 0;
|
|
1498
|
+
const cacheCreationInputTokens = response.usage?.prompt_token_details?.cached_tokens ?? 0;
|
|
1499
|
+
const costUSD = inputTokens / 1e6 * SONNET_COST_PER_MILLION_INPUT_TOKENS + outputTokens / 1e6 * SONNET_COST_PER_MILLION_OUTPUT_TOKENS + cacheReadInputTokens / 1e6 * SONNET_COST_PER_MILLION_PROMPT_CACHE_READ_TOKENS + cacheCreationInputTokens / 1e6 * SONNET_COST_PER_MILLION_PROMPT_CACHE_WRITE_TOKENS;
|
|
1500
|
+
addToTotalCost(costUSD, durationMsIncludingRetries);
|
|
1501
|
+
logLLMInteraction({
|
|
1502
|
+
systemPrompt: systemPrompt.join("\n"),
|
|
1503
|
+
messages: [...openaiSystem, ...openaiMessages],
|
|
1504
|
+
response,
|
|
1505
|
+
usage: {
|
|
1506
|
+
inputTokens,
|
|
1507
|
+
outputTokens
|
|
1508
|
+
},
|
|
1509
|
+
timing: {
|
|
1510
|
+
start,
|
|
1511
|
+
end: Date.now()
|
|
1512
|
+
},
|
|
1513
|
+
apiFormat: "openai"
|
|
1514
|
+
});
|
|
1515
|
+
return {
|
|
1516
|
+
message: {
|
|
1517
|
+
...response,
|
|
1518
|
+
content: normalizeContentFromAPI(response.content),
|
|
1519
|
+
usage: {
|
|
1520
|
+
input_tokens: inputTokens,
|
|
1521
|
+
output_tokens: outputTokens,
|
|
1522
|
+
cache_read_input_tokens: cacheReadInputTokens,
|
|
1523
|
+
cache_creation_input_tokens: 0
|
|
1524
|
+
}
|
|
1525
|
+
},
|
|
1526
|
+
costUSD,
|
|
1527
|
+
durationMs,
|
|
1528
|
+
type: "assistant",
|
|
1529
|
+
uuid: randomUUID()
|
|
1530
|
+
};
|
|
1531
|
+
}
|
|
1532
|
+
function getMaxTokensFromProfile(modelProfile) {
|
|
1533
|
+
return modelProfile?.maxTokens || 8e3;
|
|
1534
|
+
}
|
|
1535
|
+
function getModelInputTokenCostUSD(model) {
|
|
1536
|
+
for (const providerModels of Object.values(models)) {
|
|
1537
|
+
const modelInfo = providerModels.find((m) => m.model === model);
|
|
1538
|
+
if (modelInfo) {
|
|
1539
|
+
return modelInfo.input_cost_per_token || 0;
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
return 3e-6;
|
|
1543
|
+
}
|
|
1544
|
+
function getModelOutputTokenCostUSD(model) {
|
|
1545
|
+
for (const providerModels of Object.values(models)) {
|
|
1546
|
+
const modelInfo = providerModels.find((m) => m.model === model);
|
|
1547
|
+
if (modelInfo) {
|
|
1548
|
+
return modelInfo.output_cost_per_token || 0;
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
return 15e-6;
|
|
1552
|
+
}
|
|
1553
|
+
async function queryModel(modelPointer, messages, systemPrompt = [], signal) {
|
|
1554
|
+
return queryLLM(
|
|
1555
|
+
messages,
|
|
1556
|
+
systemPrompt,
|
|
1557
|
+
0,
|
|
1558
|
+
// maxThinkingTokens
|
|
1559
|
+
[],
|
|
1560
|
+
// tools
|
|
1561
|
+
signal || new AbortController().signal,
|
|
1562
|
+
{
|
|
1563
|
+
safeMode: false,
|
|
1564
|
+
model: modelPointer,
|
|
1565
|
+
prependCLISysprompt: true
|
|
1566
|
+
}
|
|
1567
|
+
);
|
|
1568
|
+
}
|
|
1569
|
+
async function queryQuick({
|
|
1570
|
+
systemPrompt = [],
|
|
1571
|
+
userPrompt,
|
|
1572
|
+
assistantPrompt,
|
|
1573
|
+
enablePromptCaching = false,
|
|
1574
|
+
signal
|
|
1575
|
+
}) {
|
|
1576
|
+
const messages = [
|
|
1577
|
+
{
|
|
1578
|
+
message: { role: "user", content: userPrompt },
|
|
1579
|
+
type: "user",
|
|
1580
|
+
uuid: randomUUID()
|
|
1581
|
+
}
|
|
1582
|
+
];
|
|
1583
|
+
return queryModel("quick", messages, systemPrompt, signal);
|
|
1584
|
+
}
|
|
1585
|
+
export {
|
|
1586
|
+
API_ERROR_MESSAGE_PREFIX,
|
|
1587
|
+
CREDIT_BALANCE_TOO_LOW_ERROR_MESSAGE,
|
|
1588
|
+
INVALID_API_KEY_ERROR_MESSAGE,
|
|
1589
|
+
MAIN_QUERY_TEMPERATURE,
|
|
1590
|
+
NO_CONTENT_MESSAGE,
|
|
1591
|
+
PROMPT_TOO_LONG_ERROR_MESSAGE,
|
|
1592
|
+
assistantMessageToMessageParam,
|
|
1593
|
+
fetchAnthropicModels,
|
|
1594
|
+
formatSystemPromptWithContext,
|
|
1595
|
+
generateKodeContext,
|
|
1596
|
+
getAnthropicClient,
|
|
1597
|
+
queryLLM,
|
|
1598
|
+
queryModel,
|
|
1599
|
+
queryQuick,
|
|
1600
|
+
refreshKodeContext,
|
|
1601
|
+
resetAnthropicClient,
|
|
1602
|
+
userMessageToMessageParam,
|
|
1603
|
+
verifyApiKey
|
|
1604
|
+
};
|
|
1605
|
+
//# sourceMappingURL=claude.js.map
|