@yolk-sdk/knowledge 0.1.0-canary.32 → 0.1.0-canary.33

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/README.md CHANGED
@@ -33,21 +33,21 @@ Optional files and chunks are modeled as `KnowledgeFile` and `KnowledgeChunk`.
33
33
 
34
34
  ## Subpaths
35
35
 
36
- | Subpath | Purpose |
37
- | --- | --- |
38
- | `@yolk-sdk/knowledge` | Root context/store/file/error helpers |
39
- | `@yolk-sdk/knowledge/documents` | Document, file, chunk, status, availability, and scope schemas |
40
- | `@yolk-sdk/knowledge/files` | File blob-store contract |
41
- | `@yolk-sdk/knowledge/store` | Document store and search-index store contracts |
42
- | `@yolk-sdk/knowledge/context` | Pinned context builder |
43
- | `@yolk-sdk/knowledge/chunking` | Text chunker contracts and defaults |
44
- | `@yolk-sdk/knowledge/embeddings` | Embedder contract and vector types |
45
- | `@yolk-sdk/knowledge/extraction` | Source/extractor contract |
46
- | `@yolk-sdk/knowledge/ingestion` | Search chunk ingestion helper |
47
- | `@yolk-sdk/knowledge/search` | Vector/hybrid chunk search helpers |
48
- | `@yolk-sdk/knowledge/summarization` | Optional title/summary service contract |
49
- | `@yolk-sdk/knowledge/agent` | `knowledge_lookup` and `knowledge_manage` tool factories |
50
- | `@yolk-sdk/knowledge/errors` | Shared error types |
36
+ | Subpath | Purpose |
37
+ | ----------------------------------- | -------------------------------------------------------------- |
38
+ | `@yolk-sdk/knowledge` | Root context/store/file/error helpers |
39
+ | `@yolk-sdk/knowledge/documents` | Document, file, chunk, status, availability, and scope schemas |
40
+ | `@yolk-sdk/knowledge/files` | File blob-store contract |
41
+ | `@yolk-sdk/knowledge/store` | Document store and search-index store contracts |
42
+ | `@yolk-sdk/knowledge/context` | Pinned context builder |
43
+ | `@yolk-sdk/knowledge/chunking` | Text chunker contracts and defaults |
44
+ | `@yolk-sdk/knowledge/embeddings` | Embedder contract and vector types |
45
+ | `@yolk-sdk/knowledge/extraction` | Source/extractor contract |
46
+ | `@yolk-sdk/knowledge/ingestion` | Search chunk ingestion helper |
47
+ | `@yolk-sdk/knowledge/search` | Vector/hybrid chunk search helpers |
48
+ | `@yolk-sdk/knowledge/summarization` | Optional title/summary service contract |
49
+ | `@yolk-sdk/knowledge/agent` | `knowledge_lookup` and `knowledge_manage` tool factories |
50
+ | `@yolk-sdk/knowledge/errors` | Shared error types |
51
51
 
52
52
  ## Imports
53
53
 
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.mts","names":[],"sources":["../src/agent.ts"],"mappings":";;;;;;KAiEY,eAAA;EAAA,SACD,IAAA;EAAA,SACA,KAAK;AAAA;AAAA,KAGJ,qBAAA;EAAA,SACD,QAAA,EAAU,iBAAA;EAAA,SACV,KAAA;EAAA,SACA,OAAA,GAAU,aAAa;IAAA,SAAY,OAAA;EAAA;AAAA;AAAA,KAGlC,sBAAA;EAAA,SACD,EAAA;EAAA,SACA,IAAA;EAAA,SACA,KAAA;AAAA;AAAA,KAGC,uBAAA;EAAA,SACD,MAAA,GAAS,KAAA;IAAA,SACP,OAAA,EAAS,OAAA;IAAA,SACT,KAAA;IAAA,SACA,KAAA;IAAA,SACA,QAAA;IAAA,SACA,aAAA;EAAA,MACL,MAAA,CAAO,MAAA,CAAO,aAAA,CAAc,qBAAA,GAAwB,SAAA;EAAA,SACjD,GAAA,GAAM,KAAA;IAAA,SACJ,OAAA,EAAS,OAAA;IAAA,SACT,EAAA;IAAA,SACA,MAAA,GAAS,eAAA;EAAA,MACd,MAAA,CAAO,MAAA,CAAO,iBAAA,EAAmB,SAAA;AAAA;AAAA,KAG7B,uBAAA;EAAA,SACD,MAAA,GAAS,KAAA;IAAA,SACP,OAAA,EAAS,OAAA;IAAA,SACT,MAAA,EAAQ,eAAA;IAAA,SACR,KAAA;IAAA,SACA,OAAA;IAAA,SACA,MAAA;IAAA,SACA,OAAA;IAAA,SACA,YAAA,EAAc,qBAAA;EAAA,MACnB,MAAA,CAAO,MAAA,CAAO,sBAAA,EAAwB,SAAA;EAAA,SACnC,eAAA,GAAkB,KAAA;IAAA,SAChB,OAAA,EAAS,OAAA;IAAA,SACT,MAAA,EAAQ,eAAA;IAAA,SACR,YAAA,EAAc,qBAAA;EAAA,MACnB,MAAA,CAAO,MAAA,CAAO,sBAAA,EAAwB,SAAA;EAAA,SACnC,UAAA,GAAa,KAAA;IAAA,SACX,OAAA,EAAS,OAAA;IAAA,SACT,MAAA,EAAQ,eAAA;IAAA,SACR,QAAA;EAAA,MACL,MAAA,CAAO,MAAA,CAAO,sBAAA,EAAwB,SAAA;EAAA,SACnC,MAAA,GAAS,KAAA;IAAA,SACP,OAAA,EAAS,OAAA;IAAA,SACT,MAAA,EAAQ,eAAA;EAAA,MACb,MAAA,CAAO,MAAA,CAAO,sBAAA,EAAwB,SAAA;AAAA;AAAA,cAoDjC,uBAAA,YACX,QAAA,EAAU,uBAAA,CAAwB,OAAA,GAClC,OAAA;EAAA,SAAoB,IAAA;EAAA,SAAwB,WAAA;AAAA,MAC3C,gBAAA,CAAiB,OAAA;AAAA,cAmCP,uBAAA,YACX,QAAA,EAAU,uBAAA,CAAwB,OAAA,GAClC,OAAA;EAAA,SAAoB,IAAA;EAAA,SAAwB,WAAA;AAAA,MAC3C,gBAAA,CAAiB,OAAA"}
1
+ {"version":3,"file":"agent.d.mts","names":[],"sources":["../src/agent.ts"],"mappings":";;;;;;KAiEY,eAAA;EAAA,SACD,IAAA;EAAA,SACA,KAAK;AAAA;AAAA,KAGJ,qBAAA;EAAA,SACD,QAAA,EAAU,iBAAA;EAAA,SACV,KAAA;EAAA,SACA,OAAA,GAAU,aAAa;IAAA,SAAY,OAAA;EAAA;AAAA;AAAA,KAGlC,sBAAA;EAAA,SACD,EAAA;EAAA,SACA,IAAA;EAAA,SACA,KAAA;AAAA;AAAA,KAGC,uBAAA;EAAA,SACD,MAAA,GAAS,KAAA;IAAA,SACP,OAAA,EAAS,OAAA;IAAA,SACT,KAAA;IAAA,SACA,KAAA;IAAA,SACA,QAAA;IAAA,SACA,aAAA;EAAA,MACL,MAAA,CAAO,MAAA,CAAO,aAAA,CAAc,qBAAA,GAAwB,SAAA;EAAA,SACjD,GAAA,GAAM,KAAA;IAAA,SACJ,OAAA,EAAS,OAAA;IAAA,SACT,EAAA;IAAA,SACA,MAAA,GAAS,eAAA;EAAA,MACd,MAAA,CAAO,MAAA,CAAO,iBAAA,EAAmB,SAAA;AAAA;AAAA,KAG7B,uBAAA;EAAA,SACD,MAAA,GAAS,KAAA;IAAA,SACP,OAAA,EAAS,OAAA;IAAA,SACT,MAAA,EAAQ,eAAA;IAAA,SACR,KAAA;IAAA,SACA,OAAA;IAAA,SACA,MAAA;IAAA,SACA,OAAA;IAAA,SACA,YAAA,EAAc,qBAAA;EAAA,MACnB,MAAA,CAAO,MAAA,CAAO,sBAAA,EAAwB,SAAA;EAAA,SACnC,eAAA,GAAkB,KAAA;IAAA,SAChB,OAAA,EAAS,OAAA;IAAA,SACT,MAAA,EAAQ,eAAA;IAAA,SACR,YAAA,EAAc,qBAAA;EAAA,MACnB,MAAA,CAAO,MAAA,CAAO,sBAAA,EAAwB,SAAA;EAAA,SACnC,UAAA,GAAa,KAAA;IAAA,SACX,OAAA,EAAS,OAAA;IAAA,SACT,MAAA,EAAQ,eAAA;IAAA,SACR,QAAA;EAAA,MACL,MAAA,CAAO,MAAA,CAAO,sBAAA,EAAwB,SAAA;EAAA,SACnC,MAAA,GAAS,KAAA;IAAA,SACP,OAAA,EAAS,OAAA;IAAA,SACT,MAAA,EAAQ,eAAA;EAAA,MACb,MAAA,CAAO,MAAA,CAAO,sBAAA,EAAwB,SAAA;AAAA;AAAA,cAuDjC,uBAAA,YACX,QAAA,EAAU,uBAAA,CAAwB,OAAA,GAClC,OAAA;EAAA,SAAoB,IAAA;EAAA,SAAwB,WAAA;AAAA,MAC3C,gBAAA,CAAiB,OAAA;AAAA,cAmCP,uBAAA,YACX,QAAA,EAAU,uBAAA,CAAwB,OAAA,GAClC,OAAA;EAAA,SAAoB,IAAA;EAAA,SAAwB,WAAA;AAAA,MAC3C,gBAAA,CAAiB,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"agent.mjs","names":[],"sources":["../src/agent.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport { ToolError } from '@yolk-sdk/agent/loop'\nimport { ToolResult } from '@yolk-sdk/agent/protocol'\nimport { makeTool, type ToolRegistration } from '@yolk-sdk/agent/tools'\nimport {\n KnowledgeAvailabilitySchema,\n NonEmptyTrimmedString,\n type KnowledgeAvailability,\n type KnowledgeDocument\n} from './documents.ts'\n\nconst OptionalNonEmptyTrimmedString = Schema.optional(Schema.NullOr(NonEmptyTrimmedString))\nconst OptionalNumber = Schema.optional(Schema.NullOr(Schema.Number))\n\nconst KnowledgeTargetParamsSchema = Schema.Struct({\n slug: NonEmptyTrimmedString,\n scope: OptionalNonEmptyTrimmedString\n})\n\nconst KnowledgeLookupParams = Schema.Union([\n Schema.Struct({\n operation: Schema.Literal('search'),\n query: NonEmptyTrimmedString,\n limit: OptionalNumber,\n minScore: OptionalNumber,\n contextChunks: OptionalNumber\n }),\n Schema.Struct({\n operation: Schema.Literal('get'),\n id: OptionalNonEmptyTrimmedString,\n target: Schema.optional(Schema.NullOr(KnowledgeTargetParamsSchema))\n })\n])\n\nconst KnowledgeManageParams = Schema.Union([\n Schema.Struct({\n operation: Schema.Literal('upsert'),\n target: KnowledgeTargetParamsSchema,\n title: NonEmptyTrimmedString,\n purpose: NonEmptyTrimmedString,\n origin: NonEmptyTrimmedString,\n content: NonEmptyTrimmedString,\n availability: KnowledgeAvailabilitySchema\n }),\n Schema.Struct({\n operation: Schema.Literal('set_availability'),\n target: KnowledgeTargetParamsSchema,\n availability: KnowledgeAvailabilitySchema\n }),\n Schema.Struct({\n operation: Schema.Literal('rename_slug'),\n target: KnowledgeTargetParamsSchema,\n nextSlug: NonEmptyTrimmedString\n }),\n Schema.Struct({\n operation: Schema.Literal('delete'),\n target: KnowledgeTargetParamsSchema\n })\n])\n\ntype KnowledgeTargetParams = typeof KnowledgeTargetParamsSchema.Type\ntype KnowledgeLookupParams = typeof KnowledgeLookupParams.Type\ntype KnowledgeManageParams = typeof KnowledgeManageParams.Type\n\nexport type KnowledgeTarget = {\n readonly slug: string\n readonly scope?: string\n}\n\nexport type KnowledgeLookupResult = {\n readonly document: KnowledgeDocument\n readonly score?: number\n readonly context?: ReadonlyArray<{ readonly content: string }>\n}\n\nexport type KnowledgeSavedDocument = {\n readonly id: string\n readonly slug: string\n readonly title: string\n}\n\nexport type KnowledgeLookupHandlers<Context> = {\n readonly search: (input: {\n readonly context: Context\n readonly query: string\n readonly limit?: number\n readonly minScore?: number\n readonly contextChunks?: number\n }) => Effect.Effect<ReadonlyArray<KnowledgeLookupResult>, ToolError>\n readonly get: (input: {\n readonly context: Context\n readonly id?: string\n readonly target?: KnowledgeTarget\n }) => Effect.Effect<KnowledgeDocument, ToolError>\n}\n\nexport type KnowledgeManageHandlers<Context> = {\n readonly upsert: (input: {\n readonly context: Context\n readonly target: KnowledgeTarget\n readonly title: string\n readonly purpose: string\n readonly origin: string\n readonly content: string\n readonly availability: KnowledgeAvailability\n }) => Effect.Effect<KnowledgeSavedDocument, ToolError>\n readonly setAvailability: (input: {\n readonly context: Context\n readonly target: KnowledgeTarget\n readonly availability: KnowledgeAvailability\n }) => Effect.Effect<KnowledgeSavedDocument, ToolError>\n readonly renameSlug: (input: {\n readonly context: Context\n readonly target: KnowledgeTarget\n readonly nextSlug: string\n }) => Effect.Effect<KnowledgeSavedDocument, ToolError>\n readonly delete: (input: {\n readonly context: Context\n readonly target: KnowledgeTarget\n }) => Effect.Effect<KnowledgeSavedDocument, ToolError>\n}\n\nconst unknownToMessage = (error: unknown) => error instanceof Error ? error.message : String(error)\n\nconst optionalValue = <Value>(value: Value | null | undefined) => value ?? undefined\n\nconst targetFromParams = (target: KnowledgeTargetParams): KnowledgeTarget =>\n target.scope === null || target.scope === undefined\n ? { slug: target.slug }\n : { slug: target.slug, scope: target.scope }\n\nconst optionalTargetFromParams = (target: KnowledgeTargetParams | null | undefined) =>\n target === null || target === undefined ? undefined : targetFromParams(target)\n\nconst formatDocument = (document: KnowledgeDocument) =>\n [\n `# ${document.title}`,\n `document_id: ${document.id}`,\n `slug: ${document.slug}`,\n `purpose: ${document.purpose}`,\n `origin: ${document.origin}`,\n `availability: ${document.availability}`,\n `status: ${document.status}`,\n '',\n document.content\n ].join('\\n')\n\nconst formatSearchResults = (results: ReadonlyArray<KnowledgeLookupResult>) =>\n results.length === 0\n ? 'No knowledge matches found.'\n : results\n .map(result =>\n [\n `## ${result.document.title}`,\n `document_id: ${result.document.id}`,\n `slug: ${result.document.slug}`,\n `purpose: ${result.document.purpose}`,\n `origin: ${result.document.origin}`,\n `availability: ${result.document.availability}`,\n result.score === undefined ? undefined : `score: ${result.score}`,\n '',\n result.context?.map(chunk => chunk.content).join('\\n\\n') ?? result.document.content\n ]\n .filter(line => line !== undefined)\n .join('\\n')\n )\n .join('\\n\\n')\n\nconst formatSaved = (verb: string, document: KnowledgeSavedDocument) =>\n [verb, `title: ${document.title}`, `slug: ${document.slug}`, `document_id: ${document.id}`].join('\\n')\n\nexport const makeKnowledgeLookupTool = <Context>(\n handlers: KnowledgeLookupHandlers<Context>,\n options: { readonly name?: string; readonly description?: string } = {}\n): ToolRegistration<Context> => {\n const name = options.name ?? 'knowledge_lookup'\n\n return makeTool({\n name,\n description:\n options.description ??\n 'Look up durable knowledge. Search for semantic discovery; get when document_id or slug is known.',\n parameters: KnowledgeLookupParams,\n access: 'read',\n invalidParamsMessage: error => `Invalid knowledge lookup arguments: ${unknownToMessage(error)}`,\n execute: ({ call, context, params }) =>\n Effect.gen(function* () {\n if (params.operation === 'search') {\n const results = yield* handlers.search({\n context,\n query: params.query,\n limit: optionalValue(params.limit),\n minScore: optionalValue(params.minScore),\n contextChunks: optionalValue(params.contextChunks)\n })\n\n return ToolResult.make({ toolCallId: call.id, content: formatSearchResults(results) })\n }\n\n const document = yield* handlers.get({\n context,\n id: optionalValue(params.id),\n target: optionalTargetFromParams(params.target)\n })\n return ToolResult.make({ toolCallId: call.id, content: formatDocument(document) })\n })\n })\n}\n\nexport const makeKnowledgeManageTool = <Context>(\n handlers: KnowledgeManageHandlers<Context>,\n options: { readonly name?: string; readonly description?: string } = {}\n): ToolRegistration<Context> => {\n const name = options.name ?? 'knowledge_manage'\n\n return makeTool({\n name,\n description:\n options.description ??\n 'Create, replace, pin, archive, rename, or delete durable knowledge. Use only when explicitly asked.',\n parameters: KnowledgeManageParams,\n access: 'write',\n invalidParamsMessage: error => `Invalid knowledge manage arguments: ${unknownToMessage(error)}`,\n execute: ({ call, context, params }) =>\n Effect.gen(function* () {\n switch (params.operation) {\n case 'upsert': {\n const document = yield* handlers.upsert({\n context,\n target: targetFromParams(params.target),\n title: params.title,\n purpose: params.purpose,\n origin: params.origin,\n content: params.content,\n availability: params.availability\n })\n return ToolResult.make({ toolCallId: call.id, content: formatSaved('Knowledge upserted', document) })\n }\n case 'set_availability': {\n const document = yield* handlers.setAvailability({\n context,\n target: targetFromParams(params.target),\n availability: params.availability\n })\n return ToolResult.make({\n toolCallId: call.id,\n content: formatSaved('Knowledge availability updated', document)\n })\n }\n case 'rename_slug': {\n const document = yield* handlers.renameSlug({\n context,\n target: targetFromParams(params.target),\n nextSlug: params.nextSlug\n })\n return ToolResult.make({ toolCallId: call.id, content: formatSaved('Knowledge slug renamed', document) })\n }\n case 'delete': {\n const document = yield* handlers.delete({ context, target: targetFromParams(params.target) })\n return ToolResult.make({ toolCallId: call.id, content: formatSaved('Knowledge deleted', document) })\n }\n }\n\n return yield* Effect.fail(\n new ToolError({ tool: call.name, message: 'Unsupported knowledge operation', cause: 'validation' })\n )\n })\n })\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"agent.mjs","names":[],"sources":["../src/agent.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport { ToolError } from '@yolk-sdk/agent/loop'\nimport { ToolResult } from '@yolk-sdk/agent/protocol'\nimport { makeTool, type ToolRegistration } from '@yolk-sdk/agent/tools'\nimport {\n KnowledgeAvailabilitySchema,\n NonEmptyTrimmedString,\n type KnowledgeAvailability,\n type KnowledgeDocument\n} from './documents.ts'\n\nconst OptionalNonEmptyTrimmedString = Schema.optional(Schema.NullOr(NonEmptyTrimmedString))\nconst OptionalNumber = Schema.optional(Schema.NullOr(Schema.Number))\n\nconst KnowledgeTargetParamsSchema = Schema.Struct({\n slug: NonEmptyTrimmedString,\n scope: OptionalNonEmptyTrimmedString\n})\n\nconst KnowledgeLookupParams = Schema.Union([\n Schema.Struct({\n operation: Schema.Literal('search'),\n query: NonEmptyTrimmedString,\n limit: OptionalNumber,\n minScore: OptionalNumber,\n contextChunks: OptionalNumber\n }),\n Schema.Struct({\n operation: Schema.Literal('get'),\n id: OptionalNonEmptyTrimmedString,\n target: Schema.optional(Schema.NullOr(KnowledgeTargetParamsSchema))\n })\n])\n\nconst KnowledgeManageParams = Schema.Union([\n Schema.Struct({\n operation: Schema.Literal('upsert'),\n target: KnowledgeTargetParamsSchema,\n title: NonEmptyTrimmedString,\n purpose: NonEmptyTrimmedString,\n origin: NonEmptyTrimmedString,\n content: NonEmptyTrimmedString,\n availability: KnowledgeAvailabilitySchema\n }),\n Schema.Struct({\n operation: Schema.Literal('set_availability'),\n target: KnowledgeTargetParamsSchema,\n availability: KnowledgeAvailabilitySchema\n }),\n Schema.Struct({\n operation: Schema.Literal('rename_slug'),\n target: KnowledgeTargetParamsSchema,\n nextSlug: NonEmptyTrimmedString\n }),\n Schema.Struct({\n operation: Schema.Literal('delete'),\n target: KnowledgeTargetParamsSchema\n })\n])\n\ntype KnowledgeTargetParams = typeof KnowledgeTargetParamsSchema.Type\ntype KnowledgeLookupParams = typeof KnowledgeLookupParams.Type\ntype KnowledgeManageParams = typeof KnowledgeManageParams.Type\n\nexport type KnowledgeTarget = {\n readonly slug: string\n readonly scope?: string\n}\n\nexport type KnowledgeLookupResult = {\n readonly document: KnowledgeDocument\n readonly score?: number\n readonly context?: ReadonlyArray<{ readonly content: string }>\n}\n\nexport type KnowledgeSavedDocument = {\n readonly id: string\n readonly slug: string\n readonly title: string\n}\n\nexport type KnowledgeLookupHandlers<Context> = {\n readonly search: (input: {\n readonly context: Context\n readonly query: string\n readonly limit?: number\n readonly minScore?: number\n readonly contextChunks?: number\n }) => Effect.Effect<ReadonlyArray<KnowledgeLookupResult>, ToolError>\n readonly get: (input: {\n readonly context: Context\n readonly id?: string\n readonly target?: KnowledgeTarget\n }) => Effect.Effect<KnowledgeDocument, ToolError>\n}\n\nexport type KnowledgeManageHandlers<Context> = {\n readonly upsert: (input: {\n readonly context: Context\n readonly target: KnowledgeTarget\n readonly title: string\n readonly purpose: string\n readonly origin: string\n readonly content: string\n readonly availability: KnowledgeAvailability\n }) => Effect.Effect<KnowledgeSavedDocument, ToolError>\n readonly setAvailability: (input: {\n readonly context: Context\n readonly target: KnowledgeTarget\n readonly availability: KnowledgeAvailability\n }) => Effect.Effect<KnowledgeSavedDocument, ToolError>\n readonly renameSlug: (input: {\n readonly context: Context\n readonly target: KnowledgeTarget\n readonly nextSlug: string\n }) => Effect.Effect<KnowledgeSavedDocument, ToolError>\n readonly delete: (input: {\n readonly context: Context\n readonly target: KnowledgeTarget\n }) => Effect.Effect<KnowledgeSavedDocument, ToolError>\n}\n\nconst unknownToMessage = (error: unknown) =>\n error instanceof Error ? error.message : String(error)\n\nconst optionalValue = <Value>(value: Value | null | undefined) => value ?? undefined\n\nconst targetFromParams = (target: KnowledgeTargetParams): KnowledgeTarget =>\n target.scope === null || target.scope === undefined\n ? { slug: target.slug }\n : { slug: target.slug, scope: target.scope }\n\nconst optionalTargetFromParams = (target: KnowledgeTargetParams | null | undefined) =>\n target === null || target === undefined ? undefined : targetFromParams(target)\n\nconst formatDocument = (document: KnowledgeDocument) =>\n [\n `# ${document.title}`,\n `document_id: ${document.id}`,\n `slug: ${document.slug}`,\n `purpose: ${document.purpose}`,\n `origin: ${document.origin}`,\n `availability: ${document.availability}`,\n `status: ${document.status}`,\n '',\n document.content\n ].join('\\n')\n\nconst formatSearchResults = (results: ReadonlyArray<KnowledgeLookupResult>) =>\n results.length === 0\n ? 'No knowledge matches found.'\n : results\n .map(result =>\n [\n `## ${result.document.title}`,\n `document_id: ${result.document.id}`,\n `slug: ${result.document.slug}`,\n `purpose: ${result.document.purpose}`,\n `origin: ${result.document.origin}`,\n `availability: ${result.document.availability}`,\n result.score === undefined ? undefined : `score: ${result.score}`,\n '',\n result.context?.map(chunk => chunk.content).join('\\n\\n') ?? result.document.content\n ]\n .filter(line => line !== undefined)\n .join('\\n')\n )\n .join('\\n\\n')\n\nconst formatSaved = (verb: string, document: KnowledgeSavedDocument) =>\n [verb, `title: ${document.title}`, `slug: ${document.slug}`, `document_id: ${document.id}`].join(\n '\\n'\n )\n\nexport const makeKnowledgeLookupTool = <Context>(\n handlers: KnowledgeLookupHandlers<Context>,\n options: { readonly name?: string; readonly description?: string } = {}\n): ToolRegistration<Context> => {\n const name = options.name ?? 'knowledge_lookup'\n\n return makeTool({\n name,\n description:\n options.description ??\n 'Look up durable knowledge. Search for semantic discovery; get when document_id or slug is known.',\n parameters: KnowledgeLookupParams,\n access: 'read',\n invalidParamsMessage: error => `Invalid knowledge lookup arguments: ${unknownToMessage(error)}`,\n execute: ({ call, context, params }) =>\n Effect.gen(function* () {\n if (params.operation === 'search') {\n const results = yield* handlers.search({\n context,\n query: params.query,\n limit: optionalValue(params.limit),\n minScore: optionalValue(params.minScore),\n contextChunks: optionalValue(params.contextChunks)\n })\n\n return ToolResult.make({ toolCallId: call.id, content: formatSearchResults(results) })\n }\n\n const document = yield* handlers.get({\n context,\n id: optionalValue(params.id),\n target: optionalTargetFromParams(params.target)\n })\n return ToolResult.make({ toolCallId: call.id, content: formatDocument(document) })\n })\n })\n}\n\nexport const makeKnowledgeManageTool = <Context>(\n handlers: KnowledgeManageHandlers<Context>,\n options: { readonly name?: string; readonly description?: string } = {}\n): ToolRegistration<Context> => {\n const name = options.name ?? 'knowledge_manage'\n\n return makeTool({\n name,\n description:\n options.description ??\n 'Create, replace, pin, archive, rename, or delete durable knowledge. Use only when explicitly asked.',\n parameters: KnowledgeManageParams,\n access: 'write',\n invalidParamsMessage: error => `Invalid knowledge manage arguments: ${unknownToMessage(error)}`,\n execute: ({ call, context, params }) =>\n Effect.gen(function* () {\n switch (params.operation) {\n case 'upsert': {\n const document = yield* handlers.upsert({\n context,\n target: targetFromParams(params.target),\n title: params.title,\n purpose: params.purpose,\n origin: params.origin,\n content: params.content,\n availability: params.availability\n })\n return ToolResult.make({\n toolCallId: call.id,\n content: formatSaved('Knowledge upserted', document)\n })\n }\n case 'set_availability': {\n const document = yield* handlers.setAvailability({\n context,\n target: targetFromParams(params.target),\n availability: params.availability\n })\n return ToolResult.make({\n toolCallId: call.id,\n content: formatSaved('Knowledge availability updated', document)\n })\n }\n case 'rename_slug': {\n const document = yield* handlers.renameSlug({\n context,\n target: targetFromParams(params.target),\n nextSlug: params.nextSlug\n })\n return ToolResult.make({\n toolCallId: call.id,\n content: formatSaved('Knowledge slug renamed', document)\n })\n }\n case 'delete': {\n const document = yield* handlers.delete({\n context,\n target: targetFromParams(params.target)\n })\n return ToolResult.make({\n toolCallId: call.id,\n content: formatSaved('Knowledge deleted', document)\n })\n }\n }\n\n return yield* Effect.fail(\n new ToolError({\n tool: call.name,\n message: 'Unsupported knowledge operation',\n cause: 'validation'\n })\n )\n })\n })\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"chunking.d.mts","names":[],"sources":["../src/chunking.ts"],"mappings":";;;;;KASY,2BAAA;EAAA,SACD,OAAA;EAAA,SACA,UAAA;EAAA,SACA,OAAA;EAAA,SACA,SAAA;EAAA,SACA,QAAA,GAAW,iBAAiB;AAAA;AAAA,KAG3B,mBAAA;EAAA,SACD,KAAA,GACP,KAAA,EAAO,2BAAA,KACJ,MAAA,CAAO,MAAA,CAAO,aAAA,CAAc,cAAA,GAAiB,sBAAA;AAAA;AAAA,cACnD,qBAAA;cAEY,gBAAA,SAAyB,qBAErC;AAAA,cAEY,yBAAA,GAA6B,IAAY;AAAA,cA+GzC,kBAAA,GAAsB,KAAA,EAAO,2BAAA,EAA6B,SAAA,aAAiB,MAAA,CAAA,MAAA;;;;;;;;;;;cA+B3E,2BAAA,GAA+B,KAAA;EAAA,SAAkB,SAAA;AAAA,MAAsB,mBAElF;AAAA,cAEW,2BAAA,GAA+B,KAAA;EAAA,SAAkB,SAAA;AAAA,MAAwC,KAAA,CAAA,KAAA,CAAA,gBAAA"}
1
+ {"version":3,"file":"chunking.d.mts","names":[],"sources":["../src/chunking.ts"],"mappings":";;;;;KASY,2BAAA;EAAA,SACD,OAAA;EAAA,SACA,UAAA;EAAA,SACA,OAAA;EAAA,SACA,SAAA;EAAA,SACA,QAAA,GAAW,iBAAiB;AAAA;AAAA,KAG3B,mBAAA;EAAA,SACD,KAAA,GACP,KAAA,EAAO,2BAAA,KACJ,MAAA,CAAO,MAAA,CAAO,aAAA,CAAc,cAAA,GAAiB,sBAAA;AAAA;AAAA,cACnD,qBAAA;cAEY,gBAAA,SAAyB,qBAErC;AAAA,cAEY,yBAAA,GAA6B,IAAY;AAAA,cA+GzC,kBAAA,GAAsB,KAAA,EAAO,2BAAA,EAA6B,SAAA,aAAiB,MAAA,CAAA,MAAA;;;;;;;;;;;cAiC3E,2BAAA,GAA+B,KAAA;EAAA,SACjC,SAAA;AAAA,MACP,mBAEF;AAAA,cAEW,2BAAA,GACX,KAAA;EAAA,SAAkB,SAAA;AAAA,MAAwC,KAAA,CAAA,KAAA,CAAA,gBAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"chunking.mjs","names":[],"sources":["../src/chunking.ts"],"sourcesContent":["import { Context, Effect, Layer } from 'effect'\nimport { countTokens, decode, encode } from 'gpt-tokenizer/encoding/o200k_base'\nimport type { KnowledgeChunk, KnowledgeMetadata } from './documents.ts'\nimport { KnowledgeChunkingError } from './errors.ts'\n\nconst SENTENCE_PATTERN = /[^.!?]+[.!?]+(?:[\"')\\]]+)?\\s*|[^.!?]+$/g\nconst PARAGRAPH_BREAK_PATTERN = /(\\n{2,})/\nconst WORD_PATTERN = /\\S+\\s*/g\n\nexport type ChunkKnowledgeDocumentInput = {\n readonly scopeId: string\n readonly documentId: string\n readonly content: string\n readonly maxTokens?: number\n readonly metadata?: KnowledgeMetadata\n}\n\nexport type KnowledgeChunkerApi = {\n readonly chunk: (\n input: ChunkKnowledgeDocumentInput\n ) => Effect.Effect<ReadonlyArray<KnowledgeChunk>, KnowledgeChunkingError>\n}\n\nexport class KnowledgeChunker extends Context.Service<KnowledgeChunker, KnowledgeChunkerApi>()(\n '@yolk-sdk/knowledge/KnowledgeChunker'\n) {}\n\nexport const countKnowledgeChunkTokens = (text: string) => countTokens(text)\n\nconst sanitizeText = (text: string) =>\n text\n .replace(/\\r\\n/g, '\\n')\n .replace(/[\\t ]+/g, ' ')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim()\n\nconst splitSentences = (text: string) =>\n text\n .split(PARAGRAPH_BREAK_PATTERN)\n .flatMap(part => {\n if (part.length === 0) {\n return []\n }\n\n if (/^\\n{2,}$/.test(part)) {\n return ['\\n\\n']\n }\n\n return part.match(SENTENCE_PATTERN) ?? [part]\n })\n .filter(unit => unit.length > 0)\n\nconst splitEncodedTokens = (text: string, maxTokens: number) => {\n const tokens = encode(text)\n return Array.from({ length: Math.ceil(tokens.length / maxTokens) }, (_, index) =>\n decode(tokens.slice(index * maxTokens, index * maxTokens + maxTokens)).trim()\n ).filter(chunk => chunk.length > 0)\n}\n\nconst splitOversizedUnit = (text: string, maxTokens: number) => {\n const words = text.match(WORD_PATTERN) ?? []\n const chunks: string[] = []\n let current = ''\n let currentTokenCount = 0\n\n for (const word of words) {\n const wordTokenCount = countTokens(word)\n\n if (wordTokenCount > maxTokens) {\n const currentChunk = current.trim()\n if (currentChunk.length > 0) {\n chunks.push(currentChunk)\n }\n\n chunks.push(...splitEncodedTokens(word, maxTokens))\n current = ''\n currentTokenCount = 0\n continue\n }\n\n if (currentTokenCount > 0 && currentTokenCount + wordTokenCount > maxTokens) {\n const currentChunk = current.trim()\n if (currentChunk.length > 0) {\n chunks.push(currentChunk)\n }\n\n current = word\n currentTokenCount = wordTokenCount\n continue\n }\n\n current = `${current}${word}`\n currentTokenCount += wordTokenCount\n }\n\n const finalChunk = current.trim()\n if (finalChunk.length > 0) {\n chunks.push(finalChunk)\n }\n\n return chunks\n}\n\nconst splitUnitsBySize = (units: ReadonlyArray<string>, maxTokens: number) =>\n units.flatMap(unit =>\n countTokens(unit) <= maxTokens ? [unit] : splitOversizedUnit(unit, maxTokens)\n )\n\nconst buildChunkContents = (units: ReadonlyArray<string>, maxTokens: number) => {\n const chunks: string[] = []\n let current = ''\n let currentTokenCount = 0\n\n const pushCurrent = () => {\n const content = current.trim()\n if (content.length > 0) {\n chunks.push(content)\n }\n }\n\n for (const unit of units) {\n const unitTokenCount = countTokens(unit)\n\n if (currentTokenCount > 0 && currentTokenCount + unitTokenCount > maxTokens) {\n pushCurrent()\n current = unit\n currentTokenCount = unitTokenCount\n continue\n }\n\n current = `${current}${unit}`\n currentTokenCount += unitTokenCount\n }\n\n pushCurrent()\n return chunks\n}\n\nexport const chunkKnowledgeText = (input: ChunkKnowledgeDocumentInput, maxTokens: number) =>\n Effect.gen(function* () {\n if (!Number.isInteger(maxTokens) || maxTokens < 1) {\n return yield* Effect.fail(\n new KnowledgeChunkingError({ message: 'Chunk maxTokens must be a positive integer' })\n )\n }\n\n const sanitized = sanitizeText(input.content)\n if (sanitized.length === 0) {\n return yield* Effect.fail(new KnowledgeChunkingError({ message: 'Cannot chunk empty content' }))\n }\n\n const units = splitUnitsBySize(splitSentences(sanitized), maxTokens)\n const contents = buildChunkContents(units, maxTokens)\n\n if (contents.length === 0) {\n return yield* Effect.fail(new KnowledgeChunkingError({ message: 'No chunks produced' }))\n }\n\n return contents.map((content, position) => ({\n id: `${input.documentId}:chunk:${position}`,\n scopeId: input.scopeId,\n documentId: input.documentId,\n content,\n position,\n tokenCount: countTokens(content),\n metadata: input.metadata\n })) satisfies ReadonlyArray<KnowledgeChunk>\n })\n\nexport const makeDefaultKnowledgeChunker = (input: { readonly maxTokens: number }): KnowledgeChunkerApi => ({\n chunk: document => chunkKnowledgeText(document, document.maxTokens ?? input.maxTokens)\n})\n\nexport const DefaultKnowledgeChunkerLive = (input: { readonly maxTokens: number } = { maxTokens: 512 }) =>\n Layer.succeed(KnowledgeChunker, makeDefaultKnowledgeChunker(input))\n"],"mappings":"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"}
1
+ {"version":3,"file":"chunking.mjs","names":[],"sources":["../src/chunking.ts"],"sourcesContent":["import { Context, Effect, Layer } from 'effect'\nimport { countTokens, decode, encode } from 'gpt-tokenizer/encoding/o200k_base'\nimport type { KnowledgeChunk, KnowledgeMetadata } from './documents.ts'\nimport { KnowledgeChunkingError } from './errors.ts'\n\nconst SENTENCE_PATTERN = /[^.!?]+[.!?]+(?:[\"')\\]]+)?\\s*|[^.!?]+$/g\nconst PARAGRAPH_BREAK_PATTERN = /(\\n{2,})/\nconst WORD_PATTERN = /\\S+\\s*/g\n\nexport type ChunkKnowledgeDocumentInput = {\n readonly scopeId: string\n readonly documentId: string\n readonly content: string\n readonly maxTokens?: number\n readonly metadata?: KnowledgeMetadata\n}\n\nexport type KnowledgeChunkerApi = {\n readonly chunk: (\n input: ChunkKnowledgeDocumentInput\n ) => Effect.Effect<ReadonlyArray<KnowledgeChunk>, KnowledgeChunkingError>\n}\n\nexport class KnowledgeChunker extends Context.Service<KnowledgeChunker, KnowledgeChunkerApi>()(\n '@yolk-sdk/knowledge/KnowledgeChunker'\n) {}\n\nexport const countKnowledgeChunkTokens = (text: string) => countTokens(text)\n\nconst sanitizeText = (text: string) =>\n text\n .replace(/\\r\\n/g, '\\n')\n .replace(/[\\t ]+/g, ' ')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim()\n\nconst splitSentences = (text: string) =>\n text\n .split(PARAGRAPH_BREAK_PATTERN)\n .flatMap(part => {\n if (part.length === 0) {\n return []\n }\n\n if (/^\\n{2,}$/.test(part)) {\n return ['\\n\\n']\n }\n\n return part.match(SENTENCE_PATTERN) ?? [part]\n })\n .filter(unit => unit.length > 0)\n\nconst splitEncodedTokens = (text: string, maxTokens: number) => {\n const tokens = encode(text)\n return Array.from({ length: Math.ceil(tokens.length / maxTokens) }, (_, index) =>\n decode(tokens.slice(index * maxTokens, index * maxTokens + maxTokens)).trim()\n ).filter(chunk => chunk.length > 0)\n}\n\nconst splitOversizedUnit = (text: string, maxTokens: number) => {\n const words = text.match(WORD_PATTERN) ?? []\n const chunks: string[] = []\n let current = ''\n let currentTokenCount = 0\n\n for (const word of words) {\n const wordTokenCount = countTokens(word)\n\n if (wordTokenCount > maxTokens) {\n const currentChunk = current.trim()\n if (currentChunk.length > 0) {\n chunks.push(currentChunk)\n }\n\n chunks.push(...splitEncodedTokens(word, maxTokens))\n current = ''\n currentTokenCount = 0\n continue\n }\n\n if (currentTokenCount > 0 && currentTokenCount + wordTokenCount > maxTokens) {\n const currentChunk = current.trim()\n if (currentChunk.length > 0) {\n chunks.push(currentChunk)\n }\n\n current = word\n currentTokenCount = wordTokenCount\n continue\n }\n\n current = `${current}${word}`\n currentTokenCount += wordTokenCount\n }\n\n const finalChunk = current.trim()\n if (finalChunk.length > 0) {\n chunks.push(finalChunk)\n }\n\n return chunks\n}\n\nconst splitUnitsBySize = (units: ReadonlyArray<string>, maxTokens: number) =>\n units.flatMap(unit =>\n countTokens(unit) <= maxTokens ? [unit] : splitOversizedUnit(unit, maxTokens)\n )\n\nconst buildChunkContents = (units: ReadonlyArray<string>, maxTokens: number) => {\n const chunks: string[] = []\n let current = ''\n let currentTokenCount = 0\n\n const pushCurrent = () => {\n const content = current.trim()\n if (content.length > 0) {\n chunks.push(content)\n }\n }\n\n for (const unit of units) {\n const unitTokenCount = countTokens(unit)\n\n if (currentTokenCount > 0 && currentTokenCount + unitTokenCount > maxTokens) {\n pushCurrent()\n current = unit\n currentTokenCount = unitTokenCount\n continue\n }\n\n current = `${current}${unit}`\n currentTokenCount += unitTokenCount\n }\n\n pushCurrent()\n return chunks\n}\n\nexport const chunkKnowledgeText = (input: ChunkKnowledgeDocumentInput, maxTokens: number) =>\n Effect.gen(function* () {\n if (!Number.isInteger(maxTokens) || maxTokens < 1) {\n return yield* Effect.fail(\n new KnowledgeChunkingError({ message: 'Chunk maxTokens must be a positive integer' })\n )\n }\n\n const sanitized = sanitizeText(input.content)\n if (sanitized.length === 0) {\n return yield* Effect.fail(\n new KnowledgeChunkingError({ message: 'Cannot chunk empty content' })\n )\n }\n\n const units = splitUnitsBySize(splitSentences(sanitized), maxTokens)\n const contents = buildChunkContents(units, maxTokens)\n\n if (contents.length === 0) {\n return yield* Effect.fail(new KnowledgeChunkingError({ message: 'No chunks produced' }))\n }\n\n return contents.map((content, position) => ({\n id: `${input.documentId}:chunk:${position}`,\n scopeId: input.scopeId,\n documentId: input.documentId,\n content,\n position,\n tokenCount: countTokens(content),\n metadata: input.metadata\n })) satisfies ReadonlyArray<KnowledgeChunk>\n })\n\nexport const makeDefaultKnowledgeChunker = (input: {\n readonly maxTokens: number\n}): KnowledgeChunkerApi => ({\n chunk: document => chunkKnowledgeText(document, document.maxTokens ?? input.maxTokens)\n})\n\nexport const DefaultKnowledgeChunkerLive = (\n input: { readonly maxTokens: number } = { maxTokens: 512 }\n) => Layer.succeed(KnowledgeChunker, makeDefaultKnowledgeChunker(input))\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"context.mjs","names":["Arr"],"sources":["../src/context.ts"],"sourcesContent":["import { Array as Arr } from 'effect'\nimport type { KnowledgeDocument } from './documents.ts'\n\nexport type BuildKnowledgeContextInput = {\n readonly documents: ReadonlyArray<KnowledgeDocument>\n readonly maxCharacters: number\n}\n\nconst truncationMarker = '\\n\\n[truncated: pinned knowledge exceeded context budget]'\n\nconst documentHeader = (document: KnowledgeDocument) =>\n [\n `## ${document.title}`,\n `slug: ${document.slug}`,\n `purpose: ${document.purpose}`,\n `origin: ${document.origin}`,\n `status: ${document.status}`,\n `availability: ${document.availability}`,\n document.reviewedAt === undefined ? undefined : `reviewed_at: ${document.reviewedAt.toString()}`\n ]\n .filter(line => line !== undefined && line.trim().length > 0)\n .join('\\n')\n\nconst documentBody = (document: KnowledgeDocument) =>\n [documentHeader(document), document.summary, document.content]\n .filter(section => section !== undefined && section.trim().length > 0)\n .join('\\n')\n\nexport const buildKnowledgeContext = (input: BuildKnowledgeContextInput) => {\n const sections = Arr.map(input.documents, documentBody).filter(section => section.trim().length > 0)\n const header = '# Pinned knowledge\\nUse this durable knowledge as high-priority context.'\n const body = sections.join('\\n\\n')\n const context = body.length === 0 ? '' : `${header}\\n\\n${body}`\n\n if (context.length <= input.maxCharacters) {\n return context\n }\n\n if (input.maxCharacters <= truncationMarker.length) {\n return context.slice(0, input.maxCharacters).trimEnd()\n }\n\n return `${context.slice(0, input.maxCharacters - truncationMarker.length).trimEnd()}${truncationMarker}`\n}\n"],"mappings":";;AAQA,MAAM,mBAAmB;AAEzB,MAAM,kBAAkB,aACtB;CACE,MAAM,SAAS;CACf,SAAS,SAAS;CAClB,YAAY,SAAS;CACrB,WAAW,SAAS;CACpB,WAAW,SAAS;CACpB,iBAAiB,SAAS;CAC1B,SAAS,eAAe,KAAA,IAAY,KAAA,IAAY,gBAAgB,SAAS,WAAW,SAAS;AAC/F,EACG,QAAO,SAAQ,SAAS,KAAA,KAAa,KAAK,KAAK,EAAE,SAAS,CAAC,EAC3D,KAAK,IAAI;AAEd,MAAM,gBAAgB,aACpB;CAAC,eAAe,QAAQ;CAAG,SAAS;CAAS,SAAS;AAAO,EAC1D,QAAO,YAAW,YAAY,KAAA,KAAa,QAAQ,KAAK,EAAE,SAAS,CAAC,EACpE,KAAK,IAAI;AAEd,MAAa,yBAAyB,UAAsC;CAC1E,MAAM,WAAWA,MAAI,IAAI,MAAM,WAAW,YAAY,EAAE,QAAO,YAAW,QAAQ,KAAK,EAAE,SAAS,CAAC;CACnG,MAAM,SAAS;CACf,MAAM,OAAO,SAAS,KAAK,MAAM;CACjC,MAAM,UAAU,KAAK,WAAW,IAAI,KAAK,GAAG,OAAO,MAAM;CAEzD,IAAI,QAAQ,UAAU,MAAM,eAC1B,OAAO;CAGT,IAAI,MAAM,iBAAiB,IACzB,OAAO,QAAQ,MAAM,GAAG,MAAM,aAAa,EAAE,QAAQ;CAGvD,OAAO,GAAG,QAAQ,MAAM,GAAG,MAAM,gBAAgB,EAAuB,EAAE,QAAQ,IAAI;AACxF"}
1
+ {"version":3,"file":"context.mjs","names":["Arr"],"sources":["../src/context.ts"],"sourcesContent":["import { Array as Arr } from 'effect'\nimport type { KnowledgeDocument } from './documents.ts'\n\nexport type BuildKnowledgeContextInput = {\n readonly documents: ReadonlyArray<KnowledgeDocument>\n readonly maxCharacters: number\n}\n\nconst truncationMarker = '\\n\\n[truncated: pinned knowledge exceeded context budget]'\n\nconst documentHeader = (document: KnowledgeDocument) =>\n [\n `## ${document.title}`,\n `slug: ${document.slug}`,\n `purpose: ${document.purpose}`,\n `origin: ${document.origin}`,\n `status: ${document.status}`,\n `availability: ${document.availability}`,\n document.reviewedAt === undefined ? undefined : `reviewed_at: ${document.reviewedAt.toString()}`\n ]\n .filter(line => line !== undefined && line.trim().length > 0)\n .join('\\n')\n\nconst documentBody = (document: KnowledgeDocument) =>\n [documentHeader(document), document.summary, document.content]\n .filter(section => section !== undefined && section.trim().length > 0)\n .join('\\n')\n\nexport const buildKnowledgeContext = (input: BuildKnowledgeContextInput) => {\n const sections = Arr.map(input.documents, documentBody).filter(\n section => section.trim().length > 0\n )\n const header = '# Pinned knowledge\\nUse this durable knowledge as high-priority context.'\n const body = sections.join('\\n\\n')\n const context = body.length === 0 ? '' : `${header}\\n\\n${body}`\n\n if (context.length <= input.maxCharacters) {\n return context\n }\n\n if (input.maxCharacters <= truncationMarker.length) {\n return context.slice(0, input.maxCharacters).trimEnd()\n }\n\n return `${context.slice(0, input.maxCharacters - truncationMarker.length).trimEnd()}${truncationMarker}`\n}\n"],"mappings":";;AAQA,MAAM,mBAAmB;AAEzB,MAAM,kBAAkB,aACtB;CACE,MAAM,SAAS;CACf,SAAS,SAAS;CAClB,YAAY,SAAS;CACrB,WAAW,SAAS;CACpB,WAAW,SAAS;CACpB,iBAAiB,SAAS;CAC1B,SAAS,eAAe,KAAA,IAAY,KAAA,IAAY,gBAAgB,SAAS,WAAW,SAAS;AAC/F,EACG,QAAO,SAAQ,SAAS,KAAA,KAAa,KAAK,KAAK,EAAE,SAAS,CAAC,EAC3D,KAAK,IAAI;AAEd,MAAM,gBAAgB,aACpB;CAAC,eAAe,QAAQ;CAAG,SAAS;CAAS,SAAS;AAAO,EAC1D,QAAO,YAAW,YAAY,KAAA,KAAa,QAAQ,KAAK,EAAE,SAAS,CAAC,EACpE,KAAK,IAAI;AAEd,MAAa,yBAAyB,UAAsC;CAC1E,MAAM,WAAWA,MAAI,IAAI,MAAM,WAAW,YAAY,EAAE,QACtD,YAAW,QAAQ,KAAK,EAAE,SAAS,CACrC;CACA,MAAM,SAAS;CACf,MAAM,OAAO,SAAS,KAAK,MAAM;CACjC,MAAM,UAAU,KAAK,WAAW,IAAI,KAAK,GAAG,OAAO,MAAM;CAEzD,IAAI,QAAQ,UAAU,MAAM,eAC1B,OAAO;CAGT,IAAI,MAAM,iBAAiB,IACzB,OAAO,QAAQ,MAAM,GAAG,MAAM,aAAa,EAAE,QAAQ;CAGvD,OAAO,GAAG,QAAQ,MAAM,GAAG,MAAM,gBAAgB,EAAuB,EAAE,QAAQ,IAAI;AACxF"}
@@ -1 +1 @@
1
- {"version":3,"file":"documents.d.mts","names":[],"sources":["../src/documents.ts"],"mappings":";;;cAEa,qBAAA,EAAqB,MAAA,CAAA,OAAyD;AAAA,cAC9E,kBAAA,EAAkB,MAAA,CAAA,GAAkE;AAAA,cACpF,eAAA,EAAe,MAAA,CAAA,GAAyD;AAAA,cAExE,uBAAA,EAAuB,MAAA,CAAA,OAAA,CAAA,MAAA,CAAA,MAAA,EAAA,MAAA,CAAA,OAAA;AAAA,KACxB,iBAAA,GAAoB,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,uBAAA;AAAA,cAE7C,2BAAA,EAA2B,MAAA,CAAA,QAAA;AAAA,KAC5B,qBAAA,GAAwB,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,2BAAA;AAAA,cAEjD,6BAAA,EAA6B,MAAA,CAAA,QAAA;AAAA,KAC9B,uBAAA,GAA0B,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,6BAAA;AAAA,cAEnD,oBAAA,EAAoB,MAAA,CAAA,MAAA;EAAA;;;KAIrB,cAAA,GAAiB,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,oBAAA;AAAA,cAE1C,uBAAA,EAAuB,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;;;KAgBxB,iBAAA,GAAoB,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,uBAAA;AAAA,cAE7C,kCAAA,EAAkC,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;KAWnC,4BAAA,GAA+B,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,kCAAA;AAAA,cAExD,kCAAA,EAAkC,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;;;;;KAenC,4BAAA,GAA+B,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,kCAAA;AAAA,cAExD,mBAAA,EAAmB,MAAA,CAAA,MAAA;EAAA;;;;;;;;;KAUpB,aAAA,GAAgB,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,mBAAA;AAAA,cAEzC,oBAAA,EAAoB,MAAA,CAAA,MAAA;EAAA;;;;;;;;KASrB,cAAA,GAAiB,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,oBAAA;AAAA,cAE1C,0BAAA,EAA0B,MAAA,CAAA,KAAA,WAAA,MAAA,CAAA,MAAA;EAAA;;;;;;KAI3B,oBAAA,GAAuB,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,0BAAA;AAAA,cAEhD,qBAAA,EAAqB,MAAA,CAAA,KAAA,WAAA,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;KAgBtB,eAAA,GAAkB,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,qBAAA;AAAA,cAE3C,8BAAA,EAA8B,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;KAa/B,wBAAA,GAA2B,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,8BAAA;AAAA,cAEpD,gCAAA,EAAgC,MAAA,CAAA,MAAA;EAAA;;;;;KAMjC,0BAAA,GAA6B,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,gCAAA;AAAA,cAEtD,8BAAA"}
1
+ {"version":3,"file":"documents.d.mts","names":[],"sources":["../src/documents.ts"],"mappings":";;;cAEa,qBAAA,EAAqB,MAAA,CAAA,OAAyD;AAAA,cAC9E,kBAAA,EAAkB,MAAA,CAAA,GAAkE;AAAA,cACpF,eAAA,EAAe,MAAA,CAAA,GAAyD;AAAA,cAExE,uBAAA,EAAuB,MAAA,CAAA,OAAA,CAAA,MAAA,CAAA,MAAA,EAAA,MAAA,CAAA,OAAA;AAAA,KACxB,iBAAA,GAAoB,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,uBAAA;AAAA,cAE7C,2BAAA,EAA2B,MAAA,CAAA,QAAA;AAAA,KAC5B,qBAAA,GAAwB,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,2BAAA;AAAA,cAEjD,6BAAA,EAA6B,MAAA,CAAA,QAAA;AAAA,KAC9B,uBAAA,GAA0B,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,6BAAA;AAAA,cAEnD,oBAAA,EAAoB,MAAA,CAAA,MAAA;EAAA;;;KAIrB,cAAA,GAAiB,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,oBAAA;AAAA,cAE1C,uBAAA,EAAuB,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;;;KAgBxB,iBAAA,GAAoB,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,uBAAA;AAAA,cAE7C,kCAAA,EAAkC,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;KAWnC,4BAAA,GAA+B,MAAA,CAAO,MAAA,CAAO,IAAI,QACpD,kCAAA;AAAA,cAGI,kCAAA,EAAkC,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;;;;;KAenC,4BAAA,GAA+B,MAAA,CAAO,MAAA,CAAO,IAAI,QACpD,kCAAA;AAAA,cAGI,mBAAA,EAAmB,MAAA,CAAA,MAAA;EAAA;;;;;;;;;KAUpB,aAAA,GAAgB,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,mBAAA;AAAA,cAEzC,oBAAA,EAAoB,MAAA,CAAA,MAAA;EAAA;;;;;;;;KASrB,cAAA,GAAiB,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,oBAAA;AAAA,cAE1C,0BAAA,EAA0B,MAAA,CAAA,KAAA,WAAA,MAAA,CAAA,MAAA;EAAA;;;;;;KAO3B,oBAAA,GAAuB,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,0BAAA;AAAA,cAEhD,qBAAA,EAAqB,MAAA,CAAA,KAAA,WAAA,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;KAgBtB,eAAA,GAAkB,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,qBAAA;AAAA,cAE3C,8BAAA,EAA8B,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;KAa/B,wBAAA,GAA2B,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,8BAAA;AAAA,cAEpD,gCAAA,EAAgC,MAAA,CAAA,MAAA;EAAA;;;;;KAMjC,0BAAA,GAA6B,MAAA,CAAO,MAAA,CAAO,IAAI,QAAQ,gCAAA;AAAA,cAEtD,8BAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"documents.mjs","names":[],"sources":["../src/documents.ts"],"sourcesContent":["import * as Schema from 'effect/Schema'\n\nexport const NonEmptyTrimmedString = Schema.Trimmed.pipe(Schema.check(Schema.isNonEmpty()))\nexport const NonNegativeInteger = Schema.Int.pipe(Schema.check(Schema.isGreaterThanOrEqualTo(0)))\nexport const PositiveInteger = Schema.Int.pipe(Schema.check(Schema.isGreaterThan(0)))\n\nexport const KnowledgeMetadataSchema = Schema.Record(Schema.String, Schema.Unknown)\nexport type KnowledgeMetadata = Schema.Schema.Type<typeof KnowledgeMetadataSchema>\n\nexport const KnowledgeAvailabilitySchema = Schema.Literals(['pinned', 'searchable', 'archived'])\nexport type KnowledgeAvailability = Schema.Schema.Type<typeof KnowledgeAvailabilitySchema>\n\nexport const KnowledgeDocumentStatusSchema = Schema.Literals(['processing', 'ready', 'error'])\nexport type KnowledgeDocumentStatus = Schema.Schema.Type<typeof KnowledgeDocumentStatusSchema>\n\nexport const KnowledgeScopeSchema = Schema.Struct({\n id: NonEmptyTrimmedString,\n kind: Schema.optional(NonEmptyTrimmedString)\n})\nexport type KnowledgeScope = Schema.Schema.Type<typeof KnowledgeScopeSchema>\n\nexport const KnowledgeDocumentSchema = Schema.Struct({\n id: NonEmptyTrimmedString,\n slug: NonEmptyTrimmedString,\n title: NonEmptyTrimmedString,\n purpose: NonEmptyTrimmedString,\n origin: NonEmptyTrimmedString,\n content: NonEmptyTrimmedString,\n status: KnowledgeDocumentStatusSchema,\n availability: KnowledgeAvailabilitySchema,\n summary: Schema.optional(Schema.String),\n errorMessage: Schema.optional(Schema.String),\n reviewedAt: Schema.optional(Schema.DateTimeUtc),\n metadata: Schema.optional(KnowledgeMetadataSchema),\n createdAt: Schema.DateTimeUtc,\n updatedAt: Schema.DateTimeUtc\n})\nexport type KnowledgeDocument = Schema.Schema.Type<typeof KnowledgeDocumentSchema>\n\nexport const CreateKnowledgeDocumentInputSchema = Schema.Struct({\n scope: KnowledgeScopeSchema,\n slug: NonEmptyTrimmedString,\n title: NonEmptyTrimmedString,\n purpose: NonEmptyTrimmedString,\n origin: NonEmptyTrimmedString,\n content: NonEmptyTrimmedString,\n availability: KnowledgeAvailabilitySchema,\n summary: Schema.optional(Schema.String),\n metadata: Schema.optional(KnowledgeMetadataSchema)\n})\nexport type CreateKnowledgeDocumentInput = Schema.Schema.Type<typeof CreateKnowledgeDocumentInputSchema>\n\nexport const UpdateKnowledgeDocumentInputSchema = Schema.Struct({\n scope: KnowledgeScopeSchema,\n id: NonEmptyTrimmedString,\n slug: Schema.optional(NonEmptyTrimmedString),\n title: Schema.optional(NonEmptyTrimmedString),\n purpose: Schema.optional(NonEmptyTrimmedString),\n origin: Schema.optional(NonEmptyTrimmedString),\n content: Schema.optional(NonEmptyTrimmedString),\n status: Schema.optional(KnowledgeDocumentStatusSchema),\n availability: Schema.optional(KnowledgeAvailabilitySchema),\n summary: Schema.optional(Schema.String),\n errorMessage: Schema.optional(Schema.String),\n reviewedAt: Schema.optional(Schema.DateTimeUtc),\n metadata: Schema.optional(KnowledgeMetadataSchema)\n})\nexport type UpdateKnowledgeDocumentInput = Schema.Schema.Type<typeof UpdateKnowledgeDocumentInputSchema>\n\nexport const KnowledgeFileSchema = Schema.Struct({\n id: NonEmptyTrimmedString,\n documentId: NonEmptyTrimmedString,\n storageKey: NonEmptyTrimmedString,\n mediaType: Schema.optional(NonEmptyTrimmedString),\n byteSize: Schema.optional(NonNegativeInteger),\n checksum: Schema.optional(NonEmptyTrimmedString),\n metadata: Schema.optional(KnowledgeMetadataSchema),\n createdAt: Schema.DateTimeUtc\n})\nexport type KnowledgeFile = Schema.Schema.Type<typeof KnowledgeFileSchema>\n\nexport const KnowledgeChunkSchema = Schema.Struct({\n id: NonEmptyTrimmedString,\n scopeId: NonEmptyTrimmedString,\n documentId: NonEmptyTrimmedString,\n content: NonEmptyTrimmedString,\n position: NonNegativeInteger,\n tokenCount: PositiveInteger,\n metadata: Schema.optional(KnowledgeMetadataSchema)\n})\nexport type KnowledgeChunk = Schema.Schema.Type<typeof KnowledgeChunkSchema>\n\nexport const KnowledgeSearchScopeSchema = Schema.Union([\n Schema.Struct({ _tag: Schema.Literal('KnowledgeScope'), id: NonEmptyTrimmedString }),\n Schema.Struct({ _tag: Schema.Literal('KnowledgeScopes'), ids: Schema.Array(NonEmptyTrimmedString) })\n])\nexport type KnowledgeSearchScope = Schema.Schema.Type<typeof KnowledgeSearchScopeSchema>\n\nexport const KnowledgeSourceSchema = Schema.Union([\n Schema.Struct({\n _tag: Schema.Literal('File'),\n ref: NonEmptyTrimmedString,\n name: Schema.optional(NonEmptyTrimmedString),\n mediaType: Schema.optional(NonEmptyTrimmedString)\n }),\n Schema.Struct({\n _tag: Schema.Literal('Url'),\n url: NonEmptyTrimmedString\n }),\n Schema.Struct({\n _tag: Schema.Literal('Text'),\n label: Schema.optional(NonEmptyTrimmedString)\n })\n])\nexport type KnowledgeSource = Schema.Schema.Type<typeof KnowledgeSourceSchema>\n\nexport const IndexedKnowledgeDocumentSchema = Schema.Struct({\n id: NonEmptyTrimmedString,\n scopeId: NonEmptyTrimmedString,\n source: KnowledgeSourceSchema,\n status: KnowledgeDocumentStatusSchema,\n title: Schema.optional(NonEmptyTrimmedString),\n summary: Schema.optional(Schema.String),\n errorMessage: Schema.optional(Schema.String),\n contentHash: Schema.optional(NonEmptyTrimmedString),\n tokenCount: Schema.optional(NonNegativeInteger),\n chunkCount: Schema.optional(NonNegativeInteger),\n metadata: Schema.optional(KnowledgeMetadataSchema)\n})\nexport type IndexedKnowledgeDocument = Schema.Schema.Type<typeof IndexedKnowledgeDocumentSchema>\n\nexport const ExtractedKnowledgeDocumentSchema = Schema.Struct({\n content: NonEmptyTrimmedString,\n title: Schema.optional(NonEmptyTrimmedString),\n summary: Schema.optional(Schema.String),\n metadata: Schema.optional(KnowledgeMetadataSchema)\n})\nexport type ExtractedKnowledgeDocument = Schema.Schema.Type<typeof ExtractedKnowledgeDocumentSchema>\n\nexport const defaultKnowledgeChunkMaxTokens = 512\n"],"mappings":"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"}
1
+ {"version":3,"file":"documents.mjs","names":[],"sources":["../src/documents.ts"],"sourcesContent":["import * as Schema from 'effect/Schema'\n\nexport const NonEmptyTrimmedString = Schema.Trimmed.pipe(Schema.check(Schema.isNonEmpty()))\nexport const NonNegativeInteger = Schema.Int.pipe(Schema.check(Schema.isGreaterThanOrEqualTo(0)))\nexport const PositiveInteger = Schema.Int.pipe(Schema.check(Schema.isGreaterThan(0)))\n\nexport const KnowledgeMetadataSchema = Schema.Record(Schema.String, Schema.Unknown)\nexport type KnowledgeMetadata = Schema.Schema.Type<typeof KnowledgeMetadataSchema>\n\nexport const KnowledgeAvailabilitySchema = Schema.Literals(['pinned', 'searchable', 'archived'])\nexport type KnowledgeAvailability = Schema.Schema.Type<typeof KnowledgeAvailabilitySchema>\n\nexport const KnowledgeDocumentStatusSchema = Schema.Literals(['processing', 'ready', 'error'])\nexport type KnowledgeDocumentStatus = Schema.Schema.Type<typeof KnowledgeDocumentStatusSchema>\n\nexport const KnowledgeScopeSchema = Schema.Struct({\n id: NonEmptyTrimmedString,\n kind: Schema.optional(NonEmptyTrimmedString)\n})\nexport type KnowledgeScope = Schema.Schema.Type<typeof KnowledgeScopeSchema>\n\nexport const KnowledgeDocumentSchema = Schema.Struct({\n id: NonEmptyTrimmedString,\n slug: NonEmptyTrimmedString,\n title: NonEmptyTrimmedString,\n purpose: NonEmptyTrimmedString,\n origin: NonEmptyTrimmedString,\n content: NonEmptyTrimmedString,\n status: KnowledgeDocumentStatusSchema,\n availability: KnowledgeAvailabilitySchema,\n summary: Schema.optional(Schema.String),\n errorMessage: Schema.optional(Schema.String),\n reviewedAt: Schema.optional(Schema.DateTimeUtc),\n metadata: Schema.optional(KnowledgeMetadataSchema),\n createdAt: Schema.DateTimeUtc,\n updatedAt: Schema.DateTimeUtc\n})\nexport type KnowledgeDocument = Schema.Schema.Type<typeof KnowledgeDocumentSchema>\n\nexport const CreateKnowledgeDocumentInputSchema = Schema.Struct({\n scope: KnowledgeScopeSchema,\n slug: NonEmptyTrimmedString,\n title: NonEmptyTrimmedString,\n purpose: NonEmptyTrimmedString,\n origin: NonEmptyTrimmedString,\n content: NonEmptyTrimmedString,\n availability: KnowledgeAvailabilitySchema,\n summary: Schema.optional(Schema.String),\n metadata: Schema.optional(KnowledgeMetadataSchema)\n})\nexport type CreateKnowledgeDocumentInput = Schema.Schema.Type<\n typeof CreateKnowledgeDocumentInputSchema\n>\n\nexport const UpdateKnowledgeDocumentInputSchema = Schema.Struct({\n scope: KnowledgeScopeSchema,\n id: NonEmptyTrimmedString,\n slug: Schema.optional(NonEmptyTrimmedString),\n title: Schema.optional(NonEmptyTrimmedString),\n purpose: Schema.optional(NonEmptyTrimmedString),\n origin: Schema.optional(NonEmptyTrimmedString),\n content: Schema.optional(NonEmptyTrimmedString),\n status: Schema.optional(KnowledgeDocumentStatusSchema),\n availability: Schema.optional(KnowledgeAvailabilitySchema),\n summary: Schema.optional(Schema.String),\n errorMessage: Schema.optional(Schema.String),\n reviewedAt: Schema.optional(Schema.DateTimeUtc),\n metadata: Schema.optional(KnowledgeMetadataSchema)\n})\nexport type UpdateKnowledgeDocumentInput = Schema.Schema.Type<\n typeof UpdateKnowledgeDocumentInputSchema\n>\n\nexport const KnowledgeFileSchema = Schema.Struct({\n id: NonEmptyTrimmedString,\n documentId: NonEmptyTrimmedString,\n storageKey: NonEmptyTrimmedString,\n mediaType: Schema.optional(NonEmptyTrimmedString),\n byteSize: Schema.optional(NonNegativeInteger),\n checksum: Schema.optional(NonEmptyTrimmedString),\n metadata: Schema.optional(KnowledgeMetadataSchema),\n createdAt: Schema.DateTimeUtc\n})\nexport type KnowledgeFile = Schema.Schema.Type<typeof KnowledgeFileSchema>\n\nexport const KnowledgeChunkSchema = Schema.Struct({\n id: NonEmptyTrimmedString,\n scopeId: NonEmptyTrimmedString,\n documentId: NonEmptyTrimmedString,\n content: NonEmptyTrimmedString,\n position: NonNegativeInteger,\n tokenCount: PositiveInteger,\n metadata: Schema.optional(KnowledgeMetadataSchema)\n})\nexport type KnowledgeChunk = Schema.Schema.Type<typeof KnowledgeChunkSchema>\n\nexport const KnowledgeSearchScopeSchema = Schema.Union([\n Schema.Struct({ _tag: Schema.Literal('KnowledgeScope'), id: NonEmptyTrimmedString }),\n Schema.Struct({\n _tag: Schema.Literal('KnowledgeScopes'),\n ids: Schema.Array(NonEmptyTrimmedString)\n })\n])\nexport type KnowledgeSearchScope = Schema.Schema.Type<typeof KnowledgeSearchScopeSchema>\n\nexport const KnowledgeSourceSchema = Schema.Union([\n Schema.Struct({\n _tag: Schema.Literal('File'),\n ref: NonEmptyTrimmedString,\n name: Schema.optional(NonEmptyTrimmedString),\n mediaType: Schema.optional(NonEmptyTrimmedString)\n }),\n Schema.Struct({\n _tag: Schema.Literal('Url'),\n url: NonEmptyTrimmedString\n }),\n Schema.Struct({\n _tag: Schema.Literal('Text'),\n label: Schema.optional(NonEmptyTrimmedString)\n })\n])\nexport type KnowledgeSource = Schema.Schema.Type<typeof KnowledgeSourceSchema>\n\nexport const IndexedKnowledgeDocumentSchema = Schema.Struct({\n id: NonEmptyTrimmedString,\n scopeId: NonEmptyTrimmedString,\n source: KnowledgeSourceSchema,\n status: KnowledgeDocumentStatusSchema,\n title: Schema.optional(NonEmptyTrimmedString),\n summary: Schema.optional(Schema.String),\n errorMessage: Schema.optional(Schema.String),\n contentHash: Schema.optional(NonEmptyTrimmedString),\n tokenCount: Schema.optional(NonNegativeInteger),\n chunkCount: Schema.optional(NonNegativeInteger),\n metadata: Schema.optional(KnowledgeMetadataSchema)\n})\nexport type IndexedKnowledgeDocument = Schema.Schema.Type<typeof IndexedKnowledgeDocumentSchema>\n\nexport const ExtractedKnowledgeDocumentSchema = Schema.Struct({\n content: NonEmptyTrimmedString,\n title: Schema.optional(NonEmptyTrimmedString),\n summary: Schema.optional(Schema.String),\n metadata: Schema.optional(KnowledgeMetadataSchema)\n})\nexport type ExtractedKnowledgeDocument = Schema.Schema.Type<typeof ExtractedKnowledgeDocumentSchema>\n\nexport const defaultKnowledgeChunkMaxTokens = 512\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"extraction.d.mts","names":[],"sources":["../src/extraction.ts"],"mappings":";;;;;KAKY,qBAAA;EAAA,SACD,MAAA,EAAQ,eAAA;EAAA,SACR,OAAA,WAAkB,UAAA;EAAA,SAClB,SAAA;EAAA,SACA,QAAA,GAAW,iBAAA;AAAA;AAAA,KAGV,qBAAA;EAAA,SACD,OAAA,GACP,MAAA,EAAQ,qBAAA,KACL,MAAA,CAAO,MAAA,CAAO,0BAAA,EAA4B,wBAAA;AAAA;AAAA,cAChD,uBAAA;cAEY,kBAAA,SAA2B,uBAEvC"}
1
+ {"version":3,"file":"extraction.d.mts","names":[],"sources":["../src/extraction.ts"],"mappings":";;;;;KAKY,qBAAA;EAAA,SACD,MAAA,EAAQ,eAAA;EAAA,SACR,OAAA,WAAkB,UAAA;EAAA,SAClB,SAAA;EAAA,SACA,QAAA,GAAW,iBAAA;AAAA;AAAA,KAGV,qBAAA;EAAA,SACD,OAAA,GACP,MAAA,EAAQ,qBAAA,KACL,MAAA,CAAO,MAAA,CAAO,0BAAA,EAA4B,wBAAA;AAAA;AAAA,cAChD,uBAAA;cAEY,kBAAA,SAA2B,uBAGK"}
@@ -1 +1 @@
1
- {"version":3,"file":"extraction.mjs","names":[],"sources":["../src/extraction.ts"],"sourcesContent":["import { Context } from 'effect'\nimport type { Effect } from 'effect'\nimport type { ExtractedKnowledgeDocument, KnowledgeMetadata, KnowledgeSource } from './documents.ts'\nimport type { KnowledgeExtractionError } from './errors.ts'\n\nexport type LoadedKnowledgeSource = {\n readonly source: KnowledgeSource\n readonly content: string | Uint8Array\n readonly mediaType?: string\n readonly metadata?: KnowledgeMetadata\n}\n\nexport type KnowledgeExtractorApi = {\n readonly extract: (\n source: LoadedKnowledgeSource\n ) => Effect.Effect<ExtractedKnowledgeDocument, KnowledgeExtractionError>\n}\n\nexport class KnowledgeExtractor extends Context.Service<KnowledgeExtractor, KnowledgeExtractorApi>()(\n '@yolk-sdk/knowledge/KnowledgeExtractor'\n) {}\n"],"mappings":";;AAkBA,IAAa,qBAAb,cAAwC,QAAQ,QAAmD,EACjG,wCACF,EAAE,CAAC"}
1
+ {"version":3,"file":"extraction.mjs","names":[],"sources":["../src/extraction.ts"],"sourcesContent":["import { Context } from 'effect'\nimport type { Effect } from 'effect'\nimport type { ExtractedKnowledgeDocument, KnowledgeMetadata, KnowledgeSource } from './documents.ts'\nimport type { KnowledgeExtractionError } from './errors.ts'\n\nexport type LoadedKnowledgeSource = {\n readonly source: KnowledgeSource\n readonly content: string | Uint8Array\n readonly mediaType?: string\n readonly metadata?: KnowledgeMetadata\n}\n\nexport type KnowledgeExtractorApi = {\n readonly extract: (\n source: LoadedKnowledgeSource\n ) => Effect.Effect<ExtractedKnowledgeDocument, KnowledgeExtractionError>\n}\n\nexport class KnowledgeExtractor extends Context.Service<\n KnowledgeExtractor,\n KnowledgeExtractorApi\n>()('@yolk-sdk/knowledge/KnowledgeExtractor') {}\n"],"mappings":";;AAkBA,IAAa,qBAAb,cAAwC,QAAQ,QAG9C,EAAE,wCAAwC,EAAE,CAAC"}
@@ -16,8 +16,8 @@ type IngestKnowledgeDocumentInput = {
16
16
  };
17
17
  declare const ingestKnowledgeDocument: (input: IngestKnowledgeDocumentInput) => Effect.Effect<{
18
18
  readonly id: string;
19
- readonly status: "processing" | "ready" | "error";
20
19
  readonly scopeId: string;
20
+ readonly status: "processing" | "ready" | "error";
21
21
  readonly source: {
22
22
  readonly _tag: "File";
23
23
  readonly ref: string;
@@ -30,16 +30,16 @@ declare const ingestKnowledgeDocument: (input: IngestKnowledgeDocumentInput) =>
30
30
  readonly _tag: "Text";
31
31
  readonly label?: string | undefined;
32
32
  };
33
- readonly summary?: string | undefined;
34
- readonly errorMessage?: string | undefined;
35
33
  readonly metadata?: {
36
34
  readonly [x: string]: unknown;
37
35
  } | undefined;
38
- readonly title?: string | undefined;
39
36
  readonly tokenCount?: number | undefined;
37
+ readonly summary?: string | undefined;
38
+ readonly errorMessage?: string | undefined;
39
+ readonly title?: string | undefined;
40
40
  readonly contentHash?: string | undefined;
41
41
  readonly chunkCount?: number | undefined;
42
- }, KnowledgeIngestionError, KnowledgeSummarizer | KnowledgeChunker | KnowledgeExtractor | SearchIndexStore | KnowledgeEmbedder>;
42
+ }, KnowledgeIngestionError, KnowledgeSummarizer | KnowledgeChunker | KnowledgeEmbedder | KnowledgeExtractor | SearchIndexStore>;
43
43
  type KnowledgeIngestionPipeline = {
44
44
  readonly ingest: (input: IngestKnowledgeDocumentInput) => ReturnType<typeof ingestKnowledgeDocument>;
45
45
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ingestion.d.mts","names":[],"sources":["../src/ingestion.ts"],"mappings":";;;;;;;;;KAUY,4BAAA;EAAA,SACD,OAAA;EAAA,SACA,UAAA;EAAA,SACA,MAAA,EAAQ,qBAAqB;EAAA,SAC7B,WAAA;EAAA,SACA,SAAA;AAAA;AAAA,cAaE,uBAAA,GAA2B,KAAA,EAAO,4BAAA,KAA4B,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;KAqH/D,0BAAA;EAAA,SACD,MAAA,GAAS,KAAA,EAAO,4BAAA,KAAiC,UAAA,QAAkB,uBAAA;AAAA;AAAA,cAGjE,qBAAA,QAA4B,0BAEvC"}
1
+ {"version":3,"file":"ingestion.d.mts","names":[],"sources":["../src/ingestion.ts"],"mappings":";;;;;;;;;KAUY,4BAAA;EAAA,SACD,OAAA;EAAA,SACA,UAAA;EAAA,SACA,MAAA,EAAQ,qBAAqB;EAAA,SAC7B,WAAA;EAAA,SACA,SAAA;AAAA;AAAA,cAaE,uBAAA,GAA2B,KAAA,EAAO,4BAAA,KAA4B,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;KA0I/D,0BAAA;EAAA,SACD,MAAA,GACP,KAAA,EAAO,4BAAA,KACJ,UAAA,QAAkB,uBAAA;AAAA;AAAA,cAGZ,qBAAA,QAA4B,0BAEvC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ingestion.mjs","names":["Arr"],"sources":["../src/ingestion.ts"],"sourcesContent":["import { Array as Arr, Effect } from 'effect'\nimport { KnowledgeChunker } from './chunking.ts'\nimport { defaultKnowledgeChunkMaxTokens } from './documents.ts'\nimport { KnowledgeEmbedder } from './embeddings.ts'\nimport { KnowledgeExtractor } from './extraction.ts'\nimport { KnowledgeSummarizer } from './summarization.ts'\nimport type { LoadedKnowledgeSource } from './extraction.ts'\nimport { KnowledgeIngestionError } from './errors.ts'\nimport { SearchIndexStore } from './store.ts'\n\nexport type IngestKnowledgeDocumentInput = {\n readonly scopeId: string\n readonly documentId: string\n readonly source: LoadedKnowledgeSource\n readonly contentHash?: string\n readonly maxTokens?: number\n}\n\nconst markErrorBestEffort = (input: IngestKnowledgeDocumentInput, error: KnowledgeIngestionError) =>\n Effect.gen(function* () {\n const store = yield* SearchIndexStore\n yield* store.markDocumentError({\n scopeId: input.scopeId,\n documentId: input.documentId,\n message: error.message\n })\n }).pipe(Effect.catch(() => Effect.void))\n\nexport const ingestKnowledgeDocument = (input: IngestKnowledgeDocumentInput) =>\n Effect.gen(function* () {\n yield* Effect.annotateCurrentSpan({\n 'knowledge_search.scope_id': input.scopeId,\n 'knowledge_search.document_id': input.documentId,\n 'knowledge_search.source_type': input.source.source._tag\n })\n const store = yield* SearchIndexStore\n const extractor = yield* KnowledgeExtractor\n const chunker = yield* KnowledgeChunker\n const embedder = yield* KnowledgeEmbedder\n const summarizer = yield* KnowledgeSummarizer\n\n yield* store\n .upsertDocument({\n document: {\n id: input.documentId,\n scopeId: input.scopeId,\n source: input.source.source,\n status: 'processing',\n metadata: input.source.metadata\n }\n })\n .pipe(\n Effect.mapError(\n error => new KnowledgeIngestionError({ message: error.message, stage: 'store', cause: error })\n )\n )\n\n const extracted = yield* extractor\n .extract(input.source)\n .pipe(\n Effect.mapError(\n error => new KnowledgeIngestionError({ message: error.message, stage: 'extract', cause: error })\n )\n )\n\n const chunks = yield* chunker\n .chunk({\n scopeId: input.scopeId,\n documentId: input.documentId,\n content: extracted.content,\n maxTokens: input.maxTokens ?? defaultKnowledgeChunkMaxTokens,\n metadata: extracted.metadata\n })\n .pipe(\n Effect.mapError(\n error => new KnowledgeIngestionError({ message: error.message, stage: 'chunk', cause: error })\n )\n )\n\n const indexed = yield* Effect.all(\n {\n embeddings: embedder.embedTexts(chunks.map(chunk => chunk.content)).pipe(\n Effect.mapError(\n error => new KnowledgeIngestionError({ message: error.message, stage: 'embed', cause: error })\n )\n ),\n summary: summarizer\n .summarize({\n content: extracted.content,\n sourceTitle: extracted.title,\n metadata: extracted.metadata\n })\n .pipe(\n Effect.mapError(\n error =>\n new KnowledgeIngestionError({ message: error.message, stage: 'summarize', cause: error })\n )\n )\n },\n { concurrency: 'unbounded' }\n )\n\n if (indexed.embeddings.length !== chunks.length) {\n return yield* Effect.fail(\n new KnowledgeIngestionError({ message: 'Embedding count did not match chunk count', stage: 'embed' })\n )\n }\n\n const indexedChunks = Arr.zip(chunks, indexed.embeddings).map(([chunk, embedding]) => ({\n chunk,\n embedding\n }))\n yield* store\n .replaceDocumentChunks({\n scopeId: input.scopeId,\n documentId: input.documentId,\n chunks: indexedChunks\n })\n .pipe(\n Effect.mapError(\n error => new KnowledgeIngestionError({ message: error.message, stage: 'store', cause: error })\n )\n )\n\n const tokenCount = chunks.reduce((total, chunk) => total + chunk.tokenCount, 0)\n return yield* store\n .markDocumentReady({\n scopeId: input.scopeId,\n documentId: input.documentId,\n title: indexed.summary.title ?? extracted.title,\n summary: indexed.summary.summary ?? extracted.summary,\n contentHash: input.contentHash,\n tokenCount,\n chunkCount: chunks.length\n })\n .pipe(\n Effect.mapError(\n error => new KnowledgeIngestionError({ message: error.message, stage: 'store', cause: error })\n )\n )\n }).pipe(\n Effect.withSpan('knowledge_search.ingestDocument'),\n Effect.catch(error => markErrorBestEffort(input, error).pipe(Effect.flatMap(() => Effect.fail(error))))\n )\n\nexport type KnowledgeIngestionPipeline = {\n readonly ingest: (input: IngestKnowledgeDocumentInput) => ReturnType<typeof ingestKnowledgeDocument>\n}\n\nexport const makeIngestionPipeline = (): KnowledgeIngestionPipeline => ({\n ingest: ingestKnowledgeDocument\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"ingestion.mjs","names":["Arr"],"sources":["../src/ingestion.ts"],"sourcesContent":["import { Array as Arr, Effect } from 'effect'\nimport { KnowledgeChunker } from './chunking.ts'\nimport { defaultKnowledgeChunkMaxTokens } from './documents.ts'\nimport { KnowledgeEmbedder } from './embeddings.ts'\nimport { KnowledgeExtractor } from './extraction.ts'\nimport { KnowledgeSummarizer } from './summarization.ts'\nimport type { LoadedKnowledgeSource } from './extraction.ts'\nimport { KnowledgeIngestionError } from './errors.ts'\nimport { SearchIndexStore } from './store.ts'\n\nexport type IngestKnowledgeDocumentInput = {\n readonly scopeId: string\n readonly documentId: string\n readonly source: LoadedKnowledgeSource\n readonly contentHash?: string\n readonly maxTokens?: number\n}\n\nconst markErrorBestEffort = (input: IngestKnowledgeDocumentInput, error: KnowledgeIngestionError) =>\n Effect.gen(function* () {\n const store = yield* SearchIndexStore\n yield* store.markDocumentError({\n scopeId: input.scopeId,\n documentId: input.documentId,\n message: error.message\n })\n }).pipe(Effect.catch(() => Effect.void))\n\nexport const ingestKnowledgeDocument = (input: IngestKnowledgeDocumentInput) =>\n Effect.gen(function* () {\n yield* Effect.annotateCurrentSpan({\n 'knowledge_search.scope_id': input.scopeId,\n 'knowledge_search.document_id': input.documentId,\n 'knowledge_search.source_type': input.source.source._tag\n })\n const store = yield* SearchIndexStore\n const extractor = yield* KnowledgeExtractor\n const chunker = yield* KnowledgeChunker\n const embedder = yield* KnowledgeEmbedder\n const summarizer = yield* KnowledgeSummarizer\n\n yield* store\n .upsertDocument({\n document: {\n id: input.documentId,\n scopeId: input.scopeId,\n source: input.source.source,\n status: 'processing',\n metadata: input.source.metadata\n }\n })\n .pipe(\n Effect.mapError(\n error =>\n new KnowledgeIngestionError({ message: error.message, stage: 'store', cause: error })\n )\n )\n\n const extracted = yield* extractor\n .extract(input.source)\n .pipe(\n Effect.mapError(\n error =>\n new KnowledgeIngestionError({ message: error.message, stage: 'extract', cause: error })\n )\n )\n\n const chunks = yield* chunker\n .chunk({\n scopeId: input.scopeId,\n documentId: input.documentId,\n content: extracted.content,\n maxTokens: input.maxTokens ?? defaultKnowledgeChunkMaxTokens,\n metadata: extracted.metadata\n })\n .pipe(\n Effect.mapError(\n error =>\n new KnowledgeIngestionError({ message: error.message, stage: 'chunk', cause: error })\n )\n )\n\n const indexed = yield* Effect.all(\n {\n embeddings: embedder\n .embedTexts(chunks.map(chunk => chunk.content))\n .pipe(\n Effect.mapError(\n error =>\n new KnowledgeIngestionError({\n message: error.message,\n stage: 'embed',\n cause: error\n })\n )\n ),\n summary: summarizer\n .summarize({\n content: extracted.content,\n sourceTitle: extracted.title,\n metadata: extracted.metadata\n })\n .pipe(\n Effect.mapError(\n error =>\n new KnowledgeIngestionError({\n message: error.message,\n stage: 'summarize',\n cause: error\n })\n )\n )\n },\n { concurrency: 'unbounded' }\n )\n\n if (indexed.embeddings.length !== chunks.length) {\n return yield* Effect.fail(\n new KnowledgeIngestionError({\n message: 'Embedding count did not match chunk count',\n stage: 'embed'\n })\n )\n }\n\n const indexedChunks = Arr.zip(chunks, indexed.embeddings).map(([chunk, embedding]) => ({\n chunk,\n embedding\n }))\n yield* store\n .replaceDocumentChunks({\n scopeId: input.scopeId,\n documentId: input.documentId,\n chunks: indexedChunks\n })\n .pipe(\n Effect.mapError(\n error =>\n new KnowledgeIngestionError({ message: error.message, stage: 'store', cause: error })\n )\n )\n\n const tokenCount = chunks.reduce((total, chunk) => total + chunk.tokenCount, 0)\n return yield* store\n .markDocumentReady({\n scopeId: input.scopeId,\n documentId: input.documentId,\n title: indexed.summary.title ?? extracted.title,\n summary: indexed.summary.summary ?? extracted.summary,\n contentHash: input.contentHash,\n tokenCount,\n chunkCount: chunks.length\n })\n .pipe(\n Effect.mapError(\n error =>\n new KnowledgeIngestionError({ message: error.message, stage: 'store', cause: error })\n )\n )\n }).pipe(\n Effect.withSpan('knowledge_search.ingestDocument'),\n Effect.catch(error =>\n markErrorBestEffort(input, error).pipe(Effect.flatMap(() => Effect.fail(error)))\n )\n )\n\nexport type KnowledgeIngestionPipeline = {\n readonly ingest: (\n input: IngestKnowledgeDocumentInput\n ) => ReturnType<typeof ingestKnowledgeDocument>\n}\n\nexport const makeIngestionPipeline = (): KnowledgeIngestionPipeline => ({\n ingest: ingestKnowledgeDocument\n})\n"],"mappings":"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"}
package/dist/search.d.mts CHANGED
@@ -43,7 +43,7 @@ declare const fuseKnowledgeSearchResults: (input: {
43
43
  readonly limit: number;
44
44
  readonly rankConstant?: number;
45
45
  }) => ReadonlyArray<KnowledgeSearchResult>;
46
- declare const searchKnowledge: (input: KnowledgeSearchInput) => Effect.Effect<readonly KnowledgeSearchResult[], KnowledgeSearchError, SearchIndexStore | KnowledgeEmbedder>;
46
+ declare const searchKnowledge: (input: KnowledgeSearchInput) => Effect.Effect<readonly KnowledgeSearchResult[], KnowledgeSearchError, KnowledgeEmbedder | SearchIndexStore>;
47
47
  //#endregion
48
48
  export { KnowledgeSearchContext, KnowledgeSearchInput, KnowledgeSearchMode, KnowledgeSearchResult, KnowledgeSearchScores, KnowledgeSearcher, fuseKnowledgeSearchResults, packKnowledgeSearchContext, searchKnowledge };
49
49
  //# sourceMappingURL=search.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"search.d.mts","names":[],"sources":["../src/search.ts"],"mappings":";;;;;;;KAMY,oBAAA;EAAA,SACD,KAAA,EAAO,oBAAA;EAAA,SACP,KAAA;EAAA,SACA,KAAA;EAAA,SACA,QAAA;EAAA,SACA,aAAA;EAAA,SACA,IAAA,GAAO,mBAAmB;EAAA,SAC1B,WAAA;EAAA,SACA,SAAA;AAAA;AAAA,KAGC,mBAAA;AAAA,KAEA,qBAAA;EAAA,SACD,MAAA;EAAA,SACA,IAAA;EAAA,SACA,KAAA;AAAA;AAAA,KAGC,qBAAA;EAAA,SACD,KAAA,EAAO,cAAA;EAAA,SACP,KAAA;EAAA,SACA,QAAA,EAAU,wBAAA;EAAA,SACV,OAAA,GAAU,aAAA,CAAc,cAAA;EAAA,SACxB,MAAA,GAAS,qBAAA;AAAA;AAAA,KAGR,sBAAA;EAAA,SACD,KAAA;EAAA,SACA,OAAA,EAAS,aAAa,CAAC,qBAAA;EAAA,SACvB,IAAA;AAAA;AAAA,KAGC,iBAAA;EAAA,SACD,MAAA,GACP,KAAA,EAAO,oBAAA,KACJ,MAAA,CAAO,MAAA,CAAO,aAAA,CAAc,qBAAA,GAAwB,oBAAA;AAAA;AAAA,cAM9C,0BAAA,GAA8B,KAAA,UAAe,OAAA,EAAS,aAAA,CAAc,qBAAA,MAAyB,sBAAA;AAAA,cAoB7F,0BAAA,GAA8B,KAAA;EAAA,SAChC,aAAA,EAAe,aAAA,CAAc,qBAAA;EAAA,SAC7B,WAAA,EAAa,aAAA,CAAc,qBAAA;EAAA,SAC3B,KAAA;EAAA,SACA,YAAA;AAAA,MACP,aAAA,CAAc,qBAAA;AAAA,cAsIL,eAAA,GAAmB,KAAA,EAAO,oBAAA,KAAoB,MAAA,CAAA,MAAA,UAAA,qBAAA,IAAA,oBAAA,EAAA,gBAAA,GAAA,iBAAA"}
1
+ {"version":3,"file":"search.d.mts","names":[],"sources":["../src/search.ts"],"mappings":";;;;;;;KAMY,oBAAA;EAAA,SACD,KAAA,EAAO,oBAAA;EAAA,SACP,KAAA;EAAA,SACA,KAAA;EAAA,SACA,QAAA;EAAA,SACA,aAAA;EAAA,SACA,IAAA,GAAO,mBAAmB;EAAA,SAC1B,WAAA;EAAA,SACA,SAAA;AAAA;AAAA,KAGC,mBAAA;AAAA,KAEA,qBAAA;EAAA,SACD,MAAA;EAAA,SACA,IAAA;EAAA,SACA,KAAA;AAAA;AAAA,KAGC,qBAAA;EAAA,SACD,KAAA,EAAO,cAAA;EAAA,SACP,KAAA;EAAA,SACA,QAAA,EAAU,wBAAA;EAAA,SACV,OAAA,GAAU,aAAA,CAAc,cAAA;EAAA,SACxB,MAAA,GAAS,qBAAA;AAAA;AAAA,KAGR,sBAAA;EAAA,SACD,KAAA;EAAA,SACA,OAAA,EAAS,aAAa,CAAC,qBAAA;EAAA,SACvB,IAAA;AAAA;AAAA,KAGC,iBAAA;EAAA,SACD,MAAA,GACP,KAAA,EAAO,oBAAA,KACJ,MAAA,CAAO,MAAA,CAAO,aAAA,CAAc,qBAAA,GAAwB,oBAAA;AAAA;AAAA,cAM9C,0BAAA,GACX,KAAA,UACA,OAAA,EAAS,aAAA,CAAc,qBAAA,MACtB,sBAAA;AAAA,cAmBU,0BAAA,GAA8B,KAAA;EAAA,SAChC,aAAA,EAAe,aAAA,CAAc,qBAAA;EAAA,SAC7B,WAAA,EAAa,aAAA,CAAc,qBAAA;EAAA,SAC3B,KAAA;EAAA,SACA,YAAA;AAAA,MACP,aAAA,CAAc,qBAAA;AAAA,cAyJL,eAAA,GAAmB,KAAA,EAAO,oBAAA,KAAoB,MAAA,CAAA,MAAA,UAAA,qBAAA,IAAA,oBAAA,EAAA,iBAAA,GAAA,gBAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"search.mjs","names":[],"sources":["../src/search.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport type { IndexedKnowledgeDocument, KnowledgeChunk, KnowledgeSearchScope } from './documents.ts'\nimport { KnowledgeEmbedder } from './embeddings.ts'\nimport { KnowledgeSearchError } from './errors.ts'\nimport { SearchIndexStore } from './store.ts'\n\nexport type KnowledgeSearchInput = {\n readonly scope: KnowledgeSearchScope\n readonly query: string\n readonly limit?: number\n readonly minScore?: number\n readonly contextChunks?: number\n readonly mode?: KnowledgeSearchMode\n readonly vectorLimit?: number\n readonly textLimit?: number\n}\n\nexport type KnowledgeSearchMode = 'vector' | 'hybrid'\n\nexport type KnowledgeSearchScores = {\n readonly vector?: number\n readonly text?: number\n readonly fused?: number\n}\n\nexport type KnowledgeSearchResult = {\n readonly chunk: KnowledgeChunk\n readonly score: number\n readonly document: IndexedKnowledgeDocument\n readonly context?: ReadonlyArray<KnowledgeChunk>\n readonly scores?: KnowledgeSearchScores\n}\n\nexport type KnowledgeSearchContext = {\n readonly query: string\n readonly results: ReadonlyArray<KnowledgeSearchResult>\n readonly text: string\n}\n\nexport type KnowledgeSearcher = {\n readonly search: (\n input: KnowledgeSearchInput\n ) => Effect.Effect<ReadonlyArray<KnowledgeSearchResult>, KnowledgeSearchError>\n}\n\nconst packedResultText = (result: KnowledgeSearchResult) =>\n result.context?.map(chunk => chunk.content).join('\\n\\n') ?? result.chunk.content\n\nexport const packKnowledgeSearchContext = (query: string, results: ReadonlyArray<KnowledgeSearchResult>): KnowledgeSearchContext =>\n ({\n query,\n results,\n text: results.map(packedResultText).join('\\n\\n')\n })\n\nconst scopeIds = (scope: KnowledgeSearchScope): ReadonlyArray<string> => {\n switch (scope._tag) {\n case 'KnowledgeScope':\n return [scope.id]\n case 'KnowledgeScopes':\n return scope.ids\n }\n}\n\nconst defaultHybridCandidateLimit = (limit: number) => Math.max(limit * 5, 40)\n\nconst reciprocalRankFusionScore = (rank: number, rankConstant: number) => 1 / (rankConstant + rank)\n\nexport const fuseKnowledgeSearchResults = (input: {\n readonly vectorResults: ReadonlyArray<KnowledgeSearchResult>\n readonly textResults: ReadonlyArray<KnowledgeSearchResult>\n readonly limit: number\n readonly rankConstant?: number\n}): ReadonlyArray<KnowledgeSearchResult> => {\n const rankConstant = input.rankConstant ?? 60\n const fused = new Map<\n string,\n {\n readonly result: KnowledgeSearchResult\n readonly vector?: number\n readonly text?: number\n readonly fused: number\n }\n >()\n\n const addResults = (results: ReadonlyArray<KnowledgeSearchResult>, kind: 'vector' | 'text') => {\n results.forEach((result, index) => {\n const rank = index + 1\n const previous = fused.get(result.chunk.id)\n const nextFused = (previous?.fused ?? 0) + reciprocalRankFusionScore(rank, rankConstant)\n fused.set(result.chunk.id, {\n result: previous?.result ?? result,\n vector: kind === 'vector' ? result.score : previous?.vector,\n text: kind === 'text' ? result.score : previous?.text,\n fused: nextFused\n })\n })\n }\n\n addResults(input.vectorResults, 'vector')\n addResults(input.textResults, 'text')\n\n return Array.from(fused.values())\n .sort((left, right) => right.fused - left.fused)\n .slice(0, input.limit)\n .map(item => ({\n ...item.result,\n score: item.fused,\n scores: { vector: item.vector, text: item.text, fused: item.fused }\n }))\n}\n\nconst validateSearchInput = (input: KnowledgeSearchInput) => {\n const query = input.query.trim()\n const ids = scopeIds(input.scope)\n const limit = input.limit ?? 10\n const contextChunks = input.contextChunks ?? 0\n const mode = input.mode ?? 'hybrid'\n const vectorLimit = input.vectorLimit ?? (mode === 'hybrid' ? defaultHybridCandidateLimit(limit) : limit)\n const textLimit = input.textLimit ?? defaultHybridCandidateLimit(limit)\n\n if (query.length === 0) {\n return Effect.fail(new KnowledgeSearchError({ message: 'Search query is empty', stage: 'embed' }))\n }\n\n if (ids.length === 0) {\n return Effect.fail(new KnowledgeSearchError({ message: 'Search scope is empty', stage: 'store' }))\n }\n\n if (!Number.isInteger(limit) || limit < 1) {\n return Effect.fail(new KnowledgeSearchError({ message: 'Search limit must be positive', stage: 'store' }))\n }\n\n if (!Number.isInteger(vectorLimit) || vectorLimit < 1) {\n return Effect.fail(new KnowledgeSearchError({ message: 'Vector search limit must be positive', stage: 'store' }))\n }\n\n if (!Number.isInteger(textLimit) || textLimit < 1) {\n return Effect.fail(new KnowledgeSearchError({ message: 'Text search limit must be positive', stage: 'store' }))\n }\n\n if (mode !== 'vector' && mode !== 'hybrid') {\n return Effect.fail(new KnowledgeSearchError({ message: 'Search mode is invalid', stage: 'store' }))\n }\n\n if (!Number.isInteger(contextChunks) || contextChunks < 0) {\n return Effect.fail(\n new KnowledgeSearchError({ message: 'Context chunks must be zero or positive', stage: 'store' })\n )\n }\n\n if (input.minScore !== undefined && !Number.isFinite(input.minScore)) {\n return Effect.fail(\n new KnowledgeSearchError({ message: 'Search minScore must be finite', stage: 'store' })\n )\n }\n\n return Effect.succeed({ query, limit, contextChunks, mode, vectorLimit, textLimit })\n}\n\nconst searchVectorChunks = (input: {\n readonly scope: KnowledgeSearchScope\n readonly query: string\n readonly limit: number\n readonly minScore?: number\n}) =>\n Effect.gen(function* () {\n const store = yield* SearchIndexStore\n const embedder = yield* KnowledgeEmbedder\n const embedding = yield* embedder\n .embedQuery(input.query)\n .pipe(\n Effect.mapError(\n error => new KnowledgeSearchError({ message: error.message, stage: 'embed', cause: error })\n )\n )\n\n return yield* store\n .searchChunks({\n scope: input.scope,\n embedding,\n limit: input.limit,\n minScore: input.minScore\n })\n .pipe(\n Effect.mapError(\n error => new KnowledgeSearchError({ message: error.message, stage: 'store', cause: error })\n )\n )\n })\n\nconst searchTextChunks = (input: {\n readonly scope: KnowledgeSearchScope\n readonly query: string\n readonly limit: number\n}) =>\n Effect.gen(function* () {\n const store = yield* SearchIndexStore\n return yield* store\n .searchChunksByText({ scope: input.scope, query: input.query, limit: input.limit })\n .pipe(\n Effect.mapError(\n error => new KnowledgeSearchError({ message: error.message, stage: 'store', cause: error })\n )\n )\n })\n\nexport const searchKnowledge = (input: KnowledgeSearchInput) =>\n Effect.gen(function* () {\n const valid = yield* validateSearchInput(input)\n yield* Effect.annotateCurrentSpan({\n 'knowledge_search.query_length': valid.query.length,\n 'knowledge_search.limit': valid.limit,\n 'knowledge_search.mode': valid.mode,\n 'knowledge_search.context_chunks': valid.contextChunks,\n 'knowledge_search.scope_count': scopeIds(input.scope).length\n })\n const store = yield* SearchIndexStore\n const results: ReadonlyArray<KnowledgeSearchResult> = valid.mode === 'vector'\n ? yield* searchVectorChunks({\n scope: input.scope,\n query: valid.query,\n limit: valid.vectorLimit,\n minScore: input.minScore\n })\n : yield* Effect.gen(function* () {\n const searches = yield* Effect.all(\n {\n vectorResults: searchVectorChunks({\n scope: input.scope,\n query: valid.query,\n limit: valid.vectorLimit,\n minScore: input.minScore\n }),\n textResults: searchTextChunks({\n scope: input.scope,\n query: valid.query,\n limit: valid.textLimit\n })\n },\n { concurrency: 'unbounded' }\n )\n\n return fuseKnowledgeSearchResults({\n vectorResults: searches.vectorResults,\n textResults: searches.textResults,\n limit: valid.limit\n })\n })\n\n if (valid.contextChunks === 0) {\n return results\n }\n\n return yield* Effect.forEach(results, result =>\n store\n .getContextChunks({\n scopeId: result.chunk.scopeId,\n documentId: result.chunk.documentId,\n position: result.chunk.position,\n contextChunks: valid.contextChunks\n })\n .pipe(\n Effect.map(context => ({ ...result, context })),\n Effect.mapError(\n error => new KnowledgeSearchError({ message: error.message, stage: 'store', cause: error })\n )\n )\n )\n }).pipe(Effect.withSpan('knowledge_search.search'))\n"],"mappings":"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"}
1
+ {"version":3,"file":"search.mjs","names":[],"sources":["../src/search.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport type { IndexedKnowledgeDocument, KnowledgeChunk, KnowledgeSearchScope } from './documents.ts'\nimport { KnowledgeEmbedder } from './embeddings.ts'\nimport { KnowledgeSearchError } from './errors.ts'\nimport { SearchIndexStore } from './store.ts'\n\nexport type KnowledgeSearchInput = {\n readonly scope: KnowledgeSearchScope\n readonly query: string\n readonly limit?: number\n readonly minScore?: number\n readonly contextChunks?: number\n readonly mode?: KnowledgeSearchMode\n readonly vectorLimit?: number\n readonly textLimit?: number\n}\n\nexport type KnowledgeSearchMode = 'vector' | 'hybrid'\n\nexport type KnowledgeSearchScores = {\n readonly vector?: number\n readonly text?: number\n readonly fused?: number\n}\n\nexport type KnowledgeSearchResult = {\n readonly chunk: KnowledgeChunk\n readonly score: number\n readonly document: IndexedKnowledgeDocument\n readonly context?: ReadonlyArray<KnowledgeChunk>\n readonly scores?: KnowledgeSearchScores\n}\n\nexport type KnowledgeSearchContext = {\n readonly query: string\n readonly results: ReadonlyArray<KnowledgeSearchResult>\n readonly text: string\n}\n\nexport type KnowledgeSearcher = {\n readonly search: (\n input: KnowledgeSearchInput\n ) => Effect.Effect<ReadonlyArray<KnowledgeSearchResult>, KnowledgeSearchError>\n}\n\nconst packedResultText = (result: KnowledgeSearchResult) =>\n result.context?.map(chunk => chunk.content).join('\\n\\n') ?? result.chunk.content\n\nexport const packKnowledgeSearchContext = (\n query: string,\n results: ReadonlyArray<KnowledgeSearchResult>\n): KnowledgeSearchContext => ({\n query,\n results,\n text: results.map(packedResultText).join('\\n\\n')\n})\n\nconst scopeIds = (scope: KnowledgeSearchScope): ReadonlyArray<string> => {\n switch (scope._tag) {\n case 'KnowledgeScope':\n return [scope.id]\n case 'KnowledgeScopes':\n return scope.ids\n }\n}\n\nconst defaultHybridCandidateLimit = (limit: number) => Math.max(limit * 5, 40)\n\nconst reciprocalRankFusionScore = (rank: number, rankConstant: number) => 1 / (rankConstant + rank)\n\nexport const fuseKnowledgeSearchResults = (input: {\n readonly vectorResults: ReadonlyArray<KnowledgeSearchResult>\n readonly textResults: ReadonlyArray<KnowledgeSearchResult>\n readonly limit: number\n readonly rankConstant?: number\n}): ReadonlyArray<KnowledgeSearchResult> => {\n const rankConstant = input.rankConstant ?? 60\n const fused = new Map<\n string,\n {\n readonly result: KnowledgeSearchResult\n readonly vector?: number\n readonly text?: number\n readonly fused: number\n }\n >()\n\n const addResults = (results: ReadonlyArray<KnowledgeSearchResult>, kind: 'vector' | 'text') => {\n results.forEach((result, index) => {\n const rank = index + 1\n const previous = fused.get(result.chunk.id)\n const nextFused = (previous?.fused ?? 0) + reciprocalRankFusionScore(rank, rankConstant)\n fused.set(result.chunk.id, {\n result: previous?.result ?? result,\n vector: kind === 'vector' ? result.score : previous?.vector,\n text: kind === 'text' ? result.score : previous?.text,\n fused: nextFused\n })\n })\n }\n\n addResults(input.vectorResults, 'vector')\n addResults(input.textResults, 'text')\n\n return Array.from(fused.values())\n .sort((left, right) => right.fused - left.fused)\n .slice(0, input.limit)\n .map(item => ({\n ...item.result,\n score: item.fused,\n scores: { vector: item.vector, text: item.text, fused: item.fused }\n }))\n}\n\nconst validateSearchInput = (input: KnowledgeSearchInput) => {\n const query = input.query.trim()\n const ids = scopeIds(input.scope)\n const limit = input.limit ?? 10\n const contextChunks = input.contextChunks ?? 0\n const mode = input.mode ?? 'hybrid'\n const vectorLimit =\n input.vectorLimit ?? (mode === 'hybrid' ? defaultHybridCandidateLimit(limit) : limit)\n const textLimit = input.textLimit ?? defaultHybridCandidateLimit(limit)\n\n if (query.length === 0) {\n return Effect.fail(\n new KnowledgeSearchError({ message: 'Search query is empty', stage: 'embed' })\n )\n }\n\n if (ids.length === 0) {\n return Effect.fail(\n new KnowledgeSearchError({ message: 'Search scope is empty', stage: 'store' })\n )\n }\n\n if (!Number.isInteger(limit) || limit < 1) {\n return Effect.fail(\n new KnowledgeSearchError({ message: 'Search limit must be positive', stage: 'store' })\n )\n }\n\n if (!Number.isInteger(vectorLimit) || vectorLimit < 1) {\n return Effect.fail(\n new KnowledgeSearchError({ message: 'Vector search limit must be positive', stage: 'store' })\n )\n }\n\n if (!Number.isInteger(textLimit) || textLimit < 1) {\n return Effect.fail(\n new KnowledgeSearchError({ message: 'Text search limit must be positive', stage: 'store' })\n )\n }\n\n if (mode !== 'vector' && mode !== 'hybrid') {\n return Effect.fail(\n new KnowledgeSearchError({ message: 'Search mode is invalid', stage: 'store' })\n )\n }\n\n if (!Number.isInteger(contextChunks) || contextChunks < 0) {\n return Effect.fail(\n new KnowledgeSearchError({\n message: 'Context chunks must be zero or positive',\n stage: 'store'\n })\n )\n }\n\n if (input.minScore !== undefined && !Number.isFinite(input.minScore)) {\n return Effect.fail(\n new KnowledgeSearchError({ message: 'Search minScore must be finite', stage: 'store' })\n )\n }\n\n return Effect.succeed({ query, limit, contextChunks, mode, vectorLimit, textLimit })\n}\n\nconst searchVectorChunks = (input: {\n readonly scope: KnowledgeSearchScope\n readonly query: string\n readonly limit: number\n readonly minScore?: number\n}) =>\n Effect.gen(function* () {\n const store = yield* SearchIndexStore\n const embedder = yield* KnowledgeEmbedder\n const embedding = yield* embedder\n .embedQuery(input.query)\n .pipe(\n Effect.mapError(\n error =>\n new KnowledgeSearchError({ message: error.message, stage: 'embed', cause: error })\n )\n )\n\n return yield* store\n .searchChunks({\n scope: input.scope,\n embedding,\n limit: input.limit,\n minScore: input.minScore\n })\n .pipe(\n Effect.mapError(\n error =>\n new KnowledgeSearchError({ message: error.message, stage: 'store', cause: error })\n )\n )\n })\n\nconst searchTextChunks = (input: {\n readonly scope: KnowledgeSearchScope\n readonly query: string\n readonly limit: number\n}) =>\n Effect.gen(function* () {\n const store = yield* SearchIndexStore\n return yield* store\n .searchChunksByText({ scope: input.scope, query: input.query, limit: input.limit })\n .pipe(\n Effect.mapError(\n error =>\n new KnowledgeSearchError({ message: error.message, stage: 'store', cause: error })\n )\n )\n })\n\nexport const searchKnowledge = (input: KnowledgeSearchInput) =>\n Effect.gen(function* () {\n const valid = yield* validateSearchInput(input)\n yield* Effect.annotateCurrentSpan({\n 'knowledge_search.query_length': valid.query.length,\n 'knowledge_search.limit': valid.limit,\n 'knowledge_search.mode': valid.mode,\n 'knowledge_search.context_chunks': valid.contextChunks,\n 'knowledge_search.scope_count': scopeIds(input.scope).length\n })\n const store = yield* SearchIndexStore\n const results: ReadonlyArray<KnowledgeSearchResult> =\n valid.mode === 'vector'\n ? yield* searchVectorChunks({\n scope: input.scope,\n query: valid.query,\n limit: valid.vectorLimit,\n minScore: input.minScore\n })\n : yield* Effect.gen(function* () {\n const searches = yield* Effect.all(\n {\n vectorResults: searchVectorChunks({\n scope: input.scope,\n query: valid.query,\n limit: valid.vectorLimit,\n minScore: input.minScore\n }),\n textResults: searchTextChunks({\n scope: input.scope,\n query: valid.query,\n limit: valid.textLimit\n })\n },\n { concurrency: 'unbounded' }\n )\n\n return fuseKnowledgeSearchResults({\n vectorResults: searches.vectorResults,\n textResults: searches.textResults,\n limit: valid.limit\n })\n })\n\n if (valid.contextChunks === 0) {\n return results\n }\n\n return yield* Effect.forEach(results, result =>\n store\n .getContextChunks({\n scopeId: result.chunk.scopeId,\n documentId: result.chunk.documentId,\n position: result.chunk.position,\n contextChunks: valid.contextChunks\n })\n .pipe(\n Effect.map(context => ({ ...result, context })),\n Effect.mapError(\n error =>\n new KnowledgeSearchError({ message: error.message, stage: 'store', cause: error })\n )\n )\n )\n }).pipe(Effect.withSpan('knowledge_search.search'))\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.mts","names":[],"sources":["../src/store.ts"],"mappings":"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"}
1
+ {"version":3,"file":"store.d.mts","names":[],"sources":["../src/store.ts"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"store.mjs","names":[],"sources":["../src/store.ts"],"sourcesContent":["import { Context } from 'effect'\nimport type { Effect } from 'effect'\nimport type {\n CreateKnowledgeDocumentInput,\n IndexedKnowledgeDocument,\n KnowledgeChunk,\n KnowledgeDocument,\n KnowledgeFile,\n KnowledgeScope,\n KnowledgeSearchScope,\n UpdateKnowledgeDocumentInput\n} from './documents.ts'\nimport type { KnowledgeEmbedding } from './embeddings.ts'\nimport type { KnowledgeStoreError, SearchIndexStoreError } from './errors.ts'\n\nexport type GetKnowledgeDocumentInput = {\n readonly scope: KnowledgeScope\n readonly id: string\n}\n\nexport type GetKnowledgeDocumentBySlugInput = {\n readonly scope: KnowledgeScope\n readonly slug: string\n}\n\nexport type ListKnowledgeDocumentsInput = {\n readonly scope: KnowledgeScope\n readonly limit: number\n readonly availability?: KnowledgeDocument['availability']\n}\n\nexport type ListKnowledgeDocumentsResult = {\n readonly documents: ReadonlyArray<KnowledgeDocument>\n}\n\nexport type ListPinnedKnowledgeInput = {\n readonly scope: KnowledgeScope\n readonly limit: number\n}\n\nexport type ListPinnedKnowledgeResult = {\n readonly documents: ReadonlyArray<KnowledgeDocument>\n}\n\nexport type KnowledgeStoreApi = {\n readonly createDocument: (\n input: CreateKnowledgeDocumentInput\n ) => Effect.Effect<KnowledgeDocument, KnowledgeStoreError>\n readonly updateDocument: (\n input: UpdateKnowledgeDocumentInput\n ) => Effect.Effect<KnowledgeDocument, KnowledgeStoreError>\n readonly getDocument: (\n input: GetKnowledgeDocumentInput\n ) => Effect.Effect<KnowledgeDocument, KnowledgeStoreError>\n readonly getDocumentBySlug: (\n input: GetKnowledgeDocumentBySlugInput\n ) => Effect.Effect<KnowledgeDocument, KnowledgeStoreError>\n readonly listDocuments: (\n input: ListKnowledgeDocumentsInput\n ) => Effect.Effect<ListKnowledgeDocumentsResult, KnowledgeStoreError>\n readonly listPinned: (\n input: ListPinnedKnowledgeInput\n ) => Effect.Effect<ListPinnedKnowledgeResult, KnowledgeStoreError>\n readonly deleteDocument: (input: GetKnowledgeDocumentInput) => Effect.Effect<void, KnowledgeStoreError>\n readonly listFiles: (input: GetKnowledgeDocumentInput) => Effect.Effect<ReadonlyArray<KnowledgeFile>, KnowledgeStoreError>\n}\n\nexport class KnowledgeStore extends Context.Service<KnowledgeStore, KnowledgeStoreApi>()(\n '@yolk-sdk/knowledge/KnowledgeStore'\n) {}\n\nexport type UpsertIndexedKnowledgeDocumentInput = {\n readonly document: IndexedKnowledgeDocument\n}\n\nexport type ReplaceKnowledgeDocumentChunksInput = {\n readonly scopeId: string\n readonly documentId: string\n readonly chunks: ReadonlyArray<{\n readonly chunk: KnowledgeChunk\n readonly embedding: KnowledgeEmbedding\n }>\n}\n\nexport type MarkKnowledgeDocumentReadyInput = {\n readonly scopeId: string\n readonly documentId: string\n readonly title?: string\n readonly summary?: string\n readonly contentHash?: string\n readonly tokenCount: number\n readonly chunkCount: number\n}\n\nexport type MarkKnowledgeDocumentErrorInput = {\n readonly scopeId: string\n readonly documentId: string\n readonly message: string\n}\n\nexport type KnowledgeChunkSearchInput = {\n readonly scope: KnowledgeSearchScope\n readonly embedding: KnowledgeEmbedding\n readonly limit: number\n readonly minScore?: number\n}\n\nexport type KnowledgeChunkTextSearchInput = {\n readonly scope: KnowledgeSearchScope\n readonly query: string\n readonly limit: number\n}\n\nexport type KnowledgeChunkSearchResult = {\n readonly chunk: KnowledgeChunk\n readonly score: number\n readonly document: IndexedKnowledgeDocument\n}\n\nexport type KnowledgeSearchContextChunksInput = {\n readonly scopeId: string\n readonly documentId: string\n readonly position: number\n readonly contextChunks: number\n}\n\nexport type SearchIndexStoreApi = {\n readonly upsertDocument: (\n input: UpsertIndexedKnowledgeDocumentInput\n ) => Effect.Effect<IndexedKnowledgeDocument, SearchIndexStoreError>\n readonly markDocumentProcessing: (input: {\n readonly scopeId: string\n readonly documentId: string\n }) => Effect.Effect<IndexedKnowledgeDocument, SearchIndexStoreError>\n readonly replaceDocumentChunks: (\n input: ReplaceKnowledgeDocumentChunksInput\n ) => Effect.Effect<void, SearchIndexStoreError>\n readonly markDocumentReady: (\n input: MarkKnowledgeDocumentReadyInput\n ) => Effect.Effect<IndexedKnowledgeDocument, SearchIndexStoreError>\n readonly markDocumentError: (\n input: MarkKnowledgeDocumentErrorInput\n ) => Effect.Effect<void, SearchIndexStoreError>\n readonly deleteDocument: (input: {\n readonly scopeId: string\n readonly documentId: string\n }) => Effect.Effect<void, SearchIndexStoreError>\n readonly searchChunks: (\n input: KnowledgeChunkSearchInput\n ) => Effect.Effect<ReadonlyArray<KnowledgeChunkSearchResult>, SearchIndexStoreError>\n readonly searchChunksByText: (\n input: KnowledgeChunkTextSearchInput\n ) => Effect.Effect<ReadonlyArray<KnowledgeChunkSearchResult>, SearchIndexStoreError>\n readonly getContextChunks: (\n input: KnowledgeSearchContextChunksInput\n ) => Effect.Effect<ReadonlyArray<KnowledgeChunk>, SearchIndexStoreError>\n}\n\nexport class SearchIndexStore extends Context.Service<SearchIndexStore, SearchIndexStoreApi>()(\n '@yolk-sdk/knowledge/SearchIndexStore'\n) {}\n"],"mappings":";;AAmEA,IAAa,iBAAb,cAAoC,QAAQ,QAA2C,EACrF,oCACF,EAAE,CAAC;AAyFH,IAAa,mBAAb,cAAsC,QAAQ,QAA+C,EAC3F,sCACF,EAAE,CAAC"}
1
+ {"version":3,"file":"store.mjs","names":[],"sources":["../src/store.ts"],"sourcesContent":["import { Context } from 'effect'\nimport type { Effect } from 'effect'\nimport type {\n CreateKnowledgeDocumentInput,\n IndexedKnowledgeDocument,\n KnowledgeChunk,\n KnowledgeDocument,\n KnowledgeFile,\n KnowledgeScope,\n KnowledgeSearchScope,\n UpdateKnowledgeDocumentInput\n} from './documents.ts'\nimport type { KnowledgeEmbedding } from './embeddings.ts'\nimport type { KnowledgeStoreError, SearchIndexStoreError } from './errors.ts'\n\nexport type GetKnowledgeDocumentInput = {\n readonly scope: KnowledgeScope\n readonly id: string\n}\n\nexport type GetKnowledgeDocumentBySlugInput = {\n readonly scope: KnowledgeScope\n readonly slug: string\n}\n\nexport type ListKnowledgeDocumentsInput = {\n readonly scope: KnowledgeScope\n readonly limit: number\n readonly availability?: KnowledgeDocument['availability']\n}\n\nexport type ListKnowledgeDocumentsResult = {\n readonly documents: ReadonlyArray<KnowledgeDocument>\n}\n\nexport type ListPinnedKnowledgeInput = {\n readonly scope: KnowledgeScope\n readonly limit: number\n}\n\nexport type ListPinnedKnowledgeResult = {\n readonly documents: ReadonlyArray<KnowledgeDocument>\n}\n\nexport type KnowledgeStoreApi = {\n readonly createDocument: (\n input: CreateKnowledgeDocumentInput\n ) => Effect.Effect<KnowledgeDocument, KnowledgeStoreError>\n readonly updateDocument: (\n input: UpdateKnowledgeDocumentInput\n ) => Effect.Effect<KnowledgeDocument, KnowledgeStoreError>\n readonly getDocument: (\n input: GetKnowledgeDocumentInput\n ) => Effect.Effect<KnowledgeDocument, KnowledgeStoreError>\n readonly getDocumentBySlug: (\n input: GetKnowledgeDocumentBySlugInput\n ) => Effect.Effect<KnowledgeDocument, KnowledgeStoreError>\n readonly listDocuments: (\n input: ListKnowledgeDocumentsInput\n ) => Effect.Effect<ListKnowledgeDocumentsResult, KnowledgeStoreError>\n readonly listPinned: (\n input: ListPinnedKnowledgeInput\n ) => Effect.Effect<ListPinnedKnowledgeResult, KnowledgeStoreError>\n readonly deleteDocument: (\n input: GetKnowledgeDocumentInput\n ) => Effect.Effect<void, KnowledgeStoreError>\n readonly listFiles: (\n input: GetKnowledgeDocumentInput\n ) => Effect.Effect<ReadonlyArray<KnowledgeFile>, KnowledgeStoreError>\n}\n\nexport class KnowledgeStore extends Context.Service<KnowledgeStore, KnowledgeStoreApi>()(\n '@yolk-sdk/knowledge/KnowledgeStore'\n) {}\n\nexport type UpsertIndexedKnowledgeDocumentInput = {\n readonly document: IndexedKnowledgeDocument\n}\n\nexport type ReplaceKnowledgeDocumentChunksInput = {\n readonly scopeId: string\n readonly documentId: string\n readonly chunks: ReadonlyArray<{\n readonly chunk: KnowledgeChunk\n readonly embedding: KnowledgeEmbedding\n }>\n}\n\nexport type MarkKnowledgeDocumentReadyInput = {\n readonly scopeId: string\n readonly documentId: string\n readonly title?: string\n readonly summary?: string\n readonly contentHash?: string\n readonly tokenCount: number\n readonly chunkCount: number\n}\n\nexport type MarkKnowledgeDocumentErrorInput = {\n readonly scopeId: string\n readonly documentId: string\n readonly message: string\n}\n\nexport type KnowledgeChunkSearchInput = {\n readonly scope: KnowledgeSearchScope\n readonly embedding: KnowledgeEmbedding\n readonly limit: number\n readonly minScore?: number\n}\n\nexport type KnowledgeChunkTextSearchInput = {\n readonly scope: KnowledgeSearchScope\n readonly query: string\n readonly limit: number\n}\n\nexport type KnowledgeChunkSearchResult = {\n readonly chunk: KnowledgeChunk\n readonly score: number\n readonly document: IndexedKnowledgeDocument\n}\n\nexport type KnowledgeSearchContextChunksInput = {\n readonly scopeId: string\n readonly documentId: string\n readonly position: number\n readonly contextChunks: number\n}\n\nexport type SearchIndexStoreApi = {\n readonly upsertDocument: (\n input: UpsertIndexedKnowledgeDocumentInput\n ) => Effect.Effect<IndexedKnowledgeDocument, SearchIndexStoreError>\n readonly markDocumentProcessing: (input: {\n readonly scopeId: string\n readonly documentId: string\n }) => Effect.Effect<IndexedKnowledgeDocument, SearchIndexStoreError>\n readonly replaceDocumentChunks: (\n input: ReplaceKnowledgeDocumentChunksInput\n ) => Effect.Effect<void, SearchIndexStoreError>\n readonly markDocumentReady: (\n input: MarkKnowledgeDocumentReadyInput\n ) => Effect.Effect<IndexedKnowledgeDocument, SearchIndexStoreError>\n readonly markDocumentError: (\n input: MarkKnowledgeDocumentErrorInput\n ) => Effect.Effect<void, SearchIndexStoreError>\n readonly deleteDocument: (input: {\n readonly scopeId: string\n readonly documentId: string\n }) => Effect.Effect<void, SearchIndexStoreError>\n readonly searchChunks: (\n input: KnowledgeChunkSearchInput\n ) => Effect.Effect<ReadonlyArray<KnowledgeChunkSearchResult>, SearchIndexStoreError>\n readonly searchChunksByText: (\n input: KnowledgeChunkTextSearchInput\n ) => Effect.Effect<ReadonlyArray<KnowledgeChunkSearchResult>, SearchIndexStoreError>\n readonly getContextChunks: (\n input: KnowledgeSearchContextChunksInput\n ) => Effect.Effect<ReadonlyArray<KnowledgeChunk>, SearchIndexStoreError>\n}\n\nexport class SearchIndexStore extends Context.Service<SearchIndexStore, SearchIndexStoreApi>()(\n '@yolk-sdk/knowledge/SearchIndexStore'\n) {}\n"],"mappings":";;AAuEA,IAAa,iBAAb,cAAoC,QAAQ,QAA2C,EACrF,oCACF,EAAE,CAAC;AAyFH,IAAa,mBAAb,cAAsC,QAAQ,QAA+C,EAC3F,sCACF,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"summarization.d.mts","names":[],"sources":["../src/summarization.ts"],"mappings":";;;;;KAIY,wBAAA;EAAA,SACD,KAAA;EAAA,SACA,OAAO;AAAA;AAAA,KAGN,+BAAA;EAAA,SACD,OAAA;EAAA,SACA,WAAA;EAAA,SACA,QAAA,GAAW,iBAAiB;AAAA;AAAA,KAG3B,sBAAA;EAAA,SACD,SAAA,GACP,KAAA,EAAO,+BAAA,KACJ,MAAA,CAAO,MAAA,CAAO,wBAAA,EAA0B,2BAAA;AAAA;AAAA,cAC9C,wBAAA;cAEY,mBAAA,SAA4B,wBAExC;AAAA,cAEY,2BAAA,EAA2B,KAAA,CAAA,KAAA,CAAA,mBAAA"}
1
+ {"version":3,"file":"summarization.d.mts","names":[],"sources":["../src/summarization.ts"],"mappings":";;;;;KAIY,wBAAA;EAAA,SACD,KAAA;EAAA,SACA,OAAO;AAAA;AAAA,KAGN,+BAAA;EAAA,SACD,OAAA;EAAA,SACA,WAAA;EAAA,SACA,QAAA,GAAW,iBAAiB;AAAA;AAAA,KAG3B,sBAAA;EAAA,SACD,SAAA,GACP,KAAA,EAAO,+BAAA,KACJ,MAAA,CAAO,MAAA,CAAO,wBAAA,EAA0B,2BAAA;AAAA;AAAA,cAC9C,wBAAA;cAEY,mBAAA,SAA4B,wBAGK;AAAA,cAEjC,2BAAA,EAA2B,KAAA,CAAA,KAAA,CAAA,mBAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"summarization.mjs","names":[],"sources":["../src/summarization.ts"],"sourcesContent":["import { Context, Effect, Layer } from 'effect'\nimport type { KnowledgeMetadata } from './documents.ts'\nimport type { KnowledgeSummarizationError } from './errors.ts'\n\nexport type KnowledgeDocumentSummary = {\n readonly title?: string\n readonly summary?: string\n}\n\nexport type SummarizeKnowledgeDocumentInput = {\n readonly content: string\n readonly sourceTitle?: string\n readonly metadata?: KnowledgeMetadata\n}\n\nexport type KnowledgeSummarizerApi = {\n readonly summarize: (\n input: SummarizeKnowledgeDocumentInput\n ) => Effect.Effect<KnowledgeDocumentSummary, KnowledgeSummarizationError>\n}\n\nexport class KnowledgeSummarizer extends Context.Service<KnowledgeSummarizer, KnowledgeSummarizerApi>()(\n '@yolk-sdk/knowledge/KnowledgeSummarizer'\n) {}\n\nexport const NoopKnowledgeSummarizerLive = Layer.succeed(KnowledgeSummarizer, {\n summarize: input => Effect.succeed({ title: input.sourceTitle })\n})\n"],"mappings":";;AAqBA,IAAa,sBAAb,cAAyC,QAAQ,QAAqD,EACpG,yCACF,EAAE,CAAC;AAEH,MAAa,8BAA8B,MAAM,QAAQ,qBAAqB,EAC5E,YAAW,UAAS,OAAO,QAAQ,EAAE,OAAO,MAAM,YAAY,CAAC,EACjE,CAAC"}
1
+ {"version":3,"file":"summarization.mjs","names":[],"sources":["../src/summarization.ts"],"sourcesContent":["import { Context, Effect, Layer } from 'effect'\nimport type { KnowledgeMetadata } from './documents.ts'\nimport type { KnowledgeSummarizationError } from './errors.ts'\n\nexport type KnowledgeDocumentSummary = {\n readonly title?: string\n readonly summary?: string\n}\n\nexport type SummarizeKnowledgeDocumentInput = {\n readonly content: string\n readonly sourceTitle?: string\n readonly metadata?: KnowledgeMetadata\n}\n\nexport type KnowledgeSummarizerApi = {\n readonly summarize: (\n input: SummarizeKnowledgeDocumentInput\n ) => Effect.Effect<KnowledgeDocumentSummary, KnowledgeSummarizationError>\n}\n\nexport class KnowledgeSummarizer extends Context.Service<\n KnowledgeSummarizer,\n KnowledgeSummarizerApi\n>()('@yolk-sdk/knowledge/KnowledgeSummarizer') {}\n\nexport const NoopKnowledgeSummarizerLive = Layer.succeed(KnowledgeSummarizer, {\n summarize: input => Effect.succeed({ title: input.sourceTitle })\n})\n"],"mappings":";;AAqBA,IAAa,sBAAb,cAAyC,QAAQ,QAG/C,EAAE,yCAAyC,EAAE,CAAC;AAEhD,MAAa,8BAA8B,MAAM,QAAQ,qBAAqB,EAC5E,YAAW,UAAS,OAAO,QAAQ,EAAE,OAAO,MAAM,YAAY,CAAC,EACjE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yolk-sdk/knowledge",
3
- "version": "0.1.0-canary.32",
3
+ "version": "0.1.0-canary.33",
4
4
  "description": "Domain-free durable knowledge document, file, search, context, and tool contracts for Yolk agents.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -106,7 +106,7 @@
106
106
  "dependencies": {
107
107
  "effect": "4.0.0-beta.65",
108
108
  "gpt-tokenizer": "^3.4.0",
109
- "@yolk-sdk/agent": "^0.1.0-canary.32"
109
+ "@yolk-sdk/agent": "^0.1.0-canary.33"
110
110
  },
111
111
  "scripts": {
112
112
  "build": "tsdown",
package/src/agent.ts CHANGED
@@ -121,7 +121,8 @@ export type KnowledgeManageHandlers<Context> = {
121
121
  }) => Effect.Effect<KnowledgeSavedDocument, ToolError>
122
122
  }
123
123
 
124
- const unknownToMessage = (error: unknown) => error instanceof Error ? error.message : String(error)
124
+ const unknownToMessage = (error: unknown) =>
125
+ error instanceof Error ? error.message : String(error)
125
126
 
126
127
  const optionalValue = <Value>(value: Value | null | undefined) => value ?? undefined
127
128
 
@@ -168,7 +169,9 @@ const formatSearchResults = (results: ReadonlyArray<KnowledgeLookupResult>) =>
168
169
  .join('\n\n')
169
170
 
170
171
  const formatSaved = (verb: string, document: KnowledgeSavedDocument) =>
171
- [verb, `title: ${document.title}`, `slug: ${document.slug}`, `document_id: ${document.id}`].join('\n')
172
+ [verb, `title: ${document.title}`, `slug: ${document.slug}`, `document_id: ${document.id}`].join(
173
+ '\n'
174
+ )
172
175
 
173
176
  export const makeKnowledgeLookupTool = <Context>(
174
177
  handlers: KnowledgeLookupHandlers<Context>,
@@ -235,7 +238,10 @@ export const makeKnowledgeManageTool = <Context>(
235
238
  content: params.content,
236
239
  availability: params.availability
237
240
  })
238
- return ToolResult.make({ toolCallId: call.id, content: formatSaved('Knowledge upserted', document) })
241
+ return ToolResult.make({
242
+ toolCallId: call.id,
243
+ content: formatSaved('Knowledge upserted', document)
244
+ })
239
245
  }
240
246
  case 'set_availability': {
241
247
  const document = yield* handlers.setAvailability({
@@ -254,16 +260,29 @@ export const makeKnowledgeManageTool = <Context>(
254
260
  target: targetFromParams(params.target),
255
261
  nextSlug: params.nextSlug
256
262
  })
257
- return ToolResult.make({ toolCallId: call.id, content: formatSaved('Knowledge slug renamed', document) })
263
+ return ToolResult.make({
264
+ toolCallId: call.id,
265
+ content: formatSaved('Knowledge slug renamed', document)
266
+ })
258
267
  }
259
268
  case 'delete': {
260
- const document = yield* handlers.delete({ context, target: targetFromParams(params.target) })
261
- return ToolResult.make({ toolCallId: call.id, content: formatSaved('Knowledge deleted', document) })
269
+ const document = yield* handlers.delete({
270
+ context,
271
+ target: targetFromParams(params.target)
272
+ })
273
+ return ToolResult.make({
274
+ toolCallId: call.id,
275
+ content: formatSaved('Knowledge deleted', document)
276
+ })
262
277
  }
263
278
  }
264
279
 
265
280
  return yield* Effect.fail(
266
- new ToolError({ tool: call.name, message: 'Unsupported knowledge operation', cause: 'validation' })
281
+ new ToolError({
282
+ tool: call.name,
283
+ message: 'Unsupported knowledge operation',
284
+ cause: 'validation'
285
+ })
267
286
  )
268
287
  })
269
288
  })
package/src/chunking.ts CHANGED
@@ -146,7 +146,9 @@ export const chunkKnowledgeText = (input: ChunkKnowledgeDocumentInput, maxTokens
146
146
 
147
147
  const sanitized = sanitizeText(input.content)
148
148
  if (sanitized.length === 0) {
149
- return yield* Effect.fail(new KnowledgeChunkingError({ message: 'Cannot chunk empty content' }))
149
+ return yield* Effect.fail(
150
+ new KnowledgeChunkingError({ message: 'Cannot chunk empty content' })
151
+ )
150
152
  }
151
153
 
152
154
  const units = splitUnitsBySize(splitSentences(sanitized), maxTokens)
@@ -167,9 +169,12 @@ export const chunkKnowledgeText = (input: ChunkKnowledgeDocumentInput, maxTokens
167
169
  })) satisfies ReadonlyArray<KnowledgeChunk>
168
170
  })
169
171
 
170
- export const makeDefaultKnowledgeChunker = (input: { readonly maxTokens: number }): KnowledgeChunkerApi => ({
172
+ export const makeDefaultKnowledgeChunker = (input: {
173
+ readonly maxTokens: number
174
+ }): KnowledgeChunkerApi => ({
171
175
  chunk: document => chunkKnowledgeText(document, document.maxTokens ?? input.maxTokens)
172
176
  })
173
177
 
174
- export const DefaultKnowledgeChunkerLive = (input: { readonly maxTokens: number } = { maxTokens: 512 }) =>
175
- Layer.succeed(KnowledgeChunker, makeDefaultKnowledgeChunker(input))
178
+ export const DefaultKnowledgeChunkerLive = (
179
+ input: { readonly maxTokens: number } = { maxTokens: 512 }
180
+ ) => Layer.succeed(KnowledgeChunker, makeDefaultKnowledgeChunker(input))
package/src/context.ts CHANGED
@@ -27,7 +27,9 @@ const documentBody = (document: KnowledgeDocument) =>
27
27
  .join('\n')
28
28
 
29
29
  export const buildKnowledgeContext = (input: BuildKnowledgeContextInput) => {
30
- const sections = Arr.map(input.documents, documentBody).filter(section => section.trim().length > 0)
30
+ const sections = Arr.map(input.documents, documentBody).filter(
31
+ section => section.trim().length > 0
32
+ )
31
33
  const header = '# Pinned knowledge\nUse this durable knowledge as high-priority context.'
32
34
  const body = sections.join('\n\n')
33
35
  const context = body.length === 0 ? '' : `${header}\n\n${body}`
package/src/documents.ts CHANGED
@@ -48,7 +48,9 @@ export const CreateKnowledgeDocumentInputSchema = Schema.Struct({
48
48
  summary: Schema.optional(Schema.String),
49
49
  metadata: Schema.optional(KnowledgeMetadataSchema)
50
50
  })
51
- export type CreateKnowledgeDocumentInput = Schema.Schema.Type<typeof CreateKnowledgeDocumentInputSchema>
51
+ export type CreateKnowledgeDocumentInput = Schema.Schema.Type<
52
+ typeof CreateKnowledgeDocumentInputSchema
53
+ >
52
54
 
53
55
  export const UpdateKnowledgeDocumentInputSchema = Schema.Struct({
54
56
  scope: KnowledgeScopeSchema,
@@ -65,7 +67,9 @@ export const UpdateKnowledgeDocumentInputSchema = Schema.Struct({
65
67
  reviewedAt: Schema.optional(Schema.DateTimeUtc),
66
68
  metadata: Schema.optional(KnowledgeMetadataSchema)
67
69
  })
68
- export type UpdateKnowledgeDocumentInput = Schema.Schema.Type<typeof UpdateKnowledgeDocumentInputSchema>
70
+ export type UpdateKnowledgeDocumentInput = Schema.Schema.Type<
71
+ typeof UpdateKnowledgeDocumentInputSchema
72
+ >
69
73
 
70
74
  export const KnowledgeFileSchema = Schema.Struct({
71
75
  id: NonEmptyTrimmedString,
@@ -92,7 +96,10 @@ export type KnowledgeChunk = Schema.Schema.Type<typeof KnowledgeChunkSchema>
92
96
 
93
97
  export const KnowledgeSearchScopeSchema = Schema.Union([
94
98
  Schema.Struct({ _tag: Schema.Literal('KnowledgeScope'), id: NonEmptyTrimmedString }),
95
- Schema.Struct({ _tag: Schema.Literal('KnowledgeScopes'), ids: Schema.Array(NonEmptyTrimmedString) })
99
+ Schema.Struct({
100
+ _tag: Schema.Literal('KnowledgeScopes'),
101
+ ids: Schema.Array(NonEmptyTrimmedString)
102
+ })
96
103
  ])
97
104
  export type KnowledgeSearchScope = Schema.Schema.Type<typeof KnowledgeSearchScopeSchema>
98
105
 
package/src/extraction.ts CHANGED
@@ -16,6 +16,7 @@ export type KnowledgeExtractorApi = {
16
16
  ) => Effect.Effect<ExtractedKnowledgeDocument, KnowledgeExtractionError>
17
17
  }
18
18
 
19
- export class KnowledgeExtractor extends Context.Service<KnowledgeExtractor, KnowledgeExtractorApi>()(
20
- '@yolk-sdk/knowledge/KnowledgeExtractor'
21
- ) {}
19
+ export class KnowledgeExtractor extends Context.Service<
20
+ KnowledgeExtractor,
21
+ KnowledgeExtractorApi
22
+ >()('@yolk-sdk/knowledge/KnowledgeExtractor') {}
package/src/ingestion.ts CHANGED
@@ -51,7 +51,8 @@ export const ingestKnowledgeDocument = (input: IngestKnowledgeDocumentInput) =>
51
51
  })
52
52
  .pipe(
53
53
  Effect.mapError(
54
- error => new KnowledgeIngestionError({ message: error.message, stage: 'store', cause: error })
54
+ error =>
55
+ new KnowledgeIngestionError({ message: error.message, stage: 'store', cause: error })
55
56
  )
56
57
  )
57
58
 
@@ -59,7 +60,8 @@ export const ingestKnowledgeDocument = (input: IngestKnowledgeDocumentInput) =>
59
60
  .extract(input.source)
60
61
  .pipe(
61
62
  Effect.mapError(
62
- error => new KnowledgeIngestionError({ message: error.message, stage: 'extract', cause: error })
63
+ error =>
64
+ new KnowledgeIngestionError({ message: error.message, stage: 'extract', cause: error })
63
65
  )
64
66
  )
65
67
 
@@ -73,17 +75,25 @@ export const ingestKnowledgeDocument = (input: IngestKnowledgeDocumentInput) =>
73
75
  })
74
76
  .pipe(
75
77
  Effect.mapError(
76
- error => new KnowledgeIngestionError({ message: error.message, stage: 'chunk', cause: error })
78
+ error =>
79
+ new KnowledgeIngestionError({ message: error.message, stage: 'chunk', cause: error })
77
80
  )
78
81
  )
79
82
 
80
83
  const indexed = yield* Effect.all(
81
84
  {
82
- embeddings: embedder.embedTexts(chunks.map(chunk => chunk.content)).pipe(
83
- Effect.mapError(
84
- error => new KnowledgeIngestionError({ message: error.message, stage: 'embed', cause: error })
85
- )
86
- ),
85
+ embeddings: embedder
86
+ .embedTexts(chunks.map(chunk => chunk.content))
87
+ .pipe(
88
+ Effect.mapError(
89
+ error =>
90
+ new KnowledgeIngestionError({
91
+ message: error.message,
92
+ stage: 'embed',
93
+ cause: error
94
+ })
95
+ )
96
+ ),
87
97
  summary: summarizer
88
98
  .summarize({
89
99
  content: extracted.content,
@@ -93,7 +103,11 @@ export const ingestKnowledgeDocument = (input: IngestKnowledgeDocumentInput) =>
93
103
  .pipe(
94
104
  Effect.mapError(
95
105
  error =>
96
- new KnowledgeIngestionError({ message: error.message, stage: 'summarize', cause: error })
106
+ new KnowledgeIngestionError({
107
+ message: error.message,
108
+ stage: 'summarize',
109
+ cause: error
110
+ })
97
111
  )
98
112
  )
99
113
  },
@@ -102,7 +116,10 @@ export const ingestKnowledgeDocument = (input: IngestKnowledgeDocumentInput) =>
102
116
 
103
117
  if (indexed.embeddings.length !== chunks.length) {
104
118
  return yield* Effect.fail(
105
- new KnowledgeIngestionError({ message: 'Embedding count did not match chunk count', stage: 'embed' })
119
+ new KnowledgeIngestionError({
120
+ message: 'Embedding count did not match chunk count',
121
+ stage: 'embed'
122
+ })
106
123
  )
107
124
  }
108
125
 
@@ -118,7 +135,8 @@ export const ingestKnowledgeDocument = (input: IngestKnowledgeDocumentInput) =>
118
135
  })
119
136
  .pipe(
120
137
  Effect.mapError(
121
- error => new KnowledgeIngestionError({ message: error.message, stage: 'store', cause: error })
138
+ error =>
139
+ new KnowledgeIngestionError({ message: error.message, stage: 'store', cause: error })
122
140
  )
123
141
  )
124
142
 
@@ -135,16 +153,21 @@ export const ingestKnowledgeDocument = (input: IngestKnowledgeDocumentInput) =>
135
153
  })
136
154
  .pipe(
137
155
  Effect.mapError(
138
- error => new KnowledgeIngestionError({ message: error.message, stage: 'store', cause: error })
156
+ error =>
157
+ new KnowledgeIngestionError({ message: error.message, stage: 'store', cause: error })
139
158
  )
140
159
  )
141
160
  }).pipe(
142
161
  Effect.withSpan('knowledge_search.ingestDocument'),
143
- Effect.catch(error => markErrorBestEffort(input, error).pipe(Effect.flatMap(() => Effect.fail(error))))
162
+ Effect.catch(error =>
163
+ markErrorBestEffort(input, error).pipe(Effect.flatMap(() => Effect.fail(error)))
164
+ )
144
165
  )
145
166
 
146
167
  export type KnowledgeIngestionPipeline = {
147
- readonly ingest: (input: IngestKnowledgeDocumentInput) => ReturnType<typeof ingestKnowledgeDocument>
168
+ readonly ingest: (
169
+ input: IngestKnowledgeDocumentInput
170
+ ) => ReturnType<typeof ingestKnowledgeDocument>
148
171
  }
149
172
 
150
173
  export const makeIngestionPipeline = (): KnowledgeIngestionPipeline => ({
package/src/search.ts CHANGED
@@ -46,12 +46,14 @@ export type KnowledgeSearcher = {
46
46
  const packedResultText = (result: KnowledgeSearchResult) =>
47
47
  result.context?.map(chunk => chunk.content).join('\n\n') ?? result.chunk.content
48
48
 
49
- export const packKnowledgeSearchContext = (query: string, results: ReadonlyArray<KnowledgeSearchResult>): KnowledgeSearchContext =>
50
- ({
51
- query,
52
- results,
53
- text: results.map(packedResultText).join('\n\n')
54
- })
49
+ export const packKnowledgeSearchContext = (
50
+ query: string,
51
+ results: ReadonlyArray<KnowledgeSearchResult>
52
+ ): KnowledgeSearchContext => ({
53
+ query,
54
+ results,
55
+ text: results.map(packedResultText).join('\n\n')
56
+ })
55
57
 
56
58
  const scopeIds = (scope: KnowledgeSearchScope): ReadonlyArray<string> => {
57
59
  switch (scope._tag) {
@@ -116,36 +118,52 @@ const validateSearchInput = (input: KnowledgeSearchInput) => {
116
118
  const limit = input.limit ?? 10
117
119
  const contextChunks = input.contextChunks ?? 0
118
120
  const mode = input.mode ?? 'hybrid'
119
- const vectorLimit = input.vectorLimit ?? (mode === 'hybrid' ? defaultHybridCandidateLimit(limit) : limit)
121
+ const vectorLimit =
122
+ input.vectorLimit ?? (mode === 'hybrid' ? defaultHybridCandidateLimit(limit) : limit)
120
123
  const textLimit = input.textLimit ?? defaultHybridCandidateLimit(limit)
121
124
 
122
125
  if (query.length === 0) {
123
- return Effect.fail(new KnowledgeSearchError({ message: 'Search query is empty', stage: 'embed' }))
126
+ return Effect.fail(
127
+ new KnowledgeSearchError({ message: 'Search query is empty', stage: 'embed' })
128
+ )
124
129
  }
125
130
 
126
131
  if (ids.length === 0) {
127
- return Effect.fail(new KnowledgeSearchError({ message: 'Search scope is empty', stage: 'store' }))
132
+ return Effect.fail(
133
+ new KnowledgeSearchError({ message: 'Search scope is empty', stage: 'store' })
134
+ )
128
135
  }
129
136
 
130
137
  if (!Number.isInteger(limit) || limit < 1) {
131
- return Effect.fail(new KnowledgeSearchError({ message: 'Search limit must be positive', stage: 'store' }))
138
+ return Effect.fail(
139
+ new KnowledgeSearchError({ message: 'Search limit must be positive', stage: 'store' })
140
+ )
132
141
  }
133
142
 
134
143
  if (!Number.isInteger(vectorLimit) || vectorLimit < 1) {
135
- return Effect.fail(new KnowledgeSearchError({ message: 'Vector search limit must be positive', stage: 'store' }))
144
+ return Effect.fail(
145
+ new KnowledgeSearchError({ message: 'Vector search limit must be positive', stage: 'store' })
146
+ )
136
147
  }
137
148
 
138
149
  if (!Number.isInteger(textLimit) || textLimit < 1) {
139
- return Effect.fail(new KnowledgeSearchError({ message: 'Text search limit must be positive', stage: 'store' }))
150
+ return Effect.fail(
151
+ new KnowledgeSearchError({ message: 'Text search limit must be positive', stage: 'store' })
152
+ )
140
153
  }
141
154
 
142
155
  if (mode !== 'vector' && mode !== 'hybrid') {
143
- return Effect.fail(new KnowledgeSearchError({ message: 'Search mode is invalid', stage: 'store' }))
156
+ return Effect.fail(
157
+ new KnowledgeSearchError({ message: 'Search mode is invalid', stage: 'store' })
158
+ )
144
159
  }
145
160
 
146
161
  if (!Number.isInteger(contextChunks) || contextChunks < 0) {
147
162
  return Effect.fail(
148
- new KnowledgeSearchError({ message: 'Context chunks must be zero or positive', stage: 'store' })
163
+ new KnowledgeSearchError({
164
+ message: 'Context chunks must be zero or positive',
165
+ stage: 'store'
166
+ })
149
167
  )
150
168
  }
151
169
 
@@ -171,7 +189,8 @@ const searchVectorChunks = (input: {
171
189
  .embedQuery(input.query)
172
190
  .pipe(
173
191
  Effect.mapError(
174
- error => new KnowledgeSearchError({ message: error.message, stage: 'embed', cause: error })
192
+ error =>
193
+ new KnowledgeSearchError({ message: error.message, stage: 'embed', cause: error })
175
194
  )
176
195
  )
177
196
 
@@ -184,7 +203,8 @@ const searchVectorChunks = (input: {
184
203
  })
185
204
  .pipe(
186
205
  Effect.mapError(
187
- error => new KnowledgeSearchError({ message: error.message, stage: 'store', cause: error })
206
+ error =>
207
+ new KnowledgeSearchError({ message: error.message, stage: 'store', cause: error })
188
208
  )
189
209
  )
190
210
  })
@@ -200,7 +220,8 @@ const searchTextChunks = (input: {
200
220
  .searchChunksByText({ scope: input.scope, query: input.query, limit: input.limit })
201
221
  .pipe(
202
222
  Effect.mapError(
203
- error => new KnowledgeSearchError({ message: error.message, stage: 'store', cause: error })
223
+ error =>
224
+ new KnowledgeSearchError({ message: error.message, stage: 'store', cause: error })
204
225
  )
205
226
  )
206
227
  })
@@ -216,37 +237,38 @@ export const searchKnowledge = (input: KnowledgeSearchInput) =>
216
237
  'knowledge_search.scope_count': scopeIds(input.scope).length
217
238
  })
218
239
  const store = yield* SearchIndexStore
219
- const results: ReadonlyArray<KnowledgeSearchResult> = valid.mode === 'vector'
220
- ? yield* searchVectorChunks({
221
- scope: input.scope,
222
- query: valid.query,
223
- limit: valid.vectorLimit,
224
- minScore: input.minScore
225
- })
226
- : yield* Effect.gen(function* () {
227
- const searches = yield* Effect.all(
228
- {
229
- vectorResults: searchVectorChunks({
230
- scope: input.scope,
231
- query: valid.query,
232
- limit: valid.vectorLimit,
233
- minScore: input.minScore
234
- }),
235
- textResults: searchTextChunks({
236
- scope: input.scope,
237
- query: valid.query,
238
- limit: valid.textLimit
240
+ const results: ReadonlyArray<KnowledgeSearchResult> =
241
+ valid.mode === 'vector'
242
+ ? yield* searchVectorChunks({
243
+ scope: input.scope,
244
+ query: valid.query,
245
+ limit: valid.vectorLimit,
246
+ minScore: input.minScore
247
+ })
248
+ : yield* Effect.gen(function* () {
249
+ const searches = yield* Effect.all(
250
+ {
251
+ vectorResults: searchVectorChunks({
252
+ scope: input.scope,
253
+ query: valid.query,
254
+ limit: valid.vectorLimit,
255
+ minScore: input.minScore
256
+ }),
257
+ textResults: searchTextChunks({
258
+ scope: input.scope,
259
+ query: valid.query,
260
+ limit: valid.textLimit
261
+ })
262
+ },
263
+ { concurrency: 'unbounded' }
264
+ )
265
+
266
+ return fuseKnowledgeSearchResults({
267
+ vectorResults: searches.vectorResults,
268
+ textResults: searches.textResults,
269
+ limit: valid.limit
239
270
  })
240
- },
241
- { concurrency: 'unbounded' }
242
- )
243
-
244
- return fuseKnowledgeSearchResults({
245
- vectorResults: searches.vectorResults,
246
- textResults: searches.textResults,
247
- limit: valid.limit
248
- })
249
- })
271
+ })
250
272
 
251
273
  if (valid.contextChunks === 0) {
252
274
  return results
@@ -263,7 +285,8 @@ export const searchKnowledge = (input: KnowledgeSearchInput) =>
263
285
  .pipe(
264
286
  Effect.map(context => ({ ...result, context })),
265
287
  Effect.mapError(
266
- error => new KnowledgeSearchError({ message: error.message, stage: 'store', cause: error })
288
+ error =>
289
+ new KnowledgeSearchError({ message: error.message, stage: 'store', cause: error })
267
290
  )
268
291
  )
269
292
  )
package/src/store.ts CHANGED
@@ -61,8 +61,12 @@ export type KnowledgeStoreApi = {
61
61
  readonly listPinned: (
62
62
  input: ListPinnedKnowledgeInput
63
63
  ) => Effect.Effect<ListPinnedKnowledgeResult, KnowledgeStoreError>
64
- readonly deleteDocument: (input: GetKnowledgeDocumentInput) => Effect.Effect<void, KnowledgeStoreError>
65
- readonly listFiles: (input: GetKnowledgeDocumentInput) => Effect.Effect<ReadonlyArray<KnowledgeFile>, KnowledgeStoreError>
64
+ readonly deleteDocument: (
65
+ input: GetKnowledgeDocumentInput
66
+ ) => Effect.Effect<void, KnowledgeStoreError>
67
+ readonly listFiles: (
68
+ input: GetKnowledgeDocumentInput
69
+ ) => Effect.Effect<ReadonlyArray<KnowledgeFile>, KnowledgeStoreError>
66
70
  }
67
71
 
68
72
  export class KnowledgeStore extends Context.Service<KnowledgeStore, KnowledgeStoreApi>()(
@@ -19,9 +19,10 @@ export type KnowledgeSummarizerApi = {
19
19
  ) => Effect.Effect<KnowledgeDocumentSummary, KnowledgeSummarizationError>
20
20
  }
21
21
 
22
- export class KnowledgeSummarizer extends Context.Service<KnowledgeSummarizer, KnowledgeSummarizerApi>()(
23
- '@yolk-sdk/knowledge/KnowledgeSummarizer'
24
- ) {}
22
+ export class KnowledgeSummarizer extends Context.Service<
23
+ KnowledgeSummarizer,
24
+ KnowledgeSummarizerApi
25
+ >()('@yolk-sdk/knowledge/KnowledgeSummarizer') {}
25
26
 
26
27
  export const NoopKnowledgeSummarizerLive = Layer.succeed(KnowledgeSummarizer, {
27
28
  summarize: input => Effect.succeed({ title: input.sourceTitle })