@vellumai/assistant 0.9.0 → 0.10.0-dev.202606192226.8ed8a6a
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 +19 -35
- package/bun.lock +7 -8
- package/docs/activation-funnel-telemetry.md +28 -22
- package/docs/architecture/security.md +29 -28
- package/docs/stt-provider-onboarding.md +3 -5
- package/docs/workflows-testing.md +13 -44
- package/docs/workflows.md +3 -5
- package/node_modules/@vellumai/ces-client/src/__tests__/ces-client.test.ts +47 -0
- package/node_modules/@vellumai/ces-client/src/rpc-client.ts +28 -5
- package/node_modules/@vellumai/environments/src/seeds.ts +2 -5
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +97 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +10 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +32 -6
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +119 -0
- package/node_modules/@vellumai/gateway-client/src/types.ts +15 -84
- package/openapi.yaml +1128 -119
- package/package.json +2 -1
- package/scripts/sync-llm-catalog.ts +6 -15
- package/scripts/sync-web-search-catalog.ts +3 -11
- package/src/__tests__/access-request-card-view.test.ts +98 -0
- package/src/__tests__/access-request-seed-content-blocks.test.ts +2 -4
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +72 -32
- package/src/__tests__/agent-loop-compaction-strip.test.ts +241 -0
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +16 -13
- package/src/__tests__/agent-loop-output-hooks.test.ts +69 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +25 -0
- package/src/__tests__/agent-loop-pushes-post-hook-prompt.test.ts +306 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -3
- package/src/__tests__/app-compiler.test.ts +15 -1
- package/src/__tests__/app-dir-path-guard.test.ts +0 -1
- package/src/__tests__/approval-cascade.test.ts +6 -0
- package/src/__tests__/approval-routes-http.test.ts +128 -0
- package/src/__tests__/assistant-feature-flag-guard.test.ts +1 -4
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +0 -2
- package/src/__tests__/auth-fallback-events-store.test.ts +6 -14
- package/src/__tests__/avatar-identity-sync.test.ts +2 -27
- package/src/__tests__/btw-routes.test.ts +6 -8
- package/src/__tests__/call-pointer-messages.test.ts +28 -0
- package/src/__tests__/cancel-clears-processing.test.ts +89 -0
- package/src/__tests__/channel-approval-routes.test.ts +0 -4
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +5 -15
- package/src/__tests__/checker.test.ts +0 -3
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +3 -4
- package/src/__tests__/compaction-events.test.ts +6 -0
- package/src/__tests__/compactor-image-manifest-trust.test.ts +21 -1
- package/src/__tests__/compactor-summary-call-truncation.test.ts +223 -0
- package/src/__tests__/config-loader-backfill.test.ts +268 -27
- package/src/__tests__/config-schema.test.ts +35 -0
- package/src/__tests__/config-watcher.test.ts +0 -18
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -2
- package/src/__tests__/contact-store-user-file.test.ts +0 -6
- package/src/__tests__/contacts-tools.test.ts +29 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +22 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop.test.ts +58 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
- package/src/__tests__/conversation-confirmation-signals.test.ts +6 -0
- package/src/__tests__/conversation-lifecycle.test.ts +7 -9
- package/src/__tests__/conversation-load-history-repair.test.ts +101 -0
- package/src/__tests__/conversation-process-callsite.test.ts +6 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/conversation-queue.test.ts +6 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +15 -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-surfaces-activation-emit.test.ts +6 -3
- package/src/__tests__/conversation-title-service.test.ts +62 -0
- 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__/credential-broker.test.ts +449 -1
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +18 -11
- package/src/__tests__/credential-execution-tools.test.ts +0 -1
- package/src/__tests__/credential-prompt-route.test.ts +4 -4
- package/src/__tests__/credential-routes.test.ts +360 -0
- package/src/__tests__/credential-security-invariants.test.ts +4 -13
- package/src/__tests__/disk-pressure-policy.test.ts +12 -0
- package/src/__tests__/disk-pressure-tools.test.ts +41 -1
- package/src/__tests__/disk-usage.test.ts +65 -0
- package/src/__tests__/document-tool-security.test.ts +9 -6
- package/src/__tests__/document-update-default-surface.test.ts +202 -0
- package/src/__tests__/dynamic-page-surface.test.ts +152 -1
- package/src/__tests__/fixtures/credential-security-fixtures.ts +2 -33
- package/src/__tests__/gateway-flag-listener.test.ts +110 -1
- package/src/__tests__/gateway-only-guard.test.ts +3 -7
- package/src/__tests__/gemini-count-tokens.test.ts +70 -0
- package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
- package/src/__tests__/guardian-card-withdrawal.test.ts +403 -0
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +5 -3
- package/src/__tests__/guardian-grant-minting.test.ts +3 -35
- package/src/__tests__/guardian-routing-invariants.test.ts +64 -26
- package/src/__tests__/guardian-routing-state.test.ts +0 -1
- package/src/__tests__/headless-browser-mode.test.ts +10 -0
- package/src/__tests__/headless-browser-navigate.test.ts +8 -3
- package/src/__tests__/helpers/create-guardian-binding.ts +0 -1
- package/src/__tests__/host-browser-proxy.test.ts +87 -0
- package/src/__tests__/identity-routes.test.ts +0 -189
- package/src/__tests__/inbound-invite-redemption.test.ts +4 -4
- package/src/__tests__/injector-disk-pressure.test.ts +10 -5
- package/src/__tests__/injector-v3-suppression.test.ts +27 -20
- package/src/__tests__/internal-telemetry-routes.test.ts +6 -14
- package/src/__tests__/invite-redemption-service.test.ts +4 -7
- package/src/__tests__/llm-callsite-catalog.test.ts +5 -6
- package/src/__tests__/llm-catalog-parity.test.ts +30 -23
- package/src/__tests__/llm-resolver.test.ts +70 -24
- package/src/__tests__/llm-schema.test.ts +1 -0
- package/src/__tests__/managed-profile-guard.test.ts +163 -4
- package/src/__tests__/mcp-health-check.test.ts +6 -7
- package/src/__tests__/media-stream-server-integration.test.ts +317 -13
- package/src/__tests__/oauth-provider-seed-logos.test.ts +4 -6
- package/src/__tests__/onboarding-persona-write.test.ts +1 -1
- package/src/__tests__/path-policy.test.ts +34 -0
- package/src/__tests__/persona-resolver.test.ts +49 -14
- package/src/__tests__/plugin-api-model-profiles.test.ts +178 -0
- package/src/__tests__/plugin-api-provider.test.ts +24 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +6 -3
- package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +214 -0
- package/src/__tests__/provider-send-message-override-profile.test.ts +76 -0
- package/src/__tests__/reaction-persistence.test.ts +150 -29
- package/src/__tests__/registry.test.ts +2 -7
- package/src/__tests__/relay-server.test.ts +285 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
- package/src/__tests__/schedule-routes-workflow-validation.test.ts +1 -10
- package/src/__tests__/schedule-routes.test.ts +0 -30
- package/src/__tests__/schedule-tools.test.ts +2 -18
- package/src/__tests__/scheduler-reuse-conversation.test.ts +8 -5
- package/src/__tests__/secret-response-routing.test.ts +35 -0
- package/src/__tests__/secret-routes-platform-proxy.test.ts +16 -2
- package/src/__tests__/skill-execute-input.test.ts +177 -1
- package/src/__tests__/skill-load-tool.test.ts +72 -0
- package/src/__tests__/skill-runtime-path.test.ts +2 -3
- package/src/__tests__/skills.test.ts +51 -0
- package/src/__tests__/slack-notification-approval-card.test.ts +176 -0
- package/src/__tests__/slack-reaction-canonical-approval.test.ts +285 -0
- package/src/__tests__/subagent-tools.test.ts +266 -0
- package/src/__tests__/surface-completion-nudge-hook.test.ts +367 -0
- package/src/__tests__/system-storage-cleanup-skill.test.ts +56 -0
- package/src/__tests__/task-progress-nudge-hook.test.ts +1 -1
- package/src/__tests__/title-generate-hook.test.ts +100 -3
- package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +1 -29
- package/src/__tests__/token-manager.test.ts +519 -0
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +1 -1
- package/src/__tests__/tool-audit-listener.test.ts +7 -7
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +6 -3
- package/src/__tests__/tool-executor.test.ts +0 -79
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +4 -2
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +220 -3
- package/src/__tests__/trusted-contact-multichannel.test.ts +3 -3
- package/src/__tests__/trusted-contact-verification.test.ts +8 -10
- package/src/__tests__/twilio-routes.test.ts +81 -1
- package/src/__tests__/voice-invite-redemption.test.ts +2 -3
- package/src/__tests__/weak-open-model.test.ts +30 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +6 -25
- package/src/__tests__/workspace-greetings.test.ts +152 -0
- package/src/__tests__/workspace-migration-105-enable-memory-v3-live-for-new-workspaces.test.ts +149 -0
- package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +285 -0
- package/src/__tests__/workspace-migration-add-send-diagnostics.test.ts +1 -1
- package/src/__tests__/workspace-migration-drop-collect-usage-data.test.ts +118 -0
- package/src/__tests__/workspace-migration-drop-send-diagnostics.test.ts +118 -0
- package/src/a2a/__tests__/e2e-a2a-channel.test.ts +0 -4
- package/src/agent/loop.ts +75 -29
- package/src/api/README.md +6 -6
- package/src/api/events/tool-result.ts +6 -0
- package/src/api/events/workflow-completed.ts +53 -0
- package/src/api/events/workflow-leaf-finished.ts +38 -0
- package/src/api/events/workflow-leaf-started.ts +35 -0
- package/src/api/events/workflow-progress.ts +32 -0
- package/src/api/events/workflow-started.ts +31 -0
- package/src/api/index.ts +40 -0
- package/src/api/responses/conversation-message.ts +28 -4
- package/src/api/responses/home.ts +26 -4
- package/src/api/responses/workflow-journal.ts +53 -0
- package/src/approvals/guardian-card-withdrawal.ts +145 -0
- package/src/approvals/guardian-decision-primitive.ts +26 -3
- package/src/approvals/guardian-request-resolvers.ts +183 -80
- package/src/calls/__tests__/channel-admission-reader.test.ts +132 -0
- package/src/calls/__tests__/relay-setup-router.test.ts +350 -0
- package/src/calls/call-pointer-messages.ts +10 -4
- package/src/calls/channel-admission-reader.ts +104 -0
- package/src/calls/guardian-dispatch.ts +17 -45
- package/src/calls/media-stream-server.ts +84 -2
- package/src/calls/relay-access-wait.ts +1 -1
- package/src/calls/relay-server.ts +66 -0
- package/src/calls/relay-setup-router.ts +82 -1
- package/src/calls/twilio-routes.ts +17 -8
- package/src/calls/voice-session-bridge.ts +2 -2
- package/src/cli/commands/clients.ts +3 -0
- package/src/cli/commands/db/status.ts +37 -3
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2-compare-render.test.ts +1 -1
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2.test.ts +8 -7
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v3.test.ts +5 -4
- package/src/cli/commands/memory/index.ts +30 -0
- package/src/cli/commands/{memory-v2-compare-render.ts → memory/memory-v2-compare-render.ts} +1 -1
- package/src/cli/commands/{memory-v2.ts → memory/memory-v2.ts} +6 -15
- package/src/cli/commands/{memory-v3.ts → memory/memory-v3.ts} +97 -11
- package/src/cli/commands/oauth/status.test.ts +36 -0
- package/src/cli/commands/oauth/status.ts +23 -3
- package/src/cli/commands/plugins.ts +400 -14
- package/src/cli/lib/__tests__/diff-plugin.test.ts +443 -0
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +31 -0
- package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +443 -0
- package/src/cli/lib/__tests__/plugin-pin-history.test.ts +162 -0
- package/src/cli/lib/__tests__/plugin-surfaces.test.ts +111 -0
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +295 -2
- package/src/cli/lib/diff-plugin.ts +346 -0
- package/src/cli/lib/inspect-plugin.ts +12 -1
- package/src/cli/lib/install-from-github.ts +128 -19
- package/src/cli/lib/merge-plugin-tree.ts +328 -0
- package/src/cli/lib/plugin-fingerprint.ts +14 -0
- package/src/cli/lib/plugin-marketplace.ts +11 -0
- package/src/cli/lib/plugin-pin-history.ts +257 -0
- package/src/cli/lib/plugin-surfaces.ts +104 -0
- package/src/cli/lib/upgrade-plugin.ts +298 -10
- package/src/cli/program.ts +2 -6
- package/src/config/__tests__/sync-gated-profiles.test.ts +368 -0
- package/src/config/assistant-feature-flags.ts +22 -7
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +0 -1
- package/src/config/bundled-skills/document-editor/SKILL.md +3 -3
- package/src/config/bundled-skills/document-editor/TOOLS.json +2 -2
- package/src/config/bundled-skills/messaging/SKILL.md +6 -4
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +9 -8
- package/src/config/bundled-skills/subagent/SKILL.md +4 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +4 -0
- package/src/config/bundled-skills/system-storage-cleanup/SKILL.md +74 -0
- package/src/config/bundled-skills/workflows/SKILL.md +14 -8
- package/src/config/bundled-tool-registry.ts +2 -7
- package/src/config/call-site-defaults.ts +15 -2
- package/src/config/feature-flag-registry.json +46 -31
- package/src/config/inference-profile-validation.ts +26 -0
- package/src/config/llm-resolver.ts +3 -0
- package/src/config/loader.ts +4 -0
- package/src/config/memory-v3-gate.ts +11 -0
- package/src/config/profile-order.ts +28 -0
- package/src/config/schema.ts +8 -6
- 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/channels.ts +11 -0
- package/src/config/schemas/elevenlabs.ts +0 -1
- package/src/config/schemas/llm.ts +31 -0
- package/src/config/schemas/memory-lifecycle.ts +3 -7
- package/src/config/schemas/memory-v3.ts +6 -0
- package/src/config/schemas/platform.ts +0 -8
- package/src/config/schemas/services.ts +18 -0
- package/src/config/seed-inference-profiles.ts +109 -44
- package/src/config/skills.ts +21 -0
- package/src/config/sync-gated-profiles.ts +220 -0
- package/src/contacts/contact-store.ts +89 -106
- package/src/contacts/contacts-write.ts +5 -22
- package/src/contacts/types.ts +0 -1
- package/src/context/compactor.ts +88 -54
- package/src/context/strip-injections.ts +58 -10
- package/src/context/token-estimator.ts +1 -1
- package/src/credential-execution/process-manager.ts +55 -14
- package/src/credential-execution/prompted-credential.ts +2 -3
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -2
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +44 -0
- package/src/daemon/config-watcher.ts +0 -4
- package/src/daemon/conversation-agent-loop-handlers.ts +2 -0
- package/src/daemon/conversation-agent-loop.ts +114 -22
- package/src/daemon/conversation-history.ts +1 -1
- package/src/daemon/conversation-lifecycle.ts +3 -5
- package/src/daemon/conversation-process.ts +13 -5
- package/src/daemon/conversation-runtime-assembly.ts +13 -15
- package/src/daemon/conversation-slash.ts +2 -23
- package/src/daemon/conversation-surfaces.ts +26 -0
- package/src/daemon/conversation-tool-setup.ts +53 -19
- package/src/daemon/conversation.ts +131 -20
- package/src/daemon/disk-pressure-policy.ts +5 -3
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +0 -1
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -1
- package/src/daemon/handlers/config-a2a.ts +0 -2
- package/src/daemon/handlers/config-channels.ts +15 -16
- package/src/daemon/handlers/config-slack-channel.ts +22 -3
- package/src/daemon/handlers/conversations.ts +107 -0
- package/src/daemon/host-browser-proxy.ts +41 -0
- package/src/daemon/lifecycle.ts +55 -27
- package/src/daemon/memory-v2-startup.test.ts +131 -0
- package/src/daemon/memory-v2-startup.ts +100 -1
- package/src/daemon/message-provenance.ts +2 -0
- package/src/daemon/message-types/contacts.ts +0 -1
- package/src/daemon/message-types/conversations.ts +3 -3
- package/src/daemon/message-types/sync.ts +0 -1
- package/src/daemon/message-types/web-activity.ts +7 -1
- package/src/daemon/message-types/workflows.ts +83 -1
- package/src/daemon/orphan-reaper.test.ts +0 -19
- package/src/daemon/orphan-reaper.ts +2 -24
- package/src/daemon/server.ts +0 -10
- package/src/daemon/tool-setup-types.ts +4 -0
- package/src/daemon/trust-context.ts +1 -1
- package/src/daemon/wake-conversation-ops.ts +1 -0
- package/src/events/tool-audit-listener.ts +2 -2
- package/src/home/feed-source-enrichment.test.ts +151 -0
- package/src/home/feed-source-enrichment.ts +176 -0
- package/src/home/relationship-state.ts +2 -4
- package/src/instrument.ts +18 -6
- package/src/ipc/__tests__/binary-result-ipc.test.ts +81 -0
- package/src/ipc/__tests__/clients-list-ipc.test.ts +20 -0
- package/src/ipc/assistant-server.ts +37 -4
- package/src/ipc/gateway-flag-listener.ts +18 -2
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +5 -16
- package/src/memory/__tests__/db-logs-attach.test.ts +122 -0
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +7 -11
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +37 -7
- package/src/memory/__tests__/memory-retrospective-job.test.ts +229 -401
- package/src/memory/__tests__/onboarding-events-store.test.ts +7 -7
- package/src/memory/auth-fallback-events-store.ts +2 -2
- package/src/memory/auto-analysis-enqueue.ts +3 -5
- package/src/memory/bookmark-crud.ts +1 -2
- package/src/memory/canonical-guardian-store.ts +39 -1
- package/src/memory/conversation-crud.ts +9 -4
- package/src/memory/conversation-key-store.ts +17 -2
- package/src/memory/conversation-title-service.ts +64 -7
- package/src/memory/db-async-query.ts +20 -2
- package/src/memory/db-connection.ts +49 -5
- package/src/memory/db-init.ts +17 -17
- package/src/memory/embedding-backend.ts +38 -1
- package/src/memory/embedding-billing-breaker.ts +96 -0
- package/src/memory/jobs-store.ts +25 -13
- package/src/memory/jobs-worker.ts +54 -1
- package/src/memory/lifecycle-events-store.ts +2 -2
- package/src/memory/memory-retrospective-constants.ts +4 -4
- package/src/memory/memory-retrospective-enqueue.ts +31 -6
- package/src/memory/memory-retrospective-job.ts +28 -227
- package/src/memory/migrations/129-contact-channels-access-fields.ts +18 -9
- package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +14 -2
- package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +10 -0
- package/src/memory/migrations/291-contact-channels-renormalize-addresses.ts +72 -0
- package/src/memory/migrations/292-schedule-default-no-reuse-conversation.test.ts +67 -0
- package/src/memory/migrations/292-schedule-default-no-reuse-conversation.ts +25 -0
- package/src/memory/migrations/293-workflow-journal-leaf-tokens.ts +32 -0
- package/src/memory/migrations/294-drop-external-user-id.ts +31 -0
- package/src/memory/migrations/295-drop-approval-prompt-ts-tracker.ts +20 -0
- package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +110 -0
- package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.ts +68 -0
- package/src/memory/migrations/__tests__/131-drop-legacy-member-guardian-tables.test.ts +154 -0
- package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +31 -0
- package/src/memory/migrations/__tests__/291-contact-channels-renormalize-addresses.test.ts +341 -0
- package/src/memory/migrations/__tests__/run-migrations.test.ts +52 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/run-migrations.ts +41 -0
- package/src/memory/migrations/validate-migration-state.ts +1 -1
- package/src/memory/onboarding-events-store.ts +3 -3
- package/src/memory/schema/contacts.ts +0 -5
- package/src/memory/skill-loaded-events-store.test.ts +7 -15
- package/src/memory/skill-loaded-events-store.ts +2 -2
- package/src/memory/tool-executed-events-store.test.ts +7 -7
- package/src/memory/turn-trace-store.test.ts +736 -0
- package/src/memory/turn-trace-store.ts +364 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +8 -0
- package/src/memory/v2/__tests__/skill-content.test.ts +30 -0
- package/src/memory/v2/consolidation-job.ts +2 -2
- package/src/memory/v2/skill-content.ts +25 -7
- package/src/memory/v2/skill-store.ts +7 -1
- package/src/memory/v3-eval/__tests__/eval-packets.test.ts +248 -0
- package/src/memory/v3-eval/eval-packets.ts +546 -0
- package/src/messaging/providers/slack/adapter.ts +1 -1
- package/src/messaging/providers/slack/api.ts +31 -0
- package/src/messaging/providers/slack/send.test.ts +114 -2
- package/src/messaging/providers/slack/send.ts +30 -7
- package/src/messaging/providers/slack/withdraw.test.ts +200 -0
- package/src/messaging/providers/slack/withdraw.ts +161 -0
- package/src/notifications/AGENTS.md +2 -0
- package/src/notifications/access-request-copy.ts +72 -59
- package/src/notifications/adapters/shared.ts +29 -0
- package/src/notifications/adapters/slack.ts +58 -103
- package/src/notifications/adapters/telegram.ts +2 -20
- package/src/notifications/approval-card-data.ts +333 -0
- package/src/notifications/broadcaster.ts +16 -3
- package/src/notifications/canonical-delivery-recorder.ts +139 -0
- package/src/notifications/copy-composer.ts +3 -3
- package/src/notifications/decision-engine.ts +4 -2
- package/src/notifications/destination-resolver.ts +4 -6
- package/src/notifications/guardian-question-mode.ts +10 -0
- package/src/notifications/home-feed-side-effect.ts +7 -16
- package/src/notifications/notification-utils.ts +19 -20
- package/src/notifications/signal.ts +79 -43
- package/src/notifications/types.ts +98 -121
- package/src/oauth/AGENTS.md +5 -24
- package/src/permissions/checker.test.ts +51 -0
- package/src/permissions/checker.ts +185 -26
- package/src/permissions/ipc-risk-types.ts +24 -0
- package/src/permissions/question-prompter.test.ts +27 -0
- package/src/permissions/question-prompter.ts +4 -0
- package/src/permissions/secret-prompter.ts +15 -1
- package/src/platform/client.test.ts +119 -0
- package/src/platform/client.ts +66 -0
- package/src/platform/consent-cache.test.ts +267 -0
- package/src/platform/consent-cache.ts +174 -0
- package/src/plugin-api/constants.ts +1 -1
- package/src/plugin-api/index.ts +33 -1
- package/src/plugin-api/model-profiles.ts +33 -0
- package/src/plugin-api/types.ts +50 -2
- package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +56 -0
- package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +43 -0
- package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +137 -0
- package/src/plugins/defaults/advisor/__tests__/consult.test.ts +153 -0
- package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +138 -0
- package/src/plugins/defaults/advisor/__tests__/transcript.test.ts +147 -0
- package/src/plugins/defaults/advisor/advisor-gate.ts +29 -0
- package/src/plugins/defaults/advisor/advisor-state-store.ts +94 -0
- package/src/plugins/defaults/advisor/config.ts +21 -0
- package/src/plugins/defaults/advisor/consult.ts +93 -0
- package/src/plugins/defaults/advisor/hooks/post-model-call.ts +34 -0
- package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +30 -0
- package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +19 -0
- package/src/plugins/defaults/advisor/package.json +14 -0
- package/src/plugins/defaults/advisor/steering.ts +67 -0
- package/src/plugins/defaults/advisor/tools/advisor.ts +65 -0
- package/src/plugins/defaults/advisor/transcript.ts +76 -0
- package/src/plugins/defaults/compaction/window-manager.ts +18 -0
- package/src/plugins/defaults/index.ts +60 -0
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +22 -9
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +2 -2
- package/src/plugins/defaults/memory-retrieval/injectors.ts +4 -4
- package/src/plugins/defaults/memory-retrieval/tail-reinjection-strip.ts +64 -0
- package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +29 -21
- package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +129 -9
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +31 -4
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +77 -2
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +7 -10
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +144 -11
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +32 -20
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +56 -3
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +23 -2
- package/src/plugins/defaults/surface-completion-nudge/hooks/post-model-call.ts +276 -0
- package/src/plugins/defaults/surface-completion-nudge/hooks/stop.ts +22 -0
- package/src/plugins/defaults/surface-completion-nudge/nudge-state-store.ts +46 -0
- package/src/plugins/defaults/surface-completion-nudge/package.json +14 -0
- package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +3 -13
- package/src/plugins/defaults/title-generate/hooks/stop.ts +56 -21
- package/src/prompts/persona-resolver.ts +14 -4
- package/src/prompts/templates/system-sections.ts +7 -2
- package/src/providers/__tests__/count-tokens-forwarding.test.ts +98 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +1 -0
- package/src/providers/__tests__/retry-callsite.test.ts +176 -0
- package/src/providers/anthropic/client.ts +230 -175
- package/src/providers/atlascloud/client.ts +85 -0
- package/src/providers/call-site-routing.ts +10 -0
- package/src/providers/fetch-provider-catalog.ts +85 -0
- package/src/providers/gemini/client.ts +43 -0
- package/src/providers/inference/adapter-factory.ts +3 -0
- package/src/providers/model-catalog.ts +58 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +33 -0
- package/src/providers/openai/chat-completions-provider.ts +7 -0
- package/src/providers/openai/responses-provider.ts +10 -0
- package/src/providers/provider-send-message.ts +11 -3
- package/src/providers/ratelimit.ts +9 -0
- package/src/providers/retry.ts +62 -12
- package/src/providers/search-provider-catalog.ts +10 -0
- package/src/providers/types.ts +16 -0
- package/src/providers/usage-tracking.ts +7 -0
- package/src/providers/weak-open-model.ts +22 -0
- package/src/runtime/AGENTS.md +0 -1
- package/src/runtime/__tests__/agent-wake.test.ts +227 -0
- package/src/runtime/__tests__/client-health.test.ts +44 -0
- package/src/runtime/access-request-helper.ts +21 -53
- package/src/runtime/actor-trust-resolver.ts +59 -63
- package/src/runtime/agent-wake.ts +71 -0
- package/src/runtime/assistant-event-hub.ts +18 -4
- package/src/runtime/auth/__tests__/route-policy.test.ts +12 -0
- package/src/runtime/auth/require-bound-guardian.ts +1 -4
- package/src/runtime/btw-sidechain.ts +3 -6
- package/src/runtime/capabilities.test.ts +120 -0
- package/src/runtime/capabilities.ts +197 -0
- package/src/runtime/channel-approval-types.ts +22 -45
- package/src/runtime/channel-invite-transports/telegram.ts +4 -4
- package/src/runtime/channel-retry-sweep.ts +1 -0
- package/src/runtime/channel-verification-service.ts +3 -3
- package/src/runtime/client-health.ts +26 -0
- package/src/runtime/confirmation-request-guardian-bridge.ts +38 -29
- package/src/runtime/effective-capabilities.test.ts +128 -0
- package/src/runtime/effective-capabilities.ts +84 -0
- package/src/runtime/guardian-reply-router.ts +106 -21
- package/src/runtime/invite-redemption-service.ts +9 -25
- package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +126 -0
- package/src/runtime/migrations/vbundle-builder.ts +49 -20
- package/src/runtime/pending-interactions.ts +35 -0
- package/src/runtime/routes/__tests__/client-routes.test.ts +13 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +67 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +383 -1
- package/src/runtime/routes/app-routes.ts +1 -1
- package/src/runtime/routes/approval-routes.ts +40 -9
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +2 -2
- package/src/runtime/routes/assets/vellum-design-system.css +1959 -0
- package/src/runtime/routes/browser-tabs-routes.ts +9 -0
- package/src/runtime/routes/btw-routes.ts +1 -27
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +17 -8
- package/src/runtime/routes/client-routes.ts +10 -0
- package/src/runtime/routes/contact-routes.ts +31 -8
- package/src/runtime/routes/conversation-compaction-routes.ts +1 -1
- package/src/runtime/routes/conversation-management-routes.ts +80 -1
- package/src/runtime/routes/conversation-query-routes.ts +68 -22
- package/src/runtime/routes/conversation-routes.ts +39 -14
- package/src/runtime/routes/credential-routes.ts +40 -16
- package/src/runtime/routes/empty-state-greeting-cache.ts +1 -2
- package/src/runtime/routes/events-routes.ts +1 -3
- package/src/runtime/routes/guardian-approval-interception.ts +14 -73
- package/src/runtime/routes/guardian-approval-prompt.ts +22 -4
- package/src/runtime/routes/home-feed-routes.ts +8 -3
- package/src/runtime/routes/identity-routes.ts +1 -296
- package/src/runtime/routes/inbound-message-handler.ts +214 -228
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +89 -7
- package/src/runtime/routes/inbound-stages/admission-policy.test.ts +154 -0
- package/src/runtime/routes/inbound-stages/admission-policy.ts +140 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +3 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +11 -6
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -2
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +1 -2
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +7 -7
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +47 -28
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +358 -0
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +8 -0
- package/src/runtime/routes/integrations/slack/channel.ts +36 -0
- package/src/runtime/routes/internal-telemetry-routes.ts +1 -1
- package/src/runtime/routes/mcp-auth-routes.ts +233 -41
- package/src/runtime/routes/memory-eval-routes.ts +87 -0
- package/src/runtime/routes/notification-routes.ts +122 -133
- package/src/runtime/routes/platform-routes.ts +2 -2
- package/src/runtime/routes/plugins-routes.ts +366 -11
- package/src/runtime/routes/schedule-routes.ts +0 -22
- package/src/runtime/routes/secret-routes.ts +15 -0
- package/src/runtime/routes/surface-action-routes.ts +2 -1
- package/src/runtime/routes/tool-call-question-enrichment.test.ts +146 -0
- package/src/runtime/routes/tool-call-question-enrichment.ts +66 -0
- package/src/runtime/routes/workflow-routes.test.ts +229 -44
- package/src/runtime/routes/workflow-routes.ts +131 -29
- package/src/runtime/routes/workspace-greetings.ts +55 -0
- package/src/runtime/sync/resource-sync-events.ts +1 -11
- package/src/runtime/tool-grant-request-helper.ts +18 -16
- package/src/runtime/trust-context-resolver.ts +8 -5
- package/src/schedule/inference-profile.ts +2 -14
- package/src/schedule/schedule-store.ts +1 -1
- package/src/schedule/scheduler-types.ts +5 -1
- package/src/security/__tests__/provider-key-env-fallback.test.ts +6 -0
- package/src/security/secret-patterns.ts +3 -0
- package/src/subagent/manager.ts +17 -4
- package/src/subagent/types.ts +6 -0
- package/src/telemetry/trace-collection-policy.test.ts +28 -0
- package/src/telemetry/trace-collection-policy.ts +30 -0
- package/src/telemetry/types.ts +89 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +586 -36
- package/src/telemetry/usage-telemetry-reporter.ts +148 -41
- package/src/tools/AGENTS.md +3 -3
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +31 -0
- package/src/tools/browser/browser-execution.ts +30 -19
- package/src/tools/document/document-tool.ts +30 -6
- package/src/tools/executor.ts +5 -3
- package/src/tools/host-terminal/host-shell.ts +5 -4
- package/src/tools/memory/register.ts +2 -2
- package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +360 -0
- package/src/tools/network/__tests__/web-search.test.ts +143 -0
- package/src/tools/network/web-fetch.ts +372 -1
- package/src/tools/network/web-search-error.ts +1 -1
- package/src/tools/network/web-search.ts +213 -10
- package/src/tools/permission-checker.ts +4 -3
- package/src/tools/registry.ts +20 -0
- package/src/tools/schedule/create.ts +7 -12
- package/src/tools/schedule/update.ts +4 -11
- package/src/tools/shared/filesystem/path-policy.ts +39 -13
- package/src/tools/side-effects.ts +2 -17
- package/src/tools/skills/execute.ts +99 -2
- package/src/tools/skills/load.ts +43 -2
- package/src/tools/subagent/spawn.ts +64 -15
- package/src/tools/terminal/shell.ts +10 -4
- package/src/tools/tool-approval-handler.ts +18 -13
- package/src/tools/tool-manifest.ts +0 -2
- package/src/tools/types.ts +10 -0
- package/src/tools/ui-surface/definitions.ts +64 -3
- package/src/tools/verification-control-plane-policy.ts +3 -1
- package/src/tools/workflows/run-workflow.test.ts +8 -18
- package/src/tools/workflows/run-workflow.ts +1 -0
- package/src/util/disk-usage.ts +78 -23
- package/src/util/logs-db-path.ts +22 -0
- package/src/util/platform.ts +10 -3
- package/src/watcher/telemetry.ts +2 -2
- package/src/workflows/capabilities.ts +2 -3
- package/src/workflows/engine.test.ts +175 -1
- package/src/workflows/engine.ts +82 -0
- package/src/workflows/journal-store.test.ts +70 -0
- package/src/workflows/journal-store.ts +18 -3
- package/src/workflows/run-manager.test.ts +171 -28
- package/src/workflows/run-manager.ts +66 -24
- package/src/workspace/migrations/105-enable-memory-v3-live-for-new-workspaces.ts +63 -0
- package/src/workspace/migrations/106-drop-collect-usage-data.ts +47 -0
- package/src/workspace/migrations/107-drop-send-diagnostics.ts +47 -0
- package/src/workspace/migrations/108-drop-balanced-economy-profile.ts +129 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/__tests__/app-control-no-global-cgevent.test.ts +0 -98
- package/src/__tests__/credential-security-e2e.test.ts +0 -362
- package/src/__tests__/credential-vault-unit.test.ts +0 -1528
- package/src/__tests__/credential-vault.test.ts +0 -1706
- package/src/__tests__/identity-intro-cache.test.ts +0 -315
- package/src/__tests__/secret-onetime-send.test.ts +0 -182
- package/src/cli/commands/__tests__/task.test.ts +0 -914
- package/src/cli/commands/task.ts +0 -771
- package/src/config/bundled-skills/personal-page/SKILL.md +0 -57
- package/src/config/bundled-skills/personal-page/TOOLS.json +0 -27
- package/src/config/bundled-skills/personal-page/tools/app-refresh.ts +0 -17
- package/src/config/preloaded-apps/personal-page/src/components/About.tsx +0 -22
- package/src/config/preloaded-apps/personal-page/src/components/App.tsx +0 -16
- package/src/config/preloaded-apps/personal-page/src/components/Features.tsx +0 -77
- package/src/config/preloaded-apps/personal-page/src/components/Hero.tsx +0 -57
- package/src/config/preloaded-apps/personal-page/src/components/Pending.tsx +0 -28
- package/src/config/preloaded-apps/personal-page/src/components/animations.tsx +0 -234
- package/src/config/preloaded-apps/personal-page/src/components/icons.tsx +0 -48
- package/src/config/preloaded-apps/personal-page/src/components/media.ts +0 -16
- package/src/config/preloaded-apps/personal-page/src/index.html +0 -20
- package/src/config/preloaded-apps/personal-page/src/main.tsx +0 -7
- package/src/config/preloaded-apps/personal-page/src/profile-data.ts +0 -82
- package/src/config/preloaded-apps/personal-page/src/styles.css +0 -759
- package/src/memory/__tests__/preloaded-apps.test.ts +0 -85
- package/src/memory/preloaded-apps.ts +0 -116
- package/src/notifications/tool-approval-copy.ts +0 -142
- package/src/runtime/routes/approval-prompt-ts-tracker.ts +0 -78
- package/src/runtime/routes/identity-intro-cache.ts +0 -172
- package/src/tools/credentials/vault.ts +0 -712
|
@@ -28,7 +28,10 @@ import {
|
|
|
28
28
|
import { extractPreferences } from "../notifications/preference-extractor.js";
|
|
29
29
|
import { createPreference } from "../notifications/preferences-store.js";
|
|
30
30
|
import type { ContextWindowResult } from "../plugins/defaults/compaction/window-manager.js";
|
|
31
|
-
import {
|
|
31
|
+
import {
|
|
32
|
+
type GuardianPendingScope,
|
|
33
|
+
routeGuardianReply,
|
|
34
|
+
} from "../runtime/guardian-reply-router.js";
|
|
32
35
|
import { publishConversationMessagesChanged } from "../runtime/sync/resource-sync-events.js";
|
|
33
36
|
import { getLogger } from "../util/logger.js";
|
|
34
37
|
import type { CleanResult, Conversation } from "./conversation.js";
|
|
@@ -153,7 +156,7 @@ function resolveQueuedTurnInterfaceContext(
|
|
|
153
156
|
}
|
|
154
157
|
|
|
155
158
|
/** Build a SlashContext from the current conversation state and config. */
|
|
156
|
-
function buildSlashContext(
|
|
159
|
+
export function buildSlashContext(
|
|
157
160
|
content: string,
|
|
158
161
|
conversation: Conversation,
|
|
159
162
|
): SlashContext | undefined {
|
|
@@ -1407,9 +1410,14 @@ export async function processMessage(
|
|
|
1407
1410
|
"vellum",
|
|
1408
1411
|
).map((request) => request.id)
|
|
1409
1412
|
: [];
|
|
1410
|
-
|
|
1413
|
+
// Empty hints → leave the scope unset (identity-fallback): the desktop
|
|
1414
|
+
// guardian can still resolve their pending work by identity/principal.
|
|
1415
|
+
const pendingScope: GuardianPendingScope | undefined =
|
|
1411
1416
|
canonicalPendingRequestHintIdsForConversation.length > 0
|
|
1412
|
-
?
|
|
1417
|
+
? {
|
|
1418
|
+
mode: "scoped",
|
|
1419
|
+
requestIds: canonicalPendingRequestHintIdsForConversation,
|
|
1420
|
+
}
|
|
1413
1421
|
: undefined;
|
|
1414
1422
|
|
|
1415
1423
|
// ── Canonical guardian reply router (desktop/conversation path) ──
|
|
@@ -1428,7 +1436,7 @@ export async function processMessage(
|
|
|
1428
1436
|
conversation.trustContext?.guardianPrincipalId ?? undefined,
|
|
1429
1437
|
},
|
|
1430
1438
|
conversationId: conversation.conversationId,
|
|
1431
|
-
|
|
1439
|
+
pendingScope,
|
|
1432
1440
|
// Desktop path: disable NL classification to avoid consuming non-decision
|
|
1433
1441
|
// messages while a tool confirmation is pending. Deterministic code-prefix
|
|
1434
1442
|
// and callback parsing remain active.
|
|
@@ -9,9 +9,9 @@ import { statSync } from "node:fs";
|
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
|
|
11
11
|
import { type ChannelId, parseInterfaceId } from "../channels/types.js";
|
|
12
|
-
import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
|
|
13
12
|
import { resolveCallSiteConfig } from "../config/llm-resolver.js";
|
|
14
13
|
import { getConfig } from "../config/loader.js";
|
|
14
|
+
import { isMemoryV3Live } from "../config/memory-v3-gate.js";
|
|
15
15
|
import type { LLMCallSite, LLMConfig } from "../config/schemas/llm.js";
|
|
16
16
|
import {
|
|
17
17
|
NOW_SCRATCHPAD_STRIP_PREFIXES,
|
|
@@ -62,11 +62,11 @@ import type {
|
|
|
62
62
|
import type { ContentBlock, Message } from "../providers/types.js";
|
|
63
63
|
import {
|
|
64
64
|
type ActorTrustContext,
|
|
65
|
-
isUntrustedTrustClass,
|
|
66
65
|
resolveActorTrust,
|
|
67
66
|
type TrustClass,
|
|
68
67
|
} from "../runtime/actor-trust-resolver.js";
|
|
69
68
|
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
|
|
69
|
+
import { resolveCapabilities } from "../runtime/capabilities.js";
|
|
70
70
|
import { channelStatusToMemberStatus } from "../runtime/routes/inbound-stages/acl-enforcement.js";
|
|
71
71
|
import { getSubagentManager } from "../subagent/index.js";
|
|
72
72
|
import type { SubagentState } from "../subagent/types.js";
|
|
@@ -125,8 +125,8 @@ export interface InboundActorContext {
|
|
|
125
125
|
actorSenderDisplayName?: string;
|
|
126
126
|
/** Guardian-managed display name from the contact record. */
|
|
127
127
|
actorMemberDisplayName?: string;
|
|
128
|
-
/** Trust classification:
|
|
129
|
-
trustClass:
|
|
128
|
+
/** Trust classification: see TrustClass. */
|
|
129
|
+
trustClass: TrustClass;
|
|
130
130
|
/** Guardian identity for this (assistant, channel) binding. */
|
|
131
131
|
guardianIdentity?: string;
|
|
132
132
|
/** Member status when the actor has a contact record. */
|
|
@@ -916,7 +916,7 @@ function filterSlackConversationRowsForActor(
|
|
|
916
916
|
rows: MessageRow[],
|
|
917
917
|
trustClass: TrustClass | undefined,
|
|
918
918
|
): MessageRow[] {
|
|
919
|
-
if (
|
|
919
|
+
if (resolveCapabilities(trustClass).canAccessMemory) return rows;
|
|
920
920
|
const nonSlackVisibleRows = filterMessagesForUntrustedActor(rows);
|
|
921
921
|
const nonSlackVisibleIds = new Set(nonSlackVisibleRows.map((row) => row.id));
|
|
922
922
|
return rows.filter((row) => {
|
|
@@ -1009,6 +1009,7 @@ function rowToRenderable(row: SlackTranscriptInputRow): RenderableSlackMessage {
|
|
|
1009
1009
|
if (
|
|
1010
1010
|
outer.provenanceTrustClass === "guardian" ||
|
|
1011
1011
|
outer.provenanceTrustClass === "trusted_contact" ||
|
|
1012
|
+
outer.provenanceTrustClass === "unverified_contact" ||
|
|
1012
1013
|
outer.provenanceTrustClass === "unknown"
|
|
1013
1014
|
) {
|
|
1014
1015
|
provenanceTrustClass = outer.provenanceTrustClass;
|
|
@@ -1322,9 +1323,9 @@ export function loadSlackChronologicalContext(
|
|
|
1322
1323
|
options,
|
|
1323
1324
|
);
|
|
1324
1325
|
return assembleSlackChronologicalContext(rows, capabilities, {
|
|
1325
|
-
contextSummary:
|
|
1326
|
-
?
|
|
1327
|
-
:
|
|
1326
|
+
contextSummary: resolveCapabilities(options.trustClass).canAccessMemory
|
|
1327
|
+
? options.contextSummary
|
|
1328
|
+
: null,
|
|
1328
1329
|
});
|
|
1329
1330
|
}
|
|
1330
1331
|
|
|
@@ -1536,8 +1537,8 @@ export interface RuntimeInjectionBlocks {
|
|
|
1536
1537
|
*/
|
|
1537
1538
|
memoryV3InjectedBlock?: string;
|
|
1538
1539
|
/**
|
|
1539
|
-
* True when memory-v3 superseded v2 as this turn's `<memory>` source —
|
|
1540
|
-
* `memory
|
|
1540
|
+
* True when memory-v3 superseded v2 as this turn's `<memory>` source —
|
|
1541
|
+
* `memory.v3.live` is on AND the v3 injector produced a block (possibly
|
|
1541
1542
|
* empty-text on an all-repeat turn), i.e. exactly when assembly stripped
|
|
1542
1543
|
* v2's fresh tail block. The user-prompt-submit hook keys v2's
|
|
1543
1544
|
* `memoryInjectedBlock` metadata persist off this so a stripped v2 block is
|
|
@@ -2177,7 +2178,7 @@ export async function applyRuntimeInjections(
|
|
|
2177
2178
|
// no-op, keeping the v2 path bit-for-bit identical.
|
|
2178
2179
|
let runMessagesForAssembly = stripSpotlightInjections(runMessages);
|
|
2179
2180
|
|
|
2180
|
-
// v2 suppression: when
|
|
2181
|
+
// v2 suppression: when `memory.v3.live` is on AND the v3 injector
|
|
2181
2182
|
// produced a block this turn (possibly empty-text on an all-repeat turn), v3
|
|
2182
2183
|
// owns the `<memory>` layer. v2's `prepareMemory` already prepended its own
|
|
2183
2184
|
// fresh `<memory>` block to the tail user message — strip the TAIL's v2
|
|
@@ -2196,10 +2197,7 @@ export async function applyRuntimeInjections(
|
|
|
2196
2197
|
// (`produce()` → null) leaves v2's block intact — fallback rather than a
|
|
2197
2198
|
// memory-less turn. Idempotent: re-injection sites that already stripped
|
|
2198
2199
|
// see no change. Flag off → bit-for-bit identical to the v2 path.
|
|
2199
|
-
const suppressV2MemoryForV3 =
|
|
2200
|
-
"memory-v3-live",
|
|
2201
|
-
getConfig(),
|
|
2202
|
-
);
|
|
2200
|
+
const suppressV2MemoryForV3 = isMemoryV3Live(getConfig());
|
|
2203
2201
|
const v3ProducedBlock = afterMemory.some((b) => b.id === MEMORY_V3_BLOCK_ID);
|
|
2204
2202
|
const memoryV3Active = suppressV2MemoryForV3 && v3ProducedBlock;
|
|
2205
2203
|
if (memoryV3Active) {
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
loadRawConfig,
|
|
8
8
|
saveRawConfig,
|
|
9
9
|
} from "../config/loader.js";
|
|
10
|
+
import { orderProfileKeys } from "../config/profile-order.js";
|
|
10
11
|
import { getConversationOverrideProfile } from "../memory/conversation-crud.js";
|
|
11
12
|
import { getConfiguredProviders } from "../providers/provider-availability.js";
|
|
12
13
|
import { getVisibleProviderCatalog } from "../providers/provider-catalog-visibility.js";
|
|
@@ -130,28 +131,6 @@ function parseModelCommand(trimmed: string): ModelCommandParse | null {
|
|
|
130
131
|
return { kind: "switch", profileName: rest };
|
|
131
132
|
}
|
|
132
133
|
|
|
133
|
-
function orderedProfileNames(
|
|
134
|
-
profiles: Record<
|
|
135
|
-
string,
|
|
136
|
-
{ label?: string; description?: string; status?: "active" | "disabled" }
|
|
137
|
-
>,
|
|
138
|
-
profileOrder: readonly string[] | undefined,
|
|
139
|
-
): string[] {
|
|
140
|
-
const order = profileOrder ?? [];
|
|
141
|
-
const seen = new Set<string>();
|
|
142
|
-
const ordered: string[] = [];
|
|
143
|
-
for (const name of order) {
|
|
144
|
-
if (profiles[name] != null && !seen.has(name)) {
|
|
145
|
-
ordered.push(name);
|
|
146
|
-
seen.add(name);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
const tail = Object.keys(profiles)
|
|
150
|
-
.filter((n) => !seen.has(n))
|
|
151
|
-
.sort();
|
|
152
|
-
return [...ordered, ...tail];
|
|
153
|
-
}
|
|
154
|
-
|
|
155
134
|
async function resolveModelCommand(
|
|
156
135
|
parse: ModelCommandParse,
|
|
157
136
|
): Promise<SlashResolution> {
|
|
@@ -160,7 +139,7 @@ async function resolveModelCommand(
|
|
|
160
139
|
string,
|
|
161
140
|
{ label?: string; description?: string; status?: "active" | "disabled" }
|
|
162
141
|
>;
|
|
163
|
-
const profileNames =
|
|
142
|
+
const profileNames = orderProfileKeys(profiles, config.llm.profileOrder);
|
|
164
143
|
const activeProfile = config.llm.activeProfile;
|
|
165
144
|
|
|
166
145
|
if (parse.kind === "list") {
|
|
@@ -291,6 +291,32 @@ export function markSurfaceCompleted(
|
|
|
291
291
|
}
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
+
/**
|
|
295
|
+
* Complete a `ui_surface` card and notify live clients, addressed only by
|
|
296
|
+
* conversation + surface id.
|
|
297
|
+
*
|
|
298
|
+
* Unlike {@link completeSurfaceFromAction}, this needs no live `Conversation`
|
|
299
|
+
* instance, so it can run from flows that don't own one — projecting a
|
|
300
|
+
* terminal guardian-request status onto its in-app approval card when the
|
|
301
|
+
* request was resolved on another surface (or by the expiry sweep). Persists
|
|
302
|
+
* the completion (reload-safe) and broadcasts `ui_surface_complete` so every
|
|
303
|
+
* connected client of this guardian converges. No-ops when the surface block
|
|
304
|
+
* isn't found in the conversation.
|
|
305
|
+
*/
|
|
306
|
+
export function completeSurfaceAndNotify(
|
|
307
|
+
conversationId: string,
|
|
308
|
+
surfaceId: string,
|
|
309
|
+
summary: string,
|
|
310
|
+
): void {
|
|
311
|
+
markSurfaceCompleted({ conversationId }, surfaceId, summary);
|
|
312
|
+
broadcastMessage({
|
|
313
|
+
type: "ui_surface_complete",
|
|
314
|
+
conversationId,
|
|
315
|
+
surfaceId,
|
|
316
|
+
summary,
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
|
|
294
320
|
/**
|
|
295
321
|
* Remove a `ui_surface` content block from history so a passively dismissed
|
|
296
322
|
* surface does not survive a reload. The live client drops a dismissed surface
|
|
@@ -17,16 +17,21 @@ import type { LLMCallSite } from "../config/schemas/llm.js";
|
|
|
17
17
|
import { getBindingByConversation } from "../memory/external-conversation-store.js";
|
|
18
18
|
import type { PermissionPrompter } from "../permissions/prompter.js";
|
|
19
19
|
import type { SecretPrompter } from "../permissions/secret-prompter.js";
|
|
20
|
+
import { advisorEnabledForProfile } from "../plugins/defaults/advisor/advisor-gate.js";
|
|
20
21
|
import type { Message, ToolDefinition } from "../providers/types.js";
|
|
21
22
|
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
22
23
|
import { registerConversationSender } from "../tools/browser/browser-screencast.js";
|
|
23
24
|
import type { ToolExecutor } from "../tools/executor.js";
|
|
24
|
-
import { getMcpToolDefinitions } from "../tools/registry.js";
|
|
25
|
+
import { getMcpToolDefinitions, getTool } from "../tools/registry.js";
|
|
25
26
|
import {
|
|
26
27
|
ACTIVITY_SKIP_SET,
|
|
27
28
|
injectActivityField,
|
|
28
29
|
} from "../tools/schema-transforms.js";
|
|
29
|
-
import {
|
|
30
|
+
import {
|
|
31
|
+
augmentSkillExecuteError,
|
|
32
|
+
recoverSkillExecuteEnvelope,
|
|
33
|
+
resolveSkillExecuteInput,
|
|
34
|
+
} from "../tools/skills/execute.js";
|
|
30
35
|
import { resolveToolInvocationAlias } from "../tools/tool-name-aliases.js";
|
|
31
36
|
import {
|
|
32
37
|
isDiskPressureCleanupToolName,
|
|
@@ -52,7 +57,7 @@ import {
|
|
|
52
57
|
} from "./doordash-steps.js";
|
|
53
58
|
import type { ServerMessage, UiSurfaceShow } from "./message-protocol.js";
|
|
54
59
|
import { runPostExecutionSideEffects } from "./tool-side-effects.js";
|
|
55
|
-
import { resolveTrustClass } from "./trust-context.js";
|
|
60
|
+
import { FALLBACK_TURN_TRUST, resolveTrustClass } from "./trust-context.js";
|
|
56
61
|
|
|
57
62
|
const log = getLogger("conversation-tool-setup");
|
|
58
63
|
|
|
@@ -88,8 +93,10 @@ export type {
|
|
|
88
93
|
* agent's). The conversation id is threaded as the mix selection seed so
|
|
89
94
|
* mix-profile arms match what the dispatch path actually ran.
|
|
90
95
|
*
|
|
91
|
-
* Returns `null` on any failure: attribution
|
|
92
|
-
*
|
|
96
|
+
* Returns `null` on any failure: attribution must never break tool execution
|
|
97
|
+
* (or skill loads, which reuse this helper). Consumers read it best-effort —
|
|
98
|
+
* usage telemetry, and `subagent_spawn`, which inherits the resolved
|
|
99
|
+
* `appliedProfile` so a child defaults to the invoking turn's profile.
|
|
93
100
|
*/
|
|
94
101
|
export function resolveConversationAttribution(
|
|
95
102
|
ctx: Pick<
|
|
@@ -178,28 +185,32 @@ export function createToolExecutor(
|
|
|
178
185
|
markDoordashStepInProgress(ctx, executionInput);
|
|
179
186
|
}
|
|
180
187
|
|
|
181
|
-
//
|
|
182
|
-
//
|
|
188
|
+
// Per-turn trust snapshot: prefer the snapshot captured at turn start so
|
|
189
|
+
// a concurrent owner meta command (/status, /clean) that mutates the live
|
|
190
|
+
// trustContext cannot elevate the in-flight turn to guardian.
|
|
191
|
+
const turnTrust =
|
|
192
|
+
ctx.currentTurnTrustContext ?? ctx.trustContext ?? FALLBACK_TURN_TRUST;
|
|
193
|
+
|
|
183
194
|
const toolContext: ToolContext = {
|
|
184
195
|
workingDir: ctx.workingDir,
|
|
185
196
|
conversationId: ctx.conversationId,
|
|
186
197
|
assistantId: ctx.assistantId,
|
|
187
198
|
requestId: ctx.currentRequestId,
|
|
188
199
|
taskRunId: ctx.taskRunId,
|
|
189
|
-
trustClass: resolveTrustClass(
|
|
190
|
-
executionChannel:
|
|
191
|
-
sourceActorPrincipalId:
|
|
200
|
+
trustClass: resolveTrustClass(turnTrust),
|
|
201
|
+
executionChannel: turnTrust.sourceChannel,
|
|
202
|
+
sourceActorPrincipalId: turnTrust.guardianPrincipalId,
|
|
192
203
|
callSessionId: ctx.callSessionId,
|
|
193
204
|
triggeredBySurfaceAction:
|
|
194
205
|
ctx.surfaceActionRequestIds?.has(ctx.currentRequestId ?? "") ?? false,
|
|
195
206
|
approvedViaPrompt: ctx.approvedViaPromptThisTurn || undefined,
|
|
196
207
|
batchAuthorizedByTask: false,
|
|
197
|
-
requesterExternalUserId:
|
|
198
|
-
requesterChatId:
|
|
199
|
-
requesterIdentifier:
|
|
200
|
-
requesterDisplayName:
|
|
208
|
+
requesterExternalUserId: turnTrust.requesterExternalUserId,
|
|
209
|
+
requesterChatId: turnTrust.requesterChatId,
|
|
210
|
+
requesterIdentifier: turnTrust.requesterIdentifier,
|
|
211
|
+
requesterDisplayName: turnTrust.requesterDisplayName,
|
|
201
212
|
channelPermissionChannelId:
|
|
202
|
-
|
|
213
|
+
turnTrust.sourceChannel === "slack"
|
|
203
214
|
? getBindingByConversation(ctx.conversationId)?.externalChatId
|
|
204
215
|
: undefined,
|
|
205
216
|
onOutput,
|
|
@@ -211,6 +222,7 @@ export function createToolExecutor(
|
|
|
211
222
|
isPlatformHosted: getIsPlatform(),
|
|
212
223
|
transportInterface: ctx.transportInterface,
|
|
213
224
|
overrideProfile: ctx.currentTurnOverrideProfile,
|
|
225
|
+
invokingCallSite: ctx.currentCallSite ?? "mainAgent",
|
|
214
226
|
attribution: resolveConversationAttribution(ctx),
|
|
215
227
|
onToolLifecycleEvent: handleToolLifecycleEvent,
|
|
216
228
|
sendToClient: (msg) => {
|
|
@@ -295,9 +307,16 @@ export function createToolExecutor(
|
|
|
295
307
|
// risk level, permission checks, hooks, and lifecycle events all fire
|
|
296
308
|
// with the real tool name.
|
|
297
309
|
if (executionName === "skill_execute") {
|
|
310
|
+
// Recover an envelope the provider wrapped as unparseable when MiniMax's
|
|
311
|
+
// coercion failed to JSON-decode a bare-string `input` (see
|
|
312
|
+
// recoverSkillExecuteEnvelope), then resolve the inner tool + params.
|
|
313
|
+
const envelope = recoverSkillExecuteEnvelope(executionInput);
|
|
298
314
|
const rawToolName =
|
|
299
|
-
typeof
|
|
300
|
-
const
|
|
315
|
+
typeof envelope.tool === "string" ? envelope.tool : "";
|
|
316
|
+
const innerSchema = rawToolName
|
|
317
|
+
? getTool(rawToolName)?.input_schema
|
|
318
|
+
: undefined;
|
|
319
|
+
const rawToolInput = resolveSkillExecuteInput(envelope, innerSchema);
|
|
301
320
|
|
|
302
321
|
// Clone to avoid mutating shared input objects
|
|
303
322
|
const { name: toolName, input: toolInput } = resolveToolInvocationAlias(
|
|
@@ -320,7 +339,12 @@ export function createToolExecutor(
|
|
|
320
339
|
const innerRejection = rejectNonAllowlistedTool(toolName);
|
|
321
340
|
if (innerRejection) return innerRejection;
|
|
322
341
|
|
|
323
|
-
const
|
|
342
|
+
const rawResult = await executor.execute(
|
|
343
|
+
toolName,
|
|
344
|
+
toolInput,
|
|
345
|
+
toolContext,
|
|
346
|
+
);
|
|
347
|
+
const result = augmentSkillExecuteError(toolName, toolInput, rawResult);
|
|
324
348
|
if (toolContext.approvedViaPrompt) {
|
|
325
349
|
ctx.approvedViaPromptThisTurn = true;
|
|
326
350
|
}
|
|
@@ -371,7 +395,7 @@ export function createProxyApprovalCallback(
|
|
|
371
395
|
* history or explicit preactivation. Without this, their tools are
|
|
372
396
|
* unavailable in fresh conversations until `skill_load` is called.
|
|
373
397
|
*/
|
|
374
|
-
const DEFAULT_PREACTIVATED_SKILL_IDS = ["
|
|
398
|
+
const DEFAULT_PREACTIVATED_SKILL_IDS = ["notifications", "subagent"];
|
|
375
399
|
|
|
376
400
|
/**
|
|
377
401
|
* Subset of Conversation state that the resolveTools callback reads at each
|
|
@@ -576,6 +600,16 @@ export function isToolActiveForContext(
|
|
|
576
600
|
return true;
|
|
577
601
|
}
|
|
578
602
|
}
|
|
603
|
+
if (name === "advisor") {
|
|
604
|
+
// Gated per chat-profile (`ProfileEntry.advisorEnabled`): when the resolved
|
|
605
|
+
// profile disables the advisor, omit the tool from the wire list so the
|
|
606
|
+
// model never sees a tool it can only no-op on. Resolves the profile the
|
|
607
|
+
// same way the advisor's execution-time guard does (the per-turn override,
|
|
608
|
+
// else the active profile). The wire list is fixed before PRE_MODEL_CALL
|
|
609
|
+
// hooks run, so a hook that re-routes the profile mid-turn (the model-router
|
|
610
|
+
// lever on `PreModelCallContext.modelProfile`) is not reflected here.
|
|
611
|
+
return advisorEnabledForProfile(ctx.currentTurnOverrideProfile ?? null);
|
|
612
|
+
}
|
|
579
613
|
if (UI_SURFACE_TOOL_NAMES.has(name)) {
|
|
580
614
|
if (
|
|
581
615
|
channelCapabilities?.channel === "slack" &&
|
|
@@ -80,12 +80,10 @@ import {
|
|
|
80
80
|
} from "../prompts/system-prompt.js";
|
|
81
81
|
import type { ContentBlock, Message } from "../providers/types.js";
|
|
82
82
|
import type { Provider } from "../providers/types.js";
|
|
83
|
-
import {
|
|
84
|
-
isUntrustedTrustClass,
|
|
85
|
-
type TrustClass,
|
|
86
|
-
} from "../runtime/actor-trust-resolver.js";
|
|
83
|
+
import { type TrustClass } from "../runtime/actor-trust-resolver.js";
|
|
87
84
|
import { broadcastMessage } from "../runtime/assistant-event-hub.js";
|
|
88
85
|
import type { AuthContext } from "../runtime/auth/types.js";
|
|
86
|
+
import { resolveCapabilities } from "../runtime/capabilities.js";
|
|
89
87
|
import type { InteractiveUiResult } from "../runtime/interactive-ui.js";
|
|
90
88
|
import { publishSyncInvalidation } from "../runtime/sync/sync-publisher.js";
|
|
91
89
|
import {
|
|
@@ -107,7 +105,7 @@ import {
|
|
|
107
105
|
runAgentLoopImpl,
|
|
108
106
|
} from "./conversation-agent-loop.js";
|
|
109
107
|
import type { HistoryConversationContext } from "./conversation-history.js";
|
|
110
|
-
import { undo as undoImpl } from "./conversation-history.js";
|
|
108
|
+
import { isToolResultBlock, undo as undoImpl } from "./conversation-history.js";
|
|
111
109
|
import {
|
|
112
110
|
abortConversation,
|
|
113
111
|
disposeConversation,
|
|
@@ -175,6 +173,36 @@ import { TraceEmitter } from "./trace-emitter.js";
|
|
|
175
173
|
|
|
176
174
|
const log = getLogger("conversation");
|
|
177
175
|
|
|
176
|
+
/**
|
|
177
|
+
* Whether a persisted message starts a new conversation turn. A turn is
|
|
178
|
+
* delimited by a "real" user message; a user message whose content is entirely
|
|
179
|
+
* tool_result blocks is a continuation within the current turn, and assistant
|
|
180
|
+
* messages never start one. Mirrors the turn-boundary definition used by
|
|
181
|
+
* `getAssistantMessageIdsInTurn`/`getTurnTimeBounds` and the agent loop's
|
|
182
|
+
* per-turn `turnCount++`, so counting these reconstructs `turnCount` on load.
|
|
183
|
+
*/
|
|
184
|
+
function startsNewTurn(role: string, content: string): boolean {
|
|
185
|
+
if (role !== "user") return false;
|
|
186
|
+
try {
|
|
187
|
+
const parsed = JSON.parse(content);
|
|
188
|
+
if (
|
|
189
|
+
Array.isArray(parsed) &&
|
|
190
|
+
parsed.length > 0 &&
|
|
191
|
+
parsed.every(
|
|
192
|
+
(block: unknown) =>
|
|
193
|
+
block != null &&
|
|
194
|
+
typeof block === "object" &&
|
|
195
|
+
isToolResultBlock(block as Record<string, unknown>),
|
|
196
|
+
)
|
|
197
|
+
) {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
} catch {
|
|
201
|
+
// Non-JSON content is a plain user message — a turn boundary.
|
|
202
|
+
}
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
|
|
178
206
|
export interface CleanResult {
|
|
179
207
|
previousEstimatedInputTokens: number;
|
|
180
208
|
estimatedInputTokens: number;
|
|
@@ -366,6 +394,13 @@ export class Conversation {
|
|
|
366
394
|
workspaceDir: string,
|
|
367
395
|
) => Pick<WorkspaceGitService, "ensureInitialized">;
|
|
368
396
|
/** @internal */ commitTurnChanges?: typeof commitTurnChanges;
|
|
397
|
+
/**
|
|
398
|
+
* Abort-watchdog timeout (ms) for the agent loop's bounded-unwind backstop.
|
|
399
|
+
* Overridable in tests to fire the watchdog quickly; defaults to the
|
|
400
|
+
* production constant in the agent loop when unset.
|
|
401
|
+
* @internal
|
|
402
|
+
*/
|
|
403
|
+
abortWatchdogMs?: number;
|
|
369
404
|
/**
|
|
370
405
|
* The conversation's immutable creation type (`interactive`, `background`,
|
|
371
406
|
* `scheduled`, …) as stored on the DB row. Cached on load (and set directly
|
|
@@ -824,10 +859,25 @@ export class Conversation {
|
|
|
824
859
|
|
|
825
860
|
async loadFromDb(): Promise<void> {
|
|
826
861
|
const trustClass = this.trustContext?.trustClass;
|
|
862
|
+
const canAccessMemory = resolveCapabilities(trustClass).canAccessMemory;
|
|
827
863
|
const allDbMessages = getMessages(this.conversationId);
|
|
828
|
-
const dbMessages =
|
|
829
|
-
?
|
|
830
|
-
: allDbMessages;
|
|
864
|
+
const dbMessages = canAccessMemory
|
|
865
|
+
? allDbMessages
|
|
866
|
+
: filterMessagesForUntrustedActor(allDbMessages);
|
|
867
|
+
|
|
868
|
+
// Rehydrate the in-memory turn counter from persisted history. `turnCount`
|
|
869
|
+
// is otherwise a fresh-zero field, so a reloaded conversation (eviction,
|
|
870
|
+
// restart, fork) would restart its turn numbering at 0 and the next turn
|
|
871
|
+
// would reuse `turnIndex` 0 — colliding with the conversation's first turn.
|
|
872
|
+
// The memory-v3 selector memoizes per (conversationId, turnIndex) for the
|
|
873
|
+
// life of the daemon process, so a collided turnIndex serves a stale
|
|
874
|
+
// selection and skips retrieval. One turn per real (turn-starting) user
|
|
875
|
+
// message, matching the agent loop's per-turn `turnCount++`. Counted from
|
|
876
|
+
// the full unsliced history so it survives compaction and is independent of
|
|
877
|
+
// the viewer's trust class.
|
|
878
|
+
this.turnCount = allDbMessages.filter((m) =>
|
|
879
|
+
startsNewTurn(m.role, m.content),
|
|
880
|
+
).length;
|
|
831
881
|
|
|
832
882
|
const conv = getConversation(this.conversationId);
|
|
833
883
|
this.conversationType = conv?.conversationType ?? undefined;
|
|
@@ -855,12 +905,12 @@ export class Conversation {
|
|
|
855
905
|
// than exist. Slack chronological context is a separate consumer that
|
|
856
906
|
// applies its own trust filtering downstream, so it reads the raw
|
|
857
907
|
// mirrored count rather than this in-context boundary.
|
|
858
|
-
const inContextCompactedCount =
|
|
859
|
-
?
|
|
860
|
-
:
|
|
861
|
-
const contextSummaryForHistory =
|
|
862
|
-
? null
|
|
863
|
-
:
|
|
908
|
+
const inContextCompactedCount = canAccessMemory
|
|
909
|
+
? Math.min(this.contextCompactedMessageCount, dbMessages.length)
|
|
910
|
+
: 0;
|
|
911
|
+
const contextSummaryForHistory = canAccessMemory
|
|
912
|
+
? this.contextSummary?.trim() || null
|
|
913
|
+
: null;
|
|
864
914
|
|
|
865
915
|
// Every injection-strip event (`/clean` or compaction) updates
|
|
866
916
|
// `historyStrippedAt`. Messages older than this should skip metadata
|
|
@@ -1556,8 +1606,65 @@ export class Conversation {
|
|
|
1556
1606
|
}
|
|
1557
1607
|
}
|
|
1558
1608
|
|
|
1609
|
+
/**
|
|
1610
|
+
* Token count for `messages` used to render the user-facing `/compact` and
|
|
1611
|
+
* `/clean` figures. Prefers the provider's real `count_tokens` tokenizer (so
|
|
1612
|
+
* the numbers match the context-window indicator's provider-reported usage)
|
|
1613
|
+
* and falls back to the context-window manager's local estimate when the
|
|
1614
|
+
* provider has no count endpoint or the count call fails — both measure the
|
|
1615
|
+
* same system-prompt + tools composition the manager sizes against.
|
|
1616
|
+
*
|
|
1617
|
+
* The count is a network round-trip with its own rate limit, so this is for
|
|
1618
|
+
* user-initiated actions only, never the per-turn auto-compaction gate.
|
|
1619
|
+
*/
|
|
1620
|
+
private async calculateTokens(messages: Message[]): Promise<number> {
|
|
1621
|
+
const countInputTokens = this.provider.countInputTokens;
|
|
1622
|
+
if (!countInputTokens) {
|
|
1623
|
+
return this.contextWindowManager.estimateInputTokens(messages);
|
|
1624
|
+
}
|
|
1625
|
+
try {
|
|
1626
|
+
const { systemPrompt, tools } =
|
|
1627
|
+
this.contextWindowManager.tokenCountInputs;
|
|
1628
|
+
return await countInputTokens.call(
|
|
1629
|
+
this.provider,
|
|
1630
|
+
messages,
|
|
1631
|
+
systemPrompt,
|
|
1632
|
+
tools,
|
|
1633
|
+
);
|
|
1634
|
+
} catch (err) {
|
|
1635
|
+
log.warn(
|
|
1636
|
+
{ err, conversationId: this.conversationId },
|
|
1637
|
+
"Provider token count failed — falling back to local estimate",
|
|
1638
|
+
);
|
|
1639
|
+
return this.contextWindowManager.estimateInputTokens(messages);
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1559
1643
|
async forceCompact(): Promise<ContextWindowResult> {
|
|
1560
|
-
|
|
1644
|
+
// Report the user-facing before/after using the provider's real tokenizer
|
|
1645
|
+
// (count_tokens) so the `/compact` line matches the context-window
|
|
1646
|
+
// indicator, which reflects the provider's actual reported usage — rather
|
|
1647
|
+
// than the local chars/4 estimate the compaction pipeline runs internally
|
|
1648
|
+
// (it under-counts by ~25% on typical histories). `calculateTokens`
|
|
1649
|
+
// falls back to that estimate when the provider has no count endpoint or
|
|
1650
|
+
// the count call fails, so behavior degrades gracefully.
|
|
1651
|
+
//
|
|
1652
|
+
// Only the *displayed* numbers are overridden — the compaction log and
|
|
1653
|
+
// circuit-breaker accounting inside `runCompaction` keep the estimate-based
|
|
1654
|
+
// figures, leaving calibration and historical logs untouched.
|
|
1655
|
+
const before = await this.calculateTokens(this.messages);
|
|
1656
|
+
const result = await this.runCompaction(true);
|
|
1657
|
+
// `runCompaction` applies the compacted history to `this.messages` in
|
|
1658
|
+
// place, so after a successful compaction this re-counts the new history;
|
|
1659
|
+
// a no-op leaves the context unchanged, so before === after.
|
|
1660
|
+
const after = result.compacted
|
|
1661
|
+
? await this.calculateTokens(this.messages)
|
|
1662
|
+
: before;
|
|
1663
|
+
return {
|
|
1664
|
+
...result,
|
|
1665
|
+
previousEstimatedInputTokens: before,
|
|
1666
|
+
estimatedInputTokens: after,
|
|
1667
|
+
};
|
|
1561
1668
|
}
|
|
1562
1669
|
|
|
1563
1670
|
/**
|
|
@@ -1676,15 +1783,17 @@ export class Conversation {
|
|
|
1676
1783
|
* activations are no longer deduped against the prior session.
|
|
1677
1784
|
*/
|
|
1678
1785
|
async forceClean(): Promise<CleanResult> {
|
|
1679
|
-
|
|
1680
|
-
|
|
1786
|
+
// Use the provider's real tokenizer for the displayed before/after (see
|
|
1787
|
+
// `forceCompact` for why); falls back to the local estimate when count
|
|
1788
|
+
// isn't available.
|
|
1789
|
+
const previousEstimatedInputTokens = await this.calculateTokens(
|
|
1790
|
+
this.messages,
|
|
1791
|
+
);
|
|
1681
1792
|
const stripped = stripInjectionsForCompaction(this.messages);
|
|
1682
1793
|
this.messages = stripped;
|
|
1683
1794
|
await this.graphMemory.onCompacted(0);
|
|
1684
1795
|
setConversationHistoryStrippedAt(this.conversationId, Date.now());
|
|
1685
|
-
const estimatedInputTokens = this.
|
|
1686
|
-
this.messages,
|
|
1687
|
-
);
|
|
1796
|
+
const estimatedInputTokens = await this.calculateTokens(this.messages);
|
|
1688
1797
|
return {
|
|
1689
1798
|
previousEstimatedInputTokens,
|
|
1690
1799
|
estimatedInputTokens,
|
|
@@ -1847,6 +1956,8 @@ export class Conversation {
|
|
|
1847
1956
|
* this value via {@link SubagentManager.spawn}.
|
|
1848
1957
|
*/
|
|
1849
1958
|
overrideProfile?: string;
|
|
1959
|
+
/** Float `overrideProfile` above call-site layers for this run. */
|
|
1960
|
+
forceOverrideProfile?: boolean;
|
|
1850
1961
|
},
|
|
1851
1962
|
): Promise<void> {
|
|
1852
1963
|
const { onEvent, ...rest } = options ?? {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { InterfaceId } from "../channels/types.js";
|
|
2
2
|
import type { LLMCallSite } from "../config/schemas/llm.js";
|
|
3
|
+
import { resolveCapabilities } from "../runtime/capabilities.js";
|
|
3
4
|
import type { DiskPressureStatus } from "./disk-pressure-guard.js";
|
|
4
5
|
import type { ConversationType } from "./message-types/shared.js";
|
|
5
6
|
import type { TrustContext } from "./trust-context.js";
|
|
@@ -74,11 +75,11 @@ export function classifyDiskPressureTurnPolicy(
|
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
const trustClass = metadata.trustContext?.trustClass;
|
|
77
|
-
if (trustClass
|
|
78
|
+
if (resolveCapabilities(trustClass).canActUnderDiskPressureCleanup) {
|
|
78
79
|
return { action: "allow-cleanup-mode", reason: "guardian" };
|
|
79
80
|
}
|
|
80
81
|
|
|
81
|
-
if (trustClass === "trusted_contact") {
|
|
82
|
+
if (trustClass === "trusted_contact" || trustClass === "unverified_contact") {
|
|
82
83
|
return { action: "block", reason: "trusted-contact" };
|
|
83
84
|
}
|
|
84
85
|
|
|
@@ -156,6 +157,7 @@ function isExplicitLocalOwnerCleanupTurn(
|
|
|
156
157
|
}
|
|
157
158
|
return (
|
|
158
159
|
metadata.trustContext == null ||
|
|
159
|
-
metadata.trustContext.trustClass
|
|
160
|
+
resolveCapabilities(metadata.trustContext.trustClass)
|
|
161
|
+
.canActUnderDiskPressureCleanup
|
|
160
162
|
);
|
|
161
163
|
}
|
|
@@ -121,7 +121,6 @@ describe("completeA2AInvite", () => {
|
|
|
121
121
|
const invite = findById(created.inviteId!);
|
|
122
122
|
const contact = getContact(invite!.contactId);
|
|
123
123
|
expect(contact!.channels[0]!.address).toBe("upper-case-id-123");
|
|
124
|
-
expect(contact!.channels[0]!.externalUserId).toBe("UPPER-Case-ID-123");
|
|
125
124
|
});
|
|
126
125
|
|
|
127
126
|
test("assistantContactMetadata has correct assistantId and gatewayUrl", () => {
|
|
@@ -120,7 +120,6 @@ describe("redeemA2AInvite", () => {
|
|
|
120
120
|
|
|
121
121
|
const contact = getContact(result.contactId!);
|
|
122
122
|
expect(contact!.channels[0]!.address).toBe("upper-case-sender-id");
|
|
123
|
-
expect(contact!.channels[0]!.externalUserId).toBe("UPPER-Case-SENDER-ID");
|
|
124
123
|
});
|
|
125
124
|
|
|
126
125
|
test("does not make outbound fetch calls", () => {
|
|
@@ -221,7 +221,6 @@ export function completeA2AInvite(params: {
|
|
|
221
221
|
{
|
|
222
222
|
type: "a2a",
|
|
223
223
|
address: params.acceptor.assistantId.toLowerCase(),
|
|
224
|
-
externalUserId: params.acceptor.assistantId,
|
|
225
224
|
status: "active",
|
|
226
225
|
policy: "allow",
|
|
227
226
|
},
|
|
@@ -289,7 +288,6 @@ export function redeemA2AInvite(params: {
|
|
|
289
288
|
{
|
|
290
289
|
type: "a2a",
|
|
291
290
|
address: params.sender.assistantId.toLowerCase(),
|
|
292
|
-
externalUserId: params.sender.assistantId,
|
|
293
291
|
status: "active",
|
|
294
292
|
policy: "allow",
|
|
295
293
|
},
|