@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
|
@@ -11,6 +11,7 @@ import type { ModelIntent } from "../providers/types.js";
|
|
|
11
11
|
import { credentialKey } from "../security/credential-key.js";
|
|
12
12
|
import { getLogger } from "../util/logger.js";
|
|
13
13
|
import { loadRawConfig, saveRawConfig } from "./loader.js";
|
|
14
|
+
import { isDispatchableProfile } from "./profile-dispatchability.js";
|
|
14
15
|
import {
|
|
15
16
|
DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS,
|
|
16
17
|
type ProfileEntry,
|
|
@@ -41,12 +42,12 @@ type ManagedProfileTemplate = Omit<
|
|
|
41
42
|
* (`preserveProfileNames`) take precedence when present.
|
|
42
43
|
*/
|
|
43
44
|
const MANAGED_PROFILE_TEMPLATES: Record<string, ManagedProfileTemplate> = {
|
|
44
|
-
// Served by MiniMax M3 on
|
|
45
|
+
// Served by MiniMax M3 on Together AI via managed platform inference: a strong
|
|
45
46
|
// open model at a lower price point than the managed Anthropic route.
|
|
46
47
|
balanced: {
|
|
47
48
|
intent: "balanced",
|
|
48
|
-
provider: "
|
|
49
|
-
connectionName: "
|
|
49
|
+
provider: "together",
|
|
50
|
+
connectionName: "together-managed",
|
|
50
51
|
source: "managed",
|
|
51
52
|
label: "Balanced",
|
|
52
53
|
description: "Good balance of quality, cost, and speed",
|
|
@@ -56,12 +57,28 @@ const MANAGED_PROFILE_TEMPLATES: Record<string, ManagedProfileTemplate> = {
|
|
|
56
57
|
contextWindow: { maxInputTokens: DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS },
|
|
57
58
|
topP: 0.95,
|
|
58
59
|
},
|
|
60
|
+
// Served by GLM 5.2 on Fireworks via managed platform inference: a leading
|
|
61
|
+
// open model. `model` is pinned explicitly rather than resolved via the
|
|
62
|
+
// `quality-optimized` intent (which still maps to Anthropic Opus for the
|
|
63
|
+
// `frontier` profile below).
|
|
59
64
|
"quality-optimized": {
|
|
65
|
+
model: "accounts/fireworks/models/glm-5p2",
|
|
66
|
+
provider: "fireworks",
|
|
67
|
+
connectionName: "fireworks-managed",
|
|
68
|
+
source: "managed",
|
|
69
|
+
label: "Quality",
|
|
70
|
+
description: "High-quality results with a leading open model (GLM 5.2)",
|
|
71
|
+
maxTokens: 32000,
|
|
72
|
+
effort: "high",
|
|
73
|
+
thinking: { enabled: true, streamThinking: true },
|
|
74
|
+
contextWindow: { maxInputTokens: DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS },
|
|
75
|
+
},
|
|
76
|
+
frontier: {
|
|
60
77
|
intent: "quality-optimized",
|
|
61
78
|
provider: "anthropic",
|
|
62
79
|
connectionName: "anthropic-managed",
|
|
63
80
|
source: "managed",
|
|
64
|
-
label: "
|
|
81
|
+
label: "Frontier",
|
|
65
82
|
description: "Best results with the most capable model",
|
|
66
83
|
maxTokens: 32000,
|
|
67
84
|
effort: "high",
|
|
@@ -131,14 +148,6 @@ const USER_PROFILE_TEMPLATES: Record<string, ManagedProfileTemplate> = {
|
|
|
131
148
|
},
|
|
132
149
|
};
|
|
133
150
|
|
|
134
|
-
/**
|
|
135
|
-
* The "auto" profile key. When active, the daemon injects the
|
|
136
|
-
* `switch_inference_profile` tool and lets the model self-select a profile
|
|
137
|
-
* per query. No provider/model — the resolver falls through to the call-site
|
|
138
|
-
* default (balanced or custom-balanced for BYOK).
|
|
139
|
-
*/
|
|
140
|
-
export const AUTO_PROFILE_KEY = "auto";
|
|
141
|
-
|
|
142
151
|
export const OS_BETA_PROFILE_KEY = "os-beta";
|
|
143
152
|
export const OS_BETA_FEATURE_FLAG_KEY = "os-beta";
|
|
144
153
|
|
|
@@ -170,9 +179,19 @@ export const OS_BETA_PROFILE_TEMPLATE: ManagedProfileTemplate = {
|
|
|
170
179
|
export const MANAGED_PROFILE_NAMES = new Set([
|
|
171
180
|
...Object.keys(MANAGED_PROFILE_TEMPLATES),
|
|
172
181
|
OS_BETA_PROFILE_KEY,
|
|
173
|
-
AUTO_PROFILE_KEY,
|
|
174
182
|
]);
|
|
175
183
|
|
|
184
|
+
// Managed names introduced after profile-ownership metadata existed, so any
|
|
185
|
+
// pre-existing same-named entry must have been user-created. The seed loop
|
|
186
|
+
// protects these from being clobbered: a user may already own a profile under
|
|
187
|
+
// such a name (the settings UI saves custom profiles without a `source`), so an
|
|
188
|
+
// entry that isn't explicitly `source: "managed"` is treated as theirs. The
|
|
189
|
+
// original canonical names (`balanced`/`quality-optimized`/`cost-optimized`)
|
|
190
|
+
// predate ownership metadata — migration 052 seeded them source-less — so they
|
|
191
|
+
// are NOT listed here and always reseed, even when source is absent.
|
|
192
|
+
const NEWLY_RESERVED_MANAGED_NAMES = new Set(["frontier"]);
|
|
193
|
+
const MIX_MIN_ARMS = 2;
|
|
194
|
+
|
|
176
195
|
export type SeedInferenceProfilesOptions = {
|
|
177
196
|
/**
|
|
178
197
|
* Profile names supplied by the platform/default overlay for this startup.
|
|
@@ -289,6 +308,21 @@ export function seedInferenceProfiles(
|
|
|
289
308
|
if (preservedProfileNames.has(name)) continue;
|
|
290
309
|
|
|
291
310
|
const previous = readObject(profiles[name]);
|
|
311
|
+
// Never clobber a custom profile that happens to share a *newly reserved*
|
|
312
|
+
// managed name (e.g. `frontier`): reseeding would change its provider/model
|
|
313
|
+
// and mark it managed. Treat anything not explicitly `source: "managed"` as
|
|
314
|
+
// the user's, since the settings UI saves custom profiles without a `source`
|
|
315
|
+
// and the source backfill below skips managed names. The original canonical
|
|
316
|
+
// names are excluded from this guard — they may be source-less *managed*
|
|
317
|
+
// entries from migration 052, so they must keep reseeding to receive
|
|
318
|
+
// template updates (see NEWLY_RESERVED_MANAGED_NAMES).
|
|
319
|
+
if (
|
|
320
|
+
NEWLY_RESERVED_MANAGED_NAMES.has(name) &&
|
|
321
|
+
previous &&
|
|
322
|
+
previous.source !== "managed"
|
|
323
|
+
) {
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
292
326
|
const effectiveTemplate: ManagedProfileTemplate = isByokMode
|
|
293
327
|
? { ...template, label: `${template.label} (Managed)` }
|
|
294
328
|
: template;
|
|
@@ -334,25 +368,6 @@ export function seedInferenceProfiles(
|
|
|
334
368
|
profiles[name] = next as ProfileEntry;
|
|
335
369
|
}
|
|
336
370
|
|
|
337
|
-
// 1b. Auto profile — a metadata-only profile with no provider/model. When
|
|
338
|
-
// the user selects "Auto", the resolver falls through to the call-site
|
|
339
|
-
// default (balanced or custom-balanced), and the agent loop injects the
|
|
340
|
-
// switch_inference_profile tool so the model can self-select per query.
|
|
341
|
-
if (!preservedProfileNames.has(AUTO_PROFILE_KEY)) {
|
|
342
|
-
const previousAuto = readObject(profiles[AUTO_PROFILE_KEY]);
|
|
343
|
-
const autoEntry: Record<string, unknown> = {
|
|
344
|
-
source: "managed",
|
|
345
|
-
label: "Auto",
|
|
346
|
-
description:
|
|
347
|
-
"Automatically routes each query to the best profile — fast for simple questions, capable for complex ones",
|
|
348
|
-
};
|
|
349
|
-
if (previousAuto) {
|
|
350
|
-
if ("label" in previousAuto) autoEntry.label = previousAuto.label;
|
|
351
|
-
if ("status" in previousAuto) autoEntry.status = previousAuto.status;
|
|
352
|
-
}
|
|
353
|
-
profiles[AUTO_PROFILE_KEY] = autoEntry as ProfileEntry;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
371
|
// 2. User profiles — only at hatch time for off-platform installations.
|
|
357
372
|
let userConnectionName: string | undefined;
|
|
358
373
|
if (options.isHatch && !isPlatform) {
|
|
@@ -394,6 +409,8 @@ export function seedInferenceProfiles(
|
|
|
394
409
|
}
|
|
395
410
|
}
|
|
396
411
|
|
|
412
|
+
pruneNonDispatchableProfiles(llm, profiles);
|
|
413
|
+
|
|
397
414
|
// Active profile resolution.
|
|
398
415
|
const requestedActiveProfile = readString(llm.activeProfile);
|
|
399
416
|
const requestedActiveEntry =
|
|
@@ -414,26 +431,26 @@ export function seedInferenceProfiles(
|
|
|
414
431
|
}
|
|
415
432
|
|
|
416
433
|
// Advisor profile: default to the strongest managed profile when unset, so
|
|
417
|
-
// the advisor consults `
|
|
418
|
-
//
|
|
419
|
-
//
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
434
|
+
// the advisor consults `frontier` (Anthropic Opus) out of the box, falling
|
|
435
|
+
// back to `quality-optimized` if `frontier` is unavailable. The `frontier`
|
|
436
|
+
// arm requires managed ownership: the seed loop above leaves a user-owned
|
|
437
|
+
// profile named `frontier` in place, and pointing the advisor at that would
|
|
438
|
+
// consult an arbitrary user model. Guarded on existence so it never names a
|
|
439
|
+
// missing profile (superRefine rejects that); off-platform/BYOK installs can
|
|
440
|
+
// repoint it at one of their own profiles.
|
|
441
|
+
if (readString(llm.advisorProfile) === undefined) {
|
|
442
|
+
if (readObject(profiles["frontier"])?.source === "managed") {
|
|
443
|
+
llm.advisorProfile = "frontier";
|
|
444
|
+
} else if (readObject(profiles["quality-optimized"]) !== null) {
|
|
445
|
+
llm.advisorProfile = "quality-optimized";
|
|
446
|
+
}
|
|
425
447
|
}
|
|
426
448
|
|
|
427
449
|
// Profile ordering — ensure all seeded profiles appear in the order array.
|
|
428
|
-
// "auto" is prepended so it appears first in the picker.
|
|
429
450
|
const profileOrder = Array.isArray(llm.profileOrder)
|
|
430
451
|
? (llm.profileOrder as string[])
|
|
431
452
|
: [];
|
|
432
453
|
const orderSet = new Set(profileOrder);
|
|
433
|
-
if (!orderSet.has(AUTO_PROFILE_KEY)) {
|
|
434
|
-
profileOrder.unshift(AUTO_PROFILE_KEY);
|
|
435
|
-
orderSet.add(AUTO_PROFILE_KEY);
|
|
436
|
-
}
|
|
437
454
|
for (const name of Object.keys(MANAGED_PROFILE_TEMPLATES)) {
|
|
438
455
|
if (!orderSet.has(name)) {
|
|
439
456
|
profileOrder.push(name);
|
|
@@ -490,6 +507,77 @@ export function readObject(value: unknown): Record<string, unknown> | null {
|
|
|
490
507
|
: null;
|
|
491
508
|
}
|
|
492
509
|
|
|
510
|
+
function pruneNonDispatchableProfiles(
|
|
511
|
+
llm: Record<string, unknown>,
|
|
512
|
+
profiles: Record<string, Record<string, unknown>>,
|
|
513
|
+
): void {
|
|
514
|
+
const removed = new Set<string>();
|
|
515
|
+
for (const [name, profile] of Object.entries(profiles)) {
|
|
516
|
+
if (!isDispatchableProfile(profile)) {
|
|
517
|
+
delete profiles[name];
|
|
518
|
+
removed.add(name);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
pruneRemovedProfileReferences(llm, profiles, removed);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
function pruneRemovedProfileReferences(
|
|
525
|
+
llm: Record<string, unknown>,
|
|
526
|
+
profiles: Record<string, Record<string, unknown>>,
|
|
527
|
+
removed: Set<string>,
|
|
528
|
+
): void {
|
|
529
|
+
if (removed.size === 0) return;
|
|
530
|
+
|
|
531
|
+
let cascading = true;
|
|
532
|
+
while (cascading) {
|
|
533
|
+
cascading = false;
|
|
534
|
+
for (const [name, profile] of Object.entries(profiles)) {
|
|
535
|
+
if (removed.has(name)) continue;
|
|
536
|
+
if (!Array.isArray(profile.mix)) continue;
|
|
537
|
+
const arms = profile.mix as unknown[];
|
|
538
|
+
const kept = arms.filter((arm) => {
|
|
539
|
+
const armProfile = readObject(arm)?.profile;
|
|
540
|
+
return typeof armProfile !== "string" || !removed.has(armProfile);
|
|
541
|
+
});
|
|
542
|
+
if (kept.length === arms.length) continue;
|
|
543
|
+
if (kept.length >= MIX_MIN_ARMS) {
|
|
544
|
+
profile.mix = kept;
|
|
545
|
+
} else {
|
|
546
|
+
delete profiles[name];
|
|
547
|
+
removed.add(name);
|
|
548
|
+
}
|
|
549
|
+
cascading = true;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
if (Array.isArray(llm.profileOrder)) {
|
|
554
|
+
llm.profileOrder = (llm.profileOrder as unknown[]).filter(
|
|
555
|
+
(name) => typeof name !== "string" || !removed.has(name),
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
if (
|
|
560
|
+
typeof llm.advisorProfile === "string" &&
|
|
561
|
+
removed.has(llm.advisorProfile)
|
|
562
|
+
) {
|
|
563
|
+
delete llm.advisorProfile;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
const callSites = readObject(llm.callSites);
|
|
567
|
+
if (callSites) {
|
|
568
|
+
for (const entry of Object.values(callSites)) {
|
|
569
|
+
const site = readObject(entry);
|
|
570
|
+
if (
|
|
571
|
+
site &&
|
|
572
|
+
typeof site.profile === "string" &&
|
|
573
|
+
removed.has(site.profile)
|
|
574
|
+
) {
|
|
575
|
+
delete site.profile;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
493
581
|
function readString(value: unknown): string | undefined {
|
|
494
582
|
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
495
583
|
}
|
|
@@ -193,7 +193,19 @@ function disableProfile(
|
|
|
193
193
|
typeof llm.advisorProfile === "string" &&
|
|
194
194
|
removed.has(llm.advisorProfile)
|
|
195
195
|
) {
|
|
196
|
-
|
|
196
|
+
// Repoint the advisor at the managed Frontier profile (the strongest).
|
|
197
|
+
// `frontier` is seeded unconditionally every boot, so target it even if it
|
|
198
|
+
// has not been materialized yet this startup — this reconcile can run before
|
|
199
|
+
// the seeder in the boot sequence, and the later seeder won't rewrite an
|
|
200
|
+
// already-set `advisorProfile`. The exception is a user-owned profile named
|
|
201
|
+
// `frontier`: that is not ours to route to, so fall back to the
|
|
202
|
+
// always-managed Quality profile, then clear the pointer as a last resort.
|
|
203
|
+
const frontierEntry = readObject(profiles["frontier"]);
|
|
204
|
+
const frontierIsUserOwned =
|
|
205
|
+
frontierEntry !== null && frontierEntry.source !== "managed";
|
|
206
|
+
if (!frontierIsUserOwned) {
|
|
207
|
+
llm.advisorProfile = "frontier";
|
|
208
|
+
} else if (readObject(profiles["quality-optimized"]) !== null) {
|
|
197
209
|
llm.advisorProfile = "quality-optimized";
|
|
198
210
|
} else {
|
|
199
211
|
delete llm.advisorProfile;
|
|
@@ -184,6 +184,27 @@ export function getContact(id: string): ContactWithChannels | null {
|
|
|
184
184
|
/** @deprecated Use {@link getContact} directly. */
|
|
185
185
|
export const getContactInternal = getContact;
|
|
186
186
|
|
|
187
|
+
/** INFO-only contact fields, joined locally by contact ID. */
|
|
188
|
+
export interface ContactInfo {
|
|
189
|
+
notes: string | null;
|
|
190
|
+
interactionCount: number;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Look up a contact's INFO fields (notes, interaction count) by ID.
|
|
195
|
+
*
|
|
196
|
+
* Carries no ACL state (status/policy/verification) — those are owned by the
|
|
197
|
+
* gateway-stamped trust verdict. Returns null when the contact does not exist.
|
|
198
|
+
*/
|
|
199
|
+
export function findContactInfoById(contactId: string): ContactInfo | null {
|
|
200
|
+
const contact = getContact(contactId);
|
|
201
|
+
if (!contact) return null;
|
|
202
|
+
return {
|
|
203
|
+
notes: contact.notes,
|
|
204
|
+
interactionCount: contact.interactionCount,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
187
208
|
/**
|
|
188
209
|
* Look up a single contact channel by its primary key.
|
|
189
210
|
* Returns the parsed channel row, or null if it does not exist.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ChannelStatus } from "./types.js";
|
|
2
|
+
|
|
3
|
+
/** Map ChannelStatus to the API-facing member status (excludes "unverified"). */
|
|
4
|
+
export function channelStatusToMemberStatus(
|
|
5
|
+
status: ChannelStatus,
|
|
6
|
+
): Exclude<ChannelStatus, "unverified"> {
|
|
7
|
+
if (status === "unverified") return "pending";
|
|
8
|
+
return status;
|
|
9
|
+
}
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
type OAuthConnectionRow,
|
|
25
25
|
type OAuthProviderRow,
|
|
26
26
|
} from "../oauth/oauth-store.js";
|
|
27
|
+
import { scopeDifference } from "../oauth/scope-utils.js";
|
|
27
28
|
import {
|
|
28
29
|
TokenExpiredError,
|
|
29
30
|
withValidToken,
|
|
@@ -77,11 +78,6 @@ function safeJsonParse<T>(raw: string | null | undefined, fallback: T): T {
|
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
function scopeDifference(required: string[], granted: string[]): string[] {
|
|
81
|
-
const grantedSet = new Set(granted);
|
|
82
|
-
return required.filter((s) => !grantedSet.has(s));
|
|
83
|
-
}
|
|
84
|
-
|
|
85
81
|
// ── Liveness ping ─────────────────────────────────────────────────────
|
|
86
82
|
|
|
87
83
|
/** @internal Exposed for test injection. */
|
|
@@ -47,6 +47,20 @@ mock.module("../../runtime/assistant-event-hub.js", () => ({
|
|
|
47
47
|
broadcastMessage: () => {},
|
|
48
48
|
}));
|
|
49
49
|
|
|
50
|
+
// Control the advisor profile gate to verify the advisor tool is wired to it.
|
|
51
|
+
// The gate's own config semantics (default-on, active-profile fallback) are
|
|
52
|
+
// covered by advisor-gate.test.ts; here we only assert the wiring and the
|
|
53
|
+
// profile argument isToolActiveForContext passes through.
|
|
54
|
+
let advisorGateResult = true;
|
|
55
|
+
const advisorGateProfiles: (string | null)[] = [];
|
|
56
|
+
|
|
57
|
+
mock.module("../../plugins/defaults/advisor/advisor-gate.js", () => ({
|
|
58
|
+
advisorEnabledForProfile: (profile: string | null) => {
|
|
59
|
+
advisorGateProfiles.push(profile);
|
|
60
|
+
return advisorGateResult;
|
|
61
|
+
},
|
|
62
|
+
}));
|
|
63
|
+
|
|
50
64
|
// Dynamic imports after mock.module calls so the stubs take effect
|
|
51
65
|
// before the modules under test are loaded.
|
|
52
66
|
const { HOST_TOOL_NAMES, HOST_TOOL_TO_CAPABILITY, isToolActiveForContext } =
|
|
@@ -597,6 +611,36 @@ describe("isToolActiveForContext — ask_question macOS gating", () => {
|
|
|
597
611
|
});
|
|
598
612
|
});
|
|
599
613
|
|
|
614
|
+
describe("isToolActiveForContext — advisor profile gate", () => {
|
|
615
|
+
beforeEach(() => {
|
|
616
|
+
advisorGateResult = true;
|
|
617
|
+
advisorGateProfiles.length = 0;
|
|
618
|
+
});
|
|
619
|
+
|
|
620
|
+
test("advisor is active when the profile enables it", () => {
|
|
621
|
+
advisorGateResult = true;
|
|
622
|
+
expect(isToolActiveForContext("advisor", makeCtx())).toBe(true);
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
test("advisor is NOT active when the profile disables it", () => {
|
|
626
|
+
advisorGateResult = false;
|
|
627
|
+
expect(isToolActiveForContext("advisor", makeCtx())).toBe(false);
|
|
628
|
+
});
|
|
629
|
+
|
|
630
|
+
test("consults the gate with the per-turn override profile", () => {
|
|
631
|
+
isToolActiveForContext(
|
|
632
|
+
"advisor",
|
|
633
|
+
makeCtx({ currentTurnOverrideProfile: "cost-optimized" }),
|
|
634
|
+
);
|
|
635
|
+
expect(advisorGateProfiles).toEqual(["cost-optimized"]);
|
|
636
|
+
});
|
|
637
|
+
|
|
638
|
+
test("consults the gate with null when no per-turn override is set", () => {
|
|
639
|
+
isToolActiveForContext("advisor", makeCtx());
|
|
640
|
+
expect(advisorGateProfiles).toEqual([null]);
|
|
641
|
+
});
|
|
642
|
+
});
|
|
643
|
+
|
|
600
644
|
describe("HOST_TOOL_NAMES derivation", () => {
|
|
601
645
|
test("HOST_TOOL_NAMES is derived from HOST_TOOL_TO_CAPABILITY", () => {
|
|
602
646
|
// Sanity check: every tool in the names set has a capability mapping.
|
|
@@ -11,11 +11,9 @@
|
|
|
11
11
|
|
|
12
12
|
import { existsSync, type FSWatcher, watch } from "node:fs";
|
|
13
13
|
|
|
14
|
-
import {
|
|
15
|
-
getAppsDir,
|
|
16
|
-
resolveAppIdByDirName,
|
|
17
|
-
} from "../memory/app-store.js";
|
|
14
|
+
import { getAppsDir, resolveAppIdByDirName } from "../memory/app-store.js";
|
|
18
15
|
import { DebouncerMap } from "../util/debounce.js";
|
|
16
|
+
import { attachFsWatcherErrorHandler } from "../util/fs-watcher-error.js";
|
|
19
17
|
import { getLogger } from "../util/logger.js";
|
|
20
18
|
|
|
21
19
|
const log = getLogger("app-source-watcher");
|
|
@@ -51,8 +49,10 @@ function resolveAppIdFromRelPath(relPath: string): string | null {
|
|
|
51
49
|
|
|
52
50
|
// Skip non-source directories (include bare directory names for fs.watch events)
|
|
53
51
|
if (
|
|
54
|
-
innerPath === "records" ||
|
|
55
|
-
innerPath
|
|
52
|
+
innerPath === "records" ||
|
|
53
|
+
innerPath.startsWith("records/") ||
|
|
54
|
+
innerPath === "dist" ||
|
|
55
|
+
innerPath.startsWith("dist/")
|
|
56
56
|
) {
|
|
57
57
|
return null;
|
|
58
58
|
}
|
|
@@ -89,7 +89,9 @@ export class AppSourceWatcher {
|
|
|
89
89
|
try {
|
|
90
90
|
appsDir = getAppsDir();
|
|
91
91
|
} catch {
|
|
92
|
-
log.warn(
|
|
92
|
+
log.warn(
|
|
93
|
+
"Could not resolve apps directory; app source watching disabled",
|
|
94
|
+
);
|
|
93
95
|
return;
|
|
94
96
|
}
|
|
95
97
|
|
|
@@ -102,19 +104,30 @@ export class AppSourceWatcher {
|
|
|
102
104
|
if (!onChange) return;
|
|
103
105
|
|
|
104
106
|
try {
|
|
105
|
-
this.watcher = watch(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
107
|
+
this.watcher = watch(
|
|
108
|
+
appsDir,
|
|
109
|
+
{ recursive: true },
|
|
110
|
+
(_eventType, filename) => {
|
|
111
|
+
if (!filename) return;
|
|
112
|
+
|
|
113
|
+
const appId = resolveAppIdFromRelPath(filename);
|
|
114
|
+
if (!appId) return;
|
|
115
|
+
|
|
116
|
+
this.debouncer.schedule(`app:${appId}`, () => {
|
|
117
|
+
onChange(appId);
|
|
118
|
+
});
|
|
119
|
+
},
|
|
120
|
+
);
|
|
121
|
+
// Recursive watches over app trees (incl. node_modules) can exhaust the
|
|
122
|
+
// inotify watch limit and emit ENOSPC asynchronously. Without an 'error'
|
|
123
|
+
// listener that unhandled emitter error crashes the daemon.
|
|
124
|
+
attachFsWatcherErrorHandler(this.watcher, log, appsDir);
|
|
115
125
|
log.info("App source watcher started");
|
|
116
126
|
} catch (err) {
|
|
117
|
-
log.warn(
|
|
127
|
+
log.warn(
|
|
128
|
+
{ err },
|
|
129
|
+
"Failed to watch apps directory; source watching disabled",
|
|
130
|
+
);
|
|
118
131
|
}
|
|
119
132
|
}
|
|
120
133
|
|
|
@@ -256,6 +256,88 @@ export function parseDirectives(text: string): DirectiveParseResult {
|
|
|
256
256
|
};
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
+
// ---------------------------------------------------------------------------
|
|
260
|
+
// vellum:// markdown link extraction
|
|
261
|
+
// ---------------------------------------------------------------------------
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Match markdown links with `vellum://workspace/` or `vellum://host/` URLs.
|
|
265
|
+
*
|
|
266
|
+
* Captures:
|
|
267
|
+
* [1] = link text (filename)
|
|
268
|
+
* [2] = scheme authority: "workspace" or "host"
|
|
269
|
+
* [3] = path after the authority
|
|
270
|
+
*
|
|
271
|
+
* The link text is NOT stripped from the assistant's message — unlike
|
|
272
|
+
* `<vellum-attachment />` tags, the markdown link is valid user-facing
|
|
273
|
+
* content that renders as a clickable download link.
|
|
274
|
+
*/
|
|
275
|
+
const VELLUM_LINK_RE = /\[([^\]]+)\]\(vellum:\/\/(workspace|host)(\/[^)]*)\)/g;
|
|
276
|
+
|
|
277
|
+
interface VellumLinkExtractResult {
|
|
278
|
+
directiveRequests: DirectiveRequest[];
|
|
279
|
+
parseWarnings: string[];
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Extract `[text](vellum://workspace/path)` and `[text](vellum://host/path)`
|
|
284
|
+
* markdown links from assistant text and return corresponding directive
|
|
285
|
+
* requests. The text is NOT modified — the links remain as rendered markdown.
|
|
286
|
+
*/
|
|
287
|
+
export function extractVellumLinks(text: string): VellumLinkExtractResult {
|
|
288
|
+
const directiveRequests: DirectiveRequest[] = [];
|
|
289
|
+
const parseWarnings: string[] = [];
|
|
290
|
+
|
|
291
|
+
let m: RegExpExecArray | null;
|
|
292
|
+
while ((m = VELLUM_LINK_RE.exec(text)) != null) {
|
|
293
|
+
const linkText = m[1]!;
|
|
294
|
+
const authority = m[2]!;
|
|
295
|
+
const rawPath = m[3]!;
|
|
296
|
+
|
|
297
|
+
if (authority === "workspace") {
|
|
298
|
+
// Strip the leading "/" to get a workspace-relative path
|
|
299
|
+
const path = rawPath.startsWith("/") ? rawPath.slice(1) : rawPath;
|
|
300
|
+
if (!path) {
|
|
301
|
+
parseWarnings.push(
|
|
302
|
+
`Ignored vellum://workspace link "${linkText}": empty path.`,
|
|
303
|
+
);
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
directiveRequests.push({
|
|
307
|
+
source: "sandbox",
|
|
308
|
+
path,
|
|
309
|
+
filename: linkText || undefined,
|
|
310
|
+
mimeType: undefined,
|
|
311
|
+
});
|
|
312
|
+
} else {
|
|
313
|
+
// host: rawPath is already absolute (starts with /)
|
|
314
|
+
if (!rawPath || rawPath === "/") {
|
|
315
|
+
parseWarnings.push(
|
|
316
|
+
`Ignored vellum://host link "${linkText}": empty path.`,
|
|
317
|
+
);
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
directiveRequests.push({
|
|
321
|
+
source: "host",
|
|
322
|
+
path: rawPath,
|
|
323
|
+
filename: linkText || undefined,
|
|
324
|
+
mimeType: undefined,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return { directiveRequests, parseWarnings };
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Replace `[text](vellum://...)` markdown links with their link text.
|
|
334
|
+
* Used to sanitize text before channel delivery (Slack, Telegram, etc.)
|
|
335
|
+
* where the `vellum://` scheme has no meaning.
|
|
336
|
+
*/
|
|
337
|
+
export function stripVellumLinks(text: string): string {
|
|
338
|
+
return text.replace(VELLUM_LINK_RE, "$1");
|
|
339
|
+
}
|
|
340
|
+
|
|
259
341
|
/**
|
|
260
342
|
* Drain streamed assistant text while stripping only valid, complete
|
|
261
343
|
* self-closing `<vellum-attachment ... />` directives.
|
|
@@ -707,10 +789,18 @@ export function cleanAssistantContent(content: readonly unknown[]): {
|
|
|
707
789
|
const b = block as Record<string, unknown>;
|
|
708
790
|
if (b.type !== "text") return block;
|
|
709
791
|
const text = b.text as string;
|
|
710
|
-
|
|
711
|
-
//
|
|
712
|
-
|
|
713
|
-
|
|
792
|
+
|
|
793
|
+
// Extract vellum:// markdown links (non-destructive — links stay in text)
|
|
794
|
+
if (text.includes("vellum://")) {
|
|
795
|
+
const linkResult = extractVellumLinks(text);
|
|
796
|
+
directives.push(...linkResult.directiveRequests);
|
|
797
|
+
warnings.push(...linkResult.parseWarnings);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
// Strip legacy <vellum-attachment /> tags from the text
|
|
801
|
+
if (!text.includes("<vellum-attachment")) {
|
|
802
|
+
return block;
|
|
803
|
+
}
|
|
714
804
|
const result = parseDirectives(text);
|
|
715
805
|
directives.push(...result.directiveRequests);
|
|
716
806
|
warnings.push(...result.parseWarnings);
|