@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.
Files changed (141) hide show
  1. package/lib/chat/ChatFloating.d.ts +5 -4
  2. package/lib/chat/ChatFloating.js +8 -6
  3. package/lib/chat/ChatLanguage.d.ts +17 -0
  4. package/lib/chat/ChatLanguage.js +29 -0
  5. package/lib/chat/assistant/AssistantStage.d.ts +4 -4
  6. package/lib/chat/assistant/AssistantStage.js +4 -2
  7. package/lib/chat/assistant/BalloonParts.d.ts +2 -1
  8. package/lib/chat/assistant/BalloonParts.js +12 -5
  9. package/lib/chat/assistant/BalloonVisual.js +3 -1
  10. package/lib/chat/assistant/ConversationBalloon.d.ts +1 -1
  11. package/lib/chat/assistant/ConversationBalloon.js +3 -2
  12. package/lib/chat/assistant/SpeechBalloon.d.ts +1 -1
  13. package/lib/chat/assistant/SpeechBalloon.js +10 -7
  14. package/lib/chat/assistant/toolLine.d.ts +8 -4
  15. package/lib/chat/assistant/toolLine.js +13 -9
  16. package/lib/chat/base/ChatBase.js +14 -11
  17. package/lib/chat/display/EmptyState.js +3 -1
  18. package/lib/chat/index.d.ts +2 -0
  19. package/lib/chat/index.js +3 -0
  20. package/lib/chat/messages/ChatMessages.js +3 -1
  21. package/lib/chat/messages/TurnFooter.js +3 -1
  22. package/lib/chat/prompt/InputPrompt.js +3 -1
  23. package/lib/chat/prompt/InputPromptLexical.js +3 -1
  24. package/lib/chat/prompt/footer/InPromptFooter.js +3 -1
  25. package/lib/chat/tools/ToolApprovalBanner.js +5 -3
  26. package/lib/chat/tools/ToolApprovalDialog.js +5 -3
  27. package/lib/chat/tools/ToolCallDisplay.js +29 -25
  28. package/lib/chat/words.d.ts +102 -0
  29. package/lib/chat/words.js +460 -0
  30. package/lib/components/a2ui/custom/index.d.ts +39 -0
  31. package/lib/components/a2ui/custom/index.js +95 -0
  32. package/lib/components/a2ui/custom/sandbox.d.ts +73 -0
  33. package/lib/components/a2ui/custom/sandbox.js +188 -0
  34. package/lib/components/a2ui/datalayer/index.d.ts +1 -1
  35. package/lib/components/a2ui/datalayer/index.js +1 -1
  36. package/lib/components/a2ui/datalayer/schema.d.ts +10 -0
  37. package/lib/components/a2ui/datalayer/schema.js +12 -1
  38. package/lib/components/a2ui/index.d.ts +1 -0
  39. package/lib/components/a2ui/index.js +1 -0
  40. package/lib/components/a2ui/visibleWhen.d.ts +12 -1
  41. package/lib/components/a2ui/visibleWhen.js +24 -3
  42. package/lib/components/inspector/AgentInspector.d.ts +25 -44
  43. package/lib/components/inspector/AgentInspector.js +27 -215
  44. package/lib/components/inspector/AgentInspectorDialog.d.ts +6 -6
  45. package/lib/components/inspector/AgentInspectorDialog.js +2 -2
  46. package/lib/components/inspector/a2aSpans.d.ts +51 -0
  47. package/lib/components/inspector/a2aSpans.js +373 -0
  48. package/lib/components/inspector/agentSpans.d.ts +120 -0
  49. package/lib/components/inspector/agentSpans.js +253 -0
  50. package/lib/components/inspector/chatSpans.d.ts +36 -0
  51. package/lib/components/inspector/chatSpans.js +50 -0
  52. package/lib/components/inspector/classify.d.ts +11 -8
  53. package/lib/components/inspector/classify.js +23 -24
  54. package/lib/components/inspector/index.d.ts +7 -7
  55. package/lib/components/inspector/index.js +7 -7
  56. package/lib/components/teams/A2ATeamGraph.d.ts +4 -4
  57. package/lib/components/teams/SceneTranscript.d.ts +29 -0
  58. package/lib/components/teams/SceneTranscript.js +54 -0
  59. package/lib/components/teams/SceneView.d.ts +41 -0
  60. package/lib/components/teams/SceneView.js +28 -0
  61. package/lib/components/teams/index.d.ts +3 -0
  62. package/lib/components/teams/index.js +3 -0
  63. package/lib/components/teams/sceneTranscript.d.ts +74 -0
  64. package/lib/components/teams/sceneTranscript.js +294 -0
  65. package/lib/components/teams/teamConnections.d.ts +2 -2
  66. package/lib/components/teams/teamConnections.js +3 -3
  67. package/lib/components/teams/useA2ATeam.d.ts +4 -4
  68. package/lib/components/teams/useA2ATeam.js +50 -46
  69. package/lib/examples/AgentA2ATeamExample.d.ts +10 -9
  70. package/lib/examples/AgentA2ATeamExample.js +70 -60
  71. package/lib/examples/AssistantExample.js +2 -2
  72. package/lib/loop/apps/AppComposer.d.ts +2 -1
  73. package/lib/loop/apps/AppComposer.js +6 -3
  74. package/lib/loop/apps/AppRenderer.d.ts +2 -1
  75. package/lib/loop/apps/AppRenderer.js +34 -25
  76. package/lib/loop/apps/appspec.d.ts +11 -1
  77. package/lib/loop/apps/appspec.js +115 -1
  78. package/lib/loop/apps/checks.d.ts +8 -0
  79. package/lib/loop/apps/checks.js +106 -4
  80. package/lib/loop/apps/customComponents.d.ts +41 -0
  81. package/lib/loop/apps/customComponents.js +260 -0
  82. package/lib/loop/apps/hostTools.d.ts +8 -1
  83. package/lib/loop/apps/hostTools.js +9 -0
  84. package/lib/loop/apps/index.d.ts +1 -0
  85. package/lib/loop/apps/index.js +1 -0
  86. package/lib/loop/core/a2uiComponents.d.ts +10 -0
  87. package/lib/loop/core/a2uiComponents.js +15 -0
  88. package/lib/loop/core/index.d.ts +1 -0
  89. package/lib/loop/core/index.js +3 -0
  90. package/lib/loop/embed/AppEmbed.d.ts +11 -3
  91. package/lib/loop/embed/AppEmbed.js +42 -16
  92. package/lib/loop/embed/element.d.ts +5 -0
  93. package/lib/loop/embed/element.js +61 -5
  94. package/lib/loop/embed/embedConfig.d.ts +8 -0
  95. package/lib/loop/embed/embedConfig.js +18 -0
  96. package/lib/loop/embed/hostBridge.d.ts +28 -2
  97. package/lib/loop/embed/hostBridge.js +22 -2
  98. package/lib/loop/index.d.ts +4 -3
  99. package/lib/loop/index.js +4 -3
  100. package/lib/loop/plugins/a2ui-surface/InlineSurface.d.ts +7 -1
  101. package/lib/loop/plugins/a2ui-surface/InlineSurface.js +7 -2
  102. package/lib/loop/plugins/a2ui-surface/SurfaceToolResult.js +4 -1
  103. package/lib/loop/plugins/a2ui-surface/ownComponents.d.ts +6 -0
  104. package/lib/loop/plugins/a2ui-surface/ownComponents.js +30 -0
  105. package/lib/loop/plugins/app-components/index.d.ts +26 -0
  106. package/lib/loop/plugins/app-components/index.js +56 -0
  107. package/lib/loop/plugins/app-elements/AppElements.js +4 -1
  108. package/lib/loop/plugins/app-page/AppPage.d.ts +9 -0
  109. package/lib/loop/plugins/app-page/AppPage.js +106 -8
  110. package/lib/loop/plugins/app-page/appPageModel.d.ts +17 -1
  111. package/lib/loop/plugins/app-page/appPageModel.js +120 -4
  112. package/lib/loop/plugins/app-page/index.d.ts +1 -0
  113. package/lib/loop/plugins/app-page/index.js +1 -0
  114. package/lib/loop/plugins/app-page/pageRun.d.ts +46 -0
  115. package/lib/loop/plugins/app-page/pageRun.js +111 -0
  116. package/lib/loop/plugins/assistant/index.js +8 -6
  117. package/lib/loop/plugins/chat/ChatView.js +6 -4
  118. package/lib/loop/plugins/chat/index.d.ts +1 -1
  119. package/lib/loop/plugins/chat/index.js +2 -1
  120. package/lib/models/PageTag.d.ts +1 -1
  121. package/lib/runtimes/browser/a2aPeer.d.ts +2 -1
  122. package/lib/specs/actions.js +78 -1
  123. package/lib/specs/apps.d.ts +5 -0
  124. package/lib/specs/apps.js +1384 -231
  125. package/lib/specs/appspecSchema.js +191 -1
  126. package/lib/specs/teams/teams.d.ts +3 -0
  127. package/lib/specs/teams/teams.js +249 -0
  128. package/lib/types/agentspecs.d.ts +70 -0
  129. package/lib/types/chat.d.ts +6 -5
  130. package/lib/types/teams.d.ts +13 -2
  131. package/package.json +2 -2
  132. package/scripts/codegen/generate_apps.py +4 -2
  133. package/scripts/codegen/generate_teams.py +15 -2
  134. package/lib/components/inspector/JsonTree.d.ts +0 -24
  135. package/lib/components/inspector/JsonTree.js +0 -89
  136. package/lib/components/inspector/a2aInspect.d.ts +0 -56
  137. package/lib/components/inspector/a2aInspect.js +0 -478
  138. package/lib/components/inspector/agentInspector.d.ts +0 -179
  139. package/lib/components/inspector/agentInspector.js +0 -267
  140. package/lib/components/inspector/chatInspect.d.ts +0 -38
  141. package/lib/components/inspector/chatInspect.js +0 -65
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datalayer/agent-runtimes",
3
- "version": "1.3.84",
3
+ "version": "1.3.85",
4
4
  "type": "module",
5
5
  "workspaces": [
6
6
  ".",
@@ -147,7 +147,7 @@
147
147
  "@ai-sdk/react": "4.0.93",
148
148
  "@anthropic-ai/sdk": "^0.52.0",
149
149
  "@datalayer/agent-teams": "^1.0.0",
150
- "@datalayer/core": "^1.2.14",
150
+ "@datalayer/core": "^1.2.18",
151
151
  "@datalayer/decks": "^1.0.4",
152
152
  "@datalayer/icons-react": "^1.0.16",
153
153
  "@datalayer/jupyter-lexical": "^2.0.18",
@@ -55,6 +55,7 @@ CAMEL = {
55
55
  "backend_tools": "backendTools",
56
56
  "character_alone": "characterAlone",
57
57
  "settings_ui": "settingsUi",
58
+ "custom_components": "customComponents",
58
59
  }
59
60
 
60
61
  #: The keys whose value is carried as it is written: a component tree, weights by name.
@@ -126,6 +127,9 @@ def load_specs(specs_dir: Path) -> tuple[list[dict[str, Any]], dict[str, Any]]:
126
127
  for case in spec["tests"]["cases"]:
127
128
  if not case.get("code"):
128
129
  case.pop("code", None)
130
+ # Components of its own: said only when it has some.
131
+ if not spec["interface"].get("custom_components"):
132
+ spec["interface"].pop("custom_components", None)
129
133
  for key in ("description", "instructions", "goal"):
130
134
  spec[key] = _flat(spec.get(key))
131
135
  spec["interface"]["welcome"] = _flat(spec["interface"].get("welcome"))
@@ -492,8 +496,6 @@ def generate_schema_typescript_code() -> str:
492
496
  " * @module specs/appspecSchema",
493
497
  " */",
494
498
  "",
495
- "/* eslint-disable */",
496
- "",
497
499
  "export type JsonSchema = {",
498
500
  " [key: string]: unknown;",
499
501
  " type?: string;",
@@ -151,6 +151,8 @@ def _generate_team_agent_py(agent: Dict[str, Any]) -> str:
151
151
  # emitted only when said, as a team of agents says none of them.
152
152
  if agent.get("app"):
153
153
  lines.append(f' app="{agent["app"]}",')
154
+ if agent.get("server"):
155
+ lines.append(f' server="{agent["server"]}",')
154
156
  if agent.get("runs_in"):
155
157
  lines.append(f' runs_in="{agent["runs_in"]}",')
156
158
  links = agent.get("talks_to") or []
@@ -220,6 +222,7 @@ def _generate_team_agent_ts(agent: Dict[str, Any]) -> str:
220
222
  links = agent.get("talks_to") or []
221
223
  application = (
222
224
  (f"\n app: '{agent['app']}'," if agent.get("app") else "")
225
+ + (f"\n server: '{agent['server']}'," if agent.get("server") else "")
223
226
  + (f"\n runsIn: '{agent['runs_in']}'," if agent.get("runs_in") else "")
224
227
  + (
225
228
  "\n talksTo: ["
@@ -484,10 +487,14 @@ from agent_runtimes.types import (
484
487
  # `shared` by default: routing only makes sense if the member
485
488
  # receiving the work can see what was already said.
486
489
  context = spec.get("context") or {}
490
+ # The Frames of its shared context (LOOP A-04): written only when
491
+ # it names some, as the parser reads it.
492
+ frames = context.get("frames") or []
487
493
  code += (
488
494
  " context=TeamContextSpec("
489
495
  f'sharing="{context.get("sharing", "shared")}"'
490
- "),\n"
496
+ + (f", frames={_fmt_list(frames)}" if frames else "")
497
+ + "),\n"
491
498
  )
492
499
  code += f" validation={validation_code},\n"
493
500
  code += f" agents={agents_code},\n"
@@ -778,7 +785,13 @@ import type {{ TeamSpec }} from '{types_import_path}';
778
785
  " },\n"
779
786
  )
780
787
  context = spec.get("context") or {}
781
- code += f" context: {{ sharing: '{context.get('sharing', 'shared')}' }},\n"
788
+ frames = context.get("frames") or []
789
+ frames_ts = (
790
+ ", frames: [" + ", ".join(f"'{frame}'" for frame in frames) + "]"
791
+ if frames
792
+ else ""
793
+ )
794
+ code += f" context: {{ sharing: '{context.get('sharing', 'shared')}'{frames_ts} }},\n"
782
795
  code += f" validation: {validation_ts},\n"
783
796
  code += f" agents: {agents_ts},\n"
784
797
  if rr_ts is not None:
@@ -1,24 +0,0 @@
1
- /**
2
- * A JSON value as a tree: objects and arrays fold and unfold, each value
3
- * coloured by its type (theme colours, light and dark), long strings cut
4
- * until asked for whole, and the whole value copied as JSON.
5
- *
6
- * @module components/inspector/JsonTree
7
- */
8
- import type { JSX } from 'react';
9
- export type JsonTreeProps = {
10
- value: unknown;
11
- /** The root's name, shown as its key. */
12
- name?: string;
13
- /** How many levels open at first. */
14
- expandDepth?: number;
15
- /** Offer *Copy JSON* above the tree. */
16
- copyable?: boolean;
17
- /** Longer strings are cut until clicked. */
18
- stringLimit?: number;
19
- };
20
- /** A value's type, as the tree colours it. */
21
- export declare function jsonType(value: unknown): 'string' | 'number' | 'boolean' | 'null' | 'array' | 'object' | 'undefined';
22
- /** A JSON value, as a tree. */
23
- export declare function JsonTree({ value, name, expandDepth, copyable, stringLimit, }: JsonTreeProps): JSX.Element;
24
- export default JsonTree;
@@ -1,89 +0,0 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { Button, Text } from '@primer/react';
4
- import { Box } from '@datalayer/primer-addons';
5
- import { CopyIcon, CheckIcon } from '@primer/octicons-react';
6
- const MONO = 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace';
7
- /** A value's type, as the tree colours it. */
8
- export function jsonType(value) {
9
- if (value === null) {
10
- return 'null';
11
- }
12
- if (Array.isArray(value)) {
13
- return 'array';
14
- }
15
- const type = typeof value;
16
- if (type === 'string' || type === 'number' || type === 'boolean') {
17
- return type;
18
- }
19
- if (type === 'bigint') {
20
- return 'number';
21
- }
22
- return type === 'undefined' ? 'undefined' : 'object';
23
- }
24
- const COLOURS = {
25
- string: 'success.fg',
26
- number: 'accent.fg',
27
- boolean: 'done.fg',
28
- null: 'fg.muted',
29
- undefined: 'fg.muted',
30
- };
31
- function Leaf({ value, stringLimit, }) {
32
- const type = jsonType(value);
33
- const [whole, setWhole] = useState(false);
34
- if (type === 'string') {
35
- const text = value;
36
- const cut = !whole && text.length > stringLimit;
37
- return (_jsxs(Text, { "data-json-type": "string", sx: {
38
- color: COLOURS.string,
39
- whiteSpace: 'pre-wrap',
40
- wordBreak: 'break-word',
41
- }, children: [JSON.stringify(cut ? text.slice(0, stringLimit) : text), cut && (_jsxs(Box, { as: "button", type: "button", onClick: () => setWhole(true), sx: {
42
- ml: 1,
43
- p: 0,
44
- border: 0,
45
- bg: 'transparent',
46
- color: 'accent.fg',
47
- cursor: 'pointer',
48
- font: 'inherit',
49
- }, children: ["\u2026 ", text.length - stringLimit, " more"] }))] }));
50
- }
51
- return (_jsx(Text, { "data-json-type": type, sx: { color: COLOURS[type] ?? 'fg.default' }, children: type === 'undefined' ? 'undefined' : String(value) }));
52
- }
53
- function Node({ name, value, depth, expandDepth, stringLimit, }) {
54
- const type = jsonType(value);
55
- const branch = type === 'array' || type === 'object';
56
- const [open, setOpen] = useState(depth < expandDepth);
57
- const key = name !== undefined ? (_jsxs(Text, { sx: { color: 'fg.default', fontWeight: 600 }, children: [name, ": "] })) : null;
58
- if (!branch) {
59
- return (_jsxs(Box, { role: "treeitem", "data-json-node": "", sx: { pl: 3 }, children: [key, _jsx(Leaf, { value: value, stringLimit: stringLimit })] }));
60
- }
61
- const items = type === 'array'
62
- ? value.map((item, index) => [String(index), item])
63
- : Object.entries(value);
64
- const [openMark, closeMark] = type === 'array' ? ['[', ']'] : ['{', '}'];
65
- return (_jsxs(Box, { role: "treeitem", "aria-expanded": open, "data-json-node": "", sx: { pl: depth ? 3 : 0 }, children: [_jsxs(Box, { as: "button", type: "button", onClick: () => setOpen(!open), "aria-label": `${open ? 'Fold' : 'Unfold'} ${name ?? 'the value'}`, "data-json-toggle": "", sx: {
66
- p: 0,
67
- border: 0,
68
- bg: 'transparent',
69
- color: 'inherit',
70
- font: 'inherit',
71
- cursor: 'pointer',
72
- textAlign: 'left',
73
- }, children: [_jsx(Text, { sx: { color: 'fg.muted', display: 'inline-block', width: '1em' }, children: open ? '▾' : '▸' }), key, _jsx(Text, { sx: { color: 'fg.muted' }, children: open
74
- ? openMark
75
- : `${openMark} ${items.length} ${type === 'array' ? (items.length === 1 ? 'item' : 'items') : items.length === 1 ? 'key' : 'keys'} ${closeMark}` })] }), open && (_jsxs(Box, { role: "group", children: [items.map(([itemName, item]) => (_jsx(Node, { name: itemName, value: item, depth: depth + 1, expandDepth: expandDepth, stringLimit: stringLimit }, itemName))), _jsx(Text, { sx: { color: 'fg.muted', pl: 3 }, children: closeMark })] }))] }));
76
- }
77
- /** A JSON value, as a tree. */
78
- export function JsonTree({ value, name, expandDepth = 1, copyable = true, stringLimit = 240, }) {
79
- const [copied, setCopied] = useState(false);
80
- const copy = () => {
81
- const text = JSON.stringify(value, null, 2) ?? 'undefined';
82
- void navigator.clipboard?.writeText(text).then(() => {
83
- setCopied(true);
84
- setTimeout(() => setCopied(false), 1500);
85
- }, () => undefined);
86
- };
87
- return (_jsxs(Box, { "data-json-tree": "", sx: { fontFamily: MONO, fontSize: 0, lineHeight: 1.6, minWidth: 0 }, children: [copyable && (_jsx(Button, { size: "small", variant: "invisible", leadingVisual: copied ? CheckIcon : CopyIcon, onClick: copy, "data-json-copy": "", sx: { float: 'right' }, children: copied ? 'Copied' : 'Copy JSON' })), _jsx(Box, { role: "tree", "aria-label": name ?? 'JSON', children: _jsx(Node, { name: name, value: value, depth: 0, expandDepth: expandDepth, stringLimit: stringLimit }) })] }));
88
- }
89
- export default JsonTree;
@@ -1,56 +0,0 @@
1
- /**
2
- * The A2A traffic between two agents, as the Agent Inspector records it: a
3
- * fetch that hands every request on and records what went (the JSON-RPC
4
- * request: its method, its message) and what came back — a JSON-RPC
5
- * response, or each server-sent event of a stream (the task, its status
6
- * updates, its artifact updates, a message) — with its task, context and
7
- * state, whole.
8
- *
9
- * It sits under the A2A SDK (`ClientFactory`'s `JsonRpcTransportFactory`
10
- * takes a `fetchImpl`): the SDK reads the response it is handed, and the
11
- * inspector reads a copy of its body. Nothing it records changes what the
12
- * SDK sees, and a key sent as a header is never recorded.
13
- *
14
- * A peer served by agent-runtimes tells each tool call of its agent on a
15
- * `working` status (`{tool_call}`, then `{tool_result}`): each call is
16
- * recorded besides as one entry of its own, the peer's, from its start to
17
- * its end, linked to the two statuses — an MCP call, a skill, or a tool its
18
- * runtime runs, by who claims its name. The text chunks of one artifact are
19
- * one entry, their count kept.
20
- *
21
- * {@link linkA2APeerEvent} attaches what the asker made of an event (an
22
- * `A2APeerEvent`) to the entry it came from.
23
- *
24
- * @module components/inspector/a2aInspect
25
- */
26
- import type { A2APeerEvent } from '../../runtimes/browser/a2aPeer';
27
- import { type AgentInspectorEntry, type AgentInspectorSink, type ToolClass } from './agentInspector';
28
- export type A2AInspectOptions = {
29
- sink: AgentInspectorSink;
30
- /** The agent that asks: `Sales`. */
31
- asker: string;
32
- /** The agent asked: `Accounting`. */
33
- peer: string;
34
- /**
35
- * Where a peer's tool call comes from — an MCP server's, a skill, … — and
36
- * its mark (`classifyToolCall`, or a team's `teamToolClassifier`).
37
- * Without it, a tool the peer's runtime runs (`backend-tool`).
38
- */
39
- classifyTool?: (name: string, args?: Record<string, unknown>) => ToolClass;
40
- };
41
- /** The text of an A2A 1.0 message's or artifact's parts, as JSON carries them. */
42
- export declare function partsText(parts: unknown): string;
43
- /** `TASK_STATE_WORKING` is `working`. */
44
- export declare function stateWord(state: unknown): string;
45
- /**
46
- * A fetch that records the A2A traffic it carries into `options.sink`, and
47
- * hands the SDK what the network gave.
48
- */
49
- export declare function inspectA2AFetch(base: typeof globalThis.fetch, options: A2AInspectOptions): typeof globalThis.fetch;
50
- /**
51
- * The linker the A2A capture adds to its sink: an `A2APeerEvent` noted
52
- * (`sink.note`) is attached to the entry it came from.
53
- */
54
- export declare function a2aEventLinker(event: unknown): ((entry: AgentInspectorEntry) => boolean) | undefined;
55
- /** Attach what the asker made of an event to the A2A entry it came from. */
56
- export declare function linkA2APeerEvent(sink: AgentInspectorSink, event: A2APeerEvent): void;