@gmickel/gno 1.46.0 → 2.1.0
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/README.md +17 -5
- package/THIRD_PARTY_NOTICES.md +46 -0
- package/assets/skill/SKILL.md +7 -6
- package/assets/spa-production.json.gz +0 -0
- package/browser-extension/artifacts/gno-browser-clipper-v2.1.0.zip +0 -0
- package/browser-extension/artifacts/gno-browser-clipper-v2.1.0.zip.sha256 +1 -0
- package/browser-extension/dist/chunk-4tc9v0ja.js +74 -0
- package/browser-extension/dist/manifest.json +1 -1
- package/browser-extension/dist/preview.html +1 -1
- package/browser-extension/dist/service-worker.js +32 -33
- package/bunfig.toml +2 -0
- package/package.json +40 -26
- package/spec/cli.md +29 -4
- package/spec/db/schema.sql +146 -1
- package/spec/mcp.md +26 -0
- package/src/app/context-runtime-types.ts +3 -0
- package/src/app/context-runtime.ts +2 -0
- package/src/cli/commands/ask.ts +6 -1
- package/src/cli/commands/daemon.ts +21 -8
- package/src/cli/commands/embed.ts +77 -41
- package/src/cli/detach.ts +3 -2
- package/src/config/types.ts +3 -3
- package/src/converters/adapters/markitdownTs/adapter.ts +1 -2
- package/src/converters/adapters/officeparser/adapter.ts +1 -2
- package/src/converters/versions.ts +6 -8
- package/src/core/context-evidence.ts +8 -4
- package/src/core/job-manager.ts +95 -13
- package/src/core/network-boundary-inventory.ts +10 -0
- package/src/core/shutdown-budget.ts +45 -0
- package/src/embed/backlog.ts +107 -4
- package/src/embed/batch.ts +42 -2
- package/src/embed/fingerprint.ts +16 -0
- package/src/embed/retry.ts +113 -5
- package/src/embed/variant-backlog.ts +105 -0
- package/src/embed/variant-plan.ts +62 -0
- package/src/embed/variant-retry.ts +113 -0
- package/src/ingestion/graph-reconciliation.ts +327 -0
- package/src/ingestion/sync.ts +9 -272
- package/src/llm/http-inference.ts +6 -0
- package/src/llm/httpEmbedding.ts +37 -6
- package/src/llm/httpGeneration.ts +18 -3
- package/src/llm/httpRerank.ts +23 -5
- package/src/llm/inference-cancellation.ts +168 -0
- package/src/llm/inference-scope.ts +202 -0
- package/src/llm/lazy-ports.ts +115 -0
- package/src/llm/native-worker/client.ts +541 -0
- package/src/llm/native-worker/dispatcher.ts +228 -0
- package/src/llm/native-worker/embedding-identity.ts +33 -0
- package/src/llm/native-worker/entry.ts +173 -0
- package/src/llm/native-worker/errors.ts +32 -0
- package/src/llm/native-worker/evaluation.ts +16 -0
- package/src/llm/native-worker/owned-exit.ts +108 -0
- package/src/llm/native-worker/owner.ts +141 -0
- package/src/llm/native-worker/ports.ts +317 -0
- package/src/llm/native-worker/protocol.ts +442 -0
- package/src/llm/native-worker/runtime-config.ts +92 -0
- package/src/llm/nodeLlamaCpp/adapter.ts +77 -20
- package/src/llm/nodeLlamaCpp/embedding.ts +130 -46
- package/src/llm/nodeLlamaCpp/generation.ts +34 -5
- package/src/llm/nodeLlamaCpp/lifecycle-options.ts +99 -0
- package/src/llm/nodeLlamaCpp/lifecycle.ts +209 -204
- package/src/llm/nodeLlamaCpp/rerank-capacity.ts +111 -0
- package/src/llm/nodeLlamaCpp/rerank.ts +118 -27
- package/src/llm/nodeLlamaCpp/simulator-handle.ts +73 -0
- package/src/llm/nodeLlamaCpp/simulator-install.ts +124 -0
- package/src/llm/nodeLlamaCpp/simulator-session.ts +240 -0
- package/src/llm/nodeLlamaCpp/simulator-types.ts +80 -0
- package/src/llm/types.ts +35 -5
- package/src/mcp/context.ts +27 -0
- package/src/mcp/http-transport.ts +12 -10
- package/src/mcp/server.ts +3 -0
- package/src/mcp/tool-profile.ts +30 -8
- package/src/mcp/tools/context.ts +8 -11
- package/src/mcp/tools/embed.ts +1 -1
- package/src/mcp/tools/index-cmd.ts +1 -1
- package/src/mcp/tools/index.ts +10 -8
- package/src/mcp/tools/query.ts +14 -30
- package/src/mcp/tools/vsearch.ts +1 -1
- package/src/pipeline/answer.ts +23 -3
- package/src/pipeline/claim-verifier.ts +6 -0
- package/src/pipeline/expansion.ts +43 -40
- package/src/pipeline/explain.ts +6 -2
- package/src/pipeline/filters.ts +63 -0
- package/src/pipeline/fusion.ts +29 -9
- package/src/pipeline/graph-retrieval.ts +29 -9
- package/src/pipeline/hybrid.ts +198 -55
- package/src/pipeline/hydration.ts +161 -0
- package/src/pipeline/owner-fusion.ts +87 -0
- package/src/pipeline/rerank.ts +35 -11
- package/src/pipeline/search.ts +13 -2
- package/src/pipeline/types.ts +5 -3
- package/src/pipeline/vsearch.ts +87 -7
- package/src/sdk/client.ts +47 -3
- package/src/sdk/embed.ts +63 -39
- package/src/serve/background-runtime.ts +1 -1
- package/src/serve/context.ts +41 -56
- package/src/serve/embed-scheduler.ts +58 -35
- package/src/serve/public/components/IndexingProgress.tsx +46 -60
- package/src/serve/public/components/PublishExportDialog.tsx +266 -0
- package/src/serve/public/globals.built.css +1 -1
- package/src/serve/public/globals.css +35 -0
- package/src/serve/public/lib/publish-export.ts +81 -1
- package/src/serve/public/lib/shiki-language-ids.ts +14 -0
- package/src/serve/public/pages/Collections.tsx +12 -46
- package/src/serve/public/pages/DocView.tsx +14 -52
- package/src/serve/resident-admission.ts +36 -36
- package/src/serve/resident-background-work.ts +20 -2
- package/src/serve/resident-request.ts +11 -5
- package/src/serve/resident-runtime.ts +97 -61
- package/src/serve/resident-shutdown.ts +153 -0
- package/src/serve/routes/api.ts +3 -1
- package/src/serve/server.ts +47 -26
- package/src/store/migrations/028-vector-variants.ts +54 -0
- package/src/store/migrations/029-graph-reference-state.ts +77 -0
- package/src/store/migrations/index.ts +4 -0
- package/src/store/sqlite/adapter.ts +251 -183
- package/src/store/sqlite/eligibility.ts +174 -0
- package/src/store/sqlite/graph-edge-application.ts +66 -0
- package/src/store/sqlite/graph-reference-state.ts +194 -0
- package/src/store/sqlite/legacy-vector-ownership.ts +79 -0
- package/src/store/types.ts +80 -12
- package/src/store/vector/eligibility.ts +36 -0
- package/src/store/vector/freshness.ts +33 -6
- package/src/store/vector/lazy.ts +81 -0
- package/src/store/vector/sqlite-vec.ts +106 -54
- package/src/store/vector/stats.ts +14 -3
- package/src/store/vector/types.ts +35 -2
- package/src/store/vector/variant-search.ts +192 -0
- package/src/store/vector/variants.ts +451 -0
- package/vendor/converters/markitdown-ts/LICENSE +21 -0
- package/vendor/converters/markitdown-ts/dist/index.cjs +1180 -0
- package/vendor/converters/markitdown-ts/dist/index.d.cts +46 -0
- package/vendor/converters/markitdown-ts/dist/index.d.mts +46 -0
- package/vendor/converters/markitdown-ts/dist/index.d.ts +46 -0
- package/vendor/converters/markitdown-ts/dist/index.mjs +1152 -0
- package/vendor/converters/markitdown-ts/package.json +77 -0
- package/vendor/converters/officeparser/LICENSE +21 -0
- package/vendor/converters/officeparser/dist/OfficeConverter.d.ts +47 -0
- package/vendor/converters/officeparser/dist/OfficeConverter.js +76 -0
- package/vendor/converters/officeparser/dist/OfficeGenerator.d.ts +23 -0
- package/vendor/converters/officeparser/dist/OfficeGenerator.js +73 -0
- package/vendor/converters/officeparser/dist/OfficeParser.d.ts +106 -0
- package/vendor/converters/officeparser/dist/OfficeParser.js +332 -0
- package/vendor/converters/officeparser/dist/cli.d.ts +28 -0
- package/vendor/converters/officeparser/dist/cli.js +381 -0
- package/vendor/converters/officeparser/dist/defaults.d.ts +41 -0
- package/vendor/converters/officeparser/dist/defaults.js +218 -0
- package/vendor/converters/officeparser/dist/generators/BaseGenerator.d.ts +107 -0
- package/vendor/converters/officeparser/dist/generators/BaseGenerator.js +248 -0
- package/vendor/converters/officeparser/dist/generators/ChunkingGenerator.d.ts +82 -0
- package/vendor/converters/officeparser/dist/generators/ChunkingGenerator.js +797 -0
- package/vendor/converters/officeparser/dist/generators/CsvGenerator.d.ts +38 -0
- package/vendor/converters/officeparser/dist/generators/CsvGenerator.js +245 -0
- package/vendor/converters/officeparser/dist/generators/EpubGenerator.d.ts +43 -0
- package/vendor/converters/officeparser/dist/generators/EpubGenerator.js +315 -0
- package/vendor/converters/officeparser/dist/generators/HtmlGenerator.d.ts +59 -0
- package/vendor/converters/officeparser/dist/generators/HtmlGenerator.js +1942 -0
- package/vendor/converters/officeparser/dist/generators/MarkdownGenerator.d.ts +96 -0
- package/vendor/converters/officeparser/dist/generators/MarkdownGenerator.js +1175 -0
- package/vendor/converters/officeparser/dist/generators/PdfGenerator.d.ts +22 -0
- package/vendor/converters/officeparser/dist/generators/PdfGenerator.js +194 -0
- package/vendor/converters/officeparser/dist/generators/RtfGenerator.d.ts +29 -0
- package/vendor/converters/officeparser/dist/generators/RtfGenerator.js +316 -0
- package/vendor/converters/officeparser/dist/generators/TextGenerator.d.ts +13 -0
- package/vendor/converters/officeparser/dist/generators/TextGenerator.js +201 -0
- package/vendor/converters/officeparser/dist/index.d.ts +60 -0
- package/vendor/converters/officeparser/dist/index.js +72 -0
- package/vendor/converters/officeparser/dist/index.mjs +18 -0
- package/vendor/converters/officeparser/dist/officeparser.browser.d.ts +2621 -0
- package/vendor/converters/officeparser/dist/officeparser.browser.iife.js +1336 -0
- package/vendor/converters/officeparser/dist/officeparser.browser.mjs +1335 -0
- package/vendor/converters/officeparser/dist/officeparser.browser.slim.d.ts +2621 -0
- package/vendor/converters/officeparser/dist/officeparser.browser.slim.iife.js +1336 -0
- package/vendor/converters/officeparser/dist/officeparser.browser.slim.mjs +1335 -0
- package/vendor/converters/officeparser/dist/parsers/CsvParser.d.ts +9 -0
- package/vendor/converters/officeparser/dist/parsers/CsvParser.js +115 -0
- package/vendor/converters/officeparser/dist/parsers/EpubParser.d.ts +8 -0
- package/vendor/converters/officeparser/dist/parsers/EpubParser.js +217 -0
- package/vendor/converters/officeparser/dist/parsers/ExcelParser.d.ts +32 -0
- package/vendor/converters/officeparser/dist/parsers/ExcelParser.js +736 -0
- package/vendor/converters/officeparser/dist/parsers/HtmlParser.d.ts +2 -0
- package/vendor/converters/officeparser/dist/parsers/HtmlParser.js +1287 -0
- package/vendor/converters/officeparser/dist/parsers/MarkdownParser.d.ts +2 -0
- package/vendor/converters/officeparser/dist/parsers/MarkdownParser.js +1272 -0
- package/vendor/converters/officeparser/dist/parsers/OpenOfficeParser.d.ts +31 -0
- package/vendor/converters/officeparser/dist/parsers/OpenOfficeParser.js +1819 -0
- package/vendor/converters/officeparser/dist/parsers/PdfParser.d.ts +67 -0
- package/vendor/converters/officeparser/dist/parsers/PdfParser.js +848 -0
- package/vendor/converters/officeparser/dist/parsers/PowerPointParser.d.ts +32 -0
- package/vendor/converters/officeparser/dist/parsers/PowerPointParser.js +950 -0
- package/vendor/converters/officeparser/dist/parsers/RtfParser.d.ts +187 -0
- package/vendor/converters/officeparser/dist/parsers/RtfParser.js +1801 -0
- package/vendor/converters/officeparser/dist/parsers/WordParser.d.ts +79 -0
- package/vendor/converters/officeparser/dist/parsers/WordParser.js +1177 -0
- package/vendor/converters/officeparser/dist/sbom.cdx.json +1763 -0
- package/vendor/converters/officeparser/dist/types.d.ts +2507 -0
- package/vendor/converters/officeparser/dist/types.js +107 -0
- package/vendor/converters/officeparser/dist/utils/astUtils.d.ts +16 -0
- package/vendor/converters/officeparser/dist/utils/astUtils.js +33 -0
- package/vendor/converters/officeparser/dist/utils/chartUtils.d.ts +6 -0
- package/vendor/converters/officeparser/dist/utils/chartUtils.js +257 -0
- package/vendor/converters/officeparser/dist/utils/configUtils.d.ts +44 -0
- package/vendor/converters/officeparser/dist/utils/configUtils.js +315 -0
- package/vendor/converters/officeparser/dist/utils/dateUtils.d.ts +17 -0
- package/vendor/converters/officeparser/dist/utils/dateUtils.js +69 -0
- package/vendor/converters/officeparser/dist/utils/envUtils.d.ts +29 -0
- package/vendor/converters/officeparser/dist/utils/envUtils.js +152 -0
- package/vendor/converters/officeparser/dist/utils/errorUtils.d.ts +72 -0
- package/vendor/converters/officeparser/dist/utils/errorUtils.js +245 -0
- package/vendor/converters/officeparser/dist/utils/imageUtils.d.ts +66 -0
- package/vendor/converters/officeparser/dist/utils/imageUtils.js +133 -0
- package/vendor/converters/officeparser/dist/utils/mathUtils.d.ts +42 -0
- package/vendor/converters/officeparser/dist/utils/mathUtils.js +385 -0
- package/vendor/converters/officeparser/dist/utils/moduleLoader.d.ts +18 -0
- package/vendor/converters/officeparser/dist/utils/moduleLoader.js +106 -0
- package/vendor/converters/officeparser/dist/utils/ocrUtils.d.ts +42 -0
- package/vendor/converters/officeparser/dist/utils/ocrUtils.js +428 -0
- package/vendor/converters/officeparser/dist/utils/sanitize.d.ts +148 -0
- package/vendor/converters/officeparser/dist/utils/sanitize.js +344 -0
- package/vendor/converters/officeparser/dist/utils/sheetUtils.d.ts +7 -0
- package/vendor/converters/officeparser/dist/utils/sheetUtils.js +35 -0
- package/vendor/converters/officeparser/dist/utils/styleMapper.d.ts +36 -0
- package/vendor/converters/officeparser/dist/utils/styleMapper.js +224 -0
- package/vendor/converters/officeparser/dist/utils/xmlUtils.d.ts +163 -0
- package/vendor/converters/officeparser/dist/utils/xmlUtils.js +461 -0
- package/vendor/converters/officeparser/dist/utils/zipUtils.d.ts +134 -0
- package/vendor/converters/officeparser/dist/utils/zipUtils.js +337 -0
- package/vendor/converters/officeparser/package.json +147 -0
- package/vendor/converters/upstream-manifest.json +124 -0
- package/vendor/dependency-fixes/README.md +77 -0
- package/vendor/dependency-fixes/vendor-converters.py +83 -0
- package/browser-extension/artifacts/gno-browser-clipper-v1.46.0.zip +0 -0
- package/browser-extension/artifacts/gno-browser-clipper-v1.46.0.zip.sha256 +0 -1
- package/browser-extension/dist/chunk-627emwpj.js +0 -75
- /package/browser-extension/dist/{chunk-ydfx5d7p.css → chunk-z74y8n8c.css} +0 -0
|
@@ -42,9 +42,13 @@ import {
|
|
|
42
42
|
} from "../core/findings-run-state";
|
|
43
43
|
import { JobManager } from "../core/job-manager";
|
|
44
44
|
import { recordContentMutation } from "../core/mutation-generations";
|
|
45
|
+
import {
|
|
46
|
+
shutdownDuration,
|
|
47
|
+
SHUTDOWN_DRAIN_MS,
|
|
48
|
+
SHUTDOWN_ABORT_MS,
|
|
49
|
+
} from "../core/shutdown-budget";
|
|
45
50
|
import { defaultSyncService, withContentTypeRules } from "../ingestion";
|
|
46
|
-
import {
|
|
47
|
-
import { getModelConfig } from "../llm/registry";
|
|
51
|
+
import { withOwnedInferenceScope } from "../llm/inference-scope";
|
|
48
52
|
import { getActivePreset } from "../llm/registry";
|
|
49
53
|
import { createToolContext, Mutex } from "../mcp/context";
|
|
50
54
|
import { SqliteAdapter } from "../store/sqlite/adapter";
|
|
@@ -58,10 +62,13 @@ import { createEmbedScheduler } from "./embed-scheduler";
|
|
|
58
62
|
import { FindingsScheduler, type FindingsPassResult } from "./findings-pass";
|
|
59
63
|
import { AdmissionController, ReaderGate } from "./resident-admission";
|
|
60
64
|
import { ResidentBackgroundWork } from "./resident-background-work";
|
|
61
|
-
import {
|
|
65
|
+
import { disposeResidentResources } from "./resident-shutdown";
|
|
66
|
+
import {
|
|
67
|
+
createStandaloneResidentStatus,
|
|
68
|
+
buildResidentStatusSnapshot,
|
|
69
|
+
} from "./resident-status";
|
|
62
70
|
import { CollectionWatchService as DefaultCollectionWatchService } from "./watch-service";
|
|
63
71
|
|
|
64
|
-
const DEFAULT_SHUTDOWN_DEADLINE_MS = 5_000;
|
|
65
72
|
const OWNER_LOCK_TIMEOUT_MS = 0;
|
|
66
73
|
|
|
67
74
|
export type ResidentMode = "serve" | "daemon";
|
|
@@ -110,7 +117,10 @@ export interface ResidentRuntime {
|
|
|
110
117
|
readonly capsuleReverificationScheduler: SavedCapsuleReverificationScheduler;
|
|
111
118
|
/** Present only when daemon mode runs with `findings.enabled`. */
|
|
112
119
|
readonly findingsScheduler: FindingsScheduler | null;
|
|
113
|
-
readonly modelManager:
|
|
120
|
+
readonly modelManager: Pick<
|
|
121
|
+
ModelManager,
|
|
122
|
+
"acquireLease" | "getLifecycleStats" | "disposeAll"
|
|
123
|
+
>;
|
|
114
124
|
readonly mcpContext: ToolContext;
|
|
115
125
|
readonly generations: ResidentGeneration;
|
|
116
126
|
readonly activeRequests: number;
|
|
@@ -136,7 +146,7 @@ export interface ResidentRuntime {
|
|
|
136
146
|
runUpdateCmd?: boolean;
|
|
137
147
|
triggerEmbed?: boolean;
|
|
138
148
|
}): Promise<{ syncResult: SyncResult; embedResult: EmbedResult | null }>;
|
|
139
|
-
dispose(): Promise<void>;
|
|
149
|
+
dispose(closeSurface?: () => Promise<unknown>): Promise<void>;
|
|
140
150
|
}
|
|
141
151
|
|
|
142
152
|
export type ResidentRuntimeResult =
|
|
@@ -176,6 +186,8 @@ export async function startResidentRuntime(
|
|
|
176
186
|
options: ResidentRuntimeOptions = {},
|
|
177
187
|
deps: ResidentRuntimeDeps = {}
|
|
178
188
|
): Promise<ResidentRuntimeResult> {
|
|
189
|
+
shutdownDuration(options.shutdownDeadlineMs, SHUTDOWN_DRAIN_MS);
|
|
190
|
+
shutdownDuration(options.shutdownAbortSettleMs, SHUTDOWN_ABORT_MS);
|
|
179
191
|
if (options.index !== undefined && !isValidIndexName(options.index)) {
|
|
180
192
|
return {
|
|
181
193
|
success: false,
|
|
@@ -274,9 +286,16 @@ export async function startResidentRuntime(
|
|
|
274
286
|
eventBus: options.eventBus ?? null,
|
|
275
287
|
watchService: null,
|
|
276
288
|
};
|
|
277
|
-
const modelManager =
|
|
278
|
-
|
|
279
|
-
|
|
289
|
+
const modelManager = deps.modelManagerFactory?.(initialConfig) ?? {
|
|
290
|
+
acquireLease: () =>
|
|
291
|
+
ctxHolder.current.llm?.acquireModelLease() ?? { release() {} },
|
|
292
|
+
getLifecycleStats: () =>
|
|
293
|
+
ctxHolder.current.llm?.getLifecycleStats() ??
|
|
294
|
+
createStandaloneResidentStatus("stdio").models,
|
|
295
|
+
disposeAll: async () => {
|
|
296
|
+
await ctxHolder.current.llm?.dispose();
|
|
297
|
+
},
|
|
298
|
+
};
|
|
280
299
|
const generations: ResidentGeneration = { content: 0, index: 0 };
|
|
281
300
|
ctxHolder.markContentMutation = () => {
|
|
282
301
|
generations.content += 1;
|
|
@@ -289,7 +308,6 @@ export async function startResidentRuntime(
|
|
|
289
308
|
getEmbedPort: () => ctxHolder.current.embedPort,
|
|
290
309
|
getVectorIndex: () => ctxHolder.current.vectorIndex,
|
|
291
310
|
getModelUri: () => getActivePreset(ctxHolder.config).embed,
|
|
292
|
-
acquireModelLease: () => modelManager.acquireLease(),
|
|
293
311
|
onEmbedded: () => {
|
|
294
312
|
generations.index += 1;
|
|
295
313
|
},
|
|
@@ -350,6 +368,7 @@ export async function startResidentRuntime(
|
|
|
350
368
|
let shutdownState: ResidentStatus["shutdown"]["state"] = "none";
|
|
351
369
|
let admissionState: ResidentStatus["admission"]["state"] = "accepting";
|
|
352
370
|
let disposed = false;
|
|
371
|
+
let disposal: Promise<void> | undefined;
|
|
353
372
|
const backgroundWork = new ResidentBackgroundWork(
|
|
354
373
|
() => !disposed && admission.accepting
|
|
355
374
|
);
|
|
@@ -405,7 +424,8 @@ export async function startResidentRuntime(
|
|
|
405
424
|
writeLockPath,
|
|
406
425
|
enableWrite: false,
|
|
407
426
|
isShuttingDown: () => disposed || !admission.accepting,
|
|
408
|
-
|
|
427
|
+
getModelAdapter: (config) =>
|
|
428
|
+
config === ctxHolder.current.config ? ctxHolder.current.llm : undefined,
|
|
409
429
|
markContentMutation: () => {
|
|
410
430
|
generations.content += 1;
|
|
411
431
|
},
|
|
@@ -545,60 +565,76 @@ export async function startResidentRuntime(
|
|
|
545
565
|
policySessionInvalidator = invalidator;
|
|
546
566
|
},
|
|
547
567
|
async syncAll(syncOptions = {}) {
|
|
548
|
-
const
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
568
|
+
const request = admission.admit();
|
|
569
|
+
if (!request) throw new Error("Resident runtime is shutting down");
|
|
570
|
+
try {
|
|
571
|
+
return await withOwnedInferenceScope(
|
|
572
|
+
{ signal: request.signal },
|
|
573
|
+
async () => {
|
|
574
|
+
const config = ctxHolder.config;
|
|
575
|
+
const syncAllService = deps.syncAllService
|
|
576
|
+
? (...args: Parameters<typeof defaultSyncService.syncAll>) =>
|
|
577
|
+
deps.syncAllService!(...args)
|
|
578
|
+
: defaultSyncService.syncAll.bind(defaultSyncService);
|
|
579
|
+
const syncResult = await syncAllService(
|
|
580
|
+
config.collections,
|
|
581
|
+
store,
|
|
582
|
+
withContentTypeRules(
|
|
583
|
+
{
|
|
584
|
+
gitPull: syncOptions.gitPull,
|
|
585
|
+
runUpdateCmd: syncOptions.runUpdateCmd,
|
|
586
|
+
},
|
|
587
|
+
config
|
|
588
|
+
)
|
|
589
|
+
);
|
|
590
|
+
recordContentMutation(syncResult, () => {
|
|
591
|
+
generations.content += 1;
|
|
592
|
+
});
|
|
593
|
+
const embedResult =
|
|
594
|
+
syncOptions.triggerEmbed === false
|
|
595
|
+
? null
|
|
596
|
+
: await scheduler.triggerNow();
|
|
597
|
+
capsuleReverificationScheduler.notifySyncSettled();
|
|
598
|
+
return { syncResult, embedResult };
|
|
599
|
+
}
|
|
600
|
+
);
|
|
601
|
+
} finally {
|
|
602
|
+
request.finish();
|
|
603
|
+
}
|
|
573
604
|
},
|
|
574
|
-
|
|
575
|
-
if (
|
|
605
|
+
dispose(closeSurface) {
|
|
606
|
+
if (disposal) return disposal;
|
|
576
607
|
disposed = true;
|
|
608
|
+
admission.stop();
|
|
609
|
+
jobManager.stop();
|
|
577
610
|
admissionState = "draining";
|
|
578
611
|
shutdownState = "graceful";
|
|
579
|
-
|
|
580
|
-
options
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
612
|
+
disposal = disposeResidentResources({
|
|
613
|
+
options,
|
|
614
|
+
admission,
|
|
615
|
+
backgroundWork,
|
|
616
|
+
jobManager,
|
|
617
|
+
scheduler,
|
|
618
|
+
store,
|
|
619
|
+
watchService,
|
|
620
|
+
context: ctxHolder.current,
|
|
621
|
+
mcpContext,
|
|
622
|
+
modelManager,
|
|
623
|
+
ownerLock,
|
|
624
|
+
stopFindings: () => findingsScheduler?.dispose(),
|
|
625
|
+
stopCapsules: () => capsuleReverificationScheduler.dispose(),
|
|
626
|
+
closeEvents: () => options.eventBus?.close(),
|
|
627
|
+
disposeContext: deps.disposeServerContext ?? disposeServerContext,
|
|
628
|
+
closeSurface,
|
|
629
|
+
onDeadline: () => {
|
|
630
|
+
shutdownState = "deadline";
|
|
631
|
+
},
|
|
632
|
+
}).then(() => {
|
|
633
|
+
admissionState = "closed";
|
|
634
|
+
transportStatusProvider = null;
|
|
635
|
+
listenerPort = null;
|
|
636
|
+
});
|
|
637
|
+
return disposal;
|
|
602
638
|
},
|
|
603
639
|
};
|
|
604
640
|
ctxHolder.startBackgroundWork = (operation) =>
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import type { WriteLockHandle } from "../core/file-lock";
|
|
2
|
+
/** One finite shutdown clock for the resources owned by a resident runtime. */
|
|
3
|
+
import type { JobManager } from "../core/job-manager";
|
|
4
|
+
import type { ToolContext } from "../mcp/context";
|
|
5
|
+
import type { SqliteAdapter } from "../store/sqlite/adapter";
|
|
6
|
+
import type { ServerContext } from "./context";
|
|
7
|
+
import type { EmbedScheduler } from "./embed-scheduler";
|
|
8
|
+
import type { AdmissionController } from "./resident-admission";
|
|
9
|
+
import type { ResidentBackgroundWork } from "./resident-background-work";
|
|
10
|
+
import type { ResidentRuntimeOptions } from "./resident-runtime";
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
settlesBy,
|
|
14
|
+
shutdownDuration,
|
|
15
|
+
SHUTDOWN_DRAIN_MS,
|
|
16
|
+
SHUTDOWN_ABORT_MS,
|
|
17
|
+
SHUTDOWN_EXIT_MS,
|
|
18
|
+
} from "../core/shutdown-budget";
|
|
19
|
+
|
|
20
|
+
interface ResidentShutdownResources {
|
|
21
|
+
options: ResidentRuntimeOptions;
|
|
22
|
+
admission: AdmissionController;
|
|
23
|
+
backgroundWork: ResidentBackgroundWork;
|
|
24
|
+
jobManager: JobManager;
|
|
25
|
+
scheduler: EmbedScheduler;
|
|
26
|
+
store: SqliteAdapter;
|
|
27
|
+
watchService: { dispose(): void | Promise<void> };
|
|
28
|
+
context: ServerContext;
|
|
29
|
+
mcpContext: ToolContext;
|
|
30
|
+
modelManager: { disposeAll(): Promise<void> };
|
|
31
|
+
ownerLock: WriteLockHandle;
|
|
32
|
+
stopFindings: () => void;
|
|
33
|
+
stopCapsules: () => Promise<void>;
|
|
34
|
+
closeEvents: () => void | Promise<void>;
|
|
35
|
+
disposeContext: (context: ServerContext) => Promise<void>;
|
|
36
|
+
closeSurface?: () => Promise<unknown>;
|
|
37
|
+
onDeadline: () => void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export async function disposeResidentResources(
|
|
41
|
+
resources: ResidentShutdownResources
|
|
42
|
+
): Promise<void> {
|
|
43
|
+
const {
|
|
44
|
+
options,
|
|
45
|
+
admission,
|
|
46
|
+
backgroundWork,
|
|
47
|
+
jobManager,
|
|
48
|
+
scheduler,
|
|
49
|
+
store,
|
|
50
|
+
watchService,
|
|
51
|
+
context,
|
|
52
|
+
mcpContext,
|
|
53
|
+
modelManager,
|
|
54
|
+
ownerLock,
|
|
55
|
+
stopFindings,
|
|
56
|
+
stopCapsules,
|
|
57
|
+
closeEvents,
|
|
58
|
+
disposeContext,
|
|
59
|
+
closeSurface,
|
|
60
|
+
onDeadline,
|
|
61
|
+
} = resources;
|
|
62
|
+
let deadlineReached = false;
|
|
63
|
+
const drainDeadline =
|
|
64
|
+
performance.now() +
|
|
65
|
+
shutdownDuration(options.shutdownDeadlineMs, SHUTDOWN_DRAIN_MS);
|
|
66
|
+
const abortDeadline =
|
|
67
|
+
drainDeadline +
|
|
68
|
+
shutdownDuration(options.shutdownAbortSettleMs, SHUTDOWN_ABORT_MS);
|
|
69
|
+
const exitDeadline = abortDeadline + SHUTDOWN_EXIT_MS;
|
|
70
|
+
let unfinishedJobs: Promise<void> = Promise.resolve();
|
|
71
|
+
let writeFailure: unknown;
|
|
72
|
+
store.beginShutdown?.(abortDeadline);
|
|
73
|
+
const observe = (operation: () => unknown): Promise<void> =>
|
|
74
|
+
Promise.resolve()
|
|
75
|
+
.then(operation)
|
|
76
|
+
.then(
|
|
77
|
+
() => {},
|
|
78
|
+
(error: unknown) => console.error("Resident cleanup failed:", error)
|
|
79
|
+
);
|
|
80
|
+
stopFindings();
|
|
81
|
+
const schedulerDrain = observe(() =>
|
|
82
|
+
scheduler.stop ? scheduler.stop() : scheduler.dispose()
|
|
83
|
+
);
|
|
84
|
+
const work = Promise.all([
|
|
85
|
+
observe(() => closeSurface?.()),
|
|
86
|
+
admission.drain(),
|
|
87
|
+
backgroundWork.drain(),
|
|
88
|
+
jobManager.shutdown(),
|
|
89
|
+
schedulerDrain,
|
|
90
|
+
observe(() => stopCapsules()),
|
|
91
|
+
observe(() => watchService.dispose()),
|
|
92
|
+
observe(() => closeEvents()),
|
|
93
|
+
]);
|
|
94
|
+
if (!(await settlesBy(work, drainDeadline))) {
|
|
95
|
+
deadlineReached = true;
|
|
96
|
+
onDeadline();
|
|
97
|
+
admission.cancel();
|
|
98
|
+
backgroundWork.cancel();
|
|
99
|
+
jobManager.cancel();
|
|
100
|
+
const canceledScheduler = observe(() => scheduler.dispose());
|
|
101
|
+
if (
|
|
102
|
+
!(await settlesBy(Promise.all([work, canceledScheduler]), abortDeadline))
|
|
103
|
+
) {
|
|
104
|
+
// Revoke/rollback suspended parent writers before closing their DB.
|
|
105
|
+
// The ordinary store API also fences any late noncooperative callback.
|
|
106
|
+
try {
|
|
107
|
+
store.fenceForShutdown?.();
|
|
108
|
+
// Calling close synchronously closes cached raw handles before
|
|
109
|
+
// any late callback can resume in the native-exit wait.
|
|
110
|
+
const closing = store.close();
|
|
111
|
+
unfinishedJobs = jobManager.failUnfinished();
|
|
112
|
+
if (!(await settlesBy(closing, exitDeadline)))
|
|
113
|
+
throw new Error("Store close exceeded shutdown deadline");
|
|
114
|
+
} catch (error) {
|
|
115
|
+
writeFailure = error;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Reach the single native owner directly; port disposal may itself wait
|
|
120
|
+
// for that owner. Never let such a wait hide the forced-exit deadline.
|
|
121
|
+
const nativeOptions = {
|
|
122
|
+
deadline: exitDeadline,
|
|
123
|
+
force: deadlineReached,
|
|
124
|
+
};
|
|
125
|
+
const native = Promise.all([
|
|
126
|
+
context.llm?.dispose(nativeOptions),
|
|
127
|
+
mcpContext.disposeModels?.(nativeOptions),
|
|
128
|
+
]);
|
|
129
|
+
let nativeFailure: unknown;
|
|
130
|
+
try {
|
|
131
|
+
if (!(await settlesBy(native, exitDeadline)))
|
|
132
|
+
throw new Error(
|
|
133
|
+
"Native shutdown did not settle before owned-child exit deadline"
|
|
134
|
+
);
|
|
135
|
+
} catch (error) {
|
|
136
|
+
nativeFailure = error;
|
|
137
|
+
console.error("Resident native shutdown failed:", error);
|
|
138
|
+
}
|
|
139
|
+
const cleanup = Promise.all([
|
|
140
|
+
unfinishedJobs,
|
|
141
|
+
observe(() => disposeContext(context)),
|
|
142
|
+
observe(() => modelManager.disposeAll()),
|
|
143
|
+
]);
|
|
144
|
+
if (!(await settlesBy(cleanup, exitDeadline)))
|
|
145
|
+
console.error("Resident resource cleanup exceeded shutdown deadline");
|
|
146
|
+
// close performs synchronous rollback/revocation before disconnecting.
|
|
147
|
+
if (writeFailure) throw writeFailure;
|
|
148
|
+
if (!(await settlesBy(store.close(), exitDeadline)))
|
|
149
|
+
throw new Error("Store close exceeded shutdown deadline");
|
|
150
|
+
if (!(await settlesBy(ownerLock.release(), exitDeadline)))
|
|
151
|
+
throw new Error("Resident owner lock release exceeded shutdown deadline");
|
|
152
|
+
if (nativeFailure) throw nativeFailure;
|
|
153
|
+
}
|
package/src/serve/routes/api.ts
CHANGED
|
@@ -4244,7 +4244,9 @@ export async function handleSearch(
|
|
|
4244
4244
|
req,
|
|
4245
4245
|
trace.session,
|
|
4246
4246
|
"failed",
|
|
4247
|
-
|
|
4247
|
+
result.error.code === "INVALID_INPUT"
|
|
4248
|
+
? errorResponse("VALIDATION", result.error.message, 400)
|
|
4249
|
+
: errorResponse("RUNTIME", result.error.message, 500)
|
|
4248
4250
|
);
|
|
4249
4251
|
}
|
|
4250
4252
|
|
package/src/serve/server.ts
CHANGED
|
@@ -472,8 +472,8 @@ export async function startServer(
|
|
|
472
472
|
}
|
|
473
473
|
} catch (error) {
|
|
474
474
|
removeShutdownHandlers();
|
|
475
|
-
|
|
476
|
-
await
|
|
475
|
+
const surfaceClose = Promise.resolve().then(() => gateway.close());
|
|
476
|
+
await runtime.dispose(() => surfaceClose);
|
|
477
477
|
return {
|
|
478
478
|
success: false,
|
|
479
479
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -1134,8 +1134,11 @@ export async function startServer(
|
|
|
1134
1134
|
return withSecurityHeaders(forbiddenResponse(), isDev);
|
|
1135
1135
|
}
|
|
1136
1136
|
return withSecurityHeaders(
|
|
1137
|
-
await handleResidentRead(
|
|
1138
|
-
|
|
1137
|
+
await handleResidentRead(
|
|
1138
|
+
runtime as ResidentRuntime,
|
|
1139
|
+
req,
|
|
1140
|
+
(signal) =>
|
|
1141
|
+
handleQuery(ctxHolder.current, new Request(req, { signal }))
|
|
1139
1142
|
),
|
|
1140
1143
|
isDev
|
|
1141
1144
|
);
|
|
@@ -1147,8 +1150,14 @@ export async function startServer(
|
|
|
1147
1150
|
return withSecurityHeaders(forbiddenResponse(), isDev);
|
|
1148
1151
|
}
|
|
1149
1152
|
return withSecurityHeaders(
|
|
1150
|
-
await handleResidentRead(
|
|
1151
|
-
|
|
1153
|
+
await handleResidentRead(
|
|
1154
|
+
runtime as ResidentRuntime,
|
|
1155
|
+
req,
|
|
1156
|
+
(signal) =>
|
|
1157
|
+
handleContextBuild(
|
|
1158
|
+
ctxHolder.current,
|
|
1159
|
+
new Request(req, { signal })
|
|
1160
|
+
)
|
|
1152
1161
|
),
|
|
1153
1162
|
isDev
|
|
1154
1163
|
);
|
|
@@ -1160,8 +1169,14 @@ export async function startServer(
|
|
|
1160
1169
|
return withSecurityHeaders(forbiddenResponse(), isDev);
|
|
1161
1170
|
}
|
|
1162
1171
|
return withSecurityHeaders(
|
|
1163
|
-
await handleResidentRead(
|
|
1164
|
-
|
|
1172
|
+
await handleResidentRead(
|
|
1173
|
+
runtime as ResidentRuntime,
|
|
1174
|
+
req,
|
|
1175
|
+
(signal) =>
|
|
1176
|
+
handleContextVerify(
|
|
1177
|
+
ctxHolder.current,
|
|
1178
|
+
new Request(req, { signal })
|
|
1179
|
+
)
|
|
1165
1180
|
),
|
|
1166
1181
|
isDev
|
|
1167
1182
|
);
|
|
@@ -1173,8 +1188,14 @@ export async function startServer(
|
|
|
1173
1188
|
return withSecurityHeaders(forbiddenResponse(), isDev);
|
|
1174
1189
|
}
|
|
1175
1190
|
return withSecurityHeaders(
|
|
1176
|
-
await handleResidentRead(
|
|
1177
|
-
|
|
1191
|
+
await handleResidentRead(
|
|
1192
|
+
runtime as ResidentRuntime,
|
|
1193
|
+
req,
|
|
1194
|
+
(signal) =>
|
|
1195
|
+
handleQueryDiagnose(
|
|
1196
|
+
ctxHolder.current,
|
|
1197
|
+
new Request(req, { signal })
|
|
1198
|
+
)
|
|
1178
1199
|
),
|
|
1179
1200
|
isDev
|
|
1180
1201
|
);
|
|
@@ -1186,8 +1207,11 @@ export async function startServer(
|
|
|
1186
1207
|
return withSecurityHeaders(forbiddenResponse(), isDev);
|
|
1187
1208
|
}
|
|
1188
1209
|
return withSecurityHeaders(
|
|
1189
|
-
await handleResidentRead(
|
|
1190
|
-
|
|
1210
|
+
await handleResidentRead(
|
|
1211
|
+
runtime as ResidentRuntime,
|
|
1212
|
+
req,
|
|
1213
|
+
(signal) =>
|
|
1214
|
+
handleAsk(ctxHolder.current, new Request(req, { signal }))
|
|
1191
1215
|
),
|
|
1192
1216
|
isDev
|
|
1193
1217
|
);
|
|
@@ -1481,11 +1505,11 @@ export async function startServer(
|
|
|
1481
1505
|
});
|
|
1482
1506
|
} catch (e) {
|
|
1483
1507
|
removeShutdownHandlers();
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
await
|
|
1508
|
+
const surfaceClose = Promise.all([
|
|
1509
|
+
Promise.resolve().then(() => spaBundleSource?.close()),
|
|
1510
|
+
Promise.resolve().then(() => gateway.close()),
|
|
1511
|
+
]);
|
|
1512
|
+
await runtime.dispose(() => surfaceClose);
|
|
1489
1513
|
return {
|
|
1490
1514
|
success: false,
|
|
1491
1515
|
error: e instanceof Error ? e.message : String(e),
|
|
@@ -1510,14 +1534,11 @@ export async function startServer(
|
|
|
1510
1534
|
}
|
|
1511
1535
|
|
|
1512
1536
|
removeShutdownHandlers();
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
await Promise.allSettled([gateway.close()]);
|
|
1520
|
-
await Promise.allSettled([runtime.dispose()]);
|
|
1521
|
-
}
|
|
1537
|
+
const surfaceClose = Promise.all([
|
|
1538
|
+
Promise.resolve().then(() => server.stop(true)),
|
|
1539
|
+
Promise.resolve().then(() => spaBundleSource?.close()),
|
|
1540
|
+
Promise.resolve().then(() => gateway.close()),
|
|
1541
|
+
]);
|
|
1542
|
+
await runtime.dispose(() => surfaceClose);
|
|
1522
1543
|
return { success: true };
|
|
1523
1544
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** Additive exact-input variants; existing vectors have no historical proof. */
|
|
2
|
+
import type { Migration } from "./runner";
|
|
3
|
+
|
|
4
|
+
export const migration: Migration = {
|
|
5
|
+
version: 28,
|
|
6
|
+
name: "vector_variants",
|
|
7
|
+
up(db): void {
|
|
8
|
+
db.exec(`
|
|
9
|
+
CREATE TABLE vector_variant_epoch (
|
|
10
|
+
id INTEGER PRIMARY KEY CHECK (id = 1), epoch INTEGER NOT NULL DEFAULT 0
|
|
11
|
+
);
|
|
12
|
+
INSERT INTO vector_variant_epoch(id) VALUES (1);
|
|
13
|
+
CREATE TABLE vector_partitions (
|
|
14
|
+
partition_id TEXT PRIMARY KEY,
|
|
15
|
+
version INTEGER NOT NULL CHECK (version = 1),
|
|
16
|
+
model TEXT NOT NULL, fingerprint TEXT NOT NULL,
|
|
17
|
+
dimensions INTEGER NOT NULL CHECK (dimensions > 0),
|
|
18
|
+
state TEXT NOT NULL DEFAULT 'shadow' CHECK (state IN ('shadow', 'active')),
|
|
19
|
+
activated_epoch INTEGER,
|
|
20
|
+
UNIQUE(model, fingerprint, dimensions)
|
|
21
|
+
);
|
|
22
|
+
CREATE TABLE vector_variants (
|
|
23
|
+
variant_id INTEGER PRIMARY KEY,
|
|
24
|
+
partition_id TEXT NOT NULL REFERENCES vector_partitions(partition_id),
|
|
25
|
+
input_hash TEXT NOT NULL CHECK (length(input_hash) = 64),
|
|
26
|
+
embedding BLOB NOT NULL,
|
|
27
|
+
UNIQUE(partition_id, input_hash), UNIQUE(partition_id, variant_id)
|
|
28
|
+
);
|
|
29
|
+
CREATE TABLE vector_owners (
|
|
30
|
+
document_id INTEGER NOT NULL REFERENCES documents(id) ON DELETE CASCADE,
|
|
31
|
+
mirror_hash TEXT NOT NULL, seq INTEGER NOT NULL,
|
|
32
|
+
partition_id TEXT NOT NULL, variant_id INTEGER NOT NULL,
|
|
33
|
+
PRIMARY KEY(document_id, seq, partition_id),
|
|
34
|
+
FOREIGN KEY(partition_id, variant_id)
|
|
35
|
+
REFERENCES vector_variants(partition_id, variant_id)
|
|
36
|
+
);
|
|
37
|
+
CREATE INDEX idx_vector_owners_variant ON vector_owners(variant_id);
|
|
38
|
+
`);
|
|
39
|
+
// All writers, including old consumers and raw SQL, participate in the fence.
|
|
40
|
+
for (const table of [
|
|
41
|
+
"documents",
|
|
42
|
+
"content_chunks",
|
|
43
|
+
"vector_owners",
|
|
44
|
+
"vector_variants",
|
|
45
|
+
]) {
|
|
46
|
+
for (const event of ["INSERT", "UPDATE", "DELETE"]) {
|
|
47
|
+
db.exec(`CREATE TRIGGER variant_epoch_${table}_${event}
|
|
48
|
+
AFTER ${event} ON ${table} BEGIN
|
|
49
|
+
UPDATE vector_variant_epoch SET epoch = epoch + 1 WHERE id = 1;
|
|
50
|
+
END`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/** Durable unresolved references and conservative projection recovery. */
|
|
2
|
+
import type { Migration } from "./runner";
|
|
3
|
+
|
|
4
|
+
export const migration: Migration = {
|
|
5
|
+
version: 29,
|
|
6
|
+
name: "graph_reference_state",
|
|
7
|
+
up(db): void {
|
|
8
|
+
db.exec(`
|
|
9
|
+
-- Graph reference inventory (migration 029). Parsed links remain in doc_links.
|
|
10
|
+
-- Snapshots deliberately survive document deletion: closure needs old identities.
|
|
11
|
+
-- Missing inventory, changed version/config, or dirty state requires full recovery.
|
|
12
|
+
-- Begin persists dirty before projection. Complete only after successful edge writes,
|
|
13
|
+
-- unchanged input epoch, and coverage of every active source; compose in a transaction.
|
|
14
|
+
CREATE TABLE graph_projection_state (
|
|
15
|
+
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
16
|
+
epoch INTEGER NOT NULL DEFAULT 0,
|
|
17
|
+
version INTEGER,
|
|
18
|
+
config_fingerprint TEXT,
|
|
19
|
+
in_progress INTEGER NOT NULL DEFAULT 0 CHECK (in_progress IN (0, 1)),
|
|
20
|
+
dirty INTEGER NOT NULL DEFAULT 1 CHECK (dirty IN (0, 1))
|
|
21
|
+
);
|
|
22
|
+
INSERT INTO graph_projection_state(id) VALUES (1);
|
|
23
|
+
CREATE TABLE graph_reference_documents (
|
|
24
|
+
document_id INTEGER PRIMARY KEY,
|
|
25
|
+
collection TEXT NOT NULL, rel_path TEXT NOT NULL, docid TEXT NOT NULL,
|
|
26
|
+
uri TEXT NOT NULL, title TEXT, mirror_hash TEXT, source_hash TEXT NOT NULL,
|
|
27
|
+
content_type TEXT
|
|
28
|
+
);
|
|
29
|
+
CREATE INDEX idx_graph_reference_uri ON graph_reference_documents(uri);
|
|
30
|
+
CREATE INDEX idx_graph_reference_path ON graph_reference_documents(collection, rel_path);
|
|
31
|
+
CREATE INDEX idx_graph_reference_title ON graph_reference_documents(title);
|
|
32
|
+
CREATE TABLE graph_frontmatter_references (
|
|
33
|
+
source_doc_id INTEGER NOT NULL REFERENCES graph_reference_documents(document_id) ON DELETE CASCADE,
|
|
34
|
+
ordinal INTEGER NOT NULL,
|
|
35
|
+
edge_type TEXT NOT NULL,
|
|
36
|
+
target TEXT NOT NULL,
|
|
37
|
+
PRIMARY KEY(source_doc_id, ordinal)
|
|
38
|
+
);
|
|
39
|
+
CREATE INDEX idx_graph_reference_target ON graph_frontmatter_references(target);
|
|
40
|
+
`);
|
|
41
|
+
for (const table of ["documents", "doc_links"]) {
|
|
42
|
+
for (const operation of ["INSERT", "UPDATE", "DELETE"]) {
|
|
43
|
+
const changed =
|
|
44
|
+
table === "documents" && operation === "UPDATE"
|
|
45
|
+
? " WHEN " +
|
|
46
|
+
[
|
|
47
|
+
"collection",
|
|
48
|
+
"rel_path",
|
|
49
|
+
"docid",
|
|
50
|
+
"uri",
|
|
51
|
+
"title",
|
|
52
|
+
"mirror_hash",
|
|
53
|
+
"source_hash",
|
|
54
|
+
"content_type",
|
|
55
|
+
"active",
|
|
56
|
+
]
|
|
57
|
+
.map((column) => `OLD.${column} IS NOT NEW.${column}`)
|
|
58
|
+
.join(" OR ")
|
|
59
|
+
: "";
|
|
60
|
+
db.exec(`CREATE TRIGGER graph_input_${table}_${operation.toLowerCase()}
|
|
61
|
+
AFTER ${operation} ON ${table}${changed} BEGIN
|
|
62
|
+
UPDATE graph_projection_state SET epoch = epoch + 1, dirty = 1 WHERE id = 1;
|
|
63
|
+
END`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
for (const table of [
|
|
67
|
+
"graph_reference_documents",
|
|
68
|
+
"graph_frontmatter_references",
|
|
69
|
+
]) {
|
|
70
|
+
for (const operation of ["INSERT", "UPDATE", "DELETE"]) {
|
|
71
|
+
db.exec(`CREATE TRIGGER graph_inventory_${table}_${operation.toLowerCase()}
|
|
72
|
+
AFTER ${operation} ON ${table} BEGIN
|
|
73
|
+
UPDATE graph_projection_state SET dirty = 1, in_progress = 1 WHERE id = 1; END`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
};
|
|
@@ -41,6 +41,8 @@ import { migration as m024 } from "./024-egress-derived-lineage";
|
|
|
41
41
|
import { migration as m025 } from "./025-collection-egress-policy-revision";
|
|
42
42
|
import { migration as m026 } from "./026-file-refactor-recovery-journal";
|
|
43
43
|
import { migration as m027 } from "./027-memory-scopes";
|
|
44
|
+
import { migration as m028 } from "./028-vector-variants";
|
|
45
|
+
import { migration as m029 } from "./029-graph-reference-state";
|
|
44
46
|
|
|
45
47
|
/** All migrations in order */
|
|
46
48
|
export const migrations = [
|
|
@@ -71,4 +73,6 @@ export const migrations = [
|
|
|
71
73
|
m025,
|
|
72
74
|
m026,
|
|
73
75
|
m027,
|
|
76
|
+
m028,
|
|
77
|
+
m029,
|
|
74
78
|
];
|