@vellumai/assistant 0.10.12 → 0.11.0-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/AGENTS.md +1 -1
- package/ARCHITECTURE.md +4 -5
- package/README.md +1 -1
- package/docs/architecture/memory.md +60 -23
- package/docs/error-handling.md +3 -3
- package/docs/guardian-request-flow.md +112 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts +28 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts +2 -2
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.js.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts +2 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts.map +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/package.json +1 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/node_modules/@vellumai/gateway-client/package.json +1 -1
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +6 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +34 -0
- package/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
- package/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
- package/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
- package/openapi.yaml +264 -14
- package/package.json +2 -2
- package/src/__tests__/acp-session.test.ts +3 -3
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +3 -0
- package/src/__tests__/anthropic-provider.test.ts +40 -0
- package/src/__tests__/app-conversation-ids-backfill.test.ts +33 -2
- package/src/__tests__/app-conversation-ids.test.ts +204 -0
- package/src/__tests__/approval-cascade.test.ts +5 -5
- package/src/__tests__/approval-routes-http.test.ts +3 -3
- package/src/__tests__/ask-question-resolver.test.ts +207 -0
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +16 -16
- package/src/__tests__/assistant-event-hub-targeted.test.ts +13 -11
- package/src/__tests__/assistant-event-hub.test.ts +13 -11
- package/src/__tests__/assistant-event.test.ts +12 -9
- package/src/__tests__/assistant-feature-flag-guard.test.ts +3 -3
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +1 -1
- package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -58
- package/src/__tests__/assistant-stream-state.test.ts +17 -7
- package/src/__tests__/avatar-identity-sync.test.ts +3 -3
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -0
- package/src/__tests__/call-conversation-messages.test.ts +134 -18
- package/src/__tests__/call-start-guardian-guard.test.ts +27 -0
- package/src/__tests__/channel-approvals.test.ts +0 -27
- package/src/__tests__/channel-guardian.test.ts +85 -512
- package/src/__tests__/channel-readiness-slack-remote.test.ts +151 -3
- package/src/__tests__/channel-retry-sweep.test.ts +88 -1
- package/src/__tests__/channel-setup-panel-ack.test.ts +12 -9
- package/src/__tests__/chat-reveal-guard-priming.test.ts +31 -34
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +2 -2
- package/src/__tests__/compaction-events.test.ts +8 -8
- package/src/__tests__/config-loader-platform-defaults.test.ts +54 -28
- package/src/__tests__/config-model-image-provider.test.ts +20 -0
- package/src/__tests__/config-schema-memory-substrate.test.ts +306 -0
- package/src/__tests__/config-schema.test.ts +14 -2
- package/src/__tests__/config-set-platform-guard.test.ts +11 -12
- package/src/__tests__/config-sounds-sync.test.ts +4 -4
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +5 -0
- package/src/__tests__/context-search-memory-source.test.ts +1 -1
- package/src/__tests__/context-search-memory-v2-source.test.ts +6 -6
- package/src/__tests__/context-token-estimator.test.ts +54 -1
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +12 -3
- package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +13 -4
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +4 -4
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +22 -13
- package/src/__tests__/conversation-agent-loop.test.ts +39 -30
- package/src/__tests__/conversation-confirmation-signals.test.ts +14 -14
- package/src/__tests__/conversation-evictor.test.ts +49 -0
- package/src/__tests__/conversation-fork-crud.test.ts +1 -1
- package/src/__tests__/conversation-group-tools.test.ts +279 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-key-store-disk-view.test.ts +5 -5
- package/src/__tests__/conversation-lineage.test.ts +235 -0
- package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +5 -5
- package/src/__tests__/conversation-message-sync-tags.test.ts +4 -4
- package/src/__tests__/conversation-queue.test.ts +81 -81
- package/src/__tests__/conversation-routes-enabled-plugins.test.ts +8 -1
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +8 -1
- package/src/__tests__/conversation-routes-slash-commands.test.ts +10 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +29 -2
- package/src/__tests__/conversation-slash-queue.test.ts +11 -11
- package/src/__tests__/conversation-slash-unknown.test.ts +2 -2
- package/src/__tests__/conversation-speed-override.test.ts +2 -2
- package/src/__tests__/conversation-summarize-route.test.ts +9 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +18 -16
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +17 -17
- package/src/__tests__/conversation-surfaces-app-open.test.ts +7 -4
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +7 -7
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +9 -9
- package/src/__tests__/conversation-surfaces-standalone.test.ts +12 -12
- package/src/__tests__/conversation-surfaces-state-update.test.ts +8 -5
- package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +46 -46
- package/src/__tests__/conversation-sync-tags.test.ts +5 -5
- package/src/__tests__/conversation-wait-for-idle.test.ts +2 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -4
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -3
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -3
- package/src/__tests__/copy-composer-tc-templates.test.ts +3 -131
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/daemon-assistant-events.test.ts +14 -15
- package/src/__tests__/db-test-helpers.ts +13 -27
- package/src/__tests__/disk-pressure-routes.test.ts +12 -3
- package/src/__tests__/document-tool-security.test.ts +95 -0
- package/src/__tests__/drain-kick-guard.test.ts +232 -0
- package/src/__tests__/dynamic-skill-background-guard.test.ts +19 -6
- package/src/__tests__/emit-event-signal.test.ts +5 -6
- package/src/__tests__/encrypted-store-test-helpers.ts +10 -20
- package/src/__tests__/events-tail-route.test.ts +6 -4
- package/src/__tests__/feature-flag-test-helpers.ts +10 -20
- package/src/__tests__/file-edit-tool.test.ts +24 -4
- package/src/__tests__/file-list-tool.test.ts +2 -1
- package/src/__tests__/file-read-tool.test.ts +62 -10
- package/src/__tests__/file-write-tool.test.ts +24 -5
- package/src/__tests__/followup-tools.test.ts +58 -0
- package/src/__tests__/gateway-threshold-reader-mock.ts +99 -0
- package/src/__tests__/graph-extraction-event-date.test.ts +1 -1
- package/src/__tests__/guardian-question-mode.test.ts +42 -3
- package/src/__tests__/guardian-reply-router-answer-mode.test.ts +283 -0
- package/src/__tests__/guardian-vellum-destination-pinning.test.ts +221 -0
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +1 -0
- package/src/__tests__/helpers/native-web-search-harness.ts +10 -10
- package/src/__tests__/host-browser-proxy.test.ts +1 -1
- package/src/__tests__/host-file-edit-tool.test.ts +3 -3
- package/src/__tests__/host-file-read-tool.test.ts +2 -2
- package/src/__tests__/host-file-write-tool.test.ts +7 -3
- package/src/__tests__/host-shell-tool.test.ts +17 -5
- package/src/__tests__/host-transfer-pending-interactions.test.ts +8 -8
- package/src/__tests__/image-credentials.test.ts +65 -8
- package/src/__tests__/injection-block.test.ts +4 -4
- package/src/__tests__/injector-chain.test.ts +1 -1
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
- package/src/__tests__/injector-registry-order-guard.test.ts +4 -9
- package/src/__tests__/injector-v3-suppression.test.ts +6 -4
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +27 -28
- package/src/__tests__/list-messages-page-latest.test.ts +2 -2
- package/src/__tests__/llm-usage-store.test.ts +67 -4
- package/src/__tests__/log-redact.test.ts +18 -0
- package/src/__tests__/managed-profile-guard.test.ts +27 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +2 -2
- package/src/__tests__/media-generate-image.test.ts +62 -11
- package/src/__tests__/memory-identity-context-parity.test.ts +1 -1
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +9 -1
- package/src/__tests__/memory-retrieval-hook.test.ts +4 -4
- package/src/__tests__/notification-decision-strategy.test.ts +115 -11
- package/src/__tests__/notification-deep-link.test.ts +12 -12
- package/src/__tests__/notification-vellum-adapter.test.ts +8 -8
- package/src/__tests__/outbound-slack-persistence.test.ts +8 -8
- package/src/__tests__/path-policy.test.ts +315 -0
- package/src/__tests__/pending-interactions-resolved-event.test.ts +6 -6
- package/src/__tests__/persistence-layering-guard.test.ts +2 -2
- package/src/__tests__/pkb-autoinject.test.ts +1 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +1 -0
- package/src/__tests__/platform-callback-registration.test.ts +10 -10
- package/src/__tests__/plugin-event-hub-facade.test.ts +22 -15
- package/src/__tests__/plugin-import-boundary-guard.test.ts +15 -15
- package/src/__tests__/processing-flag-persist-failure.test.ts +0 -4
- package/src/__tests__/provider-platform-proxy-integration.test.ts +0 -1
- package/src/__tests__/rebuild-index-graph-nodes.test.ts +1 -1
- package/src/__tests__/request-secret-standalone-channel-gate.test.ts +5 -5
- package/src/__tests__/require-fresh-approval.test.ts +38 -38
- package/src/__tests__/resolve-app-id.test.ts +32 -0
- package/src/__tests__/run-due-schedules.test.ts +72 -1
- package/src/__tests__/runtime-events-sse-parity.test.ts +11 -10
- package/src/__tests__/runtime-events-sse.test.ts +1 -1
- package/src/__tests__/schedule-routes.test.ts +44 -5
- package/src/__tests__/schedule-store.test.ts +3 -3
- package/src/__tests__/schedule-tools.test.ts +176 -0
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +3 -3
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +3 -3
- package/src/__tests__/secret-response-routing.test.ts +3 -3
- package/src/__tests__/secret-routes-platform-proxy.test.ts +4 -7
- package/src/__tests__/secret-scanner.test.ts +36 -0
- package/src/__tests__/send-endpoint-busy.test.ts +7 -7
- package/src/__tests__/slack-required-scopes-mirror.test.ts +81 -0
- package/src/__tests__/starter-task-flow.test.ts +26 -3
- package/src/__tests__/subagent-call-site-routing.test.ts +2 -2
- package/src/__tests__/subagent-disposal.test.ts +40 -11
- package/src/__tests__/subagent-fork-notifications.test.ts +4 -4
- package/src/__tests__/subagent-fork-prompt-role.test.ts +3 -3
- package/src/__tests__/subagent-fork-spawn.test.ts +4 -4
- package/src/__tests__/subagent-manager-notify.test.ts +73 -14
- package/src/__tests__/subagent-notify-parent.test.ts +48 -4
- package/src/__tests__/subagent-spawn-and-await.test.ts +62 -14
- package/src/__tests__/subagent-tools.test.ts +64 -0
- package/src/__tests__/sync-message-contract.test.ts +3 -3
- package/src/__tests__/terminal-tools.test.ts +12 -3
- package/src/__tests__/test-preload.ts +9 -0
- package/src/__tests__/tool-approval-handler.test.ts +587 -43
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +7 -4
- package/src/__tests__/tool-executor.test.ts +116 -0
- package/src/__tests__/tool-grant-request-escalation.test.ts +5 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +32 -29
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +5 -5
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
- package/src/__tests__/tool-start-timestamp.test.ts +4 -4
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +9 -22
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +13 -13
- package/src/__tests__/ui-work-result-surface.test.ts +3 -3
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +6 -6
- package/src/__tests__/voice-session-bridge.test.ts +44 -44
- package/src/__tests__/workspace-migration-134-image-generation-mode-to-provider.test.ts +284 -0
- package/src/__tests__/workspace-policy.test.ts +482 -2
- package/src/acp/__tests__/client-handler.test.ts +3 -3
- package/src/acp/__tests__/session-manager-persistence.test.ts +10 -10
- package/src/acp/__tests__/session-manager-resume.test.ts +7 -7
- package/src/acp/client-handler.ts +3 -3
- package/src/acp/session-manager.ts +8 -8
- package/src/api/events/subagent-event.ts +2 -2
- package/src/api/responses/memory-v2-activation-log.ts +2 -2
- package/src/api/responses/subagent-detail.ts +13 -0
- package/src/approvals/AGENTS.md +2 -0
- package/src/approvals/guardian-request-resolvers.ts +118 -24
- package/src/apps/app-store.ts +95 -4
- package/src/calls/__tests__/voice-control-protocol.test.ts +57 -0
- package/src/calls/__tests__/voice-session-bridge.test.ts +229 -7
- package/src/calls/__tests__/voice-triage-escalate.test.ts +3 -4
- package/src/calls/call-controller.ts +27 -27
- package/src/calls/call-conversation-messages.ts +58 -18
- package/src/calls/voice-control-protocol.ts +56 -0
- package/src/calls/voice-session-bridge.ts +178 -65
- package/src/calls/voice-triage-escalate.ts +2 -3
- package/src/channels/config.ts +8 -0
- package/src/channels/types.ts +1 -0
- package/src/cli/commands/config.ts +49 -13
- package/src/cli/commands/memory/index.help.ts +4 -2
- package/src/cli/commands/memory/memory-retrospective.ts +5 -0
- package/src/cli/commands/webhooks.help.ts +9 -4
- package/src/cli/lib/bundled-marketplace.json +12 -0
- package/src/cli.ts +2 -109
- package/src/config/__tests__/deployment-context-defaults.test.ts +9 -0
- package/src/config/__tests__/substrate-twin-shadowing.test.ts +191 -0
- package/src/config/assistant-feature-flags.ts +1 -1
- package/src/config/bundled-skills/conversation-groups/SKILL.md +29 -0
- package/src/config/bundled-skills/conversation-groups/TOOLS.json +58 -0
- package/src/config/bundled-skills/conversation-groups/tools/group-create.ts +12 -0
- package/src/config/bundled-skills/conversation-groups/tools/group-list.ts +12 -0
- package/src/config/bundled-skills/conversation-groups/tools/move-to-group.ts +12 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +13 -7
- package/src/config/bundled-skills/schedule/SKILL.md +2 -0
- package/src/config/feature-flag-cache.ts +6 -16
- package/src/config/feature-flag-registry.json +14 -38
- package/src/config/loader.ts +7 -1
- package/src/config/memory-tier.ts +15 -10
- package/src/config/memory-v3-gate.test.ts +278 -1
- package/src/config/memory-v3-gate.ts +88 -26
- package/src/config/raw-config-utils.ts +1 -1
- package/src/config/schemas/__tests__/live-voice.test.ts +27 -16
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/live-voice.ts +33 -7
- package/src/config/schemas/llm.ts +1 -0
- package/src/config/schemas/memory-retrospective.ts +13 -0
- package/src/config/schemas/memory-substrate.ts +183 -0
- package/src/config/schemas/memory-v2.ts +3 -2
- package/src/config/schemas/memory-v3.ts +11 -4
- package/src/config/schemas/memory.ts +35 -1
- package/src/config/schemas/services.ts +10 -2
- package/src/config/substrate-twin-shadowing.ts +195 -0
- package/src/config/webhook-routing.ts +67 -0
- package/src/context/compactor.ts +10 -3
- package/src/context/token-estimator.ts +21 -0
- package/src/daemon/__tests__/channel-ui-capability.test.ts +85 -0
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +3 -3
- package/src/daemon/__tests__/embedding-reconcile.test.ts +3 -3
- package/src/daemon/__tests__/inference-profile-notification.test.ts +3 -6
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +5 -5
- package/src/daemon/__tests__/web-search-status-text.test.ts +2 -2
- package/src/daemon/channel-ui-capability.ts +70 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +4 -4
- package/src/daemon/conversation-agent-loop.ts +12 -5
- package/src/daemon/conversation-evictor.ts +26 -4
- package/src/daemon/conversation-launch.ts +11 -14
- package/src/daemon/conversation-lineage.ts +76 -0
- package/src/daemon/conversation-messaging.ts +14 -14
- package/src/daemon/conversation-notifiers.ts +2 -2
- package/src/daemon/conversation-process.ts +133 -21
- package/src/daemon/conversation-queue-manager.ts +7 -7
- package/src/daemon/conversation-runtime-assembly.ts +16 -0
- package/src/daemon/conversation-store.ts +11 -3
- package/src/daemon/conversation-surfaces.ts +8 -14
- package/src/daemon/conversation-tool-setup.ts +13 -7
- package/src/daemon/conversation-usage.ts +12 -11
- package/src/daemon/conversation.ts +38 -15
- package/src/daemon/disk-pressure-guard.ts +5 -12
- package/src/daemon/embedding-reconcile.ts +14 -9
- package/src/daemon/handlers/config-channels.ts +40 -134
- package/src/daemon/handlers/config-model.ts +15 -7
- package/src/daemon/handlers/conversations.ts +4 -2
- package/src/daemon/handlers/shared.ts +29 -0
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/lifecycle.ts +13 -0
- package/src/daemon/message-protocol.ts +8 -144
- package/src/daemon/message-types/computer-use.ts +0 -12
- package/src/daemon/message-types/conversations.ts +9 -345
- package/src/daemon/message-types/host-app-control.ts +0 -9
- package/src/daemon/message-types/host-browser.ts +0 -7
- package/src/daemon/message-types/host-ui-snapshot.ts +0 -7
- package/src/daemon/message-types/messages.ts +0 -48
- package/src/daemon/message-types/notifications.ts +0 -7
- package/src/daemon/message-types/skills.ts +0 -5
- package/src/daemon/message-types/surfaces.ts +0 -9
- package/src/daemon/message-types/sync.ts +0 -2
- package/src/daemon/process-message.ts +5 -5
- package/src/daemon/skill-memory-refresh.ts +5 -5
- package/src/daemon/tool-side-effects.ts +32 -16
- package/src/daemon/trust-context.ts +1 -1
- package/src/daemon/wake-conversation-ops.ts +4 -4
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +100 -7
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +67 -0
- package/src/heartbeat/heartbeat-run-store.ts +81 -4
- package/src/heartbeat/heartbeat-service.ts +32 -1
- package/src/home/__tests__/feed-writer.test.ts +7 -7
- package/src/home/__tests__/home-content-refresh.test.ts +3 -0
- package/src/home/__tests__/suggested-prompts.test.ts +1 -0
- package/src/home/feed-writer.ts +6 -13
- package/src/home/home-content-refresh.ts +6 -9
- package/src/home/relationship-state-writer.ts +5 -12
- package/src/home/suggested-prompts-cache.ts +6 -19
- package/src/ipc/__tests__/events-publish-client.test.ts +67 -0
- package/src/ipc/events-publish-client.ts +44 -0
- package/src/ipc/routes/__tests__/conversation-sync-ipc-routes.test.ts +2 -2
- package/src/ipc/routes/__tests__/events-ipc-routes.test.ts +38 -9
- package/src/ipc/routes/events-ipc-routes.ts +11 -31
- package/src/live-voice/__tests__/front-decision.test.ts +4 -176
- package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +276 -68
- package/src/live-voice/__tests__/live-voice-continuation-fork-hydration.test.ts +286 -0
- package/src/live-voice/__tests__/live-voice-events.test.ts +6 -3
- package/src/live-voice/__tests__/live-voice-progress.test.ts +185 -46
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +24 -59
- package/src/live-voice/__tests__/live-voice-tts-session.test.ts +38 -54
- package/src/live-voice/__tests__/live-voice-vad.test.ts +1154 -636
- package/src/live-voice/front-decision.ts +5 -155
- package/src/live-voice/live-voice-metrics.ts +4 -1
- package/src/live-voice/live-voice-session.ts +1288 -439
- package/src/live-voice/progress-phrases.ts +17 -0
- package/src/live-voice/protocol.ts +15 -0
- package/src/media/app-icon-generator.ts +15 -8
- package/src/media/avatar-router.ts +9 -5
- package/src/media/image-credentials.ts +42 -10
- package/src/media/image-service.ts +1 -13
- package/src/media/types.ts +26 -3
- package/src/notifications/AGENTS.md +2 -0
- package/src/notifications/__tests__/broadcaster.test.ts +95 -0
- package/src/notifications/adapters/macos.ts +3 -3
- package/src/notifications/broadcaster.ts +57 -0
- package/src/notifications/copy-composer.ts +0 -15
- package/src/notifications/decision-engine.ts +21 -22
- package/src/notifications/guardian-question-mode.ts +57 -2
- package/src/notifications/home-feed-side-effect.ts +4 -0
- package/src/notifications/signal.ts +6 -4
- package/src/notifications/trusted-contact-payloads.ts +3 -4
- package/src/notifications/vellum-card-affinity.ts +39 -0
- package/src/oauth/AGENTS.md +1 -1
- package/src/permissions/channel-permission-query.test.ts +69 -0
- package/src/permissions/channel-permission-query.ts +73 -1
- package/src/permissions/checker.test.ts +298 -15
- package/src/permissions/checker.ts +102 -36
- package/src/permissions/confirmation-guardian-request.test.ts +2 -2
- package/src/permissions/confirmation-guardian-request.ts +2 -2
- package/src/permissions/gateway-threshold-reader.test.ts +224 -17
- package/src/permissions/gateway-threshold-reader.ts +82 -10
- package/src/permissions/ipc-risk-types.ts +8 -0
- package/src/permissions/prompter.ts +5 -5
- package/src/permissions/question-guardian-request.test.ts +222 -0
- package/src/permissions/question-guardian-request.ts +179 -0
- package/src/permissions/question-prompter.test.ts +8 -8
- package/src/permissions/question-prompter.ts +18 -0
- package/src/permissions/secret-prompter.ts +2 -4
- package/src/permissions/workspace-policy.ts +269 -34
- package/src/persistence/__tests__/lifecycle-quiesce.test.ts +82 -0
- package/src/persistence/__tests__/message-content-file.test.ts +58 -3
- package/src/persistence/conversation-crud.ts +93 -0
- package/src/persistence/conversation-key-store.ts +63 -0
- package/src/persistence/conversation-parent.ts +27 -0
- package/src/persistence/db-async-query.ts +1 -1
- package/src/persistence/db-singleton.ts +14 -27
- package/src/persistence/delivery-crud.ts +45 -0
- package/src/persistence/embeddings/embedding-backend.ts +2 -1
- package/src/persistence/embeddings/embedding-identity.ts +7 -3
- package/src/persistence/job-utils.ts +32 -27
- package/src/persistence/jobs-store.ts +92 -3
- package/src/persistence/lifecycle-quiesce.ts +80 -0
- package/src/persistence/llm-usage-store.ts +45 -8
- package/src/persistence/message-content-file.ts +4 -4
- package/src/persistence/migrations/336-move-memory-v2-activation-logs-to-memory-db.ts +1 -1
- package/src/persistence/migrations/351-schedule-skill-script-handoff.ts +39 -0
- package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.test.ts +83 -0
- package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.ts +36 -0
- package/src/persistence/migrations/353-add-llm-usage-conversation-type.test.ts +110 -0
- package/src/persistence/migrations/353-add-llm-usage-conversation-type.ts +49 -0
- package/src/persistence/migrations/354-backfill-app-conversation-lineage.ts +41 -0
- package/src/persistence/schema/infrastructure.ts +11 -0
- package/src/persistence/steps.ts +9 -1
- package/src/plugin-api/__tests__/publish-event-forwarding.test.ts +113 -0
- package/src/plugin-api/__tests__/publish-event.test.ts +57 -0
- package/src/plugin-api/conversation-turn.ts +4 -4
- package/src/plugin-api/event-hub-facade.ts +15 -6
- package/src/plugin-api/index.ts +10 -4
- package/src/plugin-api/publish-event.ts +36 -0
- package/src/plugins/AGENTS.md +2 -0
- package/src/plugins/defaults/compaction/window-manager.ts +9 -0
- package/src/plugins/defaults/index.ts +9 -13
- package/src/plugins/defaults/memory/AGENTS.md +775 -0
- package/src/plugins/defaults/memory/__tests__/capability-seed-embed-gate.test.ts +186 -0
- package/src/plugins/defaults/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/indexer-tier-dispatch.test.ts +129 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-quiesce-gate.test.ts +91 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v1-graph-substrate-noop.test.ts +342 -0
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +9 -1
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +36 -1
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-sweep-defer.test.ts +9 -1
- package/src/plugins/defaults/memory/__tests__/memory-log-stores-degraded.test.ts +2 -2
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +44 -10
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +151 -10
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +1155 -0
- package/src/plugins/defaults/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -3
- package/src/plugins/defaults/memory/__tests__/tools-delete-memory-page.test.ts +1 -1
- package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +71 -35
- package/src/plugins/defaults/memory/context-search/sources/memory.ts +5 -1
- package/src/plugins/defaults/memory/fork-conversation-memory.ts +4 -4
- package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +80 -10
- package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +1 -1
- package/src/plugins/defaults/memory/graph/capability-seed.ts +24 -10
- package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +123 -49
- package/src/plugins/defaults/memory/graph/graph-search.ts +6 -118
- package/src/plugins/defaults/memory/graph/in-context-tracker.test.ts +173 -0
- package/src/plugins/defaults/memory/graph/in-context-tracker.ts +109 -0
- package/src/plugins/defaults/memory/graph/store.ts +1 -0
- package/src/plugins/defaults/memory/graph/tool-handlers.test.ts +1 -1
- package/src/plugins/defaults/memory/graph/tool-handlers.ts +5 -2
- package/src/plugins/defaults/memory/graph-topology/__tests__/build-memory-graph.test.ts +1 -1
- package/src/plugins/defaults/memory/graph-topology/build-memory-graph.ts +6 -9
- package/src/plugins/defaults/memory/hooks/__tests__/user-prompt-submit.test.ts +30 -16
- package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +18 -14
- package/src/plugins/defaults/memory/indexer.ts +146 -89
- package/src/plugins/defaults/memory/injectors.ts +86 -41
- package/src/plugins/defaults/memory/job-handlers.ts +130 -39
- package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +2 -2
- package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +22 -10
- package/src/plugins/defaults/memory/jobs-worker.ts +279 -208
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +4 -2
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +40 -3
- package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +99 -11
- package/src/plugins/defaults/memory/src/__tests__/memory-v2-routes.test.ts +5 -3
- package/src/plugins/defaults/memory/src/__tests__/memory-v2-simulate-route.test.ts +3 -4
- package/src/plugins/defaults/memory/src/memory-graph-routes.ts +2 -1
- package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +7 -5
- package/src/plugins/defaults/memory/src/memory-item-routes.ts +51 -19
- package/src/plugins/defaults/memory/src/memory-v2-routes.ts +31 -20
- package/src/plugins/defaults/memory/startup.ts +58 -21
- package/src/plugins/defaults/memory/substrate/__tests__/boot-maintenance.test.ts +335 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/cli-command-store.test.ts +14 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-job.test.ts +51 -21
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/edge-index.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/frontmatter-sweep.test.ts +3 -3
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-index.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-store.test.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/prompts-consolidation.test.ts +2 -2
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/qdrant.test.ts +23 -14
- package/src/plugins/defaults/memory/substrate/__tests__/reembed-job.test.ts +262 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sim.test.ts +9 -12
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-content.test.ts +2 -2
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-store.test.ts +9 -9
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sparse-bm25.test.ts +12 -5
- package/src/plugins/defaults/memory/substrate/__tests__/spread.test.ts +276 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/static-context.test.ts +17 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sweep-job.test.ts +9 -9
- package/src/plugins/defaults/memory/{v3/substrate/memory-v2-startup.ts → substrate/boot-maintenance.ts} +43 -24
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-store.ts +13 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/consolidation-job.ts +51 -27
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/constants.ts +1 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/edge-index.ts +28 -9
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/frontmatter-sweep.ts +14 -7
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/injected-block-slugs.ts +9 -3
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-index.ts +29 -10
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-store.ts +35 -12
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/consolidation.ts +14 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/sweep.ts +4 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/qdrant.ts +96 -36
- package/src/plugins/defaults/memory/substrate/reembed-job.ts +54 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sim.ts +26 -15
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-content.ts +1 -1
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-store.ts +13 -8
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sparse-bm25.ts +27 -10
- package/src/plugins/defaults/memory/substrate/spread.ts +165 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/static-context.ts +12 -7
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/sweep-job.ts +20 -15
- package/src/plugins/defaults/memory/substrate/tuning.ts +93 -0
- package/src/plugins/defaults/memory/{v3/substrate → substrate}/types.ts +7 -4
- package/src/plugins/defaults/memory/tools.test.ts +1 -1
- package/src/plugins/defaults/memory/tools.ts +1 -1
- package/src/plugins/defaults/memory/v1/README.md +5 -0
- package/src/plugins/defaults/memory/{__tests__ → v1/__tests__}/filing-jobs.test.ts +4 -4
- package/src/plugins/defaults/memory/{filing-jobs.ts → v1/filing-jobs.ts} +3 -3
- package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.test.ts +68 -6
- package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.ts +40 -21
- package/src/plugins/defaults/memory/{graph → v1/graph}/consolidation.ts +14 -14
- package/src/plugins/defaults/memory/{graph → v1/graph}/decay.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/decay.ts +3 -3
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction-job.ts +5 -5
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.ts +20 -14
- package/src/plugins/defaults/memory/{graph → v1/graph}/graph-search.test.ts +3 -3
- package/src/plugins/defaults/memory/v1/graph/graph-search.ts +123 -0
- package/src/plugins/defaults/memory/{graph → v1/graph}/injection.test.ts +1 -118
- package/src/plugins/defaults/memory/{graph → v1/graph}/injection.ts +9 -111
- package/src/plugins/defaults/memory/{graph → v1/graph}/narrative.ts +6 -6
- package/src/plugins/defaults/memory/{graph → v1/graph}/pattern-scan.ts +5 -5
- package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.test.ts +135 -42
- package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.ts +40 -22
- package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/serendipity.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.test.ts +1 -1
- package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.ts +1 -1
- package/src/plugins/defaults/memory/{identity-context.ts → v1/identity-context.ts} +4 -4
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/backfill.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.test.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.ts +6 -6
- package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/index-maintenance.ts +8 -8
- package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.test.ts +7 -7
- package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.ts +5 -5
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/autoinject.ts +1 -1
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/context.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.ts +2 -2
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.test.ts +3 -3
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.ts +6 -6
- package/src/plugins/defaults/memory/{pkb → v1/pkb}/types.ts +3 -5
- package/src/plugins/defaults/memory/{pkb-schedule.ts → v1/pkb-schedule.ts} +2 -2
- package/src/plugins/defaults/memory/{search/semantic.ts → v1/semantic-search.ts} +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/activation-store.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/activation.test.ts +11 -274
- package/src/plugins/defaults/memory/v2/__tests__/backfill-jobs.test.ts +9 -131
- package/src/plugins/defaults/memory/v2/__tests__/harness-compare.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/harness-oracle.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/harness-replay-input.test.ts +1 -1
- package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +14 -10
- package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +7 -5
- package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +12 -6
- package/src/plugins/defaults/memory/{memory-v2-activation-log-store.ts → v2/activation-log-store.ts} +2 -2
- package/src/plugins/defaults/memory/v2/activation-store.ts +22 -8
- package/src/plugins/defaults/memory/v2/activation.ts +30 -163
- package/src/plugins/defaults/memory/v2/backfill-jobs.ts +7 -54
- package/src/plugins/defaults/memory/{memory-v2-concept-frequency.ts → v2/concept-frequency.ts} +3 -3
- package/src/plugins/defaults/memory/v2/harness/oracle.ts +1 -1
- package/src/plugins/defaults/memory/v2/harness/replay-input.ts +2 -2
- package/src/plugins/defaults/memory/v2/harness/retriever.ts +1 -1
- package/src/plugins/defaults/memory/v2/injection.ts +36 -26
- package/src/plugins/defaults/memory/v2/migration.ts +2 -2
- package/src/plugins/defaults/memory/{rerank-local.ts → v2/rerank-local.ts} +44 -18
- package/src/plugins/defaults/memory/v2/reranker.ts +29 -11
- package/src/plugins/defaults/memory/v2/router.ts +38 -15
- package/src/plugins/defaults/memory/v3/__tests__/candidate-match.test.ts +5 -3
- package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +21 -8
- package/src/plugins/defaults/memory/v3/__tests__/edge.test.ts +1 -1
- package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +1 -1
- package/src/plugins/defaults/memory/v3/__tests__/maintain-job.test.ts +4 -1
- package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +181 -3
- package/src/plugins/defaults/memory/v3/__tests__/selection-log-store.test.ts +3 -0
- package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +14 -5
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +40 -50
- package/src/plugins/defaults/memory/v3/__tests__/tuning-profile.test.ts +1 -0
- package/src/plugins/defaults/memory/v3/candidate-match.ts +2 -2
- package/src/plugins/defaults/memory/v3/capabilities.ts +6 -4
- package/src/plugins/defaults/memory/v3/card.ts +25 -9
- package/src/plugins/defaults/memory/v3/edge.ts +52 -18
- package/src/plugins/defaults/memory/v3/gate.ts +4 -4
- package/src/plugins/defaults/memory/v3/injector.ts +10 -3
- package/src/plugins/defaults/memory/v3/maintain-job.ts +3 -3
- package/src/plugins/defaults/memory/v3/orchestrate.ts +100 -18
- package/src/plugins/defaults/memory/v3/page-content.ts +26 -10
- package/src/plugins/defaults/memory/v3/prune.ts +40 -16
- package/src/plugins/defaults/memory/v3/selection-log-store.ts +34 -12
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +9 -13
- package/src/plugins/defaults/memory/v3/span-query.test.ts +86 -0
- package/src/plugins/defaults/memory/v3/span-query.ts +71 -0
- package/src/plugins/defaults/memory/v3/tuning-profile.ts +3 -0
- package/src/plugins/defaults/memory/v3/types.ts +4 -1
- package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +2 -2
- package/src/plugins/defaults/memory/validation.ts +1 -1
- package/src/plugins/defaults/memory/worker.ts +2 -1
- package/src/plugins/defaults/platform-hosted/__tests__/reengage.test.ts +104 -12
- package/src/plugins/defaults/platform-hosted/routes/reengage.ts +104 -12
- package/src/plugins/types.ts +2 -2
- package/src/prompts/sections.ts +4 -16
- package/src/providers/__tests__/registry-native-web-search.test.ts +47 -2
- package/src/providers/anthropic/client.ts +15 -6
- package/src/providers/content-block-schema.ts +26 -0
- package/src/providers/inference/__tests__/connections-credential-normalize.test.ts +87 -0
- package/src/providers/inference/adapter-factory.ts +6 -0
- package/src/providers/inference/connections.ts +30 -14
- package/src/providers/model-catalog.ts +77 -0
- package/src/providers/openai/__tests__/chat-completions-input-audio.test.ts +260 -0
- package/src/providers/openai/chat-completions-provider.ts +65 -17
- package/src/providers/openai/input-audio.ts +76 -0
- package/src/providers/openrouter/client.ts +0 -2
- package/src/providers/platform-proxy/constants.ts +4 -0
- package/src/providers/poolside/client.ts +42 -0
- package/src/providers/registry.ts +40 -8
- package/src/providers/retry.ts +2 -0
- package/src/providers/types.ts +39 -1
- package/src/providers/vercel-ai-gateway/client.ts +0 -2
- package/src/runtime/AGENTS.md +7 -5
- package/src/runtime/__tests__/question-request-guardian-bridge.test.ts +173 -0
- package/src/runtime/__tests__/question-resolution.test.ts +111 -0
- package/src/runtime/access-request-helper.ts +7 -15
- package/src/runtime/assistant-event-hub.ts +43 -31
- package/src/runtime/assistant-event-publish-options.ts +31 -0
- package/src/runtime/assistant-event.ts +19 -30
- package/src/runtime/assistant-stream-state.ts +4 -4
- package/src/runtime/channel-approvals.ts +0 -25
- package/src/runtime/channel-readiness-service.ts +99 -40
- package/src/runtime/channel-retry-sweep.ts +38 -15
- package/src/runtime/confirmation-request-guardian-bridge.ts +4 -0
- package/src/runtime/guardian-reply-router.ts +108 -0
- package/src/runtime/http-server.ts +8 -0
- package/src/runtime/http-types.ts +2 -2
- package/src/runtime/process-role.ts +42 -0
- package/src/runtime/question-request-guardian-bridge.ts +184 -0
- package/src/runtime/question-resolution.ts +153 -0
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +6 -2
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/subagents-routes.test.ts +250 -0
- package/src/runtime/routes/__tests__/webhook-routes.test.ts +201 -0
- package/src/runtime/routes/acp-routes.ts +2 -2
- package/src/runtime/routes/bookmark-routes.ts +3 -15
- package/src/runtime/routes/canned-message-complete.ts +2 -2
- package/src/runtime/routes/consolidation-routes.ts +8 -2
- package/src/runtime/routes/conversation-list-routes.ts +3 -19
- package/src/runtime/routes/conversation-management-routes.ts +1 -5
- package/src/runtime/routes/conversation-query-routes.ts +52 -8
- package/src/runtime/routes/conversation-routes.ts +36 -22
- package/src/runtime/routes/credential-request-routes.ts +0 -1
- package/src/runtime/routes/filing-routes.ts +7 -7
- package/src/runtime/routes/global-search-routes.ts +1 -1
- package/src/runtime/routes/guardian-approval-prompt.ts +2 -2
- package/src/runtime/routes/image-generation-routes.ts +12 -9
- package/src/runtime/routes/inbound-message-handler.ts +17 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +50 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +19 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -4
- package/src/runtime/routes/inbound-stages/inbound-content-prep.test.ts +129 -0
- package/src/runtime/routes/inbound-stages/inbound-content-prep.ts +141 -9
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/lifecycle-routes.ts +199 -0
- package/src/runtime/routes/platform-routes.ts +3 -8
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +7 -7
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +5 -5
- package/src/runtime/routes/question-routes.ts +34 -87
- package/src/runtime/routes/secret-routes.ts +11 -1
- package/src/runtime/routes/settings-routes.ts +8 -18
- package/src/runtime/routes/subagents-routes.ts +35 -8
- package/src/runtime/routes/upgrade-broadcast-routes.ts +4 -5
- package/src/runtime/routes/webhook-routes.ts +89 -30
- package/src/runtime/routes/workspace-routes.test.ts +7 -4
- package/src/runtime/slack-reply-session.test.ts +12 -12
- package/src/runtime/slack-reply-session.ts +17 -17
- package/src/runtime/sync/sync-publisher.test.ts +7 -5
- package/src/runtime/tool-grant-request-helper.ts +4 -0
- package/src/schedule/schedule-store.ts +70 -0
- package/src/schedule/scheduler.ts +27 -0
- package/src/security/AGENTS.md +1 -1
- package/src/security/credential-key.ts +17 -0
- package/src/security/secret-ingress.ts +14 -105
- package/src/security/secret-patterns.ts +8 -139
- package/src/security/secret-scanner.ts +8 -3
- package/src/security/store-path-override.ts +6 -16
- package/src/sequence/store.ts +8 -0
- package/src/signals/emit-event.ts +5 -10
- package/src/signals/event-stream.ts +20 -10
- package/src/subagent/manager.ts +76 -25
- package/src/subagent/notify.ts +8 -0
- package/src/subagent/types.ts +13 -3
- package/src/telegram/__tests__/webhook-health.test.ts +442 -0
- package/src/telegram/webhook-health.ts +478 -0
- package/src/telemetry/AGENTS.md +6 -0
- package/src/telemetry/memory-corpus-size.test.ts +129 -0
- package/src/telemetry/memory-corpus-size.ts +184 -0
- package/src/telemetry/memory-tier-reporter.test.ts +67 -2
- package/src/telemetry/memory-tier-reporter.ts +30 -3
- package/src/tools/__tests__/conversation-group-tool-input-schemas.test.ts +61 -0
- package/src/tools/__tests__/document-tool-input-schemas.test.ts +103 -0
- package/src/tools/__tests__/followup-call-acp-tool-input-schemas.test.ts +125 -0
- package/src/tools/__tests__/schedule-tool-input-schemas.test.ts +83 -0
- package/src/tools/__tests__/subagent-workflow-tool-input-schemas.test.ts +116 -0
- package/src/tools/__tests__/tool-input-schemas.test.ts +192 -0
- package/src/tools/__tests__/tool-schema-drift-harness.ts +142 -0
- package/src/tools/acp/abort.ts +21 -1
- package/src/tools/acp/context.ts +5 -5
- package/src/tools/acp/spawn.test.ts +15 -5
- package/src/tools/acp/spawn.ts +26 -3
- package/src/tools/acp/status.ts +20 -1
- package/src/tools/acp/steer.test.ts +20 -0
- package/src/tools/acp/steer.ts +23 -2
- package/src/tools/apps/resolve-app-id.ts +15 -3
- package/src/tools/ask-question/ask-question-tool.test.ts +65 -0
- package/src/tools/ask-question/ask-question-tool.ts +68 -92
- package/src/tools/browser/browser-screencast.ts +6 -6
- package/src/tools/calls/call-end.ts +24 -3
- package/src/tools/calls/call-start.ts +35 -11
- package/src/tools/calls/call-status.ts +20 -1
- package/src/tools/conversation-groups/group_create.ts +63 -0
- package/src/tools/conversation-groups/group_list.ts +20 -0
- package/src/tools/conversation-groups/group_shared.ts +52 -0
- package/src/tools/conversation-groups/move_to_group.ts +106 -0
- package/src/tools/document/document-comment-tool.test.ts +49 -0
- package/src/tools/document/document-comment-tool.ts +45 -6
- package/src/tools/document/document-tool.ts +142 -24
- package/src/tools/executor.ts +27 -13
- package/src/tools/filesystem/edit.ts +62 -60
- package/src/tools/filesystem/list.ts +36 -29
- package/src/tools/filesystem/read.ts +56 -39
- package/src/tools/filesystem/write.ts +44 -38
- package/src/tools/followups/followup_create.ts +41 -12
- package/src/tools/followups/followup_list.ts +34 -6
- package/src/tools/followups/followup_resolve.ts +26 -4
- package/src/tools/host-filesystem/edit.ts +50 -60
- package/src/tools/host-filesystem/read.ts +45 -39
- package/src/tools/host-filesystem/write.ts +31 -36
- package/src/tools/host-terminal/host-shell.ts +76 -62
- package/src/tools/policy-context.ts +27 -10
- package/src/tools/schedule/create.ts +76 -33
- package/src/tools/schedule/delete.ts +21 -2
- package/src/tools/schedule/list.ts +25 -3
- package/src/tools/schedule/update.ts +105 -48
- package/src/tools/shared/filesystem/path-policy.ts +246 -40
- package/src/tools/shared/zod-tool-schema.ts +117 -0
- package/src/tools/subagent/abort.ts +12 -4
- package/src/tools/subagent/consult-deadline.ts +9 -3
- package/src/tools/subagent/message.ts +21 -5
- package/src/tools/subagent/notify-parent.ts +44 -23
- package/src/tools/subagent/read.ts +15 -4
- package/src/tools/subagent/resolve.ts +26 -4
- package/src/tools/subagent/spawn.ts +37 -13
- package/src/tools/subagent/status.ts +12 -4
- package/src/tools/system/request-permission.ts +35 -26
- package/src/tools/terminal/shell.ts +68 -55
- package/src/tools/tool-approval-handler.ts +327 -53
- package/src/tools/tool-input-schemas.ts +85 -0
- package/src/tools/tool-types.ts +7 -0
- package/src/tools/types.ts +8 -0
- package/src/tools/workflows/manage-workflows.ts +30 -2
- package/src/tools/workflows/run-workflow.test.ts +54 -2
- package/src/tools/workflows/run-workflow.ts +32 -4
- package/src/util/fs-symlinks.ts +30 -0
- package/src/util/log-redact.ts +7 -3
- package/src/util/platform.ts +15 -0
- package/src/vellum-assistant-namespace.d.ts +80 -0
- package/src/watcher/watcher-store.ts +8 -0
- package/src/workflows/leaf-runner.test.ts +104 -2
- package/src/workflows/leaf-runner.ts +31 -6
- package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +2 -2
- package/src/workspace/migrations/134-image-generation-mode-to-provider.ts +128 -0
- package/src/workspace/migrations/135-copy-substrate-tunables.ts +248 -0
- package/src/workspace/migrations/__tests__/135-copy-substrate-tunables.test.ts +446 -0
- package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +2 -2
- package/src/workspace/migrations/registry.ts +4 -0
- package/tsconfig.plugin-api.json +1 -1
- package/src/__tests__/memory-retrieval-budget.test.ts +0 -49
- package/src/__tests__/secret-patterns.test.ts +0 -27
- package/src/config/__tests__/proc-to-skills.test.ts +0 -21
- package/src/config/memory-tier.test.ts +0 -44
- package/src/daemon/message-types/acp.ts +0 -20
- package/src/daemon/message-types/apps.ts +0 -11
- package/src/daemon/message-types/background-tools.ts +0 -14
- package/src/daemon/message-types/bookmarks.ts +0 -13
- package/src/daemon/message-types/contacts.ts +0 -13
- package/src/daemon/message-types/document-comments.ts +0 -14
- package/src/daemon/message-types/documents.ts +0 -13
- package/src/daemon/message-types/home.ts +0 -15
- package/src/daemon/message-types/host-bash.ts +0 -12
- package/src/daemon/message-types/host-cu.ts +0 -10
- package/src/daemon/message-types/host-file.ts +0 -12
- package/src/daemon/message-types/host-transfer.ts +0 -12
- package/src/daemon/message-types/integrations.ts +0 -90
- package/src/daemon/message-types/memory.ts +0 -10
- package/src/daemon/message-types/schedules.ts +0 -14
- package/src/daemon/message-types/settings.ts +0 -17
- package/src/daemon/message-types/subagents.ts +0 -63
- package/src/daemon/message-types/upgrades.ts +0 -14
- package/src/daemon/message-types/workflows.ts +0 -25
- package/src/daemon/message-types/workspace.ts +0 -137
- package/src/live-voice/ack-phrases.ts +0 -58
- package/src/plugins/defaults/memory/retrieval-budget.ts +0 -29
- package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +0 -69
- package/src/plugins/defaults/memory/v3/gate-flag.ts +0 -20
- package/src/plugins/defaults/memory/v3/substrate/__tests__/memory-v2-startup.test.ts +0 -86
- package/src/plugins/defaults/memory/v3/substrate/memory-v2-startup.test.ts +0 -205
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/concept-page-frontmatter-schema.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-prompt-flag-gating-guard.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/injected-block-slugs.test.ts +0 -0
- /package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-content.ts +0 -0
|
@@ -8,6 +8,12 @@
|
|
|
8
8
|
|
|
9
9
|
import { v7 as uuidv7 } from "uuid";
|
|
10
10
|
|
|
11
|
+
import type {
|
|
12
|
+
AssistantEvent,
|
|
13
|
+
AssistantTextDeltaEvent,
|
|
14
|
+
GenerationCancelledEvent,
|
|
15
|
+
MessageCompleteEvent,
|
|
16
|
+
} from "../api/index.js";
|
|
11
17
|
import { consumeGrantForInvocation } from "../approvals/approval-primitive.js";
|
|
12
18
|
import type {
|
|
13
19
|
ChannelId,
|
|
@@ -20,7 +26,6 @@ import { ABORT_WATCHDOG_MS } from "../daemon/abort-watchdog.js";
|
|
|
20
26
|
import { CONVERSATION_BUSY_MESSAGE } from "../daemon/conversation-messaging.js";
|
|
21
27
|
import { resolveChannelCapabilities } from "../daemon/conversation-runtime-assembly.js";
|
|
22
28
|
import { getOrCreateConversation } from "../daemon/conversation-store.js";
|
|
23
|
-
import type { ServerMessage } from "../daemon/message-protocol.js";
|
|
24
29
|
import type { TrustContext } from "../daemon/trust-context-types.js";
|
|
25
30
|
import {
|
|
26
31
|
deleteMessageById,
|
|
@@ -43,6 +48,7 @@ import {
|
|
|
43
48
|
CALL_VERIFICATION_COMPLETE_MARKER,
|
|
44
49
|
ESCALATE_VERDICT_TOKEN,
|
|
45
50
|
HOLD_VERDICT_TOKEN,
|
|
51
|
+
MINIMIZE_ROOM_MARKER,
|
|
46
52
|
stripInternalSpeechMarkers,
|
|
47
53
|
} from "./voice-control-protocol.js";
|
|
48
54
|
import {
|
|
@@ -216,15 +222,8 @@ export interface VoiceToolResultEvent {
|
|
|
216
222
|
* standard channel path.
|
|
217
223
|
*/
|
|
218
224
|
export interface VoiceRunEventSink {
|
|
219
|
-
onTextDelta(
|
|
220
|
-
|
|
221
|
-
): void;
|
|
222
|
-
onMessageComplete(
|
|
223
|
-
msg: Extract<
|
|
224
|
-
ServerMessage,
|
|
225
|
-
{ type: "message_complete" } | { type: "generation_cancelled" }
|
|
226
|
-
>,
|
|
227
|
-
): void;
|
|
225
|
+
onTextDelta(msg: AssistantTextDeltaEvent): void;
|
|
226
|
+
onMessageComplete(msg: MessageCompleteEvent | GenerationCancelledEvent): void;
|
|
228
227
|
onError(message: string): void;
|
|
229
228
|
onToolUse(
|
|
230
229
|
toolName: string,
|
|
@@ -235,19 +234,17 @@ export interface VoiceRunEventSink {
|
|
|
235
234
|
}
|
|
236
235
|
|
|
237
236
|
export interface VoiceTurnCallbacks {
|
|
238
|
-
assistant_text_delta?: (
|
|
239
|
-
msg: Extract<ServerMessage, { type: "assistant_text_delta" }>,
|
|
240
|
-
) => void;
|
|
237
|
+
assistant_text_delta?: (msg: AssistantTextDeltaEvent) => void;
|
|
241
238
|
message_complete?: (
|
|
242
|
-
msg:
|
|
243
|
-
ServerMessage,
|
|
244
|
-
{ type: "message_complete" } | { type: "generation_cancelled" }
|
|
245
|
-
>,
|
|
239
|
+
msg: MessageCompleteEvent | GenerationCancelledEvent,
|
|
246
240
|
) => void;
|
|
247
241
|
persisted_user_message_id?: (messageId: string) => void;
|
|
248
242
|
persisted_assistant_message_id?: (messageId: string) => void;
|
|
249
243
|
/** Fired when the agent run starts a definitive tool use this turn. */
|
|
250
|
-
tool_use_start?: (
|
|
244
|
+
tool_use_start?: (
|
|
245
|
+
toolName: string,
|
|
246
|
+
detail?: { toolUseId?: string; input?: Record<string, unknown> },
|
|
247
|
+
) => void;
|
|
251
248
|
/** Fired when a tool invocation finishes. */
|
|
252
249
|
tool_result?: (event: VoiceToolResultEvent) => void;
|
|
253
250
|
}
|
|
@@ -314,6 +311,14 @@ export interface VoiceTurnOptions {
|
|
|
314
311
|
* Only meaningful with `routingLeg: "escalated"`.
|
|
315
312
|
*/
|
|
316
313
|
spokenEscalationBridge?: string;
|
|
314
|
+
/**
|
|
315
|
+
* Marks this turn's `content` as an internal instruction rather than user
|
|
316
|
+
* speech: it persists `hidden` so `/messages` filters it after a reload,
|
|
317
|
+
* its echo is suppressed, and prompt-as-user-speech consumers (title
|
|
318
|
+
* generation) skip it. Set by callers whose synthetic prompt text is not a
|
|
319
|
+
* fixed sentinel.
|
|
320
|
+
*/
|
|
321
|
+
hiddenSyntheticPrompt?: boolean;
|
|
317
322
|
/**
|
|
318
323
|
* Unified front-door: this leg was dispatched speculatively at a silence
|
|
319
324
|
* boundary, so its decision rule includes the hold branch (leading token
|
|
@@ -466,9 +471,9 @@ function buildVoiceCallControlPrompt(opts: {
|
|
|
466
471
|
`12. ${VOICE_NO_SETUP_FLOWS_RULE}`,
|
|
467
472
|
);
|
|
468
473
|
|
|
469
|
-
// Triage-and-escalate routing rules
|
|
470
|
-
//
|
|
471
|
-
//
|
|
474
|
+
// Triage-and-escalate routing rules. The front-door leg decides and may
|
|
475
|
+
// hand off; the escalated leg continues the answer after a holding phrase
|
|
476
|
+
// was already spoken.
|
|
472
477
|
if (opts.routingLeg === "front-door") {
|
|
473
478
|
lines.push(`13. ${frontDoorRuleWithDigest(opts.unifiedVerdict === true)}`);
|
|
474
479
|
} else if (opts.routingLeg === "escalated") {
|
|
@@ -481,9 +486,85 @@ function buildVoiceCallControlPrompt(opts: {
|
|
|
481
486
|
}
|
|
482
487
|
|
|
483
488
|
// ---------------------------------------------------------------------------
|
|
484
|
-
//
|
|
489
|
+
// Transcript hygiene
|
|
485
490
|
// ---------------------------------------------------------------------------
|
|
486
491
|
|
|
492
|
+
/** The concatenated text of a row's text blocks. */
|
|
493
|
+
function joinedTextOfBlocks(blocks: ContentBlock[]): string {
|
|
494
|
+
return blocks
|
|
495
|
+
.map((block) => (block.type === "text" ? block.text : ""))
|
|
496
|
+
.join("");
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Strip internal speech markers from every text block, dropping text blocks
|
|
501
|
+
* the strip leaves empty; non-text blocks pass through untouched. Shared by
|
|
502
|
+
* the front-door stray-token rewrite and the main-leg minimize-marker
|
|
503
|
+
* rewrite.
|
|
504
|
+
*/
|
|
505
|
+
function stripMarkersFromBlocks(blocks: ContentBlock[]): ContentBlock[] {
|
|
506
|
+
const kept: ContentBlock[] = [];
|
|
507
|
+
for (const block of blocks) {
|
|
508
|
+
if (block.type !== "text") {
|
|
509
|
+
kept.push(block);
|
|
510
|
+
continue;
|
|
511
|
+
}
|
|
512
|
+
const cleaned = stripInternalSpeechMarkers(block.text);
|
|
513
|
+
if (cleaned.trim().length > 0) {
|
|
514
|
+
kept.push({ ...block, text: cleaned });
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
return kept;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Remove the terminal MINIMIZE_ROOM_MARKER from the end of a row's text,
|
|
522
|
+
* walking text blocks from the last one backward so a marker split across
|
|
523
|
+
* block boundaries (e.g. `"Done [-"` + `"1]"`) is removed whole — the
|
|
524
|
+
* per-block strip in {@link stripMarkersFromBlocks} only sees fragments and
|
|
525
|
+
* would leave both halves in place. Callers must have established that the
|
|
526
|
+
* row's joined text ends with the marker after trimming trailing whitespace.
|
|
527
|
+
*/
|
|
528
|
+
function stripTerminalMinimizeMarker(blocks: ContentBlock[]): ContentBlock[] {
|
|
529
|
+
const result = blocks.map((block) => ({ ...block }));
|
|
530
|
+
const joined = joinedTextOfBlocks(result);
|
|
531
|
+
const cutAt = joined.trimEnd().length - MINIMIZE_ROOM_MARKER.length;
|
|
532
|
+
let blockEnd = joined.length;
|
|
533
|
+
for (let i = result.length - 1; i >= 0 && blockEnd > cutAt; i--) {
|
|
534
|
+
const block = result[i]!;
|
|
535
|
+
if (block.type !== "text") {
|
|
536
|
+
continue;
|
|
537
|
+
}
|
|
538
|
+
const blockStart = blockEnd - block.text.length;
|
|
539
|
+
block.text = block.text.slice(0, Math.max(0, cutAt - blockStart));
|
|
540
|
+
blockEnd = blockStart;
|
|
541
|
+
}
|
|
542
|
+
return result;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Trim whitespace stranded at a rewritten row's outer edges by a stripped
|
|
547
|
+
* edge marker (e.g. "Done, take a look [-1]"), leaving inter-block spacing
|
|
548
|
+
* untouched.
|
|
549
|
+
*/
|
|
550
|
+
function trimOuterTextEdges(blocks: ContentBlock[]): ContentBlock[] {
|
|
551
|
+
const result = blocks.map((block) => ({ ...block }));
|
|
552
|
+
for (const block of result) {
|
|
553
|
+
if (block.type === "text") {
|
|
554
|
+
block.text = block.text.trimStart();
|
|
555
|
+
break;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
for (let i = result.length - 1; i >= 0; i--) {
|
|
559
|
+
const block = result[i]!;
|
|
560
|
+
if (block.type === "text") {
|
|
561
|
+
block.text = block.text.trimEnd();
|
|
562
|
+
break;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
return result;
|
|
566
|
+
}
|
|
567
|
+
|
|
487
568
|
/**
|
|
488
569
|
* Reduce a front-door leg's persisted content to what was actually spoken
|
|
489
570
|
* under the verdict-first protocol.
|
|
@@ -500,9 +581,7 @@ function buildVoiceCallControlPrompt(opts: {
|
|
|
500
581
|
export function cutFrontDoorContentAtVerdict(
|
|
501
582
|
blocks: ContentBlock[],
|
|
502
583
|
): { blocks: ContentBlock[]; spokenText: string } | null {
|
|
503
|
-
const joinedText = blocks
|
|
504
|
-
.map((block) => (block.type === "text" ? block.text : ""))
|
|
505
|
-
.join("");
|
|
584
|
+
const joinedText = joinedTextOfBlocks(blocks);
|
|
506
585
|
if (joinedText.trimStart().startsWith(ESCALATE_VERDICT_TOKEN)) {
|
|
507
586
|
const spokenText = spokenBridgeText(joinedText);
|
|
508
587
|
return {
|
|
@@ -516,21 +595,8 @@ export function cutFrontDoorContentAtVerdict(
|
|
|
516
595
|
) {
|
|
517
596
|
return null;
|
|
518
597
|
}
|
|
519
|
-
const kept
|
|
520
|
-
|
|
521
|
-
if (block.type !== "text") {
|
|
522
|
-
kept.push(block);
|
|
523
|
-
continue;
|
|
524
|
-
}
|
|
525
|
-
const cleaned = stripInternalSpeechMarkers(block.text);
|
|
526
|
-
if (cleaned.trim().length > 0) {
|
|
527
|
-
kept.push({ ...block, text: cleaned });
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
const spokenText = kept
|
|
531
|
-
.map((block) => (block.type === "text" ? block.text : ""))
|
|
532
|
-
.join("")
|
|
533
|
-
.trim();
|
|
598
|
+
const kept = stripMarkersFromBlocks(blocks);
|
|
599
|
+
const spokenText = joinedTextOfBlocks(kept).trim();
|
|
534
600
|
return { blocks: kept, spokenText };
|
|
535
601
|
}
|
|
536
602
|
|
|
@@ -589,7 +655,7 @@ export async function startVoiceTurn(
|
|
|
589
655
|
},
|
|
590
656
|
onToolUse: (toolName, input, toolUseId) => {
|
|
591
657
|
log.debug({ toolName, input }, "Voice turn tool_use event");
|
|
592
|
-
opts.callbacks?.tool_use_start?.(toolName, { toolUseId });
|
|
658
|
+
opts.callbacks?.tool_use_start?.(toolName, { toolUseId, input });
|
|
593
659
|
},
|
|
594
660
|
onToolResult: (event) => {
|
|
595
661
|
opts.callbacks?.tool_result?.(event);
|
|
@@ -625,11 +691,13 @@ export async function startVoiceTurn(
|
|
|
625
691
|
? "(verification completed — transitioning into conversation)"
|
|
626
692
|
: opts.content;
|
|
627
693
|
|
|
628
|
-
// Opener / verification / escalation-continuation prompts
|
|
629
|
-
// scaffolding: they persist a row so the
|
|
630
|
-
// speech and must not render as a live
|
|
631
|
-
//
|
|
694
|
+
// Opener / verification / escalation-continuation prompts, plus any turn a
|
|
695
|
+
// caller declares hidden, are internal scaffolding: they persist a row so the
|
|
696
|
+
// model wakes, but they are not user speech and must not render as a live
|
|
697
|
+
// user bubble. Their echo is suppressed below (parity with
|
|
698
|
+
// `isEchoSuppressedUserMessage` on the text path).
|
|
632
699
|
const isSyntheticVoicePrompt =
|
|
700
|
+
opts.hiddenSyntheticPrompt === true ||
|
|
633
701
|
opts.content === CALL_OPENING_MARKER ||
|
|
634
702
|
opts.content === CALL_VERIFICATION_COMPLETE_MARKER ||
|
|
635
703
|
opts.content === ESCALATION_CONTINUATION_CONTENT;
|
|
@@ -641,8 +709,10 @@ export async function startVoiceTurn(
|
|
|
641
709
|
// `/messages` filters it out after a refetch/reload, and flag the turn as a
|
|
642
710
|
// hidden prompt so prompt-as-user-speech consumers (e.g. title generation)
|
|
643
711
|
// skip it. The escalated model still sees the row in context — `hidden` only
|
|
644
|
-
// affects client display.
|
|
712
|
+
// affects client display. A caller whose prompt text is not a fixed sentinel
|
|
713
|
+
// opts into the same treatment with `hiddenSyntheticPrompt`.
|
|
645
714
|
const isHiddenSyntheticPrompt =
|
|
715
|
+
opts.hiddenSyntheticPrompt === true ||
|
|
646
716
|
opts.content === ESCALATION_CONTINUATION_CONTENT;
|
|
647
717
|
|
|
648
718
|
// Build the call-control protocol prompt so the model knows how to emit
|
|
@@ -1034,7 +1104,7 @@ export async function startVoiceTurn(
|
|
|
1034
1104
|
// Hook into conversation to intercept confirmation_request and secret_request events.
|
|
1035
1105
|
// Voice auto-denies/auto-allows/auto-resolves these since there's no interactive UI.
|
|
1036
1106
|
let lastError: string | null = null;
|
|
1037
|
-
conversation.updateClient(async (msg:
|
|
1107
|
+
conversation.updateClient(async (msg: AssistantEvent) => {
|
|
1038
1108
|
if (msg.type === "confirmation_request") {
|
|
1039
1109
|
// Broadcast the request BEFORE resolving it: resolution synchronously
|
|
1040
1110
|
// broadcasts `interaction_resolved` (handleConfirmationResponse →
|
|
@@ -1178,6 +1248,14 @@ export async function startVoiceTurn(
|
|
|
1178
1248
|
* never the verdict token or the text streamed past the cap (issue
|
|
1179
1249
|
* #37850). A row with no spoken bridge (canned-fallback case — that
|
|
1180
1250
|
* bridge is audio-only) is deleted.
|
|
1251
|
+
* - Any leg whose row ENDS with the `[-1]` minimize marker (swallowed
|
|
1252
|
+
* before TTS on the live path) has its text blocks rewritten through
|
|
1253
|
+
* `stripInternalSpeechMarkers` so the marker never renders in the chat
|
|
1254
|
+
* transcript. This covers front-door answers too: that leg is never
|
|
1255
|
+
* taught the marker, but it can parrot one from visible conversation
|
|
1256
|
+
* history, and the parroted marker is never spoken and never minimizes
|
|
1257
|
+
* the room. Deliberately scoped to that marker: rows without it
|
|
1258
|
+
* persist byte-identical.
|
|
1181
1259
|
*
|
|
1182
1260
|
* After a rewrite, in-memory history is reloaded from the clean DB before
|
|
1183
1261
|
* the escalated leg — blocked on this turn's teardown — snapshots it, so
|
|
@@ -1198,9 +1276,6 @@ export async function startVoiceTurn(
|
|
|
1198
1276
|
}
|
|
1199
1277
|
return;
|
|
1200
1278
|
}
|
|
1201
|
-
if (!discarded && opts.routingLeg !== "front-door") {
|
|
1202
|
-
return;
|
|
1203
|
-
}
|
|
1204
1279
|
try {
|
|
1205
1280
|
let action = "none";
|
|
1206
1281
|
if (discarded) {
|
|
@@ -1208,8 +1283,13 @@ export async function startVoiceTurn(
|
|
|
1208
1283
|
action = "delete_discarded";
|
|
1209
1284
|
} else {
|
|
1210
1285
|
const row = getMessageById(reservedAssistantRowId, opts.conversationId);
|
|
1211
|
-
const cut =
|
|
1212
|
-
|
|
1286
|
+
const cut =
|
|
1287
|
+
row && opts.routingLeg === "front-door"
|
|
1288
|
+
? cutFrontDoorContentAtVerdict(row.content)
|
|
1289
|
+
: null;
|
|
1290
|
+
if (!row) {
|
|
1291
|
+
action = "row_missing";
|
|
1292
|
+
} else if (cut) {
|
|
1213
1293
|
if (cut.spokenText.length > 0) {
|
|
1214
1294
|
updateMessageContent(
|
|
1215
1295
|
reservedAssistantRowId,
|
|
@@ -1220,20 +1300,53 @@ export async function startVoiceTurn(
|
|
|
1220
1300
|
deleteMessageById(reservedAssistantRowId);
|
|
1221
1301
|
action = "delete_empty";
|
|
1222
1302
|
}
|
|
1223
|
-
} else if (
|
|
1224
|
-
|
|
1303
|
+
} else if (
|
|
1304
|
+
// Terminal position only — mirrors the live latch in
|
|
1305
|
+
// createControlMarkerHoldback: a reply whose CONTENT contains
|
|
1306
|
+
// "[-1]" mid-text never minimized the room, so its transcript
|
|
1307
|
+
// keeps that content untouched too. Front-door answer rows (no
|
|
1308
|
+
// verdict token to cut) take this branch as well.
|
|
1309
|
+
joinedTextOfBlocks(row.content)
|
|
1310
|
+
.trimEnd()
|
|
1311
|
+
.endsWith(MINIMIZE_ROOM_MARKER)
|
|
1312
|
+
) {
|
|
1313
|
+
// Terminal marker first (boundary-aware — it may span text blocks),
|
|
1314
|
+
// then the per-block strip for any interior complete markers.
|
|
1315
|
+
const cleaned = trimOuterTextEdges(
|
|
1316
|
+
stripMarkersFromBlocks(stripTerminalMinimizeMarker(row.content)),
|
|
1317
|
+
);
|
|
1318
|
+
// A marker-only reply (the model said nothing beyond "[-1]") strips
|
|
1319
|
+
// to nothing at all; keeping the row would render a blank assistant
|
|
1320
|
+
// bubble, so delete it like the front-door empty case. Any surviving
|
|
1321
|
+
// block — including non-text blocks like tool_use — keeps the row.
|
|
1322
|
+
if (cleaned.length === 0) {
|
|
1323
|
+
deleteMessageById(reservedAssistantRowId);
|
|
1324
|
+
action = "delete_empty";
|
|
1325
|
+
} else {
|
|
1326
|
+
updateMessageContent(
|
|
1327
|
+
reservedAssistantRowId,
|
|
1328
|
+
JSON.stringify(cleaned),
|
|
1329
|
+
);
|
|
1330
|
+
action = "strip_minimize_marker";
|
|
1331
|
+
}
|
|
1225
1332
|
}
|
|
1226
1333
|
}
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1334
|
+
// Main legs run the pass on every voice turn; keep the no-op case
|
|
1335
|
+
// out of the logs.
|
|
1336
|
+
const isMainLegNoOp =
|
|
1337
|
+
action === "none" && !discarded && opts.routingLeg !== "front-door";
|
|
1338
|
+
if (!isMainLegNoOp) {
|
|
1339
|
+
log.info(
|
|
1340
|
+
{
|
|
1341
|
+
turnId,
|
|
1342
|
+
messageId: reservedAssistantRowId,
|
|
1343
|
+
routingLeg: opts.routingLeg ?? null,
|
|
1344
|
+
discarded,
|
|
1345
|
+
action,
|
|
1346
|
+
},
|
|
1347
|
+
"Voice leg transcript hygiene",
|
|
1348
|
+
);
|
|
1349
|
+
}
|
|
1237
1350
|
if (action !== "none" && action !== "row_missing") {
|
|
1238
1351
|
await conversation.loadFromDb();
|
|
1239
1352
|
publishConversationMessagesChanged(opts.conversationId);
|
|
@@ -1283,7 +1396,7 @@ export async function startVoiceTurn(
|
|
|
1283
1396
|
frontDoorToolsSuppressed = true;
|
|
1284
1397
|
}
|
|
1285
1398
|
await conversation.runAgentLoop(persistedContent, messageId, {
|
|
1286
|
-
onEvent: (msg:
|
|
1399
|
+
onEvent: (msg: AssistantEvent) => {
|
|
1287
1400
|
if (msg.type === "assistant_turn_start") {
|
|
1288
1401
|
reservedAssistantRowId = msg.messageId;
|
|
1289
1402
|
} else if (msg.type === "error") {
|
|
@@ -23,8 +23,7 @@
|
|
|
23
23
|
*
|
|
24
24
|
* This module owns the routing policy in one place: the profile key, the
|
|
25
25
|
* leg-specific prompt rules, the leading-token classifier, and the bridge
|
|
26
|
-
* cap/fallback policy.
|
|
27
|
-
* LiveVoiceSession that drives the routing.
|
|
26
|
+
* cap/fallback policy. LiveVoiceSession drives the routing.
|
|
28
27
|
*/
|
|
29
28
|
|
|
30
29
|
import {
|
|
@@ -296,6 +295,6 @@ export function escalatedContinuationRule(spokenBridge?: string): string {
|
|
|
296
295
|
'Do NOT greet again, do NOT say things like "as I was saying", and do NOT repeat, paraphrase, or re-announce that holding phrase —',
|
|
297
296
|
'opening with another "Let me check", "One moment", or any restatement of what you are about to do sounds broken, because the caller just heard that.',
|
|
298
297
|
"Your first words must carry new substance: the answer itself, what you found, or a question you genuinely need answered.",
|
|
299
|
-
`Never output ${ESCALATE_VERDICT_TOKEN} or any other verdict token — you are the model that finishes the answer
|
|
298
|
+
`Never output ${ESCALATE_VERDICT_TOKEN} or any other front-door verdict token — you are the model that finishes the answer. (The [-1] room-minimize marker from your call instructions is not a verdict token and stays allowed.)`,
|
|
300
299
|
].join(" ");
|
|
301
300
|
}
|
package/src/channels/config.ts
CHANGED
|
@@ -73,6 +73,14 @@ const CHANNEL_POLICIES = {
|
|
|
73
73
|
conversationStrategy: "continue_existing_conversation",
|
|
74
74
|
},
|
|
75
75
|
},
|
|
76
|
+
discord: {
|
|
77
|
+
notification: {
|
|
78
|
+
// Discord has no outbound transport, so enabling delivery would route
|
|
79
|
+
// notifications at a callback no transport owns.
|
|
80
|
+
deliveryEnabled: false,
|
|
81
|
+
conversationStrategy: "continue_existing_conversation",
|
|
82
|
+
},
|
|
83
|
+
},
|
|
76
84
|
} as const satisfies Record<ChannelId, ChannelNotificationPolicy>;
|
|
77
85
|
|
|
78
86
|
export type ChannelPolicies = typeof CHANNEL_POLICIES;
|
package/src/channels/types.ts
CHANGED
|
@@ -150,6 +150,7 @@ export const INTERFACE_IDS = [
|
|
|
150
150
|
"email",
|
|
151
151
|
"chrome-extension",
|
|
152
152
|
"a2a",
|
|
153
|
+
"discord",
|
|
153
154
|
// Turns injected by workspace custom routes (webhook receivers, cron jobs,
|
|
154
155
|
// device/service callbacks). Non-interactive — permission prompts route
|
|
155
156
|
// through the guardian system, not an interactive client — and non-host-proxy.
|
|
@@ -30,9 +30,27 @@ function flattenConfig(
|
|
|
30
30
|
return result;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
/** Matches config paths like `services.
|
|
33
|
+
/** Matches config paths like `services.google-oauth.mode` (mode-based services). */
|
|
34
34
|
const SERVICE_MODE_PATH_RE = /^services\.[^.]+\.mode$/;
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Services configured by provider alone: their schemas strip a raw `mode`
|
|
38
|
+
* write, so the CLI rejects it with the provider-based replacement instead
|
|
39
|
+
* of printing success on a no-op.
|
|
40
|
+
*/
|
|
41
|
+
const REMOVED_MODE_PATHS: Record<string, string> = {
|
|
42
|
+
"services.web-search.mode":
|
|
43
|
+
"services.web-search.mode does not exist; web search is configured by provider alone. For managed search run `config set services.web-search.provider vellum`.",
|
|
44
|
+
"services.image-generation.mode":
|
|
45
|
+
"services.image-generation.mode does not exist; image generation is configured by provider alone. For managed image generation run `config set services.image-generation.provider vellum`.",
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/** Provider paths whose "vellum" value requires a platform connection. */
|
|
49
|
+
const VELLUM_PROVIDER_PATHS = new Set([
|
|
50
|
+
"services.web-search.provider",
|
|
51
|
+
"services.image-generation.provider",
|
|
52
|
+
]);
|
|
53
|
+
|
|
36
54
|
/**
|
|
37
55
|
* Fetch the full raw config from the assistant via IPC.
|
|
38
56
|
* On transport / connection error, prints a helpful message and exits.
|
|
@@ -69,13 +87,10 @@ export function registerConfigCommand(program: Command): void {
|
|
|
69
87
|
// Web-search has no mode field: the schema strips it, so a write
|
|
70
88
|
// here would print success while changing nothing. Reject it with
|
|
71
89
|
// the provider-based replacement instead.
|
|
72
|
-
|
|
90
|
+
const removedModePath = REMOVED_MODE_PATHS[key];
|
|
91
|
+
if (removedModePath) {
|
|
73
92
|
const { writeOutput } = await import("../output.js");
|
|
74
|
-
writeOutput(cmd, {
|
|
75
|
-
ok: false,
|
|
76
|
-
error:
|
|
77
|
-
"services.web-search.mode does not exist; web search is configured by provider alone. For managed search run `config set services.web-search.provider vellum`.",
|
|
78
|
-
});
|
|
93
|
+
writeOutput(cmd, { ok: false, error: removedModePath });
|
|
79
94
|
process.exitCode = 1;
|
|
80
95
|
return;
|
|
81
96
|
}
|
|
@@ -85,7 +100,7 @@ export function registerConfigCommand(program: Command): void {
|
|
|
85
100
|
// web search.
|
|
86
101
|
const requiresPlatform =
|
|
87
102
|
(SERVICE_MODE_PATH_RE.test(key) && parsed === "managed") ||
|
|
88
|
-
(key
|
|
103
|
+
(VELLUM_PROVIDER_PATHS.has(key) && parsed === "vellum");
|
|
89
104
|
if (requiresPlatform) {
|
|
90
105
|
const { requirePlatformConnection } =
|
|
91
106
|
await import("./oauth/shared.js");
|
|
@@ -98,21 +113,31 @@ export function registerConfigCommand(program: Command): void {
|
|
|
98
113
|
// Direct-replacement set semantics (preserves null, replaces objects).
|
|
99
114
|
// See conversation-query-routes.ts:handleSetConfig for why this is a
|
|
100
115
|
// separate route from config_patch.
|
|
101
|
-
const result = await cliIpcCall(
|
|
102
|
-
|
|
103
|
-
|
|
116
|
+
const result = await cliIpcCall<{ ok: boolean; warning?: string }>(
|
|
117
|
+
"config_set",
|
|
118
|
+
{ body: { path: key, value: parsed } },
|
|
119
|
+
);
|
|
104
120
|
if (!result.ok) {
|
|
105
121
|
exitFromIpcResult(result, cmd);
|
|
106
122
|
return;
|
|
107
123
|
}
|
|
108
124
|
log.info(`Set ${key} = ${JSON.stringify(parsed)}`);
|
|
125
|
+
// A write the daemon accepted but that another namespace overrides
|
|
126
|
+
// is reported alongside the success, so a no-op set never reads as
|
|
127
|
+
// an effective one.
|
|
128
|
+
const warning = result.result?.warning;
|
|
129
|
+
if (warning) {
|
|
130
|
+
log.warn(`Warning: ${warning}`);
|
|
131
|
+
}
|
|
109
132
|
},
|
|
110
133
|
);
|
|
111
134
|
|
|
112
135
|
subcommand(config, "get").action(
|
|
113
136
|
async (key: string, _opts: unknown, cmd: Command) => {
|
|
114
137
|
const raw = await fetchRawConfig(cmd);
|
|
115
|
-
if (!raw)
|
|
138
|
+
if (!raw) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
116
141
|
const value = getNestedValue(raw, key);
|
|
117
142
|
if (value === undefined) {
|
|
118
143
|
log.info(`(not set)`);
|
|
@@ -123,6 +148,15 @@ export function registerConfigCommand(program: Command): void {
|
|
|
123
148
|
: String(value),
|
|
124
149
|
);
|
|
125
150
|
}
|
|
151
|
+
// A `memory.v2` substrate tunable whose `memory.substrate` twin is
|
|
152
|
+
// set has a second reader — print which key the runtime consults so
|
|
153
|
+
// the value above cannot be mistaken for the effective one.
|
|
154
|
+
const { describeShadowedConfigGet, findSubstrateShadowing } =
|
|
155
|
+
await import("../../config/substrate-twin-shadowing.js");
|
|
156
|
+
const shadowing = findSubstrateShadowing(raw, key);
|
|
157
|
+
if (shadowing) {
|
|
158
|
+
log.warn(describeShadowedConfigGet(shadowing, key));
|
|
159
|
+
}
|
|
126
160
|
},
|
|
127
161
|
);
|
|
128
162
|
|
|
@@ -143,7 +177,9 @@ export function registerConfigCommand(program: Command): void {
|
|
|
143
177
|
subcommand(config, "list").action(
|
|
144
178
|
async (opts: { search?: string }, cmd: Command) => {
|
|
145
179
|
const raw = await fetchRawConfig(cmd);
|
|
146
|
-
if (!raw)
|
|
180
|
+
if (!raw) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
147
183
|
if (Object.keys(raw).length === 0) {
|
|
148
184
|
log.info("No configuration set");
|
|
149
185
|
return;
|
|
@@ -15,7 +15,8 @@ export const memoryHelp: CliCommandHelp = {
|
|
|
15
15
|
"Manage memory items and maintain the assistant memory subsystem",
|
|
16
16
|
helpText: `
|
|
17
17
|
The 'nodes' subgroup provides content-based list, delete, and update over
|
|
18
|
-
memory
|
|
18
|
+
memory graph nodes — address facts by text, not UUID (requires concept-page
|
|
19
|
+
memory: memory.v3.live or memory.v2.enabled).
|
|
19
20
|
|
|
20
21
|
The 'items' subgroup exposes full CRUD over individual memory items
|
|
21
22
|
(remembered facts) — list, get, create, update, delete.
|
|
@@ -46,7 +47,8 @@ memory v2 subsystem. Unlike 'memory items', which addresses nodes by UUID, these
|
|
|
46
47
|
commands address nodes by content text — matching the way an operator refers to
|
|
47
48
|
a remembered fact without first looking up its ID.
|
|
48
49
|
|
|
49
|
-
All subcommands require memory
|
|
50
|
+
All subcommands require concept-page memory (memory.v3.live or
|
|
51
|
+
memory.v2.enabled) and the assistant to be running.
|
|
50
52
|
|
|
51
53
|
Examples:
|
|
52
54
|
$ assistant memory nodes stats
|
|
@@ -135,6 +135,11 @@ function renderOutcome(outcome: MemoryRetrospectiveOutcome): void {
|
|
|
135
135
|
case "no_new_messages":
|
|
136
136
|
log.info("No new messages to review since the last retrospective.");
|
|
137
137
|
break;
|
|
138
|
+
case "source_dormant":
|
|
139
|
+
log.info(
|
|
140
|
+
"Source conversation is dormant beyond the sweep lookback; skipping.",
|
|
141
|
+
);
|
|
142
|
+
break;
|
|
138
143
|
case "source_processing":
|
|
139
144
|
log.info(
|
|
140
145
|
"Source conversation is mid-turn; skipping (will retry next trigger).",
|
|
@@ -13,8 +13,9 @@ Resolves a stable callback URL that external services (Telegram, Twilio,
|
|
|
13
13
|
email providers, OAuth) should use to reach this assistant.
|
|
14
14
|
|
|
15
15
|
On platform-managed assistants, this registers a callback route with the
|
|
16
|
-
platform gateway.
|
|
17
|
-
ingress
|
|
16
|
+
platform gateway. Otherwise it uses the configured ingress.publicBaseUrl,
|
|
17
|
+
falling back to the platform gateway when no ingress is configured and the
|
|
18
|
+
assistant is connected to the platform.
|
|
18
19
|
|
|
19
20
|
The webhook path is derived from the type: underscores become path
|
|
20
21
|
separators, prefixed with webhooks/.
|
|
@@ -49,8 +50,12 @@ Examples:
|
|
|
49
50
|
helpText: `
|
|
50
51
|
Resolves a callback URL for the given webhook type. On platform-managed
|
|
51
52
|
assistants (IS_PLATFORM=true), registers a callback route with the platform
|
|
52
|
-
gateway and returns the stable external URL.
|
|
53
|
-
|
|
53
|
+
gateway and returns the stable external URL. Otherwise it reads
|
|
54
|
+
ingress.publicBaseUrl from config and appends the webhook path. That URL is
|
|
55
|
+
either your own tunnel or the Velay tunnel URL the gateway publishes. If no
|
|
56
|
+
ingress is configured and the assistant is connected to the platform
|
|
57
|
+
(via 'assistant platform connect'), it registers a callback route with the
|
|
58
|
+
platform gateway instead of failing.
|
|
54
59
|
|
|
55
60
|
Arguments:
|
|
56
61
|
type The webhook type to register. The path is derived automatically:
|
|
@@ -474,6 +474,18 @@
|
|
|
474
474
|
"homepage": "https://github.com/vellum-ai/battleship",
|
|
475
475
|
"license": "MIT",
|
|
476
476
|
"icon": "⚓"
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
"name": "octolens",
|
|
480
|
+
"source": {
|
|
481
|
+
"source": "github",
|
|
482
|
+
"repo": "vellum-ai/octolens",
|
|
483
|
+
"ref": "d9117f5c6b97b3bff75dec1a04bedc32571c6538"
|
|
484
|
+
},
|
|
485
|
+
"description": "Social listening plugin for Octolens. Monitor brand mentions, competitor activity, and industry conversations across 13+ platforms. Query mentions, run analytics, manage keywords and feeds via REST API tools, or connect the Octolens MCP server for natural-language workflows.",
|
|
486
|
+
"category": "growth",
|
|
487
|
+
"homepage": "https://github.com/vellum-ai/octolens",
|
|
488
|
+
"license": "MIT"
|
|
477
489
|
}
|
|
478
490
|
]
|
|
479
491
|
}
|