@vellumai/assistant 0.8.7 → 0.8.8
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/Dockerfile +20 -4
- package/docker-entrypoint.sh +4 -2
- package/docker-init-apt-root.sh +3 -1
- package/docker-kata-apt-env.sh +3 -1
- package/docker-kata-runtime-family.sh +12 -0
- package/docs/architecture/memory.md +1 -1
- package/docs/plugins.md +75 -79
- package/examples/plugins/echo/README.md +6 -12
- package/examples/plugins/echo/register.ts +0 -41
- package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +3 -3
- package/openapi.yaml +3381 -348
- package/package.json +1 -1
- package/scripts/generate-openapi.ts +68 -41
- package/src/__tests__/agent-loop-exit-reason.test.ts +34 -39
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +1 -1
- package/src/__tests__/agent-loop.test.ts +37 -87
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +2 -0
- package/src/__tests__/annotate-activity-metadata.test.ts +262 -0
- package/src/__tests__/annotate-risk-options.test.ts +2 -3
- package/src/__tests__/anthropic-provider.test.ts +95 -2
- package/src/__tests__/assistant-event-hub.test.ts +25 -0
- package/src/__tests__/assistant-events-sse-shed.test.ts +8 -0
- package/src/__tests__/{conversation-stream-state.test.ts → assistant-stream-state.test.ts} +252 -91
- package/src/__tests__/auth-fallback-events-store.test.ts +116 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +6 -0
- package/src/__tests__/btw-routes.test.ts +62 -3
- package/src/__tests__/build-persisted-content.test.ts +184 -0
- package/src/__tests__/catalog-files.test.ts +1 -1
- package/src/__tests__/clawhub-files.test.ts +1 -1
- package/src/__tests__/compaction-pipeline.test.ts +1 -1
- package/src/__tests__/compaction.benchmark.test.ts +0 -30
- package/src/__tests__/config-watcher.test.ts +1 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +57 -19
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +6 -2
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -4
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +313 -1136
- package/src/__tests__/conversation-agent-loop.test.ts +596 -1616
- package/src/__tests__/conversation-analysis-routes.test.ts +6 -0
- package/src/__tests__/conversation-history-web-search.test.ts +11 -1
- package/src/__tests__/conversation-pairing.test.ts +4 -31
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +6 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +26 -5
- package/src/__tests__/conversation-queue.test.ts +2 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +3 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +6 -5
- package/src/__tests__/conversation-runtime-assembly.test.ts +170 -229
- package/src/__tests__/conversation-runtime-workspace.test.ts +3 -24
- package/src/__tests__/conversation-slash-commands.test.ts +8 -42
- package/src/__tests__/conversation-slash-queue.test.ts +6 -1
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +84 -0
- package/src/__tests__/conversation-sync-tags.test.ts +27 -15
- package/src/__tests__/conversation-title-service.test.ts +135 -2
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
- package/src/__tests__/cross-provider-web-search.test.ts +214 -1
- package/src/__tests__/db-schedule-syntax-migration.test.ts +5 -0
- package/src/__tests__/dm-persistence.test.ts +5 -1
- package/src/__tests__/empty-response-hook.test.ts +304 -0
- package/src/__tests__/feature-flag-test-helpers.ts +2 -2
- package/src/__tests__/gemini-image-service.test.ts +13 -0
- package/src/__tests__/helpers/mock-provider.ts +110 -0
- package/src/__tests__/helpers/native-web-search-harness.ts +129 -0
- package/src/__tests__/history-repair-hook.test.ts +1 -0
- package/src/__tests__/identity-intro-cache.test.ts +12 -100
- package/src/__tests__/identity-routes.test.ts +248 -7
- package/src/__tests__/inbound-slack-persistence.test.ts +5 -1
- package/src/__tests__/injector-background-turn.test.ts +2 -8
- package/src/__tests__/injector-chain.test.ts +106 -270
- package/src/__tests__/injector-disk-pressure.test.ts +3 -12
- package/src/__tests__/injector-document-comments.test.ts +2 -2
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +30 -22
- package/src/__tests__/injector-v3-suppression.test.ts +31 -37
- package/src/__tests__/internal-telemetry-routes.test.ts +109 -0
- package/src/__tests__/list-messages-page-latest.test.ts +60 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +20 -0
- package/src/__tests__/llm-usage-store.test.ts +223 -1
- package/src/__tests__/memory-retrieval-hook.test.ts +297 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +103 -35
- package/src/__tests__/native-web-search.test.ts +191 -0
- package/src/__tests__/onboarding-template-contract.test.ts +2 -0
- package/src/__tests__/openai-image-service.test.ts +17 -0
- package/src/__tests__/openai-provider.test.ts +31 -1
- package/src/__tests__/persist-unsendable-image.test.ts +215 -0
- package/src/__tests__/persistence-secret-redaction.test.ts +1 -0
- package/src/__tests__/pipeline-runner.test.ts +29 -39
- package/src/__tests__/pkb-autoinject.test.ts +2 -5
- package/src/__tests__/plugin-bootstrap.test.ts +13 -28
- package/src/__tests__/plugin-registry.test.ts +0 -27
- package/src/__tests__/plugin-types.test.ts +2 -125
- package/src/__tests__/process-message-display-content.test.ts +6 -2
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +5 -1
- package/src/__tests__/resolve-trust-class.test.ts +4 -4
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +60 -23
- package/src/__tests__/schedule-routes.test.ts +603 -2
- package/src/__tests__/schedule-store.test.ts +41 -0
- package/src/__tests__/schedule-tools.test.ts +35 -0
- package/src/__tests__/server-history-render.test.ts +314 -1
- package/src/__tests__/skillssh-files.test.ts +1 -1
- package/src/__tests__/system-prompt.test.ts +20 -0
- package/src/__tests__/task-scheduler.test.ts +162 -1
- package/src/__tests__/terminal-tools.test.ts +6 -1
- package/src/__tests__/title-generate-hook.test.ts +319 -0
- package/src/__tests__/tool-error-hook.test.ts +278 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +468 -5
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
- package/src/__tests__/tool-result-truncate-hook.test.ts +127 -0
- package/src/__tests__/tool-result-truncation.test.ts +0 -2
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +254 -0
- package/src/__tests__/ui-work-result-surface.test.ts +159 -0
- package/src/__tests__/usage-routes.test.ts +285 -1
- package/src/__tests__/user-plugin-loader.test.ts +2 -2
- package/src/__tests__/voice-session-bridge.test.ts +6 -3
- package/src/__tests__/web-search-backend-failure.test.ts +166 -0
- package/src/agent/loop.ts +346 -442
- package/src/api/events/assistant-thinking-delta.ts +33 -0
- package/src/api/events/tool-output-chunk.ts +45 -0
- package/src/api/events/tool-use-preview-start.ts +32 -0
- package/src/api/events/trace-event.ts +69 -0
- package/src/api/index.ts +48 -13
- package/src/api/responses/conversation-message.ts +368 -0
- package/src/avatar/__tests__/avatar-store.test.ts +34 -29
- package/src/cli/commands/__tests__/notifications.test.ts +58 -14
- package/src/cli/commands/notifications.ts +112 -60
- package/src/config/assistant-feature-flags.ts +22 -11
- package/src/config/bundled-skills/app-builder/SKILL.md +3 -20
- package/src/config/bundled-skills/app-builder/references/examples/README.md +17 -0
- package/src/config/bundled-skills/app-builder/references/examples/expense-tracker.md +515 -0
- package/src/config/bundled-skills/app-builder/references/examples/focus-timer.md +342 -0
- package/src/config/bundled-skills/app-builder/references/examples/habit-tracker.md +490 -0
- package/src/config/bundled-skills/document-editor/SKILL.md +1 -1
- package/src/config/bundled-skills/messaging/SKILL.md +0 -7
- package/src/config/feature-flag-cache.ts +3 -3
- package/src/config/feature-flag-registry.json +35 -3
- package/src/config/schemas/__tests__/memory-v2.test.ts +1 -0
- package/src/config/schemas/__tests__/memory-v3.test.ts +25 -0
- package/src/config/schemas/llm.ts +1 -0
- package/src/config/schemas/memory-v2.ts +8 -0
- package/src/config/schemas/memory-v3.ts +8 -0
- package/src/config/schemas/platform.ts +8 -0
- package/src/config/seed-inference-profiles.ts +2 -2
- package/src/config/skills.ts +13 -0
- package/src/context/compactor.ts +1 -1
- package/src/context/strip-injections.ts +122 -0
- package/src/context/token-estimator.ts +23 -0
- package/src/context/tool-result-truncation.ts +0 -23
- package/src/context/window-manager.ts +3 -6
- package/src/credential-execution/executable-discovery.ts +16 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +6 -0
- package/src/daemon/__tests__/inference-profile-notification.test.ts +153 -0
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +10 -8
- package/src/daemon/assistant-attachments.ts +1 -1
- package/src/daemon/config-watcher.ts +2 -2
- package/src/daemon/context-overflow-reducer.ts +0 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +605 -153
- package/src/daemon/conversation-agent-loop.ts +281 -760
- package/src/daemon/conversation-history.ts +5 -4
- package/src/daemon/conversation-lifecycle.ts +3 -4
- package/src/daemon/conversation-messaging.ts +7 -6
- package/src/daemon/conversation-process.ts +11 -16
- package/src/daemon/conversation-runtime-assembly.ts +130 -347
- package/src/daemon/conversation-slash.ts +6 -25
- package/src/daemon/conversation-surfaces.ts +222 -4
- package/src/daemon/conversation-tool-setup.ts +2 -29
- package/src/daemon/conversation.ts +32 -14
- package/src/daemon/external-plugins-bootstrap.ts +9 -10
- package/src/daemon/handlers/config-a2a.ts +51 -36
- package/src/daemon/handlers/config-slack-channel.ts +20 -14
- package/src/daemon/handlers/config-telegram.ts +16 -2
- package/src/daemon/handlers/shared.ts +156 -84
- package/src/daemon/handlers/skills.ts +39 -10
- package/src/daemon/lifecycle.ts +4 -0
- package/src/daemon/message-types/apps.ts +1 -29
- package/src/daemon/message-types/messages.ts +9 -57
- package/src/daemon/message-types/skills.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +136 -3
- package/src/daemon/now-scratchpad.ts +21 -0
- package/src/daemon/orphan-reaper.test.ts +210 -0
- package/src/daemon/orphan-reaper.ts +240 -0
- package/src/daemon/persist-unsendable-image.ts +117 -0
- package/src/daemon/process-message.ts +1 -3
- package/src/daemon/trace-emitter.ts +6 -4
- package/src/daemon/trust-context.ts +19 -0
- package/src/daemon/wake-target-adapter.ts +3 -1
- package/src/home/home-greeting-cache.ts +24 -1
- package/src/ipc/gateway-client.test.ts +2 -2
- package/src/ipc/gateway-client.ts +3 -3
- package/src/media/gemini-image-service.ts +15 -0
- package/src/media/openai-image-service.ts +14 -0
- package/src/media/types.ts +34 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +56 -0
- package/src/memory/auth-fallback-events-store.ts +94 -0
- package/src/memory/conversation-title-service.ts +65 -41
- package/src/memory/db-init.ts +4 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-registry.test.ts +119 -0
- package/src/memory/graph/conversation-graph-memory.ts +65 -0
- package/src/memory/jobs-store.ts +33 -0
- package/src/memory/jobs-worker.ts +31 -4
- package/src/memory/llm-usage-store.ts +224 -50
- package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +6 -5
- package/src/memory/migrations/270-schedule-source-conversation.ts +13 -0
- package/src/memory/migrations/271-create-auth-fallback-events.ts +21 -0
- package/src/memory/migrations/index.ts +2 -0
- package/src/memory/pkb/autoinject.ts +61 -0
- package/src/memory/pkb/context.ts +50 -0
- package/src/memory/pkb/types.ts +14 -0
- package/src/memory/schedule-attribution-sql.ts +104 -0
- package/src/memory/schema/infrastructure.ts +16 -0
- package/src/memory/usage-grouped-buckets.ts +6 -1
- package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -1
- package/src/memory/v2/consolidation-job.ts +1 -1
- package/src/memory/v3/__tests__/health.test.ts +16 -0
- package/src/memory/v3/__tests__/orchestrate.test.ts +45 -9
- package/src/memory/v3/__tests__/provider-blocks.test.ts +13 -0
- package/src/memory/v3/__tests__/router.test.ts +101 -29
- package/src/memory/v3/__tests__/selector.test.ts +93 -27
- package/src/memory/v3/__tests__/shadow-plugin.test.ts +23 -5
- package/src/memory/v3/health.ts +0 -0
- package/src/memory/v3/llm-retry.ts +32 -0
- package/src/memory/v3/orchestrate.ts +26 -14
- package/src/memory/v3/provider-blocks.ts +15 -5
- package/src/memory/v3/router.ts +48 -42
- package/src/memory/v3/selector.ts +57 -42
- package/src/memory/v3/shadow-plugin.ts +47 -15
- package/src/memory/v3/types.ts +8 -0
- package/src/notifications/conversation-pairing.ts +8 -15
- package/src/notifications/decision-engine.ts +6 -3
- package/src/notifications/home-feed-side-effect.ts +12 -1
- package/src/permissions/prompter.ts +4 -0
- package/src/plugin-api/constants.ts +4 -0
- package/src/plugin-api/index.ts +8 -1
- package/src/plugin-api/types.ts +151 -1
- package/src/plugins/defaults/empty-response/hooks/stop.ts +126 -0
- package/src/plugins/defaults/empty-response/register.ts +8 -13
- package/src/plugins/defaults/index.ts +1 -15
- package/src/plugins/defaults/injectors/register.ts +243 -74
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +91 -0
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +216 -0
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +35 -0
- package/src/plugins/defaults/title-generate/hooks/stop.ts +75 -0
- package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +35 -0
- package/src/plugins/defaults/title-generate/package.json +1 -1
- package/src/plugins/defaults/title-generate/register.ts +18 -18
- package/src/plugins/defaults/tool-error/hooks/post-tool-use.ts +118 -0
- package/src/plugins/defaults/tool-error/package.json +1 -1
- package/src/plugins/defaults/tool-error/register.ts +9 -21
- package/src/plugins/defaults/tool-result-truncate/hooks/post-tool-use.ts +32 -0
- package/src/plugins/defaults/tool-result-truncate/register.ts +10 -21
- package/src/plugins/defaults/tool-result-truncate/terminal.ts +37 -18
- package/src/plugins/pipeline.ts +6 -18
- package/src/plugins/registry.ts +8 -25
- package/src/plugins/types.ts +43 -474
- package/src/proactive-artifact/aux-message-injector.ts +3 -3
- package/src/proactive-artifact/job.test.ts +7 -12
- package/src/prompts/__tests__/system-prompt.test.ts +36 -0
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +62 -0
- package/src/prompts/templates/BOOTSTRAP.md +2 -2
- package/src/prompts/templates/system-sections.ts +15 -0
- package/src/providers/anthropic/client.ts +37 -29
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +112 -0
- package/src/providers/openai/chat-completions-provider.ts +44 -0
- package/src/providers/openrouter/client.ts +1 -0
- package/src/providers/placeholder-sentinels.ts +35 -0
- package/src/runtime/__tests__/agent-wake.test.ts +5 -1
- package/src/runtime/agent-wake.ts +2 -2
- package/src/runtime/assistant-event-hub.ts +36 -6
- package/src/runtime/{conversation-stream-state.ts → assistant-stream-state.ts} +132 -58
- package/src/runtime/http-router.ts +16 -21
- package/src/runtime/http-types.ts +16 -70
- package/src/runtime/pending-interactions.ts +1 -0
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +265 -2
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +31 -1
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +6 -2
- package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
- package/src/runtime/routes/app-management-routes.ts +6 -117
- package/src/runtime/routes/app-routes.ts +13 -15
- package/src/runtime/routes/attachment-routes.ts +26 -15
- package/src/runtime/routes/avatar-routes.ts +26 -0
- package/src/runtime/routes/btw-routes.ts +29 -23
- package/src/runtime/routes/consolidation-routes.ts +120 -20
- package/src/runtime/routes/conversation-query-routes.ts +2 -0
- package/src/runtime/routes/conversation-routes.ts +358 -184
- package/src/runtime/routes/documents-routes.ts +4 -0
- package/src/runtime/routes/domain-routes.ts +51 -37
- package/src/runtime/routes/epoch-millis-range.ts +34 -0
- package/src/runtime/routes/events-routes.ts +28 -34
- package/src/runtime/routes/gateway-log-routes.ts +26 -4
- package/src/runtime/routes/heartbeat-routes.ts +32 -12
- package/src/runtime/routes/identity-intro-cache.ts +11 -34
- package/src/runtime/routes/identity-routes.ts +208 -17
- package/src/runtime/routes/image-generation-routes.ts +40 -2
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/integrations/a2a.ts +12 -10
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +16 -0
- package/src/runtime/routes/integrations/slack/channel.ts +4 -0
- package/src/runtime/routes/integrations/slack/share.ts +27 -6
- package/src/runtime/routes/integrations/telegram.ts +6 -0
- package/src/runtime/routes/integrations/twilio.ts +42 -0
- package/src/runtime/routes/internal-telemetry-routes.ts +88 -0
- package/src/runtime/routes/log-export-routes.ts +8 -0
- package/src/runtime/routes/memory-v2-routes.ts +15 -8
- package/src/runtime/routes/memory-v3-routes.ts +50 -28
- package/src/runtime/routes/oauth-apps.ts +66 -12
- package/src/runtime/routes/oauth-providers.ts +44 -5
- package/src/runtime/routes/platform-routes.ts +81 -5
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +6 -4
- package/src/runtime/routes/playground/force-compact.ts +1 -1
- package/src/runtime/routes/rename-conversation-routes.ts +5 -0
- package/src/runtime/routes/schedule-routes.ts +152 -42
- package/src/runtime/routes/secret-routes.ts +14 -2
- package/src/runtime/routes/skills-routes.ts +43 -14
- package/src/runtime/routes/tool-call-confirmation-enrichment.test.ts +161 -0
- package/src/runtime/routes/tool-call-confirmation-enrichment.ts +107 -0
- package/src/runtime/routes/trust-rules-routes.ts +26 -2
- package/src/runtime/routes/tts-routes.ts +35 -0
- package/src/runtime/routes/types.ts +66 -8
- package/src/runtime/routes/usage-routes.ts +47 -39
- package/src/runtime/routes/webhook-routes.ts +41 -2
- package/src/runtime/routes/workspace-routes.ts +4 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +6 -0
- package/src/runtime/services/analyze-conversation.ts +2 -2
- package/src/schedule/schedule-store.ts +20 -1
- package/src/schedule/schedule-usage-store.ts +83 -0
- package/src/schedule/scheduler.ts +12 -5
- package/src/skills/catalog-files.ts +2 -2
- package/src/skills/catalog-install.ts +3 -0
- package/src/skills/categories-cache.ts +118 -0
- package/src/skills/clawhub-files.ts +1 -2
- package/src/skills/skillssh-files.ts +1 -2
- package/src/telemetry/types.ts +29 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +112 -3
- package/src/telemetry/usage-telemetry-reporter.ts +57 -2
- package/src/tools/executor.ts +1 -53
- package/src/tools/network/__tests__/web-search-metadata.test.ts +7 -1
- package/src/tools/network/__tests__/web-search.test.ts +11 -3
- package/src/tools/network/web-search-error.test.ts +248 -0
- package/src/tools/network/web-search-error.ts +267 -0
- package/src/tools/network/web-search.ts +207 -48
- package/src/tools/schedule/create.ts +2 -0
- package/src/tools/terminal/safe-env.ts +10 -1
- package/src/tools/ui-surface/definitions.ts +9 -1
- package/src/tts/__tests__/provider-catalog-consistency.test.ts +85 -1
- package/src/tts/provider-catalog.ts +76 -1
- package/src/util/mutex.ts +47 -0
- package/src/workspace/git-service.ts +1 -42
- package/src/workspace/migrations/095-bump-heartbeat-interval-30m-to-60m.ts +51 -0
- package/src/workspace/migrations/096-reduce-quality-profile-effort.ts +72 -0
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +93 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/__tests__/bootstrap-turn-cleanup.test.ts +0 -44
- package/src/__tests__/empty-response-pipeline.test.ts +0 -423
- package/src/__tests__/llm-call-pipeline.test.ts +0 -287
- package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -418
- package/src/__tests__/persistence-pipeline.test.ts +0 -503
- package/src/__tests__/title-generate-pipeline.test.ts +0 -211
- package/src/__tests__/token-estimate-pipeline.test.ts +0 -479
- package/src/__tests__/tool-error-pipeline.test.ts +0 -241
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -417
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -341
- package/src/daemon/bootstrap-turn-cleanup.ts +0 -45
- package/src/gallery/default-gallery.ts +0 -1359
- package/src/gallery/gallery-manifest.ts +0 -28
- package/src/home/feature-gate.ts +0 -22
- package/src/plugins/defaults/empty-response/middlewares/emptyResponse.ts +0 -22
- package/src/plugins/defaults/empty-response/terminal.ts +0 -106
- package/src/plugins/defaults/injectors/package.json +0 -15
- package/src/plugins/defaults/llm-call/middlewares/llmCall.ts +0 -17
- package/src/plugins/defaults/llm-call/package.json +0 -15
- package/src/plugins/defaults/llm-call/register.ts +0 -45
- package/src/plugins/defaults/memory-retrieval/middlewares/memoryRetrieval.ts +0 -17
- package/src/plugins/defaults/memory-retrieval/package.json +0 -15
- package/src/plugins/defaults/memory-retrieval/register.ts +0 -181
- package/src/plugins/defaults/persistence/middlewares/persistence.ts +0 -19
- package/src/plugins/defaults/persistence/package.json +0 -15
- package/src/plugins/defaults/persistence/register.ts +0 -38
- package/src/plugins/defaults/persistence/terminal.ts +0 -83
- package/src/plugins/defaults/title-generate/terminal.ts +0 -31
- package/src/plugins/defaults/token-estimate/middlewares/tokenEstimate.ts +0 -23
- package/src/plugins/defaults/token-estimate/package.json +0 -15
- package/src/plugins/defaults/token-estimate/register.ts +0 -34
- package/src/plugins/defaults/token-estimate/terminal.ts +0 -40
- package/src/plugins/defaults/tool-error/middlewares/toolError.ts +0 -21
- package/src/plugins/defaults/tool-error/terminal.ts +0 -47
- package/src/plugins/defaults/tool-execute/middlewares/toolExecute.ts +0 -23
- package/src/plugins/defaults/tool-execute/package.json +0 -15
- package/src/plugins/defaults/tool-execute/register.ts +0 -49
- package/src/plugins/defaults/tool-result-truncate/middlewares/toolResultTruncate.ts +0 -23
- package/src/plugins/defaults/tool-result-truncate/types.ts +0 -22
- package/src/skills/category-inference.ts +0 -111
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
export interface GalleryManifest {
|
|
2
|
-
version: number;
|
|
3
|
-
updatedAt: string;
|
|
4
|
-
categories: GalleryCategory[];
|
|
5
|
-
apps: GalleryApp[];
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export interface GalleryCategory {
|
|
9
|
-
id: string; // e.g. "productivity", "health", "fun"
|
|
10
|
-
name: string; // Display name
|
|
11
|
-
icon: string; // Emoji
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface GalleryApp {
|
|
15
|
-
id: string; // Unique identifier
|
|
16
|
-
name: string;
|
|
17
|
-
description: string;
|
|
18
|
-
icon: string; // Emoji
|
|
19
|
-
category: string; // Category ID
|
|
20
|
-
version: string; // e.g. "1.0.0"
|
|
21
|
-
featured?: boolean;
|
|
22
|
-
schemaJson: string; // JSON schema for app records
|
|
23
|
-
htmlDefinition: string; // Complete HTML app (also serves as compiled fallback)
|
|
24
|
-
/** 2 = multi-file TSX format with sourceFiles */
|
|
25
|
-
formatVersion?: number;
|
|
26
|
-
/** Maps relative path to file content, e.g. { "src/main.tsx": "...", "src/index.html": "..." } */
|
|
27
|
-
sourceFiles?: Record<string, string>;
|
|
28
|
-
}
|
package/src/home/feature-gate.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
|
|
2
|
-
import type { AssistantConfig } from "../config/schema.js";
|
|
3
|
-
|
|
4
|
-
const HOME_PAGE_FLAG_KEY = "home-page" as const;
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Whether the home page / home feed surface is enabled for this install.
|
|
8
|
-
*
|
|
9
|
-
* `home-page` is a `"both"`-scope flag: the client renders the home feed as the
|
|
10
|
-
* landing view, and the notification pipeline uses it to decide whether passive
|
|
11
|
-
* notifications have a home-feed surface to land on (when off, they fall back to
|
|
12
|
-
* materializing a conversation instead of being suppressed).
|
|
13
|
-
*
|
|
14
|
-
* `config` is accepted for parity with the other gate modules but is unused —
|
|
15
|
-
* the value resolves from the gateway override cache / registry default.
|
|
16
|
-
*/
|
|
17
|
-
export function isHomePageEnabled(config?: AssistantConfig): boolean {
|
|
18
|
-
return isAssistantFeatureFlagEnabled(
|
|
19
|
-
HOME_PAGE_FLAG_KEY,
|
|
20
|
-
(config ?? {}) as AssistantConfig,
|
|
21
|
-
);
|
|
22
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
EmptyResponseArgs,
|
|
3
|
-
EmptyResponseResult,
|
|
4
|
-
Middleware,
|
|
5
|
-
} from "../../../types.js";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Passthrough middleware for the `emptyResponse` pipeline. Forwards to
|
|
9
|
-
* `next(args)` unchanged; the actual empty-response decision lives in the
|
|
10
|
-
* terminal handler (`../terminal.ts`), wired in at the `runPipeline` call site
|
|
11
|
-
* in `agent/loop.ts`.
|
|
12
|
-
*
|
|
13
|
-
* Defaults register at the OUTERMOST onion position, so deciding here without
|
|
14
|
-
* calling `next` would shadow every later-registered plugin. Routing through
|
|
15
|
-
* `next(args)` lets user middleware participate normally.
|
|
16
|
-
*/
|
|
17
|
-
const passthrough: Middleware<EmptyResponseArgs, EmptyResponseResult> = async (
|
|
18
|
-
args,
|
|
19
|
-
next,
|
|
20
|
-
) => next(args);
|
|
21
|
-
|
|
22
|
-
export default passthrough;
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Default `emptyResponse` behavior: decides whether an empty assistant turn
|
|
3
|
-
* should be nudged (re-queried) or accepted.
|
|
4
|
-
*
|
|
5
|
-
* This module is side-effect free: importing it does not register any plugin.
|
|
6
|
-
*
|
|
7
|
-
* The handler inspects the turn snapshot and returns one of:
|
|
8
|
-
*
|
|
9
|
-
* 1. `"nudge"` — fired in two distinct shapes:
|
|
10
|
-
* (a) **Post-tool empty.** The turn produced no visible text,
|
|
11
|
-
* no tool calls, follows at least one prior tool-use turn,
|
|
12
|
-
* no earlier turn in this run() has already delivered
|
|
13
|
-
* visible text, AND the retry counter is below
|
|
14
|
-
* `maxEmptyResponseRetries`. Uses `NUDGE_TEXT`.
|
|
15
|
-
* (b) **Refusal stop.** The provider returned
|
|
16
|
-
* `stopReason === "refusal"` with no visible text and no
|
|
17
|
-
* tool calls (Anthropic's safety classifier). Nudges even
|
|
18
|
-
* on turn 0 / before any tool use, because a refusal on
|
|
19
|
-
* the first model call of the run is a hard guarantee
|
|
20
|
-
* that no organic text exists yet — without intervening
|
|
21
|
-
* we'd persist an empty assistant bubble to the user.
|
|
22
|
-
* Uses the refusal-specific `REFUSAL_NUDGE_TEXT`. The
|
|
23
|
-
* retry cap still applies; after `maxEmptyResponseRetries`
|
|
24
|
-
* refusals in a row the terminal falls through to accept.
|
|
25
|
-
* The loop appends the chosen `nudgeText` as a `user` turn
|
|
26
|
-
* and re-queries the model.
|
|
27
|
-
* 2. `"accept"` — every other case. The turn either legitimately ended
|
|
28
|
-
* (model said its piece earlier), is still in progress
|
|
29
|
-
* (tool calls pending), or exhausted its retry budget. The
|
|
30
|
-
* loop pushes the assistant message and continues normally.
|
|
31
|
-
*
|
|
32
|
-
* The default never returns `"error"` — that action is an escape hatch for
|
|
33
|
-
* downstream plugins (e.g. a circuit breaker) that want to surface an
|
|
34
|
-
* explicit error instead of silently absorbing an empty turn.
|
|
35
|
-
*
|
|
36
|
-
* `MAX_EMPTY_RESPONSE_RETRIES` lives in `agent/loop.ts` and is passed in via
|
|
37
|
-
* `EmptyResponseArgs.maxEmptyResponseRetries` so the cap is declared in one
|
|
38
|
-
* place only.
|
|
39
|
-
*/
|
|
40
|
-
|
|
41
|
-
import type { EmptyResponseArgs, EmptyResponseResult } from "../../types.js";
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Canonical nudge text. Must stay verbatim so a plugin that wraps the
|
|
45
|
-
* default cannot accidentally see a different string.
|
|
46
|
-
*
|
|
47
|
-
* Wire-compat note: this is shown to the LLM, not the user. Edits here
|
|
48
|
-
* affect model behavior but not end-user UX directly.
|
|
49
|
-
*/
|
|
50
|
-
const NUDGE_TEXT =
|
|
51
|
-
"<system_notice>Your previous response was empty. You must respond to the user with a summary of what you found or did. Do not use any tools — just respond with text.</system_notice>";
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Refusal-specific nudge. Used when the provider stops with `"refusal"`
|
|
55
|
-
* before any tool use — i.e. the safety classifier zeroed the response.
|
|
56
|
-
* Kept distinct from `NUDGE_TEXT` so the model gets context-appropriate
|
|
57
|
-
* guidance (no "summary of what you found or did" — there is no tool
|
|
58
|
-
* trail to summarize on a turn-0 refusal).
|
|
59
|
-
*
|
|
60
|
-
* Wire-compat note: this is shown to the LLM, not the user. Edits here
|
|
61
|
-
* affect retry behavior but not end-user UX directly.
|
|
62
|
-
*/
|
|
63
|
-
export const REFUSAL_NUDGE_TEXT =
|
|
64
|
-
'<system_notice>Your previous response was empty because the upstream provider returned stop_reason="refusal". Please answer the user\'s last message directly with a plain-text response. Do not use any tools — just respond with text.</system_notice>';
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Decide whether an empty turn should be nudged or accepted. Exported so the
|
|
68
|
-
* agent loop can call it directly and tests can verify the decision logic.
|
|
69
|
-
*/
|
|
70
|
-
export function defaultEmptyResponseTerminal(
|
|
71
|
-
args: EmptyResponseArgs,
|
|
72
|
-
): EmptyResponseResult {
|
|
73
|
-
const hasVisibleText = args.responseContent.some(
|
|
74
|
-
(block) =>
|
|
75
|
-
block.type === "text" &&
|
|
76
|
-
typeof (block as { text?: unknown }).text === "string" &&
|
|
77
|
-
(block as { text: string }).text.trim().length > 0,
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
// Refusal stop with zero usable content — the provider's safety
|
|
81
|
-
// classifier zeroed the response. Nudge regardless of toolUseTurns or
|
|
82
|
-
// priorAssistantHadVisibleText: a `"refusal"` stop with no visible
|
|
83
|
-
// text and no tool calls IS the failure mode this branch exists to
|
|
84
|
-
// catch (otherwise we persist an empty assistant bubble to the user).
|
|
85
|
-
// Still respect the retry cap so a persistent classifier doesn't
|
|
86
|
-
// burn turns indefinitely.
|
|
87
|
-
const isRefusal =
|
|
88
|
-
args.stopReason === "refusal" &&
|
|
89
|
-
!hasVisibleText &&
|
|
90
|
-
args.toolUseBlocksLength === 0;
|
|
91
|
-
|
|
92
|
-
if (isRefusal && args.emptyResponseRetries < args.maxEmptyResponseRetries) {
|
|
93
|
-
return { action: "nudge", nudgeText: REFUSAL_NUDGE_TEXT };
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const isEmptyTurn =
|
|
97
|
-
!hasVisibleText &&
|
|
98
|
-
args.toolUseBlocksLength === 0 &&
|
|
99
|
-
args.toolUseTurns > 0 &&
|
|
100
|
-
!args.priorAssistantHadVisibleText;
|
|
101
|
-
|
|
102
|
-
if (isEmptyTurn && args.emptyResponseRetries < args.maxEmptyResponseRetries) {
|
|
103
|
-
return { action: "nudge", nudgeText: NUDGE_TEXT };
|
|
104
|
-
}
|
|
105
|
-
return { action: "accept" };
|
|
106
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "default-injectors",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"description": "First-party default plugin wrapping the assistant's built-in injectors pipeline with a passthrough implementation.",
|
|
5
|
-
"private": true,
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"type": "module",
|
|
8
|
-
"main": "./register.ts",
|
|
9
|
-
"engines": {
|
|
10
|
-
"node": ">=20.12.0"
|
|
11
|
-
},
|
|
12
|
-
"peerDependencies": {
|
|
13
|
-
"@vellumai/plugin-api": "^0.8.0"
|
|
14
|
-
}
|
|
15
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { LLMCallArgs, LLMCallResult, Middleware } from "../../../types.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Passthrough middleware for the `llmCall` pipeline. Forwards to `next(args)`
|
|
5
|
-
* unchanged so any user-registered middleware (registered later, inner in the
|
|
6
|
-
* onion) still runs and the terminal at the call site (`agent/loop.ts`)
|
|
7
|
-
* performs the actual `provider.sendMessage(...)` call.
|
|
8
|
-
*
|
|
9
|
-
* Defaults register at the OUTERMOST onion position; forwarding
|
|
10
|
-
* unconditionally keeps user-registered middleware reachable.
|
|
11
|
-
*/
|
|
12
|
-
const defaultLlmCall: Middleware<LLMCallArgs, LLMCallResult> =
|
|
13
|
-
async function defaultLlmCall(args, next, _ctx) {
|
|
14
|
-
return next(args);
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export default defaultLlmCall;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "default-llm-call",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"description": "First-party default plugin wrapping the assistant's built-in llm-call pipeline with a passthrough implementation.",
|
|
5
|
-
"private": true,
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"type": "module",
|
|
8
|
-
"main": "./register.ts",
|
|
9
|
-
"engines": {
|
|
10
|
-
"node": ">=20.12.0"
|
|
11
|
-
},
|
|
12
|
-
"peerDependencies": {
|
|
13
|
-
"@vellumai/plugin-api": "^0.8.0"
|
|
14
|
-
}
|
|
15
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Default `llmCall` plugin — a passthrough that declares the pipeline
|
|
3
|
-
* surface and yields to downstream middleware.
|
|
4
|
-
*
|
|
5
|
-
* The plugin system wraps every LLM request in the `llmCall` pipeline. The
|
|
6
|
-
* actual call to {@link Provider.sendMessage} lives in the `runPipeline`
|
|
7
|
-
* terminal at the call site (`agent/loop.ts`); this default's only job is to
|
|
8
|
-
* contribute the manifest (`provides.llmCall: "v1"`) so other plugins can
|
|
9
|
-
* negotiate against the pipeline surface.
|
|
10
|
-
*
|
|
11
|
-
* This plugin registers at module load — before user plugins are loaded by
|
|
12
|
-
* `bootstrapPlugins()` — so it sits at the outermost layer in
|
|
13
|
-
* `composeMiddleware`'s onion ordering. To keep user-registered middleware
|
|
14
|
-
* reachable, the middleware forwards unconditionally via `next(args)`.
|
|
15
|
-
*
|
|
16
|
-
* Registered from `daemon/external-plugins-bootstrap.ts` via a side-effect
|
|
17
|
-
* import so the plugin is present in the registry before
|
|
18
|
-
* {@link bootstrapPlugins} walks it.
|
|
19
|
-
*
|
|
20
|
-
* Design doc: `.private/plans/agent-plugin-system.md` (PR 15).
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
import { type Plugin } from "../../types.js";
|
|
24
|
-
import llmCall from "./middlewares/llmCall.js";
|
|
25
|
-
import pkg from "./package.json" with { type: "json" };
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* The default LLM-call plugin. Its `llmCall` middleware is a passthrough that
|
|
29
|
-
* forwards to `next(args)` unchanged so any user-registered middleware
|
|
30
|
-
* (registered later, inner in the onion) still runs and the terminal at the
|
|
31
|
-
* call site performs the actual `provider.sendMessage(...)` call.
|
|
32
|
-
*
|
|
33
|
-
* Manifest declares `provides.llmCall: "v1"` so other plugins can negotiate
|
|
34
|
-
* against the pipeline surface and `requires.pluginRuntime: "v1"` to satisfy
|
|
35
|
-
* the registry's mandatory capability check.
|
|
36
|
-
*/
|
|
37
|
-
export const defaultLlmCallPlugin: Plugin = {
|
|
38
|
-
manifest: {
|
|
39
|
-
name: pkg.name,
|
|
40
|
-
version: pkg.version,
|
|
41
|
-
},
|
|
42
|
-
middleware: {
|
|
43
|
-
llmCall,
|
|
44
|
-
},
|
|
45
|
-
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { MemoryArgs, MemoryResult, Middleware } from "../../../types.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Passthrough middleware for the `memoryRetrieval` pipeline.
|
|
5
|
-
*
|
|
6
|
-
* Keeping a real middleware registered (rather than an empty list) makes the
|
|
7
|
-
* pipeline observable in `plugin.pipeline` logs with a non-empty `chain` field
|
|
8
|
-
* and lets third-party plugins rely on the default slot being present even
|
|
9
|
-
* when nothing is overriding it. The work happens in the terminal supplied by
|
|
10
|
-
* the agent loop, which calls `runDefaultMemoryRetrieval`.
|
|
11
|
-
*/
|
|
12
|
-
const defaultMemoryRetrievalMiddleware: Middleware<MemoryArgs, MemoryResult> =
|
|
13
|
-
async function defaultMemoryRetrieval(args, next) {
|
|
14
|
-
return next(args);
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export default defaultMemoryRetrievalMiddleware;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "default-memory-retrieval",
|
|
3
|
-
"version": "0.0.1",
|
|
4
|
-
"description": "First-party default plugin wrapping the assistant's built-in memory-retrieval pipeline with a passthrough implementation.",
|
|
5
|
-
"private": true,
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"type": "module",
|
|
8
|
-
"main": "./register.ts",
|
|
9
|
-
"engines": {
|
|
10
|
-
"node": ">=20.12.0"
|
|
11
|
-
},
|
|
12
|
-
"peerDependencies": {
|
|
13
|
-
"@vellumai/plugin-api": "^0.8.0"
|
|
14
|
-
}
|
|
15
|
-
}
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Default `memoryRetrieval` plugin.
|
|
3
|
-
*
|
|
4
|
-
* Encapsulates the three retrievals the agent loop performs before building
|
|
5
|
-
* the runtime-injection block for a turn:
|
|
6
|
-
*
|
|
7
|
-
* 1. **PKB context** via {@link readPkbContext} — always-loaded workspace
|
|
8
|
-
* notes (INDEX.md, essentials.md, …) that precede the user's message.
|
|
9
|
-
* 2. **NOW.md scratchpad** via {@link readNowScratchpad} — the short
|
|
10
|
-
* user-maintained note the assistant keeps up to date.
|
|
11
|
-
* 3. **Memory graph** via {@link ConversationGraphMemory.prepareMemory} —
|
|
12
|
-
* dispatches to context-load or per-turn retrieval depending on
|
|
13
|
-
* initialization state; gated on the actor being trusted (guardian).
|
|
14
|
-
*
|
|
15
|
-
* The default plugin registers a pass-through middleware so the pipeline
|
|
16
|
-
* runner always has at least one entry and downstream telemetry observes a
|
|
17
|
-
* deterministic chain. The actual retrieval runs in the terminal supplied
|
|
18
|
-
* by the agent loop; centralizing the helper here (as
|
|
19
|
-
* {@link runDefaultMemoryRetrieval}) makes it trivial for a plugin to
|
|
20
|
-
* fall back to the default behavior by calling this helper from its own
|
|
21
|
-
* middleware.
|
|
22
|
-
*
|
|
23
|
-
* See `.private/plans/agent-plugin-system.md` PR 20 for the containing
|
|
24
|
-
* milestone.
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
import type { AssistantConfig } from "../../../config/schema.js";
|
|
28
|
-
import {
|
|
29
|
-
readNowScratchpad,
|
|
30
|
-
readPkbContext,
|
|
31
|
-
} from "../../../daemon/conversation-runtime-assembly.js";
|
|
32
|
-
import type { ServerMessage } from "../../../daemon/message-protocol.js";
|
|
33
|
-
import type { ConversationGraphMemory } from "../../../memory/graph/conversation-graph-memory.js";
|
|
34
|
-
import type { Message } from "../../../providers/types.js";
|
|
35
|
-
import {
|
|
36
|
-
type MemoryArgs,
|
|
37
|
-
type MemoryResult,
|
|
38
|
-
type Plugin,
|
|
39
|
-
} from "../../types.js";
|
|
40
|
-
import defaultMemoryRetrievalMiddleware from "./middlewares/memoryRetrieval.js";
|
|
41
|
-
import pkg from "./package.json" with { type: "json" };
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Discriminator the agent loop uses to narrow `MemoryResult.memoryGraphBlocks`
|
|
45
|
-
* back into the full {@link GraphMemoryPayload} shape. Plugins that substitute
|
|
46
|
-
* their own memory blocks without setting this marker will fall through the
|
|
47
|
-
* agent loop's graph-result consumption path — which is the intended escape
|
|
48
|
-
* hatch for custom retrievers.
|
|
49
|
-
*/
|
|
50
|
-
export const DEFAULT_MEMORY_GRAPH_KIND = "default.graph" as const;
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Shape of the single block the default memory-graph retriever emits.
|
|
54
|
-
*
|
|
55
|
-
* Mirrors the object returned by
|
|
56
|
-
* {@link ConversationGraphMemory.prepareMemory} — the agent loop consumes
|
|
57
|
-
* every field downstream (PKB query vectors, metrics persistence, memory
|
|
58
|
-
* event emission). Kept as a concrete type here so both the terminal and the
|
|
59
|
-
* agent loop can share one import.
|
|
60
|
-
*/
|
|
61
|
-
export interface GraphMemoryPayload {
|
|
62
|
-
readonly kind: typeof DEFAULT_MEMORY_GRAPH_KIND;
|
|
63
|
-
readonly result: Awaited<
|
|
64
|
-
ReturnType<ConversationGraphMemory["prepareMemory"]>
|
|
65
|
-
>;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* External state the default retriever needs but the pipeline args cannot
|
|
70
|
-
* carry (conversation-scoped graph handle, event sink, live message list).
|
|
71
|
-
* Passed as a second argument to {@link runDefaultMemoryRetrieval} rather
|
|
72
|
-
* than threaded through {@link MemoryArgs} to keep the plugin-facing
|
|
73
|
-
* pipeline surface minimal.
|
|
74
|
-
*/
|
|
75
|
-
export interface DefaultMemoryRetrievalDeps {
|
|
76
|
-
/** Live message list for this turn (pre-injection). */
|
|
77
|
-
readonly messages: Message[];
|
|
78
|
-
/** Per-conversation memory graph handle. */
|
|
79
|
-
readonly graphMemory: ConversationGraphMemory;
|
|
80
|
-
/** Assistant config snapshot. */
|
|
81
|
-
readonly config: AssistantConfig;
|
|
82
|
-
/** Event sink used by the graph retriever (memory_status events). */
|
|
83
|
-
readonly onEvent: (msg: ServerMessage) => void;
|
|
84
|
-
/** True when the actor for this turn is trusted (guardian-class). */
|
|
85
|
-
readonly isTrustedActor: boolean;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Run the default retrieval. Always returns a {@link MemoryResult}; skips
|
|
90
|
-
* the memory-graph call entirely when the actor is not trusted (matches the
|
|
91
|
-
* prior agent-loop gate).
|
|
92
|
-
*
|
|
93
|
-
* The returned `memoryGraphBlocks` is either empty (when the actor is not
|
|
94
|
-
* trusted) or a single {@link GraphMemoryPayload} wrapping the graph
|
|
95
|
-
* retriever's full output. The agent loop narrows via
|
|
96
|
-
* {@link DEFAULT_MEMORY_GRAPH_KIND} to consume it.
|
|
97
|
-
*
|
|
98
|
-
* Memory retrieval blocks the turn — there is no soft timeout here. Memory
|
|
99
|
-
* is critical context, and silently dropping it produces a worse outcome
|
|
100
|
-
* than a slower turn. Cancellation still works via `args.signal`, which is
|
|
101
|
-
* threaded into `prepareMemory`.
|
|
102
|
-
*/
|
|
103
|
-
export async function runDefaultMemoryRetrieval(
|
|
104
|
-
args: MemoryArgs,
|
|
105
|
-
deps: DefaultMemoryRetrievalDeps,
|
|
106
|
-
): Promise<MemoryResult> {
|
|
107
|
-
// NOW.md and PKB are read unconditionally — the agent loop decides
|
|
108
|
-
// whether to inject them based on first-turn / post-compaction gating.
|
|
109
|
-
const pkbContent = readPkbContext();
|
|
110
|
-
const nowContent = readNowScratchpad();
|
|
111
|
-
|
|
112
|
-
if (!deps.isTrustedActor) {
|
|
113
|
-
// Untrusted actors skip memory-graph retrieval entirely — preserves the
|
|
114
|
-
// pre-plugin gate that lived inline in `conversation-agent-loop.ts`.
|
|
115
|
-
return {
|
|
116
|
-
pkbContent,
|
|
117
|
-
nowContent,
|
|
118
|
-
memoryGraphBlocks: [],
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const graphResult = await deps.graphMemory.prepareMemory(
|
|
123
|
-
deps.messages,
|
|
124
|
-
deps.config,
|
|
125
|
-
args.signal,
|
|
126
|
-
deps.onEvent,
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
const payload: GraphMemoryPayload = {
|
|
130
|
-
kind: DEFAULT_MEMORY_GRAPH_KIND,
|
|
131
|
-
result: graphResult,
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
return {
|
|
135
|
-
pkbContent,
|
|
136
|
-
nowContent,
|
|
137
|
-
memoryGraphBlocks: [payload],
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Narrow a {@link MemoryResult} memory-graph block back into the full
|
|
143
|
-
* {@link GraphMemoryPayload} the default retriever emits. Returns `null` when
|
|
144
|
-
* the pipeline output came from a custom retriever (no blocks, or a block
|
|
145
|
-
* without the {@link DEFAULT_MEMORY_GRAPH_KIND} discriminator).
|
|
146
|
-
*
|
|
147
|
-
* The agent loop uses this helper to decide whether to run its downstream
|
|
148
|
-
* graph-result consumption path (query-vector propagation, metric
|
|
149
|
-
* persistence, memory-event emission). Custom retrievers that skip that
|
|
150
|
-
* path are expected to handle their own side effects inside their
|
|
151
|
-
* middleware.
|
|
152
|
-
*/
|
|
153
|
-
export function asDefaultGraphPayload(
|
|
154
|
-
blocks: ReadonlyArray<unknown>,
|
|
155
|
-
): GraphMemoryPayload | null {
|
|
156
|
-
const first = blocks[0];
|
|
157
|
-
if (
|
|
158
|
-
first != null &&
|
|
159
|
-
typeof first === "object" &&
|
|
160
|
-
"kind" in first &&
|
|
161
|
-
(first as { kind?: unknown }).kind === DEFAULT_MEMORY_GRAPH_KIND
|
|
162
|
-
) {
|
|
163
|
-
return first as GraphMemoryPayload;
|
|
164
|
-
}
|
|
165
|
-
return null;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Default plugin exposing the `memoryRetrieval` pipeline slot. Registered
|
|
170
|
-
* by {@link registerDefaultMemoryRetrievalPlugin} from the plugin
|
|
171
|
-
* bootstrap wiring so ordering is deterministic across boots.
|
|
172
|
-
*/
|
|
173
|
-
export const defaultMemoryRetrievalPlugin: Plugin = {
|
|
174
|
-
manifest: {
|
|
175
|
-
name: pkg.name,
|
|
176
|
-
version: pkg.version,
|
|
177
|
-
},
|
|
178
|
-
middleware: {
|
|
179
|
-
memoryRetrieval: defaultMemoryRetrievalMiddleware,
|
|
180
|
-
},
|
|
181
|
-
};
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { Middleware, PersistArgs, PersistResult } from "../../../types.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Passthrough middleware for the `persistence` pipeline. Forwards to
|
|
5
|
-
* `next(args)` unchanged; the actual dispatch lives in the terminal handler
|
|
6
|
-
* (`../terminal.ts`), wired in at the `runPipeline` call sites in
|
|
7
|
-
* `daemon/conversation-agent-loop.ts` and
|
|
8
|
-
* `daemon/conversation-agent-loop-handlers.ts`.
|
|
9
|
-
*
|
|
10
|
-
* Defaults register at the OUTERMOST onion position, so deciding here without
|
|
11
|
-
* calling `next` would shadow every later-registered plugin. Routing through
|
|
12
|
-
* `next(args)` lets user middleware participate normally.
|
|
13
|
-
*/
|
|
14
|
-
const passthrough: Middleware<PersistArgs, PersistResult> = async (
|
|
15
|
-
args,
|
|
16
|
-
next,
|
|
17
|
-
) => next(args);
|
|
18
|
-
|
|
19
|
-
export default passthrough;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "default-persistence",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"description": "First-party default plugin wrapping the assistant's built-in persistence pipeline with a passthrough implementation.",
|
|
5
|
-
"private": true,
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"type": "module",
|
|
8
|
-
"main": "./register.ts",
|
|
9
|
-
"engines": {
|
|
10
|
-
"node": ">=20.12.0"
|
|
11
|
-
},
|
|
12
|
-
"peerDependencies": {
|
|
13
|
-
"@vellumai/plugin-api": "^0.8.0"
|
|
14
|
-
}
|
|
15
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Default `persistence` plugin.
|
|
3
|
-
*
|
|
4
|
-
* The plugin's middleware is a passthrough — it calls `next(args)` and returns
|
|
5
|
-
* the result unchanged. The actual dispatch lives in the terminal handler in
|
|
6
|
-
* `./terminal.ts`, which is wired in as the pipeline's `terminal` argument by
|
|
7
|
-
* `runPipeline` call sites in `daemon/conversation-agent-loop.ts` and
|
|
8
|
-
* `daemon/conversation-agent-loop-handlers.ts`. This separation matters: the
|
|
9
|
-
* default plugin is registered before any user plugin (defaults load first in
|
|
10
|
-
* `bootstrapPlugins()`), which puts it at the OUTERMOST position of the onion
|
|
11
|
-
* chain. If the default middleware were to invoke the terminal directly
|
|
12
|
-
* without calling `next`, it would shadow every later-registered plugin.
|
|
13
|
-
* Routing through `next(args)` lets user middleware participate normally.
|
|
14
|
-
*
|
|
15
|
-
* Manifest declares `provides.persistence: "v1"` so other plugins can
|
|
16
|
-
* negotiate against the pipeline surface and `requires.pluginRuntime: "v1"`
|
|
17
|
-
* to satisfy the registry's mandatory capability check.
|
|
18
|
-
*
|
|
19
|
-
* Registered from `daemon/external-plugins-bootstrap.ts` via a side-effect
|
|
20
|
-
* import so the plugin is present in the registry before
|
|
21
|
-
* {@link bootstrapPlugins} walks it.
|
|
22
|
-
*
|
|
23
|
-
* Design doc: `.private/plans/agent-plugin-system.md` (PR 27).
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
import { type Plugin } from "../../types.js";
|
|
27
|
-
import persistence from "./middlewares/persistence.js";
|
|
28
|
-
import pkg from "./package.json" with { type: "json" };
|
|
29
|
-
|
|
30
|
-
export const defaultPersistencePlugin: Plugin = {
|
|
31
|
-
manifest: {
|
|
32
|
-
name: pkg.name,
|
|
33
|
-
version: pkg.version,
|
|
34
|
-
},
|
|
35
|
-
middleware: {
|
|
36
|
-
persistence,
|
|
37
|
-
},
|
|
38
|
-
};
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Default `persistence` behavior: writes conversation messages to the database
|
|
3
|
-
* (and optionally the JSONL disk view).
|
|
4
|
-
*
|
|
5
|
-
* This module is side-effect free: importing it does not register any plugin.
|
|
6
|
-
*
|
|
7
|
-
* The handler dispatches on the discriminated {@link PersistArgs.op} field:
|
|
8
|
-
*
|
|
9
|
-
* - `add` → {@link addMessage}, optionally followed by
|
|
10
|
-
* {@link syncMessageToDisk} when `args.syncToDisk` is true.
|
|
11
|
-
* - `reserve` → {@link reserveMessage} — pre-allocates an empty row
|
|
12
|
-
* for assistant anchor stamping.
|
|
13
|
-
* - `updateContent` → {@link updateMessageContent} — overwrites an existing
|
|
14
|
-
* row's content (returns `void`, wrapped as
|
|
15
|
-
* `{ op: "updateContent" }`).
|
|
16
|
-
* - `update` → {@link updateMessageMetadata} (returns `void`, wrapped
|
|
17
|
-
* as `{ op: "update" }`).
|
|
18
|
-
* - `delete` → {@link deleteMessageById} (returns the segment/summary
|
|
19
|
-
* IDs the caller must clean up out-of-band).
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
import {
|
|
23
|
-
addMessage,
|
|
24
|
-
deleteMessageById,
|
|
25
|
-
reserveMessage,
|
|
26
|
-
updateMessageContent,
|
|
27
|
-
updateMessageMetadata,
|
|
28
|
-
} from "../../../memory/conversation-crud.js";
|
|
29
|
-
import { syncMessageToDisk } from "../../../memory/conversation-disk-view.js";
|
|
30
|
-
import type { PersistArgs, PersistResult } from "../../types.js";
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Persist a message according to `args.op`. Exported so the agent-loop call
|
|
34
|
-
* sites can invoke it directly and tests can verify each op in isolation.
|
|
35
|
-
*/
|
|
36
|
-
export async function defaultPersistenceTerminal(
|
|
37
|
-
args: PersistArgs,
|
|
38
|
-
): Promise<PersistResult> {
|
|
39
|
-
switch (args.op) {
|
|
40
|
-
case "add": {
|
|
41
|
-
const message = await addMessage(
|
|
42
|
-
args.conversationId,
|
|
43
|
-
args.role,
|
|
44
|
-
args.content,
|
|
45
|
-
{
|
|
46
|
-
metadata: args.metadata,
|
|
47
|
-
...args.addOptions,
|
|
48
|
-
},
|
|
49
|
-
);
|
|
50
|
-
// Sync the just-persisted row to the JSONL disk view when the caller
|
|
51
|
-
// opted in. The handler that emits tool-result rows sets
|
|
52
|
-
// `syncToDisk: true` so the disk view stays in lockstep with the DB.
|
|
53
|
-
if (args.syncToDisk && args.createdAtMs !== undefined) {
|
|
54
|
-
syncMessageToDisk(args.conversationId, message.id, args.createdAtMs);
|
|
55
|
-
}
|
|
56
|
-
return { op: "add", message };
|
|
57
|
-
}
|
|
58
|
-
case "reserve": {
|
|
59
|
-
const message = await reserveMessage(
|
|
60
|
-
args.conversationId,
|
|
61
|
-
args.role,
|
|
62
|
-
args.metadata,
|
|
63
|
-
);
|
|
64
|
-
return { op: "reserve", message };
|
|
65
|
-
}
|
|
66
|
-
case "updateContent": {
|
|
67
|
-
updateMessageContent(args.messageId, args.content);
|
|
68
|
-
return { op: "updateContent" };
|
|
69
|
-
}
|
|
70
|
-
case "update": {
|
|
71
|
-
updateMessageMetadata(args.messageId, args.updates);
|
|
72
|
-
return { op: "update" };
|
|
73
|
-
}
|
|
74
|
-
case "delete": {
|
|
75
|
-
const deleted = deleteMessageById(args.messageId);
|
|
76
|
-
return {
|
|
77
|
-
op: "delete",
|
|
78
|
-
segmentIds: deleted.segmentIds,
|
|
79
|
-
deletedSummaryIds: deleted.deletedSummaryIds,
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|