@vellumai/assistant 0.8.6 → 0.8.7-dev.202606052118.34cd356
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 +4 -4
- package/Dockerfile +21 -4
- package/bun.lock +13 -4
- package/docker-entrypoint.sh +12 -8
- package/docker-init-apt-root.sh +3 -1
- package/docker-kata-apt-env.sh +3 -1
- package/docker-kata-runtime-family.sh +12 -0
- package/docs/architecture/memory.md +1 -1
- package/docs/plugins.md +110 -83
- package/examples/plugins/echo/README.md +13 -12
- package/examples/plugins/echo/register.ts +0 -54
- package/knip.json +1 -0
- package/node_modules/@vellumai/environments/bun.lock +24 -0
- package/node_modules/@vellumai/environments/package.json +18 -0
- package/node_modules/@vellumai/environments/src/__tests__/package-boundary.test.ts +95 -0
- package/node_modules/@vellumai/environments/src/index.ts +11 -0
- package/node_modules/@vellumai/environments/src/seeds.ts +73 -0
- package/node_modules/@vellumai/environments/src/types.ts +70 -0
- package/node_modules/@vellumai/environments/tsconfig.json +20 -0
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +11 -0
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +3 -4
- package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +3 -3
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +13 -8
- package/openapi.yaml +6964 -539
- package/package.json +8 -4
- package/scripts/generate-openapi.ts +88 -54
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +42 -80
- package/src/__tests__/agent-loop-exit-reason.test.ts +188 -45
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +141 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +19 -32
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +7 -5
- package/src/__tests__/agent-loop-thinking.test.ts +17 -12
- package/src/__tests__/agent-loop.test.ts +238 -422
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +6 -2
- package/src/__tests__/agent-wake-override-profile.test.ts +22 -40
- package/src/__tests__/annotate-activity-metadata.test.ts +262 -0
- package/src/__tests__/annotate-risk-options.test.ts +2 -3
- package/src/__tests__/anthropic-provider.test.ts +296 -57
- package/src/__tests__/app-builder-skill-instructions.test.ts +22 -0
- package/src/__tests__/app-control-flow.test.ts +6 -1
- package/src/__tests__/app-dir-path-guard.test.ts +1 -0
- package/src/__tests__/approval-cascade.test.ts +4 -11
- package/src/__tests__/approval-routes-http.test.ts +8 -3
- package/src/__tests__/assistant-event-hub.test.ts +25 -0
- package/src/__tests__/assistant-event.test.ts +15 -0
- package/src/__tests__/assistant-events-sse-shed.test.ts +8 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
- package/src/__tests__/assistant-stream-state.test.ts +645 -0
- package/src/__tests__/auth-fallback-events-store.test.ts +116 -0
- package/src/__tests__/avatar-e2e.test.ts +7 -37
- package/src/__tests__/avatar-generator.test.ts +12 -42
- package/src/__tests__/avatar-identity-sync.test.ts +28 -3
- package/src/__tests__/background-shell-bash.test.ts +3 -7
- package/src/__tests__/background-workers-disk-pressure.test.ts +6 -0
- package/src/__tests__/btw-routes.test.ts +69 -15
- package/src/__tests__/build-persisted-content.test.ts +184 -0
- package/src/__tests__/call-pointer-messages.test.ts +5 -3
- package/src/__tests__/call-site-routing-provider.test.ts +22 -40
- package/src/__tests__/catalog-files.test.ts +1 -0
- package/src/__tests__/channel-approval-routes.test.ts +49 -21
- package/src/__tests__/channel-approvals.test.ts +4 -2
- package/src/__tests__/channel-invite-transport.test.ts +1 -5
- package/src/__tests__/channel-readiness-routes.test.ts +0 -4
- package/src/__tests__/channel-readiness-slack-remote.test.ts +2 -7
- package/src/__tests__/channel-retry-sweep.test.ts +71 -79
- package/src/__tests__/clawhub-files.test.ts +1 -0
- package/src/__tests__/compaction-circuit.test.ts +258 -0
- package/src/__tests__/compaction-direct.test.ts +132 -0
- package/src/__tests__/compaction-events.test.ts +5 -17
- package/src/__tests__/compaction-trail-store.test.ts +1 -79
- package/src/__tests__/compaction.benchmark.test.ts +0 -30
- package/src/__tests__/compactor-image-manifest-trust.test.ts +112 -0
- package/src/__tests__/computer-use-tools.test.ts +2 -2
- package/src/__tests__/config-watcher.test.ts +28 -0
- package/src/__tests__/context-search-agent-runner.test.ts +6 -3
- package/src/__tests__/context-token-estimator.test.ts +34 -0
- package/src/__tests__/context-window-manager-compact-retry.test.ts +291 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +70 -25
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +9 -7
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +22 -34
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +476 -963
- package/src/__tests__/conversation-agent-loop.test.ts +823 -1321
- package/src/__tests__/conversation-analysis-routes.test.ts +7 -3
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
- package/src/__tests__/conversation-clean-command.test.ts +5 -2
- package/src/__tests__/conversation-clear-safety.test.ts +20 -10
- package/src/__tests__/conversation-confirmation-signals.test.ts +15 -45
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-disk-view.test.ts +10 -17
- package/src/__tests__/conversation-fork-crud.test.ts +86 -172
- package/src/__tests__/conversation-fork-route.test.ts +16 -14
- package/src/__tests__/conversation-history-web-search.test.ts +11 -1
- package/src/__tests__/conversation-init.benchmark.test.ts +6 -6
- package/src/__tests__/conversation-lifecycle.test.ts +3 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +3 -2
- package/src/__tests__/conversation-load-history-stripped.test.ts +1 -1
- package/src/__tests__/conversation-message-sync-tags.test.ts +3 -4
- package/src/__tests__/conversation-pairing.test.ts +10 -7
- package/src/__tests__/conversation-pre-run-repair.test.ts +1 -1
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +10 -0
- package/src/__tests__/conversation-process-callsite.test.ts +27 -30
- package/src/__tests__/conversation-provider-retry-repair.test.ts +80 -51
- package/src/__tests__/conversation-queue.test.ts +272 -164
- package/src/__tests__/conversation-routes-disk-view.test.ts +6 -2
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +2 -2
- package/src/__tests__/conversation-routes-slash-commands.test.ts +8 -7
- package/src/__tests__/conversation-runtime-assembly.test.ts +317 -313
- package/src/__tests__/conversation-runtime-workspace.test.ts +114 -36
- package/src/__tests__/conversation-slash-commands.test.ts +8 -42
- package/src/__tests__/conversation-slash-queue.test.ts +42 -31
- package/src/__tests__/conversation-slash-unknown.test.ts +13 -15
- package/src/__tests__/conversation-speed-override.test.ts +8 -22
- package/src/__tests__/conversation-starter-routes.test.ts +14 -6
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +90 -15
- package/src/__tests__/conversation-surfaces-app-control.test.ts +32 -4
- package/src/__tests__/conversation-surfaces-state-update.test.ts +5 -2
- package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -15
- package/src/__tests__/conversation-sync-tags.test.ts +27 -15
- package/src/__tests__/conversation-title-service.test.ts +135 -2
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +23 -11
- package/src/__tests__/conversation-unread-route.test.ts +14 -2
- package/src/__tests__/conversation-usage.test.ts +0 -2
- package/src/__tests__/conversation-wipe.test.ts +1 -1
- package/src/__tests__/conversation-workspace-cache-state.test.ts +20 -17
- package/src/__tests__/conversation-workspace-injection.test.ts +114 -23
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +34 -13
- package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
- package/src/__tests__/credential-execution-tools.test.ts +1 -2
- package/src/__tests__/credential-security-invariants.test.ts +0 -1
- package/src/__tests__/cross-provider-web-search.test.ts +220 -3
- package/src/__tests__/cu-unified-flow.test.ts +26 -1
- package/src/__tests__/db-acp-history.test.ts +101 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +16 -0
- package/src/__tests__/disk-pressure-guard.test.ts +66 -0
- package/src/__tests__/disk-pressure-routes.test.ts +9 -2
- package/src/__tests__/dm-persistence.test.ts +12 -3
- package/src/__tests__/dynamic-page-surface.test.ts +99 -0
- package/src/__tests__/edit-propagation.test.ts +1 -2
- package/src/__tests__/empty-response-hook.test.ts +304 -0
- package/src/__tests__/feature-flag-test-helpers.ts +2 -2
- package/src/__tests__/file-write-tool.test.ts +63 -0
- package/src/__tests__/filing-service.test.ts +2 -2
- package/src/__tests__/first-greeting.test.ts +55 -14
- package/src/__tests__/gemini-image-service.test.ts +13 -0
- package/src/__tests__/gemini-inline-media.test.ts +78 -0
- package/src/__tests__/gemini-provider.test.ts +351 -28
- package/src/__tests__/guardian-grant-minting.test.ts +1 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
- package/src/__tests__/guardian-routing-state.test.ts +60 -71
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +10 -8
- package/src/__tests__/heartbeat-disk-pressure.test.ts +2 -0
- package/src/__tests__/heartbeat-service.test.ts +3 -1
- package/src/__tests__/helpers/mock-provider.ts +110 -0
- package/src/__tests__/helpers/native-web-search-harness.ts +129 -0
- package/src/__tests__/history-repair-hook.test.ts +162 -0
- package/src/__tests__/history-repair-observability.test.ts +1 -1
- package/src/__tests__/history-repair.test.ts +2 -1
- package/src/__tests__/host-app-control-proxy.test.ts +2 -0
- package/src/__tests__/host-app-control-routes.test.ts +1 -1
- package/src/__tests__/host-cu-proxy.test.ts +2 -0
- package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
- package/src/__tests__/host-file-edit-tool.test.ts +4 -2
- package/src/__tests__/host-file-proxy.test.ts +31 -0
- package/src/__tests__/host-file-read-tool.test.ts +4 -2
- package/src/__tests__/host-file-write-tool.test.ts +9 -3
- package/src/__tests__/host-proxy-preactivation.test.ts +53 -14
- package/src/__tests__/host-shell-tool.test.ts +9 -4
- package/src/__tests__/http-user-message-parity.test.ts +2 -2
- package/src/__tests__/identity-intro-cache.test.ts +47 -114
- package/src/__tests__/identity-routes.test.ts +248 -7
- package/src/__tests__/inbound-slack-persistence.test.ts +12 -3
- package/src/__tests__/injector-background-turn.test.ts +3 -9
- package/src/__tests__/injector-chain.test.ts +139 -275
- package/src/__tests__/injector-disk-pressure.test.ts +75 -41
- package/src/__tests__/injector-document-comments.test.ts +3 -3
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +30 -22
- package/src/__tests__/injector-v3-suppression.test.ts +214 -0
- package/src/__tests__/internal-telemetry-routes.test.ts +109 -0
- package/src/__tests__/list-messages-attachments.test.ts +7 -8
- package/src/__tests__/list-messages-hidden-metadata.test.ts +55 -15
- package/src/__tests__/list-messages-page-latest.test.ts +60 -1
- package/src/__tests__/list-messages-tool-merge.test.ts +56 -6
- package/src/__tests__/llm-request-log-turn-query.test.ts +42 -86
- package/src/__tests__/llm-resolver.test.ts +23 -47
- package/src/__tests__/llm-usage-store.test.ts +268 -1
- package/src/__tests__/log-export-routes.test.ts +59 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +1 -8
- package/src/__tests__/mcp-auth-routes.test.ts +15 -10
- package/src/__tests__/mcp-health-check.test.ts +18 -13
- package/src/__tests__/memory-retrieval-hook.test.ts +297 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +103 -35
- package/src/__tests__/messaging-send-tool.test.ts +8 -4
- package/src/__tests__/migration-export-http.test.ts +12 -12
- package/src/__tests__/migration-import-commit-http.test.ts +8 -8
- package/src/__tests__/migration-import-preflight-http.test.ts +7 -7
- package/src/__tests__/migration-validate-http.test.ts +3 -3
- package/src/__tests__/native-web-search.test.ts +205 -20
- package/src/__tests__/notification-decision-identity.test.ts +9 -18
- package/src/__tests__/notification-decision-recipient-context.test.ts +3 -6
- package/src/__tests__/oauth-commands-routes.test.ts +1 -1
- package/src/__tests__/onboarding-template-contract.test.ts +12 -0
- package/src/__tests__/openai-image-service.test.ts +17 -0
- package/src/__tests__/openai-provider.test.ts +97 -71
- package/src/__tests__/openai-responses-provider.test.ts +21 -77
- package/src/__tests__/outbound-slack-persistence.test.ts +2 -1
- package/src/__tests__/{overflow-reduce-pipeline.test.ts → overflow-reduction-loop.test.ts} +64 -286
- package/src/__tests__/parallel-tool.benchmark.test.ts +24 -36
- package/src/__tests__/persist-unsendable-image.test.ts +215 -0
- package/src/__tests__/persistence-secret-redaction.test.ts +3 -1
- package/src/__tests__/pipeline-runner.test.ts +31 -43
- package/src/__tests__/pkb-autoinject.test.ts +2 -5
- package/src/__tests__/plugin-bootstrap.test.ts +62 -51
- package/src/__tests__/plugin-registry.test.ts +0 -27
- package/src/__tests__/plugin-route-contribution.test.ts +6 -16
- package/src/__tests__/plugin-skill-contribution.test.ts +7 -17
- package/src/__tests__/plugin-tool-contribution.test.ts +10 -26
- package/src/__tests__/plugin-types.test.ts +8 -173
- package/src/__tests__/prechat-onboarding-contract.test.ts +23 -0
- package/src/__tests__/process-message-background-slack.test.ts +17 -16
- package/src/__tests__/process-message-display-content.test.ts +36 -44
- package/src/__tests__/provider-commit-message-generator.test.ts +19 -14
- package/src/__tests__/provider-error-scenarios.test.ts +7 -6
- package/src/__tests__/provider-platform-proxy-integration.test.ts +3 -8
- package/src/__tests__/provider-send-message-override-profile.test.ts +9 -25
- package/src/__tests__/provider-streaming.benchmark.test.ts +12 -22
- package/src/__tests__/provider-usage-tracking.test.ts +0 -6
- package/src/__tests__/ratelimit.test.ts +9 -4
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +5 -1
- package/src/__tests__/relay-server.test.ts +20 -13
- package/src/__tests__/resolve-trust-class.test.ts +4 -4
- package/src/__tests__/retry-openrouter-only-normalization.test.ts +5 -8
- package/src/__tests__/retry-thinking-tool-choice.test.ts +10 -13
- package/src/__tests__/retry-verbosity-normalization.test.ts +5 -8
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +390 -0
- package/src/__tests__/schedule-routes.test.ts +683 -12
- package/src/__tests__/schedule-store.test.ts +108 -0
- package/src/__tests__/schedule-tools.test.ts +160 -0
- package/src/__tests__/secret-ingress-http.test.ts +2 -2
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +11 -7
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +11 -9
- package/src/__tests__/secret-response-routing.test.ts +13 -11
- package/src/__tests__/send-endpoint-busy.test.ts +6 -2
- package/src/__tests__/server-history-render.test.ts +314 -1
- package/src/__tests__/shell-observability.test.ts +249 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +44 -11
- package/src/__tests__/skill-feature-flags.test.ts +6 -6
- package/src/__tests__/skill-load-feature-flag.test.ts +10 -10
- package/src/__tests__/skills-files-catalog-fallback.test.ts +10 -0
- package/src/__tests__/skillssh-files.test.ts +1 -0
- package/src/__tests__/starter-task-flow.test.ts +6 -6
- package/src/__tests__/strip-memory-injections.test.ts +102 -14
- package/src/__tests__/subagent-call-site-routing.test.ts +3 -3
- package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
- package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
- package/src/__tests__/subagent-manager-notify.test.ts +1 -3
- package/src/__tests__/subagent-notify-parent.test.ts +1 -3
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
- package/src/__tests__/suggestion-routes.test.ts +3 -3
- package/src/__tests__/sync-message-contract.test.ts +19 -16
- package/src/__tests__/system-prompt.test.ts +74 -0
- package/src/__tests__/task-scheduler.test.ts +162 -1
- package/src/__tests__/terminal-tools.test.ts +9 -25
- package/src/__tests__/thread-backfill.test.ts +4 -9
- package/src/__tests__/title-generate-hook.test.ts +319 -0
- package/src/__tests__/tool-error-hook.test.ts +278 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +481 -16
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
- package/src/__tests__/tool-result-truncate-hook.test.ts +127 -0
- package/src/__tests__/tool-result-truncation.test.ts +1 -1
- package/src/__tests__/tools-audio-read.test.ts +113 -0
- package/src/__tests__/turn-boundary-resolution.test.ts +44 -84
- package/src/__tests__/turn-events-store.test.ts +11 -7
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +254 -0
- package/src/__tests__/ui-work-result-surface.test.ts +159 -0
- package/src/__tests__/usage-routes.test.ts +285 -1
- package/src/__tests__/user-plugin-loader.test.ts +2 -2
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +8 -6
- package/src/__tests__/voice-session-bridge.test.ts +19 -10
- package/src/__tests__/web-search-backend-failure.test.ts +166 -0
- package/src/acp/__tests__/agent-process.test.ts +161 -0
- package/src/acp/__tests__/client-handler.test.ts +40 -0
- package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
- package/src/acp/__tests__/helpers/exec-file-stub.ts +101 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +143 -31
- package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
- package/src/acp/__tests__/session-manager-resume.test.ts +695 -0
- package/src/acp/agent-process.ts +61 -1
- package/src/acp/auto-install.test.ts +125 -0
- package/src/acp/auto-install.ts +174 -0
- package/src/acp/client-handler.ts +31 -0
- package/src/acp/feature-gate.test.ts +48 -0
- package/src/acp/feature-gate.ts +34 -0
- package/src/acp/prepare-agent-env.ts +52 -11
- package/src/acp/resolve-agent.test.ts +147 -6
- package/src/acp/resolve-agent.ts +81 -7
- package/src/acp/resume-hint.ts +22 -0
- package/src/acp/session-manager.ts +487 -71
- package/src/agent/compaction-circuit.ts +98 -0
- package/src/agent/loop.ts +651 -450
- package/src/api/README.md +19 -17
- package/src/api/constants/tool-execution.ts +21 -0
- package/src/api/events/assistant-activity-state.ts +75 -0
- package/src/api/events/assistant-outbound-attachment.ts +25 -27
- package/src/api/events/assistant-text-delta.ts +6 -8
- package/src/api/events/assistant-thinking-delta.ts +33 -0
- package/src/api/events/assistant-turn-start.ts +5 -7
- package/src/api/events/avatar-updated.ts +24 -0
- package/src/api/events/compaction-circuit-closed.ts +26 -0
- package/src/api/events/compaction-circuit-open.ts +28 -0
- package/src/api/events/confirmation-request.ts +114 -0
- package/src/api/events/contact-request.ts +33 -0
- package/src/api/events/conversation-error.ts +77 -0
- package/src/api/events/conversation-list-invalidated.ts +38 -0
- package/src/api/events/conversation-title-updated.ts +24 -0
- package/src/api/events/disk-pressure-status-changed.ts +61 -0
- package/src/api/events/document-comment-created.ts +24 -28
- package/src/api/events/document-comment-deleted.ts +6 -8
- package/src/api/events/document-comment-reopened.ts +6 -8
- package/src/api/events/document-comment-resolved.ts +8 -10
- package/src/api/events/document-editor-update.ts +27 -0
- package/src/api/events/error.ts +32 -0
- package/src/api/events/generation-cancelled.ts +4 -6
- package/src/api/events/generation-handoff.ts +13 -15
- package/src/api/events/home-feed-updated.ts +26 -0
- package/src/api/events/identity-changed.ts +32 -0
- package/src/api/events/interaction-resolved.ts +50 -0
- package/src/api/events/message-complete.ts +10 -12
- package/src/api/events/message-dequeued.ts +21 -0
- package/src/api/events/message-queued-deleted.ts +23 -0
- package/src/api/events/message-queued.ts +22 -0
- package/src/api/events/message-request-complete.ts +29 -0
- package/src/api/events/navigate-settings.ts +20 -0
- package/src/api/events/notification-intent.ts +33 -0
- package/src/api/events/open-url.ts +6 -8
- package/src/api/events/question-request.ts +67 -0
- package/src/api/events/relationship-state-updated.ts +4 -6
- package/src/api/events/secret-request.ts +42 -0
- package/src/api/events/subagent-event.ts +79 -0
- package/src/api/events/subagent-spawned.ts +40 -0
- package/src/api/events/subagent-status-changed.ts +65 -0
- package/src/api/events/sync-changed.ts +29 -0
- package/src/api/events/tool-output-chunk.ts +45 -0
- package/src/api/events/tool-result.ts +129 -0
- package/src/api/events/tool-use-preview-start.ts +32 -0
- package/src/api/events/tool-use-start.ts +8 -10
- package/src/api/events/trace-event.ts +69 -0
- package/src/api/events/turn-profile-auto-routed.ts +28 -0
- package/src/api/events/ui-surface-complete.ts +30 -0
- package/src/api/events/ui-surface-dismiss.ts +22 -0
- package/src/api/events/ui-surface-show.ts +67 -0
- package/src/api/events/ui-surface-update.ts +26 -0
- package/src/api/events/usage-update.ts +34 -0
- package/src/api/events/user-message-echo.ts +35 -0
- package/src/api/index.ts +389 -0
- package/src/api/requests/dictation.ts +45 -0
- package/src/api/responses/conversation-message.ts +374 -0
- package/src/api/responses/disk-pressure-status.ts +26 -0
- package/src/api/responses/home.ts +217 -0
- package/src/api/responses/llm-context-response.ts +2 -0
- package/src/api/responses/memory-v3-selection-log.ts +50 -0
- package/src/api/responses/subagent-detail.ts +48 -0
- package/src/approvals/guardian-decision-primitive.ts +7 -15
- package/src/approvals/guardian-request-resolvers.ts +7 -10
- package/src/avatar/__tests__/avatar-manifest.test.ts +236 -0
- package/src/avatar/__tests__/avatar-store.test.ts +198 -0
- package/src/avatar/avatar-manifest.ts +195 -0
- package/src/avatar/avatar-store.ts +113 -0
- package/src/avatar/traits-png-sync.ts +8 -2
- package/src/background-wake/next-wake.test.ts +31 -1
- package/src/background-wake/next-wake.ts +5 -1
- package/src/calls/call-conversation-messages.ts +6 -4
- package/src/calls/guardian-action-sweep.ts +6 -4
- package/src/calls/relay-server.ts +12 -8
- package/src/calls/voice-session-bridge.ts +13 -27
- package/src/cli/commands/__tests__/memory-v3.test.ts +245 -0
- package/src/cli/commands/__tests__/notifications.test.ts +58 -14
- package/src/cli/commands/avatar.ts +17 -11
- package/src/cli/commands/conversations.ts +15 -1
- package/src/cli/commands/db/__tests__/repair.test.ts +540 -0
- package/src/cli/commands/db/__tests__/status.test.ts +253 -0
- package/src/cli/commands/db/format.ts +48 -0
- package/src/cli/commands/db/index.ts +29 -0
- package/src/cli/commands/db/repair-step-conversation-backfill.ts +345 -0
- package/src/cli/commands/db/repair-step-integrity.ts +146 -0
- package/src/cli/commands/db/repair-steps.ts +164 -0
- package/src/cli/commands/db/repair.ts +141 -0
- package/src/cli/commands/db/status.ts +366 -0
- package/src/cli/commands/memory-v3.ts +159 -445
- package/src/cli/commands/notifications.ts +112 -60
- package/src/cli/lib/cli-colors.ts +24 -6
- package/src/cli/program.ts +4 -5
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +4 -4
- package/src/config/acp-defaults.test.ts +10 -0
- package/src/config/acp-defaults.ts +6 -0
- package/src/config/assistant-feature-flags.ts +24 -13
- package/src/config/bundled-skills/acp/SKILL.md +64 -30
- package/src/config/bundled-skills/acp/TOOLS.json +4 -4
- package/src/config/bundled-skills/app-builder/SKILL.md +224 -387
- package/src/config/bundled-skills/app-builder/TOOLS.json +29 -0
- package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
- package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
- package/src/config/bundled-skills/app-builder/references/examples/README.md +17 -0
- package/src/config/bundled-skills/app-builder/references/examples/expense-tracker.md +515 -0
- package/src/config/bundled-skills/app-builder/references/examples/focus-timer.md +342 -0
- package/src/config/bundled-skills/app-builder/references/examples/habit-tracker.md +490 -0
- package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
- package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
- package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
- package/src/config/bundled-skills/media-processing/services/reduce.ts +6 -9
- package/src/config/bundled-skills/messaging/SKILL.md +0 -7
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +1 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
- package/src/config/bundled-tool-registry.ts +2 -0
- package/src/config/call-site-defaults.ts +2 -7
- package/src/config/feature-flag-cache.ts +3 -3
- package/src/config/feature-flag-registry.json +68 -12
- package/src/config/schemas/__tests__/memory-v2.test.ts +2 -226
- package/src/config/schemas/__tests__/memory-v3.test.ts +25 -0
- package/src/config/schemas/call-site-catalog.ts +8 -15
- package/src/config/schemas/heartbeat.ts +9 -0
- package/src/config/schemas/llm.ts +3 -3
- package/src/config/schemas/memory-lifecycle.ts +24 -0
- package/src/config/schemas/memory-v2.ts +8 -253
- package/src/config/schemas/memory-v3.ts +47 -0
- package/src/config/schemas/memory.ts +6 -1
- package/src/config/schemas/platform.ts +8 -0
- package/src/config/schemas/timeouts.ts +3 -1
- package/src/config/seed-inference-profiles.ts +2 -2
- package/src/config/skills.ts +13 -0
- package/src/context/compactor.ts +55 -32
- package/src/context/strip-injections.ts +128 -0
- package/src/context/token-estimator.ts +42 -0
- package/src/context/tool-result-truncation.ts +1 -66
- package/src/context/window-manager.ts +141 -26
- package/src/credential-execution/executable-discovery.ts +16 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +6 -0
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +2 -2
- package/src/daemon/__tests__/inference-profile-notification.test.ts +153 -0
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +10 -8
- package/src/daemon/__tests__/web-search-status-text.test.ts +10 -6
- package/src/daemon/approval-generators.ts +4 -4
- package/src/daemon/assistant-attachments.ts +1 -1
- package/src/daemon/config-watcher.ts +7 -1
- package/src/daemon/context-overflow-reducer.ts +0 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +793 -215
- package/src/daemon/conversation-agent-loop.ts +487 -1478
- package/src/daemon/conversation-error.ts +7 -7
- package/src/daemon/conversation-history.ts +27 -10
- package/src/daemon/conversation-launch.ts +4 -8
- package/src/daemon/conversation-lifecycle.ts +13 -42
- package/src/daemon/conversation-messaging.ts +8 -9
- package/src/daemon/conversation-notifiers.ts +7 -5
- package/src/daemon/conversation-process.ts +109 -93
- package/src/daemon/conversation-registry.ts +159 -0
- package/src/daemon/conversation-runtime-assembly.ts +209 -382
- package/src/daemon/conversation-slash.ts +6 -25
- package/src/daemon/conversation-store.ts +15 -95
- package/src/daemon/conversation-surfaces.ts +277 -73
- package/src/daemon/conversation-tool-setup.ts +5 -29
- package/src/daemon/conversation-workspace.ts +17 -0
- package/src/daemon/conversation.ts +123 -146
- package/src/daemon/daemon-skill-host.ts +2 -6
- package/src/daemon/disk-pressure-guard.ts +35 -29
- package/src/daemon/external-plugins-bootstrap.ts +53 -32
- package/src/daemon/first-greeting.ts +26 -4
- package/src/daemon/guardian-action-generators.ts +2 -2
- package/src/daemon/handlers/config-a2a.ts +51 -36
- package/src/daemon/handlers/config-slack-channel.ts +20 -14
- package/src/daemon/handlers/config-telegram.ts +16 -2
- package/src/daemon/handlers/conversations.ts +9 -23
- package/src/daemon/handlers/shared.ts +158 -82
- package/src/daemon/handlers/skills.ts +53 -20
- package/src/daemon/host-app-control-proxy.ts +54 -1
- package/src/daemon/host-cu-proxy.ts +46 -22
- package/src/daemon/host-file-proxy.ts +25 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -6
- package/src/daemon/lifecycle.ts +53 -55
- package/src/daemon/message-protocol.ts +2 -3
- package/src/daemon/message-provenance.ts +49 -0
- package/src/daemon/message-types/apps.ts +1 -29
- package/src/daemon/message-types/contacts.ts +3 -20
- package/src/daemon/message-types/conversations.ts +13 -111
- package/src/daemon/message-types/documents.ts +3 -9
- package/src/daemon/message-types/home.ts +4 -17
- package/src/daemon/message-types/integrations.ts +2 -6
- package/src/daemon/message-types/messages.ts +37 -400
- package/src/daemon/message-types/notifications.ts +2 -32
- package/src/daemon/message-types/settings.ts +3 -8
- package/src/daemon/message-types/skills.ts +4 -0
- package/src/daemon/message-types/surfaces.ts +138 -3
- package/src/daemon/message-types/sync.ts +12 -25
- package/src/daemon/message-types/workspace.ts +3 -11
- package/src/daemon/now-scratchpad.ts +21 -0
- package/src/daemon/orphan-reaper.test.ts +210 -0
- package/src/daemon/orphan-reaper.ts +240 -0
- package/src/daemon/overflow-reduction-loop.ts +230 -0
- package/src/daemon/persist-unsendable-image.ts +117 -0
- package/src/daemon/process-message.ts +50 -49
- package/src/daemon/server.ts +14 -0
- package/src/daemon/tool-side-effects.ts +10 -7
- package/src/daemon/trace-emitter.ts +6 -4
- package/src/daemon/trust-context.ts +32 -0
- package/src/daemon/wake-target-adapter.ts +14 -2
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +6 -1
- package/src/heartbeat/heartbeat-run-store.ts +54 -1
- package/src/heartbeat/heartbeat-service.ts +42 -0
- package/src/home/feed-types.ts +36 -221
- package/src/home/home-greeting-cache.ts +24 -1
- package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
- package/src/ipc/__tests__/email-ipc.test.ts +0 -9
- package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
- package/src/ipc/gateway-client.test.ts +2 -2
- package/src/ipc/gateway-client.ts +3 -3
- package/src/ipc/routes/__tests__/route-adapter.test.ts +244 -0
- package/src/ipc/routes/route-adapter.ts +45 -6
- package/src/ipc/skill-routes/__tests__/memory.test.ts +33 -9
- package/src/ipc/skill-routes/__tests__/providers.test.ts +10 -10
- package/src/ipc/skill-routes/__tests__/registries.test.ts +28 -18
- package/src/ipc/skill-routes/memory.ts +29 -14
- package/src/ipc/skill-routes/providers.ts +5 -6
- package/src/ipc/skill-routes/registries.ts +13 -61
- package/src/live-voice/__tests__/live-voice-archive.test.ts +24 -11
- package/src/media/gemini-image-service.ts +15 -0
- package/src/media/openai-image-service.ts +14 -0
- package/src/media/types.ts +34 -0
- package/src/memory/__tests__/conversation-queries.test.ts +192 -8
- package/src/memory/__tests__/db-maintenance.test.ts +128 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +5 -4
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +56 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +10 -6
- package/src/memory/__tests__/memory-v3-selections-migration.test.ts +103 -0
- package/src/memory/auth-fallback-events-store.ts +94 -0
- package/src/memory/context-search/agent-runner.ts +2 -4
- package/src/memory/conversation-crud.ts +39 -8
- package/src/memory/conversation-queries.ts +78 -22
- package/src/memory/conversation-starter-checkpoints.ts +1 -0
- package/src/memory/conversation-title-service.ts +65 -41
- package/src/memory/db-init.ts +14 -0
- package/src/memory/db-maintenance.ts +18 -2
- package/src/memory/graph/__tests__/conversation-graph-memory-registry.test.ts +119 -0
- package/src/memory/graph/consolidation.ts +8 -11
- package/src/memory/graph/conversation-graph-memory.ts +106 -8
- package/src/memory/graph/extraction.ts +6 -9
- package/src/memory/graph/narrative.ts +2 -2
- package/src/memory/graph/pattern-scan.ts +2 -2
- package/src/memory/graph/retriever.ts +20 -26
- package/src/memory/graph/tools.ts +4 -4
- package/src/memory/job-handlers/conversation-starters.ts +45 -34
- package/src/memory/job-handlers/summarization.ts +1 -2
- package/src/memory/jobs-store.ts +36 -1
- package/src/memory/jobs-worker.ts +82 -43
- package/src/memory/llm-request-log-source-clickhouse.ts +5 -31
- package/src/memory/llm-request-log-source-local.ts +0 -11
- package/src/memory/llm-request-log-source.ts +9 -25
- package/src/memory/llm-request-log-store.ts +0 -41
- package/src/memory/llm-usage-store.ts +234 -50
- package/src/memory/memory-marker.ts +17 -0
- package/src/memory/memory-retrospective-job.ts +6 -2
- package/src/memory/memory-v2-activation-log-store.ts +1 -83
- package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +6 -5
- package/src/memory/migrations/267-llm-usage-events-add-assistant-version.ts +46 -0
- package/src/memory/migrations/268-add-memory-v3-selections.ts +28 -0
- package/src/memory/migrations/269-schedule-script-timeout.ts +11 -0
- package/src/memory/migrations/270-messages-role-created-at-index.ts +18 -0
- package/src/memory/migrations/270-schedule-source-conversation.ts +13 -0
- package/src/memory/migrations/271-create-auth-fallback-events.ts +21 -0
- package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
- package/src/memory/migrations/__tests__/267-llm-usage-events-add-assistant-version.test.ts +117 -0
- package/src/memory/migrations/index.ts +7 -0
- package/src/memory/pkb/autoinject.ts +61 -0
- package/src/memory/pkb/context.ts +50 -0
- package/src/memory/pkb/types.ts +14 -0
- package/src/memory/schedule-attribution-sql.ts +104 -0
- package/src/memory/schema/acp.ts +4 -0
- package/src/memory/schema/infrastructure.ts +27 -0
- package/src/memory/usage-grouped-buckets.ts +6 -1
- package/src/memory/v2/__tests__/consolidation-job.test.ts +125 -1
- package/src/memory/v2/__tests__/migration.test.ts +11 -3
- package/src/memory/v2/__tests__/page-index.test.ts +37 -1
- package/src/memory/v2/__tests__/router.test.ts +14 -4
- package/src/memory/v2/__tests__/sweep-job.test.ts +6 -5
- package/src/memory/v2/backfill-jobs.ts +6 -0
- package/src/memory/v2/consolidation-job.ts +99 -10
- package/src/memory/v2/migration.ts +5 -3
- package/src/memory/v2/page-index.ts +11 -0
- package/src/memory/v2/router.ts +8 -11
- package/src/memory/v2/sweep-job.ts +8 -11
- package/src/memory/v2/types.ts +1 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +1 -1
- package/src/messaging/providers/slack/render-transcript.ts +2 -2
- package/src/messaging/style-analyzer.ts +8 -11
- package/src/notifications/conversation-pairing.ts +8 -13
- package/src/notifications/decision-engine.ts +16 -16
- package/src/notifications/home-feed-side-effect.ts +12 -1
- package/src/notifications/preference-extractor.ts +11 -14
- package/src/permissions/prompter.ts +46 -36
- package/src/permissions/question-prompter.test.ts +35 -26
- package/src/permissions/question-prompter.ts +6 -10
- package/src/plugin-api/constants.ts +4 -0
- package/src/plugin-api/index.ts +10 -1
- package/src/plugin-api/types.ts +176 -4
- package/src/plugins/defaults/compaction/compact.ts +59 -0
- package/src/plugins/defaults/compaction/package.json +15 -0
- package/src/plugins/defaults/compaction/register.ts +24 -0
- package/src/plugins/defaults/empty-response/hooks/stop.ts +126 -0
- package/src/plugins/defaults/empty-response/package.json +15 -0
- package/src/plugins/defaults/empty-response/register.ts +23 -0
- package/src/plugins/defaults/history-repair/hooks/user-prompt-submit.ts +35 -0
- package/src/plugins/defaults/history-repair/package.json +15 -0
- package/src/plugins/defaults/history-repair/register.ts +24 -0
- package/src/{daemon/history-repair.ts → plugins/defaults/history-repair/terminal.ts} +48 -35
- package/src/plugins/defaults/index.ts +22 -49
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +95 -0
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +216 -0
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +35 -0
- package/src/plugins/defaults/{injectors.ts → memory-retrieval/injectors.ts} +295 -112
- package/src/plugins/defaults/memory-v3-shadow/__tests__/assign.test.ts +242 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/capabilities.test.ts +118 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/core.test.ts +39 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/eval-turns.json +36 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/live-turns.json +37 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/health.test.ts +219 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/live-integration.test.ts +330 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +288 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/needle.test.ts +107 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +436 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/provider-blocks.test.ts +13 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/reconcile.test.ts +274 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +61 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/router.test.ts +332 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +179 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selector.test.ts +470 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +432 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/snapshot.test.ts +168 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/tree.test.ts +192 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/types.test.ts +54 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-eviction.test.ts +106 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-skeleton.test.ts +44 -0
- package/src/plugins/defaults/memory-v3-shadow/assign.ts +268 -0
- package/src/plugins/defaults/memory-v3-shadow/capabilities.ts +124 -0
- package/src/plugins/defaults/memory-v3-shadow/core.ts +26 -0
- package/src/plugins/defaults/memory-v3-shadow/data/README.md +84 -0
- package/src/plugins/defaults/memory-v3-shadow/data/assignments.json +5 -0
- package/src/plugins/defaults/memory-v3-shadow/data/core.json +1 -0
- package/src/plugins/defaults/memory-v3-shadow/data/leaves/domain-a/topic-x.md +9 -0
- package/src/plugins/defaults/memory-v3-shadow/data/leaves/domain-a/topic-y.md +9 -0
- package/src/plugins/defaults/memory-v3-shadow/data/leaves/domain-b/topic-z.md +9 -0
- package/src/plugins/defaults/memory-v3-shadow/health.ts +0 -0
- package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
- package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +75 -0
- package/src/plugins/defaults/memory-v3-shadow/llm-retry.ts +32 -0
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +314 -0
- package/src/plugins/defaults/memory-v3-shadow/needle.ts +115 -0
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +126 -0
- package/src/plugins/defaults/memory-v3-shadow/package.json +15 -0
- package/src/plugins/defaults/memory-v3-shadow/page-content.ts +34 -0
- package/src/plugins/defaults/memory-v3-shadow/provider-blocks.ts +26 -0
- package/src/plugins/defaults/memory-v3-shadow/reconcile.ts +523 -0
- package/src/plugins/defaults/memory-v3-shadow/register.ts +26 -0
- package/src/plugins/defaults/memory-v3-shadow/render-injection.ts +32 -0
- package/src/plugins/defaults/memory-v3-shadow/router.ts +190 -0
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +84 -0
- package/src/plugins/defaults/memory-v3-shadow/selector.ts +226 -0
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +349 -0
- package/src/plugins/defaults/memory-v3-shadow/snapshot.ts +209 -0
- package/src/plugins/defaults/memory-v3-shadow/tree.ts +174 -0
- package/src/plugins/defaults/memory-v3-shadow/types.ts +59 -0
- package/src/plugins/defaults/memory-v3-shadow/working-set.ts +88 -0
- package/src/plugins/defaults/title-generate/hooks/stop.ts +75 -0
- package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +35 -0
- package/src/plugins/defaults/title-generate/package.json +15 -0
- package/src/plugins/defaults/title-generate/register.ts +35 -0
- package/src/plugins/defaults/tool-error/hooks/post-tool-use.ts +118 -0
- package/src/plugins/defaults/tool-error/package.json +15 -0
- package/src/plugins/defaults/tool-error/register.ts +23 -0
- package/src/plugins/defaults/tool-result-truncate/hooks/post-tool-use.ts +32 -0
- package/src/plugins/defaults/tool-result-truncate/package.json +15 -0
- package/src/plugins/defaults/tool-result-truncate/register.ts +24 -0
- package/src/plugins/defaults/tool-result-truncate/terminal.ts +132 -0
- package/src/plugins/external-plugin-loader.ts +2 -2
- package/src/plugins/pipeline.ts +8 -35
- package/src/plugins/registry.ts +8 -25
- package/src/plugins/types.ts +62 -721
- package/src/plugins/user-loader.ts +4 -3
- package/src/proactive-artifact/aux-message-injector.ts +4 -5
- package/src/proactive-artifact/job.test.ts +28 -21
- package/src/proactive-artifact/job.ts +3 -1
- package/src/prompts/__tests__/system-prompt.test.ts +42 -0
- package/src/prompts/sections.ts +20 -7
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +64 -0
- package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +2 -2
- package/src/prompts/templates/BOOTSTRAP.md +7 -3
- package/src/prompts/templates/system-sections.ts +21 -0
- package/src/providers/__tests__/retry-callsite.test.ts +25 -25
- package/src/providers/__tests__/satellite-connection-routing.test.ts +7 -21
- package/src/providers/anthropic/client.ts +61 -34
- package/src/providers/call-site-routing.ts +1 -9
- package/src/providers/gemini/client.ts +152 -34
- package/src/providers/gemini/inline-media.ts +74 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +112 -2
- package/src/providers/openai/chat-completions-provider.ts +45 -4
- package/src/providers/openai/responses-provider.ts +1 -4
- package/src/providers/openrouter/client.ts +2 -6
- package/src/providers/placeholder-sentinels.ts +35 -0
- package/src/providers/provider-send-message.ts +6 -6
- package/src/providers/ratelimit.ts +1 -9
- package/src/providers/retry.ts +0 -5
- package/src/providers/types.ts +11 -2
- package/src/providers/usage-tracking.ts +1 -9
- package/src/runtime/__tests__/agent-wake.test.ts +141 -32
- package/src/runtime/__tests__/background-job-runner.test.ts +1 -3
- package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
- package/src/runtime/agent-wake.ts +95 -23
- package/src/runtime/assistant-event-hub.ts +38 -8
- package/src/runtime/assistant-stream-state.ts +368 -0
- package/src/runtime/auth/__tests__/guard-tests.test.ts +75 -109
- package/src/runtime/auth/__tests__/route-policy.test.ts +153 -170
- package/src/runtime/auth/route-policy.ts +42 -1079
- package/src/runtime/background-job-runner.ts +1 -4
- package/src/runtime/btw-sidechain.ts +3 -1
- package/src/runtime/channel-approvals.ts +4 -15
- package/src/runtime/channel-invite-transport.ts +5 -6
- package/src/runtime/channel-readiness-service.ts +2 -5
- package/src/runtime/channel-retry-sweep.ts +12 -16
- package/src/runtime/http-router.ts +35 -43
- package/src/runtime/http-types.ts +23 -71
- package/src/runtime/interactive-ui.ts +1 -1
- package/src/runtime/invite-instruction-generator.ts +3 -3
- package/src/runtime/pending-interactions.ts +3 -2
- package/src/runtime/routes/__tests__/acp-routes.test.ts +253 -55
- package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +565 -0
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +265 -2
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +4 -4
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +62 -32
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +237 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +31 -1
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -22
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +6 -2
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +7 -2
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +6 -6
- package/src/runtime/routes/__tests__/stt-routes.test.ts +3 -3
- package/src/runtime/routes/__tests__/suggest-trust-rule-routes.test.ts +5 -2
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
- package/src/runtime/routes/__tests__/tts-routes.test.ts +9 -5
- package/src/runtime/routes/acp-routes.test.ts +186 -100
- package/src/runtime/routes/acp-routes.ts +110 -35
- package/src/runtime/routes/app-management-routes.ts +93 -131
- package/src/runtime/routes/app-routes.ts +38 -20
- package/src/runtime/routes/approval-routes.ts +17 -5
- package/src/runtime/routes/attachment-routes.ts +51 -16
- package/src/runtime/routes/audio-routes.ts +1 -0
- package/src/runtime/routes/audit-routes.ts +5 -0
- package/src/runtime/routes/auth-routes.ts +5 -0
- package/src/runtime/routes/avatar-routes.ts +264 -59
- package/src/runtime/routes/background-tool-routes.ts +9 -0
- package/src/runtime/routes/background-wake-routes.ts +13 -3
- package/src/runtime/routes/backup-routes.ts +45 -0
- package/src/runtime/routes/bookmark-routes.ts +13 -0
- package/src/runtime/routes/brain-graph-routes.ts +9 -0
- package/src/runtime/routes/browser-routes.ts +6 -1
- package/src/runtime/routes/browser-tabs-routes.ts +11 -10
- package/src/runtime/routes/btw-routes.ts +34 -24
- package/src/runtime/routes/cache-routes.ts +13 -0
- package/src/runtime/routes/call-routes.ts +21 -10
- package/src/runtime/routes/channel-availability-routes.ts +5 -1
- package/src/runtime/routes/channel-readiness-routes.ts +37 -4
- package/src/runtime/routes/channel-route-definitions.ts +21 -0
- package/src/runtime/routes/channel-verification-routes.ts +21 -0
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +9 -2
- package/src/runtime/routes/client-routes.ts +9 -0
- package/src/runtime/routes/consolidation-routes.ts +133 -25
- package/src/runtime/routes/contact-prompt-routes.ts +9 -0
- package/src/runtime/routes/contact-routes.ts +90 -23
- package/src/runtime/routes/content-source-routes.ts +5 -1
- package/src/runtime/routes/conversation-analysis-routes.ts +5 -1
- package/src/runtime/routes/conversation-attention-routes.ts +5 -0
- package/src/runtime/routes/conversation-cli-routes.ts +54 -7
- package/src/runtime/routes/conversation-compaction-routes.ts +54 -25
- package/src/runtime/routes/conversation-list-routes.ts +81 -12
- package/src/runtime/routes/conversation-management-routes.ts +57 -14
- package/src/runtime/routes/conversation-query-routes.ts +90 -41
- package/src/runtime/routes/conversation-routes.ts +446 -204
- package/src/runtime/routes/conversation-starter-routes.ts +35 -20
- package/src/runtime/routes/conversations-import-routes.ts +30 -8
- package/src/runtime/routes/credential-prompt-routes.ts +5 -0
- package/src/runtime/routes/credential-routes.ts +25 -6
- package/src/runtime/routes/debug-bash-routes.ts +5 -0
- package/src/runtime/routes/debug-routes.ts +11 -2
- package/src/runtime/routes/defer-routes.ts +13 -0
- package/src/runtime/routes/diagnostics-routes.ts +37 -46
- package/src/runtime/routes/disk-pressure-routes.ts +17 -31
- package/src/runtime/routes/document-comments-routes.ts +46 -27
- package/src/runtime/routes/documents-routes.ts +25 -10
- package/src/runtime/routes/domain-routes.ts +98 -51
- package/src/runtime/routes/email-routes.ts +33 -0
- package/src/runtime/routes/epoch-millis-range.ts +34 -0
- package/src/runtime/routes/events-routes.ts +107 -8
- package/src/runtime/routes/filing-routes.ts +9 -4
- package/src/runtime/routes/gateway-log-routes.ts +31 -4
- package/src/runtime/routes/global-search-routes.ts +53 -50
- package/src/runtime/routes/group-routes.ts +21 -5
- package/src/runtime/routes/guardian-action-routes.ts +9 -0
- package/src/runtime/routes/guardian-approval-interception.ts +0 -31
- package/src/runtime/routes/heartbeat-routes.ts +57 -21
- package/src/runtime/routes/home-feed-routes.ts +23 -19
- package/src/runtime/routes/home-state-routes.ts +8 -40
- package/src/runtime/routes/host-app-control-routes.ts +6 -1
- package/src/runtime/routes/host-bash-routes.ts +5 -0
- package/src/runtime/routes/host-browser-routes.ts +13 -0
- package/src/runtime/routes/host-cu-routes.ts +6 -1
- package/src/runtime/routes/host-file-routes.ts +26 -6
- package/src/runtime/routes/host-transfer-routes.ts +13 -2
- package/src/runtime/routes/http-adapter.ts +1 -2
- package/src/runtime/routes/identity-intro-cache.ts +28 -40
- package/src/runtime/routes/identity-routes.ts +236 -20
- package/src/runtime/routes/image-generation-routes.ts +45 -2
- package/src/runtime/routes/inbound-message-handler.ts +16 -12
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +0 -12
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +15 -19
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/inference-profile-session-routes.ts +13 -3
- package/src/runtime/routes/inference-provider-connection-routes.ts +21 -5
- package/src/runtime/routes/inference-send-routes.ts +11 -11
- package/src/runtime/routes/integrations/a2a.ts +32 -7
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +16 -0
- package/src/runtime/routes/integrations/slack/channel.ts +23 -3
- package/src/runtime/routes/integrations/slack/share.ts +36 -8
- package/src/runtime/routes/integrations/telegram.ts +34 -9
- package/src/runtime/routes/integrations/twilio.ts +77 -7
- package/src/runtime/routes/integrations/vercel.ts +3 -3
- package/src/runtime/routes/internal-oauth-routes.ts +5 -0
- package/src/runtime/routes/internal-telemetry-routes.ts +88 -0
- package/src/runtime/routes/internal-twilio-routes.ts +13 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +39 -4
- package/src/runtime/routes/log-export-routes.ts +36 -10
- package/src/runtime/routes/mcp-auth-routes.ts +25 -0
- package/src/runtime/routes/memory-item-routes.ts +21 -10
- package/src/runtime/routes/memory-v2-routes.ts +105 -44
- package/src/runtime/routes/memory-v3-routes.ts +306 -408
- package/src/runtime/routes/migration-rollback-routes.ts +5 -1
- package/src/runtime/routes/migration-routes.ts +29 -0
- package/src/runtime/routes/notification-routes.ts +17 -1
- package/src/runtime/routes/oauth-apps.ts +99 -23
- package/src/runtime/routes/oauth-commands-routes.ts +37 -14
- package/src/runtime/routes/oauth-connect-routes.ts +9 -0
- package/src/runtime/routes/oauth-lifecycle-routes.ts +5 -1
- package/src/runtime/routes/oauth-providers.ts +79 -15
- package/src/runtime/routes/platform-routes.ts +102 -5
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +9 -6
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +37 -16
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +7 -3
- package/src/runtime/routes/playground/__tests__/state.test.ts +10 -3
- package/src/runtime/routes/playground/force-compact.ts +2 -2
- package/src/runtime/routes/playground/helpers.ts +1 -2
- package/src/runtime/routes/playground/inject-failures.ts +13 -8
- package/src/runtime/routes/playground/reset-circuit.ts +14 -9
- package/src/runtime/routes/playground/seed-conversation.ts +1 -1
- package/src/runtime/routes/playground/seeded-conversations.ts +3 -3
- package/src/runtime/routes/playground/state.ts +4 -3
- package/src/runtime/routes/plugins-routes.ts +22 -19
- package/src/runtime/routes/profiler-routes.ts +17 -4
- package/src/runtime/routes/ps-routes.ts +5 -0
- package/src/runtime/routes/publish-routes.ts +13 -3
- package/src/runtime/routes/question-routes.ts +5 -0
- package/src/runtime/routes/recording-routes.ts +25 -12
- package/src/runtime/routes/rename-conversation-routes.ts +10 -0
- package/src/runtime/routes/sanity-routes.ts +9 -2
- package/src/runtime/routes/schedule-routes.ts +288 -88
- package/src/runtime/routes/secret-routes.ts +31 -6
- package/src/runtime/routes/sequence-routes.ts +33 -0
- package/src/runtime/routes/settings-routes.ts +65 -19
- package/src/runtime/routes/skills-routes.ts +166 -73
- package/src/runtime/routes/slack-channel-routes.ts +5 -0
- package/src/runtime/routes/stt-routes.ts +13 -6
- package/src/runtime/routes/subagents-routes.ts +24 -18
- package/src/runtime/routes/suggest-trust-rule-routes.ts +7 -2
- package/src/runtime/routes/surface-action-routes.ts +9 -0
- package/src/runtime/routes/surface-content-routes.ts +10 -2
- package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
- package/src/runtime/routes/task-routes.ts +37 -0
- package/src/runtime/routes/telemetry-routes.ts +9 -0
- package/src/runtime/routes/tool-call-confirmation-enrichment.test.ts +161 -0
- package/src/runtime/routes/tool-call-confirmation-enrichment.ts +107 -0
- package/src/runtime/routes/trace-event-routes.ts +42 -1
- package/src/runtime/routes/trust-rules-routes.ts +31 -2
- package/src/runtime/routes/tts-routes.ts +48 -6
- package/src/runtime/routes/types.ts +83 -16
- package/src/runtime/routes/ui-request-routes.ts +5 -0
- package/src/runtime/routes/upgrade-broadcast-routes.ts +5 -0
- package/src/runtime/routes/usage-routes.ts +118 -42
- package/src/runtime/routes/user-routes-cli.ts +9 -0
- package/src/runtime/routes/user-routes.ts +5 -1
- package/src/runtime/routes/wake-conversation-routes.ts +5 -0
- package/src/runtime/routes/watcher-routes.ts +21 -0
- package/src/runtime/routes/webhook-routes.ts +50 -2
- package/src/runtime/routes/wipe-conversation-routes.ts +5 -0
- package/src/runtime/routes/work-items-routes.ts +49 -23
- package/src/runtime/routes/workspace-commit-routes.ts +5 -0
- package/src/runtime/routes/workspace-routes.test.ts +42 -0
- package/src/runtime/routes/workspace-routes.ts +124 -9
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +8 -4
- package/src/runtime/services/analyze-conversation.ts +5 -8
- package/src/runtime/services/conversation-serializer.ts +24 -2
- package/src/runtime/sync/resource-sync-events.ts +16 -2
- package/src/runtime/sync/sync-publisher.ts +2 -2
- package/src/schedule/run-script.ts +28 -3
- package/src/schedule/schedule-store.ts +28 -1
- package/src/schedule/schedule-usage-store.ts +83 -0
- package/src/schedule/scheduler.ts +15 -6
- package/src/signals/cancel.ts +2 -4
- package/src/signals/user-message.ts +5 -8
- package/src/skills/catalog-files.ts +4 -1
- package/src/skills/catalog-install.ts +3 -0
- package/src/skills/categories-cache.ts +118 -0
- package/src/skills/clawhub-files.ts +1 -0
- package/src/skills/skillssh-files.ts +1 -0
- package/src/subagent/manager.ts +20 -11
- package/src/telemetry/types.ts +55 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +250 -4
- package/src/telemetry/usage-telemetry-reporter.ts +88 -2
- package/src/tools/acp/context.ts +20 -0
- package/src/tools/acp/list-agents.test.ts +7 -1
- package/src/tools/acp/spawn.test.ts +198 -93
- package/src/tools/acp/spawn.ts +32 -70
- package/src/tools/acp/steer.test.ts +105 -8
- package/src/tools/acp/steer.ts +48 -17
- package/src/tools/apps/definitions.ts +8 -4
- package/src/tools/apps/executors.ts +13 -8
- package/src/tools/ask-question/ask-question-tool.test.ts +120 -105
- package/src/tools/ask-question/ask-question-tool.ts +85 -90
- package/src/tools/computer-use/definitions.ts +28 -24
- package/src/tools/credential-execution/make-authenticated-request.ts +56 -51
- package/src/tools/credential-execution/manage-secure-command-tool.ts +2 -2
- package/src/tools/credential-execution/run-authenticated-command.ts +82 -77
- package/src/tools/credentials/vault.ts +112 -111
- package/src/tools/execution-target.ts +1 -1
- package/src/tools/execution-timeout.ts +3 -4
- package/src/tools/executor.ts +1 -53
- package/src/tools/filesystem/edit.ts +45 -42
- package/src/tools/filesystem/list.ts +33 -30
- package/src/tools/filesystem/read.ts +54 -35
- package/src/tools/filesystem/write.ts +69 -32
- package/src/tools/host-filesystem/edit.ts +44 -42
- package/src/tools/host-filesystem/read.ts +49 -35
- package/src/tools/host-filesystem/transfer.ts +121 -108
- package/src/tools/host-filesystem/write.ts +33 -31
- package/src/tools/host-terminal/host-shell.ts +50 -48
- package/src/tools/memory/register.ts +23 -24
- package/src/tools/network/__tests__/web-search-metadata.test.ts +7 -1
- package/src/tools/network/__tests__/web-search.test.ts +11 -3
- package/src/tools/network/web-fetch.ts +49 -46
- package/src/tools/network/web-search-error.test.ts +248 -0
- package/src/tools/network/web-search-error.ts +267 -0
- package/src/tools/network/web-search.ts +223 -61
- package/src/tools/registry.ts +39 -16
- package/src/tools/schedule/create.ts +13 -0
- package/src/tools/schedule/update.ts +16 -0
- package/src/tools/shared/filesystem/audio-read.ts +122 -0
- package/src/tools/shared/filesystem/image-read.ts +1 -1
- package/src/tools/skills/execute.ts +34 -31
- package/src/tools/skills/load.ts +29 -23
- package/src/tools/subagent/notify-parent.ts +35 -32
- package/src/tools/subagent/spawn.ts +2 -4
- package/src/tools/system/avatar-generator.ts +13 -22
- package/src/tools/system/request-permission.ts +30 -27
- package/src/tools/terminal/safe-env.ts +10 -1
- package/src/tools/terminal/shell.ts +190 -61
- package/src/tools/tool-defaults.ts +20 -9
- package/src/tools/tool-manifest.ts +4 -4
- package/src/tools/types.ts +74 -23
- package/src/tools/ui-surface/definitions.ts +99 -10
- package/src/tts/__tests__/provider-catalog-consistency.test.ts +85 -1
- package/src/tts/provider-catalog.ts +76 -1
- package/src/usage/types.ts +10 -0
- package/src/util/errors.ts +2 -2
- package/src/util/map-limit.ts +27 -0
- package/src/util/mutex.ts +47 -0
- package/src/util/platform.ts +15 -12
- package/src/work-items/work-item-runner.ts +7 -2
- package/src/workspace/git-service.ts +1 -42
- package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +7 -20
- package/src/workspace/migrations/092-backfill-v3-leaves.ts +169 -0
- package/src/workspace/migrations/093-backfill-leaf-ids.ts +144 -0
- package/src/workspace/migrations/094-seed-avatar-manifest.ts +155 -0
- package/src/workspace/migrations/095-bump-heartbeat-interval-30m-to-60m.ts +51 -0
- package/src/workspace/migrations/096-reduce-quality-profile-effort.ts +72 -0
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +117 -0
- package/src/workspace/migrations/__tests__/094-seed-avatar-manifest.test.ts +136 -0
- package/src/workspace/migrations/__tests__/backfill-leaf-ids.test.ts +175 -0
- package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +124 -0
- package/src/workspace/migrations/registry.ts +12 -0
- package/src/workspace/provider-commit-message-generator.ts +15 -17
- package/tsconfig.json +4 -1
- package/src/__tests__/bootstrap-turn-cleanup.test.ts +0 -44
- package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
- package/src/__tests__/compaction-pipeline.test.ts +0 -210
- package/src/__tests__/compaction-timeout-recovery.test.ts +0 -262
- package/src/__tests__/empty-response-pipeline.test.ts +0 -301
- package/src/__tests__/history-repair-pipeline.test.ts +0 -396
- package/src/__tests__/llm-call-pipeline.test.ts +0 -281
- package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -418
- package/src/__tests__/persistence-pipeline.test.ts +0 -514
- package/src/__tests__/title-generate-pipeline.test.ts +0 -211
- package/src/__tests__/token-estimate-pipeline.test.ts +0 -481
- package/src/__tests__/tool-error-pipeline.test.ts +0 -241
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -417
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -344
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +0 -340
- package/src/cli/commands/memory-v3-render.ts +0 -491
- package/src/daemon/bootstrap-turn-cleanup.ts +0 -45
- package/src/daemon/message-types/disk-pressure.ts +0 -9
- package/src/email/feature-gate.ts +0 -23
- package/src/gallery/default-gallery.ts +0 -1359
- package/src/gallery/gallery-manifest.ts +0 -28
- package/src/memory/v3/__tests__/coactivation-store.test.ts +0 -422
- package/src/memory/v3/__tests__/consolidation-job.test.ts +0 -466
- package/src/memory/v3/__tests__/coretrieval-seed.test.ts +0 -270
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +0 -324
- package/src/memory/v3/__tests__/edges.test.ts +0 -706
- package/src/memory/v3/__tests__/filter.test.ts +0 -560
- package/src/memory/v3/__tests__/gate.test.ts +0 -637
- package/src/memory/v3/__tests__/index-composition.test.ts +0 -291
- package/src/memory/v3/__tests__/loop.test.ts +0 -775
- package/src/memory/v3/__tests__/retriever.test.ts +0 -226
- package/src/memory/v3/__tests__/scouts.test.ts +0 -489
- package/src/memory/v3/__tests__/shadow-diff.test.ts +0 -225
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +0 -398
- package/src/memory/v3/__tests__/system-prompts.test.ts +0 -154
- package/src/memory/v3/__tests__/traversal.test.ts +0 -508
- package/src/memory/v3/__tests__/tree-index.test.ts +0 -280
- package/src/memory/v3/__tests__/tree-store.test.ts +0 -529
- package/src/memory/v3/__tests__/tree-walk.test.ts +0 -784
- package/src/memory/v3/__tests__/validate.test.ts +0 -277
- package/src/memory/v3/auto-edges.ts +0 -223
- package/src/memory/v3/coactivation-store.ts +0 -124
- package/src/memory/v3/consolidation-job.ts +0 -323
- package/src/memory/v3/coretrieval-seed.ts +0 -240
- package/src/memory/v3/edge-learning-job.ts +0 -160
- package/src/memory/v3/edges.ts +0 -286
- package/src/memory/v3/filter.ts +0 -286
- package/src/memory/v3/gate.ts +0 -349
- package/src/memory/v3/index-composition.ts +0 -126
- package/src/memory/v3/llm-capture.ts +0 -46
- package/src/memory/v3/loop.ts +0 -430
- package/src/memory/v3/maintenance.ts +0 -144
- package/src/memory/v3/prompt-context.ts +0 -33
- package/src/memory/v3/prompts/consolidation.ts +0 -458
- package/src/memory/v3/prompts/system-prompts.ts +0 -196
- package/src/memory/v3/retriever.ts +0 -33
- package/src/memory/v3/scouts.ts +0 -431
- package/src/memory/v3/shadow-diff.ts +0 -287
- package/src/memory/v3/shadow-middleware.ts +0 -347
- package/src/memory/v3/traversal.ts +0 -211
- package/src/memory/v3/tree-index.ts +0 -237
- package/src/memory/v3/tree-store.ts +0 -394
- package/src/memory/v3/tree-walk.ts +0 -356
- package/src/memory/v3/types.ts +0 -65
- package/src/memory/v3/validate.ts +0 -323
- package/src/plugins/defaults/circuit-breaker.ts +0 -141
- package/src/plugins/defaults/compaction.ts +0 -141
- package/src/plugins/defaults/empty-response.ts +0 -124
- package/src/plugins/defaults/history-repair.ts +0 -83
- package/src/plugins/defaults/llm-call.ts +0 -77
- package/src/plugins/defaults/memory-retrieval.ts +0 -219
- package/src/plugins/defaults/overflow-reduce.ts +0 -185
- package/src/plugins/defaults/persistence.ts +0 -146
- package/src/plugins/defaults/title-generate.ts +0 -90
- package/src/plugins/defaults/token-estimate.ts +0 -101
- package/src/plugins/defaults/tool-error.ts +0 -119
- package/src/plugins/defaults/tool-execute.ts +0 -87
- package/src/plugins/defaults/tool-result-truncate.ts +0 -84
- package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +0 -35
- package/src/skills/category-inference.ts +0 -111
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
createAssistantMessage,
|
|
11
11
|
createUserMessage,
|
|
12
12
|
} from "../../agent/message-types.js";
|
|
13
|
+
import { ConversationMessageSchema } from "../../api/responses/conversation-message.js";
|
|
13
14
|
import {
|
|
14
15
|
CHANNEL_IDS,
|
|
15
16
|
INTERFACE_IDS,
|
|
@@ -18,6 +19,7 @@ import {
|
|
|
18
19
|
parseInterfaceId,
|
|
19
20
|
supportsHostProxy,
|
|
20
21
|
} from "../../channels/types.js";
|
|
22
|
+
import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
|
|
21
23
|
import { isHttpAuthDisabled } from "../../config/env.js";
|
|
22
24
|
import { getConfig } from "../../config/loader.js";
|
|
23
25
|
import {
|
|
@@ -41,10 +43,15 @@ import { getOrCreateConversation as getOrCreateConversationInstance } from "../.
|
|
|
41
43
|
import { canonicalizeTimeZone } from "../../daemon/date-context.js";
|
|
42
44
|
import {
|
|
43
45
|
buildScanFirstMessage,
|
|
46
|
+
buildSelfIntroMessage,
|
|
44
47
|
getCannedFirstGreeting,
|
|
45
48
|
isWakeUpGreeting,
|
|
46
49
|
} from "../../daemon/first-greeting.js";
|
|
47
|
-
import {
|
|
50
|
+
import {
|
|
51
|
+
collectAttachmentRefs,
|
|
52
|
+
type HistoryAttachmentRef,
|
|
53
|
+
renderHistoryContent,
|
|
54
|
+
} from "../../daemon/handlers/shared.js";
|
|
48
55
|
import { HostAppControlProxy } from "../../daemon/host-app-control-proxy.js";
|
|
49
56
|
import { HostCuProxy } from "../../daemon/host-cu-proxy.js";
|
|
50
57
|
import {
|
|
@@ -103,10 +110,15 @@ import type { Provider } from "../../providers/types.js";
|
|
|
103
110
|
import { checkIngressForSecrets } from "../../security/secret-ingress.js";
|
|
104
111
|
import { getSubagentManager } from "../../subagent/index.js";
|
|
105
112
|
import { getLogger } from "../../util/logger.js";
|
|
106
|
-
import {
|
|
113
|
+
import {
|
|
114
|
+
getWorkspaceDir,
|
|
115
|
+
getWorkspacePromptPath,
|
|
116
|
+
} from "../../util/platform.js";
|
|
107
117
|
import { silentlyWithLog } from "../../util/silently.js";
|
|
108
118
|
import { assistantEventHub, broadcastMessage } from "../assistant-event-hub.js";
|
|
109
119
|
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../assistant-scope.js";
|
|
120
|
+
import { getPersistedSeq } from "../assistant-stream-state.js";
|
|
121
|
+
import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
|
|
110
122
|
import { routeGuardianReply } from "../guardian-reply-router.js";
|
|
111
123
|
import { healGuardianBindingDrift } from "../guardian-vellum-migration.js";
|
|
112
124
|
import type {
|
|
@@ -131,6 +143,10 @@ import {
|
|
|
131
143
|
NotFoundError,
|
|
132
144
|
RouteError,
|
|
133
145
|
} from "./errors.js";
|
|
146
|
+
import {
|
|
147
|
+
collectPendingConfirmations,
|
|
148
|
+
enrichToolCallsWithConfirmation,
|
|
149
|
+
} from "./tool-call-confirmation-enrichment.js";
|
|
134
150
|
import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
|
|
135
151
|
import { RouteResponse } from "./types.js";
|
|
136
152
|
|
|
@@ -140,6 +156,128 @@ const log = getLogger("conversation-routes");
|
|
|
140
156
|
const NO_RESPONSE_INLINE_RE = /<no_response\s*\/?>/g;
|
|
141
157
|
const ATTACHMENT_ENTRY_RE = /^attachment:(\d+)$/;
|
|
142
158
|
|
|
159
|
+
/** Rewrites a rendered `contentOrder` to reflect attachment alignment. */
|
|
160
|
+
type ContentOrderRewrite = (contentOrder: string[]) => string[];
|
|
161
|
+
|
|
162
|
+
interface AlignedAttachments {
|
|
163
|
+
/** Hydrated rows, reordered to match the inline file-block order. */
|
|
164
|
+
attachments: RuntimeAttachmentMetadata[];
|
|
165
|
+
/**
|
|
166
|
+
* Resolves a content-walk attachment ref index to its hydrated DB row,
|
|
167
|
+
* mirroring the inline placement `rewriteContentOrder` encodes. Refs with no
|
|
168
|
+
* inline placement (unmatched ids, count mismatch, no DB rows) are absent, so
|
|
169
|
+
* `renderHistoryContent` emits no `attachment` block for them — the row still
|
|
170
|
+
* ships via the flat `attachments` array.
|
|
171
|
+
*/
|
|
172
|
+
refIndexToAttachment: Map<number, RuntimeAttachmentMetadata>;
|
|
173
|
+
rewriteContentOrder: ContentOrderRewrite;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Align DB-hydrated attachment rows with the file-block refs `renderHistoryContent`
|
|
178
|
+
* captured. When a file block was persisted with `_attachmentId` (user-message
|
|
179
|
+
* uploads) we join on that id to position the chip inline; DB rows without a
|
|
180
|
+
* matching ref go to the tail as orphan chips, and unmatched refs drop their
|
|
181
|
+
* `attachment:N` entry. Assistant-authored file blocks carry no `_attachmentId`,
|
|
182
|
+
* so when no ids match we fall back to positional alignment if the ref and row
|
|
183
|
+
* counts agree; otherwise we strip the markers and let chips fall to the tail.
|
|
184
|
+
*/
|
|
185
|
+
function alignAttachments(
|
|
186
|
+
attachmentRefs: HistoryAttachmentRef[],
|
|
187
|
+
attachments: RuntimeAttachmentMetadata[],
|
|
188
|
+
): AlignedAttachments {
|
|
189
|
+
const refIndexToAttachment = new Map<number, RuntimeAttachmentMetadata>();
|
|
190
|
+
const identity: ContentOrderRewrite = (contentOrder) => contentOrder;
|
|
191
|
+
const stripAttachmentEntries: ContentOrderRewrite = (contentOrder) =>
|
|
192
|
+
contentOrder.filter((entry) => !ATTACHMENT_ENTRY_RE.test(entry));
|
|
193
|
+
|
|
194
|
+
if (attachmentRefs.length === 0) {
|
|
195
|
+
return { attachments, refIndexToAttachment, rewriteContentOrder: identity };
|
|
196
|
+
}
|
|
197
|
+
if (attachments.length === 0) {
|
|
198
|
+
// Refs were captured but no DB rows came back — drop the contentOrder
|
|
199
|
+
// entries to avoid out-of-bounds renders.
|
|
200
|
+
return {
|
|
201
|
+
attachments,
|
|
202
|
+
refIndexToAttachment,
|
|
203
|
+
rewriteContentOrder: stripAttachmentEntries,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const byId = new Map<string, number>();
|
|
208
|
+
attachments.forEach((att, idx) => {
|
|
209
|
+
if (att.id) byId.set(att.id, idx);
|
|
210
|
+
});
|
|
211
|
+
const consumed = new Set<number>();
|
|
212
|
+
const orderedRowIdx: Array<number | null> = attachmentRefs.map((ref) => {
|
|
213
|
+
if (!ref.attachmentId) return null;
|
|
214
|
+
const idx = byId.get(ref.attachmentId);
|
|
215
|
+
if (idx === undefined || consumed.has(idx)) return null;
|
|
216
|
+
consumed.add(idx);
|
|
217
|
+
return idx;
|
|
218
|
+
});
|
|
219
|
+
const matchedRows = orderedRowIdx.filter(
|
|
220
|
+
(idx): idx is number => idx !== null,
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
if (matchedRows.length > 0) {
|
|
224
|
+
const orphanRows: number[] = [];
|
|
225
|
+
for (let i = 0; i < attachments.length; i++) {
|
|
226
|
+
if (!consumed.has(i)) orphanRows.push(i);
|
|
227
|
+
}
|
|
228
|
+
const reordered = [
|
|
229
|
+
...matchedRows.map((i) => attachments[i]),
|
|
230
|
+
...orphanRows.map((i) => attachments[i]),
|
|
231
|
+
];
|
|
232
|
+
const refToNewIdx = new Map<number, number>();
|
|
233
|
+
let nextIdx = 0;
|
|
234
|
+
orderedRowIdx.forEach((rowIdx, refIdx) => {
|
|
235
|
+
if (rowIdx !== null) {
|
|
236
|
+
refToNewIdx.set(refIdx, nextIdx);
|
|
237
|
+
refIndexToAttachment.set(refIdx, reordered[nextIdx]);
|
|
238
|
+
nextIdx++;
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
const rewriteContentOrder: ContentOrderRewrite = (contentOrder) =>
|
|
242
|
+
contentOrder
|
|
243
|
+
.map((entry) => {
|
|
244
|
+
const match = entry.match(ATTACHMENT_ENTRY_RE);
|
|
245
|
+
if (!match) return entry;
|
|
246
|
+
const remapped = refToNewIdx.get(Number(match[1]));
|
|
247
|
+
return remapped !== undefined ? `attachment:${remapped}` : undefined;
|
|
248
|
+
})
|
|
249
|
+
.filter((e): e is string => e !== undefined);
|
|
250
|
+
return {
|
|
251
|
+
attachments: reordered,
|
|
252
|
+
refIndexToAttachment,
|
|
253
|
+
rewriteContentOrder,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (attachmentRefs.length !== attachments.length) {
|
|
258
|
+
// No ref carried an attachmentId we could match and the counts disagree, so
|
|
259
|
+
// positional mapping can't be trusted — strip any attachment:N entries so
|
|
260
|
+
// the client doesn't position attachments inline against a misaligned array
|
|
261
|
+
// (they fall to the tail instead).
|
|
262
|
+
return {
|
|
263
|
+
attachments,
|
|
264
|
+
refIndexToAttachment,
|
|
265
|
+
rewriteContentOrder: stripAttachmentEntries,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// No ref matched an id but the counts agree (the assistant-authored case):
|
|
270
|
+
// the Nth marker maps to the Nth row positionally, so the original
|
|
271
|
+
// contentOrder is left untouched.
|
|
272
|
+
attachmentRefs.forEach((_ref, refIdx) => {
|
|
273
|
+
refIndexToAttachment.set(refIdx, attachments[refIdx]);
|
|
274
|
+
});
|
|
275
|
+
return { attachments, refIndexToAttachment, rewriteContentOrder: identity };
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/** Feature flag gating the self-intro first message (see first-greeting.ts). */
|
|
279
|
+
const SELF_INTRO_GREETING_FLAG = "self-intro-greeting" as const;
|
|
280
|
+
|
|
143
281
|
const SUGGESTION_CACHE_MAX = 100;
|
|
144
282
|
const VALID_RISK_THRESHOLDS = ["none", "low", "medium", "high"] as const;
|
|
145
283
|
type RiskThreshold = (typeof VALID_RISK_THRESHOLDS)[number];
|
|
@@ -409,7 +547,7 @@ async function tryConsumeCanonicalGuardianReply(params: {
|
|
|
409
547
|
conversationId,
|
|
410
548
|
"user",
|
|
411
549
|
JSON.stringify(cleanUserMessage.content),
|
|
412
|
-
channelMeta,
|
|
550
|
+
{ metadata: channelMeta },
|
|
413
551
|
);
|
|
414
552
|
messageId = persistedUser.id;
|
|
415
553
|
|
|
@@ -423,7 +561,7 @@ async function tryConsumeCanonicalGuardianReply(params: {
|
|
|
423
561
|
conversationId,
|
|
424
562
|
"assistant",
|
|
425
563
|
JSON.stringify(assistantMessage.content),
|
|
426
|
-
channelMeta,
|
|
564
|
+
{ metadata: channelMeta },
|
|
427
565
|
);
|
|
428
566
|
|
|
429
567
|
// Avoid mutating in-memory history / emitting stream deltas while a run is active.
|
|
@@ -503,6 +641,7 @@ export function handleListMessages({
|
|
|
503
641
|
hasMore: false,
|
|
504
642
|
oldestTimestamp: null,
|
|
505
643
|
oldestMessageId: null,
|
|
644
|
+
seq: null,
|
|
506
645
|
};
|
|
507
646
|
}
|
|
508
647
|
return { messages: [] };
|
|
@@ -541,7 +680,14 @@ export function handleListMessages({
|
|
|
541
680
|
// assistant message has tool_use blocks but its matching user tool_result
|
|
542
681
|
// is left visible, the result will render as a standalone orphan because
|
|
543
682
|
// `mergeToolResultsIntoAssistantMessages` has nothing to merge it into.
|
|
544
|
-
|
|
683
|
+
//
|
|
684
|
+
// Only renderable roles reach this UI-facing transcript. `system` rows (a
|
|
685
|
+
// permitted `MessageRole`, e.g. skill-authored context) are agent-context
|
|
686
|
+
// scaffolding, never a displayed turn, so they are dropped here at the
|
|
687
|
+
// source rather than narrowed away per-client.
|
|
688
|
+
const visibleFilter = (m: MessageRow) =>
|
|
689
|
+
!isHiddenMessage(m.metadata) &&
|
|
690
|
+
(m.role === "user" || m.role === "assistant");
|
|
545
691
|
|
|
546
692
|
if (isPaginated) {
|
|
547
693
|
const result = getMessagesPaginated(
|
|
@@ -575,7 +721,10 @@ export function handleListMessages({
|
|
|
575
721
|
mergeConsecutiveAssistantMessages(mergedMessages);
|
|
576
722
|
const assistantSlackDisplayName = getAssistantName()?.trim() || undefined;
|
|
577
723
|
|
|
578
|
-
// Parse content
|
|
724
|
+
// Parse each row's stored content and per-message metadata. Rendering is
|
|
725
|
+
// deferred to the serializer pass below so it runs after attachment
|
|
726
|
+
// alignment, letting renderHistoryContent inline `attachment` blocks during
|
|
727
|
+
// its single content walk.
|
|
579
728
|
const parsed = consolidatedMessages.map((msg) => {
|
|
580
729
|
let content: unknown;
|
|
581
730
|
try {
|
|
@@ -583,7 +732,6 @@ export function handleListMessages({
|
|
|
583
732
|
} catch {
|
|
584
733
|
content = msg.content;
|
|
585
734
|
}
|
|
586
|
-
const rendered = renderHistoryContent(content);
|
|
587
735
|
|
|
588
736
|
// Extract sentAt from metadata for display timestamps. When a message
|
|
589
737
|
// was queued or its persistence was delayed (long assistant generation),
|
|
@@ -631,94 +779,51 @@ export function handleListMessages({
|
|
|
631
779
|
},
|
|
632
780
|
);
|
|
633
781
|
|
|
634
|
-
//
|
|
635
|
-
//
|
|
636
|
-
//
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
const keepIndices: number[] = [];
|
|
640
|
-
const filteredSegments: string[] = [];
|
|
641
|
-
for (let i = 0; i < originalSegments.length; i++) {
|
|
642
|
-
const cleaned = originalSegments[i]
|
|
643
|
-
.replace(NO_RESPONSE_INLINE_RE, "")
|
|
644
|
-
.trim();
|
|
645
|
-
if (cleaned.length > 0) {
|
|
646
|
-
keepIndices.push(i);
|
|
647
|
-
filteredSegments.push(cleaned);
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
// Remap contentOrder text:N indices to account for removed segments
|
|
651
|
-
const indexMap = new Map<number, number>();
|
|
652
|
-
keepIndices.forEach((oldIdx, newIdx) => indexMap.set(oldIdx, newIdx));
|
|
653
|
-
const filteredContentOrder = rendered.contentOrder
|
|
654
|
-
.map((entry) => {
|
|
655
|
-
const m = entry.match(/^text:(\d+)$/);
|
|
656
|
-
if (!m) return entry;
|
|
657
|
-
const newIdx = indexMap.get(Number(m[1]));
|
|
658
|
-
return newIdx !== undefined ? `text:${newIdx}` : undefined;
|
|
659
|
-
})
|
|
660
|
-
.filter((e): e is string => e !== undefined);
|
|
661
|
-
|
|
662
|
-
return {
|
|
663
|
-
role: msg.role,
|
|
664
|
-
text: rendered.text.replace(NO_RESPONSE_INLINE_RE, "").trim(),
|
|
665
|
-
timestamp: msg.createdAt,
|
|
666
|
-
sentAt,
|
|
667
|
-
toolCalls: rendered.toolCalls,
|
|
668
|
-
toolCallsBeforeText: rendered.toolCallsBeforeText,
|
|
669
|
-
textSegments: filteredSegments,
|
|
670
|
-
contentOrder: filteredContentOrder,
|
|
671
|
-
surfaces: rendered.surfaces,
|
|
672
|
-
attachmentRefs: rendered.attachments,
|
|
673
|
-
slackMessage,
|
|
674
|
-
...(rendered.thinkingSegments.length > 0
|
|
675
|
-
? { thinkingSegments: rendered.thinkingSegments }
|
|
676
|
-
: {}),
|
|
677
|
-
id: msg.id,
|
|
678
|
-
subagentNotification,
|
|
679
|
-
};
|
|
680
|
-
}
|
|
782
|
+
// `visibleFilter` has already dropped every non-renderable role, so the
|
|
783
|
+
// only values reaching here are `user` and `assistant`; narrow the raw DB
|
|
784
|
+
// `string` to the wire union.
|
|
785
|
+
const role: "user" | "assistant" =
|
|
786
|
+
msg.role === "assistant" ? "assistant" : "user";
|
|
681
787
|
|
|
682
788
|
return {
|
|
683
|
-
role: msg.role,
|
|
684
|
-
text: rendered.text,
|
|
685
|
-
timestamp: msg.createdAt,
|
|
686
|
-
sentAt,
|
|
687
|
-
toolCalls: rendered.toolCalls,
|
|
688
|
-
toolCallsBeforeText: rendered.toolCallsBeforeText,
|
|
689
|
-
textSegments: rendered.textSegments,
|
|
690
|
-
contentOrder: rendered.contentOrder,
|
|
691
|
-
surfaces: rendered.surfaces,
|
|
692
|
-
attachmentRefs: rendered.attachments,
|
|
693
|
-
slackMessage,
|
|
694
|
-
...(rendered.thinkingSegments.length > 0
|
|
695
|
-
? { thinkingSegments: rendered.thinkingSegments }
|
|
696
|
-
: {}),
|
|
697
789
|
id: msg.id,
|
|
790
|
+
role,
|
|
791
|
+
content,
|
|
792
|
+
createdAt: msg.createdAt,
|
|
793
|
+
sentAt,
|
|
698
794
|
subagentNotification,
|
|
795
|
+
slackMessage,
|
|
699
796
|
};
|
|
700
797
|
});
|
|
701
798
|
|
|
799
|
+
// Confirmation context layered onto rendered tool calls at render time: the
|
|
800
|
+
// derived scope ladder for scope-aware tools, and any in-flight prompt read
|
|
801
|
+
// from the pending-interactions registry. Both are computed once per request
|
|
802
|
+
// and applied per message below.
|
|
803
|
+
const workspaceDir = getWorkspaceDir();
|
|
804
|
+
const pendingConfirmations = collectPendingConfirmations(
|
|
805
|
+
resolvedConversationId,
|
|
806
|
+
);
|
|
807
|
+
|
|
702
808
|
const messages: RuntimeMessagePayload[] = parsed.map((m) => {
|
|
809
|
+
const mergedMessageIds = m.id ? (mergedIdMap.get(m.id) ?? []) : [];
|
|
810
|
+
|
|
811
|
+
// Hydrate the row's attachments from the DB. A metadata-only query avoids
|
|
812
|
+
// loading large base64 blobs for non-image attachments (documents, audio);
|
|
813
|
+
// full data is fetched only for images so the client can generate
|
|
814
|
+
// thumbnails for inline display on history restore. Merged messages
|
|
815
|
+
// (consecutive assistant merge) are queried too so their attachments
|
|
816
|
+
// aren't lost before DB compaction relinks them.
|
|
703
817
|
let msgAttachments: RuntimeAttachmentMetadata[] = [];
|
|
704
818
|
if (m.id) {
|
|
705
|
-
|
|
706
|
-
// blobs for non-image attachments (documents, audio). Then
|
|
707
|
-
// selectively fetch full data only for images so the client can
|
|
708
|
-
// generate thumbnails for inline display on history restore.
|
|
709
|
-
// Also query attachments for any messages that were merged into
|
|
710
|
-
// this one (consecutive assistant merge), so their attachments
|
|
711
|
-
// aren't lost before DB compaction relinks them.
|
|
712
|
-
const idsToQuery = [m.id, ...(mergedIdMap.get(m.id) ?? [])];
|
|
819
|
+
const idsToQuery = [m.id, ...mergedMessageIds];
|
|
713
820
|
const linked = idsToQuery.flatMap((id) =>
|
|
714
821
|
getAttachmentMetadataForMessage(id),
|
|
715
822
|
);
|
|
716
823
|
if (linked.length > 0) {
|
|
717
824
|
msgAttachments = linked.map((a) => {
|
|
718
825
|
if (a.mimeType.startsWith("image/")) {
|
|
719
|
-
const full = getAttachmentById(a.id, {
|
|
720
|
-
hydrateFileData: true,
|
|
721
|
-
});
|
|
826
|
+
const full = getAttachmentById(a.id, { hydrateFileData: true });
|
|
722
827
|
return {
|
|
723
828
|
id: a.id,
|
|
724
829
|
filename: a.originalFilename,
|
|
@@ -745,107 +850,101 @@ export function handleListMessages({
|
|
|
745
850
|
}
|
|
746
851
|
}
|
|
747
852
|
|
|
748
|
-
// Align
|
|
749
|
-
//
|
|
750
|
-
//
|
|
751
|
-
//
|
|
752
|
-
//
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
853
|
+
// Align the hydrated rows with the file-block refs, then render. Rendering
|
|
854
|
+
// after alignment lets renderHistoryContent inline each `attachment` block
|
|
855
|
+
// during its single content walk, so `contentBlocks` comes back ready to
|
|
856
|
+
// ship with no post-processing. The aligned reorder/rewrite keeps the
|
|
857
|
+
// legacy `attachments` array and `contentOrder` positions consistent.
|
|
858
|
+
const attachmentRefs = collectAttachmentRefs(m.content);
|
|
859
|
+
const aligned = alignAttachments(attachmentRefs, msgAttachments);
|
|
860
|
+
msgAttachments = aligned.attachments;
|
|
861
|
+
const attachmentBlocks = attachmentRefs.map(
|
|
862
|
+
(_ref, refIdx) => aligned.refIndexToAttachment.get(refIdx) ?? null,
|
|
863
|
+
);
|
|
864
|
+
const rendered = renderHistoryContent(
|
|
865
|
+
m.content,
|
|
866
|
+
attachmentBlocks,
|
|
867
|
+
m.id ?? undefined,
|
|
868
|
+
);
|
|
869
|
+
|
|
870
|
+
const toolCalls = enrichToolCallsWithConfirmation(rendered.toolCalls, {
|
|
871
|
+
workspaceDir,
|
|
872
|
+
pendingConfirmations,
|
|
873
|
+
});
|
|
874
|
+
|
|
875
|
+
// Strip <no_response/> markers from assistant messages so web/API clients
|
|
876
|
+
// never see the raw sentinel. Only assistant messages produce it; user
|
|
877
|
+
// messages are untouched. The filter is applied consistently to the flat
|
|
878
|
+
// text, the segments, the contentOrder text refs, and the text blocks of
|
|
879
|
+
// contentBlocks.
|
|
880
|
+
let text = rendered.text;
|
|
881
|
+
let textSegments = rendered.textSegments;
|
|
882
|
+
let contentOrder = rendered.contentOrder;
|
|
883
|
+
let contentBlocks = rendered.contentBlocks;
|
|
884
|
+
if (m.role === "assistant") {
|
|
885
|
+
const keepIndices: number[] = [];
|
|
886
|
+
const filteredSegments: string[] = [];
|
|
887
|
+
for (let i = 0; i < rendered.textSegments.length; i++) {
|
|
888
|
+
const cleaned = rendered.textSegments[i]
|
|
889
|
+
.replace(NO_RESPONSE_INLINE_RE, "")
|
|
890
|
+
.trim();
|
|
891
|
+
if (cleaned.length > 0) {
|
|
892
|
+
keepIndices.push(i);
|
|
893
|
+
filteredSegments.push(cleaned);
|
|
784
894
|
}
|
|
785
|
-
msgAttachments = [
|
|
786
|
-
...matchedRows.map((i) => msgAttachments[i]),
|
|
787
|
-
...orphanRows.map((i) => msgAttachments[i]),
|
|
788
|
-
];
|
|
789
|
-
const refToNewIdx = new Map<number, number>();
|
|
790
|
-
let nextIdx = 0;
|
|
791
|
-
orderedRowIdx.forEach((rowIdx, refIdx) => {
|
|
792
|
-
if (rowIdx !== null) {
|
|
793
|
-
refToNewIdx.set(refIdx, nextIdx);
|
|
794
|
-
nextIdx++;
|
|
795
|
-
}
|
|
796
|
-
});
|
|
797
|
-
alignedContentOrder = m.contentOrder
|
|
798
|
-
.map((entry) => {
|
|
799
|
-
const match = entry.match(ATTACHMENT_ENTRY_RE);
|
|
800
|
-
if (!match) return entry;
|
|
801
|
-
const remapped = refToNewIdx.get(Number(match[1]));
|
|
802
|
-
return remapped !== undefined
|
|
803
|
-
? `attachment:${remapped}`
|
|
804
|
-
: undefined;
|
|
805
|
-
})
|
|
806
|
-
.filter((e): e is string => e !== undefined);
|
|
807
|
-
} else if (m.attachmentRefs.length !== msgAttachments.length) {
|
|
808
|
-
// No ref carried an attachmentId we could match and the counts
|
|
809
|
-
// disagree, so positional mapping can't be trusted — strip any
|
|
810
|
-
// attachment:N entries so the client doesn't position attachments
|
|
811
|
-
// inline against a misaligned array (they fall to the tail instead).
|
|
812
|
-
alignedContentOrder = m.contentOrder.filter(
|
|
813
|
-
(entry) => !ATTACHMENT_ENTRY_RE.test(entry),
|
|
814
|
-
);
|
|
815
895
|
}
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
896
|
+
const indexMap = new Map<number, number>();
|
|
897
|
+
keepIndices.forEach((oldIdx, newIdx) => indexMap.set(oldIdx, newIdx));
|
|
898
|
+
contentOrder = rendered.contentOrder
|
|
899
|
+
.map((entry) => {
|
|
900
|
+
const tm = entry.match(/^text:(\d+)$/);
|
|
901
|
+
if (!tm) return entry;
|
|
902
|
+
const newIdx = indexMap.get(Number(tm[1]));
|
|
903
|
+
return newIdx !== undefined ? `text:${newIdx}` : undefined;
|
|
904
|
+
})
|
|
905
|
+
.filter((e): e is string => e !== undefined);
|
|
906
|
+
textSegments = filteredSegments;
|
|
907
|
+
text = rendered.text.replace(NO_RESPONSE_INLINE_RE, "").trim();
|
|
908
|
+
contentBlocks = rendered.contentBlocks
|
|
909
|
+
.map((block) =>
|
|
910
|
+
block.type === "text"
|
|
911
|
+
? {
|
|
912
|
+
type: "text" as const,
|
|
913
|
+
text: block.text.replace(NO_RESPONSE_INLINE_RE, "").trim(),
|
|
914
|
+
}
|
|
915
|
+
: block,
|
|
916
|
+
)
|
|
917
|
+
.filter((block) => block.type !== "text" || block.text.length > 0);
|
|
825
918
|
}
|
|
826
919
|
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
//
|
|
830
|
-
//
|
|
831
|
-
//
|
|
832
|
-
//
|
|
833
|
-
|
|
920
|
+
const alignedContentOrder = aligned.rewriteContentOrder(contentOrder);
|
|
921
|
+
|
|
922
|
+
// Use sentAt (actual event time) for the display timestamp when available,
|
|
923
|
+
// falling back to createdAt (persistence time). Clients use this display
|
|
924
|
+
// timestamp as their pagination cursor after memory-pressure trimming,
|
|
925
|
+
// while server-side pagination filters on createdAt. The mismatch is
|
|
926
|
+
// benign — it may return slightly extra data on a page boundary but never
|
|
927
|
+
// loses messages.
|
|
928
|
+
const displayTimestamp = m.sentAt ?? m.createdAt;
|
|
834
929
|
return {
|
|
835
930
|
id: m.id ?? "",
|
|
931
|
+
...(mergedMessageIds.length > 0 ? { mergedMessageIds } : {}),
|
|
836
932
|
role: m.role,
|
|
837
|
-
|
|
933
|
+
// Flat plain-text body the legacy Swift client reads directly; see the
|
|
934
|
+
// `content` field on ConversationMessageSchema for why this must stay.
|
|
935
|
+
content: text,
|
|
838
936
|
timestamp: new Date(displayTimestamp).toISOString(),
|
|
839
937
|
attachments: msgAttachments,
|
|
840
|
-
...(
|
|
841
|
-
...(
|
|
842
|
-
...(
|
|
843
|
-
...(
|
|
844
|
-
? { thinkingSegments:
|
|
938
|
+
...(toolCalls.length > 0 ? { toolCalls } : {}),
|
|
939
|
+
...(rendered.surfaces.length > 0 ? { surfaces: rendered.surfaces } : {}),
|
|
940
|
+
...(textSegments.length > 0 ? { textSegments } : {}),
|
|
941
|
+
...(rendered.thinkingSegments.length > 0
|
|
942
|
+
? { thinkingSegments: rendered.thinkingSegments }
|
|
845
943
|
: {}),
|
|
846
944
|
...(alignedContentOrder.length > 0
|
|
847
945
|
? { contentOrder: alignedContentOrder }
|
|
848
946
|
: {}),
|
|
947
|
+
...(contentBlocks.length > 0 ? { contentBlocks } : {}),
|
|
849
948
|
...(m.subagentNotification
|
|
850
949
|
? { subagentNotification: m.subagentNotification }
|
|
851
950
|
: {}),
|
|
@@ -853,6 +952,13 @@ export function handleListMessages({
|
|
|
853
952
|
};
|
|
854
953
|
});
|
|
855
954
|
|
|
955
|
+
// Snapshot↔stream alignment token: the `seq` of the last event whose
|
|
956
|
+
// content is durably persisted for this conversation in the current
|
|
957
|
+
// daemon process. Returned on every resolved-conversation response so a
|
|
958
|
+
// client can apply only stream events with a higher `seq`. Null when
|
|
959
|
+
// nothing has been persisted in-process (cold/aged-out/post-restart).
|
|
960
|
+
const persistedSeq = getPersistedSeq(resolvedConversationId);
|
|
961
|
+
|
|
856
962
|
if (isPaginated) {
|
|
857
963
|
// Prefer the page's oldest visible row (the documented cursor semantic).
|
|
858
964
|
// When a scan-cap-truncated page comes back empty there's no visible row
|
|
@@ -874,6 +980,7 @@ export function handleListMessages({
|
|
|
874
980
|
hasMore,
|
|
875
981
|
oldestTimestamp: oldestTimestamp ?? null,
|
|
876
982
|
oldestMessageId: oldestMessageId ?? null,
|
|
983
|
+
seq: persistedSeq,
|
|
877
984
|
};
|
|
878
985
|
}
|
|
879
986
|
|
|
@@ -882,10 +989,11 @@ export function handleListMessages({
|
|
|
882
989
|
hasMore,
|
|
883
990
|
...(oldestTimestamp != null ? { oldestTimestamp } : {}),
|
|
884
991
|
...(oldestMessageId != null ? { oldestMessageId } : {}),
|
|
992
|
+
seq: persistedSeq,
|
|
885
993
|
};
|
|
886
994
|
}
|
|
887
995
|
|
|
888
|
-
return { messages };
|
|
996
|
+
return { messages, seq: persistedSeq };
|
|
889
997
|
}
|
|
890
998
|
|
|
891
999
|
/**
|
|
@@ -1330,10 +1438,20 @@ export async function handleSendMessage(
|
|
|
1330
1438
|
}
|
|
1331
1439
|
|
|
1332
1440
|
const isInteractive = isInteractiveInterface(sourceInterface);
|
|
1441
|
+
// Use the JWT-verified requester principal — not guardianPrincipalId,
|
|
1442
|
+
// which is the workspace owner and would let a trusted contact's web
|
|
1443
|
+
// turn match against the guardian's macOS client.
|
|
1444
|
+
const sourceActorPrincipalId = actorPrincipalId ?? undefined;
|
|
1333
1445
|
// Bash/File/Transfer singletons are globally available via isAvailable() —
|
|
1334
1446
|
// no per-conversation gating needed. CU is per-conversation (owns step
|
|
1335
1447
|
// count, AX tree history, loop detection).
|
|
1336
|
-
if (
|
|
1448
|
+
if (
|
|
1449
|
+
shouldAttachHostProxyForCapability(
|
|
1450
|
+
"host_cu",
|
|
1451
|
+
sourceInterface,
|
|
1452
|
+
sourceActorPrincipalId,
|
|
1453
|
+
)
|
|
1454
|
+
) {
|
|
1337
1455
|
if (!conversation.isProcessing() || !conversation.hostCuProxy) {
|
|
1338
1456
|
conversation.setHostCuProxy(new HostCuProxy());
|
|
1339
1457
|
}
|
|
@@ -1346,7 +1464,13 @@ export async function handleSendMessage(
|
|
|
1346
1464
|
// lives in the skill-projection layer (which reads the `feature-flag:
|
|
1347
1465
|
// app-control` declaration in SKILL.md frontmatter), so an attached proxy
|
|
1348
1466
|
// is harmless when the flag resolves to off.
|
|
1349
|
-
if (
|
|
1467
|
+
if (
|
|
1468
|
+
shouldAttachHostProxyForCapability(
|
|
1469
|
+
"host_app_control",
|
|
1470
|
+
sourceInterface,
|
|
1471
|
+
sourceActorPrincipalId,
|
|
1472
|
+
)
|
|
1473
|
+
) {
|
|
1350
1474
|
if (!conversation.isProcessing() || !conversation.hostAppControlProxy) {
|
|
1351
1475
|
conversation.setHostAppControlProxy(
|
|
1352
1476
|
new HostAppControlProxy(mapping.conversationId),
|
|
@@ -1359,7 +1483,11 @@ export async function handleSendMessage(
|
|
|
1359
1483
|
// this message will be queued and preactivation is deferred to dequeue
|
|
1360
1484
|
// time in drainQueueImpl to avoid mutating in-flight turn state.
|
|
1361
1485
|
if (!conversation.isProcessing()) {
|
|
1362
|
-
preactivateHostProxySkills(
|
|
1486
|
+
preactivateHostProxySkills(
|
|
1487
|
+
conversation,
|
|
1488
|
+
sourceInterface,
|
|
1489
|
+
sourceActorPrincipalId,
|
|
1490
|
+
);
|
|
1363
1491
|
}
|
|
1364
1492
|
// Wire sendToClient to the SSE hub so all subsystems can reach the HTTP client.
|
|
1365
1493
|
// hasNoClient must remain `!isInteractive` so downstream tool gating
|
|
@@ -1392,6 +1520,16 @@ export async function handleSendMessage(
|
|
|
1392
1520
|
conversation.getMessages().length,
|
|
1393
1521
|
);
|
|
1394
1522
|
const isScanPath = !!scanUrl && isWakeUp;
|
|
1523
|
+
// Self-intro path: when we know a name, send a natural introduction on the
|
|
1524
|
+
// user's behalf instead of the canned greeting, so the assistant generates a
|
|
1525
|
+
// real first response. Gated behind the `self-intro-greeting` flag (default
|
|
1526
|
+
// off); `undefined` (flag off or no names) falls back to the canned path.
|
|
1527
|
+
const selfIntroGreetingEnabled =
|
|
1528
|
+
isWakeUp &&
|
|
1529
|
+
isAssistantFeatureFlagEnabled(SELF_INTRO_GREETING_FLAG, getConfig());
|
|
1530
|
+
const selfIntro = selfIntroGreetingEnabled
|
|
1531
|
+
? buildSelfIntroMessage(body.onboarding ?? undefined)
|
|
1532
|
+
: undefined;
|
|
1395
1533
|
|
|
1396
1534
|
let effectiveContent: string | undefined;
|
|
1397
1535
|
if (isScanPath) {
|
|
@@ -1400,12 +1538,16 @@ export async function handleSendMessage(
|
|
|
1400
1538
|
: ("content-source" as const);
|
|
1401
1539
|
effectiveContent = buildScanFirstMessage(scanUrl, scanVariant);
|
|
1402
1540
|
// Fall through to normal inference path below
|
|
1403
|
-
} else if (
|
|
1541
|
+
} else if (selfIntroGreetingEnabled && body.onboarding?.initialMessage) {
|
|
1404
1542
|
effectiveContent = body.onboarding.initialMessage;
|
|
1543
|
+
} else if (isWakeUp && selfIntro) {
|
|
1544
|
+
// Rewrite to the self-introduction and fall through to real inference
|
|
1545
|
+
// (mirrors the scan path above).
|
|
1546
|
+
effectiveContent = selfIntro;
|
|
1405
1547
|
} else if (isWakeUp) {
|
|
1406
1548
|
const cannedGreeting = getCannedFirstGreeting(body.onboarding ?? undefined);
|
|
1407
1549
|
|
|
1408
|
-
conversation.
|
|
1550
|
+
conversation.setProcessing(true);
|
|
1409
1551
|
let cleanupDeferred = false;
|
|
1410
1552
|
try {
|
|
1411
1553
|
const rawContent = content ?? "";
|
|
@@ -1435,7 +1577,7 @@ export async function handleSendMessage(
|
|
|
1435
1577
|
mapping.conversationId,
|
|
1436
1578
|
"assistant",
|
|
1437
1579
|
JSON.stringify(assistantMsg.content),
|
|
1438
|
-
channelMeta,
|
|
1580
|
+
{ metadata: channelMeta },
|
|
1439
1581
|
);
|
|
1440
1582
|
conversation.getMessages().push(assistantMsg);
|
|
1441
1583
|
|
|
@@ -1481,7 +1623,7 @@ export async function handleSendMessage(
|
|
|
1481
1623
|
persistedAssistant.id,
|
|
1482
1624
|
);
|
|
1483
1625
|
publishConversationMessagesChanged(conversationId, originClientId);
|
|
1484
|
-
conversation.
|
|
1626
|
+
conversation.setProcessing(false);
|
|
1485
1627
|
silentlyWithLog(
|
|
1486
1628
|
conversation.drainQueue(),
|
|
1487
1629
|
"canned-greeting queue drain",
|
|
@@ -1497,8 +1639,8 @@ export async function handleSendMessage(
|
|
|
1497
1639
|
cleanupDeferred = true;
|
|
1498
1640
|
return response;
|
|
1499
1641
|
} finally {
|
|
1500
|
-
if (!cleanupDeferred && conversation.
|
|
1501
|
-
conversation.
|
|
1642
|
+
if (!cleanupDeferred && conversation.isProcessing()) {
|
|
1643
|
+
conversation.setProcessing(false);
|
|
1502
1644
|
silentlyWithLog(conversation.drainQueue(), "error-path queue drain");
|
|
1503
1645
|
}
|
|
1504
1646
|
}
|
|
@@ -1711,7 +1853,7 @@ export async function handleSendMessage(
|
|
|
1711
1853
|
const slashResult = await resolveSlash(rawContent, slashContext);
|
|
1712
1854
|
|
|
1713
1855
|
if (slashResult.kind === "unknown") {
|
|
1714
|
-
conversation.
|
|
1856
|
+
conversation.setProcessing(true);
|
|
1715
1857
|
let cleanupDeferred = false;
|
|
1716
1858
|
try {
|
|
1717
1859
|
const slashMeta = {
|
|
@@ -1744,7 +1886,7 @@ export async function handleSendMessage(
|
|
|
1744
1886
|
mapping.conversationId,
|
|
1745
1887
|
"assistant",
|
|
1746
1888
|
JSON.stringify(assistantMsg.content),
|
|
1747
|
-
channelMeta,
|
|
1889
|
+
{ metadata: channelMeta },
|
|
1748
1890
|
);
|
|
1749
1891
|
conversation.getMessages().push(assistantMsg);
|
|
1750
1892
|
|
|
@@ -1792,7 +1934,7 @@ export async function handleSendMessage(
|
|
|
1792
1934
|
persistedAssistant.id,
|
|
1793
1935
|
);
|
|
1794
1936
|
publishConversationMessagesChanged(conversationId, originClientId);
|
|
1795
|
-
conversation.
|
|
1937
|
+
conversation.setProcessing(false);
|
|
1796
1938
|
silentlyWithLog(conversation.drainQueue(), "slash-command queue drain");
|
|
1797
1939
|
}, 0);
|
|
1798
1940
|
|
|
@@ -1801,15 +1943,15 @@ export async function handleSendMessage(
|
|
|
1801
1943
|
} finally {
|
|
1802
1944
|
// No-op for the slash-command early-return path (handled inside
|
|
1803
1945
|
// setTimeout above), but still needed for error paths.
|
|
1804
|
-
if (!cleanupDeferred && conversation.
|
|
1805
|
-
conversation.
|
|
1946
|
+
if (!cleanupDeferred && conversation.isProcessing()) {
|
|
1947
|
+
conversation.setProcessing(false);
|
|
1806
1948
|
silentlyWithLog(conversation.drainQueue(), "error-path queue drain");
|
|
1807
1949
|
}
|
|
1808
1950
|
}
|
|
1809
1951
|
}
|
|
1810
1952
|
|
|
1811
1953
|
if (slashResult.kind === "compact") {
|
|
1812
|
-
conversation.
|
|
1954
|
+
conversation.setProcessing(true);
|
|
1813
1955
|
const slashMeta = {
|
|
1814
1956
|
userMessageChannel: sourceChannel,
|
|
1815
1957
|
assistantMessageChannel: sourceChannel,
|
|
@@ -1829,12 +1971,12 @@ export async function handleSendMessage(
|
|
|
1829
1971
|
// The fire-and-forget compaction below owns clearing `processing`, but a
|
|
1830
1972
|
// throw from this initial persist never reaches it — reset here so the
|
|
1831
1973
|
// conversation isn't stranded in queued mode.
|
|
1832
|
-
conversation.
|
|
1974
|
+
conversation.setProcessing(false);
|
|
1833
1975
|
silentlyWithLog(conversation.drainQueue(), "compact-command queue drain");
|
|
1834
1976
|
throw err;
|
|
1835
1977
|
}
|
|
1836
1978
|
if (persisted.deduplicated) {
|
|
1837
|
-
conversation.
|
|
1979
|
+
conversation.setProcessing(false);
|
|
1838
1980
|
silentlyWithLog(conversation.drainQueue(), "compact-dedup queue drain");
|
|
1839
1981
|
return {
|
|
1840
1982
|
accepted: true,
|
|
@@ -1862,14 +2004,8 @@ export async function handleSendMessage(
|
|
|
1862
2004
|
clientMessageId,
|
|
1863
2005
|
});
|
|
1864
2006
|
publishConversationMessagesChanged(conversationId, originClientId);
|
|
1865
|
-
conversation.emitActivityState(
|
|
1866
|
-
|
|
1867
|
-
"context_compacting",
|
|
1868
|
-
"assistant_turn",
|
|
1869
|
-
);
|
|
1870
|
-
const result = await conversation.forceCompact({
|
|
1871
|
-
targetInputTokensOverride: slashResult.targetInputTokensOverride,
|
|
1872
|
-
});
|
|
2007
|
+
conversation.emitActivityState("thinking", "context_compacting");
|
|
2008
|
+
const result = await conversation.forceCompact();
|
|
1873
2009
|
const responseText = formatCompactResult(result);
|
|
1874
2010
|
|
|
1875
2011
|
const assistantMsg = createAssistantMessage(responseText);
|
|
@@ -1877,7 +2013,7 @@ export async function handleSendMessage(
|
|
|
1877
2013
|
conversationId,
|
|
1878
2014
|
"assistant",
|
|
1879
2015
|
JSON.stringify(assistantMsg.content),
|
|
1880
|
-
channelMeta,
|
|
2016
|
+
{ metadata: channelMeta },
|
|
1881
2017
|
);
|
|
1882
2018
|
assistantMessagePersisted = true;
|
|
1883
2019
|
conversation.getMessages().push(assistantMsg);
|
|
@@ -1906,7 +2042,7 @@ export async function handleSendMessage(
|
|
|
1906
2042
|
retryable: true,
|
|
1907
2043
|
});
|
|
1908
2044
|
} finally {
|
|
1909
|
-
conversation.
|
|
2045
|
+
conversation.setProcessing(false);
|
|
1910
2046
|
silentlyWithLog(
|
|
1911
2047
|
conversation.drainQueue(),
|
|
1912
2048
|
"compact-command queue drain",
|
|
@@ -1922,7 +2058,7 @@ export async function handleSendMessage(
|
|
|
1922
2058
|
}
|
|
1923
2059
|
|
|
1924
2060
|
if (slashResult.kind === "clean") {
|
|
1925
|
-
conversation.
|
|
2061
|
+
conversation.setProcessing(true);
|
|
1926
2062
|
const conversationId = mapping.conversationId;
|
|
1927
2063
|
// Outer try/finally guarantees the processing flag is cleared (and the
|
|
1928
2064
|
// queue drained) on every failure path — including a throw from the
|
|
@@ -1972,7 +2108,7 @@ export async function handleSendMessage(
|
|
|
1972
2108
|
conversationId,
|
|
1973
2109
|
"assistant",
|
|
1974
2110
|
JSON.stringify(assistantMsg.content),
|
|
1975
|
-
channelMeta,
|
|
2111
|
+
{ metadata: channelMeta },
|
|
1976
2112
|
);
|
|
1977
2113
|
assistantMessagePersisted = true;
|
|
1978
2114
|
conversation.getMessages().push(assistantMsg);
|
|
@@ -2008,7 +2144,7 @@ export async function handleSendMessage(
|
|
|
2008
2144
|
conversationId,
|
|
2009
2145
|
};
|
|
2010
2146
|
} finally {
|
|
2011
|
-
conversation.
|
|
2147
|
+
conversation.setProcessing(false);
|
|
2012
2148
|
silentlyWithLog(conversation.drainQueue(), "clean-command queue drain");
|
|
2013
2149
|
}
|
|
2014
2150
|
}
|
|
@@ -2046,7 +2182,8 @@ export async function handleSendMessage(
|
|
|
2046
2182
|
|
|
2047
2183
|
// Fire-and-forget the agent loop; events flow to the hub via broadcastMessage.
|
|
2048
2184
|
conversation
|
|
2049
|
-
.runAgentLoop(resolvedContent, messageId,
|
|
2185
|
+
.runAgentLoop(resolvedContent, messageId, {
|
|
2186
|
+
onEvent: broadcastMessage,
|
|
2050
2187
|
isInteractive,
|
|
2051
2188
|
isUserMessage: true,
|
|
2052
2189
|
})
|
|
@@ -2124,9 +2261,10 @@ async function generateLlmSuggestion(
|
|
|
2124
2261
|
// tokens here would be wasteful.
|
|
2125
2262
|
const response = await provider.sendMessage(
|
|
2126
2263
|
[{ role: "user", content: [{ type: "text", text: userPrompt }] }],
|
|
2127
|
-
[], // no tools
|
|
2128
|
-
systemPrompt,
|
|
2129
2264
|
{
|
|
2265
|
+
tools: [],
|
|
2266
|
+
// no tools
|
|
2267
|
+
systemPrompt,
|
|
2130
2268
|
config: {
|
|
2131
2269
|
callSite: "replySuggestion",
|
|
2132
2270
|
max_tokens: 60,
|
|
@@ -2418,12 +2556,54 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
2418
2556
|
operationId: "messages_get",
|
|
2419
2557
|
endpoint: "messages",
|
|
2420
2558
|
method: "GET",
|
|
2559
|
+
policy: {
|
|
2560
|
+
requiredScopes: ["chat.read"],
|
|
2561
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
2562
|
+
},
|
|
2421
2563
|
summary: "List messages",
|
|
2422
2564
|
description:
|
|
2423
2565
|
"Return messages for a conversation, including attachments and interface file metadata.",
|
|
2424
2566
|
tags: ["messages"],
|
|
2567
|
+
queryParams: [
|
|
2568
|
+
{
|
|
2569
|
+
name: "conversationId",
|
|
2570
|
+
type: "string",
|
|
2571
|
+
required: false,
|
|
2572
|
+
description:
|
|
2573
|
+
"Conversation UUID. One of conversationId or conversationKey is required.",
|
|
2574
|
+
},
|
|
2575
|
+
{
|
|
2576
|
+
name: "conversationKey",
|
|
2577
|
+
type: "string",
|
|
2578
|
+
required: false,
|
|
2579
|
+
description:
|
|
2580
|
+
"Channel/external conversation key. One of conversationId or conversationKey is required.",
|
|
2581
|
+
},
|
|
2582
|
+
{
|
|
2583
|
+
name: "page",
|
|
2584
|
+
type: "string",
|
|
2585
|
+
required: false,
|
|
2586
|
+
description:
|
|
2587
|
+
"When set to 'latest', returns the most recent page of messages with pagination metadata.",
|
|
2588
|
+
},
|
|
2589
|
+
{
|
|
2590
|
+
name: "beforeTimestamp",
|
|
2591
|
+
type: "integer",
|
|
2592
|
+
required: false,
|
|
2593
|
+
description:
|
|
2594
|
+
"Return messages older than this timestamp (ms since epoch). Used for paging older history.",
|
|
2595
|
+
},
|
|
2596
|
+
{
|
|
2597
|
+
name: "limit",
|
|
2598
|
+
type: "integer",
|
|
2599
|
+
required: false,
|
|
2600
|
+
description: "Maximum number of messages to return.",
|
|
2601
|
+
},
|
|
2602
|
+
],
|
|
2425
2603
|
responseBody: z.object({
|
|
2426
|
-
messages: z
|
|
2604
|
+
messages: z
|
|
2605
|
+
.array(ConversationMessageSchema)
|
|
2606
|
+
.describe("Array of message objects"),
|
|
2427
2607
|
hasMore: z
|
|
2428
2608
|
.boolean()
|
|
2429
2609
|
.optional()
|
|
@@ -2440,6 +2620,13 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
2440
2620
|
.nullable()
|
|
2441
2621
|
.optional()
|
|
2442
2622
|
.describe("ID of the oldest message in this page"),
|
|
2623
|
+
seq: z
|
|
2624
|
+
.number()
|
|
2625
|
+
.nullable()
|
|
2626
|
+
.optional()
|
|
2627
|
+
.describe(
|
|
2628
|
+
"Global SSE `seq` of the last event whose content is durably persisted for this conversation in the current daemon process. A client can align this snapshot with the `/events` stream by applying only events with `seq` greater than this value. Null when no events have been persisted in this process (cold conversation, after a daemon restart, or when the conversation has aged out of the in-memory map) — clients should cold-start in that case. Absent on older daemons that predate this field.",
|
|
2629
|
+
),
|
|
2443
2630
|
}),
|
|
2444
2631
|
handler: (args) => handleListMessages(args),
|
|
2445
2632
|
},
|
|
@@ -2447,23 +2634,70 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
2447
2634
|
operationId: "messages_post",
|
|
2448
2635
|
endpoint: "messages",
|
|
2449
2636
|
method: "POST",
|
|
2637
|
+
policy: {
|
|
2638
|
+
requiredScopes: ["chat.write"],
|
|
2639
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
2640
|
+
},
|
|
2450
2641
|
summary: "Send a message",
|
|
2451
2642
|
description:
|
|
2452
2643
|
"Send a user message to a conversation and trigger the assistant response.",
|
|
2453
2644
|
tags: ["messages"],
|
|
2454
2645
|
responseStatus: "202",
|
|
2455
2646
|
requestBody: z.object({
|
|
2456
|
-
|
|
2647
|
+
conversationId: z
|
|
2648
|
+
.string()
|
|
2649
|
+
.nullable()
|
|
2650
|
+
.optional()
|
|
2651
|
+
.describe(
|
|
2652
|
+
"Internal conversation id (0.8.6+ strict lookup). Omit both id and key to mint a new conversation server-side.",
|
|
2653
|
+
),
|
|
2654
|
+
conversationKey: z.string().nullable().optional(),
|
|
2457
2655
|
content: z.string().describe("Message text content"),
|
|
2458
2656
|
attachments: z
|
|
2459
2657
|
.array(z.unknown())
|
|
2460
|
-
.describe("Optional file attachments")
|
|
2658
|
+
.describe("Optional inline file attachments")
|
|
2461
2659
|
.optional(),
|
|
2660
|
+
attachmentIds: z
|
|
2661
|
+
.array(z.string())
|
|
2662
|
+
.describe("Ids of previously uploaded attachments to attach")
|
|
2663
|
+
.optional(),
|
|
2664
|
+
sourceChannel: z
|
|
2665
|
+
.string()
|
|
2666
|
+
.describe('Originating channel id (e.g. "vellum")'),
|
|
2667
|
+
interface: z
|
|
2668
|
+
.string()
|
|
2669
|
+
.describe('Originating interface id (e.g. "vellum")'),
|
|
2462
2670
|
conversationType: z.string().optional(),
|
|
2463
2671
|
slashCommand: z.string().optional(),
|
|
2464
2672
|
clientTimezone: z.string().optional(),
|
|
2465
2673
|
inferenceProfile: z.string().nullable().optional(),
|
|
2466
2674
|
riskThreshold: z.enum(VALID_RISK_THRESHOLDS).optional(),
|
|
2675
|
+
onboarding: z
|
|
2676
|
+
.object({
|
|
2677
|
+
tools: z.array(z.string()),
|
|
2678
|
+
tasks: z.array(z.string()),
|
|
2679
|
+
tone: z.string(),
|
|
2680
|
+
userName: z.string().optional(),
|
|
2681
|
+
assistantName: z.string().optional(),
|
|
2682
|
+
googleConnected: z.boolean().optional(),
|
|
2683
|
+
googleScopes: z.array(z.string()).optional(),
|
|
2684
|
+
priorAssistants: z.array(z.string()).optional(),
|
|
2685
|
+
cohort: z.string().optional(),
|
|
2686
|
+
websiteUrl: z.string().optional(),
|
|
2687
|
+
contentSourceUrl: z.string().optional(),
|
|
2688
|
+
bootstrapTemplate: z.string().optional(),
|
|
2689
|
+
initialMessage: z.string().optional(),
|
|
2690
|
+
skills: z.array(z.string()).optional(),
|
|
2691
|
+
})
|
|
2692
|
+
.describe("PreChat onboarding context, sent on the first message only")
|
|
2693
|
+
.optional(),
|
|
2694
|
+
}),
|
|
2695
|
+
responseBody: z.object({
|
|
2696
|
+
accepted: z.boolean(),
|
|
2697
|
+
conversationId: z.string().optional(),
|
|
2698
|
+
messageId: z.string().optional(),
|
|
2699
|
+
queued: z.boolean().optional(),
|
|
2700
|
+
requestId: z.string().optional(),
|
|
2467
2701
|
}),
|
|
2468
2702
|
handler: async (args) =>
|
|
2469
2703
|
handleSendMessage(args, {
|
|
@@ -2479,6 +2713,10 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
2479
2713
|
operationId: "search_get",
|
|
2480
2714
|
endpoint: "search",
|
|
2481
2715
|
method: "GET",
|
|
2716
|
+
policy: {
|
|
2717
|
+
requiredScopes: ["chat.read"],
|
|
2718
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
2719
|
+
},
|
|
2482
2720
|
summary: "Search conversations",
|
|
2483
2721
|
description: "Full-text search across all conversations.",
|
|
2484
2722
|
tags: ["conversations"],
|
|
@@ -2492,6 +2730,10 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
2492
2730
|
operationId: "suggestion_get",
|
|
2493
2731
|
endpoint: "suggestion",
|
|
2494
2732
|
method: "GET",
|
|
2733
|
+
policy: {
|
|
2734
|
+
requiredScopes: ["chat.read"],
|
|
2735
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
2736
|
+
},
|
|
2495
2737
|
summary: "Get reply suggestion",
|
|
2496
2738
|
description:
|
|
2497
2739
|
"Return an LLM-generated follow-up suggestion for the most recent assistant message.",
|