@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
|
@@ -248,26 +248,23 @@ export async function runBackgroundJob(
|
|
|
248
248
|
conversation.id,
|
|
249
249
|
"user",
|
|
250
250
|
opts.assistantSandwich.preamble,
|
|
251
|
-
undefined,
|
|
252
251
|
{ skipIndexing: true },
|
|
253
252
|
);
|
|
254
253
|
await addMessage(
|
|
255
254
|
conversation.id,
|
|
256
255
|
"assistant",
|
|
257
256
|
opts.assistantSandwich.content,
|
|
258
|
-
undefined,
|
|
259
257
|
{ skipIndexing: true },
|
|
260
258
|
);
|
|
261
259
|
await addMessage(
|
|
262
260
|
conversation.id,
|
|
263
261
|
"user",
|
|
264
262
|
opts.assistantSandwich.postamble,
|
|
265
|
-
undefined,
|
|
266
263
|
{ skipIndexing: true },
|
|
267
264
|
);
|
|
268
265
|
}
|
|
269
266
|
|
|
270
|
-
const work = processMessage(conversation.id, opts.prompt,
|
|
267
|
+
const work = processMessage(conversation.id, opts.prompt, {
|
|
271
268
|
trustContext: opts.trustContext,
|
|
272
269
|
callSite: opts.callSite,
|
|
273
270
|
});
|
|
@@ -89,7 +89,9 @@ export async function runBtwSidechain(
|
|
|
89
89
|
let hadTextDeltas = false;
|
|
90
90
|
|
|
91
91
|
try {
|
|
92
|
-
const response = await provider.sendMessage(messages,
|
|
92
|
+
const response = await provider.sendMessage(messages, {
|
|
93
|
+
tools,
|
|
94
|
+
systemPrompt,
|
|
93
95
|
config: {
|
|
94
96
|
max_tokens: params.maxTokens ?? 1024,
|
|
95
97
|
tool_choice: { type: "none" },
|
|
@@ -170,20 +170,9 @@ export function handleChannelDecision(
|
|
|
170
170
|
const conversation = findConversation(resolved.conversationId);
|
|
171
171
|
if (!conversation) return { applied: false };
|
|
172
172
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
userDecision,
|
|
177
|
-
);
|
|
178
|
-
} else {
|
|
179
|
-
conversation.handleConfirmationResponse(
|
|
180
|
-
info.requestId,
|
|
181
|
-
userDecision,
|
|
182
|
-
undefined,
|
|
183
|
-
undefined,
|
|
184
|
-
decisionContext,
|
|
185
|
-
);
|
|
186
|
-
}
|
|
173
|
+
conversation.handleConfirmationResponse(info.requestId, userDecision, {
|
|
174
|
+
decisionContext,
|
|
175
|
+
});
|
|
187
176
|
|
|
188
177
|
return {
|
|
189
178
|
applied: true,
|
|
@@ -13,8 +13,6 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import type { ChannelId } from "../channels/types.js";
|
|
16
|
-
import { getConfig } from "../config/loader.js";
|
|
17
|
-
import { isEmailEnabled } from "../email/feature-gate.js";
|
|
18
16
|
import { emailInviteAdapter } from "./channel-invite-transports/email.js";
|
|
19
17
|
import { slackInviteAdapter } from "./channel-invite-transports/slack.js";
|
|
20
18
|
import { telegramInviteAdapter } from "./channel-invite-transports/telegram.js";
|
|
@@ -24,7 +22,10 @@ import { whatsappInviteAdapter } from "./channel-invite-transports/whatsapp.js";
|
|
|
24
22
|
// Types
|
|
25
23
|
// ---------------------------------------------------------------------------
|
|
26
24
|
import type { ChannelInviteAdapter } from "./channel-invite-types.js";
|
|
27
|
-
export type {
|
|
25
|
+
export type {
|
|
26
|
+
ChannelInviteAdapter,
|
|
27
|
+
InviteShareLink,
|
|
28
|
+
} from "./channel-invite-types.js";
|
|
28
29
|
|
|
29
30
|
// ---------------------------------------------------------------------------
|
|
30
31
|
// Registry
|
|
@@ -95,9 +96,7 @@ export async function resolveAdapterHandle(
|
|
|
95
96
|
/** Create a registry instance with built-in adapters registered. */
|
|
96
97
|
export function createInviteAdapterRegistry(): InviteAdapterRegistry {
|
|
97
98
|
const registry = new InviteAdapterRegistry();
|
|
98
|
-
|
|
99
|
-
registry.register(emailInviteAdapter);
|
|
100
|
-
}
|
|
99
|
+
registry.register(emailInviteAdapter);
|
|
101
100
|
registry.register(slackInviteAdapter);
|
|
102
101
|
registry.register(telegramInviteAdapter);
|
|
103
102
|
registry.register(voiceInviteAdapter);
|
|
@@ -7,8 +7,7 @@ import { resolveTwilioPhoneNumber } from "../calls/twilio-config.js";
|
|
|
7
7
|
import { hasTwilioCredentials } from "../calls/twilio-rest.js";
|
|
8
8
|
import { getChannelInvitePolicy } from "../channels/config.js";
|
|
9
9
|
import { getIsPlatform } from "../config/env-registry.js";
|
|
10
|
-
import {
|
|
11
|
-
import { isEmailEnabled } from "../email/feature-gate.js";
|
|
10
|
+
import { getNestedValue, loadRawConfig } from "../config/loader.js";
|
|
12
11
|
import { credentialKey } from "../security/credential-key.js";
|
|
13
12
|
import { getSecureKeyAsync } from "../security/secure-keys.js";
|
|
14
13
|
import { resolveWhatsAppDisplayNumber } from "./channel-invite-transports/whatsapp.js";
|
|
@@ -513,9 +512,7 @@ export function createReadinessService(): ChannelReadinessService {
|
|
|
513
512
|
const service = new ChannelReadinessService();
|
|
514
513
|
service.registerProbe(voiceProbe);
|
|
515
514
|
service.registerProbe(telegramProbe);
|
|
516
|
-
|
|
517
|
-
service.registerProbe(emailProbe);
|
|
518
|
-
}
|
|
515
|
+
service.registerProbe(emailProbe);
|
|
519
516
|
service.registerProbe(whatsappProbe);
|
|
520
517
|
service.registerProbe(slackProbe);
|
|
521
518
|
return service;
|
|
@@ -298,26 +298,22 @@ export async function sweepFailedEvents(
|
|
|
298
298
|
|
|
299
299
|
let userMessageId: string | undefined;
|
|
300
300
|
try {
|
|
301
|
-
const result = await processMessage(
|
|
302
|
-
event.conversationId,
|
|
303
|
-
content,
|
|
301
|
+
const result = await processMessage(event.conversationId, content, {
|
|
304
302
|
attachmentIds,
|
|
305
|
-
{
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
chatType: metadataChatType,
|
|
311
|
-
},
|
|
312
|
-
assistantId,
|
|
313
|
-
trustContext,
|
|
314
|
-
isInteractive:
|
|
315
|
-
resolveRoutingStateFromRuntime(trustContext).promptWaitingAllowed,
|
|
316
|
-
onEvent: observeAgentEvent,
|
|
303
|
+
transport: {
|
|
304
|
+
channelId: sourceChannel,
|
|
305
|
+
hints: metadataHints.length > 0 ? metadataHints : undefined,
|
|
306
|
+
uxBrief: metadataUxBrief,
|
|
307
|
+
chatType: metadataChatType,
|
|
317
308
|
},
|
|
309
|
+
assistantId,
|
|
310
|
+
trustContext,
|
|
311
|
+
isInteractive:
|
|
312
|
+
resolveRoutingStateFromRuntime(trustContext).promptWaitingAllowed,
|
|
313
|
+
onEvent: observeAgentEvent,
|
|
318
314
|
sourceChannel,
|
|
319
315
|
sourceInterface,
|
|
320
|
-
);
|
|
316
|
+
});
|
|
321
317
|
userMessageId = result.messageId;
|
|
322
318
|
linkMessage(event.id, userMessageId);
|
|
323
319
|
markProcessed(event.id);
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversation Stream State -- per-conversation SSE sequence counter and
|
|
3
|
+
* ring buffer for `Last-Event-ID` replay (B7 Unit 1).
|
|
4
|
+
*
|
|
5
|
+
* Every conversation-scoped outbound event picks up a monotonic `seq`
|
|
6
|
+
* number from this module. The same event is also pushed onto a bounded
|
|
7
|
+
* ring buffer so a reconnecting client can request replay of events the
|
|
8
|
+
* daemon emitted while it was disconnected.
|
|
9
|
+
*
|
|
10
|
+
* Bounds (oldest evicted first; first bound hit wins):
|
|
11
|
+
* - Count: 200 events
|
|
12
|
+
* - Total size: 256 KB
|
|
13
|
+
* - Age: 30 seconds
|
|
14
|
+
*
|
|
15
|
+
* The ring is in-memory and per-daemon-process. After a daemon restart
|
|
16
|
+
* all seqs reset and reconnecting clients fall through to the snapshot
|
|
17
|
+
* path (delivered by B7 Unit 2). The ring is sized generously enough
|
|
18
|
+
* that a typical refresh round-trip (~1-3s) is well within window.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import type { AssistantEvent } from "./assistant-event.js";
|
|
22
|
+
|
|
23
|
+
// ── Tunables ─────────────────────────────────────────────────────────
|
|
24
|
+
|
|
25
|
+
const RING_COUNT_LIMIT = 200;
|
|
26
|
+
const RING_SIZE_LIMIT_BYTES = 256 * 1024;
|
|
27
|
+
const RING_AGE_LIMIT_MS = 30_000;
|
|
28
|
+
|
|
29
|
+
// ── Types ────────────────────────────────────────────────────────────
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Targeting / exclusion modifiers attached to an event at publish time.
|
|
33
|
+
* Stored on ring entries so replay can re-apply the same delivery
|
|
34
|
+
* filter that the live `publish()` path used.
|
|
35
|
+
*
|
|
36
|
+
* Fields use plain `string` rather than branded channel types so
|
|
37
|
+
* this module stays independent of the `channels/` package.
|
|
38
|
+
*/
|
|
39
|
+
export interface EventTargeting {
|
|
40
|
+
targetCapability?: string;
|
|
41
|
+
targetClientId?: string;
|
|
42
|
+
targetInterfaceId?: string;
|
|
43
|
+
excludeClientId?: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Identity of the subscriber requesting a replay window. Replay
|
|
48
|
+
* filtering mirrors the live `publish()` logic in `AssistantEventHub`:
|
|
49
|
+
* targeted entries are only delivered when the subscriber matches.
|
|
50
|
+
*/
|
|
51
|
+
export interface ReplaySubscriber {
|
|
52
|
+
type: "client" | "process";
|
|
53
|
+
clientId?: string;
|
|
54
|
+
interfaceId?: string;
|
|
55
|
+
capabilities?: readonly string[];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
interface RingEntry {
|
|
59
|
+
seq: number;
|
|
60
|
+
event: AssistantEvent;
|
|
61
|
+
emittedAt: number;
|
|
62
|
+
sizeBytes: number;
|
|
63
|
+
targeting?: EventTargeting;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
interface ConversationStreamState {
|
|
67
|
+
nextSeq: number;
|
|
68
|
+
ring: RingEntry[];
|
|
69
|
+
totalSizeBytes: number;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ── State ────────────────────────────────────────────────────────────
|
|
73
|
+
|
|
74
|
+
const streams = new Map<string, ConversationStreamState>();
|
|
75
|
+
|
|
76
|
+
function getOrCreate(conversationId: string): ConversationStreamState {
|
|
77
|
+
let state = streams.get(conversationId);
|
|
78
|
+
if (!state) {
|
|
79
|
+
state = { nextSeq: 1, ring: [], totalSizeBytes: 0 };
|
|
80
|
+
streams.set(conversationId, state);
|
|
81
|
+
}
|
|
82
|
+
return state;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ── Public API ───────────────────────────────────────────────────────
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Assign a monotonic `seq` to a conversation-scoped event and push it
|
|
89
|
+
* onto the ring buffer. No-op when `event.conversationId` is absent
|
|
90
|
+
* (unscoped broadcasts are never replayable).
|
|
91
|
+
*
|
|
92
|
+
* When `options.targeting` is provided, the metadata is stored on the
|
|
93
|
+
* ring entry so that {@link getReplayWindow} can re-apply the same
|
|
94
|
+
* delivery filter at replay time. This keeps targeted events in the
|
|
95
|
+
* ring (preventing false-positive seq gaps on reconnect) without
|
|
96
|
+
* leaking them to subscribers outside their intended delivery set.
|
|
97
|
+
*
|
|
98
|
+
* Mutates `event.seq` in place.
|
|
99
|
+
*/
|
|
100
|
+
export function stampAndBuffer(
|
|
101
|
+
event: AssistantEvent,
|
|
102
|
+
options?: { targeting?: EventTargeting },
|
|
103
|
+
): void {
|
|
104
|
+
const cid = event.conversationId;
|
|
105
|
+
if (cid == null) return;
|
|
106
|
+
|
|
107
|
+
const state = getOrCreate(cid);
|
|
108
|
+
event.seq = state.nextSeq++;
|
|
109
|
+
|
|
110
|
+
// Approximate size by serialized JSON length. This is the same
|
|
111
|
+
// bytes-on-wire we'll send, so it tracks ring memory pressure
|
|
112
|
+
// closely without a separate measurement pass.
|
|
113
|
+
const sizeBytes = JSON.stringify(event).length;
|
|
114
|
+
const entry: RingEntry = {
|
|
115
|
+
seq: event.seq,
|
|
116
|
+
event,
|
|
117
|
+
emittedAt: Date.now(),
|
|
118
|
+
sizeBytes,
|
|
119
|
+
};
|
|
120
|
+
if (options?.targeting) {
|
|
121
|
+
entry.targeting = options.targeting;
|
|
122
|
+
}
|
|
123
|
+
state.ring.push(entry);
|
|
124
|
+
state.totalSizeBytes += sizeBytes;
|
|
125
|
+
|
|
126
|
+
evict(state);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Replay events with `seq > lastSeenSeq` for a given conversation.
|
|
131
|
+
* Returns `null` when the requested cursor is older than the oldest
|
|
132
|
+
* buffered entry -- callers should fall back to a snapshot resync.
|
|
133
|
+
*
|
|
134
|
+
* When `subscriber` is provided, entries carrying targeting metadata
|
|
135
|
+
* are filtered using the same rules as the live `publish()` path in
|
|
136
|
+
* `AssistantEventHub`. This prevents targeted events from leaking to
|
|
137
|
+
* subscribers outside their intended delivery set on reconnect.
|
|
138
|
+
* When `subscriber` is omitted, all entries are returned unfiltered
|
|
139
|
+
* (backwards-compatible behaviour).
|
|
140
|
+
*
|
|
141
|
+
* Sweeps age-expired entries at read time so an idle conversation
|
|
142
|
+
* cannot serve stale deltas past the 30-second window (eviction
|
|
143
|
+
* only runs on `stampAndBuffer`, so without this an idle stream
|
|
144
|
+
* would retain its tail until the next write). When the sweep
|
|
145
|
+
* drains the ring entirely, the conversation's state entry is
|
|
146
|
+
* dropped to keep the global map from growing unboundedly with
|
|
147
|
+
* inactive conversations.
|
|
148
|
+
*/
|
|
149
|
+
export function getReplayWindow(
|
|
150
|
+
conversationId: string,
|
|
151
|
+
lastSeenSeq: number,
|
|
152
|
+
subscriber?: ReplaySubscriber,
|
|
153
|
+
): readonly AssistantEvent[] | null {
|
|
154
|
+
const state = streams.get(conversationId);
|
|
155
|
+
if (!state) return [];
|
|
156
|
+
|
|
157
|
+
evict(state);
|
|
158
|
+
|
|
159
|
+
if (state.ring.length === 0) {
|
|
160
|
+
streams.delete(conversationId);
|
|
161
|
+
return [];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const oldest = state.ring[0]?.seq ?? Infinity;
|
|
165
|
+
if (lastSeenSeq < oldest - 1) return null;
|
|
166
|
+
|
|
167
|
+
return state.ring
|
|
168
|
+
.filter(
|
|
169
|
+
(entry) =>
|
|
170
|
+
entry.seq > lastSeenSeq &&
|
|
171
|
+
(subscriber == null || matchesSubscriber(entry, subscriber)),
|
|
172
|
+
)
|
|
173
|
+
.map((entry) => entry.event);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Drop all state for a conversation. Currently unused -- the ring
|
|
178
|
+
* self-evicts by age -- but exposed for explicit dispose flows
|
|
179
|
+
* (e.g. when a conversation is deleted).
|
|
180
|
+
*/
|
|
181
|
+
export function clearConversationStream(conversationId: string): void {
|
|
182
|
+
streams.delete(conversationId);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Reset all stream state. Test-only.
|
|
187
|
+
*/
|
|
188
|
+
export function _resetConversationStreamsForTesting(): void {
|
|
189
|
+
streams.clear();
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Read-only inspector for tests.
|
|
194
|
+
*/
|
|
195
|
+
export function _peekStreamForTesting(conversationId: string): {
|
|
196
|
+
nextSeq: number;
|
|
197
|
+
ringLength: number;
|
|
198
|
+
totalSizeBytes: number;
|
|
199
|
+
oldestSeq: number | null;
|
|
200
|
+
newestSeq: number | null;
|
|
201
|
+
} | null {
|
|
202
|
+
const state = streams.get(conversationId);
|
|
203
|
+
if (!state) return null;
|
|
204
|
+
return {
|
|
205
|
+
nextSeq: state.nextSeq,
|
|
206
|
+
ringLength: state.ring.length,
|
|
207
|
+
totalSizeBytes: state.totalSizeBytes,
|
|
208
|
+
oldestSeq: state.ring[0]?.seq ?? null,
|
|
209
|
+
newestSeq: state.ring[state.ring.length - 1]?.seq ?? null,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// ── Internals ────────────────────────────────────────────────────────
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Mirrors the delivery logic in `AssistantEventHub.publish()`. Returns
|
|
217
|
+
* `true` when `subscriber` would have received the entry during live
|
|
218
|
+
* fanout.
|
|
219
|
+
*/
|
|
220
|
+
function matchesSubscriber(
|
|
221
|
+
entry: RingEntry,
|
|
222
|
+
subscriber: ReplaySubscriber,
|
|
223
|
+
): boolean {
|
|
224
|
+
const t = entry.targeting;
|
|
225
|
+
if (!t) return true;
|
|
226
|
+
|
|
227
|
+
// Self-echo suppression: the originating client never receives the
|
|
228
|
+
// event back.
|
|
229
|
+
if (
|
|
230
|
+
t.excludeClientId != null &&
|
|
231
|
+
subscriber.type === "client" &&
|
|
232
|
+
subscriber.clientId === t.excludeClientId
|
|
233
|
+
) {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Interface targeting: only clients of the requested interface.
|
|
238
|
+
if (t.targetInterfaceId != null) {
|
|
239
|
+
if (
|
|
240
|
+
subscriber.type !== "client" ||
|
|
241
|
+
subscriber.interfaceId !== t.targetInterfaceId
|
|
242
|
+
) {
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (t.targetClientId != null) {
|
|
248
|
+
// Client targeting: bypass conversation filter, deliver only to the
|
|
249
|
+
// named client.
|
|
250
|
+
if (
|
|
251
|
+
subscriber.type !== "client" ||
|
|
252
|
+
subscriber.clientId !== t.targetClientId
|
|
253
|
+
) {
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
if (
|
|
257
|
+
t.targetCapability != null &&
|
|
258
|
+
!subscriber.capabilities?.includes(t.targetCapability)
|
|
259
|
+
) {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
return true;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Capability targeting (without client targeting): only subscribers
|
|
266
|
+
// that declare the required capability.
|
|
267
|
+
if (t.targetCapability != null) {
|
|
268
|
+
if (
|
|
269
|
+
subscriber.type !== "client" ||
|
|
270
|
+
!subscriber.capabilities?.includes(t.targetCapability)
|
|
271
|
+
) {
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function evict(state: ConversationStreamState): void {
|
|
280
|
+
const now = Date.now();
|
|
281
|
+
while (state.ring.length > 0) {
|
|
282
|
+
const head = state.ring[0];
|
|
283
|
+
if (head == null) break;
|
|
284
|
+
|
|
285
|
+
const overCount = state.ring.length > RING_COUNT_LIMIT;
|
|
286
|
+
const overSize = state.totalSizeBytes > RING_SIZE_LIMIT_BYTES;
|
|
287
|
+
const overAge = now - head.emittedAt > RING_AGE_LIMIT_MS;
|
|
288
|
+
|
|
289
|
+
if (!overCount && !overSize && !overAge) break;
|
|
290
|
+
|
|
291
|
+
state.ring.shift();
|
|
292
|
+
state.totalSizeBytes -= head.sizeBytes;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
|
|
13
13
|
import type { z } from "zod";
|
|
14
14
|
|
|
15
|
-
import {
|
|
15
|
+
import type { RoutePolicy } from "./auth/route-policy.js";
|
|
16
|
+
import { enforcePolicy } from "./auth/route-policy.js";
|
|
16
17
|
import type { AuthContext } from "./auth/types.js";
|
|
17
18
|
import { httpError } from "./http-errors.js";
|
|
18
19
|
import { withErrorHandling } from "./middleware/error-handler.js";
|
|
@@ -82,14 +83,15 @@ export interface RouteRequestBodyVariant {
|
|
|
82
83
|
* catch-all params that match across slashes (e.g. `interfaces/:path*`).
|
|
83
84
|
* - `method`: HTTP method (GET, POST, DELETE, PATCH, PUT).
|
|
84
85
|
* - `handler`: Async function that produces the Response.
|
|
85
|
-
* - `
|
|
86
|
-
*
|
|
86
|
+
* - `policy`: Scope + principal-type policy for this route, or `null`
|
|
87
|
+
* when the route is intentionally unprotected. See
|
|
88
|
+
* `runtime/auth/route-policy.ts` for the type.
|
|
87
89
|
*/
|
|
88
90
|
export interface HTTPRouteDefinition {
|
|
89
91
|
endpoint: string;
|
|
90
92
|
method: string;
|
|
91
93
|
handler: (ctx: RouteContext) => Promise<Response> | Response;
|
|
92
|
-
|
|
94
|
+
policy: RoutePolicy | null;
|
|
93
95
|
|
|
94
96
|
/** Stable identifier used as the IPC method name when served over both transports. */
|
|
95
97
|
operationId?: string;
|
|
@@ -143,8 +145,6 @@ interface CompiledRoute {
|
|
|
143
145
|
def: HTTPRouteDefinition;
|
|
144
146
|
regex: RegExp;
|
|
145
147
|
paramNames: string[];
|
|
146
|
-
/** Policy key used for enforcePolicy() lookups. */
|
|
147
|
-
resolvedPolicyKey: string;
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
// ---------------------------------------------------------------------------
|
|
@@ -228,13 +228,14 @@ export class HttpRouter {
|
|
|
228
228
|
}
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
-
// Enforce route-level scope/principal policy.
|
|
232
|
-
//
|
|
233
|
-
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
231
|
+
// Enforce route-level scope/principal policy. The policy
|
|
232
|
+
// travels with the RouteDefinition itself — no side-registry
|
|
233
|
+
// lookup, no derivation, no key mismatch.
|
|
234
|
+
const policyDenied = enforcePolicy(
|
|
235
|
+
compiled.def.endpoint,
|
|
236
|
+
compiled.def.policy,
|
|
237
|
+
authContext,
|
|
238
|
+
);
|
|
238
239
|
if (policyDenied) return policyDenied;
|
|
239
240
|
|
|
240
241
|
return withErrorHandling(endpoint, () =>
|
|
@@ -265,21 +266,22 @@ const PARAM_TYPE_PATTERNS: Record<string, string> = {
|
|
|
265
266
|
};
|
|
266
267
|
|
|
267
268
|
/**
|
|
268
|
-
* Compile a route definition into a regex + param list
|
|
269
|
+
* Compile a route definition into a regex + param list.
|
|
269
270
|
*
|
|
270
271
|
* Endpoint patterns like `calls/:id/cancel` become:
|
|
271
272
|
* regex: /^calls\/([^/]+)\/cancel$/
|
|
272
273
|
* paramNames: ["id"]
|
|
273
|
-
* resolvedPolicyKey: "calls/cancel" (params stripped)
|
|
274
274
|
*
|
|
275
275
|
* When the route declares `pathParams` with a `type` constraint (e.g.
|
|
276
276
|
* `{ name: "id", type: "uuid" }`), the capture group is narrowed to
|
|
277
277
|
* only match values of that type. This prevents parameterized routes
|
|
278
278
|
* from shadowing literal sibling routes regardless of declaration order.
|
|
279
|
+
*
|
|
280
|
+
* Policies are declared inline on the RouteDefinition itself —
|
|
281
|
+
* no derivation, no lookup key.
|
|
279
282
|
*/
|
|
280
283
|
function compileRoute(def: HTTPRouteDefinition): CompiledRoute {
|
|
281
284
|
const paramNames: string[] = [];
|
|
282
|
-
const policySegments: string[] = [];
|
|
283
285
|
|
|
284
286
|
// Build a lookup for typed path params.
|
|
285
287
|
const paramTypeMap = new Map<string, string>();
|
|
@@ -306,18 +308,13 @@ function compileRoute(def: HTTPRouteDefinition): CompiledRoute {
|
|
|
306
308
|
const typePattern = PARAM_TYPE_PATTERNS[paramTypeMap.get(name) ?? ""];
|
|
307
309
|
return typePattern ? `(${typePattern})` : "([^/]+)";
|
|
308
310
|
}
|
|
309
|
-
policySegments.push(segment);
|
|
310
311
|
return escapeRegex(segment);
|
|
311
312
|
})
|
|
312
313
|
.join("\\/");
|
|
313
314
|
|
|
314
315
|
const regex = new RegExp(`^${regexSource}$`);
|
|
315
316
|
|
|
316
|
-
|
|
317
|
-
// the non-param segments (e.g. `calls/:id/cancel` -> `calls/cancel`).
|
|
318
|
-
const resolvedPolicyKey = def.policyKey ?? policySegments.join("/");
|
|
319
|
-
|
|
320
|
-
return { def, regex, paramNames, resolvedPolicyKey };
|
|
317
|
+
return { def, regex, paramNames };
|
|
321
318
|
}
|
|
322
319
|
|
|
323
320
|
function escapeRegex(str: string): string {
|
|
@@ -85,8 +85,7 @@ export interface RuntimeMessageConversationOptions {
|
|
|
85
85
|
/**
|
|
86
86
|
* Optional LLM call-site identifier. Channel ingress and other inbound paths
|
|
87
87
|
* may pass this so the daemon's per-call provider config picks up the right
|
|
88
|
-
* profile via `resolveCallSiteConfig`.
|
|
89
|
-
* literals into specific call paths.
|
|
88
|
+
* profile via `resolveCallSiteConfig`.
|
|
90
89
|
*/
|
|
91
90
|
callSite?: LLMCallSite;
|
|
92
91
|
/**
|
|
@@ -96,15 +95,18 @@ export interface RuntimeMessageConversationOptions {
|
|
|
96
95
|
* chronological renderer to consume.
|
|
97
96
|
*/
|
|
98
97
|
slackInbound?: SlackInboundMessageMetadata;
|
|
98
|
+
/** IDs of user-uploaded attachments to resolve and include in the turn. */
|
|
99
|
+
attachmentIds?: string[];
|
|
100
|
+
/** Originating channel (e.g. "slack", "telegram"). Defaults to "vellum". */
|
|
101
|
+
sourceChannel?: ChannelId;
|
|
102
|
+
/** Originating interface (e.g. "cli", "web"). Defaults to "web". */
|
|
103
|
+
sourceInterface?: InterfaceId;
|
|
99
104
|
}
|
|
100
105
|
|
|
101
106
|
export type MessageProcessor = (
|
|
102
107
|
conversationId: string,
|
|
103
108
|
content: string,
|
|
104
|
-
attachmentIds?: string[],
|
|
105
109
|
options?: RuntimeMessageConversationOptions,
|
|
106
|
-
sourceChannel?: ChannelId,
|
|
107
|
-
sourceInterface?: InterfaceId,
|
|
108
110
|
) => Promise<{ messageId: string; assistantMessageId?: string }>;
|
|
109
111
|
|
|
110
112
|
/**
|
|
@@ -148,8 +150,12 @@ export interface RuntimeAttachmentMetadata {
|
|
|
148
150
|
|
|
149
151
|
export interface RuntimeMessagePayload {
|
|
150
152
|
id: string;
|
|
153
|
+
/**
|
|
154
|
+
* Server message ids that were folded into this display row when consecutive
|
|
155
|
+
* assistant messages were consolidated for history rendering.
|
|
156
|
+
*/
|
|
157
|
+
mergedMessageIds?: string[];
|
|
151
158
|
role: string;
|
|
152
|
-
content: string;
|
|
153
159
|
timestamp: string;
|
|
154
160
|
attachments: RuntimeAttachmentMetadata[];
|
|
155
161
|
toolCalls?: Array<{
|
|
@@ -70,7 +70,9 @@ export async function generateInviteInstruction(params: {
|
|
|
70
70
|
? `Send ${contact} this link: ${params.shareUrl} — or tell them to message me${handle} with the code below.`
|
|
71
71
|
: `Tell ${contact} to message me${handle} with the code below.`;
|
|
72
72
|
|
|
73
|
-
const resolved = await resolveConfiguredProvider(
|
|
73
|
+
const resolved = await resolveConfiguredProvider(
|
|
74
|
+
"inviteInstructionGenerator",
|
|
75
|
+
);
|
|
74
76
|
if (!resolved) {
|
|
75
77
|
log.debug(
|
|
76
78
|
"No provider available for invite instruction generation, using fallback",
|
|
@@ -121,8 +123,6 @@ export async function generateInviteInstruction(params: {
|
|
|
121
123
|
|
|
122
124
|
const response = await resolved.provider.sendMessage(
|
|
123
125
|
[userMessage(prompt)],
|
|
124
|
-
undefined,
|
|
125
|
-
undefined,
|
|
126
126
|
{ signal, config: { callSite: "inviteInstructionGenerator" } },
|
|
127
127
|
);
|
|
128
128
|
|
|
@@ -18,14 +18,14 @@
|
|
|
18
18
|
* resolve the interaction.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import type { InteractionResolutionState } from "../
|
|
21
|
+
import type { InteractionResolutionState } from "../api/events/interaction-resolved.js";
|
|
22
22
|
import type { UserDecision } from "../permissions/types.js";
|
|
23
23
|
import { getLogger } from "../util/logger.js";
|
|
24
24
|
import { broadcastMessage } from "./assistant-event-hub.js";
|
|
25
25
|
|
|
26
26
|
const log = getLogger("pending-interactions");
|
|
27
27
|
|
|
28
|
-
export type { InteractionResolutionState } from "../
|
|
28
|
+
export type { InteractionResolutionState } from "../api/events/interaction-resolved.js";
|
|
29
29
|
|
|
30
30
|
export interface ConfirmationDetails {
|
|
31
31
|
toolName: string;
|