@workglow/knowledge-base 0.0.122 → 0.0.124
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.js +2 -2
- package/dist/browser.js.map +9 -9
- package/dist/bun.js +2 -2
- package/dist/bun.js.map +9 -9
- package/dist/chunk/ChunkSchema.d.ts +1 -1
- package/dist/chunk/ChunkSchema.d.ts.map +1 -1
- package/dist/chunk/ChunkVectorStorageSchema.d.ts +1 -1
- package/dist/chunk/ChunkVectorStorageSchema.d.ts.map +1 -1
- package/dist/document/DocumentSchema.d.ts +1 -1
- package/dist/document/DocumentSchema.d.ts.map +1 -1
- package/dist/document/DocumentStorageSchema.d.ts +1 -1
- package/dist/document/DocumentStorageSchema.d.ts.map +1 -1
- package/dist/knowledge-base/KnowledgeBase.d.ts +1 -1
- package/dist/knowledge-base/KnowledgeBase.d.ts.map +1 -1
- package/dist/knowledge-base/KnowledgeBaseSchema.d.ts +1 -1
- package/dist/knowledge-base/KnowledgeBaseSchema.d.ts.map +1 -1
- package/dist/knowledge-base/createKnowledgeBase.d.ts +1 -1
- package/dist/knowledge-base/createKnowledgeBase.d.ts.map +1 -1
- package/dist/node.js +2 -2
- package/dist/node.js.map +9 -9
- package/package.json +7 -7
package/dist/browser.js
CHANGED
|
@@ -342,7 +342,7 @@ var ChunkRecordArraySchema = {
|
|
|
342
342
|
description: "Array of chunk records"
|
|
343
343
|
};
|
|
344
344
|
// src/chunk/ChunkVectorStorageSchema.ts
|
|
345
|
-
import { TypedArraySchema } from "@workglow/util";
|
|
345
|
+
import { TypedArraySchema } from "@workglow/util/schema";
|
|
346
346
|
var ChunkVectorStorageSchema = {
|
|
347
347
|
type: "object",
|
|
348
348
|
properties: {
|
|
@@ -1068,4 +1068,4 @@ export {
|
|
|
1068
1068
|
ChunkRecordArraySchema
|
|
1069
1069
|
};
|
|
1070
1070
|
|
|
1071
|
-
//# debugId=
|
|
1071
|
+
//# debugId=C250E01932058F3464756E2164756E21
|
package/dist/browser.js.map
CHANGED
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
"version": 3,
|
|
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"],
|
|
4
4
|
"sourcesContent": [
|
|
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\";\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
|
-
"/**\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\";\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 { TypedArraySchema, type DataPortSchemaObject, type TypedArray } from \"@workglow/util\";\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",
|
|
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
|
+
"/**\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 { TypedArraySchema, type DataPortSchemaObject, type 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
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 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\";\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 * 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\";\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",
|
|
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 * 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
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<\n typeof KnowledgeBaseRecordSchema,\n typeof KnowledgeBasePrimaryKeyNames\n >\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
12
|
"/**\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
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 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 kbs.set(id, kb);\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 const repo = getGlobalKnowledgeBaseRepository();\n await repo.addKnowledgeBase(record);\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",
|
|
14
|
-
"/**\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\";\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 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\";\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 type { JsonSchema } from \"@workglow/util\";\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",
|
|
14
|
+
"/**\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 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 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
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/**\n * Traverse document tree depth-first\n */\nexport function* traverseDepthFirst(node: DocumentNode): Generator<DocumentNode> {\n yield node;\n if (hasChildren(node)) {\n for (const child of node.children) {\n yield* traverseDepthFirst(child);\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): boolean {\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)) {\n return true;\n }\n }\n }\n path.pop();\n return false;\n }\n\n return search(root) ? 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
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 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\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\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 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\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
19
|
],
|
|
20
20
|
"mappings": "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",
|
|
21
|
-
"debugId": "
|
|
21
|
+
"debugId": "C250E01932058F3464756E2164756E21",
|
|
22
22
|
"names": []
|
|
23
23
|
}
|
package/dist/bun.js
CHANGED
|
@@ -343,7 +343,7 @@ var ChunkRecordArraySchema = {
|
|
|
343
343
|
description: "Array of chunk records"
|
|
344
344
|
};
|
|
345
345
|
// src/chunk/ChunkVectorStorageSchema.ts
|
|
346
|
-
import { TypedArraySchema } from "@workglow/util";
|
|
346
|
+
import { TypedArraySchema } from "@workglow/util/schema";
|
|
347
347
|
var ChunkVectorStorageSchema = {
|
|
348
348
|
type: "object",
|
|
349
349
|
properties: {
|
|
@@ -1069,4 +1069,4 @@ export {
|
|
|
1069
1069
|
ChunkRecordArraySchema
|
|
1070
1070
|
};
|
|
1071
1071
|
|
|
1072
|
-
//# debugId=
|
|
1072
|
+
//# debugId=C2C0AF9D153FAB9064756E2164756E21
|
package/dist/bun.js.map
CHANGED
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
"version": 3,
|
|
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"],
|
|
4
4
|
"sourcesContent": [
|
|
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\";\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
|
-
"/**\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\";\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 { TypedArraySchema, type DataPortSchemaObject, type TypedArray } from \"@workglow/util\";\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",
|
|
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
|
+
"/**\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 { TypedArraySchema, type DataPortSchemaObject, type 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
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 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\";\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 * 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\";\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",
|
|
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 * 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
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<\n typeof KnowledgeBaseRecordSchema,\n typeof KnowledgeBasePrimaryKeyNames\n >\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
12
|
"/**\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
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 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 kbs.set(id, kb);\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 const repo = getGlobalKnowledgeBaseRepository();\n await repo.addKnowledgeBase(record);\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",
|
|
14
|
-
"/**\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\";\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 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\";\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 type { JsonSchema } from \"@workglow/util\";\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",
|
|
14
|
+
"/**\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 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 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
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/**\n * Traverse document tree depth-first\n */\nexport function* traverseDepthFirst(node: DocumentNode): Generator<DocumentNode> {\n yield node;\n if (hasChildren(node)) {\n for (const child of node.children) {\n yield* traverseDepthFirst(child);\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): boolean {\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)) {\n return true;\n }\n }\n }\n path.pop();\n return false;\n }\n\n return search(root) ? 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
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 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\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\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 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\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
19
|
],
|
|
20
20
|
"mappings": "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",
|
|
21
|
-
"debugId": "
|
|
21
|
+
"debugId": "C2C0AF9D153FAB9064756E2164756E21",
|
|
22
22
|
"names": []
|
|
23
23
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import type { FromSchema } from "@workglow/util";
|
|
6
|
+
import type { FromSchema } from "@workglow/util/schema";
|
|
7
7
|
/**
|
|
8
8
|
* Schema for a unified chunk record.
|
|
9
9
|
* Replaces ChunkNode, ChunkMetadata, and EnrichedChunkMetadata with a single flat type.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChunkSchema.d.ts","sourceRoot":"","sources":["../../src/chunk/ChunkSchema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAkB,UAAU,EAAc,MAAM,
|
|
1
|
+
{"version":3,"file":"ChunkSchema.d.ts","sourceRoot":"","sources":["../../src/chunk/ChunkSchema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAkB,UAAU,EAAc,MAAM,uBAAuB,CAAC;AAGpF;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkEQ,CAAC;AAEvC,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC;AAE3E;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAKJ,CAAC"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import { IVectorStorage } from "@workglow/storage";
|
|
7
|
-
import { type TypedArray } from "@workglow/util";
|
|
7
|
+
import { type TypedArray } from "@workglow/util/schema";
|
|
8
8
|
import type { ChunkRecord } from "./ChunkSchema";
|
|
9
9
|
/**
|
|
10
10
|
* Schema for chunk vector storage with typed metadata.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChunkVectorStorageSchema.d.ts","sourceRoot":"","sources":["../../src/chunk/ChunkVectorStorageSchema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAA+C,KAAK,UAAU,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"ChunkVectorStorageSchema.d.ts","sourceRoot":"","sources":["../../src/chunk/ChunkVectorStorageSchema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAA+C,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACrG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD;;;GAGG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;CAUI,CAAC;AAC1C,MAAM,MAAM,wBAAwB,GAAG,OAAO,wBAAwB,CAAC;AAEvE,eAAO,MAAM,qBAAqB,uBAAwB,CAAC;AAC3D,MAAM,MAAM,qBAAqB,GAAG,OAAO,qBAAqB,CAAC;AAEjE,MAAM,WAAW,iBAAiB,CAChC,QAAQ,SAAS,WAAW,GAAG,WAAW,EAC1C,MAAM,SAAS,UAAU,GAAG,UAAU;IAEtC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,MAAM,uBAAuB,CACjC,QAAQ,SAAS,WAAW,GAAG,WAAW,EAC1C,MAAM,SAAS,UAAU,GAAG,UAAU,IACpC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,UAAU,CAAC,GACvD,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC;AAEjE;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAC7C,WAAW,EACX,OAAO,wBAAwB,EAC/B,iBAAiB,EACjB,qBAAqB,CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import type { FromSchema } from "@workglow/util";
|
|
6
|
+
import type { FromSchema } from "@workglow/util/schema";
|
|
7
7
|
/**
|
|
8
8
|
* Node kind discriminator for hierarchical document structure
|
|
9
9
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocumentSchema.d.ts","sourceRoot":"","sources":["../../src/document/DocumentSchema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAkB,UAAU,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"DocumentSchema.d.ts","sourceRoot":"","sources":["../../src/document/DocumentSchema.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import { ITabularStorage } from "@workglow/storage";
|
|
7
|
-
import { TypedArraySchemaOptions, type FromSchema } from "@workglow/util";
|
|
7
|
+
import { TypedArraySchemaOptions, type FromSchema } from "@workglow/util/schema";
|
|
8
8
|
/**
|
|
9
9
|
* Schema for storing documents in tabular storage
|
|
10
10
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocumentStorageSchema.d.ts","sourceRoot":"","sources":["../../src/document/DocumentStorageSchema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EACL,uBAAuB,EAEvB,KAAK,UAAU,EAChB,MAAM,
|
|
1
|
+
{"version":3,"file":"DocumentStorageSchema.d.ts","sourceRoot":"","sources":["../../src/document/DocumentStorageSchema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EACL,uBAAuB,EAEvB,KAAK,UAAU,EAChB,MAAM,uBAAuB,CAAC;AAE/B;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;CAsBO,CAAC;AAC1C,MAAM,MAAM,qBAAqB,GAAG,OAAO,qBAAqB,CAAC;AAEjE,eAAO,MAAM,kBAAkB,qBAAsB,CAAC;AACtD,MAAM,MAAM,kBAAkB,GAAG,OAAO,kBAAkB,CAAC;AAE3D,MAAM,MAAM,qBAAqB,GAAG,UAAU,CAAC,qBAAqB,EAAE,uBAAuB,CAAC,CAAC;AAE/F;;GAEG;AACH,MAAM,MAAM,2BAA2B,GAAG,IAAI,CAAC,qBAAqB,EAAE,QAAQ,CAAC,GAC7E,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE,QAAQ,CAAC,CAAC,CAAC;AAEjD,MAAM,MAAM,sBAAsB,GAAG,eAAe,CAClD,OAAO,qBAAqB,EAC5B,kBAAkB,EAClB,qBAAqB,CACtB,CAAC"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import type { HybridSearchOptions, VectorSearchOptions } from "@workglow/storage";
|
|
7
|
-
import type { TypedArray } from "@workglow/util";
|
|
7
|
+
import type { TypedArray } from "@workglow/util/schema";
|
|
8
8
|
import type { ChunkRecord } from "../chunk/ChunkSchema";
|
|
9
9
|
import type { ChunkSearchResult, ChunkVectorEntity, ChunkVectorStorage, InsertChunkVectorEntity } from "../chunk/ChunkVectorStorageSchema";
|
|
10
10
|
import { Document } from "../document/Document";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KnowledgeBase.d.ts","sourceRoot":"","sources":["../../src/knowledge-base/KnowledgeBase.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"KnowledgeBase.d.ts","sourceRoot":"","sources":["../../src/knowledge-base/KnowledgeBase.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import type { FromSchema } from "@workglow/util";
|
|
6
|
+
import type { FromSchema } from "@workglow/util/schema";
|
|
7
7
|
/**
|
|
8
8
|
* Schema for persisting KnowledgeBase metadata to tabular storage.
|
|
9
9
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KnowledgeBaseSchema.d.ts","sourceRoot":"","sources":["../../src/knowledge-base/KnowledgeBaseSchema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAwB,UAAU,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"KnowledgeBaseSchema.d.ts","sourceRoot":"","sources":["../../src/knowledge-base/KnowledgeBaseSchema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAwB,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAE9E;;GAEG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuBG,CAAC;AAE1C,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAC/E,eAAO,MAAM,4BAA4B,oBAAqB,CAAC;AAE/D;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG;IACrD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B,CAMA"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Copyright 2025 Steven Roussey <sroussey@gmail.com>
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import type { TypedArray } from "@workglow/util";
|
|
6
|
+
import type { TypedArray } from "@workglow/util/schema";
|
|
7
7
|
import { KnowledgeBase } from "./KnowledgeBase";
|
|
8
8
|
export interface CreateKnowledgeBaseOptions {
|
|
9
9
|
readonly name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createKnowledgeBase.d.ts","sourceRoot":"","sources":["../../src/knowledge-base/createKnowledgeBase.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"createKnowledgeBase.d.ts","sourceRoot":"","sources":["../../src/knowledge-base/createKnowledgeBase.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAKxD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE;QAAE,KAAK,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,CAAA;KAAE,CAAC;IAC5D,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,aAAa,CAAC,CAmCxB"}
|
package/dist/node.js
CHANGED
|
@@ -342,7 +342,7 @@ var ChunkRecordArraySchema = {
|
|
|
342
342
|
description: "Array of chunk records"
|
|
343
343
|
};
|
|
344
344
|
// src/chunk/ChunkVectorStorageSchema.ts
|
|
345
|
-
import { TypedArraySchema } from "@workglow/util";
|
|
345
|
+
import { TypedArraySchema } from "@workglow/util/schema";
|
|
346
346
|
var ChunkVectorStorageSchema = {
|
|
347
347
|
type: "object",
|
|
348
348
|
properties: {
|
|
@@ -1068,4 +1068,4 @@ export {
|
|
|
1068
1068
|
ChunkRecordArraySchema
|
|
1069
1069
|
};
|
|
1070
1070
|
|
|
1071
|
-
//# debugId=
|
|
1071
|
+
//# debugId=BCA0AF2E9AAFAEC964756E2164756E21
|
package/dist/node.js.map
CHANGED
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
"version": 3,
|
|
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"],
|
|
4
4
|
"sourcesContent": [
|
|
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\";\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
|
-
"/**\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\";\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 { TypedArraySchema, type DataPortSchemaObject, type TypedArray } from \"@workglow/util\";\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",
|
|
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
|
+
"/**\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 { TypedArraySchema, type DataPortSchemaObject, type 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
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 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\";\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 * 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\";\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",
|
|
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 * 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
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<\n typeof KnowledgeBaseRecordSchema,\n typeof KnowledgeBasePrimaryKeyNames\n >\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
12
|
"/**\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
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 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 kbs.set(id, kb);\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 const repo = getGlobalKnowledgeBaseRepository();\n await repo.addKnowledgeBase(record);\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",
|
|
14
|
-
"/**\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\";\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 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\";\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 type { JsonSchema } from \"@workglow/util\";\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",
|
|
14
|
+
"/**\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 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 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
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/**\n * Traverse document tree depth-first\n */\nexport function* traverseDepthFirst(node: DocumentNode): Generator<DocumentNode> {\n yield node;\n if (hasChildren(node)) {\n for (const child of node.children) {\n yield* traverseDepthFirst(child);\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): boolean {\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)) {\n return true;\n }\n }\n }\n path.pop();\n return false;\n }\n\n return search(root) ? 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
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 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\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\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 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\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
19
|
],
|
|
20
20
|
"mappings": "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",
|
|
21
|
-
"debugId": "
|
|
21
|
+
"debugId": "BCA0AF2E9AAFAEC964756E2164756E21",
|
|
22
22
|
"names": []
|
|
23
23
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workglow/knowledge-base",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.124",
|
|
5
5
|
"description": "Dataset package for Workglow.",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"watch": "concurrently -c 'auto' 'bun:watch-*'",
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
"test": "bun test"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
24
|
-
"@workglow/storage": "0.0.
|
|
25
|
-
"@workglow/util": "0.0.
|
|
26
|
-
"@workglow/sqlite": "0.0.
|
|
24
|
+
"@workglow/storage": "0.0.124",
|
|
25
|
+
"@workglow/util": "0.0.124",
|
|
26
|
+
"@workglow/sqlite": "0.0.124"
|
|
27
27
|
},
|
|
28
28
|
"peerDependenciesMeta": {
|
|
29
29
|
"@workglow/storage": {
|
|
@@ -37,9 +37,9 @@
|
|
|
37
37
|
}
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@workglow/storage": "0.0.
|
|
41
|
-
"@workglow/util": "0.0.
|
|
42
|
-
"@workglow/sqlite": "0.0.
|
|
40
|
+
"@workglow/storage": "0.0.124",
|
|
41
|
+
"@workglow/util": "0.0.124",
|
|
42
|
+
"@workglow/sqlite": "0.0.124"
|
|
43
43
|
},
|
|
44
44
|
"exports": {
|
|
45
45
|
".": {
|