@vellumai/assistant 0.12.3-staging.1 → 0.12.3-staging.2
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/ARCHITECTURE.md +43 -29
- package/Dockerfile +63 -0
- package/docs/architecture/security.md +10 -5
- package/docs/architecture/turn-actor.md +2 -0
- package/docs/desktop-browser-cli.md +45 -4
- package/docs/live-voice-task-outcomes.md +100 -0
- package/docs/mode-sessions.md +183 -0
- package/docs/voice-input-diagnostics.md +58 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +2 -1
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/integration-categories.ts +36 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +2 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/integration-categories.ts +36 -0
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +20 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +4 -1
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +38 -7
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +5 -6
- package/node_modules/@vellumai/service-contracts/package.json +2 -1
- package/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/integration-categories.ts +36 -0
- package/node_modules/@vellumai/slack-text/src/index.ts +4 -8
- package/openapi.yaml +665 -14
- package/package.json +1 -1
- package/scripts/smoke-desktop-browser-cli.ts +10 -26
- package/scripts/smoke-desktop-window-theme.ts +2 -3
- package/src/__tests__/agent-loop-output-hooks.test.ts +150 -1
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +87 -19
- package/src/__tests__/annotate-activity-metadata.test.ts +3 -1
- package/src/__tests__/annotate-risk-options.test.ts +2 -0
- package/src/__tests__/answered-question-persistence.test.ts +2 -0
- package/src/__tests__/anthropic-gateway-shared.test.ts +22 -0
- package/src/__tests__/approval-message-composer.test.ts +1 -118
- package/src/__tests__/approval-routes-http.test.ts +3 -0
- package/src/__tests__/assistant-event-hub-connection-history.test.ts +111 -0
- package/src/__tests__/assistant-event-hub-targeted.test.ts +50 -0
- package/src/__tests__/assistant-event-targeting.test.ts +186 -0
- package/src/__tests__/assistant-stream-state.test.ts +29 -9
- package/src/__tests__/browser-fill-credential.test.ts +11 -22
- package/src/__tests__/btw-routes.test.ts +4 -1
- package/src/__tests__/build-persisted-content.test.ts +1 -1
- package/src/__tests__/call-conversation-messages.test.ts +5 -0
- package/src/__tests__/call-recovery.test.ts +7 -2
- package/src/__tests__/call-routes-http.test.ts +12 -0
- package/src/__tests__/call-store.test.ts +7 -2
- package/src/__tests__/channel-retry-sweep.test.ts +9 -0
- package/src/__tests__/chat-reveal-guard-priming.test.ts +2 -0
- package/src/__tests__/checker.test.ts +11 -3
- package/src/__tests__/client-os-metadata-persistence.test.ts +35 -1
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +0 -25
- package/src/__tests__/computer-use-tools.test.ts +1 -233
- package/src/__tests__/config-model-image-provider.test.ts +39 -0
- package/src/__tests__/config-schema.test.ts +16 -0
- package/src/__tests__/config-watcher.test.ts +24 -0
- package/src/__tests__/context-search-agent-runner.test.ts +260 -1
- package/src/__tests__/context-search-fanout.test.ts +1 -1
- package/src/__tests__/context-search-types.test.ts +7 -7
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +8 -2
- package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop.test.ts +546 -16
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +53 -1
- package/src/__tests__/conversation-evictor.test.ts +62 -37
- package/src/__tests__/conversation-history-boundary-repair-failure.test.ts +174 -0
- package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +2 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +2 -0
- package/src/__tests__/conversation-retry-route.test.ts +22 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +2 -0
- package/src/__tests__/conversation-routes-enabled-plugins.test.ts +2 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +10 -0
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +2 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +2 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +29 -0
- package/src/__tests__/conversation-surface-snapshots.test.ts +543 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +151 -0
- package/src/__tests__/conversation-surfaces-point-at-budget.test.ts +63 -1
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +23 -0
- package/src/__tests__/conversation-undo.test.ts +61 -0
- package/src/__tests__/credential-execution-client.test.ts +6 -6
- package/src/__tests__/credential-prompt-route.test.ts +35 -3
- package/src/__tests__/cu-unified-flow.test.ts +82 -1
- package/src/__tests__/db-mode-sessions-migration.test.ts +175 -0
- package/src/__tests__/deterministic-verification-control-plane.test.ts +2 -0
- package/src/__tests__/dm-backfill.test.ts +91 -1
- package/src/__tests__/document-create-route.test.ts +88 -0
- package/src/__tests__/document-sync-tags.test.ts +27 -0
- package/src/__tests__/emit-signal-routing-intent.test.ts +142 -2
- package/src/__tests__/events-tail-route.test.ts +25 -0
- package/src/__tests__/evict-conversations-for-reload.test.ts +57 -8
- package/src/__tests__/guardian-action-sweep.test.ts +16 -0
- package/src/__tests__/guardian-dispatch.test.ts +13 -0
- package/src/__tests__/headless-browser-interactions.test.ts +64 -20
- package/src/__tests__/heartbeat-service.test.ts +2 -59
- package/src/__tests__/helpers/mock-conversation.ts +21 -0
- package/src/__tests__/helpers/native-web-search-harness.ts +2 -0
- package/src/__tests__/helpers/verification-sessions-ipc-sim.ts +5 -0
- package/src/__tests__/host-cu-proxy.test.ts +46 -2
- package/src/__tests__/http-user-message-parity.test.ts +2 -0
- package/src/__tests__/image-credentials.test.ts +49 -0
- package/src/__tests__/image-service-dispatcher.test.ts +45 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +1 -1
- package/src/__tests__/interrupt-on-send.test.ts +57 -43
- package/src/__tests__/interrupt-turn-note.test.ts +5 -6
- package/src/__tests__/llm-catalog-parity.test.ts +2 -2
- package/src/__tests__/media-generate-image.test.ts +49 -1
- package/src/__tests__/message-provenance-contact-id.test.ts +69 -0
- package/src/__tests__/migration-export-to-gcs.test.ts +142 -0
- package/src/__tests__/mode-session-history.test.ts +245 -0
- package/src/__tests__/mode-session-recovery.test.ts +222 -0
- package/src/__tests__/mode-session-wire.test.ts +141 -0
- package/src/__tests__/notification-guardian-path.test.ts +7 -0
- package/src/__tests__/notification-telegram-adapter.test.ts +2 -2
- package/src/__tests__/notification-vellum-adapter.test.ts +34 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +12 -0
- package/src/__tests__/oauth-providers-routes.test.ts +1 -0
- package/src/__tests__/outbound-slack-persistence.test.ts +2 -0
- package/src/__tests__/persistence-secret-redaction.test.ts +2 -0
- package/src/__tests__/plugin-api-provider.test.ts +5 -0
- package/src/__tests__/plugin-api-resolve-credential.test.ts +97 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +9 -0
- package/src/__tests__/process-message-display-content.test.ts +56 -0
- package/src/__tests__/reaction-persistence.test.ts +5 -0
- package/src/__tests__/request-secret-standalone-channel-gate.test.ts +25 -9
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +1 -1
- package/src/__tests__/scripted-turn-metadata-persistence.test.ts +73 -0
- package/src/__tests__/secret-ingress-http.test.ts +2 -0
- package/src/__tests__/secure-keys.test.ts +43 -1
- package/src/__tests__/send-endpoint-busy.test.ts +163 -1
- package/src/__tests__/server-history-render.test.ts +91 -1
- package/src/__tests__/settings-routes.test.ts +50 -1
- package/src/__tests__/skill-script-runner-sandbox.test.ts +32 -0
- package/src/__tests__/subagent-fork-notifications.test.ts +1 -2
- package/src/__tests__/subagent-manager-notify.test.ts +1 -2
- package/src/__tests__/subagent-notify-parent.test.ts +146 -39
- package/src/__tests__/subagent-notify-stale-rebuild.test.ts +2 -4
- package/src/__tests__/surface-completion-in-flight-snapshot.test.ts +2 -0
- package/src/__tests__/thread-backfill.test.ts +53 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +2 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +3 -1
- package/src/__tests__/tool-start-timestamp.test.ts +2 -0
- package/src/__tests__/twilio-routes.test.ts +1 -0
- package/src/__tests__/web-search-backend-failure.test.ts +1 -1
- package/src/activation/progress-store.test.ts +12 -7
- package/src/agent/loop.ts +99 -41
- package/src/api/events/assistant-turn-start.ts +3 -0
- package/src/api/events/generation-handoff.ts +2 -0
- package/src/api/events/message-complete.ts +2 -0
- package/src/api/events/notification-conversation-created.ts +14 -16
- package/src/api/events/notification-intent.ts +4 -2
- package/src/api/events/tool-result.ts +85 -0
- package/src/api/events/tool-use-start.ts +3 -0
- package/src/api/events/user-message-echo.ts +3 -0
- package/src/api/index.ts +31 -6
- package/src/api/mode-session.test.ts +131 -0
- package/src/api/mode-session.ts +148 -0
- package/src/api/remember-tool.ts +15 -0
- package/src/api/responses/conversation-message.ts +6 -0
- package/src/approvals/AGENTS.md +4 -2
- package/src/browser/__tests__/operations.test.ts +29 -0
- package/src/browser/operation-meta.ts +2 -1
- package/src/browser/operations.ts +29 -0
- package/src/browser/virtual-desktop-target.ts +2 -8
- package/src/bundler/bundle-signer.ts +1 -3
- package/src/calls/__tests__/barge-in-guard.test.ts +3 -0
- package/src/calls/__tests__/call-controller.test.ts +94 -0
- package/src/calls/__tests__/call-funnel-telemetry.test.ts +204 -0
- package/src/calls/__tests__/voice-control-protocol.test.ts +15 -0
- package/src/calls/__tests__/voice-escalation-judge.test.ts +209 -0
- package/src/calls/__tests__/voice-leg-coordinator.test.ts +168 -0
- package/src/{live-voice/__tests__/live-voice-metrics.test.ts → calls/__tests__/voice-metrics.test.ts} +32 -38
- package/src/calls/__tests__/voice-session-bridge.test.ts +576 -122
- package/src/calls/barge-in-guard.ts +5 -0
- package/src/calls/call-controller.ts +196 -1
- package/src/calls/call-domain.ts +4 -0
- package/src/calls/call-store.ts +87 -2
- package/src/calls/guardian-action-sweep.ts +22 -8
- package/src/calls/media-stream-audio-transcode.ts +1 -3
- package/src/calls/typesafe-noul.ts +156 -0
- package/src/calls/voice-control-protocol.ts +6 -0
- package/src/calls/voice-escalation-judge.ts +145 -0
- package/src/calls/voice-escalation-target.ts +10 -0
- package/src/calls/voice-leg-coordinator.ts +121 -3
- package/src/{live-voice/live-voice-metrics.ts → calls/voice-metrics.ts} +94 -87
- package/src/calls/voice-session-bridge.ts +256 -112
- package/src/calls/voice-triage-escalate.ts +7 -0
- package/src/cli/__tests__/roadmap-cli.test.ts +4 -41
- package/src/cli/commands/__tests__/notifications.test.ts +35 -10
- package/src/cli/commands/browser.help.ts +4 -5
- package/src/cli/commands/browser.ts +0 -1
- package/src/cli/commands/clients.help.ts +46 -0
- package/src/cli/commands/clients.ts +116 -0
- package/src/cli/commands/credentials.help.ts +6 -1
- package/src/cli/commands/notifications.help.ts +16 -2
- package/src/cli/commands/notifications.ts +30 -8
- package/src/cli/commands/roadmap.help.ts +18 -21
- package/src/cli/commands/roadmap.ts +4 -21
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +5 -2
- package/src/cli/lib/bundled-marketplace.json +84 -34
- package/src/cli/lib/plugin-marketplace.ts +8 -0
- package/src/cli/lib/publish-plugin.ts +1 -2
- package/src/config/__tests__/default-provider.test.ts +3 -1
- package/src/config/__tests__/memory-retrospective-schema.test.ts +14 -1
- package/src/config/bundled-skills/computer-use/SKILL.md +1 -1
- package/src/config/bundled-skills/computer-use/TOOLS.json +89 -1
- package/src/config/bundled-skills/image-studio/SKILL.md +17 -2
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +7 -11
- package/src/config/bundled-skills/sequences/TOOLS.json +1 -5
- package/src/config/call-site-defaults.ts +9 -0
- package/src/config/feature-flag-registry.json +16 -0
- package/src/config/profile-text-generation.test.ts +2 -2
- package/src/config/schemas/__tests__/tools.test.ts +31 -0
- package/src/config/schemas/call-site-catalog.ts +14 -0
- package/src/config/schemas/channels.ts +0 -18
- package/src/config/schemas/llm.ts +3 -1
- package/src/config/schemas/mcp.ts +2 -1
- package/src/config/schemas/memory-retrospective.ts +11 -2
- package/src/config/schemas/services.ts +15 -6
- package/src/config/schemas/tools.ts +10 -0
- package/src/config/session-groups-gate.ts +21 -0
- package/src/config/skills.ts +2 -6
- package/src/conversations/__tests__/message-consolidation.test.ts +149 -0
- package/src/conversations/message-consolidation.ts +102 -5
- package/src/credential-execution/ces-connect.test.ts +69 -0
- package/src/credential-execution/ces-connect.ts +115 -0
- package/src/credential-execution/ces-runtime.ts +55 -93
- package/src/credential-execution/executable-discovery.ts +1 -11
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +10 -1
- package/src/daemon/__tests__/inference-profile-notification.test.ts +2 -0
- package/src/daemon/browser-mode-session.test.ts +402 -0
- package/src/daemon/browser-mode-session.ts +186 -0
- package/src/daemon/computer-use-mode-session.test.ts +210 -0
- package/src/daemon/computer-use-mode-session.ts +105 -0
- package/src/daemon/config-watcher.ts +10 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +58 -10
- package/src/daemon/conversation-agent-loop.ts +219 -25
- package/src/daemon/conversation-evictor.ts +5 -24
- package/src/daemon/conversation-history.ts +10 -0
- package/src/daemon/conversation-interrupt-repair.ts +4 -43
- package/src/daemon/conversation-interrupt.ts +7 -11
- package/src/daemon/conversation-messaging.ts +58 -5
- package/src/daemon/conversation-mode-session.test.ts +1667 -0
- package/src/daemon/conversation-mode-session.ts +1008 -0
- package/src/daemon/conversation-process.ts +5 -0
- package/src/daemon/conversation-runtime-assembly.ts +10 -20
- package/src/daemon/conversation-skill-tools.ts +1 -0
- package/src/daemon/conversation-store.ts +4 -4
- package/src/daemon/conversation-surface-snapshots.ts +135 -0
- package/src/daemon/conversation-surfaces.ts +113 -5
- package/src/daemon/conversation-tool-setup.ts +8 -3
- package/src/daemon/conversation.ts +143 -41
- package/src/daemon/handlers/config-model.ts +7 -5
- package/src/daemon/handlers/shared.ts +55 -16
- package/src/daemon/host-cu-proxy.ts +51 -22
- package/src/daemon/lifecycle.ts +30 -13
- package/src/daemon/message-protocol.ts +0 -1
- package/src/daemon/message-provenance.ts +28 -4
- package/src/daemon/mode-session-startup-recovery.ts +23 -0
- package/src/daemon/mode-session-tracking.ts +54 -0
- package/src/daemon/process-message.ts +13 -4
- package/src/daemon/virtual-desktop-context.ts +21 -0
- package/src/desktop/__tests__/fake-desktop.ts +1 -0
- package/src/desktop/desktop-accessibility-script.ts +88 -0
- package/src/desktop/desktop-accessibility.test.ts +160 -0
- package/src/desktop/desktop-accessibility.ts +169 -0
- package/src/desktop/desktop-automation-lease.test.ts +76 -68
- package/src/desktop/desktop-automation-lease.ts +41 -50
- package/src/desktop/desktop-browser-endpoint.ts +4 -0
- package/src/desktop/desktop-computer-use-routing.test.ts +330 -0
- package/src/desktop/desktop-computer-use.test.ts +449 -0
- package/src/desktop/desktop-computer-use.ts +502 -0
- package/src/desktop/desktop-dependencies.ts +47 -293
- package/src/desktop/desktop-display.ts +2 -2
- package/src/desktop/desktop-panel-config.test.ts +13 -3
- package/src/desktop/desktop-panel-config.ts +109 -15
- package/src/desktop/desktop-session-manager.test.ts +69 -21
- package/src/desktop/desktop-session-manager.ts +76 -22
- package/src/desktop/desktop-stream-bridge.test.ts +11 -122
- package/src/desktop/desktop-stream-bridge.ts +6 -8
- package/src/desktop/desktop-window-theme.ts +5 -25
- package/src/desktop/virtual-desktop-feature.ts +52 -2
- package/src/desktop/virtual-desktop-platform.test.ts +5 -9
- package/src/documents/document-store.ts +23 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +22 -26
- package/src/heartbeat/heartbeat-service.ts +5 -33
- package/src/ipc/__tests__/browser-ipc.test.ts +215 -6
- package/src/ipc/assistant-server.ts +2 -0
- package/src/ipc/routes/__tests__/channel-reply-ipc-routes.test.ts +111 -0
- package/src/ipc/routes/channel-reply-ipc-routes.ts +73 -0
- package/src/live-voice/__tests__/continuation-judge.test.ts +151 -0
- package/src/live-voice/__tests__/live-activity-reporter.test.ts +154 -15
- package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +743 -31
- package/src/live-voice/__tests__/live-voice-look-follow-up.test.ts +191 -10
- package/src/live-voice/__tests__/live-voice-session-groups-gate.test.ts +87 -0
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +5 -1
- package/src/live-voice/__tests__/live-voice-sight-frame-echo.test.ts +41 -0
- package/src/live-voice/__tests__/live-voice-sight-frame.test.ts +1017 -9
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +224 -1
- package/src/live-voice/__tests__/live-voice-tts-session.test.ts +101 -0
- package/src/live-voice/__tests__/live-voice-tts.test.ts +44 -0
- package/src/live-voice/__tests__/live-voice-vad.test.ts +939 -75
- package/src/live-voice/__tests__/microphone-idle-gate.test.ts +87 -0
- package/src/live-voice/__tests__/session-controls.test.ts +23 -0
- package/src/live-voice/__tests__/task-outcomes.test.ts +117 -0
- package/src/live-voice/__tests__/voice-input-diagnostics.test.ts +117 -0
- package/src/live-voice/camera-mode-session.test.ts +265 -0
- package/src/live-voice/camera-mode-session.ts +277 -0
- package/src/live-voice/continuation-judge.ts +123 -0
- package/src/live-voice/live-activity-reporter.ts +115 -6
- package/src/live-voice/live-voice-manager.ts +36 -1
- package/src/live-voice/live-voice-photo.ts +88 -7
- package/src/live-voice/live-voice-session-manager.ts +15 -0
- package/src/live-voice/live-voice-session.ts +1443 -747
- package/src/live-voice/live-voice-tts.ts +22 -4
- package/src/live-voice/microphone-idle-gate.ts +56 -0
- package/src/live-voice/protocol.ts +171 -4
- package/src/live-voice/session-controls.ts +11 -3
- package/src/live-voice/task-outcomes.ts +131 -0
- package/src/live-voice/voice-input-diagnostics.ts +117 -0
- package/src/mcp/__tests__/manager-tool-caps.test.ts +63 -18
- package/src/mcp/__tests__/tool-caps.test.ts +28 -1
- package/src/mcp/manager.ts +3 -0
- package/src/mcp/tool-caps.ts +12 -4
- package/src/media/__tests__/image-models.test.ts +58 -0
- package/src/media/image-credentials.ts +5 -0
- package/src/media/image-models.ts +52 -0
- package/src/media/image-service.ts +8 -0
- package/src/media/openrouter-image-service.test.ts +133 -0
- package/src/media/openrouter-image-service.ts +153 -0
- package/src/media/types.ts +1 -1
- package/src/messaging/providers/__tests__/transport-dispatch.test.ts +65 -11
- package/src/messaging/providers/discord/send.ts +4 -17
- package/src/messaging/providers/discord/transport.ts +2 -2
- package/src/messaging/providers/outlook/client.ts +16 -22
- package/src/messaging/providers/telegram-bot/send.test.ts +236 -1
- package/src/messaging/providers/telegram-bot/send.ts +10 -7
- package/src/messaging/providers/telegram-bot/transport.ts +3 -10
- package/src/messaging/providers/whatsapp/send.test.ts +169 -4
- package/src/monitoring/__tests__/control.test.ts +17 -5
- package/src/monitoring/control.ts +15 -5
- package/src/notifications/AGENTS.md +1 -1
- package/src/notifications/README.md +83 -99
- package/src/notifications/__tests__/broadcaster.test.ts +1 -1
- package/src/notifications/__tests__/channel-allowlist.test.ts +39 -0
- package/src/notifications/__tests__/copy-composer.test.ts +1 -1
- package/src/notifications/__tests__/decision-engine.test.ts +79 -2
- package/src/notifications/__tests__/deterministic-checks.test.ts +10 -10
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +93 -4
- package/src/notifications/__tests__/notification-utils.test.ts +18 -0
- package/src/notifications/adapters/macos.ts +37 -46
- package/src/notifications/broadcaster.ts +5 -6
- package/src/notifications/channel-allowlist.ts +44 -0
- package/src/notifications/copy-composer.ts +0 -23
- package/src/notifications/decision-engine.ts +24 -14
- package/src/notifications/deterministic-checks.ts +1 -1
- package/src/notifications/emit-signal.ts +123 -37
- package/src/notifications/home-feed-side-effect.ts +9 -7
- package/src/notifications/notification-utils.ts +19 -0
- package/src/notifications/signal.ts +4 -19
- package/src/notifications/types.ts +15 -0
- package/src/oauth/connection-resolver.ts +1 -2
- package/src/oauth/oauth-store.ts +1 -3
- package/src/oauth/provider-serializer.ts +7 -0
- package/src/oauth/seed-providers.ts +30 -0
- package/src/onboarding/onboarding-events-store.ts +99 -12
- package/src/persistence/__tests__/client-connection-events-store.test.ts +322 -0
- package/src/persistence/client-connection-events-store.ts +377 -0
- package/src/persistence/conversation-crud.ts +55 -6
- package/src/persistence/conversation-mode-sessions.test.ts +424 -0
- package/src/persistence/conversation-mode-sessions.ts +460 -0
- package/src/persistence/conversation-queries.ts +6 -19
- package/src/persistence/llm-usage-store.ts +3 -9
- package/src/persistence/message-metadata.ts +25 -0
- package/src/persistence/migrations/381-create-conversation-mode-sessions.ts +41 -0
- package/src/persistence/migrations/382-create-client-connection-events.ts +40 -0
- package/src/persistence/migrations/__tests__/382-create-client-connection-events.test.ts +56 -0
- package/src/persistence/schema/conversations.ts +67 -0
- package/src/persistence/schema/infrastructure.ts +29 -0
- package/src/persistence/steps.ts +17 -0
- package/src/plugin-api/__tests__/plugin-name-env.test.ts +249 -0
- package/src/plugin-api/effective-context-window.ts +33 -0
- package/src/plugin-api/index.ts +24 -5
- package/src/plugin-api/plugin-name-env.ts +125 -0
- package/src/plugin-api/resolve-credential.ts +79 -20
- package/src/plugin-api/vision-support.test.ts +22 -0
- package/src/plugin-api/vision-support.ts +17 -5
- package/src/plugins/__tests__/active-plugin-env.test.ts +136 -0
- package/src/plugins/active-plugin-env.ts +51 -0
- package/src/plugins/defaults/index.ts +24 -0
- package/src/plugins/defaults/memory/__tests__/archive-removal-framing.test.ts +64 -0
- package/src/plugins/defaults/memory/__tests__/worker-control.test.ts +19 -6
- package/src/plugins/defaults/memory/context-search/agent-protocol.ts +9 -12
- package/src/plugins/defaults/memory/context-search/agent-runner.ts +78 -22
- package/src/plugins/defaults/memory/context-search/format.ts +51 -7
- package/src/plugins/defaults/memory/context-search/limits.ts +10 -12
- package/src/plugins/defaults/memory/context-search/recall-input.ts +38 -0
- package/src/plugins/defaults/memory/context-search/search.ts +8 -14
- package/src/plugins/defaults/memory/context-search/sources/conversations.ts +1 -0
- package/src/plugins/defaults/memory/context-search/types.ts +1 -11
- package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +11 -4
- package/src/plugins/defaults/memory/graph/tool-handlers.ts +12 -21
- package/src/plugins/defaults/memory/graph/tools.ts +35 -64
- package/src/plugins/defaults/memory/src/memory-eval-routes.ts +2 -3
- package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +5 -0
- package/src/plugins/defaults/memory/src/memory-item-routes.ts +2 -1
- package/src/plugins/defaults/memory/substrate/prompts/consolidation.ts +2 -2
- package/src/plugins/defaults/memory/tools.test.ts +124 -9
- package/src/plugins/defaults/memory/tools.ts +38 -11
- package/src/plugins/defaults/memory/v3/__tests__/pool-log-store.test.ts +165 -27
- package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +626 -27
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +46 -27
- package/src/plugins/defaults/memory/v3/orchestrate.ts +78 -38
- package/src/plugins/defaults/memory/v3/pool-log-store.ts +65 -79
- package/src/plugins/defaults/memory/v3/pool-select.test.ts +14 -5
- package/src/plugins/defaults/memory/v3/pool-select.ts +683 -44
- package/src/plugins/defaults/memory/worker-control.ts +15 -5
- package/src/plugins/defaults/task-progress/__tests__/registration.test.ts +70 -0
- package/src/plugins/defaults/task-progress/__tests__/task-progress-context.test.ts +380 -0
- package/src/plugins/defaults/task-progress/hooks/post-compact.ts +19 -0
- package/src/plugins/defaults/task-progress/hooks/user-prompt-submit.ts +24 -0
- package/src/plugins/defaults/task-progress/package.json +14 -0
- package/src/plugins/defaults/task-progress/src/apply-task-progress-context.ts +93 -0
- package/src/plugins/defaults/task-progress/src/format-task-progress-context.ts +67 -0
- package/src/providers/__tests__/context-overflow-error.test.ts +10 -0
- package/src/providers/__tests__/search-provider-catalog.test.ts +18 -0
- package/src/providers/anthropic/client.ts +10 -1
- package/src/providers/anthropic-gateway-shared.ts +6 -0
- package/src/providers/fetch-provider-catalog.ts +11 -0
- package/src/providers/gemini/client.ts +25 -8
- package/src/providers/inference/adapter-factory.ts +1 -1
- package/src/providers/jev/client.test.ts +10 -0
- package/src/providers/jev/client.ts +20 -4
- package/src/providers/model-catalog.ts +4 -3
- package/src/providers/openai/__tests__/chat-completions-extra-body.test.ts +94 -1
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +106 -1
- package/src/providers/openai/__tests__/chat-template-flatten.test.ts +24 -0
- package/src/providers/openai/__tests__/google-thought-signature.test.ts +1 -2
- package/src/providers/openai/chat-completions-provider.ts +100 -29
- package/src/providers/openai/google-thought-signature.ts +0 -6
- package/src/providers/openai/responses-provider.ts +23 -1
- package/src/providers/ratelimit.ts +1 -3
- package/src/providers/search-provider-catalog.ts +24 -0
- package/src/providers/speech-to-text/__tests__/deepgram-flux-frames.test.ts +24 -0
- package/src/providers/speech-to-text/__tests__/deepgram-flux-realtime.test.ts +7 -1
- package/src/providers/speech-to-text/__tests__/vellum-managed-realtime.test.ts +50 -1
- package/src/providers/speech-to-text/deepgram-flux-frames.ts +11 -0
- package/src/providers/speech-to-text/vellum-managed-flux-realtime.ts +13 -0
- package/src/providers/types.ts +5 -0
- package/src/routes/control.ts +7 -5
- package/src/runtime/AGENTS.md +4 -2
- package/src/runtime/actor-trust-resolver.ts +3 -3
- package/src/runtime/agent-wake.ts +1 -1
- package/src/runtime/approval-message-composer.ts +3 -69
- package/src/runtime/assistant-event-hub.ts +73 -75
- package/src/runtime/assistant-event-publish-options.ts +7 -0
- package/src/runtime/assistant-event-targeting.ts +79 -0
- package/src/runtime/assistant-stream-state.ts +13 -100
- package/src/runtime/background-job-runner.ts +5 -5
- package/src/runtime/channel-retry-sweep.ts +1 -0
- package/src/runtime/guardian-action-message-composer.ts +8 -161
- package/src/runtime/guardian-reply-router.ts +28 -32
- package/src/runtime/http-types.ts +6 -0
- package/src/runtime/message-composer-types.ts +3 -61
- package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +67 -1
- package/src/runtime/migrations/vbundle-builder.ts +24 -1
- package/src/runtime/migrations/vbundle-import-analyzer.ts +13 -4
- package/src/runtime/migrations/vbundle-import-policy.ts +10 -0
- package/src/runtime/migrations/vbundle-importer.ts +4 -1
- package/src/runtime/migrations/vbundle-streaming-importer.ts +4 -1
- package/src/runtime/migrations/vbundle-validator.ts +1 -0
- package/src/runtime/pending-interactions-mode-session.test.ts +62 -0
- package/src/runtime/pending-interactions.ts +29 -0
- package/src/runtime/routes/__tests__/client-history-routes.test.ts +104 -0
- package/src/runtime/routes/__tests__/image-generation-routes.test.ts +97 -0
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/roadmap-routes.test.ts +29 -6
- package/src/runtime/routes/browser-context.ts +31 -11
- package/src/runtime/routes/browser-routes.ts +43 -4
- package/src/runtime/routes/btw-routes.ts +9 -4
- package/src/runtime/routes/client-routes.ts +108 -0
- package/src/runtime/routes/conversation-management-routes.ts +4 -1
- package/src/runtime/routes/conversation-routes.ts +113 -27
- package/src/runtime/routes/credential-prompt-routes.ts +4 -3
- package/src/runtime/routes/credential-routes.ts +1 -2
- package/src/runtime/routes/desktop-setup-routes.test.ts +9 -18
- package/src/runtime/routes/desktop-setup-routes.ts +4 -6
- package/src/runtime/routes/documents-routes.ts +51 -0
- package/src/runtime/routes/email-routes.ts +3 -7
- package/src/runtime/routes/events-routes.ts +75 -54
- package/src/runtime/routes/identity-routes.ts +1 -5
- package/src/runtime/routes/image-generation-routes.ts +8 -14
- package/src/runtime/routes/inbound-message-handler.ts +35 -38
- package/src/runtime/routes/inbound-stages/backfill-sender-provenance.test.ts +168 -0
- package/src/runtime/routes/inbound-stages/backfill-sender-provenance.ts +96 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +38 -9
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +2 -5
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +2 -0
- package/src/runtime/routes/llm-context-normalization.ts +1 -7
- package/src/runtime/routes/migration-routes.ts +73 -2
- package/src/runtime/routes/notification-routes.ts +10 -0
- package/src/runtime/routes/oauth-providers.ts +7 -0
- package/src/runtime/routes/plugins-routes.ts +6 -0
- package/src/runtime/routes/roadmap-routes.ts +47 -8
- package/src/runtime/routes/secret-routes.ts +1 -1
- package/src/runtime/routes/settings-routes.ts +10 -4
- package/src/runtime/routes/watcher-routes.ts +1 -3
- package/src/runtime/trust-class.test.ts +7 -6
- package/src/runtime/trust-class.ts +9 -17
- package/src/schedule/__tests__/worker-control.test.ts +36 -5
- package/src/schedule/worker-control.ts +15 -5
- package/src/security/secure-keys.ts +53 -103
- package/src/skills/clawhub.ts +3 -8
- package/src/skills/managed-store.ts +1 -5
- package/src/stt/types.ts +4 -0
- package/src/subagent/notify.ts +54 -34
- package/src/subagent/parent-notification.ts +6 -0
- package/src/telemetry/__tests__/phone-call-funnel.test.ts +72 -0
- package/src/telemetry/phone-call-funnel.ts +144 -0
- package/src/tools/__tests__/tool-schema-root-combinator-guard.test.ts +81 -0
- package/src/tools/ask-question/ask-question-tool.ts +6 -4
- package/src/tools/browser/browser-execution.ts +22 -59
- package/src/tools/browser/cdp-client/__tests__/cdp-dom-helpers.test.ts +561 -39
- package/src/tools/browser/cdp-client/cdp-dom-helpers.ts +435 -39
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +1 -8
- package/src/tools/client-os.ts +15 -0
- package/src/tools/computer-use/skill-proxy-bridge.ts +1 -1
- package/src/tools/computer-use/target.ts +42 -0
- package/src/tools/document/document-tool.ts +13 -18
- package/src/tools/execution-target.ts +14 -16
- package/src/tools/host-terminal/host-shell.ts +4 -1
- package/src/tools/network/__tests__/web-fetch-tinyfish.test.ts +250 -0
- package/src/tools/network/__tests__/web-search.test.ts +203 -0
- package/src/tools/network/web-fetch.ts +274 -7
- package/src/tools/network/web-search.ts +468 -6
- package/src/tools/permission-checker.ts +3 -3
- package/src/tools/policy-context.ts +3 -1
- package/src/tools/skills/load.ts +2 -1
- package/src/tools/skills/sandbox-runner.ts +11 -2
- package/src/tools/skills/skill-script-runner.ts +7 -0
- package/src/tools/skills/skill-tool-factory.ts +15 -1
- package/src/tools/terminal/__tests__/safe-env.test.ts +11 -0
- package/src/tools/terminal/safe-env.ts +4 -0
- package/src/tools/terminal/shell.ts +2 -0
- package/src/tools/tool-approval-handler.ts +5 -1
- package/src/tools/tool-types.ts +3 -3
- package/src/tools/types.ts +8 -2
- package/src/util/__tests__/worker-process-command.test.ts +5 -4
- package/src/util/abort-reasons.ts +18 -26
- package/src/util/canonicalize-identity.test.ts +21 -0
- package/src/util/canonicalize-identity.ts +16 -0
- package/src/util/errors.ts +13 -3
- package/src/util/provider-error-patterns.ts +3 -0
- package/src/util/worker-process.ts +77 -35
- package/src/workspace/migrations/157-add-desktop-files-launcher.ts +94 -0
- package/src/workspace/migrations/__tests__/156-extract-workspace-mcp-json.test.ts +4 -10
- package/src/workspace/migrations/__tests__/157-add-desktop-files-launcher.test.ts +113 -0
- package/src/workspace/migrations/registry.ts +2 -0
- package/src/__tests__/computer-use-window-schema.test.ts +0 -24
- package/src/api/events/heartbeat-alert.ts +0 -20
- package/src/daemon/message-types/web-activity.ts +0 -65
- package/src/desktop/desktop-dependencies.test.ts +0 -131
- package/src/tools/computer-use/definitions.ts +0 -607
|
@@ -2,14 +2,11 @@
|
|
|
2
2
|
// Memory Tool definitions for agentic recall and remember.
|
|
3
3
|
// ---------------------------------------------------------------------------
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
ALL_RECALL_SOURCES,
|
|
7
|
-
MAX_RECALL_MAX_RESULTS,
|
|
8
|
-
MIN_RECALL_MAX_RESULTS,
|
|
9
|
-
} from "../context-search/limits.js";
|
|
10
|
-
import type { ToolDefinition } from "../llm-helpers.js";
|
|
5
|
+
import { toToolInputSchema } from "@vellumai/plugin-api";
|
|
11
6
|
|
|
12
|
-
|
|
7
|
+
import { RememberInputSchema } from "../../../../api/remember-tool.js";
|
|
8
|
+
import { RecallInputSchema } from "../context-search/recall-input.js";
|
|
9
|
+
import type { ToolDefinition } from "../llm-helpers.js";
|
|
13
10
|
|
|
14
11
|
/**
|
|
15
12
|
* Explicit local information search across memory, conversations, and
|
|
@@ -19,38 +16,7 @@ export const graphRecallDefinition = {
|
|
|
19
16
|
name: "recall",
|
|
20
17
|
description:
|
|
21
18
|
'Search local information the moment you feel uncertain. Use recall for memory, past conversations, and workspace files — before you guess, before you ask, before you hedge. Auto-injection is incomplete by design; it surfaces patterns, not the specifics you need to answer well. If you catch yourself reaching for "I think", "I believe", "if I remember", "didn\'t we", "last time" — that\'s the signal. Recall. If a turn references someone, a place, a decision, a document, or prior work you should be able to find locally — recall. Call it multiple times per conversation if the turn warrants it. Be specific in your query for best results. Results reflect what was true when the memory was written — do not use recall alone to answer questions about current system state (account connections, watchers, service health); verify those with live checks.',
|
|
22
|
-
input_schema:
|
|
23
|
-
type: "object",
|
|
24
|
-
properties: {
|
|
25
|
-
query: {
|
|
26
|
-
type: "string",
|
|
27
|
-
description:
|
|
28
|
-
"What you're looking for. Be specific and descriptive: include the topic, person, project, decision, time period, or file clues when known.",
|
|
29
|
-
},
|
|
30
|
-
sources: {
|
|
31
|
-
type: "array",
|
|
32
|
-
items: {
|
|
33
|
-
type: "string",
|
|
34
|
-
enum: [...ALL_RECALL_SOURCES],
|
|
35
|
-
},
|
|
36
|
-
description:
|
|
37
|
-
"Optional local sources to search. Omit to search memory, conversations, and workspace files.",
|
|
38
|
-
},
|
|
39
|
-
max_results: {
|
|
40
|
-
type: "integer",
|
|
41
|
-
minimum: MIN_RECALL_MAX_RESULTS,
|
|
42
|
-
maximum: MAX_RECALL_MAX_RESULTS,
|
|
43
|
-
description: "Maximum number of evidence items to return.",
|
|
44
|
-
},
|
|
45
|
-
depth: {
|
|
46
|
-
type: "string",
|
|
47
|
-
enum: [...RECALL_DEPTHS],
|
|
48
|
-
description:
|
|
49
|
-
"Search effort. Use fast for quick lookups, standard by default, and deep when the answer may require multiple local searches.",
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
required: ["query"],
|
|
53
|
-
},
|
|
19
|
+
input_schema: toToolInputSchema(RecallInputSchema),
|
|
54
20
|
} satisfies ToolDefinition;
|
|
55
21
|
|
|
56
22
|
/**
|
|
@@ -77,8 +43,9 @@ export const REMEMBER_PAGE_HINT_GUIDANCE =
|
|
|
77
43
|
"When a fact relates to memory pages already in your context, reference the most specific ones inline as [[slug]] wikilinks — consolidation reads hinted pages first when filing the fact, which matters most for corrections (the hint names the page carrying the outdated fact). Hint only pages you have actually seen, and prefer specific pages over broad hubs.";
|
|
78
44
|
|
|
79
45
|
/**
|
|
80
|
-
* Build the `remember` input schema
|
|
81
|
-
*
|
|
46
|
+
* Build the `remember` input schema from {@link RememberInputSchema}, the one
|
|
47
|
+
* `execute` parses with, adding the descriptions the model reads.
|
|
48
|
+
* `pageHints` reflects whether concept-page memory is active and appends
|
|
82
49
|
* {@link REMEMBER_PAGE_HINT_GUIDANCE} to the `content` description. It is a
|
|
83
50
|
* thunk re-resolved on every read of that description: the registry's
|
|
84
51
|
* finalized tool shares the returned schema object by reference, so a
|
|
@@ -87,29 +54,33 @@ export const REMEMBER_PAGE_HINT_GUIDANCE =
|
|
|
87
54
|
*/
|
|
88
55
|
export function buildRememberInputSchema(options: {
|
|
89
56
|
pageHints: () => boolean;
|
|
90
|
-
}) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
57
|
+
}): Record<string, unknown> {
|
|
58
|
+
const schema = toToolInputSchema(
|
|
59
|
+
RememberInputSchema.extend({
|
|
60
|
+
content: RememberInputSchema.shape.content.describe(
|
|
61
|
+
REMEMBER_CONTENT_DESCRIPTION,
|
|
62
|
+
),
|
|
63
|
+
finish_turn: RememberInputSchema.shape.finish_turn.describe(
|
|
64
|
+
"When you have nothing else to say and want to yield the turn you MUST set this to true. When true, your turn ends after this tool call. It's critical that you do this in order to avoid unnecessary LLM calls.",
|
|
65
|
+
),
|
|
66
|
+
}),
|
|
67
|
+
);
|
|
68
|
+
const properties = schema.properties;
|
|
69
|
+
const content =
|
|
70
|
+
typeof properties === "object" && properties !== null
|
|
71
|
+
? Reflect.get(properties, "content")
|
|
72
|
+
: undefined;
|
|
73
|
+
if (typeof content === "object" && content !== null) {
|
|
74
|
+
Object.defineProperty(content, "description", {
|
|
75
|
+
enumerable: true,
|
|
76
|
+
configurable: true,
|
|
77
|
+
get: (): string =>
|
|
78
|
+
options.pageHints()
|
|
79
|
+
? `${REMEMBER_CONTENT_DESCRIPTION} ${REMEMBER_PAGE_HINT_GUIDANCE}`
|
|
80
|
+
: REMEMBER_CONTENT_DESCRIPTION,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return schema;
|
|
113
84
|
}
|
|
114
85
|
|
|
115
86
|
/**
|
|
@@ -23,7 +23,7 @@ import type { RouteDefinition } from "../../../../runtime/routes/types.js";
|
|
|
23
23
|
import { getLogger } from "../logging.js";
|
|
24
24
|
import { getWorkspaceDir } from "../paths.js";
|
|
25
25
|
import { runMemoryEval } from "../v3-eval/eval-packets.js";
|
|
26
|
-
import {
|
|
26
|
+
import { tallyVerdicts } from "../v3-eval/eval-tally.js";
|
|
27
27
|
|
|
28
28
|
const log = getLogger("memory-eval-routes");
|
|
29
29
|
|
|
@@ -138,12 +138,11 @@ export type MemoryEvalTallyResult = z.infer<typeof MemoryEvalTallyResultSchema>;
|
|
|
138
138
|
*/
|
|
139
139
|
export function handleMemoryEvalTally(body: unknown): MemoryEvalTallyResult {
|
|
140
140
|
const params = MemoryEvalTallyParamsSchema.parse(body ?? {});
|
|
141
|
-
|
|
141
|
+
return tallyVerdicts(
|
|
142
142
|
params.verdicts,
|
|
143
143
|
params.key,
|
|
144
144
|
params.alpha !== undefined ? { alpha: params.alpha } : {},
|
|
145
145
|
);
|
|
146
|
-
return result;
|
|
147
146
|
}
|
|
148
147
|
|
|
149
148
|
const WRITE_POLICY: RoutePolicy = {
|
|
@@ -1199,6 +1199,11 @@ describe("Memory Item Routes", () => {
|
|
|
1199
1199
|
const body = (await res.json()) as RememberBody;
|
|
1200
1200
|
expect(body.success).toBe(true);
|
|
1201
1201
|
expect(body.message.length).toBeGreaterThan(0);
|
|
1202
|
+
// Exactly the declared response fields: the handler's saved-facts list
|
|
1203
|
+
// stays on the tool path.
|
|
1204
|
+
expect(Object.keys(body).sort()).toEqual(
|
|
1205
|
+
["message", "pendingNodeId", "success"].sort(),
|
|
1206
|
+
);
|
|
1202
1207
|
});
|
|
1203
1208
|
|
|
1204
1209
|
test("returns the pending node id of the appended entry", async () => {
|
|
@@ -1162,6 +1162,7 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
1162
1162
|
return result;
|
|
1163
1163
|
}
|
|
1164
1164
|
maybeEnqueueConsolidationForCreate(config);
|
|
1165
|
+
const created = { success: true, message: result.message };
|
|
1165
1166
|
|
|
1166
1167
|
// Resolve the pending graph-node id of the entry just appended so the
|
|
1167
1168
|
// client can fly the map to it. Matched by this request's content
|
|
@@ -1179,7 +1180,7 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
1179
1180
|
} catch (err) {
|
|
1180
1181
|
log.warn({ err }, "Failed to resolve pending node id after create");
|
|
1181
1182
|
}
|
|
1182
|
-
return pendingNodeId ? { ...
|
|
1183
|
+
return pendingNodeId ? { ...created, pendingNodeId } : created;
|
|
1183
1184
|
},
|
|
1184
1185
|
},
|
|
1185
1186
|
];
|
|
@@ -312,7 +312,7 @@ Cutoff timestamp for this run: \`${CUTOFF_PLACEHOLDER}\`. The entries for this p
|
|
|
312
312
|
- Updated \`memory/threads.md\` (≤10000 chars)
|
|
313
313
|
- Updated \`edges:\` frontmatter in any pages whose outgoing links changed
|
|
314
314
|
|
|
315
|
-
How retrieval works: high-activation pages are loaded at the start of each turn. Activations spread along **directed** edges from source to target
|
|
315
|
+
How retrieval works: high-activation pages are loaded at the start of each turn. Activations spread along **directed** edges from source to target: activating A pulls in the pages A points at, but not the reverse.
|
|
316
316
|
|
|
317
317
|
---
|
|
318
318
|
|
|
@@ -724,7 +724,7 @@ Three consequences:
|
|
|
724
724
|
|
|
725
725
|
1. **The lead IS the card, and the fallback.** Write every lead as a standalone orientation: what this article is, the one or two facts that identify it, where it sits. If the lead only makes sense after reading the sections, the card is useless and so is the fallback. One to three short paragraphs.
|
|
726
726
|
2. **Section names are navigation.** They appear on the selector's card as the table of contents and head every injected section. Name sections so future-you can tell from the name alone whether the answer lives there.
|
|
727
|
-
3. **Sections are the unit of growth and retrieval.** A fact filed in the right section of the right article is findable and arrives in context with its section (kept under the 6000-character chunk window, so the section travels whole); a fact buried mid-paragraph in an overlong lead is not.
|
|
727
|
+
3. **Sections are the unit of growth and retrieval.** A fact filed in the right section of the right article is findable and arrives in context with its section (kept under the 6000-character chunk window, so the section travels whole); a fact buried mid-paragraph in an overlong lead is not.
|
|
728
728
|
|
|
729
729
|
---
|
|
730
730
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
1
|
+
import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import {
|
|
@@ -11,7 +11,10 @@ import {
|
|
|
11
11
|
test,
|
|
12
12
|
} from "bun:test";
|
|
13
13
|
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
|
|
14
16
|
import { setConfig } from "../../../__tests__/helpers/set-config.js";
|
|
17
|
+
import type { RecallMetadata } from "../../../api/events/tool-result.js";
|
|
15
18
|
import type { ToolContext } from "../../../tools/types.js";
|
|
16
19
|
|
|
17
20
|
let tmpWorkspace: string;
|
|
@@ -31,6 +34,14 @@ const recallCalls: Array<{
|
|
|
31
34
|
context: Record<string, unknown>;
|
|
32
35
|
}> = [];
|
|
33
36
|
let recallContent = "agentic recall answer";
|
|
37
|
+
const recallActivity: RecallMetadata = {
|
|
38
|
+
query: "guardian recall",
|
|
39
|
+
depth: "standard",
|
|
40
|
+
sources: ["memory"],
|
|
41
|
+
answer: "agentic recall answer",
|
|
42
|
+
evidence: [],
|
|
43
|
+
searchedSources: [{ source: "memory", status: "searched", evidenceCount: 0 }],
|
|
44
|
+
};
|
|
34
45
|
|
|
35
46
|
mock.module("./v1/jobs/embed-pkb-file.js", () => ({
|
|
36
47
|
enqueuePkbIndexJob: (input: { pkbRoot: string; absPath: string }) => {
|
|
@@ -52,6 +63,7 @@ mock.module("./context-search/agent-runner.js", () => ({
|
|
|
52
63
|
content: recallContent,
|
|
53
64
|
answer: recallContent,
|
|
54
65
|
evidence: [],
|
|
66
|
+
activity: recallActivity,
|
|
55
67
|
debug: { mode: "agentic" },
|
|
56
68
|
};
|
|
57
69
|
},
|
|
@@ -146,6 +158,7 @@ describe("recallTool.execute", () => {
|
|
|
146
158
|
expect(result).toEqual({
|
|
147
159
|
content: "agentic recall answer",
|
|
148
160
|
isError: false,
|
|
161
|
+
activityMetadata: { recall: recallActivity },
|
|
149
162
|
});
|
|
150
163
|
expect(recallCalls).toHaveLength(1);
|
|
151
164
|
expect(recallCalls[0]?.input).toEqual({ query: "guardian recall" });
|
|
@@ -179,6 +192,7 @@ describe("recallTool.execute", () => {
|
|
|
179
192
|
expect(result).toEqual({
|
|
180
193
|
content: "agentic recall answer",
|
|
181
194
|
isError: false,
|
|
195
|
+
activityMetadata: { recall: recallActivity },
|
|
182
196
|
});
|
|
183
197
|
expect(recallCalls).toHaveLength(1);
|
|
184
198
|
expect(recallCalls[0]?.input).toEqual({
|
|
@@ -189,6 +203,37 @@ describe("recallTool.execute", () => {
|
|
|
189
203
|
});
|
|
190
204
|
});
|
|
191
205
|
|
|
206
|
+
test("refuses an unknown source before searching", async () => {
|
|
207
|
+
const result = await recallTool.execute(
|
|
208
|
+
{ query: "launch notes", sources: ["calendar"] },
|
|
209
|
+
makeContext(),
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
expect(result.isError).toBe(true);
|
|
213
|
+
expect(result.content).toContain('Invalid input for tool "recall"');
|
|
214
|
+
expect(result.content).toContain("sources.0");
|
|
215
|
+
expect(recallCalls).toHaveLength(0);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
test("reads null optionals as omitted and leaves max_results to the clamp", async () => {
|
|
219
|
+
await recallTool.execute(
|
|
220
|
+
{
|
|
221
|
+
query: "launch notes",
|
|
222
|
+
sources: null,
|
|
223
|
+
depth: null,
|
|
224
|
+
max_results: 50,
|
|
225
|
+
activity: "Looking up launch notes",
|
|
226
|
+
},
|
|
227
|
+
makeContext(),
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
expect(recallCalls[0]?.input).toEqual({
|
|
231
|
+
query: "launch notes",
|
|
232
|
+
max_results: 50,
|
|
233
|
+
activity: "Looking up launch notes",
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
192
237
|
test("returns deterministic fallback content directly", async () => {
|
|
193
238
|
recallContent = "Found evidence:\n\n- [workspace] fallback note";
|
|
194
239
|
|
|
@@ -200,6 +245,7 @@ describe("recallTool.execute", () => {
|
|
|
200
245
|
expect(result).toEqual({
|
|
201
246
|
content: "Found evidence:\n\n- [workspace] fallback note",
|
|
202
247
|
isError: false,
|
|
248
|
+
activityMetadata: { recall: recallActivity },
|
|
203
249
|
});
|
|
204
250
|
});
|
|
205
251
|
|
|
@@ -305,6 +351,30 @@ describe("rememberTool.execute — buffer writes", () => {
|
|
|
305
351
|
});
|
|
306
352
|
});
|
|
307
353
|
|
|
354
|
+
describe("rememberTool.execute — memory access", () => {
|
|
355
|
+
test.each(["trusted_contact", "unverified_contact", "unknown"] as const)(
|
|
356
|
+
"refuses a %s write without touching the memory buffer",
|
|
357
|
+
async (trustClass) => {
|
|
358
|
+
const fact = `a claim made on a ${trustClass} turn`;
|
|
359
|
+
const result = await rememberTool.execute(
|
|
360
|
+
{ content: fact, finish_turn: true },
|
|
361
|
+
makeContext({ trustClass }),
|
|
362
|
+
);
|
|
363
|
+
|
|
364
|
+
expect(result.isError).toBe(true);
|
|
365
|
+
expect(result.content).toContain("Not saved");
|
|
366
|
+
expect(result.activityMetadata).toBeUndefined();
|
|
367
|
+
// The turn continues so the model can relay the refusal.
|
|
368
|
+
expect(result.yieldToUser).toBeUndefined();
|
|
369
|
+
const bufferPath = join(tmpWorkspace, "memory", "buffer.md");
|
|
370
|
+
const buffer = existsSync(bufferPath)
|
|
371
|
+
? readFileSync(bufferPath, "utf-8")
|
|
372
|
+
: "";
|
|
373
|
+
expect(buffer).not.toContain(fact);
|
|
374
|
+
},
|
|
375
|
+
);
|
|
376
|
+
});
|
|
377
|
+
|
|
308
378
|
describe("rememberTool.execute — batch (array) content", () => {
|
|
309
379
|
beforeEach(() => {
|
|
310
380
|
enqueueCalls.length = 0;
|
|
@@ -313,10 +383,13 @@ describe("rememberTool.execute — batch (array) content", () => {
|
|
|
313
383
|
|
|
314
384
|
test("records every fact from an array in the memory buffer", async () => {
|
|
315
385
|
const result = await rememberTool.execute(
|
|
316
|
-
{ content: ["batch fact A", "batch fact B"] },
|
|
386
|
+
{ content: [" batch fact A ", "batch fact B", " "] },
|
|
317
387
|
makeContext(),
|
|
318
388
|
);
|
|
319
389
|
expect(result.isError).toBe(false);
|
|
390
|
+
expect(result.activityMetadata).toEqual({
|
|
391
|
+
remember: { facts: ["batch fact A", "batch fact B"] },
|
|
392
|
+
});
|
|
320
393
|
|
|
321
394
|
const bufferContents = readFileSync(
|
|
322
395
|
join(tmpWorkspace, "memory", "buffer.md"),
|
|
@@ -328,16 +401,58 @@ describe("rememberTool.execute — batch (array) content", () => {
|
|
|
328
401
|
expect(enqueueCalls).toHaveLength(0);
|
|
329
402
|
});
|
|
330
403
|
|
|
404
|
+
test("refuses a non-string fact without writing any of the batch", async () => {
|
|
405
|
+
const result = await rememberTool.execute(
|
|
406
|
+
{ content: ["a fact beside a number", 42] },
|
|
407
|
+
makeContext(),
|
|
408
|
+
);
|
|
409
|
+
|
|
410
|
+
expect(result.isError).toBe(true);
|
|
411
|
+
expect(result.content).toContain('Invalid input for tool "remember"');
|
|
412
|
+
const bufferPath = join(tmpWorkspace, "memory", "buffer.md");
|
|
413
|
+
const buffer = existsSync(bufferPath)
|
|
414
|
+
? readFileSync(bufferPath, "utf-8")
|
|
415
|
+
: "";
|
|
416
|
+
expect(buffer).not.toContain("a fact beside a number");
|
|
417
|
+
});
|
|
418
|
+
|
|
331
419
|
test("rejects an all-blank array without writing or enqueueing", async () => {
|
|
332
420
|
const result = await rememberTool.execute(
|
|
333
421
|
{ content: [" ", ""] },
|
|
334
422
|
makeContext(),
|
|
335
423
|
);
|
|
336
424
|
expect(result.isError).toBe(true);
|
|
425
|
+
expect(result.activityMetadata).toBeUndefined();
|
|
337
426
|
expect(enqueueCalls).toHaveLength(0);
|
|
338
427
|
});
|
|
339
428
|
});
|
|
340
429
|
|
|
430
|
+
/** The advertised `content` description, read as the provider serializes it. */
|
|
431
|
+
function contentDescription(schema: Record<string, unknown>): string {
|
|
432
|
+
return z
|
|
433
|
+
.object({
|
|
434
|
+
properties: z.object({ content: z.object({ description: z.string() }) }),
|
|
435
|
+
})
|
|
436
|
+
.parse(schema).properties.content.description;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
describe("rememberTool definition", () => {
|
|
440
|
+
test("advertises the schema it parses with", () => {
|
|
441
|
+
const schema = rememberTool.input_schema;
|
|
442
|
+
|
|
443
|
+
expect(schema.required).toEqual(["content"]);
|
|
444
|
+
expect(schema.properties).toMatchObject({
|
|
445
|
+
content: {
|
|
446
|
+
anyOf: [
|
|
447
|
+
{ type: "string" },
|
|
448
|
+
{ type: "array", items: { type: "string" }, minItems: 1 },
|
|
449
|
+
],
|
|
450
|
+
},
|
|
451
|
+
finish_turn: { type: "boolean" },
|
|
452
|
+
});
|
|
453
|
+
});
|
|
454
|
+
});
|
|
455
|
+
|
|
341
456
|
describe("rememberTool definition — page-hint guidance gating", () => {
|
|
342
457
|
// The rest of this file seeds the v2 flag off; restore that seed.
|
|
343
458
|
afterAll(() => {
|
|
@@ -346,14 +461,14 @@ describe("rememberTool definition — page-hint guidance gating", () => {
|
|
|
346
461
|
|
|
347
462
|
test("omits the [[slug]] hint guidance in v1/PKB mode", () => {
|
|
348
463
|
setConfig("memory", { v2: { enabled: false } });
|
|
349
|
-
expect(
|
|
350
|
-
|
|
351
|
-
)
|
|
464
|
+
expect(contentDescription(rememberTool.input_schema)).not.toContain(
|
|
465
|
+
"[[slug]]",
|
|
466
|
+
);
|
|
352
467
|
});
|
|
353
468
|
|
|
354
469
|
test("includes the [[slug]] hint guidance under concept-page memory (v2)", () => {
|
|
355
470
|
setConfig("memory", { v2: { enabled: true } });
|
|
356
|
-
expect(rememberTool.input_schema
|
|
471
|
+
expect(contentDescription(rememberTool.input_schema)).toContain(
|
|
357
472
|
"[[slug]] wikilinks",
|
|
358
473
|
);
|
|
359
474
|
// The gate must survive JSON serialization — that's how the schema
|
|
@@ -365,7 +480,7 @@ describe("rememberTool definition — page-hint guidance gating", () => {
|
|
|
365
480
|
|
|
366
481
|
test("includes the [[slug]] hint guidance when v3 is live with the v2 flag off", () => {
|
|
367
482
|
setConfig("memory", { v2: { enabled: false }, v3: { live: true } });
|
|
368
|
-
expect(rememberTool.input_schema
|
|
483
|
+
expect(contentDescription(rememberTool.input_schema)).toContain(
|
|
369
484
|
"[[slug]] wikilinks",
|
|
370
485
|
);
|
|
371
486
|
});
|
|
@@ -373,8 +488,8 @@ describe("rememberTool definition — page-hint guidance gating", () => {
|
|
|
373
488
|
test("re-resolves against config on each read, without re-registration", () => {
|
|
374
489
|
const schema = rememberTool.input_schema;
|
|
375
490
|
setConfig("memory", { v2: { enabled: true } });
|
|
376
|
-
expect(schema
|
|
491
|
+
expect(contentDescription(schema)).toContain("[[slug]]");
|
|
377
492
|
setConfig("memory", { v2: { enabled: false } });
|
|
378
|
-
expect(schema
|
|
493
|
+
expect(contentDescription(schema)).not.toContain("[[slug]]");
|
|
379
494
|
});
|
|
380
495
|
});
|
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Core, always-loaded tools registered via the host tool manifest
|
|
5
5
|
* (`tools/tool-manifest.ts`), so they carry core/workspace-override precedence
|
|
6
|
-
* and the `"memory"` tool category.
|
|
7
|
-
*
|
|
6
|
+
* and the `"memory"` tool category. The host's central input check covers only
|
|
7
|
+
* tools it can import, which excludes a plugin's, so each tool here parses its
|
|
8
|
+
* own input.
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
|
-
import { throwIfCancelled } from "@vellumai/plugin-api";
|
|
11
|
+
import { invalidToolInputResult, throwIfCancelled } from "@vellumai/plugin-api";
|
|
11
12
|
|
|
13
|
+
import { RememberInputSchema } from "../../../api/remember-tool.js";
|
|
12
14
|
import { getConfig, getConfigReadOnly } from "../../../config/loader.js";
|
|
13
15
|
import { usesConceptPageMemory } from "../../../config/memory-v3-gate.js";
|
|
14
16
|
import { RiskLevel } from "../../../permissions/types.js";
|
|
@@ -19,8 +21,8 @@ import type {
|
|
|
19
21
|
ToolExecutionResult,
|
|
20
22
|
} from "../../../tools/types.js";
|
|
21
23
|
import { runAgenticRecall } from "./context-search/agent-runner.js";
|
|
22
|
-
import
|
|
23
|
-
import { handleRemember
|
|
24
|
+
import { RecallInputSchema } from "./context-search/recall-input.js";
|
|
25
|
+
import { handleRemember } from "./graph/tool-handlers.js";
|
|
24
26
|
import {
|
|
25
27
|
buildRememberInputSchema,
|
|
26
28
|
graphRecallDefinition,
|
|
@@ -52,18 +54,35 @@ export const rememberTool = {
|
|
|
52
54
|
input: Record<string, unknown>,
|
|
53
55
|
context: ToolContext,
|
|
54
56
|
): Promise<ToolExecutionResult> {
|
|
55
|
-
const typedInput = input as unknown as RememberInput;
|
|
56
57
|
// The append below writes the memory buffer, so a cancelled turn stops here.
|
|
57
58
|
throwIfCancelled(context);
|
|
59
|
+
if (!resolveCapabilities(context.trustClass).canAccessMemory) {
|
|
60
|
+
// No yield even when finish_turn is set: the model has to see this, so
|
|
61
|
+
// it never tells someone a fact was saved when it was not. An error, not
|
|
62
|
+
// a quiet no-op: a non-error `remember` result reads as a durable write to
|
|
63
|
+
// `memory-run-evidence`.
|
|
64
|
+
return {
|
|
65
|
+
content:
|
|
66
|
+
"Not saved: remember writes the guardian's long-term memory, which is only available on the guardian's own turns. Retrying will not help. Tell the person only if they asked you to remember this or you said you would.",
|
|
67
|
+
isError: true,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const parsed = RememberInputSchema.safeParse(input);
|
|
71
|
+
if (!parsed.success) {
|
|
72
|
+
return invalidToolInputResult("remember", parsed.error);
|
|
73
|
+
}
|
|
58
74
|
const result = handleRemember(
|
|
59
|
-
|
|
75
|
+
parsed.data,
|
|
60
76
|
context.conversationId,
|
|
61
77
|
getConfig(),
|
|
62
78
|
);
|
|
63
79
|
return {
|
|
64
80
|
content: result.message,
|
|
65
81
|
isError: !result.success,
|
|
66
|
-
...(
|
|
82
|
+
...(result.success
|
|
83
|
+
? { activityMetadata: { remember: { facts: result.facts } } }
|
|
84
|
+
: {}),
|
|
85
|
+
...(parsed.data.finish_turn === true ? { yieldToUser: true } : {}),
|
|
67
86
|
};
|
|
68
87
|
},
|
|
69
88
|
} satisfies ToolDefinition;
|
|
@@ -90,15 +109,23 @@ export const recallTool = {
|
|
|
90
109
|
};
|
|
91
110
|
}
|
|
92
111
|
|
|
112
|
+
const parsed = RecallInputSchema.safeParse(input);
|
|
113
|
+
if (!parsed.success) {
|
|
114
|
+
return invalidToolInputResult("recall", parsed.error);
|
|
115
|
+
}
|
|
93
116
|
const config = getConfig();
|
|
94
|
-
const result = await runAgenticRecall(
|
|
117
|
+
const result = await runAgenticRecall(parsed.data, {
|
|
95
118
|
workingDir: context.workingDir,
|
|
96
119
|
conversationId: context.conversationId,
|
|
97
120
|
config,
|
|
98
121
|
signal: context.signal,
|
|
99
122
|
});
|
|
100
123
|
|
|
101
|
-
return {
|
|
124
|
+
return {
|
|
125
|
+
content: result.content,
|
|
126
|
+
isError: false,
|
|
127
|
+
activityMetadata: { recall: result.activity },
|
|
128
|
+
};
|
|
102
129
|
},
|
|
103
130
|
} satisfies ToolDefinition;
|
|
104
131
|
|
|
@@ -127,7 +154,7 @@ export const recallTool = {
|
|
|
127
154
|
export const deleteMemoryPageTool = {
|
|
128
155
|
name: "delete_memory_page",
|
|
129
156
|
description:
|
|
130
|
-
"Delete one concept page from your memory wiki, addressed by slug (its path under `memory/concepts/` minus `.md`, e.g. `alice`, `people/alice`, `procs/git-flow`). Use during a consolidation/maintenance pass to retire a page you merged into another, renamed (write the new page, then delete the old slug), or dropped as a dead stub. Only concept pages can be deleted: the index files (`recent.md`, `essentials.md`, `threads.md`) are rewritten with file_write/file_edit, never deleted, and `buffer.md` is never written by you at all; the runtime removes the entries it handed you once the pass completes. Idempotent: deleting a slug that is already gone is not an error.
|
|
157
|
+
"Delete one concept page from your memory wiki, addressed by slug (its path under `memory/concepts/` minus `.md`, e.g. `alice`, `people/alice`, `procs/git-flow`). Use during a consolidation/maintenance pass to retire a page you merged into another, renamed (write the new page, then delete the old slug), or dropped as a dead stub. Only concept pages can be deleted: the index files (`recent.md`, `essentials.md`, `threads.md`) are rewritten with file_write/file_edit, never deleted, and `buffer.md` is never written by you at all; the runtime removes the entries it handed you once the pass completes. Idempotent: deleting a slug that is already gone is not an error.",
|
|
131
158
|
category: "memory",
|
|
132
159
|
executionTarget: "sandbox",
|
|
133
160
|
defaultRiskLevel: RiskLevel.Low,
|