@vellumai/assistant 0.8.1 → 0.8.2
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 -7
- package/Dockerfile +75 -1
- package/bun.lock +11 -1
- package/docker-entrypoint.sh +5 -0
- package/docker-init-apt-root.sh +94 -0
- package/docker-kata-apt-env.sh +39 -0
- package/docs/plugins.md +88 -47
- package/docs/skills.md +9 -7
- package/examples/plugins/echo/README.md +27 -27
- package/examples/plugins/echo/package.json +3 -0
- package/examples/plugins/echo/register.ts +31 -31
- package/node_modules/@vellumai/slack-text/src/index.test.ts +114 -14
- package/node_modules/@vellumai/slack-text/src/index.ts +82 -18
- package/openapi.yaml +325 -3
- package/package.json +3 -1
- package/scripts/generate-openapi.ts +83 -10
- package/scripts/sync-llm-catalog.ts +2 -2
- package/scripts/sync-web-search-catalog.ts +47 -25
- package/src/__tests__/agent-image-optimize.test.ts +11 -3
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +131 -0
- package/src/__tests__/anthropic-provider.test.ts +45 -0
- package/src/__tests__/app-builder-tool-scripts.test.ts +9 -3
- package/src/__tests__/app-executors.test.ts +220 -4
- package/src/__tests__/auto-analysis-end-to-end.test.ts +35 -0
- package/src/__tests__/bundled-asset.test.ts +6 -6
- package/src/__tests__/channel-availability-routes.test.ts +206 -0
- package/src/__tests__/channel-delivery-store.test.ts +289 -1
- package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -1
- package/src/__tests__/clawhub.test.ts +75 -16
- package/src/__tests__/compactor-tail-resolution.test.ts +41 -0
- package/src/__tests__/config-schema.test.ts +21 -0
- package/src/__tests__/config-set-route.test.ts +80 -0
- package/src/__tests__/config-sounds-sync.test.ts +97 -0
- package/src/__tests__/config-watcher-skill-reseed.test.ts +453 -0
- package/src/__tests__/context-search-conversations-source.test.ts +117 -2
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -1
- package/src/__tests__/context-search-workspace-source.test.ts +7 -0
- package/src/__tests__/context-token-estimator.test.ts +1 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +4 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +92 -92
- package/src/__tests__/conversation-agent-loop.test.ts +2 -0
- package/src/__tests__/conversation-error.test.ts +42 -3
- package/src/__tests__/conversation-fork-crud.test.ts +82 -0
- package/src/__tests__/conversation-inference-profile-route.test.ts +40 -4
- package/src/__tests__/conversation-lifecycle.test.ts +173 -0
- package/src/__tests__/conversation-message-sync-tags.test.ts +97 -0
- package/src/__tests__/conversation-pairing.test.ts +54 -0
- package/src/__tests__/conversation-process-callsite.test.ts +4 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +5 -1
- package/src/__tests__/conversation-queue.test.ts +4 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +76 -9
- package/src/__tests__/conversation-slash-queue.test.ts +59 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +4 -1
- package/src/__tests__/conversation-surfaces-table-action.test.ts +360 -0
- package/src/__tests__/conversation-sync-tags.test.ts +235 -0
- 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-security-invariants.test.ts +3 -2
- package/src/__tests__/db-slack-external-content-normalization.test.ts +301 -0
- package/src/__tests__/delete-managed-skill-tool.test.ts +55 -13
- package/src/__tests__/disk-pressure-tools.test.ts +1 -0
- package/src/__tests__/dm-backfill.test.ts +121 -10
- package/src/__tests__/document-tool-security.test.ts +258 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/edit-propagation.test.ts +33 -0
- package/src/__tests__/empty-response-pipeline.test.ts +0 -4
- package/src/__tests__/external-plugin-loader.test.ts +60 -36
- package/src/__tests__/filing-service.test.ts +140 -0
- package/src/__tests__/get-skill-detail-audit.test.ts +0 -4
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +43 -62
- package/src/__tests__/helpers/tar-fixtures.ts +39 -0
- package/src/__tests__/helpers/wait-for.ts +21 -0
- package/src/__tests__/history-repair-pipeline.test.ts +0 -3
- package/src/__tests__/history-repair.test.ts +73 -0
- package/src/__tests__/host-app-control-proxy.test.ts +266 -10
- package/src/__tests__/image-credentials.test.ts +1 -1
- package/src/__tests__/inbound-slack-persistence.test.ts +2 -0
- package/src/__tests__/inference-no-mode-boot-e2e.test.ts +1 -1
- package/src/__tests__/inference-profile-reaper.test.ts +4 -2
- package/src/__tests__/inference-profile-session-handler.test.ts +18 -6
- package/src/__tests__/inference-profile-session-ipc.test.ts +17 -5
- package/src/__tests__/injector-chain.test.ts +10 -8
- package/src/__tests__/install-skill-routing.test.ts +155 -37
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +92 -3
- package/src/__tests__/list-messages-page-latest.test.ts +55 -0
- package/src/__tests__/llm-call-pipeline.test.ts +0 -3
- package/src/__tests__/llm-catalog-parity.test.ts +55 -13
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +34 -0
- package/src/__tests__/llm-request-log-source-factory.test.ts +29 -53
- package/src/__tests__/llm-usage-store.test.ts +114 -0
- package/src/__tests__/managed-profile-guard.test.ts +31 -29
- package/src/__tests__/managed-skill-lifecycle.test.ts +109 -18
- package/src/__tests__/managed-store.test.ts +84 -192
- package/src/__tests__/media-generate-image.test.ts +1 -1
- package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -2
- package/src/__tests__/messages-after-tiebreaker.test.ts +122 -0
- package/src/__tests__/oauth-commands-routes.test.ts +168 -16
- package/src/__tests__/oauth-provider-profiles.test.ts +9 -0
- package/src/__tests__/openai-provider.test.ts +24 -0
- package/src/__tests__/openai-responses-cutover-guard.test.ts +17 -9
- package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -2
- package/src/__tests__/persistence-pipeline.test.ts +0 -2
- package/src/__tests__/{managed-proxy-context.test.ts → platform-proxy-context.test.ts} +1 -1
- package/src/__tests__/platform.test.ts +2 -0
- package/src/__tests__/plugin-api-shim.test.ts +125 -0
- package/src/__tests__/plugin-bootstrap.test.ts +10 -36
- package/src/__tests__/plugin-external-api.test.ts +68 -0
- package/src/__tests__/plugin-registry.test.ts +0 -77
- package/src/__tests__/plugin-route-contribution.test.ts +0 -1
- package/src/__tests__/plugin-skill-contribution.test.ts +0 -2
- package/src/__tests__/plugin-tool-contribution.test.ts +16 -15
- package/src/__tests__/plugin-types.test.ts +3 -13
- package/src/__tests__/process-message-background-slack.test.ts +8 -1
- package/src/__tests__/process-message-display-content.test.ts +421 -0
- package/src/__tests__/provider-catalog-visibility.test.ts +142 -0
- package/src/__tests__/provider-error-scenarios.test.ts +111 -0
- package/src/__tests__/{provider-managed-proxy-integration.test.ts → provider-platform-proxy-integration.test.ts} +8 -8
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +65 -13
- package/src/__tests__/schedule-routes.test.ts +50 -3
- package/src/__tests__/schedule-store.test.ts +94 -0
- package/src/__tests__/scheduler-reuse-conversation.test.ts +54 -7
- package/src/__tests__/schema-transforms.test.ts +20 -0
- package/src/__tests__/search-skills-unified.test.ts +0 -5
- package/src/__tests__/server-history-render.test.ts +43 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +0 -12
- package/src/__tests__/skill-load-tool.test.ts +27 -89
- package/src/__tests__/skill-memory.test.ts +23 -3
- package/src/__tests__/skills-file-content-endpoint.test.ts +9 -38
- package/src/__tests__/skills-files-catalog-fallback.test.ts +0 -3
- package/src/__tests__/skills-install-extract.test.ts +49 -38
- package/src/__tests__/skills-install-staging.test.ts +159 -0
- package/src/__tests__/skills-uninstall.test.ts +9 -41
- package/src/__tests__/skills.test.ts +51 -58
- package/src/__tests__/slack-channel-config.test.ts +9 -0
- package/src/__tests__/subagent-tool-filtering.test.ts +50 -0
- package/src/__tests__/system-prompt.test.ts +737 -63
- package/src/__tests__/terminal-tools.test.ts +28 -1
- package/src/__tests__/thread-backfill.test.ts +557 -27
- package/src/__tests__/title-generate-pipeline.test.ts +0 -13
- package/src/__tests__/token-estimate-pipeline.test.ts +0 -3
- package/src/__tests__/tool-error-pipeline.test.ts +0 -3
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -5
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -1
- package/src/__tests__/tool-executor.test.ts +16 -4
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -12
- package/src/__tests__/turn-events-store.test.ts +256 -0
- package/src/__tests__/twilio-routes.test.ts +4 -0
- package/src/__tests__/user-plugin-loader.test.ts +0 -7
- package/src/__tests__/voice-session-bridge.test.ts +198 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +32 -10
- package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +115 -3
- package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +50 -0
- package/src/__tests__/workspace-migration-073-repair-recall-callsite-empty-profile.test.ts +153 -0
- package/src/__tests__/workspace-migration-085-memory-v2-bm25-b-reembed-disabled-v2-pages.test.ts +220 -0
- package/src/__tests__/workspace-migration-086-revert-stale-gemini-mis-rewrites.test.ts +269 -0
- package/src/__tests__/workspace-migration-remove-legacy-skills-index.test.ts +309 -0
- package/src/__tests__/workspace-migrations-runner.test.ts +111 -3
- package/src/acp/resolve-agent.ts +1 -1
- package/src/agent/image-optimize.ts +13 -5
- package/src/calls/voice-session-bridge.ts +61 -42
- package/src/channels/types.ts +108 -0
- package/src/cli/__tests__/unknown-command.test.ts +24 -0
- package/src/cli/commands/__tests__/changelog.test.ts +304 -319
- package/src/cli/commands/__tests__/schedules.test.ts +491 -0
- package/src/cli/commands/changelog.ts +106 -42
- package/src/cli/commands/conversations.ts +102 -17
- package/src/cli/commands/default-action.ts +10 -53
- package/src/cli/commands/notifications.ts +329 -317
- package/src/cli/commands/plugins.ts +185 -0
- package/src/cli/commands/schedules.ts +391 -0
- package/src/cli/commands/telemetry.ts +40 -0
- package/src/cli/lib/__tests__/cli-colors.test.ts +48 -0
- package/src/cli/lib/__tests__/confirm-prompt.test.ts +159 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +355 -0
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +154 -0
- package/src/cli/lib/__tests__/uninstall-plugin.test.ts +124 -0
- package/src/cli/lib/__tests__/unknown-command.test.ts +106 -0
- package/src/cli/lib/cli-colors.ts +12 -0
- package/src/cli/lib/confirm-prompt.ts +79 -0
- package/src/cli/lib/install-from-github.ts +304 -0
- package/src/cli/lib/list-installed-plugins.ts +137 -0
- package/src/cli/lib/uninstall-plugin.ts +82 -0
- package/src/cli/lib/unknown-command.ts +111 -0
- package/src/cli/program.ts +38 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +23 -21
- package/src/config/bundled-skills/app-builder/TOOLS.json +7 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +15 -52
- package/src/config/bundled-skills/document/SKILL.md +23 -3
- package/src/config/bundled-skills/document/TOOLS.json +53 -0
- package/src/config/bundled-skills/document/tools/document-delete.ts +12 -0
- package/src/config/bundled-skills/document/tools/document-list.ts +12 -0
- package/src/config/bundled-skills/document/tools/document-read.ts +12 -0
- package/src/config/bundled-skills/skill-management/SKILL.md +2 -2
- package/src/config/bundled-skills/skill-management/TOOLS.json +7 -7
- package/src/config/bundled-tool-registry.ts +6 -0
- package/src/config/feature-flag-registry.json +41 -1
- package/src/config/loader.ts +64 -38
- package/src/config/schema.ts +7 -10
- package/src/config/schemas/__tests__/llm-request-logs.test.ts +36 -0
- package/src/config/schemas/channels.ts +8 -0
- package/src/config/schemas/compaction.ts +28 -0
- package/src/config/schemas/heartbeat.ts +9 -0
- package/src/config/schemas/llm-request-logs.ts +31 -7
- package/src/config/schemas/llm.ts +3 -0
- package/src/config/schemas/memory-retrieval.ts +18 -0
- package/src/config/schemas/tools.ts +14 -0
- package/src/config/skills.ts +3 -96
- package/src/context/compactor.ts +1047 -0
- package/src/context/token-estimator.ts +2 -2
- package/src/context/window-manager.ts +197 -1520
- package/src/credential-execution/managed-catalog.ts +37 -0
- package/src/credential-health/credential-health-service.ts +280 -19
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +34 -0
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +138 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +74 -0
- package/src/daemon/approval-generators.ts +8 -6
- package/src/daemon/config-watcher.ts +94 -31
- package/src/daemon/conversation-agent-loop.ts +169 -9
- package/src/daemon/conversation-error.ts +171 -37
- package/src/daemon/conversation-lifecycle.ts +53 -40
- package/src/daemon/conversation-messaging.ts +25 -6
- package/src/daemon/conversation-process.ts +49 -12
- package/src/daemon/conversation-runtime-assembly.ts +16 -1
- package/src/daemon/conversation-slash.ts +12 -5
- package/src/daemon/conversation-store.ts +11 -4
- package/src/daemon/conversation-tool-setup.ts +39 -7
- package/src/daemon/conversation.ts +33 -1
- package/src/daemon/external-plugins-bootstrap.ts +217 -181
- package/src/daemon/first-greeting.ts +22 -2
- package/src/daemon/handlers/config-model.ts +6 -5
- package/src/daemon/handlers/config-slack-channel.ts +15 -3
- package/src/daemon/handlers/shared.ts +14 -5
- package/src/daemon/handlers/skills.ts +111 -108
- package/src/daemon/history-repair.ts +28 -1
- package/src/daemon/host-app-control-proxy.ts +98 -23
- package/src/daemon/lifecycle.ts +45 -35
- package/src/daemon/meet-host-supervisor.ts +5 -4
- package/src/daemon/memory-v2-startup.ts +49 -0
- package/src/daemon/message-protocol.ts +1 -0
- package/src/daemon/message-types/conversations.ts +25 -0
- package/src/daemon/message-types/messages.ts +61 -0
- package/src/daemon/message-types/subagents.ts +1 -0
- package/src/daemon/message-types/sync.ts +1 -0
- package/src/daemon/pkb-reminder-builder.test.ts +1 -1
- package/src/daemon/pkb-reminder-builder.ts +1 -1
- package/src/daemon/plugin-source-watcher.ts +146 -0
- package/src/daemon/process-message.ts +21 -3
- package/src/daemon/server.ts +11 -2
- package/src/daemon/skill-memory-refresh.ts +29 -0
- package/src/documents/document-store.ts +221 -3
- package/src/embedded/plugin-api.ts +40 -0
- package/src/filing/filing-service.ts +39 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +91 -6
- package/src/heartbeat/heartbeat-run-store.ts +2 -1
- package/src/heartbeat/heartbeat-service.ts +41 -0
- package/src/home/__tests__/feed-types.test.ts +40 -0
- package/src/home/feed-types.ts +22 -0
- package/src/home/post-connect-feed.ts +1 -0
- package/src/index.ts +18 -1
- package/src/live-voice/__tests__/live-voice-stt.test.ts +57 -0
- package/src/mcp/client.ts +20 -4
- package/src/media/image-credentials.ts +3 -3
- package/src/memory/__tests__/bookmark-crud.test.ts +33 -27
- package/src/memory/__tests__/conversation-queries.test.ts +263 -0
- package/src/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +113 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +119 -14
- package/src/memory/__tests__/message-content.test.ts +35 -0
- package/src/memory/bookmark-crud.ts +42 -10
- package/src/memory/context-search/sources/conversations.ts +62 -2
- package/src/memory/context-search/sources/workspace.ts +4 -0
- package/src/memory/conversation-crud.ts +63 -19
- package/src/memory/conversation-queries.ts +110 -10
- package/src/memory/db-init.ts +6 -0
- package/src/memory/delivery-crud.ts +152 -5
- package/src/memory/embedding-backend.ts +4 -4
- package/src/memory/external-conversation-store.ts +66 -5
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +66 -9
- package/src/memory/graph/conversation-graph-memory.ts +31 -15
- package/src/memory/graph/tools.ts +3 -3
- package/src/memory/indexer.ts +34 -29
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +73 -0
- package/src/memory/jobs/embed-concept-page.ts +20 -11
- package/src/memory/jobs-worker.ts +6 -1
- package/src/memory/llm-request-log-source-clickhouse.ts +17 -10
- package/src/memory/llm-request-log-source.ts +19 -52
- package/src/memory/llm-usage-store.ts +125 -5
- package/src/memory/memory-retrospective-startup-cleanup.ts +72 -5
- package/src/memory/message-content.ts +1 -1
- package/src/memory/migrations/109-external-conversation-bindings.ts +15 -4
- package/src/memory/migrations/229-delete-private-conversations.test.ts +38 -1
- package/src/memory/migrations/229-delete-private-conversations.ts +7 -0
- package/src/memory/migrations/247-external-conversation-binding-thread-id.ts +78 -0
- package/src/memory/migrations/248-create-onboarding-events.ts +21 -0
- package/src/memory/migrations/249-normalize-slack-external-content.ts +240 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/onboarding-events-store.ts +106 -0
- package/src/memory/schema/bookmarks.ts +0 -2
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/inference.ts +1 -3
- package/src/memory/schema/infrastructure.ts +12 -0
- package/src/memory/turn-events-store.ts +127 -2
- package/src/memory/v2/__tests__/activation.test.ts +0 -8
- package/src/memory/v2/__tests__/injection.test.ts +98 -8
- package/src/memory/v2/__tests__/migration.test.ts +87 -0
- package/src/memory/v2/__tests__/page-index.test.ts +83 -0
- package/src/memory/v2/__tests__/prompts-router.test.ts +58 -6
- package/src/memory/v2/__tests__/qdrant.test.ts +66 -3
- package/src/memory/v2/__tests__/router.test.ts +15 -0
- package/src/memory/v2/__tests__/skill-store.test.ts +387 -8
- package/src/memory/v2/injection.ts +32 -6
- package/src/memory/v2/migration.ts +49 -19
- package/src/memory/v2/page-index.ts +35 -5
- package/src/memory/v2/prompts/router.ts +11 -8
- package/src/memory/v2/prompts/sweep.ts +2 -2
- package/src/memory/v2/qdrant.ts +135 -7
- package/src/memory/v2/router.ts +9 -8
- package/src/memory/v2/skill-store.ts +120 -35
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +45 -5
- package/src/messaging/providers/slack/__tests__/download.test.ts +231 -0
- package/src/messaging/providers/slack/adapter.ts +43 -5
- package/src/messaging/providers/slack/client.ts +27 -0
- package/src/messaging/providers/slack/deep-link.ts +65 -0
- package/src/messaging/providers/slack/download.ts +104 -0
- package/src/messaging/providers/slack/message-metadata.test.ts +32 -0
- package/src/messaging/providers/slack/message-metadata.ts +27 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +134 -0
- package/src/messaging/providers/slack/render-transcript.ts +69 -5
- package/src/messaging/providers/slack/types.ts +20 -1
- package/src/notifications/conversation-pairing.ts +2 -1
- package/src/notifications/decision-engine.ts +2 -1
- package/src/notifications/emit-signal.ts +20 -1
- package/src/notifications/home-feed-side-effect.ts +54 -0
- package/src/notifications/signal.ts +3 -1
- package/src/oauth/connection-resolver.ts +8 -4
- package/src/oauth/platform-connection.ts +6 -2
- package/src/oauth/seed-providers.ts +10 -1
- package/src/permissions/checker.ts +2 -0
- package/src/permissions/ipc-risk-types.ts +1 -0
- package/src/permissions/question-prompter.test.ts +416 -0
- package/src/permissions/question-prompter.ts +294 -0
- package/src/platform/client.test.ts +1 -1
- package/src/platform/client.ts +1 -1
- package/src/plugin-api/constants.ts +26 -0
- package/src/plugin-api/index.ts +34 -1
- package/src/plugin-api/types.ts +104 -22
- package/src/plugins/defaults/circuit-breaker.ts +0 -5
- package/src/plugins/defaults/compaction.ts +0 -4
- package/src/plugins/defaults/empty-response.ts +0 -2
- package/src/plugins/defaults/history-repair.ts +0 -2
- package/src/plugins/defaults/injectors.ts +36 -3
- package/src/plugins/defaults/llm-call.ts +0 -2
- package/src/plugins/defaults/memory-retrieval.ts +0 -1
- package/src/plugins/defaults/overflow-reduce.ts +0 -1
- package/src/plugins/defaults/persistence.ts +0 -2
- package/src/plugins/defaults/title-generate.ts +0 -5
- package/src/plugins/defaults/token-estimate.ts +0 -2
- package/src/plugins/defaults/tool-error.ts +0 -7
- package/src/plugins/defaults/tool-execute.ts +0 -2
- package/src/plugins/defaults/tool-result-truncate.ts +0 -4
- package/src/plugins/ensure-plugin-api-shim.ts +96 -0
- package/src/plugins/external-api.ts +104 -0
- package/src/plugins/external-plugin-loader.ts +105 -32
- package/src/plugins/feature-gate.ts +22 -0
- package/src/plugins/pipeline.ts +37 -0
- package/src/plugins/registry.ts +48 -80
- package/src/plugins/types.ts +31 -26
- package/src/plugins/user-loader.ts +21 -2
- package/src/proactive-artifact/aux-message-injector.ts +11 -0
- package/src/proactive-artifact/job.test.ts +37 -5
- package/src/prompts/__tests__/system-prompt.test.ts +12 -0
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +99 -0
- package/src/prompts/normalize-onboarding.ts +27 -0
- package/src/prompts/sections.ts +302 -0
- package/src/prompts/system-prompt.ts +63 -166
- package/src/prompts/templates/BOOTSTRAP.md +17 -1
- package/src/prompts/templates/system-sections.ts +173 -0
- package/src/providers/__tests__/inference.test.ts +22 -7
- package/src/providers/anthropic/client.ts +28 -28
- package/src/providers/connection-resolution.ts +7 -0
- package/src/providers/inference/adapter-factory.ts +41 -4
- package/src/providers/inference/connections.ts +74 -29
- package/src/providers/inference/resolve-auth.ts +12 -4
- package/src/providers/model-catalog.ts +294 -12
- package/src/providers/openai/chat-completions-provider.ts +10 -2
- package/src/providers/openrouter/client.ts +7 -0
- package/src/providers/{managed-proxy → platform-proxy}/constants.ts +4 -1
- package/src/providers/{managed-proxy → platform-proxy}/context.ts +3 -3
- package/src/providers/provider-availability.ts +17 -2
- package/src/providers/provider-catalog-visibility.ts +36 -0
- package/src/providers/registry.ts +22 -14
- package/src/providers/retry.ts +47 -1
- package/src/runtime/__tests__/agent-wake.test.ts +152 -0
- package/src/runtime/agent-wake.ts +42 -14
- package/src/runtime/auth/route-policy.ts +8 -1
- package/src/runtime/btw-sidechain.ts +2 -0
- package/src/runtime/http-types.ts +19 -0
- package/src/runtime/migrations/origin-mode.ts +1 -1
- package/src/runtime/pending-interactions.ts +1 -0
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +17 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +5 -1
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +107 -20
- package/src/runtime/routes/__tests__/question-routes.test.ts +395 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +64 -1
- package/src/runtime/routes/acp-routes-list.test.ts +143 -0
- package/src/runtime/routes/acp-routes.ts +5 -3
- package/src/runtime/routes/auth-routes.ts +1 -1
- package/src/runtime/routes/bookmark-routes.ts +5 -3
- package/src/runtime/routes/btw-routes.ts +5 -1
- package/src/runtime/routes/channel-availability-routes.ts +121 -0
- package/src/runtime/routes/conversation-cli-routes.ts +44 -3
- package/src/runtime/routes/conversation-list-routes.ts +3 -20
- package/src/runtime/routes/conversation-management-routes.ts +17 -42
- package/src/runtime/routes/conversation-query-routes.ts +40 -35
- package/src/runtime/routes/conversation-routes.ts +90 -11
- package/src/runtime/routes/documents-routes.ts +25 -86
- package/src/runtime/routes/group-routes.ts +5 -0
- package/src/runtime/routes/inbound-conversation.ts +28 -8
- package/src/runtime/routes/inbound-message-handler.ts +236 -41
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +111 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +32 -1
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +17 -4
- package/src/runtime/routes/index.ts +6 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +17 -44
- package/src/runtime/routes/inference-profile-session-reaper.ts +7 -21
- package/src/runtime/routes/inference-provider-connection-routes.ts +65 -21
- package/src/runtime/routes/integrations/slack/share.ts +4 -52
- package/src/runtime/routes/integrations/slack/token.ts +43 -0
- package/src/runtime/routes/integrations/twilio.ts +6 -13
- package/src/runtime/routes/notification-routes.ts +1 -1
- package/src/runtime/routes/oauth-commands-routes.ts +105 -15
- package/src/runtime/routes/oauth-lifecycle-routes.ts +43 -0
- package/src/runtime/routes/question-routes.ts +259 -0
- package/src/runtime/routes/rename-conversation-routes.ts +2 -33
- package/src/runtime/routes/schedule-routes.ts +4 -7
- package/src/runtime/routes/subagents-routes.ts +57 -18
- package/src/runtime/routes/telemetry-routes.ts +27 -0
- package/src/runtime/routes/tts-routes.ts +27 -2
- package/src/runtime/routes/workspace-routes.test.ts +43 -0
- package/src/runtime/routes/workspace-routes.ts +28 -0
- package/src/runtime/services/conversation-serializer.ts +39 -7
- package/src/runtime/sync/resource-sync-events.ts +93 -1
- package/src/schedule/schedule-store.ts +27 -2
- package/src/schedule/scheduler.ts +9 -1
- package/src/security/__tests__/untrusted-content.test.ts +86 -0
- package/src/security/untrusted-content.ts +93 -8
- package/src/skills/catalog-files.ts +1 -1
- package/src/skills/catalog-install.ts +233 -116
- package/src/skills/clawhub.ts +70 -13
- package/src/skills/managed-store.ts +4 -119
- package/src/skills/skillssh-registry.ts +27 -48
- package/src/subagent/manager.ts +15 -7
- package/src/telemetry/types.ts +113 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +312 -5
- package/src/telemetry/usage-telemetry-reporter.ts +113 -7
- package/src/tools/apps/executors.ts +58 -7
- package/src/tools/ask-question/ask-question-tool.test.ts +509 -0
- package/src/tools/ask-question/ask-question-tool.ts +304 -0
- package/src/tools/browser/browser-execution.ts +15 -11
- package/src/tools/computer-use/definitions.ts +3 -3
- package/src/tools/credentials/vault.ts +1 -1
- package/src/tools/document/document-tool.ts +124 -1
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +1 -1
- package/src/tools/filesystem/write.ts +5 -2
- package/src/tools/host-filesystem/transfer.ts +1 -1
- package/src/tools/host-terminal/host-shell.ts +1 -1
- package/src/tools/permission-checker.ts +1 -1
- package/src/tools/registry.ts +17 -7
- package/src/tools/schedule/create.ts +2 -2
- package/src/tools/schema-transforms.ts +7 -2
- package/src/tools/side-effects.ts +1 -0
- package/src/tools/skills/delete-managed.ts +4 -4
- package/src/tools/skills/execute.ts +1 -1
- package/src/tools/skills/scaffold-managed.ts +3 -2
- package/src/tools/subagent/notify-parent.ts +1 -1
- package/src/tools/system/request-permission.ts +2 -2
- package/src/tools/terminal/safe-env.ts +60 -1
- package/src/tools/tool-manifest.ts +2 -0
- package/src/tools/types.ts +72 -21
- package/src/tools/ui-surface/definitions.ts +6 -5
- package/src/tts/__tests__/provider-adapters.test.ts +76 -2
- package/src/tts/providers/elevenlabs-provider.ts +75 -1
- package/src/types/onboarding-context.ts +2 -0
- package/src/util/errors.ts +17 -0
- package/src/util/platform.ts +10 -0
- package/src/watcher/__tests__/engine.test.ts +22 -0
- package/src/watcher/engine.ts +6 -2
- package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +80 -15
- package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +35 -22
- package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +3 -1
- package/src/workspace/migrations/083-system-prompt-prefix-to-file.ts +191 -0
- package/src/workspace/migrations/084-remove-legacy-skills-index.ts +276 -0
- package/src/workspace/migrations/085-memory-v2-bm25-b-reembed-disabled-v2-pages.ts +137 -0
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +198 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/workspace/migrations/runner.ts +39 -9
- package/src/workspace/migrations/types.ts +4 -0
- package/examples/plugins/echo/bun.lock +0 -25
- package/src/__tests__/context-window-manager.test.ts +0 -2481
- package/src/context/__tests__/compact-prompt.test.ts +0 -63
- package/src/context/prompts/compact.md +0 -26
- package/src/prompts/__tests__/build-cli-reference-section.test.ts +0 -37
- /package/src/__tests__/{secret-routes-managed-proxy.test.ts → secret-routes-platform-proxy.test.ts} +0 -0
|
@@ -17,9 +17,15 @@
|
|
|
17
17
|
* targets the user's actual desktop application, which is a host-wide
|
|
18
18
|
* resource. It is acquired optimistically when `app_control_start` is
|
|
19
19
|
* dispatched (storing `(conversationId, app)`) so that the synchronous
|
|
20
|
-
* guard and the asynchronous host round-trip cannot race
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* guard and the asynchronous host round-trip cannot race. A separate
|
|
21
|
+
* `confirmedAppControlSession` tracks the last session the host reported
|
|
22
|
+
* `running`; the rollback path on a failed `start` restores from the
|
|
23
|
+
* current confirmed pointer (not from a per-call snapshot of a sibling
|
|
24
|
+
* optimistic write), so two overlapping starts that both fail cannot
|
|
25
|
+
* leave a phantom lock — and a late-arriving `running` for an older
|
|
26
|
+
* overlapping start still updates the confirmed pointer so the lock
|
|
27
|
+
* survives a subsequent rollback of the newer start. The lock is
|
|
28
|
+
* released outright when the owning proxy's `dispose()` fires.
|
|
23
29
|
*
|
|
24
30
|
* `app_control_start` is the only tool that can acquire the lock — the
|
|
25
31
|
* user's medium-risk approval at start time is the consent boundary. All
|
|
@@ -81,34 +87,47 @@ export interface ActiveAppControlSession {
|
|
|
81
87
|
}
|
|
82
88
|
|
|
83
89
|
/**
|
|
84
|
-
* Currently active session, or `undefined` when no session is held.
|
|
90
|
+
* Currently active session, or `undefined` when no session is held. This
|
|
91
|
+
* is the optimistic value: it is set the moment a `start` is dispatched
|
|
92
|
+
* and only promoted to {@link confirmedAppControlSession} when the host
|
|
93
|
+
* returns `running`.
|
|
85
94
|
*
|
|
86
95
|
* Exported for test inspection only. Production code paths must not read
|
|
87
96
|
* or mutate this directly — use the proxy methods.
|
|
88
97
|
*/
|
|
89
98
|
let activeAppControlSession: ActiveAppControlSession | undefined;
|
|
90
99
|
|
|
91
|
-
/**
|
|
100
|
+
/**
|
|
101
|
+
* Last session whose `start` was confirmed by the host (`payload.state ===
|
|
102
|
+
* "running"`). Used as the rollback baseline so a failed start never
|
|
103
|
+
* restores a sibling in-flight optimistic write — only a session that was
|
|
104
|
+
* actually running can re-emerge from a rollback.
|
|
105
|
+
*/
|
|
106
|
+
let confirmedAppControlSession: ActiveAppControlSession | undefined;
|
|
107
|
+
|
|
108
|
+
/** Test-only helper: read current (optimistic) session. */
|
|
92
109
|
export function _getActiveAppControlSession():
|
|
93
110
|
| ActiveAppControlSession
|
|
94
111
|
| undefined {
|
|
95
112
|
return activeAppControlSession;
|
|
96
113
|
}
|
|
97
114
|
|
|
98
|
-
/** Test-only helper: clear session between test cases. */
|
|
115
|
+
/** Test-only helper: clear both session pointers between test cases. */
|
|
99
116
|
export function _resetActiveAppControlSession(): void {
|
|
100
117
|
activeAppControlSession = undefined;
|
|
118
|
+
confirmedAppControlSession = undefined;
|
|
101
119
|
}
|
|
102
120
|
|
|
103
121
|
/**
|
|
104
|
-
* Test-only helper: prime
|
|
105
|
-
* Useful for tests that exercise non-start tool paths and
|
|
106
|
-
* verify the start flow itself.
|
|
122
|
+
* Test-only helper: prime both session pointers without a full `start`
|
|
123
|
+
* round-trip. Useful for tests that exercise non-start tool paths and
|
|
124
|
+
* don't need to verify the start flow itself.
|
|
107
125
|
*/
|
|
108
126
|
export function _setActiveAppControlSession(
|
|
109
127
|
session: ActiveAppControlSession,
|
|
110
128
|
): void {
|
|
111
129
|
activeAppControlSession = session;
|
|
130
|
+
confirmedAppControlSession = session;
|
|
112
131
|
}
|
|
113
132
|
|
|
114
133
|
/**
|
|
@@ -236,6 +255,7 @@ export class HostAppControlProxy extends HostProxyBase<
|
|
|
236
255
|
// belong to the active session and target the same `app`. Without this
|
|
237
256
|
// gate, prompt-injected calls would bypass the start-time approval and
|
|
238
257
|
// send raw input to arbitrary apps.
|
|
258
|
+
let attemptedSession: ActiveAppControlSession | undefined;
|
|
239
259
|
if (input.tool === "start") {
|
|
240
260
|
if (
|
|
241
261
|
activeAppControlSession != null &&
|
|
@@ -253,12 +273,15 @@ export class HostAppControlProxy extends HostProxyBase<
|
|
|
253
273
|
// synchronous guard and the asynchronous `dispatchRequest` below. Two
|
|
254
274
|
// concurrent starts from different conversations would otherwise both
|
|
255
275
|
// see `activeAppControlSession == null` and both pass the guard. The
|
|
256
|
-
// lock is
|
|
257
|
-
// non-running state
|
|
258
|
-
|
|
276
|
+
// lock is rolled back below if dispatch fails or the host returns a
|
|
277
|
+
// non-running state — keyed on object identity so that a later
|
|
278
|
+
// overlapping start that has already replaced our write is not
|
|
279
|
+
// clobbered by a stale rollback.
|
|
280
|
+
attemptedSession = {
|
|
259
281
|
conversationId: this.conversationId,
|
|
260
282
|
app: input.app,
|
|
261
283
|
};
|
|
284
|
+
activeAppControlSession = attemptedSession;
|
|
262
285
|
} else {
|
|
263
286
|
const sessionError = checkNonStartAuthorization(
|
|
264
287
|
input,
|
|
@@ -278,10 +301,17 @@ export class HostAppControlProxy extends HostProxyBase<
|
|
|
278
301
|
undefined,
|
|
279
302
|
targetClientId,
|
|
280
303
|
);
|
|
281
|
-
|
|
304
|
+
if (input.tool === "start") {
|
|
305
|
+
if (payload.state === "running") {
|
|
306
|
+
this.promoteStartIfCurrent(attemptedSession);
|
|
307
|
+
} else {
|
|
308
|
+
this.rollbackStartIfCurrent(attemptedSession);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return this.handleSuccess(payload);
|
|
282
312
|
} catch (err) {
|
|
283
313
|
if (input.tool === "start") {
|
|
284
|
-
this.
|
|
314
|
+
this.rollbackStartIfCurrent(attemptedSession);
|
|
285
315
|
}
|
|
286
316
|
if (err instanceof HostProxyRequestError) {
|
|
287
317
|
if (err.reason === "timeout") {
|
|
@@ -301,10 +331,64 @@ export class HostAppControlProxy extends HostProxyBase<
|
|
|
301
331
|
}
|
|
302
332
|
}
|
|
303
333
|
|
|
334
|
+
/**
|
|
335
|
+
* Roll back the optimistic overwrite performed by a `start` when the
|
|
336
|
+
* dispatch fails or the host returns non-running. Keyed on the
|
|
337
|
+
* `attempted` reference, not just `conversationId`, so that an
|
|
338
|
+
* out-of-order failure does not clobber a newer overlapping start that
|
|
339
|
+
* already replaced our write — e.g. start A → start B (pending) →
|
|
340
|
+
* start C (success); when B later fails, the live session is C and the
|
|
341
|
+
* identity check makes our rollback a no-op rather than restoring A.
|
|
342
|
+
*
|
|
343
|
+
* Restores from the *current* `confirmedAppControlSession`, not a
|
|
344
|
+
* per-call snapshot of it. This matters when a late-arriving `running`
|
|
345
|
+
* for an older overlapping start has updated `confirmedAppControlSession`
|
|
346
|
+
* in the meantime: if A is dispatched, then C is dispatched (overwriting
|
|
347
|
+
* active), then A returns `running` (confirming A), then C returns
|
|
348
|
+
* non-running, the rollback must restore active to A — not undefined.
|
|
349
|
+
*/
|
|
350
|
+
private rollbackStartIfCurrent(
|
|
351
|
+
attempted: ActiveAppControlSession | undefined,
|
|
352
|
+
): void {
|
|
353
|
+
if (attempted != null && activeAppControlSession === attempted) {
|
|
354
|
+
activeAppControlSession = confirmedAppControlSession;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Promote this start's optimistic write to the confirmed pointer when
|
|
360
|
+
* the host returns `running`. Gated on conversation ownership rather
|
|
361
|
+
* than object identity: a newer overlapping start in the same
|
|
362
|
+
* conversation may have superseded our optimistic write while we were
|
|
363
|
+
* waiting on the host, but the host's `running` response for our
|
|
364
|
+
* `attempted` is still ground-truth that the lock should be held.
|
|
365
|
+
* The conversation-ownership check ensures we don't resurrect a session
|
|
366
|
+
* after `dispose()` cleared the lock or after another conversation
|
|
367
|
+
* acquired it.
|
|
368
|
+
*/
|
|
369
|
+
private promoteStartIfCurrent(
|
|
370
|
+
attempted: ActiveAppControlSession | undefined,
|
|
371
|
+
): void {
|
|
372
|
+
if (attempted == null) return;
|
|
373
|
+
if (activeAppControlSession?.conversationId !== attempted.conversationId) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
confirmedAppControlSession = attempted;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Release both the optimistic and confirmed module-level session
|
|
381
|
+
* pointers if this proxy is the current holder. Used by `dispose()` —
|
|
382
|
+
* distinct from `rollbackStartIfCurrent` because dispose is keyed on
|
|
383
|
+
* ownership (conversationId) rather than on a specific in-flight start.
|
|
384
|
+
*/
|
|
304
385
|
private releaseSessionIfHeld(): void {
|
|
305
386
|
if (activeAppControlSession?.conversationId === this.conversationId) {
|
|
306
387
|
activeAppControlSession = undefined;
|
|
307
388
|
}
|
|
389
|
+
if (confirmedAppControlSession?.conversationId === this.conversationId) {
|
|
390
|
+
confirmedAppControlSession = undefined;
|
|
391
|
+
}
|
|
308
392
|
}
|
|
309
393
|
|
|
310
394
|
// ---------------------------------------------------------------------------
|
|
@@ -312,7 +396,6 @@ export class HostAppControlProxy extends HostProxyBase<
|
|
|
312
396
|
// ---------------------------------------------------------------------------
|
|
313
397
|
|
|
314
398
|
private handleSuccess(
|
|
315
|
-
input: HostAppControlInput,
|
|
316
399
|
payload: HostAppControlResultPayload,
|
|
317
400
|
): ToolExecutionResult {
|
|
318
401
|
// Update PNG-hash loop tracking only for the "running" state — other
|
|
@@ -332,14 +415,6 @@ export class HostAppControlProxy extends HostProxyBase<
|
|
|
332
415
|
}
|
|
333
416
|
}
|
|
334
417
|
|
|
335
|
-
// The optimistic lock acquired in `request()` for `start` stays held
|
|
336
|
-
// only when the host confirms the session is running. Non-running
|
|
337
|
-
// outcomes (missing/minimized) release it so a retry or another
|
|
338
|
-
// conversation can acquire.
|
|
339
|
-
if (input.tool === "start" && payload.state !== "running") {
|
|
340
|
-
this.releaseSessionIfHeld();
|
|
341
|
-
}
|
|
342
|
-
|
|
343
418
|
return this.formatResult(payload, stuck);
|
|
344
419
|
}
|
|
345
420
|
|
package/src/daemon/lifecycle.ts
CHANGED
|
@@ -20,6 +20,7 @@ import type { AssistantConfig } from "../config/schema.js";
|
|
|
20
20
|
import { seedInferenceProfiles } from "../config/seed-inference-profiles.js";
|
|
21
21
|
import type { CesClient } from "../credential-execution/client.js";
|
|
22
22
|
import { createCesClient } from "../credential-execution/client.js";
|
|
23
|
+
import { refreshManagedConnectionCache } from "../credential-execution/managed-catalog.js";
|
|
23
24
|
import {
|
|
24
25
|
type CesProcessManager,
|
|
25
26
|
CesUnavailableError,
|
|
@@ -54,11 +55,12 @@ import {
|
|
|
54
55
|
} from "../notifications/emit-signal.js";
|
|
55
56
|
import { backfillManualTokenConnections } from "../oauth/manual-token-connection.js";
|
|
56
57
|
import { seedOAuthProviders } from "../oauth/seed-providers.js";
|
|
58
|
+
import { installPluginRuntime } from "../plugins/external-api.js";
|
|
57
59
|
import { loadUserPlugins } from "../plugins/user-loader.js";
|
|
58
60
|
import { backfillGuardIfNeeded } from "../proactive-artifact/index.js";
|
|
59
61
|
import { ensurePromptFiles } from "../prompts/system-prompt.js";
|
|
60
62
|
import { runProviderConnectionsBackfill } from "../providers/inference/backfill.js";
|
|
61
|
-
import { resolveManagedProxyContext } from "../providers/
|
|
63
|
+
import { resolveManagedProxyContext } from "../providers/platform-proxy/context.js";
|
|
62
64
|
import { broadcastMessage } from "../runtime/assistant-event-hub.js";
|
|
63
65
|
import {
|
|
64
66
|
initAuthSigningKey,
|
|
@@ -74,7 +76,10 @@ import {
|
|
|
74
76
|
setCesClient,
|
|
75
77
|
setCesReconnect,
|
|
76
78
|
} from "../security/secure-keys.js";
|
|
77
|
-
import {
|
|
79
|
+
import {
|
|
80
|
+
setUsageTelemetryReporter,
|
|
81
|
+
UsageTelemetryReporter,
|
|
82
|
+
} from "../telemetry/usage-telemetry-reporter.js";
|
|
78
83
|
import { registerBuiltinTtsProviders } from "../tts/providers/register-builtins.js";
|
|
79
84
|
import { getDeviceId } from "../util/device-id.js";
|
|
80
85
|
import { getLogger, initLogger } from "../util/logger.js";
|
|
@@ -114,7 +119,7 @@ import { backfillSlackInjectionTemplates } from "./handlers/config-slack-channel
|
|
|
114
119
|
import { installAssistantSymlink } from "./install-symlink.js";
|
|
115
120
|
import {
|
|
116
121
|
maybeRebuildMemoryV2Concepts,
|
|
117
|
-
|
|
122
|
+
rebuildBm25CorpusStatsAndReseedSkills,
|
|
118
123
|
} from "./memory-v2-startup.js";
|
|
119
124
|
import { processMessage } from "./process-message.js";
|
|
120
125
|
import { runProfilerSweep } from "./profiler-run-store.js";
|
|
@@ -126,6 +131,7 @@ import {
|
|
|
126
131
|
import { seedInterfaceFiles } from "./seed-files.js";
|
|
127
132
|
import { DaemonServer } from "./server.js";
|
|
128
133
|
import { installShutdownHandlers } from "./shutdown-handlers.js";
|
|
134
|
+
import { refreshSkillCapabilityMemories } from "./skill-memory-refresh.js";
|
|
129
135
|
|
|
130
136
|
const log = getLogger("lifecycle");
|
|
131
137
|
let diskPressureStartupSampleTimer: ReturnType<typeof setTimeout> | null = null;
|
|
@@ -504,6 +510,25 @@ export async function runDaemon(): Promise<void> {
|
|
|
504
510
|
}
|
|
505
511
|
} // end if (dbReady)
|
|
506
512
|
|
|
513
|
+
// Populate the managed-connection cache so buildIntegrationSection()
|
|
514
|
+
// can include platform-managed OAuth connections (e.g. Twitter) in the
|
|
515
|
+
// system prompt's "Connected Services" section from the first turn.
|
|
516
|
+
// This is an HTTP-only call with no DB dependency, so it runs regardless
|
|
517
|
+
// of dbReady. A periodic refresh keeps the cache current when users
|
|
518
|
+
// connect/disconnect managed providers while the assistant is running.
|
|
519
|
+
void refreshManagedConnectionCache().catch((err) =>
|
|
520
|
+
log.warn(
|
|
521
|
+
{ err },
|
|
522
|
+
"Managed connection cache refresh failed — continuing startup",
|
|
523
|
+
),
|
|
524
|
+
);
|
|
525
|
+
const MANAGED_CONNECTION_REFRESH_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes
|
|
526
|
+
setInterval(() => {
|
|
527
|
+
void refreshManagedConnectionCache().catch((err) =>
|
|
528
|
+
log.warn({ err }, "Periodic managed connection cache refresh failed"),
|
|
529
|
+
);
|
|
530
|
+
}, MANAGED_CONNECTION_REFRESH_INTERVAL_MS);
|
|
531
|
+
|
|
507
532
|
// Merge CLI-provided default config (from VELLUM_DEFAULT_WORKSPACE_CONFIG_PATH)
|
|
508
533
|
// into the workspace config file before profile seeding and the first
|
|
509
534
|
// loadConfig() call so onboarding/platform preferences are visible to the
|
|
@@ -565,6 +590,7 @@ export async function runDaemon(): Promise<void> {
|
|
|
565
590
|
let telemetryReporter: UsageTelemetryReporter | null = null;
|
|
566
591
|
if (collectUsageData) {
|
|
567
592
|
telemetryReporter = new UsageTelemetryReporter();
|
|
593
|
+
setUsageTelemetryReporter(telemetryReporter);
|
|
568
594
|
telemetryReporter.start();
|
|
569
595
|
log.info("Usage telemetry reporter started");
|
|
570
596
|
}
|
|
@@ -648,6 +674,12 @@ export async function runDaemon(): Promise<void> {
|
|
|
648
674
|
});
|
|
649
675
|
}
|
|
650
676
|
|
|
677
|
+
// Install the `globalThis.__vellumPluginRuntime` bridge before scanning
|
|
678
|
+
// for user plugins. Plugins that touch the bridge from their module body
|
|
679
|
+
// would throw without this — see `plugins/external-api.ts` for the
|
|
680
|
+
// rationale (compiled-binary module identity).
|
|
681
|
+
installPluginRuntime();
|
|
682
|
+
|
|
651
683
|
// Populate the registry with user plugins from `<workspaceDir>/plugins/*`
|
|
652
684
|
// AFTER first-party plugins have already registered via their static
|
|
653
685
|
// side-effect imports. User plugins may fail to load individually; a
|
|
@@ -830,25 +862,13 @@ export async function runDaemon(): Promise<void> {
|
|
|
830
862
|
}
|
|
831
863
|
|
|
832
864
|
// Build the BM25 corpus stats (per-token document frequencies and
|
|
833
|
-
// average document length) used by the v2 sparse channel
|
|
834
|
-
//
|
|
835
|
-
//
|
|
836
|
-
//
|
|
837
|
-
//
|
|
838
|
-
// boot-blocking
|
|
839
|
-
void (
|
|
840
|
-
try {
|
|
841
|
-
const { rebuildConceptPageCorpusStats } =
|
|
842
|
-
await import("../memory/v2/sparse-bm25.js");
|
|
843
|
-
await rebuildConceptPageCorpusStats(getWorkspaceDir());
|
|
844
|
-
log.info("Memory v2 BM25 corpus stats built");
|
|
845
|
-
} catch (err) {
|
|
846
|
-
log.warn(
|
|
847
|
-
{ err },
|
|
848
|
-
"BM25 corpus-stats rebuild failed — sparse channel will fall back to TF-only until next rebuild",
|
|
849
|
-
);
|
|
850
|
-
}
|
|
851
|
-
})();
|
|
865
|
+
// average document length) used by the v2 sparse channel, then
|
|
866
|
+
// re-seed v2 skill entries so any skill vectors written during the
|
|
867
|
+
// cold-start window with the legacy TF encoder get rewritten with
|
|
868
|
+
// stemmed BM25 vectors. Fire-and-forget for the same reason as PKB
|
|
869
|
+
// reconcile — the stats and skill reseed are optional optimizations,
|
|
870
|
+
// never boot-blocking dependencies.
|
|
871
|
+
void rebuildBm25CorpusStatsAndReseedSkills(config);
|
|
852
872
|
|
|
853
873
|
// Validate every concept page's frontmatter against the strict
|
|
854
874
|
// schema and emit a `warn` per offender. Surfaces schema drift
|
|
@@ -876,20 +896,10 @@ export async function runDaemon(): Promise<void> {
|
|
|
876
896
|
|
|
877
897
|
// Seed capability graph nodes (new memory graph system)
|
|
878
898
|
try {
|
|
879
|
-
const {
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
seedUninstalledCatalogSkillMemories,
|
|
883
|
-
} = await import("../memory/graph/capability-seed.js");
|
|
884
|
-
seedSkillGraphNodes();
|
|
885
|
-
maybeSeedMemoryV2Skills(config);
|
|
899
|
+
const { seedCliGraphNodes } =
|
|
900
|
+
await import("../memory/graph/capability-seed.js");
|
|
901
|
+
refreshSkillCapabilityMemories(config);
|
|
886
902
|
await seedCliGraphNodes();
|
|
887
|
-
void seedUninstalledCatalogSkillMemories().catch((err) =>
|
|
888
|
-
log.warn(
|
|
889
|
-
{ err },
|
|
890
|
-
"Uninstalled catalog skill memory seeding failed — continuing",
|
|
891
|
-
),
|
|
892
|
-
);
|
|
893
903
|
} catch (err) {
|
|
894
904
|
log.warn({ err }, "Graph capability seeding failed — continuing");
|
|
895
905
|
}
|
|
@@ -254,10 +254,11 @@ export class MeetHostSupervisor {
|
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
/**
|
|
257
|
-
* Ensure the meet-host child is spawned
|
|
258
|
-
* received
|
|
259
|
-
*
|
|
260
|
-
*
|
|
257
|
+
* Ensure the meet-host child is spawned and the IPC handshake has
|
|
258
|
+
* been received. Idempotent: a second call while the child is
|
|
259
|
+
* already running is a no-op; a second call during an in-flight
|
|
260
|
+
* spawn awaits the same promise. Manifest hash validation is
|
|
261
|
+
* currently dormant (see {@link notifyHandshake}).
|
|
261
262
|
*/
|
|
262
263
|
ensureRunning(): Promise<void> {
|
|
263
264
|
if (this.shuttingDown) {
|
|
@@ -35,6 +35,55 @@ export function maybeSeedMemoryV2Skills(config: AssistantConfig): void {
|
|
|
35
35
|
);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Build the v2 BM25 corpus stats (per-token document frequencies + avg doc
|
|
40
|
+
* length), then re-seed the v2 skill entries so any skills written during
|
|
41
|
+
* cold start with the legacy TF encoder get rewritten with stemmed BM25
|
|
42
|
+
* vectors. The cold-start window exists because the very first
|
|
43
|
+
* `maybeSeedMemoryV2Skills` call can race ahead of the corpus-stats build —
|
|
44
|
+
* `skill-store.runSeedOnce` falls back to `generateSparseEmbedding` while
|
|
45
|
+
* `getConceptPageCorpusStats()` is still `null`, leaving stored skill
|
|
46
|
+
* sparse vectors in a different hash space than the BM25 query vectors
|
|
47
|
+
* callers issue (see `simBatch`, `activation.selectCandidates`). Reseeding
|
|
48
|
+
* here closes that gap without operator intervention.
|
|
49
|
+
*
|
|
50
|
+
* Fire-and-forget by design — startup must not block on either step. The
|
|
51
|
+
* reseed depends on the corpus-stats build, so a corpus-stats failure
|
|
52
|
+
* short-circuits and skips the reseed (the BM25 vectors it would produce
|
|
53
|
+
* would be wrong without fresh stats). Both steps log and swallow their own
|
|
54
|
+
* errors so neither blocks startup.
|
|
55
|
+
*/
|
|
56
|
+
export async function rebuildBm25CorpusStatsAndReseedSkills(
|
|
57
|
+
config: AssistantConfig,
|
|
58
|
+
): Promise<void> {
|
|
59
|
+
try {
|
|
60
|
+
const { rebuildConceptPageCorpusStats } =
|
|
61
|
+
await import("../memory/v2/sparse-bm25.js");
|
|
62
|
+
await rebuildConceptPageCorpusStats(getWorkspaceDir());
|
|
63
|
+
log.info("Memory v2 BM25 corpus stats built");
|
|
64
|
+
} catch (err) {
|
|
65
|
+
log.warn(
|
|
66
|
+
{ err },
|
|
67
|
+
"BM25 corpus-stats rebuild failed — sparse channel will fall back to TF-only until next rebuild",
|
|
68
|
+
);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!config.memory.v2.enabled) return;
|
|
73
|
+
try {
|
|
74
|
+
const { seedV2SkillEntries } = await import("../memory/v2/skill-store.js");
|
|
75
|
+
await seedV2SkillEntries({ throwOnError: true });
|
|
76
|
+
log.info(
|
|
77
|
+
"Memory v2 skill embeddings re-seeded with BM25 vectors after corpus-stats build",
|
|
78
|
+
);
|
|
79
|
+
} catch (err) {
|
|
80
|
+
log.warn(
|
|
81
|
+
{ err },
|
|
82
|
+
"Failed to re-seed v2 skill entries after BM25 corpus-stats build — skills seeded during cold start may keep TF-only sparse vectors until next reseed",
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
38
87
|
/**
|
|
39
88
|
* Reconcile the v2 concept-page Qdrant collection with the expected schema
|
|
40
89
|
* and enqueue `memory_v2_reembed` when the collection is missing data.
|
|
@@ -224,9 +224,18 @@ export interface ConversationTitleUpdated {
|
|
|
224
224
|
interface ChannelBinding {
|
|
225
225
|
sourceChannel: ChannelId;
|
|
226
226
|
externalChatId: string;
|
|
227
|
+
externalThreadId?: string | null;
|
|
227
228
|
externalUserId?: string | null;
|
|
228
229
|
displayName?: string | null;
|
|
229
230
|
username?: string | null;
|
|
231
|
+
slackThread?: {
|
|
232
|
+
channelId: string;
|
|
233
|
+
threadTs: string;
|
|
234
|
+
link?: {
|
|
235
|
+
appUrl?: string;
|
|
236
|
+
webUrl?: string;
|
|
237
|
+
};
|
|
238
|
+
};
|
|
230
239
|
}
|
|
231
240
|
|
|
232
241
|
/** Attention state metadata for a conversation's latest assistant message. */
|
|
@@ -411,6 +420,7 @@ export interface HistoryResponse {
|
|
|
411
420
|
status: "running" | "completed" | "failed" | "aborted";
|
|
412
421
|
error?: string;
|
|
413
422
|
conversationId?: string;
|
|
423
|
+
objective?: string;
|
|
414
424
|
};
|
|
415
425
|
/** True when text or tool result content was truncated due to maxTextChars/maxToolResultChars. */
|
|
416
426
|
wasTruncated?: boolean;
|
|
@@ -535,6 +545,7 @@ export type ConversationErrorCode =
|
|
|
535
545
|
| "PROVIDER_ORDERING"
|
|
536
546
|
| "PROVIDER_WEB_SEARCH"
|
|
537
547
|
| "PROVIDER_NOT_CONFIGURED"
|
|
548
|
+
| "PROVIDER_INVALID_KEY"
|
|
538
549
|
| "MANAGED_KEY_INVALID"
|
|
539
550
|
| "CONTEXT_TOO_LARGE"
|
|
540
551
|
| "CONVERSATION_ABORTED"
|
|
@@ -552,6 +563,20 @@ export interface ConversationErrorMessage {
|
|
|
552
563
|
debugDetails?: string;
|
|
553
564
|
/** Machine-readable error category for log report metadata and triage. */
|
|
554
565
|
errorCategory?: string;
|
|
566
|
+
/**
|
|
567
|
+
* Name of the `provider_connections` row in play when the error occurred.
|
|
568
|
+
* Surfaced by the macOS chat banner so users know which connection to fix
|
|
569
|
+
* (e.g. an invalid API key on `my-anthropic`). Optional because some
|
|
570
|
+
* errors fire before a connection is resolved.
|
|
571
|
+
*/
|
|
572
|
+
connectionName?: string;
|
|
573
|
+
/**
|
|
574
|
+
* Name of the resolved profile (`llm.activeProfile` or per-call override)
|
|
575
|
+
* in play when the error occurred. Lets the macOS chat banner point
|
|
576
|
+
* users at the right profile even when the connection name is generic.
|
|
577
|
+
* Optional because some errors fire before a profile is resolved.
|
|
578
|
+
*/
|
|
579
|
+
profileName?: string;
|
|
555
580
|
}
|
|
556
581
|
|
|
557
582
|
/** Reason the conversation list was invalidated. */
|
|
@@ -235,6 +235,66 @@ export interface SecretRequest {
|
|
|
235
235
|
allowOneTimeSend?: boolean;
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
+
export interface QuestionOption {
|
|
239
|
+
id: string;
|
|
240
|
+
label: string;
|
|
241
|
+
description?: string;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* One entry in a batched ask-question request.
|
|
246
|
+
*
|
|
247
|
+
* `id` is daemon-assigned (e.g. `q1`, `q2`...) — the LLM neither sees nor
|
|
248
|
+
* supplies it. It exists so the client has a stable handle to post the
|
|
249
|
+
* user's answer back against. See `QuestionRequest` for the batching
|
|
250
|
+
* contract.
|
|
251
|
+
*/
|
|
252
|
+
export interface QuestionEntry {
|
|
253
|
+
id: string;
|
|
254
|
+
question: string;
|
|
255
|
+
description?: string;
|
|
256
|
+
/** LLM-supplied options, capped at 4. The client always renders a fixed
|
|
257
|
+
* 5th "Type something else" slot wired to a free-text response — so this
|
|
258
|
+
* array never represents the full choice set the user sees. */
|
|
259
|
+
options: QuestionOption[];
|
|
260
|
+
/** Optional placeholder shown in the free-text input. */
|
|
261
|
+
freeTextPlaceholder?: string;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* A single broadcast that carries either one or a small batch (≤5) of
|
|
266
|
+
* clarifying questions. The whole batch is one card lifecycle on the client:
|
|
267
|
+
* one render, one state machine, one response submission.
|
|
268
|
+
*
|
|
269
|
+
* Wire-compat plan: both shapes are populated on every broadcast.
|
|
270
|
+
* - `questions[]` is the canonical shape new clients should consume.
|
|
271
|
+
* - The flat `question` / `description` / `options` / `freeTextPlaceholder`
|
|
272
|
+
* fields mirror `questions[0]` for backwards compat with the existing
|
|
273
|
+
* web client, which keys off the flat fields. Once that client adopts
|
|
274
|
+
* `questions[]`, the flat fields can be dropped (separate cleanup).
|
|
275
|
+
*
|
|
276
|
+
* Daemon callers that don't supply a batch get a one-element `questions`
|
|
277
|
+
* array synthesized from the flat fields.
|
|
278
|
+
*/
|
|
279
|
+
export interface QuestionRequest {
|
|
280
|
+
type: "question_request";
|
|
281
|
+
requestId: string;
|
|
282
|
+
/** Batched-question payload. Always populated (single questions are sent
|
|
283
|
+
* as a one-element array). Each entry's `id` is daemon-assigned. */
|
|
284
|
+
questions: QuestionEntry[];
|
|
285
|
+
/** Legacy: mirrors `questions[0].question`. Kept populated for clients
|
|
286
|
+
* that haven't adopted the batched `questions[]` shape yet. */
|
|
287
|
+
question: string;
|
|
288
|
+
/** Legacy: mirrors `questions[0].description`. */
|
|
289
|
+
description?: string;
|
|
290
|
+
/** Legacy: mirrors `questions[0].options`. */
|
|
291
|
+
options: QuestionOption[];
|
|
292
|
+
/** Legacy: mirrors `questions[0].freeTextPlaceholder`. */
|
|
293
|
+
freeTextPlaceholder?: string;
|
|
294
|
+
conversationId?: string;
|
|
295
|
+
toolUseId?: string;
|
|
296
|
+
}
|
|
297
|
+
|
|
238
298
|
export interface MessageComplete {
|
|
239
299
|
type: "message_complete";
|
|
240
300
|
conversationId?: string;
|
|
@@ -430,6 +490,7 @@ export type _MessagesServerMessages =
|
|
|
430
490
|
| ToolResult
|
|
431
491
|
| ConfirmationRequest
|
|
432
492
|
| SecretRequest
|
|
493
|
+
| QuestionRequest
|
|
433
494
|
| MessageComplete
|
|
434
495
|
| ErrorMessage
|
|
435
496
|
| MessageQueued
|
|
@@ -5,6 +5,7 @@ export const SYNC_TAGS = {
|
|
|
5
5
|
assistantIdentity: "assistant:self:identity",
|
|
6
6
|
assistantConfig: "assistant:self:config",
|
|
7
7
|
assistantSounds: "assistant:self:sounds",
|
|
8
|
+
assistantSchedules: "assistant:self:schedules",
|
|
8
9
|
conversationsList: "conversations:list",
|
|
9
10
|
} as const;
|
|
10
11
|
|
|
@@ -14,7 +14,7 @@ const BASE_REMINDER_DEFAULT =
|
|
|
14
14
|
// `memory-retrospective` feature flag is on.
|
|
15
15
|
const BASE_REMINDER_RELAXED =
|
|
16
16
|
"<system_reminder>" +
|
|
17
|
-
"\nStay present in this conversation. Use `remember` when something feels worth pausing to mark — corrections (highest priority), plans, decisions, felt moments
|
|
17
|
+
"\nStay present in this conversation. Use `remember` when something feels worth pausing to mark — corrections (highest priority), plans, decisions, felt moments. You don't have to capture everything in the moment — a retrospective pass reviews this conversation in the background and saves what you didn't capture." +
|
|
18
18
|
"\nIf you're unsure about something that may live in the workspace — past decisions, prior conversations, files — use `recall` before asking or guessing." +
|
|
19
19
|
"\n</system_reminder>";
|
|
20
20
|
|
|
@@ -3,7 +3,7 @@ const BODY_DEFAULT =
|
|
|
3
3
|
"\nIf you're unsure about something that may live in the workspace — past decisions, prior conversations, files — use `recall` before asking or guessing.";
|
|
4
4
|
|
|
5
5
|
const BODY_RELAXED =
|
|
6
|
-
"\nStay present in this conversation. Use `remember` when something feels worth pausing to mark — corrections (highest priority), plans, decisions, felt moments
|
|
6
|
+
"\nStay present in this conversation. Use `remember` when something feels worth pausing to mark — corrections (highest priority), plans, decisions, felt moments. You don't have to capture everything in the moment — a retrospective pass reviews this conversation in the background and saves what you didn't capture." +
|
|
7
7
|
"\nIf you're unsure about something that may live in the workspace — past decisions, prior conversations, files — use `recall` before asking or guessing.";
|
|
8
8
|
|
|
9
9
|
/**
|