@vellumai/assistant 0.8.4 → 0.8.6
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/AGENTS.md +33 -1
- package/ARCHITECTURE.md +3 -3
- package/bunfig.toml +6 -1
- package/docs/browser-use-architecture-phase2.md +1 -1
- package/docs/credential-execution-service.md +6 -6
- package/docs/plugins.md +4 -3
- package/knip.json +2 -1
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
- package/openapi.yaml +2748 -216
- package/package.json +1 -1
- package/src/__tests__/actor-token-service.test.ts +3 -2
- package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
- package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
- package/src/__tests__/annotate-risk-options.test.ts +1 -0
- package/src/__tests__/anthropic-provider.test.ts +34 -37
- package/src/__tests__/approval-cascade.test.ts +1 -0
- package/src/__tests__/approval-routes-http.test.ts +9 -13
- package/src/__tests__/assert-not-live-db.ts +79 -0
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +12 -28
- package/src/__tests__/audit-log-rotation.test.ts +72 -18
- package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
- package/src/__tests__/background-workers-disk-pressure.test.ts +8 -11
- package/src/__tests__/browser-skill-endstate.test.ts +3 -3
- package/src/__tests__/btw-routes.test.ts +5 -5
- package/src/__tests__/call-controller.test.ts +3 -3
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +3 -2
- package/src/__tests__/channel-guardian.test.ts +6 -5
- package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
- package/src/__tests__/channel-reply-delivery.test.ts +35 -0
- package/src/__tests__/channel-retry-sweep.test.ts +320 -3
- package/src/__tests__/checker.test.ts +18 -27
- package/src/__tests__/compaction-events.test.ts +2 -0
- package/src/__tests__/compaction-trail-store.test.ts +264 -0
- package/src/__tests__/compactor-call-site-logging.test.ts +215 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -16
- package/src/__tests__/computer-use-tools.test.ts +14 -18
- package/src/__tests__/config-loader-backfill.test.ts +13 -28
- package/src/__tests__/config-loader-corrupt.test.ts +5 -5
- package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
- package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
- package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
- package/src/__tests__/config-schema.test.ts +10 -10
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/connection-model-compat.test.ts +83 -0
- package/src/__tests__/contacts-tools.test.ts +3 -2
- package/src/__tests__/context-token-estimator.test.ts +22 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +231 -2
- package/src/__tests__/conversation-agent-loop.test.ts +581 -54
- package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
- package/src/__tests__/conversation-app-control-instantiation.test.ts +31 -24
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
- package/src/__tests__/conversation-attention-store.test.ts +101 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
- package/src/__tests__/conversation-clear-safety.test.ts +25 -25
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-error.test.ts +61 -0
- package/src/__tests__/conversation-fork-crud.test.ts +239 -15
- package/src/__tests__/conversation-fork-route.test.ts +3 -2
- package/src/__tests__/conversation-history-web-search.test.ts +1 -0
- package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
- package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
- package/src/__tests__/conversation-lifecycle.test.ts +53 -11
- package/src/__tests__/conversation-list-source.test.ts +3 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
- package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +14 -13
- package/src/__tests__/conversation-pairing.test.ts +53 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
- package/src/__tests__/conversation-process-callsite.test.ts +1 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/conversation-queue.test.ts +333 -291
- package/src/__tests__/conversation-routes-disk-view.test.ts +112 -18
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
- package/src/__tests__/conversation-routes-slash-commands.test.ts +68 -2
- package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
- package/src/__tests__/conversation-skill-tools.test.ts +40 -147
- package/src/__tests__/conversation-slash-queue.test.ts +84 -32
- package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
- package/src/__tests__/conversation-speed-override.test.ts +1 -0
- package/src/__tests__/conversation-store.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
- package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
- package/src/__tests__/conversation-sync-tags.test.ts +218 -35
- package/src/__tests__/conversation-title-service.test.ts +1 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
- package/src/__tests__/conversation-usage.test.ts +1 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -1
- package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
- package/src/__tests__/credential-broker-server-use.test.ts +5 -5
- package/src/__tests__/credential-execution-client.test.ts +72 -1
- package/src/__tests__/credential-execution-feature-gates.test.ts +19 -19
- package/src/__tests__/credential-execution-tools.test.ts +6 -6
- package/src/__tests__/credential-health-service.test.ts +252 -3
- package/src/__tests__/credential-security-invariants.test.ts +6 -5
- package/src/__tests__/credential-vault-unit.test.ts +21 -21
- package/src/__tests__/credential-vault.test.ts +5 -5
- package/src/__tests__/cross-provider-web-search.test.ts +56 -2
- package/src/__tests__/db-connection-isolation.test.ts +7 -6
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
- package/src/__tests__/db-test-helpers.ts +58 -0
- package/src/__tests__/disk-pressure-guard.test.ts +58 -41
- package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
- package/src/__tests__/disk-pressure-routes.test.ts +0 -33
- package/src/__tests__/disk-pressure-tools.test.ts +0 -4
- package/src/__tests__/dm-persistence.test.ts +26 -40
- package/src/__tests__/document-create-dedupe.test.ts +189 -0
- package/src/__tests__/document-find-replace.test.ts +3 -2
- package/src/__tests__/document-tool-security.test.ts +81 -2
- package/src/__tests__/dynamic-page-surface.test.ts +2 -2
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
- package/src/__tests__/email-html-renderer.test.ts +12 -0
- package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
- package/src/__tests__/encrypted-store.test.ts +11 -9
- package/src/__tests__/feature-flag-test-helpers.ts +53 -0
- package/src/__tests__/filing-service.test.ts +1 -0
- package/src/__tests__/first-greeting.test.ts +62 -12
- package/src/__tests__/gateway-flag-listener.test.ts +236 -0
- package/src/__tests__/gemini-provider.test.ts +104 -0
- package/src/__tests__/guardian-action-sweep.test.ts +3 -2
- package/src/__tests__/guardian-dispatch.test.ts +0 -1
- package/src/__tests__/guardian-outbound-http.test.ts +10 -7
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +5 -0
- package/src/__tests__/heartbeat-service.test.ts +5 -0
- package/src/__tests__/helpers/mock-logger.ts +26 -0
- package/src/__tests__/host-bash-routes.test.ts +1 -0
- package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-shell-tool.test.ts +6 -5
- package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
- package/src/__tests__/http-conversation-lineage.test.ts +3 -2
- package/src/__tests__/http-user-message-parity.test.ts +29 -7
- package/src/__tests__/identity-intro-cache.test.ts +133 -22
- package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
- package/src/__tests__/inference-profile-reaper.test.ts +3 -2
- package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
- package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
- package/src/__tests__/injector-disk-pressure.test.ts +3 -17
- package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
- package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
- package/src/__tests__/llm-context-normalization.test.ts +42 -0
- package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
- package/src/__tests__/llm-resolver.test.ts +408 -9
- package/src/__tests__/llm-schema.test.ts +1 -1
- package/src/__tests__/llm-usage-store.test.ts +66 -0
- package/src/__tests__/logger.test.ts +89 -0
- package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
- package/src/__tests__/mcp-abort-signal.test.ts +16 -2
- package/src/__tests__/mcp-client-auth.test.ts +14 -0
- package/src/__tests__/media-generate-image.test.ts +31 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
- package/src/__tests__/messaging-send-tool.test.ts +1 -0
- package/src/__tests__/migration-import-from-url.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +18 -2
- package/src/__tests__/model-intents.test.ts +4 -6
- package/src/__tests__/native-web-search.test.ts +30 -2
- package/src/__tests__/notification-deep-link.test.ts +62 -0
- package/src/__tests__/notification-guardian-path.test.ts +0 -1
- package/src/__tests__/oauth-commands-routes.test.ts +37 -0
- package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
- package/src/__tests__/oauth-store.test.ts +3 -2
- package/src/__tests__/onboarding-template-contract.test.ts +4 -3
- package/src/__tests__/openai-provider.test.ts +54 -9
- package/src/__tests__/openai-responses-provider.test.ts +176 -14
- package/src/__tests__/openrouter-provider-only.test.ts +27 -5
- package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
- package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
- package/src/__tests__/persistence-pipeline.test.ts +139 -1
- package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
- package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
- package/src/__tests__/platform.test.ts +2 -2
- package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
- package/src/__tests__/plugin-bootstrap.test.ts +11 -13
- package/src/__tests__/plugin-tool-contribution.test.ts +50 -40
- package/src/__tests__/plugin-types.test.ts +3 -2
- package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
- package/src/__tests__/pricing.test.ts +12 -0
- package/src/__tests__/process-message-background-slack.test.ts +21 -16
- package/src/__tests__/process-message-display-content.test.ts +19 -22
- package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
- package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
- package/src/__tests__/provider-registry-ollama.test.ts +45 -22
- package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
- package/src/__tests__/recording-handler.test.ts +1 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +84 -84
- package/src/__tests__/relay-server.test.ts +10 -10
- package/src/__tests__/require-fresh-approval.test.ts +2 -2
- package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
- package/src/__tests__/schedule-store.test.ts +16 -1
- package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
- package/src/__tests__/secret-ingress-http.test.ts +5 -1
- package/src/__tests__/secure-keys.test.ts +3 -3
- package/src/__tests__/send-endpoint-busy.test.ts +81 -42
- package/src/__tests__/server-history-render.test.ts +4 -1
- package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
- package/src/__tests__/skill-feature-flags.test.ts +16 -18
- package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
- package/src/__tests__/skill-projection-feature-flag.test.ts +48 -37
- package/src/__tests__/skill-projection.benchmark.test.ts +7 -13
- package/src/__tests__/skill-tool-factory.test.ts +97 -96
- package/src/__tests__/slack-channel-config.test.ts +3 -3
- package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
- package/src/__tests__/subagent-disposal.test.ts +27 -8
- package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
- package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
- package/src/__tests__/subagent-manager-notify.test.ts +20 -8
- package/src/__tests__/subagent-notify-parent.test.ts +6 -5
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
- package/src/__tests__/subagent-tools.test.ts +2 -1
- package/src/__tests__/suggestion-routes.test.ts +2 -0
- package/src/__tests__/sync-message-contract.test.ts +59 -0
- package/src/__tests__/system-prompt.test.ts +183 -131
- package/src/__tests__/terminal-tools.test.ts +1 -1
- package/src/__tests__/test-preload-verifier.ts +68 -0
- package/src/__tests__/test-preload.ts +32 -39
- package/src/__tests__/tool-approval-handler.test.ts +1 -5
- package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +35 -12
- package/src/__tests__/tool-executor.test.ts +64 -72
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
- package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
- package/src/__tests__/twilio-routes.test.ts +3 -2
- package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
- package/src/__tests__/usage-routes.test.ts +3 -0
- package/src/__tests__/validate-input.test.ts +381 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +3 -2
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
- package/src/__tests__/voice-session-bridge.test.ts +37 -28
- package/src/__tests__/workspace-git-service.test.ts +6 -5
- package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
- package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
- package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
- package/src/acp/prepare-agent-env.ts +78 -0
- package/src/acp/session-manager.ts +6 -7
- package/src/agent/loop.ts +88 -0
- package/src/api/README.md +127 -0
- package/src/api/constants/call-sites.ts +27 -0
- package/src/api/events/assistant-outbound-attachment.ts +51 -0
- package/src/api/events/assistant-text-delta.ts +32 -0
- package/src/api/events/assistant-turn-start.ts +33 -0
- package/src/api/events/document-comment-created.ts +48 -0
- package/src/api/events/document-comment-deleted.ts +24 -0
- package/src/api/events/document-comment-reopened.ts +25 -0
- package/src/api/events/document-comment-resolved.ts +27 -0
- package/src/api/events/generation-cancelled.ts +24 -0
- package/src/api/events/generation-handoff.ts +41 -0
- package/src/api/events/message-complete.ts +42 -0
- package/src/api/events/open-url.ts +30 -0
- package/src/api/events/relationship-state-updated.ts +25 -0
- package/src/api/events/tool-use-start.ts +32 -0
- package/src/api/index.ts +129 -0
- package/src/api/package.json +10 -0
- package/src/api/responses/llm-context-response.ts +39 -0
- package/src/api/responses/llm-request-log-entry.ts +93 -0
- package/src/api/responses/memory-recall-log.ts +65 -0
- package/src/api/responses/memory-v2-activation-log.ts +78 -0
- package/src/background-wake/background-wake-routes.test.ts +868 -0
- package/src/background-wake/platform-client.test.ts +308 -0
- package/src/background-wake/platform-client.ts +167 -0
- package/src/background-wake/publisher.ts +91 -0
- package/src/background-wake/runtime-registry.ts +24 -0
- package/src/background-wake/wake-intent-hooks.test.ts +282 -0
- package/src/calls/guardian-dispatch.ts +1 -0
- package/src/calls/voice-session-bridge.ts +4 -4
- package/src/cli/commands/__tests__/browser.test.ts +23 -5
- package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
- package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
- package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +1 -0
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
- package/src/cli/commands/__tests__/notifications.test.ts +184 -40
- package/src/cli/commands/browser.ts +247 -0
- package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
- package/src/cli/commands/channels/index.ts +229 -0
- package/src/cli/commands/domain.ts +91 -41
- package/src/cli/commands/inference.ts +93 -40
- package/src/cli/commands/memory-v2-compare-render.ts +115 -0
- package/src/cli/commands/memory-v2.ts +176 -1
- package/src/cli/commands/memory-v3-render.ts +491 -0
- package/src/cli/commands/memory-v3.ts +567 -0
- package/src/cli/commands/notifications.ts +365 -55
- package/src/cli/lib/open-browser.ts +7 -2
- package/src/cli/program.ts +4 -0
- package/src/config/assistant-feature-flags.ts +39 -46
- package/src/config/bundled-skills/document-editor/SKILL.md +16 -3
- package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
- package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
- package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +1 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
- package/src/config/bundled-tool-registry.ts +2 -0
- package/src/config/call-site-defaults.ts +8 -7
- package/src/config/feature-flag-cache.ts +86 -0
- package/src/config/feature-flag-registry.json +33 -17
- package/src/config/llm-context-resolution.ts +10 -1
- package/src/config/llm-resolver.ts +121 -15
- package/src/config/loader.ts +4 -5
- package/src/config/schemas/__tests__/memory-v2.test.ts +228 -1
- package/src/config/schemas/call-site-catalog.ts +21 -7
- package/src/config/schemas/heartbeat.ts +1 -1
- package/src/config/schemas/llm.ts +102 -2
- package/src/config/schemas/memory-v2.ts +272 -0
- package/src/config/schemas/memory.ts +2 -1
- package/src/config/schemas/services.ts +6 -2
- package/src/config/seed-inference-profiles.ts +36 -16
- package/src/context/compactor.ts +52 -0
- package/src/context/token-estimator.ts +10 -5
- package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
- package/src/conversations/message-consolidation.ts +404 -0
- package/src/credential-execution/executable-discovery.ts +40 -0
- package/src/credential-execution/process-manager.ts +6 -2
- package/src/credential-health/credential-health-service.ts +125 -40
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +2 -3
- package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
- package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +390 -80
- package/src/daemon/conversation-agent-loop.ts +244 -90
- package/src/daemon/conversation-error.ts +64 -6
- package/src/daemon/conversation-lifecycle.ts +27 -22
- package/src/daemon/conversation-messaging.ts +84 -43
- package/src/daemon/conversation-process.ts +74 -37
- package/src/daemon/conversation-runtime-assembly.ts +38 -17
- package/src/daemon/conversation-skill-tools.ts +14 -30
- package/src/daemon/conversation-surfaces.ts +69 -34
- package/src/daemon/conversation-tool-setup.ts +77 -32
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +40 -75
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/daemon-skill-host.ts +9 -2
- package/src/daemon/disk-pressure-guard.ts +39 -29
- package/src/daemon/first-greeting.ts +31 -13
- package/src/daemon/handlers/config-model.test.ts +1 -0
- package/src/daemon/handlers/conversations.ts +11 -3
- package/src/daemon/handlers/shared.ts +6 -1
- package/src/daemon/host-browser-proxy.ts +5 -5
- package/src/daemon/host-cu-proxy.ts +4 -4
- package/src/daemon/host-file-proxy.ts +4 -4
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/host-transfer-proxy.ts +10 -10
- package/src/daemon/lifecycle.ts +29 -26
- package/src/daemon/mcp-reload-service.ts +1 -1
- package/src/daemon/meet-manifest-loader.ts +11 -24
- package/src/daemon/message-types/conversations.ts +22 -27
- package/src/daemon/message-types/document-comments.ts +8 -44
- package/src/daemon/message-types/home.ts +2 -14
- package/src/daemon/message-types/integrations.ts +2 -7
- package/src/daemon/message-types/messages.ts +25 -48
- package/src/daemon/message-types/subagents.ts +6 -0
- package/src/daemon/message-types/sync.ts +14 -0
- package/src/daemon/process-message.ts +9 -9
- package/src/daemon/providers-setup.ts +1 -1
- package/src/daemon/server.ts +16 -0
- package/src/daemon/shutdown-handlers.ts +24 -5
- package/src/daemon/switch-inference-profile-tool.ts +62 -0
- package/src/daemon/tool-setup-types.ts +7 -0
- package/src/daemon/wake-target-adapter.ts +10 -0
- package/src/documents/document-store.ts +38 -0
- package/src/export/__tests__/transcript-formatter.test.ts +1 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +30 -1
- package/src/heartbeat/heartbeat-service.ts +63 -0
- package/src/home/__tests__/feed-writer.test.ts +161 -0
- package/src/home/__tests__/post-connect-feed.test.ts +1 -0
- package/src/home/__tests__/suggested-prompts.test.ts +55 -59
- package/src/home/feed-writer.ts +146 -7
- package/src/home/home-greeting.ts +0 -9
- package/src/home/suggested-prompts.ts +27 -154
- package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
- package/src/ipc/gateway-client.test.ts +4 -1
- package/src/ipc/gateway-flag-listener.ts +123 -0
- package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
- package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
- package/src/ipc/skill-routes/memory.ts +4 -3
- package/src/ipc/skill-routes/registries.ts +35 -40
- package/src/memory/__tests__/db-async-query.test.ts +165 -0
- package/src/memory/__tests__/db-maintenance.test.ts +115 -0
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +242 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
- package/src/memory/auto-analysis-enqueue.ts +5 -1
- package/src/memory/conversation-attention-store.ts +17 -3
- package/src/memory/conversation-crud.ts +423 -182
- package/src/memory/conversation-starters-cadence.ts +3 -1
- package/src/memory/conversation-title-service.ts +19 -3
- package/src/memory/db-async-query.ts +214 -0
- package/src/memory/db-connection.ts +29 -19
- package/src/memory/db-init.ts +14 -0
- package/src/memory/db-maintenance.ts +30 -21
- package/src/memory/db-singleton.ts +77 -0
- package/src/memory/delivery-channels.ts +82 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
- package/src/memory/graph/bootstrap.ts +8 -1
- package/src/memory/graph/capability-seed.ts +7 -3
- package/src/memory/graph/conversation-graph-memory.ts +100 -17
- package/src/memory/graph/extraction.ts +1 -5
- package/src/memory/graph/graph-search.ts +7 -1
- package/src/memory/graph/retriever.test.ts +3 -3
- package/src/memory/indexer.ts +28 -18
- package/src/memory/job-handlers/cleanup.ts +76 -18
- package/src/memory/job-handlers/conversation-starters.ts +1 -4
- package/src/memory/job-handlers/embedding.test.ts +3 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
- package/src/memory/jobs/embed-pkb-file.ts +6 -1
- package/src/memory/jobs-store.ts +14 -0
- package/src/memory/jobs-worker.ts +66 -22
- package/src/memory/llm-request-log-source-clickhouse.ts +122 -2
- package/src/memory/llm-request-log-source-local.ts +31 -0
- package/src/memory/llm-request-log-source.ts +40 -2
- package/src/memory/llm-request-log-store.ts +228 -1
- package/src/memory/llm-usage-store.ts +24 -0
- package/src/memory/memory-retrospective-enqueue.ts +8 -1
- package/src/memory/memory-retrospective-job.ts +5 -0
- package/src/memory/memory-v2-activation-log-store.ts +110 -7
- package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
- package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
- package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
- package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
- package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
- package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
- package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
- package/src/memory/migrations/index.ts +19 -0
- package/src/memory/migrations/registry.ts +33 -0
- package/src/memory/schema/conversations.ts +10 -2
- package/src/memory/schema/inference.ts +0 -1
- package/src/memory/schema/infrastructure.ts +21 -0
- package/src/memory/tool-usage-store.ts +36 -8
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
- package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
- package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
- package/src/memory/v2/__tests__/harness-metrics.test.ts +83 -0
- package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +230 -0
- package/src/memory/v2/__tests__/harness-runner.test.ts +135 -0
- package/src/memory/v2/__tests__/injection.test.ts +127 -98
- package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
- package/src/memory/v2/__tests__/router.test.ts +171 -3
- package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
- package/src/memory/v2/harness/compare.ts +57 -0
- package/src/memory/v2/harness/metrics.ts +128 -0
- package/src/memory/v2/harness/oracle.ts +145 -0
- package/src/memory/v2/harness/replay-input.ts +240 -0
- package/src/memory/v2/harness/retriever.ts +74 -0
- package/src/memory/v2/harness/router-retriever.ts +43 -0
- package/src/memory/v2/harness/runner.ts +112 -0
- package/src/memory/v2/harness/trace.ts +64 -0
- package/src/memory/v2/injection.ts +21 -15
- package/src/memory/v2/prompts/router.ts +26 -1
- package/src/memory/v2/qdrant.ts +14 -2
- package/src/memory/v2/router.ts +171 -18
- package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
- package/src/memory/v3/__tests__/consolidation-job.test.ts +466 -0
- package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
- package/src/memory/v3/__tests__/edges.test.ts +706 -0
- package/src/memory/v3/__tests__/filter.test.ts +560 -0
- package/src/memory/v3/__tests__/gate.test.ts +637 -0
- package/src/memory/v3/__tests__/index-composition.test.ts +291 -0
- package/src/memory/v3/__tests__/loop.test.ts +775 -0
- package/src/memory/v3/__tests__/retriever.test.ts +226 -0
- package/src/memory/v3/__tests__/scouts.test.ts +489 -0
- package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +398 -0
- package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
- package/src/memory/v3/__tests__/traversal.test.ts +508 -0
- package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
- package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
- package/src/memory/v3/__tests__/tree-walk.test.ts +784 -0
- package/src/memory/v3/__tests__/validate.test.ts +277 -0
- package/src/memory/v3/auto-edges.ts +223 -0
- package/src/memory/v3/coactivation-store.ts +124 -0
- package/src/memory/v3/consolidation-job.ts +323 -0
- package/src/memory/v3/coretrieval-seed.ts +240 -0
- package/src/memory/v3/edge-learning-job.ts +160 -0
- package/src/memory/v3/edges.ts +286 -0
- package/src/memory/v3/filter.ts +286 -0
- package/src/memory/v3/gate.ts +349 -0
- package/src/memory/v3/index-composition.ts +126 -0
- package/src/memory/v3/llm-capture.ts +46 -0
- package/src/memory/v3/loop.ts +430 -0
- package/src/memory/v3/maintenance.ts +144 -0
- package/src/memory/v3/prompt-context.ts +33 -0
- package/src/memory/v3/prompts/consolidation.ts +458 -0
- package/src/memory/v3/prompts/system-prompts.ts +196 -0
- package/src/memory/v3/retriever.ts +33 -0
- package/src/memory/v3/scouts.ts +431 -0
- package/src/memory/v3/shadow-diff.ts +287 -0
- package/src/memory/v3/shadow-middleware.ts +347 -0
- package/src/memory/v3/traversal.ts +211 -0
- package/src/memory/v3/tree-index.ts +237 -0
- package/src/memory/v3/tree-store.ts +394 -0
- package/src/memory/v3/tree-walk.ts +356 -0
- package/src/memory/v3/types.ts +65 -0
- package/src/memory/v3/validate.ts +323 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
- package/src/notifications/adapters/macos.ts +18 -1
- package/src/notifications/adapters/platform.ts +1 -1
- package/src/notifications/adapters/slack.ts +45 -11
- package/src/notifications/broadcaster.ts +114 -63
- package/src/notifications/conversation-pairing.ts +23 -3
- package/src/notifications/decision-engine.ts +1 -4
- package/src/notifications/decisions-store.ts +32 -1
- package/src/notifications/deliveries-store.ts +45 -0
- package/src/notifications/edit-notification.ts +201 -0
- package/src/notifications/emit-signal.ts +40 -50
- package/src/notifications/signal.ts +10 -0
- package/src/notifications/types.ts +37 -0
- package/src/oauth/byo-connection.test.ts +67 -3
- package/src/oauth/byo-connection.ts +32 -5
- package/src/oauth/connect-orchestrator.ts +9 -0
- package/src/oauth/connection-resolver.test.ts +76 -0
- package/src/oauth/connection-resolver.ts +49 -10
- package/src/oauth/manual-token-connection.ts +51 -3
- package/src/oauth/seed-providers.ts +3 -0
- package/src/permissions/approval-policy.test.ts +19 -5
- package/src/permissions/approval-policy.ts +14 -3
- package/src/permissions/checker.ts +21 -8
- package/src/permissions/prompter.ts +3 -3
- package/src/permissions/question-prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +2 -2
- package/src/platform/client.test.ts +24 -1
- package/src/platform/client.ts +8 -0
- package/src/platform/feature-gate.ts +15 -0
- package/src/plugin-api/index.ts +4 -0
- package/src/plugin-api/types.ts +7 -33
- package/src/plugins/defaults/index.ts +6 -0
- package/src/plugins/defaults/injectors.ts +20 -19
- package/src/plugins/defaults/persistence.ts +25 -6
- package/src/plugins/external-plugin-loader.ts +5 -68
- package/src/plugins/types.ts +68 -29
- package/src/proactive-artifact/aux-message-injector.ts +17 -4
- package/src/proactive-artifact/job.test.ts +1 -0
- package/src/prompts/__tests__/system-prompt.test.ts +4 -4
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
- package/src/prompts/persona-resolver.ts +36 -21
- package/src/prompts/sections.ts +39 -7
- package/src/prompts/system-prompt.ts +84 -221
- package/src/prompts/template-detection.ts +10 -4
- package/src/prompts/templates/BOOTSTRAP.md +9 -13
- package/src/prompts/templates/IDENTITY.md +0 -2
- package/src/prompts/templates/system-sections.ts +230 -8
- package/src/providers/__tests__/connection-model-compat.test.ts +233 -0
- package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
- package/src/providers/__tests__/retry-callsite.test.ts +85 -5
- package/src/providers/anthropic/client.ts +32 -66
- package/src/providers/call-site-routing.ts +42 -6
- package/src/providers/connection-model-compat.ts +61 -0
- package/src/providers/connection-resolution.ts +47 -14
- package/src/providers/fireworks/client.ts +1 -0
- package/src/providers/gemini/client.ts +70 -6
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
- package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
- package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
- package/src/providers/inference/adapter-factory.ts +3 -0
- package/src/providers/inference/auth.ts +0 -8
- package/src/providers/inference/connections.ts +3 -66
- package/src/providers/inference/resolve-auth.ts +2 -3
- package/src/providers/minimax/client.ts +106 -0
- package/src/providers/model-catalog.ts +78 -1
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
- package/src/providers/openai/chat-completions-provider.ts +116 -15
- package/src/providers/openai/codex-models.ts +20 -0
- package/src/providers/openai/responses-provider.ts +87 -30
- package/src/providers/openrouter/client.ts +13 -8
- package/src/providers/provider-send-message.ts +20 -5
- package/src/providers/registry.ts +48 -8
- package/src/providers/retry.ts +50 -7
- package/src/providers/search-provider-catalog.ts +17 -9
- package/src/providers/thinking-config.ts +26 -1
- package/src/providers/types.ts +9 -0
- package/src/providers/usage-tracking.ts +2 -0
- package/src/runtime/AGENTS.md +2 -2
- package/src/runtime/__tests__/agent-wake.test.ts +1 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
- package/src/runtime/access-request-helper.ts +1 -0
- package/src/runtime/agent-wake.ts +1 -0
- package/src/runtime/assistant-event-hub.ts +76 -6
- package/src/runtime/auth/route-policy.ts +46 -0
- package/src/runtime/btw-sidechain.ts +0 -6
- package/src/runtime/channel-readiness-service.ts +68 -0
- package/src/runtime/channel-reply-delivery.ts +23 -0
- package/src/runtime/channel-retry-sweep.ts +47 -14
- package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
- package/src/runtime/http-types.ts +0 -2
- package/src/runtime/migrations/vbundle-builder.ts +12 -4
- package/src/runtime/pending-interactions.ts +0 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +204 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +76 -9
- package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
- package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
- package/src/runtime/routes/acp-routes-list.test.ts +3 -0
- package/src/runtime/routes/acp-routes.test.ts +255 -6
- package/src/runtime/routes/acp-routes.ts +8 -1
- package/src/runtime/routes/app-management-routes.ts +111 -4
- package/src/runtime/routes/avatar-routes.ts +10 -10
- package/src/runtime/routes/background-wake-routes.ts +356 -0
- package/src/runtime/routes/browser-tabs-routes.ts +200 -0
- package/src/runtime/routes/btw-routes.ts +4 -10
- package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
- package/src/runtime/routes/conversation-cli-routes.ts +1 -1
- package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
- package/src/runtime/routes/conversation-list-routes.ts +159 -4
- package/src/runtime/routes/conversation-management-routes.ts +108 -26
- package/src/runtime/routes/conversation-query-routes.ts +200 -44
- package/src/runtime/routes/conversation-routes.ts +409 -521
- package/src/runtime/routes/conversation-starter-routes.ts +6 -3
- package/src/runtime/routes/conversations-import-routes.ts +19 -6
- package/src/runtime/routes/disk-pressure-routes.ts +1 -1
- package/src/runtime/routes/documents-routes.ts +10 -1
- package/src/runtime/routes/domain-routes.ts +60 -10
- package/src/runtime/routes/email-routes.ts +5 -2
- package/src/runtime/routes/events-routes.ts +54 -10
- package/src/runtime/routes/group-routes.ts +35 -8
- package/src/runtime/routes/home-feed-routes.ts +129 -0
- package/src/runtime/routes/host-browser-routes.ts +10 -2
- package/src/runtime/routes/host-cu-routes.ts +2 -2
- package/src/runtime/routes/identity-intro-cache.ts +61 -16
- package/src/runtime/routes/identity-routes.ts +30 -9
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
- package/src/runtime/routes/index.ts +10 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
- package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
- package/src/runtime/routes/inference-provider-connection-routes.ts +5 -26
- package/src/runtime/routes/integrations/vercel.ts +15 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
- package/src/runtime/routes/llm-context-normalization.ts +7 -2
- package/src/runtime/routes/memory-item-routes.ts +8 -3
- package/src/runtime/routes/memory-v2-routes.ts +215 -5
- package/src/runtime/routes/memory-v3-routes.ts +474 -0
- package/src/runtime/routes/migration-routes.ts +32 -28
- package/src/runtime/routes/notification-routes.ts +63 -1
- package/src/runtime/routes/oauth-commands-routes.ts +6 -1
- package/src/runtime/routes/plugins-routes.ts +337 -0
- package/src/runtime/routes/rename-conversation-routes.ts +6 -2
- package/src/runtime/routes/secret-routes.ts +25 -5
- package/src/runtime/routes/settings-routes.ts +12 -11
- package/src/runtime/routes/slack-channel-routes.ts +5 -4
- package/src/runtime/routes/surface-action-routes.ts +1 -38
- package/src/runtime/routes/surface-content-routes.ts +12 -5
- package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
- package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
- package/src/runtime/routes/workspace-routes.ts +25 -10
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
- package/src/runtime/slack-dm-text-delivery.ts +177 -0
- package/src/runtime/sync/resource-sync-events.ts +106 -38
- package/src/runtime/sync/sync-publisher.test.ts +49 -0
- package/src/runtime/sync/sync-publisher.ts +2 -1
- package/src/runtime/tool-grant-request-helper.ts +1 -0
- package/src/runtime/verification-outbound-actions.ts +73 -1
- package/src/schedule/schedule-store.ts +8 -1
- package/src/schedule/scheduler.ts +111 -15
- package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
- package/src/security/encrypted-store.ts +7 -16
- package/src/security/store-path-override.ts +61 -0
- package/src/signals/user-message.ts +5 -8
- package/src/skills/validate-input.ts +177 -0
- package/src/subagent/manager.ts +13 -13
- package/src/subagent/types.ts +6 -0
- package/src/tasks/tool-sanitizer.ts +2 -2
- package/src/telemetry/types.ts +12 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/acp/spawn.test.ts +119 -0
- package/src/tools/acp/spawn.ts +15 -2
- package/src/tools/apps/definitions.ts +36 -28
- package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
- package/src/tools/ask-question/ask-question-tool.ts +38 -45
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
- package/src/tools/browser/__tests__/pinned-tabs.test.ts +70 -0
- package/src/tools/browser/browser-execution.ts +16 -3
- package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
- package/src/tools/browser/cdp-client/factory.ts +100 -17
- package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
- package/src/tools/browser/cdp-client/types.ts +65 -0
- package/src/tools/browser/pinned-tabs.ts +96 -40
- package/src/tools/computer-use/definitions.ts +282 -336
- package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
- package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
- package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
- package/src/tools/credentials/vault.ts +3 -9
- package/src/tools/document/document-tool.ts +189 -7
- package/src/tools/execution-target.ts +18 -23
- package/src/tools/executor.ts +24 -56
- package/src/tools/filesystem/edit.ts +3 -9
- package/src/tools/filesystem/list.ts +3 -9
- package/src/tools/filesystem/read.ts +3 -9
- package/src/tools/filesystem/write.ts +3 -9
- package/src/tools/host-filesystem/edit.test.ts +1 -0
- package/src/tools/host-filesystem/edit.ts +3 -9
- package/src/tools/host-filesystem/read.test.ts +1 -0
- package/src/tools/host-filesystem/read.ts +3 -9
- package/src/tools/host-filesystem/transfer.test.ts +31 -6
- package/src/tools/host-filesystem/transfer.ts +3 -9
- package/src/tools/host-filesystem/write.test.ts +1 -0
- package/src/tools/host-filesystem/write.ts +3 -9
- package/src/tools/host-terminal/host-shell.ts +3 -9
- package/src/tools/mcp/mcp-tool-factory.ts +1 -10
- package/src/tools/memory/register.test.ts +1 -1
- package/src/tools/memory/register.ts +4 -9
- package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
- package/src/tools/network/__tests__/web-search.test.ts +211 -3
- package/src/tools/network/managed-search-proxy.ts +183 -0
- package/src/tools/network/web-fetch.ts +3 -9
- package/src/tools/network/web-search.ts +224 -76
- package/src/tools/policy-context.ts +3 -1
- package/src/tools/registry.ts +150 -123
- package/src/tools/schedule/create.ts +1 -1
- package/src/tools/schema-transforms.ts +1 -1
- package/src/tools/skills/execute.ts +3 -9
- package/src/tools/skills/load.ts +3 -9
- package/src/tools/skills/skill-tool-factory.ts +18 -44
- package/src/tools/subagent/notify-parent.ts +3 -9
- package/src/tools/subagent/spawn.ts +3 -0
- package/src/tools/system/request-permission.ts +3 -9
- package/src/tools/terminal/shell.ts +3 -9
- package/src/tools/tool-approval-handler.ts +10 -4
- package/src/tools/tool-defaults.ts +94 -0
- package/src/tools/tool-name-aliases.ts +72 -14
- package/src/tools/types.ts +32 -101
- package/src/tools/ui-surface/definitions.ts +104 -108
- package/src/types/onboarding-context.ts +6 -0
- package/src/usage/attribution.ts +32 -1
- package/src/usage/pricing.ts +23 -0
- package/src/usage/types.ts +12 -0
- package/src/util/browser.ts +7 -2
- package/src/util/logger.ts +16 -7
- package/src/util/platform.ts +7 -2
- package/src/util/sqlite3-runtime.ts +65 -0
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
- package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
- package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
- package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
- package/src/__tests__/message-complete-display-id.test.ts +0 -175
- package/src/daemon/query-complexity-router.ts +0 -75
- package/src/prompts/cache-boundary.ts +0 -8
|
@@ -1,22 +1,12 @@
|
|
|
1
|
-
import { describe, expect, mock, test } from "bun:test";
|
|
1
|
+
import { afterEach, describe, expect, mock, test } from "bun:test";
|
|
2
2
|
|
|
3
3
|
// ─── Mocks ─────────────────────────────────────────────────────────────
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
mock.module("../../oauth/oauth-store.js", () => ({
|
|
8
|
-
listProviders: () => [
|
|
9
|
-
{ provider: "google" },
|
|
10
|
-
{ provider: "slack" },
|
|
11
|
-
{ provider: "notion" },
|
|
12
|
-
{ provider: "linear" },
|
|
13
|
-
{ provider: "github" },
|
|
14
|
-
],
|
|
15
|
-
}));
|
|
5
|
+
const mockIntegrationSummary = "Gmail ✓ | Slack ✓ | Twilio ✗ | Telegram ✗";
|
|
6
|
+
let mockSidechainText = "";
|
|
16
7
|
|
|
17
8
|
mock.module("../../schedule/integration-status.js", () => ({
|
|
18
|
-
|
|
19
|
-
mockConnectedProviders.has(provider),
|
|
9
|
+
formatIntegrationSummary: async () => mockIntegrationSummary,
|
|
20
10
|
}));
|
|
21
11
|
|
|
22
12
|
mock.module("../../util/logger.js", () => ({
|
|
@@ -31,7 +21,7 @@ mock.module("../../config/loader.js", () => ({
|
|
|
31
21
|
}));
|
|
32
22
|
|
|
33
23
|
mock.module("../../config/llm-resolver.js", () => ({
|
|
34
|
-
resolveCallSiteConfig: () => ({ provider: "mock" }),
|
|
24
|
+
resolveCallSiteConfig: () => ({ provider: "mock", maxTokens: 256 }),
|
|
35
25
|
}));
|
|
36
26
|
|
|
37
27
|
mock.module("../../providers/provider-send-message.js", () => ({
|
|
@@ -51,70 +41,76 @@ mock.module("../../prompts/system-prompt.js", () => ({
|
|
|
51
41
|
}));
|
|
52
42
|
|
|
53
43
|
mock.module("../../runtime/btw-sidechain.js", () => ({
|
|
54
|
-
runBtwSidechain: async () => ({ text:
|
|
44
|
+
runBtwSidechain: async () => ({ text: mockSidechainText }),
|
|
55
45
|
}));
|
|
56
46
|
|
|
57
|
-
|
|
47
|
+
mock.module("../../runtime/assistant-event.js", () => ({
|
|
48
|
+
buildAssistantEvent: (e: unknown) => e,
|
|
49
|
+
}));
|
|
50
|
+
|
|
51
|
+
mock.module("../../runtime/assistant-event-hub.js", () => ({
|
|
52
|
+
assistantEventHub: { publish: async () => {} },
|
|
53
|
+
}));
|
|
54
|
+
|
|
55
|
+
const {
|
|
56
|
+
getSuggestedPrompts,
|
|
57
|
+
refreshAssistantSuggestedPrompts,
|
|
58
|
+
invalidateAssistantSuggestedPromptsCache,
|
|
59
|
+
} = await import("../suggested-prompts.js");
|
|
58
60
|
|
|
59
61
|
// ─── Tests ─────────────────────────────────────────────────────────────
|
|
60
62
|
|
|
61
63
|
describe("getSuggestedPrompts", () => {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
afterEach(() => {
|
|
65
|
+
invalidateAssistantSuggestedPromptsCache();
|
|
66
|
+
mockSidechainText = "";
|
|
67
|
+
});
|
|
64
68
|
|
|
69
|
+
test("returns empty array before cache is populated", async () => {
|
|
65
70
|
const prompts = await getSuggestedPrompts();
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
expect(ids).toContain("connect-google");
|
|
69
|
-
expect(ids).toContain("connect-slack");
|
|
70
|
-
expect(prompts.find((p) => p.id === "connect-google")!.label).toBe(
|
|
71
|
-
"Connect Gmail",
|
|
72
|
-
);
|
|
71
|
+
expect(prompts).toEqual([]);
|
|
73
72
|
});
|
|
74
73
|
|
|
75
|
-
test("
|
|
76
|
-
|
|
74
|
+
test("returns LLM-generated prompts after refresh", async () => {
|
|
75
|
+
mockSidechainText = JSON.stringify([
|
|
76
|
+
{ label: "Triage my inbox", prompt: "Help me triage my inbox" },
|
|
77
|
+
{ label: "Check meetings", prompt: "What meetings do I have today?" },
|
|
78
|
+
]);
|
|
77
79
|
|
|
80
|
+
await refreshAssistantSuggestedPrompts();
|
|
78
81
|
const prompts = await getSuggestedPrompts();
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
expect(
|
|
83
|
-
|
|
84
|
-
// Should show management prompts
|
|
85
|
-
expect(ids).toContain("manage-google-triage-my-inbox");
|
|
86
|
-
expect(ids).toContain("manage-google-summarize-today's-emails");
|
|
87
|
-
|
|
88
|
-
const triage = prompts.find(
|
|
89
|
-
(p) => p.id === "manage-google-triage-my-inbox",
|
|
90
|
-
);
|
|
91
|
-
expect(triage).toBeDefined();
|
|
92
|
-
expect(triage!.label).toBe("Triage my inbox");
|
|
93
|
-
expect(triage!.icon).toBe("mail");
|
|
94
|
-
expect(triage!.source).toBe("deterministic");
|
|
82
|
+
|
|
83
|
+
expect(prompts).toHaveLength(2);
|
|
84
|
+
expect(prompts[0]!.label).toBe("Triage my inbox");
|
|
85
|
+
expect(prompts[0]!.source).toBe("assistant");
|
|
86
|
+
expect(prompts[1]!.label).toBe("Check meetings");
|
|
95
87
|
});
|
|
96
88
|
|
|
97
|
-
test("
|
|
98
|
-
|
|
89
|
+
test("invalidation clears the cache", async () => {
|
|
90
|
+
mockSidechainText = JSON.stringify([
|
|
91
|
+
{ label: "Do stuff", prompt: "Do stuff for me" },
|
|
92
|
+
]);
|
|
99
93
|
|
|
100
|
-
|
|
101
|
-
|
|
94
|
+
await refreshAssistantSuggestedPrompts();
|
|
95
|
+
expect(await getSuggestedPrompts()).toHaveLength(1);
|
|
102
96
|
|
|
103
|
-
|
|
104
|
-
expect(
|
|
105
|
-
// Slack still disconnected
|
|
106
|
-
expect(ids).toContain("connect-slack");
|
|
97
|
+
invalidateAssistantSuggestedPromptsCache();
|
|
98
|
+
expect(await getSuggestedPrompts()).toEqual([]);
|
|
107
99
|
});
|
|
108
100
|
|
|
109
|
-
test("
|
|
110
|
-
|
|
101
|
+
test("handles empty LLM response gracefully", async () => {
|
|
102
|
+
mockSidechainText = "";
|
|
111
103
|
|
|
104
|
+
await refreshAssistantSuggestedPrompts();
|
|
112
105
|
const prompts = await getSuggestedPrompts();
|
|
113
|
-
|
|
106
|
+
expect(prompts).toEqual([]);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test("handles malformed LLM response gracefully", async () => {
|
|
110
|
+
mockSidechainText = "not valid json at all";
|
|
114
111
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
expect(ids.filter((id) => id.startsWith("manage-slack"))).toHaveLength(0);
|
|
112
|
+
await refreshAssistantSuggestedPrompts();
|
|
113
|
+
const prompts = await getSuggestedPrompts();
|
|
114
|
+
expect(prompts).toEqual([]);
|
|
119
115
|
});
|
|
120
116
|
});
|
package/src/home/feed-writer.ts
CHANGED
|
@@ -44,6 +44,7 @@ import { getDataDir } from "../util/platform.js";
|
|
|
44
44
|
import {
|
|
45
45
|
type FeedItem,
|
|
46
46
|
type FeedItemStatus,
|
|
47
|
+
type FeedItemUrgency,
|
|
47
48
|
type HomeFeedFile,
|
|
48
49
|
parseFeedFile,
|
|
49
50
|
} from "./feed-types.js";
|
|
@@ -155,6 +156,72 @@ export async function patchFeedItemStatus(
|
|
|
155
156
|
return resultPromise;
|
|
156
157
|
}
|
|
157
158
|
|
|
159
|
+
/**
|
|
160
|
+
* Patch the user-editable copy fields on a single feed item by id.
|
|
161
|
+
*
|
|
162
|
+
* Returns the updated `FeedItem`, or `null` if no item with the given
|
|
163
|
+
* id exists. Used by the `assistant notifications edit` flow. Patches
|
|
164
|
+
* are applied inside the same coalescing queue as appends and status
|
|
165
|
+
* patches so overlapping writes don't race.
|
|
166
|
+
*
|
|
167
|
+
* Only fields explicitly present on `patch` are touched. Pass an empty
|
|
168
|
+
* object and the call is a no-op that returns the existing item (or
|
|
169
|
+
* `null` if the id isn't on disk).
|
|
170
|
+
*/
|
|
171
|
+
export interface FeedItemContentPatch {
|
|
172
|
+
title?: string;
|
|
173
|
+
summary?: string;
|
|
174
|
+
urgency?: FeedItemUrgency;
|
|
175
|
+
status?: FeedItemStatus;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export async function patchFeedItemContent(
|
|
179
|
+
id: string,
|
|
180
|
+
patch: FeedItemContentPatch,
|
|
181
|
+
): Promise<FeedItem | null> {
|
|
182
|
+
let resolveResult!: (value: FeedItem | null) => void;
|
|
183
|
+
const resultPromise = new Promise<FeedItem | null>((resolve) => {
|
|
184
|
+
resolveResult = resolve;
|
|
185
|
+
});
|
|
186
|
+
pendingContentPatches.push({ id, patch, resolve: resolveResult });
|
|
187
|
+
void scheduleWrite();
|
|
188
|
+
return resultPromise;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Remove the `conversationId` field from all feed items that reference
|
|
193
|
+
* the given conversation. Returns the number of items modified.
|
|
194
|
+
*
|
|
195
|
+
* This is the daemon-side cleanup path invoked when a conversation is
|
|
196
|
+
* deleted — it prevents "Go to Thread" buttons from linking to a
|
|
197
|
+
* conversation that no longer exists. Goes through the same coalescing
|
|
198
|
+
* queue as appends and patches so there are no file-I/O races.
|
|
199
|
+
*/
|
|
200
|
+
export async function stripConversationIds(
|
|
201
|
+
conversationId: string,
|
|
202
|
+
): Promise<number> {
|
|
203
|
+
let resolveResult!: (count: number) => void;
|
|
204
|
+
const resultPromise = new Promise<number>((resolve) => {
|
|
205
|
+
resolveResult = resolve;
|
|
206
|
+
});
|
|
207
|
+
pendingStrips.push({ conversationId, resolve: resolveResult });
|
|
208
|
+
void scheduleWrite();
|
|
209
|
+
return resultPromise;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Remove the `conversationId` field from ALL feed items that have one.
|
|
214
|
+
* Returns the number of items modified.
|
|
215
|
+
*
|
|
216
|
+
* Used by the clear-all-conversations flow to bulk-invalidate every
|
|
217
|
+
* "Go to Thread" link at once. Uses the same coalescing queue with a
|
|
218
|
+
* `"*"` sentinel that the strip loop in `runWrite` treats as "match
|
|
219
|
+
* all items with a conversationId".
|
|
220
|
+
*/
|
|
221
|
+
export async function clearAllConversationIds(): Promise<number> {
|
|
222
|
+
return stripConversationIds("*");
|
|
223
|
+
}
|
|
224
|
+
|
|
158
225
|
// ─── Internal: coalescing queue ────────────────────────────────────────
|
|
159
226
|
|
|
160
227
|
/**
|
|
@@ -168,6 +235,15 @@ const pendingPatches: Array<{
|
|
|
168
235
|
status: FeedItemStatus;
|
|
169
236
|
resolve: (value: FeedItem | null) => void;
|
|
170
237
|
}> = [];
|
|
238
|
+
const pendingContentPatches: Array<{
|
|
239
|
+
id: string;
|
|
240
|
+
patch: FeedItemContentPatch;
|
|
241
|
+
resolve: (value: FeedItem | null) => void;
|
|
242
|
+
}> = [];
|
|
243
|
+
const pendingStrips: Array<{
|
|
244
|
+
conversationId: string;
|
|
245
|
+
resolve: (count: number) => void;
|
|
246
|
+
}> = [];
|
|
171
247
|
|
|
172
248
|
let writeInFlight: Promise<void> | null = null;
|
|
173
249
|
let writeDirty = false;
|
|
@@ -206,6 +282,11 @@ function scheduleWrite(): Promise<void> {
|
|
|
206
282
|
async function runWrite(): Promise<void> {
|
|
207
283
|
const appendsToApply = pendingAppends.splice(0, pendingAppends.length);
|
|
208
284
|
const patchesToApply = pendingPatches.splice(0, pendingPatches.length);
|
|
285
|
+
const contentPatchesToApply = pendingContentPatches.splice(
|
|
286
|
+
0,
|
|
287
|
+
pendingContentPatches.length,
|
|
288
|
+
);
|
|
289
|
+
const stripsToApply = pendingStrips.splice(0, pendingStrips.length);
|
|
209
290
|
|
|
210
291
|
const current = readHomeFeed();
|
|
211
292
|
let items = current.items.slice();
|
|
@@ -233,6 +314,57 @@ async function runWrite(): Promise<void> {
|
|
|
233
314
|
patchResults.push({ resolve: patch.resolve, value: updated });
|
|
234
315
|
}
|
|
235
316
|
|
|
317
|
+
const contentPatchResults: Array<{
|
|
318
|
+
resolve: (v: FeedItem | null) => void;
|
|
319
|
+
value: FeedItem | null;
|
|
320
|
+
}> = [];
|
|
321
|
+
for (const { id, patch, resolve } of contentPatchesToApply) {
|
|
322
|
+
const idx = items.findIndex((i) => i.id === id);
|
|
323
|
+
if (idx === -1) {
|
|
324
|
+
contentPatchResults.push({ resolve, value: null });
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
const existing = items[idx]!;
|
|
328
|
+
const updated: FeedItem = { ...existing };
|
|
329
|
+
if (patch.title !== undefined) {
|
|
330
|
+
const trimmed = patch.title.trim();
|
|
331
|
+
if (trimmed.length === 0) {
|
|
332
|
+
delete updated.title;
|
|
333
|
+
} else {
|
|
334
|
+
updated.title = trimmed;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (patch.summary !== undefined) {
|
|
338
|
+
updated.summary = patch.summary;
|
|
339
|
+
}
|
|
340
|
+
if (patch.urgency !== undefined) {
|
|
341
|
+
updated.urgency = patch.urgency;
|
|
342
|
+
}
|
|
343
|
+
if (patch.status !== undefined) {
|
|
344
|
+
updated.status = patch.status;
|
|
345
|
+
}
|
|
346
|
+
items[idx] = updated;
|
|
347
|
+
contentPatchResults.push({ resolve, value: updated });
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Strip conversationId from matching items.
|
|
351
|
+
const stripResults: Array<{
|
|
352
|
+
resolve: (count: number) => void;
|
|
353
|
+
count: number;
|
|
354
|
+
}> = [];
|
|
355
|
+
for (const strip of stripsToApply) {
|
|
356
|
+
let count = 0;
|
|
357
|
+
for (let i = 0; i < items.length; i++) {
|
|
358
|
+
const matchAll = strip.conversationId === "*";
|
|
359
|
+
const matchOne = items[i]!.conversationId === strip.conversationId;
|
|
360
|
+
if (matchAll ? items[i]!.conversationId != null : matchOne) {
|
|
361
|
+
items[i] = { ...items[i]!, conversationId: undefined };
|
|
362
|
+
count++;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
stripResults.push({ resolve: strip.resolve, count });
|
|
366
|
+
}
|
|
367
|
+
|
|
236
368
|
items.sort(compareFeedItems);
|
|
237
369
|
|
|
238
370
|
const updatedAt = new Date().toISOString();
|
|
@@ -258,17 +390,24 @@ async function runWrite(): Promise<void> {
|
|
|
258
390
|
publishHomeFeedUpdated(updatedAt, newItemCount);
|
|
259
391
|
}
|
|
260
392
|
|
|
261
|
-
// Resolve pending patch promises AFTER we've emitted the
|
|
262
|
-
// so callers awaiting `patchFeedItemStatus`
|
|
263
|
-
//
|
|
264
|
-
//
|
|
393
|
+
// Resolve pending patch and strip promises AFTER we've emitted the
|
|
394
|
+
// SSE event so callers awaiting `patchFeedItemStatus` or
|
|
395
|
+
// `stripConversationIds` observe a fully consistent world: the
|
|
396
|
+
// on-disk file, the SSE event, and the returned value all reflect
|
|
397
|
+
// the same write.
|
|
265
398
|
//
|
|
266
|
-
// If the write failed, resolve
|
|
267
|
-
// state was not persisted, and callers
|
|
268
|
-
//
|
|
399
|
+
// If the write failed, resolve patch promises with `null` and strip
|
|
400
|
+
// promises with `0` — the state was not persisted, and callers must
|
|
401
|
+
// not report success when the underlying write failed.
|
|
269
402
|
for (const { resolve, value } of patchResults) {
|
|
270
403
|
resolve(wrote ? value : null);
|
|
271
404
|
}
|
|
405
|
+
for (const { resolve, value } of contentPatchResults) {
|
|
406
|
+
resolve(wrote ? value : null);
|
|
407
|
+
}
|
|
408
|
+
for (const { resolve, count } of stripResults) {
|
|
409
|
+
resolve(wrote ? count : 0);
|
|
410
|
+
}
|
|
272
411
|
}
|
|
273
412
|
|
|
274
413
|
/**
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
|
|
14
14
|
import { resolveCallSiteConfig } from "../config/llm-resolver.js";
|
|
15
15
|
import { getConfig } from "../config/loader.js";
|
|
16
|
-
import { resolvePersonaContext } from "../prompts/persona-resolver.js";
|
|
17
16
|
import { buildSystemPrompt } from "../prompts/system-prompt.js";
|
|
18
17
|
import { getConfiguredProvider } from "../providers/provider-send-message.js";
|
|
19
18
|
import { runBtwSidechain } from "../runtime/btw-sidechain.js";
|
|
@@ -56,17 +55,9 @@ export async function refreshPersonalizedGreeting(): Promise<void> {
|
|
|
56
55
|
return;
|
|
57
56
|
}
|
|
58
57
|
|
|
59
|
-
const { userPersona, userSlug, channelPersona } = resolvePersonaContext(
|
|
60
|
-
undefined,
|
|
61
|
-
undefined,
|
|
62
|
-
);
|
|
63
|
-
|
|
64
58
|
const systemPrompt = buildSystemPrompt({
|
|
65
59
|
excludeBootstrap: true,
|
|
66
60
|
excludeCustomPrefix: true,
|
|
67
|
-
userPersona,
|
|
68
|
-
channelPersona,
|
|
69
|
-
userSlug,
|
|
70
61
|
});
|
|
71
62
|
|
|
72
63
|
const result = await runBtwSidechain({
|
|
@@ -2,88 +2,25 @@
|
|
|
2
2
|
* Suggested prompt producer for the Home feed.
|
|
3
3
|
*
|
|
4
4
|
* Returns an array of `SuggestedPrompt` items shown at the top of the
|
|
5
|
-
* Home page as conversation starters
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* Computed inline (read-only, safe for GET).
|
|
10
|
-
* - **Assistant-generated** — contextual suggestions from the LLM
|
|
11
|
-
* based on what's relevant to the user. Read from an in-memory
|
|
12
|
-
* cache in the GET path; generation runs in the background via
|
|
13
|
-
* `refreshAssistantSuggestedPrompts`.
|
|
5
|
+
* Home page as conversation starters. All prompts are generated by the
|
|
6
|
+
* assistant based on the user's connected services and context —
|
|
7
|
+
* read from an in-memory cache in the GET path; generation runs in
|
|
8
|
+
* the background via `refreshAssistantSuggestedPrompts`.
|
|
14
9
|
*/
|
|
15
10
|
|
|
16
11
|
import { resolveCallSiteConfig } from "../config/llm-resolver.js";
|
|
17
12
|
import { getConfig } from "../config/loader.js";
|
|
18
|
-
import { listProviders } from "../oauth/oauth-store.js";
|
|
19
|
-
import { resolvePersonaContext } from "../prompts/persona-resolver.js";
|
|
20
13
|
import { buildSystemPrompt } from "../prompts/system-prompt.js";
|
|
21
14
|
import { getConfiguredProvider } from "../providers/provider-send-message.js";
|
|
22
15
|
import { buildAssistantEvent } from "../runtime/assistant-event.js";
|
|
23
16
|
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
24
17
|
import { runBtwSidechain } from "../runtime/btw-sidechain.js";
|
|
25
|
-
import {
|
|
18
|
+
import { formatIntegrationSummary } from "../schedule/integration-status.js";
|
|
26
19
|
import { getLogger } from "../util/logger.js";
|
|
27
20
|
import type { SuggestedPrompt } from "./feed-types.js";
|
|
28
21
|
|
|
29
22
|
const log = getLogger("suggested-prompts");
|
|
30
23
|
|
|
31
|
-
/**
|
|
32
|
-
* Map of provider keys to their suggested-prompt metadata. Only providers
|
|
33
|
-
* listed here produce deterministic "Connect X" prompts when disconnected.
|
|
34
|
-
* The icon values are VIcon case names rendered by the macOS client.
|
|
35
|
-
*/
|
|
36
|
-
interface PromptEntry {
|
|
37
|
-
label: string;
|
|
38
|
-
prompt: string;
|
|
39
|
-
icon: string;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const CONNECT_PROMPT_META: Record<
|
|
43
|
-
string,
|
|
44
|
-
PromptEntry & { connectedPrompts?: PromptEntry[] }
|
|
45
|
-
> = {
|
|
46
|
-
google: {
|
|
47
|
-
label: "Connect Gmail",
|
|
48
|
-
prompt: "Help me connect my Gmail account",
|
|
49
|
-
icon: "mail",
|
|
50
|
-
connectedPrompts: [
|
|
51
|
-
{
|
|
52
|
-
label: "Triage my inbox",
|
|
53
|
-
prompt:
|
|
54
|
-
"Help me triage my inbox — summarize what's unread and flag anything that needs a reply",
|
|
55
|
-
icon: "mail",
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
label: "Summarize today's emails",
|
|
59
|
-
prompt:
|
|
60
|
-
"Summarize the emails I received today and highlight anything important",
|
|
61
|
-
icon: "mail",
|
|
62
|
-
},
|
|
63
|
-
],
|
|
64
|
-
},
|
|
65
|
-
slack: {
|
|
66
|
-
label: "Connect Slack",
|
|
67
|
-
prompt: "Help me connect my Slack workspace",
|
|
68
|
-
icon: "hash",
|
|
69
|
-
},
|
|
70
|
-
notion: {
|
|
71
|
-
label: "Connect Notion",
|
|
72
|
-
prompt: "Help me connect my Notion workspace",
|
|
73
|
-
icon: "fileText",
|
|
74
|
-
},
|
|
75
|
-
linear: {
|
|
76
|
-
label: "Connect Linear",
|
|
77
|
-
prompt: "Help me connect my Linear workspace",
|
|
78
|
-
icon: "clipboardList",
|
|
79
|
-
},
|
|
80
|
-
github: {
|
|
81
|
-
label: "Connect GitHub",
|
|
82
|
-
prompt: "Help me connect my GitHub account",
|
|
83
|
-
icon: "terminal",
|
|
84
|
-
},
|
|
85
|
-
};
|
|
86
|
-
|
|
87
24
|
const LLM_SUGGESTIONS_TIMEOUT_MS = 5_000;
|
|
88
25
|
const LLM_CACHE_TTL_MS = 30 * 60 * 1000; // 30 minutes
|
|
89
26
|
|
|
@@ -95,37 +32,23 @@ let cachedLLMPrompts: SuggestedPrompt[] = [];
|
|
|
95
32
|
let cachedLLMPromptsAt = 0;
|
|
96
33
|
|
|
97
34
|
/**
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
35
|
+
* Return cached assistant-generated prompts. No LLM calls happen in
|
|
36
|
+
* this path — safe for GET. Returns an empty array until the first
|
|
37
|
+
* background refresh populates the cache.
|
|
101
38
|
*/
|
|
102
39
|
export async function getSuggestedPrompts(): Promise<SuggestedPrompt[]> {
|
|
103
|
-
const prompts: SuggestedPrompt[] = [];
|
|
104
|
-
|
|
105
|
-
let deterministicPrompts: SuggestedPrompt[] = [];
|
|
106
|
-
try {
|
|
107
|
-
deterministicPrompts = await getDeterministicPrompts();
|
|
108
|
-
prompts.push(...deterministicPrompts);
|
|
109
|
-
} catch (err) {
|
|
110
|
-
log.warn({ err }, "Failed to compute deterministic suggested prompts");
|
|
111
|
-
}
|
|
112
|
-
|
|
113
40
|
if (Date.now() - cachedLLMPromptsAt < LLM_CACHE_TTL_MS) {
|
|
114
|
-
|
|
41
|
+
return [...cachedLLMPrompts];
|
|
115
42
|
}
|
|
116
|
-
|
|
117
|
-
return prompts;
|
|
43
|
+
return [];
|
|
118
44
|
}
|
|
119
45
|
|
|
120
46
|
/**
|
|
121
|
-
* Drops the in-memory
|
|
122
|
-
*
|
|
123
|
-
* a follow-up background refresh repopulates the LLM half).
|
|
47
|
+
* Drops the in-memory suggestion cache so the next background refresh
|
|
48
|
+
* regenerates prompts with current integration state.
|
|
124
49
|
*
|
|
125
|
-
* Called from OAuth connect/disconnect paths so
|
|
126
|
-
*
|
|
127
|
-
* 30-minute TTL would otherwise pin a stale suggestion until the next
|
|
128
|
-
* periodic refresh.
|
|
50
|
+
* Called from OAuth connect/disconnect paths so suggestions reflect the
|
|
51
|
+
* new state within one reload instead of waiting for the 30-minute TTL.
|
|
129
52
|
*/
|
|
130
53
|
export function invalidateAssistantSuggestedPromptsCache(): void {
|
|
131
54
|
cachedLLMPrompts = [];
|
|
@@ -157,8 +80,7 @@ export async function refreshAssistantSuggestedPrompts(): Promise<void> {
|
|
|
157
80
|
}
|
|
158
81
|
|
|
159
82
|
try {
|
|
160
|
-
const
|
|
161
|
-
const llmPrompts = await generateAssistantPrompts(deterministicPrompts);
|
|
83
|
+
const llmPrompts = await generateAssistantPrompts();
|
|
162
84
|
cachedLLMPrompts = llmPrompts;
|
|
163
85
|
cachedLLMPromptsAt = Date.now();
|
|
164
86
|
} catch (err) {
|
|
@@ -166,49 +88,6 @@ export async function refreshAssistantSuggestedPrompts(): Promise<void> {
|
|
|
166
88
|
}
|
|
167
89
|
}
|
|
168
90
|
|
|
169
|
-
/**
|
|
170
|
-
* Check which well-known OAuth providers are not connected and return
|
|
171
|
-
* a "Connect X" prompt for each. For connected providers that have
|
|
172
|
-
* `connectedPrompts`, return those instead so users discover ongoing
|
|
173
|
-
* management capabilities.
|
|
174
|
-
*/
|
|
175
|
-
async function getDeterministicPrompts(): Promise<SuggestedPrompt[]> {
|
|
176
|
-
const providers = listProviders();
|
|
177
|
-
const prompts: SuggestedPrompt[] = [];
|
|
178
|
-
|
|
179
|
-
for (const provider of providers) {
|
|
180
|
-
const meta = CONNECT_PROMPT_META[provider.provider];
|
|
181
|
-
if (!meta) continue;
|
|
182
|
-
|
|
183
|
-
const connected = await isOAuthProviderConnected(provider.provider);
|
|
184
|
-
|
|
185
|
-
if (!connected) {
|
|
186
|
-
prompts.push({
|
|
187
|
-
id: `connect-${provider.provider}`,
|
|
188
|
-
label: meta.label,
|
|
189
|
-
icon: meta.icon,
|
|
190
|
-
prompt: meta.prompt,
|
|
191
|
-
source: "deterministic",
|
|
192
|
-
});
|
|
193
|
-
continue;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
if (meta.connectedPrompts) {
|
|
197
|
-
for (const cp of meta.connectedPrompts) {
|
|
198
|
-
prompts.push({
|
|
199
|
-
id: `manage-${provider.provider}-${cp.label.toLowerCase().replace(/\s+/g, "-")}`,
|
|
200
|
-
label: cp.label,
|
|
201
|
-
icon: cp.icon,
|
|
202
|
-
prompt: cp.prompt,
|
|
203
|
-
source: "deterministic",
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
return prompts;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
91
|
// ---------------------------------------------------------------------------
|
|
213
92
|
// LLM-generated suggestions
|
|
214
93
|
// ---------------------------------------------------------------------------
|
|
@@ -221,11 +100,9 @@ interface LLMSuggestion {
|
|
|
221
100
|
/**
|
|
222
101
|
* Ask the LLM to generate contextual conversation-starter suggestions
|
|
223
102
|
* based on the assistant's persona and the user's connected services.
|
|
224
|
-
* Returns an empty array on failure
|
|
103
|
+
* Returns an empty array on failure.
|
|
225
104
|
*/
|
|
226
|
-
async function generateAssistantPrompts(
|
|
227
|
-
deterministicPrompts: SuggestedPrompt[],
|
|
228
|
-
): Promise<SuggestedPrompt[]> {
|
|
105
|
+
async function generateAssistantPrompts(): Promise<SuggestedPrompt[]> {
|
|
229
106
|
const config = getConfig();
|
|
230
107
|
const resolved = resolveCallSiteConfig("homeSuggestedPrompts", config.llm);
|
|
231
108
|
|
|
@@ -234,30 +111,26 @@ async function generateAssistantPrompts(
|
|
|
234
111
|
return [];
|
|
235
112
|
}
|
|
236
113
|
|
|
237
|
-
const { userPersona, userSlug, channelPersona } = resolvePersonaContext(
|
|
238
|
-
undefined,
|
|
239
|
-
undefined,
|
|
240
|
-
);
|
|
241
|
-
|
|
242
114
|
const systemPrompt = buildSystemPrompt({
|
|
243
115
|
excludeBootstrap: true,
|
|
244
116
|
excludeCustomPrefix: true,
|
|
245
|
-
userPersona,
|
|
246
|
-
channelPersona,
|
|
247
|
-
userSlug,
|
|
248
117
|
});
|
|
249
118
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
119
|
+
let integrationContext = "";
|
|
120
|
+
try {
|
|
121
|
+
integrationContext = `\nConnected integrations: ${await formatIntegrationSummary()}`;
|
|
122
|
+
} catch {
|
|
123
|
+
// Best-effort — continue without integration info
|
|
124
|
+
}
|
|
254
125
|
|
|
255
126
|
const result = await runBtwSidechain({
|
|
256
127
|
content:
|
|
257
128
|
"Suggest 2-3 short, actionable conversation starters for the home page. " +
|
|
258
129
|
"Each should be something specific and helpful you can do for the user right now. " +
|
|
259
|
-
|
|
260
|
-
|
|
130
|
+
"Focus on things the user's connected services enable — don't suggest connecting services they already have. " +
|
|
131
|
+
"You may suggest connecting a service only if it's not yet connected and would be genuinely useful." +
|
|
132
|
+
integrationContext +
|
|
133
|
+
' Return ONLY a JSON array of objects with "label" (max 5 words) and "prompt" (the full message to send). ' +
|
|
261
134
|
"No markdown fences, no explanation.",
|
|
262
135
|
provider,
|
|
263
136
|
systemPrompt,
|
|
@@ -37,6 +37,7 @@ mock.module("../../runtime/agent-wake.js", () => ({
|
|
|
37
37
|
|
|
38
38
|
mock.module("../../memory/conversation-crud.js", () => ({
|
|
39
39
|
getConversation: (id: string) => ({ id, createdAt: Date.now() }),
|
|
40
|
+
reserveMessage: mock(async () => ({ id: "msg-reserve" })),
|
|
40
41
|
}));
|
|
41
42
|
|
|
42
43
|
// ---------------------------------------------------------------------------
|
|
@@ -108,7 +108,10 @@ describe("ipcGetFeatureFlags", () => {
|
|
|
108
108
|
});
|
|
109
109
|
|
|
110
110
|
test("returns empty record when IPC returns undefined", async () => {
|
|
111
|
-
//
|
|
111
|
+
// Explicitly suppress the mock's default `get_feature_flags` sentinel
|
|
112
|
+
// (which exists to short-circuit `initFeatureFlagOverrides()`'s retry
|
|
113
|
+
// loop) so this test exercises the underlying-undefined path.
|
|
114
|
+
mockGatewayIpc(null, { results: { get_feature_flags: undefined } });
|
|
112
115
|
const flags = await ipcGetFeatureFlags();
|
|
113
116
|
expect(flags).toEqual({});
|
|
114
117
|
});
|