@vellumai/assistant 0.6.2 → 0.6.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 +273 -10
- package/Dockerfile +2 -3
- package/bun.lock +41 -49
- package/bunfig.toml +3 -0
- package/docs/architecture/memory.md +1 -1
- package/docs/backup-troubleshooting.md +52 -0
- package/docs/browser-use-architecture-phase2.md +174 -0
- package/docs/stt-provider-onboarding.md +120 -0
- package/knip.json +12 -2
- package/node_modules/@vellumai/ces-contracts/bun.lock +8 -6
- package/node_modules/@vellumai/ces-contracts/package.json +3 -3
- package/node_modules/@vellumai/ces-contracts/src/rpc.ts +42 -0
- package/openapi.yaml +1111 -86
- package/package.json +40 -42
- package/scripts/generate-openapi.ts +0 -2
- package/scripts/test.sh +73 -18
- package/src/__tests__/acp-session.test.ts +43 -0
- package/src/__tests__/agent-image-optimize.test.ts +28 -0
- package/src/__tests__/agent-loop.test.ts +123 -0
- package/src/__tests__/anthropic-provider.test.ts +263 -10
- package/src/__tests__/app-builder-tool-scripts.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +1 -0
- package/src/__tests__/app-source-watcher.test.ts +37 -11
- package/src/__tests__/approval-routes-http.test.ts +178 -1
- package/src/__tests__/auto-analysis-end-to-end.test.ts +550 -0
- package/src/__tests__/auto-analysis-prompt.test.ts +50 -0
- package/src/__tests__/browser-fill-credential.test.ts +240 -94
- package/src/__tests__/browser-manager.test.ts +40 -27
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
- package/src/__tests__/browser-skill-endstate.test.ts +31 -7
- package/src/__tests__/btw-routes.test.ts +7 -0
- package/src/__tests__/call-controller.test.ts +581 -20
- package/src/__tests__/catalog-files.test.ts +1000 -0
- package/src/__tests__/channel-approvals.test.ts +53 -0
- package/src/__tests__/channel-invite-transport.test.ts +2 -2
- package/src/__tests__/channel-readiness-routes.test.ts +16 -20
- package/src/__tests__/channel-readiness-service.test.ts +12 -7
- package/src/__tests__/checker.test.ts +157 -10
- package/src/__tests__/clawhub-files.test.ts +347 -0
- package/src/__tests__/commit-message-enrichment-service.test.ts +36 -19
- package/src/__tests__/config-analysis.test.ts +100 -0
- package/src/__tests__/config-managed-gemini-defaults.test.ts +326 -0
- package/src/__tests__/config-schema-cmd.test.ts +2 -2
- package/src/__tests__/config-schema.test.ts +1248 -224
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +339 -0
- package/src/__tests__/config-watcher.test.ts +43 -8
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +23 -0
- package/src/__tests__/contact-store-user-file.test.ts +512 -0
- package/src/__tests__/contacts-write.test.ts +197 -0
- package/src/__tests__/context-overflow-approval.test.ts +16 -1
- package/src/__tests__/context-window-manager.test.ts +88 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop.test.ts +99 -3
- package/src/__tests__/conversation-analysis-routes.test.ts +2 -2
- package/src/__tests__/conversation-attachments.test.ts +80 -4
- package/src/__tests__/conversation-confirmation-signals.test.ts +290 -0
- package/src/__tests__/conversation-error.test.ts +70 -0
- package/src/__tests__/conversation-fork-crud.test.ts +17 -0
- package/src/__tests__/conversation-history-web-search.test.ts +12 -4
- package/src/__tests__/conversation-host-access-routes.test.ts +229 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +6 -1
- package/src/__tests__/conversation-inject-context.test.ts +103 -0
- package/src/__tests__/conversation-launcher-skill-regression.test.ts +51 -0
- package/src/__tests__/conversation-list-source.test.ts +145 -0
- package/src/__tests__/conversation-pre-run-repair.test.ts +2 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -0
- package/src/__tests__/conversation-queue.test.ts +946 -62
- package/src/__tests__/conversation-routes-disk-view.test.ts +275 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +16 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +324 -46
- package/src/__tests__/conversation-skill-tools.test.ts +7 -4
- package/src/__tests__/conversation-slash-commands.test.ts +33 -0
- package/src/__tests__/conversation-slash-queue.test.ts +89 -18
- package/src/__tests__/conversation-slash-unknown.test.ts +2 -0
- package/src/__tests__/conversation-starter-routes.test.ts +126 -0
- package/src/__tests__/conversation-starters-cadence.test.ts +161 -0
- package/src/__tests__/conversation-store.test.ts +195 -0
- package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +226 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +193 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +2 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +2 -0
- package/src/__tests__/credential-execution-approval-bridge.test.ts +32 -1
- package/src/__tests__/credential-health-service.test.ts +352 -0
- package/src/__tests__/credential-security-invariants.test.ts +6 -3
- package/src/__tests__/credential-vault-unit.test.ts +383 -7
- package/src/__tests__/credential-vault.test.ts +152 -13
- package/src/__tests__/credentials-cli.test.ts +42 -18
- package/src/__tests__/cross-provider-web-search.test.ts +146 -35
- package/src/__tests__/date-context.test.ts +4 -4
- package/src/__tests__/deterministic-verification-control-plane.test.ts +10 -1
- package/src/__tests__/device-id.test.ts +112 -0
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +167 -4
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +1 -3
- package/src/__tests__/email-html-renderer.test.ts +71 -0
- package/src/__tests__/email-invite-adapter.test.ts +36 -32
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +256 -0
- package/src/__tests__/emit-event-signal.test.ts +71 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +222 -0
- package/src/__tests__/fixtures/mock-chrome-extension.ts +386 -0
- package/src/__tests__/gateway-only-enforcement.test.ts +206 -1
- package/src/__tests__/gateway-only-guard.test.ts +2 -0
- package/src/__tests__/gemini-provider.test.ts +66 -2
- package/src/__tests__/get-skill-detail-audit.test.ts +325 -0
- package/src/__tests__/gmail-archive-fallback.test.ts +193 -0
- package/src/__tests__/gmail-archive-gate.test.ts +246 -0
- package/src/__tests__/gmail-preferences.test.ts +117 -0
- package/src/__tests__/guardian-routing-invariants.test.ts +70 -2
- package/src/__tests__/headless-browser-interactions.test.ts +738 -359
- package/src/__tests__/headless-browser-mode.test.ts +614 -0
- package/src/__tests__/headless-browser-navigate.test.ts +528 -49
- package/src/__tests__/headless-browser-read-tools.test.ts +274 -100
- package/src/__tests__/headless-browser-snapshot.test.ts +250 -77
- package/src/__tests__/heartbeat-service.test.ts +70 -17
- package/src/__tests__/home-state-routes.test.ts +162 -0
- package/src/__tests__/host-bash-proxy.test.ts +145 -1
- package/src/__tests__/host-browser-e2e-cloud.test.ts +596 -0
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +286 -0
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +374 -0
- package/src/__tests__/host-browser-event-routes.test.ts +350 -0
- package/src/__tests__/host-browser-proxy.test.ts +444 -0
- package/src/__tests__/host-browser-routes.test.ts +198 -0
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +423 -0
- package/src/__tests__/host-cu-proxy.test.ts +166 -1
- package/src/__tests__/host-file-proxy.test.ts +185 -1
- package/src/__tests__/host-file-read-tool.test.ts +52 -0
- package/src/__tests__/host-proxy-interface.test.ts +165 -0
- package/src/__tests__/host-shell-tool.test.ts +1 -11
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- package/src/__tests__/identity-intro-cache.test.ts +40 -10
- package/src/__tests__/init-feature-flag-overrides.test.ts +38 -112
- package/src/__tests__/integration-status.test.ts +6 -7
- package/src/__tests__/jobs-store-upsert-debounced.test.ts +141 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +37 -12
- package/src/__tests__/llm-context-normalization.test.ts +488 -0
- package/src/__tests__/llm-context-route-provider.test.ts +86 -5
- package/src/__tests__/llm-usage-store.test.ts +363 -0
- package/src/__tests__/mcp-client-auth.test.ts +40 -4
- package/src/__tests__/mcp-health-check.test.ts +10 -3
- package/src/__tests__/media-stream-output.test.ts +555 -0
- package/src/__tests__/media-stream-parser.test.ts +374 -0
- package/src/__tests__/media-stream-server-integration.test.ts +1234 -0
- package/src/__tests__/media-stream-stt-session.test.ts +588 -0
- package/src/__tests__/media-turn-detector.test.ts +440 -0
- package/src/__tests__/message-queue.test.ts +125 -0
- package/src/__tests__/migration-cross-version-compatibility.test.ts +3 -1
- package/src/__tests__/migration-export-http.test.ts +67 -8
- package/src/__tests__/migration-export-streaming.test.ts +66 -0
- package/src/__tests__/migration-import-commit-http.test.ts +109 -7
- package/src/__tests__/migration-import-preflight-http.test.ts +6 -5
- package/src/__tests__/migration-validate-http.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +151 -0
- package/src/__tests__/model-intents.test.ts +2 -2
- package/src/__tests__/native-host-marker-sync-guard.test.ts +157 -0
- package/src/__tests__/oauth-apps-routes.test.ts +18 -12
- package/src/__tests__/oauth-cli.test.ts +709 -60
- package/src/__tests__/oauth-connect-orchestrator.test.ts +118 -24
- package/src/__tests__/oauth-provider-seed-logos.test.ts +23 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +147 -10
- package/src/__tests__/oauth-provider-visibility.test.ts +19 -21
- package/src/__tests__/oauth-providers-routes.test.ts +52 -14
- package/src/__tests__/oauth-store.test.ts +1465 -176
- package/src/__tests__/oauth2-gateway-transport.test.ts +460 -26
- package/src/__tests__/onboarding-template-contract.test.ts +81 -70
- package/src/__tests__/openai-provider.test.ts +178 -2
- package/src/__tests__/openai-responses-cutover-guard.test.ts +184 -0
- package/src/__tests__/openai-responses-provider.test.ts +1105 -0
- package/src/__tests__/openrouter-token-estimation.test.ts +100 -0
- package/src/__tests__/outlook-categories.test.ts +1 -1
- package/src/__tests__/outlook-client-automation.test.ts +1 -1
- package/src/__tests__/outlook-compose-tools.test.ts +1 -1
- package/src/__tests__/outlook-email-watcher.test.ts +1 -1
- package/src/__tests__/outlook-follow-up.test.ts +1 -1
- package/src/__tests__/outlook-messaging-provider.test.ts +2 -2
- package/src/__tests__/outlook-trash.test.ts +1 -1
- package/src/__tests__/outlook-unsubscribe.test.ts +32 -3
- package/src/__tests__/permission-checker-host-gate.test.ts +74 -14
- package/src/__tests__/permission-mode.test.ts +28 -56
- package/src/__tests__/persona-resolver.test.ts +251 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +4 -0
- package/src/__tests__/platform-callback-registration.test.ts +19 -0
- package/src/__tests__/platform.test.ts +92 -1
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +343 -0
- package/src/__tests__/prechat-onboarding-contract.test.ts +267 -0
- package/src/__tests__/pricing.test.ts +174 -0
- package/src/__tests__/proxy-approval-callback.test.ts +18 -0
- package/src/__tests__/qdrant-manager.test.ts +29 -8
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +194 -0
- package/src/__tests__/relationship-state-contract.test.ts +175 -0
- package/src/__tests__/relay-server.test.ts +423 -5
- package/src/__tests__/require-fresh-approval.test.ts +40 -1
- package/src/__tests__/sanitize-config-for-transfer.test.ts +132 -0
- package/src/__tests__/schedule-routes.test.ts +162 -0
- package/src/__tests__/search-skills-unified.test.ts +118 -0
- package/src/__tests__/secret-detection-handler.test.ts +84 -0
- package/src/__tests__/secret-ingress-http.test.ts +1 -0
- package/src/__tests__/secret-scanner-executor.test.ts +4 -0
- package/src/__tests__/secure-keys.test.ts +107 -0
- package/src/__tests__/send-endpoint-busy.test.ts +8 -1
- package/src/__tests__/sequence-store.test.ts +1 -1
- package/src/__tests__/server-history-render.test.ts +49 -0
- package/src/__tests__/set-permission-mode.test.ts +13 -250
- package/src/__tests__/settings-routes.test.ts +201 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skills-file-content-endpoint.test.ts +801 -0
- package/src/__tests__/skills-files-catalog-fallback.test.ts +738 -0
- package/src/__tests__/skills.test.ts +5 -2
- package/src/__tests__/skillssh-files.test.ts +446 -0
- package/src/__tests__/slack-block-formatting.test.ts +110 -0
- package/src/__tests__/slack-channel-config.test.ts +576 -16
- package/src/__tests__/stt-catalog-parity.test.ts +282 -0
- package/src/__tests__/stt-stream-session.test.ts +535 -0
- package/src/__tests__/subagent-detail.test.ts +44 -2
- package/src/__tests__/subagent-disposal.test.ts +1 -0
- package/src/__tests__/subagent-fork-notifications.test.ts +291 -0
- package/src/__tests__/subagent-fork-spawn.test.ts +384 -0
- package/src/__tests__/subagent-manager-notify.test.ts +1 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -0
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +411 -0
- package/src/__tests__/subagent-tools.test.ts +1 -0
- package/src/__tests__/subagent-types.test.ts +1 -0
- package/src/__tests__/system-prompt-ask-mode.test.ts +27 -71
- package/src/__tests__/system-prompt.test.ts +184 -27
- package/src/__tests__/task-scheduler.test.ts +32 -6
- package/src/__tests__/telegram-config.test.ts +10 -13
- package/src/__tests__/telephony-stt-routing.test.ts +329 -0
- package/src/__tests__/terminal-tools.test.ts +25 -5
- package/src/__tests__/test-preload.ts +18 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +4 -1
- package/src/__tests__/tool-approval-handler.test.ts +73 -0
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +9 -5
- package/src/__tests__/tool-executor-shell-integration.test.ts +4 -0
- package/src/__tests__/tool-executor.test.ts +33 -24
- package/src/__tests__/tool-result-truncation.test.ts +36 -0
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +22 -0
- package/src/__tests__/top-level-renderer.test.ts +73 -1
- package/src/__tests__/transport-hints-queue.test.ts +14 -29
- package/src/__tests__/trust-store.test.ts +7 -1
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +109 -0
- package/src/__tests__/tts-catalog-parity.test.ts +345 -0
- package/src/__tests__/twilio-routes-twiml.test.ts +512 -114
- package/src/__tests__/twilio-routes.test.ts +376 -0
- package/src/__tests__/unicode.test.ts +293 -0
- package/src/__tests__/update-bulletin-format.test.ts +59 -0
- package/src/__tests__/update-bulletin.test.ts +206 -5
- package/src/__tests__/usage-routes.test.ts +25 -4
- package/src/__tests__/user-reference.test.ts +46 -61
- package/src/__tests__/v2-consent-policy.test.ts +103 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +4 -0
- package/src/__tests__/voice-config-update.test.ts +403 -0
- package/src/__tests__/voice-quality.test.ts +434 -19
- package/src/__tests__/workspace-heartbeat-service.test.ts +7 -0
- package/src/__tests__/workspace-migration-033-stt-service-explicit-config.test.ts +547 -0
- package/src/__tests__/workspace-migration-034-remove-calls-voice-transcription-provider.test.ts +596 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +368 -0
- package/src/__tests__/workspace-migration-meets.test.ts +244 -0
- package/src/__tests__/workspace-migration-seed-device-id.test.ts +14 -20
- package/src/__tests__/workspace-policy.test.ts +2 -0
- package/src/acp/client-handler.ts +30 -4
- package/src/agent/image-optimize.ts +24 -12
- package/src/agent/loop.ts +55 -9
- package/src/approvals/guardian-request-resolvers.ts +21 -15
- package/src/backup/__tests__/backup-key.test.ts +152 -0
- package/src/backup/__tests__/backup-worker.test.ts +767 -0
- package/src/backup/__tests__/list-snapshots.test.ts +87 -0
- package/src/backup/__tests__/local-writer.test.ts +218 -0
- package/src/backup/__tests__/offsite-writer.test.ts +641 -0
- package/src/backup/__tests__/paths.test.ts +300 -0
- package/src/backup/__tests__/restore.test.ts +498 -0
- package/src/backup/__tests__/snapshot-lock.test.ts +352 -0
- package/src/backup/__tests__/stream-crypt.test.ts +228 -0
- package/src/backup/backup-key.ts +137 -0
- package/src/backup/backup-worker.ts +459 -0
- package/src/backup/list-snapshots.ts +147 -0
- package/src/backup/local-writer.ts +133 -0
- package/src/backup/offsite-writer.ts +222 -0
- package/src/backup/paths.ts +226 -0
- package/src/backup/restore.ts +322 -0
- package/src/backup/snapshot-lock.ts +431 -0
- package/src/backup/stream-crypt.ts +263 -0
- package/src/browser-session/__tests__/manager.test.ts +297 -0
- package/src/browser-session/backends/cdp-inspect.ts +30 -0
- package/src/browser-session/backends/extension.ts +26 -0
- package/src/browser-session/backends/local.ts +24 -0
- package/src/browser-session/events.ts +164 -0
- package/src/browser-session/index.ts +27 -0
- package/src/browser-session/manager.ts +159 -0
- package/src/browser-session/types.ts +28 -0
- package/src/bundler/package-resolver.ts +4 -0
- package/src/calls/audio-store.ts +11 -5
- package/src/calls/call-controller.ts +226 -71
- package/src/calls/call-domain.ts +9 -0
- package/src/calls/call-speech-output.ts +190 -0
- package/src/calls/call-transport.ts +77 -0
- package/src/calls/media-stream-audio-transcode.ts +173 -0
- package/src/calls/media-stream-output.ts +660 -0
- package/src/calls/media-stream-parser.ts +300 -0
- package/src/calls/media-stream-protocol.ts +166 -0
- package/src/calls/media-stream-server.ts +592 -0
- package/src/calls/media-stream-stt-session.ts +460 -0
- package/src/calls/media-turn-detector.ts +230 -0
- package/src/calls/relay-server.ts +90 -75
- package/src/calls/resolve-call-tts-provider.ts +136 -0
- package/src/calls/telephony-stt-routing.ts +145 -0
- package/src/calls/tts-call-strategy.ts +161 -0
- package/src/calls/tts-text-sanitizer.ts +32 -16
- package/src/calls/twilio-routes.ts +281 -17
- package/src/calls/voice-quality.ts +78 -35
- package/src/calls/voice-session-bridge.ts +8 -1
- package/src/channels/__tests__/types.test.ts +134 -0
- package/src/channels/types.ts +69 -3
- package/src/cli/__tests__/run-assistant-command.ts +11 -1
- package/src/cli/commands/__tests__/backup.test.ts +1165 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +234 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +132 -0
- package/src/cli/commands/__tests__/email-attachment.test.ts +422 -0
- package/src/cli/commands/__tests__/email-download.test.ts +16 -1
- package/src/cli/commands/__tests__/email-list.test.ts +22 -4
- package/src/cli/commands/__tests__/email-register.test.ts +4 -4
- package/src/cli/commands/__tests__/email-send.test.ts +37 -4
- package/src/cli/commands/__tests__/email-status.test.ts +5 -1
- package/src/cli/commands/__tests__/email-unregister.test.ts +34 -5
- package/src/cli/commands/backup.ts +993 -0
- package/src/cli/commands/conversations.ts +77 -0
- package/src/cli/commands/credentials.ts +3 -4
- package/src/cli/commands/domain.ts +210 -0
- package/src/cli/commands/email.ts +273 -16
- package/src/cli/commands/mcp.ts +16 -4
- package/src/cli/commands/oauth/__tests__/connect.test.ts +56 -44
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +21 -21
- package/src/cli/commands/oauth/__tests__/mode.test.ts +17 -17
- package/src/cli/commands/oauth/__tests__/ping.test.ts +16 -16
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +32 -33
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +330 -0
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +117 -12
- package/src/cli/commands/oauth/__tests__/status.test.ts +10 -10
- package/src/cli/commands/oauth/__tests__/token.test.ts +7 -7
- package/src/cli/commands/oauth/apps.ts +7 -4
- package/src/cli/commands/oauth/connect.ts +6 -3
- package/src/cli/commands/oauth/disconnect.ts +1 -1
- package/src/cli/commands/oauth/mode.ts +12 -3
- package/src/cli/commands/oauth/providers.ts +215 -36
- package/src/cli/commands/oauth/shared.ts +7 -6
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +254 -0
- package/src/cli/commands/platform/__tests__/connect.test.ts +6 -0
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +6 -0
- package/src/cli/commands/platform/index.ts +107 -10
- package/src/cli/commands/usage.ts +10 -9
- package/src/cli/lib/daemon-credential-client.ts +4 -0
- package/src/cli/program.ts +30 -4
- package/src/config/__tests__/backup-schema.test.ts +134 -0
- package/src/config/assistant-feature-flags.ts +61 -62
- package/src/config/bundled-skills/app-builder/SKILL.md +26 -249
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +141 -0
- package/src/config/bundled-skills/app-builder/references/INTERACTION_HOOKS.md +56 -0
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +125 -0
- package/src/config/bundled-skills/browser/SKILL.md +30 -5
- package/src/config/bundled-skills/browser/TOOLS.json +123 -0
- package/src/config/bundled-skills/browser/tools/browser-attach.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-detach.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-status.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +17 -0
- package/src/config/bundled-skills/contacts/SKILL.md +5 -2
- package/src/config/bundled-skills/document/SKILL.md +4 -0
- package/src/config/bundled-skills/gmail/SKILL.md +54 -8
- package/src/config/bundled-skills/gmail/TOOLS.json +33 -3
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +116 -9
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +138 -11
- package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +59 -0
- package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +82 -0
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +113 -17
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +2 -2
- package/src/config/bundled-skills/media-processing/SKILL.md +3 -9
- package/src/config/bundled-skills/media-processing/TOOLS.json +1 -6
- package/src/config/bundled-skills/media-processing/__tests__/audio-transcribe.test.ts +125 -0
- package/src/config/bundled-skills/media-processing/__tests__/extract-keyframes.test.ts +181 -0
- package/src/config/bundled-skills/media-processing/__tests__/preprocess-audio.test.ts +141 -0
- package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +32 -87
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +8 -4
- package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +0 -10
- package/src/config/bundled-skills/messaging/SKILL.md +3 -3
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +2 -2
- package/src/config/bundled-skills/outlook/SKILL.md +9 -2
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +2 -2
- package/src/config/bundled-skills/phone-calls/SKILL.md +2 -2
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +27 -18
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +3 -3
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +26 -22
- package/src/config/bundled-skills/slack/SKILL.md +1 -0
- package/src/config/bundled-skills/subagent/SKILL.md +21 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +8 -4
- package/src/config/bundled-skills/tasks/SKILL.md +5 -0
- package/src/config/bundled-skills/transcribe/SKILL.md +9 -14
- package/src/config/bundled-skills/transcribe/TOOLS.json +2 -7
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +256 -0
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +38 -188
- package/src/config/bundled-tool-registry.ts +8 -0
- package/src/config/env-registry.ts +38 -0
- package/src/config/env.ts +49 -4
- package/src/config/feature-flag-registry.json +85 -14
- package/src/config/loader.ts +82 -13
- package/src/config/sanitize-for-transfer.ts +47 -0
- package/src/config/schema.ts +81 -15
- package/src/config/schemas/__tests__/stt.test.ts +43 -0
- package/src/config/schemas/analysis.ts +51 -0
- package/src/config/schemas/backup.ts +72 -0
- package/src/config/schemas/calls.ts +1 -26
- package/src/config/schemas/elevenlabs.ts +0 -59
- package/src/config/schemas/filing.ts +47 -7
- package/src/config/schemas/heartbeat.ts +27 -5
- package/src/config/schemas/host-browser.ts +112 -0
- package/src/config/schemas/inference.ts +1 -1
- package/src/config/schemas/memory-lifecycle.ts +14 -2
- package/src/config/schemas/memory-retrieval.ts +103 -0
- package/src/config/schemas/security.ts +0 -6
- package/src/config/schemas/services.ts +52 -0
- package/src/config/schemas/stt.ts +59 -0
- package/src/config/schemas/tts.ts +230 -0
- package/src/config/schemas/updates.ts +14 -0
- package/src/config/skills.ts +4 -0
- package/src/config/types.ts +4 -1
- package/src/contacts/contact-store.ts +56 -11
- package/src/contacts/contacts-write.ts +38 -1
- package/src/context/post-turn-tool-result-truncation.ts +177 -0
- package/src/context/tool-result-truncation.ts +2 -1
- package/src/context/window-manager.ts +61 -10
- package/src/credential-execution/approval-bridge.ts +49 -15
- package/src/credential-execution/executable-discovery.ts +12 -2
- package/src/credential-execution/process-manager.ts +33 -2
- package/src/credential-health/credential-health-service.ts +366 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +324 -0
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +497 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +195 -0
- package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +127 -0
- package/src/daemon/app-source-watcher.ts +35 -0
- package/src/daemon/config-watcher.ts +99 -5
- package/src/daemon/context-overflow-approval.ts +5 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +23 -2
- package/src/daemon/conversation-agent-loop.ts +153 -42
- package/src/daemon/conversation-attachments.ts +40 -0
- package/src/daemon/conversation-error.ts +11 -0
- package/src/daemon/conversation-history.ts +40 -6
- package/src/daemon/conversation-launch.ts +220 -0
- package/src/daemon/conversation-lifecycle.ts +59 -9
- package/src/daemon/conversation-messaging.ts +37 -3
- package/src/daemon/conversation-notifiers.ts +5 -0
- package/src/daemon/conversation-process.ts +622 -13
- package/src/daemon/conversation-queue-manager.ts +24 -0
- package/src/daemon/conversation-runtime-assembly.ts +128 -36
- package/src/daemon/conversation-slash.ts +36 -0
- package/src/daemon/conversation-surfaces.ts +131 -40
- package/src/daemon/conversation-tool-setup.ts +99 -8
- package/src/daemon/conversation-usage.ts +7 -4
- package/src/daemon/conversation-workspace.ts +12 -0
- package/src/daemon/conversation.ts +292 -16
- package/src/daemon/date-context.ts +10 -10
- package/src/daemon/first-greeting.ts +3 -2
- package/src/daemon/handlers/config-slack-channel.ts +269 -94
- package/src/daemon/handlers/conversations.ts +13 -141
- package/src/daemon/handlers/shared.ts +80 -0
- package/src/daemon/handlers/skills.ts +483 -44
- package/src/daemon/host-bash-proxy.ts +48 -13
- package/src/daemon/host-browser-proxy.ts +192 -0
- package/src/daemon/host-cu-proxy.ts +36 -11
- package/src/daemon/host-file-proxy.ts +57 -9
- package/src/daemon/lifecycle.ts +179 -28
- package/src/daemon/message-protocol.ts +13 -0
- package/src/daemon/message-types/conversations.ts +89 -14
- package/src/daemon/message-types/home.ts +40 -0
- package/src/daemon/message-types/host-browser.ts +100 -0
- package/src/daemon/message-types/meet.ts +143 -0
- package/src/daemon/message-types/messages.ts +19 -5
- package/src/daemon/message-types/schedules.ts +34 -2
- package/src/daemon/message-types/skills.ts +26 -0
- package/src/daemon/message-types/subagents.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/server.ts +439 -14
- package/src/daemon/shutdown-handlers.ts +32 -4
- package/src/daemon/shutdown-registry.ts +40 -0
- package/src/daemon/tool-side-effects.ts +15 -0
- package/src/daemon/transport-hints.ts +5 -24
- package/src/email/html-renderer.ts +76 -0
- package/src/heartbeat/heartbeat-service.ts +93 -7
- package/src/home/__tests__/assistant-feed-authoring.test.ts +156 -0
- package/src/home/__tests__/emit-feed-event.test.ts +169 -0
- package/src/home/__tests__/feed-scheduler.test.ts +194 -0
- package/src/home/__tests__/feed-types.test.ts +275 -0
- package/src/home/__tests__/feed-writer.test.ts +688 -0
- package/src/home/__tests__/phase5-exit-criteria.test.ts +212 -0
- package/src/home/__tests__/platform-gmail-digest.test.ts +222 -0
- package/src/home/__tests__/progress-formula.test.ts +213 -0
- package/src/home/__tests__/relationship-state-writer.test.ts +740 -0
- package/src/home/__tests__/rollup-producer.test.ts +398 -0
- package/src/home/assistant-feed-authoring.ts +124 -0
- package/src/home/emit-feed-event.ts +158 -0
- package/src/home/feed-scheduler.ts +247 -0
- package/src/home/feed-types.ts +181 -0
- package/src/home/feed-writer.ts +469 -0
- package/src/home/platform-gmail-digest.ts +163 -0
- package/src/home/progress-formula.ts +86 -0
- package/src/home/relationship-state-writer.ts +824 -0
- package/src/home/relationship-state.ts +143 -0
- package/src/home/rollup-producer.ts +384 -0
- package/src/hooks/runner.ts +7 -0
- package/src/inbound/platform-callback-registration.ts +30 -20
- package/src/inbound/public-ingress-urls.ts +12 -0
- package/src/instrument.ts +1 -1
- package/src/ipc/__tests__/cli-ipc.test.ts +200 -0
- package/src/ipc/cli-client.ts +151 -0
- package/src/ipc/cli-server.ts +234 -0
- package/src/ipc/gateway-client.ts +180 -0
- package/src/ipc/routes/index.ts +5 -0
- package/src/ipc/routes/wake-conversation.ts +19 -0
- package/src/mcp/client.ts +59 -24
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +356 -0
- package/src/memory/__tests__/auto-analysis-guard.test.ts +57 -0
- package/src/memory/__tests__/conversation-analyze-job.test.ts +232 -0
- package/src/memory/__tests__/find-analysis-conversation.test.ts +196 -0
- package/src/memory/app-store.ts +31 -1
- package/src/memory/attachments-store.ts +70 -0
- package/src/memory/auto-analysis-enqueue.ts +127 -0
- package/src/memory/auto-analysis-guard.ts +27 -0
- package/src/memory/cleanup-schedule-state.ts +37 -0
- package/src/memory/conversation-analyze-job.ts +73 -0
- package/src/memory/conversation-crud.ts +122 -0
- package/src/memory/conversation-disk-view.ts +7 -0
- package/src/memory/conversation-group-migration.ts +34 -2
- package/src/memory/conversation-queries.ts +6 -5
- package/src/memory/conversation-starters-cadence.ts +76 -0
- package/src/memory/conversation-title-service.ts +5 -2
- package/src/memory/db-init.ts +18 -0
- package/src/memory/db-maintenance.ts +108 -0
- package/src/memory/db.ts +1 -0
- package/src/memory/embedding-backend.test.ts +75 -0
- package/src/memory/embedding-backend.ts +131 -5
- package/src/memory/embedding-gemini.test.ts +54 -0
- package/src/memory/embedding-gemini.ts +20 -9
- package/src/memory/embedding-local.ts +176 -17
- package/src/memory/graph/consolidation.ts +10 -23
- package/src/memory/graph/conversation-graph-memory.ts +15 -0
- package/src/memory/graph/extraction-job.ts +15 -0
- package/src/memory/graph/extraction.test.ts +23 -0
- package/src/memory/graph/extraction.ts +8 -0
- package/src/memory/graph/retriever.ts +67 -40
- package/src/memory/graph/scoring.test.ts +186 -0
- package/src/memory/graph/scoring.ts +31 -1
- package/src/memory/graph/store.test.ts +7 -3
- package/src/memory/graph/store.ts +47 -12
- package/src/memory/graph/tools.ts +1 -1
- package/src/memory/group-crud.ts +6 -1
- package/src/memory/indexer.ts +95 -16
- package/src/memory/job-handlers/cleanup.ts +11 -8
- package/src/memory/job-handlers/conversation-starters.ts +16 -10
- package/src/memory/jobs-store.ts +64 -4
- package/src/memory/jobs-worker.ts +22 -9
- package/src/memory/llm-usage-store.ts +137 -60
- package/src/memory/migrations/213-oauth-providers-scope-separator.ts +13 -0
- package/src/memory/migrations/214-oauth-providers-refresh-url.ts +11 -0
- package/src/memory/migrations/215-oauth-providers-revoke.ts +14 -0
- package/src/memory/migrations/216-oauth-providers-token-auth-method.ts +30 -0
- package/src/memory/migrations/217-conversation-host-access.ts +40 -0
- package/src/memory/migrations/218-oauth-providers-logo-url.ts +11 -0
- package/src/memory/migrations/219-oauth-providers-token-exchange-body-format.ts +15 -0
- package/src/memory/migrations/220-normalize-user-file-by-principal.ts +190 -0
- package/src/memory/migrations/221-conversations-archived-at.ts +16 -0
- package/src/memory/migrations/index.ts +12 -0
- package/src/memory/migrations/registry.ts +16 -0
- package/src/memory/qdrant-manager.ts +43 -16
- package/src/memory/schema/conversations.ts +3 -0
- package/src/memory/schema/oauth.ts +21 -13
- package/src/memory/usage-buckets.ts +396 -0
- package/src/messaging/providers/gmail/client.ts +57 -6
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +282 -0
- package/src/messaging/providers/slack/adapter.ts +143 -38
- package/src/messaging/providers/slack/client.ts +16 -0
- package/src/messaging/providers/slack/types.ts +4 -0
- package/src/notifications/decision-engine.ts +3 -3
- package/src/notifications/signal.ts +5 -0
- package/src/oauth/AGENTS.md +76 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +25 -19
- package/src/oauth/__tests__/seed-providers-managed.test.ts +32 -0
- package/src/oauth/byo-connection.test.ts +26 -9
- package/src/oauth/byo-connection.ts +10 -8
- package/src/oauth/connect-orchestrator.ts +25 -21
- package/src/oauth/connect-types.ts +3 -3
- package/src/oauth/connection-resolver.test.ts +17 -4
- package/src/oauth/connection-resolver.ts +22 -18
- package/src/oauth/connection.ts +3 -1
- package/src/oauth/manual-token-connection.ts +13 -13
- package/src/oauth/oauth-store.ts +223 -100
- package/src/oauth/platform-connection.test.ts +101 -3
- package/src/oauth/platform-connection.ts +56 -35
- package/src/oauth/provider-serializer.ts +31 -5
- package/src/oauth/revoke.ts +76 -0
- package/src/oauth/seed-providers.ts +133 -87
- package/src/oauth/token-persistence.ts +1 -1
- package/src/permissions/checker.ts +16 -6
- package/src/permissions/defaults.ts +49 -1
- package/src/permissions/permission-mode.ts +4 -11
- package/src/permissions/prompter.ts +13 -1
- package/src/permissions/trust-store.ts +3 -3
- package/src/permissions/v2-consent-policy.ts +87 -0
- package/src/permissions/workspace-policy.ts +3 -0
- package/src/platform/client.test.ts +10 -0
- package/src/platform/sync-identity.ts +129 -0
- package/src/prompts/persona-resolver.ts +126 -2
- package/src/prompts/system-prompt.ts +76 -38
- package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +3 -65
- package/src/prompts/templates/BOOTSTRAP.md +59 -105
- package/src/prompts/templates/SOUL.md +3 -1
- package/src/prompts/templates/UPDATES.md +12 -0
- package/src/prompts/templates/channels/slack.md +20 -0
- package/src/prompts/update-bulletin-format.ts +26 -9
- package/src/prompts/update-bulletin.ts +34 -23
- package/src/prompts/user-reference.ts +20 -17
- package/src/providers/__tests__/provider-secret-catalog.test.ts +42 -0
- package/src/providers/anthropic/client.ts +157 -60
- package/src/providers/fireworks/client.ts +2 -2
- package/src/providers/gemini/client.ts +9 -1
- package/src/providers/model-catalog.ts +6 -0
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/ollama/client.ts +2 -2
- package/src/providers/openai/chat-completions-provider.ts +474 -0
- package/src/providers/openai/client.ts +25 -440
- package/src/providers/openai/responses-provider.ts +502 -0
- package/src/providers/openrouter/client.ts +101 -4
- package/src/providers/provider-secret-catalog.ts +139 -0
- package/src/providers/registry.ts +2 -2
- package/src/providers/retry.ts +14 -3
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +251 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +828 -0
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +980 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +767 -0
- package/src/providers/speech-to-text/deepgram.test.ts +332 -0
- package/src/providers/speech-to-text/deepgram.ts +115 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.test.ts +743 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.ts +625 -0
- package/src/providers/speech-to-text/google-gemini.test.ts +226 -0
- package/src/providers/speech-to-text/google-gemini.ts +101 -0
- package/src/providers/speech-to-text/openai-whisper-stream.test.ts +564 -0
- package/src/providers/speech-to-text/openai-whisper-stream.ts +381 -0
- package/src/providers/speech-to-text/openai-whisper.test.ts +1 -37
- package/src/providers/speech-to-text/openai-whisper.ts +63 -33
- package/src/providers/speech-to-text/provider-catalog.ts +306 -0
- package/src/providers/speech-to-text/resolve.ts +386 -6
- package/src/providers/types.ts +10 -1
- package/src/runtime/AGENTS.md +65 -0
- package/src/runtime/__tests__/agent-wake.test.ts +831 -0
- package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +715 -0
- package/src/runtime/__tests__/capability-tokens.test.ts +258 -0
- package/src/runtime/__tests__/chrome-extension-registry.test.ts +518 -0
- package/src/runtime/__tests__/runtime-mode.test.ts +62 -0
- package/src/runtime/__tests__/slack-block-formatting.test.ts +481 -0
- package/src/runtime/agent-wake.ts +512 -0
- package/src/runtime/assistant-event-hub.ts +2 -2
- package/src/runtime/auth/__tests__/guard-tests.test.ts +1 -0
- package/src/runtime/auth/__tests__/middleware.test.ts +116 -1
- package/src/runtime/auth/__tests__/route-policy.test.ts +48 -0
- package/src/runtime/auth/middleware.ts +98 -0
- package/src/runtime/auth/route-policy.ts +33 -9
- package/src/runtime/auth/token-service.ts +56 -1
- package/src/runtime/btw-sidechain.ts +2 -0
- package/src/runtime/capability-tokens.ts +414 -0
- package/src/runtime/channel-approvals.ts +18 -5
- package/src/runtime/channel-invite-transport.ts +1 -1
- package/src/runtime/channel-invite-transports/email.ts +14 -6
- package/src/runtime/channel-readiness-service.ts +12 -22
- package/src/runtime/chrome-extension-registry.ts +368 -0
- package/src/runtime/confirmation-request-guardian-bridge.ts +6 -0
- package/src/runtime/guardian-decision-types.ts +7 -0
- package/src/runtime/http-server.ts +815 -75
- package/src/runtime/http-types.ts +6 -2
- package/src/runtime/migrations/__tests__/rebind-secrets-credentials.test.ts +172 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +276 -0
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +198 -0
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +360 -0
- package/src/runtime/migrations/migration-transport.ts +7 -0
- package/src/runtime/migrations/migration-wizard.ts +23 -2
- package/src/runtime/migrations/rebind-secrets-screen.ts +76 -15
- package/src/runtime/migrations/vbundle-builder.ts +145 -38
- package/src/runtime/migrations/vbundle-import-analyzer.ts +96 -1
- package/src/runtime/migrations/vbundle-importer.ts +89 -5
- package/src/runtime/pending-interactions.ts +18 -13
- package/src/runtime/routes/__tests__/backup-routes.test.ts +967 -0
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +507 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +208 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +406 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +474 -0
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +148 -17
- package/src/runtime/routes/app-management-routes.ts +12 -18
- package/src/runtime/routes/approval-routes.ts +90 -16
- package/src/runtime/routes/attachment-routes.test.ts +9 -3
- package/src/runtime/routes/attachment-routes.ts +216 -17
- package/src/runtime/routes/backup-routes.ts +519 -0
- package/src/runtime/routes/browser-extension-pair-routes.ts +556 -0
- package/src/runtime/routes/btw-routes.ts +8 -6
- package/src/runtime/routes/contact-routes.test.ts +298 -0
- package/src/runtime/routes/contact-routes.ts +132 -5
- package/src/runtime/routes/conversation-analysis-routes.ts +22 -141
- package/src/runtime/routes/conversation-management-routes.ts +223 -0
- package/src/runtime/routes/conversation-routes.ts +598 -103
- package/src/runtime/routes/conversation-starter-routes.ts +78 -16
- package/src/runtime/routes/filing-routes.ts +93 -0
- package/src/runtime/routes/guardian-action-routes.ts +24 -13
- package/src/runtime/routes/home-feed-routes.ts +334 -0
- package/src/runtime/routes/home-state-routes.ts +138 -0
- package/src/runtime/routes/host-browser-routes.ts +268 -0
- package/src/runtime/routes/host-file-routes.ts +9 -1
- package/src/runtime/routes/identity-intro-cache.ts +7 -3
- package/src/runtime/routes/identity-routes.ts +262 -33
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +46 -39
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +15 -15
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +137 -0
- package/src/runtime/routes/integrations/slack/__tests__/share.test.ts +179 -0
- package/src/runtime/routes/integrations/slack/channel.ts +11 -3
- package/src/runtime/routes/integrations/slack/share.ts +45 -7
- package/src/runtime/routes/llm-context-normalization.ts +303 -0
- package/src/runtime/routes/log-export-routes.ts +42 -22
- package/src/runtime/routes/memory-item-routes.test.ts +3 -2
- package/src/runtime/routes/memory-item-routes.ts +1 -7
- package/src/runtime/routes/migration-routes.ts +122 -2
- package/src/runtime/routes/oauth-apps.ts +15 -17
- package/src/runtime/routes/oauth-providers.ts +4 -0
- package/src/runtime/routes/schedule-routes.ts +24 -11
- package/src/runtime/routes/settings-routes.ts +31 -102
- package/src/runtime/routes/skills-routes.ts +128 -9
- package/src/runtime/routes/stt-routes.ts +233 -0
- package/src/runtime/routes/subagents-routes.ts +14 -10
- package/src/runtime/routes/surface-action-routes.ts +41 -2
- package/src/runtime/routes/tts-routes.ts +108 -24
- package/src/runtime/routes/usage-routes.ts +38 -9
- package/src/runtime/routes/user-route-dispatcher.ts +50 -5
- package/src/runtime/routes/user-routes.ts +13 -1
- package/src/runtime/routes/work-items-routes.ts +8 -1
- package/src/runtime/routes/workspace-routes.test.ts +22 -0
- package/src/runtime/routes/workspace-routes.ts +8 -1
- package/src/runtime/routes/workspace-utils.ts +2 -0
- package/src/runtime/runtime-mode.ts +33 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +444 -0
- package/src/runtime/services/__tests__/analyze-deps-singleton.test.ts +67 -0
- package/src/runtime/services/__tests__/auto-analysis-prompt.test.ts +53 -0
- package/src/runtime/services/__tests__/manual-analysis-prompt.test.ts +41 -0
- package/src/runtime/services/analyze-conversation.ts +344 -0
- package/src/runtime/services/analyze-deps-singleton.ts +32 -0
- package/src/runtime/services/auto-analysis-prompt.ts +55 -0
- package/src/runtime/skill-route-registry.ts +49 -0
- package/src/runtime/slack-block-formatting.ts +437 -10
- package/src/schedule/scheduler.ts +57 -5
- package/src/security/ces-credential-client.ts +20 -0
- package/src/security/ces-rpc-credential-backend.ts +17 -0
- package/src/security/credential-backend.ts +5 -0
- package/src/security/oauth2.ts +68 -29
- package/src/security/secure-keys.ts +143 -27
- package/src/security/token-manager.ts +31 -10
- package/src/sequence/engine.ts +23 -0
- package/src/sequence/types.ts +1 -1
- package/src/skills/catalog-files.ts +554 -0
- package/src/skills/category-inference.ts +122 -0
- package/src/skills/clawhub-files.ts +213 -0
- package/src/skills/clawhub.ts +84 -23
- package/src/skills/skill-file-provider.ts +40 -0
- package/src/skills/skillssh-files.ts +395 -0
- package/src/skills/skillssh-registry.ts +4 -4
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +392 -0
- package/src/stt/__tests__/types.test.ts +89 -0
- package/src/stt/daemon-batch-transcriber.ts +195 -0
- package/src/stt/stt-stream-session.ts +499 -0
- package/src/stt/types.ts +330 -0
- package/src/stt/wav-encoder.test.ts +373 -0
- package/src/stt/wav-encoder.ts +175 -0
- package/src/subagent/manager.ts +169 -40
- package/src/subagent/types.ts +19 -0
- package/src/tools/apps/executors.ts +11 -2
- package/src/tools/browser/__tests__/auth-detector.test.ts +202 -108
- package/src/tools/browser/__tests__/browser-mode.test.ts +119 -0
- package/src/tools/browser/__tests__/browser-status.test.ts +123 -0
- package/src/tools/browser/auth-detector.ts +43 -12
- package/src/tools/browser/browser-execution.ts +1787 -342
- package/src/tools/browser/browser-manager.ts +81 -12
- package/src/tools/browser/browser-mode-constants.ts +12 -0
- package/src/tools/browser/browser-mode.ts +92 -0
- package/src/tools/browser/browser-status-constants.ts +33 -0
- package/src/tools/browser/cdp-client/__tests__/accessibility-snapshot.test.ts +318 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-dom-helpers.test.ts +1175 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +1263 -0
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +359 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +1993 -0
- package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-nested-frames.json +64 -0
- package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-simple.json +69 -0
- package/src/tools/browser/cdp-client/__tests__/local-cdp-client.test.ts +310 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +96 -0
- package/src/tools/browser/cdp-client/accessibility-snapshot.ts +387 -0
- package/src/tools/browser/cdp-client/cdp-dom-helpers.ts +695 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +1007 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +580 -0
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +744 -0
- package/src/tools/browser/cdp-client/cdp-inspect/ws-transport.ts +579 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +868 -0
- package/src/tools/browser/cdp-client/errors.ts +49 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +148 -0
- package/src/tools/browser/cdp-client/factory.ts +914 -0
- package/src/tools/browser/cdp-client/index.ts +28 -0
- package/src/tools/browser/cdp-client/local-cdp-client.ts +187 -0
- package/src/tools/browser/cdp-client/types.ts +120 -0
- package/src/tools/credentials/vault.ts +35 -6
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +1 -1
- package/src/tools/filesystem/write.ts +2 -1
- package/src/tools/host-filesystem/edit.ts +1 -1
- package/src/tools/host-filesystem/read.ts +12 -15
- package/src/tools/host-filesystem/write.ts +1 -1
- package/src/tools/host-terminal/host-shell.ts +21 -16
- package/src/tools/network/web-fetch.ts +5 -2
- package/src/tools/network/web-search.ts +5 -2
- package/src/tools/permission-checker.ts +77 -82
- package/src/tools/registry.ts +0 -2
- package/src/tools/secret-detection-handler.ts +34 -0
- package/src/tools/shared/filesystem/image-read.ts +61 -40
- package/src/tools/shared/shell-output.ts +3 -1
- package/src/tools/side-effects.ts +2 -0
- package/src/tools/skills/sandbox-runner.ts +3 -2
- package/src/tools/subagent/spawn.ts +47 -3
- package/src/tools/subagent/status.ts +2 -0
- package/src/tools/system/register.ts +2 -16
- package/src/tools/terminal/safe-env.ts +15 -0
- package/src/tools/terminal/shell.ts +36 -20
- package/src/tools/tool-approval-handler.ts +48 -2
- package/src/tools/tool-manifest.ts +21 -0
- package/src/tools/types.ts +19 -0
- package/src/tools/ui-surface/definitions.ts +6 -1
- package/src/tts/__tests__/provider-adapters.test.ts +834 -0
- package/src/tts/__tests__/provider-catalog-consistency.test.ts +196 -0
- package/src/tts/__tests__/provider-catalog.test.ts +183 -0
- package/src/tts/__tests__/provider-registry.test.ts +90 -0
- package/src/tts/provider-catalog.ts +201 -0
- package/src/tts/provider-registry.ts +73 -0
- package/src/tts/providers/deepgram-provider.ts +219 -0
- package/src/tts/providers/elevenlabs-provider.ts +211 -0
- package/src/tts/providers/fish-audio-provider.ts +183 -0
- package/src/tts/providers/index.ts +42 -0
- package/src/tts/providers/register-builtins.ts +130 -0
- package/src/tts/synthesize-text.ts +110 -0
- package/src/tts/tts-config-resolver.ts +78 -0
- package/src/tts/types.ts +153 -0
- package/src/types/onboarding-context.ts +7 -0
- package/src/util/abort-reasons.ts +58 -0
- package/src/util/device-id.ts +32 -16
- package/src/util/errors.ts +9 -1
- package/src/util/platform.ts +63 -24
- package/src/util/pricing.ts +66 -3
- package/src/util/spawn.ts +1 -1
- package/src/util/truncate.ts +4 -2
- package/src/util/unicode.ts +201 -0
- package/src/version.ts +19 -24
- package/src/watcher/engine.ts +23 -0
- package/src/watcher/watcher-store.ts +31 -0
- package/src/workspace/migrations/003-seed-device-id.ts +9 -3
- package/src/workspace/migrations/017-seed-persona-dirs.ts +68 -4
- package/src/workspace/migrations/029-seed-pkb.ts +1 -1
- package/src/workspace/migrations/031-drop-user-md.ts +317 -0
- package/src/workspace/migrations/031-llm-log-retention-zero-to-null.ts +73 -0
- package/src/workspace/migrations/032-tts-provider-unification.ts +227 -0
- package/src/workspace/migrations/033-stt-service-explicit-config.ts +122 -0
- package/src/workspace/migrations/034-remove-calls-voice-transcription-provider.ts +215 -0
- package/src/workspace/migrations/035-seed-slack-channel-persona.ts +50 -0
- package/src/workspace/migrations/036-update-pkb-index-bar.ts +37 -0
- package/src/workspace/migrations/037-create-meets-dir.ts +61 -0
- package/src/workspace/migrations/registry.ts +16 -0
- package/src/workspace/top-level-renderer.ts +31 -1
- package/src/workspace/turn-commit.ts +31 -0
- package/src/__tests__/chrome-cdp.test.ts +0 -419
- package/src/__tests__/email-cli.test.ts +0 -297
- package/src/__tests__/email-service-config-fallback.test.ts +0 -102
- package/src/__tests__/permission-mode-sse.test.ts +0 -418
- package/src/__tests__/permission-mode-store.test.ts +0 -277
- package/src/browser-extension-relay/protocol.ts +0 -63
- package/src/browser-extension-relay/server.ts +0 -203
- package/src/cli/commands/browser-relay.ts +0 -536
- package/src/config/schemas/sandbox.ts +0 -14
- package/src/email/guardrails.ts +0 -221
- package/src/email/provider.ts +0 -117
- package/src/email/providers/agentmail.ts +0 -361
- package/src/email/providers/index.ts +0 -65
- package/src/email/service.ts +0 -384
- package/src/email/types.ts +0 -126
- package/src/permissions/permission-mode-store.ts +0 -180
- package/src/prompts/templates/USER.md +0 -13
- package/src/providers/speech-to-text/types.ts +0 -17
- package/src/tools/browser/chrome-cdp.ts +0 -239
- package/src/tools/system/set-permission-mode.ts +0 -103
|
@@ -8,11 +8,10 @@ import {
|
|
|
8
8
|
} from "node:fs";
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
|
|
11
|
-
import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
|
|
12
11
|
import { getIsContainerized } from "../config/env-registry.js";
|
|
13
12
|
import { loadConfig } from "../config/loader.js";
|
|
14
13
|
import { listConnections } from "../oauth/oauth-store.js";
|
|
15
|
-
import {
|
|
14
|
+
import type { OnboardingContext } from "../types/onboarding-context.js";
|
|
16
15
|
import { resolveBundledDir } from "../util/bundled-asset.js";
|
|
17
16
|
import { getLogger } from "../util/logger.js";
|
|
18
17
|
import {
|
|
@@ -27,7 +26,27 @@ export { SYSTEM_PROMPT_CACHE_BOUNDARY };
|
|
|
27
26
|
|
|
28
27
|
const log = getLogger("system-prompt");
|
|
29
28
|
|
|
30
|
-
const PROMPT_FILES = ["SOUL.md", "IDENTITY.md"
|
|
29
|
+
const PROMPT_FILES = ["SOUL.md", "IDENTITY.md"] as const;
|
|
30
|
+
|
|
31
|
+
function hasPopulatedUsersDir(): boolean {
|
|
32
|
+
try {
|
|
33
|
+
const usersDir = join(getWorkspaceDir(), "users");
|
|
34
|
+
if (!existsSync(usersDir)) return false;
|
|
35
|
+
return readdirSync(usersDir).length > 0;
|
|
36
|
+
} catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function hasExistingConversations(): boolean {
|
|
42
|
+
try {
|
|
43
|
+
const convDir = getConversationsDir();
|
|
44
|
+
if (!existsSync(convDir)) return false;
|
|
45
|
+
return readdirSync(convDir).length > 0;
|
|
46
|
+
} catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
31
50
|
|
|
32
51
|
/**
|
|
33
52
|
* Copy template prompt files into the data directory if they don't already exist.
|
|
@@ -45,10 +64,16 @@ export function ensurePromptFiles(): void {
|
|
|
45
64
|
"templates",
|
|
46
65
|
);
|
|
47
66
|
|
|
48
|
-
// Track whether this is a fresh workspace
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
67
|
+
// Track whether this is a fresh workspace. A workspace counts as fresh
|
|
68
|
+
// only when none of these signals are present: core prompt files, a
|
|
69
|
+
// populated `users/` directory, or existing conversations. Upgraded
|
|
70
|
+
// workspaces that dropped USER.md but still carry personas or history
|
|
71
|
+
// would otherwise be mistaken for fresh installs and re-trigger
|
|
72
|
+
// onboarding.
|
|
73
|
+
const isFirstRun =
|
|
74
|
+
PROMPT_FILES.every((file) => !existsSync(getWorkspacePromptPath(file))) &&
|
|
75
|
+
!hasPopulatedUsersDir() &&
|
|
76
|
+
!hasExistingConversations();
|
|
52
77
|
|
|
53
78
|
for (const file of PROMPT_FILES) {
|
|
54
79
|
const dest = getWorkspacePromptPath(file);
|
|
@@ -192,7 +217,7 @@ export function ensurePromptFiles(): void {
|
|
|
192
217
|
*
|
|
193
218
|
* Composition:
|
|
194
219
|
* 1. Base prompt: IDENTITY.md + SOUL.md (guaranteed to exist after ensurePromptFiles)
|
|
195
|
-
* 2. Append
|
|
220
|
+
* 2. Append the resolved user persona from users/<slug>.md (via options.userPersona)
|
|
196
221
|
* 3. If BOOTSTRAP.md exists, append first-run ritual instructions
|
|
197
222
|
*/
|
|
198
223
|
export interface BuildSystemPromptOptions {
|
|
@@ -201,6 +226,7 @@ export interface BuildSystemPromptOptions {
|
|
|
201
226
|
userPersona?: string | null;
|
|
202
227
|
channelPersona?: string | null;
|
|
203
228
|
userSlug?: string | null;
|
|
229
|
+
onboardingContext?: OnboardingContext;
|
|
204
230
|
}
|
|
205
231
|
|
|
206
232
|
/**
|
|
@@ -217,8 +243,10 @@ export function buildSystemPrompt(options?: BuildSystemPromptOptions): string {
|
|
|
217
243
|
// ── Static instruction sections (stable across turns) ──
|
|
218
244
|
// These sections are deterministic within a process lifetime. They form
|
|
219
245
|
// the first cache block so they remain cached even when workspace files
|
|
220
|
-
// (IDENTITY.md, SOUL.md,
|
|
246
|
+
// (IDENTITY.md, SOUL.md, users/<slug>.md, etc.) are edited between turns.
|
|
221
247
|
const staticParts: string[] = [];
|
|
248
|
+
const customPrefix = readCustomSystemPromptPrefix();
|
|
249
|
+
if (customPrefix) staticParts.push(customPrefix);
|
|
222
250
|
staticParts.push(buildParallelToolCallsSection());
|
|
223
251
|
if (getIsContainerized()) staticParts.push(buildContainerizedSection());
|
|
224
252
|
staticParts.push(buildCliReferenceSection());
|
|
@@ -242,13 +270,11 @@ export function buildSystemPrompt(options?: BuildSystemPromptOptions): string {
|
|
|
242
270
|
|
|
243
271
|
const soulPath = getWorkspacePromptPath("SOUL.md");
|
|
244
272
|
const identityPath = getWorkspacePromptPath("IDENTITY.md");
|
|
245
|
-
const userPath = getWorkspacePromptPath("USER.md");
|
|
246
273
|
const bootstrapPath = getWorkspacePromptPath("BOOTSTRAP.md");
|
|
247
274
|
const updatesPath = getWorkspacePromptPath("UPDATES.md");
|
|
248
275
|
|
|
249
276
|
const soul = readPromptFile(soulPath);
|
|
250
277
|
const identity = readPromptFile(identityPath);
|
|
251
|
-
const user = readPromptFile(userPath);
|
|
252
278
|
const bootstrap = readPromptFile(bootstrapPath);
|
|
253
279
|
const updates = readPromptFile(updatesPath);
|
|
254
280
|
|
|
@@ -262,7 +288,6 @@ export function buildSystemPrompt(options?: BuildSystemPromptOptions): string {
|
|
|
262
288
|
// source and skip them — SOUL.md provides sufficient personality defaults
|
|
263
289
|
// until onboarding completes.
|
|
264
290
|
const identityIsTemplate = isTemplateContent(identity, "IDENTITY.md");
|
|
265
|
-
const userIsTemplate = isTemplateContent(user, "USER.md");
|
|
266
291
|
|
|
267
292
|
if (identity && !identityIsTemplate) {
|
|
268
293
|
// Strip placeholder lines (e.g. "- **Name:** _(not yet chosen)_") so
|
|
@@ -278,13 +303,28 @@ export function buildSystemPrompt(options?: BuildSystemPromptOptions): string {
|
|
|
278
303
|
if (soul) dynamicParts.push(soul);
|
|
279
304
|
if (options?.userPersona) dynamicParts.push(options.userPersona);
|
|
280
305
|
if (options?.channelPersona) dynamicParts.push(options.channelPersona);
|
|
281
|
-
if (user && !userIsTemplate && !options?.userPersona) dynamicParts.push(user);
|
|
282
306
|
if (includeBootstrap) {
|
|
307
|
+
const userSlug = options?.userSlug ?? "default";
|
|
308
|
+
const bootstrapWithSlug = bootstrap.replaceAll(
|
|
309
|
+
"{{USER_PERSONA_FILE}}",
|
|
310
|
+
`${userSlug}.md`,
|
|
311
|
+
);
|
|
283
312
|
dynamicParts.push(
|
|
284
313
|
"# First-Run Ritual\n\n" +
|
|
285
314
|
"BOOTSTRAP.md is present — this is your first conversation. Follow its instructions.\n\n" +
|
|
286
|
-
|
|
315
|
+
bootstrapWithSlug,
|
|
287
316
|
);
|
|
317
|
+
|
|
318
|
+
if (options?.onboardingContext) {
|
|
319
|
+
dynamicParts.push(
|
|
320
|
+
"## Pre-chat Onboarding Context\n\n" +
|
|
321
|
+
"The user completed the native pre-chat onboarding. Here is their context:\n\n" +
|
|
322
|
+
"```json\n" +
|
|
323
|
+
JSON.stringify(options.onboardingContext, null, 2) +
|
|
324
|
+
"\n```\n\n" +
|
|
325
|
+
"Use this to personalize your opener and skip redundant discovery.",
|
|
326
|
+
);
|
|
327
|
+
}
|
|
288
328
|
}
|
|
289
329
|
if (updates) {
|
|
290
330
|
dynamicParts.push(
|
|
@@ -313,9 +353,6 @@ export function buildSystemPrompt(options?: BuildSystemPromptOptions): string {
|
|
|
313
353
|
// Journal entries are extracted into graph nodes by the memory pipeline.
|
|
314
354
|
// Journal files remain writable on disk.
|
|
315
355
|
|
|
316
|
-
const askBeforeActingSection = buildAskBeforeActingSection();
|
|
317
|
-
if (askBeforeActingSection) dynamicParts.push(askBeforeActingSection);
|
|
318
|
-
|
|
319
356
|
const dynamic = dynamicParts.join("\n\n");
|
|
320
357
|
|
|
321
358
|
return staticParts.join("\n\n") + SYSTEM_PROMPT_CACHE_BOUNDARY + dynamic;
|
|
@@ -370,7 +407,7 @@ function buildCredentialSecuritySection(): string {
|
|
|
370
407
|
}
|
|
371
408
|
|
|
372
409
|
function buildIntegrationSection(): string {
|
|
373
|
-
let connections: {
|
|
410
|
+
let connections: { provider: string; accountInfo?: string | null }[];
|
|
374
411
|
try {
|
|
375
412
|
connections = listConnections().filter((c) => c.status === "active");
|
|
376
413
|
} catch {
|
|
@@ -385,31 +422,27 @@ function buildIntegrationSection(): string {
|
|
|
385
422
|
const state = conn.accountInfo
|
|
386
423
|
? `Connected (${conn.accountInfo})`
|
|
387
424
|
: "Connected";
|
|
388
|
-
lines.push(`- **${conn.
|
|
425
|
+
lines.push(`- **${conn.provider}**: ${state}`);
|
|
389
426
|
}
|
|
390
427
|
|
|
391
428
|
return lines.join("\n");
|
|
392
429
|
}
|
|
393
430
|
|
|
394
|
-
|
|
431
|
+
/**
|
|
432
|
+
* Read the user-configured custom system prompt prefix. Returns the trimmed
|
|
433
|
+
* value when set and non-empty, otherwise null. Errors (e.g. config file
|
|
434
|
+
* unavailable) are swallowed so prompt construction never fails.
|
|
435
|
+
*/
|
|
436
|
+
function readCustomSystemPromptPrefix(): string | null {
|
|
395
437
|
try {
|
|
396
|
-
const
|
|
397
|
-
if (
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
const mode = getMode();
|
|
401
|
-
if (!mode.askBeforeActing) return null;
|
|
402
|
-
|
|
403
|
-
return [
|
|
404
|
-
"## Action Confirmation Mode",
|
|
405
|
-
"",
|
|
406
|
-
'You are in "Ask before acting" mode. Use your judgment about when to check in with the user before proceeding. You should ask for confirmation before actions that are costly, time-consuming, or hard to reverse — for example: sending emails or messages, deleting files or data, making purchases, posting publicly, modifying permissions, or taking actions with significant real-world consequences. You do NOT need to ask before routine low-stakes actions like reading files, searching, running safe shell commands, or making code edits — just do those.',
|
|
407
|
-
].join("\n");
|
|
438
|
+
const prefix = loadConfig().systemPromptPrefix;
|
|
439
|
+
if (typeof prefix !== "string") return null;
|
|
440
|
+
const trimmed = prefix.trim();
|
|
441
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
408
442
|
} catch {
|
|
409
443
|
return null;
|
|
410
444
|
}
|
|
411
445
|
}
|
|
412
|
-
|
|
413
446
|
function buildContainerizedSection(): string {
|
|
414
447
|
const workspaceDir = getWorkspaceDir();
|
|
415
448
|
return [
|
|
@@ -430,7 +463,11 @@ function buildContainerizedSection(): string {
|
|
|
430
463
|
function buildParallelToolCallsSection(): string {
|
|
431
464
|
return [
|
|
432
465
|
"<use_parallel_tool_calls>",
|
|
433
|
-
"
|
|
466
|
+
"Batch independent tool calls into the same response. An extra LLM round trip costs orders of magnitude more than a few wasted tool calls — err on the side of parallelizing when calls are independent. Reading multiple files, `glob`/`grep`, `ls`, `git status`/`diff`/`log`, type-checks, and tests should be batched.",
|
|
467
|
+
"",
|
|
468
|
+
"Before emitting a single tool call, ask whether your next turn would be another tool call that doesn't consume this one's output — if so, they belong together. Serialized tool calls without a real data dependency are a bug.",
|
|
469
|
+
"",
|
|
470
|
+
"For non-trivial independent workstreams — research, coding, multi-step investigations — delegate to subagents (load the `subagent` skill) and spawn them early and in parallel; an unnecessary subagent is cheaper than serialized work.",
|
|
434
471
|
"</use_parallel_tool_calls>",
|
|
435
472
|
].join("\n");
|
|
436
473
|
}
|
|
@@ -444,6 +481,8 @@ export function buildCliReferenceSection(): string {
|
|
|
444
481
|
"Use `assistant platform status` to check the current Vellum platform connection state, and `assistant platform --help` to see all platform management subcommands.",
|
|
445
482
|
"",
|
|
446
483
|
"Run `assistant --help` to see all available commands, or `assistant <command> --help` for detailed help on any subcommand.",
|
|
484
|
+
"",
|
|
485
|
+
"**Before telling a user you cannot do something, run `assistant --help` to check whether a built-in command exists for it.** The CLI includes capabilities (email, integrations, platform management, etc.) that you may not know about from training data alone. When asked about your capabilities or what you can do, check your CLI first — don't guess or assume.",
|
|
447
486
|
].join("\n");
|
|
448
487
|
}
|
|
449
488
|
|
|
@@ -493,7 +532,7 @@ function readPromptFile(path: string): string | null {
|
|
|
493
532
|
}
|
|
494
533
|
|
|
495
534
|
/**
|
|
496
|
-
* Reads the core identity/personality prompt files (SOUL.md, IDENTITY.md
|
|
535
|
+
* Reads the core identity/personality prompt files (SOUL.md, IDENTITY.md)
|
|
497
536
|
* and concatenates whichever exist. Returns null if none are present.
|
|
498
537
|
*
|
|
499
538
|
* This is useful for injecting identity context into subsystems (e.g. memory
|
|
@@ -507,10 +546,9 @@ export function buildCoreIdentityContext(opts?: {
|
|
|
507
546
|
const content = readPromptFile(getWorkspacePromptPath(file));
|
|
508
547
|
if (!content) continue;
|
|
509
548
|
// SOUL.md is always included — it provides personality defaults even
|
|
510
|
-
// before onboarding completes. Only skip IDENTITY.md
|
|
511
|
-
//
|
|
549
|
+
// before onboarding completes. Only skip IDENTITY.md when it is still
|
|
550
|
+
// an unmodified template (matching buildSystemPrompt).
|
|
512
551
|
if (file !== "SOUL.md" && isTemplateContent(content, file)) continue;
|
|
513
|
-
if (file === "USER.md" && opts?.userPersona) continue;
|
|
514
552
|
parts.push(content);
|
|
515
553
|
}
|
|
516
554
|
if (opts?.userPersona) parts.push(opts.userPersona);
|
|
@@ -1,71 +1,9 @@
|
|
|
1
|
-
_
|
|
1
|
+
_ Optional reference payloads. The model may use these if it chooses to show a task card, but is not required to.
|
|
2
2
|
_ This file is deleted alongside BOOTSTRAP.md when onboarding completes.
|
|
3
3
|
|
|
4
|
-
## Personality Form
|
|
5
|
-
|
|
6
|
-
Use this exact `ui_show` payload for Step 2 (Personality Quiz):
|
|
7
|
-
|
|
8
|
-
ui_show({
|
|
9
|
-
surface_type: "form",
|
|
10
|
-
data: {
|
|
11
|
-
description: "Let's figure out how we work together. Pick what feels right.",
|
|
12
|
-
fields: [
|
|
13
|
-
{
|
|
14
|
-
id: "communication_style",
|
|
15
|
-
type: "select",
|
|
16
|
-
label: "When we're going back and forth, it's more like...",
|
|
17
|
-
required: true,
|
|
18
|
-
options: [
|
|
19
|
-
{ label: "Casual friends texting", value: "casual_friends" },
|
|
20
|
-
{ label: "Sharp coworkers who respect each other", value: "sharp_coworkers" },
|
|
21
|
-
{ label: "Chill and low-key, no drama", value: "chill" },
|
|
22
|
-
{ label: "High energy sparring partners", value: "sparring" },
|
|
23
|
-
{ label: "Professional but warm", value: "professional_warm" }
|
|
24
|
-
]
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
id: "task_style",
|
|
28
|
-
type: "select",
|
|
29
|
-
label: "When I'm doing something for you, you want me to...",
|
|
30
|
-
required: true,
|
|
31
|
-
options: [
|
|
32
|
-
{ label: "Just do it, don't explain unless I ask", value: "just_do_it" },
|
|
33
|
-
{ label: "Walk me through your thinking", value: "explain" },
|
|
34
|
-
{ label: "Ask me before making big decisions", value: "check_first" },
|
|
35
|
-
{ label: "Be opinionated, push back if you disagree", value: "opinionated" }
|
|
36
|
-
]
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
id: "humor",
|
|
40
|
-
type: "select",
|
|
41
|
-
label: "When it comes to humor...",
|
|
42
|
-
required: true,
|
|
43
|
-
options: [
|
|
44
|
-
{ label: "Dry and deadpan", value: "dry" },
|
|
45
|
-
{ label: "Playful and light", value: "playful" },
|
|
46
|
-
{ label: "Keep it professional", value: "professional" },
|
|
47
|
-
{ label: "Match my energy", value: "match" }
|
|
48
|
-
]
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
id: "depth",
|
|
52
|
-
type: "select",
|
|
53
|
-
label: "When explaining things...",
|
|
54
|
-
required: true,
|
|
55
|
-
options: [
|
|
56
|
-
{ label: "Keep it simple", value: "simple" },
|
|
57
|
-
{ label: "I like details", value: "detailed" },
|
|
58
|
-
{ label: "Depends on the topic", value: "adaptive" }
|
|
59
|
-
]
|
|
60
|
-
}
|
|
61
|
-
],
|
|
62
|
-
submitLabel: "Lock it in"
|
|
63
|
-
}
|
|
64
|
-
})
|
|
65
|
-
|
|
66
4
|
## Task Card (Email Not Connected)
|
|
67
5
|
|
|
68
|
-
Use this `ui_show` payload
|
|
6
|
+
Use this `ui_show` payload when Gmail/Outlook is NOT in the Connected Services section:
|
|
69
7
|
|
|
70
8
|
ui_show({
|
|
71
9
|
surface_type: "card",
|
|
@@ -83,7 +21,7 @@ ui_show({
|
|
|
83
21
|
|
|
84
22
|
## Task Card (Email Already Connected)
|
|
85
23
|
|
|
86
|
-
Use this `ui_show` payload
|
|
24
|
+
Use this `ui_show` payload when Google or Outlook IS in the Connected Services section:
|
|
87
25
|
|
|
88
26
|
ui_show({
|
|
89
27
|
surface_type: "card",
|
|
@@ -1,152 +1,106 @@
|
|
|
1
1
|
_ Lines starting with _ are comments. They won't appear in the system prompt
|
|
2
2
|
|
|
3
|
-
# BOOTSTRAP.md
|
|
3
|
+
# BOOTSTRAP.md — First Conversation
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This is your first conversation. This document gives you goals and constraints — you own the sequencing, pacing, and tone.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Goals
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
1. **"Oh, this has personality."** Names, style, vibe. You're a person, not a product.
|
|
11
|
-
2. **"Oh, this is useful."** Complete a real task. Prove you're worth keeping around.
|
|
12
|
-
3. **"Oh, this remembers me."** Save what you learn silently. They should feel known.
|
|
9
|
+
1. **Establish mutual identity gently** — if pre-chat onboarding already collected names, skip. If the user skipped pre-chat, do NOT force it. At most pick a default ("I'll go by Pax and call you 'you' for now") and move on. Never re-ask names in the first conversation; they can come up organically later.
|
|
13
10
|
|
|
14
|
-
|
|
11
|
+
2. **Prove value fast** — do something useful before asking for anything. Wow moment within 2-3 exchanges.
|
|
15
12
|
|
|
16
|
-
**
|
|
13
|
+
3. **Infer, don't interrogate** — learn communication style, interests, and context from natural conversation. No personality quiz. No dropdown forms. No structured intake.
|
|
17
14
|
|
|
18
|
-
**
|
|
15
|
+
4. **Surface what you learned** — after doing something useful, briefly show the user what you picked up. Make it correctable. ("from that I picked up X, Y, Z — sound right?")
|
|
19
16
|
|
|
20
|
-
|
|
17
|
+
5. **Offer the next level** — once you know something, offer a capability it enables. Not as a reward — as a natural relationship step.
|
|
21
18
|
|
|
22
|
-
|
|
19
|
+
6. **Write everything immediately** — every fact learned gets saved to users/{{USER_PERSONA_FILE}} the same turn. Style observations go to SOUL.md. No batching.
|
|
23
20
|
|
|
24
|
-
**
|
|
21
|
+
7. **Clean up** — delete BOOTSTRAP.md and BOOTSTRAP-REFERENCE.md at the end of this conversation, regardless of how far you got. One-shot.
|
|
25
22
|
|
|
26
|
-
|
|
23
|
+
## Constraints
|
|
27
24
|
|
|
28
|
-
|
|
25
|
+
- **Budget:** $2 soft cap, $5 hard cap. Keep tasks light. Don't burn credits on onboarding overhead.
|
|
26
|
+
- Never ask more than 2 questions without doing something.
|
|
27
|
+
- Don't block on setup. If the user wants to do something, do it. Weave discovery into the work.
|
|
28
|
+
- One-shot. Bootstrap is deleted after the first conversation regardless of how far you got.
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
1. I'm new and still forming (honesty)
|
|
32
|
-
2. I get better over time, like training a new colleague (sets expectations)
|
|
33
|
-
3. Let's start with who we are (personality-first)
|
|
30
|
+
## What You Own (do NOT prescribe)
|
|
34
31
|
|
|
35
|
-
|
|
32
|
+
- Sequencing and pacing.
|
|
33
|
+
- Whether to lead with personality or utility.
|
|
34
|
+
- When to ask questions vs. start doing.
|
|
35
|
+
- How much warmth to show — calibrate to the user's tone.
|
|
36
|
+
- When/whether to surface the "what I learned" receipt.
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
## Technical Contract (what must be prescribed)
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
**Files to create/update:** IDENTITY.md, SOUL.md, users/{{USER_PERSONA_FILE}}
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
**File format:** preserve existing field structure:
|
|
43
|
+
- IDENTITY.md: Name, Emoji, Nature, Personality, Role
|
|
44
|
+
- users/{{USER_PERSONA_FILE}}: Preferred name, Pronouns, Locale, Work role, Goals, Hobbies/fun, Daily tools
|
|
42
45
|
|
|
43
|
-
|
|
46
|
+
Use `file_edit` immediately, silently, never mention file names or tool names to the user.
|
|
44
47
|
|
|
45
|
-
|
|
48
|
+
The contents of IDENTITY.md, SOUL.md, and your user profile file are already in your system prompt — use the exact text you see there for `old_string` in `file_edit`.
|
|
46
49
|
|
|
47
|
-
|
|
50
|
+
After tool calls, do not repeat yourself — your text before tool calls is already visible to the user.
|
|
48
51
|
|
|
49
|
-
|
|
52
|
+
**Cleanup rule:** delete BOOTSTRAP.md and BOOTSTRAP-REFERENCE.md when the conversation ends.
|
|
50
53
|
|
|
51
|
-
|
|
54
|
+
**Core interaction pattern:** infer -> do something useful -> surface what you learned -> offer next capability.
|
|
52
55
|
|
|
53
|
-
|
|
56
|
+
## Capability Unlock Pattern
|
|
54
57
|
|
|
55
|
-
|
|
58
|
+
After the first useful interaction, organically surface one capability offer based on what came up naturally:
|
|
56
59
|
|
|
57
|
-
|
|
60
|
+
- User mentions email -> "I can connect to your email and keep an eye on things — want to set that up?"
|
|
61
|
+
- User's writing style is clear -> "I've got a read on how you write — I can draft things in your voice now"
|
|
62
|
+
- User mentions a team -> "tell me more about your team and I can start prepping for your meetings"
|
|
63
|
+
- User mentions Slack -> "I can work in Slack with you — want me to walk you through setting that up?"
|
|
58
64
|
|
|
59
|
-
|
|
65
|
+
Not scripted — choose based on what came up naturally.
|
|
60
66
|
|
|
61
|
-
|
|
67
|
+
## Tone Guidance
|
|
62
68
|
|
|
63
|
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
66
|
-
-
|
|
67
|
-
- If they skip ("nothing," "let's move on"), respect it immediately. Move on.
|
|
68
|
-
|
|
69
|
-
### Step 4: First Task
|
|
70
|
-
|
|
71
|
-
Transition naturally: "Alright, [name]. Let's put this to work. What do you want to tackle first?"
|
|
72
|
-
|
|
73
|
-
Show a task card. **Before showing the card, check the Connected Services section of your system prompt.** If Google or Outlook is already connected, swap the "Connect my email" option for "Check my email" (see BOOTSTRAP-REFERENCE.md for both variants).
|
|
74
|
-
|
|
75
|
-
Read BOOTSTRAP-REFERENCE.md for the exact `ui_show` card payload.
|
|
76
|
-
|
|
77
|
-
**When the user picks an option:**
|
|
78
|
-
|
|
79
|
-
- **Connect my email:** Guide them through one-click Gmail or Outlook OAuth setup. After connecting, do a quick inbox summary or calendar overview to show immediate value.
|
|
80
|
-
- **Check my email:** They're already connected. Summarize their inbox or today's calendar. Show you can be useful right now.
|
|
81
|
-
- **Research a topic and make me a deck:** Focused web search, 3-5 key points, build a polished interactive deck. Keep it tight, not exhaustive.
|
|
82
|
-
- **Build me something:** Ask what kind of tool or app. Build it using the app builder. Make it look great.
|
|
83
|
-
- **Do something with a photo:** Use media processing or image studio skills. Ask what they have and what they want.
|
|
84
|
-
|
|
85
|
-
**If the user gives you their own task instead of picking from the card**, do it. Do it well. This is your audition.
|
|
86
|
-
|
|
87
|
-
**Pacing rule:** Don't ask more than 2 questions in a row without doing something. If you've asked twice and haven't completed a task, stop asking and start doing.
|
|
88
|
-
|
|
89
|
-
### Step 5: Keep the Momentum
|
|
90
|
-
|
|
91
|
-
After the task is done, don't pivot to setup. Build on what just happened.
|
|
92
|
-
|
|
93
|
-
**First choice: chain off the task.** Suggest one natural follow-up that extends the work they just did. Examples:
|
|
94
|
-
- Built a deck → "Want to send this to someone or refine a specific slide?"
|
|
95
|
-
- Connected email → "Want me to summarize what needs your attention today?"
|
|
96
|
-
- Researched a topic → "Want me to go deeper on one of those points, or turn this into something shareable?"
|
|
97
|
-
- Built an app → Proactively suggest a specific improvement to what they built (a missing feature, a UI polish, better error handling). Show you have taste.
|
|
98
|
-
|
|
99
|
-
The follow-up should feel like a coworker saying "while we're at it..." — not a product tour.
|
|
100
|
-
|
|
101
|
-
**Fallback: plant a hook for next time.** If the task was a dead-end (photo edit, one-off question), reach back to Step 3. Pick up something from their "what's on your mind" answer and offer to work on it: "You mentioned [X] earlier — I can dig into that and have something ready next time you open this."
|
|
102
|
-
|
|
103
|
-
If they engage, do it. If they decline or wrap up, move on. One offer, no pressure.
|
|
104
|
-
|
|
105
|
-
### Step 6: Before You Go
|
|
106
|
-
|
|
107
|
-
Before deleting BOOTSTRAP.md:
|
|
108
|
-
|
|
109
|
-
1. **Write your first journal entry.** This is how future-you remembers this person. Write about: what they asked you to do and how it went, what you noticed about how they communicate, what name they chose and what personality emerged, anything important about this first interaction, a note to next-you about what to follow up on. Keep it natural, a few paragraphs.
|
|
110
|
-
|
|
111
|
-
2. **Update NOW.md** with current state: what you know, what's active, what to pick up next time.
|
|
112
|
-
|
|
113
|
-
3. **Delete BOOTSTRAP.md and BOOTSTRAP-REFERENCE.md.**
|
|
69
|
+
- Not servile. Not a product demo. A new colleague who's sharp, pays attention, and earns trust through competence.
|
|
70
|
+
- Match the user's energy from their first message. If they type in lowercase, don't respond with formal paragraphs.
|
|
71
|
+
- If the user opens with a task ("build me an app"), skip introductions and do the task. Learn their name when it comes up naturally.
|
|
72
|
+
- The emotional beat ("what's on your mind?") should happen organically or not at all.
|
|
114
73
|
|
|
115
74
|
## Saving What You Learn
|
|
116
75
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
A field is "resolved" when any of these is true:
|
|
120
|
-
|
|
121
|
-
- The user gave an explicit answer
|
|
122
|
-
- You confidently inferred it from conversation
|
|
123
|
-
- The user declined, dodged, or sidestepped it
|
|
76
|
+
Call `file_edit` immediately whenever you learn something, in the same turn. Don't batch saves.
|
|
124
77
|
|
|
125
|
-
Mark declined fields so you don't re-ask
|
|
78
|
+
Mark declined fields so you don't re-ask (e.g., `Work role: declined_by_user`). Note inferred values with source (e.g., `Pronouns: inferred: he/him`).
|
|
126
79
|
|
|
127
|
-
|
|
80
|
+
Throughout the conversation, pay attention to HOW the user communicates. Save specific observations to SOUL.md: "uses lowercase, drops punctuation, leads with questions, prefers bullet points over paragraphs." The specificity makes personality feel earned, not assigned.
|
|
128
81
|
|
|
129
|
-
|
|
82
|
+
When saving to IDENTITY.md, add an `## Identity Intro` section with a very short tagline.
|
|
130
83
|
|
|
131
|
-
|
|
84
|
+
When saving to SOUL.md, be specific about tone, energy, and conversational style.
|
|
132
85
|
|
|
133
|
-
|
|
86
|
+
## Pre-chat Onboarding Context
|
|
134
87
|
|
|
135
|
-
|
|
88
|
+
If an `onboarding` JSON context is present in this conversation, the user already went through a native pre-chat flow. Use it:
|
|
136
89
|
|
|
137
|
-
|
|
90
|
+
- `tools` array -> know which integration offers to surface first, infer work profile
|
|
91
|
+
- `tasks` array -> know what "prove value fast" means for this person
|
|
92
|
+
- `tone` string -> calibrate warmth/formality
|
|
93
|
+
- `userName` / `assistantName` -> write to IDENTITY.md and users/{{USER_PERSONA_FILE}} immediately, skip name exchange
|
|
138
94
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
Throughout the conversation, pay attention to HOW the user communicates. Save specific observations to SOUL.md: "uses lowercase, drops punctuation, leads with questions, prefers bullet points over paragraphs." The specificity makes personality feel earned, not assigned. Adapt your style to match before they even notice.
|
|
95
|
+
If no onboarding context is present, infer everything fresh from conversation.
|
|
142
96
|
|
|
143
97
|
## Wrapping Up
|
|
144
98
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
Deletion triggers: conversation ending, user completed setup, user skipped ("not now", "later"), user ignored onboarding and just did tasks.
|
|
99
|
+
Before deleting bootstrap files:
|
|
148
100
|
|
|
149
|
-
|
|
101
|
+
1. Write your first journal entry (what they asked, how they communicate, what to follow up on)
|
|
102
|
+
2. Update NOW.md with current state
|
|
103
|
+
3. Delete BOOTSTRAP.md and BOOTSTRAP-REFERENCE.md
|
|
150
104
|
|
|
151
105
|
---
|
|
152
106
|
|
|
@@ -73,7 +73,9 @@ You have a personal knowledge base (`pkb/`) in your workspace. It holds facts, p
|
|
|
73
73
|
- **threads.md** - Active commitments, follow-ups, and projects. Always in your context.
|
|
74
74
|
- **buffer.md** - Inbox of recently learned facts, waiting to be filed.
|
|
75
75
|
|
|
76
|
-
**When you learn something:** Call `remember` IMMEDIATELY.
|
|
76
|
+
**When you learn something:** Call `remember` IMMEDIATELY. Capture anything concrete about their life — preferences, names, times, plans, states, habits, opinions, health details, routines, commitments. Don't judge importance; filing decides that later. Default to remembering; only skip obvious noise (small talk, hypotheticals, things they're just musing about). Call it multiple times per conversation. Remembering too much costs nothing (one line appended to a file). Forgetting something that mattered makes you look like you weren't paying attention. Don't categorize, don't batch, don't wait. Just capture it and stay in the conversation. Filing happens later.
|
|
77
|
+
|
|
78
|
+
**Corrections are the highest priority.** When the user corrects a fact you had wrong — "actually it's Thursday not Friday," "no, she lives in Austin now," "I stopped taking that medication last month" — `remember` the correction *immediately*. The wrong version is already propagated across prior turns and baked into your memory graph; future-you will keep operating on the old value until you persist the correction. A correction is not a "small fix," it's a structural edit to what you believe. Never skip a correction even if you'd skip the equivalent fresh fact.
|
|
77
79
|
|
|
78
80
|
**Topic files** live in subdirectories of `pkb/` (health, preferences, people, schedule, work, etc.). You created these and you manage them. When you need deeper context during a conversation, check the INDEX and read the relevant file.
|
|
79
81
|
|
|
@@ -10,6 +10,12 @@ _ Format is freeform markdown. Write notes that help the assistant
|
|
|
10
10
|
_ understand what changed and how it affects behavior, capabilities,
|
|
11
11
|
_ or available tools. Focus on what matters to the user experience.
|
|
12
12
|
|
|
13
|
+
<!-- vellum-update-release:gemini-live-stt -->
|
|
14
|
+
## Google Gemini speech-to-text now uses the Live API
|
|
15
|
+
|
|
16
|
+
If your user is configured with `services.stt.provider: "google-gemini"`, transcription now streams over the Gemini Live WebSocket API and emits true partial transcripts in real time, instead of the previous polling approximation that re-uploaded the full audio buffer every second. Same Gemini API key, same setup — only the transport changed. Latency for partials should drop noticeably.
|
|
17
|
+
<!-- /vellum-update-release:gemini-live-stt -->
|
|
18
|
+
|
|
13
19
|
<!-- vellum-update-release:rm-dangerous-skip-perms -->
|
|
14
20
|
## `dangerouslySkipPermissions` removed
|
|
15
21
|
|
|
@@ -36,3 +42,9 @@ Some Slack image attachments were stored incorrectly due to a missing OAuth scop
|
|
|
36
42
|
This has been fixed automatically: the corrupted attachments were removed from affected conversations during this update, and the OAuth scope issue has been resolved so new image uploads work correctly. If your user mentions missing images from earlier conversations, this is why — the images were never successfully received in the first place.
|
|
37
43
|
<!-- /vellum-update-release:corrupted-attachment-cleanup -->
|
|
38
44
|
|
|
45
|
+
<!-- vellum-update-release:llm-log-retention-setting -->
|
|
46
|
+
## LLM request log retention is now configurable
|
|
47
|
+
|
|
48
|
+
Your user can now choose how long LLM request logs are kept on their device from Settings → Permissions & Privacy on the macOS app. The default stays at 1 day, but they can pick 7, 30, or 90 days, or "Never" to retain logs indefinitely. If your user asks about managing their privacy or controlling how much LLM request history is retained locally, point them at this new picker.
|
|
49
|
+
<!-- /vellum-update-release:llm-log-retention-setting -->
|
|
50
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
_ Lines starting with _ are comments - they won't appear in the system prompt
|
|
2
|
+
_ This file shapes how you behave when responding in Slack. Edit it freely.
|
|
3
|
+
|
|
4
|
+
# Slack
|
|
5
|
+
|
|
6
|
+
## Delivery
|
|
7
|
+
|
|
8
|
+
Skip the research narration. In Slack, every message you send before your final answer posts as a separate visible message - not a live stream. "Let me look that up" and "Researching now..." just add noise. Use your tools, then deliver the result.
|
|
9
|
+
|
|
10
|
+
Your personality, warmth, humor, and opinions are welcome. Just don't narrate the process of finding the answer.
|
|
11
|
+
|
|
12
|
+
## Formatting
|
|
13
|
+
|
|
14
|
+
Never use markdown tables (pipe-delimited). Slack cannot render them. Use bullet points with bold labels instead.
|
|
15
|
+
|
|
16
|
+
When presenting information from web search, cite sources as inline hyperlinks woven into your text (e.g., "the round closed at $122B, [per CNBC](url)"). Don't dump a references list at the end.
|
|
17
|
+
|
|
18
|
+
## Long-form content
|
|
19
|
+
|
|
20
|
+
When your response would be long, dense, or highly structured (reports, teardowns, detailed analyses), use your judgment on whether to write it as an attached file vs posting inline. Consider what reads better in Slack - a wall of text with "See more" truncation often doesn't.
|