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
|
@@ -7,37 +7,65 @@
|
|
|
7
7
|
* - Can message other teammates directly
|
|
8
8
|
* - Full tool access (not restricted like subagents)
|
|
9
9
|
*/
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
import { fork } from "child_process";
|
|
11
12
|
import { fileURLToPath } from "url";
|
|
12
|
-
import { loadTeam, claimTask, completeTask, failTask, getAvailableTasks, sendMessage, getUnreadMessages, markMessagesRead, updateTeammate
|
|
13
|
-
import { LoopDetector, estimateCostUsd } from "../../shared/agent-core.js";
|
|
13
|
+
import { loadTeam, claimTask, completeTask, failTask, getAvailableTasks, sendMessage, getUnreadMessages, markMessagesRead, updateTeammate } from "./team-state.js";
|
|
14
|
+
import { LoopDetector, estimateCostUsd, AGENT_DEFAULTS, resolveAgentLoopConfig } from "../../shared/agent-core.js";
|
|
15
|
+
import { preCompact } from "../../shared/compaction.js";
|
|
16
|
+
import { loadCLIAgentConfig } from "./agent-config.js";
|
|
14
17
|
import { MODEL_MAP } from "../../shared/constants.js";
|
|
15
|
-
import { LOCAL_TOOL_DEFINITIONS
|
|
16
|
-
import { loadServerToolDefinitions
|
|
18
|
+
import { LOCAL_TOOL_DEFINITIONS } from "./local-tools.js";
|
|
19
|
+
import { loadServerToolDefinitions } from "./server-tools.js";
|
|
17
20
|
import { getValidToken } from "./auth-service.js";
|
|
18
|
-
import { logSpan, generateSpanId, generateTraceId, getConversationId, initializeTelemetryClient } from "./telemetry.js";
|
|
19
|
-
import { callAgentAPI, executeToolBlocks, extractTextBlocks, extractToolUseBlocks, } from "./agent-worker-base.js";
|
|
21
|
+
import { logSpan, generateSpanId, generateTraceId, getConversationId, initializeTelemetryClient, flushCliSpans, PKG_VERSION } from "./telemetry.js";
|
|
22
|
+
import { callAgentAPI, executeToolBlocks, extractTextBlocks, extractToolUseBlocks, deduplicateTools, assertUniqueToolNames } from "./agent-worker-base.js";
|
|
23
|
+
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// TYPES
|
|
26
|
+
// ============================================================================
|
|
27
|
+
|
|
20
28
|
// ============================================================================
|
|
21
29
|
// CONSTANTS
|
|
22
30
|
// ============================================================================
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
|
|
32
|
+
// Teammate constants — ALL from DB via AGENT_DEFAULTS, nothing hardcoded
|
|
33
|
+
let TEAMMATE_MAX_TURNS_PER_TASK = AGENT_DEFAULTS.subagentMaxTurns; // DB overridable
|
|
34
|
+
let TEAMMATE_MAX_OUTPUT_TOKENS = AGENT_DEFAULTS.subagentMaxTokens; // DB overridable
|
|
35
|
+
let TEAMMATE_MAX_TOTAL_TURNS = AGENT_DEFAULTS.teammateMaxTotalTurns;
|
|
36
|
+
let TEAMMATE_MAX_DURATION_MS = AGENT_DEFAULTS.maxDurationMs;
|
|
37
|
+
let API_TIMEOUT_MS = AGENT_DEFAULTS.apiTimeoutMs; // DB overridable
|
|
38
|
+
let TOOL_TIMEOUT_MS = AGENT_DEFAULTS.toolTimeoutMs; // DB overridable
|
|
39
|
+
|
|
40
|
+
// Cached resolved config for LoopDetector creation
|
|
41
|
+
let resolvedTeammateConfig = null;
|
|
42
|
+
|
|
43
|
+
// Lazy init from DB — called once per teammate spawn. ALL knobs from DB, nothing hardcoded.
|
|
44
|
+
async function resolveTeammateConfig() {
|
|
45
|
+
const dbAgent = await loadCLIAgentConfig();
|
|
46
|
+
if (!dbAgent?.context_config) return;
|
|
47
|
+
const cc = dbAgent.context_config;
|
|
48
|
+
TEAMMATE_MAX_TURNS_PER_TASK = cc.subagent_max_turns ?? TEAMMATE_MAX_TURNS_PER_TASK;
|
|
49
|
+
TEAMMATE_MAX_OUTPUT_TOKENS = cc.subagent_max_tokens ?? TEAMMATE_MAX_OUTPUT_TOKENS;
|
|
50
|
+
TEAMMATE_MAX_DURATION_MS = cc.max_duration_ms ?? TEAMMATE_MAX_DURATION_MS;
|
|
51
|
+
TEAMMATE_MAX_TOTAL_TURNS = cc.teammate_max_total_turns ?? TEAMMATE_MAX_TOTAL_TURNS;
|
|
52
|
+
API_TIMEOUT_MS = cc.api_timeout_ms ?? API_TIMEOUT_MS;
|
|
53
|
+
TOOL_TIMEOUT_MS = cc.tool_timeout_ms ?? TOOL_TIMEOUT_MS;
|
|
54
|
+
// Cache resolved config for LoopDetector
|
|
55
|
+
resolvedTeammateConfig = resolveAgentLoopConfig(dbAgent, "sse");
|
|
56
|
+
}
|
|
57
|
+
|
|
29
58
|
// ============================================================================
|
|
30
59
|
// TEAMMATE SYSTEM PROMPT
|
|
31
60
|
// ============================================================================
|
|
61
|
+
|
|
32
62
|
function buildTeammatePrompt(teammateName, team, currentTask, cwd) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const teammates = team.teammates.map(t => `- ${t.name} (${t.id}): ${t.status}${t.currentTask ? ` - working on task` : ""}`).join("\n");
|
|
40
|
-
return `You are ${teammateName}, a teammate in the "${team.name}" team.
|
|
63
|
+
const taskList = team.tasks.map(t => {
|
|
64
|
+
const status = t.status === "in_progress" && t.assignedTo ? `in_progress (${team.teammates.find(tm => tm.id === t.assignedTo)?.name || "unknown"})` : t.status;
|
|
65
|
+
return `- [${status}] ${t.description}${t.id === currentTask?.id ? " (YOUR TASK)" : ""}`;
|
|
66
|
+
}).join("\n");
|
|
67
|
+
const teammates = team.teammates.map(t => `- ${t.name} (${t.id}): ${t.status}${t.currentTask ? ` - working on task` : ""}`).join("\n");
|
|
68
|
+
return `You are ${teammateName}, a teammate in the "${team.name}" team.
|
|
41
69
|
|
|
42
70
|
## Working Directory
|
|
43
71
|
${cwd}
|
|
@@ -71,13 +99,18 @@ You can delegate sub-tasks to specialized subagents using the 'task' tool:
|
|
|
71
99
|
- Use model="haiku" for simple lookups (cheapest/fastest)
|
|
72
100
|
- This lets you work on multiple things in parallel while staying focused on your main task
|
|
73
101
|
|
|
102
|
+
## CRITICAL: Task Completion Protocol
|
|
103
|
+
You MUST call team_complete_task when your work is done. This is NOT optional.
|
|
104
|
+
- Your task is NOT considered complete until you call team_complete_task
|
|
105
|
+
- Include a structured summary: what files were changed, what was done, any issues found
|
|
106
|
+
- If you cannot complete the task, still call team_complete_task with what you accomplished and what remains
|
|
107
|
+
|
|
74
108
|
## Guidelines
|
|
75
|
-
1. Focus on YOUR assigned task
|
|
76
|
-
2. Communicate blockers or discoveries that affect other tasks
|
|
77
|
-
3.
|
|
78
|
-
4.
|
|
79
|
-
5.
|
|
80
|
-
6. Delegate research or exploration to subagents when your task requires checking multiple areas
|
|
109
|
+
1. Focus on YOUR assigned task — don't work on others' tasks
|
|
110
|
+
2. Communicate blockers or discoveries that affect other tasks via team_message
|
|
111
|
+
3. Check messages periodically for updates from teammates
|
|
112
|
+
4. Avoid modifying files assigned to other teammates' tasks
|
|
113
|
+
5. Delegate research or exploration to subagents when your task requires checking multiple areas
|
|
81
114
|
|
|
82
115
|
## Self-Monitoring
|
|
83
116
|
If a tool fails, use audit_trail (action="errors") to check patterns before retrying.
|
|
@@ -87,603 +120,872 @@ If a tool fails repeatedly, try a different approach instead of retrying the sam
|
|
|
87
120
|
## Output
|
|
88
121
|
Be concise. Report progress and results clearly. Use tools to do the work.`;
|
|
89
122
|
}
|
|
123
|
+
|
|
90
124
|
// ============================================================================
|
|
91
125
|
// TEAM-SPECIFIC TOOLS
|
|
92
126
|
// ============================================================================
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
},
|
|
109
|
-
required: ["to", "message"],
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
name: "team_broadcast",
|
|
114
|
-
description: "Send a message to all teammates",
|
|
115
|
-
input_schema: {
|
|
116
|
-
type: "object",
|
|
117
|
-
properties: {
|
|
118
|
-
message: {
|
|
119
|
-
type: "string",
|
|
120
|
-
description: "Message to broadcast",
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
required: ["message"],
|
|
124
|
-
},
|
|
127
|
+
|
|
128
|
+
const TEAM_TOOLS = [{
|
|
129
|
+
name: "team_message",
|
|
130
|
+
description: "Send a message to a specific teammate or the team lead",
|
|
131
|
+
input_schema: {
|
|
132
|
+
type: "object",
|
|
133
|
+
properties: {
|
|
134
|
+
to: {
|
|
135
|
+
type: "string",
|
|
136
|
+
description: "Teammate ID or 'lead' for team lead"
|
|
137
|
+
},
|
|
138
|
+
message: {
|
|
139
|
+
type: "string",
|
|
140
|
+
description: "Message content"
|
|
141
|
+
}
|
|
125
142
|
},
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
},
|
|
143
|
+
required: ["to", "message"]
|
|
144
|
+
}
|
|
145
|
+
}, {
|
|
146
|
+
name: "team_broadcast",
|
|
147
|
+
description: "Send a message to all teammates",
|
|
148
|
+
input_schema: {
|
|
149
|
+
type: "object",
|
|
150
|
+
properties: {
|
|
151
|
+
message: {
|
|
152
|
+
type: "string",
|
|
153
|
+
description: "Message to broadcast"
|
|
154
|
+
}
|
|
139
155
|
},
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
},
|
|
156
|
+
required: ["message"]
|
|
157
|
+
}
|
|
158
|
+
}, {
|
|
159
|
+
name: "team_claim_task",
|
|
160
|
+
description: "Claim an available task to work on",
|
|
161
|
+
input_schema: {
|
|
162
|
+
type: "object",
|
|
163
|
+
properties: {
|
|
164
|
+
task_id: {
|
|
165
|
+
type: "string",
|
|
166
|
+
description: "ID of the task to claim"
|
|
167
|
+
}
|
|
153
168
|
},
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
169
|
+
required: ["task_id"]
|
|
170
|
+
}
|
|
171
|
+
}, {
|
|
172
|
+
name: "team_complete_task",
|
|
173
|
+
description: "REQUIRED: Mark your current task as complete. You MUST call this tool when done — your task is not considered complete without it. Include a summary of files changed and work done.",
|
|
174
|
+
input_schema: {
|
|
175
|
+
type: "object",
|
|
176
|
+
properties: {
|
|
177
|
+
result: {
|
|
178
|
+
type: "string",
|
|
179
|
+
description: "Summary of what was accomplished"
|
|
180
|
+
}
|
|
161
181
|
},
|
|
162
|
-
]
|
|
182
|
+
required: ["result"]
|
|
183
|
+
}
|
|
184
|
+
}, {
|
|
185
|
+
name: "team_check_messages",
|
|
186
|
+
description: "Check for unread messages from teammates",
|
|
187
|
+
input_schema: {
|
|
188
|
+
type: "object",
|
|
189
|
+
properties: {}
|
|
190
|
+
}
|
|
191
|
+
}];
|
|
192
|
+
|
|
163
193
|
// ============================================================================
|
|
164
194
|
// TOOL EXECUTION
|
|
165
195
|
// ============================================================================
|
|
196
|
+
|
|
166
197
|
async function executeTeamTool(toolName, input, teamId, teammateId, currentTaskId) {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
198
|
+
switch (toolName) {
|
|
199
|
+
case "team_message":
|
|
200
|
+
{
|
|
201
|
+
const to = input.to;
|
|
202
|
+
const message = input.message;
|
|
203
|
+
const result = await sendMessage(teamId, teammateId, to, message);
|
|
204
|
+
return result ? {
|
|
205
|
+
success: true,
|
|
206
|
+
output: `Message sent to ${to}`
|
|
207
|
+
} : {
|
|
208
|
+
success: false,
|
|
209
|
+
output: "Failed to send message"
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
case "team_broadcast":
|
|
213
|
+
{
|
|
214
|
+
const message = input.message;
|
|
215
|
+
const result = await sendMessage(teamId, teammateId, "all", message);
|
|
216
|
+
return result ? {
|
|
217
|
+
success: true,
|
|
218
|
+
output: "Message broadcast to all teammates"
|
|
219
|
+
} : {
|
|
220
|
+
success: false,
|
|
221
|
+
output: "Failed to broadcast message"
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
case "team_claim_task":
|
|
225
|
+
{
|
|
226
|
+
const taskId = input.task_id;
|
|
227
|
+
const task = await claimTask(teamId, taskId, teammateId);
|
|
228
|
+
return task ? {
|
|
229
|
+
success: true,
|
|
230
|
+
output: `Claimed task: ${task.description}`
|
|
231
|
+
} : {
|
|
232
|
+
success: false,
|
|
233
|
+
output: "Failed to claim task (may be unavailable or have unmet dependencies)"
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
case "team_complete_task":
|
|
237
|
+
{
|
|
238
|
+
if (!currentTaskId) {
|
|
239
|
+
return {
|
|
240
|
+
success: false,
|
|
241
|
+
output: "No task currently assigned"
|
|
242
|
+
};
|
|
199
243
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
244
|
+
const result = input.result;
|
|
245
|
+
const success = await completeTask(teamId, currentTaskId, result);
|
|
246
|
+
return success ? {
|
|
247
|
+
success: true,
|
|
248
|
+
output: `Task completed: ${result}`
|
|
249
|
+
} : {
|
|
250
|
+
success: false,
|
|
251
|
+
output: "Failed to complete task"
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
case "team_check_messages":
|
|
255
|
+
{
|
|
256
|
+
const messages = await getUnreadMessages(teamId, teammateId);
|
|
257
|
+
if (messages.length === 0) {
|
|
258
|
+
return {
|
|
259
|
+
success: true,
|
|
260
|
+
output: "No unread messages"
|
|
261
|
+
};
|
|
208
262
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
263
|
+
const msgList = messages.map(m => `From ${m.from}: ${m.content}`).join("\n");
|
|
264
|
+
await markMessagesRead(teamId, messages.map(m => m.id));
|
|
265
|
+
return {
|
|
266
|
+
success: true,
|
|
267
|
+
output: `${messages.length} messages:\n${msgList}`
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
default:
|
|
271
|
+
return {
|
|
272
|
+
success: false,
|
|
273
|
+
output: `Unknown team tool: ${toolName}`
|
|
274
|
+
};
|
|
275
|
+
}
|
|
212
276
|
}
|
|
277
|
+
|
|
213
278
|
// ============================================================================
|
|
214
279
|
// API CLIENT — uses shared callAgentAPI from agent-worker-base
|
|
215
280
|
// ============================================================================
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
281
|
+
|
|
282
|
+
async function callAPI(modelId, systemPrompt, messages, tools, thinkingEnabled = false, onHeartbeat) {
|
|
283
|
+
return callAgentAPI({
|
|
284
|
+
modelId,
|
|
285
|
+
contextProfile: "teammate",
|
|
286
|
+
systemPrompt,
|
|
287
|
+
messages,
|
|
288
|
+
tools,
|
|
289
|
+
thinkingEnabled,
|
|
290
|
+
maxOutputTokens: TEAMMATE_MAX_OUTPUT_TOKENS,
|
|
291
|
+
timeoutMs: API_TIMEOUT_MS,
|
|
292
|
+
onHeartbeat
|
|
293
|
+
});
|
|
227
294
|
}
|
|
295
|
+
|
|
228
296
|
// ============================================================================
|
|
229
297
|
// TEAMMATE WORKER LOOP
|
|
230
298
|
// ============================================================================
|
|
299
|
+
|
|
231
300
|
async function runTeammateLoop(data) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
301
|
+
const {
|
|
302
|
+
teamId,
|
|
303
|
+
teammateId,
|
|
304
|
+
teammateName,
|
|
305
|
+
model,
|
|
306
|
+
cwd,
|
|
307
|
+
parentConversationId,
|
|
308
|
+
teamName,
|
|
309
|
+
authToken,
|
|
310
|
+
preloadedConfig,
|
|
311
|
+
preloadedServerTools
|
|
312
|
+
} = data;
|
|
313
|
+
const modelId = MODEL_MAP[model] || MODEL_MAP.opus; // Inherit parent default
|
|
314
|
+
const startTime = Date.now();
|
|
315
|
+
|
|
316
|
+
// Initialize telemetry client with auth token if provided (do first for early spans)
|
|
317
|
+
if (authToken) {
|
|
318
|
+
initializeTelemetryClient(authToken);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Use pre-loaded config from parent if available (avoids redundant DB call per child).
|
|
322
|
+
// Falls back to direct DB load if parent didn't pre-load.
|
|
323
|
+
if (preloadedConfig?.context_config) {
|
|
324
|
+
const cc = preloadedConfig.context_config;
|
|
325
|
+
TEAMMATE_MAX_TURNS_PER_TASK = cc.subagent_max_turns ?? TEAMMATE_MAX_TURNS_PER_TASK;
|
|
326
|
+
TEAMMATE_MAX_OUTPUT_TOKENS = cc.subagent_max_tokens ?? TEAMMATE_MAX_OUTPUT_TOKENS;
|
|
327
|
+
TEAMMATE_MAX_DURATION_MS = cc.max_duration_ms ?? TEAMMATE_MAX_DURATION_MS;
|
|
328
|
+
TEAMMATE_MAX_TOTAL_TURNS = cc.teammate_max_total_turns ?? TEAMMATE_MAX_TOTAL_TURNS;
|
|
329
|
+
API_TIMEOUT_MS = cc.api_timeout_ms ?? API_TIMEOUT_MS;
|
|
330
|
+
TOOL_TIMEOUT_MS = cc.tool_timeout_ms ?? TOOL_TIMEOUT_MS;
|
|
331
|
+
resolvedTeammateConfig = resolveAgentLoopConfig(preloadedConfig, "sse");
|
|
332
|
+
} else {
|
|
333
|
+
await resolveTeammateConfig();
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Each teammate gets its own conversation_id (separate trace)
|
|
337
|
+
// but links to parent via parent_conversation_id
|
|
338
|
+
const teammateConversationId = getConversationId(); // Worker's own ID
|
|
339
|
+
|
|
340
|
+
// Create trace context for this teammate
|
|
341
|
+
const teammateTraceId = generateTraceId();
|
|
342
|
+
const teammateSpanId = generateSpanId();
|
|
343
|
+
|
|
344
|
+
// Log teammate start - links to parent for tree hierarchy
|
|
345
|
+
logSpan({
|
|
346
|
+
action: "team.teammate_start",
|
|
347
|
+
durationMs: 0,
|
|
348
|
+
context: {
|
|
349
|
+
traceId: teammateTraceId,
|
|
350
|
+
spanId: teammateSpanId,
|
|
351
|
+
conversationId: teammateConversationId,
|
|
352
|
+
source: "claude_code",
|
|
353
|
+
serviceName: "whale-cli",
|
|
354
|
+
serviceVersion: PKG_VERSION,
|
|
355
|
+
model: modelId
|
|
356
|
+
},
|
|
357
|
+
details: {
|
|
358
|
+
is_team: true,
|
|
359
|
+
is_teammate: true,
|
|
360
|
+
team_id: teamId,
|
|
361
|
+
teammate_id: teammateId,
|
|
362
|
+
teammate_name: teammateName,
|
|
363
|
+
team_name: teamName,
|
|
364
|
+
parent_conversation_id: parentConversationId,
|
|
365
|
+
// Link to parent trace
|
|
366
|
+
model: model,
|
|
367
|
+
display_name: teammateName,
|
|
368
|
+
display_icon: "person.fill",
|
|
369
|
+
display_color: "#3B82F6"
|
|
238
370
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
371
|
+
});
|
|
372
|
+
const report = msg => {
|
|
373
|
+
if (process.send) {
|
|
374
|
+
process.send(msg);
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
// Report early — let parent know we're alive before async init
|
|
379
|
+
report({
|
|
380
|
+
type: "progress",
|
|
381
|
+
teammateId,
|
|
382
|
+
content: `${teammateName} initializing...`
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
// Get all tools (local + server + team)
|
|
386
|
+
const localTools = LOCAL_TOOL_DEFINITIONS.map(t => ({
|
|
387
|
+
name: t.name,
|
|
388
|
+
description: t.description,
|
|
389
|
+
input_schema: t.input_schema
|
|
390
|
+
}));
|
|
391
|
+
|
|
392
|
+
// Use pre-loaded server tools from parent if available (avoids redundant API call per child)
|
|
393
|
+
let serverTools = preloadedServerTools || [];
|
|
394
|
+
if (!preloadedServerTools) {
|
|
395
|
+
try {
|
|
396
|
+
serverTools = await loadServerToolDefinitions();
|
|
397
|
+
} catch {/* server tools unavailable — continue with local tools only */}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Deduplicate: local tools take priority, then server tools, then team tools
|
|
401
|
+
const allTools = deduplicateTools([...localTools, ...serverTools, ...TEAM_TOOLS]);
|
|
402
|
+
assertUniqueToolNames(allTools);
|
|
403
|
+
const loopDetector = resolvedTeammateConfig ? LoopDetector.fromResolved(resolvedTeammateConfig) : new LoopDetector();
|
|
404
|
+
let totalIn = 0;
|
|
405
|
+
let totalOut = 0;
|
|
406
|
+
let currentTaskId = null;
|
|
407
|
+
let currentTaskModelId = modelId; // Per-task model (defaults to team model)
|
|
408
|
+
let currentTaskThinking = false; // Per-task thinking toggle
|
|
409
|
+
let messages = [];
|
|
410
|
+
let tasksCompleted = 0;
|
|
411
|
+
report({
|
|
412
|
+
type: "progress",
|
|
413
|
+
teammateId,
|
|
414
|
+
content: `${teammateName} ready (${allTools.length} tools)`
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
// Helper to log teammate completion
|
|
418
|
+
const logTeammateComplete = reason => {
|
|
419
|
+
const teammateCost = estimateCostUsd(totalIn, totalOut, modelId);
|
|
246
420
|
logSpan({
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
421
|
+
action: "team.teammate_done",
|
|
422
|
+
durationMs: Date.now() - startTime,
|
|
423
|
+
context: {
|
|
424
|
+
traceId: teammateTraceId,
|
|
425
|
+
spanId: generateSpanId(),
|
|
426
|
+
parentSpanId: teammateSpanId,
|
|
427
|
+
conversationId: teammateConversationId,
|
|
428
|
+
source: "claude_code",
|
|
429
|
+
serviceName: "whale-cli",
|
|
430
|
+
serviceVersion: PKG_VERSION,
|
|
431
|
+
model: modelId,
|
|
432
|
+
inputTokens: totalIn,
|
|
433
|
+
outputTokens: totalOut,
|
|
434
|
+
totalCost: teammateCost
|
|
435
|
+
},
|
|
436
|
+
details: {
|
|
437
|
+
is_team: true,
|
|
438
|
+
is_teammate: true,
|
|
439
|
+
team_id: teamId,
|
|
440
|
+
teammate_id: teammateId,
|
|
441
|
+
teammate_name: teammateName,
|
|
442
|
+
team_name: teamName,
|
|
443
|
+
parent_conversation_id: parentConversationId,
|
|
444
|
+
tasks_completed: tasksCompleted,
|
|
445
|
+
completion_reason: reason,
|
|
446
|
+
"gen_ai.request.model": modelId,
|
|
447
|
+
"gen_ai.usage.input_tokens": totalIn,
|
|
448
|
+
"gen_ai.usage.output_tokens": totalOut,
|
|
449
|
+
"gen_ai.usage.cost": teammateCost,
|
|
450
|
+
display_name: `${teammateName} done`,
|
|
451
|
+
display_icon: "checkmark.circle.fill",
|
|
452
|
+
display_color: "#10B981"
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
// Main work loop - keep working until no more tasks
|
|
458
|
+
let outerTurn = 0;
|
|
459
|
+
while (true) {
|
|
460
|
+
// Safety: max turns guard (0 = no limit, Claude Code parity)
|
|
461
|
+
if (TEAMMATE_MAX_TOTAL_TURNS > 0 && ++outerTurn > TEAMMATE_MAX_TOTAL_TURNS) {
|
|
462
|
+
logTeammateComplete("max_turns_reached");
|
|
463
|
+
report({
|
|
464
|
+
type: "done",
|
|
465
|
+
teammateId,
|
|
466
|
+
content: `${teammateName} reached max turns (${TEAMMATE_MAX_TOTAL_TURNS})`,
|
|
467
|
+
tokensUsed: {
|
|
468
|
+
input: totalIn,
|
|
469
|
+
output: totalOut
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
break;
|
|
473
|
+
}
|
|
474
|
+
// Safety: elapsed time guard
|
|
475
|
+
if (Date.now() - startTime > TEAMMATE_MAX_DURATION_MS) {
|
|
476
|
+
logTeammateComplete("timeout");
|
|
477
|
+
report({
|
|
478
|
+
type: "done",
|
|
479
|
+
teammateId,
|
|
480
|
+
content: `${teammateName} timed out after ${Math.round(TEAMMATE_MAX_DURATION_MS / 60_000)}min`,
|
|
481
|
+
tokensUsed: {
|
|
482
|
+
input: totalIn,
|
|
483
|
+
output: totalOut
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
break;
|
|
487
|
+
}
|
|
488
|
+
const team = loadTeam(teamId);
|
|
489
|
+
if (!team || team.status !== "active") {
|
|
490
|
+
logTeammateComplete("team_inactive");
|
|
491
|
+
report({
|
|
492
|
+
type: "done",
|
|
493
|
+
teammateId,
|
|
494
|
+
content: "Team completed or inactive",
|
|
495
|
+
tokensUsed: {
|
|
496
|
+
input: totalIn,
|
|
497
|
+
output: totalOut
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
break;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// Find current task or claim a new one
|
|
504
|
+
const currentTask = currentTaskId ? team.tasks.find(t => t.id === currentTaskId) : null;
|
|
505
|
+
|
|
506
|
+
// If no current task, try to claim one
|
|
507
|
+
if (!currentTask || currentTask.status === "completed") {
|
|
508
|
+
const available = getAvailableTasks(team);
|
|
509
|
+
if (available.length === 0) {
|
|
510
|
+
// No tasks available, check if all done or waiting
|
|
511
|
+
const inProgress = team.tasks.filter(t => t.status === "in_progress").length;
|
|
512
|
+
if (inProgress === 0) {
|
|
513
|
+
logTeammateComplete("all_tasks_done");
|
|
514
|
+
report({
|
|
515
|
+
type: "done",
|
|
516
|
+
teammateId,
|
|
517
|
+
content: "All tasks completed",
|
|
518
|
+
tokensUsed: {
|
|
519
|
+
input: totalIn,
|
|
520
|
+
output: totalOut
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
break;
|
|
524
|
+
}
|
|
525
|
+
// Wait and retry
|
|
526
|
+
await new Promise(r => setTimeout(r, 2000));
|
|
527
|
+
continue;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// Claim first available task
|
|
531
|
+
const claimed = await claimTask(teamId, available[0].id, teammateId);
|
|
532
|
+
if (!claimed) {
|
|
533
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
534
|
+
continue;
|
|
535
|
+
}
|
|
536
|
+
currentTaskId = claimed.id;
|
|
537
|
+
|
|
538
|
+
// Resolve per-task model: task-level → team default
|
|
539
|
+
const taskModel = claimed.model || model;
|
|
540
|
+
currentTaskModelId = MODEL_MAP[taskModel] || MODEL_MAP[model] || MODEL_MAP.opus;
|
|
541
|
+
|
|
542
|
+
// Enable thinking for teammates — with 32K output tokens (matching Claude Code),
|
|
543
|
+
// adaptive thinking has room to reason without starving code output.
|
|
544
|
+
currentTaskThinking = true;
|
|
545
|
+
await updateTeammate(teamId, teammateId, {
|
|
546
|
+
status: "working",
|
|
547
|
+
currentTask: currentTaskId
|
|
548
|
+
});
|
|
549
|
+
report({
|
|
550
|
+
type: "task_started",
|
|
551
|
+
teammateId,
|
|
552
|
+
taskId: currentTaskId,
|
|
553
|
+
content: claimed.description
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
// Start fresh conversation for new task
|
|
557
|
+
messages = [{
|
|
558
|
+
role: "user",
|
|
559
|
+
content: `Your task: ${claimed.description}\n\nBegin working on this task. When finished, you MUST call team_complete_task with a summary of changes made. Do not stop without calling team_complete_task.`
|
|
560
|
+
}];
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// Build system prompt with current state
|
|
564
|
+
const freshTeam = loadTeam(teamId);
|
|
565
|
+
const freshTask = freshTeam.tasks.find(t => t.id === currentTaskId) || null;
|
|
566
|
+
const systemPrompt = buildTeammatePrompt(teammateName, freshTeam, freshTask, cwd);
|
|
567
|
+
|
|
568
|
+
// Agent loop for current task
|
|
569
|
+
let apiError = null;
|
|
570
|
+
let lastTurn = 0;
|
|
571
|
+
// 0 = no limit (agent self-regulates via end_turn, Claude Code parity)
|
|
572
|
+
const taskTurnLimit = TEAMMATE_MAX_TURNS_PER_TASK === 0 ? Number.MAX_SAFE_INTEGER : TEAMMATE_MAX_TURNS_PER_TASK;
|
|
573
|
+
for (let turn = 0; turn < taskTurnLimit; turn++) {
|
|
574
|
+
lastTurn = turn;
|
|
575
|
+
const apiStart = Date.now();
|
|
576
|
+
let response;
|
|
577
|
+
try {
|
|
578
|
+
response = await callAPI(currentTaskModelId, systemPrompt, messages, allTools, currentTaskThinking, () => {
|
|
579
|
+
// Heartbeat during long API calls (thinking/streaming) — keeps parent stall detector alive.
|
|
580
|
+
// Without this, a 90s API call = 90s silence → parent kills worker at WORKER_STALL_MS.
|
|
581
|
+
report({
|
|
582
|
+
type: "progress",
|
|
583
|
+
teammateId,
|
|
584
|
+
content: "streaming..."
|
|
585
|
+
});
|
|
586
|
+
});
|
|
587
|
+
} catch (err) {
|
|
588
|
+
apiError = err.message || String(err);
|
|
589
|
+
report({
|
|
590
|
+
type: "progress",
|
|
591
|
+
teammateId,
|
|
592
|
+
content: `API error: ${apiError.slice(0, 80)}`
|
|
593
|
+
});
|
|
594
|
+
logSpan({
|
|
595
|
+
action: "claude_api_request",
|
|
596
|
+
durationMs: Date.now() - apiStart,
|
|
597
|
+
severity: "error",
|
|
598
|
+
error: apiError || undefined,
|
|
599
|
+
context: {
|
|
250
600
|
traceId: teammateTraceId,
|
|
251
|
-
spanId:
|
|
601
|
+
spanId: generateSpanId(),
|
|
602
|
+
parentSpanId: teammateSpanId,
|
|
252
603
|
conversationId: teammateConversationId,
|
|
253
604
|
source: "claude_code",
|
|
254
605
|
serviceName: "whale-cli",
|
|
255
|
-
serviceVersion:
|
|
256
|
-
model:
|
|
257
|
-
|
|
258
|
-
|
|
606
|
+
serviceVersion: PKG_VERSION,
|
|
607
|
+
model: currentTaskModelId
|
|
608
|
+
},
|
|
609
|
+
details: {
|
|
259
610
|
is_team: true,
|
|
260
611
|
is_teammate: true,
|
|
261
612
|
team_id: teamId,
|
|
262
613
|
teammate_id: teammateId,
|
|
263
614
|
teammate_name: teammateName,
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
615
|
+
parent_conversation_id: parentConversationId,
|
|
616
|
+
turn_number: turn + 1,
|
|
617
|
+
task_id: currentTaskId
|
|
618
|
+
}
|
|
619
|
+
});
|
|
620
|
+
break; // Exit inner loop — force-complete handler below will deal with the task
|
|
621
|
+
}
|
|
622
|
+
const apiDuration = Date.now() - apiStart;
|
|
623
|
+
totalIn += response.usage.input_tokens;
|
|
624
|
+
totalOut += response.usage.output_tokens;
|
|
625
|
+
|
|
626
|
+
// Log Claude API request telemetry — include cache tokens for accurate cost
|
|
627
|
+
const turnCostUsd = estimateCostUsd(response.usage.input_tokens, response.usage.output_tokens, currentTaskModelId, 0,
|
|
628
|
+
// thinkingTokens (disabled for teammates)
|
|
629
|
+
response.usage.cache_read_tokens, response.usage.cache_creation_tokens);
|
|
630
|
+
logSpan({
|
|
631
|
+
action: "claude_api_request",
|
|
632
|
+
durationMs: apiDuration,
|
|
633
|
+
context: {
|
|
634
|
+
traceId: teammateTraceId,
|
|
635
|
+
spanId: generateSpanId(),
|
|
636
|
+
parentSpanId: teammateSpanId,
|
|
637
|
+
conversationId: teammateConversationId,
|
|
638
|
+
source: "claude_code",
|
|
639
|
+
serviceName: "whale-cli",
|
|
640
|
+
serviceVersion: PKG_VERSION,
|
|
641
|
+
model: currentTaskModelId,
|
|
642
|
+
inputTokens: response.usage.input_tokens,
|
|
643
|
+
outputTokens: response.usage.output_tokens,
|
|
644
|
+
cacheReadTokens: response.usage.cache_read_tokens,
|
|
645
|
+
cacheCreationTokens: response.usage.cache_creation_tokens,
|
|
646
|
+
totalCost: turnCostUsd
|
|
270
647
|
},
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
648
|
+
details: {
|
|
649
|
+
is_team: true,
|
|
650
|
+
is_teammate: true,
|
|
651
|
+
team_id: teamId,
|
|
652
|
+
teammate_id: teammateId,
|
|
653
|
+
teammate_name: teammateName,
|
|
654
|
+
parent_conversation_id: parentConversationId,
|
|
655
|
+
turn_number: turn + 1,
|
|
656
|
+
task_id: currentTaskId,
|
|
657
|
+
stop_reason: response.stop_reason,
|
|
658
|
+
"gen_ai.request.model": currentTaskModelId,
|
|
659
|
+
"gen_ai.usage.input_tokens": response.usage.input_tokens,
|
|
660
|
+
"gen_ai.usage.output_tokens": response.usage.output_tokens,
|
|
661
|
+
"gen_ai.usage.cache_read_tokens": response.usage.cache_read_tokens,
|
|
662
|
+
"gen_ai.usage.cache_creation_tokens": response.usage.cache_creation_tokens,
|
|
663
|
+
"gen_ai.usage.cost": turnCostUsd
|
|
275
664
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
665
|
+
});
|
|
666
|
+
const textBlocks = extractTextBlocks(response.content);
|
|
667
|
+
const toolBlocks = extractToolUseBlocks(response.content);
|
|
668
|
+
|
|
669
|
+
// Report progress
|
|
670
|
+
if (textBlocks.length) {
|
|
671
|
+
report({
|
|
672
|
+
type: "progress",
|
|
673
|
+
teammateId,
|
|
674
|
+
taskId: currentTaskId || undefined,
|
|
675
|
+
content: textBlocks[0].text.slice(0, 200)
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
// Compaction handling — API paused after generating context summary.
|
|
680
|
+
// Replace entire message history with the compaction block (per Anthropic docs).
|
|
681
|
+
if (response.stop_reason === "compaction") {
|
|
682
|
+
const compactionBlock = response.content.find(b => b.type === "compaction");
|
|
683
|
+
if (compactionBlock) {
|
|
684
|
+
report({
|
|
685
|
+
type: "progress",
|
|
686
|
+
teammateId,
|
|
687
|
+
taskId: currentTaskId || undefined,
|
|
688
|
+
content: "context compacted"
|
|
689
|
+
});
|
|
690
|
+
messages = [{
|
|
691
|
+
role: "assistant",
|
|
692
|
+
content: [{
|
|
693
|
+
type: "compaction",
|
|
694
|
+
content: compactionBlock.content
|
|
695
|
+
}]
|
|
696
|
+
}, {
|
|
697
|
+
role: "user",
|
|
698
|
+
content: [{
|
|
699
|
+
type: "text",
|
|
700
|
+
text: "Continue with your task."
|
|
701
|
+
}]
|
|
702
|
+
}];
|
|
703
|
+
turn--; // Don't count compaction as a turn
|
|
704
|
+
continue;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
// No tools = done with this turn
|
|
709
|
+
if (toolBlocks.length === 0) break;
|
|
710
|
+
|
|
711
|
+
// Execute tools using shared executeToolBlocks with team-specific custom executor
|
|
712
|
+
let taskCompleted = false;
|
|
713
|
+
const {
|
|
714
|
+
toolResults
|
|
715
|
+
} = await executeToolBlocks({
|
|
716
|
+
toolBlocks,
|
|
717
|
+
loopDetector,
|
|
718
|
+
toolTimeoutMs: TOOL_TIMEOUT_MS,
|
|
719
|
+
customExecutor: async (toolName, input) => {
|
|
720
|
+
// Only handle team tools; return null to fall through to standard routing
|
|
721
|
+
if (!TEAM_TOOLS.some(t => t.name === toolName)) return null;
|
|
722
|
+
const result = await executeTeamTool(toolName, input, teamId, teammateId, currentTaskId);
|
|
723
|
+
|
|
724
|
+
// Check if task was completed
|
|
725
|
+
if (toolName === "team_complete_task" && result.success) {
|
|
726
|
+
taskCompleted = true;
|
|
727
|
+
tasksCompleted++;
|
|
728
|
+
report({
|
|
729
|
+
type: "task_completed",
|
|
730
|
+
teammateId,
|
|
731
|
+
taskId: currentTaskId || undefined,
|
|
732
|
+
content: result.output
|
|
733
|
+
});
|
|
734
|
+
|
|
735
|
+
// Log task completion to telemetry
|
|
736
|
+
logSpan({
|
|
737
|
+
action: "team.task_complete",
|
|
738
|
+
durationMs: 0,
|
|
739
|
+
context: {
|
|
310
740
|
traceId: teammateTraceId,
|
|
311
741
|
spanId: generateSpanId(),
|
|
312
742
|
parentSpanId: teammateSpanId,
|
|
313
743
|
conversationId: teammateConversationId,
|
|
314
744
|
source: "claude_code",
|
|
315
745
|
serviceName: "whale-cli",
|
|
316
|
-
serviceVersion:
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
outputTokens: totalOut,
|
|
320
|
-
totalCost: teammateCost,
|
|
321
|
-
},
|
|
322
|
-
details: {
|
|
746
|
+
serviceVersion: PKG_VERSION
|
|
747
|
+
},
|
|
748
|
+
details: {
|
|
323
749
|
is_team: true,
|
|
324
750
|
is_teammate: true,
|
|
325
751
|
team_id: teamId,
|
|
326
752
|
teammate_id: teammateId,
|
|
327
753
|
teammate_name: teammateName,
|
|
328
|
-
team_name: teamName,
|
|
329
754
|
parent_conversation_id: parentConversationId,
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
"
|
|
333
|
-
"
|
|
334
|
-
"
|
|
335
|
-
|
|
336
|
-
display_name: `${teammateName} done`,
|
|
337
|
-
display_icon: "checkmark.circle.fill",
|
|
338
|
-
display_color: "#10B981",
|
|
339
|
-
},
|
|
340
|
-
});
|
|
341
|
-
};
|
|
342
|
-
// Main work loop - keep working until no more tasks
|
|
343
|
-
let outerTurn = 0;
|
|
344
|
-
while (true) {
|
|
345
|
-
// Safety: max turns guard
|
|
346
|
-
if (++outerTurn > MAX_TEAMMATE_TURNS) {
|
|
347
|
-
logTeammateComplete("max_turns_reached");
|
|
348
|
-
report({ type: "done", teammateId, content: `${teammateName} reached max turns (${MAX_TEAMMATE_TURNS})`, tokensUsed: { input: totalIn, output: totalOut } });
|
|
349
|
-
break;
|
|
350
|
-
}
|
|
351
|
-
// Safety: elapsed time guard
|
|
352
|
-
if (Date.now() - startTime > MAX_TEAMMATE_DURATION_MS) {
|
|
353
|
-
logTeammateComplete("timeout");
|
|
354
|
-
report({ type: "done", teammateId, content: `${teammateName} timed out after ${Math.round(MAX_TEAMMATE_DURATION_MS / 60_000)}min`, tokensUsed: { input: totalIn, output: totalOut } });
|
|
355
|
-
break;
|
|
356
|
-
}
|
|
357
|
-
const team = loadTeam(teamId);
|
|
358
|
-
if (!team || team.status !== "active") {
|
|
359
|
-
logTeammateComplete("team_inactive");
|
|
360
|
-
report({ type: "done", teammateId, content: "Team completed or inactive", tokensUsed: { input: totalIn, output: totalOut } });
|
|
361
|
-
break;
|
|
362
|
-
}
|
|
363
|
-
// Find current task or claim a new one
|
|
364
|
-
const currentTask = currentTaskId
|
|
365
|
-
? team.tasks.find(t => t.id === currentTaskId)
|
|
366
|
-
: null;
|
|
367
|
-
// If no current task, try to claim one
|
|
368
|
-
if (!currentTask || currentTask.status === "completed") {
|
|
369
|
-
const available = getAvailableTasks(team);
|
|
370
|
-
if (available.length === 0) {
|
|
371
|
-
// No tasks available, check if all done or waiting
|
|
372
|
-
const inProgress = team.tasks.filter(t => t.status === "in_progress").length;
|
|
373
|
-
if (inProgress === 0) {
|
|
374
|
-
logTeammateComplete("all_tasks_done");
|
|
375
|
-
report({ type: "done", teammateId, content: "All tasks completed", tokensUsed: { input: totalIn, output: totalOut } });
|
|
376
|
-
break;
|
|
377
|
-
}
|
|
378
|
-
// Wait and retry
|
|
379
|
-
await new Promise(r => setTimeout(r, 2000));
|
|
380
|
-
continue;
|
|
381
|
-
}
|
|
382
|
-
// Claim first available task
|
|
383
|
-
const claimed = await claimTask(teamId, available[0].id, teammateId);
|
|
384
|
-
if (!claimed) {
|
|
385
|
-
await new Promise(r => setTimeout(r, 1000));
|
|
386
|
-
continue;
|
|
387
|
-
}
|
|
388
|
-
currentTaskId = claimed.id;
|
|
389
|
-
// Resolve per-task model: task-level → team default
|
|
390
|
-
const taskModel = claimed.model || model;
|
|
391
|
-
currentTaskModelId = MODEL_MAP[taskModel] || MODEL_MAP[model] || MODEL_MAP.opus;
|
|
392
|
-
// Disable thinking for teammates — with MAX_OUTPUT_TOKENS=16K, adaptive thinking
|
|
393
|
-
// burns 8-12K tokens on reasoning per turn, leaving only 4-8K for actual code output.
|
|
394
|
-
// This caused catastrophic token bloat (359K input tokens per task) and truncated responses.
|
|
395
|
-
currentTaskThinking = false;
|
|
396
|
-
await updateTeammate(teamId, teammateId, { status: "working", currentTask: currentTaskId });
|
|
397
|
-
report({ type: "task_started", teammateId, taskId: currentTaskId, content: claimed.description });
|
|
398
|
-
// Start fresh conversation for new task
|
|
399
|
-
messages = [{
|
|
400
|
-
role: "user",
|
|
401
|
-
content: `Your task: ${claimed.description}\n\nBegin working on this task. Use the available tools to complete it, then use team_complete_task when done.`,
|
|
402
|
-
}];
|
|
403
|
-
}
|
|
404
|
-
// Build system prompt with current state
|
|
405
|
-
const freshTeam = loadTeam(teamId);
|
|
406
|
-
const freshTask = freshTeam.tasks.find(t => t.id === currentTaskId) || null;
|
|
407
|
-
const systemPrompt = buildTeammatePrompt(teammateName, freshTeam, freshTask, cwd);
|
|
408
|
-
// Agent loop for current task
|
|
409
|
-
let apiError = null;
|
|
410
|
-
for (let turn = 0; turn < MAX_TURNS_PER_TASK; turn++) {
|
|
411
|
-
const apiStart = Date.now();
|
|
412
|
-
let response;
|
|
413
|
-
try {
|
|
414
|
-
response = await callAPI(currentTaskModelId, systemPrompt, messages, allTools, currentTaskThinking);
|
|
415
|
-
}
|
|
416
|
-
catch (err) {
|
|
417
|
-
apiError = err.message || String(err);
|
|
418
|
-
report({ type: "progress", teammateId, content: `API error: ${apiError.slice(0, 80)}` });
|
|
419
|
-
logSpan({
|
|
420
|
-
action: "claude_api_request",
|
|
421
|
-
durationMs: Date.now() - apiStart,
|
|
422
|
-
severity: "error",
|
|
423
|
-
error: apiError || undefined,
|
|
424
|
-
context: {
|
|
425
|
-
traceId: teammateTraceId,
|
|
426
|
-
spanId: generateSpanId(),
|
|
427
|
-
parentSpanId: teammateSpanId,
|
|
428
|
-
conversationId: teammateConversationId,
|
|
429
|
-
source: "claude_code",
|
|
430
|
-
serviceName: "whale-cli",
|
|
431
|
-
serviceVersion: "2.1.0",
|
|
432
|
-
model: currentTaskModelId,
|
|
433
|
-
},
|
|
434
|
-
details: {
|
|
435
|
-
is_team: true,
|
|
436
|
-
is_teammate: true,
|
|
437
|
-
team_id: teamId,
|
|
438
|
-
teammate_id: teammateId,
|
|
439
|
-
teammate_name: teammateName,
|
|
440
|
-
parent_conversation_id: parentConversationId,
|
|
441
|
-
turn_number: turn + 1,
|
|
442
|
-
task_id: currentTaskId,
|
|
443
|
-
},
|
|
444
|
-
});
|
|
445
|
-
break; // Exit inner loop — force-complete handler below will deal with the task
|
|
446
|
-
}
|
|
447
|
-
const apiDuration = Date.now() - apiStart;
|
|
448
|
-
totalIn += response.usage.input_tokens;
|
|
449
|
-
totalOut += response.usage.output_tokens;
|
|
450
|
-
// Log Claude API request telemetry
|
|
451
|
-
const turnCostUsd = estimateCostUsd(response.usage.input_tokens, response.usage.output_tokens, currentTaskModelId);
|
|
452
|
-
logSpan({
|
|
453
|
-
action: "claude_api_request",
|
|
454
|
-
durationMs: apiDuration,
|
|
455
|
-
context: {
|
|
456
|
-
traceId: teammateTraceId,
|
|
457
|
-
spanId: generateSpanId(),
|
|
458
|
-
parentSpanId: teammateSpanId,
|
|
459
|
-
conversationId: teammateConversationId,
|
|
460
|
-
source: "claude_code",
|
|
461
|
-
serviceName: "whale-cli",
|
|
462
|
-
serviceVersion: "2.1.0",
|
|
463
|
-
model: currentTaskModelId,
|
|
464
|
-
inputTokens: response.usage.input_tokens,
|
|
465
|
-
outputTokens: response.usage.output_tokens,
|
|
466
|
-
totalCost: turnCostUsd,
|
|
467
|
-
},
|
|
468
|
-
details: {
|
|
469
|
-
is_team: true,
|
|
470
|
-
is_teammate: true,
|
|
471
|
-
team_id: teamId,
|
|
472
|
-
teammate_id: teammateId,
|
|
473
|
-
teammate_name: teammateName,
|
|
474
|
-
parent_conversation_id: parentConversationId,
|
|
475
|
-
turn_number: turn + 1,
|
|
476
|
-
task_id: currentTaskId,
|
|
477
|
-
stop_reason: response.stop_reason,
|
|
478
|
-
"gen_ai.request.model": currentTaskModelId,
|
|
479
|
-
"gen_ai.usage.input_tokens": response.usage.input_tokens,
|
|
480
|
-
"gen_ai.usage.output_tokens": response.usage.output_tokens,
|
|
481
|
-
"gen_ai.usage.cost": turnCostUsd,
|
|
482
|
-
},
|
|
755
|
+
task_id: currentTaskId,
|
|
756
|
+
task_result: result.output.slice(0, 500),
|
|
757
|
+
display_name: "Task completed",
|
|
758
|
+
display_icon: "checkmark.square.fill",
|
|
759
|
+
display_color: "#10B981"
|
|
760
|
+
}
|
|
483
761
|
});
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
//
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
loopDetector,
|
|
498
|
-
toolTimeoutMs: TOOL_TIMEOUT_MS,
|
|
499
|
-
customExecutor: async (toolName, input) => {
|
|
500
|
-
// Only handle team tools; return null to fall through to standard routing
|
|
501
|
-
if (!TEAM_TOOLS.some(t => t.name === toolName))
|
|
502
|
-
return null;
|
|
503
|
-
const result = await executeTeamTool(toolName, input, teamId, teammateId, currentTaskId);
|
|
504
|
-
// Check if task was completed
|
|
505
|
-
if (toolName === "team_complete_task" && result.success) {
|
|
506
|
-
taskCompleted = true;
|
|
507
|
-
tasksCompleted++;
|
|
508
|
-
report({ type: "task_completed", teammateId, taskId: currentTaskId || undefined, content: result.output });
|
|
509
|
-
// Log task completion to telemetry
|
|
510
|
-
logSpan({
|
|
511
|
-
action: "team.task_complete",
|
|
512
|
-
durationMs: 0,
|
|
513
|
-
context: {
|
|
514
|
-
traceId: teammateTraceId,
|
|
515
|
-
spanId: generateSpanId(),
|
|
516
|
-
parentSpanId: teammateSpanId,
|
|
517
|
-
conversationId: teammateConversationId,
|
|
518
|
-
source: "claude_code",
|
|
519
|
-
serviceName: "whale-cli",
|
|
520
|
-
serviceVersion: "2.1.0",
|
|
521
|
-
},
|
|
522
|
-
details: {
|
|
523
|
-
is_team: true,
|
|
524
|
-
is_teammate: true,
|
|
525
|
-
team_id: teamId,
|
|
526
|
-
teammate_id: teammateId,
|
|
527
|
-
teammate_name: teammateName,
|
|
528
|
-
parent_conversation_id: parentConversationId,
|
|
529
|
-
task_id: currentTaskId,
|
|
530
|
-
task_result: result.output.slice(0, 500),
|
|
531
|
-
display_name: "Task completed",
|
|
532
|
-
display_icon: "checkmark.square.fill",
|
|
533
|
-
display_color: "#10B981",
|
|
534
|
-
},
|
|
535
|
-
});
|
|
536
|
-
}
|
|
537
|
-
return result;
|
|
538
|
-
},
|
|
539
|
-
callbacks: {
|
|
540
|
-
onToolEnd: (toolName, success, durationMs) => {
|
|
541
|
-
// Determine tool category for telemetry
|
|
542
|
-
const toolCategory = TEAM_TOOLS.some(t => t.name === toolName) ? "team" : "standard";
|
|
543
|
-
logSpan({
|
|
544
|
-
action: `tool.${toolName}`,
|
|
545
|
-
durationMs,
|
|
546
|
-
severity: success ? "info" : "error",
|
|
547
|
-
context: {
|
|
548
|
-
traceId: teammateTraceId,
|
|
549
|
-
spanId: generateSpanId(),
|
|
550
|
-
parentSpanId: teammateSpanId,
|
|
551
|
-
conversationId: teammateConversationId,
|
|
552
|
-
source: "claude_code",
|
|
553
|
-
serviceName: "whale-cli",
|
|
554
|
-
serviceVersion: "2.1.0",
|
|
555
|
-
},
|
|
556
|
-
error: success ? undefined : "(see tool result)",
|
|
557
|
-
details: {
|
|
558
|
-
is_team: true,
|
|
559
|
-
is_teammate: true,
|
|
560
|
-
team_id: teamId,
|
|
561
|
-
teammate_id: teammateId,
|
|
562
|
-
teammate_name: teammateName,
|
|
563
|
-
parent_conversation_id: parentConversationId,
|
|
564
|
-
tool_category: toolCategory,
|
|
565
|
-
},
|
|
566
|
-
});
|
|
567
|
-
},
|
|
568
|
-
},
|
|
762
|
+
}
|
|
763
|
+
return result;
|
|
764
|
+
},
|
|
765
|
+
callbacks: {
|
|
766
|
+
onToolEnd: (toolName, success, durationMs) => {
|
|
767
|
+
// Heartbeat: report tool activity to parent so stall detector knows we're alive.
|
|
768
|
+
// Without this, tool-only responses (no text blocks) never update lastMessageTime
|
|
769
|
+
// and the worker gets false-positive killed after WORKER_STALL_MS.
|
|
770
|
+
report({
|
|
771
|
+
type: "progress",
|
|
772
|
+
teammateId,
|
|
773
|
+
taskId: currentTaskId || undefined,
|
|
774
|
+
content: `${toolName} (${durationMs}ms)`
|
|
569
775
|
});
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
776
|
+
|
|
777
|
+
// Determine tool category for telemetry
|
|
778
|
+
const toolCategory = TEAM_TOOLS.some(t => t.name === toolName) ? "team" : "standard";
|
|
779
|
+
logSpan({
|
|
780
|
+
action: `tool.${toolName}`,
|
|
781
|
+
durationMs,
|
|
782
|
+
severity: success ? "info" : "error",
|
|
783
|
+
context: {
|
|
784
|
+
traceId: teammateTraceId,
|
|
785
|
+
spanId: generateSpanId(),
|
|
786
|
+
parentSpanId: teammateSpanId,
|
|
787
|
+
conversationId: teammateConversationId,
|
|
788
|
+
source: "claude_code",
|
|
789
|
+
serviceName: "whale-cli",
|
|
790
|
+
serviceVersion: PKG_VERSION
|
|
791
|
+
},
|
|
792
|
+
error: success ? undefined : "(see tool result)",
|
|
793
|
+
details: {
|
|
794
|
+
is_team: true,
|
|
795
|
+
is_teammate: true,
|
|
796
|
+
team_id: teamId,
|
|
797
|
+
teammate_id: teammateId,
|
|
798
|
+
teammate_name: teammateName,
|
|
799
|
+
parent_conversation_id: parentConversationId,
|
|
800
|
+
tool_category: toolCategory
|
|
801
|
+
}
|
|
802
|
+
});
|
|
803
|
+
}
|
|
579
804
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
805
|
+
});
|
|
806
|
+
|
|
807
|
+
// Append to messages
|
|
808
|
+
messages.push({
|
|
809
|
+
role: "assistant",
|
|
810
|
+
content: response.content
|
|
811
|
+
});
|
|
812
|
+
messages.push({
|
|
813
|
+
role: "user",
|
|
814
|
+
content: toolResults
|
|
815
|
+
});
|
|
816
|
+
|
|
817
|
+
// Pre-compact: trim large tool results and thinking blocks to prevent context bloat.
|
|
818
|
+
// Without this, teammate context grows unbounded (same issue as subagent pre-fix).
|
|
819
|
+
const maxToolResultChars = resolvedTeammateConfig?.maxToolResultChars ?? AGENT_DEFAULTS.maxToolResultChars;
|
|
820
|
+
const {
|
|
821
|
+
messages: compactedMessages
|
|
822
|
+
} = preCompact(messages, {
|
|
823
|
+
maxToolResultChars,
|
|
824
|
+
stripThinking: true
|
|
825
|
+
});
|
|
826
|
+
messages = compactedMessages;
|
|
827
|
+
|
|
828
|
+
// If task was completed, break out to get next task
|
|
829
|
+
if (taskCompleted) {
|
|
830
|
+
currentTaskId = null;
|
|
831
|
+
await updateTeammate(teamId, teammateId, {
|
|
832
|
+
status: "idle",
|
|
833
|
+
currentTask: undefined
|
|
834
|
+
});
|
|
835
|
+
break;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
// If inner loop ended without the model calling team_complete_task (exhausted turns, API error, or model end_turn)
|
|
840
|
+
if (currentTaskId) {
|
|
841
|
+
const team = loadTeam(teamId);
|
|
842
|
+
const task = team?.tasks.find(t => t.id === currentTaskId);
|
|
843
|
+
if (task && task.status === "in_progress") {
|
|
844
|
+
if (apiError) {
|
|
845
|
+
// API failed — mark task as failed, not completed
|
|
846
|
+
await failTask(teamId, currentTaskId, apiError);
|
|
847
|
+
// Report as progress (not error) — error type causes red flash in UI via handleTeammateFailure double-handling
|
|
848
|
+
report({
|
|
849
|
+
type: "progress",
|
|
850
|
+
teammateId,
|
|
851
|
+
taskId: currentTaskId,
|
|
852
|
+
content: `Task failed: ${apiError.slice(0, 80)}`
|
|
853
|
+
});
|
|
854
|
+
} else if (totalIn === 0 && totalOut === 0) {
|
|
855
|
+
// Zero tokens used means no real work was done — fail the task
|
|
856
|
+
await failTask(teamId, currentTaskId, "No API response received (0 tokens)");
|
|
857
|
+
report({
|
|
858
|
+
type: "progress",
|
|
859
|
+
teammateId,
|
|
860
|
+
taskId: currentTaskId,
|
|
861
|
+
content: "Task failed: no API response"
|
|
862
|
+
});
|
|
863
|
+
} else {
|
|
864
|
+
// Model stopped (end_turn) or exhausted turns — auto-complete with result
|
|
865
|
+
const hitTurnLimit = lastTurn >= taskTurnLimit - 1;
|
|
866
|
+
const lastText = messages.length > 0 ? messages[messages.length - 1] : null;
|
|
867
|
+
let partialResult = hitTurnLimit ? `Task auto-completed after reaching turn limit (${taskTurnLimit} turns).` : "Task completed (model finished).";
|
|
868
|
+
if (lastText && typeof lastText === "object" && "content" in lastText) {
|
|
869
|
+
const content = lastText.content;
|
|
870
|
+
if (typeof content === "string") partialResult = content.slice(0, 500);else if (Array.isArray(content)) {
|
|
871
|
+
const txt = content.find(b => b.type === "text");
|
|
872
|
+
if (txt && "text" in txt) partialResult = txt.text.slice(0, 500);
|
|
614
873
|
}
|
|
615
|
-
|
|
616
|
-
|
|
874
|
+
}
|
|
875
|
+
await completeTask(teamId, currentTaskId, partialResult);
|
|
876
|
+
tasksCompleted++;
|
|
877
|
+
report({
|
|
878
|
+
type: "task_completed",
|
|
879
|
+
teammateId,
|
|
880
|
+
taskId: currentTaskId,
|
|
881
|
+
content: partialResult
|
|
882
|
+
});
|
|
617
883
|
}
|
|
884
|
+
}
|
|
885
|
+
currentTaskId = null;
|
|
886
|
+
await updateTeammate(teamId, teammateId, {
|
|
887
|
+
status: "idle",
|
|
888
|
+
currentTask: undefined
|
|
889
|
+
});
|
|
618
890
|
}
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
// Final update
|
|
894
|
+
await updateTeammate(teamId, teammateId, {
|
|
895
|
+
status: "done",
|
|
896
|
+
currentTask: undefined,
|
|
897
|
+
tokensUsed: {
|
|
898
|
+
input: totalIn,
|
|
899
|
+
output: totalOut
|
|
900
|
+
}
|
|
901
|
+
});
|
|
625
902
|
}
|
|
903
|
+
|
|
626
904
|
// ============================================================================
|
|
627
|
-
//
|
|
905
|
+
// CHILD PROCESS ENTRY POINT
|
|
628
906
|
// ============================================================================
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
907
|
+
|
|
908
|
+
// Detect if we were forked as a child process (process.send exists when IPC channel is open)
|
|
909
|
+
if (process.send && process.argv.includes("--teammate-child")) {
|
|
910
|
+
// Wait for startup data from parent via IPC
|
|
911
|
+
process.on("message", msg => {
|
|
912
|
+
if (msg?.type === "__teammate_start") {
|
|
913
|
+
const data = msg.data;
|
|
914
|
+
|
|
915
|
+
// Catch ALL errors including module-level and unhandled rejections
|
|
916
|
+
process.on("uncaughtException", err => {
|
|
633
917
|
try {
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
}
|
|
640
|
-
catch { /* last resort — nothing we can do */ }
|
|
918
|
+
process.send({
|
|
919
|
+
type: "error",
|
|
920
|
+
teammateId: data.teammateId,
|
|
921
|
+
content: `Uncaught exception: ${err.message || String(err)}`
|
|
922
|
+
});
|
|
923
|
+
} catch {/* last resort — nothing we can do */}
|
|
641
924
|
process.exit(1);
|
|
642
|
-
|
|
643
|
-
|
|
925
|
+
});
|
|
926
|
+
process.on("unhandledRejection", reason => {
|
|
644
927
|
try {
|
|
645
|
-
|
|
646
|
-
type: "error",
|
|
647
|
-
teammateId: data.teammateId,
|
|
648
|
-
content: `Unhandled rejection: ${reason instanceof Error ? reason.message : String(reason)}`,
|
|
649
|
-
});
|
|
650
|
-
}
|
|
651
|
-
catch { /* last resort */ }
|
|
652
|
-
});
|
|
653
|
-
runTeammateLoop(data)
|
|
654
|
-
.catch(err => {
|
|
655
|
-
parentPort.postMessage({
|
|
928
|
+
process.send({
|
|
656
929
|
type: "error",
|
|
657
930
|
teammateId: data.teammateId,
|
|
658
|
-
content:
|
|
931
|
+
content: `Unhandled rejection: ${reason instanceof Error ? reason.message : String(reason)}`
|
|
932
|
+
});
|
|
933
|
+
} catch {/* last resort */}
|
|
934
|
+
});
|
|
935
|
+
runTeammateLoop(data).catch(err => {
|
|
936
|
+
process.send({
|
|
937
|
+
type: "error",
|
|
938
|
+
teammateId: data.teammateId,
|
|
939
|
+
content: err.message || String(err)
|
|
659
940
|
});
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
//
|
|
664
|
-
//
|
|
665
|
-
setTimeout(() => process.exit(0),
|
|
666
|
-
|
|
941
|
+
}).finally(() => {
|
|
942
|
+
// Flush telemetry spans before exiting
|
|
943
|
+
flushCliSpans();
|
|
944
|
+
// Brief delay for final IPC messages and telemetry to flush,
|
|
945
|
+
// then exit cleanly. With process isolation, OS reclaims all resources.
|
|
946
|
+
setTimeout(() => process.exit(0), 300);
|
|
947
|
+
});
|
|
948
|
+
}
|
|
949
|
+
});
|
|
667
950
|
}
|
|
951
|
+
|
|
668
952
|
// ============================================================================
|
|
669
953
|
// SPAWN TEAMMATE (from main thread)
|
|
670
954
|
// ============================================================================
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
955
|
+
|
|
956
|
+
export async function spawnTeammate(teamId, teammateId, teammateName, model, cwd, parentConversationId, teamName, preloadedConfig, preloadedServerTools) {
|
|
957
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
958
|
+
|
|
959
|
+
// Get auth token to pass to child for telemetry
|
|
960
|
+
const authToken = await getValidToken();
|
|
961
|
+
|
|
962
|
+
// Fork a child process running this same file with --teammate-child flag
|
|
963
|
+
const child = fork(__filename, ["--teammate-child"], {
|
|
964
|
+
cwd,
|
|
965
|
+
stdio: ["pipe", "pipe", "pipe", "ipc"],
|
|
966
|
+
// Inherit parent's env so NODE_PATH, API keys etc. are available
|
|
967
|
+
env: {
|
|
968
|
+
...process.env
|
|
969
|
+
}
|
|
970
|
+
});
|
|
971
|
+
|
|
972
|
+
// Send startup data via IPC (replaces workerData)
|
|
973
|
+
// Pre-loaded config and tools avoid each child making redundant DB/API calls
|
|
974
|
+
child.send({
|
|
975
|
+
type: "__teammate_start",
|
|
976
|
+
data: {
|
|
977
|
+
teamId,
|
|
978
|
+
teammateId,
|
|
979
|
+
teammateName,
|
|
980
|
+
model,
|
|
981
|
+
cwd,
|
|
982
|
+
parentConversationId,
|
|
983
|
+
teamName,
|
|
984
|
+
authToken: authToken || undefined,
|
|
985
|
+
preloadedConfig: preloadedConfig ?? undefined,
|
|
986
|
+
preloadedServerTools: preloadedServerTools ?? undefined
|
|
987
|
+
}
|
|
988
|
+
});
|
|
989
|
+
return child;
|
|
689
990
|
}
|
|
991
|
+
//# sourceMappingURL=teammate.js.map
|