@cubicecho/agent-core 2.2.4 → 2.4.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 +138 -3
- package/dist/capabilities.d.ts +7 -3
- package/dist/capabilities.js +22 -9
- package/dist/client.d.ts +28 -0
- package/dist/client.js +94 -9
- package/dist/events.d.ts +71 -1
- package/dist/events.js +70 -35
- package/dist/hooks.d.ts +271 -0
- package/dist/hooks.js +256 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.js +5 -4
- package/dist/reset.d.ts +6 -5
- package/dist/reset.js +8 -5
- package/dist/retry.d.ts +5 -0
- package/dist/retry.js +5 -0
- package/dist/run-turn.d.ts +5 -0
- package/dist/run-turn.js +14 -1
- package/dist/side-task.js +8 -8
- package/dist/stream.d.ts +19 -1
- package/dist/stream.js +11 -1
- package/dist/tool-loading.d.ts +30 -10
- package/dist/tool-loading.js +45 -18
- package/llms.txt +30 -2
- package/package.json +1 -1
package/dist/tool-loading.d.ts
CHANGED
|
@@ -52,6 +52,11 @@ export declare function catalogPrompt(catalog: CatalogServer[], loaded?: Readonl
|
|
|
52
52
|
* in the position on-demand loading exists to avoid — a tool array too large to choose from.
|
|
53
53
|
* Over-broad requests are refused with the matching names listed, so the next call can be
|
|
54
54
|
* precise.
|
|
55
|
+
*
|
|
56
|
+
* The default rather than the rule: twelve is what a small model chooses well from, and a caller
|
|
57
|
+
* running a large one against a large window can say otherwise to `expandNames`, `preselection`
|
|
58
|
+
* and `preselectSystem`. Whatever it says is carried on the resolution, so the refusal the model
|
|
59
|
+
* reads names the number it was actually held to.
|
|
55
60
|
*/
|
|
56
61
|
export declare const MAX_PER_LOAD = 12;
|
|
57
62
|
/**
|
|
@@ -59,7 +64,7 @@ export declare const MAX_PER_LOAD = 12;
|
|
|
59
64
|
* conversation runs; least-recently-used names fall off the front.
|
|
60
65
|
*
|
|
61
66
|
* Only a multi-turn caller needs this — a run that starts from nothing each time has nothing to
|
|
62
|
-
* carry. See `carryOver
|
|
67
|
+
* carry. See `carryOver`, which takes another number if this one is not yours.
|
|
63
68
|
*/
|
|
64
69
|
export declare const MAX_CARRIED = 16;
|
|
65
70
|
/**
|
|
@@ -67,8 +72,10 @@ export declare const MAX_CARRIED = 16;
|
|
|
67
72
|
*
|
|
68
73
|
* @param previous Last turn's names, oldest first.
|
|
69
74
|
* @param used What this turn called. Moved to the end, so the oldest unused fall off.
|
|
75
|
+
* @param max How many to carry, defaulting to `MAX_CARRIED`. At least one: a cap of zero is
|
|
76
|
+
* read as no cap, which is what `slice` does with it and not what anybody asking for zero meant.
|
|
70
77
|
*/
|
|
71
|
-
export declare const carryOver: (previous: string[], used: Set<string
|
|
78
|
+
export declare const carryOver: (previous: string[], used: Set<string>, max?: number) => string[];
|
|
72
79
|
/**
|
|
73
80
|
* Resolves requested names against the catalogue, expanding trailing `*` wildcards.
|
|
74
81
|
*
|
|
@@ -80,8 +87,10 @@ export declare const carryOver: (previous: string[], used: Set<string>) => strin
|
|
|
80
87
|
*
|
|
81
88
|
* @param requested What the model asked for. A trailing `*` expands.
|
|
82
89
|
* @param catalog The servers to resolve against.
|
|
90
|
+
* @param maxPerLoad The most this call may load, defaulting to `MAX_PER_LOAD`. It comes back on
|
|
91
|
+
* the resolution so `loadResult` reports the same number rather than a second opinion of it.
|
|
83
92
|
*/
|
|
84
|
-
export declare function expandNames(requested: string[], catalog: CatalogServer[]): {
|
|
93
|
+
export declare function expandNames(requested: string[], catalog: CatalogServer[], maxPerLoad?: number): {
|
|
85
94
|
matched: string[];
|
|
86
95
|
unknown: string[];
|
|
87
96
|
overBroad: {
|
|
@@ -89,6 +98,7 @@ export declare function expandNames(requested: string[], catalog: CatalogServer[
|
|
|
89
98
|
hits: string[];
|
|
90
99
|
}[];
|
|
91
100
|
deferred: string[];
|
|
101
|
+
maxPerLoad: number;
|
|
92
102
|
};
|
|
93
103
|
/**
|
|
94
104
|
* What `load_tools` reports back: the descriptions, now that they are worth their tokens.
|
|
@@ -96,7 +106,7 @@ export declare function expandNames(requested: string[], catalog: CatalogServer[
|
|
|
96
106
|
* @param expanded What `expandNames` resolved: the matches, the misses, and the over-broad asks.
|
|
97
107
|
* @param catalog The servers, read for the descriptions now worth their tokens.
|
|
98
108
|
*/
|
|
99
|
-
export declare function loadResult({ matched, unknown, overBroad, deferred }: ReturnType<typeof expandNames>, catalog: CatalogServer[]): string;
|
|
109
|
+
export declare function loadResult({ matched, unknown, overBroad, deferred, maxPerLoad }: ReturnType<typeof expandNames>, catalog: CatalogServer[]): string;
|
|
100
110
|
/**
|
|
101
111
|
* Whether the catalogue holds a tool by this name.
|
|
102
112
|
*
|
|
@@ -111,7 +121,7 @@ export declare const inCatalog: (catalog: CatalogServer[], name: string) => bool
|
|
|
111
121
|
*/
|
|
112
122
|
export declare function requestedNames(args: Record<string, unknown>): string[];
|
|
113
123
|
/**
|
|
114
|
-
*
|
|
124
|
+
* The system prompt a preselector is given, holding it to the cap its answer will be held to.
|
|
115
125
|
*
|
|
116
126
|
* On-demand loading otherwise costs a round trip every run: the model reads the catalogue,
|
|
117
127
|
* calls `load_tools`, and only then can do the work. A small model reading the same catalogue
|
|
@@ -119,22 +129,32 @@ export declare function requestedNames(args: Record<string, unknown>): string[];
|
|
|
119
129
|
* starts working on its first step.
|
|
120
130
|
*
|
|
121
131
|
* A wrong guess is cheap — an unused definition is a few hundred tokens for one run — but a
|
|
122
|
-
* broad guess is not, so the same
|
|
132
|
+
* broad guess is not, so the same cap applies here as to a `load_tools` call.
|
|
133
|
+
*
|
|
134
|
+
* @param maxPerLoad The most to ask for, defaulting to `MAX_PER_LOAD`. Give `preselection` the
|
|
135
|
+
* same number: this one is what the preselector is told, and that one is what it is held to.
|
|
123
136
|
*/
|
|
137
|
+
export declare const preselectSystem: (maxPerLoad?: number) => string;
|
|
138
|
+
/** The preselection system prompt at the default cap, for a caller that never changes it. */
|
|
124
139
|
export declare const PRESELECT_SYSTEM: string;
|
|
125
140
|
/**
|
|
126
141
|
* The user message for a preselection call: the catalogue, then the request.
|
|
127
142
|
*
|
|
128
143
|
* @param catalog The connected servers, rendered as the name-only listing.
|
|
129
|
-
* @param prompt The request being planned for, truncated
|
|
130
|
-
*
|
|
144
|
+
* @param prompt The request being planned for, truncated — choosing tools needs the shape of the
|
|
145
|
+
* ask, not all of it.
|
|
146
|
+
* @param maxPromptChars Where the request is cut, defaulting to 2000. A caller whose requests
|
|
147
|
+
* carry the part that names the work at the end wants a larger one, and pays for it in the
|
|
148
|
+
* preselector's prompt.
|
|
131
149
|
*/
|
|
132
|
-
export declare const preselectInput: (catalog: CatalogServer[], prompt: string) => string;
|
|
150
|
+
export declare const preselectInput: (catalog: CatalogServer[], prompt: string, maxPromptChars?: number) => string;
|
|
133
151
|
/**
|
|
134
152
|
* Resolves a preselection against the catalogue: unknown names dropped, count capped.
|
|
135
153
|
*
|
|
136
154
|
* @param names What the preselector replied. Unvalidated: a non-array gives none, and entries
|
|
137
155
|
* that are not strings are dropped.
|
|
138
156
|
* @param catalog The servers to resolve against.
|
|
157
|
+
* @param maxPerLoad The most to keep, defaulting to `MAX_PER_LOAD`. The same number
|
|
158
|
+
* `preselectSystem` was given, or the model is being held to a cap it was never told about.
|
|
139
159
|
*/
|
|
140
|
-
export declare function preselection(names: unknown, catalog: CatalogServer[]): string[];
|
|
160
|
+
export declare function preselection(names: unknown, catalog: CatalogServer[], maxPerLoad?: number): string[];
|
package/dist/tool-loading.js
CHANGED
|
@@ -103,6 +103,11 @@ const flatten = (catalog) => catalog.flatMap((server) => server.tools);
|
|
|
103
103
|
* in the position on-demand loading exists to avoid — a tool array too large to choose from.
|
|
104
104
|
* Over-broad requests are refused with the matching names listed, so the next call can be
|
|
105
105
|
* precise.
|
|
106
|
+
*
|
|
107
|
+
* The default rather than the rule: twelve is what a small model chooses well from, and a caller
|
|
108
|
+
* running a large one against a large window can say otherwise to `expandNames`, `preselection`
|
|
109
|
+
* and `preselectSystem`. Whatever it says is carried on the resolution, so the refusal the model
|
|
110
|
+
* reads names the number it was actually held to.
|
|
106
111
|
*/
|
|
107
112
|
export const MAX_PER_LOAD = 12;
|
|
108
113
|
/**
|
|
@@ -110,7 +115,7 @@ export const MAX_PER_LOAD = 12;
|
|
|
110
115
|
* conversation runs; least-recently-used names fall off the front.
|
|
111
116
|
*
|
|
112
117
|
* Only a multi-turn caller needs this — a run that starts from nothing each time has nothing to
|
|
113
|
-
* carry. See `carryOver
|
|
118
|
+
* carry. See `carryOver`, which takes another number if this one is not yours.
|
|
114
119
|
*/
|
|
115
120
|
export const MAX_CARRIED = 16;
|
|
116
121
|
/**
|
|
@@ -118,8 +123,10 @@ export const MAX_CARRIED = 16;
|
|
|
118
123
|
*
|
|
119
124
|
* @param previous Last turn's names, oldest first.
|
|
120
125
|
* @param used What this turn called. Moved to the end, so the oldest unused fall off.
|
|
126
|
+
* @param max How many to carry, defaulting to `MAX_CARRIED`. At least one: a cap of zero is
|
|
127
|
+
* read as no cap, which is what `slice` does with it and not what anybody asking for zero meant.
|
|
121
128
|
*/
|
|
122
|
-
export const carryOver = (previous, used) => [...previous.filter((name) => !used.has(name)), ...used].slice(-
|
|
129
|
+
export const carryOver = (previous, used, max = MAX_CARRIED) => [...previous.filter((name) => !used.has(name)), ...used].slice(-Math.max(1, max));
|
|
123
130
|
/**
|
|
124
131
|
* Resolves requested names against the catalogue, expanding trailing `*` wildcards.
|
|
125
132
|
*
|
|
@@ -131,8 +138,10 @@ export const carryOver = (previous, used) => [...previous.filter((name) => !used
|
|
|
131
138
|
*
|
|
132
139
|
* @param requested What the model asked for. A trailing `*` expands.
|
|
133
140
|
* @param catalog The servers to resolve against.
|
|
141
|
+
* @param maxPerLoad The most this call may load, defaulting to `MAX_PER_LOAD`. It comes back on
|
|
142
|
+
* the resolution so `loadResult` reports the same number rather than a second opinion of it.
|
|
134
143
|
*/
|
|
135
|
-
export function expandNames(requested, catalog) {
|
|
144
|
+
export function expandNames(requested, catalog, maxPerLoad = MAX_PER_LOAD) {
|
|
136
145
|
const all = flatten(catalog);
|
|
137
146
|
const matched = new Set();
|
|
138
147
|
const unknown = [];
|
|
@@ -179,15 +188,15 @@ export function expandNames(requested, catalog) {
|
|
|
179
188
|
// enough already — telling a model that asked for one exact tool that it matches one tool,
|
|
180
189
|
// "more than the twelve one call may load", and to choose from a list holding just that
|
|
181
190
|
// name, leaves it nothing to do but send the identical call again.
|
|
182
|
-
if (fresh.length >
|
|
191
|
+
if (fresh.length > maxPerLoad)
|
|
183
192
|
overBroad.push({ name, hits });
|
|
184
|
-
else if (matched.size + fresh.length >
|
|
193
|
+
else if (matched.size + fresh.length > maxPerLoad)
|
|
185
194
|
deferred.push(name);
|
|
186
195
|
else
|
|
187
196
|
for (const hit of hits)
|
|
188
197
|
matched.add(hit);
|
|
189
198
|
}
|
|
190
|
-
return { matched: [...matched], unknown, overBroad, deferred };
|
|
199
|
+
return { matched: [...matched], unknown, overBroad, deferred, maxPerLoad };
|
|
191
200
|
}
|
|
192
201
|
/**
|
|
193
202
|
* What `load_tools` reports back: the descriptions, now that they are worth their tokens.
|
|
@@ -195,7 +204,7 @@ export function expandNames(requested, catalog) {
|
|
|
195
204
|
* @param expanded What `expandNames` resolved: the matches, the misses, and the over-broad asks.
|
|
196
205
|
* @param catalog The servers, read for the descriptions now worth their tokens.
|
|
197
206
|
*/
|
|
198
|
-
export function loadResult({ matched, unknown, overBroad, deferred }, catalog) {
|
|
207
|
+
export function loadResult({ matched, unknown, overBroad, deferred, maxPerLoad }, catalog) {
|
|
199
208
|
const byName = new Map(flatten(catalog).map((tool) => [tool.name, tool.description]));
|
|
200
209
|
const lines = [];
|
|
201
210
|
if (matched.length) {
|
|
@@ -206,12 +215,12 @@ export function loadResult({ matched, unknown, overBroad, deferred }, catalog) {
|
|
|
206
215
|
for (const { name, hits } of overBroad) {
|
|
207
216
|
if (lines.length)
|
|
208
217
|
lines.push("");
|
|
209
|
-
lines.push(`\`${name}\` matches ${hits.length} tools, more than the ${
|
|
218
|
+
lines.push(`\`${name}\` matches ${hits.length} tools, more than the ${maxPerLoad} one call may load.`, "Name the ones you need from:", ...hits.map((hit) => ` ${hit}`));
|
|
210
219
|
}
|
|
211
220
|
if (deferred.length) {
|
|
212
221
|
if (lines.length)
|
|
213
222
|
lines.push("");
|
|
214
|
-
lines.push(`This call is full at ${
|
|
223
|
+
lines.push(`This call is full at ${maxPerLoad} tools, so these were not loaded: ${deferred.join(", ")}.`, "Ask for them on your next step.");
|
|
215
224
|
}
|
|
216
225
|
if (unknown.length) {
|
|
217
226
|
if (lines.length)
|
|
@@ -241,7 +250,15 @@ export function requestedNames(args) {
|
|
|
241
250
|
return [];
|
|
242
251
|
}
|
|
243
252
|
/**
|
|
244
|
-
*
|
|
253
|
+
* Where a request is cut for the preselector, in characters.
|
|
254
|
+
*
|
|
255
|
+
* A tool choice is made on what the work is, which is the top of a request rather than all of
|
|
256
|
+
* it — and the whole of a long one is paid for again in the preselection call. `preselectInput`
|
|
257
|
+
* takes another number for a caller whose requests are not shaped that way.
|
|
258
|
+
*/
|
|
259
|
+
const PRESELECT_PROMPT_CHARS = 2000;
|
|
260
|
+
/**
|
|
261
|
+
* The system prompt a preselector is given, holding it to the cap its answer will be held to.
|
|
245
262
|
*
|
|
246
263
|
* On-demand loading otherwise costs a round trip every run: the model reads the catalogue,
|
|
247
264
|
* calls `load_tools`, and only then can do the work. A small model reading the same catalogue
|
|
@@ -249,30 +266,40 @@ export function requestedNames(args) {
|
|
|
249
266
|
* starts working on its first step.
|
|
250
267
|
*
|
|
251
268
|
* A wrong guess is cheap — an unused definition is a few hundred tokens for one run — but a
|
|
252
|
-
* broad guess is not, so the same
|
|
269
|
+
* broad guess is not, so the same cap applies here as to a `load_tools` call.
|
|
270
|
+
*
|
|
271
|
+
* @param maxPerLoad The most to ask for, defaulting to `MAX_PER_LOAD`. Give `preselection` the
|
|
272
|
+
* same number: this one is what the preselector is told, and that one is what it is held to.
|
|
253
273
|
*/
|
|
254
|
-
export const
|
|
274
|
+
export const preselectSystem = (maxPerLoad = MAX_PER_LOAD) => "You choose tools. Below is a catalogue of tool names, then a request. Reply with a JSON " +
|
|
255
275
|
"array of the names the request is likely to need — exact names from the catalogue, at most " +
|
|
256
|
-
`${
|
|
276
|
+
`${maxPerLoad}, and as few as could do the job. Reply with \`[]\` if the request can be ` +
|
|
257
277
|
"answered without tools. Reply with the array alone — no prose, no explanation.";
|
|
278
|
+
/** The preselection system prompt at the default cap, for a caller that never changes it. */
|
|
279
|
+
export const PRESELECT_SYSTEM = preselectSystem();
|
|
258
280
|
/**
|
|
259
281
|
* The user message for a preselection call: the catalogue, then the request.
|
|
260
282
|
*
|
|
261
283
|
* @param catalog The connected servers, rendered as the name-only listing.
|
|
262
|
-
* @param prompt The request being planned for, truncated
|
|
263
|
-
*
|
|
284
|
+
* @param prompt The request being planned for, truncated — choosing tools needs the shape of the
|
|
285
|
+
* ask, not all of it.
|
|
286
|
+
* @param maxPromptChars Where the request is cut, defaulting to 2000. A caller whose requests
|
|
287
|
+
* carry the part that names the work at the end wants a larger one, and pays for it in the
|
|
288
|
+
* preselector's prompt.
|
|
264
289
|
*/
|
|
265
|
-
export const preselectInput = (catalog, prompt) => `# Tool catalogue\n\n${catalogList(catalog)}\n\n# Request\n\n${prompt.slice(0,
|
|
290
|
+
export const preselectInput = (catalog, prompt, maxPromptChars = PRESELECT_PROMPT_CHARS) => `# Tool catalogue\n\n${catalogList(catalog)}\n\n# Request\n\n${prompt.slice(0, maxPromptChars)}`;
|
|
266
291
|
/**
|
|
267
292
|
* Resolves a preselection against the catalogue: unknown names dropped, count capped.
|
|
268
293
|
*
|
|
269
294
|
* @param names What the preselector replied. Unvalidated: a non-array gives none, and entries
|
|
270
295
|
* that are not strings are dropped.
|
|
271
296
|
* @param catalog The servers to resolve against.
|
|
297
|
+
* @param maxPerLoad The most to keep, defaulting to `MAX_PER_LOAD`. The same number
|
|
298
|
+
* `preselectSystem` was given, or the model is being held to a cap it was never told about.
|
|
272
299
|
*/
|
|
273
|
-
export function preselection(names, catalog) {
|
|
300
|
+
export function preselection(names, catalog, maxPerLoad = MAX_PER_LOAD) {
|
|
274
301
|
if (!Array.isArray(names))
|
|
275
302
|
return [];
|
|
276
303
|
const wanted = names.filter((name) => typeof name === "string");
|
|
277
|
-
return expandNames(wanted, catalog).matched.slice(0,
|
|
304
|
+
return expandNames(wanted, catalog, maxPerLoad).matched.slice(0, maxPerLoad);
|
|
278
305
|
}
|
package/llms.txt
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> The endpoint-agnostic half of an OpenAI-compatible agent loop: tool-schema compatibility, on-demand tool loading, one-shot side tasks, run events, and a pooled client.
|
|
4
4
|
|
|
5
|
-
What is here is everything that does not know what the agent is *for*: making a tool schema a strict server will accept, getting tool definitions in front of a model without paying for all of them, reading one streamed turn back into a message, answering an endpoint that refuses one of those, one-shot calls that support a run, the event bus a watcher reads, a pooled client, and the rules about retrying. What is not here is the work — orchestration, prompts, and whatever the run is about — because that is the caller's, and it is the part that differs between one server and the next.
|
|
5
|
+
What is here is everything that does not know what the agent is *for*: making a tool schema a strict server will accept, getting tool definitions in front of a model without paying for all of them, reading one streamed turn back into a message, answering an endpoint that refuses one of those, one-shot calls that support a run, the host's side of lifecycle hooks, the event bus a watcher reads, a pooled client, and the rules about retrying. What is not here is the work — orchestration, prompts, and whatever the run is about — because that is the caller's, and it is the part that differs between one server and the next.
|
|
6
6
|
|
|
7
7
|
Requires Node >=22, with `openai` >=6 as a peer dependency. ESM only.
|
|
8
8
|
Full prose, worked examples and the reasoning behind each seam are in README.md; this file is the index.
|
|
@@ -55,6 +55,8 @@ What this package needs to know about a caller's configuration.
|
|
|
55
55
|
|
|
56
56
|
What a run is doing, while it is doing it.
|
|
57
57
|
|
|
58
|
+
- `configureEvents` — Changes what the bus keeps, for a process whose runs are not shaped like the ones these defaults were chosen for.
|
|
59
|
+
- `EventBusOptions` (type) — What the bus keeps and for how long.
|
|
58
60
|
- `emit` — Records one event and hands it to everyone watching that run.
|
|
59
61
|
- `endRun` — Forgets a run that will not be emitting `done` — one whose process is tearing down, or whose loop threw where it could not be caught.
|
|
60
62
|
- `fold` — Consecutive tokens of one kind are one thing being said, not hundreds of things.
|
|
@@ -66,6 +68,31 @@ What a run is doing, while it is doing it.
|
|
|
66
68
|
- `resetEvents` — Test seam: forget every run, so one test's events cannot be read by the next.
|
|
67
69
|
- `watch` — Everything that has happened on a run, then everything that happens next, until it ends.
|
|
68
70
|
|
|
71
|
+
### hooks
|
|
72
|
+
|
|
73
|
+
Lifecycle hooks, from the host's side: what a session looks like to them, where their context lands in a request, and what is said about each one.
|
|
74
|
+
|
|
75
|
+
- `assembleContext` — Builds the context a set of outcomes adds and the notes that go with it.
|
|
76
|
+
- `configureHooks` — Changes what hooks are held to, for a process whose windows are not the size these defaults were chosen for.
|
|
77
|
+
- `Gathered` (type) — The context a set of outcomes adds to a request, and a note for each hook worth mentioning.
|
|
78
|
+
- `gather` — Runs the hooks ahead of a request and builds what they add to it.
|
|
79
|
+
- `HOOK_CONTEXT_TOKENS` — The most context all of a request's hooks add between them by default, in estimated tokens.
|
|
80
|
+
- `HOOK_EVENTS` — Every event a hook can be bound to, in the order a session meets them.
|
|
81
|
+
- `HOOK_PREFACE` — Said once, above the blocks, so the model reads them as background rather than instructions.
|
|
82
|
+
- `HookContext` (type) — What a host knows at an event.
|
|
83
|
+
- `HookEvent` (type) — A point in a session a hook can be bound to.
|
|
84
|
+
- `HookMessage` (type) — One message of a session as a hook is handed it.
|
|
85
|
+
- `HookNote` (type) — One hook's line for whoever is watching: the context it added, or why it added none.
|
|
86
|
+
- `HookOptions` (type) — What hooks are held to across a process.
|
|
87
|
+
- `HookOutcome` (type) — What one hook did.
|
|
88
|
+
- `HookRunner` (type) — Runs one event's hooks.
|
|
89
|
+
- `INJECT_EVENTS` — The events whose hooks run before a request, and so the only ones whose output can reach it.
|
|
90
|
+
- `notify` — Runs the hooks for an event that reads what happened and adds nothing to a request.
|
|
91
|
+
- `resetHooks` — Test seam: puts `configureHooks` back to the defaults, so one test's budget is not the next's.
|
|
92
|
+
- `turnIndex` — Which turn of a session begins at a point, from 0: the user messages ahead of it.
|
|
93
|
+
- `turnMessages` — A stretch of a transcript as a hook reads it: what the user and the assistant said, and nothing else.
|
|
94
|
+
- `withContext` — The request, with the hooks' context added to this turn's question.
|
|
95
|
+
|
|
69
96
|
### reset
|
|
70
97
|
|
|
71
98
|
- `resetAll` — Forgets everything this package remembers between calls.
|
|
@@ -137,7 +164,8 @@ Reading one streamed turn back into a message.
|
|
|
137
164
|
- `loadResult` — What `load_tools` reports back: the descriptions, now that they are worth their tokens.
|
|
138
165
|
- `MAX_CARRIED` — The most a conversation carries between turns.
|
|
139
166
|
- `MAX_PER_LOAD` — The most a single `load_tools` call may pull in.
|
|
140
|
-
- `PRESELECT_SYSTEM` —
|
|
167
|
+
- `PRESELECT_SYSTEM` — The preselection system prompt at the default cap, for a caller that never changes it.
|
|
141
168
|
- `preselectInput` — The user message for a preselection call: the catalogue, then the request.
|
|
142
169
|
- `preselection` — Resolves a preselection against the catalogue: unknown names dropped, count capped.
|
|
170
|
+
- `preselectSystem` — The system prompt a preselector is given, holding it to the cap its answer will be held to.
|
|
143
171
|
- `requestedNames` — `load_tools` arguments, defensively — a model may send a bare string or a nested object.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cubicecho/agent-core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "The endpoint-agnostic half of an OpenAI-compatible agent loop: tool-schema compatibility, on-demand tool loading, one-shot side tasks, run events, and a pooled client.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openai",
|