@vellumai/assistant 0.8.3 → 0.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +2 -2
- package/docker-entrypoint.sh +0 -1
- package/docs/browser-use-architecture-phase2.md +1 -1
- package/knip.json +2 -1
- package/node_modules/@vellumai/gateway-client/src/types.ts +2 -0
- package/openapi.yaml +1492 -100
- package/package.json +1 -1
- package/src/__tests__/agent-loop-exit-reason.test.ts +4 -5
- package/src/__tests__/agent-loop-override-profile.test.ts +1 -1
- package/src/__tests__/agent-loop.test.ts +88 -3
- package/src/__tests__/anthropic-provider.test.ts +302 -33
- package/src/__tests__/approval-cascade.test.ts +1 -1
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +3 -3
- package/src/__tests__/audit-log-rotation.test.ts +70 -16
- package/src/__tests__/background-workers-disk-pressure.test.ts +4 -3
- package/src/__tests__/btw-routes.test.ts +2 -3
- package/src/__tests__/call-controller.test.ts +0 -1
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
- package/src/__tests__/channel-delivery-store.test.ts +193 -0
- package/src/__tests__/channel-guardian.test.ts +3 -3
- package/src/__tests__/channel-reply-delivery.test.ts +284 -5
- package/src/__tests__/channel-retry-sweep.test.ts +274 -1
- package/src/__tests__/checker.test.ts +6 -15
- package/src/__tests__/compaction-events.test.ts +2 -1
- package/src/__tests__/compactor-call-site-logging.test.ts +214 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +110 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +5 -11
- package/src/__tests__/computer-use-tools.test.ts +2 -4
- package/src/__tests__/config-watcher.test.ts +1 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/context-token-estimator.test.ts +91 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +55 -4
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +228 -8
- package/src/__tests__/conversation-agent-loop.test.ts +188 -129
- package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -5
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
- package/src/__tests__/conversation-clean-command.test.ts +137 -0
- package/src/__tests__/conversation-clear-safety.test.ts +25 -25
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -1
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-error.test.ts +31 -0
- package/src/__tests__/conversation-fork-crud.test.ts +324 -0
- package/src/__tests__/conversation-lifecycle.test.ts +53 -12
- package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
- package/src/__tests__/conversation-load-history-stripped.test.ts +279 -0
- package/src/__tests__/conversation-pairing.test.ts +2 -2
- package/src/__tests__/conversation-process-callsite.test.ts +1 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -1
- package/src/__tests__/conversation-queue.test.ts +1 -1
- package/src/__tests__/conversation-routes-disk-view.test.ts +109 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +35 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +264 -81
- package/src/__tests__/conversation-seed-composer.test.ts +66 -4
- package/src/__tests__/conversation-skill-tools.test.ts +2 -5
- package/src/__tests__/conversation-slash-commands.test.ts +36 -8
- package/src/__tests__/conversation-slash-queue.test.ts +1 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -1
- package/src/__tests__/conversation-speed-override.test.ts +1 -1
- package/src/__tests__/conversation-store.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +220 -0
- package/src/__tests__/conversation-sync-tags.test.ts +99 -32
- package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
- package/src/__tests__/credential-execution-feature-gates.test.ts +9 -7
- package/src/__tests__/credential-execution-tools.test.ts +6 -6
- package/src/__tests__/credential-security-invariants.test.ts +7 -0
- package/src/__tests__/credential-vault-unit.test.ts +2 -2
- package/src/__tests__/cu-unified-flow.test.ts +10 -1
- package/src/__tests__/dm-backfill.test.ts +64 -0
- package/src/__tests__/dm-persistence.test.ts +33 -0
- package/src/__tests__/document-find-replace.test.ts +501 -0
- package/src/__tests__/dynamic-page-surface.test.ts +2 -2
- package/src/__tests__/email-html-renderer.test.ts +12 -0
- package/src/__tests__/first-greeting.test.ts +23 -2
- package/src/__tests__/gateway-flag-listener.test.ts +237 -0
- package/src/__tests__/gemini-provider.test.ts +78 -0
- package/src/__tests__/guardian-dispatch.test.ts +0 -1
- package/src/__tests__/guardian-outbound-http.test.ts +7 -5
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
- package/src/__tests__/headless-browser-navigate.test.ts +172 -0
- package/src/__tests__/heartbeat-disk-pressure.test.ts +4 -0
- package/src/__tests__/heartbeat-service.test.ts +4 -0
- package/src/__tests__/host-bash-proxy.test.ts +6 -0
- package/src/__tests__/host-browser-proxy.test.ts +10 -0
- package/src/__tests__/host-cu-proxy.test.ts +8 -1
- package/src/__tests__/host-file-proxy.test.ts +8 -1
- package/src/__tests__/host-shell-tool.test.ts +1 -1
- package/src/__tests__/host-transfer-proxy.test.ts +8 -1
- package/src/__tests__/identity-routes.test.ts +57 -0
- package/src/__tests__/inbound-slack-persistence.test.ts +3 -0
- package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
- package/src/__tests__/injector-chain.test.ts +2 -0
- package/src/__tests__/injector-document-comments.test.ts +378 -0
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +4 -25
- package/src/__tests__/list-messages-attachments.test.ts +21 -17
- package/src/__tests__/list-messages-hidden-metadata.test.ts +217 -0
- package/src/__tests__/list-messages-page-latest.test.ts +130 -14
- package/src/__tests__/list-messages-tool-merge.test.ts +77 -17
- package/src/__tests__/llm-context-normalization.test.ts +0 -2
- package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
- package/src/__tests__/llm-resolver.test.ts +161 -9
- package/src/__tests__/llm-usage-store.test.ts +66 -0
- package/src/__tests__/log-export-routes.test.ts +99 -2
- package/src/__tests__/logger.test.ts +89 -0
- package/src/__tests__/mcp-abort-signal.test.ts +2 -2
- package/src/__tests__/media-generate-image.test.ts +31 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
- package/src/__tests__/message-queue-steer.test.ts +114 -0
- package/src/__tests__/model-intents.test.ts +2 -4
- package/src/__tests__/notification-guardian-path.test.ts +0 -1
- package/src/__tests__/onboarding-template-contract.test.ts +1 -1
- package/src/__tests__/openai-provider.test.ts +151 -0
- package/src/__tests__/openai-responses-provider.test.ts +118 -16
- package/src/__tests__/outbound-slack-persistence.test.ts +187 -20
- package/src/__tests__/pending-interactions-resolved-event.test.ts +189 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
- package/src/__tests__/platform.test.ts +2 -5
- package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
- package/src/__tests__/plugin-bootstrap.test.ts +2 -2
- package/src/__tests__/plugin-source-watcher.test.ts +302 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +13 -6
- package/src/__tests__/plugin-types.test.ts +3 -2
- package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
- package/src/__tests__/pricing.test.ts +12 -0
- package/src/__tests__/process-message-background-slack.test.ts +1 -51
- package/src/__tests__/process-message-display-content.test.ts +21 -16
- package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
- package/src/__tests__/registry.test.ts +2 -8
- package/src/__tests__/require-fresh-approval.test.ts +2 -2
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
- package/src/__tests__/server-history-render.test.ts +83 -4
- package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
- package/src/__tests__/skill-feature-flags.test.ts +2 -2
- package/src/__tests__/skill-projection-feature-flag.test.ts +4 -7
- package/src/__tests__/skill-projection.benchmark.test.ts +2 -6
- package/src/__tests__/skill-tool-factory.test.ts +1 -1
- package/src/__tests__/steer-tool-repair.test.ts +249 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -1
- package/src/__tests__/suggestion-routes.test.ts +1 -0
- package/src/__tests__/sync-message-contract.test.ts +59 -0
- package/src/__tests__/system-prompt.test.ts +161 -124
- package/src/__tests__/terminal-tools.test.ts +12 -2
- package/src/__tests__/thinking-block-replay.test.ts +113 -0
- package/src/__tests__/thread-backfill.test.ts +370 -22
- package/src/__tests__/tool-approval-handler.test.ts +1 -5
- package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +15 -5
- package/src/__tests__/tool-executor.test.ts +89 -53
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +167 -0
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
- package/src/__tests__/twilio-routes.test.ts +1 -1
- package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
- package/src/__tests__/usage-routes.test.ts +3 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -2
- package/src/__tests__/web-fetch.test.ts +2 -2
- package/src/__tests__/workspace-git-service.test.ts +94 -10
- package/src/__tests__/workspace-migration-088-deprecate-background-conversation-override.test.ts +158 -0
- package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
- package/src/acp/prepare-agent-env.ts +78 -0
- package/src/acp/session-manager.ts +1 -1
- package/src/agent/attachments.ts +1 -0
- package/src/agent/loop.ts +65 -20
- package/src/api/README.md +5 -0
- package/src/api/index.ts +4 -0
- package/src/api/package.json +10 -0
- package/src/background-wake/background-wake-routes.test.ts +233 -0
- package/src/background-wake/next-wake.test.ts +289 -0
- package/src/background-wake/next-wake.ts +172 -0
- package/src/background-wake/runtime-registry.ts +24 -0
- package/src/browser/operations.ts +15 -0
- package/src/cli/commands/__tests__/browser.test.ts +23 -5
- package/src/cli/commands/__tests__/conversations-slack.test.ts +572 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
- package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
- package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +10 -12
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
- package/src/cli/commands/browser.ts +247 -0
- package/src/cli/commands/conversations.ts +128 -1
- package/src/cli/commands/domain.ts +91 -41
- package/src/cli/commands/inference-providers.ts +147 -1
- package/src/cli/commands/inference.ts +93 -40
- package/src/cli/commands/memory-v2-compare-render.ts +115 -0
- package/src/cli/commands/memory-v2.ts +483 -0
- package/src/cli/commands/memory-v3-render.ts +344 -0
- package/src/cli/commands/memory-v3.ts +316 -0
- package/src/cli/commands/notifications.ts +24 -2
- package/src/cli/program.ts +2 -0
- package/src/cli/utils/conversation-id.ts +17 -5
- package/src/config/assistant-feature-flags.ts +21 -9
- package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
- package/src/config/bundled-skills/document-editor/SKILL.md +124 -0
- package/src/config/bundled-skills/document-editor/TOOLS.json +258 -0
- package/src/config/bundled-skills/document-editor/tools/comment-list.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-reply.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-resolve.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-find.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-replace-text.ts +12 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
- package/src/config/bundled-skills/media-processing/SKILL.md +8 -0
- package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +8 -0
- package/src/config/bundled-tool-registry.ts +24 -12
- package/src/config/call-site-defaults.ts +20 -0
- package/src/config/feature-flag-registry.json +115 -3
- package/src/config/llm-resolver.ts +16 -2
- package/src/config/schemas/__tests__/memory-v2.test.ts +217 -1
- package/src/config/schemas/call-site-catalog.ts +35 -0
- package/src/config/schemas/llm.ts +14 -0
- package/src/config/schemas/memory-v2.ts +294 -1
- package/src/config/schemas/memory.ts +2 -1
- package/src/context/compactor.ts +60 -1
- package/src/context/token-estimator.ts +47 -4
- package/src/context/window-manager.ts +25 -0
- package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
- package/src/conversations/message-consolidation.ts +404 -0
- package/src/credential-health/credential-health-service.ts +34 -19
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -1
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -6
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +1 -1
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +357 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +287 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +155 -36
- package/src/daemon/conversation-agent-loop.ts +307 -88
- package/src/daemon/conversation-error.ts +31 -1
- package/src/daemon/conversation-lifecycle.ts +149 -118
- package/src/daemon/conversation-messaging.ts +3 -0
- package/src/daemon/conversation-process.ts +273 -0
- package/src/daemon/conversation-queue-manager.ts +14 -0
- package/src/daemon/conversation-runtime-assembly.ts +145 -84
- package/src/daemon/conversation-slash.ts +37 -5
- package/src/daemon/conversation-surfaces.ts +45 -2
- package/src/daemon/conversation-tool-setup.ts +70 -3
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +54 -32
- package/src/daemon/disk-pressure-guard.ts +14 -2
- package/src/daemon/first-greeting.ts +10 -0
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +498 -0
- package/src/daemon/handlers/config-a2a.ts +160 -0
- package/src/daemon/handlers/config-model.test.ts +2 -0
- package/src/daemon/handlers/conversations.ts +90 -3
- package/src/daemon/handlers/shared.ts +92 -29
- package/src/daemon/host-bash-proxy.ts +1 -1
- package/src/daemon/host-browser-proxy.ts +5 -5
- package/src/daemon/host-cu-proxy.ts +5 -5
- package/src/daemon/host-file-proxy.ts +5 -5
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/host-transfer-proxy.ts +11 -11
- package/src/daemon/lifecycle.ts +40 -23
- package/src/daemon/meet-manifest-loader.ts +1 -7
- package/src/daemon/message-protocol.ts +4 -0
- package/src/daemon/message-types/conversations.ts +14 -9
- package/src/daemon/message-types/document-comments.ts +50 -0
- package/src/daemon/message-types/home.ts +1 -13
- package/src/daemon/message-types/messages.ts +66 -7
- package/src/daemon/message-types/surfaces.ts +3 -1
- package/src/daemon/message-types/sync.ts +14 -0
- package/src/daemon/message-types/web-activity.ts +57 -0
- package/src/daemon/plugin-source-watcher.ts +135 -3
- package/src/daemon/process-message.ts +69 -12
- package/src/daemon/shutdown-handlers.ts +24 -5
- package/src/daemon/switch-inference-profile-tool.ts +52 -0
- package/src/daemon/tool-setup-types.ts +13 -0
- package/src/daemon/trust-context.ts +6 -0
- package/src/documents/document-comments-store.test.ts +338 -0
- package/src/documents/document-comments-store.ts +237 -0
- package/src/documents/document-store.ts +202 -0
- package/src/events/relationship-state-updated.ts +25 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +1 -2
- package/src/heartbeat/heartbeat-service.ts +1 -0
- package/src/home/__tests__/suggested-prompts.test.ts +33 -2
- package/src/home/feed-types.ts +6 -1
- package/src/home/home-content-refresh.ts +52 -0
- package/src/home/home-greeting-cache.ts +69 -0
- package/src/home/home-greeting.ts +85 -0
- package/src/home/suggested-prompts.ts +168 -9
- package/src/ipc/gateway-flag-listener.ts +123 -0
- package/src/ipc/skill-routes/registries.ts +8 -12
- package/src/memory/__tests__/db-async-query.test.ts +165 -0
- package/src/memory/__tests__/db-maintenance.test.ts +115 -0
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +241 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +135 -2
- package/src/memory/__tests__/memory-retrospective-job.test.ts +327 -6
- package/src/memory/auto-analysis-enqueue.ts +5 -1
- package/src/memory/conversation-crud.ts +191 -100
- package/src/memory/conversation-starters-cadence.ts +3 -1
- package/src/memory/conversation-title-service.ts +19 -3
- package/src/memory/db-async-query.ts +214 -0
- package/src/memory/db-init.ts +26 -0
- package/src/memory/db-maintenance.ts +30 -21
- package/src/memory/delivery-crud.ts +41 -0
- package/src/memory/delivery-status.ts +141 -15
- package/src/memory/external-conversation-store.ts +32 -1
- package/src/memory/graph/bootstrap.ts +8 -1
- package/src/memory/graph/capability-seed.ts +7 -3
- package/src/memory/graph/conversation-graph-memory.ts +100 -17
- package/src/memory/graph/extraction.ts +1 -5
- package/src/memory/graph/graph-search.ts +7 -1
- package/src/memory/indexer.ts +28 -18
- package/src/memory/job-handlers/cleanup.ts +76 -18
- package/src/memory/job-handlers/conversation-starters.ts +1 -4
- package/src/memory/jobs/embed-pkb-file.ts +6 -1
- package/src/memory/jobs-store.ts +14 -0
- package/src/memory/jobs-worker.ts +68 -15
- package/src/memory/llm-request-log-source-clickhouse.ts +42 -2
- package/src/memory/llm-request-log-source-local.ts +7 -0
- package/src/memory/llm-request-log-source.ts +9 -2
- package/src/memory/llm-request-log-store.ts +43 -1
- package/src/memory/llm-usage-store.ts +24 -0
- package/src/memory/memory-retrospective-constants.ts +28 -0
- package/src/memory/memory-retrospective-enqueue.ts +11 -3
- package/src/memory/memory-retrospective-job.ts +413 -18
- package/src/memory/memory-retrospective-startup-cleanup.ts +3 -3
- package/src/memory/memory-v2-activation-log-store.ts +41 -14
- package/src/memory/migrations/100-core-tables.ts +1 -0
- package/src/memory/migrations/109-external-conversation-bindings.ts +1 -0
- package/src/memory/migrations/253-conversation-last-notified-profile.ts +15 -0
- package/src/memory/migrations/253-document-comments.ts +47 -0
- package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +43 -0
- package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +24 -0
- package/src/memory/migrations/256-memory-v2-injection-events.ts +113 -0
- package/src/memory/migrations/257-strip-base-url-non-openai-compatible.ts +22 -0
- package/src/memory/migrations/258-onboarding-events-prior-assistants.ts +13 -0
- package/src/memory/migrations/259-conversation-cleaned-at.ts +33 -0
- package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
- package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
- package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
- package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
- package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
- package/src/memory/migrations/index.ts +34 -0
- package/src/memory/migrations/registry.ts +58 -0
- package/src/memory/onboarding-events-store.ts +7 -0
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/conversations.ts +3 -0
- package/src/memory/schema/infrastructure.ts +22 -0
- package/src/memory/tool-usage-store.ts +36 -8
- package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
- package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
- package/src/memory/v2/__tests__/harness-metrics.test.ts +74 -0
- package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +225 -0
- package/src/memory/v2/__tests__/harness-runner.test.ts +109 -0
- package/src/memory/v2/__tests__/injection-events.test.ts +318 -0
- package/src/memory/v2/__tests__/injection.test.ts +158 -112
- package/src/memory/v2/__tests__/page-index.test.ts +365 -1
- package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
- package/src/memory/v2/__tests__/router.test.ts +660 -4
- package/src/memory/v2/consolidation-job.ts +14 -0
- package/src/memory/v2/harness/compare.ts +57 -0
- package/src/memory/v2/harness/metrics.ts +124 -0
- package/src/memory/v2/harness/oracle.ts +145 -0
- package/src/memory/v2/harness/replay-input.ts +224 -0
- package/src/memory/v2/harness/retriever.ts +74 -0
- package/src/memory/v2/harness/router-retriever.ts +43 -0
- package/src/memory/v2/harness/runner.ts +106 -0
- package/src/memory/v2/harness/trace.ts +58 -0
- package/src/memory/v2/injection-events.ts +101 -0
- package/src/memory/v2/injection.ts +42 -25
- package/src/memory/v2/page-index.ts +209 -7
- package/src/memory/v2/page-store.ts +18 -0
- package/src/memory/v2/prompts/router.ts +26 -1
- package/src/memory/v2/qdrant.ts +14 -2
- package/src/memory/v2/router.ts +369 -62
- package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
- package/src/memory/v3/__tests__/consolidation-job.test.ts +468 -0
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
- package/src/memory/v3/__tests__/edges.test.ts +563 -0
- package/src/memory/v3/__tests__/filter.test.ts +512 -0
- package/src/memory/v3/__tests__/gate.test.ts +574 -0
- package/src/memory/v3/__tests__/index-composition.test.ts +233 -0
- package/src/memory/v3/__tests__/loop.test.ts +530 -0
- package/src/memory/v3/__tests__/retriever.test.ts +226 -0
- package/src/memory/v3/__tests__/scouts.test.ts +440 -0
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +312 -0
- package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
- package/src/memory/v3/__tests__/traversal.test.ts +469 -0
- package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
- package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
- package/src/memory/v3/__tests__/tree-walk.test.ts +707 -0
- package/src/memory/v3/__tests__/validate.test.ts +245 -0
- package/src/memory/v3/auto-edges.ts +223 -0
- package/src/memory/v3/coactivation-store.ts +124 -0
- package/src/memory/v3/consolidation-job.ts +323 -0
- package/src/memory/v3/edge-learning-job.ts +160 -0
- package/src/memory/v3/edges.ts +249 -0
- package/src/memory/v3/filter.ts +281 -0
- package/src/memory/v3/gate.ts +334 -0
- package/src/memory/v3/index-composition.ts +113 -0
- package/src/memory/v3/llm-capture.ts +46 -0
- package/src/memory/v3/loop.ts +382 -0
- package/src/memory/v3/maintenance.ts +144 -0
- package/src/memory/v3/prompt-context.ts +33 -0
- package/src/memory/v3/prompts/consolidation.ts +458 -0
- package/src/memory/v3/prompts/system-prompts.ts +196 -0
- package/src/memory/v3/retriever.ts +33 -0
- package/src/memory/v3/scouts.ts +420 -0
- package/src/memory/v3/shadow-middleware.ts +305 -0
- package/src/memory/v3/traversal.ts +206 -0
- package/src/memory/v3/tree-index.ts +237 -0
- package/src/memory/v3/tree-store.ts +394 -0
- package/src/memory/v3/tree-walk.ts +351 -0
- package/src/memory/v3/types.ts +65 -0
- package/src/memory/v3/validate.ts +300 -0
- package/src/messaging/providers/index.ts +7 -1
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +329 -3
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +34 -1
- package/src/messaging/providers/slack/adapter.ts +178 -25
- package/src/messaging/providers/slack/api.test.ts +54 -0
- package/src/messaging/providers/slack/api.ts +119 -3
- package/src/messaging/providers/slack/client.ts +12 -0
- package/src/messaging/providers/slack/deep-link.ts +20 -1
- package/src/messaging/providers/slack/message-metadata.test.ts +48 -0
- package/src/messaging/providers/slack/message-metadata.ts +156 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +107 -75
- package/src/messaging/providers/slack/render-transcript.ts +176 -49
- package/src/messaging/providers/slack/send.test.ts +77 -0
- package/src/messaging/providers/slack/send.ts +8 -2
- package/src/messaging/providers/slack/types.ts +14 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +4 -1
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +116 -54
- package/src/notifications/adapters/macos.ts +18 -1
- package/src/notifications/adapters/platform.ts +1 -1
- package/src/notifications/conversation-seed-composer.ts +14 -2
- package/src/notifications/decision-engine.ts +1 -4
- package/src/notifications/deferred-emit.ts +135 -0
- package/src/notifications/emit-signal.ts +38 -50
- package/src/notifications/home-feed-side-effect.ts +60 -30
- package/src/oauth/connect-orchestrator.ts +3 -0
- package/src/oauth/credential-token-resolver.ts +2 -0
- package/src/oauth/manual-token-connection.ts +19 -0
- package/src/oauth/oauth-store.ts +12 -0
- package/src/oauth/seed-providers.ts +22 -0
- package/src/permissions/prompter.ts +8 -5
- package/src/permissions/question-prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +6 -3
- package/src/plugin-api/index.ts +4 -0
- package/src/plugin-api/types.ts +7 -33
- package/src/plugins/defaults/index.ts +6 -0
- package/src/plugins/defaults/injectors.ts +100 -20
- package/src/plugins/external-plugin-loader.ts +5 -68
- package/src/plugins/types.ts +11 -16
- package/src/proactive-artifact/aux-message-injector.ts +17 -4
- package/src/prompts/__tests__/system-prompt.test.ts +46 -2
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
- package/src/prompts/normalize-onboarding.ts +40 -0
- package/src/prompts/persona-resolver.ts +36 -21
- package/src/prompts/sections.ts +69 -19
- package/src/prompts/system-prompt.ts +118 -216
- package/src/prompts/template-detection.ts +37 -0
- package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +141 -0
- package/src/prompts/templates/BOOTSTRAP.md +10 -2
- package/src/prompts/templates/VOICE.md +3 -0
- package/src/prompts/templates/system-sections.ts +281 -9
- package/src/providers/__tests__/connection-model-compat.test.ts +234 -0
- package/src/providers/__tests__/retry-callsite.test.ts +85 -5
- package/src/providers/anthropic/client.ts +159 -66
- package/src/providers/call-site-routing.ts +14 -2
- package/src/providers/connection-model-compat.ts +38 -0
- package/src/providers/connection-resolution.ts +16 -2
- package/src/providers/fireworks/client.ts +20 -2
- package/src/providers/gemini/client.ts +49 -6
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +342 -0
- package/src/providers/inference/__tests__/base-url-security.test.ts +189 -0
- package/src/providers/inference/__tests__/codex-token-refresh.test.ts +254 -0
- package/src/providers/inference/adapter-factory.ts +18 -1
- package/src/providers/inference/auth.ts +3 -3
- package/src/providers/inference/codex-token-refresh.ts +128 -0
- package/src/providers/inference/resolve-auth.ts +49 -6
- package/src/providers/minimax/client.ts +106 -0
- package/src/providers/model-catalog.ts +91 -1
- package/src/providers/model-intents.ts +1 -1
- package/src/providers/openai/chat-completions-provider.ts +63 -23
- package/src/providers/openai/codex-models.ts +18 -0
- package/src/providers/openai/responses-provider.ts +86 -23
- package/src/providers/openrouter/client.ts +5 -1
- package/src/providers/provider-send-message.ts +7 -1
- package/src/providers/retry.ts +34 -3
- package/src/providers/thinking-config.ts +26 -1
- package/src/providers/types.ts +25 -0
- package/src/providers/usage-tracking.ts +2 -0
- package/src/runtime/AGENTS.md +2 -2
- package/src/runtime/__tests__/agent-wake.test.ts +214 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +128 -0
- package/src/runtime/agent-wake.ts +152 -56
- package/src/runtime/assistant-event-hub.ts +76 -6
- package/src/runtime/auth/route-policy.ts +43 -3
- package/src/runtime/background-job-runner.ts +26 -0
- package/src/runtime/btw-sidechain.ts +0 -6
- package/src/runtime/channel-reply-delivery.ts +182 -47
- package/src/runtime/channel-retry-sweep.ts +141 -16
- package/src/runtime/http-types.ts +7 -6
- package/src/runtime/migrations/vbundle-builder.ts +10 -3
- package/src/runtime/pending-interactions.ts +50 -8
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +162 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +161 -1
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +14 -0
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +290 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +280 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +266 -0
- package/src/runtime/routes/acp-routes.test.ts +255 -6
- package/src/runtime/routes/acp-routes.ts +8 -1
- package/src/runtime/routes/approval-routes.ts +4 -1
- package/src/runtime/routes/avatar-routes.ts +10 -10
- package/src/runtime/routes/background-wake-routes.ts +188 -0
- package/src/runtime/routes/browser-tabs-routes.ts +200 -0
- package/src/runtime/routes/btw-routes.ts +0 -6
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +246 -0
- package/src/runtime/routes/content-source-routes.ts +78 -0
- package/src/runtime/routes/conversation-cli-routes.ts +147 -2
- package/src/runtime/routes/conversation-list-routes.ts +12 -4
- package/src/runtime/routes/conversation-management-routes.ts +77 -20
- package/src/runtime/routes/conversation-query-routes.ts +196 -31
- package/src/runtime/routes/conversation-routes.ts +472 -425
- package/src/runtime/routes/conversation-starter-routes.ts +6 -3
- package/src/runtime/routes/disk-pressure-routes.ts +1 -1
- package/src/runtime/routes/document-comments-routes.ts +287 -0
- package/src/runtime/routes/documents-routes.ts +33 -0
- package/src/runtime/routes/domain-routes.ts +60 -10
- package/src/runtime/routes/email-routes.ts +5 -2
- package/src/runtime/routes/events-routes.ts +54 -10
- package/src/runtime/routes/group-routes.ts +24 -8
- package/src/runtime/routes/home-feed-routes.ts +6 -3
- package/src/runtime/routes/host-app-control-routes.ts +1 -1
- package/src/runtime/routes/host-browser-routes.ts +17 -2
- package/src/runtime/routes/host-cu-routes.ts +2 -2
- package/src/runtime/routes/identity-routes.ts +21 -0
- package/src/runtime/routes/inbound-message-handler.ts +288 -58
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +365 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +283 -82
- package/src/runtime/routes/index.ts +20 -4
- package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
- package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
- package/src/runtime/routes/inference-provider-connection-routes.ts +63 -7
- package/src/runtime/routes/integrations/a2a.ts +60 -1
- package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
- package/src/runtime/routes/log-export-routes.ts +39 -0
- package/src/runtime/routes/memory-item-routes.ts +8 -3
- package/src/runtime/routes/memory-v2-routes.ts +427 -0
- package/src/runtime/routes/memory-v3-routes.ts +316 -0
- package/src/runtime/routes/migration-routes.ts +21 -24
- package/src/runtime/routes/notification-routes.ts +19 -2
- package/src/runtime/routes/plugins-routes.ts +337 -0
- package/src/runtime/routes/question-routes.ts +4 -1
- package/src/runtime/routes/rename-conversation-routes.ts +6 -2
- package/src/runtime/routes/sanity-routes.ts +159 -0
- package/src/runtime/routes/secret-routes.ts +25 -5
- package/src/runtime/routes/settings-routes.ts +12 -11
- package/src/runtime/routes/slack-channel-routes.ts +188 -0
- package/src/runtime/routes/workspace-routes.ts +25 -10
- package/src/runtime/services/conversation-serializer.ts +30 -4
- package/src/runtime/sync/resource-sync-events.ts +106 -38
- package/src/runtime/sync/sync-publisher.test.ts +49 -0
- package/src/runtime/sync/sync-publisher.ts +2 -1
- package/src/runtime/verification-outbound-actions.ts +73 -1
- package/src/schedule/integration-status.ts +3 -1
- package/src/security/__tests__/oauth2-device-code.test.ts +479 -0
- package/src/security/oauth2-device-code.ts +307 -0
- package/src/security/oauth2.ts +26 -9
- package/src/security/secure-keys.ts +5 -0
- package/src/skills/catalog-install.ts +6 -2
- package/src/telemetry/types.ts +12 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/acp/spawn.test.ts +119 -0
- package/src/tools/acp/spawn.ts +15 -2
- package/src/tools/apps/definitions.ts +2 -8
- package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
- package/src/tools/ask-question/ask-question-tool.ts +38 -45
- package/src/tools/browser/__tests__/pinned-tabs.test.ts +150 -0
- package/src/tools/browser/browser-execution.ts +106 -0
- package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +28 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +4 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +22 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +42 -2
- package/src/tools/browser/cdp-client/factory.ts +171 -4
- package/src/tools/browser/cdp-client/local-cdp-client.ts +21 -0
- package/src/tools/browser/cdp-client/types.ts +101 -0
- package/src/tools/browser/pinned-tabs.ts +146 -0
- package/src/tools/computer-use/definitions.ts +22 -78
- package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
- package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
- package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
- package/src/tools/credentials/vault.ts +3 -9
- package/src/tools/document/document-comment-tool.test.ts +379 -0
- package/src/tools/document/document-comment-tool.ts +156 -0
- package/src/tools/document/document-tool.ts +187 -2
- package/src/tools/execution-target.ts +21 -23
- package/src/tools/executor.ts +6 -1
- package/src/tools/filesystem/edit.ts +3 -9
- package/src/tools/filesystem/list.ts +3 -9
- package/src/tools/filesystem/read.ts +3 -9
- package/src/tools/filesystem/write.ts +3 -9
- package/src/tools/host-filesystem/edit.ts +3 -9
- package/src/tools/host-filesystem/read.ts +3 -9
- package/src/tools/host-filesystem/transfer.ts +3 -9
- package/src/tools/host-filesystem/write.ts +3 -9
- package/src/tools/host-terminal/host-shell.ts +3 -9
- package/src/tools/mcp/mcp-tool-factory.ts +1 -8
- package/src/tools/memory/register.test.ts +1 -1
- package/src/tools/memory/register.ts +4 -9
- package/src/tools/network/__tests__/web-fetch-metadata.test.ts +229 -0
- package/src/tools/network/__tests__/web-search-metadata.test.ts +346 -0
- package/src/tools/network/domain-normalize.ts +17 -0
- package/src/tools/network/web-fetch.ts +216 -73
- package/src/tools/network/web-search.ts +216 -98
- package/src/tools/registry.ts +7 -23
- package/src/tools/schema-transforms.ts +1 -1
- package/src/tools/skills/execute.ts +3 -9
- package/src/tools/skills/load.ts +3 -9
- package/src/tools/skills/skill-tool-factory.ts +1 -8
- package/src/tools/subagent/notify-parent.ts +3 -9
- package/src/tools/system/request-permission.ts +3 -9
- package/src/tools/terminal/safe-env.ts +3 -2
- package/src/tools/terminal/shell.ts +3 -9
- package/src/tools/tool-approval-handler.ts +19 -12
- package/src/tools/tool-defaults.ts +94 -0
- package/src/tools/types.ts +31 -98
- package/src/tools/ui-surface/definitions.ts +9 -23
- package/src/types/onboarding-context.ts +4 -0
- package/src/usage/pricing.ts +23 -0
- package/src/usage/types.ts +12 -0
- package/src/util/__tests__/favicon.test.ts +84 -0
- package/src/util/favicon.ts +40 -0
- package/src/util/logger.ts +16 -7
- package/src/util/platform.ts +7 -7
- package/src/util/sqlite3-runtime.ts +65 -0
- package/src/workspace/git-service.ts +75 -4
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
- package/src/workspace/migrations/088-deprecate-background-conversation-override.ts +103 -0
- package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
- package/src/__tests__/message-complete-display-id.test.ts +0 -175
- package/src/config/bundled-skills/document/SKILL.md +0 -54
- package/src/config/bundled-skills/document/TOOLS.json +0 -106
- package/src/daemon/seed-files.ts +0 -18
- package/src/prompts/cache-boundary.ts +0 -8
- package/src/runtime/routes/interface-routes.ts +0 -43
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-create.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-delete.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-list.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-read.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-update.ts +0 -0
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
* | `memory-v2-static` | 38 | after-memory-prefix |
|
|
21
21
|
* | `now-md` | 40 | after-memory-prefix |
|
|
22
22
|
* | `active-documents` | 45 | prepend-user-tail |
|
|
23
|
+
* | `document-comments` | 46 | prepend-user-tail |
|
|
23
24
|
* | `subagent-status` | 50 | append-user-tail |
|
|
24
25
|
* | `slack-messages` | 60 | replace-run-messages |
|
|
25
26
|
* | `thread-focus` | 70 | append-user-tail |
|
|
@@ -51,6 +52,7 @@ import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-fl
|
|
|
51
52
|
import { getConfig } from "../../config/loader.js";
|
|
52
53
|
import { getInContextPkbPaths } from "../../daemon/pkb-context-tracker.js";
|
|
53
54
|
import { buildPkbReminder } from "../../daemon/pkb-reminder-builder.js";
|
|
55
|
+
import { listComments } from "../../documents/document-comments-store.js";
|
|
54
56
|
import { searchPkbFiles } from "../../memory/pkb/pkb-search.js";
|
|
55
57
|
import { getLogger } from "../../util/logger.js";
|
|
56
58
|
import { registerPlugin } from "../registry.js";
|
|
@@ -94,6 +96,7 @@ export const DEFAULT_INJECTOR_ORDER = {
|
|
|
94
96
|
memoryV2Static: 38,
|
|
95
97
|
nowMd: 40,
|
|
96
98
|
activeDocuments: 45,
|
|
99
|
+
documentComments: 46,
|
|
97
100
|
subagentStatus: 50,
|
|
98
101
|
slackMessages: 60,
|
|
99
102
|
threadFocus: 70,
|
|
@@ -133,12 +136,11 @@ const diskPressureWarningInjector: Injector = {
|
|
|
133
136
|
};
|
|
134
137
|
|
|
135
138
|
/**
|
|
136
|
-
* v2 read-side cutover guard.
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
* state independent of PKB and fires unchanged.
|
|
139
|
+
* v2 read-side cutover guard. Under v2 both `pkb-context` and `pkb-reminder`
|
|
140
|
+
* silence themselves entirely — the `<knowledge_base>` content and the
|
|
141
|
+
* generic recall/remember nudge are both supplanted by the v2 static
|
|
142
|
+
* `<memory>` block. NOW.md is workspace state independent of PKB and fires
|
|
143
|
+
* unchanged.
|
|
142
144
|
*/
|
|
143
145
|
function isPkbInjectionSilencedByV2(): boolean {
|
|
144
146
|
return getConfig().memory.v2.enabled;
|
|
@@ -287,9 +289,8 @@ const pkbReminderInjector: Injector = {
|
|
|
287
289
|
const mode = inputs.mode ?? "full";
|
|
288
290
|
if (mode !== "full") return null;
|
|
289
291
|
if (!inputs.pkbActive) return null;
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
: await buildPkbReminderWithHints(inputs);
|
|
292
|
+
if (isPkbInjectionSilencedByV2()) return null;
|
|
293
|
+
const reminder = await buildPkbReminderWithHints(inputs);
|
|
293
294
|
return {
|
|
294
295
|
id: "pkb-reminder",
|
|
295
296
|
text: reminder,
|
|
@@ -386,17 +387,20 @@ async function buildPkbReminderWithHints(
|
|
|
386
387
|
* `memory-v2-static` injector — order 38, after-memory-prefix.
|
|
387
388
|
*
|
|
388
389
|
* Injects the v2 static memory block (essentials/threads/recent/buffer
|
|
389
|
-
* concatenated under markdown headings) wrapped in `<
|
|
390
|
+
* concatenated under markdown headings) wrapped in `<info>...</info>`
|
|
390
391
|
* onto the user message. The agent loop only forwards `memoryV2Static` on
|
|
391
392
|
* full-mode turns (first turn / post-compaction), mirroring the PKB
|
|
392
393
|
* auto-inject cadence — subsequent turns get `null` and the prior block
|
|
393
394
|
* stays cached on its original user message.
|
|
394
395
|
*
|
|
395
|
-
* Sits between `pkb-reminder` (35) and `now-md` (40)
|
|
396
|
-
* after
|
|
397
|
-
*
|
|
398
|
-
*
|
|
399
|
-
*
|
|
396
|
+
* Sits between `pkb-reminder` (35) and `now-md` (40). Because every
|
|
397
|
+
* after-memory-prefix splice lands at the memory-prefix boundary in
|
|
398
|
+
* ascending `order`, higher-order blocks end up closer to the memory
|
|
399
|
+
* prefix. The rendered layout is therefore `[<memory>dynamic</memory>,
|
|
400
|
+
* <info>memory-v2-static</info>, <NOW.md>, <system_reminder>,
|
|
401
|
+
* <knowledge_base>, ...user text]` when every PKB injector also fires.
|
|
402
|
+
* `countMemoryPrefixBlocks` treats the `<info>` static block as part of
|
|
403
|
+
* the memory prefix so `now-md` (40) splices after it.
|
|
400
404
|
*
|
|
401
405
|
* Gating:
|
|
402
406
|
* - `mode === "full"`.
|
|
@@ -419,14 +423,18 @@ const memoryV2StaticInjector: Injector = {
|
|
|
419
423
|
},
|
|
420
424
|
};
|
|
421
425
|
|
|
426
|
+
const INFO_CLOSE_TAG_RE = /<\/info\s*>/gi;
|
|
427
|
+
|
|
422
428
|
/**
|
|
423
|
-
* Wrap the static memory content in `<
|
|
424
|
-
* closing `</
|
|
425
|
-
* accidentally break out of the wrapper.
|
|
429
|
+
* Wrap the static memory content in `<info>...</info>`. Escapes any
|
|
430
|
+
* closing `</info>` inside the content so authored memory files cannot
|
|
431
|
+
* accidentally break out of the wrapper. Distinct from the dynamic
|
|
432
|
+
* activation block (which uses `<memory>...</memory>`) so downstream
|
|
433
|
+
* logic can address the two differently.
|
|
426
434
|
*/
|
|
427
435
|
function buildMemoryV2StaticBlock(content: string): string {
|
|
428
|
-
const escaped = content.replace(
|
|
429
|
-
return `<
|
|
436
|
+
const escaped = content.replace(INFO_CLOSE_TAG_RE, "</info>");
|
|
437
|
+
return `<info>\n${escaped}\n</info>`;
|
|
430
438
|
}
|
|
431
439
|
|
|
432
440
|
/**
|
|
@@ -491,6 +499,77 @@ const activeDocumentsInjector: Injector = {
|
|
|
491
499
|
},
|
|
492
500
|
};
|
|
493
501
|
|
|
502
|
+
/** Maximum open comments surfaced per document to limit context bloat. */
|
|
503
|
+
const DOCUMENT_COMMENTS_CAP = 10;
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Escape closing `</document_comments>` inside user-controlled strings so
|
|
507
|
+
* they cannot break out of the XML wrapper — same pattern as
|
|
508
|
+
* {@link buildPkbContextBlock} and {@link buildMemoryV2StaticBlock}.
|
|
509
|
+
*/
|
|
510
|
+
function escapeDocCommentTag(s: string): string {
|
|
511
|
+
return s.replace(/<\/document_comments\s*>/gi, "</document_comments>");
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* `document-comments` injector — order 46, prepend-user-tail.
|
|
516
|
+
*
|
|
517
|
+
* Surfaces open top-level comments on active documents so the assistant
|
|
518
|
+
* knows what feedback to address. For each active document, queries the
|
|
519
|
+
* comment store for open top-level comments (capped at
|
|
520
|
+
* {@link DOCUMENT_COMMENTS_CAP} most recent per document). Inline comments
|
|
521
|
+
* include the quoted anchor text; doc-level comments are labelled as such.
|
|
522
|
+
*
|
|
523
|
+
* Gating:
|
|
524
|
+
* - `mode === "full"`.
|
|
525
|
+
* - `activeDocuments` has at least one entry.
|
|
526
|
+
* - At least one document has open comments (returns null otherwise).
|
|
527
|
+
*/
|
|
528
|
+
const documentCommentsInjector: Injector = {
|
|
529
|
+
name: "document-comments",
|
|
530
|
+
order: DEFAULT_INJECTOR_ORDER.documentComments,
|
|
531
|
+
async produce(ctx: TurnContext): Promise<InjectionBlock | null> {
|
|
532
|
+
const inputs = readInjectionInputs(ctx);
|
|
533
|
+
const mode = inputs.mode ?? "full";
|
|
534
|
+
if (mode !== "full") return null;
|
|
535
|
+
const docs = inputs.activeDocuments;
|
|
536
|
+
if (!docs || docs.length === 0) return null;
|
|
537
|
+
|
|
538
|
+
const sections: string[] = [];
|
|
539
|
+
for (const doc of docs) {
|
|
540
|
+
const comments = listComments(doc.surfaceId, {
|
|
541
|
+
status: "open",
|
|
542
|
+
topLevelOnly: true,
|
|
543
|
+
}).slice(-DOCUMENT_COMMENTS_CAP);
|
|
544
|
+
if (comments.length === 0) continue;
|
|
545
|
+
|
|
546
|
+
const lines = comments.map((c) => {
|
|
547
|
+
const anchor =
|
|
548
|
+
c.anchorText != null ? escapeDocCommentTag(c.anchorText) : null;
|
|
549
|
+
const label =
|
|
550
|
+
anchor != null ? `inline, anchored to "${anchor}"` : "doc-level";
|
|
551
|
+
return `- Comment #${c.id} (${label}): "${escapeDocCommentTag(c.content)}"`;
|
|
552
|
+
});
|
|
553
|
+
sections.push(
|
|
554
|
+
`Document: "${escapeDocCommentTag(doc.title)}" (surface_id: "${doc.surfaceId}")\n${lines.join("\n")}`,
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
if (sections.length === 0) return null;
|
|
559
|
+
|
|
560
|
+
const text = `<document_comments>
|
|
561
|
+
Open comments on your documents. Address these by editing the document, then use comment_resolve to mark each resolved.
|
|
562
|
+
|
|
563
|
+
${sections.join("\n\n")}
|
|
564
|
+
</document_comments>`;
|
|
565
|
+
return {
|
|
566
|
+
id: "document-comments",
|
|
567
|
+
text,
|
|
568
|
+
placement: "prepend-user-tail",
|
|
569
|
+
};
|
|
570
|
+
},
|
|
571
|
+
};
|
|
572
|
+
|
|
494
573
|
/**
|
|
495
574
|
* `subagent-status` injector — order 50, append-user-tail.
|
|
496
575
|
*
|
|
@@ -626,6 +705,7 @@ export const defaultInjectorsPlugin: Plugin = {
|
|
|
626
705
|
memoryV2StaticInjector,
|
|
627
706
|
nowMdInjector,
|
|
628
707
|
activeDocumentsInjector,
|
|
708
|
+
documentCommentsInjector,
|
|
629
709
|
subagentStatusInjector,
|
|
630
710
|
slackMessagesInjector,
|
|
631
711
|
threadFocusInjector,
|
|
@@ -49,12 +49,8 @@ import semver from "semver";
|
|
|
49
49
|
import { z } from "zod";
|
|
50
50
|
|
|
51
51
|
import assistantPkg from "../../package.json" with { type: "json" };
|
|
52
|
-
import
|
|
53
|
-
|
|
54
|
-
PluginTool,
|
|
55
|
-
RiskLevel,
|
|
56
|
-
ToolExecutionResult,
|
|
57
|
-
} from "../tools/types.js";
|
|
52
|
+
import { finalizeTool } from "../tools/tool-defaults.js";
|
|
53
|
+
import type { LoadedTool, ToolDefinition } from "../tools/types.js";
|
|
58
54
|
import { getLogger } from "../util/logger.js";
|
|
59
55
|
import { registerPlugin } from "./registry.js";
|
|
60
56
|
import type {
|
|
@@ -62,7 +58,6 @@ import type {
|
|
|
62
58
|
PluginHookFn,
|
|
63
59
|
PluginHooks,
|
|
64
60
|
PluginManifest,
|
|
65
|
-
PluginToolRegistration,
|
|
66
61
|
} from "./types.js";
|
|
67
62
|
|
|
68
63
|
const PLUGIN_API_PEER_DEP = "@vellumai/plugin-api";
|
|
@@ -122,64 +117,6 @@ function deriveToolName(toolFileBaseName: string): string {
|
|
|
122
117
|
return toToolNameSegment(toolFileBaseName);
|
|
123
118
|
}
|
|
124
119
|
|
|
125
|
-
/**
|
|
126
|
-
* Defaults applied by {@link applyPluginToolDefaults} when a plugin tool
|
|
127
|
-
* omits one of the normally-required fields. Exported as a constant so
|
|
128
|
-
* tests and callers can reference the same source of truth.
|
|
129
|
-
*
|
|
130
|
-
* The default `execute` returns an error result so the model sees a clear
|
|
131
|
-
* "this tool isn't wired up" signal at call time. The plugin still loads
|
|
132
|
-
* cleanly — broken individual tools must never block daemon boot.
|
|
133
|
-
*/
|
|
134
|
-
export const PLUGIN_TOOL_DEFAULTS = Object.freeze({
|
|
135
|
-
description: "",
|
|
136
|
-
defaultRiskLevel: "medium" as RiskLevel,
|
|
137
|
-
input_schema: Object.freeze({
|
|
138
|
-
type: "object",
|
|
139
|
-
properties: {},
|
|
140
|
-
additionalProperties: false,
|
|
141
|
-
}) as object,
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Fill the four normally-required {@link PluginTool} fields with documented
|
|
146
|
-
* defaults when the author omitted them. Returns a {@link LoadedPluginTool}
|
|
147
|
-
* that is safe to register.
|
|
148
|
-
*/
|
|
149
|
-
function applyPluginToolDefaults(
|
|
150
|
-
tool: PluginTool,
|
|
151
|
-
name: string,
|
|
152
|
-
): LoadedPluginTool {
|
|
153
|
-
const description =
|
|
154
|
-
typeof tool.description === "string"
|
|
155
|
-
? tool.description
|
|
156
|
-
: PLUGIN_TOOL_DEFAULTS.description;
|
|
157
|
-
const defaultRiskLevel =
|
|
158
|
-
typeof tool.defaultRiskLevel === "string"
|
|
159
|
-
? tool.defaultRiskLevel
|
|
160
|
-
: PLUGIN_TOOL_DEFAULTS.defaultRiskLevel;
|
|
161
|
-
const input_schema =
|
|
162
|
-
tool.input_schema !== null &&
|
|
163
|
-
typeof tool.input_schema === "object"
|
|
164
|
-
? tool.input_schema
|
|
165
|
-
: PLUGIN_TOOL_DEFAULTS.input_schema;
|
|
166
|
-
const execute =
|
|
167
|
-
typeof tool.execute === "function"
|
|
168
|
-
? tool.execute
|
|
169
|
-
: async (): Promise<ToolExecutionResult> => ({
|
|
170
|
-
content: `plugin tool ${name} has no execute implementation`,
|
|
171
|
-
isError: true,
|
|
172
|
-
});
|
|
173
|
-
return {
|
|
174
|
-
...tool,
|
|
175
|
-
name,
|
|
176
|
-
description,
|
|
177
|
-
defaultRiskLevel,
|
|
178
|
-
input_schema,
|
|
179
|
-
execute,
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
|
|
183
120
|
/**
|
|
184
121
|
* Dynamic-import `absolutePath` and return its default export. Throws when
|
|
185
122
|
* the module has no default export — callers attribute the error.
|
|
@@ -339,17 +276,17 @@ async function buildPluginFromDir(pluginDir: string): Promise<Plugin> {
|
|
|
339
276
|
const hooks = await loadHooks(pluginDir, name);
|
|
340
277
|
if (hooks !== undefined) plugin.hooks = hooks;
|
|
341
278
|
|
|
342
|
-
const tools:
|
|
279
|
+
const tools: LoadedTool[] = [];
|
|
343
280
|
for (const { name: toolName, path: toolPath } of listSurfaceDir(
|
|
344
281
|
join(pluginDir, "tools"),
|
|
345
282
|
)) {
|
|
346
|
-
const tool = await importDefault<
|
|
283
|
+
const tool = await importDefault<ToolDefinition>(toolPath);
|
|
347
284
|
if (tool === null || typeof tool !== "object") {
|
|
348
285
|
throw new Error(
|
|
349
286
|
`external plugin ${name}: ${toolPath} default export must be an object`,
|
|
350
287
|
);
|
|
351
288
|
}
|
|
352
|
-
tools.push(
|
|
289
|
+
tools.push(finalizeTool(tool, deriveToolName(toolName)));
|
|
353
290
|
}
|
|
354
291
|
if (tools.length > 0) plugin.tools = tools;
|
|
355
292
|
|
package/src/plugins/types.ts
CHANGED
|
@@ -43,7 +43,7 @@ import type {
|
|
|
43
43
|
} from "../providers/types.js";
|
|
44
44
|
import type { SkillRoute } from "../runtime/skill-route-registry.js";
|
|
45
45
|
import type {
|
|
46
|
-
|
|
46
|
+
LoadedTool,
|
|
47
47
|
ToolContext,
|
|
48
48
|
ToolExecutionResult,
|
|
49
49
|
} from "../tools/types.js";
|
|
@@ -1007,19 +1007,6 @@ export interface Injector {
|
|
|
1007
1007
|
// `PluginSkillRegistration` shape below so plugins can declare
|
|
1008
1008
|
// catalog-discoverable skills today.
|
|
1009
1009
|
|
|
1010
|
-
/**
|
|
1011
|
-
* Tool registration contributed by a plugin. Uses the narrow
|
|
1012
|
-
* {@link LoadedPluginTool} shape. External plugin authors declare the
|
|
1013
|
-
* nameless `PluginTool` file shape; the loader derives `name` from the
|
|
1014
|
-
* `tools/<name>.ts` basename before storing it on `plugin.tools`. Authors
|
|
1015
|
-
* also leave category / ownership metadata to the bootstrap, which stamps
|
|
1016
|
-
* `category: "plugin"`, `origin: "plugin"`, and
|
|
1017
|
-
* `ownerPluginId: <plugin.name>` before handing the batch to
|
|
1018
|
-
* `registerPluginTools`. The registration boundary synthesizes
|
|
1019
|
-
* `getDefinition()` from `{name, description, input_schema}` so the canonical
|
|
1020
|
-
* {@link Tool} interface used by the internal registry stays unchanged.
|
|
1021
|
-
*/
|
|
1022
|
-
export type PluginToolRegistration = LoadedPluginTool;
|
|
1023
1010
|
/**
|
|
1024
1011
|
* HTTP route registration contributed by a plugin. Plugins express routes as
|
|
1025
1012
|
* {@link SkillRoute} values — the same shape the skill-route registry
|
|
@@ -1120,8 +1107,16 @@ export interface Plugin {
|
|
|
1120
1107
|
manifest: PluginManifest;
|
|
1121
1108
|
/** Lifecycle hooks (init, shutdown). See {@link PluginHooks}. */
|
|
1122
1109
|
hooks?: PluginHooks;
|
|
1123
|
-
/**
|
|
1124
|
-
|
|
1110
|
+
/**
|
|
1111
|
+
* Tool registrations visible to the model. External plugin authors
|
|
1112
|
+
* declare the nameless `ToolDefinition` file shape (from
|
|
1113
|
+
* `@vellumai/plugin-api`); the loader derives `name` from the
|
|
1114
|
+
* `tools/<name>.ts` basename and runs the definition through
|
|
1115
|
+
* `finalizeTool` to fill omitted required fields, producing the
|
|
1116
|
+
* `LoadedTool` values stored here. Category / ownership metadata is
|
|
1117
|
+
* stamped by `registerPluginTools` at registration time.
|
|
1118
|
+
*/
|
|
1119
|
+
tools?: LoadedTool[];
|
|
1125
1120
|
/** HTTP route registrations served by the assistant. */
|
|
1126
1121
|
routes?: PluginRouteRegistration[];
|
|
1127
1122
|
/** Skill registrations loaded at startup. */
|
|
@@ -71,10 +71,23 @@ export async function injectAuxAssistantMessage(params: {
|
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
// The injected aux message bumps `lastMessageAt`, which can move the
|
|
75
|
+
// row in the paginated sidebar window — that's a shape change. macOS
|
|
76
|
+
// refreshes its full list on `conversation_list_invalidated`; web
|
|
77
|
+
// refreshes via the paired `sync_changed` `conversationsList` tag.
|
|
78
|
+
//
|
|
79
|
+
// TODO(electron-cutover): drop the `conversation_list_invalidated`
|
|
80
|
+
// emission once macOS migrates to the Electron client and consumes
|
|
81
|
+
// `sync_changed` directly. See `runtime/sync/resource-sync-events.ts`
|
|
82
|
+
// for the symmetric helper used by route handlers.
|
|
83
|
+
params.broadcastMessage(
|
|
84
|
+
{
|
|
85
|
+
type: "conversation_list_invalidated",
|
|
86
|
+
reason: "reordered",
|
|
87
|
+
},
|
|
88
|
+
undefined,
|
|
89
|
+
{ targetInterfaceId: "macos" },
|
|
90
|
+
);
|
|
78
91
|
params.broadcastMessage({
|
|
79
92
|
type: "sync_changed",
|
|
80
93
|
tags: [
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
* user-message injection that replaced it.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { mkdirSync } from "node:fs";
|
|
9
|
+
import { copyFileSync, mkdirSync, readFileSync } from "node:fs";
|
|
10
|
+
import { join } from "node:path";
|
|
10
11
|
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
11
12
|
|
|
12
13
|
const TEST_DIR = process.env.VELLUM_WORKSPACE_DIR!;
|
|
@@ -57,7 +58,8 @@ mock.module("../../config/loader.js", () => ({
|
|
|
57
58
|
setNestedValue: () => {},
|
|
58
59
|
}));
|
|
59
60
|
|
|
60
|
-
const { buildSystemPrompt } =
|
|
61
|
+
const { buildSystemPrompt, maybeReseedBootstrapForCohort } =
|
|
62
|
+
await import("../system-prompt.js");
|
|
61
63
|
|
|
62
64
|
describe("buildSystemPrompt — tool routing guidance", () => {
|
|
63
65
|
beforeEach(() => {
|
|
@@ -70,3 +72,45 @@ describe("buildSystemPrompt — tool routing guidance", () => {
|
|
|
70
72
|
expect(result).not.toContain("ask_question");
|
|
71
73
|
});
|
|
72
74
|
});
|
|
75
|
+
|
|
76
|
+
describe("maybeReseedBootstrapForCohort — content-automation template", () => {
|
|
77
|
+
const templatesDir = join(import.meta.dirname!, "..", "templates");
|
|
78
|
+
|
|
79
|
+
beforeEach(() => {
|
|
80
|
+
mkdirSync(TEST_DIR, { recursive: true });
|
|
81
|
+
// Seed the workspace with the generic BOOTSTRAP.md so the cohort
|
|
82
|
+
// reseed detects it as an unmodified template and overwrites it.
|
|
83
|
+
copyFileSync(
|
|
84
|
+
join(templatesDir, "BOOTSTRAP.md"),
|
|
85
|
+
join(TEST_DIR, "BOOTSTRAP.md"),
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
function reseedAndRead(): string {
|
|
90
|
+
maybeReseedBootstrapForCohort("content-automation");
|
|
91
|
+
return readFileSync(join(TEST_DIR, "BOOTSTRAP.md"), "utf-8");
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
test("loads the geo-writing skill on first turn", () => {
|
|
95
|
+
const content = reseedAndRead();
|
|
96
|
+
expect(content).toContain("geo-writing");
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test("uses skill-first onboarding approach", () => {
|
|
100
|
+
const content = reseedAndRead();
|
|
101
|
+
expect(content).toContain("Skill-First Onboarding");
|
|
102
|
+
expect(content).toContain("The skill is the onboarding");
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test("includes comment-driven edit loop", () => {
|
|
106
|
+
const content = reseedAndRead();
|
|
107
|
+
expect(content).toContain("comment-driven");
|
|
108
|
+
expect(content).toContain("comment_resolve");
|
|
109
|
+
expect(content).toContain("document_update");
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test("references VOICE.md for voice capture", () => {
|
|
113
|
+
const content = reseedAndRead();
|
|
114
|
+
expect(content).toContain("VOICE.md");
|
|
115
|
+
});
|
|
116
|
+
});
|
|
@@ -54,8 +54,9 @@ mock.module("../../config/loader.js", () => ({
|
|
|
54
54
|
setNestedValue: () => {},
|
|
55
55
|
}));
|
|
56
56
|
|
|
57
|
-
const { buildSystemPrompt, ensurePromptFiles
|
|
58
|
-
|
|
57
|
+
const { buildSystemPrompt, ensurePromptFiles } = await import(
|
|
58
|
+
"../system-prompt.js"
|
|
59
|
+
);
|
|
59
60
|
|
|
60
61
|
describe("task_progress hint in parallel-tool-calls section", () => {
|
|
61
62
|
beforeEach(() => {
|
|
@@ -85,11 +86,4 @@ describe("task_progress hint in parallel-tool-calls section", () => {
|
|
|
85
86
|
expect(withExcludePrefix).toContain("task_progress");
|
|
86
87
|
});
|
|
87
88
|
|
|
88
|
-
test("hint lives in the static (cached) block before SYSTEM_PROMPT_CACHE_BOUNDARY", () => {
|
|
89
|
-
const result = buildSystemPrompt();
|
|
90
|
-
const boundaryIdx = result.indexOf(SYSTEM_PROMPT_CACHE_BOUNDARY);
|
|
91
|
-
expect(boundaryIdx).toBeGreaterThan(-1);
|
|
92
|
-
const staticBlock = result.slice(0, boundaryIdx);
|
|
93
|
-
expect(staticBlock).toContain("task_progress");
|
|
94
|
-
});
|
|
95
89
|
});
|
|
@@ -19,6 +19,20 @@ export const TOOL_DISPLAY_NAMES: Record<string, string> = {
|
|
|
19
19
|
"apple-notes": "Apple Notes",
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Map of known prior-assistant IDs (from the client onboarding UI) to display names.
|
|
24
|
+
* Unknown IDs pass through with first-letter capitalization via `normalizePriorAssistants`.
|
|
25
|
+
*/
|
|
26
|
+
export const PRIOR_ASSISTANT_DISPLAY_NAMES: Record<string, string> = {
|
|
27
|
+
chatgpt: "ChatGPT",
|
|
28
|
+
claude: "Claude",
|
|
29
|
+
openclaw: "OpenClaw",
|
|
30
|
+
hermes: "Hermes",
|
|
31
|
+
manus: "Manus",
|
|
32
|
+
gemini: "Gemini",
|
|
33
|
+
copilot: "Copilot",
|
|
34
|
+
};
|
|
35
|
+
|
|
22
36
|
/**
|
|
23
37
|
* Map of known task IDs to plain-language labels describing what the assistant
|
|
24
38
|
* does for each task category.
|
|
@@ -56,14 +70,28 @@ export function normalizeTasks(tasks: string[]): string[] {
|
|
|
56
70
|
return tasks.map((id) => TASK_DISPLAY_LABELS[id] ?? id);
|
|
57
71
|
}
|
|
58
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Maps each prior-assistant ID through `PRIOR_ASSISTANT_DISPLAY_NAMES`,
|
|
75
|
+
* falling back to first-letter capitalization for unknown IDs.
|
|
76
|
+
*/
|
|
77
|
+
export function normalizePriorAssistants(assistants: string[]): string[] {
|
|
78
|
+
return assistants.map(
|
|
79
|
+
(id) => PRIOR_ASSISTANT_DISPLAY_NAMES[id] ?? capitalizeFirst(id),
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
59
83
|
export interface NormalizedOnboarding {
|
|
60
84
|
preferredName?: string;
|
|
61
85
|
commonWork: string[];
|
|
62
86
|
dailyTools: string[];
|
|
63
87
|
tone?: string;
|
|
64
88
|
assistantName?: string;
|
|
89
|
+
priorAssistants?: string[];
|
|
65
90
|
googleConnected?: boolean;
|
|
66
91
|
googleServices?: string[];
|
|
92
|
+
cohort?: string;
|
|
93
|
+
websiteUrl?: string;
|
|
94
|
+
contentSourceUrl?: string;
|
|
67
95
|
}
|
|
68
96
|
|
|
69
97
|
const SCOPE_SERVICE_MAP: Record<string, string> = {
|
|
@@ -103,5 +131,17 @@ export function normalizeOnboardingContext(
|
|
|
103
131
|
googleServices: ctx.googleConnected
|
|
104
132
|
? deriveGoogleServices(ctx.googleScopes)
|
|
105
133
|
: undefined,
|
|
134
|
+
priorAssistants: ctx.priorAssistants?.length
|
|
135
|
+
? normalizePriorAssistants(ctx.priorAssistants)
|
|
136
|
+
: undefined,
|
|
137
|
+
cohort: ctx.cohort,
|
|
138
|
+
websiteUrl:
|
|
139
|
+
typeof ctx.websiteUrl === "string"
|
|
140
|
+
? ctx.websiteUrl.trim().replace(/[\r\n\t]/g, "") || undefined
|
|
141
|
+
: undefined,
|
|
142
|
+
contentSourceUrl:
|
|
143
|
+
typeof ctx.contentSourceUrl === "string"
|
|
144
|
+
? ctx.contentSourceUrl.trim().replace(/[\r\n\t]/g, "") || undefined
|
|
145
|
+
: undefined,
|
|
106
146
|
};
|
|
107
147
|
}
|
|
@@ -77,31 +77,46 @@ function resolveUserFilename(
|
|
|
77
77
|
): string | null {
|
|
78
78
|
let filename: string | null = null;
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
filename = guardian.contact.userFile ?? "guardian.md";
|
|
87
|
-
}
|
|
88
|
-
} else if (trustContext.requesterExternalUserId) {
|
|
89
|
-
// Channel-routed request — look up contact by channel identity
|
|
90
|
-
const contactWithChannels = findContactByChannelExternalId(
|
|
91
|
-
trustContext.sourceChannel,
|
|
92
|
-
trustContext.requesterExternalUserId,
|
|
93
|
-
);
|
|
94
|
-
if (contactWithChannels) {
|
|
95
|
-
filename = contactWithChannels.userFile ?? null;
|
|
96
|
-
} else if (trustContext.trustClass === "guardian") {
|
|
97
|
-
// Managed desktop: the JWT principal ID used as requesterExternalUserId
|
|
98
|
-
// may differ from the contact channel's external_user_id (they are
|
|
99
|
-
// separate identity concepts). Fall back to the channel-type guardian.
|
|
100
|
-
const guardian = findGuardianForChannel(trustContext.sourceChannel);
|
|
80
|
+
try {
|
|
81
|
+
if (trustContext === undefined) {
|
|
82
|
+
// Desktop / native (no gateway) — resolve via guardian contact,
|
|
83
|
+
// preferring the vellum-channel guardian when multiple exist.
|
|
84
|
+
const vellumGuardian = findGuardianForChannel("vellum");
|
|
85
|
+
const guardian = vellumGuardian ?? listGuardianChannels();
|
|
101
86
|
if (guardian) {
|
|
102
87
|
filename = guardian.contact.userFile ?? "guardian.md";
|
|
103
88
|
}
|
|
89
|
+
} else if (trustContext.requesterExternalUserId) {
|
|
90
|
+
// Channel-routed request — look up contact by channel identity
|
|
91
|
+
const contactWithChannels = findContactByChannelExternalId(
|
|
92
|
+
trustContext.sourceChannel,
|
|
93
|
+
trustContext.requesterExternalUserId,
|
|
94
|
+
);
|
|
95
|
+
if (contactWithChannels) {
|
|
96
|
+
filename = contactWithChannels.userFile ?? null;
|
|
97
|
+
} else if (trustContext.trustClass === "guardian") {
|
|
98
|
+
// Managed desktop: the JWT principal ID used as requesterExternalUserId
|
|
99
|
+
// may differ from the contact channel's external_user_id (they are
|
|
100
|
+
// separate identity concepts). Fall back to the channel-type guardian.
|
|
101
|
+
const guardian = findGuardianForChannel(trustContext.sourceChannel);
|
|
102
|
+
if (guardian) {
|
|
103
|
+
filename = guardian.contact.userFile ?? "guardian.md";
|
|
104
|
+
}
|
|
105
|
+
}
|
|
104
106
|
}
|
|
107
|
+
} catch (err) {
|
|
108
|
+
// Contacts table may be absent — happens during early bootstrap
|
|
109
|
+
// before migrations run, in CLI smoke commands that don't touch
|
|
110
|
+
// the DB, and in tests that build the system prompt without first
|
|
111
|
+
// initializing a schema. Treat the same as "no guardian found"
|
|
112
|
+
// so callers fall back to `users/default.md`. Mirrors the same
|
|
113
|
+
// try/catch pattern used by `renderConnectedServices()` around
|
|
114
|
+
// `listConnections()`.
|
|
115
|
+
log.debug(
|
|
116
|
+
{ err: err instanceof Error ? err.message : String(err) },
|
|
117
|
+
"Contacts lookup failed during persona resolution; treating as no guardian",
|
|
118
|
+
);
|
|
119
|
+
return null;
|
|
105
120
|
}
|
|
106
121
|
|
|
107
122
|
// Validate basename to prevent path traversal
|