@yolk-sdk/knowledge 0.1.0-canary.96 → 0.1.0-canary.98
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 +11 -2
- package/dist/agent.d.mts +58 -1
- package/dist/agent.d.mts.map +1 -1
- package/dist/agent.mjs +102 -21
- package/dist/agent.mjs.map +1 -1
- package/dist/ingestion.d.mts +4 -4
- package/package.json +3 -3
- package/src/agent.ts +136 -17
package/README.md
CHANGED
|
@@ -5,11 +5,11 @@ Domain-free knowledge document/source/file/context, ingestion, hybrid search, an
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
pnpm add @yolk-sdk/knowledge@canary @yolk-sdk/agent@canary effect@4.0.0
|
|
8
|
+
pnpm add @yolk-sdk/knowledge@canary @yolk-sdk/agent@canary effect@4.0.0
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
Canary APIs are unstable. Keep all `@yolk-sdk/*` packages on the same version.
|
|
12
|
-
Use the SDK's matching Effect version (`4.0.0
|
|
12
|
+
Use the SDK's matching Effect version (`4.0.0`) in host code.
|
|
13
13
|
Published package metadata requires Node.js 22+.
|
|
14
14
|
|
|
15
15
|
## Model
|
|
@@ -141,6 +141,13 @@ const manageTool = makeKnowledgeManageTool({
|
|
|
141
141
|
The callbacks are host adapters and receive the agent tool context. Hosts own authorization,
|
|
142
142
|
storage, scope enforcement, and safe `ToolError` mapping.
|
|
143
143
|
|
|
144
|
+
Both tools declare an output (`KnowledgeLookupOutput`, `KnowledgeManageOutput`) and return its JSON
|
|
145
|
+
encoding as `structuredContent` (dates as ISO strings) next to the text, so code mode scripts get
|
|
146
|
+
`{ operation: 'search', results }`, `{ operation: 'get', document }`, or
|
|
147
|
+
`{ operation, document: { id, slug, title } }`. A handler value that does not encode fails the call
|
|
148
|
+
with an `execution` `ToolError`. Unknown argument keys are model-visible validation errors with a
|
|
149
|
+
hint naming the allowed keys, not stripped.
|
|
150
|
+
|
|
144
151
|
## Ingestion semantics
|
|
145
152
|
|
|
146
153
|
`ingestKnowledgeDocument` upserts a `processing` index record, extracts, chunks, embeds and
|
|
@@ -168,6 +175,8 @@ filtering, and any coordination with the content document store.
|
|
|
168
175
|
`KnowledgeSummarizer`, and `SearchIndexStore` layers. Summary/title values may be absent, but the
|
|
169
176
|
current pipeline still requires the summarizer service.
|
|
170
177
|
- Own concrete extraction, embeddings, search SQL/vector storage, and upload URLs.
|
|
178
|
+
`@yolk-sdk/extractors/knowledge` provides a `KnowledgeExtractor` for PDF, DOCX, XLSX, PPTX, and
|
|
179
|
+
text files (`FileKnowledgeExtractorLayer`) on top of its Node `FileExtractor`.
|
|
171
180
|
- Keep slug uniqueness scoped to the host boundary.
|
|
172
181
|
|
|
173
182
|
## Boundaries
|
package/dist/agent.d.mts
CHANGED
|
@@ -1,9 +1,66 @@
|
|
|
1
1
|
import { KnowledgeAvailability, KnowledgeDocument } from "./documents.mjs";
|
|
2
2
|
import { Effect } from "effect";
|
|
3
|
+
import * as Schema from "effect/Schema";
|
|
3
4
|
import { ToolError } from "@yolk-sdk/agent/loop";
|
|
4
5
|
import { ToolRegistration } from "@yolk-sdk/agent/tools";
|
|
5
6
|
|
|
6
7
|
//#region src/agent.d.ts
|
|
8
|
+
/** Declared output of `makeKnowledgeLookupTool`; `structuredContent` is its JSON encoding
|
|
9
|
+
* (`Schema.toCodecJson`: document dates become ISO strings). */
|
|
10
|
+
declare const KnowledgeLookupOutput: Schema.Union<readonly [Schema.Struct<{
|
|
11
|
+
readonly operation: Schema.Literal<"search">;
|
|
12
|
+
readonly results: Schema.$Array<Schema.Struct<{
|
|
13
|
+
readonly document: Schema.Struct<{
|
|
14
|
+
readonly id: Schema.brand<Schema.Trimmed, "KnowledgeDocumentId">;
|
|
15
|
+
readonly slug: Schema.Trimmed;
|
|
16
|
+
readonly title: Schema.Trimmed;
|
|
17
|
+
readonly purpose: Schema.Trimmed;
|
|
18
|
+
readonly origin: Schema.Trimmed;
|
|
19
|
+
readonly content: Schema.Trimmed;
|
|
20
|
+
readonly status: Schema.Literals<readonly ["processing", "ready", "error"]>;
|
|
21
|
+
readonly availability: Schema.Literals<readonly ["pinned", "searchable", "archived"]>;
|
|
22
|
+
readonly summary: Schema.optional<Schema.String>;
|
|
23
|
+
readonly errorMessage: Schema.optional<Schema.String>;
|
|
24
|
+
readonly reviewedAt: Schema.optional<Schema.DateTimeUtc>;
|
|
25
|
+
readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
|
|
26
|
+
readonly createdAt: Schema.DateTimeUtc;
|
|
27
|
+
readonly updatedAt: Schema.DateTimeUtc;
|
|
28
|
+
}>;
|
|
29
|
+
readonly score: Schema.optionalKey<Schema.Number>;
|
|
30
|
+
readonly context: Schema.optionalKey<Schema.$Array<Schema.Struct<{
|
|
31
|
+
readonly content: Schema.String;
|
|
32
|
+
}>>>;
|
|
33
|
+
}>>;
|
|
34
|
+
}>, Schema.Struct<{
|
|
35
|
+
readonly operation: Schema.Literal<"get">;
|
|
36
|
+
readonly document: Schema.Struct<{
|
|
37
|
+
readonly id: Schema.brand<Schema.Trimmed, "KnowledgeDocumentId">;
|
|
38
|
+
readonly slug: Schema.Trimmed;
|
|
39
|
+
readonly title: Schema.Trimmed;
|
|
40
|
+
readonly purpose: Schema.Trimmed;
|
|
41
|
+
readonly origin: Schema.Trimmed;
|
|
42
|
+
readonly content: Schema.Trimmed;
|
|
43
|
+
readonly status: Schema.Literals<readonly ["processing", "ready", "error"]>;
|
|
44
|
+
readonly availability: Schema.Literals<readonly ["pinned", "searchable", "archived"]>;
|
|
45
|
+
readonly summary: Schema.optional<Schema.String>;
|
|
46
|
+
readonly errorMessage: Schema.optional<Schema.String>;
|
|
47
|
+
readonly reviewedAt: Schema.optional<Schema.DateTimeUtc>;
|
|
48
|
+
readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
|
|
49
|
+
readonly createdAt: Schema.DateTimeUtc;
|
|
50
|
+
readonly updatedAt: Schema.DateTimeUtc;
|
|
51
|
+
}>;
|
|
52
|
+
}>]>;
|
|
53
|
+
type KnowledgeLookupOutput = typeof KnowledgeLookupOutput.Type;
|
|
54
|
+
/** Declared output of `makeKnowledgeManageTool`; `structuredContent` is its JSON encoding. */
|
|
55
|
+
declare const KnowledgeManageOutput: Schema.Struct<{
|
|
56
|
+
readonly operation: Schema.Literals<readonly ["upsert", "set_availability", "rename_slug", "delete"]>;
|
|
57
|
+
readonly document: Schema.Struct<{
|
|
58
|
+
readonly id: Schema.String;
|
|
59
|
+
readonly slug: Schema.String;
|
|
60
|
+
readonly title: Schema.String;
|
|
61
|
+
}>;
|
|
62
|
+
}>;
|
|
63
|
+
type KnowledgeManageOutput = typeof KnowledgeManageOutput.Type;
|
|
7
64
|
type KnowledgeTarget = {
|
|
8
65
|
readonly slug: string;
|
|
9
66
|
readonly scope?: string;
|
|
@@ -68,5 +125,5 @@ declare const makeKnowledgeManageTool: <Context>(handlers: KnowledgeManageHandle
|
|
|
68
125
|
readonly description?: string;
|
|
69
126
|
}) => ToolRegistration<Context>;
|
|
70
127
|
//#endregion
|
|
71
|
-
export { KnowledgeLookupHandlers, KnowledgeLookupResult, KnowledgeManageHandlers, KnowledgeSavedDocument, KnowledgeTarget, makeKnowledgeLookupTool, makeKnowledgeManageTool };
|
|
128
|
+
export { KnowledgeLookupHandlers, KnowledgeLookupOutput, KnowledgeLookupResult, KnowledgeManageHandlers, KnowledgeManageOutput, KnowledgeSavedDocument, KnowledgeTarget, makeKnowledgeLookupTool, makeKnowledgeManageTool };
|
|
72
129
|
//# sourceMappingURL=agent.d.mts.map
|
package/dist/agent.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.mts","names":[],"sources":["../src/agent.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"agent.d.mts","names":[],"sources":["../src/agent.ts"],"mappings":";;;;;;;;;cA6Ea,qBAAA,EAAqB,MAAA,CAAA,KAAA,WAAA,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAWtB,qBAAA,UAA+B,qBAAA,CAAsB,IAAI;;cAGxD,qBAAA,EAAqB,MAAA,CAAA,MAAA;EAAA;;;;;;;KAKtB,qBAAA,UAA+B,qBAAA,CAAsB,IAAI;AAAA,KAqBzD,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,cA2FjC,uBAAA,YACX,QAAA,EAAU,uBAAA,CAAwB,OAAA,GAClC,OAAA;EAAA,SAAoB,IAAA;EAAA,SAAwB,WAAA;AAAA,MAC3C,gBAAA,CAAiB,OAAA;AAAA,cA0DP,uBAAA,YACX,QAAA,EAAU,uBAAA,CAAwB,OAAA,GAClC,OAAA;EAAA,SAAoB,IAAA;EAAA,SAAwB,WAAA;AAAA,MAC3C,gBAAA,CAAiB,OAAA"}
|
package/dist/agent.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { KnowledgeAvailabilitySchema, NonEmptyTrimmedString, NonNegativeInteger, PositiveInteger } from "./documents.mjs";
|
|
1
|
+
import { KnowledgeAvailabilitySchema, KnowledgeDocumentSchema, NonEmptyTrimmedString, NonNegativeInteger, PositiveInteger } from "./documents.mjs";
|
|
2
2
|
import { Effect } from "effect";
|
|
3
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";
|
|
6
|
+
import { makeTool, withToolArgumentsErrorHint } from "@yolk-sdk/agent/tools";
|
|
7
7
|
//#region src/agent.ts
|
|
8
8
|
const OptionalNonEmptyTrimmedString = Schema.optional(Schema.NullOr(NonEmptyTrimmedString));
|
|
9
9
|
const OptionalPositiveInteger = Schema.optional(Schema.NullOr(PositiveInteger));
|
|
@@ -49,6 +49,43 @@ const KnowledgeManageParams = Schema.Union([
|
|
|
49
49
|
target: KnowledgeTargetParamsSchema
|
|
50
50
|
})
|
|
51
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
|
+
});
|
|
52
89
|
const optionalValue = (value) => value ?? void 0;
|
|
53
90
|
const targetFromParams = (target) => target.scope === null || target.scope === void 0 ? { slug: target.slug } : {
|
|
54
91
|
slug: target.slug,
|
|
@@ -83,13 +120,33 @@ const formatSaved = (verb, document) => [
|
|
|
83
120
|
`slug: ${document.slug}`,
|
|
84
121
|
`document_id: ${document.id}`
|
|
85
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
|
+
})));
|
|
86
141
|
const makeKnowledgeLookupTool = (handlers, options = {}) => {
|
|
142
|
+
const name = options.name ?? "knowledge_lookup";
|
|
87
143
|
return makeTool({
|
|
88
|
-
name
|
|
144
|
+
name,
|
|
89
145
|
description: options.description ?? "Look up durable knowledge. Search for semantic discovery; get when document_id or slug is known.",
|
|
90
146
|
parameters: KnowledgeLookupParams,
|
|
147
|
+
output: KnowledgeLookupOutput,
|
|
91
148
|
access: "read",
|
|
92
|
-
invalidParamsMessage: (error) => `Invalid knowledge lookup arguments: ${error instanceof Error ? error.message : String(error)}`,
|
|
149
|
+
invalidParamsMessage: (error) => withToolArgumentsErrorHint(`Invalid knowledge lookup arguments: ${error instanceof Error ? error.message : String(error)}`, error),
|
|
93
150
|
execute: ({ call, context, params }) => Effect.gen(function* () {
|
|
94
151
|
if (params.operation === "search") {
|
|
95
152
|
const results = yield* handlers.search({
|
|
@@ -99,9 +156,14 @@ const makeKnowledgeLookupTool = (handlers, options = {}) => {
|
|
|
99
156
|
minScore: optionalValue(params.minScore),
|
|
100
157
|
contextChunks: optionalValue(params.contextChunks)
|
|
101
158
|
});
|
|
159
|
+
const structuredContent = yield* encodeLookupOutput({
|
|
160
|
+
operation: "search",
|
|
161
|
+
results: results.map(lookupResultOutput)
|
|
162
|
+
}).pipe(Effect.mapError(outputError(name)));
|
|
102
163
|
return ToolResult.make({
|
|
103
164
|
toolCallId: call.id,
|
|
104
|
-
content: formatSearchResults(results)
|
|
165
|
+
content: formatSearchResults(results),
|
|
166
|
+
structuredContent
|
|
105
167
|
});
|
|
106
168
|
}
|
|
107
169
|
const document = yield* handlers.get({
|
|
@@ -109,20 +171,27 @@ const makeKnowledgeLookupTool = (handlers, options = {}) => {
|
|
|
109
171
|
id: optionalValue(params.id),
|
|
110
172
|
target: optionalTargetFromParams(params.target)
|
|
111
173
|
});
|
|
174
|
+
const structuredContent = yield* encodeLookupOutput({
|
|
175
|
+
operation: "get",
|
|
176
|
+
document
|
|
177
|
+
}).pipe(Effect.mapError(outputError(name)));
|
|
112
178
|
return ToolResult.make({
|
|
113
179
|
toolCallId: call.id,
|
|
114
|
-
content: formatDocument(document)
|
|
180
|
+
content: formatDocument(document),
|
|
181
|
+
structuredContent
|
|
115
182
|
});
|
|
116
183
|
})
|
|
117
184
|
});
|
|
118
185
|
};
|
|
119
186
|
const makeKnowledgeManageTool = (handlers, options = {}) => {
|
|
187
|
+
const name = options.name ?? "knowledge_manage";
|
|
120
188
|
return makeTool({
|
|
121
|
-
name
|
|
189
|
+
name,
|
|
122
190
|
description: options.description ?? "Create, replace, pin, archive, rename, or delete durable knowledge. Use only when explicitly asked.",
|
|
123
191
|
parameters: KnowledgeManageParams,
|
|
192
|
+
output: KnowledgeManageOutput,
|
|
124
193
|
access: "write",
|
|
125
|
-
invalidParamsMessage: (error) => `Invalid knowledge manage arguments: ${error instanceof Error ? error.message : String(error)}`,
|
|
194
|
+
invalidParamsMessage: (error) => withToolArgumentsErrorHint(`Invalid knowledge manage arguments: ${error instanceof Error ? error.message : String(error)}`, error),
|
|
126
195
|
execute: ({ call, context, params }) => Effect.gen(function* () {
|
|
127
196
|
switch (params.operation) {
|
|
128
197
|
case "upsert": {
|
|
@@ -135,9 +204,12 @@ const makeKnowledgeManageTool = (handlers, options = {}) => {
|
|
|
135
204
|
content: params.content,
|
|
136
205
|
availability: params.availability
|
|
137
206
|
});
|
|
138
|
-
return
|
|
139
|
-
|
|
140
|
-
|
|
207
|
+
return yield* savedResult({
|
|
208
|
+
name,
|
|
209
|
+
callId: call.id,
|
|
210
|
+
verb: "Knowledge upserted",
|
|
211
|
+
operation: "upsert",
|
|
212
|
+
document
|
|
141
213
|
});
|
|
142
214
|
}
|
|
143
215
|
case "set_availability": {
|
|
@@ -146,9 +218,12 @@ const makeKnowledgeManageTool = (handlers, options = {}) => {
|
|
|
146
218
|
target: targetFromParams(params.target),
|
|
147
219
|
availability: params.availability
|
|
148
220
|
});
|
|
149
|
-
return
|
|
150
|
-
|
|
151
|
-
|
|
221
|
+
return yield* savedResult({
|
|
222
|
+
name,
|
|
223
|
+
callId: call.id,
|
|
224
|
+
verb: "Knowledge availability updated",
|
|
225
|
+
operation: "set_availability",
|
|
226
|
+
document
|
|
152
227
|
});
|
|
153
228
|
}
|
|
154
229
|
case "rename_slug": {
|
|
@@ -157,9 +232,12 @@ const makeKnowledgeManageTool = (handlers, options = {}) => {
|
|
|
157
232
|
target: targetFromParams(params.target),
|
|
158
233
|
nextSlug: params.nextSlug
|
|
159
234
|
});
|
|
160
|
-
return
|
|
161
|
-
|
|
162
|
-
|
|
235
|
+
return yield* savedResult({
|
|
236
|
+
name,
|
|
237
|
+
callId: call.id,
|
|
238
|
+
verb: "Knowledge slug renamed",
|
|
239
|
+
operation: "rename_slug",
|
|
240
|
+
document
|
|
163
241
|
});
|
|
164
242
|
}
|
|
165
243
|
case "delete": {
|
|
@@ -167,9 +245,12 @@ const makeKnowledgeManageTool = (handlers, options = {}) => {
|
|
|
167
245
|
context,
|
|
168
246
|
target: targetFromParams(params.target)
|
|
169
247
|
});
|
|
170
|
-
return
|
|
171
|
-
|
|
172
|
-
|
|
248
|
+
return yield* savedResult({
|
|
249
|
+
name,
|
|
250
|
+
callId: call.id,
|
|
251
|
+
verb: "Knowledge deleted",
|
|
252
|
+
operation: "delete",
|
|
253
|
+
document
|
|
173
254
|
});
|
|
174
255
|
}
|
|
175
256
|
}
|
|
@@ -182,6 +263,6 @@ const makeKnowledgeManageTool = (handlers, options = {}) => {
|
|
|
182
263
|
});
|
|
183
264
|
};
|
|
184
265
|
//#endregion
|
|
185
|
-
export { makeKnowledgeLookupTool, makeKnowledgeManageTool };
|
|
266
|
+
export { KnowledgeLookupOutput, KnowledgeManageOutput, makeKnowledgeLookupTool, makeKnowledgeManageTool };
|
|
186
267
|
|
|
187
268
|
//# sourceMappingURL=agent.mjs.map
|
package/dist/agent.mjs.map
CHANGED
|
@@ -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 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\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\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 =>\n `Invalid knowledge lookup arguments: ${error instanceof Error ? error.message : String(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\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 =>\n `Invalid knowledge manage arguments: ${error instanceof Error ? error.message : String(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\n return ToolResult.make({\n toolCallId: call.id,\n content: formatSaved('Knowledge upserted', 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 ToolResult.make({\n toolCallId: call.id,\n content: formatSaved('Knowledge availability updated', 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 ToolResult.make({\n toolCallId: call.id,\n content: formatSaved('Knowledge slug renamed', document)\n })\n }\n\n case 'delete': {\n const document = yield* handlers.delete({\n context,\n target: targetFromParams(params.target)\n })\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
|
+
{"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/ingestion.d.mts
CHANGED
|
@@ -17,8 +17,8 @@ type IngestKnowledgeDocumentInput = {
|
|
|
17
17
|
};
|
|
18
18
|
declare const ingestKnowledgeDocument: (input: IngestKnowledgeDocumentInput) => Effect.Effect<{
|
|
19
19
|
readonly id: string & import("effect/Brand").Brand<"KnowledgeDocumentId">;
|
|
20
|
-
readonly scopeId: string & import("effect/Brand").Brand<"KnowledgeScopeId">;
|
|
21
20
|
readonly status: "processing" | "ready" | "error";
|
|
21
|
+
readonly scopeId: string & import("effect/Brand").Brand<"KnowledgeScopeId">;
|
|
22
22
|
readonly source: {
|
|
23
23
|
readonly _tag: "File";
|
|
24
24
|
readonly ref: string;
|
|
@@ -31,13 +31,13 @@ declare const ingestKnowledgeDocument: (input: IngestKnowledgeDocumentInput) =>
|
|
|
31
31
|
readonly _tag: "Text";
|
|
32
32
|
readonly label?: string | undefined;
|
|
33
33
|
};
|
|
34
|
+
readonly summary?: string | undefined;
|
|
35
|
+
readonly errorMessage?: string | undefined;
|
|
34
36
|
readonly metadata?: {
|
|
35
37
|
readonly [x: string]: unknown;
|
|
36
38
|
} | undefined;
|
|
37
|
-
readonly tokenCount?: number | undefined;
|
|
38
|
-
readonly summary?: string | undefined;
|
|
39
|
-
readonly errorMessage?: string | undefined;
|
|
40
39
|
readonly title?: string | undefined;
|
|
40
|
+
readonly tokenCount?: number | undefined;
|
|
41
41
|
readonly contentHash?: string | undefined;
|
|
42
42
|
readonly chunkCount?: number | undefined;
|
|
43
43
|
}, KnowledgeIngestionError, KnowledgeSummarizer | KnowledgeChunker | KnowledgeEmbedder | KnowledgeExtractor | SearchIndexStore>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yolk-sdk/knowledge",
|
|
3
|
-
"version": "0.1.0-canary.
|
|
3
|
+
"version": "0.1.0-canary.98",
|
|
4
4
|
"description": "Domain-free knowledge document/source/file/context, ingestion, hybrid search, and lookup/manage tool helpers for agents.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -104,9 +104,9 @@
|
|
|
104
104
|
"provenance": true
|
|
105
105
|
},
|
|
106
106
|
"dependencies": {
|
|
107
|
-
"effect": "4.0.0
|
|
107
|
+
"effect": "4.0.0",
|
|
108
108
|
"gpt-tokenizer": "^3.4.0",
|
|
109
|
-
"@yolk-sdk/agent": "^0.1.0-canary.
|
|
109
|
+
"@yolk-sdk/agent": "^0.1.0-canary.98"
|
|
110
110
|
},
|
|
111
111
|
"scripts": {
|
|
112
112
|
"build": "tsdown",
|
package/src/agent.ts
CHANGED
|
@@ -2,9 +2,10 @@ import { Effect } from 'effect'
|
|
|
2
2
|
import * as Schema from 'effect/Schema'
|
|
3
3
|
import { ToolError } from '@yolk-sdk/agent/loop'
|
|
4
4
|
import { ToolResult } from '@yolk-sdk/agent/protocol'
|
|
5
|
-
import { makeTool, type ToolRegistration } from '@yolk-sdk/agent/tools'
|
|
5
|
+
import { makeTool, withToolArgumentsErrorHint, type ToolRegistration } from '@yolk-sdk/agent/tools'
|
|
6
6
|
import {
|
|
7
7
|
KnowledgeAvailabilitySchema,
|
|
8
|
+
KnowledgeDocumentSchema,
|
|
8
9
|
NonNegativeInteger,
|
|
9
10
|
NonEmptyTrimmedString,
|
|
10
11
|
PositiveInteger,
|
|
@@ -66,6 +67,48 @@ const KnowledgeManageParams = Schema.Union([
|
|
|
66
67
|
})
|
|
67
68
|
])
|
|
68
69
|
|
|
70
|
+
const KnowledgeLookupResultSchema = Schema.Struct({
|
|
71
|
+
document: KnowledgeDocumentSchema,
|
|
72
|
+
score: Schema.optionalKey(Schema.Number),
|
|
73
|
+
context: Schema.optionalKey(Schema.Array(Schema.Struct({ content: Schema.String })))
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
/** Declared output of `makeKnowledgeLookupTool`; `structuredContent` is its JSON encoding
|
|
77
|
+
* (`Schema.toCodecJson`: document dates become ISO strings). */
|
|
78
|
+
export const KnowledgeLookupOutput = Schema.Union([
|
|
79
|
+
Schema.Struct({
|
|
80
|
+
operation: Schema.Literal('search'),
|
|
81
|
+
results: Schema.Array(KnowledgeLookupResultSchema)
|
|
82
|
+
}),
|
|
83
|
+
Schema.Struct({
|
|
84
|
+
operation: Schema.Literal('get'),
|
|
85
|
+
document: KnowledgeDocumentSchema
|
|
86
|
+
})
|
|
87
|
+
])
|
|
88
|
+
|
|
89
|
+
export type KnowledgeLookupOutput = typeof KnowledgeLookupOutput.Type
|
|
90
|
+
|
|
91
|
+
/** Declared output of `makeKnowledgeManageTool`; `structuredContent` is its JSON encoding. */
|
|
92
|
+
export const KnowledgeManageOutput = Schema.Struct({
|
|
93
|
+
operation: Schema.Literals(['upsert', 'set_availability', 'rename_slug', 'delete']),
|
|
94
|
+
document: Schema.Struct({ id: Schema.String, slug: Schema.String, title: Schema.String })
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
export type KnowledgeManageOutput = typeof KnowledgeManageOutput.Type
|
|
98
|
+
|
|
99
|
+
const encodeLookupOutput = Schema.encodeEffect(Schema.toCodecJson(KnowledgeLookupOutput))
|
|
100
|
+
|
|
101
|
+
const encodeManageOutput = Schema.encodeEffect(Schema.toCodecJson(KnowledgeManageOutput))
|
|
102
|
+
|
|
103
|
+
/** A handler result that does not encode to the declared output is a host bug, not a model
|
|
104
|
+
* mistake: fail with a safe message (no values). */
|
|
105
|
+
const outputError = (tool: string) => () =>
|
|
106
|
+
new ToolError({
|
|
107
|
+
tool,
|
|
108
|
+
message: `${tool} produced a result that does not match its output schema.`,
|
|
109
|
+
cause: 'execution'
|
|
110
|
+
})
|
|
111
|
+
|
|
69
112
|
type KnowledgeTargetParams = typeof KnowledgeTargetParamsSchema.Type
|
|
70
113
|
|
|
71
114
|
type KnowledgeLookupParams = typeof KnowledgeLookupParams.Type
|
|
@@ -179,6 +222,45 @@ const formatSaved = (verb: string, document: KnowledgeSavedDocument) =>
|
|
|
179
222
|
'\n'
|
|
180
223
|
)
|
|
181
224
|
|
|
225
|
+
type KnowledgeLookupResultOutput = {
|
|
226
|
+
readonly document: KnowledgeDocument
|
|
227
|
+
score?: number
|
|
228
|
+
context?: ReadonlyArray<{ readonly content: string }>
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const lookupResultOutput = (result: KnowledgeLookupResult) => {
|
|
232
|
+
const output: KnowledgeLookupResultOutput = { document: result.document }
|
|
233
|
+
|
|
234
|
+
if (result.score !== undefined) output.score = result.score
|
|
235
|
+
|
|
236
|
+
if (result.context !== undefined) {
|
|
237
|
+
output.context = result.context.map(chunk => ({ content: chunk.content }))
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return output
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const savedResult = (input: {
|
|
244
|
+
readonly name: string
|
|
245
|
+
readonly callId: string
|
|
246
|
+
readonly verb: string
|
|
247
|
+
readonly operation: KnowledgeManageOutput['operation']
|
|
248
|
+
readonly document: KnowledgeSavedDocument
|
|
249
|
+
}) =>
|
|
250
|
+
encodeManageOutput({
|
|
251
|
+
operation: input.operation,
|
|
252
|
+
document: { id: input.document.id, slug: input.document.slug, title: input.document.title }
|
|
253
|
+
}).pipe(
|
|
254
|
+
Effect.mapError(outputError(input.name)),
|
|
255
|
+
Effect.map(structuredContent =>
|
|
256
|
+
ToolResult.make({
|
|
257
|
+
toolCallId: input.callId,
|
|
258
|
+
content: formatSaved(input.verb, input.document),
|
|
259
|
+
structuredContent
|
|
260
|
+
})
|
|
261
|
+
)
|
|
262
|
+
)
|
|
263
|
+
|
|
182
264
|
export const makeKnowledgeLookupTool = <Context>(
|
|
183
265
|
handlers: KnowledgeLookupHandlers<Context>,
|
|
184
266
|
options: { readonly name?: string; readonly description?: string } = {}
|
|
@@ -191,9 +273,13 @@ export const makeKnowledgeLookupTool = <Context>(
|
|
|
191
273
|
options.description ??
|
|
192
274
|
'Look up durable knowledge. Search for semantic discovery; get when document_id or slug is known.',
|
|
193
275
|
parameters: KnowledgeLookupParams,
|
|
276
|
+
output: KnowledgeLookupOutput,
|
|
194
277
|
access: 'read',
|
|
195
278
|
invalidParamsMessage: error =>
|
|
196
|
-
|
|
279
|
+
withToolArgumentsErrorHint(
|
|
280
|
+
`Invalid knowledge lookup arguments: ${error instanceof Error ? error.message : String(error)}`,
|
|
281
|
+
error
|
|
282
|
+
),
|
|
197
283
|
execute: ({ call, context, params }) =>
|
|
198
284
|
Effect.gen(function* () {
|
|
199
285
|
if (params.operation === 'search') {
|
|
@@ -205,7 +291,16 @@ export const makeKnowledgeLookupTool = <Context>(
|
|
|
205
291
|
contextChunks: optionalValue(params.contextChunks)
|
|
206
292
|
})
|
|
207
293
|
|
|
208
|
-
|
|
294
|
+
const structuredContent = yield* encodeLookupOutput({
|
|
295
|
+
operation: 'search',
|
|
296
|
+
results: results.map(lookupResultOutput)
|
|
297
|
+
}).pipe(Effect.mapError(outputError(name)))
|
|
298
|
+
|
|
299
|
+
return ToolResult.make({
|
|
300
|
+
toolCallId: call.id,
|
|
301
|
+
content: formatSearchResults(results),
|
|
302
|
+
structuredContent
|
|
303
|
+
})
|
|
209
304
|
}
|
|
210
305
|
|
|
211
306
|
const document = yield* handlers.get({
|
|
@@ -214,7 +309,15 @@ export const makeKnowledgeLookupTool = <Context>(
|
|
|
214
309
|
target: optionalTargetFromParams(params.target)
|
|
215
310
|
})
|
|
216
311
|
|
|
217
|
-
|
|
312
|
+
const structuredContent = yield* encodeLookupOutput({ operation: 'get', document }).pipe(
|
|
313
|
+
Effect.mapError(outputError(name))
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
return ToolResult.make({
|
|
317
|
+
toolCallId: call.id,
|
|
318
|
+
content: formatDocument(document),
|
|
319
|
+
structuredContent
|
|
320
|
+
})
|
|
218
321
|
})
|
|
219
322
|
})
|
|
220
323
|
}
|
|
@@ -231,9 +334,13 @@ export const makeKnowledgeManageTool = <Context>(
|
|
|
231
334
|
options.description ??
|
|
232
335
|
'Create, replace, pin, archive, rename, or delete durable knowledge. Use only when explicitly asked.',
|
|
233
336
|
parameters: KnowledgeManageParams,
|
|
337
|
+
output: KnowledgeManageOutput,
|
|
234
338
|
access: 'write',
|
|
235
339
|
invalidParamsMessage: error =>
|
|
236
|
-
|
|
340
|
+
withToolArgumentsErrorHint(
|
|
341
|
+
`Invalid knowledge manage arguments: ${error instanceof Error ? error.message : String(error)}`,
|
|
342
|
+
error
|
|
343
|
+
),
|
|
237
344
|
execute: ({ call, context, params }) =>
|
|
238
345
|
Effect.gen(function* () {
|
|
239
346
|
switch (params.operation) {
|
|
@@ -248,9 +355,12 @@ export const makeKnowledgeManageTool = <Context>(
|
|
|
248
355
|
availability: params.availability
|
|
249
356
|
})
|
|
250
357
|
|
|
251
|
-
return
|
|
252
|
-
|
|
253
|
-
|
|
358
|
+
return yield* savedResult({
|
|
359
|
+
name,
|
|
360
|
+
callId: call.id,
|
|
361
|
+
verb: 'Knowledge upserted',
|
|
362
|
+
operation: 'upsert',
|
|
363
|
+
document
|
|
254
364
|
})
|
|
255
365
|
}
|
|
256
366
|
|
|
@@ -261,9 +371,12 @@ export const makeKnowledgeManageTool = <Context>(
|
|
|
261
371
|
availability: params.availability
|
|
262
372
|
})
|
|
263
373
|
|
|
264
|
-
return
|
|
265
|
-
|
|
266
|
-
|
|
374
|
+
return yield* savedResult({
|
|
375
|
+
name,
|
|
376
|
+
callId: call.id,
|
|
377
|
+
verb: 'Knowledge availability updated',
|
|
378
|
+
operation: 'set_availability',
|
|
379
|
+
document
|
|
267
380
|
})
|
|
268
381
|
}
|
|
269
382
|
|
|
@@ -274,9 +387,12 @@ export const makeKnowledgeManageTool = <Context>(
|
|
|
274
387
|
nextSlug: params.nextSlug
|
|
275
388
|
})
|
|
276
389
|
|
|
277
|
-
return
|
|
278
|
-
|
|
279
|
-
|
|
390
|
+
return yield* savedResult({
|
|
391
|
+
name,
|
|
392
|
+
callId: call.id,
|
|
393
|
+
verb: 'Knowledge slug renamed',
|
|
394
|
+
operation: 'rename_slug',
|
|
395
|
+
document
|
|
280
396
|
})
|
|
281
397
|
}
|
|
282
398
|
|
|
@@ -286,9 +402,12 @@ export const makeKnowledgeManageTool = <Context>(
|
|
|
286
402
|
target: targetFromParams(params.target)
|
|
287
403
|
})
|
|
288
404
|
|
|
289
|
-
return
|
|
290
|
-
|
|
291
|
-
|
|
405
|
+
return yield* savedResult({
|
|
406
|
+
name,
|
|
407
|
+
callId: call.id,
|
|
408
|
+
verb: 'Knowledge deleted',
|
|
409
|
+
operation: 'delete',
|
|
410
|
+
document
|
|
292
411
|
})
|
|
293
412
|
}
|
|
294
413
|
}
|