@vellumai/assistant 0.6.4 → 0.6.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/.prettierignore +5 -0
- package/AGENTS.md +9 -1
- package/ARCHITECTURE.md +43 -49
- package/Dockerfile +17 -3
- package/README.md +3 -4
- package/__tests__/permissions/gateway-threshold-reader.test.ts +283 -0
- package/bun.lock +8 -3
- package/docs/architecture/integrations.md +33 -59
- package/docs/architecture/memory.md +25 -30
- package/docs/architecture/security.md +19 -18
- package/docs/browser-use-architecture-phase2.md +63 -20
- package/docs/error-handling.md +111 -0
- package/docs/plugins.md +761 -0
- package/docs/skills.md +10 -10
- package/docs/stt-provider-onboarding.md +2 -1
- package/examples/plugins/echo/README.md +132 -0
- package/examples/plugins/echo/package.json +17 -0
- package/examples/plugins/echo/register.ts +187 -0
- package/knip.json +9 -2
- package/node_modules/@vellumai/ces-contracts/package.json +2 -1
- package/node_modules/@vellumai/ces-contracts/src/__tests__/trust-rules.test.ts +471 -0
- package/node_modules/@vellumai/ces-contracts/src/trust-rules.ts +398 -4
- package/node_modules/@vellumai/credential-storage/bun.lock +2 -2
- package/node_modules/@vellumai/credential-storage/package.json +2 -2
- package/node_modules/@vellumai/credential-storage/src/oauth-runtime.ts +20 -2
- package/node_modules/@vellumai/egress-proxy/bun.lock +2 -2
- package/node_modules/@vellumai/egress-proxy/package.json +2 -2
- package/node_modules/@vellumai/egress-proxy/src/types.ts +19 -0
- package/openapi.yaml +334 -78
- package/package.json +6 -3
- package/scripts/generate-openapi.ts +50 -11
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +318 -0
- package/src/__tests__/agent-loop-sentry-hygiene.test.ts +137 -0
- package/src/__tests__/agent-loop.test.ts +112 -1
- package/src/__tests__/anthropic-error-formatting.test.ts +98 -0
- package/src/__tests__/anthropic-provider.test.ts +171 -2
- package/src/__tests__/app-compiler.test.ts +57 -0
- package/src/__tests__/approval-cascade.test.ts +36 -10
- package/src/__tests__/approval-routes-http.test.ts +134 -10
- package/src/__tests__/assistant-attachments.test.ts +44 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -0
- package/src/__tests__/auto-analysis-end-to-end.test.ts +1 -0
- package/src/__tests__/avatar-generator.test.ts +4 -2
- package/src/__tests__/browser-fill-credential.test.ts +1 -1
- package/src/__tests__/browser-identifier-parity-guard.test.ts +53 -0
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +23 -33
- package/src/__tests__/browser-skill-endstate.test.ts +51 -182
- package/src/__tests__/btw-routes.test.ts +47 -1
- package/src/__tests__/bundled-asset.test.ts +6 -6
- package/src/__tests__/call-controller.test.ts +1 -2
- package/src/__tests__/call-site-routing-provider.test.ts +214 -0
- package/src/__tests__/catalog-cache.test.ts +96 -4
- package/src/__tests__/channel-approval-routes.test.ts +4 -4
- package/src/__tests__/channel-reply-delivery.test.ts +300 -2
- package/src/__tests__/checker.test.ts +870 -655
- package/src/__tests__/circuit-breaker-pipeline.test.ts +406 -0
- package/src/__tests__/cli-command-risk-guard.test.ts +30 -33
- package/src/__tests__/compaction-events.test.ts +501 -0
- package/src/__tests__/compaction-pipeline.test.ts +210 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +181 -0
- package/src/__tests__/compaction-timeout-recovery.test.ts +262 -0
- package/src/__tests__/compaction.benchmark.test.ts +1 -1
- package/src/__tests__/config-analysis.test.ts +11 -28
- package/src/__tests__/config-loader-backfill.test.ts +174 -0
- package/src/__tests__/config-loader-corrupt.test.ts +183 -0
- package/src/__tests__/config-loader-quarantine-bulletin.test.ts +202 -0
- package/src/__tests__/config-model-image-provider.test.ts +110 -0
- package/src/__tests__/config-schema-cmd.test.ts +11 -5
- package/src/__tests__/config-schema.test.ts +440 -114
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +0 -4
- package/src/__tests__/config-watcher.test.ts +2 -2
- package/src/__tests__/contact-store-user-file.test.ts +72 -73
- package/src/__tests__/contacts-tools.test.ts +26 -0
- package/src/__tests__/contacts-write.test.ts +4 -4
- package/src/__tests__/context-overflow-policy.test.ts +7 -7
- package/src/__tests__/context-token-estimator.test.ts +191 -1
- package/src/__tests__/context-window-manager.test.ts +883 -4
- package/src/__tests__/conversation-abort-tool-results.test.ts +32 -15
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +86 -46
- package/src/__tests__/conversation-agent-loop.test.ts +435 -216
- package/src/__tests__/conversation-attachments.test.ts +1 -1
- package/src/__tests__/conversation-confirmation-signals.test.ts +36 -10
- package/src/__tests__/conversation-error.test.ts +37 -6
- package/src/__tests__/conversation-history-web-search.test.ts +7 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +34 -12
- package/src/__tests__/conversation-lifecycle.test.ts +336 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +27 -10
- package/src/__tests__/conversation-pairing.test.ts +174 -10
- package/src/__tests__/conversation-pre-run-repair.test.ts +32 -15
- package/src/__tests__/conversation-process-callsite.test.ts +309 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +44 -21
- package/src/__tests__/conversation-queue.test.ts +68 -38
- package/src/__tests__/conversation-routes-disk-view.test.ts +36 -7
- package/src/__tests__/conversation-routes-slash-commands.test.ts +31 -3
- package/src/__tests__/conversation-runtime-assembly.test.ts +2877 -152
- package/src/__tests__/conversation-runtime-workspace.test.ts +35 -50
- package/src/__tests__/conversation-seed-composer.test.ts +2 -2
- package/src/__tests__/conversation-skill-tools.test.ts +12 -146
- package/src/__tests__/conversation-slash-queue.test.ts +39 -19
- package/src/__tests__/conversation-slash-unknown.test.ts +53 -16
- package/src/__tests__/conversation-speed-override.test.ts +36 -12
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +1035 -0
- package/src/__tests__/conversation-surfaces-standalone.test.ts +630 -0
- package/src/__tests__/conversation-title-service.test.ts +118 -2
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +41 -2
- package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +1 -1
- package/src/__tests__/conversation-unread-route.test.ts +2 -2
- package/src/__tests__/conversation-usage.test.ts +4 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +33 -9
- package/src/__tests__/conversation-workspace-injection.test.ts +46 -15
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +46 -15
- package/src/__tests__/credential-broker-browser-fill.test.ts +110 -0
- package/src/__tests__/credential-health-service.test.ts +78 -9
- package/src/__tests__/credential-security-invariants.test.ts +5 -2
- package/src/__tests__/credential-storage-oauth-compat.test.ts +18 -0
- package/src/__tests__/credential-storage-static-compat.test.ts +28 -0
- package/src/__tests__/credential-vault-unit.test.ts +135 -19
- package/src/__tests__/credentials-cli.test.ts +1 -9
- package/src/__tests__/cross-provider-web-search.test.ts +84 -0
- package/src/__tests__/daemon-server-persist-and-process-callsite.test.ts +92 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +1 -0
- package/src/__tests__/delete-propagation.test.ts +437 -0
- package/src/__tests__/dm-backfill.test.ts +417 -0
- package/src/__tests__/dm-persistence.test.ts +227 -0
- package/src/__tests__/edit-propagation.test.ts +280 -0
- package/src/__tests__/empty-response-pipeline.test.ts +305 -0
- package/src/__tests__/ephemeral-permissions.test.ts +93 -3
- package/src/__tests__/estimator-calibration-integration.test.ts +208 -0
- package/src/__tests__/estimator-calibration.test.ts +213 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +29 -10
- package/src/__tests__/file-write-tool.test.ts +151 -1
- package/src/__tests__/filing-service.test.ts +255 -0
- package/src/__tests__/first-greeting.test.ts +247 -5
- package/src/__tests__/gemini-provider.test.ts +0 -3
- package/src/__tests__/guardian-grant-minting.test.ts +8 -0
- package/src/__tests__/headless-browser-interactions.test.ts +1 -1
- package/src/__tests__/headless-browser-mode.test.ts +57 -0
- package/src/__tests__/heartbeat-service.test.ts +96 -15
- package/src/__tests__/history-repair-pipeline.test.ts +399 -0
- package/src/__tests__/host-browser-e2e-cloud.test.ts +307 -0
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +3 -3
- package/src/__tests__/host-proxy-interface.test.ts +36 -2
- package/src/__tests__/host-shell-tool.test.ts +124 -18
- package/src/__tests__/http-user-message-parity.test.ts +29 -1
- package/src/__tests__/image-credentials.test.ts +137 -0
- package/src/__tests__/image-service-dispatcher.test.ts +186 -0
- package/src/__tests__/inbound-slack-persistence.test.ts +340 -0
- package/src/__tests__/injector-chain.test.ts +526 -0
- package/src/__tests__/intent-routing.test.ts +1 -66
- package/src/__tests__/llm-call-pipeline.test.ts +285 -0
- package/src/__tests__/llm-catalog-parity.test.ts +174 -0
- package/src/__tests__/llm-context-normalization.test.ts +121 -0
- package/src/__tests__/llm-resolver.test.ts +214 -0
- package/src/__tests__/llm-schema.test.ts +223 -0
- package/src/__tests__/managed-proxy-context.test.ts +6 -2
- package/src/__tests__/media-generate-image.test.ts +119 -13
- package/src/__tests__/memory-retrieval-pipeline.test.ts +401 -0
- package/src/__tests__/memory-upsert-concurrency.test.ts +1 -0
- package/src/__tests__/messaging-skill-split.test.ts +3 -34
- package/src/__tests__/migration-import-from-url.test.ts +621 -0
- package/src/__tests__/model-intents.test.ts +11 -83
- package/src/__tests__/notification-broadcaster.test.ts +3 -3
- package/src/__tests__/notification-decision-fallback.test.ts +0 -10
- package/src/__tests__/notification-decision-identity.test.ts +0 -9
- package/src/__tests__/notification-decision-recipient-context.test.ts +0 -9
- package/src/__tests__/notification-decision-strategy.test.ts +0 -11
- package/src/__tests__/notification-schedule-notify-dedup.test.ts +108 -0
- package/src/__tests__/oauth-apps-routes.test.ts +1 -1
- package/src/__tests__/oauth-cli.test.ts +14 -12
- package/src/__tests__/oauth-connect-orchestrator.test.ts +4 -13
- package/src/__tests__/oauth-provider-serializer.test.ts +6 -4
- package/src/__tests__/oauth-provider-visibility.test.ts +3 -5
- package/src/__tests__/oauth-providers-routes.test.ts +3 -2
- package/src/__tests__/oauth-store.test.ts +46 -78
- package/src/__tests__/oauth2-gateway-transport.test.ts +8 -3
- package/src/__tests__/oauth2-refresh-retry.test.ts +279 -0
- package/src/__tests__/onboarding-template-contract.test.ts +16 -64
- package/src/__tests__/openai-image-service.test.ts +368 -0
- package/src/__tests__/openai-provider.test.ts +7 -0
- package/src/__tests__/openai-responses-provider.test.ts +396 -0
- package/src/__tests__/openrouter-provider-only.test.ts +135 -0
- package/src/__tests__/outbound-slack-persistence.test.ts +293 -0
- package/src/__tests__/overflow-reduce-pipeline.test.ts +676 -0
- package/src/__tests__/permission-checker-host-gate.test.ts +1 -25
- package/src/__tests__/permission-mode.test.ts +16 -0
- package/src/__tests__/permission-types.test.ts +0 -1
- package/src/__tests__/persist-onboarding-artifacts.test.ts +266 -0
- package/src/__tests__/persistence-pipeline.test.ts +377 -0
- package/src/__tests__/persona-resolver.test.ts +13 -13
- package/src/__tests__/pipeline-runner.test.ts +565 -0
- package/src/__tests__/pkb-autoinject.test.ts +37 -1
- package/src/__tests__/platform-bash-auto-approve.test.ts +1 -1
- package/src/__tests__/platform.test.ts +5 -2
- package/src/__tests__/plugin-bootstrap.test.ts +483 -0
- package/src/__tests__/plugin-registry.test.ts +273 -0
- package/src/__tests__/plugin-route-contribution.test.ts +288 -0
- package/src/__tests__/plugin-skill-contribution.test.ts +367 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +286 -0
- package/src/__tests__/plugin-types.test.ts +320 -0
- package/src/__tests__/pricing.test.ts +93 -14
- package/src/__tests__/profiler-routes.test.ts +1 -1
- package/src/__tests__/provider-commit-message-generator.test.ts +14 -84
- package/src/__tests__/provider-env-vars-scope.test.ts +52 -0
- package/src/__tests__/provider-error-scenarios.test.ts +135 -6
- package/src/__tests__/provider-managed-proxy-integration.test.ts +42 -11
- package/src/__tests__/provider-registry-ollama.test.ts +1 -2
- package/src/__tests__/proxy-approval-callback.test.ts +69 -9
- package/src/__tests__/reaction-persistence.test.ts +561 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +0 -2
- package/src/__tests__/relay-server.test.ts +1 -1
- package/src/__tests__/require-fresh-approval.test.ts +1 -1
- package/src/__tests__/retry-openrouter-only-normalization.test.ts +136 -0
- package/src/__tests__/retry-thinking-tool-choice.test.ts +226 -0
- package/src/__tests__/risk-classifier-parity.test.ts +230 -0
- package/src/__tests__/sanitize-config-for-transfer.test.ts +78 -1
- package/src/__tests__/schedule-routes.test.ts +131 -1
- package/src/__tests__/scheduler-recurrence.test.ts +14 -70
- package/src/__tests__/scheduler-reuse-conversation.test.ts +10 -50
- package/src/__tests__/secret-detection-handler.test.ts +0 -10
- package/src/__tests__/secret-ingress-http.test.ts +28 -0
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +125 -0
- package/src/__tests__/secret-routes-managed-proxy.test.ts +2 -3
- package/src/__tests__/secret-scanner-executor.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +29 -1
- package/src/__tests__/server-history-render.test.ts +31 -0
- package/src/__tests__/shell-identity.test.ts +0 -134
- package/src/__tests__/shell-parser-property.test.ts +13 -13
- package/src/__tests__/skill-cache-store.test.ts +182 -0
- package/src/__tests__/skills.test.ts +19 -33
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +3 -1
- package/src/__tests__/slack-skill.test.ts +3 -8
- package/src/__tests__/starter-bundle.test.ts +35 -0
- package/src/__tests__/subagent-call-site-routing.test.ts +280 -0
- package/src/__tests__/suggestion-routes.test.ts +259 -3
- package/src/__tests__/system-prompt.test.ts +22 -35
- package/src/__tests__/task-memory-cleanup.test.ts +1 -0
- package/src/__tests__/task-runner.test.ts +3 -1
- package/src/__tests__/task-scheduler.test.ts +3 -15
- package/src/__tests__/tcc-sandbox-deny.test.ts +198 -0
- package/src/__tests__/terminal-tools.test.ts +8 -0
- package/src/__tests__/test-preload.ts +11 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +2 -52
- package/src/__tests__/thread-backfill.test.ts +941 -0
- package/src/__tests__/title-generate-pipeline.test.ts +224 -0
- package/src/__tests__/token-estimate-pipeline.test.ts +431 -0
- package/src/__tests__/tool-error-pipeline.test.ts +244 -0
- package/src/__tests__/tool-execute-pipeline.test.ts +431 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -8
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +2 -2
- package/src/__tests__/tool-executor-shell-integration.test.ts +7 -10
- package/src/__tests__/tool-executor.test.ts +201 -94
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +356 -0
- package/src/__tests__/tool-result-truncation.test.ts +0 -110
- package/src/__tests__/trust-store.test.ts +442 -109
- package/src/__tests__/update-bulletin-job.test.ts +389 -0
- package/src/__tests__/usage-cache-backfill-migration.test.ts +3 -1
- package/src/__tests__/user-plugin-loader.test.ts +191 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +1 -22
- package/src/__tests__/voice-session-bridge.test.ts +39 -0
- package/src/__tests__/volume-security-guard.test.ts +3 -2
- package/src/__tests__/web-search-history.test.ts +337 -0
- package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +343 -0
- package/src/__tests__/workspace-migration-043-release-notes-latex-rendering.test.ts +202 -0
- package/src/__tests__/workspace-migration-045-release-notes-meet-avatar.test.ts +210 -0
- package/src/__tests__/workspace-migration-046-seed-conversation-starters-callsite.test.ts +185 -0
- package/src/__tests__/workspace-migration-049-release-notes-default-sonnet.test.ts +100 -0
- package/src/__tests__/workspace-migration-050-seed-main-agent-opus-callsite.test.ts +171 -0
- package/src/__tests__/workspace-migration-051-seed-conversation-summarization-callsite.test.ts +252 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +11 -11
- package/src/__tests__/workspace-migration-remove-hooks.test.ts +99 -0
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +841 -0
- package/src/__tests__/workspace-policy.test.ts +22 -16
- package/src/acp/client-handler.ts +1 -2
- package/src/agent/loop.ts +545 -115
- package/src/approvals/__tests__/guardian-feed-event.test.ts +304 -0
- package/src/approvals/guardian-request-resolvers.ts +80 -0
- package/src/avatar/resvg-lazy.test.ts +136 -0
- package/src/avatar/resvg-lazy.ts +82 -9
- package/src/avatar/traits-png-sync.ts +21 -1
- package/src/backup/__tests__/backup-worker.test.ts +2 -13
- package/src/backup/backup-worker.ts +3 -15
- package/src/browser/__tests__/operations.test.ts +163 -0
- package/src/browser/identifiers.ts +51 -0
- package/src/browser/operations.ts +660 -0
- package/src/browser/types.ts +81 -0
- package/src/bundler/app-compiler.ts +84 -1
- package/src/calls/call-state.ts +2 -2
- package/src/calls/guardian-question-copy.ts +2 -2
- package/src/calls/telephony-stt-routing.ts +1 -1
- package/src/calls/voice-session-bridge.ts +1 -0
- package/src/channels/__tests__/types.test.ts +3 -3
- package/src/channels/types.ts +6 -4
- package/src/cli/AGENTS.md +1 -1
- package/src/cli/__tests__/notifications.test.ts +87 -211
- package/src/cli/commands/__tests__/attachment.test.ts +438 -0
- package/src/cli/commands/__tests__/backup.test.ts +1 -1
- package/src/cli/commands/__tests__/browser.test.ts +554 -0
- package/src/cli/commands/__tests__/cache.test.ts +623 -0
- package/src/cli/commands/__tests__/email-list.test.ts +6 -0
- package/src/cli/commands/__tests__/email-send.test.ts +93 -1
- package/src/cli/commands/__tests__/image-generation.test.ts +886 -0
- package/src/cli/commands/__tests__/inference-send.test.ts +463 -0
- package/src/cli/commands/__tests__/stt-transcribe.test.ts +454 -0
- package/src/cli/commands/__tests__/task.test.ts +913 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +606 -0
- package/src/cli/commands/__tests__/ui-confirm.test.ts +650 -0
- package/src/cli/commands/__tests__/ui.test.ts +1215 -0
- package/src/cli/commands/__tests__/watchers.test.ts +716 -0
- package/src/cli/commands/attachment.ts +182 -0
- package/src/cli/commands/backup.ts +2 -2
- package/src/cli/commands/browser.ts +350 -0
- package/src/cli/commands/cache.ts +341 -0
- package/src/cli/commands/clients.ts +138 -0
- package/src/cli/commands/completions.ts +2 -12
- package/src/cli/commands/config.ts +6 -6
- package/src/cli/commands/conversations-import.ts +347 -0
- package/src/cli/commands/conversations.ts +69 -8
- package/src/cli/commands/email.ts +234 -194
- package/src/cli/commands/image-generation.ts +299 -0
- package/src/cli/commands/inference.ts +200 -0
- package/src/cli/commands/memory.ts +127 -17
- package/src/cli/commands/notifications.ts +68 -103
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +1 -1
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -1
- package/src/cli/commands/oauth/connect.ts +2 -2
- package/src/cli/commands/oauth/providers.ts +176 -8
- package/src/cli/commands/oauth/status.ts +46 -36
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/connect.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +0 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +0 -1
- package/src/cli/commands/skills.ts +3 -4
- package/src/cli/commands/stt.ts +339 -0
- package/src/cli/commands/task.ts +795 -0
- package/src/cli/commands/trust.ts +50 -19
- package/src/cli/commands/tts.ts +273 -0
- package/src/cli/commands/ui.ts +670 -0
- package/src/cli/commands/watchers.ts +509 -0
- package/src/cli/lib/daemon-credential-client.ts +0 -19
- package/src/cli/program.ts +39 -24
- package/src/cli.ts +0 -37
- package/src/config/__tests__/backup-schema.test.ts +7 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +10 -10
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +66 -87
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +28 -51
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +22 -40
- package/src/config/bundled-skills/image-studio/SKILL.md +2 -1
- package/src/config/bundled-skills/image-studio/TOOLS.json +2 -1
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +23 -39
- package/src/config/bundled-skills/media-processing/services/reduce.ts +1 -1
- package/src/config/bundled-skills/messaging/SKILL.md +5 -5
- package/src/config/bundled-skills/messaging/TOOLS.json +4 -0
- package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +207 -0
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +20 -1
- package/src/config/bundled-skills/messaging/tools/messaging-read.ts +15 -1
- package/src/config/bundled-skills/messaging/tools/messaging-search.ts +21 -1
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +69 -12
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +9 -8
- package/src/config/bundled-skills/schedule/SKILL.md +8 -3
- package/src/config/bundled-skills/schedule/TOOLS.json +15 -7
- package/src/config/bundled-skills/schedule/references/SCRIPT_MODE_PATTERNS.md +59 -0
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-tool-registry.ts +0 -190
- package/src/config/env.ts +7 -2
- package/src/config/feature-flag-registry.json +42 -10
- package/src/config/llm-resolver.ts +128 -0
- package/src/config/loader.ts +194 -10
- package/src/config/raw-config-utils.ts +30 -2
- package/src/config/sanitize-for-transfer.ts +35 -0
- package/src/config/schema.ts +49 -41
- package/src/config/schemas/analysis.ts +3 -22
- package/src/config/schemas/backup.ts +1 -1
- package/src/config/schemas/calls.ts +0 -4
- package/src/config/schemas/conversations.ts +16 -0
- package/src/config/schemas/filing.ts +2 -7
- package/src/config/schemas/heartbeat.ts +0 -5
- package/src/config/schemas/inference.ts +3 -23
- package/src/config/schemas/llm.ts +317 -0
- package/src/config/schemas/memory-processing.ts +1 -9
- package/src/config/schemas/notifications.ts +4 -11
- package/src/config/schemas/platform.ts +3 -9
- package/src/config/schemas/security.ts +33 -0
- package/src/config/schemas/services.ts +9 -4
- package/src/config/schemas/stt.ts +1 -0
- package/src/config/schemas/tts.ts +64 -0
- package/src/config/schemas/updates.ts +1 -1
- package/src/config/schemas/workspace-git.ts +3 -40
- package/src/config/skill-state.ts +6 -2
- package/src/config/skills.ts +96 -7
- package/src/context/__tests__/compact-prompt.test.ts +63 -0
- package/src/context/__tests__/microcompact.test.ts +805 -0
- package/src/context/estimator-calibration.ts +136 -0
- package/src/context/microcompact.ts +443 -0
- package/src/context/prompts/compact.md +26 -0
- package/src/context/token-estimator.ts +61 -3
- package/src/context/tool-result-truncation.ts +3 -63
- package/src/context/window-manager.ts +417 -39
- package/src/credential-execution/approval-bridge.ts +0 -1
- package/src/credential-execution/executable-discovery.ts +19 -8
- package/src/credential-execution/process-manager.test.ts +109 -0
- package/src/credential-execution/process-manager.ts +65 -2
- package/src/credential-health/credential-health-service.ts +19 -6
- package/src/daemon/__tests__/conversation-feed-event.test.ts +317 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +4 -12
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +14 -15
- package/src/daemon/approval-generators.ts +29 -4
- package/src/daemon/assistant-attachments.ts +24 -13
- package/src/daemon/classifier.ts +2 -2
- package/src/daemon/config-watcher.ts +0 -3
- package/src/daemon/context-overflow-policy.ts +4 -13
- package/src/daemon/context-overflow-reducer.ts +4 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +162 -34
- package/src/daemon/conversation-agent-loop.ts +1282 -599
- package/src/daemon/conversation-attachments.ts +2 -6
- package/src/daemon/conversation-error.ts +36 -1
- package/src/daemon/conversation-history.ts +10 -19
- package/src/daemon/conversation-lifecycle.ts +59 -17
- package/src/daemon/conversation-messaging.ts +73 -4
- package/src/daemon/conversation-notifiers.ts +2 -110
- package/src/daemon/conversation-process.ts +24 -11
- package/src/daemon/conversation-queue-manager.ts +3 -0
- package/src/daemon/conversation-runtime-assembly.ts +1063 -211
- package/src/daemon/conversation-slash.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +389 -1
- package/src/daemon/conversation-tool-setup.ts +51 -9
- package/src/daemon/conversation-usage.ts +1 -1
- package/src/daemon/conversation.ts +197 -64
- package/src/daemon/external-plugins-bootstrap.ts +478 -0
- package/src/daemon/external-skills-bootstrap.ts +41 -0
- package/src/daemon/first-greeting.ts +191 -14
- package/src/daemon/guardian-action-generators.ts +34 -14
- package/src/daemon/handlers/config-model.test.ts +86 -0
- package/src/daemon/handlers/config-model.ts +65 -12
- package/src/daemon/handlers/conversations.ts +9 -2
- package/src/daemon/handlers/shared.ts +39 -11
- package/src/daemon/handlers/skills.ts +7 -3
- package/src/daemon/handlers/slack-channel-oauth-install.ts +197 -0
- package/src/daemon/lifecycle.ts +109 -82
- package/src/daemon/message-types/computer-use.ts +2 -34
- package/src/daemon/message-types/conversations.ts +63 -0
- package/src/daemon/message-types/messages.ts +21 -1
- package/src/daemon/message-types/trust.ts +0 -2
- package/src/daemon/parse-actual-tokens-from-error.test.ts +57 -1
- package/src/daemon/parse-actual-tokens-from-error.ts +66 -0
- package/src/daemon/pkb-context-tracker.test.ts +169 -0
- package/src/daemon/pkb-context-tracker.ts +125 -0
- package/src/daemon/pkb-reminder-builder.test.ts +70 -0
- package/src/daemon/pkb-reminder-builder.ts +31 -0
- package/src/daemon/providers-setup.ts +6 -0
- package/src/daemon/server.ts +122 -12
- package/src/daemon/shutdown-handlers.ts +2 -12
- package/src/daemon/tool-side-effects.ts +14 -65
- package/src/daemon/web-search-history.ts +126 -0
- package/src/events/domain-events.ts +0 -1
- package/src/filing/filing-service.ts +9 -10
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +160 -0
- package/src/heartbeat/heartbeat-service.ts +99 -28
- package/src/home/__tests__/feed-population-integration.test.ts +312 -0
- package/src/home/__tests__/feed-scheduler.test.ts +39 -11
- package/src/home/__tests__/rollup-producer.test.ts +44 -0
- package/src/home/assistant-feed-authoring.ts +4 -0
- package/src/home/emit-feed-event.ts +11 -0
- package/src/home/feed-scheduler.ts +20 -4
- package/src/home/feed-types.ts +97 -4
- package/src/home/relationship-state-writer.ts +2 -2
- package/src/home/rewrite-command-preview.ts +66 -0
- package/src/home/rollup-producer.ts +34 -5
- package/src/home/suggested-prompts.ts +101 -0
- package/src/ipc/__tests__/attachment-ipc.test.ts +213 -0
- package/src/ipc/__tests__/browser-ipc.test.ts +339 -0
- package/src/ipc/__tests__/cache-ipc.test.ts +266 -0
- package/src/ipc/__tests__/socket-path.test.ts +34 -0
- package/src/ipc/__tests__/task-ipc.test.ts +577 -0
- package/src/ipc/__tests__/ui-request-route.test.ts +495 -0
- package/src/ipc/__tests__/watcher-ipc.test.ts +295 -0
- package/src/ipc/cli-client.ts +2 -1
- package/src/ipc/cli-server.ts +26 -8
- package/src/ipc/gateway-client.ts +6 -3
- package/src/ipc/routes/attachment.ts +114 -0
- package/src/ipc/routes/browser-context.ts +63 -0
- package/src/ipc/routes/browser.ts +97 -0
- package/src/ipc/routes/cache.ts +96 -0
- package/src/ipc/routes/get-contact.ts +16 -0
- package/src/ipc/routes/index.ts +31 -1
- package/src/ipc/routes/list-clients.ts +31 -0
- package/src/ipc/routes/merge-contacts.ts +17 -0
- package/src/ipc/routes/notification.ts +133 -0
- package/src/ipc/routes/rename-conversation.ts +59 -0
- package/src/ipc/routes/search-contacts.ts +19 -0
- package/src/ipc/routes/task-queue.ts +226 -0
- package/src/ipc/routes/task.ts +173 -0
- package/src/ipc/routes/ui-request.ts +50 -0
- package/src/ipc/routes/upsert-contact.ts +25 -0
- package/src/ipc/routes/watcher.ts +203 -0
- package/src/ipc/socket-path.ts +76 -0
- package/src/media/app-icon-generator.ts +23 -46
- package/src/media/avatar-router.ts +26 -41
- package/src/media/gemini-image-service.ts +8 -41
- package/src/media/image-credentials.ts +73 -0
- package/src/media/image-service.ts +85 -0
- package/src/media/openai-image-service.ts +131 -0
- package/src/media/types.ts +46 -0
- package/src/memory/__tests__/conversation-analyze-job.test.ts +9 -8
- package/src/memory/__tests__/conversation-group-migration.test.ts +99 -0
- package/src/memory/admin.ts +18 -0
- package/src/memory/conversation-analyze-job.ts +14 -13
- package/src/memory/conversation-attention-store.ts +13 -6
- package/src/memory/conversation-crud.ts +133 -3
- package/src/memory/conversation-group-migration.ts +38 -6
- package/src/memory/conversation-queries.ts +57 -4
- package/src/memory/conversation-title-service.ts +32 -4
- package/src/memory/db-init.ts +10 -0
- package/src/memory/embedding-backend.ts +1 -1
- package/src/memory/embedding-gemini.test.ts +41 -2
- package/src/memory/embedding-gemini.ts +6 -1
- package/src/memory/graph/bootstrap.test.ts +282 -0
- package/src/memory/graph/bootstrap.ts +8 -5
- package/src/memory/graph/compaction.ts +299 -0
- package/src/memory/graph/consolidation.ts +4 -4
- package/src/memory/graph/conversation-graph-memory.ts +89 -29
- package/src/memory/graph/extraction.test.ts +272 -2
- package/src/memory/graph/extraction.ts +183 -53
- package/src/memory/graph/graph-search.test.ts +93 -0
- package/src/memory/graph/graph-search.ts +4 -1
- package/src/memory/graph/inspect.ts +2 -2
- package/src/memory/graph/narrative.ts +2 -2
- package/src/memory/graph/pattern-scan.ts +2 -2
- package/src/memory/graph/retriever.test.ts +459 -0
- package/src/memory/graph/retriever.ts +237 -48
- package/src/memory/graph/store.ts +41 -0
- package/src/memory/graph/tool-handlers.ts +27 -0
- package/src/memory/graph/tools.ts +6 -1
- package/src/memory/indexer.ts +5 -5
- package/src/memory/job-handlers/conversation-starters.ts +23 -20
- package/src/memory/job-handlers/summarization.ts +2 -2
- package/src/memory/job-utils.ts +7 -1
- package/src/memory/jobs/embed-pkb-file.test.ts +168 -0
- package/src/memory/jobs/embed-pkb-file.ts +54 -0
- package/src/memory/jobs-store.ts +44 -3
- package/src/memory/jobs-worker.ts +4 -0
- package/src/memory/migrations/041-approval-prompt-ts-tracker.ts +26 -0
- package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +1 -1
- package/src/memory/migrations/149-oauth-tables.ts +1 -0
- package/src/memory/migrations/220-normalize-user-file-by-principal.ts +2 -2
- package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +82 -0
- package/src/memory/migrations/223-schedule-script-column.ts +11 -0
- package/src/memory/migrations/224-oauth-providers-managed-service-is-paid.ts +24 -0
- package/src/memory/migrations/225-oauth-providers-available-scopes.ts +13 -0
- package/src/memory/migrations/index.ts +5 -0
- package/src/memory/pkb/pkb-index.test.ts +369 -0
- package/src/memory/pkb/pkb-index.ts +255 -0
- package/src/memory/pkb/pkb-reconcile.test.ts +252 -0
- package/src/memory/pkb/pkb-reconcile.ts +148 -0
- package/src/memory/pkb/pkb-search.test.ts +499 -0
- package/src/memory/pkb/pkb-search.ts +159 -0
- package/src/memory/pkb/types.ts +53 -0
- package/src/memory/qdrant-client.test.ts +60 -0
- package/src/memory/qdrant-client.ts +147 -1
- package/src/memory/schema/infrastructure.ts +1 -0
- package/src/memory/schema/oauth.ts +4 -1
- package/src/memory/slack-thread-store.ts +37 -0
- package/src/messaging/providers/gmail/adapter.ts +6 -16
- package/src/messaging/providers/gmail/client.ts +22 -0
- package/src/messaging/providers/gmail/types.ts +7 -0
- package/src/messaging/providers/slack/adapter.ts +14 -2
- package/src/messaging/providers/slack/backfill.test.ts +257 -0
- package/src/messaging/providers/slack/backfill.ts +101 -0
- package/src/messaging/providers/slack/message-metadata.test.ts +316 -0
- package/src/messaging/providers/slack/message-metadata.ts +123 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +1421 -0
- package/src/messaging/providers/slack/render-transcript.ts +501 -0
- package/src/messaging/style-analyzer.ts +5 -2
- package/src/notifications/README.md +9 -5
- package/src/notifications/conversation-pairing.ts +78 -19
- package/src/notifications/copy-composer.ts +0 -5
- package/src/notifications/decision-engine.ts +3 -9
- package/src/notifications/emit-signal.ts +1 -1
- package/src/notifications/preference-extractor.ts +2 -6
- package/src/notifications/signal.ts +1 -2
- package/src/oauth/AGENTS.md +1 -1
- package/src/oauth/__tests__/identity-verifier.test.ts +2 -1
- package/src/oauth/connect-orchestrator.ts +8 -34
- package/src/oauth/connect-types.ts +6 -10
- package/src/oauth/manual-token-connection.ts +23 -0
- package/src/oauth/oauth-store.ts +31 -14
- package/src/oauth/platform-connection.test.ts +47 -0
- package/src/oauth/platform-connection.ts +15 -5
- package/src/oauth/provider-serializer.ts +6 -1
- package/src/oauth/seed-providers.ts +56 -106
- package/src/outbound-proxy/http-forwarder.ts +9 -0
- package/src/permissions/approval-policy.test.ts +1223 -0
- package/src/permissions/approval-policy.ts +309 -0
- package/src/permissions/arg-parser.test.ts +161 -0
- package/src/permissions/arg-parser.ts +141 -0
- package/src/permissions/bash-risk-classifier.test.ts +1620 -0
- package/src/permissions/bash-risk-classifier.ts +950 -0
- package/src/permissions/checker.ts +348 -711
- package/src/permissions/command-registry.test.ts +774 -0
- package/src/permissions/command-registry.ts +1005 -0
- package/src/permissions/defaults.ts +28 -79
- package/src/permissions/file-risk-classifier.test.ts +535 -0
- package/src/permissions/file-risk-classifier.ts +274 -0
- package/src/permissions/gateway-threshold-reader.ts +196 -0
- package/src/permissions/prompter.ts +4 -0
- package/src/permissions/risk-types.ts +262 -0
- package/src/permissions/schedule-risk-classifier.test.ts +129 -0
- package/src/permissions/schedule-risk-classifier.ts +85 -0
- package/src/permissions/secret-prompter.ts +53 -2
- package/src/permissions/shell-identity.ts +2 -42
- package/src/permissions/skill-risk-classifier.test.ts +311 -0
- package/src/permissions/skill-risk-classifier.ts +214 -0
- package/src/permissions/trust-client.ts +52 -25
- package/src/permissions/trust-store-interface.ts +1 -6
- package/src/permissions/trust-store.ts +161 -62
- package/src/permissions/types.ts +25 -14
- package/src/permissions/web-risk-classifier.test.ts +170 -0
- package/src/permissions/web-risk-classifier.ts +89 -0
- package/src/permissions/workspace-policy.ts +9 -19
- package/src/platform/client.ts +19 -1
- package/src/plugins/defaults/circuit-breaker.ts +146 -0
- package/src/plugins/defaults/compaction.ts +145 -0
- package/src/plugins/defaults/empty-response.ts +126 -0
- package/src/plugins/defaults/history-repair.ts +85 -0
- package/src/plugins/defaults/index.ts +116 -0
- package/src/plugins/defaults/injectors.ts +491 -0
- package/src/plugins/defaults/llm-call.ts +82 -0
- package/src/plugins/defaults/memory-retrieval.ts +226 -0
- package/src/plugins/defaults/overflow-reduce.ts +181 -0
- package/src/plugins/defaults/persistence.ts +129 -0
- package/src/plugins/defaults/title-generate.ts +95 -0
- package/src/plugins/defaults/token-estimate.ts +104 -0
- package/src/plugins/defaults/tool-error.ts +126 -0
- package/src/plugins/defaults/tool-execute.ts +89 -0
- package/src/plugins/defaults/tool-result-truncate.ts +88 -0
- package/src/plugins/pipeline.ts +316 -0
- package/src/plugins/plugin-skill-contributions.ts +292 -0
- package/src/plugins/registry.ts +241 -0
- package/src/plugins/types.ts +1134 -0
- package/src/plugins/user-loader.ts +177 -0
- package/src/prompts/persona-resolver.ts +3 -3
- package/src/prompts/system-prompt.ts +19 -20
- package/src/prompts/templates/BOOTSTRAP.md +27 -77
- package/src/prompts/templates/SOUL.md +2 -2
- package/src/prompts/update-bulletin-job.ts +190 -0
- package/src/providers/__tests__/context-overflow-error.test.ts +328 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +102 -0
- package/src/providers/__tests__/retry-callsite.test.ts +424 -0
- package/src/providers/anthropic/client.ts +183 -14
- package/src/providers/call-site-routing.ts +71 -0
- package/src/providers/gemini/client.ts +65 -2
- package/src/providers/managed-proxy/constants.ts +2 -1
- package/src/providers/model-catalog.ts +524 -33
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/openai/chat-completions-provider.ts +57 -1
- package/src/providers/openai/responses-provider.ts +86 -9
- package/src/providers/openrouter/client.ts +80 -9
- package/src/providers/provider-env-vars.ts +56 -0
- package/src/providers/provider-send-message.ts +22 -5
- package/src/providers/ratelimit.ts +4 -0
- package/src/providers/registry.ts +19 -8
- package/src/providers/retry.ts +174 -39
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +55 -0
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +61 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +57 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.ts +4 -4
- package/src/providers/speech-to-text/provider-catalog.ts +17 -0
- package/src/providers/speech-to-text/resolve.ts +7 -0
- package/src/providers/speech-to-text/xai-realtime.test.ts +646 -0
- package/src/providers/speech-to-text/xai-realtime.ts +821 -0
- package/src/providers/speech-to-text/xai.test.ts +155 -0
- package/src/providers/speech-to-text/xai.ts +97 -0
- package/src/providers/types.ts +93 -3
- package/src/runtime/AGENTS.md +27 -18
- package/src/runtime/__tests__/agent-wake.test.ts +43 -2
- package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +3 -3
- package/src/runtime/__tests__/client-registry.test.ts +293 -0
- package/src/runtime/__tests__/interactive-ui.test.ts +673 -0
- package/src/runtime/agent-wake.ts +63 -22
- package/src/runtime/auth/route-policy.ts +4 -0
- package/src/runtime/btw-sidechain.ts +13 -3
- package/src/runtime/channel-reply-delivery.ts +106 -2
- package/src/runtime/client-registry.ts +261 -0
- package/src/runtime/decision-token.ts +116 -0
- package/src/runtime/gateway-client.ts +2 -2
- package/src/runtime/http-router.ts +32 -0
- package/src/runtime/http-server.ts +129 -9
- package/src/runtime/http-types.ts +23 -3
- package/src/runtime/interactive-ui.ts +362 -0
- package/src/runtime/invite-instruction-generator.ts +2 -2
- package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +176 -0
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +390 -0
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge.test.ts +221 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +1540 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +453 -0
- package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +222 -0
- package/src/runtime/migrations/gcs-signed-url.ts +162 -0
- package/src/runtime/migrations/vbundle-builder.ts +1 -22
- package/src/runtime/migrations/vbundle-importer.ts +154 -9
- package/src/runtime/migrations/vbundle-metadata-merge.ts +124 -0
- package/src/runtime/migrations/vbundle-streaming-importer.ts +2522 -0
- package/src/runtime/migrations/vbundle-streaming-validator.ts +244 -0
- package/src/runtime/migrations/vbundle-tar-stream.ts +217 -0
- package/src/runtime/migrations/vbundle-validator.ts +15 -6
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +111 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +114 -75
- package/src/runtime/routes/__tests__/migration-vellum-metadata-reconcile.test.ts +246 -0
- package/src/runtime/routes/approval-prompt-ts-tracker.ts +78 -0
- package/src/runtime/routes/approval-routes.ts +29 -17
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +9 -0
- package/src/runtime/routes/avatar-routes.ts +20 -4
- package/src/runtime/routes/browser-extension-pair-routes.ts +27 -8
- package/src/runtime/routes/btw-routes.ts +1 -4
- package/src/runtime/routes/conversation-management-routes.ts +20 -2
- package/src/runtime/routes/conversation-routes.ts +351 -138
- package/src/runtime/routes/debug-routes.ts +1 -1
- package/src/runtime/routes/diagnostics-routes.ts +6 -4
- package/src/runtime/routes/events-routes.ts +16 -0
- package/src/runtime/routes/guardian-approval-interception.ts +33 -3
- package/src/runtime/routes/guardian-approval-prompt.ts +13 -3
- package/src/runtime/routes/home-feed-routes.ts +120 -2
- package/src/runtime/routes/inbound-message-handler.ts +987 -2
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +113 -2
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +61 -3
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +129 -6
- package/src/runtime/routes/integrations/slack/channel.ts +25 -3
- package/src/runtime/routes/llm-context-normalization.ts +23 -1
- package/src/runtime/routes/memory-item-routes.test.ts +1 -0
- package/src/runtime/routes/migration-routes.ts +720 -127
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +284 -0
- package/src/runtime/routes/playground/__tests__/guard.test.ts +80 -0
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +294 -0
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +271 -0
- package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +202 -0
- package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +309 -0
- package/src/runtime/routes/playground/__tests__/state.test.ts +224 -0
- package/src/runtime/routes/playground/conversation-not-found.ts +29 -0
- package/src/runtime/routes/playground/deps.ts +56 -0
- package/src/runtime/routes/playground/force-compact.ts +73 -0
- package/src/runtime/routes/playground/guard.ts +37 -0
- package/src/runtime/routes/playground/index.ts +28 -0
- package/src/runtime/routes/playground/inject-failures.ts +159 -0
- package/src/runtime/routes/playground/reset-circuit.ts +115 -0
- package/src/runtime/routes/playground/seed-conversation.ts +139 -0
- package/src/runtime/routes/playground/seeded-conversations.ts +78 -0
- package/src/runtime/routes/playground/state.ts +78 -0
- package/src/runtime/routes/schedule-routes.ts +89 -8
- package/src/runtime/routes/settings-routes.ts +4 -2
- package/src/runtime/routes/trust-rules-routes.ts +30 -14
- package/src/runtime/routes/work-items-routes.test.ts +1 -1
- package/src/runtime/routes/work-items-routes.ts +3 -2
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +25 -43
- package/src/runtime/services/analyze-conversation.ts +12 -16
- package/src/runtime/skill-route-registry.ts +97 -15
- package/src/schedule/run-script.ts +68 -0
- package/src/schedule/schedule-store.ts +7 -1
- package/src/schedule/scheduler.ts +56 -8
- package/src/security/__tests__/provider-key-env-fallback.test.ts +119 -0
- package/src/security/__tests__/untrusted-content.test.ts +109 -0
- package/src/security/oauth2.ts +98 -35
- package/src/security/secure-keys.ts +7 -8
- package/src/security/token-manager.ts +27 -13
- package/src/security/untrusted-content.ts +102 -0
- package/src/skills/catalog-cache.ts +35 -9
- package/src/skills/catalog-install.ts +31 -3
- package/src/skills/skill-cache-store.ts +97 -0
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +76 -0
- package/src/stt/daemon-batch-transcriber.ts +33 -0
- package/src/stt/stt-stream-session.ts +8 -1
- package/src/stt/types.ts +5 -1
- package/src/subagent/manager.ts +41 -13
- package/src/tasks/ephemeral-permissions.ts +9 -4
- package/src/telemetry/usage-telemetry-reporter.ts +27 -5
- package/src/tools/browser/__tests__/browser-status.test.ts +234 -2
- package/src/tools/browser/browser-execution.ts +150 -54
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +230 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +146 -3
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +22 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +54 -3
- package/src/tools/browser/cdp-client/factory.ts +15 -4
- package/src/tools/credentials/tool-policy.ts +39 -5
- package/src/tools/credentials/vault.ts +9 -4
- package/src/tools/executor.ts +129 -73
- package/src/tools/filesystem/write.ts +52 -0
- package/src/tools/host-terminal/host-shell.ts +45 -5
- package/src/tools/memory/register.test.ts +185 -0
- package/src/tools/memory/register.ts +3 -1
- package/src/tools/network/script-proxy/session-manager.ts +37 -1
- package/src/tools/network/web-fetch.ts +20 -10
- package/src/tools/network/web-search.ts +19 -4
- package/src/tools/permission-checker.ts +116 -46
- package/src/tools/policy-context.ts +29 -8
- package/src/tools/registry.ts +195 -6
- package/src/tools/schedule/create.ts +23 -8
- package/src/tools/schedule/update.ts +3 -1
- package/src/tools/secret-detection-handler.ts +0 -51
- package/src/tools/side-effects.ts +0 -11
- package/src/tools/skills/execute.ts +2 -2
- package/src/tools/skills/sandbox-runner.ts +5 -2
- package/src/tools/system/avatar-generator.ts +6 -2
- package/src/tools/terminal/backends/native.ts +51 -2
- package/src/tools/terminal/safe-env.ts +3 -2
- package/src/tools/terminal/shell.ts +1 -0
- package/src/tools/tool-manifest.ts +6 -21
- package/src/tools/types.ts +40 -5
- package/src/tools/verification-control-plane-policy.ts +1 -1
- package/src/tts/__tests__/provider-adapters.test.ts +240 -13
- package/src/tts/provider-catalog.ts +18 -0
- package/src/tts/providers/index.ts +2 -0
- package/src/tts/providers/xai-provider.ts +224 -0
- package/src/tts/types.ts +46 -0
- package/src/types/tar-stream.d.ts +66 -0
- package/src/util/json.ts +17 -0
- package/src/util/platform.ts +9 -4
- package/src/util/pricing.ts +41 -8
- package/src/watcher/engine.ts +1 -1
- package/src/watcher/providers/google-calendar.ts +134 -8
- package/src/watcher/providers/outlook-calendar.ts +42 -2
- package/src/workspace/git-service.ts +23 -4
- package/src/workspace/migrations/006-services-config.ts +2 -4
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +2 -3
- package/src/workspace/migrations/038-unify-llm-callsite-configs.ts +516 -0
- package/src/workspace/migrations/039-drop-legacy-llm-keys.ts +171 -0
- package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +154 -0
- package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +56 -0
- package/src/workspace/migrations/042-fix-backfill-google-gmail-settings-scope.ts +70 -0
- package/src/workspace/migrations/043-release-notes-latex-rendering.ts +75 -0
- package/src/workspace/migrations/044-bump-stale-provider-stream-timeout.ts +51 -0
- package/src/workspace/migrations/045-release-notes-meet-avatar.ts +130 -0
- package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +108 -0
- package/src/workspace/migrations/047-remove-watch-callsites.ts +54 -0
- package/src/workspace/migrations/048-remove-workspace-hooks.ts +81 -0
- package/src/workspace/migrations/049-release-notes-default-sonnet.ts +80 -0
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +86 -0
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +128 -0
- package/src/workspace/migrations/AGENTS.md +1 -1
- package/src/workspace/migrations/registry.ts +28 -0
- package/src/workspace/provider-commit-message-generator.ts +19 -38
- package/tsconfig.json +1 -1
- package/hook-templates/debug-prompt-logger/hook.json +0 -7
- package/hook-templates/debug-prompt-logger/run.sh +0 -66
- package/src/__tests__/context-overflow-approval.test.ts +0 -156
- package/src/__tests__/gmail-archive-fallback.test.ts +0 -193
- package/src/__tests__/gmail-archive-gate.test.ts +0 -246
- package/src/__tests__/gmail-preferences.test.ts +0 -117
- package/src/__tests__/hooks-blocking.test.ts +0 -178
- package/src/__tests__/hooks-cli.test.ts +0 -182
- package/src/__tests__/hooks-config.test.ts +0 -108
- package/src/__tests__/hooks-discovery.test.ts +0 -211
- package/src/__tests__/hooks-integration.test.ts +0 -196
- package/src/__tests__/hooks-manager.test.ts +0 -226
- package/src/__tests__/hooks-runner.test.ts +0 -175
- package/src/__tests__/hooks-settings.test.ts +0 -160
- package/src/__tests__/hooks-templates.test.ts +0 -169
- package/src/__tests__/hooks-ts-runner.test.ts +0 -170
- package/src/__tests__/hooks-watch.test.ts +0 -112
- package/src/__tests__/notification-schedule-dedup.test.ts +0 -213
- package/src/__tests__/oauth-scope-policy.test.ts +0 -180
- package/src/__tests__/outlook-attachments.test.ts +0 -301
- package/src/__tests__/outlook-automation-tools.test.ts +0 -425
- package/src/__tests__/outlook-categories.test.ts +0 -212
- package/src/__tests__/outlook-compose-tools.test.ts +0 -325
- package/src/__tests__/outlook-declutter-tools.test.ts +0 -585
- package/src/__tests__/outlook-follow-up.test.ts +0 -196
- package/src/__tests__/outlook-trash.test.ts +0 -77
- package/src/__tests__/outlook-unsubscribe.test.ts +0 -279
- package/src/__tests__/send-notification-tool.test.ts +0 -83
- package/src/__tests__/update-bulletin-format.test.ts +0 -181
- package/src/__tests__/update-bulletin-state.test.ts +0 -135
- package/src/__tests__/update-bulletin.test.ts +0 -478
- package/src/__tests__/update-template-contract.test.ts +0 -29
- package/src/cli/commands/doctor.ts +0 -341
- package/src/cli/commands/shotgun.ts +0 -266
- package/src/config/bundled-skills/browser/SKILL.md +0 -88
- package/src/config/bundled-skills/browser/TOOLS.json +0 -516
- package/src/config/bundled-skills/browser/tools/browser-attach.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-click.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-close.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-detach.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-extract.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-hover.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-navigate.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-press-key.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-scroll.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-select-option.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-status.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-type.ts +0 -12
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +0 -49
- package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +0 -12
- package/src/config/bundled-skills/chatgpt-import/SKILL.md +0 -27
- package/src/config/bundled-skills/chatgpt-import/TOOLS.json +0 -27
- package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +0 -378
- package/src/config/bundled-skills/conversations/SKILL.md +0 -20
- package/src/config/bundled-skills/conversations/TOOLS.json +0 -23
- package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +0 -66
- package/src/config/bundled-skills/gmail/SKILL.md +0 -221
- package/src/config/bundled-skills/gmail/TOOLS.json +0 -588
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +0 -256
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +0 -112
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +0 -44
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +0 -81
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +0 -108
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +0 -146
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +0 -53
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +0 -347
- package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +0 -59
- package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +0 -82
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +0 -26
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +0 -347
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +0 -29
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +0 -122
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +0 -67
- package/src/config/bundled-skills/gmail/tools/scan-result-store.ts +0 -100
- package/src/config/bundled-skills/gmail/tools/shared.ts +0 -47
- package/src/config/bundled-skills/google-calendar/SKILL.md +0 -51
- package/src/config/bundled-skills/google-calendar/TOOLS.json +0 -226
- package/src/config/bundled-skills/google-calendar/calendar-client.ts +0 -223
- package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +0 -27
- package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +0 -48
- package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +0 -19
- package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +0 -36
- package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +0 -58
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +0 -17
- package/src/config/bundled-skills/google-calendar/types.ts +0 -97
- package/src/config/bundled-skills/heartbeat/SKILL.md +0 -43
- package/src/config/bundled-skills/notifications/SKILL.md +0 -40
- package/src/config/bundled-skills/notifications/TOOLS.json +0 -80
- package/src/config/bundled-skills/notifications/tools/send-notification.ts +0 -152
- package/src/config/bundled-skills/notifications/tools/shared.ts +0 -13
- package/src/config/bundled-skills/outlook/SKILL.md +0 -196
- package/src/config/bundled-skills/outlook/TOOLS.json +0 -530
- package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +0 -85
- package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +0 -77
- package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +0 -84
- package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +0 -94
- package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +0 -49
- package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +0 -237
- package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +0 -161
- package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +0 -32
- package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +0 -272
- package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +0 -29
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +0 -129
- package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +0 -87
- package/src/config/bundled-skills/outlook/tools/shared.ts +0 -20
- package/src/config/bundled-skills/outlook-calendar/SKILL.md +0 -51
- package/src/config/bundled-skills/outlook-calendar/TOOLS.json +0 -221
- package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +0 -252
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +0 -53
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +0 -74
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +0 -18
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +0 -46
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +0 -36
- package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +0 -17
- package/src/config/bundled-skills/outlook-calendar/types.ts +0 -120
- package/src/config/bundled-skills/screen-watch/SKILL.md +0 -27
- package/src/config/bundled-skills/screen-watch/TOOLS.json +0 -35
- package/src/config/bundled-skills/screen-watch/tools/start-screen-watch.ts +0 -12
- package/src/config/bundled-skills/skills-catalog/SKILL.md +0 -84
- package/src/config/bundled-skills/slack/SKILL.md +0 -108
- package/src/config/bundled-skills/tasks/SKILL.md +0 -37
- package/src/config/bundled-skills/tasks/TOOLS.json +0 -353
- package/src/config/bundled-skills/tasks/icon.svg +0 -34
- package/src/config/bundled-skills/tasks/tools/task-delete.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-add.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-show.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list-update.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-list.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-queue-run.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-run.ts +0 -12
- package/src/config/bundled-skills/tasks/tools/task-save.ts +0 -12
- package/src/config/bundled-skills/watcher/SKILL.md +0 -31
- package/src/config/bundled-skills/watcher/TOOLS.json +0 -167
- package/src/config/bundled-skills/watcher/tools/watcher-create.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-list.ts +0 -12
- package/src/config/bundled-skills/watcher/tools/watcher-update.ts +0 -12
- package/src/daemon/context-overflow-approval.ts +0 -52
- package/src/daemon/watch-handler.ts +0 -399
- package/src/hooks/cli.ts +0 -253
- package/src/hooks/config.ts +0 -100
- package/src/hooks/discovery.ts +0 -135
- package/src/hooks/manager.ts +0 -179
- package/src/hooks/runner.ts +0 -117
- package/src/hooks/templates.ts +0 -77
- package/src/hooks/types.ts +0 -75
- package/src/oauth/scope-policy.ts +0 -89
- package/src/prompts/templates/UPDATES.md +0 -50
- package/src/prompts/update-bulletin-format.ts +0 -85
- package/src/prompts/update-bulletin-state.ts +0 -58
- package/src/prompts/update-bulletin-template-path.ts +0 -13
- package/src/prompts/update-bulletin.ts +0 -139
- package/src/runtime/gateway-internal-client.ts +0 -94
- package/src/runtime/routes/watch-routes.ts +0 -156
- package/src/shared/provider-env-vars.ts +0 -19
- package/src/signals/shotgun.ts +0 -203
- package/src/tools/watch/screen-watch.ts +0 -144
- package/src/tools/watch/watch-state.ts +0 -142
- package/src/tools/watcher/create.ts +0 -86
- package/src/tools/watcher/delete.ts +0 -36
- package/src/tools/watcher/digest.ts +0 -54
- package/src/tools/watcher/list.ts +0 -83
- package/src/tools/watcher/update.ts +0 -71
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Route handlers for conversation messages and suggestions.
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
existsSync,
|
|
6
|
+
readdirSync,
|
|
7
|
+
readFileSync,
|
|
8
|
+
statSync,
|
|
9
|
+
writeFileSync,
|
|
10
|
+
} from "node:fs";
|
|
5
11
|
import { join, relative } from "node:path";
|
|
6
12
|
|
|
7
13
|
import { z } from "zod";
|
|
@@ -48,10 +54,12 @@ import type {
|
|
|
48
54
|
NonHostProxyTransportMetadata,
|
|
49
55
|
} from "../../daemon/message-types/conversations.js";
|
|
50
56
|
import type { HeartbeatService } from "../../heartbeat/heartbeat-service.js";
|
|
57
|
+
import { emitFeedEvent } from "../../home/emit-feed-event.js";
|
|
51
58
|
import {
|
|
52
59
|
writeOnboardingSidecar,
|
|
53
60
|
writeRelationshipState,
|
|
54
61
|
} from "../../home/relationship-state-writer.js";
|
|
62
|
+
import { rewriteCommandPreview } from "../../home/rewrite-command-preview.js";
|
|
55
63
|
import * as attachmentsStore from "../../memory/attachments-store.js";
|
|
56
64
|
import {
|
|
57
65
|
createCanonicalGuardianRequest,
|
|
@@ -65,6 +73,7 @@ import {
|
|
|
65
73
|
getLastAssistantTimestampBefore,
|
|
66
74
|
getMessages,
|
|
67
75
|
getMessagesPaginated,
|
|
76
|
+
hasMessages,
|
|
68
77
|
type MessageRow,
|
|
69
78
|
provenanceFromTrustContext,
|
|
70
79
|
setConversationOriginChannelIfUnset,
|
|
@@ -87,6 +96,7 @@ import { buildAssistantEvent } from "../assistant-event.js";
|
|
|
87
96
|
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../assistant-scope.js";
|
|
88
97
|
import type { AuthContext } from "../auth/types.js";
|
|
89
98
|
import { getChromeExtensionRegistry } from "../chrome-extension-registry.js";
|
|
99
|
+
import { getClientRegistry } from "../client-registry.js";
|
|
90
100
|
import { bridgeConfirmationRequestToGuardian } from "../confirmation-request-guardian-bridge.js";
|
|
91
101
|
import { routeGuardianReply } from "../guardian-reply-router.js";
|
|
92
102
|
import { healGuardianBindingDrift } from "../guardian-vellum-migration.js";
|
|
@@ -997,6 +1007,54 @@ function makeHubPublisher(
|
|
|
997
1007
|
},
|
|
998
1008
|
});
|
|
999
1009
|
|
|
1010
|
+
const inputRecord = msg.input as Record<string, unknown>;
|
|
1011
|
+
const commandPreview =
|
|
1012
|
+
redactSecrets(summarizeToolInput(msg.toolName, inputRecord)) ||
|
|
1013
|
+
undefined;
|
|
1014
|
+
const technicalTitle = commandPreview
|
|
1015
|
+
? `Requesting permission: ${commandPreview}`
|
|
1016
|
+
: `Requesting approval to use ${msg.toolName}.`;
|
|
1017
|
+
const dedupKey = `tool-approval:${msg.requestId}`;
|
|
1018
|
+
|
|
1019
|
+
// Emit immediately with the technical preview.
|
|
1020
|
+
void emitFeedEvent({
|
|
1021
|
+
source: "assistant",
|
|
1022
|
+
title: technicalTitle,
|
|
1023
|
+
summary: technicalTitle,
|
|
1024
|
+
dedupKey,
|
|
1025
|
+
urgency: msg.riskLevel === "high" ? "high" : "medium",
|
|
1026
|
+
conversationId,
|
|
1027
|
+
}).catch((err) => {
|
|
1028
|
+
log.warn(
|
|
1029
|
+
{ err, requestId: msg.requestId },
|
|
1030
|
+
"Failed to emit tool approval request feed event",
|
|
1031
|
+
);
|
|
1032
|
+
});
|
|
1033
|
+
|
|
1034
|
+
// Background: rewrite into prose and update the feed item.
|
|
1035
|
+
if (commandPreview) {
|
|
1036
|
+
void rewriteCommandPreview(msg.toolName, commandPreview)
|
|
1037
|
+
.then((prose) => {
|
|
1038
|
+
if (prose) {
|
|
1039
|
+
const proseTitle = `Requesting permission: ${prose}`;
|
|
1040
|
+
return emitFeedEvent({
|
|
1041
|
+
source: "assistant",
|
|
1042
|
+
title: proseTitle,
|
|
1043
|
+
summary: proseTitle,
|
|
1044
|
+
dedupKey,
|
|
1045
|
+
urgency: msg.riskLevel === "high" ? "high" : "medium",
|
|
1046
|
+
conversationId,
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
})
|
|
1050
|
+
.catch((err) => {
|
|
1051
|
+
log.warn(
|
|
1052
|
+
{ err, requestId: msg.requestId },
|
|
1053
|
+
"Failed to update feed event with prose rewrite",
|
|
1054
|
+
);
|
|
1055
|
+
});
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1000
1058
|
// Create a canonical guardian request so HTTP handlers can find it
|
|
1001
1059
|
// via applyCanonicalGuardianDecision.
|
|
1002
1060
|
try {
|
|
@@ -1066,7 +1124,20 @@ function makeHubPublisher(
|
|
|
1066
1124
|
typeof (msg as { conversationId?: unknown }).conversationId === "string"
|
|
1067
1125
|
? (msg as { conversationId: string }).conversationId
|
|
1068
1126
|
: undefined;
|
|
1069
|
-
|
|
1127
|
+
// `conversation_list_invalidated` is a list-level system event: it
|
|
1128
|
+
// describes no particular conversation and every connected client
|
|
1129
|
+
// should refresh its sidebar. Publish it unscoped so the SSE hub does
|
|
1130
|
+
// not filter it out by the subscriber's `filter.conversationId`.
|
|
1131
|
+
// Other events (including `conversation_title_updated`) stay scoped to
|
|
1132
|
+
// their conversation — unscoped scoped-events would leak foreign
|
|
1133
|
+
// `conversationId` values to native clients' speculative ID-resolution
|
|
1134
|
+
// path. For `conversation_title_updated` we instead enqueue a matching
|
|
1135
|
+
// unscoped `conversation_list_invalidated` below so other clients'
|
|
1136
|
+
// sidebars can refresh and pick up the new title.
|
|
1137
|
+
const resolvedConversationId =
|
|
1138
|
+
msg.type === "conversation_list_invalidated"
|
|
1139
|
+
? undefined
|
|
1140
|
+
: (msgConversationId ?? conversationId);
|
|
1070
1141
|
const event = buildAssistantEvent(
|
|
1071
1142
|
DAEMON_INTERNAL_ASSISTANT_ID,
|
|
1072
1143
|
msg,
|
|
@@ -1082,6 +1153,29 @@ function makeHubPublisher(
|
|
|
1082
1153
|
"assistant-events hub subscriber threw during POST /messages",
|
|
1083
1154
|
);
|
|
1084
1155
|
}
|
|
1156
|
+
|
|
1157
|
+
// When the agent loop auto-generates a conversation title, also
|
|
1158
|
+
// broadcast an unscoped `conversation_list_invalidated` so every
|
|
1159
|
+
// connected client's sidebar can refresh and pick up the new title.
|
|
1160
|
+
// Without this, clients viewing other conversations (or a draft)
|
|
1161
|
+
// would never learn that the title for this conversation changed.
|
|
1162
|
+
// The scoped `conversation_title_updated` above still handles the
|
|
1163
|
+
// in-place update for the client currently viewing this conversation.
|
|
1164
|
+
if (msg.type === "conversation_title_updated") {
|
|
1165
|
+
try {
|
|
1166
|
+
await deps.assistantEventHub.publish(
|
|
1167
|
+
buildAssistantEvent(DAEMON_INTERNAL_ASSISTANT_ID, {
|
|
1168
|
+
type: "conversation_list_invalidated",
|
|
1169
|
+
reason: "renamed",
|
|
1170
|
+
}),
|
|
1171
|
+
);
|
|
1172
|
+
} catch (err) {
|
|
1173
|
+
log.warn(
|
|
1174
|
+
{ err },
|
|
1175
|
+
"Failed to publish conversation_list_invalidated after title update",
|
|
1176
|
+
);
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1085
1179
|
})();
|
|
1086
1180
|
};
|
|
1087
1181
|
}
|
|
@@ -1234,7 +1328,7 @@ function resolveHostBrowserSender(
|
|
|
1234
1328
|
* failure. The route handler path must never reject because of a
|
|
1235
1329
|
* best-effort persistence step.
|
|
1236
1330
|
*/
|
|
1237
|
-
function persistOnboardingArtifacts(onboarding: {
|
|
1331
|
+
export function persistOnboardingArtifacts(onboarding: {
|
|
1238
1332
|
tools: string[];
|
|
1239
1333
|
tasks: string[];
|
|
1240
1334
|
tone: string;
|
|
@@ -1246,31 +1340,49 @@ function persistOnboardingArtifacts(onboarding: {
|
|
|
1246
1340
|
const assistantName = onboarding.assistantName?.trim();
|
|
1247
1341
|
if (assistantName) {
|
|
1248
1342
|
const identityPath = getWorkspacePromptPath("IDENTITY.md");
|
|
1249
|
-
|
|
1250
|
-
|
|
1343
|
+
try {
|
|
1344
|
+
if (existsSync(identityPath)) {
|
|
1345
|
+
const content = readFileSync(identityPath, "utf-8");
|
|
1346
|
+
const updated = content.replace(
|
|
1347
|
+
/^- (?:\*\*)?Name:(?:\*\*)?\s*.*$/m,
|
|
1348
|
+
() => `- **Name:** ${assistantName}`,
|
|
1349
|
+
);
|
|
1350
|
+
if (updated !== content) {
|
|
1351
|
+
writeFileSync(identityPath, updated, "utf-8");
|
|
1352
|
+
}
|
|
1353
|
+
} else {
|
|
1251
1354
|
writeFileSync(
|
|
1252
1355
|
identityPath,
|
|
1253
|
-
`# Identity\n\n- Name
|
|
1356
|
+
`# Identity\n\n- **Name:** ${assistantName}\n`,
|
|
1254
1357
|
"utf-8",
|
|
1255
1358
|
);
|
|
1256
|
-
} catch (err) {
|
|
1257
|
-
log.warn(
|
|
1258
|
-
{ err, identityPath },
|
|
1259
|
-
"Failed to seed IDENTITY.md from onboarding",
|
|
1260
|
-
);
|
|
1261
1359
|
}
|
|
1360
|
+
} catch (err) {
|
|
1361
|
+
log.warn(
|
|
1362
|
+
{ err, identityPath },
|
|
1363
|
+
"Failed to seed IDENTITY.md from onboarding",
|
|
1364
|
+
);
|
|
1262
1365
|
}
|
|
1263
1366
|
}
|
|
1264
1367
|
|
|
1265
1368
|
const userName = onboarding.userName?.trim();
|
|
1266
1369
|
if (userName) {
|
|
1267
1370
|
const userPath = getWorkspacePromptPath("USER.md");
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1371
|
+
try {
|
|
1372
|
+
if (existsSync(userPath)) {
|
|
1373
|
+
const content = readFileSync(userPath, "utf-8");
|
|
1374
|
+
const updated = content.replace(
|
|
1375
|
+
/^- (?:\*\*)?Name:(?:\*\*)?\s*.*$/m,
|
|
1376
|
+
() => `- **Name:** ${userName}`,
|
|
1377
|
+
);
|
|
1378
|
+
if (updated !== content) {
|
|
1379
|
+
writeFileSync(userPath, updated, "utf-8");
|
|
1380
|
+
}
|
|
1381
|
+
} else {
|
|
1382
|
+
writeFileSync(userPath, `# User\n\n- **Name:** ${userName}\n`, "utf-8");
|
|
1273
1383
|
}
|
|
1384
|
+
} catch (err) {
|
|
1385
|
+
log.warn({ err, userPath }, "Failed to seed USER.md from onboarding");
|
|
1274
1386
|
}
|
|
1275
1387
|
}
|
|
1276
1388
|
|
|
@@ -1302,6 +1414,8 @@ export async function handleSendMessage(
|
|
|
1302
1414
|
bypassSecretCheck?: boolean;
|
|
1303
1415
|
hostHomeDir?: string;
|
|
1304
1416
|
hostUsername?: string;
|
|
1417
|
+
clientId?: string;
|
|
1418
|
+
clientMessageId?: string;
|
|
1305
1419
|
onboarding?: {
|
|
1306
1420
|
tools: string[];
|
|
1307
1421
|
tasks: string[];
|
|
@@ -1312,6 +1426,8 @@ export async function handleSendMessage(
|
|
|
1312
1426
|
};
|
|
1313
1427
|
|
|
1314
1428
|
const { conversationKey, content, attachmentIds } = body;
|
|
1429
|
+
const clientMessageId =
|
|
1430
|
+
typeof body.clientMessageId === "string" ? body.clientMessageId : undefined;
|
|
1315
1431
|
if (!body.sourceChannel || typeof body.sourceChannel !== "string") {
|
|
1316
1432
|
return httpError("BAD_REQUEST", "sourceChannel is required", 400);
|
|
1317
1433
|
}
|
|
@@ -1414,19 +1530,27 @@ export async function handleSendMessage(
|
|
|
1414
1530
|
|
|
1415
1531
|
const smDeps = deps.sendMessageDeps;
|
|
1416
1532
|
|
|
1417
|
-
// Notify all connected clients that the conversation list changed when
|
|
1418
|
-
//
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
.
|
|
1428
|
-
|
|
1429
|
-
|
|
1533
|
+
// Notify all connected clients that the conversation list changed when
|
|
1534
|
+
// this is the first message in a standard conversation, so sidebars on
|
|
1535
|
+
// other devices can refresh. We check for first-message rather than
|
|
1536
|
+
// first-create because the SSE subscribe handler (events-routes.ts) may
|
|
1537
|
+
// have already materialised the conversation from a draft key before any
|
|
1538
|
+
// message was sent — in that case `mapping.created` is `false` even
|
|
1539
|
+
// though, from the user's perspective, this is a brand-new conversation
|
|
1540
|
+
// that other clients don't yet know about.
|
|
1541
|
+
if (mapping.conversationType === "standard") {
|
|
1542
|
+
if (!hasMessages(mapping.conversationId)) {
|
|
1543
|
+
smDeps.assistantEventHub
|
|
1544
|
+
.publish(
|
|
1545
|
+
buildAssistantEvent(DAEMON_INTERNAL_ASSISTANT_ID, {
|
|
1546
|
+
type: "conversation_list_invalidated",
|
|
1547
|
+
reason: "created",
|
|
1548
|
+
}),
|
|
1549
|
+
)
|
|
1550
|
+
.catch((err) => {
|
|
1551
|
+
log.warn({ err }, "Failed to publish conversation_list_invalidated");
|
|
1552
|
+
});
|
|
1553
|
+
}
|
|
1430
1554
|
}
|
|
1431
1555
|
|
|
1432
1556
|
// Build transport metadata from the request so the daemon can inject
|
|
@@ -1447,20 +1571,37 @@ export async function handleSendMessage(
|
|
|
1447
1571
|
interfaceId: sourceInterface,
|
|
1448
1572
|
} satisfies NonHostProxyTransportMetadata);
|
|
1449
1573
|
|
|
1574
|
+
// Register/refresh the client in the unified client registry so
|
|
1575
|
+
// `assistant clients list` can discover all connected interfaces.
|
|
1576
|
+
// Uses the client-supplied clientId when available (stable per-install
|
|
1577
|
+
// UUID), falling back to a synthetic key derived from interfaceId so
|
|
1578
|
+
// older clients that don't send clientId still appear in the registry.
|
|
1579
|
+
const effectiveClientId =
|
|
1580
|
+
typeof body.clientId === "string" && body.clientId.length > 0
|
|
1581
|
+
? body.clientId
|
|
1582
|
+
: `synthetic:${sourceInterface}`;
|
|
1583
|
+
getClientRegistry().register({
|
|
1584
|
+
clientId: effectiveClientId,
|
|
1585
|
+
interfaceId: sourceInterface,
|
|
1586
|
+
hostHomeDir: body.hostHomeDir,
|
|
1587
|
+
hostUsername: body.hostUsername,
|
|
1588
|
+
});
|
|
1589
|
+
|
|
1450
1590
|
const conversation = await smDeps.getOrCreateConversation(
|
|
1451
1591
|
mapping.conversationId,
|
|
1452
1592
|
{ transport },
|
|
1453
1593
|
);
|
|
1454
1594
|
|
|
1455
1595
|
// Store pre-chat onboarding context on the conversation when this is the
|
|
1456
|
-
// very first message (no prior messages loaded).
|
|
1457
|
-
//
|
|
1458
|
-
//
|
|
1459
|
-
//
|
|
1460
|
-
//
|
|
1461
|
-
|
|
1462
|
-
conversation.
|
|
1463
|
-
|
|
1596
|
+
// very first message (no prior messages loaded). Artifact persistence
|
|
1597
|
+
// (IDENTITY.md, USER.md, sidecar) is deferred: on the canned greeting
|
|
1598
|
+
// path it runs inside the setTimeout right before warmPromptCache() so
|
|
1599
|
+
// the warmed system prompt includes the identity; on the normal LLM
|
|
1600
|
+
// path it runs immediately before inference starts.
|
|
1601
|
+
const isFirstOnboarding =
|
|
1602
|
+
!!body.onboarding && conversation.messages.length === 0;
|
|
1603
|
+
if (isFirstOnboarding) {
|
|
1604
|
+
conversation.setOnboardingContext(body.onboarding!);
|
|
1464
1605
|
}
|
|
1465
1606
|
|
|
1466
1607
|
// Resolve guardian context from the AuthContext's actorPrincipalId.
|
|
@@ -1570,14 +1711,13 @@ export async function handleSendMessage(
|
|
|
1570
1711
|
conversation.hostBrowserSenderOverride = undefined;
|
|
1571
1712
|
}
|
|
1572
1713
|
|
|
1573
|
-
// Provision the host browser proxy.
|
|
1574
|
-
//
|
|
1575
|
-
//
|
|
1576
|
-
//
|
|
1577
|
-
//
|
|
1578
|
-
//
|
|
1579
|
-
//
|
|
1580
|
-
// provisioning and browser tools fall through to cdp-inspect/local.
|
|
1714
|
+
// Provision the host browser proxy. Both macOS and chrome-extension
|
|
1715
|
+
// natively support host_browser. For macOS, the proxy is wired to the
|
|
1716
|
+
// SSE sender by default so `host_browser_request` frames reach the
|
|
1717
|
+
// desktop client directly. When the guardian also has an active extension
|
|
1718
|
+
// connection (isRegistryRouted), the registry-routed sender is used
|
|
1719
|
+
// instead so browser tools route through the user's real Chrome session.
|
|
1720
|
+
// For chrome-extension, the registry sender is always used.
|
|
1581
1721
|
const shouldProvisionBrowserProxy =
|
|
1582
1722
|
supportsHostProxy(sourceInterface, "host_browser") ||
|
|
1583
1723
|
(canServiceRegistryBrowser(sourceInterface) && isRegistryRouted);
|
|
@@ -1640,9 +1780,10 @@ export async function handleSendMessage(
|
|
|
1640
1780
|
skipProxySenderUpdate: preservingProxies,
|
|
1641
1781
|
});
|
|
1642
1782
|
// Re-enable the browser proxy for turns that provisioned one. This covers:
|
|
1783
|
+
// - macOS: always provisioned (SSE sender or registry-routed when extension
|
|
1784
|
+
// is connected)
|
|
1643
1785
|
// - chrome-extension: natively supports host_browser (non-interactive but
|
|
1644
1786
|
// has a connected client for host_browser_request events)
|
|
1645
|
-
// - macOS with extension: provisioned above when isRegistryRouted is true
|
|
1646
1787
|
//
|
|
1647
1788
|
// The helper bypasses the `hasNoClient` gate so chrome-extension turns can
|
|
1648
1789
|
// drive the browser via CDP without leaking host_bash/host_file tool
|
|
@@ -1655,96 +1796,102 @@ export async function handleSendMessage(
|
|
|
1655
1796
|
|
|
1656
1797
|
// ── Canned first-greeting fast path ──
|
|
1657
1798
|
// On a completely fresh workspace, skip LLM inference for the macOS
|
|
1658
|
-
// wake-up greeting and return a pre-written response.
|
|
1659
|
-
//
|
|
1799
|
+
// wake-up greeting and return a pre-written response. When onboarding
|
|
1800
|
+
// context is present the greeting is personalized using the selections;
|
|
1801
|
+
// otherwise a generic greeting is served. Both paths are instant.
|
|
1660
1802
|
if (isWakeUpGreeting(trimmedContent, conversation.getMessages().length)) {
|
|
1661
|
-
const cannedGreeting = getCannedFirstGreeting();
|
|
1662
|
-
if (cannedGreeting) {
|
|
1663
|
-
conversation.processing = true;
|
|
1664
|
-
let cleanupDeferred = false;
|
|
1665
|
-
try {
|
|
1666
|
-
const provenance = provenanceFromTrustContext(
|
|
1667
|
-
conversation.trustContext,
|
|
1668
|
-
);
|
|
1669
|
-
const channelMeta = {
|
|
1670
|
-
...provenance,
|
|
1671
|
-
userMessageChannel: sourceChannel,
|
|
1672
|
-
assistantMessageChannel: sourceChannel,
|
|
1673
|
-
userMessageInterface: sourceInterface,
|
|
1674
|
-
assistantMessageInterface: sourceInterface,
|
|
1675
|
-
};
|
|
1676
|
-
|
|
1677
|
-
const rawContent = content ?? "";
|
|
1678
|
-
const attachments = hasAttachments
|
|
1679
|
-
? smDeps.resolveAttachments(attachmentIds)
|
|
1680
|
-
: [];
|
|
1681
|
-
const userMsg = createUserMessage(rawContent, attachments);
|
|
1682
|
-
const persisted = await addMessage(
|
|
1683
|
-
mapping.conversationId,
|
|
1684
|
-
"user",
|
|
1685
|
-
JSON.stringify(userMsg.content),
|
|
1686
|
-
channelMeta,
|
|
1687
|
-
);
|
|
1688
|
-
conversation.getMessages().push(userMsg);
|
|
1803
|
+
const cannedGreeting = getCannedFirstGreeting(body.onboarding ?? undefined);
|
|
1689
1804
|
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1805
|
+
conversation.processing = true;
|
|
1806
|
+
let cleanupDeferred = false;
|
|
1807
|
+
try {
|
|
1808
|
+
const provenance = provenanceFromTrustContext(conversation.trustContext);
|
|
1809
|
+
const channelMeta = {
|
|
1810
|
+
...provenance,
|
|
1811
|
+
userMessageChannel: sourceChannel,
|
|
1812
|
+
assistantMessageChannel: sourceChannel,
|
|
1813
|
+
userMessageInterface: sourceInterface,
|
|
1814
|
+
assistantMessageInterface: sourceInterface,
|
|
1815
|
+
};
|
|
1698
1816
|
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1817
|
+
const rawContent = content ?? "";
|
|
1818
|
+
const attachments = hasAttachments
|
|
1819
|
+
? smDeps.resolveAttachments(attachmentIds)
|
|
1820
|
+
: [];
|
|
1821
|
+
const userMsg = createUserMessage(rawContent, attachments);
|
|
1822
|
+
const persisted = await addMessage(
|
|
1823
|
+
mapping.conversationId,
|
|
1824
|
+
"user",
|
|
1825
|
+
JSON.stringify(userMsg.content),
|
|
1826
|
+
channelMeta,
|
|
1827
|
+
);
|
|
1828
|
+
conversation.getMessages().push(userMsg);
|
|
1707
1829
|
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1830
|
+
setConversationOriginChannelIfUnset(
|
|
1831
|
+
mapping.conversationId,
|
|
1832
|
+
sourceChannel,
|
|
1833
|
+
);
|
|
1834
|
+
setConversationOriginInterfaceIfUnset(
|
|
1835
|
+
mapping.conversationId,
|
|
1836
|
+
sourceInterface,
|
|
1837
|
+
);
|
|
1713
1838
|
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
onEvent({ type: "assistant_text_delta", text: cannedGreeting });
|
|
1725
|
-
onEvent({ type: "message_complete", conversationId });
|
|
1726
|
-
conversation.processing = false;
|
|
1727
|
-
silentlyWithLog(
|
|
1728
|
-
conversation.drainQueue(),
|
|
1729
|
-
"canned-greeting queue drain",
|
|
1730
|
-
);
|
|
1731
|
-
}, 0);
|
|
1839
|
+
const conversationId = mapping.conversationId;
|
|
1840
|
+
|
|
1841
|
+
const assistantMsg = createAssistantMessage(cannedGreeting);
|
|
1842
|
+
await addMessage(
|
|
1843
|
+
mapping.conversationId,
|
|
1844
|
+
"assistant",
|
|
1845
|
+
JSON.stringify(assistantMsg.content),
|
|
1846
|
+
channelMeta,
|
|
1847
|
+
);
|
|
1848
|
+
conversation.getMessages().push(assistantMsg);
|
|
1732
1849
|
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1850
|
+
const response = Response.json(
|
|
1851
|
+
{ accepted: true, messageId: persisted.id, conversationId },
|
|
1852
|
+
{ status: 202 },
|
|
1853
|
+
);
|
|
1854
|
+
|
|
1855
|
+
setTimeout(() => {
|
|
1856
|
+
onEvent({
|
|
1857
|
+
type: "user_message_echo",
|
|
1858
|
+
text: rawContent,
|
|
1859
|
+
conversationId,
|
|
1860
|
+
messageId: persisted.id,
|
|
1861
|
+
clientMessageId,
|
|
1862
|
+
});
|
|
1863
|
+
onEvent({ type: "assistant_text_delta", text: cannedGreeting });
|
|
1864
|
+
onEvent({ type: "message_complete", conversationId });
|
|
1865
|
+
conversation.processing = false;
|
|
1866
|
+
silentlyWithLog(
|
|
1867
|
+
conversation.drainQueue(),
|
|
1868
|
+
"canned-greeting queue drain",
|
|
1736
1869
|
);
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
if (!cleanupDeferred && conversation.processing) {
|
|
1741
|
-
conversation.processing = false;
|
|
1742
|
-
silentlyWithLog(conversation.drainQueue(), "error-path queue drain");
|
|
1870
|
+
|
|
1871
|
+
if (isFirstOnboarding) {
|
|
1872
|
+
persistOnboardingArtifacts(body.onboarding!);
|
|
1743
1873
|
}
|
|
1874
|
+
conversation.warmPromptCache();
|
|
1875
|
+
}, 0);
|
|
1876
|
+
|
|
1877
|
+
log.info(
|
|
1878
|
+
{ conversationId, personalized: !!body.onboarding },
|
|
1879
|
+
"Served canned first greeting — skipped LLM inference",
|
|
1880
|
+
);
|
|
1881
|
+
cleanupDeferred = true;
|
|
1882
|
+
return response;
|
|
1883
|
+
} finally {
|
|
1884
|
+
if (!cleanupDeferred && conversation.processing) {
|
|
1885
|
+
conversation.processing = false;
|
|
1886
|
+
silentlyWithLog(conversation.drainQueue(), "error-path queue drain");
|
|
1744
1887
|
}
|
|
1745
1888
|
}
|
|
1746
1889
|
}
|
|
1747
1890
|
|
|
1891
|
+
if (isFirstOnboarding) {
|
|
1892
|
+
persistOnboardingArtifacts(body.onboarding!);
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1748
1895
|
const attachments = hasAttachments
|
|
1749
1896
|
? smDeps.resolveAttachments(attachmentIds)
|
|
1750
1897
|
: [];
|
|
@@ -1817,6 +1964,7 @@ export async function handleSendMessage(
|
|
|
1817
1964
|
{ isInteractive },
|
|
1818
1965
|
undefined, // displayContent
|
|
1819
1966
|
transport,
|
|
1967
|
+
clientMessageId,
|
|
1820
1968
|
);
|
|
1821
1969
|
if (enqueueResult.rejected) {
|
|
1822
1970
|
return Response.json(
|
|
@@ -1929,9 +2077,9 @@ export async function handleSendMessage(
|
|
|
1929
2077
|
messageCount: conversation.getMessages().length,
|
|
1930
2078
|
inputTokens: conversation.usageStats.inputTokens,
|
|
1931
2079
|
outputTokens: conversation.usageStats.outputTokens,
|
|
1932
|
-
maxInputTokens: config.contextWindow.maxInputTokens,
|
|
1933
|
-
model: config.
|
|
1934
|
-
provider: config.
|
|
2080
|
+
maxInputTokens: config.llm.default.contextWindow.maxInputTokens,
|
|
2081
|
+
model: config.llm.default.model,
|
|
2082
|
+
provider: config.llm.default.provider,
|
|
1935
2083
|
estimatedCost: conversation.usageStats.estimatedCost,
|
|
1936
2084
|
userMessageInterface: sourceInterface,
|
|
1937
2085
|
};
|
|
@@ -2019,6 +2167,7 @@ export async function handleSendMessage(
|
|
|
2019
2167
|
text: rawContent,
|
|
2020
2168
|
conversationId,
|
|
2021
2169
|
messageId: persisted.id,
|
|
2170
|
+
clientMessageId,
|
|
2022
2171
|
});
|
|
2023
2172
|
if (modelInfoEvent) {
|
|
2024
2173
|
onEvent(modelInfoEvent);
|
|
@@ -2075,6 +2224,7 @@ export async function handleSendMessage(
|
|
|
2075
2224
|
text: rawContent,
|
|
2076
2225
|
conversationId,
|
|
2077
2226
|
messageId: persisted.id,
|
|
2227
|
+
clientMessageId,
|
|
2078
2228
|
});
|
|
2079
2229
|
conversation.emitActivityState(
|
|
2080
2230
|
"thinking",
|
|
@@ -2144,6 +2294,7 @@ export async function handleSendMessage(
|
|
|
2144
2294
|
conversationId: mapping.conversationId,
|
|
2145
2295
|
messageId,
|
|
2146
2296
|
requestId,
|
|
2297
|
+
clientMessageId,
|
|
2147
2298
|
});
|
|
2148
2299
|
|
|
2149
2300
|
// Fire-and-forget the agent loop; events flow to the hub via onEvent.
|
|
@@ -2165,28 +2316,71 @@ export async function handleSendMessage(
|
|
|
2165
2316
|
);
|
|
2166
2317
|
}
|
|
2167
2318
|
|
|
2319
|
+
function escapeXmlContent(text: string): string {
|
|
2320
|
+
return text
|
|
2321
|
+
.replace(/&/g, "&")
|
|
2322
|
+
.replace(/</g, "<")
|
|
2323
|
+
.replace(/>/g, ">");
|
|
2324
|
+
}
|
|
2325
|
+
|
|
2168
2326
|
async function generateLlmSuggestion(
|
|
2169
2327
|
provider: Provider,
|
|
2170
2328
|
assistantText: string,
|
|
2329
|
+
priorUserText: string | null,
|
|
2171
2330
|
): Promise<string | null> {
|
|
2172
2331
|
const log = (await import("../../util/logger.js")).getLogger("runtime-http");
|
|
2173
|
-
const
|
|
2174
|
-
assistantText.length > 2000 ? assistantText.slice(-2000) : assistantText
|
|
2332
|
+
const truncatedAssistant = escapeXmlContent(
|
|
2333
|
+
assistantText.length > 2000 ? assistantText.slice(-2000) : assistantText,
|
|
2334
|
+
);
|
|
2335
|
+
const truncatedUser =
|
|
2336
|
+
priorUserText && priorUserText.length > 500
|
|
2337
|
+
? escapeXmlContent(priorUserText.slice(-500))
|
|
2338
|
+
: priorUserText
|
|
2339
|
+
? escapeXmlContent(priorUserText)
|
|
2340
|
+
: priorUserText;
|
|
2175
2341
|
|
|
2176
|
-
const prompt = `Given this assistant message, write a very short tab-complete suggestion the user could send next. Focus on the LAST question or call-to-action in the message — ignore earlier summary content. Be casual, curious, or actionable — like a quick reply, not a formal request. Reply with ONLY the suggestion text.\n\nAssistant's message:\n${truncated}`;
|
|
2177
2342
|
const systemPrompt =
|
|
2178
|
-
"You
|
|
2179
|
-
|
|
2343
|
+
"You generate short, casual reply suggestions a user might type next in a chat. Match the tone and register of the preceding conversation. Output only the reply text inside the requested tags — no preamble, no commentary.";
|
|
2344
|
+
|
|
2345
|
+
const userPrompt =
|
|
2346
|
+
`Here is the end of a conversation:\n\n` +
|
|
2347
|
+
`<user_message>${truncatedUser ?? "(no prior user message)"}</user_message>\n` +
|
|
2348
|
+
`<assistant_message>${truncatedAssistant}</assistant_message>\n\n` +
|
|
2349
|
+
`Write the user's next reply, focusing on the LAST question or call-to-action in the assistant message. Keep it short (under 15 words), casual, and in the user's voice. Respond in this exact format:\n\n` +
|
|
2350
|
+
`<reply>YOUR_REPLY_HERE</reply>`;
|
|
2351
|
+
|
|
2352
|
+
// Single user message only — no assistant-role prefill. Anthropic
|
|
2353
|
+
// rejects assistant prefill whenever the request triggers extended
|
|
2354
|
+
// thinking (e.g. Opus 4.x at `effort: "xhigh"`), and the call-site
|
|
2355
|
+
// config is user-controlled, so we can't statically guarantee a
|
|
2356
|
+
// prefill-safe model. Keep `stop_sequences: ["</reply>"]` as an
|
|
2357
|
+
// early-termination hint; the parser below handles both tagged and
|
|
2358
|
+
// untagged responses so untagged "casual answer" replies still work.
|
|
2180
2359
|
const response = await provider.sendMessage(
|
|
2181
|
-
[{ role: "user", content: [{ type: "text", text:
|
|
2360
|
+
[{ role: "user", content: [{ type: "text", text: userPrompt }] }],
|
|
2182
2361
|
[], // no tools
|
|
2183
2362
|
systemPrompt,
|
|
2184
|
-
{
|
|
2363
|
+
{
|
|
2364
|
+
config: {
|
|
2365
|
+
callSite: "conversationStarters",
|
|
2366
|
+
max_tokens: 60,
|
|
2367
|
+
stop_sequences: ["</reply>"],
|
|
2368
|
+
temperature: 0.7,
|
|
2369
|
+
},
|
|
2370
|
+
},
|
|
2185
2371
|
);
|
|
2186
2372
|
|
|
2187
2373
|
const textBlock = response.content.find((b) => b.type === "text");
|
|
2188
|
-
const raw = textBlock && "text" in textBlock ? textBlock.text
|
|
2189
|
-
|
|
2374
|
+
const raw = textBlock && "text" in textBlock ? textBlock.text : "";
|
|
2375
|
+
// Prefer the content inside <reply>…</reply> when the model honors the
|
|
2376
|
+
// tag format. If the response has no tags, fall back to the raw text —
|
|
2377
|
+
// a plain "Sure, tomorrow works" without tags is still a valid chip.
|
|
2378
|
+
const tagMatch = raw.match(/<reply>([\s\S]*?)(?:<\/reply>|$)/i);
|
|
2379
|
+
const extracted = tagMatch ? tagMatch[1] : raw;
|
|
2380
|
+
const stripped = extracted
|
|
2381
|
+
.replace(/<\/?reply>/gi, "")
|
|
2382
|
+
.replace(/^["'`]+|["'`]+$/g, "")
|
|
2383
|
+
.trim();
|
|
2190
2384
|
|
|
2191
2385
|
if (!stripped) {
|
|
2192
2386
|
log.debug("Suggestion rejected: empty LLM response");
|
|
@@ -2299,14 +2493,33 @@ export async function handleGetSuggestion(
|
|
|
2299
2493
|
});
|
|
2300
2494
|
}
|
|
2301
2495
|
|
|
2496
|
+
// Find the most recent user message preceding this assistant turn so the
|
|
2497
|
+
// suggestion model can see both sides of the conversation and doesn't have
|
|
2498
|
+
// to guess which role it's generating for.
|
|
2499
|
+
let priorUserText: string | null = null;
|
|
2500
|
+
for (let j = i - 1; j >= 0; j--) {
|
|
2501
|
+
if (rawMessages[j].role !== "user") continue;
|
|
2502
|
+
let userContent: unknown;
|
|
2503
|
+
try {
|
|
2504
|
+
userContent = JSON.parse(rawMessages[j].content);
|
|
2505
|
+
} catch {
|
|
2506
|
+
userContent = rawMessages[j].content;
|
|
2507
|
+
}
|
|
2508
|
+
const userText = renderHistoryContent(userContent).text.trim();
|
|
2509
|
+
if (userText) {
|
|
2510
|
+
priorUserText = userText;
|
|
2511
|
+
break;
|
|
2512
|
+
}
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2302
2515
|
// Try LLM suggestion using the configured provider
|
|
2303
|
-
const provider = await getConfiguredProvider();
|
|
2516
|
+
const provider = await getConfiguredProvider("conversationStarters");
|
|
2304
2517
|
if (provider) {
|
|
2305
2518
|
try {
|
|
2306
2519
|
// Deduplicate concurrent requests
|
|
2307
2520
|
let promise = suggestionInFlight.get(msg.id);
|
|
2308
2521
|
if (!promise) {
|
|
2309
|
-
promise = generateLlmSuggestion(provider, text);
|
|
2522
|
+
promise = generateLlmSuggestion(provider, text, priorUserText);
|
|
2310
2523
|
suggestionInFlight.set(msg.id, promise);
|
|
2311
2524
|
}
|
|
2312
2525
|
|