@vellumai/assistant 0.8.10 → 0.8.11-staging.1
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/bun.lock +62 -1
- package/docs/workspace-tools.md +196 -0
- package/examples/plugins/echo/README.md +3 -3
- package/knip.json +1 -0
- package/openapi.yaml +460 -128
- package/package.json +2 -1
- package/scripts/build-plugin-api.ts +299 -0
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +7 -0
- package/src/__tests__/agent-loop-compaction-events.test.ts +197 -0
- package/src/__tests__/agent-loop-exit-reason.test.ts +93 -96
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +2 -0
- package/src/__tests__/agent-loop-output-hooks.test.ts +274 -1
- package/src/__tests__/agent-loop-override-profile.test.ts +3 -0
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +4 -0
- package/src/__tests__/agent-loop-thinking.test.ts +4 -0
- package/src/__tests__/agent-loop.test.ts +578 -5
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +0 -1
- package/src/__tests__/approval-cascade.test.ts +1 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +0 -2
- package/src/__tests__/btw-routes.test.ts +0 -1
- package/src/__tests__/build-persisted-content.test.ts +75 -1
- package/src/__tests__/catalog-install-normalize.test.ts +141 -0
- package/src/__tests__/ces-startup-timeout.test.ts +60 -0
- package/src/__tests__/compaction-events.test.ts +1 -0
- package/src/__tests__/config-managed-gemini-defaults.test.ts +2 -46
- package/src/__tests__/context-overflow-reducer.test.ts +264 -124
- package/src/__tests__/context-window-manager-overflow-rung.test.ts +351 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +13 -5
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +284 -455
- package/src/__tests__/conversation-agent-loop.test.ts +131 -551
- package/src/__tests__/conversation-app-control-instantiation.test.ts +13 -0
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
- package/src/__tests__/conversation-fork-crud.test.ts +259 -0
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-lifecycle.test.ts +257 -1
- package/src/__tests__/conversation-process-callsite.test.ts +1 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +38 -377
- package/src/__tests__/conversation-queue.test.ts +1 -39
- package/src/__tests__/conversation-runtime-assembly.test.ts +119 -8
- package/src/__tests__/conversation-skill-tools.test.ts +491 -5
- package/src/__tests__/conversation-slash-queue.test.ts +1 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -0
- package/src/__tests__/conversation-speed-override.test.ts +1 -0
- package/src/__tests__/conversation-store.test.ts +74 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +4 -1
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +323 -0
- package/src/__tests__/conversation-tool-setup-tools-disabled.test.ts +34 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -0
- package/src/__tests__/corrected-target.test.ts +93 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +3 -5
- package/src/__tests__/credential-execution-tools.test.ts +23 -11
- package/src/__tests__/credential-security-invariants.test.ts +6 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +80 -0
- package/src/__tests__/device-id.test.ts +70 -1
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +6 -40
- package/src/__tests__/empty-response-hook.test.ts +242 -66
- package/src/__tests__/external-plugin-loader.test.ts +0 -31
- package/src/__tests__/get-skill-detail-audit.test.ts +43 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +91 -0
- package/src/__tests__/history-repair-hook.test.ts +228 -3
- package/src/__tests__/host-app-control-proxy.test.ts +45 -0
- package/src/__tests__/host-browser-proxy.test.ts +254 -9
- package/src/__tests__/identity-routes.test.ts +1 -0
- package/src/__tests__/image-recovery-hook.test.ts +387 -0
- package/src/__tests__/injector-chain.test.ts +5 -4
- package/src/__tests__/injector-v3-suppression.test.ts +373 -47
- package/src/__tests__/intent-routing.test.ts +7 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +117 -15
- package/src/__tests__/notification-decision-strategy.test.ts +3 -3
- package/src/__tests__/oauth-store.test.ts +0 -85
- package/src/__tests__/{context-overflow-policy.test.ts → overflow-policy.test.ts} +1 -1
- package/src/__tests__/parallel-tool.benchmark.test.ts +4 -0
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +29 -9
- package/src/__tests__/persist-unsendable-image.test.ts +4 -4
- package/src/__tests__/persistence-secret-redaction.test.ts +78 -0
- package/src/__tests__/plugin-bootstrap.test.ts +82 -73
- package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
- package/src/__tests__/plugin-types.test.ts +0 -8
- package/src/__tests__/provider-catalog-visibility.test.ts +1 -9
- package/src/__tests__/prune-old-conversations-job.test.ts +99 -0
- package/src/__tests__/registry.test.ts +240 -1
- package/src/__tests__/require-fresh-approval.test.ts +3 -0
- package/src/__tests__/schedule-routes.test.ts +116 -1
- package/src/__tests__/schedule-store.test.ts +28 -0
- package/src/__tests__/schedule-tools.test.ts +94 -1
- package/src/__tests__/server-history-render.test.ts +39 -0
- package/src/__tests__/skill-projection-feature-flag.test.ts +13 -0
- package/src/__tests__/skill-projection.benchmark.test.ts +25 -7
- package/src/__tests__/skills.test.ts +202 -0
- package/src/__tests__/slim-skill-category.test.ts +195 -0
- package/src/__tests__/strip-memory-injections.test.ts +33 -39
- package/src/__tests__/test-support/tool-invocation-seed.ts +79 -0
- package/src/__tests__/title-generate-hook.test.ts +9 -7
- package/src/__tests__/tool-audit-listener.test.ts +264 -1
- package/src/__tests__/tool-error-hook.test.ts +4 -3
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -0
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +273 -0
- package/src/__tests__/tool-result-truncate-hook.test.ts +1 -0
- package/src/__tests__/tool-start-timestamp.test.ts +218 -0
- package/src/__tests__/tools-get-route.test.ts +202 -0
- package/src/__tests__/workspace-tool-loader.test.ts +319 -0
- package/src/__tests__/workspace-tools-watcher-flag.test.ts +70 -0
- package/src/agent/loop.ts +569 -319
- package/src/api/events/tool-result.ts +9 -0
- package/src/api/events/tool-use-start.ts +7 -0
- package/src/api/index.ts +10 -0
- package/src/api/responses/conversation-message.ts +135 -27
- package/src/api/responses/memory-v3-selection-log.ts +4 -4
- package/src/approvals/guardian-request-resolvers.ts +26 -0
- package/src/browser-session/backends/host-bridge.ts +29 -0
- package/src/browser-session/index.ts +1 -0
- package/src/browser-session/types.ts +5 -1
- package/src/cli/commands/__tests__/schedules.test.ts +62 -4
- package/src/cli/commands/__tests__/skills.test.ts +53 -0
- package/src/cli/commands/channel-verification-sessions.ts +6 -6
- package/src/cli/commands/inference-providers.ts +0 -8
- package/src/cli/commands/plugins.ts +2 -2
- package/src/cli/commands/schedules.ts +27 -4
- package/src/cli/commands/skills.ts +187 -146
- package/src/cli/commands/tools.ts +106 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +256 -328
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +6 -2
- package/src/cli/lib/__tests__/plugin-details.test.ts +10 -16
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +2 -2
- package/src/cli/lib/__tests__/search-plugins.test.ts +145 -240
- package/src/cli/lib/install-from-github.ts +187 -117
- package/src/cli/lib/plugin-catalog-cache.ts +9 -9
- package/src/cli/lib/plugin-details.ts +38 -68
- package/src/cli/lib/plugin-marketplace.ts +42 -14
- package/src/cli/lib/search-plugins.ts +29 -129
- package/src/cli/program.ts +2 -0
- package/src/config/bundled-skills/acp/SKILL.md +1 -0
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -0
- package/src/config/bundled-skills/app-control/SKILL.md +1 -0
- package/src/config/bundled-skills/computer-use/SKILL.md +1 -0
- package/src/config/bundled-skills/contacts/SKILL.md +1 -0
- package/src/config/bundled-skills/document-editor/SKILL.md +1 -0
- package/src/config/bundled-skills/followups/SKILL.md +1 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +1 -0
- package/src/config/bundled-skills/media-processing/SKILL.md +1 -0
- package/src/config/bundled-skills/messaging/SKILL.md +1 -0
- package/src/config/bundled-skills/phone-calls/SKILL.md +1 -0
- package/src/config/bundled-skills/playbooks/SKILL.md +1 -0
- package/src/config/bundled-skills/schedule/SKILL.md +1 -0
- package/src/config/bundled-skills/schedule/TOOLS.json +11 -3
- package/src/config/bundled-skills/sequences/SKILL.md +1 -0
- package/src/config/bundled-skills/settings/SKILL.md +1 -0
- package/src/config/bundled-skills/skill-management/SKILL.md +101 -1
- package/src/config/bundled-skills/subagent/SKILL.md +1 -0
- package/src/config/bundled-skills/transcribe/SKILL.md +1 -0
- package/src/config/env-registry.ts +23 -0
- package/src/config/feature-flag-registry.json +17 -81
- package/src/config/loader.ts +5 -22
- package/src/config/schema.ts +2 -0
- package/src/config/schemas/__tests__/compaction-logs.test.ts +56 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +0 -1
- package/src/config/schemas/__tests__/memory-v3.test.ts +61 -1
- package/src/config/schemas/compaction-logs.ts +79 -0
- package/src/config/schemas/memory-v2.ts +0 -8
- package/src/config/schemas/memory-v3.ts +104 -33
- package/src/config/seed-inference-profiles.ts +1 -1
- package/src/config/skills.ts +117 -47
- package/src/context/compactor.ts +11 -0
- package/src/context/strip-injections.ts +38 -4
- package/src/credential-execution/feature-gates.ts +0 -21
- package/src/credential-execution/startup-timeout.ts +32 -4
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +18 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +140 -91
- package/src/daemon/conversation-agent-loop.ts +123 -658
- package/src/daemon/conversation-error.ts +6 -33
- package/src/daemon/conversation-lifecycle.ts +1 -1
- package/src/daemon/conversation-runtime-assembly.ts +183 -22
- package/src/daemon/conversation-skill-tools.ts +137 -8
- package/src/daemon/conversation-slash.ts +0 -14
- package/src/daemon/conversation-store.ts +2 -19
- package/src/daemon/conversation-tool-setup.ts +87 -1
- package/src/daemon/conversation.ts +119 -50
- package/src/daemon/external-plugins-bootstrap.ts +36 -95
- package/src/daemon/handlers/config-channels.ts +11 -2
- package/src/daemon/handlers/shared.ts +9 -1
- package/src/daemon/handlers/skills.ts +10 -4
- package/src/daemon/host-app-control-proxy.ts +72 -57
- package/src/daemon/host-browser-proxy.ts +117 -22
- package/src/daemon/lifecycle.ts +34 -5
- package/src/daemon/message-protocol.ts +0 -7
- package/src/daemon/message-types/schedules.ts +1 -0
- package/src/daemon/message-types/skills.ts +17 -0
- package/src/daemon/providers-setup.ts +3 -0
- package/src/daemon/server.ts +3 -3
- package/src/daemon/tool-setup-types.ts +9 -3
- package/src/daemon/trust-context.ts +23 -0
- package/src/daemon/workspace-tools-watcher.ts +324 -0
- package/src/events/tool-audit-listener.ts +78 -16
- package/src/events/tool-metrics-listener.ts +2 -5
- package/src/memory/__tests__/compaction-log-writer-clickhouse.test.ts +227 -0
- package/src/memory/__tests__/conversation-queries.test.ts +176 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +20 -32
- package/src/memory/compaction-log-writer-clickhouse.ts +418 -0
- package/src/memory/conversation-crud.ts +134 -3
- package/src/memory/conversation-queries.ts +64 -7
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.test.ts +130 -1
- package/src/memory/embedding-backend.ts +79 -106
- package/src/memory/embedding-gemini.ts +5 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +12 -0
- package/src/memory/graph/__tests__/handle-remember-v2.test.ts +19 -0
- package/src/memory/graph/conversation-graph-memory.ts +36 -25
- package/src/memory/graph/tool-handlers.ts +3 -0
- package/src/memory/job-handlers/cleanup.ts +3 -1
- package/src/memory/jobs-store.ts +0 -28
- package/src/memory/jobs-worker.ts +10 -22
- package/src/memory/memory-marker.ts +29 -0
- package/src/memory/memory-retrospective-startup-cleanup.ts +1 -1
- package/src/memory/migrations/268-add-memory-v3-selections.ts +6 -0
- package/src/memory/migrations/270-schedule-description.ts +36 -0
- package/src/memory/migrations/275-tool-invocations-add-skill-id.test.ts +81 -0
- package/src/memory/migrations/275-tool-invocations-add-skill-id.ts +20 -0
- package/src/memory/migrations/276-tool-invocations-created-at-id-index.test.ts +68 -0
- package/src/memory/migrations/276-tool-invocations-created-at-id-index.ts +20 -0
- package/src/memory/migrations/277-add-memory-v3-ever-injected.ts +29 -0
- package/src/memory/migrations/278-tool-invocations-telemetry-columns.test.ts +96 -0
- package/src/memory/migrations/278-tool-invocations-telemetry-columns.ts +39 -0
- package/src/memory/migrations/279-create-skill-loaded-events.test.ts +84 -0
- package/src/memory/migrations/279-create-skill-loaded-events.ts +26 -0
- package/src/memory/migrations/280-conversations-surfaced-at.test.ts +88 -0
- package/src/memory/migrations/280-conversations-surfaced-at.ts +24 -0
- package/src/memory/migrations/index.ts +10 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/schema/conversations.ts +16 -0
- package/src/memory/schema/infrastructure.ts +26 -0
- package/src/memory/skill-loaded-events-store.test.ts +160 -0
- package/src/memory/skill-loaded-events-store.ts +95 -0
- package/src/memory/tool-executed-events-store.test.ts +219 -0
- package/src/memory/tool-executed-events-store.ts +102 -0
- package/src/memory/tool-usage-store.ts +15 -3
- package/src/memory/v2/__tests__/consolidation-job.test.ts +117 -12
- package/src/memory/v2/__tests__/consolidation-prompt-flag-gating-guard.test.ts +189 -0
- package/src/memory/v2/__tests__/injected-block-slugs.test.ts +90 -0
- package/src/memory/v2/__tests__/page-store.test.ts +33 -0
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +88 -15
- package/src/memory/v2/activation-store.ts +50 -1
- package/src/memory/v2/consolidation-job.ts +113 -29
- package/src/memory/v2/injected-block-slugs.ts +79 -0
- package/src/memory/v2/injection.ts +6 -1
- package/src/memory/v2/prompts/consolidation.ts +414 -13
- package/src/memory/v2/router.ts +2 -28
- package/src/memory/v2/static-context.ts +1 -1
- package/src/memory/v2/types.ts +16 -0
- 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 +2 -1
- 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/oauth/oauth-store.ts +0 -9
- package/src/permissions/checker.test.ts +83 -1
- package/src/permissions/checker.ts +25 -2
- package/src/permissions/gateway-threshold-reader.test.ts +182 -0
- package/src/permissions/gateway-threshold-reader.ts +80 -0
- package/src/platform/client.ts +1 -3
- package/src/platform/feature-gate.ts +3 -12
- package/src/plugin-api/constants.ts +4 -2
- package/src/plugin-api/index.ts +63 -11
- package/src/plugin-api/types.ts +236 -71
- package/src/plugins/defaults/compaction/compact.ts +66 -2
- package/src/plugins/defaults/compaction/context-overflow-reducer.ts +240 -32
- package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
- package/src/{daemon/context-overflow-policy.ts → plugins/defaults/compaction/overflow-policy.ts} +1 -1
- package/src/plugins/defaults/compaction/window-manager.ts +303 -1
- package/src/plugins/defaults/empty-response/hooks/post-model-call.ts +173 -0
- package/src/plugins/defaults/empty-response/hooks/stop.ts +11 -115
- package/src/plugins/defaults/empty-response/nudge-state-store.ts +46 -0
- package/src/plugins/defaults/history-repair/hooks/post-model-call.ts +50 -0
- package/src/plugins/defaults/history-repair/hooks/stop.ts +22 -0
- package/src/plugins/defaults/history-repair/repair-state-store.ts +51 -0
- package/src/plugins/defaults/history-repair/terminal.ts +39 -2
- package/src/plugins/defaults/image-recovery/detect.ts +25 -0
- package/src/plugins/defaults/image-recovery/hooks/post-model-call.ts +73 -0
- package/src/plugins/defaults/image-recovery/hooks/stop.ts +22 -0
- package/src/plugins/defaults/image-recovery/image-recovery-state-store.ts +48 -0
- package/src/plugins/defaults/image-recovery/package.json +14 -0
- package/src/{daemon/persist-unsendable-image.ts → plugins/defaults/image-recovery/recover.ts} +67 -14
- package/src/plugins/defaults/index.ts +71 -5
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +76 -112
- package/src/plugins/defaults/memory-retrieval/hooks/{user-prompt-submit-temp.ts → user-prompt-submit.ts} +83 -74
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +14 -8
- package/src/plugins/defaults/memory-retrieval/injectors.ts +2 -18
- package/src/plugins/defaults/memory-retrieval/package.json +14 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1157 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +683 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/live-integration.test.ts +161 -140
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +160 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +335 -316
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +145 -53
- package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +38 -1
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +18 -8
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +112 -71
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +192 -51
- package/src/plugins/defaults/memory-v3-shadow/__tests__/types.test.ts +4 -16
- package/src/plugins/defaults/memory-v3-shadow/card.test.ts +173 -0
- package/src/plugins/defaults/memory-v3-shadow/card.ts +116 -0
- package/src/plugins/defaults/memory-v3-shadow/core-set.test.ts +104 -0
- package/src/plugins/defaults/memory-v3-shadow/core-set.ts +59 -0
- package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.test.ts +305 -0
- package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.ts +278 -0
- package/src/plugins/defaults/memory-v3-shadow/hot-set.test.ts +138 -0
- package/src/plugins/defaults/memory-v3-shadow/hot-set.ts +85 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +331 -24
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +119 -13
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +169 -114
- package/src/plugins/defaults/memory-v3-shadow/page-content.ts +47 -16
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +144 -66
- package/src/plugins/defaults/memory-v3-shadow/prune.test.ts +758 -0
- package/src/plugins/defaults/memory-v3-shadow/prune.ts +471 -0
- package/src/plugins/defaults/memory-v3-shadow/render-injection.ts +68 -16
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +19 -12
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +96 -43
- package/src/plugins/defaults/memory-v3-shadow/types.ts +34 -17
- package/src/plugins/defaults/title-generate/hooks/stop.ts +9 -11
- package/src/plugins/pipeline.ts +8 -5
- package/src/plugins/types.ts +5 -51
- package/src/providers/cache-control.ts +26 -0
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +1 -2
- package/src/providers/model-catalog.ts +13 -1
- package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +147 -0
- package/src/providers/openai/chat-completions-provider.ts +46 -0
- package/src/providers/openai/responses-provider.ts +45 -0
- package/src/providers/registry.ts +0 -8
- package/src/runtime/__tests__/agent-wake.test.ts +0 -1
- package/src/runtime/agent-wake.ts +13 -0
- package/src/runtime/routes/__tests__/acp-routes.test.ts +151 -0
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +12 -50
- package/src/runtime/routes/__tests__/conversation-surface-routes.test.ts +322 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +0 -62
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +31 -11
- package/src/runtime/routes/acp-routes.test.ts +106 -0
- package/src/runtime/routes/acp-routes.ts +248 -2
- package/src/runtime/routes/browser-tabs-routes.ts +1 -1
- package/src/runtime/routes/channel-verification-routes.ts +14 -5
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +0 -14
- package/src/runtime/routes/consolidation-routes.ts +6 -82
- package/src/runtime/routes/conversation-list-routes.ts +6 -0
- package/src/runtime/routes/conversation-management-routes.ts +71 -0
- package/src/runtime/routes/identity-routes.ts +8 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
- package/src/runtime/routes/inference-provider-connection-routes.ts +0 -45
- package/src/runtime/routes/plugins-routes.ts +34 -45
- package/src/runtime/routes/schedule-routes.ts +43 -5
- package/src/runtime/routes/settings-routes.ts +140 -15
- package/src/runtime/routes/skills-routes.ts +18 -6
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +140 -0
- package/src/runtime/services/conversation-serializer.ts +38 -1
- package/src/runtime/verification-outbound-actions.ts +147 -2
- package/src/runtime/verification-templates.ts +29 -3
- package/src/schedule/schedule-store.ts +19 -0
- package/src/skills/catalog-install.ts +77 -13
- package/src/tasks/task-scheduler.ts +1 -0
- package/src/telemetry/types.ts +66 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +542 -13
- package/src/telemetry/usage-telemetry-reporter.ts +213 -20
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +49 -2
- package/src/tools/browser/__tests__/browser-status.test.ts +29 -5
- package/src/tools/browser/browser-execution.ts +27 -9
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +380 -4
- package/src/tools/browser/cdp-client/__tests__/host-bridge-cdp-client.test.ts +107 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +6 -1
- package/src/tools/browser/cdp-client/factory.ts +217 -17
- package/src/tools/browser/cdp-client/host-bridge-cdp-client.ts +67 -0
- package/src/tools/browser/cdp-client/types.ts +22 -2
- package/src/tools/credential-execution/make-authenticated-request.ts +2 -1
- package/src/tools/credential-execution/manage-secure-command-tool.ts +169 -164
- package/src/tools/credential-execution/run-authenticated-command.ts +2 -1
- package/src/tools/executor.ts +39 -7
- package/src/tools/registry.ts +387 -5
- package/src/tools/schedule/create.ts +16 -0
- package/src/tools/schedule/list.ts +12 -4
- package/src/tools/schedule/update.ts +12 -0
- package/src/tools/skills/load.ts +11 -6
- package/src/tools/terminal/safe-env.ts +2 -0
- package/src/tools/types.ts +65 -9
- package/src/tools/workspace-tools/loader.ts +673 -0
- package/src/usage/attribution.ts +28 -0
- package/src/util/device-id.ts +17 -3
- package/src/util/platform.ts +16 -0
- package/tsconfig.plugin-api.json +13 -0
- package/src/__tests__/plugin-external-api.test.ts +0 -68
- package/src/__tests__/plugin-skill-contribution.test.ts +0 -355
- package/src/daemon/message-types/browser.ts +0 -10
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/eval-turns.json +0 -36
- package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/live-turns.json +0 -37
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-eviction.test.ts +0 -106
- package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-skeleton.test.ts +0 -44
- package/src/plugins/defaults/memory-v3-shadow/working-set.ts +0 -91
- package/src/plugins/external-api.ts +0 -114
- package/src/plugins/plugin-skill-contributions.ts +0 -292
|
@@ -121,6 +121,24 @@ describe("createResolveToolsCallback — config.tools.exclude", () => {
|
|
|
121
121
|
).toEqual(["bash", "file_read"]);
|
|
122
122
|
});
|
|
123
123
|
|
|
124
|
+
test("memory.enabled=false hides remember but keeps recall available", () => {
|
|
125
|
+
const stub: Partial<AssistantConfig> = {
|
|
126
|
+
memory: { enabled: false } as AssistantConfig["memory"],
|
|
127
|
+
tools: { exclude: [] },
|
|
128
|
+
};
|
|
129
|
+
getConfigSpy = spyOn(configLoader, "getConfig").mockReturnValue(
|
|
130
|
+
stub as AssistantConfig,
|
|
131
|
+
);
|
|
132
|
+
const resolver = createResolveToolsCallback(
|
|
133
|
+
[def("remember"), def("recall"), def("file_read")],
|
|
134
|
+
makeCtx(),
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
const names = resolver!([]).map((d) => d.name);
|
|
138
|
+
|
|
139
|
+
expect(names).toEqual(["recall", "file_read"]);
|
|
140
|
+
});
|
|
141
|
+
|
|
124
142
|
test("excluded tool stays excluded under disk-pressure cleanup mode", () => {
|
|
125
143
|
// `bash` is a cleanup-safe tool and would normally survive cleanup mode;
|
|
126
144
|
// the exclude filter must still suppress it.
|
|
@@ -17,6 +17,10 @@ import type {
|
|
|
17
17
|
import { getConfig } from "../config/loader.js";
|
|
18
18
|
import { recordEstimate } from "../context/estimator-calibration.js";
|
|
19
19
|
import { getCalibrationProviderKey } from "../context/token-estimator.js";
|
|
20
|
+
import {
|
|
21
|
+
recordCompactionEndBestEffort,
|
|
22
|
+
recordCompactionStartBestEffort,
|
|
23
|
+
} from "../memory/compaction-log-writer-clickhouse.js";
|
|
20
24
|
import { projectAssistantMessage } from "../memory/conversation-attention-store.js";
|
|
21
25
|
import {
|
|
22
26
|
deleteMessageById,
|
|
@@ -51,7 +55,6 @@ import type {
|
|
|
51
55
|
ImageContent,
|
|
52
56
|
Message,
|
|
53
57
|
} from "../providers/types.js";
|
|
54
|
-
import { isContextOverflowError } from "../providers/types.js";
|
|
55
58
|
import {
|
|
56
59
|
getCurrentSeq,
|
|
57
60
|
recordPersistedSeq,
|
|
@@ -81,10 +84,8 @@ import type { AssistantSurface } from "./conversation-agent-loop.js";
|
|
|
81
84
|
import {
|
|
82
85
|
buildConversationErrorMessage,
|
|
83
86
|
classifyConversationError,
|
|
84
|
-
isContextTooLarge,
|
|
85
87
|
maxTokensReachedClassification,
|
|
86
88
|
} from "./conversation-error.js";
|
|
87
|
-
import { isProviderOrderingError } from "./conversation-slash.js";
|
|
88
89
|
import { resolveTurnTimezoneContext } from "./date-context.js";
|
|
89
90
|
import type {
|
|
90
91
|
CardSurfaceData,
|
|
@@ -159,23 +160,6 @@ export interface EventHandlerState {
|
|
|
159
160
|
exchangeLlmCallCount: number;
|
|
160
161
|
readonly exchangeRawResponses: unknown[];
|
|
161
162
|
model: string;
|
|
162
|
-
orderingErrorDetected: boolean;
|
|
163
|
-
deferredOrderingError: string | null;
|
|
164
|
-
contextTooLargeDetected: boolean;
|
|
165
|
-
/**
|
|
166
|
-
* Set when the provider rejects with an image-dimension error. The agent
|
|
167
|
-
* loop strips or downscales oversized image blocks from ctx.messages and
|
|
168
|
-
* retries once before surfacing an error to the user.
|
|
169
|
-
*/
|
|
170
|
-
imageTooLargeDetected: boolean;
|
|
171
|
-
/**
|
|
172
|
-
* The provider error object when context_too_large is detected, preserved
|
|
173
|
-
* so `parseActualTokensFromError` can prefer the typed
|
|
174
|
-
* `ContextOverflowError` fields over the string-regex fallback. The
|
|
175
|
-
* message is always reachable via `.message` on this object — no separate
|
|
176
|
-
* field is needed.
|
|
177
|
-
*/
|
|
178
|
-
contextTooLargeError: unknown;
|
|
179
163
|
providerErrorUserMessage: string | null;
|
|
180
164
|
lastAssistantMessageId: string | undefined;
|
|
181
165
|
/**
|
|
@@ -282,6 +266,15 @@ export interface EventHandlerState {
|
|
|
282
266
|
* debounce so a mid-turn snapshot reflects what the user is watching live.
|
|
283
267
|
*/
|
|
284
268
|
currentMessageContent: ContentBlock[];
|
|
269
|
+
/**
|
|
270
|
+
* Per-thinking-block timing for the in-flight LLM call, in stream order:
|
|
271
|
+
* entry `i` is the `i`-th thinking block mirrored into `currentMessageContent`.
|
|
272
|
+
* `startedAt` is stamped when a thinking block opens; `completedAt` is the
|
|
273
|
+
* last reasoning delta fused into it. Used to stamp `_startedAt`/`_completedAt`
|
|
274
|
+
* onto the authoritative thinking blocks at `message_complete`, mirroring how
|
|
275
|
+
* tool calls persist timing. Reset alongside `currentMessageContent`.
|
|
276
|
+
*/
|
|
277
|
+
currentThinkingTimestamps: { startedAt: number; completedAt: number }[];
|
|
285
278
|
/**
|
|
286
279
|
* `seq` of the most recent streamed content delta mirrored into
|
|
287
280
|
* `currentMessageContent`. Recorded as the conversation's persisted `seq`
|
|
@@ -309,14 +302,14 @@ export interface EventHandlerDeps {
|
|
|
309
302
|
/**
|
|
310
303
|
* Commit a successful inline compaction to durable state. Invoked from the
|
|
311
304
|
* `compaction_completed` dispatch case (when `result.compacted`) with the
|
|
312
|
-
* loop's compaction result and the stripped pre-compaction `
|
|
305
|
+
* loop's compaction result and the stripped pre-compaction `messages`. Supplied
|
|
313
306
|
* by the orchestrator because the body writes Conversation DB-record fields,
|
|
314
307
|
* projects Slack provenance, and emits transport the loop is intentionally
|
|
315
308
|
* blind to.
|
|
316
309
|
*/
|
|
317
310
|
readonly applyCompaction: (
|
|
318
311
|
result: ContextWindowResult,
|
|
319
|
-
|
|
312
|
+
messages: Message[],
|
|
320
313
|
) => Promise<void>;
|
|
321
314
|
}
|
|
322
315
|
|
|
@@ -337,11 +330,6 @@ export function createEventHandlerState(): EventHandlerState {
|
|
|
337
330
|
exchangeLlmCallCount: 0,
|
|
338
331
|
exchangeRawResponses: [],
|
|
339
332
|
model: "",
|
|
340
|
-
orderingErrorDetected: false,
|
|
341
|
-
deferredOrderingError: null,
|
|
342
|
-
contextTooLargeDetected: false,
|
|
343
|
-
imageTooLargeDetected: false,
|
|
344
|
-
contextTooLargeError: null,
|
|
345
333
|
providerErrorUserMessage: null,
|
|
346
334
|
lastAssistantMessageId: undefined,
|
|
347
335
|
assistantRowAwaitingFinalization: false,
|
|
@@ -371,6 +359,7 @@ export function createEventHandlerState(): EventHandlerState {
|
|
|
371
359
|
pendingPartialFlushTimer: undefined,
|
|
372
360
|
pendingPartialFlushPromise: undefined,
|
|
373
361
|
currentMessageContent: [],
|
|
362
|
+
currentThinkingTimestamps: [],
|
|
374
363
|
lastPersistedContentSeq: undefined,
|
|
375
364
|
};
|
|
376
365
|
}
|
|
@@ -420,6 +409,37 @@ export function buildPersistedAssistantContent(
|
|
|
420
409
|
});
|
|
421
410
|
}
|
|
422
411
|
|
|
412
|
+
/**
|
|
413
|
+
* Stamp `_startedAt`/`_completedAt` onto the content's thinking blocks from the
|
|
414
|
+
* per-block timing captured while streaming, matched by position: the `i`-th
|
|
415
|
+
* thinking block in `content` takes `timings[i]`. The `_`-prefixed fields are
|
|
416
|
+
* vellum-internal metadata (never sent to providers), mirroring how tool calls
|
|
417
|
+
* persist timing; `renderHistoryContent` reads them back onto the wire schema's
|
|
418
|
+
* `startedAt`/`completedAt`.
|
|
419
|
+
*
|
|
420
|
+
* Timing is only captured when reasoning is streamed (`streamThinking`), so a
|
|
421
|
+
* turn with thinking disabled — or any block without a matching entry — is left
|
|
422
|
+
* unstamped and the UI hides its duration, exactly as a tool call with no
|
|
423
|
+
* timing does.
|
|
424
|
+
*/
|
|
425
|
+
export function stampThinkingTiming(
|
|
426
|
+
content: ContentBlock[],
|
|
427
|
+
timings: ReadonlyArray<{ startedAt: number; completedAt: number }>,
|
|
428
|
+
): ContentBlock[] {
|
|
429
|
+
if (timings.length === 0) return content;
|
|
430
|
+
let thinkingIdx = 0;
|
|
431
|
+
return content.map((block) => {
|
|
432
|
+
if (block.type !== "thinking") return block;
|
|
433
|
+
const timing = timings[thinkingIdx++];
|
|
434
|
+
if (!timing) return block;
|
|
435
|
+
return {
|
|
436
|
+
...block,
|
|
437
|
+
_startedAt: timing.startedAt,
|
|
438
|
+
_completedAt: timing.completedAt,
|
|
439
|
+
} as ContentBlock;
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
|
|
423
443
|
/** Append a streamed text chunk to `state.currentMessageContent`, fusing into tail text block. */
|
|
424
444
|
function appendTextToCurrentMessage(
|
|
425
445
|
state: EventHandlerState,
|
|
@@ -446,15 +466,19 @@ function appendThinkingToCurrentMessage(
|
|
|
446
466
|
thinking: string,
|
|
447
467
|
): void {
|
|
448
468
|
if (thinking.length === 0) return;
|
|
469
|
+
const now = Date.now();
|
|
449
470
|
const tail = state.currentMessageContent.at(-1);
|
|
450
471
|
if (tail && tail.type === "thinking") {
|
|
451
472
|
tail.thinking = tail.thinking + thinking;
|
|
473
|
+
const timing = state.currentThinkingTimestamps.at(-1);
|
|
474
|
+
if (timing) timing.completedAt = now;
|
|
452
475
|
} else {
|
|
453
476
|
state.currentMessageContent.push({
|
|
454
477
|
type: "thinking",
|
|
455
478
|
thinking,
|
|
456
479
|
signature: "",
|
|
457
480
|
});
|
|
481
|
+
state.currentThinkingTimestamps.push({ startedAt: now, completedAt: now });
|
|
458
482
|
}
|
|
459
483
|
}
|
|
460
484
|
|
|
@@ -465,6 +489,7 @@ function resetPartialPersistAccumulator(state: EventHandlerState): void {
|
|
|
465
489
|
state.pendingPartialFlushTimer = undefined;
|
|
466
490
|
}
|
|
467
491
|
state.currentMessageContent = [];
|
|
492
|
+
state.currentThinkingTimestamps = [];
|
|
468
493
|
state.lastPersistedContentSeq = undefined;
|
|
469
494
|
state.pendingPartialFlushPromise = undefined;
|
|
470
495
|
}
|
|
@@ -852,9 +877,14 @@ export function handleToolUse(
|
|
|
852
877
|
if (event.name === "app_create" || event.name === "app_refresh") {
|
|
853
878
|
state.appBuildToolUsedThisRun = true;
|
|
854
879
|
}
|
|
855
|
-
|
|
880
|
+
const startedAt = Date.now();
|
|
881
|
+
state.toolCallTimestamps.set(event.id, { startedAt });
|
|
856
882
|
state.currentToolUseId = event.id;
|
|
857
883
|
state.currentTurnToolUseIds.push(event.id);
|
|
884
|
+
// Stamp the start time onto the already-durable tool_use block so a snapshot
|
|
885
|
+
// fetched mid-tool (refresh / reconnect) carries it and clients can render a
|
|
886
|
+
// running timer without having seen the live `tool_use_start` event.
|
|
887
|
+
recordToolStartOnPersistedMessage(state, event.id, startedAt);
|
|
858
888
|
const statusText = computeToolUseStatusText(event.name, event.input);
|
|
859
889
|
deps.ctx.emitActivityState("tool_running", "tool_use_start", {
|
|
860
890
|
requestId: deps.reqId,
|
|
@@ -867,6 +897,7 @@ export function handleToolUse(
|
|
|
867
897
|
conversationId: deps.ctx.conversationId,
|
|
868
898
|
toolUseId: event.id,
|
|
869
899
|
messageId: state.lastAssistantMessageId,
|
|
900
|
+
startedAt,
|
|
870
901
|
});
|
|
871
902
|
// `message_complete` always precedes tool events (see handleMessageComplete),
|
|
872
903
|
// so this tool_use block is already durable in the assistant row. The
|
|
@@ -1248,8 +1279,9 @@ export async function handleToolResult(
|
|
|
1248
1279
|
});
|
|
1249
1280
|
|
|
1250
1281
|
// Record tool completion timestamp
|
|
1282
|
+
const completedAt = Date.now();
|
|
1251
1283
|
const ts = state.toolCallTimestamps.get(event.toolUseId);
|
|
1252
|
-
if (ts) ts.completedAt =
|
|
1284
|
+
if (ts) ts.completedAt = completedAt;
|
|
1253
1285
|
state.currentToolUseId = undefined;
|
|
1254
1286
|
|
|
1255
1287
|
// Capture risk metadata when present. autoApproved is true when the tool
|
|
@@ -1368,6 +1400,7 @@ export async function handleToolResult(
|
|
|
1368
1400
|
approvalReason: event.approvalReason,
|
|
1369
1401
|
riskThreshold: event.riskThreshold,
|
|
1370
1402
|
activityMetadata: event.activityMetadata,
|
|
1403
|
+
completedAt,
|
|
1371
1404
|
});
|
|
1372
1405
|
|
|
1373
1406
|
// Capture the seq synchronously (before the persist await) so it reflects the
|
|
@@ -1385,6 +1418,44 @@ export async function handleToolResult(
|
|
|
1385
1418
|
}
|
|
1386
1419
|
}
|
|
1387
1420
|
|
|
1421
|
+
/**
|
|
1422
|
+
* Stamp `_startedAt` onto the in-flight tool_use block in the persisted
|
|
1423
|
+
* assistant message the moment the tool begins. The block is already durable
|
|
1424
|
+
* (message_complete precedes tool events), so without this a `/messages`
|
|
1425
|
+
* snapshot fetched mid-tool would carry no start time and clients could not
|
|
1426
|
+
* render a running elapsed-time counter until the whole turn finished. The
|
|
1427
|
+
* full timing + risk annotation still happens in
|
|
1428
|
+
* `annotatePersistedAssistantMessage` once every tool in the turn completes.
|
|
1429
|
+
*/
|
|
1430
|
+
function recordToolStartOnPersistedMessage(
|
|
1431
|
+
state: EventHandlerState,
|
|
1432
|
+
toolUseId: string,
|
|
1433
|
+
startedAt: number,
|
|
1434
|
+
): void {
|
|
1435
|
+
const messageId = state.lastAssistantMessageId;
|
|
1436
|
+
if (!messageId) return;
|
|
1437
|
+
|
|
1438
|
+
const row = getMessageById(messageId);
|
|
1439
|
+
if (!row) return;
|
|
1440
|
+
|
|
1441
|
+
let content: ContentBlock[];
|
|
1442
|
+
try {
|
|
1443
|
+
content = JSON.parse(row.content) as ContentBlock[];
|
|
1444
|
+
} catch {
|
|
1445
|
+
return;
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
for (const block of content) {
|
|
1449
|
+
if (block.type !== "tool_use") continue;
|
|
1450
|
+
const rec = block as unknown as Record<string, unknown>;
|
|
1451
|
+
if (rec.id !== toolUseId) continue;
|
|
1452
|
+
if (rec._startedAt === startedAt) return;
|
|
1453
|
+
rec._startedAt = startedAt;
|
|
1454
|
+
updateMessageContent(messageId, JSON.stringify(content));
|
|
1455
|
+
return;
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1388
1459
|
/**
|
|
1389
1460
|
* After all tools for the current turn complete, fetch the persisted assistant
|
|
1390
1461
|
* message, annotate its tool_use blocks with timing and confirmation metadata,
|
|
@@ -1508,61 +1579,32 @@ function handleError(
|
|
|
1508
1579
|
deps: EventHandlerDeps,
|
|
1509
1580
|
event: Extract<AgentEvent, { type: "error" }>,
|
|
1510
1581
|
): void {
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
} else if (
|
|
1533
|
-
classified.code === "PROVIDER_ORDERING" ||
|
|
1534
|
-
classified.code === "PROVIDER_WEB_SEARCH"
|
|
1535
|
-
) {
|
|
1536
|
-
// Ordering errors detected via classifyConversationError (e.g. from ProviderError
|
|
1537
|
-
// with statusCode 400 and ordering message) — trigger the retry path.
|
|
1538
|
-
state.orderingErrorDetected = true;
|
|
1539
|
-
state.deferredOrderingError = event.error.message;
|
|
1540
|
-
} else {
|
|
1541
|
-
if (classified.errorCategory === "provider_api_error") {
|
|
1542
|
-
log.error(
|
|
1543
|
-
{
|
|
1544
|
-
conversationId: deps.ctx.conversationId,
|
|
1545
|
-
errorCode: classified.code,
|
|
1546
|
-
errorCategory: classified.errorCategory,
|
|
1547
|
-
statusCode:
|
|
1548
|
-
event.error instanceof ProviderError
|
|
1549
|
-
? event.error.statusCode
|
|
1550
|
-
: undefined,
|
|
1551
|
-
provider:
|
|
1552
|
-
event.error instanceof ProviderError
|
|
1553
|
-
? event.error.provider
|
|
1554
|
-
: undefined,
|
|
1555
|
-
errorMessage: event.error.message,
|
|
1556
|
-
},
|
|
1557
|
-
"Provider rejected request with unclassified 4xx error",
|
|
1558
|
-
);
|
|
1559
|
-
}
|
|
1560
|
-
deps.onEvent(
|
|
1561
|
-
buildConversationErrorMessage(deps.ctx.conversationId, classified),
|
|
1562
|
-
);
|
|
1563
|
-
state.providerErrorUserMessage = classified.userMessage;
|
|
1564
|
-
}
|
|
1582
|
+
const classified = classifyConversationError(event.error, {
|
|
1583
|
+
phase: "agent_loop",
|
|
1584
|
+
});
|
|
1585
|
+
if (classified.errorCategory === "provider_api_error") {
|
|
1586
|
+
log.error(
|
|
1587
|
+
{
|
|
1588
|
+
conversationId: deps.ctx.conversationId,
|
|
1589
|
+
errorCode: classified.code,
|
|
1590
|
+
errorCategory: classified.errorCategory,
|
|
1591
|
+
statusCode:
|
|
1592
|
+
event.error instanceof ProviderError
|
|
1593
|
+
? event.error.statusCode
|
|
1594
|
+
: undefined,
|
|
1595
|
+
provider:
|
|
1596
|
+
event.error instanceof ProviderError
|
|
1597
|
+
? event.error.provider
|
|
1598
|
+
: undefined,
|
|
1599
|
+
errorMessage: event.error.message,
|
|
1600
|
+
},
|
|
1601
|
+
"Provider rejected request with unclassified 4xx error",
|
|
1602
|
+
);
|
|
1565
1603
|
}
|
|
1604
|
+
deps.onEvent(
|
|
1605
|
+
buildConversationErrorMessage(deps.ctx.conversationId, classified),
|
|
1606
|
+
);
|
|
1607
|
+
state.providerErrorUserMessage = classified.userMessage;
|
|
1566
1608
|
}
|
|
1567
1609
|
|
|
1568
1610
|
export function handleMaxTokensReached(
|
|
@@ -1730,10 +1772,13 @@ export async function handleMessageComplete(
|
|
|
1730
1772
|
// redacted) via the shared helper. The partial-persist flush uses
|
|
1731
1773
|
// the same helper with `surfaces=[]` so a mid-turn snapshot lands in
|
|
1732
1774
|
// the same shape as the finalize.
|
|
1733
|
-
const contentForPersistence =
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1775
|
+
const contentForPersistence = stampThinkingTiming(
|
|
1776
|
+
buildPersistedAssistantContent(
|
|
1777
|
+
event.message.content as ContentBlock[],
|
|
1778
|
+
deps.ctx.currentTurnSurfaces,
|
|
1779
|
+
state.toolActivityMetadata,
|
|
1780
|
+
),
|
|
1781
|
+
state.currentThinkingTimestamps,
|
|
1737
1782
|
);
|
|
1738
1783
|
|
|
1739
1784
|
// The row was reserved at `llm_call_started` (with channel metadata
|
|
@@ -1766,6 +1811,7 @@ export async function handleMessageComplete(
|
|
|
1766
1811
|
// Reset the partial-persist mirror so subsequent calls in this turn
|
|
1767
1812
|
// start with an empty running view.
|
|
1768
1813
|
state.currentMessageContent = [];
|
|
1814
|
+
state.currentThinkingTimestamps = [];
|
|
1769
1815
|
state.lastPersistedContentSeq = undefined;
|
|
1770
1816
|
|
|
1771
1817
|
// ── Indexing + attention projection ──
|
|
@@ -2269,6 +2315,7 @@ export async function dispatchAgentEvent(
|
|
|
2269
2315
|
break;
|
|
2270
2316
|
}
|
|
2271
2317
|
case "context_compacting":
|
|
2318
|
+
recordCompactionStartBestEffort(deps.ctx.conversationId, event);
|
|
2272
2319
|
deps.ctx.emitActivityState("thinking", "context_compacting", {
|
|
2273
2320
|
requestId: deps.reqId,
|
|
2274
2321
|
statusText: "Compacting context",
|
|
@@ -2283,7 +2330,7 @@ export async function dispatchAgentEvent(
|
|
|
2283
2330
|
deps.onEvent(event);
|
|
2284
2331
|
break;
|
|
2285
2332
|
case "compaction_completed":
|
|
2286
|
-
// Always commit the loop-stripped `
|
|
2333
|
+
// Always commit the loop-stripped `messages` as the durable message base
|
|
2287
2334
|
// so re-injection re-applies onto the stripped history even when the
|
|
2288
2335
|
// pipeline ran but did not compact. When it did compact, commit the
|
|
2289
2336
|
// durable result (DB-record fields, Slack provenance, SSE) — which
|
|
@@ -2292,9 +2339,10 @@ export async function dispatchAgentEvent(
|
|
|
2292
2339
|
// so the committed history is in place in time. A failed durable
|
|
2293
2340
|
// commit re-throws below to abort the turn rather than re-injecting
|
|
2294
2341
|
// against half-applied state.
|
|
2295
|
-
deps.ctx.
|
|
2342
|
+
recordCompactionEndBestEffort(deps.ctx.conversationId, event);
|
|
2343
|
+
deps.ctx.messages = event.messages;
|
|
2296
2344
|
if (event.result.compacted) {
|
|
2297
|
-
await deps.applyCompaction(event.result, event.
|
|
2345
|
+
await deps.applyCompaction(event.result, event.messages);
|
|
2298
2346
|
}
|
|
2299
2347
|
break;
|
|
2300
2348
|
case "history_stripped":
|
|
@@ -2354,7 +2402,8 @@ export async function dispatchAgentEvent(
|
|
|
2354
2402
|
);
|
|
2355
2403
|
// Re-throw errors from critical handlers that must not be silently swallowed:
|
|
2356
2404
|
// - message_complete: persists assistant message to DB, sets state flags
|
|
2357
|
-
// - error:
|
|
2405
|
+
// - error: triggers image recovery or surfaces the user-facing error
|
|
2406
|
+
// message
|
|
2358
2407
|
// - usage: records token accounting
|
|
2359
2408
|
// - compaction_completed: durable compaction commit; aborting the turn is
|
|
2360
2409
|
// safer than re-injecting against a half-applied compaction
|