@vellumai/assistant 0.8.3 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docker-entrypoint.sh +0 -1
- package/node_modules/@vellumai/gateway-client/src/types.ts +2 -0
- package/openapi.yaml +610 -16
- package/package.json +1 -1
- package/src/__tests__/agent-loop-exit-reason.test.ts +4 -5
- package/src/__tests__/agent-loop-override-profile.test.ts +1 -1
- package/src/__tests__/agent-loop.test.ts +88 -3
- package/src/__tests__/anthropic-provider.test.ts +272 -0
- package/src/__tests__/approval-cascade.test.ts +1 -1
- package/src/__tests__/background-workers-disk-pressure.test.ts +2 -1
- package/src/__tests__/channel-delivery-store.test.ts +193 -0
- package/src/__tests__/channel-reply-delivery.test.ts +284 -5
- package/src/__tests__/channel-retry-sweep.test.ts +274 -1
- package/src/__tests__/compaction-events.test.ts +1 -1
- package/src/__tests__/compactor-preserved-tail-count.test.ts +110 -0
- package/src/__tests__/config-watcher.test.ts +1 -1
- package/src/__tests__/context-token-estimator.test.ts +91 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +54 -3
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +31 -6
- package/src/__tests__/conversation-agent-loop.test.ts +25 -7
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
- package/src/__tests__/conversation-clean-command.test.ts +137 -0
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -1
- package/src/__tests__/conversation-fork-crud.test.ts +161 -0
- package/src/__tests__/conversation-lifecycle.test.ts +1 -1
- package/src/__tests__/conversation-load-cleaned-at.test.ts +279 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
- package/src/__tests__/conversation-pairing.test.ts +2 -2
- package/src/__tests__/conversation-process-callsite.test.ts +1 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -1
- package/src/__tests__/conversation-queue.test.ts +1 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +264 -81
- package/src/__tests__/conversation-seed-composer.test.ts +66 -4
- package/src/__tests__/conversation-slash-commands.test.ts +36 -8
- package/src/__tests__/conversation-slash-queue.test.ts +1 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -1
- package/src/__tests__/conversation-speed-override.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +220 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
- package/src/__tests__/credential-security-invariants.test.ts +6 -0
- package/src/__tests__/cu-unified-flow.test.ts +10 -1
- package/src/__tests__/dm-backfill.test.ts +64 -0
- package/src/__tests__/dm-persistence.test.ts +33 -0
- package/src/__tests__/document-find-replace.test.ts +501 -0
- package/src/__tests__/first-greeting.test.ts +23 -2
- package/src/__tests__/headless-browser-navigate.test.ts +172 -0
- package/src/__tests__/host-bash-proxy.test.ts +6 -0
- package/src/__tests__/host-browser-proxy.test.ts +10 -0
- package/src/__tests__/host-cu-proxy.test.ts +8 -1
- package/src/__tests__/host-file-proxy.test.ts +8 -1
- package/src/__tests__/host-transfer-proxy.test.ts +8 -1
- package/src/__tests__/identity-routes.test.ts +57 -0
- package/src/__tests__/inbound-slack-persistence.test.ts +3 -0
- package/src/__tests__/injector-chain.test.ts +2 -0
- package/src/__tests__/injector-document-comments.test.ts +378 -0
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +4 -25
- package/src/__tests__/list-messages-attachments.test.ts +21 -17
- package/src/__tests__/list-messages-hidden-metadata.test.ts +217 -0
- package/src/__tests__/list-messages-page-latest.test.ts +130 -14
- package/src/__tests__/list-messages-tool-merge.test.ts +17 -16
- package/src/__tests__/llm-context-normalization.test.ts +0 -2
- package/src/__tests__/llm-resolver.test.ts +85 -1
- package/src/__tests__/log-export-routes.test.ts +99 -2
- package/src/__tests__/message-queue-steer.test.ts +114 -0
- package/src/__tests__/openai-provider.test.ts +105 -0
- package/src/__tests__/openai-responses-provider.test.ts +4 -4
- package/src/__tests__/outbound-slack-persistence.test.ts +187 -20
- package/src/__tests__/pending-interactions-resolved-event.test.ts +190 -0
- package/src/__tests__/platform.test.ts +0 -3
- package/src/__tests__/plugin-source-watcher.test.ts +302 -0
- package/src/__tests__/process-message-background-slack.test.ts +1 -51
- package/src/__tests__/process-message-display-content.test.ts +21 -16
- package/src/__tests__/server-history-render.test.ts +83 -4
- package/src/__tests__/steer-tool-repair.test.ts +249 -0
- package/src/__tests__/system-prompt.test.ts +51 -28
- package/src/__tests__/terminal-tools.test.ts +11 -1
- package/src/__tests__/thinking-block-replay.test.ts +113 -0
- package/src/__tests__/thread-backfill.test.ts +370 -22
- package/src/__tests__/tool-executor.test.ts +90 -1
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +167 -0
- package/src/__tests__/twilio-routes.test.ts +1 -1
- package/src/__tests__/web-fetch.test.ts +2 -2
- package/src/__tests__/workspace-git-service.test.ts +88 -5
- package/src/__tests__/workspace-migration-088-deprecate-background-conversation-override.test.ts +158 -0
- package/src/agent/attachments.ts +1 -0
- package/src/agent/loop.ts +57 -20
- package/src/background-wake/next-wake.test.ts +289 -0
- package/src/background-wake/next-wake.ts +172 -0
- package/src/browser/operations.ts +15 -0
- package/src/cli/commands/__tests__/conversations-slack.test.ts +572 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +9 -12
- package/src/cli/commands/conversations.ts +128 -1
- package/src/cli/commands/inference-providers.ts +147 -1
- package/src/cli/commands/memory-v2.ts +308 -0
- package/src/cli/commands/notifications.ts +24 -2
- package/src/cli/utils/conversation-id.ts +17 -5
- package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
- package/src/config/bundled-skills/document-editor/SKILL.md +115 -0
- package/src/config/bundled-skills/document-editor/TOOLS.json +240 -0
- package/src/config/bundled-skills/document-editor/tools/comment-list.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-reply.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-resolve.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-find.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-replace-text.ts +12 -0
- package/src/config/bundled-skills/media-processing/SKILL.md +8 -0
- package/src/config/bundled-skills/schedule/SKILL.md +8 -0
- package/src/config/bundled-tool-registry.ts +22 -12
- package/src/config/call-site-defaults.ts +19 -0
- package/src/config/feature-flag-registry.json +99 -3
- package/src/config/llm-resolver.ts +16 -2
- package/src/config/schemas/__tests__/memory-v2.test.ts +4 -0
- package/src/config/schemas/call-site-catalog.ts +21 -0
- package/src/config/schemas/llm.ts +3 -0
- package/src/config/schemas/memory-v2.ts +48 -1
- package/src/context/compactor.ts +8 -1
- package/src/context/token-estimator.ts +47 -4
- package/src/context/window-manager.ts +25 -0
- package/src/credential-health/credential-health-service.ts +34 -19
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -6
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +357 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +287 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +153 -23
- package/src/daemon/conversation-agent-loop.ts +223 -54
- package/src/daemon/conversation-lifecycle.ts +142 -116
- package/src/daemon/conversation-messaging.ts +3 -0
- package/src/daemon/conversation-process.ts +273 -0
- package/src/daemon/conversation-queue-manager.ts +14 -0
- package/src/daemon/conversation-runtime-assembly.ts +135 -75
- package/src/daemon/conversation-slash.ts +37 -5
- package/src/daemon/conversation-surfaces.ts +45 -2
- package/src/daemon/conversation-tool-setup.ts +7 -0
- package/src/daemon/conversation.ts +42 -5
- package/src/daemon/first-greeting.ts +10 -0
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +498 -0
- package/src/daemon/handlers/config-a2a.ts +160 -0
- package/src/daemon/handlers/config-model.test.ts +1 -0
- package/src/daemon/handlers/conversations.ts +79 -0
- package/src/daemon/handlers/shared.ts +92 -29
- package/src/daemon/host-bash-proxy.ts +1 -1
- package/src/daemon/host-cu-proxy.ts +1 -1
- package/src/daemon/host-file-proxy.ts +1 -1
- package/src/daemon/host-transfer-proxy.ts +1 -1
- package/src/daemon/lifecycle.ts +18 -4
- package/src/daemon/message-protocol.ts +4 -0
- package/src/daemon/message-types/conversations.ts +8 -0
- package/src/daemon/message-types/document-comments.ts +50 -0
- package/src/daemon/message-types/messages.ts +68 -1
- package/src/daemon/message-types/surfaces.ts +3 -1
- package/src/daemon/message-types/web-activity.ts +57 -0
- package/src/daemon/plugin-source-watcher.ts +135 -3
- package/src/daemon/process-message.ts +69 -12
- package/src/daemon/query-complexity-router.ts +75 -0
- package/src/daemon/trust-context.ts +6 -0
- package/src/documents/document-comments-store.test.ts +338 -0
- package/src/documents/document-comments-store.ts +237 -0
- package/src/documents/document-store.ts +202 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +0 -1
- package/src/heartbeat/heartbeat-service.ts +1 -0
- package/src/home/__tests__/suggested-prompts.test.ts +33 -2
- package/src/home/feed-types.ts +6 -1
- package/src/home/home-content-refresh.ts +52 -0
- package/src/home/home-greeting-cache.ts +69 -0
- package/src/home/home-greeting.ts +94 -0
- package/src/home/suggested-prompts.ts +177 -9
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +135 -2
- package/src/memory/__tests__/memory-retrospective-job.test.ts +320 -6
- package/src/memory/conversation-crud.ts +133 -43
- package/src/memory/db-init.ts +16 -0
- package/src/memory/delivery-crud.ts +41 -0
- package/src/memory/delivery-status.ts +141 -15
- package/src/memory/external-conversation-store.ts +32 -1
- package/src/memory/jobs-worker.ts +21 -1
- package/src/memory/memory-retrospective-constants.ts +28 -0
- package/src/memory/memory-retrospective-enqueue.ts +3 -2
- package/src/memory/memory-retrospective-job.ts +408 -18
- package/src/memory/memory-retrospective-startup-cleanup.ts +3 -3
- package/src/memory/memory-v2-activation-log-store.ts +26 -8
- package/src/memory/migrations/100-core-tables.ts +1 -0
- package/src/memory/migrations/109-external-conversation-bindings.ts +1 -0
- package/src/memory/migrations/253-conversation-last-notified-profile.ts +15 -0
- package/src/memory/migrations/253-document-comments.ts +47 -0
- package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +43 -0
- package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +24 -0
- package/src/memory/migrations/256-memory-v2-injection-events.ts +113 -0
- package/src/memory/migrations/257-strip-base-url-non-openai-compatible.ts +22 -0
- package/src/memory/migrations/258-onboarding-events-prior-assistants.ts +13 -0
- package/src/memory/migrations/259-conversation-cleaned-at.ts +33 -0
- package/src/memory/migrations/index.ts +17 -0
- package/src/memory/migrations/registry.ts +25 -0
- package/src/memory/onboarding-events-store.ts +7 -0
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/conversations.ts +3 -0
- package/src/memory/schema/infrastructure.ts +1 -0
- package/src/memory/v2/__tests__/injection-events.test.ts +318 -0
- package/src/memory/v2/__tests__/injection.test.ts +31 -14
- package/src/memory/v2/__tests__/page-index.test.ts +365 -1
- package/src/memory/v2/__tests__/router.test.ts +489 -1
- package/src/memory/v2/consolidation-job.ts +14 -0
- package/src/memory/v2/injection-events.ts +101 -0
- package/src/memory/v2/injection.ts +21 -10
- package/src/memory/v2/page-index.ts +209 -7
- package/src/memory/v2/page-store.ts +18 -0
- package/src/memory/v2/router.ts +209 -55
- package/src/messaging/providers/index.ts +7 -1
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +329 -3
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +34 -1
- package/src/messaging/providers/slack/adapter.ts +178 -25
- package/src/messaging/providers/slack/api.test.ts +54 -0
- package/src/messaging/providers/slack/api.ts +119 -3
- package/src/messaging/providers/slack/client.ts +12 -0
- package/src/messaging/providers/slack/deep-link.ts +20 -1
- package/src/messaging/providers/slack/message-metadata.test.ts +48 -0
- package/src/messaging/providers/slack/message-metadata.ts +156 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +107 -75
- package/src/messaging/providers/slack/render-transcript.ts +176 -49
- package/src/messaging/providers/slack/send.test.ts +77 -0
- package/src/messaging/providers/slack/send.ts +8 -2
- package/src/messaging/providers/slack/types.ts +14 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +4 -1
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +116 -54
- package/src/notifications/conversation-seed-composer.ts +14 -2
- package/src/notifications/deferred-emit.ts +135 -0
- package/src/notifications/emit-signal.ts +9 -1
- package/src/notifications/home-feed-side-effect.ts +60 -30
- package/src/oauth/connect-orchestrator.ts +3 -0
- package/src/oauth/credential-token-resolver.ts +2 -0
- package/src/oauth/manual-token-connection.ts +19 -0
- package/src/oauth/oauth-store.ts +12 -0
- package/src/oauth/seed-providers.ts +22 -0
- package/src/permissions/prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +4 -1
- package/src/plugins/defaults/injectors.ts +82 -9
- package/src/prompts/__tests__/system-prompt.test.ts +46 -2
- package/src/prompts/normalize-onboarding.ts +40 -0
- package/src/prompts/sections.ts +32 -14
- package/src/prompts/system-prompt.ts +105 -68
- package/src/prompts/template-detection.ts +37 -0
- package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +141 -0
- package/src/prompts/templates/BOOTSTRAP.md +8 -0
- package/src/prompts/templates/VOICE.md +3 -0
- package/src/prompts/templates/system-sections.ts +53 -3
- package/src/providers/anthropic/client.ts +132 -5
- package/src/providers/fireworks/client.ts +20 -2
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +342 -0
- package/src/providers/inference/__tests__/base-url-security.test.ts +189 -0
- package/src/providers/inference/__tests__/codex-token-refresh.test.ts +254 -0
- package/src/providers/inference/adapter-factory.ts +15 -1
- package/src/providers/inference/auth.ts +3 -3
- package/src/providers/inference/codex-token-refresh.ts +128 -0
- package/src/providers/inference/resolve-auth.ts +49 -6
- package/src/providers/model-catalog.ts +48 -1
- package/src/providers/openai/chat-completions-provider.ts +57 -20
- package/src/providers/openai/responses-provider.ts +9 -3
- package/src/providers/openrouter/client.ts +5 -1
- package/src/providers/types.ts +25 -0
- package/src/runtime/__tests__/agent-wake.test.ts +214 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +128 -0
- package/src/runtime/agent-wake.ts +151 -56
- package/src/runtime/auth/route-policy.ts +7 -3
- package/src/runtime/background-job-runner.ts +26 -0
- package/src/runtime/channel-reply-delivery.ts +182 -47
- package/src/runtime/channel-retry-sweep.ts +141 -16
- package/src/runtime/http-types.ts +7 -4
- package/src/runtime/pending-interactions.ts +51 -8
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +162 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +55 -1
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +14 -0
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +271 -0
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +280 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +266 -0
- package/src/runtime/routes/approval-routes.ts +4 -1
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +246 -0
- package/src/runtime/routes/content-source-routes.ts +78 -0
- package/src/runtime/routes/conversation-cli-routes.ts +146 -1
- package/src/runtime/routes/conversation-query-routes.ts +60 -1
- package/src/runtime/routes/conversation-routes.ts +281 -76
- package/src/runtime/routes/document-comments-routes.ts +287 -0
- package/src/runtime/routes/documents-routes.ts +33 -0
- package/src/runtime/routes/home-feed-routes.ts +6 -3
- package/src/runtime/routes/host-app-control-routes.ts +1 -1
- package/src/runtime/routes/host-browser-routes.ts +8 -1
- package/src/runtime/routes/identity-routes.ts +21 -0
- package/src/runtime/routes/inbound-message-handler.ts +288 -58
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +365 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +283 -82
- package/src/runtime/routes/index.ts +12 -4
- package/src/runtime/routes/inference-provider-connection-routes.ts +63 -7
- package/src/runtime/routes/integrations/a2a.ts +60 -1
- package/src/runtime/routes/log-export-routes.ts +39 -0
- package/src/runtime/routes/memory-v2-routes.ts +217 -0
- package/src/runtime/routes/notification-routes.ts +19 -2
- package/src/runtime/routes/question-routes.ts +4 -1
- package/src/runtime/routes/sanity-routes.ts +159 -0
- package/src/runtime/routes/slack-channel-routes.ts +187 -0
- package/src/runtime/services/conversation-serializer.ts +30 -4
- package/src/schedule/integration-status.ts +3 -1
- package/src/security/__tests__/oauth2-device-code.test.ts +479 -0
- package/src/security/oauth2-device-code.ts +307 -0
- package/src/security/oauth2.ts +26 -9
- package/src/security/secure-keys.ts +5 -0
- package/src/skills/catalog-install.ts +6 -2
- package/src/tools/browser/__tests__/pinned-tabs.test.ts +80 -0
- package/src/tools/browser/browser-execution.ts +93 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +28 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +1 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +10 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +15 -1
- package/src/tools/browser/cdp-client/factory.ts +87 -3
- package/src/tools/browser/cdp-client/local-cdp-client.ts +9 -0
- package/src/tools/browser/cdp-client/types.ts +36 -0
- package/src/tools/browser/pinned-tabs.ts +90 -0
- package/src/tools/document/document-comment-tool.test.ts +379 -0
- package/src/tools/document/document-comment-tool.ts +156 -0
- package/src/tools/document/document-tool.ts +128 -2
- package/src/tools/network/__tests__/web-fetch-metadata.test.ts +229 -0
- package/src/tools/network/__tests__/web-search-metadata.test.ts +346 -0
- package/src/tools/network/domain-normalize.ts +17 -0
- package/src/tools/network/web-fetch.ts +213 -64
- package/src/tools/network/web-search.ts +191 -66
- package/src/tools/terminal/safe-env.ts +3 -2
- package/src/tools/tool-approval-handler.ts +19 -12
- package/src/tools/types.ts +4 -0
- package/src/tools/ui-surface/definitions.ts +3 -1
- package/src/types/onboarding-context.ts +4 -0
- package/src/util/__tests__/favicon.test.ts +84 -0
- package/src/util/favicon.ts +40 -0
- package/src/util/platform.ts +0 -5
- package/src/workspace/git-service.ts +75 -4
- package/src/workspace/migrations/088-deprecate-background-conversation-override.ts +103 -0
- package/src/workspace/migrations/registry.ts +2 -0
- package/src/config/bundled-skills/document/SKILL.md +0 -54
- package/src/config/bundled-skills/document/TOOLS.json +0 -106
- package/src/daemon/seed-files.ts +0 -18
- package/src/runtime/routes/interface-routes.ts +0 -43
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-create.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-delete.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-list.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-read.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-update.ts +0 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
2
|
+
import { tableHasColumn } from "./schema-introspection.js";
|
|
3
|
+
import { withCrashRecovery } from "./validate-migration-state.js";
|
|
4
|
+
|
|
5
|
+
const CHECKPOINT_KEY = "migration_external_conversation_binding_chat_name_v1";
|
|
6
|
+
|
|
7
|
+
export function migrateExternalConversationBindingChatName(
|
|
8
|
+
database: DrizzleDb,
|
|
9
|
+
): void {
|
|
10
|
+
withCrashRecovery(database, CHECKPOINT_KEY, () => {
|
|
11
|
+
if (
|
|
12
|
+
tableHasColumn(
|
|
13
|
+
database,
|
|
14
|
+
"external_conversation_bindings",
|
|
15
|
+
"external_chat_name",
|
|
16
|
+
)
|
|
17
|
+
) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
database.run(
|
|
22
|
+
`ALTER TABLE external_conversation_bindings ADD COLUMN external_chat_name TEXT`,
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function downExternalConversationBindingChatName(
|
|
28
|
+
database: DrizzleDb,
|
|
29
|
+
): void {
|
|
30
|
+
if (
|
|
31
|
+
!tableHasColumn(
|
|
32
|
+
database,
|
|
33
|
+
"external_conversation_bindings",
|
|
34
|
+
"external_chat_name",
|
|
35
|
+
)
|
|
36
|
+
) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
database.run(
|
|
41
|
+
`ALTER TABLE external_conversation_bindings DROP COLUMN external_chat_name`,
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
2
|
+
import { getSqliteFrom } from "../db-connection.js";
|
|
3
|
+
import { tableHasColumn } from "./schema-introspection.js";
|
|
4
|
+
import { withCrashRecovery } from "./validate-migration-state.js";
|
|
5
|
+
|
|
6
|
+
const CHECKPOINT_KEY = "migration_channel_inbound_delivery_attempts_v1";
|
|
7
|
+
|
|
8
|
+
/** Add a delivery-specific retry counter for channel inbound events. */
|
|
9
|
+
export function migrateChannelInboundDeliveryAttempts(
|
|
10
|
+
database: DrizzleDb,
|
|
11
|
+
): void {
|
|
12
|
+
withCrashRecovery(database, CHECKPOINT_KEY, () => {
|
|
13
|
+
if (
|
|
14
|
+
tableHasColumn(database, "channel_inbound_events", "delivery_attempts")
|
|
15
|
+
) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const raw = getSqliteFrom(database);
|
|
19
|
+
raw.exec(/*sql*/ `
|
|
20
|
+
ALTER TABLE channel_inbound_events
|
|
21
|
+
ADD COLUMN delivery_attempts INTEGER NOT NULL DEFAULT 0
|
|
22
|
+
`);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { getLogger } from "../../util/logger.js";
|
|
2
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
3
|
+
import { getSqliteFrom } from "../db-connection.js";
|
|
4
|
+
import { withCrashRecovery } from "./validate-migration-state.js";
|
|
5
|
+
|
|
6
|
+
const CHECKPOINT_KEY = "migration_memory_v2_injection_events_v1";
|
|
7
|
+
const log = getLogger("memory-v2-injection-events-migration");
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Create the memory_v2_injection_events table — an append-only event log of
|
|
11
|
+
* (slug, injected_at) tuples capturing every router selection.
|
|
12
|
+
*
|
|
13
|
+
* This is the data source for the time-decayed injection frequency score
|
|
14
|
+
* that drives tier 2 assignment in memory router v4. Score is computed on
|
|
15
|
+
* read as `Σ exp(-λ × (now - tᵢ))` with `λ = ln(2) / 3 days`, so the table
|
|
16
|
+
* just accumulates raw events; the formula or half-life can change later
|
|
17
|
+
* without losing signal.
|
|
18
|
+
*
|
|
19
|
+
* Backfill: walks existing `memory_v2_activation_logs` and replays each
|
|
20
|
+
* row's router-sourced slugs as historical events. Without backfill the
|
|
21
|
+
* scores would take ~3 half-lives (≈9 days) to reach steady state; with
|
|
22
|
+
* backfill tier 2 assignment has signal from day one.
|
|
23
|
+
*
|
|
24
|
+
* Indexes:
|
|
25
|
+
* - `(slug, injected_at)` for per-slug score reads (the hot path).
|
|
26
|
+
* - `(injected_at)` for time-range pruning later.
|
|
27
|
+
*/
|
|
28
|
+
export function migrateMemoryV2InjectionEvents(database: DrizzleDb): void {
|
|
29
|
+
withCrashRecovery(database, CHECKPOINT_KEY, () => {
|
|
30
|
+
const raw = getSqliteFrom(database);
|
|
31
|
+
raw.exec(/*sql*/ `
|
|
32
|
+
CREATE TABLE IF NOT EXISTS memory_v2_injection_events (
|
|
33
|
+
id INTEGER PRIMARY KEY,
|
|
34
|
+
slug TEXT NOT NULL,
|
|
35
|
+
injected_at INTEGER NOT NULL
|
|
36
|
+
)
|
|
37
|
+
`);
|
|
38
|
+
raw.exec(/*sql*/ `
|
|
39
|
+
CREATE INDEX IF NOT EXISTS idx_memory_v2_injection_events_slug_time
|
|
40
|
+
ON memory_v2_injection_events (slug, injected_at)
|
|
41
|
+
`);
|
|
42
|
+
raw.exec(/*sql*/ `
|
|
43
|
+
CREATE INDEX IF NOT EXISTS idx_memory_v2_injection_events_time
|
|
44
|
+
ON memory_v2_injection_events (injected_at)
|
|
45
|
+
`);
|
|
46
|
+
|
|
47
|
+
// Bail before backfill on databases that predate memory_v2_activation_logs
|
|
48
|
+
// (migration 234) — there's no historical signal to replay.
|
|
49
|
+
const logsTable = raw
|
|
50
|
+
.query(
|
|
51
|
+
`SELECT name FROM sqlite_master WHERE type='table' AND name='memory_v2_activation_logs'`,
|
|
52
|
+
)
|
|
53
|
+
.get();
|
|
54
|
+
if (!logsTable) return;
|
|
55
|
+
|
|
56
|
+
// Re-run safety net independent of the checkpoint: if events already
|
|
57
|
+
// exist, do not append duplicates. The checkpoint normally short-circuits
|
|
58
|
+
// re-runs in withCrashRecovery; this guards the manual-clear path.
|
|
59
|
+
const existing = raw
|
|
60
|
+
.query(`SELECT COUNT(*) as n FROM memory_v2_injection_events`)
|
|
61
|
+
.get() as { n: number };
|
|
62
|
+
if (existing.n > 0) return;
|
|
63
|
+
|
|
64
|
+
const rows = raw
|
|
65
|
+
.query(
|
|
66
|
+
`SELECT concepts_json, created_at FROM memory_v2_activation_logs ORDER BY created_at ASC`,
|
|
67
|
+
)
|
|
68
|
+
.all() as Array<{ concepts_json: string; created_at: number }>;
|
|
69
|
+
if (rows.length === 0) return;
|
|
70
|
+
|
|
71
|
+
const insert = raw.prepare(
|
|
72
|
+
`INSERT INTO memory_v2_injection_events (slug, injected_at) VALUES (?, ?)`,
|
|
73
|
+
);
|
|
74
|
+
const replay = raw.transaction(
|
|
75
|
+
(events: ReadonlyArray<{ slug: string; t: number }>) => {
|
|
76
|
+
for (const e of events) insert.run(e.slug, e.t);
|
|
77
|
+
},
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const buffer: Array<{ slug: string; t: number }> = [];
|
|
81
|
+
let parseFailures = 0;
|
|
82
|
+
for (const row of rows) {
|
|
83
|
+
let concepts: Array<{ slug?: unknown; source?: unknown }>;
|
|
84
|
+
try {
|
|
85
|
+
concepts = JSON.parse(row.concepts_json) as Array<{
|
|
86
|
+
slug?: unknown;
|
|
87
|
+
source?: unknown;
|
|
88
|
+
}>;
|
|
89
|
+
} catch {
|
|
90
|
+
parseFailures += 1;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (!Array.isArray(concepts)) continue;
|
|
94
|
+
for (const c of concepts) {
|
|
95
|
+
if (typeof c.slug !== "string") continue;
|
|
96
|
+
// Carry-over entries were not router-selected this turn — exclude.
|
|
97
|
+
if (c.source !== "router") continue;
|
|
98
|
+
buffer.push({ slug: c.slug, t: row.created_at });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (buffer.length > 0) replay(buffer);
|
|
103
|
+
log.info(
|
|
104
|
+
{ inserted: buffer.length, rowsScanned: rows.length, parseFailures },
|
|
105
|
+
`Backfilled ${buffer.length} injection events from ${rows.length} activation log rows`,
|
|
106
|
+
);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function downMemoryV2InjectionEvents(database: DrizzleDb): void {
|
|
111
|
+
const raw = getSqliteFrom(database);
|
|
112
|
+
raw.exec(/*sql*/ `DROP TABLE IF EXISTS memory_v2_injection_events`);
|
|
113
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type DrizzleDb, getSqliteFrom } from "../db-connection.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Strip `base_url` from provider connections whose provider is NOT
|
|
5
|
+
* `openai-compatible`. These values should never have been accepted — the
|
|
6
|
+
* route layer now rejects them, but existing rows may still carry one from
|
|
7
|
+
* before the validation was added. Setting it to NULL prevents
|
|
8
|
+
* API-key exfiltration via a redirected base URL.
|
|
9
|
+
*
|
|
10
|
+
* Idempotent — re-running is a no-op once all non-openai-compatible rows
|
|
11
|
+
* already have NULL base_url.
|
|
12
|
+
*/
|
|
13
|
+
export function migrateStripBaseUrlNonOpenaiCompatible(
|
|
14
|
+
database: DrizzleDb,
|
|
15
|
+
): void {
|
|
16
|
+
const raw = getSqliteFrom(database);
|
|
17
|
+
|
|
18
|
+
// Only clear base_url on rows where provider is NOT openai-compatible.
|
|
19
|
+
raw.exec(
|
|
20
|
+
`UPDATE provider_connections SET base_url = NULL WHERE provider != 'openai-compatible' AND base_url IS NOT NULL`,
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
2
|
+
|
|
3
|
+
export function migrateOnboardingEventsPriorAssistants(
|
|
4
|
+
database: DrizzleDb,
|
|
5
|
+
): void {
|
|
6
|
+
try {
|
|
7
|
+
database.run(
|
|
8
|
+
/*sql*/ `ALTER TABLE onboarding_events ADD COLUMN prior_assistants_json TEXT`,
|
|
9
|
+
);
|
|
10
|
+
} catch {
|
|
11
|
+
/* already exists */
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
2
|
+
import { tableHasColumn } from "./schema-introspection.js";
|
|
3
|
+
import { withCrashRecovery } from "./validate-migration-state.js";
|
|
4
|
+
|
|
5
|
+
const CHECKPOINT_KEY = "migration_conversation_cleaned_at_v1";
|
|
6
|
+
|
|
7
|
+
const COLUMN_NAME = "cleaned_at";
|
|
8
|
+
const COLUMN_DEFINITION = "cleaned_at INTEGER";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Add a `cleaned_at` timestamp to conversations.
|
|
12
|
+
*
|
|
13
|
+
* Records the moment `/clean` ran. The load path uses it to skip metadata
|
|
14
|
+
* reinjection (and strip injection prefixes from message content) for
|
|
15
|
+
* messages whose `created_at < cleaned_at`, so the clean survives daemon
|
|
16
|
+
* restart and conversation eviction. `forkConversation` copies the marker
|
|
17
|
+
* to the child only when the fork point is at-or-after the clean.
|
|
18
|
+
*/
|
|
19
|
+
export function migrateConversationCleanedAt(database: DrizzleDb): void {
|
|
20
|
+
withCrashRecovery(database, CHECKPOINT_KEY, () => {
|
|
21
|
+
if (tableHasColumn(database, "conversations", COLUMN_NAME)) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
database.run(`ALTER TABLE conversations ADD COLUMN ${COLUMN_DEFINITION}`);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function downConversationCleanedAt(database: DrizzleDb): void {
|
|
29
|
+
if (!tableHasColumn(database, "conversations", COLUMN_NAME)) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
database.run(`ALTER TABLE conversations DROP COLUMN ${COLUMN_NAME}`);
|
|
33
|
+
}
|
|
@@ -217,6 +217,23 @@ export {
|
|
|
217
217
|
export { migrateProviderConnectionBaseUrlAndModels } from "./250-provider-connection-base-url-and-models.js";
|
|
218
218
|
export { downA2ATasks, migrateA2ATasks } from "./251-a2a-tasks.js";
|
|
219
219
|
export { migrateLlmRequestLogAgentLoopExitReason } from "./252-llm-request-log-agent-loop-exit-reason.js";
|
|
220
|
+
export { migrateConversationLastNotifiedProfile } from "./253-conversation-last-notified-profile.js";
|
|
221
|
+
export { migrateCreateDocumentComments } from "./253-document-comments.js";
|
|
222
|
+
export {
|
|
223
|
+
downExternalConversationBindingChatName,
|
|
224
|
+
migrateExternalConversationBindingChatName,
|
|
225
|
+
} from "./254-external-conversation-binding-chat-name.js";
|
|
226
|
+
export { migrateChannelInboundDeliveryAttempts } from "./255-channel-inbound-delivery-attempts.js";
|
|
227
|
+
export {
|
|
228
|
+
downMemoryV2InjectionEvents,
|
|
229
|
+
migrateMemoryV2InjectionEvents,
|
|
230
|
+
} from "./256-memory-v2-injection-events.js";
|
|
231
|
+
export { migrateStripBaseUrlNonOpenaiCompatible } from "./257-strip-base-url-non-openai-compatible.js";
|
|
232
|
+
export { migrateOnboardingEventsPriorAssistants } from "./258-onboarding-events-prior-assistants.js";
|
|
233
|
+
export {
|
|
234
|
+
downConversationCleanedAt,
|
|
235
|
+
migrateConversationCleanedAt,
|
|
236
|
+
} from "./259-conversation-cleaned-at.js";
|
|
220
237
|
export {
|
|
221
238
|
MIGRATION_REGISTRY,
|
|
222
239
|
type MigrationRegistryEntry,
|
|
@@ -50,6 +50,9 @@ import { downToolInvocationsMatchedRuleId } from "./236-tool-invocations-matched
|
|
|
50
50
|
import { downHeartbeatRuns } from "./237-heartbeat-runs.js";
|
|
51
51
|
import { downNormalizeSlackExternalContent } from "./249-normalize-slack-external-content.js";
|
|
52
52
|
import { downA2ATasks } from "./251-a2a-tasks.js";
|
|
53
|
+
import { downExternalConversationBindingChatName } from "./254-external-conversation-binding-chat-name.js";
|
|
54
|
+
import { downMemoryV2InjectionEvents } from "./256-memory-v2-injection-events.js";
|
|
55
|
+
import { downConversationCleanedAt } from "./259-conversation-cleaned-at.js";
|
|
53
56
|
|
|
54
57
|
export interface MigrationRegistryEntry {
|
|
55
58
|
/** The checkpoint key written to memory_checkpoints on completion. */
|
|
@@ -428,6 +431,28 @@ export const MIGRATION_REGISTRY: MigrationRegistryEntry[] = [
|
|
|
428
431
|
"Create a2a_tasks table for tracking A2A request/response lifecycle",
|
|
429
432
|
down: downA2ATasks,
|
|
430
433
|
},
|
|
434
|
+
{
|
|
435
|
+
key: "migration_external_conversation_binding_chat_name_v1",
|
|
436
|
+
version: 50,
|
|
437
|
+
description:
|
|
438
|
+
"Add external_chat_name to external conversation bindings for channel footer metadata",
|
|
439
|
+
down: downExternalConversationBindingChatName,
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
key: "migration_memory_v2_injection_events_v1",
|
|
443
|
+
version: 51,
|
|
444
|
+
dependsOn: ["migration_memory_v2_activation_logs_v1"],
|
|
445
|
+
description:
|
|
446
|
+
"Create memory_v2_injection_events table and backfill from activation logs for EMA-based tier 2 routing",
|
|
447
|
+
down: downMemoryV2InjectionEvents,
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
key: "migration_conversation_cleaned_at_v1",
|
|
451
|
+
version: 52,
|
|
452
|
+
description:
|
|
453
|
+
"Add cleaned_at timestamp to conversations so /clean survives reload and forks inherit conditionally on fork point",
|
|
454
|
+
down: downConversationCleanedAt,
|
|
455
|
+
},
|
|
431
456
|
];
|
|
432
457
|
|
|
433
458
|
export function getMaxMigrationVersion(): number {
|
|
@@ -14,6 +14,7 @@ export interface OnboardingEvent {
|
|
|
14
14
|
tone: string | null;
|
|
15
15
|
googleConnected: boolean | null;
|
|
16
16
|
googleScopesJson: string | null;
|
|
17
|
+
priorAssistantsJson: string | null;
|
|
17
18
|
abVariant: string | null;
|
|
18
19
|
}
|
|
19
20
|
|
|
@@ -24,6 +25,7 @@ export interface RecordOnboardingEventParams {
|
|
|
24
25
|
tone?: string;
|
|
25
26
|
googleConnected?: boolean;
|
|
26
27
|
googleScopes?: string[];
|
|
28
|
+
priorAssistants?: string[];
|
|
27
29
|
abVariant?: string;
|
|
28
30
|
}
|
|
29
31
|
|
|
@@ -47,6 +49,9 @@ export function recordOnboardingEvent(
|
|
|
47
49
|
googleScopesJson: params.googleScopes
|
|
48
50
|
? JSON.stringify(params.googleScopes)
|
|
49
51
|
: null,
|
|
52
|
+
priorAssistantsJson: params.priorAssistants
|
|
53
|
+
? JSON.stringify(params.priorAssistants)
|
|
54
|
+
: null,
|
|
50
55
|
abVariant: params.abVariant ?? null,
|
|
51
56
|
};
|
|
52
57
|
db.insert(onboardingEvents)
|
|
@@ -59,6 +64,7 @@ export function recordOnboardingEvent(
|
|
|
59
64
|
tone: event.tone,
|
|
60
65
|
googleConnected: event.googleConnected,
|
|
61
66
|
googleScopesJson: event.googleScopesJson,
|
|
67
|
+
priorAssistantsJson: event.priorAssistantsJson,
|
|
62
68
|
abVariant: event.abVariant,
|
|
63
69
|
})
|
|
64
70
|
.run();
|
|
@@ -85,6 +91,7 @@ export function queryUnreportedOnboardingEvents(
|
|
|
85
91
|
tone: onboardingEvents.tone,
|
|
86
92
|
googleConnected: onboardingEvents.googleConnected,
|
|
87
93
|
googleScopesJson: onboardingEvents.googleScopesJson,
|
|
94
|
+
priorAssistantsJson: onboardingEvents.priorAssistantsJson,
|
|
88
95
|
abVariant: onboardingEvents.abVariant,
|
|
89
96
|
})
|
|
90
97
|
.from(onboardingEvents)
|
|
@@ -78,6 +78,7 @@ export const externalConversationBindings = sqliteTable(
|
|
|
78
78
|
.references(() => conversations.id, { onDelete: "cascade" }),
|
|
79
79
|
sourceChannel: text("source_channel").notNull(),
|
|
80
80
|
externalChatId: text("external_chat_id").notNull(),
|
|
81
|
+
externalChatName: text("external_chat_name"),
|
|
81
82
|
externalThreadId: text("external_thread_id"),
|
|
82
83
|
externalUserId: text("external_user_id"),
|
|
83
84
|
displayName: text("display_name"),
|
|
@@ -21,6 +21,7 @@ export const conversations = sqliteTable(
|
|
|
21
21
|
.notNull()
|
|
22
22
|
.default(0),
|
|
23
23
|
contextCompactedAt: integer("context_compacted_at"),
|
|
24
|
+
cleanedAt: integer("cleaned_at"),
|
|
24
25
|
slackContextCompactionWatermarkTs: text(
|
|
25
26
|
"slack_context_compaction_watermark_ts",
|
|
26
27
|
),
|
|
@@ -41,6 +42,7 @@ export const conversations = sqliteTable(
|
|
|
41
42
|
inferenceProfile: text("inference_profile"),
|
|
42
43
|
inferenceProfileSessionId: text("inference_profile_session_id"),
|
|
43
44
|
inferenceProfileExpiresAt: integer("inference_profile_expires_at"),
|
|
45
|
+
lastNotifiedInferenceProfile: text("last_notified_inference_profile"),
|
|
44
46
|
},
|
|
45
47
|
(table) => [
|
|
46
48
|
index("idx_conversations_updated_at").on(table.updatedAt),
|
|
@@ -150,6 +152,7 @@ export const channelInboundEvents = sqliteTable("channel_inbound_events", {
|
|
|
150
152
|
deliveryStatus: text("delivery_status").notNull().default("pending"),
|
|
151
153
|
processingStatus: text("processing_status").notNull().default("pending"),
|
|
152
154
|
processingAttempts: integer("processing_attempts").notNull().default(0),
|
|
155
|
+
deliveryAttempts: integer("delivery_attempts").notNull().default(0),
|
|
153
156
|
lastProcessingError: text("last_processing_error"),
|
|
154
157
|
retryAfter: integer("retry_after"),
|
|
155
158
|
rawPayload: text("raw_payload"),
|
|
@@ -242,6 +242,7 @@ export const onboardingEvents = sqliteTable("onboarding_events", {
|
|
|
242
242
|
tone: text("tone"),
|
|
243
243
|
googleConnected: integer("google_connected", { mode: "boolean" }),
|
|
244
244
|
googleScopesJson: text("google_scopes_json"),
|
|
245
|
+
priorAssistantsJson: text("prior_assistants_json"),
|
|
245
246
|
abVariant: text("ab_variant"),
|
|
246
247
|
});
|
|
247
248
|
|