@deepagents/context 0.26.0 → 0.28.0
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 +9 -16
- package/dist/browser.d.ts +2 -1
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +825 -310
- package/dist/browser.js.map +4 -4
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2632 -1972
- package/dist/index.js.map +4 -4
- package/dist/lib/agent.d.ts +1 -0
- package/dist/lib/agent.d.ts.map +1 -1
- package/dist/lib/chat.d.ts +3 -0
- package/dist/lib/chat.d.ts.map +1 -1
- package/dist/lib/codec/codec.d.ts.map +1 -0
- package/dist/lib/codec/serialized-codec.d.ts +3 -0
- package/dist/lib/codec/serialized-codec.d.ts.map +1 -0
- package/dist/lib/codec/serialized-fragments.d.ts +114 -0
- package/dist/lib/codec/serialized-fragments.d.ts.map +1 -0
- package/dist/lib/engine.d.ts +9 -2
- package/dist/lib/engine.d.ts.map +1 -1
- package/dist/lib/fragments/domain.d.ts.map +1 -1
- package/dist/lib/fragments/message/user.d.ts +27 -4
- package/dist/lib/fragments/message/user.d.ts.map +1 -1
- package/dist/lib/fragments/user.d.ts +1 -16
- package/dist/lib/fragments/user.d.ts.map +1 -1
- package/dist/lib/fragments.d.ts +3 -2
- package/dist/lib/fragments.d.ts.map +1 -1
- package/dist/lib/renderers/abstract.renderer.d.ts.map +1 -1
- package/dist/lib/skills/classifier.d.ts.map +1 -1
- package/dist/lib/title.d.ts +10 -0
- package/dist/lib/title.d.ts.map +1 -0
- package/package.json +4 -3
- package/dist/lib/codec.d.ts.map +0 -1
- /package/dist/lib/{codec.d.ts → codec/codec.d.ts} +0 -0
package/dist/browser.js
CHANGED
|
@@ -1,167 +1,7 @@
|
|
|
1
|
-
// packages/context/src/lib/estimate.ts
|
|
2
|
-
import { encode } from "gpt-tokenizer";
|
|
3
|
-
var defaultTokenizer = {
|
|
4
|
-
encode(text) {
|
|
5
|
-
return encode(text);
|
|
6
|
-
},
|
|
7
|
-
count(text) {
|
|
8
|
-
return encode(text).length;
|
|
9
|
-
}
|
|
10
|
-
};
|
|
11
|
-
var ModelsRegistry = class {
|
|
12
|
-
#cache = /* @__PURE__ */ new Map();
|
|
13
|
-
#loaded = false;
|
|
14
|
-
#tokenizers = /* @__PURE__ */ new Map();
|
|
15
|
-
#defaultTokenizer = defaultTokenizer;
|
|
16
|
-
/**
|
|
17
|
-
* Load models data from models.dev API
|
|
18
|
-
*/
|
|
19
|
-
async load() {
|
|
20
|
-
if (this.#loaded) return;
|
|
21
|
-
const response = await fetch("https://models.dev/api.json");
|
|
22
|
-
if (!response.ok) {
|
|
23
|
-
throw new Error(`Failed to fetch models: ${response.statusText}`);
|
|
24
|
-
}
|
|
25
|
-
const data = await response.json();
|
|
26
|
-
for (const [providerId, provider] of Object.entries(data)) {
|
|
27
|
-
for (const [modelId, model] of Object.entries(provider.models)) {
|
|
28
|
-
const info = {
|
|
29
|
-
id: model.id,
|
|
30
|
-
name: model.name,
|
|
31
|
-
family: model.family,
|
|
32
|
-
cost: model.cost,
|
|
33
|
-
limit: model.limit,
|
|
34
|
-
provider: providerId
|
|
35
|
-
};
|
|
36
|
-
this.#cache.set(`${providerId}:${modelId}`, info);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
this.#loaded = true;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Get model info by ID
|
|
43
|
-
* @param modelId - Model ID (e.g., "openai:gpt-4o")
|
|
44
|
-
*/
|
|
45
|
-
get(modelId) {
|
|
46
|
-
return this.#cache.get(modelId);
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Check if a model exists in the registry
|
|
50
|
-
*/
|
|
51
|
-
has(modelId) {
|
|
52
|
-
return this.#cache.has(modelId);
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* List all available model IDs
|
|
56
|
-
*/
|
|
57
|
-
list() {
|
|
58
|
-
return [...this.#cache.keys()];
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Register a custom tokenizer for specific model families
|
|
62
|
-
* @param family - Model family name (e.g., "llama", "claude")
|
|
63
|
-
* @param tokenizer - Tokenizer implementation
|
|
64
|
-
*/
|
|
65
|
-
registerTokenizer(family, tokenizer) {
|
|
66
|
-
this.#tokenizers.set(family, tokenizer);
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Set the default tokenizer used when no family-specific tokenizer is registered
|
|
70
|
-
*/
|
|
71
|
-
setDefaultTokenizer(tokenizer) {
|
|
72
|
-
this.#defaultTokenizer = tokenizer;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Get the appropriate tokenizer for a model
|
|
76
|
-
*/
|
|
77
|
-
getTokenizer(modelId) {
|
|
78
|
-
const model = this.get(modelId);
|
|
79
|
-
if (model) {
|
|
80
|
-
const familyTokenizer = this.#tokenizers.get(model.family);
|
|
81
|
-
if (familyTokenizer) {
|
|
82
|
-
return familyTokenizer;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
return this.#defaultTokenizer;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Estimate token count and cost for given text and model
|
|
89
|
-
* @param modelId - Model ID to use for pricing (e.g., "openai:gpt-4o")
|
|
90
|
-
* @param input - Input text (prompt)
|
|
91
|
-
*/
|
|
92
|
-
estimate(modelId, input) {
|
|
93
|
-
const model = this.get(modelId);
|
|
94
|
-
if (!model) {
|
|
95
|
-
throw new Error(
|
|
96
|
-
`Model "${modelId}" not found. Call load() first or check model ID.`
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
const tokenizer = this.getTokenizer(modelId);
|
|
100
|
-
const tokens = tokenizer.count(input);
|
|
101
|
-
const cost = tokens / 1e6 * model.cost.input;
|
|
102
|
-
return {
|
|
103
|
-
model: model.id,
|
|
104
|
-
provider: model.provider,
|
|
105
|
-
tokens,
|
|
106
|
-
cost,
|
|
107
|
-
limits: {
|
|
108
|
-
context: model.limit.context,
|
|
109
|
-
output: model.limit.output,
|
|
110
|
-
exceedsContext: tokens > model.limit.context
|
|
111
|
-
},
|
|
112
|
-
fragments: []
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
var _registry = null;
|
|
117
|
-
function getModelsRegistry() {
|
|
118
|
-
if (!_registry) {
|
|
119
|
-
_registry = new ModelsRegistry();
|
|
120
|
-
}
|
|
121
|
-
return _registry;
|
|
122
|
-
}
|
|
123
|
-
async function estimate(modelId, renderer, ...fragments) {
|
|
124
|
-
const registry = getModelsRegistry();
|
|
125
|
-
await registry.load();
|
|
126
|
-
const input = renderer.render(fragments);
|
|
127
|
-
const model = registry.get(modelId);
|
|
128
|
-
if (!model) {
|
|
129
|
-
throw new Error(
|
|
130
|
-
`Model "${modelId}" not found. Call load() first or check model ID.`
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
const tokenizer = registry.getTokenizer(modelId);
|
|
134
|
-
const totalTokens = tokenizer.count(input);
|
|
135
|
-
const totalCost = totalTokens / 1e6 * model.cost.input;
|
|
136
|
-
const fragmentEstimates = fragments.map((fragment2) => {
|
|
137
|
-
const rendered = renderer.render([fragment2]);
|
|
138
|
-
const tokens = tokenizer.count(rendered);
|
|
139
|
-
const cost = tokens / 1e6 * model.cost.input;
|
|
140
|
-
return {
|
|
141
|
-
id: fragment2.id,
|
|
142
|
-
name: fragment2.name,
|
|
143
|
-
tokens,
|
|
144
|
-
cost
|
|
145
|
-
};
|
|
146
|
-
});
|
|
147
|
-
return {
|
|
148
|
-
model: model.id,
|
|
149
|
-
provider: model.provider,
|
|
150
|
-
tokens: totalTokens,
|
|
151
|
-
cost: totalCost,
|
|
152
|
-
limits: {
|
|
153
|
-
context: model.limit.context,
|
|
154
|
-
output: model.limit.output,
|
|
155
|
-
exceedsContext: totalTokens > model.limit.context
|
|
156
|
-
},
|
|
157
|
-
fragments: fragmentEstimates
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
|
|
161
1
|
// packages/context/src/lib/fragments.ts
|
|
162
2
|
import { generateId } from "ai";
|
|
163
3
|
function isFragment(data) {
|
|
164
|
-
return typeof data === "object" && data !== null && "name" in data && "data" in data && typeof data.name === "string";
|
|
4
|
+
return typeof data === "object" && data !== null && "name" in data && ("data" in data || "codec" in data) && typeof data.name === "string";
|
|
165
5
|
}
|
|
166
6
|
function isFragmentObject(data) {
|
|
167
7
|
return typeof data === "object" && data !== null && !Array.isArray(data) && !isFragment(data);
|
|
@@ -169,6 +9,15 @@ function isFragmentObject(data) {
|
|
|
169
9
|
function isMessageFragment(fragment2) {
|
|
170
10
|
return fragment2.type === "message";
|
|
171
11
|
}
|
|
12
|
+
function getFragmentData(fragment2) {
|
|
13
|
+
if (fragment2.codec) {
|
|
14
|
+
return fragment2.codec.decode();
|
|
15
|
+
}
|
|
16
|
+
if ("data" in fragment2) {
|
|
17
|
+
return fragment2.data;
|
|
18
|
+
}
|
|
19
|
+
throw new Error(`Fragment "${fragment2.name}" is missing data and codec`);
|
|
20
|
+
}
|
|
172
21
|
function fragment(name, ...children) {
|
|
173
22
|
return {
|
|
174
23
|
name,
|
|
@@ -179,7 +28,6 @@ function assistant(message2) {
|
|
|
179
28
|
return {
|
|
180
29
|
id: message2.id,
|
|
181
30
|
name: "assistant",
|
|
182
|
-
data: "content",
|
|
183
31
|
type: "message",
|
|
184
32
|
persist: true,
|
|
185
33
|
codec: {
|
|
@@ -201,7 +49,6 @@ function message(content) {
|
|
|
201
49
|
return {
|
|
202
50
|
id: message2.id,
|
|
203
51
|
name: message2.role,
|
|
204
|
-
data: "content",
|
|
205
52
|
type: "message",
|
|
206
53
|
persist: true,
|
|
207
54
|
codec: {
|
|
@@ -239,17 +86,60 @@ function lastAssistantMessage(content) {
|
|
|
239
86
|
};
|
|
240
87
|
}
|
|
241
88
|
|
|
89
|
+
// packages/context/src/lib/codec/serialized-codec.ts
|
|
90
|
+
function encodeSerializedValue(value) {
|
|
91
|
+
if (isFragment(value)) {
|
|
92
|
+
if (isMessageFragment(value)) {
|
|
93
|
+
throw new Error(
|
|
94
|
+
"Message fragments are not supported by serialized fragment conversion"
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
if (!value.codec) {
|
|
98
|
+
throw new Error(`Fragment "${value.name}" is missing codec`);
|
|
99
|
+
}
|
|
100
|
+
return value.codec.encode();
|
|
101
|
+
}
|
|
102
|
+
if (Array.isArray(value)) {
|
|
103
|
+
return value.map((item) => encodeSerializedValue(item));
|
|
104
|
+
}
|
|
105
|
+
if (isFragmentObject(value)) {
|
|
106
|
+
return Object.fromEntries(
|
|
107
|
+
Object.entries(value).map(([key, entry]) => [
|
|
108
|
+
key,
|
|
109
|
+
encodeSerializedValue(entry)
|
|
110
|
+
])
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
return value;
|
|
114
|
+
}
|
|
115
|
+
|
|
242
116
|
// packages/context/src/lib/fragments/domain.ts
|
|
243
117
|
function term(name, definition) {
|
|
244
118
|
return {
|
|
245
119
|
name: "term",
|
|
246
|
-
data: { name, definition }
|
|
120
|
+
data: { name, definition },
|
|
121
|
+
codec: {
|
|
122
|
+
encode() {
|
|
123
|
+
return { type: "term", name, definition };
|
|
124
|
+
},
|
|
125
|
+
decode() {
|
|
126
|
+
return { name, definition };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
247
129
|
};
|
|
248
130
|
}
|
|
249
131
|
function hint(text) {
|
|
250
132
|
return {
|
|
251
133
|
name: "hint",
|
|
252
|
-
data: text
|
|
134
|
+
data: text,
|
|
135
|
+
codec: {
|
|
136
|
+
encode() {
|
|
137
|
+
return { type: "hint", text };
|
|
138
|
+
},
|
|
139
|
+
decode() {
|
|
140
|
+
return text;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
253
143
|
};
|
|
254
144
|
}
|
|
255
145
|
function guardrail(input) {
|
|
@@ -259,6 +149,23 @@ function guardrail(input) {
|
|
|
259
149
|
rule: input.rule,
|
|
260
150
|
...input.reason && { reason: input.reason },
|
|
261
151
|
...input.action && { action: input.action }
|
|
152
|
+
},
|
|
153
|
+
codec: {
|
|
154
|
+
encode() {
|
|
155
|
+
return {
|
|
156
|
+
type: "guardrail",
|
|
157
|
+
rule: input.rule,
|
|
158
|
+
...input.reason && { reason: input.reason },
|
|
159
|
+
...input.action && { action: input.action }
|
|
160
|
+
};
|
|
161
|
+
},
|
|
162
|
+
decode() {
|
|
163
|
+
return {
|
|
164
|
+
rule: input.rule,
|
|
165
|
+
...input.reason && { reason: input.reason },
|
|
166
|
+
...input.action && { action: input.action }
|
|
167
|
+
};
|
|
168
|
+
}
|
|
262
169
|
}
|
|
263
170
|
};
|
|
264
171
|
}
|
|
@@ -269,6 +176,23 @@ function explain(input) {
|
|
|
269
176
|
concept: input.concept,
|
|
270
177
|
explanation: input.explanation,
|
|
271
178
|
...input.therefore && { therefore: input.therefore }
|
|
179
|
+
},
|
|
180
|
+
codec: {
|
|
181
|
+
encode() {
|
|
182
|
+
return {
|
|
183
|
+
type: "explain",
|
|
184
|
+
concept: input.concept,
|
|
185
|
+
explanation: input.explanation,
|
|
186
|
+
...input.therefore && { therefore: input.therefore }
|
|
187
|
+
};
|
|
188
|
+
},
|
|
189
|
+
decode() {
|
|
190
|
+
return {
|
|
191
|
+
concept: input.concept,
|
|
192
|
+
explanation: input.explanation,
|
|
193
|
+
...input.therefore && { therefore: input.therefore }
|
|
194
|
+
};
|
|
195
|
+
}
|
|
272
196
|
}
|
|
273
197
|
};
|
|
274
198
|
}
|
|
@@ -279,6 +203,23 @@ function example(input) {
|
|
|
279
203
|
question: input.question,
|
|
280
204
|
answer: input.answer,
|
|
281
205
|
...input.note && { note: input.note }
|
|
206
|
+
},
|
|
207
|
+
codec: {
|
|
208
|
+
encode() {
|
|
209
|
+
return {
|
|
210
|
+
type: "example",
|
|
211
|
+
question: input.question,
|
|
212
|
+
answer: input.answer,
|
|
213
|
+
...input.note && { note: input.note }
|
|
214
|
+
};
|
|
215
|
+
},
|
|
216
|
+
decode() {
|
|
217
|
+
return {
|
|
218
|
+
question: input.question,
|
|
219
|
+
answer: input.answer,
|
|
220
|
+
...input.note && { note: input.note }
|
|
221
|
+
};
|
|
222
|
+
}
|
|
282
223
|
}
|
|
283
224
|
};
|
|
284
225
|
}
|
|
@@ -289,6 +230,23 @@ function clarification(input) {
|
|
|
289
230
|
when: input.when,
|
|
290
231
|
ask: input.ask,
|
|
291
232
|
reason: input.reason
|
|
233
|
+
},
|
|
234
|
+
codec: {
|
|
235
|
+
encode() {
|
|
236
|
+
return {
|
|
237
|
+
type: "clarification",
|
|
238
|
+
when: input.when,
|
|
239
|
+
ask: input.ask,
|
|
240
|
+
reason: input.reason
|
|
241
|
+
};
|
|
242
|
+
},
|
|
243
|
+
decode() {
|
|
244
|
+
return {
|
|
245
|
+
when: input.when,
|
|
246
|
+
ask: input.ask,
|
|
247
|
+
reason: input.reason
|
|
248
|
+
};
|
|
249
|
+
}
|
|
292
250
|
}
|
|
293
251
|
};
|
|
294
252
|
}
|
|
@@ -300,6 +258,25 @@ function workflow(input) {
|
|
|
300
258
|
steps: input.steps,
|
|
301
259
|
...input.triggers?.length && { triggers: input.triggers },
|
|
302
260
|
...input.notes && { notes: input.notes }
|
|
261
|
+
},
|
|
262
|
+
codec: {
|
|
263
|
+
encode() {
|
|
264
|
+
return {
|
|
265
|
+
type: "workflow",
|
|
266
|
+
task: input.task,
|
|
267
|
+
steps: input.steps,
|
|
268
|
+
...input.triggers?.length && { triggers: input.triggers },
|
|
269
|
+
...input.notes && { notes: input.notes }
|
|
270
|
+
};
|
|
271
|
+
},
|
|
272
|
+
decode() {
|
|
273
|
+
return {
|
|
274
|
+
task: input.task,
|
|
275
|
+
steps: input.steps,
|
|
276
|
+
...input.triggers?.length && { triggers: input.triggers },
|
|
277
|
+
...input.notes && { notes: input.notes }
|
|
278
|
+
};
|
|
279
|
+
}
|
|
303
280
|
}
|
|
304
281
|
};
|
|
305
282
|
}
|
|
@@ -309,6 +286,21 @@ function quirk(input) {
|
|
|
309
286
|
data: {
|
|
310
287
|
issue: input.issue,
|
|
311
288
|
workaround: input.workaround
|
|
289
|
+
},
|
|
290
|
+
codec: {
|
|
291
|
+
encode() {
|
|
292
|
+
return {
|
|
293
|
+
type: "quirk",
|
|
294
|
+
issue: input.issue,
|
|
295
|
+
workaround: input.workaround
|
|
296
|
+
};
|
|
297
|
+
},
|
|
298
|
+
decode() {
|
|
299
|
+
return {
|
|
300
|
+
issue: input.issue,
|
|
301
|
+
workaround: input.workaround
|
|
302
|
+
};
|
|
303
|
+
}
|
|
312
304
|
}
|
|
313
305
|
};
|
|
314
306
|
}
|
|
@@ -319,6 +311,23 @@ function styleGuide(input) {
|
|
|
319
311
|
prefer: input.prefer,
|
|
320
312
|
...input.never && { never: input.never },
|
|
321
313
|
...input.always && { always: input.always }
|
|
314
|
+
},
|
|
315
|
+
codec: {
|
|
316
|
+
encode() {
|
|
317
|
+
return {
|
|
318
|
+
type: "styleGuide",
|
|
319
|
+
prefer: input.prefer,
|
|
320
|
+
...input.never && { never: input.never },
|
|
321
|
+
...input.always && { always: input.always }
|
|
322
|
+
};
|
|
323
|
+
},
|
|
324
|
+
decode() {
|
|
325
|
+
return {
|
|
326
|
+
prefer: input.prefer,
|
|
327
|
+
...input.never && { never: input.never },
|
|
328
|
+
...input.always && { always: input.always }
|
|
329
|
+
};
|
|
330
|
+
}
|
|
322
331
|
}
|
|
323
332
|
};
|
|
324
333
|
}
|
|
@@ -331,43 +340,562 @@ function analogy(input) {
|
|
|
331
340
|
...input.insight && { insight: input.insight },
|
|
332
341
|
...input.therefore && { therefore: input.therefore },
|
|
333
342
|
...input.pitfall && { pitfall: input.pitfall }
|
|
343
|
+
},
|
|
344
|
+
codec: {
|
|
345
|
+
encode() {
|
|
346
|
+
return {
|
|
347
|
+
type: "analogy",
|
|
348
|
+
concepts: input.concepts,
|
|
349
|
+
relationship: input.relationship,
|
|
350
|
+
...input.insight && { insight: input.insight },
|
|
351
|
+
...input.therefore && { therefore: input.therefore },
|
|
352
|
+
...input.pitfall && { pitfall: input.pitfall }
|
|
353
|
+
};
|
|
354
|
+
},
|
|
355
|
+
decode() {
|
|
356
|
+
return {
|
|
357
|
+
concepts: input.concepts,
|
|
358
|
+
relationship: input.relationship,
|
|
359
|
+
...input.insight && { insight: input.insight },
|
|
360
|
+
...input.therefore && { therefore: input.therefore },
|
|
361
|
+
...input.pitfall && { pitfall: input.pitfall }
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
function glossary(entries) {
|
|
368
|
+
return {
|
|
369
|
+
name: "glossary",
|
|
370
|
+
data: Object.entries(entries).map(([term2, expression]) => ({
|
|
371
|
+
term: term2,
|
|
372
|
+
expression
|
|
373
|
+
})),
|
|
374
|
+
codec: {
|
|
375
|
+
encode() {
|
|
376
|
+
return { type: "glossary", entries };
|
|
377
|
+
},
|
|
378
|
+
decode() {
|
|
379
|
+
return Object.entries(entries).map(([term2, expression]) => ({
|
|
380
|
+
term: term2,
|
|
381
|
+
expression
|
|
382
|
+
}));
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
function role(content) {
|
|
388
|
+
return {
|
|
389
|
+
name: "role",
|
|
390
|
+
data: content,
|
|
391
|
+
codec: {
|
|
392
|
+
encode() {
|
|
393
|
+
return { type: "role", content };
|
|
394
|
+
},
|
|
395
|
+
decode() {
|
|
396
|
+
return content;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
function principle(input) {
|
|
402
|
+
return {
|
|
403
|
+
name: "principle",
|
|
404
|
+
data: {
|
|
405
|
+
title: input.title,
|
|
406
|
+
description: input.description,
|
|
407
|
+
...input.policies?.length && { policies: input.policies }
|
|
408
|
+
},
|
|
409
|
+
codec: {
|
|
410
|
+
encode() {
|
|
411
|
+
return {
|
|
412
|
+
type: "principle",
|
|
413
|
+
title: input.title,
|
|
414
|
+
description: input.description,
|
|
415
|
+
...input.policies?.length && {
|
|
416
|
+
policies: input.policies.map((item) => encodeSerializedValue(item))
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
},
|
|
420
|
+
decode() {
|
|
421
|
+
return {
|
|
422
|
+
title: input.title,
|
|
423
|
+
description: input.description,
|
|
424
|
+
...input.policies?.length && { policies: input.policies }
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
function policy(input) {
|
|
431
|
+
return {
|
|
432
|
+
name: "policy",
|
|
433
|
+
data: {
|
|
434
|
+
rule: input.rule,
|
|
435
|
+
...input.before && { before: input.before },
|
|
436
|
+
...input.reason && { reason: input.reason },
|
|
437
|
+
...input.policies?.length && { policies: input.policies }
|
|
438
|
+
},
|
|
439
|
+
codec: {
|
|
440
|
+
encode() {
|
|
441
|
+
return {
|
|
442
|
+
type: "policy",
|
|
443
|
+
rule: input.rule,
|
|
444
|
+
...input.before && { before: input.before },
|
|
445
|
+
...input.reason && { reason: input.reason },
|
|
446
|
+
...input.policies?.length && {
|
|
447
|
+
policies: input.policies.map((item) => encodeSerializedValue(item))
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
},
|
|
451
|
+
decode() {
|
|
452
|
+
return {
|
|
453
|
+
rule: input.rule,
|
|
454
|
+
...input.before && { before: input.before },
|
|
455
|
+
...input.reason && { reason: input.reason },
|
|
456
|
+
...input.policies?.length && { policies: input.policies }
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// packages/context/src/lib/fragments/user.ts
|
|
464
|
+
function identity(input) {
|
|
465
|
+
return {
|
|
466
|
+
name: "identity",
|
|
467
|
+
data: {
|
|
468
|
+
...input.name && { name: input.name },
|
|
469
|
+
...input.role && { role: input.role }
|
|
470
|
+
},
|
|
471
|
+
codec: {
|
|
472
|
+
encode() {
|
|
473
|
+
return {
|
|
474
|
+
type: "identity",
|
|
475
|
+
...input.name && { name: input.name },
|
|
476
|
+
...input.role && { role: input.role }
|
|
477
|
+
};
|
|
478
|
+
},
|
|
479
|
+
decode() {
|
|
480
|
+
return {
|
|
481
|
+
...input.name && { name: input.name },
|
|
482
|
+
...input.role && { role: input.role }
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
function persona(input) {
|
|
489
|
+
return {
|
|
490
|
+
name: "persona",
|
|
491
|
+
data: {
|
|
492
|
+
name: input.name,
|
|
493
|
+
...input.role && { role: input.role },
|
|
494
|
+
...input.objective && { objective: input.objective },
|
|
495
|
+
...input.tone && { tone: input.tone }
|
|
496
|
+
},
|
|
497
|
+
codec: {
|
|
498
|
+
encode() {
|
|
499
|
+
return {
|
|
500
|
+
type: "persona",
|
|
501
|
+
name: input.name,
|
|
502
|
+
...input.role && { role: input.role },
|
|
503
|
+
...input.objective && { objective: input.objective },
|
|
504
|
+
...input.tone && { tone: input.tone }
|
|
505
|
+
};
|
|
506
|
+
},
|
|
507
|
+
decode() {
|
|
508
|
+
return {
|
|
509
|
+
name: input.name,
|
|
510
|
+
...input.role && { role: input.role },
|
|
511
|
+
...input.objective && { objective: input.objective },
|
|
512
|
+
...input.tone && { tone: input.tone }
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
function alias(term2, meaning) {
|
|
519
|
+
return {
|
|
520
|
+
name: "alias",
|
|
521
|
+
data: { term: term2, meaning },
|
|
522
|
+
codec: {
|
|
523
|
+
encode() {
|
|
524
|
+
return { type: "alias", term: term2, meaning };
|
|
525
|
+
},
|
|
526
|
+
decode() {
|
|
527
|
+
return { term: term2, meaning };
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
function preference(aspect, value) {
|
|
533
|
+
return {
|
|
534
|
+
name: "preference",
|
|
535
|
+
data: { aspect, value },
|
|
536
|
+
codec: {
|
|
537
|
+
encode() {
|
|
538
|
+
return { type: "preference", aspect, value };
|
|
539
|
+
},
|
|
540
|
+
decode() {
|
|
541
|
+
return { aspect, value };
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
function correction(subject, clarification2) {
|
|
547
|
+
return {
|
|
548
|
+
name: "correction",
|
|
549
|
+
data: { subject, clarification: clarification2 },
|
|
550
|
+
codec: {
|
|
551
|
+
encode() {
|
|
552
|
+
return { type: "correction", subject, clarification: clarification2 };
|
|
553
|
+
},
|
|
554
|
+
decode() {
|
|
555
|
+
return { subject, clarification: clarification2 };
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// packages/context/src/lib/codec/serialized-fragments.ts
|
|
562
|
+
function isSerializedFragmentLike(value) {
|
|
563
|
+
return typeof value === "object" && value !== null && "type" in value && typeof value.type === "string";
|
|
564
|
+
}
|
|
565
|
+
function toFragmentData(value, options) {
|
|
566
|
+
if (isSerializedFragmentLike(value)) {
|
|
567
|
+
return toFragment(value, options);
|
|
568
|
+
}
|
|
569
|
+
if (Array.isArray(value)) {
|
|
570
|
+
return value.map((item) => toFragmentData(item, options));
|
|
571
|
+
}
|
|
572
|
+
if (isFragmentObject(value)) {
|
|
573
|
+
return Object.fromEntries(
|
|
574
|
+
Object.entries(value).map(([key, entry]) => [
|
|
575
|
+
key,
|
|
576
|
+
toFragmentData(entry, options)
|
|
577
|
+
])
|
|
578
|
+
);
|
|
579
|
+
}
|
|
580
|
+
return value;
|
|
581
|
+
}
|
|
582
|
+
var builtInSerializedRegistry = {
|
|
583
|
+
term: {
|
|
584
|
+
toFragment: (input) => term(input.name, input.definition)
|
|
585
|
+
},
|
|
586
|
+
hint: {
|
|
587
|
+
toFragment: (input) => hint(input.text)
|
|
588
|
+
},
|
|
589
|
+
guardrail: {
|
|
590
|
+
toFragment: (input) => guardrail({
|
|
591
|
+
rule: input.rule,
|
|
592
|
+
reason: input.reason,
|
|
593
|
+
action: input.action
|
|
594
|
+
})
|
|
595
|
+
},
|
|
596
|
+
explain: {
|
|
597
|
+
toFragment: (input) => explain({
|
|
598
|
+
concept: input.concept,
|
|
599
|
+
explanation: input.explanation,
|
|
600
|
+
therefore: input.therefore
|
|
601
|
+
})
|
|
602
|
+
},
|
|
603
|
+
example: {
|
|
604
|
+
toFragment: (input) => example({
|
|
605
|
+
question: input.question,
|
|
606
|
+
answer: input.answer,
|
|
607
|
+
note: input.note
|
|
608
|
+
})
|
|
609
|
+
},
|
|
610
|
+
clarification: {
|
|
611
|
+
toFragment: (input) => clarification({
|
|
612
|
+
when: input.when,
|
|
613
|
+
ask: input.ask,
|
|
614
|
+
reason: input.reason
|
|
615
|
+
})
|
|
616
|
+
},
|
|
617
|
+
workflow: {
|
|
618
|
+
toFragment: (input) => workflow({
|
|
619
|
+
task: input.task,
|
|
620
|
+
steps: input.steps,
|
|
621
|
+
triggers: input.triggers,
|
|
622
|
+
notes: input.notes
|
|
623
|
+
})
|
|
624
|
+
},
|
|
625
|
+
quirk: {
|
|
626
|
+
toFragment: (input) => quirk({
|
|
627
|
+
issue: input.issue,
|
|
628
|
+
workaround: input.workaround
|
|
629
|
+
})
|
|
630
|
+
},
|
|
631
|
+
styleGuide: {
|
|
632
|
+
toFragment: (input) => styleGuide({
|
|
633
|
+
prefer: input.prefer,
|
|
634
|
+
never: input.never,
|
|
635
|
+
always: input.always
|
|
636
|
+
})
|
|
637
|
+
},
|
|
638
|
+
analogy: {
|
|
639
|
+
toFragment: (input) => analogy({
|
|
640
|
+
concepts: input.concepts,
|
|
641
|
+
relationship: input.relationship,
|
|
642
|
+
insight: input.insight,
|
|
643
|
+
therefore: input.therefore,
|
|
644
|
+
pitfall: input.pitfall
|
|
645
|
+
})
|
|
646
|
+
},
|
|
647
|
+
glossary: {
|
|
648
|
+
toFragment: (input) => glossary(input.entries)
|
|
649
|
+
},
|
|
650
|
+
role: {
|
|
651
|
+
toFragment: (input) => role(input.content)
|
|
652
|
+
},
|
|
653
|
+
principle: {
|
|
654
|
+
toFragment: (input, options) => principle({
|
|
655
|
+
title: input.title,
|
|
656
|
+
description: input.description,
|
|
657
|
+
policies: input.policies?.map((item) => toFragmentData(item, options))
|
|
658
|
+
})
|
|
659
|
+
},
|
|
660
|
+
policy: {
|
|
661
|
+
toFragment: (input, options) => policy({
|
|
662
|
+
rule: input.rule,
|
|
663
|
+
before: input.before,
|
|
664
|
+
reason: input.reason,
|
|
665
|
+
policies: input.policies?.map((item) => toFragmentData(item, options))
|
|
666
|
+
})
|
|
667
|
+
},
|
|
668
|
+
identity: {
|
|
669
|
+
toFragment: (input) => identity({
|
|
670
|
+
name: input.name,
|
|
671
|
+
role: input.role
|
|
672
|
+
})
|
|
673
|
+
},
|
|
674
|
+
persona: {
|
|
675
|
+
toFragment: (input) => persona({
|
|
676
|
+
name: input.name,
|
|
677
|
+
role: input.role,
|
|
678
|
+
objective: input.objective,
|
|
679
|
+
tone: input.tone
|
|
680
|
+
})
|
|
681
|
+
},
|
|
682
|
+
alias: {
|
|
683
|
+
toFragment: (input) => alias(input.term, input.meaning)
|
|
684
|
+
},
|
|
685
|
+
preference: {
|
|
686
|
+
toFragment: (input) => preference(input.aspect, input.value)
|
|
687
|
+
},
|
|
688
|
+
correction: {
|
|
689
|
+
toFragment: (input) => correction(input.subject, input.clarification)
|
|
690
|
+
}
|
|
691
|
+
};
|
|
692
|
+
var messageLikeTypes = /* @__PURE__ */ new Set(["user", "assistant", "message"]);
|
|
693
|
+
function findCustomSerializedFragment(fragment2, options) {
|
|
694
|
+
if (!options?.registry) {
|
|
695
|
+
return void 0;
|
|
696
|
+
}
|
|
697
|
+
for (const entry of Object.values(options.registry)) {
|
|
698
|
+
const serialized = entry.fromFragment?.(fragment2, options);
|
|
699
|
+
if (serialized !== void 0) {
|
|
700
|
+
return serialized;
|
|
334
701
|
}
|
|
335
|
-
}
|
|
702
|
+
}
|
|
703
|
+
return void 0;
|
|
336
704
|
}
|
|
337
|
-
function
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
705
|
+
function toFragment(input, options) {
|
|
706
|
+
if (messageLikeTypes.has(input.type)) {
|
|
707
|
+
throw new Error(
|
|
708
|
+
"Message fragments are not supported by serialized fragment conversion"
|
|
709
|
+
);
|
|
710
|
+
}
|
|
711
|
+
const entry = options?.registry?.[input.type] ?? builtInSerializedRegistry[input.type];
|
|
712
|
+
if (!entry) {
|
|
713
|
+
throw new Error(`Unsupported serialized fragment type: ${input.type}`);
|
|
714
|
+
}
|
|
715
|
+
return entry.toFragment(input, options);
|
|
345
716
|
}
|
|
346
|
-
function
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
717
|
+
function fromFragment(fragment2, options) {
|
|
718
|
+
if (isMessageFragment(fragment2)) {
|
|
719
|
+
throw new Error(
|
|
720
|
+
"Message fragments are not supported by serialized fragment conversion"
|
|
721
|
+
);
|
|
722
|
+
}
|
|
723
|
+
const customSerialized = findCustomSerializedFragment(fragment2, options);
|
|
724
|
+
if (customSerialized !== void 0) {
|
|
725
|
+
return customSerialized;
|
|
726
|
+
}
|
|
727
|
+
if (fragment2.codec) {
|
|
728
|
+
const encoded = fragment2.codec.encode();
|
|
729
|
+
if (!isSerializedFragmentLike(encoded)) {
|
|
730
|
+
throw new Error(
|
|
731
|
+
`Fragment "${fragment2.name}" codec must encode to a serialized fragment object`
|
|
732
|
+
);
|
|
733
|
+
}
|
|
734
|
+
return encoded;
|
|
735
|
+
}
|
|
736
|
+
if (!builtInSerializedRegistry[fragment2.name]) {
|
|
737
|
+
throw new Error(`Unsupported fragment name: ${fragment2.name}`);
|
|
738
|
+
}
|
|
739
|
+
throw new Error(`Fragment "${fragment2.name}" is missing codec`);
|
|
351
740
|
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
741
|
+
|
|
742
|
+
// packages/context/src/lib/estimate.ts
|
|
743
|
+
import { encode } from "gpt-tokenizer";
|
|
744
|
+
var defaultTokenizer = {
|
|
745
|
+
encode(text) {
|
|
746
|
+
return encode(text);
|
|
747
|
+
},
|
|
748
|
+
count(text) {
|
|
749
|
+
return encode(text).length;
|
|
750
|
+
}
|
|
751
|
+
};
|
|
752
|
+
var ModelsRegistry = class {
|
|
753
|
+
#cache = /* @__PURE__ */ new Map();
|
|
754
|
+
#loaded = false;
|
|
755
|
+
#tokenizers = /* @__PURE__ */ new Map();
|
|
756
|
+
#defaultTokenizer = defaultTokenizer;
|
|
757
|
+
/**
|
|
758
|
+
* Load models data from models.dev API
|
|
759
|
+
*/
|
|
760
|
+
async load() {
|
|
761
|
+
if (this.#loaded) return;
|
|
762
|
+
const response = await fetch("https://models.dev/api.json");
|
|
763
|
+
if (!response.ok) {
|
|
764
|
+
throw new Error(`Failed to fetch models: ${response.statusText}`);
|
|
359
765
|
}
|
|
360
|
-
|
|
766
|
+
const data = await response.json();
|
|
767
|
+
for (const [providerId, provider] of Object.entries(data)) {
|
|
768
|
+
for (const [modelId, model] of Object.entries(provider.models)) {
|
|
769
|
+
const info = {
|
|
770
|
+
id: model.id,
|
|
771
|
+
name: model.name,
|
|
772
|
+
family: model.family,
|
|
773
|
+
cost: model.cost,
|
|
774
|
+
limit: model.limit,
|
|
775
|
+
provider: providerId
|
|
776
|
+
};
|
|
777
|
+
this.#cache.set(`${providerId}:${modelId}`, info);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
this.#loaded = true;
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* Get model info by ID
|
|
784
|
+
* @param modelId - Model ID (e.g., "openai:gpt-4o")
|
|
785
|
+
*/
|
|
786
|
+
get(modelId) {
|
|
787
|
+
return this.#cache.get(modelId);
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* Check if a model exists in the registry
|
|
791
|
+
*/
|
|
792
|
+
has(modelId) {
|
|
793
|
+
return this.#cache.has(modelId);
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* List all available model IDs
|
|
797
|
+
*/
|
|
798
|
+
list() {
|
|
799
|
+
return [...this.#cache.keys()];
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Register a custom tokenizer for specific model families
|
|
803
|
+
* @param family - Model family name (e.g., "llama", "claude")
|
|
804
|
+
* @param tokenizer - Tokenizer implementation
|
|
805
|
+
*/
|
|
806
|
+
registerTokenizer(family, tokenizer) {
|
|
807
|
+
this.#tokenizers.set(family, tokenizer);
|
|
808
|
+
}
|
|
809
|
+
/**
|
|
810
|
+
* Set the default tokenizer used when no family-specific tokenizer is registered
|
|
811
|
+
*/
|
|
812
|
+
setDefaultTokenizer(tokenizer) {
|
|
813
|
+
this.#defaultTokenizer = tokenizer;
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
816
|
+
* Get the appropriate tokenizer for a model
|
|
817
|
+
*/
|
|
818
|
+
getTokenizer(modelId) {
|
|
819
|
+
const model = this.get(modelId);
|
|
820
|
+
if (model) {
|
|
821
|
+
const familyTokenizer = this.#tokenizers.get(model.family);
|
|
822
|
+
if (familyTokenizer) {
|
|
823
|
+
return familyTokenizer;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
return this.#defaultTokenizer;
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* Estimate token count and cost for given text and model
|
|
830
|
+
* @param modelId - Model ID to use for pricing (e.g., "openai:gpt-4o")
|
|
831
|
+
* @param input - Input text (prompt)
|
|
832
|
+
*/
|
|
833
|
+
estimate(modelId, input) {
|
|
834
|
+
const model = this.get(modelId);
|
|
835
|
+
if (!model) {
|
|
836
|
+
throw new Error(
|
|
837
|
+
`Model "${modelId}" not found. Call load() first or check model ID.`
|
|
838
|
+
);
|
|
839
|
+
}
|
|
840
|
+
const tokenizer = this.getTokenizer(modelId);
|
|
841
|
+
const tokens = tokenizer.count(input);
|
|
842
|
+
const cost = tokens / 1e6 * model.cost.input;
|
|
843
|
+
return {
|
|
844
|
+
model: model.id,
|
|
845
|
+
provider: model.provider,
|
|
846
|
+
tokens,
|
|
847
|
+
cost,
|
|
848
|
+
limits: {
|
|
849
|
+
context: model.limit.context,
|
|
850
|
+
output: model.limit.output,
|
|
851
|
+
exceedsContext: tokens > model.limit.context
|
|
852
|
+
},
|
|
853
|
+
fragments: []
|
|
854
|
+
};
|
|
855
|
+
}
|
|
856
|
+
};
|
|
857
|
+
var _registry = null;
|
|
858
|
+
function getModelsRegistry() {
|
|
859
|
+
if (!_registry) {
|
|
860
|
+
_registry = new ModelsRegistry();
|
|
861
|
+
}
|
|
862
|
+
return _registry;
|
|
361
863
|
}
|
|
362
|
-
function
|
|
864
|
+
async function estimate(modelId, renderer, ...fragments) {
|
|
865
|
+
const registry = getModelsRegistry();
|
|
866
|
+
await registry.load();
|
|
867
|
+
const input = renderer.render(fragments);
|
|
868
|
+
const model = registry.get(modelId);
|
|
869
|
+
if (!model) {
|
|
870
|
+
throw new Error(
|
|
871
|
+
`Model "${modelId}" not found. Call load() first or check model ID.`
|
|
872
|
+
);
|
|
873
|
+
}
|
|
874
|
+
const tokenizer = registry.getTokenizer(modelId);
|
|
875
|
+
const totalTokens = tokenizer.count(input);
|
|
876
|
+
const totalCost = totalTokens / 1e6 * model.cost.input;
|
|
877
|
+
const fragmentEstimates = fragments.map((fragment2) => {
|
|
878
|
+
const rendered = renderer.render([fragment2]);
|
|
879
|
+
const tokens = tokenizer.count(rendered);
|
|
880
|
+
const cost = tokens / 1e6 * model.cost.input;
|
|
881
|
+
return {
|
|
882
|
+
id: fragment2.id,
|
|
883
|
+
name: fragment2.name,
|
|
884
|
+
tokens,
|
|
885
|
+
cost
|
|
886
|
+
};
|
|
887
|
+
});
|
|
363
888
|
return {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
889
|
+
model: model.id,
|
|
890
|
+
provider: model.provider,
|
|
891
|
+
tokens: totalTokens,
|
|
892
|
+
cost: totalCost,
|
|
893
|
+
limits: {
|
|
894
|
+
context: model.limit.context,
|
|
895
|
+
output: model.limit.output,
|
|
896
|
+
exceedsContext: totalTokens > model.limit.context
|
|
897
|
+
},
|
|
898
|
+
fragments: fragmentEstimates
|
|
371
899
|
};
|
|
372
900
|
}
|
|
373
901
|
|
|
@@ -507,26 +1035,51 @@ function applyPartReminder(message2, value) {
|
|
|
507
1035
|
mode: "part"
|
|
508
1036
|
};
|
|
509
1037
|
}
|
|
1038
|
+
function hasSchedule(reminder2) {
|
|
1039
|
+
return reminder2.everyNTurns !== void 0 || reminder2.once !== void 0 || reminder2.firstN !== void 0 || reminder2.afterTurn !== void 0 || reminder2.when !== void 0;
|
|
1040
|
+
}
|
|
1041
|
+
function shouldIncludeReminder(reminder2, turn) {
|
|
1042
|
+
if (reminder2.once && turn !== 1) return false;
|
|
1043
|
+
if (reminder2.firstN !== void 0 && turn > reminder2.firstN) return false;
|
|
1044
|
+
if (reminder2.afterTurn !== void 0 && turn <= reminder2.afterTurn)
|
|
1045
|
+
return false;
|
|
1046
|
+
if (reminder2.everyNTurns !== void 0 && turn % reminder2.everyNTurns !== 0)
|
|
1047
|
+
return false;
|
|
1048
|
+
if (reminder2.when && !reminder2.when(turn)) return false;
|
|
1049
|
+
return true;
|
|
1050
|
+
}
|
|
510
1051
|
function reminder(text, options) {
|
|
511
1052
|
if (typeof text === "string") {
|
|
512
1053
|
assertReminderText(text);
|
|
513
1054
|
}
|
|
514
1055
|
return {
|
|
515
1056
|
text,
|
|
516
|
-
asPart: options?.asPart ?? false
|
|
1057
|
+
asPart: options?.asPart ?? false,
|
|
1058
|
+
...options?.everyNTurns !== void 0 && {
|
|
1059
|
+
everyNTurns: options.everyNTurns
|
|
1060
|
+
},
|
|
1061
|
+
...options?.once !== void 0 && { once: options.once },
|
|
1062
|
+
...options?.firstN !== void 0 && { firstN: options.firstN },
|
|
1063
|
+
...options?.afterTurn !== void 0 && { afterTurn: options.afterTurn },
|
|
1064
|
+
...options?.when !== void 0 && { when: options.when }
|
|
517
1065
|
};
|
|
518
1066
|
}
|
|
1067
|
+
function resolveReminderText(item, ctx) {
|
|
1068
|
+
return typeof item.text === "function" ? item.text(ctx) : item.text;
|
|
1069
|
+
}
|
|
519
1070
|
function user(content, ...reminders) {
|
|
520
1071
|
const message2 = typeof content === "string" ? {
|
|
521
1072
|
id: generateId2(),
|
|
522
1073
|
role: "user",
|
|
523
1074
|
parts: [{ type: "text", text: content }]
|
|
524
1075
|
} : { ...content, role: "user", parts: [...content.parts] };
|
|
525
|
-
|
|
1076
|
+
const immediateReminders = reminders.filter((r) => !hasSchedule(r));
|
|
1077
|
+
const scheduledReminders = reminders.filter((r) => hasSchedule(r));
|
|
1078
|
+
if (immediateReminders.length > 0) {
|
|
526
1079
|
const addedReminders = [];
|
|
527
1080
|
const plainText = extractPlainText(message2);
|
|
528
|
-
for (const item of
|
|
529
|
-
const resolvedText =
|
|
1081
|
+
for (const item of immediateReminders) {
|
|
1082
|
+
const resolvedText = resolveReminderText(item, { content: plainText });
|
|
530
1083
|
if (resolvedText.trim().length === 0) {
|
|
531
1084
|
continue;
|
|
532
1085
|
}
|
|
@@ -541,10 +1094,10 @@ function user(content, ...reminders) {
|
|
|
541
1094
|
message2.metadata = metadata;
|
|
542
1095
|
}
|
|
543
1096
|
}
|
|
1097
|
+
const fragmentMetadata = scheduledReminders.length > 0 ? { scheduledReminders } : void 0;
|
|
544
1098
|
return {
|
|
545
1099
|
id: message2.id,
|
|
546
1100
|
name: "user",
|
|
547
|
-
data: "content",
|
|
548
1101
|
type: "message",
|
|
549
1102
|
persist: true,
|
|
550
1103
|
codec: {
|
|
@@ -554,53 +1107,8 @@ function user(content, ...reminders) {
|
|
|
554
1107
|
encode() {
|
|
555
1108
|
return message2;
|
|
556
1109
|
}
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
// packages/context/src/lib/fragments/user.ts
|
|
562
|
-
function identity(input) {
|
|
563
|
-
return {
|
|
564
|
-
name: "identity",
|
|
565
|
-
data: {
|
|
566
|
-
...input.name && { name: input.name },
|
|
567
|
-
...input.role && { role: input.role }
|
|
568
|
-
}
|
|
569
|
-
};
|
|
570
|
-
}
|
|
571
|
-
function persona(input) {
|
|
572
|
-
return {
|
|
573
|
-
name: "persona",
|
|
574
|
-
data: {
|
|
575
|
-
name: input.name,
|
|
576
|
-
...input.role && { role: input.role },
|
|
577
|
-
...input.objective && { objective: input.objective },
|
|
578
|
-
...input.tone && { tone: input.tone }
|
|
579
|
-
}
|
|
580
|
-
};
|
|
581
|
-
}
|
|
582
|
-
function alias(term2, meaning) {
|
|
583
|
-
return {
|
|
584
|
-
name: "alias",
|
|
585
|
-
data: { term: term2, meaning }
|
|
586
|
-
};
|
|
587
|
-
}
|
|
588
|
-
function preference(aspect, value) {
|
|
589
|
-
return {
|
|
590
|
-
name: "preference",
|
|
591
|
-
data: { aspect, value }
|
|
592
|
-
};
|
|
593
|
-
}
|
|
594
|
-
function userContext(description) {
|
|
595
|
-
return {
|
|
596
|
-
name: "userContext",
|
|
597
|
-
data: description
|
|
598
|
-
};
|
|
599
|
-
}
|
|
600
|
-
function correction(subject, clarification2) {
|
|
601
|
-
return {
|
|
602
|
-
name: "correction",
|
|
603
|
-
data: { subject, clarification: clarification2 }
|
|
1110
|
+
},
|
|
1111
|
+
metadata: fragmentMetadata
|
|
604
1112
|
};
|
|
605
1113
|
}
|
|
606
1114
|
|
|
@@ -668,7 +1176,7 @@ var ContextRenderer = class {
|
|
|
668
1176
|
return sanitized;
|
|
669
1177
|
}
|
|
670
1178
|
sanitizeFragment(fragment2, seen) {
|
|
671
|
-
const data = this.sanitizeData(fragment2
|
|
1179
|
+
const data = this.sanitizeData(getFragmentData(fragment2), seen);
|
|
672
1180
|
if (data == null) {
|
|
673
1181
|
return null;
|
|
674
1182
|
}
|
|
@@ -745,12 +1253,13 @@ var XmlRenderer = class extends ContextRenderer {
|
|
|
745
1253
|
return sanitized.map((f) => this.#renderTopLevel(f)).filter(Boolean).join("\n");
|
|
746
1254
|
}
|
|
747
1255
|
#renderTopLevel(fragment2) {
|
|
748
|
-
|
|
749
|
-
|
|
1256
|
+
const data = getFragmentData(fragment2);
|
|
1257
|
+
if (this.isPrimitive(data)) {
|
|
1258
|
+
return this.#leafRoot(fragment2.name, String(data));
|
|
750
1259
|
}
|
|
751
|
-
if (Array.isArray(
|
|
752
|
-
if (
|
|
753
|
-
const single =
|
|
1260
|
+
if (Array.isArray(data)) {
|
|
1261
|
+
if (data.length === 1) {
|
|
1262
|
+
const single = data[0];
|
|
754
1263
|
if (this.isPrimitive(single)) {
|
|
755
1264
|
return this.#leafRoot(fragment2.name, String(single));
|
|
756
1265
|
}
|
|
@@ -768,19 +1277,15 @@ var XmlRenderer = class extends ContextRenderer {
|
|
|
768
1277
|
);
|
|
769
1278
|
}
|
|
770
1279
|
}
|
|
771
|
-
return this.#renderArray(fragment2.name,
|
|
1280
|
+
return this.#renderArray(fragment2.name, data, 0);
|
|
772
1281
|
}
|
|
773
|
-
if (isFragment(
|
|
774
|
-
return this.#renderFragmentContentsUnderParent(
|
|
775
|
-
fragment2.name,
|
|
776
|
-
fragment2.data,
|
|
777
|
-
0
|
|
778
|
-
);
|
|
1282
|
+
if (isFragment(data)) {
|
|
1283
|
+
return this.#renderFragmentContentsUnderParent(fragment2.name, data, 0);
|
|
779
1284
|
}
|
|
780
|
-
if (isFragmentObject(
|
|
1285
|
+
if (isFragmentObject(data)) {
|
|
781
1286
|
return this.#wrap(
|
|
782
1287
|
fragment2.name,
|
|
783
|
-
this.renderEntries(
|
|
1288
|
+
this.renderEntries(data, { depth: 1, path: [] })
|
|
784
1289
|
);
|
|
785
1290
|
}
|
|
786
1291
|
return "";
|
|
@@ -912,23 +1417,23 @@ ${this.#indent(safe, 2)}
|
|
|
912
1417
|
return `<${tag}>${safe}</${tag}>`;
|
|
913
1418
|
}
|
|
914
1419
|
renderFragment(fragment2, ctx) {
|
|
915
|
-
const
|
|
1420
|
+
const data = getFragmentData(fragment2);
|
|
916
1421
|
if (this.isPrimitive(data)) {
|
|
917
|
-
return this.#leaf(name, String(data), ctx.depth);
|
|
1422
|
+
return this.#leaf(fragment2.name, String(data), ctx.depth);
|
|
918
1423
|
}
|
|
919
1424
|
if (isFragment(data)) {
|
|
920
1425
|
const child = this.renderFragment(data, { ...ctx, depth: ctx.depth + 1 });
|
|
921
|
-
return this.#wrapIndented(name, [child], ctx.depth);
|
|
1426
|
+
return this.#wrapIndented(fragment2.name, [child], ctx.depth);
|
|
922
1427
|
}
|
|
923
1428
|
if (Array.isArray(data)) {
|
|
924
|
-
return this.#renderArrayIndented(name, data, ctx.depth);
|
|
1429
|
+
return this.#renderArrayIndented(fragment2.name, data, ctx.depth);
|
|
925
1430
|
}
|
|
926
1431
|
if (isFragmentObject(data)) {
|
|
927
1432
|
const children = this.renderEntries(data, {
|
|
928
1433
|
...ctx,
|
|
929
1434
|
depth: ctx.depth + 1
|
|
930
1435
|
});
|
|
931
|
-
return this.#wrapIndented(name, children, ctx.depth);
|
|
1436
|
+
return this.#wrapIndented(fragment2.name, children, ctx.depth);
|
|
932
1437
|
}
|
|
933
1438
|
return "";
|
|
934
1439
|
}
|
|
@@ -1045,21 +1550,22 @@ var MarkdownRenderer = class extends ContextRenderer {
|
|
|
1045
1550
|
render(fragments) {
|
|
1046
1551
|
return this.sanitizeFragments(fragments).map((f) => {
|
|
1047
1552
|
const title = `## ${titlecase(f.name)}`;
|
|
1048
|
-
|
|
1553
|
+
const data = getFragmentData(f);
|
|
1554
|
+
if (this.isPrimitive(data)) {
|
|
1049
1555
|
return `${title}
|
|
1050
|
-
${String(
|
|
1556
|
+
${String(data)}`;
|
|
1051
1557
|
}
|
|
1052
|
-
if (Array.isArray(
|
|
1558
|
+
if (Array.isArray(data)) {
|
|
1053
1559
|
return `${title}
|
|
1054
|
-
${this.#renderArray(
|
|
1560
|
+
${this.#renderArray(data, 0)}`;
|
|
1055
1561
|
}
|
|
1056
|
-
if (isFragment(
|
|
1562
|
+
if (isFragment(data)) {
|
|
1057
1563
|
return `${title}
|
|
1058
|
-
${this.renderFragment(
|
|
1564
|
+
${this.renderFragment(data, { depth: 0, path: [] })}`;
|
|
1059
1565
|
}
|
|
1060
|
-
if (isFragmentObject(
|
|
1566
|
+
if (isFragmentObject(data)) {
|
|
1061
1567
|
return `${title}
|
|
1062
|
-
${this.renderEntries(
|
|
1568
|
+
${this.renderEntries(data, { depth: 0, path: [] }).join("\n")}`;
|
|
1063
1569
|
}
|
|
1064
1570
|
return `${title}
|
|
1065
1571
|
`;
|
|
@@ -1109,10 +1615,10 @@ ${this.renderEntries(f.data, { depth: 0, path: [] }).join("\n")}`;
|
|
|
1109
1615
|
return `${this.#pad(depth)}- ${String(item)}`;
|
|
1110
1616
|
}
|
|
1111
1617
|
renderFragment(fragment2, ctx) {
|
|
1112
|
-
const
|
|
1113
|
-
const header = `${this.#pad(ctx.depth)}- **${name}**:`;
|
|
1618
|
+
const data = getFragmentData(fragment2);
|
|
1619
|
+
const header = `${this.#pad(ctx.depth)}- **${fragment2.name}**:`;
|
|
1114
1620
|
if (this.isPrimitive(data)) {
|
|
1115
|
-
return `${this.#pad(ctx.depth)}- **${name}**: ${String(data)}`;
|
|
1621
|
+
return `${this.#pad(ctx.depth)}- **${fragment2.name}**: ${String(data)}`;
|
|
1116
1622
|
}
|
|
1117
1623
|
if (isFragment(data)) {
|
|
1118
1624
|
const child = this.renderFragment(data, { ...ctx, depth: ctx.depth + 1 });
|
|
@@ -1151,21 +1657,22 @@ ${this.renderEntries(f.data, { depth: 0, path: [] }).join("\n")}`;
|
|
|
1151
1657
|
var TomlRenderer = class extends ContextRenderer {
|
|
1152
1658
|
render(fragments) {
|
|
1153
1659
|
const rendered = [];
|
|
1154
|
-
for (const
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1660
|
+
for (const it of this.sanitizeFragments(fragments)) {
|
|
1661
|
+
const data = getFragmentData(it);
|
|
1662
|
+
if (this.isPrimitive(data)) {
|
|
1663
|
+
rendered.push(`${it.name} = ${this.#formatValue(data)}`);
|
|
1664
|
+
} else if (Array.isArray(data)) {
|
|
1665
|
+
rendered.push(this.#renderTopLevelArray(it.name, data));
|
|
1666
|
+
} else if (isFragment(data)) {
|
|
1160
1667
|
rendered.push(
|
|
1161
1668
|
[
|
|
1162
|
-
`[${
|
|
1163
|
-
this.renderFragment(
|
|
1669
|
+
`[${it.name}]`,
|
|
1670
|
+
this.renderFragment(data, { depth: 0, path: [it.name] })
|
|
1164
1671
|
].join("\n")
|
|
1165
1672
|
);
|
|
1166
|
-
} else if (isFragmentObject(
|
|
1167
|
-
const entries = this.#renderObjectEntries(
|
|
1168
|
-
rendered.push([`[${
|
|
1673
|
+
} else if (isFragmentObject(data)) {
|
|
1674
|
+
const entries = this.#renderObjectEntries(data, [it.name]);
|
|
1675
|
+
rendered.push([`[${it.name}]`, ...entries].join("\n"));
|
|
1169
1676
|
}
|
|
1170
1677
|
}
|
|
1171
1678
|
return rendered.join("\n\n");
|
|
@@ -1235,10 +1742,10 @@ var TomlRenderer = class extends ContextRenderer {
|
|
|
1235
1742
|
}).filter(Boolean);
|
|
1236
1743
|
}
|
|
1237
1744
|
renderFragment(fragment2, ctx) {
|
|
1238
|
-
const
|
|
1239
|
-
const newPath = [...ctx.path, name];
|
|
1745
|
+
const data = getFragmentData(fragment2);
|
|
1746
|
+
const newPath = [...ctx.path, fragment2.name];
|
|
1240
1747
|
if (this.isPrimitive(data)) {
|
|
1241
|
-
return `${name} = ${this.#formatValue(data)}`;
|
|
1748
|
+
return `${fragment2.name} = ${this.#formatValue(data)}`;
|
|
1242
1749
|
}
|
|
1243
1750
|
if (isFragment(data)) {
|
|
1244
1751
|
return [
|
|
@@ -1260,7 +1767,7 @@ var TomlRenderer = class extends ContextRenderer {
|
|
|
1260
1767
|
return parts.join("\n");
|
|
1261
1768
|
}
|
|
1262
1769
|
const values = nonFragmentItems.map((item) => this.#formatValue(item));
|
|
1263
|
-
return `${name} = [${values.join(", ")}]`;
|
|
1770
|
+
return `${fragment2.name} = [${values.join(", ")}]`;
|
|
1264
1771
|
}
|
|
1265
1772
|
if (isFragmentObject(data)) {
|
|
1266
1773
|
const entries = this.#renderObjectEntries(data, newPath);
|
|
@@ -1290,27 +1797,27 @@ var ToonRenderer = class extends ContextRenderer {
|
|
|
1290
1797
|
return sanitized.map((f) => this.#renderTopLevel(f)).filter(Boolean).join("\n");
|
|
1291
1798
|
}
|
|
1292
1799
|
#renderTopLevel(fragment2) {
|
|
1293
|
-
const
|
|
1800
|
+
const data = getFragmentData(fragment2);
|
|
1294
1801
|
if (this.isPrimitive(data)) {
|
|
1295
|
-
return `${name}: ${this.#formatValue(data)}`;
|
|
1802
|
+
return `${fragment2.name}: ${this.#formatValue(data)}`;
|
|
1296
1803
|
}
|
|
1297
1804
|
if (Array.isArray(data)) {
|
|
1298
|
-
return this.#renderArrayField(name, data, 0);
|
|
1805
|
+
return this.#renderArrayField(fragment2.name, data, 0);
|
|
1299
1806
|
}
|
|
1300
1807
|
if (isFragment(data)) {
|
|
1301
1808
|
const child = this.renderFragment(data, { depth: 1, path: [] });
|
|
1302
|
-
return `${name}:
|
|
1809
|
+
return `${fragment2.name}:
|
|
1303
1810
|
${child}`;
|
|
1304
1811
|
}
|
|
1305
1812
|
if (isFragmentObject(data)) {
|
|
1306
1813
|
const entries = this.#renderObjectEntries(data, 1);
|
|
1307
1814
|
if (!entries) {
|
|
1308
|
-
return `${name}:`;
|
|
1815
|
+
return `${fragment2.name}:`;
|
|
1309
1816
|
}
|
|
1310
|
-
return `${name}:
|
|
1817
|
+
return `${fragment2.name}:
|
|
1311
1818
|
${entries}`;
|
|
1312
1819
|
}
|
|
1313
|
-
return `${name}:`;
|
|
1820
|
+
return `${fragment2.name}:`;
|
|
1314
1821
|
}
|
|
1315
1822
|
#renderArrayField(key, items, depth) {
|
|
1316
1823
|
const filtered = items.filter((item) => item != null);
|
|
@@ -1385,8 +1892,9 @@ ${entries}`;
|
|
|
1385
1892
|
depth: depth + 1,
|
|
1386
1893
|
path: []
|
|
1387
1894
|
});
|
|
1388
|
-
|
|
1389
|
-
|
|
1895
|
+
const itemData = getFragmentData(item);
|
|
1896
|
+
if (this.isPrimitive(itemData)) {
|
|
1897
|
+
return `${this.#pad(depth)}- ${item.name}: ${this.#formatValue(itemData)}`;
|
|
1390
1898
|
}
|
|
1391
1899
|
return `${this.#pad(depth)}- ${item.name}:
|
|
1392
1900
|
${rendered.split("\n").slice(1).join("\n")}`;
|
|
@@ -1429,30 +1937,30 @@ ${nested}`);
|
|
|
1429
1937
|
return lines.join("\n");
|
|
1430
1938
|
}
|
|
1431
1939
|
renderFragment(fragment2, ctx) {
|
|
1432
|
-
const
|
|
1940
|
+
const data = getFragmentData(fragment2);
|
|
1433
1941
|
if (this.isPrimitive(data)) {
|
|
1434
|
-
return `${this.#pad(ctx.depth)}${name}: ${this.#formatValue(data)}`;
|
|
1942
|
+
return `${this.#pad(ctx.depth)}${fragment2.name}: ${this.#formatValue(data)}`;
|
|
1435
1943
|
}
|
|
1436
1944
|
if (isFragment(data)) {
|
|
1437
1945
|
const child = this.renderFragment(data, {
|
|
1438
1946
|
...ctx,
|
|
1439
1947
|
depth: ctx.depth + 1
|
|
1440
1948
|
});
|
|
1441
|
-
return `${this.#pad(ctx.depth)}${name}:
|
|
1949
|
+
return `${this.#pad(ctx.depth)}${fragment2.name}:
|
|
1442
1950
|
${child}`;
|
|
1443
1951
|
}
|
|
1444
1952
|
if (Array.isArray(data)) {
|
|
1445
|
-
return this.#renderArrayField(name, data, ctx.depth);
|
|
1953
|
+
return this.#renderArrayField(fragment2.name, data, ctx.depth);
|
|
1446
1954
|
}
|
|
1447
1955
|
if (isFragmentObject(data)) {
|
|
1448
1956
|
const entries = this.#renderObjectEntries(data, ctx.depth + 1);
|
|
1449
1957
|
if (!entries) {
|
|
1450
|
-
return `${this.#pad(ctx.depth)}${name}:`;
|
|
1958
|
+
return `${this.#pad(ctx.depth)}${fragment2.name}:`;
|
|
1451
1959
|
}
|
|
1452
|
-
return `${this.#pad(ctx.depth)}${name}:
|
|
1960
|
+
return `${this.#pad(ctx.depth)}${fragment2.name}:
|
|
1453
1961
|
${entries}`;
|
|
1454
1962
|
}
|
|
1455
|
-
return `${this.#pad(ctx.depth)}${name}:`;
|
|
1963
|
+
return `${this.#pad(ctx.depth)}${fragment2.name}:`;
|
|
1456
1964
|
}
|
|
1457
1965
|
renderPrimitive(key, value, ctx) {
|
|
1458
1966
|
return `${this.#pad(ctx.depth)}${key}: ${this.#formatValue(value)}`;
|
|
@@ -1668,6 +2176,8 @@ export {
|
|
|
1668
2176
|
XmlRenderer,
|
|
1669
2177
|
alias,
|
|
1670
2178
|
analogy,
|
|
2179
|
+
applyInlineReminder,
|
|
2180
|
+
applyPartReminder,
|
|
1671
2181
|
assistant,
|
|
1672
2182
|
assistantText,
|
|
1673
2183
|
clarification,
|
|
@@ -1678,10 +2188,13 @@ export {
|
|
|
1678
2188
|
explain,
|
|
1679
2189
|
fail,
|
|
1680
2190
|
fragment,
|
|
2191
|
+
fromFragment,
|
|
2192
|
+
getFragmentData,
|
|
1681
2193
|
getModelsRegistry,
|
|
1682
2194
|
getReminderRanges,
|
|
1683
2195
|
glossary,
|
|
1684
2196
|
guardrail,
|
|
2197
|
+
hasSchedule,
|
|
1685
2198
|
hint,
|
|
1686
2199
|
identity,
|
|
1687
2200
|
isFragment,
|
|
@@ -1699,16 +2212,18 @@ export {
|
|
|
1699
2212
|
quirk,
|
|
1700
2213
|
reminder,
|
|
1701
2214
|
render,
|
|
2215
|
+
resolveReminderText,
|
|
1702
2216
|
role,
|
|
1703
2217
|
runGuardrailChain,
|
|
2218
|
+
shouldIncludeReminder,
|
|
1704
2219
|
soul,
|
|
1705
2220
|
stop,
|
|
1706
2221
|
stripReminders,
|
|
1707
2222
|
stripTextByRanges,
|
|
1708
2223
|
styleGuide,
|
|
1709
2224
|
term,
|
|
2225
|
+
toFragment,
|
|
1710
2226
|
user,
|
|
1711
|
-
userContext,
|
|
1712
2227
|
visualizeGraph,
|
|
1713
2228
|
workflow
|
|
1714
2229
|
};
|