@vellumai/assistant 0.8.6 → 0.8.7
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 +1 -0
- package/bun.lock +11 -2
- package/docker-entrypoint.sh +8 -6
- package/docs/plugins.md +63 -28
- package/examples/plugins/echo/register.ts +4 -7
- 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/skill-host.ts +6 -2
- package/openapi.yaml +3735 -353
- package/package.json +7 -3
- package/scripts/generate-openapi.ts +20 -13
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +42 -80
- package/src/__tests__/agent-loop-exit-reason.test.ts +240 -39
- 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 +6 -4
- package/src/__tests__/agent-loop-thinking.test.ts +17 -12
- package/src/__tests__/agent-loop.test.ts +207 -341
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +4 -2
- package/src/__tests__/agent-wake-override-profile.test.ts +22 -40
- package/src/__tests__/anthropic-provider.test.ts +201 -55
- package/src/__tests__/app-builder-skill-instructions.test.ts +22 -0
- package/src/__tests__/app-control-flow.test.ts +5 -0
- package/src/__tests__/approval-cascade.test.ts +4 -11
- package/src/__tests__/approval-routes-http.test.ts +4 -2
- package/src/__tests__/assistant-event.test.ts +15 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
- 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__/btw-routes.test.ts +7 -12
- 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 +48 -20
- package/src/__tests__/channel-approvals.test.ts +3 -1
- 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__/circuit-breaker-pipeline.test.ts +3 -3
- package/src/__tests__/clawhub-files.test.ts +1 -0
- package/src/__tests__/compaction-events.test.ts +5 -17
- package/src/__tests__/compaction-pipeline.test.ts +1 -1
- package/src/__tests__/compaction-timeout-recovery.test.ts +37 -48
- package/src/__tests__/compaction-trail-store.test.ts +1 -79
- 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 +14 -7
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +3 -2
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +12 -27
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +430 -90
- package/src/__tests__/conversation-agent-loop.test.ts +581 -62
- package/src/__tests__/conversation-analysis-routes.test.ts +1 -3
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
- 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-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 +34 -4
- package/src/__tests__/conversation-pre-run-repair.test.ts +1 -1
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -0
- package/src/__tests__/conversation-process-callsite.test.ts +27 -30
- package/src/__tests__/conversation-provider-retry-repair.test.ts +53 -44
- package/src/__tests__/conversation-queue.test.ts +270 -164
- package/src/__tests__/conversation-routes-disk-view.test.ts +3 -2
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +2 -2
- package/src/__tests__/conversation-routes-slash-commands.test.ts +2 -2
- package/src/__tests__/conversation-runtime-assembly.test.ts +20 -22
- package/src/__tests__/conversation-runtime-workspace.test.ts +19 -1
- package/src/__tests__/conversation-slash-queue.test.ts +37 -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-stream-state.test.ts +484 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +6 -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-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 +3 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +48 -22
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +27 -7
- 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 +6 -2
- package/src/__tests__/cu-unified-flow.test.ts +26 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +11 -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 +7 -2
- package/src/__tests__/dynamic-page-surface.test.ts +68 -0
- package/src/__tests__/edit-propagation.test.ts +1 -2
- package/src/__tests__/empty-response-pipeline.test.ts +127 -5
- package/src/__tests__/filing-service.test.ts +2 -2
- package/src/__tests__/first-greeting.test.ts +55 -14
- package/src/__tests__/gemini-inline-media.test.ts +78 -0
- package/src/__tests__/gemini-provider.test.ts +351 -28
- package/src/__tests__/guardian-routing-state.test.ts +60 -71
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +9 -7
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +2 -1
- package/src/__tests__/history-repair-hook.test.ts +161 -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-cu-proxy.test.ts +2 -0
- 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 +35 -14
- package/src/__tests__/inbound-slack-persistence.test.ts +7 -2
- package/src/__tests__/injector-background-turn.test.ts +1 -1
- package/src/__tests__/injector-chain.test.ts +1 -1
- package/src/__tests__/injector-disk-pressure.test.ts +1 -1
- package/src/__tests__/injector-document-comments.test.ts +1 -1
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +1 -1
- package/src/__tests__/injector-v3-suppression.test.ts +220 -0
- package/src/__tests__/list-messages-attachments.test.ts +7 -8
- package/src/__tests__/list-messages-hidden-metadata.test.ts +17 -15
- package/src/__tests__/list-messages-page-latest.test.ts +0 -1
- package/src/__tests__/list-messages-tool-merge.test.ts +36 -6
- package/src/__tests__/llm-call-pipeline.test.ts +21 -15
- 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 +45 -0
- 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-pipeline.test.ts +1 -1
- package/src/__tests__/memory-v2-static-injector.test.ts +1 -1
- 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 +14 -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 +10 -0
- package/src/__tests__/openai-provider.test.ts +66 -70
- 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 +2 -4
- package/src/__tests__/parallel-tool.benchmark.test.ts +24 -36
- package/src/__tests__/persistence-pipeline.test.ts +15 -26
- package/src/__tests__/persistence-secret-redaction.test.ts +2 -1
- package/src/__tests__/pipeline-runner.test.ts +2 -3
- package/src/__tests__/plugin-bootstrap.test.ts +51 -25
- 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 +7 -14
- 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 +30 -42
- 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__/relay-server.test.ts +20 -13
- 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 +353 -0
- package/src/__tests__/schedule-routes.test.ts +80 -10
- package/src/__tests__/schedule-store.test.ts +67 -0
- package/src/__tests__/schedule-tools.test.ts +125 -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 +2 -1
- package/src/__tests__/shell-observability.test.ts +249 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +11 -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 +2 -2
- 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 +54 -0
- package/src/__tests__/terminal-tools.test.ts +3 -24
- package/src/__tests__/thread-backfill.test.ts +4 -9
- package/src/__tests__/title-generate-pipeline.test.ts +1 -1
- package/src/__tests__/token-estimate-pipeline.test.ts +2 -4
- package/src/__tests__/tool-error-pipeline.test.ts +2 -2
- package/src/__tests__/tool-execute-pipeline.test.ts +1 -1
- package/src/__tests__/tool-preview-lifecycle.test.ts +13 -11
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +9 -12
- package/src/__tests__/tool-result-truncation.test.ts +3 -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__/voice-scoped-grant-consumer.test.ts +8 -6
- package/src/__tests__/voice-session-bridge.test.ts +13 -7
- package/src/acp/__tests__/prepare-agent-env.test.ts +143 -31
- package/src/acp/prepare-agent-env.ts +52 -11
- package/src/agent/compaction-circuit.ts +140 -0
- package/src/agent/loop.ts +409 -85
- 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-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-result.ts +129 -0
- package/src/api/events/tool-use-start.ts +8 -10
- 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 +354 -0
- package/src/api/requests/dictation.ts +45 -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 +6 -9
- package/src/avatar/__tests__/avatar-manifest.test.ts +236 -0
- package/src/avatar/__tests__/avatar-store.test.ts +193 -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 +4 -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/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/lib/cli-colors.ts +24 -6
- package/src/cli/program.ts +4 -5
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/assistant-feature-flags.ts +2 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +14 -3
- package/src/config/bundled-skills/media-processing/services/reduce.ts +6 -9
- 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/call-site-defaults.ts +2 -7
- package/src/config/feature-flag-registry.json +25 -9
- package/src/config/schemas/__tests__/memory-v2.test.ts +1 -226
- package/src/config/schemas/call-site-catalog.ts +8 -15
- package/src/config/schemas/llm.ts +2 -3
- package/src/config/schemas/memory-lifecycle.ts +24 -0
- package/src/config/schemas/memory-v2.ts +0 -253
- package/src/config/schemas/memory-v3.ts +39 -0
- package/src/config/schemas/memory.ts +6 -1
- package/src/config/schemas/timeouts.ts +3 -1
- package/src/context/compactor.ts +54 -31
- package/src/context/token-estimator.ts +19 -0
- package/src/context/tool-result-truncation.ts +1 -43
- package/src/context/window-manager.ts +138 -20
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +2 -2
- package/src/daemon/__tests__/web-search-status-text.test.ts +10 -6
- package/src/daemon/approval-generators.ts +4 -4
- package/src/daemon/config-watcher.ts +7 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +225 -88
- package/src/daemon/conversation-agent-loop.ts +284 -584
- package/src/daemon/conversation-error.ts +7 -7
- package/src/daemon/conversation-history.ts +22 -6
- package/src/daemon/conversation-launch.ts +4 -8
- package/src/daemon/conversation-lifecycle.ts +10 -38
- package/src/daemon/conversation-messaging.ts +1 -3
- package/src/daemon/conversation-notifiers.ts +7 -5
- package/src/daemon/conversation-process.ts +100 -79
- package/src/daemon/conversation-runtime-assembly.ts +47 -21
- package/src/daemon/conversation-store.ts +6 -5
- package/src/daemon/conversation-surfaces.ts +55 -69
- package/src/daemon/conversation-tool-setup.ts +3 -0
- package/src/daemon/conversation.ts +91 -126
- 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 +46 -24
- package/src/daemon/first-greeting.ts +26 -4
- package/src/daemon/guardian-action-generators.ts +2 -2
- package/src/daemon/handlers/conversations.ts +6 -22
- package/src/daemon/handlers/shared.ts +4 -0
- package/src/daemon/handlers/skills.ts +15 -14
- 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 +28 -55
- package/src/daemon/message-protocol.ts +2 -3
- package/src/daemon/message-provenance.ts +49 -0
- 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 +28 -343
- 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 +2 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/message-types/sync.ts +12 -25
- package/src/daemon/message-types/workspace.ts +3 -11
- package/src/daemon/process-message.ts +49 -46
- package/src/daemon/server.ts +12 -0
- package/src/daemon/tool-side-effects.ts +10 -7
- package/src/daemon/trust-context.ts +13 -0
- package/src/daemon/wake-target-adapter.ts +11 -1
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -1
- package/src/heartbeat/heartbeat-run-store.ts +31 -0
- package/src/heartbeat/heartbeat-service.ts +16 -0
- package/src/home/feature-gate.ts +22 -0
- package/src/home/feed-types.ts +36 -221
- package/src/ipc/__tests__/email-ipc.test.ts +0 -9
- 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 +18 -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 +26 -13
- 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/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__/memory-retrospective-job.test.ts +10 -6
- package/src/memory/__tests__/memory-v3-selections-migration.test.ts +103 -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/db-init.ts +8 -0
- package/src/memory/db-maintenance.ts +18 -2
- package/src/memory/graph/consolidation.ts +8 -11
- package/src/memory/graph/conversation-graph-memory.ts +41 -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 +32 -32
- package/src/memory/job-handlers/summarization.ts +1 -2
- package/src/memory/jobs-store.ts +3 -1
- package/src/memory/jobs-worker.ts +51 -39
- 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 +10 -0
- 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/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/__tests__/267-llm-usage-events-add-assistant-version.test.ts +117 -0
- package/src/memory/migrations/index.ts +4 -0
- package/src/memory/schema/infrastructure.ts +11 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +124 -0
- 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 +89 -9
- 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/memory/v3/__tests__/assign.test.ts +242 -0
- package/src/memory/v3/__tests__/capabilities.test.ts +118 -0
- package/src/memory/v3/__tests__/core.test.ts +39 -0
- package/src/memory/v3/__tests__/fixtures/eval-turns.json +36 -0
- package/src/memory/v3/__tests__/fixtures/live-turns.json +37 -0
- package/src/memory/v3/__tests__/health.test.ts +203 -0
- package/src/memory/v3/__tests__/live-integration.test.ts +330 -0
- package/src/memory/v3/__tests__/maintain-job.test.ts +288 -0
- package/src/memory/v3/__tests__/needle.test.ts +107 -0
- package/src/memory/v3/__tests__/orchestrate.test.ts +400 -0
- package/src/memory/v3/__tests__/reconcile.test.ts +274 -0
- package/src/memory/v3/__tests__/render-injection.test.ts +61 -0
- package/src/memory/v3/__tests__/router.test.ts +260 -0
- package/src/memory/v3/__tests__/selection-log-store.test.ts +179 -0
- package/src/memory/v3/__tests__/selector.test.ts +404 -0
- package/src/memory/v3/__tests__/shadow-plugin.test.ts +414 -0
- package/src/memory/v3/__tests__/snapshot.test.ts +168 -0
- package/src/memory/v3/__tests__/tree.test.ts +192 -0
- package/src/memory/v3/__tests__/types.test.ts +54 -0
- package/src/memory/v3/__tests__/working-set-eviction.test.ts +106 -0
- package/src/memory/v3/__tests__/working-set-skeleton.test.ts +44 -0
- package/src/memory/v3/assign.ts +268 -0
- package/src/memory/v3/capabilities.ts +124 -0
- package/src/memory/v3/core.ts +26 -0
- package/src/memory/v3/data/README.md +84 -0
- package/src/memory/v3/data/assignments.json +5 -0
- package/src/memory/v3/data/core.json +1 -0
- package/src/memory/v3/data/leaves/domain-a/topic-x.md +9 -0
- package/src/memory/v3/data/leaves/domain-a/topic-y.md +9 -0
- package/src/memory/v3/data/leaves/domain-b/topic-z.md +9 -0
- package/src/memory/v3/health.ts +0 -0
- package/src/memory/v3/maintain-job.ts +314 -0
- package/src/memory/v3/needle.ts +115 -0
- package/src/memory/v3/orchestrate.ts +114 -0
- package/src/memory/v3/page-content.ts +34 -0
- package/src/memory/v3/provider-blocks.ts +16 -0
- package/src/memory/v3/reconcile.ts +523 -0
- package/src/memory/v3/render-injection.ts +32 -0
- package/src/memory/v3/router.ts +184 -0
- package/src/memory/v3/selection-log-store.ts +84 -0
- package/src/memory/v3/selector.ts +211 -0
- package/src/memory/v3/shadow-plugin.ts +379 -0
- package/src/memory/v3/snapshot.ts +209 -0
- package/src/memory/v3/tree.ts +174 -0
- package/src/memory/v3/types.ts +46 -60
- package/src/memory/v3/working-set.ts +88 -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 -6
- package/src/notifications/decision-engine.ts +10 -13
- package/src/notifications/preference-extractor.ts +11 -14
- package/src/permissions/prompter.ts +42 -36
- package/src/permissions/question-prompter.test.ts +35 -26
- package/src/permissions/question-prompter.ts +6 -10
- package/src/plugin-api/index.ts +2 -0
- package/src/plugin-api/types.ts +25 -3
- package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +93 -0
- package/src/plugins/defaults/circuit-breaker/package.json +15 -0
- package/src/plugins/defaults/circuit-breaker/register.ts +39 -0
- package/src/plugins/defaults/compaction/middlewares/compaction.ts +25 -0
- package/src/plugins/defaults/compaction/package.json +15 -0
- package/src/plugins/defaults/compaction/register.ts +35 -0
- package/src/plugins/defaults/compaction/terminal.ts +73 -0
- package/src/plugins/defaults/empty-response/middlewares/emptyResponse.ts +22 -0
- package/src/plugins/defaults/empty-response/package.json +15 -0
- package/src/plugins/defaults/empty-response/register.ts +28 -0
- package/src/plugins/defaults/empty-response/terminal.ts +106 -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 +29 -40
- package/src/plugins/defaults/injectors/package.json +15 -0
- package/src/plugins/defaults/{injectors.ts → injectors/register.ts} +14 -38
- package/src/plugins/defaults/llm-call/middlewares/llmCall.ts +17 -0
- package/src/plugins/defaults/llm-call/package.json +15 -0
- package/src/plugins/defaults/{llm-call.ts → llm-call/register.ts} +6 -38
- package/src/plugins/defaults/memory-retrieval/middlewares/memoryRetrieval.ts +17 -0
- package/src/plugins/defaults/memory-retrieval/package.json +15 -0
- package/src/plugins/defaults/{memory-retrieval.ts → memory-retrieval/register.ts} +10 -48
- package/src/plugins/defaults/{overflow-reduce.ts → overflow-reduce/middlewares/overflowReduce.ts} +18 -77
- package/src/plugins/defaults/overflow-reduce/package.json +15 -0
- package/src/plugins/defaults/overflow-reduce/register.ts +42 -0
- package/src/plugins/defaults/persistence/middlewares/persistence.ts +19 -0
- package/src/plugins/defaults/persistence/package.json +15 -0
- package/src/plugins/defaults/persistence/register.ts +38 -0
- package/src/plugins/defaults/persistence/terminal.ts +83 -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/title-generate/terminal.ts +31 -0
- package/src/plugins/defaults/token-estimate/middlewares/tokenEstimate.ts +23 -0
- package/src/plugins/defaults/token-estimate/package.json +15 -0
- package/src/plugins/defaults/token-estimate/register.ts +34 -0
- package/src/plugins/defaults/token-estimate/terminal.ts +40 -0
- package/src/plugins/defaults/tool-error/middlewares/toolError.ts +21 -0
- package/src/plugins/defaults/tool-error/package.json +15 -0
- package/src/plugins/defaults/tool-error/register.ts +35 -0
- package/src/plugins/defaults/tool-error/terminal.ts +47 -0
- package/src/plugins/defaults/tool-execute/middlewares/toolExecute.ts +23 -0
- package/src/plugins/defaults/tool-execute/package.json +15 -0
- package/src/plugins/defaults/{tool-execute.ts → tool-execute/register.ts} +8 -46
- package/src/plugins/defaults/tool-result-truncate/middlewares/toolResultTruncate.ts +23 -0
- package/src/plugins/defaults/tool-result-truncate/package.json +15 -0
- package/src/plugins/defaults/tool-result-truncate/register.ts +35 -0
- package/src/plugins/defaults/tool-result-truncate/terminal.ts +113 -0
- package/src/plugins/defaults/tool-result-truncate/types.ts +22 -0
- package/src/plugins/external-plugin-loader.ts +2 -2
- package/src/plugins/pipeline.ts +0 -12
- package/src/plugins/types.ts +51 -90
- package/src/plugins/user-loader.ts +4 -3
- package/src/proactive-artifact/aux-message-injector.ts +0 -1
- package/src/proactive-artifact/job.test.ts +20 -8
- package/src/proactive-artifact/job.ts +3 -1
- package/src/prompts/sections.ts +20 -7
- package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +2 -2
- package/src/prompts/templates/BOOTSTRAP.md +5 -1
- package/src/prompts/templates/system-sections.ts +6 -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 +24 -5
- 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 +0 -2
- package/src/providers/openai/chat-completions-provider.ts +1 -4
- package/src/providers/openai/responses-provider.ts +1 -4
- package/src/providers/openrouter/client.ts +1 -6
- 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 +131 -26
- package/src/runtime/__tests__/background-job-runner.test.ts +1 -3
- package/src/runtime/agent-wake.ts +93 -18
- package/src/runtime/assistant-event-hub.ts +2 -2
- 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 +3 -14
- 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/conversation-stream-state.ts +294 -0
- package/src/runtime/http-router.ts +19 -22
- package/src/runtime/http-types.ts +12 -6
- package/src/runtime/invite-instruction-generator.ts +3 -3
- package/src/runtime/pending-interactions.ts +2 -2
- package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +565 -0
- 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__/inference-provider-connection-routes.test.ts +13 -22
- 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__/tts-routes.test.ts +3 -3
- package/src/runtime/routes/acp-routes.test.ts +97 -75
- package/src/runtime/routes/acp-routes.ts +29 -6
- package/src/runtime/routes/app-management-routes.ts +97 -24
- package/src/runtime/routes/app-routes.ts +25 -5
- package/src/runtime/routes/approval-routes.ts +16 -4
- package/src/runtime/routes/attachment-routes.ts +25 -1
- 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 +238 -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 +5 -0
- package/src/runtime/routes/browser-tabs-routes.ts +5 -0
- package/src/runtime/routes/btw-routes.ts +5 -1
- 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 +13 -5
- 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 +88 -41
- package/src/runtime/routes/conversation-routes.ts +74 -19
- package/src/runtime/routes/conversation-starter-routes.ts +22 -13
- package/src/runtime/routes/conversations-import-routes.ts +6 -1
- 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 +21 -10
- package/src/runtime/routes/domain-routes.ts +61 -28
- package/src/runtime/routes/email-routes.ts +33 -0
- package/src/runtime/routes/events-routes.ts +114 -9
- package/src/runtime/routes/filing-routes.ts +9 -4
- package/src/runtime/routes/gateway-log-routes.ts +5 -0
- 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 +25 -9
- 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 +5 -0
- 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 +5 -0
- 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 +17 -6
- package/src/runtime/routes/identity-routes.ts +12 -2
- package/src/runtime/routes/image-generation-routes.ts +5 -0
- package/src/runtime/routes/inbound-message-handler.ts +15 -11
- 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/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 +30 -7
- package/src/runtime/routes/integrations/slack/channel.ts +19 -3
- package/src/runtime/routes/integrations/slack/share.ts +9 -2
- package/src/runtime/routes/integrations/telegram.ts +28 -9
- package/src/runtime/routes/integrations/twilio.ts +35 -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-twilio-routes.ts +13 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +39 -4
- package/src/runtime/routes/log-export-routes.ts +28 -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 +90 -36
- package/src/runtime/routes/memory-v3-routes.ts +273 -407
- 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 +33 -11
- 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 +35 -10
- package/src/runtime/routes/platform-routes.ts +21 -0
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +3 -2
- 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 +1 -1
- package/src/runtime/routes/playground/helpers.ts +0 -1
- 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 +5 -0
- package/src/runtime/routes/sanity-routes.ts +9 -2
- package/src/runtime/routes/schedule-routes.ts +137 -47
- package/src/runtime/routes/secret-routes.ts +17 -4
- 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 +133 -69
- 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/task-routes.ts +37 -0
- package/src/runtime/routes/telemetry-routes.ts +9 -0
- package/src/runtime/routes/trace-event-routes.ts +42 -1
- package/src/runtime/routes/trust-rules-routes.ts +5 -0
- package/src/runtime/routes/tts-routes.ts +13 -6
- package/src/runtime/routes/types.ts +17 -8
- 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 +71 -3
- 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 +9 -0
- package/src/runtime/routes/wipe-conversation-routes.ts +5 -0
- package/src/runtime/routes/work-items-routes.ts +47 -19
- 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 +120 -9
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -4
- package/src/runtime/services/analyze-conversation.ts +3 -6
- 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 +8 -0
- package/src/schedule/scheduler.ts +3 -1
- package/src/signals/user-message.ts +5 -8
- package/src/skills/catalog-files.ts +4 -1
- package/src/skills/clawhub-files.ts +2 -0
- package/src/skills/skillssh-files.ts +2 -0
- package/src/subagent/manager.ts +3 -6
- package/src/telemetry/types.ts +26 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +138 -1
- package/src/telemetry/usage-telemetry-reporter.ts +31 -0
- package/src/tools/acp/spawn.test.ts +88 -38
- package/src/tools/apps/definitions.ts +8 -4
- 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/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 +34 -31
- 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/web-fetch.ts +49 -46
- package/src/tools/network/web-search.ts +16 -13
- package/src/tools/registry.ts +39 -16
- package/src/tools/schedule/create.ts +11 -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/system/avatar-generator.ts +13 -22
- package/src/tools/system/request-permission.ts +30 -27
- 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 +69 -9
- 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/platform.ts +15 -12
- package/src/work-items/work-item-runner.ts +7 -2
- 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/__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 +6 -0
- package/src/workspace/provider-commit-message-generator.ts +15 -17
- package/tsconfig.json +4 -1
- package/src/__tests__/history-repair-pipeline.test.ts +0 -396
- 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/message-types/disk-pressure.ts +0 -9
- package/src/email/feature-gate.ts +0 -23
- 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/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/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-result-truncate.ts +0 -84
- package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +0 -35
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Do not store secrets here — use the credential store or protected/ directory.
|
|
5
5
|
*/
|
|
6
6
|
import {
|
|
7
|
+
type Dirent,
|
|
7
8
|
existsSync,
|
|
8
9
|
mkdirSync,
|
|
9
10
|
readdirSync,
|
|
@@ -18,6 +19,7 @@ import { basename, dirname, join } from "node:path";
|
|
|
18
19
|
import { z } from "zod";
|
|
19
20
|
|
|
20
21
|
import { getWorkspaceDir } from "../../util/platform.js";
|
|
22
|
+
import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
|
|
21
23
|
import { publishSoundsConfigUpdated } from "../sync/resource-sync-events.js";
|
|
22
24
|
import {
|
|
23
25
|
BadRequestError,
|
|
@@ -33,13 +35,77 @@ import {
|
|
|
33
35
|
resolveWorkspacePath,
|
|
34
36
|
} from "./workspace-utils.js";
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
name: string
|
|
38
|
-
path: string
|
|
39
|
-
type: "file"
|
|
40
|
-
size: number
|
|
41
|
-
mimeType: string
|
|
42
|
-
modifiedAt: string
|
|
38
|
+
const workspaceTreeEntrySchema = z.object({
|
|
39
|
+
name: z.string(),
|
|
40
|
+
path: z.string(),
|
|
41
|
+
type: z.enum(["file", "directory"]),
|
|
42
|
+
size: z.number().nullable(),
|
|
43
|
+
mimeType: z.string().nullable(),
|
|
44
|
+
modifiedAt: z.string(),
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
type TreeEntry = z.infer<typeof workspaceTreeEntrySchema>;
|
|
48
|
+
|
|
49
|
+
// Total number of filesystem entries we're willing to traverse when computing
|
|
50
|
+
// recursive directory sizes for a single tree listing. The budget is shared
|
|
51
|
+
// across every directory in the response so a giant `repos/` checkout cannot
|
|
52
|
+
// starve the request — once exhausted, remaining directories report `size:
|
|
53
|
+
// null` (caller renders an unknown-size placeholder). 50k is generous for
|
|
54
|
+
// typical workspaces (sounds, db, logs) while bailing fast on multi-repo
|
|
55
|
+
// trees.
|
|
56
|
+
const DIR_SIZE_TOTAL_ENTRY_BUDGET = 50_000;
|
|
57
|
+
|
|
58
|
+
interface DirSizeBudget {
|
|
59
|
+
remaining: number;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Recursively sum the byte size of every regular file under `absPath`,
|
|
64
|
+
* sharing a single entry budget across all directories in the same listing.
|
|
65
|
+
*
|
|
66
|
+
* Returns:
|
|
67
|
+
* - the total size in bytes when the entire subtree was traversed within
|
|
68
|
+
* budget
|
|
69
|
+
* - `null` if the shared budget was exhausted before completion (the caller
|
|
70
|
+
* surfaces that as an unknown size in the UI)
|
|
71
|
+
*
|
|
72
|
+
* Symlinks are not followed. We rely on `withFileTypes` so we never `stat`
|
|
73
|
+
* directories purely to discover their type.
|
|
74
|
+
*/
|
|
75
|
+
function computeDirSize(absPath: string, budget: DirSizeBudget): number | null {
|
|
76
|
+
if (budget.remaining <= 0) return null;
|
|
77
|
+
|
|
78
|
+
let total = 0;
|
|
79
|
+
const stack: string[] = [absPath];
|
|
80
|
+
|
|
81
|
+
while (stack.length > 0) {
|
|
82
|
+
const dir = stack.pop()!;
|
|
83
|
+
|
|
84
|
+
let dirents: Dirent[];
|
|
85
|
+
try {
|
|
86
|
+
dirents = readdirSync(dir, { withFileTypes: true });
|
|
87
|
+
} catch {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
for (const entry of dirents) {
|
|
92
|
+
if (budget.remaining <= 0) return null;
|
|
93
|
+
budget.remaining -= 1;
|
|
94
|
+
|
|
95
|
+
if (entry.isDirectory()) {
|
|
96
|
+
stack.push(join(dir, entry.name));
|
|
97
|
+
} else if (entry.isFile()) {
|
|
98
|
+
try {
|
|
99
|
+
total += statSync(join(dir, entry.name)).size;
|
|
100
|
+
} catch {
|
|
101
|
+
// unreadable file — skip, do not abort the whole computation
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// symlinks, sockets, fifos, etc. are intentionally ignored
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return total;
|
|
43
109
|
}
|
|
44
110
|
|
|
45
111
|
const SOUNDS_WORKSPACE_PATH = "data/sounds";
|
|
@@ -75,6 +141,7 @@ function publishSoundsConfigUpdatedForPaths(
|
|
|
75
141
|
function handleWorkspaceTree({ queryParams }: RouteHandlerArgs) {
|
|
76
142
|
const requestedPath = queryParams?.path ?? "";
|
|
77
143
|
const showHidden = queryParams?.showHidden === "true";
|
|
144
|
+
const includeDirSizes = queryParams?.includeDirSizes === "true";
|
|
78
145
|
const resolved = resolveWorkspacePath(requestedPath, {
|
|
79
146
|
allowHidden: showHidden,
|
|
80
147
|
});
|
|
@@ -86,6 +153,12 @@ function handleWorkspaceTree({ queryParams }: RouteHandlerArgs) {
|
|
|
86
153
|
const dirents = readdirSync(resolved, { withFileTypes: true });
|
|
87
154
|
const workspaceDir = getWorkspaceDir();
|
|
88
155
|
|
|
156
|
+
// Shared budget across every directory in this listing. When opted out,
|
|
157
|
+
// we never construct one, so directories report `size: null` as before.
|
|
158
|
+
const dirSizeBudget: DirSizeBudget | undefined = includeDirSizes
|
|
159
|
+
? { remaining: DIR_SIZE_TOTAL_ENTRY_BUDGET }
|
|
160
|
+
: undefined;
|
|
161
|
+
|
|
89
162
|
const entries: TreeEntry[] = [];
|
|
90
163
|
for (const entry of dirents) {
|
|
91
164
|
if (!showHidden && entry.name.startsWith(".")) continue;
|
|
@@ -102,11 +175,14 @@ function handleWorkspaceTree({ queryParams }: RouteHandlerArgs) {
|
|
|
102
175
|
const isDir = stats.isDirectory();
|
|
103
176
|
const relativePath = fullPath.slice(workspaceDir.length + 1);
|
|
104
177
|
|
|
178
|
+
const dirSize =
|
|
179
|
+
isDir && dirSizeBudget ? computeDirSize(fullPath, dirSizeBudget) : null;
|
|
180
|
+
|
|
105
181
|
entries.push({
|
|
106
182
|
name: entry.name,
|
|
107
183
|
path: relativePath,
|
|
108
184
|
type: isDir ? "directory" : "file",
|
|
109
|
-
size: isDir ?
|
|
185
|
+
size: isDir ? dirSize : stats.size,
|
|
110
186
|
mimeType: isDir ? null : Bun.file(fullPath).type,
|
|
111
187
|
modifiedAt: stats.mtime.toISOString(),
|
|
112
188
|
});
|
|
@@ -416,6 +492,10 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
416
492
|
operationId: "workspace_tree",
|
|
417
493
|
endpoint: "workspace/tree",
|
|
418
494
|
method: "GET",
|
|
495
|
+
policy: {
|
|
496
|
+
requiredScopes: ["settings.read"],
|
|
497
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
498
|
+
},
|
|
419
499
|
summary: "List workspace directory",
|
|
420
500
|
description: "Return directory entries for a workspace path.",
|
|
421
501
|
tags: ["workspace"],
|
|
@@ -428,10 +508,17 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
428
508
|
name: "showHidden",
|
|
429
509
|
description: "Include dotfiles (true/false)",
|
|
430
510
|
},
|
|
511
|
+
{
|
|
512
|
+
name: "includeDirSizes",
|
|
513
|
+
description:
|
|
514
|
+
"Compute recursive byte size for each directory entry (true/false). Budget-bounded — large subtrees may return size: null.",
|
|
515
|
+
},
|
|
431
516
|
],
|
|
432
517
|
responseBody: z.object({
|
|
433
518
|
path: z.string(),
|
|
434
|
-
entries: z
|
|
519
|
+
entries: z
|
|
520
|
+
.array(workspaceTreeEntrySchema)
|
|
521
|
+
.describe("Directory entry objects"),
|
|
435
522
|
}),
|
|
436
523
|
handler: handleWorkspaceTree,
|
|
437
524
|
},
|
|
@@ -439,6 +526,10 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
439
526
|
operationId: "workspace_file",
|
|
440
527
|
endpoint: "workspace/file",
|
|
441
528
|
method: "GET",
|
|
529
|
+
policy: {
|
|
530
|
+
requiredScopes: ["settings.read"],
|
|
531
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
532
|
+
},
|
|
442
533
|
summary: "Get workspace file metadata",
|
|
443
534
|
description:
|
|
444
535
|
"Return file metadata and inline text content (if small enough).",
|
|
@@ -468,6 +559,10 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
468
559
|
operationId: "workspace_write",
|
|
469
560
|
endpoint: "workspace/write",
|
|
470
561
|
method: "POST",
|
|
562
|
+
policy: {
|
|
563
|
+
requiredScopes: ["settings.write"],
|
|
564
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
565
|
+
},
|
|
471
566
|
summary: "Write workspace file",
|
|
472
567
|
description: "Create or overwrite a file in the workspace.",
|
|
473
568
|
tags: ["workspace"],
|
|
@@ -489,6 +584,10 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
489
584
|
operationId: "workspace_mkdir",
|
|
490
585
|
endpoint: "workspace/mkdir",
|
|
491
586
|
method: "POST",
|
|
587
|
+
policy: {
|
|
588
|
+
requiredScopes: ["settings.write"],
|
|
589
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
590
|
+
},
|
|
492
591
|
summary: "Create workspace directory",
|
|
493
592
|
description: "Create directories recursively in the workspace.",
|
|
494
593
|
tags: ["workspace"],
|
|
@@ -504,6 +603,10 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
504
603
|
operationId: "workspace_rename",
|
|
505
604
|
endpoint: "workspace/rename",
|
|
506
605
|
method: "POST",
|
|
606
|
+
policy: {
|
|
607
|
+
requiredScopes: ["settings.write"],
|
|
608
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
609
|
+
},
|
|
507
610
|
summary: "Rename workspace entry",
|
|
508
611
|
description: "Rename or move a file or directory in the workspace.",
|
|
509
612
|
tags: ["workspace"],
|
|
@@ -521,6 +624,10 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
521
624
|
operationId: "workspace_delete",
|
|
522
625
|
endpoint: "workspace/delete",
|
|
523
626
|
method: "POST",
|
|
627
|
+
policy: {
|
|
628
|
+
requiredScopes: ["settings.write"],
|
|
629
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
630
|
+
},
|
|
524
631
|
summary: "Delete workspace entry",
|
|
525
632
|
description: "Delete a file or directory from the workspace.",
|
|
526
633
|
tags: ["workspace"],
|
|
@@ -536,6 +643,10 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
536
643
|
operationId: "workspace_file_content",
|
|
537
644
|
endpoint: "workspace/file/content",
|
|
538
645
|
method: "GET",
|
|
646
|
+
policy: {
|
|
647
|
+
requiredScopes: ["settings.read"],
|
|
648
|
+
allowedPrincipalTypes: ACTOR_PRINCIPALS,
|
|
649
|
+
},
|
|
539
650
|
summary: "Get workspace file content",
|
|
540
651
|
description: "Return raw file bytes with HTTP range support.",
|
|
541
652
|
tags: ["workspace"],
|
|
@@ -167,7 +167,7 @@ describe("analyzeConversation", () => {
|
|
|
167
167
|
"analysis-new",
|
|
168
168
|
"user",
|
|
169
169
|
expect.any(String),
|
|
170
|
-
{ provenanceTrustClass: "unknown" },
|
|
170
|
+
{ metadata: { provenanceTrustClass: "unknown" } },
|
|
171
171
|
);
|
|
172
172
|
|
|
173
173
|
// Sets trust context to unknown.
|
|
@@ -192,7 +192,6 @@ describe("analyzeConversation", () => {
|
|
|
192
192
|
expect(currentConversation.runAgentLoop).toHaveBeenCalledWith(
|
|
193
193
|
expect.any(String),
|
|
194
194
|
"msg-1",
|
|
195
|
-
undefined,
|
|
196
195
|
expect.objectContaining({
|
|
197
196
|
isInteractive: false,
|
|
198
197
|
isUserMessage: true,
|
|
@@ -287,7 +286,7 @@ describe("analyzeConversation", () => {
|
|
|
287
286
|
"analysis-existing",
|
|
288
287
|
"user",
|
|
289
288
|
expect.any(String),
|
|
290
|
-
{ provenanceTrustClass: "guardian" },
|
|
289
|
+
{ metadata: { provenanceTrustClass: "guardian" } },
|
|
291
290
|
);
|
|
292
291
|
});
|
|
293
292
|
|
|
@@ -366,7 +365,6 @@ describe("analyzeConversation", () => {
|
|
|
366
365
|
expect(currentConversation.runAgentLoop).toHaveBeenCalledWith(
|
|
367
366
|
expect.any(String),
|
|
368
367
|
"msg-1",
|
|
369
|
-
undefined,
|
|
370
368
|
expect.objectContaining({ callSite: "analyzeConversation" }),
|
|
371
369
|
);
|
|
372
370
|
});
|
|
@@ -35,10 +35,7 @@ import {
|
|
|
35
35
|
} from "../../memory/conversation-crud.js";
|
|
36
36
|
import { resolveConversationId } from "../../memory/conversation-key-store.js";
|
|
37
37
|
import { getLogger } from "../../util/logger.js";
|
|
38
|
-
import {
|
|
39
|
-
assistantEventHub,
|
|
40
|
-
broadcastMessage,
|
|
41
|
-
} from "../assistant-event-hub.js";
|
|
38
|
+
import { assistantEventHub, broadcastMessage } from "../assistant-event-hub.js";
|
|
42
39
|
import {
|
|
43
40
|
buildAutoAnalysisPrompt,
|
|
44
41
|
neutralizeTranscriptSentinel,
|
|
@@ -218,7 +215,7 @@ export async function analyzeConversation(
|
|
|
218
215
|
analysisConversationId,
|
|
219
216
|
"user",
|
|
220
217
|
JSON.stringify([{ type: "text", text: prompt }]),
|
|
221
|
-
{ provenanceTrustClass: trustClass },
|
|
218
|
+
{ metadata: { provenanceTrustClass: trustClass } },
|
|
222
219
|
);
|
|
223
220
|
const messageId = message.id;
|
|
224
221
|
|
|
@@ -258,7 +255,7 @@ export async function analyzeConversation(
|
|
|
258
255
|
// routes the per-call provider config through `resolveCallSiteConfig`
|
|
259
256
|
// against `llm.callSites.analyzeConversation`.
|
|
260
257
|
analysisConversation
|
|
261
|
-
.runAgentLoop(prompt, messageId,
|
|
258
|
+
.runAgentLoop(prompt, messageId, {
|
|
262
259
|
isInteractive: false,
|
|
263
260
|
isUserMessage: true,
|
|
264
261
|
callSite: "analyzeConversation",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { parseChannelId } from "../../channels/types.js";
|
|
11
11
|
import { getConfig } from "../../config/loader.js";
|
|
12
|
+
import { findConversation } from "../../daemon/conversation-store.js";
|
|
12
13
|
import { normalizeConversationType } from "../../daemon/message-types/shared.js";
|
|
13
14
|
import {
|
|
14
15
|
type AttentionState,
|
|
@@ -162,9 +163,24 @@ export function serializeConversationSummary(params: {
|
|
|
162
163
|
groupId: string | null;
|
|
163
164
|
};
|
|
164
165
|
parentCache: Map<string, ConversationRow | null>;
|
|
166
|
+
/**
|
|
167
|
+
* Whether the agent loop is currently mid-turn for this conversation.
|
|
168
|
+
* Sourced from the in-memory daemon `Conversation.isProcessing()` flag
|
|
169
|
+
* — callers resolve via `findConversation(id)?.isProcessing() ?? false`
|
|
170
|
+
* so cold (evicted / never-loaded) rows report `false`. Plumbed in
|
|
171
|
+
* rather than read here so the serializer stays a pure shape mapper
|
|
172
|
+
* with no daemon-store coupling.
|
|
173
|
+
*/
|
|
174
|
+
isProcessing: boolean;
|
|
165
175
|
}) {
|
|
166
|
-
const {
|
|
167
|
-
|
|
176
|
+
const {
|
|
177
|
+
conversation,
|
|
178
|
+
binding,
|
|
179
|
+
attentionState,
|
|
180
|
+
displayMeta,
|
|
181
|
+
parentCache,
|
|
182
|
+
isProcessing,
|
|
183
|
+
} = params;
|
|
168
184
|
const originChannel = parseChannelId(conversation.originChannel);
|
|
169
185
|
const assistantAttention = buildAssistantAttention(attentionState);
|
|
170
186
|
const forkParent = buildForkParent(conversation, parentCache);
|
|
@@ -205,6 +221,7 @@ export function serializeConversationSummary(params: {
|
|
|
205
221
|
...(conversation.inferenceProfile != null
|
|
206
222
|
? { inferenceProfile: conversation.inferenceProfile }
|
|
207
223
|
: {}),
|
|
224
|
+
isProcessing,
|
|
208
225
|
};
|
|
209
226
|
}
|
|
210
227
|
|
|
@@ -232,6 +249,11 @@ export function buildConversationDetailResponse(
|
|
|
232
249
|
attentionState: attentionStates.get(conversation.id),
|
|
233
250
|
displayMeta: displayMeta.get(conversation.id),
|
|
234
251
|
parentCache,
|
|
252
|
+
// Cold (evicted / never-loaded) rows aren't in the in-memory
|
|
253
|
+
// store, so `findConversation` returns `undefined` and they
|
|
254
|
+
// report `isProcessing: false` — by definition they aren't
|
|
255
|
+
// mid-turn since the agent loop only runs on resident convs.
|
|
256
|
+
isProcessing: findConversation(conversation.id)?.isProcessing() ?? false,
|
|
235
257
|
}),
|
|
236
258
|
};
|
|
237
259
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { ConversationListInvalidatedReason } from "../../api/events/conversation-list-invalidated.js";
|
|
1
2
|
import type { IdentityFields } from "../../daemon/handlers/identity.js";
|
|
2
|
-
import type { ConversationListInvalidatedReason } from "../../daemon/message-types/conversations.js";
|
|
3
3
|
import {
|
|
4
4
|
conversationMessagesSyncTag,
|
|
5
5
|
conversationMetadataSyncTag,
|
|
@@ -29,7 +29,17 @@ export function publishIdentityChanged(
|
|
|
29
29
|
emoji: fields.emoji,
|
|
30
30
|
home: fields.home,
|
|
31
31
|
});
|
|
32
|
-
void publishSyncInvalidation(
|
|
32
|
+
void publishSyncInvalidation(
|
|
33
|
+
[SYNC_TAGS.assistantIdentity, SYNC_TAGS.assistantIdentityIntro],
|
|
34
|
+
originClientId,
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function publishIdentityIntroChanged(originClientId?: string): void {
|
|
39
|
+
void publishSyncInvalidation(
|
|
40
|
+
[SYNC_TAGS.assistantIdentityIntro],
|
|
41
|
+
originClientId,
|
|
42
|
+
);
|
|
33
43
|
}
|
|
34
44
|
|
|
35
45
|
export function publishConfigChanged(originClientId?: string): void {
|
|
@@ -46,6 +56,10 @@ export function publishSchedulesChanged(originClientId?: string): void {
|
|
|
46
56
|
void publishSyncInvalidation([SYNC_TAGS.assistantSchedules], originClientId);
|
|
47
57
|
}
|
|
48
58
|
|
|
59
|
+
export function publishAppsChanged(originClientId?: string): void {
|
|
60
|
+
void publishSyncInvalidation([SYNC_TAGS.appsList], originClientId);
|
|
61
|
+
}
|
|
62
|
+
|
|
49
63
|
/**
|
|
50
64
|
* Reasons that change the *shape* of the conversation list — a row is
|
|
51
65
|
* added, removed, or its position changes. These require web clients to
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { SyncChangedMessage } from "../../daemon/message-types/sync.js";
|
|
2
1
|
import {
|
|
3
2
|
buildSyncChangedMessage,
|
|
3
|
+
type SyncChangedEvent,
|
|
4
4
|
type SyncInvalidationTag,
|
|
5
5
|
} from "../../daemon/message-types/sync.js";
|
|
6
6
|
import { getLogger } from "../../util/logger.js";
|
|
@@ -11,7 +11,7 @@ const log = getLogger("sync-publisher");
|
|
|
11
11
|
export async function publishSyncInvalidation(
|
|
12
12
|
tags: SyncInvalidationTag[],
|
|
13
13
|
originClientId?: string,
|
|
14
|
-
): Promise<
|
|
14
|
+
): Promise<SyncChangedEvent> {
|
|
15
15
|
const message = buildSyncChangedMessage(tags, originClientId);
|
|
16
16
|
try {
|
|
17
17
|
broadcastMessage(message);
|
|
@@ -6,8 +6,16 @@ const log = getLogger("run-script");
|
|
|
6
6
|
|
|
7
7
|
/** Maximum combined stdout + stderr captured (bytes). */
|
|
8
8
|
const MAX_OUTPUT_BYTES = 10_000;
|
|
9
|
-
/** Default timeout for script execution (ms). */
|
|
10
|
-
const DEFAULT_TIMEOUT_MS = 60_000;
|
|
9
|
+
/** Default timeout for script execution (ms) when a schedule sets no override. */
|
|
10
|
+
export const DEFAULT_TIMEOUT_MS = 60_000;
|
|
11
|
+
/** Smallest script timeout override a caller may set (ms). */
|
|
12
|
+
export const MIN_SCRIPT_TIMEOUT_MS = 1_000;
|
|
13
|
+
/**
|
|
14
|
+
* Largest script timeout override a caller may set (ms). Capped so a wedged
|
|
15
|
+
* script cannot block the scheduler tick indefinitely; mirrors the talk-mode
|
|
16
|
+
* budget in scheduler.ts.
|
|
17
|
+
*/
|
|
18
|
+
export const MAX_SCRIPT_TIMEOUT_MS = 30 * 60 * 1000;
|
|
11
19
|
|
|
12
20
|
export interface ScriptResult {
|
|
13
21
|
exitCode: number;
|
|
@@ -75,7 +83,9 @@ export async function runScript(
|
|
|
75
83
|
]);
|
|
76
84
|
const stdout = truncate(stdoutStr);
|
|
77
85
|
const timeoutMsg = `Script timed out after ${timeoutMs}ms`;
|
|
78
|
-
const stderr = truncate(
|
|
86
|
+
const stderr = truncate(
|
|
87
|
+
stderrStr ? `${timeoutMsg}\n${stderrStr}` : timeoutMsg,
|
|
88
|
+
);
|
|
79
89
|
log.info(
|
|
80
90
|
{ command, timedOut: true, stdoutLen: stdout.length },
|
|
81
91
|
"Script timed out",
|
|
@@ -98,3 +108,18 @@ function truncate(text: string): string {
|
|
|
98
108
|
if (text.length <= MAX_OUTPUT_BYTES) return text;
|
|
99
109
|
return text.slice(0, MAX_OUTPUT_BYTES) + "\n... (truncated)";
|
|
100
110
|
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Validate a caller-supplied script timeout override (ms). Returns an error
|
|
114
|
+
* message when the value is not a positive integer within the allowed bounds,
|
|
115
|
+
* or `null` when it is acceptable.
|
|
116
|
+
*/
|
|
117
|
+
export function validateScriptTimeoutMs(value: number): string | null {
|
|
118
|
+
if (!Number.isInteger(value)) {
|
|
119
|
+
return "timeout_ms must be an integer number of milliseconds";
|
|
120
|
+
}
|
|
121
|
+
if (value < MIN_SCRIPT_TIMEOUT_MS || value > MAX_SCRIPT_TIMEOUT_MS) {
|
|
122
|
+
return `timeout_ms must be between ${MIN_SCRIPT_TIMEOUT_MS} and ${MAX_SCRIPT_TIMEOUT_MS} (ms)`;
|
|
123
|
+
}
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
@@ -47,6 +47,8 @@ export interface ScheduleJob {
|
|
|
47
47
|
retryCount: number;
|
|
48
48
|
maxRetries: number;
|
|
49
49
|
retryBackoffMs: number;
|
|
50
|
+
/** Script-mode execution timeout override (ms); null = use the default. */
|
|
51
|
+
timeoutMs: number | null;
|
|
50
52
|
createdBy: string;
|
|
51
53
|
mode: ScheduleMode;
|
|
52
54
|
routingIntent: RoutingIntent;
|
|
@@ -99,6 +101,7 @@ export function createSchedule(params: {
|
|
|
99
101
|
reuseConversation?: boolean;
|
|
100
102
|
maxRetries?: number;
|
|
101
103
|
retryBackoffMs?: number;
|
|
104
|
+
timeoutMs?: number | null;
|
|
102
105
|
}): ScheduleJob {
|
|
103
106
|
const expression = params.expression ?? params.cronExpression ?? null;
|
|
104
107
|
const isOneShot = expression == null;
|
|
@@ -134,6 +137,7 @@ export function createSchedule(params: {
|
|
|
134
137
|
const reuseConversation = params.reuseConversation ?? !isOneShot;
|
|
135
138
|
const maxRetries = params.maxRetries ?? 3;
|
|
136
139
|
const retryBackoffMs = params.retryBackoffMs ?? 60000;
|
|
140
|
+
const timeoutMs = params.timeoutMs ?? null;
|
|
137
141
|
|
|
138
142
|
let nextRunAt: number;
|
|
139
143
|
if (isOneShot) {
|
|
@@ -160,6 +164,7 @@ export function createSchedule(params: {
|
|
|
160
164
|
retryCount: 0,
|
|
161
165
|
maxRetries,
|
|
162
166
|
retryBackoffMs,
|
|
167
|
+
timeoutMs,
|
|
163
168
|
createdBy: params.createdBy ?? "agent",
|
|
164
169
|
mode,
|
|
165
170
|
routingIntent,
|
|
@@ -258,6 +263,7 @@ export function updateSchedule(
|
|
|
258
263
|
wakeConversationId?: string | null;
|
|
259
264
|
maxRetries?: number;
|
|
260
265
|
retryBackoffMs?: number;
|
|
266
|
+
timeoutMs?: number | null;
|
|
261
267
|
},
|
|
262
268
|
): ScheduleJob | null {
|
|
263
269
|
const db = getDb();
|
|
@@ -322,6 +328,7 @@ export function updateSchedule(
|
|
|
322
328
|
if (updates.maxRetries !== undefined) set.maxRetries = updates.maxRetries;
|
|
323
329
|
if (updates.retryBackoffMs !== undefined)
|
|
324
330
|
set.retryBackoffMs = updates.retryBackoffMs;
|
|
331
|
+
if (updates.timeoutMs !== undefined) set.timeoutMs = updates.timeoutMs;
|
|
325
332
|
|
|
326
333
|
// Recompute nextRunAt if schedule timing may have changed (only for recurring)
|
|
327
334
|
if (
|
|
@@ -969,6 +976,7 @@ function parseJobRow(row: typeof scheduleJobs.$inferSelect): ScheduleJob {
|
|
|
969
976
|
retryCount: row.retryCount,
|
|
970
977
|
maxRetries: row.maxRetries ?? 3,
|
|
971
978
|
retryBackoffMs: row.retryBackoffMs ?? 60000,
|
|
979
|
+
timeoutMs: row.timeoutMs ?? null,
|
|
972
980
|
createdBy: row.createdBy,
|
|
973
981
|
mode: (row.mode ?? "execute") as ScheduleMode,
|
|
974
982
|
routingIntent: (row.routingIntent ?? "all_channels") as RoutingIntent,
|
|
@@ -303,7 +303,9 @@ export async function runScheduleDueWorkOnce(
|
|
|
303
303
|
{ jobId: job.id, name: job.name, isOneShot },
|
|
304
304
|
"Executing script schedule",
|
|
305
305
|
);
|
|
306
|
-
const result: ScriptResult = await runScript(job.script
|
|
306
|
+
const result: ScriptResult = await runScript(job.script, {
|
|
307
|
+
timeoutMs: job.timeoutMs ?? undefined,
|
|
308
|
+
});
|
|
307
309
|
completeScheduleRun(runId, {
|
|
308
310
|
status: result.exitCode === 0 ? "ok" : "error",
|
|
309
311
|
output: result.stdout || undefined,
|
|
@@ -134,14 +134,11 @@ async function dispatchUserMessage(params: {
|
|
|
134
134
|
return { accepted: !result.rejected };
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
await processMessageInBackground(
|
|
138
|
-
|
|
139
|
-
params.
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
params.sourceChannel,
|
|
143
|
-
params.sourceInterface,
|
|
144
|
-
);
|
|
137
|
+
await processMessageInBackground(conversationId, params.content, {
|
|
138
|
+
attachmentIds: attachmentIds.length > 0 ? attachmentIds : undefined,
|
|
139
|
+
sourceChannel: params.sourceChannel,
|
|
140
|
+
sourceInterface: params.sourceInterface,
|
|
141
|
+
});
|
|
145
142
|
return { accepted: true };
|
|
146
143
|
}
|
|
147
144
|
|
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
import { getLogger } from "../util/logger.js";
|
|
38
38
|
import { getCachedCatalogSync, getCatalog } from "./catalog-cache.js";
|
|
39
39
|
import { type CatalogSkill, getRepoSkillsDir } from "./catalog-install.js";
|
|
40
|
+
import { inferCategory } from "./category-inference.js";
|
|
40
41
|
import type { SkillFileProvider } from "./skill-file-provider.js";
|
|
41
42
|
|
|
42
43
|
const log = getLogger("catalog-files");
|
|
@@ -497,14 +498,16 @@ export async function readCatalogSkillFileContent(
|
|
|
497
498
|
* otherwise be reachable via the handler module.
|
|
498
499
|
*/
|
|
499
500
|
export function catalogSkillToSlim(cs: CatalogSkill): SlimSkillResponse {
|
|
501
|
+
const name = cs.metadata?.vellum?.["display-name"] ?? cs.name;
|
|
500
502
|
return {
|
|
501
503
|
id: cs.id,
|
|
502
|
-
name
|
|
504
|
+
name,
|
|
503
505
|
description: cs.description,
|
|
504
506
|
emoji: cs.emoji ?? cs.metadata?.emoji,
|
|
505
507
|
kind: "catalog",
|
|
506
508
|
origin: "vellum",
|
|
507
509
|
status: "available",
|
|
510
|
+
category: inferCategory(name, cs.description),
|
|
508
511
|
};
|
|
509
512
|
}
|
|
510
513
|
|
|
@@ -17,6 +17,7 @@ import type { SlimSkillResponse } from "../daemon/message-types/skills.js";
|
|
|
17
17
|
import { isTextMimeType as isTextMime } from "../runtime/routes/workspace-utils.js";
|
|
18
18
|
import { getLogger } from "../util/logger.js";
|
|
19
19
|
import type { SkillFileEntry } from "./catalog-files.js";
|
|
20
|
+
import { inferCategory } from "./category-inference.js";
|
|
20
21
|
import {
|
|
21
22
|
clawhubInspect,
|
|
22
23
|
clawhubInspectFile,
|
|
@@ -198,6 +199,7 @@ export function createClawhubProvider(): SkillFileProvider {
|
|
|
198
199
|
kind: "catalog",
|
|
199
200
|
status: "available",
|
|
200
201
|
origin: "clawhub",
|
|
202
|
+
category: inferCategory(data.skill.displayName, data.skill.summary),
|
|
201
203
|
slug: data.skill.slug,
|
|
202
204
|
author: data.owner?.handle ?? "",
|
|
203
205
|
stars: data.stats?.stars ?? 0,
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
sanitizeRelativePath,
|
|
25
25
|
SKIP_DIRS,
|
|
26
26
|
} from "./catalog-files.js";
|
|
27
|
+
import { inferCategory } from "./category-inference.js";
|
|
27
28
|
import type { SkillFileProvider } from "./skill-file-provider.js";
|
|
28
29
|
import type { GitHubContentsEntry } from "./skillssh-registry.js";
|
|
29
30
|
import {
|
|
@@ -383,6 +384,7 @@ export function createSkillsShProvider(): SkillFileProvider {
|
|
|
383
384
|
kind: "catalog",
|
|
384
385
|
status: "available",
|
|
385
386
|
origin: "skillssh",
|
|
387
|
+
category: inferCategory(source.skillSlug, ""),
|
|
386
388
|
slug: skillId,
|
|
387
389
|
sourceRepo: `${source.owner}/${source.repo}`,
|
|
388
390
|
installs: 0,
|
package/src/subagent/manager.ts
CHANGED
|
@@ -285,12 +285,9 @@ export class SubagentManager {
|
|
|
285
285
|
conversationRecord.id,
|
|
286
286
|
provider,
|
|
287
287
|
systemPrompt,
|
|
288
|
-
maxTokens,
|
|
289
288
|
wrappedSendToClient,
|
|
290
289
|
workingDir,
|
|
291
|
-
|
|
292
|
-
undefined, // speedOverride
|
|
293
|
-
"5m", // cacheTtl — subagents run tight tool-use loops, 5m is always hot
|
|
290
|
+
{ maxTokens, cacheTtl: "5m" },
|
|
294
291
|
);
|
|
295
292
|
|
|
296
293
|
// Mark conversation as having no direct client — it routes through parent.
|
|
@@ -439,7 +436,7 @@ export class SubagentManager {
|
|
|
439
436
|
const { id: messageId } = await conversation.persistUserMessage({
|
|
440
437
|
content: message,
|
|
441
438
|
});
|
|
442
|
-
await conversation.runAgentLoop(message, messageId,
|
|
439
|
+
await conversation.runAgentLoop(message, messageId, {
|
|
443
440
|
callSite: "subagentSpawn",
|
|
444
441
|
...(managed.state.config.overrideProfile
|
|
445
442
|
? { overrideProfile: managed.state.config.overrideProfile }
|
|
@@ -627,7 +624,7 @@ export class SubagentManager {
|
|
|
627
624
|
content: trimmed,
|
|
628
625
|
});
|
|
629
626
|
conversation
|
|
630
|
-
.runAgentLoop(trimmed, messageId,
|
|
627
|
+
.runAgentLoop(trimmed, messageId, {
|
|
631
628
|
callSite: "subagentSpawn",
|
|
632
629
|
...(managed.state.config.overrideProfile
|
|
633
630
|
? { overrideProfile: managed.state.config.overrideProfile }
|
package/src/telemetry/types.ts
CHANGED
|
@@ -6,6 +6,32 @@ export interface TelemetryEventBase {
|
|
|
6
6
|
type: string;
|
|
7
7
|
daemon_event_id: string;
|
|
8
8
|
recorded_at: number;
|
|
9
|
+
/**
|
|
10
|
+
* Version of the assistant binary at the moment THIS event was
|
|
11
|
+
* RECORDED (not when the batch was uploaded). Distinct from the
|
|
12
|
+
* envelope's `assistant_version` field, which still ships for
|
|
13
|
+
* back-compat with platforms that haven't deployed the per-event
|
|
14
|
+
* handling.
|
|
15
|
+
*
|
|
16
|
+
* The platform's `TelemetryIngestView` prefers per-event over
|
|
17
|
+
* envelope: when a per-event value is present (including explicit
|
|
18
|
+
* `null`) it wins. When the field is omitted on the event entirely
|
|
19
|
+
* (old assistant), the envelope value is the back-compat fallback.
|
|
20
|
+
*
|
|
21
|
+
* Daemon-side, this field is always non-null — the reporter stamps
|
|
22
|
+
* the running binary's `APP_VERSION` when the underlying SQLite row
|
|
23
|
+
* has no record-time value. In this PR only `llm_usage` events
|
|
24
|
+
* carry a true record-time value (legacy llm_usage rows from before
|
|
25
|
+
* migration 267 fall back to `APP_VERSION`); turn, lifecycle, and
|
|
26
|
+
* onboarding events all stamp `APP_VERSION` directly until the
|
|
27
|
+
* follow-ups that add the column to `messages` / `lifecycle_events`
|
|
28
|
+
* (#18112) / `onboarding_events` (#30733) land. Stamping
|
|
29
|
+
* `APP_VERSION` instead of emitting explicit `null` preserves
|
|
30
|
+
* envelope-equivalent behavior under the per-event-wins contract.
|
|
31
|
+
* The type allows `null` for parity with the platform contract;
|
|
32
|
+
* in practice the daemon never sends it.
|
|
33
|
+
*/
|
|
34
|
+
assistant_version: string | null;
|
|
9
35
|
}
|
|
10
36
|
|
|
11
37
|
/** LLM usage event — one per provider API call. */
|