@vellumai/assistant 0.11.9 → 0.11.10-dev.202609091114.7b6342c
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 +2 -2
- package/Dockerfile +6 -12
- package/docs/architecture/memory.md +17 -9
- package/docs/guardian-request-flow.md +7 -4
- package/docs/runbook-trusted-contacts.md +13 -2
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +3 -1
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/plan-credit.test.ts +51 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +2 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/desktop-presence.ts +11 -0
- 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/plan-credit.ts +66 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +7 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +3 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/plan-credit.test.ts +51 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +2 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/desktop-presence.ts +11 -0
- 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/plan-credit.ts +66 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +7 -0
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +72 -0
- package/node_modules/@vellumai/service-contracts/package.json +3 -1
- package/node_modules/@vellumai/service-contracts/src/__tests__/plan-credit.test.ts +51 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +2 -0
- package/node_modules/@vellumai/service-contracts/src/desktop-presence.ts +11 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/plan-credit.ts +66 -0
- package/node_modules/@vellumai/service-contracts/src/secret-detection.ts +7 -0
- package/openapi.yaml +729 -63
- package/package.json +1 -1
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +19 -21
- package/src/__tests__/assistant-event-hub-machine-name.test.ts +40 -0
- package/src/__tests__/assistant-event-hub.test.ts +45 -0
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +0 -1
- package/src/__tests__/compactor-assistant-tail-preview.test.ts +111 -0
- package/src/__tests__/compactor-tail-resolution.test.ts +116 -0
- package/src/__tests__/computer-use-native-history.test.ts +30 -0
- package/src/__tests__/computer-use-window-schema.test.ts +24 -0
- package/src/__tests__/config-get-vision-flag.test.ts +36 -0
- package/src/__tests__/config-loader-validation-reset-notice.test.ts +47 -15
- package/src/__tests__/context-search-conversations-source.test.ts +27 -5
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +189 -195
- package/src/__tests__/conversation-agent-loop.test.ts +690 -50
- package/src/__tests__/conversation-fork-crud.test.ts +132 -45
- package/src/__tests__/conversation-fork-retrospective.test.ts +9 -7
- package/src/__tests__/conversation-lifecycle.test.ts +684 -10
- package/src/__tests__/conversation-pairing.test.ts +10 -9
- package/src/__tests__/conversation-runtime-assembly.test.ts +288 -1
- package/src/__tests__/conversation-surfaces-history-restored-completion.test.ts +21 -4
- package/src/__tests__/conversation-surfaces-point-at-budget.test.ts +150 -0
- package/src/__tests__/conversation-surfaces-point-at-capability.test.ts +161 -0
- package/src/__tests__/copy-composer-tc-templates.test.ts +2 -2
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/delivered-post-record.test.ts +107 -0
- package/src/__tests__/guardian-action-service-scope.test.ts +53 -0
- package/src/__tests__/guardian-question-mode.test.ts +88 -138
- package/src/__tests__/headless-browser-mode.test.ts +63 -13
- package/src/__tests__/heartbeat-disk-pressure.test.ts +2 -0
- package/src/__tests__/heartbeat-service.test.ts +118 -27
- package/src/__tests__/host-cu-proxy.test.ts +159 -1
- package/src/__tests__/host-proxy-interface.test.ts +15 -0
- package/src/__tests__/host-proxy-preactivation.test.ts +61 -0
- package/src/__tests__/injector-chain.test.ts +3 -3
- package/src/__tests__/injector-registry-order-guard.test.ts +1 -1
- package/src/__tests__/injector-v3-suppression.test.ts +587 -45
- package/src/__tests__/llm-schema.test.ts +70 -2
- package/src/__tests__/logger.test.ts +33 -32
- package/src/__tests__/mcp-config-secret-boundary.test.ts +2 -0
- package/src/__tests__/memory-config-file-parity.test.ts +18 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +53 -3
- package/src/__tests__/messages-read-boundary-guard.test.ts +0 -1
- package/src/__tests__/messaging-send-tool.test.ts +251 -128
- package/src/__tests__/messaging-shared.test.ts +19 -0
- package/src/__tests__/notification-decision-fallback.test.ts +98 -76
- package/src/__tests__/notification-decision-strategy.test.ts +10 -38
- package/src/__tests__/notification-events-source-context-probe.test.ts +211 -0
- package/src/__tests__/openai-responses-prompt-cache.test.ts +7 -2
- package/src/__tests__/openai-responses-provider.test.ts +42 -0
- package/src/__tests__/outlook-messaging-provider.test.ts +9 -0
- package/src/__tests__/platform-callback-registration.test.ts +162 -3
- package/src/__tests__/plugin-api-webhook-url.test.ts +66 -4
- package/src/__tests__/plugin-import-boundary-guard.test.ts +1 -0
- package/src/__tests__/pricing.test.ts +29 -0
- package/src/__tests__/prompt-cache-cross-turn-stability.test.ts +63 -3
- package/src/__tests__/scheduler-result-notification.test.ts +209 -0
- package/src/__tests__/strip-memory-injections.test.ts +75 -27
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +4 -13
- package/src/acp/auto-install.test.ts +35 -1
- package/src/acp/resolve-agent.test.ts +3 -3
- package/src/agent/loop.ts +116 -45
- package/src/api/constants/personality-sliders.test.ts +21 -0
- package/src/api/constants/personality-sliders.ts +64 -0
- package/src/api/events/contact-record-request.ts +16 -4
- package/src/api/events/contact-request.ts +10 -1
- package/src/api/index.ts +12 -0
- package/src/api/responses/memory-v3-selection-log.ts +64 -13
- package/src/api/surfaces.ts +6 -5
- package/src/background-wake/next-wake.test.ts +13 -0
- package/src/background-wake/next-wake.ts +4 -2
- package/src/calls/__tests__/voice-session-bridge.test.ts +166 -0
- package/src/calls/__tests__/voice-turn-sight-hold.test.ts +301 -0
- package/src/calls/voice-session-bridge.ts +162 -1
- package/src/calls/voice-triage-escalate.ts +1 -1
- package/src/channels/types.ts +14 -0
- package/src/cli/__tests__/catalog-search-help.test.ts +1 -0
- package/src/cli/__tests__/contacts-address-prompt-cli.test.ts +701 -0
- package/src/cli/__tests__/contacts-record-prompt-cli.test.ts +276 -15
- package/src/cli/__tests__/roadmap-cli.test.ts +313 -0
- package/src/cli/__tests__/run-assistant-command.ts +59 -20
- package/src/cli/commands/__tests__/conversations-slack.test.ts +12 -0
- package/src/cli/commands/__tests__/plugins-search.test.ts +81 -0
- package/src/cli/commands/config.help.ts +3 -1
- package/src/cli/commands/contacts.help.ts +179 -12
- package/src/cli/commands/contacts.ts +442 -47
- package/src/cli/commands/memory/worker.ts +1 -1
- package/src/cli/commands/platform/__tests__/credits-format.test.ts +152 -0
- package/src/cli/commands/platform/__tests__/credits.test.ts +20 -0
- package/src/cli/commands/platform/credits-format.ts +108 -0
- package/src/cli/commands/platform/index.help.ts +33 -11
- package/src/cli/commands/platform/index.ts +7 -18
- package/src/cli/commands/plugins.help.ts +4 -1
- package/src/cli/commands/plugins.ts +2 -1
- package/src/cli/commands/roadmap.help.ts +171 -0
- package/src/cli/commands/roadmap.ts +358 -0
- package/src/cli/index.help.ts +2 -0
- package/src/cli/lib/__tests__/cli-output.test.ts +5 -0
- package/src/cli/lib/cli-output.ts +6 -6
- package/src/cli/program.ts +2 -0
- package/src/config/__tests__/webhook-routing.test.ts +42 -0
- package/src/config/acp-defaults.test.ts +3 -3
- package/src/config/acp-defaults.ts +5 -5
- package/src/config/bundled-skills/acp/SKILL.md +8 -11
- package/src/config/bundled-skills/computer-use/SKILL.md +21 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +6 -0
- package/src/config/bundled-skills/contacts/SKILL.md +61 -11
- package/src/config/bundled-skills/messaging/SKILL.md +2 -0
- package/src/config/bundled-skills/messaging/TOOLS.json +4 -4
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +160 -36
- package/src/config/bundled-skills/messaging/tools/shared.ts +6 -0
- package/src/config/bundled-skills/schedule/SKILL.md +10 -2
- package/src/config/bundled-skills/screen-annotation/SKILL.md +80 -0
- package/src/config/bundled-skills/screen-annotation/TOOLS.json +73 -0
- package/src/config/bundled-skills/screen-annotation/tools/screen-annotation.test.ts +74 -0
- package/src/config/bundled-skills/screen-annotation/tools/screen-clear-marks.ts +33 -0
- package/src/config/bundled-skills/screen-annotation/tools/screen-point-at.ts +25 -0
- package/src/config/env-registry.ts +2 -0
- package/src/config/feature-flag-registry.json +39 -7
- package/src/config/input-modalities.test.ts +71 -0
- package/src/config/input-modalities.ts +95 -0
- package/src/config/loader.ts +2 -0
- package/src/config/schemas/__tests__/memory-v3.test.ts +58 -15
- package/src/config/schemas/heartbeat.ts +3 -3
- package/src/config/schemas/llm.ts +47 -10
- package/src/config/schemas/memory-storage.test.ts +39 -0
- package/src/config/schemas/memory-storage.ts +21 -0
- package/src/config/schemas/memory-v3.ts +73 -46
- package/src/config/schemas/services.ts +18 -0
- package/src/config/webhook-routing.ts +12 -2
- package/src/context/compactor.ts +12 -13
- package/src/context/strip-injections.ts +29 -25
- package/src/context/token-estimator.ts +2 -2
- package/src/daemon/__tests__/embedding-reconcile.test.ts +77 -0
- package/src/daemon/__tests__/lifecycle-embedding-reconcile.test.ts +3 -0
- package/src/daemon/__tests__/turn-actor.test.ts +68 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +152 -22
- package/src/daemon/conversation-agent-loop.ts +19 -3
- package/src/daemon/conversation-messaging.ts +3 -2
- package/src/daemon/conversation-runtime-assembly.ts +191 -69
- package/src/daemon/conversation-surfaces.ts +32 -62
- package/src/daemon/conversation.ts +153 -46
- package/src/daemon/embedding-reconcile.ts +64 -1
- package/src/daemon/handlers/config-embeddings.ts +31 -0
- package/src/daemon/host-cu-proxy.ts +66 -50
- package/src/daemon/host-cu-target.ts +139 -0
- package/src/daemon/host-proxy-preactivation.ts +29 -1
- package/src/daemon/mcp-reload-service.ts +6 -0
- package/src/daemon/providers-setup.ts +5 -26
- package/src/daemon/trust-context.ts +1 -1
- package/src/daemon/turn-actor.ts +46 -0
- package/src/heartbeat/heartbeat-service.ts +72 -13
- package/src/inbound/platform-callback-registration.ts +77 -11
- package/src/inbound/pod-webhook-claim.ts +35 -0
- package/src/inbound/velay-webhooks-gate.ts +20 -0
- package/src/ipc/gateway-client.ts +91 -0
- package/src/live-voice/__tests__/live-voice-photo.test.ts +174 -0
- package/src/live-voice/__tests__/live-voice-session-guardian.test.ts +127 -0
- package/src/live-voice/__tests__/live-voice-session-telemetry.test.ts +42 -2
- package/src/live-voice/__tests__/live-voice-sight-frame.test.ts +81 -0
- package/src/live-voice/__tests__/protocol.test.ts +67 -0
- package/src/live-voice/live-voice-connection.ts +14 -1
- package/src/live-voice/live-voice-photo.ts +109 -4
- package/src/live-voice/live-voice-session-manager.ts +10 -1
- package/src/live-voice/live-voice-session.ts +196 -31
- package/src/live-voice/protocol.ts +134 -1
- package/src/mcp/__tests__/reload-signal-emission.test.ts +54 -0
- package/src/mcp/__tests__/reload-signal.test.ts +57 -0
- package/src/mcp/__tests__/startup.test.ts +150 -0
- package/src/mcp/reload-signal.ts +50 -0
- package/src/mcp/startup.ts +101 -0
- package/src/messaging/providers/outlook/adapter.ts +2 -13
- package/src/messaging/providers/outlook/client.ts +13 -1
- package/src/messaging/providers/outlook/types.ts +3 -0
- package/src/messaging/providers/telegram-bot/adapter.ts +9 -2
- package/src/messaging/providers/telegram-bot/client.ts +8 -2
- package/src/messaging/providers/whatsapp/adapter.ts +9 -2
- package/src/messaging/providers/whatsapp/client.ts +8 -2
- package/src/notifications/AGENTS.md +5 -0
- package/src/notifications/README.md +21 -7
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +3 -10
- package/src/notifications/__tests__/background-failure-signal.test.ts +96 -0
- package/src/notifications/__tests__/broadcaster.test.ts +171 -7
- package/src/notifications/__tests__/decision-engine.test.ts +79 -6
- package/src/notifications/__tests__/edit-notification.test.ts +59 -0
- package/src/notifications/__tests__/resolve-visible-in-source.test.ts +96 -0
- package/src/notifications/__tests__/schedule-result-producer.test.ts +397 -0
- package/src/notifications/access-request-copy.ts +5 -5
- package/src/notifications/approval-card-data.ts +29 -13
- package/src/notifications/assistant-reply-producer.ts +0 -4
- package/src/notifications/background-failure-signal.ts +13 -1
- package/src/notifications/broadcaster.ts +65 -2
- package/src/notifications/conversation-pairing.ts +263 -155
- package/src/notifications/copy-composer.ts +38 -22
- package/src/notifications/decision-engine.ts +89 -61
- package/src/notifications/delivered-post-record.ts +81 -0
- package/src/notifications/deliveries-store.ts +8 -1
- package/src/notifications/edit-notification.ts +16 -0
- package/src/notifications/events-store.ts +68 -2
- package/src/notifications/guardian-question-mode.ts +24 -232
- package/src/notifications/home-feed-side-effect.ts +1 -0
- package/src/notifications/notification-utils.ts +13 -5
- package/src/notifications/resolve-visible-in-source.ts +56 -0
- package/src/notifications/schedule-result-producer.ts +275 -0
- package/src/notifications/signal.ts +5 -0
- package/src/oauth/__tests__/seed-providers-managed.test.ts +82 -0
- package/src/oauth/seed-providers.ts +201 -3
- package/src/onboarding/onboarding-events-store.ts +14 -8
- package/src/persistence/conversation-crud.ts +68 -19
- package/src/persistence/embeddings/embedding-backend.test.ts +162 -0
- package/src/persistence/embeddings/embedding-backend.ts +148 -11
- package/src/persistence/embeddings/embedding-gemini.test.ts +328 -9
- package/src/persistence/embeddings/embedding-gemini.ts +211 -27
- package/src/persistence/embeddings/embedding-openai.test.ts +113 -0
- package/src/persistence/embeddings/embedding-openai.ts +55 -4
- package/src/persistence/embeddings/embedding-types.test.ts +24 -0
- package/src/persistence/embeddings/embedding-types.ts +25 -1
- package/src/persistence/job-utils.ts +6 -2
- package/src/persistence/message-metadata.ts +20 -0
- package/src/persistence/migrations/283-memory-v3-selections-message-id-and-sections.ts +2 -1
- package/src/persistence/migrations/376-notification-deliveries-canonical-message-id.ts +37 -0
- package/src/persistence/schema/memory-injection.ts +31 -9
- package/src/persistence/schema/notifications.ts +8 -0
- package/src/persistence/steps.ts +2 -0
- package/src/plugin-api/index.ts +2 -1
- package/src/plugin-api/vision-support.test.ts +81 -0
- package/src/plugin-api/vision-support.ts +57 -10
- package/src/plugin-api/webhook-url.ts +18 -4
- package/src/plugins/AGENTS.md +1 -1
- package/src/plugins/defaults/channel/injectors.ts +3 -1
- package/src/plugins/defaults/injector-order.ts +2 -2
- package/src/plugins/defaults/memory/AGENTS.md +263 -30
- package/src/plugins/defaults/memory/__tests__/conversation-memory-orphan-sweep.test.ts +4 -0
- package/src/plugins/defaults/memory/__tests__/conversation-memory-purge.test.ts +6 -0
- package/src/plugins/defaults/memory/__tests__/db-memory-attach.test.ts +9 -3
- package/src/plugins/defaults/memory/__tests__/memory-log-stores-degraded.test.ts +3 -7
- package/src/plugins/defaults/memory/__tests__/relocated-memory-test-rows.ts +18 -0
- package/src/plugins/defaults/memory/context-search/sources/conversations.ts +16 -2
- package/src/plugins/defaults/memory/conversation-memory-purge.ts +2 -0
- package/src/plugins/defaults/memory/fork-conversation-memory.ts +13 -13
- package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +19 -12
- package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +17 -15
- package/src/plugins/defaults/memory/graph-topology/build-memory-graph.ts +1 -1
- package/src/plugins/defaults/memory/hooks/__tests__/post-compact.test.ts +121 -0
- package/src/plugins/defaults/memory/hooks/init.ts +10 -0
- package/src/plugins/defaults/memory/hooks/injection-metadata.ts +100 -0
- package/src/plugins/defaults/memory/hooks/post-compact.ts +19 -7
- package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +11 -83
- package/src/plugins/defaults/memory/injectors.ts +4 -4
- package/src/plugins/defaults/memory/job-handlers.ts +4 -1
- package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +1 -0
- package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +11 -3
- package/src/plugins/defaults/memory/memory-db.ts +4 -0
- package/src/plugins/defaults/memory/memory-marker.ts +28 -17
- package/src/plugins/defaults/memory/src/__tests__/memory-v2-simulate-route.test.ts +0 -1
- package/src/plugins/defaults/memory/src/__tests__/memory-worker-routes.test.ts +20 -0
- package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +0 -1
- package/src/plugins/defaults/memory/src/memory-worker-routes.ts +3 -1
- package/src/plugins/defaults/memory/substrate/__tests__/cli-command-store.test.ts +1 -1
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-job.test.ts +66 -0
- package/src/plugins/defaults/memory/substrate/__tests__/injected-block-slugs.test.ts +345 -0
- package/src/plugins/defaults/memory/substrate/__tests__/page-index.test.ts +0 -1
- package/src/plugins/defaults/memory/substrate/__tests__/prompts-consolidation.test.ts +170 -1
- package/src/plugins/defaults/memory/substrate/__tests__/reembed-job.test.ts +1 -0
- package/src/plugins/defaults/memory/substrate/capability-slugs.ts +53 -0
- package/src/plugins/defaults/memory/substrate/cli-command-store.ts +4 -18
- package/src/plugins/defaults/memory/substrate/consolidation-job.ts +40 -1
- package/src/plugins/defaults/memory/substrate/ingest.ts +11 -9
- package/src/plugins/defaults/memory/substrate/injected-block-slugs.ts +426 -42
- package/src/plugins/defaults/memory/substrate/page-index.ts +5 -4
- package/src/plugins/defaults/memory/substrate/prompts/consolidation.ts +127 -14
- package/src/plugins/defaults/memory/substrate/skill-store.ts +1 -18
- package/src/plugins/defaults/memory/v2/__tests__/backfill-jobs.test.ts +1 -0
- package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +2 -8
- package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +0 -1
- package/src/plugins/defaults/memory/v2/injection.ts +4 -4
- package/src/plugins/defaults/memory/v3/__tests__/capabilities.test.ts +16 -0
- package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +1004 -319
- package/src/plugins/defaults/memory/v3/__tests__/dense.test.ts +227 -4
- package/src/plugins/defaults/memory/v3/__tests__/injection.test.ts +836 -263
- package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +65 -38
- package/src/plugins/defaults/memory/v3/__tests__/maintain-job.test.ts +354 -3
- package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +688 -104
- package/src/plugins/defaults/memory/v3/__tests__/overlong-sections.test.ts +109 -0
- package/src/plugins/defaults/memory/v3/__tests__/page-content.test.ts +144 -0
- package/src/plugins/defaults/memory/v3/__tests__/plugin-schema.test.ts +534 -0
- package/src/plugins/defaults/memory/v3/__tests__/pool-log-store.test.ts +449 -0
- package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +265 -27
- package/src/plugins/defaults/memory/v3/__tests__/render-injection.test.ts +34 -117
- package/src/plugins/defaults/memory/v3/__tests__/section-dense-store.test.ts +491 -4
- package/src/plugins/defaults/memory/v3/__tests__/section-needle.test.ts +124 -1
- package/src/plugins/defaults/memory/v3/__tests__/sections.test.ts +264 -4
- package/src/plugins/defaults/memory/v3/__tests__/selection-log-store.test.ts +560 -22
- package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +40 -33
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +718 -63
- package/src/plugins/defaults/memory/v3/__tests__/types.test.ts +83 -2
- package/src/plugins/defaults/memory/v3/candidate-match.ts +1 -1
- package/src/plugins/defaults/memory/v3/capabilities.ts +90 -14
- package/src/plugins/defaults/memory/v3/card.test.ts +15 -16
- package/src/plugins/defaults/memory/v3/card.ts +16 -15
- package/src/plugins/defaults/memory/v3/dense.ts +10 -0
- package/src/plugins/defaults/memory/v3/ever-injected-store.test.ts +643 -140
- package/src/plugins/defaults/memory/v3/ever-injected-store.ts +462 -212
- package/src/plugins/defaults/memory/v3/hot-set.test.ts +2 -2
- package/src/plugins/defaults/memory/v3/injector.ts +366 -278
- package/src/plugins/defaults/memory/v3/learned-edges.test.ts +2 -2
- package/src/plugins/defaults/memory/v3/maintain-job.ts +299 -73
- package/src/plugins/defaults/memory/v3/orchestrate.ts +327 -214
- package/src/plugins/defaults/memory/v3/overlong-sections.ts +83 -0
- package/src/plugins/defaults/memory/v3/page-content.ts +72 -92
- package/src/plugins/defaults/memory/v3/plugin-schema.ts +346 -0
- package/src/plugins/defaults/memory/v3/pool-log-store.ts +291 -0
- package/src/plugins/defaults/memory/v3/pool-select.test.ts +2 -2
- package/src/plugins/defaults/memory/v3/pool-select.ts +160 -60
- package/src/plugins/defaults/memory/v3/prune.test.ts +1042 -329
- package/src/plugins/defaults/memory/v3/prune.ts +433 -270
- package/src/plugins/defaults/memory/v3/rare-term-lane.test.ts +269 -0
- package/src/plugins/defaults/memory/v3/rare-term-lane.ts +141 -0
- package/src/plugins/defaults/memory/v3/render-injection.ts +43 -82
- package/src/plugins/defaults/memory/v3/section-dense-store.ts +316 -28
- package/src/plugins/defaults/memory/v3/section-needle.ts +145 -11
- package/src/plugins/defaults/memory/v3/sections.ts +103 -16
- package/src/plugins/defaults/memory/v3/selection-log-store.ts +243 -78
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +189 -68
- package/src/plugins/defaults/memory/v3/tuning-profile.ts +6 -0
- package/src/plugins/defaults/memory/v3/types.ts +169 -23
- package/src/plugins/defaults/memory/v3-eval/__tests__/eval-packets.test.ts +21 -4
- package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +77 -26
- package/src/plugins/types.ts +14 -0
- package/src/providers/__tests__/connection-model-compat.test.ts +1 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +4 -0
- package/src/providers/__tests__/xml-tool-call-salvage.test.ts +172 -0
- package/src/providers/inline-audio-support.test.ts +34 -0
- package/src/providers/inline-audio-support.ts +27 -0
- package/src/providers/model-catalog.ts +102 -0
- package/src/providers/openai/__tests__/chat-completions-extra-body.test.ts +51 -0
- package/src/providers/openai/__tests__/chat-completions-provider-xml-salvage.test.ts +291 -0
- package/src/providers/openai/chat-completions-provider.ts +114 -14
- package/src/providers/openai/codex-models.ts +1 -0
- package/src/providers/openai/responses-provider.ts +65 -15
- package/src/providers/opencode/client.test.ts +24 -0
- package/src/providers/opencode/client.ts +6 -1
- package/src/providers/provider-secret-catalog.ts +11 -1
- package/src/providers/retry.ts +6 -0
- package/src/providers/vellum/client.ts +14 -1
- package/src/providers/vellum/personality-directions.test.ts +163 -0
- package/src/providers/vellum/personality-directions.ts +120 -0
- package/src/providers/xml-tool-call-salvage.ts +212 -0
- package/src/runtime/AGENTS.md +7 -2
- package/src/runtime/__tests__/background-job-runner.test.ts +115 -0
- package/src/runtime/__tests__/guardian-form-registry.test.ts +0 -32
- package/src/runtime/__tests__/host-observe.test.ts +44 -0
- package/src/runtime/assistant-event-hub.ts +14 -9
- package/src/runtime/auth/__tests__/guard-tests.test.ts +1 -4
- package/src/runtime/auth/__tests__/route-policy.test.ts +65 -0
- package/src/runtime/auth/same-actor.ts +4 -3
- package/src/runtime/background-job-runner.ts +10 -0
- package/src/runtime/channel-reply-delivery.ts +1 -162
- package/src/runtime/guardian-action-service.ts +20 -1
- package/src/runtime/host-observe.ts +56 -6
- package/src/runtime/http-server.ts +35 -0
- package/src/runtime/outbound-post-reconciliation.ts +183 -0
- package/src/runtime/routes/__tests__/contact-address-prompt-route.test.ts +231 -0
- package/src/runtime/routes/__tests__/contact-record-prompt-route.test.ts +59 -3
- package/src/runtime/routes/__tests__/guardian-form-routes.test.ts +85 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +24 -0
- package/src/runtime/routes/__tests__/platform-credits-routes.test.ts +239 -0
- package/src/runtime/routes/__tests__/roadmap-routes.test.ts +469 -0
- package/src/runtime/routes/__tests__/watch-routes.test.ts +70 -1
- package/src/runtime/routes/__tests__/webhook-routes.test.ts +83 -0
- package/src/runtime/routes/contact-prompt-routes.ts +177 -28
- package/src/runtime/routes/conversation-query-routes.ts +53 -11
- package/src/runtime/routes/events-routes.ts +13 -3
- package/src/runtime/routes/guardian-action-routes.ts +7 -0
- package/src/runtime/routes/guardian-form-routes.ts +6 -4
- package/src/runtime/routes/heartbeat-routes.ts +41 -53
- package/src/runtime/routes/index.ts +2 -2
- package/src/runtime/routes/integrations/a2a.ts +12 -3
- package/src/runtime/routes/integrations/vercel.ts +13 -3
- package/src/runtime/routes/platform-routes.ts +175 -23
- package/src/runtime/routes/roadmap-routes.ts +744 -0
- package/src/runtime/routes/watch-routes.ts +50 -0
- package/src/runtime/routes/webhook-routes.ts +24 -2
- package/src/runtime/web-presence.ts +13 -9
- package/src/schedule/__tests__/schedule-timezone.test.ts +21 -3
- package/src/schedule/__tests__/worker-mcp-tools.test.ts +88 -0
- package/src/schedule/schedule-timezone.ts +25 -0
- package/src/schedule/scheduler.ts +19 -0
- package/src/schedule/worker.ts +119 -2
- package/src/telemetry/__tests__/live-voice-funnel.test.ts +32 -0
- package/src/telemetry/live-voice-funnel.ts +33 -0
- package/src/tools/acp/list-agents.test.ts +1 -1
- package/src/tools/browser/__tests__/browser-status.test.ts +3 -0
- package/src/tools/browser/browser-execution.ts +117 -53
- package/src/tools/browser/browser-status-constants.ts +6 -6
- package/src/tools/capability-offer.test.ts +87 -0
- package/src/tools/capability-offer.ts +93 -0
- package/src/tools/computer-use/definitions.ts +6 -0
- package/src/tools/computer-use/skill-proxy-bridge.ts +10 -0
- package/src/tools/terminal/safe-env.ts +2 -0
- package/src/watch/__tests__/watch-retro.test.ts +11 -10
- package/src/watch/__tests__/watch-session-manager.test.ts +75 -1
- package/src/watch/watch-retro.ts +10 -9
- package/src/watch/watch-session-manager.ts +17 -0
- package/src/runtime/routes/__tests__/sight-frame-routes.test.ts +0 -487
- package/src/runtime/routes/sight-frame-routes.ts +0 -136
package/ARCHITECTURE.md
CHANGED
|
@@ -145,7 +145,7 @@ All guardian approval decisions, regardless of how they arrive, route through a
|
|
|
145
145
|
|
|
146
146
|
**Text fallback path (always available):**
|
|
147
147
|
|
|
148
|
-
- Every prompt includes a `requestCode` (6-char alphanumeric). Guardians can reply with `<requestCode> approve` or `<requestCode> reject` on any channel.
|
|
148
|
+
- Every prompt includes a `requestCode` (6-char alphanumeric). Guardians can reply with `<requestCode> approve` or `<requestCode> reject` on any channel. The instruction saying so travels only in the card's `plainTextFallback`, which a transport appends when it sends text without buttons; composed copy and `questionText` never carry it.
|
|
149
149
|
- `access_request` prompts carry the request-code verify/trust/reject/block directive in the card's `plainTextFallback`, appended by a transport only when it sends text without buttons; the `"open invite flow"` phrase for starting the Trusted Contacts invite flow stays in the text on every surface because nothing offers a button for it.
|
|
150
150
|
- `pending_question` prompts (voice-originated) support `<requestCode> <your answer>` for free-text answers.
|
|
151
151
|
- The `routeGuardianReply` router processes text replies through a priority-ordered pipeline: callback parsing -> request code parsing -> NL classification. All paths converge on `applyGuardianDecision`.
|
|
@@ -199,7 +199,7 @@ The guardian request system provides a channel-agnostic, unified domain for all
|
|
|
199
199
|
|
|
200
200
|
4. **Deterministic API (prompt listing and decision endpoints):** Desktop clients and API consumers use `GET /v1/guardian-actions/pending` and `POST /v1/guardian-actions/decision` (HTTP). These endpoints surface guardian requests alongside legacy pending interactions and channel approval records, with deduplication to avoid double-rendering.
|
|
201
201
|
|
|
202
|
-
5. **Buttons first, text fallback:** All request kinds (`tool_approval`, `pending_question`, `access_request`) are rendered as structured button cards when displayed in macOS guardian conversations. Each
|
|
202
|
+
5. **Buttons first, text fallback:** All request kinds (`tool_approval`, `pending_question`, `access_request`) are rendered as structured button cards when displayed in macOS guardian conversations. Each card also carries deterministic text fallback instructions (request-code-based directives, and for `access_request` the "open invite flow" phrase) in its `plainTextFallback`, appended by a transport only when it sends text without buttons, so text-based channels and manual fallback always work without the instructions duplicating the buttons. Code-only messages (just a request code without decision text) return clarification instead of auto-approving. Disambiguation with multiple pending requests stays fail-closed: no auto-resolve when the target is ambiguous.
|
|
203
203
|
|
|
204
204
|
**Resolver registry:** Kind-specific resolvers (`src/approvals/guardian-request-resolvers.ts`) handle side effects after CAS resolution. Built-in resolvers: `tool_approval` (channel/desktop approval path), `pending_question` (voice call question path), and `access_request` (trusted-contact verification session creation). New request kinds register resolvers without touching the core primitive.
|
|
205
205
|
|
package/Dockerfile
CHANGED
|
@@ -30,19 +30,10 @@ COPY assistant/package.json ./assistant/
|
|
|
30
30
|
COPY assistant/src/api/package.json ./assistant/src/api/
|
|
31
31
|
COPY --parents packages/*/package.json ./
|
|
32
32
|
|
|
33
|
-
RUN bun
|
|
33
|
+
RUN --mount=type=cache,id=bun-install-cache,target=/root/.bun/install/cache \
|
|
34
|
+
bun install --frozen-lockfile --ignore-scripts \
|
|
34
35
|
--filter='./assistant' --filter='./assistant/src/api'
|
|
35
36
|
|
|
36
|
-
# The repo-root .dockerignore decides which skills (and files) ship.
|
|
37
|
-
COPY skills ./skills
|
|
38
|
-
RUN set -eu; for pkg in /app/skills/*/package.json; do \
|
|
39
|
-
[ -e "$pkg" ] || continue; \
|
|
40
|
-
dir="$(dirname "$pkg")"; \
|
|
41
|
-
echo "Installing dependencies for $dir"; \
|
|
42
|
-
(cd "$dir" && (bun install --frozen-lockfile 2>/dev/null || bun install)); \
|
|
43
|
-
done
|
|
44
|
-
|
|
45
|
-
|
|
46
37
|
# Final stage
|
|
47
38
|
FROM debian:trixie-slim@sha256:4ffb3a1511099754cddc70eb1b12e50ffdb67619aa0ab6c13fcd800a78ef7c7a AS runner
|
|
48
39
|
|
|
@@ -114,7 +105,7 @@ RUN apt-get update && apt-get install -y \
|
|
|
114
105
|
COPY --from=builder /root/.bun/bin/bun /usr/local/bin/bun
|
|
115
106
|
RUN ln -sf /usr/local/bin/bun /usr/local/bin/bunx
|
|
116
107
|
|
|
117
|
-
COPY --from=builder /app /app
|
|
108
|
+
COPY --link --from=builder /app /app
|
|
118
109
|
|
|
119
110
|
# Copy source after installing dependencies for better layer caching.
|
|
120
111
|
COPY packages/avatar-catalog /app/packages/avatar-catalog
|
|
@@ -131,6 +122,9 @@ COPY packages/twilio-client /app/packages/twilio-client
|
|
|
131
122
|
|
|
132
123
|
COPY assistant /app/assistant
|
|
133
124
|
|
|
125
|
+
# The repo-root .dockerignore decides which skills (and files) ship.
|
|
126
|
+
COPY skills /app/skills
|
|
127
|
+
|
|
134
128
|
# Materialize the git-ignored offline plugin manifest from its canonical source.
|
|
135
129
|
# `assistant/src/cli/lib/plugin-catalog-local.ts` statically imports this JSON
|
|
136
130
|
# (loaded even when platform features are enabled), so it must exist in the image
|
|
@@ -13,7 +13,7 @@ An assistant runs exactly one memory tier, derived by `memoryTier()` in
|
|
|
13
13
|
| Tier | Selected when | Injection source |
|
|
14
14
|
| ----- | -------------------------------------------- | ------------------------------------------------ |
|
|
15
15
|
| `off` | `memory.enabled === false` | none |
|
|
16
|
-
| `v3` | `memory.v3.live === true` | v3 lanes +
|
|
16
|
+
| `v3` | `memory.v3.live === true` | v3 lanes + sections (`v3/injector.ts`) |
|
|
17
17
|
| `v2` | `memory.v2.enabled === true` and v3 not live | v2 activation/router engine (`v2/`) |
|
|
18
18
|
| `v1` | otherwise | PKB `<knowledge_base>` block (`v1/pkb/`, legacy) |
|
|
19
19
|
|
|
@@ -172,12 +172,20 @@ Ingested pages carry provenance frontmatter with distinct consumers:
|
|
|
172
172
|
|
|
173
173
|
- **v3 (live)**: per-turn lane selection over concept pages (dense/sparse
|
|
174
174
|
retrieval via `substrate/sim.ts` over the concept-page collection,
|
|
175
|
-
learned edges, entity/hot/fresh/core sets)
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
175
|
+
learned edges, entity/hot/fresh/core sets). The injection unit is the
|
|
176
|
+
SECTION: the selector pool lists a page once per matched section, and
|
|
177
|
+
`v3/injector.ts` renders each selected page's selected sections (its lead
|
|
178
|
+
when it was selected with none) into a `<memory>` block,
|
|
179
|
+
net-new sections only, deduped per `(page, section)` through
|
|
180
|
+
`memory_v3_injected_sections` and bounded by a recency prune valve with no
|
|
181
|
+
lane exemptions. Section bodies are backslash-escaped where a line would
|
|
182
|
+
read as a block header, so page text never forges a section boundary, and a
|
|
183
|
+
pruned section is dropped from any pointer that named it. Frozen section
|
|
184
|
+
blocks stay on historical user messages so
|
|
185
|
+
the provider prefix stays cacheable. Re-selected sections that are already
|
|
186
|
+
resident are listed, paths only, in a per-turn `<memory_pointer>` block
|
|
187
|
+
that stays on the user message it was sent with; a new pointer is added
|
|
188
|
+
only on the new tail, so older messages are not rewritten. The static `<info>` block
|
|
181
189
|
(`substrate/static-context.ts`: essentials/threads/recent/buffer) also
|
|
182
190
|
injects whenever the substrate is active.
|
|
183
191
|
- **v2 (transitional)**: activation/router engine in `v2/`
|
|
@@ -192,8 +200,8 @@ Ingested pages carry provenance frontmatter with distinct consumers:
|
|
|
192
200
|
|
|
193
201
|
The live voice front door does not await current-turn memory retrieval. Its
|
|
194
202
|
prompt hook skips legacy graph retrieval, and both v3 injectors skip
|
|
195
|
-
orchestration for `voiceFrontDoor`. Frozen
|
|
196
|
-
substrate context remain available. When the answer depends on a saved personal
|
|
203
|
+
orchestration for `voiceFrontDoor`. Frozen sections from prior turns and the
|
|
204
|
+
static substrate context remain available. When the answer depends on a saved personal
|
|
197
205
|
fact that is absent from that context, the front-door rule escalates instead of
|
|
198
206
|
guessing.
|
|
199
207
|
|
|
@@ -131,10 +131,13 @@ routing after a restart even though the card is absent from the model's history.
|
|
|
131
131
|
Two instruction modes exist per request kind (`notifications/guardian-question-mode.ts`):
|
|
132
132
|
**approval** ("CODE approve" / approve–reject buttons) and **answer**
|
|
133
133
|
("CODE <your answer>" / option buttons). `pending_question` is answer-mode.
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
134
|
+
The "CODE <reply>" instruction lives in exactly one place: the
|
|
135
|
+
`plainTextFallback` the broadcaster builds beside the card's actions. Composed
|
|
136
|
+
copy never carries it (the decision engine strips a model's echo of it on
|
|
137
|
+
every channel), and a transport appends it only when it sends text without
|
|
138
|
+
buttons: a rich delivery that failed, or a request with no actions to draw,
|
|
139
|
+
which is how an option-less voice question stays answerable. Every surface
|
|
140
|
+
with buttons, and the bell, banner, and push, show the ask alone.
|
|
138
141
|
|
|
139
142
|
## Worked example: `ask_question` on a channel
|
|
140
143
|
|
|
@@ -146,9 +146,13 @@ sqlite3 "file:$GW_DB?mode=ro" \
|
|
|
146
146
|
|
|
147
147
|
## 3b. Contact writes
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
Contact writes are gateway-owned, and they reach it two ways. An operator ACL
|
|
150
|
+
write (a risk ceiling) goes through the gateway CLI directly, not through
|
|
150
151
|
`assistant contacts`. From the host, run the same command via
|
|
151
|
-
`vellum exec --service gateway --`.
|
|
152
|
+
`vellum exec --service gateway --`. A write that changes the contact graph
|
|
153
|
+
itself (the record, or a channel binding) goes through `assistant contacts`,
|
|
154
|
+
which opens a form in the guardian's app and writes nothing until they submit
|
|
155
|
+
it; the gateway still performs the write.
|
|
152
156
|
|
|
153
157
|
```bash
|
|
154
158
|
gateway contacts set-risk-threshold <contactId> --threshold high
|
|
@@ -156,6 +160,13 @@ gateway contacts set-risk-threshold <contactId> --threshold high
|
|
|
156
160
|
|
|
157
161
|
`inherit` clears the risk ceiling so the contact follows room and trust-class settings. Stored vocabulary is `none`, `low`, `medium`, or `high`.
|
|
158
162
|
|
|
163
|
+
Binding an address to a contact goes through the guardian instead of the operator. The command below opens a form in the guardian's app naming that contact, and the gateway writes the channel only when they submit it. An address already held by a different contact is refused, naming that contact.
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
assistant contacts channels add <contactId> --channel <type> --address <addr>
|
|
167
|
+
assistant contacts channels add <contactId> --channel email --address alice@example.com
|
|
168
|
+
```
|
|
169
|
+
|
|
159
170
|
## 4. Force-Revoke a Trusted Contact
|
|
160
171
|
|
|
161
172
|
### Via CLI (preferred)
|
package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"./conversation-handle": "./src/conversation-handle.ts",
|
|
11
11
|
"./client-metadata": "./src/client-metadata.ts",
|
|
12
12
|
"./credential-rpc": "./src/credential-rpc.ts",
|
|
13
|
+
"./desktop-presence": "./src/desktop-presence.ts",
|
|
13
14
|
"./ingress": "./src/ingress.ts",
|
|
14
15
|
"./no-response": "./src/no-response.ts",
|
|
15
16
|
"./remote-web-pairing": "./src/remote-web-pairing.ts",
|
|
@@ -25,7 +26,8 @@
|
|
|
25
26
|
"./error": "./src/error.ts",
|
|
26
27
|
"./reactions": "./src/reactions.ts",
|
|
27
28
|
"./guardian-requests": "./src/guardian-requests.ts",
|
|
28
|
-
"./platform-credential": "./src/platform-credential.ts"
|
|
29
|
+
"./platform-credential": "./src/platform-credential.ts",
|
|
30
|
+
"./plan-credit": "./src/plan-credit.ts"
|
|
29
31
|
},
|
|
30
32
|
"scripts": {
|
|
31
33
|
"typecheck": "bunx tsc --noEmit",
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
extraCreditUsd,
|
|
5
|
+
planCreditUsedFraction,
|
|
6
|
+
usageGrantRatio,
|
|
7
|
+
} from "../plan-credit.js";
|
|
8
|
+
|
|
9
|
+
describe("usageGrantRatio", () => {
|
|
10
|
+
test("reads the used share and clamps to 0..1", () => {
|
|
11
|
+
expect(usageGrantRatio(20, 9.1)).toBeCloseTo(0.545);
|
|
12
|
+
expect(usageGrantRatio(20, 0)).toBe(1);
|
|
13
|
+
expect(usageGrantRatio(20, 25)).toBe(0);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test("has no reading without both figures or with nothing granted", () => {
|
|
17
|
+
expect(usageGrantRatio(null, 5)).toBeNull();
|
|
18
|
+
expect(usageGrantRatio(20, null)).toBeNull();
|
|
19
|
+
expect(usageGrantRatio(0, 0)).toBeNull();
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe("planCreditUsedFraction", () => {
|
|
24
|
+
test("prefers the ratio whatever the plan", () => {
|
|
25
|
+
expect(planCreditUsedFraction(20, 9.1, "base")).toBeCloseTo(0.545);
|
|
26
|
+
expect(planCreditUsedFraction(20, 9.1, null)).toBeCloseTo(0.545);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("treats a Pro plan with nothing granted as fully spent", () => {
|
|
30
|
+
expect(planCreditUsedFraction(0, 0, "pro")).toBe(1);
|
|
31
|
+
expect(planCreditUsedFraction(0, null, "pro")).toBe(1);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test("gives a base or unknown plan with nothing granted no reading", () => {
|
|
35
|
+
expect(planCreditUsedFraction(0, 0, "base")).toBeNull();
|
|
36
|
+
expect(planCreditUsedFraction(0, 0, null)).toBeNull();
|
|
37
|
+
expect(planCreditUsedFraction(null, null, "pro")).toBeNull();
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe("extraCreditUsd", () => {
|
|
42
|
+
test("nets unused grant credit out of the balance to the cent", () => {
|
|
43
|
+
expect(extraCreditUsd(42.17, 9.1)).toBe(33.07);
|
|
44
|
+
expect(extraCreditUsd(34.65, 9.1)).toBe(25.55);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("never goes below zero", () => {
|
|
48
|
+
expect(extraCreditUsd(5, 9.1)).toBe(0);
|
|
49
|
+
expect(extraCreditUsd(-2.5, 0)).toBe(0);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -38,6 +38,8 @@ const FIXTURES: Record<string, string> = {
|
|
|
38
38
|
"GitLab Token": `glpat-${filler(20)}`,
|
|
39
39
|
"Stripe Secret Key": `sk_live_${filler(24)}`,
|
|
40
40
|
"Stripe Restricted Key": `rk_live_${filler(24)}`,
|
|
41
|
+
"Link Access Token": `liwltoken_${filler(24)}`,
|
|
42
|
+
"Link Refresh Token": `liwlrefresh_${filler(24)}`,
|
|
41
43
|
"Slack Bot Token": `xoxb-1234567890-1234567890-${filler(24)}`,
|
|
42
44
|
"Slack User Token": `xoxp-1234567890-1234567890-1234567890-${"0123456789abcdef".repeat(2)}`,
|
|
43
45
|
"Slack App Token": "xapp-1-abc123-4567-defghij890",
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The presence states a desktop client may report. Single runtime source for
|
|
3
|
+
* the daemon's stored type, the client route's wire enum, and the Electron
|
|
4
|
+
* presence monitor.
|
|
5
|
+
*
|
|
6
|
+
* Member order is load-bearing: the route feeds this tuple to `z.enum`, so
|
|
7
|
+
* reordering rewrites the generated `assistant/openapi.yaml`.
|
|
8
|
+
*/
|
|
9
|
+
export const DESKTOP_PRESENCE_STATES = ["active", "idle", "away"] as const;
|
|
10
|
+
|
|
11
|
+
export type DesktopPresenceState = (typeof DESKTOP_PRESENCE_STATES)[number];
|
package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/index.ts
CHANGED
|
@@ -28,6 +28,7 @@ export * from "./rpc.js";
|
|
|
28
28
|
export * from "./trust-rules.js";
|
|
29
29
|
export * from "./ingress.js";
|
|
30
30
|
export * from "./no-response.js";
|
|
31
|
+
export * from "./plan-credit.js";
|
|
31
32
|
export * from "./platform-credential.js";
|
|
32
33
|
export * from "./remote-web-pairing.js";
|
|
33
34
|
export * from "./twilio-ingress.js";
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan-credit derivations shared by the assistant runtime's `platform credits`
|
|
3
|
+
* route and the web client's usage meter, so both read the billing summary's
|
|
4
|
+
* grant figures the same way and can never quote different readings.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export type BillingPlanId = "base" | "pro";
|
|
8
|
+
|
|
9
|
+
function clamp01(value: number): number {
|
|
10
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
return value > 1 ? 1 : value;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* How much of the usage credit an account was granted it has already used:
|
|
18
|
+
* the granted total less what is still unused, over that total. The initial
|
|
19
|
+
* $5 grant burns 0 to 100% as it is spent, and a further grant grows the total
|
|
20
|
+
* so the bar drops back. Null when nothing was ever granted, or when the
|
|
21
|
+
* platform reports neither figure, which has no honest reading rather than a
|
|
22
|
+
* full or empty bar.
|
|
23
|
+
*/
|
|
24
|
+
export function usageGrantRatio(
|
|
25
|
+
totalUsd: number | null,
|
|
26
|
+
availableUsd: number | null,
|
|
27
|
+
): number | null {
|
|
28
|
+
if (totalUsd == null || availableUsd == null || totalUsd <= 0) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return clamp01((totalUsd - availableUsd) / totalUsd);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The plan-credit reading with the plan's fallback applied. The grant figures
|
|
36
|
+
* count only unexpired grants, so a Pro subscription whose grants total
|
|
37
|
+
* nothing has used or expired everything it was granted (a full bar, with
|
|
38
|
+
* nothing scheduled to refill it), while a base plan in that position was
|
|
39
|
+
* never granted anything (no reading). An unknown plan gets the ratio when
|
|
40
|
+
* the figures allow one and no fallback otherwise.
|
|
41
|
+
*/
|
|
42
|
+
export function planCreditUsedFraction(
|
|
43
|
+
totalUsd: number | null,
|
|
44
|
+
availableUsd: number | null,
|
|
45
|
+
planId: BillingPlanId | null,
|
|
46
|
+
): number | null {
|
|
47
|
+
const ratio = usageGrantRatio(totalUsd, availableUsd);
|
|
48
|
+
if (ratio != null) {
|
|
49
|
+
return ratio;
|
|
50
|
+
}
|
|
51
|
+
if (planId === "pro" && totalUsd != null && totalUsd <= 0) {
|
|
52
|
+
return 1;
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Credit bought or earned on top of the plan-included grants: the balance less
|
|
59
|
+
* whatever is still unused on those grants, never below zero, to the cent.
|
|
60
|
+
*/
|
|
61
|
+
export function extraCreditUsd(
|
|
62
|
+
balanceUsd: number,
|
|
63
|
+
availableUsd: number,
|
|
64
|
+
): number {
|
|
65
|
+
return Math.round(Math.max(0, balanceUsd - availableUsd) * 100) / 100;
|
|
66
|
+
}
|
|
@@ -143,6 +143,13 @@ export const PREFIX_PATTERNS: SecretPrefixPattern[] = [
|
|
|
143
143
|
// -- Stripe --
|
|
144
144
|
{ label: "Stripe Secret Key", regex: /sk_live_[A-Za-z0-9]{24,}/ },
|
|
145
145
|
{ label: "Stripe Restricted Key", regex: /rk_live_[A-Za-z0-9]{24,}/ },
|
|
146
|
+
// Link (Stripe's wallet) issues prefixed OAuth tokens rather than opaque
|
|
147
|
+
// ones, and its own docs tell users to export the access token as
|
|
148
|
+
// LINK_ACCESS_TOKEN to drive link-cli, so these do get pasted by hand. A
|
|
149
|
+
// leaked one can spend from the wallet. The `lwlpk_` client id is public
|
|
150
|
+
// (it ships in the CLI bundle) and is deliberately not matched here.
|
|
151
|
+
{ label: "Link Access Token", regex: /liwltoken_[A-Za-z0-9]{16,}/ },
|
|
152
|
+
{ label: "Link Refresh Token", regex: /liwlrefresh_[A-Za-z0-9]{16,}/ },
|
|
146
153
|
|
|
147
154
|
// -- Slack --
|
|
148
155
|
{
|
package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"./conversation-handle": "./src/conversation-handle.ts",
|
|
11
11
|
"./client-metadata": "./src/client-metadata.ts",
|
|
12
12
|
"./credential-rpc": "./src/credential-rpc.ts",
|
|
13
|
+
"./desktop-presence": "./src/desktop-presence.ts",
|
|
13
14
|
"./ingress": "./src/ingress.ts",
|
|
14
15
|
"./no-response": "./src/no-response.ts",
|
|
15
16
|
"./remote-web-pairing": "./src/remote-web-pairing.ts",
|
|
@@ -25,7 +26,8 @@
|
|
|
25
26
|
"./error": "./src/error.ts",
|
|
26
27
|
"./reactions": "./src/reactions.ts",
|
|
27
28
|
"./guardian-requests": "./src/guardian-requests.ts",
|
|
28
|
-
"./platform-credential": "./src/platform-credential.ts"
|
|
29
|
+
"./platform-credential": "./src/platform-credential.ts",
|
|
30
|
+
"./plan-credit": "./src/plan-credit.ts"
|
|
29
31
|
},
|
|
30
32
|
"scripts": {
|
|
31
33
|
"typecheck": "bunx tsc --noEmit",
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
extraCreditUsd,
|
|
5
|
+
planCreditUsedFraction,
|
|
6
|
+
usageGrantRatio,
|
|
7
|
+
} from "../plan-credit.js";
|
|
8
|
+
|
|
9
|
+
describe("usageGrantRatio", () => {
|
|
10
|
+
test("reads the used share and clamps to 0..1", () => {
|
|
11
|
+
expect(usageGrantRatio(20, 9.1)).toBeCloseTo(0.545);
|
|
12
|
+
expect(usageGrantRatio(20, 0)).toBe(1);
|
|
13
|
+
expect(usageGrantRatio(20, 25)).toBe(0);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test("has no reading without both figures or with nothing granted", () => {
|
|
17
|
+
expect(usageGrantRatio(null, 5)).toBeNull();
|
|
18
|
+
expect(usageGrantRatio(20, null)).toBeNull();
|
|
19
|
+
expect(usageGrantRatio(0, 0)).toBeNull();
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe("planCreditUsedFraction", () => {
|
|
24
|
+
test("prefers the ratio whatever the plan", () => {
|
|
25
|
+
expect(planCreditUsedFraction(20, 9.1, "base")).toBeCloseTo(0.545);
|
|
26
|
+
expect(planCreditUsedFraction(20, 9.1, null)).toBeCloseTo(0.545);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("treats a Pro plan with nothing granted as fully spent", () => {
|
|
30
|
+
expect(planCreditUsedFraction(0, 0, "pro")).toBe(1);
|
|
31
|
+
expect(planCreditUsedFraction(0, null, "pro")).toBe(1);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test("gives a base or unknown plan with nothing granted no reading", () => {
|
|
35
|
+
expect(planCreditUsedFraction(0, 0, "base")).toBeNull();
|
|
36
|
+
expect(planCreditUsedFraction(0, 0, null)).toBeNull();
|
|
37
|
+
expect(planCreditUsedFraction(null, null, "pro")).toBeNull();
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe("extraCreditUsd", () => {
|
|
42
|
+
test("nets unused grant credit out of the balance to the cent", () => {
|
|
43
|
+
expect(extraCreditUsd(42.17, 9.1)).toBe(33.07);
|
|
44
|
+
expect(extraCreditUsd(34.65, 9.1)).toBe(25.55);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("never goes below zero", () => {
|
|
48
|
+
expect(extraCreditUsd(5, 9.1)).toBe(0);
|
|
49
|
+
expect(extraCreditUsd(-2.5, 0)).toBe(0);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -38,6 +38,8 @@ const FIXTURES: Record<string, string> = {
|
|
|
38
38
|
"GitLab Token": `glpat-${filler(20)}`,
|
|
39
39
|
"Stripe Secret Key": `sk_live_${filler(24)}`,
|
|
40
40
|
"Stripe Restricted Key": `rk_live_${filler(24)}`,
|
|
41
|
+
"Link Access Token": `liwltoken_${filler(24)}`,
|
|
42
|
+
"Link Refresh Token": `liwlrefresh_${filler(24)}`,
|
|
41
43
|
"Slack Bot Token": `xoxb-1234567890-1234567890-${filler(24)}`,
|
|
42
44
|
"Slack User Token": `xoxp-1234567890-1234567890-1234567890-${"0123456789abcdef".repeat(2)}`,
|
|
43
45
|
"Slack App Token": "xapp-1-abc123-4567-defghij890",
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The presence states a desktop client may report. Single runtime source for
|
|
3
|
+
* the daemon's stored type, the client route's wire enum, and the Electron
|
|
4
|
+
* presence monitor.
|
|
5
|
+
*
|
|
6
|
+
* Member order is load-bearing: the route feeds this tuple to `z.enum`, so
|
|
7
|
+
* reordering rewrites the generated `assistant/openapi.yaml`.
|
|
8
|
+
*/
|
|
9
|
+
export const DESKTOP_PRESENCE_STATES = ["active", "idle", "away"] as const;
|
|
10
|
+
|
|
11
|
+
export type DesktopPresenceState = (typeof DESKTOP_PRESENCE_STATES)[number];
|
package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/index.ts
CHANGED
|
@@ -28,6 +28,7 @@ export * from "./rpc.js";
|
|
|
28
28
|
export * from "./trust-rules.js";
|
|
29
29
|
export * from "./ingress.js";
|
|
30
30
|
export * from "./no-response.js";
|
|
31
|
+
export * from "./plan-credit.js";
|
|
31
32
|
export * from "./platform-credential.js";
|
|
32
33
|
export * from "./remote-web-pairing.js";
|
|
33
34
|
export * from "./twilio-ingress.js";
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan-credit derivations shared by the assistant runtime's `platform credits`
|
|
3
|
+
* route and the web client's usage meter, so both read the billing summary's
|
|
4
|
+
* grant figures the same way and can never quote different readings.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export type BillingPlanId = "base" | "pro";
|
|
8
|
+
|
|
9
|
+
function clamp01(value: number): number {
|
|
10
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
return value > 1 ? 1 : value;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* How much of the usage credit an account was granted it has already used:
|
|
18
|
+
* the granted total less what is still unused, over that total. The initial
|
|
19
|
+
* $5 grant burns 0 to 100% as it is spent, and a further grant grows the total
|
|
20
|
+
* so the bar drops back. Null when nothing was ever granted, or when the
|
|
21
|
+
* platform reports neither figure, which has no honest reading rather than a
|
|
22
|
+
* full or empty bar.
|
|
23
|
+
*/
|
|
24
|
+
export function usageGrantRatio(
|
|
25
|
+
totalUsd: number | null,
|
|
26
|
+
availableUsd: number | null,
|
|
27
|
+
): number | null {
|
|
28
|
+
if (totalUsd == null || availableUsd == null || totalUsd <= 0) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return clamp01((totalUsd - availableUsd) / totalUsd);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The plan-credit reading with the plan's fallback applied. The grant figures
|
|
36
|
+
* count only unexpired grants, so a Pro subscription whose grants total
|
|
37
|
+
* nothing has used or expired everything it was granted (a full bar, with
|
|
38
|
+
* nothing scheduled to refill it), while a base plan in that position was
|
|
39
|
+
* never granted anything (no reading). An unknown plan gets the ratio when
|
|
40
|
+
* the figures allow one and no fallback otherwise.
|
|
41
|
+
*/
|
|
42
|
+
export function planCreditUsedFraction(
|
|
43
|
+
totalUsd: number | null,
|
|
44
|
+
availableUsd: number | null,
|
|
45
|
+
planId: BillingPlanId | null,
|
|
46
|
+
): number | null {
|
|
47
|
+
const ratio = usageGrantRatio(totalUsd, availableUsd);
|
|
48
|
+
if (ratio != null) {
|
|
49
|
+
return ratio;
|
|
50
|
+
}
|
|
51
|
+
if (planId === "pro" && totalUsd != null && totalUsd <= 0) {
|
|
52
|
+
return 1;
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Credit bought or earned on top of the plan-included grants: the balance less
|
|
59
|
+
* whatever is still unused on those grants, never below zero, to the cent.
|
|
60
|
+
*/
|
|
61
|
+
export function extraCreditUsd(
|
|
62
|
+
balanceUsd: number,
|
|
63
|
+
availableUsd: number,
|
|
64
|
+
): number {
|
|
65
|
+
return Math.round(Math.max(0, balanceUsd - availableUsd) * 100) / 100;
|
|
66
|
+
}
|
|
@@ -143,6 +143,13 @@ export const PREFIX_PATTERNS: SecretPrefixPattern[] = [
|
|
|
143
143
|
// -- Stripe --
|
|
144
144
|
{ label: "Stripe Secret Key", regex: /sk_live_[A-Za-z0-9]{24,}/ },
|
|
145
145
|
{ label: "Stripe Restricted Key", regex: /rk_live_[A-Za-z0-9]{24,}/ },
|
|
146
|
+
// Link (Stripe's wallet) issues prefixed OAuth tokens rather than opaque
|
|
147
|
+
// ones, and its own docs tell users to export the access token as
|
|
148
|
+
// LINK_ACCESS_TOKEN to drive link-cli, so these do get pasted by hand. A
|
|
149
|
+
// leaked one can spend from the wallet. The `lwlpk_` client id is public
|
|
150
|
+
// (it ships in the CLI bundle) and is deliberately not matched here.
|
|
151
|
+
{ label: "Link Access Token", regex: /liwltoken_[A-Za-z0-9]{16,}/ },
|
|
152
|
+
{ label: "Link Refresh Token", regex: /liwlrefresh_[A-Za-z0-9]{16,}/ },
|
|
146
153
|
|
|
147
154
|
// -- Slack --
|
|
148
155
|
{
|
|
@@ -401,6 +401,78 @@ export type ContactsIdentitySnapshotIpcResponse = z.infer<
|
|
|
401
401
|
typeof ContactsIdentitySnapshotIpcResponseSchema
|
|
402
402
|
>;
|
|
403
403
|
|
|
404
|
+
// ── webhook ingress routes ───────────────────────────────────────────────────
|
|
405
|
+
// The gateway owns the registry of subpaths this assistant answers from
|
|
406
|
+
// outside; the daemon claims, drops, and inspects them over IPC. Both sides
|
|
407
|
+
// read these schemas so a change to the stored row has to travel through the
|
|
408
|
+
// contract.
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Feature flag gating the whole webhook ingress registry. The gateway reads it
|
|
412
|
+
* to decide whether to accept a claim and how to advertise its allowed paths,
|
|
413
|
+
* and the daemon reads it to decide whether to claim at all, so both sides have
|
|
414
|
+
* to name the same key.
|
|
415
|
+
*/
|
|
416
|
+
export const WebhookIngressRouteSchema = z.object({
|
|
417
|
+
path: z.string(),
|
|
418
|
+
type: z.string(),
|
|
419
|
+
source: z.string().nullable(),
|
|
420
|
+
match: z.literal("exact"),
|
|
421
|
+
createdAt: z.number(),
|
|
422
|
+
lastRegisteredAt: z.number(),
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
export type WebhookIngressRoute = z.infer<typeof WebhookIngressRouteSchema>;
|
|
426
|
+
|
|
427
|
+
export const RegisterWebhookRouteIpcParamsSchema = z.object({
|
|
428
|
+
/** Exact subpath, leading slash included, under `/webhooks/`. */
|
|
429
|
+
path: z.string().min(1),
|
|
430
|
+
type: z.string().min(1),
|
|
431
|
+
source: z.string().nullish(),
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
export type RegisterWebhookRouteIpcParams = z.infer<
|
|
435
|
+
typeof RegisterWebhookRouteIpcParamsSchema
|
|
436
|
+
>;
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* A refusal is a normal result rather than an error: the daemon reads
|
|
440
|
+
* `disabled` as "this assistant is not serving its own webhooks" and falls
|
|
441
|
+
* back to the platform's callback routes.
|
|
442
|
+
*/
|
|
443
|
+
export const RegisterWebhookRouteIpcResponseSchema = z.union([
|
|
444
|
+
z.object({ disabled: z.literal(true) }),
|
|
445
|
+
z.object({ disabled: z.literal(false), route: WebhookIngressRouteSchema }),
|
|
446
|
+
]);
|
|
447
|
+
|
|
448
|
+
export type RegisterWebhookRouteIpcResponse = z.infer<
|
|
449
|
+
typeof RegisterWebhookRouteIpcResponseSchema
|
|
450
|
+
>;
|
|
451
|
+
|
|
452
|
+
export const UnregisterWebhookRouteIpcParamsSchema = z.object({
|
|
453
|
+
path: z.string().min(1),
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
export type UnregisterWebhookRouteIpcParams = z.infer<
|
|
457
|
+
typeof UnregisterWebhookRouteIpcParamsSchema
|
|
458
|
+
>;
|
|
459
|
+
|
|
460
|
+
export const UnregisterWebhookRouteIpcResponseSchema = z.object({
|
|
461
|
+
removed: z.boolean(),
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
export type UnregisterWebhookRouteIpcResponse = z.infer<
|
|
465
|
+
typeof UnregisterWebhookRouteIpcResponseSchema
|
|
466
|
+
>;
|
|
467
|
+
|
|
468
|
+
export const ListWebhookRoutesIpcResponseSchema = z.object({
|
|
469
|
+
routes: z.array(WebhookIngressRouteSchema),
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
export type ListWebhookRoutesIpcResponse = z.infer<
|
|
473
|
+
typeof ListWebhookRoutesIpcResponseSchema
|
|
474
|
+
>;
|
|
475
|
+
|
|
404
476
|
// ── classify_risk ────────────────────────────────────────────────────────────
|
|
405
477
|
// Risk classification is gateway-owned; the assistant sends one request per
|
|
406
478
|
// tool invocation and reads the whole answer back. The gateway validates the
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"./conversation-handle": "./src/conversation-handle.ts",
|
|
11
11
|
"./client-metadata": "./src/client-metadata.ts",
|
|
12
12
|
"./credential-rpc": "./src/credential-rpc.ts",
|
|
13
|
+
"./desktop-presence": "./src/desktop-presence.ts",
|
|
13
14
|
"./ingress": "./src/ingress.ts",
|
|
14
15
|
"./no-response": "./src/no-response.ts",
|
|
15
16
|
"./remote-web-pairing": "./src/remote-web-pairing.ts",
|
|
@@ -25,7 +26,8 @@
|
|
|
25
26
|
"./error": "./src/error.ts",
|
|
26
27
|
"./reactions": "./src/reactions.ts",
|
|
27
28
|
"./guardian-requests": "./src/guardian-requests.ts",
|
|
28
|
-
"./platform-credential": "./src/platform-credential.ts"
|
|
29
|
+
"./platform-credential": "./src/platform-credential.ts",
|
|
30
|
+
"./plan-credit": "./src/plan-credit.ts"
|
|
29
31
|
},
|
|
30
32
|
"scripts": {
|
|
31
33
|
"typecheck": "bunx tsc --noEmit",
|