@dudousxd/nestjs-agent-core 0.17.0 → 0.19.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 +2 -0
- package/dist/guardrails/index.d.cts +1 -1
- package/dist/guardrails/index.d.ts +1 -1
- package/dist/index.cjs +138 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +47 -179
- package/dist/index.d.ts +47 -179
- package/dist/index.js +136 -11
- package/dist/index.js.map +1 -1
- package/dist/{tool-CL9oEytW.d.cts → tool-Q2rmGeaG.d.cts} +295 -1
- package/dist/{tool-CL9oEytW.d.ts → tool-Q2rmGeaG.d.ts} +295 -1
- package/package.json +1 -1
|
@@ -266,6 +266,282 @@ interface AgentHistoryWindow {
|
|
|
266
266
|
summarize?: boolean;
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
+
/**
|
|
270
|
+
* The structured live-stream vocabulary carried over the {@link SinkWriter} byte channel.
|
|
271
|
+
*
|
|
272
|
+
* The model turn (via the AI-SDK adapter) and the agent loop write these events as NDJSON — one
|
|
273
|
+
* `JSON.stringify(event)\n` per {@link SinkWriter.write}. The HTTP layer forwards each line as an
|
|
274
|
+
* SSE `data:` frame, and the client transport maps them back to the AI SDK UI-message chunk
|
|
275
|
+
* protocol so the browser renders text, reasoning, and tool cards (input + output) LIVE — the same
|
|
276
|
+
* rich rendering a raw `streamText().toUIMessageStream()` would give, but reconstructed on the
|
|
277
|
+
* client so the sink stays a format-agnostic byte buffer (durable buffering/replay is untouched).
|
|
278
|
+
*
|
|
279
|
+
* Keeping this vocabulary neutral (not AI-SDK `UIMessageChunk`) means core never depends on `ai`:
|
|
280
|
+
* the adapter owns model-parts → event, the transport owns event → UI-chunk.
|
|
281
|
+
*
|
|
282
|
+
* The vocabulary is also a CONTRACT for runners that are not this library's loop: anything that
|
|
283
|
+
* writes these frames (one JSON object per SSE `data:` line) gets the React transport, transcript
|
|
284
|
+
* model and hooks for free. Two rules keep it evolvable:
|
|
285
|
+
* - every frame is a JSON object with a string `kind`; a reader MUST tolerate kinds it does not
|
|
286
|
+
* know (the React transport forwards them as `data-<kind>` parts rather than dropping them);
|
|
287
|
+
* - fields are only ever added, and new fields are optional.
|
|
288
|
+
*/
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* A component the server pushed into the conversation: generative UI that is NOT a tool call's
|
|
292
|
+
* rendering. It is addressed by `component` (a key in the client's own component registry), never
|
|
293
|
+
* by a tool name, so a runner can emit one from anywhere — a tool body, a post-processing step, a
|
|
294
|
+
* sandboxed agent that renders through its own protocol.
|
|
295
|
+
*
|
|
296
|
+
* `id` is the component's identity within the message: a second frame with the same `id` REPLACES
|
|
297
|
+
* the first (streaming props into a chart, flipping a card from "loading" to "ready"), it never
|
|
298
|
+
* adds a second component.
|
|
299
|
+
*/
|
|
300
|
+
interface AgentUiComponent {
|
|
301
|
+
id: string;
|
|
302
|
+
/** Registry key the client resolves to its own renderer, e.g. `data-table`. */
|
|
303
|
+
component: string;
|
|
304
|
+
props: Record<string, unknown>;
|
|
305
|
+
/** Schema version of `props`, so a client can keep rendering components persisted by an older server. */
|
|
306
|
+
version?: number;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Who has to settle an action tool call, and until when. Metadata only: the call itself is still
|
|
310
|
+
* settled through the tool-call approve/reject routes, by its `toolCallId`.
|
|
311
|
+
*/
|
|
312
|
+
interface AgentApprovalRequest {
|
|
313
|
+
/** The tool call awaiting the decision — the `id` of a call already announced on this stream. */
|
|
314
|
+
id: string;
|
|
315
|
+
/**
|
|
316
|
+
* Who may decide. Open vocabulary the host defines — `'requester'` (the person chatting),
|
|
317
|
+
* `'admin'`, a role name, a team. A client uses it to say "waiting on an admin" instead of
|
|
318
|
+
* offering buttons the viewer cannot use.
|
|
319
|
+
*/
|
|
320
|
+
approver: string;
|
|
321
|
+
/** ISO-8601 instant after which the request lapses. Absent → it never expires. */
|
|
322
|
+
expiresAt?: string;
|
|
323
|
+
/** Why this call needs a person, in words for that person. */
|
|
324
|
+
reason?: string;
|
|
325
|
+
}
|
|
326
|
+
type AgentStreamEvent = {
|
|
327
|
+
kind: 'step-start';
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Closes the step opened by the matching `step-start`. Carries the model call's token usage and
|
|
331
|
+
* `costUsd` (an estimate from the bound pricing store, or `null` when unpriced/unbound — never a
|
|
332
|
+
* fabricated `0`) so a live client can render running cost without waiting for a thread re-fetch.
|
|
333
|
+
*/
|
|
334
|
+
| {
|
|
335
|
+
kind: 'step-finish';
|
|
336
|
+
usage?: MessageUsage;
|
|
337
|
+
costUsd?: number | null;
|
|
338
|
+
/**
|
|
339
|
+
* How long the model spent thinking in this step, in ms — the same number persisted as
|
|
340
|
+
* `StoredMessage.reasoningMs`, so a live thread and a reloaded one read the same duration.
|
|
341
|
+
* Absent when the step had no reasoning.
|
|
342
|
+
*/
|
|
343
|
+
reasoningMs?: number;
|
|
344
|
+
} | {
|
|
345
|
+
kind: 'text';
|
|
346
|
+
text: string;
|
|
347
|
+
} | {
|
|
348
|
+
kind: 'reasoning';
|
|
349
|
+
text: string;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* `toolKind` collapses `ToolKind`'s `'agent'` into `'read'` — delegation tools auto-execute like a read tool.
|
|
353
|
+
*
|
|
354
|
+
* `parentId` nests this call under another call on the same stream: the inner calls a code-mode
|
|
355
|
+
* `execute` makes, the tools a delegated sub-agent runs. The parent must be announced first. A
|
|
356
|
+
* call's parent is fixed by its first frame that names one; later frames may omit it.
|
|
357
|
+
*/
|
|
358
|
+
| {
|
|
359
|
+
kind: 'tool-input-start';
|
|
360
|
+
id: string;
|
|
361
|
+
name: string;
|
|
362
|
+
toolKind: 'read' | 'action';
|
|
363
|
+
parentId?: string;
|
|
364
|
+
} | {
|
|
365
|
+
kind: 'tool-input-delta';
|
|
366
|
+
id: string;
|
|
367
|
+
delta: string;
|
|
368
|
+
} | {
|
|
369
|
+
kind: 'tool-input-available';
|
|
370
|
+
id: string;
|
|
371
|
+
name: string;
|
|
372
|
+
input: unknown;
|
|
373
|
+
toolKind: 'read' | 'action';
|
|
374
|
+
/** Same as on `tool-input-start`, for a runner that announces a call without streaming its input. */
|
|
375
|
+
parentId?: string;
|
|
376
|
+
} | {
|
|
377
|
+
kind: 'tool-output';
|
|
378
|
+
id: string;
|
|
379
|
+
output: unknown;
|
|
380
|
+
} | {
|
|
381
|
+
kind: 'tool-output-error';
|
|
382
|
+
id: string;
|
|
383
|
+
error: string;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* A person was asked to approve an action tool and declined it. Its own frame, NOT
|
|
387
|
+
* `tool-output-error`: a refusal is a decision with a known outcome — nothing ran — while a
|
|
388
|
+
* failure is an outcome nobody chose and whose effects are unknown. Rendering them the same way
|
|
389
|
+
* tells an operator their own "no" was a malfunction. Maps onto the SDK's `output-denied` tool
|
|
390
|
+
* part state, which a client reads without knowing any tool's name.
|
|
391
|
+
*/
|
|
392
|
+
| {
|
|
393
|
+
kind: 'tool-output-denied';
|
|
394
|
+
id: string;
|
|
395
|
+
reason?: string;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* The run has put a question set to the user and is parked until someone answers it (or skips).
|
|
399
|
+
* Written by the LOOP for both elicitation surfaces — the configured intake and the model's `ask`
|
|
400
|
+
* tool — so a client renders one form either way rather than learning to recognise a tool name.
|
|
401
|
+
* The matching `tool-output` frame, under the same `id`, carries the settled answers.
|
|
402
|
+
*/
|
|
403
|
+
| {
|
|
404
|
+
kind: 'elicitation';
|
|
405
|
+
id: string;
|
|
406
|
+
request: ElicitationRequest;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* An action tool call (already announced by `tool-input-start`/`tool-input-available` under the
|
|
410
|
+
* same `id`) is parked on a person. Optional: a client still treats an `action` call stuck at
|
|
411
|
+
* its input as pending — this frame adds WHO has to decide and UNTIL WHEN, and moves the call
|
|
412
|
+
* into the AI SDK's native `approval-requested` state.
|
|
413
|
+
*/
|
|
414
|
+
| ({
|
|
415
|
+
kind: 'approval-requested';
|
|
416
|
+
} & AgentApprovalRequest)
|
|
417
|
+
/**
|
|
418
|
+
* Server-pushed generative UI, positioned in the message where it arrives. Not tied to a tool
|
|
419
|
+
* call. See {@link AgentUiComponent}.
|
|
420
|
+
*/
|
|
421
|
+
| ({
|
|
422
|
+
kind: 'ui';
|
|
423
|
+
} & AgentUiComponent)
|
|
424
|
+
/**
|
|
425
|
+
* The thread's title was set or changed while this run streamed (typically derived from the
|
|
426
|
+
* first exchange). Thread-level, not message content: a client updates its header/sidebar and
|
|
427
|
+
* does not render it in the transcript.
|
|
428
|
+
*/
|
|
429
|
+
| {
|
|
430
|
+
kind: 'title';
|
|
431
|
+
title: string;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Someone stopped this run. The stream's LAST frame, written by the runner that settled the
|
|
435
|
+
* cancel, immediately before a normal `end()` — never a `fail()`, because a cancel is not an
|
|
436
|
+
* error and a client that retries on a failed stream must not retry this.
|
|
437
|
+
*
|
|
438
|
+
* A run that simply ends wrote everything it had; one that ends after this frame did not, and the
|
|
439
|
+
* difference is the whole point: without it a reader cannot tell a truncated answer from a
|
|
440
|
+
* complete one. Consumers that predate the frame ignore it and see the `end()` they always saw.
|
|
441
|
+
*/
|
|
442
|
+
| {
|
|
443
|
+
kind: 'cancelled';
|
|
444
|
+
};
|
|
445
|
+
/** Encode one event as an NDJSON line (`{...}\n`) for {@link SinkWriter.write}. */
|
|
446
|
+
declare function encodeStreamEvent(event: AgentStreamEvent): Uint8Array;
|
|
447
|
+
/**
|
|
448
|
+
* Read one NDJSON line back, or `null` when the line is not a stream event at all.
|
|
449
|
+
*
|
|
450
|
+
* `null` covers a genuinely opaque chunk, not just malformed JSON: the sink is a byte channel, so a
|
|
451
|
+
* model provider is free to write anything into it and some write bare text. A caller that has to
|
|
452
|
+
* CLASSIFY a chunk — the output gate, which may only forward what it can prove is not the answer —
|
|
453
|
+
* treats an unreadable frame as unclassifiable rather than guessing.
|
|
454
|
+
*/
|
|
455
|
+
declare function decodeStreamEvent(line: string): AgentStreamEvent | null;
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* How a person-facing surface talks about a tool WITHOUT ever naming it. Declared on the server,
|
|
459
|
+
* beside the tool's input schema, because whoever changes the input is the one who has to re-word
|
|
460
|
+
* the sentence that mentions it — and a client that shipped its own name-to-sentence map would go
|
|
461
|
+
* stale the moment a tool was renamed. A tool name is an identifier, never copy.
|
|
462
|
+
*
|
|
463
|
+
* `running` / `done` (and `confirm.title`, `confirm.detail`, `result.text`) are templates:
|
|
464
|
+
* `{dotted.path}` placeholders are filled from the call's INPUT (or, for `result`, its OUTPUT), so one
|
|
465
|
+
* declaration covers every call the tool will ever receive and replays identically from history.
|
|
466
|
+
* A placeholder with nothing behind it collapses along with the space before it.
|
|
467
|
+
*/
|
|
468
|
+
interface ToolPresentation {
|
|
469
|
+
/** Noun phrase, for counts and headings: "Database query", "Knowledge base". */
|
|
470
|
+
label: string;
|
|
471
|
+
/** Present progressive, while the call is in flight: "Reading {bucket}". */
|
|
472
|
+
running: string;
|
|
473
|
+
/** Settled, once the output is in: "Read {bucket}". */
|
|
474
|
+
done: string;
|
|
475
|
+
/** A key into the client's own glyph map (`database`, `search`, …). Unknown keys fall back to a generic glyph there. */
|
|
476
|
+
icon?: string;
|
|
477
|
+
/** One line naming what the tool reaches, for when the activity line is opened. */
|
|
478
|
+
detail?: string;
|
|
479
|
+
/** `destructive` earns the warning treatment on an approval prompt. */
|
|
480
|
+
tone?: ToolPresentationTone;
|
|
481
|
+
/** What a person is being asked to allow when an `action` call parks for approval. */
|
|
482
|
+
confirm?: ToolConfirmation;
|
|
483
|
+
/** How the call's OUTPUT reads as content. */
|
|
484
|
+
result?: ToolResultView;
|
|
485
|
+
}
|
|
486
|
+
type ToolPresentationTone = 'neutral' | 'destructive';
|
|
487
|
+
interface ToolConfirmation {
|
|
488
|
+
/** "Delete {count} files?" */
|
|
489
|
+
title: string;
|
|
490
|
+
/** The button: "Delete". */
|
|
491
|
+
verb: string;
|
|
492
|
+
/** A sentence under the title, when the title alone does not say what changes. */
|
|
493
|
+
detail?: string;
|
|
494
|
+
}
|
|
495
|
+
/** A value read out of a tool's output by dotted path, with the words to put next to it. */
|
|
496
|
+
interface ToolResultField {
|
|
497
|
+
path: string;
|
|
498
|
+
label: string;
|
|
499
|
+
unit?: string;
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* How a tool's output reads as content. Every variant names dotted paths into the output rather
|
|
503
|
+
* than shapes, so a renderer never has to recognise which tool it is drawing: it receives
|
|
504
|
+
* `{ view, output }` and draws it.
|
|
505
|
+
*/
|
|
506
|
+
type ToolResultView =
|
|
507
|
+
/** A row of labelled readings — one result, several facets. */
|
|
508
|
+
{
|
|
509
|
+
kind: 'metrics';
|
|
510
|
+
fields: ToolResultField[];
|
|
511
|
+
}
|
|
512
|
+
/** `rows` is a path to an array; each column's `path` is read WITHIN a row. */
|
|
513
|
+
| {
|
|
514
|
+
kind: 'table';
|
|
515
|
+
columns: ToolResultField[];
|
|
516
|
+
rows: string;
|
|
517
|
+
empty?: string;
|
|
518
|
+
}
|
|
519
|
+
/** `lines` is a path to an array of strings, drawn as a log tail. */
|
|
520
|
+
| {
|
|
521
|
+
kind: 'log';
|
|
522
|
+
lines: string;
|
|
523
|
+
}
|
|
524
|
+
/** One sentence, templated over the output. */
|
|
525
|
+
| {
|
|
526
|
+
kind: 'note';
|
|
527
|
+
text: string;
|
|
528
|
+
}
|
|
529
|
+
/** The output is drawn somewhere else on the screen already (a pushed component, a side panel). */
|
|
530
|
+
| {
|
|
531
|
+
kind: 'elsewhere';
|
|
532
|
+
};
|
|
533
|
+
/**
|
|
534
|
+
* One tool as `GET <base>/tools` reports it: the tools THIS actor may be offered by the chosen agent,
|
|
535
|
+
* with how each is spoken about. `presentation` is absent for a tool that declared none — a client
|
|
536
|
+
* then narrates it generically rather than falling back to its name.
|
|
537
|
+
*/
|
|
538
|
+
interface ToolCatalogEntry {
|
|
539
|
+
/** The wire name tool parts carry (`tool-<name>`) — the key a client looks a call up by. */
|
|
540
|
+
name: string;
|
|
541
|
+
kind: ToolKind;
|
|
542
|
+
presentation?: ToolPresentation;
|
|
543
|
+
}
|
|
544
|
+
|
|
269
545
|
/**
|
|
270
546
|
* Transient tool-error classification + the retry loop that wraps a tool's own invocation. A
|
|
271
547
|
* classified-transient error (a DB deadlock, a lock-wait timeout, a serialization failure) means
|
|
@@ -385,6 +661,11 @@ interface ToolSpec {
|
|
|
385
661
|
name: string;
|
|
386
662
|
kind: ToolKind;
|
|
387
663
|
description: string;
|
|
664
|
+
/**
|
|
665
|
+
* How a person-facing surface talks about this tool (see {@link ToolPresentation}). Never shown
|
|
666
|
+
* to the model; served to clients by `GET <base>/tools`.
|
|
667
|
+
*/
|
|
668
|
+
presentation?: ToolPresentation;
|
|
388
669
|
/**
|
|
389
670
|
* Input schema as a [Standard Schema](https://standardschema.dev) — validation-agnostic, so
|
|
390
671
|
* Zod, Valibot, or ArkType all work. The loop validates input via `~standard.validate` before
|
|
@@ -750,6 +1031,19 @@ interface StoredMessage {
|
|
|
750
1031
|
usage?: MessageUsage;
|
|
751
1032
|
/** The run (turn) that produced this message; absent on a row written before this was recorded. */
|
|
752
1033
|
runId?: string;
|
|
1034
|
+
/**
|
|
1035
|
+
* The model's thinking for this step, as it streamed (`reasoning` frames), so a reloaded thread
|
|
1036
|
+
* shows it where the live one did. Absent when the model produced none, or on a row written
|
|
1037
|
+
* before this was recorded.
|
|
1038
|
+
*/
|
|
1039
|
+
reasoning?: string;
|
|
1040
|
+
/** How long the model spent thinking in this step, in ms — what a "Thought for 4s" label reads. */
|
|
1041
|
+
reasoningMs?: number;
|
|
1042
|
+
/**
|
|
1043
|
+
* Components the server pushed into this step (`ui` frames), in first-seen order with the last
|
|
1044
|
+
* props for each `id` — a reloaded thread replays them as `data-ui` parts.
|
|
1045
|
+
*/
|
|
1046
|
+
ui?: AgentUiComponent[];
|
|
753
1047
|
createdAt: string;
|
|
754
1048
|
}
|
|
755
1049
|
interface ThreadDetail extends ThreadSummary {
|
|
@@ -1011,4 +1305,4 @@ interface ToolHandler<I = unknown> {
|
|
|
1011
1305
|
canUse?(actor: Actor): boolean | Promise<boolean>;
|
|
1012
1306
|
}
|
|
1013
1307
|
|
|
1014
|
-
export { type
|
|
1308
|
+
export { type HistoryPolicyContext as $, type Actor as A, type AgentApprovalRequest as B, type AgentCatalogEntry as C, type DetachedDelivery as D, type ElicitationRequest as E, type AgentHistoryWindow as F, type AgentStreamEvent as G, type HumanReply as H, type InputProcessor as I, type AskToolInput as J, DEFAULT_INCREMENTAL_LOOKBACK_CHARS as K, type LlmStepEnvelope as L, type ModelMessage as M, DEFAULT_INTAKE_PREAMBLE as N, type OutputProcessor as O, type ProcessorContext as P, type QuotaState as Q, DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS as R, type StoredMessage as S, type ToolHandler as T, type UsagePurpose as U, DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS as V, type ElicitationOption as W, type ElicitationOutcome as X, type ElicitationQuestion as Y, type ElicitationReply as Z, type ElicitationResult as _, type ToolDefinition as a, type HistorySelection as a0, type HistorySummary as a1, type IncrementalGating as a2, type InvokeWithTransientRetryOptions as a3, MAX_ASK_QUESTIONS as a4, type MessageRole as a5, OutputRejectedError as a6, type OutputVerdict as a7, ProcessorFailedError as a8, type PromptContext as a9, type QuotaView as aa, type ToolCatalogEntry as ab, type ToolConfirmation as ac, type ToolKind as ad, type ToolPresentation as ae, type ToolPresentationTone as af, type ToolResultField as ag, type ToolResultView as ah, type ToolStepCtx as ai, type ToolTransientRetryNumbers as aj, type ToolTransientRetryOptions as ak, askInputSchema as al, askToolDefinition as am, decodeStreamEvent as an, encodeStreamEvent as ao, invokeWithTransientRetry as ap, isTransientToolError as aq, normalizeElicitationReply as ar, renderElicitationAnswers as as, resolveElicitation as at, resolveToolTransientRetryNumbers as au, settleElicitation as av, type ToolCallRequest as b, type MessageUsage as c, type AgentUiComponent as d, type ThreadSummary as e, type ThreadDetail as f, type ToolResult as g, type MessageAttachment as h, type ToolCallStatus as i, type ToolSpec as j, type AgentRunInput as k, type HistoryPolicy as l, type ProcessedPrompt as m, type ModelAnswer as n, type PageContext as o, type AgentDefinition as p, type AgentDelegation as q, type AiToolCtx as r, type PromptBuilder as s, type PromptContributor as t, type ToolTransientRetrySetting as u, type AgentIntake as v, type Decision as w, type ToolStepEnvelope as x, ASK_TOOL_DESCRIPTION as y, ASK_TOOL_NAME as z };
|
|
@@ -266,6 +266,282 @@ interface AgentHistoryWindow {
|
|
|
266
266
|
summarize?: boolean;
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
+
/**
|
|
270
|
+
* The structured live-stream vocabulary carried over the {@link SinkWriter} byte channel.
|
|
271
|
+
*
|
|
272
|
+
* The model turn (via the AI-SDK adapter) and the agent loop write these events as NDJSON — one
|
|
273
|
+
* `JSON.stringify(event)\n` per {@link SinkWriter.write}. The HTTP layer forwards each line as an
|
|
274
|
+
* SSE `data:` frame, and the client transport maps them back to the AI SDK UI-message chunk
|
|
275
|
+
* protocol so the browser renders text, reasoning, and tool cards (input + output) LIVE — the same
|
|
276
|
+
* rich rendering a raw `streamText().toUIMessageStream()` would give, but reconstructed on the
|
|
277
|
+
* client so the sink stays a format-agnostic byte buffer (durable buffering/replay is untouched).
|
|
278
|
+
*
|
|
279
|
+
* Keeping this vocabulary neutral (not AI-SDK `UIMessageChunk`) means core never depends on `ai`:
|
|
280
|
+
* the adapter owns model-parts → event, the transport owns event → UI-chunk.
|
|
281
|
+
*
|
|
282
|
+
* The vocabulary is also a CONTRACT for runners that are not this library's loop: anything that
|
|
283
|
+
* writes these frames (one JSON object per SSE `data:` line) gets the React transport, transcript
|
|
284
|
+
* model and hooks for free. Two rules keep it evolvable:
|
|
285
|
+
* - every frame is a JSON object with a string `kind`; a reader MUST tolerate kinds it does not
|
|
286
|
+
* know (the React transport forwards them as `data-<kind>` parts rather than dropping them);
|
|
287
|
+
* - fields are only ever added, and new fields are optional.
|
|
288
|
+
*/
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* A component the server pushed into the conversation: generative UI that is NOT a tool call's
|
|
292
|
+
* rendering. It is addressed by `component` (a key in the client's own component registry), never
|
|
293
|
+
* by a tool name, so a runner can emit one from anywhere — a tool body, a post-processing step, a
|
|
294
|
+
* sandboxed agent that renders through its own protocol.
|
|
295
|
+
*
|
|
296
|
+
* `id` is the component's identity within the message: a second frame with the same `id` REPLACES
|
|
297
|
+
* the first (streaming props into a chart, flipping a card from "loading" to "ready"), it never
|
|
298
|
+
* adds a second component.
|
|
299
|
+
*/
|
|
300
|
+
interface AgentUiComponent {
|
|
301
|
+
id: string;
|
|
302
|
+
/** Registry key the client resolves to its own renderer, e.g. `data-table`. */
|
|
303
|
+
component: string;
|
|
304
|
+
props: Record<string, unknown>;
|
|
305
|
+
/** Schema version of `props`, so a client can keep rendering components persisted by an older server. */
|
|
306
|
+
version?: number;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Who has to settle an action tool call, and until when. Metadata only: the call itself is still
|
|
310
|
+
* settled through the tool-call approve/reject routes, by its `toolCallId`.
|
|
311
|
+
*/
|
|
312
|
+
interface AgentApprovalRequest {
|
|
313
|
+
/** The tool call awaiting the decision — the `id` of a call already announced on this stream. */
|
|
314
|
+
id: string;
|
|
315
|
+
/**
|
|
316
|
+
* Who may decide. Open vocabulary the host defines — `'requester'` (the person chatting),
|
|
317
|
+
* `'admin'`, a role name, a team. A client uses it to say "waiting on an admin" instead of
|
|
318
|
+
* offering buttons the viewer cannot use.
|
|
319
|
+
*/
|
|
320
|
+
approver: string;
|
|
321
|
+
/** ISO-8601 instant after which the request lapses. Absent → it never expires. */
|
|
322
|
+
expiresAt?: string;
|
|
323
|
+
/** Why this call needs a person, in words for that person. */
|
|
324
|
+
reason?: string;
|
|
325
|
+
}
|
|
326
|
+
type AgentStreamEvent = {
|
|
327
|
+
kind: 'step-start';
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Closes the step opened by the matching `step-start`. Carries the model call's token usage and
|
|
331
|
+
* `costUsd` (an estimate from the bound pricing store, or `null` when unpriced/unbound — never a
|
|
332
|
+
* fabricated `0`) so a live client can render running cost without waiting for a thread re-fetch.
|
|
333
|
+
*/
|
|
334
|
+
| {
|
|
335
|
+
kind: 'step-finish';
|
|
336
|
+
usage?: MessageUsage;
|
|
337
|
+
costUsd?: number | null;
|
|
338
|
+
/**
|
|
339
|
+
* How long the model spent thinking in this step, in ms — the same number persisted as
|
|
340
|
+
* `StoredMessage.reasoningMs`, so a live thread and a reloaded one read the same duration.
|
|
341
|
+
* Absent when the step had no reasoning.
|
|
342
|
+
*/
|
|
343
|
+
reasoningMs?: number;
|
|
344
|
+
} | {
|
|
345
|
+
kind: 'text';
|
|
346
|
+
text: string;
|
|
347
|
+
} | {
|
|
348
|
+
kind: 'reasoning';
|
|
349
|
+
text: string;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* `toolKind` collapses `ToolKind`'s `'agent'` into `'read'` — delegation tools auto-execute like a read tool.
|
|
353
|
+
*
|
|
354
|
+
* `parentId` nests this call under another call on the same stream: the inner calls a code-mode
|
|
355
|
+
* `execute` makes, the tools a delegated sub-agent runs. The parent must be announced first. A
|
|
356
|
+
* call's parent is fixed by its first frame that names one; later frames may omit it.
|
|
357
|
+
*/
|
|
358
|
+
| {
|
|
359
|
+
kind: 'tool-input-start';
|
|
360
|
+
id: string;
|
|
361
|
+
name: string;
|
|
362
|
+
toolKind: 'read' | 'action';
|
|
363
|
+
parentId?: string;
|
|
364
|
+
} | {
|
|
365
|
+
kind: 'tool-input-delta';
|
|
366
|
+
id: string;
|
|
367
|
+
delta: string;
|
|
368
|
+
} | {
|
|
369
|
+
kind: 'tool-input-available';
|
|
370
|
+
id: string;
|
|
371
|
+
name: string;
|
|
372
|
+
input: unknown;
|
|
373
|
+
toolKind: 'read' | 'action';
|
|
374
|
+
/** Same as on `tool-input-start`, for a runner that announces a call without streaming its input. */
|
|
375
|
+
parentId?: string;
|
|
376
|
+
} | {
|
|
377
|
+
kind: 'tool-output';
|
|
378
|
+
id: string;
|
|
379
|
+
output: unknown;
|
|
380
|
+
} | {
|
|
381
|
+
kind: 'tool-output-error';
|
|
382
|
+
id: string;
|
|
383
|
+
error: string;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* A person was asked to approve an action tool and declined it. Its own frame, NOT
|
|
387
|
+
* `tool-output-error`: a refusal is a decision with a known outcome — nothing ran — while a
|
|
388
|
+
* failure is an outcome nobody chose and whose effects are unknown. Rendering them the same way
|
|
389
|
+
* tells an operator their own "no" was a malfunction. Maps onto the SDK's `output-denied` tool
|
|
390
|
+
* part state, which a client reads without knowing any tool's name.
|
|
391
|
+
*/
|
|
392
|
+
| {
|
|
393
|
+
kind: 'tool-output-denied';
|
|
394
|
+
id: string;
|
|
395
|
+
reason?: string;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* The run has put a question set to the user and is parked until someone answers it (or skips).
|
|
399
|
+
* Written by the LOOP for both elicitation surfaces — the configured intake and the model's `ask`
|
|
400
|
+
* tool — so a client renders one form either way rather than learning to recognise a tool name.
|
|
401
|
+
* The matching `tool-output` frame, under the same `id`, carries the settled answers.
|
|
402
|
+
*/
|
|
403
|
+
| {
|
|
404
|
+
kind: 'elicitation';
|
|
405
|
+
id: string;
|
|
406
|
+
request: ElicitationRequest;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* An action tool call (already announced by `tool-input-start`/`tool-input-available` under the
|
|
410
|
+
* same `id`) is parked on a person. Optional: a client still treats an `action` call stuck at
|
|
411
|
+
* its input as pending — this frame adds WHO has to decide and UNTIL WHEN, and moves the call
|
|
412
|
+
* into the AI SDK's native `approval-requested` state.
|
|
413
|
+
*/
|
|
414
|
+
| ({
|
|
415
|
+
kind: 'approval-requested';
|
|
416
|
+
} & AgentApprovalRequest)
|
|
417
|
+
/**
|
|
418
|
+
* Server-pushed generative UI, positioned in the message where it arrives. Not tied to a tool
|
|
419
|
+
* call. See {@link AgentUiComponent}.
|
|
420
|
+
*/
|
|
421
|
+
| ({
|
|
422
|
+
kind: 'ui';
|
|
423
|
+
} & AgentUiComponent)
|
|
424
|
+
/**
|
|
425
|
+
* The thread's title was set or changed while this run streamed (typically derived from the
|
|
426
|
+
* first exchange). Thread-level, not message content: a client updates its header/sidebar and
|
|
427
|
+
* does not render it in the transcript.
|
|
428
|
+
*/
|
|
429
|
+
| {
|
|
430
|
+
kind: 'title';
|
|
431
|
+
title: string;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Someone stopped this run. The stream's LAST frame, written by the runner that settled the
|
|
435
|
+
* cancel, immediately before a normal `end()` — never a `fail()`, because a cancel is not an
|
|
436
|
+
* error and a client that retries on a failed stream must not retry this.
|
|
437
|
+
*
|
|
438
|
+
* A run that simply ends wrote everything it had; one that ends after this frame did not, and the
|
|
439
|
+
* difference is the whole point: without it a reader cannot tell a truncated answer from a
|
|
440
|
+
* complete one. Consumers that predate the frame ignore it and see the `end()` they always saw.
|
|
441
|
+
*/
|
|
442
|
+
| {
|
|
443
|
+
kind: 'cancelled';
|
|
444
|
+
};
|
|
445
|
+
/** Encode one event as an NDJSON line (`{...}\n`) for {@link SinkWriter.write}. */
|
|
446
|
+
declare function encodeStreamEvent(event: AgentStreamEvent): Uint8Array;
|
|
447
|
+
/**
|
|
448
|
+
* Read one NDJSON line back, or `null` when the line is not a stream event at all.
|
|
449
|
+
*
|
|
450
|
+
* `null` covers a genuinely opaque chunk, not just malformed JSON: the sink is a byte channel, so a
|
|
451
|
+
* model provider is free to write anything into it and some write bare text. A caller that has to
|
|
452
|
+
* CLASSIFY a chunk — the output gate, which may only forward what it can prove is not the answer —
|
|
453
|
+
* treats an unreadable frame as unclassifiable rather than guessing.
|
|
454
|
+
*/
|
|
455
|
+
declare function decodeStreamEvent(line: string): AgentStreamEvent | null;
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* How a person-facing surface talks about a tool WITHOUT ever naming it. Declared on the server,
|
|
459
|
+
* beside the tool's input schema, because whoever changes the input is the one who has to re-word
|
|
460
|
+
* the sentence that mentions it — and a client that shipped its own name-to-sentence map would go
|
|
461
|
+
* stale the moment a tool was renamed. A tool name is an identifier, never copy.
|
|
462
|
+
*
|
|
463
|
+
* `running` / `done` (and `confirm.title`, `confirm.detail`, `result.text`) are templates:
|
|
464
|
+
* `{dotted.path}` placeholders are filled from the call's INPUT (or, for `result`, its OUTPUT), so one
|
|
465
|
+
* declaration covers every call the tool will ever receive and replays identically from history.
|
|
466
|
+
* A placeholder with nothing behind it collapses along with the space before it.
|
|
467
|
+
*/
|
|
468
|
+
interface ToolPresentation {
|
|
469
|
+
/** Noun phrase, for counts and headings: "Database query", "Knowledge base". */
|
|
470
|
+
label: string;
|
|
471
|
+
/** Present progressive, while the call is in flight: "Reading {bucket}". */
|
|
472
|
+
running: string;
|
|
473
|
+
/** Settled, once the output is in: "Read {bucket}". */
|
|
474
|
+
done: string;
|
|
475
|
+
/** A key into the client's own glyph map (`database`, `search`, …). Unknown keys fall back to a generic glyph there. */
|
|
476
|
+
icon?: string;
|
|
477
|
+
/** One line naming what the tool reaches, for when the activity line is opened. */
|
|
478
|
+
detail?: string;
|
|
479
|
+
/** `destructive` earns the warning treatment on an approval prompt. */
|
|
480
|
+
tone?: ToolPresentationTone;
|
|
481
|
+
/** What a person is being asked to allow when an `action` call parks for approval. */
|
|
482
|
+
confirm?: ToolConfirmation;
|
|
483
|
+
/** How the call's OUTPUT reads as content. */
|
|
484
|
+
result?: ToolResultView;
|
|
485
|
+
}
|
|
486
|
+
type ToolPresentationTone = 'neutral' | 'destructive';
|
|
487
|
+
interface ToolConfirmation {
|
|
488
|
+
/** "Delete {count} files?" */
|
|
489
|
+
title: string;
|
|
490
|
+
/** The button: "Delete". */
|
|
491
|
+
verb: string;
|
|
492
|
+
/** A sentence under the title, when the title alone does not say what changes. */
|
|
493
|
+
detail?: string;
|
|
494
|
+
}
|
|
495
|
+
/** A value read out of a tool's output by dotted path, with the words to put next to it. */
|
|
496
|
+
interface ToolResultField {
|
|
497
|
+
path: string;
|
|
498
|
+
label: string;
|
|
499
|
+
unit?: string;
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* How a tool's output reads as content. Every variant names dotted paths into the output rather
|
|
503
|
+
* than shapes, so a renderer never has to recognise which tool it is drawing: it receives
|
|
504
|
+
* `{ view, output }` and draws it.
|
|
505
|
+
*/
|
|
506
|
+
type ToolResultView =
|
|
507
|
+
/** A row of labelled readings — one result, several facets. */
|
|
508
|
+
{
|
|
509
|
+
kind: 'metrics';
|
|
510
|
+
fields: ToolResultField[];
|
|
511
|
+
}
|
|
512
|
+
/** `rows` is a path to an array; each column's `path` is read WITHIN a row. */
|
|
513
|
+
| {
|
|
514
|
+
kind: 'table';
|
|
515
|
+
columns: ToolResultField[];
|
|
516
|
+
rows: string;
|
|
517
|
+
empty?: string;
|
|
518
|
+
}
|
|
519
|
+
/** `lines` is a path to an array of strings, drawn as a log tail. */
|
|
520
|
+
| {
|
|
521
|
+
kind: 'log';
|
|
522
|
+
lines: string;
|
|
523
|
+
}
|
|
524
|
+
/** One sentence, templated over the output. */
|
|
525
|
+
| {
|
|
526
|
+
kind: 'note';
|
|
527
|
+
text: string;
|
|
528
|
+
}
|
|
529
|
+
/** The output is drawn somewhere else on the screen already (a pushed component, a side panel). */
|
|
530
|
+
| {
|
|
531
|
+
kind: 'elsewhere';
|
|
532
|
+
};
|
|
533
|
+
/**
|
|
534
|
+
* One tool as `GET <base>/tools` reports it: the tools THIS actor may be offered by the chosen agent,
|
|
535
|
+
* with how each is spoken about. `presentation` is absent for a tool that declared none — a client
|
|
536
|
+
* then narrates it generically rather than falling back to its name.
|
|
537
|
+
*/
|
|
538
|
+
interface ToolCatalogEntry {
|
|
539
|
+
/** The wire name tool parts carry (`tool-<name>`) — the key a client looks a call up by. */
|
|
540
|
+
name: string;
|
|
541
|
+
kind: ToolKind;
|
|
542
|
+
presentation?: ToolPresentation;
|
|
543
|
+
}
|
|
544
|
+
|
|
269
545
|
/**
|
|
270
546
|
* Transient tool-error classification + the retry loop that wraps a tool's own invocation. A
|
|
271
547
|
* classified-transient error (a DB deadlock, a lock-wait timeout, a serialization failure) means
|
|
@@ -385,6 +661,11 @@ interface ToolSpec {
|
|
|
385
661
|
name: string;
|
|
386
662
|
kind: ToolKind;
|
|
387
663
|
description: string;
|
|
664
|
+
/**
|
|
665
|
+
* How a person-facing surface talks about this tool (see {@link ToolPresentation}). Never shown
|
|
666
|
+
* to the model; served to clients by `GET <base>/tools`.
|
|
667
|
+
*/
|
|
668
|
+
presentation?: ToolPresentation;
|
|
388
669
|
/**
|
|
389
670
|
* Input schema as a [Standard Schema](https://standardschema.dev) — validation-agnostic, so
|
|
390
671
|
* Zod, Valibot, or ArkType all work. The loop validates input via `~standard.validate` before
|
|
@@ -750,6 +1031,19 @@ interface StoredMessage {
|
|
|
750
1031
|
usage?: MessageUsage;
|
|
751
1032
|
/** The run (turn) that produced this message; absent on a row written before this was recorded. */
|
|
752
1033
|
runId?: string;
|
|
1034
|
+
/**
|
|
1035
|
+
* The model's thinking for this step, as it streamed (`reasoning` frames), so a reloaded thread
|
|
1036
|
+
* shows it where the live one did. Absent when the model produced none, or on a row written
|
|
1037
|
+
* before this was recorded.
|
|
1038
|
+
*/
|
|
1039
|
+
reasoning?: string;
|
|
1040
|
+
/** How long the model spent thinking in this step, in ms — what a "Thought for 4s" label reads. */
|
|
1041
|
+
reasoningMs?: number;
|
|
1042
|
+
/**
|
|
1043
|
+
* Components the server pushed into this step (`ui` frames), in first-seen order with the last
|
|
1044
|
+
* props for each `id` — a reloaded thread replays them as `data-ui` parts.
|
|
1045
|
+
*/
|
|
1046
|
+
ui?: AgentUiComponent[];
|
|
753
1047
|
createdAt: string;
|
|
754
1048
|
}
|
|
755
1049
|
interface ThreadDetail extends ThreadSummary {
|
|
@@ -1011,4 +1305,4 @@ interface ToolHandler<I = unknown> {
|
|
|
1011
1305
|
canUse?(actor: Actor): boolean | Promise<boolean>;
|
|
1012
1306
|
}
|
|
1013
1307
|
|
|
1014
|
-
export { type
|
|
1308
|
+
export { type HistoryPolicyContext as $, type Actor as A, type AgentApprovalRequest as B, type AgentCatalogEntry as C, type DetachedDelivery as D, type ElicitationRequest as E, type AgentHistoryWindow as F, type AgentStreamEvent as G, type HumanReply as H, type InputProcessor as I, type AskToolInput as J, DEFAULT_INCREMENTAL_LOOKBACK_CHARS as K, type LlmStepEnvelope as L, type ModelMessage as M, DEFAULT_INTAKE_PREAMBLE as N, type OutputProcessor as O, type ProcessorContext as P, type QuotaState as Q, DEFAULT_TOOL_TRANSIENT_RETRY_ATTEMPTS as R, type StoredMessage as S, type ToolHandler as T, type UsagePurpose as U, DEFAULT_TOOL_TRANSIENT_RETRY_BACKOFF_MS as V, type ElicitationOption as W, type ElicitationOutcome as X, type ElicitationQuestion as Y, type ElicitationReply as Z, type ElicitationResult as _, type ToolDefinition as a, type HistorySelection as a0, type HistorySummary as a1, type IncrementalGating as a2, type InvokeWithTransientRetryOptions as a3, MAX_ASK_QUESTIONS as a4, type MessageRole as a5, OutputRejectedError as a6, type OutputVerdict as a7, ProcessorFailedError as a8, type PromptContext as a9, type QuotaView as aa, type ToolCatalogEntry as ab, type ToolConfirmation as ac, type ToolKind as ad, type ToolPresentation as ae, type ToolPresentationTone as af, type ToolResultField as ag, type ToolResultView as ah, type ToolStepCtx as ai, type ToolTransientRetryNumbers as aj, type ToolTransientRetryOptions as ak, askInputSchema as al, askToolDefinition as am, decodeStreamEvent as an, encodeStreamEvent as ao, invokeWithTransientRetry as ap, isTransientToolError as aq, normalizeElicitationReply as ar, renderElicitationAnswers as as, resolveElicitation as at, resolveToolTransientRetryNumbers as au, settleElicitation as av, type ToolCallRequest as b, type MessageUsage as c, type AgentUiComponent as d, type ThreadSummary as e, type ThreadDetail as f, type ToolResult as g, type MessageAttachment as h, type ToolCallStatus as i, type ToolSpec as j, type AgentRunInput as k, type HistoryPolicy as l, type ProcessedPrompt as m, type ModelAnswer as n, type PageContext as o, type AgentDefinition as p, type AgentDelegation as q, type AiToolCtx as r, type PromptBuilder as s, type PromptContributor as t, type ToolTransientRetrySetting as u, type AgentIntake as v, type Decision as w, type ToolStepEnvelope as x, ASK_TOOL_DESCRIPTION as y, ASK_TOOL_NAME as z };
|