@hraness/oh 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/LICENSE +3 -0
  2. package/README.md +4 -1
  3. package/dist/cli.d.ts +1 -1
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/cli.js +15590 -1705
  6. package/dist/index.js +15209 -261
  7. package/dist/libsql-model.d.ts +75 -0
  8. package/dist/libsql-model.d.ts.map +1 -0
  9. package/dist/libsql-platform.d.ts +24 -0
  10. package/dist/libsql-platform.d.ts.map +1 -0
  11. package/dist/libsql-program.d.ts +64 -0
  12. package/dist/libsql-program.d.ts.map +1 -0
  13. package/dist/libsql-runtime.d.ts +13 -0
  14. package/dist/libsql-runtime.d.ts.map +1 -0
  15. package/dist/libsql.d.ts +4 -36
  16. package/dist/libsql.d.ts.map +1 -1
  17. package/dist/libsql.js +16583 -1426
  18. package/dist/memory-authority-platform.d.ts +210 -0
  19. package/dist/memory-authority-platform.d.ts.map +1 -0
  20. package/dist/memory-authority-program.d.ts +15 -0
  21. package/dist/memory-authority-program.d.ts.map +1 -0
  22. package/dist/memory-authority-runtime.d.ts +4 -0
  23. package/dist/memory-authority-runtime.d.ts.map +1 -0
  24. package/dist/memory-core.d.ts +522 -0
  25. package/dist/memory-core.d.ts.map +1 -0
  26. package/dist/memory.d.ts +5 -445
  27. package/dist/memory.d.ts.map +1 -1
  28. package/dist/memory.js +18232 -4143
  29. package/dist/sdk.js +15266 -318
  30. package/dist/semantic-cloud.js +1 -260
  31. package/dist/semantic-model.d.ts +75 -0
  32. package/dist/semantic-model.d.ts.map +1 -0
  33. package/dist/semantic-platform.d.ts +32 -0
  34. package/dist/semantic-platform.d.ts.map +1 -0
  35. package/dist/semantic-program.d.ts +18 -0
  36. package/dist/semantic-program.d.ts.map +1 -0
  37. package/dist/semantic-runtime.d.ts +6 -0
  38. package/dist/semantic-runtime.d.ts.map +1 -0
  39. package/dist/semantic.d.ts +6 -57
  40. package/dist/semantic.d.ts.map +1 -1
  41. package/dist/semantic.js +15541 -514
  42. package/dist/sqlite/index.js +1148 -1378
  43. package/dist/sqlite/port.d.ts +1 -1
  44. package/dist/sqlite/port.d.ts.map +1 -1
  45. package/dist/sync-libsql-program.d.ts +5 -0
  46. package/dist/sync-libsql-program.d.ts.map +1 -0
  47. package/dist/sync-model.d.ts +60 -0
  48. package/dist/sync-model.d.ts.map +1 -0
  49. package/dist/sync-platform.d.ts +41 -0
  50. package/dist/sync-platform.d.ts.map +1 -0
  51. package/dist/sync-program.d.ts +11 -0
  52. package/dist/sync-program.d.ts.map +1 -0
  53. package/dist/sync-runtime.d.ts +6 -0
  54. package/dist/sync-runtime.d.ts.map +1 -0
  55. package/dist/sync.d.ts +5 -55
  56. package/dist/sync.d.ts.map +1 -1
  57. package/dist/sync.js +15174 -226
  58. package/package.json +7 -5
  59. package/skills/oh/SKILL.md +2 -1
  60. package/spec/v1/store.md +14 -0
  61. package/src/cli.test.ts +35 -0
  62. package/src/cli.ts +4 -3
  63. package/src/cloudflare-embedding.ts +1 -1
  64. package/src/libsql-lifecycle.test.ts +76 -0
  65. package/src/libsql-model.ts +350 -0
  66. package/src/libsql-platform.ts +51 -0
  67. package/src/libsql-program.ts +1583 -0
  68. package/src/libsql-runtime.ts +89 -0
  69. package/src/libsql-semantic-v2.ts +1 -1
  70. package/src/libsql-semantic.ts +1 -1
  71. package/src/libsql.test.ts +245 -0
  72. package/src/libsql.ts +26 -1698
  73. package/src/memory-authority-platform.ts +133 -0
  74. package/src/memory-authority-program.ts +309 -0
  75. package/src/memory-authority-runtime.ts +40 -0
  76. package/src/memory-core.ts +2401 -0
  77. package/src/memory.test.ts +55 -0
  78. package/src/memory.ts +68 -2759
  79. package/src/semantic-model.ts +142 -0
  80. package/src/semantic-platform.ts +130 -0
  81. package/src/semantic-program.ts +113 -0
  82. package/src/semantic-runtime.ts +53 -0
  83. package/src/semantic.test.ts +115 -1
  84. package/src/semantic.ts +14 -324
  85. package/src/sqlite/port.ts +1 -1
  86. package/src/sync-libsql-program.ts +170 -0
  87. package/src/sync-lifecycle.test.ts +110 -0
  88. package/src/sync-model.ts +530 -0
  89. package/src/sync-platform.ts +87 -0
  90. package/src/sync-program.ts +117 -0
  91. package/src/sync-runtime.ts +33 -0
  92. package/src/sync.ts +10 -765
@@ -182,10 +182,6 @@ function sortUnique(values, key) {
182
182
  return sorted;
183
183
  }
184
184
 
185
- // src/semantic.ts
186
- import { mkdir, readFile, readdir, rename, unlink, writeFile } from "node:fs/promises";
187
- import { join, resolve } from "node:path";
188
-
189
185
  // src/graph.ts
190
186
  var OH_GRAPH_FORMAT_VERSION_V1 = 1;
191
187
  var OH_GRAPH_LIMITS_V1 = Object.freeze({
@@ -352,7 +348,7 @@ function graphRevisionSha256V1(input) {
352
348
  return canonicalSha256({ changes, operationId, parentGraphRevisionSha256, recordsSha256, revision, v: 1 });
353
349
  }
354
350
 
355
- // src/semantic.ts
351
+ // src/semantic-model.ts
356
352
  var OH_EMBEDDING_PROFILE_V1 = Object.freeze({
357
353
  dimensions: 768,
358
354
  distance: "cosine",
@@ -384,261 +380,6 @@ function normalizeOhEmbeddingV1(vector) {
384
380
  }
385
381
  return normalized;
386
382
  }
387
- var qmdModuleSpecifier = "@tobilu/qmd";
388
- async function defaultQmdStoreFactory(options) {
389
- let module;
390
- try {
391
- module = await import(qmdModuleSpecifier);
392
- } catch {
393
- throw new Error("Semantic search needs the optional @tobilu/qmd@2.5.3 package.");
394
- }
395
- const createStore = module.createStore;
396
- if (typeof createStore !== "function")
397
- throw new Error("The installed QMD package has no compatible createStore export.");
398
- return await createStore(options);
399
- }
400
- function recordDocument(record) {
401
- return `# ${record.key}
402
-
403
- kind: ${record.kind}
404
-
405
- ${canonicalJson(record.value)}
406
- `;
407
- }
408
- var QMD_VECTOR_RESULT_KEYS = [
409
- "body",
410
- "bodyLength",
411
- "chunkPos",
412
- "collectionName",
413
- "context",
414
- "displayPath",
415
- "docid",
416
- "filepath",
417
- "hash",
418
- "modifiedAt",
419
- "score",
420
- "source",
421
- "title"
422
- ];
423
- function semanticManifest(entries) {
424
- const immutableEntries = {};
425
- for (const [filename, entry] of Object.entries(entries)) {
426
- immutableEntries[filename] = Object.freeze({ ...entry });
427
- }
428
- return Object.freeze({
429
- entries: Object.freeze(immutableEntries),
430
- profileSha256: canonicalSha256(OH_EMBEDDING_PROFILE_V1),
431
- v: 1
432
- });
433
- }
434
- function parseQmdVectorResult(value) {
435
- if (!isPlainRecord(value) || !hasExactKeys(value, QMD_VECTOR_RESULT_KEYS))
436
- return null;
437
- const pathMatch = typeof value.filepath === "string" ? /^qmd:\/\/oh\/([a-f0-9]{64}\.md)$/u.exec(value.filepath) : null;
438
- const filename = pathMatch?.[1];
439
- const hash = parseSha256Hex(value.hash);
440
- const title = safeCode(value.title, 512);
441
- if (filename === undefined || value.displayPath !== `oh/${filename}` || value.collectionName !== "oh" || value.source !== "vec" || value.context !== null || value.modifiedAt !== "" || hash === null || value.docid !== hash.slice(0, 6) || title === null || typeof value.body !== "string" || typeof value.bodyLength !== "number" || !Number.isSafeInteger(value.bodyLength) || value.bodyLength < 0 || value.bodyLength > OH_GRAPH_LIMITS_V1.recordBytes + 4096 || value.body.length !== value.bodyLength || hash !== sha256Hex(value.body) || typeof value.chunkPos !== "number" || !Number.isSafeInteger(value.chunkPos) || value.chunkPos < 0 || typeof value.score !== "number" || !Number.isFinite(value.score) || value.score < 0 || value.score > 1) {
442
- return null;
443
- }
444
- return { body: value.body, filename, hash, score: value.score, title };
445
- }
446
- function parseQmdVectorResults(value) {
447
- if (!Array.isArray(value) || value.length > 100) {
448
- throw new Error("QMD returned an invalid vector result batch.");
449
- }
450
- return value.map(parseQmdVectorResult).filter((result) => result !== null);
451
- }
452
-
453
- class OhQmdSemanticBackendV1 {
454
- profile = OH_EMBEDDING_PROFILE_V1;
455
- #cacheDirectory;
456
- #databasePath;
457
- #factory;
458
- #manifest = semanticManifest({});
459
- #manifestLoad = null;
460
- #store = null;
461
- #storeClose = null;
462
- #closure = null;
463
- #indexQueue = Promise.resolve();
464
- #activeSearches = new Set;
465
- #closed = false;
466
- constructor(options) {
467
- this.#cacheDirectory = resolve(options.cacheDirectory);
468
- this.#databasePath = resolve(options.databasePath ?? join(this.#cacheDirectory, "qmd.sqlite"));
469
- this.#factory = options.storeFactory ?? defaultQmdStoreFactory;
470
- }
471
- async#open() {
472
- if (this.#closed)
473
- throw new Error("The semantic backend is closed.");
474
- this.#store ??= this.#initializeStore();
475
- const store = await this.#store;
476
- if (this.#closed) {
477
- await this.#closeStore(store);
478
- throw new Error("The semantic backend is closed.");
479
- }
480
- return store;
481
- }
482
- async#initializeStore() {
483
- const documents = join(this.#cacheDirectory, "documents");
484
- await mkdir(documents, { recursive: true });
485
- await this.#loadManifest();
486
- if (this.#closed)
487
- throw new Error("The semantic backend is closed.");
488
- const store = await this.#factory({
489
- dbPath: this.#databasePath,
490
- config: {
491
- collections: { oh: { path: documents, pattern: "*.md" } },
492
- models: { embed: OH_EMBEDDING_PROFILE_V1.model }
493
- }
494
- });
495
- if (this.#closed) {
496
- await this.#closeStore(store);
497
- throw new Error("The semantic backend is closed.");
498
- }
499
- return store;
500
- }
501
- #closeStore(store) {
502
- this.#storeClose ??= Promise.resolve().then(() => store.close());
503
- return this.#storeClose;
504
- }
505
- #loadManifest() {
506
- this.#manifestLoad ??= this.#readManifest();
507
- return this.#manifestLoad;
508
- }
509
- async#readManifest() {
510
- let text;
511
- try {
512
- text = await readFile(join(this.#cacheDirectory, "manifest.json"), "utf8");
513
- } catch (error) {
514
- if (error.code === "ENOENT")
515
- return;
516
- throw error;
517
- }
518
- let value;
519
- try {
520
- value = JSON.parse(text);
521
- } catch {
522
- throw new Error("The semantic manifest is not JSON.");
523
- }
524
- if (canonicalJson(value) !== text || !isPlainRecord(value) || !hasExactKeys(value, ["entries", "profileSha256", "v"]) || value.v !== 1 || value.profileSha256 !== canonicalSha256(OH_EMBEDDING_PROFILE_V1) || !isPlainRecord(value.entries) || Object.keys(value.entries).length > 65536)
525
- throw new Error("The semantic manifest is incompatible or invalid.");
526
- const entries = {};
527
- for (const [filename, candidate] of Object.entries(value.entries)) {
528
- if (!/^[a-f0-9]{64}\.md$/u.test(filename) || !isPlainRecord(candidate) || !hasExactKeys(candidate, ["key", "recordSha256"]))
529
- throw new Error("The semantic manifest has an invalid entry.");
530
- const key = safeCode(candidate.key, 512);
531
- const recordSha256 = parseSha256Hex(candidate.recordSha256);
532
- if (key === null || recordSha256 === null || filename !== `${sha256Hex(key)}.md`) {
533
- throw new Error("The semantic manifest entry identity is invalid.");
534
- }
535
- entries[filename] = { key, recordSha256 };
536
- }
537
- this.#manifest = semanticManifest(entries);
538
- }
539
- index(records) {
540
- if (records.length > 65536) {
541
- return Promise.reject(new RangeError("A semantic snapshot may contain at most 65,536 records."));
542
- }
543
- if (this.#closed)
544
- return Promise.reject(new Error("The semantic backend is closed."));
545
- const snapshot = [...records];
546
- const operation = this.#indexQueue.then(() => this.#indexSnapshot(snapshot));
547
- this.#indexQueue = operation.then(() => {
548
- return;
549
- }, () => {
550
- return;
551
- });
552
- return operation;
553
- }
554
- async#indexSnapshot(records) {
555
- if (this.#closed)
556
- throw new Error("The semantic backend is closed.");
557
- const documents = join(this.#cacheDirectory, "documents");
558
- await mkdir(documents, { recursive: true });
559
- await this.#loadManifest();
560
- const entries = {};
561
- for (const record of records) {
562
- const filename = `${sha256Hex(record.key)}.md`;
563
- entries[filename] = { key: record.key, recordSha256: record.recordSha256 };
564
- const path = join(documents, filename);
565
- const temporary = `${path}.${process.pid}.tmp`;
566
- await writeFile(temporary, recordDocument(record), { encoding: "utf8", mode: 384 });
567
- await rename(temporary, path);
568
- }
569
- const retained = new Set(Object.keys(entries));
570
- for (const filename of await readdir(documents)) {
571
- if (/^[a-f0-9]{64}\.md$/u.test(filename) && !retained.has(filename))
572
- await unlink(join(documents, filename));
573
- }
574
- const nextManifest = semanticManifest(entries);
575
- const store = await this.#open();
576
- await store.update({ collections: ["oh"] });
577
- await store.embed({ collection: "oh", model: OH_EMBEDDING_PROFILE_V1.model });
578
- const manifestPath = join(this.#cacheDirectory, "manifest.json");
579
- const temporaryManifest = `${manifestPath}.${process.pid}.tmp`;
580
- await writeFile(temporaryManifest, canonicalJson(nextManifest), { encoding: "utf8", mode: 384 });
581
- await rename(temporaryManifest, manifestPath);
582
- this.#manifest = nextManifest;
583
- return { indexed: records.length, v: 1 };
584
- }
585
- search(query, limit, authority) {
586
- if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100) {
587
- return Promise.reject(new RangeError("Semantic limit must be 1 through 100."));
588
- }
589
- if (this.#closed)
590
- return Promise.reject(new Error("The semantic backend is closed."));
591
- const operation = this.#searchSnapshot(query, limit, authority);
592
- this.#activeSearches.add(operation);
593
- operation.then(() => {
594
- this.#activeSearches.delete(operation);
595
- }, () => {
596
- this.#activeSearches.delete(operation);
597
- });
598
- return operation;
599
- }
600
- async#searchSnapshot(query, limit, authority) {
601
- const store = await this.#open();
602
- const manifest = this.#manifest;
603
- const results = parseQmdVectorResults(await store.searchVector(query, { collection: "oh", limit: Math.min(100, limit * 3) }));
604
- const output = [];
605
- const seen = new Set;
606
- for (const result of results) {
607
- const entry = manifest.entries[result.filename];
608
- if (entry === undefined || result.title !== entry.key || seen.has(entry.key))
609
- continue;
610
- const current = authority.get(entry.key);
611
- if (current === null || current.recordSha256 !== entry.recordSha256)
612
- continue;
613
- const expectedDocument = recordDocument(current);
614
- if (result.body !== expectedDocument || result.hash !== sha256Hex(expectedDocument))
615
- continue;
616
- seen.add(entry.key);
617
- output.push({ key: entry.key, recordSha256: entry.recordSha256, score: result.score, v: 1 });
618
- if (output.length === limit)
619
- break;
620
- }
621
- return output;
622
- }
623
- async#finishClose() {
624
- await this.#indexQueue;
625
- await Promise.allSettled([...this.#activeSearches]);
626
- if (this.#store === null)
627
- return;
628
- try {
629
- const store = await this.#store;
630
- await this.#closeStore(store);
631
- } catch {
632
- if (this.#storeClose !== null)
633
- await this.#storeClose;
634
- }
635
- }
636
- close() {
637
- this.#closed = true;
638
- this.#closure ??= this.#finishClose();
639
- return this.#closure;
640
- }
641
- }
642
383
 
643
384
  // src/cloudflare-embedding.ts
644
385
  var cloudflareEmbeddingProfilePayload = Object.freeze({
@@ -0,0 +1,75 @@
1
+ import { type Sha256Hex } from "./canonical";
2
+ import { type KnowledgeGraphRecordV1 } from "./graph";
3
+ import type { OhSqliteStore } from "./sqlite/store";
4
+ export declare const OH_EMBEDDING_PROFILE_V1: Readonly<{
5
+ readonly dimensions: 768;
6
+ readonly distance: "cosine";
7
+ readonly documentation: "https://ai.google.dev/gemma/docs/embeddinggemma";
8
+ readonly documentFormat: "title: {title} | text: {content}";
9
+ readonly engine: "@tobilu/qmd@2.5.3";
10
+ readonly model: "hf:ggml-org/embeddinggemma-300M-GGUF/embeddinggemma-300M-Q8_0.gguf";
11
+ readonly normalization: "l2";
12
+ readonly queryFormat: "task: search result | query: {query}";
13
+ readonly v: 1;
14
+ }>;
15
+ export type OhEmbeddingProfileV1 = typeof OH_EMBEDDING_PROFILE_V1;
16
+ export declare function formatOhEmbeddingQueryV1(query: string): string;
17
+ export declare function formatOhEmbeddingDocumentV1(title: string, content: string): string;
18
+ export declare function normalizeOhEmbeddingV1(vector: readonly number[]): readonly number[];
19
+ export declare function cosineSimilarityV1(left: readonly number[], right: readonly number[]): number;
20
+ export type OhSemanticSearchResultV1 = Readonly<{
21
+ key: string;
22
+ recordSha256: Sha256Hex;
23
+ score: number;
24
+ v: 1;
25
+ }>;
26
+ export interface OhSemanticSearchBackendV1 {
27
+ readonly profile: OhEmbeddingProfileV1;
28
+ close(): Promise<void>;
29
+ index(records: readonly KnowledgeGraphRecordV1[]): Promise<Readonly<{
30
+ indexed: number;
31
+ v: 1;
32
+ }>>;
33
+ search(query: string, limit: number, authority: OhSqliteStore): Promise<readonly OhSemanticSearchResultV1[]>;
34
+ }
35
+ export type QmdStore = {
36
+ close(): Promise<void>;
37
+ embed(options: Readonly<{
38
+ collection: string;
39
+ model: string;
40
+ }>): Promise<unknown>;
41
+ searchVector(query: string, options: Readonly<{
42
+ collection: string;
43
+ limit: number;
44
+ }>): Promise<unknown>;
45
+ update(options: Readonly<{
46
+ collections: readonly string[];
47
+ }>): Promise<unknown>;
48
+ };
49
+ export type QmdStoreFactoryV1 = (options: Readonly<{
50
+ config: Readonly<Record<string, unknown>>;
51
+ dbPath: string;
52
+ }>) => Promise<QmdStore>;
53
+ export type SemanticManifestV1 = Readonly<{
54
+ entries: Readonly<Record<string, Readonly<{
55
+ key: string;
56
+ recordSha256: Sha256Hex;
57
+ }>>>;
58
+ profileSha256: Sha256Hex;
59
+ v: 1;
60
+ }>;
61
+ export declare function recordDocument(record: KnowledgeGraphRecordV1): string;
62
+ type ParsedQmdVectorResult = Readonly<{
63
+ body: string;
64
+ filename: string;
65
+ hash: Sha256Hex;
66
+ score: number;
67
+ title: string;
68
+ }>;
69
+ export declare function semanticManifest(entries: Record<string, {
70
+ key: string;
71
+ recordSha256: Sha256Hex;
72
+ }>): SemanticManifestV1;
73
+ export declare function parseQmdVectorResults(value: unknown): readonly ParsedQmdVectorResult[];
74
+ export {};
75
+ //# sourceMappingURL=semantic-model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-model.d.ts","sourceRoot":"","sources":["../src/semantic-model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import { Context, Effect, Layer } from "effect";
2
+ import type { KnowledgeGraphRecordV1 } from "./graph";
3
+ import type { OhSqliteStore } from "./sqlite/store";
4
+ import { type QmdStore, type QmdStoreFactoryV1, type SemanticManifestV1 } from "./semantic-model";
5
+ export type SemanticFailure = Readonly<{
6
+ _tag: "FilesystemFailure" | "BackendFailure" | "ManifestFailure" | "ResultFailure" | "AuthorityFailure" | "Closed";
7
+ cause: unknown;
8
+ }>;
9
+ export type SemanticOptions = Readonly<{
10
+ cacheDirectory: string;
11
+ databasePath?: string;
12
+ storeFactory?: QmdStoreFactoryV1;
13
+ }>;
14
+ export interface SemanticPlatformService {
15
+ readonly prepare: Effect.Effect<void, SemanticFailure>;
16
+ readonly loadManifest: Effect.Effect<SemanticManifestV1, SemanticFailure>;
17
+ readonly open: Effect.Effect<QmdStore, SemanticFailure>;
18
+ close(store: QmdStore): Effect.Effect<void, SemanticFailure>;
19
+ update(store: QmdStore): Effect.Effect<unknown, SemanticFailure>;
20
+ embed(store: QmdStore): Effect.Effect<unknown, SemanticFailure>;
21
+ search(store: QmdStore, query: string, limit: number): Effect.Effect<unknown, SemanticFailure>;
22
+ writeDocuments(records: readonly KnowledgeGraphRecordV1[]): Effect.Effect<SemanticManifestV1, SemanticFailure>;
23
+ publishManifest(manifest: SemanticManifestV1): Effect.Effect<void, SemanticFailure>;
24
+ readAuthority(authority: OhSqliteStore, key: string): Effect.Effect<KnowledgeGraphRecordV1 | null, SemanticFailure>;
25
+ }
26
+ declare const SemanticPlatform_base: Context.TagClass<SemanticPlatform, "@hraness/oh/SemanticPlatform", SemanticPlatformService>;
27
+ export declare class SemanticPlatform extends SemanticPlatform_base {
28
+ }
29
+ /** Foreign filesystem and optional QMD calls are confined to this adapter. */
30
+ export declare function semanticPlatformLive(options: SemanticOptions): Layer.Layer<SemanticPlatform>;
31
+ export {};
32
+ //# sourceMappingURL=semantic-platform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-platform.d.ts","sourceRoot":"","sources":["../src/semantic-platform.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAIhD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACL,KAAK,QAAQ,EAAE,KAAK,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE3F,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,IAAI,EAAE,mBAAmB,GAAG,gBAAgB,GAAG,iBAAiB,GAAG,eAAe,GAAG,kBAAkB,GAAG,QAAQ,CAAC;IAEnH,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,iBAAiB,CAAC;CAClC,CAAC,CAAC;AAEH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IACvD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,eAAe,CAAC,CAAC;IAC1E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACxD,KAAK,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IAC7D,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IACjE,KAAK,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAChE,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAC/F,cAAc,CAAC,OAAO,EAAE,SAAS,sBAAsB,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,eAAe,CAAC,CAAC;IAC/G,eAAe,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IACpF,aAAa,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,sBAAsB,GAAG,IAAI,EAAE,eAAe,CAAC,CAAC;CACrH;;AAED,qBAAa,gBAAiB,SAAQ,qBAEnC;CAAG;AAsCN,8EAA8E;AAC9E,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,GAAG,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAoD5F"}
@@ -0,0 +1,18 @@
1
+ import { Effect, Exit, FiberSet, Ref } from "effect";
2
+ import type { KnowledgeGraphRecordV1 } from "./graph";
3
+ import { type OhSemanticSearchResultV1 } from "./semantic-model";
4
+ import { SemanticPlatform, type SemanticFailure } from "./semantic-platform";
5
+ import type { OhSqliteStore } from "./sqlite/store";
6
+ export interface SemanticLifecycle {
7
+ readonly closed: Ref.Ref<boolean>;
8
+ readonly operations: FiberSet.FiberSet<Exit.Exit<unknown, SemanticFailure>, never>;
9
+ readonly close: Effect.Effect<void, SemanticFailure>;
10
+ index(records: readonly KnowledgeGraphRecordV1[]): Effect.Effect<Readonly<{
11
+ indexed: number;
12
+ v: 1;
13
+ }>, SemanticFailure>;
14
+ search(query: string, limit: number, authority: OhSqliteStore): Effect.Effect<readonly OhSemanticSearchResultV1[], SemanticFailure>;
15
+ }
16
+ /** One owner scope holds the optional store until all admitted operations settle. */
17
+ export declare const makeSemanticLifecycle: Effect.Effect<SemanticLifecycle, never, SemanticPlatform>;
18
+ //# sourceMappingURL=semantic-program.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-program.d.ts","sourceRoot":"","sources":["../src/semantic-program.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAS,MAAM,QAAQ,CAAC;AAG5D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EACL,KAAK,wBAAwB,EAA2B,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE,KAAK,CAAC,CAAC;IACnF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IACrD,KAAK,CAAC,OAAO,EAAE,SAAS,sBAAsB,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,CAAC,CAAA;KAAE,CAAC,EAAE,eAAe,CAAC,CAAC;IACvH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,wBAAwB,EAAE,EAAE,eAAe,CAAC,CAAC;CACrI;AAED,qFAAqF;AACrF,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,KAAK,EAAE,gBAAgB,CA8F1F,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { OhSemanticSearchBackendV1 } from "./semantic-model";
2
+ import { type SemanticOptions } from "./semantic-platform";
3
+ type SemanticBoundary = Omit<OhSemanticSearchBackendV1, "profile">;
4
+ export declare function makeSemanticBoundary(options: SemanticOptions): SemanticBoundary;
5
+ export {};
6
+ //# sourceMappingURL=semantic-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-runtime.d.ts","sourceRoot":"","sources":["../src/semantic-runtime.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAA8C,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGvG,KAAK,gBAAgB,GAAG,IAAI,CAAC,yBAAyB,EAAE,SAAS,CAAC,CAAC;AAWnE,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,GAAG,gBAAgB,CAmC/E"}
@@ -1,55 +1,8 @@
1
- import { type Sha256Hex } from "./canonical";
2
- import { type KnowledgeGraphRecordV1 } from "./graph";
1
+ import type { KnowledgeGraphRecordV1 } from "./graph";
2
+ import { type OhSemanticSearchBackendV1, type QmdStoreFactoryV1 } from "./semantic-model";
3
3
  import type { OhSqliteStore } from "./sqlite/store";
4
- export declare const OH_EMBEDDING_PROFILE_V1: Readonly<{
5
- readonly dimensions: 768;
6
- readonly distance: "cosine";
7
- readonly documentation: "https://ai.google.dev/gemma/docs/embeddinggemma";
8
- readonly documentFormat: "title: {title} | text: {content}";
9
- readonly engine: "@tobilu/qmd@2.5.3";
10
- readonly model: "hf:ggml-org/embeddinggemma-300M-GGUF/embeddinggemma-300M-Q8_0.gguf";
11
- readonly normalization: "l2";
12
- readonly queryFormat: "task: search result | query: {query}";
13
- readonly v: 1;
14
- }>;
15
- export type OhEmbeddingProfileV1 = typeof OH_EMBEDDING_PROFILE_V1;
16
- export declare function formatOhEmbeddingQueryV1(query: string): string;
17
- export declare function formatOhEmbeddingDocumentV1(title: string, content: string): string;
18
- export declare function normalizeOhEmbeddingV1(vector: readonly number[]): readonly number[];
19
- export declare function cosineSimilarityV1(left: readonly number[], right: readonly number[]): number;
20
- export type OhSemanticSearchResultV1 = Readonly<{
21
- key: string;
22
- recordSha256: Sha256Hex;
23
- score: number;
24
- v: 1;
25
- }>;
26
- export interface OhSemanticSearchBackendV1 {
27
- readonly profile: OhEmbeddingProfileV1;
28
- close(): Promise<void>;
29
- index(records: readonly KnowledgeGraphRecordV1[]): Promise<Readonly<{
30
- indexed: number;
31
- v: 1;
32
- }>>;
33
- search(query: string, limit: number, authority: OhSqliteStore): Promise<readonly OhSemanticSearchResultV1[]>;
34
- }
35
- type QmdStore = {
36
- close(): Promise<void>;
37
- embed(options: Readonly<{
38
- collection: string;
39
- model: string;
40
- }>): Promise<unknown>;
41
- searchVector(query: string, options: Readonly<{
42
- collection: string;
43
- limit: number;
44
- }>): Promise<unknown>;
45
- update(options: Readonly<{
46
- collections: readonly string[];
47
- }>): Promise<unknown>;
48
- };
49
- export type QmdStoreFactoryV1 = (options: Readonly<{
50
- config: Readonly<Record<string, unknown>>;
51
- dbPath: string;
52
- }>) => Promise<QmdStore>;
4
+ export { OH_EMBEDDING_PROFILE_V1, cosineSimilarityV1, formatOhEmbeddingDocumentV1, formatOhEmbeddingQueryV1, normalizeOhEmbeddingV1 } from "./semantic-model";
5
+ export type { OhEmbeddingProfileV1, OhSemanticSearchBackendV1, OhSemanticSearchResultV1, QmdStoreFactoryV1 } from "./semantic-model";
53
6
  /**
54
7
  * Optional, rebuildable local QMD index. SQLite records remain authoritative;
55
8
  * every returned hit is rejoined to its exact current record digest.
@@ -72,12 +25,8 @@ export declare class OhQmdSemanticBackendV1 implements OhSemanticSearchBackendV1
72
25
  databasePath?: string;
73
26
  storeFactory?: QmdStoreFactoryV1;
74
27
  }>);
75
- index(records: readonly KnowledgeGraphRecordV1[]): Promise<Readonly<{
76
- indexed: number;
77
- v: 1;
78
- }>>;
79
- search(query: string, limit: number, authority: OhSqliteStore): Promise<readonly OhSemanticSearchResultV1[]>;
28
+ index(records: readonly KnowledgeGraphRecordV1[]): ReturnType<OhSemanticSearchBackendV1["index"]>;
29
+ search(query: string, limit: number, authority: OhSqliteStore): ReturnType<OhSemanticSearchBackendV1["search"]>;
80
30
  close(): Promise<void>;
81
31
  }
82
- export {};
83
32
  //# sourceMappingURL=semantic.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"semantic.d.ts","sourceRoot":"","sources":["../src/semantic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"semantic.d.ts","sourceRoot":"","sources":["../src/semantic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAA2B,KAAK,yBAAyB,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEnH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,2BAA2B,EAC/E,wBAAwB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC7E,YAAY,EAAE,oBAAoB,EAAE,yBAAyB,EAC3D,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAExE;;;GAGG;AACH,qBAAa,sBAAuB,YAAW,yBAAyB;;IACtE,QAAQ,CAAC,OAAO;;;;;;;;;;OAA2B;gBAG/B,OAAO,EAAE,QAAQ,CAAC;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,iBAAiB,CAAA;KAAE,CAAC;IAIlH,KAAK,CAAC,OAAO,EAAE,SAAS,sBAAsB,EAAE,GAAG,UAAU,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC;IAIjG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,GAAG,UAAU,CAAC,yBAAyB,CAAC,QAAQ,CAAC,CAAC;IAI/G,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAGvB"}