@vellumai/assistant 0.6.5 → 0.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +9 -1
- package/ARCHITECTURE.md +15 -17
- package/Dockerfile +6 -4
- package/__tests__/permissions/gateway-threshold-reader.test.ts +283 -0
- package/docs/architecture/integrations.md +32 -39
- package/docs/architecture/memory.md +25 -30
- package/docs/architecture/security.md +7 -6
- package/docs/browser-use-architecture-phase2.md +63 -20
- package/docs/plugins.md +761 -0
- package/examples/plugins/echo/README.md +132 -0
- package/examples/plugins/echo/package.json +17 -0
- package/examples/plugins/echo/register.ts +187 -0
- package/node_modules/@vellumai/egress-proxy/src/types.ts +19 -0
- package/openapi.yaml +212 -68
- package/package.json +1 -1
- package/src/__tests__/app-compiler.test.ts +57 -0
- package/src/__tests__/approval-cascade.test.ts +7 -2
- package/src/__tests__/auto-analysis-end-to-end.test.ts +1 -0
- package/src/__tests__/avatar-generator.test.ts +4 -2
- package/src/__tests__/bundled-asset.test.ts +6 -6
- package/src/__tests__/catalog-cache.test.ts +69 -0
- package/src/__tests__/checker.test.ts +459 -171
- package/src/__tests__/circuit-breaker-pipeline.test.ts +406 -0
- package/src/__tests__/compaction-events.test.ts +501 -0
- package/src/__tests__/compaction-pipeline.test.ts +210 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +181 -0
- package/src/__tests__/compaction-timeout-recovery.test.ts +262 -0
- package/src/__tests__/config-model-image-provider.test.ts +110 -0
- package/src/__tests__/config-schema.test.ts +22 -9
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +0 -4
- package/src/__tests__/contacts-tools.test.ts +26 -0
- package/src/__tests__/context-overflow-policy.test.ts +7 -7
- package/src/__tests__/context-window-manager.test.ts +355 -4
- package/src/__tests__/conversation-abort-tool-results.test.ts +4 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +26 -30
- package/src/__tests__/conversation-agent-loop.test.ts +30 -141
- package/src/__tests__/conversation-confirmation-signals.test.ts +6 -1
- package/src/__tests__/conversation-history-web-search.test.ts +1 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +2 -16
- package/src/__tests__/conversation-pairing.test.ts +174 -10
- package/src/__tests__/conversation-pre-run-repair.test.ts +4 -1
- package/src/__tests__/conversation-process-callsite.test.ts +3 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +16 -7
- package/src/__tests__/conversation-queue.test.ts +29 -14
- package/src/__tests__/conversation-routes-disk-view.test.ts +7 -6
- package/src/__tests__/conversation-runtime-assembly.test.ts +155 -110
- package/src/__tests__/conversation-runtime-workspace.test.ts +23 -38
- package/src/__tests__/conversation-seed-composer.test.ts +2 -2
- package/src/__tests__/conversation-slash-queue.test.ts +7 -2
- package/src/__tests__/conversation-slash-unknown.test.ts +25 -2
- package/src/__tests__/conversation-speed-override.test.ts +6 -1
- package/src/__tests__/conversation-title-service.test.ts +116 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +41 -2
- package/src/__tests__/conversation-usage.test.ts +1 -1
- package/src/__tests__/conversation-workspace-cache-state.test.ts +4 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +3 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +4 -1
- package/src/__tests__/credential-health-service.test.ts +78 -9
- package/src/__tests__/credential-security-invariants.test.ts +2 -2
- package/src/__tests__/db-schedule-syntax-migration.test.ts +1 -0
- package/src/__tests__/empty-response-pipeline.test.ts +305 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +3 -3
- package/src/__tests__/first-greeting.test.ts +247 -5
- package/src/__tests__/headless-browser-mode.test.ts +57 -0
- package/src/__tests__/history-repair-pipeline.test.ts +399 -0
- package/src/__tests__/host-browser-e2e-cloud.test.ts +307 -0
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +3 -3
- package/src/__tests__/host-proxy-interface.test.ts +36 -2
- package/src/__tests__/image-credentials.test.ts +137 -0
- package/src/__tests__/image-service-dispatcher.test.ts +186 -0
- package/src/__tests__/injector-chain.test.ts +526 -0
- package/src/__tests__/intent-routing.test.ts +0 -26
- package/src/__tests__/llm-call-pipeline.test.ts +285 -0
- package/src/__tests__/llm-schema.test.ts +1 -1
- package/src/__tests__/media-generate-image.test.ts +119 -13
- package/src/__tests__/memory-retrieval-pipeline.test.ts +401 -0
- package/src/__tests__/memory-upsert-concurrency.test.ts +1 -0
- package/src/__tests__/migration-import-from-url.test.ts +5 -68
- package/src/__tests__/model-intents.test.ts +4 -2
- package/src/__tests__/notification-broadcaster.test.ts +3 -3
- package/src/__tests__/notification-decision-strategy.test.ts +0 -11
- package/src/__tests__/notification-schedule-notify-dedup.test.ts +108 -0
- package/src/__tests__/oauth-apps-routes.test.ts +1 -1
- package/src/__tests__/oauth-cli.test.ts +14 -12
- package/src/__tests__/oauth-connect-orchestrator.test.ts +4 -13
- package/src/__tests__/oauth-provider-serializer.test.ts +6 -4
- package/src/__tests__/oauth-provider-visibility.test.ts +3 -5
- package/src/__tests__/oauth-providers-routes.test.ts +3 -2
- package/src/__tests__/oauth-store.test.ts +41 -76
- package/src/__tests__/onboarding-template-contract.test.ts +16 -64
- package/src/__tests__/openai-image-service.test.ts +368 -0
- package/src/__tests__/overflow-reduce-pipeline.test.ts +676 -0
- package/src/__tests__/permission-checker-host-gate.test.ts +0 -24
- package/src/__tests__/persist-onboarding-artifacts.test.ts +266 -0
- package/src/__tests__/persistence-pipeline.test.ts +377 -0
- package/src/__tests__/pipeline-runner.test.ts +565 -0
- package/src/__tests__/platform.test.ts +5 -2
- package/src/__tests__/plugin-bootstrap.test.ts +483 -0
- package/src/__tests__/plugin-registry.test.ts +273 -0
- package/src/__tests__/plugin-route-contribution.test.ts +288 -0
- package/src/__tests__/plugin-skill-contribution.test.ts +367 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +286 -0
- package/src/__tests__/plugin-types.test.ts +320 -0
- package/src/__tests__/pricing.test.ts +44 -12
- package/src/__tests__/proxy-approval-callback.test.ts +69 -8
- package/src/__tests__/reaction-persistence.test.ts +1 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +0 -2
- package/src/__tests__/schedule-routes.test.ts +131 -1
- package/src/__tests__/scheduler-recurrence.test.ts +14 -70
- package/src/__tests__/scheduler-reuse-conversation.test.ts +10 -50
- package/src/__tests__/secret-detection-handler.test.ts +0 -10
- package/src/__tests__/shell-identity.test.ts +0 -134
- package/src/__tests__/suggestion-routes.test.ts +103 -4
- package/src/__tests__/task-memory-cleanup.test.ts +1 -0
- package/src/__tests__/task-scheduler.test.ts +3 -15
- package/src/__tests__/test-preload.ts +11 -0
- package/src/__tests__/title-generate-pipeline.test.ts +224 -0
- package/src/__tests__/token-estimate-pipeline.test.ts +431 -0
- package/src/__tests__/tool-error-pipeline.test.ts +244 -0
- package/src/__tests__/tool-execute-pipeline.test.ts +431 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -6
- package/src/__tests__/tool-executor-shell-integration.test.ts +7 -10
- package/src/__tests__/tool-executor.test.ts +141 -0
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +356 -0
- package/src/__tests__/tool-result-truncation.test.ts +0 -110
- package/src/__tests__/user-plugin-loader.test.ts +191 -0
- package/src/__tests__/workspace-migration-046-seed-conversation-starters-callsite.test.ts +185 -0
- package/src/__tests__/workspace-migration-049-release-notes-default-sonnet.test.ts +100 -0
- package/src/__tests__/workspace-migration-050-seed-main-agent-opus-callsite.test.ts +171 -0
- package/src/__tests__/workspace-migration-051-seed-conversation-summarization-callsite.test.ts +252 -0
- package/src/__tests__/workspace-migration-remove-hooks.test.ts +99 -0
- package/src/__tests__/workspace-policy.test.ts +21 -3
- package/src/agent/loop.ts +340 -102
- package/src/approvals/__tests__/guardian-feed-event.test.ts +304 -0
- package/src/approvals/guardian-request-resolvers.ts +80 -0
- package/src/backup/__tests__/backup-worker.test.ts +2 -13
- package/src/backup/backup-worker.ts +3 -15
- package/src/bundler/app-compiler.ts +84 -1
- package/src/calls/call-state.ts +2 -2
- package/src/channels/__tests__/types.test.ts +3 -3
- package/src/channels/types.ts +6 -4
- package/src/cli/__tests__/notifications.test.ts +87 -211
- package/src/cli/commands/__tests__/backup.test.ts +1 -1
- package/src/cli/commands/__tests__/image-generation.test.ts +255 -35
- package/src/cli/commands/__tests__/inference-send.test.ts +12 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +12 -0
- package/src/cli/commands/backup.ts +2 -2
- package/src/cli/commands/clients.ts +138 -0
- package/src/cli/commands/completions.ts +2 -9
- package/src/cli/commands/conversations.ts +55 -7
- package/src/cli/commands/image-generation.ts +33 -34
- package/src/cli/commands/notifications.ts +68 -103
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +1 -1
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -1
- package/src/cli/commands/oauth/connect.ts +2 -2
- package/src/cli/commands/oauth/providers.ts +176 -8
- package/src/cli/commands/oauth/status.ts +46 -36
- package/src/cli/commands/skills.ts +3 -4
- package/src/cli/program.ts +25 -29
- package/src/config/__tests__/backup-schema.test.ts +7 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +10 -10
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +66 -87
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +28 -51
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +22 -40
- package/src/config/bundled-skills/image-studio/SKILL.md +2 -1
- package/src/config/bundled-skills/image-studio/TOOLS.json +2 -1
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +23 -39
- package/src/config/bundled-skills/messaging/SKILL.md +3 -3
- package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +207 -0
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +12 -0
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +58 -0
- package/src/config/bundled-skills/schedule/SKILL.md +8 -3
- package/src/config/bundled-skills/schedule/TOOLS.json +15 -7
- package/src/config/bundled-skills/schedule/references/SCRIPT_MODE_PATTERNS.md +59 -0
- package/src/config/bundled-tool-registry.ts +0 -15
- package/src/config/feature-flag-registry.json +17 -1
- package/src/config/schema.ts +19 -0
- package/src/config/schemas/backup.ts +1 -1
- package/src/config/schemas/conversations.ts +16 -0
- package/src/config/schemas/llm.ts +2 -3
- package/src/config/schemas/security.ts +6 -6
- package/src/config/schemas/tts.ts +11 -0
- package/src/config/skill-state.ts +6 -2
- package/src/config/skills.ts +94 -5
- package/src/context/__tests__/compact-prompt.test.ts +27 -9
- package/src/context/prompts/compact.md +26 -12
- package/src/context/tool-result-truncation.ts +3 -63
- package/src/context/window-manager.ts +190 -16
- package/src/credential-health/credential-health-service.ts +19 -6
- package/src/daemon/__tests__/conversation-feed-event.test.ts +317 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +4 -12
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +14 -15
- package/src/daemon/config-watcher.ts +0 -2
- package/src/daemon/context-overflow-policy.ts +4 -13
- package/src/daemon/conversation-agent-loop-handlers.ts +83 -22
- package/src/daemon/conversation-agent-loop.ts +984 -683
- package/src/daemon/conversation-history.ts +10 -19
- package/src/daemon/conversation-lifecycle.ts +37 -19
- package/src/daemon/conversation-notifiers.ts +2 -110
- package/src/daemon/conversation-process.ts +14 -7
- package/src/daemon/conversation-runtime-assembly.ts +532 -411
- package/src/daemon/conversation-tool-setup.ts +41 -4
- package/src/daemon/conversation.ts +80 -35
- package/src/daemon/external-plugins-bootstrap.ts +478 -0
- package/src/daemon/first-greeting.ts +191 -14
- package/src/daemon/handlers/config-model.ts +11 -0
- package/src/daemon/handlers/skills.ts +5 -1
- package/src/daemon/lifecycle.ts +33 -68
- package/src/daemon/message-types/computer-use.ts +2 -34
- package/src/daemon/message-types/conversations.ts +49 -0
- package/src/daemon/message-types/messages.ts +12 -0
- package/src/daemon/server.ts +5 -3
- package/src/daemon/shutdown-handlers.ts +2 -12
- package/src/daemon/tool-side-effects.ts +14 -56
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +160 -0
- package/src/heartbeat/heartbeat-service.ts +24 -1
- package/src/home/__tests__/feed-population-integration.test.ts +312 -0
- package/src/home/emit-feed-event.ts +7 -0
- package/src/home/feed-types.ts +41 -2
- package/src/home/rewrite-command-preview.ts +66 -0
- package/src/ipc/__tests__/socket-path.test.ts +11 -50
- package/src/ipc/cli-client.ts +1 -1
- package/src/ipc/cli-server.ts +3 -3
- package/src/ipc/gateway-client.ts +4 -1
- package/src/ipc/routes/browser-context.ts +2 -0
- package/src/ipc/routes/browser.ts +1 -0
- package/src/ipc/routes/get-contact.ts +16 -0
- package/src/ipc/routes/index.ts +14 -0
- package/src/ipc/routes/list-clients.ts +31 -0
- package/src/ipc/routes/merge-contacts.ts +17 -0
- package/src/ipc/routes/notification.ts +133 -0
- package/src/ipc/routes/rename-conversation.ts +59 -0
- package/src/ipc/routes/search-contacts.ts +19 -0
- package/src/ipc/routes/upsert-contact.ts +25 -0
- package/src/ipc/socket-path.ts +14 -38
- package/src/media/app-icon-generator.ts +23 -46
- package/src/media/avatar-router.ts +26 -41
- package/src/media/gemini-image-service.ts +8 -41
- package/src/media/image-credentials.ts +73 -0
- package/src/media/image-service.ts +85 -0
- package/src/media/openai-image-service.ts +131 -0
- package/src/media/types.ts +46 -0
- package/src/memory/conversation-crud.ts +48 -18
- package/src/memory/conversation-queries.ts +57 -4
- package/src/memory/conversation-title-service.ts +25 -0
- package/src/memory/db-init.ts +8 -0
- package/src/memory/embedding-gemini.test.ts +41 -2
- package/src/memory/embedding-gemini.ts +6 -1
- package/src/memory/graph/bootstrap.test.ts +282 -0
- package/src/memory/graph/bootstrap.ts +8 -5
- package/src/memory/graph/extraction.ts +10 -2
- package/src/memory/graph/graph-search.test.ts +1 -0
- package/src/memory/graph/inspect.ts +2 -2
- package/src/memory/graph/retriever.ts +10 -3
- package/src/memory/migrations/041-approval-prompt-ts-tracker.ts +26 -0
- package/src/memory/migrations/149-oauth-tables.ts +1 -0
- package/src/memory/migrations/223-schedule-script-column.ts +11 -0
- package/src/memory/migrations/224-oauth-providers-managed-service-is-paid.ts +24 -0
- package/src/memory/migrations/225-oauth-providers-available-scopes.ts +13 -0
- package/src/memory/migrations/index.ts +4 -0
- package/src/memory/pkb/pkb-index.test.ts +1 -0
- package/src/memory/pkb/pkb-reconcile.test.ts +1 -0
- package/src/memory/pkb/pkb-search.test.ts +65 -4
- package/src/memory/pkb/pkb-search.ts +40 -18
- package/src/memory/qdrant-client.test.ts +60 -0
- package/src/memory/qdrant-client.ts +25 -0
- package/src/memory/schema/infrastructure.ts +1 -0
- package/src/memory/schema/oauth.ts +4 -1
- package/src/messaging/providers/slack/render-transcript.test.ts +77 -29
- package/src/messaging/providers/slack/render-transcript.ts +58 -0
- package/src/notifications/conversation-pairing.ts +78 -19
- package/src/notifications/copy-composer.ts +0 -5
- package/src/notifications/emit-signal.ts +1 -1
- package/src/notifications/signal.ts +1 -2
- package/src/oauth/AGENTS.md +1 -1
- package/src/oauth/__tests__/identity-verifier.test.ts +2 -1
- package/src/oauth/connect-orchestrator.ts +8 -34
- package/src/oauth/connect-types.ts +6 -10
- package/src/oauth/manual-token-connection.ts +23 -0
- package/src/oauth/oauth-store.ts +30 -14
- package/src/oauth/provider-serializer.ts +6 -1
- package/src/oauth/seed-providers.ts +56 -108
- package/src/outbound-proxy/http-forwarder.ts +9 -0
- package/src/permissions/approval-policy.test.ts +293 -18
- package/src/permissions/approval-policy.ts +110 -58
- package/src/permissions/arg-parser.test.ts +161 -0
- package/src/permissions/arg-parser.ts +141 -0
- package/src/permissions/bash-risk-classifier.test.ts +414 -2
- package/src/permissions/bash-risk-classifier.ts +303 -60
- package/src/permissions/checker.ts +157 -29
- package/src/permissions/command-registry.test.ts +239 -0
- package/src/permissions/command-registry.ts +234 -54
- package/src/permissions/defaults.ts +5 -4
- package/src/permissions/gateway-threshold-reader.ts +196 -0
- package/src/permissions/prompter.ts +4 -0
- package/src/permissions/risk-types.ts +61 -4
- package/src/permissions/schedule-risk-classifier.test.ts +129 -0
- package/src/permissions/schedule-risk-classifier.ts +85 -0
- package/src/permissions/shell-identity.ts +2 -42
- package/src/permissions/types.ts +2 -0
- package/src/permissions/workspace-policy.ts +8 -3
- package/src/plugins/defaults/circuit-breaker.ts +146 -0
- package/src/plugins/defaults/compaction.ts +145 -0
- package/src/plugins/defaults/empty-response.ts +126 -0
- package/src/plugins/defaults/history-repair.ts +85 -0
- package/src/plugins/defaults/index.ts +116 -0
- package/src/plugins/defaults/injectors.ts +491 -0
- package/src/plugins/defaults/llm-call.ts +82 -0
- package/src/plugins/defaults/memory-retrieval.ts +226 -0
- package/src/plugins/defaults/overflow-reduce.ts +181 -0
- package/src/plugins/defaults/persistence.ts +129 -0
- package/src/plugins/defaults/title-generate.ts +95 -0
- package/src/plugins/defaults/token-estimate.ts +104 -0
- package/src/plugins/defaults/tool-error.ts +126 -0
- package/src/plugins/defaults/tool-execute.ts +89 -0
- package/src/plugins/defaults/tool-result-truncate.ts +88 -0
- package/src/plugins/pipeline.ts +316 -0
- package/src/plugins/plugin-skill-contributions.ts +292 -0
- package/src/plugins/registry.ts +241 -0
- package/src/plugins/types.ts +1134 -0
- package/src/plugins/user-loader.ts +177 -0
- package/src/prompts/templates/BOOTSTRAP.md +27 -77
- package/src/providers/model-catalog.ts +52 -29
- package/src/providers/model-intents.ts +1 -1
- package/src/providers/openrouter/client.ts +5 -1
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +61 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +57 -0
- package/src/providers/speech-to-text/xai-realtime.test.ts +72 -4
- package/src/providers/speech-to-text/xai-realtime.ts +39 -14
- package/src/runtime/AGENTS.md +25 -16
- package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +3 -3
- package/src/runtime/__tests__/client-registry.test.ts +293 -0
- package/src/runtime/client-registry.ts +261 -0
- package/src/runtime/http-server.ts +77 -8
- package/src/runtime/http-types.ts +0 -2
- package/src/runtime/migrations/vbundle-builder.ts +1 -22
- package/src/runtime/routes/approval-prompt-ts-tracker.ts +51 -31
- package/src/runtime/routes/approval-routes.ts +17 -0
- package/src/runtime/routes/browser-extension-pair-routes.ts +27 -8
- package/src/runtime/routes/conversation-routes.ts +223 -116
- package/src/runtime/routes/inbound-message-handler.ts +88 -13
- package/src/runtime/routes/memory-item-routes.test.ts +1 -0
- package/src/runtime/routes/migration-routes.ts +0 -3
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +284 -0
- package/src/runtime/routes/playground/__tests__/guard.test.ts +80 -0
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +294 -0
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +271 -0
- package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +202 -0
- package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +309 -0
- package/src/runtime/routes/playground/__tests__/state.test.ts +224 -0
- package/src/runtime/routes/playground/conversation-not-found.ts +29 -0
- package/src/runtime/routes/playground/deps.ts +56 -0
- package/src/runtime/routes/playground/force-compact.ts +73 -0
- package/src/runtime/routes/playground/guard.ts +37 -0
- package/src/runtime/routes/playground/index.ts +28 -0
- package/src/runtime/routes/playground/inject-failures.ts +159 -0
- package/src/runtime/routes/playground/reset-circuit.ts +115 -0
- package/src/runtime/routes/playground/seed-conversation.ts +139 -0
- package/src/runtime/routes/playground/seeded-conversations.ts +78 -0
- package/src/runtime/routes/playground/state.ts +78 -0
- package/src/runtime/routes/schedule-routes.ts +89 -8
- package/src/runtime/skill-route-registry.ts +75 -15
- package/src/schedule/run-script.ts +68 -0
- package/src/schedule/schedule-store.ts +7 -1
- package/src/schedule/scheduler.ts +48 -8
- package/src/skills/catalog-cache.ts +12 -5
- package/src/tools/browser/__tests__/browser-status.test.ts +189 -0
- package/src/tools/browser/browser-execution.ts +88 -19
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +230 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +146 -3
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +54 -3
- package/src/tools/browser/cdp-client/factory.ts +15 -4
- package/src/tools/executor.ts +126 -74
- package/src/tools/network/script-proxy/session-manager.ts +37 -1
- package/src/tools/permission-checker.ts +98 -49
- package/src/tools/policy-context.ts +4 -0
- package/src/tools/registry.ts +140 -3
- package/src/tools/schedule/create.ts +23 -8
- package/src/tools/schedule/update.ts +3 -1
- package/src/tools/secret-detection-handler.ts +0 -51
- package/src/tools/system/avatar-generator.ts +6 -2
- package/src/tools/types.ts +28 -2
- package/src/util/platform.ts +7 -2
- package/src/util/pricing.ts +26 -3
- package/src/workspace/migrations/006-services-config.ts +2 -4
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +2 -3
- package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +3 -4
- package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +108 -0
- package/src/workspace/migrations/047-remove-watch-callsites.ts +54 -0
- package/src/workspace/migrations/048-remove-workspace-hooks.ts +81 -0
- package/src/workspace/migrations/049-release-notes-default-sonnet.ts +80 -0
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +86 -0
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +128 -0
- package/src/workspace/migrations/registry.ts +12 -0
- package/tsconfig.json +1 -1
- package/hook-templates/debug-prompt-logger/hook.json +0 -7
- package/hook-templates/debug-prompt-logger/run.sh +0 -66
- package/src/__tests__/compaction-circuit-breaker.test.ts +0 -336
- package/src/__tests__/context-overflow-approval.test.ts +0 -156
- package/src/__tests__/hooks-blocking.test.ts +0 -178
- package/src/__tests__/hooks-cli.test.ts +0 -182
- package/src/__tests__/hooks-config.test.ts +0 -108
- package/src/__tests__/hooks-discovery.test.ts +0 -211
- package/src/__tests__/hooks-integration.test.ts +0 -196
- package/src/__tests__/hooks-manager.test.ts +0 -226
- package/src/__tests__/hooks-runner.test.ts +0 -175
- package/src/__tests__/hooks-settings.test.ts +0 -160
- package/src/__tests__/hooks-templates.test.ts +0 -169
- package/src/__tests__/hooks-ts-runner.test.ts +0 -170
- package/src/__tests__/hooks-watch.test.ts +0 -112
- package/src/__tests__/notification-schedule-dedup.test.ts +0 -213
- package/src/__tests__/oauth-scope-policy.test.ts +0 -180
- package/src/__tests__/send-notification-tool.test.ts +0 -83
- package/src/cli/commands/shotgun.ts +0 -266
- package/src/config/bundled-skills/conversations/SKILL.md +0 -20
- package/src/config/bundled-skills/conversations/TOOLS.json +0 -23
- package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +0 -88
- package/src/config/bundled-skills/heartbeat/SKILL.md +0 -43
- package/src/config/bundled-skills/notifications/SKILL.md +0 -40
- package/src/config/bundled-skills/notifications/TOOLS.json +0 -80
- package/src/config/bundled-skills/notifications/tools/send-notification.ts +0 -152
- package/src/config/bundled-skills/notifications/tools/shared.ts +0 -13
- package/src/config/bundled-skills/screen-watch/SKILL.md +0 -27
- package/src/config/bundled-skills/screen-watch/TOOLS.json +0 -35
- package/src/config/bundled-skills/screen-watch/tools/start-screen-watch.ts +0 -12
- package/src/config/bundled-skills/skills-catalog/SKILL.md +0 -84
- package/src/daemon/context-overflow-approval.ts +0 -52
- package/src/daemon/watch-handler.ts +0 -399
- package/src/hooks/cli.ts +0 -253
- package/src/hooks/config.ts +0 -100
- package/src/hooks/discovery.ts +0 -135
- package/src/hooks/manager.ts +0 -179
- package/src/hooks/runner.ts +0 -117
- package/src/hooks/templates.ts +0 -77
- package/src/hooks/types.ts +0 -75
- package/src/oauth/scope-policy.ts +0 -89
- package/src/runtime/gateway-internal-client.ts +0 -94
- package/src/runtime/routes/watch-routes.ts +0 -156
- package/src/signals/shotgun.ts +0 -203
- package/src/tools/watch/screen-watch.ts +0 -144
- package/src/tools/watch/watch-state.ts +0 -142
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default `tokenEstimate` plugin.
|
|
3
|
+
*
|
|
4
|
+
* The plugin's middleware is a passthrough — it calls `next(args)` and returns
|
|
5
|
+
* the result unchanged. The actual estimate lives in
|
|
6
|
+
* {@link defaultTokenEstimateTerminal}, which is wired in as the pipeline's
|
|
7
|
+
* `terminal` argument by `runPipeline` call sites in
|
|
8
|
+
* `daemon/conversation-agent-loop.ts`. This separation matters: the default
|
|
9
|
+
* plugin is registered before any user plugin (defaults load first in
|
|
10
|
+
* `bootstrapPlugins()`), which puts it at the OUTERMOST position of the onion
|
|
11
|
+
* chain. If the default middleware were to invoke the terminal directly
|
|
12
|
+
* without calling `next`, it would shadow every later-registered plugin. The
|
|
13
|
+
* passthrough lets user middleware that wraps the default (e.g. a doubler, a
|
|
14
|
+
* provider-native `countTokens` override) participate normally.
|
|
15
|
+
*
|
|
16
|
+
* The terminal delegates to
|
|
17
|
+
* {@link import("../../context/token-estimator.js").estimatePromptTokens estimatePromptTokens},
|
|
18
|
+
* which applies the EWMA calibration correction recorded from past provider
|
|
19
|
+
* responses. Preflight + mid-loop checks must use the calibrated estimate —
|
|
20
|
+
* before this pipeline existed, both call sites invoked `estimatePromptTokens`
|
|
21
|
+
* directly, and the calibrated estimate is what keeps the overflow gate
|
|
22
|
+
* consistent with the convergence path in the reducer. The pre-send
|
|
23
|
+
* calibration capture in `agent/loop.ts` still uses `estimatePromptTokensRaw`
|
|
24
|
+
* on purpose — the calibrator must learn against the raw estimate so the EWMA
|
|
25
|
+
* converges against provider ground truth rather than chasing its own
|
|
26
|
+
* corrected output. Pipelines produce user-facing estimates; calibration
|
|
27
|
+
* capture stays outside the pipeline.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
import {
|
|
31
|
+
estimatePromptTokens,
|
|
32
|
+
estimateToolsTokens,
|
|
33
|
+
} from "../../context/token-estimator.js";
|
|
34
|
+
import { registerPlugin } from "../registry.js";
|
|
35
|
+
import {
|
|
36
|
+
type EstimateArgs,
|
|
37
|
+
type EstimateResult,
|
|
38
|
+
type Middleware,
|
|
39
|
+
type Plugin,
|
|
40
|
+
PluginExecutionError,
|
|
41
|
+
} from "../types.js";
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Terminal handler for the `tokenEstimate` pipeline. Computes the tool token
|
|
45
|
+
* budget from `args.tools` and delegates to {@link estimatePromptTokens} with
|
|
46
|
+
* the canonical provider key, applying the EWMA calibration correction.
|
|
47
|
+
* Exported so tests can verify default behavior directly without going through
|
|
48
|
+
* `runPipeline`, and so `daemon/conversation-agent-loop.ts` can pass it as the
|
|
49
|
+
* `terminal` argument to `runPipeline`.
|
|
50
|
+
*/
|
|
51
|
+
export const defaultTokenEstimateTerminal = async (
|
|
52
|
+
args: EstimateArgs,
|
|
53
|
+
): Promise<EstimateResult> => {
|
|
54
|
+
const toolTokenBudget =
|
|
55
|
+
args.tools.length > 0 ? estimateToolsTokens(args.tools) : 0;
|
|
56
|
+
return estimatePromptTokens(args.history, args.systemPrompt, {
|
|
57
|
+
providerName: args.providerName,
|
|
58
|
+
toolTokenBudget,
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const passthrough: Middleware<EstimateArgs, EstimateResult> = async (
|
|
63
|
+
args,
|
|
64
|
+
next,
|
|
65
|
+
) => next(args);
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Default `tokenEstimate` plugin. Registered by
|
|
69
|
+
* {@link bootstrapPlugins} on daemon startup so the pipeline always has a
|
|
70
|
+
* terminal handler even when no other plugin contributes one.
|
|
71
|
+
*/
|
|
72
|
+
export const defaultTokenEstimatePlugin: Plugin = {
|
|
73
|
+
manifest: {
|
|
74
|
+
name: "default-token-estimate",
|
|
75
|
+
version: "1.0.0",
|
|
76
|
+
provides: { tokenEstimate: "v1" },
|
|
77
|
+
requires: { pluginRuntime: "v1", tokenEstimateApi: "v1" },
|
|
78
|
+
},
|
|
79
|
+
middleware: {
|
|
80
|
+
tokenEstimate: passthrough,
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// Module-load side effect: register this default at import time so
|
|
85
|
+
// downstream consumers (including tests that skip `bootstrapPlugins()`)
|
|
86
|
+
// observe a populated registry by default. Idempotent via the swallowed
|
|
87
|
+
// duplicate-name check. Kept local to this module (rather than iterating
|
|
88
|
+
// an array in `defaults/index.ts`) so the registration only references
|
|
89
|
+
// the already-initialized `defaultTokenEstimatePlugin` identifier —
|
|
90
|
+
// avoiding a TDZ crash when tests `mock.module(...)` a dependency of any
|
|
91
|
+
// other default plugin and directly import this file.
|
|
92
|
+
try {
|
|
93
|
+
registerPlugin(defaultTokenEstimatePlugin);
|
|
94
|
+
} catch (err) {
|
|
95
|
+
if (
|
|
96
|
+
err instanceof PluginExecutionError &&
|
|
97
|
+
err.message.includes("already registered")
|
|
98
|
+
) {
|
|
99
|
+
// already registered — expected when both index.ts and the direct
|
|
100
|
+
// file are imported in the same process
|
|
101
|
+
} else {
|
|
102
|
+
throw err;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default `toolError` plugin.
|
|
3
|
+
*
|
|
4
|
+
* The plugin's middleware is a passthrough — it calls `next(args)` and returns
|
|
5
|
+
* the result unchanged. The actual nudge-decision logic lives in
|
|
6
|
+
* {@link defaultToolErrorTerminal}, which is wired in as the pipeline's
|
|
7
|
+
* `terminal` argument by the `runPipeline` call site in `agent/loop.ts`. This
|
|
8
|
+
* separation matters: the default plugin is registered before any user plugin
|
|
9
|
+
* (defaults load first via module-side-effect imports / `registerDefaultPlugins`),
|
|
10
|
+
* which puts it at the OUTERMOST position of the onion chain. If the default
|
|
11
|
+
* middleware invoked the decision logic directly without calling `next`, it
|
|
12
|
+
* would shadow every later-registered plugin. Routing through `next(args)`
|
|
13
|
+
* lets user middleware participate normally.
|
|
14
|
+
*
|
|
15
|
+
* The canonical nudge decision: when the current turn produced at least one
|
|
16
|
+
* failed tool result, append a system-notice block to the tool results that
|
|
17
|
+
* coaches the LLM to either retry with corrected parameters (for recoverable
|
|
18
|
+
* errors) or report the failure to the user (for unrecoverable ones). Once
|
|
19
|
+
* the consecutive-error-turn counter exceeds the caller-supplied cap, the
|
|
20
|
+
* nudge is skipped — the error is likely not something the LLM can fix on
|
|
21
|
+
* its own and continuing to nudge only burns tokens.
|
|
22
|
+
*
|
|
23
|
+
* Design doc: `.private/plans/agent-plugin-system.md` (PR 19).
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { registerPlugin } from "../registry.js";
|
|
27
|
+
import {
|
|
28
|
+
type Middleware,
|
|
29
|
+
type Plugin,
|
|
30
|
+
PluginExecutionError,
|
|
31
|
+
type ToolErrorArgs,
|
|
32
|
+
type ToolErrorDecision,
|
|
33
|
+
} from "../types.js";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Canonical nudge text. Kept as a module-level constant so tests and future
|
|
37
|
+
* plugins can match it without duplicating the string.
|
|
38
|
+
*/
|
|
39
|
+
export const DEFAULT_TOOL_ERROR_NUDGE_TEXT =
|
|
40
|
+
"<system_notice>One or more tool calls returned an error. If the error looks recoverable (e.g. missing or invalid parameters), fix the parameters and retry. If the error is clearly unrecoverable (e.g. a service is down, a resource does not exist, or a permission is permanently denied), report it to the user.</system_notice>";
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Terminal handler for the `toolError` pipeline. Nudge iff the current turn
|
|
44
|
+
* had an error AND the consecutive-error counter is within the cap. Once the
|
|
45
|
+
* cap is breached the caller should stop appending the nudge (the error is
|
|
46
|
+
* likely unrecoverable and the LLM already had multiple attempts to correct
|
|
47
|
+
* it).
|
|
48
|
+
*
|
|
49
|
+
* Exported so `agent/loop.ts` can pass it as the `terminal` argument to
|
|
50
|
+
* `runPipeline` (ensuring the nudge decision fires even when no plugin is
|
|
51
|
+
* registered — e.g. direct AgentLoop callers that skip `bootstrapPlugins()`)
|
|
52
|
+
* and so tests can verify the decision logic directly without going through
|
|
53
|
+
* the pipeline runner.
|
|
54
|
+
*/
|
|
55
|
+
export const defaultToolErrorTerminal = async (
|
|
56
|
+
args: ToolErrorArgs,
|
|
57
|
+
): Promise<ToolErrorDecision> => {
|
|
58
|
+
if (
|
|
59
|
+
args.hasToolError &&
|
|
60
|
+
args.consecutiveErrorTurns <= args.maxConsecutiveErrorNudges
|
|
61
|
+
) {
|
|
62
|
+
return {
|
|
63
|
+
action: "nudge",
|
|
64
|
+
nudgeText: DEFAULT_TOOL_ERROR_NUDGE_TEXT,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return { action: "skip" };
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Default middleware for the `toolError` slot. Passthrough — calls `next(args)`
|
|
72
|
+
* so later-registered user plugins still participate in the onion chain. The
|
|
73
|
+
* actual decision logic lives in {@link defaultToolErrorTerminal}, wired in
|
|
74
|
+
* at the `runPipeline` call site in `agent/loop.ts`.
|
|
75
|
+
*
|
|
76
|
+
* Named explicitly so the pipeline's structured log record carries
|
|
77
|
+
* `"defaultToolErrorMiddleware"` in `chain` instead of an anonymous entry.
|
|
78
|
+
*/
|
|
79
|
+
const defaultToolErrorMiddleware: Middleware<ToolErrorArgs, ToolErrorDecision> =
|
|
80
|
+
async function defaultToolErrorMiddleware(args, next) {
|
|
81
|
+
return next(args);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Plugin registration for the default `toolError` behavior. Registered by
|
|
86
|
+
* `daemon/external-plugins-bootstrap.ts` via a side-effect import so the
|
|
87
|
+
* middleware is available to the pipeline runner from daemon startup.
|
|
88
|
+
*/
|
|
89
|
+
export const defaultToolErrorPlugin: Plugin = {
|
|
90
|
+
manifest: {
|
|
91
|
+
name: "default-tool-error",
|
|
92
|
+
version: "1.0.0",
|
|
93
|
+
requires: {
|
|
94
|
+
pluginRuntime: "v1",
|
|
95
|
+
toolErrorApi: "v1",
|
|
96
|
+
},
|
|
97
|
+
provides: {
|
|
98
|
+
toolError: "v1",
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
middleware: {
|
|
102
|
+
toolError: defaultToolErrorMiddleware,
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// Module-load side effect: register this default at import time so
|
|
107
|
+
// downstream consumers (including tests that skip `bootstrapPlugins()`)
|
|
108
|
+
// observe a populated registry by default. Idempotent via the swallowed
|
|
109
|
+
// duplicate-name check. Kept local to this module (rather than iterating
|
|
110
|
+
// an array in `defaults/index.ts`) so the registration only references
|
|
111
|
+
// the already-initialized `defaultToolErrorPlugin` identifier —
|
|
112
|
+
// avoiding a TDZ crash when tests `mock.module(...)` a dependency of any
|
|
113
|
+
// other default plugin and directly import this file.
|
|
114
|
+
try {
|
|
115
|
+
registerPlugin(defaultToolErrorPlugin);
|
|
116
|
+
} catch (err) {
|
|
117
|
+
if (
|
|
118
|
+
err instanceof PluginExecutionError &&
|
|
119
|
+
err.message.includes("already registered")
|
|
120
|
+
) {
|
|
121
|
+
// already registered — expected when both index.ts and the direct
|
|
122
|
+
// file are imported in the same process
|
|
123
|
+
} else {
|
|
124
|
+
throw err;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default `toolExecute` plugin — a no-argument passthrough that preserves
|
|
3
|
+
* the behavior `ToolExecutor.execute` had before the pipeline wrapper was
|
|
4
|
+
* introduced.
|
|
5
|
+
*
|
|
6
|
+
* Design
|
|
7
|
+
* ------
|
|
8
|
+
* The public {@link ToolExecutor.execute} method invokes
|
|
9
|
+
* {@link runPipeline} with the terminal bound to an internal
|
|
10
|
+
* `executeInternal` method (the original execute body, refactored to avoid
|
|
11
|
+
* recursion). Because the terminal IS the original behavior, the default
|
|
12
|
+
* plugin's `middleware.toolExecute` is a thin passthrough: it forwards to
|
|
13
|
+
* `next(args)` and returns the downstream result unchanged.
|
|
14
|
+
*
|
|
15
|
+
* This matches the convention set by PR 15 (`default-llm-call.ts`) for
|
|
16
|
+
* `llmCall` — the default plugin makes the pipeline shape explicit without
|
|
17
|
+
* introducing any behavior of its own. When no third-party plugins are
|
|
18
|
+
* registered the chain is `[defaultMiddleware] → terminal`, which composes
|
|
19
|
+
* identically to `[] → terminal`, so the shell-integration tests (which
|
|
20
|
+
* never register the default) stay unchanged-green.
|
|
21
|
+
*
|
|
22
|
+
* Why a dedicated plugin at all?
|
|
23
|
+
* ------------------------------
|
|
24
|
+
* - It signals publicly that `toolExecute` is a supported pipeline slot with
|
|
25
|
+
* a concrete contract.
|
|
26
|
+
* - Registration order determines onion order. If a third-party plugin
|
|
27
|
+
* wraps `toolExecute`, the runtime should boot with the default present
|
|
28
|
+
* (as the innermost passthrough) so the chain visibly contains a
|
|
29
|
+
* canonical terminator regardless of which third parties load.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import { registerPlugin } from "../registry.js";
|
|
33
|
+
import {
|
|
34
|
+
type Middleware,
|
|
35
|
+
type Plugin,
|
|
36
|
+
PluginExecutionError,
|
|
37
|
+
type ToolExecuteArgs,
|
|
38
|
+
type ToolExecuteResult,
|
|
39
|
+
} from "../types.js";
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Passthrough middleware — forwards the call to `next`. Named so the
|
|
43
|
+
* pipeline runner's `chain` log entry reads `defaultToolExecute` instead of
|
|
44
|
+
* `anonymous`.
|
|
45
|
+
*/
|
|
46
|
+
const defaultToolExecute: Middleware<ToolExecuteArgs, ToolExecuteResult> =
|
|
47
|
+
async function defaultToolExecute(args, next) {
|
|
48
|
+
return next(args);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The default `toolExecute` plugin. Exported as a module constant so the
|
|
53
|
+
* daemon bootstrap can register it via a side-effect import. Tests may
|
|
54
|
+
* import and register it explicitly via `registerPlugin()` to cover the
|
|
55
|
+
* on-by-default execution path.
|
|
56
|
+
*/
|
|
57
|
+
export const defaultToolExecutePlugin: Plugin = {
|
|
58
|
+
manifest: {
|
|
59
|
+
name: "default-tool-execute",
|
|
60
|
+
version: "1.0.0",
|
|
61
|
+
provides: { toolExecuteApi: "v1" },
|
|
62
|
+
requires: { pluginRuntime: "v1", toolExecuteApi: "v1" },
|
|
63
|
+
},
|
|
64
|
+
middleware: {
|
|
65
|
+
toolExecute: defaultToolExecute,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Module-load side effect: register this default at import time so
|
|
70
|
+
// downstream consumers (including tests that skip `bootstrapPlugins()`)
|
|
71
|
+
// observe a populated registry by default. Idempotent via the swallowed
|
|
72
|
+
// duplicate-name check. Kept local to this module (rather than iterating
|
|
73
|
+
// an array in `defaults/index.ts`) so the registration only references
|
|
74
|
+
// the already-initialized `defaultToolExecutePlugin` identifier —
|
|
75
|
+
// avoiding a TDZ crash when tests `mock.module(...)` a dependency of any
|
|
76
|
+
// other default plugin and directly import this file.
|
|
77
|
+
try {
|
|
78
|
+
registerPlugin(defaultToolExecutePlugin);
|
|
79
|
+
} catch (err) {
|
|
80
|
+
if (
|
|
81
|
+
err instanceof PluginExecutionError &&
|
|
82
|
+
err.message.includes("already registered")
|
|
83
|
+
) {
|
|
84
|
+
// already registered — expected when both index.ts and the direct
|
|
85
|
+
// file are imported in the same process
|
|
86
|
+
} else {
|
|
87
|
+
throw err;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default `toolResultTruncate` plugin.
|
|
3
|
+
*
|
|
4
|
+
* The plugin's middleware is a passthrough — it calls `next(args)` and returns
|
|
5
|
+
* the result unchanged. The actual truncation lives in
|
|
6
|
+
* {@link defaultToolResultTruncateTerminal}, which is wired in as the
|
|
7
|
+
* pipeline's `terminal` argument by the `runPipeline` call site in
|
|
8
|
+
* `agent/loop.ts`. This separation matters: the default plugin is registered
|
|
9
|
+
* before any user plugin (defaults load first in `bootstrapPlugins()`), which
|
|
10
|
+
* puts it at the OUTERMOST position of the onion chain. If the default
|
|
11
|
+
* middleware were to invoke the terminal directly without calling `next`, it
|
|
12
|
+
* would shadow every later-registered plugin (including hot-reloaded ones).
|
|
13
|
+
* Routing through `next(args)` lets user middleware participate normally.
|
|
14
|
+
*
|
|
15
|
+
* Design doc: `.private/plans/agent-plugin-system.md` (PR 17).
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { truncateToolResultText } from "../../context/tool-result-truncation.js";
|
|
19
|
+
import { registerPlugin } from "../registry.js";
|
|
20
|
+
import {
|
|
21
|
+
type Middleware,
|
|
22
|
+
type Plugin,
|
|
23
|
+
PluginExecutionError,
|
|
24
|
+
type ToolResultTruncateArgs,
|
|
25
|
+
type ToolResultTruncateResult,
|
|
26
|
+
} from "../types.js";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Terminal handler for the `toolResultTruncate` pipeline. Exported so tests
|
|
30
|
+
* can verify default behavior directly without going through `runPipeline`,
|
|
31
|
+
* and so `agent/loop.ts` can pass it as the `terminal` argument to
|
|
32
|
+
* `runPipeline`.
|
|
33
|
+
*/
|
|
34
|
+
export function defaultToolResultTruncateTerminal(
|
|
35
|
+
args: ToolResultTruncateArgs,
|
|
36
|
+
): ToolResultTruncateResult {
|
|
37
|
+
const truncated = truncateToolResultText(args.content, args.maxChars);
|
|
38
|
+
return {
|
|
39
|
+
content: truncated,
|
|
40
|
+
truncated: truncated !== args.content,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const passthrough: Middleware<
|
|
45
|
+
ToolResultTruncateArgs,
|
|
46
|
+
ToolResultTruncateResult
|
|
47
|
+
> = async (args, next) => next(args);
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Plugin descriptor for the default tool-result truncation middleware.
|
|
51
|
+
* Registered by `plugins/defaults/index.ts` so the registry always has at
|
|
52
|
+
* least one middleware for the `toolResultTruncate` pipeline.
|
|
53
|
+
*/
|
|
54
|
+
export const defaultToolResultTruncatePlugin: Plugin = {
|
|
55
|
+
manifest: {
|
|
56
|
+
name: "default-tool-result-truncate",
|
|
57
|
+
version: "1.0.0",
|
|
58
|
+
requires: {
|
|
59
|
+
pluginRuntime: "v1",
|
|
60
|
+
toolResultTruncateApi: "v1",
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
middleware: {
|
|
64
|
+
toolResultTruncate: passthrough,
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// Module-load side effect: register this default at import time so
|
|
69
|
+
// downstream consumers (including tests that skip `bootstrapPlugins()`)
|
|
70
|
+
// observe a populated registry by default. Idempotent via the swallowed
|
|
71
|
+
// duplicate-name check. Kept local to this module (rather than iterating
|
|
72
|
+
// an array in `defaults/index.ts`) so the registration only references
|
|
73
|
+
// the already-initialized `defaultToolResultTruncatePlugin` identifier —
|
|
74
|
+
// avoiding a TDZ crash when tests `mock.module(...)` a dependency of any
|
|
75
|
+
// other default plugin and directly import this file.
|
|
76
|
+
try {
|
|
77
|
+
registerPlugin(defaultToolResultTruncatePlugin);
|
|
78
|
+
} catch (err) {
|
|
79
|
+
if (
|
|
80
|
+
err instanceof PluginExecutionError &&
|
|
81
|
+
err.message.includes("already registered")
|
|
82
|
+
) {
|
|
83
|
+
// already registered — expected when both index.ts and the direct
|
|
84
|
+
// file are imported in the same process
|
|
85
|
+
} else {
|
|
86
|
+
throw err;
|
|
87
|
+
}
|
|
88
|
+
}
|