@datalayer/agent-runtimes 1.3.84 → 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 +14 -11
- 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/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 +2 -1
- package/lib/loop/apps/AppComposer.js +6 -3
- package/lib/loop/apps/AppRenderer.d.ts +2 -1
- package/lib/loop/apps/AppRenderer.js +34 -25
- package/lib/loop/apps/appspec.d.ts +11 -1
- package/lib/loop/apps/appspec.js +115 -1
- package/lib/loop/apps/checks.d.ts +8 -0
- package/lib/loop/apps/checks.js +106 -4
- 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/core/a2uiComponents.d.ts +10 -0
- package/lib/loop/core/a2uiComponents.js +15 -0
- package/lib/loop/core/index.d.ts +1 -0
- package/lib/loop/core/index.js +3 -0
- package/lib/loop/embed/AppEmbed.d.ts +11 -3
- package/lib/loop/embed/AppEmbed.js +42 -16
- package/lib/loop/embed/element.d.ts +5 -0
- package/lib/loop/embed/element.js +61 -5
- package/lib/loop/embed/embedConfig.d.ts +8 -0
- package/lib/loop/embed/embedConfig.js +18 -0
- package/lib/loop/embed/hostBridge.d.ts +28 -2
- 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.js +4 -1
- 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 +120 -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 +6 -4
- 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/runtimes/browser/a2aPeer.d.ts +2 -1
- package/lib/specs/actions.js +78 -1
- package/lib/specs/apps.d.ts +5 -0
- package/lib/specs/apps.js +1384 -231
- package/lib/specs/appspecSchema.js +191 -1
- package/lib/specs/teams/teams.d.ts +3 -0
- package/lib/specs/teams/teams.js +249 -0
- package/lib/types/agentspecs.d.ts +70 -0
- 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 +4 -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
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* The frame a component its developer wrote is drawn in (LOOP P-17), and
|
|
7
|
+
* what passes between it and the page.
|
|
8
|
+
*
|
|
9
|
+
* A hosted application lives on the origin where people are signed in, and
|
|
10
|
+
* no script an application supplies reaches that page (LOOP D-22). A custom
|
|
11
|
+
* component's module is such a script, so it never runs in the page: it runs
|
|
12
|
+
* in an `<iframe sandbox="allow-scripts">` — no `allow-same-origin`, so the
|
|
13
|
+
* frame has an origin of its own that is no one's: no cookie, no storage, no
|
|
14
|
+
* access to the page, its DOM or its tokens — whose document allows nothing
|
|
15
|
+
* but its own bootstrap and the module it is handed (`default-src 'none'`):
|
|
16
|
+
* no request leaves the frame, no form, no navigation of the page.
|
|
17
|
+
*
|
|
18
|
+
* The page fetches the module — without credentials — checks it against the
|
|
19
|
+
* hash it was reviewed with when the spec gives one (`integrity`), and hands
|
|
20
|
+
* its text to the frame, which imports it from a `blob:` address. Its
|
|
21
|
+
* default export draws it: `export default function (root, {props, send})`,
|
|
22
|
+
* returning `{update(props)}` to be told of new properties. What it is given
|
|
23
|
+
* is its properties and what it shows; what it gives back is what it sends,
|
|
24
|
+
* by name, each refused unless declared.
|
|
25
|
+
*
|
|
26
|
+
* @module components/a2ui/custom/sandbox
|
|
27
|
+
*/
|
|
28
|
+
/** What the frame of a custom component may do: run scripts, nothing else. */
|
|
29
|
+
export const CUSTOM_FRAME_SANDBOX = 'allow-scripts';
|
|
30
|
+
/** The largest module the page hands to a frame, in bytes. */
|
|
31
|
+
export const MAX_MODULE_BYTES = 2 * 1024 * 1024;
|
|
32
|
+
/** The tag every message between the page and a frame carries. */
|
|
33
|
+
export const FRAME_TAG = 'loop.component';
|
|
34
|
+
/** The policy of the frame's document: its bootstrap, the module it is handed, nothing else. */
|
|
35
|
+
export function customFramePolicy(nonce) {
|
|
36
|
+
return [
|
|
37
|
+
"default-src 'none'",
|
|
38
|
+
`script-src 'nonce-${nonce}' blob:`,
|
|
39
|
+
"style-src 'unsafe-inline'",
|
|
40
|
+
'img-src data: blob:',
|
|
41
|
+
'font-src data:',
|
|
42
|
+
'media-src data: blob:',
|
|
43
|
+
"form-action 'none'",
|
|
44
|
+
"base-uri 'none'",
|
|
45
|
+
].join('; ');
|
|
46
|
+
}
|
|
47
|
+
/** A nonce for one frame's bootstrap. */
|
|
48
|
+
export function frameNonce() {
|
|
49
|
+
const bytes = new Uint8Array(16);
|
|
50
|
+
crypto.getRandomValues(bytes);
|
|
51
|
+
return Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join('');
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The document of a custom component's frame (its `srcdoc`): the policy,
|
|
55
|
+
* the root it draws into, and the bootstrap that imports the module it is
|
|
56
|
+
* handed and passes properties in and what it sends out.
|
|
57
|
+
*/
|
|
58
|
+
export function customFrameDocument(nonce, label) {
|
|
59
|
+
const escaped = label.replace(/[&<>"]/g, char => `&#${char.charCodeAt(0)};`);
|
|
60
|
+
return `<!doctype html>
|
|
61
|
+
<html lang="en">
|
|
62
|
+
<head>
|
|
63
|
+
<meta charset="utf-8">
|
|
64
|
+
<meta http-equiv="Content-Security-Policy" content="${customFramePolicy(nonce)}">
|
|
65
|
+
<title>${escaped}</title>
|
|
66
|
+
<style>html,body{margin:0;padding:0;background:transparent;color-scheme:light dark;font-family:system-ui,-apple-system,sans-serif}#root{box-sizing:border-box;min-height:100vh}</style>
|
|
67
|
+
</head>
|
|
68
|
+
<body>
|
|
69
|
+
<div id="root"></div>
|
|
70
|
+
<script nonce="${nonce}">
|
|
71
|
+
(() => {
|
|
72
|
+
const TAG = ${JSON.stringify(FRAME_TAG)};
|
|
73
|
+
const root = document.getElementById('root');
|
|
74
|
+
let props = {};
|
|
75
|
+
let drawn = null;
|
|
76
|
+
let started = false;
|
|
77
|
+
const say = message => parent.postMessage(Object.assign({ tag: TAG }, message), '*');
|
|
78
|
+
const send = (name, value) => say({ kind: 'send', name: String(name), value: value });
|
|
79
|
+
addEventListener('message', async event => {
|
|
80
|
+
if (event.source !== parent) return;
|
|
81
|
+
const data = event.data;
|
|
82
|
+
if (!data || data.tag !== TAG) return;
|
|
83
|
+
if (data.kind === 'props') {
|
|
84
|
+
props = data.props || {};
|
|
85
|
+
if (drawn && typeof drawn.update === 'function') drawn.update(props);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (data.kind !== 'module' || started) return;
|
|
89
|
+
started = true;
|
|
90
|
+
try {
|
|
91
|
+
const url = URL.createObjectURL(new Blob([data.code], { type: 'text/javascript' }));
|
|
92
|
+
const module = await import(url);
|
|
93
|
+
URL.revokeObjectURL(url);
|
|
94
|
+
if (typeof module.default !== 'function') {
|
|
95
|
+
throw new Error('its module has no default export that draws it');
|
|
96
|
+
}
|
|
97
|
+
drawn = (await module.default(root, { props: props, send: send })) || {};
|
|
98
|
+
say({ kind: 'drawn' });
|
|
99
|
+
} catch (error) {
|
|
100
|
+
say({ kind: 'failed', message: String((error && error.message) || error) });
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
say({ kind: 'ready' });
|
|
104
|
+
})();
|
|
105
|
+
</script>
|
|
106
|
+
</body>
|
|
107
|
+
</html>`;
|
|
108
|
+
}
|
|
109
|
+
/** What a frame said, when it is a message of the frame drawn here; null otherwise. */
|
|
110
|
+
export function fromFrame(event, frame) {
|
|
111
|
+
if (!frame || event.source !== frame) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
const data = event.data;
|
|
115
|
+
if (!data || typeof data !== 'object' || data.tag !== FRAME_TAG) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
switch (data.kind) {
|
|
119
|
+
case 'ready':
|
|
120
|
+
case 'drawn':
|
|
121
|
+
return { kind: data.kind };
|
|
122
|
+
case 'failed':
|
|
123
|
+
return { kind: 'failed', message: String(data.message ?? '') };
|
|
124
|
+
case 'send':
|
|
125
|
+
return typeof data.name === 'string'
|
|
126
|
+
? { kind: 'send', name: data.name, value: data.value }
|
|
127
|
+
: null;
|
|
128
|
+
default:
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const ALGORITHMS = {
|
|
133
|
+
sha256: 'SHA-256',
|
|
134
|
+
sha384: 'SHA-384',
|
|
135
|
+
sha512: 'SHA-512',
|
|
136
|
+
};
|
|
137
|
+
function base64(bytes) {
|
|
138
|
+
let binary = '';
|
|
139
|
+
for (const byte of new Uint8Array(bytes)) {
|
|
140
|
+
binary += String.fromCharCode(byte);
|
|
141
|
+
}
|
|
142
|
+
return btoa(binary);
|
|
143
|
+
}
|
|
144
|
+
/** Whether a module's bytes are the ones its Subresource Integrity hash names. */
|
|
145
|
+
export async function integrityHolds(bytes, integrity) {
|
|
146
|
+
const at = integrity.indexOf('-');
|
|
147
|
+
const algorithm = ALGORITHMS[integrity.slice(0, at)];
|
|
148
|
+
if (at < 0 || !algorithm) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
const digest = await crypto.subtle.digest(algorithm, bytes);
|
|
152
|
+
return base64(digest) === integrity.slice(at + 1);
|
|
153
|
+
}
|
|
154
|
+
/** The modules fetched, by address and hash: each fetched once per page. */
|
|
155
|
+
const MODULES = new Map();
|
|
156
|
+
/**
|
|
157
|
+
* The text of a custom component's module, fetched without credentials and
|
|
158
|
+
* checked against its hash when one is given. It throws, with a sentence,
|
|
159
|
+
* for a module that cannot be fetched, is too large, or is not the one
|
|
160
|
+
* reviewed.
|
|
161
|
+
*/
|
|
162
|
+
export function customModule(source, integrity, fetcher = fetch) {
|
|
163
|
+
const key = `${source}\n${integrity}`;
|
|
164
|
+
let module = MODULES.get(key);
|
|
165
|
+
if (!module) {
|
|
166
|
+
module = (async () => {
|
|
167
|
+
const response = await fetcher(source, {
|
|
168
|
+
credentials: 'omit',
|
|
169
|
+
mode: 'cors',
|
|
170
|
+
});
|
|
171
|
+
if (!response.ok) {
|
|
172
|
+
throw new Error(`Its module could not be fetched from ${source} (${response.status}).`);
|
|
173
|
+
}
|
|
174
|
+
const bytes = await response.arrayBuffer();
|
|
175
|
+
if (bytes.byteLength > MAX_MODULE_BYTES) {
|
|
176
|
+
throw new Error(`Its module is larger than ${MAX_MODULE_BYTES / 1024 / 1024} MB.`);
|
|
177
|
+
}
|
|
178
|
+
if (integrity && !(await integrityHolds(bytes, integrity))) {
|
|
179
|
+
throw new Error('Its module is not the one reviewed: its hash differs from its integrity.');
|
|
180
|
+
}
|
|
181
|
+
return new TextDecoder().decode(bytes);
|
|
182
|
+
})();
|
|
183
|
+
// A failure is not kept: the next drawing tries again.
|
|
184
|
+
module.catch(() => MODULES.delete(key));
|
|
185
|
+
MODULES.set(key, module);
|
|
186
|
+
}
|
|
187
|
+
return module;
|
|
188
|
+
}
|
|
@@ -14,7 +14,7 @@ import type { ReactComponentImplementation } from '@a2ui/react/v0_9';
|
|
|
14
14
|
* a renderer for one it no longer has, fails at once.
|
|
15
15
|
*/
|
|
16
16
|
export declare const OWN_COMPONENTS: ReactComponentImplementation[];
|
|
17
|
-
export { OWN_COMPONENT_IDS, ownComponentSchema } from './schema';
|
|
17
|
+
export { OWN_COMPONENT_IDS, componentSchemaOf, ownComponentSchema, } from './schema';
|
|
18
18
|
export { DRAWN_OWN_COMPONENTS, type DrawnOwnComponent } from './drawn';
|
|
19
19
|
export { chartOption, chartPoints, chartSeries } from './Chart';
|
|
20
20
|
export { chatItems } from './Chat';
|
|
@@ -35,7 +35,7 @@ export const OWN_COMPONENTS = (() => {
|
|
|
35
35
|
}
|
|
36
36
|
return OWN_COMPONENT_IDS.map(id => RENDERERS[id]);
|
|
37
37
|
})();
|
|
38
|
-
export { OWN_COMPONENT_IDS, ownComponentSchema } from './schema';
|
|
38
|
+
export { OWN_COMPONENT_IDS, componentSchemaOf, ownComponentSchema, } from './schema';
|
|
39
39
|
export { DRAWN_OWN_COMPONENTS } from './drawn';
|
|
40
40
|
export { chartOption, chartPoints, chartSeries } from './Chart';
|
|
41
41
|
export { chatItems } from './Chat';
|
|
@@ -32,3 +32,13 @@ export declare function ownComponentSchema(id: string): z.ZodObject<Record<strin
|
|
|
32
32
|
}, {
|
|
33
33
|
[x: string]: any;
|
|
34
34
|
}>;
|
|
35
|
+
/**
|
|
36
|
+
* The A2UI schema of a component of Datalayer's own kind, from its entry in
|
|
37
|
+
* the catalog — one of Datalayer's own, or one an application's developer
|
|
38
|
+
* wrote (LOOP P-17), listed as the catalog lists a component.
|
|
39
|
+
*/
|
|
40
|
+
export declare function componentSchemaOf(component: ComponentSpec): z.ZodObject<Record<string, z.ZodTypeAny>, "strict", z.ZodTypeAny, {
|
|
41
|
+
[x: string]: any;
|
|
42
|
+
}, {
|
|
43
|
+
[x: string]: any;
|
|
44
|
+
}>;
|
|
@@ -83,7 +83,18 @@ export function bindingNames(component) {
|
|
|
83
83
|
* catalog's are: a key it does not declare refuses the tree.
|
|
84
84
|
*/
|
|
85
85
|
export function ownComponentSchema(id) {
|
|
86
|
-
|
|
86
|
+
return componentSchemaOf(ownComponent(id));
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* The A2UI schema of a component of Datalayer's own kind, from its entry in
|
|
90
|
+
* the catalog — one of Datalayer's own, or one an application's developer
|
|
91
|
+
* wrote (LOOP P-17), listed as the catalog lists a component.
|
|
92
|
+
*/
|
|
93
|
+
export function componentSchemaOf(component) {
|
|
94
|
+
const id = component.id;
|
|
95
|
+
if (!component.bindings) {
|
|
96
|
+
throw new Error(`${id} says nothing of what it shows or sends.`);
|
|
97
|
+
}
|
|
87
98
|
const json = component.properties;
|
|
88
99
|
const required = new Set(json.required ?? []);
|
|
89
100
|
const shape = {};
|
|
@@ -22,5 +22,16 @@ export declare const datalayerCatalog: Catalog<ReactComponentImplementation, imp
|
|
|
22
22
|
* plugins contribute as blocks (LOOP R-01b, `loop.canvas.block`), so that an
|
|
23
23
|
* application's page draws what its Canvas can place and nothing else. Under
|
|
24
24
|
* the same id; a name the catalog does not draw is an error.
|
|
25
|
+
*
|
|
26
|
+
* `own` are the renderers of the components the application's developer
|
|
27
|
+
* wrote (LOOP P-17, `customImplementations`): drawn for that application's
|
|
28
|
+
* page alone, each behind `visible_when` as the catalog's are. One that
|
|
29
|
+
* takes the name of a component of the catalog is an error.
|
|
25
30
|
*/
|
|
26
|
-
export declare function catalogOfBlocks(names: readonly string[]): Catalog<ReactComponentImplementation>;
|
|
31
|
+
export declare function catalogOfBlocks(names: readonly string[], own?: readonly ReactComponentImplementation[]): Catalog<ReactComponentImplementation>;
|
|
32
|
+
/**
|
|
33
|
+
* Datalayer's whole catalog with the components an application's developer
|
|
34
|
+
* wrote (LOOP P-17): what its answers and the elements its code shows are
|
|
35
|
+
* drawn with (P-04, P-18). Datalayer's catalog itself when it wrote none.
|
|
36
|
+
*/
|
|
37
|
+
export declare function catalogWithOwn(own: readonly ReactComponentImplementation[]): Catalog<ReactComponentImplementation>;
|
|
@@ -60,11 +60,32 @@ export const datalayerCatalog = new Catalog(basicCatalog.id, basicCatalog.protoc
|
|
|
60
60
|
* plugins contribute as blocks (LOOP R-01b, `loop.canvas.block`), so that an
|
|
61
61
|
* application's page draws what its Canvas can place and nothing else. Under
|
|
62
62
|
* the same id; a name the catalog does not draw is an error.
|
|
63
|
+
*
|
|
64
|
+
* `own` are the renderers of the components the application's developer
|
|
65
|
+
* wrote (LOOP P-17, `customImplementations`): drawn for that application's
|
|
66
|
+
* page alone, each behind `visible_when` as the catalog's are. One that
|
|
67
|
+
* takes the name of a component of the catalog is an error.
|
|
63
68
|
*/
|
|
64
|
-
export function catalogOfBlocks(names) {
|
|
65
|
-
const
|
|
69
|
+
export function catalogOfBlocks(names, own = []) {
|
|
70
|
+
const custom = new Map(own.map(component => [component.name, withVisibleWhen(component)]));
|
|
71
|
+
const taken = [...custom.keys()].filter(name => datalayerCatalog.components.has(name));
|
|
72
|
+
if (taken.length > 0) {
|
|
73
|
+
throw new Error(`${taken.join(', ')} ${taken.length === 1 ? 'is a component' : 'are components'} of the catalog: a component of an application's own is named otherwise.`);
|
|
74
|
+
}
|
|
75
|
+
const unknown = names.filter(name => !datalayerCatalog.components.has(name) && !custom.has(name));
|
|
66
76
|
if (unknown.length > 0) {
|
|
67
77
|
throw new Error(`No renderer draws ${unknown.join(', ')}: a block is contributed by a plugin whose component the catalog draws.`);
|
|
68
78
|
}
|
|
69
|
-
return new Catalog(datalayerCatalog.id, datalayerCatalog.protocolVersion, names.map(name => datalayerCatalog.components.get(name)), [...datalayerCatalog.functions.values()], datalayerCatalog.themeSchema, datalayerCatalog.instructions);
|
|
79
|
+
return new Catalog(datalayerCatalog.id, datalayerCatalog.protocolVersion, names.map(name => datalayerCatalog.components.get(name) ?? custom.get(name)), [...datalayerCatalog.functions.values()], datalayerCatalog.themeSchema, datalayerCatalog.instructions);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Datalayer's whole catalog with the components an application's developer
|
|
83
|
+
* wrote (LOOP P-17): what its answers and the elements its code shows are
|
|
84
|
+
* drawn with (P-04, P-18). Datalayer's catalog itself when it wrote none.
|
|
85
|
+
*/
|
|
86
|
+
export function catalogWithOwn(own) {
|
|
87
|
+
if (own.length === 0) {
|
|
88
|
+
return datalayerCatalog;
|
|
89
|
+
}
|
|
90
|
+
return catalogOfBlocks([...datalayerCatalog.components.keys(), ...own.map(each => each.name)], own);
|
|
70
91
|
}
|
|
@@ -1,59 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The Agent Inspector: what agents do,
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
2
|
+
* The Agent Inspector: what agents do, as the OpenTelemetry spans the page
|
|
3
|
+
* records (`agentSpans`, `chatSpans`, `a2aSpans`), drawn by core's OTEL view
|
|
4
|
+
* (`OtelLiveSpans`): each turn a trace, its tool calls and its A2A requests
|
|
5
|
+
* under it, newest last; a span opens to its attributes (a call's arguments
|
|
6
|
+
* and result, a request whole), its events (what the peer answered, event by
|
|
7
|
+
* event) and its trace tree.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* Fed by a sink (`useAgentInspector`) or given its entries.
|
|
9
|
+
* One agent's own (`agent`): what it did, and what was sent to it — one A2A
|
|
10
|
+
* request shows in the asker's and in the peer's. Filters by source (A2A,
|
|
11
|
+
* MCP, frontend tool, skill, codemode, runtime tool, model), operation and
|
|
12
|
+
* agent; *Pause*, *Clear*, *Export* as the OTEL view has them.
|
|
13
13
|
*
|
|
14
14
|
* @module components/inspector/AgentInspector
|
|
15
15
|
*/
|
|
16
16
|
import type { JSX } from 'react';
|
|
17
|
-
import
|
|
17
|
+
import type { OtelLiveTracer } from '@datalayer/core/lib/otel/live';
|
|
18
|
+
import type { OtelSpan } from '@datalayer/core/lib/otel/types';
|
|
19
|
+
import { type OtelSpanFacet } from '@datalayer/core/lib/otel/views/OtelLiveSpans';
|
|
18
20
|
export type AgentInspectorProps = {
|
|
19
21
|
/** The record to show, kept current. */
|
|
20
|
-
|
|
21
|
-
/** Or its
|
|
22
|
-
|
|
23
|
-
/**
|
|
22
|
+
tracer?: OtelLiveTracer | null;
|
|
23
|
+
/** Or its spans, as given. */
|
|
24
|
+
spans?: readonly OtelSpan[];
|
|
25
|
+
/** One agent's own record: what it did, and what was sent to it. */
|
|
26
|
+
agent?: string;
|
|
27
|
+
/** How tall the list grows before it scrolls. */
|
|
24
28
|
maxHeight?: number | string;
|
|
25
|
-
/**
|
|
26
|
-
|
|
29
|
+
/** Narrower, the detail under the list: beside other content. */
|
|
30
|
+
compact?: boolean;
|
|
27
31
|
/** What is said while nothing is recorded. */
|
|
28
32
|
emptyText?: string;
|
|
29
|
-
/** The file
|
|
33
|
+
/** The file the spans are exported as, without `.json`. */
|
|
30
34
|
exportName?: string;
|
|
31
|
-
/**
|
|
32
|
-
* One agent's own record: what it did (`actor`), and the A2A messages it
|
|
33
|
-
* sent or received — one message shows in the sender's and in the
|
|
34
|
-
* receiver's, the same entry, as sent in one and received in the other.
|
|
35
|
-
*/
|
|
36
|
-
agent?: string;
|
|
37
|
-
};
|
|
38
|
-
/** Whether an entry is one agent's: done by it, or sent to or by it. */
|
|
39
|
-
export declare function isAgentsEntry(entry: AgentInspectorEntry, agent: string): boolean;
|
|
40
|
-
/** Which way an entry went, from one agent's side: `→ Accounting`, `← Accounting`. */
|
|
41
|
-
export declare function directionFrom(entry: AgentInspectorEntry, agent: string | undefined): string;
|
|
42
|
-
/** A time of day, to the millisecond: `15:44:31.299`. */
|
|
43
|
-
export declare function clockTime(at: number): string;
|
|
44
|
-
/** Time since the first entry: `+1.204s`. */
|
|
45
|
-
export declare function sinceFirst(at: number, first: number): string;
|
|
46
|
-
/** How long a call took: `412 ms`, `3.4 s`. */
|
|
47
|
-
export declare function durationText(ms: number): string;
|
|
48
|
-
export type AgentInspectorFilter = {
|
|
49
|
-
sources: ReadonlySet<AgentInspectorSource>;
|
|
50
|
-
kinds: ReadonlySet<string>;
|
|
51
|
-
actors: ReadonlySet<string>;
|
|
52
35
|
};
|
|
53
|
-
/** The
|
|
54
|
-
export declare
|
|
55
|
-
/** A session, as JSON. */
|
|
56
|
-
export declare function exportEntries(entries: readonly AgentInspectorEntry[]): AgentInspectorExport;
|
|
36
|
+
/** The Inspector's filters: where a span comes from, what it does, which agent. */
|
|
37
|
+
export declare const AGENT_INSPECTOR_FACETS: readonly OtelSpanFacet[];
|
|
57
38
|
/** The Agent Inspector. */
|
|
58
|
-
export declare function AgentInspector({
|
|
39
|
+
export declare function AgentInspector({ tracer, spans, agent, maxHeight, compact, emptyText, exportName, }: AgentInspectorProps): JSX.Element;
|
|
59
40
|
export default AgentInspector;
|