@vellumai/assistant 0.8.8 → 0.8.9-dev.202606091926.ebb2d62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +6 -6
- package/bun.lock +2 -2
- package/docs/activation-funnel-telemetry.md +310 -0
- package/examples/plugins/echo/README.md +61 -60
- package/examples/plugins/echo/hooks/post-tool-use.ts +18 -0
- package/examples/plugins/echo/hooks/stop.ts +16 -0
- package/examples/plugins/echo/hooks/user-prompt-submit.ts +18 -0
- package/examples/plugins/echo/package.json +1 -2
- package/examples/plugins/echo/src/emit.ts +19 -0
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
- package/openapi.yaml +273 -121
- package/package.json +2 -2
- package/scripts/sync-llm-catalog.ts +2 -0
- package/src/__tests__/activation-early-marking.test.ts +120 -0
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +69 -14
- package/src/__tests__/agent-loop-exit-reason.test.ts +204 -144
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +50 -35
- package/src/__tests__/agent-loop-output-hooks.test.ts +357 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +25 -6
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +41 -21
- package/src/__tests__/agent-loop-thinking.test.ts +36 -20
- package/src/__tests__/agent-loop.test.ts +441 -96
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +14 -14
- package/src/__tests__/agent-wake-override-profile.test.ts +17 -21
- package/src/__tests__/anthropic-provider.test.ts +23 -8
- package/src/__tests__/app-builder-tool-scripts.test.ts +21 -0
- package/src/__tests__/app-control-flow.test.ts +1 -1
- package/src/__tests__/app-dir-path-guard.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +132 -0
- package/src/__tests__/approval-cascade.test.ts +6 -5
- package/src/__tests__/approval-routes-http.test.ts +4 -1
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
- package/src/__tests__/build-persisted-content.test.ts +75 -1
- package/src/__tests__/channel-approval-routes.test.ts +1 -1
- package/src/__tests__/channel-approvals.test.ts +1 -1
- package/src/__tests__/compaction-circuit.test.ts +258 -0
- package/src/__tests__/compaction-direct.test.ts +146 -0
- package/src/__tests__/compaction-events.test.ts +7 -7
- package/src/__tests__/compaction.benchmark.test.ts +1 -1
- package/src/__tests__/compactor-web-search-strip.test.ts +213 -0
- package/src/__tests__/config-managed-gemini-defaults.test.ts +2 -46
- package/src/__tests__/context-overflow-reducer.test.ts +265 -125
- package/src/__tests__/context-window-manager-compact-retry.test.ts +121 -15
- package/src/__tests__/conversation-abort-tool-results.test.ts +7 -5
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +7 -10
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +78 -119
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +158 -234
- package/src/__tests__/conversation-agent-loop.test.ts +342 -623
- package/src/__tests__/conversation-clean-command.test.ts +5 -2
- package/src/__tests__/conversation-confirmation-signals.test.ts +6 -5
- package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
- package/src/__tests__/conversation-error.test.ts +15 -1
- package/src/__tests__/conversation-history-web-search.test.ts +6 -1
- package/src/__tests__/conversation-media-retry.test.ts +1 -1
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +44 -4
- package/src/__tests__/conversation-process-callsite.test.ts +15 -15
- package/src/__tests__/conversation-provider-retry-repair.test.ts +66 -65
- package/src/__tests__/conversation-queue.test.ts +10 -10
- package/src/__tests__/conversation-runtime-assembly.test.ts +1059 -231
- package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
- package/src/__tests__/conversation-slash-queue.test.ts +7 -5
- package/src/__tests__/conversation-slash-unknown.test.ts +7 -5
- package/src/__tests__/conversation-speed-override.test.ts +11 -10
- package/src/__tests__/conversation-starter-routes.test.ts +14 -6
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +395 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +48 -1
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +73 -4
- package/src/__tests__/conversation-undo.test.ts +2 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +24 -21
- package/src/__tests__/conversation-workspace-injection.test.ts +69 -7
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +15 -12
- package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
- package/src/__tests__/corrected-target.test.ts +93 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +5 -4
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/cu-unified-flow.test.ts +36 -0
- package/src/__tests__/db-acp-history.test.ts +101 -0
- package/src/__tests__/dynamic-page-surface.test.ts +31 -0
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +6 -40
- package/src/__tests__/empty-response-hook.test.ts +1 -1
- package/src/__tests__/file-write-tool.test.ts +63 -0
- package/src/__tests__/gateway-only-guard.test.ts +17 -2
- package/src/__tests__/guardian-grant-minting.test.ts +1 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +93 -4
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +1 -0
- package/src/__tests__/history-repair-hook.test.ts +5 -1
- package/src/__tests__/host-app-control-proxy.test.ts +45 -0
- package/src/__tests__/host-app-control-routes.test.ts +1 -1
- package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
- package/src/__tests__/inference-profile-reaper.test.ts +62 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +86 -0
- package/src/__tests__/injector-background-turn.test.ts +13 -23
- package/src/__tests__/injector-chain.test.ts +268 -44
- package/src/__tests__/injector-disk-pressure.test.ts +210 -52
- package/src/__tests__/injector-document-comments.test.ts +97 -114
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
- package/src/__tests__/injector-v3-suppression.test.ts +4 -4
- package/src/__tests__/list-messages-client-message-id.test.ts +91 -0
- package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
- package/src/__tests__/llm-catalog-parity.test.ts +4 -0
- package/src/__tests__/llm-resolver.test.ts +73 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +156 -38
- package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
- package/src/__tests__/notification-decision-strategy.test.ts +3 -3
- package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +145 -0
- package/src/__tests__/persist-unsendable-image.test.ts +97 -1
- package/src/__tests__/persistence-secret-redaction.test.ts +78 -0
- package/src/__tests__/plugin-api-shim.test.ts +6 -9
- package/src/__tests__/plugin-bootstrap.test.ts +91 -81
- package/src/__tests__/plugin-registry.test.ts +3 -49
- package/src/__tests__/plugin-skill-contribution.test.ts +15 -14
- package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
- package/src/__tests__/plugin-types.test.ts +0 -70
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +69 -0
- package/src/__tests__/pre-model-call-sanitize.test.ts +109 -0
- package/src/__tests__/published-app-updater.test.ts +138 -0
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- package/src/__tests__/retry-thinking-adaptive-only.test.ts +245 -0
- package/src/__tests__/send-endpoint-busy.test.ts +4 -1
- package/src/__tests__/server-history-render.test.ts +39 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +31 -0
- package/src/__tests__/steer-tool-repair.test.ts +1 -1
- package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
- package/src/__tests__/subagent-detail.test.ts +25 -7
- 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__/title-generate-hook.test.ts +5 -1
- package/src/__tests__/tool-error-hook.test.ts +1 -1
- package/src/__tests__/tool-result-truncate-hook.test.ts +1 -1
- package/src/__tests__/tool-start-timestamp.test.ts +218 -0
- package/src/__tests__/user-plugin-loader.test.ts +54 -286
- package/src/__tests__/web-fetch.test.ts +45 -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-config-stub.ts +0 -2
- package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
- package/src/acp/__tests__/helpers/exec-file-stub.ts +106 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +97 -0
- package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
- package/src/acp/__tests__/session-manager-resume.test.ts +888 -0
- package/src/acp/agent-process.ts +61 -1
- package/src/acp/auto-install.test.ts +280 -0
- package/src/acp/auto-install.ts +232 -0
- package/src/acp/client-handler.ts +31 -0
- package/src/acp/prepare-agent-env.ts +80 -27
- package/src/acp/resolve-agent.test.ts +188 -28
- package/src/acp/resolve-agent.ts +119 -42
- package/src/acp/resume-hint.ts +23 -0
- package/src/acp/session-manager.ts +507 -73
- package/src/agent/compaction-circuit.ts +60 -102
- package/src/agent/loop.ts +403 -251
- package/src/api/events/tool-result.ts +9 -0
- package/src/api/events/tool-use-start.ts +7 -0
- package/src/api/responses/conversation-message.ts +72 -13
- package/src/api/responses/memory-v3-selection-log.ts +19 -10
- package/src/approvals/guardian-request-resolvers.ts +27 -1
- package/src/background-wake/next-wake.ts +1 -0
- package/src/cli/commands/__tests__/memory-v3.test.ts +191 -210
- package/src/cli/commands/channel-verification-sessions.ts +6 -6
- package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
- package/src/cli/commands/memory-v3.ts +57 -199
- package/src/cli/commands/plugins.ts +43 -37
- package/src/cli/lib/__tests__/install-from-github.test.ts +790 -111
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
- package/src/cli/lib/__tests__/plugin-details.test.ts +381 -0
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +270 -0
- package/src/cli/lib/__tests__/search-plugins.test.ts +233 -32
- package/src/cli/lib/install-from-github.ts +797 -60
- package/src/cli/lib/plugin-catalog-cache.ts +84 -0
- package/src/cli/lib/plugin-details.ts +416 -0
- package/src/cli/lib/plugin-marketplace.ts +215 -0
- package/src/cli/lib/search-plugins.ts +201 -29
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/acp-defaults.test.ts +10 -0
- package/src/config/acp-defaults.ts +9 -3
- package/src/config/acp-schema.ts +1 -7
- package/src/config/bundled-skills/acp/SKILL.md +80 -41
- package/src/config/bundled-skills/acp/TOOLS.json +4 -4
- package/src/config/bundled-skills/app-builder/SKILL.md +224 -381
- package/src/config/bundled-skills/app-builder/TOOLS.json +72 -2
- 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/tools/app-list.ts +62 -0
- package/src/config/bundled-skills/app-builder/tools/app-update.ts +18 -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-tool-registry.ts +4 -0
- package/src/config/call-site-defaults.ts +0 -3
- package/src/config/feature-flag-registry.json +10 -56
- package/src/config/llm-resolver.ts +39 -7
- package/src/config/loader.ts +5 -22
- package/src/config/schemas/__tests__/memory-v3.test.ts +25 -9
- package/src/config/schemas/call-site-catalog.ts +0 -21
- package/src/config/schemas/heartbeat.ts +9 -0
- package/src/config/schemas/llm.ts +17 -3
- package/src/config/schemas/memory-v3.ts +58 -8
- package/src/config/seed-inference-profiles.ts +18 -0
- package/src/context/compactor.ts +22 -4
- package/src/context/post-turn-tool-result-truncation.ts +39 -1
- package/src/context/strip-injections.ts +8 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +120 -42
- package/src/daemon/conversation-agent-loop.ts +308 -1297
- package/src/daemon/conversation-error.ts +31 -4
- package/src/daemon/conversation-history.ts +1 -1
- package/src/daemon/conversation-lifecycle.ts +11 -255
- package/src/daemon/conversation-media-retry.ts +19 -6
- package/src/daemon/conversation-messaging.ts +17 -0
- package/src/daemon/conversation-process.ts +22 -141
- package/src/daemon/conversation-queue-manager.ts +8 -0
- package/src/daemon/conversation-registry.ts +159 -0
- package/src/daemon/conversation-runtime-assembly.ts +361 -393
- package/src/daemon/conversation-store.ts +9 -90
- package/src/daemon/conversation-surfaces.ts +165 -11
- package/src/daemon/conversation-workspace.ts +17 -0
- package/src/daemon/conversation.ts +444 -62
- package/src/daemon/disk-pressure-policy.ts +0 -1
- package/src/daemon/external-plugins-bootstrap.ts +36 -46
- package/src/daemon/handlers/config-channels.ts +11 -2
- package/src/daemon/handlers/conversations.ts +3 -1
- package/src/daemon/handlers/shared.ts +9 -1
- package/src/daemon/handlers/skills.ts +4 -1
- package/src/daemon/host-app-control-proxy.ts +72 -57
- package/src/daemon/host-proxy-preactivation.ts +1 -3
- package/src/daemon/lifecycle.ts +21 -7
- package/src/daemon/persist-unsendable-image.ts +62 -25
- package/src/daemon/process-message.ts +1 -1
- package/src/daemon/server.ts +2 -0
- package/src/daemon/tool-side-effects.ts +15 -0
- package/src/daemon/wake-conversation-ops.ts +269 -0
- package/src/embedded/plugin-api.ts +2 -2
- package/src/export/__tests__/transcript-formatter.test.ts +5 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
- package/src/heartbeat/heartbeat-run-store.ts +23 -1
- package/src/heartbeat/heartbeat-service.ts +26 -0
- package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
- package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
- package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
- package/src/ipc/skill-routes/memory.ts +4 -2
- package/src/memory/__tests__/activation-session-store.test.ts +41 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
- package/src/memory/__tests__/onboarding-events-store.test.ts +80 -0
- package/src/memory/activation-session-store.ts +43 -0
- package/src/memory/conversation-crud.ts +29 -19
- package/src/memory/conversation-starter-checkpoints.ts +1 -0
- package/src/memory/db-init.ts +6 -0
- package/src/memory/embedding-backend.ts +5 -22
- package/src/memory/job-handlers/conversation-starters.ts +13 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -4
- package/src/memory/jobs-worker.ts +25 -1
- package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
- package/src/memory/migrations/273-onboarding-events-funnel-columns.ts +46 -0
- package/src/memory/migrations/274-create-activation-sessions.ts +15 -0
- package/src/memory/migrations/index.ts +3 -0
- package/src/memory/onboarding-events-store.ts +66 -18
- package/src/memory/schema/acp.ts +4 -0
- package/src/memory/schema/infrastructure.ts +13 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +4 -97
- package/src/memory/v2/__tests__/page-store.test.ts +22 -0
- package/src/memory/v2/consolidation-job.ts +2 -63
- package/src/memory/v2/types.ts +5 -0
- package/src/messaging/providers/telegram-bot/api.ts +14 -5
- package/src/notifications/__tests__/copy-composer.test.ts +244 -0
- package/src/notifications/access-request-copy.ts +298 -0
- package/src/notifications/adapters/slack.ts +3 -3
- package/src/notifications/adapters/telegram.ts +9 -2
- package/src/notifications/copy-composer.ts +49 -267
- package/src/notifications/decision-engine.ts +16 -35
- package/src/notifications/home-feed-side-effect.ts +1 -6
- package/src/plugin-api/constants.ts +4 -0
- package/src/plugin-api/index.ts +40 -11
- package/src/plugin-api/types.ts +108 -0
- package/src/plugins/defaults/compaction/compact.ts +106 -0
- package/src/{daemon → plugins/defaults/compaction}/context-overflow-reducer.ts +250 -42
- package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
- package/src/plugins/defaults/compaction/manager-store.ts +57 -0
- package/src/plugins/defaults/compaction/package.json +1 -2
- package/src/{context → plugins/defaults/compaction}/window-manager.ts +95 -25
- package/src/plugins/defaults/empty-response/package.json +0 -1
- package/src/plugins/defaults/history-repair/package.json +0 -1
- package/src/plugins/defaults/index.ts +156 -26
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +100 -52
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +285 -0
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
- package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +148 -73
- package/src/plugins/defaults/memory-retrieval/package.json +14 -0
- package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/capabilities.test.ts +71 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/dense.test.ts +181 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/edge.test.ts +247 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +147 -134
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +456 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +662 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +306 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +91 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +402 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/section-needle.test.ts +135 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/sections.test.ts +125 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +74 -19
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +446 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +592 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -24
- package/src/plugins/defaults/memory-v3-shadow/capabilities.ts +91 -0
- package/src/plugins/defaults/memory-v3-shadow/dense.ts +97 -0
- package/src/plugins/defaults/memory-v3-shadow/edge.ts +252 -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 +76 -0
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +555 -0
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +266 -0
- package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
- package/src/plugins/defaults/memory-v3-shadow/page-content.ts +71 -0
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +204 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +16 -8
- package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +236 -0
- package/src/plugins/defaults/memory-v3-shadow/section-needle.ts +200 -0
- package/src/plugins/defaults/memory-v3-shadow/sections.ts +115 -0
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +156 -0
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +382 -0
- package/src/plugins/defaults/memory-v3-shadow/types.ts +92 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +4 -1
- package/src/plugins/defaults/title-generate/package.json +0 -1
- package/src/plugins/defaults/tool-error/package.json +0 -1
- package/src/plugins/defaults/tool-result-truncate/package.json +0 -1
- package/src/plugins/external-api.ts +12 -2
- package/src/plugins/pipeline.ts +6 -293
- package/src/plugins/registry.ts +9 -37
- package/src/plugins/types.ts +76 -381
- package/src/plugins/user-loader.ts +30 -127
- package/src/prompts/__tests__/system-prompt.test.ts +6 -0
- package/src/prompts/system-prompt.ts +61 -10
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +71 -4
- package/src/providers/anthropic/client.ts +9 -10
- package/src/providers/inference/kimi-cjk-token-ids.ts +493 -0
- package/src/providers/inference/logit-bias.ts +55 -0
- package/src/providers/model-catalog.ts +57 -0
- package/src/providers/openai/__tests__/vision-not-supported.test.ts +75 -0
- package/src/providers/openai/chat-completions-provider.ts +44 -1
- package/src/providers/retry.ts +57 -7
- package/src/providers/types.ts +6 -0
- package/src/runtime/__tests__/agent-wake.test.ts +555 -691
- package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
- package/src/runtime/agent-wake.ts +108 -209
- package/src/runtime/assistant-event-hub.ts +1 -1
- package/src/runtime/channel-approvals.ts +1 -1
- package/src/runtime/interactive-ui.ts +1 -1
- package/src/runtime/routes/__tests__/acp-routes.test.ts +466 -55
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +423 -73
- package/src/runtime/routes/__tests__/stt-routes.test.ts +112 -0
- 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/acp-routes.test.ts +185 -32
- package/src/runtime/routes/acp-routes.ts +328 -30
- package/src/runtime/routes/app-management-routes.ts +3 -0
- package/src/runtime/routes/approval-routes.ts +1 -1
- package/src/runtime/routes/browser-routes.ts +1 -1
- package/src/runtime/routes/browser-tabs-routes.ts +6 -10
- package/src/runtime/routes/channel-verification-routes.ts +14 -5
- package/src/runtime/routes/conversation-cli-routes.ts +1 -1
- package/src/runtime/routes/conversation-list-routes.ts +1 -1
- package/src/runtime/routes/conversation-query-routes.ts +1 -1
- package/src/runtime/routes/conversation-routes.ts +30 -2
- package/src/runtime/routes/conversation-starter-routes.ts +13 -7
- package/src/runtime/routes/conversations-import-routes.ts +24 -7
- package/src/runtime/routes/host-app-control-routes.ts +1 -1
- package/src/runtime/routes/host-cu-routes.ts +1 -1
- package/src/runtime/routes/identity-routes.ts +18 -3
- package/src/runtime/routes/inbound-message-handler.ts +1 -1
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
- package/src/runtime/routes/inference-profile-session-handler.ts +11 -0
- package/src/runtime/routes/inference-profile-session-reaper.ts +6 -0
- package/src/runtime/routes/memory-v3-routes.ts +65 -305
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +1 -1
- package/src/runtime/routes/playground/helpers.ts +1 -1
- package/src/runtime/routes/plugins-routes.ts +337 -35
- package/src/runtime/routes/stt-routes.ts +45 -12
- package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
- package/src/runtime/routes/work-items-routes.ts +2 -4
- package/src/runtime/routes/workspace-routes.ts +50 -15
- package/src/runtime/services/conversation-serializer.ts +1 -1
- package/src/runtime/verification-outbound-actions.ts +147 -2
- package/src/runtime/verification-templates.ts +29 -3
- package/src/services/published-app-updater.ts +30 -8
- package/src/signals/cancel.ts +2 -4
- package/src/subagent/manager.ts +21 -5
- package/src/telemetry/__tests__/activation-funnel.test.ts +95 -0
- package/src/telemetry/activation-funnel.ts +167 -0
- package/src/telemetry/types.ts +13 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +154 -0
- package/src/telemetry/usage-telemetry-reporter.ts +26 -1
- package/src/tools/acp/context.ts +20 -0
- package/src/tools/acp/list-agents.test.ts +9 -19
- package/src/tools/acp/list-agents.ts +3 -15
- package/src/tools/acp/spawn.test.ts +173 -202
- package/src/tools/acp/spawn.ts +37 -172
- package/src/tools/acp/steer.test.ts +105 -8
- package/src/tools/acp/steer.ts +48 -17
- package/src/tools/apps/executors.ts +166 -50
- package/src/tools/browser/browser-execution.ts +12 -2
- package/src/tools/filesystem/write.ts +34 -0
- package/src/tools/network/web-fetch.ts +65 -24
- package/src/tools/skills/load.ts +1 -1
- package/src/tools/subagent/spawn.ts +2 -4
- package/src/tools/ui-surface/definitions.ts +32 -5
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +69 -45
- package/docs/plugins.md +0 -832
- package/examples/plugins/echo/register.ts +0 -143
- 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 -251
- package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -667
- package/src/__tests__/pipeline-runner.test.ts +0 -554
- package/src/daemon/wake-target-adapter.ts +0 -253
- package/src/memory/v3/__tests__/assign.test.ts +0 -242
- package/src/memory/v3/__tests__/capabilities.test.ts +0 -118
- package/src/memory/v3/__tests__/core.test.ts +0 -39
- package/src/memory/v3/__tests__/health.test.ts +0 -219
- package/src/memory/v3/__tests__/maintain-job.test.ts +0 -288
- package/src/memory/v3/__tests__/needle.test.ts +0 -107
- package/src/memory/v3/__tests__/orchestrate.test.ts +0 -436
- package/src/memory/v3/__tests__/provider-blocks.test.ts +0 -13
- package/src/memory/v3/__tests__/reconcile.test.ts +0 -274
- package/src/memory/v3/__tests__/render-injection.test.ts +0 -61
- package/src/memory/v3/__tests__/router.test.ts +0 -332
- package/src/memory/v3/__tests__/selector.test.ts +0 -470
- package/src/memory/v3/__tests__/shadow-plugin.test.ts +0 -432
- package/src/memory/v3/__tests__/snapshot.test.ts +0 -168
- package/src/memory/v3/__tests__/tree.test.ts +0 -192
- package/src/memory/v3/assign.ts +0 -268
- package/src/memory/v3/capabilities.ts +0 -124
- package/src/memory/v3/core.ts +0 -26
- package/src/memory/v3/health.ts +0 -0
- package/src/memory/v3/maintain-job.ts +0 -314
- package/src/memory/v3/needle.ts +0 -115
- package/src/memory/v3/orchestrate.ts +0 -126
- package/src/memory/v3/page-content.ts +0 -34
- package/src/memory/v3/provider-blocks.ts +0 -26
- package/src/memory/v3/reconcile.ts +0 -523
- package/src/memory/v3/router.ts +0 -190
- package/src/memory/v3/selection-log-store.ts +0 -84
- package/src/memory/v3/selector.ts +0 -226
- package/src/memory/v3/shadow-plugin.ts +0 -411
- package/src/memory/v3/snapshot.ts +0 -209
- package/src/memory/v3/tree.ts +0 -174
- package/src/memory/v3/types.ts +0 -59
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
- package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
- package/src/plugins/defaults/circuit-breaker/package.json +0 -15
- package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
- package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
- package/src/plugins/defaults/compaction/register.ts +0 -35
- package/src/plugins/defaults/compaction/terminal.ts +0 -73
- package/src/plugins/defaults/empty-response/register.ts +0 -23
- package/src/plugins/defaults/history-repair/register.ts +0 -24
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +0 -216
- package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
- package/src/plugins/defaults/overflow-reduce/package.json +0 -15
- package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
- package/src/plugins/defaults/title-generate/register.ts +0 -35
- package/src/plugins/defaults/tool-error/register.ts +0 -23
- package/src/plugins/defaults/tool-result-truncate/register.ts +0 -24
- package/src/proactive-artifact/aux-message-injector.ts +0 -97
- package/src/proactive-artifact/decision.test.ts +0 -226
- package/src/proactive-artifact/decision.ts +0 -165
- package/src/proactive-artifact/index.ts +0 -7
- package/src/proactive-artifact/job.test.ts +0 -962
- package/src/proactive-artifact/job.ts +0 -372
- package/src/proactive-artifact/message-copy.ts +0 -58
- package/src/proactive-artifact/trigger-state.test.ts +0 -286
- package/src/proactive-artifact/trigger-state.ts +0 -123
- package/src/util/map-limit.ts +0 -27
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/llm-retry.ts +0 -0
|
@@ -27,99 +27,18 @@ import { ProviderNotConfiguredError } from "../util/errors.js";
|
|
|
27
27
|
import { getSandboxWorkingDir } from "../util/platform.js";
|
|
28
28
|
import { Conversation } from "./conversation.js";
|
|
29
29
|
import type { ConversationEvictor } from "./conversation-evictor.js";
|
|
30
|
+
import {
|
|
31
|
+
allConversations,
|
|
32
|
+
clearConversations,
|
|
33
|
+
conversationCount,
|
|
34
|
+
conversationIds,
|
|
35
|
+
deleteConversation,
|
|
36
|
+
findConversation,
|
|
37
|
+
setConversation,
|
|
38
|
+
} from "./conversation-registry.js";
|
|
30
39
|
import type { ConversationCreateOptions } from "./handlers/shared.js";
|
|
31
40
|
import { buildTransportHints } from "./transport-hints.js";
|
|
32
41
|
|
|
33
|
-
// ── Private store ──────────────────────────────────────────────────
|
|
34
|
-
|
|
35
|
-
const conversations = new Map<string, Conversation>();
|
|
36
|
-
|
|
37
|
-
// ── Read helpers ───────────────────────────────────────────────────
|
|
38
|
-
|
|
39
|
-
export function findConversation(
|
|
40
|
-
conversationId: string,
|
|
41
|
-
): Conversation | undefined {
|
|
42
|
-
return conversations.get(conversationId);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function findConversationBySurfaceId(
|
|
46
|
-
surfaceId: string,
|
|
47
|
-
): Conversation | undefined {
|
|
48
|
-
// Fast path: exact surfaceId match in surfaceState
|
|
49
|
-
for (const c of conversations.values()) {
|
|
50
|
-
if (c.surfaceState.has(surfaceId)) return c;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Fallback: standalone app surfaces use "app-open-{appId}" IDs that
|
|
54
|
-
// were never part of any conversation. Extract the appId and find
|
|
55
|
-
// a conversation whose surfaceState has a surface for that app.
|
|
56
|
-
const appOpenPrefix = "app-open-";
|
|
57
|
-
if (surfaceId.startsWith(appOpenPrefix)) {
|
|
58
|
-
const appId = surfaceId.slice(appOpenPrefix.length);
|
|
59
|
-
for (const c of conversations.values()) {
|
|
60
|
-
for (const [, state] of c.surfaceState.entries()) {
|
|
61
|
-
const data = state.data as unknown as Record<string, unknown>;
|
|
62
|
-
if (data?.appId === appId) {
|
|
63
|
-
// Register this surfaceId so subsequent lookups are O(1)
|
|
64
|
-
c.surfaceState.set(surfaceId, state);
|
|
65
|
-
return c;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return undefined;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function conversationCount(): number {
|
|
75
|
-
return conversations.size;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/** Iterate over all active conversations. */
|
|
79
|
-
export function allConversations(): IterableIterator<Conversation> {
|
|
80
|
-
return conversations.values();
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/** Iterate over all [id, conversation] entries. */
|
|
84
|
-
export function conversationEntries(): IterableIterator<
|
|
85
|
-
[string, Conversation]
|
|
86
|
-
> {
|
|
87
|
-
return conversations.entries();
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/** Iterate over all active conversation IDs. */
|
|
91
|
-
function conversationIds(): IterableIterator<string> {
|
|
92
|
-
return conversations.keys();
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// ── Write helpers ──────────────────────────────────────────────────
|
|
96
|
-
|
|
97
|
-
export function setConversation(
|
|
98
|
-
conversationId: string,
|
|
99
|
-
conversation: Conversation,
|
|
100
|
-
): void {
|
|
101
|
-
conversations.set(conversationId, conversation);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export function deleteConversation(conversationId: string): boolean {
|
|
105
|
-
return conversations.delete(conversationId);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export function clearConversations(): void {
|
|
109
|
-
conversations.clear();
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// ── Underlying Map (for the evictor, which takes a mutable ref) ───
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Expose the raw Map for the {@link ConversationEvictor}, which needs
|
|
116
|
-
* a mutable reference to delete entries during sweeps. No other code
|
|
117
|
-
* should use this — prefer the named helpers above.
|
|
118
|
-
*/
|
|
119
|
-
export function getConversationMap(): Map<string, Conversation> {
|
|
120
|
-
return conversations;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
42
|
// ── Per-conversation persistent options ────────────────────────────
|
|
124
43
|
|
|
125
44
|
const conversationOptions = new Map<string, ConversationCreateOptions>();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { v4 as uuid } from "uuid";
|
|
2
2
|
|
|
3
|
+
import { isActivationSession } from "../memory/activation-session-store.js";
|
|
3
4
|
import {
|
|
4
5
|
addAppConversationId,
|
|
5
6
|
getApp,
|
|
@@ -14,6 +15,7 @@ import {
|
|
|
14
15
|
getMessages,
|
|
15
16
|
updateMessageContent,
|
|
16
17
|
} from "../memory/conversation-crud.js";
|
|
18
|
+
import { recordActivationEvent } from "../memory/onboarding-events-store.js";
|
|
17
19
|
import {
|
|
18
20
|
assistantEventHub,
|
|
19
21
|
broadcastMessage,
|
|
@@ -23,10 +25,17 @@ import {
|
|
|
23
25
|
enforceSameActorOrErrorResult,
|
|
24
26
|
pickSameUserAutoResolve,
|
|
25
27
|
} from "../runtime/auth/same-actor.js";
|
|
28
|
+
import type { AuthContext } from "../runtime/auth/types.js";
|
|
26
29
|
import type {
|
|
27
30
|
InteractiveUiRequest,
|
|
28
31
|
InteractiveUiResult,
|
|
29
32
|
} from "../runtime/interactive-ui-types.js";
|
|
33
|
+
import {
|
|
34
|
+
activationMomentEmitsAtShow,
|
|
35
|
+
type ActivationMomentParam,
|
|
36
|
+
activationStepNameForMomentParam,
|
|
37
|
+
isActivationMomentParam,
|
|
38
|
+
} from "../telemetry/activation-funnel.js";
|
|
30
39
|
import type { ToolExecutionResult } from "../tools/types.js";
|
|
31
40
|
import { getLogger } from "../util/logger.js";
|
|
32
41
|
import { isPlainObject } from "../util/object.js";
|
|
@@ -544,6 +553,12 @@ export interface SurfaceConversationContext {
|
|
|
544
553
|
readonly assistantId?: string;
|
|
545
554
|
/** Inherited to spawned conversations in the `launch_conversation` action path. */
|
|
546
555
|
readonly trustContext?: TrustContext;
|
|
556
|
+
/** Verified requester auth context for the active turn. */
|
|
557
|
+
readonly authContext?: AuthContext;
|
|
558
|
+
/** Per-turn auth snapshot, preferred for tool dispatch authorization. */
|
|
559
|
+
readonly currentTurnAuthContext?: AuthContext;
|
|
560
|
+
/** JWT-verified requester principal for the active turn. */
|
|
561
|
+
readonly currentTurnSourceActorPrincipalId?: string;
|
|
547
562
|
readonly channelCapabilities?: {
|
|
548
563
|
channel: string;
|
|
549
564
|
supportsDynamicUi: boolean;
|
|
@@ -569,6 +584,14 @@ export interface SurfaceConversationContext {
|
|
|
569
584
|
style?: string;
|
|
570
585
|
data?: Record<string, unknown>;
|
|
571
586
|
}>;
|
|
587
|
+
/**
|
|
588
|
+
* Activation-rail telemetry tag (daemon-only). When the model tags a
|
|
589
|
+
* `ui_show` surface as an activation funnel moment, the token is captured
|
|
590
|
+
* here so the milestone can be recorded deterministically when the user
|
|
591
|
+
* commits the surface (`handleSurfaceAction`). Never forwarded to the
|
|
592
|
+
* client.
|
|
593
|
+
*/
|
|
594
|
+
activationMoment?: ActivationMomentParam;
|
|
572
595
|
}
|
|
573
596
|
>;
|
|
574
597
|
surfaceUndoStacks: Map<string, string[]>;
|
|
@@ -613,6 +636,12 @@ export interface SurfaceConversationContext {
|
|
|
613
636
|
display?: string;
|
|
614
637
|
persistent?: boolean;
|
|
615
638
|
toolCallId?: string;
|
|
639
|
+
/**
|
|
640
|
+
* Commit-timing activation-rail tag (daemon-only). Carried through to the
|
|
641
|
+
* persisted `ui_surface` history block so it survives a reload — never sent
|
|
642
|
+
* to the client.
|
|
643
|
+
*/
|
|
644
|
+
activationMoment?: ActivationMomentParam;
|
|
616
645
|
}>;
|
|
617
646
|
/** Optional proxy for delegating computer-use actions to a connected desktop client. */
|
|
618
647
|
hostCuProxy?: HostCuProxy;
|
|
@@ -1250,6 +1279,60 @@ function getRequestedSurfaceCompletionSummary(
|
|
|
1250
1279
|
return summary || "Completed";
|
|
1251
1280
|
}
|
|
1252
1281
|
|
|
1282
|
+
/**
|
|
1283
|
+
* Best-effort recorder for a single activation-funnel moment. Gated on the
|
|
1284
|
+
* conversation being a marked activation-rail session. Fire-and-forget: never
|
|
1285
|
+
* throws, never blocks or alters the surface-action flow (a failure is logged
|
|
1286
|
+
* and swallowed). Shared by the show-time path (`first_wow_executed`, recorded
|
|
1287
|
+
* when the surface renders) and the commit-time path (the other moments,
|
|
1288
|
+
* recorded when the user commits the surface).
|
|
1289
|
+
*/
|
|
1290
|
+
function recordActivationMoment(
|
|
1291
|
+
ctx: SurfaceConversationContext,
|
|
1292
|
+
moment: ActivationMomentParam,
|
|
1293
|
+
): void {
|
|
1294
|
+
try {
|
|
1295
|
+
if (!isActivationSession(ctx.conversationId)) return;
|
|
1296
|
+
recordActivationEvent({
|
|
1297
|
+
stepName: activationStepNameForMomentParam(moment),
|
|
1298
|
+
sessionId: ctx.conversationId,
|
|
1299
|
+
});
|
|
1300
|
+
} catch (err) {
|
|
1301
|
+
log.warn(
|
|
1302
|
+
{ err, conversationId: ctx.conversationId, moment },
|
|
1303
|
+
"Failed to record activation moment",
|
|
1304
|
+
);
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
/**
|
|
1309
|
+
* Best-effort activation-funnel emission on a user surface commit.
|
|
1310
|
+
*
|
|
1311
|
+
* When the committed surface carries a commit-timing `activationMoment` tag,
|
|
1312
|
+
* record the corresponding funnel milestone. Show-timing moments
|
|
1313
|
+
* (`first_wow_executed`) are recorded at render time in `surfaceProxyResolver`
|
|
1314
|
+
* and are NOT stored on `surfaceState`, so they never reach this path. The tag
|
|
1315
|
+
* is cleared after the first record so re-entrant or repeated commits on the
|
|
1316
|
+
* same surface do not double-emit (and the deterministic `daemon_event_id`
|
|
1317
|
+
* collapses any cross-surface duplicate downstream anyway).
|
|
1318
|
+
*
|
|
1319
|
+
* Must be called only from terminal-commit paths (user clicked an action /
|
|
1320
|
+
* submitted / selected-and-committed), NOT from intermediate non-terminal
|
|
1321
|
+
* events (`selection_changed` / `content_changed` / `state_update`).
|
|
1322
|
+
*/
|
|
1323
|
+
function maybeEmitActivationMoment(
|
|
1324
|
+
ctx: SurfaceConversationContext,
|
|
1325
|
+
surfaceId: string,
|
|
1326
|
+
): void {
|
|
1327
|
+
const stored = ctx.surfaceState.get(surfaceId);
|
|
1328
|
+
const moment = stored?.activationMoment;
|
|
1329
|
+
if (!moment) return;
|
|
1330
|
+
// Clear the tag first so this can fire at most once per surface even if the
|
|
1331
|
+
// commit path is re-entered.
|
|
1332
|
+
stored.activationMoment = undefined;
|
|
1333
|
+
recordActivationMoment(ctx, moment);
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1253
1336
|
function completeSurfaceFromAction(
|
|
1254
1337
|
ctx: SurfaceConversationContext,
|
|
1255
1338
|
surfaceId: string,
|
|
@@ -1317,6 +1400,13 @@ export async function handleSurfaceAction(
|
|
|
1317
1400
|
});
|
|
1318
1401
|
markSurfaceCompleted(ctx, surfaceId, summary);
|
|
1319
1402
|
|
|
1403
|
+
// Terminal user commit on a standalone surface (submit, not cancel/dismiss)
|
|
1404
|
+
// — record an activation milestone if tagged. Must run before
|
|
1405
|
+
// `cleanupStandaloneSurface` clears the surface state.
|
|
1406
|
+
if (!isCancellation) {
|
|
1407
|
+
maybeEmitActivationMoment(ctx, surfaceId);
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1320
1410
|
// Cleanup and resolve — order matters: cleanup clears the timer
|
|
1321
1411
|
// before resolve() unblocks the caller.
|
|
1322
1412
|
cleanupStandaloneSurface(ctx, surfaceId);
|
|
@@ -1403,6 +1493,10 @@ export async function handleSurfaceAction(
|
|
|
1403
1493
|
{ originConversationId: ctx.conversationId, conversationId, surfaceId },
|
|
1404
1494
|
"launch_conversation dispatched inline from surface action",
|
|
1405
1495
|
);
|
|
1496
|
+
// Launching a child conversation is a terminal user commit — record an
|
|
1497
|
+
// activation milestone if tagged. The helper clears the tag after firing,
|
|
1498
|
+
// so the other commit-path call sites below can't double-emit.
|
|
1499
|
+
maybeEmitActivationMoment(ctx, surfaceId);
|
|
1406
1500
|
return { accepted: true, conversationId };
|
|
1407
1501
|
}
|
|
1408
1502
|
|
|
@@ -1557,6 +1651,12 @@ export async function handleSurfaceAction(
|
|
|
1557
1651
|
return;
|
|
1558
1652
|
}
|
|
1559
1653
|
|
|
1654
|
+
// Terminal user commit accepted — record the activation milestone if this
|
|
1655
|
+
// surface was tagged (best-effort, no-op otherwise). Deferred until after
|
|
1656
|
+
// the rejection check so a queue-full click doesn't over-report a moment
|
|
1657
|
+
// (and the one-shot tag stays intact for the user's retry).
|
|
1658
|
+
maybeEmitActivationMoment(ctx, surfaceId);
|
|
1659
|
+
|
|
1560
1660
|
const requestedCompletionSummary =
|
|
1561
1661
|
getRequestedSurfaceCompletionSummary(mergedData);
|
|
1562
1662
|
if (requestedCompletionSummary) {
|
|
@@ -1796,6 +1896,12 @@ export async function handleSurfaceAction(
|
|
|
1796
1896
|
return;
|
|
1797
1897
|
}
|
|
1798
1898
|
|
|
1899
|
+
// Terminal user commit accepted — record the activation milestone if this
|
|
1900
|
+
// surface was tagged (best-effort, no-op otherwise). Deferred until after the
|
|
1901
|
+
// rejection check so a queue-full click doesn't over-report a moment (and the
|
|
1902
|
+
// one-shot tag stays intact for the user's retry).
|
|
1903
|
+
maybeEmitActivationMoment(ctx, surfaceId);
|
|
1904
|
+
|
|
1799
1905
|
const requestedCompletionSummary =
|
|
1800
1906
|
getRequestedSurfaceCompletionSummary(mergedData);
|
|
1801
1907
|
|
|
@@ -1960,6 +2066,15 @@ export function refreshSurfacesForApp(
|
|
|
1960
2066
|
return refreshed;
|
|
1961
2067
|
}
|
|
1962
2068
|
|
|
2069
|
+
/**
|
|
2070
|
+
* Strip a leading "Connect "/"Connected " verb from an OAuth provider label so
|
|
2071
|
+
* a supplied displayName like "Connect Gmail" doesn't double the verb when
|
|
2072
|
+
* prefixed (e.g. avoids "Connected Connect Gmail").
|
|
2073
|
+
*/
|
|
2074
|
+
function stripConnectVerb(label: string): string {
|
|
2075
|
+
return label.replace(/^connect(?:ed)?\s+/i, "");
|
|
2076
|
+
}
|
|
2077
|
+
|
|
1963
2078
|
export function buildCompletionSummary(
|
|
1964
2079
|
surfaceType: string | undefined,
|
|
1965
2080
|
actionId: string,
|
|
@@ -2026,20 +2141,24 @@ export function buildCompletionSummary(
|
|
|
2026
2141
|
: typeof data?.providerKey === "string"
|
|
2027
2142
|
? data.providerKey
|
|
2028
2143
|
: "OAuth";
|
|
2144
|
+
// Strip the verb once so every branch (connected/cancelled/failed/
|
|
2145
|
+
// fallback) is normalized — a displayName like "Connect Gmail" must not
|
|
2146
|
+
// produce "Cancelled Connect Gmail connection".
|
|
2147
|
+
const label = stripConnectVerb(providerLabel);
|
|
2029
2148
|
const accountLabel =
|
|
2030
2149
|
typeof data?.accountLabel === "string" ? data.accountLabel : undefined;
|
|
2031
2150
|
if (actionId === "connect" || data?.status === "connected") {
|
|
2032
2151
|
return accountLabel
|
|
2033
|
-
? `Connected ${
|
|
2034
|
-
: `Connected ${
|
|
2152
|
+
? `Connected ${label}: ${accountLabel}`
|
|
2153
|
+
: `Connected ${label}`;
|
|
2035
2154
|
}
|
|
2036
2155
|
if (actionId === "cancel" || data?.status === "cancelled") {
|
|
2037
|
-
return `Cancelled ${
|
|
2156
|
+
return `Cancelled ${label} connection`;
|
|
2038
2157
|
}
|
|
2039
2158
|
if (data?.status === "error") {
|
|
2040
|
-
return `${
|
|
2159
|
+
return `${label} connection failed`;
|
|
2041
2160
|
}
|
|
2042
|
-
return `${
|
|
2161
|
+
return `${label} connection ${actionId}`;
|
|
2043
2162
|
}
|
|
2044
2163
|
if (surfaceType === "list" && data) {
|
|
2045
2164
|
const selectedIds = data.selectedIds as string[] | undefined;
|
|
@@ -2120,18 +2239,21 @@ function buildUserFacingLabel(
|
|
|
2120
2239
|
: typeof data?.providerKey === "string"
|
|
2121
2240
|
? data.providerKey
|
|
2122
2241
|
: "OAuth";
|
|
2242
|
+
// Strip the verb once so every branch is normalized (e.g. a displayName
|
|
2243
|
+
// like "Connect Gmail" must not produce "Connect Gmail connection failed").
|
|
2244
|
+
const label = stripConnectVerb(providerLabel);
|
|
2123
2245
|
const accountLabel =
|
|
2124
2246
|
typeof data?.accountLabel === "string" ? data.accountLabel : undefined;
|
|
2125
2247
|
if (actionId === "connect" || data?.status === "connected") {
|
|
2126
2248
|
return accountLabel
|
|
2127
|
-
? `Connected ${
|
|
2128
|
-
: `Connected ${
|
|
2249
|
+
? `Connected ${label}: ${accountLabel}`
|
|
2250
|
+
: `Connected ${label}`;
|
|
2129
2251
|
}
|
|
2130
2252
|
if (actionId === "cancel" || data?.status === "cancelled") {
|
|
2131
2253
|
return "Cancelled";
|
|
2132
2254
|
}
|
|
2133
2255
|
if (data?.status === "error") {
|
|
2134
|
-
return `${
|
|
2256
|
+
return `${label} connection failed`;
|
|
2135
2257
|
}
|
|
2136
2258
|
return `Selected: ${actionId}`;
|
|
2137
2259
|
}
|
|
@@ -2199,7 +2321,10 @@ export async function surfaceProxyResolver(
|
|
|
2199
2321
|
// validate at the tool-resolution layer for the same reason. The proxy
|
|
2200
2322
|
// re-checks same-user (single authoritative gate); using the shared
|
|
2201
2323
|
// helper keeps log payload and error wording identical at both layers.
|
|
2202
|
-
const sourceActorPrincipalId =
|
|
2324
|
+
const sourceActorPrincipalId =
|
|
2325
|
+
ctx.currentTurnSourceActorPrincipalId ??
|
|
2326
|
+
ctx.currentTurnAuthContext?.actorPrincipalId ??
|
|
2327
|
+
ctx.authContext?.actorPrincipalId;
|
|
2203
2328
|
if (targetClientId != null) {
|
|
2204
2329
|
const client = assistantEventHub.getClientById(targetClientId);
|
|
2205
2330
|
if (!client) {
|
|
@@ -2305,7 +2430,10 @@ export async function surfaceProxyResolver(
|
|
|
2305
2430
|
? input.target_client_id
|
|
2306
2431
|
: undefined;
|
|
2307
2432
|
|
|
2308
|
-
const sourceActorPrincipalId =
|
|
2433
|
+
const sourceActorPrincipalId =
|
|
2434
|
+
ctx.currentTurnSourceActorPrincipalId ??
|
|
2435
|
+
ctx.currentTurnAuthContext?.actorPrincipalId ??
|
|
2436
|
+
ctx.authContext?.actorPrincipalId;
|
|
2309
2437
|
if (targetClientId != null) {
|
|
2310
2438
|
const client = assistantEventHub.getClientById(targetClientId);
|
|
2311
2439
|
if (!client) {
|
|
@@ -2488,6 +2616,24 @@ export async function surfaceProxyResolver(
|
|
|
2488
2616
|
...(a.data ? { data: a.data } : {}),
|
|
2489
2617
|
}));
|
|
2490
2618
|
|
|
2619
|
+
// Optional activation-rail telemetry tag. Daemon-only metadata: validated
|
|
2620
|
+
// and ignored if invalid; never forwarded to the client.
|
|
2621
|
+
const activationMoment =
|
|
2622
|
+
typeof input.activation_moment === "string" &&
|
|
2623
|
+
isActivationMomentParam(input.activation_moment)
|
|
2624
|
+
? input.activation_moment
|
|
2625
|
+
: undefined;
|
|
2626
|
+
|
|
2627
|
+
// Show-timing moments (`first_wow_executed`) record the instant the surface
|
|
2628
|
+
// renders — a display-only result/`work_result` card may never be committed,
|
|
2629
|
+
// so a commit-time emit would never fire. We record now and do NOT store the
|
|
2630
|
+
// tag, so the commit path won't double-emit. Commit-timing moments are
|
|
2631
|
+
// stored and recorded when the user commits the surface (see
|
|
2632
|
+
// `handleSurfaceAction` → `maybeEmitActivationMoment`).
|
|
2633
|
+
const storeTagForCommit =
|
|
2634
|
+
activationMoment !== undefined &&
|
|
2635
|
+
!activationMomentEmitsAtShow(activationMoment);
|
|
2636
|
+
|
|
2491
2637
|
// Track surface state for ui_update merging (includes actions so we can
|
|
2492
2638
|
// look up per-action data payloads when the client sends an action back).
|
|
2493
2639
|
ctx.surfaceState.set(surfaceId, {
|
|
@@ -2495,8 +2641,13 @@ export async function surfaceProxyResolver(
|
|
|
2495
2641
|
data,
|
|
2496
2642
|
title,
|
|
2497
2643
|
actions: mappedActions,
|
|
2644
|
+
...(storeTagForCommit ? { activationMoment } : {}),
|
|
2498
2645
|
});
|
|
2499
2646
|
|
|
2647
|
+
if (activationMoment !== undefined && !storeTagForCommit) {
|
|
2648
|
+
recordActivationMoment(ctx, activationMoment);
|
|
2649
|
+
}
|
|
2650
|
+
|
|
2500
2651
|
log.info(
|
|
2501
2652
|
{
|
|
2502
2653
|
surfaceId,
|
|
@@ -2524,7 +2675,9 @@ export async function surfaceProxyResolver(
|
|
|
2524
2675
|
...(toolUseId ? { toolCallId: toolUseId } : {}),
|
|
2525
2676
|
} as unknown as UiSurfaceShow);
|
|
2526
2677
|
|
|
2527
|
-
// Track surface for persistence with the message
|
|
2678
|
+
// Track surface for persistence with the message. The commit-timing
|
|
2679
|
+
// activation tag rides along (daemon-only) so it survives history restore;
|
|
2680
|
+
// show-timing moments aren't stored here (already recorded at render).
|
|
2528
2681
|
ctx.currentTurnSurfaces.push({
|
|
2529
2682
|
surfaceId,
|
|
2530
2683
|
surfaceType,
|
|
@@ -2534,6 +2687,7 @@ export async function surfaceProxyResolver(
|
|
|
2534
2687
|
display,
|
|
2535
2688
|
...(persistent ? { persistent: true } : {}),
|
|
2536
2689
|
...(toolUseId ? { toolCallId: toolUseId } : {}),
|
|
2690
|
+
...(storeTagForCommit ? { activationMoment } : {}),
|
|
2537
2691
|
});
|
|
2538
2692
|
|
|
2539
2693
|
if (awaitAction) {
|
|
@@ -4,6 +4,7 @@ import { getConversation } from "../memory/conversation-crud.js";
|
|
|
4
4
|
import { resolveConversationDirectoryPaths } from "../memory/conversation-directories.js";
|
|
5
5
|
import { renderWorkspaceTopLevelContext } from "../workspace/top-level-renderer.js";
|
|
6
6
|
import { scanTopLevelDirectories } from "../workspace/top-level-scanner.js";
|
|
7
|
+
import { findConversationOrSubagent } from "./conversation-registry.js";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Subset of Conversation state that workspace context helpers need.
|
|
@@ -25,6 +26,22 @@ export interface WorkspaceConversationContext {
|
|
|
25
26
|
hostUsername?: string;
|
|
26
27
|
}
|
|
27
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Resolve the live workspace top-level block for a conversation, refreshing
|
|
31
|
+
* the dirty-guarded cache first so a workspace-mutating tool's
|
|
32
|
+
* `markWorkspaceTopLevelDirty` from the prior turn is picked up. Returns `null`
|
|
33
|
+
* when no live conversation is found (no active conversation, or a context with
|
|
34
|
+
* no conversation id) or when the rendered context is empty.
|
|
35
|
+
*/
|
|
36
|
+
export function resolveWorkspaceTopLevelContext(
|
|
37
|
+
conversationId: string | undefined,
|
|
38
|
+
): string | null {
|
|
39
|
+
const conversation = findConversationOrSubagent(conversationId);
|
|
40
|
+
if (!conversation) return null;
|
|
41
|
+
refreshWorkspaceTopLevelContextIfNeeded(conversation);
|
|
42
|
+
return conversation.workspaceTopLevelContext;
|
|
43
|
+
}
|
|
44
|
+
|
|
28
45
|
/** Refresh workspace top-level directory context if needed. */
|
|
29
46
|
export function refreshWorkspaceTopLevelContextIfNeeded(
|
|
30
47
|
ctx: WorkspaceConversationContext,
|