@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
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consume a gateway-stamped {@link TrustVerdict} into the daemon's local
|
|
3
|
+
* trust shapes.
|
|
4
|
+
*
|
|
5
|
+
* The gateway resolves a per-actor verdict from its ACL DB and stamps it onto
|
|
6
|
+
* inbound `sourceMetadata`. These pure mappers turn that verdict into the same
|
|
7
|
+
* {@link TrustContext} / {@link ResolvedMember} the local resolver would have
|
|
8
|
+
* produced — ACL + identity only. INFO fields (notes, userFile, contactType,
|
|
9
|
+
* interactionCount) are never carried on the wire; the consumer re-joins them
|
|
10
|
+
* locally by contactId.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { TrustVerdict } from "@vellumai/gateway-client";
|
|
14
|
+
|
|
15
|
+
import type { ChannelId } from "../channels/types.js";
|
|
16
|
+
import { channelStatusToMemberStatus } from "../contacts/member-status.js";
|
|
17
|
+
import type {
|
|
18
|
+
ChannelPolicy,
|
|
19
|
+
ChannelStatus,
|
|
20
|
+
ContactChannel,
|
|
21
|
+
ContactWithChannels,
|
|
22
|
+
} from "../contacts/types.js";
|
|
23
|
+
import type { TrustContext } from "../daemon/trust-context.js";
|
|
24
|
+
import type { ActorTrustContext } from "./actor-trust-resolver.js";
|
|
25
|
+
import { toTrustContext } from "./actor-trust-resolver.js";
|
|
26
|
+
import type { ResolvedMember } from "./routes/inbound-stages/acl-enforcement.js";
|
|
27
|
+
|
|
28
|
+
export interface TrustVerdictTransport {
|
|
29
|
+
sourceChannel: ChannelId;
|
|
30
|
+
conversationExternalId: string;
|
|
31
|
+
actorUsername?: string;
|
|
32
|
+
actorDisplayName?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Build a {@link TrustContext} from a gateway verdict + transport identity.
|
|
37
|
+
*
|
|
38
|
+
* Reassembles an {@link ActorTrustContext} (mirroring `resolveActorTrust`) and
|
|
39
|
+
* routes it through {@link toTrustContext}, so the output is byte-identical to
|
|
40
|
+
* the local resolution path.
|
|
41
|
+
*/
|
|
42
|
+
export function trustContextFromVerdict(
|
|
43
|
+
verdict: TrustVerdict,
|
|
44
|
+
input: TrustVerdictTransport,
|
|
45
|
+
): TrustContext {
|
|
46
|
+
const canonicalSenderId = verdict.canonicalSenderId;
|
|
47
|
+
const memberDisplayName = verdict.memberDisplayName;
|
|
48
|
+
const senderDisplayName = input.actorDisplayName;
|
|
49
|
+
const username = input.actorUsername;
|
|
50
|
+
const identifier = username
|
|
51
|
+
? `@${username}`
|
|
52
|
+
: (canonicalSenderId ?? undefined);
|
|
53
|
+
|
|
54
|
+
const actorTrustContext: ActorTrustContext = {
|
|
55
|
+
canonicalSenderId,
|
|
56
|
+
guardianBindingMatch: verdict.guardianExternalUserId
|
|
57
|
+
? {
|
|
58
|
+
guardianExternalUserId: verdict.guardianExternalUserId,
|
|
59
|
+
guardianDeliveryChatId: verdict.guardianDeliveryChatId ?? null,
|
|
60
|
+
}
|
|
61
|
+
: null,
|
|
62
|
+
guardianPrincipalId: verdict.guardianPrincipalId,
|
|
63
|
+
memberRecord: null,
|
|
64
|
+
trustClass: verdict.trustClass,
|
|
65
|
+
actorMetadata: {
|
|
66
|
+
identifier,
|
|
67
|
+
displayName: memberDisplayName ?? senderDisplayName,
|
|
68
|
+
senderDisplayName,
|
|
69
|
+
memberDisplayName,
|
|
70
|
+
username,
|
|
71
|
+
channel: input.sourceChannel,
|
|
72
|
+
trustStatus: verdict.trustClass,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const context = toTrustContext(
|
|
77
|
+
actorTrustContext,
|
|
78
|
+
input.conversationExternalId,
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// Stamp the verdict's ACL member fields onto the context so downstream turn
|
|
82
|
+
// assembly reads member status/policy from the verdict rather than a local
|
|
83
|
+
// re-resolution. The contact ID anchors the local info-only join.
|
|
84
|
+
const member = resolvedMemberFromVerdict(verdict);
|
|
85
|
+
if (member) {
|
|
86
|
+
context.requesterContactId = member.contact.id;
|
|
87
|
+
context.memberStatus = channelStatusToMemberStatus(member.channel.status);
|
|
88
|
+
context.memberPolicy = member.channel.policy;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return context;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Allowed ACL enum values, kept in sync with the ContactChannel union types.
|
|
95
|
+
const CHANNEL_STATUS_VALUES: readonly ChannelStatus[] = [
|
|
96
|
+
"active",
|
|
97
|
+
"pending",
|
|
98
|
+
"revoked",
|
|
99
|
+
"blocked",
|
|
100
|
+
"unverified",
|
|
101
|
+
];
|
|
102
|
+
const CHANNEL_POLICY_VALUES: readonly ChannelPolicy[] = [
|
|
103
|
+
"allow",
|
|
104
|
+
"deny",
|
|
105
|
+
"escalate",
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
function isChannelStatus(value: string): value is ChannelStatus {
|
|
109
|
+
return (CHANNEL_STATUS_VALUES as readonly string[]).includes(value);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function isChannelPolicy(value: string): value is ChannelPolicy {
|
|
113
|
+
return (CHANNEL_POLICY_VALUES as readonly string[]).includes(value);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Build a synthetic {@link ResolvedMember} from a gateway verdict.
|
|
118
|
+
*
|
|
119
|
+
* ACL + identity only; info fields are placeholders, re-joined locally by
|
|
120
|
+
* contactId. Returns null for memberless verdicts.
|
|
121
|
+
*/
|
|
122
|
+
export function resolvedMemberFromVerdict(
|
|
123
|
+
verdict: TrustVerdict,
|
|
124
|
+
): ResolvedMember | null {
|
|
125
|
+
if (!verdict.contactId || !verdict.channelId) return null;
|
|
126
|
+
// Member verdict requires valid known status+policy enums, else null
|
|
127
|
+
// (fail-closed): a partial/mixed-version verdict (absent OR
|
|
128
|
+
// present-but-unknown ACL value) must not synthesize an active/allow channel
|
|
129
|
+
// that would skip ingress ACL gates.
|
|
130
|
+
if (!verdict.status || !verdict.policy) return null;
|
|
131
|
+
if (!isChannelStatus(verdict.status) || !isChannelPolicy(verdict.policy)) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const channel: ContactChannel = {
|
|
136
|
+
id: verdict.channelId,
|
|
137
|
+
contactId: verdict.contactId,
|
|
138
|
+
type: verdict.type ?? "",
|
|
139
|
+
address: verdict.address ?? "",
|
|
140
|
+
isPrimary: false,
|
|
141
|
+
externalChatId: verdict.externalChatId ?? null,
|
|
142
|
+
status: verdict.status,
|
|
143
|
+
policy: verdict.policy,
|
|
144
|
+
verifiedAt: verdict.verifiedAt ?? null,
|
|
145
|
+
verifiedVia: verdict.verifiedVia ?? null,
|
|
146
|
+
inviteId: null,
|
|
147
|
+
revokedReason: null,
|
|
148
|
+
blockedReason: null,
|
|
149
|
+
lastSeenAt: null,
|
|
150
|
+
interactionCount: 0,
|
|
151
|
+
lastInteraction: null,
|
|
152
|
+
updatedAt: null,
|
|
153
|
+
createdAt: 0,
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const contact: ContactWithChannels = {
|
|
157
|
+
id: verdict.contactId,
|
|
158
|
+
displayName: verdict.memberDisplayName ?? "",
|
|
159
|
+
notes: null,
|
|
160
|
+
lastInteraction: null,
|
|
161
|
+
interactionCount: 0,
|
|
162
|
+
createdAt: 0,
|
|
163
|
+
updatedAt: 0,
|
|
164
|
+
role: verdict.trustClass === "guardian" ? "guardian" : "contact",
|
|
165
|
+
contactType: "human",
|
|
166
|
+
principalId: verdict.guardianPrincipalId ?? null,
|
|
167
|
+
userFile: null,
|
|
168
|
+
channels: [channel],
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
return { contact, channel };
|
|
172
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getConfig } from "../config/loader.js";
|
|
1
2
|
import {
|
|
2
3
|
checkDiskPressureBackgroundGate,
|
|
3
4
|
diskPressureBackgroundSkipLogFields,
|
|
@@ -85,14 +86,6 @@ const TICK_INTERVAL_MS = 15_000;
|
|
|
85
86
|
*/
|
|
86
87
|
const WAKE_MAX_RETRIES = 20;
|
|
87
88
|
|
|
88
|
-
/**
|
|
89
|
-
* Hard timeout for `talk`-mode scheduled jobs. Schedules can do
|
|
90
|
-
* non-trivial work (research, summarize the day, etc.), so the cap is
|
|
91
|
-
* generous; it exists primarily so a wedged turn cannot block the next
|
|
92
|
-
* scheduler tick indefinitely. Mirrors the heartbeat/filing budgets.
|
|
93
|
-
*/
|
|
94
|
-
const SCHEDULE_TALK_TIMEOUT_MS = 30 * 60 * 1000;
|
|
95
|
-
|
|
96
89
|
/**
|
|
97
90
|
* Apply retry policy on schedule-execution failure. Retries are scheduled by
|
|
98
91
|
* `applyRetryDecision`; once retries are exhausted, the `emitAlert` callback
|
|
@@ -362,6 +355,7 @@ export async function runScheduleDueWorkOnce(
|
|
|
362
355
|
conversationId: wakeConversationId,
|
|
363
356
|
hint: job.message,
|
|
364
357
|
source: "defer",
|
|
358
|
+
persistTriggerAsEvent: true,
|
|
365
359
|
...(job.inferenceProfile
|
|
366
360
|
? { forceOverrideProfile: job.inferenceProfile }
|
|
367
361
|
: {}),
|
|
@@ -718,7 +712,10 @@ export async function runScheduleDueWorkOnce(
|
|
|
718
712
|
...(job.inferenceProfile
|
|
719
713
|
? { overrideProfile: job.inferenceProfile }
|
|
720
714
|
: {}),
|
|
721
|
-
|
|
715
|
+
// Hard timeout for talk-mode scheduled turns: bounds a wedged turn so
|
|
716
|
+
// it cannot block the next scheduler tick. Configurable via
|
|
717
|
+
// timeouts.scheduleTurnTimeoutSec (default 1800s).
|
|
718
|
+
timeoutMs: getConfig().timeouts.scheduleTurnTimeoutSec * 1000,
|
|
722
719
|
origin: "schedule",
|
|
723
720
|
groupId: "system:scheduled",
|
|
724
721
|
conversationType: "scheduled",
|
|
@@ -241,7 +241,7 @@ import {
|
|
|
241
241
|
} from "./activation-funnel.js";
|
|
242
242
|
import { UsageTelemetryReporter } from "./usage-telemetry-reporter.js";
|
|
243
243
|
|
|
244
|
-
initializeDb();
|
|
244
|
+
await initializeDb();
|
|
245
245
|
|
|
246
246
|
// ---------------------------------------------------------------------------
|
|
247
247
|
// Helpers
|
|
@@ -59,7 +59,9 @@ beforeEach(() => {
|
|
|
59
59
|
};
|
|
60
60
|
});
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
// A single question used to build batches. The tool only accepts the
|
|
63
|
+
// batched `{ questions: [...] }` shape.
|
|
64
|
+
const singleQ = {
|
|
63
65
|
question: "Which fruit?",
|
|
64
66
|
description: "Pick one to add to the smoothie.",
|
|
65
67
|
options: [
|
|
@@ -69,12 +71,7 @@ const validInput = {
|
|
|
69
71
|
freeTextPlaceholder: "Type a fruit",
|
|
70
72
|
};
|
|
71
73
|
|
|
72
|
-
const
|
|
73
|
-
question: validInput.question,
|
|
74
|
-
description: validInput.description,
|
|
75
|
-
options: validInput.options,
|
|
76
|
-
freeTextPlaceholder: validInput.freeTextPlaceholder,
|
|
77
|
-
};
|
|
74
|
+
const validInput = { questions: [singleQ] };
|
|
78
75
|
|
|
79
76
|
describe("askQuestionTool definition", () => {
|
|
80
77
|
test("exposes the expected schema shape and description language", () => {
|
|
@@ -91,7 +88,6 @@ describe("askQuestionTool definition", () => {
|
|
|
91
88
|
expect(def.description).toContain("remove guessing");
|
|
92
89
|
expect(def.description).toContain("a question is skipped");
|
|
93
90
|
expect(def.description).toContain("every question in the batch is skipped");
|
|
94
|
-
// Batching language is back now that the prompter handles batches.
|
|
95
91
|
expect(def.description).toContain("Batch related clarifications");
|
|
96
92
|
expect(def.description).toContain("up to 5");
|
|
97
93
|
expect(def.description).toContain("Skip button");
|
|
@@ -99,13 +95,23 @@ describe("askQuestionTool definition", () => {
|
|
|
99
95
|
const schema = def.input_schema as {
|
|
100
96
|
properties: Record<
|
|
101
97
|
string,
|
|
102
|
-
{
|
|
98
|
+
{
|
|
99
|
+
type?: string;
|
|
100
|
+
items?: {
|
|
101
|
+
properties?: Record<
|
|
102
|
+
string,
|
|
103
|
+
{ type?: string; minItems?: number; maxItems?: number }
|
|
104
|
+
>;
|
|
105
|
+
};
|
|
106
|
+
}
|
|
103
107
|
>;
|
|
104
108
|
required?: string[];
|
|
105
109
|
};
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
expect(
|
|
110
|
+
const optionsSchema =
|
|
111
|
+
schema.properties.questions?.items?.properties?.options;
|
|
112
|
+
expect(optionsSchema?.type).toBe("array");
|
|
113
|
+
expect(optionsSchema?.minItems).toBe(2);
|
|
114
|
+
expect(optionsSchema?.maxItems).toBe(4);
|
|
109
115
|
});
|
|
110
116
|
});
|
|
111
117
|
|
|
@@ -132,17 +138,17 @@ describe("AskQuestionTool.execute", () => {
|
|
|
132
138
|
expect(calls).toHaveLength(1);
|
|
133
139
|
expect(calls[0]?.conversationId).toBe("conv-1");
|
|
134
140
|
expect(calls[0]?.questions).toHaveLength(1);
|
|
135
|
-
expect(calls[0]?.questions[0]?.question).toBe(
|
|
136
|
-
expect(calls[0]?.questions[0]?.description).toBe(
|
|
137
|
-
expect(calls[0]?.questions[0]?.options).toEqual(
|
|
141
|
+
expect(calls[0]?.questions[0]?.question).toBe(singleQ.question);
|
|
142
|
+
expect(calls[0]?.questions[0]?.description).toBe(singleQ.description);
|
|
143
|
+
expect(calls[0]?.questions[0]?.options).toEqual(singleQ.options);
|
|
138
144
|
expect(calls[0]?.questions[0]?.freeTextPlaceholder).toBe(
|
|
139
|
-
|
|
145
|
+
singleQ.freeTextPlaceholder,
|
|
140
146
|
);
|
|
141
147
|
expect(calls[0]?.toolUseId).toBe("tu-1");
|
|
142
148
|
|
|
143
149
|
expect(result.isError).toBe(false);
|
|
144
150
|
expect(result.content).toBe(
|
|
145
|
-
`Question "${
|
|
151
|
+
`Question "${singleQ.question}" → Option: a (Apple)`,
|
|
146
152
|
);
|
|
147
153
|
});
|
|
148
154
|
|
|
@@ -150,7 +156,7 @@ describe("AskQuestionTool.execute", () => {
|
|
|
150
156
|
setNextResult(singleCompleted({ decision: "option", optionId: "b" }));
|
|
151
157
|
const result = await askQuestionTool.execute(validInput, makeContext());
|
|
152
158
|
expect(result.content).toBe(
|
|
153
|
-
`Question "${
|
|
159
|
+
`Question "${singleQ.question}" → Option: b (Banana)`,
|
|
154
160
|
);
|
|
155
161
|
expect(result.isError).toBe(false);
|
|
156
162
|
});
|
|
@@ -159,7 +165,7 @@ describe("AskQuestionTool.execute", () => {
|
|
|
159
165
|
setNextResult(singleCompleted({ decision: "option", optionId: "ghost" }));
|
|
160
166
|
const result = await askQuestionTool.execute(validInput, makeContext());
|
|
161
167
|
expect(result.content).toBe(
|
|
162
|
-
`Question "${
|
|
168
|
+
`Question "${singleQ.question}" → Option: ghost ((unknown))`,
|
|
163
169
|
);
|
|
164
170
|
expect(result.isError).toBe(false);
|
|
165
171
|
});
|
|
@@ -168,7 +174,7 @@ describe("AskQuestionTool.execute", () => {
|
|
|
168
174
|
setNextResult(singleCompleted({ decision: "free_text", text: "Cherry" }));
|
|
169
175
|
const result = await askQuestionTool.execute(validInput, makeContext());
|
|
170
176
|
expect(result.content).toBe(
|
|
171
|
-
`Question "${
|
|
177
|
+
`Question "${singleQ.question}" → Free text: Cherry`,
|
|
172
178
|
);
|
|
173
179
|
expect(result.isError).toBe(false);
|
|
174
180
|
});
|
|
@@ -176,7 +182,7 @@ describe("AskQuestionTool.execute", () => {
|
|
|
176
182
|
test("formats skipped result", async () => {
|
|
177
183
|
setNextResult(singleCompleted({ decision: "skipped" }));
|
|
178
184
|
const result = await askQuestionTool.execute(validInput, makeContext());
|
|
179
|
-
expect(result.content).toBe(`Question "${
|
|
185
|
+
expect(result.content).toBe(`Question "${singleQ.question}" → Skipped`);
|
|
180
186
|
expect(result.isError).toBe(false);
|
|
181
187
|
});
|
|
182
188
|
|
|
@@ -200,10 +206,10 @@ describe("AskQuestionTool.execute", () => {
|
|
|
200
206
|
expect(result.content).toBe("Question aborted");
|
|
201
207
|
});
|
|
202
208
|
|
|
203
|
-
test("rejects
|
|
209
|
+
test("rejects a question with fewer than 2 options", async () => {
|
|
204
210
|
setNextResult(singleCompleted({ decision: "option", optionId: "a" }));
|
|
205
211
|
const result = await askQuestionTool.execute(
|
|
206
|
-
{ ...
|
|
212
|
+
{ questions: [{ ...singleQ, options: [{ id: "a", label: "Apple" }] }] },
|
|
207
213
|
makeContext(),
|
|
208
214
|
);
|
|
209
215
|
expect(result.isError).toBe(true);
|
|
@@ -211,17 +217,21 @@ describe("AskQuestionTool.execute", () => {
|
|
|
211
217
|
expect(calls).toHaveLength(0);
|
|
212
218
|
});
|
|
213
219
|
|
|
214
|
-
test("rejects
|
|
220
|
+
test("rejects a question with more than 4 options", async () => {
|
|
215
221
|
setNextResult(singleCompleted({ decision: "option", optionId: "a" }));
|
|
216
222
|
const result = await askQuestionTool.execute(
|
|
217
223
|
{
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
224
|
+
questions: [
|
|
225
|
+
{
|
|
226
|
+
...singleQ,
|
|
227
|
+
options: [
|
|
228
|
+
{ id: "a", label: "A" },
|
|
229
|
+
{ id: "b", label: "B" },
|
|
230
|
+
{ id: "c", label: "C" },
|
|
231
|
+
{ id: "d", label: "D" },
|
|
232
|
+
{ id: "e", label: "E" },
|
|
233
|
+
],
|
|
234
|
+
},
|
|
225
235
|
],
|
|
226
236
|
},
|
|
227
237
|
makeContext(),
|
|
@@ -230,10 +240,10 @@ describe("AskQuestionTool.execute", () => {
|
|
|
230
240
|
expect(calls).toHaveLength(0);
|
|
231
241
|
});
|
|
232
242
|
|
|
233
|
-
test("rejects
|
|
243
|
+
test("rejects a question with empty text", async () => {
|
|
234
244
|
setNextResult(singleCompleted({ decision: "option", optionId: "a" }));
|
|
235
245
|
const result = await askQuestionTool.execute(
|
|
236
|
-
{ ...
|
|
246
|
+
{ questions: [{ ...singleQ, question: "" }] },
|
|
237
247
|
makeContext(),
|
|
238
248
|
);
|
|
239
249
|
expect(result.isError).toBe(true);
|
|
@@ -254,18 +264,6 @@ describe("AskQuestionTool.execute", () => {
|
|
|
254
264
|
// ── Batched input ───────────────────────────────────────────────────
|
|
255
265
|
|
|
256
266
|
describe("AskQuestionTool batched input", () => {
|
|
257
|
-
test("normalizes legacy flat input into a one-element batch forwarded to the prompter", async () => {
|
|
258
|
-
setNextResult(singleCompleted({ decision: "option", optionId: "a" }));
|
|
259
|
-
|
|
260
|
-
const result = await askQuestionTool.execute(validInput, makeContext());
|
|
261
|
-
|
|
262
|
-
expect(calls).toHaveLength(1);
|
|
263
|
-
expect(calls[0]?.questions).toHaveLength(1);
|
|
264
|
-
expect(calls[0]?.questions[0]?.question).toBe(validInput.question);
|
|
265
|
-
expect(calls[0]?.questions[0]?.options).toEqual(validInput.options);
|
|
266
|
-
expect(result.isError).toBe(false);
|
|
267
|
-
});
|
|
268
|
-
|
|
269
267
|
test("accepts a single-element `questions` batch", async () => {
|
|
270
268
|
setNextResult(singleCompleted({ decision: "option", optionId: "a" }));
|
|
271
269
|
|
|
@@ -454,7 +452,7 @@ describe("AskQuestionTool batched input", () => {
|
|
|
454
452
|
expect(calls).toHaveLength(0);
|
|
455
453
|
});
|
|
456
454
|
|
|
457
|
-
test("rejects input missing
|
|
455
|
+
test("rejects input missing `questions`", async () => {
|
|
458
456
|
setNextResult(singleCompleted({ decision: "option", optionId: "a" }));
|
|
459
457
|
|
|
460
458
|
const result = await askQuestionTool.execute({}, makeContext());
|
|
@@ -464,11 +462,17 @@ describe("AskQuestionTool batched input", () => {
|
|
|
464
462
|
expect(calls).toHaveLength(0);
|
|
465
463
|
});
|
|
466
464
|
|
|
467
|
-
test("rejects
|
|
465
|
+
test("rejects the dropped flat single-question shape", async () => {
|
|
468
466
|
setNextResult(singleCompleted({ decision: "option", optionId: "a" }));
|
|
469
467
|
|
|
470
468
|
const result = await askQuestionTool.execute(
|
|
471
|
-
{
|
|
469
|
+
{
|
|
470
|
+
question: "Hi?",
|
|
471
|
+
options: [
|
|
472
|
+
{ id: "a", label: "A" },
|
|
473
|
+
{ id: "b", label: "B" },
|
|
474
|
+
],
|
|
475
|
+
},
|
|
472
476
|
makeContext(),
|
|
473
477
|
);
|
|
474
478
|
|
|
@@ -479,7 +483,7 @@ describe("AskQuestionTool batched input", () => {
|
|
|
479
483
|
});
|
|
480
484
|
|
|
481
485
|
describe("askQuestionTool definition (batched schema)", () => {
|
|
482
|
-
test("exposes `questions[]` shape,
|
|
486
|
+
test("exposes `questions[]` shape, requires it, and drops the flat fields", () => {
|
|
483
487
|
const def = askQuestionTool;
|
|
484
488
|
const schema = def.input_schema as unknown as {
|
|
485
489
|
properties: Record<
|
|
@@ -517,8 +521,12 @@ describe("askQuestionTool definition (batched schema)", () => {
|
|
|
517
521
|
|
|
518
522
|
expect(questions?.items?.required).toEqual(["question", "options"]);
|
|
519
523
|
|
|
520
|
-
//
|
|
521
|
-
expect(schema.
|
|
522
|
-
expect(schema.properties
|
|
524
|
+
// `questions` is the only top-level input now.
|
|
525
|
+
expect(schema.required).toEqual(["questions"]);
|
|
526
|
+
expect(Object.keys(schema.properties)).toEqual(["questions"]);
|
|
527
|
+
|
|
528
|
+
// The legacy flat fields are gone.
|
|
529
|
+
expect(schema.properties.question).toBeUndefined();
|
|
530
|
+
expect(schema.properties.options).toBeUndefined();
|
|
523
531
|
});
|
|
524
532
|
});
|
|
@@ -40,35 +40,16 @@ const SingleQuestionSchema = z.object({
|
|
|
40
40
|
// input with ≥6 entries is rejected with a clear Zod error.
|
|
41
41
|
const MAX_QUESTIONS_PER_BATCH = 5;
|
|
42
42
|
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
})
|
|
54
|
-
.optional(),
|
|
55
|
-
// Legacy flat fields. Optional so batched callers can omit them; when
|
|
56
|
-
// present and `questions` is absent, they are normalized into a
|
|
57
|
-
// one-element batch in `execute()`.
|
|
58
|
-
question: z.string().min(1).optional(),
|
|
59
|
-
description: z.string().optional(),
|
|
60
|
-
options: z.array(OptionSchema).min(2).max(4).optional(),
|
|
61
|
-
freeTextPlaceholder: z.string().optional(),
|
|
62
|
-
})
|
|
63
|
-
.refine(
|
|
64
|
-
(v) =>
|
|
65
|
-
v.questions !== undefined ||
|
|
66
|
-
(v.question !== undefined && v.options !== undefined),
|
|
67
|
-
{
|
|
68
|
-
message:
|
|
69
|
-
"Provide `questions` (preferred) or the legacy flat fields (`question` + `options`).",
|
|
70
|
-
},
|
|
71
|
-
);
|
|
43
|
+
// Callers pass a (possibly single-element) batch of questions. `execute()`
|
|
44
|
+
// forwards them straight to the prompter.
|
|
45
|
+
const InputSchema = z.object({
|
|
46
|
+
questions: z
|
|
47
|
+
.array(SingleQuestionSchema)
|
|
48
|
+
.min(1)
|
|
49
|
+
.max(MAX_QUESTIONS_PER_BATCH, {
|
|
50
|
+
message: `At most ${MAX_QUESTIONS_PER_BATCH} questions per batch; split into multiple turns if you need more.`,
|
|
51
|
+
}),
|
|
52
|
+
});
|
|
72
53
|
|
|
73
54
|
export type SingleQuestion = z.infer<typeof SingleQuestionSchema>;
|
|
74
55
|
export type AskQuestionInput = z.infer<typeof InputSchema>;
|
|
@@ -111,8 +92,7 @@ const DESCRIPTION = [
|
|
|
111
92
|
"context shown beneath the label.",
|
|
112
93
|
].join("\n");
|
|
113
94
|
|
|
114
|
-
//
|
|
115
|
-
// shape and the legacy flat `options` field.
|
|
95
|
+
// Option-schema fragment for the items in `questions[].options`.
|
|
116
96
|
const OPTION_ITEMS_SCHEMA = {
|
|
117
97
|
type: "object",
|
|
118
98
|
properties: {
|
|
@@ -150,12 +130,11 @@ export const askQuestionTool = {
|
|
|
150
130
|
input_schema: {
|
|
151
131
|
type: "object",
|
|
152
132
|
properties: {
|
|
153
|
-
// ── Recommended shape ─────────────────────────────────────
|
|
154
133
|
questions: {
|
|
155
134
|
type: "array",
|
|
156
135
|
minItems: 1,
|
|
157
136
|
maxItems: MAX_QUESTIONS_PER_BATCH,
|
|
158
|
-
description: `
|
|
137
|
+
description: `1–${MAX_QUESTIONS_PER_BATCH} clarifying questions to ask in a single turn. Use a batch when several independent ambiguities block progress; ask one at a time when they're sequentially dependent. Past ${MAX_QUESTIONS_PER_BATCH} questions you should be implementing, not asking.`,
|
|
159
138
|
items: {
|
|
160
139
|
type: "object",
|
|
161
140
|
properties: {
|
|
@@ -185,35 +164,8 @@ export const askQuestionTool = {
|
|
|
185
164
|
required: ["question", "options"],
|
|
186
165
|
},
|
|
187
166
|
},
|
|
188
|
-
// ── Legacy single-question fields ─────────────────────────
|
|
189
|
-
// Kept optional so existing prompt caches and any single-question
|
|
190
|
-
// callers continue to work. New callers should use `questions`.
|
|
191
|
-
question: {
|
|
192
|
-
type: "string",
|
|
193
|
-
description:
|
|
194
|
-
"Legacy: the single clarifying question. Prefer `questions[]` for new code.",
|
|
195
|
-
},
|
|
196
|
-
description: {
|
|
197
|
-
type: "string",
|
|
198
|
-
description:
|
|
199
|
-
"Legacy: optional one-line context shown beneath the question. Prefer `questions[].description`.",
|
|
200
|
-
},
|
|
201
|
-
options: {
|
|
202
|
-
type: "array",
|
|
203
|
-
minItems: 2,
|
|
204
|
-
maxItems: 4,
|
|
205
|
-
description:
|
|
206
|
-
"Legacy: 2–4 structured options. Prefer `questions[].options`. The UI always appends a free-text fallback slot, so do not include a 'something else' option here.",
|
|
207
|
-
items: OPTION_ITEMS_SCHEMA,
|
|
208
|
-
},
|
|
209
|
-
freeTextPlaceholder: {
|
|
210
|
-
type: "string",
|
|
211
|
-
description:
|
|
212
|
-
"Legacy: optional placeholder text for the free-text fallback input. Prefer `questions[].freeTextPlaceholder`.",
|
|
213
|
-
},
|
|
214
167
|
},
|
|
215
|
-
|
|
216
|
-
// or the legacy flat trio (`question` + `options`). Enforced in Zod.
|
|
168
|
+
required: ["questions"],
|
|
217
169
|
},
|
|
218
170
|
|
|
219
171
|
async execute(
|
|
@@ -228,18 +180,7 @@ export const askQuestionTool = {
|
|
|
228
180
|
};
|
|
229
181
|
}
|
|
230
182
|
|
|
231
|
-
|
|
232
|
-
// downstream code only has to deal with the batched shape. The refine
|
|
233
|
-
// above guarantees `question` and `options` are present whenever
|
|
234
|
-
// `questions` is absent.
|
|
235
|
-
const questions: SingleQuestion[] = parsed.data.questions ?? [
|
|
236
|
-
{
|
|
237
|
-
question: parsed.data.question!,
|
|
238
|
-
description: parsed.data.description,
|
|
239
|
-
options: parsed.data.options!,
|
|
240
|
-
freeTextPlaceholder: parsed.data.freeTextPlaceholder,
|
|
241
|
-
},
|
|
242
|
-
];
|
|
183
|
+
const questions: SingleQuestion[] = parsed.data.questions;
|
|
243
184
|
|
|
244
185
|
const prompter = new QuestionPrompter();
|
|
245
186
|
const result = await prompter.prompt({
|
|
@@ -296,4 +296,24 @@ describe("executeBrowserStatus", () => {
|
|
|
296
296
|
expect(extension.available).toBe(true);
|
|
297
297
|
expect(extension.details.transport).toBe("extension-ws");
|
|
298
298
|
});
|
|
299
|
+
|
|
300
|
+
test("reports extension as connected when probe fails on the Chrome Web Store / extensions gallery", async () => {
|
|
301
|
+
mockSingletonProxy = { isAvailable: () => true, hasExtensionClient: () => true, request: () => {} };
|
|
302
|
+
probeOutcomes[BROWSER_STATUS_MODE.EXTENSION] = "fail";
|
|
303
|
+
probeErrors[BROWSER_STATUS_MODE.EXTENSION] = new CdpError(
|
|
304
|
+
"cdp_error",
|
|
305
|
+
"The extensions gallery cannot be scripted.",
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
const result = await executeBrowserStatus({}, makeContext());
|
|
309
|
+
expect(result.isError).toBe(false);
|
|
310
|
+
const payload = JSON.parse(result.content);
|
|
311
|
+
const extension = payload.modes.find(
|
|
312
|
+
(m: { mode: string }) => m.mode === BROWSER_STATUS_MODE.EXTENSION,
|
|
313
|
+
);
|
|
314
|
+
expect(extension).toBeDefined();
|
|
315
|
+
expect(extension.available).toBe(true);
|
|
316
|
+
expect(extension.verified).toBe("active_probe");
|
|
317
|
+
expect(extension.details.restrictedActiveTab).toBe(true);
|
|
318
|
+
});
|
|
299
319
|
});
|
|
@@ -345,10 +345,22 @@ function collectRemediationHints(
|
|
|
345
345
|
|
|
346
346
|
/**
|
|
347
347
|
* Detect the common extension CDP failure where the active tab is a
|
|
348
|
-
*
|
|
348
|
+
* page Chrome forbids extensions from scripting — either a privileged
|
|
349
|
+
* `chrome://` internal page (e.g. `chrome://newtab`) or the Chrome Web
|
|
350
|
+
* Store / extensions gallery (which yields "The extensions gallery
|
|
351
|
+
* cannot be scripted."). The latter is especially common right after
|
|
352
|
+
* install, when the Web Store page is still the active tab.
|
|
353
|
+
*
|
|
354
|
+
* Keep this restricted-error match in sync with the Page.navigate
|
|
355
|
+
* recovery in the chrome-extension dispatcher (host-browser-dispatcher.ts,
|
|
356
|
+
* separate package, duplicated by necessity): the status side reports the
|
|
357
|
+
* tab as recoverable, and the navigate side must actually recover it.
|
|
349
358
|
*/
|
|
350
359
|
function isRestrictedChromePageProbeError(error: CdpError): boolean {
|
|
351
|
-
|
|
360
|
+
const message = error.message.toLowerCase();
|
|
361
|
+
return (
|
|
362
|
+
message.includes("chrome://") || message.includes("cannot be scripted")
|
|
363
|
+
);
|
|
352
364
|
}
|
|
353
365
|
|
|
354
366
|
/**
|
|
@@ -2450,9 +2462,9 @@ async function checkExtensionModeStatus(
|
|
|
2450
2462
|
verified: "active_probe",
|
|
2451
2463
|
autoCandidate,
|
|
2452
2464
|
summary:
|
|
2453
|
-
"Extension mode transport is connected, but the active Chrome tab is a
|
|
2465
|
+
"Extension mode transport is connected, but the active Chrome tab is a page Chrome won't let extensions script (a chrome:// page or the Chrome Web Store / extensions gallery). Switch to a regular website tab if browser actions fail.",
|
|
2454
2466
|
userActions: [
|
|
2455
|
-
"Switch Chrome to a regular http(s) tab
|
|
2467
|
+
"Switch Chrome to a regular http(s) tab — not a chrome:// page or the Chrome Web Store / extensions gallery — and retry.",
|
|
2456
2468
|
],
|
|
2457
2469
|
tradeoffs: modeTradeoffs(BROWSER_STATUS_MODE.EXTENSION),
|
|
2458
2470
|
details: {
|