@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
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
} from "node:fs";
|
|
26
26
|
import { join, resolve, sep } from "node:path";
|
|
27
27
|
|
|
28
|
-
import { and, desc, eq, sql } from "drizzle-orm";
|
|
28
|
+
import { and, desc, eq, inArray, notInArray, sql } from "drizzle-orm";
|
|
29
29
|
|
|
30
30
|
import type { AssistantConfig } from "../../config/types.js";
|
|
31
31
|
import { renderCard } from "../../plugins/defaults/memory-v3-shadow/card.js";
|
|
@@ -304,12 +304,67 @@ export function pairTurns(
|
|
|
304
304
|
return capped.slice(0, opts.limit);
|
|
305
305
|
}
|
|
306
306
|
|
|
307
|
-
/**
|
|
307
|
+
/** The conversation id embedded in a `${conversationId}:${createdAt}` turn id. */
|
|
308
|
+
export function turnConversationId(turnId: string): string {
|
|
309
|
+
return turnId.slice(0, turnId.lastIndexOf(":"));
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Keep exactly the pinned turn ids, in pinned order. Turns that no longer exist
|
|
314
|
+
* (deleted since the ids were captured) are dropped — the caller compares the
|
|
315
|
+
* returned count to the requested count to surface drops. Pure over `allTurns`
|
|
316
|
+
* so it is unit-testable.
|
|
317
|
+
*/
|
|
318
|
+
export function selectPinnedTurns(
|
|
319
|
+
allTurns: MinedTurn[],
|
|
320
|
+
pinnedTurnIds: string[],
|
|
321
|
+
): MinedTurn[] {
|
|
322
|
+
const byId = new Map(allTurns.map((t) => [t.turn, t]));
|
|
323
|
+
const out: MinedTurn[] = [];
|
|
324
|
+
for (const id of pinnedTurnIds) {
|
|
325
|
+
const t = byId.get(id);
|
|
326
|
+
if (t) out.push(t);
|
|
327
|
+
}
|
|
328
|
+
return out;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/** Group by conversation, ascending by time, so `pairTurns` walks each in order. */
|
|
332
|
+
function sortForPairing(rows: RawMsgRow[]): RawMsgRow[] {
|
|
333
|
+
return [...rows].sort(
|
|
334
|
+
(a, b) =>
|
|
335
|
+
a.conversationId.localeCompare(b.conversationId) ||
|
|
336
|
+
a.createdAt - b.createdAt ||
|
|
337
|
+
a.id.localeCompare(b.id),
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Read user→assistant turns from the live DB (read-only).
|
|
343
|
+
*
|
|
344
|
+
* Default: the most recent `limit` turns by recency, optionally omitting given
|
|
345
|
+
* conversations — e.g. the migration's own chat, which would otherwise let the
|
|
346
|
+
* eval judge turns from the very conversation driving the migration. With
|
|
347
|
+
* `pinnedTurnIds`, instead re-mine EXACTLY those turns (scoped to their
|
|
348
|
+
* conversations, no recency window) so a re-run measures the same turn set as a
|
|
349
|
+
* prior run — the eval is only reproducible if the turns are held fixed while
|
|
350
|
+
* the staged corpus changes.
|
|
351
|
+
*/
|
|
308
352
|
export function mineTurns(
|
|
309
353
|
db: DrizzleDb,
|
|
310
|
-
opts: {
|
|
354
|
+
opts: {
|
|
355
|
+
limit: number;
|
|
356
|
+
perConversationCap: number;
|
|
357
|
+
maxScan?: number;
|
|
358
|
+
pinnedTurnIds?: string[];
|
|
359
|
+
excludeConversationIds?: string[];
|
|
360
|
+
},
|
|
311
361
|
): MinedTurn[] {
|
|
362
|
+
if (opts.pinnedTurnIds && opts.pinnedTurnIds.length > 0) {
|
|
363
|
+
return minePinnedTurns(db, opts.pinnedTurnIds);
|
|
364
|
+
}
|
|
365
|
+
|
|
312
366
|
const maxScan = opts.maxScan ?? 6000;
|
|
367
|
+
const exclude = opts.excludeConversationIds ?? [];
|
|
313
368
|
const recent = db
|
|
314
369
|
.select({
|
|
315
370
|
conversationId: messages.conversationId,
|
|
@@ -324,20 +379,45 @@ export function mineTurns(
|
|
|
324
379
|
and(
|
|
325
380
|
sql`COALESCE(${conversations.source}, 'user') = 'user'`,
|
|
326
381
|
sql`${conversations.scheduleJobId} IS NULL`,
|
|
382
|
+
...(exclude.length > 0
|
|
383
|
+
? [notInArray(messages.conversationId, exclude)]
|
|
384
|
+
: []),
|
|
327
385
|
),
|
|
328
386
|
)
|
|
329
387
|
.orderBy(desc(messages.createdAt), desc(messages.id))
|
|
330
388
|
.limit(maxScan)
|
|
331
389
|
.all() as RawMsgRow[];
|
|
332
390
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
391
|
+
return pairTurns(sortForPairing(recent), opts);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/** Re-mine exactly the pinned turns from their conversations (no recency cap). */
|
|
395
|
+
function minePinnedTurns(db: DrizzleDb, pinnedTurnIds: string[]): MinedTurn[] {
|
|
396
|
+
const conversationIds = [...new Set(pinnedTurnIds.map(turnConversationId))];
|
|
397
|
+
const rows = db
|
|
398
|
+
.select({
|
|
399
|
+
conversationId: messages.conversationId,
|
|
400
|
+
id: messages.id,
|
|
401
|
+
role: messages.role,
|
|
402
|
+
content: messages.content,
|
|
403
|
+
createdAt: messages.createdAt,
|
|
404
|
+
})
|
|
405
|
+
.from(messages)
|
|
406
|
+
.innerJoin(conversations, eq(messages.conversationId, conversations.id))
|
|
407
|
+
.where(
|
|
408
|
+
and(
|
|
409
|
+
inArray(messages.conversationId, conversationIds),
|
|
410
|
+
sql`COALESCE(${conversations.source}, 'user') = 'user'`,
|
|
411
|
+
sql`${conversations.scheduleJobId} IS NULL`,
|
|
412
|
+
),
|
|
413
|
+
)
|
|
414
|
+
.all() as RawMsgRow[];
|
|
415
|
+
|
|
416
|
+
const allTurns = pairTurns(sortForPairing(rows), {
|
|
417
|
+
limit: Number.MAX_SAFE_INTEGER,
|
|
418
|
+
perConversationCap: Number.MAX_SAFE_INTEGER,
|
|
419
|
+
});
|
|
420
|
+
return selectPinnedTurns(allTurns, pinnedTurnIds);
|
|
341
421
|
}
|
|
342
422
|
|
|
343
423
|
// ---------------------------------------------------------------------------
|
|
@@ -436,16 +516,52 @@ export interface EvalParams {
|
|
|
436
516
|
dense?: boolean;
|
|
437
517
|
seed?: number;
|
|
438
518
|
sectionCharCap?: number;
|
|
519
|
+
/**
|
|
520
|
+
* Pin the exact turns to mine (the `turn` ids from a prior run's key.json or
|
|
521
|
+
* packets.json). Re-running with the same pinned set holds the comparison
|
|
522
|
+
* fixed while the staged corpus changes — required for a reproducible re-judge.
|
|
523
|
+
*/
|
|
524
|
+
turnIds?: string[];
|
|
525
|
+
/**
|
|
526
|
+
* Conversations to omit from the default (recency) mining — e.g. the
|
|
527
|
+
* migration's own chat, so the eval does not judge turns from the very
|
|
528
|
+
* conversation driving it. Ignored when `turnIds` is set.
|
|
529
|
+
*/
|
|
530
|
+
excludeConversationIds?: string[];
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* The embedding backend identity in effect for a run, recorded in eval-meta.json.
|
|
535
|
+
* Dense retrieval is only comparable across runs with the SAME identity: a
|
|
536
|
+
* mid-migration config change (e.g. a 384-dim local model to a 3072-dim hosted
|
|
537
|
+
* one) silently re-embeds both corpora in a different vector space, so a re-run
|
|
538
|
+
* that drifted here is measuring something different — exactly the kind of hidden
|
|
539
|
+
* variable that made an eval gate look non-reproducible.
|
|
540
|
+
*/
|
|
541
|
+
export interface EmbeddingIdentity {
|
|
542
|
+
provider: string;
|
|
543
|
+
model: string;
|
|
544
|
+
/** Observed embedding dimension (from the first vector); null when dense is off. */
|
|
545
|
+
dims: number | null;
|
|
439
546
|
}
|
|
440
547
|
|
|
441
548
|
export interface EvalResult {
|
|
442
549
|
turnsMined: number;
|
|
550
|
+
/** Turns requested: the pinned count, or the recency `turns` limit. */
|
|
551
|
+
turnsRequested: number;
|
|
443
552
|
packetsWritten: number;
|
|
444
553
|
packetsPath: string;
|
|
445
554
|
keyPath: string;
|
|
555
|
+
/** eval-meta.json: seed/k/dense/embedding identity + the resolved turn ids. */
|
|
556
|
+
metaPath: string;
|
|
446
557
|
snapshotPages: number;
|
|
447
558
|
stagingPages: number;
|
|
448
559
|
dense: boolean;
|
|
560
|
+
seed: number;
|
|
561
|
+
k: number;
|
|
562
|
+
embedding: EmbeddingIdentity;
|
|
563
|
+
/** The resolved turn ids actually packed — pass as `turnIds` to pin a re-run. */
|
|
564
|
+
turnIds: string[];
|
|
449
565
|
}
|
|
450
566
|
|
|
451
567
|
export interface EvalDeps {
|
|
@@ -456,6 +572,26 @@ export interface EvalDeps {
|
|
|
456
572
|
embed?: EmbedAll;
|
|
457
573
|
}
|
|
458
574
|
|
|
575
|
+
/** Human-readable identity of the configured embedding model (provider + model name). */
|
|
576
|
+
function describeEmbeddingModel(config: AssistantConfig): {
|
|
577
|
+
provider: string;
|
|
578
|
+
model: string;
|
|
579
|
+
} {
|
|
580
|
+
const e = config.memory?.embeddings;
|
|
581
|
+
const provider = e?.provider ?? "unknown";
|
|
582
|
+
const model =
|
|
583
|
+
provider === "gemini"
|
|
584
|
+
? e?.geminiModel
|
|
585
|
+
: provider === "openai"
|
|
586
|
+
? e?.openaiModel
|
|
587
|
+
: provider === "ollama"
|
|
588
|
+
? e?.ollamaModel
|
|
589
|
+
: provider === "local"
|
|
590
|
+
? e?.localModel
|
|
591
|
+
: provider; // "auto" / future providers: name == provider
|
|
592
|
+
return { provider, model: model ?? provider };
|
|
593
|
+
}
|
|
594
|
+
|
|
459
595
|
/** Chunk an embed function so a large corpus never overruns provider batch limits. */
|
|
460
596
|
function chunkedEmbed(embed: EmbedAll, batchSize = 96): EmbedAll {
|
|
461
597
|
return async (texts: string[]) => {
|
|
@@ -502,7 +638,17 @@ export async function runMemoryEval(
|
|
|
502
638
|
const baseEmbed: EmbedAll =
|
|
503
639
|
deps.embed ??
|
|
504
640
|
(async (texts) => (await embedWithRetry(deps.config, texts)).vectors);
|
|
505
|
-
|
|
641
|
+
// Capture the observed embedding dimension so eval-meta.json records the
|
|
642
|
+
// vector space the dense lane actually ran in (drift detection across re-runs).
|
|
643
|
+
let observedDims: number | null = null;
|
|
644
|
+
const capturingEmbed: EmbedAll = async (texts) => {
|
|
645
|
+
const vectors = await baseEmbed(texts);
|
|
646
|
+
if (observedDims === null && vectors.length > 0 && vectors[0]) {
|
|
647
|
+
observedDims = vectors[0].length;
|
|
648
|
+
}
|
|
649
|
+
return vectors;
|
|
650
|
+
};
|
|
651
|
+
const embedAll = chunkedEmbed(capturingEmbed);
|
|
506
652
|
|
|
507
653
|
const snapshotCorpus = loadCorpus(snapshotDir);
|
|
508
654
|
const stagingCorpus = loadCorpus(stagingDir);
|
|
@@ -510,9 +656,17 @@ export async function runMemoryEval(
|
|
|
510
656
|
const snapshot = await buildRetriever(snapshotCorpus, embedAll, dense);
|
|
511
657
|
const staging = await buildRetriever(stagingCorpus, embedAll, dense);
|
|
512
658
|
|
|
659
|
+
const turnsRequested =
|
|
660
|
+
params.turnIds && params.turnIds.length > 0
|
|
661
|
+
? params.turnIds.length
|
|
662
|
+
: (params.turns ?? 30);
|
|
513
663
|
const turns = mineTurns(deps.db, {
|
|
514
664
|
limit: params.turns ?? 30,
|
|
515
665
|
perConversationCap: params.perConversationCap ?? 4,
|
|
666
|
+
...(params.turnIds ? { pinnedTurnIds: params.turnIds } : {}),
|
|
667
|
+
...(params.excludeConversationIds
|
|
668
|
+
? { excludeConversationIds: params.excludeConversationIds }
|
|
669
|
+
: {}),
|
|
516
670
|
});
|
|
517
671
|
|
|
518
672
|
const { packets, key } = await buildPackets(
|
|
@@ -528,19 +682,50 @@ export async function runMemoryEval(
|
|
|
528
682
|
},
|
|
529
683
|
);
|
|
530
684
|
|
|
685
|
+
const embedding: EmbeddingIdentity = {
|
|
686
|
+
...describeEmbeddingModel(deps.config),
|
|
687
|
+
dims: dense ? observedDims : null,
|
|
688
|
+
};
|
|
689
|
+
const turnIds = packets.map((p) => p.turn);
|
|
690
|
+
|
|
531
691
|
mkdirSync(outDir, { recursive: true });
|
|
532
692
|
const packetsPath = join(outDir, "packets.json");
|
|
533
693
|
const keyPath = join(outDir, "key.json");
|
|
694
|
+
const metaPath = join(outDir, "eval-meta.json");
|
|
534
695
|
writeFileSync(packetsPath, JSON.stringify(packets, null, 2));
|
|
535
696
|
writeFileSync(keyPath, JSON.stringify(key, null, 2));
|
|
697
|
+
writeFileSync(
|
|
698
|
+
metaPath,
|
|
699
|
+
JSON.stringify(
|
|
700
|
+
{
|
|
701
|
+
seed,
|
|
702
|
+
k,
|
|
703
|
+
dense,
|
|
704
|
+
embedding,
|
|
705
|
+
snapshotPages: snapshotCorpus.slugs.length,
|
|
706
|
+
stagingPages: stagingCorpus.slugs.length,
|
|
707
|
+
turnsRequested,
|
|
708
|
+
turnsMined: turns.length,
|
|
709
|
+
turnIds,
|
|
710
|
+
},
|
|
711
|
+
null,
|
|
712
|
+
2,
|
|
713
|
+
),
|
|
714
|
+
);
|
|
536
715
|
|
|
537
716
|
return {
|
|
538
717
|
turnsMined: turns.length,
|
|
718
|
+
turnsRequested,
|
|
539
719
|
packetsWritten: packets.length,
|
|
540
720
|
packetsPath,
|
|
541
721
|
keyPath,
|
|
722
|
+
metaPath,
|
|
542
723
|
snapshotPages: snapshotCorpus.slugs.length,
|
|
543
724
|
stagingPages: stagingCorpus.slugs.length,
|
|
544
725
|
dense,
|
|
726
|
+
seed,
|
|
727
|
+
k,
|
|
728
|
+
embedding,
|
|
729
|
+
turnIds,
|
|
545
730
|
};
|
|
546
731
|
}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic unblind + tally for the memory-v3 corpus eval gate.
|
|
3
|
+
*
|
|
4
|
+
* The blind-judge workflow returns one verdict per packet (A vs B) without
|
|
5
|
+
* knowing which side is which; `eval` writes a separate per-turn `key.json`
|
|
6
|
+
* mapping A/B → snapshot/staging. This module joins the two and produces the
|
|
7
|
+
* gate verdict, replacing an ad-hoc hand tally.
|
|
8
|
+
*
|
|
9
|
+
* Two failure modes this exists to prevent (both seen in the field):
|
|
10
|
+
*
|
|
11
|
+
* 1. **A/B is shuffled PER TURN** (a single run has A=snapshot on some turns
|
|
12
|
+
* and A=staging on others). A global "A won N times" count is meaningless —
|
|
13
|
+
* the winner must be mapped through the key turn-by-turn. A hand tally that
|
|
14
|
+
* assumed "A == snapshot" for the whole run flipped the result.
|
|
15
|
+
* 2. **Win-count over near-tied per-turn scores amplifies judge noise.** When
|
|
16
|
+
* most decided turns hinge on a single point of a 0–10 score, a 12–11 split
|
|
17
|
+
* is a coin flip, not a loss. The gate therefore applies a two-sided sign
|
|
18
|
+
* test: the wiki only FAILS when the snapshot's win lead is statistically
|
|
19
|
+
* significant. "Win or tie" passes; a within-noise difference is a tie.
|
|
20
|
+
*
|
|
21
|
+
* Supports a judge PANEL: pass multiple verdicts per turn (e.g. K judges, or
|
|
22
|
+
* the same set re-judged under different seeds) and each turn is decided by the
|
|
23
|
+
* panel's majority before the set-level tally. A larger panel tightens the
|
|
24
|
+
* per-turn signal that the sign test then aggregates.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import type { EvalKeyEntry } from "./eval-packets.js";
|
|
28
|
+
|
|
29
|
+
/** One judge's verdict for one packet (the blind-judge workflow's leaf output). */
|
|
30
|
+
export interface JudgeVerdict {
|
|
31
|
+
turn: string;
|
|
32
|
+
/** The judge's explicit call. When absent/invalid it is derived from scores. */
|
|
33
|
+
winner?: "A" | "B" | "tie" | string;
|
|
34
|
+
scoreA: number;
|
|
35
|
+
scoreB: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface TallyOptions {
|
|
39
|
+
/** Significance threshold for the two-sided sign test (default 0.05). */
|
|
40
|
+
alpha?: number;
|
|
41
|
+
/** Minimum decided turns to call the result confident (default 10). */
|
|
42
|
+
minDecided?: number;
|
|
43
|
+
/** Minimum mean panel votes/turn to call the result confident (default 3). */
|
|
44
|
+
minPanel?: number;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface TallyResult {
|
|
48
|
+
/** Distinct turns with at least one verdict matched to the key. */
|
|
49
|
+
turns: number;
|
|
50
|
+
verdictsCounted: number;
|
|
51
|
+
/** Verdicts whose `turn` had no key entry (ignored). */
|
|
52
|
+
unmatchedVerdicts: number;
|
|
53
|
+
/** Votes per turn across the panel. */
|
|
54
|
+
panel: { min: number; max: number; mean: number };
|
|
55
|
+
snapshotWins: number;
|
|
56
|
+
stagingWins: number;
|
|
57
|
+
ties: number;
|
|
58
|
+
/** snapshotWins + stagingWins (turns that were not a tie). */
|
|
59
|
+
decided: number;
|
|
60
|
+
/** Mean per-turn score for each corpus (each turn weighted equally). */
|
|
61
|
+
meanSnapshot: number;
|
|
62
|
+
meanStaging: number;
|
|
63
|
+
/** Two-sided binomial sign-test p-value for the snapshot/staging win split. */
|
|
64
|
+
signTestP: number;
|
|
65
|
+
/** wiki-wins / tie / wiki-loses — significance-gated, not raw count. */
|
|
66
|
+
verdict: "wiki-wins" | "tie" | "wiki-loses";
|
|
67
|
+
/** The ship gate: the wiki must win OR tie, so `fail` iff `wiki-loses`. */
|
|
68
|
+
gate: "pass" | "fail";
|
|
69
|
+
/** Enough decided turns + panel votes to trust the verdict. */
|
|
70
|
+
confident: boolean;
|
|
71
|
+
notes: string[];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Two-sided binomial sign-test p-value for a split of `a` vs `b` successes under
|
|
76
|
+
* H0 p=0.5. Computed in log space (via log-factorials) so it is stable for the
|
|
77
|
+
* few-hundred-turn range without overflowing `2^n`.
|
|
78
|
+
*/
|
|
79
|
+
export function binomialTwoSidedSignP(a: number, b: number): number {
|
|
80
|
+
const n = a + b;
|
|
81
|
+
if (n === 0) return 1;
|
|
82
|
+
const logFact: number[] = new Array(n + 1);
|
|
83
|
+
logFact[0] = 0;
|
|
84
|
+
for (let i = 1; i <= n; i++) logFact[i] = logFact[i - 1]! + Math.log(i);
|
|
85
|
+
const logChoose = (k: number): number =>
|
|
86
|
+
logFact[n]! - logFact[k]! - logFact[n - k]!;
|
|
87
|
+
const hi = Math.max(a, b);
|
|
88
|
+
let tail = 0;
|
|
89
|
+
for (let k = hi; k <= n; k++) {
|
|
90
|
+
tail += Math.exp(logChoose(k) - n * Math.LN2);
|
|
91
|
+
}
|
|
92
|
+
return Math.min(1, 2 * tail);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function mean(xs: number[]): number {
|
|
96
|
+
return xs.length === 0 ? 0 : xs.reduce((s, x) => s + x, 0) / xs.length;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Resolve a verdict's winning corpus, deriving from scores if `winner` is unusable. */
|
|
100
|
+
function winnerSide(
|
|
101
|
+
v: JudgeVerdict,
|
|
102
|
+
key: EvalKeyEntry,
|
|
103
|
+
): "snapshot" | "staging" | "tie" {
|
|
104
|
+
let w = v.winner;
|
|
105
|
+
if (w !== "A" && w !== "B" && w !== "tie") {
|
|
106
|
+
w = v.scoreA > v.scoreB ? "A" : v.scoreB > v.scoreA ? "B" : "tie";
|
|
107
|
+
}
|
|
108
|
+
if (w === "tie") return "tie";
|
|
109
|
+
return w === "A" ? key.a : key.b;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Join judge verdicts to the unblinding key and produce the gate verdict.
|
|
114
|
+
* Pure over its inputs.
|
|
115
|
+
*/
|
|
116
|
+
export function tallyVerdicts(
|
|
117
|
+
verdicts: JudgeVerdict[],
|
|
118
|
+
key: EvalKeyEntry[],
|
|
119
|
+
opts: TallyOptions = {},
|
|
120
|
+
): TallyResult {
|
|
121
|
+
const alpha = opts.alpha ?? 0.05;
|
|
122
|
+
const minDecided = opts.minDecided ?? 10;
|
|
123
|
+
const minPanel = opts.minPanel ?? 3;
|
|
124
|
+
|
|
125
|
+
const keyByTurn = new Map(key.map((k) => [k.turn, k]));
|
|
126
|
+
const byTurn = new Map<
|
|
127
|
+
string,
|
|
128
|
+
{
|
|
129
|
+
sides: ("snapshot" | "staging" | "tie")[];
|
|
130
|
+
snap: number[];
|
|
131
|
+
stage: number[];
|
|
132
|
+
}
|
|
133
|
+
>();
|
|
134
|
+
let unmatched = 0;
|
|
135
|
+
let counted = 0;
|
|
136
|
+
for (const v of verdicts) {
|
|
137
|
+
const k = keyByTurn.get(v.turn);
|
|
138
|
+
if (!k) {
|
|
139
|
+
unmatched++;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
counted++;
|
|
143
|
+
let g = byTurn.get(v.turn);
|
|
144
|
+
if (!g) {
|
|
145
|
+
g = { sides: [], snap: [], stage: [] };
|
|
146
|
+
byTurn.set(v.turn, g);
|
|
147
|
+
}
|
|
148
|
+
g.sides.push(winnerSide(v, k));
|
|
149
|
+
g.snap.push(k.a === "snapshot" ? v.scoreA : v.scoreB);
|
|
150
|
+
g.stage.push(k.a === "snapshot" ? v.scoreB : v.scoreA);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
let snapshotWins = 0;
|
|
154
|
+
let stagingWins = 0;
|
|
155
|
+
let ties = 0;
|
|
156
|
+
let sumSnap = 0;
|
|
157
|
+
let sumStage = 0;
|
|
158
|
+
const panelSizes: number[] = [];
|
|
159
|
+
for (const g of byTurn.values()) {
|
|
160
|
+
panelSizes.push(g.sides.length);
|
|
161
|
+
const nSnap = g.sides.filter((s) => s === "snapshot").length;
|
|
162
|
+
const nStage = g.sides.filter((s) => s === "staging").length;
|
|
163
|
+
if (nStage > nSnap) stagingWins++;
|
|
164
|
+
else if (nSnap > nStage) snapshotWins++;
|
|
165
|
+
else ties++; // tie vote, or equal snapshot/staging votes
|
|
166
|
+
sumSnap += mean(g.snap);
|
|
167
|
+
sumStage += mean(g.stage);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const turns = byTurn.size;
|
|
171
|
+
const decided = snapshotWins + stagingWins;
|
|
172
|
+
const signTestP = binomialTwoSidedSignP(snapshotWins, stagingWins);
|
|
173
|
+
|
|
174
|
+
let verdict: TallyResult["verdict"];
|
|
175
|
+
if (stagingWins > snapshotWins && signTestP < alpha) verdict = "wiki-wins";
|
|
176
|
+
else if (snapshotWins > stagingWins && signTestP < alpha)
|
|
177
|
+
verdict = "wiki-loses";
|
|
178
|
+
else verdict = "tie";
|
|
179
|
+
const gate: "pass" | "fail" = verdict === "wiki-loses" ? "fail" : "pass";
|
|
180
|
+
|
|
181
|
+
const panel = {
|
|
182
|
+
min: panelSizes.length ? Math.min(...panelSizes) : 0,
|
|
183
|
+
max: panelSizes.length ? Math.max(...panelSizes) : 0,
|
|
184
|
+
mean: mean(panelSizes),
|
|
185
|
+
};
|
|
186
|
+
const confident = decided >= minDecided && panel.mean >= minPanel;
|
|
187
|
+
|
|
188
|
+
const notes: string[] = [];
|
|
189
|
+
if (turns === 0) {
|
|
190
|
+
notes.push(
|
|
191
|
+
"No verdicts matched the key — check the verdicts/key files are from the same run.",
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
if (turns > 0 && panel.mean < minPanel) {
|
|
195
|
+
notes.push(
|
|
196
|
+
`Low panel size (mean ${panel.mean.toFixed(1)} votes/turn) — single-vote judging is noisy; ` +
|
|
197
|
+
`re-judge with a panel (K judges per turn) or repeat under multiple --seed values.`,
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
if (turns > 0 && decided < minDecided) {
|
|
201
|
+
notes.push(
|
|
202
|
+
`Only ${decided} decided turns — too few to be confident; mine more turns.`,
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
if (unmatched > 0) {
|
|
206
|
+
notes.push(
|
|
207
|
+
`${unmatched} verdict(s) had no matching key entry and were ignored.`,
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
if (verdict === "tie") {
|
|
211
|
+
notes.push(
|
|
212
|
+
"Snapshot vs wiki is within noise — a tie satisfies the win-or-tie gate, " +
|
|
213
|
+
"but the wiki did not clearly beat the current corpus.",
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
turns,
|
|
219
|
+
verdictsCounted: counted,
|
|
220
|
+
unmatchedVerdicts: unmatched,
|
|
221
|
+
panel,
|
|
222
|
+
snapshotWins,
|
|
223
|
+
stagingWins,
|
|
224
|
+
ties,
|
|
225
|
+
decided,
|
|
226
|
+
meanSnapshot: turns ? sumSnap / turns : 0,
|
|
227
|
+
meanStaging: turns ? sumStage / turns : 0,
|
|
228
|
+
signTestP,
|
|
229
|
+
verdict,
|
|
230
|
+
gate,
|
|
231
|
+
confident,
|
|
232
|
+
notes,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
@@ -29,6 +29,16 @@ export interface MessagingProvider {
|
|
|
29
29
|
/** Credential service name for token-manager (e.g. 'slack'). */
|
|
30
30
|
credentialService: string;
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Scopes a connection must carry for this provider's tools to work. Set when
|
|
34
|
+
* the credential service bundles several products behind one OAuth app and
|
|
35
|
+
* this provider only works with a subset (e.g. Gmail under the shared
|
|
36
|
+
* 'google' service needs Gmail scopes, not Calendar-only). Forwarded as
|
|
37
|
+
* `requiredScopes` to {@link resolveOAuthConnection} so a narrowly-scoped
|
|
38
|
+
* connection fails with an actionable "reconnect" error instead of a 403.
|
|
39
|
+
*/
|
|
40
|
+
requiredScopes?: string[];
|
|
41
|
+
|
|
32
42
|
// ── Universal operations (every platform must implement) ──────────
|
|
33
43
|
|
|
34
44
|
testConnection(connection?: OAuthConnection): Promise<ConnectionInfo>;
|
|
@@ -16,6 +16,20 @@ import type {
|
|
|
16
16
|
|
|
17
17
|
const GMAIL_BATCH_URL = "https://www.googleapis.com/batch/gmail/v1";
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Minimum Google OAuth scope a connection must carry to be usable for Gmail.
|
|
21
|
+
*
|
|
22
|
+
* The managed `google` OAuth app bundles Gmail + Calendar + Drive, but a
|
|
23
|
+
* connection can be granted a narrow subset (e.g. the onboarding check-in flow
|
|
24
|
+
* requests Calendar-only). Every Gmail read/search/send call needs at least
|
|
25
|
+
* `gmail.readonly`, so a connection lacking it cannot serve Gmail at all —
|
|
26
|
+
* resolving against this scope turns a downstream 403 into an actionable
|
|
27
|
+
* "reconnect Google and grant Gmail" error at resolution time.
|
|
28
|
+
*/
|
|
29
|
+
export const GMAIL_REQUIRED_SCOPES = [
|
|
30
|
+
"https://www.googleapis.com/auth/gmail.readonly",
|
|
31
|
+
];
|
|
32
|
+
|
|
19
33
|
/** Max sub-requests per batch HTTP call (Gmail API limit) */
|
|
20
34
|
const BATCH_SUB_LIMIT = 100;
|
|
21
35
|
/** Max concurrent batch calls */
|
|
@@ -197,7 +197,7 @@ async function deliverSlack(
|
|
|
197
197
|
if (text) {
|
|
198
198
|
const result = await sendSlackReply(chatId, text, {
|
|
199
199
|
threadTs,
|
|
200
|
-
blocks
|
|
200
|
+
blocks,
|
|
201
201
|
approval: payload.approval,
|
|
202
202
|
useBlocks: payload.useBlocks,
|
|
203
203
|
ephemeral: payload.ephemeral,
|