@vellumai/assistant 0.8.4 → 0.8.6
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/AGENTS.md +33 -1
- package/ARCHITECTURE.md +3 -3
- package/bunfig.toml +6 -1
- package/docs/browser-use-architecture-phase2.md +1 -1
- package/docs/credential-execution-service.md +6 -6
- package/docs/plugins.md +4 -3
- package/knip.json +2 -1
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
- package/openapi.yaml +2748 -216
- package/package.json +1 -1
- package/src/__tests__/actor-token-service.test.ts +3 -2
- package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
- package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
- package/src/__tests__/annotate-risk-options.test.ts +1 -0
- package/src/__tests__/anthropic-provider.test.ts +34 -37
- package/src/__tests__/approval-cascade.test.ts +1 -0
- package/src/__tests__/approval-routes-http.test.ts +9 -13
- package/src/__tests__/assert-not-live-db.ts +79 -0
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +12 -28
- package/src/__tests__/audit-log-rotation.test.ts +72 -18
- package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
- package/src/__tests__/background-workers-disk-pressure.test.ts +8 -11
- package/src/__tests__/browser-skill-endstate.test.ts +3 -3
- package/src/__tests__/btw-routes.test.ts +5 -5
- package/src/__tests__/call-controller.test.ts +3 -3
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +3 -2
- package/src/__tests__/channel-guardian.test.ts +6 -5
- package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
- package/src/__tests__/channel-reply-delivery.test.ts +35 -0
- package/src/__tests__/channel-retry-sweep.test.ts +320 -3
- package/src/__tests__/checker.test.ts +18 -27
- package/src/__tests__/compaction-events.test.ts +2 -0
- package/src/__tests__/compaction-trail-store.test.ts +264 -0
- package/src/__tests__/compactor-call-site-logging.test.ts +215 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -16
- package/src/__tests__/computer-use-tools.test.ts +14 -18
- package/src/__tests__/config-loader-backfill.test.ts +13 -28
- package/src/__tests__/config-loader-corrupt.test.ts +5 -5
- package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
- package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
- package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
- package/src/__tests__/config-schema.test.ts +10 -10
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/connection-model-compat.test.ts +83 -0
- package/src/__tests__/contacts-tools.test.ts +3 -2
- package/src/__tests__/context-token-estimator.test.ts +22 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +231 -2
- package/src/__tests__/conversation-agent-loop.test.ts +581 -54
- package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
- package/src/__tests__/conversation-app-control-instantiation.test.ts +31 -24
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
- package/src/__tests__/conversation-attention-store.test.ts +101 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
- package/src/__tests__/conversation-clear-safety.test.ts +25 -25
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-error.test.ts +61 -0
- package/src/__tests__/conversation-fork-crud.test.ts +239 -15
- package/src/__tests__/conversation-fork-route.test.ts +3 -2
- package/src/__tests__/conversation-history-web-search.test.ts +1 -0
- package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
- package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
- package/src/__tests__/conversation-lifecycle.test.ts +53 -11
- package/src/__tests__/conversation-list-source.test.ts +3 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
- package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +14 -13
- package/src/__tests__/conversation-pairing.test.ts +53 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
- package/src/__tests__/conversation-process-callsite.test.ts +1 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/conversation-queue.test.ts +333 -291
- package/src/__tests__/conversation-routes-disk-view.test.ts +112 -18
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
- package/src/__tests__/conversation-routes-slash-commands.test.ts +68 -2
- package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
- package/src/__tests__/conversation-skill-tools.test.ts +40 -147
- package/src/__tests__/conversation-slash-queue.test.ts +84 -32
- package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
- package/src/__tests__/conversation-speed-override.test.ts +1 -0
- package/src/__tests__/conversation-store.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
- package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
- package/src/__tests__/conversation-sync-tags.test.ts +218 -35
- package/src/__tests__/conversation-title-service.test.ts +1 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
- package/src/__tests__/conversation-usage.test.ts +1 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -1
- package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
- package/src/__tests__/credential-broker-server-use.test.ts +5 -5
- package/src/__tests__/credential-execution-client.test.ts +72 -1
- package/src/__tests__/credential-execution-feature-gates.test.ts +19 -19
- package/src/__tests__/credential-execution-tools.test.ts +6 -6
- package/src/__tests__/credential-health-service.test.ts +252 -3
- package/src/__tests__/credential-security-invariants.test.ts +6 -5
- package/src/__tests__/credential-vault-unit.test.ts +21 -21
- package/src/__tests__/credential-vault.test.ts +5 -5
- package/src/__tests__/cross-provider-web-search.test.ts +56 -2
- package/src/__tests__/db-connection-isolation.test.ts +7 -6
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
- package/src/__tests__/db-test-helpers.ts +58 -0
- package/src/__tests__/disk-pressure-guard.test.ts +58 -41
- package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
- package/src/__tests__/disk-pressure-routes.test.ts +0 -33
- package/src/__tests__/disk-pressure-tools.test.ts +0 -4
- package/src/__tests__/dm-persistence.test.ts +26 -40
- package/src/__tests__/document-create-dedupe.test.ts +189 -0
- package/src/__tests__/document-find-replace.test.ts +3 -2
- package/src/__tests__/document-tool-security.test.ts +81 -2
- package/src/__tests__/dynamic-page-surface.test.ts +2 -2
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
- package/src/__tests__/email-html-renderer.test.ts +12 -0
- package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
- package/src/__tests__/encrypted-store.test.ts +11 -9
- package/src/__tests__/feature-flag-test-helpers.ts +53 -0
- package/src/__tests__/filing-service.test.ts +1 -0
- package/src/__tests__/first-greeting.test.ts +62 -12
- package/src/__tests__/gateway-flag-listener.test.ts +236 -0
- package/src/__tests__/gemini-provider.test.ts +104 -0
- package/src/__tests__/guardian-action-sweep.test.ts +3 -2
- package/src/__tests__/guardian-dispatch.test.ts +0 -1
- package/src/__tests__/guardian-outbound-http.test.ts +10 -7
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +5 -0
- package/src/__tests__/heartbeat-service.test.ts +5 -0
- package/src/__tests__/helpers/mock-logger.ts +26 -0
- package/src/__tests__/host-bash-routes.test.ts +1 -0
- package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-shell-tool.test.ts +6 -5
- package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
- package/src/__tests__/http-conversation-lineage.test.ts +3 -2
- package/src/__tests__/http-user-message-parity.test.ts +29 -7
- package/src/__tests__/identity-intro-cache.test.ts +133 -22
- package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
- package/src/__tests__/inference-profile-reaper.test.ts +3 -2
- package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
- package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
- package/src/__tests__/injector-disk-pressure.test.ts +3 -17
- package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
- package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
- package/src/__tests__/llm-context-normalization.test.ts +42 -0
- package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
- package/src/__tests__/llm-resolver.test.ts +408 -9
- package/src/__tests__/llm-schema.test.ts +1 -1
- package/src/__tests__/llm-usage-store.test.ts +66 -0
- package/src/__tests__/logger.test.ts +89 -0
- package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
- package/src/__tests__/mcp-abort-signal.test.ts +16 -2
- package/src/__tests__/mcp-client-auth.test.ts +14 -0
- package/src/__tests__/media-generate-image.test.ts +31 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
- package/src/__tests__/messaging-send-tool.test.ts +1 -0
- package/src/__tests__/migration-import-from-url.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +18 -2
- package/src/__tests__/model-intents.test.ts +4 -6
- package/src/__tests__/native-web-search.test.ts +30 -2
- package/src/__tests__/notification-deep-link.test.ts +62 -0
- package/src/__tests__/notification-guardian-path.test.ts +0 -1
- package/src/__tests__/oauth-commands-routes.test.ts +37 -0
- package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
- package/src/__tests__/oauth-store.test.ts +3 -2
- package/src/__tests__/onboarding-template-contract.test.ts +4 -3
- package/src/__tests__/openai-provider.test.ts +54 -9
- package/src/__tests__/openai-responses-provider.test.ts +176 -14
- package/src/__tests__/openrouter-provider-only.test.ts +27 -5
- package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
- package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
- package/src/__tests__/persistence-pipeline.test.ts +139 -1
- package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
- package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
- package/src/__tests__/platform.test.ts +2 -2
- package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
- package/src/__tests__/plugin-bootstrap.test.ts +11 -13
- package/src/__tests__/plugin-tool-contribution.test.ts +50 -40
- package/src/__tests__/plugin-types.test.ts +3 -2
- package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
- package/src/__tests__/pricing.test.ts +12 -0
- package/src/__tests__/process-message-background-slack.test.ts +21 -16
- package/src/__tests__/process-message-display-content.test.ts +19 -22
- package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
- package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
- package/src/__tests__/provider-registry-ollama.test.ts +45 -22
- package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
- package/src/__tests__/recording-handler.test.ts +1 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +84 -84
- package/src/__tests__/relay-server.test.ts +10 -10
- package/src/__tests__/require-fresh-approval.test.ts +2 -2
- package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
- package/src/__tests__/schedule-store.test.ts +16 -1
- package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
- package/src/__tests__/secret-ingress-http.test.ts +5 -1
- package/src/__tests__/secure-keys.test.ts +3 -3
- package/src/__tests__/send-endpoint-busy.test.ts +81 -42
- package/src/__tests__/server-history-render.test.ts +4 -1
- package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
- package/src/__tests__/skill-feature-flags.test.ts +16 -18
- package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
- package/src/__tests__/skill-projection-feature-flag.test.ts +48 -37
- package/src/__tests__/skill-projection.benchmark.test.ts +7 -13
- package/src/__tests__/skill-tool-factory.test.ts +97 -96
- package/src/__tests__/slack-channel-config.test.ts +3 -3
- package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
- package/src/__tests__/subagent-disposal.test.ts +27 -8
- package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
- package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
- package/src/__tests__/subagent-manager-notify.test.ts +20 -8
- package/src/__tests__/subagent-notify-parent.test.ts +6 -5
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
- package/src/__tests__/subagent-tools.test.ts +2 -1
- package/src/__tests__/suggestion-routes.test.ts +2 -0
- package/src/__tests__/sync-message-contract.test.ts +59 -0
- package/src/__tests__/system-prompt.test.ts +183 -131
- package/src/__tests__/terminal-tools.test.ts +1 -1
- package/src/__tests__/test-preload-verifier.ts +68 -0
- package/src/__tests__/test-preload.ts +32 -39
- package/src/__tests__/tool-approval-handler.test.ts +1 -5
- package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +35 -12
- package/src/__tests__/tool-executor.test.ts +64 -72
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
- package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
- package/src/__tests__/twilio-routes.test.ts +3 -2
- package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
- package/src/__tests__/usage-routes.test.ts +3 -0
- package/src/__tests__/validate-input.test.ts +381 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +3 -2
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
- package/src/__tests__/voice-session-bridge.test.ts +37 -28
- package/src/__tests__/workspace-git-service.test.ts +6 -5
- package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
- package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
- package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
- package/src/acp/prepare-agent-env.ts +78 -0
- package/src/acp/session-manager.ts +6 -7
- package/src/agent/loop.ts +88 -0
- package/src/api/README.md +127 -0
- package/src/api/constants/call-sites.ts +27 -0
- package/src/api/events/assistant-outbound-attachment.ts +51 -0
- package/src/api/events/assistant-text-delta.ts +32 -0
- package/src/api/events/assistant-turn-start.ts +33 -0
- package/src/api/events/document-comment-created.ts +48 -0
- package/src/api/events/document-comment-deleted.ts +24 -0
- package/src/api/events/document-comment-reopened.ts +25 -0
- package/src/api/events/document-comment-resolved.ts +27 -0
- package/src/api/events/generation-cancelled.ts +24 -0
- package/src/api/events/generation-handoff.ts +41 -0
- package/src/api/events/message-complete.ts +42 -0
- package/src/api/events/open-url.ts +30 -0
- package/src/api/events/relationship-state-updated.ts +25 -0
- package/src/api/events/tool-use-start.ts +32 -0
- package/src/api/index.ts +129 -0
- package/src/api/package.json +10 -0
- package/src/api/responses/llm-context-response.ts +39 -0
- package/src/api/responses/llm-request-log-entry.ts +93 -0
- package/src/api/responses/memory-recall-log.ts +65 -0
- package/src/api/responses/memory-v2-activation-log.ts +78 -0
- package/src/background-wake/background-wake-routes.test.ts +868 -0
- package/src/background-wake/platform-client.test.ts +308 -0
- package/src/background-wake/platform-client.ts +167 -0
- package/src/background-wake/publisher.ts +91 -0
- package/src/background-wake/runtime-registry.ts +24 -0
- package/src/background-wake/wake-intent-hooks.test.ts +282 -0
- package/src/calls/guardian-dispatch.ts +1 -0
- package/src/calls/voice-session-bridge.ts +4 -4
- package/src/cli/commands/__tests__/browser.test.ts +23 -5
- package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
- package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
- package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +1 -0
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
- package/src/cli/commands/__tests__/notifications.test.ts +184 -40
- package/src/cli/commands/browser.ts +247 -0
- package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
- package/src/cli/commands/channels/index.ts +229 -0
- package/src/cli/commands/domain.ts +91 -41
- package/src/cli/commands/inference.ts +93 -40
- package/src/cli/commands/memory-v2-compare-render.ts +115 -0
- package/src/cli/commands/memory-v2.ts +176 -1
- package/src/cli/commands/memory-v3-render.ts +491 -0
- package/src/cli/commands/memory-v3.ts +567 -0
- package/src/cli/commands/notifications.ts +365 -55
- package/src/cli/lib/open-browser.ts +7 -2
- package/src/cli/program.ts +4 -0
- package/src/config/assistant-feature-flags.ts +39 -46
- package/src/config/bundled-skills/document-editor/SKILL.md +16 -3
- package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
- package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
- package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +1 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
- package/src/config/bundled-tool-registry.ts +2 -0
- package/src/config/call-site-defaults.ts +8 -7
- package/src/config/feature-flag-cache.ts +86 -0
- package/src/config/feature-flag-registry.json +33 -17
- package/src/config/llm-context-resolution.ts +10 -1
- package/src/config/llm-resolver.ts +121 -15
- package/src/config/loader.ts +4 -5
- package/src/config/schemas/__tests__/memory-v2.test.ts +228 -1
- package/src/config/schemas/call-site-catalog.ts +21 -7
- package/src/config/schemas/heartbeat.ts +1 -1
- package/src/config/schemas/llm.ts +102 -2
- package/src/config/schemas/memory-v2.ts +272 -0
- package/src/config/schemas/memory.ts +2 -1
- package/src/config/schemas/services.ts +6 -2
- package/src/config/seed-inference-profiles.ts +36 -16
- package/src/context/compactor.ts +52 -0
- package/src/context/token-estimator.ts +10 -5
- package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
- package/src/conversations/message-consolidation.ts +404 -0
- package/src/credential-execution/executable-discovery.ts +40 -0
- package/src/credential-execution/process-manager.ts +6 -2
- package/src/credential-health/credential-health-service.ts +125 -40
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +2 -3
- package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
- package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +390 -80
- package/src/daemon/conversation-agent-loop.ts +244 -90
- package/src/daemon/conversation-error.ts +64 -6
- package/src/daemon/conversation-lifecycle.ts +27 -22
- package/src/daemon/conversation-messaging.ts +84 -43
- package/src/daemon/conversation-process.ts +74 -37
- package/src/daemon/conversation-runtime-assembly.ts +38 -17
- package/src/daemon/conversation-skill-tools.ts +14 -30
- package/src/daemon/conversation-surfaces.ts +69 -34
- package/src/daemon/conversation-tool-setup.ts +77 -32
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +40 -75
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/daemon-skill-host.ts +9 -2
- package/src/daemon/disk-pressure-guard.ts +39 -29
- package/src/daemon/first-greeting.ts +31 -13
- package/src/daemon/handlers/config-model.test.ts +1 -0
- package/src/daemon/handlers/conversations.ts +11 -3
- package/src/daemon/handlers/shared.ts +6 -1
- package/src/daemon/host-browser-proxy.ts +5 -5
- package/src/daemon/host-cu-proxy.ts +4 -4
- package/src/daemon/host-file-proxy.ts +4 -4
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/host-transfer-proxy.ts +10 -10
- package/src/daemon/lifecycle.ts +29 -26
- package/src/daemon/mcp-reload-service.ts +1 -1
- package/src/daemon/meet-manifest-loader.ts +11 -24
- package/src/daemon/message-types/conversations.ts +22 -27
- package/src/daemon/message-types/document-comments.ts +8 -44
- package/src/daemon/message-types/home.ts +2 -14
- package/src/daemon/message-types/integrations.ts +2 -7
- package/src/daemon/message-types/messages.ts +25 -48
- package/src/daemon/message-types/subagents.ts +6 -0
- package/src/daemon/message-types/sync.ts +14 -0
- package/src/daemon/process-message.ts +9 -9
- package/src/daemon/providers-setup.ts +1 -1
- package/src/daemon/server.ts +16 -0
- package/src/daemon/shutdown-handlers.ts +24 -5
- package/src/daemon/switch-inference-profile-tool.ts +62 -0
- package/src/daemon/tool-setup-types.ts +7 -0
- package/src/daemon/wake-target-adapter.ts +10 -0
- package/src/documents/document-store.ts +38 -0
- package/src/export/__tests__/transcript-formatter.test.ts +1 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +30 -1
- package/src/heartbeat/heartbeat-service.ts +63 -0
- package/src/home/__tests__/feed-writer.test.ts +161 -0
- package/src/home/__tests__/post-connect-feed.test.ts +1 -0
- package/src/home/__tests__/suggested-prompts.test.ts +55 -59
- package/src/home/feed-writer.ts +146 -7
- package/src/home/home-greeting.ts +0 -9
- package/src/home/suggested-prompts.ts +27 -154
- package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
- package/src/ipc/gateway-client.test.ts +4 -1
- package/src/ipc/gateway-flag-listener.ts +123 -0
- package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
- package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
- package/src/ipc/skill-routes/memory.ts +4 -3
- package/src/ipc/skill-routes/registries.ts +35 -40
- package/src/memory/__tests__/db-async-query.test.ts +165 -0
- package/src/memory/__tests__/db-maintenance.test.ts +115 -0
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +242 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
- package/src/memory/auto-analysis-enqueue.ts +5 -1
- package/src/memory/conversation-attention-store.ts +17 -3
- package/src/memory/conversation-crud.ts +423 -182
- package/src/memory/conversation-starters-cadence.ts +3 -1
- package/src/memory/conversation-title-service.ts +19 -3
- package/src/memory/db-async-query.ts +214 -0
- package/src/memory/db-connection.ts +29 -19
- package/src/memory/db-init.ts +14 -0
- package/src/memory/db-maintenance.ts +30 -21
- package/src/memory/db-singleton.ts +77 -0
- package/src/memory/delivery-channels.ts +82 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
- package/src/memory/graph/bootstrap.ts +8 -1
- package/src/memory/graph/capability-seed.ts +7 -3
- package/src/memory/graph/conversation-graph-memory.ts +100 -17
- package/src/memory/graph/extraction.ts +1 -5
- package/src/memory/graph/graph-search.ts +7 -1
- package/src/memory/graph/retriever.test.ts +3 -3
- package/src/memory/indexer.ts +28 -18
- package/src/memory/job-handlers/cleanup.ts +76 -18
- package/src/memory/job-handlers/conversation-starters.ts +1 -4
- package/src/memory/job-handlers/embedding.test.ts +3 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
- package/src/memory/jobs/embed-pkb-file.ts +6 -1
- package/src/memory/jobs-store.ts +14 -0
- package/src/memory/jobs-worker.ts +66 -22
- package/src/memory/llm-request-log-source-clickhouse.ts +122 -2
- package/src/memory/llm-request-log-source-local.ts +31 -0
- package/src/memory/llm-request-log-source.ts +40 -2
- package/src/memory/llm-request-log-store.ts +228 -1
- package/src/memory/llm-usage-store.ts +24 -0
- package/src/memory/memory-retrospective-enqueue.ts +8 -1
- package/src/memory/memory-retrospective-job.ts +5 -0
- package/src/memory/memory-v2-activation-log-store.ts +110 -7
- package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
- package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
- package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
- package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
- package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
- package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
- package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
- package/src/memory/migrations/index.ts +19 -0
- package/src/memory/migrations/registry.ts +33 -0
- package/src/memory/schema/conversations.ts +10 -2
- package/src/memory/schema/inference.ts +0 -1
- package/src/memory/schema/infrastructure.ts +21 -0
- package/src/memory/tool-usage-store.ts +36 -8
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
- package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
- package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
- package/src/memory/v2/__tests__/harness-metrics.test.ts +83 -0
- package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +230 -0
- package/src/memory/v2/__tests__/harness-runner.test.ts +135 -0
- package/src/memory/v2/__tests__/injection.test.ts +127 -98
- package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
- package/src/memory/v2/__tests__/router.test.ts +171 -3
- package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
- package/src/memory/v2/harness/compare.ts +57 -0
- package/src/memory/v2/harness/metrics.ts +128 -0
- package/src/memory/v2/harness/oracle.ts +145 -0
- package/src/memory/v2/harness/replay-input.ts +240 -0
- package/src/memory/v2/harness/retriever.ts +74 -0
- package/src/memory/v2/harness/router-retriever.ts +43 -0
- package/src/memory/v2/harness/runner.ts +112 -0
- package/src/memory/v2/harness/trace.ts +64 -0
- package/src/memory/v2/injection.ts +21 -15
- package/src/memory/v2/prompts/router.ts +26 -1
- package/src/memory/v2/qdrant.ts +14 -2
- package/src/memory/v2/router.ts +171 -18
- package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
- package/src/memory/v3/__tests__/consolidation-job.test.ts +466 -0
- package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
- package/src/memory/v3/__tests__/edges.test.ts +706 -0
- package/src/memory/v3/__tests__/filter.test.ts +560 -0
- package/src/memory/v3/__tests__/gate.test.ts +637 -0
- package/src/memory/v3/__tests__/index-composition.test.ts +291 -0
- package/src/memory/v3/__tests__/loop.test.ts +775 -0
- package/src/memory/v3/__tests__/retriever.test.ts +226 -0
- package/src/memory/v3/__tests__/scouts.test.ts +489 -0
- package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +398 -0
- package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
- package/src/memory/v3/__tests__/traversal.test.ts +508 -0
- package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
- package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
- package/src/memory/v3/__tests__/tree-walk.test.ts +784 -0
- package/src/memory/v3/__tests__/validate.test.ts +277 -0
- package/src/memory/v3/auto-edges.ts +223 -0
- package/src/memory/v3/coactivation-store.ts +124 -0
- package/src/memory/v3/consolidation-job.ts +323 -0
- package/src/memory/v3/coretrieval-seed.ts +240 -0
- package/src/memory/v3/edge-learning-job.ts +160 -0
- package/src/memory/v3/edges.ts +286 -0
- package/src/memory/v3/filter.ts +286 -0
- package/src/memory/v3/gate.ts +349 -0
- package/src/memory/v3/index-composition.ts +126 -0
- package/src/memory/v3/llm-capture.ts +46 -0
- package/src/memory/v3/loop.ts +430 -0
- package/src/memory/v3/maintenance.ts +144 -0
- package/src/memory/v3/prompt-context.ts +33 -0
- package/src/memory/v3/prompts/consolidation.ts +458 -0
- package/src/memory/v3/prompts/system-prompts.ts +196 -0
- package/src/memory/v3/retriever.ts +33 -0
- package/src/memory/v3/scouts.ts +431 -0
- package/src/memory/v3/shadow-diff.ts +287 -0
- package/src/memory/v3/shadow-middleware.ts +347 -0
- package/src/memory/v3/traversal.ts +211 -0
- package/src/memory/v3/tree-index.ts +237 -0
- package/src/memory/v3/tree-store.ts +394 -0
- package/src/memory/v3/tree-walk.ts +356 -0
- package/src/memory/v3/types.ts +65 -0
- package/src/memory/v3/validate.ts +323 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
- package/src/notifications/adapters/macos.ts +18 -1
- package/src/notifications/adapters/platform.ts +1 -1
- package/src/notifications/adapters/slack.ts +45 -11
- package/src/notifications/broadcaster.ts +114 -63
- package/src/notifications/conversation-pairing.ts +23 -3
- package/src/notifications/decision-engine.ts +1 -4
- package/src/notifications/decisions-store.ts +32 -1
- package/src/notifications/deliveries-store.ts +45 -0
- package/src/notifications/edit-notification.ts +201 -0
- package/src/notifications/emit-signal.ts +40 -50
- package/src/notifications/signal.ts +10 -0
- package/src/notifications/types.ts +37 -0
- package/src/oauth/byo-connection.test.ts +67 -3
- package/src/oauth/byo-connection.ts +32 -5
- package/src/oauth/connect-orchestrator.ts +9 -0
- package/src/oauth/connection-resolver.test.ts +76 -0
- package/src/oauth/connection-resolver.ts +49 -10
- package/src/oauth/manual-token-connection.ts +51 -3
- package/src/oauth/seed-providers.ts +3 -0
- package/src/permissions/approval-policy.test.ts +19 -5
- package/src/permissions/approval-policy.ts +14 -3
- package/src/permissions/checker.ts +21 -8
- package/src/permissions/prompter.ts +3 -3
- package/src/permissions/question-prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +2 -2
- package/src/platform/client.test.ts +24 -1
- package/src/platform/client.ts +8 -0
- package/src/platform/feature-gate.ts +15 -0
- package/src/plugin-api/index.ts +4 -0
- package/src/plugin-api/types.ts +7 -33
- package/src/plugins/defaults/index.ts +6 -0
- package/src/plugins/defaults/injectors.ts +20 -19
- package/src/plugins/defaults/persistence.ts +25 -6
- package/src/plugins/external-plugin-loader.ts +5 -68
- package/src/plugins/types.ts +68 -29
- package/src/proactive-artifact/aux-message-injector.ts +17 -4
- package/src/proactive-artifact/job.test.ts +1 -0
- package/src/prompts/__tests__/system-prompt.test.ts +4 -4
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
- package/src/prompts/persona-resolver.ts +36 -21
- package/src/prompts/sections.ts +39 -7
- package/src/prompts/system-prompt.ts +84 -221
- package/src/prompts/template-detection.ts +10 -4
- package/src/prompts/templates/BOOTSTRAP.md +9 -13
- package/src/prompts/templates/IDENTITY.md +0 -2
- package/src/prompts/templates/system-sections.ts +230 -8
- package/src/providers/__tests__/connection-model-compat.test.ts +233 -0
- package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
- package/src/providers/__tests__/retry-callsite.test.ts +85 -5
- package/src/providers/anthropic/client.ts +32 -66
- package/src/providers/call-site-routing.ts +42 -6
- package/src/providers/connection-model-compat.ts +61 -0
- package/src/providers/connection-resolution.ts +47 -14
- package/src/providers/fireworks/client.ts +1 -0
- package/src/providers/gemini/client.ts +70 -6
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
- package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
- package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
- package/src/providers/inference/adapter-factory.ts +3 -0
- package/src/providers/inference/auth.ts +0 -8
- package/src/providers/inference/connections.ts +3 -66
- package/src/providers/inference/resolve-auth.ts +2 -3
- package/src/providers/minimax/client.ts +106 -0
- package/src/providers/model-catalog.ts +78 -1
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
- package/src/providers/openai/chat-completions-provider.ts +116 -15
- package/src/providers/openai/codex-models.ts +20 -0
- package/src/providers/openai/responses-provider.ts +87 -30
- package/src/providers/openrouter/client.ts +13 -8
- package/src/providers/provider-send-message.ts +20 -5
- package/src/providers/registry.ts +48 -8
- package/src/providers/retry.ts +50 -7
- package/src/providers/search-provider-catalog.ts +17 -9
- package/src/providers/thinking-config.ts +26 -1
- package/src/providers/types.ts +9 -0
- package/src/providers/usage-tracking.ts +2 -0
- package/src/runtime/AGENTS.md +2 -2
- package/src/runtime/__tests__/agent-wake.test.ts +1 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
- package/src/runtime/access-request-helper.ts +1 -0
- package/src/runtime/agent-wake.ts +1 -0
- package/src/runtime/assistant-event-hub.ts +76 -6
- package/src/runtime/auth/route-policy.ts +46 -0
- package/src/runtime/btw-sidechain.ts +0 -6
- package/src/runtime/channel-readiness-service.ts +68 -0
- package/src/runtime/channel-reply-delivery.ts +23 -0
- package/src/runtime/channel-retry-sweep.ts +47 -14
- package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
- package/src/runtime/http-types.ts +0 -2
- package/src/runtime/migrations/vbundle-builder.ts +12 -4
- package/src/runtime/pending-interactions.ts +0 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +204 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +76 -9
- package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
- package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
- package/src/runtime/routes/acp-routes-list.test.ts +3 -0
- package/src/runtime/routes/acp-routes.test.ts +255 -6
- package/src/runtime/routes/acp-routes.ts +8 -1
- package/src/runtime/routes/app-management-routes.ts +111 -4
- package/src/runtime/routes/avatar-routes.ts +10 -10
- package/src/runtime/routes/background-wake-routes.ts +356 -0
- package/src/runtime/routes/browser-tabs-routes.ts +200 -0
- package/src/runtime/routes/btw-routes.ts +4 -10
- package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
- package/src/runtime/routes/conversation-cli-routes.ts +1 -1
- package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
- package/src/runtime/routes/conversation-list-routes.ts +159 -4
- package/src/runtime/routes/conversation-management-routes.ts +108 -26
- package/src/runtime/routes/conversation-query-routes.ts +200 -44
- package/src/runtime/routes/conversation-routes.ts +409 -521
- package/src/runtime/routes/conversation-starter-routes.ts +6 -3
- package/src/runtime/routes/conversations-import-routes.ts +19 -6
- package/src/runtime/routes/disk-pressure-routes.ts +1 -1
- package/src/runtime/routes/documents-routes.ts +10 -1
- package/src/runtime/routes/domain-routes.ts +60 -10
- package/src/runtime/routes/email-routes.ts +5 -2
- package/src/runtime/routes/events-routes.ts +54 -10
- package/src/runtime/routes/group-routes.ts +35 -8
- package/src/runtime/routes/home-feed-routes.ts +129 -0
- package/src/runtime/routes/host-browser-routes.ts +10 -2
- package/src/runtime/routes/host-cu-routes.ts +2 -2
- package/src/runtime/routes/identity-intro-cache.ts +61 -16
- package/src/runtime/routes/identity-routes.ts +30 -9
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
- package/src/runtime/routes/index.ts +10 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
- package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
- package/src/runtime/routes/inference-provider-connection-routes.ts +5 -26
- package/src/runtime/routes/integrations/vercel.ts +15 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
- package/src/runtime/routes/llm-context-normalization.ts +7 -2
- package/src/runtime/routes/memory-item-routes.ts +8 -3
- package/src/runtime/routes/memory-v2-routes.ts +215 -5
- package/src/runtime/routes/memory-v3-routes.ts +474 -0
- package/src/runtime/routes/migration-routes.ts +32 -28
- package/src/runtime/routes/notification-routes.ts +63 -1
- package/src/runtime/routes/oauth-commands-routes.ts +6 -1
- package/src/runtime/routes/plugins-routes.ts +337 -0
- package/src/runtime/routes/rename-conversation-routes.ts +6 -2
- package/src/runtime/routes/secret-routes.ts +25 -5
- package/src/runtime/routes/settings-routes.ts +12 -11
- package/src/runtime/routes/slack-channel-routes.ts +5 -4
- package/src/runtime/routes/surface-action-routes.ts +1 -38
- package/src/runtime/routes/surface-content-routes.ts +12 -5
- package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
- package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
- package/src/runtime/routes/workspace-routes.ts +25 -10
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
- package/src/runtime/slack-dm-text-delivery.ts +177 -0
- package/src/runtime/sync/resource-sync-events.ts +106 -38
- package/src/runtime/sync/sync-publisher.test.ts +49 -0
- package/src/runtime/sync/sync-publisher.ts +2 -1
- package/src/runtime/tool-grant-request-helper.ts +1 -0
- package/src/runtime/verification-outbound-actions.ts +73 -1
- package/src/schedule/schedule-store.ts +8 -1
- package/src/schedule/scheduler.ts +111 -15
- package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
- package/src/security/encrypted-store.ts +7 -16
- package/src/security/store-path-override.ts +61 -0
- package/src/signals/user-message.ts +5 -8
- package/src/skills/validate-input.ts +177 -0
- package/src/subagent/manager.ts +13 -13
- package/src/subagent/types.ts +6 -0
- package/src/tasks/tool-sanitizer.ts +2 -2
- package/src/telemetry/types.ts +12 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/acp/spawn.test.ts +119 -0
- package/src/tools/acp/spawn.ts +15 -2
- package/src/tools/apps/definitions.ts +36 -28
- package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
- package/src/tools/ask-question/ask-question-tool.ts +38 -45
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
- package/src/tools/browser/__tests__/pinned-tabs.test.ts +70 -0
- package/src/tools/browser/browser-execution.ts +16 -3
- package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
- package/src/tools/browser/cdp-client/factory.ts +100 -17
- package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
- package/src/tools/browser/cdp-client/types.ts +65 -0
- package/src/tools/browser/pinned-tabs.ts +96 -40
- package/src/tools/computer-use/definitions.ts +282 -336
- package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
- package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
- package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
- package/src/tools/credentials/vault.ts +3 -9
- package/src/tools/document/document-tool.ts +189 -7
- package/src/tools/execution-target.ts +18 -23
- package/src/tools/executor.ts +24 -56
- package/src/tools/filesystem/edit.ts +3 -9
- package/src/tools/filesystem/list.ts +3 -9
- package/src/tools/filesystem/read.ts +3 -9
- package/src/tools/filesystem/write.ts +3 -9
- package/src/tools/host-filesystem/edit.test.ts +1 -0
- package/src/tools/host-filesystem/edit.ts +3 -9
- package/src/tools/host-filesystem/read.test.ts +1 -0
- package/src/tools/host-filesystem/read.ts +3 -9
- package/src/tools/host-filesystem/transfer.test.ts +31 -6
- package/src/tools/host-filesystem/transfer.ts +3 -9
- package/src/tools/host-filesystem/write.test.ts +1 -0
- package/src/tools/host-filesystem/write.ts +3 -9
- package/src/tools/host-terminal/host-shell.ts +3 -9
- package/src/tools/mcp/mcp-tool-factory.ts +1 -10
- package/src/tools/memory/register.test.ts +1 -1
- package/src/tools/memory/register.ts +4 -9
- package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
- package/src/tools/network/__tests__/web-search.test.ts +211 -3
- package/src/tools/network/managed-search-proxy.ts +183 -0
- package/src/tools/network/web-fetch.ts +3 -9
- package/src/tools/network/web-search.ts +224 -76
- package/src/tools/policy-context.ts +3 -1
- package/src/tools/registry.ts +150 -123
- package/src/tools/schedule/create.ts +1 -1
- package/src/tools/schema-transforms.ts +1 -1
- package/src/tools/skills/execute.ts +3 -9
- package/src/tools/skills/load.ts +3 -9
- package/src/tools/skills/skill-tool-factory.ts +18 -44
- package/src/tools/subagent/notify-parent.ts +3 -9
- package/src/tools/subagent/spawn.ts +3 -0
- package/src/tools/system/request-permission.ts +3 -9
- package/src/tools/terminal/shell.ts +3 -9
- package/src/tools/tool-approval-handler.ts +10 -4
- package/src/tools/tool-defaults.ts +94 -0
- package/src/tools/tool-name-aliases.ts +72 -14
- package/src/tools/types.ts +32 -101
- package/src/tools/ui-surface/definitions.ts +104 -108
- package/src/types/onboarding-context.ts +6 -0
- package/src/usage/attribution.ts +32 -1
- package/src/usage/pricing.ts +23 -0
- package/src/usage/types.ts +12 -0
- package/src/util/browser.ts +7 -2
- package/src/util/logger.ts +16 -7
- package/src/util/platform.ts +7 -2
- package/src/util/sqlite3-runtime.ts +65 -0
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
- package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
- package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
- package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
- package/src/__tests__/message-complete-display-id.test.ts +0 -175
- package/src/daemon/query-complexity-router.ts +0 -75
- package/src/prompts/cache-boundary.ts +0 -8
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type pino from "pino";
|
|
10
|
+
import { v4 as uuid } from "uuid";
|
|
10
11
|
|
|
11
12
|
import type { AgentEvent } from "../agent/loop.js";
|
|
12
13
|
import type {
|
|
@@ -16,12 +17,16 @@ import type {
|
|
|
16
17
|
import { getConfig } from "../config/loader.js";
|
|
17
18
|
import { recordEstimate } from "../context/estimator-calibration.js";
|
|
18
19
|
import { getCalibrationProviderKey } from "../context/token-estimator.js";
|
|
20
|
+
import { projectAssistantMessage } from "../memory/conversation-attention-store.js";
|
|
19
21
|
import {
|
|
22
|
+
deleteMessageById,
|
|
20
23
|
getConversation,
|
|
21
24
|
getMessageById,
|
|
25
|
+
messageMetadataSchema,
|
|
22
26
|
provenanceFromTrustContext,
|
|
23
27
|
updateMessageContent,
|
|
24
28
|
} from "../memory/conversation-crud.js";
|
|
29
|
+
import { indexMessageNow } from "../memory/indexer.js";
|
|
25
30
|
import {
|
|
26
31
|
backfillMessageIdOnLogs,
|
|
27
32
|
buildProviderErrorResponsePayload,
|
|
@@ -40,15 +45,20 @@ import { defaultPersistenceTerminal } from "../plugins/defaults/persistence.js";
|
|
|
40
45
|
import { DEFAULT_TIMEOUTS, runPipeline } from "../plugins/pipeline.js";
|
|
41
46
|
import { getMiddlewaresFor } from "../plugins/registry.js";
|
|
42
47
|
import type {
|
|
43
|
-
PersistAddResult,
|
|
44
48
|
PersistArgs,
|
|
49
|
+
PersistReserveResult,
|
|
45
50
|
PersistResult,
|
|
46
51
|
TurnContext,
|
|
47
52
|
} from "../plugins/types.js";
|
|
48
53
|
import type { ContentBlock, ImageContent } from "../providers/types.js";
|
|
49
54
|
import { isContextOverflowError } from "../providers/types.js";
|
|
55
|
+
import { publishSyncInvalidation } from "../runtime/sync/sync-publisher.js";
|
|
50
56
|
import { redactSecrets } from "../security/secret-scanner.js";
|
|
51
57
|
import { extractDomain } from "../tools/network/domain-normalize.js";
|
|
58
|
+
import {
|
|
59
|
+
buildPricingUsage,
|
|
60
|
+
resolveStructuredPricing,
|
|
61
|
+
} from "../usage/pricing.js";
|
|
52
62
|
import { ProviderError } from "../util/errors.js";
|
|
53
63
|
import { faviconUrlForDomain } from "../util/favicon.js";
|
|
54
64
|
import { getLogger } from "../util/logger.js";
|
|
@@ -62,10 +72,17 @@ import {
|
|
|
62
72
|
buildConversationErrorMessage,
|
|
63
73
|
classifyConversationError,
|
|
64
74
|
isContextTooLarge,
|
|
75
|
+
maxTokensReachedClassification,
|
|
65
76
|
} from "./conversation-error.js";
|
|
66
77
|
import { isProviderOrderingError } from "./conversation-slash.js";
|
|
67
78
|
import { resolveTurnTimezoneContext } from "./date-context.js";
|
|
68
|
-
import type {
|
|
79
|
+
import type {
|
|
80
|
+
CardSurfaceData,
|
|
81
|
+
ServerMessage,
|
|
82
|
+
SurfaceAction,
|
|
83
|
+
UiSurfaceShow,
|
|
84
|
+
} from "./message-protocol.js";
|
|
85
|
+
import { conversationMetadataSyncTag } from "./message-types/sync.js";
|
|
69
86
|
import type {
|
|
70
87
|
WebSearchMetadata,
|
|
71
88
|
WebSearchResultItem,
|
|
@@ -144,12 +161,22 @@ export interface EventHandlerState {
|
|
|
144
161
|
*/
|
|
145
162
|
contextTooLargeError: unknown;
|
|
146
163
|
providerErrorUserMessage: string | null;
|
|
164
|
+
lastAssistantMessageId: string | undefined;
|
|
147
165
|
/**
|
|
148
|
-
*
|
|
149
|
-
*
|
|
166
|
+
* True when `handleLlmCallStarted` has reserved an empty assistant row
|
|
167
|
+
* that has NOT yet been finalized via `handleMessageComplete`
|
|
168
|
+
* (`op:"updateContent"` + indexing + projection). Used by error/retry
|
|
169
|
+
* paths to detect a stranded reservation that must be cleaned up
|
|
170
|
+
* before the next LLM call reserves a fresh row — without it, every
|
|
171
|
+
* retryable failure (overflow, ordering, image overflow) and every
|
|
172
|
+
* terminal provider rejection would leak an empty assistant bubble
|
|
173
|
+
* into the transcript and mispoint downstream sync/projection.
|
|
174
|
+
*
|
|
175
|
+
* Cleared by `handleMessageComplete` on successful finalize, and by
|
|
176
|
+
* the synthetic-error branch in `conversation-agent-loop.ts` after it
|
|
177
|
+
* absorbs the reserved row into the error message.
|
|
150
178
|
*/
|
|
151
|
-
|
|
152
|
-
lastAssistantMessageId: string | undefined;
|
|
179
|
+
assistantRowAwaitingFinalization: boolean;
|
|
153
180
|
readonly pendingToolResults: Map<string, PendingToolResult>;
|
|
154
181
|
readonly persistedToolUseIds: Set<string>;
|
|
155
182
|
readonly accumulatedDirectives: DirectiveRequest[];
|
|
@@ -249,8 +276,8 @@ export function createEventHandlerState(): EventHandlerState {
|
|
|
249
276
|
imageTooLargeDetected: false,
|
|
250
277
|
contextTooLargeError: null,
|
|
251
278
|
providerErrorUserMessage: null,
|
|
252
|
-
firstAssistantMessageId: undefined,
|
|
253
279
|
lastAssistantMessageId: undefined,
|
|
280
|
+
assistantRowAwaitingFinalization: false,
|
|
254
281
|
pendingToolResults: new Map(),
|
|
255
282
|
persistedToolUseIds: new Set(),
|
|
256
283
|
accumulatedDirectives: [],
|
|
@@ -275,12 +302,6 @@ export function createEventHandlerState(): EventHandlerState {
|
|
|
275
302
|
};
|
|
276
303
|
}
|
|
277
304
|
|
|
278
|
-
export function getClientDisplayMessageId(
|
|
279
|
-
state: EventHandlerState,
|
|
280
|
-
): string | undefined {
|
|
281
|
-
return state.firstAssistantMessageId ?? state.lastAssistantMessageId;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
305
|
// ── Shared Helper ────────────────────────────────────────────────────
|
|
285
306
|
|
|
286
307
|
// providerNameOverride should be supplied when the caller already knows the
|
|
@@ -319,6 +340,9 @@ function emitLlmCallStartedIfNeeded(
|
|
|
319
340
|
// tools the client discards it (extractCodePreview only handles app tools),
|
|
320
341
|
// so we skip forwarding entirely to avoid transport/decode overhead.
|
|
321
342
|
const APP_TOOL_NAMES = new Set(["app_create"]);
|
|
343
|
+
const MAX_TOKENS_CONTINUE_PROMPT =
|
|
344
|
+
"Continue from where you stopped. Do not repeat content you've already sent.";
|
|
345
|
+
const MAX_TOKENS_SURFACE_COMPLETION_SUMMARY = "Continue";
|
|
322
346
|
|
|
323
347
|
// ── Friendly Tool Names ──────────────────────────────────────────────
|
|
324
348
|
|
|
@@ -401,6 +425,133 @@ function resolveAssistantReplyTimestampTimezone(
|
|
|
401
425
|
}).effectiveTimezone;
|
|
402
426
|
}
|
|
403
427
|
|
|
428
|
+
/**
|
|
429
|
+
* Assemble the metadata envelope written to the assistant message row.
|
|
430
|
+
*
|
|
431
|
+
* Stamped at reserve time (before `provider.sendMessage`) so the row carries
|
|
432
|
+
* channel provenance from the moment it lands in SQLite, mirroring the
|
|
433
|
+
* snapshot that handleMessageComplete used to compute at end-of-turn. All
|
|
434
|
+
* inputs (channel context, trust context, turnStartedAt) are stable across
|
|
435
|
+
* the LLM call, so building this once at reserve is equivalent to building
|
|
436
|
+
* it at complete. Slack reply rows further stamp a `slackMeta` sub-object —
|
|
437
|
+
* the `channelTs` field stays absent here and is back-filled by
|
|
438
|
+
* `deliverReplyViaCallback` after the gateway returns the ts.
|
|
439
|
+
*/
|
|
440
|
+
function buildAssistantChannelMetadata(
|
|
441
|
+
state: EventHandlerState,
|
|
442
|
+
deps: EventHandlerDeps,
|
|
443
|
+
): Record<string, unknown> {
|
|
444
|
+
const metadata: Record<string, unknown> = {
|
|
445
|
+
...provenanceFromTrustContext(deps.ctx.trustContext),
|
|
446
|
+
userMessageChannel: deps.turnChannelContext.userMessageChannel,
|
|
447
|
+
assistantMessageChannel: deps.turnChannelContext.assistantMessageChannel,
|
|
448
|
+
userMessageInterface: deps.turnInterfaceContext.userMessageInterface,
|
|
449
|
+
assistantMessageInterface:
|
|
450
|
+
deps.turnInterfaceContext.assistantMessageInterface,
|
|
451
|
+
sentAt: state.turnStartedAt,
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
if (deps.turnChannelContext.assistantMessageChannel === "slack") {
|
|
455
|
+
const channelId = deps.ctx.trustContext?.requesterChatId;
|
|
456
|
+
if (channelId) {
|
|
457
|
+
const threadTs = getThreadTs(deps.ctx.conversationId);
|
|
458
|
+
const timestampTimezone = resolveAssistantReplyTimestampTimezone(
|
|
459
|
+
deps.ctx,
|
|
460
|
+
);
|
|
461
|
+
const timestampTimezoneLabel = formatSlackTimezoneLabel(
|
|
462
|
+
timestampTimezone,
|
|
463
|
+
{ nowMs: state.turnStartedAt },
|
|
464
|
+
);
|
|
465
|
+
const partialSlackMeta: Partial<SlackMessageMetadata> = {
|
|
466
|
+
source: "slack",
|
|
467
|
+
eventKind: "message",
|
|
468
|
+
channelId,
|
|
469
|
+
...(threadTs ? { threadTs } : {}),
|
|
470
|
+
timestampTimezone,
|
|
471
|
+
...(timestampTimezoneLabel ? { timestampTimezoneLabel } : {}),
|
|
472
|
+
};
|
|
473
|
+
// `channelTs` is filled in by the post-send reconciliation step in
|
|
474
|
+
// `deliverReplyViaCallback`; cast through the Partial to satisfy
|
|
475
|
+
// the writer's type at this pre-send boundary.
|
|
476
|
+
metadata.slackMeta = writeSlackMetadata(
|
|
477
|
+
partialSlackMeta as SlackMessageMetadata,
|
|
478
|
+
);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
return metadata;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Reserve an empty assistant row for the LLM call about to begin, stash
|
|
487
|
+
* its id on `state.lastAssistantMessageId`, and announce the boundary on
|
|
488
|
+
* the wire via `assistant_turn_start`.
|
|
489
|
+
*
|
|
490
|
+
* Awaited so the row exists and the client has the anchor id BEFORE any
|
|
491
|
+
* streaming delta arrives — every subsequent `deps.onEvent` in this LLM
|
|
492
|
+
* call stamps `messageId: state.lastAssistantMessageId`, and
|
|
493
|
+
* `handleMessageComplete` flushes the final content to the same row via
|
|
494
|
+
* `op: "updateContent"` instead of inserting a fresh one.
|
|
495
|
+
*
|
|
496
|
+
* Multi-LLM-call agent turns (LLM call → tool execution → LLM call) emit
|
|
497
|
+
* one `llm_call_started` per call, so each LLM call reserves its own row.
|
|
498
|
+
* The read-path `findDisplayTurnEndIndex` collapses consecutive assistant
|
|
499
|
+
* rows for the merged history view, matching today's per-call DB layout.
|
|
500
|
+
*/
|
|
501
|
+
export async function handleLlmCallStarted(
|
|
502
|
+
state: EventHandlerState,
|
|
503
|
+
deps: EventHandlerDeps,
|
|
504
|
+
): Promise<void> {
|
|
505
|
+
// Clean up an orphaned reservation from a previous LLM call in this run
|
|
506
|
+
// that errored before `message_complete` could finalize it. This covers
|
|
507
|
+
// the retryable paths (overflow, ordering, image overflow) where the
|
|
508
|
+
// agent loop re-enters with a fresh `run()` and reserves another row;
|
|
509
|
+
// without this delete the failed-attempt row stays in the transcript as
|
|
510
|
+
// an empty assistant bubble. The finalized-row case is filtered out via
|
|
511
|
+
// the `assistantRowAwaitingFinalization` flag — `handleMessageComplete`
|
|
512
|
+
// clears it after the successful `updateContent`, so the previous call's
|
|
513
|
+
// committed row is never touched here.
|
|
514
|
+
//
|
|
515
|
+
// Direct `deleteMessageById` (not via the `persistence` pipeline) is
|
|
516
|
+
// intentional: a never-finalized reservation has no segments, no
|
|
517
|
+
// attachments, and no observable history — undoing it isn't a real
|
|
518
|
+
// persistence event for plugins to react to, so routing through the
|
|
519
|
+
// pipeline would only widen the mock surface for no observability win.
|
|
520
|
+
if (state.assistantRowAwaitingFinalization && state.lastAssistantMessageId) {
|
|
521
|
+
try {
|
|
522
|
+
deleteMessageById(state.lastAssistantMessageId);
|
|
523
|
+
} catch (err) {
|
|
524
|
+
// Non-fatal: a leaked empty row is preferable to a turn-level throw.
|
|
525
|
+
deps.rlog.warn(
|
|
526
|
+
{ err, messageId: state.lastAssistantMessageId },
|
|
527
|
+
"Failed to clean up stranded reserved assistant row before new reservation",
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
const metadata = buildAssistantChannelMetadata(state, deps);
|
|
533
|
+
const reserveResult = (await runPipeline<PersistArgs, PersistResult>(
|
|
534
|
+
"persistence",
|
|
535
|
+
getMiddlewaresFor("persistence"),
|
|
536
|
+
defaultPersistenceTerminal,
|
|
537
|
+
{
|
|
538
|
+
op: "reserve",
|
|
539
|
+
conversationId: deps.ctx.conversationId,
|
|
540
|
+
role: "assistant",
|
|
541
|
+
metadata,
|
|
542
|
+
},
|
|
543
|
+
buildHandlerTurnContext(deps),
|
|
544
|
+
DEFAULT_TIMEOUTS.persistence,
|
|
545
|
+
)) as PersistReserveResult;
|
|
546
|
+
state.lastAssistantMessageId = reserveResult.message.id;
|
|
547
|
+
state.assistantRowAwaitingFinalization = true;
|
|
548
|
+
deps.onEvent({
|
|
549
|
+
type: "assistant_turn_start",
|
|
550
|
+
messageId: reserveResult.message.id,
|
|
551
|
+
conversationId: deps.ctx.conversationId,
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
|
|
404
555
|
// ── Individual Handlers ──────────────────────────────────────────────
|
|
405
556
|
|
|
406
557
|
function handleTextDelta(
|
|
@@ -429,6 +580,7 @@ function handleTextDelta(
|
|
|
429
580
|
type: "assistant_text_delta",
|
|
430
581
|
text: drained.emitText,
|
|
431
582
|
conversationId: deps.ctx.conversationId,
|
|
583
|
+
messageId: state.lastAssistantMessageId,
|
|
432
584
|
});
|
|
433
585
|
if (deps.shouldGenerateTitle) state.firstAssistantText += drained.emitText;
|
|
434
586
|
}
|
|
@@ -466,6 +618,7 @@ function handleThinkingDelta(
|
|
|
466
618
|
type: "assistant_thinking_delta",
|
|
467
619
|
thinking: event.thinking,
|
|
468
620
|
conversationId: deps.ctx.conversationId,
|
|
621
|
+
messageId: state.lastAssistantMessageId,
|
|
469
622
|
});
|
|
470
623
|
}
|
|
471
624
|
|
|
@@ -496,11 +649,12 @@ export function handleToolUse(
|
|
|
496
649
|
input: event.input,
|
|
497
650
|
conversationId: deps.ctx.conversationId,
|
|
498
651
|
toolUseId: event.id,
|
|
652
|
+
messageId: state.lastAssistantMessageId,
|
|
499
653
|
});
|
|
500
654
|
}
|
|
501
655
|
|
|
502
656
|
export function handleToolUsePreviewStart(
|
|
503
|
-
|
|
657
|
+
state: EventHandlerState,
|
|
504
658
|
deps: EventHandlerDeps,
|
|
505
659
|
event: Extract<AgentEvent, { type: "tool_use_preview_start" }>,
|
|
506
660
|
): void {
|
|
@@ -509,6 +663,7 @@ export function handleToolUsePreviewStart(
|
|
|
509
663
|
toolUseId: event.toolUseId,
|
|
510
664
|
toolName: event.toolName,
|
|
511
665
|
conversationId: deps.ctx.conversationId,
|
|
666
|
+
messageId: state.lastAssistantMessageId,
|
|
512
667
|
});
|
|
513
668
|
const statusText = `Preparing ${friendlyToolName(event.toolName)}...`;
|
|
514
669
|
deps.ctx.emitActivityState(
|
|
@@ -521,7 +676,7 @@ export function handleToolUsePreviewStart(
|
|
|
521
676
|
}
|
|
522
677
|
|
|
523
678
|
function handleToolOutputChunk(
|
|
524
|
-
|
|
679
|
+
state: EventHandlerState,
|
|
525
680
|
deps: EventHandlerDeps,
|
|
526
681
|
event: Extract<AgentEvent, { type: "tool_output_chunk" }>,
|
|
527
682
|
): void {
|
|
@@ -579,6 +734,7 @@ function handleToolOutputChunk(
|
|
|
579
734
|
chunk: event.chunk,
|
|
580
735
|
conversationId: deps.ctx.conversationId,
|
|
581
736
|
toolUseId: event.toolUseId,
|
|
737
|
+
messageId: state.lastAssistantMessageId,
|
|
582
738
|
subType: structured.subType,
|
|
583
739
|
subToolName: structured.subToolName,
|
|
584
740
|
subToolInput: structured.subToolInput,
|
|
@@ -591,12 +747,13 @@ function handleToolOutputChunk(
|
|
|
591
747
|
chunk: event.chunk,
|
|
592
748
|
conversationId: deps.ctx.conversationId,
|
|
593
749
|
toolUseId: event.toolUseId,
|
|
750
|
+
messageId: state.lastAssistantMessageId,
|
|
594
751
|
});
|
|
595
752
|
}
|
|
596
753
|
}
|
|
597
754
|
|
|
598
755
|
export function handleInputJsonDelta(
|
|
599
|
-
|
|
756
|
+
state: EventHandlerState,
|
|
600
757
|
deps: EventHandlerDeps,
|
|
601
758
|
event: Extract<AgentEvent, { type: "input_json_delta" }>,
|
|
602
759
|
): void {
|
|
@@ -610,6 +767,7 @@ export function handleInputJsonDelta(
|
|
|
610
767
|
content: event.accumulatedJson,
|
|
611
768
|
conversationId: deps.ctx.conversationId,
|
|
612
769
|
toolUseId: event.toolUseId,
|
|
770
|
+
messageId: state.lastAssistantMessageId,
|
|
613
771
|
});
|
|
614
772
|
}
|
|
615
773
|
|
|
@@ -736,6 +894,7 @@ export function handleToolResult(
|
|
|
736
894
|
diff: event.diff,
|
|
737
895
|
status: event.status,
|
|
738
896
|
conversationId: deps.ctx.conversationId,
|
|
897
|
+
messageId: state.lastAssistantMessageId,
|
|
739
898
|
imageData: imageDataList?.[0],
|
|
740
899
|
imageDataList,
|
|
741
900
|
toolUseId: event.toolUseId,
|
|
@@ -915,6 +1074,69 @@ function handleError(
|
|
|
915
1074
|
}
|
|
916
1075
|
}
|
|
917
1076
|
|
|
1077
|
+
export function handleMaxTokensReached(
|
|
1078
|
+
_state: EventHandlerState,
|
|
1079
|
+
deps: EventHandlerDeps,
|
|
1080
|
+
event: Extract<AgentEvent, { type: "max_tokens_reached" }>,
|
|
1081
|
+
): void {
|
|
1082
|
+
const classified = maxTokensReachedClassification();
|
|
1083
|
+
const surfaceId = `max_tokens_${uuid()}`;
|
|
1084
|
+
const data: CardSurfaceData = {
|
|
1085
|
+
title: "Response limit reached",
|
|
1086
|
+
subtitle: "The partial response above was saved.",
|
|
1087
|
+
body: classified.userMessage,
|
|
1088
|
+
};
|
|
1089
|
+
const actions: SurfaceAction[] = [
|
|
1090
|
+
{
|
|
1091
|
+
id: "relay_prompt",
|
|
1092
|
+
label: "Continue",
|
|
1093
|
+
style: "primary",
|
|
1094
|
+
data: {
|
|
1095
|
+
prompt: MAX_TOKENS_CONTINUE_PROMPT,
|
|
1096
|
+
_completeSurface: true,
|
|
1097
|
+
_completionSummary: MAX_TOKENS_SURFACE_COMPLETION_SUMMARY,
|
|
1098
|
+
},
|
|
1099
|
+
},
|
|
1100
|
+
];
|
|
1101
|
+
|
|
1102
|
+
deps.ctx.surfaceState.set(surfaceId, {
|
|
1103
|
+
surfaceType: "card",
|
|
1104
|
+
title: data.title,
|
|
1105
|
+
data,
|
|
1106
|
+
actions,
|
|
1107
|
+
});
|
|
1108
|
+
deps.ctx.currentTurnSurfaces.push({
|
|
1109
|
+
surfaceId,
|
|
1110
|
+
surfaceType: "card",
|
|
1111
|
+
title: data.title,
|
|
1112
|
+
data,
|
|
1113
|
+
actions,
|
|
1114
|
+
display: "inline",
|
|
1115
|
+
persistent: true,
|
|
1116
|
+
});
|
|
1117
|
+
|
|
1118
|
+
deps.rlog.warn(
|
|
1119
|
+
{
|
|
1120
|
+
conversationId: deps.ctx.conversationId,
|
|
1121
|
+
stopReason: event.stopReason,
|
|
1122
|
+
surfaceId,
|
|
1123
|
+
},
|
|
1124
|
+
"Surfacing max-tokens continuation card",
|
|
1125
|
+
);
|
|
1126
|
+
|
|
1127
|
+
deps.onEvent({
|
|
1128
|
+
type: "ui_surface_show",
|
|
1129
|
+
conversationId: deps.ctx.conversationId,
|
|
1130
|
+
surfaceId,
|
|
1131
|
+
surfaceType: "card",
|
|
1132
|
+
title: data.title,
|
|
1133
|
+
data,
|
|
1134
|
+
actions,
|
|
1135
|
+
display: "inline",
|
|
1136
|
+
persistent: true,
|
|
1137
|
+
} as UiSurfaceShow);
|
|
1138
|
+
}
|
|
1139
|
+
|
|
918
1140
|
export async function handleMessageComplete(
|
|
919
1141
|
state: EventHandlerState,
|
|
920
1142
|
deps: EventHandlerDeps,
|
|
@@ -929,6 +1151,7 @@ export async function handleMessageComplete(
|
|
|
929
1151
|
type: "assistant_text_delta",
|
|
930
1152
|
text: state.pendingDirectiveDisplayBuffer,
|
|
931
1153
|
conversationId: deps.ctx.conversationId,
|
|
1154
|
+
messageId: state.lastAssistantMessageId,
|
|
932
1155
|
});
|
|
933
1156
|
if (deps.shouldGenerateTitle)
|
|
934
1157
|
state.firstAssistantText += state.pendingDirectiveDisplayBuffer;
|
|
@@ -1035,52 +1258,6 @@ export async function handleMessageComplete(
|
|
|
1035
1258
|
} as unknown as ContentBlock);
|
|
1036
1259
|
}
|
|
1037
1260
|
|
|
1038
|
-
const assistantChannelMetadata: Record<string, unknown> = {
|
|
1039
|
-
...provenanceFromTrustContext(deps.ctx.trustContext),
|
|
1040
|
-
userMessageChannel: deps.turnChannelContext.userMessageChannel,
|
|
1041
|
-
assistantMessageChannel: deps.turnChannelContext.assistantMessageChannel,
|
|
1042
|
-
userMessageInterface: deps.turnInterfaceContext.userMessageInterface,
|
|
1043
|
-
assistantMessageInterface:
|
|
1044
|
-
deps.turnInterfaceContext.assistantMessageInterface,
|
|
1045
|
-
sentAt: state.turnStartedAt,
|
|
1046
|
-
};
|
|
1047
|
-
|
|
1048
|
-
// When the assistant is replying through Slack, stamp a `slackMeta`
|
|
1049
|
-
// sub-object so the transcript-rendering / thread-aware-context lookup
|
|
1050
|
-
// can identify this row's thread without joining tables.
|
|
1051
|
-
// Persistence happens BEFORE the Slack adapter sends the message, so
|
|
1052
|
-
// Slack's authoritative `ts` (-> `channelTs`) is not yet known and is
|
|
1053
|
-
// intentionally omitted here. The post-send reconciliation step in
|
|
1054
|
-
// `deliverReplyViaCallback` writes `channelTs` back into this row once
|
|
1055
|
-
// the gateway returns the Slack-assigned ts, restoring a fully-formed
|
|
1056
|
-
// metadata envelope before any subsequent turn reads the row.
|
|
1057
|
-
if (deps.turnChannelContext.assistantMessageChannel === "slack") {
|
|
1058
|
-
const channelId = deps.ctx.trustContext?.requesterChatId;
|
|
1059
|
-
if (channelId) {
|
|
1060
|
-
const threadTs = getThreadTs(deps.ctx.conversationId);
|
|
1061
|
-
const timestampTimezone = resolveAssistantReplyTimestampTimezone(
|
|
1062
|
-
deps.ctx,
|
|
1063
|
-
);
|
|
1064
|
-
const timestampTimezoneLabel = formatSlackTimezoneLabel(
|
|
1065
|
-
timestampTimezone,
|
|
1066
|
-
{ nowMs: state.turnStartedAt },
|
|
1067
|
-
);
|
|
1068
|
-
const partialSlackMeta: Partial<SlackMessageMetadata> = {
|
|
1069
|
-
source: "slack",
|
|
1070
|
-
eventKind: "message",
|
|
1071
|
-
channelId,
|
|
1072
|
-
...(threadTs ? { threadTs } : {}),
|
|
1073
|
-
timestampTimezone,
|
|
1074
|
-
...(timestampTimezoneLabel ? { timestampTimezoneLabel } : {}),
|
|
1075
|
-
};
|
|
1076
|
-
assistantChannelMetadata.slackMeta = writeSlackMetadata(
|
|
1077
|
-
// `channelTs` is filled in by the post-send reconciliation step in
|
|
1078
|
-
// `deliverReplyViaCallback`; cast through the Partial to satisfy
|
|
1079
|
-
// the writer's type at this pre-send boundary.
|
|
1080
|
-
partialSlackMeta as SlackMessageMetadata,
|
|
1081
|
-
);
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
1261
|
// Redact known-pattern secrets from assistant text blocks before they are
|
|
1085
1262
|
// written to durable storage. Non-text blocks (images, UI surfaces) pass
|
|
1086
1263
|
// through unchanged. The live model history retains the original values.
|
|
@@ -1092,33 +1269,123 @@ export async function handleMessageComplete(
|
|
|
1092
1269
|
return block;
|
|
1093
1270
|
});
|
|
1094
1271
|
|
|
1095
|
-
//
|
|
1096
|
-
//
|
|
1097
|
-
//
|
|
1098
|
-
//
|
|
1099
|
-
|
|
1272
|
+
// The row was reserved at `llm_call_started` (with channel metadata
|
|
1273
|
+
// stamped at that point) and `state.lastAssistantMessageId` carries its
|
|
1274
|
+
// id. Flush the final content via `updateContent` instead of inserting a
|
|
1275
|
+
// new row. No `syncToDisk` flag here — the orchestrator separately
|
|
1276
|
+
// invokes `syncMessageToDisk` on `state.lastAssistantMessageId` after
|
|
1277
|
+
// the loop completes (see
|
|
1278
|
+
// `conversation-agent-loop.ts::syncLastAssistantMessageToDisk`).
|
|
1279
|
+
const assistantMessageId = state.lastAssistantMessageId;
|
|
1280
|
+
if (!assistantMessageId) {
|
|
1281
|
+
throw new Error(
|
|
1282
|
+
"handleMessageComplete fired without a prior llm_call_started reserving an assistant row",
|
|
1283
|
+
);
|
|
1284
|
+
}
|
|
1285
|
+
const contentJson = JSON.stringify(contentForPersistence);
|
|
1286
|
+
await runPipeline<PersistArgs, PersistResult>(
|
|
1100
1287
|
"persistence",
|
|
1101
1288
|
getMiddlewaresFor("persistence"),
|
|
1102
1289
|
defaultPersistenceTerminal,
|
|
1103
1290
|
{
|
|
1104
|
-
op: "
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
content: JSON.stringify(contentForPersistence),
|
|
1108
|
-
metadata: assistantChannelMetadata,
|
|
1291
|
+
op: "updateContent",
|
|
1292
|
+
messageId: assistantMessageId,
|
|
1293
|
+
content: contentJson,
|
|
1109
1294
|
},
|
|
1110
1295
|
buildHandlerTurnContext(deps),
|
|
1111
1296
|
DEFAULT_TIMEOUTS.persistence,
|
|
1112
|
-
)
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1297
|
+
);
|
|
1298
|
+
state.assistantRowAwaitingFinalization = false;
|
|
1299
|
+
|
|
1300
|
+
// ── Indexing + attention projection (restored from the pre-B3 `add` path) ──
|
|
1301
|
+
// `reserveMessage` + `updateMessageContent` are CRUD-only: they don't run
|
|
1302
|
+
// the memory indexer or the attention-cursor projector. The pre-B3 path
|
|
1303
|
+
// wrote the row via `addMessage`, which ran both as side-effects of the
|
|
1304
|
+
// insert. Calling them here keeps the assistant row's external state
|
|
1305
|
+
// (Qdrant segments, conversation attention cursor) in lockstep with the
|
|
1306
|
+
// finalized content. Both are non-fatal — a memory hiccup must not
|
|
1307
|
+
// escalate a successful generation into a turn-level throw. Indexing
|
|
1308
|
+
// intentionally fires AFTER `updateContent` succeeds so we never index
|
|
1309
|
+
// the empty reserved placeholder.
|
|
1310
|
+
const finalizedRow = getMessageById(
|
|
1311
|
+
assistantMessageId,
|
|
1312
|
+
deps.ctx.conversationId,
|
|
1313
|
+
);
|
|
1314
|
+
if (finalizedRow) {
|
|
1315
|
+
let provenanceTrustClass:
|
|
1316
|
+
| "guardian"
|
|
1317
|
+
| "trusted_contact"
|
|
1318
|
+
| "unknown"
|
|
1319
|
+
| undefined;
|
|
1320
|
+
let automated: boolean | undefined;
|
|
1321
|
+
if (finalizedRow.metadata) {
|
|
1322
|
+
try {
|
|
1323
|
+
const parsedMeta = messageMetadataSchema.safeParse(
|
|
1324
|
+
JSON.parse(finalizedRow.metadata),
|
|
1325
|
+
);
|
|
1326
|
+
if (parsedMeta.success) {
|
|
1327
|
+
provenanceTrustClass = parsedMeta.data.provenanceTrustClass;
|
|
1328
|
+
automated = parsedMeta.data.automated;
|
|
1329
|
+
}
|
|
1330
|
+
} catch {
|
|
1331
|
+
// Malformed metadata JSON — fall through with undefined fields,
|
|
1332
|
+
// matching the legacy behavior in `addMessage`.
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
try {
|
|
1336
|
+
await indexMessageNow(
|
|
1337
|
+
{
|
|
1338
|
+
messageId: assistantMessageId,
|
|
1339
|
+
conversationId: deps.ctx.conversationId,
|
|
1340
|
+
role: "assistant",
|
|
1341
|
+
content: contentJson,
|
|
1342
|
+
createdAt: finalizedRow.createdAt,
|
|
1343
|
+
scopeId: "default",
|
|
1344
|
+
provenanceTrustClass,
|
|
1345
|
+
automated,
|
|
1346
|
+
},
|
|
1347
|
+
getConfig().memory,
|
|
1348
|
+
);
|
|
1349
|
+
} catch (err) {
|
|
1350
|
+
deps.rlog.warn(
|
|
1351
|
+
{
|
|
1352
|
+
err,
|
|
1353
|
+
conversationId: deps.ctx.conversationId,
|
|
1354
|
+
messageId: assistantMessageId,
|
|
1355
|
+
},
|
|
1356
|
+
"Failed to index assistant message for memory (non-fatal)",
|
|
1357
|
+
);
|
|
1358
|
+
}
|
|
1359
|
+
try {
|
|
1360
|
+
const attentionStateChanged = projectAssistantMessage({
|
|
1361
|
+
conversationId: deps.ctx.conversationId,
|
|
1362
|
+
messageId: assistantMessageId,
|
|
1363
|
+
messageAt: finalizedRow.createdAt,
|
|
1364
|
+
});
|
|
1365
|
+
if (attentionStateChanged) {
|
|
1366
|
+
void publishSyncInvalidation([
|
|
1367
|
+
conversationMetadataSyncTag(deps.ctx.conversationId),
|
|
1368
|
+
]);
|
|
1369
|
+
}
|
|
1370
|
+
} catch (err) {
|
|
1371
|
+
deps.rlog.warn(
|
|
1372
|
+
{
|
|
1373
|
+
err,
|
|
1374
|
+
conversationId: deps.ctx.conversationId,
|
|
1375
|
+
messageId: assistantMessageId,
|
|
1376
|
+
},
|
|
1377
|
+
"Failed to project assistant message for attention tracking (non-fatal)",
|
|
1378
|
+
);
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1116
1381
|
|
|
1117
1382
|
// Backfill message_id on all LLM request logs from this turn.
|
|
1118
1383
|
// The agent loop is single-threaded per conversation, so all rows with
|
|
1119
|
-
// message_id IS NULL belong to the current turn.
|
|
1384
|
+
// message_id IS NULL belong to the current turn. The reserved id was
|
|
1385
|
+
// available before the LLM call ran but the logs are inserted DURING
|
|
1386
|
+
// the call, so the sweep still runs here.
|
|
1120
1387
|
try {
|
|
1121
|
-
backfillMessageIdOnLogs(deps.ctx.conversationId,
|
|
1388
|
+
backfillMessageIdOnLogs(deps.ctx.conversationId, assistantMessageId);
|
|
1122
1389
|
} catch (err) {
|
|
1123
1390
|
deps.rlog.warn(
|
|
1124
1391
|
{ err },
|
|
@@ -1127,7 +1394,10 @@ export async function handleMessageComplete(
|
|
|
1127
1394
|
}
|
|
1128
1395
|
|
|
1129
1396
|
try {
|
|
1130
|
-
backfillMemoryRecallLogMessageId(
|
|
1397
|
+
backfillMemoryRecallLogMessageId(
|
|
1398
|
+
deps.ctx.conversationId,
|
|
1399
|
+
assistantMessageId,
|
|
1400
|
+
);
|
|
1131
1401
|
} catch (err) {
|
|
1132
1402
|
deps.rlog.warn(
|
|
1133
1403
|
{ err },
|
|
@@ -1138,7 +1408,7 @@ export async function handleMessageComplete(
|
|
|
1138
1408
|
try {
|
|
1139
1409
|
backfillMemoryV2ActivationMessageId(
|
|
1140
1410
|
deps.ctx.conversationId,
|
|
1141
|
-
|
|
1411
|
+
assistantMessageId,
|
|
1142
1412
|
);
|
|
1143
1413
|
} catch (err) {
|
|
1144
1414
|
deps.rlog.warn(
|
|
@@ -1222,6 +1492,7 @@ function handleUsage(
|
|
|
1222
1492
|
JSON.stringify(event.rawResponse),
|
|
1223
1493
|
undefined,
|
|
1224
1494
|
providerName,
|
|
1495
|
+
"mainAgent",
|
|
1225
1496
|
);
|
|
1226
1497
|
} catch (err) {
|
|
1227
1498
|
deps.rlog.warn({ err }, "Failed to persist LLM request log (non-fatal)");
|
|
@@ -1248,6 +1519,36 @@ function handleUsage(
|
|
|
1248
1519
|
},
|
|
1249
1520
|
);
|
|
1250
1521
|
state.llmCallStartedEmitted = false;
|
|
1522
|
+
|
|
1523
|
+
// Emit a lightweight per-call usage progress event so clients can show
|
|
1524
|
+
// live-updating token/cost metrics. This is a UI hint only — no DB writes.
|
|
1525
|
+
const pricingUsage = buildPricingUsage({
|
|
1526
|
+
providerName,
|
|
1527
|
+
model: event.model,
|
|
1528
|
+
inputTokens: event.inputTokens,
|
|
1529
|
+
outputTokens: event.outputTokens,
|
|
1530
|
+
cacheCreationInputTokens: event.cacheCreationInputTokens,
|
|
1531
|
+
cacheReadInputTokens: event.cacheReadInputTokens,
|
|
1532
|
+
rawResponse: event.rawResponse,
|
|
1533
|
+
});
|
|
1534
|
+
const pricing = resolveStructuredPricing(
|
|
1535
|
+
providerName,
|
|
1536
|
+
event.model,
|
|
1537
|
+
pricingUsage,
|
|
1538
|
+
);
|
|
1539
|
+
const estimatedCost =
|
|
1540
|
+
pricing.pricingStatus === "priced" && pricing.estimatedCostUsd != null
|
|
1541
|
+
? pricing.estimatedCostUsd
|
|
1542
|
+
: 0;
|
|
1543
|
+
|
|
1544
|
+
deps.onEvent({
|
|
1545
|
+
type: "usage_progress",
|
|
1546
|
+
conversationId: deps.ctx.conversationId,
|
|
1547
|
+
inputTokens: event.inputTokens,
|
|
1548
|
+
outputTokens: event.outputTokens,
|
|
1549
|
+
estimatedCost,
|
|
1550
|
+
model: event.model,
|
|
1551
|
+
});
|
|
1251
1552
|
}
|
|
1252
1553
|
|
|
1253
1554
|
/**
|
|
@@ -1287,6 +1588,7 @@ function handleProviderError(
|
|
|
1287
1588
|
JSON.stringify(buildProviderErrorResponsePayload(event.error)),
|
|
1288
1589
|
undefined,
|
|
1289
1590
|
event.actualProvider,
|
|
1591
|
+
"mainAgent",
|
|
1290
1592
|
);
|
|
1291
1593
|
} catch (err) {
|
|
1292
1594
|
deps.rlog.warn(
|
|
@@ -1306,6 +1608,9 @@ export async function dispatchAgentEvent(
|
|
|
1306
1608
|
): Promise<void> {
|
|
1307
1609
|
try {
|
|
1308
1610
|
switch (event.type) {
|
|
1611
|
+
case "llm_call_started":
|
|
1612
|
+
await handleLlmCallStarted(state, deps);
|
|
1613
|
+
break;
|
|
1309
1614
|
case "text_delta":
|
|
1310
1615
|
handleTextDelta(state, deps, event);
|
|
1311
1616
|
break;
|
|
@@ -1346,6 +1651,7 @@ export async function dispatchAgentEvent(
|
|
|
1346
1651
|
input: event.input,
|
|
1347
1652
|
conversationId: deps.ctx.conversationId,
|
|
1348
1653
|
toolUseId: event.toolUseId,
|
|
1654
|
+
messageId: state.lastAssistantMessageId,
|
|
1349
1655
|
});
|
|
1350
1656
|
break;
|
|
1351
1657
|
}
|
|
@@ -1425,6 +1731,7 @@ export async function dispatchAgentEvent(
|
|
|
1425
1731
|
isError: event.isError,
|
|
1426
1732
|
conversationId: deps.ctx.conversationId,
|
|
1427
1733
|
toolUseId: event.toolUseId,
|
|
1734
|
+
messageId: state.lastAssistantMessageId,
|
|
1428
1735
|
...(metadata ? { activityMetadata: { webSearch: metadata } } : {}),
|
|
1429
1736
|
});
|
|
1430
1737
|
break;
|
|
@@ -1432,6 +1739,9 @@ export async function dispatchAgentEvent(
|
|
|
1432
1739
|
case "error":
|
|
1433
1740
|
handleError(state, deps, event);
|
|
1434
1741
|
break;
|
|
1742
|
+
case "max_tokens_reached":
|
|
1743
|
+
handleMaxTokensReached(state, deps, event);
|
|
1744
|
+
break;
|
|
1435
1745
|
case "provider_error":
|
|
1436
1746
|
handleProviderError(deps, event);
|
|
1437
1747
|
break;
|