@vellumai/assistant 0.8.0 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +11 -0
- package/ARCHITECTURE.md +2 -7
- package/Dockerfile +80 -5
- package/README.md +2 -2
- package/bun.lock +11 -1
- package/docker-entrypoint.sh +21 -0
- package/docker-init-apt-root.sh +94 -0
- package/docker-kata-apt-env.sh +39 -0
- package/docs/plugins.md +88 -47
- package/docs/skills.md +9 -7
- package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
- package/eslint-rules/cli-no-daemon-internals.js +283 -0
- package/eslint.config.mjs +12 -0
- package/examples/plugins/echo/README.md +27 -27
- package/examples/plugins/echo/package.json +3 -0
- package/examples/plugins/echo/register.ts +31 -31
- package/knip.json +2 -1
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
- package/node_modules/@vellumai/slack-text/src/index.test.ts +114 -14
- package/node_modules/@vellumai/slack-text/src/index.ts +82 -18
- package/openapi.yaml +4462 -991
- package/package.json +5 -1
- package/scripts/generate-openapi.ts +135 -14
- package/scripts/sync-llm-catalog.ts +165 -0
- package/scripts/sync-web-search-catalog.ts +129 -0
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
- package/src/__tests__/agent-image-optimize.test.ts +11 -3
- package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +131 -0
- package/src/__tests__/anthropic-provider.test.ts +137 -2
- package/src/__tests__/app-builder-tool-scripts.test.ts +9 -3
- package/src/__tests__/app-control-flow.test.ts +7 -0
- package/src/__tests__/app-executors.test.ts +220 -4
- package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
- package/src/__tests__/auto-analysis-end-to-end.test.ts +35 -0
- package/src/__tests__/avatar-identity-sync.test.ts +87 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
- package/src/__tests__/btw-routes.test.ts +1 -0
- package/src/__tests__/bundled-asset.test.ts +6 -6
- package/src/__tests__/call-site-routing-provider.test.ts +172 -45
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
- package/src/__tests__/channel-availability-routes.test.ts +206 -0
- package/src/__tests__/channel-delivery-store.test.ts +289 -1
- package/src/__tests__/channel-policy.test.ts +12 -0
- package/src/__tests__/checker.test.ts +89 -0
- package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -1
- package/src/__tests__/clawhub.test.ts +75 -16
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +35 -7
- package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
- package/src/__tests__/compactor-tail-resolution.test.ts +41 -0
- package/src/__tests__/config-loader-backfill.test.ts +526 -102
- package/src/__tests__/config-loader-corrupt.test.ts +68 -0
- package/src/__tests__/config-loader-platform-defaults.test.ts +77 -23
- package/src/__tests__/config-schema-cmd.test.ts +63 -29
- package/src/__tests__/config-schema.test.ts +35 -3
- package/src/__tests__/config-set-platform-guard.test.ts +75 -152
- package/src/__tests__/config-set-route.test.ts +278 -0
- package/src/__tests__/config-sounds-sync.test.ts +97 -0
- package/src/__tests__/config-watcher-skill-reseed.test.ts +453 -0
- package/src/__tests__/config-watcher.test.ts +6 -0
- package/src/__tests__/contacts-tools.test.ts +51 -199
- package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
- package/src/__tests__/context-search-agent-runner.test.ts +22 -138
- package/src/__tests__/context-search-conversations-source.test.ts +159 -18
- package/src/__tests__/context-search-fanout.test.ts +20 -157
- package/src/__tests__/context-search-memory-v2-source.test.ts +3 -4
- package/src/__tests__/context-search-types.test.ts +7 -2
- package/src/__tests__/context-search-workspace-source.test.ts +7 -0
- package/src/__tests__/context-token-estimator.test.ts +1 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +4 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +93 -92
- package/src/__tests__/conversation-agent-loop.test.ts +2 -0
- package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
- package/src/__tests__/conversation-error.test.ts +80 -3
- package/src/__tests__/conversation-fork-crud.test.ts +323 -1
- package/src/__tests__/conversation-inference-profile-route.test.ts +54 -18
- package/src/__tests__/conversation-init.benchmark.test.ts +1 -0
- package/src/__tests__/conversation-lifecycle.test.ts +297 -0
- package/src/__tests__/conversation-message-sync-tags.test.ts +97 -0
- package/src/__tests__/conversation-pairing.test.ts +54 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
- package/src/__tests__/conversation-process-callsite.test.ts +25 -2
- package/src/__tests__/conversation-provider-retry-repair.test.ts +5 -1
- package/src/__tests__/conversation-queue.test.ts +4 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +80 -13
- package/src/__tests__/conversation-slash-commands.test.ts +194 -2
- package/src/__tests__/conversation-slash-queue.test.ts +59 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +4 -1
- package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
- package/src/__tests__/conversation-surfaces-table-action.test.ts +360 -0
- package/src/__tests__/conversation-sync-tags.test.ts +235 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
- package/src/__tests__/credential-security-invariants.test.ts +8 -8
- package/src/__tests__/daemon-credential-client.test.ts +56 -1
- package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
- package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
- package/src/__tests__/db-proxy-transaction.test.ts +206 -0
- package/src/__tests__/db-slack-external-content-normalization.test.ts +301 -0
- package/src/__tests__/delete-managed-skill-tool.test.ts +55 -13
- package/src/__tests__/disk-pressure-tools.test.ts +1 -0
- package/src/__tests__/dm-backfill.test.ts +121 -10
- package/src/__tests__/document-tool-security.test.ts +258 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/edit-propagation.test.ts +33 -0
- package/src/__tests__/empty-response-pipeline.test.ts +0 -4
- package/src/__tests__/external-plugin-loader.test.ts +482 -0
- package/src/__tests__/filing-service.test.ts +163 -3
- package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/get-skill-detail-audit.test.ts +0 -4
- package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +42 -69
- package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
- package/src/__tests__/heartbeat-service.test.ts +50 -233
- package/src/__tests__/helpers/tar-fixtures.ts +39 -0
- package/src/__tests__/helpers/wait-for.ts +21 -0
- package/src/__tests__/history-repair-pipeline.test.ts +0 -3
- package/src/__tests__/history-repair.test.ts +162 -0
- package/src/__tests__/host-app-control-proxy.test.ts +365 -1
- package/src/__tests__/host-app-control-routes.test.ts +247 -1
- package/src/__tests__/host-browser-proxy.test.ts +416 -20
- package/src/__tests__/host-browser-routes.test.ts +325 -33
- package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
- package/src/__tests__/image-credentials.test.ts +1 -1
- package/src/__tests__/inbound-slack-persistence.test.ts +2 -0
- package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
- package/src/__tests__/inference-profile-reaper.test.ts +156 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +410 -0
- package/src/__tests__/inference-profile-session-ipc.test.ts +248 -0
- package/src/__tests__/injector-chain.test.ts +10 -8
- package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
- package/src/__tests__/install-skill-routing.test.ts +157 -39
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +107 -3
- package/src/__tests__/list-messages-page-latest.test.ts +55 -0
- package/src/__tests__/llm-call-pipeline.test.ts +0 -3
- package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
- package/src/__tests__/llm-catalog-parity.test.ts +190 -2
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +222 -0
- package/src/__tests__/llm-request-log-source-factory.test.ts +100 -0
- package/src/__tests__/llm-resolver.test.ts +46 -0
- package/src/__tests__/llm-usage-store.test.ts +114 -0
- package/src/__tests__/managed-profile-guard.test.ts +145 -14
- package/src/__tests__/managed-skill-lifecycle.test.ts +109 -18
- package/src/__tests__/managed-store.test.ts +84 -192
- package/src/__tests__/mcp-auth-routes.test.ts +1 -0
- package/src/__tests__/mcp-cli.test.ts +182 -220
- package/src/__tests__/mcp-health-check.test.ts +56 -27
- package/src/__tests__/media-generate-image.test.ts +1 -1
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
- package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -2
- package/src/__tests__/message-complete-display-id.test.ts +175 -0
- package/src/__tests__/messages-after-tiebreaker.test.ts +122 -0
- package/src/__tests__/notification-platform-adapter.test.ts +229 -0
- package/src/__tests__/oauth-cli.test.ts +38 -2009
- package/src/__tests__/oauth-commands-routes.test.ts +863 -0
- package/src/__tests__/oauth-connect-routes.test.ts +174 -11
- package/src/__tests__/oauth-provider-profiles.test.ts +9 -0
- package/src/__tests__/oauth-providers-routes.test.ts +14 -10
- package/src/__tests__/openai-provider.test.ts +24 -0
- package/src/__tests__/openai-responses-cutover-guard.test.ts +48 -19
- package/src/__tests__/openai-responses-provider.test.ts +17 -0
- package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -2
- package/src/__tests__/persistence-pipeline.test.ts +0 -2
- package/src/__tests__/{managed-proxy-context.test.ts → platform-proxy-context.test.ts} +1 -1
- package/src/__tests__/platform.test.ts +2 -0
- package/src/__tests__/plugin-api-shim.test.ts +125 -0
- package/src/__tests__/plugin-bootstrap.test.ts +41 -38
- package/src/__tests__/plugin-external-api.test.ts +68 -0
- package/src/__tests__/plugin-registry.test.ts +0 -77
- package/src/__tests__/plugin-route-contribution.test.ts +31 -4
- package/src/__tests__/plugin-skill-contribution.test.ts +0 -2
- package/src/__tests__/plugin-tool-contribution.test.ts +47 -18
- package/src/__tests__/plugin-types.test.ts +15 -23
- package/src/__tests__/process-message-background-slack.test.ts +53 -0
- package/src/__tests__/process-message-display-content.test.ts +421 -0
- package/src/__tests__/profile-entry-status.test.ts +43 -0
- package/src/__tests__/provider-catalog-visibility.test.ts +142 -0
- package/src/__tests__/provider-error-scenarios.test.ts +111 -0
- package/src/__tests__/{provider-managed-proxy-integration.test.ts → provider-platform-proxy-integration.test.ts} +20 -12
- package/src/__tests__/provider-registry-ollama.test.ts +12 -4
- package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
- package/src/__tests__/relay-server.test.ts +118 -0
- package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +65 -13
- package/src/__tests__/schedule-retry.test.ts +56 -4
- package/src/__tests__/schedule-routes.test.ts +151 -0
- package/src/__tests__/schedule-store.test.ts +94 -0
- package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
- package/src/__tests__/scheduler-recurrence.test.ts +87 -34
- package/src/__tests__/scheduler-reuse-conversation.test.ts +208 -5
- package/src/__tests__/scheduler-wake.test.ts +0 -63
- package/src/__tests__/schema-transforms.test.ts +20 -0
- package/src/__tests__/search-skills-unified.test.ts +0 -5
- package/src/__tests__/secret-allowlist.test.ts +1 -0
- package/src/__tests__/{secret-routes-managed-proxy.test.ts → secret-routes-platform-proxy.test.ts} +12 -4
- package/src/__tests__/server-history-render.test.ts +43 -0
- package/src/__tests__/shell-credential-ref.test.ts +95 -3
- package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -12
- package/src/__tests__/skill-load-tool.test.ts +29 -93
- package/src/__tests__/skill-memory.test.ts +23 -3
- package/src/__tests__/skills-file-content-endpoint.test.ts +9 -38
- package/src/__tests__/skills-files-catalog-fallback.test.ts +0 -3
- package/src/__tests__/skills-install-extract.test.ts +49 -38
- package/src/__tests__/skills-install-staging.test.ts +159 -0
- package/src/__tests__/skills-uninstall.test.ts +9 -41
- package/src/__tests__/skills.test.ts +51 -58
- package/src/__tests__/slack-channel-config.test.ts +9 -0
- package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
- package/src/__tests__/subagent-tool-filtering.test.ts +50 -0
- package/src/__tests__/suggestion-routes.test.ts +3 -3
- package/src/__tests__/sync-message-contract.test.ts +63 -0
- package/src/__tests__/system-prompt.test.ts +737 -63
- package/src/__tests__/task-scheduler.test.ts +88 -23
- package/src/__tests__/terminal-tools.test.ts +28 -1
- package/src/__tests__/thread-backfill.test.ts +557 -27
- package/src/__tests__/title-generate-pipeline.test.ts +0 -13
- package/src/__tests__/token-estimate-pipeline.test.ts +0 -3
- package/src/__tests__/tool-error-pipeline.test.ts +0 -3
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -5
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -1
- package/src/__tests__/tool-executor.test.ts +16 -4
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -12
- package/src/__tests__/turn-events-store.test.ts +256 -0
- package/src/__tests__/twilio-routes.test.ts +4 -0
- package/src/__tests__/update-bulletin-job.test.ts +96 -193
- package/src/__tests__/usage-cli.test.ts +11 -73
- package/src/__tests__/user-plugin-loader.test.ts +143 -5
- package/src/__tests__/vercel-config.test.ts +168 -0
- package/src/__tests__/voice-session-bridge.test.ts +198 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +108 -0
- package/src/__tests__/web-search.test.ts +303 -2
- package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
- package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +170 -0
- package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +53 -20
- package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +241 -0
- package/src/__tests__/workspace-migration-073-repair-recall-callsite-empty-profile.test.ts +153 -0
- package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
- package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
- package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
- package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
- package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
- package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
- package/src/__tests__/workspace-migration-085-memory-v2-bm25-b-reembed-disabled-v2-pages.test.ts +220 -0
- package/src/__tests__/workspace-migration-086-revert-stale-gemini-mis-rewrites.test.ts +269 -0
- package/src/__tests__/workspace-migration-remove-legacy-skills-index.test.ts +309 -0
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
- package/src/__tests__/workspace-migrations-runner.test.ts +111 -3
- package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
- package/src/acp/__tests__/helpers/which-stub.ts +4 -2
- package/src/acp/resolve-agent.test.ts +25 -0
- package/src/acp/resolve-agent.ts +13 -2
- package/src/acp/session-manager.ts +14 -0
- package/src/agent/image-optimize.ts +13 -5
- package/src/approvals/guardian-request-resolvers.ts +32 -87
- package/src/calls/relay-server.ts +35 -0
- package/src/calls/relay-setup-router.ts +36 -0
- package/src/calls/types.ts +1 -0
- package/src/calls/voice-session-bridge.ts +74 -36
- package/src/channels/config.ts +14 -1
- package/src/channels/types.ts +109 -0
- package/src/cli/AGENTS.md +164 -4
- package/src/cli/__tests__/notifications.test.ts +54 -0
- package/src/cli/__tests__/unknown-command.test.ts +24 -0
- package/src/cli/commands/__tests__/avatar.test.ts +540 -0
- package/src/cli/commands/__tests__/backup.test.ts +236 -776
- package/src/cli/commands/__tests__/cache.test.ts +1 -1
- package/src/cli/commands/__tests__/changelog.test.ts +578 -0
- package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
- package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
- package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
- package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
- package/src/cli/commands/__tests__/email-core.test.ts +579 -0
- package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
- package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
- package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
- package/src/cli/commands/__tests__/schedules.test.ts +491 -0
- package/src/cli/commands/__tests__/skills.test.ts +563 -0
- package/src/cli/commands/__tests__/status.test.ts +249 -0
- package/src/cli/commands/__tests__/stt.test.ts +320 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
- package/src/cli/commands/__tests__/tts.test.ts +321 -0
- package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
- package/src/cli/commands/attachment.ts +8 -3
- package/src/cli/commands/audit.ts +95 -64
- package/src/cli/commands/auth.ts +61 -58
- package/src/cli/commands/avatar.ts +276 -390
- package/src/cli/commands/backup.ts +409 -505
- package/src/cli/commands/bash.ts +9 -5
- package/src/cli/commands/browser.ts +28 -9
- package/src/cli/commands/cache.ts +9 -4
- package/src/cli/commands/changelog.ts +478 -0
- package/src/cli/commands/channel-verification-sessions.ts +238 -317
- package/src/cli/commands/clients.ts +8 -3
- package/src/cli/commands/completions.ts +9 -9
- package/src/cli/commands/config.ts +102 -72
- package/src/cli/commands/contacts.ts +575 -696
- package/src/cli/commands/conversations-defer.ts +17 -69
- package/src/cli/commands/conversations-import.ts +90 -253
- package/src/cli/commands/conversations.ts +429 -434
- package/src/cli/commands/credential-execution.ts +9 -6
- package/src/cli/commands/credentials.ts +456 -736
- package/src/cli/commands/default-action.ts +10 -53
- package/src/cli/commands/domain.ts +128 -206
- package/src/cli/commands/email.ts +606 -794
- package/src/cli/commands/gateway.ts +8 -1
- package/src/cli/commands/image-generation.ts +157 -205
- package/src/cli/commands/inference-providers.ts +352 -0
- package/src/cli/commands/inference-session.ts +415 -0
- package/src/cli/commands/inference.ts +87 -65
- package/src/cli/commands/keys.ts +8 -3
- package/src/cli/commands/mcp.ts +103 -287
- package/src/cli/commands/memory-v2.ts +162 -516
- package/src/cli/commands/notifications.ts +342 -304
- package/src/cli/commands/oauth/apps.ts +292 -261
- package/src/cli/commands/oauth/connect.ts +176 -297
- package/src/cli/commands/oauth/disconnect.ts +16 -215
- package/src/cli/commands/oauth/index.ts +49 -45
- package/src/cli/commands/oauth/mode.ts +43 -199
- package/src/cli/commands/oauth/ping.ts +17 -125
- package/src/cli/commands/oauth/providers.ts +732 -921
- package/src/cli/commands/oauth/request.ts +60 -350
- package/src/cli/commands/oauth/shared.ts +11 -121
- package/src/cli/commands/oauth/status.ts +31 -121
- package/src/cli/commands/oauth/token.ts +13 -55
- package/src/cli/commands/pending.ts +19 -10
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
- package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
- package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
- package/src/cli/commands/platform/connect.ts +16 -80
- package/src/cli/commands/platform/disconnect.ts +14 -112
- package/src/cli/commands/platform/index.ts +177 -246
- package/src/cli/commands/plugins.ts +185 -0
- package/src/cli/commands/routes.ts +153 -336
- package/src/cli/commands/schedules.ts +391 -0
- package/src/cli/commands/sequence.ts +316 -360
- package/src/cli/commands/skills.ts +449 -671
- package/src/cli/commands/status.ts +58 -37
- package/src/cli/commands/stt.ts +94 -262
- package/src/cli/commands/task.ts +14 -40
- package/src/cli/commands/telemetry.ts +40 -0
- package/src/cli/commands/trust.ts +8 -3
- package/src/cli/commands/tts.ts +162 -167
- package/src/cli/commands/ui.ts +35 -42
- package/src/cli/commands/usage.ts +188 -126
- package/src/cli/commands/watchers.ts +8 -3
- package/src/cli/commands/webhooks.ts +99 -193
- package/src/cli/lib/__tests__/cli-colors.test.ts +48 -0
- package/src/cli/lib/__tests__/confirm-prompt.test.ts +159 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +355 -0
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +154 -0
- package/src/cli/lib/__tests__/register-command.test.ts +85 -0
- package/src/cli/lib/__tests__/uninstall-plugin.test.ts +124 -0
- package/src/cli/lib/__tests__/unknown-command.test.ts +106 -0
- package/src/cli/lib/cli-colors.ts +12 -0
- package/src/cli/lib/confirm-prompt.ts +79 -0
- package/src/cli/lib/daemon-credential-client.ts +4 -5
- package/src/cli/lib/install-from-github.ts +304 -0
- package/src/cli/lib/list-installed-plugins.ts +137 -0
- package/src/cli/lib/nested-value.ts +44 -0
- package/src/cli/lib/open-browser.ts +36 -0
- package/src/cli/lib/register-command.ts +19 -0
- package/src/cli/lib/time-ago.ts +34 -0
- package/src/cli/lib/uninstall-plugin.ts +82 -0
- package/src/cli/lib/unknown-command.ts +111 -0
- package/src/cli/program.ts +40 -6
- package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
- package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
- package/src/cli/utils/conversation-id.ts +30 -0
- package/src/cli/utils/parse-duration.ts +41 -0
- package/src/config/acp-defaults.test.ts +5 -1
- package/src/config/acp-defaults.ts +11 -4
- package/src/config/bundled-skills/acp/TOOLS.json +2 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +23 -21
- package/src/config/bundled-skills/app-builder/TOOLS.json +7 -0
- package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +15 -52
- package/src/config/bundled-skills/contacts/SKILL.md +12 -45
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
- package/src/config/bundled-skills/document/SKILL.md +23 -3
- package/src/config/bundled-skills/document/TOOLS.json +53 -0
- package/src/config/bundled-skills/document/tools/document-delete.ts +12 -0
- package/src/config/bundled-skills/document/tools/document-list.ts +12 -0
- package/src/config/bundled-skills/document/tools/document-read.ts +12 -0
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
- package/src/config/bundled-skills/skill-management/SKILL.md +2 -2
- package/src/config/bundled-skills/skill-management/TOOLS.json +7 -7
- package/src/config/bundled-tool-registry.ts +6 -2
- package/src/config/feature-flag-registry.json +57 -1
- package/src/config/llm-resolver.ts +16 -1
- package/src/config/loader.ts +140 -52
- package/src/config/raw-config-utils.ts +2 -30
- package/src/config/schema.ts +8 -7
- package/src/config/schemas/__tests__/llm-request-logs.test.ts +36 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
- package/src/config/schemas/call-site-catalog.ts +29 -7
- package/src/config/schemas/channels.ts +8 -0
- package/src/config/schemas/compaction.ts +28 -0
- package/src/config/schemas/heartbeat.ts +9 -0
- package/src/config/schemas/llm-request-logs.ts +81 -0
- package/src/config/schemas/llm.ts +55 -2
- package/src/config/schemas/memory-retrieval.ts +18 -0
- package/src/config/schemas/memory-retrospective.ts +48 -0
- package/src/config/schemas/memory-v2.ts +32 -1
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/services.ts +15 -12
- package/src/config/schemas/tools.ts +14 -0
- package/src/config/seed-inference-profiles.ts +195 -134
- package/src/config/skills.ts +3 -96
- package/src/contacts/contact-store.ts +0 -61
- package/src/context/compactor.ts +1047 -0
- package/src/context/token-estimator.ts +2 -2
- package/src/context/window-manager.ts +197 -1334
- package/src/credential-execution/managed-catalog.ts +37 -0
- package/src/credential-health/credential-health-service.ts +280 -19
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +113 -0
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +138 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +183 -4
- package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
- package/src/daemon/approval-generators.ts +26 -30
- package/src/daemon/config-watcher.ts +94 -29
- package/src/daemon/conversation-agent-loop-handlers.ts +24 -0
- package/src/daemon/conversation-agent-loop.ts +293 -103
- package/src/daemon/conversation-error.ts +188 -33
- package/src/daemon/conversation-lifecycle.ts +80 -26
- package/src/daemon/conversation-messaging.ts +25 -6
- package/src/daemon/conversation-process.ts +85 -31
- package/src/daemon/conversation-runtime-assembly.ts +30 -6
- package/src/daemon/conversation-slash.ts +184 -25
- package/src/daemon/conversation-store.ts +24 -10
- package/src/daemon/conversation-surfaces.ts +76 -12
- package/src/daemon/conversation-tool-setup.ts +63 -21
- package/src/daemon/conversation.ts +81 -10
- package/src/daemon/external-plugins-bootstrap.ts +231 -185
- package/src/daemon/first-greeting.ts +22 -2
- package/src/daemon/guardian-action-generators.ts +7 -22
- package/src/daemon/handlers/config-model.ts +13 -130
- package/src/daemon/handlers/config-slack-channel.ts +25 -10
- package/src/daemon/handlers/config-vercel.ts +3 -1
- package/src/daemon/handlers/shared.ts +14 -5
- package/src/daemon/handlers/skills.ts +166 -84
- package/src/daemon/history-repair.ts +61 -7
- package/src/daemon/host-app-control-proxy.ts +129 -29
- package/src/daemon/host-bash-proxy.ts +85 -158
- package/src/daemon/host-browser-proxy.ts +96 -35
- package/src/daemon/host-proxy-base.ts +13 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -1
- package/src/daemon/identity-helpers.ts +19 -0
- package/src/daemon/lifecycle.ts +79 -70
- package/src/daemon/meet-host-supervisor.ts +20 -19
- package/src/daemon/memory-v2-startup.ts +58 -2
- package/src/daemon/message-protocol.ts +7 -0
- package/src/daemon/message-types/bookmarks.ts +18 -0
- package/src/daemon/message-types/conversations.ts +37 -9
- package/src/daemon/message-types/messages.ts +70 -1
- package/src/daemon/message-types/subagents.ts +1 -0
- package/src/daemon/message-types/sync.ts +61 -0
- package/src/daemon/pkb-reminder-builder.test.ts +54 -13
- package/src/daemon/pkb-reminder-builder.ts +21 -7
- package/src/daemon/plugin-source-watcher.ts +146 -0
- package/src/daemon/process-message.ts +77 -26
- package/src/daemon/server.ts +34 -20
- package/src/daemon/shutdown-handlers.ts +0 -2
- package/src/daemon/skill-memory-refresh.ts +29 -0
- package/src/daemon/tool-setup-types.ts +9 -0
- package/src/daemon/tool-side-effects.ts +6 -4
- package/src/daemon/wake-target-adapter.ts +11 -0
- package/src/documents/document-store.ts +221 -3
- package/src/embedded/plugin-api.ts +40 -0
- package/src/export/transcript-formatter.ts +61 -2
- package/src/filing/filing-service.ts +79 -53
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +444 -0
- package/src/heartbeat/heartbeat-run-store.ts +3 -1
- package/src/heartbeat/heartbeat-service.ts +189 -127
- package/src/home/__tests__/feed-types.test.ts +99 -127
- package/src/home/__tests__/feed-writer.test.ts +77 -278
- package/src/home/__tests__/post-connect-feed.test.ts +9 -12
- package/src/home/feed-types.ts +41 -73
- package/src/home/feed-writer.ts +25 -156
- package/src/home/post-connect-feed.ts +2 -3
- package/src/index.ts +18 -1
- package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
- package/src/ipc/__tests__/email-ipc.test.ts +506 -0
- package/src/ipc/__tests__/exit-helper.test.ts +104 -0
- package/src/ipc/__tests__/streaming-client.test.ts +237 -0
- package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
- package/src/ipc/assistant-server.ts +55 -6
- package/src/ipc/cli-client.ts +370 -50
- package/src/ipc/routes/db-proxy-transaction.ts +151 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
- package/src/ipc/skill-routes/events.ts +30 -3
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
- package/src/live-voice/__tests__/live-voice-stt.test.ts +57 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
- package/src/live-voice/live-voice-session-manager.ts +11 -4
- package/src/live-voice/live-voice-session.ts +14 -6
- package/src/mcp/client.ts +20 -4
- package/src/media/image-credentials.ts +3 -3
- package/src/memory/__tests__/bookmark-crud.test.ts +264 -0
- package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
- package/src/memory/__tests__/conversation-queries.test.ts +263 -0
- package/src/memory/__tests__/conversation-types.test.ts +36 -0
- package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
- package/src/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +113 -0
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +318 -0
- package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
- package/src/memory/__tests__/message-content.test.ts +35 -0
- package/src/memory/bookmark-crud.ts +211 -0
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
- package/src/memory/context-search/agent-protocol.ts +5 -1
- package/src/memory/context-search/agent-runner.ts +60 -85
- package/src/memory/context-search/limits.ts +1 -4
- package/src/memory/context-search/search.ts +23 -113
- package/src/memory/context-search/sources/conversations.ts +80 -8
- package/src/memory/context-search/sources/memory-v2.ts +39 -14
- package/src/memory/context-search/sources/memory.ts +7 -0
- package/src/memory/context-search/sources/workspace.ts +17 -10
- package/src/memory/context-search/types.ts +1 -1
- package/src/memory/conversation-bootstrap.ts +11 -0
- package/src/memory/conversation-crud.ts +368 -22
- package/src/memory/conversation-queries.ts +116 -12
- package/src/memory/conversation-title-service.ts +1 -0
- package/src/memory/conversation-types.ts +16 -0
- package/src/memory/db-init.ts +20 -0
- package/src/memory/delivery-crud.ts +152 -5
- package/src/memory/embedding-backend.ts +6 -5
- package/src/memory/embedding-runtime-manager.ts +1 -2
- package/src/memory/external-conversation-store.ts +66 -5
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +66 -9
- package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
- package/src/memory/graph/conversation-graph-memory.ts +92 -5
- package/src/memory/graph/extraction.ts +4 -0
- package/src/memory/graph/graph-memory-state-store.ts +16 -3
- package/src/memory/graph/tool-handlers.ts +17 -7
- package/src/memory/graph/tools.ts +45 -6
- package/src/memory/indexer.ts +51 -29
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +86 -15
- package/src/memory/jobs/embed-concept-page.ts +65 -20
- package/src/memory/jobs-store.ts +51 -1
- package/src/memory/jobs-worker.ts +57 -3
- package/src/memory/llm-request-log-source-clickhouse.ts +324 -0
- package/src/memory/llm-request-log-source-local.ts +26 -0
- package/src/memory/llm-request-log-source.ts +64 -0
- package/src/memory/llm-request-log-store.ts +1 -1
- package/src/memory/llm-usage-store.ts +125 -5
- package/src/memory/memory-retrospective-constants.ts +13 -0
- package/src/memory/memory-retrospective-enqueue.ts +114 -0
- package/src/memory/memory-retrospective-job.ts +351 -0
- package/src/memory/memory-retrospective-startup-cleanup.ts +175 -0
- package/src/memory/memory-retrospective-state.ts +162 -0
- package/src/memory/memory-retrospective-trigger-check.ts +91 -0
- package/src/memory/memory-v2-activation-log-store.ts +49 -5
- package/src/memory/memory-v2-concept-frequency.ts +4 -0
- package/src/memory/message-content.ts +38 -1
- package/src/memory/migrations/109-external-conversation-bindings.ts +15 -4
- package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
- package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
- package/src/memory/migrations/229-delete-private-conversations.test.ts +107 -1
- package/src/memory/migrations/229-delete-private-conversations.ts +19 -0
- package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
- package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
- package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
- package/src/memory/migrations/242-message-bookmarks.ts +38 -0
- package/src/memory/migrations/243-provider-connections.ts +68 -0
- package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
- package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
- package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
- package/src/memory/migrations/247-external-conversation-binding-thread-id.ts +78 -0
- package/src/memory/migrations/248-create-onboarding-events.ts +21 -0
- package/src/memory/migrations/249-normalize-slack-external-content.ts +240 -0
- package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
- package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
- package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
- package/src/memory/migrations/index.ts +13 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/onboarding-events-store.ts +106 -0
- package/src/memory/published-pages-store.ts +16 -0
- package/src/memory/schema/bookmarks.ts +36 -0
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/conversations.ts +2 -0
- package/src/memory/schema/index.ts +2 -0
- package/src/memory/schema/inference.ts +27 -0
- package/src/memory/schema/infrastructure.ts +12 -0
- package/src/memory/schema/memory-core.ts +9 -0
- package/src/memory/search/semantic.ts +1 -4
- package/src/memory/turn-events-store.ts +127 -2
- package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
- package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
- package/src/memory/v2/__tests__/activation.test.ts +11 -12
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
- package/src/memory/v2/__tests__/consolidation-job.test.ts +123 -135
- package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
- package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
- package/src/memory/v2/__tests__/injection.test.ts +726 -18
- package/src/memory/v2/__tests__/migration.test.ts +94 -3
- package/src/memory/v2/__tests__/page-index.test.ts +360 -0
- package/src/memory/v2/__tests__/page-store.test.ts +14 -1
- package/src/memory/v2/__tests__/prompts-router.test.ts +309 -0
- package/src/memory/v2/__tests__/qdrant.test.ts +138 -3
- package/src/memory/v2/__tests__/reranker.test.ts +4 -4
- package/src/memory/v2/__tests__/router.test.ts +531 -0
- package/src/memory/v2/__tests__/sim.test.ts +45 -1
- package/src/memory/v2/__tests__/skill-store.test.ts +445 -11
- package/src/memory/v2/__tests__/static-context.test.ts +7 -22
- package/src/memory/v2/__tests__/sweep-job.test.ts +95 -0
- package/src/memory/v2/activation-store.ts +34 -5
- package/src/memory/v2/activation.ts +40 -27
- package/src/memory/v2/backfill-jobs.ts +17 -84
- package/src/memory/v2/consolidation-job.ts +85 -78
- package/src/memory/v2/frontmatter-sweep.ts +91 -0
- package/src/memory/v2/injection.ts +466 -109
- package/src/memory/v2/migration.ts +147 -20
- package/src/memory/v2/page-index.ts +221 -0
- package/src/memory/v2/page-store.ts +3 -0
- package/src/memory/v2/prompts/consolidation.ts +9 -7
- package/src/memory/v2/prompts/router.ts +195 -0
- package/src/memory/v2/prompts/sweep.ts +2 -2
- package/src/memory/v2/qdrant.ts +234 -93
- package/src/memory/v2/reranker.ts +14 -7
- package/src/memory/v2/router.ts +323 -0
- package/src/memory/v2/sim.ts +25 -12
- package/src/memory/v2/skill-store.ts +204 -30
- package/src/memory/v2/static-context.ts +16 -9
- package/src/memory/v2/sweep-job.ts +122 -96
- package/src/memory/v2/types.ts +10 -6
- package/src/memory/validation.ts +13 -0
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +45 -5
- package/src/messaging/providers/slack/__tests__/download.test.ts +231 -0
- package/src/messaging/providers/slack/adapter.ts +43 -5
- package/src/messaging/providers/slack/client.ts +27 -0
- package/src/messaging/providers/slack/deep-link.ts +65 -0
- package/src/messaging/providers/slack/download.ts +104 -0
- package/src/messaging/providers/slack/message-metadata.test.ts +32 -0
- package/src/messaging/providers/slack/message-metadata.ts +27 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +134 -0
- package/src/messaging/providers/slack/render-transcript.ts +69 -5
- package/src/messaging/providers/slack/types.ts +20 -1
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
- package/src/notifications/__tests__/signal-registry.test.ts +17 -0
- package/src/notifications/adapters/platform.ts +171 -0
- package/src/notifications/conversation-pairing.ts +4 -3
- package/src/notifications/copy-composer.ts +15 -0
- package/src/notifications/decision-engine.ts +2 -1
- package/src/notifications/destination-resolver.ts +21 -0
- package/src/notifications/emit-signal.ts +48 -2
- package/src/notifications/home-feed-side-effect.ts +165 -0
- package/src/notifications/signal.ts +8 -1
- package/src/oauth/connection-resolver.ts +8 -4
- package/src/oauth/platform-connection.ts +6 -2
- package/src/oauth/seed-providers.ts +10 -1
- package/src/permissions/checker.ts +14 -0
- package/src/permissions/ipc-risk-types.ts +3 -0
- package/src/permissions/question-prompter.test.ts +416 -0
- package/src/permissions/question-prompter.ts +294 -0
- package/src/platform/client.test.ts +1 -1
- package/src/platform/client.ts +1 -1
- package/src/plugin-api/constants.ts +26 -0
- package/src/plugin-api/index.ts +46 -0
- package/src/plugin-api/package.json +12 -0
- package/src/plugin-api/types.ts +144 -0
- package/src/plugins/defaults/circuit-breaker.ts +0 -5
- package/src/plugins/defaults/compaction.ts +0 -4
- package/src/plugins/defaults/empty-response.ts +0 -2
- package/src/plugins/defaults/history-repair.ts +0 -2
- package/src/plugins/defaults/injectors.ts +55 -6
- package/src/plugins/defaults/llm-call.ts +0 -2
- package/src/plugins/defaults/memory-retrieval.ts +0 -1
- package/src/plugins/defaults/overflow-reduce.ts +0 -1
- package/src/plugins/defaults/persistence.ts +0 -2
- package/src/plugins/defaults/title-generate.ts +0 -5
- package/src/plugins/defaults/token-estimate.ts +0 -2
- package/src/plugins/defaults/tool-error.ts +0 -7
- package/src/plugins/defaults/tool-execute.ts +0 -2
- package/src/plugins/defaults/tool-result-truncate.ts +0 -4
- package/src/plugins/ensure-plugin-api-shim.ts +96 -0
- package/src/plugins/external-api.ts +104 -0
- package/src/plugins/external-plugin-loader.ts +367 -0
- package/src/plugins/feature-gate.ts +22 -0
- package/src/plugins/pipeline.ts +37 -0
- package/src/plugins/registry.ts +48 -80
- package/src/plugins/types.ts +74 -53
- package/src/plugins/user-loader.ts +85 -43
- package/src/proactive-artifact/aux-message-injector.ts +11 -0
- package/src/proactive-artifact/job.test.ts +49 -9
- package/src/proactive-artifact/job.ts +4 -0
- package/src/proactive-artifact/trigger-state.test.ts +9 -0
- package/src/proactive-artifact/trigger-state.ts +4 -0
- package/src/prompts/__tests__/system-prompt.test.ts +117 -0
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +99 -0
- package/src/prompts/normalize-onboarding.ts +27 -0
- package/src/prompts/sections.ts +302 -0
- package/src/prompts/system-prompt.ts +72 -154
- package/src/prompts/templates/BOOTSTRAP.md +17 -1
- package/src/prompts/templates/system-sections.ts +173 -0
- package/src/prompts/update-bulletin-job.ts +61 -73
- package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
- package/src/providers/__tests__/inference.test.ts +303 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
- package/src/providers/__tests__/retry-callsite.test.ts +14 -32
- package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
- package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
- package/src/providers/anthropic/client.ts +123 -54
- package/src/providers/call-site-routing.ts +94 -16
- package/src/providers/connection-resolution.ts +170 -0
- package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
- package/src/providers/inference/adapter-factory.ts +210 -0
- package/src/providers/inference/auth.ts +112 -0
- package/src/providers/inference/backfill.ts +196 -0
- package/src/providers/inference/connections.ts +401 -0
- package/src/providers/inference/resolve-auth.ts +73 -0
- package/src/providers/model-catalog.ts +386 -6
- package/src/providers/openai/chat-completions-provider.ts +10 -2
- package/src/providers/openai/responses-provider.ts +4 -2
- package/src/providers/openrouter/client.ts +7 -0
- package/src/providers/{managed-proxy → platform-proxy}/constants.ts +4 -1
- package/src/providers/{managed-proxy → platform-proxy}/context.ts +3 -3
- package/src/providers/provider-availability.ts +17 -2
- package/src/providers/provider-catalog-visibility.ts +36 -0
- package/src/providers/provider-env-vars.ts +17 -7
- package/src/providers/provider-secret-catalog.ts +49 -30
- package/src/providers/provider-send-message.ts +41 -20
- package/src/providers/registry.ts +151 -159
- package/src/providers/retry.ts +65 -11
- package/src/providers/search-provider-catalog.ts +121 -0
- package/src/runtime/AGENTS.md +18 -5
- package/src/runtime/__tests__/agent-wake.test.ts +152 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
- package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
- package/src/runtime/actor-trust-resolver.ts +32 -10
- package/src/runtime/agent-wake.ts +64 -7
- package/src/runtime/assistant-event-hub.ts +3 -85
- package/src/runtime/auth/route-policy.ts +311 -9
- package/src/runtime/auth/same-actor.ts +2 -0
- package/src/runtime/background-job-runner.ts +339 -0
- package/src/runtime/btw-sidechain.ts +3 -0
- package/src/runtime/http-router.ts +36 -1
- package/src/runtime/http-server.ts +31 -5
- package/src/runtime/http-types.ts +21 -0
- package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
- package/src/runtime/middleware/request-logger.ts +62 -1
- package/src/runtime/migrations/origin-mode.ts +1 -1
- package/src/runtime/pending-interactions.ts +1 -0
- package/src/runtime/pre-first-message-gate.ts +83 -0
- package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +268 -0
- package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +319 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +280 -4
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +4 -4
- package/src/runtime/routes/__tests__/question-routes.test.ts +395 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +70 -3
- package/src/runtime/routes/acp-routes-list.test.ts +143 -0
- package/src/runtime/routes/acp-routes.ts +12 -8
- package/src/runtime/routes/app-management-routes.ts +228 -3
- package/src/runtime/routes/approval-routes.ts +0 -18
- package/src/runtime/routes/audit-routes.ts +43 -0
- package/src/runtime/routes/auth-routes.ts +72 -0
- package/src/runtime/routes/avatar-routes.ts +273 -20
- package/src/runtime/routes/backup-routes.ts +406 -2
- package/src/runtime/routes/bookmark-routes.ts +156 -0
- package/src/runtime/routes/btw-routes.ts +5 -1
- package/src/runtime/routes/channel-availability-routes.ts +121 -0
- package/src/runtime/routes/channel-verification-routes.ts +2 -1
- package/src/runtime/routes/contact-routes.ts +0 -160
- package/src/runtime/routes/conversation-cli-routes.ts +233 -0
- package/src/runtime/routes/conversation-list-routes.ts +3 -20
- package/src/runtime/routes/conversation-management-routes.ts +47 -85
- package/src/runtime/routes/conversation-query-routes.ts +350 -97
- package/src/runtime/routes/conversation-routes.ts +121 -21
- package/src/runtime/routes/conversations-import-routes.ts +229 -0
- package/src/runtime/routes/credential-routes.ts +540 -0
- package/src/runtime/routes/debug-routes.ts +2 -2
- package/src/runtime/routes/document-pdf-renderer.ts +5 -1
- package/src/runtime/routes/documents-routes.ts +25 -86
- package/src/runtime/routes/domain-routes.ts +167 -0
- package/src/runtime/routes/email-routes.ts +603 -0
- package/src/runtime/routes/errors.ts +2 -2
- package/src/runtime/routes/events-routes.ts +192 -0
- package/src/runtime/routes/group-routes.ts +5 -0
- package/src/runtime/routes/home-feed-routes.ts +6 -78
- package/src/runtime/routes/host-app-control-routes.ts +44 -2
- package/src/runtime/routes/host-browser-routes.ts +103 -22
- package/src/runtime/routes/http-adapter.ts +2 -0
- package/src/runtime/routes/identity-routes.ts +5 -0
- package/src/runtime/routes/image-generation-routes.ts +99 -0
- package/src/runtime/routes/inbound-conversation.ts +28 -8
- package/src/runtime/routes/inbound-message-handler.ts +236 -41
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +248 -1
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +118 -7
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +17 -4
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -4
- package/src/runtime/routes/index.ts +42 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +285 -0
- package/src/runtime/routes/inference-profile-session-reaper.ts +84 -0
- package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +361 -0
- package/src/runtime/routes/inference-send-routes.ts +115 -0
- package/src/runtime/routes/integrations/slack/share.ts +4 -52
- package/src/runtime/routes/integrations/slack/token.ts +43 -0
- package/src/runtime/routes/integrations/twilio.ts +7 -13
- package/src/runtime/routes/mcp-auth-routes.ts +283 -9
- package/src/runtime/routes/memory-v2-routes.ts +13 -398
- package/src/runtime/routes/notification-routes.ts +3 -1
- package/src/runtime/routes/oauth-apps.ts +112 -7
- package/src/runtime/routes/oauth-commands-routes.ts +1097 -0
- package/src/runtime/routes/oauth-connect-routes.ts +67 -5
- package/src/runtime/routes/oauth-lifecycle-routes.ts +43 -0
- package/src/runtime/routes/oauth-providers.ts +298 -8
- package/src/runtime/routes/platform-routes.ts +336 -0
- package/src/runtime/routes/playground/inject-failures.ts +2 -1
- package/src/runtime/routes/playground/reset-circuit.ts +2 -1
- package/src/runtime/routes/playground/state.ts +2 -1
- package/src/runtime/routes/publish-routes.ts +221 -0
- package/src/runtime/routes/question-routes.ts +259 -0
- package/src/runtime/routes/rename-conversation-routes.ts +2 -33
- package/src/runtime/routes/schedule-routes.ts +79 -0
- package/src/runtime/routes/sequence-routes.ts +291 -0
- package/src/runtime/routes/settings-routes.ts +2 -10
- package/src/runtime/routes/skills-routes.ts +31 -1
- package/src/runtime/routes/stt-routes.ts +240 -3
- package/src/runtime/routes/subagents-routes.ts +57 -18
- package/src/runtime/routes/surface-action-routes.ts +43 -7
- package/src/runtime/routes/telemetry-routes.ts +27 -0
- package/src/runtime/routes/tts-routes.ts +93 -1
- package/src/runtime/routes/types.ts +32 -0
- package/src/runtime/routes/user-routes-cli.ts +243 -0
- package/src/runtime/routes/webhook-routes.ts +165 -0
- package/src/runtime/routes/workspace-routes.test.ts +43 -0
- package/src/runtime/routes/workspace-routes.ts +28 -0
- package/src/runtime/services/conversation-serializer.ts +39 -7
- package/src/runtime/sync/resource-sync-events.ts +117 -0
- package/src/runtime/sync/sync-publisher.test.ts +105 -0
- package/src/runtime/sync/sync-publisher.ts +21 -0
- package/src/schedule/schedule-store.ts +27 -2
- package/src/schedule/scheduler.ts +208 -123
- package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
- package/src/security/__tests__/untrusted-content.test.ts +86 -0
- package/src/security/secret-patterns.ts +3 -0
- package/src/security/untrusted-content.ts +93 -8
- package/src/sequence/engine.ts +38 -40
- package/src/skills/catalog-files.ts +1 -1
- package/src/skills/catalog-install.ts +233 -116
- package/src/skills/clawhub.ts +70 -13
- package/src/skills/managed-store.ts +4 -119
- package/src/skills/skillssh-registry.ts +27 -48
- package/src/subagent/manager.ts +28 -15
- package/src/telemetry/types.ts +113 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +312 -5
- package/src/telemetry/usage-telemetry-reporter.ts +113 -7
- package/src/tools/apps/executors.ts +58 -7
- package/src/tools/ask-question/ask-question-tool.test.ts +509 -0
- package/src/tools/ask-question/ask-question-tool.ts +304 -0
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
- package/src/tools/browser/browser-execution.ts +29 -14
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
- package/src/tools/browser/cdp-client/factory.ts +66 -5
- package/src/tools/browser/runtime-check.ts +77 -0
- package/src/tools/computer-use/definitions.ts +3 -3
- package/src/tools/credentials/vault.ts +1 -1
- package/src/tools/document/document-tool.ts +124 -1
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +1 -1
- package/src/tools/filesystem/write.ts +5 -2
- package/src/tools/host-filesystem/transfer.ts +1 -1
- package/src/tools/host-terminal/host-shell.ts +1 -1
- package/src/tools/memory/register.test.ts +3 -3
- package/src/tools/memory/register.ts +9 -1
- package/src/tools/network/__tests__/web-search.test.ts +156 -0
- package/src/tools/network/web-search.ts +280 -37
- package/src/tools/permission-checker.ts +14 -6
- package/src/tools/registry.ts +17 -7
- package/src/tools/schedule/create.ts +2 -2
- package/src/tools/schema-transforms.ts +7 -2
- package/src/tools/side-effects.ts +1 -0
- package/src/tools/skills/delete-managed.ts +4 -4
- package/src/tools/skills/execute.ts +1 -1
- package/src/tools/skills/scaffold-managed.ts +3 -2
- package/src/tools/subagent/notify-parent.ts +1 -1
- package/src/tools/subagent/spawn.ts +3 -3
- package/src/tools/system/request-permission.ts +2 -2
- package/src/tools/terminal/safe-env.ts +60 -1
- package/src/tools/terminal/shell.ts +44 -0
- package/src/tools/tool-manifest.ts +2 -0
- package/src/tools/types.ts +72 -21
- package/src/tools/ui-surface/definitions.ts +6 -5
- package/src/tts/__tests__/provider-adapters.test.ts +76 -2
- package/src/tts/providers/elevenlabs-provider.ts +75 -1
- package/src/types/onboarding-context.ts +2 -0
- package/src/usage/attribution.ts +3 -2
- package/src/util/errors.ts +17 -0
- package/src/util/platform.ts +10 -0
- package/src/util/pricing.ts +86 -160
- package/src/watcher/__tests__/engine.test.ts +323 -0
- package/src/watcher/constants.ts +7 -0
- package/src/watcher/engine.ts +94 -90
- package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
- package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
- package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +94 -5
- package/src/workspace/migrations/069-seed-onboarding-threads.ts +8 -2
- package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +117 -0
- package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +95 -0
- package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
- package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
- package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
- package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
- package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
- package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
- package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
- package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
- package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
- package/src/workspace/migrations/083-system-prompt-prefix-to-file.ts +191 -0
- package/src/workspace/migrations/084-remove-legacy-skills-index.ts +276 -0
- package/src/workspace/migrations/085-memory-v2-bm25-b-reembed-disabled-v2-pages.ts +137 -0
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +198 -0
- package/src/workspace/migrations/registry.ts +30 -0
- package/src/workspace/migrations/runner.ts +46 -5
- package/src/workspace/migrations/types.ts +17 -3
- package/src/workspace/provider-commit-message-generator.ts +3 -2
- package/examples/plugins/echo/bun.lock +0 -25
- package/src/__tests__/context-search-pkb-source.test.ts +0 -498
- package/src/__tests__/context-window-manager.test.ts +0 -2093
- package/src/__tests__/credentials-cli.test.ts +0 -1225
- package/src/__tests__/memory-admin-recall.test.ts +0 -213
- package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
- package/src/cli/commands/__tests__/email-download.test.ts +0 -260
- package/src/cli/commands/__tests__/email-list.test.ts +0 -216
- package/src/cli/commands/__tests__/email-register.test.ts +0 -186
- package/src/cli/commands/__tests__/email-send.test.ts +0 -416
- package/src/cli/commands/__tests__/email-status.test.ts +0 -185
- package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
- package/src/cli/commands/__tests__/routes.test.ts +0 -562
- package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
- package/src/cli/commands/autonomy.ts +0 -365
- package/src/cli/commands/memory.ts +0 -424
- package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -947
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
- package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
- package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
- package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
- package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
- package/src/cli/lib/daemon-avatar-client.ts +0 -37
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
- package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
- package/src/context/__tests__/compact-prompt.test.ts +0 -63
- package/src/context/prompts/compact.md +0 -26
- package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
- package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
- package/src/home/__tests__/emit-feed-event.test.ts +0 -169
- package/src/home/__tests__/feed-population-integration.test.ts +0 -312
- package/src/home/__tests__/feed-scheduler.test.ts +0 -222
- package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
- package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
- package/src/home/__tests__/rollup-producer.test.ts +0 -507
- package/src/home/assistant-feed-authoring.ts +0 -135
- package/src/home/emit-feed-event.ts +0 -169
- package/src/home/feed-scheduler.ts +0 -281
- package/src/home/platform-gmail-digest.ts +0 -163
- package/src/home/rewrite-command-preview.ts +0 -66
- package/src/home/rewrite-feed-title.ts +0 -58
- package/src/home/rollup-producer.ts +0 -426
- package/src/memory/admin.ts +0 -326
- package/src/memory/context-search/sources/pkb.ts +0 -476
- package/src/memory/graph/compaction.ts +0 -299
- package/src/prompts/__tests__/build-cli-reference-section.test.ts +0 -37
- /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
|
@@ -9,10 +9,12 @@ import {
|
|
|
9
9
|
gt,
|
|
10
10
|
gte,
|
|
11
11
|
inArray,
|
|
12
|
+
isNotNull,
|
|
12
13
|
isNull,
|
|
13
14
|
like,
|
|
14
15
|
lt,
|
|
15
16
|
lte,
|
|
17
|
+
or,
|
|
16
18
|
sql,
|
|
17
19
|
} from "drizzle-orm";
|
|
18
20
|
import { v4 as uuid } from "uuid";
|
|
@@ -45,8 +47,11 @@ import {
|
|
|
45
47
|
} from "./conversation-disk-view.js";
|
|
46
48
|
import { ensureDisplayOrderMigration } from "./conversation-display-order-migration.js";
|
|
47
49
|
import { ensureGroupMigration } from "./conversation-group-migration.js";
|
|
48
|
-
import { getDb } from "./db-connection.js";
|
|
50
|
+
import { getDb, getSqliteFrom } from "./db-connection.js";
|
|
51
|
+
import { forkGraphMemoryState } from "./graph/graph-memory-state-store.js";
|
|
49
52
|
import { indexMessageNow } from "./indexer.js";
|
|
53
|
+
import { MEMORY_RETROSPECTIVE_SOURCE } from "./memory-retrospective-constants.js";
|
|
54
|
+
import { forkRetrospectiveState } from "./memory-retrospective-state.js";
|
|
50
55
|
import { rawExec, rawGet, rawRun } from "./raw-query.js";
|
|
51
56
|
import {
|
|
52
57
|
channelInboundEvents,
|
|
@@ -60,6 +65,7 @@ import {
|
|
|
60
65
|
toolInvocations,
|
|
61
66
|
} from "./schema.js";
|
|
62
67
|
import { cancelPendingJobsForConversation } from "./task-memory-cleanup.js";
|
|
68
|
+
import { forkActivationState } from "./v2/activation-store.js";
|
|
63
69
|
|
|
64
70
|
const log = getLogger("conversation-store");
|
|
65
71
|
|
|
@@ -81,6 +87,7 @@ const subagentNotificationSchema = z.object({
|
|
|
81
87
|
status: z.enum(["running", "completed", "failed", "aborted"]),
|
|
82
88
|
error: z.string().optional(),
|
|
83
89
|
conversationId: z.string().optional(),
|
|
90
|
+
objective: z.string().optional(),
|
|
84
91
|
});
|
|
85
92
|
|
|
86
93
|
export const messageMetadataSchema = z
|
|
@@ -89,6 +96,16 @@ export const messageMetadataSchema = z
|
|
|
89
96
|
assistantMessageChannel: channelIdSchema.optional(),
|
|
90
97
|
userMessageInterface: interfaceIdSchema.optional(),
|
|
91
98
|
assistantMessageInterface: interfaceIdSchema.optional(),
|
|
99
|
+
/**
|
|
100
|
+
* Optional client-side metadata bag attached to user messages by HTTP
|
|
101
|
+
* header middleware (reads `x-vellum-browser-family`,
|
|
102
|
+
* `x-vellum-browser-version`, `x-vellum-client-os`,
|
|
103
|
+
* `x-vellum-interface-version`). Forwarded verbatim onto
|
|
104
|
+
* `TurnTelemetryEvent.client` for downstream analytics. Kept as a
|
|
105
|
+
* permissive `record` so adding a new client field doesn't require a
|
|
106
|
+
* migration -- dbt can unpack later via JSON_VALUE.
|
|
107
|
+
*/
|
|
108
|
+
client: z.record(z.string(), z.unknown()).optional(),
|
|
92
109
|
subagentNotification: subagentNotificationSchema.optional(),
|
|
93
110
|
/**
|
|
94
111
|
* Trust class of the actor at the time this message was persisted.
|
|
@@ -112,6 +129,7 @@ export const messageMetadataSchema = z
|
|
|
112
129
|
workspaceBlock: z.string().optional(),
|
|
113
130
|
nowScratchpadBlock: z.string().optional(),
|
|
114
131
|
pkbContextBlock: z.string().optional(),
|
|
132
|
+
memoryV2StaticBlock: z.string().optional(),
|
|
115
133
|
})
|
|
116
134
|
.passthrough();
|
|
117
135
|
|
|
@@ -186,6 +204,8 @@ export interface ConversationRow {
|
|
|
186
204
|
lastMessageAt: number | null;
|
|
187
205
|
archivedAt: number | null;
|
|
188
206
|
inferenceProfile: string | null;
|
|
207
|
+
inferenceProfileSessionId: string | null;
|
|
208
|
+
inferenceProfileExpiresAt: number | null;
|
|
189
209
|
}
|
|
190
210
|
|
|
191
211
|
export const parseConversation = createRowMapper<
|
|
@@ -216,6 +236,8 @@ export const parseConversation = createRowMapper<
|
|
|
216
236
|
lastMessageAt: "lastMessageAt",
|
|
217
237
|
archivedAt: "archivedAt",
|
|
218
238
|
inferenceProfile: "inferenceProfile",
|
|
239
|
+
inferenceProfileSessionId: "inferenceProfileSessionId",
|
|
240
|
+
inferenceProfileExpiresAt: "inferenceProfileExpiresAt",
|
|
219
241
|
});
|
|
220
242
|
|
|
221
243
|
export interface MessageRow {
|
|
@@ -427,6 +449,60 @@ export function findAnalysisConversationFor(
|
|
|
427
449
|
return row ? { id: row.id } : null;
|
|
428
450
|
}
|
|
429
451
|
|
|
452
|
+
/**
|
|
453
|
+
* Find the most recent memory-retrospective background conversation rooted
|
|
454
|
+
* at `parentConversationId`. Used by the memory-retrospective job handler
|
|
455
|
+
* to load the prior retrospective's `remember` calls into the new run's
|
|
456
|
+
* `<already_remembered>` block — bounded source-of-truth for "what the
|
|
457
|
+
* prior pass already saved" that scales as the source conversation grows.
|
|
458
|
+
*
|
|
459
|
+
* Walks up `forkParentConversationId` when no retrospective exists at the
|
|
460
|
+
* current level. This lets a forked conversation inherit dedup context from
|
|
461
|
+
* its source's most recent retro on the fork's *first* retrospective —
|
|
462
|
+
* otherwise the fork would re-save every fact the source already retro'd.
|
|
463
|
+
* Once the fork accumulates its own retros, those are found at the first
|
|
464
|
+
* iteration and we never walk up.
|
|
465
|
+
*
|
|
466
|
+
* Returns `null` when no prior retrospective exists anywhere in the fork
|
|
467
|
+
* chain (true first-run case).
|
|
468
|
+
*
|
|
469
|
+
* Hits `idx_conversations_fork_parent_conversation_id` for the
|
|
470
|
+
* `forkParentConversationId` lookup.
|
|
471
|
+
*/
|
|
472
|
+
const MAX_FORK_CHAIN_DEPTH = 16;
|
|
473
|
+
|
|
474
|
+
export function findMostRecentRetrospectiveFor(
|
|
475
|
+
parentConversationId: string,
|
|
476
|
+
): { id: string } | null {
|
|
477
|
+
const db = getDb();
|
|
478
|
+
let currentId: string | null = parentConversationId;
|
|
479
|
+
for (let depth = 0; depth < MAX_FORK_CHAIN_DEPTH && currentId; depth++) {
|
|
480
|
+
const row = db
|
|
481
|
+
.select({ id: conversations.id })
|
|
482
|
+
.from(conversations)
|
|
483
|
+
.where(
|
|
484
|
+
and(
|
|
485
|
+
eq(conversations.source, MEMORY_RETROSPECTIVE_SOURCE),
|
|
486
|
+
eq(conversations.forkParentConversationId, currentId),
|
|
487
|
+
),
|
|
488
|
+
)
|
|
489
|
+
.orderBy(desc(conversations.createdAt))
|
|
490
|
+
.limit(1)
|
|
491
|
+
.get();
|
|
492
|
+
if (row) return { id: row.id };
|
|
493
|
+
|
|
494
|
+
const parent = db
|
|
495
|
+
.select({
|
|
496
|
+
forkParentConversationId: conversations.forkParentConversationId,
|
|
497
|
+
})
|
|
498
|
+
.from(conversations)
|
|
499
|
+
.where(eq(conversations.id, currentId))
|
|
500
|
+
.get();
|
|
501
|
+
currentId = parent?.forkParentConversationId ?? null;
|
|
502
|
+
}
|
|
503
|
+
return null;
|
|
504
|
+
}
|
|
505
|
+
|
|
430
506
|
/**
|
|
431
507
|
* Returns the `source` column for the given conversation, or null if
|
|
432
508
|
* not found. Tiny convenience used by the recursion guard in the
|
|
@@ -661,6 +737,24 @@ export function forkConversation(params: {
|
|
|
661
737
|
latestAssistantMessageAt: latestForkedAssistant?.messageAt ?? null,
|
|
662
738
|
});
|
|
663
739
|
|
|
740
|
+
// Carry the parent's per-conversation memory state into the child so the
|
|
741
|
+
// forked thread resumes with the same activation/injection log and
|
|
742
|
+
// in-context tracker the parent had at fork time. Only valid for
|
|
743
|
+
// full-history forks: a truncated fork would inherit activation/tracker
|
|
744
|
+
// entries for turns the child does not actually contain.
|
|
745
|
+
const isFullHistoryFork = copyBoundaryIndex === sourceMessages.length - 1;
|
|
746
|
+
if (isFullHistoryFork) {
|
|
747
|
+
forkActivationState(db, sourceConversation.id, fc.id);
|
|
748
|
+
forkGraphMemoryState(sourceConversation.id, fc.id);
|
|
749
|
+
}
|
|
750
|
+
forkRetrospectiveState({
|
|
751
|
+
database: db,
|
|
752
|
+
sourceConversationId: sourceConversation.id,
|
|
753
|
+
forkedConversationId: fc.id,
|
|
754
|
+
forkedMessageIds,
|
|
755
|
+
lastCopiedSourceMessageId: messagesToCopy.at(-1)?.id ?? null,
|
|
756
|
+
});
|
|
757
|
+
|
|
664
758
|
return fc;
|
|
665
759
|
});
|
|
666
760
|
|
|
@@ -963,22 +1057,23 @@ export function getMessages(conversationId: string): MessageRow[] {
|
|
|
963
1057
|
}
|
|
964
1058
|
|
|
965
1059
|
/**
|
|
966
|
-
* Return raw `metadata` strings for messages whose metadata
|
|
967
|
-
*
|
|
968
|
-
*
|
|
969
|
-
*
|
|
970
|
-
*
|
|
971
|
-
*
|
|
972
|
-
*
|
|
973
|
-
*
|
|
974
|
-
*
|
|
975
|
-
*
|
|
976
|
-
*
|
|
1060
|
+
* Return raw `metadata` strings for messages whose metadata looks like it may
|
|
1061
|
+
* contain Slack metadata, capped at `limit` and skipping the first `offset`
|
|
1062
|
+
* matches. Pushes `LIKE` + `LIMIT`/`OFFSET` into SQL so warm Slack DM
|
|
1063
|
+
* conversations don't require a full-table scan on the webhook critical path.
|
|
1064
|
+
* The substring match is an indexable prefilter only — callers must parse and
|
|
1065
|
+
* validate each returned string against the Slack metadata schema, because a
|
|
1066
|
+
* malformed row (partial write, legacy format, unrelated key accidentally
|
|
1067
|
+
* containing the literal) can still slip through the substring match. Callers
|
|
1068
|
+
* that need a fixed number of *valid* rows should iterate with increasing
|
|
1069
|
+
* offsets until the target is reached (capped at a reasonable maximum to bound
|
|
1070
|
+
* scan cost).
|
|
977
1071
|
*/
|
|
978
1072
|
export function selectSlackMetaCandidateMetadata(
|
|
979
1073
|
conversationId: string,
|
|
980
1074
|
limit: number,
|
|
981
1075
|
offset = 0,
|
|
1076
|
+
opts?: { includeFlatLegacy?: boolean },
|
|
982
1077
|
): string[] {
|
|
983
1078
|
const db = getDb();
|
|
984
1079
|
const rows = db
|
|
@@ -987,7 +1082,12 @@ export function selectSlackMetaCandidateMetadata(
|
|
|
987
1082
|
.where(
|
|
988
1083
|
and(
|
|
989
1084
|
eq(messages.conversationId, conversationId),
|
|
990
|
-
|
|
1085
|
+
opts?.includeFlatLegacy
|
|
1086
|
+
? or(
|
|
1087
|
+
like(messages.metadata, '%"slackMeta"%'),
|
|
1088
|
+
like(messages.metadata, '%"source":"slack"%'),
|
|
1089
|
+
)
|
|
1090
|
+
: like(messages.metadata, '%"slackMeta"%'),
|
|
991
1091
|
),
|
|
992
1092
|
)
|
|
993
1093
|
.orderBy(asc(messages.createdAt))
|
|
@@ -1003,6 +1103,111 @@ export function selectSlackMetaCandidateMetadata(
|
|
|
1003
1103
|
return out;
|
|
1004
1104
|
}
|
|
1005
1105
|
|
|
1106
|
+
/**
|
|
1107
|
+
* Count messages in a conversation that were created strictly after the
|
|
1108
|
+
* `afterMessageId` reference message. If `afterMessageId` is `null` or empty,
|
|
1109
|
+
* counts all messages in the conversation. If the referenced message no
|
|
1110
|
+
* longer exists (e.g. deleted by a separate flow), returns 0 — callers
|
|
1111
|
+
* decide how to react to a vanished reference, and the conservative answer
|
|
1112
|
+
* here is "no new work."
|
|
1113
|
+
*
|
|
1114
|
+
* Used by the memory-retrospective trigger check to decide whether to fire
|
|
1115
|
+
* the message-count trigger without loading message bodies.
|
|
1116
|
+
*/
|
|
1117
|
+
export function countMessagesAfter(
|
|
1118
|
+
conversationId: string,
|
|
1119
|
+
afterMessageId: string | null,
|
|
1120
|
+
): number {
|
|
1121
|
+
const db = getDb();
|
|
1122
|
+
if (afterMessageId === null || afterMessageId === "") {
|
|
1123
|
+
const row = db
|
|
1124
|
+
.select({ c: count() })
|
|
1125
|
+
.from(messages)
|
|
1126
|
+
.where(eq(messages.conversationId, conversationId))
|
|
1127
|
+
.get();
|
|
1128
|
+
return row?.c ?? 0;
|
|
1129
|
+
}
|
|
1130
|
+
const ref = db
|
|
1131
|
+
.select({ createdAt: messages.createdAt })
|
|
1132
|
+
.from(messages)
|
|
1133
|
+
.where(eq(messages.id, afterMessageId))
|
|
1134
|
+
.get();
|
|
1135
|
+
if (!ref) return 0;
|
|
1136
|
+
// Tie-breaker on `messages.id` so rows that share a millisecond timestamp
|
|
1137
|
+
// with the reference are not permanently skipped. Mirrors the
|
|
1138
|
+
// `(createdAt, id)` cursor pattern used by the backfill job-handler and
|
|
1139
|
+
// turn-events-store.
|
|
1140
|
+
const row = db
|
|
1141
|
+
.select({ c: count() })
|
|
1142
|
+
.from(messages)
|
|
1143
|
+
.where(
|
|
1144
|
+
and(
|
|
1145
|
+
eq(messages.conversationId, conversationId),
|
|
1146
|
+
or(
|
|
1147
|
+
gt(messages.createdAt, ref.createdAt),
|
|
1148
|
+
and(
|
|
1149
|
+
eq(messages.createdAt, ref.createdAt),
|
|
1150
|
+
gt(messages.id, afterMessageId),
|
|
1151
|
+
),
|
|
1152
|
+
),
|
|
1153
|
+
),
|
|
1154
|
+
)
|
|
1155
|
+
.get();
|
|
1156
|
+
return row?.c ?? 0;
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
/**
|
|
1160
|
+
* Return messages in a conversation created strictly after the
|
|
1161
|
+
* `afterMessageId` reference. If the reference is `null`/empty, returns all
|
|
1162
|
+
* messages. If the reference doesn't exist, returns an empty array (mirrors
|
|
1163
|
+
* `countMessagesAfter`'s conservative semantics). Used by the
|
|
1164
|
+
* memory-retrospective job handler to load the message slice it processes.
|
|
1165
|
+
*/
|
|
1166
|
+
export function getMessagesAfter(
|
|
1167
|
+
conversationId: string,
|
|
1168
|
+
afterMessageId: string | null,
|
|
1169
|
+
): MessageRow[] {
|
|
1170
|
+
const db = getDb();
|
|
1171
|
+
if (afterMessageId === null || afterMessageId === "") {
|
|
1172
|
+
// Secondary `asc(messages.id)` matches the non-null path's cursor
|
|
1173
|
+
// ordering, so callers tracking `cutoffMessageId` across runs see a
|
|
1174
|
+
// consistent ordering when multiple rows share a millisecond timestamp.
|
|
1175
|
+
return db
|
|
1176
|
+
.select()
|
|
1177
|
+
.from(messages)
|
|
1178
|
+
.where(eq(messages.conversationId, conversationId))
|
|
1179
|
+
.orderBy(asc(messages.createdAt), asc(messages.id))
|
|
1180
|
+
.all()
|
|
1181
|
+
.map(parseMessage);
|
|
1182
|
+
}
|
|
1183
|
+
const ref = db
|
|
1184
|
+
.select({ createdAt: messages.createdAt })
|
|
1185
|
+
.from(messages)
|
|
1186
|
+
.where(eq(messages.id, afterMessageId))
|
|
1187
|
+
.get();
|
|
1188
|
+
if (!ref) return [];
|
|
1189
|
+
// Same `(createdAt, id)` cursor as `countMessagesAfter` — rows sharing
|
|
1190
|
+
// the reference's millisecond timestamp would otherwise be skipped.
|
|
1191
|
+
return db
|
|
1192
|
+
.select()
|
|
1193
|
+
.from(messages)
|
|
1194
|
+
.where(
|
|
1195
|
+
and(
|
|
1196
|
+
eq(messages.conversationId, conversationId),
|
|
1197
|
+
or(
|
|
1198
|
+
gt(messages.createdAt, ref.createdAt),
|
|
1199
|
+
and(
|
|
1200
|
+
eq(messages.createdAt, ref.createdAt),
|
|
1201
|
+
gt(messages.id, afterMessageId),
|
|
1202
|
+
),
|
|
1203
|
+
),
|
|
1204
|
+
),
|
|
1205
|
+
)
|
|
1206
|
+
.orderBy(asc(messages.createdAt), asc(messages.id))
|
|
1207
|
+
.all()
|
|
1208
|
+
.map(parseMessage);
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1006
1211
|
/**
|
|
1007
1212
|
* Efficient existence check — returns true if the conversation has at least
|
|
1008
1213
|
* one message row. Uses `LIMIT 1` + `select({ 1 })` to avoid loading and
|
|
@@ -1226,6 +1431,10 @@ export function unarchiveConversation(id: string): boolean {
|
|
|
1226
1431
|
* Set or clear the inference profile override for a conversation.
|
|
1227
1432
|
* Pass `null` to clear the override and fall back to the workspace
|
|
1228
1433
|
* `llm.activeProfile` resolution.
|
|
1434
|
+
*
|
|
1435
|
+
* Also clears any stale session columns (`inferenceProfileSessionId`,
|
|
1436
|
+
* `inferenceProfileExpiresAt`) so that the reaper and lazy expiry check
|
|
1437
|
+
* cannot later clobber the newly-set profile.
|
|
1229
1438
|
*/
|
|
1230
1439
|
export function setConversationInferenceProfile(
|
|
1231
1440
|
conversationId: string,
|
|
@@ -1233,17 +1442,130 @@ export function setConversationInferenceProfile(
|
|
|
1233
1442
|
): void {
|
|
1234
1443
|
const db = getDb();
|
|
1235
1444
|
db.update(conversations)
|
|
1236
|
-
.set({
|
|
1445
|
+
.set({
|
|
1446
|
+
inferenceProfile: profile,
|
|
1447
|
+
inferenceProfileSessionId: null,
|
|
1448
|
+
inferenceProfileExpiresAt: null,
|
|
1449
|
+
updatedAt: Date.now(),
|
|
1450
|
+
})
|
|
1451
|
+
.where(eq(conversations.id, conversationId))
|
|
1452
|
+
.run();
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
/**
|
|
1456
|
+
* Atomically set the inference profile, session id, and expiry timestamp for
|
|
1457
|
+
* a conversation. Pass `null` for all three to clear the session-backed
|
|
1458
|
+
* override and fall back to the workspace `llm.activeProfile` resolution.
|
|
1459
|
+
*/
|
|
1460
|
+
export function setConversationInferenceProfileSession(
|
|
1461
|
+
conversationId: string,
|
|
1462
|
+
profile: string | null,
|
|
1463
|
+
sessionId: string | null,
|
|
1464
|
+
expiresAt: number | null,
|
|
1465
|
+
): void {
|
|
1466
|
+
const db = getDb();
|
|
1467
|
+
db.update(conversations)
|
|
1468
|
+
.set({
|
|
1469
|
+
inferenceProfile: profile,
|
|
1470
|
+
inferenceProfileSessionId: sessionId,
|
|
1471
|
+
inferenceProfileExpiresAt: expiresAt,
|
|
1472
|
+
updatedAt: Date.now(),
|
|
1473
|
+
})
|
|
1237
1474
|
.where(eq(conversations.id, conversationId))
|
|
1238
1475
|
.run();
|
|
1239
1476
|
}
|
|
1240
1477
|
|
|
1478
|
+
/**
|
|
1479
|
+
* Clear all conversations whose session-backed inference profile has expired.
|
|
1480
|
+
* Returns an array of `{ conversationId, sessionId }` for each cleared row so
|
|
1481
|
+
* callers can emit the appropriate update events.
|
|
1482
|
+
*/
|
|
1483
|
+
export function clearExpiredInferenceProfiles(
|
|
1484
|
+
now: number,
|
|
1485
|
+
): Array<{ conversationId: string; sessionId: string | null }> {
|
|
1486
|
+
const raw = getSqliteFrom(getDb());
|
|
1487
|
+
// Two-step approach: SELECT to get pre-clear sessionIds, then UPDATE.
|
|
1488
|
+
// The UPDATE re-applies the WHERE condition for CAS safety.
|
|
1489
|
+
// RETURNING the id lets us know which rows were actually cleared.
|
|
1490
|
+
const expired = raw
|
|
1491
|
+
.prepare(
|
|
1492
|
+
`
|
|
1493
|
+
SELECT id AS conversationId, inference_profile_session_id AS sessionId
|
|
1494
|
+
FROM conversations
|
|
1495
|
+
WHERE inference_profile_expires_at IS NOT NULL AND inference_profile_expires_at <= ?
|
|
1496
|
+
`,
|
|
1497
|
+
)
|
|
1498
|
+
.all(now) as Array<{ conversationId: string; sessionId: string | null }>;
|
|
1499
|
+
|
|
1500
|
+
if (expired.length === 0) return [];
|
|
1501
|
+
|
|
1502
|
+
const ids = expired.map((r) => r.conversationId);
|
|
1503
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
1504
|
+
|
|
1505
|
+
const actuallyCleared = raw
|
|
1506
|
+
.prepare(
|
|
1507
|
+
`
|
|
1508
|
+
UPDATE conversations
|
|
1509
|
+
SET inference_profile = NULL, inference_profile_session_id = NULL, inference_profile_expires_at = NULL
|
|
1510
|
+
WHERE id IN (${placeholders}) AND inference_profile_expires_at IS NOT NULL AND inference_profile_expires_at <= ?
|
|
1511
|
+
RETURNING id AS conversationId
|
|
1512
|
+
`,
|
|
1513
|
+
)
|
|
1514
|
+
.all(...ids, now) as Array<{ conversationId: string }>;
|
|
1515
|
+
|
|
1516
|
+
const clearedSet = new Set(actuallyCleared.map((r) => r.conversationId));
|
|
1517
|
+
return expired.filter((r) => clearedSet.has(r.conversationId));
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
/**
|
|
1521
|
+
* List conversations with an active (non-expired) session-backed inference
|
|
1522
|
+
* profile. Pass a `conversationId` to narrow to a single conversation.
|
|
1523
|
+
*/
|
|
1524
|
+
export function listActiveInferenceProfileSessions(
|
|
1525
|
+
conversationId?: string,
|
|
1526
|
+
): Array<{
|
|
1527
|
+
conversationId: string;
|
|
1528
|
+
conversationTitle: string | null;
|
|
1529
|
+
profile: string;
|
|
1530
|
+
sessionId: string;
|
|
1531
|
+
expiresAt: number;
|
|
1532
|
+
}> {
|
|
1533
|
+
const db = getDb();
|
|
1534
|
+
const now = Date.now();
|
|
1535
|
+
const baseConditions = [
|
|
1536
|
+
isNotNull(conversations.inferenceProfile),
|
|
1537
|
+
isNotNull(conversations.inferenceProfileExpiresAt),
|
|
1538
|
+
gt(conversations.inferenceProfileExpiresAt, now),
|
|
1539
|
+
isNotNull(conversations.inferenceProfileSessionId),
|
|
1540
|
+
];
|
|
1541
|
+
if (conversationId) {
|
|
1542
|
+
baseConditions.push(eq(conversations.id, conversationId));
|
|
1543
|
+
}
|
|
1544
|
+
return db
|
|
1545
|
+
.select({
|
|
1546
|
+
conversationId: conversations.id,
|
|
1547
|
+
conversationTitle: conversations.title,
|
|
1548
|
+
profile: conversations.inferenceProfile,
|
|
1549
|
+
sessionId: conversations.inferenceProfileSessionId,
|
|
1550
|
+
expiresAt: conversations.inferenceProfileExpiresAt,
|
|
1551
|
+
})
|
|
1552
|
+
.from(conversations)
|
|
1553
|
+
.where(and(...baseConditions))
|
|
1554
|
+
.all() as Array<{
|
|
1555
|
+
conversationId: string;
|
|
1556
|
+
conversationTitle: string | null;
|
|
1557
|
+
profile: string;
|
|
1558
|
+
sessionId: string;
|
|
1559
|
+
expiresAt: number;
|
|
1560
|
+
}>;
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1241
1563
|
/**
|
|
1242
1564
|
* Resolve the per-turn inference-profile override from an already-loaded
|
|
1243
|
-
* conversation row. Returns the row's `inferenceProfile` for
|
|
1244
|
-
* conversations, `undefined`
|
|
1245
|
-
* scheduled tasks, update bulletins) run on the workspace defaults
|
|
1246
|
-
* than inheriting an interactive override.
|
|
1565
|
+
* conversation row. Returns the row's `inferenceProfile` for interactive
|
|
1566
|
+
* conversations, `undefined` for automation threads (subagent fan-out,
|
|
1567
|
+
* scheduled tasks, update bulletins) so they run on the workspace defaults
|
|
1568
|
+
* rather than inheriting an interactive override.
|
|
1247
1569
|
*
|
|
1248
1570
|
* Prefer this row-based form when the caller already needs to read the
|
|
1249
1571
|
* conversation row for other reasons (e.g. the agent loop's title check).
|
|
@@ -1251,7 +1573,27 @@ export function setConversationInferenceProfile(
|
|
|
1251
1573
|
export function getConversationOverrideProfileFromRow(
|
|
1252
1574
|
conv: ConversationRow | null,
|
|
1253
1575
|
): string | undefined {
|
|
1254
|
-
if (
|
|
1576
|
+
if (
|
|
1577
|
+
conv?.conversationType === "background" ||
|
|
1578
|
+
conv?.conversationType === "scheduled"
|
|
1579
|
+
) {
|
|
1580
|
+
return undefined;
|
|
1581
|
+
}
|
|
1582
|
+
// Treat an expired session as if the override is absent. The eager reaper
|
|
1583
|
+
// clears the row and emits the update event; the lazy check here ensures
|
|
1584
|
+
// correctness on read paths before the reaper fires.
|
|
1585
|
+
//
|
|
1586
|
+
// `<=` (not `<`) for boundary consistency with the rest of the session
|
|
1587
|
+
// logic: the reaper SQL uses `expires_at <= ?`, and the active-session
|
|
1588
|
+
// queries use `expiresAt > now` (i.e. treat exact-expiry as inactive).
|
|
1589
|
+
// Without this, a session at the exact-expiry millisecond would be served
|
|
1590
|
+
// for one extra turn here while being cleared by the reaper.
|
|
1591
|
+
if (
|
|
1592
|
+
conv?.inferenceProfileExpiresAt != null &&
|
|
1593
|
+
conv.inferenceProfileExpiresAt <= Date.now()
|
|
1594
|
+
) {
|
|
1595
|
+
return undefined;
|
|
1596
|
+
}
|
|
1255
1597
|
return conv?.inferenceProfile ?? undefined;
|
|
1256
1598
|
}
|
|
1257
1599
|
|
|
@@ -1481,8 +1823,10 @@ export function updateMessageMetadata(
|
|
|
1481
1823
|
/**
|
|
1482
1824
|
* Bulk-remove the metadata fields that back the blocks stripped by
|
|
1483
1825
|
* `stripInjectionsForCompaction` — currently `pkbSystemReminderBlock`
|
|
1484
|
-
* (`<system_reminder>`), `nowScratchpadBlock` (`<NOW.md …>`),
|
|
1485
|
-
* `pkbContextBlock` (`<knowledge_base>`)
|
|
1826
|
+
* (`<system_reminder>`), `nowScratchpadBlock` (`<NOW.md …>`),
|
|
1827
|
+
* `pkbContextBlock` (`<knowledge_base>`), and `memoryV2StaticBlock`
|
|
1828
|
+
* (the static `<memory>\n…</memory>` block matched by the `<memory>\n`
|
|
1829
|
+
* prefix in `RUNTIME_INJECTION_PREFIXES`). Called from compaction-strip
|
|
1486
1830
|
* sites so post-restart rehydration stays consistent with the in-memory
|
|
1487
1831
|
* state produced by `stripInjectionsForCompaction` (which removes those
|
|
1488
1832
|
* tags from live messages but cannot touch the DB). Fields backing
|
|
@@ -1498,7 +1842,8 @@ export function clearStrippedInjectionMetadataForConversation(
|
|
|
1498
1842
|
metadata,
|
|
1499
1843
|
'$.pkbSystemReminderBlock',
|
|
1500
1844
|
'$.nowScratchpadBlock',
|
|
1501
|
-
'$.pkbContextBlock'
|
|
1845
|
+
'$.pkbContextBlock',
|
|
1846
|
+
'$.memoryV2StaticBlock'
|
|
1502
1847
|
)
|
|
1503
1848
|
WHERE conversation_id = ?
|
|
1504
1849
|
AND role = 'user'
|
|
@@ -1507,6 +1852,7 @@ export function clearStrippedInjectionMetadataForConversation(
|
|
|
1507
1852
|
json_extract(metadata, '$.pkbSystemReminderBlock') IS NOT NULL
|
|
1508
1853
|
OR json_extract(metadata, '$.nowScratchpadBlock') IS NOT NULL
|
|
1509
1854
|
OR json_extract(metadata, '$.pkbContextBlock') IS NOT NULL
|
|
1855
|
+
OR json_extract(metadata, '$.memoryV2StaticBlock') IS NOT NULL
|
|
1510
1856
|
)`,
|
|
1511
1857
|
conversationId,
|
|
1512
1858
|
);
|