@cubicecho/agent-core 4.19.0 → 4.21.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 +41 -3
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -1
- package/dist/run/agent-loop.d.ts +42 -2
- package/dist/run/agent-loop.js +40 -17
- package/dist/run/artifacts.d.ts +145 -0
- package/dist/run/artifacts.js +412 -0
- package/dist/run/events.d.ts +5 -3
- package/dist/run/events.js +5 -3
- package/dist/run/run-calls.d.ts +21 -4
- package/dist/run/run-calls.js +120 -39
- package/dist/wire/tool-calls.d.ts +64 -6
- package/dist/wire/tool-calls.js +22 -0
- package/llms.txt +16 -0
- package/package.json +1 -1
package/dist/run/run-calls.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { isRecord } from '../core/guards.js';
|
|
1
2
|
import { CALL_TOOL, expandNames, inCatalog, LOAD_TOOLS, loadResult, proxiedCall, proxyLoadResult, requestedNames, shownCall, toolName, } from '../tools/tool-loading.js';
|
|
2
3
|
import { errorMessage } from '../wire/errors.js';
|
|
3
4
|
import { parseToolArguments, } from '../wire/tool-calls.js';
|
|
4
5
|
import { FUNCTION_TOOL, Role } from '../wire/wire.js';
|
|
6
|
+
import { declaredArtifact, detectArtifact, RECORD_ARTIFACT, } from './artifacts.js';
|
|
5
7
|
import { RunEventKind } from './events.js';
|
|
6
8
|
/**
|
|
7
9
|
* The tools between two turns: a step's calls read, run and written into the transcript.
|
|
@@ -26,20 +28,40 @@ export const preview = (text, limit = 2000) => text.length > limit ? `${text.sli
|
|
|
26
28
|
const STOPPED_CALL = 'Stopped before this call finished.';
|
|
27
29
|
/** The same for a call of that step the loop never got to. */
|
|
28
30
|
const UNRUN_CALL = 'Not run: the run stopped first.';
|
|
31
|
+
/**
|
|
32
|
+
* Whether a call's arguments are, as written, the JSON of an object — or no arguments at all.
|
|
33
|
+
*
|
|
34
|
+
* @param raw - The arguments as the turn carried them: a string, or an object a server parsed.
|
|
35
|
+
* @returns False where reading them took `parseToolArguments`' repairs.
|
|
36
|
+
*/
|
|
37
|
+
function readsAsWritten(raw) {
|
|
38
|
+
if (typeof raw !== 'string' || !raw.trim()) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
return isRecord(JSON.parse(raw));
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
29
48
|
/**
|
|
30
49
|
* One call with its arguments read, or with why they could not be.
|
|
31
50
|
*
|
|
32
51
|
* @param call - The call as the turn carried it.
|
|
33
52
|
* @param finishReason - Why the turn ended, which tells a call cut off from one written wrongly.
|
|
53
|
+
* @param recovered - Whether the call was recovered from the reply's text, which makes it repaired
|
|
54
|
+
* whatever its arguments.
|
|
34
55
|
* @returns The call beside its arguments and their repaired JSON, or beside the error and `{}`.
|
|
35
56
|
*/
|
|
36
|
-
function readCall(call, finishReason) {
|
|
57
|
+
function readCall(call, finishReason, recovered) {
|
|
37
58
|
try {
|
|
38
59
|
const args = parseToolArguments(call.function.arguments, { finishReason });
|
|
39
|
-
|
|
60
|
+
const repaired = recovered || !readsAsWritten(call.function.arguments);
|
|
61
|
+
return { call, args, normal: JSON.stringify(args), repaired };
|
|
40
62
|
}
|
|
41
63
|
catch (error) {
|
|
42
|
-
return { call, error, normal: '{}' };
|
|
64
|
+
return { call, error, normal: '{}', repaired: false };
|
|
43
65
|
}
|
|
44
66
|
}
|
|
45
67
|
/**
|
|
@@ -47,6 +69,7 @@ function readCall(call, finishReason) {
|
|
|
47
69
|
*
|
|
48
70
|
* @param calls - The turn's calls, in the order the model made them.
|
|
49
71
|
* @param finishReason - Why the turn ended, which tells a call cut off from one written wrongly.
|
|
72
|
+
* @param [recovered] - Whether the calls were recovered from the reply's text.
|
|
50
73
|
* @returns One entry per call, in the same order. Unreadable arguments do not throw: the entry
|
|
51
74
|
* carries the error in place of them.
|
|
52
75
|
*
|
|
@@ -54,7 +77,7 @@ function readCall(call, finishReason) {
|
|
|
54
77
|
* A server that parses replayed arguments refuses the almost-JSON a model wrote, so each is
|
|
55
78
|
* normalised here, and one that could not be read at all is replayed as no arguments.
|
|
56
79
|
*/
|
|
57
|
-
export const readCalls = (calls, finishReason) => calls.map((call) => readCall(call, finishReason));
|
|
80
|
+
export const readCalls = (calls, finishReason, recovered = false) => calls.map((call) => readCall(call, finishReason, recovered));
|
|
58
81
|
/**
|
|
59
82
|
* The assistant message a turn is written into the transcript as, its calls' arguments repaired.
|
|
60
83
|
*
|
|
@@ -75,6 +98,19 @@ export const assistantMessage = (content, parsed) => ({
|
|
|
75
98
|
}
|
|
76
99
|
: {}),
|
|
77
100
|
});
|
|
101
|
+
/**
|
|
102
|
+
* The assistant message a turn is, as the model produced it: its text and calls as they streamed.
|
|
103
|
+
*
|
|
104
|
+
* @param content - The turn's text, recovered calls left in it. Empty is written as `null`.
|
|
105
|
+
* @param calls - The calls the model sent as calls, with their arguments as streamed. Not written
|
|
106
|
+
* to. None leaves `tool_calls` off the message rather than empty.
|
|
107
|
+
* @returns A new message, each call on it a copy.
|
|
108
|
+
*/
|
|
109
|
+
export const writtenMessage = (content, calls) => ({
|
|
110
|
+
role: Role.Assistant,
|
|
111
|
+
content: content || null,
|
|
112
|
+
...(calls.length ? { tool_calls: calls.map((call) => ({ ...call, function: { ...call.function } })) } : {}),
|
|
113
|
+
});
|
|
78
114
|
/**
|
|
79
115
|
* The definitions the host gave for these names, in the order the names are given.
|
|
80
116
|
*
|
|
@@ -227,28 +263,57 @@ async function once(answered, key, make) {
|
|
|
227
263
|
}
|
|
228
264
|
}
|
|
229
265
|
/**
|
|
230
|
-
*
|
|
266
|
+
* Tells watchers of artifacts the run had not produced before.
|
|
231
267
|
*
|
|
232
|
-
* @param run - The run
|
|
233
|
-
* @param
|
|
234
|
-
* @param from - The call they came from.
|
|
268
|
+
* @param run - The run, whose watchers hear of them.
|
|
269
|
+
* @param added - The new artifacts, each told once.
|
|
235
270
|
*/
|
|
236
|
-
function
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
271
|
+
function announceArtifacts(run, added) {
|
|
272
|
+
for (const { link, callId, tool } of added) {
|
|
273
|
+
run.onEvent({ kind: RunEventKind.Artifact, id: callId, name: tool, text: link.title || link.uri, link });
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Adds what one successful call produced to the run's artifacts: its links, and — where the run
|
|
278
|
+
* collects them — what it was given and answered, and the write it reads as.
|
|
279
|
+
*
|
|
280
|
+
* @param run - The run. Written to: its `artifacts`.
|
|
281
|
+
* @param request - The call, under the tool it was shown as.
|
|
282
|
+
* @param content - What it answered.
|
|
283
|
+
* @param links - What its answer linked to.
|
|
284
|
+
* @param from - The call, as an artifact is put down to it.
|
|
285
|
+
*/
|
|
286
|
+
function collect(run, request, content, links, from) {
|
|
287
|
+
announceArtifacts(run, run.artifacts.link(links, from));
|
|
288
|
+
if (run.declares) {
|
|
289
|
+
run.artifacts.witness(request.args, content, links, from);
|
|
251
290
|
}
|
|
291
|
+
const draft = run.detects?.(request) ? detectArtifact(request.name, request.args) : null;
|
|
292
|
+
const added = draft ? run.artifacts.add(draft, from) : undefined;
|
|
293
|
+
announceArtifacts(run, added ? [added] : []);
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Answers a `record_artifact`, keeping the declaration where some call in the run touched the
|
|
297
|
+
* location.
|
|
298
|
+
*
|
|
299
|
+
* @param run - The run. Written to: its `artifacts`, where the declaration is believed.
|
|
300
|
+
* @param args - The call's arguments.
|
|
301
|
+
* @returns What the model reads. Throws, which the model reads instead, for a declaration with no
|
|
302
|
+
* location or one no call in the run was given or answered with.
|
|
303
|
+
*/
|
|
304
|
+
function answerRecord(run, args) {
|
|
305
|
+
const draft = declaredArtifact(args);
|
|
306
|
+
if (draft === null) {
|
|
307
|
+
throw new Error(`${RECORD_ARTIFACT} needs a location.`);
|
|
308
|
+
}
|
|
309
|
+
const from = run.artifacts.seen(draft.location);
|
|
310
|
+
if (from === undefined) {
|
|
311
|
+
throw new Error(`No tool call in this run touched ${draft.location}, so it was not recorded. ` +
|
|
312
|
+
'Record only what one of your tools stored, after the call that stored it.');
|
|
313
|
+
}
|
|
314
|
+
const added = run.artifacts.add(draft, from);
|
|
315
|
+
announceArtifacts(run, added ? [added] : []);
|
|
316
|
+
return `Recorded ${draft.location}.`;
|
|
252
317
|
}
|
|
253
318
|
/**
|
|
254
319
|
* A call looked through and built into the request every host callback is handed.
|
|
@@ -284,14 +349,15 @@ function prepare(run, entry) {
|
|
|
284
349
|
}
|
|
285
350
|
// Built for every call rather than only the dispatched ones, so a host hears of the calls
|
|
286
351
|
// the loop answers itself in the same shape. Arguments that could not be read are none.
|
|
287
|
-
const request = { id: call.id, name, args: inner, raw };
|
|
352
|
+
const request = { id: call.id, name, args: inner, raw, repaired: entry.repaired };
|
|
288
353
|
// By the name the model called, not the one a `call_tool` wraps: `load_tools` is not in
|
|
289
354
|
// the catalogue, and one reached through `call_tool` is refused like any other.
|
|
290
355
|
const load = onDemand && call.function.name === LOAD_TOOLS;
|
|
291
|
-
const
|
|
356
|
+
const record = run.declares && call.function.name === RECORD_ARTIFACT;
|
|
357
|
+
const dispatched = args !== undefined && load === false && record === false && refused === undefined;
|
|
292
358
|
// Keyed on the inner call, so one made through `call_tool` and one made natively share.
|
|
293
359
|
const key = `${name}\0${proxy ? JSON.stringify(inner) : normal}`;
|
|
294
|
-
return { entry, request, load, refused, dedupable: dispatched && run.dedupable(request), key };
|
|
360
|
+
return { entry, request, load, record, refused, dedupable: dispatched && run.dedupable(request), key };
|
|
295
361
|
}
|
|
296
362
|
/**
|
|
297
363
|
* Whether a call is answered without `dispatch` seeing it, so it can run beside anything.
|
|
@@ -299,10 +365,15 @@ function prepare(run, entry) {
|
|
|
299
365
|
* @param prepared - The call.
|
|
300
366
|
* @param answered - The step's calls already made, by key. A call that threw is not in it.
|
|
301
367
|
* @param batch - The keys of the calls in the batch being gathered, which a repeat shares.
|
|
302
|
-
* @returns True for a `load_tools`, a call whose arguments could not be read,
|
|
303
|
-
* was refused, and an identical repeat that `dedupeToolCalls` answers from the
|
|
368
|
+
* @returns True for a `load_tools`, a `record_artifact`, a call whose arguments could not be read,
|
|
369
|
+
* a `call_tool` that was refused, and an identical repeat that `dedupeToolCalls` answers from the
|
|
370
|
+
* first.
|
|
304
371
|
*/
|
|
305
|
-
const answersItself = ({ entry, load, refused, dedupable, key }, answered, batch) => entry.args === undefined ||
|
|
372
|
+
const answersItself = ({ entry, load, record, refused, dedupable, key }, answered, batch) => entry.args === undefined ||
|
|
373
|
+
load ||
|
|
374
|
+
record ||
|
|
375
|
+
refused !== undefined ||
|
|
376
|
+
(dedupable && (answered.has(key) || batch.has(key)));
|
|
306
377
|
/**
|
|
307
378
|
* Where the batch of calls starting at `from` ends: every call, one call, or the calls up to the
|
|
308
379
|
* first one the host's predicate does not pass.
|
|
@@ -355,7 +426,7 @@ function batchEnd(run, ready, from, total, answered) {
|
|
|
355
426
|
*/
|
|
356
427
|
async function runCall(run, prepared, answered, step) {
|
|
357
428
|
const { catalog, onDemand, proxied, signal } = run;
|
|
358
|
-
const { entry, request, load, refused, dedupable, key } = prepared;
|
|
429
|
+
const { entry, request, load, record, refused, dedupable, key } = prepared;
|
|
359
430
|
const { call, args, error: unreadable } = entry;
|
|
360
431
|
const { name, raw } = request;
|
|
361
432
|
run.onEvent({ kind: RunEventKind.ToolCall, id: call.id, name, text: preview(raw) });
|
|
@@ -375,6 +446,9 @@ async function runCall(run, prepared, answered, step) {
|
|
|
375
446
|
if (load) {
|
|
376
447
|
({ content, ok, counts: loads } = answerLoad(run, args));
|
|
377
448
|
}
|
|
449
|
+
else if (record) {
|
|
450
|
+
content = answerRecord(run, args);
|
|
451
|
+
}
|
|
378
452
|
else {
|
|
379
453
|
if (refused) {
|
|
380
454
|
throw refused.error;
|
|
@@ -414,9 +488,10 @@ async function runCall(run, prepared, answered, step) {
|
|
|
414
488
|
text: preview(content),
|
|
415
489
|
...(loads ? { loads } : {}),
|
|
416
490
|
});
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
491
|
+
// Only what `dispatch` answered made anything, and a repeat made nothing the first did not.
|
|
492
|
+
const isMade = ok && load === false && record === false && shared === false;
|
|
493
|
+
if (isMade) {
|
|
494
|
+
collect(run, request, content, links, { callId: call.id, tool: name, step });
|
|
420
495
|
}
|
|
421
496
|
const result = { id: call.id, name, ok, content, ...(links.length ? { links } : {}) };
|
|
422
497
|
run.onToolResult?.(result);
|
|
@@ -480,11 +555,17 @@ export async function runCalls(run, parsed, messages, step) {
|
|
|
480
555
|
const start = from;
|
|
481
556
|
const to = batchEnd(run, ready, start, parsed.length, answered);
|
|
482
557
|
begun = to;
|
|
483
|
-
|
|
484
|
-
const { result, end } = await runCall(run, ready(
|
|
485
|
-
outcomes[
|
|
486
|
-
ends[
|
|
487
|
-
}
|
|
558
|
+
const runAt = async (at) => {
|
|
559
|
+
const { result, end } = await runCall(run, ready(at), answered, step);
|
|
560
|
+
outcomes[at] = result;
|
|
561
|
+
ends[at] = end;
|
|
562
|
+
};
|
|
563
|
+
// A declaration describes what the batch beside it stored, so it waits for the rest of the
|
|
564
|
+
// batch: run together, it would be checked before the write it names had answered.
|
|
565
|
+
const positions = parsed.slice(start, to).map((_, offset) => start + offset);
|
|
566
|
+
const isRecord = (at) => ready(at).record;
|
|
567
|
+
await Promise.all(positions.filter((at) => isRecord(at) === false).map(runAt));
|
|
568
|
+
await Promise.all(positions.filter(isRecord).map(runAt));
|
|
488
569
|
for (const { id, name, ok, content } of outcomes.slice(from, to).flatMap((outcome) => outcome ?? [])) {
|
|
489
570
|
toolCalls.push({ id, name, ok });
|
|
490
571
|
await keep(id, content);
|
|
@@ -540,7 +621,7 @@ export async function loadShortlist(run, shortlist, messages) {
|
|
|
540
621
|
// host that shortlisted more has already chosen.
|
|
541
622
|
const content = proxyLoadResult(expandNames(names, catalog, names.length), catalog, shortlist);
|
|
542
623
|
run.onEvent({ kind: RunEventKind.ToolCall, id, name: LOAD_TOOLS, text: preview(args) });
|
|
543
|
-
run.onToolCall?.({ id, name: LOAD_TOOLS, args: { names }, raw: args });
|
|
624
|
+
run.onToolCall?.({ id, name: LOAD_TOOLS, args: { names }, raw: args, repaired: false });
|
|
544
625
|
const loads = { toolsLoaded: names.length, redundantLoads: 0, unknownToolNames: 0 };
|
|
545
626
|
run.onEvent({ kind: RunEventKind.ToolResult, id, name: LOAD_TOOLS, ok: true, text: preview(content), loads });
|
|
546
627
|
run.onToolResult?.({ id, name: LOAD_TOOLS, ok: true, content });
|
|
@@ -114,9 +114,24 @@ export interface ToolCallRequest {
|
|
|
114
114
|
args: Record<string, unknown>;
|
|
115
115
|
/**
|
|
116
116
|
* The arguments as the model wrote them, before any repair. Through `call_tool`, the inner
|
|
117
|
-
* arguments as JSON text.
|
|
117
|
+
* arguments as JSON text. For a call recovered from the reply's text, the arguments recovery read
|
|
118
|
+
* out of it, as JSON text: the words the model wrote are the reply's content, which `onMessage`'s
|
|
119
|
+
* `raw` message carries.
|
|
118
120
|
*/
|
|
119
121
|
raw: string;
|
|
122
|
+
/**
|
|
123
|
+
* Whether `args` took a repair to read: true where `raw` does not parse, as written, to the JSON
|
|
124
|
+
* object `args` holds — near-JSON, or JSON inside a string — and for every call recovered from
|
|
125
|
+
* text, which the model never sent as a call. False for blank arguments, which every reader takes
|
|
126
|
+
* as none, and for arguments that could not be read at all. Through `call_tool`, whether the
|
|
127
|
+
* `call_tool`'s own arguments did.
|
|
128
|
+
*
|
|
129
|
+
* @remarks
|
|
130
|
+
* A host that shows or stores what the model said reads `raw` where this is true. Whitespace is
|
|
131
|
+
* not a repair, though the replayed arguments are re-serialised either way. `runAgentLoop` always
|
|
132
|
+
* sets it; optional so a request built before it existed still compiles.
|
|
133
|
+
*/
|
|
134
|
+
repaired?: boolean;
|
|
120
135
|
}
|
|
121
136
|
/** What one tool call did, in the order the model asked. */
|
|
122
137
|
export interface ToolCallOutcome {
|
|
@@ -263,25 +278,68 @@ export interface ToolCallReport {
|
|
|
263
278
|
*/
|
|
264
279
|
log: (entry: ServerLogEntry) => void;
|
|
265
280
|
}
|
|
281
|
+
/**
|
|
282
|
+
* How the loop came to know of an artifact, most trusted first.
|
|
283
|
+
*
|
|
284
|
+
* @remarks
|
|
285
|
+
* `linked` is a call's answer saying so, and is the only one that takes no guessing. `declared` is
|
|
286
|
+
* the model naming it through `record_artifact`, believed only where some call in the run touched
|
|
287
|
+
* the location. `detected` is the loop reading a successful call as a write: a verb at the front
|
|
288
|
+
* of its name and a path in its arguments. The last two are opt-in, through `artifacts` on the
|
|
289
|
+
* loop's options.
|
|
290
|
+
*/
|
|
291
|
+
export declare const ArtifactSource: {
|
|
292
|
+
readonly Linked: 'linked';
|
|
293
|
+
readonly Declared: 'declared';
|
|
294
|
+
readonly Detected: 'detected';
|
|
295
|
+
};
|
|
296
|
+
/** Any one of the sources in `ArtifactSource`. */
|
|
297
|
+
export type ArtifactSource = (typeof ArtifactSource)[keyof typeof ArtifactSource];
|
|
298
|
+
/** What the run's last write did to an artifact's location, as a detection read it. */
|
|
299
|
+
export declare const ArtifactAction: {
|
|
300
|
+
readonly Created: 'created';
|
|
301
|
+
readonly Updated: 'updated';
|
|
302
|
+
readonly Moved: 'moved';
|
|
303
|
+
readonly Deleted: 'deleted';
|
|
304
|
+
};
|
|
305
|
+
/** Any one of the actions in `ArtifactAction`. */
|
|
306
|
+
export type ArtifactAction = (typeof ArtifactAction)[keyof typeof ArtifactAction];
|
|
266
307
|
/**
|
|
267
308
|
* One thing a run's tool calls produced: the first link to a uri, and where it came from.
|
|
268
309
|
*
|
|
269
310
|
* @remarks
|
|
270
311
|
* A link is what one call answered with; an artifact is what the run made, one per uri however
|
|
271
|
-
* many calls linked to it.
|
|
312
|
+
* many calls linked to it. A declared or detected artifact is one per location the same way, and
|
|
313
|
+
* its `link` is built from what was said of it: the location as `uri`, its last segment as `name`.
|
|
272
314
|
*/
|
|
273
315
|
export interface RunArtifact {
|
|
274
|
-
/**
|
|
316
|
+
/**
|
|
317
|
+
* The link as the first call to give its uri gave it. A later call's says nothing new here, and
|
|
318
|
+
* a declaration only fills in a `title` or `description` it left out.
|
|
319
|
+
*/
|
|
275
320
|
link: ResourceLink;
|
|
276
|
-
/** The call that first linked to it. */
|
|
321
|
+
/** The call that first linked to it, wrote it, or — for a declaration alone — last touched it. */
|
|
277
322
|
callId: string;
|
|
278
323
|
/** That call's tool. For a `call_tool`, the tool it named. */
|
|
279
324
|
tool: string;
|
|
280
325
|
/** The loop's step that call was made in, from 0. */
|
|
281
326
|
step: number;
|
|
282
327
|
/**
|
|
283
|
-
* How many calls linked to it. A deduplicated repeat does not count, since nothing
|
|
284
|
-
* twice,
|
|
328
|
+
* How many calls linked to it or wrote it. A deduplicated repeat does not count, since nothing
|
|
329
|
+
* was made twice, a call that links one uri twice counts once, and a declaration counts none.
|
|
285
330
|
*/
|
|
286
331
|
count: number;
|
|
332
|
+
/**
|
|
333
|
+
* How it came to be known: `linked` where absent, which is every artifact a call's answer
|
|
334
|
+
* linked to, so the shape from before the other two sources still reads the same. A declaration
|
|
335
|
+
* over a detection takes the source over; a link over either does too.
|
|
336
|
+
*/
|
|
337
|
+
source?: ArtifactSource;
|
|
338
|
+
/**
|
|
339
|
+
* What the latest write a detection read did to it. Absent where no detection did: a link or a
|
|
340
|
+
* declaration says a thing exists, not what was done to it.
|
|
341
|
+
*/
|
|
342
|
+
action?: ArtifactAction;
|
|
343
|
+
/** The bytes the latest detected write carried, where its arguments held the content. */
|
|
344
|
+
sizeBytes?: number;
|
|
287
345
|
}
|
package/dist/wire/tool-calls.js
CHANGED
|
@@ -489,3 +489,25 @@ export const ServerLogLevel = {
|
|
|
489
489
|
Alert: 'alert',
|
|
490
490
|
Emergency: 'emergency',
|
|
491
491
|
};
|
|
492
|
+
/**
|
|
493
|
+
* How the loop came to know of an artifact, most trusted first.
|
|
494
|
+
*
|
|
495
|
+
* @remarks
|
|
496
|
+
* `linked` is a call's answer saying so, and is the only one that takes no guessing. `declared` is
|
|
497
|
+
* the model naming it through `record_artifact`, believed only where some call in the run touched
|
|
498
|
+
* the location. `detected` is the loop reading a successful call as a write: a verb at the front
|
|
499
|
+
* of its name and a path in its arguments. The last two are opt-in, through `artifacts` on the
|
|
500
|
+
* loop's options.
|
|
501
|
+
*/
|
|
502
|
+
export const ArtifactSource = {
|
|
503
|
+
Linked: 'linked',
|
|
504
|
+
Declared: 'declared',
|
|
505
|
+
Detected: 'detected',
|
|
506
|
+
};
|
|
507
|
+
/** What the run's last write did to an artifact's location, as a detection read it. */
|
|
508
|
+
export const ArtifactAction = {
|
|
509
|
+
Created: 'created',
|
|
510
|
+
Updated: 'updated',
|
|
511
|
+
Moved: 'moved',
|
|
512
|
+
Deleted: 'deleted',
|
|
513
|
+
};
|
package/llms.txt
CHANGED
|
@@ -176,6 +176,20 @@ The loop above a turn: send, run the tools the model asked for, send again, unti
|
|
|
176
176
|
- `PRESELECTED_NOTICE` — What opens the notice naming the loop's own picks, ahead of the names.
|
|
177
177
|
- `runAgentLoop` — Runs a question to its answer: one `runTurn` per step, the tools it asks for between them, until a turn asks for none or a call's answer ends the run.
|
|
178
178
|
- `StepWindow` (type) — How full the window is as a step is about to be sent, as `beforeStep` is told it.
|
|
179
|
+
- `WrittenMessage` (type) — What `onMessage` is handed beside an assistant message the model wrote: that message as the model produced it.
|
|
180
|
+
|
|
181
|
+
### artifacts
|
|
182
|
+
|
|
183
|
+
What a run left behind, from the two sources that take a guess: the model saying so, and a call that reads as a write.
|
|
184
|
+
|
|
185
|
+
- `ArtifactDraft` (type) — What one declaration or detection said of a location, before it is merged into the run's.
|
|
186
|
+
- `ArtifactOptions` (type) — Which of the guessing sources a run collects, beside the links every run keeps.
|
|
187
|
+
- `artifactSource` — How an artifact came to be known, reading an absent `source` as the link it always was.
|
|
188
|
+
- `declaredArtifact` — What the model said through `record_artifact`.
|
|
189
|
+
- `detectArtifact` — What a successful call wrote, if its name and arguments look like a write.
|
|
190
|
+
- `mediaTypeFor` — A media type guessed off a location's extension.
|
|
191
|
+
- `RECORD_ARTIFACT` — The name of the tool the loop declares and answers itself when `artifacts.declare` is on.
|
|
192
|
+
- `RECORD_ARTIFACT_TOOL` — The definition of `record_artifact`, as the loop declares it beside the host's own tools.
|
|
179
193
|
|
|
180
194
|
### events
|
|
181
195
|
|
|
@@ -432,6 +446,8 @@ Reading what a model meant by a tool call when it did not write one cleanly.
|
|
|
432
446
|
|
|
433
447
|
- `ARGUMENTS_MALFORMED` — The `ToolArgumentsError` kind for a call the model wrote wrongly.
|
|
434
448
|
- `ARGUMENTS_TRUNCATED` — The `ToolArgumentsError` kind for a call cut off at the reply ceiling.
|
|
449
|
+
- `ArtifactAction` — Any one of the actions in `ArtifactAction`.
|
|
450
|
+
- `ArtifactSource` — Any one of the sources in `ArtifactSource`.
|
|
435
451
|
- `EndedBy` (type) — The call that ended a run through its answer's `end`, as `AgentLoopResult.ended` says it.
|
|
436
452
|
- `parseToolArguments` — A tool call's arguments as the object the tool is handed.
|
|
437
453
|
- `ResourceLink` (type) — A handle to something a tool call made or found — a document it wrote, a file it saved.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cubicecho/agent-core",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.21.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",
|