@vellumai/assistant 0.8.6 → 0.8.7
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 +4 -4
- package/Dockerfile +1 -0
- package/bun.lock +11 -2
- package/docker-entrypoint.sh +8 -6
- package/docs/plugins.md +63 -28
- package/examples/plugins/echo/register.ts +4 -7
- package/knip.json +1 -0
- package/node_modules/@vellumai/environments/bun.lock +24 -0
- package/node_modules/@vellumai/environments/package.json +18 -0
- package/node_modules/@vellumai/environments/src/__tests__/package-boundary.test.ts +95 -0
- package/node_modules/@vellumai/environments/src/index.ts +11 -0
- package/node_modules/@vellumai/environments/src/seeds.ts +73 -0
- package/node_modules/@vellumai/environments/src/types.ts +70 -0
- package/node_modules/@vellumai/environments/tsconfig.json +20 -0
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +11 -0
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +3 -4
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +6 -2
- package/openapi.yaml +3735 -353
- package/package.json +7 -3
- package/scripts/generate-openapi.ts +20 -13
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +42 -80
- package/src/__tests__/agent-loop-exit-reason.test.ts +240 -39
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +141 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +19 -32
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +6 -4
- package/src/__tests__/agent-loop-thinking.test.ts +17 -12
- package/src/__tests__/agent-loop.test.ts +207 -341
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +4 -2
- package/src/__tests__/agent-wake-override-profile.test.ts +22 -40
- package/src/__tests__/anthropic-provider.test.ts +201 -55
- package/src/__tests__/app-builder-skill-instructions.test.ts +22 -0
- package/src/__tests__/app-control-flow.test.ts +5 -0
- package/src/__tests__/approval-cascade.test.ts +4 -11
- package/src/__tests__/approval-routes-http.test.ts +4 -2
- package/src/__tests__/assistant-event.test.ts +15 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
- package/src/__tests__/avatar-e2e.test.ts +7 -37
- package/src/__tests__/avatar-generator.test.ts +12 -42
- package/src/__tests__/avatar-identity-sync.test.ts +28 -3
- package/src/__tests__/background-shell-bash.test.ts +3 -7
- package/src/__tests__/btw-routes.test.ts +7 -12
- package/src/__tests__/call-pointer-messages.test.ts +5 -3
- package/src/__tests__/call-site-routing-provider.test.ts +22 -40
- package/src/__tests__/catalog-files.test.ts +1 -0
- package/src/__tests__/channel-approval-routes.test.ts +48 -20
- package/src/__tests__/channel-approvals.test.ts +3 -1
- package/src/__tests__/channel-invite-transport.test.ts +1 -5
- package/src/__tests__/channel-readiness-routes.test.ts +0 -4
- package/src/__tests__/channel-readiness-slack-remote.test.ts +2 -7
- package/src/__tests__/channel-retry-sweep.test.ts +71 -79
- package/src/__tests__/circuit-breaker-pipeline.test.ts +3 -3
- package/src/__tests__/clawhub-files.test.ts +1 -0
- package/src/__tests__/compaction-events.test.ts +5 -17
- package/src/__tests__/compaction-pipeline.test.ts +1 -1
- package/src/__tests__/compaction-timeout-recovery.test.ts +37 -48
- package/src/__tests__/compaction-trail-store.test.ts +1 -79
- package/src/__tests__/compactor-image-manifest-trust.test.ts +112 -0
- package/src/__tests__/computer-use-tools.test.ts +2 -2
- package/src/__tests__/config-watcher.test.ts +28 -0
- package/src/__tests__/context-search-agent-runner.test.ts +6 -3
- package/src/__tests__/context-token-estimator.test.ts +34 -0
- package/src/__tests__/context-window-manager-compact-retry.test.ts +291 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +14 -7
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +3 -2
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +12 -27
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +430 -90
- package/src/__tests__/conversation-agent-loop.test.ts +581 -62
- package/src/__tests__/conversation-analysis-routes.test.ts +1 -3
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
- package/src/__tests__/conversation-clear-safety.test.ts +20 -10
- package/src/__tests__/conversation-confirmation-signals.test.ts +15 -45
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-disk-view.test.ts +10 -17
- package/src/__tests__/conversation-fork-crud.test.ts +86 -172
- package/src/__tests__/conversation-fork-route.test.ts +16 -14
- package/src/__tests__/conversation-init.benchmark.test.ts +6 -6
- package/src/__tests__/conversation-lifecycle.test.ts +3 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +3 -2
- package/src/__tests__/conversation-load-history-stripped.test.ts +1 -1
- package/src/__tests__/conversation-message-sync-tags.test.ts +3 -4
- package/src/__tests__/conversation-pairing.test.ts +34 -4
- package/src/__tests__/conversation-pre-run-repair.test.ts +1 -1
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -0
- package/src/__tests__/conversation-process-callsite.test.ts +27 -30
- package/src/__tests__/conversation-provider-retry-repair.test.ts +53 -44
- package/src/__tests__/conversation-queue.test.ts +270 -164
- package/src/__tests__/conversation-routes-disk-view.test.ts +3 -2
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +2 -2
- package/src/__tests__/conversation-routes-slash-commands.test.ts +2 -2
- package/src/__tests__/conversation-runtime-assembly.test.ts +20 -22
- package/src/__tests__/conversation-runtime-workspace.test.ts +19 -1
- package/src/__tests__/conversation-slash-queue.test.ts +37 -31
- package/src/__tests__/conversation-slash-unknown.test.ts +13 -15
- package/src/__tests__/conversation-speed-override.test.ts +8 -22
- package/src/__tests__/conversation-stream-state.test.ts +484 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +6 -15
- package/src/__tests__/conversation-surfaces-app-control.test.ts +32 -4
- package/src/__tests__/conversation-surfaces-state-update.test.ts +5 -2
- package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -15
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +23 -11
- package/src/__tests__/conversation-unread-route.test.ts +14 -2
- package/src/__tests__/conversation-usage.test.ts +0 -2
- package/src/__tests__/conversation-wipe.test.ts +1 -1
- package/src/__tests__/conversation-workspace-cache-state.test.ts +3 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +48 -22
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +27 -7
- package/src/__tests__/credential-execution-tools.test.ts +1 -2
- package/src/__tests__/credential-security-invariants.test.ts +0 -1
- package/src/__tests__/cross-provider-web-search.test.ts +6 -2
- package/src/__tests__/cu-unified-flow.test.ts +26 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +11 -0
- package/src/__tests__/disk-pressure-guard.test.ts +66 -0
- package/src/__tests__/disk-pressure-routes.test.ts +9 -2
- package/src/__tests__/dm-persistence.test.ts +7 -2
- package/src/__tests__/dynamic-page-surface.test.ts +68 -0
- package/src/__tests__/edit-propagation.test.ts +1 -2
- package/src/__tests__/empty-response-pipeline.test.ts +127 -5
- package/src/__tests__/filing-service.test.ts +2 -2
- package/src/__tests__/first-greeting.test.ts +55 -14
- package/src/__tests__/gemini-inline-media.test.ts +78 -0
- package/src/__tests__/gemini-provider.test.ts +351 -28
- package/src/__tests__/guardian-routing-state.test.ts +60 -71
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +9 -7
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +2 -1
- package/src/__tests__/history-repair-hook.test.ts +161 -0
- package/src/__tests__/history-repair-observability.test.ts +1 -1
- package/src/__tests__/history-repair.test.ts +2 -1
- package/src/__tests__/host-app-control-proxy.test.ts +2 -0
- package/src/__tests__/host-cu-proxy.test.ts +2 -0
- package/src/__tests__/host-file-edit-tool.test.ts +4 -2
- package/src/__tests__/host-file-proxy.test.ts +31 -0
- package/src/__tests__/host-file-read-tool.test.ts +4 -2
- package/src/__tests__/host-file-write-tool.test.ts +9 -3
- package/src/__tests__/host-proxy-preactivation.test.ts +53 -14
- package/src/__tests__/host-shell-tool.test.ts +9 -4
- package/src/__tests__/http-user-message-parity.test.ts +2 -2
- package/src/__tests__/identity-intro-cache.test.ts +35 -14
- package/src/__tests__/inbound-slack-persistence.test.ts +7 -2
- package/src/__tests__/injector-background-turn.test.ts +1 -1
- package/src/__tests__/injector-chain.test.ts +1 -1
- package/src/__tests__/injector-disk-pressure.test.ts +1 -1
- package/src/__tests__/injector-document-comments.test.ts +1 -1
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +1 -1
- package/src/__tests__/injector-v3-suppression.test.ts +220 -0
- package/src/__tests__/list-messages-attachments.test.ts +7 -8
- package/src/__tests__/list-messages-hidden-metadata.test.ts +17 -15
- package/src/__tests__/list-messages-page-latest.test.ts +0 -1
- package/src/__tests__/list-messages-tool-merge.test.ts +36 -6
- package/src/__tests__/llm-call-pipeline.test.ts +21 -15
- package/src/__tests__/llm-request-log-turn-query.test.ts +42 -86
- package/src/__tests__/llm-resolver.test.ts +23 -47
- package/src/__tests__/llm-usage-store.test.ts +45 -0
- package/src/__tests__/log-export-routes.test.ts +59 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +1 -8
- package/src/__tests__/mcp-auth-routes.test.ts +15 -10
- package/src/__tests__/mcp-health-check.test.ts +18 -13
- package/src/__tests__/memory-retrieval-pipeline.test.ts +1 -1
- package/src/__tests__/memory-v2-static-injector.test.ts +1 -1
- package/src/__tests__/messaging-send-tool.test.ts +8 -4
- package/src/__tests__/migration-export-http.test.ts +12 -12
- package/src/__tests__/migration-import-commit-http.test.ts +8 -8
- package/src/__tests__/migration-import-preflight-http.test.ts +7 -7
- package/src/__tests__/migration-validate-http.test.ts +3 -3
- package/src/__tests__/native-web-search.test.ts +14 -20
- package/src/__tests__/notification-decision-identity.test.ts +9 -18
- package/src/__tests__/notification-decision-recipient-context.test.ts +3 -6
- package/src/__tests__/oauth-commands-routes.test.ts +1 -1
- package/src/__tests__/onboarding-template-contract.test.ts +10 -0
- package/src/__tests__/openai-provider.test.ts +66 -70
- package/src/__tests__/openai-responses-provider.test.ts +21 -77
- package/src/__tests__/outbound-slack-persistence.test.ts +2 -1
- package/src/__tests__/overflow-reduce-pipeline.test.ts +2 -4
- package/src/__tests__/parallel-tool.benchmark.test.ts +24 -36
- package/src/__tests__/persistence-pipeline.test.ts +15 -26
- package/src/__tests__/persistence-secret-redaction.test.ts +2 -1
- package/src/__tests__/pipeline-runner.test.ts +2 -3
- package/src/__tests__/plugin-bootstrap.test.ts +51 -25
- package/src/__tests__/plugin-route-contribution.test.ts +6 -16
- package/src/__tests__/plugin-skill-contribution.test.ts +7 -17
- package/src/__tests__/plugin-tool-contribution.test.ts +10 -26
- package/src/__tests__/plugin-types.test.ts +7 -14
- package/src/__tests__/prechat-onboarding-contract.test.ts +23 -0
- package/src/__tests__/process-message-background-slack.test.ts +17 -16
- package/src/__tests__/process-message-display-content.test.ts +30 -42
- package/src/__tests__/provider-commit-message-generator.test.ts +19 -14
- package/src/__tests__/provider-error-scenarios.test.ts +7 -6
- package/src/__tests__/provider-platform-proxy-integration.test.ts +3 -8
- package/src/__tests__/provider-send-message-override-profile.test.ts +9 -25
- package/src/__tests__/provider-streaming.benchmark.test.ts +12 -22
- package/src/__tests__/provider-usage-tracking.test.ts +0 -6
- package/src/__tests__/ratelimit.test.ts +9 -4
- package/src/__tests__/relay-server.test.ts +20 -13
- package/src/__tests__/retry-openrouter-only-normalization.test.ts +5 -8
- package/src/__tests__/retry-thinking-tool-choice.test.ts +10 -13
- package/src/__tests__/retry-verbosity-normalization.test.ts +5 -8
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +353 -0
- package/src/__tests__/schedule-routes.test.ts +80 -10
- package/src/__tests__/schedule-store.test.ts +67 -0
- package/src/__tests__/schedule-tools.test.ts +125 -0
- package/src/__tests__/secret-ingress-http.test.ts +2 -2
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +11 -7
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +11 -9
- package/src/__tests__/secret-response-routing.test.ts +13 -11
- package/src/__tests__/send-endpoint-busy.test.ts +2 -1
- package/src/__tests__/shell-observability.test.ts +249 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +11 -11
- package/src/__tests__/skill-feature-flags.test.ts +6 -6
- package/src/__tests__/skill-load-feature-flag.test.ts +10 -10
- package/src/__tests__/skills-files-catalog-fallback.test.ts +10 -0
- package/src/__tests__/skillssh-files.test.ts +1 -0
- package/src/__tests__/starter-task-flow.test.ts +6 -6
- package/src/__tests__/strip-memory-injections.test.ts +102 -14
- package/src/__tests__/subagent-call-site-routing.test.ts +2 -2
- package/src/__tests__/suggestion-routes.test.ts +3 -3
- package/src/__tests__/sync-message-contract.test.ts +19 -16
- package/src/__tests__/system-prompt.test.ts +54 -0
- package/src/__tests__/terminal-tools.test.ts +3 -24
- package/src/__tests__/thread-backfill.test.ts +4 -9
- package/src/__tests__/title-generate-pipeline.test.ts +1 -1
- package/src/__tests__/token-estimate-pipeline.test.ts +2 -4
- package/src/__tests__/tool-error-pipeline.test.ts +2 -2
- package/src/__tests__/tool-execute-pipeline.test.ts +1 -1
- package/src/__tests__/tool-preview-lifecycle.test.ts +13 -11
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +9 -12
- package/src/__tests__/tool-result-truncation.test.ts +3 -1
- package/src/__tests__/tools-audio-read.test.ts +113 -0
- package/src/__tests__/turn-boundary-resolution.test.ts +44 -84
- package/src/__tests__/turn-events-store.test.ts +11 -7
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +8 -6
- package/src/__tests__/voice-session-bridge.test.ts +13 -7
- package/src/acp/__tests__/prepare-agent-env.test.ts +143 -31
- package/src/acp/prepare-agent-env.ts +52 -11
- package/src/agent/compaction-circuit.ts +140 -0
- package/src/agent/loop.ts +409 -85
- package/src/api/README.md +19 -17
- package/src/api/constants/tool-execution.ts +21 -0
- package/src/api/events/assistant-activity-state.ts +75 -0
- package/src/api/events/assistant-outbound-attachment.ts +25 -27
- package/src/api/events/assistant-text-delta.ts +6 -8
- package/src/api/events/assistant-turn-start.ts +5 -7
- package/src/api/events/avatar-updated.ts +24 -0
- package/src/api/events/compaction-circuit-closed.ts +26 -0
- package/src/api/events/compaction-circuit-open.ts +28 -0
- package/src/api/events/confirmation-request.ts +114 -0
- package/src/api/events/contact-request.ts +33 -0
- package/src/api/events/conversation-error.ts +77 -0
- package/src/api/events/conversation-list-invalidated.ts +38 -0
- package/src/api/events/conversation-title-updated.ts +24 -0
- package/src/api/events/disk-pressure-status-changed.ts +61 -0
- package/src/api/events/document-comment-created.ts +24 -28
- package/src/api/events/document-comment-deleted.ts +6 -8
- package/src/api/events/document-comment-reopened.ts +6 -8
- package/src/api/events/document-comment-resolved.ts +8 -10
- package/src/api/events/document-editor-update.ts +27 -0
- package/src/api/events/error.ts +32 -0
- package/src/api/events/generation-cancelled.ts +4 -6
- package/src/api/events/generation-handoff.ts +13 -15
- package/src/api/events/home-feed-updated.ts +26 -0
- package/src/api/events/identity-changed.ts +32 -0
- package/src/api/events/interaction-resolved.ts +50 -0
- package/src/api/events/message-complete.ts +10 -12
- package/src/api/events/message-dequeued.ts +21 -0
- package/src/api/events/message-queued-deleted.ts +23 -0
- package/src/api/events/message-queued.ts +22 -0
- package/src/api/events/message-request-complete.ts +29 -0
- package/src/api/events/navigate-settings.ts +20 -0
- package/src/api/events/notification-intent.ts +33 -0
- package/src/api/events/open-url.ts +6 -8
- package/src/api/events/question-request.ts +67 -0
- package/src/api/events/relationship-state-updated.ts +4 -6
- package/src/api/events/secret-request.ts +42 -0
- package/src/api/events/subagent-event.ts +79 -0
- package/src/api/events/subagent-spawned.ts +40 -0
- package/src/api/events/subagent-status-changed.ts +65 -0
- package/src/api/events/sync-changed.ts +29 -0
- package/src/api/events/tool-result.ts +129 -0
- package/src/api/events/tool-use-start.ts +8 -10
- package/src/api/events/turn-profile-auto-routed.ts +28 -0
- package/src/api/events/ui-surface-complete.ts +30 -0
- package/src/api/events/ui-surface-dismiss.ts +22 -0
- package/src/api/events/ui-surface-show.ts +67 -0
- package/src/api/events/ui-surface-update.ts +26 -0
- package/src/api/events/usage-update.ts +34 -0
- package/src/api/events/user-message-echo.ts +35 -0
- package/src/api/index.ts +354 -0
- package/src/api/requests/dictation.ts +45 -0
- package/src/api/responses/disk-pressure-status.ts +26 -0
- package/src/api/responses/home.ts +217 -0
- package/src/api/responses/llm-context-response.ts +2 -0
- package/src/api/responses/memory-v3-selection-log.ts +50 -0
- package/src/api/responses/subagent-detail.ts +48 -0
- package/src/approvals/guardian-decision-primitive.ts +7 -15
- package/src/approvals/guardian-request-resolvers.ts +6 -9
- package/src/avatar/__tests__/avatar-manifest.test.ts +236 -0
- package/src/avatar/__tests__/avatar-store.test.ts +193 -0
- package/src/avatar/avatar-manifest.ts +195 -0
- package/src/avatar/avatar-store.ts +113 -0
- package/src/avatar/traits-png-sync.ts +8 -2
- package/src/background-wake/next-wake.test.ts +31 -1
- package/src/background-wake/next-wake.ts +4 -1
- package/src/calls/call-conversation-messages.ts +6 -4
- package/src/calls/guardian-action-sweep.ts +6 -4
- package/src/calls/relay-server.ts +12 -8
- package/src/calls/voice-session-bridge.ts +13 -27
- package/src/cli/commands/__tests__/memory-v3.test.ts +245 -0
- package/src/cli/commands/avatar.ts +17 -11
- package/src/cli/commands/conversations.ts +15 -1
- package/src/cli/commands/db/__tests__/repair.test.ts +540 -0
- package/src/cli/commands/db/__tests__/status.test.ts +253 -0
- package/src/cli/commands/db/format.ts +48 -0
- package/src/cli/commands/db/index.ts +29 -0
- package/src/cli/commands/db/repair-step-conversation-backfill.ts +345 -0
- package/src/cli/commands/db/repair-step-integrity.ts +146 -0
- package/src/cli/commands/db/repair-steps.ts +164 -0
- package/src/cli/commands/db/repair.ts +141 -0
- package/src/cli/commands/db/status.ts +366 -0
- package/src/cli/commands/memory-v3.ts +159 -445
- package/src/cli/lib/cli-colors.ts +24 -6
- package/src/cli/program.ts +4 -5
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/assistant-feature-flags.ts +2 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +14 -3
- package/src/config/bundled-skills/media-processing/services/reduce.ts +6 -9
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +1 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
- package/src/config/call-site-defaults.ts +2 -7
- package/src/config/feature-flag-registry.json +25 -9
- package/src/config/schemas/__tests__/memory-v2.test.ts +1 -226
- package/src/config/schemas/call-site-catalog.ts +8 -15
- package/src/config/schemas/llm.ts +2 -3
- package/src/config/schemas/memory-lifecycle.ts +24 -0
- package/src/config/schemas/memory-v2.ts +0 -253
- package/src/config/schemas/memory-v3.ts +39 -0
- package/src/config/schemas/memory.ts +6 -1
- package/src/config/schemas/timeouts.ts +3 -1
- package/src/context/compactor.ts +54 -31
- package/src/context/token-estimator.ts +19 -0
- package/src/context/tool-result-truncation.ts +1 -43
- package/src/context/window-manager.ts +138 -20
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +2 -2
- package/src/daemon/__tests__/web-search-status-text.test.ts +10 -6
- package/src/daemon/approval-generators.ts +4 -4
- package/src/daemon/config-watcher.ts +7 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +225 -88
- package/src/daemon/conversation-agent-loop.ts +284 -584
- package/src/daemon/conversation-error.ts +7 -7
- package/src/daemon/conversation-history.ts +22 -6
- package/src/daemon/conversation-launch.ts +4 -8
- package/src/daemon/conversation-lifecycle.ts +10 -38
- package/src/daemon/conversation-messaging.ts +1 -3
- package/src/daemon/conversation-notifiers.ts +7 -5
- package/src/daemon/conversation-process.ts +100 -79
- package/src/daemon/conversation-runtime-assembly.ts +47 -21
- package/src/daemon/conversation-store.ts +6 -5
- package/src/daemon/conversation-surfaces.ts +55 -69
- package/src/daemon/conversation-tool-setup.ts +3 -0
- package/src/daemon/conversation.ts +91 -126
- package/src/daemon/daemon-skill-host.ts +2 -6
- package/src/daemon/disk-pressure-guard.ts +35 -29
- package/src/daemon/external-plugins-bootstrap.ts +46 -24
- package/src/daemon/first-greeting.ts +26 -4
- package/src/daemon/guardian-action-generators.ts +2 -2
- package/src/daemon/handlers/conversations.ts +6 -22
- package/src/daemon/handlers/shared.ts +4 -0
- package/src/daemon/handlers/skills.ts +15 -14
- package/src/daemon/host-app-control-proxy.ts +54 -1
- package/src/daemon/host-cu-proxy.ts +46 -22
- package/src/daemon/host-file-proxy.ts +25 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -6
- package/src/daemon/lifecycle.ts +28 -55
- package/src/daemon/message-protocol.ts +2 -3
- package/src/daemon/message-provenance.ts +49 -0
- package/src/daemon/message-types/contacts.ts +3 -20
- package/src/daemon/message-types/conversations.ts +13 -111
- package/src/daemon/message-types/documents.ts +3 -9
- package/src/daemon/message-types/home.ts +4 -17
- package/src/daemon/message-types/integrations.ts +2 -6
- package/src/daemon/message-types/messages.ts +28 -343
- package/src/daemon/message-types/notifications.ts +2 -32
- package/src/daemon/message-types/settings.ts +3 -8
- package/src/daemon/message-types/skills.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/message-types/sync.ts +12 -25
- package/src/daemon/message-types/workspace.ts +3 -11
- package/src/daemon/process-message.ts +49 -46
- package/src/daemon/server.ts +12 -0
- package/src/daemon/tool-side-effects.ts +10 -7
- package/src/daemon/trust-context.ts +13 -0
- package/src/daemon/wake-target-adapter.ts +11 -1
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -1
- package/src/heartbeat/heartbeat-run-store.ts +31 -0
- package/src/heartbeat/heartbeat-service.ts +16 -0
- package/src/home/feature-gate.ts +22 -0
- package/src/home/feed-types.ts +36 -221
- package/src/ipc/__tests__/email-ipc.test.ts +0 -9
- package/src/ipc/routes/__tests__/route-adapter.test.ts +244 -0
- package/src/ipc/routes/route-adapter.ts +45 -6
- package/src/ipc/skill-routes/__tests__/memory.test.ts +18 -9
- package/src/ipc/skill-routes/__tests__/providers.test.ts +10 -10
- package/src/ipc/skill-routes/__tests__/registries.test.ts +28 -18
- package/src/ipc/skill-routes/memory.ts +26 -13
- package/src/ipc/skill-routes/providers.ts +5 -6
- package/src/ipc/skill-routes/registries.ts +13 -61
- package/src/live-voice/__tests__/live-voice-archive.test.ts +24 -11
- package/src/memory/__tests__/conversation-queries.test.ts +192 -8
- package/src/memory/__tests__/db-maintenance.test.ts +128 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +5 -4
- package/src/memory/__tests__/memory-retrospective-job.test.ts +10 -6
- package/src/memory/__tests__/memory-v3-selections-migration.test.ts +103 -0
- package/src/memory/context-search/agent-runner.ts +2 -4
- package/src/memory/conversation-crud.ts +39 -8
- package/src/memory/conversation-queries.ts +78 -22
- package/src/memory/db-init.ts +8 -0
- package/src/memory/db-maintenance.ts +18 -2
- package/src/memory/graph/consolidation.ts +8 -11
- package/src/memory/graph/conversation-graph-memory.ts +41 -8
- package/src/memory/graph/extraction.ts +6 -9
- package/src/memory/graph/narrative.ts +2 -2
- package/src/memory/graph/pattern-scan.ts +2 -2
- package/src/memory/graph/retriever.ts +20 -26
- package/src/memory/graph/tools.ts +4 -4
- package/src/memory/job-handlers/conversation-starters.ts +32 -32
- package/src/memory/job-handlers/summarization.ts +1 -2
- package/src/memory/jobs-store.ts +3 -1
- package/src/memory/jobs-worker.ts +51 -39
- package/src/memory/llm-request-log-source-clickhouse.ts +5 -31
- package/src/memory/llm-request-log-source-local.ts +0 -11
- package/src/memory/llm-request-log-source.ts +9 -25
- package/src/memory/llm-request-log-store.ts +0 -41
- package/src/memory/llm-usage-store.ts +10 -0
- package/src/memory/memory-marker.ts +17 -0
- package/src/memory/memory-retrospective-job.ts +6 -2
- package/src/memory/memory-v2-activation-log-store.ts +1 -83
- package/src/memory/migrations/267-llm-usage-events-add-assistant-version.ts +46 -0
- package/src/memory/migrations/268-add-memory-v3-selections.ts +28 -0
- package/src/memory/migrations/269-schedule-script-timeout.ts +11 -0
- package/src/memory/migrations/270-messages-role-created-at-index.ts +18 -0
- package/src/memory/migrations/__tests__/267-llm-usage-events-add-assistant-version.test.ts +117 -0
- package/src/memory/migrations/index.ts +4 -0
- package/src/memory/schema/infrastructure.ts +11 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +124 -0
- package/src/memory/v2/__tests__/migration.test.ts +11 -3
- package/src/memory/v2/__tests__/page-index.test.ts +37 -1
- package/src/memory/v2/__tests__/router.test.ts +14 -4
- package/src/memory/v2/__tests__/sweep-job.test.ts +6 -5
- package/src/memory/v2/backfill-jobs.ts +6 -0
- package/src/memory/v2/consolidation-job.ts +89 -9
- package/src/memory/v2/migration.ts +5 -3
- package/src/memory/v2/page-index.ts +11 -0
- package/src/memory/v2/router.ts +8 -11
- package/src/memory/v2/sweep-job.ts +8 -11
- package/src/memory/v2/types.ts +1 -0
- package/src/memory/v3/__tests__/assign.test.ts +242 -0
- package/src/memory/v3/__tests__/capabilities.test.ts +118 -0
- package/src/memory/v3/__tests__/core.test.ts +39 -0
- package/src/memory/v3/__tests__/fixtures/eval-turns.json +36 -0
- package/src/memory/v3/__tests__/fixtures/live-turns.json +37 -0
- package/src/memory/v3/__tests__/health.test.ts +203 -0
- package/src/memory/v3/__tests__/live-integration.test.ts +330 -0
- package/src/memory/v3/__tests__/maintain-job.test.ts +288 -0
- package/src/memory/v3/__tests__/needle.test.ts +107 -0
- package/src/memory/v3/__tests__/orchestrate.test.ts +400 -0
- package/src/memory/v3/__tests__/reconcile.test.ts +274 -0
- package/src/memory/v3/__tests__/render-injection.test.ts +61 -0
- package/src/memory/v3/__tests__/router.test.ts +260 -0
- package/src/memory/v3/__tests__/selection-log-store.test.ts +179 -0
- package/src/memory/v3/__tests__/selector.test.ts +404 -0
- package/src/memory/v3/__tests__/shadow-plugin.test.ts +414 -0
- package/src/memory/v3/__tests__/snapshot.test.ts +168 -0
- package/src/memory/v3/__tests__/tree.test.ts +192 -0
- package/src/memory/v3/__tests__/types.test.ts +54 -0
- package/src/memory/v3/__tests__/working-set-eviction.test.ts +106 -0
- package/src/memory/v3/__tests__/working-set-skeleton.test.ts +44 -0
- package/src/memory/v3/assign.ts +268 -0
- package/src/memory/v3/capabilities.ts +124 -0
- package/src/memory/v3/core.ts +26 -0
- package/src/memory/v3/data/README.md +84 -0
- package/src/memory/v3/data/assignments.json +5 -0
- package/src/memory/v3/data/core.json +1 -0
- package/src/memory/v3/data/leaves/domain-a/topic-x.md +9 -0
- package/src/memory/v3/data/leaves/domain-a/topic-y.md +9 -0
- package/src/memory/v3/data/leaves/domain-b/topic-z.md +9 -0
- package/src/memory/v3/health.ts +0 -0
- package/src/memory/v3/maintain-job.ts +314 -0
- package/src/memory/v3/needle.ts +115 -0
- package/src/memory/v3/orchestrate.ts +114 -0
- package/src/memory/v3/page-content.ts +34 -0
- package/src/memory/v3/provider-blocks.ts +16 -0
- package/src/memory/v3/reconcile.ts +523 -0
- package/src/memory/v3/render-injection.ts +32 -0
- package/src/memory/v3/router.ts +184 -0
- package/src/memory/v3/selection-log-store.ts +84 -0
- package/src/memory/v3/selector.ts +211 -0
- package/src/memory/v3/shadow-plugin.ts +379 -0
- package/src/memory/v3/snapshot.ts +209 -0
- package/src/memory/v3/tree.ts +174 -0
- package/src/memory/v3/types.ts +46 -60
- package/src/memory/v3/working-set.ts +88 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +1 -1
- package/src/messaging/providers/slack/render-transcript.ts +2 -2
- package/src/messaging/style-analyzer.ts +8 -11
- package/src/notifications/conversation-pairing.ts +8 -6
- package/src/notifications/decision-engine.ts +10 -13
- package/src/notifications/preference-extractor.ts +11 -14
- package/src/permissions/prompter.ts +42 -36
- package/src/permissions/question-prompter.test.ts +35 -26
- package/src/permissions/question-prompter.ts +6 -10
- package/src/plugin-api/index.ts +2 -0
- package/src/plugin-api/types.ts +25 -3
- package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +93 -0
- package/src/plugins/defaults/circuit-breaker/package.json +15 -0
- package/src/plugins/defaults/circuit-breaker/register.ts +39 -0
- package/src/plugins/defaults/compaction/middlewares/compaction.ts +25 -0
- package/src/plugins/defaults/compaction/package.json +15 -0
- package/src/plugins/defaults/compaction/register.ts +35 -0
- package/src/plugins/defaults/compaction/terminal.ts +73 -0
- package/src/plugins/defaults/empty-response/middlewares/emptyResponse.ts +22 -0
- package/src/plugins/defaults/empty-response/package.json +15 -0
- package/src/plugins/defaults/empty-response/register.ts +28 -0
- package/src/plugins/defaults/empty-response/terminal.ts +106 -0
- package/src/plugins/defaults/history-repair/hooks/user-prompt-submit.ts +35 -0
- package/src/plugins/defaults/history-repair/package.json +15 -0
- package/src/plugins/defaults/history-repair/register.ts +24 -0
- package/src/{daemon/history-repair.ts → plugins/defaults/history-repair/terminal.ts} +48 -35
- package/src/plugins/defaults/index.ts +29 -40
- package/src/plugins/defaults/injectors/package.json +15 -0
- package/src/plugins/defaults/{injectors.ts → injectors/register.ts} +14 -38
- package/src/plugins/defaults/llm-call/middlewares/llmCall.ts +17 -0
- package/src/plugins/defaults/llm-call/package.json +15 -0
- package/src/plugins/defaults/{llm-call.ts → llm-call/register.ts} +6 -38
- package/src/plugins/defaults/memory-retrieval/middlewares/memoryRetrieval.ts +17 -0
- package/src/plugins/defaults/memory-retrieval/package.json +15 -0
- package/src/plugins/defaults/{memory-retrieval.ts → memory-retrieval/register.ts} +10 -48
- package/src/plugins/defaults/{overflow-reduce.ts → overflow-reduce/middlewares/overflowReduce.ts} +18 -77
- package/src/plugins/defaults/overflow-reduce/package.json +15 -0
- package/src/plugins/defaults/overflow-reduce/register.ts +42 -0
- package/src/plugins/defaults/persistence/middlewares/persistence.ts +19 -0
- package/src/plugins/defaults/persistence/package.json +15 -0
- package/src/plugins/defaults/persistence/register.ts +38 -0
- package/src/plugins/defaults/persistence/terminal.ts +83 -0
- package/src/plugins/defaults/title-generate/package.json +15 -0
- package/src/plugins/defaults/title-generate/register.ts +35 -0
- package/src/plugins/defaults/title-generate/terminal.ts +31 -0
- package/src/plugins/defaults/token-estimate/middlewares/tokenEstimate.ts +23 -0
- package/src/plugins/defaults/token-estimate/package.json +15 -0
- package/src/plugins/defaults/token-estimate/register.ts +34 -0
- package/src/plugins/defaults/token-estimate/terminal.ts +40 -0
- package/src/plugins/defaults/tool-error/middlewares/toolError.ts +21 -0
- package/src/plugins/defaults/tool-error/package.json +15 -0
- package/src/plugins/defaults/tool-error/register.ts +35 -0
- package/src/plugins/defaults/tool-error/terminal.ts +47 -0
- package/src/plugins/defaults/tool-execute/middlewares/toolExecute.ts +23 -0
- package/src/plugins/defaults/tool-execute/package.json +15 -0
- package/src/plugins/defaults/{tool-execute.ts → tool-execute/register.ts} +8 -46
- package/src/plugins/defaults/tool-result-truncate/middlewares/toolResultTruncate.ts +23 -0
- package/src/plugins/defaults/tool-result-truncate/package.json +15 -0
- package/src/plugins/defaults/tool-result-truncate/register.ts +35 -0
- package/src/plugins/defaults/tool-result-truncate/terminal.ts +113 -0
- package/src/plugins/defaults/tool-result-truncate/types.ts +22 -0
- package/src/plugins/external-plugin-loader.ts +2 -2
- package/src/plugins/pipeline.ts +0 -12
- package/src/plugins/types.ts +51 -90
- package/src/plugins/user-loader.ts +4 -3
- package/src/proactive-artifact/aux-message-injector.ts +0 -1
- package/src/proactive-artifact/job.test.ts +20 -8
- package/src/proactive-artifact/job.ts +3 -1
- package/src/prompts/sections.ts +20 -7
- package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +2 -2
- package/src/prompts/templates/BOOTSTRAP.md +5 -1
- package/src/prompts/templates/system-sections.ts +6 -0
- package/src/providers/__tests__/retry-callsite.test.ts +25 -25
- package/src/providers/__tests__/satellite-connection-routing.test.ts +7 -21
- package/src/providers/anthropic/client.ts +24 -5
- package/src/providers/call-site-routing.ts +1 -9
- package/src/providers/gemini/client.ts +152 -34
- package/src/providers/gemini/inline-media.ts +74 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +0 -2
- package/src/providers/openai/chat-completions-provider.ts +1 -4
- package/src/providers/openai/responses-provider.ts +1 -4
- package/src/providers/openrouter/client.ts +1 -6
- package/src/providers/provider-send-message.ts +6 -6
- package/src/providers/ratelimit.ts +1 -9
- package/src/providers/retry.ts +0 -5
- package/src/providers/types.ts +11 -2
- package/src/providers/usage-tracking.ts +1 -9
- package/src/runtime/__tests__/agent-wake.test.ts +131 -26
- package/src/runtime/__tests__/background-job-runner.test.ts +1 -3
- package/src/runtime/agent-wake.ts +93 -18
- package/src/runtime/assistant-event-hub.ts +2 -2
- package/src/runtime/auth/__tests__/guard-tests.test.ts +75 -109
- package/src/runtime/auth/__tests__/route-policy.test.ts +153 -170
- package/src/runtime/auth/route-policy.ts +42 -1079
- package/src/runtime/background-job-runner.ts +1 -4
- package/src/runtime/btw-sidechain.ts +3 -1
- package/src/runtime/channel-approvals.ts +3 -14
- package/src/runtime/channel-invite-transport.ts +5 -6
- package/src/runtime/channel-readiness-service.ts +2 -5
- package/src/runtime/channel-retry-sweep.ts +12 -16
- package/src/runtime/conversation-stream-state.ts +294 -0
- package/src/runtime/http-router.ts +19 -22
- package/src/runtime/http-types.ts +12 -6
- package/src/runtime/invite-instruction-generator.ts +3 -3
- package/src/runtime/pending-interactions.ts +2 -2
- package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +565 -0
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +4 -4
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +62 -32
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +237 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -22
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +7 -2
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +6 -6
- package/src/runtime/routes/__tests__/stt-routes.test.ts +3 -3
- package/src/runtime/routes/__tests__/suggest-trust-rule-routes.test.ts +5 -2
- package/src/runtime/routes/__tests__/tts-routes.test.ts +3 -3
- package/src/runtime/routes/acp-routes.test.ts +97 -75
- package/src/runtime/routes/acp-routes.ts +29 -6
- package/src/runtime/routes/app-management-routes.ts +97 -24
- package/src/runtime/routes/app-routes.ts +25 -5
- package/src/runtime/routes/approval-routes.ts +16 -4
- package/src/runtime/routes/attachment-routes.ts +25 -1
- package/src/runtime/routes/audio-routes.ts +1 -0
- package/src/runtime/routes/audit-routes.ts +5 -0
- package/src/runtime/routes/auth-routes.ts +5 -0
- package/src/runtime/routes/avatar-routes.ts +238 -59
- package/src/runtime/routes/background-tool-routes.ts +9 -0
- package/src/runtime/routes/background-wake-routes.ts +13 -3
- package/src/runtime/routes/backup-routes.ts +45 -0
- package/src/runtime/routes/bookmark-routes.ts +13 -0
- package/src/runtime/routes/brain-graph-routes.ts +9 -0
- package/src/runtime/routes/browser-routes.ts +5 -0
- package/src/runtime/routes/browser-tabs-routes.ts +5 -0
- package/src/runtime/routes/btw-routes.ts +5 -1
- package/src/runtime/routes/cache-routes.ts +13 -0
- package/src/runtime/routes/call-routes.ts +21 -10
- package/src/runtime/routes/channel-availability-routes.ts +5 -1
- package/src/runtime/routes/channel-readiness-routes.ts +37 -4
- package/src/runtime/routes/channel-route-definitions.ts +21 -0
- package/src/runtime/routes/channel-verification-routes.ts +21 -0
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +9 -2
- package/src/runtime/routes/client-routes.ts +9 -0
- package/src/runtime/routes/consolidation-routes.ts +13 -5
- package/src/runtime/routes/contact-prompt-routes.ts +9 -0
- package/src/runtime/routes/contact-routes.ts +90 -23
- package/src/runtime/routes/content-source-routes.ts +5 -1
- package/src/runtime/routes/conversation-analysis-routes.ts +5 -1
- package/src/runtime/routes/conversation-attention-routes.ts +5 -0
- package/src/runtime/routes/conversation-cli-routes.ts +54 -7
- package/src/runtime/routes/conversation-compaction-routes.ts +54 -25
- package/src/runtime/routes/conversation-list-routes.ts +81 -12
- package/src/runtime/routes/conversation-management-routes.ts +57 -14
- package/src/runtime/routes/conversation-query-routes.ts +88 -41
- package/src/runtime/routes/conversation-routes.ts +74 -19
- package/src/runtime/routes/conversation-starter-routes.ts +22 -13
- package/src/runtime/routes/conversations-import-routes.ts +6 -1
- package/src/runtime/routes/credential-prompt-routes.ts +5 -0
- package/src/runtime/routes/credential-routes.ts +25 -6
- package/src/runtime/routes/debug-bash-routes.ts +5 -0
- package/src/runtime/routes/debug-routes.ts +11 -2
- package/src/runtime/routes/defer-routes.ts +13 -0
- package/src/runtime/routes/diagnostics-routes.ts +37 -46
- package/src/runtime/routes/disk-pressure-routes.ts +17 -31
- package/src/runtime/routes/document-comments-routes.ts +46 -27
- package/src/runtime/routes/documents-routes.ts +21 -10
- package/src/runtime/routes/domain-routes.ts +61 -28
- package/src/runtime/routes/email-routes.ts +33 -0
- package/src/runtime/routes/events-routes.ts +114 -9
- package/src/runtime/routes/filing-routes.ts +9 -4
- package/src/runtime/routes/gateway-log-routes.ts +5 -0
- package/src/runtime/routes/global-search-routes.ts +53 -50
- package/src/runtime/routes/group-routes.ts +21 -5
- package/src/runtime/routes/guardian-action-routes.ts +9 -0
- package/src/runtime/routes/guardian-approval-interception.ts +0 -31
- package/src/runtime/routes/heartbeat-routes.ts +25 -9
- package/src/runtime/routes/home-feed-routes.ts +23 -19
- package/src/runtime/routes/home-state-routes.ts +8 -40
- package/src/runtime/routes/host-app-control-routes.ts +5 -0
- package/src/runtime/routes/host-bash-routes.ts +5 -0
- package/src/runtime/routes/host-browser-routes.ts +13 -0
- package/src/runtime/routes/host-cu-routes.ts +5 -0
- package/src/runtime/routes/host-file-routes.ts +26 -6
- package/src/runtime/routes/host-transfer-routes.ts +13 -2
- package/src/runtime/routes/http-adapter.ts +1 -2
- package/src/runtime/routes/identity-intro-cache.ts +17 -6
- package/src/runtime/routes/identity-routes.ts +12 -2
- package/src/runtime/routes/image-generation-routes.ts +5 -0
- package/src/runtime/routes/inbound-message-handler.ts +15 -11
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +0 -12
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +15 -19
- package/src/runtime/routes/inference-profile-session-routes.ts +13 -3
- package/src/runtime/routes/inference-provider-connection-routes.ts +21 -5
- package/src/runtime/routes/inference-send-routes.ts +11 -11
- package/src/runtime/routes/integrations/a2a.ts +30 -7
- package/src/runtime/routes/integrations/slack/channel.ts +19 -3
- package/src/runtime/routes/integrations/slack/share.ts +9 -2
- package/src/runtime/routes/integrations/telegram.ts +28 -9
- package/src/runtime/routes/integrations/twilio.ts +35 -7
- package/src/runtime/routes/integrations/vercel.ts +3 -3
- package/src/runtime/routes/internal-oauth-routes.ts +5 -0
- package/src/runtime/routes/internal-twilio-routes.ts +13 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +39 -4
- package/src/runtime/routes/log-export-routes.ts +28 -10
- package/src/runtime/routes/mcp-auth-routes.ts +25 -0
- package/src/runtime/routes/memory-item-routes.ts +21 -10
- package/src/runtime/routes/memory-v2-routes.ts +90 -36
- package/src/runtime/routes/memory-v3-routes.ts +273 -407
- package/src/runtime/routes/migration-rollback-routes.ts +5 -1
- package/src/runtime/routes/migration-routes.ts +29 -0
- package/src/runtime/routes/notification-routes.ts +17 -1
- package/src/runtime/routes/oauth-apps.ts +33 -11
- package/src/runtime/routes/oauth-commands-routes.ts +37 -14
- package/src/runtime/routes/oauth-connect-routes.ts +9 -0
- package/src/runtime/routes/oauth-lifecycle-routes.ts +5 -1
- package/src/runtime/routes/oauth-providers.ts +35 -10
- package/src/runtime/routes/platform-routes.ts +21 -0
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +3 -2
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +37 -16
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +7 -3
- package/src/runtime/routes/playground/__tests__/state.test.ts +10 -3
- package/src/runtime/routes/playground/force-compact.ts +1 -1
- package/src/runtime/routes/playground/helpers.ts +0 -1
- package/src/runtime/routes/playground/inject-failures.ts +13 -8
- package/src/runtime/routes/playground/reset-circuit.ts +14 -9
- package/src/runtime/routes/playground/seed-conversation.ts +1 -1
- package/src/runtime/routes/playground/seeded-conversations.ts +3 -3
- package/src/runtime/routes/playground/state.ts +4 -3
- package/src/runtime/routes/plugins-routes.ts +22 -19
- package/src/runtime/routes/profiler-routes.ts +17 -4
- package/src/runtime/routes/ps-routes.ts +5 -0
- package/src/runtime/routes/publish-routes.ts +13 -3
- package/src/runtime/routes/question-routes.ts +5 -0
- package/src/runtime/routes/recording-routes.ts +25 -12
- package/src/runtime/routes/rename-conversation-routes.ts +5 -0
- package/src/runtime/routes/sanity-routes.ts +9 -2
- package/src/runtime/routes/schedule-routes.ts +137 -47
- package/src/runtime/routes/secret-routes.ts +17 -4
- package/src/runtime/routes/sequence-routes.ts +33 -0
- package/src/runtime/routes/settings-routes.ts +65 -19
- package/src/runtime/routes/skills-routes.ts +133 -69
- package/src/runtime/routes/slack-channel-routes.ts +5 -0
- package/src/runtime/routes/stt-routes.ts +13 -6
- package/src/runtime/routes/subagents-routes.ts +24 -18
- package/src/runtime/routes/suggest-trust-rule-routes.ts +7 -2
- package/src/runtime/routes/surface-action-routes.ts +9 -0
- package/src/runtime/routes/surface-content-routes.ts +10 -2
- package/src/runtime/routes/task-routes.ts +37 -0
- package/src/runtime/routes/telemetry-routes.ts +9 -0
- package/src/runtime/routes/trace-event-routes.ts +42 -1
- package/src/runtime/routes/trust-rules-routes.ts +5 -0
- package/src/runtime/routes/tts-routes.ts +13 -6
- package/src/runtime/routes/types.ts +17 -8
- package/src/runtime/routes/ui-request-routes.ts +5 -0
- package/src/runtime/routes/upgrade-broadcast-routes.ts +5 -0
- package/src/runtime/routes/usage-routes.ts +71 -3
- package/src/runtime/routes/user-routes-cli.ts +9 -0
- package/src/runtime/routes/user-routes.ts +5 -1
- package/src/runtime/routes/wake-conversation-routes.ts +5 -0
- package/src/runtime/routes/watcher-routes.ts +21 -0
- package/src/runtime/routes/webhook-routes.ts +9 -0
- package/src/runtime/routes/wipe-conversation-routes.ts +5 -0
- package/src/runtime/routes/work-items-routes.ts +47 -19
- package/src/runtime/routes/workspace-commit-routes.ts +5 -0
- package/src/runtime/routes/workspace-routes.test.ts +42 -0
- package/src/runtime/routes/workspace-routes.ts +120 -9
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -4
- package/src/runtime/services/analyze-conversation.ts +3 -6
- package/src/runtime/services/conversation-serializer.ts +24 -2
- package/src/runtime/sync/resource-sync-events.ts +16 -2
- package/src/runtime/sync/sync-publisher.ts +2 -2
- package/src/schedule/run-script.ts +28 -3
- package/src/schedule/schedule-store.ts +8 -0
- package/src/schedule/scheduler.ts +3 -1
- package/src/signals/user-message.ts +5 -8
- package/src/skills/catalog-files.ts +4 -1
- package/src/skills/clawhub-files.ts +2 -0
- package/src/skills/skillssh-files.ts +2 -0
- package/src/subagent/manager.ts +3 -6
- package/src/telemetry/types.ts +26 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +138 -1
- package/src/telemetry/usage-telemetry-reporter.ts +31 -0
- package/src/tools/acp/spawn.test.ts +88 -38
- package/src/tools/apps/definitions.ts +8 -4
- package/src/tools/ask-question/ask-question-tool.test.ts +120 -105
- package/src/tools/ask-question/ask-question-tool.ts +85 -90
- package/src/tools/computer-use/definitions.ts +28 -24
- package/src/tools/credential-execution/make-authenticated-request.ts +56 -51
- package/src/tools/credential-execution/manage-secure-command-tool.ts +2 -2
- package/src/tools/credential-execution/run-authenticated-command.ts +82 -77
- package/src/tools/credentials/vault.ts +112 -111
- package/src/tools/execution-target.ts +1 -1
- package/src/tools/execution-timeout.ts +3 -4
- package/src/tools/filesystem/edit.ts +45 -42
- package/src/tools/filesystem/list.ts +33 -30
- package/src/tools/filesystem/read.ts +54 -35
- package/src/tools/filesystem/write.ts +34 -31
- package/src/tools/host-filesystem/edit.ts +44 -42
- package/src/tools/host-filesystem/read.ts +49 -35
- package/src/tools/host-filesystem/transfer.ts +121 -108
- package/src/tools/host-filesystem/write.ts +33 -31
- package/src/tools/host-terminal/host-shell.ts +50 -48
- package/src/tools/memory/register.ts +23 -24
- package/src/tools/network/web-fetch.ts +49 -46
- package/src/tools/network/web-search.ts +16 -13
- package/src/tools/registry.ts +39 -16
- package/src/tools/schedule/create.ts +11 -0
- package/src/tools/schedule/update.ts +16 -0
- package/src/tools/shared/filesystem/audio-read.ts +122 -0
- package/src/tools/shared/filesystem/image-read.ts +1 -1
- package/src/tools/skills/execute.ts +34 -31
- package/src/tools/skills/load.ts +29 -23
- package/src/tools/subagent/notify-parent.ts +35 -32
- package/src/tools/system/avatar-generator.ts +13 -22
- package/src/tools/system/request-permission.ts +30 -27
- package/src/tools/terminal/shell.ts +190 -61
- package/src/tools/tool-defaults.ts +20 -9
- package/src/tools/tool-manifest.ts +4 -4
- package/src/tools/types.ts +74 -23
- package/src/tools/ui-surface/definitions.ts +69 -9
- package/src/usage/types.ts +10 -0
- package/src/util/errors.ts +2 -2
- package/src/util/map-limit.ts +27 -0
- package/src/util/platform.ts +15 -12
- package/src/work-items/work-item-runner.ts +7 -2
- package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +7 -20
- package/src/workspace/migrations/092-backfill-v3-leaves.ts +169 -0
- package/src/workspace/migrations/093-backfill-leaf-ids.ts +144 -0
- package/src/workspace/migrations/094-seed-avatar-manifest.ts +155 -0
- package/src/workspace/migrations/__tests__/094-seed-avatar-manifest.test.ts +136 -0
- package/src/workspace/migrations/__tests__/backfill-leaf-ids.test.ts +175 -0
- package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +124 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/workspace/provider-commit-message-generator.ts +15 -17
- package/tsconfig.json +4 -1
- package/src/__tests__/history-repair-pipeline.test.ts +0 -396
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +0 -340
- package/src/cli/commands/memory-v3-render.ts +0 -491
- package/src/daemon/message-types/disk-pressure.ts +0 -9
- package/src/email/feature-gate.ts +0 -23
- package/src/memory/v3/__tests__/coactivation-store.test.ts +0 -422
- package/src/memory/v3/__tests__/consolidation-job.test.ts +0 -466
- package/src/memory/v3/__tests__/coretrieval-seed.test.ts +0 -270
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +0 -324
- package/src/memory/v3/__tests__/edges.test.ts +0 -706
- package/src/memory/v3/__tests__/filter.test.ts +0 -560
- package/src/memory/v3/__tests__/gate.test.ts +0 -637
- package/src/memory/v3/__tests__/index-composition.test.ts +0 -291
- package/src/memory/v3/__tests__/loop.test.ts +0 -775
- package/src/memory/v3/__tests__/retriever.test.ts +0 -226
- package/src/memory/v3/__tests__/scouts.test.ts +0 -489
- package/src/memory/v3/__tests__/shadow-diff.test.ts +0 -225
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +0 -398
- package/src/memory/v3/__tests__/system-prompts.test.ts +0 -154
- package/src/memory/v3/__tests__/traversal.test.ts +0 -508
- package/src/memory/v3/__tests__/tree-index.test.ts +0 -280
- package/src/memory/v3/__tests__/tree-store.test.ts +0 -529
- package/src/memory/v3/__tests__/tree-walk.test.ts +0 -784
- package/src/memory/v3/__tests__/validate.test.ts +0 -277
- package/src/memory/v3/auto-edges.ts +0 -223
- package/src/memory/v3/coactivation-store.ts +0 -124
- package/src/memory/v3/consolidation-job.ts +0 -323
- package/src/memory/v3/coretrieval-seed.ts +0 -240
- package/src/memory/v3/edge-learning-job.ts +0 -160
- package/src/memory/v3/edges.ts +0 -286
- package/src/memory/v3/filter.ts +0 -286
- package/src/memory/v3/gate.ts +0 -349
- package/src/memory/v3/index-composition.ts +0 -126
- package/src/memory/v3/llm-capture.ts +0 -46
- package/src/memory/v3/loop.ts +0 -430
- package/src/memory/v3/maintenance.ts +0 -144
- package/src/memory/v3/prompt-context.ts +0 -33
- package/src/memory/v3/prompts/consolidation.ts +0 -458
- package/src/memory/v3/prompts/system-prompts.ts +0 -196
- package/src/memory/v3/retriever.ts +0 -33
- package/src/memory/v3/scouts.ts +0 -431
- package/src/memory/v3/shadow-diff.ts +0 -287
- package/src/memory/v3/shadow-middleware.ts +0 -347
- package/src/memory/v3/traversal.ts +0 -211
- package/src/memory/v3/tree-index.ts +0 -237
- package/src/memory/v3/tree-store.ts +0 -394
- package/src/memory/v3/tree-walk.ts +0 -356
- package/src/memory/v3/validate.ts +0 -323
- package/src/plugins/defaults/circuit-breaker.ts +0 -141
- package/src/plugins/defaults/compaction.ts +0 -141
- package/src/plugins/defaults/empty-response.ts +0 -124
- package/src/plugins/defaults/history-repair.ts +0 -83
- package/src/plugins/defaults/persistence.ts +0 -146
- package/src/plugins/defaults/title-generate.ts +0 -90
- package/src/plugins/defaults/token-estimate.ts +0 -101
- package/src/plugins/defaults/tool-error.ts +0 -119
- package/src/plugins/defaults/tool-result-truncate.ts +0 -84
- package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +0 -35
|
@@ -104,27 +104,27 @@ export class PermissionPrompter {
|
|
|
104
104
|
pendingInteractions.register(requestId, {
|
|
105
105
|
conversationId: conversationId ?? "",
|
|
106
106
|
kind: "confirmation",
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
107
|
+
confirmationDetails: {
|
|
108
|
+
toolName,
|
|
109
|
+
input: redactSensitiveFields(input),
|
|
110
|
+
riskLevel,
|
|
111
|
+
executionTarget,
|
|
112
|
+
allowlistOptions: allowlistOptions.map((o) => ({
|
|
113
|
+
label: o.label,
|
|
114
|
+
description: o.description,
|
|
115
|
+
pattern: o.pattern,
|
|
116
|
+
})),
|
|
117
|
+
scopeOptions: scopeOptions.map((o) => ({
|
|
118
|
+
label: o.label,
|
|
119
|
+
scope: o.scope,
|
|
120
|
+
})),
|
|
121
|
+
persistentDecisionsAllowed: persistentDecisionsAllowed ?? true,
|
|
122
|
+
},
|
|
123
|
+
rpcResolve: resolve as (value: unknown) => void,
|
|
124
|
+
rpcReject: reject,
|
|
125
|
+
timer,
|
|
126
|
+
toolUseId,
|
|
127
|
+
});
|
|
128
128
|
this.ownedIds.add(requestId);
|
|
129
129
|
|
|
130
130
|
if (signal) {
|
|
@@ -156,7 +156,10 @@ export class PermissionPrompter {
|
|
|
156
156
|
scope: o.scope,
|
|
157
157
|
})),
|
|
158
158
|
directoryScopeOptions: directoryScopeOptions
|
|
159
|
-
? directoryScopeOptions.map((o) => ({
|
|
159
|
+
? directoryScopeOptions.map((o) => ({
|
|
160
|
+
scope: o.scope,
|
|
161
|
+
label: o.label,
|
|
162
|
+
}))
|
|
160
163
|
: undefined,
|
|
161
164
|
diff,
|
|
162
165
|
conversationId,
|
|
@@ -186,9 +189,11 @@ export class PermissionPrompter {
|
|
|
186
189
|
resolveConfirmation(
|
|
187
190
|
requestId: string,
|
|
188
191
|
decision: UserDecision,
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
+
options?: {
|
|
193
|
+
selectedPattern?: string;
|
|
194
|
+
selectedScope?: string;
|
|
195
|
+
decisionContext?: string;
|
|
196
|
+
},
|
|
192
197
|
): void {
|
|
193
198
|
if (!this.ownedIds.has(requestId)) {
|
|
194
199
|
log.warn({ requestId }, "No pending prompt for confirmation response");
|
|
@@ -201,9 +206,12 @@ export class PermissionPrompter {
|
|
|
201
206
|
decision === "allow" ? "approved" : "rejected",
|
|
202
207
|
);
|
|
203
208
|
this.ownedIds.delete(requestId);
|
|
204
|
-
(interaction?.rpcResolve as ((v: ConfirmResult) => void) | undefined)?.(
|
|
205
|
-
|
|
206
|
-
|
|
209
|
+
(interaction?.rpcResolve as ((v: ConfirmResult) => void) | undefined)?.({
|
|
210
|
+
decision,
|
|
211
|
+
selectedPattern: options?.selectedPattern,
|
|
212
|
+
selectedScope: options?.selectedScope,
|
|
213
|
+
decisionContext: options?.decisionContext,
|
|
214
|
+
});
|
|
207
215
|
}
|
|
208
216
|
|
|
209
217
|
/**
|
|
@@ -215,14 +223,12 @@ export class PermissionPrompter {
|
|
|
215
223
|
for (const requestId of [...this.ownedIds]) {
|
|
216
224
|
const interaction = pendingInteractions.resolve(requestId, "superseded");
|
|
217
225
|
this.ownedIds.delete(requestId);
|
|
218
|
-
(interaction?.rpcResolve as ((v: ConfirmResult) => void) | undefined)?.(
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
},
|
|
225
|
-
);
|
|
226
|
+
(interaction?.rpcResolve as ((v: ConfirmResult) => void) | undefined)?.({
|
|
227
|
+
decision: "deny",
|
|
228
|
+
wasSystemCancel: true,
|
|
229
|
+
decisionContext:
|
|
230
|
+
"The user sent a new message instead of responding to this permission prompt. Stop what you are doing and respond to the user's new message. Do NOT retry this tool or request permission again until the user asks you to.",
|
|
231
|
+
});
|
|
226
232
|
}
|
|
227
233
|
}
|
|
228
234
|
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
2
|
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
ServerMessage,
|
|
6
|
-
} from "../daemon/message-protocol.js";
|
|
3
|
+
import type { QuestionRequestEvent } from "../api/events/question-request.js";
|
|
4
|
+
import type { ServerMessage } from "../daemon/message-protocol.js";
|
|
7
5
|
import type {
|
|
8
6
|
QuestionBatchSubmission,
|
|
9
7
|
QuestionPromptResult,
|
|
@@ -13,7 +11,12 @@ import type {
|
|
|
13
11
|
const mockConfig = {
|
|
14
12
|
timeouts: { permissionTimeoutSec: 0.05 },
|
|
15
13
|
};
|
|
14
|
+
// Preserve every other export from the real config/loader so other
|
|
15
|
+
// tests in the same `bun test` run (which share module-level mocks)
|
|
16
|
+
// don't lose access to e.g. `setNestedValue`.
|
|
17
|
+
const realConfigLoader = await import("../config/loader.js");
|
|
16
18
|
mock.module("../config/loader.js", () => ({
|
|
19
|
+
...realConfigLoader,
|
|
17
20
|
getConfig: () => mockConfig,
|
|
18
21
|
loadConfig: () => mockConfig,
|
|
19
22
|
invalidateConfigCache: () => {},
|
|
@@ -63,17 +66,26 @@ mock.module("../runtime/pending-interactions.js", () => ({
|
|
|
63
66
|
clear: () => _piStore.clear(),
|
|
64
67
|
}));
|
|
65
68
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
// `QuestionPrompter` imports `broadcastMessage` directly from
|
|
70
|
+
// assistant-event-hub now (the constructor-injection seam was removed).
|
|
71
|
+
// Intercept that one export so each test instance can observe what the
|
|
72
|
+
// prompter would have broadcast — but preserve every other export from
|
|
73
|
+
// the real module so other tests in the same `bun test` run (which
|
|
74
|
+
// share module-level mocks) still see e.g. `assistantEventHub`.
|
|
75
|
+
let _sentBuffer: ServerMessage[] = [];
|
|
76
|
+
const realEventHub = await import("../runtime/assistant-event-hub.js");
|
|
77
|
+
mock.module("../runtime/assistant-event-hub.js", () => ({
|
|
78
|
+
...realEventHub,
|
|
79
|
+
broadcastMessage: (msg: ServerMessage) => _sentBuffer.push(msg),
|
|
80
|
+
}));
|
|
81
|
+
|
|
82
|
+
const { QuestionPrompter, QuestionBatchValidationError, buildBatchEntries } =
|
|
83
|
+
await import("./question-prompter.js");
|
|
71
84
|
|
|
72
85
|
function makePrompter() {
|
|
73
86
|
const sent: ServerMessage[] = [];
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
});
|
|
87
|
+
_sentBuffer = sent;
|
|
88
|
+
const prompter = new QuestionPrompter();
|
|
77
89
|
return { prompter, sent };
|
|
78
90
|
}
|
|
79
91
|
|
|
@@ -176,7 +188,7 @@ describe("QuestionPrompter", () => {
|
|
|
176
188
|
const promise = prompter.prompt(singleQuestionParams);
|
|
177
189
|
|
|
178
190
|
expect(sent).toHaveLength(1);
|
|
179
|
-
const req = sent[0] as
|
|
191
|
+
const req = sent[0] as QuestionRequestEvent;
|
|
180
192
|
expect(req.type).toBe("question_request");
|
|
181
193
|
expect(req.questions).toHaveLength(1);
|
|
182
194
|
expect(req.questions[0]?.id).toBe("q1");
|
|
@@ -207,7 +219,7 @@ describe("QuestionPrompter", () => {
|
|
|
207
219
|
],
|
|
208
220
|
});
|
|
209
221
|
|
|
210
|
-
const req = sent[0] as
|
|
222
|
+
const req = sent[0] as QuestionRequestEvent;
|
|
211
223
|
expect(req.freeTextPlaceholder).toBe("Type a fruit");
|
|
212
224
|
expect(req.questions[0]?.freeTextPlaceholder).toBe("Type a fruit");
|
|
213
225
|
|
|
@@ -228,7 +240,7 @@ describe("QuestionPrompter", () => {
|
|
|
228
240
|
void prompter.prompt(threeQuestionParams);
|
|
229
241
|
|
|
230
242
|
expect(sent).toHaveLength(1);
|
|
231
|
-
const req = sent[0] as
|
|
243
|
+
const req = sent[0] as QuestionRequestEvent;
|
|
232
244
|
expect(req.questions.map((q) => q.id)).toEqual(["q1", "q2", "q3"]);
|
|
233
245
|
// Flat fields mirror the first entry for backwards compat.
|
|
234
246
|
expect(req.question).toBe("Q1?");
|
|
@@ -239,7 +251,7 @@ describe("QuestionPrompter", () => {
|
|
|
239
251
|
const { prompter, sent } = makePrompter();
|
|
240
252
|
|
|
241
253
|
const promise = prompter.prompt(threeQuestionParams);
|
|
242
|
-
const req = sent[0] as
|
|
254
|
+
const req = sent[0] as QuestionRequestEvent;
|
|
243
255
|
|
|
244
256
|
resolveBatch(req.requestId, [
|
|
245
257
|
{ questionId: "q2", kind: "option", optionId: "y" },
|
|
@@ -262,7 +274,7 @@ describe("QuestionPrompter", () => {
|
|
|
262
274
|
const { prompter, sent } = makePrompter();
|
|
263
275
|
|
|
264
276
|
const promise = prompter.prompt(threeQuestionParams);
|
|
265
|
-
const req = sent[0] as
|
|
277
|
+
const req = sent[0] as QuestionRequestEvent;
|
|
266
278
|
|
|
267
279
|
resolveBatch(req.requestId, [
|
|
268
280
|
{ questionId: "q1", kind: "skip" },
|
|
@@ -279,7 +291,7 @@ describe("QuestionPrompter", () => {
|
|
|
279
291
|
const { prompter, sent } = makePrompter();
|
|
280
292
|
|
|
281
293
|
const promise = prompter.prompt(threeQuestionParams);
|
|
282
|
-
const req = sent[0] as
|
|
294
|
+
const req = sent[0] as QuestionRequestEvent;
|
|
283
295
|
|
|
284
296
|
closeBatch(req.requestId);
|
|
285
297
|
|
|
@@ -294,12 +306,9 @@ describe("QuestionPrompter", () => {
|
|
|
294
306
|
|
|
295
307
|
test("buildBatchEntries rejects unknown questionId", () => {
|
|
296
308
|
expect(() =>
|
|
297
|
-
buildBatchEntries(
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
new Set(["q1"]),
|
|
301
|
-
[{ questionId: "qX", kind: "option", optionId: "a" }],
|
|
302
|
-
),
|
|
309
|
+
buildBatchEntries(["q1"], () => true, new Set(["q1"]), [
|
|
310
|
+
{ questionId: "qX", kind: "option", optionId: "a" },
|
|
311
|
+
]),
|
|
303
312
|
).toThrow(QuestionBatchValidationError);
|
|
304
313
|
});
|
|
305
314
|
|
|
@@ -347,7 +356,7 @@ describe("QuestionPrompter", () => {
|
|
|
347
356
|
...threeQuestionParams,
|
|
348
357
|
signal: ac.signal,
|
|
349
358
|
});
|
|
350
|
-
const req = sent[0] as
|
|
359
|
+
const req = sent[0] as QuestionRequestEvent;
|
|
351
360
|
expect(_piStore.has(req.requestId)).toBe(true);
|
|
352
361
|
|
|
353
362
|
ac.abort();
|
|
@@ -377,7 +386,7 @@ describe("QuestionPrompter", () => {
|
|
|
377
386
|
...threeQuestionParams,
|
|
378
387
|
signal: ac.signal,
|
|
379
388
|
});
|
|
380
|
-
const req = sent[0] as
|
|
389
|
+
const req = sent[0] as QuestionRequestEvent;
|
|
381
390
|
expect(_piStore.has(req.requestId)).toBe(true);
|
|
382
391
|
|
|
383
392
|
// Simulate `removeByConversation` clearing the registry entry before
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { v4 as uuid } from "uuid";
|
|
2
2
|
|
|
3
|
-
import { getConfig } from "../config/loader.js";
|
|
4
3
|
import type {
|
|
5
4
|
QuestionOption,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from "../
|
|
5
|
+
QuestionRequestEvent,
|
|
6
|
+
} from "../api/events/question-request.js";
|
|
7
|
+
import { getConfig } from "../config/loader.js";
|
|
8
|
+
import { broadcastMessage } from "../runtime/assistant-event-hub.js";
|
|
9
9
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
10
10
|
import { AssistantError, ErrorCode } from "../util/errors.js";
|
|
11
11
|
import { getLogger } from "../util/logger.js";
|
|
@@ -161,10 +161,6 @@ export interface QuestionBatchMetadata {
|
|
|
161
161
|
* secret prompts, so they share the same idle-timeout knob.
|
|
162
162
|
*/
|
|
163
163
|
export class QuestionPrompter {
|
|
164
|
-
constructor(
|
|
165
|
-
private deps: { broadcastMessage(msg: ServerMessage): void },
|
|
166
|
-
) {}
|
|
167
|
-
|
|
168
164
|
async prompt(params: QuestionPromptParams): Promise<QuestionPromptResult> {
|
|
169
165
|
const { conversationId, questions, toolUseId, signal } = params;
|
|
170
166
|
|
|
@@ -279,7 +275,7 @@ export class QuestionPrompter {
|
|
|
279
275
|
// batched payload, and the flat fields mirror `questions[0]` for
|
|
280
276
|
// backwards compat with clients that haven't adopted `questions[]`.
|
|
281
277
|
const head = entries[0]!;
|
|
282
|
-
const msg:
|
|
278
|
+
const msg: QuestionRequestEvent = {
|
|
283
279
|
type: "question_request",
|
|
284
280
|
requestId,
|
|
285
281
|
questions: entries,
|
|
@@ -291,7 +287,7 @@ export class QuestionPrompter {
|
|
|
291
287
|
toolUseId,
|
|
292
288
|
};
|
|
293
289
|
|
|
294
|
-
|
|
290
|
+
broadcastMessage(msg);
|
|
295
291
|
});
|
|
296
292
|
}
|
|
297
293
|
}
|
package/src/plugin-api/index.ts
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
* - {@link PluginShutdownContext} — passed to `shutdown` hook at teardown
|
|
25
25
|
* - {@link UserPromptSubmitContext} — passed to `user-prompt-submit` hook,
|
|
26
26
|
* fired immediately before the agent loop receives a user's prompt
|
|
27
|
+
* - {@link PluginHookFn} — signature every lifecycle hook implements
|
|
27
28
|
* - {@link PluginLogger} — pino-compatible logger shape on the contexts
|
|
28
29
|
* - {@link ToolDefinition} — author-facing tool spec (default-export shape
|
|
29
30
|
* for both plugin tool files and workspace tool files)
|
|
@@ -39,6 +40,7 @@
|
|
|
39
40
|
export type { HookName } from "./constants.js";
|
|
40
41
|
export { HOOKS } from "./constants.js";
|
|
41
42
|
export type {
|
|
43
|
+
PluginHookFn,
|
|
42
44
|
PluginInitContext,
|
|
43
45
|
PluginLogger,
|
|
44
46
|
PluginShutdownContext,
|
package/src/plugin-api/types.ts
CHANGED
|
@@ -34,6 +34,22 @@ export interface PluginLogger {
|
|
|
34
34
|
debug(obj: Record<string, unknown>, msg?: string): void;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
// ─── Hook function ───────────────────────────────────────────────────────────
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* A plugin lifecycle hook. Receives a per-lifecycle context shape and
|
|
41
|
+
* may return either a transformed context or `void`. Today's runtime
|
|
42
|
+
* consumes only the resolved-or-rejected nature of the promise; the
|
|
43
|
+
* `TCtx` return is reserved for hooks that fan a transformed context out
|
|
44
|
+
* to downstream plugins (e.g. `user-prompt-submit`).
|
|
45
|
+
*
|
|
46
|
+
* Each known hook key has a documented context shape:
|
|
47
|
+
* - `init` — {@link PluginInitContext}
|
|
48
|
+
* - `shutdown` — {@link PluginShutdownContext}
|
|
49
|
+
* - `user-prompt-submit` — {@link UserPromptSubmitContext}
|
|
50
|
+
*/
|
|
51
|
+
export type PluginHookFn<TCtx = unknown> = (ctx: TCtx) => Promise<TCtx | void>;
|
|
52
|
+
|
|
37
53
|
// ─── Init context ────────────────────────────────────────────────────────────
|
|
38
54
|
|
|
39
55
|
/**
|
|
@@ -83,9 +99,9 @@ export interface PluginShutdownContext {
|
|
|
83
99
|
/**
|
|
84
100
|
* Context passed to the `user-prompt-submit` hook. Fires once per user
|
|
85
101
|
* turn, after the agent loop has prepared the message list (PKB / NOW /
|
|
86
|
-
* memory-graph injections,
|
|
87
|
-
*
|
|
88
|
-
*
|
|
102
|
+
* memory-graph injections, overflow reduction all already applied) and
|
|
103
|
+
* immediately before the messages are handed to the agent loop's tool/LLM
|
|
104
|
+
* iteration.
|
|
89
105
|
*
|
|
90
106
|
* The hook may transform `latestMessages` either by mutating it in place
|
|
91
107
|
* (`push` / `splice` / `length = 0`) or by returning a new context with
|
|
@@ -115,4 +131,10 @@ export interface UserPromptSubmitContext {
|
|
|
115
131
|
* may mutate this in place or replace it by returning a new context.
|
|
116
132
|
*/
|
|
117
133
|
latestMessages: Message[];
|
|
134
|
+
/**
|
|
135
|
+
* Logger scoped to the current turn. The same instance is shared by
|
|
136
|
+
* every hook in the chain, so plugins should tag their structured log
|
|
137
|
+
* fields (e.g. `{ plugin: "<name>" }`) for attribution.
|
|
138
|
+
*/
|
|
139
|
+
readonly logger: PluginLogger;
|
|
118
140
|
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CircuitBreakerArgs,
|
|
3
|
+
CircuitBreakerResult,
|
|
4
|
+
Middleware,
|
|
5
|
+
} from "../../../types.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Consecutive failures required to trip the breaker. Matches the legacy
|
|
9
|
+
* `COMPACTION_CIRCUIT_FAILURE_THRESHOLD` in `conversation-agent-loop.ts`.
|
|
10
|
+
*/
|
|
11
|
+
export const COMPACTION_CIRCUIT_FAILURE_THRESHOLD = 3;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Cooldown window after the breaker trips, during which auto-compaction is
|
|
15
|
+
* suspended. Matches the legacy `COMPACTION_CIRCUIT_COOLDOWN_MS`.
|
|
16
|
+
*/
|
|
17
|
+
export const COMPACTION_CIRCUIT_COOLDOWN_MS = 60 * 60 * 1000;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Default middleware for the `circuitBreaker` pipeline. A thin wrapper over the
|
|
21
|
+
* state container passed in `CircuitBreakerArgs.state`:
|
|
22
|
+
*
|
|
23
|
+
* - `{ key }` — query. Defers to `next` for the current
|
|
24
|
+
* `{ open, cooldownRemainingMs? }`.
|
|
25
|
+
* - `{ key, outcome }` — update state based on outcome, then defer to `next`
|
|
26
|
+
* for the post-update decision. A run of three failures trips the breaker;
|
|
27
|
+
* any non-failure outcome resets both the counter and the cooldown timestamp.
|
|
28
|
+
*
|
|
29
|
+
* Event emission preserves the existing `trackCompactionOutcome` behavior:
|
|
30
|
+
* `compaction_circuit_open` fires once when the counter first reaches the
|
|
31
|
+
* threshold while the circuit is dormant; `compaction_circuit_closed` fires
|
|
32
|
+
* only on the open→closed transition.
|
|
33
|
+
*/
|
|
34
|
+
const circuitBreaker: Middleware<CircuitBreakerArgs, CircuitBreakerResult> =
|
|
35
|
+
async function circuitBreaker(args, next) {
|
|
36
|
+
const { outcome, state, onEvent } = args;
|
|
37
|
+
|
|
38
|
+
// Update branch — mutate state first, then defer to the downstream
|
|
39
|
+
// chain (or terminal) for the decision so outer observers still see
|
|
40
|
+
// the fully-processed outcome. Separating state mutation from
|
|
41
|
+
// decision computation also keeps this middleware composable: an
|
|
42
|
+
// outer plugin may wrap the invocation to observe both the pre-update
|
|
43
|
+
// args and the post-update result.
|
|
44
|
+
if (outcome !== undefined) {
|
|
45
|
+
if (outcome === "failure") {
|
|
46
|
+
state.consecutiveCompactionFailures += 1;
|
|
47
|
+
// Treat a stale/expired open-until timestamp the same as null so
|
|
48
|
+
// a new 3-strike window can re-open the circuit after the prior
|
|
49
|
+
// cooldown elapses. Without this, subsequent trips would no-op
|
|
50
|
+
// because `compactionCircuitOpenUntil` remains set to a past
|
|
51
|
+
// timestamp even though the breaker is effectively closed.
|
|
52
|
+
const circuitDormant =
|
|
53
|
+
state.compactionCircuitOpenUntil === null ||
|
|
54
|
+
Date.now() >= state.compactionCircuitOpenUntil;
|
|
55
|
+
if (
|
|
56
|
+
state.consecutiveCompactionFailures >=
|
|
57
|
+
COMPACTION_CIRCUIT_FAILURE_THRESHOLD &&
|
|
58
|
+
circuitDormant
|
|
59
|
+
) {
|
|
60
|
+
const openUntil = Date.now() + COMPACTION_CIRCUIT_COOLDOWN_MS;
|
|
61
|
+
state.compactionCircuitOpenUntil = openUntil;
|
|
62
|
+
if (onEvent) {
|
|
63
|
+
onEvent({
|
|
64
|
+
type: "compaction_circuit_open",
|
|
65
|
+
conversationId: state.conversationId,
|
|
66
|
+
reason: "3_consecutive_failures",
|
|
67
|
+
openUntil,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
} else {
|
|
72
|
+
// Emit only on the open→closed transition; firing on the common
|
|
73
|
+
// closed→closed case would be noise.
|
|
74
|
+
const wasOpen = state.compactionCircuitOpenUntil !== null;
|
|
75
|
+
state.consecutiveCompactionFailures = 0;
|
|
76
|
+
state.compactionCircuitOpenUntil = null;
|
|
77
|
+
if (wasOpen && onEvent) {
|
|
78
|
+
onEvent({
|
|
79
|
+
type: "compaction_circuit_closed",
|
|
80
|
+
conversationId: state.conversationId,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Defer to downstream (the terminal, in the default registration, but
|
|
87
|
+
// potentially another plugin in a customized chain) for the final
|
|
88
|
+
// decision. The terminal's implementation is the canonical read of
|
|
89
|
+
// the (now-updated) state container.
|
|
90
|
+
return next(args);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export default circuitBreaker;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "default-circuit-breaker",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "First-party default plugin wrapping the assistant's built-in circuit-breaker pipeline with a passthrough implementation.",
|
|
5
|
+
"private": true,
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "./register.ts",
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=20.12.0"
|
|
11
|
+
},
|
|
12
|
+
"peerDependencies": {
|
|
13
|
+
"@vellumai/plugin-api": "^0.8.0"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default `circuitBreaker` plugin.
|
|
3
|
+
*
|
|
4
|
+
* Replicates the inline compaction circuit-breaker logic that previously
|
|
5
|
+
* lived in `daemon/conversation-agent-loop.ts`: three consecutive summary-LLM
|
|
6
|
+
* failures open the circuit for a one-hour cooldown, and any successful
|
|
7
|
+
* compaction resets the counter.
|
|
8
|
+
*
|
|
9
|
+
* The plugin is a thin wrapper over the state container passed in
|
|
10
|
+
* `CircuitBreakerArgs.state`. The {@link Conversation} owns the underlying
|
|
11
|
+
* fields (`consecutiveCompactionFailures`, `compactionCircuitOpenUntil`)
|
|
12
|
+
* because dev-only playground routes (`POST /playground/reset-compaction-circuit`,
|
|
13
|
+
* `POST /playground/inject-compaction-failures`) read and mutate them
|
|
14
|
+
* directly. Keeping ownership on the conversation lets this plugin stay a
|
|
15
|
+
* pure wrapper while preserving those hatches.
|
|
16
|
+
*
|
|
17
|
+
* The `key` parameter is carried through for multi-circuit futures but the
|
|
18
|
+
* default plugin currently bundles all circuit state into the `state`
|
|
19
|
+
* container; the key is attached to the log record via the pipeline runner.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { type Plugin } from "../../types.js";
|
|
23
|
+
import circuitBreaker from "./middlewares/circuitBreaker.js";
|
|
24
|
+
import pkg from "./package.json" with { type: "json" };
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Default plugin registered at daemon startup. Consumers negotiate against
|
|
28
|
+
* `circuitBreakerApi@v1` via the registry's capability table.
|
|
29
|
+
*/
|
|
30
|
+
export const defaultCircuitBreakerPlugin: Plugin = {
|
|
31
|
+
manifest: {
|
|
32
|
+
name: pkg.name,
|
|
33
|
+
version: pkg.version,
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
middleware: {
|
|
37
|
+
circuitBreaker,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CompactionArgs,
|
|
3
|
+
CompactionResult,
|
|
4
|
+
Middleware,
|
|
5
|
+
} from "../../../types.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Passthrough middleware for the `compaction` pipeline. Forwards to
|
|
9
|
+
* `next(args)` so any custom plugins layered outside still run; when this is
|
|
10
|
+
* the only middleware, `next` is the terminal handler (`../terminal.ts`) and
|
|
11
|
+
* returns the real compaction output.
|
|
12
|
+
*
|
|
13
|
+
* Defaults register at the OUTERMOST onion position, so deciding here without
|
|
14
|
+
* calling `next` would shadow every later-registered plugin. Routing through
|
|
15
|
+
* `next(args)` lets user middleware participate normally.
|
|
16
|
+
*/
|
|
17
|
+
const defaultCompactionMiddleware: Middleware<
|
|
18
|
+
CompactionArgs,
|
|
19
|
+
CompactionResult
|
|
20
|
+
> = async function defaultCompaction(args, next, ctx) {
|
|
21
|
+
void ctx;
|
|
22
|
+
return next(args);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default defaultCompactionMiddleware;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "default-compaction",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "First-party default plugin wrapping the assistant's built-in compaction pipeline with a passthrough implementation.",
|
|
5
|
+
"private": true,
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "./register.ts",
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=20.12.0"
|
|
11
|
+
},
|
|
12
|
+
"peerDependencies": {
|
|
13
|
+
"@vellumai/plugin-api": "^0.8.0"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default `compaction` plugin.
|
|
3
|
+
*
|
|
4
|
+
* The plugin's middleware is a passthrough — it calls `next(args)` and returns
|
|
5
|
+
* the result unchanged. The actual compaction lives in the terminal handler in
|
|
6
|
+
* `./terminal.ts`, which is wired in as the pipeline's `terminal` argument by
|
|
7
|
+
* the `runPipeline` call site in `daemon/conversation-agent-loop.ts`. This
|
|
8
|
+
* separation matters: the default plugin is registered before any user plugin
|
|
9
|
+
* (defaults load first in `bootstrapPlugins()`), which puts it at the
|
|
10
|
+
* OUTERMOST position of the onion chain. If the default middleware were to
|
|
11
|
+
* invoke the terminal directly without calling `next`, it would shadow every
|
|
12
|
+
* later-registered plugin. Routing through `next(args)` lets user middleware
|
|
13
|
+
* participate normally.
|
|
14
|
+
*
|
|
15
|
+
* Design doc: `.private/plans/agent-plugin-system.md` (PR 25).
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { type Plugin } from "../../types.js";
|
|
19
|
+
import defaultCompactionMiddleware from "./middlewares/compaction.js";
|
|
20
|
+
import pkg from "./package.json" with { type: "json" };
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Manifest + middleware wiring for the default compaction plugin. The
|
|
24
|
+
* registration happens in `daemon/external-plugins-bootstrap.ts` before
|
|
25
|
+
* {@link bootstrapPlugins} fires plugin `init()` hooks.
|
|
26
|
+
*/
|
|
27
|
+
export const defaultCompactionPlugin: Plugin = {
|
|
28
|
+
manifest: {
|
|
29
|
+
name: pkg.name,
|
|
30
|
+
version: pkg.version,
|
|
31
|
+
},
|
|
32
|
+
middleware: {
|
|
33
|
+
compaction: defaultCompactionMiddleware,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default `compaction` behavior: summarizes conversation history when the
|
|
3
|
+
* context window fills up.
|
|
4
|
+
*
|
|
5
|
+
* This module is side-effect free: importing it does not register any plugin.
|
|
6
|
+
*
|
|
7
|
+
* Delegates to the orchestrator's existing {@link ContextWindowManager}
|
|
8
|
+
* instance, read from `ctx.contextWindowManager` on the {@link TurnContext} as
|
|
9
|
+
* a typed optional field. The orchestrator is responsible for attaching that
|
|
10
|
+
* handle to the per-turn context. If the handle is missing, this throws a
|
|
11
|
+
* {@link PluginExecutionError} so the bug surfaces with clear attribution
|
|
12
|
+
* instead of a late `undefined.maybeCompact is not a function`.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type {
|
|
16
|
+
ContextWindowCompactOptions,
|
|
17
|
+
ContextWindowManager,
|
|
18
|
+
ContextWindowResult,
|
|
19
|
+
} from "../../../context/window-manager.js";
|
|
20
|
+
import type { Message } from "../../../providers/types.js";
|
|
21
|
+
import {
|
|
22
|
+
type CompactionArgs,
|
|
23
|
+
type CompactionResult,
|
|
24
|
+
PluginExecutionError,
|
|
25
|
+
type TurnContext,
|
|
26
|
+
} from "../../types.js";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Name under which the default plugin registers. Exposed so tests and later
|
|
30
|
+
* plugins can assert registration order or override the default via
|
|
31
|
+
* composition.
|
|
32
|
+
*/
|
|
33
|
+
export const DEFAULT_COMPACTION_PLUGIN_NAME = "default-compaction";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Read `contextWindowManager` off the turn context. Throws
|
|
37
|
+
* {@link PluginExecutionError} when absent so the failure attributes cleanly
|
|
38
|
+
* to the default plugin instead of manifesting as a later NPE.
|
|
39
|
+
*/
|
|
40
|
+
function extractManager(ctx: TurnContext): ContextWindowManager {
|
|
41
|
+
const manager = ctx.contextWindowManager;
|
|
42
|
+
if (
|
|
43
|
+
manager == null ||
|
|
44
|
+
typeof manager !== "object" ||
|
|
45
|
+
typeof (manager as { maybeCompact?: unknown }).maybeCompact !== "function"
|
|
46
|
+
) {
|
|
47
|
+
throw new PluginExecutionError(
|
|
48
|
+
"default-compaction: ctx.contextWindowManager is missing — orchestrator must attach it before invoking compaction",
|
|
49
|
+
DEFAULT_COMPACTION_PLUGIN_NAME,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
return manager;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Run compaction for the turn: reads the context window manager off the turn
|
|
57
|
+
* context and returns the (possibly summarized) message history from
|
|
58
|
+
* `maybeCompact`.
|
|
59
|
+
*/
|
|
60
|
+
export async function defaultCompactionTerminal(
|
|
61
|
+
args: CompactionArgs,
|
|
62
|
+
ctx: TurnContext,
|
|
63
|
+
): Promise<CompactionResult> {
|
|
64
|
+
const manager = extractManager(ctx);
|
|
65
|
+
const messages = args.messages as Message[];
|
|
66
|
+
const options = args.options as ContextWindowCompactOptions | undefined;
|
|
67
|
+
const result: ContextWindowResult = await manager.maybeCompact(
|
|
68
|
+
messages,
|
|
69
|
+
args.signal,
|
|
70
|
+
options,
|
|
71
|
+
);
|
|
72
|
+
return result;
|
|
73
|
+
}
|