@vellumai/assistant 0.10.0 → 0.10.1-dev.202606240206.7c2bca6
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-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 +1 -1
- package/src/__tests__/prune-old-conversations-job.test.ts +1 -1
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- 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/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.ts +45 -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 +145 -52
- 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 +46 -0
- package/src/plugins/defaults/advisor/consult.ts +18 -1
- package/src/plugins/defaults/advisor/tools/advisor.ts +4 -0
- 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 +285 -185
- package/src/providers/call-site-routing.ts +10 -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/platform-proxy/constants.ts +5 -0
- package/src/providers/ratelimit.ts +9 -0
- package/src/providers/retry.ts +10 -0
- package/src/providers/together/client.ts +35 -0
- package/src/providers/types.ts +16 -0
- package/src/providers/usage-tracking.ts +7 -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/types.ts +1 -0
- 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
|
@@ -7,12 +7,9 @@ import type { AdmissionPolicy, SourceMetadata } from "@vellumai/gateway-client";
|
|
|
7
7
|
|
|
8
8
|
import { isInviteCodeRedemptionEnabled } from "../../../channels/config.js";
|
|
9
9
|
import type { ChannelId } from "../../../channels/types.js";
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
findGuardianForChannel,
|
|
13
|
-
} from "../../../contacts/contact-store.js";
|
|
10
|
+
import { getGuardianDelivery } from "../../../contacts/guardian-delivery-reader.js";
|
|
11
|
+
import { channelStatusToMemberStatus } from "../../../contacts/member-status.js";
|
|
14
12
|
import type {
|
|
15
|
-
ChannelStatus,
|
|
16
13
|
ContactChannel,
|
|
17
14
|
ContactWithChannels,
|
|
18
15
|
} from "../../../contacts/types.js";
|
|
@@ -28,6 +25,7 @@ import { getLogger } from "../../../util/logger.js";
|
|
|
28
25
|
import { truncate } from "../../../util/truncate.js";
|
|
29
26
|
import { hashVoiceCode } from "../../../util/voice-code.js";
|
|
30
27
|
import { notifyGuardianOfAccessRequest } from "../../access-request-helper.js";
|
|
28
|
+
import { resolveAnchoredGuardian } from "../../anchored-guardian.js";
|
|
31
29
|
import { getInviteAdapterRegistry } from "../../channel-invite-transport.js";
|
|
32
30
|
import {
|
|
33
31
|
createOutboundSession,
|
|
@@ -41,6 +39,7 @@ import {
|
|
|
41
39
|
redeemInviteByCode,
|
|
42
40
|
} from "../../invite-redemption-service.js";
|
|
43
41
|
import { getInviteRedemptionReply } from "../../invite-redemption-templates.js";
|
|
42
|
+
import { resolvedMemberFromVerdict } from "../../trust-verdict-consumer.js";
|
|
44
43
|
|
|
45
44
|
const log = getLogger("runtime-http");
|
|
46
45
|
|
|
@@ -48,28 +47,20 @@ const log = getLogger("runtime-http");
|
|
|
48
47
|
* Resolve the guardian's display name for use in requester-facing messages.
|
|
49
48
|
*
|
|
50
49
|
* Uses the assistant's anchored vellum principal to validate the guardian
|
|
51
|
-
*
|
|
52
|
-
* This prevents stale or cross-assistant
|
|
50
|
+
* binding, matching the same strategy used by `notifyGuardianOfAccessRequest`.
|
|
51
|
+
* This prevents stale or cross-assistant bindings from leaking a wrong name.
|
|
52
|
+
* Cosmetic copy, not an admission decision, so a null gateway list degrades
|
|
53
|
+
* gracefully to the default reference.
|
|
53
54
|
*/
|
|
54
|
-
function resolveGuardianLabel(sourceChannel: ChannelId): string {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
// matches the assistant's anchor.
|
|
64
|
-
const sourceGuardian = findGuardianForChannel(sourceChannel);
|
|
65
|
-
if (
|
|
66
|
-
sourceGuardian &&
|
|
67
|
-
sourceGuardian.contact.principalId === anchoredPrincipalId
|
|
68
|
-
) {
|
|
69
|
-
return resolveGuardianName(sourceGuardian.contact.displayName);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return resolveGuardianName(vellumGuardian.contact.displayName);
|
|
55
|
+
async function resolveGuardianLabel(sourceChannel: ChannelId): Promise<string> {
|
|
56
|
+
// Cosmetic copy, not an admission decision: no local-store fallback, and a
|
|
57
|
+
// missing anchor principal degrades to the default reference.
|
|
58
|
+
const anchored = resolveAnchoredGuardian({
|
|
59
|
+
guardians: await getGuardianDelivery(),
|
|
60
|
+
sourceChannel,
|
|
61
|
+
requireAnchorPrincipal: true,
|
|
62
|
+
});
|
|
63
|
+
return resolveGuardianName(anchored?.displayName);
|
|
73
64
|
}
|
|
74
65
|
|
|
75
66
|
// ---------------------------------------------------------------------------
|
|
@@ -122,14 +113,6 @@ export interface AclResult {
|
|
|
122
113
|
isValidatedBootstrap?: boolean;
|
|
123
114
|
}
|
|
124
115
|
|
|
125
|
-
/** Map ChannelStatus to the API-facing member status (excludes "unverified"). */
|
|
126
|
-
export function channelStatusToMemberStatus(
|
|
127
|
-
status: ChannelStatus,
|
|
128
|
-
): Exclude<ChannelStatus, "unverified"> {
|
|
129
|
-
if (status === "unverified") return "pending";
|
|
130
|
-
return status;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
116
|
/**
|
|
134
117
|
* Enforce ingress ACL rules: member lookup, non-member/inactive denial,
|
|
135
118
|
* policy enforcement (allow/deny/escalate bypass), invite token intercepts,
|
|
@@ -164,7 +147,63 @@ export async function enforceIngressAcl(
|
|
|
164
147
|
// Slack message timestamp for permalink construction.
|
|
165
148
|
const messageTs = sourceMetadata?.messageId ?? undefined;
|
|
166
149
|
|
|
167
|
-
|
|
150
|
+
// Absent verdict = gateway could not vouch for this actor → fail-closed deny.
|
|
151
|
+
// A PRESENT verdict with no member (stranger) still flows through the
|
|
152
|
+
// intercepts below; only a missing verdict short-circuits here.
|
|
153
|
+
const verdict = sourceMetadata?.trustVerdict;
|
|
154
|
+
if (verdict == null) {
|
|
155
|
+
log.info(
|
|
156
|
+
{ sourceChannel, externalUserId: canonicalSenderId },
|
|
157
|
+
"Ingress ACL: absent trust verdict, denying fail-closed",
|
|
158
|
+
);
|
|
159
|
+
return {
|
|
160
|
+
resolvedMember: null,
|
|
161
|
+
earlyResponse: {
|
|
162
|
+
accepted: true,
|
|
163
|
+
denied: true,
|
|
164
|
+
reason: "not_a_member",
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Gateway attempted resolution but failed (DB error) → fail-closed deny,
|
|
170
|
+
// distinct from an absent verdict and from a real stranger. TEXT does not
|
|
171
|
+
// fall back to local ACL reads; the sender can retry.
|
|
172
|
+
if (verdict.resolutionFailed === true) {
|
|
173
|
+
log.warn(
|
|
174
|
+
{ sourceChannel, externalUserId: canonicalSenderId },
|
|
175
|
+
"Ingress ACL: gateway trust resolution failed, denying fail-closed",
|
|
176
|
+
);
|
|
177
|
+
return {
|
|
178
|
+
resolvedMember: null,
|
|
179
|
+
earlyResponse: {
|
|
180
|
+
accepted: true,
|
|
181
|
+
denied: true,
|
|
182
|
+
reason: "not_a_member",
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Member resolved from the gateway verdict (ACL + identity only); null for a
|
|
188
|
+
// stranger verdict, which falls through to the non-member intercepts.
|
|
189
|
+
const resolvedMember: ResolvedMember | null = resolvedMemberFromVerdict(verdict);
|
|
190
|
+
|
|
191
|
+
// A verdict carrying member identity but no resolvable member
|
|
192
|
+
// (malformed/unknown ACL) fails closed, not treated as a stranger.
|
|
193
|
+
if (!resolvedMember && (verdict.contactId || verdict.channelId)) {
|
|
194
|
+
log.info(
|
|
195
|
+
{ sourceChannel, externalUserId: canonicalSenderId },
|
|
196
|
+
"Ingress ACL: member verdict with unresolvable ACL, denying fail-closed",
|
|
197
|
+
);
|
|
198
|
+
return {
|
|
199
|
+
resolvedMember: null,
|
|
200
|
+
earlyResponse: {
|
|
201
|
+
accepted: true,
|
|
202
|
+
denied: true,
|
|
203
|
+
reason: "not_a_member",
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
}
|
|
168
207
|
|
|
169
208
|
// /start gv_<token> bootstrap commands must also bypass ACL — the user
|
|
170
209
|
// hasn't been verified yet and needs to complete the bootstrap handshake.
|
|
@@ -181,23 +220,6 @@ export async function enforceIngressAcl(
|
|
|
181
220
|
});
|
|
182
221
|
|
|
183
222
|
if (canonicalSenderId || hasSenderIdentityClaim) {
|
|
184
|
-
// Only perform member lookup when we have a usable canonical ID.
|
|
185
|
-
// Whitespace-only senders (hasSenderIdentityClaim=true but
|
|
186
|
-
// canonicalSenderId=null) skip the lookup and fall into the deny path.
|
|
187
|
-
if (canonicalSenderId) {
|
|
188
|
-
const contactResult = findContactChannel({
|
|
189
|
-
channelType: sourceChannel,
|
|
190
|
-
address: canonicalSenderId,
|
|
191
|
-
externalChatId: conversationExternalId,
|
|
192
|
-
});
|
|
193
|
-
resolvedMember = contactResult
|
|
194
|
-
? {
|
|
195
|
-
contact: contactResult.contact,
|
|
196
|
-
channel: contactResult.channel,
|
|
197
|
-
}
|
|
198
|
-
: null;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
223
|
if (!resolvedMember) {
|
|
202
224
|
let denyNonMember = true;
|
|
203
225
|
|
|
@@ -318,7 +340,7 @@ export async function enforceIngressAcl(
|
|
|
318
340
|
if (slackVerifyResult.initiated) {
|
|
319
341
|
// Still notify the guardian about the access attempt
|
|
320
342
|
try {
|
|
321
|
-
notifyGuardianOfAccessRequest({
|
|
343
|
+
await notifyGuardianOfAccessRequest({
|
|
322
344
|
canonicalAssistantId,
|
|
323
345
|
sourceChannel,
|
|
324
346
|
conversationExternalId,
|
|
@@ -358,7 +380,7 @@ export async function enforceIngressAcl(
|
|
|
358
380
|
try {
|
|
359
381
|
await deliverChannelReply(dmCallbackUrl, {
|
|
360
382
|
chatId: senderUserId,
|
|
361
|
-
text: `I don't recognize you yet! I've let ${resolveGuardianLabel(sourceChannel)} know you're trying to reach me. They'll need to share a 6-digit verification code with you — ask them directly if you know them. Once you have the code, reply here with it.`,
|
|
383
|
+
text: `I don't recognize you yet! I've let ${await resolveGuardianLabel(sourceChannel)} know you're trying to reach me. They'll need to share a 6-digit verification code with you — ask them directly if you know them. Once you have the code, reply here with it.`,
|
|
362
384
|
assistantId,
|
|
363
385
|
});
|
|
364
386
|
} catch (err) {
|
|
@@ -393,7 +415,7 @@ export async function enforceIngressAcl(
|
|
|
393
415
|
|
|
394
416
|
if (emailVerifyResult.initiated) {
|
|
395
417
|
try {
|
|
396
|
-
notifyGuardianOfAccessRequest({
|
|
418
|
+
await notifyGuardianOfAccessRequest({
|
|
397
419
|
canonicalAssistantId,
|
|
398
420
|
sourceChannel,
|
|
399
421
|
conversationExternalId,
|
|
@@ -432,7 +454,7 @@ export async function enforceIngressAcl(
|
|
|
432
454
|
// deduplication, canonical request creation, and notification emission.
|
|
433
455
|
let guardianNotified = false;
|
|
434
456
|
try {
|
|
435
|
-
const accessResult = notifyGuardianOfAccessRequest({
|
|
457
|
+
const accessResult = await notifyGuardianOfAccessRequest({
|
|
436
458
|
canonicalAssistantId,
|
|
437
459
|
sourceChannel,
|
|
438
460
|
conversationExternalId,
|
|
@@ -456,7 +478,7 @@ export async function enforceIngressAcl(
|
|
|
456
478
|
}
|
|
457
479
|
|
|
458
480
|
const replyText = guardianNotified
|
|
459
|
-
? `Hmm looks like you don't have access to talk to me. I'll let ${resolveGuardianLabel(sourceChannel)} know you tried talking to me and get back to you.`
|
|
481
|
+
? `Hmm looks like you don't have access to talk to me. I'll let ${await resolveGuardianLabel(sourceChannel)} know you tried talking to me and get back to you.`
|
|
460
482
|
: "Sorry, you haven't been approved to message this assistant.";
|
|
461
483
|
let replyDelivered = false;
|
|
462
484
|
if (replyCallbackUrl) {
|
|
@@ -638,7 +660,7 @@ export async function enforceIngressAcl(
|
|
|
638
660
|
|
|
639
661
|
if (slackVerifyResult.initiated) {
|
|
640
662
|
try {
|
|
641
|
-
notifyGuardianOfAccessRequest({
|
|
663
|
+
await notifyGuardianOfAccessRequest({
|
|
642
664
|
canonicalAssistantId,
|
|
643
665
|
sourceChannel,
|
|
644
666
|
conversationExternalId,
|
|
@@ -677,7 +699,7 @@ export async function enforceIngressAcl(
|
|
|
677
699
|
try {
|
|
678
700
|
await deliverChannelReply(dmCallbackUrl, {
|
|
679
701
|
chatId: senderUserId,
|
|
680
|
-
text: `I don't recognize you yet! I've let ${resolveGuardianLabel(sourceChannel)} know you're trying to reach me. They'll need to share a 6-digit verification code with you — ask them directly if you know them. Once you have the code, reply here with it.`,
|
|
702
|
+
text: `I don't recognize you yet! I've let ${await resolveGuardianLabel(sourceChannel)} know you're trying to reach me. They'll need to share a 6-digit verification code with you — ask them directly if you know them. Once you have the code, reply here with it.`,
|
|
681
703
|
assistantId,
|
|
682
704
|
});
|
|
683
705
|
} catch (err) {
|
|
@@ -706,7 +728,7 @@ export async function enforceIngressAcl(
|
|
|
706
728
|
let guardianNotified = false;
|
|
707
729
|
if (resolvedMember.channel.status !== "blocked") {
|
|
708
730
|
try {
|
|
709
|
-
const accessResult = notifyGuardianOfAccessRequest({
|
|
731
|
+
const accessResult = await notifyGuardianOfAccessRequest({
|
|
710
732
|
canonicalAssistantId,
|
|
711
733
|
sourceChannel,
|
|
712
734
|
conversationExternalId,
|
|
@@ -734,7 +756,7 @@ export async function enforceIngressAcl(
|
|
|
734
756
|
}
|
|
735
757
|
|
|
736
758
|
const inactiveReplyText = guardianNotified
|
|
737
|
-
? `Hmm looks like you don't have access to talk to me. I'll let ${resolveGuardianLabel(sourceChannel)} know you tried talking to me and get back to you.`
|
|
759
|
+
? `Hmm looks like you don't have access to talk to me. I'll let ${await resolveGuardianLabel(sourceChannel)} know you tried talking to me and get back to you.`
|
|
738
760
|
: "Sorry, you haven't been approved to message this assistant.";
|
|
739
761
|
let inactiveReplyDelivered = false;
|
|
740
762
|
if (replyCallbackUrl) {
|
|
@@ -875,7 +897,7 @@ async function handleInviteTokenIntercept(params: {
|
|
|
875
897
|
};
|
|
876
898
|
}
|
|
877
899
|
|
|
878
|
-
const outcome = redeemInvite({
|
|
900
|
+
const outcome = await redeemInvite({
|
|
879
901
|
rawToken,
|
|
880
902
|
sourceChannel,
|
|
881
903
|
externalUserId: senderExternalUserId,
|
|
@@ -1077,9 +1099,9 @@ async function handleInviteCodeIntercept(params: {
|
|
|
1077
1099
|
};
|
|
1078
1100
|
}
|
|
1079
1101
|
|
|
1080
|
-
let outcome: ReturnType<typeof redeemInviteByCode
|
|
1102
|
+
let outcome: Awaited<ReturnType<typeof redeemInviteByCode>>;
|
|
1081
1103
|
try {
|
|
1082
|
-
outcome = redeemInviteByCode({
|
|
1104
|
+
outcome = await redeemInviteByCode({
|
|
1083
1105
|
code,
|
|
1084
1106
|
sourceChannel,
|
|
1085
1107
|
externalUserId: senderExternalUserId,
|
|
@@ -30,10 +30,7 @@ import {
|
|
|
30
30
|
|
|
31
31
|
import type { ChannelId } from "../../../channels/types.js";
|
|
32
32
|
import type { ChannelStatus } from "../../../contacts/types.js";
|
|
33
|
-
import {
|
|
34
|
-
TRUST_CLASS_RANK,
|
|
35
|
-
type TrustClass,
|
|
36
|
-
} from "../../actor-trust-resolver.js";
|
|
33
|
+
import type { TrustClass } from "../../actor-trust-resolver.js";
|
|
37
34
|
|
|
38
35
|
// ---------------------------------------------------------------------------
|
|
39
36
|
// Types
|
|
@@ -75,6 +72,23 @@ export type AdmissionPolicyResult =
|
|
|
75
72
|
// Public API
|
|
76
73
|
// ---------------------------------------------------------------------------
|
|
77
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Trust-class ordinal compared against {@link ADMISSION_FLOOR} to make the
|
|
77
|
+
* admission decision (`rank >= floor`). Higher rank = more trusted.
|
|
78
|
+
* Blocked/revoked never reach this comparison — they short-circuit to deny on
|
|
79
|
+
* member status above — so they carry no rank here.
|
|
80
|
+
*
|
|
81
|
+
* The two halves of the floor check: this table is keyed by `TrustClass`,
|
|
82
|
+
* `ADMISSION_FLOOR` (from `@vellumai/gateway-client`) by `AdmissionPolicy`.
|
|
83
|
+
* They are only ever read together, here, so they live next to their use.
|
|
84
|
+
*/
|
|
85
|
+
const TRUST_CLASS_RANK: Record<TrustClass, number> = {
|
|
86
|
+
guardian: 4,
|
|
87
|
+
trusted_contact: 3,
|
|
88
|
+
unverified_contact: 2,
|
|
89
|
+
unknown: 1,
|
|
90
|
+
};
|
|
91
|
+
|
|
78
92
|
/**
|
|
79
93
|
* Policies under which completing verification could lift the sender past
|
|
80
94
|
* the floor. Used to decide whether to fire the upgrade UX on deny.
|
|
@@ -116,7 +130,8 @@ export function enforceAdmissionPolicy(
|
|
|
116
130
|
if (input.memberStatus === "blocked" || input.memberStatus === "revoked") {
|
|
117
131
|
return {
|
|
118
132
|
admitted: false,
|
|
119
|
-
reason:
|
|
133
|
+
reason:
|
|
134
|
+
input.memberStatus === "blocked" ? "member_blocked" : "member_revoked",
|
|
120
135
|
shouldChallenge: false,
|
|
121
136
|
effectivePolicy: input.policy,
|
|
122
137
|
};
|
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { ChannelId, InterfaceId } from "../../../channels/types.js";
|
|
11
11
|
import { findGuardianForChannel } from "../../../contacts/contact-store.js";
|
|
12
|
+
import {
|
|
13
|
+
getGuardianDelivery,
|
|
14
|
+
guardianForChannel,
|
|
15
|
+
} from "../../../contacts/guardian-delivery-reader.js";
|
|
12
16
|
import type { ServerMessage } from "../../../daemon/message-protocol.js";
|
|
13
17
|
import type { TrustContext } from "../../../daemon/trust-context.js";
|
|
14
18
|
import {
|
|
@@ -960,10 +964,18 @@ function startTrustedContactApprovalNotifier(params: {
|
|
|
960
964
|
|
|
961
965
|
if (info && !globalNotifiedApprovalRequestIds.has(info.requestId)) {
|
|
962
966
|
globalNotifiedApprovalRequestIds.set(info.requestId, conversationId);
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
+
// Gateway-resolved guardian display name with the transitional
|
|
968
|
+
// local fallback on null/no-match (display-only). Removed in Combo 11.
|
|
969
|
+
const guardians = await getGuardianDelivery({
|
|
970
|
+
channelTypes: [sourceChannel],
|
|
971
|
+
});
|
|
972
|
+
const gatewayDisplayName = guardians
|
|
973
|
+
? guardianForChannel(guardians, sourceChannel)?.displayName
|
|
974
|
+
: undefined;
|
|
975
|
+
const displayName =
|
|
976
|
+
gatewayDisplayName ??
|
|
977
|
+
findGuardianForChannel(sourceChannel)?.contact.displayName;
|
|
978
|
+
const guardianName = resolveGuardianName(displayName);
|
|
967
979
|
const waitingText = `Waiting for ${guardianName}'s approval...`;
|
|
968
980
|
try {
|
|
969
981
|
await deliverChannelReply(replyCallbackUrl, {
|
|
@@ -4,7 +4,9 @@ import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
|
4
4
|
// Mocks — must be set up before importing the module under test
|
|
5
5
|
// ---------------------------------------------------------------------------
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
// Gateway guardian-delivery list: empty = unbound, one entry = bound,
|
|
8
|
+
// null = gateway unreachable.
|
|
9
|
+
let mockGuardianList: Array<Record<string, unknown>> | null = [];
|
|
8
10
|
let mockActiveSession: Record<string, unknown> | null = null;
|
|
9
11
|
let mockSessionResult = {
|
|
10
12
|
sessionId: "sess-1",
|
|
@@ -20,8 +22,14 @@ let deliverChannelReplyCalls: unknown[][] = [];
|
|
|
20
22
|
let emitNotificationSignalCalls: unknown[] = [];
|
|
21
23
|
let messageIdCounter = 0;
|
|
22
24
|
|
|
23
|
-
mock.module("../../../contacts/
|
|
24
|
-
|
|
25
|
+
mock.module("../../../contacts/guardian-delivery-reader.js", () => ({
|
|
26
|
+
// Existence guard reads fresh (uncached) — only this variant is stubbed.
|
|
27
|
+
getGuardianDeliveryFresh: () => Promise.resolve(mockGuardianList),
|
|
28
|
+
guardianForChannel: (
|
|
29
|
+
list: Array<{ channelType: string; status: string }>,
|
|
30
|
+
channelType: string,
|
|
31
|
+
) =>
|
|
32
|
+
list.find((g) => g.channelType === channelType && g.status === "active"),
|
|
25
33
|
}));
|
|
26
34
|
|
|
27
35
|
mock.module("../../channel-verification-service.js", () => ({
|
|
@@ -96,7 +104,7 @@ function makeParams(
|
|
|
96
104
|
|
|
97
105
|
describe("handleGuardianActivationIntercept", () => {
|
|
98
106
|
beforeEach(() => {
|
|
99
|
-
|
|
107
|
+
mockGuardianList = [];
|
|
100
108
|
mockActiveSession = null;
|
|
101
109
|
mockSessionResult = {
|
|
102
110
|
sessionId: "sess-1",
|
|
@@ -155,10 +163,15 @@ describe("handleGuardianActivationIntercept", () => {
|
|
|
155
163
|
});
|
|
156
164
|
|
|
157
165
|
test("bare /start with existing guardian returns null", async () => {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
166
|
+
mockGuardianList = [{ channelType: "telegram", status: "active" }];
|
|
167
|
+
|
|
168
|
+
const result = await handleGuardianActivationIntercept(makeParams());
|
|
169
|
+
expect(result).toBeNull();
|
|
170
|
+
expect(createOutboundSessionCalls).toHaveLength(0);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test("null guardian list (gateway unreachable) does NOT auto-start", async () => {
|
|
174
|
+
mockGuardianList = null;
|
|
162
175
|
|
|
163
176
|
const result = await handleGuardianActivationIntercept(makeParams());
|
|
164
177
|
expect(result).toBeNull();
|
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
* the guardian binding, and sends a success reply.
|
|
10
10
|
*/
|
|
11
11
|
import type { ChannelId } from "../../../channels/types.js";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
getGuardianDeliveryFresh,
|
|
14
|
+
guardianForChannel,
|
|
15
|
+
} from "../../../contacts/guardian-delivery-reader.js";
|
|
13
16
|
import { emitNotificationSignal } from "../../../notifications/emit-signal.js";
|
|
14
17
|
import { getLogger } from "../../../util/logger.js";
|
|
15
18
|
import {
|
|
@@ -88,8 +91,16 @@ export async function handleGuardianActivationIntercept(
|
|
|
88
91
|
// Only proceed for Telegram (can be extended later)
|
|
89
92
|
if (sourceChannel !== "telegram") return null;
|
|
90
93
|
|
|
91
|
-
// If a guardian already exists for this channel, continue to normal flow
|
|
92
|
-
|
|
94
|
+
// If a guardian already exists for this channel, continue to normal flow.
|
|
95
|
+
// Null-list (gateway unreachable) is treated as guardian-present so a
|
|
96
|
+
// transient miss does NOT spuriously auto-start verification.
|
|
97
|
+
// Read fresh: gateway-side binding writes don't invalidate the daemon cache.
|
|
98
|
+
const guardianList = await getGuardianDeliveryFresh({
|
|
99
|
+
channelTypes: [sourceChannel],
|
|
100
|
+
});
|
|
101
|
+
if (guardianList === null || guardianForChannel(guardianList, sourceChannel)) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
93
104
|
|
|
94
105
|
// Can't bind a session without sender identity
|
|
95
106
|
if (!rawSenderId) return null;
|
|
@@ -40,10 +40,27 @@ export interface LlmContextSection {
|
|
|
40
40
|
language?: string;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Structured error extracted from a rejected call's response payload.
|
|
45
|
+
* Mirrors the on-disk `responsePayload.error` shape produced by
|
|
46
|
+
* `buildProviderErrorResponsePayload`. Present only when the call failed
|
|
47
|
+
* before returning a response — consumers branch on its presence to
|
|
48
|
+
* render the call as failed.
|
|
49
|
+
*/
|
|
50
|
+
export interface LlmContextError {
|
|
51
|
+
name?: string;
|
|
52
|
+
message?: string;
|
|
53
|
+
code?: string;
|
|
54
|
+
provider?: string;
|
|
55
|
+
statusCode?: number;
|
|
56
|
+
retryAfterMs?: number;
|
|
57
|
+
}
|
|
58
|
+
|
|
43
59
|
export interface LlmContextNormalizationResult {
|
|
44
60
|
summary?: LlmContextSummary;
|
|
45
61
|
requestSections?: LlmContextSection[];
|
|
46
62
|
responseSections?: LlmContextSection[];
|
|
63
|
+
error?: LlmContextError;
|
|
47
64
|
}
|
|
48
65
|
|
|
49
66
|
interface NormalizedPayloadCandidate {
|
|
@@ -55,6 +72,60 @@ interface NormalizedPayloadCandidate {
|
|
|
55
72
|
|
|
56
73
|
export function normalizeLlmContextPayloads(
|
|
57
74
|
input: LlmContextNormalizationInput,
|
|
75
|
+
): LlmContextNormalizationResult {
|
|
76
|
+
const base = normalizeSuccessPayloads(input);
|
|
77
|
+
const error = normalizeProviderErrorPayload(input.responsePayload);
|
|
78
|
+
if (!error) {
|
|
79
|
+
return base;
|
|
80
|
+
}
|
|
81
|
+
// A rejected call has no response sections to render — only the request
|
|
82
|
+
// side normalized. Attach the structured error so the inspector can show
|
|
83
|
+
// a failure banner and treat the cost as $0.00 instead of silently
|
|
84
|
+
// falling back to "section rendering unavailable".
|
|
85
|
+
return { ...base, error };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Detect a provider/transport error stored in the response payload.
|
|
90
|
+
*
|
|
91
|
+
* Error rows are written as `{ error: { name, message, code?, provider?,
|
|
92
|
+
* statusCode?, retryAfterMs? } }` by `buildProviderErrorResponsePayload`.
|
|
93
|
+
* Successful provider responses never carry a top-level `error` object, so
|
|
94
|
+
* the presence of one (with at least one identifying field) is a reliable
|
|
95
|
+
* signal that the call failed.
|
|
96
|
+
*/
|
|
97
|
+
function normalizeProviderErrorPayload(
|
|
98
|
+
responsePayload: unknown,
|
|
99
|
+
): LlmContextError | null {
|
|
100
|
+
const error = asRecord(asRecord(responsePayload)?.error);
|
|
101
|
+
if (!error) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const name = asString(error.name);
|
|
106
|
+
const message = asString(error.message);
|
|
107
|
+
const code = asString(error.code);
|
|
108
|
+
// Require at least one identifying field so an unrelated `error` key on a
|
|
109
|
+
// success payload isn't misread as a provider failure.
|
|
110
|
+
if (name === undefined && message === undefined && code === undefined) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const normalized: LlmContextError = {};
|
|
115
|
+
if (name !== undefined) normalized.name = name;
|
|
116
|
+
if (message !== undefined) normalized.message = message;
|
|
117
|
+
if (code !== undefined) normalized.code = code;
|
|
118
|
+
const provider = asString(error.provider);
|
|
119
|
+
if (provider !== undefined) normalized.provider = provider;
|
|
120
|
+
const statusCode = asNumber(error.statusCode);
|
|
121
|
+
if (statusCode !== undefined) normalized.statusCode = statusCode;
|
|
122
|
+
const retryAfterMs = asNumber(error.retryAfterMs);
|
|
123
|
+
if (retryAfterMs !== undefined) normalized.retryAfterMs = retryAfterMs;
|
|
124
|
+
return normalized;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function normalizeSuccessPayloads(
|
|
128
|
+
input: LlmContextNormalizationInput,
|
|
58
129
|
): LlmContextNormalizationResult {
|
|
59
130
|
const requestCandidates = [
|
|
60
131
|
normalizeOpenAiRequestPayload(input.requestPayload),
|
|
@@ -22,7 +22,7 @@ import { join } from "node:path";
|
|
|
22
22
|
import { and, desc, eq, gte, lte } from "drizzle-orm";
|
|
23
23
|
import { z } from "zod";
|
|
24
24
|
|
|
25
|
-
import { getDb } from "../../memory/db-connection.js";
|
|
25
|
+
import { getDb, getLogsDb } from "../../memory/db-connection.js";
|
|
26
26
|
import {
|
|
27
27
|
llmRequestLogs,
|
|
28
28
|
llmUsageEvents,
|
|
@@ -168,7 +168,7 @@ async function handleExport({
|
|
|
168
168
|
: [];
|
|
169
169
|
|
|
170
170
|
const llmLogRows = capRows(
|
|
171
|
-
db
|
|
171
|
+
(getLogsDb() ?? db)
|
|
172
172
|
.select()
|
|
173
173
|
.from(llmRequestLogs)
|
|
174
174
|
.where(
|
|
@@ -24,7 +24,7 @@ import { getMcpAuthState } from "../../mcp/mcp-auth-state.js";
|
|
|
24
24
|
import { deleteMcpOAuthCredentials } from "../../mcp/mcp-oauth-provider.js";
|
|
25
25
|
import { getMcpToolsByServer } from "../../tools/registry.js";
|
|
26
26
|
import { getLogger } from "../../util/logger.js";
|
|
27
|
-
import { ACTOR_PRINCIPALS
|
|
27
|
+
import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
|
|
28
28
|
import { BadRequestError, InternalError, NotFoundError } from "./errors.js";
|
|
29
29
|
import type { RouteDefinition } from "./types.js";
|
|
30
30
|
|
|
@@ -281,6 +281,7 @@ async function handleMcpUpdate({
|
|
|
281
281
|
maxTools,
|
|
282
282
|
allowedTools,
|
|
283
283
|
blockedTools,
|
|
284
|
+
headers,
|
|
284
285
|
} = body as {
|
|
285
286
|
name: string;
|
|
286
287
|
enabled?: boolean;
|
|
@@ -288,6 +289,7 @@ async function handleMcpUpdate({
|
|
|
288
289
|
maxTools?: number;
|
|
289
290
|
allowedTools?: string[] | null;
|
|
290
291
|
blockedTools?: string[] | null;
|
|
292
|
+
headers?: Record<string, string> | null;
|
|
291
293
|
};
|
|
292
294
|
|
|
293
295
|
const raw = loadRawConfig();
|
|
@@ -326,6 +328,19 @@ async function handleMcpUpdate({
|
|
|
326
328
|
server.blockedTools = blockedTools;
|
|
327
329
|
}
|
|
328
330
|
}
|
|
331
|
+
if (headers !== undefined) {
|
|
332
|
+
const transport = server.transport as Record<string, unknown> | undefined;
|
|
333
|
+
if (
|
|
334
|
+
transport &&
|
|
335
|
+
(transport.type === "sse" || transport.type === "streamable-http")
|
|
336
|
+
) {
|
|
337
|
+
if (headers === null || Object.keys(headers).length === 0) {
|
|
338
|
+
delete transport.headers;
|
|
339
|
+
} else {
|
|
340
|
+
transport.headers = headers;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
329
344
|
|
|
330
345
|
saveRawConfig(raw);
|
|
331
346
|
triggerReload("internal_mcp_update");
|
|
@@ -342,15 +357,17 @@ async function handleMcpAdd({
|
|
|
342
357
|
}: {
|
|
343
358
|
body?: Record<string, unknown>;
|
|
344
359
|
}): Promise<{ added: true }> {
|
|
345
|
-
const { name, transportType, url, command, args, risk, disabled } =
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
360
|
+
const { name, transportType, url, command, args, risk, disabled, headers } =
|
|
361
|
+
body as {
|
|
362
|
+
name: string;
|
|
363
|
+
transportType: string;
|
|
364
|
+
url?: string;
|
|
365
|
+
command?: string;
|
|
366
|
+
args?: string[];
|
|
367
|
+
risk?: string;
|
|
368
|
+
disabled?: boolean;
|
|
369
|
+
headers?: Record<string, string>;
|
|
370
|
+
};
|
|
354
371
|
|
|
355
372
|
const riskLevel = risk ?? "high";
|
|
356
373
|
if (!["low", "medium", "high"].includes(riskLevel)) {
|
|
@@ -374,7 +391,11 @@ async function handleMcpAdd({
|
|
|
374
391
|
`--url is required for ${transportType} transport`,
|
|
375
392
|
);
|
|
376
393
|
}
|
|
377
|
-
transport = {
|
|
394
|
+
transport = {
|
|
395
|
+
type: transportType,
|
|
396
|
+
url,
|
|
397
|
+
...(headers && Object.keys(headers).length > 0 ? { headers } : {}),
|
|
398
|
+
};
|
|
378
399
|
break;
|
|
379
400
|
default:
|
|
380
401
|
throw new BadRequestError(
|
|
@@ -455,8 +476,8 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
455
476
|
endpoint: "internal/mcp/auth/start",
|
|
456
477
|
method: "POST",
|
|
457
478
|
policy: {
|
|
458
|
-
requiredScopes: ["
|
|
459
|
-
allowedPrincipalTypes:
|
|
479
|
+
requiredScopes: ["settings.write"],
|
|
480
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
460
481
|
},
|
|
461
482
|
summary: "Start MCP OAuth flow",
|
|
462
483
|
description:
|
|
@@ -470,8 +491,8 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
470
491
|
endpoint: "internal/mcp/auth/status/:serverId",
|
|
471
492
|
method: "GET",
|
|
472
493
|
policy: {
|
|
473
|
-
requiredScopes: ["
|
|
474
|
-
allowedPrincipalTypes:
|
|
494
|
+
requiredScopes: ["settings.read"],
|
|
495
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
475
496
|
},
|
|
476
497
|
summary: "Poll MCP OAuth flow status",
|
|
477
498
|
description:
|
|
@@ -579,6 +600,7 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
579
600
|
maxTools: z.number().optional(),
|
|
580
601
|
allowedTools: z.array(z.string()).nullable().optional(),
|
|
581
602
|
blockedTools: z.array(z.string()).nullable().optional(),
|
|
603
|
+
headers: z.record(z.string(), z.string()).nullable().optional(),
|
|
582
604
|
}),
|
|
583
605
|
handler: handleMcpUpdate,
|
|
584
606
|
},
|
|
@@ -602,6 +624,7 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
602
624
|
args: z.array(z.string()).optional(),
|
|
603
625
|
risk: z.string().optional(),
|
|
604
626
|
disabled: z.boolean().optional(),
|
|
627
|
+
headers: z.record(z.string(), z.string()).optional(),
|
|
605
628
|
}),
|
|
606
629
|
handler: handleMcpAdd,
|
|
607
630
|
},
|