@vellumai/assistant 0.10.0 → 0.10.1-dev.202606240317.ea25efe
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +36 -37
- package/bun.lock +3 -0
- package/docs/workflows.md +12 -7
- package/eslint-rules/cli-no-daemon-internals.js +12 -0
- package/node_modules/@slack/types/LICENSE +23 -0
- package/node_modules/@slack/types/README.md +32 -0
- package/node_modules/@slack/types/dist/block-kit/block-elements.d.ts +953 -0
- package/node_modules/@slack/types/dist/block-kit/block-elements.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/block-elements.js +4 -0
- package/node_modules/@slack/types/dist/block-kit/block-elements.js.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/blocks.d.ts +474 -0
- package/node_modules/@slack/types/dist/block-kit/blocks.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/blocks.js +3 -0
- package/node_modules/@slack/types/dist/block-kit/blocks.js.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/composition-objects.d.ts +237 -0
- package/node_modules/@slack/types/dist/block-kit/composition-objects.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/composition-objects.js +4 -0
- package/node_modules/@slack/types/dist/block-kit/composition-objects.js.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/extensions.d.ts +88 -0
- package/node_modules/@slack/types/dist/block-kit/extensions.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/block-kit/extensions.js +3 -0
- package/node_modules/@slack/types/dist/block-kit/extensions.js.map +1 -0
- package/node_modules/@slack/types/dist/calls.d.ts +26 -0
- package/node_modules/@slack/types/dist/calls.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/calls.js +6 -0
- package/node_modules/@slack/types/dist/calls.js.map +1 -0
- package/node_modules/@slack/types/dist/chunk.d.ts +52 -0
- package/node_modules/@slack/types/dist/chunk.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/chunk.js +3 -0
- package/node_modules/@slack/types/dist/chunk.js.map +1 -0
- package/node_modules/@slack/types/dist/common/bot-profile.d.ts +12 -0
- package/node_modules/@slack/types/dist/common/bot-profile.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/common/bot-profile.js +3 -0
- package/node_modules/@slack/types/dist/common/bot-profile.js.map +1 -0
- package/node_modules/@slack/types/dist/common/status-emoji-display-info.d.ts +6 -0
- package/node_modules/@slack/types/dist/common/status-emoji-display-info.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/common/status-emoji-display-info.js +3 -0
- package/node_modules/@slack/types/dist/common/status-emoji-display-info.js.map +1 -0
- package/node_modules/@slack/types/dist/dialog.d.ts +36 -0
- package/node_modules/@slack/types/dist/dialog.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/dialog.js +3 -0
- package/node_modules/@slack/types/dist/dialog.js.map +1 -0
- package/node_modules/@slack/types/dist/events/app.d.ts +204 -0
- package/node_modules/@slack/types/dist/events/app.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/app.js +3 -0
- package/node_modules/@slack/types/dist/events/app.js.map +1 -0
- package/node_modules/@slack/types/dist/events/assistant.d.ts +29 -0
- package/node_modules/@slack/types/dist/events/assistant.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/assistant.js +3 -0
- package/node_modules/@slack/types/dist/events/assistant.js.map +1 -0
- package/node_modules/@slack/types/dist/events/call.d.ts +8 -0
- package/node_modules/@slack/types/dist/events/call.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/call.js +3 -0
- package/node_modules/@slack/types/dist/events/call.js.map +1 -0
- package/node_modules/@slack/types/dist/events/channel.d.ts +85 -0
- package/node_modules/@slack/types/dist/events/channel.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/channel.js +3 -0
- package/node_modules/@slack/types/dist/events/channel.js.map +1 -0
- package/node_modules/@slack/types/dist/events/dnd.d.ts +24 -0
- package/node_modules/@slack/types/dist/events/dnd.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/dnd.js +3 -0
- package/node_modules/@slack/types/dist/events/dnd.js.map +1 -0
- package/node_modules/@slack/types/dist/events/email.d.ts +6 -0
- package/node_modules/@slack/types/dist/events/email.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/email.js +3 -0
- package/node_modules/@slack/types/dist/events/email.js.map +1 -0
- package/node_modules/@slack/types/dist/events/emoji.d.ts +11 -0
- package/node_modules/@slack/types/dist/events/emoji.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/emoji.js +3 -0
- package/node_modules/@slack/types/dist/events/emoji.js.map +1 -0
- package/node_modules/@slack/types/dist/events/entity-details-requested.d.ts +21 -0
- package/node_modules/@slack/types/dist/events/entity-details-requested.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/entity-details-requested.js +3 -0
- package/node_modules/@slack/types/dist/events/entity-details-requested.js.map +1 -0
- package/node_modules/@slack/types/dist/events/file.d.ts +60 -0
- package/node_modules/@slack/types/dist/events/file.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/file.js +4 -0
- package/node_modules/@slack/types/dist/events/file.js.map +1 -0
- package/node_modules/@slack/types/dist/events/function.d.ts +33 -0
- package/node_modules/@slack/types/dist/events/function.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/function.js +3 -0
- package/node_modules/@slack/types/dist/events/function.js.map +1 -0
- package/node_modules/@slack/types/dist/events/grid-migration.d.ts +9 -0
- package/node_modules/@slack/types/dist/events/grid-migration.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/grid-migration.js +3 -0
- package/node_modules/@slack/types/dist/events/grid-migration.js.map +1 -0
- package/node_modules/@slack/types/dist/events/group.d.ts +55 -0
- package/node_modules/@slack/types/dist/events/group.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/group.js +3 -0
- package/node_modules/@slack/types/dist/events/group.js.map +1 -0
- package/node_modules/@slack/types/dist/events/im.d.ts +26 -0
- package/node_modules/@slack/types/dist/events/im.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/im.js +3 -0
- package/node_modules/@slack/types/dist/events/im.js.map +1 -0
- package/node_modules/@slack/types/dist/events/index.d.ts +60 -0
- package/node_modules/@slack/types/dist/events/index.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/index.js +43 -0
- package/node_modules/@slack/types/dist/events/index.js.map +1 -0
- package/node_modules/@slack/types/dist/events/invite.d.ts +20 -0
- package/node_modules/@slack/types/dist/events/invite.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/invite.js +3 -0
- package/node_modules/@slack/types/dist/events/invite.js.map +1 -0
- package/node_modules/@slack/types/dist/events/link-shared.d.ts +16 -0
- package/node_modules/@slack/types/dist/events/link-shared.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/link-shared.js +3 -0
- package/node_modules/@slack/types/dist/events/link-shared.js.map +1 -0
- package/node_modules/@slack/types/dist/events/member.d.ts +19 -0
- package/node_modules/@slack/types/dist/events/member.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/member.js +3 -0
- package/node_modules/@slack/types/dist/events/member.js.map +1 -0
- package/node_modules/@slack/types/dist/events/message-metadata.d.ts +38 -0
- package/node_modules/@slack/types/dist/events/message-metadata.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/message-metadata.js +3 -0
- package/node_modules/@slack/types/dist/events/message-metadata.js.map +1 -0
- package/node_modules/@slack/types/dist/events/message.d.ts +306 -0
- package/node_modules/@slack/types/dist/events/message.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/message.js +3 -0
- package/node_modules/@slack/types/dist/events/message.js.map +1 -0
- package/node_modules/@slack/types/dist/events/pin.d.ts +60 -0
- package/node_modules/@slack/types/dist/events/pin.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/pin.js +3 -0
- package/node_modules/@slack/types/dist/events/pin.js.map +1 -0
- package/node_modules/@slack/types/dist/events/reaction.d.ts +23 -0
- package/node_modules/@slack/types/dist/events/reaction.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/reaction.js +3 -0
- package/node_modules/@slack/types/dist/events/reaction.js.map +1 -0
- package/node_modules/@slack/types/dist/events/shared-channel.d.ts +134 -0
- package/node_modules/@slack/types/dist/events/shared-channel.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/shared-channel.js +3 -0
- package/node_modules/@slack/types/dist/events/shared-channel.js.map +1 -0
- package/node_modules/@slack/types/dist/events/star.d.ts +13 -0
- package/node_modules/@slack/types/dist/events/star.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/star.js +3 -0
- package/node_modules/@slack/types/dist/events/star.js.map +1 -0
- package/node_modules/@slack/types/dist/events/steps-from-apps.d.ts +82 -0
- package/node_modules/@slack/types/dist/events/steps-from-apps.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/steps-from-apps.js +3 -0
- package/node_modules/@slack/types/dist/events/steps-from-apps.js.map +1 -0
- package/node_modules/@slack/types/dist/events/subteam.d.ts +66 -0
- package/node_modules/@slack/types/dist/events/subteam.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/subteam.js +3 -0
- package/node_modules/@slack/types/dist/events/subteam.js.map +1 -0
- package/node_modules/@slack/types/dist/events/team.d.ts +99 -0
- package/node_modules/@slack/types/dist/events/team.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/team.js +3 -0
- package/node_modules/@slack/types/dist/events/team.js.map +1 -0
- package/node_modules/@slack/types/dist/events/token.d.ts +8 -0
- package/node_modules/@slack/types/dist/events/token.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/token.js +3 -0
- package/node_modules/@slack/types/dist/events/token.js.map +1 -0
- package/node_modules/@slack/types/dist/events/user.d.ts +313 -0
- package/node_modules/@slack/types/dist/events/user.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/events/user.js +3 -0
- package/node_modules/@slack/types/dist/events/user.js.map +1 -0
- package/node_modules/@slack/types/dist/index.d.ts +12 -0
- package/node_modules/@slack/types/dist/index.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/index.js +28 -0
- package/node_modules/@slack/types/dist/index.js.map +1 -0
- package/node_modules/@slack/types/dist/message-attachments.d.ts +171 -0
- package/node_modules/@slack/types/dist/message-attachments.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/message-attachments.js +3 -0
- package/node_modules/@slack/types/dist/message-attachments.js.map +1 -0
- package/node_modules/@slack/types/dist/message-metadata.d.ts +281 -0
- package/node_modules/@slack/types/dist/message-metadata.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/message-metadata.js +27 -0
- package/node_modules/@slack/types/dist/message-metadata.js.map +1 -0
- package/node_modules/@slack/types/dist/views.d.ts +71 -0
- package/node_modules/@slack/types/dist/views.d.ts.map +1 -0
- package/node_modules/@slack/types/dist/views.js +3 -0
- package/node_modules/@slack/types/dist/views.js.map +1 -0
- package/node_modules/@slack/types/package.json +47 -0
- package/node_modules/@vellumai/gateway-client/bun.lock +3 -0
- package/node_modules/@vellumai/gateway-client/package.json +1 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/contact-read-contracts.test.ts +69 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/guardian-delivery-contract.test.ts +91 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +96 -0
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +162 -0
- package/node_modules/@vellumai/gateway-client/src/guardian-delivery-contract.ts +48 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +8 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +28 -0
- package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +4 -2
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +3 -2
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +95 -0
- package/openapi.yaml +458 -18
- package/package.json +2 -1
- package/scripts/memory-inspect.ts +24 -14
- package/scripts/test.sh +36 -15
- package/src/__tests__/access-request-seed-content-blocks.test.ts +83 -103
- package/src/__tests__/activation-early-marking.test.ts +1 -1
- package/src/__tests__/actor-token-service.test.ts +39 -17
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +1 -40
- package/src/__tests__/agent-loop-compaction-events.test.ts +0 -1
- package/src/__tests__/agent-loop-compaction-strip.test.ts +0 -1
- package/src/__tests__/agent-loop-exit-reason.test.ts +0 -1
- package/src/__tests__/agent-loop-pushes-post-hook-prompt.test.ts +306 -0
- package/src/__tests__/agent-loop-regrowth-guard.test.ts +0 -1
- package/src/__tests__/agent-loop.test.ts +3 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +2 -0
- package/src/__tests__/anthropic-provider.test.ts +210 -9
- package/src/__tests__/app-builder-skill-instructions.test.ts +47 -5
- package/src/__tests__/app-conversation-ids-backfill.test.ts +1 -1
- package/src/__tests__/app-source-watcher.test.ts +30 -10
- package/src/__tests__/approval-cascade.test.ts +6 -0
- package/src/__tests__/approval-interception-trust-gates.test.ts +151 -0
- package/src/__tests__/approval-primitive.test.ts +1 -1
- package/src/__tests__/approval-routes-http.test.ts +1 -1
- package/src/__tests__/assistant-attachments.test.ts +155 -0
- package/src/__tests__/assistant-event-hub-machine-name.test.ts +2 -4
- package/src/__tests__/assistant-events-sse-hardening.test.ts +1 -1
- package/src/__tests__/assistant-events-sse-shed.test.ts +1 -1
- package/src/__tests__/attachment-upload-trusted-source.test.ts +13 -8
- package/src/__tests__/attachments-store.test.ts +1 -1
- package/src/__tests__/audit-log-rotation.test.ts +50 -54
- package/src/__tests__/auth-fallback-events-store.test.ts +1 -1
- package/src/__tests__/auto-analysis-end-to-end.test.ts +9 -14
- package/src/__tests__/background-shell-bash.test.ts +4 -1
- package/src/__tests__/background-shell-host-bash.test.ts +17 -3
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -0
- package/src/__tests__/call-controller.test.ts +20 -1
- package/src/__tests__/call-conversation-messages.test.ts +1 -1
- package/src/__tests__/call-domain.test.ts +1 -1
- package/src/__tests__/call-pointer-messages.test.ts +3 -4
- package/src/__tests__/call-recovery.test.ts +1 -1
- package/src/__tests__/call-routes-http.test.ts +1 -1
- package/src/__tests__/call-store.test.ts +1 -1
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
- package/src/__tests__/canonical-guardian-store.test.ts +24 -1
- package/src/__tests__/card-surface-data.test.ts +60 -0
- package/src/__tests__/channel-approval-routes.test.ts +73 -1119
- package/src/__tests__/channel-delivery-store.test.ts +1 -1
- package/src/__tests__/channel-guardian.test.ts +291 -641
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +1 -2
- package/src/__tests__/channel-retry-sweep.test.ts +1 -1
- package/src/__tests__/compaction-events.test.ts +6 -0
- package/src/__tests__/compaction-trail-store.test.ts +6 -5
- package/src/__tests__/compaction.benchmark.test.ts +0 -1
- package/src/__tests__/compactor-image-manifest-trust.test.ts +1 -1
- package/src/__tests__/config-loader-backfill.test.ts +188 -52
- package/src/__tests__/config-schema.test.ts +35 -0
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +1 -2
- package/src/__tests__/contact-store-user-file.test.ts +2 -2
- package/src/__tests__/contacts-relay-reads.test.ts +409 -0
- package/src/__tests__/contacts-tools.test.ts +4 -4
- package/src/__tests__/contacts-write.test.ts +1 -2
- package/src/__tests__/context-search-conversations-source.test.ts +1 -1
- package/src/__tests__/context-window-manager-compact-retry.test.ts +6 -2
- package/src/__tests__/context-window-manager-overflow-rung.test.ts +6 -2
- package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +3 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +3 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +3 -0
- package/src/__tests__/conversation-agent-loop.test.ts +7 -0
- package/src/__tests__/conversation-attachments.test.ts +2 -5
- package/src/__tests__/conversation-attention-store.test.ts +1 -1
- package/src/__tests__/conversation-attention-telegram.test.ts +1 -2
- package/src/__tests__/conversation-clear-safety.test.ts +1 -1
- package/src/__tests__/conversation-confirmation-signals.test.ts +6 -0
- package/src/__tests__/conversation-crud-inference-profile.test.ts +1 -1
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +12 -19
- package/src/__tests__/conversation-disk-view-integration.test.ts +1 -1
- package/src/__tests__/conversation-disk-view.test.ts +1 -1
- package/src/__tests__/conversation-fork-crud.test.ts +10 -8
- package/src/__tests__/conversation-fork-retrospective.test.ts +250 -0
- package/src/__tests__/conversation-fork-route.test.ts +1 -1
- package/src/__tests__/conversation-inference-profile-list.test.ts +1 -1
- package/src/__tests__/conversation-inference-profile-route.test.ts +1 -1
- package/src/__tests__/conversation-init.benchmark.test.ts +1 -1
- package/src/__tests__/conversation-key-store-disk-view.test.ts +1 -1
- package/src/__tests__/conversation-lifecycle.test.ts +117 -0
- package/src/__tests__/conversation-list-source.test.ts +3 -3
- package/src/__tests__/conversation-process-callsite.test.ts +6 -14
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/conversation-queue.test.ts +95 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +1 -1
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +12 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +12 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +115 -12
- package/src/__tests__/conversation-slash-queue.test.ts +6 -0
- package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
- package/src/__tests__/conversation-speed-override.test.ts +6 -0
- package/src/__tests__/conversation-starter-routes.test.ts +5 -5
- package/src/__tests__/conversation-store.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +4 -4
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +352 -0
- package/src/__tests__/conversation-sync-tags.test.ts +1 -1
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +47 -0
- package/src/__tests__/conversation-usage.test.ts +1 -1
- package/src/__tests__/conversation-wipe.test.ts +9 -8
- package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
- package/src/__tests__/conversations-import-system-filter.test.ts +1 -1
- package/src/__tests__/copy-composer-tc-templates.test.ts +17 -0
- package/src/__tests__/credential-security-invariants.test.ts +0 -1
- package/src/__tests__/db-acp-history.test.ts +2 -2
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +5 -7
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +6 -7
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +5 -10
- package/src/__tests__/db-migration-rollback.test.ts +129 -39
- package/src/__tests__/db-proxy-transaction.test.ts +1 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +0 -11
- package/src/__tests__/db-test-helpers.ts +36 -19
- package/src/__tests__/delete-propagation.test.ts +1 -1
- package/src/__tests__/deterministic-verification-control-plane.test.ts +28 -8
- package/src/__tests__/disk-pressure-guard.test.ts +41 -0
- package/src/__tests__/disk-pressure-tools.test.ts +41 -1
- package/src/__tests__/dm-backfill.test.ts +1 -1
- package/src/__tests__/drop-capability-card-state-migration.test.ts +0 -8
- package/src/__tests__/dynamic-page-surface.test.ts +0 -94
- package/src/__tests__/edit-propagation.test.ts +1 -1
- package/src/__tests__/emit-signal-routing-intent.test.ts +93 -5
- package/src/__tests__/empty-response-hook.test.ts +42 -0
- package/src/__tests__/events-client-registration.test.ts +1 -1
- package/src/__tests__/events-dev-bypass-actor.test.ts +7 -1
- package/src/__tests__/followup-tools.test.ts +1 -1
- package/src/__tests__/gemini-count-tokens.test.ts +70 -0
- package/src/__tests__/guardian-action-sweep.test.ts +9 -2
- package/src/__tests__/guardian-binding-drift-heal.test.ts +76 -11
- package/src/__tests__/guardian-card-withdrawal.test.ts +1 -1
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +1 -1
- package/src/__tests__/guardian-dispatch.test.ts +96 -2
- package/src/__tests__/guardian-outbound-http.test.ts +20 -12
- package/src/__tests__/guardian-principal-id-roundtrip.test.ts +1 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
- package/src/__tests__/guardian-routing-state.test.ts +1 -2
- package/src/__tests__/guardian-verification-voice-binding.test.ts +1 -1
- package/src/__tests__/headless-browser-mode.test.ts +2 -2
- package/src/__tests__/heartbeat-disk-pressure.test.ts +4 -0
- package/src/__tests__/heartbeat-service.test.ts +6 -0
- package/src/__tests__/helpers/channel-test-adapter.ts +92 -0
- package/src/__tests__/host-app-control-routes.test.ts +24 -30
- package/src/__tests__/host-bash-routes.test.ts +31 -41
- package/src/__tests__/host-browser-routes.test.ts +26 -32
- package/src/__tests__/host-cu-routes-targeted.test.ts +25 -33
- package/src/__tests__/host-file-routes-targeted.test.ts +40 -52
- package/src/__tests__/host-transfer-routes-targeted.test.ts +31 -43
- package/src/__tests__/http-conversation-lineage.test.ts +1 -1
- package/src/__tests__/http-user-message-parity.test.ts +165 -8
- package/src/__tests__/image-recovery-hook.test.ts +1 -1
- package/src/__tests__/inbound-invite-redemption.test.ts +1 -2
- package/src/__tests__/inbound-trust-verdict.test.ts +254 -0
- package/src/__tests__/inference-profile-reaper.test.ts +1 -1
- package/src/__tests__/inference-profile-session-handler.test.ts +1 -1
- package/src/__tests__/inference-profile-session-ipc.test.ts +1 -1
- package/src/__tests__/injector-chain.test.ts +1 -1
- package/src/__tests__/injector-disk-pressure.test.ts +11 -6
- package/src/__tests__/internal-telemetry-routes.test.ts +1 -1
- package/src/__tests__/invite-redemption-service.test.ts +244 -43
- package/src/__tests__/invite-routes-http.test.ts +35 -186
- package/src/__tests__/invite-service-ipc.test.ts +287 -0
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +5 -5
- package/src/__tests__/jobs-store-upsert-debounced.test.ts +9 -12
- package/src/__tests__/list-messages-attachments.test.ts +42 -1
- package/src/__tests__/list-messages-client-message-id.test.ts +1 -1
- package/src/__tests__/list-messages-hidden-metadata.test.ts +1 -1
- package/src/__tests__/list-messages-page-latest.test.ts +1 -1
- package/src/__tests__/list-messages-tool-merge.test.ts +1 -1
- package/src/__tests__/llm-context-normalization.test.ts +105 -0
- package/src/__tests__/llm-context-route-provider.test.ts +69 -4
- package/src/__tests__/llm-request-log-agent-loop-exit-reason.test.ts +9 -5
- package/src/__tests__/llm-request-log-call-site.test.ts +6 -6
- package/src/__tests__/llm-request-log-turn-query.test.ts +27 -13
- package/src/__tests__/llm-resolver.test.ts +205 -5
- package/src/__tests__/llm-usage-store.test.ts +65 -1
- package/src/__tests__/log-export-routes.test.ts +1 -1
- package/src/__tests__/log-export-workspace.test.ts +3 -3
- package/src/__tests__/media-stream-server-integration.test.ts +127 -0
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +5 -5
- package/src/__tests__/memory-recall-log-store.test.ts +1 -1
- package/src/__tests__/memory-upsert-concurrency.test.ts +3 -4
- package/src/__tests__/messages-after-tiebreaker.test.ts +1 -1
- package/src/__tests__/migration-import-from-url.test.ts +2 -2
- package/src/__tests__/mtime-cache.test.ts +375 -0
- package/src/__tests__/non-member-access-request.test.ts +190 -19
- package/src/__tests__/notification-broadcaster.test.ts +4 -0
- package/src/__tests__/notification-candidate-guardian-context.test.ts +203 -0
- package/src/__tests__/notification-decision-recipient-context.test.ts +33 -32
- package/src/__tests__/notification-deep-link.test.ts +4 -0
- package/src/__tests__/notification-guardian-path.test.ts +20 -1
- package/src/__tests__/notification-schedule-notify-dedup.test.ts +1 -1
- package/src/__tests__/oauth-provider-profiles.test.ts +1 -1
- package/src/__tests__/oauth-provider-visibility.test.ts +1 -1
- package/src/__tests__/oauth-store.test.ts +1 -1
- package/src/__tests__/pending-interactions-resolved-event.test.ts +7 -4
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +1 -1
- package/src/__tests__/persist-unsendable-image.test.ts +1 -1
- package/src/__tests__/persona-resolver.test.ts +39 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +1 -1
- package/src/__tests__/playbook-execution.test.ts +1 -1
- package/src/__tests__/playbook-tools.test.ts +1 -1
- package/src/__tests__/plugin-api-model-profiles.test.ts +74 -21
- package/src/__tests__/plugin-bootstrap.test.ts +78 -0
- package/src/__tests__/provider-platform-proxy-integration.test.ts +25 -5
- package/src/__tests__/provider-usage-tracking.test.ts +40 -1
- package/src/__tests__/prune-old-conversations-job.test.ts +1 -1
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- package/src/__tests__/registry.test.ts +3 -0
- package/src/__tests__/relay-server.test.ts +1026 -73
- package/src/__tests__/runtime-attachment-metadata.test.ts +9 -1
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +7 -9
- package/src/__tests__/runtime-events-sse-parity.test.ts +1 -1
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +1 -1
- package/src/__tests__/runtime-events-sse.test.ts +1 -1
- package/src/__tests__/schedule-retry.test.ts +1 -1
- package/src/__tests__/schedule-routes-workflow-validation.test.ts +1 -1
- package/src/__tests__/schedule-routes.test.ts +1 -1
- package/src/__tests__/schedule-store.test.ts +1 -1
- package/src/__tests__/schedule-tools.test.ts +1 -1
- package/src/__tests__/scheduler-disk-pressure.test.ts +1 -1
- package/src/__tests__/scheduler-recurrence.test.ts +1 -1
- package/src/__tests__/scheduler-reuse-conversation.test.ts +1 -1
- package/src/__tests__/scheduler-wake.test.ts +2 -1
- package/src/__tests__/scoped-approval-grants.test.ts +1 -1
- package/src/__tests__/scoped-grant-security-matrix.test.ts +5 -5
- package/src/__tests__/scrub-corrupted-image-attachments.test.ts +0 -8
- package/src/__tests__/secret-ingress-http.test.ts +12 -0
- package/src/__tests__/secret-routes-platform-proxy.test.ts +1 -0
- package/src/__tests__/send-endpoint-busy.test.ts +31 -9
- package/src/__tests__/sequence-store.test.ts +1 -1
- package/src/__tests__/server-history-render.test.ts +40 -1
- package/src/__tests__/settings-routes.test.ts +11 -10
- package/src/__tests__/skill-load-tool.test.ts +72 -0
- package/src/__tests__/skills.test.ts +44 -0
- package/src/__tests__/slack-inbound-verification.test.ts +48 -5
- package/src/__tests__/slack-messaging-token-resolution.test.ts +13 -2
- package/src/__tests__/slack-reaction-canonical-approval.test.ts +1 -1
- package/src/__tests__/sse-actor-principal-guardian-source.test.ts +102 -0
- package/src/__tests__/steer-on-enqueue-question.test.ts +181 -0
- package/src/__tests__/stt-hints.test.ts +44 -13
- package/src/__tests__/subagent-detail.test.ts +27 -0
- package/src/__tests__/subagent-disposal.test.ts +65 -0
- package/src/__tests__/subagent-tool-gate-mode.test.ts +2 -73
- package/src/__tests__/subagent-tools.test.ts +1 -31
- package/src/__tests__/system-prompt.test.ts +1 -1
- package/src/__tests__/system-storage-cleanup-skill.test.ts +56 -0
- package/src/__tests__/task-compiler.test.ts +1 -1
- package/src/__tests__/task-management-tools.test.ts +1 -1
- package/src/__tests__/task-memory-cleanup.test.ts +9 -6
- package/src/__tests__/task-scheduler.test.ts +1 -1
- package/src/__tests__/thread-backfill.test.ts +1 -1
- package/src/__tests__/tool-approval-handler.test.ts +1 -1
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +2 -0
- package/src/__tests__/tool-executor.test.ts +37 -1
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -2
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +73 -1
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +34 -34
- package/src/__tests__/trusted-contact-multichannel.test.ts +1 -2
- package/src/__tests__/trusted-contact-verification.test.ts +1 -1
- package/src/__tests__/turn-boundary-resolution.test.ts +3 -3
- package/src/__tests__/turn-events-store.test.ts +1 -1
- package/src/__tests__/twilio-routes.test.ts +98 -3
- package/src/__tests__/usage-cache-backfill-migration.test.ts +20 -10
- package/src/__tests__/usage-routes.test.ts +1 -1
- package/src/__tests__/user-plugin-loader.test.ts +34 -29
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -2
- package/src/__tests__/voice-invite-redemption.test.ts +134 -36
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +1 -1
- package/src/__tests__/voice-session-bridge.test.ts +1 -1
- package/src/__tests__/workspace-git-service.test.ts +114 -1
- package/src/__tests__/workspace-heartbeat-service.test.ts +45 -0
- package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +1 -1
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +1 -1
- package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +88 -18
- package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +6 -6
- package/src/__tests__/workspace-migration-109-swap-quality-profile-to-glm-5p2.test.ts +281 -0
- package/src/__tests__/workspace-migration-110-flip-balanced-profile-to-together.test.ts +167 -0
- package/src/__tests__/workspace-migrations-runner.test.ts +55 -0
- package/src/__tests__/workspace-tool-loader.test.ts +3 -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-exclusive-tool.test.ts +150 -0
- package/src/agent/loop.ts +101 -27
- package/src/api/constants/sse-replay.ts +41 -0
- package/src/api/events/ui-surface-show.ts +8 -3
- package/src/api/index.ts +7 -6
- package/src/api/responses/conversation-message.ts +4 -0
- package/src/api/responses/llm-request-log-entry.ts +25 -0
- package/src/api/responses/subagent-detail.ts +17 -0
- package/src/api/surfaces.ts +33 -0
- package/src/approvals/AGENTS.md +1 -2
- package/src/approvals/guardian-decision-primitive.ts +13 -210
- package/src/approvals/guardian-request-resolvers.ts +104 -58
- package/src/background-wake/wake-intent-hooks.test.ts +1 -1
- package/src/calls/__tests__/inbound-trust-reader.test.ts +110 -0
- package/src/calls/__tests__/relay-setup-router.test.ts +349 -65
- package/src/calls/guardian-dispatch.ts +10 -8
- package/src/calls/inbound-trust-reader.ts +56 -0
- package/src/calls/media-stream-server.ts +21 -0
- package/src/calls/relay-server.ts +231 -72
- package/src/calls/relay-setup-router.ts +57 -13
- package/src/calls/relay-verification.ts +7 -7
- package/src/calls/stt-hints.ts +9 -12
- package/src/calls/twilio-routes.ts +13 -3
- package/src/cli/commands/__tests__/cache.test.ts +8 -1
- package/src/cli/commands/cache.ts +194 -181
- package/src/cli/commands/contacts.ts +6 -24
- package/src/cli/commands/db/__tests__/repair.test.ts +15 -6
- package/src/cli/commands/db/__tests__/status.test.ts +7 -3
- package/src/cli/commands/db/status.ts +212 -33
- package/src/cli/commands/mcp.ts +252 -218
- package/src/cli/commands/memory/__tests__/memory-v3.test.ts +6 -1
- package/src/cli/commands/memory/__tests__/worker.test.ts +302 -0
- package/src/cli/commands/memory/index.ts +4 -0
- package/src/cli/commands/memory/memory-retrospective.ts +129 -0
- package/src/cli/commands/memory/memory-v3.ts +176 -4
- package/src/cli/commands/memory/worker.ts +175 -0
- package/src/cli/commands/plugins.ts +343 -14
- package/src/cli/lib/__tests__/install-from-github.test.ts +40 -0
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +160 -1
- package/src/cli/lib/__tests__/plugin-pin-history.test.ts +162 -0
- package/src/cli/lib/__tests__/toggle-plugin.test.ts +158 -0
- package/src/cli/lib/install-from-github.ts +47 -6
- package/src/cli/lib/list-installed-plugins.ts +179 -1
- package/src/cli/lib/plugin-marketplace.ts +11 -0
- package/src/cli/lib/plugin-pin-history.ts +257 -0
- package/src/cli/lib/toggle-plugin.ts +146 -0
- package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +143 -0
- package/src/config/__tests__/sync-gated-profiles.test.ts +2 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +15 -33
- package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +3 -8
- package/src/config/bundled-skills/app-builder/references/INTERACTION_HOOKS.md +64 -37
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +1 -1
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +14 -72
- package/src/config/bundled-skills/app-builder/references/examples/README.md +1 -2
- package/src/config/bundled-skills/contacts/SKILL.md +7 -12
- package/src/config/bundled-skills/messaging/tools/shared.ts +4 -1
- package/src/config/bundled-skills/system-storage-cleanup/SKILL.md +74 -0
- package/src/config/bundled-skills/workflows/SKILL.md +4 -3
- package/src/config/call-site-defaults.ts +11 -2
- package/src/config/feature-flag-registry.json +0 -8
- package/src/config/llm-resolver.ts +151 -14
- package/src/config/loader.ts +36 -5
- package/src/config/profile-dispatchability.ts +11 -0
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/call-site-catalog.ts +7 -0
- package/src/config/schemas/llm.ts +2 -0
- package/src/config/schemas/memory-lifecycle.ts +17 -3
- package/src/config/schemas/memory-v3.ts +7 -0
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/timeouts.ts +32 -0
- package/src/config/seed-inference-profiles.ts +147 -50
- package/src/config/skills.ts +27 -5
- package/src/config/sync-gated-profiles.ts +13 -1
- package/src/contacts/__tests__/guardian-delivery-reader.test.ts +312 -0
- package/src/contacts/contact-store.ts +21 -0
- package/src/contacts/contacts-write.ts +3 -0
- package/src/contacts/guardian-delivery-reader.ts +223 -0
- package/src/contacts/member-status.ts +9 -0
- package/src/credential-health/credential-health-service.ts +1 -5
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +44 -0
- package/src/daemon/app-source-watcher.ts +31 -18
- package/src/daemon/assistant-attachments.ts +94 -4
- package/src/daemon/conversation-agent-loop-handlers.ts +3 -0
- package/src/daemon/conversation-agent-loop.ts +18 -36
- package/src/daemon/conversation-process.ts +35 -16
- package/src/daemon/conversation-runtime-assembly.ts +91 -66
- package/src/daemon/conversation-surfaces.ts +273 -18
- package/src/daemon/conversation-tool-setup.ts +24 -64
- package/src/daemon/conversation.ts +149 -53
- package/src/daemon/disk-pressure-guard.ts +12 -2
- package/src/daemon/event-loop-watchdog.test.ts +85 -0
- package/src/daemon/event-loop-watchdog.ts +133 -0
- package/src/daemon/external-plugins-bootstrap.ts +26 -80
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +1 -1
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +1 -1
- package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +1 -1
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +1 -1
- package/src/daemon/handlers/__tests__/config-a2a.test.ts +1 -1
- package/src/daemon/handlers/config-channels.ts +41 -27
- package/src/daemon/handlers/conversations.ts +84 -0
- package/src/daemon/handlers/shared.ts +7 -0
- package/src/daemon/lifecycle.ts +44 -5
- package/src/daemon/memory-v2-startup.test.ts +72 -0
- package/src/daemon/memory-v2-startup.ts +87 -19
- package/src/daemon/message-types/inbox.ts +0 -6
- package/src/daemon/message-types/messages.ts +0 -4
- package/src/daemon/message-types/surfaces.ts +12 -11
- package/src/daemon/server.ts +0 -4
- package/src/daemon/shutdown-handlers.ts +20 -0
- package/src/daemon/tool-setup-types.ts +7 -5
- package/src/daemon/trust-context.ts +6 -0
- package/src/daemon/wake-conversation-ops.ts +70 -0
- package/src/daemon/workspace-tools-watcher.ts +7 -3
- package/src/documents/document-comments-store.test.ts +1 -1
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +1 -1
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +6 -0
- package/src/heartbeat/heartbeat-service.ts +3 -4
- package/src/ipc/__tests__/attachment-ipc.test.ts +1 -1
- package/src/ipc/__tests__/browser-ipc.test.ts +73 -2
- package/src/ipc/__tests__/clients-list-ipc.test.ts +1 -1
- package/src/ipc/__tests__/watcher-ipc.test.ts +59 -39
- package/src/ipc/assistant-server.ts +10 -2
- package/src/ipc/gateway-client.ts +2 -1
- package/src/ipc/routes/__tests__/invite-ipc-routes.test.ts +58 -0
- package/src/ipc/routes/invite-ipc-routes.ts +66 -0
- package/src/live-voice/__tests__/live-voice-archive.test.ts +1 -1
- package/src/memory/__tests__/activation-session-store.test.ts +1 -1
- package/src/memory/__tests__/auto-analysis-guard.test.ts +1 -1
- package/src/memory/__tests__/conversation-group-migration.test.ts +1 -1
- package/src/memory/__tests__/conversation-queries.test.ts +1 -1
- package/src/memory/__tests__/db-async-query.test.ts +1 -1
- package/src/memory/__tests__/db-logs-attach.test.ts +110 -0
- package/src/memory/__tests__/db-maintenance.test.ts +28 -36
- package/src/memory/__tests__/db-memory-attach.test.ts +113 -0
- package/src/memory/__tests__/find-analysis-conversation.test.ts +1 -1
- package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +1 -1
- package/src/memory/__tests__/fork-message-copy.test.ts +232 -0
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +3 -0
- package/src/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +5 -5
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +8 -6
- package/src/memory/__tests__/memory-retrospective-job.test.ts +30 -37
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +69 -66
- package/src/memory/__tests__/memory-retrospective-state.test.ts +1 -1
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -1
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +1 -1
- package/src/memory/__tests__/onboarding-events-store.test.ts +1 -1
- package/src/memory/__tests__/prompt-override.test.ts +192 -0
- package/src/memory/__tests__/table-relocation.test.ts +129 -0
- package/src/memory/conversation-crud.ts +461 -152
- package/src/memory/db-async-query.ts +89 -5
- package/src/memory/db-connection.ts +101 -18
- package/src/memory/db-init.ts +409 -234
- package/src/memory/db-maintenance.ts +43 -38
- package/src/memory/db-singleton.ts +45 -19
- package/src/memory/embedding-gemini.test.ts +3 -1
- package/src/memory/embedding-gemini.ts +18 -2
- package/src/memory/fork-message-copy.ts +170 -0
- package/src/memory/graph/__tests__/handle-remember-v2.test.ts +92 -0
- package/src/memory/graph/bootstrap.test.ts +6 -3
- package/src/memory/graph/retriever.test.ts +12 -12
- package/src/memory/graph/store.test.ts +15 -25
- package/src/memory/graph/store.ts +23 -14
- package/src/memory/graph/tool-handlers.ts +34 -5
- package/src/memory/graph/tools.ts +5 -2
- package/src/memory/indexer.ts +21 -9
- package/src/memory/job-handlers/cleanup.ts +10 -3
- package/src/memory/job-handlers/embedding.test.ts +4 -4
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +4 -4
- package/src/memory/jobs/embed-pkb-file.test.ts +7 -7
- package/src/memory/jobs-store.ts +36 -24
- package/src/memory/llm-request-log-store.ts +51 -19
- package/src/memory/llm-usage-store.ts +79 -21
- package/src/memory/memory-retrospective-job.ts +27 -19
- package/src/memory/memory-retrospective-startup-cleanup.ts +10 -2
- package/src/memory/migrations/{100-core-tables.ts → 000-core-tables.ts} +6 -10
- package/src/memory/migrations/014-backfill-inbox-thread-state.ts +13 -3
- package/src/memory/migrations/104-core-indexes.ts +1 -1
- package/src/memory/migrations/126-backfill-guardian-principal-id.ts +189 -196
- package/src/memory/migrations/127-guardian-principal-id-not-null.ts +98 -105
- package/src/memory/migrations/134-contacts-notes-column.ts +66 -69
- package/src/memory/migrations/135-backfill-contact-interaction-stats.ts +19 -22
- package/src/memory/migrations/136-drop-assistant-id-columns.ts +241 -219
- package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +204 -209
- package/src/memory/migrations/141-rename-verification-table.ts +45 -48
- package/src/memory/migrations/142-rename-verification-session-id-column.ts +16 -23
- package/src/memory/migrations/143-rename-guardian-verification-values.ts +23 -30
- package/src/memory/migrations/144-rename-voice-to-phone.ts +133 -136
- package/src/memory/migrations/145-drop-accounts-table.ts +4 -7
- package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +79 -82
- package/src/memory/migrations/148-drop-reminders-table.ts +3 -6
- package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +71 -78
- package/src/memory/migrations/157-invite-contact-id.ts +73 -76
- package/src/memory/migrations/162-guardian-timestamps-epoch-ms.ts +44 -58
- package/src/memory/migrations/169-rename-gmail-provider-key-to-google.ts +36 -43
- package/src/memory/migrations/174-rename-thread-starters-table.ts +30 -37
- package/src/memory/migrations/176-drop-capability-card-state.ts +17 -22
- package/src/memory/migrations/177-create-trace-events-table.ts +23 -28
- package/src/memory/migrations/180-backfill-inline-attachments-to-disk.ts +36 -43
- package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +14 -21
- package/src/memory/migrations/191-backfill-audio-attachment-mime-types.ts +17 -24
- package/src/memory/migrations/192-contacts-user-file-column.ts +6 -9
- package/src/memory/migrations/193-add-source-type-columns.ts +33 -36
- package/src/memory/migrations/194-memory-recall-logs.ts +34 -39
- package/src/memory/migrations/196-strip-integration-prefix-from-provider-keys.ts +59 -66
- package/src/memory/migrations/199-guardian-request-enrichment-columns.ts +41 -48
- package/src/memory/migrations/204-rename-memory-graph-type-values.ts +11 -18
- package/src/memory/migrations/206-scrub-corrupted-image-attachments.ts +76 -83
- package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +135 -68
- package/src/memory/migrations/211-memory-recall-logs-query-context.ts +6 -11
- package/src/memory/migrations/212-llm-request-logs-created-at-index.ts +4 -9
- package/src/memory/migrations/217-conversation-host-access.ts +13 -18
- package/src/memory/migrations/220-normalize-user-file-by-principal.ts +86 -93
- package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +41 -48
- package/src/memory/migrations/230-acp-session-history.ts +23 -28
- package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +58 -62
- package/src/memory/migrations/232-activation-state.ts +11 -16
- package/src/memory/migrations/233-document-conversations.ts +20 -25
- package/src/memory/migrations/234-memory-v2-activation-logs.ts +26 -31
- package/src/memory/migrations/235-slack-compaction-watermark.ts +5 -10
- package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +6 -11
- package/src/memory/migrations/237-heartbeat-runs.ts +22 -27
- package/src/memory/migrations/239-trace-events-created-at-index.ts +4 -9
- package/src/memory/migrations/242-message-bookmarks.ts +17 -22
- package/src/memory/migrations/245-memory-retrospective-state.ts +8 -13
- package/src/memory/migrations/249-normalize-slack-external-content.ts +37 -41
- package/src/memory/migrations/251-a2a-tasks.ts +27 -32
- package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +12 -17
- package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +10 -15
- package/src/memory/migrations/256-memory-v2-injection-events.ts +70 -74
- package/src/memory/migrations/259-conversation-cleaned-at.ts +4 -9
- package/src/memory/migrations/260-rename-cleaned-at.ts +11 -16
- package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +3 -8
- package/src/memory/migrations/262-memory-v3-coactivation.ts +21 -26
- package/src/memory/migrations/263-memory-v3-auto-edges.ts +14 -19
- package/src/memory/migrations/270-schedule-description.ts +7 -12
- package/src/memory/migrations/272-acp-session-history-cwd.ts +8 -13
- package/src/memory/migrations/281-memory-retrospective-remembered-log.ts +8 -13
- package/src/memory/migrations/297-move-llm-request-logs-to-logs-db.ts +111 -0
- package/src/memory/migrations/298-move-memory-jobs-to-memory-db.ts +128 -0
- package/src/memory/migrations/299-canonical-guardian-deliveries-conversation-index.ts +19 -0
- package/src/memory/migrations/__tests__/014-backfill-inbox-thread-state.test.ts +108 -0
- package/src/memory/migrations/__tests__/136-drop-assistant-id-columns.test.ts +82 -0
- package/src/memory/migrations/__tests__/209-strip-thinking-from-consolidated.test.ts +224 -0
- package/src/memory/migrations/__tests__/297-move-llm-request-logs.test.ts +180 -0
- package/src/memory/migrations/__tests__/run-migrations.test.ts +333 -7
- package/src/memory/migrations/helpers/relocation.ts +227 -0
- package/src/memory/migrations/registry.ts +63 -0
- package/src/memory/migrations/run-migrations.ts +187 -16
- package/src/memory/migrations/schema-introspection.ts +14 -0
- package/src/memory/migrations/validate-migration-state.ts +50 -145
- package/src/memory/prompt-override.ts +129 -0
- package/src/memory/raw-query.ts +47 -2
- package/src/memory/skill-loaded-events-store.test.ts +1 -1
- package/src/memory/task-memory-cleanup.ts +62 -41
- package/src/memory/tool-executed-events-store.test.ts +1 -1
- package/src/memory/turn-trace-store.test.ts +1 -1
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +16 -15
- package/src/memory/v2/__tests__/cli-command-store.test.ts +25 -0
- package/src/memory/v2/__tests__/harness-compare.test.ts +1 -1
- package/src/memory/v2/__tests__/harness-oracle.test.ts +1 -1
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +1 -1
- package/src/memory/v2/__tests__/skill-store.test.ts +80 -0
- package/src/memory/v2/__tests__/sweep-job.test.ts +2 -2
- package/src/memory/v2/cli-command-store.ts +75 -38
- package/src/memory/v2/prompts/consolidation.ts +13 -82
- package/src/memory/v2/prompts/router.ts +21 -93
- package/src/memory/v2/skill-store.ts +68 -31
- package/src/memory/v3-eval/__tests__/eval-packets.test.ts +38 -0
- package/src/memory/v3-eval/__tests__/eval-tally.test.ts +139 -0
- package/src/memory/v3-eval/eval-packets.ts +197 -12
- package/src/memory/v3-eval/eval-tally.ts +234 -0
- package/src/memory/worker-control.ts +118 -0
- package/src/memory/worker-process.ts +72 -0
- package/src/messaging/provider.ts +10 -0
- package/src/messaging/providers/gmail/adapter.ts +1 -0
- package/src/messaging/providers/gmail/client.ts +13 -0
- package/src/messaging/providers/index.ts +1 -1
- package/src/messaging/providers/slack/send.test.ts +87 -39
- package/src/messaging/providers/slack/send.ts +84 -105
- package/src/notifications/README.md +9 -5
- package/src/notifications/__tests__/broadcaster.test.ts +16 -8
- package/src/notifications/__tests__/connected-channels.test.ts +114 -0
- package/src/notifications/__tests__/decision-engine.test.ts +78 -9
- package/src/notifications/__tests__/destination-resolver.test.ts +256 -0
- package/src/notifications/__tests__/deterministic-checks.test.ts +43 -1
- package/src/notifications/adapters/slack.ts +12 -10
- package/src/notifications/approval-card-builder.ts +81 -20
- package/src/notifications/approval-card-data.ts +8 -5
- package/src/notifications/broadcaster.ts +8 -1
- package/src/notifications/canonical-delivery-recorder.ts +7 -5
- package/src/notifications/conversation-candidates.ts +24 -59
- package/src/notifications/copy-composer.ts +48 -68
- package/src/notifications/decision-engine.ts +15 -7
- package/src/notifications/destination-resolver.ts +68 -24
- package/src/notifications/deterministic-checks.ts +19 -16
- package/src/notifications/emit-signal.ts +68 -15
- package/src/notifications/trusted-contact-payloads.ts +70 -0
- package/src/oauth/byo-connection.test.ts +9 -0
- package/src/oauth/connection-resolver.test.ts +174 -6
- package/src/oauth/connection-resolver.ts +132 -5
- package/src/oauth/oauth-store.ts +16 -3
- package/src/oauth/scope-utils.ts +39 -0
- package/src/permissions/question-prompter.test.ts +1 -1
- package/src/permissions/question-prompter.ts +7 -4
- package/src/plugin-api/index.ts +9 -4
- package/src/plugin-api/model-profiles.test.ts +123 -0
- package/src/plugin-api/model-profiles.ts +5 -1
- package/src/plugin-api/vision-support.test.ts +173 -0
- package/src/plugin-api/vision-support.ts +113 -0
- package/src/plugins/defaults/advisor/__tests__/consult.test.ts +90 -0
- package/src/plugins/defaults/advisor/__tests__/context-pack-gating.test.ts +106 -0
- package/src/plugins/defaults/advisor/__tests__/context-pack.test.ts +60 -0
- package/src/plugins/defaults/advisor/consult.ts +65 -6
- package/src/plugins/defaults/advisor/context-pack.ts +288 -0
- package/src/plugins/defaults/advisor/steering.ts +14 -2
- package/src/plugins/defaults/advisor/tools/advisor.ts +32 -5
- package/src/plugins/defaults/compaction/window-manager.ts +45 -64
- package/src/plugins/defaults/empty-response/hooks/post-model-call.ts +13 -4
- package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +441 -0
- package/src/plugins/defaults/image-fallback/hooks/post-tool-use.ts +57 -0
- package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +61 -0
- package/src/plugins/defaults/image-fallback/package.json +14 -0
- package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +108 -0
- package/src/plugins/defaults/image-fallback/src/caption-cache.ts +49 -0
- package/src/plugins/defaults/image-fallback/src/image-persist.ts +56 -0
- package/src/plugins/defaults/image-fallback/src/vision-caption.ts +120 -0
- package/src/plugins/defaults/index.ts +27 -0
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +14 -1
- package/src/plugins/defaults/memory-retrieval/injectors.ts +4 -4
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +134 -5
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +11 -2
- package/src/plugins/defaults/memory-v3-shadow/pool-select.test.ts +146 -0
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +246 -19
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +8 -1
- package/src/plugins/external-plugin-loader.ts +47 -6
- package/src/plugins/mtime-cache.ts +772 -0
- package/src/plugins/pipeline.ts +7 -2
- package/src/plugins/registry.ts +16 -5
- package/src/plugins/user-loader.ts +22 -76
- package/src/prompts/persona-resolver.ts +29 -11
- package/src/prompts/system-prompt.ts +1 -1
- package/src/prompts/templates/system-sections.ts +4 -4
- package/src/providers/__tests__/count-tokens-forwarding.test.ts +98 -0
- package/src/providers/anthropic/client.ts +290 -185
- package/src/providers/call-site-routing.ts +14 -0
- package/src/providers/gemini/client.ts +43 -0
- package/src/providers/inference/adapter-factory.ts +6 -0
- package/src/providers/inference/connections.ts +6 -1
- package/src/providers/model-catalog.ts +53 -0
- package/src/providers/openai/responses-provider.ts +5 -0
- package/src/providers/openrouter/client.ts +5 -0
- package/src/providers/platform-proxy/constants.ts +5 -0
- package/src/providers/provider-send-message.ts +4 -0
- package/src/providers/ratelimit.ts +13 -0
- package/src/providers/retry.ts +14 -0
- package/src/providers/together/client.ts +35 -0
- package/src/providers/types.ts +25 -0
- package/src/providers/usage-tracking.ts +11 -0
- package/src/runtime/AGENTS.md +9 -1
- package/src/runtime/__tests__/agent-wake.test.ts +259 -4
- package/src/runtime/__tests__/guardian-vellum-migration.test.ts +181 -0
- package/src/runtime/__tests__/is-guardian-bound-for-channel.test.ts +64 -0
- package/src/runtime/__tests__/local-principal-trust.test.ts +164 -0
- package/src/runtime/__tests__/slack-block-formatting.test.ts +39 -10
- package/src/runtime/__tests__/trust-verdict-consumer.test.ts +670 -0
- package/src/runtime/access-request-helper.ts +19 -39
- package/src/runtime/actor-trust-resolver.ts +8 -16
- package/src/runtime/agent-wake.ts +183 -60
- package/src/runtime/anchored-guardian.test.ts +156 -0
- package/src/runtime/anchored-guardian.ts +135 -0
- package/src/runtime/assistant-stream-state.ts +9 -2
- package/src/runtime/auth/__tests__/require-bound-guardian.test.ts +99 -0
- package/src/runtime/auth/require-bound-guardian.ts +21 -11
- package/src/runtime/channel-reply-delivery.ts +6 -3
- package/src/runtime/channel-verification-service.ts +24 -0
- package/src/runtime/guardian-decision-types.ts +3 -22
- package/src/runtime/guardian-vellum-migration.ts +66 -7
- package/src/runtime/http-server.ts +1 -15
- package/src/runtime/invite-redemption-service.ts +155 -6
- package/src/runtime/invite-service.ts +113 -62
- package/src/runtime/local-actor-identity.ts +76 -11
- package/src/runtime/local-principal-trust.ts +52 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +3 -0
- package/src/runtime/pending-interactions.ts +11 -1
- package/src/runtime/routes/__tests__/acp-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +277 -0
- package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +140 -0
- package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +26 -7
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +14 -10
- package/src/runtime/routes/__tests__/contact-routes-update-channel-relay.test.ts +164 -0
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +8 -8
- package/src/runtime/routes/__tests__/conversation-surface-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +1 -3
- package/src/runtime/routes/__tests__/invite-relay-routes.test.ts +240 -0
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +4 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +143 -0
- package/src/runtime/routes/__tests__/retrospective-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +163 -0
- package/src/runtime/routes/acp-routes-list.test.ts +4 -0
- package/src/runtime/routes/acp-routes.test.ts +5 -6
- package/src/runtime/routes/attachment-routes.ts +21 -17
- package/src/runtime/routes/browser-routes.ts +19 -1
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +5 -9
- package/src/runtime/routes/channel-verification-routes.ts +13 -2
- package/src/runtime/routes/contact-routes.ts +275 -164
- package/src/runtime/routes/conversation-query-routes.ts +15 -5
- package/src/runtime/routes/conversation-routes.ts +80 -66
- package/src/runtime/routes/conversation-starter-routes.ts +7 -8
- package/src/runtime/routes/events-routes.ts +2 -2
- package/src/runtime/routes/guardian-approval-interception.ts +13 -274
- package/src/runtime/routes/host-app-control-routes.ts +5 -4
- package/src/runtime/routes/host-bash-routes.ts +5 -4
- package/src/runtime/routes/host-browser-routes.ts +9 -11
- package/src/runtime/routes/host-cu-routes.ts +5 -4
- package/src/runtime/routes/host-file-routes.ts +5 -4
- package/src/runtime/routes/host-transfer-routes.ts +6 -6
- package/src/runtime/routes/http-adapter.ts +1 -1
- package/src/runtime/routes/inbound-message-handler.ts +21 -16
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +376 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +86 -64
- package/src/runtime/routes/inbound-stages/admission-policy.ts +20 -5
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +16 -4
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +21 -8
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +14 -3
- package/src/runtime/routes/llm-context-normalization.ts +71 -0
- package/src/runtime/routes/log-export-routes.ts +2 -2
- package/src/runtime/routes/mcp-auth-routes.ts +38 -15
- package/src/runtime/routes/memory-eval-routes.ts +92 -0
- package/src/runtime/routes/memory-item-routes.test.ts +12 -11
- package/src/runtime/routes/migration-routes.ts +51 -40
- package/src/runtime/routes/plugins-routes.ts +164 -8
- package/src/runtime/routes/schedule-routes.ts +1 -0
- package/src/runtime/routes/subagents-routes.ts +5 -0
- package/src/runtime/routes/surface-action-routes.ts +39 -51
- package/src/runtime/routes/usage-routes.ts +3 -0
- package/src/runtime/routes/work-items-routes.test.ts +1 -1
- package/src/runtime/slack-block-formatting.ts +46 -48
- package/src/runtime/trust-verdict-consumer.ts +210 -0
- package/src/schedule/scheduler.ts +6 -9
- package/src/signals/user-message.ts +16 -0
- package/src/subagent/manager.ts +9 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +1 -1
- package/src/tools/ask-question/ask-question-tool.test.ts +89 -52
- package/src/tools/ask-question/ask-question-tool.ts +27 -73
- package/src/tools/browser/__tests__/browser-status.test.ts +20 -0
- package/src/tools/browser/browser-execution.ts +16 -4
- package/src/tools/document/document-comment-tool.test.ts +1 -1
- package/src/tools/executor.ts +15 -3
- package/src/tools/host-terminal/host-shell.ts +28 -9
- package/src/tools/memory/register.test.ts +32 -0
- package/src/tools/skills/load.ts +43 -2
- package/src/tools/subagent/spawn.ts +4 -10
- package/src/tools/terminal/shell.ts +16 -5
- package/src/tools/tool-defaults.ts +2 -0
- package/src/tools/types.ts +18 -2
- package/src/tools/ui-surface/definitions.ts +0 -43
- package/src/util/fs-watcher-error.ts +36 -0
- package/src/util/log-redact.ts +2 -4
- package/src/util/logs-db-path.ts +22 -0
- package/src/util/memory-db-path.ts +23 -0
- package/src/util/platform.ts +5 -0
- package/src/watcher/providers/gmail.ts +7 -2
- package/src/workflows/engine-integration.test.ts +1 -1
- package/src/workflows/engine.test.ts +1 -1
- package/src/workflows/engine.ts +22 -0
- package/src/workflows/fanout-load.test.ts +1 -1
- package/src/workflows/journal-store.test.ts +1 -1
- package/src/workflows/leaf-runner.test.ts +40 -1
- package/src/workflows/leaf-runner.ts +26 -1
- package/src/workspace/git-service.ts +144 -29
- package/src/workspace/migrations/109-swap-quality-profile-to-glm-5p2.ts +121 -0
- package/src/workspace/migrations/110-flip-balanced-profile-to-together.ts +82 -0
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/workspace/migrations/runner.ts +32 -2
- package/src/__tests__/access-request-decision.test.ts +0 -375
- package/src/__tests__/guardian-grant-minting.test.ts +0 -607
- package/src/__tests__/plugin-source-watcher.test.ts +0 -302
- package/src/api/events/turn-profile-auto-routed.ts +0 -28
- package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +0 -107
- package/src/daemon/plugin-source-watcher.ts +0 -278
- package/src/daemon/switch-inference-profile-tool.ts +0 -62
- package/src/memory/guardian-approvals.ts +0 -361
- package/src/memory/migrations/010-ext-conv-bindings-channel-chat-unique.ts +0 -66
- package/src/memory/migrations/038-actor-token-records.ts +0 -45
- package/src/memory/migrations/039-actor-refresh-token-records.ts +0 -57
- package/src/memory/migrations/103-complex-migrations.ts +0 -23
- package/src/memory/migrations/113-late-migrations.ts +0 -30
- package/src/memory/migrations/index.ts +0 -301
- package/src/runtime/routes/access-request-decision.ts +0 -297
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +0 -963
- package/src/runtime/routes/channel-guardian-routes.ts +0 -19
- package/src/runtime/routes/guardian-expiry-sweep.ts +0 -132
|
@@ -18,6 +18,7 @@ import type {
|
|
|
18
18
|
Provider,
|
|
19
19
|
ProviderResponse,
|
|
20
20
|
SendMessageOptions,
|
|
21
|
+
ToolDefinition,
|
|
21
22
|
} from "../types.js";
|
|
22
23
|
import {
|
|
23
24
|
ContextOverflowError,
|
|
@@ -785,6 +786,11 @@ export class AnthropicProvider implements Provider {
|
|
|
785
786
|
this.useNativeWebSearch = options.useNativeWebSearch ?? false;
|
|
786
787
|
}
|
|
787
788
|
|
|
789
|
+
/** See {@link Provider.supportsNativeWebSearch}. */
|
|
790
|
+
get supportsNativeWebSearch(): boolean {
|
|
791
|
+
return this.useNativeWebSearch;
|
|
792
|
+
}
|
|
793
|
+
|
|
788
794
|
async sendMessage(
|
|
789
795
|
messages: Message[],
|
|
790
796
|
options?: SendMessageOptions,
|
|
@@ -823,181 +829,7 @@ export class AnthropicProvider implements Provider {
|
|
|
823
829
|
// edge LB, NAT idle) — only the latter should be retried.
|
|
824
830
|
let innerTimeoutSignal: AbortSignal | undefined;
|
|
825
831
|
try {
|
|
826
|
-
|
|
827
|
-
.map((m) => {
|
|
828
|
-
// Track whether an unknown block was dropped during filtering
|
|
829
|
-
let droppedUnknownBlock = false;
|
|
830
|
-
|
|
831
|
-
const content = m.content
|
|
832
|
-
.map((block) => {
|
|
833
|
-
const result = this.toAnthropicBlockSafe(block);
|
|
834
|
-
if (result == null) {
|
|
835
|
-
droppedUnknownBlock = true;
|
|
836
|
-
}
|
|
837
|
-
return result;
|
|
838
|
-
})
|
|
839
|
-
.filter(
|
|
840
|
-
(block): block is Anthropic.ContentBlockParam => block != null,
|
|
841
|
-
)
|
|
842
|
-
.filter(
|
|
843
|
-
(block) =>
|
|
844
|
-
!(
|
|
845
|
-
block.type === "text" &&
|
|
846
|
-
!(block as { text?: string }).text?.trim()
|
|
847
|
-
),
|
|
848
|
-
);
|
|
849
|
-
|
|
850
|
-
// Preserve assistant turns that would otherwise become empty after filtering
|
|
851
|
-
// unknown block types (e.g. ui_surface). Dropping these messages can violate
|
|
852
|
-
// Anthropic's role alternation requirement.
|
|
853
|
-
if (
|
|
854
|
-
content.length === 0 &&
|
|
855
|
-
m.role === "assistant" &&
|
|
856
|
-
droppedUnknownBlock
|
|
857
|
-
) {
|
|
858
|
-
return {
|
|
859
|
-
role: m.role as "assistant",
|
|
860
|
-
content: [
|
|
861
|
-
{ type: "text" as const, text: PLACEHOLDER_BLOCKS_OMITTED },
|
|
862
|
-
],
|
|
863
|
-
};
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
return {
|
|
867
|
-
role: m.role,
|
|
868
|
-
content,
|
|
869
|
-
} as Anthropic.MessageParam;
|
|
870
|
-
})
|
|
871
|
-
.reduce<Anthropic.MessageParam[]>((acc, m) => {
|
|
872
|
-
if (m.content.length > 0) {
|
|
873
|
-
acc.push(m);
|
|
874
|
-
return acc;
|
|
875
|
-
}
|
|
876
|
-
// Dropping an empty assistant message between two user messages (or vice
|
|
877
|
-
// versa) would create consecutive same-role messages, violating
|
|
878
|
-
// Anthropic's role alternation requirement. Inject a placeholder instead.
|
|
879
|
-
const prev = acc[acc.length - 1];
|
|
880
|
-
if (m.role === "assistant" && prev && prev.role !== "assistant") {
|
|
881
|
-
acc.push({
|
|
882
|
-
role: "assistant" as const,
|
|
883
|
-
content: [
|
|
884
|
-
{ type: "text" as const, text: PLACEHOLDER_EMPTY_TURN },
|
|
885
|
-
],
|
|
886
|
-
});
|
|
887
|
-
}
|
|
888
|
-
return acc;
|
|
889
|
-
}, []);
|
|
890
|
-
|
|
891
|
-
// Post-processing: merge consecutive same-role messages that violate
|
|
892
|
-
// Anthropic's strict user/assistant alternation requirement. These can
|
|
893
|
-
// arise from:
|
|
894
|
-
// - Dropping empty messages in the reduce above (placeholder-adjacent)
|
|
895
|
-
// - History reconstruction artifacts that bypass repairHistory
|
|
896
|
-
//
|
|
897
|
-
// Walk backwards so splice indices stay valid. After a merge+splice
|
|
898
|
-
// the element that was at i+1 shifts to i, potentially creating a
|
|
899
|
-
// new adjacent pair — bump i back up to recheck that position.
|
|
900
|
-
{
|
|
901
|
-
let i = formatted.length - 1;
|
|
902
|
-
while (i > 0 && i < formatted.length) {
|
|
903
|
-
if (formatted[i].role !== formatted[i - 1].role) {
|
|
904
|
-
i--;
|
|
905
|
-
continue;
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
const iContent = (
|
|
909
|
-
Array.isArray(formatted[i].content) ? formatted[i].content : []
|
|
910
|
-
) as Anthropic.ContentBlockParam[];
|
|
911
|
-
const prevContent = (
|
|
912
|
-
Array.isArray(formatted[i - 1].content)
|
|
913
|
-
? formatted[i - 1].content
|
|
914
|
-
: []
|
|
915
|
-
) as Anthropic.ContentBlockParam[];
|
|
916
|
-
const isPlaceholder = (c: Anthropic.ContentBlockParam[]): boolean => {
|
|
917
|
-
if (
|
|
918
|
-
c.length !== 1 ||
|
|
919
|
-
typeof c[0] === "string" ||
|
|
920
|
-
c[0].type !== "text"
|
|
921
|
-
)
|
|
922
|
-
return false;
|
|
923
|
-
const text = (c[0] as { text?: string }).text;
|
|
924
|
-
return typeof text === "string" && isPlaceholderSentinelText(text);
|
|
925
|
-
};
|
|
926
|
-
|
|
927
|
-
if (isPlaceholder(iContent)) {
|
|
928
|
-
formatted.splice(i, 1);
|
|
929
|
-
// Removed the later element. The new formatted[i] (formerly
|
|
930
|
-
// i+1) may now be same-role as i-1, so decrement once to
|
|
931
|
-
// recheck from the correct position.
|
|
932
|
-
i--;
|
|
933
|
-
} else if (isPlaceholder(prevContent)) {
|
|
934
|
-
formatted.splice(i - 1, 1);
|
|
935
|
-
// Removed the earlier element — everything shifted down by 1.
|
|
936
|
-
// The element that was at i is now at i-1. Decrement so the
|
|
937
|
-
// next iteration compares the new i-1 with i-2 (or exits if
|
|
938
|
-
// i-1 is 0).
|
|
939
|
-
i--;
|
|
940
|
-
} else {
|
|
941
|
-
// Neither is a placeholder — merge content blocks into the
|
|
942
|
-
// earlier message and remove the later one. Skip the merge
|
|
943
|
-
// when either message carries tool_use or tool_result blocks;
|
|
944
|
-
// those require structural alternation for ensureToolPairing
|
|
945
|
-
// to inject the correct synthetic results downstream.
|
|
946
|
-
const hasToolBlock = (c: Anthropic.ContentBlockParam[]): boolean =>
|
|
947
|
-
c.some(
|
|
948
|
-
(b) =>
|
|
949
|
-
typeof b !== "string" &&
|
|
950
|
-
(b.type === "tool_use" || b.type === "tool_result"),
|
|
951
|
-
);
|
|
952
|
-
if (!hasToolBlock(prevContent) && !hasToolBlock(iContent)) {
|
|
953
|
-
formatted[i - 1] = {
|
|
954
|
-
...formatted[i - 1],
|
|
955
|
-
content: [...prevContent, ...iContent],
|
|
956
|
-
};
|
|
957
|
-
formatted.splice(i, 1);
|
|
958
|
-
// Clamp i to the new last index — the splice may have put
|
|
959
|
-
// us past the end. If there's a new element at i (formerly
|
|
960
|
-
// i+1), it will be rechecked against the merged i-1.
|
|
961
|
-
if (i >= formatted.length) {
|
|
962
|
-
i = formatted.length - 1;
|
|
963
|
-
}
|
|
964
|
-
} else {
|
|
965
|
-
// Can't merge (tool blocks present) — leave for
|
|
966
|
-
// ensureToolPairing which handles tool_use/tool_result
|
|
967
|
-
// alternation in its own forward walk.
|
|
968
|
-
i--;
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
// Strip thinking/redacted_thinking blocks from completed historical
|
|
975
|
-
// assistant turns. Anthropic only requires these blocks for active
|
|
976
|
-
// tool-use continuation (the tail span where assistant tool_use is
|
|
977
|
-
// followed by user tool_result). Replaying stale thinking blocks from
|
|
978
|
-
// earlier turns causes 400 errors when the signature is no longer
|
|
979
|
-
// valid (e.g. after a provider/model/profile switch).
|
|
980
|
-
const activeToolUseStart = findActiveToolUseContinuationStart(formatted);
|
|
981
|
-
for (let i = 0; i < activeToolUseStart; i++) {
|
|
982
|
-
const msg = formatted[i];
|
|
983
|
-
if (msg.role !== "assistant" || !Array.isArray(msg.content)) continue;
|
|
984
|
-
const stripped = (msg.content as Anthropic.ContentBlockParam[]).filter(
|
|
985
|
-
(b) =>
|
|
986
|
-
typeof b === "string" ||
|
|
987
|
-
(b.type !== "thinking" && b.type !== "redacted_thinking"),
|
|
988
|
-
);
|
|
989
|
-
if (stripped.length === 0) {
|
|
990
|
-
stripped.push({
|
|
991
|
-
type: "text" as const,
|
|
992
|
-
text: PLACEHOLDER_BLOCKS_OMITTED,
|
|
993
|
-
});
|
|
994
|
-
}
|
|
995
|
-
formatted[i] = { ...msg, content: stripped };
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
sentMessages = ensureToolPairing(
|
|
999
|
-
repairOrphanedServerToolBlocks(formatted),
|
|
1000
|
-
);
|
|
832
|
+
sentMessages = this.buildSentMessages(messages);
|
|
1001
833
|
const {
|
|
1002
834
|
effort,
|
|
1003
835
|
speed,
|
|
@@ -1008,6 +840,11 @@ export class AnthropicProvider implements Provider {
|
|
|
1008
840
|
disableCache: _disableCache,
|
|
1009
841
|
max_tokens: callerMaxTokens,
|
|
1010
842
|
usageAttributionHeaders,
|
|
843
|
+
// Pulled out of `restConfig` so they are forwarded conditionally below:
|
|
844
|
+
// newer models reject them outright (see `deprecatesSamplingParams`).
|
|
845
|
+
temperature: callerTemperature,
|
|
846
|
+
top_p: callerTopP,
|
|
847
|
+
top_k: callerTopK,
|
|
1011
848
|
...restConfig
|
|
1012
849
|
} = (config ?? {}) as Record<string, unknown> & {
|
|
1013
850
|
// "xhigh" is an intermediate tier between "high" and "max" supported
|
|
@@ -1020,6 +857,9 @@ export class AnthropicProvider implements Provider {
|
|
|
1020
857
|
speed?: "standard" | "fast";
|
|
1021
858
|
output_config?: Record<string, unknown>;
|
|
1022
859
|
usageAttributionHeaders?: Record<string, string>;
|
|
860
|
+
temperature?: number;
|
|
861
|
+
top_p?: number;
|
|
862
|
+
top_k?: number;
|
|
1023
863
|
};
|
|
1024
864
|
// Haiku does not support the effort / output_config parameter or
|
|
1025
865
|
// extended cache TTL betas.
|
|
@@ -1029,6 +869,16 @@ export class AnthropicProvider implements Provider {
|
|
|
1029
869
|
(restConfig as Record<string, unknown>).model?.toString() ?? this.model;
|
|
1030
870
|
const isHaiku = effectiveModel.includes("haiku");
|
|
1031
871
|
const supportsEffort = !isHaiku;
|
|
872
|
+
// opus-4-7 / opus-4-8 reject `temperature` and `top_p` with a 400
|
|
873
|
+
// "`temperature`/`top_p` is deprecated for this model" — model-wide, not
|
|
874
|
+
// effort-conditional (verified 2026-06-23). opus-4-6 / sonnet-4-6 /
|
|
875
|
+
// haiku-4-5 still accept them. fable-5 is included conservatively (a
|
|
876
|
+
// frontier model that could not be verified directly but follows the same
|
|
877
|
+
// deprecation direction). Stripping the params here keeps callers that set
|
|
878
|
+
// them (e.g. the memory-v3 L2 selector's `temperature: 0`) from 400ing.
|
|
879
|
+
const deprecatesSamplingParams =
|
|
880
|
+
/claude-opus-4-[78]\b/.test(effectiveModel) ||
|
|
881
|
+
effectiveModel.startsWith("claude-fable-");
|
|
1032
882
|
const mergedOutputConfig = {
|
|
1033
883
|
...(output_config ?? {}),
|
|
1034
884
|
...(effort && effort !== "none" && supportsEffort
|
|
@@ -1056,6 +906,19 @@ export class AnthropicProvider implements Provider {
|
|
|
1056
906
|
: 64000,
|
|
1057
907
|
messages: sentMessages,
|
|
1058
908
|
...restConfig,
|
|
909
|
+
// Forward `temperature` / `top_p` / `top_k` only to models that still
|
|
910
|
+
// accept them; newer models 400 on any of the deprecated sampler params.
|
|
911
|
+
// `temperature: 0` is preserved for accepting models (a `typeof ===
|
|
912
|
+
// "number"` check, not truthiness).
|
|
913
|
+
...(deprecatesSamplingParams
|
|
914
|
+
? {}
|
|
915
|
+
: {
|
|
916
|
+
...(typeof callerTemperature === "number"
|
|
917
|
+
? { temperature: callerTemperature }
|
|
918
|
+
: {}),
|
|
919
|
+
...(typeof callerTopP === "number" ? { top_p: callerTopP } : {}),
|
|
920
|
+
...(typeof callerTopK === "number" ? { top_k: callerTopK } : {}),
|
|
921
|
+
}),
|
|
1059
922
|
...(Object.keys(mergedOutputConfig).length > 0
|
|
1060
923
|
? { output_config: mergedOutputConfig }
|
|
1061
924
|
: {}),
|
|
@@ -1195,15 +1058,27 @@ export class AnthropicProvider implements Provider {
|
|
|
1195
1058
|
}
|
|
1196
1059
|
|
|
1197
1060
|
// Advancing tail: place a short-lived 5m cache breakpoint on the last
|
|
1198
|
-
// block of the last message
|
|
1199
|
-
//
|
|
1200
|
-
//
|
|
1201
|
-
//
|
|
1061
|
+
// block of the last message. This caches the growing tail cheaply
|
|
1062
|
+
// without conflicting with the 1h breakpoints above. It fires during
|
|
1063
|
+
// tool-use loops (the tail falls after the turn-starting user message)
|
|
1064
|
+
// and also on a first-of-turn request whose volatile turn-start anchor
|
|
1065
|
+
// was skipped while a previous-turn anchor exists: there the latest
|
|
1066
|
+
// message would otherwise carry no breakpoint, so the next request's
|
|
1067
|
+
// anchor can land far ahead of the previous-turn anchor and Anthropic's
|
|
1068
|
+
// ~20-block cache lookback can't bridge the gap — forcing a full
|
|
1069
|
+
// re-creation of the prefix. The 5m breakpoint gives the next call an
|
|
1070
|
+
// exact, reachable boundary; cross-turn it expires harmlessly. The
|
|
1071
|
+
// first-of-turn bridge lands on the turn-start block, so it honors
|
|
1072
|
+
// `disableTurnStartCache` like the long-TTL anchor above. Skip
|
|
1073
|
+
// thinking/redacted_thinking blocks — Anthropic doesn't allow
|
|
1202
1074
|
// cache_control on those types.
|
|
1203
1075
|
if (
|
|
1204
1076
|
!disableCache &&
|
|
1205
1077
|
turnStartIdx >= 0 &&
|
|
1206
|
-
turnStartIdx < sentMessages.length - 1
|
|
1078
|
+
(turnStartIdx < sentMessages.length - 1 ||
|
|
1079
|
+
(skipVolatileTurnStartAnchor &&
|
|
1080
|
+
turnStartIdx > 0 &&
|
|
1081
|
+
!disableTurnStartCache))
|
|
1207
1082
|
) {
|
|
1208
1083
|
const lastMsg = sentMessages[sentMessages.length - 1];
|
|
1209
1084
|
if (Array.isArray(lastMsg.content) && lastMsg.content.length > 0) {
|
|
@@ -1230,11 +1105,13 @@ export class AnthropicProvider implements Provider {
|
|
|
1230
1105
|
}
|
|
1231
1106
|
|
|
1232
1107
|
// Cache-breakpoint accounting: system(≤2) + tools(1, only when the
|
|
1233
|
-
// system is a single block or absent) +
|
|
1234
|
-
//
|
|
1235
|
-
//
|
|
1236
|
-
//
|
|
1237
|
-
//
|
|
1108
|
+
// system is a single block or absent) + at most two message anchors
|
|
1109
|
+
// ≤ 4 — Anthropic's per-request cap. The two message anchors are
|
|
1110
|
+
// turn-start + prev-turn-anchor (first-of-turn), turn-start + tail
|
|
1111
|
+
// (tool-use loop), or prev-turn-anchor + tail (first-of-turn with the
|
|
1112
|
+
// volatile turn-start anchor skipped — the freed turn-start slot covers
|
|
1113
|
+
// the tail). At most two message-level breakpoints are placed, so the
|
|
1114
|
+
// total can't drift past 4.
|
|
1238
1115
|
|
|
1239
1116
|
// Strip orphaned UTF-16 surrogates so the Anthropic JSON parser never
|
|
1240
1117
|
// sees invalid strings produced by upstream surrogate-splitting `.slice()` calls.
|
|
@@ -1681,6 +1558,234 @@ export class AnthropicProvider implements Provider {
|
|
|
1681
1558
|
}
|
|
1682
1559
|
}
|
|
1683
1560
|
|
|
1561
|
+
/**
|
|
1562
|
+
* Exact prompt-token count via Anthropic's `/v1/messages/count_tokens`
|
|
1563
|
+
* endpoint — the real tokenizer, no inference. Serializes `messages` /
|
|
1564
|
+
* `systemPrompt` / `tools` the same way {@link sendMessage} does (so the
|
|
1565
|
+
* count tracks what the next call would actually send), minus the
|
|
1566
|
+
* `cache_control` breakpoints, which don't affect token counts.
|
|
1567
|
+
*
|
|
1568
|
+
* The serialization here is intentionally simpler than `sendMessage`'s
|
|
1569
|
+
* (no role-alternation merge / placeholder injection): on a pathological
|
|
1570
|
+
* history `count_tokens` may reject the request, which surfaces as a thrown
|
|
1571
|
+
* error the caller turns into a local-estimator fallback. The common path —
|
|
1572
|
+
* a well-formed history — counts exactly.
|
|
1573
|
+
*/
|
|
1574
|
+
async countInputTokens(
|
|
1575
|
+
messages: Message[],
|
|
1576
|
+
systemPrompt: string,
|
|
1577
|
+
tools?: ToolDefinition[],
|
|
1578
|
+
): Promise<number> {
|
|
1579
|
+
const sentMessages = this.buildSentMessages(messages);
|
|
1580
|
+
|
|
1581
|
+
const system = systemPrompt
|
|
1582
|
+
? systemPrompt
|
|
1583
|
+
.split(SYSTEM_PROMPT_CACHE_BOUNDARY)
|
|
1584
|
+
.filter((text) => text.length > 0)
|
|
1585
|
+
.map((text) => ({ type: "text" as const, text }))
|
|
1586
|
+
: [];
|
|
1587
|
+
const toolsParam =
|
|
1588
|
+
tools && tools.length > 0
|
|
1589
|
+
? tools.map((t) => ({
|
|
1590
|
+
name: t.name,
|
|
1591
|
+
description: t.description,
|
|
1592
|
+
input_schema: t.input_schema as Anthropic.Tool["input_schema"],
|
|
1593
|
+
}))
|
|
1594
|
+
: undefined;
|
|
1595
|
+
|
|
1596
|
+
const res = await this.client.messages.countTokens({
|
|
1597
|
+
model: this.model,
|
|
1598
|
+
messages: sentMessages,
|
|
1599
|
+
...(system.length > 0 ? { system } : {}),
|
|
1600
|
+
...(toolsParam ? { tools: toolsParam } : {}),
|
|
1601
|
+
});
|
|
1602
|
+
return res.input_tokens;
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
/**
|
|
1606
|
+
* Serialize internal `Message[]` into the Anthropic `MessageParam[]` the
|
|
1607
|
+
* Messages API expects: drop unknown/empty blocks, preserve role
|
|
1608
|
+
* alternation (placeholder injection + same-role merge), strip stale
|
|
1609
|
+
* thinking blocks outside the active tool-use continuation, and repair
|
|
1610
|
+
* tool_use/tool_result pairing. Shared by {@link sendMessage} and
|
|
1611
|
+
* {@link countInputTokens} so both send the identical message payload —
|
|
1612
|
+
* `cache_control` breakpoints (which don't affect token counts) are the
|
|
1613
|
+
* only thing layered on top in `sendMessage`.
|
|
1614
|
+
*/
|
|
1615
|
+
private buildSentMessages(messages: Message[]): Anthropic.MessageParam[] {
|
|
1616
|
+
const formatted = messages
|
|
1617
|
+
.map((m) => {
|
|
1618
|
+
// Track whether an unknown block was dropped during filtering
|
|
1619
|
+
let droppedUnknownBlock = false;
|
|
1620
|
+
|
|
1621
|
+
const content = m.content
|
|
1622
|
+
.map((block) => {
|
|
1623
|
+
const result = this.toAnthropicBlockSafe(block);
|
|
1624
|
+
if (result == null) {
|
|
1625
|
+
droppedUnknownBlock = true;
|
|
1626
|
+
}
|
|
1627
|
+
return result;
|
|
1628
|
+
})
|
|
1629
|
+
.filter(
|
|
1630
|
+
(block): block is Anthropic.ContentBlockParam => block != null,
|
|
1631
|
+
)
|
|
1632
|
+
.filter(
|
|
1633
|
+
(block) =>
|
|
1634
|
+
!(
|
|
1635
|
+
block.type === "text" &&
|
|
1636
|
+
!(block as { text?: string }).text?.trim()
|
|
1637
|
+
),
|
|
1638
|
+
);
|
|
1639
|
+
|
|
1640
|
+
// Preserve assistant turns that would otherwise become empty after filtering
|
|
1641
|
+
// unknown block types (e.g. ui_surface). Dropping these messages can violate
|
|
1642
|
+
// Anthropic's role alternation requirement.
|
|
1643
|
+
if (
|
|
1644
|
+
content.length === 0 &&
|
|
1645
|
+
m.role === "assistant" &&
|
|
1646
|
+
droppedUnknownBlock
|
|
1647
|
+
) {
|
|
1648
|
+
return {
|
|
1649
|
+
role: m.role as "assistant",
|
|
1650
|
+
content: [
|
|
1651
|
+
{ type: "text" as const, text: PLACEHOLDER_BLOCKS_OMITTED },
|
|
1652
|
+
],
|
|
1653
|
+
};
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
return {
|
|
1657
|
+
role: m.role,
|
|
1658
|
+
content,
|
|
1659
|
+
} as Anthropic.MessageParam;
|
|
1660
|
+
})
|
|
1661
|
+
.reduce<Anthropic.MessageParam[]>((acc, m) => {
|
|
1662
|
+
if (m.content.length > 0) {
|
|
1663
|
+
acc.push(m);
|
|
1664
|
+
return acc;
|
|
1665
|
+
}
|
|
1666
|
+
// Dropping an empty assistant message between two user messages (or vice
|
|
1667
|
+
// versa) would create consecutive same-role messages, violating
|
|
1668
|
+
// Anthropic's role alternation requirement. Inject a placeholder instead.
|
|
1669
|
+
const prev = acc[acc.length - 1];
|
|
1670
|
+
if (m.role === "assistant" && prev && prev.role !== "assistant") {
|
|
1671
|
+
acc.push({
|
|
1672
|
+
role: "assistant" as const,
|
|
1673
|
+
content: [{ type: "text" as const, text: PLACEHOLDER_EMPTY_TURN }],
|
|
1674
|
+
});
|
|
1675
|
+
}
|
|
1676
|
+
return acc;
|
|
1677
|
+
}, []);
|
|
1678
|
+
|
|
1679
|
+
// Post-processing: merge consecutive same-role messages that violate
|
|
1680
|
+
// Anthropic's strict user/assistant alternation requirement. These can
|
|
1681
|
+
// arise from:
|
|
1682
|
+
// - Dropping empty messages in the reduce above (placeholder-adjacent)
|
|
1683
|
+
// - History reconstruction artifacts that bypass repairHistory
|
|
1684
|
+
//
|
|
1685
|
+
// Walk backwards so splice indices stay valid. After a merge+splice
|
|
1686
|
+
// the element that was at i+1 shifts to i, potentially creating a
|
|
1687
|
+
// new adjacent pair — bump i back up to recheck that position.
|
|
1688
|
+
{
|
|
1689
|
+
let i = formatted.length - 1;
|
|
1690
|
+
while (i > 0 && i < formatted.length) {
|
|
1691
|
+
if (formatted[i].role !== formatted[i - 1].role) {
|
|
1692
|
+
i--;
|
|
1693
|
+
continue;
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
const iContent = (
|
|
1697
|
+
Array.isArray(formatted[i].content) ? formatted[i].content : []
|
|
1698
|
+
) as Anthropic.ContentBlockParam[];
|
|
1699
|
+
const prevContent = (
|
|
1700
|
+
Array.isArray(formatted[i - 1].content)
|
|
1701
|
+
? formatted[i - 1].content
|
|
1702
|
+
: []
|
|
1703
|
+
) as Anthropic.ContentBlockParam[];
|
|
1704
|
+
const isPlaceholder = (c: Anthropic.ContentBlockParam[]): boolean => {
|
|
1705
|
+
if (
|
|
1706
|
+
c.length !== 1 ||
|
|
1707
|
+
typeof c[0] === "string" ||
|
|
1708
|
+
c[0].type !== "text"
|
|
1709
|
+
)
|
|
1710
|
+
return false;
|
|
1711
|
+
const text = (c[0] as { text?: string }).text;
|
|
1712
|
+
return typeof text === "string" && isPlaceholderSentinelText(text);
|
|
1713
|
+
};
|
|
1714
|
+
|
|
1715
|
+
if (isPlaceholder(iContent)) {
|
|
1716
|
+
formatted.splice(i, 1);
|
|
1717
|
+
// Removed the later element. The new formatted[i] (formerly
|
|
1718
|
+
// i+1) may now be same-role as i-1, so decrement once to
|
|
1719
|
+
// recheck from the correct position.
|
|
1720
|
+
i--;
|
|
1721
|
+
} else if (isPlaceholder(prevContent)) {
|
|
1722
|
+
formatted.splice(i - 1, 1);
|
|
1723
|
+
// Removed the earlier element — everything shifted down by 1.
|
|
1724
|
+
// The element that was at i is now at i-1. Decrement so the
|
|
1725
|
+
// next iteration compares the new i-1 with i-2 (or exits if
|
|
1726
|
+
// i-1 is 0).
|
|
1727
|
+
i--;
|
|
1728
|
+
} else {
|
|
1729
|
+
// Neither is a placeholder — merge content blocks into the
|
|
1730
|
+
// earlier message and remove the later one. Skip the merge
|
|
1731
|
+
// when either message carries tool_use or tool_result blocks;
|
|
1732
|
+
// those require structural alternation for ensureToolPairing
|
|
1733
|
+
// to inject the correct synthetic results downstream.
|
|
1734
|
+
const hasToolBlock = (c: Anthropic.ContentBlockParam[]): boolean =>
|
|
1735
|
+
c.some(
|
|
1736
|
+
(b) =>
|
|
1737
|
+
typeof b !== "string" &&
|
|
1738
|
+
(b.type === "tool_use" || b.type === "tool_result"),
|
|
1739
|
+
);
|
|
1740
|
+
if (!hasToolBlock(prevContent) && !hasToolBlock(iContent)) {
|
|
1741
|
+
formatted[i - 1] = {
|
|
1742
|
+
...formatted[i - 1],
|
|
1743
|
+
content: [...prevContent, ...iContent],
|
|
1744
|
+
};
|
|
1745
|
+
formatted.splice(i, 1);
|
|
1746
|
+
// Clamp i to the new last index — the splice may have put
|
|
1747
|
+
// us past the end. If there's a new element at i (formerly
|
|
1748
|
+
// i+1), it will be rechecked against the merged i-1.
|
|
1749
|
+
if (i >= formatted.length) {
|
|
1750
|
+
i = formatted.length - 1;
|
|
1751
|
+
}
|
|
1752
|
+
} else {
|
|
1753
|
+
// Can't merge (tool blocks present) — leave for
|
|
1754
|
+
// ensureToolPairing which handles tool_use/tool_result
|
|
1755
|
+
// alternation in its own forward walk.
|
|
1756
|
+
i--;
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
// Strip thinking/redacted_thinking blocks from completed historical
|
|
1763
|
+
// assistant turns. Anthropic only requires these blocks for active
|
|
1764
|
+
// tool-use continuation (the tail span where assistant tool_use is
|
|
1765
|
+
// followed by user tool_result). Replaying stale thinking blocks from
|
|
1766
|
+
// earlier turns causes 400 errors when the signature is no longer
|
|
1767
|
+
// valid (e.g. after a provider/model/profile switch).
|
|
1768
|
+
const activeToolUseStart = findActiveToolUseContinuationStart(formatted);
|
|
1769
|
+
for (let i = 0; i < activeToolUseStart; i++) {
|
|
1770
|
+
const msg = formatted[i];
|
|
1771
|
+
if (msg.role !== "assistant" || !Array.isArray(msg.content)) continue;
|
|
1772
|
+
const stripped = (msg.content as Anthropic.ContentBlockParam[]).filter(
|
|
1773
|
+
(b) =>
|
|
1774
|
+
typeof b === "string" ||
|
|
1775
|
+
(b.type !== "thinking" && b.type !== "redacted_thinking"),
|
|
1776
|
+
);
|
|
1777
|
+
if (stripped.length === 0) {
|
|
1778
|
+
stripped.push({
|
|
1779
|
+
type: "text" as const,
|
|
1780
|
+
text: PLACEHOLDER_BLOCKS_OMITTED,
|
|
1781
|
+
});
|
|
1782
|
+
}
|
|
1783
|
+
formatted[i] = { ...msg, content: stripped };
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1786
|
+
return ensureToolPairing(repairOrphanedServerToolBlocks(formatted));
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1684
1789
|
/**
|
|
1685
1790
|
* Convert a content block to Anthropic format, returning null for unknown
|
|
1686
1791
|
* block types instead of throwing. Unknown types (e.g. ui_surface stored
|
|
@@ -43,6 +43,9 @@ import type {
|
|
|
43
43
|
|
|
44
44
|
export class CallSiteRoutingProvider implements Provider {
|
|
45
45
|
public readonly tokenEstimationProvider?: string;
|
|
46
|
+
// Forward native web-search capability so it survives the wrapper chain
|
|
47
|
+
// (callers like the advisor consult gate on it). Fixed at construction.
|
|
48
|
+
public readonly supportsNativeWebSearch?: boolean;
|
|
46
49
|
|
|
47
50
|
// Per-call async context that tracks which provider is currently executing.
|
|
48
51
|
// Using AsyncLocalStorage instead of a plain instance field means concurrent
|
|
@@ -60,6 +63,12 @@ export class CallSiteRoutingProvider implements Provider {
|
|
|
60
63
|
return this._activeProviderContext.getStore() ?? this.defaultProvider.name;
|
|
61
64
|
}
|
|
62
65
|
|
|
66
|
+
// Forward the optional token-counting endpoint from the default provider —
|
|
67
|
+
// the same one whose `tokenEstimationProvider` this wrapper surfaces, and
|
|
68
|
+
// the provider that handles the main agent turn that `/compact` sizes
|
|
69
|
+
// against. Per-call connection routing only affects `sendMessage`.
|
|
70
|
+
public readonly countInputTokens?: NonNullable<Provider["countInputTokens"]>;
|
|
71
|
+
|
|
63
72
|
constructor(
|
|
64
73
|
private readonly defaultProvider: Provider,
|
|
65
74
|
/**
|
|
@@ -88,6 +97,11 @@ export class CallSiteRoutingProvider implements Provider {
|
|
|
88
97
|
) => Promise<Provider | null>,
|
|
89
98
|
) {
|
|
90
99
|
this.tokenEstimationProvider = defaultProvider.tokenEstimationProvider;
|
|
100
|
+
this.supportsNativeWebSearch = defaultProvider.supportsNativeWebSearch;
|
|
101
|
+
if (defaultProvider.countInputTokens) {
|
|
102
|
+
this.countInputTokens =
|
|
103
|
+
defaultProvider.countInputTokens.bind(defaultProvider);
|
|
104
|
+
}
|
|
91
105
|
}
|
|
92
106
|
|
|
93
107
|
async sendMessage(
|
|
@@ -17,6 +17,7 @@ import type {
|
|
|
17
17
|
Provider,
|
|
18
18
|
ProviderResponse,
|
|
19
19
|
SendMessageOptions,
|
|
20
|
+
ToolDefinition,
|
|
20
21
|
} from "../types.js";
|
|
21
22
|
import {
|
|
22
23
|
ContextOverflowError,
|
|
@@ -518,6 +519,48 @@ export class GeminiProvider implements Provider {
|
|
|
518
519
|
}
|
|
519
520
|
}
|
|
520
521
|
|
|
522
|
+
/**
|
|
523
|
+
* Exact prompt-token count via Gemini's `models.countTokens` — the real
|
|
524
|
+
* tokenizer, no generation. Mirrors {@link sendMessage}'s composition
|
|
525
|
+
* (contents + `systemInstruction` + tool function declarations) so the count
|
|
526
|
+
* tracks what a real call would send. Throws when the endpoint returns no
|
|
527
|
+
* `totalTokens`, so the caller falls back to the local estimate.
|
|
528
|
+
*/
|
|
529
|
+
async countInputTokens(
|
|
530
|
+
messages: Message[],
|
|
531
|
+
systemPrompt: string,
|
|
532
|
+
tools?: ToolDefinition[],
|
|
533
|
+
): Promise<number> {
|
|
534
|
+
const contents = this.toGeminiContents(messages, this.model);
|
|
535
|
+
const config: genai.CountTokensConfig = {};
|
|
536
|
+
if (systemPrompt) {
|
|
537
|
+
config.systemInstruction = systemPrompt.replaceAll(
|
|
538
|
+
SYSTEM_PROMPT_CACHE_BOUNDARY,
|
|
539
|
+
"\n\n",
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
if (tools && tools.length > 0) {
|
|
543
|
+
config.tools = [
|
|
544
|
+
{
|
|
545
|
+
functionDeclarations: tools.map((t) => ({
|
|
546
|
+
name: t.name,
|
|
547
|
+
description: t.description,
|
|
548
|
+
parametersJsonSchema: t.input_schema,
|
|
549
|
+
})),
|
|
550
|
+
},
|
|
551
|
+
];
|
|
552
|
+
}
|
|
553
|
+
const res = await this.client.models.countTokens({
|
|
554
|
+
model: this.model,
|
|
555
|
+
contents,
|
|
556
|
+
...(Object.keys(config).length > 0 ? { config } : {}),
|
|
557
|
+
});
|
|
558
|
+
if (typeof res.totalTokens !== "number") {
|
|
559
|
+
throw new Error("Gemini countTokens returned no totalTokens");
|
|
560
|
+
}
|
|
561
|
+
return res.totalTokens;
|
|
562
|
+
}
|
|
563
|
+
|
|
521
564
|
/** Convert neutral messages to Gemini Content[] format. */
|
|
522
565
|
private toGeminiContents(
|
|
523
566
|
messages: Message[],
|
|
@@ -29,6 +29,7 @@ import { OpenAIChatCompletionsProvider } from "../openai/chat-completions-provid
|
|
|
29
29
|
import { OpenAIResponsesProvider } from "../openai/responses-provider.js";
|
|
30
30
|
import { OpenRouterProvider } from "../openrouter/client.js";
|
|
31
31
|
import { RetryProvider } from "../retry.js";
|
|
32
|
+
import { TogetherProvider } from "../together/client.js";
|
|
32
33
|
import type { Provider } from "../types.js";
|
|
33
34
|
import { UsageTrackingProvider } from "../usage-tracking.js";
|
|
34
35
|
import type { ResolvedAuth } from "./auth.js";
|
|
@@ -117,6 +118,11 @@ const ADAPTER_FACTORIES: Record<string, AdapterFactory> = {
|
|
|
117
118
|
new MinimaxProvider(apiKey, model, { streamTimeoutMs }),
|
|
118
119
|
atlascloud: ({ apiKey, model, streamTimeoutMs }) =>
|
|
119
120
|
new AtlasCloudProvider(apiKey, model, { streamTimeoutMs }),
|
|
121
|
+
together: ({ apiKey, model, streamTimeoutMs, baseURL }) =>
|
|
122
|
+
new TogetherProvider(apiKey, model, {
|
|
123
|
+
streamTimeoutMs,
|
|
124
|
+
...(baseURL ? { baseURL } : {}),
|
|
125
|
+
}),
|
|
120
126
|
};
|
|
121
127
|
|
|
122
128
|
/**
|
|
@@ -346,6 +346,12 @@ const CANONICAL_CONNECTIONS: Array<{
|
|
|
346
346
|
auth: { type: "platform" },
|
|
347
347
|
label: "Fireworks",
|
|
348
348
|
},
|
|
349
|
+
{
|
|
350
|
+
name: "together-managed",
|
|
351
|
+
provider: "together",
|
|
352
|
+
auth: { type: "platform" },
|
|
353
|
+
label: "Together AI",
|
|
354
|
+
},
|
|
349
355
|
];
|
|
350
356
|
|
|
351
357
|
/**
|
|
@@ -415,4 +421,3 @@ export function seedCanonicalConnections(db: DrizzleDb): void {
|
|
|
415
421
|
.run();
|
|
416
422
|
}
|
|
417
423
|
}
|
|
418
|
-
|