whale-code 6.5.5 → 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 +5 -1
- package/dist/cli/services/agent-config.js +66 -36
- 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 +976 -688
- 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.js +187 -169
- 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 +605 -433
- 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 +857 -569
- 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.js +1030 -895
- package/dist/server/handlers/api-docs.js.map +1 -0
- package/dist/server/handlers/api-keys.js +291 -242
- 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.js +1439 -984
- 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 -1039
- 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 +3167 -2422
- 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.js +952 -788
- 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 +4 -1
- package/dist/server/lib/server-agent-loop.js +906 -634
- package/dist/server/lib/server-agent-loop.js.map +1 -0
- package/dist/server/lib/server-subagent.js +260 -164
- 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 +250 -172
- package/dist/server/providers/anthropic.js.map +1 -0
- package/dist/server/providers/bedrock.js +217 -158
- 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.js +959 -599
- 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 +115 -26
- package/dist/shared/agent-core.js +956 -522
- 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 +16 -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 -0
- 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,49 +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, AGENT_DEFAULTS } 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";
|
|
14
16
|
import { loadCLIAgentConfig } from "./agent-config.js";
|
|
15
17
|
import { MODEL_MAP } from "../../shared/constants.js";
|
|
16
|
-
import { LOCAL_TOOL_DEFINITIONS
|
|
17
|
-
import { loadServerToolDefinitions
|
|
18
|
+
import { LOCAL_TOOL_DEFINITIONS } from "./local-tools.js";
|
|
19
|
+
import { loadServerToolDefinitions } from "./server-tools.js";
|
|
18
20
|
import { getValidToken } from "./auth-service.js";
|
|
19
|
-
import { logSpan, generateSpanId, generateTraceId, getConversationId, initializeTelemetryClient } from "./telemetry.js";
|
|
20
|
-
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
|
+
|
|
21
28
|
// ============================================================================
|
|
22
29
|
// CONSTANTS
|
|
23
30
|
// ============================================================================
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
let
|
|
27
|
-
let
|
|
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;
|
|
28
36
|
let TEAMMATE_MAX_DURATION_MS = AGENT_DEFAULTS.maxDurationMs;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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.
|
|
32
44
|
async function resolveTeammateConfig() {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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");
|
|
40
56
|
}
|
|
57
|
+
|
|
41
58
|
// ============================================================================
|
|
42
59
|
// TEAMMATE SYSTEM PROMPT
|
|
43
60
|
// ============================================================================
|
|
61
|
+
|
|
44
62
|
function buildTeammatePrompt(teammateName, team, currentTask, cwd) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const teammates = team.teammates.map(t => `- ${t.name} (${t.id}): ${t.status}${t.currentTask ? ` - working on task` : ""}`).join("\n");
|
|
52
|
-
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.
|
|
53
69
|
|
|
54
70
|
## Working Directory
|
|
55
71
|
${cwd}
|
|
@@ -83,13 +99,18 @@ You can delegate sub-tasks to specialized subagents using the 'task' tool:
|
|
|
83
99
|
- Use model="haiku" for simple lookups (cheapest/fastest)
|
|
84
100
|
- This lets you work on multiple things in parallel while staying focused on your main task
|
|
85
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
|
+
|
|
86
108
|
## Guidelines
|
|
87
|
-
1. Focus on YOUR assigned task
|
|
88
|
-
2. Communicate blockers or discoveries that affect other tasks
|
|
89
|
-
3.
|
|
90
|
-
4.
|
|
91
|
-
5.
|
|
92
|
-
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
|
|
93
114
|
|
|
94
115
|
## Self-Monitoring
|
|
95
116
|
If a tool fails, use audit_trail (action="errors") to check patterns before retrying.
|
|
@@ -99,605 +120,872 @@ If a tool fails repeatedly, try a different approach instead of retrying the sam
|
|
|
99
120
|
## Output
|
|
100
121
|
Be concise. Report progress and results clearly. Use tools to do the work.`;
|
|
101
122
|
}
|
|
123
|
+
|
|
102
124
|
// ============================================================================
|
|
103
125
|
// TEAM-SPECIFIC TOOLS
|
|
104
126
|
// ============================================================================
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
},
|
|
121
|
-
required: ["to", "message"],
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
name: "team_broadcast",
|
|
126
|
-
description: "Send a message to all teammates",
|
|
127
|
-
input_schema: {
|
|
128
|
-
type: "object",
|
|
129
|
-
properties: {
|
|
130
|
-
message: {
|
|
131
|
-
type: "string",
|
|
132
|
-
description: "Message to broadcast",
|
|
133
|
-
},
|
|
134
|
-
},
|
|
135
|
-
required: ["message"],
|
|
136
|
-
},
|
|
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
|
+
}
|
|
137
142
|
},
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
},
|
|
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
|
+
}
|
|
151
155
|
},
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
},
|
|
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
|
+
}
|
|
165
168
|
},
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
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
|
+
}
|
|
173
181
|
},
|
|
174
|
-
]
|
|
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
|
+
|
|
175
193
|
// ============================================================================
|
|
176
194
|
// TOOL EXECUTION
|
|
177
195
|
// ============================================================================
|
|
196
|
+
|
|
178
197
|
async function executeTeamTool(toolName, input, teamId, teammateId, currentTaskId) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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
|
+
};
|
|
194
243
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
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
|
+
};
|
|
201
262
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
return { success: true, output: "No unread messages" };
|
|
216
|
-
}
|
|
217
|
-
const msgList = messages.map(m => `From ${m.from}: ${m.content}`).join("\n");
|
|
218
|
-
await markMessagesRead(teamId, messages.map(m => m.id));
|
|
219
|
-
return { success: true, output: `${messages.length} messages:\n${msgList}` };
|
|
220
|
-
}
|
|
221
|
-
default:
|
|
222
|
-
return { success: false, output: `Unknown team tool: ${toolName}` };
|
|
223
|
-
}
|
|
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
|
+
}
|
|
224
276
|
}
|
|
277
|
+
|
|
225
278
|
// ============================================================================
|
|
226
279
|
// API CLIENT — uses shared callAgentAPI from agent-worker-base
|
|
227
280
|
// ============================================================================
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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
|
+
});
|
|
239
294
|
}
|
|
295
|
+
|
|
240
296
|
// ============================================================================
|
|
241
297
|
// TEAMMATE WORKER LOOP
|
|
242
298
|
// ============================================================================
|
|
299
|
+
|
|
243
300
|
async function runTeammateLoop(data) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
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 {
|
|
248
333
|
await resolveTeammateConfig();
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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"
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
const report = msg => {
|
|
373
|
+
if (process.send) {
|
|
374
|
+
process.send(msg);
|
|
252
375
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
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);
|
|
260
420
|
logSpan({
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
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: {
|
|
264
600
|
traceId: teammateTraceId,
|
|
265
|
-
spanId:
|
|
601
|
+
spanId: generateSpanId(),
|
|
602
|
+
parentSpanId: teammateSpanId,
|
|
266
603
|
conversationId: teammateConversationId,
|
|
267
604
|
source: "claude_code",
|
|
268
605
|
serviceName: "whale-cli",
|
|
269
|
-
serviceVersion:
|
|
270
|
-
model:
|
|
271
|
-
|
|
272
|
-
|
|
606
|
+
serviceVersion: PKG_VERSION,
|
|
607
|
+
model: currentTaskModelId
|
|
608
|
+
},
|
|
609
|
+
details: {
|
|
273
610
|
is_team: true,
|
|
274
611
|
is_teammate: true,
|
|
275
612
|
team_id: teamId,
|
|
276
613
|
teammate_id: teammateId,
|
|
277
614
|
teammate_name: teammateName,
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
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
|
|
284
647
|
},
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
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
|
|
289
664
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
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: {
|
|
324
740
|
traceId: teammateTraceId,
|
|
325
741
|
spanId: generateSpanId(),
|
|
326
742
|
parentSpanId: teammateSpanId,
|
|
327
743
|
conversationId: teammateConversationId,
|
|
328
744
|
source: "claude_code",
|
|
329
745
|
serviceName: "whale-cli",
|
|
330
|
-
serviceVersion:
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
outputTokens: totalOut,
|
|
334
|
-
totalCost: teammateCost,
|
|
335
|
-
},
|
|
336
|
-
details: {
|
|
746
|
+
serviceVersion: PKG_VERSION
|
|
747
|
+
},
|
|
748
|
+
details: {
|
|
337
749
|
is_team: true,
|
|
338
750
|
is_teammate: true,
|
|
339
751
|
team_id: teamId,
|
|
340
752
|
teammate_id: teammateId,
|
|
341
753
|
teammate_name: teammateName,
|
|
342
|
-
team_name: teamName,
|
|
343
754
|
parent_conversation_id: parentConversationId,
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
"
|
|
347
|
-
"
|
|
348
|
-
"
|
|
349
|
-
|
|
350
|
-
display_name: `${teammateName} done`,
|
|
351
|
-
display_icon: "checkmark.circle.fill",
|
|
352
|
-
display_color: "#10B981",
|
|
353
|
-
},
|
|
354
|
-
});
|
|
355
|
-
};
|
|
356
|
-
// Main work loop - keep working until no more tasks
|
|
357
|
-
let outerTurn = 0;
|
|
358
|
-
while (true) {
|
|
359
|
-
// Safety: max turns guard
|
|
360
|
-
if (++outerTurn > TEAMMATE_MAX_TOTAL_TURNS) {
|
|
361
|
-
logTeammateComplete("max_turns_reached");
|
|
362
|
-
report({ type: "done", teammateId, content: `${teammateName} reached max turns (${TEAMMATE_MAX_TOTAL_TURNS})`, tokensUsed: { input: totalIn, output: totalOut } });
|
|
363
|
-
break;
|
|
364
|
-
}
|
|
365
|
-
// Safety: elapsed time guard
|
|
366
|
-
if (Date.now() - startTime > TEAMMATE_MAX_DURATION_MS) {
|
|
367
|
-
logTeammateComplete("timeout");
|
|
368
|
-
report({ type: "done", teammateId, content: `${teammateName} timed out after ${Math.round(TEAMMATE_MAX_DURATION_MS / 60_000)}min`, tokensUsed: { input: totalIn, output: totalOut } });
|
|
369
|
-
break;
|
|
370
|
-
}
|
|
371
|
-
const team = loadTeam(teamId);
|
|
372
|
-
if (!team || team.status !== "active") {
|
|
373
|
-
logTeammateComplete("team_inactive");
|
|
374
|
-
report({ type: "done", teammateId, content: "Team completed or inactive", tokensUsed: { input: totalIn, output: totalOut } });
|
|
375
|
-
break;
|
|
376
|
-
}
|
|
377
|
-
// Find current task or claim a new one
|
|
378
|
-
const currentTask = currentTaskId
|
|
379
|
-
? team.tasks.find(t => t.id === currentTaskId)
|
|
380
|
-
: null;
|
|
381
|
-
// If no current task, try to claim one
|
|
382
|
-
if (!currentTask || currentTask.status === "completed") {
|
|
383
|
-
const available = getAvailableTasks(team);
|
|
384
|
-
if (available.length === 0) {
|
|
385
|
-
// No tasks available, check if all done or waiting
|
|
386
|
-
const inProgress = team.tasks.filter(t => t.status === "in_progress").length;
|
|
387
|
-
if (inProgress === 0) {
|
|
388
|
-
logTeammateComplete("all_tasks_done");
|
|
389
|
-
report({ type: "done", teammateId, content: "All tasks completed", tokensUsed: { input: totalIn, output: totalOut } });
|
|
390
|
-
break;
|
|
391
|
-
}
|
|
392
|
-
// Wait and retry
|
|
393
|
-
await new Promise(r => setTimeout(r, 2000));
|
|
394
|
-
continue;
|
|
395
|
-
}
|
|
396
|
-
// Claim first available task
|
|
397
|
-
const claimed = await claimTask(teamId, available[0].id, teammateId);
|
|
398
|
-
if (!claimed) {
|
|
399
|
-
await new Promise(r => setTimeout(r, 1000));
|
|
400
|
-
continue;
|
|
401
|
-
}
|
|
402
|
-
currentTaskId = claimed.id;
|
|
403
|
-
// Resolve per-task model: task-level → team default
|
|
404
|
-
const taskModel = claimed.model || model;
|
|
405
|
-
currentTaskModelId = MODEL_MAP[taskModel] || MODEL_MAP[model] || MODEL_MAP.opus;
|
|
406
|
-
// Disable thinking for teammates — with TEAMMATE_MAX_OUTPUT_TOKENS=16K, adaptive thinking
|
|
407
|
-
// burns 8-12K tokens on reasoning per turn, leaving only 4-8K for actual code output.
|
|
408
|
-
// This caused catastrophic token bloat (359K input tokens per task) and truncated responses.
|
|
409
|
-
currentTaskThinking = false;
|
|
410
|
-
await updateTeammate(teamId, teammateId, { status: "working", currentTask: currentTaskId });
|
|
411
|
-
report({ type: "task_started", teammateId, taskId: currentTaskId, content: claimed.description });
|
|
412
|
-
// Start fresh conversation for new task
|
|
413
|
-
messages = [{
|
|
414
|
-
role: "user",
|
|
415
|
-
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.`,
|
|
416
|
-
}];
|
|
417
|
-
}
|
|
418
|
-
// Build system prompt with current state
|
|
419
|
-
const freshTeam = loadTeam(teamId);
|
|
420
|
-
const freshTask = freshTeam.tasks.find(t => t.id === currentTaskId) || null;
|
|
421
|
-
const systemPrompt = buildTeammatePrompt(teammateName, freshTeam, freshTask, cwd);
|
|
422
|
-
// Agent loop for current task
|
|
423
|
-
let apiError = null;
|
|
424
|
-
for (let turn = 0; turn < TEAMMATE_MAX_TURNS_PER_TASK; turn++) {
|
|
425
|
-
const apiStart = Date.now();
|
|
426
|
-
let response;
|
|
427
|
-
try {
|
|
428
|
-
response = await callAPI(currentTaskModelId, systemPrompt, messages, allTools, currentTaskThinking);
|
|
429
|
-
}
|
|
430
|
-
catch (err) {
|
|
431
|
-
apiError = err.message || String(err);
|
|
432
|
-
report({ type: "progress", teammateId, content: `API error: ${apiError.slice(0, 80)}` });
|
|
433
|
-
logSpan({
|
|
434
|
-
action: "claude_api_request",
|
|
435
|
-
durationMs: Date.now() - apiStart,
|
|
436
|
-
severity: "error",
|
|
437
|
-
error: apiError || undefined,
|
|
438
|
-
context: {
|
|
439
|
-
traceId: teammateTraceId,
|
|
440
|
-
spanId: generateSpanId(),
|
|
441
|
-
parentSpanId: teammateSpanId,
|
|
442
|
-
conversationId: teammateConversationId,
|
|
443
|
-
source: "claude_code",
|
|
444
|
-
serviceName: "whale-cli",
|
|
445
|
-
serviceVersion: "2.1.0",
|
|
446
|
-
model: currentTaskModelId,
|
|
447
|
-
},
|
|
448
|
-
details: {
|
|
449
|
-
is_team: true,
|
|
450
|
-
is_teammate: true,
|
|
451
|
-
team_id: teamId,
|
|
452
|
-
teammate_id: teammateId,
|
|
453
|
-
teammate_name: teammateName,
|
|
454
|
-
parent_conversation_id: parentConversationId,
|
|
455
|
-
turn_number: turn + 1,
|
|
456
|
-
task_id: currentTaskId,
|
|
457
|
-
},
|
|
458
|
-
});
|
|
459
|
-
break; // Exit inner loop — force-complete handler below will deal with the task
|
|
460
|
-
}
|
|
461
|
-
const apiDuration = Date.now() - apiStart;
|
|
462
|
-
totalIn += response.usage.input_tokens;
|
|
463
|
-
totalOut += response.usage.output_tokens;
|
|
464
|
-
// Log Claude API request telemetry
|
|
465
|
-
const turnCostUsd = estimateCostUsd(response.usage.input_tokens, response.usage.output_tokens, currentTaskModelId);
|
|
466
|
-
logSpan({
|
|
467
|
-
action: "claude_api_request",
|
|
468
|
-
durationMs: apiDuration,
|
|
469
|
-
context: {
|
|
470
|
-
traceId: teammateTraceId,
|
|
471
|
-
spanId: generateSpanId(),
|
|
472
|
-
parentSpanId: teammateSpanId,
|
|
473
|
-
conversationId: teammateConversationId,
|
|
474
|
-
source: "claude_code",
|
|
475
|
-
serviceName: "whale-cli",
|
|
476
|
-
serviceVersion: "2.1.0",
|
|
477
|
-
model: currentTaskModelId,
|
|
478
|
-
inputTokens: response.usage.input_tokens,
|
|
479
|
-
outputTokens: response.usage.output_tokens,
|
|
480
|
-
totalCost: turnCostUsd,
|
|
481
|
-
},
|
|
482
|
-
details: {
|
|
483
|
-
is_team: true,
|
|
484
|
-
is_teammate: true,
|
|
485
|
-
team_id: teamId,
|
|
486
|
-
teammate_id: teammateId,
|
|
487
|
-
teammate_name: teammateName,
|
|
488
|
-
parent_conversation_id: parentConversationId,
|
|
489
|
-
turn_number: turn + 1,
|
|
490
|
-
task_id: currentTaskId,
|
|
491
|
-
stop_reason: response.stop_reason,
|
|
492
|
-
"gen_ai.request.model": currentTaskModelId,
|
|
493
|
-
"gen_ai.usage.input_tokens": response.usage.input_tokens,
|
|
494
|
-
"gen_ai.usage.output_tokens": response.usage.output_tokens,
|
|
495
|
-
"gen_ai.usage.cost": turnCostUsd,
|
|
496
|
-
},
|
|
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
|
+
}
|
|
497
761
|
});
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
//
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
loopDetector,
|
|
512
|
-
toolTimeoutMs: TOOL_TIMEOUT_MS,
|
|
513
|
-
customExecutor: async (toolName, input) => {
|
|
514
|
-
// Only handle team tools; return null to fall through to standard routing
|
|
515
|
-
if (!TEAM_TOOLS.some(t => t.name === toolName))
|
|
516
|
-
return null;
|
|
517
|
-
const result = await executeTeamTool(toolName, input, teamId, teammateId, currentTaskId);
|
|
518
|
-
// Check if task was completed
|
|
519
|
-
if (toolName === "team_complete_task" && result.success) {
|
|
520
|
-
taskCompleted = true;
|
|
521
|
-
tasksCompleted++;
|
|
522
|
-
report({ type: "task_completed", teammateId, taskId: currentTaskId || undefined, content: result.output });
|
|
523
|
-
// Log task completion to telemetry
|
|
524
|
-
logSpan({
|
|
525
|
-
action: "team.task_complete",
|
|
526
|
-
durationMs: 0,
|
|
527
|
-
context: {
|
|
528
|
-
traceId: teammateTraceId,
|
|
529
|
-
spanId: generateSpanId(),
|
|
530
|
-
parentSpanId: teammateSpanId,
|
|
531
|
-
conversationId: teammateConversationId,
|
|
532
|
-
source: "claude_code",
|
|
533
|
-
serviceName: "whale-cli",
|
|
534
|
-
serviceVersion: "2.1.0",
|
|
535
|
-
},
|
|
536
|
-
details: {
|
|
537
|
-
is_team: true,
|
|
538
|
-
is_teammate: true,
|
|
539
|
-
team_id: teamId,
|
|
540
|
-
teammate_id: teammateId,
|
|
541
|
-
teammate_name: teammateName,
|
|
542
|
-
parent_conversation_id: parentConversationId,
|
|
543
|
-
task_id: currentTaskId,
|
|
544
|
-
task_result: result.output.slice(0, 500),
|
|
545
|
-
display_name: "Task completed",
|
|
546
|
-
display_icon: "checkmark.square.fill",
|
|
547
|
-
display_color: "#10B981",
|
|
548
|
-
},
|
|
549
|
-
});
|
|
550
|
-
}
|
|
551
|
-
return result;
|
|
552
|
-
},
|
|
553
|
-
callbacks: {
|
|
554
|
-
onToolEnd: (toolName, success, durationMs) => {
|
|
555
|
-
// Determine tool category for telemetry
|
|
556
|
-
const toolCategory = TEAM_TOOLS.some(t => t.name === toolName) ? "team" : "standard";
|
|
557
|
-
logSpan({
|
|
558
|
-
action: `tool.${toolName}`,
|
|
559
|
-
durationMs,
|
|
560
|
-
severity: success ? "info" : "error",
|
|
561
|
-
context: {
|
|
562
|
-
traceId: teammateTraceId,
|
|
563
|
-
spanId: generateSpanId(),
|
|
564
|
-
parentSpanId: teammateSpanId,
|
|
565
|
-
conversationId: teammateConversationId,
|
|
566
|
-
source: "claude_code",
|
|
567
|
-
serviceName: "whale-cli",
|
|
568
|
-
serviceVersion: "2.1.0",
|
|
569
|
-
},
|
|
570
|
-
error: success ? undefined : "(see tool result)",
|
|
571
|
-
details: {
|
|
572
|
-
is_team: true,
|
|
573
|
-
is_teammate: true,
|
|
574
|
-
team_id: teamId,
|
|
575
|
-
teammate_id: teammateId,
|
|
576
|
-
teammate_name: teammateName,
|
|
577
|
-
parent_conversation_id: parentConversationId,
|
|
578
|
-
tool_category: toolCategory,
|
|
579
|
-
},
|
|
580
|
-
});
|
|
581
|
-
},
|
|
582
|
-
},
|
|
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)`
|
|
583
775
|
});
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
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
|
+
}
|
|
593
804
|
}
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
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);
|
|
628
873
|
}
|
|
629
|
-
|
|
630
|
-
|
|
874
|
+
}
|
|
875
|
+
await completeTask(teamId, currentTaskId, partialResult);
|
|
876
|
+
tasksCompleted++;
|
|
877
|
+
report({
|
|
878
|
+
type: "task_completed",
|
|
879
|
+
teammateId,
|
|
880
|
+
taskId: currentTaskId,
|
|
881
|
+
content: partialResult
|
|
882
|
+
});
|
|
631
883
|
}
|
|
884
|
+
}
|
|
885
|
+
currentTaskId = null;
|
|
886
|
+
await updateTeammate(teamId, teammateId, {
|
|
887
|
+
status: "idle",
|
|
888
|
+
currentTask: undefined
|
|
889
|
+
});
|
|
632
890
|
}
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
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
|
+
});
|
|
639
902
|
}
|
|
903
|
+
|
|
640
904
|
// ============================================================================
|
|
641
|
-
//
|
|
905
|
+
// CHILD PROCESS ENTRY POINT
|
|
642
906
|
// ============================================================================
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
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 => {
|
|
647
917
|
try {
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
}
|
|
654
|
-
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 */}
|
|
655
924
|
process.exit(1);
|
|
656
|
-
|
|
657
|
-
|
|
925
|
+
});
|
|
926
|
+
process.on("unhandledRejection", reason => {
|
|
658
927
|
try {
|
|
659
|
-
|
|
660
|
-
type: "error",
|
|
661
|
-
teammateId: data.teammateId,
|
|
662
|
-
content: `Unhandled rejection: ${reason instanceof Error ? reason.message : String(reason)}`,
|
|
663
|
-
});
|
|
664
|
-
}
|
|
665
|
-
catch { /* last resort */ }
|
|
666
|
-
});
|
|
667
|
-
runTeammateLoop(data)
|
|
668
|
-
.catch(err => {
|
|
669
|
-
parentPort.postMessage({
|
|
928
|
+
process.send({
|
|
670
929
|
type: "error",
|
|
671
930
|
teammateId: data.teammateId,
|
|
672
|
-
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)
|
|
673
940
|
});
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
//
|
|
678
|
-
//
|
|
679
|
-
setTimeout(() => process.exit(0),
|
|
680
|
-
|
|
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
|
+
});
|
|
681
950
|
}
|
|
951
|
+
|
|
682
952
|
// ============================================================================
|
|
683
953
|
// SPAWN TEAMMATE (from main thread)
|
|
684
954
|
// ============================================================================
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
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;
|
|
703
990
|
}
|
|
991
|
+
//# sourceMappingURL=teammate.js.map
|