@datalayer/agent-runtimes 1.3.74 → 1.3.78

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.
Files changed (143) hide show
  1. package/lib/agents/AgentDetails.d.ts +16 -2
  2. package/lib/agents/AgentDetails.js +381 -272
  3. package/lib/chat/ChatFloating.d.ts +27 -1
  4. package/lib/chat/ChatFloating.js +97 -13
  5. package/lib/chat/assistant/AgentDetailsDialog.d.ts +21 -0
  6. package/lib/chat/assistant/AgentDetailsDialog.js +19 -0
  7. package/lib/chat/assistant/AssistantContextMenu.d.ts +67 -0
  8. package/lib/chat/assistant/AssistantContextMenu.js +68 -0
  9. package/lib/chat/assistant/AssistantStage.d.ts +144 -4
  10. package/lib/chat/assistant/AssistantStage.js +280 -10
  11. package/lib/chat/assistant/BalloonParts.d.ts +33 -5
  12. package/lib/chat/assistant/BalloonParts.js +66 -44
  13. package/lib/chat/assistant/BalloonVisual.d.ts +10 -2
  14. package/lib/chat/assistant/BalloonVisual.js +4 -3
  15. package/lib/chat/assistant/SandboxDetailsDialog.d.ts +44 -0
  16. package/lib/chat/assistant/SandboxDetailsDialog.js +214 -0
  17. package/lib/chat/assistant/SpeechBalloon.d.ts +54 -6
  18. package/lib/chat/assistant/SpeechBalloon.js +73 -22
  19. package/lib/chat/assistant/assistantDetails.d.ts +84 -0
  20. package/lib/chat/assistant/assistantDetails.js +140 -0
  21. package/lib/chat/assistant/formats/files.d.ts +23 -0
  22. package/lib/chat/assistant/formats/files.js +48 -0
  23. package/lib/chat/assistant/formats/index.d.ts +2 -0
  24. package/lib/chat/assistant/formats/index.js +1 -0
  25. package/lib/chat/assistant/state.d.ts +7 -14
  26. package/lib/chat/assistant/state.js +21 -20
  27. package/lib/chat/assistant/toolLine.d.ts +16 -0
  28. package/lib/chat/assistant/toolLine.js +46 -0
  29. package/lib/chat/base/ChatBase.js +71 -1
  30. package/lib/chat/base/loopMessage.d.ts +37 -0
  31. package/lib/chat/base/loopMessage.js +37 -0
  32. package/lib/chat/indicators/TypingDots.d.ts +13 -0
  33. package/lib/chat/indicators/TypingDots.js +21 -0
  34. package/lib/chat/messages/ChatMarkdown.d.ts +16 -0
  35. package/lib/chat/messages/ChatMarkdown.js +18 -0
  36. package/lib/chat/messages/ChatMessageList.d.ts +8 -1
  37. package/lib/chat/messages/ChatMessageList.js +25 -33
  38. package/lib/chat/styles/streamdownStyles.js +3 -1
  39. package/lib/chat/tools/ToolCallDisplay.d.ts +8 -1
  40. package/lib/chat/tools/ToolCallDisplay.js +8 -7
  41. package/lib/components/code-sandboxes/CodeSandboxCellVariablesDialog.js +5 -11
  42. package/lib/components/code-sandboxes/CodeSandboxVariables.d.ts +8 -0
  43. package/lib/components/code-sandboxes/CodeSandboxVariables.js +17 -11
  44. package/lib/components/inspector/AgentInspector.d.ts +59 -0
  45. package/lib/components/inspector/AgentInspector.js +220 -0
  46. package/lib/components/inspector/AgentInspectorDialog.d.ts +19 -0
  47. package/lib/components/inspector/AgentInspectorDialog.js +9 -0
  48. package/lib/components/inspector/JsonTree.d.ts +24 -0
  49. package/lib/components/inspector/JsonTree.js +89 -0
  50. package/lib/components/inspector/a2aInspect.d.ts +56 -0
  51. package/lib/components/inspector/a2aInspect.js +478 -0
  52. package/lib/components/inspector/agentInspector.d.ts +179 -0
  53. package/lib/components/inspector/agentInspector.js +267 -0
  54. package/lib/components/inspector/chatInspect.d.ts +38 -0
  55. package/lib/components/inspector/chatInspect.js +65 -0
  56. package/lib/components/inspector/classify.d.ts +19 -0
  57. package/lib/components/inspector/classify.js +42 -0
  58. package/lib/components/inspector/index.d.ts +14 -0
  59. package/lib/components/inspector/index.js +18 -0
  60. package/lib/components/teams/A2ATeamGraph.d.ts +69 -1
  61. package/lib/components/teams/A2ATeamGraph.js +277 -37
  62. package/lib/components/teams/NotebookPreviewView.js +9 -1
  63. package/lib/components/teams/TeamNotebook.d.ts +3 -1
  64. package/lib/components/teams/TeamNotebook.js +3 -3
  65. package/lib/components/teams/TeamNotebookView.js +15 -0
  66. package/lib/components/teams/jupyterThemeVariables.d.ts +9 -0
  67. package/lib/components/teams/jupyterThemeVariables.js +441 -0
  68. package/lib/components/teams/teamConnections.d.ts +9 -1
  69. package/lib/components/teams/teamConnections.js +20 -0
  70. package/lib/components/teams/teamNotebookKernel.d.ts +3 -0
  71. package/lib/components/teams/teamNotebookKernel.js +17 -0
  72. package/lib/components/teams/useA2ATeam.d.ts +20 -3
  73. package/lib/components/teams/useA2ATeam.js +108 -23
  74. package/lib/examples/AgentA2ATeamExample.d.ts +13 -0
  75. package/lib/examples/AgentA2ATeamExample.js +67 -13
  76. package/lib/examples/AssistantExample.js +65 -26
  77. package/lib/examples/AssistantGalleryExample.js +2 -1
  78. package/lib/examples/exampleGroups.d.ts +1 -1
  79. package/lib/examples/exampleGroups.js +1 -1
  80. package/lib/examples/utils/assistantGallery.d.ts +7 -6
  81. package/lib/examples/utils/assistantGallery.js +23 -8
  82. package/lib/jupyter/exec/Python.d.ts +0 -1
  83. package/lib/jupyter/exec/Python.js +0 -32
  84. package/lib/jupyter/exec/Snippets.d.ts +4 -12
  85. package/lib/jupyter/exec/Snippets.js +0 -8
  86. package/lib/loop/apps/AppFeedback.js +3 -1
  87. package/lib/loop/apps/AppKept.d.ts +22 -0
  88. package/lib/loop/apps/AppKept.js +36 -0
  89. package/lib/loop/apps/AppRenderer.d.ts +11 -1
  90. package/lib/loop/apps/AppRenderer.js +22 -4
  91. package/lib/loop/apps/checks.d.ts +7 -0
  92. package/lib/loop/apps/checks.js +39 -0
  93. package/lib/loop/apps/index.d.ts +3 -0
  94. package/lib/loop/apps/index.js +3 -0
  95. package/lib/loop/apps/kept.d.ts +30 -0
  96. package/lib/loop/apps/kept.js +52 -0
  97. package/lib/loop/apps/records.d.ts +12 -4
  98. package/lib/loop/apps/records.js +13 -5
  99. package/lib/loop/apps/saved.d.ts +30 -0
  100. package/lib/loop/apps/saved.js +40 -0
  101. package/lib/loop/core/index.d.ts +17 -0
  102. package/lib/loop/core/index.js +1 -0
  103. package/lib/loop/embed/AppEmbed.d.ts +8 -1
  104. package/lib/loop/embed/AppEmbed.js +4 -4
  105. package/lib/loop/embed/LoopEmbed.d.ts +6 -1
  106. package/lib/loop/embed/LoopEmbed.js +4 -2
  107. package/lib/loop/embed/element.js +1 -1
  108. package/lib/loop/plugins/agents/DatalayerAgentBridge.js +12 -6
  109. package/lib/loop/plugins/agents/browserService.d.ts +7 -1
  110. package/lib/loop/plugins/agents/browserService.js +4 -0
  111. package/lib/loop/plugins/agents/plugin.d.ts +16 -0
  112. package/lib/loop/plugins/agents/switchable.d.ts +3 -0
  113. package/lib/loop/plugins/agents/switchable.js +1 -0
  114. package/lib/loop/plugins/app-activity/index.js +3 -0
  115. package/lib/loop/plugins/app-computer/index.js +3 -0
  116. package/lib/loop/plugins/app-rules/AppRulesCard.d.ts +5 -0
  117. package/lib/loop/plugins/app-rules/AppRulesCard.js +25 -6
  118. package/lib/loop/plugins/app-rules/index.js +3 -0
  119. package/lib/loop/plugins/assistant/index.d.ts +7 -2
  120. package/lib/loop/plugins/assistant/index.js +58 -4
  121. package/lib/loop/plugins/assistant-characters/index.d.ts +7 -0
  122. package/lib/loop/plugins/assistant-characters/index.js +17 -0
  123. package/lib/loop/plugins/chat/ChatView.js +4 -1
  124. package/lib/loop/plugins/page-layout/SplitLayout.d.ts +2 -1
  125. package/lib/loop/plugins/page-layout/SplitLayout.js +4 -0
  126. package/lib/loop/presets.d.ts +4 -0
  127. package/lib/loop/presets.js +3 -1
  128. package/lib/loop/shell/LoopWorkspace.d.ts +7 -0
  129. package/lib/loop/shell/LoopWorkspace.js +5 -4
  130. package/lib/loop/shell/SidebarRail.d.ts +53 -0
  131. package/lib/loop/shell/SidebarRail.js +74 -0
  132. package/lib/loop/shell/index.d.ts +2 -0
  133. package/lib/loop/shell/index.js +2 -0
  134. package/lib/loop/shell/paneMotion.d.ts +21 -0
  135. package/lib/loop/shell/paneMotion.js +37 -0
  136. package/lib/runtimes/browser/a2aPeer.d.ts +4 -1
  137. package/lib/specs/apps.js +8 -5
  138. package/lib/specs/uiPlugins.js +529 -0
  139. package/lib/types/agentspecs.d.ts +5 -3
  140. package/lib/types/chat.d.ts +12 -0
  141. package/package.json +2 -2
  142. package/scripts/codegen/generate_jupyter_theme_variables.mjs +57 -0
  143. package/scripts/codegen/generate_ui_plugins.py +112 -2
@@ -89,10 +89,12 @@ export interface ComponentSpec {
89
89
  category: string;
90
90
  /** Its face on the palette. */
91
91
  emoji: string;
92
- /** Its properties are its protocol's own. */
92
+ /** Its version in the catalog. */
93
+ version: string;
94
+ /** Named and drawn as its protocol says (A2UI's basic catalog). */
93
95
  standard: boolean;
94
- /** Its properties as a JSON Schema, when it is Datalayer's own. */
95
- properties?: Record<string, unknown>;
96
+ /** Its properties as a JSON Schema: what a builder sets (C-13). */
97
+ properties: Record<string, unknown>;
96
98
  /** What it can be bound to: what it shows, what it sends. */
97
99
  bindings?: {
98
100
  shows: string[];
@@ -8,6 +8,7 @@ import type { ComponentType, ReactNode } from 'react';
8
8
  import type { ICollaborationProvider } from '@datalayer/jupyter-react';
9
9
  import type { ChatMessage, MessageHandler } from './messages';
10
10
  import type { Protocol, ProtocolConfig } from './protocol';
11
+ import type { AgentInspectorSink } from '../components/inspector/agentInspector';
11
12
  import type { McpServerSelection } from './inference';
12
13
  import type { MCPServerTool } from './mcp';
13
14
  import type { AgentRuntimeConfig } from './config';
@@ -152,6 +153,11 @@ export interface ToolCallMessage {
152
153
  };
153
154
  /** Exit code when code called sys.exit() */
154
155
  exitCode?: number | null;
156
+ /**
157
+ * What the tool does, in its runtime's own words (`Asking Accounting…`):
158
+ * shown in place of its arguments' summary.
159
+ */
160
+ summary?: string;
155
161
  }
156
162
  /**
157
163
  * Union type for all displayable items in the chat
@@ -1238,6 +1244,12 @@ export interface ChatBaseProps {
1238
1244
  * ```
1239
1245
  */
1240
1246
  onToolCallComplete?: (context: ToolCallCompleteContext) => void;
1247
+ /**
1248
+ * The Agent Inspector's sink: the agent's turns (its model, its tokens)
1249
+ * and its tool calls, from start to end, are recorded there. Without it,
1250
+ * the sink of the nearest `AgentInspectorProvider`, if any.
1251
+ */
1252
+ inspector?: AgentInspectorSink | null;
1241
1253
  /**
1242
1254
  * Whether to render the top-of-chat tool approval banner (and its review
1243
1255
  * dialog) when `pendingApprovals` is non-empty. The banner/dialog render
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datalayer/agent-runtimes",
3
- "version": "1.3.74",
3
+ "version": "1.3.78",
4
4
  "type": "module",
5
5
  "workspaces": [
6
6
  ".",
@@ -151,7 +151,7 @@
151
151
  "@datalayer/decks": "^1.0.4",
152
152
  "@datalayer/icons-react": "^1.0.16",
153
153
  "@datalayer/jupyter-lexical": "^2.0.18",
154
- "@datalayer/jupyter-react": "^2.0.18",
154
+ "@datalayer/jupyter-react": "^2.0.19",
155
155
  "@datalayer/jupyter-server-nbmodel": "^0.2.8",
156
156
  "@datalayer/lexical-loro": "^1.0.6",
157
157
  "@datalayer/primer-addons": "^1.0.23",
@@ -0,0 +1,57 @@
1
+ /*
2
+ * Copyright (c) 2025-2026 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+
6
+ /**
7
+ * Writes src/components/teams/jupyterThemeVariables.ts: JupyterLab's light
8
+ * and dark theme variables (`--jp-*`), read from the theme extensions'
9
+ * variables.css, so a notebook preview can carry its own mode on its own
10
+ * subtree — JupyterLab writes them for the whole page.
11
+ *
12
+ * node scripts/codegen/generate_jupyter_theme_variables.mjs
13
+ */
14
+ import { readFileSync, writeFileSync } from 'node:fs';
15
+ import { createRequire } from 'node:module';
16
+
17
+ const require = createRequire(import.meta.url);
18
+
19
+ function variables(pkg) {
20
+ const css = readFileSync(require.resolve(`${pkg}/style/variables.css`), 'utf8')
21
+ .replace(/\/\*[\s\S]*?\*\//g, '');
22
+ const out = {};
23
+ for (const block of css.matchAll(/:root\s*\{([\s\S]*?)\}/g)) {
24
+ for (const declaration of block[1].split(';')) {
25
+ const match = /^\s*(--jp-[\w-]+)\s*:\s*([\s\S]+?)\s*$/.exec(declaration);
26
+ if (match) {
27
+ out[match[1]] = match[2].replace(/\s+/g, ' ');
28
+ }
29
+ }
30
+ }
31
+ return out;
32
+ }
33
+
34
+ const light = variables('@jupyterlab/theme-light-extension');
35
+ const dark = variables('@jupyterlab/theme-dark-extension');
36
+ const target = new URL('../../src/components/teams/jupyterThemeVariables.ts', import.meta.url);
37
+ writeFileSync(
38
+ target,
39
+ `/*
40
+ * Copyright (c) 2025-2026 Datalayer, Inc.
41
+ * Distributed under the terms of the Modified BSD License.
42
+ */
43
+
44
+ /**
45
+ * JupyterLab's theme variables, light and dark, as its theme extensions state
46
+ * them. Generated by scripts/codegen/generate_jupyter_theme_variables.mjs: do
47
+ * not edit.
48
+ *
49
+ * @module components/teams/jupyterThemeVariables
50
+ */
51
+
52
+ export const JUPYTER_LIGHT_VARIABLES: Readonly<Record<string, string>> = ${JSON.stringify(light, null, 2)};
53
+
54
+ export const JUPYTER_DARK_VARIABLES: Readonly<Record<string, string>> = ${JSON.stringify(dark, null, 2)};
55
+ `,
56
+ );
57
+ console.log(`light ${Object.keys(light).length}, dark ${Object.keys(dark).length}`);
@@ -19,6 +19,7 @@ Usage:
19
19
 
20
20
  import argparse
21
21
  import json
22
+ import re
22
23
  import sys
23
24
  from pathlib import Path
24
25
  from typing import Any
@@ -62,7 +63,7 @@ def _py_component(component: dict[str, Any]) -> str:
62
63
  f"id={_py(component['id'])}, name={json.dumps(component['name'], ensure_ascii=False)}, "
63
64
  f"description={json.dumps(component['description'].strip(), ensure_ascii=False)}, "
64
65
  f"category={_py(component['category'])}, emoji={json.dumps(component['emoji'], ensure_ascii=False)}, "
65
- f"standard={bool(component['standard'])}, "
66
+ f"version={_py(str(component['version']))}, standard={bool(component['standard'])}, "
66
67
  f"properties={component.get('properties')!r}, "
67
68
  + (
68
69
  f"bindings=ComponentBindingsSpec(shows={bindings['shows']!r}, sends={bindings['sends']!r}), "
@@ -73,6 +74,114 @@ def _py_component(component: dict[str, Any]) -> str:
73
74
  )
74
75
 
75
76
 
77
+ def call_name(component_id: str) -> str:
78
+ """The Python call of a component: ``Table`` → ``table``, ``TextField`` → ``text_field``."""
79
+ return re.sub(r"(?<!^)(?=[A-Z])", "_", component_id).lower()
80
+
81
+
82
+ def _py_type(prop: dict[str, Any]) -> str:
83
+ """The Python type of a property of a component's JSON Schema."""
84
+ if "enum" in prop:
85
+ return "Literal[" + ", ".join(json.dumps(value) for value in prop["enum"]) + "]"
86
+ kind = prop.get("type")
87
+ if kind == "array":
88
+ return f"List[{_py_type(prop.get('items') or {})}]"
89
+ return {
90
+ "string": "str",
91
+ "integer": "int",
92
+ "number": "float",
93
+ "boolean": "bool",
94
+ "object": "Dict[str, Any]",
95
+ }.get(str(kind), "Any")
96
+
97
+
98
+ def _py_calls(specs: list[dict[str, Any]]) -> list[str]:
99
+ """The catalog's components as typed calls (LOOP C-15), one method each."""
100
+ lines = [
101
+ "",
102
+ "",
103
+ "# " + "=" * 76,
104
+ "# The components as typed calls (LOOP C-15)",
105
+ "# " + "=" * 76,
106
+ "",
107
+ "#: A property bound to what the application publishes or takes: ``{\"path\": \"/runs\"}``.",
108
+ "Bound = Mapping[str, str]",
109
+ "",
110
+ "",
111
+ "class SurfaceComponents:",
112
+ ' """Every component of the catalog as a typed call: ``app.ui.table(\"runs\", columns=[...])``.',
113
+ "",
114
+ " Each places the node the Canvas and the YAML write, through",
115
+ " `Application.component`, which checks it against the same JSON Schema; an",
116
+ " IDE completes its properties, and a type checker refuses a wrong value",
117
+ " before the application runs. A property may be bound instead",
118
+ ' (``{\"path\": ...}``); a property left as ``None`` is not written.',
119
+ ' """',
120
+ "",
121
+ " def __init__(self, place: Callable[..., Dict[str, Any]]) -> None:",
122
+ " self._place = place",
123
+ ]
124
+ for spec in specs:
125
+ if not spec.get("enabled", True):
126
+ continue
127
+ for component in spec.get("components") or []:
128
+ schema = component.get("properties") or {}
129
+ required = set(schema.get("required") or [])
130
+ fields = dict(schema.get("properties") or {})
131
+ bindings = component.get("bindings") or {}
132
+ extra = [
133
+ name
134
+ for name in dict.fromkeys([*(bindings.get("shows") or []), *(bindings.get("sends") or [])])
135
+ if name not in fields
136
+ ]
137
+ params = [" self,", " id: str,", " *,"]
138
+ ordered = [n for n in fields if n in required] + [n for n in fields if n not in required]
139
+ for name in ordered:
140
+ kind = f"Union[{_py_type(fields[name])}, Bound]"
141
+ params.append(
142
+ f" {name}: {kind}," if name in required else f" {name}: Optional[{kind}] = None,"
143
+ )
144
+ for name in extra:
145
+ params.append(f" {name}: Optional[Bound] = None,")
146
+ if component.get("events") and "action" not in fields:
147
+ params.append(" action: Optional[Dict[str, Any]] = None,")
148
+ params.append(" visible_when: Optional[Bound] = None,")
149
+ params.append(" weight: Optional[float] = None,")
150
+ doc = [
151
+ f' """{component["name"]}, version {component["version"]}: {component["description"].strip()}',
152
+ "",
153
+ " Parameters",
154
+ " ----------",
155
+ " id : str",
156
+ " Its id on the surface, unique; ``root`` is where the surface starts.",
157
+ ]
158
+ for name in ordered:
159
+ field = fields[name]
160
+ doc += [f" {name} : {_py_type(field)} or Bound", f" {field.get('title', name)}: {field.get('description', '')}"]
161
+ for name in extra:
162
+ said = "What it shows" if name in (bindings.get("shows") or []) else "Where what a person does is written"
163
+ doc += [f" {name} : Bound", f" {said}."]
164
+ doc += [' """']
165
+ names = [*ordered, *extra]
166
+ if component.get("events") and "action" not in fields:
167
+ names.append("action")
168
+ names += ["visible_when", "weight"]
169
+ lines += [
170
+ "",
171
+ f" def {call_name(component['id'])}(",
172
+ *params,
173
+ " ) -> Dict[str, Any]:",
174
+ *[d.replace('\\', '\\\\') for d in doc],
175
+ " given = {",
176
+ *[f" {json.dumps(name)}: {name}," for name in names],
177
+ " }",
178
+ " return self._place(",
179
+ f" id, {_py(component['id'])}, **{{name: value for name, value in given.items() if value is not None}}",
180
+ " )",
181
+ ]
182
+ return lines
183
+
184
+
76
185
  def generate_python_code(specs: list[dict[str, Any]]) -> str:
77
186
  """Generate Python code from UI-plugin specifications."""
78
187
  lines = [
@@ -87,7 +196,7 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
87
196
  "DO NOT EDIT MANUALLY - run 'make specs' to regenerate.",
88
197
  '"""',
89
198
  "",
90
- "from typing import Dict",
199
+ "from typing import Any, Callable, Dict, List, Literal, Mapping, Optional, Union",
91
200
  "",
92
201
  "from agent_runtimes.types import ComponentBindingsSpec, ComponentSpec, UIPluginSpec",
93
202
  "",
@@ -160,6 +269,7 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
160
269
  "",
161
270
  "def list_components() -> list[ComponentSpec]:",
162
271
  " return list(COMPONENT_CATALOGUE.values())",
272
+ *_py_calls(specs),
163
273
  "",
164
274
  ]
165
275
  )