@vellumai/assistant 0.10.0 → 0.10.1-dev.202606240317.ea25efe
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 +36 -37
- package/bun.lock +3 -0
- package/docs/workflows.md +12 -7
- package/eslint-rules/cli-no-daemon-internals.js +12 -0
- package/node_modules/@slack/types/LICENSE +23 -0
- package/node_modules/@slack/types/README.md +32 -0
- package/node_modules/@slack/types/dist/block-kit/block-elements.d.ts +953 -0
- package/node_modules/@slack/types/dist/block-kit/block-elements.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/block-elements.js +4 -0
- package/node_modules/@slack/types/dist/block-kit/block-elements.js.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/blocks.d.ts +474 -0
- package/node_modules/@slack/types/dist/block-kit/blocks.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/blocks.js +3 -0
- package/node_modules/@slack/types/dist/block-kit/blocks.js.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/composition-objects.d.ts +237 -0
- package/node_modules/@slack/types/dist/block-kit/composition-objects.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/composition-objects.js +4 -0
- package/node_modules/@slack/types/dist/block-kit/composition-objects.js.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/extensions.d.ts +88 -0
- package/node_modules/@slack/types/dist/block-kit/extensions.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/extensions.js +3 -0
- package/node_modules/@slack/types/dist/block-kit/extensions.js.map +1 -0
- package/node_modules/@slack/types/dist/calls.d.ts +26 -0
- package/node_modules/@slack/types/dist/calls.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/calls.js +6 -0
- package/node_modules/@slack/types/dist/calls.js.map +1 -0
- package/node_modules/@slack/types/dist/chunk.d.ts +52 -0
- package/node_modules/@slack/types/dist/chunk.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/chunk.js +3 -0
- package/node_modules/@slack/types/dist/chunk.js.map +1 -0
- package/node_modules/@slack/types/dist/common/bot-profile.d.ts +12 -0
- package/node_modules/@slack/types/dist/common/bot-profile.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/common/bot-profile.js +3 -0
- package/node_modules/@slack/types/dist/common/bot-profile.js.map +1 -0
- package/node_modules/@slack/types/dist/common/status-emoji-display-info.d.ts +6 -0
- package/node_modules/@slack/types/dist/common/status-emoji-display-info.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/common/status-emoji-display-info.js +3 -0
- package/node_modules/@slack/types/dist/common/status-emoji-display-info.js.map +1 -0
- package/node_modules/@slack/types/dist/dialog.d.ts +36 -0
- package/node_modules/@slack/types/dist/dialog.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/dialog.js +3 -0
- package/node_modules/@slack/types/dist/dialog.js.map +1 -0
- package/node_modules/@slack/types/dist/events/app.d.ts +204 -0
- package/node_modules/@slack/types/dist/events/app.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/app.js +3 -0
- package/node_modules/@slack/types/dist/events/app.js.map +1 -0
- package/node_modules/@slack/types/dist/events/assistant.d.ts +29 -0
- package/node_modules/@slack/types/dist/events/assistant.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/assistant.js +3 -0
- package/node_modules/@slack/types/dist/events/assistant.js.map +1 -0
- package/node_modules/@slack/types/dist/events/call.d.ts +8 -0
- package/node_modules/@slack/types/dist/events/call.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/call.js +3 -0
- package/node_modules/@slack/types/dist/events/call.js.map +1 -0
- package/node_modules/@slack/types/dist/events/channel.d.ts +85 -0
- package/node_modules/@slack/types/dist/events/channel.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/channel.js +3 -0
- package/node_modules/@slack/types/dist/events/channel.js.map +1 -0
- package/node_modules/@slack/types/dist/events/dnd.d.ts +24 -0
- package/node_modules/@slack/types/dist/events/dnd.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/dnd.js +3 -0
- package/node_modules/@slack/types/dist/events/dnd.js.map +1 -0
- package/node_modules/@slack/types/dist/events/email.d.ts +6 -0
- package/node_modules/@slack/types/dist/events/email.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/email.js +3 -0
- package/node_modules/@slack/types/dist/events/email.js.map +1 -0
- package/node_modules/@slack/types/dist/events/emoji.d.ts +11 -0
- package/node_modules/@slack/types/dist/events/emoji.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/emoji.js +3 -0
- package/node_modules/@slack/types/dist/events/emoji.js.map +1 -0
- package/node_modules/@slack/types/dist/events/entity-details-requested.d.ts +21 -0
- package/node_modules/@slack/types/dist/events/entity-details-requested.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/entity-details-requested.js +3 -0
- package/node_modules/@slack/types/dist/events/entity-details-requested.js.map +1 -0
- package/node_modules/@slack/types/dist/events/file.d.ts +60 -0
- package/node_modules/@slack/types/dist/events/file.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/file.js +4 -0
- package/node_modules/@slack/types/dist/events/file.js.map +1 -0
- package/node_modules/@slack/types/dist/events/function.d.ts +33 -0
- package/node_modules/@slack/types/dist/events/function.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/function.js +3 -0
- package/node_modules/@slack/types/dist/events/function.js.map +1 -0
- package/node_modules/@slack/types/dist/events/grid-migration.d.ts +9 -0
- package/node_modules/@slack/types/dist/events/grid-migration.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/grid-migration.js +3 -0
- package/node_modules/@slack/types/dist/events/grid-migration.js.map +1 -0
- package/node_modules/@slack/types/dist/events/group.d.ts +55 -0
- package/node_modules/@slack/types/dist/events/group.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/group.js +3 -0
- package/node_modules/@slack/types/dist/events/group.js.map +1 -0
- package/node_modules/@slack/types/dist/events/im.d.ts +26 -0
- package/node_modules/@slack/types/dist/events/im.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/im.js +3 -0
- package/node_modules/@slack/types/dist/events/im.js.map +1 -0
- package/node_modules/@slack/types/dist/events/index.d.ts +60 -0
- package/node_modules/@slack/types/dist/events/index.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/index.js +43 -0
- package/node_modules/@slack/types/dist/events/index.js.map +1 -0
- package/node_modules/@slack/types/dist/events/invite.d.ts +20 -0
- package/node_modules/@slack/types/dist/events/invite.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/invite.js +3 -0
- package/node_modules/@slack/types/dist/events/invite.js.map +1 -0
- package/node_modules/@slack/types/dist/events/link-shared.d.ts +16 -0
- package/node_modules/@slack/types/dist/events/link-shared.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/link-shared.js +3 -0
- package/node_modules/@slack/types/dist/events/link-shared.js.map +1 -0
- package/node_modules/@slack/types/dist/events/member.d.ts +19 -0
- package/node_modules/@slack/types/dist/events/member.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/member.js +3 -0
- package/node_modules/@slack/types/dist/events/member.js.map +1 -0
- package/node_modules/@slack/types/dist/events/message-metadata.d.ts +38 -0
- package/node_modules/@slack/types/dist/events/message-metadata.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/message-metadata.js +3 -0
- package/node_modules/@slack/types/dist/events/message-metadata.js.map +1 -0
- package/node_modules/@slack/types/dist/events/message.d.ts +306 -0
- package/node_modules/@slack/types/dist/events/message.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/message.js +3 -0
- package/node_modules/@slack/types/dist/events/message.js.map +1 -0
- package/node_modules/@slack/types/dist/events/pin.d.ts +60 -0
- package/node_modules/@slack/types/dist/events/pin.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/pin.js +3 -0
- package/node_modules/@slack/types/dist/events/pin.js.map +1 -0
- package/node_modules/@slack/types/dist/events/reaction.d.ts +23 -0
- package/node_modules/@slack/types/dist/events/reaction.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/reaction.js +3 -0
- package/node_modules/@slack/types/dist/events/reaction.js.map +1 -0
- package/node_modules/@slack/types/dist/events/shared-channel.d.ts +134 -0
- package/node_modules/@slack/types/dist/events/shared-channel.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/shared-channel.js +3 -0
- package/node_modules/@slack/types/dist/events/shared-channel.js.map +1 -0
- package/node_modules/@slack/types/dist/events/star.d.ts +13 -0
- package/node_modules/@slack/types/dist/events/star.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/star.js +3 -0
- package/node_modules/@slack/types/dist/events/star.js.map +1 -0
- package/node_modules/@slack/types/dist/events/steps-from-apps.d.ts +82 -0
- package/node_modules/@slack/types/dist/events/steps-from-apps.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/steps-from-apps.js +3 -0
- package/node_modules/@slack/types/dist/events/steps-from-apps.js.map +1 -0
- package/node_modules/@slack/types/dist/events/subteam.d.ts +66 -0
- package/node_modules/@slack/types/dist/events/subteam.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/subteam.js +3 -0
- package/node_modules/@slack/types/dist/events/subteam.js.map +1 -0
- package/node_modules/@slack/types/dist/events/team.d.ts +99 -0
- package/node_modules/@slack/types/dist/events/team.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/team.js +3 -0
- package/node_modules/@slack/types/dist/events/team.js.map +1 -0
- package/node_modules/@slack/types/dist/events/token.d.ts +8 -0
- package/node_modules/@slack/types/dist/events/token.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/token.js +3 -0
- package/node_modules/@slack/types/dist/events/token.js.map +1 -0
- package/node_modules/@slack/types/dist/events/user.d.ts +313 -0
- package/node_modules/@slack/types/dist/events/user.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/user.js +3 -0
- package/node_modules/@slack/types/dist/events/user.js.map +1 -0
- package/node_modules/@slack/types/dist/index.d.ts +12 -0
- package/node_modules/@slack/types/dist/index.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/index.js +28 -0
- package/node_modules/@slack/types/dist/index.js.map +1 -0
- package/node_modules/@slack/types/dist/message-attachments.d.ts +171 -0
- package/node_modules/@slack/types/dist/message-attachments.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/message-attachments.js +3 -0
- package/node_modules/@slack/types/dist/message-attachments.js.map +1 -0
- package/node_modules/@slack/types/dist/message-metadata.d.ts +281 -0
- package/node_modules/@slack/types/dist/message-metadata.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/message-metadata.js +27 -0
- package/node_modules/@slack/types/dist/message-metadata.js.map +1 -0
- package/node_modules/@slack/types/dist/views.d.ts +71 -0
- package/node_modules/@slack/types/dist/views.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/views.js +3 -0
- package/node_modules/@slack/types/dist/views.js.map +1 -0
- package/node_modules/@slack/types/package.json +47 -0
- package/node_modules/@vellumai/gateway-client/bun.lock +3 -0
- package/node_modules/@vellumai/gateway-client/package.json +1 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/contact-read-contracts.test.ts +69 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/guardian-delivery-contract.test.ts +91 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +96 -0
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +162 -0
- package/node_modules/@vellumai/gateway-client/src/guardian-delivery-contract.ts +48 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +8 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +28 -0
- package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +4 -2
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +3 -2
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +95 -0
- package/openapi.yaml +458 -18
- package/package.json +2 -1
- package/scripts/memory-inspect.ts +24 -14
- package/scripts/test.sh +36 -15
- package/src/__tests__/access-request-seed-content-blocks.test.ts +83 -103
- package/src/__tests__/activation-early-marking.test.ts +1 -1
- package/src/__tests__/actor-token-service.test.ts +39 -17
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +1 -40
- package/src/__tests__/agent-loop-compaction-events.test.ts +0 -1
- package/src/__tests__/agent-loop-compaction-strip.test.ts +0 -1
- package/src/__tests__/agent-loop-exit-reason.test.ts +0 -1
- package/src/__tests__/agent-loop-pushes-post-hook-prompt.test.ts +306 -0
- package/src/__tests__/agent-loop-regrowth-guard.test.ts +0 -1
- package/src/__tests__/agent-loop.test.ts +3 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +2 -0
- package/src/__tests__/anthropic-provider.test.ts +210 -9
- package/src/__tests__/app-builder-skill-instructions.test.ts +47 -5
- package/src/__tests__/app-conversation-ids-backfill.test.ts +1 -1
- package/src/__tests__/app-source-watcher.test.ts +30 -10
- package/src/__tests__/approval-cascade.test.ts +6 -0
- package/src/__tests__/approval-interception-trust-gates.test.ts +151 -0
- package/src/__tests__/approval-primitive.test.ts +1 -1
- package/src/__tests__/approval-routes-http.test.ts +1 -1
- package/src/__tests__/assistant-attachments.test.ts +155 -0
- package/src/__tests__/assistant-event-hub-machine-name.test.ts +2 -4
- package/src/__tests__/assistant-events-sse-hardening.test.ts +1 -1
- package/src/__tests__/assistant-events-sse-shed.test.ts +1 -1
- package/src/__tests__/attachment-upload-trusted-source.test.ts +13 -8
- package/src/__tests__/attachments-store.test.ts +1 -1
- package/src/__tests__/audit-log-rotation.test.ts +50 -54
- package/src/__tests__/auth-fallback-events-store.test.ts +1 -1
- package/src/__tests__/auto-analysis-end-to-end.test.ts +9 -14
- package/src/__tests__/background-shell-bash.test.ts +4 -1
- package/src/__tests__/background-shell-host-bash.test.ts +17 -3
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -0
- package/src/__tests__/call-controller.test.ts +20 -1
- package/src/__tests__/call-conversation-messages.test.ts +1 -1
- package/src/__tests__/call-domain.test.ts +1 -1
- package/src/__tests__/call-pointer-messages.test.ts +3 -4
- package/src/__tests__/call-recovery.test.ts +1 -1
- package/src/__tests__/call-routes-http.test.ts +1 -1
- package/src/__tests__/call-store.test.ts +1 -1
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
- package/src/__tests__/canonical-guardian-store.test.ts +24 -1
- package/src/__tests__/card-surface-data.test.ts +60 -0
- package/src/__tests__/channel-approval-routes.test.ts +73 -1119
- package/src/__tests__/channel-delivery-store.test.ts +1 -1
- package/src/__tests__/channel-guardian.test.ts +291 -641
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +1 -2
- package/src/__tests__/channel-retry-sweep.test.ts +1 -1
- package/src/__tests__/compaction-events.test.ts +6 -0
- package/src/__tests__/compaction-trail-store.test.ts +6 -5
- package/src/__tests__/compaction.benchmark.test.ts +0 -1
- package/src/__tests__/compactor-image-manifest-trust.test.ts +1 -1
- package/src/__tests__/config-loader-backfill.test.ts +188 -52
- package/src/__tests__/config-schema.test.ts +35 -0
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +1 -2
- package/src/__tests__/contact-store-user-file.test.ts +2 -2
- package/src/__tests__/contacts-relay-reads.test.ts +409 -0
- package/src/__tests__/contacts-tools.test.ts +4 -4
- package/src/__tests__/contacts-write.test.ts +1 -2
- package/src/__tests__/context-search-conversations-source.test.ts +1 -1
- package/src/__tests__/context-window-manager-compact-retry.test.ts +6 -2
- package/src/__tests__/context-window-manager-overflow-rung.test.ts +6 -2
- package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +3 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +3 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +3 -0
- package/src/__tests__/conversation-agent-loop.test.ts +7 -0
- package/src/__tests__/conversation-attachments.test.ts +2 -5
- package/src/__tests__/conversation-attention-store.test.ts +1 -1
- package/src/__tests__/conversation-attention-telegram.test.ts +1 -2
- package/src/__tests__/conversation-clear-safety.test.ts +1 -1
- package/src/__tests__/conversation-confirmation-signals.test.ts +6 -0
- package/src/__tests__/conversation-crud-inference-profile.test.ts +1 -1
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +12 -19
- package/src/__tests__/conversation-disk-view-integration.test.ts +1 -1
- package/src/__tests__/conversation-disk-view.test.ts +1 -1
- package/src/__tests__/conversation-fork-crud.test.ts +10 -8
- package/src/__tests__/conversation-fork-retrospective.test.ts +250 -0
- package/src/__tests__/conversation-fork-route.test.ts +1 -1
- package/src/__tests__/conversation-inference-profile-list.test.ts +1 -1
- package/src/__tests__/conversation-inference-profile-route.test.ts +1 -1
- package/src/__tests__/conversation-init.benchmark.test.ts +1 -1
- package/src/__tests__/conversation-key-store-disk-view.test.ts +1 -1
- package/src/__tests__/conversation-lifecycle.test.ts +117 -0
- package/src/__tests__/conversation-list-source.test.ts +3 -3
- package/src/__tests__/conversation-process-callsite.test.ts +6 -14
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/conversation-queue.test.ts +95 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +1 -1
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +12 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +12 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +115 -12
- package/src/__tests__/conversation-slash-queue.test.ts +6 -0
- package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
- package/src/__tests__/conversation-speed-override.test.ts +6 -0
- package/src/__tests__/conversation-starter-routes.test.ts +5 -5
- package/src/__tests__/conversation-store.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +4 -4
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +352 -0
- package/src/__tests__/conversation-sync-tags.test.ts +1 -1
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +47 -0
- package/src/__tests__/conversation-usage.test.ts +1 -1
- package/src/__tests__/conversation-wipe.test.ts +9 -8
- package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
- package/src/__tests__/conversations-import-system-filter.test.ts +1 -1
- package/src/__tests__/copy-composer-tc-templates.test.ts +17 -0
- package/src/__tests__/credential-security-invariants.test.ts +0 -1
- package/src/__tests__/db-acp-history.test.ts +2 -2
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +5 -7
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +6 -7
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +5 -10
- package/src/__tests__/db-migration-rollback.test.ts +129 -39
- package/src/__tests__/db-proxy-transaction.test.ts +1 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +0 -11
- package/src/__tests__/db-test-helpers.ts +36 -19
- package/src/__tests__/delete-propagation.test.ts +1 -1
- package/src/__tests__/deterministic-verification-control-plane.test.ts +28 -8
- package/src/__tests__/disk-pressure-guard.test.ts +41 -0
- package/src/__tests__/disk-pressure-tools.test.ts +41 -1
- package/src/__tests__/dm-backfill.test.ts +1 -1
- package/src/__tests__/drop-capability-card-state-migration.test.ts +0 -8
- package/src/__tests__/dynamic-page-surface.test.ts +0 -94
- package/src/__tests__/edit-propagation.test.ts +1 -1
- package/src/__tests__/emit-signal-routing-intent.test.ts +93 -5
- package/src/__tests__/empty-response-hook.test.ts +42 -0
- package/src/__tests__/events-client-registration.test.ts +1 -1
- package/src/__tests__/events-dev-bypass-actor.test.ts +7 -1
- package/src/__tests__/followup-tools.test.ts +1 -1
- package/src/__tests__/gemini-count-tokens.test.ts +70 -0
- package/src/__tests__/guardian-action-sweep.test.ts +9 -2
- package/src/__tests__/guardian-binding-drift-heal.test.ts +76 -11
- package/src/__tests__/guardian-card-withdrawal.test.ts +1 -1
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +1 -1
- package/src/__tests__/guardian-dispatch.test.ts +96 -2
- package/src/__tests__/guardian-outbound-http.test.ts +20 -12
- package/src/__tests__/guardian-principal-id-roundtrip.test.ts +1 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
- package/src/__tests__/guardian-routing-state.test.ts +1 -2
- package/src/__tests__/guardian-verification-voice-binding.test.ts +1 -1
- package/src/__tests__/headless-browser-mode.test.ts +2 -2
- package/src/__tests__/heartbeat-disk-pressure.test.ts +4 -0
- package/src/__tests__/heartbeat-service.test.ts +6 -0
- package/src/__tests__/helpers/channel-test-adapter.ts +92 -0
- package/src/__tests__/host-app-control-routes.test.ts +24 -30
- package/src/__tests__/host-bash-routes.test.ts +31 -41
- package/src/__tests__/host-browser-routes.test.ts +26 -32
- package/src/__tests__/host-cu-routes-targeted.test.ts +25 -33
- package/src/__tests__/host-file-routes-targeted.test.ts +40 -52
- package/src/__tests__/host-transfer-routes-targeted.test.ts +31 -43
- package/src/__tests__/http-conversation-lineage.test.ts +1 -1
- package/src/__tests__/http-user-message-parity.test.ts +165 -8
- package/src/__tests__/image-recovery-hook.test.ts +1 -1
- package/src/__tests__/inbound-invite-redemption.test.ts +1 -2
- package/src/__tests__/inbound-trust-verdict.test.ts +254 -0
- package/src/__tests__/inference-profile-reaper.test.ts +1 -1
- package/src/__tests__/inference-profile-session-handler.test.ts +1 -1
- package/src/__tests__/inference-profile-session-ipc.test.ts +1 -1
- package/src/__tests__/injector-chain.test.ts +1 -1
- package/src/__tests__/injector-disk-pressure.test.ts +11 -6
- package/src/__tests__/internal-telemetry-routes.test.ts +1 -1
- package/src/__tests__/invite-redemption-service.test.ts +244 -43
- package/src/__tests__/invite-routes-http.test.ts +35 -186
- package/src/__tests__/invite-service-ipc.test.ts +287 -0
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +5 -5
- package/src/__tests__/jobs-store-upsert-debounced.test.ts +9 -12
- package/src/__tests__/list-messages-attachments.test.ts +42 -1
- package/src/__tests__/list-messages-client-message-id.test.ts +1 -1
- package/src/__tests__/list-messages-hidden-metadata.test.ts +1 -1
- package/src/__tests__/list-messages-page-latest.test.ts +1 -1
- package/src/__tests__/list-messages-tool-merge.test.ts +1 -1
- package/src/__tests__/llm-context-normalization.test.ts +105 -0
- package/src/__tests__/llm-context-route-provider.test.ts +69 -4
- package/src/__tests__/llm-request-log-agent-loop-exit-reason.test.ts +9 -5
- package/src/__tests__/llm-request-log-call-site.test.ts +6 -6
- package/src/__tests__/llm-request-log-turn-query.test.ts +27 -13
- package/src/__tests__/llm-resolver.test.ts +205 -5
- package/src/__tests__/llm-usage-store.test.ts +65 -1
- package/src/__tests__/log-export-routes.test.ts +1 -1
- package/src/__tests__/log-export-workspace.test.ts +3 -3
- package/src/__tests__/media-stream-server-integration.test.ts +127 -0
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +5 -5
- package/src/__tests__/memory-recall-log-store.test.ts +1 -1
- package/src/__tests__/memory-upsert-concurrency.test.ts +3 -4
- package/src/__tests__/messages-after-tiebreaker.test.ts +1 -1
- package/src/__tests__/migration-import-from-url.test.ts +2 -2
- package/src/__tests__/mtime-cache.test.ts +375 -0
- package/src/__tests__/non-member-access-request.test.ts +190 -19
- package/src/__tests__/notification-broadcaster.test.ts +4 -0
- package/src/__tests__/notification-candidate-guardian-context.test.ts +203 -0
- package/src/__tests__/notification-decision-recipient-context.test.ts +33 -32
- package/src/__tests__/notification-deep-link.test.ts +4 -0
- package/src/__tests__/notification-guardian-path.test.ts +20 -1
- package/src/__tests__/notification-schedule-notify-dedup.test.ts +1 -1
- package/src/__tests__/oauth-provider-profiles.test.ts +1 -1
- package/src/__tests__/oauth-provider-visibility.test.ts +1 -1
- package/src/__tests__/oauth-store.test.ts +1 -1
- package/src/__tests__/pending-interactions-resolved-event.test.ts +7 -4
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +1 -1
- package/src/__tests__/persist-unsendable-image.test.ts +1 -1
- package/src/__tests__/persona-resolver.test.ts +39 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +1 -1
- package/src/__tests__/playbook-execution.test.ts +1 -1
- package/src/__tests__/playbook-tools.test.ts +1 -1
- package/src/__tests__/plugin-api-model-profiles.test.ts +74 -21
- package/src/__tests__/plugin-bootstrap.test.ts +78 -0
- package/src/__tests__/provider-platform-proxy-integration.test.ts +25 -5
- package/src/__tests__/provider-usage-tracking.test.ts +40 -1
- package/src/__tests__/prune-old-conversations-job.test.ts +1 -1
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- package/src/__tests__/registry.test.ts +3 -0
- package/src/__tests__/relay-server.test.ts +1026 -73
- package/src/__tests__/runtime-attachment-metadata.test.ts +9 -1
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +7 -9
- package/src/__tests__/runtime-events-sse-parity.test.ts +1 -1
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +1 -1
- package/src/__tests__/runtime-events-sse.test.ts +1 -1
- package/src/__tests__/schedule-retry.test.ts +1 -1
- package/src/__tests__/schedule-routes-workflow-validation.test.ts +1 -1
- package/src/__tests__/schedule-routes.test.ts +1 -1
- package/src/__tests__/schedule-store.test.ts +1 -1
- package/src/__tests__/schedule-tools.test.ts +1 -1
- package/src/__tests__/scheduler-disk-pressure.test.ts +1 -1
- package/src/__tests__/scheduler-recurrence.test.ts +1 -1
- package/src/__tests__/scheduler-reuse-conversation.test.ts +1 -1
- package/src/__tests__/scheduler-wake.test.ts +2 -1
- package/src/__tests__/scoped-approval-grants.test.ts +1 -1
- package/src/__tests__/scoped-grant-security-matrix.test.ts +5 -5
- package/src/__tests__/scrub-corrupted-image-attachments.test.ts +0 -8
- package/src/__tests__/secret-ingress-http.test.ts +12 -0
- package/src/__tests__/secret-routes-platform-proxy.test.ts +1 -0
- package/src/__tests__/send-endpoint-busy.test.ts +31 -9
- package/src/__tests__/sequence-store.test.ts +1 -1
- package/src/__tests__/server-history-render.test.ts +40 -1
- package/src/__tests__/settings-routes.test.ts +11 -10
- package/src/__tests__/skill-load-tool.test.ts +72 -0
- package/src/__tests__/skills.test.ts +44 -0
- package/src/__tests__/slack-inbound-verification.test.ts +48 -5
- package/src/__tests__/slack-messaging-token-resolution.test.ts +13 -2
- package/src/__tests__/slack-reaction-canonical-approval.test.ts +1 -1
- package/src/__tests__/sse-actor-principal-guardian-source.test.ts +102 -0
- package/src/__tests__/steer-on-enqueue-question.test.ts +181 -0
- package/src/__tests__/stt-hints.test.ts +44 -13
- package/src/__tests__/subagent-detail.test.ts +27 -0
- package/src/__tests__/subagent-disposal.test.ts +65 -0
- package/src/__tests__/subagent-tool-gate-mode.test.ts +2 -73
- package/src/__tests__/subagent-tools.test.ts +1 -31
- package/src/__tests__/system-prompt.test.ts +1 -1
- package/src/__tests__/system-storage-cleanup-skill.test.ts +56 -0
- package/src/__tests__/task-compiler.test.ts +1 -1
- package/src/__tests__/task-management-tools.test.ts +1 -1
- package/src/__tests__/task-memory-cleanup.test.ts +9 -6
- package/src/__tests__/task-scheduler.test.ts +1 -1
- package/src/__tests__/thread-backfill.test.ts +1 -1
- package/src/__tests__/tool-approval-handler.test.ts +1 -1
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +2 -0
- package/src/__tests__/tool-executor.test.ts +37 -1
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -2
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +73 -1
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +34 -34
- package/src/__tests__/trusted-contact-multichannel.test.ts +1 -2
- package/src/__tests__/trusted-contact-verification.test.ts +1 -1
- package/src/__tests__/turn-boundary-resolution.test.ts +3 -3
- package/src/__tests__/turn-events-store.test.ts +1 -1
- package/src/__tests__/twilio-routes.test.ts +98 -3
- package/src/__tests__/usage-cache-backfill-migration.test.ts +20 -10
- package/src/__tests__/usage-routes.test.ts +1 -1
- package/src/__tests__/user-plugin-loader.test.ts +34 -29
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -2
- package/src/__tests__/voice-invite-redemption.test.ts +134 -36
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +1 -1
- package/src/__tests__/voice-session-bridge.test.ts +1 -1
- package/src/__tests__/workspace-git-service.test.ts +114 -1
- package/src/__tests__/workspace-heartbeat-service.test.ts +45 -0
- package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +1 -1
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +1 -1
- package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +88 -18
- package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +6 -6
- package/src/__tests__/workspace-migration-109-swap-quality-profile-to-glm-5p2.test.ts +281 -0
- package/src/__tests__/workspace-migration-110-flip-balanced-profile-to-together.test.ts +167 -0
- package/src/__tests__/workspace-migrations-runner.test.ts +55 -0
- package/src/__tests__/workspace-tool-loader.test.ts +3 -0
- package/src/a2a/__tests__/e2e-a2a-channel.test.ts +1 -1
- package/src/a2a/__tests__/task-store.test.ts +1 -1
- package/src/acp/__tests__/session-manager-persistence.test.ts +1 -1
- package/src/acp/__tests__/session-manager-resume.test.ts +22 -11
- package/src/acp/__tests__/session-manager-startup.test.ts +1 -1
- package/src/acp/__tests__/session-manager.test.ts +72 -1
- package/src/acp/index.ts +10 -0
- package/src/acp/session-manager.ts +35 -0
- package/src/agent/loop-exclusive-tool.test.ts +150 -0
- package/src/agent/loop.ts +101 -27
- package/src/api/constants/sse-replay.ts +41 -0
- package/src/api/events/ui-surface-show.ts +8 -3
- package/src/api/index.ts +7 -6
- package/src/api/responses/conversation-message.ts +4 -0
- package/src/api/responses/llm-request-log-entry.ts +25 -0
- package/src/api/responses/subagent-detail.ts +17 -0
- package/src/api/surfaces.ts +33 -0
- package/src/approvals/AGENTS.md +1 -2
- package/src/approvals/guardian-decision-primitive.ts +13 -210
- package/src/approvals/guardian-request-resolvers.ts +104 -58
- package/src/background-wake/wake-intent-hooks.test.ts +1 -1
- package/src/calls/__tests__/inbound-trust-reader.test.ts +110 -0
- package/src/calls/__tests__/relay-setup-router.test.ts +349 -65
- package/src/calls/guardian-dispatch.ts +10 -8
- package/src/calls/inbound-trust-reader.ts +56 -0
- package/src/calls/media-stream-server.ts +21 -0
- package/src/calls/relay-server.ts +231 -72
- package/src/calls/relay-setup-router.ts +57 -13
- package/src/calls/relay-verification.ts +7 -7
- package/src/calls/stt-hints.ts +9 -12
- package/src/calls/twilio-routes.ts +13 -3
- package/src/cli/commands/__tests__/cache.test.ts +8 -1
- package/src/cli/commands/cache.ts +194 -181
- package/src/cli/commands/contacts.ts +6 -24
- package/src/cli/commands/db/__tests__/repair.test.ts +15 -6
- package/src/cli/commands/db/__tests__/status.test.ts +7 -3
- package/src/cli/commands/db/status.ts +212 -33
- package/src/cli/commands/mcp.ts +252 -218
- package/src/cli/commands/memory/__tests__/memory-v3.test.ts +6 -1
- package/src/cli/commands/memory/__tests__/worker.test.ts +302 -0
- package/src/cli/commands/memory/index.ts +4 -0
- package/src/cli/commands/memory/memory-retrospective.ts +129 -0
- package/src/cli/commands/memory/memory-v3.ts +176 -4
- package/src/cli/commands/memory/worker.ts +175 -0
- package/src/cli/commands/plugins.ts +343 -14
- package/src/cli/lib/__tests__/install-from-github.test.ts +40 -0
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +160 -1
- package/src/cli/lib/__tests__/plugin-pin-history.test.ts +162 -0
- package/src/cli/lib/__tests__/toggle-plugin.test.ts +158 -0
- package/src/cli/lib/install-from-github.ts +47 -6
- package/src/cli/lib/list-installed-plugins.ts +179 -1
- package/src/cli/lib/plugin-marketplace.ts +11 -0
- package/src/cli/lib/plugin-pin-history.ts +257 -0
- package/src/cli/lib/toggle-plugin.ts +146 -0
- package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +143 -0
- package/src/config/__tests__/sync-gated-profiles.test.ts +2 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +15 -33
- package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +3 -8
- package/src/config/bundled-skills/app-builder/references/INTERACTION_HOOKS.md +64 -37
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +1 -1
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +14 -72
- package/src/config/bundled-skills/app-builder/references/examples/README.md +1 -2
- package/src/config/bundled-skills/contacts/SKILL.md +7 -12
- package/src/config/bundled-skills/messaging/tools/shared.ts +4 -1
- package/src/config/bundled-skills/system-storage-cleanup/SKILL.md +74 -0
- package/src/config/bundled-skills/workflows/SKILL.md +4 -3
- package/src/config/call-site-defaults.ts +11 -2
- package/src/config/feature-flag-registry.json +0 -8
- package/src/config/llm-resolver.ts +151 -14
- package/src/config/loader.ts +36 -5
- package/src/config/profile-dispatchability.ts +11 -0
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/call-site-catalog.ts +7 -0
- package/src/config/schemas/llm.ts +2 -0
- package/src/config/schemas/memory-lifecycle.ts +17 -3
- package/src/config/schemas/memory-v3.ts +7 -0
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/timeouts.ts +32 -0
- package/src/config/seed-inference-profiles.ts +147 -50
- package/src/config/skills.ts +27 -5
- package/src/config/sync-gated-profiles.ts +13 -1
- package/src/contacts/__tests__/guardian-delivery-reader.test.ts +312 -0
- package/src/contacts/contact-store.ts +21 -0
- package/src/contacts/contacts-write.ts +3 -0
- package/src/contacts/guardian-delivery-reader.ts +223 -0
- package/src/contacts/member-status.ts +9 -0
- package/src/credential-health/credential-health-service.ts +1 -5
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +44 -0
- package/src/daemon/app-source-watcher.ts +31 -18
- package/src/daemon/assistant-attachments.ts +94 -4
- package/src/daemon/conversation-agent-loop-handlers.ts +3 -0
- package/src/daemon/conversation-agent-loop.ts +18 -36
- package/src/daemon/conversation-process.ts +35 -16
- package/src/daemon/conversation-runtime-assembly.ts +91 -66
- package/src/daemon/conversation-surfaces.ts +273 -18
- package/src/daemon/conversation-tool-setup.ts +24 -64
- package/src/daemon/conversation.ts +149 -53
- package/src/daemon/disk-pressure-guard.ts +12 -2
- package/src/daemon/event-loop-watchdog.test.ts +85 -0
- package/src/daemon/event-loop-watchdog.ts +133 -0
- package/src/daemon/external-plugins-bootstrap.ts +26 -80
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +1 -1
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +1 -1
- package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +1 -1
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +1 -1
- package/src/daemon/handlers/__tests__/config-a2a.test.ts +1 -1
- package/src/daemon/handlers/config-channels.ts +41 -27
- package/src/daemon/handlers/conversations.ts +84 -0
- package/src/daemon/handlers/shared.ts +7 -0
- package/src/daemon/lifecycle.ts +44 -5
- package/src/daemon/memory-v2-startup.test.ts +72 -0
- package/src/daemon/memory-v2-startup.ts +87 -19
- package/src/daemon/message-types/inbox.ts +0 -6
- package/src/daemon/message-types/messages.ts +0 -4
- package/src/daemon/message-types/surfaces.ts +12 -11
- package/src/daemon/server.ts +0 -4
- package/src/daemon/shutdown-handlers.ts +20 -0
- package/src/daemon/tool-setup-types.ts +7 -5
- package/src/daemon/trust-context.ts +6 -0
- package/src/daemon/wake-conversation-ops.ts +70 -0
- package/src/daemon/workspace-tools-watcher.ts +7 -3
- package/src/documents/document-comments-store.test.ts +1 -1
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +1 -1
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +6 -0
- package/src/heartbeat/heartbeat-service.ts +3 -4
- package/src/ipc/__tests__/attachment-ipc.test.ts +1 -1
- package/src/ipc/__tests__/browser-ipc.test.ts +73 -2
- package/src/ipc/__tests__/clients-list-ipc.test.ts +1 -1
- package/src/ipc/__tests__/watcher-ipc.test.ts +59 -39
- package/src/ipc/assistant-server.ts +10 -2
- package/src/ipc/gateway-client.ts +2 -1
- package/src/ipc/routes/__tests__/invite-ipc-routes.test.ts +58 -0
- package/src/ipc/routes/invite-ipc-routes.ts +66 -0
- package/src/live-voice/__tests__/live-voice-archive.test.ts +1 -1
- package/src/memory/__tests__/activation-session-store.test.ts +1 -1
- package/src/memory/__tests__/auto-analysis-guard.test.ts +1 -1
- package/src/memory/__tests__/conversation-group-migration.test.ts +1 -1
- package/src/memory/__tests__/conversation-queries.test.ts +1 -1
- package/src/memory/__tests__/db-async-query.test.ts +1 -1
- package/src/memory/__tests__/db-logs-attach.test.ts +110 -0
- package/src/memory/__tests__/db-maintenance.test.ts +28 -36
- package/src/memory/__tests__/db-memory-attach.test.ts +113 -0
- package/src/memory/__tests__/find-analysis-conversation.test.ts +1 -1
- package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +1 -1
- package/src/memory/__tests__/fork-message-copy.test.ts +232 -0
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +3 -0
- package/src/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +5 -5
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +8 -6
- package/src/memory/__tests__/memory-retrospective-job.test.ts +30 -37
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +69 -66
- package/src/memory/__tests__/memory-retrospective-state.test.ts +1 -1
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -1
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +1 -1
- package/src/memory/__tests__/onboarding-events-store.test.ts +1 -1
- package/src/memory/__tests__/prompt-override.test.ts +192 -0
- package/src/memory/__tests__/table-relocation.test.ts +129 -0
- package/src/memory/conversation-crud.ts +461 -152
- package/src/memory/db-async-query.ts +89 -5
- package/src/memory/db-connection.ts +101 -18
- package/src/memory/db-init.ts +409 -234
- package/src/memory/db-maintenance.ts +43 -38
- package/src/memory/db-singleton.ts +45 -19
- package/src/memory/embedding-gemini.test.ts +3 -1
- package/src/memory/embedding-gemini.ts +18 -2
- package/src/memory/fork-message-copy.ts +170 -0
- package/src/memory/graph/__tests__/handle-remember-v2.test.ts +92 -0
- package/src/memory/graph/bootstrap.test.ts +6 -3
- package/src/memory/graph/retriever.test.ts +12 -12
- package/src/memory/graph/store.test.ts +15 -25
- package/src/memory/graph/store.ts +23 -14
- package/src/memory/graph/tool-handlers.ts +34 -5
- package/src/memory/graph/tools.ts +5 -2
- package/src/memory/indexer.ts +21 -9
- package/src/memory/job-handlers/cleanup.ts +10 -3
- package/src/memory/job-handlers/embedding.test.ts +4 -4
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +4 -4
- package/src/memory/jobs/embed-pkb-file.test.ts +7 -7
- package/src/memory/jobs-store.ts +36 -24
- package/src/memory/llm-request-log-store.ts +51 -19
- package/src/memory/llm-usage-store.ts +79 -21
- package/src/memory/memory-retrospective-job.ts +27 -19
- package/src/memory/memory-retrospective-startup-cleanup.ts +10 -2
- package/src/memory/migrations/{100-core-tables.ts → 000-core-tables.ts} +6 -10
- package/src/memory/migrations/014-backfill-inbox-thread-state.ts +13 -3
- package/src/memory/migrations/104-core-indexes.ts +1 -1
- package/src/memory/migrations/126-backfill-guardian-principal-id.ts +189 -196
- package/src/memory/migrations/127-guardian-principal-id-not-null.ts +98 -105
- package/src/memory/migrations/134-contacts-notes-column.ts +66 -69
- package/src/memory/migrations/135-backfill-contact-interaction-stats.ts +19 -22
- package/src/memory/migrations/136-drop-assistant-id-columns.ts +241 -219
- package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +204 -209
- package/src/memory/migrations/141-rename-verification-table.ts +45 -48
- package/src/memory/migrations/142-rename-verification-session-id-column.ts +16 -23
- package/src/memory/migrations/143-rename-guardian-verification-values.ts +23 -30
- package/src/memory/migrations/144-rename-voice-to-phone.ts +133 -136
- package/src/memory/migrations/145-drop-accounts-table.ts +4 -7
- package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +79 -82
- package/src/memory/migrations/148-drop-reminders-table.ts +3 -6
- package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +71 -78
- package/src/memory/migrations/157-invite-contact-id.ts +73 -76
- package/src/memory/migrations/162-guardian-timestamps-epoch-ms.ts +44 -58
- package/src/memory/migrations/169-rename-gmail-provider-key-to-google.ts +36 -43
- package/src/memory/migrations/174-rename-thread-starters-table.ts +30 -37
- package/src/memory/migrations/176-drop-capability-card-state.ts +17 -22
- package/src/memory/migrations/177-create-trace-events-table.ts +23 -28
- package/src/memory/migrations/180-backfill-inline-attachments-to-disk.ts +36 -43
- package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +14 -21
- package/src/memory/migrations/191-backfill-audio-attachment-mime-types.ts +17 -24
- package/src/memory/migrations/192-contacts-user-file-column.ts +6 -9
- package/src/memory/migrations/193-add-source-type-columns.ts +33 -36
- package/src/memory/migrations/194-memory-recall-logs.ts +34 -39
- package/src/memory/migrations/196-strip-integration-prefix-from-provider-keys.ts +59 -66
- package/src/memory/migrations/199-guardian-request-enrichment-columns.ts +41 -48
- package/src/memory/migrations/204-rename-memory-graph-type-values.ts +11 -18
- package/src/memory/migrations/206-scrub-corrupted-image-attachments.ts +76 -83
- package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +135 -68
- package/src/memory/migrations/211-memory-recall-logs-query-context.ts +6 -11
- package/src/memory/migrations/212-llm-request-logs-created-at-index.ts +4 -9
- package/src/memory/migrations/217-conversation-host-access.ts +13 -18
- package/src/memory/migrations/220-normalize-user-file-by-principal.ts +86 -93
- package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +41 -48
- package/src/memory/migrations/230-acp-session-history.ts +23 -28
- package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +58 -62
- package/src/memory/migrations/232-activation-state.ts +11 -16
- package/src/memory/migrations/233-document-conversations.ts +20 -25
- package/src/memory/migrations/234-memory-v2-activation-logs.ts +26 -31
- package/src/memory/migrations/235-slack-compaction-watermark.ts +5 -10
- package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +6 -11
- package/src/memory/migrations/237-heartbeat-runs.ts +22 -27
- package/src/memory/migrations/239-trace-events-created-at-index.ts +4 -9
- package/src/memory/migrations/242-message-bookmarks.ts +17 -22
- package/src/memory/migrations/245-memory-retrospective-state.ts +8 -13
- package/src/memory/migrations/249-normalize-slack-external-content.ts +37 -41
- package/src/memory/migrations/251-a2a-tasks.ts +27 -32
- package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +12 -17
- package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +10 -15
- package/src/memory/migrations/256-memory-v2-injection-events.ts +70 -74
- package/src/memory/migrations/259-conversation-cleaned-at.ts +4 -9
- package/src/memory/migrations/260-rename-cleaned-at.ts +11 -16
- package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +3 -8
- package/src/memory/migrations/262-memory-v3-coactivation.ts +21 -26
- package/src/memory/migrations/263-memory-v3-auto-edges.ts +14 -19
- package/src/memory/migrations/270-schedule-description.ts +7 -12
- package/src/memory/migrations/272-acp-session-history-cwd.ts +8 -13
- package/src/memory/migrations/281-memory-retrospective-remembered-log.ts +8 -13
- package/src/memory/migrations/297-move-llm-request-logs-to-logs-db.ts +111 -0
- package/src/memory/migrations/298-move-memory-jobs-to-memory-db.ts +128 -0
- package/src/memory/migrations/299-canonical-guardian-deliveries-conversation-index.ts +19 -0
- package/src/memory/migrations/__tests__/014-backfill-inbox-thread-state.test.ts +108 -0
- package/src/memory/migrations/__tests__/136-drop-assistant-id-columns.test.ts +82 -0
- package/src/memory/migrations/__tests__/209-strip-thinking-from-consolidated.test.ts +224 -0
- package/src/memory/migrations/__tests__/297-move-llm-request-logs.test.ts +180 -0
- package/src/memory/migrations/__tests__/run-migrations.test.ts +333 -7
- package/src/memory/migrations/helpers/relocation.ts +227 -0
- package/src/memory/migrations/registry.ts +63 -0
- package/src/memory/migrations/run-migrations.ts +187 -16
- package/src/memory/migrations/schema-introspection.ts +14 -0
- package/src/memory/migrations/validate-migration-state.ts +50 -145
- package/src/memory/prompt-override.ts +129 -0
- package/src/memory/raw-query.ts +47 -2
- package/src/memory/skill-loaded-events-store.test.ts +1 -1
- package/src/memory/task-memory-cleanup.ts +62 -41
- package/src/memory/tool-executed-events-store.test.ts +1 -1
- package/src/memory/turn-trace-store.test.ts +1 -1
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +16 -15
- package/src/memory/v2/__tests__/cli-command-store.test.ts +25 -0
- package/src/memory/v2/__tests__/harness-compare.test.ts +1 -1
- package/src/memory/v2/__tests__/harness-oracle.test.ts +1 -1
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +1 -1
- package/src/memory/v2/__tests__/skill-store.test.ts +80 -0
- package/src/memory/v2/__tests__/sweep-job.test.ts +2 -2
- package/src/memory/v2/cli-command-store.ts +75 -38
- package/src/memory/v2/prompts/consolidation.ts +13 -82
- package/src/memory/v2/prompts/router.ts +21 -93
- package/src/memory/v2/skill-store.ts +68 -31
- package/src/memory/v3-eval/__tests__/eval-packets.test.ts +38 -0
- package/src/memory/v3-eval/__tests__/eval-tally.test.ts +139 -0
- package/src/memory/v3-eval/eval-packets.ts +197 -12
- package/src/memory/v3-eval/eval-tally.ts +234 -0
- package/src/memory/worker-control.ts +118 -0
- package/src/memory/worker-process.ts +72 -0
- package/src/messaging/provider.ts +10 -0
- package/src/messaging/providers/gmail/adapter.ts +1 -0
- package/src/messaging/providers/gmail/client.ts +13 -0
- package/src/messaging/providers/index.ts +1 -1
- package/src/messaging/providers/slack/send.test.ts +87 -39
- package/src/messaging/providers/slack/send.ts +84 -105
- package/src/notifications/README.md +9 -5
- package/src/notifications/__tests__/broadcaster.test.ts +16 -8
- package/src/notifications/__tests__/connected-channels.test.ts +114 -0
- package/src/notifications/__tests__/decision-engine.test.ts +78 -9
- package/src/notifications/__tests__/destination-resolver.test.ts +256 -0
- package/src/notifications/__tests__/deterministic-checks.test.ts +43 -1
- package/src/notifications/adapters/slack.ts +12 -10
- package/src/notifications/approval-card-builder.ts +81 -20
- package/src/notifications/approval-card-data.ts +8 -5
- package/src/notifications/broadcaster.ts +8 -1
- package/src/notifications/canonical-delivery-recorder.ts +7 -5
- package/src/notifications/conversation-candidates.ts +24 -59
- package/src/notifications/copy-composer.ts +48 -68
- package/src/notifications/decision-engine.ts +15 -7
- package/src/notifications/destination-resolver.ts +68 -24
- package/src/notifications/deterministic-checks.ts +19 -16
- package/src/notifications/emit-signal.ts +68 -15
- package/src/notifications/trusted-contact-payloads.ts +70 -0
- package/src/oauth/byo-connection.test.ts +9 -0
- package/src/oauth/connection-resolver.test.ts +174 -6
- package/src/oauth/connection-resolver.ts +132 -5
- package/src/oauth/oauth-store.ts +16 -3
- package/src/oauth/scope-utils.ts +39 -0
- package/src/permissions/question-prompter.test.ts +1 -1
- package/src/permissions/question-prompter.ts +7 -4
- package/src/plugin-api/index.ts +9 -4
- package/src/plugin-api/model-profiles.test.ts +123 -0
- package/src/plugin-api/model-profiles.ts +5 -1
- package/src/plugin-api/vision-support.test.ts +173 -0
- package/src/plugin-api/vision-support.ts +113 -0
- package/src/plugins/defaults/advisor/__tests__/consult.test.ts +90 -0
- package/src/plugins/defaults/advisor/__tests__/context-pack-gating.test.ts +106 -0
- package/src/plugins/defaults/advisor/__tests__/context-pack.test.ts +60 -0
- package/src/plugins/defaults/advisor/consult.ts +65 -6
- package/src/plugins/defaults/advisor/context-pack.ts +288 -0
- package/src/plugins/defaults/advisor/steering.ts +14 -2
- package/src/plugins/defaults/advisor/tools/advisor.ts +32 -5
- package/src/plugins/defaults/compaction/window-manager.ts +45 -64
- package/src/plugins/defaults/empty-response/hooks/post-model-call.ts +13 -4
- package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +441 -0
- package/src/plugins/defaults/image-fallback/hooks/post-tool-use.ts +57 -0
- package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +61 -0
- package/src/plugins/defaults/image-fallback/package.json +14 -0
- package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +108 -0
- package/src/plugins/defaults/image-fallback/src/caption-cache.ts +49 -0
- package/src/plugins/defaults/image-fallback/src/image-persist.ts +56 -0
- package/src/plugins/defaults/image-fallback/src/vision-caption.ts +120 -0
- package/src/plugins/defaults/index.ts +27 -0
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +14 -1
- package/src/plugins/defaults/memory-retrieval/injectors.ts +4 -4
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +134 -5
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +11 -2
- package/src/plugins/defaults/memory-v3-shadow/pool-select.test.ts +146 -0
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +246 -19
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +8 -1
- package/src/plugins/external-plugin-loader.ts +47 -6
- package/src/plugins/mtime-cache.ts +772 -0
- package/src/plugins/pipeline.ts +7 -2
- package/src/plugins/registry.ts +16 -5
- package/src/plugins/user-loader.ts +22 -76
- package/src/prompts/persona-resolver.ts +29 -11
- package/src/prompts/system-prompt.ts +1 -1
- package/src/prompts/templates/system-sections.ts +4 -4
- package/src/providers/__tests__/count-tokens-forwarding.test.ts +98 -0
- package/src/providers/anthropic/client.ts +290 -185
- package/src/providers/call-site-routing.ts +14 -0
- package/src/providers/gemini/client.ts +43 -0
- package/src/providers/inference/adapter-factory.ts +6 -0
- package/src/providers/inference/connections.ts +6 -1
- package/src/providers/model-catalog.ts +53 -0
- package/src/providers/openai/responses-provider.ts +5 -0
- package/src/providers/openrouter/client.ts +5 -0
- package/src/providers/platform-proxy/constants.ts +5 -0
- package/src/providers/provider-send-message.ts +4 -0
- package/src/providers/ratelimit.ts +13 -0
- package/src/providers/retry.ts +14 -0
- package/src/providers/together/client.ts +35 -0
- package/src/providers/types.ts +25 -0
- package/src/providers/usage-tracking.ts +11 -0
- package/src/runtime/AGENTS.md +9 -1
- package/src/runtime/__tests__/agent-wake.test.ts +259 -4
- package/src/runtime/__tests__/guardian-vellum-migration.test.ts +181 -0
- package/src/runtime/__tests__/is-guardian-bound-for-channel.test.ts +64 -0
- package/src/runtime/__tests__/local-principal-trust.test.ts +164 -0
- package/src/runtime/__tests__/slack-block-formatting.test.ts +39 -10
- package/src/runtime/__tests__/trust-verdict-consumer.test.ts +670 -0
- package/src/runtime/access-request-helper.ts +19 -39
- package/src/runtime/actor-trust-resolver.ts +8 -16
- package/src/runtime/agent-wake.ts +183 -60
- package/src/runtime/anchored-guardian.test.ts +156 -0
- package/src/runtime/anchored-guardian.ts +135 -0
- package/src/runtime/assistant-stream-state.ts +9 -2
- package/src/runtime/auth/__tests__/require-bound-guardian.test.ts +99 -0
- package/src/runtime/auth/require-bound-guardian.ts +21 -11
- package/src/runtime/channel-reply-delivery.ts +6 -3
- package/src/runtime/channel-verification-service.ts +24 -0
- package/src/runtime/guardian-decision-types.ts +3 -22
- package/src/runtime/guardian-vellum-migration.ts +66 -7
- package/src/runtime/http-server.ts +1 -15
- package/src/runtime/invite-redemption-service.ts +155 -6
- package/src/runtime/invite-service.ts +113 -62
- package/src/runtime/local-actor-identity.ts +76 -11
- package/src/runtime/local-principal-trust.ts +52 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +3 -0
- package/src/runtime/pending-interactions.ts +11 -1
- package/src/runtime/routes/__tests__/acp-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +277 -0
- package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +140 -0
- package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +26 -7
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +14 -10
- package/src/runtime/routes/__tests__/contact-routes-update-channel-relay.test.ts +164 -0
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +8 -8
- package/src/runtime/routes/__tests__/conversation-surface-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +1 -3
- package/src/runtime/routes/__tests__/invite-relay-routes.test.ts +240 -0
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +4 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +143 -0
- package/src/runtime/routes/__tests__/retrospective-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +163 -0
- package/src/runtime/routes/acp-routes-list.test.ts +4 -0
- package/src/runtime/routes/acp-routes.test.ts +5 -6
- package/src/runtime/routes/attachment-routes.ts +21 -17
- package/src/runtime/routes/browser-routes.ts +19 -1
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +5 -9
- package/src/runtime/routes/channel-verification-routes.ts +13 -2
- package/src/runtime/routes/contact-routes.ts +275 -164
- package/src/runtime/routes/conversation-query-routes.ts +15 -5
- package/src/runtime/routes/conversation-routes.ts +80 -66
- package/src/runtime/routes/conversation-starter-routes.ts +7 -8
- package/src/runtime/routes/events-routes.ts +2 -2
- package/src/runtime/routes/guardian-approval-interception.ts +13 -274
- package/src/runtime/routes/host-app-control-routes.ts +5 -4
- package/src/runtime/routes/host-bash-routes.ts +5 -4
- package/src/runtime/routes/host-browser-routes.ts +9 -11
- package/src/runtime/routes/host-cu-routes.ts +5 -4
- package/src/runtime/routes/host-file-routes.ts +5 -4
- package/src/runtime/routes/host-transfer-routes.ts +6 -6
- package/src/runtime/routes/http-adapter.ts +1 -1
- package/src/runtime/routes/inbound-message-handler.ts +21 -16
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +376 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +86 -64
- package/src/runtime/routes/inbound-stages/admission-policy.ts +20 -5
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +16 -4
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +21 -8
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +14 -3
- package/src/runtime/routes/llm-context-normalization.ts +71 -0
- package/src/runtime/routes/log-export-routes.ts +2 -2
- package/src/runtime/routes/mcp-auth-routes.ts +38 -15
- package/src/runtime/routes/memory-eval-routes.ts +92 -0
- package/src/runtime/routes/memory-item-routes.test.ts +12 -11
- package/src/runtime/routes/migration-routes.ts +51 -40
- package/src/runtime/routes/plugins-routes.ts +164 -8
- package/src/runtime/routes/schedule-routes.ts +1 -0
- package/src/runtime/routes/subagents-routes.ts +5 -0
- package/src/runtime/routes/surface-action-routes.ts +39 -51
- package/src/runtime/routes/usage-routes.ts +3 -0
- package/src/runtime/routes/work-items-routes.test.ts +1 -1
- package/src/runtime/slack-block-formatting.ts +46 -48
- package/src/runtime/trust-verdict-consumer.ts +210 -0
- package/src/schedule/scheduler.ts +6 -9
- package/src/signals/user-message.ts +16 -0
- package/src/subagent/manager.ts +9 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +1 -1
- package/src/tools/ask-question/ask-question-tool.test.ts +89 -52
- package/src/tools/ask-question/ask-question-tool.ts +27 -73
- package/src/tools/browser/__tests__/browser-status.test.ts +20 -0
- package/src/tools/browser/browser-execution.ts +16 -4
- package/src/tools/document/document-comment-tool.test.ts +1 -1
- package/src/tools/executor.ts +15 -3
- package/src/tools/host-terminal/host-shell.ts +28 -9
- package/src/tools/memory/register.test.ts +32 -0
- package/src/tools/skills/load.ts +43 -2
- package/src/tools/subagent/spawn.ts +4 -10
- package/src/tools/terminal/shell.ts +16 -5
- package/src/tools/tool-defaults.ts +2 -0
- package/src/tools/types.ts +18 -2
- package/src/tools/ui-surface/definitions.ts +0 -43
- package/src/util/fs-watcher-error.ts +36 -0
- package/src/util/log-redact.ts +2 -4
- package/src/util/logs-db-path.ts +22 -0
- package/src/util/memory-db-path.ts +23 -0
- package/src/util/platform.ts +5 -0
- package/src/watcher/providers/gmail.ts +7 -2
- package/src/workflows/engine-integration.test.ts +1 -1
- package/src/workflows/engine.test.ts +1 -1
- package/src/workflows/engine.ts +22 -0
- package/src/workflows/fanout-load.test.ts +1 -1
- package/src/workflows/journal-store.test.ts +1 -1
- package/src/workflows/leaf-runner.test.ts +40 -1
- package/src/workflows/leaf-runner.ts +26 -1
- package/src/workspace/git-service.ts +144 -29
- package/src/workspace/migrations/109-swap-quality-profile-to-glm-5p2.ts +121 -0
- package/src/workspace/migrations/110-flip-balanced-profile-to-together.ts +82 -0
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/workspace/migrations/runner.ts +32 -2
- package/src/__tests__/access-request-decision.test.ts +0 -375
- package/src/__tests__/guardian-grant-minting.test.ts +0 -607
- package/src/__tests__/plugin-source-watcher.test.ts +0 -302
- package/src/api/events/turn-profile-auto-routed.ts +0 -28
- package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +0 -107
- package/src/daemon/plugin-source-watcher.ts +0 -278
- package/src/daemon/switch-inference-profile-tool.ts +0 -62
- package/src/memory/guardian-approvals.ts +0 -361
- package/src/memory/migrations/010-ext-conv-bindings-channel-chat-unique.ts +0 -66
- package/src/memory/migrations/038-actor-token-records.ts +0 -45
- package/src/memory/migrations/039-actor-refresh-token-records.ts +0 -57
- package/src/memory/migrations/103-complex-migrations.ts +0 -23
- package/src/memory/migrations/113-late-migrations.ts +0 -30
- package/src/memory/migrations/index.ts +0 -301
- package/src/runtime/routes/access-request-decision.ts +0 -297
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +0 -963
- package/src/runtime/routes/channel-guardian-routes.ts +0 -19
- package/src/runtime/routes/guardian-expiry-sweep.ts +0 -132
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import type { ChannelId } from "../channels/types.js";
|
|
15
|
-
import {
|
|
15
|
+
import { getGuardianDelivery } from "../contacts/guardian-delivery-reader.js";
|
|
16
16
|
import type { ChannelStatus } from "../contacts/types.js";
|
|
17
17
|
import {
|
|
18
18
|
createCanonicalGuardianRequest,
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
import { emitNotificationSignal } from "../notifications/emit-signal.js";
|
|
26
26
|
import type { GuardianResolutionSource } from "../notifications/signal.js";
|
|
27
27
|
import { getLogger } from "../util/logger.js";
|
|
28
|
+
import { resolveAnchoredGuardian } from "./anchored-guardian.js";
|
|
28
29
|
import { GUARDIAN_APPROVAL_TTL_MS } from "./routes/channel-route-shared.js";
|
|
29
30
|
|
|
30
31
|
const log = getLogger("access-request-helper");
|
|
@@ -70,12 +71,12 @@ export type AccessRequestResult =
|
|
|
70
71
|
* trust anchor and only accepts source-channel contacts that match it. This
|
|
71
72
|
* prevents stale or cross-assistant contacts from being bound to the request.
|
|
72
73
|
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
74
|
+
* The canonical store writes complete before this resolves; the notification
|
|
75
|
+
* signal emission is fire-and-forget.
|
|
75
76
|
*/
|
|
76
|
-
export function notifyGuardianOfAccessRequest(
|
|
77
|
+
export async function notifyGuardianOfAccessRequest(
|
|
77
78
|
params: AccessRequestParams,
|
|
78
|
-
): AccessRequestResult {
|
|
79
|
+
): Promise<AccessRequestResult> {
|
|
79
80
|
const {
|
|
80
81
|
canonicalAssistantId,
|
|
81
82
|
sourceChannel,
|
|
@@ -94,40 +95,19 @@ export function notifyGuardianOfAccessRequest(
|
|
|
94
95
|
return { notified: false, reason: "no_sender_id" };
|
|
95
96
|
}
|
|
96
97
|
|
|
97
|
-
// Resolve guardian identity with assistant-anchored strategy
|
|
98
|
-
//
|
|
99
|
-
//
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
// anchored principal. This blocks cross-assistant/stale contact selection.
|
|
111
|
-
const sourceGuardian = findGuardianForChannel(sourceChannel);
|
|
112
|
-
if (
|
|
113
|
-
assistantGuardianPrincipalId &&
|
|
114
|
-
sourceGuardian &&
|
|
115
|
-
sourceGuardian.contact.principalId === assistantGuardianPrincipalId
|
|
116
|
-
) {
|
|
117
|
-
guardianExternalUserId = sourceGuardian.channel.address;
|
|
118
|
-
guardianPrincipalId = sourceGuardian.contact.principalId;
|
|
119
|
-
guardianBindingChannel = sourceGuardian.channel.type;
|
|
120
|
-
guardianResolutionSource = "source-channel-contact";
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Access requests always require a principal. If source-channel resolution
|
|
124
|
-
// did not match the assistant anchor, use the anchored vellum identity.
|
|
125
|
-
if (!guardianPrincipalId && vellumGuardian) {
|
|
126
|
-
guardianExternalUserId = vellumGuardian.channel.address;
|
|
127
|
-
guardianPrincipalId = assistantGuardianPrincipalId ?? null;
|
|
128
|
-
guardianBindingChannel = guardianBindingChannel ?? "vellum";
|
|
129
|
-
guardianResolutionSource = "vellum-anchor";
|
|
130
|
-
}
|
|
98
|
+
// Resolve guardian identity with the assistant-anchored strategy (gateway
|
|
99
|
+
// source-channel match validated against the vellum anchor, else the vellum
|
|
100
|
+
// anchor), with a LOCAL-store fallback when the gateway read is empty.
|
|
101
|
+
const anchored = resolveAnchoredGuardian({
|
|
102
|
+
guardians: await getGuardianDelivery(),
|
|
103
|
+
sourceChannel,
|
|
104
|
+
useLocalFallback: true,
|
|
105
|
+
});
|
|
106
|
+
const guardianExternalUserId = anchored?.address ?? null;
|
|
107
|
+
const guardianPrincipalId = anchored?.principalId ?? null;
|
|
108
|
+
const guardianBindingChannel = anchored?.channelType ?? null;
|
|
109
|
+
const guardianResolutionSource: GuardianResolutionSource =
|
|
110
|
+
anchored?.source ?? "none";
|
|
131
111
|
|
|
132
112
|
log.debug(
|
|
133
113
|
{
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
findContactByAddress,
|
|
22
22
|
findGuardianForChannel,
|
|
23
23
|
} from "../contacts/contact-store.js";
|
|
24
|
+
import { channelStatusToMemberStatus } from "../contacts/member-status.js";
|
|
24
25
|
import type { ContactChannel, ContactWithChannels } from "../contacts/types.js";
|
|
25
26
|
import type { TrustContext } from "../daemon/trust-context.js";
|
|
26
27
|
import { canonicalizeInboundIdentity } from "../util/canonicalize-identity.js";
|
|
@@ -57,22 +58,6 @@ export type TrustClass =
|
|
|
57
58
|
| "unverified_contact"
|
|
58
59
|
| "unknown";
|
|
59
60
|
|
|
60
|
-
/**
|
|
61
|
-
* Trust-class ordinal used by the per-channel admission policy floor check.
|
|
62
|
-
* Higher rank = more trusted. Blocked/revoked never reach classification —
|
|
63
|
-
* their effective rank is 0 and is enforced by the inbound ACL stage's
|
|
64
|
-
* member-status short-circuit, not via this table.
|
|
65
|
-
*
|
|
66
|
-
* See `wave-b-plan.md` §2.4. Paired with `ADMISSION_FLOOR` from
|
|
67
|
-
* `@vellumai/gateway-client` — both tables move together.
|
|
68
|
-
*/
|
|
69
|
-
export const TRUST_CLASS_RANK: Record<TrustClass, number> = {
|
|
70
|
-
guardian: 4,
|
|
71
|
-
trusted_contact: 3,
|
|
72
|
-
unverified_contact: 2,
|
|
73
|
-
unknown: 1,
|
|
74
|
-
};
|
|
75
|
-
|
|
76
61
|
/**
|
|
77
62
|
* Fully resolved trust context from the actor trust resolver.
|
|
78
63
|
*
|
|
@@ -338,5 +323,12 @@ export function toTrustContext(
|
|
|
338
323
|
requesterMemberDisplayName: ctx.actorMetadata.memberDisplayName,
|
|
339
324
|
requesterExternalUserId: ctx.canonicalSenderId ?? undefined,
|
|
340
325
|
requesterChatId: conversationExternalId,
|
|
326
|
+
// Member grounding from the resolved memberRecord (voice + verdict paths
|
|
327
|
+
// both populate it).
|
|
328
|
+
requesterContactId: ctx.memberRecord?.contact.id,
|
|
329
|
+
memberStatus: ctx.memberRecord
|
|
330
|
+
? channelStatusToMemberStatus(ctx.memberRecord.channel.status)
|
|
331
|
+
: undefined,
|
|
332
|
+
memberPolicy: ctx.memberRecord?.channel.policy,
|
|
341
333
|
};
|
|
342
334
|
}
|
|
@@ -14,13 +14,22 @@
|
|
|
14
14
|
* `suppressAutoCompaction: true` to skip it; a suppressed wake whose
|
|
15
15
|
* input exceeds the effective context window fails deterministically
|
|
16
16
|
* with `reason: "context_overflow"` instead of compacting.
|
|
17
|
-
* -
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
17
|
+
* - Hint delivery has two modes:
|
|
18
|
+
* - Default (ephemeral): appends `hint` as a non-persisted assistant
|
|
19
|
+
* message sandwiched between two static user bookends — never shows up
|
|
20
|
+
* in the transcript or SSE feed. The assistant role defangs prompt
|
|
21
|
+
* injection (LLMs don't follow instructions in their own prior output)
|
|
22
|
+
* and the bookends are hardcoded strings with no dynamic content. Suited
|
|
23
|
+
* to wakes carrying arbitrary/untrusted hint text (meet chat
|
|
24
|
+
* opportunities, the explicit wake route).
|
|
25
|
+
* - `persistTriggerAsEvent`: appends the trigger as a SINGLE PERSISTED,
|
|
26
|
+
* transcript-visible user message wrapped in `<background_event>` (any
|
|
27
|
+
* untrusted command output fenced in `<external_content>`). Keeping the
|
|
28
|
+
* trigger in durable, append-only history lets the provider prompt-cache
|
|
29
|
+
* treat repeated wakes like normal user turns instead of re-creating the
|
|
30
|
+
* whole prefix each wake. Used by background-command and scheduled wakes
|
|
31
|
+
* whose `hint` is trusted framing; wakes carrying arbitrary caller hint
|
|
32
|
+
* text stay on the ephemeral trio above.
|
|
24
33
|
* - Invokes the agent loop with all conversation tools available unless
|
|
25
34
|
* the caller provides an explicit `allowedTools` scope.
|
|
26
35
|
* - No tool calls AND no assistant text → silent no-op (nothing persisted,
|
|
@@ -74,6 +83,7 @@ import {
|
|
|
74
83
|
broadcastWakeSurface,
|
|
75
84
|
emitWakeAgentEvent,
|
|
76
85
|
persistWakeTailMessage,
|
|
86
|
+
persistWakeTriggerMessage,
|
|
77
87
|
scopeWakeAllowedTools,
|
|
78
88
|
} from "../daemon/wake-conversation-ops.js";
|
|
79
89
|
import {
|
|
@@ -88,6 +98,10 @@ import {
|
|
|
88
98
|
} from "../memory/llm-request-log-store.js";
|
|
89
99
|
import type { SystemPromptPersonaOverride } from "../prompts/system-prompt.js";
|
|
90
100
|
import type { Message } from "../providers/types.js";
|
|
101
|
+
import {
|
|
102
|
+
type UntrustedContentSource,
|
|
103
|
+
wrapUntrustedContent,
|
|
104
|
+
} from "../security/untrusted-content.js";
|
|
91
105
|
import { getLogger } from "../util/logger.js";
|
|
92
106
|
|
|
93
107
|
const log = getLogger("agent-wake");
|
|
@@ -100,6 +114,46 @@ const WAKE_PREAMBLE =
|
|
|
100
114
|
const WAKE_POSTAMBLE =
|
|
101
115
|
"[system] End of message from external system, continue the conversation.";
|
|
102
116
|
|
|
117
|
+
/** Sanitize a value for use as an XML attribute (no quotes/brackets/newlines). */
|
|
118
|
+
function sanitizeEventAttr(value: string): string {
|
|
119
|
+
return value.replace(/[<>"&\r\n]/g, "").slice(0, 200);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Untrusted third-party output to fence inside a persisted wake trigger via
|
|
124
|
+
* {@link wrapUntrustedContent}. `maxChars` overrides the per-source character
|
|
125
|
+
* budget — used for preformatted shell output that `formatShellOutput` already
|
|
126
|
+
* bounded (to `MAX_OUTPUT_LENGTH`) and appended an `<output_truncated file=…/>`
|
|
127
|
+
* recovery marker to, so the wrapper does not re-truncate that marker off.
|
|
128
|
+
*/
|
|
129
|
+
interface WakeUntrustedOutput {
|
|
130
|
+
content: string;
|
|
131
|
+
source: UntrustedContentSource;
|
|
132
|
+
maxChars?: number;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Build the text for a persisted wake-trigger message: a `<background_event>`
|
|
137
|
+
* wrapper carrying the trusted framing, with any untrusted command output
|
|
138
|
+
* fenced in an `<external_content>` block the model is instructed never to
|
|
139
|
+
* obey. The wrapper signals "a system event woke you" (replacing the legacy
|
|
140
|
+
* `[system] external system` / `[opportunity:…]` bookends); `source` lives in
|
|
141
|
+
* the tag attribute and the message metadata.
|
|
142
|
+
*/
|
|
143
|
+
function buildBackgroundEventText(
|
|
144
|
+
source: string,
|
|
145
|
+
framing: string,
|
|
146
|
+
untrustedOutput?: WakeUntrustedOutput,
|
|
147
|
+
): string {
|
|
148
|
+
const body = untrustedOutput
|
|
149
|
+
? `${framing}\n${wrapUntrustedContent(untrustedOutput.content, {
|
|
150
|
+
source: untrustedOutput.source,
|
|
151
|
+
maxChars: untrustedOutput.maxChars,
|
|
152
|
+
})}`
|
|
153
|
+
: framing;
|
|
154
|
+
return `<background_event source="${sanitizeEventAttr(source)}">\n${body}\n</background_event>`;
|
|
155
|
+
}
|
|
156
|
+
|
|
103
157
|
/**
|
|
104
158
|
* Warn line shared by the two reactive over-window failure sites (provider
|
|
105
159
|
* rejection escaped as a throw / swallowed into a no-output stop). The
|
|
@@ -196,14 +250,6 @@ export interface WakeOptions {
|
|
|
196
250
|
* retrospectives whose conversation title already says "(Retrospective)").
|
|
197
251
|
*/
|
|
198
252
|
suppressWakeSurface?: boolean;
|
|
199
|
-
/**
|
|
200
|
-
* Run the wake's turn as non-interactive (no client present). Threads to the
|
|
201
|
-
* agent loop's `isNonInteractive`, which gates the `<non_interactive_context>`
|
|
202
|
-
* and `<background_turn>` injectors. Fork-based memory retrospectives set this
|
|
203
|
-
* to the source conversation's background-turn state so the fork reproduces
|
|
204
|
-
* the source's injected turn block (prompt-cache prefix parity). Default false.
|
|
205
|
-
*/
|
|
206
|
-
isNonInteractive?: boolean;
|
|
207
253
|
/**
|
|
208
254
|
* Optional exact tool allowlist for this wake. Used by internal maintenance
|
|
209
255
|
* jobs that need the assistant's judgment but must not execute arbitrary
|
|
@@ -249,6 +295,28 @@ export interface WakeOptions {
|
|
|
249
295
|
* class and approval semantics are governed solely by `trustContext`.
|
|
250
296
|
*/
|
|
251
297
|
personaOverride?: SystemPromptPersonaOverride;
|
|
298
|
+
/**
|
|
299
|
+
* Inject the wake's trigger as a SINGLE PERSISTED, transcript-visible user
|
|
300
|
+
* message (wrapped in `<background_event>`) appended to the conversation
|
|
301
|
+
* BEFORE the run, instead of the default ephemeral hint trio. This keeps the
|
|
302
|
+
* message array append-only so the provider prompt-cache behaves like a
|
|
303
|
+
* normal user turn — repeated wakes stop re-creating the whole prefix. The
|
|
304
|
+
* trigger is persisted unconditionally (like a normal user turn's message),
|
|
305
|
+
* even if the wake then produces no reply.
|
|
306
|
+
*
|
|
307
|
+
* `hint` is the trusted framing line; `untrustedOutput`, when given, is
|
|
308
|
+
* appended fenced in `<external_content>` so the model treats command output
|
|
309
|
+
* as data, never instructions. Mutually exclusive with the legacy
|
|
310
|
+
* `hintRole` / `skipHintInjection` injection.
|
|
311
|
+
*/
|
|
312
|
+
persistTriggerAsEvent?: boolean;
|
|
313
|
+
/**
|
|
314
|
+
* Untrusted third-party output (e.g. background-command stdout) to fence
|
|
315
|
+
* inside the persisted trigger via {@link wrapUntrustedContent}. Only
|
|
316
|
+
* consulted when `persistTriggerAsEvent` is set; `hint` stays the trusted
|
|
317
|
+
* framing outside the fence.
|
|
318
|
+
*/
|
|
319
|
+
untrustedOutput?: WakeUntrustedOutput;
|
|
252
320
|
}
|
|
253
321
|
|
|
254
322
|
/**
|
|
@@ -596,7 +664,6 @@ export async function wakeAgentForOpportunity(
|
|
|
596
664
|
opts.forceOverrideProfile ??
|
|
597
665
|
getConversationOverrideProfile(conversationId);
|
|
598
666
|
const callSite = opts.callSite ?? "mainAgent";
|
|
599
|
-
const isNonInteractive = opts.isNonInteractive ?? false;
|
|
600
667
|
const config = getConfig();
|
|
601
668
|
const effectiveContextWindow = resolveEffectiveContextWindow({
|
|
602
669
|
llm: config.llm,
|
|
@@ -606,13 +673,14 @@ export async function wakeAgentForOpportunity(
|
|
|
606
673
|
});
|
|
607
674
|
|
|
608
675
|
// Apply the caller's persona override for the duration of the run. The
|
|
609
|
-
//
|
|
610
|
-
//
|
|
611
|
-
// before drainQueue) so a queued user turn never builds
|
|
612
|
-
// the wake's override. Assigned only AFTER the
|
|
613
|
-
// — those can throw, and they run before the
|
|
614
|
-
// override, so an earlier assignment would
|
|
615
|
-
// cached Conversation and corrupt every later
|
|
676
|
+
// prompt is built once before `agentLoop.run()` (via
|
|
677
|
+
// `conversation.buildCurrentSystemPrompt()`), which reads this field;
|
|
678
|
+
// cleared (below, before drainQueue) so a queued user turn never builds
|
|
679
|
+
// its prompt under the wake's override. Assigned only AFTER the
|
|
680
|
+
// profile/config reads above — those can throw, and they run before the
|
|
681
|
+
// try/finally that clears the override, so an earlier assignment would
|
|
682
|
+
// strand the override on the cached Conversation and corrupt every later
|
|
683
|
+
// prompt build on it.
|
|
616
684
|
if (opts.personaOverride) {
|
|
617
685
|
conversation.wakePersonaOverride = opts.personaOverride;
|
|
618
686
|
}
|
|
@@ -661,6 +729,38 @@ export async function wakeAgentForOpportunity(
|
|
|
661
729
|
}
|
|
662
730
|
}
|
|
663
731
|
|
|
732
|
+
// ── Persisted-trigger injection (append-only wake) ─────────────────
|
|
733
|
+
// Append the trigger as a single VISIBLE user message to the in-memory
|
|
734
|
+
// history AND the DB BEFORE snapshotting the baseline, so the message
|
|
735
|
+
// array stays append-only (prompt-cache parity with a normal user turn)
|
|
736
|
+
// and `baseline` already contains it. Runs after `maybeCompact` (a
|
|
737
|
+
// successful compaction replaces `conversation.messages`) and inside the
|
|
738
|
+
// single-flight lock + processing flag, so no concurrent turn interleaves.
|
|
739
|
+
// Push first, then persist (matching the wake-tail flush idiom); a persist
|
|
740
|
+
// failure is non-fatal — the in-memory push keeps this run's prompt
|
|
741
|
+
// consistent. The trigger is part of `baseline`, so `flushPendingTail`
|
|
742
|
+
// never re-persists it.
|
|
743
|
+
if (opts.persistTriggerAsEvent) {
|
|
744
|
+
const triggerMessage: Message = {
|
|
745
|
+
role: "user",
|
|
746
|
+
content: [
|
|
747
|
+
{
|
|
748
|
+
type: "text",
|
|
749
|
+
text: buildBackgroundEventText(source, hint, opts.untrustedOutput),
|
|
750
|
+
},
|
|
751
|
+
],
|
|
752
|
+
};
|
|
753
|
+
conversation.messages.push(triggerMessage);
|
|
754
|
+
try {
|
|
755
|
+
await persistWakeTriggerMessage(conversation, triggerMessage, source);
|
|
756
|
+
} catch (err) {
|
|
757
|
+
log.warn(
|
|
758
|
+
{ conversationId, source, err },
|
|
759
|
+
"agent-wake: failed to persist wake trigger message; continuing",
|
|
760
|
+
);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
|
|
664
764
|
const baseline = conversation.getMessages();
|
|
665
765
|
// Snapshot the baseline length BEFORE the run starts. Incremental
|
|
666
766
|
// persistence pushes onto `conversation.messages` mid-run, which grows the
|
|
@@ -669,44 +769,46 @@ export async function wakeAgentForOpportunity(
|
|
|
669
769
|
// tail-slice math would skip every message.
|
|
670
770
|
const baselineLength = baseline.length;
|
|
671
771
|
const wakeTrust = buildWakeTrust(opts, diskPressureDecision);
|
|
672
|
-
// Build the hint injection.
|
|
673
|
-
//
|
|
674
|
-
//
|
|
675
|
-
//
|
|
676
|
-
//
|
|
677
|
-
//
|
|
678
|
-
//
|
|
772
|
+
// Build the ephemeral hint injection. `persistTriggerAsEvent` and
|
|
773
|
+
// `skipHintInjection` produce no injection here — the former already
|
|
774
|
+
// appended the trigger as a persisted message above; the latter relies on
|
|
775
|
+
// the caller having persisted an instruction (fork retrospectives). The
|
|
776
|
+
// remaining modes inject a non-persisted hint:
|
|
777
|
+
// - `hintRole === "user"`: single user-role message containing the hint
|
|
778
|
+
// directly. Used by trusted internal callers where the hint reads
|
|
779
|
+
// naturally as an instruction.
|
|
679
780
|
// - default (`hintRole === "assistant"`): sandwich the hint as an
|
|
680
|
-
// assistant message between two hardcoded user bookends. The
|
|
681
|
-
//
|
|
682
|
-
//
|
|
683
|
-
//
|
|
781
|
+
// assistant message between two hardcoded user bookends. The assistant
|
|
782
|
+
// role defangs prompt injection (LLMs don't follow instructions in
|
|
783
|
+
// their own prior output) and the trailing user message satisfies
|
|
784
|
+
// providers that reject assistant prefill.
|
|
684
785
|
const hintRole = opts.hintRole ?? "assistant";
|
|
685
|
-
const wakeMessages: Message[] =
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
786
|
+
const wakeMessages: Message[] =
|
|
787
|
+
opts.persistTriggerAsEvent || opts.skipHintInjection
|
|
788
|
+
? []
|
|
789
|
+
: hintRole === "user"
|
|
790
|
+
? [
|
|
791
|
+
{
|
|
792
|
+
role: "user",
|
|
793
|
+
content: [{ type: "text", text: hint }],
|
|
794
|
+
},
|
|
795
|
+
]
|
|
796
|
+
: [
|
|
797
|
+
{
|
|
798
|
+
role: "user",
|
|
799
|
+
content: [{ type: "text", text: WAKE_PREAMBLE }],
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
role: "assistant",
|
|
803
|
+
content: [
|
|
804
|
+
{ type: "text", text: `[opportunity:${source}] ${hint}` },
|
|
805
|
+
],
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
role: "user",
|
|
809
|
+
content: [{ type: "text", text: WAKE_POSTAMBLE }],
|
|
810
|
+
},
|
|
811
|
+
];
|
|
710
812
|
const wakeHintMessageCount = wakeMessages.length;
|
|
711
813
|
const runInput: Message[] = [...baseline, ...wakeMessages];
|
|
712
814
|
|
|
@@ -1114,6 +1216,19 @@ export async function wakeAgentForOpportunity(
|
|
|
1114
1216
|
};
|
|
1115
1217
|
}
|
|
1116
1218
|
|
|
1219
|
+
// Wakes bypass `runAgentLoopImpl`, which is what stamps the live turn's
|
|
1220
|
+
// call site and override profile onto the conversation for the tool
|
|
1221
|
+
// executor to read. Without stamping them here, `subagent_spawn` (and
|
|
1222
|
+
// usage attribution) see an unstamped context and resolve children under
|
|
1223
|
+
// workspace defaults instead of the profile this wake actually runs
|
|
1224
|
+
// under — so a wake on a conversation pinned to another profile spawns
|
|
1225
|
+
// children under the wrong one. Restored in the `finally` so a queued
|
|
1226
|
+
// user turn or a later background read never inherits the wake's stamps.
|
|
1227
|
+
const priorCallSite = conversation.currentCallSite;
|
|
1228
|
+
const priorTurnOverrideProfile = conversation.currentTurnOverrideProfile;
|
|
1229
|
+
conversation.currentCallSite = callSite;
|
|
1230
|
+
conversation.currentTurnOverrideProfile = overrideProfile;
|
|
1231
|
+
|
|
1117
1232
|
let updatedHistory: Message[];
|
|
1118
1233
|
try {
|
|
1119
1234
|
({ history: updatedHistory } = await conversation.agentLoop.run({
|
|
@@ -1131,7 +1246,6 @@ export async function wakeAgentForOpportunity(
|
|
|
1131
1246
|
trust: wakeTrust,
|
|
1132
1247
|
overrideProfile,
|
|
1133
1248
|
forceOverrideProfile,
|
|
1134
|
-
isNonInteractive,
|
|
1135
1249
|
// The wake's compaction lives in the pre-run gate above
|
|
1136
1250
|
// (`conversation.maybeCompact()`), never in the loop: the in-loop
|
|
1137
1251
|
// budget gate and overflow-recovery ladder stay disabled because
|
|
@@ -1143,6 +1257,9 @@ export async function wakeAgentForOpportunity(
|
|
|
1143
1257
|
maxInputTokens: effectiveContextWindow.maxInputTokens,
|
|
1144
1258
|
overflowRecovery: { enabled: false, safetyMarginRatio: 0 },
|
|
1145
1259
|
}),
|
|
1260
|
+
...(conversation.modelOverride
|
|
1261
|
+
? { model: conversation.modelOverride }
|
|
1262
|
+
: {}),
|
|
1146
1263
|
}));
|
|
1147
1264
|
} catch (err) {
|
|
1148
1265
|
// An over-window throw on a compaction-suppressed wake is the
|
|
@@ -1164,6 +1281,12 @@ export async function wakeAgentForOpportunity(
|
|
|
1164
1281
|
// `processing` and drain the queue.
|
|
1165
1282
|
runError = err instanceof Error ? err : new Error(String(err));
|
|
1166
1283
|
return { invoked: true, producedToolCalls: false };
|
|
1284
|
+
} finally {
|
|
1285
|
+
// Restore the pre-wake values so a queued user turn or background read
|
|
1286
|
+
// never observes the wake's stamps. (`runAgentLoopImpl` re-stamps both
|
|
1287
|
+
// at the start of the next normal turn regardless.)
|
|
1288
|
+
conversation.currentCallSite = priorCallSite;
|
|
1289
|
+
conversation.currentTurnOverrideProfile = priorTurnOverrideProfile;
|
|
1167
1290
|
}
|
|
1168
1291
|
|
|
1169
1292
|
// The loop swallows provider rejections into a graceful no-output
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for `resolveAnchoredGuardian`.
|
|
3
|
+
*
|
|
4
|
+
* Covers the gateway arms (source-channel match validated against the vellum
|
|
5
|
+
* anchor, vellum-anchor fallback), the LOCAL-store fallback when the gateway
|
|
6
|
+
* list is empty, and the cosmetic `requireAnchorPrincipal` guard.
|
|
7
|
+
*/
|
|
8
|
+
import { afterEach, describe, expect, mock, test } from "bun:test";
|
|
9
|
+
|
|
10
|
+
import type { GuardianDelivery } from "@vellumai/gateway-client";
|
|
11
|
+
|
|
12
|
+
// Local store fallback is mocked so we can drive both arms deterministically.
|
|
13
|
+
let localGuardians: Record<
|
|
14
|
+
string,
|
|
15
|
+
{ contact: { principalId: string | null; displayName: string }; channel: { address: string; type: string } } | null
|
|
16
|
+
> = {};
|
|
17
|
+
mock.module("../contacts/contact-store.js", () => ({
|
|
18
|
+
findGuardianForChannel: (channelType: string) =>
|
|
19
|
+
localGuardians[channelType] ?? null,
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
const { resolveAnchoredGuardian } = await import("./anchored-guardian.js");
|
|
23
|
+
|
|
24
|
+
function gw(g: Partial<GuardianDelivery> & { channelType: string; address: string }): GuardianDelivery {
|
|
25
|
+
return {
|
|
26
|
+
contactId: `c-${g.channelType}`,
|
|
27
|
+
status: "active",
|
|
28
|
+
...g,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
afterEach(() => {
|
|
33
|
+
localGuardians = {};
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe("resolveAnchoredGuardian — gateway arm", () => {
|
|
37
|
+
test("source-channel guardian matching the anchor wins", () => {
|
|
38
|
+
const result = resolveAnchoredGuardian({
|
|
39
|
+
guardians: [
|
|
40
|
+
gw({ channelType: "vellum", address: "v-addr", principalId: "p-anchor", displayName: "Vellum" }),
|
|
41
|
+
gw({ channelType: "telegram", address: "tg-addr", principalId: "p-anchor", displayName: "Alice" }),
|
|
42
|
+
],
|
|
43
|
+
sourceChannel: "telegram",
|
|
44
|
+
});
|
|
45
|
+
expect(result).toEqual({
|
|
46
|
+
principalId: "p-anchor",
|
|
47
|
+
address: "tg-addr",
|
|
48
|
+
displayName: "Alice",
|
|
49
|
+
channelType: "telegram",
|
|
50
|
+
source: "source-channel-contact",
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("source-channel guardian NOT matching the anchor falls back to vellum-anchor", () => {
|
|
55
|
+
const result = resolveAnchoredGuardian({
|
|
56
|
+
guardians: [
|
|
57
|
+
gw({ channelType: "vellum", address: "v-addr", principalId: "p-anchor", displayName: "Vellum" }),
|
|
58
|
+
gw({ channelType: "telegram", address: "tg-addr", principalId: "p-other", displayName: "Stale" }),
|
|
59
|
+
],
|
|
60
|
+
sourceChannel: "telegram",
|
|
61
|
+
});
|
|
62
|
+
expect(result).toEqual({
|
|
63
|
+
principalId: "p-anchor",
|
|
64
|
+
address: "v-addr",
|
|
65
|
+
displayName: "Vellum",
|
|
66
|
+
channelType: "vellum",
|
|
67
|
+
source: "vellum-anchor",
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test("no source-channel guardian falls back to vellum-anchor", () => {
|
|
72
|
+
const result = resolveAnchoredGuardian({
|
|
73
|
+
guardians: [
|
|
74
|
+
gw({ channelType: "vellum", address: "v-addr", principalId: "p-anchor", displayName: "Vellum" }),
|
|
75
|
+
],
|
|
76
|
+
sourceChannel: "telegram",
|
|
77
|
+
});
|
|
78
|
+
expect(result?.source).toBe("vellum-anchor");
|
|
79
|
+
expect(result?.principalId).toBe("p-anchor");
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe("resolveAnchoredGuardian — local fallback", () => {
|
|
84
|
+
test("gateway empty + local source-channel match returns the local record", () => {
|
|
85
|
+
localGuardians = {
|
|
86
|
+
vellum: { contact: { principalId: "p-local", displayName: "LocalVellum" }, channel: { address: "lv-addr", type: "vellum" } },
|
|
87
|
+
telegram: { contact: { principalId: "p-local", displayName: "LocalAlice" }, channel: { address: "ltg-addr", type: "telegram" } },
|
|
88
|
+
};
|
|
89
|
+
const result = resolveAnchoredGuardian({
|
|
90
|
+
guardians: null,
|
|
91
|
+
sourceChannel: "telegram",
|
|
92
|
+
useLocalFallback: true,
|
|
93
|
+
});
|
|
94
|
+
expect(result).toEqual({
|
|
95
|
+
principalId: "p-local",
|
|
96
|
+
address: "ltg-addr",
|
|
97
|
+
displayName: "LocalAlice",
|
|
98
|
+
channelType: "telegram",
|
|
99
|
+
source: "source-channel-contact",
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test("gateway empty + only local vellum returns the local vellum-anchor", () => {
|
|
104
|
+
localGuardians = {
|
|
105
|
+
vellum: { contact: { principalId: "p-local", displayName: "LocalVellum" }, channel: { address: "lv-addr", type: "vellum" } },
|
|
106
|
+
};
|
|
107
|
+
const result = resolveAnchoredGuardian({
|
|
108
|
+
guardians: null,
|
|
109
|
+
sourceChannel: "telegram",
|
|
110
|
+
useLocalFallback: true,
|
|
111
|
+
});
|
|
112
|
+
expect(result?.source).toBe("vellum-anchor");
|
|
113
|
+
expect(result?.address).toBe("lv-addr");
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test("gateway empty + no local + fallback disabled returns null", () => {
|
|
117
|
+
const result = resolveAnchoredGuardian({
|
|
118
|
+
guardians: null,
|
|
119
|
+
sourceChannel: "telegram",
|
|
120
|
+
});
|
|
121
|
+
expect(result).toBeNull();
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test("nothing anywhere returns null", () => {
|
|
125
|
+
const result = resolveAnchoredGuardian({
|
|
126
|
+
guardians: [],
|
|
127
|
+
sourceChannel: "telegram",
|
|
128
|
+
useLocalFallback: true,
|
|
129
|
+
});
|
|
130
|
+
expect(result).toBeNull();
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe("resolveAnchoredGuardian — requireAnchorPrincipal (cosmetic label)", () => {
|
|
135
|
+
test("vellum guardian with a null principal degrades to null", () => {
|
|
136
|
+
const result = resolveAnchoredGuardian({
|
|
137
|
+
guardians: [
|
|
138
|
+
gw({ channelType: "vellum", address: "v-addr", principalId: null, displayName: "Vellum" }),
|
|
139
|
+
],
|
|
140
|
+
sourceChannel: "telegram",
|
|
141
|
+
requireAnchorPrincipal: true,
|
|
142
|
+
});
|
|
143
|
+
expect(result).toBeNull();
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
test("without requireAnchorPrincipal a null-principal vellum still resolves", () => {
|
|
147
|
+
const result = resolveAnchoredGuardian({
|
|
148
|
+
guardians: [
|
|
149
|
+
gw({ channelType: "vellum", address: "v-addr", principalId: null, displayName: "Vellum" }),
|
|
150
|
+
],
|
|
151
|
+
sourceChannel: "telegram",
|
|
152
|
+
});
|
|
153
|
+
expect(result?.source).toBe("vellum-anchor");
|
|
154
|
+
expect(result?.principalId).toBeNull();
|
|
155
|
+
});
|
|
156
|
+
});
|