@cjhyy/code-shell-core 0.5.0-rc.2 → 0.6.0-rc.10
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 +3 -0
- package/dist/agent/agent-definition-registry.js +3 -1
- package/dist/agent/agent-definition.d.ts +15 -0
- package/dist/agent/agent-definition.js +27 -3
- package/dist/arena/context/context-tools.js +47 -4
- package/dist/arena/ledger.js +9 -1
- package/dist/arena/strategies/utils.d.ts +1 -4
- package/dist/arena/strategies/utils.js +7 -84
- package/dist/automation/cron-expr.d.ts +10 -0
- package/dist/automation/cron-expr.js +23 -5
- package/dist/automation/runner.d.ts +21 -4
- package/dist/automation/runner.js +48 -12
- package/dist/automation/scheduler.d.ts +38 -0
- package/dist/automation/scheduler.js +89 -12
- package/dist/automation/store.js +5 -2
- package/dist/capability-control/disabled-lists.d.ts +25 -0
- package/dist/capability-control/disabled-lists.js +57 -0
- package/dist/capability-control/overlay.d.ts +15 -0
- package/dist/capability-control/overlay.js +27 -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 +15 -1
- package/dist/cli/agent-server-stdio.js +115 -17
- package/dist/cli/agent-server-tcp.js +40 -26
- package/dist/context/compaction.d.ts +86 -0
- package/dist/context/compaction.js +279 -0
- package/dist/context/manager.d.ts +18 -0
- package/dist/context/manager.js +181 -48
- package/dist/context/token-counter.js +13 -0
- 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/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/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 +280 -141
- package/dist/engine/engine.js +1193 -245
- package/dist/engine/friendly-error.d.ts +18 -0
- package/dist/engine/friendly-error.js +63 -0
- package/dist/engine/goal.d.ts +145 -0
- package/dist/engine/goal.js +144 -0
- package/dist/engine/image-policy.d.ts +13 -0
- package/dist/engine/image-policy.js +24 -0
- package/dist/engine/model-connections-pool.d.ts +17 -0
- package/dist/engine/model-connections-pool.js +67 -0
- package/dist/engine/model-facade.d.ts +10 -0
- package/dist/engine/model-facade.js +15 -0
- package/dist/engine/patch-orphaned-tools.js +3 -0
- package/dist/engine/query.js +2 -0
- package/dist/engine/resolve-llm-config.d.ts +16 -0
- package/dist/engine/resolve-llm-config.js +44 -0
- package/dist/engine/runtime.d.ts +2 -0
- package/dist/engine/runtime.js +27 -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-usage.d.ts +31 -0
- package/dist/engine/session-usage.js +81 -0
- package/dist/engine/steer-queue.d.ts +33 -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 -4
- package/dist/engine/turn-loop.js +432 -54
- 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/utils.d.ts +12 -0
- package/dist/git/utils.js +38 -6
- package/dist/git/worktree.d.ts +48 -0
- package/dist/git/worktree.js +86 -10
- package/dist/hooks/goal-stop-hook.d.ts +28 -0
- package/dist/hooks/goal-stop-hook.js +186 -9
- package/dist/hooks/registry.d.ts +8 -0
- package/dist/hooks/registry.js +19 -0
- package/dist/hooks/shell-runner.js +10 -21
- package/dist/index.d.ts +51 -7
- package/dist/index.js +62 -5
- package/dist/llm/capabilities/param-specs.d.ts +14 -0
- package/dist/llm/capabilities/param-specs.js +62 -0
- package/dist/llm/capabilities/rules.js +5 -1
- package/dist/llm/capabilities/types.d.ts +10 -0
- package/dist/llm/client-base.d.ts +28 -1
- package/dist/llm/client-base.js +119 -13
- package/dist/llm/model-cache.js +4 -2
- package/dist/llm/model-pool.d.ts +21 -0
- package/dist/llm/model-pool.js +21 -1
- package/dist/llm/provider-auth.d.ts +41 -0
- package/dist/llm/provider-auth.js +76 -0
- package/dist/llm/provider-catalog.d.ts +4 -0
- package/dist/llm/providers/anthropic.js +64 -14
- package/dist/llm/providers/openai.d.ts +36 -0
- package/dist/llm/providers/openai.js +257 -51
- package/dist/llm/reasoning-setting.d.ts +3 -3
- package/dist/llm/reasoning-setting.js +9 -1
- package/dist/llm/stream-watchdog.js +5 -1
- package/dist/llm/token-counter.js +9 -2
- package/dist/llm/types.d.ts +4 -0
- package/dist/logging/sanitize-messages.js +22 -0
- package/dist/lsp/manager.d.ts +1 -1
- package/dist/lsp/manager.js +40 -10
- package/dist/model-catalog/builtin.d.ts +12 -0
- package/dist/model-catalog/builtin.js +412 -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 +61 -326
- package/dist/plugins/gitOps.d.ts +19 -0
- package/dist/plugins/gitOps.js +73 -4
- package/dist/plugins/installer/checkUpdate.d.ts +16 -0
- package/dist/plugins/installer/checkUpdate.js +32 -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 +5 -2
- package/dist/plugins/installer/codex/convertMcp.js +45 -5
- package/dist/plugins/installer/install.js +25 -1
- package/dist/plugins/installer/installFromArchive.d.ts +43 -0
- package/dist/plugins/installer/installFromArchive.js +134 -0
- package/dist/plugins/installer/installFromSource.js +8 -2
- package/dist/plugins/installer/loadPluginAgents.js +6 -2
- package/dist/plugins/installer/loadPluginMcp.d.ts +9 -2
- package/dist/plugins/installer/loadPluginMcp.js +35 -2
- package/dist/plugins/installer/pruneDisabled.d.ts +24 -0
- package/dist/plugins/installer/pruneDisabled.js +73 -0
- package/dist/plugins/installer/types.d.ts +5 -2
- package/dist/plugins/installer/types.js +1 -0
- package/dist/plugins/installer/uninstall.js +4 -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 +14 -0
- package/dist/plugins/installer/update.js +53 -21
- package/dist/plugins/loadPluginHooks.d.ts +47 -1
- package/dist/plugins/loadPluginHooks.js +73 -1
- package/dist/plugins/marketplaceManager.d.ts +7 -0
- package/dist/plugins/marketplaceManager.js +20 -0
- package/dist/plugins/pluginCommandHook.js +4 -18
- package/dist/plugins/pluginContent.d.ts +30 -0
- package/dist/plugins/pluginContent.js +83 -0
- package/dist/plugins/pluginInstaller.d.ts +13 -0
- package/dist/plugins/pluginInstaller.js +42 -8
- package/dist/plugins/schemas.js +1 -0
- package/dist/plugins/types.d.ts +6 -0
- package/dist/preset/index.d.ts +11 -1
- package/dist/preset/index.js +115 -6
- package/dist/product/types.d.ts +1 -1
- package/dist/prompt/composer.d.ts +32 -0
- package/dist/prompt/composer.js +75 -21
- package/dist/prompt/instruction-scanner.js +5 -3
- package/dist/prompt/section-loader.js +1 -0
- package/dist/prompt/sections/base.md +2 -0
- package/dist/prompt/sections/browser.md +10 -0
- package/dist/prompt/sections/coding.md +4 -0
- package/dist/protocol/chat-session-manager.d.ts +9 -2
- package/dist/protocol/chat-session-manager.js +38 -0
- package/dist/protocol/chat-session.d.ts +69 -1
- package/dist/protocol/chat-session.js +102 -4
- package/dist/protocol/client.d.ts +31 -0
- package/dist/protocol/client.js +44 -0
- package/dist/protocol/server.d.ts +120 -7
- package/dist/protocol/server.js +753 -51
- package/dist/protocol/transport.js +3 -2
- package/dist/protocol/types.d.ts +60 -0
- package/dist/protocol/types.js +16 -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/review/review-prompt.d.ts +28 -0
- package/dist/review/review-prompt.js +81 -0
- package/dist/run/FileRunStore.js +8 -3
- package/dist/run/RunApprovalBackend.js +25 -5
- package/dist/run/RunManager.d.ts +12 -0
- package/dist/run/RunManager.js +35 -0
- package/dist/run/factory.d.ts +1 -1
- package/dist/runtime/background-shell.d.ts +139 -0
- package/dist/runtime/background-shell.js +509 -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 +98 -39
- package/dist/runtime/spawn-common.d.ts +159 -0
- package/dist/runtime/spawn-common.js +404 -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/diagnostics.d.ts +1 -2
- package/dist/services/diagnostics.js +12 -7
- 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 -50
- package/dist/services/session-memory.js +24 -12
- package/dist/session/file-history.d.ts +124 -1
- package/dist/session/file-history.js +222 -6
- package/dist/session/memory.d.ts +116 -2
- package/dist/session/memory.js +250 -28
- package/dist/session/session-manager.d.ts +40 -0
- package/dist/session/session-manager.js +119 -3
- package/dist/session/simple-diff.d.ts +23 -0
- package/dist/session/simple-diff.js +84 -0
- package/dist/session/transcript.d.ts +29 -1
- package/dist/session/transcript.js +56 -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 +9 -2
- package/dist/settings/disk-defaults.js +11 -2
- package/dist/settings/feature-flags.d.ts +64 -0
- package/dist/settings/feature-flags.js +61 -0
- package/dist/settings/manager.d.ts +68 -1
- package/dist/settings/manager.js +266 -29
- package/dist/settings/migrate-config.d.ts +45 -0
- package/dist/settings/migrate-config.js +125 -0
- package/dist/settings/schema-export.d.ts +25 -0
- package/dist/settings/schema-export.js +38 -0
- package/dist/settings/schema.d.ts +1186 -771
- package/dist/settings/schema.js +268 -97
- 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/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 +12 -0
- package/dist/tool-system/builtin/agent-registry.js +8 -0
- package/dist/tool-system/builtin/agent.d.ts +21 -1
- package/dist/tool-system/builtin/agent.js +489 -42
- 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 +0 -15
- 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 +101 -64
- 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/config.js +7 -0
- package/dist/tool-system/builtin/cron.d.ts +7 -0
- package/dist/tool-system/builtin/cron.js +64 -4
- 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 +104 -0
- package/dist/tool-system/builtin/edit.js +20 -16
- 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 +35 -0
- package/dist/tool-system/builtin/generate-image.js +278 -50
- package/dist/tool-system/builtin/generate-video.d.ts +55 -0
- package/dist/tool-system/builtin/generate-video.js +364 -0
- package/dist/tool-system/builtin/glob.js +0 -7
- package/dist/tool-system/builtin/grep.d.ts +9 -0
- package/dist/tool-system/builtin/grep.js +106 -11
- 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 +10 -2
- package/dist/tool-system/builtin/index.js +251 -27
- 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.js +0 -7
- package/dist/tool-system/builtin/powershell.js +8 -2
- package/dist/tool-system/builtin/read.js +10 -10
- 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 +8 -2
- package/dist/tool-system/builtin/tool-search.js +25 -7
- 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/web-fetch.js +12 -2
- package/dist/tool-system/builtin/web-search.js +21 -7
- 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.js +0 -6
- package/dist/tool-system/context.d.ts +164 -6
- package/dist/tool-system/executor.d.ts +3 -1
- package/dist/tool-system/executor.js +197 -90
- package/dist/tool-system/investigation-guard.js +1 -1
- package/dist/tool-system/mcp-manager.d.ts +42 -4
- package/dist/tool-system/mcp-manager.js +203 -20
- package/dist/tool-system/mcp-stdio-diagnostics.d.ts +9 -0
- package/dist/tool-system/mcp-stdio-diagnostics.js +93 -0
- package/dist/tool-system/path-policy.d.ts +5 -0
- package/dist/tool-system/path-policy.js +307 -8
- package/dist/tool-system/permission.d.ts +39 -2
- package/dist/tool-system/permission.js +283 -70
- package/dist/tool-system/plan-mode-allowlist.d.ts +13 -2
- package/dist/tool-system/plan-mode-allowlist.js +24 -2
- package/dist/tool-system/registry.d.ts +1 -0
- package/dist/tool-system/registry.js +16 -2
- package/dist/tool-system/sandbox/index.d.ts +8 -0
- package/dist/tool-system/sandbox/index.js +7 -2
- package/dist/tool-system/sandbox/off.js +7 -1
- package/dist/tool-system/validate-tool-metadata.d.ts +36 -0
- package/dist/tool-system/validate-tool-metadata.js +63 -0
- package/dist/types.d.ts +252 -7
- 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 +48 -0
- package/dist/utils/exec.js +154 -0
- package/dist/utils/json.d.ts +12 -0
- package/dist/utils/json.js +92 -0
- package/dist/utils/theme.d.ts +1 -1
- package/dist/utils/theme.js +1 -1
- package/dist/utils/toolDisplay.js +0 -1
- package/package.json +13 -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
|
@@ -23,6 +23,7 @@ import { ChatSessionManager } from "../protocol/chat-session-manager.js";
|
|
|
23
23
|
import { AgentServer } from "../protocol/server.js";
|
|
24
24
|
import { listenTcp } from "../protocol/tcp-transport.js";
|
|
25
25
|
import { SettingsManager } from "../settings/manager.js";
|
|
26
|
+
import { computeEffectiveDisabledLists } from "../capability-control/disabled-lists.js";
|
|
26
27
|
import { personalizationFrom } from "../settings/personalization.js";
|
|
27
28
|
import { MCPManager } from "../tool-system/mcp-manager.js";
|
|
28
29
|
import { mergePluginMcpServers } from "../plugins/installer/loadPluginMcp.js";
|
|
@@ -31,18 +32,24 @@ import { HeadlessApprovalBackend } from "../tool-system/permission.js";
|
|
|
31
32
|
import { createRunManager } from "../run/factory.js";
|
|
32
33
|
import { startAutomation } from "../automation/index.js";
|
|
33
34
|
import { CronStore, defaultCronStorePath } from "../automation/store.js";
|
|
35
|
+
import { resolveLLMConfigForTag } from "../engine/resolve-llm-config.js";
|
|
34
36
|
const cwd = process.env.AGENT_CWD ?? process.cwd();
|
|
35
37
|
const port = Number(process.env.AGENT_TCP_PORT ?? "4321");
|
|
36
38
|
const host = process.env.AGENT_TCP_HOST ?? "127.0.0.1";
|
|
37
39
|
const settingsManager = new SettingsManager(cwd, "full");
|
|
40
|
+
// Read once at startup and reuse for every session (see engineFactory below).
|
|
41
|
+
// This is intentional for the TCP host: it's a headless long-running server,
|
|
42
|
+
// so config changes — including `mcpServers` — take effect on restart, not
|
|
43
|
+
// mid-session. (The stdio host re-reads per session via freshSettings(); the
|
|
44
|
+
// difference is by design, not a bug. Assessment §4.8.)
|
|
38
45
|
const settings = settingsManager.get();
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
const seedLlm = resolveLLMConfigForTag(settings, "text", settings.defaults?.text);
|
|
47
|
+
if (!seedLlm) {
|
|
48
|
+
console.error(`[agent-server] 没有可用的文本模型连接(defaults.text=${settings.defaults?.text ?? "未设置"})。` +
|
|
49
|
+
`请在「连接」页添加并填写凭证。`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
const llmConfig = seedLlm;
|
|
46
53
|
// ── Shared runtime (same bootstrap as stdio) ─────────────────────
|
|
47
54
|
const seedEngine = new Engine({ llm: llmConfig, cwd, settingsScope: "full" });
|
|
48
55
|
const modelPool = seedEngine.getModelPool();
|
|
@@ -60,25 +67,32 @@ const runtime = new EngineRuntime({
|
|
|
60
67
|
});
|
|
61
68
|
const chatManager = new ChatSessionManager({
|
|
62
69
|
runtime,
|
|
63
|
-
engineFactory: (slice) =>
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
70
|
+
engineFactory: (slice) => {
|
|
71
|
+
// Fold project capabilityOverrides over the global disabledPlugins for
|
|
72
|
+
// the MCP merge (能力总览 project "on" must override global off) — same
|
|
73
|
+
// contract as the stdio host's factory.
|
|
74
|
+
const sessionCwd = slice.cwd ?? cwd;
|
|
75
|
+
const { disabledPlugins } = computeEffectiveDisabledLists(new SettingsManager(sessionCwd, "full"), sessionCwd);
|
|
76
|
+
return new Engine({
|
|
77
|
+
llm: runtime.modelPool.resolveLLMConfig() ?? resolvedLlmConfig,
|
|
78
|
+
clientDefaults: resolvedClientDefaults,
|
|
79
|
+
cwd,
|
|
80
|
+
runtime,
|
|
81
|
+
settingsScope: "full",
|
|
82
|
+
mcpServers: mergePluginMcpServers(settings.mcpServers ?? {}, disabledPlugins, settings.mcpServerOverrides ?? {}),
|
|
83
|
+
permissionMode: slice.permissionMode,
|
|
84
|
+
preset: slice.preset,
|
|
85
|
+
customSystemPrompt: slice.customSystemPrompt,
|
|
86
|
+
appendSystemPrompt: slice.appendSystemPrompt,
|
|
87
|
+
// Personalization + instruction compat come from disk settings only
|
|
88
|
+
// (not per-request slice overrides) — same disk-only contract as the
|
|
89
|
+
// stdio host. Shared helper keeps the three fields wired identically.
|
|
90
|
+
...personalizationFrom(settings.agent),
|
|
91
|
+
maxTurns: slice.maxTurns,
|
|
92
|
+
maxContextTokens: slice.maxContextTokens,
|
|
93
|
+
...(slice.cwd ? { cwd: slice.cwd } : {}),
|
|
94
|
+
});
|
|
95
|
+
},
|
|
82
96
|
maxSessions: 16,
|
|
83
97
|
idleTtlMs: 30 * 60 * 1000,
|
|
84
98
|
});
|
|
@@ -16,6 +16,54 @@ import type { Message } from "../types.js";
|
|
|
16
16
|
* Uses per-block-type estimation with 33% overhead padding.
|
|
17
17
|
*/
|
|
18
18
|
export declare function estimateTokens(messages: Message[]): number;
|
|
19
|
+
export declare const IMAGE_HISTORY_PLACEHOLDER_PREFIX = "[image #";
|
|
20
|
+
export declare const IMAGE_HISTORY_PLACEHOLDER_SUFFIX = ", \u5DF2\u5904\u7406 / already provided earlier]";
|
|
21
|
+
interface ImagePreserveSet {
|
|
22
|
+
has(message: Message): boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface DowngradeImageHistoryOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Messages whose image payloads are being sent for their first model
|
|
27
|
+
* consumption in this request. They still count toward image numbering but
|
|
28
|
+
* keep their base64 until the caller clears the preserve set after a
|
|
29
|
+
* successful model response.
|
|
30
|
+
*/
|
|
31
|
+
preserveMessages?: ImagePreserveSet;
|
|
32
|
+
}
|
|
33
|
+
export interface DowngradeImageHistoryResult {
|
|
34
|
+
messages: Message[];
|
|
35
|
+
replacedCount: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Replace already-consumed image payload blocks with compact text markers.
|
|
39
|
+
*
|
|
40
|
+
* The transcript may retain the full image bytes for rendering/resume, but the
|
|
41
|
+
* working message history sent to the model should not re-send base64 after the
|
|
42
|
+
* model has seen it once. This handles both our internal Anthropic-style image
|
|
43
|
+
* blocks and OpenAI-style data-url image blocks defensively, including images
|
|
44
|
+
* nested inside tool_result.content arrays (view_image / browser screenshots).
|
|
45
|
+
*/
|
|
46
|
+
export declare function downgradeImagePayloadsInHistory(messages: Message[], options?: DowngradeImageHistoryOptions): DowngradeImageHistoryResult;
|
|
47
|
+
export declare function messageHasBase64ImagePayload(message: Message): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Reconcile user-supplied compaction ratios into a safe ordering.
|
|
50
|
+
*
|
|
51
|
+
* The three tiers must satisfy `floor < compact < summarize` or the manager
|
|
52
|
+
* fires them in the wrong order (e.g. an emergency window-compact before the
|
|
53
|
+
* cheaper summary). Users edit these freely in settings.json, so we clamp
|
|
54
|
+
* rather than trust: summarize is pulled up to at least compact, floor is
|
|
55
|
+
* pushed down to at most compact. Absent fields are left undefined so the
|
|
56
|
+
* ContextManager keeps its own default for them.
|
|
57
|
+
*/
|
|
58
|
+
export declare function clampContextRatios(input: {
|
|
59
|
+
compactAtRatio?: number;
|
|
60
|
+
summarizeAtRatio?: number;
|
|
61
|
+
microcompactFloorRatio?: number;
|
|
62
|
+
}): {
|
|
63
|
+
compactAtRatio?: number;
|
|
64
|
+
summarizeAtRatio?: number;
|
|
65
|
+
microcompactFloorRatio?: number;
|
|
66
|
+
};
|
|
19
67
|
/**
|
|
20
68
|
* Expand a slice start-index backwards so that every tool_result in the
|
|
21
69
|
* kept range has its corresponding tool_use in the kept range too.
|
|
@@ -74,6 +122,43 @@ export interface MicrocompactOptions {
|
|
|
74
122
|
* forced into blind re-Reads (which then trip the Investigation guard).
|
|
75
123
|
*/
|
|
76
124
|
export declare function microcompact(messages: Message[], options?: MicrocompactOptions): Message[];
|
|
125
|
+
export interface DedupeFileReadsResult {
|
|
126
|
+
messages: Message[];
|
|
127
|
+
/** How many stale Read results were cleared. */
|
|
128
|
+
clearedCount: number;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Content-aware dedup: when the SAME file is Read more than once, every Read
|
|
132
|
+
* result except the most recent is stale — the file's current state is in the
|
|
133
|
+
* latest read. Clear the older ones (replace with a fingerprint pointing at
|
|
134
|
+
* the newer read) regardless of the recency window or pressure floor, because
|
|
135
|
+
* this is pure waste removal, not lossy compaction: the model never needs two
|
|
136
|
+
* copies of the same file.
|
|
137
|
+
*
|
|
138
|
+
* Distinct from microcompact (which is recency-gated and pressure-gated): a
|
|
139
|
+
* file Read 3 times in the last 3 turns keeps 3 full copies under microcompact
|
|
140
|
+
* but only the newest under this pass. Zero-cost and always safe to run, so the
|
|
141
|
+
* ContextManager calls it as an early tier.
|
|
142
|
+
*
|
|
143
|
+
* Only `Read` is deduped (its result is exactly the file content). Edit/Write
|
|
144
|
+
* results are diffs/confirmations, not full snapshots, so they're left alone.
|
|
145
|
+
*/
|
|
146
|
+
export declare function dedupeFileReads(messages: Message[]): DedupeFileReadsResult;
|
|
147
|
+
/**
|
|
148
|
+
* Observation masking for browser_observe(snapshot) results (the research's
|
|
149
|
+
* highest-leverage browser-token saving: a page snapshot is large and only the
|
|
150
|
+
* LATEST one matters for the next decision; older ones are stale element lists).
|
|
151
|
+
* Keep the most recent snapshot result verbatim; replace every earlier one with
|
|
152
|
+
* a one-line placeholder. Deterministic — no LLM summarization needed.
|
|
153
|
+
*
|
|
154
|
+
* Keyed on the snapshot OBSERVATION (browser_observe with mode snapshot) — read/
|
|
155
|
+
* extract observations and act results are left untouched. Renamed from
|
|
156
|
+
* maskOldBrowserSnapshots when the 9 browser_* tools collapsed into 3.
|
|
157
|
+
*/
|
|
158
|
+
export declare function maskOldObservations(messages: Message[]): {
|
|
159
|
+
messages: Message[];
|
|
160
|
+
maskedCount: number;
|
|
161
|
+
};
|
|
77
162
|
/**
|
|
78
163
|
* Apply aggregate per-message tool result budget.
|
|
79
164
|
* When total tool_result content in a single message exceeds maxTotalChars,
|
|
@@ -114,3 +199,4 @@ export declare function dropOldestRounds(messages: Message[], roundsToDrop: numb
|
|
|
114
199
|
* messages. Returns paths only — the model uses Read tool on demand.
|
|
115
200
|
*/
|
|
116
201
|
export declare function extractReferencedFilePaths(messages: Message[]): string[];
|
|
202
|
+
export {};
|
|
@@ -18,6 +18,123 @@ import { estimateMessagesTokens } from "./token-counter.js";
|
|
|
18
18
|
export function estimateTokens(messages) {
|
|
19
19
|
return Math.ceil(estimateMessagesTokens(messages) * (4 / 3));
|
|
20
20
|
}
|
|
21
|
+
export const IMAGE_HISTORY_PLACEHOLDER_PREFIX = "[image #";
|
|
22
|
+
export const IMAGE_HISTORY_PLACEHOLDER_SUFFIX = ", 已处理 / already provided earlier]";
|
|
23
|
+
/**
|
|
24
|
+
* Replace already-consumed image payload blocks with compact text markers.
|
|
25
|
+
*
|
|
26
|
+
* The transcript may retain the full image bytes for rendering/resume, but the
|
|
27
|
+
* working message history sent to the model should not re-send base64 after the
|
|
28
|
+
* model has seen it once. This handles both our internal Anthropic-style image
|
|
29
|
+
* blocks and OpenAI-style data-url image blocks defensively, including images
|
|
30
|
+
* nested inside tool_result.content arrays (view_image / browser screenshots).
|
|
31
|
+
*/
|
|
32
|
+
export function downgradeImagePayloadsInHistory(messages, options = {}) {
|
|
33
|
+
let nextImageNumber = 1;
|
|
34
|
+
let replacedCount = 0;
|
|
35
|
+
let changed = false;
|
|
36
|
+
const placeholderFor = (imageNumber) => ({
|
|
37
|
+
type: "text",
|
|
38
|
+
text: `${IMAGE_HISTORY_PLACEHOLDER_PREFIX}${imageNumber}${IMAGE_HISTORY_PLACEHOLDER_SUFFIX}`,
|
|
39
|
+
});
|
|
40
|
+
const transformBlocks = (blocks, preserve) => {
|
|
41
|
+
let blocksChanged = false;
|
|
42
|
+
const out = blocks.map((block) => {
|
|
43
|
+
const placeholderNumber = imageHistoryPlaceholderNumber(block);
|
|
44
|
+
if (placeholderNumber !== undefined) {
|
|
45
|
+
nextImageNumber = Math.max(nextImageNumber, placeholderNumber + 1);
|
|
46
|
+
return block;
|
|
47
|
+
}
|
|
48
|
+
if (isBase64ImageBlock(block)) {
|
|
49
|
+
const imageNumber = nextImageNumber++;
|
|
50
|
+
if (preserve)
|
|
51
|
+
return block;
|
|
52
|
+
replacedCount++;
|
|
53
|
+
blocksChanged = true;
|
|
54
|
+
return placeholderFor(imageNumber);
|
|
55
|
+
}
|
|
56
|
+
if (block.type === "tool_result" && Array.isArray(block.content)) {
|
|
57
|
+
const nested = transformBlocks(block.content, preserve);
|
|
58
|
+
if (nested.changed) {
|
|
59
|
+
blocksChanged = true;
|
|
60
|
+
return { ...block, content: nested.blocks };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return block;
|
|
64
|
+
});
|
|
65
|
+
return { blocks: blocksChanged ? out : blocks, changed: blocksChanged };
|
|
66
|
+
};
|
|
67
|
+
const out = messages.map((msg) => {
|
|
68
|
+
if (!Array.isArray(msg.content))
|
|
69
|
+
return msg;
|
|
70
|
+
const preserve = options.preserveMessages?.has(msg) === true;
|
|
71
|
+
const result = transformBlocks(msg.content, preserve);
|
|
72
|
+
if (!result.changed)
|
|
73
|
+
return msg;
|
|
74
|
+
changed = true;
|
|
75
|
+
return { ...msg, content: result.blocks };
|
|
76
|
+
});
|
|
77
|
+
return { messages: changed ? out : messages, replacedCount };
|
|
78
|
+
}
|
|
79
|
+
export function messageHasBase64ImagePayload(message) {
|
|
80
|
+
if (!Array.isArray(message.content))
|
|
81
|
+
return false;
|
|
82
|
+
return message.content.some(blockHasBase64ImagePayload);
|
|
83
|
+
}
|
|
84
|
+
function blockHasBase64ImagePayload(block) {
|
|
85
|
+
if (isBase64ImageBlock(block))
|
|
86
|
+
return true;
|
|
87
|
+
return (block.type === "tool_result" &&
|
|
88
|
+
Array.isArray(block.content) &&
|
|
89
|
+
block.content.some(blockHasBase64ImagePayload));
|
|
90
|
+
}
|
|
91
|
+
function imageHistoryPlaceholderNumber(block) {
|
|
92
|
+
if (block.type !== "text" || typeof block.text !== "string")
|
|
93
|
+
return undefined;
|
|
94
|
+
const escapedPrefix = IMAGE_HISTORY_PLACEHOLDER_PREFIX.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
95
|
+
const escapedSuffix = IMAGE_HISTORY_PLACEHOLDER_SUFFIX.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
96
|
+
const match = block.text.match(new RegExp(`^${escapedPrefix}(\\d+)${escapedSuffix}$`));
|
|
97
|
+
if (!match?.[1])
|
|
98
|
+
return undefined;
|
|
99
|
+
const n = Number(match[1]);
|
|
100
|
+
return Number.isSafeInteger(n) && n > 0 ? n : undefined;
|
|
101
|
+
}
|
|
102
|
+
function isBase64ImageBlock(block) {
|
|
103
|
+
if (block.type === "image" &&
|
|
104
|
+
block.source?.type === "base64" &&
|
|
105
|
+
typeof block.source.data === "string" &&
|
|
106
|
+
block.source.data.length > 0) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
const maybeOpenAI = block;
|
|
110
|
+
return (maybeOpenAI.type === "image_url" &&
|
|
111
|
+
typeof maybeOpenAI.image_url?.url === "string" &&
|
|
112
|
+
/^data:image\/[^;,]+;base64,/i.test(maybeOpenAI.image_url.url));
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Reconcile user-supplied compaction ratios into a safe ordering.
|
|
116
|
+
*
|
|
117
|
+
* The three tiers must satisfy `floor < compact < summarize` or the manager
|
|
118
|
+
* fires them in the wrong order (e.g. an emergency window-compact before the
|
|
119
|
+
* cheaper summary). Users edit these freely in settings.json, so we clamp
|
|
120
|
+
* rather than trust: summarize is pulled up to at least compact, floor is
|
|
121
|
+
* pushed down to at most compact. Absent fields are left undefined so the
|
|
122
|
+
* ContextManager keeps its own default for them.
|
|
123
|
+
*/
|
|
124
|
+
export function clampContextRatios(input) {
|
|
125
|
+
const compact = input.compactAtRatio;
|
|
126
|
+
const summarize = input.summarizeAtRatio !== undefined && compact !== undefined
|
|
127
|
+
? Math.max(input.summarizeAtRatio, compact)
|
|
128
|
+
: input.summarizeAtRatio;
|
|
129
|
+
const floor = input.microcompactFloorRatio !== undefined && compact !== undefined
|
|
130
|
+
? Math.min(input.microcompactFloorRatio, compact)
|
|
131
|
+
: input.microcompactFloorRatio;
|
|
132
|
+
return {
|
|
133
|
+
compactAtRatio: compact,
|
|
134
|
+
summarizeAtRatio: summarize,
|
|
135
|
+
microcompactFloorRatio: floor,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
21
138
|
// ─── Tool Use / Result Pair Protection ──────────────────────────────
|
|
22
139
|
/**
|
|
23
140
|
* Expand a slice start-index backwards so that every tool_result in the
|
|
@@ -275,6 +392,168 @@ export function microcompact(messages, options = {}) {
|
|
|
275
392
|
}
|
|
276
393
|
return result;
|
|
277
394
|
}
|
|
395
|
+
/** Tools whose result is the content of a single file, keyed by path. */
|
|
396
|
+
const FILE_READ_TOOLS = new Set(["Read"]);
|
|
397
|
+
/**
|
|
398
|
+
* Content-aware dedup: when the SAME file is Read more than once, every Read
|
|
399
|
+
* result except the most recent is stale — the file's current state is in the
|
|
400
|
+
* latest read. Clear the older ones (replace with a fingerprint pointing at
|
|
401
|
+
* the newer read) regardless of the recency window or pressure floor, because
|
|
402
|
+
* this is pure waste removal, not lossy compaction: the model never needs two
|
|
403
|
+
* copies of the same file.
|
|
404
|
+
*
|
|
405
|
+
* Distinct from microcompact (which is recency-gated and pressure-gated): a
|
|
406
|
+
* file Read 3 times in the last 3 turns keeps 3 full copies under microcompact
|
|
407
|
+
* but only the newest under this pass. Zero-cost and always safe to run, so the
|
|
408
|
+
* ContextManager calls it as an early tier.
|
|
409
|
+
*
|
|
410
|
+
* Only `Read` is deduped (its result is exactly the file content). Edit/Write
|
|
411
|
+
* results are diffs/confirmations, not full snapshots, so they're left alone.
|
|
412
|
+
*/
|
|
413
|
+
export function dedupeFileReads(messages) {
|
|
414
|
+
const idToName = buildToolUseIdToNameMap(messages);
|
|
415
|
+
const idToInput = new Map();
|
|
416
|
+
for (const msg of messages) {
|
|
417
|
+
if (!Array.isArray(msg.content))
|
|
418
|
+
continue;
|
|
419
|
+
for (const block of msg.content) {
|
|
420
|
+
if (block.type === "tool_use" && block.id)
|
|
421
|
+
idToInput.set(block.id, block.input);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
// Resolve a Read tool_use_id to its file_path arg (the dedup key).
|
|
425
|
+
const pathOf = (toolUseId) => {
|
|
426
|
+
const input = idToInput.get(toolUseId);
|
|
427
|
+
const p = input?.file_path ?? input?.path;
|
|
428
|
+
return typeof p === "string" && p.length > 0 ? p : undefined;
|
|
429
|
+
};
|
|
430
|
+
// Collect, per file path, the message indices + block positions of every
|
|
431
|
+
// non-cleared Read result. Walk forward so "last" is the newest.
|
|
432
|
+
const byPath = new Map();
|
|
433
|
+
for (let i = 0; i < messages.length; i++) {
|
|
434
|
+
const msg = messages[i];
|
|
435
|
+
if (!Array.isArray(msg.content))
|
|
436
|
+
continue;
|
|
437
|
+
for (const block of msg.content) {
|
|
438
|
+
if (block.type !== "tool_result" || !block.tool_use_id)
|
|
439
|
+
continue;
|
|
440
|
+
if (!FILE_READ_TOOLS.has(idToName.get(block.tool_use_id) ?? ""))
|
|
441
|
+
continue;
|
|
442
|
+
if (typeof block.content !== "string")
|
|
443
|
+
continue;
|
|
444
|
+
if (block.content.startsWith("[Old tool result cleared"))
|
|
445
|
+
continue;
|
|
446
|
+
const path = pathOf(block.tool_use_id);
|
|
447
|
+
if (!path)
|
|
448
|
+
continue;
|
|
449
|
+
const list = byPath.get(path) ?? [];
|
|
450
|
+
list.push({ msgIdx: i, toolUseId: block.tool_use_id });
|
|
451
|
+
byPath.set(path, list);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
// For each path read more than once, mark all-but-last for clearing.
|
|
455
|
+
const clearIds = new Set();
|
|
456
|
+
for (const [, reads] of byPath) {
|
|
457
|
+
if (reads.length < 2)
|
|
458
|
+
continue;
|
|
459
|
+
for (let k = 0; k < reads.length - 1; k++)
|
|
460
|
+
clearIds.add(reads[k].toolUseId);
|
|
461
|
+
}
|
|
462
|
+
if (clearIds.size === 0)
|
|
463
|
+
return { messages, clearedCount: 0 };
|
|
464
|
+
let clearedCount = 0;
|
|
465
|
+
const result = messages.map((msg) => {
|
|
466
|
+
if (!Array.isArray(msg.content))
|
|
467
|
+
return msg;
|
|
468
|
+
return {
|
|
469
|
+
...msg,
|
|
470
|
+
content: msg.content.map((block) => {
|
|
471
|
+
if (block.type !== "tool_result" || !block.tool_use_id)
|
|
472
|
+
return block;
|
|
473
|
+
if (!clearIds.has(block.tool_use_id))
|
|
474
|
+
return block;
|
|
475
|
+
const argsSummary = summarizeToolCallArgs("Read", idToInput.get(block.tool_use_id));
|
|
476
|
+
clearedCount++;
|
|
477
|
+
return {
|
|
478
|
+
...block,
|
|
479
|
+
content: `[Old tool result cleared — superseded by a newer Read${argsSummary ? ` of ${argsSummary}` : ""}]`,
|
|
480
|
+
};
|
|
481
|
+
}),
|
|
482
|
+
};
|
|
483
|
+
});
|
|
484
|
+
return { messages: result, clearedCount };
|
|
485
|
+
}
|
|
486
|
+
/** Build id → true for tool_use blocks that are a browser snapshot observation,
|
|
487
|
+
* i.e. `browser_observe` with mode "snapshot" (the default when mode omitted).
|
|
488
|
+
* Only snapshots produce large, supersede-able element lists worth masking. */
|
|
489
|
+
function buildSnapshotObserveIdSet(messages) {
|
|
490
|
+
const ids = new Set();
|
|
491
|
+
for (const msg of messages) {
|
|
492
|
+
if (!Array.isArray(msg.content))
|
|
493
|
+
continue;
|
|
494
|
+
for (const block of msg.content) {
|
|
495
|
+
if (block.type !== "tool_use" || !block.id || block.name !== "browser_observe")
|
|
496
|
+
continue;
|
|
497
|
+
const mode = block.input?.mode;
|
|
498
|
+
if (mode === undefined || mode === "snapshot")
|
|
499
|
+
ids.add(block.id);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
return ids;
|
|
503
|
+
}
|
|
504
|
+
const OLD_SNAPSHOT_PLACEHOLDER = "[Old browser snapshot collapsed — superseded by a newer browser_observe(snapshot). " +
|
|
505
|
+
"Re-run browser_observe for the current page's elements.]";
|
|
506
|
+
/**
|
|
507
|
+
* Observation masking for browser_observe(snapshot) results (the research's
|
|
508
|
+
* highest-leverage browser-token saving: a page snapshot is large and only the
|
|
509
|
+
* LATEST one matters for the next decision; older ones are stale element lists).
|
|
510
|
+
* Keep the most recent snapshot result verbatim; replace every earlier one with
|
|
511
|
+
* a one-line placeholder. Deterministic — no LLM summarization needed.
|
|
512
|
+
*
|
|
513
|
+
* Keyed on the snapshot OBSERVATION (browser_observe with mode snapshot) — read/
|
|
514
|
+
* extract observations and act results are left untouched. Renamed from
|
|
515
|
+
* maskOldBrowserSnapshots when the 9 browser_* tools collapsed into 3.
|
|
516
|
+
*/
|
|
517
|
+
export function maskOldObservations(messages) {
|
|
518
|
+
const snapshotIds = buildSnapshotObserveIdSet(messages);
|
|
519
|
+
const snapResults = [];
|
|
520
|
+
for (const msg of messages) {
|
|
521
|
+
if (!Array.isArray(msg.content))
|
|
522
|
+
continue;
|
|
523
|
+
for (const block of msg.content) {
|
|
524
|
+
if (block.type !== "tool_result" || !block.tool_use_id)
|
|
525
|
+
continue;
|
|
526
|
+
if (!snapshotIds.has(block.tool_use_id))
|
|
527
|
+
continue;
|
|
528
|
+
if (typeof block.content !== "string")
|
|
529
|
+
continue;
|
|
530
|
+
if (block.content.startsWith("[Old browser snapshot collapsed"))
|
|
531
|
+
continue;
|
|
532
|
+
snapResults.push(block.tool_use_id);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
if (snapResults.length < 2)
|
|
536
|
+
return { messages, maskedCount: 0 };
|
|
537
|
+
// Mask all but the last (newest walked-forward).
|
|
538
|
+
const maskIds = new Set(snapResults.slice(0, -1));
|
|
539
|
+
let maskedCount = 0;
|
|
540
|
+
const result = messages.map((msg) => {
|
|
541
|
+
if (!Array.isArray(msg.content))
|
|
542
|
+
return msg;
|
|
543
|
+
return {
|
|
544
|
+
...msg,
|
|
545
|
+
content: msg.content.map((block) => {
|
|
546
|
+
if (block.type !== "tool_result" || !block.tool_use_id)
|
|
547
|
+
return block;
|
|
548
|
+
if (!maskIds.has(block.tool_use_id))
|
|
549
|
+
return block;
|
|
550
|
+
maskedCount++;
|
|
551
|
+
return { ...block, content: OLD_SNAPSHOT_PLACEHOLDER };
|
|
552
|
+
}),
|
|
553
|
+
};
|
|
554
|
+
});
|
|
555
|
+
return { messages: result, maskedCount };
|
|
556
|
+
}
|
|
278
557
|
/**
|
|
279
558
|
* Apply aggregate per-message tool result budget.
|
|
280
559
|
* When total tool_result content in a single message exceeds maxTotalChars,
|
|
@@ -41,6 +41,8 @@ export declare class ContextManager {
|
|
|
41
41
|
private config;
|
|
42
42
|
private summarizeFn;
|
|
43
43
|
private consecutiveSummaryFailures;
|
|
44
|
+
/** Prevents repeated spin-band LLM calls after a summary generated no shrink. */
|
|
45
|
+
private suppressNoOpMicroSummaryUntilCompact;
|
|
44
46
|
private lastSummary;
|
|
45
47
|
/** Last known actual token count from API usage data. */
|
|
46
48
|
private lastActualTokens;
|
|
@@ -73,6 +75,7 @@ export declare class ContextManager {
|
|
|
73
75
|
* Set the summarize function (injected by Engine).
|
|
74
76
|
*/
|
|
75
77
|
setSummarizeFn(fn: SummarizeFn): void;
|
|
78
|
+
private trySummaryCompact;
|
|
76
79
|
/**
|
|
77
80
|
* Set the transcript path so compaction can reference it. The
|
|
78
81
|
* tool-results directory lives alongside the transcript file:
|
|
@@ -97,6 +100,21 @@ export declare class ContextManager {
|
|
|
97
100
|
* Call this when you have access to the LLM (between turns).
|
|
98
101
|
*/
|
|
99
102
|
manageAsync(messages: Message[]): Promise<Message[]>;
|
|
103
|
+
/**
|
|
104
|
+
* Force maximum compaction, ignoring the ratio gates. This is what a manual
|
|
105
|
+
* `/compact` invokes: the user explicitly asked to shrink NOW, so we don't
|
|
106
|
+
* wait for the prompt to reach compactAtRatio.
|
|
107
|
+
*
|
|
108
|
+
* Order: tier-0 cleanups (persist/truncate/dedupe/mask) + microcompact, then
|
|
109
|
+
* an unconditional LLM summary of the older messages. If no summarizeFn is
|
|
110
|
+
* wired (or it fails / yields nothing), fall back to snip → window so the
|
|
111
|
+
* call still shrinks the conversation rather than no-opping.
|
|
112
|
+
*
|
|
113
|
+
* Unlike manage()/manageAsync(), there is NO `ratio >= compactAtRatio` gate:
|
|
114
|
+
* a long-but-under-threshold text-only conversation (the /compact bug) still
|
|
115
|
+
* gets summarized here.
|
|
116
|
+
*/
|
|
117
|
+
forceSummarize(messages: Message[]): Promise<Message[]>;
|
|
100
118
|
/**
|
|
101
119
|
* Persist large tool_result blocks to disk and replace them with a
|
|
102
120
|
* preview + filepath. No-op when transcript path hasn't been set
|