@datalayer/agent-runtimes 1.5.25 → 1.5.27

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.
@@ -1,39 +1,73 @@
1
1
  /**
2
- * A conversation as a run stream builds it, for a client that draws it
3
- * natively (Datalayer Mobile): one pure reducer over the AG-UI events of an
4
- * application's session or an agent's run, and the person's own actions.
2
+ * A conversation as a run stream builds it, for every client that draws one:
3
+ * the web chat (`ChatBase`) and Datalayer Mobile. One pure reducer over the
4
+ * AG-UI events of an application's session or an agent's run, the events
5
+ * every other protocol adapter is normalised into (`portable/adapterEvents`),
6
+ * and the person's own actions.
5
7
  *
6
- * It reads the stream as the web chat reads it — `TEXT_MESSAGE_*` into one
8
+ * It reads the stream as the chat reads it — `TEXT_MESSAGE_*` into one
7
9
  * message streamed in place, `TOOL_CALL_*` into a collapsed row whose result
8
10
  * is read by `toolResultOf`, `STEP_*` into a step row, a `MESSAGES_SNAPSHOT`
9
- * through `messagesOfThread`, a `reactor.ui` op on the run refused — and adds
10
- * what a session says besides: `loop.session`, the question its application
11
- * asks (`RUN_FINISHED` with `result.asking`, LOOP `loop.ask`), and a turn
12
- * that ended without words said by how it ended (`answered`, `stopped`,
13
- * `gone`).
11
+ * (its tool calls and their results too) through `messagesOfThread`, a
12
+ * `reactor.ui` op on the run refused — and adds what a session says besides:
13
+ * `loop.session`, the question its application asks (`RUN_FINISHED` with
14
+ * `result.asking`, LOOP `loop.ask`), and a turn that ended without words said
15
+ * by how it ended (`answered`, `stopped`, `gone`).
16
+ *
17
+ * An adapter that tells a message or a tool call whole rather than by its
18
+ * deltas — A2A, Vercel AI, ACP, the in-page agent, and the web's AG-UI
19
+ * adapter, which accumulates — says it with three events of this reducer's
20
+ * own, never AG-UI's: `MESSAGE_SAID` (a message's words so far),
21
+ * `TOOL_CALL_SAID` (a call's arguments as an object) and `TOOL_CALL_DONE`
22
+ * (its result as a value). They are refused when malformed.
14
23
  *
15
24
  * Bounded: a long tool run cannot grow it without end. Each tool's arguments
16
- * and result keep their first `TOOL_TEXT_LIMIT` characters, an answer its
17
- * first `MESSAGE_TEXT_LIMIT`, the conversation its last `ITEM_LIMIT` rows
18
- * (`dropped` counts the rest), and an event it does not draw is kept only as
19
- * its type and name, the last `DIAGNOSTIC_LIMIT` of them — never its payload.
25
+ * and result keep their first `limits.toolText` characters (their values only
26
+ * when kept whole), an answer its first `limits.messageText`, the
27
+ * conversation its last `limits.items` rows (`dropped` counts the rest), and
28
+ * an event it does not draw is kept only as its type and name, the last
29
+ * `limits.diagnostics` of them — never its payload. A phone keeps
30
+ * `DEVICE_LIMITS`, a browser `BROWSER_LIMITS`.
20
31
  *
21
32
  * @module portable/conversation
22
33
  */
23
34
  import { type AgUiEvent } from './agui';
24
35
  import { type ProtocolDisplay } from './displays';
25
- /** How many rows a conversation keeps: its newest. */
36
+ /** How many rows a conversation on a phone keeps: its newest. */
26
37
  export declare const ITEM_LIMIT = 400;
27
- /** How many characters of an answer are kept. */
38
+ /** How many characters of an answer a phone keeps. */
28
39
  export declare const MESSAGE_TEXT_LIMIT = 100000;
29
- /** How many characters of a tool's arguments, and of its result, are kept. */
40
+ /** How many characters of a tool's arguments, and of its result, a phone keeps. */
30
41
  export declare const TOOL_TEXT_LIMIT = 4000;
31
42
  /** How many events it does not draw are kept, by type and name. */
32
43
  export declare const DIAGNOSTIC_LIMIT = 50;
44
+ /** What a conversation keeps: the bounds of the device that holds it. */
45
+ export type ConversationLimits = {
46
+ /** Rows: its newest. */
47
+ items: number;
48
+ /** Characters of an answer. */
49
+ messageText: number;
50
+ /** Characters of a tool's arguments, and of its result. */
51
+ toolText: number;
52
+ /** Events it does not draw, by type and name. */
53
+ diagnostics: number;
54
+ };
55
+ /** A phone's bounds (Datalayer Mobile). */
56
+ export declare const DEVICE_LIMITS: ConversationLimits;
57
+ /** A browser's bounds (the web chat): a long working session, still bounded. */
58
+ export declare const BROWSER_LIMITS: ConversationLimits;
33
59
  /** What is said after a text cut at its limit. */
34
60
  export declare const CUT_MARK = "\u2026 (cut: too long to keep on this device)";
35
61
  /** How a turn ended without words of its own: `RUN_END_WORDS`'s. */
36
62
  export type TurnEnd = 'answered' | 'stopped' | 'gone';
63
+ /** What a running tool call waits for: a decision on its approval, or the person's answer. */
64
+ export type ToolAwaiting = 'approval' | 'person';
65
+ /** A Python exception a tool's code raised. */
66
+ export type ToolCodeError = {
67
+ name: string;
68
+ value: string;
69
+ traceback: string;
70
+ };
37
71
  /** One row of a conversation. */
38
72
  export type ConversationItem = {
39
73
  kind: 'message';
@@ -48,10 +82,22 @@ export type ConversationItem = {
48
82
  name: string;
49
83
  /** Its arguments as they streamed: JSON, cut at its limit. */
50
84
  args: string;
85
+ /** Its arguments read whole, or `null`: not yet whole, or cut. */
86
+ input: Record<string, unknown> | null;
51
87
  status: 'running' | 'complete' | 'error';
88
+ /** While running, what it waits for; else `null`. */
89
+ awaiting: ToolAwaiting | null;
52
90
  /** Its result in words, cut at its limit. */
53
91
  result: string;
92
+ /** Its result as given, what a renderer draws: `undefined` when none, or when its words were cut. */
93
+ value: unknown;
54
94
  error: string;
95
+ /** What failed around its code (its sandbox), in words, or `''`. */
96
+ executionError: string;
97
+ /** The exception its code raised, or `null`. */
98
+ codeError: ToolCodeError | null;
99
+ /** The exit code its code ended with (`sys.exit`), or `null`. */
100
+ exitCode: number | null;
55
101
  /** The protocol display its result carries, read strictly (`portable/displays`, MOBILE M-037). */
56
102
  display: ProtocolDisplay | null;
57
103
  } | {
@@ -98,13 +144,20 @@ export type ConversationState = {
98
144
  }[];
99
145
  /** How many rows the turn streaming added: whether it said anything. */
100
146
  turnRows: number;
147
+ /** What it keeps: its device's bounds. */
148
+ limits: ConversationLimits;
101
149
  };
102
- /** A conversation with nothing in it yet. */
103
- export declare const emptyConversation: () => ConversationState;
150
+ /** A conversation with nothing in it yet, kept within `limits` (a phone's by default). */
151
+ export declare const emptyConversation: (limits?: ConversationLimits) => ConversationState;
104
152
  /** The question an application asks, as `RUN_FINISHED`'s `result.asking` or a session says it. */
105
153
  export declare function questionOf(raw: unknown): ConversationQuestion | null;
106
154
  /** The person's prompt, added before it is sent: its own row. */
107
155
  export declare function withPrompt(state: ConversationState, id: string, words: string): ConversationState;
156
+ /**
157
+ * The conversation without some of its rows: those the person removed (a
158
+ * turn taken away), or a message its application took back.
159
+ */
160
+ export declare function withoutItems(state: ConversationState, ids: Iterable<string>): ConversationState;
108
161
  /**
109
162
  * The turn ended without the stream saying so: the person stopped it
110
163
  * (`stopped`), or its client went before the answer (`gone`). What streamed