@workglow/knowledge-base 0.1.2 → 0.2.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.
Files changed (33) hide show
  1. package/README.md +166 -0
  2. package/dist/browser.js +321 -25
  3. package/dist/browser.js.map +15 -12
  4. package/dist/bun.js +321 -25
  5. package/dist/bun.js.map +15 -12
  6. package/dist/chunk/ChunkVectorStorageSchema.d.ts +1 -1
  7. package/dist/chunk/ChunkVectorStorageSchema.d.ts.map +1 -1
  8. package/dist/common.d.ts +3 -0
  9. package/dist/common.d.ts.map +1 -1
  10. package/dist/document/Document.d.ts.map +1 -1
  11. package/dist/document/DocumentNode.d.ts +1 -1
  12. package/dist/document/DocumentNode.d.ts.map +1 -1
  13. package/dist/document/DocumentStorageSchema.d.ts +2 -1
  14. package/dist/document/DocumentStorageSchema.d.ts.map +1 -1
  15. package/dist/document/StructuralParser.d.ts +1 -1
  16. package/dist/document/StructuralParser.d.ts.map +1 -1
  17. package/dist/knowledge-base/KnowledgeBase.d.ts +2 -0
  18. package/dist/knowledge-base/KnowledgeBase.d.ts.map +1 -1
  19. package/dist/knowledge-base/KnowledgeBaseRegistry.d.ts +17 -1
  20. package/dist/knowledge-base/KnowledgeBaseRegistry.d.ts.map +1 -1
  21. package/dist/knowledge-base/KnowledgeBaseRepository.d.ts +5 -3
  22. package/dist/knowledge-base/KnowledgeBaseRepository.d.ts.map +1 -1
  23. package/dist/knowledge-base/KnowledgeBaseSchema.d.ts +4 -0
  24. package/dist/knowledge-base/KnowledgeBaseSchema.d.ts.map +1 -1
  25. package/dist/knowledge-base/ScopedTabularStorage.d.ts +46 -0
  26. package/dist/knowledge-base/ScopedTabularStorage.d.ts.map +1 -0
  27. package/dist/knowledge-base/ScopedVectorStorage.d.ts +27 -0
  28. package/dist/knowledge-base/ScopedVectorStorage.d.ts.map +1 -0
  29. package/dist/knowledge-base/SharedTableSchemas.d.ts +93 -0
  30. package/dist/knowledge-base/SharedTableSchemas.d.ts.map +1 -0
  31. package/dist/node.js +321 -25
  32. package/dist/node.js.map +15 -12
  33. package/package.json +10 -5
@@ -1,23 +1,26 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/document/DocumentSchema.ts", "../src/chunk/ChunkSchema.ts", "../src/chunk/ChunkVectorStorageSchema.ts", "../src/document/Document.ts", "../src/knowledge-base/KnowledgeBase.ts", "../src/knowledge-base/KnowledgeBaseSchema.ts", "../src/knowledge-base/KnowledgeBaseRepository.ts", "../src/knowledge-base/InMemoryKnowledgeBaseRepository.ts", "../src/knowledge-base/KnowledgeBaseRegistry.ts", "../src/knowledge-base/createKnowledgeBase.ts", "../src/document/DocumentStorageSchema.ts", "../src/util/DatasetSchema.ts", "../src/document/DocumentNode.ts", "../src/document/StructuralParser.ts"],
3
+ "sources": ["../src/document/DocumentSchema.ts", "../src/chunk/ChunkSchema.ts", "../src/chunk/ChunkVectorStorageSchema.ts", "../src/document/Document.ts", "../src/knowledge-base/KnowledgeBase.ts", "../src/knowledge-base/SharedTableSchemas.ts", "../src/knowledge-base/KnowledgeBaseSchema.ts", "../src/knowledge-base/KnowledgeBaseRepository.ts", "../src/knowledge-base/InMemoryKnowledgeBaseRepository.ts", "../src/knowledge-base/KnowledgeBaseRegistry.ts", "../src/knowledge-base/createKnowledgeBase.ts", "../src/document/DocumentStorageSchema.ts", "../src/knowledge-base/ScopedTabularStorage.ts", "../src/knowledge-base/ScopedVectorStorage.ts", "../src/util/DatasetSchema.ts", "../src/document/DocumentNode.ts", "../src/document/StructuralParser.ts"],
4
4
  "sourcesContent": [
5
5
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DataPortSchema, FromSchema } from \"@workglow/util/schema\";\n\n/**\n * Node kind discriminator for hierarchical document structure\n */\nexport const NodeKind = {\n DOCUMENT: \"document\",\n SECTION: \"section\",\n PARAGRAPH: \"paragraph\",\n SENTENCE: \"sentence\",\n TOPIC: \"topic\",\n} as const;\n\nexport type NodeKind = (typeof NodeKind)[keyof typeof NodeKind];\n\n// =============================================================================\n// Schema Definitions\n// =============================================================================\n\n/**\n * Schema for source range of a node (character offsets)\n */\nexport const NodeRangeSchema = {\n type: \"object\",\n properties: {\n startOffset: {\n type: \"integer\",\n title: \"Start Offset\",\n description: \"Starting character offset\",\n },\n endOffset: {\n type: \"integer\",\n title: \"End Offset\",\n description: \"Ending character offset\",\n },\n },\n required: [\"startOffset\", \"endOffset\"],\n additionalProperties: false,\n} as const satisfies DataPortSchema;\n\nexport type NodeRange = FromSchema<typeof NodeRangeSchema>;\n\n/**\n * Schema for named entity extracted from text\n */\nexport const EntitySchema = {\n type: \"object\",\n properties: {\n text: {\n type: \"string\",\n title: \"Text\",\n description: \"Entity text\",\n },\n type: {\n type: \"string\",\n title: \"Type\",\n description: \"Entity type (e.g., PERSON, ORG, LOC)\",\n },\n score: {\n type: \"number\",\n title: \"Score\",\n description: \"Confidence score\",\n },\n },\n required: [\"text\", \"type\", \"score\"],\n additionalProperties: false,\n} as const satisfies DataPortSchema;\n\nexport type Entity = FromSchema<typeof EntitySchema>;\n\n/**\n * Schema for enrichment data attached to a node\n */\nexport const NodeEnrichmentSchema = {\n type: \"object\",\n properties: {\n summary: {\n type: \"string\",\n title: \"Summary\",\n description: \"Summary of the node content\",\n },\n entities: {\n type: \"array\",\n items: EntitySchema,\n title: \"Entities\",\n description: \"Named entities extracted from the node\",\n },\n keywords: {\n type: \"array\",\n items: { type: \"string\" },\n title: \"Keywords\",\n description: \"Keywords associated with the node\",\n },\n },\n additionalProperties: false,\n} as const satisfies DataPortSchema;\n\nexport type NodeEnrichment = FromSchema<typeof NodeEnrichmentSchema>;\n\n/**\n * Schema for base document node fields (used for runtime validation)\n * Note: Individual node types and DocumentNode union are defined as interfaces\n * below because FromSchema cannot properly infer recursive discriminated unions.\n */\nexport const DocumentNodeBaseSchema = {\n type: \"object\",\n properties: {\n nodeId: {\n type: \"string\",\n title: \"Node ID\",\n description: \"Unique identifier for this node\",\n },\n kind: {\n type: \"string\",\n enum: Object.values(NodeKind),\n title: \"Kind\",\n description: \"Node type discriminator\",\n },\n range: NodeRangeSchema,\n text: {\n type: \"string\",\n title: \"Text\",\n description: \"Text content of the node\",\n },\n enrichment: NodeEnrichmentSchema,\n },\n required: [\"nodeId\", \"kind\", \"range\", \"text\"],\n additionalProperties: true,\n} as const satisfies DataPortSchema;\n\n/**\n * Schema for document node (generic, for runtime validation)\n * This is a simplified schema for task input/output validation.\n * The actual TypeScript types use a proper discriminated union.\n */\nexport const DocumentNodeSchema = {\n type: \"object\",\n title: \"Document Node\",\n description: \"A node in the hierarchical document tree\",\n properties: {\n ...DocumentNodeBaseSchema.properties,\n level: {\n type: \"integer\",\n title: \"Level\",\n description: \"Header level for section nodes\",\n },\n title: {\n type: \"string\",\n title: \"Title\",\n description: \"Section title\",\n },\n children: {\n type: \"array\",\n title: \"Children\",\n description: \"Child nodes\",\n },\n },\n required: [...DocumentNodeBaseSchema.required],\n additionalProperties: false,\n} as const satisfies DataPortSchema;\n\n/**\n * Schema for paragraph node\n */\nexport const ParagraphNodeSchema = {\n type: \"object\",\n properties: {\n ...DocumentNodeBaseSchema.properties,\n kind: {\n type: \"string\",\n const: NodeKind.PARAGRAPH,\n title: \"Kind\",\n description: \"Node type discriminator\",\n },\n },\n required: [...DocumentNodeBaseSchema.required],\n additionalProperties: false,\n} as const satisfies DataPortSchema;\n\n/**\n * Schema for sentence node\n */\nexport const SentenceNodeSchema = {\n type: \"object\",\n properties: {\n ...DocumentNodeBaseSchema.properties,\n kind: {\n type: \"string\",\n const: NodeKind.SENTENCE,\n title: \"Kind\",\n description: \"Node type discriminator\",\n },\n },\n required: [...DocumentNodeBaseSchema.required],\n additionalProperties: false,\n} as const satisfies DataPortSchema;\n\n/**\n * Schema for section node\n */\nexport const SectionNodeSchema = {\n type: \"object\",\n properties: {\n ...DocumentNodeBaseSchema.properties,\n kind: {\n type: \"string\",\n const: NodeKind.SECTION,\n title: \"Kind\",\n description: \"Node type discriminator\",\n },\n level: {\n type: \"integer\",\n minimum: 1,\n maximum: 6,\n title: \"Level\",\n description: \"Header level (1-6 for markdown)\",\n },\n title: {\n type: \"string\",\n title: \"Title\",\n description: \"Section title\",\n },\n children: {\n type: \"array\",\n items: DocumentNodeSchema,\n title: \"Children\",\n description: \"Child nodes\",\n },\n },\n required: [...DocumentNodeBaseSchema.required, \"level\", \"title\", \"children\"],\n additionalProperties: false,\n} as const satisfies DataPortSchema;\n\n/**\n * Schema for topic node\n */\nexport const TopicNodeSchema = {\n type: \"object\",\n properties: {\n ...DocumentNodeBaseSchema.properties,\n kind: {\n type: \"string\",\n const: NodeKind.TOPIC,\n title: \"Kind\",\n description: \"Node type discriminator\",\n },\n children: {\n type: \"array\",\n items: DocumentNodeSchema,\n title: \"Children\",\n description: \"Child nodes\",\n },\n },\n required: [...DocumentNodeBaseSchema.required, \"children\"],\n additionalProperties: false,\n} as const satisfies DataPortSchema;\n\n/**\n * Schema for document root node\n */\nexport const DocumentRootNodeSchema = {\n type: \"object\",\n properties: {\n ...DocumentNodeBaseSchema.properties,\n kind: {\n type: \"string\",\n const: NodeKind.DOCUMENT,\n title: \"Kind\",\n description: \"Node type discriminator\",\n },\n title: {\n type: \"string\",\n title: \"Title\",\n description: \"Document title\",\n },\n children: {\n type: \"array\",\n items: DocumentNodeSchema,\n title: \"Children\",\n description: \"Child nodes\",\n },\n },\n required: [...DocumentNodeBaseSchema.required, \"title\", \"children\"],\n additionalProperties: false,\n} as const satisfies DataPortSchema;\n\n// =============================================================================\n// Manually-defined interfaces for recursive discriminated union types\n// These provide better TypeScript inference than FromSchema for recursive types\n// =============================================================================\n\n/**\n * Base document node fields\n */\ninterface DocumentNodeBase {\n readonly nodeId: string;\n readonly kind: NodeKind;\n readonly range: NodeRange;\n readonly text: string;\n readonly enrichment?: NodeEnrichment;\n}\n\n/**\n * Document root node\n */\nexport interface DocumentRootNode extends DocumentNodeBase {\n readonly kind: typeof NodeKind.DOCUMENT;\n readonly title: string;\n readonly children: DocumentNode[];\n}\n\n/**\n * Section node (from markdown headers or structural divisions)\n */\nexport interface SectionNode extends DocumentNodeBase {\n readonly kind: typeof NodeKind.SECTION;\n readonly level: number;\n readonly title: string;\n readonly children: DocumentNode[];\n}\n\n/**\n * Paragraph node\n */\nexport interface ParagraphNode extends DocumentNodeBase {\n readonly kind: typeof NodeKind.PARAGRAPH;\n}\n\n/**\n * Sentence node (optional fine-grained segmentation)\n */\nexport interface SentenceNode extends DocumentNodeBase {\n readonly kind: typeof NodeKind.SENTENCE;\n}\n\n/**\n * Topic segment node (from TopicSegmenter)\n */\nexport interface TopicNode extends DocumentNodeBase {\n readonly kind: typeof NodeKind.TOPIC;\n readonly children: DocumentNode[];\n}\n\n/**\n * Discriminated union of all document node types\n */\nexport type DocumentNode =\n | DocumentRootNode\n | SectionNode\n | ParagraphNode\n | SentenceNode\n | TopicNode;\n\n// =============================================================================\n// Token Budget\n// =============================================================================\n\n/**\n * Schema for token budget configuration\n */\nexport const TokenBudgetSchema = {\n type: \"object\",\n properties: {\n maxTokensPerChunk: {\n type: \"integer\",\n title: \"Max Tokens Per Chunk\",\n description: \"Maximum tokens allowed per chunk\",\n },\n overlapTokens: {\n type: \"integer\",\n title: \"Overlap Tokens\",\n description: \"Number of tokens to overlap between chunks\",\n },\n reservedTokens: {\n type: \"integer\",\n title: \"Reserved Tokens\",\n description: \"Tokens reserved for metadata or context\",\n },\n },\n required: [\"maxTokensPerChunk\", \"overlapTokens\", \"reservedTokens\"],\n additionalProperties: false,\n} as const satisfies DataPortSchema;\n\nexport type TokenBudget = FromSchema<typeof TokenBudgetSchema>;\n\n// =============================================================================\n// Document Metadata\n// =============================================================================\n\n/**\n * Schema for document metadata\n */\nexport const DocumentMetadataSchema = {\n type: \"object\",\n properties: {\n title: {\n type: \"string\",\n title: \"Title\",\n description: \"Document title\",\n },\n sourceUri: {\n type: \"string\",\n title: \"Source URI\",\n description: \"Original source URI of the document\",\n },\n createdAt: {\n type: \"string\",\n title: \"Created At\",\n description: \"ISO timestamp of creation\",\n },\n },\n required: [\"title\"],\n additionalProperties: true,\n} as const satisfies DataPortSchema;\n\nexport type DocumentMetadata = FromSchema<typeof DocumentMetadataSchema>;\n",
6
6
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DataPortSchema, FromSchema, JsonSchema } from \"@workglow/util/schema\";\nimport { EntitySchema } from \"../document/DocumentSchema\";\n\n/**\n * Schema for a unified chunk record.\n * Replaces ChunkNode, ChunkMetadata, and EnrichedChunkMetadata with a single flat type.\n */\nexport const ChunkRecordSchema = () =>\n ({\n type: \"object\",\n properties: {\n chunkId: {\n type: \"string\",\n title: \"Chunk ID\",\n description: \"Unique identifier for this chunk\",\n },\n doc_id: {\n type: \"string\",\n title: \"Document ID\",\n description: \"ID of the parent document\",\n },\n text: {\n type: \"string\",\n title: \"Text\",\n description: \"Text content of the chunk\",\n },\n nodePath: {\n type: \"array\",\n items: { type: \"string\" },\n title: \"Node Path\",\n description: \"Node IDs from root to leaf\",\n },\n depth: {\n type: \"integer\",\n title: \"Depth\",\n description: \"Depth in the document tree\",\n },\n leafNodeId: {\n type: \"string\",\n title: \"Leaf Node ID\",\n description: \"ID of the leaf node this chunk belongs to\",\n },\n summary: {\n type: \"string\",\n title: \"Summary\",\n description: \"Summary of the chunk content\",\n },\n entities: {\n type: \"array\",\n items: EntitySchema,\n title: \"Entities\",\n description: \"Named entities extracted from the chunk\",\n },\n parentSummaries: {\n type: \"array\",\n items: { type: \"string\" },\n title: \"Parent Summaries\",\n description: \"Summaries from ancestor nodes\",\n },\n sectionTitles: {\n type: \"array\",\n items: { type: \"string\" },\n title: \"Section Titles\",\n description: \"Titles of ancestor section nodes\",\n },\n doc_title: {\n type: \"string\",\n title: \"Document Title\",\n description: \"Title of the parent document\",\n },\n },\n required: [\"chunkId\", \"doc_id\", \"text\", \"nodePath\", \"depth\"],\n additionalProperties: true,\n }) as const satisfies DataPortSchema;\n\nexport type ChunkRecord = FromSchema<ReturnType<typeof ChunkRecordSchema>>;\n\n/**\n * Schema for chunk record array (for use in task schemas)\n */\nexport const ChunkRecordArraySchema = {\n type: \"array\",\n items: ChunkRecordSchema(),\n title: \"Chunk Records\",\n description: \"Array of chunk records\",\n} as const satisfies JsonSchema;\n",
7
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { IVectorStorage } from \"@workglow/storage\";\nimport {\n TypedArraySchema,\n type DataPortSchemaObject,\n type TypedArray,\n} from \"@workglow/util/schema\";\nimport type { ChunkRecord } from \"./ChunkSchema\";\n\n/**\n * Schema for chunk vector storage with typed metadata.\n * Replaces DocumentChunkSchema with ChunkRecord as the metadata type.\n */\nexport const ChunkVectorStorageSchema = {\n type: \"object\",\n properties: {\n chunk_id: { type: \"string\", \"x-auto-generated\": true },\n doc_id: { type: \"string\" },\n vector: TypedArraySchema(),\n metadata: { type: \"object\", format: \"metadata\", additionalProperties: true },\n },\n required: [\"chunk_id\", \"doc_id\", \"vector\", \"metadata\"],\n additionalProperties: false,\n} as const satisfies DataPortSchemaObject;\nexport type ChunkVectorStorageSchema = typeof ChunkVectorStorageSchema;\n\nexport const ChunkVectorPrimaryKey = [\"chunk_id\"] as const;\nexport type ChunkVectorPrimaryKey = typeof ChunkVectorPrimaryKey;\n\nexport interface ChunkVectorEntity<\n Metadata extends ChunkRecord = ChunkRecord,\n Vector extends TypedArray = TypedArray,\n> {\n chunk_id: string;\n doc_id: string;\n vector: Vector;\n metadata: Metadata;\n}\n\n/**\n * Type for inserting chunk vectors - chunk_id is optional (auto-generated)\n */\nexport type InsertChunkVectorEntity<\n Metadata extends ChunkRecord = ChunkRecord,\n Vector extends TypedArray = TypedArray,\n> = Omit<ChunkVectorEntity<Metadata, Vector>, \"chunk_id\"> &\n Partial<Pick<ChunkVectorEntity<Metadata, Vector>, \"chunk_id\">>;\n\n/**\n * Type for the primary key of chunk vectors\n */\nexport type ChunkVectorKey = { chunk_id: string };\n\nexport type ChunkVectorStorage = IVectorStorage<\n ChunkRecord,\n typeof ChunkVectorStorageSchema,\n ChunkVectorEntity,\n ChunkVectorPrimaryKey\n>;\n\n/**\n * Search result with score\n */\nexport type ChunkSearchResult = ChunkVectorEntity & { score: number };\n",
8
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ChunkRecord } from \"../chunk/ChunkSchema\";\nimport type { DocumentMetadata, DocumentNode } from \"./DocumentSchema\";\n\n/**\n * Document represents a hierarchical document with chunks\n *\n * Key features:\n * - Single source-of-truth tree structure (root node)\n * - Single set of chunks\n * - Separate persistence for document structure vs vectors\n */\nexport class Document {\n public doc_id: string | undefined;\n public readonly metadata: DocumentMetadata;\n public readonly root: DocumentNode;\n private chunks: ChunkRecord[];\n\n constructor(\n root: DocumentNode,\n metadata: DocumentMetadata,\n chunks: ChunkRecord[] = [],\n doc_id?: string\n ) {\n this.doc_id = doc_id;\n this.root = root;\n this.metadata = metadata;\n this.chunks = chunks || [];\n }\n\n /**\n * Set chunks for the document\n */\n setChunks(chunks: ChunkRecord[]): void {\n this.chunks = chunks;\n }\n\n /**\n * Get all chunks\n */\n getChunks(): ChunkRecord[] {\n return this.chunks;\n }\n\n /**\n * Set the document ID\n */\n setDocId(doc_id: string): void {\n this.doc_id = doc_id;\n }\n\n /**\n * Find chunks by nodeId\n */\n findChunksByNodeId(nodeId: string): ChunkRecord[] {\n return this.chunks.filter((chunk) => chunk.nodePath.includes(nodeId));\n }\n\n /**\n * Serialize to JSON\n */\n toJSON(): {\n metadata: DocumentMetadata;\n root: DocumentNode;\n chunks: ChunkRecord[];\n } {\n return {\n metadata: this.metadata,\n root: this.root,\n chunks: this.chunks,\n };\n }\n\n /**\n * Deserialize from JSON\n */\n static fromJSON(json: string, doc_id?: string): Document {\n const obj = JSON.parse(json);\n if (!obj || typeof obj !== \"object\") {\n throw new Error(\"Document.fromJSON: expected a JSON object\");\n }\n if (!obj.root || typeof obj.root !== \"object\" || !obj.root.kind) {\n throw new Error(\"Document.fromJSON: missing or invalid 'root' node\");\n }\n if (!obj.metadata || typeof obj.metadata !== \"object\" || typeof obj.metadata.title !== \"string\") {\n throw new Error(\"Document.fromJSON: missing or invalid 'metadata' (requires 'title' string)\");\n }\n if (obj.chunks !== undefined && !Array.isArray(obj.chunks)) {\n throw new Error(\"Document.fromJSON: 'chunks' must be an array if present\");\n }\n return new Document(obj.root, obj.metadata, obj.chunks, doc_id);\n }\n}\n",
9
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { HybridSearchOptions, VectorSearchOptions } from \"@workglow/storage\";\nimport type { TypedArray } from \"@workglow/util/schema\";\nimport type { ChunkRecord } from \"../chunk/ChunkSchema\";\nimport type {\n ChunkSearchResult,\n ChunkVectorEntity,\n ChunkVectorStorage,\n InsertChunkVectorEntity,\n} from \"../chunk/ChunkVectorStorageSchema\";\nimport { Document } from \"../document/Document\";\nimport type { DocumentNode } from \"../document/DocumentSchema\";\nimport type {\n DocumentStorageEntity,\n DocumentTabularStorage,\n InsertDocumentStorageEntity,\n} from \"../document/DocumentStorageSchema\";\n\n/**\n * Unified KnowledgeBase that owns both document and vector storage,\n * providing lifecycle management and cascading deletes.\n */\nexport class KnowledgeBase {\n readonly name: string;\n readonly title: string;\n readonly description: string;\n private tabularStorage: DocumentTabularStorage;\n private chunkStorage: ChunkVectorStorage;\n\n constructor(\n name: string,\n documentStorage: DocumentTabularStorage,\n chunkStorage: ChunkVectorStorage,\n title?: string,\n description?: string\n ) {\n this.name = name;\n this.title = title ?? name;\n this.description = description ?? \"\";\n this.tabularStorage = documentStorage;\n this.chunkStorage = chunkStorage;\n }\n\n // ===========================================================================\n // Document CRUD\n // ===========================================================================\n\n /**\n * Upsert a document.\n * @returns The document with the generated doc_id if it was auto-generated\n */\n async upsertDocument(document: Document): Promise<Document> {\n const serialized = JSON.stringify(document.toJSON());\n\n const insertEntity: InsertDocumentStorageEntity = {\n doc_id: document.doc_id,\n data: serialized,\n };\n const entity = await this.tabularStorage.put(insertEntity);\n\n if (document.doc_id !== entity.doc_id) {\n document.setDocId(entity.doc_id);\n }\n return document;\n }\n\n /**\n * Get a document by ID\n */\n async getDocument(doc_id: string): Promise<Document | undefined> {\n const entity = await this.tabularStorage.get({ doc_id });\n if (!entity) {\n return undefined;\n }\n return Document.fromJSON(entity.data, entity.doc_id);\n }\n\n /**\n * Delete a document and all its chunks (cascading delete).\n */\n async deleteDocument(doc_id: string): Promise<void> {\n await this.deleteChunksForDocument(doc_id);\n await this.tabularStorage.delete({ doc_id });\n }\n\n /**\n * List all document IDs\n */\n async listDocuments(): Promise<string[]> {\n const entities = await this.tabularStorage.getAll();\n if (!entities) {\n return [];\n }\n return entities.map((e: DocumentStorageEntity) => e.doc_id);\n }\n\n // ===========================================================================\n // Tree traversal\n // ===========================================================================\n\n /**\n * Get a specific node by ID from a document\n */\n async getNode(doc_id: string, nodeId: string): Promise<DocumentNode | undefined> {\n const doc = await this.getDocument(doc_id);\n if (!doc) {\n return undefined;\n }\n\n const traverse = (node: DocumentNode): DocumentNode | undefined => {\n if (node.nodeId === nodeId) {\n return node;\n }\n if (\"children\" in node && Array.isArray(node.children)) {\n for (const child of node.children) {\n const found = traverse(child);\n if (found) return found;\n }\n }\n return undefined;\n };\n\n return traverse(doc.root);\n }\n\n /**\n * Get ancestors of a node (from root to target node)\n */\n async getAncestors(doc_id: string, nodeId: string): Promise<DocumentNode[]> {\n const doc = await this.getDocument(doc_id);\n if (!doc) {\n return [];\n }\n\n const path: string[] = [];\n const findPath = (node: DocumentNode): boolean => {\n path.push(node.nodeId);\n if (node.nodeId === nodeId) {\n return true;\n }\n if (\"children\" in node && Array.isArray(node.children)) {\n for (const child of node.children) {\n if (findPath(child)) {\n return true;\n }\n }\n }\n path.pop();\n return false;\n };\n\n if (!findPath(doc.root)) {\n return [];\n }\n\n const ancestors: DocumentNode[] = [];\n let currentNode: DocumentNode = doc.root;\n ancestors.push(currentNode);\n\n for (let i = 1; i < path.length; i++) {\n const targetId = path[i];\n if (\"children\" in currentNode && Array.isArray(currentNode.children)) {\n const found = currentNode.children.find((child: DocumentNode) => child.nodeId === targetId);\n if (found) {\n currentNode = found;\n ancestors.push(currentNode);\n } else {\n break;\n }\n } else {\n break;\n }\n }\n\n return ancestors;\n }\n\n // ===========================================================================\n // Chunk CRUD\n // ===========================================================================\n\n /**\n * Upsert a single chunk vector entity\n */\n async upsertChunk(chunk: InsertChunkVectorEntity): Promise<ChunkVectorEntity> {\n if (chunk.vector.length !== this.getVectorDimensions()) {\n throw new Error(\n `Vector dimension mismatch: expected ${this.getVectorDimensions()}, got ${chunk.vector.length}.`\n );\n }\n return this.chunkStorage.put(chunk);\n }\n\n /**\n * Upsert multiple chunk vector entities\n */\n async upsertChunksBulk(chunks: InsertChunkVectorEntity[]): Promise<ChunkVectorEntity[]> {\n const expected = this.getVectorDimensions();\n for (const chunk of chunks) {\n if (chunk.vector.length !== expected) {\n throw new Error(\n `Vector dimension mismatch: expected ${expected}, got ${chunk.vector.length}.`\n );\n }\n }\n return this.chunkStorage.putBulk(chunks);\n }\n\n /**\n * Delete all chunks for a specific document\n */\n async deleteChunksForDocument(doc_id: string): Promise<void> {\n await this.chunkStorage.deleteSearch({ doc_id });\n }\n\n /**\n * Get all chunks for a specific document\n */\n async getChunksForDocument(doc_id: string): Promise<ChunkVectorEntity[]> {\n const results = await this.chunkStorage.query({ doc_id });\n return (results ?? []) as ChunkVectorEntity[];\n }\n\n // ===========================================================================\n // Search\n // ===========================================================================\n\n /**\n * Search for similar chunks using vector similarity\n */\n async similaritySearch(\n query: TypedArray,\n options?: VectorSearchOptions<ChunkRecord>\n ): Promise<ChunkSearchResult[]> {\n return this.chunkStorage.similaritySearch(query, options);\n }\n\n /**\n * Check if the configured storage backend supports hybrid search\n */\n supportsHybridSearch(): boolean {\n return typeof this.chunkStorage.hybridSearch === \"function\";\n }\n\n /**\n * Hybrid search combining vector similarity and full-text search\n */\n async hybridSearch(\n query: TypedArray,\n options: HybridSearchOptions<ChunkRecord>\n ): Promise<ChunkSearchResult[]> {\n if (typeof this.chunkStorage.hybridSearch !== \"function\") {\n throw new Error(\n \"Hybrid search is not supported by the configured chunk storage backend. \" +\n \"Please use a vector storage implementation that provides `hybridSearch`.\"\n );\n }\n return this.chunkStorage.hybridSearch(query, options);\n }\n\n // ===========================================================================\n // Lifecycle\n // ===========================================================================\n\n /**\n * Prepare a document for re-indexing: deletes all chunks but keeps the document.\n * @returns The document if found, undefined otherwise\n */\n async prepareReindex(doc_id: string): Promise<Document | undefined> {\n const doc = await this.getDocument(doc_id);\n if (!doc) {\n return undefined;\n }\n await this.deleteChunksForDocument(doc_id);\n return doc;\n }\n\n /**\n * Setup the underlying databases\n */\n async setupDatabase(): Promise<void> {\n await this.tabularStorage.setupDatabase();\n await this.chunkStorage.setupDatabase();\n }\n\n /**\n * Destroy storage instances\n */\n destroy(): void {\n this.tabularStorage.destroy();\n this.chunkStorage.destroy();\n }\n\n // ===========================================================================\n // Accessors\n // ===========================================================================\n\n /**\n * Get a chunk by ID\n */\n async getChunk(chunk_id: string): Promise<ChunkVectorEntity | undefined> {\n return this.chunkStorage.get({ chunk_id });\n }\n\n /**\n * Store a single chunk (alias for upsertChunk)\n */\n async put(chunk: InsertChunkVectorEntity): Promise<ChunkVectorEntity> {\n return this.chunkStorage.put(chunk);\n }\n\n /**\n * Store multiple chunks (alias for upsertChunksBulk)\n */\n async putBulk(chunks: InsertChunkVectorEntity[]): Promise<ChunkVectorEntity[]> {\n return this.chunkStorage.putBulk(chunks);\n }\n\n /**\n * Get all chunks\n */\n async getAllChunks(): Promise<ChunkVectorEntity[] | undefined> {\n return this.chunkStorage.getAll() as Promise<ChunkVectorEntity[] | undefined>;\n }\n\n /**\n * Get chunk count\n */\n async chunkCount(): Promise<number> {\n return this.chunkStorage.size();\n }\n\n /**\n * Clear all chunks\n */\n async clearChunks(): Promise<void> {\n return this.chunkStorage.deleteAll();\n }\n\n /**\n * Get vector dimensions\n */\n getVectorDimensions(): number {\n return this.chunkStorage.getVectorDimensions();\n }\n\n // ===========================================================================\n // Document chunk helpers\n // ===========================================================================\n\n /**\n * Get chunks from the document JSON (not from vector storage)\n */\n async getDocumentChunks(doc_id: string): Promise<ChunkRecord[]> {\n const doc = await this.getDocument(doc_id);\n if (!doc) {\n return [];\n }\n return doc.getChunks();\n }\n\n /**\n * Find chunks in document JSON that contain a specific nodeId in their path\n */\n async findChunksByNodeId(doc_id: string, nodeId: string): Promise<ChunkRecord[]> {\n const doc = await this.getDocument(doc_id);\n if (!doc) {\n return [];\n }\n return doc.findChunksByNodeId(nodeId);\n }\n}\n",
10
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DataPortSchemaObject, FromSchema } from \"@workglow/util/schema\";\n\n/**\n * Schema for persisting KnowledgeBase metadata to tabular storage.\n */\nexport const KnowledgeBaseRecordSchema = {\n type: \"object\",\n properties: {\n kb_id: { type: \"string\" },\n title: { type: \"string\" },\n description: { type: \"string\" },\n vector_dimensions: { type: \"integer\" },\n document_table: { type: \"string\" },\n chunk_table: { type: \"string\" },\n created_at: { type: \"string\" },\n updated_at: { type: \"string\" },\n },\n required: [\n \"kb_id\",\n \"title\",\n \"description\",\n \"vector_dimensions\",\n \"document_table\",\n \"chunk_table\",\n \"created_at\",\n \"updated_at\",\n ],\n additionalProperties: false,\n} as const satisfies DataPortSchemaObject;\n\nexport type KnowledgeBaseRecord = FromSchema<typeof KnowledgeBaseRecordSchema>;\nexport const KnowledgeBasePrimaryKeyNames = [\"kb_id\"] as const;\n\n/**\n * Generates SQL-safe table names for a knowledge base's document and chunk storage.\n */\nexport function knowledgeBaseTableNames(kbId: string): {\n readonly documentTable: string;\n readonly chunkTable: string;\n} {\n const safe = kbId.replace(/[^a-zA-Z0-9_]/g, \"_\");\n return {\n documentTable: `kb_docs_${safe}`,\n chunkTable: `kb_chunks_${safe}`,\n };\n}\n",
11
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { type ITabularStorage } from \"@workglow/storage\";\nimport { EventEmitter, type EventParameters } from \"@workglow/util\";\n\nimport {\n KnowledgeBasePrimaryKeyNames,\n type KnowledgeBaseRecord,\n KnowledgeBaseRecordSchema,\n} from \"./KnowledgeBaseSchema\";\n\n/**\n * Events that can be emitted by the KnowledgeBaseRepository\n */\n\nexport type KnowledgeBaseEventListeners = {\n knowledge_base_added: (record: KnowledgeBaseRecord) => void;\n knowledge_base_removed: (record: KnowledgeBaseRecord) => void;\n knowledge_base_updated: (record: KnowledgeBaseRecord) => void;\n};\n\nexport type KnowledgeBaseEvents = keyof KnowledgeBaseEventListeners;\n\nexport type KnowledgeBaseEventListener<Event extends KnowledgeBaseEvents> =\n KnowledgeBaseEventListeners[Event];\n\nexport type KnowledgeBaseEventParameters<Event extends KnowledgeBaseEvents> = EventParameters<\n KnowledgeBaseEventListeners,\n Event\n>;\n\n/**\n * Repository for persisting KnowledgeBase metadata to tabular storage.\n * Follows the same pattern as ModelRepository.\n */\nexport class KnowledgeBaseRepository {\n /**\n * Storage for KnowledgeBase records\n */\n protected readonly storage: ITabularStorage<\n typeof KnowledgeBaseRecordSchema,\n typeof KnowledgeBasePrimaryKeyNames\n >;\n\n constructor(\n storage: ITabularStorage<typeof KnowledgeBaseRecordSchema, typeof KnowledgeBasePrimaryKeyNames>\n ) {\n this.storage = storage;\n }\n\n /** Event emitter for repository events */\n protected events = new EventEmitter<KnowledgeBaseEventListeners>();\n\n /**\n * Sets up the database for the repository.\n * Must be called before using any other methods.\n */\n async setupDatabase(): Promise<void> {\n await this.storage.setupDatabase?.();\n }\n\n /**\n * Registers an event listener for the specified event\n */\n on<Event extends KnowledgeBaseEvents>(name: Event, fn: KnowledgeBaseEventListener<Event>) {\n this.events.on(name, fn);\n }\n\n /**\n * Removes an event listener for the specified event\n */\n off<Event extends KnowledgeBaseEvents>(name: Event, fn: KnowledgeBaseEventListener<Event>) {\n this.events.off(name, fn);\n }\n\n /**\n * Adds an event listener that will only be called once\n */\n once<Event extends KnowledgeBaseEvents>(name: Event, fn: KnowledgeBaseEventListener<Event>) {\n this.events.once(name, fn);\n }\n\n /**\n * Returns when the event was emitted (promise form of once)\n */\n waitOn<Event extends KnowledgeBaseEvents>(name: Event) {\n return this.events.waitOn(name);\n }\n\n /**\n * Adds a new knowledge base record to the repository\n */\n async addKnowledgeBase(record: KnowledgeBaseRecord): Promise<KnowledgeBaseRecord> {\n await this.storage.put(record);\n this.events.emit(\"knowledge_base_added\", record);\n return record;\n }\n\n /**\n * Removes a knowledge base record from the repository\n */\n async removeKnowledgeBase(kb_id: string): Promise<void> {\n const record = await this.storage.get({ kb_id });\n if (!record) {\n throw new Error(`KnowledgeBase with id \"${kb_id}\" not found`);\n }\n await this.storage.delete({ kb_id });\n this.events.emit(\"knowledge_base_removed\", record);\n }\n\n /**\n * Retrieves a knowledge base record by ID\n */\n async getKnowledgeBase(kb_id: string): Promise<KnowledgeBaseRecord | undefined> {\n if (typeof kb_id !== \"string\") return undefined;\n const record = await this.storage.get({ kb_id });\n return record ?? undefined;\n }\n\n /**\n * Enumerates all knowledge base records\n */\n async enumerateAll(): Promise<KnowledgeBaseRecord[]> {\n const records = await this.storage.getAll();\n if (!records || records.length === 0) return [];\n return records;\n }\n\n /**\n * Gets the total number of knowledge base records\n */\n async size(): Promise<number> {\n return await this.storage.size();\n }\n}\n",
7
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { IVectorStorage } from \"@workglow/storage\";\nimport { TypedArraySchema } from \"@workglow/util/schema\";\nimport type { DataPortSchemaObject, TypedArray } from \"@workglow/util/schema\";\nimport type { ChunkRecord } from \"./ChunkSchema\";\n\n/**\n * Schema for chunk vector storage with typed metadata.\n * Replaces DocumentChunkSchema with ChunkRecord as the metadata type.\n */\nexport const ChunkVectorStorageSchema = {\n type: \"object\",\n properties: {\n chunk_id: { type: \"string\", \"x-auto-generated\": true },\n doc_id: { type: \"string\" },\n vector: TypedArraySchema(),\n metadata: { type: \"object\", format: \"metadata\", additionalProperties: true },\n },\n required: [\"chunk_id\", \"doc_id\", \"vector\", \"metadata\"],\n additionalProperties: false,\n} as const satisfies DataPortSchemaObject;\nexport type ChunkVectorStorageSchema = typeof ChunkVectorStorageSchema;\n\nexport const ChunkVectorPrimaryKey = [\"chunk_id\"] as const;\nexport type ChunkVectorPrimaryKey = typeof ChunkVectorPrimaryKey;\n\nexport interface ChunkVectorEntity<\n Metadata extends ChunkRecord = ChunkRecord,\n Vector extends TypedArray = TypedArray,\n> {\n chunk_id: string;\n doc_id: string;\n vector: Vector;\n metadata: Metadata;\n}\n\n/**\n * Type for inserting chunk vectors - chunk_id is optional (auto-generated)\n */\nexport type InsertChunkVectorEntity<\n Metadata extends ChunkRecord = ChunkRecord,\n Vector extends TypedArray = TypedArray,\n> = Omit<ChunkVectorEntity<Metadata, Vector>, \"chunk_id\"> &\n Partial<Pick<ChunkVectorEntity<Metadata, Vector>, \"chunk_id\">>;\n\n/**\n * Type for the primary key of chunk vectors\n */\nexport type ChunkVectorKey = { chunk_id: string };\n\nexport type ChunkVectorStorage = IVectorStorage<\n ChunkRecord,\n typeof ChunkVectorStorageSchema,\n ChunkVectorEntity,\n ChunkVectorPrimaryKey\n>;\n\n/**\n * Search result with score\n */\nexport type ChunkSearchResult = ChunkVectorEntity & { score: number };\n",
8
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ChunkRecord } from \"../chunk/ChunkSchema\";\nimport type { DocumentMetadata, DocumentNode } from \"./DocumentSchema\";\n\n/**\n * Document represents a hierarchical document with chunks\n *\n * Key features:\n * - Single source-of-truth tree structure (root node)\n * - Single set of chunks\n * - Separate persistence for document structure vs vectors\n */\nexport class Document {\n public doc_id: string | undefined;\n public readonly metadata: DocumentMetadata;\n public readonly root: DocumentNode;\n private chunks: ChunkRecord[];\n\n constructor(\n root: DocumentNode,\n metadata: DocumentMetadata,\n chunks: ChunkRecord[] = [],\n doc_id?: string\n ) {\n this.doc_id = doc_id;\n this.root = root;\n this.metadata = metadata;\n this.chunks = chunks || [];\n }\n\n /**\n * Set chunks for the document\n */\n setChunks(chunks: ChunkRecord[]): void {\n this.chunks = chunks;\n }\n\n /**\n * Get all chunks\n */\n getChunks(): ChunkRecord[] {\n return this.chunks;\n }\n\n /**\n * Set the document ID\n */\n setDocId(doc_id: string): void {\n this.doc_id = doc_id;\n }\n\n /**\n * Find chunks by nodeId\n */\n findChunksByNodeId(nodeId: string): ChunkRecord[] {\n return this.chunks.filter((chunk) => chunk.nodePath.includes(nodeId));\n }\n\n /**\n * Serialize to JSON\n */\n toJSON(): {\n metadata: DocumentMetadata;\n root: DocumentNode;\n chunks: ChunkRecord[];\n } {\n return {\n metadata: this.metadata,\n root: this.root,\n chunks: this.chunks,\n };\n }\n\n /**\n * Deserialize from JSON\n */\n static fromJSON(json: string, doc_id?: string): Document {\n const obj = JSON.parse(json);\n if (!obj || typeof obj !== \"object\") {\n throw new Error(\"Document.fromJSON: expected a JSON object\");\n }\n if (!obj.root || typeof obj.root !== \"object\" || !obj.root.kind) {\n throw new Error(\"Document.fromJSON: missing or invalid 'root' node\");\n }\n if (\n !obj.metadata ||\n typeof obj.metadata !== \"object\" ||\n typeof obj.metadata.title !== \"string\"\n ) {\n throw new Error(\"Document.fromJSON: missing or invalid 'metadata' (requires 'title' string)\");\n }\n if (obj.chunks !== undefined && !Array.isArray(obj.chunks)) {\n throw new Error(\"Document.fromJSON: 'chunks' must be an array if present\");\n }\n return new Document(obj.root, obj.metadata, obj.chunks, doc_id);\n }\n}\n",
9
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { HybridSearchOptions, VectorSearchOptions } from \"@workglow/storage\";\nimport type { TypedArray } from \"@workglow/util/schema\";\nimport type { ChunkRecord } from \"../chunk/ChunkSchema\";\nimport type {\n ChunkSearchResult,\n ChunkVectorEntity,\n ChunkVectorStorage,\n InsertChunkVectorEntity,\n} from \"../chunk/ChunkVectorStorageSchema\";\nimport { Document } from \"../document/Document\";\nimport type { DocumentNode } from \"../document/DocumentSchema\";\nimport type {\n DocumentStorageEntity,\n DocumentTabularStorage,\n InsertDocumentStorageEntity,\n} from \"../document/DocumentStorageSchema\";\n\n/**\n * Unified KnowledgeBase that owns both document and vector storage,\n * providing lifecycle management and cascading deletes.\n */\nexport class KnowledgeBase {\n readonly name: string;\n readonly title: string;\n readonly description: string;\n private tabularStorage: DocumentTabularStorage;\n private chunkStorage: ChunkVectorStorage;\n\n constructor(\n name: string,\n documentStorage: DocumentTabularStorage,\n chunkStorage: ChunkVectorStorage,\n title?: string,\n description?: string\n ) {\n this.name = name;\n this.title = title ?? name;\n this.description = description ?? \"\";\n this.tabularStorage = documentStorage;\n this.chunkStorage = chunkStorage;\n }\n\n // ===========================================================================\n // Document CRUD\n // ===========================================================================\n\n /**\n * Upsert a document.\n * @returns The document with the generated doc_id if it was auto-generated\n */\n async upsertDocument(document: Document): Promise<Document> {\n const serialized = JSON.stringify(document.toJSON());\n\n const insertEntity: InsertDocumentStorageEntity = {\n doc_id: document.doc_id,\n data: serialized,\n };\n const entity = await this.tabularStorage.put(insertEntity);\n\n if (document.doc_id !== entity.doc_id) {\n document.setDocId(entity.doc_id);\n }\n return document;\n }\n\n /**\n * Get a document by ID\n */\n async getDocument(doc_id: string): Promise<Document | undefined> {\n const entity = await this.tabularStorage.get({ doc_id });\n if (!entity) {\n return undefined;\n }\n return Document.fromJSON(entity.data, entity.doc_id);\n }\n\n /**\n * Delete a document and all its chunks (cascading delete).\n */\n async deleteDocument(doc_id: string): Promise<void> {\n await this.deleteChunksForDocument(doc_id);\n await this.tabularStorage.delete({ doc_id });\n }\n\n /**\n * List all document IDs\n */\n async listDocuments(): Promise<string[]> {\n const entities = await this.tabularStorage.getAll();\n if (!entities) {\n return [];\n }\n return entities.map((e: DocumentStorageEntity) => e.doc_id);\n }\n\n // ===========================================================================\n // Tree traversal\n // ===========================================================================\n\n /**\n * Get a specific node by ID from a document\n */\n async getNode(doc_id: string, nodeId: string): Promise<DocumentNode | undefined> {\n const doc = await this.getDocument(doc_id);\n if (!doc) {\n return undefined;\n }\n\n const traverse = (node: DocumentNode): DocumentNode | undefined => {\n if (node.nodeId === nodeId) {\n return node;\n }\n if (\"children\" in node && Array.isArray(node.children)) {\n for (const child of node.children) {\n const found = traverse(child);\n if (found) return found;\n }\n }\n return undefined;\n };\n\n return traverse(doc.root);\n }\n\n /**\n * Get ancestors of a node (from root to target node)\n */\n async getAncestors(doc_id: string, nodeId: string): Promise<DocumentNode[]> {\n const doc = await this.getDocument(doc_id);\n if (!doc) {\n return [];\n }\n\n const path: string[] = [];\n const findPath = (node: DocumentNode): boolean => {\n path.push(node.nodeId);\n if (node.nodeId === nodeId) {\n return true;\n }\n if (\"children\" in node && Array.isArray(node.children)) {\n for (const child of node.children) {\n if (findPath(child)) {\n return true;\n }\n }\n }\n path.pop();\n return false;\n };\n\n if (!findPath(doc.root)) {\n return [];\n }\n\n const ancestors: DocumentNode[] = [];\n let currentNode: DocumentNode = doc.root;\n ancestors.push(currentNode);\n\n for (let i = 1; i < path.length; i++) {\n const targetId = path[i];\n if (\"children\" in currentNode && Array.isArray(currentNode.children)) {\n const found = currentNode.children.find((child: DocumentNode) => child.nodeId === targetId);\n if (found) {\n currentNode = found;\n ancestors.push(currentNode);\n } else {\n break;\n }\n } else {\n break;\n }\n }\n\n return ancestors;\n }\n\n // ===========================================================================\n // Chunk CRUD\n // ===========================================================================\n\n /**\n * Upsert a single chunk vector entity\n */\n async upsertChunk(chunk: InsertChunkVectorEntity): Promise<ChunkVectorEntity> {\n if (chunk.vector.length !== this.getVectorDimensions()) {\n throw new Error(\n `Vector dimension mismatch: expected ${this.getVectorDimensions()}, got ${chunk.vector.length}.`\n );\n }\n return this.chunkStorage.put(chunk);\n }\n\n /**\n * Upsert multiple chunk vector entities\n */\n async upsertChunksBulk(chunks: InsertChunkVectorEntity[]): Promise<ChunkVectorEntity[]> {\n const expected = this.getVectorDimensions();\n for (const chunk of chunks) {\n if (chunk.vector.length !== expected) {\n throw new Error(\n `Vector dimension mismatch: expected ${expected}, got ${chunk.vector.length}.`\n );\n }\n }\n return this.chunkStorage.putBulk(chunks);\n }\n\n /**\n * Delete all chunks for a specific document\n */\n async deleteChunksForDocument(doc_id: string): Promise<void> {\n await this.chunkStorage.deleteSearch({ doc_id });\n }\n\n /**\n * Get all chunks for a specific document\n */\n async getChunksForDocument(doc_id: string): Promise<ChunkVectorEntity[]> {\n const results = await this.chunkStorage.query({ doc_id });\n return (results ?? []) as ChunkVectorEntity[];\n }\n\n // ===========================================================================\n // Search\n // ===========================================================================\n\n /**\n * Search for similar chunks using vector similarity\n */\n async similaritySearch(\n query: TypedArray,\n options?: VectorSearchOptions<ChunkRecord>\n ): Promise<ChunkSearchResult[]> {\n return this.chunkStorage.similaritySearch(query, options);\n }\n\n /**\n * Check if the configured storage backend supports hybrid search\n */\n supportsHybridSearch(): boolean {\n return typeof this.chunkStorage.hybridSearch === \"function\";\n }\n\n /**\n * Hybrid search combining vector similarity and full-text search\n */\n async hybridSearch(\n query: TypedArray,\n options: HybridSearchOptions<ChunkRecord>\n ): Promise<ChunkSearchResult[]> {\n if (typeof this.chunkStorage.hybridSearch !== \"function\") {\n throw new Error(\n \"Hybrid search is not supported by the configured chunk storage backend. \" +\n \"Please use a vector storage implementation that provides `hybridSearch`.\"\n );\n }\n return this.chunkStorage.hybridSearch(query, options);\n }\n\n // ===========================================================================\n // Lifecycle\n // ===========================================================================\n\n /**\n * Prepare a document for re-indexing: deletes all chunks but keeps the document.\n * @returns The document if found, undefined otherwise\n */\n async prepareReindex(doc_id: string): Promise<Document | undefined> {\n const doc = await this.getDocument(doc_id);\n if (!doc) {\n return undefined;\n }\n await this.deleteChunksForDocument(doc_id);\n return doc;\n }\n\n /**\n * Setup the underlying databases\n */\n async setupDatabase(): Promise<void> {\n await this.tabularStorage.setupDatabase();\n await this.chunkStorage.setupDatabase();\n }\n\n /**\n * Destroy storage instances\n */\n destroy(): void {\n this.tabularStorage.destroy();\n this.chunkStorage.destroy();\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n this.destroy();\n }\n\n [Symbol.dispose](): void {\n this.destroy();\n }\n\n // ===========================================================================\n // Accessors\n // ===========================================================================\n\n /**\n * Get a chunk by ID\n */\n async getChunk(chunk_id: string): Promise<ChunkVectorEntity | undefined> {\n return this.chunkStorage.get({ chunk_id });\n }\n\n /**\n * Store a single chunk (alias for upsertChunk)\n */\n async put(chunk: InsertChunkVectorEntity): Promise<ChunkVectorEntity> {\n return this.chunkStorage.put(chunk);\n }\n\n /**\n * Store multiple chunks (alias for upsertChunksBulk)\n */\n async putBulk(chunks: InsertChunkVectorEntity[]): Promise<ChunkVectorEntity[]> {\n return this.chunkStorage.putBulk(chunks);\n }\n\n /**\n * Get all chunks\n */\n async getAllChunks(): Promise<ChunkVectorEntity[] | undefined> {\n return this.chunkStorage.getAll() as Promise<ChunkVectorEntity[] | undefined>;\n }\n\n /**\n * Get chunk count\n */\n async chunkCount(): Promise<number> {\n return this.chunkStorage.size();\n }\n\n /**\n * Clear all chunks\n */\n async clearChunks(): Promise<void> {\n return this.chunkStorage.deleteAll();\n }\n\n /**\n * Get vector dimensions\n */\n getVectorDimensions(): number {\n return this.chunkStorage.getVectorDimensions();\n }\n\n // ===========================================================================\n // Document chunk helpers\n // ===========================================================================\n\n /**\n * Get chunks from the document JSON (not from vector storage)\n */\n async getDocumentChunks(doc_id: string): Promise<ChunkRecord[]> {\n const doc = await this.getDocument(doc_id);\n if (!doc) {\n return [];\n }\n return doc.getChunks();\n }\n\n /**\n * Find chunks in document JSON that contain a specific nodeId in their path\n */\n async findChunksByNodeId(doc_id: string, nodeId: string): Promise<ChunkRecord[]> {\n const doc = await this.getDocument(doc_id);\n if (!doc) {\n return [];\n }\n return doc.findChunksByNodeId(nodeId);\n }\n}\n",
10
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { TypedArraySchema, type DataPortSchemaObject } from \"@workglow/util/schema\";\n\n/**\n * Default table names for shared-table mode.\n */\nexport const SHARED_DOCUMENT_TABLE = \"shared_documents\";\nexport const SHARED_CHUNK_TABLE = \"shared_chunks\";\n\n/**\n * Augmented document storage schema with kb_id column for shared-table mode.\n */\nexport const SharedDocumentStorageSchema = {\n type: \"object\",\n properties: {\n doc_id: {\n type: \"string\",\n \"x-auto-generated\": true,\n title: \"Document ID\",\n description: \"Unique identifier for the document\",\n },\n kb_id: {\n type: \"string\",\n title: \"Knowledge Base ID\",\n description: \"Owning knowledge base identifier\",\n },\n data: {\n type: \"string\",\n title: \"Document Data\",\n description: \"JSON-serialized document\",\n },\n metadata: {\n type: \"object\",\n title: \"Metadata\",\n description: \"Metadata of the document\",\n },\n },\n required: [\"doc_id\", \"kb_id\", \"data\"],\n additionalProperties: true,\n} as const satisfies DataPortSchemaObject;\n\n/**\n * Augmented chunk vector storage schema with kb_id column for shared-table mode.\n */\nexport const SharedChunkVectorStorageSchema = {\n type: \"object\",\n properties: {\n chunk_id: { type: \"string\", \"x-auto-generated\": true },\n kb_id: { type: \"string\" },\n doc_id: { type: \"string\" },\n vector: TypedArraySchema(),\n metadata: { type: \"object\", format: \"metadata\", additionalProperties: true },\n },\n required: [\"chunk_id\", \"kb_id\", \"doc_id\", \"vector\", \"metadata\"],\n additionalProperties: false,\n} as const satisfies DataPortSchemaObject;\n\n/**\n * Composite primary key for shared document table — includes `kb_id` to prevent\n * cross-KB key collisions when multiple knowledge bases share the same table.\n */\nexport const SharedDocumentPrimaryKey = [\"kb_id\", \"doc_id\"] as const;\nexport type SharedDocumentPrimaryKey = typeof SharedDocumentPrimaryKey;\n\n/**\n * Composite primary key for shared chunk table — includes `kb_id` to prevent\n * cross-KB key collisions when multiple knowledge bases share the same table.\n */\nexport const SharedChunkPrimaryKey = [\"kb_id\", \"chunk_id\"] as const;\nexport type SharedChunkPrimaryKey = typeof SharedChunkPrimaryKey;\n\n/**\n * Index definitions for efficient KB-scoped queries on shared document table.\n */\nexport const SharedDocumentIndexes = [[\"kb_id\"]] as const satisfies readonly (\n | keyof any\n | readonly (keyof any)[]\n)[];\n\n/**\n * Index definitions for efficient KB-scoped queries on shared chunk table.\n */\nexport const SharedChunkIndexes = [[\"kb_id\"], [\"kb_id\", \"doc_id\"]] as const satisfies readonly (\n | keyof any\n | readonly (keyof any)[]\n)[];\n",
11
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DataPortSchemaObject, FromSchema } from \"@workglow/util/schema\";\nimport { SHARED_CHUNK_TABLE, SHARED_DOCUMENT_TABLE } from \"./SharedTableSchemas\";\n\n/**\n * Schema for persisting KnowledgeBase metadata to tabular storage.\n */\nexport const KnowledgeBaseRecordSchema = {\n type: \"object\",\n properties: {\n kb_id: { type: \"string\" },\n title: { type: \"string\" },\n description: { type: \"string\" },\n vector_dimensions: { type: \"integer\" },\n document_table: { type: \"string\" },\n chunk_table: { type: \"string\" },\n created_at: { type: \"string\" },\n updated_at: { type: \"string\" },\n },\n required: [\n \"kb_id\",\n \"title\",\n \"description\",\n \"vector_dimensions\",\n \"document_table\",\n \"chunk_table\",\n \"created_at\",\n \"updated_at\",\n ],\n additionalProperties: false,\n} as const satisfies DataPortSchemaObject;\n\nexport type KnowledgeBaseRecord = FromSchema<typeof KnowledgeBaseRecordSchema>;\nexport const KnowledgeBasePrimaryKeyNames = [\"kb_id\"] as const;\n\n/**\n * Generates SQL-safe table names for a knowledge base's document and chunk storage.\n */\nexport function knowledgeBaseTableNames(kbId: string): {\n readonly documentTable: string;\n readonly chunkTable: string;\n} {\n const safe = kbId.replace(/[^a-zA-Z0-9_]/g, \"_\");\n return {\n documentTable: `kb_docs_${safe}`,\n chunkTable: `kb_chunks_${safe}`,\n };\n}\n\n/**\n * Checks whether a KnowledgeBaseRecord uses shared-table mode.\n */\nexport function isSharedTableMode(record: KnowledgeBaseRecord): boolean {\n return (\n record.document_table === SHARED_DOCUMENT_TABLE && record.chunk_table === SHARED_CHUNK_TABLE\n );\n}\n",
12
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ITabularStorage } from \"@workglow/storage\";\nimport { EventEmitter } from \"@workglow/util\";\nimport type { EventParameters } from \"@workglow/util\";\n\nimport { KnowledgeBasePrimaryKeyNames, KnowledgeBaseRecordSchema } from \"./KnowledgeBaseSchema\";\nimport type { KnowledgeBaseRecord } from \"./KnowledgeBaseSchema\";\n\n/**\n * Events that can be emitted by the KnowledgeBaseRepository\n */\n\nexport type KnowledgeBaseEventListeners = {\n knowledge_base_added: (record: KnowledgeBaseRecord) => void;\n knowledge_base_removed: (record: KnowledgeBaseRecord) => void;\n knowledge_base_updated: (record: KnowledgeBaseRecord) => void;\n};\n\nexport type KnowledgeBaseEvents = keyof KnowledgeBaseEventListeners;\n\nexport type KnowledgeBaseEventListener<Event extends KnowledgeBaseEvents> =\n KnowledgeBaseEventListeners[Event];\n\nexport type KnowledgeBaseEventParameters<Event extends KnowledgeBaseEvents> = EventParameters<\n KnowledgeBaseEventListeners,\n Event\n>;\n\n/**\n * Repository for persisting KnowledgeBase metadata to tabular storage.\n * Follows the same pattern as ModelRepository.\n */\nexport class KnowledgeBaseRepository {\n /**\n * Storage for KnowledgeBase records\n */\n protected readonly storage: ITabularStorage<\n typeof KnowledgeBaseRecordSchema,\n typeof KnowledgeBasePrimaryKeyNames\n >;\n\n constructor(\n storage: ITabularStorage<typeof KnowledgeBaseRecordSchema, typeof KnowledgeBasePrimaryKeyNames>\n ) {\n this.storage = storage;\n }\n\n /** Event emitter for repository events */\n protected events = new EventEmitter<KnowledgeBaseEventListeners>();\n\n /**\n * Sets up the database for the repository.\n * Must be called before using any other methods.\n */\n async setupDatabase(): Promise<void> {\n await this.storage.setupDatabase?.();\n }\n\n /**\n * Registers an event listener for the specified event\n */\n on<Event extends KnowledgeBaseEvents>(name: Event, fn: KnowledgeBaseEventListener<Event>) {\n this.events.on(name, fn);\n }\n\n /**\n * Removes an event listener for the specified event\n */\n off<Event extends KnowledgeBaseEvents>(name: Event, fn: KnowledgeBaseEventListener<Event>) {\n this.events.off(name, fn);\n }\n\n /**\n * Adds an event listener that will only be called once\n */\n once<Event extends KnowledgeBaseEvents>(name: Event, fn: KnowledgeBaseEventListener<Event>) {\n this.events.once(name, fn);\n }\n\n /**\n * Returns when the event was emitted (promise form of once)\n */\n waitOn<Event extends KnowledgeBaseEvents>(name: Event) {\n return this.events.waitOn(name);\n }\n\n /**\n * Adds a new knowledge base record to the repository\n */\n async addKnowledgeBase(record: KnowledgeBaseRecord): Promise<KnowledgeBaseRecord> {\n await this.storage.put(record);\n this.events.emit(\"knowledge_base_added\", record);\n return record;\n }\n\n /**\n * Removes a knowledge base record from the repository\n */\n async removeKnowledgeBase(kb_id: string): Promise<void> {\n const record = await this.storage.get({ kb_id });\n if (!record) {\n throw new Error(`KnowledgeBase with id \"${kb_id}\" not found`);\n }\n await this.storage.delete({ kb_id });\n this.events.emit(\"knowledge_base_removed\", record);\n }\n\n /**\n * Retrieves a knowledge base record by ID\n */\n async getKnowledgeBase(kb_id: string): Promise<KnowledgeBaseRecord | undefined> {\n if (typeof kb_id !== \"string\") return undefined;\n const record = await this.storage.get({ kb_id });\n return record ?? undefined;\n }\n\n /**\n * Enumerates all knowledge base records\n */\n async enumerateAll(): Promise<KnowledgeBaseRecord[]> {\n const records = await this.storage.getAll();\n if (!records || records.length === 0) return [];\n return records;\n }\n\n /**\n * Gets the total number of knowledge base records\n */\n async size(): Promise<number> {\n return await this.storage.size();\n }\n}\n",
12
13
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { InMemoryTabularStorage } from \"@workglow/storage\";\nimport { KnowledgeBaseRepository } from \"./KnowledgeBaseRepository\";\nimport { KnowledgeBasePrimaryKeyNames, KnowledgeBaseRecordSchema } from \"./KnowledgeBaseSchema\";\n\n/**\n * In-memory implementation of a knowledge base repository.\n */\nexport class InMemoryKnowledgeBaseRepository extends KnowledgeBaseRepository {\n constructor() {\n super(new InMemoryTabularStorage(KnowledgeBaseRecordSchema, KnowledgeBasePrimaryKeyNames));\n }\n}\n",
13
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n createServiceToken,\n globalServiceRegistry,\n registerInputCompactor,\n registerInputResolver,\n ServiceRegistry,\n} from \"@workglow/util\";\nimport { InMemoryKnowledgeBaseRepository } from \"./InMemoryKnowledgeBaseRepository\";\nimport type { KnowledgeBase } from \"./KnowledgeBase\";\nimport { KnowledgeBaseRepository } from \"./KnowledgeBaseRepository\";\nimport { knowledgeBaseTableNames, type KnowledgeBaseRecord } from \"./KnowledgeBaseSchema\";\n\n/**\n * Service token for the knowledge base registry\n * Maps knowledge base IDs to KnowledgeBase instances\n */\nexport const KNOWLEDGE_BASES =\n createServiceToken<Map<string, KnowledgeBase>>(\"knowledge-base.registry\");\n\n/**\n * Service token for the knowledge base repository\n */\nexport const KNOWLEDGE_BASE_REPOSITORY = createServiceToken<KnowledgeBaseRepository>(\n \"knowledge-base.repository\"\n);\n\n// Register default factory for live KB map if not already registered\nif (!globalServiceRegistry.has(KNOWLEDGE_BASES)) {\n globalServiceRegistry.register(\n KNOWLEDGE_BASES,\n (): Map<string, KnowledgeBase> => new Map(),\n true\n );\n}\n\n// Register default factory for KB repository if not already registered\nif (!globalServiceRegistry.has(KNOWLEDGE_BASE_REPOSITORY)) {\n globalServiceRegistry.register(\n KNOWLEDGE_BASE_REPOSITORY,\n (): KnowledgeBaseRepository => new InMemoryKnowledgeBaseRepository(),\n true\n );\n}\n\n/**\n * Gets the global knowledge base registry\n */\nexport function getGlobalKnowledgeBases(): Map<string, KnowledgeBase> {\n return globalServiceRegistry.get(KNOWLEDGE_BASES);\n}\n\n/**\n * Gets the global knowledge base repository instance\n */\nexport function getGlobalKnowledgeBaseRepository(): KnowledgeBaseRepository {\n return globalServiceRegistry.get(KNOWLEDGE_BASE_REPOSITORY);\n}\n\n/**\n * Sets the global knowledge base repository instance\n */\nexport function setGlobalKnowledgeBaseRepository(repository: KnowledgeBaseRepository): void {\n globalServiceRegistry.registerInstance(KNOWLEDGE_BASE_REPOSITORY, repository);\n}\n\n/**\n * Registers a knowledge base globally by ID.\n * Adds to both the live Map and the persistent repository.\n */\nexport async function registerKnowledgeBase(id: string, kb: KnowledgeBase): Promise<void> {\n const kbs = getGlobalKnowledgeBases();\n\n const now = new Date().toISOString();\n const tableNames = knowledgeBaseTableNames(id);\n const record: KnowledgeBaseRecord = {\n kb_id: id,\n title: kb.title,\n description: kb.description,\n vector_dimensions: kb.getVectorDimensions(),\n document_table: tableNames.documentTable,\n chunk_table: tableNames.chunkTable,\n created_at: now,\n updated_at: now,\n };\n\n // Write to persistent repository first so a failure doesn't leave stale in-memory state\n const repo = getGlobalKnowledgeBaseRepository();\n await repo.addKnowledgeBase(record);\n\n // Only add to live map after successful persistence\n kbs.set(id, kb);\n}\n\n/**\n * Gets a knowledge base by ID from the global registry\n */\nexport function getKnowledgeBase(id: string): KnowledgeBase | undefined {\n return getGlobalKnowledgeBases().get(id);\n}\n\n/**\n * Resolves a knowledge base ID from the registry.\n * Used by the input resolver system.\n */\nasync function resolveKnowledgeBaseFromRegistry(\n id: string,\n format: string,\n registry: ServiceRegistry\n): Promise<KnowledgeBase> {\n const kbs = registry.has(KNOWLEDGE_BASES)\n ? registry.get<Map<string, KnowledgeBase>>(KNOWLEDGE_BASES)\n : getGlobalKnowledgeBases();\n\n const kb = kbs.get(id);\n if (!kb) {\n throw new Error(`Knowledge base \"${id}\" not found in registry`);\n }\n return kb;\n}\n\n// Register the resolver for format: \"knowledge-base\"\nregisterInputResolver(\"knowledge-base\", resolveKnowledgeBaseFromRegistry);\n\n// Register the compactor — reverse map lookup by identity\nregisterInputCompactor(\"knowledge-base\", (value, _format, registry) => {\n const kbs = registry.has(KNOWLEDGE_BASES)\n ? registry.get<Map<string, KnowledgeBase>>(KNOWLEDGE_BASES)\n : getGlobalKnowledgeBases();\n\n for (const [id, kb] of kbs) {\n if (kb === value) return id;\n }\n return undefined;\n});\n",
14
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n createServiceToken,\n globalServiceRegistry,\n registerInputCompactor,\n registerInputResolver,\n ServiceRegistry,\n} from \"@workglow/util\";\nimport { InMemoryKnowledgeBaseRepository } from \"./InMemoryKnowledgeBaseRepository\";\nimport type { KnowledgeBase } from \"./KnowledgeBase\";\nimport { KnowledgeBaseRepository } from \"./KnowledgeBaseRepository\";\nimport type { KnowledgeBaseRecord } from \"./KnowledgeBaseSchema\";\nimport { knowledgeBaseTableNames } from \"./KnowledgeBaseSchema\";\nimport { SHARED_CHUNK_TABLE, SHARED_DOCUMENT_TABLE } from \"./SharedTableSchemas\";\n\n/**\n * Service token for the knowledge base registry\n * Maps knowledge base IDs to KnowledgeBase instances\n */\nexport const KNOWLEDGE_BASES =\n createServiceToken<Map<string, KnowledgeBase>>(\"knowledge-base.registry\");\n\n/**\n * Service token for the knowledge base repository\n */\nexport const KNOWLEDGE_BASE_REPOSITORY = createServiceToken<KnowledgeBaseRepository>(\n \"knowledge-base.repository\"\n);\n\n// Register default factory for live KB map if not already registered\nglobalServiceRegistry.registerIfAbsent(\n KNOWLEDGE_BASES,\n (): Map<string, KnowledgeBase> => new Map(),\n true\n);\n\n// Register default factory for KB repository if not already registered\nglobalServiceRegistry.registerIfAbsent(\n KNOWLEDGE_BASE_REPOSITORY,\n (): KnowledgeBaseRepository => new InMemoryKnowledgeBaseRepository(),\n true\n);\n\n/**\n * Gets the global knowledge base registry\n */\nexport function getGlobalKnowledgeBases(): Map<string, KnowledgeBase> {\n return globalServiceRegistry.get(KNOWLEDGE_BASES);\n}\n\n/**\n * Gets the global knowledge base repository instance\n */\nexport function getGlobalKnowledgeBaseRepository(): KnowledgeBaseRepository {\n return globalServiceRegistry.get(KNOWLEDGE_BASE_REPOSITORY);\n}\n\n/**\n * Sets the global knowledge base repository instance\n */\nexport function setGlobalKnowledgeBaseRepository(repository: KnowledgeBaseRepository): void {\n globalServiceRegistry.registerInstance(KNOWLEDGE_BASE_REPOSITORY, repository);\n}\n\nexport interface RegisterKnowledgeBaseOptions {\n /** When true, record uses shared table names instead of per-KB table names. */\n readonly sharedTables?: boolean;\n}\n\n/**\n * Per-ID promise chain that serializes register/unregister operations\n * on the same knowledge base ID, preventing Map/repo divergence\n * during async interleaving.\n */\nconst pendingOps = new Map<string, Promise<void>>();\n\n/**\n * Enqueues an async operation for the given ID so that concurrent\n * calls on the same ID execute sequentially.\n */\nfunction withIdLock(id: string, fn: () => Promise<void>): Promise<void> {\n const prev = pendingOps.get(id) ?? Promise.resolve();\n const next = prev.then(fn, fn);\n pendingOps.set(id, next);\n const cleanup = () => {\n if (pendingOps.get(id) === next) {\n pendingOps.delete(id);\n }\n };\n next.finally(cleanup);\n return next;\n}\n\n/**\n * Registers a knowledge base globally by ID.\n * Adds to both the live Map and the persistent repository.\n * Serialized per-ID to prevent Map/repo divergence on concurrent calls.\n */\n\nexport function registerKnowledgeBase(\n id: string,\n kb: KnowledgeBase,\n options?: RegisterKnowledgeBaseOptions\n): Promise<void> {\n return withIdLock(id, async () => {\n const kbs = getGlobalKnowledgeBases();\n\n const now = new Date().toISOString();\n const useShared = options?.sharedTables === true;\n const tableNames = useShared\n ? { documentTable: SHARED_DOCUMENT_TABLE, chunkTable: SHARED_CHUNK_TABLE }\n : knowledgeBaseTableNames(id);\n const record: KnowledgeBaseRecord = {\n kb_id: id,\n title: kb.title,\n description: kb.description,\n vector_dimensions: kb.getVectorDimensions(),\n document_table: tableNames.documentTable,\n chunk_table: tableNames.chunkTable,\n created_at: now,\n updated_at: now,\n };\n\n // Write to persistent repository first so a failure doesn't leave stale in-memory state\n const repo = getGlobalKnowledgeBaseRepository();\n await repo.addKnowledgeBase(record);\n\n // Only add to live map after successful persistence\n kbs.set(id, kb);\n });\n}\n\n/**\n * Unregisters a knowledge base by ID.\n * Removes from both the persistent repository and the live Map.\n * Serialized per-ID to prevent Map/repo divergence on concurrent calls.\n */\nexport function unregisterKnowledgeBase(id: string): Promise<void> {\n return withIdLock(id, async () => {\n const repo = getGlobalKnowledgeBaseRepository();\n await repo.removeKnowledgeBase(id);\n\n const kbs = getGlobalKnowledgeBases();\n kbs.delete(id);\n });\n}\n\n/**\n * Deregisters a knowledge base by ID.\n * Removes from both the live Map and the persistent repository.\n */\nexport async function deregisterKnowledgeBase(id: string): Promise<void> {\n // Remove from persistent repository first so a failure doesn't leave stale in-memory state\n const repo = getGlobalKnowledgeBaseRepository();\n await repo.removeKnowledgeBase(id);\n\n const kbs = getGlobalKnowledgeBases();\n kbs.delete(id);\n}\n\n/**\n * Gets a knowledge base by ID from the global registry\n */\nexport function getKnowledgeBase(id: string): KnowledgeBase | undefined {\n return getGlobalKnowledgeBases().get(id);\n}\n\n/**\n * Resolves a knowledge base ID from the registry.\n * Used by the input resolver system.\n */\nasync function resolveKnowledgeBaseFromRegistry(\n id: string,\n format: string,\n registry: ServiceRegistry\n): Promise<KnowledgeBase> {\n const kbs = registry.has(KNOWLEDGE_BASES)\n ? registry.get<Map<string, KnowledgeBase>>(KNOWLEDGE_BASES)\n : getGlobalKnowledgeBases();\n\n const kb = kbs.get(id);\n if (!kb) {\n throw new Error(`Knowledge base \"${id}\" not found in registry`);\n }\n return kb;\n}\n\n// Register the resolver for format: \"knowledge-base\"\nregisterInputResolver(\"knowledge-base\", resolveKnowledgeBaseFromRegistry);\n\n// Register the compactor — reverse map lookup by identity\nregisterInputCompactor(\"knowledge-base\", (value, _format, registry) => {\n const kbs = registry.has(KNOWLEDGE_BASES)\n ? registry.get<Map<string, KnowledgeBase>>(KNOWLEDGE_BASES)\n : getGlobalKnowledgeBases();\n\n for (const [id, kb] of kbs) {\n if (kb === value) return id;\n }\n return undefined;\n});\n",
14
15
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { InMemoryTabularStorage, InMemoryVectorStorage } from \"@workglow/storage\";\nimport type { TypedArray } from \"@workglow/util/schema\";\nimport { ChunkVectorPrimaryKey, ChunkVectorStorageSchema } from \"../chunk/ChunkVectorStorageSchema\";\nimport type { ChunkVectorStorage } from \"../chunk/ChunkVectorStorageSchema\";\nimport { DocumentStorageKey, DocumentStorageSchema } from \"../document/DocumentStorageSchema\";\nimport type { DocumentTabularStorage } from \"../document/DocumentStorageSchema\";\nimport { KnowledgeBase } from \"./KnowledgeBase\";\nimport { registerKnowledgeBase } from \"./KnowledgeBaseRegistry\";\n\nexport interface CreateKnowledgeBaseOptions {\n readonly name: string;\n readonly vectorDimensions: number;\n readonly vectorType?: { new (array: number[]): TypedArray };\n readonly register?: boolean;\n readonly title?: string;\n readonly description?: string;\n}\n\n/**\n * Factory function to create a KnowledgeBase with minimal configuration.\n *\n * @example\n * ```typescript\n * const kb = await createKnowledgeBase({\n * name: \"my-kb\",\n * vectorDimensions: 1024,\n * });\n * ```\n */\nexport async function createKnowledgeBase(\n options: CreateKnowledgeBaseOptions\n): Promise<KnowledgeBase> {\n const {\n name,\n vectorDimensions,\n vectorType = Float32Array,\n register: shouldRegister = true,\n title,\n description,\n } = options;\n\n if (!name || typeof name !== \"string\" || name.trim().length === 0) {\n throw new Error(\"createKnowledgeBase: 'name' must be a non-empty string\");\n }\n if (\n typeof vectorDimensions !== \"number\" ||\n !Number.isInteger(vectorDimensions) ||\n vectorDimensions < 1\n ) {\n throw new Error(\"createKnowledgeBase: 'vectorDimensions' must be a positive integer\");\n }\n\n const tabularStorage = new InMemoryTabularStorage(DocumentStorageSchema, DocumentStorageKey);\n await tabularStorage.setupDatabase();\n\n const vectorStorage = new InMemoryVectorStorage(\n ChunkVectorStorageSchema,\n ChunkVectorPrimaryKey,\n [],\n vectorDimensions,\n vectorType\n );\n await vectorStorage.setupDatabase();\n\n const kb = new KnowledgeBase(\n name,\n tabularStorage as unknown as DocumentTabularStorage,\n vectorStorage as unknown as ChunkVectorStorage,\n title,\n description\n );\n\n if (shouldRegister) {\n await registerKnowledgeBase(name, kb);\n }\n\n return kb;\n}\n",
15
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { ITabularStorage } from \"@workglow/storage\";\nimport {\n TypedArraySchemaOptions,\n type DataPortSchemaObject,\n type FromSchema,\n} from \"@workglow/util/schema\";\n\n/**\n * Schema for storing documents in tabular storage\n */\nexport const DocumentStorageSchema = {\n type: \"object\",\n properties: {\n doc_id: {\n type: \"string\",\n \"x-auto-generated\": true,\n title: \"Document ID\",\n description: \"Unique identifier for the document\",\n },\n data: {\n type: \"string\",\n title: \"Document Data\",\n description: \"JSON-serialized document\",\n },\n metadata: {\n type: \"object\",\n title: \"Metadata\",\n description: \"Metadata of the document\",\n },\n },\n required: [\"doc_id\", \"data\"],\n additionalProperties: true,\n} as const satisfies DataPortSchemaObject;\nexport type DocumentStorageSchema = typeof DocumentStorageSchema;\n\nexport const DocumentStorageKey = [\"doc_id\"] as const;\nexport type DocumentStorageKey = typeof DocumentStorageKey;\n\nexport type DocumentStorageEntity = FromSchema<DocumentStorageSchema, TypedArraySchemaOptions>;\n\n/**\n * Type for inserting documents - doc_id is optional (auto-generated)\n */\nexport type InsertDocumentStorageEntity = Omit<DocumentStorageEntity, \"doc_id\"> &\n Partial<Pick<DocumentStorageEntity, \"doc_id\">>;\n\nexport type DocumentTabularStorage = ITabularStorage<\n typeof DocumentStorageSchema,\n DocumentStorageKey,\n DocumentStorageEntity\n>;\n",
16
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { ITabularStorage } from \"@workglow/storage\";\nimport { TypedArraySchemaOptions } from \"@workglow/util/schema\";\nimport type { DataPortSchemaObject, FromSchema } from \"@workglow/util/schema\";\n\n/**\n * Schema for storing documents in tabular storage\n */\nexport const DocumentStorageSchema = {\n type: \"object\",\n properties: {\n doc_id: {\n type: \"string\",\n \"x-auto-generated\": true,\n title: \"Document ID\",\n description: \"Unique identifier for the document\",\n },\n data: {\n type: \"string\",\n title: \"Document Data\",\n description: \"JSON-serialized document\",\n },\n metadata: {\n type: \"object\",\n title: \"Metadata\",\n description: \"Metadata of the document\",\n },\n },\n required: [\"doc_id\", \"data\"],\n additionalProperties: true,\n} as const satisfies DataPortSchemaObject;\nexport type DocumentStorageSchema = typeof DocumentStorageSchema;\n\nexport const DocumentStorageKey = [\"doc_id\"] as const;\nexport type DocumentStorageKey = typeof DocumentStorageKey;\n\nexport type DocumentStorageEntity = FromSchema<DocumentStorageSchema, TypedArraySchemaOptions>;\n\n/**\n * Type for inserting documents - doc_id is optional (auto-generated)\n */\nexport type InsertDocumentStorageEntity = Omit<DocumentStorageEntity, \"doc_id\"> &\n Partial<Pick<DocumentStorageEntity, \"doc_id\">>;\n\nexport type DocumentTabularStorage = ITabularStorage<\n typeof DocumentStorageSchema,\n DocumentStorageKey,\n DocumentStorageEntity\n>;\n",
17
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n AnyTabularStorage,\n DeleteSearchCriteria,\n ITabularStorage,\n QueryOptions,\n SearchCriteria,\n TabularChangePayload,\n TabularEventListener,\n TabularEventListeners,\n TabularEventName,\n TabularEventParameters,\n TabularSubscribeOptions,\n} from \"@workglow/storage\";\nimport { EventEmitter } from \"@workglow/util\";\nimport type { DataPortSchemaObject } from \"@workglow/util/schema\";\n\n/**\n * Wrapper implementing `ITabularStorage` that delegates to an inner shared\n * storage instance, injecting `kb_id` on writes and filtering by `kb_id` on\n * reads. The outer interface does not include `kb_id` — it is transparent to\n * the `KnowledgeBase` class.\n */\nexport class ScopedTabularStorage<\n Schema extends DataPortSchemaObject,\n PrimaryKeyNames extends ReadonlyArray<keyof Schema[\"properties\"]>,\n Entity = any,\n PrimaryKey = any,\n InsertType = any,\n> implements ITabularStorage<Schema, PrimaryKeyNames, Entity, PrimaryKey, InsertType> {\n protected readonly inner: AnyTabularStorage;\n protected readonly kbId: string;\n protected readonly events = new EventEmitter<TabularEventListeners<PrimaryKey, Entity>>();\n\n constructor(inner: AnyTabularStorage, kbId: string) {\n this.inner = inner;\n this.kbId = kbId;\n }\n\n private inject(value: any): any {\n return { ...value, kb_id: this.kbId };\n }\n\n private strip(entity: any): Entity {\n if (!entity) return entity;\n const { kb_id: _, ...rest } = entity;\n return rest as Entity;\n }\n\n private stripArray(entities: any[] | undefined): Entity[] | undefined {\n if (!entities) return undefined;\n return entities.map((e) => this.strip(e));\n }\n\n async put(value: InsertType): Promise<Entity> {\n const result = await this.inner.put(this.inject(value));\n const stripped = this.strip(result);\n this.events.emit(\"put\", stripped);\n return stripped;\n }\n\n async putBulk(values: InsertType[]): Promise<Entity[]> {\n const injected = values.map((v) => this.inject(v));\n const results = await this.inner.putBulk(injected);\n const stripped = results.map((r: any) => this.strip(r));\n for (const entity of stripped) {\n this.events.emit(\"put\", entity);\n }\n return stripped;\n }\n\n async get(key: PrimaryKey): Promise<Entity | undefined> {\n const result = await this.inner.get({ ...(key as any), kb_id: this.kbId } as any);\n if (!result) return undefined;\n const stripped = this.strip(result);\n this.events.emit(\"get\", key, stripped);\n return stripped;\n }\n\n async delete(key: PrimaryKey | Entity): Promise<void> {\n await this.inner.deleteSearch({ ...(key as any), kb_id: this.kbId } as any);\n this.events.emit(\"delete\", key as keyof Entity);\n }\n\n async getAll(options?: QueryOptions<Entity>): Promise<Entity[] | undefined> {\n const results = await this.inner.query({ kb_id: this.kbId } as any, options as any);\n return this.stripArray(results);\n }\n\n async deleteAll(): Promise<void> {\n await this.inner.deleteSearch({ kb_id: this.kbId } as any);\n this.events.emit(\"clearall\");\n }\n\n // O(n) — ITabularStorage has no count() method. Uses pagination to limit peak memory.\n async size(): Promise<number> {\n let count = 0;\n const pageSize = 1000;\n let offset = 0;\n while (true) {\n const page = await this.inner.query({ kb_id: this.kbId } as any, { offset, limit: pageSize });\n if (!page || page.length === 0) break;\n count += page.length;\n if (page.length < pageSize) break;\n offset += pageSize;\n }\n return count;\n }\n\n async query(\n criteria: SearchCriteria<Entity>,\n options?: QueryOptions<Entity>\n ): Promise<Entity[] | undefined> {\n const results = await this.inner.query(\n { ...(criteria as any), kb_id: this.kbId },\n options as any\n );\n const stripped = this.stripArray(results);\n this.events.emit(\"query\", criteria as Partial<Entity>, stripped);\n return stripped;\n }\n\n async deleteSearch(criteria: DeleteSearchCriteria<Entity>): Promise<void> {\n await this.inner.deleteSearch({ ...(criteria as any), kb_id: this.kbId });\n }\n\n async getBulk(offset: number, limit: number): Promise<Entity[] | undefined> {\n const results = await this.inner.query({ kb_id: this.kbId } as any, { offset, limit });\n return this.stripArray(results);\n }\n\n async *records(pageSize: number = 100): AsyncGenerator<Entity, void, undefined> {\n if (pageSize <= 0) {\n throw new RangeError(`pageSize must be greater than 0, got ${pageSize}`);\n }\n let offset = 0;\n while (true) {\n const page = await this.getBulk(offset, pageSize);\n if (!page || page.length === 0) {\n break;\n }\n for (const entity of page) {\n yield entity;\n }\n if (page.length < pageSize) break;\n offset += pageSize;\n }\n }\n\n async *pages(pageSize: number = 100): AsyncGenerator<Entity[], void, undefined> {\n if (pageSize <= 0) {\n throw new RangeError(`pageSize must be greater than 0, got ${pageSize}`);\n }\n let offset = 0;\n while (true) {\n const page = await this.getBulk(offset, pageSize);\n if (!page || page.length === 0) {\n break;\n }\n yield page;\n if (page.length < pageSize) break;\n offset += pageSize;\n }\n }\n\n // Events — scoped via local emitter; mutation methods emit here after inner ops\n on<Event extends TabularEventName>(\n name: Event,\n fn: TabularEventListener<Event, PrimaryKey, Entity>\n ): void {\n this.events.on(name, fn);\n }\n\n off<Event extends TabularEventName>(\n name: Event,\n fn: TabularEventListener<Event, PrimaryKey, Entity>\n ): void {\n this.events.off(name, fn);\n }\n\n emit<Event extends TabularEventName>(\n name: Event,\n ...args: TabularEventParameters<Event, PrimaryKey, Entity>\n ): void {\n this.events.emit(name, ...args);\n }\n\n once<Event extends TabularEventName>(\n name: Event,\n fn: TabularEventListener<Event, PrimaryKey, Entity>\n ): void {\n this.events.once(name, fn);\n }\n\n waitOn<Event extends TabularEventName>(\n name: Event\n ): Promise<TabularEventParameters<Event, PrimaryKey, Entity>> {\n return this.events.waitOn(name);\n }\n\n subscribeToChanges(\n callback: (change: TabularChangePayload<Entity>) => void,\n options?: TabularSubscribeOptions\n ): () => void {\n return this.inner.subscribeToChanges((change: TabularChangePayload<any>) => {\n const newKbId = change.new?.kb_id;\n const oldKbId = change.old?.kb_id;\n if (newKbId !== undefined && newKbId !== this.kbId) return;\n if (oldKbId !== undefined && oldKbId !== this.kbId) return;\n if (newKbId === undefined && oldKbId === undefined) return;\n callback({\n type: change.type,\n ...(change.old ? { old: this.strip(change.old) } : {}),\n ...(change.new ? { new: this.strip(change.new) } : {}),\n } as TabularChangePayload<Entity>);\n }, options);\n }\n\n // Lifecycle — no-op for shared storage\n async setupDatabase(): Promise<void> {\n // No-op: shared storage lifecycle is managed externally\n }\n\n destroy(): void {\n // No-op: shared storage lifecycle is managed externally\n }\n\n [Symbol.dispose](): void {\n // No-op\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n // No-op\n }\n}\n",
18
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n AnyVectorStorage,\n HybridSearchOptions,\n IVectorStorage,\n VectorSearchOptions,\n} from \"@workglow/storage\";\nimport type { DataPortSchemaObject, TypedArray } from \"@workglow/util/schema\";\nimport { ScopedTabularStorage } from \"./ScopedTabularStorage\";\n\n/**\n * Wrapper extending `ScopedTabularStorage` that also implements `IVectorStorage`.\n * Delegates vector search methods to the inner shared vector storage,\n * post-filtering results by `kb_id`.\n */\nexport class ScopedVectorStorage<\n Metadata extends Record<string, unknown> | undefined,\n Schema extends DataPortSchemaObject,\n Entity = any,\n PrimaryKeyNames extends ReadonlyArray<keyof Schema[\"properties\"]> = ReadonlyArray<\n keyof Schema[\"properties\"]\n >,\n>\n extends ScopedTabularStorage<Schema, PrimaryKeyNames, Entity>\n implements IVectorStorage<Metadata, Schema, Entity, PrimaryKeyNames>\n{\n protected override readonly inner: AnyVectorStorage;\n private readonly overFetchMultiplier: number;\n\n constructor(inner: AnyVectorStorage, kbId: string, overFetchMultiplier: number = 3) {\n super(inner, kbId);\n this.inner = inner;\n this.overFetchMultiplier = overFetchMultiplier;\n }\n\n getVectorDimensions(): number {\n return this.inner.getVectorDimensions();\n }\n\n private filterAndStrip(\n results: any[],\n topK: number | undefined,\n overfetchLimit: number | undefined\n ): (Entity & { score: number })[] {\n const filtered = results.filter((r: any) => r.kb_id === this.kbId).slice(0, topK);\n\n // Only warn when cross-KB filtering is likely the culprit: the inner search\n // returned exactly as many results as we requested (overfetch limit) and\n // filtering still left us short of topK.\n if (topK && overfetchLimit && results.length >= overfetchLimit && filtered.length < topK) {\n console.warn(\n `ScopedVectorStorage: search returned ${filtered.length}/${topK} results after ` +\n `kb_id filtering. Consider increasing overFetchMultiplier (currently ${this.overFetchMultiplier}).`\n );\n }\n\n return filtered.map((r: any) => {\n const { kb_id: _, ...rest } = r;\n return rest as Entity & { score: number };\n });\n }\n\n async similaritySearch(\n query: TypedArray,\n options?: VectorSearchOptions<Metadata>\n ): Promise<(Entity & { score: number })[]> {\n const overfetchLimit = options?.topK ? options.topK * this.overFetchMultiplier : undefined;\n const results = await this.inner.similaritySearch(query, {\n ...options,\n topK: overfetchLimit,\n } as any);\n\n return this.filterAndStrip(results, options?.topK, overfetchLimit);\n }\n\n async hybridSearch(\n query: TypedArray,\n options: HybridSearchOptions<Metadata>\n ): Promise<(Entity & { score: number })[]> {\n if (typeof this.inner.hybridSearch !== \"function\") {\n throw new Error(\n \"Hybrid search is not supported by the configured chunk storage backend. \" +\n \"Please use a vector storage implementation that provides `hybridSearch`.\"\n );\n }\n const overfetchLimit = options?.topK ? options.topK * this.overFetchMultiplier : undefined;\n const results = await this.inner.hybridSearch(query, {\n ...options,\n topK: overfetchLimit,\n } as any);\n\n return this.filterAndStrip(results, options?.topK, overfetchLimit);\n }\n}\n",
16
19
  "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { JsonSchema } from \"@workglow/util/schema\";\n\n/**\n * Creates a JSON schema for a tabular dataset input.\n * The schema accepts either a string ID (resolved from registry) or a direct dataset instance.\n */\nexport function TypeTabularStorage<O extends Record<string, unknown> = {}>(options: O = {} as O) {\n return {\n title: \"Tabular Storage\",\n description: \"Storage ID or instance for tabular data storage\",\n ...options,\n format: \"storage:tabular\" as const,\n oneOf: [\n { type: \"string\" as const, title: \"Storage ID\" },\n { title: \"Storage Instance\", additionalProperties: true },\n ],\n } as const satisfies JsonSchema;\n}\n\n/**\n * Creates a JSON schema for a knowledge base input.\n * The schema accepts either a string ID (resolved from registry) or a direct KnowledgeBase instance.\n */\nexport function TypeKnowledgeBase<O extends Record<string, unknown> = {}>(options: O = {} as O) {\n return {\n title: \"Knowledge Base\",\n description: \"Knowledge base ID or instance\",\n ...options,\n format: \"knowledge-base\" as const,\n anyOf: [\n { type: \"string\" as const, title: \"Knowledge Base ID\" },\n { title: \"Knowledge Base Instance\", additionalProperties: true },\n ],\n } as const satisfies JsonSchema;\n}\n",
17
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n NodeKind,\n type DocumentNode,\n type DocumentRootNode,\n type NodeRange,\n type SectionNode,\n type TopicNode,\n} from \"./DocumentSchema\";\n\n/**\n * Approximate token counting (v1) -- ~4 characters per token.\n * Used as a fallback when no real tokenizer is available.\n */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/**\n * Helper to check if a node has children\n */\nexport function hasChildren(\n node: DocumentNode\n): node is DocumentRootNode | SectionNode | TopicNode {\n return (\n node.kind === NodeKind.DOCUMENT ||\n node.kind === NodeKind.SECTION ||\n node.kind === NodeKind.TOPIC\n );\n}\n\n/**\n * Helper to get all children of a node\n */\nexport function getChildren(node: DocumentNode): DocumentNode[] {\n if (hasChildren(node)) {\n return node.children;\n }\n return [];\n}\n\n/** Maximum recursion depth for tree traversal to prevent stack overflow */\nconst MAX_TRAVERSAL_DEPTH = 200;\n\n/**\n * Traverse document tree depth-first\n */\nexport function* traverseDepthFirst(\n node: DocumentNode,\n depth: number = 0\n): Generator<DocumentNode> {\n if (depth > MAX_TRAVERSAL_DEPTH) {\n throw new Error(`Document tree exceeds maximum depth of ${MAX_TRAVERSAL_DEPTH}`);\n }\n yield node;\n if (hasChildren(node)) {\n for (const child of node.children) {\n yield* traverseDepthFirst(child, depth + 1);\n }\n }\n}\n\n/**\n * Get node path from root to target node\n */\nexport function getNodePath(root: DocumentNode, targetNodeId: string): string[] | undefined {\n const path: string[] = [];\n\n function search(node: DocumentNode, depth: number): boolean {\n if (depth > MAX_TRAVERSAL_DEPTH) {\n throw new Error(`Document tree exceeds maximum depth of ${MAX_TRAVERSAL_DEPTH}`);\n }\n path.push(node.nodeId);\n if (node.nodeId === targetNodeId) {\n return true;\n }\n if (hasChildren(node)) {\n for (const child of node.children) {\n if (search(child, depth + 1)) {\n return true;\n }\n }\n }\n path.pop();\n return false;\n }\n\n return search(root, 0) ? path : undefined;\n}\n\n/**\n * Get document range for a node path\n */\nexport function getDocumentRange(root: DocumentNode, nodePath: string[]): NodeRange {\n let currentNode = root as DocumentRootNode | SectionNode | TopicNode;\n\n // Start from index 1 since nodePath[0] is the root\n for (let i = 1; i < nodePath.length; i++) {\n const targetId = nodePath[i];\n const children = currentNode.children;\n let found: DocumentNode | undefined;\n\n for (let j = 0; j < children.length; j++) {\n if (children[j].nodeId === targetId) {\n found = children[j];\n break;\n }\n }\n\n if (!found) {\n throw new Error(`Node with id ${targetId} not found in path`);\n }\n\n currentNode = found as DocumentRootNode | SectionNode | TopicNode;\n }\n\n return currentNode.range;\n}\n",
18
- "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { uuid4 } from \"@workglow/util\";\nimport {\n type DocumentRootNode,\n NodeKind,\n type ParagraphNode,\n type SectionNode,\n} from \"./DocumentSchema\";\n\n/**\n * Parse markdown into a hierarchical DocumentNode tree\n */\nexport class StructuralParser {\n /**\n * Parse markdown text into a hierarchical document tree.\n *\n * Note: Offsets are measured in UTF-16 code units (consistent with\n * `String.prototype.length` and `String.prototype.slice()`).\n */\n static async parseMarkdown(\n doc_id: string,\n text: string,\n title: string\n ): Promise<DocumentRootNode> {\n const lines = text.split(\"\\n\");\n let currentOffset = 0;\n\n const root: DocumentRootNode = {\n nodeId: uuid4(),\n kind: NodeKind.DOCUMENT,\n range: { startOffset: 0, endOffset: text.length },\n text: title,\n title,\n children: [],\n };\n\n let currentParentStack: Array<DocumentRootNode | SectionNode> = [root];\n let textBuffer: string[] = [];\n let textBufferStartOffset = 0;\n\n const flushTextBuffer = async () => {\n if (textBuffer.length > 0) {\n const content = textBuffer.join(\"\\n\").trim();\n if (content) {\n const paragraphStartOffset = textBufferStartOffset;\n const paragraphEndOffset = currentOffset;\n\n const paragraph: ParagraphNode = {\n nodeId: uuid4(),\n kind: NodeKind.PARAGRAPH,\n range: {\n startOffset: paragraphStartOffset,\n endOffset: paragraphEndOffset,\n },\n text: content,\n };\n\n currentParentStack[currentParentStack.length - 1].children.push(paragraph);\n }\n textBuffer = [];\n }\n };\n\n for (const line of lines) {\n const lineLength = line.length + 1; // +1 for newline\n\n // Check if line is a header\n const headerMatch = line.match(/^(#{1,6})\\s+(.*)$/);\n if (headerMatch) {\n await flushTextBuffer();\n\n const level = headerMatch[1].length;\n const headerTitle = headerMatch[2];\n\n // Pop stack until we find appropriate parent — set endOffset to currentOffset\n // (the start of this new header line) rather than text.length\n while (\n currentParentStack.length > 1 &&\n currentParentStack[currentParentStack.length - 1].kind === NodeKind.SECTION &&\n (currentParentStack[currentParentStack.length - 1] as SectionNode).level >= level\n ) {\n const poppedSection = currentParentStack.pop() as SectionNode;\n // Update endOffset of popped section to where the next section begins\n const updatedSection: SectionNode = {\n ...poppedSection,\n range: {\n ...poppedSection.range,\n endOffset: currentOffset,\n },\n };\n // Replace in parent's children\n const parent = currentParentStack[currentParentStack.length - 1];\n parent.children[parent.children.length - 1] = updatedSection;\n }\n\n const sectionStartOffset = currentOffset;\n const section: SectionNode = {\n nodeId: uuid4(),\n kind: NodeKind.SECTION,\n level,\n title: headerTitle,\n range: {\n startOffset: sectionStartOffset,\n // Will be updated to the correct endOffset when popped or at end of parsing\n endOffset: text.length,\n },\n text: headerTitle,\n children: [],\n };\n\n currentParentStack[currentParentStack.length - 1].children.push(section);\n currentParentStack.push(section);\n } else {\n // Accumulate text\n if (textBuffer.length === 0) {\n textBufferStartOffset = currentOffset;\n }\n textBuffer.push(line);\n }\n\n currentOffset += lineLength;\n }\n\n await flushTextBuffer();\n\n // Close any remaining sections — final sections extend to the end of the text\n while (currentParentStack.length > 1) {\n const section = currentParentStack.pop() as SectionNode;\n const updatedSection: SectionNode = {\n ...section,\n range: {\n ...section.range,\n endOffset: text.length,\n },\n };\n const parent = currentParentStack[currentParentStack.length - 1];\n parent.children[parent.children.length - 1] = updatedSection;\n }\n\n return root;\n }\n\n /**\n * Parse plain text into a hierarchical document tree\n * Splits by double newlines to create paragraphs\n */\n static async parsePlainText(\n doc_id: string,\n text: string,\n title: string\n ): Promise<DocumentRootNode> {\n const root: DocumentRootNode = {\n nodeId: uuid4(),\n kind: NodeKind.DOCUMENT,\n range: { startOffset: 0, endOffset: text.length },\n text: title,\n title,\n children: [],\n };\n\n // Split by double newlines to get paragraphs while tracking offsets\n const paragraphRegex = /\\n\\s*\\n/g;\n let lastIndex = 0;\n let paragraphIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = paragraphRegex.exec(text)) !== null) {\n const rawParagraph = text.slice(lastIndex, match.index);\n const paragraphText = rawParagraph.trim();\n\n if (paragraphText.length > 0) {\n const trimmedRelativeStart = rawParagraph.indexOf(paragraphText);\n const startOffset = lastIndex + trimmedRelativeStart;\n const endOffset = startOffset + paragraphText.length;\n\n const paragraph: ParagraphNode = {\n nodeId: uuid4(),\n kind: NodeKind.PARAGRAPH,\n range: {\n startOffset,\n endOffset,\n },\n text: paragraphText,\n };\n\n root.children.push(paragraph);\n paragraphIndex++;\n }\n\n lastIndex = paragraphRegex.lastIndex;\n }\n\n // Handle trailing paragraph after the last double newline, if any\n if (lastIndex < text.length) {\n const rawParagraph = text.slice(lastIndex);\n const paragraphText = rawParagraph.trim();\n\n if (paragraphText.length > 0) {\n const trimmedRelativeStart = rawParagraph.indexOf(paragraphText);\n const startOffset = lastIndex + trimmedRelativeStart;\n const endOffset = startOffset + paragraphText.length;\n\n const paragraph: ParagraphNode = {\n nodeId: uuid4(),\n kind: NodeKind.PARAGRAPH,\n range: {\n startOffset,\n endOffset,\n },\n text: paragraphText,\n };\n\n root.children.push(paragraph);\n }\n }\n return root;\n }\n\n /**\n * Auto-detect format and parse\n */\n static parse(\n doc_id: string,\n text: string,\n title: string,\n format?: \"markdown\" | \"text\"\n ): Promise<DocumentRootNode> {\n if (format === \"markdown\" || (!format && this.looksLikeMarkdown(text))) {\n return this.parseMarkdown(doc_id, text, title);\n }\n return this.parsePlainText(doc_id, text, title);\n }\n\n /**\n * Check if text contains markdown header patterns\n * Looks for lines starting with 1-6 hash symbols followed by whitespace\n */\n private static looksLikeMarkdown(text: string): boolean {\n // Check for markdown header patterns: line starting with # followed by space\n return /^#{1,6}\\s/m.test(text);\n }\n}\n"
20
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { NodeKind } from \"./DocumentSchema\";\nimport type {\n DocumentNode,\n DocumentRootNode,\n NodeRange,\n SectionNode,\n TopicNode,\n} from \"./DocumentSchema\";\n\n/**\n * Approximate token counting (v1) -- ~4 characters per token.\n * Used as a fallback when no real tokenizer is available.\n */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/**\n * Helper to check if a node has children\n */\nexport function hasChildren(\n node: DocumentNode\n): node is DocumentRootNode | SectionNode | TopicNode {\n return (\n node.kind === NodeKind.DOCUMENT ||\n node.kind === NodeKind.SECTION ||\n node.kind === NodeKind.TOPIC\n );\n}\n\n/**\n * Helper to get all children of a node\n */\nexport function getChildren(node: DocumentNode): DocumentNode[] {\n if (hasChildren(node)) {\n return node.children;\n }\n return [];\n}\n\n/** Maximum recursion depth for tree traversal to prevent stack overflow */\nconst MAX_TRAVERSAL_DEPTH = 200;\n\n/**\n * Traverse document tree depth-first\n */\nexport function* traverseDepthFirst(\n node: DocumentNode,\n depth: number = 0\n): Generator<DocumentNode> {\n if (depth > MAX_TRAVERSAL_DEPTH) {\n throw new Error(`Document tree exceeds maximum depth of ${MAX_TRAVERSAL_DEPTH}`);\n }\n yield node;\n if (hasChildren(node)) {\n for (const child of node.children) {\n yield* traverseDepthFirst(child, depth + 1);\n }\n }\n}\n\n/**\n * Get node path from root to target node\n */\nexport function getNodePath(root: DocumentNode, targetNodeId: string): string[] | undefined {\n const path: string[] = [];\n\n function search(node: DocumentNode, depth: number): boolean {\n if (depth > MAX_TRAVERSAL_DEPTH) {\n throw new Error(`Document tree exceeds maximum depth of ${MAX_TRAVERSAL_DEPTH}`);\n }\n path.push(node.nodeId);\n if (node.nodeId === targetNodeId) {\n return true;\n }\n if (hasChildren(node)) {\n for (const child of node.children) {\n if (search(child, depth + 1)) {\n return true;\n }\n }\n }\n path.pop();\n return false;\n }\n\n return search(root, 0) ? path : undefined;\n}\n\n/**\n * Get document range for a node path\n */\nexport function getDocumentRange(root: DocumentNode, nodePath: string[]): NodeRange {\n let currentNode = root as DocumentRootNode | SectionNode | TopicNode;\n\n // Start from index 1 since nodePath[0] is the root\n for (let i = 1; i < nodePath.length; i++) {\n const targetId = nodePath[i];\n const children = currentNode.children;\n let found: DocumentNode | undefined;\n\n for (let j = 0; j < children.length; j++) {\n if (children[j].nodeId === targetId) {\n found = children[j];\n break;\n }\n }\n\n if (!found) {\n throw new Error(`Node with id ${targetId} not found in path`);\n }\n\n currentNode = found as DocumentRootNode | SectionNode | TopicNode;\n }\n\n return currentNode.range;\n}\n",
21
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { uuid4 } from \"@workglow/util\";\nimport { NodeKind } from \"./DocumentSchema\";\nimport type { DocumentRootNode, ParagraphNode, SectionNode } from \"./DocumentSchema\";\n\n/**\n * Parse markdown into a hierarchical DocumentNode tree\n */\nexport class StructuralParser {\n /**\n * Parse markdown text into a hierarchical document tree.\n *\n * Note: Offsets are measured in UTF-16 code units (consistent with\n * `String.prototype.length` and `String.prototype.slice()`).\n */\n static async parseMarkdown(\n doc_id: string,\n text: string,\n title: string\n ): Promise<DocumentRootNode> {\n const lines = text.split(\"\\n\");\n let currentOffset = 0;\n\n const root: DocumentRootNode = {\n nodeId: uuid4(),\n kind: NodeKind.DOCUMENT,\n range: { startOffset: 0, endOffset: text.length },\n text: title,\n title,\n children: [],\n };\n\n let currentParentStack: Array<DocumentRootNode | SectionNode> = [root];\n let textBuffer: string[] = [];\n let textBufferStartOffset = 0;\n\n const flushTextBuffer = async () => {\n if (textBuffer.length > 0) {\n const content = textBuffer.join(\"\\n\").trim();\n if (content) {\n const paragraphStartOffset = textBufferStartOffset;\n const paragraphEndOffset = currentOffset;\n\n const paragraph: ParagraphNode = {\n nodeId: uuid4(),\n kind: NodeKind.PARAGRAPH,\n range: {\n startOffset: paragraphStartOffset,\n endOffset: paragraphEndOffset,\n },\n text: content,\n };\n\n currentParentStack[currentParentStack.length - 1].children.push(paragraph);\n }\n textBuffer = [];\n }\n };\n\n for (const line of lines) {\n const lineLength = line.length + 1; // +1 for newline\n\n // Check if line is a header\n const headerMatch = line.match(/^(#{1,6})\\s+(.*)$/);\n if (headerMatch) {\n await flushTextBuffer();\n\n const level = headerMatch[1].length;\n const headerTitle = headerMatch[2];\n\n // Pop stack until we find appropriate parent — set endOffset to currentOffset\n // (the start of this new header line) rather than text.length\n while (\n currentParentStack.length > 1 &&\n currentParentStack[currentParentStack.length - 1].kind === NodeKind.SECTION &&\n (currentParentStack[currentParentStack.length - 1] as SectionNode).level >= level\n ) {\n const poppedSection = currentParentStack.pop() as SectionNode;\n // Update endOffset of popped section to where the next section begins\n const updatedSection: SectionNode = {\n ...poppedSection,\n range: {\n ...poppedSection.range,\n endOffset: currentOffset,\n },\n };\n // Replace in parent's children\n const parent = currentParentStack[currentParentStack.length - 1];\n parent.children[parent.children.length - 1] = updatedSection;\n }\n\n const sectionStartOffset = currentOffset;\n const section: SectionNode = {\n nodeId: uuid4(),\n kind: NodeKind.SECTION,\n level,\n title: headerTitle,\n range: {\n startOffset: sectionStartOffset,\n // Will be updated to the correct endOffset when popped or at end of parsing\n endOffset: text.length,\n },\n text: headerTitle,\n children: [],\n };\n\n currentParentStack[currentParentStack.length - 1].children.push(section);\n currentParentStack.push(section);\n } else {\n // Accumulate text\n if (textBuffer.length === 0) {\n textBufferStartOffset = currentOffset;\n }\n textBuffer.push(line);\n }\n\n currentOffset += lineLength;\n }\n\n await flushTextBuffer();\n\n // Close any remaining sections — final sections extend to the end of the text\n while (currentParentStack.length > 1) {\n const section = currentParentStack.pop() as SectionNode;\n const updatedSection: SectionNode = {\n ...section,\n range: {\n ...section.range,\n endOffset: text.length,\n },\n };\n const parent = currentParentStack[currentParentStack.length - 1];\n parent.children[parent.children.length - 1] = updatedSection;\n }\n\n return root;\n }\n\n /**\n * Parse plain text into a hierarchical document tree\n * Splits by double newlines to create paragraphs\n */\n static async parsePlainText(\n doc_id: string,\n text: string,\n title: string\n ): Promise<DocumentRootNode> {\n const root: DocumentRootNode = {\n nodeId: uuid4(),\n kind: NodeKind.DOCUMENT,\n range: { startOffset: 0, endOffset: text.length },\n text: title,\n title,\n children: [],\n };\n\n // Split by double newlines to get paragraphs while tracking offsets\n const paragraphRegex = /\\n\\s*\\n/g;\n let lastIndex = 0;\n let paragraphIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = paragraphRegex.exec(text)) !== null) {\n const rawParagraph = text.slice(lastIndex, match.index);\n const paragraphText = rawParagraph.trim();\n\n if (paragraphText.length > 0) {\n const trimmedRelativeStart = rawParagraph.indexOf(paragraphText);\n const startOffset = lastIndex + trimmedRelativeStart;\n const endOffset = startOffset + paragraphText.length;\n\n const paragraph: ParagraphNode = {\n nodeId: uuid4(),\n kind: NodeKind.PARAGRAPH,\n range: {\n startOffset,\n endOffset,\n },\n text: paragraphText,\n };\n\n root.children.push(paragraph);\n paragraphIndex++;\n }\n\n lastIndex = paragraphRegex.lastIndex;\n }\n\n // Handle trailing paragraph after the last double newline, if any\n if (lastIndex < text.length) {\n const rawParagraph = text.slice(lastIndex);\n const paragraphText = rawParagraph.trim();\n\n if (paragraphText.length > 0) {\n const trimmedRelativeStart = rawParagraph.indexOf(paragraphText);\n const startOffset = lastIndex + trimmedRelativeStart;\n const endOffset = startOffset + paragraphText.length;\n\n const paragraph: ParagraphNode = {\n nodeId: uuid4(),\n kind: NodeKind.PARAGRAPH,\n range: {\n startOffset,\n endOffset,\n },\n text: paragraphText,\n };\n\n root.children.push(paragraph);\n }\n }\n return root;\n }\n\n /**\n * Auto-detect format and parse\n */\n static parse(\n doc_id: string,\n text: string,\n title: string,\n format?: \"markdown\" | \"text\"\n ): Promise<DocumentRootNode> {\n if (format === \"markdown\" || (!format && this.looksLikeMarkdown(text))) {\n return this.parseMarkdown(doc_id, text, title);\n }\n return this.parsePlainText(doc_id, text, title);\n }\n\n /**\n * Check if text contains markdown header patterns\n * Looks for lines starting with 1-6 hash symbols followed by whitespace\n */\n private static looksLikeMarkdown(text: string): boolean {\n // Check for markdown header patterns: line starting with # followed by space\n return /^#{1,6}\\s/m.test(text);\n }\n}\n"
19
22
  ],
20
- "mappings": "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",
21
- "debugId": "D3788ECD180FA56E64756E2164756E21",
23
+ "mappings": "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",
24
+ "debugId": "6A75C04FDEE4B40064756E2164756E21",
22
25
  "names": []
23
26
  }