@datalayer/agent-runtimes 1.3.25 → 1.3.28
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/messages/ChatMessages.d.ts +4 -4
- package/lib/chat/messages/ChatMessages.js +17 -17
- package/lib/config/AgentConfiguration.js +1 -1
- package/lib/examples/example-selector.js +1 -1
- package/lib/loop/apps/AppRenderer.d.ts +8 -1
- package/lib/loop/apps/AppRenderer.js +10 -2
- package/lib/loop/apps/checks.d.ts +6 -1
- package/lib/loop/apps/checks.js +17 -0
- package/lib/loop/embed/LoopEmbed.js +14 -1
- package/lib/loop/plugins/chat/ChatView.js +40 -6
- package/lib/loop/plugins/chat/Presence.d.ts +9 -0
- package/lib/loop/plugins/chat/Presence.js +57 -0
- package/lib/loop/plugins/chat/index.d.ts +27 -0
- package/lib/loop/plugins/chat/presenceStatus.d.ts +26 -0
- package/lib/loop/plugins/chat/presenceStatus.js +28 -0
- package/lib/loop/presets.d.ts +5 -1
- package/lib/loop/presets.js +4 -2
- package/lib/protocols/A2AAdapter.d.ts +1 -1
- package/lib/specs/uiPlugins.d.ts +6 -1
- package/lib/specs/uiPlugins.js +471 -0
- package/lib/stores/chatStore.d.ts +11 -11
- package/lib/stores/chatStore.js +34 -34
- package/lib/stores/index.d.ts +1 -1
- package/lib/stores/index.js +1 -1
- package/lib/types/agentspecs.d.ts +33 -0
- package/lib/types/index.d.ts +1 -1
- package/lib/types/index.js +1 -1
- package/lib/types/{extensions.d.ts → uiPlugins.d.ts} +49 -49
- package/lib/types/{extensions.js → uiPlugins.js} +8 -8
- package/lib/{extensions/A2UIExtension.d.ts → ui-plugins/A2UIPlugin.d.ts} +7 -7
- package/lib/{extensions/A2UIExtension.js → ui-plugins/A2UIPlugin.js} +4 -4
- package/lib/{extensions/MCPUIExtension.d.ts → ui-plugins/MCPUIPlugin.d.ts} +9 -9
- package/lib/{extensions/MCPUIExtension.js → ui-plugins/MCPUIPlugin.js} +6 -6
- package/lib/ui-plugins/UIPluginRegistry.d.ts +65 -0
- package/lib/{extensions/ExtensionRegistry.js → ui-plugins/UIPluginRegistry.js} +32 -32
- package/lib/ui-plugins/index.d.ts +9 -0
- package/lib/ui-plugins/index.js +12 -0
- package/package.json +1 -1
- package/scripts/codegen/generate_agents.py +6 -6
- package/scripts/codegen/generate_ui_plugins.py +64 -4
- package/lib/extensions/ExtensionRegistry.d.ts +0 -65
- package/lib/extensions/index.d.ts +0 -9
- package/lib/extensions/index.js +0 -12
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* UI plugin exports for the chat: how an agent's answer becomes an interface (A2UI, MCP UI).
|
|
7
|
+
*
|
|
8
|
+
* @module components/uiPlugins
|
|
9
|
+
*/
|
|
10
|
+
export { UIPluginRegistry } from './UIPluginRegistry';
|
|
11
|
+
export { createA2UIRenderer, A2UIPluginImpl, } from './A2UIPlugin';
|
|
12
|
+
export { createMCPUIRenderer, MCPUIPluginImpl, } from './MCPUIPlugin';
|
package/package.json
CHANGED
|
@@ -455,8 +455,8 @@ from agent_runtimes.types import (
|
|
|
455
455
|
protocol_val = spec.get("protocol")
|
|
456
456
|
protocol_str = f'"{protocol_val}"' if protocol_val else "None"
|
|
457
457
|
delegable_str = _fmt_py_delegable(spec.get("delegable", []))
|
|
458
|
-
|
|
459
|
-
|
|
458
|
+
ui_plugin = spec.get("ui_plugin")
|
|
459
|
+
ui_plugin_str = f'"{ui_plugin}"' if ui_plugin else "None"
|
|
460
460
|
trigger_val = spec.get("trigger")
|
|
461
461
|
model_cfg = spec.get("model_config")
|
|
462
462
|
mcp_srv_tools = spec.get("mcp_server_tools")
|
|
@@ -567,7 +567,7 @@ from agent_runtimes.types import (
|
|
|
567
567
|
goal={goal_str},
|
|
568
568
|
delegable={delegable_str},
|
|
569
569
|
protocol={protocol_str},
|
|
570
|
-
ui_plugin={
|
|
570
|
+
ui_plugin={ui_plugin_str},
|
|
571
571
|
trigger={_fmt_py_literal(trigger_val)},
|
|
572
572
|
model_configuration={_fmt_py_literal(model_cfg)},
|
|
573
573
|
mcp_server_tools={_fmt_py_literal(mcp_srv_tools)},
|
|
@@ -1075,8 +1075,8 @@ const FRONTEND_TOOL_MAP: Record<string, any> = {
|
|
|
1075
1075
|
protocol_val = spec.get("protocol")
|
|
1076
1076
|
protocol_ts = f"'{protocol_val}'" if protocol_val else "undefined"
|
|
1077
1077
|
delegable_ts = _fmt_ts_delegable(spec.get("delegable", []))
|
|
1078
|
-
|
|
1079
|
-
|
|
1078
|
+
ui_plugin = spec.get("ui_plugin")
|
|
1079
|
+
ui_plugin_ts = f"'{ui_plugin}'" if ui_plugin else "undefined"
|
|
1080
1080
|
trigger_val = spec.get("trigger")
|
|
1081
1081
|
model_cfg = spec.get("model_config")
|
|
1082
1082
|
mcp_srv_tools = spec.get("mcp_server_tools")
|
|
@@ -1135,7 +1135,7 @@ const FRONTEND_TOOL_MAP: Record<string, any> = {
|
|
|
1135
1135
|
goal: {goal_ts},
|
|
1136
1136
|
delegable: {delegable_ts},
|
|
1137
1137
|
protocol: {protocol_ts},
|
|
1138
|
-
uiPlugin: {
|
|
1138
|
+
uiPlugin: {ui_plugin_ts},
|
|
1139
1139
|
trigger: {_fmt_ts_literal(trigger_val)},
|
|
1140
1140
|
modelConfig: {_fmt_ts_literal(model_cfg)},
|
|
1141
1141
|
mcpServerTools: {_fmt_ts_literal(mcp_srv_tools)},
|
|
@@ -8,7 +8,7 @@ Generate Python and TypeScript code from YAML UI-plugin specifications.
|
|
|
8
8
|
A UI plugin is how an agent's answer becomes an interface rather than text —
|
|
9
9
|
a protocol the host knows how to render (A2UI, MCP Apps, MCP UI). One YAML per
|
|
10
10
|
plugin under ``agentspecs/ui-plugins``; an agent spec's ``ui_plugin`` names
|
|
11
|
-
one.
|
|
11
|
+
one. A plugin hosts the visual components it renders (LOOP C-13).
|
|
12
12
|
|
|
13
13
|
Usage:
|
|
14
14
|
python generate_ui_plugins.py \\
|
|
@@ -18,6 +18,7 @@ Usage:
|
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
20
|
import argparse
|
|
21
|
+
import json
|
|
21
22
|
import sys
|
|
22
23
|
from pathlib import Path
|
|
23
24
|
from typing import Any
|
|
@@ -53,6 +54,25 @@ def _ts(value: str) -> str:
|
|
|
53
54
|
return "'" + value.replace("\\", "\\\\").replace("'", "\\'") + "'"
|
|
54
55
|
|
|
55
56
|
|
|
57
|
+
def _py_component(component: dict[str, Any]) -> str:
|
|
58
|
+
"""A component as the Python that builds it."""
|
|
59
|
+
bindings = component.get("bindings")
|
|
60
|
+
return (
|
|
61
|
+
"ComponentSpec("
|
|
62
|
+
f"id={_py(component['id'])}, name={json.dumps(component['name'], ensure_ascii=False)}, "
|
|
63
|
+
f"description={json.dumps(component['description'].strip(), ensure_ascii=False)}, "
|
|
64
|
+
f"category={_py(component['category'])}, emoji={json.dumps(component['emoji'], ensure_ascii=False)}, "
|
|
65
|
+
f"standard={bool(component['standard'])}, "
|
|
66
|
+
f"properties={component.get('properties')!r}, "
|
|
67
|
+
+ (
|
|
68
|
+
f"bindings=ComponentBindingsSpec(shows={bindings['shows']!r}, sends={bindings['sends']!r}), "
|
|
69
|
+
if bindings
|
|
70
|
+
else "bindings=None, "
|
|
71
|
+
)
|
|
72
|
+
+ f"events={component.get('events') or []!r}, example={component.get('example')!r})"
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
56
76
|
def generate_python_code(specs: list[dict[str, Any]]) -> str:
|
|
57
77
|
"""Generate Python code from UI-plugin specifications."""
|
|
58
78
|
lines = [
|
|
@@ -69,8 +89,7 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
|
|
|
69
89
|
"",
|
|
70
90
|
"from typing import Dict",
|
|
71
91
|
"",
|
|
72
|
-
"from agent_runtimes.types import UIPluginSpec",
|
|
73
|
-
"",
|
|
92
|
+
"from agent_runtimes.types import ComponentBindingsSpec, ComponentSpec, UIPluginSpec",
|
|
74
93
|
"",
|
|
75
94
|
"# " + "=" * 76,
|
|
76
95
|
"# UI Plugin Definitions",
|
|
@@ -88,6 +107,10 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
|
|
|
88
107
|
f" description={_py(str(spec.get('description', '')).strip())},",
|
|
89
108
|
f" docs_url={_py(str(spec.get('docs_url', '')))},",
|
|
90
109
|
f" enabled={bool(spec.get('enabled', True))},",
|
|
110
|
+
f" catalog={_py(str(spec.get('catalog', '')))},",
|
|
111
|
+
" components=[",
|
|
112
|
+
*[f" {_py_component(c)}," for c in spec.get("components") or []],
|
|
113
|
+
" ],",
|
|
91
114
|
")",
|
|
92
115
|
"",
|
|
93
116
|
]
|
|
@@ -119,6 +142,25 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
|
|
|
119
142
|
"def list_ui_plugins() -> list[UIPluginSpec]:",
|
|
120
143
|
" return list(UI_PLUGIN_CATALOGUE.values())",
|
|
121
144
|
"",
|
|
145
|
+
"",
|
|
146
|
+
"#: The visual components the enabled UI plugins render, by the name a",
|
|
147
|
+
"#: surface gives them (LOOP C-13).",
|
|
148
|
+
"COMPONENT_CATALOGUE: Dict[str, ComponentSpec] = {",
|
|
149
|
+
" component.id: component",
|
|
150
|
+
" for plugin in UI_PLUGIN_CATALOGUE.values()",
|
|
151
|
+
" if plugin.enabled",
|
|
152
|
+
" for component in plugin.components",
|
|
153
|
+
"}",
|
|
154
|
+
"",
|
|
155
|
+
"",
|
|
156
|
+
"def get_component(name: str) -> ComponentSpec | None:",
|
|
157
|
+
' """The component a layout names, or None."""',
|
|
158
|
+
" return COMPONENT_CATALOGUE.get(name)",
|
|
159
|
+
"",
|
|
160
|
+
"",
|
|
161
|
+
"def list_components() -> list[ComponentSpec]:",
|
|
162
|
+
" return list(COMPONENT_CATALOGUE.values())",
|
|
163
|
+
"",
|
|
122
164
|
]
|
|
123
165
|
)
|
|
124
166
|
return "\n".join(lines)
|
|
@@ -141,7 +183,7 @@ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
|
|
|
141
183
|
" * DO NOT EDIT MANUALLY - run 'make specs' to regenerate.",
|
|
142
184
|
" */",
|
|
143
185
|
"",
|
|
144
|
-
"import type { UIPluginSpec } from '../types/agentspecs';",
|
|
186
|
+
"import type { ComponentSpec, UIPluginSpec } from '../types/agentspecs';",
|
|
145
187
|
"",
|
|
146
188
|
]
|
|
147
189
|
for spec in specs:
|
|
@@ -155,6 +197,8 @@ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
|
|
|
155
197
|
f" description: {_ts(str(spec.get('description', '')).strip())},",
|
|
156
198
|
f" docsUrl: {_ts(str(spec.get('docs_url', '')))},",
|
|
157
199
|
f" enabled: {'true' if spec.get('enabled', True) else 'false'},",
|
|
200
|
+
f" catalog: {_ts(str(spec.get('catalog', '')))},",
|
|
201
|
+
f" components: {json.dumps([{**c, 'events': c.get('events', [])} for c in spec.get('components') or []], indent=2, ensure_ascii=False)},",
|
|
158
202
|
"};",
|
|
159
203
|
"",
|
|
160
204
|
]
|
|
@@ -177,6 +221,22 @@ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
|
|
|
177
221
|
" return Object.values(UI_PLUGIN_CATALOGUE);",
|
|
178
222
|
"}",
|
|
179
223
|
"",
|
|
224
|
+
"/** The visual components the enabled UI plugins render, by the name a surface gives them (LOOP C-13). */",
|
|
225
|
+
"export const COMPONENT_CATALOGUE: Record<string, ComponentSpec> = Object.fromEntries(",
|
|
226
|
+
" Object.values(UI_PLUGIN_CATALOGUE)",
|
|
227
|
+
" .filter(plugin => plugin.enabled)",
|
|
228
|
+
" .flatMap(plugin => plugin.components.map(component => [component.id, component])),",
|
|
229
|
+
");",
|
|
230
|
+
"",
|
|
231
|
+
"/** The component a layout names, or undefined. */",
|
|
232
|
+
"export function getComponent(name: string): ComponentSpec | undefined {",
|
|
233
|
+
" return COMPONENT_CATALOGUE[name];",
|
|
234
|
+
"}",
|
|
235
|
+
"",
|
|
236
|
+
"export function listComponents(): ComponentSpec[] {",
|
|
237
|
+
" return Object.values(COMPONENT_CATALOGUE);",
|
|
238
|
+
"}",
|
|
239
|
+
"",
|
|
180
240
|
]
|
|
181
241
|
)
|
|
182
242
|
return "\n".join(lines)
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Extension registry for chat component.
|
|
3
|
-
* Manages custom renderers and extension points.
|
|
4
|
-
*
|
|
5
|
-
* @module components/extensions/ExtensionRegistry
|
|
6
|
-
*/
|
|
7
|
-
import type { ChatExtension, MessageRendererExtension, ActivityRendererExtension, ToolUIExtension, ProtocolEventExtension, PanelExtension } from '../types/extensions';
|
|
8
|
-
/** Internal extension type for registry organization */
|
|
9
|
-
export type InternalExtensionType = 'message-renderer' | 'activity-renderer' | 'tool-ui' | 'protocol-event' | 'panel';
|
|
10
|
-
/**
|
|
11
|
-
* Extension registry class
|
|
12
|
-
*/
|
|
13
|
-
export declare class ExtensionRegistry {
|
|
14
|
-
private extensions;
|
|
15
|
-
private byType;
|
|
16
|
-
constructor();
|
|
17
|
-
/**
|
|
18
|
-
* Register an extension
|
|
19
|
-
*/
|
|
20
|
-
register(extension: ChatExtension): void;
|
|
21
|
-
/**
|
|
22
|
-
* Unregister an extension
|
|
23
|
-
*/
|
|
24
|
-
unregister(extensionName: string): void;
|
|
25
|
-
/**
|
|
26
|
-
* Get an extension by name
|
|
27
|
-
*/
|
|
28
|
-
get<T extends ChatExtension>(extensionName: string): T | undefined;
|
|
29
|
-
/**
|
|
30
|
-
* Get all extensions of a specific type
|
|
31
|
-
*/
|
|
32
|
-
getByType<T extends ChatExtension>(type: InternalExtensionType): T[];
|
|
33
|
-
/**
|
|
34
|
-
* Get all registered extensions
|
|
35
|
-
*/
|
|
36
|
-
getAll(): ChatExtension[];
|
|
37
|
-
/**
|
|
38
|
-
* Check if an extension is registered
|
|
39
|
-
*/
|
|
40
|
-
has(extensionName: string): boolean;
|
|
41
|
-
/**
|
|
42
|
-
* Get message renderers
|
|
43
|
-
*/
|
|
44
|
-
getMessageRenderers(): MessageRendererExtension[];
|
|
45
|
-
/**
|
|
46
|
-
* Get activity renderer for a specific activity type
|
|
47
|
-
*/
|
|
48
|
-
getActivityRenderer(activityType: string): ActivityRendererExtension | undefined;
|
|
49
|
-
/**
|
|
50
|
-
* Get tool UI for a specific tool
|
|
51
|
-
*/
|
|
52
|
-
getToolUI(toolName: string): ToolUIExtension | undefined;
|
|
53
|
-
/**
|
|
54
|
-
* Get all panels
|
|
55
|
-
*/
|
|
56
|
-
getPanels(): PanelExtension[];
|
|
57
|
-
/**
|
|
58
|
-
* Get protocol event handlers for an event type
|
|
59
|
-
*/
|
|
60
|
-
getProtocolEventHandlers(eventType: string): ProtocolEventExtension[];
|
|
61
|
-
/**
|
|
62
|
-
* Clear all extensions
|
|
63
|
-
*/
|
|
64
|
-
clear(): void;
|
|
65
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Extension exports for chat component.
|
|
3
|
-
*
|
|
4
|
-
* @module components/extensions
|
|
5
|
-
*/
|
|
6
|
-
export { ExtensionRegistry } from './ExtensionRegistry';
|
|
7
|
-
export type { InternalExtensionType } from './ExtensionRegistry';
|
|
8
|
-
export { createA2UIRenderer, A2UIExtensionImpl, type A2UIMessage, } from './A2UIExtension';
|
|
9
|
-
export { createMCPUIRenderer, MCPUIExtensionImpl, type MCPUIMessage, type MCPUIResource, } from './MCPUIExtension';
|
package/lib/extensions/index.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
-
* Distributed under the terms of the Modified BSD License.
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* Extension exports for chat component.
|
|
7
|
-
*
|
|
8
|
-
* @module components/extensions
|
|
9
|
-
*/
|
|
10
|
-
export { ExtensionRegistry } from './ExtensionRegistry';
|
|
11
|
-
export { createA2UIRenderer, A2UIExtensionImpl, } from './A2UIExtension';
|
|
12
|
-
export { createMCPUIRenderer, MCPUIExtensionImpl, } from './MCPUIExtension';
|