@yolk-sdk/knowledge 0.1.0-canary.13 → 0.1.0-canary.130
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 +160 -80
- package/dist/agent.d.mts +118 -19
- package/dist/agent.d.mts.map +1 -1
- package/dist/agent.mjs +256 -34
- package/dist/agent.mjs.map +1 -1
- package/dist/chunking.d.mts +13 -16
- package/dist/chunking.d.mts.map +1 -1
- package/dist/chunking.mjs +4 -4
- package/dist/chunking.mjs.map +1 -1
- package/dist/context.d.mts +4 -13
- package/dist/context.d.mts.map +1 -1
- package/dist/context.mjs +17 -13
- package/dist/context.mjs.map +1 -1
- package/dist/documents.d.mts +128 -78
- package/dist/documents.d.mts.map +1 -1
- package/dist/documents.mjs +89 -61
- package/dist/documents.mjs.map +1 -1
- package/dist/embeddings.d.mts +4 -7
- package/dist/embeddings.d.mts.map +1 -1
- package/dist/embeddings.mjs +1 -2
- package/dist/embeddings.mjs.map +1 -1
- package/dist/errors.d.mts +19 -22
- package/dist/errors.d.mts.map +1 -1
- package/dist/errors.mjs +12 -13
- package/dist/errors.mjs.map +1 -1
- package/dist/extraction.d.mts +4 -7
- package/dist/extraction.d.mts.map +1 -1
- package/dist/extraction.mjs +1 -2
- package/dist/extraction.mjs.map +1 -1
- package/dist/files.d.mts +19 -0
- package/dist/files.d.mts.map +1 -0
- package/dist/files.mjs +6 -0
- package/dist/files.mjs.map +1 -0
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +4 -4
- package/dist/ingestion.d.mts +21 -23
- package/dist/ingestion.d.mts.map +1 -1
- package/dist/ingestion.mjs +12 -17
- package/dist/ingestion.mjs.map +1 -1
- package/dist/search.d.mts +13 -17
- package/dist/search.d.mts.map +1 -1
- package/dist/search.mjs +9 -12
- package/dist/search.mjs.map +1 -1
- package/dist/store.d.mts +92 -29
- package/dist/store.d.mts.map +1 -1
- package/dist/store.mjs +3 -3
- package/dist/store.mjs.map +1 -1
- package/dist/summarization.d.mts +6 -9
- package/dist/summarization.d.mts.map +1 -1
- package/dist/summarization.mjs +1 -2
- package/dist/summarization.mjs.map +1 -1
- package/package.json +11 -41
- package/src/agent.ts +393 -65
- package/src/chunking.ts +27 -8
- package/src/context.ts +21 -16
- package/src/documents.ts +140 -71
- package/src/errors.ts +4 -4
- package/src/extraction.ts +4 -3
- package/src/files.ts +24 -0
- package/src/index.ts +6 -3
- package/src/ingestion.ts +46 -27
- package/src/search.ts +90 -62
- package/src/store.ts +139 -25
- package/src/summarization.ts +4 -3
- package/dist/artifacts.d.mts +0 -37
- package/dist/artifacts.d.mts.map +0 -1
- package/dist/artifacts.mjs +0 -28
- package/dist/artifacts.mjs.map +0 -1
- package/dist/links.d.mts +0 -17
- package/dist/links.d.mts.map +0 -1
- package/dist/links.mjs +0 -24
- package/dist/links.mjs.map +0 -1
- package/dist/provenance.d.mts +0 -20
- package/dist/provenance.d.mts.map +0 -1
- package/dist/provenance.mjs +0 -26
- package/dist/provenance.mjs.map +0 -1
- package/dist/records.d.mts +0 -59
- package/dist/records.d.mts.map +0 -1
- package/dist/records.mjs +0 -64
- package/dist/records.mjs.map +0 -1
- package/dist/representations.d.mts +0 -36
- package/dist/representations.d.mts.map +0 -1
- package/dist/representations.mjs +0 -44
- package/dist/representations.mjs.map +0 -1
- package/dist/search-store.d.mts +0 -77
- package/dist/search-store.d.mts.map +0 -1
- package/dist/search-store.mjs +0 -7
- package/dist/search-store.mjs.map +0 -1
- package/dist/vector-store.d.mts +0 -3
- package/dist/vector-store.mjs +0 -2
- package/src/artifacts.ts +0 -48
- package/src/links.ts +0 -23
- package/src/provenance.ts +0 -25
- package/src/records.ts +0 -76
- package/src/representations.ts +0 -51
- package/src/search-store.ts +0 -98
- package/src/vector-store.ts +0 -6
package/dist/agent.mjs
CHANGED
|
@@ -1,45 +1,267 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { KnowledgeAvailabilitySchema, KnowledgeDocumentSchema, NonEmptyTrimmedString, NonNegativeInteger, PositiveInteger } from "./documents.mjs";
|
|
2
2
|
import { Effect } from "effect";
|
|
3
|
-
import * as Schema
|
|
3
|
+
import * as Schema from "effect/Schema";
|
|
4
4
|
import { ToolError } from "@yolk-sdk/agent/loop";
|
|
5
5
|
import { ToolResult } from "@yolk-sdk/agent/protocol";
|
|
6
|
-
import { makeTool } from "@yolk-sdk/agent/tools";
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
import { makeTool, withToolArgumentsErrorHint } from "@yolk-sdk/agent/tools";
|
|
7
|
+
// src/agent.ts
|
|
8
|
+
const OptionalNonEmptyTrimmedString = Schema.optional(Schema.NullOr(NonEmptyTrimmedString));
|
|
9
|
+
const OptionalPositiveInteger = Schema.optional(Schema.NullOr(PositiveInteger));
|
|
10
|
+
const OptionalNonNegativeInteger = Schema.optional(Schema.NullOr(NonNegativeInteger));
|
|
11
|
+
const OptionalNumber = Schema.optional(Schema.NullOr(Schema.Number));
|
|
12
|
+
const KnowledgeTargetParamsSchema = Schema.Struct({
|
|
13
|
+
slug: NonEmptyTrimmedString,
|
|
14
|
+
scope: OptionalNonEmptyTrimmedString
|
|
15
|
+
});
|
|
16
|
+
const KnowledgeLookupParams = Schema.Union([Schema.Struct({
|
|
17
|
+
operation: Schema.Literal("search"),
|
|
18
|
+
query: NonEmptyTrimmedString,
|
|
19
|
+
limit: OptionalPositiveInteger,
|
|
20
|
+
minScore: OptionalNumber,
|
|
21
|
+
contextChunks: OptionalNonNegativeInteger
|
|
22
|
+
}), Schema.Struct({
|
|
23
|
+
operation: Schema.Literal("get"),
|
|
24
|
+
id: OptionalNonEmptyTrimmedString,
|
|
25
|
+
target: Schema.optional(Schema.NullOr(KnowledgeTargetParamsSchema))
|
|
26
|
+
})]);
|
|
27
|
+
const KnowledgeManageParams = Schema.Union([
|
|
28
|
+
Schema.Struct({
|
|
29
|
+
operation: Schema.Literal("upsert"),
|
|
30
|
+
target: KnowledgeTargetParamsSchema,
|
|
31
|
+
title: NonEmptyTrimmedString,
|
|
32
|
+
purpose: NonEmptyTrimmedString,
|
|
33
|
+
origin: NonEmptyTrimmedString,
|
|
34
|
+
content: NonEmptyTrimmedString,
|
|
35
|
+
availability: KnowledgeAvailabilitySchema
|
|
36
|
+
}),
|
|
37
|
+
Schema.Struct({
|
|
38
|
+
operation: Schema.Literal("set_availability"),
|
|
39
|
+
target: KnowledgeTargetParamsSchema,
|
|
40
|
+
availability: KnowledgeAvailabilitySchema
|
|
41
|
+
}),
|
|
42
|
+
Schema.Struct({
|
|
43
|
+
operation: Schema.Literal("rename_slug"),
|
|
44
|
+
target: KnowledgeTargetParamsSchema,
|
|
45
|
+
nextSlug: NonEmptyTrimmedString
|
|
46
|
+
}),
|
|
47
|
+
Schema.Struct({
|
|
48
|
+
operation: Schema.Literal("delete"),
|
|
49
|
+
target: KnowledgeTargetParamsSchema
|
|
50
|
+
})
|
|
51
|
+
]);
|
|
52
|
+
const KnowledgeLookupResultSchema = Schema.Struct({
|
|
53
|
+
document: KnowledgeDocumentSchema,
|
|
54
|
+
score: Schema.optionalKey(Schema.Number),
|
|
55
|
+
context: Schema.optionalKey(Schema.Array(Schema.Struct({ content: Schema.String })))
|
|
56
|
+
});
|
|
57
|
+
/** Declared output of `makeKnowledgeLookupTool`; `structuredContent` is its JSON encoding
|
|
58
|
+
* (`Schema.toCodecJson`: document dates become ISO strings). */
|
|
59
|
+
const KnowledgeLookupOutput = Schema.Union([Schema.Struct({
|
|
60
|
+
operation: Schema.Literal("search"),
|
|
61
|
+
results: Schema.Array(KnowledgeLookupResultSchema)
|
|
62
|
+
}), Schema.Struct({
|
|
63
|
+
operation: Schema.Literal("get"),
|
|
64
|
+
document: KnowledgeDocumentSchema
|
|
65
|
+
})]);
|
|
66
|
+
/** Declared output of `makeKnowledgeManageTool`; `structuredContent` is its JSON encoding. */
|
|
67
|
+
const KnowledgeManageOutput = Schema.Struct({
|
|
68
|
+
operation: Schema.Literals([
|
|
69
|
+
"upsert",
|
|
70
|
+
"set_availability",
|
|
71
|
+
"rename_slug",
|
|
72
|
+
"delete"
|
|
73
|
+
]),
|
|
74
|
+
document: Schema.Struct({
|
|
75
|
+
id: Schema.String,
|
|
76
|
+
slug: Schema.String,
|
|
77
|
+
title: Schema.String
|
|
78
|
+
})
|
|
79
|
+
});
|
|
80
|
+
const encodeLookupOutput = Schema.encodeEffect(Schema.toCodecJson(KnowledgeLookupOutput));
|
|
81
|
+
const encodeManageOutput = Schema.encodeEffect(Schema.toCodecJson(KnowledgeManageOutput));
|
|
82
|
+
/** A handler result that does not encode to the declared output is a host bug, not a model
|
|
83
|
+
* mistake: fail with a safe message (no values). */
|
|
84
|
+
const outputError = (tool) => () => new ToolError({
|
|
85
|
+
tool,
|
|
86
|
+
message: `${tool} produced a result that does not match its output schema.`,
|
|
87
|
+
cause: "execution"
|
|
88
|
+
});
|
|
89
|
+
const optionalValue = (value) => value ?? void 0;
|
|
90
|
+
const targetFromParams = (target) => target.scope === null || target.scope === void 0 ? { slug: target.slug } : {
|
|
91
|
+
slug: target.slug,
|
|
92
|
+
scope: target.scope
|
|
14
93
|
};
|
|
15
|
-
const
|
|
94
|
+
const optionalTargetFromParams = (target) => target === null || target === void 0 ? void 0 : targetFromParams(target);
|
|
95
|
+
const formatDocument = (document) => [
|
|
96
|
+
`# ${document.title}`,
|
|
97
|
+
`document_id: ${document.id}`,
|
|
98
|
+
`slug: ${document.slug}`,
|
|
99
|
+
`purpose: ${document.purpose}`,
|
|
100
|
+
`origin: ${document.origin}`,
|
|
101
|
+
`availability: ${document.availability}`,
|
|
102
|
+
`status: ${document.status}`,
|
|
103
|
+
"",
|
|
104
|
+
document.content
|
|
105
|
+
].join("\n");
|
|
106
|
+
const formatSearchResults = (results) => results.length === 0 ? "No knowledge matches found." : results.map((result) => [
|
|
107
|
+
`## ${result.document.title}`,
|
|
108
|
+
`document_id: ${result.document.id}`,
|
|
109
|
+
`slug: ${result.document.slug}`,
|
|
110
|
+
`purpose: ${result.document.purpose}`,
|
|
111
|
+
`origin: ${result.document.origin}`,
|
|
112
|
+
`availability: ${result.document.availability}`,
|
|
113
|
+
result.score === void 0 ? void 0 : `score: ${result.score}`,
|
|
114
|
+
"",
|
|
115
|
+
result.context?.map((chunk) => chunk.content).join("\n\n") ?? result.document.content
|
|
116
|
+
].filter((line) => line !== void 0).join("\n")).join("\n\n");
|
|
117
|
+
const formatSaved = (verb, document) => [
|
|
118
|
+
verb,
|
|
119
|
+
`title: ${document.title}`,
|
|
120
|
+
`slug: ${document.slug}`,
|
|
121
|
+
`document_id: ${document.id}`
|
|
122
|
+
].join("\n");
|
|
123
|
+
const lookupResultOutput = (result) => {
|
|
124
|
+
const output = { document: result.document };
|
|
125
|
+
if (result.score !== void 0) output.score = result.score;
|
|
126
|
+
if (result.context !== void 0) output.context = result.context.map((chunk) => ({ content: chunk.content }));
|
|
127
|
+
return output;
|
|
128
|
+
};
|
|
129
|
+
const savedResult = (input) => encodeManageOutput({
|
|
130
|
+
operation: input.operation,
|
|
131
|
+
document: {
|
|
132
|
+
id: input.document.id,
|
|
133
|
+
slug: input.document.slug,
|
|
134
|
+
title: input.document.title
|
|
135
|
+
}
|
|
136
|
+
}).pipe(Effect.mapError(outputError(input.name)), Effect.map((structuredContent) => ToolResult.make({
|
|
137
|
+
toolCallId: input.callId,
|
|
138
|
+
content: formatSaved(input.verb, input.document),
|
|
139
|
+
structuredContent
|
|
140
|
+
})));
|
|
141
|
+
const makeKnowledgeLookupTool = (handlers, options = {}) => {
|
|
142
|
+
const name = options.name ?? "knowledge_lookup";
|
|
16
143
|
return makeTool({
|
|
17
|
-
name
|
|
18
|
-
description: options.description ?? "
|
|
19
|
-
parameters:
|
|
144
|
+
name,
|
|
145
|
+
description: options.description ?? "Look up durable knowledge. Search for semantic discovery; get when document_id or slug is known.",
|
|
146
|
+
parameters: KnowledgeLookupParams,
|
|
147
|
+
output: KnowledgeLookupOutput,
|
|
20
148
|
access: "read",
|
|
21
|
-
invalidParamsMessage: (error) => error instanceof Error ? error.message : String(error),
|
|
22
|
-
execute: (
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
149
|
+
invalidParamsMessage: (error) => withToolArgumentsErrorHint(`Invalid knowledge lookup arguments: ${error instanceof Error ? error.message : String(error)}`, error),
|
|
150
|
+
execute: ({ call, context, params }) => Effect.gen(function* () {
|
|
151
|
+
if (params.operation === "search") {
|
|
152
|
+
const results = yield* handlers.search({
|
|
153
|
+
context,
|
|
154
|
+
query: params.query,
|
|
155
|
+
limit: optionalValue(params.limit),
|
|
156
|
+
minScore: optionalValue(params.minScore),
|
|
157
|
+
contextChunks: optionalValue(params.contextChunks)
|
|
158
|
+
});
|
|
159
|
+
const structuredContent = yield* encodeLookupOutput({
|
|
160
|
+
operation: "search",
|
|
161
|
+
results: results.map(lookupResultOutput)
|
|
162
|
+
}).pipe(Effect.mapError(outputError(name)));
|
|
163
|
+
return ToolResult.make({
|
|
164
|
+
toolCallId: call.id,
|
|
165
|
+
content: formatSearchResults(results),
|
|
166
|
+
structuredContent
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
const document = yield* handlers.get({
|
|
170
|
+
context,
|
|
171
|
+
id: optionalValue(params.id),
|
|
172
|
+
target: optionalTargetFromParams(params.target)
|
|
173
|
+
});
|
|
174
|
+
const structuredContent = yield* encodeLookupOutput({
|
|
175
|
+
operation: "get",
|
|
176
|
+
document
|
|
177
|
+
}).pipe(Effect.mapError(outputError(name)));
|
|
178
|
+
return ToolResult.make({
|
|
179
|
+
toolCallId: call.id,
|
|
180
|
+
content: formatDocument(document),
|
|
181
|
+
structuredContent
|
|
38
182
|
});
|
|
39
|
-
})
|
|
183
|
+
})
|
|
184
|
+
});
|
|
185
|
+
};
|
|
186
|
+
const makeKnowledgeManageTool = (handlers, options = {}) => {
|
|
187
|
+
const name = options.name ?? "knowledge_manage";
|
|
188
|
+
return makeTool({
|
|
189
|
+
name,
|
|
190
|
+
description: options.description ?? "Create, replace, pin, archive, rename, or delete durable knowledge. Use only when explicitly asked.",
|
|
191
|
+
parameters: KnowledgeManageParams,
|
|
192
|
+
output: KnowledgeManageOutput,
|
|
193
|
+
access: "write",
|
|
194
|
+
invalidParamsMessage: (error) => withToolArgumentsErrorHint(`Invalid knowledge manage arguments: ${error instanceof Error ? error.message : String(error)}`, error),
|
|
195
|
+
execute: ({ call, context, params }) => Effect.gen(function* () {
|
|
196
|
+
switch (params.operation) {
|
|
197
|
+
case "upsert": {
|
|
198
|
+
const document = yield* handlers.upsert({
|
|
199
|
+
context,
|
|
200
|
+
target: targetFromParams(params.target),
|
|
201
|
+
title: params.title,
|
|
202
|
+
purpose: params.purpose,
|
|
203
|
+
origin: params.origin,
|
|
204
|
+
content: params.content,
|
|
205
|
+
availability: params.availability
|
|
206
|
+
});
|
|
207
|
+
return yield* savedResult({
|
|
208
|
+
name,
|
|
209
|
+
callId: call.id,
|
|
210
|
+
verb: "Knowledge upserted",
|
|
211
|
+
operation: "upsert",
|
|
212
|
+
document
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
case "set_availability": {
|
|
216
|
+
const document = yield* handlers.setAvailability({
|
|
217
|
+
context,
|
|
218
|
+
target: targetFromParams(params.target),
|
|
219
|
+
availability: params.availability
|
|
220
|
+
});
|
|
221
|
+
return yield* savedResult({
|
|
222
|
+
name,
|
|
223
|
+
callId: call.id,
|
|
224
|
+
verb: "Knowledge availability updated",
|
|
225
|
+
operation: "set_availability",
|
|
226
|
+
document
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
case "rename_slug": {
|
|
230
|
+
const document = yield* handlers.renameSlug({
|
|
231
|
+
context,
|
|
232
|
+
target: targetFromParams(params.target),
|
|
233
|
+
nextSlug: params.nextSlug
|
|
234
|
+
});
|
|
235
|
+
return yield* savedResult({
|
|
236
|
+
name,
|
|
237
|
+
callId: call.id,
|
|
238
|
+
verb: "Knowledge slug renamed",
|
|
239
|
+
operation: "rename_slug",
|
|
240
|
+
document
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
case "delete": {
|
|
244
|
+
const document = yield* handlers.delete({
|
|
245
|
+
context,
|
|
246
|
+
target: targetFromParams(params.target)
|
|
247
|
+
});
|
|
248
|
+
return yield* savedResult({
|
|
249
|
+
name,
|
|
250
|
+
callId: call.id,
|
|
251
|
+
verb: "Knowledge deleted",
|
|
252
|
+
operation: "delete",
|
|
253
|
+
document
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return yield* Effect.fail(new ToolError({
|
|
258
|
+
tool: call.name,
|
|
259
|
+
message: "Unsupported knowledge operation",
|
|
260
|
+
cause: "validation"
|
|
261
|
+
}));
|
|
262
|
+
})
|
|
40
263
|
});
|
|
41
264
|
};
|
|
42
|
-
|
|
43
|
-
export { defaultKnowledgeAgentContextOptions, makeKnowledgeSearchTool };
|
|
265
|
+
export { KnowledgeLookupOutput, KnowledgeManageOutput, makeKnowledgeLookupTool, makeKnowledgeManageTool };
|
|
44
266
|
|
|
45
267
|
//# sourceMappingURL=agent.mjs.map
|
package/dist/agent.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.mjs","names":["Schema"],"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 type { KnowledgeScope } from './records.ts'\nimport type { KnowledgeSearchScope } from './documents.ts'\nimport type { KnowledgeSearcher } from './search.ts'\nimport { packKnowledgeSearchContext } from './search.ts'\n\nexport type ResolveKnowledgeScope<Context> = (context: Context) => KnowledgeScope\n\nexport type KnowledgeAgentContextOptions = {\n readonly maxPinnedContextCharacters: number\n}\n\nexport const defaultKnowledgeAgentContextOptions: KnowledgeAgentContextOptions = {\n maxPinnedContextCharacters: 6000\n}\n\nconst KnowledgeSearchToolParams = Schema.Struct({\n query: Schema.Trimmed.pipe(\n Schema.check(Schema.isNonEmpty()),\n Schema.annotate({ description: 'Search query for the configured knowledge search.' })\n )\n})\n\nconst isToolError = Schema.is(ToolError)\n\nexport type KnowledgeSearchToolScopeResolver<Context> =\n | KnowledgeSearchScope\n | ((context: Context) => Effect.Effect<KnowledgeSearchScope, ToolError>)\n\nexport type MakeKnowledgeSearchToolOptions<Context> = {\n readonly scope: KnowledgeSearchToolScopeResolver<Context>\n readonly name?: string\n readonly description?: string\n readonly limit?: number\n readonly minScore?: number\n readonly contextChunks?: number\n}\n\nconst resolveScope = <Context>(resolver: KnowledgeSearchToolScopeResolver<Context>, context: Context) => {\n if (typeof resolver === 'function') {\n return resolver(context)\n }\n\n return Effect.succeed(resolver)\n}\n\nexport const makeKnowledgeSearchTool = <Context>(\n searcher: KnowledgeSearcher,\n options: MakeKnowledgeSearchToolOptions<Context>\n): ToolRegistration<Context> => {\n const name = options.name ?? 'search_knowledge'\n\n return makeTool({\n name,\n description: options.description ?? 'Search the configured knowledge search.',\n parameters: KnowledgeSearchToolParams,\n access: 'read',\n invalidParamsMessage: error => error instanceof Error ? error.message : String(error),\n execute: input =>\n resolveScope(options.scope, input.context).pipe(\n Effect.flatMap(scope =>\n searcher.search({\n scope,\n query: input.params.query,\n limit: options.limit,\n minScore: options.minScore,\n contextChunks: options.contextChunks\n })\n ),\n Effect.map(results => packKnowledgeSearchContext(input.params.query, results)),\n Effect.map(\n context =>\n ToolResult.make({\n toolCallId: input.call.id,\n content: context.text,\n structuredContent: context\n })\n ),\n Effect.mapError(error => {\n if (isToolError(error)) {\n return error\n }\n\n return new ToolError({\n tool: input.call.name,\n message: error.message,\n cause: 'execution'\n })\n })\n )\n })\n}\n"],"mappings":";;;;;;;AAgBA,MAAa,sCAAoE,EAC/E,4BAA4B,IAC9B;AAEA,MAAM,4BAA4BA,SAAO,OAAO,EAC9C,OAAOA,SAAO,QAAQ,KACpBA,SAAO,MAAMA,SAAO,WAAW,CAAC,GAChCA,SAAO,SAAS,EAAE,aAAa,oDAAoD,CAAC,CACtF,EACF,CAAC;AAED,MAAM,cAAcA,SAAO,GAAG,SAAS;AAevC,MAAM,gBAAyB,UAAqD,YAAqB;CACvG,IAAI,OAAO,aAAa,YACtB,OAAO,SAAS,OAAO;CAGzB,OAAO,OAAO,QAAQ,QAAQ;AAChC;AAEA,MAAa,2BACX,UACA,YAC8B;CAG9B,OAAO,SAAS;EACd,MAHW,QAAQ,QAAQ;EAI3B,aAAa,QAAQ,eAAe;EACpC,YAAY;EACZ,QAAQ;EACR,uBAAsB,UAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EACpF,UAAS,UACP,aAAa,QAAQ,OAAO,MAAM,OAAO,EAAE,KACzC,OAAO,SAAQ,UACb,SAAS,OAAO;GACd;GACA,OAAO,MAAM,OAAO;GACpB,OAAO,QAAQ;GACf,UAAU,QAAQ;GAClB,eAAe,QAAQ;EACzB,CAAC,CACH,GACA,OAAO,KAAI,YAAW,2BAA2B,MAAM,OAAO,OAAO,OAAO,CAAC,GAC7E,OAAO,KACL,YACE,WAAW,KAAK;GACd,YAAY,MAAM,KAAK;GACvB,SAAS,QAAQ;GACjB,mBAAmB;EACrB,CAAC,CACL,GACA,OAAO,UAAS,UAAS;GACvB,IAAI,YAAY,KAAK,GACnB,OAAO;GAGT,OAAO,IAAI,UAAU;IACnB,MAAM,MAAM,KAAK;IACjB,SAAS,MAAM;IACf,OAAO;GACT,CAAC;EACH,CAAC,CACH;CACJ,CAAC;AACH"}
|
|
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, withToolArgumentsErrorHint, type ToolRegistration } from '@yolk-sdk/agent/tools'\nimport {\n KnowledgeAvailabilitySchema,\n KnowledgeDocumentSchema,\n NonNegativeInteger,\n NonEmptyTrimmedString,\n PositiveInteger,\n type KnowledgeAvailability,\n type KnowledgeDocument\n} from './documents.ts'\n\nconst OptionalNonEmptyTrimmedString = Schema.optional(Schema.NullOr(NonEmptyTrimmedString))\n\nconst OptionalPositiveInteger = Schema.optional(Schema.NullOr(PositiveInteger))\n\nconst OptionalNonNegativeInteger = Schema.optional(Schema.NullOr(NonNegativeInteger))\n\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: OptionalPositiveInteger,\n minScore: OptionalNumber,\n contextChunks: OptionalNonNegativeInteger\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\nconst KnowledgeLookupResultSchema = Schema.Struct({\n document: KnowledgeDocumentSchema,\n score: Schema.optionalKey(Schema.Number),\n context: Schema.optionalKey(Schema.Array(Schema.Struct({ content: Schema.String })))\n})\n\n/** Declared output of `makeKnowledgeLookupTool`; `structuredContent` is its JSON encoding\n * (`Schema.toCodecJson`: document dates become ISO strings). */\nexport const KnowledgeLookupOutput = Schema.Union([\n Schema.Struct({\n operation: Schema.Literal('search'),\n results: Schema.Array(KnowledgeLookupResultSchema)\n }),\n Schema.Struct({\n operation: Schema.Literal('get'),\n document: KnowledgeDocumentSchema\n })\n])\n\nexport type KnowledgeLookupOutput = typeof KnowledgeLookupOutput.Type\n\n/** Declared output of `makeKnowledgeManageTool`; `structuredContent` is its JSON encoding. */\nexport const KnowledgeManageOutput = Schema.Struct({\n operation: Schema.Literals(['upsert', 'set_availability', 'rename_slug', 'delete']),\n document: Schema.Struct({ id: Schema.String, slug: Schema.String, title: Schema.String })\n})\n\nexport type KnowledgeManageOutput = typeof KnowledgeManageOutput.Type\n\nconst encodeLookupOutput = Schema.encodeEffect(Schema.toCodecJson(KnowledgeLookupOutput))\n\nconst encodeManageOutput = Schema.encodeEffect(Schema.toCodecJson(KnowledgeManageOutput))\n\n/** A handler result that does not encode to the declared output is a host bug, not a model\n * mistake: fail with a safe message (no values). */\nconst outputError = (tool: string) => () =>\n new ToolError({\n tool,\n message: `${tool} produced a result that does not match its output schema.`,\n cause: 'execution'\n })\n\ntype KnowledgeTargetParams = typeof KnowledgeTargetParamsSchema.Type\n\ntype KnowledgeLookupParams = typeof KnowledgeLookupParams.Type\n\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 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\ntype KnowledgeLookupResultOutput = {\n readonly document: KnowledgeDocument\n score?: number\n context?: ReadonlyArray<{ readonly content: string }>\n}\n\nconst lookupResultOutput = (result: KnowledgeLookupResult) => {\n const output: KnowledgeLookupResultOutput = { document: result.document }\n\n if (result.score !== undefined) output.score = result.score\n\n if (result.context !== undefined) {\n output.context = result.context.map(chunk => ({ content: chunk.content }))\n }\n\n return output\n}\n\nconst savedResult = (input: {\n readonly name: string\n readonly callId: string\n readonly verb: string\n readonly operation: KnowledgeManageOutput['operation']\n readonly document: KnowledgeSavedDocument\n}) =>\n encodeManageOutput({\n operation: input.operation,\n document: { id: input.document.id, slug: input.document.slug, title: input.document.title }\n }).pipe(\n Effect.mapError(outputError(input.name)),\n Effect.map(structuredContent =>\n ToolResult.make({\n toolCallId: input.callId,\n content: formatSaved(input.verb, input.document),\n structuredContent\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 output: KnowledgeLookupOutput,\n access: 'read',\n invalidParamsMessage: error =>\n withToolArgumentsErrorHint(\n `Invalid knowledge lookup arguments: ${error instanceof Error ? error.message : String(error)}`,\n error\n ),\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 const structuredContent = yield* encodeLookupOutput({\n operation: 'search',\n results: results.map(lookupResultOutput)\n }).pipe(Effect.mapError(outputError(name)))\n\n return ToolResult.make({\n toolCallId: call.id,\n content: formatSearchResults(results),\n structuredContent\n })\n }\n\n const document = yield* handlers.get({\n context,\n id: optionalValue(params.id),\n target: optionalTargetFromParams(params.target)\n })\n\n const structuredContent = yield* encodeLookupOutput({ operation: 'get', document }).pipe(\n Effect.mapError(outputError(name))\n )\n\n return ToolResult.make({\n toolCallId: call.id,\n content: formatDocument(document),\n structuredContent\n })\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 output: KnowledgeManageOutput,\n access: 'write',\n invalidParamsMessage: error =>\n withToolArgumentsErrorHint(\n `Invalid knowledge manage arguments: ${error instanceof Error ? error.message : String(error)}`,\n error\n ),\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\n return yield* savedResult({\n name,\n callId: call.id,\n verb: 'Knowledge upserted',\n operation: 'upsert',\n document\n })\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\n return yield* savedResult({\n name,\n callId: call.id,\n verb: 'Knowledge availability updated',\n operation: 'set_availability',\n document\n })\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\n return yield* savedResult({\n name,\n callId: call.id,\n verb: 'Knowledge slug renamed',\n operation: 'rename_slug',\n document\n })\n }\n\n case 'delete': {\n const document = yield* handlers.delete({\n context,\n target: targetFromParams(params.target)\n })\n\n return yield* savedResult({\n name,\n callId: call.id,\n verb: 'Knowledge deleted',\n operation: 'delete',\n 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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"}
|
package/dist/chunking.d.mts
CHANGED
|
@@ -1,25 +1,23 @@
|
|
|
1
|
-
import { KnowledgeChunk, KnowledgeMetadata } from "./documents.mjs";
|
|
1
|
+
import { KnowledgeChunk, KnowledgeDocumentId, KnowledgeMetadata, KnowledgeScopeId } from "./documents.mjs";
|
|
2
2
|
import { KnowledgeChunkingError } from "./errors.mjs";
|
|
3
3
|
import { Context, Effect, Layer } from "effect";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
readonly collectionId: string;
|
|
8
|
-
readonly documentId: string;
|
|
4
|
+
export type ChunkKnowledgeDocumentInput = {
|
|
5
|
+
readonly scopeId: KnowledgeScopeId;
|
|
6
|
+
readonly documentId: KnowledgeDocumentId;
|
|
9
7
|
readonly content: string;
|
|
10
8
|
readonly maxTokens?: number;
|
|
11
9
|
readonly metadata?: KnowledgeMetadata;
|
|
12
10
|
};
|
|
13
|
-
type KnowledgeChunkerApi = {
|
|
11
|
+
export type KnowledgeChunkerApi = {
|
|
14
12
|
readonly chunk: (input: ChunkKnowledgeDocumentInput) => Effect.Effect<ReadonlyArray<KnowledgeChunk>, KnowledgeChunkingError>;
|
|
15
13
|
};
|
|
16
14
|
declare const KnowledgeChunker_base: Context.ServiceClass<KnowledgeChunker, "@yolk-sdk/knowledge/KnowledgeChunker", KnowledgeChunkerApi>;
|
|
17
|
-
declare class KnowledgeChunker extends KnowledgeChunker_base {}
|
|
18
|
-
declare const countKnowledgeChunkTokens: (text: string) => number;
|
|
19
|
-
declare const chunkKnowledgeText: (input: ChunkKnowledgeDocumentInput, maxTokens: number) => Effect.Effect<{
|
|
15
|
+
export declare class KnowledgeChunker extends KnowledgeChunker_base {}
|
|
16
|
+
export declare const countKnowledgeChunkTokens: (text: string) => number;
|
|
17
|
+
export declare const chunkKnowledgeText: (input: ChunkKnowledgeDocumentInput, maxTokens: number) => Effect.Effect<{
|
|
20
18
|
id: string;
|
|
21
|
-
|
|
22
|
-
documentId: string
|
|
19
|
+
scopeId: string & import("effect/Brand").Brand<"KnowledgeScopeId">;
|
|
20
|
+
documentId: string & import("effect/Brand").Brand<"KnowledgeDocumentId">;
|
|
23
21
|
content: string;
|
|
24
22
|
position: number;
|
|
25
23
|
tokenCount: number;
|
|
@@ -27,12 +25,11 @@ declare const chunkKnowledgeText: (input: ChunkKnowledgeDocumentInput, maxTokens
|
|
|
27
25
|
readonly [x: string]: unknown;
|
|
28
26
|
} | undefined;
|
|
29
27
|
}[], KnowledgeChunkingError, never>;
|
|
30
|
-
declare const makeDefaultKnowledgeChunker: (input: {
|
|
28
|
+
export declare const makeDefaultKnowledgeChunker: (input: {
|
|
31
29
|
readonly maxTokens: number;
|
|
32
30
|
}) => KnowledgeChunkerApi;
|
|
33
|
-
declare const DefaultKnowledgeChunkerLive: (input?: {
|
|
31
|
+
export declare const DefaultKnowledgeChunkerLive: (input?: {
|
|
34
32
|
readonly maxTokens: number;
|
|
35
33
|
}) => Layer.Layer<KnowledgeChunker, never, never>;
|
|
36
|
-
|
|
37
|
-
export { ChunkKnowledgeDocumentInput, DefaultKnowledgeChunkerLive, KnowledgeChunker, KnowledgeChunkerApi, chunkKnowledgeText, countKnowledgeChunkTokens, makeDefaultKnowledgeChunker };
|
|
34
|
+
export {};
|
|
38
35
|
//# sourceMappingURL=chunking.d.mts.map
|
package/dist/chunking.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunking.d.mts","names":[],"sources":["../src/chunking.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"chunking.d.mts","names":[],"sources":["../src/chunking.ts"],"mappings":";;;YAgBY;WACD,SAAS;WACT,YAAY;WACZ;WACA;WACA,WAAW;;YAGV;WACD,QACP,OAAO,gCACJ,OAAO,OAAO,cAAc,iBAAiB;;;qBAGvC,yBAAyB;qBAIzB,4BAAyB;qBAqHzB,qBAAkB,OAAW,6BAA2B,sBAAmB,OAAA;;;;;;;;;;KAgCpF;qBAES,8BAA2B;WAC7B;MACP;qBAIS,8BAA2B;WACpB;MAAmB,MAAA,MAAA"}
|
package/dist/chunking.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { KnowledgeChunkingError } from "./errors.mjs";
|
|
2
2
|
import { Context, Effect, Layer } from "effect";
|
|
3
3
|
import { countTokens, decode, encode } from "gpt-tokenizer/encoding/o200k_base";
|
|
4
|
-
|
|
4
|
+
// src/chunking.ts
|
|
5
5
|
const SENTENCE_PATTERN = /[^.!?]+[.!?]+(?:["')\]]+)?\s*|[^.!?]+$/g;
|
|
6
6
|
const PARAGRAPH_BREAK_PATTERN = /(\n{2,})/;
|
|
7
7
|
const WORD_PATTERN = /\S+\s*/g;
|
|
@@ -73,11 +73,12 @@ const chunkKnowledgeText = (input, maxTokens) => Effect.gen(function* () {
|
|
|
73
73
|
if (!Number.isInteger(maxTokens) || maxTokens < 1) return yield* Effect.fail(new KnowledgeChunkingError({ message: "Chunk maxTokens must be a positive integer" }));
|
|
74
74
|
const sanitized = sanitizeText(input.content);
|
|
75
75
|
if (sanitized.length === 0) return yield* Effect.fail(new KnowledgeChunkingError({ message: "Cannot chunk empty content" }));
|
|
76
|
-
const
|
|
76
|
+
const units = splitUnitsBySize(splitSentences(sanitized), maxTokens);
|
|
77
|
+
const contents = buildChunkContents(units, maxTokens);
|
|
77
78
|
if (contents.length === 0) return yield* Effect.fail(new KnowledgeChunkingError({ message: "No chunks produced" }));
|
|
78
79
|
return contents.map((content, position) => ({
|
|
79
80
|
id: `${input.documentId}:chunk:${position}`,
|
|
80
|
-
|
|
81
|
+
scopeId: input.scopeId,
|
|
81
82
|
documentId: input.documentId,
|
|
82
83
|
content,
|
|
83
84
|
position,
|
|
@@ -87,7 +88,6 @@ const chunkKnowledgeText = (input, maxTokens) => Effect.gen(function* () {
|
|
|
87
88
|
});
|
|
88
89
|
const makeDefaultKnowledgeChunker = (input) => ({ chunk: (document) => chunkKnowledgeText(document, document.maxTokens ?? input.maxTokens) });
|
|
89
90
|
const DefaultKnowledgeChunkerLive = (input = { maxTokens: 512 }) => Layer.succeed(KnowledgeChunker, makeDefaultKnowledgeChunker(input));
|
|
90
|
-
//#endregion
|
|
91
91
|
export { DefaultKnowledgeChunkerLive, KnowledgeChunker, chunkKnowledgeText, countKnowledgeChunkTokens, makeDefaultKnowledgeChunker };
|
|
92
92
|
|
|
93
93
|
//# sourceMappingURL=chunking.mjs.map
|
package/dist/chunking.mjs.map
CHANGED
|
@@ -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 {
|
|
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 {\n KnowledgeChunk,\n KnowledgeDocumentId,\n KnowledgeMetadata,\n KnowledgeScopeId\n} from './documents.ts'\nimport { KnowledgeChunkingError } from './errors.ts'\n\nconst SENTENCE_PATTERN = /[^.!?]+[.!?]+(?:[\"')\\]]+)?\\s*|[^.!?]+$/g\n\nconst PARAGRAPH_BREAK_PATTERN = /(\\n{2,})/\n\nconst WORD_PATTERN = /\\S+\\s*/g\n\nexport type ChunkKnowledgeDocumentInput = {\n readonly scopeId: KnowledgeScopeId\n readonly documentId: KnowledgeDocumentId\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\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\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\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\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\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\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\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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"}
|
package/dist/context.d.mts
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
//#region src/context.d.ts
|
|
5
|
-
type KnowledgeContextItem = {
|
|
6
|
-
readonly record: KnowledgeRecord;
|
|
7
|
-
readonly representation?: KnowledgeRepresentation;
|
|
8
|
-
};
|
|
9
|
-
type BuildKnowledgeContextInput = {
|
|
10
|
-
readonly items: ReadonlyArray<KnowledgeContextItem>;
|
|
1
|
+
import { KnowledgeDocument } from "./documents.mjs";
|
|
2
|
+
export type BuildKnowledgeContextInput = {
|
|
3
|
+
readonly documents: ReadonlyArray<KnowledgeDocument>;
|
|
11
4
|
readonly maxCharacters: number;
|
|
12
5
|
};
|
|
13
|
-
declare const buildKnowledgeContext: (input: BuildKnowledgeContextInput) => string;
|
|
14
|
-
//#endregion
|
|
15
|
-
export { BuildKnowledgeContextInput, KnowledgeContextItem, buildKnowledgeContext };
|
|
6
|
+
export declare const buildKnowledgeContext: (input: BuildKnowledgeContextInput) => string;
|
|
16
7
|
//# sourceMappingURL=context.d.mts.map
|
package/dist/context.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.mts","names":[],"sources":["../src/context.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"context.d.mts","names":[],"sources":["../src/context.ts"],"mappings":";YAGY;WACD,WAAW,cAAc;WACzB;;qBAuBE,wBAAqB,OAAW"}
|
package/dist/context.mjs
CHANGED
|
@@ -1,25 +1,29 @@
|
|
|
1
1
|
import { Array } from "effect";
|
|
2
|
-
|
|
2
|
+
// src/context.ts
|
|
3
3
|
const truncationMarker = "\n\n[truncated: pinned knowledge exceeded context budget]";
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
4
|
+
const documentHeader = (document) => [
|
|
5
|
+
`## ${document.title}`,
|
|
6
|
+
`slug: ${document.slug}`,
|
|
7
|
+
`purpose: ${document.purpose}`,
|
|
8
|
+
`origin: ${document.origin}`,
|
|
9
|
+
`status: ${document.status}`,
|
|
10
|
+
`availability: ${document.availability}`,
|
|
11
|
+
document.reviewedAt === void 0 ? void 0 : `reviewed_at: ${document.reviewedAt.toString()}`
|
|
12
|
+
].filter((line) => line !== void 0 && line.trim().length > 0).join("\n");
|
|
13
|
+
const documentBody = (document) => [
|
|
14
|
+
documentHeader(document),
|
|
15
|
+
document.summary,
|
|
16
|
+
document.content
|
|
17
|
+
].filter((section) => section !== void 0 && section.trim().length > 0).join("\n");
|
|
13
18
|
const buildKnowledgeContext = (input) => {
|
|
14
|
-
const sections = Array.map(input.
|
|
15
|
-
const header = "# Pinned knowledge\nUse this durable
|
|
19
|
+
const sections = Array.map(input.documents, documentBody).filter((section) => section.trim().length > 0);
|
|
20
|
+
const header = "# Pinned knowledge\nUse this durable knowledge as high-priority context.";
|
|
16
21
|
const body = sections.join("\n\n");
|
|
17
22
|
const context = body.length === 0 ? "" : `${header}\n\n${body}`;
|
|
18
23
|
if (context.length <= input.maxCharacters) return context;
|
|
19
24
|
if (input.maxCharacters <= 55) return context.slice(0, input.maxCharacters).trimEnd();
|
|
20
25
|
return `${context.slice(0, input.maxCharacters - 55).trimEnd()}${truncationMarker}`;
|
|
21
26
|
};
|
|
22
|
-
//#endregion
|
|
23
27
|
export { buildKnowledgeContext };
|
|
24
28
|
|
|
25
29
|
//# sourceMappingURL=context.mjs.map
|
package/dist/context.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.mjs","names":["Arr"],"sources":["../src/context.ts"],"sourcesContent":["import { Array as Arr } from 'effect'\nimport type {
|
|
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\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,CAAC,CACE,QAAO,SAAQ,SAAS,KAAA,KAAa,KAAK,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,CAC5D,KAAK,IAAI;AAEd,MAAM,gBAAgB,aACpB;CAAC,eAAe,QAAQ;CAAG,SAAS;CAAS,SAAS;AAAO,CAAC,CAC3D,QAAO,YAAW,YAAY,KAAA,KAAa,QAAQ,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,CACrE,KAAK,IAAI;AAEd,MAAa,yBAAyB,UAAsC;CAC1E,MAAM,WAAWA,MAAI,IAAI,MAAM,WAAW,YAAY,CAAC,CAAC,QACtD,YAAW,QAAQ,KAAK,CAAC,CAAC,SAAS,CACrC;CAEA,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,CAAC,CAAC,QAAQ;CAGvD,OAAO,GAAG,QAAQ,MAAM,GAAG,MAAM,gBAAgB,EAAuB,CAAC,CAAC,QAAQ,IAAI;AACxF"}
|