@cjhyy/code-shell-core 0.5.0-rc.0
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/LICENSE +21 -0
- package/README.md +162 -0
- package/dist/agent/coordinator.d.ts +49 -0
- package/dist/agent/coordinator.js +77 -0
- package/dist/arena/arena.d.ts +43 -0
- package/dist/arena/arena.js +334 -0
- package/dist/arena/context/context-tools.d.ts +16 -0
- package/dist/arena/context/context-tools.js +231 -0
- package/dist/arena/detect-mode.d.ts +20 -0
- package/dist/arena/detect-mode.js +78 -0
- package/dist/arena/digest-builder.d.ts +25 -0
- package/dist/arena/digest-builder.js +120 -0
- package/dist/arena/index.d.ts +29 -0
- package/dist/arena/index.js +29 -0
- package/dist/arena/iterate/convergence.d.ts +25 -0
- package/dist/arena/iterate/convergence.js +103 -0
- package/dist/arena/iterate/formats/index.d.ts +22 -0
- package/dist/arena/iterate/formats/index.js +283 -0
- package/dist/arena/iterate/index.d.ts +11 -0
- package/dist/arena/iterate/index.js +9 -0
- package/dist/arena/iterate/iterative-arena.d.ts +23 -0
- package/dist/arena/iterate/iterative-arena.js +237 -0
- package/dist/arena/iterate/parse.d.ts +42 -0
- package/dist/arena/iterate/parse.js +123 -0
- package/dist/arena/iterate/phases/argue.d.ts +22 -0
- package/dist/arena/iterate/phases/argue.js +159 -0
- package/dist/arena/iterate/phases/revise.d.ts +16 -0
- package/dist/arena/iterate/phases/revise.js +62 -0
- package/dist/arena/iterate/phases/tournament.d.ts +34 -0
- package/dist/arena/iterate/phases/tournament.js +113 -0
- package/dist/arena/iterate/tools/web-tools.d.ts +13 -0
- package/dist/arena/iterate/tools/web-tools.js +54 -0
- package/dist/arena/iterate/types.d.ts +152 -0
- package/dist/arena/iterate/types.js +8 -0
- package/dist/arena/ledger.d.ts +47 -0
- package/dist/arena/ledger.js +151 -0
- package/dist/arena/lenses/architecture.d.ts +5 -0
- package/dist/arena/lenses/architecture.js +22 -0
- package/dist/arena/lenses/engineering.d.ts +5 -0
- package/dist/arena/lenses/engineering.js +22 -0
- package/dist/arena/lenses/general.d.ts +5 -0
- package/dist/arena/lenses/general.js +20 -0
- package/dist/arena/lenses/index.d.ts +16 -0
- package/dist/arena/lenses/index.js +47 -0
- package/dist/arena/lenses/product.d.ts +5 -0
- package/dist/arena/lenses/product.js +22 -0
- package/dist/arena/model-presets.d.ts +23 -0
- package/dist/arena/model-presets.js +44 -0
- package/dist/arena/phases/adjudication.d.ts +24 -0
- package/dist/arena/phases/adjudication.js +144 -0
- package/dist/arena/phases/build-consensus.d.ts +29 -0
- package/dist/arena/phases/build-consensus.js +86 -0
- package/dist/arena/phases/claim-registry.d.ts +26 -0
- package/dist/arena/phases/claim-registry.js +60 -0
- package/dist/arena/phases/cross-review.d.ts +45 -0
- package/dist/arena/phases/cross-review.js +224 -0
- package/dist/arena/phases/debate-rounds.d.ts +27 -0
- package/dist/arena/phases/debate-rounds.js +162 -0
- package/dist/arena/phases/participant-research.d.ts +38 -0
- package/dist/arena/phases/participant-research.js +317 -0
- package/dist/arena/phases/planning-detail-expansion.d.ts +38 -0
- package/dist/arena/phases/planning-detail-expansion.js +121 -0
- package/dist/arena/planner.d.ts +27 -0
- package/dist/arena/planner.js +312 -0
- package/dist/arena/providers/docs.d.ts +6 -0
- package/dist/arena/providers/docs.js +108 -0
- package/dist/arena/providers/git.d.ts +8 -0
- package/dist/arena/providers/git.js +174 -0
- package/dist/arena/providers/index.d.ts +32 -0
- package/dist/arena/providers/index.js +132 -0
- package/dist/arena/providers/none.d.ts +7 -0
- package/dist/arena/providers/none.js +11 -0
- package/dist/arena/providers/repo.d.ts +6 -0
- package/dist/arena/providers/repo.js +255 -0
- package/dist/arena/render/session.d.ts +17 -0
- package/dist/arena/render/session.js +190 -0
- package/dist/arena/render/terminal.d.ts +34 -0
- package/dist/arena/render/terminal.js +286 -0
- package/dist/arena/strategies/discussion.d.ts +25 -0
- package/dist/arena/strategies/discussion.js +143 -0
- package/dist/arena/strategies/index.d.ts +15 -0
- package/dist/arena/strategies/index.js +28 -0
- package/dist/arena/strategies/language-wrapper.d.ts +17 -0
- package/dist/arena/strategies/language-wrapper.js +102 -0
- package/dist/arena/strategies/lens-wrapper.d.ts +16 -0
- package/dist/arena/strategies/lens-wrapper.js +236 -0
- package/dist/arena/strategies/planning.d.ts +30 -0
- package/dist/arena/strategies/planning.js +225 -0
- package/dist/arena/strategies/review.d.ts +26 -0
- package/dist/arena/strategies/review.js +168 -0
- package/dist/arena/strategies/utils.d.ts +39 -0
- package/dist/arena/strategies/utils.js +647 -0
- package/dist/arena/tools/selector.d.ts +17 -0
- package/dist/arena/tools/selector.js +61 -0
- package/dist/arena/transitions.d.ts +48 -0
- package/dist/arena/transitions.js +92 -0
- package/dist/arena/types.d.ts +508 -0
- package/dist/arena/types.js +27 -0
- package/dist/cli/agent-server-stdio.d.ts +32 -0
- package/dist/cli/agent-server-stdio.js +116 -0
- package/dist/colorizer.d.ts +23 -0
- package/dist/colorizer.js +12 -0
- package/dist/context/compaction.d.ts +116 -0
- package/dist/context/compaction.js +534 -0
- package/dist/context/manager.d.ts +145 -0
- package/dist/context/manager.js +423 -0
- package/dist/context/token-counter.d.ts +27 -0
- package/dist/context/token-counter.js +91 -0
- package/dist/context/tool-result-storage.d.ts +96 -0
- package/dist/context/tool-result-storage.js +296 -0
- package/dist/cost-tracker.d.ts +64 -0
- package/dist/cost-tracker.js +314 -0
- package/dist/cron/scheduler.d.ts +34 -0
- package/dist/cron/scheduler.js +115 -0
- package/dist/data/deepseek-models.json +46 -0
- package/dist/data/gemini-models.json +67 -0
- package/dist/data/openai-models.json +175 -0
- package/dist/data/openrouter-models.d.ts +35 -0
- package/dist/data/openrouter-models.js +36 -0
- package/dist/data/openrouter-models.json +4626 -0
- package/dist/data/openrouter-sync.d.ts +16 -0
- package/dist/data/openrouter-sync.js +53 -0
- package/dist/data/static-catalogs.d.ts +25 -0
- package/dist/data/static-catalogs.js +26 -0
- package/dist/data/zai-models.json +56 -0
- package/dist/engine/cost-store.d.ts +22 -0
- package/dist/engine/cost-store.js +15 -0
- package/dist/engine/engine.d.ts +295 -0
- package/dist/engine/engine.js +1467 -0
- package/dist/engine/model-facade.d.ts +24 -0
- package/dist/engine/model-facade.js +194 -0
- package/dist/engine/parse-task.d.ts +59 -0
- package/dist/engine/parse-task.js +135 -0
- package/dist/engine/patch-orphaned-tools.d.ts +52 -0
- package/dist/engine/patch-orphaned-tools.js +95 -0
- package/dist/engine/query.d.ts +50 -0
- package/dist/engine/query.js +107 -0
- package/dist/engine/runtime.d.ts +50 -0
- package/dist/engine/runtime.js +59 -0
- package/dist/engine/streaming-tool-queue.d.ts +34 -0
- package/dist/engine/streaming-tool-queue.js +61 -0
- package/dist/engine/token-budget.d.ts +22 -0
- package/dist/engine/token-budget.js +40 -0
- package/dist/engine/tool-summary.d.ts +13 -0
- package/dist/engine/tool-summary.js +35 -0
- package/dist/engine/turn-loop.d.ts +122 -0
- package/dist/engine/turn-loop.js +602 -0
- package/dist/engine/turn-state.d.ts +20 -0
- package/dist/engine/turn-state.js +17 -0
- package/dist/exceptions.d.ts +61 -0
- package/dist/exceptions.js +116 -0
- package/dist/git/utils.d.ts +35 -0
- package/dist/git/utils.js +98 -0
- package/dist/git/worktree.d.ts +36 -0
- package/dist/git/worktree.js +139 -0
- package/dist/hooks/events.d.ts +114 -0
- package/dist/hooks/events.js +4 -0
- package/dist/hooks/inject.d.ts +19 -0
- package/dist/hooks/inject.js +29 -0
- package/dist/hooks/registry.d.ts +15 -0
- package/dist/hooks/registry.js +84 -0
- package/dist/hooks/shell-runner.d.ts +45 -0
- package/dist/hooks/shell-runner.js +173 -0
- package/dist/index.d.ts +117 -0
- package/dist/index.js +145 -0
- package/dist/llm/api-key-sanitize.d.ts +22 -0
- package/dist/llm/api-key-sanitize.js +81 -0
- package/dist/llm/capabilities/index.d.ts +20 -0
- package/dist/llm/capabilities/index.js +39 -0
- package/dist/llm/capabilities/rules.d.ts +26 -0
- package/dist/llm/capabilities/rules.js +215 -0
- package/dist/llm/capabilities/types.d.ts +114 -0
- package/dist/llm/capabilities/types.js +24 -0
- package/dist/llm/client-base.d.ts +29 -0
- package/dist/llm/client-base.js +137 -0
- package/dist/llm/client-factory.d.ts +10 -0
- package/dist/llm/client-factory.js +29 -0
- package/dist/llm/model-cache.d.ts +21 -0
- package/dist/llm/model-cache.js +46 -0
- package/dist/llm/model-fetcher.d.ts +29 -0
- package/dist/llm/model-fetcher.js +282 -0
- package/dist/llm/model-pool.d.ts +95 -0
- package/dist/llm/model-pool.js +246 -0
- package/dist/llm/provider-catalog.d.ts +32 -0
- package/dist/llm/provider-catalog.js +50 -0
- package/dist/llm/provider-kinds.d.ts +21 -0
- package/dist/llm/provider-kinds.js +132 -0
- package/dist/llm/providers/anthropic.d.ts +19 -0
- package/dist/llm/providers/anthropic.js +267 -0
- package/dist/llm/providers/openai.d.ts +64 -0
- package/dist/llm/providers/openai.js +606 -0
- package/dist/llm/retry.d.ts +12 -0
- package/dist/llm/retry.js +17 -0
- package/dist/llm/stream-watchdog.d.ts +42 -0
- package/dist/llm/stream-watchdog.js +70 -0
- package/dist/llm/token-counter.d.ts +17 -0
- package/dist/llm/token-counter.js +36 -0
- package/dist/llm/types.d.ts +37 -0
- package/dist/llm/types.js +4 -0
- package/dist/logging/logger.d.ts +109 -0
- package/dist/logging/logger.js +390 -0
- package/dist/logging/sanitize-messages.d.ts +42 -0
- package/dist/logging/sanitize-messages.js +150 -0
- package/dist/logging/session-recorder.d.ts +90 -0
- package/dist/logging/session-recorder.js +304 -0
- package/dist/lsp/client.d.ts +41 -0
- package/dist/lsp/client.js +166 -0
- package/dist/lsp/manager.d.ts +40 -0
- package/dist/lsp/manager.js +124 -0
- package/dist/lsp/servers.d.ts +16 -0
- package/dist/lsp/servers.js +60 -0
- package/dist/migrate-models.d.ts +45 -0
- package/dist/migrate-models.js +179 -0
- package/dist/onboarding.d.ts +189 -0
- package/dist/onboarding.js +625 -0
- package/dist/plugins/gitOps.d.ts +32 -0
- package/dist/plugins/gitOps.js +62 -0
- package/dist/plugins/installedPlugins.d.ts +15 -0
- package/dist/plugins/installedPlugins.js +56 -0
- package/dist/plugins/knownMarketplaces.d.ts +10 -0
- package/dist/plugins/knownMarketplaces.js +46 -0
- package/dist/plugins/loadPluginHooks.d.ts +52 -0
- package/dist/plugins/loadPluginHooks.js +162 -0
- package/dist/plugins/marketplaceManager.d.ts +49 -0
- package/dist/plugins/marketplaceManager.js +142 -0
- package/dist/plugins/parseMarketplaceInput.d.ts +16 -0
- package/dist/plugins/parseMarketplaceInput.js +73 -0
- package/dist/plugins/pluginCommandHook.d.ts +54 -0
- package/dist/plugins/pluginCommandHook.js +180 -0
- package/dist/plugins/pluginCommandsLoader.d.ts +25 -0
- package/dist/plugins/pluginCommandsLoader.js +114 -0
- package/dist/plugins/pluginInstaller.d.ts +36 -0
- package/dist/plugins/pluginInstaller.js +228 -0
- package/dist/plugins/schemas.d.ts +9 -0
- package/dist/plugins/schemas.js +136 -0
- package/dist/plugins/types.d.ts +75 -0
- package/dist/plugins/types.js +7 -0
- package/dist/plugins/varRewrite.d.ts +42 -0
- package/dist/plugins/varRewrite.js +129 -0
- package/dist/preset/index.d.ts +60 -0
- package/dist/preset/index.js +159 -0
- package/dist/product/define.d.ts +60 -0
- package/dist/product/define.js +123 -0
- package/dist/product/index.d.ts +5 -0
- package/dist/product/index.js +4 -0
- package/dist/product/types.d.ts +111 -0
- package/dist/product/types.js +21 -0
- package/dist/prompt/composer.d.ts +49 -0
- package/dist/prompt/composer.js +168 -0
- package/dist/prompt/instruction-scanner.d.ts +54 -0
- package/dist/prompt/instruction-scanner.js +187 -0
- package/dist/prompt/section-cache.d.ts +15 -0
- package/dist/prompt/section-cache.js +31 -0
- package/dist/prompt/section-loader.d.ts +26 -0
- package/dist/prompt/section-loader.js +53 -0
- package/dist/prompt/sections/base.md +35 -0
- package/dist/prompt/sections/coding.md +31 -0
- package/dist/prompt/sections/orchestration.md +16 -0
- package/dist/prompt/sections/tone.md +9 -0
- package/dist/protocol/chat-session-manager.d.ts +33 -0
- package/dist/protocol/chat-session-manager.js +65 -0
- package/dist/protocol/chat-session.d.ts +49 -0
- package/dist/protocol/chat-session.js +86 -0
- package/dist/protocol/client.d.ts +104 -0
- package/dist/protocol/client.js +260 -0
- package/dist/protocol/factories.d.ts +93 -0
- package/dist/protocol/factories.js +64 -0
- package/dist/protocol/helpers.d.ts +42 -0
- package/dist/protocol/helpers.js +55 -0
- package/dist/protocol/index.d.ts +4 -0
- package/dist/protocol/index.js +4 -0
- package/dist/protocol/server.d.ts +80 -0
- package/dist/protocol/server.js +855 -0
- package/dist/protocol/transport.d.ts +37 -0
- package/dist/protocol/transport.js +85 -0
- package/dist/protocol/types.d.ts +221 -0
- package/dist/protocol/types.js +61 -0
- package/dist/remote/bridge.d.ts +37 -0
- package/dist/remote/bridge.js +103 -0
- package/dist/run/ArtifactTracker.d.ts +38 -0
- package/dist/run/ArtifactTracker.js +132 -0
- package/dist/run/CheckpointWriter.d.ts +53 -0
- package/dist/run/CheckpointWriter.js +135 -0
- package/dist/run/EngineRunner.d.ts +72 -0
- package/dist/run/EngineRunner.js +119 -0
- package/dist/run/Evaluator.d.ts +56 -0
- package/dist/run/Evaluator.js +62 -0
- package/dist/run/FileRunStore.d.ts +39 -0
- package/dist/run/FileRunStore.js +176 -0
- package/dist/run/Heartbeat.d.ts +54 -0
- package/dist/run/Heartbeat.js +123 -0
- package/dist/run/RunApprovalBackend.d.ts +53 -0
- package/dist/run/RunApprovalBackend.js +85 -0
- package/dist/run/RunLock.d.ts +40 -0
- package/dist/run/RunLock.js +98 -0
- package/dist/run/RunManager.d.ts +82 -0
- package/dist/run/RunManager.js +587 -0
- package/dist/run/RunQueue.d.ts +27 -0
- package/dist/run/RunQueue.js +73 -0
- package/dist/run/RunStore.d.ts +25 -0
- package/dist/run/RunStore.js +9 -0
- package/dist/run/factory.d.ts +63 -0
- package/dist/run/factory.js +51 -0
- package/dist/run/index.d.ts +17 -0
- package/dist/run/index.js +23 -0
- package/dist/run/types.d.ts +136 -0
- package/dist/run/types.js +28 -0
- package/dist/runtime/safe-spawn.d.ts +118 -0
- package/dist/runtime/safe-spawn.js +268 -0
- package/dist/services/analytics.d.ts +29 -0
- package/dist/services/analytics.js +84 -0
- package/dist/services/auto-dream.d.ts +49 -0
- package/dist/services/auto-dream.js +124 -0
- package/dist/services/diagnostics.d.ts +41 -0
- package/dist/services/diagnostics.js +99 -0
- package/dist/services/extract-memories.d.ts +31 -0
- package/dist/services/extract-memories.js +71 -0
- package/dist/services/index.d.ts +11 -0
- package/dist/services/index.js +17 -0
- package/dist/services/memory-orchestrator.d.ts +60 -0
- package/dist/services/memory-orchestrator.js +133 -0
- package/dist/services/notifier.d.ts +25 -0
- package/dist/services/notifier.js +69 -0
- package/dist/services/oauth.d.ts +27 -0
- package/dist/services/oauth.js +153 -0
- package/dist/services/session-memory.d.ts +37 -0
- package/dist/services/session-memory.js +81 -0
- package/dist/session/file-history.d.ts +41 -0
- package/dist/session/file-history.js +115 -0
- package/dist/session/memory.d.ts +104 -0
- package/dist/session/memory.js +310 -0
- package/dist/session/session-manager.d.ts +41 -0
- package/dist/session/session-manager.js +261 -0
- package/dist/session/transcript.d.ts +39 -0
- package/dist/session/transcript.js +186 -0
- package/dist/settings/manager.d.ts +36 -0
- package/dist/settings/manager.js +187 -0
- package/dist/settings/schema.d.ts +1219 -0
- package/dist/settings/schema.js +246 -0
- package/dist/skills/frontmatter.d.ts +13 -0
- package/dist/skills/frontmatter.js +70 -0
- package/dist/skills/index.d.ts +7 -0
- package/dist/skills/index.js +6 -0
- package/dist/skills/scanner.d.ts +31 -0
- package/dist/skills/scanner.js +171 -0
- package/dist/state.d.ts +160 -0
- package/dist/state.js +267 -0
- package/dist/tool-system/builtin/agent-notifications.d.ts +84 -0
- package/dist/tool-system/builtin/agent-notifications.js +197 -0
- package/dist/tool-system/builtin/agent-registry.d.ts +67 -0
- package/dist/tool-system/builtin/agent-registry.js +126 -0
- package/dist/tool-system/builtin/agent-transcript-translator.d.ts +22 -0
- package/dist/tool-system/builtin/agent-transcript-translator.js +160 -0
- package/dist/tool-system/builtin/agent.d.ts +16 -0
- package/dist/tool-system/builtin/agent.js +364 -0
- package/dist/tool-system/builtin/apply-patch/applier.d.ts +26 -0
- package/dist/tool-system/builtin/apply-patch/applier.js +250 -0
- package/dist/tool-system/builtin/apply-patch/index.d.ts +20 -0
- package/dist/tool-system/builtin/apply-patch/index.js +101 -0
- package/dist/tool-system/builtin/apply-patch/parser.d.ts +17 -0
- package/dist/tool-system/builtin/apply-patch/parser.js +212 -0
- package/dist/tool-system/builtin/apply-patch/seek-sequence.d.ts +18 -0
- package/dist/tool-system/builtin/apply-patch/seek-sequence.js +123 -0
- package/dist/tool-system/builtin/apply-patch/types.d.ts +49 -0
- package/dist/tool-system/builtin/apply-patch/types.js +13 -0
- package/dist/tool-system/builtin/arena.d.ts +31 -0
- package/dist/tool-system/builtin/arena.js +416 -0
- package/dist/tool-system/builtin/ask-user.d.ts +20 -0
- package/dist/tool-system/builtin/ask-user.js +99 -0
- package/dist/tool-system/builtin/bash.d.ts +21 -0
- package/dist/tool-system/builtin/bash.js +149 -0
- package/dist/tool-system/builtin/brief.d.ts +6 -0
- package/dist/tool-system/builtin/brief.js +41 -0
- package/dist/tool-system/builtin/config.d.ts +6 -0
- package/dist/tool-system/builtin/config.js +67 -0
- package/dist/tool-system/builtin/cron.d.ts +10 -0
- package/dist/tool-system/builtin/cron.js +61 -0
- package/dist/tool-system/builtin/edit.d.ts +6 -0
- package/dist/tool-system/builtin/edit.js +100 -0
- package/dist/tool-system/builtin/file-cache.d.ts +11 -0
- package/dist/tool-system/builtin/file-cache.js +39 -0
- package/dist/tool-system/builtin/glob.d.ts +7 -0
- package/dist/tool-system/builtin/glob.js +76 -0
- package/dist/tool-system/builtin/grep.d.ts +7 -0
- package/dist/tool-system/builtin/grep.js +150 -0
- package/dist/tool-system/builtin/index.d.ts +20 -0
- package/dist/tool-system/builtin/index.js +449 -0
- package/dist/tool-system/builtin/lsp.d.ts +6 -0
- package/dist/tool-system/builtin/lsp.js +141 -0
- package/dist/tool-system/builtin/mcp-tools.d.ts +10 -0
- package/dist/tool-system/builtin/mcp-tools.js +102 -0
- package/dist/tool-system/builtin/memory.d.ts +26 -0
- package/dist/tool-system/builtin/memory.js +226 -0
- package/dist/tool-system/builtin/notebook-edit.d.ts +6 -0
- package/dist/tool-system/builtin/notebook-edit.js +124 -0
- package/dist/tool-system/builtin/plan.d.ts +15 -0
- package/dist/tool-system/builtin/plan.js +55 -0
- package/dist/tool-system/builtin/powershell.d.ts +11 -0
- package/dist/tool-system/builtin/powershell.js +64 -0
- package/dist/tool-system/builtin/read.d.ts +6 -0
- package/dist/tool-system/builtin/read.js +70 -0
- package/dist/tool-system/builtin/remote-trigger.d.ts +6 -0
- package/dist/tool-system/builtin/remote-trigger.js +54 -0
- package/dist/tool-system/builtin/repl.d.ts +11 -0
- package/dist/tool-system/builtin/repl.js +82 -0
- package/dist/tool-system/builtin/send-message.d.ts +6 -0
- package/dist/tool-system/builtin/send-message.js +47 -0
- package/dist/tool-system/builtin/skill-prompt.d.ts +20 -0
- package/dist/tool-system/builtin/skill-prompt.js +52 -0
- package/dist/tool-system/builtin/skill.d.ts +9 -0
- package/dist/tool-system/builtin/skill.js +55 -0
- package/dist/tool-system/builtin/sleep.d.ts +6 -0
- package/dist/tool-system/builtin/sleep.js +33 -0
- package/dist/tool-system/builtin/task.d.ts +48 -0
- package/dist/tool-system/builtin/task.js +139 -0
- package/dist/tool-system/builtin/tool-search.d.ts +11 -0
- package/dist/tool-system/builtin/tool-search.js +90 -0
- package/dist/tool-system/builtin/web-fetch.d.ts +10 -0
- package/dist/tool-system/builtin/web-fetch.js +328 -0
- package/dist/tool-system/builtin/web-search.d.ts +25 -0
- package/dist/tool-system/builtin/web-search.js +174 -0
- package/dist/tool-system/builtin/worktree.d.ts +10 -0
- package/dist/tool-system/builtin/worktree.js +95 -0
- package/dist/tool-system/builtin/write.d.ts +6 -0
- package/dist/tool-system/builtin/write.js +36 -0
- package/dist/tool-system/context.d.ts +165 -0
- package/dist/tool-system/context.js +18 -0
- package/dist/tool-system/executor.d.ts +49 -0
- package/dist/tool-system/executor.js +495 -0
- package/dist/tool-system/investigation-guard.d.ts +46 -0
- package/dist/tool-system/investigation-guard.js +155 -0
- package/dist/tool-system/mcp-manager.d.ts +67 -0
- package/dist/tool-system/mcp-manager.js +249 -0
- package/dist/tool-system/permission.d.ts +111 -0
- package/dist/tool-system/permission.js +774 -0
- package/dist/tool-system/registry.d.ts +32 -0
- package/dist/tool-system/registry.js +131 -0
- package/dist/tool-system/sandbox/bwrap.d.ts +13 -0
- package/dist/tool-system/sandbox/bwrap.js +63 -0
- package/dist/tool-system/sandbox/index.d.ts +78 -0
- package/dist/tool-system/sandbox/index.js +222 -0
- package/dist/tool-system/sandbox/off.d.ts +2 -0
- package/dist/tool-system/sandbox/off.js +8 -0
- package/dist/tool-system/sandbox/seatbelt.d.ts +18 -0
- package/dist/tool-system/sandbox/seatbelt.js +109 -0
- package/dist/tool-system/task-guard.d.ts +29 -0
- package/dist/tool-system/task-guard.js +70 -0
- package/dist/tool-system/validation.d.ts +5 -0
- package/dist/tool-system/validation.js +39 -0
- package/dist/types.d.ts +376 -0
- package/dist/types.js +4 -0
- package/dist/updater.d.ts +65 -0
- package/dist/updater.js +405 -0
- package/dist/utils/debug.d.ts +41 -0
- package/dist/utils/debug.js +110 -0
- package/dist/utils/earlyInput.d.ts +43 -0
- package/dist/utils/earlyInput.js +166 -0
- package/dist/utils/env.d.ts +24 -0
- package/dist/utils/env.js +104 -0
- package/dist/utils/envUtils.d.ts +51 -0
- package/dist/utils/envUtils.js +135 -0
- package/dist/utils/execFileNoThrow.d.ts +39 -0
- package/dist/utils/execFileNoThrow.js +74 -0
- package/dist/utils/format.d.ts +44 -0
- package/dist/utils/format.js +236 -0
- package/dist/utils/intl.d.ts +22 -0
- package/dist/utils/intl.js +83 -0
- package/dist/utils/lockfile.d.ts +15 -0
- package/dist/utils/lockfile.js +30 -0
- package/dist/utils/memoize.d.ts +19 -0
- package/dist/utils/memoize.js +14 -0
- package/dist/utils/semver.d.ts +6 -0
- package/dist/utils/semver.js +13 -0
- package/dist/utils/sliceAnsi.d.ts +12 -0
- package/dist/utils/sliceAnsi.js +62 -0
- package/dist/utils/systemTheme.d.ts +40 -0
- package/dist/utils/systemTheme.js +108 -0
- package/dist/utils/task-sanitizer.d.ts +6 -0
- package/dist/utils/task-sanitizer.js +24 -0
- package/dist/utils/theme.d.ts +93 -0
- package/dist/utils/theme.js +544 -0
- package/dist/utils/toolDisplay.d.ts +31 -0
- package/dist/utils/toolDisplay.js +188 -0
- package/package.json +72 -0
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in Arena tool — multi-model collaborative analysis.
|
|
3
|
+
*
|
|
4
|
+
* Launches an arena session where multiple LLM participants independently
|
|
5
|
+
* research a topic, cross-review each other's findings, and build consensus.
|
|
6
|
+
*
|
|
7
|
+
* The LLM config (baseUrl, apiKey) is injected at runtime by the Engine via
|
|
8
|
+
* setArenaLLMConfig(), following the same pattern as setAskUserFn() and
|
|
9
|
+
* setSubAgentConfig().
|
|
10
|
+
*/
|
|
11
|
+
import { Arena, MODEL_PRESETS, getMaxOutputTokens } from "../../arena/index.js";
|
|
12
|
+
import { createProgressRenderer } from "../../arena/render/terminal.js";
|
|
13
|
+
import { formatArenaResultForSession } from "../../arena/render/session.js";
|
|
14
|
+
import { SettingsManager } from "../../settings/manager.js";
|
|
15
|
+
export const arenaToolDef = {
|
|
16
|
+
name: "Arena",
|
|
17
|
+
description: "Launch a multi-model collaborative analysis session. " +
|
|
18
|
+
"Arena automatically detects the mode, analysis perspective (lens), and evidence sources from the user's natural language request. " +
|
|
19
|
+
"Supports: code review, PRD/document review, architecture planning, product discussions, open-ended debates, and more. " +
|
|
20
|
+
"Multiple LLM participants independently research the topic, cross-review findings, and produce structured consensus. " +
|
|
21
|
+
"Use model preset names (e.g. 'claude', 'gpt', 'gemini', 'deepseek') or full model paths.",
|
|
22
|
+
inputSchema: {
|
|
23
|
+
type: "object",
|
|
24
|
+
properties: {
|
|
25
|
+
topic: {
|
|
26
|
+
type: "string",
|
|
27
|
+
description: "The topic or question to analyze in natural language. Arena auto-detects mode/lens/sources. " +
|
|
28
|
+
"Examples: 'review my latest changes', 'review 这个 PRD 是否完整', '讨论 arena 的产品定位', " +
|
|
29
|
+
"'规划通用化重构方案', 'discuss whether we should productize arena'",
|
|
30
|
+
},
|
|
31
|
+
mode: {
|
|
32
|
+
type: "string",
|
|
33
|
+
enum: ["review", "discussion", "planning"],
|
|
34
|
+
description: "Arena mode override. Usually auto-detected from topic. 'review' for structured review, 'discussion' for open analysis, 'planning' for roadmaps.",
|
|
35
|
+
},
|
|
36
|
+
participants: {
|
|
37
|
+
type: "array",
|
|
38
|
+
items: { type: "string" },
|
|
39
|
+
description: "Model preset names or full model paths for participants (min 2). " +
|
|
40
|
+
"Preset names: " + Object.keys(MODEL_PRESETS).join(", ") + ". " +
|
|
41
|
+
"Default: ['claude', 'gpt'] if omitted.",
|
|
42
|
+
},
|
|
43
|
+
concluder: {
|
|
44
|
+
type: "string",
|
|
45
|
+
description: "Which participant builds the final consensus (by name). Default: first participant.",
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
required: ["topic"],
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
// ─── Runtime LLM config — read from ctx, not module singletons ──
|
|
52
|
+
/**
|
|
53
|
+
* Snapshot of last-known Arena config, kept for the protocol-level
|
|
54
|
+
* /arena-status query. The query is not tied to an in-flight tool
|
|
55
|
+
* invocation, so it can't read ctx; instead, ctx-bearing tool calls
|
|
56
|
+
* publish their config here for the status endpoint to read back.
|
|
57
|
+
*
|
|
58
|
+
* This is a read-only cache used purely for diagnostics — Arena's
|
|
59
|
+
* actual execution path always reads from the per-call ctx.
|
|
60
|
+
*/
|
|
61
|
+
let _lastSeenLLMConfig;
|
|
62
|
+
let _lastSeenModelPool;
|
|
63
|
+
export function getArenaStatus() {
|
|
64
|
+
const baseUrl = _lastSeenLLMConfig?.baseUrl;
|
|
65
|
+
const entries = _lastSeenModelPool?.list() ?? [];
|
|
66
|
+
const fromSettings = readSettingsParticipants();
|
|
67
|
+
// Mirror arenaTool's resolution: settings is authoritative when
|
|
68
|
+
// present; otherwise fall back to the pool-derived preview so users
|
|
69
|
+
// can still see *something* in /arena-status before they configure.
|
|
70
|
+
const defaults = fromSettings.length >= 2 ? fromSettings : resolveDefaultParticipantNames(entries);
|
|
71
|
+
const probed = defaults.map((name) => {
|
|
72
|
+
const r = probeParticipant(name, entries, _lastSeenLLMConfig);
|
|
73
|
+
return {
|
|
74
|
+
name,
|
|
75
|
+
model: r.modelPath,
|
|
76
|
+
source: r.source,
|
|
77
|
+
compatible: r.compatible,
|
|
78
|
+
...(r.reason ? { reason: r.reason } : {}),
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
return {
|
|
82
|
+
endpoint: baseUrl,
|
|
83
|
+
defaultParticipants: probed,
|
|
84
|
+
poolSize: entries.length,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Resolve a preset name or model path into an ArenaParticipant,
|
|
89
|
+
* inheriting baseUrl/apiKey from the engine's LLM config.
|
|
90
|
+
*/
|
|
91
|
+
/**
|
|
92
|
+
* Arena uses a lower temperature than the default conversation model
|
|
93
|
+
* to produce more deterministic, evidence-grounded analysis.
|
|
94
|
+
*/
|
|
95
|
+
const ARENA_TEMPERATURE = 0.3;
|
|
96
|
+
/**
|
|
97
|
+
* Resolution priority:
|
|
98
|
+
* 1. ModelPool key (the user's own configured models — uses each
|
|
99
|
+
* entry's own baseUrl/apiKey, so e.g. a "claude" pool entry
|
|
100
|
+
* pointing at OpenRouter still works while the active session
|
|
101
|
+
* runs on DeepSeek direct).
|
|
102
|
+
* 2. MODEL_PRESETS — only if the active endpoint can accept the
|
|
103
|
+
* preset's model namespace; otherwise we throw rather than
|
|
104
|
+
* silently miswire credentials.
|
|
105
|
+
* 3. Raw model path against the active endpoint.
|
|
106
|
+
*/
|
|
107
|
+
function resolveParticipant(nameOrPath, llmConfig, pool) {
|
|
108
|
+
const fallbackBaseUrl = llmConfig.baseUrl;
|
|
109
|
+
const fallbackApiKey = llmConfig.apiKey;
|
|
110
|
+
// (1) ModelPool entry — preferred path
|
|
111
|
+
const poolEntry = pool?.get(nameOrPath);
|
|
112
|
+
if (poolEntry)
|
|
113
|
+
return participantFromPool(poolEntry, llmConfig);
|
|
114
|
+
// (2) Built-in preset
|
|
115
|
+
const preset = MODEL_PRESETS[nameOrPath];
|
|
116
|
+
if (preset) {
|
|
117
|
+
assertEndpointAcceptsModel(fallbackBaseUrl, preset.model, nameOrPath);
|
|
118
|
+
return {
|
|
119
|
+
name: nameOrPath,
|
|
120
|
+
llm: {
|
|
121
|
+
provider: preset.provider,
|
|
122
|
+
model: preset.model,
|
|
123
|
+
maxTokens: preset.maxOutputTokens,
|
|
124
|
+
baseUrl: fallbackBaseUrl,
|
|
125
|
+
apiKey: fallbackApiKey,
|
|
126
|
+
temperature: ARENA_TEMPERATURE,
|
|
127
|
+
enableStreaming: false,
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
// (3) Raw model path
|
|
132
|
+
assertEndpointAcceptsModel(fallbackBaseUrl, nameOrPath, nameOrPath);
|
|
133
|
+
return {
|
|
134
|
+
name: nameOrPath.split("/").pop() ?? nameOrPath,
|
|
135
|
+
llm: {
|
|
136
|
+
provider: "openai",
|
|
137
|
+
model: nameOrPath,
|
|
138
|
+
maxTokens: getMaxOutputTokens(nameOrPath),
|
|
139
|
+
baseUrl: fallbackBaseUrl,
|
|
140
|
+
apiKey: fallbackApiKey,
|
|
141
|
+
temperature: ARENA_TEMPERATURE,
|
|
142
|
+
enableStreaming: false,
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function participantFromPool(entry, llmConfig) {
|
|
147
|
+
// Pool entries carry their own baseUrl/apiKey — never paper over
|
|
148
|
+
// them with the active session's credentials, which is exactly the
|
|
149
|
+
// bug that caused 401/400s when Arena ran on a DeepSeek-only
|
|
150
|
+
// session but the pool had OpenRouter-keyed entries.
|
|
151
|
+
return {
|
|
152
|
+
name: entry.key,
|
|
153
|
+
llm: {
|
|
154
|
+
provider: entry.provider,
|
|
155
|
+
model: entry.model,
|
|
156
|
+
maxTokens: entry.maxOutputTokens ?? getMaxOutputTokens(entry.model),
|
|
157
|
+
baseUrl: entry.baseUrl ?? llmConfig.baseUrl,
|
|
158
|
+
apiKey: entry.apiKey ?? llmConfig.apiKey,
|
|
159
|
+
temperature: ARENA_TEMPERATURE,
|
|
160
|
+
enableStreaming: false,
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Non-throwing variant of resolveParticipant used by /arena status —
|
|
166
|
+
* we want to *display* what would happen, not bail.
|
|
167
|
+
*/
|
|
168
|
+
function probeParticipant(nameOrPath, poolEntries, llmConfig) {
|
|
169
|
+
const fromPool = poolEntries.find((e) => e.key === nameOrPath);
|
|
170
|
+
if (fromPool) {
|
|
171
|
+
return { modelPath: fromPool.model, source: "pool", compatible: true };
|
|
172
|
+
}
|
|
173
|
+
const preset = MODEL_PRESETS[nameOrPath];
|
|
174
|
+
const modelPath = preset?.model ?? nameOrPath;
|
|
175
|
+
const source = preset ? "preset" : "raw";
|
|
176
|
+
const baseUrl = llmConfig?.baseUrl;
|
|
177
|
+
const endpointVendor = baseUrl ? inferEndpointVendor(baseUrl) : null;
|
|
178
|
+
const modelVendor = modelPath.includes("/") ? modelPath.split("/")[0].toLowerCase() : null;
|
|
179
|
+
if (endpointVendor && modelVendor && modelVendor !== endpointVendor) {
|
|
180
|
+
return {
|
|
181
|
+
modelPath,
|
|
182
|
+
source,
|
|
183
|
+
compatible: false,
|
|
184
|
+
reason: `endpoint serves "${endpointVendor}" only`,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
return { modelPath, source, compatible: true };
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Quick, non-throwing predicate: would `nameOrPath` resolve to a
|
|
191
|
+
* working participant on the current endpoint? Used to decide whether
|
|
192
|
+
* the model's chosen `participants` list is honorable, or whether we
|
|
193
|
+
* should silently swap in the pool defaults (single-vendor endpoint
|
|
194
|
+
* with cross-vendor preset names is the common bad case).
|
|
195
|
+
*/
|
|
196
|
+
function participantWouldResolve(nameOrPath, poolEntries, baseUrl) {
|
|
197
|
+
return probeParticipant(nameOrPath, poolEntries, baseUrl ? { baseUrl } : undefined).compatible;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Read the user's configured arena participants from settings.json.
|
|
201
|
+
* Returns the list of string-form pool keys (the most common shape).
|
|
202
|
+
* Object-form entries (full name/model/provider tuples) are currently
|
|
203
|
+
* only honored by the CLI entry point and are skipped here.
|
|
204
|
+
*
|
|
205
|
+
* Returns an empty array if no settings file exists or the field is empty.
|
|
206
|
+
*/
|
|
207
|
+
function readSettingsParticipants(cwd) {
|
|
208
|
+
// A4: prefer Engine cwd when caller provides one; fall back to host
|
|
209
|
+
// process cwd for non-tool callers like getArenaStatus().
|
|
210
|
+
try {
|
|
211
|
+
const settings = new SettingsManager(cwd ?? process.cwd()).get();
|
|
212
|
+
const raw = settings.arena?.participants ?? [];
|
|
213
|
+
return raw.filter((p) => typeof p === "string");
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
return [];
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* If the user didn't explicitly pass `participants`, default to every
|
|
221
|
+
* pool entry. With <2 entries, fall back to pre-existing behavior so
|
|
222
|
+
* we don't regress installs that haven't filled out the pool yet.
|
|
223
|
+
*
|
|
224
|
+
* NOTE: this is now only used by getArenaStatus() for the diagnostic
|
|
225
|
+
* /arena-status preview. The actual execution path in arenaTool() reads
|
|
226
|
+
* from settings (readSettingsParticipants) and refuses to silently
|
|
227
|
+
* grab the whole pool — we hit a bug where the pool included a
|
|
228
|
+
* gemini-3.1-pro entry that the active endpoint couldn't serve, and
|
|
229
|
+
* the user's curated settings.arena.participants list was bypassed.
|
|
230
|
+
*/
|
|
231
|
+
function resolveDefaultParticipantNames(poolEntries) {
|
|
232
|
+
if (poolEntries.length >= 2) {
|
|
233
|
+
return poolEntries.map((e) => e.key);
|
|
234
|
+
}
|
|
235
|
+
if (poolEntries.length === 1) {
|
|
236
|
+
// Single-model pool: use it twice — Arena requires ≥2. Same model
|
|
237
|
+
// running twice still gives a useful self-review pass.
|
|
238
|
+
const onlyKey = poolEntries[0].key;
|
|
239
|
+
return [onlyKey, onlyKey];
|
|
240
|
+
}
|
|
241
|
+
// Empty pool: legacy fallback. The endpoint check downstream will
|
|
242
|
+
// turn an obviously-wrong combo (e.g. claude preset on DeepSeek
|
|
243
|
+
// direct) into a fast, descriptive error.
|
|
244
|
+
return ["claude", "gpt"];
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Arena presets use OpenRouter-style namespaced model paths
|
|
248
|
+
* (`anthropic/claude-opus-4.6`, `openai/gpt-5.4`, etc.). Those only
|
|
249
|
+
* resolve correctly on a multi-provider gateway like OpenRouter — a
|
|
250
|
+
* vendor's direct endpoint will reject any model name that isn't its
|
|
251
|
+
* own and we'd burn tens of seconds on retries before the user sees
|
|
252
|
+
* a useful error. Fail fast instead, naming the conflict.
|
|
253
|
+
*/
|
|
254
|
+
function assertEndpointAcceptsModel(baseUrl, modelPath, participantLabel) {
|
|
255
|
+
if (!baseUrl)
|
|
256
|
+
return;
|
|
257
|
+
const endpointVendor = inferEndpointVendor(baseUrl);
|
|
258
|
+
if (!endpointVendor)
|
|
259
|
+
return; // unknown gateway — assume permissive (e.g. OpenRouter, custom)
|
|
260
|
+
const modelVendor = modelPath.includes("/") ? modelPath.split("/")[0].toLowerCase() : null;
|
|
261
|
+
// Direct endpoint, no vendor prefix → caller must have used the
|
|
262
|
+
// exact model name the endpoint expects. Trust it.
|
|
263
|
+
if (modelVendor === null)
|
|
264
|
+
return;
|
|
265
|
+
if (modelVendor !== endpointVendor) {
|
|
266
|
+
throw new Error(`Arena participant "${participantLabel}" maps to model "${modelPath}", ` +
|
|
267
|
+
`but the active endpoint (${baseUrl}) only serves "${endpointVendor}" models. ` +
|
|
268
|
+
`Either switch to an aggregator endpoint (e.g. OpenRouter) or pick participants ` +
|
|
269
|
+
`whose models are native to this provider (e.g. "deepseek-v4-pro").`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
function inferEndpointVendor(baseUrl) {
|
|
273
|
+
const u = baseUrl.toLowerCase();
|
|
274
|
+
if (u.includes("api.deepseek.com"))
|
|
275
|
+
return "deepseek";
|
|
276
|
+
if (u.includes("api.openai.com"))
|
|
277
|
+
return "openai";
|
|
278
|
+
if (u.includes("api.anthropic.com"))
|
|
279
|
+
return "anthropic";
|
|
280
|
+
if (u.includes("generativelanguage.googleapis.com"))
|
|
281
|
+
return "google";
|
|
282
|
+
// OpenRouter, Together, custom proxies, etc. — assume multi-vendor.
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
function formatStartupBanner(participants, llmConfig, source) {
|
|
286
|
+
const endpoint = llmConfig.baseUrl ?? "(none)";
|
|
287
|
+
const lines = [];
|
|
288
|
+
lines.push(`Arena: endpoint=${endpoint}`);
|
|
289
|
+
const sourceTag = source === "explicit-coerced-to-settings"
|
|
290
|
+
? "settings (auto-corrected from incompatible user picks)"
|
|
291
|
+
: source === "explicit"
|
|
292
|
+
? "user-specified"
|
|
293
|
+
: "settings";
|
|
294
|
+
lines.push(`Arena: participants=${participants.join(", ")} (${sourceTag})`);
|
|
295
|
+
return lines.join("\n");
|
|
296
|
+
}
|
|
297
|
+
/** Strip ANSI escape codes from chalk-styled text */
|
|
298
|
+
function stripAnsi(text) {
|
|
299
|
+
// eslint-disable-next-line no-control-regex
|
|
300
|
+
return text.replace(/\x1b\[[0-9;]*m/g, "");
|
|
301
|
+
}
|
|
302
|
+
export async function arenaTool(args, ctx) {
|
|
303
|
+
const topic = args.topic;
|
|
304
|
+
if (!topic)
|
|
305
|
+
return "Error: topic is required";
|
|
306
|
+
const signal = args.__signal;
|
|
307
|
+
if (signal?.aborted)
|
|
308
|
+
return "Arena aborted before starting.";
|
|
309
|
+
if (!ctx?.llmConfig) {
|
|
310
|
+
return "Error: Arena LLM config not initialized. This is a bug — the engine should inject it via ToolContext.";
|
|
311
|
+
}
|
|
312
|
+
const llmConfig = ctx.llmConfig;
|
|
313
|
+
const pool = ctx.modelPool;
|
|
314
|
+
// Update the diagnostic snapshot used by /arena-status
|
|
315
|
+
_lastSeenLLMConfig = llmConfig;
|
|
316
|
+
_lastSeenModelPool = pool;
|
|
317
|
+
const explicitParticipants = args.participants;
|
|
318
|
+
const poolEntries = pool?.list() ?? [];
|
|
319
|
+
// Participant resolution order:
|
|
320
|
+
// 1. Explicit `participants` arg from the tool call — honored only
|
|
321
|
+
// when every entry resolves on the current endpoint; otherwise
|
|
322
|
+
// we coerce to settings (preferred) or pool defaults.
|
|
323
|
+
// 2. settings.arena.participants — the user's curated list. This
|
|
324
|
+
// is the authoritative config; we never silently grab the whole
|
|
325
|
+
// pool, because the pool can contain models that the active
|
|
326
|
+
// endpoint can't serve (e.g. gemini-3.1-pro on Google direct).
|
|
327
|
+
// 3. No settings configured → return an actionable error pointing
|
|
328
|
+
// the user at where to configure it. Previously we silently
|
|
329
|
+
// defaulted to the entire pool, which caused 404/400 storms
|
|
330
|
+
// when pool entries didn't match the active endpoint.
|
|
331
|
+
let participantNames;
|
|
332
|
+
let participantSource;
|
|
333
|
+
if (explicitParticipants && explicitParticipants.length > 0) {
|
|
334
|
+
const allCompatible = explicitParticipants.every((name) => participantWouldResolve(name, poolEntries, llmConfig.baseUrl));
|
|
335
|
+
if (allCompatible) {
|
|
336
|
+
participantNames = explicitParticipants;
|
|
337
|
+
participantSource = "explicit";
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
const fromSettings = readSettingsParticipants(ctx?.cwd);
|
|
341
|
+
if (fromSettings.length >= 2) {
|
|
342
|
+
participantNames = fromSettings;
|
|
343
|
+
participantSource = "explicit-coerced-to-settings";
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
return ("Error: Arena participants from the call are incompatible with the active endpoint, " +
|
|
347
|
+
`and no fallback is configured. Set "arena.participants" (≥2 model names) in ` +
|
|
348
|
+
"~/.code-shell/settings.json, or pass a compatible `participants` array.");
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
const fromSettings = readSettingsParticipants(ctx?.cwd);
|
|
354
|
+
if (fromSettings.length >= 2) {
|
|
355
|
+
participantNames = fromSettings;
|
|
356
|
+
participantSource = "settings";
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
return ("Error: Arena requires at least 2 participants but none are configured. " +
|
|
360
|
+
`Add an "arena": { "participants": ["model-a", "model-b", ...] } block to ` +
|
|
361
|
+
"~/.code-shell/settings.json (each entry is a model pool key, e.g. " +
|
|
362
|
+
'"deepseek-v4-pro", "openrouter-claude-opus-4.7-fast"), or pass an explicit ' +
|
|
363
|
+
"`participants` array in the tool call.");
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
if (participantNames.length < 2) {
|
|
367
|
+
return "Error: Arena requires at least 2 participants. Provide 2 or more model names.";
|
|
368
|
+
}
|
|
369
|
+
const mode = args.mode;
|
|
370
|
+
const concluder = args.concluder;
|
|
371
|
+
// Collect progress for inclusion in the final tool result.
|
|
372
|
+
// Strip ANSI codes from progress since tool results are plain text/markdown.
|
|
373
|
+
const progressLog = [];
|
|
374
|
+
const progressRenderer = createProgressRenderer((text) => {
|
|
375
|
+
progressLog.push(stripAnsi(text));
|
|
376
|
+
});
|
|
377
|
+
// Surface the resolved configuration up front so the user can see
|
|
378
|
+
// exactly which models will be polled and against which endpoint —
|
|
379
|
+
// previously this was invisible until something blew up.
|
|
380
|
+
const configLine = formatStartupBanner(participantNames, llmConfig, participantSource);
|
|
381
|
+
progressLog.push(configLine);
|
|
382
|
+
try {
|
|
383
|
+
// resolveParticipant() may throw on endpoint/model mismatch — keep
|
|
384
|
+
// it inside the try so the error returns as a tool-result string
|
|
385
|
+
// rather than crashing the engine.
|
|
386
|
+
const participants = participantNames.map((n) => resolveParticipant(n, llmConfig, pool));
|
|
387
|
+
const arena = new Arena({
|
|
388
|
+
participants,
|
|
389
|
+
mode,
|
|
390
|
+
concluder,
|
|
391
|
+
enableContextTools: true,
|
|
392
|
+
onProgress: progressRenderer,
|
|
393
|
+
signal,
|
|
394
|
+
});
|
|
395
|
+
const result = await arena.run(topic);
|
|
396
|
+
// Use session renderer (markdown, no ANSI) for tool results.
|
|
397
|
+
// Terminal renderer (chalk) is only for direct stdout printing.
|
|
398
|
+
const formattedResult = formatArenaResultForSession(result);
|
|
399
|
+
// Prepend a condensed progress summary so the LLM can see what was done
|
|
400
|
+
const progressSummary = progressLog.length > 0
|
|
401
|
+
? "── Arena Progress ──\n" + progressLog.join("\n") + "\n\n"
|
|
402
|
+
: "";
|
|
403
|
+
// Cap total output to prevent context overflow
|
|
404
|
+
const MAX_TOOL_OUTPUT = 30_000;
|
|
405
|
+
const full = progressSummary + formattedResult;
|
|
406
|
+
if (full.length > MAX_TOOL_OUTPUT) {
|
|
407
|
+
return full.slice(0, MAX_TOOL_OUTPUT) + "\n\n... (truncated, total " + full.length + " chars)";
|
|
408
|
+
}
|
|
409
|
+
return full;
|
|
410
|
+
}
|
|
411
|
+
catch (err) {
|
|
412
|
+
if (signal?.aborted)
|
|
413
|
+
return "Arena aborted.";
|
|
414
|
+
return `Arena error: ${err.message}`;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in AskUserQuestion tool — ask the user a question during execution.
|
|
3
|
+
*
|
|
4
|
+
* Two modes:
|
|
5
|
+
* - Plain text (no `options`): user types a free-text answer.
|
|
6
|
+
* - Multiple choice (`options` provided): user picks from a list. An
|
|
7
|
+
* implicit "Other..." entry is appended by the UI for free text.
|
|
8
|
+
*
|
|
9
|
+
* The actual prompt-the-user implementation is provided per-Engine via
|
|
10
|
+
* ToolContext.askUser. Headless mode (no UI wired up) leaves askUser
|
|
11
|
+
* undefined and the tool reports back asking the LLM to assume.
|
|
12
|
+
*/
|
|
13
|
+
import type { ToolDefinition } from "../../types.js";
|
|
14
|
+
import type { ToolContext } from "../context.js";
|
|
15
|
+
export type { AskUserFn, AskUserOptions, AskUserChoice } from "../context.js";
|
|
16
|
+
export declare const askUserToolDef: ToolDefinition;
|
|
17
|
+
/**
|
|
18
|
+
* Tool execution. Forwards to ToolContext.askUser.
|
|
19
|
+
*/
|
|
20
|
+
export declare function askUserTool(args: Record<string, unknown>, ctx?: ToolContext): Promise<string>;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in AskUserQuestion tool — ask the user a question during execution.
|
|
3
|
+
*
|
|
4
|
+
* Two modes:
|
|
5
|
+
* - Plain text (no `options`): user types a free-text answer.
|
|
6
|
+
* - Multiple choice (`options` provided): user picks from a list. An
|
|
7
|
+
* implicit "Other..." entry is appended by the UI for free text.
|
|
8
|
+
*
|
|
9
|
+
* The actual prompt-the-user implementation is provided per-Engine via
|
|
10
|
+
* ToolContext.askUser. Headless mode (no UI wired up) leaves askUser
|
|
11
|
+
* undefined and the tool reports back asking the LLM to assume.
|
|
12
|
+
*/
|
|
13
|
+
export const askUserToolDef = {
|
|
14
|
+
name: "AskUserQuestion",
|
|
15
|
+
description: "Ask the user a question and wait for their response. " +
|
|
16
|
+
"Use this when you need clarification, confirmation, or additional input from the user. " +
|
|
17
|
+
"Pass `options` to present a multiple-choice list (recommended when the answer is one of a small known set — much better UX than free text). " +
|
|
18
|
+
"Each option needs a short `label` (the choice the user sees) and a `description` (what it means). " +
|
|
19
|
+
"Lead with the recommended option and append a recommendation marker to its label in the same language as the question (e.g. '(Recommended)' for an English question, '(推荐)' for a Chinese question). " +
|
|
20
|
+
"Set `multiSelect: true` when more than one choice can apply. " +
|
|
21
|
+
"ALWAYS write the `question`, every option `label`, every option `description`, and the `header` in the SAME LANGUAGE the user has been writing in. If the user wrote to you in Chinese, write all of these fields in Chinese; if Japanese, in Japanese; etc. The framework's UI chrome (separator hints, the implicit 'Other...' entry) is fixed — only your fields need to match the user's language. " +
|
|
22
|
+
"In headless mode this tool will return an error.",
|
|
23
|
+
inputSchema: {
|
|
24
|
+
type: "object",
|
|
25
|
+
properties: {
|
|
26
|
+
question: {
|
|
27
|
+
type: "string",
|
|
28
|
+
description: "The question to ask the user — in the user's language",
|
|
29
|
+
},
|
|
30
|
+
header: {
|
|
31
|
+
type: "string",
|
|
32
|
+
description: "Optional short label (≤12 chars) shown as a chip above the question (e.g. 'Language', 'Approach', '语言', '方案'). Use the user's language.",
|
|
33
|
+
},
|
|
34
|
+
options: {
|
|
35
|
+
type: "array",
|
|
36
|
+
description: "Optional 2-4 multiple-choice options. Omit for free-text input. An implicit 'Other...' entry is appended automatically by the framework.",
|
|
37
|
+
items: {
|
|
38
|
+
type: "object",
|
|
39
|
+
properties: {
|
|
40
|
+
label: {
|
|
41
|
+
type: "string",
|
|
42
|
+
description: "Short display text (1-5 words) — in the user's language",
|
|
43
|
+
},
|
|
44
|
+
description: {
|
|
45
|
+
type: "string",
|
|
46
|
+
description: "What this option means or implies — shown next to the label, in the user's language",
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
required: ["label", "description"],
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
multiSelect: {
|
|
53
|
+
type: "boolean",
|
|
54
|
+
description: "If true, the user can select multiple options. Defaults to false (single choice).",
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
required: ["question"],
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Tool execution. Forwards to ToolContext.askUser.
|
|
62
|
+
*/
|
|
63
|
+
export async function askUserTool(args, ctx) {
|
|
64
|
+
const question = args.question;
|
|
65
|
+
if (!question)
|
|
66
|
+
return "Error: question is required";
|
|
67
|
+
if (!ctx?.askUser) {
|
|
68
|
+
return "Error: AskUserQuestion is not available in headless mode. Make a reasonable assumption and proceed.";
|
|
69
|
+
}
|
|
70
|
+
const opts = parseOptions(args);
|
|
71
|
+
try {
|
|
72
|
+
const answer = await ctx.askUser(question, opts);
|
|
73
|
+
return answer || "(user provided empty response)";
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
return `Error asking user: ${err.message}`;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function parseOptions(args) {
|
|
80
|
+
const rawOptions = args.options;
|
|
81
|
+
const header = typeof args.header === "string" ? args.header : undefined;
|
|
82
|
+
const multiSelect = args.multiSelect === true;
|
|
83
|
+
if (!Array.isArray(rawOptions) || rawOptions.length === 0) {
|
|
84
|
+
if (header === undefined && !multiSelect)
|
|
85
|
+
return undefined;
|
|
86
|
+
return { header, multiSelect, options: undefined };
|
|
87
|
+
}
|
|
88
|
+
const options = rawOptions
|
|
89
|
+
.filter((o) => {
|
|
90
|
+
return (typeof o === "object" &&
|
|
91
|
+
o !== null &&
|
|
92
|
+
typeof o.label === "string" &&
|
|
93
|
+
typeof o.description === "string");
|
|
94
|
+
})
|
|
95
|
+
.map((o) => ({ label: o.label, description: o.description }));
|
|
96
|
+
if (options.length === 0)
|
|
97
|
+
return { header, multiSelect, options: undefined };
|
|
98
|
+
return { header, multiSelect, options };
|
|
99
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in Bash shell command execution tool.
|
|
3
|
+
*
|
|
4
|
+
* Spawns commands under an optional OS-level sandbox (Seatbelt on macOS,
|
|
5
|
+
* bubblewrap on Linux). The sandbox is selected by the Engine and handed
|
|
6
|
+
* down via ToolContext.sandbox. Without a sandbox we fall back to the
|
|
7
|
+
* historical behavior — plain shell spawn in the user's environment.
|
|
8
|
+
*
|
|
9
|
+
* The actual lifecycle (spawn, IO drain, byte cap, abort cascade, timeout
|
|
10
|
+
* cascade, listener cleanup) lives in {@link safeSpawnShell}. This file
|
|
11
|
+
* keeps only Bash-specific concerns:
|
|
12
|
+
*
|
|
13
|
+
* - The env allowlist + deny regex (a Bash threat-model thing — REPL /
|
|
14
|
+
* PowerShell don't have free-form shell injection from the LLM).
|
|
15
|
+
* - The final user-facing output formatting (STDERR: prefix, Exit code,
|
|
16
|
+
* Killed by signal, the truncation message, sandbox denial hints).
|
|
17
|
+
*/
|
|
18
|
+
import type { ToolContext } from "../context.js";
|
|
19
|
+
import type { ToolDefinition } from "../../types.js";
|
|
20
|
+
export declare const bashToolDef: ToolDefinition;
|
|
21
|
+
export declare function bashTool(args: Record<string, unknown>, ctx?: ToolContext): Promise<string>;
|