@vellumai/assistant 0.8.2 → 0.8.4
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 +11 -12
- package/docker-entrypoint.sh +13 -2
- package/docker-init-apt-root.sh +79 -6
- package/node_modules/@vellumai/gateway-client/src/types.ts +2 -0
- package/openapi.yaml +945 -36
- package/package.json +1 -1
- package/src/__tests__/agent-loop-exit-reason.test.ts +271 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +1 -1
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +195 -0
- package/src/__tests__/agent-loop.test.ts +88 -3
- package/src/__tests__/anthropic-provider.test.ts +272 -0
- package/src/__tests__/approval-cascade.test.ts +1 -1
- package/src/__tests__/background-workers-disk-pressure.test.ts +2 -1
- package/src/__tests__/channel-delivery-store.test.ts +193 -0
- package/src/__tests__/channel-reply-delivery.test.ts +284 -5
- package/src/__tests__/channel-retry-sweep.test.ts +274 -1
- package/src/__tests__/compaction-events.test.ts +1 -1
- package/src/__tests__/compactor-preserved-tail-count.test.ts +110 -0
- package/src/__tests__/compactor-tail-resolution.test.ts +107 -1
- package/src/__tests__/config-get-vision-flag.test.ts +136 -0
- package/src/__tests__/config-loader-backfill.test.ts +115 -18
- package/src/__tests__/config-watcher.test.ts +1 -1
- package/src/__tests__/context-token-estimator.test.ts +112 -57
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +54 -3
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +31 -6
- package/src/__tests__/conversation-agent-loop.test.ts +77 -3
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
- package/src/__tests__/conversation-clean-command.test.ts +137 -0
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -1
- package/src/__tests__/conversation-fork-crud.test.ts +161 -0
- package/src/__tests__/conversation-lifecycle.test.ts +1 -1
- package/src/__tests__/conversation-load-cleaned-at.test.ts +279 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
- package/src/__tests__/conversation-media-retry.test.ts +19 -8
- package/src/__tests__/conversation-pairing.test.ts +2 -2
- package/src/__tests__/conversation-process-callsite.test.ts +1 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -1
- package/src/__tests__/conversation-queue.test.ts +1 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +290 -85
- package/src/__tests__/conversation-seed-composer.test.ts +66 -4
- package/src/__tests__/conversation-slash-commands.test.ts +36 -8
- package/src/__tests__/conversation-slash-queue.test.ts +1 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -1
- package/src/__tests__/conversation-speed-override.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +220 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
- package/src/__tests__/credential-security-invariants.test.ts +6 -0
- package/src/__tests__/cu-unified-flow.test.ts +10 -1
- package/src/__tests__/date-context.test.ts +45 -0
- package/src/__tests__/dm-backfill.test.ts +64 -0
- package/src/__tests__/dm-persistence.test.ts +33 -0
- package/src/__tests__/document-find-replace.test.ts +501 -0
- package/src/__tests__/external-plugin-loader.test.ts +91 -19
- package/src/__tests__/first-greeting.test.ts +23 -2
- package/src/__tests__/guardian-action-no-hardcoded-copy.test.ts +0 -1
- package/src/__tests__/guardian-dispatch.test.ts +1 -0
- package/src/__tests__/headless-browser-navigate.test.ts +172 -0
- package/src/__tests__/heartbeat-service.test.ts +24 -164
- package/src/__tests__/helpers/channel-test-adapter.ts +0 -2
- package/src/__tests__/host-app-control-proxy.test.ts +241 -0
- package/src/__tests__/host-bash-proxy.test.ts +6 -0
- package/src/__tests__/host-browser-proxy.test.ts +10 -0
- package/src/__tests__/host-cu-proxy.test.ts +8 -1
- package/src/__tests__/host-file-proxy.test.ts +8 -1
- package/src/__tests__/host-proxy-preactivation.test.ts +200 -13
- package/src/__tests__/host-transfer-proxy.test.ts +8 -1
- package/src/__tests__/identity-routes.test.ts +57 -0
- package/src/__tests__/inbound-slack-persistence.test.ts +3 -0
- package/src/__tests__/injector-background-turn.test.ts +153 -0
- package/src/__tests__/injector-chain.test.ts +7 -0
- package/src/__tests__/injector-document-comments.test.ts +378 -0
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +4 -25
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +9 -2
- package/src/__tests__/list-messages-attachments.test.ts +21 -17
- package/src/__tests__/list-messages-hidden-metadata.test.ts +217 -0
- package/src/__tests__/list-messages-page-latest.test.ts +130 -14
- package/src/__tests__/list-messages-tool-merge.test.ts +17 -16
- package/src/__tests__/llm-callsite-catalog.test.ts +25 -0
- package/src/__tests__/llm-catalog-parity.test.ts +3 -0
- package/src/__tests__/llm-context-normalization.test.ts +0 -2
- package/src/__tests__/llm-request-log-agent-loop-exit-reason.test.ts +116 -0
- package/src/__tests__/llm-request-log-error-payload.test.ts +138 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +2 -0
- package/src/__tests__/llm-resolver.test.ts +340 -3
- package/src/__tests__/log-export-routes.test.ts +99 -2
- package/src/__tests__/managed-profile-guard.test.ts +10 -0
- package/src/__tests__/message-queue-steer.test.ts +114 -0
- package/src/__tests__/notification-decision-fallback.test.ts +0 -91
- package/src/__tests__/notification-decision-strategy.test.ts +14 -31
- package/src/__tests__/notification-deep-link.test.ts +15 -0
- package/src/__tests__/notification-guardian-path.test.ts +1 -2
- package/src/__tests__/notification-platform-adapter.test.ts +5 -4
- package/src/__tests__/notification-telegram-adapter.test.ts +1 -0
- package/src/__tests__/notification-vellum-adapter.test.ts +113 -0
- package/src/__tests__/openai-provider.test.ts +323 -3
- package/src/__tests__/openai-responses-cutover-guard.test.ts +3 -3
- package/src/__tests__/openai-responses-provider.test.ts +4 -4
- package/src/__tests__/openrouter-provider-only.test.ts +51 -3
- package/src/__tests__/openrouter-token-estimation.test.ts +34 -25
- package/src/__tests__/outbound-slack-persistence.test.ts +187 -20
- package/src/__tests__/pending-interactions-resolved-event.test.ts +190 -0
- package/src/__tests__/platform-proxy-context.test.ts +6 -1
- package/src/__tests__/platform.test.ts +0 -3
- package/src/__tests__/plugin-source-watcher.test.ts +302 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +3 -3
- package/src/__tests__/plugin-types.test.ts +2 -2
- package/src/__tests__/process-message-background-slack.test.ts +1 -51
- package/src/__tests__/process-message-display-content.test.ts +21 -16
- package/src/__tests__/provider-catalog-visibility.test.ts +16 -0
- package/src/__tests__/provider-platform-proxy-integration.test.ts +27 -25
- package/src/__tests__/secret-routes-platform-proxy.test.ts +1 -1
- package/src/__tests__/server-history-render.test.ts +83 -4
- package/src/__tests__/steer-tool-repair.test.ts +249 -0
- package/src/__tests__/system-prompt.test.ts +57 -101
- package/src/__tests__/terminal-tools.test.ts +11 -1
- package/src/__tests__/thinking-block-replay.test.ts +113 -0
- package/src/__tests__/thread-backfill.test.ts +370 -22
- package/src/__tests__/tool-executor.test.ts +90 -1
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +167 -0
- package/src/__tests__/twilio-routes.test.ts +1 -1
- package/src/__tests__/web-fetch.test.ts +2 -2
- package/src/__tests__/workspace-git-service.test.ts +88 -5
- package/src/__tests__/workspace-migration-087-memory-router-balanced-profile.test.ts +228 -0
- package/src/__tests__/workspace-migration-088-deprecate-background-conversation-override.test.ts +158 -0
- package/src/a2a/__tests__/agent-card.test.ts +98 -0
- package/src/a2a/__tests__/e2e-a2a-channel.test.ts +597 -0
- package/src/a2a/__tests__/protocol-helpers.test.ts +113 -0
- package/src/a2a/__tests__/task-store.test.ts +246 -0
- package/src/a2a/agent-card.ts +58 -0
- package/src/a2a/feature-gate.ts +8 -0
- package/src/a2a/protocol-constants.ts +21 -0
- package/src/a2a/protocol-errors.ts +50 -0
- package/src/a2a/protocol-types.ts +162 -0
- package/src/a2a/task-store.ts +168 -0
- package/src/agent/attachments.ts +1 -0
- package/src/agent/loop.ts +208 -22
- package/src/background-wake/next-wake.test.ts +289 -0
- package/src/background-wake/next-wake.ts +172 -0
- package/src/browser/operations.ts +15 -0
- package/src/channels/config.ts +9 -0
- package/src/channels/types.ts +14 -0
- package/src/cli/commands/__tests__/conversations-slack.test.ts +572 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +9 -12
- package/src/cli/{__tests__ → commands/__tests__}/notifications.test.ts +201 -28
- package/src/cli/commands/__tests__/schedules.test.ts +469 -0
- package/src/cli/commands/conversations.ts +128 -1
- package/src/cli/commands/inference-providers.ts +147 -1
- package/src/cli/commands/memory-v2.ts +308 -0
- package/src/cli/commands/notifications.ts +89 -37
- package/src/cli/commands/plugins.ts +67 -0
- package/src/cli/commands/schedules.ts +297 -5
- package/src/cli/lib/__tests__/search-plugins.test.ts +261 -0
- package/src/cli/lib/install-from-github.ts +8 -9
- package/src/cli/lib/search-plugins.ts +163 -0
- package/src/cli/program.ts +14 -0
- package/src/cli/utils/conversation-id.ts +17 -5
- package/src/config/assistant-feature-flags.ts +24 -54
- package/src/config/bundled-skills/app-builder/SKILL.md +117 -1
- package/src/config/bundled-skills/document-editor/SKILL.md +115 -0
- package/src/config/bundled-skills/document-editor/TOOLS.json +240 -0
- package/src/config/bundled-skills/document-editor/tools/comment-list.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-reply.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-resolve.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-find.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-replace-text.ts +12 -0
- package/src/config/bundled-skills/media-processing/SKILL.md +8 -0
- package/src/config/bundled-skills/phone-calls/SKILL.md +1 -1
- package/src/config/bundled-skills/schedule/SKILL.md +8 -0
- package/src/config/bundled-tool-registry.ts +22 -12
- package/src/config/call-site-defaults.ts +124 -0
- package/src/config/feature-flag-registry.json +111 -23
- package/src/config/llm-resolver.ts +66 -1
- package/src/config/schema.ts +2 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +7 -3
- package/src/config/schemas/call-site-catalog.ts +21 -0
- package/src/config/schemas/channels.ts +9 -0
- package/src/config/schemas/conversations.ts +10 -0
- package/src/config/schemas/heartbeat.ts +14 -0
- package/src/config/schemas/llm.ts +4 -3
- package/src/config/schemas/memory-retrospective.ts +1 -1
- package/src/config/schemas/memory-v2.ts +51 -4
- package/src/config/schemas/memory.ts +3 -1
- package/src/config/seed-inference-profiles.ts +99 -29
- package/src/context/compactor.ts +80 -13
- package/src/context/token-estimator.ts +72 -31
- package/src/context/window-manager.ts +25 -0
- package/src/credential-health/credential-health-service.ts +34 -19
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -22
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -6
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +357 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +287 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +231 -23
- package/src/daemon/conversation-agent-loop.ts +252 -56
- package/src/daemon/conversation-lifecycle.ts +142 -116
- package/src/daemon/conversation-messaging.ts +3 -0
- package/src/daemon/conversation-process.ts +273 -0
- package/src/daemon/conversation-queue-manager.ts +14 -0
- package/src/daemon/conversation-runtime-assembly.ts +144 -75
- package/src/daemon/conversation-slash.ts +37 -5
- package/src/daemon/conversation-surfaces.ts +45 -2
- package/src/daemon/conversation-tool-setup.ts +7 -0
- package/src/daemon/conversation.ts +42 -12
- package/src/daemon/date-context.ts +40 -0
- package/src/daemon/first-greeting.ts +10 -0
- package/src/daemon/guardian-action-generators.ts +1 -125
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +498 -0
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +248 -0
- package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +154 -0
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +133 -0
- package/src/daemon/handlers/__tests__/config-a2a.test.ts +95 -0
- package/src/daemon/handlers/config-a2a.ts +449 -0
- package/src/daemon/handlers/config-model.test.ts +1 -0
- package/src/daemon/handlers/conversations.ts +80 -0
- package/src/daemon/handlers/shared.ts +92 -29
- package/src/daemon/host-app-control-proxy.ts +69 -18
- package/src/daemon/host-bash-proxy.ts +1 -1
- package/src/daemon/host-cu-proxy.ts +1 -1
- package/src/daemon/host-file-proxy.ts +1 -1
- package/src/daemon/host-proxy-preactivation.ts +85 -18
- package/src/daemon/host-transfer-proxy.ts +1 -1
- package/src/daemon/lifecycle.ts +67 -65
- package/src/daemon/memory-v2-startup.ts +49 -13
- package/src/daemon/message-protocol.ts +4 -0
- package/src/daemon/message-types/conversations.ts +8 -0
- package/src/daemon/message-types/document-comments.ts +50 -0
- package/src/daemon/message-types/messages.ts +68 -1
- package/src/daemon/message-types/notifications.ts +21 -0
- package/src/daemon/message-types/surfaces.ts +3 -1
- package/src/daemon/message-types/web-activity.ts +57 -0
- package/src/daemon/pkb-reminder-builder.test.ts +10 -53
- package/src/daemon/pkb-reminder-builder.ts +4 -19
- package/src/daemon/plugin-source-watcher.ts +135 -3
- package/src/daemon/process-message.ts +72 -12
- package/src/daemon/query-complexity-router.ts +75 -0
- package/src/daemon/skill-memory-refresh.ts +5 -1
- package/src/daemon/trust-context.ts +6 -0
- package/src/daemon/wake-target-adapter.ts +2 -0
- package/src/documents/document-comments-store.test.ts +338 -0
- package/src/documents/document-comments-store.ts +237 -0
- package/src/documents/document-store.ts +202 -0
- package/src/export/__tests__/transcript-formatter.test.ts +121 -0
- package/src/export/transcript-formatter.ts +54 -20
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +44 -1
- package/src/heartbeat/heartbeat-service.ts +35 -191
- package/src/home/__tests__/feed-types.test.ts +40 -0
- package/src/home/__tests__/suggested-prompts.test.ts +33 -2
- package/src/home/feed-types.ts +20 -3
- package/src/home/home-content-refresh.ts +52 -0
- package/src/home/home-greeting-cache.ts +69 -0
- package/src/home/home-greeting.ts +94 -0
- package/src/home/suggested-prompts.ts +177 -9
- package/src/ipc/cli-client.ts +147 -45
- package/src/memory/__tests__/conversation-queries.test.ts +220 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +135 -2
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +2 -50
- package/src/memory/__tests__/memory-retrospective-job.test.ts +407 -10
- package/src/memory/conversation-crud.ts +133 -43
- package/src/memory/conversation-queries.ts +87 -1
- package/src/memory/conversation-title-service.ts +26 -4
- package/src/memory/db-init.ts +22 -0
- package/src/memory/delivery-crud.ts +41 -0
- package/src/memory/delivery-status.ts +141 -15
- package/src/memory/external-conversation-store.ts +32 -1
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +84 -3
- package/src/memory/graph/conversation-graph-memory.ts +18 -6
- package/src/memory/graph/tools.ts +6 -37
- package/src/memory/invite-store.ts +53 -0
- package/src/memory/jobs-worker.ts +21 -1
- package/src/memory/llm-request-log-source-clickhouse.ts +7 -2
- package/src/memory/llm-request-log-store.ts +92 -1
- package/src/memory/memory-retrospective-constants.ts +28 -0
- package/src/memory/memory-retrospective-enqueue.ts +4 -22
- package/src/memory/memory-retrospective-job.ts +438 -21
- package/src/memory/memory-retrospective-startup-cleanup.ts +3 -3
- package/src/memory/memory-v2-activation-log-store.ts +26 -8
- package/src/memory/migrations/100-core-tables.ts +1 -0
- package/src/memory/migrations/109-external-conversation-bindings.ts +1 -0
- package/src/memory/migrations/250-provider-connection-base-url-and-models.ts +28 -0
- package/src/memory/migrations/251-a2a-tasks.ts +49 -0
- package/src/memory/migrations/252-llm-request-log-agent-loop-exit-reason.ts +32 -0
- package/src/memory/migrations/253-conversation-last-notified-profile.ts +15 -0
- package/src/memory/migrations/253-document-comments.ts +47 -0
- package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +43 -0
- package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +24 -0
- package/src/memory/migrations/256-memory-v2-injection-events.ts +113 -0
- package/src/memory/migrations/257-strip-base-url-non-openai-compatible.ts +22 -0
- package/src/memory/migrations/258-onboarding-events-prior-assistants.ts +13 -0
- package/src/memory/migrations/259-conversation-cleaned-at.ts +33 -0
- package/src/memory/migrations/index.ts +20 -0
- package/src/memory/migrations/registry.ts +33 -0
- package/src/memory/onboarding-events-store.ts +7 -0
- package/src/memory/schema/a2a.ts +15 -0
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/conversations.ts +3 -0
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/inference.ts +2 -0
- package/src/memory/schema/infrastructure.ts +2 -0
- package/src/memory/v2/__tests__/activation-store.test.ts +25 -23
- package/src/memory/v2/__tests__/cli-command-store.test.ts +404 -0
- package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +25 -4
- package/src/memory/v2/__tests__/injection-events.test.ts +318 -0
- package/src/memory/v2/__tests__/injection.test.ts +221 -17
- package/src/memory/v2/__tests__/page-index.test.ts +365 -1
- package/src/memory/v2/__tests__/router.test.ts +489 -1
- package/src/memory/v2/__tests__/static-context.test.ts +12 -1
- package/src/memory/v2/activation-store.ts +14 -16
- package/src/memory/v2/cli-command-content.ts +19 -0
- package/src/memory/v2/cli-command-store.ts +304 -0
- package/src/memory/v2/consolidation-job.ts +14 -0
- package/src/memory/v2/frontmatter-sweep.ts +7 -1
- package/src/memory/v2/injection-events.ts +101 -0
- package/src/memory/v2/injection.ts +69 -29
- package/src/memory/v2/page-index.ts +246 -19
- package/src/memory/v2/page-store.ts +18 -0
- package/src/memory/v2/router.ts +209 -55
- package/src/memory/v2/static-context.ts +4 -4
- package/src/memory/v2/types.ts +23 -0
- package/src/messaging/providers/a2a/__tests__/deliver.test.ts +274 -0
- package/src/messaging/providers/a2a/deliver.ts +156 -0
- package/src/messaging/providers/gmail/client.ts +9 -2
- package/src/messaging/providers/index.ts +18 -3
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +329 -3
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +34 -1
- package/src/messaging/providers/slack/adapter.ts +178 -25
- package/src/messaging/providers/slack/api.test.ts +54 -0
- package/src/messaging/providers/slack/api.ts +119 -3
- package/src/messaging/providers/slack/client.ts +12 -0
- package/src/messaging/providers/slack/deep-link.ts +20 -1
- package/src/messaging/providers/slack/message-metadata.test.ts +48 -0
- package/src/messaging/providers/slack/message-metadata.ts +156 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +107 -75
- package/src/messaging/providers/slack/render-transcript.ts +176 -49
- package/src/messaging/providers/slack/send.test.ts +77 -0
- package/src/messaging/providers/slack/send.ts +8 -2
- package/src/messaging/providers/slack/types.ts +14 -0
- package/src/notifications/__tests__/broadcaster.test.ts +203 -0
- package/src/notifications/__tests__/decision-engine.test.ts +283 -0
- package/src/notifications/__tests__/deterministic-checks.test.ts +286 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +5 -1
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +521 -36
- package/src/notifications/adapters/macos.ts +12 -2
- package/src/notifications/broadcaster.ts +29 -4
- package/src/notifications/conversation-seed-composer.ts +14 -2
- package/src/notifications/copy-composer.ts +17 -64
- package/src/notifications/decision-engine.ts +111 -44
- package/src/notifications/deferred-emit.ts +135 -0
- package/src/notifications/deterministic-checks.ts +96 -0
- package/src/notifications/emit-signal.ts +10 -1
- package/src/notifications/home-feed-side-effect.ts +136 -27
- package/src/notifications/signal.ts +0 -4
- package/src/notifications/types.ts +8 -0
- package/src/oauth/connect-orchestrator.ts +3 -0
- package/src/oauth/credential-token-resolver.ts +2 -0
- package/src/oauth/manual-token-connection.ts +19 -0
- package/src/oauth/oauth-store.ts +12 -0
- package/src/oauth/platform-connection.test.ts +43 -3
- package/src/oauth/platform-connection.ts +13 -4
- package/src/oauth/seed-providers.ts +22 -0
- package/src/permissions/prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +4 -1
- package/src/plugins/defaults/injectors.ts +118 -26
- package/src/plugins/external-plugin-loader.ts +82 -10
- package/src/plugins/types.ts +16 -7
- package/src/prompts/__tests__/system-prompt.test.ts +44 -45
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +4 -8
- package/src/prompts/normalize-onboarding.ts +40 -0
- package/src/prompts/sections.ts +32 -14
- package/src/prompts/system-prompt.ts +105 -76
- package/src/prompts/template-detection.ts +37 -0
- package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +141 -0
- package/src/prompts/templates/BOOTSTRAP.md +13 -5
- package/src/prompts/templates/VOICE.md +3 -0
- package/src/prompts/templates/system-sections.ts +51 -10
- package/src/providers/__tests__/inference.test.ts +2 -0
- package/src/providers/anthropic/client.ts +132 -5
- package/src/providers/call-site-routing.ts +24 -6
- package/src/providers/connection-resolution.ts +63 -13
- package/src/providers/fireworks/client.ts +20 -2
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +74 -0
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +342 -0
- package/src/providers/inference/__tests__/base-url-security.test.ts +189 -0
- package/src/providers/inference/__tests__/codex-token-refresh.test.ts +254 -0
- package/src/providers/inference/__tests__/connections-openai-compatible.test.ts +175 -0
- package/src/providers/inference/__tests__/connections-status-label.test.ts +15 -0
- package/src/providers/inference/adapter-factory.ts +24 -21
- package/src/providers/inference/auth.ts +15 -3
- package/src/providers/inference/backfill.ts +14 -1
- package/src/providers/inference/codex-token-refresh.ts +128 -0
- package/src/providers/inference/connections.ts +85 -5
- package/src/providers/inference/resolve-auth.ts +50 -5
- package/src/providers/model-catalog.ts +244 -242
- package/src/providers/model-intents.ts +3 -3
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +235 -0
- package/src/providers/openai/chat-completions-provider.ts +215 -25
- package/src/providers/openai/responses-provider.ts +9 -3
- package/src/providers/openrouter/client.ts +46 -4
- package/src/providers/platform-proxy/constants.ts +3 -4
- package/src/providers/provider-catalog-visibility.ts +3 -1
- package/src/providers/provider-send-message.ts +27 -12
- package/src/providers/registry.ts +30 -1
- package/src/providers/types.ts +25 -0
- package/src/runtime/__tests__/agent-wake.test.ts +214 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +128 -0
- package/src/runtime/agent-wake.ts +212 -57
- package/src/runtime/auth/route-policy.ts +20 -3
- package/src/runtime/background-job-runner.ts +26 -0
- package/src/runtime/channel-reply-delivery.ts +182 -47
- package/src/runtime/channel-retry-sweep.ts +141 -16
- package/src/runtime/http-server.ts +7 -16
- package/src/runtime/http-types.ts +7 -51
- package/src/runtime/pending-interactions.ts +51 -8
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +258 -0
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +162 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +121 -5
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +275 -44
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +12 -0
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +14 -0
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +271 -0
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +280 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +266 -0
- package/src/runtime/routes/approval-routes.ts +4 -1
- package/src/runtime/routes/channel-availability-routes.ts +5 -0
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +246 -0
- package/src/runtime/routes/consolidation-routes.ts +100 -0
- package/src/runtime/routes/content-source-routes.ts +78 -0
- package/src/runtime/routes/conversation-cli-routes.ts +146 -1
- package/src/runtime/routes/conversation-query-routes.ts +130 -12
- package/src/runtime/routes/conversation-routes.ts +288 -76
- package/src/runtime/routes/document-comments-routes.ts +287 -0
- package/src/runtime/routes/documents-routes.ts +33 -0
- package/src/runtime/routes/home-feed-routes.ts +6 -3
- package/src/runtime/routes/host-app-control-routes.ts +1 -1
- package/src/runtime/routes/host-browser-routes.ts +8 -1
- package/src/runtime/routes/identity-routes.ts +21 -0
- package/src/runtime/routes/inbound-message-handler.ts +288 -58
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +365 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +283 -82
- package/src/runtime/routes/index.ts +14 -4
- package/src/runtime/routes/inference-provider-connection-routes.ts +192 -3
- package/src/runtime/routes/integrations/a2a.ts +294 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +11 -1
- package/src/runtime/routes/log-export-routes.ts +39 -0
- package/src/runtime/routes/memory-v2-routes.ts +217 -0
- package/src/runtime/routes/notification-routes.ts +19 -2
- package/src/runtime/routes/question-routes.ts +4 -1
- package/src/runtime/routes/sanity-routes.ts +159 -0
- package/src/runtime/routes/slack-channel-routes.ts +187 -0
- package/src/runtime/routes/subagents-routes.ts +41 -0
- package/src/runtime/services/conversation-serializer.ts +30 -4
- package/src/schedule/integration-status.ts +3 -1
- package/src/security/__tests__/oauth2-device-code.test.ts +479 -0
- package/src/security/oauth2-device-code.ts +307 -0
- package/src/security/oauth2.ts +26 -9
- package/src/security/secure-keys.ts +5 -0
- package/src/skills/catalog-install.ts +6 -2
- package/src/subagent/manager.ts +2 -0
- package/src/tools/browser/__tests__/pinned-tabs.test.ts +80 -0
- package/src/tools/browser/browser-execution.ts +93 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +28 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +1 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +10 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +15 -1
- package/src/tools/browser/cdp-client/factory.ts +87 -3
- package/src/tools/browser/cdp-client/local-cdp-client.ts +9 -0
- package/src/tools/browser/cdp-client/types.ts +36 -0
- package/src/tools/browser/pinned-tabs.ts +90 -0
- package/src/tools/document/document-comment-tool.test.ts +379 -0
- package/src/tools/document/document-comment-tool.ts +156 -0
- package/src/tools/document/document-tool.ts +128 -2
- package/src/tools/memory/register.ts +1 -9
- package/src/tools/network/__tests__/web-fetch-metadata.test.ts +229 -0
- package/src/tools/network/__tests__/web-search-metadata.test.ts +346 -0
- package/src/tools/network/domain-normalize.ts +17 -0
- package/src/tools/network/web-fetch.ts +213 -64
- package/src/tools/network/web-search.ts +191 -66
- package/src/tools/registry.ts +2 -2
- package/src/tools/terminal/safe-env.ts +3 -2
- package/src/tools/tool-approval-handler.ts +19 -12
- package/src/tools/types.ts +41 -2
- package/src/tools/ui-surface/definitions.ts +3 -1
- package/src/types/onboarding-context.ts +4 -0
- package/src/util/__tests__/favicon.test.ts +84 -0
- package/src/util/favicon.ts +40 -0
- package/src/util/platform.ts +0 -5
- package/src/workspace/git-service.ts +75 -4
- package/src/workspace/migrations/087-memory-router-balanced-profile.ts +91 -0
- package/src/workspace/migrations/088-deprecate-background-conversation-override.ts +103 -0
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/__tests__/guardian-action-conversation-turn.test.ts +0 -441
- package/src/config/bundled-skills/document/SKILL.md +0 -54
- package/src/config/bundled-skills/document/TOOLS.json +0 -106
- package/src/daemon/seed-files.ts +0 -18
- package/src/memory/graph/__tests__/remember-description.test.ts +0 -55
- package/src/runtime/guardian-action-conversation-turn.ts +0 -99
- package/src/runtime/routes/interface-routes.ts +0 -43
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-create.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-delete.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-list.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-read.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-update.ts +0 -0
|
@@ -1,441 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
|
-
|
|
3
|
-
mock.module("../util/logger.js", () => ({
|
|
4
|
-
getLogger: () =>
|
|
5
|
-
new Proxy({} as Record<string, unknown>, {
|
|
6
|
-
get: () => () => {},
|
|
7
|
-
}),
|
|
8
|
-
}));
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
createCallSession,
|
|
12
|
-
createPendingQuestion,
|
|
13
|
-
} from "../calls/call-store.js";
|
|
14
|
-
import { getDb } from "../memory/db-connection.js";
|
|
15
|
-
import { initializeDb } from "../memory/db-init.js";
|
|
16
|
-
import {
|
|
17
|
-
createGuardianActionDelivery,
|
|
18
|
-
createGuardianActionRequest,
|
|
19
|
-
finalizeFollowup,
|
|
20
|
-
getFollowupDeliveriesByConversation,
|
|
21
|
-
getFollowupDeliveriesByDestination,
|
|
22
|
-
getGuardianActionRequest,
|
|
23
|
-
markTimedOutWithReason,
|
|
24
|
-
progressFollowupState,
|
|
25
|
-
startFollowupFromExpiredRequest,
|
|
26
|
-
updateDeliveryStatus,
|
|
27
|
-
} from "../memory/guardian-action-store.js";
|
|
28
|
-
import { conversations } from "../memory/schema.js";
|
|
29
|
-
import { processGuardianFollowUpTurn } from "../runtime/guardian-action-conversation-turn.js";
|
|
30
|
-
import type {
|
|
31
|
-
GuardianFollowUpConversationContext,
|
|
32
|
-
GuardianFollowUpConversationGenerator,
|
|
33
|
-
GuardianFollowUpTurnResult,
|
|
34
|
-
} from "../runtime/http-types.js";
|
|
35
|
-
|
|
36
|
-
initializeDb();
|
|
37
|
-
|
|
38
|
-
function ensureConversation(id: string): void {
|
|
39
|
-
const db = getDb();
|
|
40
|
-
const now = Date.now();
|
|
41
|
-
db.insert(conversations)
|
|
42
|
-
.values({
|
|
43
|
-
id,
|
|
44
|
-
title: `Conversation ${id}`,
|
|
45
|
-
createdAt: now,
|
|
46
|
-
updatedAt: now,
|
|
47
|
-
})
|
|
48
|
-
.run();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function resetTables(): void {
|
|
52
|
-
const db = getDb();
|
|
53
|
-
db.run("DELETE FROM guardian_action_deliveries");
|
|
54
|
-
db.run("DELETE FROM guardian_action_requests");
|
|
55
|
-
db.run("DELETE FROM call_pending_questions");
|
|
56
|
-
db.run("DELETE FROM call_events");
|
|
57
|
-
db.run("DELETE FROM call_sessions");
|
|
58
|
-
db.run("DELETE FROM messages");
|
|
59
|
-
db.run("DELETE FROM conversations");
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function createAwaitingChoiceRequest(
|
|
63
|
-
convId: string,
|
|
64
|
-
opts?: {
|
|
65
|
-
chatId?: string;
|
|
66
|
-
externalUserId?: string;
|
|
67
|
-
conversationId?: string;
|
|
68
|
-
},
|
|
69
|
-
) {
|
|
70
|
-
ensureConversation(convId);
|
|
71
|
-
const session = createCallSession({
|
|
72
|
-
conversationId: convId,
|
|
73
|
-
provider: "twilio",
|
|
74
|
-
fromNumber: "+15550001111",
|
|
75
|
-
toNumber: "+15550002222",
|
|
76
|
-
});
|
|
77
|
-
const pq = createPendingQuestion(session.id, "What is the gate code?");
|
|
78
|
-
const request = createGuardianActionRequest({
|
|
79
|
-
kind: "ask_guardian",
|
|
80
|
-
sourceChannel: "phone",
|
|
81
|
-
sourceConversationId: convId,
|
|
82
|
-
callSessionId: session.id,
|
|
83
|
-
pendingQuestionId: pq.id,
|
|
84
|
-
questionText: pq.questionText,
|
|
85
|
-
expiresAt: Date.now() - 10_000,
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
const deliveryConvId = opts?.conversationId ?? `delivery-conv-${request.id}`;
|
|
89
|
-
if (opts?.conversationId) {
|
|
90
|
-
ensureConversation(opts.conversationId);
|
|
91
|
-
} else {
|
|
92
|
-
ensureConversation(deliveryConvId);
|
|
93
|
-
}
|
|
94
|
-
const delivery = createGuardianActionDelivery({
|
|
95
|
-
requestId: request.id,
|
|
96
|
-
destinationChannel: "telegram",
|
|
97
|
-
destinationChatId: opts?.chatId ?? "chat-123",
|
|
98
|
-
destinationExternalUserId: opts?.externalUserId ?? "user-456",
|
|
99
|
-
destinationConversationId: deliveryConvId,
|
|
100
|
-
});
|
|
101
|
-
updateDeliveryStatus(delivery.id, "sent");
|
|
102
|
-
|
|
103
|
-
// Expire the request
|
|
104
|
-
markTimedOutWithReason(request.id, "call_timeout");
|
|
105
|
-
|
|
106
|
-
// Start follow-up (transitions to awaiting_guardian_choice)
|
|
107
|
-
startFollowupFromExpiredRequest(request.id, "The gate code is 1234");
|
|
108
|
-
|
|
109
|
-
return {
|
|
110
|
-
request: getGuardianActionRequest(request.id)!,
|
|
111
|
-
delivery,
|
|
112
|
-
deliveryConvId,
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// ---------------------------------------------------------------------------
|
|
117
|
-
// Helpers for creating mock generators
|
|
118
|
-
// ---------------------------------------------------------------------------
|
|
119
|
-
|
|
120
|
-
function createMockGenerator(
|
|
121
|
-
result: GuardianFollowUpTurnResult,
|
|
122
|
-
): GuardianFollowUpConversationGenerator {
|
|
123
|
-
return async (_context: GuardianFollowUpConversationContext) => result;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function createFailingGenerator(): GuardianFollowUpConversationGenerator {
|
|
127
|
-
return async () => {
|
|
128
|
-
throw new Error("LLM provider unavailable");
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
describe("guardian-action-conversation-turn", () => {
|
|
133
|
-
beforeEach(() => {
|
|
134
|
-
resetTables();
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
// ── processGuardianFollowUpTurn: classification ─────────────────────
|
|
138
|
-
|
|
139
|
-
test('classifies "call them back" as call_back', async () => {
|
|
140
|
-
const generator = createMockGenerator({
|
|
141
|
-
disposition: "call_back",
|
|
142
|
-
replyText: "Sure, I'll call them back right away.",
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
const result = await processGuardianFollowUpTurn(
|
|
146
|
-
{
|
|
147
|
-
questionText: "What is the gate code?",
|
|
148
|
-
lateAnswerText: "The gate code is 1234",
|
|
149
|
-
guardianReply: "Yes, call them back",
|
|
150
|
-
},
|
|
151
|
-
generator,
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
expect(result.disposition).toBe("call_back");
|
|
155
|
-
expect(result.replyText).toBe("Sure, I'll call them back right away.");
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
test('classifies "never mind" as decline', async () => {
|
|
159
|
-
const generator = createMockGenerator({
|
|
160
|
-
disposition: "decline",
|
|
161
|
-
replyText: "No problem. Let me know if you change your mind.",
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
const result = await processGuardianFollowUpTurn(
|
|
165
|
-
{
|
|
166
|
-
questionText: "What is the gate code?",
|
|
167
|
-
lateAnswerText: "The gate code is 1234",
|
|
168
|
-
guardianReply: "Never mind, forget it",
|
|
169
|
-
},
|
|
170
|
-
generator,
|
|
171
|
-
);
|
|
172
|
-
|
|
173
|
-
expect(result.disposition).toBe("decline");
|
|
174
|
-
expect(result.replyText).toBe(
|
|
175
|
-
"No problem. Let me know if you change your mind.",
|
|
176
|
-
);
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
test("classifies ambiguous input as keep_pending with clarification", async () => {
|
|
180
|
-
const generator = createMockGenerator({
|
|
181
|
-
disposition: "keep_pending",
|
|
182
|
-
replyText: "Would you like to call them back or send a text message?",
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
const result = await processGuardianFollowUpTurn(
|
|
186
|
-
{
|
|
187
|
-
questionText: "What is the gate code?",
|
|
188
|
-
lateAnswerText: "The gate code is 1234",
|
|
189
|
-
guardianReply: "hmm I dunno",
|
|
190
|
-
},
|
|
191
|
-
generator,
|
|
192
|
-
);
|
|
193
|
-
|
|
194
|
-
expect(result.disposition).toBe("keep_pending");
|
|
195
|
-
expect(result.replyText).toContain("call them back");
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
// ── Failure modes ───────────────────────────────────────────────────
|
|
199
|
-
|
|
200
|
-
test("generator failure returns keep_pending with safe fallback", async () => {
|
|
201
|
-
const generator = createFailingGenerator();
|
|
202
|
-
|
|
203
|
-
const result = await processGuardianFollowUpTurn(
|
|
204
|
-
{
|
|
205
|
-
questionText: "What is the gate code?",
|
|
206
|
-
lateAnswerText: "The gate code is 1234",
|
|
207
|
-
guardianReply: "Call them back please",
|
|
208
|
-
},
|
|
209
|
-
generator,
|
|
210
|
-
);
|
|
211
|
-
|
|
212
|
-
expect(result.disposition).toBe("keep_pending");
|
|
213
|
-
expect(result.replyText.length).toBeGreaterThan(0);
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
test("no generator returns keep_pending with safe fallback", async () => {
|
|
217
|
-
const result = await processGuardianFollowUpTurn(
|
|
218
|
-
{
|
|
219
|
-
questionText: "What is the gate code?",
|
|
220
|
-
lateAnswerText: "The gate code is 1234",
|
|
221
|
-
guardianReply: "Call them back",
|
|
222
|
-
},
|
|
223
|
-
undefined,
|
|
224
|
-
);
|
|
225
|
-
|
|
226
|
-
expect(result.disposition).toBe("keep_pending");
|
|
227
|
-
expect(result.replyText.length).toBeGreaterThan(0);
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
test("generator returning empty replyText falls back to keep_pending", async () => {
|
|
231
|
-
const generator = createMockGenerator({
|
|
232
|
-
disposition: "call_back",
|
|
233
|
-
replyText: "",
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
const result = await processGuardianFollowUpTurn(
|
|
237
|
-
{
|
|
238
|
-
questionText: "What is the gate code?",
|
|
239
|
-
lateAnswerText: "The gate code is 1234",
|
|
240
|
-
guardianReply: "Call them back",
|
|
241
|
-
},
|
|
242
|
-
generator,
|
|
243
|
-
);
|
|
244
|
-
|
|
245
|
-
expect(result.disposition).toBe("keep_pending");
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
test("generator returning invalid disposition falls back to keep_pending", async () => {
|
|
249
|
-
const generator: GuardianFollowUpConversationGenerator = async () => {
|
|
250
|
-
return {
|
|
251
|
-
disposition:
|
|
252
|
-
"invalid_value" as GuardianFollowUpTurnResult["disposition"],
|
|
253
|
-
replyText: "Some reply",
|
|
254
|
-
};
|
|
255
|
-
};
|
|
256
|
-
|
|
257
|
-
const result = await processGuardianFollowUpTurn(
|
|
258
|
-
{
|
|
259
|
-
questionText: "What is the gate code?",
|
|
260
|
-
lateAnswerText: "The gate code is 1234",
|
|
261
|
-
guardianReply: "Call them back",
|
|
262
|
-
},
|
|
263
|
-
generator,
|
|
264
|
-
);
|
|
265
|
-
|
|
266
|
-
expect(result.disposition).toBe("keep_pending");
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
test("reply text is always present in the result", async () => {
|
|
270
|
-
// With generator
|
|
271
|
-
const generatorResult = await processGuardianFollowUpTurn(
|
|
272
|
-
{
|
|
273
|
-
questionText: "What is the gate code?",
|
|
274
|
-
lateAnswerText: "The gate code is 1234",
|
|
275
|
-
guardianReply: "Call them",
|
|
276
|
-
},
|
|
277
|
-
createMockGenerator({
|
|
278
|
-
disposition: "call_back",
|
|
279
|
-
replyText: "Calling now!",
|
|
280
|
-
}),
|
|
281
|
-
);
|
|
282
|
-
expect(typeof generatorResult.replyText).toBe("string");
|
|
283
|
-
expect(generatorResult.replyText.length).toBeGreaterThan(0);
|
|
284
|
-
|
|
285
|
-
// Without generator
|
|
286
|
-
const fallbackResult = await processGuardianFollowUpTurn({
|
|
287
|
-
questionText: "What is the gate code?",
|
|
288
|
-
lateAnswerText: "The gate code is 1234",
|
|
289
|
-
guardianReply: "Call them",
|
|
290
|
-
});
|
|
291
|
-
expect(typeof fallbackResult.replyText).toBe("string");
|
|
292
|
-
expect(fallbackResult.replyText.length).toBeGreaterThan(0);
|
|
293
|
-
|
|
294
|
-
// With failing generator
|
|
295
|
-
const failResult = await processGuardianFollowUpTurn(
|
|
296
|
-
{
|
|
297
|
-
questionText: "What is the gate code?",
|
|
298
|
-
lateAnswerText: "The gate code is 1234",
|
|
299
|
-
guardianReply: "Call them",
|
|
300
|
-
},
|
|
301
|
-
createFailingGenerator(),
|
|
302
|
-
);
|
|
303
|
-
expect(typeof failResult.replyText).toBe("string");
|
|
304
|
-
expect(failResult.replyText.length).toBeGreaterThan(0);
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
// ── Store queries for awaiting_guardian_choice ───────────────────────
|
|
308
|
-
|
|
309
|
-
test("getFollowupDeliveriesByDestination returns deliveries in awaiting_guardian_choice", () => {
|
|
310
|
-
const { request } = createAwaitingChoiceRequest("conv-turn-1", {
|
|
311
|
-
chatId: "chat-abc",
|
|
312
|
-
externalUserId: "user-xyz",
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
const deliveries = getFollowupDeliveriesByDestination(
|
|
316
|
-
"telegram",
|
|
317
|
-
"chat-abc",
|
|
318
|
-
);
|
|
319
|
-
expect(deliveries).toHaveLength(1);
|
|
320
|
-
expect(deliveries[0].requestId).toBe(request.id);
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
test("getFollowupDeliveriesByDestination returns empty for non-matching channel", () => {
|
|
324
|
-
createAwaitingChoiceRequest("conv-turn-2", { chatId: "chat-abc" });
|
|
325
|
-
|
|
326
|
-
const deliveries = getFollowupDeliveriesByDestination("phone", "chat-abc");
|
|
327
|
-
expect(deliveries).toHaveLength(0);
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
test("getFollowupDeliveriesByDestination returns empty for expired with followup_state=none", () => {
|
|
331
|
-
// Create expired request WITHOUT starting follow-up
|
|
332
|
-
ensureConversation("conv-turn-3");
|
|
333
|
-
const session = createCallSession({
|
|
334
|
-
conversationId: "conv-turn-3",
|
|
335
|
-
provider: "twilio",
|
|
336
|
-
fromNumber: "+15550001111",
|
|
337
|
-
toNumber: "+15550002222",
|
|
338
|
-
});
|
|
339
|
-
const pq = createPendingQuestion(session.id, "Question?");
|
|
340
|
-
const request = createGuardianActionRequest({
|
|
341
|
-
kind: "ask_guardian",
|
|
342
|
-
sourceChannel: "phone",
|
|
343
|
-
sourceConversationId: "conv-turn-3",
|
|
344
|
-
callSessionId: session.id,
|
|
345
|
-
pendingQuestionId: pq.id,
|
|
346
|
-
questionText: pq.questionText,
|
|
347
|
-
expiresAt: Date.now() - 10_000,
|
|
348
|
-
});
|
|
349
|
-
ensureConversation(`delivery-conv-${request.id}`);
|
|
350
|
-
const delivery = createGuardianActionDelivery({
|
|
351
|
-
requestId: request.id,
|
|
352
|
-
destinationChannel: "telegram",
|
|
353
|
-
destinationChatId: "chat-none",
|
|
354
|
-
destinationExternalUserId: "user-none",
|
|
355
|
-
destinationConversationId: `delivery-conv-${request.id}`,
|
|
356
|
-
});
|
|
357
|
-
updateDeliveryStatus(delivery.id, "sent");
|
|
358
|
-
markTimedOutWithReason(request.id, "call_timeout");
|
|
359
|
-
|
|
360
|
-
// followup_state is 'none' — should not appear
|
|
361
|
-
const deliveries = getFollowupDeliveriesByDestination(
|
|
362
|
-
"telegram",
|
|
363
|
-
"chat-none",
|
|
364
|
-
);
|
|
365
|
-
expect(deliveries).toHaveLength(0);
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
test("getFollowupDeliveriesByConversation returns delivery in awaiting_guardian_choice", () => {
|
|
369
|
-
const { delivery, deliveryConvId } = createAwaitingChoiceRequest(
|
|
370
|
-
"conv-turn-4",
|
|
371
|
-
{
|
|
372
|
-
conversationId: "mac-conv-1",
|
|
373
|
-
},
|
|
374
|
-
);
|
|
375
|
-
|
|
376
|
-
const found = getFollowupDeliveriesByConversation(deliveryConvId);
|
|
377
|
-
expect(found).toHaveLength(1);
|
|
378
|
-
expect(found[0].id).toBe(delivery.id);
|
|
379
|
-
});
|
|
380
|
-
|
|
381
|
-
test("getFollowupDeliveriesByConversation returns empty for non-matching conversation", () => {
|
|
382
|
-
createAwaitingChoiceRequest("conv-turn-5", {
|
|
383
|
-
conversationId: "mac-conv-2",
|
|
384
|
-
});
|
|
385
|
-
|
|
386
|
-
const found = getFollowupDeliveriesByConversation("nonexistent-conv");
|
|
387
|
-
expect(found).toHaveLength(0);
|
|
388
|
-
});
|
|
389
|
-
|
|
390
|
-
// ── State transitions from conversation engine results ──────────────
|
|
391
|
-
|
|
392
|
-
test("call_back disposition transitions to dispatching with call_back action", () => {
|
|
393
|
-
const { request } = createAwaitingChoiceRequest("conv-turn-6");
|
|
394
|
-
|
|
395
|
-
// Simulate what the handler does with a call_back disposition
|
|
396
|
-
const updated = progressFollowupState(
|
|
397
|
-
request.id,
|
|
398
|
-
"dispatching",
|
|
399
|
-
"call_back",
|
|
400
|
-
);
|
|
401
|
-
expect(updated).not.toBeNull();
|
|
402
|
-
expect(updated!.followupState).toBe("dispatching");
|
|
403
|
-
expect(updated!.followupAction).toBe("call_back");
|
|
404
|
-
});
|
|
405
|
-
|
|
406
|
-
test("decline disposition finalizes to declined", () => {
|
|
407
|
-
const { request } = createAwaitingChoiceRequest("conv-turn-8");
|
|
408
|
-
|
|
409
|
-
const updated = finalizeFollowup(request.id, "declined");
|
|
410
|
-
expect(updated).not.toBeNull();
|
|
411
|
-
expect(updated!.followupState).toBe("declined");
|
|
412
|
-
expect(updated!.followupCompletedAt).toBeGreaterThan(0);
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
test("keep_pending disposition does not change state", () => {
|
|
416
|
-
const { request } = createAwaitingChoiceRequest("conv-turn-9");
|
|
417
|
-
|
|
418
|
-
// No state change for keep_pending — just verify the state is still awaiting_guardian_choice
|
|
419
|
-
const reloaded = getGuardianActionRequest(request.id);
|
|
420
|
-
expect(reloaded!.followupState).toBe("awaiting_guardian_choice");
|
|
421
|
-
});
|
|
422
|
-
|
|
423
|
-
test("state transitions are atomic: second call_back after dispatching fails", () => {
|
|
424
|
-
const { request } = createAwaitingChoiceRequest("conv-turn-10");
|
|
425
|
-
|
|
426
|
-
const first = progressFollowupState(request.id, "dispatching", "call_back");
|
|
427
|
-
expect(first).not.toBeNull();
|
|
428
|
-
|
|
429
|
-
// Second attempt: already in dispatching, cannot re-enter dispatching
|
|
430
|
-
const second = progressFollowupState(
|
|
431
|
-
request.id,
|
|
432
|
-
"dispatching",
|
|
433
|
-
"call_back",
|
|
434
|
-
);
|
|
435
|
-
expect(second).toBeNull();
|
|
436
|
-
|
|
437
|
-
// Original action preserved
|
|
438
|
-
const reloaded = getGuardianActionRequest(request.id);
|
|
439
|
-
expect(reloaded!.followupAction).toBe("call_back");
|
|
440
|
-
});
|
|
441
|
-
});
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: document
|
|
3
|
-
description: Write, draft, or compose long-form text (blog posts, articles, essays, reports, guides)
|
|
4
|
-
compatibility: "Designed for Vellum personal assistants"
|
|
5
|
-
metadata:
|
|
6
|
-
emoji: "📄"
|
|
7
|
-
vellum:
|
|
8
|
-
display-name: "Document"
|
|
9
|
-
activation-hints:
|
|
10
|
-
- "User asks to write, draft, or collaborate on long-form content — use the document editor for a better editing experience"
|
|
11
|
-
- "When content will be iterated on, reviewed, or exported, prefer the document editor over inline markdown"
|
|
12
|
-
- "When a file attachment contains a draft or document the user wants to iterate on, open it in the editor"
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
Create and edit long-form documents using the built-in rich text editor. Documents open in workspace mode with chat docked to the side.
|
|
16
|
-
|
|
17
|
-
## Tools
|
|
18
|
-
|
|
19
|
-
- **document_create** - Opens a new document editor with an optional title and initial Markdown content. Returns a `surface_id` for subsequent updates.
|
|
20
|
-
- **document_update** - Updates content in an open document editor by `surface_id`. Supports `replace` (overwrite) and `append` (add to end) modes.
|
|
21
|
-
- **document_read** - Reads the current content of a document by `surface_id` when it belongs to the current conversation, or when the current actor is the guardian/local user. Use to verify content before editing.
|
|
22
|
-
- **document_list** - Lists documents. Without `query`, lists the current conversation's documents. With `query`, searches by title; guardian/local users can search across conversations, while other actors are scoped to the current conversation.
|
|
23
|
-
- **document_delete** - Deletes a document by `surface_id`. Use to clean up unwanted documents.
|
|
24
|
-
|
|
25
|
-
## Retrieving existing documents
|
|
26
|
-
|
|
27
|
-
When the user asks to see, open, or pull up a document:
|
|
28
|
-
|
|
29
|
-
1. Check the `<active_documents>` block in your context — it lists all documents in this conversation with their `surface_id` and title. If the document is there, call `document_read` with its `surface_id`. Done in one call.
|
|
30
|
-
2. If the document is NOT in `<active_documents>`, call `document_list` with a `query` matching the document title. For guardian/local users, this searches across previous conversations and sessions.
|
|
31
|
-
3. Once you have the `surface_id`, call `document_read` to retrieve the content.
|
|
32
|
-
|
|
33
|
-
**Never** search the filesystem, conversation history, or archives to find a document. Always use `document_list` with a `query`.
|
|
34
|
-
|
|
35
|
-
## Creating a new document
|
|
36
|
-
|
|
37
|
-
1. **Create the document**: Call `document_create` with a title (inferred from the request). Call the tool immediately, not after conversational preamble.
|
|
38
|
-
2. **Write content in Markdown**: Use proper structure (`#` for titles, `##` for sections), **bold**, _italic_, code blocks, tables, lists, blockquotes as appropriate.
|
|
39
|
-
3. **CRITICAL - Stream content in chunks**: Call `document_update` MULTIPLE times, not just once. Break content into logical chunks (paragraphs, sections, or every 200-300 words). Call `document_update` with `mode: "append"` for EACH chunk separately. The user experiences real-time content appearing as you write.
|
|
40
|
-
|
|
41
|
-
## Editing an existing document
|
|
42
|
-
|
|
43
|
-
When the user requests changes to a document:
|
|
44
|
-
|
|
45
|
-
1. Find the `surface_id` from the `<active_documents>` context block.
|
|
46
|
-
2. Use `document_update` with the existing `surface_id` — do NOT call `document_create` again.
|
|
47
|
-
3. Use `mode: "replace"` for full rewrites or `mode: "append"` for additions.
|
|
48
|
-
|
|
49
|
-
## Usage Notes
|
|
50
|
-
|
|
51
|
-
- The `mode` parameter on `document_update` defaults to `append`.
|
|
52
|
-
- Documents are automatically saved and accessible via the Generated panel.
|
|
53
|
-
- Users can manually edit documents at any time.
|
|
54
|
-
- Write in clear, engaging prose. Use active voice, vary sentence structure, and break content into logical sections with descriptive headings.
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 1,
|
|
3
|
-
"tools": [
|
|
4
|
-
{
|
|
5
|
-
"name": "document_create",
|
|
6
|
-
"description": "Create a new long-form document with a rich text editor. Use this when the user asks to write a blog post, article, or any long-form content. The editor opens in workspace mode with chat docked to the side.",
|
|
7
|
-
"category": "document",
|
|
8
|
-
"risk": "low",
|
|
9
|
-
"input_schema": {
|
|
10
|
-
"type": "object",
|
|
11
|
-
"properties": {
|
|
12
|
-
"title": {
|
|
13
|
-
"type": "string",
|
|
14
|
-
"description": "Initial title for the document (optional, can be updated later)"
|
|
15
|
-
},
|
|
16
|
-
"initial_content": {
|
|
17
|
-
"type": "string",
|
|
18
|
-
"description": "Initial Markdown content to populate the editor (optional)"
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
"executor": "tools/document-create.ts",
|
|
23
|
-
"execution_target": "host"
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
"name": "document_update",
|
|
27
|
-
"description": "Update content in an open document editor. Use this to stream generated content or apply edits.",
|
|
28
|
-
"category": "document",
|
|
29
|
-
"risk": "low",
|
|
30
|
-
"input_schema": {
|
|
31
|
-
"type": "object",
|
|
32
|
-
"properties": {
|
|
33
|
-
"surface_id": {
|
|
34
|
-
"type": "string",
|
|
35
|
-
"description": "The ID of the document surface to update"
|
|
36
|
-
},
|
|
37
|
-
"content": {
|
|
38
|
-
"type": "string",
|
|
39
|
-
"description": "Markdown content to set or append"
|
|
40
|
-
},
|
|
41
|
-
"mode": {
|
|
42
|
-
"type": "string",
|
|
43
|
-
"enum": ["replace", "append"],
|
|
44
|
-
"description": "Whether to replace all content or append to the end. Defaults to append."
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
"required": ["surface_id", "content"]
|
|
48
|
-
},
|
|
49
|
-
"executor": "tools/document-update.ts",
|
|
50
|
-
"execution_target": "host"
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
"name": "document_read",
|
|
54
|
-
"description": "Read the current content of a document by its surface_id when it belongs to the current conversation, or when the current actor is the guardian/local user. Use this to verify document state before making edits.",
|
|
55
|
-
"category": "document",
|
|
56
|
-
"risk": "low",
|
|
57
|
-
"input_schema": {
|
|
58
|
-
"type": "object",
|
|
59
|
-
"properties": {
|
|
60
|
-
"surface_id": {
|
|
61
|
-
"type": "string",
|
|
62
|
-
"description": "The ID of the document to read"
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
"required": ["surface_id"]
|
|
66
|
-
},
|
|
67
|
-
"executor": "tools/document-read.ts",
|
|
68
|
-
"execution_target": "host"
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
"name": "document_list",
|
|
72
|
-
"description": "List documents. Without a query, lists documents in the current conversation. With a query, searches documents by title; guardian/local users can search across conversations, while other actors are scoped to the current conversation.",
|
|
73
|
-
"category": "document",
|
|
74
|
-
"risk": "low",
|
|
75
|
-
"input_schema": {
|
|
76
|
-
"type": "object",
|
|
77
|
-
"properties": {
|
|
78
|
-
"query": {
|
|
79
|
-
"type": "string",
|
|
80
|
-
"description": "Search documents by title. Omit to list only the current conversation's documents."
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
},
|
|
84
|
-
"executor": "tools/document-list.ts",
|
|
85
|
-
"execution_target": "host"
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
"name": "document_delete",
|
|
89
|
-
"description": "Delete a document by its surface_id.",
|
|
90
|
-
"category": "document",
|
|
91
|
-
"risk": "low",
|
|
92
|
-
"input_schema": {
|
|
93
|
-
"type": "object",
|
|
94
|
-
"properties": {
|
|
95
|
-
"surface_id": {
|
|
96
|
-
"type": "string",
|
|
97
|
-
"description": "The ID of the document to delete"
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
"required": ["surface_id"]
|
|
101
|
-
},
|
|
102
|
-
"executor": "tools/document-delete.ts",
|
|
103
|
-
"execution_target": "host"
|
|
104
|
-
}
|
|
105
|
-
]
|
|
106
|
-
}
|
package/src/daemon/seed-files.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { existsSync, mkdirSync } from "node:fs";
|
|
2
|
-
|
|
3
|
-
import { getLogger } from "../util/logger.js";
|
|
4
|
-
import { getInterfacesDir } from "../util/platform.js";
|
|
5
|
-
|
|
6
|
-
const log = getLogger("seed-files");
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Ensures interface directories exist so the runtime can serve files
|
|
10
|
-
* immediately. Called during daemon startup.
|
|
11
|
-
*/
|
|
12
|
-
export function seedInterfaceFiles(): void {
|
|
13
|
-
const tuiDir = getInterfacesDir();
|
|
14
|
-
if (!existsSync(tuiDir)) {
|
|
15
|
-
mkdirSync(tuiDir, { recursive: true });
|
|
16
|
-
log.info("Created interfaces directory");
|
|
17
|
-
}
|
|
18
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
|
-
|
|
3
|
-
let flagEnabled = false;
|
|
4
|
-
|
|
5
|
-
mock.module("../../../config/assistant-feature-flags.js", () => ({
|
|
6
|
-
isAssistantFeatureFlagEnabled: (_key: string, _config: unknown) =>
|
|
7
|
-
flagEnabled,
|
|
8
|
-
}));
|
|
9
|
-
|
|
10
|
-
import { getRememberDescription } from "../tools.js";
|
|
11
|
-
|
|
12
|
-
const stubConfig = {} as unknown as Parameters<
|
|
13
|
-
typeof getRememberDescription
|
|
14
|
-
>[0];
|
|
15
|
-
|
|
16
|
-
describe("getRememberDescription", () => {
|
|
17
|
-
beforeEach(() => {
|
|
18
|
-
flagEnabled = false;
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
test("flag off — returns the default high-pressure description", () => {
|
|
22
|
-
const desc = getRememberDescription(stubConfig);
|
|
23
|
-
expect(desc).toContain("**CRITICAL:**");
|
|
24
|
-
expect(desc).toContain("most frequently used tool");
|
|
25
|
-
expect(desc).toContain("almost every turn");
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
test("flag on — returns the relaxed judgment-framing description", () => {
|
|
29
|
-
flagEnabled = true;
|
|
30
|
-
const desc = getRememberDescription(stubConfig);
|
|
31
|
-
expect(desc).not.toContain("**CRITICAL:**");
|
|
32
|
-
expect(desc).not.toContain("almost every turn");
|
|
33
|
-
expect(desc).toContain("a retrospective pass");
|
|
34
|
-
expect(desc).toContain("Use judgment");
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
test("the two variants differ", () => {
|
|
38
|
-
flagEnabled = false;
|
|
39
|
-
const off = getRememberDescription(stubConfig);
|
|
40
|
-
flagEnabled = true;
|
|
41
|
-
const on = getRememberDescription(stubConfig);
|
|
42
|
-
expect(off).not.toBe(on);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
test("corrections-are-priority language is preserved in BOTH variants", () => {
|
|
46
|
-
flagEnabled = false;
|
|
47
|
-
expect(getRememberDescription(stubConfig)).toMatch(
|
|
48
|
-
/Corrections are.*highest priority/i,
|
|
49
|
-
);
|
|
50
|
-
flagEnabled = true;
|
|
51
|
-
expect(getRememberDescription(stubConfig)).toMatch(
|
|
52
|
-
/Corrections are.*highest priority/i,
|
|
53
|
-
);
|
|
54
|
-
});
|
|
55
|
-
});
|