@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
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
* substitute in.
|
|
16
16
|
*
|
|
17
17
|
* Lifecycle:
|
|
18
|
-
* 1. Bail if `config.memory.v2.enabled` is false
|
|
19
|
-
* claimed a stale row from before
|
|
18
|
+
* 1. Bail if `config.memory.enabled` or `config.memory.v2.enabled` is false
|
|
19
|
+
* (the worker may have claimed a stale row from before memory was
|
|
20
|
+
* disabled).
|
|
20
21
|
* 2. Acquire a single-process lock at `memory/.v2-state/consolidation.lock`
|
|
21
22
|
* so two overlapping schedule windows can't fight over the same files.
|
|
22
23
|
* The lock contains the holder's PID + timestamp so a crashed run leaves
|
|
@@ -41,9 +42,11 @@
|
|
|
41
42
|
* a conservative full-reembed effectively free. On failure no follow-ups
|
|
42
43
|
* are enqueued — the agent's writes may be partial and re-embedding
|
|
43
44
|
* partial state would be misleading.
|
|
44
|
-
* 7. Release the lock.
|
|
45
|
-
*
|
|
46
|
-
*
|
|
45
|
+
* 7. Release the lock. A stale lock is taken over automatically on the next
|
|
46
|
+
* run (single-writer per workspace): when the holder's PID is no longer
|
|
47
|
+
* running, or — because the daemon runs as PID 1 in containers and a
|
|
48
|
+
* restarted daemon collides with the dead holder's PID — when the lock is
|
|
49
|
+
* older than a TTL well above the run's hard timeout.
|
|
47
50
|
*
|
|
48
51
|
* The handler never propagates exceptions from the run path — `runBackgroundJob`
|
|
49
52
|
* absorbs them and returns a structured result. A thrown error before the
|
|
@@ -96,6 +99,25 @@ const MEMORY_V3_LIVE = "memory-v3-live" as const;
|
|
|
96
99
|
*/
|
|
97
100
|
const CONSOLIDATION_TIMEOUT_MS = 15 * 60 * 1000;
|
|
98
101
|
|
|
102
|
+
/**
|
|
103
|
+
* Age past which a lock held by an apparently-live PID is taken over anyway.
|
|
104
|
+
*
|
|
105
|
+
* The PID-liveness probe alone is not sufficient in containers: the daemon
|
|
106
|
+
* runs as PID 1, so after a container restart `isProcessAlive(1)` reports the
|
|
107
|
+
* NEW daemon as alive even though it is not the process that wrote the lock.
|
|
108
|
+
* PID-1 collision means a lock left behind by a crashed/restarted run can
|
|
109
|
+
* never be declared stale by liveness alone, and consolidation wedges
|
|
110
|
+
* permanently (every scheduled run skips with `locked`).
|
|
111
|
+
*
|
|
112
|
+
* A lock older than this TTL is treated as abandoned regardless of PID
|
|
113
|
+
* liveness. The bound is a large multiple of the run's hard timeout — the
|
|
114
|
+
* lock timestamp is written at acquire time and a run can hold the lock for
|
|
115
|
+
* at most `CONSOLIDATION_TIMEOUT_MS`, so a TTL well above that can never fire
|
|
116
|
+
* against a legitimately in-flight run while still recovering a wedged lock
|
|
117
|
+
* within a couple of scheduled passes.
|
|
118
|
+
*/
|
|
119
|
+
const STALE_LOCK_TTL_MS = 4 * CONSOLIDATION_TIMEOUT_MS;
|
|
120
|
+
|
|
99
121
|
/**
|
|
100
122
|
* Follow-up jobs to fan out after a successful consolidation.
|
|
101
123
|
*
|
|
@@ -129,6 +151,11 @@ export async function memoryV2ConsolidateJob(
|
|
|
129
151
|
_job: MemoryJob,
|
|
130
152
|
config: AssistantConfig,
|
|
131
153
|
): Promise<ConsolidationOutcome> {
|
|
154
|
+
if (config.memory.enabled === false) {
|
|
155
|
+
log.debug("memory.enabled is false; consolidation skipped");
|
|
156
|
+
return { kind: "disabled" };
|
|
157
|
+
}
|
|
158
|
+
|
|
132
159
|
if (!config.memory.v2.enabled) {
|
|
133
160
|
log.debug("memory.v2.enabled is false; consolidation skipped");
|
|
134
161
|
return { kind: "disabled" };
|
|
@@ -175,10 +202,23 @@ export async function memoryV2ConsolidateJob(
|
|
|
175
202
|
// the `memory.v2.consolidation_prompt_path` config override but bounds
|
|
176
203
|
// it to a regular file under 1 MiB before substitution so a stray path
|
|
177
204
|
// (or a `/dev/zero`-style pseudo-file) cannot exfiltrate megabytes of
|
|
178
|
-
// bytes through the wake hint.
|
|
205
|
+
// bytes through the wake hint. The core-pages curation section rides the
|
|
206
|
+
// same v3 gate as the maintenance follow-up: the file feeds the v3 core
|
|
207
|
+
// lane, so on a v2-only install the instruction would curate a file
|
|
208
|
+
// nothing reads.
|
|
209
|
+
// The article SHAPE is keyed on the live flag alone: under shadow, live
|
|
210
|
+
// prompts are still assembled by v2's injection model, so consolidation
|
|
211
|
+
// must keep producing `summary:`-bearing fragment pages until the flip.
|
|
212
|
+
const memoryV3Live = isAssistantFeatureFlagEnabled(MEMORY_V3_LIVE, config);
|
|
213
|
+
const memoryV3Active =
|
|
214
|
+
isAssistantFeatureFlagEnabled(MEMORY_V3_SHADOW, config) || memoryV3Live;
|
|
179
215
|
const prompt = resolveConsolidationPrompt(
|
|
180
216
|
config.memory.v2.consolidation_prompt_path,
|
|
181
217
|
cutoff,
|
|
218
|
+
{
|
|
219
|
+
includeCorePagesSection: memoryV3Active,
|
|
220
|
+
articleShape: memoryV3Live ? "v3" : "v2",
|
|
221
|
+
},
|
|
182
222
|
);
|
|
183
223
|
|
|
184
224
|
const runResult = await runBackgroundJob({
|
|
@@ -212,10 +252,7 @@ export async function memoryV2ConsolidateJob(
|
|
|
212
252
|
// is active, so it never fans out on v2-only installs.
|
|
213
253
|
const followUpJobIds: string[] = [];
|
|
214
254
|
const jobTypes: MemoryJobType[] = [...FOLLOW_UP_JOB_TYPES];
|
|
215
|
-
if (
|
|
216
|
-
isAssistantFeatureFlagEnabled(MEMORY_V3_SHADOW, config) ||
|
|
217
|
-
isAssistantFeatureFlagEnabled(MEMORY_V3_LIVE, config)
|
|
218
|
-
) {
|
|
255
|
+
if (memoryV3Active) {
|
|
219
256
|
jobTypes.push(V3_FOLLOW_UP_JOB_TYPE);
|
|
220
257
|
}
|
|
221
258
|
for (const jobType of jobTypes) {
|
|
@@ -282,11 +319,13 @@ export function countBufferLines(bufferPath: string): number {
|
|
|
282
319
|
* `null` on success, or the current holder string (file contents, typically
|
|
283
320
|
* `pid timestamp`) when the file already exists and the holder is still alive.
|
|
284
321
|
*
|
|
285
|
-
* Stale-lock takeover: if the file exists but its holder PID
|
|
286
|
-
*
|
|
287
|
-
*
|
|
288
|
-
*
|
|
289
|
-
*
|
|
322
|
+
* Stale-lock takeover: if the file exists but its holder is stale (PID not
|
|
323
|
+
* running, payload corrupt, or — for the container PID-1 collision — older
|
|
324
|
+
* than the TTL; see {@link holderStaleReason}), unlink the stale file and
|
|
325
|
+
* retry the create exactly once. This recovers automatically from a crashed
|
|
326
|
+
* or restarted daemon that died with the lock held — otherwise every
|
|
327
|
+
* subsequent scheduled consolidation would skip with `locked` indefinitely
|
|
328
|
+
* until an operator manually removed the file.
|
|
290
329
|
*
|
|
291
330
|
* The simple takeover-then-retry is safe here (unlike `snapshot-lock.ts`'s
|
|
292
331
|
* full rename-aside dance) because only the assistant's jobs worker calls
|
|
@@ -303,11 +342,12 @@ function tryAcquireLock(lockPath: string): string | null {
|
|
|
303
342
|
|
|
304
343
|
const firstHolder = tryCreate(lockPath);
|
|
305
344
|
if (firstHolder === null) return null;
|
|
306
|
-
|
|
345
|
+
const staleReason = holderStaleReason(firstHolder);
|
|
346
|
+
if (staleReason === null) return firstHolder;
|
|
307
347
|
|
|
308
348
|
log.info(
|
|
309
|
-
{ lockPath, holder: firstHolder },
|
|
310
|
-
"consolidation: taking over stale lock
|
|
349
|
+
{ lockPath, holder: firstHolder, reason: staleReason },
|
|
350
|
+
"consolidation: taking over stale lock",
|
|
311
351
|
);
|
|
312
352
|
try {
|
|
313
353
|
unlinkSync(lockPath);
|
|
@@ -359,18 +399,62 @@ function tryCreate(lockPath: string): string | null {
|
|
|
359
399
|
}
|
|
360
400
|
|
|
361
401
|
/**
|
|
362
|
-
*
|
|
363
|
-
*
|
|
364
|
-
*
|
|
365
|
-
* the
|
|
366
|
-
*
|
|
402
|
+
* Why a lock holder is considered stale, for diagnosable takeover logs:
|
|
403
|
+
* - `unparseable`: empty / corrupt payload (partial write from a crash).
|
|
404
|
+
* - `pid_dead`: the holder's PID is no longer running.
|
|
405
|
+
* - `expired`: the lock is older than {@link STALE_LOCK_TTL_MS} even though
|
|
406
|
+
* its PID still appears alive — the PID-1 collision case in containers.
|
|
367
407
|
*/
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
408
|
+
type StaleReason = "unparseable" | "pid_dead" | "expired";
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Parse a `<pid> <timestamp>` holder payload (see `tryCreate`'s write).
|
|
412
|
+
* Returns `null` when the PID cannot be parsed; a missing/garbled timestamp
|
|
413
|
+
* yields `timestamp: null` so a partial payload still gives us the PID.
|
|
414
|
+
*/
|
|
415
|
+
function parseHolder(
|
|
416
|
+
holder: string,
|
|
417
|
+
): { pid: number; timestamp: number | null } | null {
|
|
418
|
+
const match = /^(\d+)(?:\s+(\d+))?/.exec(holder);
|
|
419
|
+
if (!match) return null;
|
|
420
|
+
const pid = Number.parseInt(match[1], 10);
|
|
421
|
+
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
422
|
+
const timestamp =
|
|
423
|
+
match[2] !== undefined ? Number.parseInt(match[2], 10) : null;
|
|
424
|
+
return {
|
|
425
|
+
pid,
|
|
426
|
+
timestamp:
|
|
427
|
+
timestamp !== null && Number.isFinite(timestamp) ? timestamp : null,
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Classify a holder string, returning the reason it is stale or `null` when
|
|
433
|
+
* the lock is held by a live process and must be respected.
|
|
434
|
+
*
|
|
435
|
+
* Takeover triggers, in order:
|
|
436
|
+
* 1. Unparseable / empty / `"unknown"` payload → `unparseable`. The only
|
|
437
|
+
* writer is `tryCreate`, so corruption is a partial write from a crashed
|
|
438
|
+
* prior holder, not a live writer mid-flush.
|
|
439
|
+
* 2. PID not running → `pid_dead`. The fast path for a crashed daemon (or a
|
|
440
|
+
* different process now occupying that PID on a normal host).
|
|
441
|
+
* 3. Lock older than {@link STALE_LOCK_TTL_MS} → `expired`. Required because
|
|
442
|
+
* the daemon runs as PID 1 in containers: after a restart the new daemon
|
|
443
|
+
* is also PID 1, so the liveness probe alone reports the holder as alive
|
|
444
|
+
* forever and could never reclaim an abandoned lock. The TTL is far above
|
|
445
|
+
* the run's hard timeout, so it never fires against an in-flight run.
|
|
446
|
+
*/
|
|
447
|
+
function holderStaleReason(holder: string): StaleReason | null {
|
|
448
|
+
const parsed = parseHolder(holder);
|
|
449
|
+
if (parsed === null) return "unparseable";
|
|
450
|
+
if (!isProcessAlive(parsed.pid)) return "pid_dead";
|
|
451
|
+
if (
|
|
452
|
+
parsed.timestamp !== null &&
|
|
453
|
+
Date.now() - parsed.timestamp > STALE_LOCK_TTL_MS
|
|
454
|
+
) {
|
|
455
|
+
return "expired";
|
|
456
|
+
}
|
|
457
|
+
return null;
|
|
374
458
|
}
|
|
375
459
|
|
|
376
460
|
/**
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `# memory/concepts/<slug>.md` header convention for persisted
|
|
3
|
+
* memory-injection blocks — builder, matcher, and slug extraction.
|
|
4
|
+
*
|
|
5
|
+
* Both the v2 injection renderer (`injection.ts`) and the v3 card renderers
|
|
6
|
+
* (`plugins/defaults/memory-v3-shadow/card.ts` / `page-content.ts`) emit each
|
|
7
|
+
* concept page under this exact header inside the block that is persisted on
|
|
8
|
+
* the user message (`metadata.memoryInjectedBlock` /
|
|
9
|
+
* `metadata.memoryV3InjectedBlock`) and re-attached at request build. The
|
|
10
|
+
* v3 prune valve's card-section parser keys on the same header. Keeping the
|
|
11
|
+
* builder and the matcher in one place is what guarantees the writers and the
|
|
12
|
+
* read-side parsers never drift apart.
|
|
13
|
+
*
|
|
14
|
+
* Skill (`skills/<id>`) and CLI-command sections render under their own
|
|
15
|
+
* `# Skill:` / `# CLI command:` headers without a recoverable slug, so they
|
|
16
|
+
* are intentionally not extracted.
|
|
17
|
+
*
|
|
18
|
+
* Kept as a dependency-free leaf (like `memory-marker.ts`) so the
|
|
19
|
+
* conversation-fork path can import it without pulling in the heavyweight
|
|
20
|
+
* injection module.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/** Render the concept-page path header that opens a page's section inside an
|
|
24
|
+
* injected memory block. The read-side inverse is
|
|
25
|
+
* {@link INJECTED_CONCEPT_HEADER_REGEX}. */
|
|
26
|
+
export function injectedConceptHeader(slug: string): string {
|
|
27
|
+
return `# memory/concepts/${slug}.md`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Matches a {@link injectedConceptHeader} line inside an injected block;
|
|
32
|
+
* capture group 1 is the page slug.
|
|
33
|
+
*
|
|
34
|
+
* Flagged `gm` for `String.prototype.matchAll`, which clones the regex per
|
|
35
|
+
* spec and so never mutates this shared instance's `lastIndex`. Do NOT call
|
|
36
|
+
* `exec`/`test` on it directly — a `g`-flagged regex is stateful under those.
|
|
37
|
+
*/
|
|
38
|
+
export const INJECTED_CONCEPT_HEADER_REGEX = /^# memory\/concepts\/(.+)\.md$/gm;
|
|
39
|
+
|
|
40
|
+
/** Recover the (deduplicated, in-order) concept slugs a persisted injection
|
|
41
|
+
* block contains. */
|
|
42
|
+
export function extractInjectedConceptSlugs(block: string): string[] {
|
|
43
|
+
const slugs: string[] = [];
|
|
44
|
+
const seen = new Set<string>();
|
|
45
|
+
for (const match of block.matchAll(INJECTED_CONCEPT_HEADER_REGEX)) {
|
|
46
|
+
const slug = match[1]!;
|
|
47
|
+
if (seen.has(slug)) continue;
|
|
48
|
+
seen.add(slug);
|
|
49
|
+
slugs.push(slug);
|
|
50
|
+
}
|
|
51
|
+
return slugs;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Read a persisted memory-injection block off a message's metadata JSON, or
|
|
56
|
+
* `null` when absent/malformed. `key` selects the injection layer: v2's
|
|
57
|
+
* `memoryInjectedBlock` or memory-v3's card block
|
|
58
|
+
* (`MEMORY_V3_INJECTED_BLOCK_METADATA_KEY`).
|
|
59
|
+
*
|
|
60
|
+
* NOTE: `memory/conversation-crud.ts` carries a private copy of this exact
|
|
61
|
+
* helper (its fork-seeding scan predates this export); consolidating it onto
|
|
62
|
+
* this one is a pending cleanup tracked alongside the prune-valve work.
|
|
63
|
+
*/
|
|
64
|
+
export function readInjectedBlock(
|
|
65
|
+
metadata: string | null | undefined,
|
|
66
|
+
key: string,
|
|
67
|
+
): string | null {
|
|
68
|
+
if (!metadata) return null;
|
|
69
|
+
try {
|
|
70
|
+
const parsed: unknown = JSON.parse(metadata);
|
|
71
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
72
|
+
const block = (parsed as Record<string, unknown>)[key];
|
|
73
|
+
if (typeof block === "string") return block;
|
|
74
|
+
}
|
|
75
|
+
} catch {
|
|
76
|
+
// Malformed metadata — treat as no block.
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
@@ -727,8 +727,13 @@ interface RenderInjectionBlockResult {
|
|
|
727
727
|
* if relevant. Suppressed when every section is a full-page fallback —
|
|
728
728
|
* claiming "these are summaries" over already-complete content would mislead
|
|
729
729
|
* the agent into wasted reads.
|
|
730
|
+
*
|
|
731
|
+
* Exported for the v2-suppression regression tests: memory-v3's
|
|
732
|
+
* `V3_CARDS_INJECTION_HEADER` is deliberately byte-identical to this header,
|
|
733
|
+
* which is exactly why the v3-era tail strip must discriminate the two
|
|
734
|
+
* `<memory>` layers by block identity rather than by this shared prefix.
|
|
730
735
|
*/
|
|
731
|
-
const INJECTION_HEADER =
|
|
736
|
+
export const INJECTION_HEADER =
|
|
732
737
|
'Use `file_read("memory/concepts/path/to/file.md")` to read the full pages for any of the injected memory summaries you want more information on.';
|
|
733
738
|
|
|
734
739
|
/**
|