@equationalapplications/core-llm-wiki 4.17.2 → 4.18.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/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { __privateAdd, EmbeddingService, SearchService, JobManager, PromptService, IngestionService, MaintenanceService, ImportExportService, RetrievalService, WriteService, __privateGet, __privateSet, normalizeSourceRef, normalizeSourceHash, generateId, validateManifest, emptyManifest, mergeOntologyUpdates, resolveNodeType, validateInlineEdges, resolveEdgeDefinition, normalizeTitleKey } from './chunk-AV2ZNKEA.mjs';
2
- export { HOOK_TIMEOUT_MARKER, PromptService, PrunePartialFailureError, WikiBusyError, configureRandomSource, parseEmbedding } from './chunk-AV2ZNKEA.mjs';
3
- import { buildConceptDocument, buildLogMd, buildIndexMd, buildRootIndexMd, parseConcept, extractMarkdownLinks, parseLogMd } from '@equationalapplications/core-okf';
1
+ import { __privateAdd, EmbeddingService, SearchService, JobManager, PromptService, IngestionService, MaintenanceService, ImportExportService, RetrievalService, WriteService, __privateGet, __privateSet, normalizeSourceRef, normalizeSourceHash, generateId, validateManifest, emptyManifest, mergeOntologyUpdates, resolveNodeType, validateInlineEdges, resolveEdgeDefinition, normalizeTitleKey } from './chunk-V7QNRQFK.mjs';
2
+ export { HOOK_TIMEOUT_MARKER, PromptService, PrunePartialFailureError, WikiBusyError, configureRandomSource, parseEmbedding } from './chunk-V7QNRQFK.mjs';
3
+ import { appendRelatedSection, buildConceptDocument, buildLogMd, buildEntityIndexMd, buildRootIndexMd, isAllowedOkfPath, parseRootIndexMd, parseEntityIndexMd, parseConcept, splitRelatedSection, extractMarkdownLinks, parseLogMd, parseEventIdComment, appendEventIdComment } from '@equationalapplications/core-okf';
4
4
 
5
5
  // src/db/schema.ts
6
6
  async function setupDatabase(db, prefix) {
@@ -2385,6 +2385,7 @@ function formatMemoryDump(dump) {
2385
2385
  files
2386
2386
  };
2387
2387
  }
2388
+ var LLM_WIKI_PROFILE = "llm-wiki/1";
2388
2389
  function factFrontmatter(f) {
2389
2390
  return {
2390
2391
  type: f.okf_type ?? "fact",
@@ -2420,30 +2421,61 @@ function taskFrontmatter(t) {
2420
2421
  function formatLogDate(timestampMs) {
2421
2422
  return new Date(timestampMs).toISOString().slice(0, 10);
2422
2423
  }
2424
+ function conceptRelativePath(sourceFilePath, targetFilePath) {
2425
+ const sourceDir = sourceFilePath.slice(0, sourceFilePath.lastIndexOf("/"));
2426
+ const targetDir = targetFilePath.slice(0, targetFilePath.lastIndexOf("/"));
2427
+ const targetName = targetFilePath.slice(targetFilePath.lastIndexOf("/") + 1);
2428
+ if (sourceDir === targetDir) return `./${targetName}`;
2429
+ if (sourceDir.endsWith("/facts") && targetDir.endsWith("/tasks")) return `../tasks/${targetName}`;
2430
+ if (sourceDir.endsWith("/tasks") && targetDir.endsWith("/facts")) return `../facts/${targetName}`;
2431
+ return targetFilePath.replace(/^entities\/[^/]+\//, "");
2432
+ }
2423
2433
  function buildEventLogEntries(events, factIdToFilename) {
2424
2434
  return events.map((e) => {
2425
2435
  const factFilename = e.related_entry_id ? factIdToFilename.get(e.related_entry_id) : void 0;
2426
2436
  const summary = e.summary.replace(/\\/g, "\\\\").replace(/\[/g, "\\[").replace(/\]/g, "\\]").replace(/\r?\n/g, " ");
2427
2437
  const text = factFilename ? `(${e.event_type}) [${summary}](./facts/${factFilename}.md)` : `(${e.event_type}) ${summary}`;
2428
- return { date: formatLogDate(e.created_at), text };
2438
+ return { date: formatLogDate(e.created_at), text: appendEventIdComment(text, e.id) };
2429
2439
  });
2430
2440
  }
2431
2441
  function formatOkfBundle(dump) {
2432
2442
  const files = [];
2433
2443
  const rootEntries = [];
2434
2444
  for (const [entityId, bundle] of Object.entries(dump.entities)) {
2445
+ let relatedLinksFor2 = function(sourcePath, sourceId) {
2446
+ return (edgesBySource.get(sourceId) ?? []).map((edge) => {
2447
+ const targetPath = idToConceptPath.get(edge.target_id);
2448
+ if (!targetPath) return null;
2449
+ return { edge_type: edge.edge_type, path: conceptRelativePath(sourcePath, targetPath) };
2450
+ }).filter((link) => link != null).sort((a, b) => a.edge_type.localeCompare(b.edge_type) || a.path.localeCompare(b.path));
2451
+ };
2435
2452
  const dir = sanitizeForFilename(entityId);
2436
2453
  const factIdToFilename = new Map(
2437
2454
  bundle.facts.map((f) => [f.id, sanitizeConceptId(f.id)])
2438
2455
  );
2456
+ const idToConceptPath = /* @__PURE__ */ new Map();
2457
+ for (const f of bundle.facts) {
2458
+ idToConceptPath.set(f.id, `entities/${dir}/facts/${factIdToFilename.get(f.id)}.md`);
2459
+ }
2460
+ for (const t of bundle.tasks) {
2461
+ idToConceptPath.set(t.id, `entities/${dir}/tasks/${sanitizeConceptId(t.id)}.md`);
2462
+ }
2463
+ const edgesBySource = /* @__PURE__ */ new Map();
2464
+ for (const edge of bundle.edges ?? []) {
2465
+ const group = edgesBySource.get(edge.source_id) ?? [];
2466
+ group.push(edge);
2467
+ edgesBySource.set(edge.source_id, group);
2468
+ }
2439
2469
  const factEntries = bundle.facts.map((f) => ({
2440
2470
  path: `facts/${factIdToFilename.get(f.id)}.md`,
2441
2471
  title: f.title
2442
2472
  }));
2443
2473
  for (const f of bundle.facts) {
2474
+ const factPath = `entities/${dir}/facts/${factIdToFilename.get(f.id)}.md`;
2475
+ const factBody = appendRelatedSection(f.body, relatedLinksFor2(factPath, f.id));
2444
2476
  files.push({
2445
- path: `entities/${dir}/facts/${factIdToFilename.get(f.id)}.md`,
2446
- content: buildConceptDocument(factFrontmatter(f), f.body)
2477
+ path: factPath,
2478
+ content: buildConceptDocument(factFrontmatter(f), factBody)
2447
2479
  });
2448
2480
  }
2449
2481
  const taskEntries = bundle.tasks.map((t) => ({
@@ -2451,9 +2483,11 @@ function formatOkfBundle(dump) {
2451
2483
  title: t.description
2452
2484
  }));
2453
2485
  for (const t of bundle.tasks) {
2486
+ const taskPath = `entities/${dir}/tasks/${sanitizeConceptId(t.id)}.md`;
2487
+ const taskBody = appendRelatedSection("", relatedLinksFor2(taskPath, t.id));
2454
2488
  files.push({
2455
- path: `entities/${dir}/tasks/${sanitizeConceptId(t.id)}.md`,
2456
- content: buildConceptDocument(taskFrontmatter(t), "")
2489
+ path: taskPath,
2490
+ content: buildConceptDocument(taskFrontmatter(t), taskBody)
2457
2491
  });
2458
2492
  }
2459
2493
  files.push({
@@ -2466,8 +2500,10 @@ function formatOkfBundle(dump) {
2466
2500
  ];
2467
2501
  files.push({
2468
2502
  path: `entities/${dir}/index.md`,
2469
- content: `${buildIndexMd(entityIndexSections)}[Event log](./log.md)
2470
- `
2503
+ content: buildEntityIndexMd({
2504
+ summary: bundle.summary,
2505
+ sections: entityIndexSections
2506
+ })
2471
2507
  });
2472
2508
  rootEntries.push({ path: `entities/${dir}/index.md`, title: entityId });
2473
2509
  }
@@ -2475,7 +2511,8 @@ function formatOkfBundle(dump) {
2475
2511
  path: "index.md",
2476
2512
  content: buildRootIndexMd(
2477
2513
  "0.1",
2478
- rootEntries.length > 0 ? [{ heading: "Entities", entries: rootEntries }] : []
2514
+ rootEntries.length > 0 ? [{ heading: "Entities", entries: rootEntries }] : [],
2515
+ { profile: LLM_WIKI_PROFILE }
2479
2516
  )
2480
2517
  });
2481
2518
  return { files };
@@ -2520,6 +2557,14 @@ function resolveRelativePath(fromFile, linkPath) {
2520
2557
  }
2521
2558
  return resolved.join("/");
2522
2559
  }
2560
+ function decodeLinkPath(path) {
2561
+ if (!path.includes("%")) return path;
2562
+ try {
2563
+ return decodeURIComponent(path);
2564
+ } catch {
2565
+ return path;
2566
+ }
2567
+ }
2523
2568
  function addPathAliases(map, filePath, resolvedId) {
2524
2569
  map.set(filePath, resolvedId);
2525
2570
  const withoutDot = filePath.replace(/^\.\//, "");
@@ -2617,10 +2662,56 @@ function frontmatterToTask(entityId, id, frontmatter, now) {
2617
2662
  function findLogMdPath(files) {
2618
2663
  return files.find((f) => f.path.endsWith("/log.md") || f.path === "log.md")?.path;
2619
2664
  }
2665
+ function extractEdgesFromLinks(filePath, resolvedId, links, pathToResolvedId, entityId, now, seenEdges, edges) {
2666
+ for (const link of links) {
2667
+ const strippedPath = stripLinkSuffix(decodeLinkPath(link.path));
2668
+ const directTargetId = lookupResolvedId(pathToResolvedId, strippedPath);
2669
+ const resolvedTargetPath = resolveRelativePath(filePath, strippedPath);
2670
+ if (isStructuralPath(strippedPath) || isStructuralPath(resolvedTargetPath)) continue;
2671
+ const targetId = directTargetId ?? lookupResolvedId(pathToResolvedId, resolvedTargetPath);
2672
+ if (!targetId) continue;
2673
+ const edgeKey = `${resolvedId}\0${targetId}\0${link.text}`;
2674
+ if (seenEdges.has(edgeKey)) continue;
2675
+ seenEdges.add(edgeKey);
2676
+ edges.push({
2677
+ id: generateId(),
2678
+ entity_id: entityId,
2679
+ source_id: resolvedId,
2680
+ target_id: targetId,
2681
+ edge_type: link.text,
2682
+ created_at: now
2683
+ });
2684
+ }
2685
+ }
2620
2686
  function parseOkfBundle(entityId, files, options) {
2621
2687
  const now = Date.now();
2688
+ const normalizeOkfPath = (p) => p.replace(/^\.\//, "").replace(/\\/g, "/");
2689
+ const normalizedFiles = files.map((f) => ({ ...f, path: normalizeOkfPath(f.path) }));
2690
+ const allowlistedFiles = normalizedFiles.filter((f) => isAllowedOkfPath(f.path));
2691
+ const entityDirs = new Set(
2692
+ allowlistedFiles.map((f) => /^entities\/([^/]+)\//.exec(f.path)?.[1]).filter((dir) => !!dir)
2693
+ );
2694
+ if (entityDirs.size > 1) {
2695
+ throw new Error(
2696
+ `parseOkfBundle: expected a single-entity bundle for "${entityId}", found entities: ${Array.from(entityDirs).join(", ")}`
2697
+ );
2698
+ }
2699
+ const entityDir = entityDirs.values().next().value ?? entityId;
2700
+ const entityPrefix = `entities/${entityDir}/`;
2701
+ const allowedFiles = allowlistedFiles.filter(
2702
+ (f) => f.path === "index.md" || f.path.startsWith(entityPrefix)
2703
+ );
2704
+ const rootIndex = allowedFiles.find((f) => f.path === "index.md");
2705
+ const profileMeta = rootIndex ? parseRootIndexMd(rootIndex.content) : {};
2706
+ const isProfile1 = profileMeta.profile === "llm-wiki/1";
2707
+ let entitySummary;
2708
+ const entityIndex = allowedFiles.find((f) => f.path === `${entityPrefix}index.md`);
2709
+ if (isProfile1 && entityIndex) {
2710
+ const summary = parseEntityIndexMd(entityIndex.content).summary;
2711
+ entitySummary = summary || void 0;
2712
+ }
2622
2713
  const pathToResolvedId = /* @__PURE__ */ new Map();
2623
- for (const file of files) {
2714
+ for (const file of allowedFiles) {
2624
2715
  if (!isConceptFile(file.path)) continue;
2625
2716
  const { frontmatter } = parseConcept(file.content);
2626
2717
  const route = resolveRoute(file.path, frontmatter.type ?? "", options);
@@ -2632,8 +2723,8 @@ function parseOkfBundle(entityId, files, options) {
2632
2723
  const tasks = [];
2633
2724
  const edges = [];
2634
2725
  let logContent = null;
2635
- const logMdPath = findLogMdPath(files);
2636
- for (const file of files) {
2726
+ const logMdPath = findLogMdPath(allowedFiles);
2727
+ for (const file of allowedFiles) {
2637
2728
  if (file.path.endsWith("/log.md") || file.path === "log.md") {
2638
2729
  logContent = file.content;
2639
2730
  continue;
@@ -2643,41 +2734,38 @@ function parseOkfBundle(entityId, files, options) {
2643
2734
  const route = resolveRoute(file.path, frontmatter.type ?? "", options);
2644
2735
  if (route === "ignore") continue;
2645
2736
  const resolvedId = typeof frontmatter.id === "string" && frontmatter.id ? frontmatter.id : basenameMd(file.path);
2737
+ const { body: storedBody, relatedLinks } = splitRelatedSection(body);
2738
+ const edgeLinks = isProfile1 ? relatedLinks : [...relatedLinks, ...extractMarkdownLinks(storedBody)];
2646
2739
  if (route === "fact") {
2647
- facts.push(frontmatterToFact(entityId, resolvedId, frontmatter, body, now));
2740
+ facts.push(frontmatterToFact(entityId, resolvedId, frontmatter, storedBody, now));
2648
2741
  } else {
2649
2742
  tasks.push(frontmatterToTask(entityId, resolvedId, frontmatter, now));
2650
2743
  }
2651
2744
  const seenEdges = /* @__PURE__ */ new Set();
2652
- for (const link of extractMarkdownLinks(body)) {
2653
- const strippedPath = stripLinkSuffix(link.path);
2654
- const directTargetId = lookupResolvedId(pathToResolvedId, strippedPath);
2655
- const resolvedTargetPath = resolveRelativePath(file.path, strippedPath);
2656
- if (isStructuralPath(strippedPath) || isStructuralPath(resolvedTargetPath)) continue;
2657
- const targetId = directTargetId ?? lookupResolvedId(pathToResolvedId, resolvedTargetPath);
2658
- if (!targetId) continue;
2659
- const edgeKey = `${resolvedId}\0${targetId}\0${link.text}`;
2660
- if (seenEdges.has(edgeKey)) continue;
2661
- seenEdges.add(edgeKey);
2662
- edges.push({
2663
- id: generateId(),
2664
- entity_id: entityId,
2665
- source_id: resolvedId,
2666
- target_id: targetId,
2667
- edge_type: link.text,
2668
- created_at: now
2669
- });
2670
- }
2745
+ extractEdgesFromLinks(
2746
+ file.path,
2747
+ resolvedId,
2748
+ edgeLinks,
2749
+ pathToResolvedId,
2750
+ entityId,
2751
+ now,
2752
+ seenEdges,
2753
+ edges
2754
+ );
2671
2755
  }
2672
2756
  const events = [];
2673
2757
  if (logContent != null) {
2674
2758
  const logPath = logMdPath ?? `entities/${entityId}/log.md`;
2675
2759
  for (const entry of parseLogMd(logContent)) {
2676
- const parsed = parseLogEntryText(entry.text);
2760
+ const { text, eventId } = parseEventIdComment(entry.text);
2761
+ const parsed = parseLogEntryText(text);
2677
2762
  if (!parsed) continue;
2678
2763
  let related_entry_id = null;
2679
2764
  if (parsed.linkPath) {
2680
- const targetPath = resolveRelativePath(logPath, stripLinkSuffix(parsed.linkPath));
2765
+ const targetPath = resolveRelativePath(
2766
+ logPath,
2767
+ stripLinkSuffix(decodeLinkPath(parsed.linkPath))
2768
+ );
2681
2769
  if (!isStructuralPath(targetPath) && targetPath.includes("/facts/")) {
2682
2770
  related_entry_id = lookupResolvedId(pathToResolvedId, targetPath) ?? null;
2683
2771
  }
@@ -2685,7 +2773,7 @@ function parseOkfBundle(entityId, files, options) {
2685
2773
  const created_at = (/* @__PURE__ */ new Date(`${entry.date}T00:00:00.000Z`)).getTime();
2686
2774
  if (!Number.isFinite(created_at)) continue;
2687
2775
  events.push({
2688
- id: generateId("evt_"),
2776
+ id: eventId ?? generateId("evt_"),
2689
2777
  entity_id: entityId,
2690
2778
  event_type: parsed.event_type,
2691
2779
  summary: parsed.summary,
@@ -2697,7 +2785,7 @@ function parseOkfBundle(entityId, files, options) {
2697
2785
  return {
2698
2786
  generatedAt: now,
2699
2787
  entities: {
2700
- [entityId]: { facts, tasks, events, edges }
2788
+ [entityId]: { facts, tasks, events, edges, summary: entitySummary }
2701
2789
  }
2702
2790
  };
2703
2791
  }