@vellumai/assistant 0.4.49 → 0.4.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +24 -33
- package/README.md +3 -3
- package/docs/architecture/memory.md +180 -119
- package/package.json +2 -2
- package/src/__tests__/agent-loop.test.ts +3 -1
- package/src/__tests__/anthropic-provider.test.ts +114 -23
- package/src/__tests__/approval-cascade.test.ts +1 -15
- package/src/__tests__/approval-routes-http.test.ts +2 -0
- package/src/__tests__/assistant-feature-flag-guard.test.ts +0 -23
- package/src/__tests__/canonical-guardian-store.test.ts +95 -0
- package/src/__tests__/checker.test.ts +13 -0
- package/src/__tests__/config-schema.test.ts +1 -68
- package/src/__tests__/context-memory-e2e.test.ts +11 -100
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +8 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/credential-security-e2e.test.ts +1 -0
- package/src/__tests__/credential-vault-unit.test.ts +4 -0
- package/src/__tests__/credential-vault.test.ts +13 -1
- package/src/__tests__/cu-unified-flow.test.ts +532 -0
- package/src/__tests__/date-context.test.ts +93 -77
- package/src/__tests__/deterministic-verification-control-plane.test.ts +64 -0
- package/src/__tests__/guardian-routing-invariants.test.ts +93 -0
- package/src/__tests__/history-repair.test.ts +245 -0
- package/src/__tests__/host-cu-proxy.test.ts +165 -3
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- package/src/__tests__/invite-redemption-service.test.ts +65 -1
- package/src/__tests__/keychain-broker-client.test.ts +4 -4
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +56 -18
- package/src/__tests__/memory-lifecycle-e2e.test.ts +244 -387
- package/src/__tests__/memory-recall-quality.test.ts +244 -407
- package/src/__tests__/memory-regressions.experimental.test.ts +126 -101
- package/src/__tests__/memory-regressions.test.ts +477 -2841
- package/src/__tests__/memory-retrieval.benchmark.test.ts +33 -150
- package/src/__tests__/memory-upsert-concurrency.test.ts +5 -244
- package/src/__tests__/mime-builder.test.ts +28 -0
- package/src/__tests__/native-web-search.test.ts +1 -0
- package/src/__tests__/oauth-cli.test.ts +572 -5
- package/src/__tests__/oauth-store.test.ts +120 -6
- package/src/__tests__/qdrant-collection-migration.test.ts +53 -8
- package/src/__tests__/registry.test.ts +0 -1
- package/src/__tests__/relay-server.test.ts +46 -1
- package/src/__tests__/schedule-tools.test.ts +32 -0
- package/src/__tests__/script-proxy-certs.test.ts +1 -1
- package/src/__tests__/secret-onetime-send.test.ts +1 -0
- package/src/__tests__/secure-keys.test.ts +7 -2
- package/src/__tests__/send-endpoint-busy.test.ts +3 -0
- package/src/__tests__/session-abort-tool-results.test.ts +1 -14
- package/src/__tests__/session-agent-loop-overflow.test.ts +1583 -0
- package/src/__tests__/session-agent-loop.test.ts +19 -15
- package/src/__tests__/session-confirmation-signals.test.ts +1 -15
- package/src/__tests__/session-error.test.ts +124 -2
- package/src/__tests__/session-history-web-search.test.ts +918 -0
- package/src/__tests__/session-pre-run-repair.test.ts +1 -14
- package/src/__tests__/session-provider-retry-repair.test.ts +25 -28
- package/src/__tests__/session-queue.test.ts +37 -27
- package/src/__tests__/session-runtime-assembly.test.ts +54 -0
- package/src/__tests__/session-slash-known.test.ts +1 -15
- package/src/__tests__/session-slash-queue.test.ts +1 -15
- package/src/__tests__/session-slash-unknown.test.ts +1 -15
- package/src/__tests__/session-workspace-cache-state.test.ts +3 -33
- package/src/__tests__/session-workspace-injection.test.ts +3 -37
- package/src/__tests__/session-workspace-tool-tracking.test.ts +3 -37
- package/src/__tests__/skills-install-extract.test.ts +93 -0
- package/src/__tests__/skillssh-registry.test.ts +451 -0
- package/src/__tests__/trust-store.test.ts +15 -0
- package/src/__tests__/voice-invite-redemption.test.ts +32 -1
- package/src/agent/ax-tree-compaction.test.ts +51 -0
- package/src/agent/loop.ts +39 -12
- package/src/approvals/AGENTS.md +1 -1
- package/src/approvals/guardian-request-resolvers.ts +14 -2
- package/src/bundler/compiler-tools.ts +66 -2
- package/src/calls/call-domain.ts +132 -0
- package/src/calls/call-store.ts +6 -0
- package/src/calls/relay-server.ts +43 -5
- package/src/calls/relay-setup-router.ts +17 -1
- package/src/calls/twilio-config.ts +1 -1
- package/src/calls/types.ts +3 -1
- package/src/cli/commands/doctor.ts +4 -3
- package/src/cli/commands/mcp.ts +46 -59
- package/src/cli/commands/memory.ts +16 -165
- package/src/cli/commands/oauth/apps.ts +31 -2
- package/src/cli/commands/oauth/connections.ts +431 -97
- package/src/cli/commands/oauth/providers.ts +15 -1
- package/src/cli/commands/sessions.ts +5 -2
- package/src/cli/commands/skills.ts +173 -1
- package/src/cli/http-client.ts +0 -20
- package/src/cli/main-screen.tsx +2 -2
- package/src/cli/program.ts +5 -6
- package/src/cli.ts +4 -10
- package/src/config/bundled-skills/computer-use/TOOLS.json +1 -1
- package/src/config/bundled-skills/computer-use/tools/computer-use-observe.ts +12 -0
- package/src/config/bundled-tool-registry.ts +2 -5
- package/src/config/schema.ts +1 -12
- package/src/config/schemas/memory-lifecycle.ts +0 -9
- package/src/config/schemas/memory-processing.ts +0 -180
- package/src/config/schemas/memory-retrieval.ts +32 -104
- package/src/config/schemas/memory.ts +0 -10
- package/src/config/types.ts +0 -4
- package/src/context/window-manager.ts +4 -1
- package/src/daemon/config-watcher.ts +61 -3
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/date-context.ts +114 -31
- package/src/daemon/handlers/sessions.ts +18 -13
- package/src/daemon/handlers/skills.ts +20 -1
- package/src/daemon/history-repair.ts +72 -8
- package/src/daemon/host-cu-proxy.ts +55 -26
- package/src/daemon/lifecycle.ts +31 -3
- package/src/daemon/mcp-reload-service.ts +2 -2
- package/src/daemon/message-types/computer-use.ts +1 -12
- package/src/daemon/message-types/memory.ts +4 -16
- package/src/daemon/message-types/messages.ts +1 -0
- package/src/daemon/message-types/sessions.ts +4 -0
- package/src/daemon/server.ts +12 -1
- package/src/daemon/session-agent-loop-handlers.ts +38 -0
- package/src/daemon/session-agent-loop.ts +334 -48
- package/src/daemon/session-error.ts +89 -6
- package/src/daemon/session-history.ts +17 -7
- package/src/daemon/session-media-retry.ts +6 -2
- package/src/daemon/session-memory.ts +69 -149
- package/src/daemon/session-process.ts +10 -1
- package/src/daemon/session-runtime-assembly.ts +49 -19
- package/src/daemon/session-surfaces.ts +4 -1
- package/src/daemon/session-tool-setup.ts +7 -1
- package/src/daemon/session.ts +12 -2
- package/src/instrument.ts +61 -1
- package/src/memory/admin.ts +2 -191
- package/src/memory/canonical-guardian-store.ts +38 -2
- package/src/memory/conversation-crud.ts +0 -33
- package/src/memory/conversation-queries.ts +22 -3
- package/src/memory/db-init.ts +28 -0
- package/src/memory/embedding-backend.ts +84 -8
- package/src/memory/embedding-types.ts +9 -1
- package/src/memory/indexer.ts +7 -46
- package/src/memory/items-extractor.ts +274 -76
- package/src/memory/job-handlers/backfill.ts +2 -127
- package/src/memory/job-handlers/cleanup.ts +2 -16
- package/src/memory/job-handlers/extraction.ts +2 -138
- package/src/memory/job-handlers/index-maintenance.ts +1 -6
- package/src/memory/job-handlers/summarization.ts +3 -148
- package/src/memory/job-utils.ts +21 -59
- package/src/memory/jobs-store.ts +1 -159
- package/src/memory/jobs-worker.ts +9 -52
- package/src/memory/migrations/104-core-indexes.ts +3 -3
- package/src/memory/migrations/149-oauth-tables.ts +2 -0
- package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +98 -0
- package/src/memory/migrations/151-oauth-providers-ping-url.ts +11 -0
- package/src/memory/migrations/152-memory-item-supersession.ts +44 -0
- package/src/memory/migrations/153-drop-entity-tables.ts +15 -0
- package/src/memory/migrations/154-drop-fts.ts +20 -0
- package/src/memory/migrations/155-drop-conflicts.ts +7 -0
- package/src/memory/migrations/156-call-session-invite-metadata.ts +24 -0
- package/src/memory/migrations/index.ts +7 -0
- package/src/memory/qdrant-client.ts +148 -51
- package/src/memory/raw-query.ts +1 -1
- package/src/memory/retriever.test.ts +294 -273
- package/src/memory/retriever.ts +421 -645
- package/src/memory/schema/calls.ts +2 -0
- package/src/memory/schema/memory-core.ts +3 -48
- package/src/memory/schema/oauth.ts +2 -0
- package/src/memory/search/formatting.ts +263 -176
- package/src/memory/search/lexical.ts +1 -254
- package/src/memory/search/ranking.ts +0 -455
- package/src/memory/search/semantic.ts +100 -14
- package/src/memory/search/staleness.ts +47 -0
- package/src/memory/search/tier-classifier.ts +21 -0
- package/src/memory/search/types.ts +15 -77
- package/src/memory/task-memory-cleanup.ts +4 -6
- package/src/messaging/providers/gmail/mime-builder.ts +17 -7
- package/src/oauth/byo-connection.test.ts +8 -1
- package/src/oauth/oauth-store.ts +113 -27
- package/src/oauth/seed-providers.ts +6 -0
- package/src/oauth/token-persistence.ts +11 -3
- package/src/permissions/defaults.ts +1 -0
- package/src/permissions/trust-store.ts +23 -1
- package/src/playbooks/playbook-compiler.ts +1 -1
- package/src/prompts/system-prompt.ts +18 -2
- package/src/providers/anthropic/client.ts +56 -126
- package/src/providers/types.ts +7 -1
- package/src/runtime/AGENTS.md +9 -0
- package/src/runtime/auth/route-policy.ts +6 -3
- package/src/runtime/guardian-reply-router.ts +24 -22
- package/src/runtime/http-server.ts +2 -2
- package/src/runtime/invite-redemption-service.ts +19 -1
- package/src/runtime/invite-service.ts +25 -0
- package/src/runtime/pending-interactions.ts +2 -2
- package/src/runtime/routes/brain-graph-routes.ts +10 -90
- package/src/runtime/routes/conversation-routes.ts +9 -1
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +21 -12
- package/src/runtime/routes/memory-item-routes.test.ts +754 -0
- package/src/runtime/routes/memory-item-routes.ts +503 -0
- package/src/runtime/routes/session-management-routes.ts +3 -3
- package/src/runtime/routes/settings-routes.ts +2 -2
- package/src/runtime/routes/trust-rules-routes.ts +14 -0
- package/src/runtime/routes/workspace-routes.ts +2 -1
- package/src/security/keychain-broker-client.ts +17 -4
- package/src/security/secure-keys.ts +25 -3
- package/src/security/token-manager.ts +36 -36
- package/src/skills/catalog-install.ts +74 -18
- package/src/skills/skillssh-registry.ts +503 -0
- package/src/tools/assets/search.ts +5 -1
- package/src/tools/computer-use/definitions.ts +0 -10
- package/src/tools/computer-use/registry.ts +1 -1
- package/src/tools/credentials/vault.ts +1 -3
- package/src/tools/memory/definitions.ts +4 -13
- package/src/tools/memory/handlers.test.ts +83 -103
- package/src/tools/memory/handlers.ts +50 -85
- package/src/tools/schedule/create.ts +8 -1
- package/src/tools/schedule/update.ts +8 -1
- package/src/tools/skills/load.ts +25 -2
- package/src/__tests__/clarification-resolver.test.ts +0 -193
- package/src/__tests__/conflict-intent-tokenization.test.ts +0 -160
- package/src/__tests__/conflict-policy.test.ts +0 -269
- package/src/__tests__/conflict-store.test.ts +0 -372
- package/src/__tests__/contradiction-checker.test.ts +0 -361
- package/src/__tests__/entity-extractor.test.ts +0 -211
- package/src/__tests__/entity-search.test.ts +0 -1117
- package/src/__tests__/profile-compiler.test.ts +0 -392
- package/src/__tests__/session-conflict-gate.test.ts +0 -1228
- package/src/__tests__/session-profile-injection.test.ts +0 -557
- package/src/config/bundled-skills/knowledge-graph/SKILL.md +0 -25
- package/src/config/bundled-skills/knowledge-graph/TOOLS.json +0 -66
- package/src/config/bundled-skills/knowledge-graph/tools/graph-query.ts +0 -211
- package/src/daemon/session-conflict-gate.ts +0 -167
- package/src/daemon/session-dynamic-profile.ts +0 -77
- package/src/memory/clarification-resolver.ts +0 -417
- package/src/memory/conflict-intent.ts +0 -205
- package/src/memory/conflict-policy.ts +0 -127
- package/src/memory/conflict-store.ts +0 -410
- package/src/memory/contradiction-checker.ts +0 -508
- package/src/memory/entity-extractor.ts +0 -535
- package/src/memory/format-recall.ts +0 -47
- package/src/memory/fts-reconciler.ts +0 -165
- package/src/memory/job-handlers/conflict.ts +0 -200
- package/src/memory/profile-compiler.ts +0 -195
- package/src/memory/recall-cache.ts +0 -117
- package/src/memory/search/entity.ts +0 -535
- package/src/memory/search/query-expansion.test.ts +0 -70
- package/src/memory/search/query-expansion.ts +0 -118
- package/src/runtime/routes/mcp-routes.ts +0 -20
|
@@ -2,20 +2,11 @@ import { getConfig } from "../config/loader.js";
|
|
|
2
2
|
import type { AssistantConfig } from "../config/types.js";
|
|
3
3
|
import { getLogger } from "../util/logger.js";
|
|
4
4
|
import { rawRun } from "./db.js";
|
|
5
|
-
import {
|
|
5
|
+
import { backfillJob } from "./job-handlers/backfill.js";
|
|
6
6
|
import {
|
|
7
|
-
backfillEntityRelationsJob,
|
|
8
|
-
backfillJob,
|
|
9
|
-
} from "./job-handlers/backfill.js";
|
|
10
|
-
import {
|
|
11
|
-
checkContradictionsJob,
|
|
12
7
|
cleanupStaleSupersededItemsJob,
|
|
13
8
|
pruneOldConversationsJob,
|
|
14
9
|
} from "./job-handlers/cleanup.js";
|
|
15
|
-
import {
|
|
16
|
-
cleanupResolvedConflictsJob,
|
|
17
|
-
resolvePendingConflictsForMessageJob,
|
|
18
|
-
} from "./job-handlers/conflict.js";
|
|
19
10
|
// ── Per-job-type handlers ──────────────────────────────────────────
|
|
20
11
|
import {
|
|
21
12
|
embedAttachmentJob,
|
|
@@ -24,19 +15,13 @@ import {
|
|
|
24
15
|
embedSegmentJob,
|
|
25
16
|
embedSummaryJob,
|
|
26
17
|
} from "./job-handlers/embedding.js";
|
|
27
|
-
import {
|
|
28
|
-
extractEntitiesJob,
|
|
29
|
-
extractItemsJob,
|
|
30
|
-
} from "./job-handlers/extraction.js";
|
|
18
|
+
import { extractItemsJob } from "./job-handlers/extraction.js";
|
|
31
19
|
import {
|
|
32
20
|
deleteQdrantVectorsJob,
|
|
33
21
|
rebuildIndexJob,
|
|
34
22
|
} from "./job-handlers/index-maintenance.js";
|
|
35
23
|
import { mediaProcessingJob } from "./job-handlers/media-processing.js";
|
|
36
|
-
import {
|
|
37
|
-
buildConversationSummaryJob,
|
|
38
|
-
buildGlobalSummaryJob,
|
|
39
|
-
} from "./job-handlers/summarization.js";
|
|
24
|
+
import { buildConversationSummaryJob } from "./job-handlers/summarization.js";
|
|
40
25
|
import {
|
|
41
26
|
BackendUnavailableError,
|
|
42
27
|
classifyError,
|
|
@@ -47,20 +32,14 @@ import {
|
|
|
47
32
|
claimMemoryJobs,
|
|
48
33
|
completeMemoryJob,
|
|
49
34
|
deferMemoryJob,
|
|
50
|
-
enqueueCleanupResolvedConflictsJob,
|
|
51
35
|
enqueueCleanupStaleSupersededItemsJob,
|
|
52
36
|
enqueuePruneOldConversationsJob,
|
|
53
|
-
enqueueReconcileFtsJob,
|
|
54
37
|
failMemoryJob,
|
|
55
38
|
failStalledJobs,
|
|
56
39
|
type MemoryJob,
|
|
57
40
|
resetRunningJobsToPending,
|
|
58
41
|
} from "./jobs-store.js";
|
|
59
42
|
import { QdrantCircuitOpenError } from "./qdrant-circuit-breaker.js";
|
|
60
|
-
import { bumpMemoryVersion } from "./recall-cache.js";
|
|
61
|
-
|
|
62
|
-
// Re-export public utilities consumed by tests and other modules
|
|
63
|
-
export { currentWeekWindow } from "./job-utils.js";
|
|
64
43
|
|
|
65
44
|
const log = getLogger("memory-jobs-worker");
|
|
66
45
|
|
|
@@ -157,7 +136,6 @@ export async function runMemoryJobsOnce(
|
|
|
157
136
|
try {
|
|
158
137
|
await processJob(job, config);
|
|
159
138
|
completeMemoryJob(job.id);
|
|
160
|
-
bumpMemoryVersion();
|
|
161
139
|
groupProcessed += 1;
|
|
162
140
|
} catch (err) {
|
|
163
141
|
try {
|
|
@@ -292,13 +270,7 @@ async function processJob(
|
|
|
292
270
|
await extractItemsJob(job);
|
|
293
271
|
return;
|
|
294
272
|
case "extract_entities":
|
|
295
|
-
|
|
296
|
-
return;
|
|
297
|
-
case "resolve_pending_conflicts_for_message":
|
|
298
|
-
await resolvePendingConflictsForMessageJob(job, config);
|
|
299
|
-
return;
|
|
300
|
-
case "cleanup_resolved_conflicts":
|
|
301
|
-
cleanupResolvedConflictsJob(job, config);
|
|
273
|
+
// Entity extraction has been removed — silently drop legacy jobs
|
|
302
274
|
return;
|
|
303
275
|
case "cleanup_stale_superseded_items":
|
|
304
276
|
cleanupStaleSupersededItemsJob(job, config);
|
|
@@ -306,30 +278,22 @@ async function processJob(
|
|
|
306
278
|
case "prune_old_conversations":
|
|
307
279
|
pruneOldConversationsJob(job, config);
|
|
308
280
|
return;
|
|
309
|
-
case "check_contradictions":
|
|
310
|
-
await checkContradictionsJob(job);
|
|
311
|
-
return;
|
|
312
281
|
case "build_conversation_summary":
|
|
313
282
|
await buildConversationSummaryJob(job, config);
|
|
314
283
|
return;
|
|
315
|
-
case "refresh_weekly_summary":
|
|
316
|
-
await buildGlobalSummaryJob("weekly_global", config);
|
|
317
|
-
return;
|
|
318
|
-
case "refresh_monthly_summary":
|
|
319
|
-
await buildGlobalSummaryJob("monthly_global", config);
|
|
320
|
-
return;
|
|
321
284
|
case "backfill":
|
|
322
285
|
backfillJob(job, config);
|
|
323
286
|
return;
|
|
324
287
|
case "backfill_entity_relations":
|
|
325
|
-
|
|
288
|
+
// Entity relation backfill has been removed — silently drop legacy jobs
|
|
289
|
+
return;
|
|
290
|
+
case "refresh_weekly_summary":
|
|
291
|
+
case "refresh_monthly_summary":
|
|
292
|
+
// Global summary rollups have been removed — silently drop legacy jobs
|
|
326
293
|
return;
|
|
327
294
|
case "rebuild_index":
|
|
328
295
|
rebuildIndexJob();
|
|
329
296
|
return;
|
|
330
|
-
case "reconcile_fts":
|
|
331
|
-
reconcileFtsIndexes();
|
|
332
|
-
return;
|
|
333
297
|
case "delete_qdrant_vectors":
|
|
334
298
|
await deleteQdrantVectorsJob(job);
|
|
335
299
|
return;
|
|
@@ -371,9 +335,6 @@ export function maybeEnqueueScheduledCleanupJobs(
|
|
|
371
335
|
if (nowMs - lastScheduledCleanupEnqueueMs < cleanup.enqueueIntervalMs)
|
|
372
336
|
return false;
|
|
373
337
|
|
|
374
|
-
const resolvedConflictsJobId = enqueueCleanupResolvedConflictsJob(
|
|
375
|
-
cleanup.resolvedConflictRetentionMs,
|
|
376
|
-
);
|
|
377
338
|
const staleSupersededItemsJobId = enqueueCleanupStaleSupersededItemsJob(
|
|
378
339
|
cleanup.supersededItemRetentionMs,
|
|
379
340
|
);
|
|
@@ -381,16 +342,12 @@ export function maybeEnqueueScheduledCleanupJobs(
|
|
|
381
342
|
cleanup.conversationRetentionDays > 0
|
|
382
343
|
? enqueuePruneOldConversationsJob(cleanup.conversationRetentionDays)
|
|
383
344
|
: null;
|
|
384
|
-
const reconcileFtsJobId = enqueueReconcileFtsJob();
|
|
385
345
|
lastScheduledCleanupEnqueueMs = nowMs;
|
|
386
346
|
log.debug(
|
|
387
347
|
{
|
|
388
|
-
resolvedConflictsJobId,
|
|
389
348
|
staleSupersededItemsJobId,
|
|
390
349
|
pruneConversationsJobId,
|
|
391
|
-
reconcileFtsJobId,
|
|
392
350
|
enqueueIntervalMs: cleanup.enqueueIntervalMs,
|
|
393
|
-
resolvedConflictRetentionMs: cleanup.resolvedConflictRetentionMs,
|
|
394
351
|
supersededItemRetentionMs: cleanup.supersededItemRetentionMs,
|
|
395
352
|
conversationRetentionDays: cleanup.conversationRetentionDays,
|
|
396
353
|
},
|
|
@@ -69,9 +69,9 @@ export function createCoreIndexes(database: DrizzleDb): void {
|
|
|
69
69
|
database.run(
|
|
70
70
|
/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_items_last_seen_at ON memory_items(last_seen_at)`,
|
|
71
71
|
);
|
|
72
|
-
// Partial covering index for
|
|
73
|
-
//
|
|
74
|
-
//
|
|
72
|
+
// Partial covering index for active memory item queries: this index lets SQLite
|
|
73
|
+
// scan only active non-invalidated rows and return columns without touching
|
|
74
|
+
// the main table.
|
|
75
75
|
migrateDropActiveSearchIndex(database);
|
|
76
76
|
database.run(/*sql*/ `
|
|
77
77
|
CREATE INDEX IF NOT EXISTS idx_memory_items_active_search
|
|
@@ -18,6 +18,7 @@ export function createOAuthTables(database: DrizzleDb): void {
|
|
|
18
18
|
extra_params TEXT,
|
|
19
19
|
callback_transport TEXT,
|
|
20
20
|
loopback_port INTEGER,
|
|
21
|
+
ping_url TEXT,
|
|
21
22
|
created_at INTEGER NOT NULL,
|
|
22
23
|
updated_at INTEGER NOT NULL
|
|
23
24
|
)
|
|
@@ -28,6 +29,7 @@ export function createOAuthTables(database: DrizzleDb): void {
|
|
|
28
29
|
id TEXT PRIMARY KEY,
|
|
29
30
|
provider_key TEXT NOT NULL REFERENCES oauth_providers(provider_key),
|
|
30
31
|
client_id TEXT NOT NULL,
|
|
32
|
+
client_secret_credential_path TEXT NOT NULL DEFAULT '',
|
|
31
33
|
created_at INTEGER NOT NULL,
|
|
32
34
|
updated_at INTEGER NOT NULL
|
|
33
35
|
)
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { type DrizzleDb, getSqliteFrom } from "../db-connection.js";
|
|
2
|
+
import { withCrashRecovery } from "./validate-migration-state.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Add client_secret_credential_path column to oauth_apps.
|
|
6
|
+
*
|
|
7
|
+
* Makes explicit what was previously implicit: the credential path pattern
|
|
8
|
+
* `oauth_app/${id}/client_secret`. Steps:
|
|
9
|
+
*
|
|
10
|
+
* 1. ALTER TABLE to add the column (nullable initially).
|
|
11
|
+
* 2. Backfill existing rows with `oauth_app/${id}/client_secret`.
|
|
12
|
+
* 3. Rebuild the table to enforce NOT NULL (SQLite doesn't support ALTER COLUMN).
|
|
13
|
+
*
|
|
14
|
+
* Idempotent — skips if the column already exists with NOT NULL.
|
|
15
|
+
*/
|
|
16
|
+
export function migrateOAuthAppsClientSecretPath(database: DrizzleDb): void {
|
|
17
|
+
withCrashRecovery(
|
|
18
|
+
database,
|
|
19
|
+
"migration_oauth_apps_client_secret_path_v1",
|
|
20
|
+
() => {
|
|
21
|
+
const raw = getSqliteFrom(database);
|
|
22
|
+
|
|
23
|
+
// Guard: table must exist
|
|
24
|
+
const tableExists = raw
|
|
25
|
+
.query(
|
|
26
|
+
`SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'oauth_apps'`,
|
|
27
|
+
)
|
|
28
|
+
.get();
|
|
29
|
+
if (!tableExists) return;
|
|
30
|
+
|
|
31
|
+
// Guard: check if column already exists with NOT NULL
|
|
32
|
+
const colInfo = raw
|
|
33
|
+
.query(
|
|
34
|
+
`SELECT "notnull" FROM pragma_table_info('oauth_apps') WHERE name = 'client_secret_credential_path'`,
|
|
35
|
+
)
|
|
36
|
+
.get() as { notnull: number } | null;
|
|
37
|
+
if (colInfo && colInfo.notnull === 1) return;
|
|
38
|
+
|
|
39
|
+
// Step 1: Add the column (nullable) — wrapped in try/catch for idempotency
|
|
40
|
+
if (!colInfo) {
|
|
41
|
+
try {
|
|
42
|
+
raw.exec(
|
|
43
|
+
/*sql*/ `ALTER TABLE oauth_apps ADD COLUMN client_secret_credential_path TEXT`,
|
|
44
|
+
);
|
|
45
|
+
} catch {
|
|
46
|
+
// Column may already exist from a previous partial run
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Step 2: Backfill existing rows
|
|
51
|
+
raw.exec(
|
|
52
|
+
/*sql*/ `UPDATE oauth_apps SET client_secret_credential_path = 'oauth_app/' || id || '/client_secret' WHERE client_secret_credential_path IS NULL`,
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
// Step 3: Rebuild the table to enforce NOT NULL
|
|
56
|
+
raw.exec("PRAGMA foreign_keys = OFF");
|
|
57
|
+
try {
|
|
58
|
+
raw.exec("BEGIN");
|
|
59
|
+
|
|
60
|
+
raw.exec(/*sql*/ `
|
|
61
|
+
CREATE TABLE oauth_apps_new (
|
|
62
|
+
id TEXT PRIMARY KEY,
|
|
63
|
+
provider_key TEXT NOT NULL REFERENCES oauth_providers(provider_key),
|
|
64
|
+
client_id TEXT NOT NULL,
|
|
65
|
+
client_secret_credential_path TEXT NOT NULL,
|
|
66
|
+
created_at INTEGER NOT NULL,
|
|
67
|
+
updated_at INTEGER NOT NULL
|
|
68
|
+
)
|
|
69
|
+
`);
|
|
70
|
+
|
|
71
|
+
raw.exec(/*sql*/ `
|
|
72
|
+
INSERT INTO oauth_apps_new
|
|
73
|
+
SELECT id, provider_key, client_id, client_secret_credential_path, created_at, updated_at
|
|
74
|
+
FROM oauth_apps
|
|
75
|
+
`);
|
|
76
|
+
|
|
77
|
+
raw.exec(/*sql*/ `DROP TABLE oauth_apps`);
|
|
78
|
+
raw.exec(/*sql*/ `ALTER TABLE oauth_apps_new RENAME TO oauth_apps`);
|
|
79
|
+
|
|
80
|
+
// Recreate the unique index
|
|
81
|
+
raw.exec(
|
|
82
|
+
/*sql*/ `CREATE UNIQUE INDEX IF NOT EXISTS idx_oauth_apps_provider_client ON oauth_apps(provider_key, client_id)`,
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
raw.exec("COMMIT");
|
|
86
|
+
} catch (e) {
|
|
87
|
+
try {
|
|
88
|
+
raw.exec("ROLLBACK");
|
|
89
|
+
} catch {
|
|
90
|
+
/* no active transaction */
|
|
91
|
+
}
|
|
92
|
+
throw e;
|
|
93
|
+
} finally {
|
|
94
|
+
raw.exec("PRAGMA foreign_keys = ON");
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
);
|
|
98
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
2
|
+
import { getSqliteFrom } from "../db-connection.js";
|
|
3
|
+
|
|
4
|
+
export function migrateOAuthProvidersPingUrl(database: DrizzleDb): void {
|
|
5
|
+
const raw = getSqliteFrom(database);
|
|
6
|
+
try {
|
|
7
|
+
raw.exec(/*sql*/ `ALTER TABLE oauth_providers ADD COLUMN ping_url TEXT`);
|
|
8
|
+
} catch {
|
|
9
|
+
// Column already exists — nothing to do.
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
2
|
+
import { getSqliteFrom } from "../db-connection.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Add supersession tracking columns and override confidence to memory_items.
|
|
6
|
+
*
|
|
7
|
+
* - `supersedes` — references the ID of the item this one replaces
|
|
8
|
+
* - `superseded_by` — references the ID of the item that replaced this one
|
|
9
|
+
* - `override_confidence` — enum: "explicit", "tentative", "inferred" (default "inferred")
|
|
10
|
+
* - Index on (status, superseded_by) for filtering active non-superseded items
|
|
11
|
+
*
|
|
12
|
+
* All columns are added via ALTER TABLE with try/catch for idempotency.
|
|
13
|
+
*/
|
|
14
|
+
export function migrateMemoryItemSupersession(database: DrizzleDb): void {
|
|
15
|
+
const raw = getSqliteFrom(database);
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
raw.exec(
|
|
19
|
+
/*sql*/ `ALTER TABLE memory_items ADD COLUMN supersedes TEXT DEFAULT NULL`,
|
|
20
|
+
);
|
|
21
|
+
} catch {
|
|
22
|
+
// Column already exists
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
raw.exec(
|
|
27
|
+
/*sql*/ `ALTER TABLE memory_items ADD COLUMN superseded_by TEXT DEFAULT NULL`,
|
|
28
|
+
);
|
|
29
|
+
} catch {
|
|
30
|
+
// Column already exists
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
raw.exec(
|
|
35
|
+
/*sql*/ `ALTER TABLE memory_items ADD COLUMN override_confidence TEXT DEFAULT 'inferred'`,
|
|
36
|
+
);
|
|
37
|
+
} catch {
|
|
38
|
+
// Column already exists
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
raw.exec(
|
|
42
|
+
/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_items_status_superseded_by ON memory_items(status, superseded_by)`,
|
|
43
|
+
);
|
|
44
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
2
|
+
import { getSqliteFrom } from "../db-connection.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Drop entity-related tables that are no longer used.
|
|
6
|
+
*
|
|
7
|
+
* Entity search has been replaced by hybrid search on entity-rich text
|
|
8
|
+
* in item statements, so these tables are now dead weight.
|
|
9
|
+
*/
|
|
10
|
+
export function migrateDropEntityTables(database: DrizzleDb): void {
|
|
11
|
+
const raw = getSqliteFrom(database);
|
|
12
|
+
raw.exec(/*sql*/ `DROP TABLE IF EXISTS memory_item_entities`);
|
|
13
|
+
raw.exec(/*sql*/ `DROP TABLE IF EXISTS memory_entity_relations`);
|
|
14
|
+
raw.exec(/*sql*/ `DROP TABLE IF EXISTS memory_entities`);
|
|
15
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
2
|
+
import { getSqliteFrom } from "../db-connection.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Drop the memory_segment_fts virtual table and its associated triggers.
|
|
6
|
+
*
|
|
7
|
+
* The FTS-based lexical search pipeline has been replaced by Qdrant hybrid
|
|
8
|
+
* search. Keeping the FTS table around wastes disk space and adds write
|
|
9
|
+
* overhead on every segment insert/update/delete.
|
|
10
|
+
*/
|
|
11
|
+
export function migrateDropMemorySegmentFts(database: DrizzleDb): void {
|
|
12
|
+
const raw = getSqliteFrom(database);
|
|
13
|
+
|
|
14
|
+
// Drop triggers first — they reference the FTS table.
|
|
15
|
+
raw.exec(/*sql*/ `DROP TRIGGER IF EXISTS memory_segments_ai`);
|
|
16
|
+
raw.exec(/*sql*/ `DROP TRIGGER IF EXISTS memory_segments_ad`);
|
|
17
|
+
raw.exec(/*sql*/ `DROP TRIGGER IF EXISTS memory_segments_au`);
|
|
18
|
+
|
|
19
|
+
raw.exec(/*sql*/ `DROP TABLE IF EXISTS memory_segment_fts`);
|
|
20
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
2
|
+
import { getSqliteFrom } from "../db-connection.js";
|
|
3
|
+
|
|
4
|
+
export function migrateDropConflicts(database: DrizzleDb): void {
|
|
5
|
+
const raw = getSqliteFrom(database);
|
|
6
|
+
raw.exec(/*sql*/ `DROP TABLE IF EXISTS memory_item_conflicts`);
|
|
7
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Add invite metadata columns to call_sessions so outbound invite calls
|
|
5
|
+
* can persist friend/guardian names for deterministic routing in the
|
|
6
|
+
* relay setup router (mirroring how verification_session_id works for
|
|
7
|
+
* guardian verification calls).
|
|
8
|
+
*/
|
|
9
|
+
export function migrateCallSessionInviteMetadata(database: DrizzleDb): void {
|
|
10
|
+
try {
|
|
11
|
+
database.run(
|
|
12
|
+
/*sql*/ `ALTER TABLE call_sessions ADD COLUMN invite_friend_name TEXT`,
|
|
13
|
+
);
|
|
14
|
+
} catch {
|
|
15
|
+
/* already exists */
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
database.run(
|
|
19
|
+
/*sql*/ `ALTER TABLE call_sessions ADD COLUMN invite_guardian_name TEXT`,
|
|
20
|
+
);
|
|
21
|
+
} catch {
|
|
22
|
+
/* already exists */
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -91,6 +91,13 @@ export { migrateScheduleOneShotRouting } from "./146-schedule-oneshot-routing.js
|
|
|
91
91
|
export { migrateRemindersToSchedules } from "./147-migrate-reminders-to-schedules.js";
|
|
92
92
|
export { migrateDropRemindersTable } from "./148-drop-reminders-table.js";
|
|
93
93
|
export { createOAuthTables } from "./149-oauth-tables.js";
|
|
94
|
+
export { migrateOAuthAppsClientSecretPath } from "./150-oauth-apps-client-secret-path.js";
|
|
95
|
+
export { migrateOAuthProvidersPingUrl } from "./151-oauth-providers-ping-url.js";
|
|
96
|
+
export { migrateMemoryItemSupersession } from "./152-memory-item-supersession.js";
|
|
97
|
+
export { migrateDropEntityTables } from "./153-drop-entity-tables.js";
|
|
98
|
+
export { migrateDropMemorySegmentFts } from "./154-drop-fts.js";
|
|
99
|
+
export { migrateDropConflicts } from "./155-drop-conflicts.js";
|
|
100
|
+
export { migrateCallSessionInviteMetadata } from "./156-call-session-invite-metadata.js";
|
|
94
101
|
export {
|
|
95
102
|
MIGRATION_REGISTRY,
|
|
96
103
|
type MigrationRegistryEntry,
|