studiograph 1.1.2 → 1.2.0-beta.1
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/LICENSE +191 -0
- package/README.md +301 -10
- package/dist/agent/orchestrator.d.ts +17 -9
- package/dist/agent/orchestrator.js +142 -97
- package/dist/agent/orchestrator.js.map +1 -1
- package/dist/agent/prompts/system.md +186 -0
- package/dist/agent/skill-loader.d.ts +48 -0
- package/dist/agent/skill-loader.js +166 -0
- package/dist/agent/skill-loader.js.map +1 -0
- package/dist/agent/skills/enrich-entities.md +136 -0
- package/dist/agent/skills/entity-schema.md +502 -0
- package/dist/agent/skills/gather-context.md +46 -0
- package/dist/agent/skills/obsidian-source-setup.md +246 -0
- package/dist/agent/skills/skill-loader.d.ts +48 -0
- package/dist/agent/skills/skill-loader.js +166 -0
- package/dist/agent/skills/skill-loader.js.map +1 -0
- package/dist/agent/skills/sync-configuration.md +144 -0
- package/dist/agent/skills/sync-setup.md +68 -0
- package/dist/agent/tools/connector-tools.d.ts +37 -0
- package/dist/agent/tools/connector-tools.js +132 -0
- package/dist/agent/tools/connector-tools.js.map +1 -0
- package/dist/agent/tools/fs-tools.d.ts +39 -0
- package/dist/agent/tools/fs-tools.js +106 -0
- package/dist/agent/tools/fs-tools.js.map +1 -0
- package/dist/agent/tools/graph-tools.d.ts +30 -2
- package/dist/agent/tools/graph-tools.js +154 -37
- package/dist/agent/tools/graph-tools.js.map +1 -1
- package/dist/agent/tools/load-skill.d.ts +42 -0
- package/dist/agent/tools/load-skill.js +45 -0
- package/dist/agent/tools/load-skill.js.map +1 -0
- package/dist/agent/tools/sync-tools.d.ts +25 -0
- package/dist/agent/tools/sync-tools.js +691 -0
- package/dist/agent/tools/sync-tools.js.map +1 -0
- package/dist/agent/tools/tool-loader.d.ts +25 -0
- package/dist/agent/tools/tool-loader.js +73 -0
- package/dist/agent/tools/tool-loader.js.map +1 -0
- package/dist/auth/github.d.ts +11 -8
- package/dist/auth/github.js +56 -75
- package/dist/auth/github.js.map +1 -1
- package/dist/cli/colors.d.ts +54 -0
- package/dist/cli/colors.js +133 -0
- package/dist/cli/colors.js.map +1 -0
- package/dist/cli/commands/app.d.ts +7 -0
- package/dist/cli/commands/app.js +167 -0
- package/dist/cli/commands/app.js.map +1 -0
- package/dist/cli/commands/auth.d.ts +1 -1
- package/dist/cli/commands/auth.js +26 -10
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/clone.d.ts +9 -0
- package/dist/cli/commands/clone.js +167 -0
- package/dist/cli/commands/clone.js.map +1 -0
- package/dist/cli/commands/commit.d.ts +8 -0
- package/dist/cli/commands/commit.js +43 -0
- package/dist/cli/commands/commit.js.map +1 -0
- package/dist/cli/commands/config.d.ts +13 -0
- package/dist/cli/commands/config.js +276 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/connector.d.ts +33 -0
- package/dist/cli/commands/connector.js +178 -0
- package/dist/cli/commands/connector.js.map +1 -0
- package/dist/cli/commands/deploy.d.ts +11 -0
- package/dist/cli/commands/deploy.js +153 -0
- package/dist/cli/commands/deploy.js.map +1 -0
- package/dist/cli/commands/enrich.d.ts +11 -0
- package/dist/cli/commands/enrich.js +135 -0
- package/dist/cli/commands/enrich.js.map +1 -0
- package/dist/cli/commands/graphrag.d.ts +12 -0
- package/dist/cli/commands/graphrag.js +122 -0
- package/dist/cli/commands/graphrag.js.map +1 -0
- package/dist/cli/commands/index.d.ts +15 -0
- package/dist/cli/commands/index.js +117 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/init.js +110 -210
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/join.js +89 -24
- package/dist/cli/commands/join.js.map +1 -1
- package/dist/cli/commands/lint.d.ts +8 -0
- package/dist/cli/commands/lint.js +70 -0
- package/dist/cli/commands/lint.js.map +1 -0
- package/dist/cli/commands/mcp.d.ts +27 -0
- package/dist/cli/commands/mcp.js +56 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/orphans.d.ts +8 -0
- package/dist/cli/commands/orphans.js +125 -0
- package/dist/cli/commands/orphans.js.map +1 -0
- package/dist/cli/commands/provision.d.ts +8 -0
- package/dist/cli/commands/provision.js +116 -0
- package/dist/cli/commands/provision.js.map +1 -0
- package/dist/cli/commands/r2.d.ts +2 -0
- package/dist/cli/commands/r2.js +87 -6
- package/dist/cli/commands/r2.js.map +1 -1
- package/dist/cli/commands/reset.d.ts +12 -0
- package/dist/cli/commands/reset.js +137 -0
- package/dist/cli/commands/reset.js.map +1 -0
- package/dist/cli/commands/review.d.ts +19 -0
- package/dist/cli/commands/review.js +128 -0
- package/dist/cli/commands/review.js.map +1 -0
- package/dist/cli/commands/serve.js +47 -2
- package/dist/cli/commands/serve.js.map +1 -1
- package/dist/cli/commands/source.d.ts +16 -0
- package/dist/cli/commands/source.js +159 -0
- package/dist/cli/commands/source.js.map +1 -0
- package/dist/cli/commands/start.js +472 -103
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/sync-entities.d.ts +13 -0
- package/dist/cli/commands/sync-entities.js +242 -0
- package/dist/cli/commands/sync-entities.js.map +1 -0
- package/dist/cli/commands/sync.js +40 -9
- package/dist/cli/commands/sync.js.map +1 -1
- package/dist/cli/commands/update.d.ts +8 -0
- package/dist/cli/commands/update.js +155 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/index.js +114 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/scaffolding.d.ts +10 -0
- package/dist/cli/scaffolding.js +302 -0
- package/dist/cli/scaffolding.js.map +1 -0
- package/dist/cli/setup-wizard.d.ts +30 -0
- package/dist/cli/setup-wizard.js +244 -0
- package/dist/cli/setup-wizard.js.map +1 -0
- package/dist/cli/sync-review-interactive.d.ts +31 -0
- package/dist/cli/sync-review-interactive.js +393 -0
- package/dist/cli/sync-review-interactive.js.map +1 -0
- package/dist/cli/theme.d.ts +31 -0
- package/dist/cli/theme.js +116 -0
- package/dist/cli/theme.js.map +1 -0
- package/dist/core/graph.d.ts +16 -9
- package/dist/core/graph.js +263 -145
- package/dist/core/graph.js.map +1 -1
- package/dist/core/migration-runner.d.ts +42 -0
- package/dist/core/migration-runner.js +232 -0
- package/dist/core/migration-runner.js.map +1 -0
- package/dist/core/migration-types.d.ts +101 -0
- package/dist/core/migration-types.js +21 -0
- package/dist/core/migration-types.js.map +1 -0
- package/dist/core/migrations/20260219-formalize-memory-location.d.ts +2 -0
- package/dist/core/migrations/20260219-formalize-memory-location.js +35 -0
- package/dist/core/migrations/20260219-formalize-memory-location.js.map +1 -0
- package/dist/core/migrations/20260220-add-workspace-metadata.d.ts +12 -0
- package/dist/core/migrations/20260220-add-workspace-metadata.js +65 -0
- package/dist/core/migrations/20260220-add-workspace-metadata.js.map +1 -0
- package/dist/core/migrations/20260220-add-workspace-readme.d.ts +11 -0
- package/dist/core/migrations/20260220-add-workspace-readme.js +82 -0
- package/dist/core/migrations/20260220-add-workspace-readme.js.map +1 -0
- package/dist/core/migrations/20260220-migrate-yaml-to-json.d.ts +9 -0
- package/dist/core/migrations/20260220-migrate-yaml-to-json.js +64 -0
- package/dist/core/migrations/20260220-migrate-yaml-to-json.js.map +1 -0
- package/dist/core/migrations/index.d.ts +11 -0
- package/dist/core/migrations/index.js +23 -0
- package/dist/core/migrations/index.js.map +1 -0
- package/dist/core/schema-registry.d.ts +36 -0
- package/dist/core/schema-registry.js +161 -0
- package/dist/core/schema-registry.js.map +1 -0
- package/dist/core/types.d.ts +242 -3
- package/dist/core/types.js +21 -2
- package/dist/core/types.js.map +1 -1
- package/dist/core/user-config.d.ts +16 -0
- package/dist/core/user-config.js +8 -0
- package/dist/core/user-config.js.map +1 -1
- package/dist/core/validation.d.ts +973 -32
- package/dist/core/validation.js +163 -4
- package/dist/core/validation.js.map +1 -1
- package/dist/core/workspace-manager.d.ts +26 -2
- package/dist/core/workspace-manager.js +113 -15
- package/dist/core/workspace-manager.js.map +1 -1
- package/dist/core/workspace.d.ts +20 -11
- package/dist/core/workspace.js +123 -34
- package/dist/core/workspace.js.map +1 -1
- package/dist/mcp/connector-manager.d.ts +65 -0
- package/dist/mcp/connector-manager.js +223 -0
- package/dist/mcp/connector-manager.js.map +1 -0
- package/dist/mcp/connectors/asana.d.ts +2 -0
- package/dist/mcp/connectors/asana.js +20 -0
- package/dist/mcp/connectors/asana.js.map +1 -0
- package/dist/mcp/connectors/definitions.d.ts +45 -0
- package/dist/mcp/connectors/definitions.js +32 -0
- package/dist/mcp/connectors/definitions.js.map +1 -0
- package/dist/mcp/connectors/figma.d.ts +5 -0
- package/dist/mcp/connectors/figma.js +21 -0
- package/dist/mcp/connectors/figma.js.map +1 -0
- package/dist/mcp/connectors/gdrive.d.ts +2 -0
- package/dist/mcp/connectors/gdrive.js +20 -0
- package/dist/mcp/connectors/gdrive.js.map +1 -0
- package/dist/mcp/connectors/granola.d.ts +2 -0
- package/dist/mcp/connectors/granola.js +12 -0
- package/dist/mcp/connectors/granola.js.map +1 -0
- package/dist/mcp/connectors/linear.d.ts +2 -0
- package/dist/mcp/connectors/linear.js +19 -0
- package/dist/mcp/connectors/linear.js.map +1 -0
- package/dist/mcp/connectors/obsidian.d.ts +2 -0
- package/dist/mcp/connectors/obsidian.js +19 -0
- package/dist/mcp/connectors/obsidian.js.map +1 -0
- package/dist/mcp/connectors/pipedrive.d.ts +2 -0
- package/dist/mcp/connectors/pipedrive.js +20 -0
- package/dist/mcp/connectors/pipedrive.js.map +1 -0
- package/dist/mcp/connectors/slack.d.ts +2 -0
- package/dist/mcp/connectors/slack.js +21 -0
- package/dist/mcp/connectors/slack.js.map +1 -0
- package/dist/mcp/oauth-provider.d.ts +41 -0
- package/dist/mcp/oauth-provider.js +160 -0
- package/dist/mcp/oauth-provider.js.map +1 -0
- package/dist/mcp/server.d.ts +11 -0
- package/dist/mcp/server.js +28 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +14 -0
- package/dist/mcp/tools.js +172 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/server/index.js +17 -4
- package/dist/server/index.js.map +1 -1
- package/dist/server/plugin-loader.d.ts +15 -0
- package/dist/server/plugin-loader.js +68 -2
- package/dist/server/plugin-loader.js.map +1 -1
- package/dist/server/routes/graph-api.js +1 -1
- package/dist/server/routes/graph-api.js.map +1 -1
- package/dist/server/routes/webhook.js +33 -0
- package/dist/server/routes/webhook.js.map +1 -1
- package/dist/services/github-provisioner.d.ts +9 -3
- package/dist/services/github-provisioner.js +46 -8
- package/dist/services/github-provisioner.js.map +1 -1
- package/dist/services/lint-service.d.ts +27 -0
- package/dist/services/lint-service.js +83 -0
- package/dist/services/lint-service.js.map +1 -0
- package/dist/services/markdown.d.ts +9 -0
- package/dist/services/markdown.js +26 -5
- package/dist/services/markdown.js.map +1 -1
- package/dist/services/memory-service.d.ts +1 -2
- package/dist/services/memory-service.js +5 -4
- package/dist/services/memory-service.js.map +1 -1
- package/dist/services/orphan-service.d.ts +31 -0
- package/dist/services/orphan-service.js +100 -0
- package/dist/services/orphan-service.js.map +1 -0
- package/dist/services/sync/commit.d.ts +58 -0
- package/dist/services/sync/commit.js +350 -0
- package/dist/services/sync/commit.js.map +1 -0
- package/dist/services/sync/context-index.d.ts +69 -0
- package/dist/services/sync/context-index.js +280 -0
- package/dist/services/sync/context-index.js.map +1 -0
- package/dist/services/sync/derive.d.ts +34 -0
- package/dist/services/sync/derive.js +164 -0
- package/dist/services/sync/derive.js.map +1 -0
- package/dist/services/sync/enrichment-state.d.ts +31 -0
- package/dist/services/sync/enrichment-state.js +63 -0
- package/dist/services/sync/enrichment-state.js.map +1 -0
- package/dist/services/sync/enrichment.d.ts +25 -0
- package/dist/services/sync/enrichment.js +121 -0
- package/dist/services/sync/enrichment.js.map +1 -0
- package/dist/services/sync/frontmatter-extractor.d.ts +40 -0
- package/dist/services/sync/frontmatter-extractor.js +273 -0
- package/dist/services/sync/frontmatter-extractor.js.map +1 -0
- package/dist/services/sync/graph-match-state.d.ts +33 -0
- package/dist/services/sync/graph-match-state.js +61 -0
- package/dist/services/sync/graph-match-state.js.map +1 -0
- package/dist/services/sync/graph-match.d.ts +53 -0
- package/dist/services/sync/graph-match.js +316 -0
- package/dist/services/sync/graph-match.js.map +1 -0
- package/dist/services/sync/graphrag-client.d.ts +43 -0
- package/dist/services/sync/graphrag-client.js +94 -0
- package/dist/services/sync/graphrag-client.js.map +1 -0
- package/dist/services/sync/graphrag-config.d.ts +16 -0
- package/dist/services/sync/graphrag-config.js +39 -0
- package/dist/services/sync/graphrag-config.js.map +1 -0
- package/dist/services/sync/graphrag-context.d.ts +14 -0
- package/dist/services/sync/graphrag-context.js +109 -0
- package/dist/services/sync/graphrag-context.js.map +1 -0
- package/dist/services/sync/graphrag-indexer.d.ts +30 -0
- package/dist/services/sync/graphrag-indexer.js +358 -0
- package/dist/services/sync/graphrag-indexer.js.map +1 -0
- package/dist/services/sync/llm.d.ts +32 -0
- package/dist/services/sync/llm.js +115 -0
- package/dist/services/sync/llm.js.map +1 -0
- package/dist/services/sync/mcp-client.d.ts +59 -0
- package/dist/services/sync/mcp-client.js +285 -0
- package/dist/services/sync/mcp-client.js.map +1 -0
- package/dist/services/sync/model-factory.d.ts +10 -0
- package/dist/services/sync/model-factory.js +24 -0
- package/dist/services/sync/model-factory.js.map +1 -0
- package/dist/services/sync/name-quality.d.ts +31 -0
- package/dist/services/sync/name-quality.js +60 -0
- package/dist/services/sync/name-quality.js.map +1 -0
- package/dist/services/sync/output-schemas.d.ts +92 -0
- package/dist/services/sync/output-schemas.js +43 -0
- package/dist/services/sync/output-schemas.js.map +1 -0
- package/dist/services/sync/prompts.d.ts +19 -0
- package/dist/services/sync/prompts.js +128 -0
- package/dist/services/sync/prompts.js.map +1 -0
- package/dist/services/sync/reconciler.d.ts +48 -0
- package/dist/services/sync/reconciler.js +295 -0
- package/dist/services/sync/reconciler.js.map +1 -0
- package/dist/services/sync/source-config.d.ts +45 -0
- package/dist/services/sync/source-config.js +208 -0
- package/dist/services/sync/source-config.js.map +1 -0
- package/dist/services/sync/source-definitions/asana.d.ts +15 -0
- package/dist/services/sync/source-definitions/asana.js +48 -0
- package/dist/services/sync/source-definitions/asana.js.map +1 -0
- package/dist/services/sync/source-definitions/definitions.d.ts +21 -0
- package/dist/services/sync/source-definitions/definitions.js +26 -0
- package/dist/services/sync/source-definitions/definitions.js.map +1 -0
- package/dist/services/sync/source-definitions/gdrive.d.ts +16 -0
- package/dist/services/sync/source-definitions/gdrive.js +68 -0
- package/dist/services/sync/source-definitions/gdrive.js.map +1 -0
- package/dist/services/sync/source-definitions/granola.d.ts +2 -0
- package/dist/services/sync/source-definitions/granola.js +28 -0
- package/dist/services/sync/source-definitions/granola.js.map +1 -0
- package/dist/services/sync/source-definitions/linear.d.ts +2 -0
- package/dist/services/sync/source-definitions/linear.js +60 -0
- package/dist/services/sync/source-definitions/linear.js.map +1 -0
- package/dist/services/sync/source-definitions/obsidian.d.ts +2 -0
- package/dist/services/sync/source-definitions/obsidian.js +55 -0
- package/dist/services/sync/source-definitions/obsidian.js.map +1 -0
- package/dist/services/sync/source-definitions/pipedrive.d.ts +2 -0
- package/dist/services/sync/source-definitions/pipedrive.js +52 -0
- package/dist/services/sync/source-definitions/pipedrive.js.map +1 -0
- package/dist/services/sync/staging.d.ts +53 -0
- package/dist/services/sync/staging.js +131 -0
- package/dist/services/sync/staging.js.map +1 -0
- package/dist/services/sync/structured-extractor.d.ts +49 -0
- package/dist/services/sync/structured-extractor.js +344 -0
- package/dist/services/sync/structured-extractor.js.map +1 -0
- package/dist/services/sync/sync-runner.d.ts +32 -0
- package/dist/services/sync/sync-runner.js +195 -0
- package/dist/services/sync/sync-runner.js.map +1 -0
- package/dist/services/sync/sync-state.d.ts +43 -0
- package/dist/services/sync/sync-state.js +154 -0
- package/dist/services/sync/sync-state.js.map +1 -0
- package/dist/services/sync/types.d.ts +203 -0
- package/dist/services/sync/types.js +8 -0
- package/dist/services/sync/types.js.map +1 -0
- package/dist/services/sync/unstructured-extractor.d.ts +29 -0
- package/dist/services/sync/unstructured-extractor.js +197 -0
- package/dist/services/sync/unstructured-extractor.js.map +1 -0
- package/dist/services/vector-service.d.ts +88 -0
- package/dist/services/vector-service.js +322 -0
- package/dist/services/vector-service.js.map +1 -0
- package/dist/utils/git.d.ts +26 -4
- package/dist/utils/git.js +55 -7
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/merge-resolver.d.ts +34 -0
- package/dist/utils/merge-resolver.js +201 -0
- package/dist/utils/merge-resolver.js.map +1 -0
- package/dist/utils/preflight.d.ts +2 -1
- package/dist/utils/preflight.js +8 -1
- package/dist/utils/preflight.js.map +1 -1
- package/dist/utils/version-checker.d.ts +23 -0
- package/dist/utils/version-checker.js +116 -0
- package/dist/utils/version-checker.js.map +1 -0
- package/dist/utils/workspace-config.d.ts +8 -0
- package/dist/utils/workspace-config.js +22 -0
- package/dist/utils/workspace-config.js.map +1 -0
- package/package.json +24 -11
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GraphRAG context builder — synchronous graph traversal.
|
|
3
|
+
*
|
|
4
|
+
* Scans source content for known node names, collects neighbors
|
|
5
|
+
* and edge descriptions, and formats as markdown context sections.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Find entities mentioned in source content and collect their graph neighbors.
|
|
9
|
+
*/
|
|
10
|
+
export function getEntityContext(graph, entityName, entityType, sourceContent) {
|
|
11
|
+
if (graph.order === 0) {
|
|
12
|
+
return { formattedContext: '' };
|
|
13
|
+
}
|
|
14
|
+
const contentLower = sourceContent.toLowerCase();
|
|
15
|
+
// Collect all node names that appear in the source content
|
|
16
|
+
const matchedNodes = [];
|
|
17
|
+
graph.forEachNode((node, attrs) => {
|
|
18
|
+
const name = attrs.name ?? node;
|
|
19
|
+
if (name.length < 3)
|
|
20
|
+
return; // skip very short names to avoid false matches
|
|
21
|
+
if (contentLower.includes(name.toLowerCase())) {
|
|
22
|
+
matchedNodes.push(node);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
// Also check for the explicit entity name
|
|
26
|
+
const entityNodeKey = findNodeByName(graph, entityName);
|
|
27
|
+
if (entityNodeKey && !matchedNodes.includes(entityNodeKey)) {
|
|
28
|
+
matchedNodes.push(entityNodeKey);
|
|
29
|
+
}
|
|
30
|
+
if (matchedNodes.length === 0) {
|
|
31
|
+
return { formattedContext: '' };
|
|
32
|
+
}
|
|
33
|
+
// Collect related entities and relationships
|
|
34
|
+
const relatedEntities = new Map();
|
|
35
|
+
const relationships = [];
|
|
36
|
+
for (const nodeKey of matchedNodes) {
|
|
37
|
+
const nodeAttrs = graph.getNodeAttributes(nodeKey);
|
|
38
|
+
// Add the matched node itself as context
|
|
39
|
+
relatedEntities.set(nodeKey, {
|
|
40
|
+
name: nodeAttrs.name ?? nodeKey,
|
|
41
|
+
type: nodeAttrs.type ?? 'unknown',
|
|
42
|
+
description: nodeAttrs.description ?? '',
|
|
43
|
+
});
|
|
44
|
+
// Traverse neighbors
|
|
45
|
+
graph.forEachNeighbor(nodeKey, (neighbor, neighborAttrs) => {
|
|
46
|
+
if (!relatedEntities.has(neighbor)) {
|
|
47
|
+
relatedEntities.set(neighbor, {
|
|
48
|
+
name: neighborAttrs.name ?? neighbor,
|
|
49
|
+
type: neighborAttrs.type ?? 'unknown',
|
|
50
|
+
description: neighborAttrs.description ?? '',
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
// Collect edges from this node
|
|
55
|
+
graph.forEachEdge(nodeKey, (_edge, edgeAttrs, source, target) => {
|
|
56
|
+
const sourceAttrs = graph.getNodeAttributes(source);
|
|
57
|
+
const targetAttrs = graph.getNodeAttributes(target);
|
|
58
|
+
relationships.push({
|
|
59
|
+
source: sourceAttrs.name ?? source,
|
|
60
|
+
target: targetAttrs.name ?? target,
|
|
61
|
+
description: edgeAttrs.description ?? '',
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
// Format as markdown
|
|
66
|
+
const sections = [];
|
|
67
|
+
if (relatedEntities.size > 0) {
|
|
68
|
+
const lines = ['### Related Entities'];
|
|
69
|
+
for (const [, entity] of relatedEntities) {
|
|
70
|
+
const desc = entity.description ? ` — ${entity.description}` : '';
|
|
71
|
+
lines.push(`- **${entity.name}** (${entity.type})${desc}`);
|
|
72
|
+
}
|
|
73
|
+
sections.push(lines.join('\n'));
|
|
74
|
+
}
|
|
75
|
+
if (relationships.length > 0) {
|
|
76
|
+
// Deduplicate relationships
|
|
77
|
+
const seen = new Set();
|
|
78
|
+
const lines = ['### Relationships'];
|
|
79
|
+
for (const rel of relationships) {
|
|
80
|
+
const key = `${rel.source}→${rel.target}`;
|
|
81
|
+
if (seen.has(key))
|
|
82
|
+
continue;
|
|
83
|
+
seen.add(key);
|
|
84
|
+
const desc = rel.description ? `: ${rel.description}` : '';
|
|
85
|
+
lines.push(`- ${rel.source} → ${rel.target}${desc}`);
|
|
86
|
+
}
|
|
87
|
+
sections.push(lines.join('\n'));
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
formattedContext: sections.join('\n\n'),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Look up a node by its name attribute (case-insensitive).
|
|
95
|
+
*/
|
|
96
|
+
function findNodeByName(graph, name) {
|
|
97
|
+
const nameLower = name.toLowerCase();
|
|
98
|
+
let found;
|
|
99
|
+
graph.forEachNode((node, attrs) => {
|
|
100
|
+
if (found)
|
|
101
|
+
return;
|
|
102
|
+
const nodeName = attrs.name ?? node;
|
|
103
|
+
if (nodeName.toLowerCase() === nameLower) {
|
|
104
|
+
found = node;
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return found;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=graphrag-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphrag-context.js","sourceRoot":"","sources":["../../../src/services/sync/graphrag-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GraphRAG Indexer — batch LLM extraction into a Graphology graph.
|
|
3
|
+
*
|
|
4
|
+
* Reads markdown files from a source directory, batches them into groups,
|
|
5
|
+
* sends each batch to the LLM for entity/relationship extraction, and
|
|
6
|
+
* builds a Graphology graph serialized to disk.
|
|
7
|
+
*/
|
|
8
|
+
import type { GraphRAGConfig } from './graphrag-config.js';
|
|
9
|
+
interface IndexedFile {
|
|
10
|
+
path: string;
|
|
11
|
+
relativePath: string;
|
|
12
|
+
content: string;
|
|
13
|
+
}
|
|
14
|
+
export interface IndexResult {
|
|
15
|
+
files_processed: number;
|
|
16
|
+
entities_extracted: number;
|
|
17
|
+
relationships_extracted: number;
|
|
18
|
+
graph_path: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Index a directory of markdown files into a Graphology knowledge graph.
|
|
22
|
+
*/
|
|
23
|
+
export declare function indexIntoGraphRAG(options: {
|
|
24
|
+
sourcePath: string;
|
|
25
|
+
config: GraphRAGConfig;
|
|
26
|
+
incremental?: boolean;
|
|
27
|
+
onProgress?: (msg: string) => void;
|
|
28
|
+
}): Promise<IndexResult>;
|
|
29
|
+
export declare function collectMarkdownFiles(dirPath: string): IndexedFile[];
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GraphRAG Indexer — batch LLM extraction into a Graphology graph.
|
|
3
|
+
*
|
|
4
|
+
* Reads markdown files from a source directory, batches them into groups,
|
|
5
|
+
* sends each batch to the LLM for entity/relationship extraction, and
|
|
6
|
+
* builds a Graphology graph serialized to disk.
|
|
7
|
+
*/
|
|
8
|
+
import Graph from 'graphology';
|
|
9
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from 'fs';
|
|
10
|
+
import { join, dirname, relative, extname } from 'path';
|
|
11
|
+
import { generateText } from 'ai';
|
|
12
|
+
import { z } from 'zod';
|
|
13
|
+
import { createModel } from './model-factory.js';
|
|
14
|
+
import { loadUserConfig, getAnthropicCredential } from '../../core/user-config.js';
|
|
15
|
+
import { saveGraphRAGConfig } from './graphrag-config.js';
|
|
16
|
+
const BATCH_SIZE = 12;
|
|
17
|
+
const MAX_CHARS_PER_BATCH = 40_000; // ~10k tokens
|
|
18
|
+
const BATCH_CONCURRENCY = 5;
|
|
19
|
+
const DEFAULT_INDEXING_MODEL = 'claude-haiku-4-5-20251001';
|
|
20
|
+
const DEFAULT_PROVIDER = 'anthropic';
|
|
21
|
+
// ── Zod schemas for structured LLM output ───────────────────────────────────
|
|
22
|
+
const EntitySchema = z.object({
|
|
23
|
+
name: z.string().describe('Canonical name of the entity'),
|
|
24
|
+
type: z.string().describe('Entity type: person, client, project, meeting, process, deliverable, tool, concept, or other'),
|
|
25
|
+
description: z.string().describe('One-sentence description'),
|
|
26
|
+
sources: z.array(z.string()).describe('Which document filenames mention this entity'),
|
|
27
|
+
});
|
|
28
|
+
const RelationshipSchema = z.object({
|
|
29
|
+
source: z.string().describe('Source entity name (must match an entity name exactly)'),
|
|
30
|
+
target: z.string().describe('Target entity name (must match an entity name exactly)'),
|
|
31
|
+
description: z.string().describe('Description of the relationship'),
|
|
32
|
+
sources: z.array(z.string()).describe('Which document filenames evidence this relationship'),
|
|
33
|
+
});
|
|
34
|
+
const ExtractionResultSchema = z.object({
|
|
35
|
+
entities: z.array(EntitySchema),
|
|
36
|
+
relationships: z.array(RelationshipSchema).default([]),
|
|
37
|
+
});
|
|
38
|
+
const JSON_INSTRUCTION = `
|
|
39
|
+
|
|
40
|
+
Respond with ONLY a JSON object — no markdown fences, no commentary. Use this exact shape:
|
|
41
|
+
{
|
|
42
|
+
"entities": [{ "name": "...", "type": "person|client|project|meeting|process|deliverable|tool|concept", "description": "...", "sources": ["filename.md"] }],
|
|
43
|
+
"relationships": [{ "source": "Entity Name", "target": "Entity Name", "description": "...", "sources": ["filename.md"] }]
|
|
44
|
+
}`;
|
|
45
|
+
// ── Public API ──────────────────────────────────────────────────────────────
|
|
46
|
+
/**
|
|
47
|
+
* Index a directory of markdown files into a Graphology knowledge graph.
|
|
48
|
+
*/
|
|
49
|
+
export async function indexIntoGraphRAG(options) {
|
|
50
|
+
const { sourcePath, config, onProgress } = options;
|
|
51
|
+
const log = onProgress ?? (() => { });
|
|
52
|
+
// Collect markdown files
|
|
53
|
+
log('Scanning for markdown files...');
|
|
54
|
+
const files = collectMarkdownFiles(sourcePath);
|
|
55
|
+
log(`Found ${files.length} markdown files`);
|
|
56
|
+
if (files.length === 0) {
|
|
57
|
+
return { files_processed: 0, entities_extracted: 0, relationships_extracted: 0, graph_path: config.graph_path };
|
|
58
|
+
}
|
|
59
|
+
// Load existing graph for incremental, or start fresh
|
|
60
|
+
const graph = new Graph();
|
|
61
|
+
if (options.incremental && existsSync(config.graph_path)) {
|
|
62
|
+
try {
|
|
63
|
+
const data = JSON.parse(readFileSync(config.graph_path, 'utf-8'));
|
|
64
|
+
graph.import(data);
|
|
65
|
+
log(`Loaded existing graph: ${graph.order} nodes, ${graph.size} edges`);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
log('Could not load existing graph, starting fresh');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Batch files
|
|
72
|
+
const batches = batchFiles(files);
|
|
73
|
+
log(`Processing ${batches.length} batches...`);
|
|
74
|
+
let totalEntities = 0;
|
|
75
|
+
let totalRelationships = 0;
|
|
76
|
+
// Resolve model config
|
|
77
|
+
const userConfig = loadUserConfig();
|
|
78
|
+
const provider = userConfig.model_provider ?? DEFAULT_PROVIDER;
|
|
79
|
+
const modelId = DEFAULT_INDEXING_MODEL; // Always use Haiku for bulk indexing — 12x cheaper than Sonnet
|
|
80
|
+
const apiKey = getAnthropicCredential(userConfig) ?? undefined;
|
|
81
|
+
const llmModel = createModel(provider, modelId, apiKey);
|
|
82
|
+
log(`Using model: ${modelId}`);
|
|
83
|
+
const failedBatches = [];
|
|
84
|
+
// Process batches concurrently in groups of 3
|
|
85
|
+
for (let i = 0; i < batches.length; i += BATCH_CONCURRENCY) {
|
|
86
|
+
const group = batches.slice(i, i + BATCH_CONCURRENCY);
|
|
87
|
+
const groupStart = i;
|
|
88
|
+
const results = await Promise.all(group.map(async (batch, j) => {
|
|
89
|
+
const batchNum = groupStart + j + 1;
|
|
90
|
+
log(` Batch ${batchNum}/${batches.length} (${batch.length} files)...`);
|
|
91
|
+
return processBatch(llmModel, batch, batchNum, batches.length, log);
|
|
92
|
+
}));
|
|
93
|
+
// Merge successes, queue failures for retry
|
|
94
|
+
for (let j = 0; j < results.length; j++) {
|
|
95
|
+
const extraction = results[j];
|
|
96
|
+
if (!extraction) {
|
|
97
|
+
failedBatches.push({ batchNum: groupStart + j + 1, batch: group[j] });
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
mergeExtraction(graph, extraction);
|
|
101
|
+
totalEntities += extraction.entities.length;
|
|
102
|
+
totalRelationships += extraction.relationships.length;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Retry failed batches sequentially (no concurrency pressure)
|
|
106
|
+
if (failedBatches.length > 0) {
|
|
107
|
+
log(`\nRetrying ${failedBatches.length} failed batches sequentially...`);
|
|
108
|
+
for (const { batchNum, batch } of failedBatches) {
|
|
109
|
+
log(` Retry batch ${batchNum} (${batch.length} files)...`);
|
|
110
|
+
// Small delay to avoid rate limit
|
|
111
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
112
|
+
const extraction = await processBatch(llmModel, batch, batchNum, batches.length, log);
|
|
113
|
+
if (extraction) {
|
|
114
|
+
mergeExtraction(graph, extraction);
|
|
115
|
+
totalEntities += extraction.entities.length;
|
|
116
|
+
totalRelationships += extraction.relationships.length;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function mergeExtraction(g, extraction) {
|
|
121
|
+
for (const entity of extraction.entities) {
|
|
122
|
+
const nodeKey = entity.name.toLowerCase().replace(/\s+/g, '-');
|
|
123
|
+
g.mergeNode(nodeKey, {
|
|
124
|
+
name: entity.name,
|
|
125
|
+
type: entity.type,
|
|
126
|
+
description: entity.description,
|
|
127
|
+
sources: JSON.stringify(entity.sources),
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
for (const rel of extraction.relationships) {
|
|
131
|
+
const sourceKey = rel.source.toLowerCase().replace(/\s+/g, '-');
|
|
132
|
+
const targetKey = rel.target.toLowerCase().replace(/\s+/g, '-');
|
|
133
|
+
if (g.hasNode(sourceKey) && g.hasNode(targetKey)) {
|
|
134
|
+
g.mergeEdge(sourceKey, targetKey, {
|
|
135
|
+
description: rel.description,
|
|
136
|
+
sources: JSON.stringify(rel.sources),
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// Serialize graph to disk
|
|
142
|
+
mkdirSync(dirname(config.graph_path), { recursive: true });
|
|
143
|
+
const serialized = graph.export();
|
|
144
|
+
writeFileSync(config.graph_path, JSON.stringify(serialized, null, 2));
|
|
145
|
+
log(`\nGraph saved: ${graph.order} nodes, ${graph.size} edges → ${config.graph_path}`);
|
|
146
|
+
// Update config
|
|
147
|
+
config.last_indexed = new Date().toISOString();
|
|
148
|
+
config.files_indexed = files.length;
|
|
149
|
+
saveGraphRAGConfig(config);
|
|
150
|
+
return {
|
|
151
|
+
files_processed: files.length,
|
|
152
|
+
entities_extracted: totalEntities,
|
|
153
|
+
relationships_extracted: totalRelationships,
|
|
154
|
+
graph_path: config.graph_path,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
// ── Single batch processor ──────────────────────────────────────────────────
|
|
158
|
+
async function processBatch(llmModel, batch, batchNum, totalBatches, log) {
|
|
159
|
+
try {
|
|
160
|
+
// Use plain text mode — no structured output wrapper.
|
|
161
|
+
// Structured output (tool use) causes frequent "No output generated" errors.
|
|
162
|
+
const prompt = buildBatchPrompt(batch) + JSON_INSTRUCTION;
|
|
163
|
+
const result = await generateText({
|
|
164
|
+
model: llmModel,
|
|
165
|
+
prompt,
|
|
166
|
+
maxOutputTokens: 8192,
|
|
167
|
+
maxRetries: 0,
|
|
168
|
+
});
|
|
169
|
+
const raw = result.text ?? '';
|
|
170
|
+
if (!raw) {
|
|
171
|
+
log(` Batch ${batchNum}: empty response`);
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
// Extract JSON from the response text
|
|
175
|
+
const jsonMatch = raw.match(/\{[\s\S]*"entities"[\s\S]*/);
|
|
176
|
+
if (!jsonMatch) {
|
|
177
|
+
log(` Batch ${batchNum}: no JSON found (rawLen: ${raw.length})`);
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
// Repair truncated JSON — close unclosed arrays/objects
|
|
181
|
+
let jsonStr = jsonMatch[0];
|
|
182
|
+
try {
|
|
183
|
+
JSON.parse(jsonStr);
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
jsonStr = repairTruncatedJSON(jsonStr);
|
|
187
|
+
}
|
|
188
|
+
// Sanitize before Zod parsing — handle truncated objects
|
|
189
|
+
const rawObj = JSON.parse(jsonStr);
|
|
190
|
+
if (Array.isArray(rawObj.relationships)) {
|
|
191
|
+
rawObj.relationships = rawObj.relationships.filter((r) => r && typeof r.source === 'string' && typeof r.target === 'string');
|
|
192
|
+
}
|
|
193
|
+
const extraction = ExtractionResultSchema.parse(rawObj);
|
|
194
|
+
log(` Batch ${batchNum}: ${extraction.entities.length} entities, ${extraction.relationships.length} relationships`);
|
|
195
|
+
return extraction;
|
|
196
|
+
}
|
|
197
|
+
catch (err) {
|
|
198
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
199
|
+
log(` Batch ${batchNum}: error — ${msg}`);
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// ── JSON repair ─────────────────────────────────────────────────────────────
|
|
204
|
+
/**
|
|
205
|
+
* Attempt to repair truncated JSON by removing the last incomplete element
|
|
206
|
+
* and closing unclosed arrays/objects.
|
|
207
|
+
*/
|
|
208
|
+
function repairTruncatedJSON(str) {
|
|
209
|
+
// Remove trailing incomplete object — find the last complete }, then close arrays/root
|
|
210
|
+
let s = str;
|
|
211
|
+
// Strip any trailing partial string/value after the last complete element
|
|
212
|
+
// Find the last complete JSON object boundary ("},")
|
|
213
|
+
const lastCompleteObj = s.lastIndexOf('},');
|
|
214
|
+
const lastCompleteArr = s.lastIndexOf('],');
|
|
215
|
+
const cutPoint = Math.max(lastCompleteObj, lastCompleteArr);
|
|
216
|
+
if (cutPoint > 0) {
|
|
217
|
+
s = s.slice(0, cutPoint + 1); // keep the } or ]
|
|
218
|
+
}
|
|
219
|
+
// Count unclosed brackets
|
|
220
|
+
let openBraces = 0;
|
|
221
|
+
let openBrackets = 0;
|
|
222
|
+
let inString = false;
|
|
223
|
+
let escape = false;
|
|
224
|
+
for (const ch of s) {
|
|
225
|
+
if (escape) {
|
|
226
|
+
escape = false;
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (ch === '\\' && inString) {
|
|
230
|
+
escape = true;
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (ch === '"') {
|
|
234
|
+
inString = !inString;
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
if (inString)
|
|
238
|
+
continue;
|
|
239
|
+
if (ch === '{')
|
|
240
|
+
openBraces++;
|
|
241
|
+
if (ch === '}')
|
|
242
|
+
openBraces--;
|
|
243
|
+
if (ch === '[')
|
|
244
|
+
openBrackets++;
|
|
245
|
+
if (ch === ']')
|
|
246
|
+
openBrackets--;
|
|
247
|
+
}
|
|
248
|
+
// Close unclosed brackets
|
|
249
|
+
while (openBrackets > 0) {
|
|
250
|
+
s += ']';
|
|
251
|
+
openBrackets--;
|
|
252
|
+
}
|
|
253
|
+
while (openBraces > 0) {
|
|
254
|
+
s += '}';
|
|
255
|
+
openBraces--;
|
|
256
|
+
}
|
|
257
|
+
return s;
|
|
258
|
+
}
|
|
259
|
+
// ── File collection ─────────────────────────────────────────────────────────
|
|
260
|
+
export function collectMarkdownFiles(dirPath) {
|
|
261
|
+
const files = [];
|
|
262
|
+
walkDir(dirPath, dirPath, files);
|
|
263
|
+
return files;
|
|
264
|
+
}
|
|
265
|
+
function walkDir(basePath, currentPath, files) {
|
|
266
|
+
let entries;
|
|
267
|
+
try {
|
|
268
|
+
entries = readdirSync(currentPath);
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
for (const entry of entries) {
|
|
274
|
+
// Skip hidden dirs and common noise
|
|
275
|
+
if (entry.startsWith('.') || entry === 'node_modules')
|
|
276
|
+
continue;
|
|
277
|
+
const fullPath = join(currentPath, entry);
|
|
278
|
+
let stat;
|
|
279
|
+
try {
|
|
280
|
+
stat = statSync(fullPath);
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
if (stat.isDirectory()) {
|
|
286
|
+
walkDir(basePath, fullPath, files);
|
|
287
|
+
}
|
|
288
|
+
else if (extname(entry) === '.md') {
|
|
289
|
+
try {
|
|
290
|
+
const content = readFileSync(fullPath, 'utf-8');
|
|
291
|
+
if (content.length > 0) {
|
|
292
|
+
files.push({
|
|
293
|
+
path: fullPath,
|
|
294
|
+
relativePath: relative(basePath, fullPath),
|
|
295
|
+
content,
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
// skip unreadable files
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
// ── Batching ────────────────────────────────────────────────────────────────
|
|
306
|
+
function batchFiles(files) {
|
|
307
|
+
const batches = [];
|
|
308
|
+
let currentBatch = [];
|
|
309
|
+
let currentChars = 0;
|
|
310
|
+
for (const file of files) {
|
|
311
|
+
const fileChars = file.content.length;
|
|
312
|
+
// Start a new batch if adding this file would exceed limits
|
|
313
|
+
if (currentBatch.length >= BATCH_SIZE || (currentChars + fileChars > MAX_CHARS_PER_BATCH && currentBatch.length > 0)) {
|
|
314
|
+
batches.push(currentBatch);
|
|
315
|
+
currentBatch = [];
|
|
316
|
+
currentChars = 0;
|
|
317
|
+
}
|
|
318
|
+
// Truncate very large files
|
|
319
|
+
const truncated = file.content.length > 8000
|
|
320
|
+
? file.content.slice(0, 8000) + '\n\n[... truncated]'
|
|
321
|
+
: file.content;
|
|
322
|
+
currentBatch.push({ ...file, content: truncated });
|
|
323
|
+
currentChars += truncated.length;
|
|
324
|
+
}
|
|
325
|
+
if (currentBatch.length > 0) {
|
|
326
|
+
batches.push(currentBatch);
|
|
327
|
+
}
|
|
328
|
+
return batches;
|
|
329
|
+
}
|
|
330
|
+
// ── Prompt ──────────────────────────────────────────────────────────────────
|
|
331
|
+
function buildBatchPrompt(files) {
|
|
332
|
+
const docs = files.map(f => `### [${f.relativePath}]\n${f.content}`).join('\n\n---\n\n');
|
|
333
|
+
return `Extract all named entities and their relationships from these documents.
|
|
334
|
+
|
|
335
|
+
Focus on:
|
|
336
|
+
- People (team members, clients, contacts)
|
|
337
|
+
- Organizations/clients
|
|
338
|
+
- Projects and engagements
|
|
339
|
+
- Meetings and events
|
|
340
|
+
- Processes and workflows
|
|
341
|
+
- Deliverables and artifacts
|
|
342
|
+
- Tools and platforms
|
|
343
|
+
|
|
344
|
+
For each entity, identify:
|
|
345
|
+
- A canonical name (full name preferred, e.g. "Kenton Powell" not "Kenton")
|
|
346
|
+
- Its type (person, client, project, meeting, process, deliverable, tool, concept)
|
|
347
|
+
- A brief one-sentence description
|
|
348
|
+
- Which documents mention it
|
|
349
|
+
|
|
350
|
+
For relationships, capture how entities connect (e.g. "works on", "attended", "delivered to", "uses").
|
|
351
|
+
|
|
352
|
+
## Documents
|
|
353
|
+
|
|
354
|
+
${docs}
|
|
355
|
+
|
|
356
|
+
Extract all entities and relationships you can identify across these documents. Merge duplicate references to the same entity (e.g. "Kenton" and "Kenton Powell" should be one entity).`;
|
|
357
|
+
}
|
|
358
|
+
//# sourceMappingURL=graphrag-indexer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphrag-indexer.js","sourceRoot":"","sources":["../../../src/services/sync/graphrag-indexer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM utilities for the sync pipeline — powered by the Vercel AI SDK.
|
|
3
|
+
*
|
|
4
|
+
* - llmExtract: Structured extraction from unstructured content
|
|
5
|
+
* - llmEnrich: Enrichment with cross-source context
|
|
6
|
+
* - llmGraphMatch: Entity deduplication comparison
|
|
7
|
+
*
|
|
8
|
+
* All three functions use generateText + Output.object() for Zod-validated
|
|
9
|
+
* structured output. Provider is configurable via user config:
|
|
10
|
+
* enrichment_model_id → model_id → 'claude-sonnet-4-5-20250929'
|
|
11
|
+
* enrichment_model_provider → model_provider → 'anthropic'
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Extract structured frontmatter from content using LLM.
|
|
15
|
+
*/
|
|
16
|
+
export declare function llmExtract(content: string, entityType: string, schema: any, graphragContext?: string): Promise<Record<string, any>>;
|
|
17
|
+
/**
|
|
18
|
+
* Enrich an entity with cross-source context using LLM.
|
|
19
|
+
* Returns updated frontmatter and generated content.
|
|
20
|
+
*/
|
|
21
|
+
export declare function llmEnrich(entityData: Record<string, any>, contextBundle: string, entityType: string, schema: any): Promise<{
|
|
22
|
+
frontmatter: Record<string, any>;
|
|
23
|
+
content: string;
|
|
24
|
+
}>;
|
|
25
|
+
/**
|
|
26
|
+
* Ask LLM whether two entities (staged vs existing) are the same real-world entity.
|
|
27
|
+
*/
|
|
28
|
+
export declare function llmGraphMatch(stagedFrontmatter: Record<string, any>, existingFrontmatter: Record<string, any>, entityType: string): Promise<{
|
|
29
|
+
is_same: boolean;
|
|
30
|
+
confidence: number;
|
|
31
|
+
reasoning: string;
|
|
32
|
+
}>;
|