whale-code 6.5.4 → 6.5.6
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/README.md +39 -31
- package/bin/{swagmanager-mcp.js → whale-code.js} +17 -2
- package/dist/cli/app.js +148 -72
- package/dist/cli/app.js.map +1 -0
- package/dist/cli/chat/AgentSelector.js +105 -10
- package/dist/cli/chat/AgentSelector.js.map +1 -0
- package/dist/cli/chat/ChatApp.d.ts +31 -0
- package/dist/cli/chat/ChatApp.js +539 -286
- package/dist/cli/chat/ChatApp.js.map +1 -0
- package/dist/cli/chat/ChatInput.js +1088 -770
- package/dist/cli/chat/ChatInput.js.map +1 -0
- package/dist/cli/chat/MarkdownText.js +39 -14
- package/dist/cli/chat/MarkdownText.js.map +1 -0
- package/dist/cli/chat/MemoryManager.js +181 -46
- package/dist/cli/chat/MemoryManager.js.map +1 -0
- package/dist/cli/chat/MessageList.d.ts +2 -3
- package/dist/cli/chat/MessageList.js +186 -45
- package/dist/cli/chat/MessageList.js.map +1 -0
- package/dist/cli/chat/ModelSelector.js +282 -63
- package/dist/cli/chat/ModelSelector.js.map +1 -0
- package/dist/cli/chat/NodeManager.js +165 -75
- package/dist/cli/chat/NodeManager.js.map +1 -0
- package/dist/cli/chat/NodeSelector.js +171 -30
- package/dist/cli/chat/NodeSelector.js.map +1 -0
- package/dist/cli/chat/PlanApproval.js +281 -57
- package/dist/cli/chat/PlanApproval.js.map +1 -0
- package/dist/cli/chat/RewindViewer.js +559 -144
- package/dist/cli/chat/RewindViewer.js.map +1 -0
- package/dist/cli/chat/SessionManager.js +137 -30
- package/dist/cli/chat/SessionManager.js.map +1 -0
- package/dist/cli/chat/SlashMenu.js +293 -164
- package/dist/cli/chat/SlashMenu.js.map +1 -0
- package/dist/cli/chat/StatusBar.js +172 -9
- package/dist/cli/chat/StatusBar.js.map +1 -0
- package/dist/cli/chat/StoreSelector.js +147 -18
- package/dist/cli/chat/StoreSelector.js.map +1 -0
- package/dist/cli/chat/StreamingText.d.ts +1 -5
- package/dist/cli/chat/StreamingText.js +22 -7
- package/dist/cli/chat/StreamingText.js.map +1 -0
- package/dist/cli/chat/SubagentPanel.d.ts +1 -2
- package/dist/cli/chat/SubagentPanel.js +612 -72
- package/dist/cli/chat/SubagentPanel.js.map +1 -0
- package/dist/cli/chat/TeamPanel.d.ts +1 -0
- package/dist/cli/chat/TeamPanel.js +230 -30
- package/dist/cli/chat/TeamPanel.js.map +1 -0
- package/dist/cli/chat/ThemeSelector.js +84 -24
- package/dist/cli/chat/ThemeSelector.js.map +1 -0
- package/dist/cli/chat/ToolIndicator.js +1476 -371
- package/dist/cli/chat/ToolIndicator.js.map +1 -0
- package/dist/cli/chat/hooks/useAgentLoop.d.ts +1 -0
- package/dist/cli/chat/hooks/useAgentLoop.js +481 -367
- package/dist/cli/chat/hooks/useAgentLoop.js.map +1 -0
- package/dist/cli/chat/hooks/useSlashCommands.d.ts +3 -14
- package/dist/cli/chat/hooks/useSlashCommands.js +744 -572
- package/dist/cli/chat/hooks/useSlashCommands.js.map +1 -0
- package/dist/cli/commands/config-cmd.js +56 -57
- package/dist/cli/commands/config-cmd.js.map +1 -0
- package/dist/cli/commands/db.js +184 -169
- package/dist/cli/commands/db.js.map +1 -0
- package/dist/cli/commands/doctor.js +212 -122
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/init.js +211 -244
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/mcp.js +127 -122
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/login/LoginApp.js +355 -141
- package/dist/cli/login/LoginApp.js.map +1 -0
- package/dist/cli/print-mode.js +196 -177
- package/dist/cli/print-mode.js.map +1 -0
- package/dist/cli/serve-mode.js +615 -530
- package/dist/cli/serve-mode.js.map +1 -0
- package/dist/cli/services/agent-config.d.ts +29 -0
- package/dist/cli/services/agent-config.js +91 -0
- package/dist/cli/services/agent-config.js.map +1 -0
- package/dist/cli/services/agent-definitions.d.ts +4 -1
- package/dist/cli/services/agent-definitions.js +97 -56
- package/dist/cli/services/agent-definitions.js.map +1 -0
- package/dist/cli/services/agent-events.js +225 -162
- package/dist/cli/services/agent-events.js.map +1 -0
- package/dist/cli/services/agent-loop.js +978 -669
- package/dist/cli/services/agent-loop.js.map +1 -0
- package/dist/cli/services/agent-worker-base.d.ts +35 -5
- package/dist/cli/services/agent-worker-base.js +337 -153
- package/dist/cli/services/agent-worker-base.js.map +1 -0
- package/dist/cli/services/api-retry.js +69 -64
- package/dist/cli/services/api-retry.js.map +1 -0
- package/dist/cli/services/auth-service.d.ts +3 -3
- package/dist/cli/services/auth-service.js +209 -132
- package/dist/cli/services/auth-service.js.map +1 -0
- package/dist/cli/services/background-processes.js +343 -267
- package/dist/cli/services/background-processes.js.map +1 -0
- package/dist/cli/services/browser-auth.d.ts +2 -2
- package/dist/cli/services/browser-auth.js +159 -118
- package/dist/cli/services/browser-auth.js.map +1 -0
- package/dist/cli/services/claude-md-loader.js +40 -36
- package/dist/cli/services/claude-md-loader.js.map +1 -0
- package/dist/cli/services/config-store.d.ts +9 -4
- package/dist/cli/services/config-store.js +164 -117
- package/dist/cli/services/config-store.js.map +1 -0
- package/dist/cli/services/debug-log.d.ts +1 -1
- package/dist/cli/services/debug-log.js +34 -35
- package/dist/cli/services/debug-log.js.map +1 -0
- package/dist/cli/services/env-detect.d.ts +7 -0
- package/dist/cli/services/env-detect.js +9 -0
- package/dist/cli/services/env-detect.js.map +1 -0
- package/dist/cli/services/error-logger.d.ts +2 -3
- package/dist/cli/services/error-logger.js +189 -180
- package/dist/cli/services/error-logger.js.map +1 -0
- package/dist/cli/services/file-history.d.ts +1 -1
- package/dist/cli/services/file-history.js +50 -54
- package/dist/cli/services/file-history.js.map +1 -0
- package/dist/cli/services/format-server-response.js +332 -372
- package/dist/cli/services/format-server-response.js.map +1 -0
- package/dist/cli/services/git-context.js +61 -45
- package/dist/cli/services/git-context.js.map +1 -0
- package/dist/cli/services/hooks.d.ts +2 -2
- package/dist/cli/services/hooks.js +195 -180
- package/dist/cli/services/hooks.js.map +1 -0
- package/dist/cli/services/ink-incremental.d.ts +19 -0
- package/dist/cli/services/ink-incremental.js +59 -0
- package/dist/cli/services/ink-incremental.js.map +1 -0
- package/dist/cli/services/ink-resize-fix.js +54 -44
- package/dist/cli/services/ink-resize-fix.js.map +1 -0
- package/dist/cli/services/ink-sync-output.d.ts +12 -0
- package/dist/cli/services/ink-sync-output.js +16 -0
- package/dist/cli/services/ink-sync-output.js.map +1 -0
- package/dist/cli/services/interactive-tools.js +268 -212
- package/dist/cli/services/interactive-tools.js.map +1 -0
- package/dist/cli/services/keybinding-manager.d.ts +11 -1
- package/dist/cli/services/keybinding-manager.js +126 -63
- package/dist/cli/services/keybinding-manager.js.map +1 -0
- package/dist/cli/services/local-tools.d.ts +1 -1
- package/dist/cli/services/local-tools.js +939 -656
- package/dist/cli/services/local-tools.js.map +1 -0
- package/dist/cli/services/lsp-manager.js +757 -594
- package/dist/cli/services/lsp-manager.js.map +1 -0
- package/dist/cli/services/mcp-client.d.ts +1 -1
- package/dist/cli/services/mcp-client.js +173 -134
- package/dist/cli/services/mcp-client.js.map +1 -0
- package/dist/cli/services/memory-manager.js +53 -40
- package/dist/cli/services/memory-manager.js.map +1 -0
- package/dist/cli/services/model-manager.js +55 -40
- package/dist/cli/services/model-manager.js.map +1 -0
- package/dist/cli/services/model-router.js +115 -85
- package/dist/cli/services/model-router.js.map +1 -0
- package/dist/cli/services/paths.d.ts +30 -0
- package/dist/cli/services/paths.js +81 -0
- package/dist/cli/services/paths.js.map +1 -0
- package/dist/cli/services/permission-modes.js +32 -25
- package/dist/cli/services/permission-modes.js.map +1 -0
- package/dist/cli/services/rewind.js +182 -168
- package/dist/cli/services/rewind.js.map +1 -0
- package/dist/cli/services/ripgrep.js +115 -115
- package/dist/cli/services/ripgrep.js.map +1 -0
- package/dist/cli/services/sandbox.d.ts +1 -1
- package/dist/cli/services/sandbox.js +58 -37
- package/dist/cli/services/sandbox.js.map +1 -0
- package/dist/cli/services/server-tools.js +738 -565
- package/dist/cli/services/server-tools.js.map +1 -0
- package/dist/cli/services/session-persistence.js +69 -74
- package/dist/cli/services/session-persistence.js.map +1 -0
- package/dist/cli/services/subagent-worker.js +42 -27
- package/dist/cli/services/subagent-worker.js.map +1 -0
- package/dist/cli/services/subagent.d.ts +2 -0
- package/dist/cli/services/subagent.js +606 -430
- package/dist/cli/services/subagent.js.map +1 -0
- package/dist/cli/services/system-prompt.js +86 -78
- package/dist/cli/services/system-prompt.js.map +1 -0
- package/dist/cli/services/task-decomposer.d.ts +1 -1
- package/dist/cli/services/task-decomposer.js +172 -139
- package/dist/cli/services/task-decomposer.js.map +1 -0
- package/dist/cli/services/team-lead.d.ts +2 -2
- package/dist/cli/services/team-lead.js +727 -529
- package/dist/cli/services/team-lead.js.map +1 -0
- package/dist/cli/services/team-state.js +319 -319
- package/dist/cli/services/team-state.js.map +1 -0
- package/dist/cli/services/teammate.d.ts +8 -2
- package/dist/cli/services/teammate.js +862 -560
- package/dist/cli/services/teammate.js.map +1 -0
- package/dist/cli/services/telemetry.d.ts +6 -1
- package/dist/cli/services/telemetry.js +180 -157
- package/dist/cli/services/telemetry.js.map +1 -0
- package/dist/cli/services/tools/agent-tools.d.ts +3 -3
- package/dist/cli/services/tools/agent-tools.js +480 -322
- package/dist/cli/services/tools/agent-tools.js.map +1 -0
- package/dist/cli/services/tools/file-ops.js +563 -450
- package/dist/cli/services/tools/file-ops.js.map +1 -0
- package/dist/cli/services/tools/search-tools.js +231 -162
- package/dist/cli/services/tools/search-tools.js.map +1 -0
- package/dist/cli/services/tools/shell-exec.js +197 -151
- package/dist/cli/services/tools/shell-exec.js.map +1 -0
- package/dist/cli/services/tools/task-manager.js +206 -173
- package/dist/cli/services/tools/task-manager.js.map +1 -0
- package/dist/cli/services/tools/web-tools.js +388 -341
- package/dist/cli/services/tools/web-tools.js.map +1 -0
- package/dist/cli/setup/SetupApp.d.ts +2 -2
- package/dist/cli/setup/SetupApp.js +608 -160
- package/dist/cli/setup/SetupApp.js.map +1 -0
- package/dist/cli/shared/ErrorBoundary.d.ts +22 -0
- package/dist/cli/shared/ErrorBoundary.js +73 -0
- package/dist/cli/shared/ErrorBoundary.js.map +1 -0
- package/dist/cli/shared/MatrixIntro.js +66 -69
- package/dist/cli/shared/MatrixIntro.js.map +1 -0
- package/dist/cli/shared/SpinnerSlot.d.ts +14 -0
- package/dist/cli/shared/SpinnerSlot.js +63 -0
- package/dist/cli/shared/SpinnerSlot.js.map +1 -0
- package/dist/cli/shared/Theme.d.ts +1 -1
- package/dist/cli/shared/Theme.js +136 -92
- package/dist/cli/shared/Theme.js.map +1 -0
- package/dist/cli/shared/WhaleBanner.js +99 -11
- package/dist/cli/shared/WhaleBanner.js.map +1 -0
- package/dist/cli/shared/markdown.d.ts +3 -1
- package/dist/cli/shared/markdown.js +736 -674
- package/dist/cli/shared/markdown.js.map +1 -0
- package/dist/cli/shared/marked-terminal.d.js +2 -0
- package/dist/cli/shared/marked-terminal.d.js.map +1 -0
- package/dist/cli/shared/theme-manager.js +99 -90
- package/dist/cli/shared/theme-manager.js.map +1 -0
- package/dist/cli/shared/theme-presets.js +256 -254
- package/dist/cli/shared/theme-presets.js.map +1 -0
- package/dist/cli/status/StatusApp.js +235 -86
- package/dist/cli/status/StatusApp.js.map +1 -0
- package/dist/cli/stores/StoreApp.js +275 -65
- package/dist/cli/stores/StoreApp.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +509 -396
- package/dist/index.js.map +1 -0
- package/dist/local-agent/connection.d.ts +2 -2
- package/dist/local-agent/connection.js +352 -293
- package/dist/local-agent/connection.js.map +1 -0
- package/dist/local-agent/discovery.js +259 -122
- package/dist/local-agent/discovery.js.map +1 -0
- package/dist/local-agent/executor.js +216 -193
- package/dist/local-agent/executor.js.map +1 -0
- package/dist/local-agent/index.d.ts +2 -2
- package/dist/local-agent/index.js +156 -156
- package/dist/local-agent/index.js.map +1 -0
- package/dist/node/adapters/base.js +18 -8
- package/dist/node/adapters/base.js.map +1 -0
- package/dist/node/adapters/discord.js +286 -275
- package/dist/node/adapters/discord.js.map +1 -0
- package/dist/node/adapters/email.js +189 -202
- package/dist/node/adapters/email.js.map +1 -0
- package/dist/node/adapters/imessage.js +145 -142
- package/dist/node/adapters/imessage.js.map +1 -0
- package/dist/node/adapters/slack.js +237 -236
- package/dist/node/adapters/slack.js.map +1 -0
- package/dist/node/adapters/sms.js +149 -151
- package/dist/node/adapters/sms.js.map +1 -0
- package/dist/node/adapters/telegram.js +88 -92
- package/dist/node/adapters/telegram.js.map +1 -0
- package/dist/node/adapters/webchat.js +160 -136
- package/dist/node/adapters/webchat.js.map +1 -0
- package/dist/node/adapters/whatsapp.js +212 -215
- package/dist/node/adapters/whatsapp.js.map +1 -0
- package/dist/node/cli.js +884 -653
- package/dist/node/cli.js.map +1 -0
- package/dist/node/config.js +20 -18
- package/dist/node/config.js.map +1 -0
- package/dist/node/gateway-client.js +191 -181
- package/dist/node/gateway-client.js.map +1 -0
- package/dist/node/portal/clipboard.js +161 -130
- package/dist/node/portal/clipboard.js.map +1 -0
- package/dist/node/portal/discovery.js +51 -45
- package/dist/node/portal/discovery.js.map +1 -0
- package/dist/node/portal/forward.js +64 -58
- package/dist/node/portal/forward.js.map +1 -0
- package/dist/node/portal/index.js +246 -221
- package/dist/node/portal/index.js.map +1 -0
- package/dist/node/portal/multiplexer.js +192 -182
- package/dist/node/portal/multiplexer.js.map +1 -0
- package/dist/node/portal/permissions.js +102 -70
- package/dist/node/portal/permissions.js.map +1 -0
- package/dist/node/portal/protocol.js +153 -116
- package/dist/node/portal/protocol.js.map +1 -0
- package/dist/node/portal/screen.js +80 -69
- package/dist/node/portal/screen.js.map +1 -0
- package/dist/node/portal/session.js +124 -117
- package/dist/node/portal/session.js.map +1 -0
- package/dist/node/portal/shell.js +140 -113
- package/dist/node/portal/shell.js.map +1 -0
- package/dist/node/portal/stream.js +77 -75
- package/dist/node/portal/stream.js.map +1 -0
- package/dist/node/portal/transfer.js +190 -167
- package/dist/node/portal/transfer.js.map +1 -0
- package/dist/node/portal/ui.js +124 -99
- package/dist/node/portal/ui.js.map +1 -0
- package/dist/node/remote-desktop/compile-helper.js +50 -45
- package/dist/node/remote-desktop/compile-helper.js.map +1 -0
- package/dist/node/remote-desktop/index.js +215 -187
- package/dist/node/remote-desktop/index.js.map +1 -0
- package/dist/node/remote-desktop/protocol.js +45 -29
- package/dist/node/remote-desktop/protocol.js.map +1 -0
- package/dist/node/runtime.js +493 -410
- package/dist/node/runtime.js.map +1 -0
- package/dist/server/handlers/__test-utils__/test-db.js +39 -89
- package/dist/server/handlers/__test-utils__/test-db.js.map +1 -0
- package/dist/server/handlers/analytics.js +467 -261
- package/dist/server/handlers/analytics.js.map +1 -0
- package/dist/server/handlers/api-docs.d.ts +6 -0
- package/dist/server/handlers/api-docs.js +1613 -0
- package/dist/server/handlers/api-docs.js.map +1 -0
- package/dist/server/handlers/api-keys.js +295 -232
- package/dist/server/handlers/api-keys.js.map +1 -0
- package/dist/server/handlers/billing.js +330 -239
- package/dist/server/handlers/billing.js.map +1 -0
- package/dist/server/handlers/browser.js +468 -395
- package/dist/server/handlers/browser.js.map +1 -0
- package/dist/server/handlers/catalog.js +1377 -978
- package/dist/server/handlers/catalog.js.map +1 -0
- package/dist/server/handlers/clickhouse.js +157 -109
- package/dist/server/handlers/clickhouse.js.map +1 -0
- package/dist/server/handlers/comms.d.ts +0 -53
- package/dist/server/handlers/comms.js +1443 -970
- package/dist/server/handlers/comms.js.map +1 -0
- package/dist/server/handlers/creations.js +461 -394
- package/dist/server/handlers/creations.js.map +1 -0
- package/dist/server/handlers/crm.js +1082 -791
- package/dist/server/handlers/crm.js.map +1 -0
- package/dist/server/handlers/discovery.js +251 -232
- package/dist/server/handlers/discovery.js.map +1 -0
- package/dist/server/handlers/embeddings.js +241 -164
- package/dist/server/handlers/embeddings.js.map +1 -0
- package/dist/server/handlers/enrichment.js +887 -718
- package/dist/server/handlers/enrichment.js.map +1 -0
- package/dist/server/handlers/image-gen.js +467 -376
- package/dist/server/handlers/image-gen.js.map +1 -0
- package/dist/server/handlers/inventory.js +797 -424
- package/dist/server/handlers/inventory.js.map +1 -0
- package/dist/server/handlers/kali.js +272 -230
- package/dist/server/handlers/kali.js.map +1 -0
- package/dist/server/handlers/llm-providers.js +803 -580
- package/dist/server/handlers/llm-providers.js.map +1 -0
- package/dist/server/handlers/local-agent.js +133 -105
- package/dist/server/handlers/local-agent.js.map +1 -0
- package/dist/server/handlers/media.js +1179 -857
- package/dist/server/handlers/media.js.map +1 -0
- package/dist/server/handlers/meta-ads.js +2669 -2093
- package/dist/server/handlers/meta-ads.js.map +1 -0
- package/dist/server/handlers/nodes.js +1321 -913
- package/dist/server/handlers/nodes.js.map +1 -0
- package/dist/server/handlers/operations.js +183 -157
- package/dist/server/handlers/operations.js.map +1 -0
- package/dist/server/handlers/platform.js +346 -210
- package/dist/server/handlers/platform.js.map +1 -0
- package/dist/server/handlers/remove-bg.js +118 -86
- package/dist/server/handlers/remove-bg.js.map +1 -0
- package/dist/server/handlers/storefront.js +586 -446
- package/dist/server/handlers/storefront.js.map +1 -0
- package/dist/server/handlers/supply-chain.js +546 -326
- package/dist/server/handlers/supply-chain.js.map +1 -0
- package/dist/server/handlers/transcription.js +106 -97
- package/dist/server/handlers/transcription.js.map +1 -0
- package/dist/server/handlers/video-gen.js +593 -424
- package/dist/server/handlers/video-gen.js.map +1 -0
- package/dist/server/handlers/voice.js +1458 -1017
- package/dist/server/handlers/voice.js.map +1 -0
- package/dist/server/handlers/workflow-steps.js +2837 -2116
- package/dist/server/handlers/workflow-steps.js.map +1 -0
- package/dist/server/handlers/workflows.js +1630 -933
- package/dist/server/handlers/workflows.js.map +1 -0
- package/dist/server/index.js +3166 -2390
- package/dist/server/index.js.map +1 -0
- package/dist/server/lib/batch-client.js +471 -409
- package/dist/server/lib/batch-client.js.map +1 -0
- package/dist/server/lib/clickhouse-buffer.js +118 -104
- package/dist/server/lib/clickhouse-buffer.js.map +1 -0
- package/dist/server/lib/clickhouse-client.js +107 -107
- package/dist/server/lib/clickhouse-client.js.map +1 -0
- package/dist/server/lib/coa-renderer.js +1786 -356
- package/dist/server/lib/coa-renderer.js.map +1 -0
- package/dist/server/lib/code-worker-pool.js +227 -177
- package/dist/server/lib/code-worker-pool.js.map +1 -0
- package/dist/server/lib/code-worker.js +174 -164
- package/dist/server/lib/code-worker.js.map +1 -0
- package/dist/server/lib/compaction-service.d.ts +2 -12
- package/dist/server/lib/compaction-service.js +74 -184
- package/dist/server/lib/compaction-service.js.map +1 -0
- package/dist/server/lib/logger.js +36 -24
- package/dist/server/lib/logger.js.map +1 -0
- package/dist/server/lib/otel.js +101 -80
- package/dist/server/lib/otel.js.map +1 -0
- package/dist/server/lib/pdf-renderer.d.ts +1 -1
- package/dist/server/lib/pdf-renderer.js +954 -776
- package/dist/server/lib/pdf-renderer.js.map +1 -0
- package/dist/server/lib/prompt-sanitizer.js +188 -108
- package/dist/server/lib/prompt-sanitizer.js.map +1 -0
- package/dist/server/lib/provider-capabilities.js +136 -138
- package/dist/server/lib/provider-capabilities.js.map +1 -0
- package/dist/server/lib/provider-failover.js +190 -168
- package/dist/server/lib/provider-failover.js.map +1 -0
- package/dist/server/lib/rate-limiter.js +186 -117
- package/dist/server/lib/rate-limiter.js.map +1 -0
- package/dist/server/lib/react-pdf-layout.js +551 -382
- package/dist/server/lib/react-pdf-layout.js.map +1 -0
- package/dist/server/lib/server-agent-loop.d.ts +9 -0
- package/dist/server/lib/server-agent-loop.js +906 -624
- package/dist/server/lib/server-agent-loop.js.map +1 -0
- package/dist/server/lib/server-subagent.d.ts +2 -0
- package/dist/server/lib/server-subagent.js +260 -162
- package/dist/server/lib/server-subagent.js.map +1 -0
- package/dist/server/lib/session-checkpoint.js +105 -96
- package/dist/server/lib/session-checkpoint.js.map +1 -0
- package/dist/server/lib/ssrf-guard.js +193 -184
- package/dist/server/lib/ssrf-guard.js.map +1 -0
- package/dist/server/lib/supabase-client.js +94 -82
- package/dist/server/lib/supabase-client.js.map +1 -0
- package/dist/server/lib/template-resolver.js +154 -176
- package/dist/server/lib/template-resolver.js.map +1 -0
- package/dist/server/lib/utils.js +242 -133
- package/dist/server/lib/utils.js.map +1 -0
- package/dist/server/local-agent-gateway.d.ts +2 -2
- package/dist/server/local-agent-gateway.js +785 -627
- package/dist/server/local-agent-gateway.js.map +1 -0
- package/dist/server/providers/anthropic.js +254 -176
- package/dist/server/providers/anthropic.js.map +1 -0
- package/dist/server/providers/bedrock.js +221 -162
- package/dist/server/providers/bedrock.js.map +1 -0
- package/dist/server/providers/gemini.js +548 -418
- package/dist/server/providers/gemini.js.map +1 -0
- package/dist/server/providers/openai.js +571 -437
- package/dist/server/providers/openai.js.map +1 -0
- package/dist/server/providers/registry.js +23 -18
- package/dist/server/providers/registry.js.map +1 -0
- package/dist/server/providers/shared.js +123 -95
- package/dist/server/providers/shared.js.map +1 -0
- package/dist/server/providers/types.js +1 -11
- package/dist/server/providers/types.js.map +1 -0
- package/dist/server/proxy-handlers.js +209 -165
- package/dist/server/proxy-handlers.js.map +1 -0
- package/dist/server/tool-router.d.ts +13 -0
- package/dist/server/tool-router.js +960 -598
- package/dist/server/tool-router.js.map +1 -0
- package/dist/server/validation.js +248 -188
- package/dist/server/validation.js.map +1 -0
- package/dist/server/worker.js +202 -133
- package/dist/server/worker.js.map +1 -0
- package/dist/setup.d.ts +2 -2
- package/dist/setup.js +151 -147
- package/dist/setup.js.map +1 -0
- package/dist/shared/agent-core.d.ts +191 -24
- package/dist/shared/agent-core.js +971 -462
- package/dist/shared/agent-core.js.map +1 -0
- package/dist/shared/anthropic-types.js +1 -6
- package/dist/shared/anthropic-types.js.map +1 -0
- package/dist/shared/api-client.d.ts +17 -9
- package/dist/shared/api-client.js +419 -327
- package/dist/shared/api-client.js.map +1 -0
- package/dist/shared/compaction.d.ts +36 -0
- package/dist/shared/compaction.js +138 -0
- package/dist/shared/compaction.js.map +1 -0
- package/dist/shared/constants.js +67 -64
- package/dist/shared/constants.js.map +1 -0
- package/dist/shared/sse-parser.js +221 -219
- package/dist/shared/sse-parser.js.map +1 -0
- package/dist/shared/tool-dispatch.d.ts +4 -2
- package/dist/shared/tool-dispatch.js +226 -165
- package/dist/shared/tool-dispatch.js.map +1 -0
- package/dist/shared/types.js +1 -6
- package/dist/shared/types.js.map +1 -0
- package/dist/types/cli-highlight.d.js +2 -0
- package/dist/types/cli-highlight.d.js.map +1 -0
- package/dist/types/diff.d.js +2 -0
- package/dist/types/diff.d.js.map +1 -0
- package/dist/types/pdf-parse.d.js +2 -0
- package/dist/types/pdf-parse.d.js.map +1 -0
- package/dist/updater.d.ts +1 -1
- package/dist/updater.js +118 -92
- package/dist/updater.js.map +1 -0
- package/dist/webchat/widget.js +227 -380
- package/dist/webchat/widget.js.map +1 -0
- package/package.json +22 -10
- package/vendor/ink/build/ansi-tokenizer.d.ts +38 -0
- package/vendor/ink/build/ansi-tokenizer.js +316 -0
- package/vendor/ink/build/ansi-tokenizer.js.map +1 -0
- package/vendor/ink/build/apply-styles.js +175 -0
- package/vendor/ink/build/build-layout.js +77 -0
- package/vendor/ink/build/calculate-wrapped-text.js +53 -0
- package/vendor/ink/build/colorize.d.ts +3 -0
- package/vendor/ink/build/colorize.js +48 -0
- package/vendor/ink/build/colorize.js.map +1 -0
- package/vendor/ink/build/components/AccessibilityContext.d.ts +3 -0
- package/vendor/ink/build/components/AccessibilityContext.js +5 -0
- package/vendor/ink/build/components/AccessibilityContext.js.map +1 -0
- package/vendor/ink/build/components/App.d.ts +18 -0
- package/vendor/ink/build/components/App.js +351 -0
- package/vendor/ink/build/components/App.js.map +1 -0
- package/vendor/ink/build/components/AppContext.d.ts +15 -0
- package/vendor/ink/build/components/AppContext.js +11 -0
- package/vendor/ink/build/components/AppContext.js.map +1 -0
- package/vendor/ink/build/components/BackgroundContext.d.ts +4 -0
- package/vendor/ink/build/components/BackgroundContext.js +3 -0
- package/vendor/ink/build/components/BackgroundContext.js.map +1 -0
- package/vendor/ink/build/components/Box.d.ts +117 -0
- package/vendor/ink/build/components/Box.js +34 -0
- package/vendor/ink/build/components/Box.js.map +1 -0
- package/vendor/ink/build/components/Color.js +62 -0
- package/vendor/ink/build/components/Cursor.d.ts +83 -0
- package/vendor/ink/build/components/Cursor.js +53 -0
- package/vendor/ink/build/components/Cursor.js.map +1 -0
- package/vendor/ink/build/components/CursorContext.d.ts +11 -0
- package/vendor/ink/build/components/CursorContext.js +8 -0
- package/vendor/ink/build/components/CursorContext.js.map +1 -0
- package/vendor/ink/build/components/ErrorBoundary.d.ts +18 -0
- package/vendor/ink/build/components/ErrorBoundary.js +23 -0
- package/vendor/ink/build/components/ErrorBoundary.js.map +1 -0
- package/vendor/ink/build/components/ErrorOverview.d.ts +6 -0
- package/vendor/ink/build/components/ErrorOverview.js +84 -0
- package/vendor/ink/build/components/ErrorOverview.js.map +1 -0
- package/vendor/ink/build/components/FocusContext.d.ts +16 -0
- package/vendor/ink/build/components/FocusContext.js +17 -0
- package/vendor/ink/build/components/FocusContext.js.map +1 -0
- package/vendor/ink/build/components/Newline.d.ts +13 -0
- package/vendor/ink/build/components/Newline.js +8 -0
- package/vendor/ink/build/components/Newline.js.map +1 -0
- package/vendor/ink/build/components/Spacer.d.ts +7 -0
- package/vendor/ink/build/components/Spacer.js +11 -0
- package/vendor/ink/build/components/Spacer.js.map +1 -0
- package/vendor/ink/build/components/Static.d.ts +24 -0
- package/vendor/ink/build/components/Static.js +28 -0
- package/vendor/ink/build/components/Static.js.map +1 -0
- package/vendor/ink/build/components/StderrContext.d.ts +15 -0
- package/vendor/ink/build/components/StderrContext.js +13 -0
- package/vendor/ink/build/components/StderrContext.js.map +1 -0
- package/vendor/ink/build/components/StdinContext.d.ts +22 -0
- package/vendor/ink/build/components/StdinContext.js +19 -0
- package/vendor/ink/build/components/StdinContext.js.map +1 -0
- package/vendor/ink/build/components/StdoutContext.d.ts +15 -0
- package/vendor/ink/build/components/StdoutContext.js +13 -0
- package/vendor/ink/build/components/StdoutContext.js.map +1 -0
- package/vendor/ink/build/components/Text.d.ts +55 -0
- package/vendor/ink/build/components/Text.js +50 -0
- package/vendor/ink/build/components/Text.js.map +1 -0
- package/vendor/ink/build/components/Transform.d.ts +16 -0
- package/vendor/ink/build/components/Transform.js +15 -0
- package/vendor/ink/build/components/Transform.js.map +1 -0
- package/vendor/ink/build/cursor-helpers.d.ts +38 -0
- package/vendor/ink/build/cursor-helpers.js +56 -0
- package/vendor/ink/build/cursor-helpers.js.map +1 -0
- package/vendor/ink/build/devtools-window-polyfill.d.ts +1 -0
- package/vendor/ink/build/devtools-window-polyfill.js +65 -0
- package/vendor/ink/build/devtools-window-polyfill.js.map +1 -0
- package/vendor/ink/build/devtools.d.ts +1 -0
- package/vendor/ink/build/devtools.js +11 -0
- package/vendor/ink/build/devtools.js.map +1 -0
- package/vendor/ink/build/dom.d.ts +56 -0
- package/vendor/ink/build/dom.js +124 -0
- package/vendor/ink/build/dom.js.map +1 -0
- package/vendor/ink/build/experimental/apply-style.js +140 -0
- package/vendor/ink/build/experimental/dom.js +123 -0
- package/vendor/ink/build/experimental/output.js +91 -0
- package/vendor/ink/build/experimental/reconciler.js +141 -0
- package/vendor/ink/build/experimental/renderer.js +81 -0
- package/vendor/ink/build/get-max-width.d.ts +3 -0
- package/vendor/ink/build/get-max-width.js +10 -0
- package/vendor/ink/build/get-max-width.js.map +1 -0
- package/vendor/ink/build/hooks/use-app.d.ts +5 -0
- package/vendor/ink/build/hooks/use-app.js +8 -0
- package/vendor/ink/build/hooks/use-app.js.map +1 -0
- package/vendor/ink/build/hooks/use-cursor.d.ts +12 -0
- package/vendor/ink/build/hooks/use-cursor.js +29 -0
- package/vendor/ink/build/hooks/use-cursor.js.map +1 -0
- package/vendor/ink/build/hooks/use-focus-manager.d.ts +28 -0
- package/vendor/ink/build/hooks/use-focus-manager.js +17 -0
- package/vendor/ink/build/hooks/use-focus-manager.js.map +1 -0
- package/vendor/ink/build/hooks/use-focus.d.ts +29 -0
- package/vendor/ink/build/hooks/use-focus.js +42 -0
- package/vendor/ink/build/hooks/use-focus.js.map +1 -0
- package/vendor/ink/build/hooks/use-input.d.ts +131 -0
- package/vendor/ink/build/hooks/use-input.js +124 -0
- package/vendor/ink/build/hooks/use-input.js.map +1 -0
- package/vendor/ink/build/hooks/use-is-screen-reader-enabled.d.ts +5 -0
- package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js +11 -0
- package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js.map +1 -0
- package/vendor/ink/build/hooks/use-stderr.d.ts +5 -0
- package/vendor/ink/build/hooks/use-stderr.js +8 -0
- package/vendor/ink/build/hooks/use-stderr.js.map +1 -0
- package/vendor/ink/build/hooks/use-stdin.d.ts +5 -0
- package/vendor/ink/build/hooks/use-stdin.js +8 -0
- package/vendor/ink/build/hooks/use-stdin.js.map +1 -0
- package/vendor/ink/build/hooks/use-stdout.d.ts +5 -0
- package/vendor/ink/build/hooks/use-stdout.js +8 -0
- package/vendor/ink/build/hooks/use-stdout.js.map +1 -0
- package/vendor/ink/build/hooks/useInput.js +38 -0
- package/vendor/ink/build/index.d.ts +34 -0
- package/vendor/ink/build/index.js +20 -0
- package/vendor/ink/build/index.js.map +1 -0
- package/vendor/ink/build/ink.d.ts +90 -0
- package/vendor/ink/build/ink.js +654 -0
- package/vendor/ink/build/ink.js.map +1 -0
- package/vendor/ink/build/input-parser.d.ts +7 -0
- package/vendor/ink/build/input-parser.js +154 -0
- package/vendor/ink/build/input-parser.js.map +1 -0
- package/vendor/ink/build/instance.js +205 -0
- package/vendor/ink/build/instances.d.ts +3 -0
- package/vendor/ink/build/instances.js +8 -0
- package/vendor/ink/build/instances.js.map +1 -0
- package/vendor/ink/build/kitty-keyboard.d.ts +23 -0
- package/vendor/ink/build/kitty-keyboard.js +32 -0
- package/vendor/ink/build/kitty-keyboard.js.map +1 -0
- package/vendor/ink/build/layout.d.ts +7 -0
- package/vendor/ink/build/layout.js +33 -0
- package/vendor/ink/build/layout.js.map +1 -0
- package/vendor/ink/build/log-update.d.ts +19 -0
- package/vendor/ink/build/log-update.js +243 -0
- package/vendor/ink/build/log-update.js.map +1 -0
- package/vendor/ink/build/measure-element.d.ts +16 -0
- package/vendor/ink/build/measure-element.js +9 -0
- package/vendor/ink/build/measure-element.js.map +1 -0
- package/vendor/ink/build/measure-text.d.ts +6 -0
- package/vendor/ink/build/measure-text.js +21 -0
- package/vendor/ink/build/measure-text.js.map +1 -0
- package/vendor/ink/build/options.d.ts +52 -0
- package/vendor/ink/build/options.js +2 -0
- package/vendor/ink/build/options.js.map +1 -0
- package/vendor/ink/build/output.d.ts +35 -0
- package/vendor/ink/build/output.js +183 -0
- package/vendor/ink/build/output.js.map +1 -0
- package/vendor/ink/build/parse-keypress.d.ts +22 -0
- package/vendor/ink/build/parse-keypress.js +493 -0
- package/vendor/ink/build/parse-keypress.js.map +1 -0
- package/vendor/ink/build/reconciler.d.ts +4 -0
- package/vendor/ink/build/reconciler.js +274 -0
- package/vendor/ink/build/reconciler.js.map +1 -0
- package/vendor/ink/build/render-background.d.ts +4 -0
- package/vendor/ink/build/render-background.js +25 -0
- package/vendor/ink/build/render-background.js.map +1 -0
- package/vendor/ink/build/render-border.d.ts +4 -0
- package/vendor/ink/build/render-border.js +73 -0
- package/vendor/ink/build/render-border.js.map +1 -0
- package/vendor/ink/build/render-node-to-output.d.ts +14 -0
- package/vendor/ink/build/render-node-to-output.js +147 -0
- package/vendor/ink/build/render-node-to-output.js.map +1 -0
- package/vendor/ink/build/render-to-string.d.ts +38 -0
- package/vendor/ink/build/render-to-string.js +115 -0
- package/vendor/ink/build/render-to-string.js.map +1 -0
- package/vendor/ink/build/render.d.ts +121 -0
- package/vendor/ink/build/render.js +55 -0
- package/vendor/ink/build/render.js.map +1 -0
- package/vendor/ink/build/renderer.d.ts +8 -0
- package/vendor/ink/build/renderer.js +55 -0
- package/vendor/ink/build/renderer.js.map +1 -0
- package/vendor/ink/build/sanitize-ansi.d.ts +2 -0
- package/vendor/ink/build/sanitize-ansi.js +27 -0
- package/vendor/ink/build/sanitize-ansi.js.map +1 -0
- package/vendor/ink/build/screen-reader-update.d.ts +13 -0
- package/vendor/ink/build/screen-reader-update.js +38 -0
- package/vendor/ink/build/screen-reader-update.js.map +1 -0
- package/vendor/ink/build/squash-text-nodes.d.ts +3 -0
- package/vendor/ink/build/squash-text-nodes.js +36 -0
- package/vendor/ink/build/squash-text-nodes.js.map +1 -0
- package/vendor/ink/build/styles.d.ts +240 -0
- package/vendor/ink/build/styles.js +232 -0
- package/vendor/ink/build/styles.js.map +1 -0
- package/vendor/ink/build/utils.d.ts +2 -0
- package/vendor/ink/build/utils.js +4 -0
- package/vendor/ink/build/utils.js.map +1 -0
- package/vendor/ink/build/wrap-text.d.ts +3 -0
- package/vendor/ink/build/wrap-text.js +31 -0
- package/vendor/ink/build/wrap-text.js.map +1 -0
- package/vendor/ink/build/write-synchronized.d.ts +4 -0
- package/vendor/ink/build/write-synchronized.js +7 -0
- package/vendor/ink/build/write-synchronized.js.map +1 -0
- package/vendor/ink/license +10 -0
- package/vendor/ink/node_modules/@types/node/LICENSE +21 -0
- package/vendor/ink/node_modules/@types/node/README.md +15 -0
- package/vendor/ink/node_modules/@types/node/assert/strict.d.ts +105 -0
- package/vendor/ink/node_modules/@types/node/assert.d.ts +955 -0
- package/vendor/ink/node_modules/@types/node/async_hooks.d.ts +623 -0
- package/vendor/ink/node_modules/@types/node/buffer.buffer.d.ts +466 -0
- package/vendor/ink/node_modules/@types/node/buffer.d.ts +1810 -0
- package/vendor/ink/node_modules/@types/node/child_process.d.ts +1428 -0
- package/vendor/ink/node_modules/@types/node/cluster.d.ts +486 -0
- package/vendor/ink/node_modules/@types/node/compatibility/iterators.d.ts +21 -0
- package/vendor/ink/node_modules/@types/node/console.d.ts +151 -0
- package/vendor/ink/node_modules/@types/node/constants.d.ts +20 -0
- package/vendor/ink/node_modules/@types/node/crypto.d.ts +4065 -0
- package/vendor/ink/node_modules/@types/node/dgram.d.ts +564 -0
- package/vendor/ink/node_modules/@types/node/diagnostics_channel.d.ts +576 -0
- package/vendor/ink/node_modules/@types/node/dns/promises.d.ts +503 -0
- package/vendor/ink/node_modules/@types/node/dns.d.ts +922 -0
- package/vendor/ink/node_modules/@types/node/domain.d.ts +166 -0
- package/vendor/ink/node_modules/@types/node/events.d.ts +1054 -0
- package/vendor/ink/node_modules/@types/node/fs/promises.d.ts +1329 -0
- package/vendor/ink/node_modules/@types/node/fs.d.ts +4676 -0
- package/vendor/ink/node_modules/@types/node/globals.d.ts +150 -0
- package/vendor/ink/node_modules/@types/node/globals.typedarray.d.ts +101 -0
- package/vendor/ink/node_modules/@types/node/http.d.ts +2167 -0
- package/vendor/ink/node_modules/@types/node/http2.d.ts +2480 -0
- package/vendor/ink/node_modules/@types/node/https.d.ts +405 -0
- package/vendor/ink/node_modules/@types/node/index.d.ts +115 -0
- package/vendor/ink/node_modules/@types/node/inspector/promises.d.ts +41 -0
- package/vendor/ink/node_modules/@types/node/inspector.d.ts +224 -0
- package/vendor/ink/node_modules/@types/node/inspector.generated.d.ts +4226 -0
- package/vendor/ink/node_modules/@types/node/module.d.ts +819 -0
- package/vendor/ink/node_modules/@types/node/net.d.ts +933 -0
- package/vendor/ink/node_modules/@types/node/os.d.ts +507 -0
- package/vendor/ink/node_modules/@types/node/package.json +155 -0
- package/vendor/ink/node_modules/@types/node/path/posix.d.ts +8 -0
- package/vendor/ink/node_modules/@types/node/path/win32.d.ts +8 -0
- package/vendor/ink/node_modules/@types/node/path.d.ts +187 -0
- package/vendor/ink/node_modules/@types/node/perf_hooks.d.ts +643 -0
- package/vendor/ink/node_modules/@types/node/process.d.ts +2156 -0
- package/vendor/ink/node_modules/@types/node/punycode.d.ts +117 -0
- package/vendor/ink/node_modules/@types/node/querystring.d.ts +152 -0
- package/vendor/ink/node_modules/@types/node/quic.d.ts +910 -0
- package/vendor/ink/node_modules/@types/node/readline/promises.d.ts +161 -0
- package/vendor/ink/node_modules/@types/node/readline.d.ts +541 -0
- package/vendor/ink/node_modules/@types/node/repl.d.ts +415 -0
- package/vendor/ink/node_modules/@types/node/sea.d.ts +162 -0
- package/vendor/ink/node_modules/@types/node/sqlite.d.ts +955 -0
- package/vendor/ink/node_modules/@types/node/stream/consumers.d.ts +38 -0
- package/vendor/ink/node_modules/@types/node/stream/promises.d.ts +211 -0
- package/vendor/ink/node_modules/@types/node/stream/web.d.ts +296 -0
- package/vendor/ink/node_modules/@types/node/stream.d.ts +1760 -0
- package/vendor/ink/node_modules/@types/node/string_decoder.d.ts +67 -0
- package/vendor/ink/node_modules/@types/node/test/reporters.d.ts +96 -0
- package/vendor/ink/node_modules/@types/node/test.d.ts +2240 -0
- package/vendor/ink/node_modules/@types/node/timers/promises.d.ts +108 -0
- package/vendor/ink/node_modules/@types/node/timers.d.ts +159 -0
- package/vendor/ink/node_modules/@types/node/tls.d.ts +1198 -0
- package/vendor/ink/node_modules/@types/node/trace_events.d.ts +197 -0
- package/vendor/ink/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +462 -0
- package/vendor/ink/node_modules/@types/node/ts5.6/compatibility/float16array.d.ts +71 -0
- package/vendor/ink/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +36 -0
- package/vendor/ink/node_modules/@types/node/ts5.6/index.d.ts +117 -0
- package/vendor/ink/node_modules/@types/node/ts5.7/compatibility/float16array.d.ts +72 -0
- package/vendor/ink/node_modules/@types/node/ts5.7/index.d.ts +117 -0
- package/vendor/ink/node_modules/@types/node/tty.d.ts +250 -0
- package/vendor/ink/node_modules/@types/node/url.d.ts +519 -0
- package/vendor/ink/node_modules/@types/node/util/types.d.ts +558 -0
- package/vendor/ink/node_modules/@types/node/util.d.ts +1662 -0
- package/vendor/ink/node_modules/@types/node/v8.d.ts +983 -0
- package/vendor/ink/node_modules/@types/node/vm.d.ts +1208 -0
- package/vendor/ink/node_modules/@types/node/wasi.d.ts +202 -0
- package/vendor/ink/node_modules/@types/node/web-globals/abortcontroller.d.ts +59 -0
- package/vendor/ink/node_modules/@types/node/web-globals/blob.d.ts +23 -0
- package/vendor/ink/node_modules/@types/node/web-globals/console.d.ts +9 -0
- package/vendor/ink/node_modules/@types/node/web-globals/crypto.d.ts +39 -0
- package/vendor/ink/node_modules/@types/node/web-globals/domexception.d.ts +68 -0
- package/vendor/ink/node_modules/@types/node/web-globals/encoding.d.ts +11 -0
- package/vendor/ink/node_modules/@types/node/web-globals/events.d.ts +106 -0
- package/vendor/ink/node_modules/@types/node/web-globals/fetch.d.ts +69 -0
- package/vendor/ink/node_modules/@types/node/web-globals/importmeta.d.ts +13 -0
- package/vendor/ink/node_modules/@types/node/web-globals/messaging.d.ts +23 -0
- package/vendor/ink/node_modules/@types/node/web-globals/navigator.d.ts +25 -0
- package/vendor/ink/node_modules/@types/node/web-globals/performance.d.ts +45 -0
- package/vendor/ink/node_modules/@types/node/web-globals/storage.d.ts +24 -0
- package/vendor/ink/node_modules/@types/node/web-globals/streams.d.ts +115 -0
- package/vendor/ink/node_modules/@types/node/web-globals/timers.d.ts +44 -0
- package/vendor/ink/node_modules/@types/node/web-globals/url.d.ts +24 -0
- package/vendor/ink/node_modules/@types/node/worker_threads.d.ts +717 -0
- package/vendor/ink/node_modules/@types/node/zlib.d.ts +618 -0
- package/vendor/ink/node_modules/node-pty/LICENSE +69 -0
- package/vendor/ink/node_modules/node-pty/README.md +164 -0
- package/vendor/ink/node_modules/node-pty/binding.gyp +150 -0
- package/vendor/ink/node_modules/node-pty/lib/conpty_console_list_agent.js +25 -0
- package/vendor/ink/node_modules/node-pty/lib/eventEmitter2.js +47 -0
- package/vendor/ink/node_modules/node-pty/lib/index.js +52 -0
- package/vendor/ink/node_modules/node-pty/lib/interfaces.js +7 -0
- package/vendor/ink/node_modules/node-pty/lib/shared/conout.js +11 -0
- package/vendor/ink/node_modules/node-pty/lib/terminal.js +190 -0
- package/vendor/ink/node_modules/node-pty/lib/types.js +7 -0
- package/vendor/ink/node_modules/node-pty/lib/unixTerminal.js +349 -0
- package/vendor/ink/node_modules/node-pty/lib/utils.js +39 -0
- package/vendor/ink/node_modules/node-pty/lib/windowsConoutConnection.js +125 -0
- package/vendor/ink/node_modules/node-pty/lib/windowsPtyAgent.js +287 -0
- package/vendor/ink/node_modules/node-pty/lib/windowsTerminal.js +201 -0
- package/vendor/ink/node_modules/node-pty/lib/worker/conoutSocketWorker.js +22 -0
- package/vendor/ink/node_modules/node-pty/package.json +65 -0
- package/vendor/ink/node_modules/node-pty/prebuilds/darwin-arm64/pty.node +0 -0
- package/vendor/ink/node_modules/node-pty/prebuilds/darwin-arm64/spawn-helper +0 -0
- package/vendor/ink/node_modules/node-pty/prebuilds/darwin-x64/pty.node +0 -0
- package/vendor/ink/node_modules/node-pty/prebuilds/darwin-x64/spawn-helper +0 -0
- package/vendor/ink/node_modules/node-pty/prebuilds/linux-arm64/pty.node +0 -0
- package/vendor/ink/node_modules/node-pty/prebuilds/linux-x64/pty.node +0 -0
- package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty/OpenConsole.exe +0 -0
- package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty/conpty.dll +0 -0
- package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty.node +0 -0
- package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty.pdb +0 -0
- package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty_console_list.node +0 -0
- package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty_console_list.pdb +0 -0
- package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty/OpenConsole.exe +0 -0
- package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty/conpty.dll +0 -0
- package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty.node +0 -0
- package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty.pdb +0 -0
- package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty_console_list.node +0 -0
- package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty_console_list.pdb +0 -0
- package/vendor/ink/node_modules/node-pty/scripts/post-install.js +76 -0
- package/vendor/ink/node_modules/node-pty/scripts/prebuild.js +34 -0
- package/vendor/ink/node_modules/node-pty/src/unix/pty.cc +875 -0
- package/vendor/ink/node_modules/node-pty/src/unix/spawn-helper.cc +23 -0
- package/vendor/ink/node_modules/node-pty/src/win/conpty.cc +582 -0
- package/vendor/ink/node_modules/node-pty/src/win/conpty.h +41 -0
- package/vendor/ink/node_modules/node-pty/src/win/conpty_console_list.cc +44 -0
- package/vendor/ink/node_modules/node-pty/src/win/path_util.cc +95 -0
- package/vendor/ink/node_modules/node-pty/src/win/path_util.h +26 -0
- package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-arm64/OpenConsole.exe +0 -0
- package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-arm64/conpty.dll +0 -0
- package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-x64/OpenConsole.exe +0 -0
- package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-x64/conpty.dll +0 -0
- package/vendor/ink/node_modules/node-pty/typings/node-pty.d.ts +215 -0
- package/vendor/ink/node_modules/undici-types/LICENSE +21 -0
- package/vendor/ink/node_modules/undici-types/README.md +6 -0
- package/vendor/ink/node_modules/undici-types/agent.d.ts +32 -0
- package/vendor/ink/node_modules/undici-types/api.d.ts +43 -0
- package/vendor/ink/node_modules/undici-types/balanced-pool.d.ts +30 -0
- package/vendor/ink/node_modules/undici-types/cache-interceptor.d.ts +173 -0
- package/vendor/ink/node_modules/undici-types/cache.d.ts +36 -0
- package/vendor/ink/node_modules/undici-types/client-stats.d.ts +15 -0
- package/vendor/ink/node_modules/undici-types/client.d.ts +108 -0
- package/vendor/ink/node_modules/undici-types/connector.d.ts +34 -0
- package/vendor/ink/node_modules/undici-types/content-type.d.ts +21 -0
- package/vendor/ink/node_modules/undici-types/cookies.d.ts +30 -0
- package/vendor/ink/node_modules/undici-types/diagnostics-channel.d.ts +74 -0
- package/vendor/ink/node_modules/undici-types/dispatcher.d.ts +276 -0
- package/vendor/ink/node_modules/undici-types/env-http-proxy-agent.d.ts +22 -0
- package/vendor/ink/node_modules/undici-types/errors.d.ts +161 -0
- package/vendor/ink/node_modules/undici-types/eventsource.d.ts +66 -0
- package/vendor/ink/node_modules/undici-types/fetch.d.ts +211 -0
- package/vendor/ink/node_modules/undici-types/formdata.d.ts +108 -0
- package/vendor/ink/node_modules/undici-types/global-dispatcher.d.ts +9 -0
- package/vendor/ink/node_modules/undici-types/global-origin.d.ts +7 -0
- package/vendor/ink/node_modules/undici-types/h2c-client.d.ts +73 -0
- package/vendor/ink/node_modules/undici-types/handlers.d.ts +15 -0
- package/vendor/ink/node_modules/undici-types/header.d.ts +160 -0
- package/vendor/ink/node_modules/undici-types/index.d.ts +88 -0
- package/vendor/ink/node_modules/undici-types/interceptors.d.ts +73 -0
- package/vendor/ink/node_modules/undici-types/mock-agent.d.ts +68 -0
- package/vendor/ink/node_modules/undici-types/mock-call-history.d.ts +111 -0
- package/vendor/ink/node_modules/undici-types/mock-client.d.ts +27 -0
- package/vendor/ink/node_modules/undici-types/mock-errors.d.ts +12 -0
- package/vendor/ink/node_modules/undici-types/mock-interceptor.d.ts +94 -0
- package/vendor/ink/node_modules/undici-types/mock-pool.d.ts +27 -0
- package/vendor/ink/node_modules/undici-types/package.json +55 -0
- package/vendor/ink/node_modules/undici-types/patch.d.ts +29 -0
- package/vendor/ink/node_modules/undici-types/pool-stats.d.ts +19 -0
- package/vendor/ink/node_modules/undici-types/pool.d.ts +41 -0
- package/vendor/ink/node_modules/undici-types/proxy-agent.d.ts +29 -0
- package/vendor/ink/node_modules/undici-types/readable.d.ts +68 -0
- package/vendor/ink/node_modules/undici-types/retry-agent.d.ts +8 -0
- package/vendor/ink/node_modules/undici-types/retry-handler.d.ts +125 -0
- package/vendor/ink/node_modules/undici-types/round-robin-pool.d.ts +41 -0
- package/vendor/ink/node_modules/undici-types/snapshot-agent.d.ts +109 -0
- package/vendor/ink/node_modules/undici-types/util.d.ts +18 -0
- package/vendor/ink/node_modules/undici-types/utility.d.ts +7 -0
- package/vendor/ink/node_modules/undici-types/webidl.d.ts +341 -0
- package/vendor/ink/node_modules/undici-types/websocket.d.ts +186 -0
- package/vendor/ink/package.json +201 -0
- package/vendor/ink/readme.md +2636 -0
- package/bin/swag-agent.js +0 -9
- package/dist/server/lib/pg-rate-limiter.d.ts +0 -21
- package/dist/server/lib/pg-rate-limiter.js +0 -86
|
@@ -4,7 +4,25 @@
|
|
|
4
4
|
* Pure TypeScript, no runtime-specific APIs (no Deno.env, no process.env, no fs).
|
|
5
5
|
* Both the CLI (Node.js) and server (Fly container) import from here.
|
|
6
6
|
*/
|
|
7
|
+
|
|
7
8
|
import { getProvider } from "./constants.js";
|
|
9
|
+
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// TYPES
|
|
12
|
+
// ============================================================================
|
|
13
|
+
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// TOOL CHOICE
|
|
16
|
+
// ============================================================================
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Controls which tools the model can/must use:
|
|
20
|
+
* - "auto": Model decides whether to use tools (default)
|
|
21
|
+
* - "any": Model must use at least one tool
|
|
22
|
+
* - "none": Model must not use any tools (text-only response)
|
|
23
|
+
* - { type: "tool", name: string }: Model must use the specified tool
|
|
24
|
+
*/
|
|
25
|
+
|
|
8
26
|
/**
|
|
9
27
|
* Resolve the effective tool_choice for a given turn.
|
|
10
28
|
*
|
|
@@ -15,102 +33,164 @@ import { getProvider } from "./constants.js";
|
|
|
15
33
|
* 4. Default: "auto"
|
|
16
34
|
*/
|
|
17
35
|
export function resolveToolChoice(opts) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
// 2b. Alternating pattern detection: catch A→B→A→B→A→B death spirals (e.g. read→edit→read→edit)
|
|
29
|
-
if (opts.recentToolUses.length >= 6) {
|
|
30
|
-
const last6 = opts.recentToolUses.slice(-6);
|
|
31
|
-
const isRepeatingPair = last6[2] === last6[0] && last6[3] === last6[1] &&
|
|
32
|
-
last6[4] === last6[0] && last6[5] === last6[1];
|
|
33
|
-
if (isRepeatingPair)
|
|
34
|
-
return "none";
|
|
36
|
+
// 1. Explicit override always wins
|
|
37
|
+
if (opts.toolChoice !== undefined) return opts.toolChoice;
|
|
38
|
+
|
|
39
|
+
// 2. Loop detection: if last 3+ turns all used the exact same tool, force text
|
|
40
|
+
if (opts.recentToolUses.length >= 3) {
|
|
41
|
+
const last3 = opts.recentToolUses.slice(-3);
|
|
42
|
+
if (last3[0] === last3[1] && last3[1] === last3[2]) {
|
|
43
|
+
return "none";
|
|
35
44
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 2b. Alternating pattern detection: catch A→B→A→B→A→B death spirals (e.g. read→edit→read→edit)
|
|
48
|
+
if (opts.recentToolUses.length >= 6) {
|
|
49
|
+
const last6 = opts.recentToolUses.slice(-6);
|
|
50
|
+
const isRepeatingPair = last6[2] === last6[0] && last6[3] === last6[1] && last6[4] === last6[0] && last6[5] === last6[1];
|
|
51
|
+
if (isRepeatingPair) return "none";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 3. Keyword matching: check if the user message mentions a specific tool name
|
|
55
|
+
// Only on the first turn (avoids false positives on multi-turn conversations)
|
|
56
|
+
if (opts.turnCount === 1 && opts.userMessage && opts.availableToolNames.length > 0) {
|
|
57
|
+
const msgLower = opts.userMessage.toLowerCase();
|
|
58
|
+
for (const toolName of opts.availableToolNames) {
|
|
59
|
+
// Match tool name as a whole word (e.g. "blender_do" not "do")
|
|
60
|
+
// Only consider tool names >= 4 chars to avoid false positives
|
|
61
|
+
if (toolName.length >= 4 && msgLower.includes(toolName.toLowerCase())) {
|
|
62
|
+
return {
|
|
63
|
+
type: "tool",
|
|
64
|
+
name: toolName
|
|
65
|
+
};
|
|
66
|
+
}
|
|
47
67
|
}
|
|
48
|
-
|
|
49
|
-
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 4. Default
|
|
71
|
+
return "auto";
|
|
50
72
|
}
|
|
73
|
+
|
|
74
|
+
/** Overrides from ai_agent_config.context_config JSONB — all optional, falls back to defaults */
|
|
75
|
+
|
|
51
76
|
// ============================================================================
|
|
52
77
|
// MODEL-AWARE CONTEXT MANAGEMENT
|
|
53
78
|
// ============================================================================
|
|
54
|
-
|
|
55
|
-
export
|
|
56
|
-
|
|
79
|
+
|
|
80
|
+
// These re-export from AGENT_DEFAULTS so there's exactly one place to change.
|
|
81
|
+
// DB context_config always overrides these via resolveAgentLoopConfig().
|
|
82
|
+
|
|
83
|
+
/** Legacy compaction trigger — used by getCompactionConfig() for non-Anthropic providers. */
|
|
84
|
+
export const COMPACTION_TRIGGER_TOKENS = 167_000;
|
|
85
|
+
/** Max cumulative tokens before forcing wrap-up */
|
|
57
86
|
export const COMPACTION_TOTAL_BUDGET = 2_000_000;
|
|
58
|
-
/**
|
|
59
|
-
export const DEFAULT_SESSION_COST_BUDGET_USD =
|
|
87
|
+
/** Session cost safety cap — DB context_config.session_cost_budget_usd overrides */
|
|
88
|
+
export const DEFAULT_SESSION_COST_BUDGET_USD = 25.00;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Provider-aware compaction configuration.
|
|
92
|
+
* - Anthropic/Bedrock: native server-side compaction via compact_20260112
|
|
93
|
+
* - OpenAI/Gemini: Haiku-based summarization (same instructions, same format)
|
|
94
|
+
*/
|
|
95
|
+
|
|
60
96
|
export function getCompactionConfig(model) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
97
|
+
const provider = getProvider(model);
|
|
98
|
+
switch (provider) {
|
|
99
|
+
case "gemini":
|
|
100
|
+
return {
|
|
101
|
+
triggerTokens: 700_000,
|
|
102
|
+
totalBudget: 4_000_000,
|
|
103
|
+
isNative: false
|
|
104
|
+
};
|
|
105
|
+
case "openai":
|
|
106
|
+
return {
|
|
107
|
+
triggerTokens: 120_000,
|
|
108
|
+
totalBudget: 2_000_000,
|
|
109
|
+
isNative: false
|
|
110
|
+
};
|
|
111
|
+
case "bedrock":
|
|
112
|
+
case "anthropic":
|
|
113
|
+
default:
|
|
114
|
+
return {
|
|
115
|
+
triggerTokens: COMPACTION_TRIGGER_TOKENS,
|
|
116
|
+
totalBudget: COMPACTION_TOTAL_BUDGET,
|
|
117
|
+
isNative: true
|
|
118
|
+
};
|
|
119
|
+
}
|
|
72
120
|
}
|
|
121
|
+
|
|
73
122
|
/**
|
|
74
123
|
* Returns Anthropic beta flags and context_management config for the given model.
|
|
75
124
|
* - Opus 4.6 / Sonnet 4.6: compact at 120K (pause after) + clear thinking + clear tools at 80K/keep 3
|
|
76
125
|
* - All other Claude models: clear thinking + clear tools at 80K/keep 3
|
|
77
126
|
* - Non-Anthropic models (Gemini, OpenAI): no betas, no context management
|
|
78
127
|
*/
|
|
79
|
-
export function getContextManagement(model) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
128
|
+
export function getContextManagement(model, overrides) {
|
|
129
|
+
// Non-Anthropic models don't use Anthropic betas or context management
|
|
130
|
+
const provider = getProvider(model);
|
|
131
|
+
if (provider === "gemini" || provider === "openai") {
|
|
132
|
+
return {
|
|
133
|
+
betas: [],
|
|
134
|
+
config: {
|
|
135
|
+
edits: []
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
const edits = [];
|
|
140
|
+
const betas = ["context-management-2025-06-27"];
|
|
141
|
+
|
|
142
|
+
// Thinking block clearing — must come FIRST in edits array (API requirement).
|
|
143
|
+
// Default: keep 1 thinking turn (matches Claude Code / Anthropic API defaults).
|
|
144
|
+
const clearThinkingKeep = overrides?.clear_thinking_keep ?? 1;
|
|
145
|
+
edits.push({
|
|
146
|
+
type: "clear_thinking_20251015",
|
|
147
|
+
keep: {
|
|
148
|
+
type: "thinking_turns",
|
|
149
|
+
value: clearThinkingKeep
|
|
84
150
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// Server-side compaction for models that support compact_20260112.
|
|
154
|
+
// Default trigger: 150K tokens (matches Anthropic API default).
|
|
155
|
+
// pause_after_compaction: true enables the loop to preserve recent messages
|
|
156
|
+
// and track compaction count for budget enforcement.
|
|
157
|
+
const supportsCompaction = model.includes("opus-4-6") || model.includes("sonnet-4-6");
|
|
158
|
+
const compactionTrigger = overrides?.compaction_trigger_tokens ?? AGENT_DEFAULTS.compactionTriggerTokens;
|
|
159
|
+
if (supportsCompaction) {
|
|
90
160
|
edits.push({
|
|
91
|
-
|
|
92
|
-
|
|
161
|
+
type: "compact_20260112",
|
|
162
|
+
trigger: {
|
|
163
|
+
type: "input_tokens",
|
|
164
|
+
value: compactionTrigger
|
|
165
|
+
},
|
|
166
|
+
pause_after_compaction: true,
|
|
167
|
+
instructions: "Summarize the conversation preserving: (1) task goals and constraints, (2) files created/modified with paths, (3) decisions made and rationale, (4) errors encountered and resolutions, (5) exact next steps. Be concise but preserve all state needed to continue work without repeating mistakes."
|
|
93
168
|
});
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
169
|
+
betas.push("compact-2026-01-12");
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Clear tool uses — default: trigger at 100K, keep 3 (matches Anthropic API defaults).
|
|
173
|
+
const clearToolUsesTrigger = overrides?.clear_tool_uses_trigger ?? 100_000;
|
|
174
|
+
const clearToolUsesKeep = overrides?.clear_tool_uses_keep ?? 3;
|
|
175
|
+
edits.push({
|
|
176
|
+
type: "clear_tool_uses_20250919",
|
|
177
|
+
trigger: {
|
|
178
|
+
type: "input_tokens",
|
|
179
|
+
value: clearToolUsesTrigger
|
|
180
|
+
},
|
|
181
|
+
keep: {
|
|
182
|
+
type: "tool_uses",
|
|
183
|
+
value: clearToolUsesKeep
|
|
106
184
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
185
|
+
});
|
|
186
|
+
return {
|
|
187
|
+
betas,
|
|
188
|
+
config: {
|
|
189
|
+
edits
|
|
190
|
+
}
|
|
191
|
+
};
|
|
113
192
|
}
|
|
193
|
+
|
|
114
194
|
/**
|
|
115
195
|
* Model-aware max output tokens.
|
|
116
196
|
* Agent config max_tokens takes priority but is capped at model maximum.
|
|
@@ -118,50 +198,62 @@ export function getContextManagement(model) {
|
|
|
118
198
|
* DEFAULT_OUTPUT_TOKENS is the sensible per-response cap (like Claude Code's ~16K).
|
|
119
199
|
* The full MODEL_MAX is only used when explicitly requested via agentMax.
|
|
120
200
|
*/
|
|
121
|
-
|
|
201
|
+
// Fallback only when DB agent.max_tokens is null/0. DB value (ai_agent_config.max_tokens) takes priority.
|
|
202
|
+
const DEFAULT_OUTPUT_TOKENS = 32000;
|
|
122
203
|
const MODEL_MAX_OUTPUT_TOKENS = {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
204
|
+
// Anthropic — current models (actual API-enforced limits)
|
|
205
|
+
"claude-opus-4-6": 128000,
|
|
206
|
+
// 128K
|
|
207
|
+
"claude-sonnet-4-6": 64000,
|
|
208
|
+
// 64K (API enforces 64000, not 65536)
|
|
209
|
+
"claude-haiku-4-5-20251001": 64000,
|
|
210
|
+
// 64K
|
|
211
|
+
// Anthropic — legacy models
|
|
212
|
+
"claude-sonnet-4-5-20250929": 64000,
|
|
213
|
+
// 64K (API enforces 64000)
|
|
214
|
+
"claude-opus-4-5-20251101": 64000,
|
|
215
|
+
// 64K
|
|
216
|
+
"claude-opus-4-1-20250805": 32768,
|
|
217
|
+
// 32K
|
|
218
|
+
"claude-sonnet-4-20250514": 64000,
|
|
219
|
+
// 64K
|
|
220
|
+
"claude-opus-4-20250514": 32768,
|
|
221
|
+
// 32K
|
|
222
|
+
"claude-3-7-sonnet-20250219": 64000,
|
|
223
|
+
// 64K
|
|
224
|
+
"claude-3-haiku-20240307": 4096,
|
|
225
|
+
// 4K
|
|
226
|
+
// Bedrock — same limits as direct API
|
|
227
|
+
"anthropic.claude-sonnet-4-6": 64000,
|
|
228
|
+
"us.anthropic.claude-sonnet-4-20250514-v1:0": 64000,
|
|
229
|
+
"us.anthropic.claude-sonnet-4-5-20250929-v1:0": 64000,
|
|
230
|
+
"us.anthropic.claude-haiku-4-5-20251001-v1:0": 64000,
|
|
231
|
+
// Google Gemini
|
|
232
|
+
"gemini-3-pro-preview": 65536,
|
|
233
|
+
"gemini-3-flash-preview": 65536,
|
|
234
|
+
"gemini-2.5-pro": 65536,
|
|
235
|
+
"gemini-2.5-flash": 65536,
|
|
236
|
+
"gemini-2.5-flash-lite": 65536,
|
|
237
|
+
// OpenAI — GPT-5 family: 128K max output, o-series: 100K
|
|
238
|
+
"gpt-5": 128000,
|
|
239
|
+
"gpt-5-mini": 128000,
|
|
240
|
+
"gpt-5-nano": 128000,
|
|
241
|
+
"o3": 100000,
|
|
242
|
+
"o4-mini": 100000,
|
|
243
|
+
"gpt-4o": 16384
|
|
153
244
|
};
|
|
154
245
|
export function getMaxOutputTokens(model, agentMax) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
return Math.min(DEFAULT_OUTPUT_TOKENS, modelMax);
|
|
246
|
+
const modelMax = MODEL_MAX_OUTPUT_TOKENS[model] ?? DEFAULT_OUTPUT_TOKENS;
|
|
247
|
+
// If caller explicitly sets agentMax, respect it (capped at model max).
|
|
248
|
+
// Otherwise use sane default — never auto-request 128K output.
|
|
249
|
+
if (agentMax) return Math.min(agentMax, modelMax);
|
|
250
|
+
return Math.min(DEFAULT_OUTPUT_TOKENS, modelMax);
|
|
161
251
|
}
|
|
252
|
+
|
|
162
253
|
// ============================================================================
|
|
163
254
|
// MULTI-BREAKPOINT PROMPT CACHING
|
|
164
255
|
// ============================================================================
|
|
256
|
+
|
|
165
257
|
/**
|
|
166
258
|
* Add prompt cache breakpoints to tools and messages.
|
|
167
259
|
* Uses 2 of 4 allowed breakpoints:
|
|
@@ -170,204 +262,293 @@ export function getMaxOutputTokens(model, agentMax) {
|
|
|
170
262
|
* System prompt caching is handled by the caller.
|
|
171
263
|
*/
|
|
172
264
|
export function addPromptCaching(tools, messages) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
265
|
+
const cachedTools = tools.length > 0 ? [...tools.slice(0, -1), {
|
|
266
|
+
...tools[tools.length - 1],
|
|
267
|
+
cache_control: {
|
|
268
|
+
type: "ephemeral"
|
|
269
|
+
}
|
|
270
|
+
}] : [...tools];
|
|
271
|
+
const cachedMessages = [...messages];
|
|
272
|
+
if (cachedMessages.length >= 2) {
|
|
273
|
+
const idx = cachedMessages.length - 2;
|
|
274
|
+
const msg = cachedMessages[idx];
|
|
275
|
+
if (typeof msg.content === "string") {
|
|
276
|
+
cachedMessages[idx] = {
|
|
277
|
+
...msg,
|
|
278
|
+
content: [{
|
|
279
|
+
type: "text",
|
|
280
|
+
text: msg.content,
|
|
281
|
+
cache_control: {
|
|
282
|
+
type: "ephemeral"
|
|
283
|
+
}
|
|
284
|
+
}]
|
|
285
|
+
};
|
|
286
|
+
} else if (Array.isArray(msg.content)) {
|
|
287
|
+
const blocks = [...msg.content];
|
|
288
|
+
blocks[blocks.length - 1] = {
|
|
289
|
+
...blocks[blocks.length - 1],
|
|
290
|
+
cache_control: {
|
|
291
|
+
type: "ephemeral"
|
|
190
292
|
}
|
|
293
|
+
};
|
|
294
|
+
cachedMessages[idx] = {
|
|
295
|
+
...msg,
|
|
296
|
+
content: blocks
|
|
297
|
+
};
|
|
191
298
|
}
|
|
192
|
-
|
|
299
|
+
}
|
|
300
|
+
return {
|
|
301
|
+
tools: cachedTools,
|
|
302
|
+
messages: cachedMessages
|
|
303
|
+
};
|
|
193
304
|
}
|
|
305
|
+
|
|
194
306
|
// ============================================================================
|
|
195
307
|
// LOOP DETECTION
|
|
196
308
|
// ============================================================================
|
|
309
|
+
|
|
197
310
|
/** djb2 string hash — fast, deterministic, no dependencies */
|
|
198
311
|
export function djb2Hash(str) {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
312
|
+
let hash = 5381;
|
|
313
|
+
for (let i = 0; i < str.length; i++) {
|
|
314
|
+
hash = (hash << 5) + hash + str.charCodeAt(i) & 0xffffffff;
|
|
315
|
+
}
|
|
316
|
+
return hash.toString(36);
|
|
204
317
|
}
|
|
205
318
|
export class LoopDetector {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
319
|
+
history = [];
|
|
320
|
+
consecutiveErrors = new Map();
|
|
321
|
+
turnErrors = 0;
|
|
322
|
+
turnHadErrors = false;
|
|
323
|
+
sessionErrors = new Map();
|
|
324
|
+
failedStrategies = new Set();
|
|
325
|
+
consecutiveFailedTurns = 0;
|
|
326
|
+
totalSessionErrors = 0;
|
|
327
|
+
|
|
328
|
+
/** Tracks how many times the same file path has been read this session */
|
|
329
|
+
fileReadCounts = new Map();
|
|
330
|
+
|
|
331
|
+
/** Resolved config — accepts DB overrides, falls back to AGENT_DEFAULTS */
|
|
332
|
+
|
|
333
|
+
constructor(config) {
|
|
334
|
+
this.config = {
|
|
335
|
+
identicalCallLimit: config?.identicalCallLimit ?? AGENT_DEFAULTS.loopIdenticalCallLimit,
|
|
336
|
+
consecutiveErrorLimit: config?.consecutiveErrorLimit ?? AGENT_DEFAULTS.loopConsecutiveErrorLimit,
|
|
337
|
+
turnErrorLimit: config?.turnErrorLimit ?? AGENT_DEFAULTS.loopTurnErrorLimit,
|
|
338
|
+
window: config?.window ?? AGENT_DEFAULTS.loopWindow,
|
|
339
|
+
sessionToolErrorLimit: config?.sessionToolErrorLimit ?? AGENT_DEFAULTS.loopSessionToolErrorLimit,
|
|
340
|
+
consecutiveFailedTurnLimit: config?.consecutiveFailedTurnLimit ?? AGENT_DEFAULTS.loopConsecutiveFailedTurnLimit,
|
|
341
|
+
fileReadLimit: config?.fileReadLimit ?? AGENT_DEFAULTS.loopFileReadLimit
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/** Create a LoopDetector from a ResolvedAgentLoopConfig */
|
|
346
|
+
static fromResolved(resolved) {
|
|
347
|
+
return new LoopDetector({
|
|
348
|
+
identicalCallLimit: resolved.loopIdenticalCallLimit,
|
|
349
|
+
consecutiveErrorLimit: resolved.loopConsecutiveErrorLimit,
|
|
350
|
+
turnErrorLimit: resolved.loopTurnErrorLimit,
|
|
351
|
+
window: resolved.loopWindow,
|
|
352
|
+
sessionToolErrorLimit: resolved.loopSessionToolErrorLimit,
|
|
353
|
+
consecutiveFailedTurnLimit: resolved.loopConsecutiveFailedTurnLimit,
|
|
354
|
+
fileReadLimit: resolved.loopFileReadLimit
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/** Get the error-tracking key for a tool call. Tools with an `action` param
|
|
359
|
+
* are tracked per-action so e.g. voice/speak failing won't block voice/music_compose. */
|
|
360
|
+
errorKey(name, input) {
|
|
361
|
+
if (input && typeof input.action === "string") return `${name}:${input.action}`;
|
|
362
|
+
return name;
|
|
363
|
+
}
|
|
364
|
+
recordCall(name, input) {
|
|
365
|
+
const inputHash = djb2Hash(JSON.stringify({
|
|
366
|
+
name,
|
|
367
|
+
...input
|
|
368
|
+
}));
|
|
369
|
+
const eKey = this.errorKey(name, input);
|
|
370
|
+
if (this.failedStrategies.has(inputHash)) {
|
|
371
|
+
return {
|
|
372
|
+
blocked: true,
|
|
373
|
+
reason: `Blocked: this exact "${name}" call failed in a previous turn. Try a fundamentally different approach.`
|
|
374
|
+
};
|
|
229
375
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
reason: `Blocked: this exact "${name}" call failed in a previous turn. Try a fundamentally different approach.`,
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
const sessionErrorCount = this.sessionErrors.get(eKey) || 0;
|
|
240
|
-
if (sessionErrorCount >= LoopDetector.SESSION_TOOL_ERROR_LIMIT) {
|
|
241
|
-
return {
|
|
242
|
-
blocked: true,
|
|
243
|
-
reason: `Tool "${name}" (action: ${input.action || "default"}) has failed ${sessionErrorCount} times this session. Stop using this tool and try a different approach.`,
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
if (this.turnErrors >= LoopDetector.TURN_ERROR_LIMIT) {
|
|
247
|
-
return {
|
|
248
|
-
blocked: true,
|
|
249
|
-
reason: `${this.turnErrors} errors this turn. Stop and re-assess your approach.`,
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
const errorCount = this.consecutiveErrors.get(eKey) || 0;
|
|
253
|
-
if (errorCount >= LoopDetector.CONSECUTIVE_ERROR_LIMIT) {
|
|
254
|
-
return {
|
|
255
|
-
blocked: true,
|
|
256
|
-
reason: `Tool "${name}" (action: ${input.action || "default"}) blocked: failed ${errorCount} times consecutively. Try a different approach or action.`,
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
const windowSlice = this.history.slice(-LoopDetector.WINDOW);
|
|
260
|
-
const identicalCount = windowSlice.filter((h) => h.inputHash === inputHash).length;
|
|
261
|
-
if (identicalCount >= LoopDetector.IDENTICAL_CALL_LIMIT) {
|
|
262
|
-
return {
|
|
263
|
-
blocked: true,
|
|
264
|
-
reason: `Tool "${name}" blocked: identical call made ${identicalCount} times. Try different parameters.`,
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
this.history.push({ name, inputHash });
|
|
268
|
-
if (this.history.length > LoopDetector.WINDOW * 2) {
|
|
269
|
-
this.history = this.history.slice(-LoopDetector.WINDOW);
|
|
270
|
-
}
|
|
271
|
-
return { blocked: false };
|
|
376
|
+
const sessionErrorCount = this.sessionErrors.get(eKey) || 0;
|
|
377
|
+
if (sessionErrorCount >= this.config.sessionToolErrorLimit) {
|
|
378
|
+
return {
|
|
379
|
+
blocked: true,
|
|
380
|
+
reason: `Tool "${name}" (action: ${input.action || "default"}) has failed ${sessionErrorCount} times this session. Stop using this tool and try a different approach.`
|
|
381
|
+
};
|
|
272
382
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
const readCount = (this.fileReadCounts.get(path) || 0) + 1;
|
|
279
|
-
this.fileReadCounts.set(path, readCount);
|
|
280
|
-
if (readCount > LoopDetector.FILE_READ_LIMIT) {
|
|
281
|
-
return {
|
|
282
|
-
blocked: true,
|
|
283
|
-
reason: `File "${path}" already read ${readCount - 1} times this session. Use the content from a previous read instead of re-reading.`,
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
return { blocked: false };
|
|
383
|
+
if (this.turnErrors >= this.config.turnErrorLimit) {
|
|
384
|
+
return {
|
|
385
|
+
blocked: true,
|
|
386
|
+
reason: `${this.turnErrors} errors this turn. Stop and re-assess your approach.`
|
|
387
|
+
};
|
|
287
388
|
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
const current = this.consecutiveErrors.get(eKey) || 0;
|
|
295
|
-
this.consecutiveErrors.set(eKey, current + 1);
|
|
296
|
-
this.turnErrors++;
|
|
297
|
-
this.turnHadErrors = true;
|
|
298
|
-
const sessionCount = this.sessionErrors.get(eKey) || 0;
|
|
299
|
-
this.sessionErrors.set(eKey, sessionCount + 1);
|
|
300
|
-
this.totalSessionErrors++;
|
|
301
|
-
if (input) {
|
|
302
|
-
const inputHash = djb2Hash(JSON.stringify({ name, ...input }));
|
|
303
|
-
this.failedStrategies.add(inputHash);
|
|
304
|
-
if (this.failedStrategies.size > 200) {
|
|
305
|
-
const arr = Array.from(this.failedStrategies);
|
|
306
|
-
this.failedStrategies = new Set(arr.slice(-100));
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
389
|
+
const errorCount = this.consecutiveErrors.get(eKey) || 0;
|
|
390
|
+
if (errorCount >= this.config.consecutiveErrorLimit) {
|
|
391
|
+
return {
|
|
392
|
+
blocked: true,
|
|
393
|
+
reason: `Tool "${name}" (action: ${input.action || "default"}) blocked: failed ${errorCount} times consecutively. Try a different approach or action.`
|
|
394
|
+
};
|
|
310
395
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
396
|
+
const windowSlice = this.history.slice(-this.config.window);
|
|
397
|
+
const identicalCount = windowSlice.filter(h => h.inputHash === inputHash).length;
|
|
398
|
+
if (identicalCount >= this.config.identicalCallLimit) {
|
|
399
|
+
return {
|
|
400
|
+
blocked: true,
|
|
401
|
+
reason: `Tool "${name}" blocked: identical call made ${identicalCount} times. Try different parameters.`
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
this.history.push({
|
|
405
|
+
name,
|
|
406
|
+
inputHash
|
|
407
|
+
});
|
|
408
|
+
if (this.history.length > this.config.window * 2) {
|
|
409
|
+
this.history = this.history.slice(-this.config.window);
|
|
410
|
+
}
|
|
411
|
+
return {
|
|
412
|
+
blocked: false
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Track file read frequency — call when the tool is known to be a file read.
|
|
418
|
+
* Blocks re-reading the same path more than FILE_READ_LIMIT times per session.
|
|
419
|
+
*/
|
|
420
|
+
trackRead(path) {
|
|
421
|
+
const readCount = (this.fileReadCounts.get(path) || 0) + 1;
|
|
422
|
+
this.fileReadCounts.set(path, readCount);
|
|
423
|
+
if (readCount > this.config.fileReadLimit) {
|
|
424
|
+
return {
|
|
425
|
+
blocked: true,
|
|
426
|
+
reason: `File "${path}" already read ${readCount - 1} times this session. Use the content from a previous read instead of re-reading.`
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
return {
|
|
430
|
+
blocked: false
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Record a tool execution result.
|
|
436
|
+
* @param transient - If true, the failure is transient (timeout, rate limit)
|
|
437
|
+
* and should NOT be added to failedStrategies. Transient failures are
|
|
438
|
+
* retryable with the exact same inputs — e.g., a task_output poll that
|
|
439
|
+
* timed out because the task is still running.
|
|
440
|
+
*/
|
|
441
|
+
recordResult(name, success, input, transient) {
|
|
442
|
+
const eKey = this.errorKey(name, input);
|
|
443
|
+
if (success) {
|
|
444
|
+
this.consecutiveErrors.delete(eKey);
|
|
445
|
+
} else {
|
|
446
|
+
const current = this.consecutiveErrors.get(eKey) || 0;
|
|
447
|
+
this.consecutiveErrors.set(eKey, current + 1);
|
|
448
|
+
this.turnErrors++;
|
|
449
|
+
this.turnHadErrors = true;
|
|
450
|
+
const sessionCount = this.sessionErrors.get(eKey) || 0;
|
|
451
|
+
this.sessionErrors.set(eKey, sessionCount + 1);
|
|
452
|
+
this.totalSessionErrors++;
|
|
453
|
+
|
|
454
|
+
// Only add to failedStrategies for non-transient errors.
|
|
455
|
+
// Transient errors (timeouts, rate limits) should be retryable with
|
|
456
|
+
// the exact same inputs — blocking them creates a deadlock for polling
|
|
457
|
+
// tools like task_output where the input (task_id) never changes.
|
|
458
|
+
if (input && !transient) {
|
|
459
|
+
const inputHash = djb2Hash(JSON.stringify({
|
|
460
|
+
name,
|
|
461
|
+
...input
|
|
462
|
+
}));
|
|
463
|
+
this.failedStrategies.add(inputHash);
|
|
464
|
+
if (this.failedStrategies.size > 200) {
|
|
465
|
+
const arr = Array.from(this.failedStrategies);
|
|
466
|
+
this.failedStrategies = new Set(arr.slice(-100));
|
|
344
467
|
}
|
|
345
|
-
|
|
468
|
+
}
|
|
346
469
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
470
|
+
}
|
|
471
|
+
endTurn() {
|
|
472
|
+
if (this.turnHadErrors) {
|
|
473
|
+
this.consecutiveFailedTurns++;
|
|
474
|
+
} else {
|
|
475
|
+
this.consecutiveFailedTurns = 0;
|
|
476
|
+
// A clean turn means the agent has recovered — unblock previously failed strategies
|
|
477
|
+
// so it can retry calls that failed due to bad params (e.g., wrong UUID format)
|
|
478
|
+
this.failedStrategies.clear();
|
|
479
|
+
// Decay session error counts on clean turns so tools aren't permanently blocked.
|
|
480
|
+
// Each clean turn halves all session error counts, allowing recovery from
|
|
481
|
+
// transient issues while still blocking persistently broken tools.
|
|
482
|
+
if (this.sessionErrors.size > 0) {
|
|
483
|
+
for (const [key, count] of this.sessionErrors) {
|
|
484
|
+
const decayed = Math.floor(count / 2);
|
|
485
|
+
if (decayed <= 0) {
|
|
486
|
+
this.sessionErrors.delete(key);
|
|
487
|
+
} else {
|
|
488
|
+
this.sessionErrors.set(key, decayed);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
352
492
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
493
|
+
|
|
494
|
+
// Cap consecutiveErrors so a single bad batch (parallel Promise.all) can't
|
|
495
|
+
// permanently brick a tool. Without this, N parallel failures push
|
|
496
|
+
// consecutiveErrors to N, which exceeds consecutiveErrorLimit and creates
|
|
497
|
+
// a deadlock: the tool is blocked because it failed, but can't succeed to
|
|
498
|
+
// unblock itself because it's blocked. Capping to (limit - 1) gives the
|
|
499
|
+
// tool one retry on the next turn. Only permanently block after multiple
|
|
500
|
+
// consecutive failed turns (handled by the bail-out check below).
|
|
501
|
+
if (this.consecutiveFailedTurns < this.config.consecutiveFailedTurnLimit) {
|
|
502
|
+
for (const [key, count] of this.consecutiveErrors) {
|
|
503
|
+
if (count >= this.config.consecutiveErrorLimit) {
|
|
504
|
+
this.consecutiveErrors.set(key, this.config.consecutiveErrorLimit - 1);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
362
507
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
508
|
+
|
|
509
|
+
// Reset turn-level counters so the NEXT dispatch batch starts fresh.
|
|
510
|
+
// Session-level counters (sessionErrors, consecutiveFailedTurns) persist.
|
|
511
|
+
this.turnErrors = 0;
|
|
512
|
+
this.turnHadErrors = false;
|
|
513
|
+
if (this.consecutiveFailedTurns >= this.config.consecutiveFailedTurnLimit) {
|
|
514
|
+
return {
|
|
515
|
+
shouldBail: true,
|
|
516
|
+
message: `You have had errors in ${this.consecutiveFailedTurns} consecutive turns (${this.totalSessionErrors} total errors). Your approach is not working. STOP and explain to the user what's failing.`
|
|
517
|
+
};
|
|
369
518
|
}
|
|
519
|
+
return {
|
|
520
|
+
shouldBail: false
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
resetTurn() {
|
|
524
|
+
// Only reset per-turn counters — history and consecutiveErrors persist
|
|
525
|
+
// for cross-turn detection. The full reset() clears everything for new sessions.
|
|
526
|
+
this.turnErrors = 0;
|
|
527
|
+
this.turnHadErrors = false;
|
|
528
|
+
}
|
|
529
|
+
reset() {
|
|
530
|
+
this.resetTurn();
|
|
531
|
+
this.history = [];
|
|
532
|
+
this.consecutiveErrors.clear();
|
|
533
|
+
this.sessionErrors.clear();
|
|
534
|
+
this.failedStrategies.clear();
|
|
535
|
+
this.fileReadCounts.clear();
|
|
536
|
+
this.consecutiveFailedTurns = 0;
|
|
537
|
+
this.totalSessionErrors = 0;
|
|
538
|
+
}
|
|
539
|
+
getSessionStats() {
|
|
540
|
+
return {
|
|
541
|
+
totalErrors: this.totalSessionErrors,
|
|
542
|
+
failedStrategies: this.failedStrategies.size,
|
|
543
|
+
consecutiveFailedTurns: this.consecutiveFailedTurns
|
|
544
|
+
};
|
|
545
|
+
}
|
|
370
546
|
}
|
|
547
|
+
|
|
548
|
+
// ============================================================================
|
|
549
|
+
// EXTENDED THINKING
|
|
550
|
+
// ============================================================================
|
|
551
|
+
|
|
371
552
|
/**
|
|
372
553
|
* Returns the thinking configuration and required beta string for the given model.
|
|
373
554
|
* - Opus 4.6: adaptive thinking (no budget needed)
|
|
@@ -375,195 +556,365 @@ export class LoopDetector {
|
|
|
375
556
|
* - budget_tokens must be strictly < max_tokens
|
|
376
557
|
*/
|
|
377
558
|
export function getThinkingConfig(model, enabled) {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
559
|
+
if (!enabled) {
|
|
560
|
+
return {
|
|
561
|
+
thinking: {
|
|
562
|
+
type: "disabled"
|
|
563
|
+
},
|
|
564
|
+
beta: ""
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
const provider = getProvider(model);
|
|
568
|
+
|
|
569
|
+
// Gemini models: thinking is always-on for 2.5+/3.x — signal pass-through
|
|
570
|
+
if (provider === "gemini") {
|
|
571
|
+
return {
|
|
572
|
+
thinking: {
|
|
573
|
+
type: "enabled"
|
|
574
|
+
},
|
|
575
|
+
beta: ""
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// OpenAI models: reasoning models (o-series) have built-in reasoning, GPT models don't support thinking
|
|
580
|
+
if (provider === "openai") {
|
|
581
|
+
const isReasoning = /^o\d/.test(model);
|
|
398
582
|
return {
|
|
399
|
-
|
|
400
|
-
|
|
583
|
+
thinking: {
|
|
584
|
+
type: isReasoning ? "enabled" : "disabled"
|
|
585
|
+
},
|
|
586
|
+
beta: ""
|
|
401
587
|
};
|
|
588
|
+
}
|
|
589
|
+
if (model.includes("opus-4-6") || model.includes("sonnet-4-6")) {
|
|
590
|
+
return {
|
|
591
|
+
thinking: {
|
|
592
|
+
type: "adaptive"
|
|
593
|
+
},
|
|
594
|
+
beta: "adaptive-thinking-2026-01-28"
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// Sonnet 4.5/4.0 / Haiku: fixed budget (matches Claude Code's 31,999 default)
|
|
599
|
+
return {
|
|
600
|
+
thinking: {
|
|
601
|
+
type: "enabled",
|
|
602
|
+
budget_tokens: 31_999
|
|
603
|
+
},
|
|
604
|
+
beta: "interleaved-thinking-2025-05-14"
|
|
605
|
+
};
|
|
402
606
|
}
|
|
607
|
+
|
|
403
608
|
// ============================================================================
|
|
404
609
|
// COST TRACKING
|
|
405
610
|
// ============================================================================
|
|
611
|
+
|
|
406
612
|
export const MODEL_PRICING = {
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
613
|
+
// Anthropic direct — Claude 4.x
|
|
614
|
+
"claude-sonnet-4-6": {
|
|
615
|
+
inputPer1M: 3.0,
|
|
616
|
+
outputPer1M: 15.0,
|
|
617
|
+
thinkingPer1M: 15.0
|
|
618
|
+
},
|
|
619
|
+
"claude-sonnet-4-20250514": {
|
|
620
|
+
inputPer1M: 3.0,
|
|
621
|
+
outputPer1M: 15.0,
|
|
622
|
+
thinkingPer1M: 15.0
|
|
623
|
+
},
|
|
624
|
+
"claude-sonnet-4-5-20250929": {
|
|
625
|
+
inputPer1M: 3.0,
|
|
626
|
+
outputPer1M: 15.0,
|
|
627
|
+
thinkingPer1M: 15.0
|
|
628
|
+
},
|
|
629
|
+
"claude-opus-4-6": {
|
|
630
|
+
inputPer1M: 5.0,
|
|
631
|
+
outputPer1M: 25.0,
|
|
632
|
+
thinkingPer1M: 25.0
|
|
633
|
+
},
|
|
634
|
+
"claude-opus-4-20250514": {
|
|
635
|
+
inputPer1M: 5.0,
|
|
636
|
+
outputPer1M: 25.0,
|
|
637
|
+
thinkingPer1M: 25.0
|
|
638
|
+
},
|
|
639
|
+
"claude-opus-4-5-20251101": {
|
|
640
|
+
inputPer1M: 5.0,
|
|
641
|
+
outputPer1M: 25.0,
|
|
642
|
+
thinkingPer1M: 25.0
|
|
643
|
+
},
|
|
644
|
+
"claude-haiku-4-20250514": {
|
|
645
|
+
inputPer1M: 1.0,
|
|
646
|
+
outputPer1M: 5.0,
|
|
647
|
+
thinkingPer1M: 5.0
|
|
648
|
+
},
|
|
649
|
+
"claude-haiku-4-5-20251001": {
|
|
650
|
+
inputPer1M: 1.0,
|
|
651
|
+
outputPer1M: 5.0,
|
|
652
|
+
thinkingPer1M: 5.0
|
|
653
|
+
},
|
|
654
|
+
// Anthropic direct — Claude 3.5
|
|
655
|
+
"claude-3-5-sonnet-20241022": {
|
|
656
|
+
inputPer1M: 3.0,
|
|
657
|
+
outputPer1M: 15.0
|
|
658
|
+
},
|
|
659
|
+
"claude-3-5-haiku-20241022": {
|
|
660
|
+
inputPer1M: 0.80,
|
|
661
|
+
outputPer1M: 4.0
|
|
662
|
+
},
|
|
663
|
+
// Bedrock — Claude 4.x
|
|
664
|
+
"anthropic.claude-sonnet-4-6": {
|
|
665
|
+
inputPer1M: 3.0,
|
|
666
|
+
outputPer1M: 15.0,
|
|
667
|
+
thinkingPer1M: 15.0
|
|
668
|
+
},
|
|
669
|
+
"us.anthropic.claude-sonnet-4-20250514-v1:0": {
|
|
670
|
+
inputPer1M: 3.0,
|
|
671
|
+
outputPer1M: 15.0,
|
|
672
|
+
thinkingPer1M: 15.0
|
|
673
|
+
},
|
|
674
|
+
"us.anthropic.claude-sonnet-4-5-20250929-v1:0": {
|
|
675
|
+
inputPer1M: 3.0,
|
|
676
|
+
outputPer1M: 15.0,
|
|
677
|
+
thinkingPer1M: 15.0
|
|
678
|
+
},
|
|
679
|
+
"us.anthropic.claude-haiku-4-5-20251001-v1:0": {
|
|
680
|
+
inputPer1M: 1.0,
|
|
681
|
+
outputPer1M: 5.0,
|
|
682
|
+
thinkingPer1M: 5.0
|
|
683
|
+
},
|
|
684
|
+
// Bedrock — Claude 3.5
|
|
685
|
+
"us.anthropic.claude-3-5-haiku-20241022-v1:0": {
|
|
686
|
+
inputPer1M: 0.80,
|
|
687
|
+
outputPer1M: 4.0
|
|
688
|
+
},
|
|
689
|
+
// Bedrock — Llama & Nova
|
|
690
|
+
"us.meta.llama3-1-70b-instruct-v1:0": {
|
|
691
|
+
inputPer1M: 0.72,
|
|
692
|
+
outputPer1M: 0.72
|
|
693
|
+
},
|
|
694
|
+
"us.amazon.nova-pro-v1:0": {
|
|
695
|
+
inputPer1M: 0.80,
|
|
696
|
+
outputPer1M: 3.20
|
|
697
|
+
},
|
|
698
|
+
// Gemini (thinking tokens are cheaper than output)
|
|
699
|
+
"gemini-3-pro-preview": {
|
|
700
|
+
inputPer1M: 1.25,
|
|
701
|
+
outputPer1M: 10.0,
|
|
702
|
+
thinkingPer1M: 2.50
|
|
703
|
+
},
|
|
704
|
+
"gemini-3-flash-preview": {
|
|
705
|
+
inputPer1M: 0.15,
|
|
706
|
+
outputPer1M: 0.60,
|
|
707
|
+
thinkingPer1M: 0.15
|
|
708
|
+
},
|
|
709
|
+
"gemini-2.5-pro": {
|
|
710
|
+
inputPer1M: 1.25,
|
|
711
|
+
outputPer1M: 10.0,
|
|
712
|
+
thinkingPer1M: 2.50
|
|
713
|
+
},
|
|
714
|
+
"gemini-2.5-flash": {
|
|
715
|
+
inputPer1M: 0.15,
|
|
716
|
+
outputPer1M: 0.60,
|
|
717
|
+
thinkingPer1M: 0.15
|
|
718
|
+
},
|
|
719
|
+
"gemini-2.5-flash-lite": {
|
|
720
|
+
inputPer1M: 0.075,
|
|
721
|
+
outputPer1M: 0.30,
|
|
722
|
+
thinkingPer1M: 0.075
|
|
723
|
+
},
|
|
724
|
+
"gemini-2.0-flash": {
|
|
725
|
+
inputPer1M: 0.10,
|
|
726
|
+
outputPer1M: 0.40
|
|
727
|
+
},
|
|
728
|
+
"gemini-2.0-flash-lite": {
|
|
729
|
+
inputPer1M: 0.075,
|
|
730
|
+
outputPer1M: 0.30
|
|
731
|
+
},
|
|
732
|
+
// OpenAI — GPT
|
|
733
|
+
"gpt-5": {
|
|
734
|
+
inputPer1M: 1.25,
|
|
735
|
+
outputPer1M: 10.0
|
|
736
|
+
},
|
|
737
|
+
"gpt-5-mini": {
|
|
738
|
+
inputPer1M: 0.25,
|
|
739
|
+
outputPer1M: 2.0
|
|
740
|
+
},
|
|
741
|
+
"gpt-5-nano": {
|
|
742
|
+
inputPer1M: 0.05,
|
|
743
|
+
outputPer1M: 0.40
|
|
744
|
+
},
|
|
745
|
+
"gpt-4o": {
|
|
746
|
+
inputPer1M: 2.50,
|
|
747
|
+
outputPer1M: 10.0
|
|
748
|
+
},
|
|
749
|
+
"gpt-4o-mini": {
|
|
750
|
+
inputPer1M: 0.15,
|
|
751
|
+
outputPer1M: 0.60
|
|
752
|
+
},
|
|
753
|
+
"gpt-4-turbo": {
|
|
754
|
+
inputPer1M: 10.0,
|
|
755
|
+
outputPer1M: 30.0
|
|
756
|
+
},
|
|
757
|
+
// OpenAI — reasoning models
|
|
758
|
+
"o1": {
|
|
759
|
+
inputPer1M: 15.0,
|
|
760
|
+
outputPer1M: 60.0,
|
|
761
|
+
thinkingPer1M: 60.0
|
|
762
|
+
},
|
|
763
|
+
"o1-mini": {
|
|
764
|
+
inputPer1M: 3.0,
|
|
765
|
+
outputPer1M: 12.0,
|
|
766
|
+
thinkingPer1M: 12.0
|
|
767
|
+
},
|
|
768
|
+
"o3": {
|
|
769
|
+
inputPer1M: 2.0,
|
|
770
|
+
outputPer1M: 8.0,
|
|
771
|
+
thinkingPer1M: 8.0
|
|
772
|
+
},
|
|
773
|
+
"o3-mini": {
|
|
774
|
+
inputPer1M: 1.10,
|
|
775
|
+
outputPer1M: 4.40,
|
|
776
|
+
thinkingPer1M: 4.40
|
|
777
|
+
},
|
|
778
|
+
"o4-mini": {
|
|
779
|
+
inputPer1M: 1.10,
|
|
780
|
+
outputPer1M: 4.40,
|
|
781
|
+
thinkingPer1M: 4.40
|
|
782
|
+
}
|
|
450
783
|
};
|
|
784
|
+
|
|
451
785
|
/**
|
|
452
786
|
* Emit graduated cost warnings at 25%, 50%, 75% thresholds.
|
|
453
787
|
* Single source of truth — replaces copy-pasted blocks in server + CLI.
|
|
454
788
|
*/
|
|
455
789
|
export function emitCostWarningIfNeeded(sessionCostUsd, maxCostUsd, costWarningsEmitted, onText) {
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
onText(`\n[Cost warning: ${pct}% of budget used ($${sessionCostUsd.toFixed(2)}/$${maxCostUsd.toFixed(2)}).${pct >= 75 ? " Wrap up soon." : ""}]`);
|
|
462
|
-
}
|
|
790
|
+
if (!isFinite(maxCostUsd) || !onText) return;
|
|
791
|
+
for (const pct of [25, 50, 75]) {
|
|
792
|
+
if (!costWarningsEmitted.has(pct) && sessionCostUsd >= maxCostUsd * (pct / 100)) {
|
|
793
|
+
costWarningsEmitted.add(pct);
|
|
794
|
+
onText(`\n[Cost warning: ${pct}% of budget used ($${sessionCostUsd.toFixed(2)}/$${maxCostUsd.toFixed(2)}).${pct >= 75 ? " Wrap up soon." : ""}]`);
|
|
463
795
|
}
|
|
796
|
+
}
|
|
464
797
|
}
|
|
465
798
|
export function estimateCostUsd(inputTokens, outputTokens, model, thinkingTokens = 0, cacheReadTokens = 0, cacheCreationTokens = 0) {
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
if (
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
cost -= (cacheReadTokens / 1_000_000) * inputRate * 0.5;
|
|
488
|
-
}
|
|
489
|
-
else if (provider === "gemini") {
|
|
490
|
-
cost -= (cacheReadTokens / 1_000_000) * inputRate * 0.75;
|
|
491
|
-
}
|
|
799
|
+
// Exact match first, then find a pricing key that is a prefix of the model ID
|
|
800
|
+
const pricing = MODEL_PRICING[model] || MODEL_PRICING[Object.keys(MODEL_PRICING).find(k => model.startsWith(k)) ?? ""] || MODEL_PRICING["claude-sonnet-4-6"];
|
|
801
|
+
const thinkingRate = pricing.thinkingPer1M || pricing.outputPer1M;
|
|
802
|
+
const inputRate = pricing.inputPer1M;
|
|
803
|
+
|
|
804
|
+
// Base cost
|
|
805
|
+
let cost = inputTokens / 1_000_000 * inputRate + outputTokens / 1_000_000 * pricing.outputPer1M + thinkingTokens / 1_000_000 * thinkingRate;
|
|
806
|
+
|
|
807
|
+
// Cache pricing — subtract savings for cached tokens
|
|
808
|
+
// Anthropic/Bedrock: cache reads 90% cheaper, cache creation 25% surcharge
|
|
809
|
+
// OpenAI: cache reads 50% cheaper, no creation surcharge
|
|
810
|
+
// Gemini: cache reads 75% cheaper
|
|
811
|
+
if (cacheReadTokens > 0 || cacheCreationTokens > 0) {
|
|
812
|
+
const provider = getProvider(model);
|
|
813
|
+
if (provider === "anthropic" || provider === "bedrock") {
|
|
814
|
+
cost -= cacheReadTokens / 1_000_000 * inputRate * 0.9;
|
|
815
|
+
cost += cacheCreationTokens / 1_000_000 * inputRate * 0.25;
|
|
816
|
+
} else if (provider === "openai") {
|
|
817
|
+
cost -= cacheReadTokens / 1_000_000 * inputRate * 0.5;
|
|
818
|
+
} else if (provider === "gemini") {
|
|
819
|
+
cost -= cacheReadTokens / 1_000_000 * inputRate * 0.75;
|
|
492
820
|
}
|
|
493
|
-
|
|
821
|
+
}
|
|
822
|
+
return cost;
|
|
494
823
|
}
|
|
824
|
+
|
|
495
825
|
// ============================================================================
|
|
496
826
|
// MODEL ROUTING BY TASK COMPLEXITY
|
|
497
827
|
// ============================================================================
|
|
828
|
+
|
|
498
829
|
/**
|
|
499
830
|
* Route to cheaper model when the task is simple enough.
|
|
500
831
|
* Returns the model to actually use.
|
|
501
832
|
*/
|
|
502
833
|
export function routeModel(message, requestedModel, forceModel) {
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
834
|
+
// If user explicitly picked a model, respect it
|
|
835
|
+
if (forceModel) return requestedModel;
|
|
836
|
+
|
|
837
|
+
// Estimate token count (rough: 1 token ~= 4 chars)
|
|
838
|
+
const estimatedTokens = Math.ceil(message.length / 4);
|
|
839
|
+
|
|
840
|
+
// Simple queries → Haiku (30x cheaper than Opus)
|
|
841
|
+
const simplePatterns = /^(what|who|when|where|show|list|get|find|look ?up|check)\b/i;
|
|
842
|
+
const complexPatterns = /\b(analyze|implement|refactor|design|architect|debug|explain why|compare|evaluate|write|create|build|fix)\b/i;
|
|
843
|
+
if (estimatedTokens < 50 && simplePatterns.test(message) && !complexPatterns.test(message)) {
|
|
844
|
+
return "claude-haiku-4-5-20251001";
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
// Medium queries → Sonnet
|
|
848
|
+
if (estimatedTokens < 200 && !complexPatterns.test(message)) {
|
|
849
|
+
return "claude-sonnet-4-5-20250929";
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
// Complex → honor requested model
|
|
853
|
+
return requestedModel;
|
|
520
854
|
}
|
|
855
|
+
|
|
856
|
+
// ============================================================================
|
|
857
|
+
// ERROR CATEGORIZATION
|
|
858
|
+
// ============================================================================
|
|
859
|
+
|
|
521
860
|
export function categorizeError(err) {
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
861
|
+
const e = err;
|
|
862
|
+
const status = e?.status || e?.statusCode;
|
|
863
|
+
const msg = String(e?.message || "").toLowerCase();
|
|
864
|
+
if (status === 429 || msg.includes("rate limit")) {
|
|
865
|
+
return {
|
|
866
|
+
category: "RATE_LIMIT",
|
|
867
|
+
retryable: true
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
if (status === 401 || status === 403 || msg.includes("unauthorized") || msg.includes("forbidden") || msg.includes("invalid api key")) {
|
|
871
|
+
return {
|
|
872
|
+
category: "AUTH",
|
|
873
|
+
retryable: false
|
|
874
|
+
};
|
|
875
|
+
}
|
|
876
|
+
if (status === 400 || msg.includes("malformed") || msg.includes("invalid") || msg.includes("validation")) {
|
|
877
|
+
return {
|
|
878
|
+
category: "MALFORMED",
|
|
879
|
+
retryable: false
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
if (status === 500 || status === 502 || status === 503 || status === 529 || msg.includes("overloaded") || msg.includes("internal server error")) {
|
|
883
|
+
return {
|
|
884
|
+
category: "PROVIDER_DOWN",
|
|
885
|
+
retryable: true
|
|
886
|
+
};
|
|
887
|
+
}
|
|
888
|
+
if (msg.includes("timeout") || msg.includes("timed out") || msg.includes("deadline") || msg.includes("econnreset") || msg.includes("stream stalled")) {
|
|
889
|
+
return {
|
|
890
|
+
category: "TIMEOUT",
|
|
891
|
+
retryable: true
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
if (msg.includes("econnrefused") || msg.includes("enetunreach") || msg.includes("enotfound") || msg.includes("fetch failed") || msg.includes("network")) {
|
|
895
|
+
return {
|
|
896
|
+
category: "NETWORK",
|
|
897
|
+
retryable: true
|
|
898
|
+
};
|
|
899
|
+
}
|
|
900
|
+
return {
|
|
901
|
+
category: "UNKNOWN",
|
|
902
|
+
retryable: false
|
|
903
|
+
};
|
|
544
904
|
}
|
|
905
|
+
|
|
545
906
|
// ============================================================================
|
|
546
907
|
// RETRY LOGIC
|
|
547
908
|
// ============================================================================
|
|
909
|
+
|
|
548
910
|
export function isRetryableError(err) {
|
|
549
|
-
|
|
911
|
+
return categorizeError(err).retryable;
|
|
550
912
|
}
|
|
913
|
+
|
|
551
914
|
// ============================================================================
|
|
552
|
-
//
|
|
553
|
-
// ============================================================================
|
|
554
|
-
/** @deprecated — Anthropic context_management handles limits. Use SAFETY_MAX_CHARS in tool-dispatch instead. */
|
|
555
|
-
export function truncateToolResult(content, maxChars) {
|
|
556
|
-
if (content.length <= maxChars)
|
|
557
|
-
return content;
|
|
558
|
-
return content.slice(0, maxChars) + `\n\n... (truncated — ${content.length.toLocaleString()} chars total)`;
|
|
559
|
-
}
|
|
560
|
-
/** @deprecated — Anthropic context_management handles limits. */
|
|
561
|
-
export function getMaxToolResultChars(contextConfig) {
|
|
562
|
-
return contextConfig?.max_tool_result_chars || 80_000;
|
|
563
|
-
}
|
|
564
|
-
// ============================================================================
|
|
565
|
-
// UTILITY — sanitize errors (strip API keys, passwords)
|
|
915
|
+
// UTILITY — model demotion, sanitize errors
|
|
566
916
|
// ============================================================================
|
|
917
|
+
|
|
567
918
|
/**
|
|
568
919
|
* Demote subagent model requests — single source of truth for server + CLI.
|
|
569
920
|
* - explore/research: always haiku
|
|
@@ -571,25 +922,183 @@ export function getMaxToolResultChars(contextConfig) {
|
|
|
571
922
|
* - sonnet: kept for plan, demoted to haiku for others
|
|
572
923
|
* - default/undefined: haiku
|
|
573
924
|
*/
|
|
925
|
+
/**
|
|
926
|
+
* Resolve subagent model based on agent type and request.
|
|
927
|
+
*
|
|
928
|
+
* Claude Code behavior: general-purpose and plan subagents inherit the parent
|
|
929
|
+
* model (they do real work / need full reasoning). Only explore and research
|
|
930
|
+
* are demoted to haiku (fast, focused tasks).
|
|
931
|
+
*/
|
|
574
932
|
export function demoteSubagentModel(requested, agentType) {
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
if (requested === "sonnet")
|
|
582
|
-
|
|
583
|
-
|
|
933
|
+
// Fast, focused agent types always use haiku regardless of request
|
|
934
|
+
if (agentType === "explore" || agentType === "research") return "haiku";
|
|
935
|
+
|
|
936
|
+
// General-purpose and plan inherit the requested model (Claude Code parity)
|
|
937
|
+
if (agentType === "general-purpose" || agentType === "plan") {
|
|
938
|
+
if (requested === "opus") return "opus";
|
|
939
|
+
if (requested === "sonnet") return "sonnet";
|
|
940
|
+
return "sonnet"; // default to sonnet if no model specified
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
// Unknown/custom agent types — default to haiku for safety
|
|
944
|
+
if (!requested) return "haiku";
|
|
945
|
+
return requested === "opus" ? "sonnet" : requested === "sonnet" ? "sonnet" : "haiku";
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
// ============================================================================
|
|
949
|
+
// AGENT LOOP CONFIG RESOLVER — single source of truth for all call paths
|
|
950
|
+
// ============================================================================
|
|
951
|
+
|
|
952
|
+
/**
|
|
953
|
+
* EMERGENCY FALLBACK DEFAULTS — used ONLY when ai_agent_config DB is unreachable.
|
|
954
|
+
*
|
|
955
|
+
* The SINGLE SOURCE OF TRUTH is the ai_agent_config table (Supabase), specifically
|
|
956
|
+
* the row for Whale Code (id: 72d7aaa8-2e8b-48a0-a38d-f332f69600bb).
|
|
957
|
+
* All behavioral knobs are stored in `context_config` JSONB.
|
|
958
|
+
*
|
|
959
|
+
* These values MUST mirror what's in the DB. If you change a value, update the DB
|
|
960
|
+
* first (via Supabase dashboard or migration), then mirror it here.
|
|
961
|
+
*
|
|
962
|
+
* DB → resolveAgentLoopConfig() → code reads resolved values.
|
|
963
|
+
* AGENT_DEFAULTS → code reads ONLY if DB fetch returns null.
|
|
964
|
+
*/
|
|
965
|
+
export const AGENT_DEFAULTS = {
|
|
966
|
+
// Mirrors ai_agent_config.max_tool_calls / temperature
|
|
967
|
+
maxTurns: 0,
|
|
968
|
+
// 0 = no limit (agent self-regulates via end_turn, Claude Code parity)
|
|
969
|
+
temperature: 1.0,
|
|
970
|
+
// Mirrors ai_agent_config.context_config JSONB fields
|
|
971
|
+
maxConcurrentTools: 7,
|
|
972
|
+
enableDelegation: true,
|
|
973
|
+
maxDurationMs: 900_000,
|
|
974
|
+
maxDurationMsWorkflow: 120_000,
|
|
975
|
+
enableModelRouting: true,
|
|
976
|
+
subagentMaxTokens: 32000,
|
|
977
|
+
subagentMaxTurns: 0,
|
|
978
|
+
// 0 = no limit (agent self-regulates via end_turn, Claude Code parity)
|
|
979
|
+
subagentTemperature: 1.0,
|
|
980
|
+
subagentMaxRetries: 2,
|
|
981
|
+
// 1 retry (2 total attempts) — proxy already handles auth refresh, avoid double backoff
|
|
982
|
+
maxContinuations: 10,
|
|
983
|
+
subagentMaxContinuations: 5,
|
|
984
|
+
maxMessageChars: 100_000,
|
|
985
|
+
maxHistoryChars: 400_000,
|
|
986
|
+
maxToolResultChars: 2048,
|
|
987
|
+
compactionTriggerTokens: 167_000,
|
|
988
|
+
compactionTotalBudget: 2_000_000,
|
|
989
|
+
sessionCostBudgetUsd: 25.00,
|
|
990
|
+
// Team / teammate behavioral defaults
|
|
991
|
+
teammateMaxTotalTurns: 0,
|
|
992
|
+
// 0 = no limit (teammate self-regulates, Claude Code parity)
|
|
993
|
+
teamTimeoutMs: 600_000,
|
|
994
|
+
// 10 min global safety cap — prevents runaway team runs (DB overridable)
|
|
995
|
+
workerStallMs: 90_000,
|
|
996
|
+
// 90s no-message stall detection (API timeout is 90s, so 90s silence = truly stalled)
|
|
997
|
+
teamReviewMaxTokens: 1024,
|
|
998
|
+
// Max tokens for team review synthesis
|
|
999
|
+
// Infrastructure timeouts for teammates (DB overridable, not hardcoded)
|
|
1000
|
+
apiTimeoutMs: 90_000,
|
|
1001
|
+
// 90s timeout on proxy/API fetch calls
|
|
1002
|
+
toolTimeoutMs: 60_000,
|
|
1003
|
+
// 60s timeout on individual tool execution
|
|
1004
|
+
// Per-tool-result truncation cap (different from maxToolResultChars which is for preCompact)
|
|
1005
|
+
toolResultTruncateChars: 30_000,
|
|
1006
|
+
// Match SAFETY_MAX_CHARS from tool-dispatch.ts — 500K was blowing context windows
|
|
1007
|
+
// Loop detector thresholds (DB overridable via context_config)
|
|
1008
|
+
loopIdenticalCallLimit: 4,
|
|
1009
|
+
loopConsecutiveErrorLimit: 3,
|
|
1010
|
+
loopTurnErrorLimit: 5,
|
|
1011
|
+
loopWindow: 20,
|
|
1012
|
+
loopSessionToolErrorLimit: 10,
|
|
1013
|
+
loopConsecutiveFailedTurnLimit: 3,
|
|
1014
|
+
loopFileReadLimit: 3,
|
|
1015
|
+
loopBatchErrorLimit: 3 // Max errors from single parallel batch before abort
|
|
1016
|
+
};
|
|
1017
|
+
|
|
1018
|
+
/** Context config shape from ai_agent_config.context_config JSONB */
|
|
1019
|
+
|
|
1020
|
+
/**
|
|
1021
|
+
* Resolve all agent loop behavioral knobs from DB config.
|
|
1022
|
+
* All 3 call paths MUST use this — structurally prevents hardcoded constants.
|
|
1023
|
+
*
|
|
1024
|
+
* @param agent - Agent config (DB row or subset)
|
|
1025
|
+
* @param callPath - Which call path is invoking ("sse" | "workflow" | "channel")
|
|
1026
|
+
* @param workflowMaxTurns - Optional cap from workflow step config (workflow path only)
|
|
1027
|
+
*/
|
|
1028
|
+
export function resolveAgentLoopConfig(agent, callPath, workflowMaxTurns) {
|
|
1029
|
+
const cc = agent.context_config;
|
|
1030
|
+
const defaultsUsed = [];
|
|
1031
|
+
function resolve(dbValue, defaultValue, name) {
|
|
1032
|
+
if (dbValue != null) return dbValue;
|
|
1033
|
+
defaultsUsed.push(name);
|
|
1034
|
+
return defaultValue;
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
// Core agent behavior
|
|
1038
|
+
const agentMaxTurns = agent.max_tool_calls || AGENT_DEFAULTS.maxTurns;
|
|
1039
|
+
if (!agent.max_tool_calls) defaultsUsed.push("maxTurns");
|
|
1040
|
+
const temperature = agent.temperature ?? AGENT_DEFAULTS.temperature;
|
|
1041
|
+
if (agent.temperature == null) defaultsUsed.push("temperature");
|
|
1042
|
+
const maxTokens = getMaxOutputTokens(agent.model || "claude-sonnet-4-6", agent.max_tokens);
|
|
1043
|
+
if (!agent.max_tokens) defaultsUsed.push("maxTokens");
|
|
1044
|
+
|
|
1045
|
+
// Call-path-specific duration defaults
|
|
1046
|
+
const durationDefault = callPath === "sse" ? AGENT_DEFAULTS.maxDurationMs : AGENT_DEFAULTS.maxDurationMsWorkflow;
|
|
1047
|
+
|
|
1048
|
+
// Call-path-specific turn caps (0 = no limit, Claude Code parity)
|
|
1049
|
+
let maxTurns = agentMaxTurns;
|
|
1050
|
+
if (maxTurns > 0) {
|
|
1051
|
+
if (callPath === "channel") maxTurns = Math.min(agentMaxTurns, 15);
|
|
1052
|
+
if (callPath === "workflow" && workflowMaxTurns != null) {
|
|
1053
|
+
maxTurns = Math.min(agentMaxTurns, workflowMaxTurns);
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
return {
|
|
1057
|
+
maxTurns,
|
|
1058
|
+
temperature,
|
|
1059
|
+
maxTokens,
|
|
1060
|
+
maxConcurrentTools: resolve(cc?.max_concurrent_tools, AGENT_DEFAULTS.maxConcurrentTools, "maxConcurrentTools"),
|
|
1061
|
+
enableDelegation: resolve(cc?.enable_delegation, AGENT_DEFAULTS.enableDelegation, "enableDelegation"),
|
|
1062
|
+
maxDurationMs: resolve(cc?.max_duration_ms, durationDefault, "maxDurationMs"),
|
|
1063
|
+
enableModelRouting: resolve(cc?.enable_model_routing, AGENT_DEFAULTS.enableModelRouting, "enableModelRouting"),
|
|
1064
|
+
maxMessageChars: resolve(cc?.max_message_chars, AGENT_DEFAULTS.maxMessageChars, "maxMessageChars"),
|
|
1065
|
+
maxHistoryChars: resolve(cc?.max_history_chars, AGENT_DEFAULTS.maxHistoryChars, "maxHistoryChars"),
|
|
1066
|
+
contextOverrides: {
|
|
1067
|
+
compaction_trigger_tokens: cc?.compaction_trigger_tokens ?? undefined,
|
|
1068
|
+
compaction_total_budget: cc?.compaction_total_budget ?? undefined,
|
|
1069
|
+
clear_thinking_keep: cc?.clear_thinking_keep ?? undefined,
|
|
1070
|
+
clear_tool_uses_trigger: cc?.clear_tool_uses_trigger ?? undefined,
|
|
1071
|
+
clear_tool_uses_keep: cc?.clear_tool_uses_keep ?? undefined,
|
|
1072
|
+
session_cost_budget_usd: cc?.session_cost_budget_usd ?? undefined
|
|
1073
|
+
},
|
|
1074
|
+
subagentMaxTokens: resolve(cc?.subagent_max_tokens, AGENT_DEFAULTS.subagentMaxTokens, "subagentMaxTokens"),
|
|
1075
|
+
subagentMaxTurns: resolve(cc?.subagent_max_turns, AGENT_DEFAULTS.subagentMaxTurns, "subagentMaxTurns"),
|
|
1076
|
+
subagentTemperature: resolve(cc?.subagent_temperature, AGENT_DEFAULTS.subagentTemperature, "subagentTemperature"),
|
|
1077
|
+
maxContinuations: resolve(cc?.max_continuations, AGENT_DEFAULTS.maxContinuations, "maxContinuations"),
|
|
1078
|
+
subagentMaxContinuations: resolve(cc?.subagent_max_continuations, AGENT_DEFAULTS.subagentMaxContinuations, "subagentMaxContinuations"),
|
|
1079
|
+
subagentMaxRetries: resolve(cc?.subagent_max_retries, AGENT_DEFAULTS.subagentMaxRetries, "subagentMaxRetries"),
|
|
1080
|
+
maxToolResultChars: resolve(cc?.max_tool_result_chars, AGENT_DEFAULTS.maxToolResultChars, "maxToolResultChars"),
|
|
1081
|
+
teammateMaxTotalTurns: resolve(cc?.teammate_max_total_turns, AGENT_DEFAULTS.teammateMaxTotalTurns, "teammateMaxTotalTurns"),
|
|
1082
|
+
teamTimeoutMs: resolve(cc?.team_timeout_ms, AGENT_DEFAULTS.teamTimeoutMs, "teamTimeoutMs"),
|
|
1083
|
+
workerStallMs: resolve(cc?.worker_stall_ms, AGENT_DEFAULTS.workerStallMs, "workerStallMs"),
|
|
1084
|
+
teamReviewMaxTokens: resolve(cc?.team_review_max_tokens, AGENT_DEFAULTS.teamReviewMaxTokens, "teamReviewMaxTokens"),
|
|
1085
|
+
apiTimeoutMs: resolve(cc?.api_timeout_ms, AGENT_DEFAULTS.apiTimeoutMs, "apiTimeoutMs"),
|
|
1086
|
+
toolTimeoutMs: resolve(cc?.tool_timeout_ms, AGENT_DEFAULTS.toolTimeoutMs, "toolTimeoutMs"),
|
|
1087
|
+
toolResultTruncateChars: resolve(cc?.tool_result_truncate_chars, AGENT_DEFAULTS.toolResultTruncateChars, "toolResultTruncateChars"),
|
|
1088
|
+
// Loop detector thresholds
|
|
1089
|
+
loopIdenticalCallLimit: resolve(cc?.loop_identical_call_limit, AGENT_DEFAULTS.loopIdenticalCallLimit, "loopIdenticalCallLimit"),
|
|
1090
|
+
loopConsecutiveErrorLimit: resolve(cc?.loop_consecutive_error_limit, AGENT_DEFAULTS.loopConsecutiveErrorLimit, "loopConsecutiveErrorLimit"),
|
|
1091
|
+
loopTurnErrorLimit: resolve(cc?.loop_turn_error_limit, AGENT_DEFAULTS.loopTurnErrorLimit, "loopTurnErrorLimit"),
|
|
1092
|
+
loopWindow: resolve(cc?.loop_window, AGENT_DEFAULTS.loopWindow, "loopWindow"),
|
|
1093
|
+
loopSessionToolErrorLimit: resolve(cc?.loop_session_tool_error_limit, AGENT_DEFAULTS.loopSessionToolErrorLimit, "loopSessionToolErrorLimit"),
|
|
1094
|
+
loopConsecutiveFailedTurnLimit: resolve(cc?.loop_consecutive_failed_turn_limit, AGENT_DEFAULTS.loopConsecutiveFailedTurnLimit, "loopConsecutiveFailedTurnLimit"),
|
|
1095
|
+
loopFileReadLimit: resolve(cc?.loop_file_read_limit, AGENT_DEFAULTS.loopFileReadLimit, "loopFileReadLimit"),
|
|
1096
|
+
loopBatchErrorLimit: resolve(cc?.loop_batch_error_limit, AGENT_DEFAULTS.loopBatchErrorLimit, "loopBatchErrorLimit"),
|
|
1097
|
+
defaultsUsed
|
|
1098
|
+
};
|
|
584
1099
|
}
|
|
585
1100
|
export function sanitizeError(err) {
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
.replace(/sk-[a-zA-Z0-9_-]+/g, "sk-***")
|
|
589
|
-
.replace(/AIzaSy[a-zA-Z0-9_-]+/g, "AIzaSy***")
|
|
590
|
-
.replace(/AKIA[A-Z0-9]{16}/g, "AKIA***")
|
|
591
|
-
.replace(/key[=:]\s*["']?[a-zA-Z0-9_-]{20,}["']?/gi, "key=***")
|
|
592
|
-
.replace(/password[=:]\s*["']?[^\s"']+["']?/gi, "password=***")
|
|
593
|
-
.replace(/\n\s+at\s+.*/g, "")
|
|
594
|
-
.substring(0, 500);
|
|
1101
|
+
const msg = String(err);
|
|
1102
|
+
return msg.replace(/sk-[a-zA-Z0-9_-]+/g, "sk-***").replace(/AIzaSy[a-zA-Z0-9_-]+/g, "AIzaSy***").replace(/AKIA[A-Z0-9]{16}/g, "AKIA***").replace(/key[=:]\s*["']?[a-zA-Z0-9_-]{20,}["']?/gi, "key=***").replace(/password[=:]\s*["']?[^\s"']+["']?/gi, "password=***").replace(/\n\s+at\s+.*/g, "").substring(0, 500);
|
|
595
1103
|
}
|
|
1104
|
+
//# sourceMappingURL=agent-core.js.map
|