@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
|
@@ -31,8 +31,12 @@ import { extractPreferences } from "../notifications/preference-extractor.js";
|
|
|
31
31
|
import { createPreference } from "../notifications/preferences-store.js";
|
|
32
32
|
import type { Message } from "../providers/types.js";
|
|
33
33
|
import { routeGuardianReply } from "../runtime/guardian-reply-router.js";
|
|
34
|
+
import { publishConversationMessagesChanged } from "../runtime/sync/resource-sync-events.js";
|
|
34
35
|
import { getLogger } from "../util/logger.js";
|
|
35
|
-
import {
|
|
36
|
+
import {
|
|
37
|
+
persistQueuedMessageBody,
|
|
38
|
+
serializePersistedUserMessageContent,
|
|
39
|
+
} from "./conversation-messaging.js";
|
|
36
40
|
import type {
|
|
37
41
|
MessageQueue,
|
|
38
42
|
QueuedMessage,
|
|
@@ -513,11 +517,11 @@ async function drainSingleMessage(
|
|
|
513
517
|
// When displayContent is provided (e.g. original text before recording
|
|
514
518
|
// intent stripping), persist that to DB so users see the full message.
|
|
515
519
|
// The in-memory userMessage (sent to the LLM) still uses the stripped content.
|
|
516
|
-
const contentToPersist =
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
520
|
+
const contentToPersist = serializePersistedUserMessageContent(
|
|
521
|
+
next.content,
|
|
522
|
+
next.attachments,
|
|
523
|
+
next.displayContent,
|
|
524
|
+
);
|
|
521
525
|
await addMessage(
|
|
522
526
|
conversation.conversationId,
|
|
523
527
|
"user",
|
|
@@ -570,6 +574,7 @@ async function drainSingleMessage(
|
|
|
570
574
|
type: "message_complete",
|
|
571
575
|
conversationId: conversation.conversationId,
|
|
572
576
|
});
|
|
577
|
+
publishConversationMessagesChanged(conversation.conversationId);
|
|
573
578
|
} catch (err) {
|
|
574
579
|
const message = err instanceof Error ? err.message : String(err);
|
|
575
580
|
log.error(
|
|
@@ -602,6 +607,7 @@ async function drainSingleMessage(
|
|
|
602
607
|
|
|
603
608
|
// /compact — force context compaction, persist exchange, continue draining.
|
|
604
609
|
if (slashResult.kind === "compact") {
|
|
610
|
+
let persistedCompactMessage = false;
|
|
605
611
|
try {
|
|
606
612
|
const drainProvenance = provenanceFromTrustContext(
|
|
607
613
|
conversation.trustContext,
|
|
@@ -627,9 +633,14 @@ async function drainSingleMessage(
|
|
|
627
633
|
await addMessage(
|
|
628
634
|
conversation.conversationId,
|
|
629
635
|
"user",
|
|
630
|
-
|
|
636
|
+
serializePersistedUserMessageContent(
|
|
637
|
+
next.content,
|
|
638
|
+
next.attachments,
|
|
639
|
+
next.displayContent,
|
|
640
|
+
),
|
|
631
641
|
drainChannelMeta,
|
|
632
642
|
);
|
|
643
|
+
persistedCompactMessage = true;
|
|
633
644
|
conversation.messages.push(cleanUserMsg);
|
|
634
645
|
|
|
635
646
|
conversation.emitActivityState(
|
|
@@ -666,7 +677,11 @@ async function drainSingleMessage(
|
|
|
666
677
|
type: "message_complete",
|
|
667
678
|
conversationId: conversation.conversationId,
|
|
668
679
|
});
|
|
680
|
+
publishConversationMessagesChanged(conversation.conversationId);
|
|
669
681
|
} catch (err) {
|
|
682
|
+
if (persistedCompactMessage) {
|
|
683
|
+
publishConversationMessagesChanged(conversation.conversationId);
|
|
684
|
+
}
|
|
670
685
|
const message = err instanceof Error ? err.message : String(err);
|
|
671
686
|
log.error(
|
|
672
687
|
{
|
|
@@ -762,6 +777,7 @@ async function drainSingleMessage(
|
|
|
762
777
|
requestId: next.requestId,
|
|
763
778
|
clientMessageId: next.clientMessageId,
|
|
764
779
|
});
|
|
780
|
+
publishConversationMessagesChanged(conversation.conversationId);
|
|
765
781
|
|
|
766
782
|
// Set the active surface for the dequeued message so runAgentLoop can inject context
|
|
767
783
|
conversation.currentActiveSurfaceId = next.activeSurfaceId;
|
|
@@ -1087,6 +1103,7 @@ async function drainBatch(
|
|
|
1087
1103
|
requestId: qm.requestId,
|
|
1088
1104
|
clientMessageId: qm.clientMessageId,
|
|
1089
1105
|
});
|
|
1106
|
+
publishConversationMessagesChanged(conversation.conversationId);
|
|
1090
1107
|
|
|
1091
1108
|
// Persist succeeded. Update last-successful markers so a later tail
|
|
1092
1109
|
// failure won't overwrite them.
|
|
@@ -1306,7 +1323,11 @@ export async function processMessage(
|
|
|
1306
1323
|
const persisted = await addMessage(
|
|
1307
1324
|
conversation.conversationId,
|
|
1308
1325
|
"user",
|
|
1309
|
-
|
|
1326
|
+
serializePersistedUserMessageContent(
|
|
1327
|
+
content,
|
|
1328
|
+
attachments,
|
|
1329
|
+
displayContent,
|
|
1330
|
+
),
|
|
1310
1331
|
routerChannelMeta,
|
|
1311
1332
|
);
|
|
1312
1333
|
conversation.messages.push(llmUserMsg);
|
|
@@ -1391,9 +1412,11 @@ export async function processMessage(
|
|
|
1391
1412
|
// When displayContent is provided (e.g. original text before recording
|
|
1392
1413
|
// intent stripping), persist that to DB so users see the full message.
|
|
1393
1414
|
// The in-memory userMessage (sent to the LLM) still uses the stripped content.
|
|
1394
|
-
const contentToPersist =
|
|
1395
|
-
|
|
1396
|
-
|
|
1415
|
+
const contentToPersist = serializePersistedUserMessageContent(
|
|
1416
|
+
content,
|
|
1417
|
+
attachments,
|
|
1418
|
+
displayContent,
|
|
1419
|
+
);
|
|
1397
1420
|
const persisted = await addMessage(
|
|
1398
1421
|
conversation.conversationId,
|
|
1399
1422
|
"user",
|
|
@@ -1446,12 +1469,14 @@ export async function processMessage(
|
|
|
1446
1469
|
type: "message_complete",
|
|
1447
1470
|
conversationId: conversation.conversationId,
|
|
1448
1471
|
});
|
|
1472
|
+
publishConversationMessagesChanged(conversation.conversationId);
|
|
1449
1473
|
return persisted.id;
|
|
1450
1474
|
}
|
|
1451
1475
|
|
|
1452
1476
|
// /compact — force context compaction, persist exchange, return message ID.
|
|
1453
1477
|
if (slashResult.kind === "compact") {
|
|
1454
1478
|
conversation.processing = true;
|
|
1479
|
+
let persistedCompactMessage = false;
|
|
1455
1480
|
try {
|
|
1456
1481
|
const pmTurnCtx = conversation.getTurnChannelContext();
|
|
1457
1482
|
const pmInterfaceCtx = conversation.getTurnInterfaceContext();
|
|
@@ -1478,9 +1503,14 @@ export async function processMessage(
|
|
|
1478
1503
|
const persisted = await addMessage(
|
|
1479
1504
|
conversation.conversationId,
|
|
1480
1505
|
"user",
|
|
1481
|
-
|
|
1506
|
+
serializePersistedUserMessageContent(
|
|
1507
|
+
content,
|
|
1508
|
+
attachments,
|
|
1509
|
+
displayContent,
|
|
1510
|
+
),
|
|
1482
1511
|
pmChannelMeta,
|
|
1483
1512
|
);
|
|
1513
|
+
persistedCompactMessage = true;
|
|
1484
1514
|
conversation.messages.push(cleanUserMsg);
|
|
1485
1515
|
|
|
1486
1516
|
conversation.emitActivityState(
|
|
@@ -1517,7 +1547,13 @@ export async function processMessage(
|
|
|
1517
1547
|
type: "message_complete",
|
|
1518
1548
|
conversationId: conversation.conversationId,
|
|
1519
1549
|
});
|
|
1550
|
+
publishConversationMessagesChanged(conversation.conversationId);
|
|
1520
1551
|
return persisted.id;
|
|
1552
|
+
} catch (err) {
|
|
1553
|
+
if (persistedCompactMessage) {
|
|
1554
|
+
publishConversationMessagesChanged(conversation.conversationId);
|
|
1555
|
+
}
|
|
1556
|
+
throw err;
|
|
1521
1557
|
} finally {
|
|
1522
1558
|
conversation.processing = false;
|
|
1523
1559
|
await drainQueue(conversation);
|
|
@@ -1557,6 +1593,7 @@ export async function processMessage(
|
|
|
1557
1593
|
undefined,
|
|
1558
1594
|
displayContent,
|
|
1559
1595
|
);
|
|
1596
|
+
publishConversationMessagesChanged(conversation.conversationId);
|
|
1560
1597
|
} catch (err) {
|
|
1561
1598
|
const message = err instanceof Error ? err.message : String(err);
|
|
1562
1599
|
onEvent({
|
|
@@ -1182,12 +1182,23 @@ function placeholderForBlockType(type: ContentBlock["type"]): string | null {
|
|
|
1182
1182
|
*/
|
|
1183
1183
|
function rowToRenderable(row: SlackTranscriptInputRow): RenderableSlackMessage {
|
|
1184
1184
|
let slackMeta: ReturnType<typeof readSlackMetadata> = null;
|
|
1185
|
+
let provenanceTrustClass: TrustClass | undefined;
|
|
1185
1186
|
if (row.metadata) {
|
|
1186
1187
|
try {
|
|
1187
|
-
const outer = JSON.parse(row.metadata) as {
|
|
1188
|
+
const outer = JSON.parse(row.metadata) as {
|
|
1189
|
+
slackMeta?: unknown;
|
|
1190
|
+
provenanceTrustClass?: unknown;
|
|
1191
|
+
};
|
|
1188
1192
|
if (typeof outer.slackMeta === "string") {
|
|
1189
1193
|
slackMeta = readSlackMetadata(outer.slackMeta);
|
|
1190
1194
|
}
|
|
1195
|
+
if (
|
|
1196
|
+
outer.provenanceTrustClass === "guardian" ||
|
|
1197
|
+
outer.provenanceTrustClass === "trusted_contact" ||
|
|
1198
|
+
outer.provenanceTrustClass === "unknown"
|
|
1199
|
+
) {
|
|
1200
|
+
provenanceTrustClass = outer.provenanceTrustClass;
|
|
1201
|
+
}
|
|
1191
1202
|
} catch {
|
|
1192
1203
|
// Malformed metadata — fall through to legacy/null treatment.
|
|
1193
1204
|
}
|
|
@@ -1252,6 +1263,8 @@ function rowToRenderable(row: SlackTranscriptInputRow): RenderableSlackMessage {
|
|
|
1252
1263
|
senderLabel,
|
|
1253
1264
|
createdAt: row.createdAt,
|
|
1254
1265
|
contentBlocks,
|
|
1266
|
+
wrapContentForModel:
|
|
1267
|
+
row.role === "user" && !isReaction && provenanceTrustClass !== "guardian",
|
|
1255
1268
|
};
|
|
1256
1269
|
}
|
|
1257
1270
|
|
|
@@ -1989,6 +2002,7 @@ export interface RuntimeInjectionOptions {
|
|
|
1989
2002
|
* `undefined` when the inbound is a top-level (non-thread) post.
|
|
1990
2003
|
*/
|
|
1991
2004
|
slackActiveThreadFocusBlock?: string | null;
|
|
2005
|
+
activeDocuments?: TurnInjectionInputs["activeDocuments"];
|
|
1992
2006
|
mode?: InjectionMode;
|
|
1993
2007
|
/**
|
|
1994
2008
|
* Per-turn {@link TurnContext} forwarded to plugin-registered
|
|
@@ -2042,6 +2056,7 @@ function buildTurnInjectionInputs(
|
|
|
2042
2056
|
voiceCallControlPrompt: options.voiceCallControlPrompt,
|
|
2043
2057
|
transportHints: options.transportHints,
|
|
2044
2058
|
isNonInteractive: options.isNonInteractive,
|
|
2059
|
+
activeDocuments: options.activeDocuments,
|
|
2045
2060
|
};
|
|
2046
2061
|
}
|
|
2047
2062
|
|
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
saveRawConfig,
|
|
9
9
|
} from "../config/loader.js";
|
|
10
10
|
import { getConversationOverrideProfile } from "../memory/conversation-crud.js";
|
|
11
|
-
import { PROVIDER_CATALOG } from "../providers/model-catalog.js";
|
|
12
11
|
import { getConfiguredProviders } from "../providers/provider-availability.js";
|
|
12
|
+
import { getVisibleProviderCatalog } from "../providers/provider-catalog-visibility.js";
|
|
13
13
|
|
|
14
14
|
export type SlashResolution =
|
|
15
15
|
| { kind: "passthrough"; content: string }
|
|
@@ -132,7 +132,10 @@ function parseModelCommand(trimmed: string): ModelCommandParse | null {
|
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
function orderedProfileNames(
|
|
135
|
-
profiles: Record<
|
|
135
|
+
profiles: Record<
|
|
136
|
+
string,
|
|
137
|
+
{ label?: string; description?: string; status?: "active" | "disabled" }
|
|
138
|
+
>,
|
|
136
139
|
profileOrder: readonly string[] | undefined,
|
|
137
140
|
): string[] {
|
|
138
141
|
const order = profileOrder ?? [];
|
|
@@ -177,8 +180,12 @@ async function resolveModelCommand(
|
|
|
177
180
|
const isDisabled = profile.status === "disabled";
|
|
178
181
|
const marker = isCurrent ? " **[current]**" : "";
|
|
179
182
|
const disabled = isDisabled ? " *(disabled)*" : "";
|
|
180
|
-
const description = profile.description
|
|
181
|
-
|
|
183
|
+
const description = profile.description
|
|
184
|
+
? ` — ${profile.description}`
|
|
185
|
+
: "";
|
|
186
|
+
lines.push(
|
|
187
|
+
` - \`${name}\` (${label})${marker}${disabled}${description}`,
|
|
188
|
+
);
|
|
182
189
|
}
|
|
183
190
|
lines.push("\nSwitch with `/model <name>`.");
|
|
184
191
|
return { kind: "unknown", message: lines.join("\n") };
|
|
@@ -240,7 +247,7 @@ async function resolveModelList(): Promise<SlashResolution> {
|
|
|
240
247
|
id: provider,
|
|
241
248
|
displayName: providerName,
|
|
242
249
|
models,
|
|
243
|
-
} of
|
|
250
|
+
} of getVisibleProviderCatalog(config)) {
|
|
244
251
|
const hasKey = configuredProviders.has(provider);
|
|
245
252
|
const status = hasKey ? "✓" : "✗";
|
|
246
253
|
lines.push(`**${providerName}** ${status}`);
|
|
@@ -21,7 +21,9 @@ import { buildSystemPrompt } from "../prompts/system-prompt.js";
|
|
|
21
21
|
import { wrapWithCallSiteRouting } from "../providers/call-site-routing.js";
|
|
22
22
|
import { resolveDefaultProvider } from "../providers/connection-resolution.js";
|
|
23
23
|
import { RateLimitProvider } from "../providers/ratelimit.js";
|
|
24
|
+
import { listProviders } from "../providers/registry.js";
|
|
24
25
|
import { getSubagentManager } from "../subagent/index.js";
|
|
26
|
+
import { ProviderNotConfiguredError } from "../util/errors.js";
|
|
25
27
|
import { getSandboxWorkingDir } from "../util/platform.js";
|
|
26
28
|
import { Conversation } from "./conversation.js";
|
|
27
29
|
import type { ConversationEvictor } from "./conversation-evictor.js";
|
|
@@ -226,12 +228,17 @@ export async function getOrCreateConversation(
|
|
|
226
228
|
// Connection-aware default-provider resolution. Throws
|
|
227
229
|
// `ConnectionResolutionError` when the default profile's
|
|
228
230
|
// `provider_connection` is unset / unknown / mismatched (config
|
|
229
|
-
// bugs). Returns null on soft credential failures (
|
|
230
|
-
//
|
|
231
|
+
// bugs). Returns null on soft credential failures (missing
|
|
232
|
+
// credential, platform auth unavailable).
|
|
231
233
|
const baseProvider = await resolveDefaultProvider(config);
|
|
232
234
|
if (!baseProvider) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
+
const resolved = resolveCallSiteConfig("mainAgent", config.llm);
|
|
236
|
+
throw new ProviderNotConfiguredError(
|
|
237
|
+
resolved.provider,
|
|
238
|
+
listProviders(),
|
|
239
|
+
{
|
|
240
|
+
connectionName: resolved.provider_connection,
|
|
241
|
+
},
|
|
235
242
|
);
|
|
236
243
|
}
|
|
237
244
|
// Per-call `callSite` routing layered on top, with connection-awareness
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
} from "../channels/types.js";
|
|
14
14
|
import { isHttpAuthDisabled } from "../config/env.js";
|
|
15
15
|
import { getIsPlatform } from "../config/env-registry.js";
|
|
16
|
+
import { getConfig } from "../config/loader.js";
|
|
16
17
|
import { getBindingByConversation } from "../memory/external-conversation-store.js";
|
|
17
18
|
import type { PermissionPrompter } from "../permissions/prompter.js";
|
|
18
19
|
import type { SecretPrompter } from "../permissions/secret-prompter.js";
|
|
@@ -392,7 +393,8 @@ const CROSS_CLIENT_EXPOSED_CAPABILITIES = new Set<HostProxyCapability>([
|
|
|
392
393
|
"host_file",
|
|
393
394
|
"host_browser",
|
|
394
395
|
]);
|
|
395
|
-
|
|
396
|
+
// Tools that require a connected client but no specific host proxy capability.
|
|
397
|
+
const CLIENT_CAPABILITY_TOOL_NAMES = new Set(["app_open", "ask_question"]);
|
|
396
398
|
const PLATFORM_TOOL_NAMES = new Set(["request_system_permission"]);
|
|
397
399
|
|
|
398
400
|
/**
|
|
@@ -406,16 +408,34 @@ export const SUBAGENT_ONLY_TOOL_NAMES = new Set<string>([
|
|
|
406
408
|
]);
|
|
407
409
|
|
|
408
410
|
/**
|
|
409
|
-
* Determine whether a tool
|
|
410
|
-
*
|
|
411
|
-
*
|
|
412
|
-
*
|
|
413
|
-
* fail.
|
|
411
|
+
* Determine whether a tool is part of the final exposed tool set for the
|
|
412
|
+
* current turn. This helper mirrors the filtering applied by
|
|
413
|
+
* `createResolveToolsCallback` — including the subagent allowlist,
|
|
414
|
+
* `toolsDisabledDepth`, and disk-pressure cleanup restrictions.
|
|
414
415
|
*/
|
|
415
416
|
export function isToolActiveForContext(
|
|
416
417
|
name: string,
|
|
417
418
|
ctx: SkillProjectionContext,
|
|
418
419
|
): boolean {
|
|
420
|
+
// When the conversation is acting as a subagent, the parent orchestrator
|
|
421
|
+
// restricts the tool list. A tool that isn't on the allowlist is not
|
|
422
|
+
// available for this turn, so short-circuit before any capability checks.
|
|
423
|
+
if (ctx.subagentAllowedTools && !ctx.subagentAllowedTools.has(name)) {
|
|
424
|
+
return false;
|
|
425
|
+
}
|
|
426
|
+
// `createResolveToolsCallback` returns an empty tool list when tools are
|
|
427
|
+
// disabled (e.g. pointer-generation turns) and restricts to cleanup-safe
|
|
428
|
+
// tools under disk pressure. Mirror both here so this helper reports the
|
|
429
|
+
// same final tool set the LLM receives.
|
|
430
|
+
if (ctx.toolsDisabledDepth > 0) {
|
|
431
|
+
return false;
|
|
432
|
+
}
|
|
433
|
+
if (
|
|
434
|
+
ctx.diskPressureCleanupModeActive === true &&
|
|
435
|
+
!isDiskPressureCleanupToolName(name)
|
|
436
|
+
) {
|
|
437
|
+
return false;
|
|
438
|
+
}
|
|
419
439
|
if (UI_SURFACE_TOOL_NAMES.has(name)) {
|
|
420
440
|
return ctx.channelCapabilities?.supportsDynamicUi ?? !ctx.hasNoClient;
|
|
421
441
|
}
|
|
@@ -463,6 +483,14 @@ export function isToolActiveForContext(
|
|
|
463
483
|
return !ctx.hasNoClient;
|
|
464
484
|
}
|
|
465
485
|
if (CLIENT_CAPABILITY_TOOL_NAMES.has(name)) {
|
|
486
|
+
if (
|
|
487
|
+
name === "ask_question" &&
|
|
488
|
+
ctx.channelCapabilities?.clientOS === "macos"
|
|
489
|
+
) {
|
|
490
|
+
// macOS has no UI handler for question_request yet; hiding the tool
|
|
491
|
+
// avoids a 5-minute prompter timeout when the LLM would otherwise call it.
|
|
492
|
+
return false;
|
|
493
|
+
}
|
|
466
494
|
return !ctx.hasNoClient;
|
|
467
495
|
}
|
|
468
496
|
if (PLATFORM_TOOL_NAMES.has(name)) {
|
|
@@ -544,7 +572,10 @@ export function createResolveToolsCallback(
|
|
|
544
572
|
const scopedMcpDefs = ctx.subagentAllowedTools
|
|
545
573
|
? currentMcpDefs.filter((d) => ctx.subagentAllowedTools!.has(d.name))
|
|
546
574
|
: currentMcpDefs;
|
|
547
|
-
const
|
|
575
|
+
const excluded = new Set(getConfig().tools.exclude);
|
|
576
|
+
const allBaseDefs = [...scopedCoreDefs, ...scopedMcpDefs].filter(
|
|
577
|
+
(d) => !excluded.has(d.name),
|
|
578
|
+
);
|
|
548
579
|
|
|
549
580
|
const effectivePreactivated = [
|
|
550
581
|
...DEFAULT_PREACTIVATED_SKILL_IDS,
|
|
@@ -561,6 +592,7 @@ export function createResolveToolsCallback(
|
|
|
561
592
|
if (ctx.subagentAllowedTools && !ctx.subagentAllowedTools.has(name)) {
|
|
562
593
|
continue;
|
|
563
594
|
}
|
|
595
|
+
if (excluded.has(name)) continue;
|
|
564
596
|
turnAllowed.add(name);
|
|
565
597
|
}
|
|
566
598
|
if (ctx.diskPressureCleanupModeActive === true) {
|
|
@@ -56,6 +56,7 @@ import {
|
|
|
56
56
|
} from "../memory/conversation-crud.js";
|
|
57
57
|
import { isBackgroundConversationType } from "../memory/conversation-types.js";
|
|
58
58
|
import { ConversationGraphMemory } from "../memory/graph/conversation-graph-memory.js";
|
|
59
|
+
import { shouldExposePersonalMemory } from "../memory/v2/static-context.js";
|
|
59
60
|
import { PermissionPrompter } from "../permissions/prompter.js";
|
|
60
61
|
import { SecretPrompter } from "../permissions/secret-prompter.js";
|
|
61
62
|
import type { UserDecision } from "../permissions/types.js";
|
|
@@ -118,6 +119,7 @@ import {
|
|
|
118
119
|
buildToolDefinitions,
|
|
119
120
|
createResolveToolsCallback,
|
|
120
121
|
createToolExecutor,
|
|
122
|
+
resolveTrustClass,
|
|
121
123
|
} from "./conversation-tool-setup.js";
|
|
122
124
|
import { refreshWorkspaceTopLevelContextIfNeeded as refreshWorkspaceImpl } from "./conversation-workspace.js";
|
|
123
125
|
import { canonicalizeTimeZone } from "./date-context.js";
|
|
@@ -180,6 +182,17 @@ export class Conversation {
|
|
|
180
182
|
/** @internal */ contextWindowManager: ContextWindowManager;
|
|
181
183
|
/** @internal */ contextCompactedMessageCount = 0;
|
|
182
184
|
/** @internal */ contextCompactedAt: number | null = null;
|
|
185
|
+
/**
|
|
186
|
+
* Set true by `applyCompactionResult` when compaction strips runtime
|
|
187
|
+
* injections from the tail. The next agent loop turn reads this flag at
|
|
188
|
+
* entry, treats it as a `compactedThisTurn` trigger (re-injecting NOW.md,
|
|
189
|
+
* PKB, and the v2 essentials/threads/recent/buffer block), and clears it.
|
|
190
|
+
*
|
|
191
|
+
* Required because `/compact` runs outside the agent loop — without this
|
|
192
|
+
* signal, the next turn cannot tell that the static blocks were just
|
|
193
|
+
* stripped and never re-emits them.
|
|
194
|
+
*/
|
|
195
|
+
/** @internal */ pendingPostCompactReinject = false;
|
|
183
196
|
/**
|
|
184
197
|
* Tracks consecutive compaction failures (summary LLM call threw). In-memory
|
|
185
198
|
* only — resets to 0 on process restart, which is the intended "one free
|
|
@@ -225,6 +238,7 @@ export class Conversation {
|
|
|
225
238
|
/** @internal */ currentTurnOverrideProfile?: string;
|
|
226
239
|
/** @internal */ authContext?: AuthContext;
|
|
227
240
|
/** @internal */ loadedHistoryTrustClass?: TrustClass;
|
|
241
|
+
/** @internal */ loadedHistoryPersonalMemoryAllowed?: boolean;
|
|
228
242
|
/** @internal */ voiceCallControlPrompt?: string;
|
|
229
243
|
/** @internal */ transportHints?: string[];
|
|
230
244
|
/** @internal */ slackRuntimeContextNotice?: string;
|
|
@@ -527,6 +541,10 @@ export class Conversation {
|
|
|
527
541
|
systemPrompt: () => resolveSystemPromptCallback([]).systemPrompt,
|
|
528
542
|
config: initialContextWindowConfig,
|
|
529
543
|
toolTokenBudget: this.agentLoop.getToolTokenBudget(),
|
|
544
|
+
conversationId: this.conversationId,
|
|
545
|
+
resolveTools: resolveTools
|
|
546
|
+
? () => resolveTools(this.messages)
|
|
547
|
+
: undefined,
|
|
530
548
|
});
|
|
531
549
|
}
|
|
532
550
|
|
|
@@ -647,7 +665,21 @@ export class Conversation {
|
|
|
647
665
|
|
|
648
666
|
async ensureActorScopedHistory(): Promise<void> {
|
|
649
667
|
const currentTrustClass = this.trustContext?.trustClass;
|
|
650
|
-
|
|
668
|
+
// `loadFromDb` gates personal-memory rehydration on `sourceChannel` too
|
|
669
|
+
// (via `shouldExposePersonalMemory`), so a same-trust-class reuse from a
|
|
670
|
+
// different channel (e.g. internal `vellum` → remote channel) must also
|
|
671
|
+
// trigger a reload. Otherwise stale personal-memory blocks can leak to
|
|
672
|
+
// an untrusted remote turn, or be hidden when they should be present.
|
|
673
|
+
const currentPersonalMemoryAllowed = shouldExposePersonalMemory({
|
|
674
|
+
sourceChannel: this.trustContext?.sourceChannel,
|
|
675
|
+
isTrustedActor: resolveTrustClass(this.trustContext) === "guardian",
|
|
676
|
+
});
|
|
677
|
+
if (
|
|
678
|
+
this.loadedHistoryTrustClass === currentTrustClass &&
|
|
679
|
+
this.loadedHistoryPersonalMemoryAllowed === currentPersonalMemoryAllowed
|
|
680
|
+
) {
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
651
683
|
await this.loadFromDb();
|
|
652
684
|
}
|
|
653
685
|
|