@vellumai/assistant 0.8.10 → 0.8.11-staging.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bun.lock +62 -1
- package/docs/workspace-tools.md +196 -0
- package/examples/plugins/echo/README.md +3 -3
- package/knip.json +1 -0
- package/openapi.yaml +460 -128
- package/package.json +2 -1
- package/scripts/build-plugin-api.ts +299 -0
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +7 -0
- package/src/__tests__/agent-loop-compaction-events.test.ts +197 -0
- package/src/__tests__/agent-loop-exit-reason.test.ts +93 -96
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +2 -0
- package/src/__tests__/agent-loop-output-hooks.test.ts +274 -1
- package/src/__tests__/agent-loop-override-profile.test.ts +3 -0
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +4 -0
- package/src/__tests__/agent-loop-thinking.test.ts +4 -0
- package/src/__tests__/agent-loop.test.ts +578 -5
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +0 -1
- package/src/__tests__/approval-cascade.test.ts +1 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +0 -2
- package/src/__tests__/btw-routes.test.ts +0 -1
- package/src/__tests__/build-persisted-content.test.ts +75 -1
- package/src/__tests__/catalog-install-normalize.test.ts +141 -0
- package/src/__tests__/ces-startup-timeout.test.ts +60 -0
- package/src/__tests__/compaction-events.test.ts +1 -0
- package/src/__tests__/config-managed-gemini-defaults.test.ts +2 -46
- package/src/__tests__/context-overflow-reducer.test.ts +264 -124
- package/src/__tests__/context-window-manager-overflow-rung.test.ts +351 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +13 -5
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +284 -455
- package/src/__tests__/conversation-agent-loop.test.ts +131 -551
- package/src/__tests__/conversation-app-control-instantiation.test.ts +13 -0
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
- package/src/__tests__/conversation-fork-crud.test.ts +259 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-lifecycle.test.ts +257 -1
- package/src/__tests__/conversation-process-callsite.test.ts +1 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +38 -377
- package/src/__tests__/conversation-queue.test.ts +1 -39
- package/src/__tests__/conversation-runtime-assembly.test.ts +119 -8
- package/src/__tests__/conversation-skill-tools.test.ts +491 -5
- package/src/__tests__/conversation-slash-queue.test.ts +1 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -0
- package/src/__tests__/conversation-speed-override.test.ts +1 -0
- package/src/__tests__/conversation-store.test.ts +74 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +4 -1
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +323 -0
- package/src/__tests__/conversation-tool-setup-tools-disabled.test.ts +34 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -0
- package/src/__tests__/corrected-target.test.ts +93 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +3 -5
- package/src/__tests__/credential-execution-tools.test.ts +23 -11
- package/src/__tests__/credential-security-invariants.test.ts +6 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +80 -0
- package/src/__tests__/device-id.test.ts +70 -1
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +6 -40
- package/src/__tests__/empty-response-hook.test.ts +242 -66
- package/src/__tests__/external-plugin-loader.test.ts +0 -31
- package/src/__tests__/get-skill-detail-audit.test.ts +43 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +91 -0
- package/src/__tests__/history-repair-hook.test.ts +228 -3
- package/src/__tests__/host-app-control-proxy.test.ts +45 -0
- package/src/__tests__/host-browser-proxy.test.ts +254 -9
- package/src/__tests__/identity-routes.test.ts +1 -0
- package/src/__tests__/image-recovery-hook.test.ts +387 -0
- package/src/__tests__/injector-chain.test.ts +5 -4
- package/src/__tests__/injector-v3-suppression.test.ts +373 -47
- package/src/__tests__/intent-routing.test.ts +7 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +117 -15
- package/src/__tests__/notification-decision-strategy.test.ts +3 -3
- package/src/__tests__/oauth-store.test.ts +0 -85
- package/src/__tests__/{context-overflow-policy.test.ts → overflow-policy.test.ts} +1 -1
- package/src/__tests__/parallel-tool.benchmark.test.ts +4 -0
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +29 -9
- package/src/__tests__/persist-unsendable-image.test.ts +4 -4
- package/src/__tests__/persistence-secret-redaction.test.ts +78 -0
- package/src/__tests__/plugin-bootstrap.test.ts +82 -73
- package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
- package/src/__tests__/plugin-types.test.ts +0 -8
- package/src/__tests__/provider-catalog-visibility.test.ts +1 -9
- package/src/__tests__/prune-old-conversations-job.test.ts +99 -0
- package/src/__tests__/registry.test.ts +240 -1
- package/src/__tests__/require-fresh-approval.test.ts +3 -0
- package/src/__tests__/schedule-routes.test.ts +116 -1
- package/src/__tests__/schedule-store.test.ts +28 -0
- package/src/__tests__/schedule-tools.test.ts +94 -1
- package/src/__tests__/server-history-render.test.ts +39 -0
- package/src/__tests__/skill-projection-feature-flag.test.ts +13 -0
- package/src/__tests__/skill-projection.benchmark.test.ts +25 -7
- package/src/__tests__/skills.test.ts +202 -0
- package/src/__tests__/slim-skill-category.test.ts +195 -0
- package/src/__tests__/strip-memory-injections.test.ts +33 -39
- package/src/__tests__/test-support/tool-invocation-seed.ts +79 -0
- package/src/__tests__/title-generate-hook.test.ts +9 -7
- package/src/__tests__/tool-audit-listener.test.ts +264 -1
- package/src/__tests__/tool-error-hook.test.ts +4 -3
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -0
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +273 -0
- package/src/__tests__/tool-result-truncate-hook.test.ts +1 -0
- package/src/__tests__/tool-start-timestamp.test.ts +218 -0
- package/src/__tests__/tools-get-route.test.ts +202 -0
- package/src/__tests__/workspace-tool-loader.test.ts +319 -0
- package/src/__tests__/workspace-tools-watcher-flag.test.ts +70 -0
- package/src/agent/loop.ts +569 -319
- package/src/api/events/tool-result.ts +9 -0
- package/src/api/events/tool-use-start.ts +7 -0
- package/src/api/index.ts +10 -0
- package/src/api/responses/conversation-message.ts +135 -27
- package/src/api/responses/memory-v3-selection-log.ts +4 -4
- package/src/approvals/guardian-request-resolvers.ts +26 -0
- package/src/browser-session/backends/host-bridge.ts +29 -0
- package/src/browser-session/index.ts +1 -0
- package/src/browser-session/types.ts +5 -1
- package/src/cli/commands/__tests__/schedules.test.ts +62 -4
- package/src/cli/commands/__tests__/skills.test.ts +53 -0
- package/src/cli/commands/channel-verification-sessions.ts +6 -6
- package/src/cli/commands/inference-providers.ts +0 -8
- package/src/cli/commands/plugins.ts +2 -2
- package/src/cli/commands/schedules.ts +27 -4
- package/src/cli/commands/skills.ts +187 -146
- package/src/cli/commands/tools.ts +106 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +256 -328
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +6 -2
- package/src/cli/lib/__tests__/plugin-details.test.ts +10 -16
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +2 -2
- package/src/cli/lib/__tests__/search-plugins.test.ts +145 -240
- package/src/cli/lib/install-from-github.ts +187 -117
- package/src/cli/lib/plugin-catalog-cache.ts +9 -9
- package/src/cli/lib/plugin-details.ts +38 -68
- package/src/cli/lib/plugin-marketplace.ts +42 -14
- package/src/cli/lib/search-plugins.ts +29 -129
- package/src/cli/program.ts +2 -0
- package/src/config/bundled-skills/acp/SKILL.md +1 -0
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -0
- package/src/config/bundled-skills/app-control/SKILL.md +1 -0
- package/src/config/bundled-skills/computer-use/SKILL.md +1 -0
- package/src/config/bundled-skills/contacts/SKILL.md +1 -0
- package/src/config/bundled-skills/document-editor/SKILL.md +1 -0
- package/src/config/bundled-skills/followups/SKILL.md +1 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +1 -0
- package/src/config/bundled-skills/media-processing/SKILL.md +1 -0
- package/src/config/bundled-skills/messaging/SKILL.md +1 -0
- package/src/config/bundled-skills/phone-calls/SKILL.md +1 -0
- package/src/config/bundled-skills/playbooks/SKILL.md +1 -0
- package/src/config/bundled-skills/schedule/SKILL.md +1 -0
- package/src/config/bundled-skills/schedule/TOOLS.json +11 -3
- package/src/config/bundled-skills/sequences/SKILL.md +1 -0
- package/src/config/bundled-skills/settings/SKILL.md +1 -0
- package/src/config/bundled-skills/skill-management/SKILL.md +101 -1
- package/src/config/bundled-skills/subagent/SKILL.md +1 -0
- package/src/config/bundled-skills/transcribe/SKILL.md +1 -0
- package/src/config/env-registry.ts +23 -0
- package/src/config/feature-flag-registry.json +17 -81
- package/src/config/loader.ts +5 -22
- package/src/config/schema.ts +2 -0
- package/src/config/schemas/__tests__/compaction-logs.test.ts +56 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +0 -1
- package/src/config/schemas/__tests__/memory-v3.test.ts +61 -1
- package/src/config/schemas/compaction-logs.ts +79 -0
- package/src/config/schemas/memory-v2.ts +0 -8
- package/src/config/schemas/memory-v3.ts +104 -33
- package/src/config/seed-inference-profiles.ts +1 -1
- package/src/config/skills.ts +117 -47
- package/src/context/compactor.ts +11 -0
- package/src/context/strip-injections.ts +38 -4
- package/src/credential-execution/feature-gates.ts +0 -21
- package/src/credential-execution/startup-timeout.ts +32 -4
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +18 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +140 -91
- package/src/daemon/conversation-agent-loop.ts +123 -658
- package/src/daemon/conversation-error.ts +6 -33
- package/src/daemon/conversation-lifecycle.ts +1 -1
- package/src/daemon/conversation-runtime-assembly.ts +183 -22
- package/src/daemon/conversation-skill-tools.ts +137 -8
- package/src/daemon/conversation-slash.ts +0 -14
- package/src/daemon/conversation-store.ts +2 -19
- package/src/daemon/conversation-tool-setup.ts +87 -1
- package/src/daemon/conversation.ts +119 -50
- package/src/daemon/external-plugins-bootstrap.ts +36 -95
- package/src/daemon/handlers/config-channels.ts +11 -2
- package/src/daemon/handlers/shared.ts +9 -1
- package/src/daemon/handlers/skills.ts +10 -4
- package/src/daemon/host-app-control-proxy.ts +72 -57
- package/src/daemon/host-browser-proxy.ts +117 -22
- package/src/daemon/lifecycle.ts +34 -5
- package/src/daemon/message-protocol.ts +0 -7
- package/src/daemon/message-types/schedules.ts +1 -0
- package/src/daemon/message-types/skills.ts +17 -0
- package/src/daemon/providers-setup.ts +3 -0
- package/src/daemon/server.ts +3 -3
- package/src/daemon/tool-setup-types.ts +9 -3
- package/src/daemon/trust-context.ts +23 -0
- package/src/daemon/workspace-tools-watcher.ts +324 -0
- package/src/events/tool-audit-listener.ts +78 -16
- package/src/events/tool-metrics-listener.ts +2 -5
- package/src/memory/__tests__/compaction-log-writer-clickhouse.test.ts +227 -0
- package/src/memory/__tests__/conversation-queries.test.ts +176 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +20 -32
- package/src/memory/compaction-log-writer-clickhouse.ts +418 -0
- package/src/memory/conversation-crud.ts +134 -3
- package/src/memory/conversation-queries.ts +64 -7
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.test.ts +130 -1
- package/src/memory/embedding-backend.ts +79 -106
- package/src/memory/embedding-gemini.ts +5 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +12 -0
- package/src/memory/graph/__tests__/handle-remember-v2.test.ts +19 -0
- package/src/memory/graph/conversation-graph-memory.ts +36 -25
- package/src/memory/graph/tool-handlers.ts +3 -0
- package/src/memory/job-handlers/cleanup.ts +3 -1
- package/src/memory/jobs-store.ts +0 -28
- package/src/memory/jobs-worker.ts +10 -22
- package/src/memory/memory-marker.ts +29 -0
- package/src/memory/memory-retrospective-startup-cleanup.ts +1 -1
- package/src/memory/migrations/268-add-memory-v3-selections.ts +6 -0
- package/src/memory/migrations/270-schedule-description.ts +36 -0
- package/src/memory/migrations/275-tool-invocations-add-skill-id.test.ts +81 -0
- package/src/memory/migrations/275-tool-invocations-add-skill-id.ts +20 -0
- package/src/memory/migrations/276-tool-invocations-created-at-id-index.test.ts +68 -0
- package/src/memory/migrations/276-tool-invocations-created-at-id-index.ts +20 -0
- package/src/memory/migrations/277-add-memory-v3-ever-injected.ts +29 -0
- package/src/memory/migrations/278-tool-invocations-telemetry-columns.test.ts +96 -0
- package/src/memory/migrations/278-tool-invocations-telemetry-columns.ts +39 -0
- package/src/memory/migrations/279-create-skill-loaded-events.test.ts +84 -0
- package/src/memory/migrations/279-create-skill-loaded-events.ts +26 -0
- package/src/memory/migrations/280-conversations-surfaced-at.test.ts +88 -0
- package/src/memory/migrations/280-conversations-surfaced-at.ts +24 -0
- package/src/memory/migrations/index.ts +10 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/schema/conversations.ts +16 -0
- package/src/memory/schema/infrastructure.ts +26 -0
- package/src/memory/skill-loaded-events-store.test.ts +160 -0
- package/src/memory/skill-loaded-events-store.ts +95 -0
- package/src/memory/tool-executed-events-store.test.ts +219 -0
- package/src/memory/tool-executed-events-store.ts +102 -0
- package/src/memory/tool-usage-store.ts +15 -3
- package/src/memory/v2/__tests__/consolidation-job.test.ts +117 -12
- package/src/memory/v2/__tests__/consolidation-prompt-flag-gating-guard.test.ts +189 -0
- package/src/memory/v2/__tests__/injected-block-slugs.test.ts +90 -0
- package/src/memory/v2/__tests__/page-store.test.ts +33 -0
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +88 -15
- package/src/memory/v2/activation-store.ts +50 -1
- package/src/memory/v2/consolidation-job.ts +113 -29
- package/src/memory/v2/injected-block-slugs.ts +79 -0
- package/src/memory/v2/injection.ts +6 -1
- package/src/memory/v2/prompts/consolidation.ts +414 -13
- package/src/memory/v2/router.ts +2 -28
- package/src/memory/v2/static-context.ts +1 -1
- package/src/memory/v2/types.ts +16 -0
- package/src/notifications/__tests__/copy-composer.test.ts +244 -0
- package/src/notifications/access-request-copy.ts +298 -0
- package/src/notifications/adapters/slack.ts +3 -3
- package/src/notifications/adapters/telegram.ts +2 -1
- package/src/notifications/copy-composer.ts +49 -267
- package/src/notifications/decision-engine.ts +16 -35
- package/src/notifications/home-feed-side-effect.ts +1 -6
- package/src/oauth/oauth-store.ts +0 -9
- package/src/permissions/checker.test.ts +83 -1
- package/src/permissions/checker.ts +25 -2
- package/src/permissions/gateway-threshold-reader.test.ts +182 -0
- package/src/permissions/gateway-threshold-reader.ts +80 -0
- package/src/platform/client.ts +1 -3
- package/src/platform/feature-gate.ts +3 -12
- package/src/plugin-api/constants.ts +4 -2
- package/src/plugin-api/index.ts +63 -11
- package/src/plugin-api/types.ts +236 -71
- package/src/plugins/defaults/compaction/compact.ts +66 -2
- package/src/plugins/defaults/compaction/context-overflow-reducer.ts +240 -32
- package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
- package/src/{daemon/context-overflow-policy.ts → plugins/defaults/compaction/overflow-policy.ts} +1 -1
- package/src/plugins/defaults/compaction/window-manager.ts +303 -1
- package/src/plugins/defaults/empty-response/hooks/post-model-call.ts +173 -0
- package/src/plugins/defaults/empty-response/hooks/stop.ts +11 -115
- package/src/plugins/defaults/empty-response/nudge-state-store.ts +46 -0
- package/src/plugins/defaults/history-repair/hooks/post-model-call.ts +50 -0
- package/src/plugins/defaults/history-repair/hooks/stop.ts +22 -0
- package/src/plugins/defaults/history-repair/repair-state-store.ts +51 -0
- package/src/plugins/defaults/history-repair/terminal.ts +39 -2
- package/src/plugins/defaults/image-recovery/detect.ts +25 -0
- package/src/plugins/defaults/image-recovery/hooks/post-model-call.ts +73 -0
- package/src/plugins/defaults/image-recovery/hooks/stop.ts +22 -0
- package/src/plugins/defaults/image-recovery/image-recovery-state-store.ts +48 -0
- package/src/plugins/defaults/image-recovery/package.json +14 -0
- package/src/{daemon/persist-unsendable-image.ts → plugins/defaults/image-recovery/recover.ts} +67 -14
- package/src/plugins/defaults/index.ts +71 -5
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +76 -112
- package/src/plugins/defaults/memory-retrieval/hooks/{user-prompt-submit-temp.ts → user-prompt-submit.ts} +83 -74
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +14 -8
- package/src/plugins/defaults/memory-retrieval/injectors.ts +2 -18
- package/src/plugins/defaults/memory-retrieval/package.json +14 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1157 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +683 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/live-integration.test.ts +161 -140
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +160 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +335 -316
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +145 -53
- package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +38 -1
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +18 -8
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +112 -71
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +192 -51
- package/src/plugins/defaults/memory-v3-shadow/__tests__/types.test.ts +4 -16
- package/src/plugins/defaults/memory-v3-shadow/card.test.ts +173 -0
- package/src/plugins/defaults/memory-v3-shadow/card.ts +116 -0
- package/src/plugins/defaults/memory-v3-shadow/core-set.test.ts +104 -0
- package/src/plugins/defaults/memory-v3-shadow/core-set.ts +59 -0
- package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.test.ts +305 -0
- package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.ts +278 -0
- package/src/plugins/defaults/memory-v3-shadow/hot-set.test.ts +138 -0
- package/src/plugins/defaults/memory-v3-shadow/hot-set.ts +85 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +331 -24
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +119 -13
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +169 -114
- package/src/plugins/defaults/memory-v3-shadow/page-content.ts +47 -16
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +144 -66
- package/src/plugins/defaults/memory-v3-shadow/prune.test.ts +758 -0
- package/src/plugins/defaults/memory-v3-shadow/prune.ts +471 -0
- package/src/plugins/defaults/memory-v3-shadow/render-injection.ts +68 -16
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +19 -12
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +96 -43
- package/src/plugins/defaults/memory-v3-shadow/types.ts +34 -17
- package/src/plugins/defaults/title-generate/hooks/stop.ts +9 -11
- package/src/plugins/pipeline.ts +8 -5
- package/src/plugins/types.ts +5 -51
- package/src/providers/cache-control.ts +26 -0
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +1 -2
- package/src/providers/model-catalog.ts +13 -1
- package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +147 -0
- package/src/providers/openai/chat-completions-provider.ts +46 -0
- package/src/providers/openai/responses-provider.ts +45 -0
- package/src/providers/registry.ts +0 -8
- package/src/runtime/__tests__/agent-wake.test.ts +0 -1
- package/src/runtime/agent-wake.ts +13 -0
- package/src/runtime/routes/__tests__/acp-routes.test.ts +151 -0
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +12 -50
- package/src/runtime/routes/__tests__/conversation-surface-routes.test.ts +322 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +0 -62
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +31 -11
- package/src/runtime/routes/acp-routes.test.ts +106 -0
- package/src/runtime/routes/acp-routes.ts +248 -2
- package/src/runtime/routes/browser-tabs-routes.ts +1 -1
- package/src/runtime/routes/channel-verification-routes.ts +14 -5
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +0 -14
- package/src/runtime/routes/consolidation-routes.ts +6 -82
- package/src/runtime/routes/conversation-list-routes.ts +6 -0
- package/src/runtime/routes/conversation-management-routes.ts +71 -0
- package/src/runtime/routes/identity-routes.ts +8 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
- package/src/runtime/routes/inference-provider-connection-routes.ts +0 -45
- package/src/runtime/routes/plugins-routes.ts +34 -45
- package/src/runtime/routes/schedule-routes.ts +43 -5
- package/src/runtime/routes/settings-routes.ts +140 -15
- package/src/runtime/routes/skills-routes.ts +18 -6
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +140 -0
- package/src/runtime/services/conversation-serializer.ts +38 -1
- package/src/runtime/verification-outbound-actions.ts +147 -2
- package/src/runtime/verification-templates.ts +29 -3
- package/src/schedule/schedule-store.ts +19 -0
- package/src/skills/catalog-install.ts +77 -13
- package/src/tasks/task-scheduler.ts +1 -0
- package/src/telemetry/types.ts +66 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +542 -13
- package/src/telemetry/usage-telemetry-reporter.ts +213 -20
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +49 -2
- package/src/tools/browser/__tests__/browser-status.test.ts +29 -5
- package/src/tools/browser/browser-execution.ts +27 -9
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +380 -4
- package/src/tools/browser/cdp-client/__tests__/host-bridge-cdp-client.test.ts +107 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +6 -1
- package/src/tools/browser/cdp-client/factory.ts +217 -17
- package/src/tools/browser/cdp-client/host-bridge-cdp-client.ts +67 -0
- package/src/tools/browser/cdp-client/types.ts +22 -2
- package/src/tools/credential-execution/make-authenticated-request.ts +2 -1
- package/src/tools/credential-execution/manage-secure-command-tool.ts +169 -164
- package/src/tools/credential-execution/run-authenticated-command.ts +2 -1
- package/src/tools/executor.ts +39 -7
- package/src/tools/registry.ts +387 -5
- package/src/tools/schedule/create.ts +16 -0
- package/src/tools/schedule/list.ts +12 -4
- package/src/tools/schedule/update.ts +12 -0
- package/src/tools/skills/load.ts +11 -6
- package/src/tools/terminal/safe-env.ts +2 -0
- package/src/tools/types.ts +65 -9
- package/src/tools/workspace-tools/loader.ts +673 -0
- package/src/usage/attribution.ts +28 -0
- package/src/util/device-id.ts +17 -3
- package/src/util/platform.ts +16 -0
- package/tsconfig.plugin-api.json +13 -0
- package/src/__tests__/plugin-external-api.test.ts +0 -68
- package/src/__tests__/plugin-skill-contribution.test.ts +0 -355
- package/src/daemon/message-types/browser.ts +0 -10
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/eval-turns.json +0 -36
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/live-turns.json +0 -37
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-eviction.test.ts +0 -106
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-skeleton.test.ts +0 -44
- package/src/plugins/defaults/memory-v3-shadow/working-set.ts +0 -91
- package/src/plugins/external-api.ts +0 -114
- package/src/plugins/plugin-skill-contributions.ts +0 -292
package/src/plugin-api/types.ts
CHANGED
|
@@ -42,11 +42,19 @@ export interface PluginLogger {
|
|
|
42
42
|
// ─── Hook function ───────────────────────────────────────────────────────────
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
|
-
* A plugin lifecycle hook. Receives a per-lifecycle context shape and
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
45
|
+
* A plugin lifecycle hook. Receives a per-lifecycle context shape and may
|
|
46
|
+
* either mutate `ctx` in place (returning `void`) or return a *partial*
|
|
47
|
+
* context whose fields are merged onto the threaded context — only the keys
|
|
48
|
+
* it returns are overwritten, every other field is preserved. Returning a
|
|
49
|
+
* partial lets a hook edit just the subset of fields it cares about without
|
|
50
|
+
* having to re-specify the rest. The merged context is threaded to the next
|
|
51
|
+
* hook in the chain (e.g. `user-prompt-submit`).
|
|
52
|
+
*
|
|
53
|
+
* Because an omitted key means "keep the existing value", every field on a
|
|
54
|
+
* context shape is required (no `?`-optional or `| undefined` members): a
|
|
55
|
+
* present key always carries a concrete value, so "absent from the returned
|
|
56
|
+
* partial" is never ambiguous with "explicitly cleared". Fields that can be
|
|
57
|
+
* empty model that with `| null`, not `| undefined`.
|
|
50
58
|
*
|
|
51
59
|
* Each known hook key has a documented context shape:
|
|
52
60
|
* - `init` — {@link PluginInitContext}
|
|
@@ -57,7 +65,9 @@ export interface PluginLogger {
|
|
|
57
65
|
* - `stop` — {@link StopContext}
|
|
58
66
|
* - `post-model-call` — {@link PostModelCallContext}
|
|
59
67
|
*/
|
|
60
|
-
export type PluginHookFn<TCtx = unknown> = (
|
|
68
|
+
export type PluginHookFn<TCtx = unknown> = (
|
|
69
|
+
ctx: TCtx,
|
|
70
|
+
) => Promise<Partial<TCtx> | void>;
|
|
61
71
|
|
|
62
72
|
// ─── Init context ────────────────────────────────────────────────────────────
|
|
63
73
|
|
|
@@ -144,6 +154,25 @@ export interface UserPromptSubmitContext {
|
|
|
144
154
|
* for the turn and cannot be recovered from the message arrays.
|
|
145
155
|
*/
|
|
146
156
|
readonly requestId: string;
|
|
157
|
+
/**
|
|
158
|
+
* Active inference profile key to surface in this turn's context, or `null`
|
|
159
|
+
* when the profile is unchanged since the one last announced to the model.
|
|
160
|
+
* Hooks that emit the `model_profile` grounding line resolve the
|
|
161
|
+
* human-readable label (and model id) from this key via the workspace LLM
|
|
162
|
+
* config rather than receiving the rendered string — the key is the minimal
|
|
163
|
+
* turn input the message arrays cannot carry.
|
|
164
|
+
*/
|
|
165
|
+
readonly modelProfileKey: string | null;
|
|
166
|
+
/**
|
|
167
|
+
* Whether the turn has no human present to answer clarification questions
|
|
168
|
+
* (e.g. a scheduled, background, or headless run). Resolved once at turn
|
|
169
|
+
* start from the run's interactivity option, falling back to live client
|
|
170
|
+
* presence — a single value the hook reads rather than re-deriving from
|
|
171
|
+
* mutable conversation state that can flip mid-turn. Hooks that assemble the
|
|
172
|
+
* turn's runtime injections forward it so the assembled context reflects the
|
|
173
|
+
* turn's interactivity.
|
|
174
|
+
*/
|
|
175
|
+
readonly isNonInteractive: boolean;
|
|
147
176
|
/**
|
|
148
177
|
* The text of the user prompt that triggered this turn — the resolved
|
|
149
178
|
* user message (after slash-command expansion), independent of any
|
|
@@ -172,6 +201,69 @@ export interface UserPromptSubmitContext {
|
|
|
172
201
|
readonly logger: PluginLogger;
|
|
173
202
|
}
|
|
174
203
|
|
|
204
|
+
// ─── Post-compact hook context ───────────────────────────────────────────────
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Context passed to the `post-compact` hook. Fires after the agent loop
|
|
208
|
+
* compacts a conversation mid-turn — once the running history has been
|
|
209
|
+
* summarized down to fit the context window, and before the turn resumes.
|
|
210
|
+
*
|
|
211
|
+
* Compaction strips the turn's runtime injections (scratchpad, retrieved
|
|
212
|
+
* memory, workspace context, transcript snapshots) along with the raw messages
|
|
213
|
+
* it summarizes. This hook's job is to re-apply whatever injected context must
|
|
214
|
+
* survive onto the freshly compacted history before the next provider call.
|
|
215
|
+
* The default memory-retrieval plugin contributes a hook here that re-injects
|
|
216
|
+
* its memory blocks and re-tracks the memory graph; user hooks can re-apply
|
|
217
|
+
* their own injected context the same way.
|
|
218
|
+
*
|
|
219
|
+
* The hook re-injects by mutating `history` in place (or returning a new
|
|
220
|
+
* context with a replacement `history`) — see {@link PluginHookFn}'s
|
|
221
|
+
* polymorphic return shape. The agent loop reads the settled `history` back off
|
|
222
|
+
* the context and resumes the turn from it. Multiple plugins' hooks chain in
|
|
223
|
+
* registration order, each seeing the previous plugin's edits.
|
|
224
|
+
*/
|
|
225
|
+
export interface PostCompactContext {
|
|
226
|
+
/**
|
|
227
|
+
* The compacted message history to re-inject onto. Hooks mutate this in
|
|
228
|
+
* place (or return a new context with a replacement) to re-apply context
|
|
229
|
+
* that compaction stripped; the loop resumes the turn from the settled
|
|
230
|
+
* value.
|
|
231
|
+
*/
|
|
232
|
+
history: Message[];
|
|
233
|
+
/**
|
|
234
|
+
* Stable ID for the request that drives this turn. Hooks that perform
|
|
235
|
+
* runtime injection forward it onto the injector turn context so the
|
|
236
|
+
* re-applied blocks are attributed to the originating request; it is fixed
|
|
237
|
+
* for the turn and cannot be recovered from the message history.
|
|
238
|
+
*/
|
|
239
|
+
readonly requestId: string;
|
|
240
|
+
/** Conversation ID the turn being compacted is scoped to. */
|
|
241
|
+
readonly conversationId: string;
|
|
242
|
+
/**
|
|
243
|
+
* Whether the turn has no human present to answer clarification questions
|
|
244
|
+
* (e.g. a scheduled, background, or headless run). Mirrors the field of the
|
|
245
|
+
* same name on {@link UserPromptSubmitContext}: resolved once at turn start
|
|
246
|
+
* so re-injection reflects the turn's interactivity rather than mutable
|
|
247
|
+
* client-presence state that can flip mid-turn.
|
|
248
|
+
*/
|
|
249
|
+
readonly isNonInteractive: boolean;
|
|
250
|
+
/**
|
|
251
|
+
* Active inference profile key to surface in the re-injected context, or
|
|
252
|
+
* `null` when the profile is unchanged since the one last announced to the
|
|
253
|
+
* model. Mirrors {@link UserPromptSubmitContext.modelProfileKey}: hooks that
|
|
254
|
+
* emit the `model_profile` grounding line resolve the human-readable label
|
|
255
|
+
* from this key rather than receiving the rendered string.
|
|
256
|
+
*/
|
|
257
|
+
readonly modelProfileKey: string | null;
|
|
258
|
+
/**
|
|
259
|
+
* Volume of runtime injection to re-apply. `"full"` restores the complete
|
|
260
|
+
* runtime context; `"minimal"` is the reduced volume overflow recovery's
|
|
261
|
+
* injection-downgrade rung selects to keep the re-injected prompt small.
|
|
262
|
+
* Defaults to `"full"` when omitted.
|
|
263
|
+
*/
|
|
264
|
+
readonly injectionMode?: "full" | "minimal";
|
|
265
|
+
}
|
|
266
|
+
|
|
175
267
|
// ─── Post-tool-use hook context ──────────────────────────────────────────────
|
|
176
268
|
|
|
177
269
|
/**
|
|
@@ -219,9 +311,9 @@ export interface PostToolUseContext {
|
|
|
219
311
|
* a separate block *after* emitting the tool_result, so it reaches the model
|
|
220
312
|
* without polluting the client-facing or persisted tool output. Mirrors
|
|
221
313
|
* Claude Code's PostToolUse `hookSpecificOutput.additionalContext` and the
|
|
222
|
-
* singular of Codex's `additional_contexts`.
|
|
314
|
+
* singular of Codex's `additional_contexts`. `null` means no extra context.
|
|
223
315
|
*/
|
|
224
|
-
additionalContext
|
|
316
|
+
additionalContext: string | null;
|
|
225
317
|
/**
|
|
226
318
|
* The model's context-window size in tokens. Plugins derive their own
|
|
227
319
|
* character budget from this (e.g. a share of the window) rather than
|
|
@@ -239,65 +331,89 @@ export interface PostToolUseContext {
|
|
|
239
331
|
// ─── Stop hook context ───────────────────────────────────────────────────────
|
|
240
332
|
|
|
241
333
|
/**
|
|
242
|
-
*
|
|
243
|
-
* and
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
* - `"continue"` — re-query the model. The hook is responsible for appending
|
|
248
|
-
* the follow-up turn it wants the model to see to
|
|
249
|
-
* {@link StopContext.messages} before returning.
|
|
334
|
+
* Why an agent turn reached a terminal state. Supplied to the `stop` hook via
|
|
335
|
+
* {@link StopContext.exitReason} and emitted on the `agent_loop_exit` event,
|
|
336
|
+
* then persisted onto the final `llm_request_logs` row of the turn (rows from
|
|
337
|
+
* intermediate turns keep a NULL reason, which is how downstream tooling and
|
|
338
|
+
* the LLM Context Inspector tell "loop kept going" from "loop is done").
|
|
250
339
|
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
340
|
+
* Values are stable wire/DB strings — they are written to SQLite and surfaced
|
|
341
|
+
* over the inspector wire format, so renaming any of them is a breaking change.
|
|
253
342
|
*/
|
|
254
|
-
export type
|
|
343
|
+
export type AgentLoopExitReason =
|
|
344
|
+
/** User cancellation observed before the turn's next provider call. */
|
|
345
|
+
| "aborted_pre_call"
|
|
346
|
+
/** Assistant message had no tool-use blocks (or no tool executor). */
|
|
347
|
+
| "no_tool_calls"
|
|
348
|
+
/** User cancellation observed while building the tool-results message. */
|
|
349
|
+
| "aborted_post_response"
|
|
350
|
+
/** User cancellation observed mid-tool-execution; completed results kept. */
|
|
351
|
+
| "aborted_during_tools"
|
|
352
|
+
/** A tool result requested handing back to the user. */
|
|
353
|
+
| "yield_to_user"
|
|
354
|
+
/** The orchestrator yielded at a checkpoint to process a queued message. */
|
|
355
|
+
| "checkpoint_handoff"
|
|
356
|
+
/** Context-window recovery exhausted and the turn ended with an error. */
|
|
357
|
+
| "context_too_large"
|
|
358
|
+
/**
|
|
359
|
+
* An auto-compress rerun (post-emergency-compaction, post-tier reducer)
|
|
360
|
+
* still yielded at the mid-loop budget checkpoint — the turn terminated with
|
|
361
|
+
* no further recovery layer to re-enter. A pure observability signal so the
|
|
362
|
+
* silent stall is attributable instead of leaving the exit reason NULL.
|
|
363
|
+
*/
|
|
364
|
+
| "budget_yield_unrecovered"
|
|
365
|
+
/** Provider stopped because the configured output-token limit was reached. */
|
|
366
|
+
| "max_tokens_reached"
|
|
367
|
+
/** User cancellation landed after a non-terminal checkpoint yield. */
|
|
368
|
+
| "aborted_after_checkpoint"
|
|
369
|
+
/** User cancellation observed while the catch handler synthesized an error turn. */
|
|
370
|
+
| "aborted_via_error"
|
|
371
|
+
/** An unhandled error ended the turn. */
|
|
372
|
+
| "error";
|
|
255
373
|
|
|
256
374
|
/**
|
|
257
|
-
* Context passed to the `stop` hook
|
|
258
|
-
* with no tool calls — the run's stop boundary, where the loop is about to
|
|
259
|
-
* hand the turn back to the user. The default empty-response plugin uses it
|
|
260
|
-
* to re-query the model when a turn came back empty or as a provider refusal.
|
|
375
|
+
* Context passed to the `stop` hook — the loop's definitive terminal hook.
|
|
261
376
|
*
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
* boundary from the history itself — the messages after the last genuine user
|
|
269
|
-
* prompt — rather than an index, since mid-run compaction can rewrite the
|
|
270
|
-
* array.
|
|
377
|
+
* It fires exactly once per run, after the loop has committed to ending and
|
|
378
|
+
* will not run another iteration this run. Unlike `post-model-call` (which owns
|
|
379
|
+
* the model-call-outcome retry decision), `stop` cannot continue the loop: by
|
|
380
|
+
* the time it runs the turn's outcome is settled. That guarantee makes it the
|
|
381
|
+
* home for teardown — a hook can release per-turn resources or clear per-turn
|
|
382
|
+
* state knowing nothing will re-enter the loop this run.
|
|
271
383
|
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
384
|
+
* It fires on every terminal exit: a no-tool reply, a max-tokens stop, a
|
|
385
|
+
* yield-to-user, an exhausted context-overflow recovery, a user abort, or an
|
|
386
|
+
* unhandled error. It also fires on a `checkpoint_handoff`, which ends the run
|
|
387
|
+
* for teardown purposes even though the orchestrator resumes the conversation
|
|
388
|
+
* in a fresh run. {@link exitReason} reports which one and {@link error}
|
|
389
|
+
* carries the rejection when the turn ended on one, so a hook that should act
|
|
390
|
+
* only on a particular ending guards on {@link exitReason}.
|
|
391
|
+
*
|
|
392
|
+
* Multiple plugins' hooks chain in registration order over the same context.
|
|
274
393
|
*/
|
|
275
394
|
export interface StopContext {
|
|
276
395
|
/** Conversation ID the run belongs to. */
|
|
277
396
|
readonly conversationId: string;
|
|
278
397
|
/**
|
|
279
|
-
* Full conversation history
|
|
280
|
-
* message produced this run.
|
|
281
|
-
*
|
|
282
|
-
* next iteration.
|
|
398
|
+
* Full conversation history at the terminal stop — the inbound conversation
|
|
399
|
+
* followed by every message produced this run. Provided for inspection;
|
|
400
|
+
* mutating it has no effect, since the loop will not run again this turn.
|
|
283
401
|
*/
|
|
284
|
-
messages: Message
|
|
285
|
-
/**
|
|
286
|
-
* Content blocks of the assistant turn that triggered the stop. Guaranteed
|
|
287
|
-
* to contain no `tool_use` blocks — the hook only fires at the boundary
|
|
288
|
-
* where the model stopped requesting tools.
|
|
289
|
-
*/
|
|
290
|
-
readonly responseContent: ReadonlyArray<ContentBlock>;
|
|
402
|
+
readonly messages: ReadonlyArray<Message>;
|
|
291
403
|
/**
|
|
292
|
-
*
|
|
293
|
-
*
|
|
404
|
+
* The provider rejection that ended the turn, when it ended on one (e.g. an
|
|
405
|
+
* unrecoverable error after recovery hooks declined to retry). Absent on a
|
|
406
|
+
* clean stop.
|
|
294
407
|
*/
|
|
295
|
-
readonly
|
|
408
|
+
readonly error?: Error;
|
|
296
409
|
/**
|
|
297
|
-
*
|
|
298
|
-
*
|
|
410
|
+
* Which terminal state the turn reached. A `checkpoint_handoff` fires this
|
|
411
|
+
* hook for teardown — the run pauses so the orchestrator can drain a queued
|
|
412
|
+
* message — but is not emitted as an `agent_loop_exit`, since the
|
|
413
|
+
* conversation resumes in a fresh run. `aborted_after_checkpoint` is a
|
|
414
|
+
* control transfer that re-enters the loop and so never reaches this hook.
|
|
299
415
|
*/
|
|
300
|
-
|
|
416
|
+
readonly exitReason: AgentLoopExitReason;
|
|
301
417
|
/**
|
|
302
418
|
* Logger scoped to the current turn. The same instance is shared by
|
|
303
419
|
* every hook in the chain, so plugins should tag their structured log
|
|
@@ -325,14 +441,14 @@ export interface PreModelCallContext {
|
|
|
325
441
|
readonly conversationId: string;
|
|
326
442
|
/**
|
|
327
443
|
* The call site this provider call serves — `"mainAgent"` for the user-facing
|
|
328
|
-
* reply, or a background/utility site.
|
|
444
|
+
* reply, or a background/utility site. `null` for call sites that don't tag one.
|
|
329
445
|
*/
|
|
330
|
-
readonly callSite
|
|
446
|
+
readonly callSite: LLMCallSite | null;
|
|
331
447
|
/**
|
|
332
448
|
* The system prompt about to be sent. A hook may replace it (e.g. strip or
|
|
333
449
|
* append a section); the loop sends the resulting value.
|
|
334
450
|
*/
|
|
335
|
-
systemPrompt: string |
|
|
451
|
+
systemPrompt: string | null;
|
|
336
452
|
/**
|
|
337
453
|
* Seeded `false`. When a hook sets it `true`, the loop suppresses this turn's
|
|
338
454
|
* live assistant `text_delta` stream; a `post-model-call` hook is then
|
|
@@ -348,32 +464,81 @@ export interface PreModelCallContext {
|
|
|
348
464
|
// ─── Post-model-call hook context ────────────────────────────────────────────
|
|
349
465
|
|
|
350
466
|
/**
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
* before the message is persisted and (if deferred) streamed-final. Unlike
|
|
354
|
-
* {@link StopContext}'s read-only `responseContent` (which exists for the stop
|
|
355
|
-
* decision), {@link content} is mutable: the loop adopts the hook's result as the
|
|
356
|
-
* persisted and streamed message.
|
|
467
|
+
* Binary outcome of the `post-model-call` hook. The agent loop seeds it to
|
|
468
|
+
* `"stop"` and acts on the value the chain settles on:
|
|
357
469
|
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
*
|
|
363
|
-
*
|
|
470
|
+
* - `"stop"` — accept the model-call outcome. On a finalized reply the loop
|
|
471
|
+
* keeps the (possibly transformed) message; on a rejection it
|
|
472
|
+
* surfaces the error. This is the default.
|
|
473
|
+
* - `"continue"` — re-query the model. The hook is responsible for leaving
|
|
474
|
+
* {@link PostModelCallContext.messages} as the history the next
|
|
475
|
+
* iteration should send (append a follow-up turn, or replace
|
|
476
|
+
* the array with a repaired one).
|
|
477
|
+
*/
|
|
478
|
+
export type PostModelCallDecision = "continue" | "stop";
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Context passed to the `post-model-call` hook. Fires at every model-call
|
|
482
|
+
* outcome — the seam where the loop reacts to what the provider returned:
|
|
483
|
+
*
|
|
484
|
+
* - **Finalized reply.** The provider returned a message. {@link error} is
|
|
485
|
+
* absent, {@link content} holds the reply's blocks (mutable — the loop adopts
|
|
486
|
+
* the hook's result as the persisted and streamed message), and
|
|
487
|
+
* {@link stopReason} carries the provider's stop reason. Fires once per model
|
|
488
|
+
* call, including tool-bearing turns (a reply can carry both text and
|
|
489
|
+
* `tool_use`), so a hook should transform only the blocks it owns and leave
|
|
490
|
+
* others — notably `tool_use` — intact.
|
|
491
|
+
* - **Provider rejection.** The call threw before any reply existed.
|
|
492
|
+
* {@link error} holds the rejection, {@link content} is empty, and
|
|
493
|
+
* {@link stopReason} is `null`. A hook that recognizes the rejection may
|
|
494
|
+
* repair {@link messages} and set {@link decision} to `"continue"` to retry;
|
|
495
|
+
* hooks that only act on a real reply must guard on {@link error} and return
|
|
496
|
+
* early.
|
|
497
|
+
*
|
|
498
|
+
* The retry decision is honored only at actionable outcomes — a no-tool reply
|
|
499
|
+
* or a provider rejection — and is ignored on tool-bearing turns (the loop
|
|
500
|
+
* already runs the tools). The loop does not gate the decision on call site, so
|
|
501
|
+
* a hook that should only retry the user-facing turn MUST self-gate on
|
|
502
|
+
* {@link callSite} / {@link conversationId} to avoid re-querying background,
|
|
503
|
+
* subagent, or compaction calls. Mutate in place or return a new
|
|
504
|
+
* context; throwing is contained by the loop (the original content is kept and
|
|
505
|
+
* the outcome is treated as `"stop"`). Multiple plugins' hooks chain in
|
|
506
|
+
* registration order — each sees the previous hook's `decision` and mutations.
|
|
364
507
|
*/
|
|
365
508
|
export interface PostModelCallContext {
|
|
366
509
|
/** Conversation ID the message belongs to. */
|
|
367
510
|
readonly conversationId: string;
|
|
368
|
-
/** The call site this message serves — `"mainAgent"` for the user-facing reply. */
|
|
369
|
-
readonly callSite
|
|
511
|
+
/** The call site this message serves — `"mainAgent"` for the user-facing reply; `null` when untagged. */
|
|
512
|
+
readonly callSite: LLMCallSite | null;
|
|
370
513
|
/**
|
|
371
514
|
* The finalized message content. Mutable — transform the text blocks and leave
|
|
372
|
-
* `tool_use` (and other non-text blocks) intact.
|
|
515
|
+
* `tool_use` (and other non-text blocks) intact. Empty on a provider rejection.
|
|
373
516
|
*/
|
|
374
517
|
content: ContentBlock[];
|
|
375
|
-
/**
|
|
376
|
-
|
|
518
|
+
/**
|
|
519
|
+
* Full conversation history: the inbound conversation followed by every
|
|
520
|
+
* message produced this run. A hook that sets {@link decision} to
|
|
521
|
+
* `"continue"` leaves this as the history the next iteration should send — a
|
|
522
|
+
* finalized-reply hook appends its follow-up turn (e.g. a nudge `user`
|
|
523
|
+
* message); a rejection-recovery hook replaces the array with a repaired one.
|
|
524
|
+
*/
|
|
525
|
+
messages: Message[];
|
|
526
|
+
/** Provider-reported stop reason for the turn; `null` when not reported. */
|
|
527
|
+
readonly stopReason: string | null;
|
|
528
|
+
/**
|
|
529
|
+
* The provider rejection that ended the call, on a rejection outcome. Absent
|
|
530
|
+
* on a finalized reply. A hook that recovers from a specific rejection class
|
|
531
|
+
* inspects this and may repair {@link messages} and set {@link decision} to
|
|
532
|
+
* `"continue"`; hooks that only act on a real reply must return early when it
|
|
533
|
+
* is present.
|
|
534
|
+
*/
|
|
535
|
+
readonly error?: Error;
|
|
536
|
+
/**
|
|
537
|
+
* Seeded to `"stop"`. A hook sets it to `"continue"` to force another loop
|
|
538
|
+
* iteration; later hooks in the chain may override it. Honored only at
|
|
539
|
+
* actionable outcomes (see the interface docstring).
|
|
540
|
+
*/
|
|
541
|
+
decision: PostModelCallDecision;
|
|
377
542
|
/** Logger scoped to the current turn (tag structured fields with `{ plugin }`). */
|
|
378
543
|
readonly logger: PluginLogger;
|
|
379
544
|
}
|
|
@@ -14,7 +14,10 @@ import type { Message } from "../../../providers/types.js";
|
|
|
14
14
|
import type { TrustClass } from "../../../runtime/actor-trust-resolver.js";
|
|
15
15
|
import { PluginExecutionError } from "../../types.js";
|
|
16
16
|
import { getContextWindowManager } from "./manager-store.js";
|
|
17
|
-
import type {
|
|
17
|
+
import type {
|
|
18
|
+
ContextWindowResult,
|
|
19
|
+
EmergencyCompactOptions,
|
|
20
|
+
} from "./window-manager.js";
|
|
18
21
|
|
|
19
22
|
/**
|
|
20
23
|
* Name under which the default compaction plugin registers. Exposed so call
|
|
@@ -46,6 +49,19 @@ export interface CompactionContext {
|
|
|
46
49
|
minKeepRecentUserTurns?: number;
|
|
47
50
|
/** Trust class of the actor whose turn triggered compaction. */
|
|
48
51
|
actorTrustClass?: TrustClass;
|
|
52
|
+
/**
|
|
53
|
+
* Set when this compaction is recovering from a provider context-overflow
|
|
54
|
+
* rejection rather than the ordinary auto-threshold trip. Its presence
|
|
55
|
+
* routes the request through the manager's reduction ladder (which escalates
|
|
56
|
+
* one rung per call) instead of plain forced compaction; the agent loop
|
|
57
|
+
* records it in its overflow catch and forwards it on the next gate pass.
|
|
58
|
+
*/
|
|
59
|
+
overflowSignal?: {
|
|
60
|
+
/** Provider-reported token count from the rejection, or `null`. */
|
|
61
|
+
actualTokens: number | null;
|
|
62
|
+
/** Whether a human is present this turn (drives the auto-compress policy). */
|
|
63
|
+
isInteractive: boolean;
|
|
64
|
+
};
|
|
49
65
|
}
|
|
50
66
|
|
|
51
67
|
/**
|
|
@@ -56,7 +72,8 @@ export interface CompactionContext {
|
|
|
56
72
|
export async function defaultCompact(
|
|
57
73
|
context: CompactionContext,
|
|
58
74
|
): Promise<ContextWindowResult> {
|
|
59
|
-
const { conversationId, messages, signal, ...options } =
|
|
75
|
+
const { conversationId, messages, signal, overflowSignal, ...options } =
|
|
76
|
+
context;
|
|
60
77
|
const manager = getContextWindowManager(conversationId);
|
|
61
78
|
if (manager == null) {
|
|
62
79
|
throw new PluginExecutionError(
|
|
@@ -64,5 +81,52 @@ export async function defaultCompact(
|
|
|
64
81
|
DEFAULT_COMPACTION_PLUGIN_NAME,
|
|
65
82
|
);
|
|
66
83
|
}
|
|
84
|
+
if (overflowSignal) {
|
|
85
|
+
return manager.recoverContextOverflow(
|
|
86
|
+
messages,
|
|
87
|
+
{
|
|
88
|
+
actualTokens: overflowSignal.actualTokens,
|
|
89
|
+
isInteractive: overflowSignal.isInteractive,
|
|
90
|
+
overrideProfile: options.overrideProfile,
|
|
91
|
+
actorTrustClass: options.actorTrustClass,
|
|
92
|
+
},
|
|
93
|
+
signal,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
67
96
|
return manager.maybeCompact(messages, signal, options);
|
|
68
97
|
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Self-describing emergency-compaction request handed to
|
|
101
|
+
* {@link defaultEmergencyCompact}. Mirrors {@link CompactionContext} but
|
|
102
|
+
* carries the provider-reported token estimate at the overflow that triggered
|
|
103
|
+
* recovery, which sizes the summarize-around-last-tool-pair cut.
|
|
104
|
+
*/
|
|
105
|
+
export interface EmergencyCompactionContext extends EmergencyCompactOptions {
|
|
106
|
+
/** Conversation whose manager performs the emergency compaction. */
|
|
107
|
+
conversationId: string;
|
|
108
|
+
/** Message history to summarize around the last tool_use/tool_result pair. */
|
|
109
|
+
messages: Message[];
|
|
110
|
+
/** Abort signal forwarded to the compaction summary call. */
|
|
111
|
+
signal?: AbortSignal;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Run emergency mid-turn compaction for the turn: resolves the conversation's
|
|
116
|
+
* context window manager from the compaction store and summarizes everything
|
|
117
|
+
* before the last tool_use/tool_result pair, preserving the agent's most recent
|
|
118
|
+
* action context while aggressively compressing earlier history.
|
|
119
|
+
*/
|
|
120
|
+
export async function defaultEmergencyCompact(
|
|
121
|
+
context: EmergencyCompactionContext,
|
|
122
|
+
): Promise<ContextWindowResult> {
|
|
123
|
+
const { conversationId, messages, signal, ...options } = context;
|
|
124
|
+
const manager = getContextWindowManager(conversationId);
|
|
125
|
+
if (manager == null) {
|
|
126
|
+
throw new PluginExecutionError(
|
|
127
|
+
`default-compaction: no ContextWindowManager registered for conversation ${conversationId} — the conversation must register one before emergency compaction runs`,
|
|
128
|
+
DEFAULT_COMPACTION_PLUGIN_NAME,
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
return manager.emergencyCompact(messages, options, signal);
|
|
132
|
+
}
|