@cjhyy/code-shell-core 0.5.0-rc.1 → 0.6.0-rc.1
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 +13 -10
- package/dist/agent/agent-definition-registry.d.ts +21 -3
- package/dist/agent/agent-definition-registry.js +49 -18
- package/dist/agent/agent-definition.d.ts +32 -0
- package/dist/agent/agent-definition.js +49 -4
- package/dist/arena/arena.js +11 -12
- package/dist/arena/context/context-tools.js +47 -6
- package/dist/arena/context/within-root.d.ts +7 -0
- package/dist/arena/context/within-root.js +15 -0
- package/dist/arena/iterate/phases/argue.js +8 -2
- package/dist/arena/iterate/phases/revise.js +1 -1
- package/dist/arena/iterate/phases/tournament.js +3 -3
- package/dist/arena/ledger.js +9 -1
- package/dist/arena/phases/adjudication.js +1 -4
- package/dist/arena/phases/build-consensus.js +1 -4
- package/dist/arena/phases/cross-review.js +2 -8
- package/dist/arena/phases/debate-rounds.js +1 -4
- package/dist/arena/phases/participant-research.js +1 -4
- package/dist/arena/phases/planning-detail-expansion.js +8 -10
- package/dist/arena/planner.js +0 -1
- package/dist/arena/providers/docs.d.ts +1 -0
- package/dist/arena/providers/docs.js +5 -2
- package/dist/arena/providers/repo.d.ts +1 -0
- package/dist/arena/providers/repo.js +5 -2
- package/dist/arena/strategies/utils.d.ts +1 -4
- package/dist/arena/strategies/utils.js +7 -51
- package/dist/arena/transitions.d.ts +7 -2
- package/dist/arena/transitions.js +9 -4
- package/dist/arena/types.d.ts +8 -2
- package/dist/automation/cron-expr.d.ts +41 -0
- package/dist/automation/cron-expr.js +169 -0
- package/dist/automation/index.d.ts +41 -0
- package/dist/automation/index.js +39 -0
- package/dist/automation/runner.d.ts +84 -0
- package/dist/automation/runner.js +92 -0
- package/dist/automation/scheduler.d.ts +194 -0
- package/dist/automation/scheduler.js +623 -0
- package/dist/automation/store.d.ts +39 -0
- package/dist/automation/store.js +122 -0
- package/dist/automation/write-policy.d.ts +34 -0
- package/dist/automation/write-policy.js +113 -0
- package/dist/automation/write-run.d.ts +51 -0
- package/dist/automation/write-run.js +38 -0
- package/dist/capability-control/disabled-lists.d.ts +25 -0
- package/dist/capability-control/disabled-lists.js +57 -0
- package/dist/capability-control/index.d.ts +5 -0
- package/dist/capability-control/index.js +3 -0
- package/dist/capability-control/overlay.d.ts +64 -0
- package/dist/capability-control/overlay.js +116 -0
- package/dist/capability-control/project.d.ts +65 -0
- package/dist/capability-control/project.js +147 -0
- package/dist/capability-control/service.d.ts +70 -0
- package/dist/capability-control/service.js +147 -0
- package/dist/capability-control/types.d.ts +62 -0
- package/dist/capability-control/types.js +17 -0
- package/dist/cc-orchestrator/agent-adapter.d.ts +50 -0
- package/dist/cc-orchestrator/agent-adapter.js +133 -0
- package/dist/cc-orchestrator/cc-capability.d.ts +19 -0
- package/dist/cc-orchestrator/cc-capability.js +53 -0
- package/dist/cc-orchestrator/codex-session-discovery.d.ts +24 -0
- package/dist/cc-orchestrator/codex-session-discovery.js +191 -0
- package/dist/cc-orchestrator/codex-session-history.d.ts +25 -0
- package/dist/cc-orchestrator/codex-session-history.js +187 -0
- package/dist/cc-orchestrator/external-agent-changes.d.ts +19 -0
- package/dist/cc-orchestrator/external-agent-changes.js +214 -0
- package/dist/cc-orchestrator/external-agent-driver.d.ts +18 -0
- package/dist/cc-orchestrator/external-agent-driver.js +69 -0
- package/dist/cc-orchestrator/index.d.ts +8 -0
- package/dist/cc-orchestrator/index.js +8 -0
- package/dist/cc-orchestrator/relevance-judge.d.ts +15 -0
- package/dist/cc-orchestrator/relevance-judge.js +29 -0
- package/dist/cc-orchestrator/session-discovery.d.ts +46 -0
- package/dist/cc-orchestrator/session-discovery.js +125 -0
- package/dist/cc-orchestrator/session-history.d.ts +19 -0
- package/dist/cc-orchestrator/session-history.js +67 -0
- package/dist/cli/agent-server-stdio.d.ts +26 -1
- package/dist/cli/agent-server-stdio.js +221 -28
- package/dist/cli/agent-server-tcp.d.ts +20 -0
- package/dist/cli/agent-server-tcp.js +134 -0
- package/dist/cli/graceful-shutdown.d.ts +27 -0
- package/dist/cli/graceful-shutdown.js +30 -0
- package/dist/context/compaction.d.ts +56 -0
- package/dist/context/compaction.js +209 -15
- package/dist/context/manager.d.ts +0 -20
- package/dist/context/manager.js +25 -41
- package/dist/cost-tracker.js +5 -61
- package/dist/credentials/cipher.d.ts +49 -0
- package/dist/credentials/cipher.js +45 -0
- package/dist/credentials/cookie-jar.d.ts +24 -0
- package/dist/credentials/cookie-jar.js +40 -0
- package/dist/credentials/index.d.ts +7 -0
- package/dist/credentials/index.js +5 -0
- package/dist/credentials/inject-credential-tool.d.ts +20 -0
- package/dist/credentials/inject-credential-tool.js +130 -0
- package/dist/credentials/store.d.ts +72 -0
- package/dist/credentials/store.js +184 -0
- package/dist/credentials/types.d.ts +56 -0
- package/dist/credentials/use-credential-tool.d.ts +29 -0
- package/dist/credentials/use-credential-tool.js +205 -0
- package/dist/credentials/use-gate.d.ts +56 -0
- package/dist/credentials/use-gate.js +52 -0
- package/dist/cron/cron-runtime.d.ts +2 -0
- package/dist/cron/cron-runtime.js +2 -0
- package/dist/cron/cron-store.d.ts +2 -0
- package/dist/cron/cron-store.js +2 -0
- package/dist/cron/scheduler.d.ts +5 -32
- package/dist/cron/scheduler.js +5 -113
- package/dist/data/model-metadata.d.ts +77 -0
- package/dist/data/model-metadata.js +56 -0
- package/dist/data/model-metadata.json +216 -0
- package/dist/data/openrouter-models.d.ts +18 -7
- package/dist/data/openrouter-models.js +35 -8
- package/dist/data/openrouter-sync.js +1 -1
- package/dist/engine/aux-key.d.ts +10 -0
- package/dist/engine/aux-key.js +11 -0
- package/dist/engine/dynamic-tool-defs.d.ts +19 -0
- package/dist/engine/dynamic-tool-defs.js +36 -0
- package/dist/engine/engine.d.ts +431 -108
- package/dist/engine/engine.js +1630 -279
- package/dist/engine/friendly-error.d.ts +18 -0
- package/dist/engine/friendly-error.js +63 -0
- package/dist/engine/goal.d.ts +187 -0
- package/dist/engine/goal.js +196 -0
- package/dist/engine/image-compression.d.ts +81 -0
- package/dist/engine/image-compression.js +186 -0
- package/dist/engine/image-policy.d.ts +165 -0
- package/dist/engine/image-policy.js +189 -0
- package/dist/engine/model-connections-pool.d.ts +17 -0
- package/dist/engine/model-connections-pool.js +66 -0
- package/dist/engine/model-facade.d.ts +10 -0
- package/dist/engine/model-facade.js +25 -0
- package/dist/engine/patch-orphaned-tools.js +3 -0
- package/dist/engine/reactive-threshold.d.ts +13 -0
- package/dist/engine/reactive-threshold.js +17 -0
- package/dist/engine/resolve-llm-config.d.ts +16 -0
- package/dist/engine/resolve-llm-config.js +44 -0
- package/dist/engine/runtime.js +9 -1
- package/dist/engine/sandbox-cache-key.d.ts +10 -0
- package/dist/engine/sandbox-cache-key.js +9 -0
- package/dist/engine/sandbox-config.d.ts +31 -0
- package/dist/engine/sandbox-config.js +38 -0
- package/dist/engine/session-title.d.ts +13 -0
- package/dist/engine/session-title.js +34 -0
- package/dist/engine/session-usage.d.ts +19 -0
- package/dist/engine/session-usage.js +25 -0
- package/dist/engine/steer-queue.d.ts +32 -0
- package/dist/engine/steer-queue.js +26 -0
- package/dist/engine/streaming-tool-queue.d.ts +12 -0
- package/dist/engine/streaming-tool-queue.js +50 -10
- package/dist/engine/turn-loop.d.ts +94 -9
- package/dist/engine/turn-loop.js +775 -342
- package/dist/engine/types.d.ts +175 -0
- package/dist/engine/types.js +13 -0
- package/dist/external-agents/config.d.ts +2 -0
- package/dist/external-agents/config.js +15 -0
- package/dist/external-agents/types.d.ts +31 -0
- package/dist/external-agents/types.js +1 -0
- package/dist/git/parse-log.d.ts +13 -0
- package/dist/git/parse-log.js +21 -0
- package/dist/git/utils.d.ts +8 -6
- package/dist/git/utils.js +62 -26
- package/dist/git/worktree.d.ts +48 -0
- package/dist/git/worktree.js +111 -20
- package/dist/hooks/events.d.ts +23 -1
- package/dist/hooks/goal-stop-hook.d.ts +58 -0
- package/dist/hooks/goal-stop-hook.js +279 -0
- package/dist/hooks/hook-output.d.ts +33 -0
- package/dist/hooks/hook-output.js +79 -0
- package/dist/hooks/registry.d.ts +15 -0
- package/dist/hooks/registry.js +57 -1
- package/dist/hooks/shell-runner.d.ts +2 -0
- package/dist/hooks/shell-runner.js +48 -18
- package/dist/index.d.ts +79 -11
- package/dist/index.js +89 -6
- package/dist/llm/capabilities/param-specs.d.ts +14 -0
- package/dist/llm/capabilities/param-specs.js +62 -0
- package/dist/llm/capabilities/reasoning-control.d.ts +24 -0
- package/dist/llm/capabilities/reasoning-control.js +38 -0
- package/dist/llm/capabilities/rules.js +37 -3
- package/dist/llm/capabilities/types.d.ts +32 -2
- package/dist/llm/clamp-max-tokens.d.ts +11 -0
- package/dist/llm/clamp-max-tokens.js +17 -0
- package/dist/llm/client-base.d.ts +69 -5
- package/dist/llm/client-base.js +185 -25
- package/dist/llm/client-factory.d.ts +3 -3
- package/dist/llm/client-factory.js +2 -2
- package/dist/llm/model-cache.js +4 -2
- package/dist/llm/model-pool.d.ts +29 -11
- package/dist/llm/model-pool.js +36 -20
- package/dist/llm/provider-auth.d.ts +41 -0
- package/dist/llm/provider-auth.js +76 -0
- package/dist/llm/provider-catalog.d.ts +6 -2
- package/dist/llm/providers/anthropic.d.ts +32 -2
- package/dist/llm/providers/anthropic.js +207 -18
- package/dist/llm/providers/openai.d.ts +47 -2
- package/dist/llm/providers/openai.js +478 -71
- package/dist/llm/reasoning-setting.d.ts +51 -0
- package/dist/llm/reasoning-setting.js +40 -0
- package/dist/llm/stop-reason.d.ts +13 -0
- package/dist/llm/stop-reason.js +21 -0
- package/dist/llm/stream-watchdog.js +5 -1
- package/dist/llm/strip-vision.d.ts +32 -0
- package/dist/llm/strip-vision.js +94 -0
- package/dist/llm/token-counter.js +9 -2
- package/dist/llm/types.d.ts +9 -6
- package/dist/logging/logger.js +18 -4
- package/dist/logging/sanitize-messages.d.ts +10 -0
- package/dist/logging/sanitize-messages.js +112 -0
- package/dist/lsp/client.js +28 -8
- package/dist/lsp/manager.d.ts +1 -1
- package/dist/lsp/manager.js +42 -11
- package/dist/lsp/root-path.d.ts +9 -0
- package/dist/lsp/root-path.js +12 -0
- package/dist/model-catalog/builtin.d.ts +12 -0
- package/dist/model-catalog/builtin.js +407 -0
- package/dist/model-catalog/gen-connections.d.ts +20 -0
- package/dist/model-catalog/gen-connections.js +28 -0
- package/dist/model-catalog/index.d.ts +41 -0
- package/dist/model-catalog/index.js +90 -0
- package/dist/model-catalog/params.d.ts +20 -0
- package/dist/model-catalog/params.js +45 -0
- package/dist/model-catalog/resolve.d.ts +48 -0
- package/dist/model-catalog/resolve.js +33 -0
- package/dist/model-catalog/save-entry.d.ts +32 -0
- package/dist/model-catalog/save-entry.js +104 -0
- package/dist/model-catalog/types.d.ts +561 -0
- package/dist/model-catalog/types.js +93 -0
- package/dist/model-catalog/upsert.d.ts +9 -0
- package/dist/model-catalog/upsert.js +8 -0
- package/dist/onboarding.d.ts +12 -82
- package/dist/onboarding.js +75 -333
- package/dist/plugins/gitOps.d.ts +53 -0
- package/dist/plugins/gitOps.js +130 -5
- package/dist/plugins/installer/checkUpdate.d.ts +16 -0
- package/dist/plugins/installer/checkUpdate.js +32 -0
- package/dist/plugins/installer/codex/convertAgents.d.ts +7 -0
- package/dist/plugins/installer/codex/convertAgents.js +55 -0
- package/dist/plugins/installer/codex/convertCommands.d.ts +19 -0
- package/dist/plugins/installer/codex/convertCommands.js +46 -0
- package/dist/plugins/installer/codex/convertMcp.d.ts +11 -0
- package/dist/plugins/installer/codex/convertMcp.js +85 -0
- package/dist/plugins/installer/codex/convertSkills.d.ts +12 -0
- package/dist/plugins/installer/codex/convertSkills.js +33 -0
- package/dist/plugins/installer/detectFormat.d.ts +2 -0
- package/dist/plugins/installer/detectFormat.js +6 -0
- package/dist/plugins/installer/install.d.ts +7 -0
- package/dist/plugins/installer/install.js +123 -0
- package/dist/plugins/installer/installFromArchive.d.ts +43 -0
- package/dist/plugins/installer/installFromArchive.js +134 -0
- package/dist/plugins/installer/installFromSource.d.ts +13 -0
- package/dist/plugins/installer/installFromSource.js +51 -0
- package/dist/plugins/installer/list.d.ts +9 -0
- package/dist/plugins/installer/list.js +30 -0
- package/dist/plugins/installer/loadPluginAgents.d.ts +3 -0
- package/dist/plugins/installer/loadPluginAgents.js +27 -0
- package/dist/plugins/installer/loadPluginMcp.d.ts +14 -0
- package/dist/plugins/installer/loadPluginMcp.js +107 -0
- package/dist/plugins/installer/parseSource.d.ts +20 -0
- package/dist/plugins/installer/parseSource.js +74 -0
- package/dist/plugins/installer/paths.d.ts +5 -0
- package/dist/plugins/installer/paths.js +25 -0
- package/dist/plugins/installer/pruneDisabled.d.ts +24 -0
- package/dist/plugins/installer/pruneDisabled.js +73 -0
- package/dist/plugins/installer/types.d.ts +52 -0
- package/dist/plugins/installer/types.js +28 -0
- package/dist/plugins/installer/uninstall.d.ts +2 -0
- package/dist/plugins/installer/uninstall.js +18 -0
- package/dist/plugins/installer/unzip.d.ts +14 -0
- package/dist/plugins/installer/unzip.js +82 -0
- package/dist/plugins/installer/update.d.ts +28 -0
- package/dist/plugins/installer/update.js +97 -0
- package/dist/plugins/loadPluginHooks.d.ts +54 -1
- package/dist/plugins/loadPluginHooks.js +83 -1
- package/dist/plugins/marketplaceManager.d.ts +15 -1
- package/dist/plugins/marketplaceManager.js +58 -4
- package/dist/plugins/pluginCommandHook.js +34 -14
- package/dist/plugins/pluginContent.d.ts +30 -0
- package/dist/plugins/pluginContent.js +83 -0
- package/dist/plugins/pluginInstaller.d.ts +34 -0
- package/dist/plugins/pluginInstaller.js +168 -35
- package/dist/plugins/schemas.js +41 -6
- package/dist/plugins/types.d.ts +10 -0
- package/dist/preset/index.d.ts +7 -1
- package/dist/preset/index.js +112 -6
- package/dist/product/types.d.ts +1 -1
- package/dist/prompt/composer.d.ts +31 -0
- package/dist/prompt/composer.js +95 -25
- package/dist/prompt/instruction-scanner.js +5 -3
- package/dist/prompt/section-loader.js +1 -0
- package/dist/prompt/sections/base.md +1 -0
- package/dist/prompt/sections/browser.md +10 -0
- package/dist/prompt/sections/coding.md +4 -0
- package/dist/prompt/sections/orchestration.md +8 -0
- package/dist/protocol/chat-session-manager.d.ts +15 -2
- package/dist/protocol/chat-session-manager.js +46 -0
- package/dist/protocol/chat-session.d.ts +82 -0
- package/dist/protocol/chat-session.js +121 -1
- package/dist/protocol/client.d.ts +27 -0
- package/dist/protocol/client.js +38 -0
- package/dist/protocol/redact.d.ts +50 -0
- package/dist/protocol/redact.js +71 -0
- package/dist/protocol/server.d.ts +153 -2
- package/dist/protocol/server.js +807 -39
- package/dist/protocol/tcp-transport.d.ts +45 -0
- package/dist/protocol/tcp-transport.js +74 -0
- package/dist/protocol/transport.js +3 -2
- package/dist/protocol/types.d.ts +69 -0
- package/dist/protocol/types.js +22 -0
- package/dist/quota/credentials.d.ts +3 -0
- package/dist/quota/credentials.js +80 -0
- package/dist/quota/index.d.ts +36 -0
- package/dist/quota/index.js +155 -0
- package/dist/quota/types.d.ts +48 -0
- package/dist/quota/types.js +13 -0
- package/dist/remote/bridge.d.ts +11 -2
- package/dist/remote/bridge.js +61 -33
- package/dist/review/review-prompt.d.ts +28 -0
- package/dist/review/review-prompt.js +81 -0
- package/dist/run/ArtifactTracker.js +5 -4
- package/dist/run/EngineRunner.d.ts +27 -1
- package/dist/run/EngineRunner.js +46 -8
- package/dist/run/FileRunStore.js +40 -11
- package/dist/run/RunApprovalBackend.js +25 -5
- package/dist/run/RunLock.d.ts +28 -2
- package/dist/run/RunLock.js +49 -7
- package/dist/run/RunManager.d.ts +12 -0
- package/dist/run/RunManager.js +86 -3
- package/dist/run/RunQueue.d.ts +1 -0
- package/dist/run/RunQueue.js +8 -2
- package/dist/run/factory.d.ts +8 -1
- package/dist/run/factory.js +1 -0
- package/dist/run/index.d.ts +2 -2
- package/dist/run/index.js +1 -1
- package/dist/run/redirect-target.d.ts +7 -0
- package/dist/run/redirect-target.js +13 -0
- package/dist/run/types.js +1 -1
- package/dist/runtime/background-shell.d.ts +139 -0
- package/dist/runtime/background-shell.js +495 -0
- package/dist/runtime/output-clean.d.ts +24 -0
- package/dist/runtime/output-clean.js +41 -0
- package/dist/runtime/ring-file.d.ts +64 -0
- package/dist/runtime/ring-file.js +174 -0
- package/dist/runtime/safe-spawn.js +15 -34
- package/dist/runtime/spawn-common.d.ts +148 -0
- package/dist/runtime/spawn-common.js +303 -0
- package/dist/runtime/truncate-output.d.ts +22 -0
- package/dist/runtime/truncate-output.js +49 -0
- package/dist/runtime/utf8-cut.d.ts +11 -0
- package/dist/runtime/utf8-cut.js +23 -0
- package/dist/services/auto-dream.d.ts +4 -0
- package/dist/services/auto-dream.js +26 -26
- package/dist/services/browser-open.d.ts +13 -0
- package/dist/services/browser-open.js +16 -0
- package/dist/services/diagnostics.d.ts +1 -2
- package/dist/services/diagnostics.js +12 -7
- package/dist/services/dream-consolidation.d.ts +57 -0
- package/dist/services/dream-consolidation.js +151 -0
- package/dist/services/extract-memories.d.ts +14 -1
- package/dist/services/extract-memories.js +45 -6
- package/dist/services/memory-orchestrator.d.ts +21 -0
- package/dist/services/memory-orchestrator.js +125 -32
- package/dist/services/notifier.d.ts +8 -0
- package/dist/services/notifier.js +39 -25
- package/dist/services/oauth.js +5 -7
- package/dist/services/session-memory-sort.d.ts +8 -0
- package/dist/services/session-memory-sort.js +9 -0
- package/dist/services/session-memory.js +30 -19
- package/dist/session/file-history.d.ts +124 -1
- package/dist/session/file-history.js +232 -9
- package/dist/session/memory.d.ts +116 -2
- package/dist/session/memory.js +250 -28
- package/dist/session/session-manager.d.ts +63 -1
- package/dist/session/session-manager.js +186 -5
- package/dist/session/simple-diff.d.ts +23 -0
- package/dist/session/simple-diff.js +84 -0
- package/dist/session/transcript.d.ts +25 -1
- package/dist/session/transcript.js +35 -2
- package/dist/session/undo-target.d.ts +67 -0
- package/dist/session/undo-target.js +144 -0
- package/dist/settings/disk-defaults.d.ts +42 -0
- package/dist/settings/disk-defaults.js +33 -0
- package/dist/settings/feature-flags.d.ts +64 -0
- package/dist/settings/feature-flags.js +61 -0
- package/dist/settings/manager.d.ts +101 -1
- package/dist/settings/manager.js +345 -15
- package/dist/settings/migrate-config.d.ts +45 -0
- package/dist/settings/migrate-config.js +125 -0
- package/dist/settings/personalization.d.ts +19 -0
- package/dist/settings/personalization.js +7 -0
- package/dist/settings/schema-export.d.ts +25 -0
- package/dist/settings/schema-export.js +38 -0
- package/dist/settings/schema.d.ts +1827 -396
- package/dist/settings/schema.js +361 -81
- package/dist/skills/scanner.d.ts +9 -0
- package/dist/skills/scanner.js +30 -2
- package/dist/stt/resolve-transcribe.d.ts +31 -0
- package/dist/stt/resolve-transcribe.js +108 -0
- package/dist/stt/transcribe.d.ts +51 -0
- package/dist/stt/transcribe.js +65 -0
- package/dist/tool-system/browser-bridge.d.ts +226 -0
- package/dist/tool-system/browser-bridge.js +163 -0
- package/dist/tool-system/builtin/add-marketplace.d.ts +12 -0
- package/dist/tool-system/builtin/add-marketplace.js +76 -0
- package/dist/tool-system/builtin/agent-heartbeat.d.ts +49 -0
- package/dist/tool-system/builtin/agent-heartbeat.js +89 -0
- package/dist/tool-system/builtin/agent-notifications.d.ts +12 -3
- package/dist/tool-system/builtin/agent-notifications.js +9 -3
- package/dist/tool-system/builtin/agent-output-file.d.ts +38 -0
- package/dist/tool-system/builtin/agent-output-file.js +72 -0
- package/dist/tool-system/builtin/agent-registry.d.ts +23 -0
- package/dist/tool-system/builtin/agent-registry.js +16 -4
- package/dist/tool-system/builtin/agent.d.ts +50 -11
- package/dist/tool-system/builtin/agent.js +576 -73
- package/dist/tool-system/builtin/apply-patch/applier.js +66 -8
- package/dist/tool-system/builtin/apply-patch/backup-targets.d.ts +10 -0
- package/dist/tool-system/builtin/apply-patch/backup-targets.js +30 -0
- package/dist/tool-system/builtin/apply-patch/index.js +7 -3
- package/dist/tool-system/builtin/arena.js +6 -7
- package/dist/tool-system/builtin/background-jobs.d.ts +76 -0
- package/dist/tool-system/builtin/background-jobs.js +124 -0
- package/dist/tool-system/builtin/background-shell-tools.d.ts +20 -0
- package/dist/tool-system/builtin/background-shell-tools.js +108 -0
- package/dist/tool-system/builtin/background-work.d.ts +67 -0
- package/dist/tool-system/builtin/background-work.js +86 -0
- package/dist/tool-system/builtin/bash-output-style.d.ts +32 -0
- package/dist/tool-system/builtin/bash-output-style.js +40 -0
- package/dist/tool-system/builtin/bash.d.ts +5 -2
- package/dist/tool-system/builtin/bash.js +98 -62
- package/dist/tool-system/builtin/browser-tools.d.ts +33 -0
- package/dist/tool-system/builtin/browser-tools.js +312 -0
- package/dist/tool-system/builtin/cancel-goal.d.ts +31 -0
- package/dist/tool-system/builtin/cancel-goal.js +64 -0
- package/dist/tool-system/builtin/check-quota.d.ts +15 -0
- package/dist/tool-system/builtin/check-quota.js +34 -0
- package/dist/tool-system/builtin/complete-goal.d.ts +25 -0
- package/dist/tool-system/builtin/complete-goal.js +45 -0
- package/dist/tool-system/builtin/config.js +7 -0
- package/dist/tool-system/builtin/cron.d.ts +7 -0
- package/dist/tool-system/builtin/cron.js +105 -9
- package/dist/tool-system/builtin/drive-claude-code.d.ts +30 -0
- package/dist/tool-system/builtin/drive-claude-code.js +157 -0
- package/dist/tool-system/builtin/edit-model-catalog.d.ts +3 -0
- package/dist/tool-system/builtin/edit-model-catalog.js +94 -0
- package/dist/tool-system/builtin/edit.d.ts +2 -1
- package/dist/tool-system/builtin/edit.js +21 -12
- package/dist/tool-system/builtin/eol.d.ts +29 -0
- package/dist/tool-system/builtin/eol.js +37 -0
- package/dist/tool-system/builtin/file-cache.d.ts +6 -0
- package/dist/tool-system/builtin/file-cache.js +8 -0
- package/dist/tool-system/builtin/generate-image.d.ts +60 -0
- package/dist/tool-system/builtin/generate-image.js +374 -0
- package/dist/tool-system/builtin/generate-video.d.ts +55 -0
- package/dist/tool-system/builtin/generate-video.js +361 -0
- package/dist/tool-system/builtin/grep.js +6 -2
- package/dist/tool-system/builtin/image-providers.d.ts +86 -0
- package/dist/tool-system/builtin/image-providers.js +190 -0
- package/dist/tool-system/builtin/image-uploader.d.ts +33 -0
- package/dist/tool-system/builtin/image-uploader.js +74 -0
- package/dist/tool-system/builtin/index.d.ts +24 -1
- package/dist/tool-system/builtin/index.js +310 -25
- package/dist/tool-system/builtin/mcp-tools.js +23 -3
- package/dist/tool-system/builtin/memory.js +45 -7
- package/dist/tool-system/builtin/notebook-edit.d.ts +2 -1
- package/dist/tool-system/builtin/notebook-edit.js +1 -1
- package/dist/tool-system/builtin/powershell.js +4 -1
- package/dist/tool-system/builtin/read.d.ts +2 -1
- package/dist/tool-system/builtin/read.js +11 -3
- package/dist/tool-system/builtin/repl.js +4 -1
- package/dist/tool-system/builtin/skill.js +9 -0
- package/dist/tool-system/builtin/sleep.js +12 -5
- package/dist/tool-system/builtin/task.js +4 -1
- package/dist/tool-system/builtin/tool-search.js +25 -7
- package/dist/tool-system/builtin/update-automation-memory.d.ts +24 -0
- package/dist/tool-system/builtin/update-automation-memory.js +60 -0
- package/dist/tool-system/builtin/video-providers.d.ts +154 -0
- package/dist/tool-system/builtin/video-providers.js +235 -0
- package/dist/tool-system/builtin/view-image.d.ts +18 -0
- package/dist/tool-system/builtin/view-image.js +96 -0
- package/dist/tool-system/builtin/web-fetch.js +12 -2
- package/dist/tool-system/builtin/web-search.d.ts +4 -1
- package/dist/tool-system/builtin/web-search.js +57 -10
- package/dist/tool-system/builtin/worktree.d.ts +2 -1
- package/dist/tool-system/builtin/worktree.js +31 -4
- package/dist/tool-system/builtin/write.d.ts +2 -1
- package/dist/tool-system/builtin/write.js +1 -1
- package/dist/tool-system/context.d.ts +166 -6
- package/dist/tool-system/executor.d.ts +3 -2
- package/dist/tool-system/executor.js +197 -119
- package/dist/tool-system/investigation-guard.d.ts +4 -1
- package/dist/tool-system/investigation-guard.js +20 -4
- package/dist/tool-system/mcp-manager.d.ts +78 -16
- package/dist/tool-system/mcp-manager.js +357 -28
- package/dist/tool-system/path-policy.d.ts +99 -0
- package/dist/tool-system/path-policy.js +578 -0
- package/dist/tool-system/permission.d.ts +36 -1
- package/dist/tool-system/permission.js +322 -117
- package/dist/tool-system/plan-mode-allowlist.d.ts +32 -0
- package/dist/tool-system/plan-mode-allowlist.js +65 -0
- package/dist/tool-system/registry.d.ts +1 -0
- package/dist/tool-system/registry.js +26 -1
- package/dist/tool-system/sandbox/index.d.ts +8 -0
- package/dist/tool-system/sandbox/index.js +7 -2
- package/dist/tool-system/validate-tool-metadata.d.ts +36 -0
- package/dist/tool-system/validate-tool-metadata.js +63 -0
- package/dist/tool-system/validation.d.ts +10 -0
- package/dist/tool-system/validation.js +16 -3
- package/dist/types.d.ts +301 -15
- package/dist/updater.js +20 -9
- package/dist/utils/envUtils.d.ts +0 -9
- package/dist/utils/envUtils.js +3 -28
- package/dist/utils/exec.d.ts +40 -0
- package/dist/utils/exec.js +144 -0
- package/dist/utils/format.js +4 -2
- package/dist/utils/json.d.ts +12 -0
- package/dist/utils/json.js +92 -0
- package/dist/utils/lockfile.js +9 -2
- package/dist/utils/theme.d.ts +7 -1
- package/dist/utils/theme.js +5 -3
- package/dist/utils/toolDisplay.js +0 -1
- package/package.json +14 -7
- package/dist/agent/coordinator.d.ts +0 -49
- package/dist/agent/coordinator.js +0 -77
- package/dist/settings/manager.test.js +0 -73
- package/dist/tool-system/builtin/remote-trigger.d.ts +0 -6
- package/dist/tool-system/builtin/remote-trigger.js +0 -54
- package/dist/tool-system/builtin/send-message.d.ts +0 -6
- package/dist/tool-system/builtin/send-message.js +0 -47
- /package/dist/{settings/manager.test.d.ts → credentials/types.js} +0 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VideoProvider — adapter interface for text-to-video generation (TODO 7.1).
|
|
3
|
+
*
|
|
4
|
+
* Unlike images (one request → bytes), video generation is asynchronous and
|
|
5
|
+
* long: SUBMIT a job → POLL its status until it finishes → DOWNLOAD the bytes.
|
|
6
|
+
* The interface captures exactly those three steps so the GenerateVideo tool's
|
|
7
|
+
* background polling loop is provider-agnostic, and concrete adapters
|
|
8
|
+
* (Seedance/Kling — filled in once their private API docs are available) only
|
|
9
|
+
* implement submit/poll/download.
|
|
10
|
+
*
|
|
11
|
+
* Credentials are resolved by the tool layer from settings; adapters are pure
|
|
12
|
+
* "creds + request → job lifecycle". `fetch` is injected for testability.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Deterministic in-memory adapter for tests and local dev — no network. Models
|
|
16
|
+
* the three-step lifecycle: submit mints a job; poll returns `running` for the
|
|
17
|
+
* first N calls then `succeeded` (or `failed` after M); download returns the
|
|
18
|
+
* configured bytes. Lets the GenerateVideo background loop be tested end-to-end
|
|
19
|
+
* before any real (Seedance/Kling) adapter exists.
|
|
20
|
+
*/
|
|
21
|
+
export class FakeVideoProvider {
|
|
22
|
+
opts;
|
|
23
|
+
kind = "fake";
|
|
24
|
+
polls = new Map();
|
|
25
|
+
counter = 0;
|
|
26
|
+
constructor(opts = {}) {
|
|
27
|
+
this.opts = opts;
|
|
28
|
+
}
|
|
29
|
+
async submit(_req) {
|
|
30
|
+
this.counter += 1;
|
|
31
|
+
const jobId = `fakejob-${this.counter}`;
|
|
32
|
+
this.polls.set(jobId, 0);
|
|
33
|
+
return { ok: true, jobId };
|
|
34
|
+
}
|
|
35
|
+
async poll(req) {
|
|
36
|
+
const n = this.polls.get(req.jobId) ?? 0;
|
|
37
|
+
this.polls.set(req.jobId, n + 1);
|
|
38
|
+
if (this.opts.failAfterPolls !== undefined && n >= this.opts.failAfterPolls) {
|
|
39
|
+
return { ok: true, status: "failed", error: this.opts.failMessage ?? "job failed" };
|
|
40
|
+
}
|
|
41
|
+
if (this.opts.succeedAfterPolls !== undefined && n >= this.opts.succeedAfterPolls) {
|
|
42
|
+
return { ok: true, status: "succeeded" };
|
|
43
|
+
}
|
|
44
|
+
return { ok: true, status: "running" };
|
|
45
|
+
}
|
|
46
|
+
async download(_req) {
|
|
47
|
+
return { ok: true, bytes: Buffer.from(this.opts.bytes ?? "FAKE_VIDEO"), ext: "mp4" };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* fal.ai video adapter — submit/poll/download against the fal queue API
|
|
52
|
+
* (https://queue.fal.run). model id selects the underlying model
|
|
53
|
+
* (e.g. fal-ai/kling-video/v3/pro/text-to-video). When `image` is present we
|
|
54
|
+
* switch a `...text-to-video` model to `...image-to-video` and send image_url,
|
|
55
|
+
* so callers only need to pass an image to get i2v.
|
|
56
|
+
*
|
|
57
|
+
* IMPORTANT: fal's status/result URLs use a model-FAMILY prefix
|
|
58
|
+
* (`fal-ai/kling-video/requests/<id>`), NOT the full submit path
|
|
59
|
+
* (`.../v3/pro/text-to-video/requests/<id>` → HTTP 405). So we never
|
|
60
|
+
* reconstruct those URLs; we encode the `status_url` + `response_url` that
|
|
61
|
+
* submit returns into the jobId (`<status_url>|<response_url>`) and use them
|
|
62
|
+
* verbatim in poll/download. Verified against the live API 2026-06-10.
|
|
63
|
+
*/
|
|
64
|
+
export class FalVideoProvider {
|
|
65
|
+
fetchImpl;
|
|
66
|
+
kind = "fal";
|
|
67
|
+
constructor(fetchImpl = fetch) {
|
|
68
|
+
this.fetchImpl = fetchImpl;
|
|
69
|
+
}
|
|
70
|
+
/** Effective image list: images[] wins; else single image; else []. */
|
|
71
|
+
imageList(req) {
|
|
72
|
+
if (req.images && req.images.length)
|
|
73
|
+
return req.images;
|
|
74
|
+
if (req.image)
|
|
75
|
+
return [req.image];
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Does this model family support reference-to-video (multi-image)? Verified
|
|
80
|
+
* 2026-06-10 against the live API: Seedance has it; Kling does NOT (routing a
|
|
81
|
+
* Kling model to `.../reference-to-video` 404s at result fetch). Keep this a
|
|
82
|
+
* conservative allowlist — only families confirmed to expose the endpoint.
|
|
83
|
+
*/
|
|
84
|
+
supportsReference(model) {
|
|
85
|
+
return /seedance/i.test(model);
|
|
86
|
+
}
|
|
87
|
+
/** Route model suffix by image count: 0→text, 1→image, ≥2→reference. */
|
|
88
|
+
resolveModel(model, imageCount) {
|
|
89
|
+
const target = imageCount >= 2 ? "reference-to-video" : imageCount === 1 ? "image-to-video" : null;
|
|
90
|
+
if (target && /(text|image|reference)-to-video$/.test(model)) {
|
|
91
|
+
return model.replace(/(text|image|reference)-to-video$/, target);
|
|
92
|
+
}
|
|
93
|
+
return model;
|
|
94
|
+
}
|
|
95
|
+
/** jobId = `${statusUrl}|${responseUrl}` (fal returns both from submit). */
|
|
96
|
+
split(jobId) {
|
|
97
|
+
const idx = jobId.indexOf("|");
|
|
98
|
+
if (idx < 0)
|
|
99
|
+
return { statusUrl: jobId, responseUrl: jobId };
|
|
100
|
+
return { statusUrl: jobId.slice(0, idx), responseUrl: jobId.slice(idx + 1) };
|
|
101
|
+
}
|
|
102
|
+
async submit(req) {
|
|
103
|
+
const base = req.creds.baseUrl.replace(/\/+$/, "");
|
|
104
|
+
const imgs = this.imageList(req);
|
|
105
|
+
const vids = req.videos ?? [];
|
|
106
|
+
// Multi-image OR any reference video needs the reference-to-video endpoint,
|
|
107
|
+
// which only some families (Seedance) expose. Routing e.g. Kling there
|
|
108
|
+
// 404s at result fetch — fail fast with a clear message instead.
|
|
109
|
+
const needsReference = imgs.length >= 2 || vids.length > 0;
|
|
110
|
+
if (needsReference && !this.supportsReference(req.model)) {
|
|
111
|
+
return {
|
|
112
|
+
ok: false,
|
|
113
|
+
error: `model "${req.model}" does not support reference-to-video (multiple images or reference videos). Use a Seedance model, or pass a single image / no video.`,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
// imageCount alone can't express "reference needed"; bump to 2 when a video
|
|
117
|
+
// forces the reference endpoint so resolveModel picks reference-to-video.
|
|
118
|
+
const refImageCount = needsReference ? Math.max(imgs.length, 2) : imgs.length;
|
|
119
|
+
const model = this.resolveModel(req.model, refImageCount);
|
|
120
|
+
const body = { prompt: req.prompt };
|
|
121
|
+
if (imgs.length >= 2)
|
|
122
|
+
body.image_urls = imgs;
|
|
123
|
+
else if (imgs.length === 1)
|
|
124
|
+
body.image_url = imgs[0];
|
|
125
|
+
if (vids.length > 0)
|
|
126
|
+
body.video_urls = vids;
|
|
127
|
+
try {
|
|
128
|
+
const r = await this.fetchImpl(`${base}/${model}`, {
|
|
129
|
+
method: "POST",
|
|
130
|
+
headers: { Authorization: `Key ${req.creds.apiKey}`, "Content-Type": "application/json" },
|
|
131
|
+
body: JSON.stringify(body),
|
|
132
|
+
signal: req.signal,
|
|
133
|
+
});
|
|
134
|
+
if (!r.ok) {
|
|
135
|
+
const t = await r.text().catch(() => "");
|
|
136
|
+
return { ok: false, error: `fal submit failed: HTTP ${r.status} ${t}`.trim() };
|
|
137
|
+
}
|
|
138
|
+
const j = (await r.json());
|
|
139
|
+
if (!j.request_id)
|
|
140
|
+
return { ok: false, error: "fal submit: no request_id in response" };
|
|
141
|
+
// Prefer the URLs fal hands back; fall back to family-prefix reconstruction
|
|
142
|
+
// only if they're absent (defensive — live API always returns them).
|
|
143
|
+
const statusUrl = j.status_url ?? "";
|
|
144
|
+
const responseUrl = j.response_url ?? "";
|
|
145
|
+
if (!statusUrl || !responseUrl) {
|
|
146
|
+
return { ok: false, error: "fal submit: missing status_url/response_url" };
|
|
147
|
+
}
|
|
148
|
+
return { ok: true, jobId: `${statusUrl}|${responseUrl}` };
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
return { ok: false, error: `fal submit error: ${err.message}` };
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
async poll(req) {
|
|
155
|
+
const { statusUrl } = this.split(req.jobId);
|
|
156
|
+
try {
|
|
157
|
+
const r = await this.fetchImpl(statusUrl, {
|
|
158
|
+
method: "GET",
|
|
159
|
+
headers: { Authorization: `Key ${req.creds.apiKey}` },
|
|
160
|
+
signal: req.signal,
|
|
161
|
+
});
|
|
162
|
+
// fal returns 200/202 for valid in-progress/queued states; only treat a
|
|
163
|
+
// hard client/server error (4xx except 202, 5xx) as a transport failure.
|
|
164
|
+
if (!r.ok && r.status !== 202) {
|
|
165
|
+
const t = await r.text().catch(() => "");
|
|
166
|
+
return { ok: false, error: `fal status failed: HTTP ${r.status} ${t}`.trim() };
|
|
167
|
+
}
|
|
168
|
+
const j = (await r.json());
|
|
169
|
+
switch (j.status) {
|
|
170
|
+
case "IN_QUEUE":
|
|
171
|
+
case "IN_PROGRESS":
|
|
172
|
+
return { ok: true, status: "running" };
|
|
173
|
+
case "COMPLETED":
|
|
174
|
+
return { ok: true, status: "succeeded" };
|
|
175
|
+
default:
|
|
176
|
+
return { ok: true, status: "failed", error: `fal status: ${j.status ?? "unknown"}` };
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
return { ok: false, error: `fal poll error: ${err.message}` };
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
async download(req) {
|
|
184
|
+
const { responseUrl } = this.split(req.jobId);
|
|
185
|
+
try {
|
|
186
|
+
// hop 1: result JSON
|
|
187
|
+
const r = await this.fetchImpl(responseUrl, {
|
|
188
|
+
method: "GET",
|
|
189
|
+
headers: { Authorization: `Key ${req.creds.apiKey}` },
|
|
190
|
+
signal: req.signal,
|
|
191
|
+
});
|
|
192
|
+
if (!r.ok) {
|
|
193
|
+
const t = await r.text().catch(() => "");
|
|
194
|
+
return { ok: false, error: `fal result failed: HTTP ${r.status} ${t}`.trim() };
|
|
195
|
+
}
|
|
196
|
+
const j = (await r.json());
|
|
197
|
+
const videoUrl = j.video?.url;
|
|
198
|
+
if (!videoUrl)
|
|
199
|
+
return { ok: false, error: "fal result: no video.url" };
|
|
200
|
+
// hop 2: video bytes
|
|
201
|
+
const vr = await this.fetchImpl(videoUrl, { method: "GET", signal: req.signal });
|
|
202
|
+
if (!vr.ok) {
|
|
203
|
+
return { ok: false, error: `fal video download failed: HTTP ${vr.status}` };
|
|
204
|
+
}
|
|
205
|
+
const buf = new Uint8Array(await vr.arrayBuffer());
|
|
206
|
+
const m = /\.([a-z0-9]{2,4})(?:\?|$)/i.exec(videoUrl);
|
|
207
|
+
const ext = m ? m[1].toLowerCase() : "mp4";
|
|
208
|
+
// Surface the fal-hosted URL so the model can reuse it for video extension
|
|
209
|
+
// (videos[] → video_urls) without re-uploading. Note: signed/expiring.
|
|
210
|
+
return { ok: true, bytes: buf, ext, url: videoUrl };
|
|
211
|
+
}
|
|
212
|
+
catch (err) {
|
|
213
|
+
return { ok: false, error: `fal download error: ${err.message}` };
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/** Default model per video provider kind (filled in with real adapters). */
|
|
218
|
+
export const DEFAULT_VIDEO_MODEL = {
|
|
219
|
+
fal: "fal-ai/kling-video/v3/pro/text-to-video",
|
|
220
|
+
};
|
|
221
|
+
/**
|
|
222
|
+
* Registry of video-provider adapters, keyed by `kind`. Only `fake` exists
|
|
223
|
+
* today (test/dev). Real adapters (seedance, kling) are intentionally absent
|
|
224
|
+
* until their private API contracts are confirmed — see TODO 7.1 块3.
|
|
225
|
+
*/
|
|
226
|
+
export function getVideoProvider(kind, fetchImpl = fetch) {
|
|
227
|
+
switch (kind) {
|
|
228
|
+
case "fake":
|
|
229
|
+
return new FakeVideoProvider({ succeedAfterPolls: 0 });
|
|
230
|
+
case "fal":
|
|
231
|
+
return new FalVideoProvider(fetchImpl);
|
|
232
|
+
default:
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in view_image tool — 把一个本地图片文件以 base64 image ContentBlock
|
|
3
|
+
* 回传进上下文,让 vision 模型「看」它(对照 codex 的 view_image)。
|
|
4
|
+
*
|
|
5
|
+
* 典型用法:模型先写 SVG/Mermaid 并用 shell 转成 PNG,再调 view_image(png)
|
|
6
|
+
* 检查图画对没有(标签是否重叠、文字是否溢出),不对就改源再重转。
|
|
7
|
+
*
|
|
8
|
+
* 三道闸门,避免污染上下文 / 浪费 token:
|
|
9
|
+
* 1. vision gate —— 当前模型不支持视觉时不读文件,只回文字占位。
|
|
10
|
+
* 2. 格式 gate —— 只支持 png/jpeg/gif/webp(provider image 块能吃的);
|
|
11
|
+
* svg/pdf 等回文字提示「先转 PNG」。
|
|
12
|
+
* 3. 大小 gate —— 超过 MAX_BYTES 回文字提示,不读进 base64。
|
|
13
|
+
*/
|
|
14
|
+
import type { ToolDefinition } from "../../types.js";
|
|
15
|
+
import type { ToolContext } from "../context.js";
|
|
16
|
+
import type { BuiltinToolResult } from "./index.js";
|
|
17
|
+
export declare const viewImageToolDef: ToolDefinition;
|
|
18
|
+
export declare function viewImageTool(args: Record<string, unknown>, ctx?: ToolContext): Promise<BuiltinToolResult>;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in view_image tool — 把一个本地图片文件以 base64 image ContentBlock
|
|
3
|
+
* 回传进上下文,让 vision 模型「看」它(对照 codex 的 view_image)。
|
|
4
|
+
*
|
|
5
|
+
* 典型用法:模型先写 SVG/Mermaid 并用 shell 转成 PNG,再调 view_image(png)
|
|
6
|
+
* 检查图画对没有(标签是否重叠、文字是否溢出),不对就改源再重转。
|
|
7
|
+
*
|
|
8
|
+
* 三道闸门,避免污染上下文 / 浪费 token:
|
|
9
|
+
* 1. vision gate —— 当前模型不支持视觉时不读文件,只回文字占位。
|
|
10
|
+
* 2. 格式 gate —— 只支持 png/jpeg/gif/webp(provider image 块能吃的);
|
|
11
|
+
* svg/pdf 等回文字提示「先转 PNG」。
|
|
12
|
+
* 3. 大小 gate —— 超过 MAX_BYTES 回文字提示,不读进 base64。
|
|
13
|
+
*/
|
|
14
|
+
import { readFile, stat } from "node:fs/promises";
|
|
15
|
+
import { extname, isAbsolute, resolve } from "node:path";
|
|
16
|
+
import { capabilitiesFor } from "../../llm/capabilities/index.js";
|
|
17
|
+
const MAX_BYTES = 5 * 1024 * 1024; // 5MB —— vision 模型按 tile 计 token,大图无益且撑大请求
|
|
18
|
+
const MEDIA_TYPES = {
|
|
19
|
+
".png": "image/png",
|
|
20
|
+
".jpg": "image/jpeg",
|
|
21
|
+
".jpeg": "image/jpeg",
|
|
22
|
+
".gif": "image/gif",
|
|
23
|
+
".webp": "image/webp",
|
|
24
|
+
};
|
|
25
|
+
export const viewImageToolDef = {
|
|
26
|
+
name: "view_image",
|
|
27
|
+
description: "Load a local image file into the conversation so you can SEE it (vision). " +
|
|
28
|
+
"Use after generating or rendering an image (e.g. SVG/Mermaid → PNG) to verify it " +
|
|
29
|
+
"looks right — check for overlapping labels, clipped text, wrong layout — then fix the " +
|
|
30
|
+
"source and re-render if needed. Supports PNG/JPEG/GIF/WebP only; convert SVG/PDF to PNG " +
|
|
31
|
+
"first. Requires a vision-capable model; otherwise the image is skipped.",
|
|
32
|
+
inputSchema: {
|
|
33
|
+
type: "object",
|
|
34
|
+
properties: {
|
|
35
|
+
path: {
|
|
36
|
+
type: "string",
|
|
37
|
+
description: "Path to the image file (absolute, or relative to the working directory).",
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
required: ["path"],
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
export async function viewImageTool(args, ctx) {
|
|
44
|
+
const rawPath = args.path;
|
|
45
|
+
if (typeof rawPath !== "string" || !rawPath.trim()) {
|
|
46
|
+
return "Error: path is required";
|
|
47
|
+
}
|
|
48
|
+
const cwd = ctx?.cwd ?? process.cwd();
|
|
49
|
+
const abs = isAbsolute(rawPath) ? rawPath : resolve(cwd, rawPath);
|
|
50
|
+
// 闸门 1:vision gate —— 不支持视觉就不读文件。
|
|
51
|
+
// 缺 llmConfig 时按「非视觉」处理(fail closed),对齐 DEFAULT_CAPABILITY
|
|
52
|
+
// 的保守姿态:运行时 ToolContext.llmConfig 必有,缺失只发生在测试 / 异常
|
|
53
|
+
// 装配下,此时绝不把 base64 读进上下文。
|
|
54
|
+
const supportsVision = (() => {
|
|
55
|
+
if (!ctx?.llmConfig)
|
|
56
|
+
return false;
|
|
57
|
+
const kind = (ctx.llmConfig.providerKind ?? ctx.llmConfig.provider);
|
|
58
|
+
return capabilitiesFor(kind, ctx.llmConfig.model).supportsVision;
|
|
59
|
+
})();
|
|
60
|
+
if (!supportsVision) {
|
|
61
|
+
return `[图片未加载: ${abs} —— 当前模型不支持视觉输入,已跳过。切换到 vision 模型后再 view_image。]`;
|
|
62
|
+
}
|
|
63
|
+
// 闸门 2:格式 gate
|
|
64
|
+
const ext = extname(abs).toLowerCase();
|
|
65
|
+
const mediaType = MEDIA_TYPES[ext];
|
|
66
|
+
if (!mediaType) {
|
|
67
|
+
return `[图片未加载: ${abs} —— 格式 ${ext || "(无扩展名)"} 不支持视觉预览,请先转成 PNG/JPEG。]`;
|
|
68
|
+
}
|
|
69
|
+
// 闸门 3:大小 gate(读 stat,不读全文件)
|
|
70
|
+
let size;
|
|
71
|
+
try {
|
|
72
|
+
size = (await stat(abs)).size;
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
return `Error: 无法读取 ${abs}: ${err.message}`;
|
|
76
|
+
}
|
|
77
|
+
if (size > MAX_BYTES) {
|
|
78
|
+
const mb = (size / 1024 / 1024).toFixed(1);
|
|
79
|
+
return `[图片未加载: ${abs} —— 文件过大 (${mb} MB > 5 MB),请先压缩或缩放再 view_image。]`;
|
|
80
|
+
}
|
|
81
|
+
let buf;
|
|
82
|
+
try {
|
|
83
|
+
buf = await readFile(abs);
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
return `Error: 无法读取 ${abs}: ${err.message}`;
|
|
87
|
+
}
|
|
88
|
+
const data = buf.toString("base64");
|
|
89
|
+
const kb = Math.round(buf.length / 1024);
|
|
90
|
+
return {
|
|
91
|
+
contentBlocks: [
|
|
92
|
+
{ type: "image", source: { type: "base64", media_type: mediaType, data } },
|
|
93
|
+
],
|
|
94
|
+
result: `[已加载图片: ${abs} (${mediaType}, ${kb} KB)]`,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
@@ -176,7 +176,12 @@ export async function webFetchTool(args) {
|
|
|
176
176
|
catch {
|
|
177
177
|
return `Error: invalid URL "${url}"`;
|
|
178
178
|
}
|
|
179
|
-
|
|
179
|
+
// A non-positive max_length must NOT reach `text.slice(0, maxLength)` below
|
|
180
|
+
// with a negative end — JS reads that as "all but the last N", silently
|
|
181
|
+
// returning the WRONG bytes (+ a misleading "truncated" suffix). `|| DEFAULT`
|
|
182
|
+
// only caught 0/NaN, not negatives. Floor to the default page size first.
|
|
183
|
+
const rawMaxLength = args.max_length;
|
|
184
|
+
const maxLength = Math.min(typeof rawMaxLength === "number" && rawMaxLength > 0 ? rawMaxLength : DEFAULT_MAX, MAX_OUTPUT);
|
|
180
185
|
const rawHeaders = args.headers ?? {};
|
|
181
186
|
const baseHeaders = {
|
|
182
187
|
"User-Agent": "Mozilla/5.0 (compatible; code-shell/0.1; +https://github.com/nicepkg/code-shell)",
|
|
@@ -192,7 +197,12 @@ export async function webFetchTool(args) {
|
|
|
192
197
|
// host, and DNS-resolved IPs against the block lists. fetch() runs
|
|
193
198
|
// with redirect: "manual" so the runtime cannot silently follow a
|
|
194
199
|
// redirect into private/loopback/metadata space.
|
|
200
|
+
// Combine the 30s fetch timeout with the run's abort signal (registry injects
|
|
201
|
+
// __signal) so a user Stop cancels an in-flight fetch promptly, not only on
|
|
202
|
+
// the 30s timeout. Timeout alone was the previous behavior.
|
|
195
203
|
const timeoutSignal = AbortSignal.timeout(30_000);
|
|
204
|
+
const userSignal = args.__signal;
|
|
205
|
+
const fetchSignal = userSignal ? AbortSignal.any([userSignal, timeoutSignal]) : timeoutSignal;
|
|
196
206
|
let currentUrl = parsed;
|
|
197
207
|
let currentHeaders = { ...baseHeaders };
|
|
198
208
|
const originalOrigin = parsed;
|
|
@@ -206,7 +216,7 @@ export async function webFetchTool(args) {
|
|
|
206
216
|
const res = await fetch(currentUrl, {
|
|
207
217
|
headers: currentHeaders,
|
|
208
218
|
redirect: "manual",
|
|
209
|
-
signal:
|
|
219
|
+
signal: fetchSignal,
|
|
210
220
|
});
|
|
211
221
|
// Not a redirect: return body (or HTTP error).
|
|
212
222
|
if (res.status < 300 || res.status >= 400 || !res.headers.get("location")) {
|
|
@@ -21,5 +21,8 @@ export interface ResolvedSearchConfig {
|
|
|
21
21
|
* the user where the value came from when debugging.
|
|
22
22
|
*/
|
|
23
23
|
export declare function resolveSearchConfig(cwd?: string): ResolvedSearchConfig;
|
|
24
|
+
export declare function isWebSearchAvailable(cwd?: string, nowMs?: number): boolean;
|
|
24
25
|
export declare const webSearchToolDef: ToolDefinition;
|
|
25
|
-
export declare function webSearchTool(args: Record<string, unknown
|
|
26
|
+
export declare function webSearchTool(args: Record<string, unknown>, ctx?: {
|
|
27
|
+
cwd?: string;
|
|
28
|
+
}): Promise<string>;
|
|
@@ -18,7 +18,11 @@ export function resolveSearchConfig(cwd = process.cwd()) {
|
|
|
18
18
|
let settingsKey;
|
|
19
19
|
let settingsBaseUrl;
|
|
20
20
|
try {
|
|
21
|
-
|
|
21
|
+
// scope "full" so the USER-level ~/.code-shell/settings.json is read, not
|
|
22
|
+
// just ${cwd}/.code-shell — the search key is typically a personal/global
|
|
23
|
+
// credential. Default "project" scope would miss it (the "No search provider
|
|
24
|
+
// configured" bug, esp. for automation runs rooted at the app dir).
|
|
25
|
+
const merged = new SettingsManager(cwd, "full").get();
|
|
22
26
|
const search = merged.search ?? {};
|
|
23
27
|
const p = search.provider;
|
|
24
28
|
if (p === "serper" || p === "tavily" || p === "searxng")
|
|
@@ -68,6 +72,33 @@ export function resolveSearchConfig(cwd = process.cwd()) {
|
|
|
68
72
|
return { provider: "searxng", baseUrl: envSearxng, source: "env" };
|
|
69
73
|
return { provider: "serper", source: "none" };
|
|
70
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Tool-visibility guard: WebSearch is only useful when a search provider is
|
|
77
|
+
* configured. Mirrors the runtime check in the tool itself (source === "none"
|
|
78
|
+
* means no provider).
|
|
79
|
+
*
|
|
80
|
+
* Cached per-cwd with a short TTL: this runs on EVERY message's toolDefs
|
|
81
|
+
* assembly (engine.ts), and resolveSearchConfig reads + parses settings from
|
|
82
|
+
* disk each call. The 1s TTL collapses back-to-back reads while still picking
|
|
83
|
+
* up a newly-configured provider before the user's next message. The execution
|
|
84
|
+
* path (resolveSearchConfig) is intentionally NOT cached — only this boolean.
|
|
85
|
+
*/
|
|
86
|
+
const availCache = new Map();
|
|
87
|
+
const AVAIL_TTL_MS = 1000;
|
|
88
|
+
export function isWebSearchAvailable(cwd = process.cwd(), nowMs = Date.now()) {
|
|
89
|
+
const hit = availCache.get(cwd);
|
|
90
|
+
if (hit && nowMs - hit.at < AVAIL_TTL_MS)
|
|
91
|
+
return hit.value;
|
|
92
|
+
let value = false;
|
|
93
|
+
try {
|
|
94
|
+
value = resolveSearchConfig(cwd).source !== "none";
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
value = false; // unresolved config → treat as unavailable
|
|
98
|
+
}
|
|
99
|
+
availCache.set(cwd, { at: nowMs, value });
|
|
100
|
+
return value;
|
|
101
|
+
}
|
|
71
102
|
export const webSearchToolDef = {
|
|
72
103
|
name: "WebSearch",
|
|
73
104
|
description: "Search the web for information. Returns a list of search results with titles, URLs, and snippets. " +
|
|
@@ -84,25 +115,38 @@ export const webSearchToolDef = {
|
|
|
84
115
|
required: ["query"],
|
|
85
116
|
},
|
|
86
117
|
};
|
|
87
|
-
export async function webSearchTool(args) {
|
|
118
|
+
export async function webSearchTool(args, ctx) {
|
|
88
119
|
const query = args.query;
|
|
89
120
|
if (!query)
|
|
90
121
|
return "Error: query is required";
|
|
91
|
-
|
|
92
|
-
|
|
122
|
+
// Floor to default on non-positive: a negative num_results would reach
|
|
123
|
+
// `results.slice(0, num)` with a negative end (= all but the last N), silently
|
|
124
|
+
// returning the wrong result set. `|| 10` only caught 0/NaN, not negatives.
|
|
125
|
+
const rawNum = args.num_results;
|
|
126
|
+
const numResults = Math.min(typeof rawNum === "number" && rawNum > 0 ? rawNum : 10, 20);
|
|
127
|
+
// Use the run's cwd (e.g. an automation job's project dir) so per-project
|
|
128
|
+
// settings resolve correctly; falls back to process.cwd() when absent.
|
|
129
|
+
const config = resolveSearchConfig(ctx?.cwd);
|
|
93
130
|
if (config.source === "none") {
|
|
94
131
|
return "Error: No search provider configured. Open desktop 设置 → 连接 to add credentials, or set SERPER_API_KEY / TAVILY_API_KEY / SEARXNG_URL.";
|
|
95
132
|
}
|
|
133
|
+
// A search provider's fetch had NO timeout and NO abort wiring — a hung/slow
|
|
134
|
+
// provider blocked the tool indefinitely and a user Stop couldn't cancel it.
|
|
135
|
+
// Give every provider call a 20s timeout, combined with the run's abort
|
|
136
|
+
// signal (registry injects __signal) so Stop is prompt.
|
|
137
|
+
const userSignal = args.__signal;
|
|
138
|
+
const timeoutSignal = AbortSignal.timeout(20_000);
|
|
139
|
+
const signal = userSignal ? AbortSignal.any([userSignal, timeoutSignal]) : timeoutSignal;
|
|
96
140
|
try {
|
|
97
141
|
let results;
|
|
98
142
|
if (config.provider === "serper" && config.apiKey) {
|
|
99
|
-
results = await searchSerper(query, numResults, config.apiKey);
|
|
143
|
+
results = await searchSerper(query, numResults, config.apiKey, signal);
|
|
100
144
|
}
|
|
101
145
|
else if (config.provider === "tavily" && config.apiKey) {
|
|
102
|
-
results = await searchTavily(query, numResults, config.apiKey);
|
|
146
|
+
results = await searchTavily(query, numResults, config.apiKey, signal);
|
|
103
147
|
}
|
|
104
148
|
else if (config.provider === "searxng" && config.baseUrl) {
|
|
105
|
-
results = await searchSearXNG(query, numResults, config.baseUrl);
|
|
149
|
+
results = await searchSearXNG(query, numResults, config.baseUrl, signal);
|
|
106
150
|
}
|
|
107
151
|
else {
|
|
108
152
|
return `Error: provider "${config.provider}" missing ${config.provider === "searxng" ? "base URL" : "API key"}`;
|
|
@@ -117,7 +161,7 @@ export async function webSearchTool(args) {
|
|
|
117
161
|
return `Search error: ${err.message}`;
|
|
118
162
|
}
|
|
119
163
|
}
|
|
120
|
-
async function searchSerper(query, num, apiKey) {
|
|
164
|
+
async function searchSerper(query, num, apiKey, signal) {
|
|
121
165
|
const res = await fetch("https://google.serper.dev/search", {
|
|
122
166
|
method: "POST",
|
|
123
167
|
headers: {
|
|
@@ -125,6 +169,7 @@ async function searchSerper(query, num, apiKey) {
|
|
|
125
169
|
"Content-Type": "application/json",
|
|
126
170
|
},
|
|
127
171
|
body: JSON.stringify({ q: query, num }),
|
|
172
|
+
signal,
|
|
128
173
|
});
|
|
129
174
|
if (!res.ok)
|
|
130
175
|
throw new Error(`Serper API error: ${res.status} ${res.statusText}`);
|
|
@@ -135,7 +180,7 @@ async function searchSerper(query, num, apiKey) {
|
|
|
135
180
|
snippet: item.snippet ?? "",
|
|
136
181
|
}));
|
|
137
182
|
}
|
|
138
|
-
async function searchTavily(query, num, apiKey) {
|
|
183
|
+
async function searchTavily(query, num, apiKey, signal) {
|
|
139
184
|
const res = await fetch("https://api.tavily.com/search", {
|
|
140
185
|
method: "POST",
|
|
141
186
|
headers: { "Content-Type": "application/json" },
|
|
@@ -145,6 +190,7 @@ async function searchTavily(query, num, apiKey) {
|
|
|
145
190
|
max_results: num,
|
|
146
191
|
include_answer: false,
|
|
147
192
|
}),
|
|
193
|
+
signal,
|
|
148
194
|
});
|
|
149
195
|
if (!res.ok)
|
|
150
196
|
throw new Error(`Tavily API error: ${res.status} ${res.statusText}`);
|
|
@@ -155,13 +201,14 @@ async function searchTavily(query, num, apiKey) {
|
|
|
155
201
|
snippet: item.content ?? "",
|
|
156
202
|
}));
|
|
157
203
|
}
|
|
158
|
-
async function searchSearXNG(query, num, baseUrl) {
|
|
204
|
+
async function searchSearXNG(query, num, baseUrl, signal) {
|
|
159
205
|
const url = new URL("/search", baseUrl);
|
|
160
206
|
url.searchParams.set("q", query);
|
|
161
207
|
url.searchParams.set("format", "json");
|
|
162
208
|
url.searchParams.set("pageno", "1");
|
|
163
209
|
const res = await fetch(url.toString(), {
|
|
164
210
|
headers: { Accept: "application/json" },
|
|
211
|
+
signal,
|
|
165
212
|
});
|
|
166
213
|
if (!res.ok)
|
|
167
214
|
throw new Error(`SearXNG error: ${res.status} ${res.statusText}`);
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
* EnterWorktree / ExitWorktree tools — create and manage isolated git worktrees.
|
|
3
3
|
*/
|
|
4
4
|
import type { ToolDefinition } from "../../types.js";
|
|
5
|
+
import type { ToolContext } from "../context.js";
|
|
5
6
|
import { type WorktreeSession } from "../../git/worktree.js";
|
|
6
7
|
export declare function getActiveWorktree(): WorktreeSession | undefined;
|
|
7
8
|
export declare const enterWorktreeToolDef: ToolDefinition;
|
|
8
|
-
export declare function enterWorktreeTool(args: Record<string, unknown
|
|
9
|
+
export declare function enterWorktreeTool(args: Record<string, unknown>, ctx?: ToolContext): Promise<string>;
|
|
9
10
|
export declare const exitWorktreeToolDef: ToolDefinition;
|
|
10
11
|
export declare function exitWorktreeTool(args: Record<string, unknown>): Promise<string>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* EnterWorktree / ExitWorktree tools — create and manage isolated git worktrees.
|
|
3
3
|
*/
|
|
4
|
-
import { createWorktree, removeWorktree, validateWorktreeSlug, } from "../../git/worktree.js";
|
|
4
|
+
import { createWorktree, removeWorktree, validateWorktreeSlug, selectPlatformScript, runWorktreeSetup, } from "../../git/worktree.js";
|
|
5
5
|
// Global worktree state
|
|
6
6
|
let _activeWorktree;
|
|
7
7
|
export function getActiveWorktree() {
|
|
@@ -25,7 +25,7 @@ export const enterWorktreeToolDef = {
|
|
|
25
25
|
required: ["slug"],
|
|
26
26
|
},
|
|
27
27
|
};
|
|
28
|
-
export async function enterWorktreeTool(args) {
|
|
28
|
+
export async function enterWorktreeTool(args, ctx) {
|
|
29
29
|
const slug = args.slug;
|
|
30
30
|
if (!slug)
|
|
31
31
|
return "Error: slug is required";
|
|
@@ -41,18 +41,45 @@ export async function enterWorktreeTool(args) {
|
|
|
41
41
|
try {
|
|
42
42
|
// Use a placeholder session ID (the agent should set this properly)
|
|
43
43
|
const sessionId = args.__sessionId ?? `wt-${Date.now()}`;
|
|
44
|
-
const cwd = args.__cwd ?? process.cwd();
|
|
44
|
+
const cwd = args.__cwd ?? ctx?.cwd ?? process.cwd();
|
|
45
45
|
_activeWorktree = createWorktree(cwd, slug, sessionId);
|
|
46
|
+
// Run the project's localEnvironment.setupScripts once in the new
|
|
47
|
+
// worktree root (Beta decision 2026-06-08: setup belongs to the worktree
|
|
48
|
+
// lifecycle, not the conversation). Failure warns-but-continues — a broken
|
|
49
|
+
// setup script must not strand the agent outside a worktree it just made.
|
|
50
|
+
let setupNote = "";
|
|
51
|
+
const setupScripts = ctx?.engine?.readWorktreeSetupScripts(cwd);
|
|
52
|
+
const script = selectPlatformScript(setupScripts);
|
|
53
|
+
if (script) {
|
|
54
|
+
const setup = await runWorktreeSetup(_activeWorktree.worktreePath, script, {
|
|
55
|
+
sandbox: ctx?.sandbox,
|
|
56
|
+
shellEnv: ctx?.shellEnv,
|
|
57
|
+
signal: ctx?.signal,
|
|
58
|
+
});
|
|
59
|
+
if (setup.ok) {
|
|
60
|
+
setupNote = `\n\nRan setup script (exit 0).${setup.output ? `\n${truncate(setup.output)}` : ""}`;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
setupNote =
|
|
64
|
+
`\n\n⚠️ Setup script failed (exit ${setup.exitCode ?? "?"}) — continuing anyway. ` +
|
|
65
|
+
`You may need to run setup manually.${setup.output ? `\n${truncate(setup.output)}` : ""}`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
46
68
|
return (`Worktree created:\n` +
|
|
47
69
|
` Path: ${_activeWorktree.worktreePath}\n` +
|
|
48
70
|
` Branch: ${_activeWorktree.worktreeBranch}\n` +
|
|
49
71
|
` From: ${_activeWorktree.originalBranch ?? "HEAD"}\n\n` +
|
|
50
|
-
`You are now working in an isolated copy. Changes here won't affect the main repo.`
|
|
72
|
+
`You are now working in an isolated copy. Changes here won't affect the main repo.` +
|
|
73
|
+
setupNote);
|
|
51
74
|
}
|
|
52
75
|
catch (err) {
|
|
53
76
|
return `Error creating worktree: ${err.message}`;
|
|
54
77
|
}
|
|
55
78
|
}
|
|
79
|
+
/** Keep setup output from bloating the tool result — head+tail-ish trim. */
|
|
80
|
+
function truncate(s, max = 2000) {
|
|
81
|
+
return s.length <= max ? s : `${s.slice(0, max)}\n…(${s.length - max} more chars)`;
|
|
82
|
+
}
|
|
56
83
|
export const exitWorktreeToolDef = {
|
|
57
84
|
name: "ExitWorktree",
|
|
58
85
|
description: "Exit the current worktree and return to the main working directory. " +
|
|
@@ -2,5 +2,6 @@
|
|
|
2
2
|
* Built-in Write file tool.
|
|
3
3
|
*/
|
|
4
4
|
import type { ToolDefinition } from "../../types.js";
|
|
5
|
+
import type { ToolContext } from "../context.js";
|
|
5
6
|
export declare const writeToolDef: ToolDefinition;
|
|
6
|
-
export declare function writeTool(args: Record<string, unknown
|
|
7
|
+
export declare function writeTool(args: Record<string, unknown>, ctx?: ToolContext): Promise<string>;
|