@vellumai/assistant 0.10.0 → 0.10.1-staging.1
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 +6 -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__/trust-verdict-contract.test.ts +65 -0
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +162 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +8 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +14 -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 +78 -0
- package/openapi.yaml +345 -18
- package/package.json +2 -1
- package/scripts/memory-inspect.ts +24 -14
- 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 +3 -3
- 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 +143 -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 +1 -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__/channel-approval-routes.test.ts +73 -1119
- package/src/__tests__/channel-delivery-store.test.ts +1 -1
- package/src/__tests__/channel-guardian.test.ts +265 -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 +183 -51
- package/src/__tests__/config-schema.test.ts +34 -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 +3 -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 +6 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +1 -1
- 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 +1 -1
- package/src/__tests__/conversation-sync-tags.test.ts +1 -1
- 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 +26 -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__/edit-propagation.test.ts +1 -1
- package/src/__tests__/emit-signal-routing-intent.test.ts +83 -0
- package/src/__tests__/empty-response-hook.test.ts +42 -0
- package/src/__tests__/events-client-registration.test.ts +1 -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 +1 -1
- 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 +1 -1
- package/src/__tests__/guardian-outbound-http.test.ts +7 -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 +98 -0
- package/src/__tests__/http-conversation-lineage.test.ts +1 -1
- 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-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-usage-store.test.ts +40 -1
- package/src/__tests__/log-export-routes.test.ts +1 -1
- package/src/__tests__/log-export-workspace.test.ts +3 -3
- 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 +1 -2
- package/src/__tests__/notification-candidate-guardian-context.test.ts +203 -0
- package/src/__tests__/notification-guardian-path.test.ts +1 -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__/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 +357 -56
- package/src/__tests__/runtime-attachment-metadata.test.ts +10 -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-routes-platform-proxy.test.ts +1 -0
- package/src/__tests__/send-endpoint-busy.test.ts +1 -1
- 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__/slack-inbound-verification.test.ts +1 -3
- 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__/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 +32 -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 +2 -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/index.ts +0 -6
- 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 +88 -62
- package/src/calls/inbound-trust-reader.ts +40 -0
- package/src/calls/relay-server.ts +65 -23
- package/src/calls/relay-setup-router.ts +20 -6
- package/src/calls/relay-verification.ts +7 -7
- 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/memory/__tests__/memory-v3.test.ts +6 -1
- package/src/cli/commands/memory/index.ts +2 -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/plugins.ts +268 -11
- package/src/cli/lib/__tests__/install-from-github.test.ts +40 -0
- 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/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__/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/profile-dispatchability.ts +11 -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 +5 -3
- package/src/config/schemas/timeouts.ts +24 -0
- package/src/config/seed-inference-profiles.ts +133 -45
- package/src/config/sync-gated-profiles.ts +13 -1
- package/src/contacts/contact-store.ts +21 -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 +9 -36
- package/src/daemon/conversation-runtime-assembly.ts +91 -66
- package/src/daemon/conversation-tool-setup.ts +20 -63
- package/src/daemon/conversation.ts +144 -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 +32 -18
- package/src/daemon/handlers/conversations.ts +7 -0
- package/src/daemon/handlers/shared.ts +7 -0
- package/src/daemon/lifecycle.ts +16 -3
- 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 +18 -8
- package/src/daemon/server.ts +0 -4
- package/src/daemon/tool-setup-types.ts +0 -7
- 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__/watcher-ipc.test.ts +59 -39
- package/src/ipc/assistant-server.ts +8 -0
- 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__/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/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 +31 -1
- 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/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 +227 -230
- 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 +50 -57
- 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__/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/validate-migration-state.ts +50 -145
- 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__/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__/sweep-job.test.ts +2 -2
- 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/messaging/provider.ts +10 -0
- package/src/messaging/providers/gmail/adapter.ts +1 -0
- package/src/messaging/providers/gmail/client.ts +14 -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__/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/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/deterministic-checks.ts +19 -16
- package/src/notifications/emit-signal.ts +29 -1
- 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 +146 -6
- package/src/oauth/connection-resolver.ts +132 -5
- package/src/oauth/oauth-store.ts +16 -3
- package/src/oauth/scope-utils.ts +21 -0
- 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 +149 -0
- package/src/plugin-api/vision-support.ts +78 -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 +302 -0
- package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +103 -0
- package/src/plugins/defaults/image-fallback/package.json +14 -0
- package/src/plugins/defaults/image-fallback/src/caption-cache.ts +49 -0
- package/src/plugins/defaults/image-fallback/src/image-persist.ts +59 -0
- package/src/plugins/defaults/image-fallback/src/vision-caption.ts +120 -0
- package/src/plugins/defaults/index.ts +23 -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/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 +254 -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 +37 -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__/slack-block-formatting.test.ts +39 -10
- package/src/runtime/__tests__/trust-verdict-consumer.test.ts +417 -0
- package/src/runtime/actor-trust-resolver.ts +8 -16
- package/src/runtime/agent-wake.ts +183 -60
- package/src/runtime/channel-reply-delivery.ts +6 -3
- package/src/runtime/guardian-decision-types.ts +3 -22
- 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/migrations/__tests__/vbundle-builder-fd-leak.test.ts +3 -0
- 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/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 +12 -1
- 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 +24 -3
- package/src/runtime/routes/conversation-starter-routes.ts +7 -8
- package/src/runtime/routes/guardian-approval-interception.ts +13 -274
- package/src/runtime/routes/inbound-message-handler.ts +20 -15
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +285 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +45 -34
- package/src/runtime/routes/inbound-stages/admission-policy.ts +20 -5
- package/src/runtime/routes/log-export-routes.ts +2 -2
- 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/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 +172 -0
- package/src/schedule/scheduler.ts +6 -9
- package/src/telemetry/usage-telemetry-reporter.test.ts +1 -1
- package/src/tools/ask-question/ask-question-tool.test.ts +60 -52
- package/src/tools/ask-question/ask-question-tool.ts +14 -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/util/fs-watcher-error.ts +36 -0
- package/src/util/logs-db-path.ts +22 -0
- package/src/util/memory-db-path.ts +23 -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
|
@@ -8,36 +8,53 @@
|
|
|
8
8
|
* they don't shadow more-specific sub-paths like contacts/invites.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import {
|
|
12
|
+
GetContactIpcResponseSchema,
|
|
13
|
+
ListContactsIpcResponseSchema,
|
|
14
|
+
UpdateContactChannelIpcResponseSchema,
|
|
15
|
+
} from "@vellumai/gateway-client/gateway-ipc-contracts";
|
|
16
|
+
import { IpcCallError } from "@vellumai/gateway-client/ipc-client";
|
|
11
17
|
import { z } from "zod";
|
|
12
18
|
|
|
13
19
|
import {
|
|
14
20
|
getAssistantContactMetadata,
|
|
15
|
-
getChannelById,
|
|
16
21
|
getContact,
|
|
17
22
|
listContacts,
|
|
18
23
|
mergeContacts,
|
|
19
24
|
searchContacts,
|
|
20
|
-
updateChannelStatus,
|
|
21
25
|
} from "../../contacts/contact-store.js";
|
|
22
|
-
import type {
|
|
23
|
-
|
|
24
|
-
ChannelStatus,
|
|
25
|
-
ContactRole,
|
|
26
|
-
ContactType,
|
|
27
|
-
} from "../../contacts/types.js";
|
|
26
|
+
import type { ContactRole, ContactType } from "../../contacts/types.js";
|
|
27
|
+
import { ipcCallPersistent } from "../../ipc/gateway-client.js";
|
|
28
28
|
import { resolveGuardianName } from "../../prompts/user-reference.js";
|
|
29
|
+
import { getLogger } from "../../util/logger.js";
|
|
29
30
|
import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
|
|
30
31
|
import {
|
|
31
|
-
createIngressInvite,
|
|
32
|
-
listIngressInvites,
|
|
33
32
|
redeemIngressInvite,
|
|
34
33
|
redeemVoiceInviteCode,
|
|
35
|
-
revokeIngressInvite,
|
|
36
34
|
triggerInviteCall,
|
|
37
35
|
} from "../invite-service.js";
|
|
38
|
-
import { BadRequestError,
|
|
36
|
+
import { BadRequestError, NotFoundError, RouteError } from "./errors.js";
|
|
39
37
|
import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
|
|
40
38
|
|
|
39
|
+
const log = getLogger("contact-routes");
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Re-throw a relayed gateway `IpcCallError` as a `RouteError` so the IPC/HTTP
|
|
43
|
+
* adapters honor its statusCode/errorCode (4xx surfaces as 4xx, not a generic
|
|
44
|
+
* 500). Non-IpcCallError throws propagate unchanged.
|
|
45
|
+
*/
|
|
46
|
+
function rethrowGatewayError(err: unknown): never {
|
|
47
|
+
if (err instanceof IpcCallError) {
|
|
48
|
+
throw new RouteError(
|
|
49
|
+
err.message,
|
|
50
|
+
err.errorCode ?? "INTERNAL_ERROR",
|
|
51
|
+
err.statusCode ?? 500,
|
|
52
|
+
err.errorDetails,
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
throw err;
|
|
56
|
+
}
|
|
57
|
+
|
|
41
58
|
function withGuardianNameOverride<
|
|
42
59
|
T extends { role: string; displayName: string },
|
|
43
60
|
>(contact: T): T {
|
|
@@ -76,31 +93,10 @@ function prepareContactResponse<
|
|
|
76
93
|
|
|
77
94
|
const VALID_CONTACT_TYPES: readonly ContactType[] = ["human", "assistant"];
|
|
78
95
|
|
|
79
|
-
const VALID_CHANNEL_STATUSES: readonly ChannelStatus[] = [
|
|
80
|
-
"active",
|
|
81
|
-
"pending",
|
|
82
|
-
"revoked",
|
|
83
|
-
"blocked",
|
|
84
|
-
"unverified",
|
|
85
|
-
];
|
|
86
|
-
const VALID_CHANNEL_POLICIES: readonly ChannelPolicy[] = [
|
|
87
|
-
"allow",
|
|
88
|
-
"deny",
|
|
89
|
-
"escalate",
|
|
90
|
-
];
|
|
91
|
-
|
|
92
96
|
function isContactType(value: string): value is ContactType {
|
|
93
97
|
return (VALID_CONTACT_TYPES as readonly string[]).includes(value);
|
|
94
98
|
}
|
|
95
99
|
|
|
96
|
-
function isChannelStatus(value: string): value is ChannelStatus {
|
|
97
|
-
return (VALID_CHANNEL_STATUSES as readonly string[]).includes(value);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function isChannelPolicy(value: string): value is ChannelPolicy {
|
|
101
|
-
return (VALID_CHANNEL_POLICIES as readonly string[]).includes(value);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
100
|
// ---------------------------------------------------------------------------
|
|
105
101
|
// Response schemas (drive OpenAPI spec → codegen → typed SDK)
|
|
106
102
|
// ---------------------------------------------------------------------------
|
|
@@ -132,6 +128,8 @@ const contactSchema = z.object({
|
|
|
132
128
|
contactType: z.string().nullable().optional(),
|
|
133
129
|
lastInteraction: z.number().nullable().optional(),
|
|
134
130
|
interactionCount: z.number(),
|
|
131
|
+
createdAt: z.number(),
|
|
132
|
+
updatedAt: z.number(),
|
|
135
133
|
channels: z.array(contactChannelSchema),
|
|
136
134
|
});
|
|
137
135
|
|
|
@@ -139,7 +137,40 @@ const contactSchema = z.object({
|
|
|
139
137
|
// Contact handlers (transport-agnostic)
|
|
140
138
|
// ---------------------------------------------------------------------------
|
|
141
139
|
|
|
142
|
-
|
|
140
|
+
/**
|
|
141
|
+
* Relay a non-search contact list read to the gateway (source of truth for ACL
|
|
142
|
+
* fields), falling back to the assistant DB on IPC failure. Shared by the GET
|
|
143
|
+
* `contacts` list and the `search_contacts` no-filter case so both serve
|
|
144
|
+
* gateway-sourced data consistently.
|
|
145
|
+
*/
|
|
146
|
+
async function relayListContacts(
|
|
147
|
+
limit: number,
|
|
148
|
+
role: ContactRole | undefined,
|
|
149
|
+
) {
|
|
150
|
+
try {
|
|
151
|
+
const result = await ipcCallPersistent("contacts_list_rich", {
|
|
152
|
+
limit,
|
|
153
|
+
...(role ? { role } : {}),
|
|
154
|
+
});
|
|
155
|
+
const { contacts } = ListContactsIpcResponseSchema.parse(result);
|
|
156
|
+
return {
|
|
157
|
+
ok: true,
|
|
158
|
+
contacts: contacts.map(prepareContactResponse),
|
|
159
|
+
};
|
|
160
|
+
} catch (err) {
|
|
161
|
+
log.warn(
|
|
162
|
+
{ err },
|
|
163
|
+
"relayListContacts: gateway relay failed; falling back to assistant DB",
|
|
164
|
+
);
|
|
165
|
+
const contacts = listContacts(limit, role);
|
|
166
|
+
return {
|
|
167
|
+
ok: true,
|
|
168
|
+
contacts: contacts.map(prepareContactResponse),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export async function handleListContacts(queryParams: Record<string, string>) {
|
|
143
174
|
const limit = Number(queryParams.limit ?? 50);
|
|
144
175
|
const role = (queryParams.role as ContactRole) || undefined;
|
|
145
176
|
const contactTypeParam = queryParams.contactType;
|
|
@@ -157,7 +188,11 @@ function handleListContacts(queryParams: Record<string, string>) {
|
|
|
157
188
|
? (contactTypeParam as ContactType)
|
|
158
189
|
: undefined;
|
|
159
190
|
|
|
191
|
+
// True search stays daemon-native: gateway-native search is design-blocked.
|
|
160
192
|
if (query || channelAddress || channelType) {
|
|
193
|
+
log.debug(
|
|
194
|
+
"handleListContacts: search served daemon-native (gateway-native search is design-blocked)",
|
|
195
|
+
);
|
|
161
196
|
const contacts = searchContacts({
|
|
162
197
|
query,
|
|
163
198
|
channelAddress,
|
|
@@ -172,105 +207,175 @@ function handleListContacts(queryParams: Record<string, string>) {
|
|
|
172
207
|
};
|
|
173
208
|
}
|
|
174
209
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
210
|
+
// contactType is assistant-owned: serve daemon-native so it's filtered in SQL
|
|
211
|
+
// BEFORE the limit. The gateway relay filtered it AFTER its limit, which
|
|
212
|
+
// under-returned (and returned empty on an assistant-DB outage, since the
|
|
213
|
+
// soft-fail map dropped every row). Mirrors the search boundary.
|
|
214
|
+
if (contactType) {
|
|
215
|
+
log.debug(
|
|
216
|
+
"handleListContacts: contactType-filtered read served daemon-native (gateway-native contactType filtering is design-blocked, pending ACL classification)",
|
|
217
|
+
);
|
|
218
|
+
const contacts = listContacts(limit, role, contactType);
|
|
219
|
+
return {
|
|
220
|
+
ok: true,
|
|
221
|
+
contacts: contacts.map(prepareContactResponse),
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return relayListContacts(limit, role);
|
|
180
226
|
}
|
|
181
227
|
|
|
182
|
-
function handleGetContact(contactId: string) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
228
|
+
export async function handleGetContact(contactId: string) {
|
|
229
|
+
try {
|
|
230
|
+
const result = await ipcCallPersistent("contacts_get_rich", { contactId });
|
|
231
|
+
// The gateway returns null (no `contact`) on a clean not-found.
|
|
232
|
+
if (!result || (result as { contact?: unknown }).contact === undefined) {
|
|
233
|
+
throw new NotFoundError(`Contact "${contactId}" not found`);
|
|
234
|
+
}
|
|
235
|
+
const { contact, assistantMetadata } =
|
|
236
|
+
GetContactIpcResponseSchema.parse(result);
|
|
237
|
+
return {
|
|
238
|
+
ok: true,
|
|
239
|
+
contact: prepareContactResponse(contact),
|
|
240
|
+
assistantMetadata: assistantMetadata ?? undefined,
|
|
241
|
+
};
|
|
242
|
+
} catch (err) {
|
|
243
|
+
// A clean not-found is a real 404 — don't fall back or mask it.
|
|
244
|
+
if (err instanceof NotFoundError) throw err;
|
|
245
|
+
log.warn(
|
|
246
|
+
{ err, contactId },
|
|
247
|
+
"handleGetContact: gateway relay failed; falling back to assistant DB",
|
|
248
|
+
);
|
|
249
|
+
const contact = getContact(contactId);
|
|
250
|
+
if (!contact) {
|
|
251
|
+
throw new NotFoundError(`Contact "${contactId}" not found`);
|
|
252
|
+
}
|
|
253
|
+
const assistantMeta =
|
|
254
|
+
contact.contactType === "assistant"
|
|
255
|
+
? getAssistantContactMetadata(contact.id)
|
|
256
|
+
: undefined;
|
|
257
|
+
return {
|
|
258
|
+
ok: true,
|
|
259
|
+
contact: prepareContactResponse(contact),
|
|
260
|
+
assistantMetadata: assistantMeta ?? undefined,
|
|
261
|
+
};
|
|
186
262
|
}
|
|
187
|
-
const assistantMeta =
|
|
188
|
-
contact.contactType === "assistant"
|
|
189
|
-
? getAssistantContactMetadata(contact.id)
|
|
190
|
-
: undefined;
|
|
191
|
-
return {
|
|
192
|
-
ok: true,
|
|
193
|
-
contact: prepareContactResponse(contact),
|
|
194
|
-
assistantMetadata: assistantMeta ?? undefined,
|
|
195
|
-
};
|
|
196
263
|
}
|
|
197
264
|
|
|
198
265
|
// ---------------------------------------------------------------------------
|
|
199
266
|
// Invite handlers (transport-agnostic)
|
|
200
267
|
// ---------------------------------------------------------------------------
|
|
201
268
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
status: queryParams.status,
|
|
206
|
-
});
|
|
269
|
+
// The gateway owns the canonical invite write path. These CLI handlers relay
|
|
270
|
+
// to the gateway IPC methods via `ipcCallPersistent`; the assistant DB is
|
|
271
|
+
// written only by the gateway. (Redemption stays daemon-local — see the redeem route.)
|
|
207
272
|
|
|
208
|
-
|
|
209
|
-
|
|
273
|
+
// The invite-CREATE relay needs a generous timeout: the gateway's `invites_mint`
|
|
274
|
+
// handler calls `createIngressInvite` → `generateInviteInstruction`, which can spend
|
|
275
|
+
// up to GENERATION_TIMEOUT_MS (~5s) waiting on an LLM before falling back. The default
|
|
276
|
+
// 5s persistent-IPC timeout can fire mid-mint, so the caller sees a spurious failure
|
|
277
|
+
// even though the gateway is still writing the invite. 30s safely exceeds the inner
|
|
278
|
+
// ~5s fallback plus IPC overhead on both nested hops. (List/revoke keep the default.)
|
|
279
|
+
const INVITE_CREATE_RELAY_TIMEOUT_MS = 30_000;
|
|
280
|
+
|
|
281
|
+
export async function handleListInvites({ queryParams = {} }: RouteHandlerArgs) {
|
|
282
|
+
try {
|
|
283
|
+
const result = (await ipcCallPersistent("invites_list", {
|
|
284
|
+
...(queryParams.sourceChannel
|
|
285
|
+
? { sourceChannel: queryParams.sourceChannel }
|
|
286
|
+
: {}),
|
|
287
|
+
...(queryParams.status ? { status: queryParams.status } : {}),
|
|
288
|
+
})) as { invites: Array<Record<string, unknown>> };
|
|
289
|
+
return { ok: true, invites: result.invites };
|
|
290
|
+
} catch (err) {
|
|
291
|
+
rethrowGatewayError(err);
|
|
210
292
|
}
|
|
211
|
-
return { ok: true, invites: result.data };
|
|
212
293
|
}
|
|
213
294
|
|
|
214
295
|
export async function handleCreateInvite({ body = {} }: RouteHandlerArgs) {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
296
|
+
try {
|
|
297
|
+
const result = (await ipcCallPersistent(
|
|
298
|
+
"invites_create",
|
|
299
|
+
{
|
|
300
|
+
contactId: body.contactId as string,
|
|
301
|
+
sourceChannel: body.sourceChannel as string | undefined,
|
|
302
|
+
note: body.note as string | undefined,
|
|
303
|
+
maxUses: body.maxUses as number | undefined,
|
|
304
|
+
expiresInMs: body.expiresInMs as number | undefined,
|
|
305
|
+
expectedExternalUserId: body.expectedExternalUserId as
|
|
306
|
+
| string
|
|
307
|
+
| undefined,
|
|
308
|
+
},
|
|
309
|
+
INVITE_CREATE_RELAY_TIMEOUT_MS,
|
|
310
|
+
)) as { invite: Record<string, unknown>; rawToken?: string };
|
|
311
|
+
return {
|
|
312
|
+
ok: true,
|
|
313
|
+
invite: result.invite,
|
|
314
|
+
...(result.rawToken ? { rawToken: result.rawToken } : {}),
|
|
315
|
+
};
|
|
316
|
+
} catch (err) {
|
|
317
|
+
rethrowGatewayError(err);
|
|
230
318
|
}
|
|
231
|
-
return { ok: true, invite: result.data };
|
|
232
319
|
}
|
|
233
320
|
|
|
234
|
-
export function handleRevokeInvite({ pathParams = {} }: RouteHandlerArgs) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
321
|
+
export async function handleRevokeInvite({ pathParams = {} }: RouteHandlerArgs) {
|
|
322
|
+
try {
|
|
323
|
+
const result = (await ipcCallPersistent("invites_revoke", {
|
|
324
|
+
id: pathParams.id,
|
|
325
|
+
})) as { invite: Record<string, unknown> };
|
|
326
|
+
return { ok: true, invite: result.invite };
|
|
327
|
+
} catch (err) {
|
|
328
|
+
rethrowGatewayError(err);
|
|
239
329
|
}
|
|
240
|
-
return { ok: true, invite: result.data };
|
|
241
330
|
}
|
|
242
331
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
332
|
+
/**
|
|
333
|
+
* Redeem a voice invite code.
|
|
334
|
+
*
|
|
335
|
+
* Backs the HTTP `invites_redeem` route (voice path) and the IPC-only
|
|
336
|
+
* `invites_redeem_voice` method. Wraps the identity-bound
|
|
337
|
+
* `redeemVoiceInviteCode` path.
|
|
338
|
+
*/
|
|
339
|
+
export async function handleRedeemVoiceInvite({
|
|
340
|
+
body = {},
|
|
341
|
+
}: RouteHandlerArgs) {
|
|
342
|
+
const callerExternalUserId = body.callerExternalUserId as string | undefined;
|
|
343
|
+
const code = body.code as string | undefined;
|
|
253
344
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
sourceChannel: "phone",
|
|
258
|
-
code,
|
|
259
|
-
});
|
|
345
|
+
if (!callerExternalUserId || !code) {
|
|
346
|
+
throw new BadRequestError("callerExternalUserId and code are required");
|
|
347
|
+
}
|
|
260
348
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
349
|
+
const result = await redeemVoiceInviteCode({
|
|
350
|
+
assistantId: body.assistantId as string | undefined,
|
|
351
|
+
callerExternalUserId,
|
|
352
|
+
sourceChannel: "phone",
|
|
353
|
+
code,
|
|
354
|
+
});
|
|
264
355
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
type: result.type,
|
|
268
|
-
memberId: result.memberId,
|
|
269
|
-
...(result.type === "redeemed" ? { inviteId: result.inviteId } : {}),
|
|
270
|
-
};
|
|
356
|
+
if (!result.ok) {
|
|
357
|
+
throw new BadRequestError(result.reason);
|
|
271
358
|
}
|
|
272
359
|
|
|
273
|
-
|
|
360
|
+
return {
|
|
361
|
+
ok: true,
|
|
362
|
+
type: result.type,
|
|
363
|
+
memberId: result.memberId,
|
|
364
|
+
...(result.type === "redeemed" ? { inviteId: result.inviteId } : {}),
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Redeem a token invite.
|
|
370
|
+
*
|
|
371
|
+
* Backs the HTTP `invites_redeem` route (token path) and the IPC-only
|
|
372
|
+
* `invites_redeem_token` method. Wraps the generic `redeemIngressInvite`
|
|
373
|
+
* token path.
|
|
374
|
+
*/
|
|
375
|
+
export async function handleRedeemTokenInvite({
|
|
376
|
+
body = {},
|
|
377
|
+
}: RouteHandlerArgs) {
|
|
378
|
+
const result = await redeemIngressInvite({
|
|
274
379
|
token: body.token as string | undefined,
|
|
275
380
|
externalUserId: body.externalUserId as string | undefined,
|
|
276
381
|
externalChatId: body.externalChatId as string | undefined,
|
|
@@ -280,9 +385,23 @@ export async function handleRedeemInvite({ body = {} }: RouteHandlerArgs) {
|
|
|
280
385
|
if (!result.ok) {
|
|
281
386
|
throw new BadRequestError(result.error);
|
|
282
387
|
}
|
|
283
|
-
|
|
388
|
+
// Surface the redemption `type` so the gateway can skip mirroring an
|
|
389
|
+
// `already_member` redeem (which consumes no invite use).
|
|
390
|
+
return { ok: true, invite: result.data.invite, type: result.data.type };
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
export async function handleRedeemInvite(args: RouteHandlerArgs) {
|
|
394
|
+
const body = args.body ?? {};
|
|
395
|
+
if (body.code != null) {
|
|
396
|
+
return handleRedeemVoiceInvite(args);
|
|
397
|
+
}
|
|
398
|
+
return handleRedeemTokenInvite(args);
|
|
284
399
|
}
|
|
285
400
|
|
|
401
|
+
// Stays daemon-local by design (like invites_redeem): the gateway's call path
|
|
402
|
+
// validates its row then delegates the actual provider call to THIS handler via
|
|
403
|
+
// ipcCallAssistant("invites_trigger_call"). Relaying back would loop
|
|
404
|
+
// gateway→assistant→gateway. The provider call is a daemon capability.
|
|
286
405
|
export async function handleTriggerInviteCall({
|
|
287
406
|
pathParams = {},
|
|
288
407
|
}: RouteHandlerArgs) {
|
|
@@ -408,17 +527,18 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
408
527
|
note: z.string().describe("Optional note").optional(),
|
|
409
528
|
maxUses: z.number().describe("Max redemptions").optional(),
|
|
410
529
|
expiresInMs: z.number().describe("Expiry duration in ms").optional(),
|
|
411
|
-
contactName: z.string().describe("Contact display name").optional(),
|
|
412
530
|
expectedExternalUserId: z
|
|
413
531
|
.string()
|
|
414
532
|
.describe("Expected user ID (E.164 for phone)")
|
|
415
533
|
.optional(),
|
|
416
|
-
friendName: z.string().describe("Friend name for the invite").optional(),
|
|
417
|
-
guardianName: z.string().describe("Guardian name").optional(),
|
|
418
534
|
}),
|
|
419
535
|
responseBody: z.object({
|
|
420
536
|
ok: z.boolean(),
|
|
421
537
|
invite: z.object({}).passthrough().describe("Created invite"),
|
|
538
|
+
rawToken: z
|
|
539
|
+
.string()
|
|
540
|
+
.optional()
|
|
541
|
+
.describe("One-time raw invite token (returned at creation only)"),
|
|
422
542
|
}),
|
|
423
543
|
additionalResponses: {
|
|
424
544
|
"400": {
|
|
@@ -427,6 +547,9 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
427
547
|
},
|
|
428
548
|
},
|
|
429
549
|
{
|
|
550
|
+
// Stays daemon-local by design: redemption is an inbound-channel path (not
|
|
551
|
+
// a CLI ACL surface), and the assistant redemption service already claims
|
|
552
|
+
// the gateway row by id via record_invite_redemption — relaying would loop.
|
|
430
553
|
operationId: "invites_redeem",
|
|
431
554
|
endpoint: "contacts/invites/redeem",
|
|
432
555
|
method: "POST",
|
|
@@ -524,7 +647,7 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
524
647
|
limit: z.number().optional(),
|
|
525
648
|
}),
|
|
526
649
|
responseBody: z.array(contactSchema),
|
|
527
|
-
handler: ({ body = {} }: RouteHandlerArgs) => {
|
|
650
|
+
handler: async ({ body = {} }: RouteHandlerArgs) => {
|
|
528
651
|
const parsed = z
|
|
529
652
|
.object({
|
|
530
653
|
query: z.string().optional(),
|
|
@@ -533,6 +656,23 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
533
656
|
limit: z.number().optional(),
|
|
534
657
|
})
|
|
535
658
|
.parse(body);
|
|
659
|
+
|
|
660
|
+
const hasFilter =
|
|
661
|
+
Boolean(parsed.query?.trim()) ||
|
|
662
|
+
Boolean(parsed.channelAddress) ||
|
|
663
|
+
Boolean(parsed.channelType);
|
|
664
|
+
|
|
665
|
+
// No-filter "search" is a list read — relay to the gateway so it returns
|
|
666
|
+
// the same source-of-truth data as `contacts list`.
|
|
667
|
+
if (!hasFilter) {
|
|
668
|
+
const { contacts } = await relayListContacts(parsed.limit ?? 50, undefined);
|
|
669
|
+
return contacts;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
// True search stays daemon-native: gateway-native search is design-blocked.
|
|
673
|
+
log.debug(
|
|
674
|
+
"search_contacts: search served daemon-native (gateway-native search is design-blocked)",
|
|
675
|
+
);
|
|
536
676
|
return searchContacts(parsed).map(prepareContactResponse);
|
|
537
677
|
},
|
|
538
678
|
},
|
|
@@ -636,62 +776,33 @@ function handleMergeContactsRoute(args: RouteHandlerArgs) {
|
|
|
636
776
|
}
|
|
637
777
|
}
|
|
638
778
|
|
|
639
|
-
|
|
640
|
-
|
|
779
|
+
/**
|
|
780
|
+
* Relay the channel status/policy update to the gateway-native handler.
|
|
781
|
+
*
|
|
782
|
+
* The gateway DB is the source of truth: it owns validation, the
|
|
783
|
+
* revoke-of-blocked guard, the assistant-side channel-ID backward-compat
|
|
784
|
+
* resolution, the assistant-DB mirror, and the `contacts_changed` emit. This
|
|
785
|
+
* daemon handler writes NOTHING to the assistant DB directly — it forwards the
|
|
786
|
+
* raw channel ID + body and returns the gateway response verbatim. No fallback:
|
|
787
|
+
* an unexpected relay failure surfaces as an error (never a silent second
|
|
788
|
+
* write).
|
|
789
|
+
*/
|
|
790
|
+
export async function handleUpdateContactChannelRoute(args: RouteHandlerArgs) {
|
|
641
791
|
const body = (args.body ?? {}) as {
|
|
642
792
|
status?: string;
|
|
643
793
|
policy?: string;
|
|
644
794
|
reason?: string;
|
|
645
795
|
};
|
|
646
796
|
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
);
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
if (body.status === "revoked") {
|
|
660
|
-
const existing = getChannelById(channelId);
|
|
661
|
-
if (!existing) {
|
|
662
|
-
throw new NotFoundError(`Channel "${channelId}" not found`);
|
|
663
|
-
}
|
|
664
|
-
if (existing.status === "blocked") {
|
|
665
|
-
throw new ConflictError(
|
|
666
|
-
"Cannot revoke a blocked channel. Unblock it first or leave it blocked.",
|
|
667
|
-
);
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
const updated = updateChannelStatus(channelId, {
|
|
672
|
-
status: body.status,
|
|
673
|
-
policy: body.policy,
|
|
674
|
-
revokedReason:
|
|
675
|
-
body.status !== undefined
|
|
676
|
-
? body.status === "revoked"
|
|
677
|
-
? (body.reason ?? null)
|
|
678
|
-
: null
|
|
679
|
-
: undefined,
|
|
680
|
-
blockedReason:
|
|
681
|
-
body.status !== undefined
|
|
682
|
-
? body.status === "blocked"
|
|
683
|
-
? (body.reason ?? null)
|
|
684
|
-
: null
|
|
685
|
-
: undefined,
|
|
686
|
-
});
|
|
687
|
-
|
|
688
|
-
if (!updated) {
|
|
689
|
-
throw new NotFoundError(`Channel "${channelId}" not found`);
|
|
797
|
+
try {
|
|
798
|
+
const result = await ipcCallPersistent("update_contact_channel", {
|
|
799
|
+
contactChannelId: args.pathParams!.contactChannelId,
|
|
800
|
+
...(body.status !== undefined ? { status: body.status } : {}),
|
|
801
|
+
...(body.policy !== undefined ? { policy: body.policy } : {}),
|
|
802
|
+
...(body.reason !== undefined ? { reason: body.reason } : {}),
|
|
803
|
+
});
|
|
804
|
+
return UpdateContactChannelIpcResponseSchema.parse(result);
|
|
805
|
+
} catch (err) {
|
|
806
|
+
rethrowGatewayError(err);
|
|
690
807
|
}
|
|
691
|
-
|
|
692
|
-
const parentContact = getContact(updated.contactId);
|
|
693
|
-
return {
|
|
694
|
-
ok: true,
|
|
695
|
-
contact: parentContact ? prepareContactResponse(parentContact) : undefined,
|
|
696
|
-
};
|
|
697
808
|
}
|
|
@@ -85,7 +85,10 @@ import { PROVIDER_CATALOG } from "../../providers/model-catalog.js";
|
|
|
85
85
|
import { initializeProviders } from "../../providers/registry.js";
|
|
86
86
|
import { credentialKey } from "../../security/credential-key.js";
|
|
87
87
|
import { validateAllowlistFile } from "../../security/secret-allowlist.js";
|
|
88
|
-
import {
|
|
88
|
+
import {
|
|
89
|
+
resolvePricingForUsage,
|
|
90
|
+
usesAnthropicPricingRules,
|
|
91
|
+
} from "../../util/pricing.js";
|
|
89
92
|
import { BadRequestError, InternalError, NotFoundError } from "./errors.js";
|
|
90
93
|
import {
|
|
91
94
|
type LlmContextSummary,
|
|
@@ -212,10 +215,17 @@ function attachEstimatedCost(summary: LlmContextSummary): LlmContextSummary {
|
|
|
212
215
|
|
|
213
216
|
const cacheCreation = summary.cacheCreationInputTokens ?? 0;
|
|
214
217
|
const cacheRead = summary.cacheReadInputTokens ?? 0;
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
218
|
+
// `inputTokens` carries provider-shape-dependent cache accounting. Anthropic
|
|
219
|
+
// Messages responses (native and OpenRouter `anthropic/*`) report `input_tokens`
|
|
220
|
+
// already net of cache — cache-creation/read are separate, additive buckets —
|
|
221
|
+
// so the full-rate portion IS `inputTokens`. OpenAI/Gemini report a total
|
|
222
|
+
// prompt-token count with cached tokens as a subset, so the full-rate portion
|
|
223
|
+
// is the total minus cache. `usesAnthropicPricingRules` selects the same
|
|
224
|
+
// response shapes the pricing layer treats as Anthropic (keyed on the stored
|
|
225
|
+
// transport provider + model), so it also distinguishes the cache accounting.
|
|
226
|
+
const directInputTokens = usesAnthropicPricingRules(provider, model)
|
|
227
|
+
? Math.max(inputTokens, 0)
|
|
228
|
+
: Math.max(inputTokens - cacheCreation - cacheRead, 0);
|
|
219
229
|
|
|
220
230
|
const result = resolvePricingForUsage(provider, model, {
|
|
221
231
|
directInputTokens,
|
|
@@ -10,7 +10,10 @@ import {
|
|
|
10
10
|
createAssistantMessage,
|
|
11
11
|
createUserMessage,
|
|
12
12
|
} from "../../agent/message-types.js";
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
type ConversationContentBlock,
|
|
15
|
+
ConversationMessageSchema,
|
|
16
|
+
} from "../../api/responses/conversation-message.js";
|
|
14
17
|
import {
|
|
15
18
|
CHANNEL_IDS,
|
|
16
19
|
INTERFACE_IDS,
|
|
@@ -943,7 +946,25 @@ export function handleListMessages({
|
|
|
943
946
|
.filter((block) => block.type !== "text" || block.text.length > 0);
|
|
944
947
|
}
|
|
945
948
|
|
|
946
|
-
|
|
949
|
+
// Ensure every hydrated attachment has a corresponding content block.
|
|
950
|
+
// renderHistoryContent inlines attachment blocks only when it has
|
|
951
|
+
// file-block refs with matching DB rows; directives (assistant-authored
|
|
952
|
+
// <vellum-attachment/> tags) don't leave a file block after stripping,
|
|
953
|
+
// so their attachments end up in the flat `attachments` array but not in
|
|
954
|
+
// `contentBlocks`. Append any that are missing so the canonical
|
|
955
|
+
// projection is complete.
|
|
956
|
+
const existingAttachmentIds = new Set(
|
|
957
|
+
contentBlocks
|
|
958
|
+
.filter((b): b is Extract<ConversationContentBlock, { type: "attachment" }> => b.type === "attachment")
|
|
959
|
+
.map((b) => b.attachment.id),
|
|
960
|
+
);
|
|
961
|
+
for (const att of msgAttachments) {
|
|
962
|
+
if (!existingAttachmentIds.has(att.id)) {
|
|
963
|
+
contentBlocks.push({ type: "attachment", attachment: att });
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
const alignedContentOrder = aligned.rewriteContentOrder(contentOrder);
|
|
947
968
|
|
|
948
969
|
// Use sentAt (actual event time) for the display timestamp when available,
|
|
949
970
|
// falling back to createdAt (persistence time). Clients use this display
|
|
@@ -971,7 +992,7 @@ export function handleListMessages({
|
|
|
971
992
|
...(alignedContentOrder.length > 0
|
|
972
993
|
? { contentOrder: alignedContentOrder }
|
|
973
994
|
: {}),
|
|
974
|
-
|
|
995
|
+
contentBlocks,
|
|
975
996
|
...(m.subagentNotification
|
|
976
997
|
? { subagentNotification: m.subagentNotification }
|
|
977
998
|
: {}),
|