@datalayer/agent-runtimes 1.3.83 → 1.3.85
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/lib/chat/ChatFloating.d.ts +5 -4
- package/lib/chat/ChatFloating.js +8 -6
- package/lib/chat/ChatLanguage.d.ts +17 -0
- package/lib/chat/ChatLanguage.js +29 -0
- package/lib/chat/assistant/AssistantStage.d.ts +4 -4
- package/lib/chat/assistant/AssistantStage.js +4 -2
- package/lib/chat/assistant/BalloonParts.d.ts +2 -1
- package/lib/chat/assistant/BalloonParts.js +12 -5
- package/lib/chat/assistant/BalloonVisual.js +3 -1
- package/lib/chat/assistant/ConversationBalloon.d.ts +1 -1
- package/lib/chat/assistant/ConversationBalloon.js +3 -2
- package/lib/chat/assistant/SpeechBalloon.d.ts +1 -1
- package/lib/chat/assistant/SpeechBalloon.js +10 -7
- package/lib/chat/assistant/toolLine.d.ts +8 -4
- package/lib/chat/assistant/toolLine.js +13 -9
- package/lib/chat/base/ChatBase.js +30 -11
- package/lib/chat/base/loopElement.d.ts +53 -0
- package/lib/chat/base/loopElement.js +78 -0
- package/lib/chat/base/loopWindow.d.ts +31 -0
- package/lib/chat/base/loopWindow.js +74 -0
- package/lib/chat/display/EmptyState.js +3 -1
- package/lib/chat/index.d.ts +2 -0
- package/lib/chat/index.js +3 -0
- package/lib/chat/messages/ChatMessages.js +3 -1
- package/lib/chat/messages/TurnFooter.js +3 -1
- package/lib/chat/prompt/InputPrompt.js +3 -1
- package/lib/chat/prompt/InputPromptLexical.js +3 -1
- package/lib/chat/prompt/footer/InPromptFooter.js +3 -1
- package/lib/chat/tools/ToolApprovalBanner.js +5 -3
- package/lib/chat/tools/ToolApprovalDialog.js +5 -3
- package/lib/chat/tools/ToolCallDisplay.js +29 -25
- package/lib/chat/words.d.ts +102 -0
- package/lib/chat/words.js +460 -0
- package/lib/components/a2ui/custom/index.d.ts +39 -0
- package/lib/components/a2ui/custom/index.js +95 -0
- package/lib/components/a2ui/custom/sandbox.d.ts +73 -0
- package/lib/components/a2ui/custom/sandbox.js +188 -0
- package/lib/components/a2ui/datalayer/FileUpload.d.ts +10 -2
- package/lib/components/a2ui/datalayer/FileUpload.js +10 -7
- package/lib/components/a2ui/datalayer/Form.d.ts +2 -0
- package/lib/components/a2ui/datalayer/Form.js +9 -2
- package/lib/components/a2ui/datalayer/formWidgets.d.ts +19 -0
- package/lib/components/a2ui/datalayer/formWidgets.js +51 -0
- package/lib/components/a2ui/datalayer/index.d.ts +1 -1
- package/lib/components/a2ui/datalayer/index.js +1 -1
- package/lib/components/a2ui/datalayer/schema.d.ts +10 -0
- package/lib/components/a2ui/datalayer/schema.js +12 -1
- package/lib/components/a2ui/index.d.ts +1 -0
- package/lib/components/a2ui/index.js +1 -0
- package/lib/components/a2ui/visibleWhen.d.ts +12 -1
- package/lib/components/a2ui/visibleWhen.js +24 -3
- package/lib/components/inspector/AgentInspector.d.ts +25 -44
- package/lib/components/inspector/AgentInspector.js +27 -215
- package/lib/components/inspector/AgentInspectorDialog.d.ts +6 -6
- package/lib/components/inspector/AgentInspectorDialog.js +2 -2
- package/lib/components/inspector/a2aSpans.d.ts +51 -0
- package/lib/components/inspector/a2aSpans.js +373 -0
- package/lib/components/inspector/agentSpans.d.ts +120 -0
- package/lib/components/inspector/agentSpans.js +253 -0
- package/lib/components/inspector/chatSpans.d.ts +36 -0
- package/lib/components/inspector/chatSpans.js +50 -0
- package/lib/components/inspector/classify.d.ts +11 -8
- package/lib/components/inspector/classify.js +23 -24
- package/lib/components/inspector/index.d.ts +7 -7
- package/lib/components/inspector/index.js +7 -7
- package/lib/components/teams/A2ATeamGraph.d.ts +4 -4
- package/lib/components/teams/SceneTranscript.d.ts +29 -0
- package/lib/components/teams/SceneTranscript.js +54 -0
- package/lib/components/teams/SceneView.d.ts +41 -0
- package/lib/components/teams/SceneView.js +28 -0
- package/lib/components/teams/index.d.ts +3 -0
- package/lib/components/teams/index.js +3 -0
- package/lib/components/teams/sceneTranscript.d.ts +74 -0
- package/lib/components/teams/sceneTranscript.js +294 -0
- package/lib/components/teams/teamConnections.d.ts +2 -2
- package/lib/components/teams/teamConnections.js +3 -3
- package/lib/components/teams/useA2ATeam.d.ts +4 -4
- package/lib/components/teams/useA2ATeam.js +50 -46
- package/lib/examples/AgentA2ATeamExample.d.ts +10 -9
- package/lib/examples/AgentA2ATeamExample.js +70 -60
- package/lib/examples/AssistantExample.js +2 -2
- package/lib/loop/apps/AppComposer.d.ts +40 -4
- package/lib/loop/apps/AppComposer.js +194 -19
- package/lib/loop/apps/AppRenderer.d.ts +21 -3
- package/lib/loop/apps/AppRenderer.js +88 -48
- package/lib/loop/apps/appspec.d.ts +13 -1
- package/lib/loop/apps/appspec.js +305 -12
- package/lib/loop/apps/checks.d.ts +14 -0
- package/lib/loop/apps/checks.js +276 -5
- package/lib/loop/apps/composer.d.ts +21 -10
- package/lib/loop/apps/composer.js +41 -8
- package/lib/loop/apps/customComponents.d.ts +41 -0
- package/lib/loop/apps/customComponents.js +260 -0
- package/lib/loop/apps/hostTools.d.ts +8 -1
- package/lib/loop/apps/hostTools.js +9 -0
- package/lib/loop/apps/index.d.ts +1 -0
- package/lib/loop/apps/index.js +1 -0
- package/lib/loop/apps/language.d.ts +68 -0
- package/lib/loop/apps/language.js +275 -0
- package/lib/loop/apps/settingsInputs.d.ts +29 -0
- package/lib/loop/apps/settingsInputs.js +147 -0
- package/lib/loop/apps/uploads.d.ts +43 -0
- package/lib/loop/apps/uploads.js +66 -0
- package/lib/loop/core/a2uiComponents.d.ts +10 -0
- package/lib/loop/core/a2uiComponents.js +15 -0
- package/lib/loop/core/index.d.ts +15 -1
- package/lib/loop/core/index.js +3 -0
- package/lib/loop/embed/AppEmbed.d.ts +25 -3
- package/lib/loop/embed/AppEmbed.js +106 -18
- package/lib/loop/embed/element.d.ts +5 -0
- package/lib/loop/embed/element.js +84 -5
- package/lib/loop/embed/embedConfig.d.ts +8 -0
- package/lib/loop/embed/embedConfig.js +18 -0
- package/lib/loop/embed/embedSession.d.ts +14 -0
- package/lib/loop/embed/embedSession.js +34 -0
- package/lib/loop/embed/hostBridge.d.ts +50 -3
- package/lib/loop/embed/hostBridge.js +22 -2
- package/lib/loop/index.d.ts +4 -3
- package/lib/loop/index.js +4 -3
- package/lib/loop/plugins/a2ui-surface/InlineSurface.d.ts +7 -1
- package/lib/loop/plugins/a2ui-surface/InlineSurface.js +7 -2
- package/lib/loop/plugins/a2ui-surface/SurfaceToolResult.js +4 -1
- package/lib/loop/plugins/a2ui-surface/ownComponents.d.ts +6 -0
- package/lib/loop/plugins/a2ui-surface/ownComponents.js +30 -0
- package/lib/loop/plugins/app-components/index.d.ts +26 -0
- package/lib/loop/plugins/app-components/index.js +56 -0
- package/lib/loop/plugins/app-elements/AppElements.d.ts +27 -0
- package/lib/loop/plugins/app-elements/AppElements.js +79 -0
- package/lib/loop/plugins/app-elements/index.d.ts +20 -0
- package/lib/loop/plugins/app-elements/index.js +43 -0
- package/lib/loop/plugins/app-page/AppPage.d.ts +9 -0
- package/lib/loop/plugins/app-page/AppPage.js +106 -8
- package/lib/loop/plugins/app-page/appPageModel.d.ts +17 -1
- package/lib/loop/plugins/app-page/appPageModel.js +122 -4
- package/lib/loop/plugins/app-page/index.d.ts +1 -0
- package/lib/loop/plugins/app-page/index.js +1 -0
- package/lib/loop/plugins/app-page/pageRun.d.ts +46 -0
- package/lib/loop/plugins/app-page/pageRun.js +111 -0
- package/lib/loop/plugins/assistant/index.js +8 -6
- package/lib/loop/plugins/chat/ChatView.js +16 -6
- package/lib/loop/plugins/chat/index.d.ts +1 -1
- package/lib/loop/plugins/chat/index.js +2 -1
- package/lib/models/PageTag.d.ts +1 -1
- package/lib/protocols/BrowserAgentAdapter.d.ts +8 -6
- package/lib/protocols/BrowserAgentAdapter.js +13 -10
- package/lib/runtimes/browser/a2aPeer.d.ts +2 -1
- package/lib/runtimes/browser/protocol.d.ts +1 -1
- package/lib/specs/actions.js +78 -1
- package/lib/specs/apps.d.ts +5 -0
- package/lib/specs/apps.js +1518 -216
- package/lib/specs/appspecSchema.js +630 -3
- package/lib/specs/teams/teams.d.ts +3 -0
- package/lib/specs/teams/teams.js +249 -0
- package/lib/specs/uiPlugins.js +6 -1
- package/lib/types/agentspecs.d.ts +200 -1
- package/lib/types/chat.d.ts +6 -5
- package/lib/types/teams.d.ts +13 -2
- package/package.json +2 -2
- package/scripts/codegen/generate_apps.py +20 -2
- package/scripts/codegen/generate_teams.py +15 -2
- package/lib/components/inspector/JsonTree.d.ts +0 -24
- package/lib/components/inspector/JsonTree.js +0 -89
- package/lib/components/inspector/a2aInspect.d.ts +0 -56
- package/lib/components/inspector/a2aInspect.js +0 -478
- package/lib/components/inspector/agentInspector.d.ts +0 -179
- package/lib/components/inspector/agentInspector.js +0 -267
- package/lib/components/inspector/chatInspect.d.ts +0 -38
- package/lib/components/inspector/chatInspect.js +0 -65
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
-
* Distributed under the terms of the Modified BSD License.
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* The Agent Inspector's record: what an agent does, as it does it, one entry
|
|
7
|
-
* a thing — an A2A request or event, an MCP tool call, a skill, a frontend or
|
|
8
|
-
* backend tool, a model turn, an approval — each with its time, the agent
|
|
9
|
-
* that did it (`actor`), where it came from (`source`), its kind, its name,
|
|
10
|
-
* its status and, once it ends, its duration, a line that says it, and its
|
|
11
|
-
* payload whole.
|
|
12
|
-
*
|
|
13
|
-
* A call's start and its end are one entry: {@link AgentInspectorSink.start}
|
|
14
|
-
* opens it under a key (a tool call's id), {@link AgentInspectorSink.end}
|
|
15
|
-
* closes it with its result. Anything can push into a sink: the A2A capture
|
|
16
|
-
* (`inspectA2AFetch`), a team (`useA2ATeam`'s `inspector`), a chat
|
|
17
|
-
* (`ChatBase`, under {@link AgentInspectorProvider}). `AgentInspector` draws
|
|
18
|
-
* it.
|
|
19
|
-
*
|
|
20
|
-
* @module components/inspector/agentInspector
|
|
21
|
-
*/
|
|
22
|
-
import { createContext, createElement, useContext, useState, useSyncExternalStore, } from 'react';
|
|
23
|
-
/** Every source, in the order the filters list them. */
|
|
24
|
-
export const AGENT_INSPECTOR_SOURCES = [
|
|
25
|
-
'a2a',
|
|
26
|
-
'mcp',
|
|
27
|
-
'skill',
|
|
28
|
-
'frontend-tool',
|
|
29
|
-
'backend-tool',
|
|
30
|
-
'model',
|
|
31
|
-
'approval',
|
|
32
|
-
];
|
|
33
|
-
/** A source, in words. */
|
|
34
|
-
export const AGENT_INSPECTOR_SOURCE_LABELS = {
|
|
35
|
-
a2a: 'A2A',
|
|
36
|
-
mcp: 'MCP',
|
|
37
|
-
skill: 'Skill',
|
|
38
|
-
'frontend-tool': 'Frontend tool',
|
|
39
|
-
'backend-tool': 'Backend tool',
|
|
40
|
-
model: 'Model',
|
|
41
|
-
approval: 'Approval',
|
|
42
|
-
};
|
|
43
|
-
/** How large a value is, as JSON, in bytes. */
|
|
44
|
-
export function jsonBytes(value) {
|
|
45
|
-
if (value === undefined) {
|
|
46
|
-
return 0;
|
|
47
|
-
}
|
|
48
|
-
try {
|
|
49
|
-
const text = JSON.stringify(value);
|
|
50
|
-
return text === undefined ? 0 : new TextEncoder().encode(text).length;
|
|
51
|
-
}
|
|
52
|
-
catch {
|
|
53
|
-
return 0;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
/** A size, in words: `812 B`, `12.3 kB`, `1.2 MB`. */
|
|
57
|
-
export function formatBytes(bytes) {
|
|
58
|
-
if (bytes < 1000) {
|
|
59
|
-
return `${bytes} B`;
|
|
60
|
-
}
|
|
61
|
-
if (bytes < 1_000_000) {
|
|
62
|
-
return `${(bytes / 1000).toFixed(1)} kB`;
|
|
63
|
-
}
|
|
64
|
-
return `${(bytes / 1_000_000).toFixed(1)} MB`;
|
|
65
|
-
}
|
|
66
|
-
/** A line short enough for a row. */
|
|
67
|
-
export function shortLine(text, length = 160) {
|
|
68
|
-
const flat = text.replace(/\s+/g, ' ').trim();
|
|
69
|
-
return flat.length > length ? `${flat.slice(0, length - 1)}…` : flat;
|
|
70
|
-
}
|
|
71
|
-
/** How many semantic events wait for their entry. */
|
|
72
|
-
const PENDING_LIMIT = 32;
|
|
73
|
-
/** Make a sink: the record, and who listens to it. */
|
|
74
|
-
export function createAgentInspector(options = {}) {
|
|
75
|
-
const now = options.now ?? Date.now;
|
|
76
|
-
const limit = options.limit ?? 2000;
|
|
77
|
-
let list = [];
|
|
78
|
-
let counter = 0;
|
|
79
|
-
const open = new Map();
|
|
80
|
-
const listeners = new Set();
|
|
81
|
-
let pending = [];
|
|
82
|
-
let scheduled = false;
|
|
83
|
-
const linkers = new Set();
|
|
84
|
-
const notify = () => {
|
|
85
|
-
if (scheduled) {
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
scheduled = true;
|
|
89
|
-
queueMicrotask(() => {
|
|
90
|
-
scheduled = false;
|
|
91
|
-
listeners.forEach(listener => listener());
|
|
92
|
-
});
|
|
93
|
-
};
|
|
94
|
-
const replace = (id, next) => {
|
|
95
|
-
list = list.map(entry => (entry.id === id ? next : entry));
|
|
96
|
-
};
|
|
97
|
-
const settlePending = (entry) => {
|
|
98
|
-
if (!pending.length) {
|
|
99
|
-
return entry;
|
|
100
|
-
}
|
|
101
|
-
const taken = pending.filter(waiting => waiting.match(entry));
|
|
102
|
-
if (!taken.length) {
|
|
103
|
-
return entry;
|
|
104
|
-
}
|
|
105
|
-
pending = pending.filter(waiting => !taken.includes(waiting));
|
|
106
|
-
return {
|
|
107
|
-
...entry,
|
|
108
|
-
events: [...entry.events, ...taken.map(waiting => waiting.event)],
|
|
109
|
-
};
|
|
110
|
-
};
|
|
111
|
-
const push = (input) => {
|
|
112
|
-
counter += 1;
|
|
113
|
-
const id = `e${counter}`;
|
|
114
|
-
const { links, at, ...rest } = input;
|
|
115
|
-
const entry = settlePending({
|
|
116
|
-
...rest,
|
|
117
|
-
id,
|
|
118
|
-
at: at ?? now(),
|
|
119
|
-
bytes: jsonBytes(input.payload) + jsonBytes(input.result),
|
|
120
|
-
links: links ?? [],
|
|
121
|
-
events: [],
|
|
122
|
-
});
|
|
123
|
-
list = [...list, entry];
|
|
124
|
-
if (list.length > limit) {
|
|
125
|
-
list = list.slice(list.length - limit);
|
|
126
|
-
}
|
|
127
|
-
notify();
|
|
128
|
-
return id;
|
|
129
|
-
};
|
|
130
|
-
const find = (id) => list.find(entry => entry.id === id);
|
|
131
|
-
const sink = {
|
|
132
|
-
push,
|
|
133
|
-
start(input) {
|
|
134
|
-
const known = open.get(input.key);
|
|
135
|
-
const entry = known ? find(known) : undefined;
|
|
136
|
-
if (entry) {
|
|
137
|
-
const payload = input.payload ?? entry.payload;
|
|
138
|
-
replace(entry.id, {
|
|
139
|
-
...entry,
|
|
140
|
-
payload,
|
|
141
|
-
summary: input.summary || entry.summary,
|
|
142
|
-
links: [...entry.links, ...(input.links ?? [])],
|
|
143
|
-
bytes: jsonBytes(payload) + jsonBytes(entry.result),
|
|
144
|
-
});
|
|
145
|
-
notify();
|
|
146
|
-
return entry.id;
|
|
147
|
-
}
|
|
148
|
-
const id = push({ ...input, status: 'running' });
|
|
149
|
-
open.set(input.key, id);
|
|
150
|
-
return id;
|
|
151
|
-
},
|
|
152
|
-
end(key, outcome = {}) {
|
|
153
|
-
const id = open.get(key);
|
|
154
|
-
const entry = id ? find(id) : undefined;
|
|
155
|
-
if (!id || !entry) {
|
|
156
|
-
return undefined;
|
|
157
|
-
}
|
|
158
|
-
open.delete(key);
|
|
159
|
-
const result = outcome.result ?? entry.result;
|
|
160
|
-
replace(id, {
|
|
161
|
-
...entry,
|
|
162
|
-
status: outcome.status ?? (outcome.error ? 'failed' : 'done'),
|
|
163
|
-
endedAt: outcome.at ?? now(),
|
|
164
|
-
result,
|
|
165
|
-
error: outcome.error ?? entry.error,
|
|
166
|
-
summary: outcome.summary ?? entry.summary,
|
|
167
|
-
links: [...entry.links, ...(outcome.links ?? [])],
|
|
168
|
-
bytes: jsonBytes(entry.payload) + jsonBytes(result),
|
|
169
|
-
});
|
|
170
|
-
notify();
|
|
171
|
-
return id;
|
|
172
|
-
},
|
|
173
|
-
update(id, patch) {
|
|
174
|
-
const entry = find(id);
|
|
175
|
-
if (!entry) {
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
const next = { ...entry, ...patch(entry) };
|
|
179
|
-
replace(id, {
|
|
180
|
-
...next,
|
|
181
|
-
bytes: jsonBytes(next.payload) + jsonBytes(next.result),
|
|
182
|
-
});
|
|
183
|
-
notify();
|
|
184
|
-
},
|
|
185
|
-
attach(match, event) {
|
|
186
|
-
for (let index = list.length - 1; index >= 0; index -= 1) {
|
|
187
|
-
const entry = list[index];
|
|
188
|
-
if (match(entry) && !entry.events.includes(event)) {
|
|
189
|
-
replace(entry.id, { ...entry, events: [...entry.events, event] });
|
|
190
|
-
notify();
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
pending = [...pending, { match, event }].slice(-PENDING_LIMIT);
|
|
195
|
-
},
|
|
196
|
-
running(key) {
|
|
197
|
-
return open.has(key);
|
|
198
|
-
},
|
|
199
|
-
note(event) {
|
|
200
|
-
for (const linker of linkers) {
|
|
201
|
-
const match = linker(event);
|
|
202
|
-
if (match) {
|
|
203
|
-
sink.attach(match, event);
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
},
|
|
208
|
-
addLinker(linker) {
|
|
209
|
-
linkers.add(linker);
|
|
210
|
-
return () => {
|
|
211
|
-
linkers.delete(linker);
|
|
212
|
-
};
|
|
213
|
-
},
|
|
214
|
-
clear() {
|
|
215
|
-
list = [];
|
|
216
|
-
open.clear();
|
|
217
|
-
pending = [];
|
|
218
|
-
notify();
|
|
219
|
-
},
|
|
220
|
-
entries() {
|
|
221
|
-
return list;
|
|
222
|
-
},
|
|
223
|
-
subscribe(listener) {
|
|
224
|
-
listeners.add(listener);
|
|
225
|
-
return () => {
|
|
226
|
-
listeners.delete(listener);
|
|
227
|
-
};
|
|
228
|
-
},
|
|
229
|
-
exportSession() {
|
|
230
|
-
return { exportedAt: new Date(now()).toISOString(), entries: [...list] };
|
|
231
|
-
},
|
|
232
|
-
};
|
|
233
|
-
return sink;
|
|
234
|
-
}
|
|
235
|
-
const NO_ENTRIES = [];
|
|
236
|
-
const NO_SUBSCRIPTION = () => () => undefined;
|
|
237
|
-
/** A sink's entries, kept current; none without a sink. */
|
|
238
|
-
export function useAgentInspectorEntries(sink) {
|
|
239
|
-
return useSyncExternalStore(sink ? sink.subscribe : NO_SUBSCRIPTION, () => (sink ? sink.entries() : NO_ENTRIES), () => (sink ? sink.entries() : NO_ENTRIES));
|
|
240
|
-
}
|
|
241
|
-
/**
|
|
242
|
-
* A sink for a page, made once (or the one given), and its entries: what a
|
|
243
|
-
* page passes to its team, its chat and its `AgentInspector`.
|
|
244
|
-
*/
|
|
245
|
-
export function useAgentInspector(given) {
|
|
246
|
-
const [own] = useState(() => given ?? createAgentInspector());
|
|
247
|
-
const sink = given ?? own;
|
|
248
|
-
return { sink, entries: useAgentInspectorEntries(sink) };
|
|
249
|
-
}
|
|
250
|
-
/** The sink the chats under it push into. */
|
|
251
|
-
export const AgentInspectorContext = createContext(null);
|
|
252
|
-
/** The sink of the nearest {@link AgentInspectorProvider}, if any. */
|
|
253
|
-
export function useAgentInspectorSink() {
|
|
254
|
-
return useContext(AgentInspectorContext);
|
|
255
|
-
}
|
|
256
|
-
/** Every chat under it records what its agent does into `sink`. */
|
|
257
|
-
export function AgentInspectorProvider({ sink, children, }) {
|
|
258
|
-
return createElement(AgentInspectorContext.Provider, { value: sink }, children);
|
|
259
|
-
}
|
|
260
|
-
/** A call's arguments, in a few words: `kind=customer, limit=100`. */
|
|
261
|
-
export function argumentsLine(args, length = 100) {
|
|
262
|
-
if (!args || typeof args !== 'object') {
|
|
263
|
-
return args === undefined ? '' : shortLine(String(args), length);
|
|
264
|
-
}
|
|
265
|
-
const parts = Object.entries(args).map(([key, value]) => `${key}=${typeof value === 'string' ? value : JSON.stringify(value)}`);
|
|
266
|
-
return shortLine(parts.join(', '), length);
|
|
267
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A chat's agent, as the Agent Inspector records it: each turn of its model
|
|
3
|
-
* (the prompt, the answer, the tokens), and each tool call from its start to
|
|
4
|
-
* its end — an MCP server's, a skill, a frontend tool the page runs, a tool
|
|
5
|
-
* the runtime runs — whatever transport the chat speaks (AG-UI, Vercel AI,
|
|
6
|
-
* A2A, the in-browser harness): `ChatBase` tells it what its adapter told.
|
|
7
|
-
*
|
|
8
|
-
* @module components/inspector/chatInspect
|
|
9
|
-
*/
|
|
10
|
-
import type { MarkedMcpServer } from '../../chat/marks/toolMarks';
|
|
11
|
-
import { type AgentInspectorSink } from './agentInspector';
|
|
12
|
-
export type ChatInspectorRecorder = {
|
|
13
|
-
turnStarted: (prompt: string, model?: string) => void;
|
|
14
|
-
turnEnded: (outcome: {
|
|
15
|
-
text?: string;
|
|
16
|
-
usage?: {
|
|
17
|
-
promptTokens?: number;
|
|
18
|
-
completionTokens?: number;
|
|
19
|
-
totalTokens?: number;
|
|
20
|
-
};
|
|
21
|
-
error?: string;
|
|
22
|
-
}) => void;
|
|
23
|
-
toolStarted: (call: {
|
|
24
|
-
id: string;
|
|
25
|
-
name: string;
|
|
26
|
-
args: Record<string, unknown>;
|
|
27
|
-
}) => void;
|
|
28
|
-
toolEnded: (id: string, outcome: {
|
|
29
|
-
result?: unknown;
|
|
30
|
-
error?: string;
|
|
31
|
-
}) => void;
|
|
32
|
-
};
|
|
33
|
-
/** A recorder for one chat's agent (`actor`) into `sink`. */
|
|
34
|
-
export declare function chatInspectorRecorder(sink: AgentInspectorSink, actor: () => string, options?: {
|
|
35
|
-
/** The page's own tools, by name: frontend tools. */
|
|
36
|
-
frontendTools?: () => readonly string[];
|
|
37
|
-
mcpServers?: () => readonly MarkedMcpServer[];
|
|
38
|
-
}): ChatInspectorRecorder;
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
-
* Distributed under the terms of the Modified BSD License.
|
|
4
|
-
*/
|
|
5
|
-
import { argumentsLine, shortLine, } from './agentInspector';
|
|
6
|
-
import { classifyToolCall } from './classify';
|
|
7
|
-
/** A recorder for one chat's agent (`actor`) into `sink`. */
|
|
8
|
-
export function chatInspectorRecorder(sink, actor, options = {}) {
|
|
9
|
-
let turns = 0;
|
|
10
|
-
let turnKey;
|
|
11
|
-
return {
|
|
12
|
-
turnStarted(prompt, model) {
|
|
13
|
-
turns += 1;
|
|
14
|
-
turnKey = `chat-turn:${turns}`;
|
|
15
|
-
sink.start({
|
|
16
|
-
key: turnKey,
|
|
17
|
-
actor: actor(),
|
|
18
|
-
source: 'model',
|
|
19
|
-
kind: 'turn',
|
|
20
|
-
...(model ? { name: model } : {}),
|
|
21
|
-
summary: shortLine(prompt),
|
|
22
|
-
payload: { prompt, ...(model ? { model } : {}) },
|
|
23
|
-
});
|
|
24
|
-
},
|
|
25
|
-
turnEnded({ text, usage, error }) {
|
|
26
|
-
if (!turnKey) {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
const total = usage?.totalTokens ??
|
|
30
|
-
(usage?.promptTokens ?? 0) + (usage?.completionTokens ?? 0);
|
|
31
|
-
sink.end(turnKey, {
|
|
32
|
-
...(error ? { status: 'failed', error } : {}),
|
|
33
|
-
result: {
|
|
34
|
-
...(text ? { text } : {}),
|
|
35
|
-
...(usage ? { usage } : {}),
|
|
36
|
-
},
|
|
37
|
-
...(total ? { summary: `${total} tokens` } : {}),
|
|
38
|
-
});
|
|
39
|
-
turnKey = undefined;
|
|
40
|
-
},
|
|
41
|
-
toolStarted({ id, name, args }) {
|
|
42
|
-
const kind = classifyToolCall(name, args, {
|
|
43
|
-
frontendTools: options.frontendTools?.(),
|
|
44
|
-
mcpServers: options.mcpServers?.(),
|
|
45
|
-
});
|
|
46
|
-
sink.start({
|
|
47
|
-
key: `chat-tool:${id}`,
|
|
48
|
-
actor: actor(),
|
|
49
|
-
source: kind.source,
|
|
50
|
-
...(kind.icon ? { icon: kind.icon } : {}),
|
|
51
|
-
...(kind.emoji ? { emoji: kind.emoji } : {}),
|
|
52
|
-
kind: 'tool-call',
|
|
53
|
-
name,
|
|
54
|
-
summary: argumentsLine(args),
|
|
55
|
-
payload: args,
|
|
56
|
-
});
|
|
57
|
-
},
|
|
58
|
-
toolEnded(id, { result, error }) {
|
|
59
|
-
sink.end(`chat-tool:${id}`, {
|
|
60
|
-
...(error ? { status: 'failed', error } : {}),
|
|
61
|
-
result,
|
|
62
|
-
});
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
}
|