@datalayer/agent-runtimes 1.5.16 → 1.5.18

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 (53) hide show
  1. package/dist-embed/chunks/ChatView-Bz0eyWo6.js +32 -0
  2. package/dist-embed/datalayer-app-main.js +102 -102
  3. package/lib/apps/apps/appspec.d.ts +36 -4
  4. package/lib/apps/apps/appspec.js +104 -11
  5. package/lib/apps/apps/threads.d.ts +20 -0
  6. package/lib/apps/apps/threads.js +31 -0
  7. package/lib/apps/plugins/canvas-blocks/index.d.ts +7 -9
  8. package/lib/apps/plugins/canvas-blocks/index.js +8 -10
  9. package/lib/apps/plugins/canvas-parts/index.d.ts +4 -1
  10. package/lib/apps/plugins/canvas-parts/index.js +7 -3
  11. package/lib/apps/plugins/chat/ChatView.js +32 -7
  12. package/lib/chat/ChatFloating.js +12 -4
  13. package/lib/chat/base/ChatBase.js +31 -5
  14. package/lib/chat/messages/ChatMessageList.js +1 -1
  15. package/lib/config/AgentConfiguration.d.ts +5 -1
  16. package/lib/examples/AgentA2ATeamExample.js +6 -5
  17. package/lib/examples/ChatExample.js +2 -2
  18. package/lib/examples/VoiceChatExample.js +9 -3
  19. package/lib/hooks/useBrowserAgent.d.ts +1 -1
  20. package/lib/hooks/useBrowserAgent.js +1 -1
  21. package/lib/protocols/AGUIAdapter.d.ts +11 -0
  22. package/lib/protocols/AGUIAdapter.js +27 -2
  23. package/lib/specs/agents/agents.js +169 -169
  24. package/lib/specs/apps.d.ts +32 -32
  25. package/lib/specs/apps.js +624 -143
  26. package/lib/specs/appspecSchema.js +30 -2
  27. package/lib/specs/cogs.js +3 -3
  28. package/lib/specs/index.d.ts +1 -0
  29. package/lib/specs/index.js +1 -0
  30. package/lib/specs/protocols.js +2 -2
  31. package/lib/specs/sceneSchema.js +2 -0
  32. package/lib/specs/scenes.js +7 -7
  33. package/lib/specs/teams/teams.js +11 -11
  34. package/lib/specs/ui.d.ts +32 -6
  35. package/lib/specs/ui.js +760 -26
  36. package/lib/specs/uiRenderers.d.ts +17 -0
  37. package/lib/specs/uiRenderers.js +40 -0
  38. package/lib/specs/voices.d.ts +2 -0
  39. package/lib/specs/voices.js +5 -0
  40. package/lib/types/agentspecs.d.ts +63 -12
  41. package/lib/types/chat.d.ts +6 -0
  42. package/lib/types/protocol.d.ts +17 -0
  43. package/lib/utils/utils.js +8 -1
  44. package/lib/voice/ReadAloud.d.ts +35 -0
  45. package/lib/voice/ReadAloud.js +29 -0
  46. package/lib/voice/index.d.ts +7 -2
  47. package/lib/voice/index.js +1 -0
  48. package/package.json +2 -2
  49. package/scripts/codegen/generate_agents.py +60 -11
  50. package/scripts/codegen/generate_ui.py +68 -22
  51. package/scripts/codegen/generate_ui_renderers.py +176 -0
  52. package/scripts/codegen/generate_voices.py +5 -1
  53. package/dist-embed/chunks/ChatView-nnI1-MOR.js +0 -32
@@ -5,10 +5,13 @@
5
5
  """
6
6
  Generate Python and TypeScript code from YAML UI specifications.
7
7
 
8
- A UI spec is how an agent's answer becomes an interface rather than text —
9
- a protocol the host knows how to render (A2UI, MCP Apps, MCP UI). One YAML per
10
- plugin under ``agentspecs/ui``; an agent spec's ``ui`` names
11
- one. A UI spec hosts the visual components it renders (LOOP C-13).
8
+ A UI spec is one Reactor plugin of this package (``src/apps/plugins/``) a
9
+ Maker composes an interface with (AGENTIC_UI R8): its registered name, its
10
+ Contributions, the Contribution Points it offers, its settings, the visual
11
+ components it renders (LOOP C-13) and the UI renderers it may be exposed
12
+ through (``agentspecs/ui-renderers``, ``generate_ui_renderers.py``). One YAML
13
+ per plugin under ``agentspecs/ui``; an agent's or an application's ``ui``
14
+ names plugins, each with its renderer.
12
15
 
13
16
  Usage:
14
17
  python generate_ui.py \\
@@ -29,7 +32,13 @@ from versioning import ensure_spec_version, version_suffix
29
32
 
30
33
 
31
34
  def load_plugin_specs(specs_dir: Path) -> list[dict[str, Any]]:
32
- """Load all UI YAML specifications from a directory."""
35
+ """Load all UI YAML specifications from a directory.
36
+
37
+ A spec of the old shape — a renderer listed as a UI, with no `plugin` —
38
+ is refused, and so is a renderer the `ui-renderers` beside it does not have.
39
+ """
40
+ renderers_dir = specs_dir.parent / "ui-renderers"
41
+ renderers = {path.stem for path in renderers_dir.glob("*.yaml")}
33
42
  specs = []
34
43
  for yaml_file in sorted(specs_dir.glob("*.yaml")):
35
44
  with open(yaml_file) as f:
@@ -39,6 +48,16 @@ def load_plugin_specs(specs_dir: Path) -> list[dict[str, Any]]:
39
48
  raise ValueError(
40
49
  f"{yaml_file.name}: the file is named for id {yaml_file.stem!r}, the spec says {spec['id']!r}"
41
50
  )
51
+ if "plugin" not in spec:
52
+ raise ValueError(
53
+ f"{yaml_file.name}: a UI spec is a Reactor plugin (`plugin`); "
54
+ "a renderer is a spec of agentspecs/ui-renderers"
55
+ )
56
+ for renderer in spec.get("renderers") or []:
57
+ if renderer not in renderers:
58
+ raise ValueError(
59
+ f"{yaml_file.name}: there is no UI renderer {renderer!r} in {renderers_dir}"
60
+ )
42
61
  specs.append(spec)
43
62
  return specs
44
63
 
@@ -122,8 +141,6 @@ def _py_calls(specs: list[dict[str, Any]]) -> list[str]:
122
141
  " self._place = place",
123
142
  ]
124
143
  for spec in specs:
125
- if not spec.get("enabled", True):
126
- continue
127
144
  for component in spec.get("components") or []:
128
145
  schema = component.get("properties") or {}
129
146
  required = set(schema.get("required") or [])
@@ -203,7 +220,7 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
203
220
  '"""',
204
221
  "UI Catalog.",
205
222
  "",
206
- "How an agent's answer becomes an interface: the protocols a host renders.",
223
+ "The UI plugins: the Reactor plugins an interface is made of (AGENTIC_UI R8).",
207
224
  "",
208
225
  "This file is AUTO-GENERATED from YAML specifications.",
209
226
  "DO NOT EDIT MANUALLY - run 'make specs' to regenerate.",
@@ -211,7 +228,12 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
211
228
  "",
212
229
  "from typing import Any, Callable, Dict, List, Literal, Mapping, Optional, Union",
213
230
  "",
214
- "from agent_runtimes.types import ComponentBindingsSpec, ComponentSpec, UISpec",
231
+ "from agent_runtimes.types import (",
232
+ " ComponentBindingsSpec,",
233
+ " ComponentSpec,",
234
+ " UiContributionsSpec,",
235
+ " UISpec,",
236
+ ")",
215
237
  "",
216
238
  "# " + "=" * 76,
217
239
  "# UI Definitions",
@@ -227,9 +249,20 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
227
249
  f" version={_py(str(spec['version']))},",
228
250
  f" name={_py(spec['name'])},",
229
251
  f" description={_py(str(spec.get('description', '')).strip())},",
230
- f" docs_url={_py(str(spec.get('docs_url', '')))},",
231
- f" enabled={bool(spec.get('enabled', True))},",
232
- f" catalog={_py(str(spec.get('catalog', '')))},",
252
+ f" emoji={json.dumps(spec['emoji'], ensure_ascii=False)},",
253
+ f" octicon={_py(spec['octicon']) if spec.get('octicon') else 'None'},",
254
+ f" plugin={_py(spec['plugin'])},",
255
+ f" folder={_py(spec['folder'])},",
256
+ f" per={_py(spec['per']) if spec.get('per') else 'None'},",
257
+ " contributions=UiContributionsSpec(",
258
+ f" slots={list((spec.get('contributions') or {}).get('slots') or [])!r},",
259
+ f" points={list((spec.get('contributions') or {}).get('points') or [])!r},",
260
+ f" commands={list((spec.get('contributions') or {}).get('commands') or [])!r},",
261
+ " ),",
262
+ f" contribution_points={list(spec.get('contribution_points') or [])!r},",
263
+ f" settings={spec.get('settings') or {}!r},",
264
+ f" renderers={list(spec.get('renderers') or [])!r},",
265
+ f" catalog={_py(str(spec.get('catalog') or ''))},",
233
266
  " components=[",
234
267
  *[f" {_py_component(c)}," for c in spec.get("components") or []],
235
268
  " ],",
@@ -257,7 +290,7 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
257
290
  "",
258
291
  "",
259
292
  "def get_ui(plugin_id: str) -> UISpec | None:",
260
- ' """The UI an agent spec\'s `ui` names, or None."""',
293
+ ' """The UI plugin an agent\'s or an application\'s `ui` names, or None."""',
261
294
  " return UI_CATALOGUE.get(plugin_id)",
262
295
  "",
263
296
  "",
@@ -265,12 +298,11 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
265
298
  " return list(UI_CATALOGUE.values())",
266
299
  "",
267
300
  "",
268
- "#: The visual components the enabled UI specs render, by the name a",
301
+ "#: The visual components the UI plugins render, by the name a",
269
302
  "#: surface gives them (LOOP C-13).",
270
303
  "COMPONENT_CATALOGUE: Dict[str, ComponentSpec] = {",
271
304
  " component.id: component",
272
305
  " for plugin in UI_CATALOGUE.values()",
273
- " if plugin.enabled",
274
306
  " for component in plugin.components",
275
307
  "}",
276
308
  "",
@@ -300,7 +332,7 @@ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
300
332
  "/**",
301
333
  " * UI Catalog.",
302
334
  " *",
303
- " * How an agent's answer becomes an interface: the protocols a host renders.",
335
+ " * The UI plugins: the Reactor plugins an interface is made of (AGENTIC_UI R8).",
304
336
  " *",
305
337
  " * This file is AUTO-GENERATED from YAML specifications.",
306
338
  " * DO NOT EDIT MANUALLY - run 'make specs' to regenerate.",
@@ -318,9 +350,24 @@ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
318
350
  f" version: {_ts(str(spec['version']))},",
319
351
  f" name: {_ts(spec['name'])},",
320
352
  f" description: {_ts(str(spec.get('description', '')).strip())},",
321
- f" docsUrl: {_ts(str(spec.get('docs_url', '')))},",
322
- f" enabled: {'true' if spec.get('enabled', True) else 'false'},",
323
- f" catalog: {_ts(str(spec.get('catalog', '')))},",
353
+ f" emoji: {json.dumps(spec['emoji'], ensure_ascii=False)},",
354
+ *(
355
+ [f" octicon: {_ts(spec['octicon'])},"]
356
+ if spec.get("octicon")
357
+ else []
358
+ ),
359
+ f" plugin: {_ts(spec['plugin'])},",
360
+ f" folder: {_ts(spec['folder'])},",
361
+ *([f" per: {_ts(spec['per'])},"] if spec.get("per") else []),
362
+ " contributions: {",
363
+ f" slots: {json.dumps(list((spec.get('contributions') or {}).get('slots') or []))},",
364
+ f" points: {json.dumps(list((spec.get('contributions') or {}).get('points') or []))},",
365
+ f" commands: {json.dumps(list((spec.get('contributions') or {}).get('commands') or []))},",
366
+ " },",
367
+ f" contributionPoints: {json.dumps(list(spec.get('contribution_points') or []))},",
368
+ f" settings: {json.dumps(spec.get('settings') or {}, ensure_ascii=False)},",
369
+ f" renderers: {json.dumps(list(spec.get('renderers') or []))},",
370
+ f" catalog: {_ts(str(spec.get('catalog') or ''))},",
324
371
  f" components: {json.dumps([{**c, 'events': c.get('events', [])} for c in spec.get('components') or []], indent=2, ensure_ascii=False)},",
325
372
  "};",
326
373
  "",
@@ -335,7 +382,7 @@ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
335
382
  [
336
383
  "};",
337
384
  "",
338
- "/** The UI an agent spec's `ui` names, or undefined. */",
385
+ "/** The UI plugin an agent's or an application's `ui` names, or undefined. */",
339
386
  "export function getUI(pluginId: string): UISpec | undefined {",
340
387
  " return UI_CATALOGUE[pluginId];",
341
388
  "}",
@@ -344,10 +391,9 @@ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
344
391
  " return Object.values(UI_CATALOGUE);",
345
392
  "}",
346
393
  "",
347
- "/** The visual components the enabled UI specs render, by the name a surface gives them (LOOP C-13). */",
394
+ "/** The visual components the UI plugins render, by the name a surface gives them (LOOP C-13). */",
348
395
  "export const COMPONENT_CATALOGUE: Record<string, ComponentSpec> = Object.fromEntries(",
349
396
  " Object.values(UI_CATALOGUE)",
350
- " .filter(plugin => plugin.enabled)",
351
397
  " .flatMap(plugin => plugin.components.map(component => [component.id, component])),",
352
398
  ");",
353
399
  "",
@@ -0,0 +1,176 @@
1
+ #!/usr/bin/env python3
2
+ # Copyright (c) 2025-2026 Datalayer, Inc.
3
+ # Distributed under the terms of the Modified BSD License.
4
+
5
+ """
6
+ Generate Python and TypeScript code from the YAML UI renderer specifications.
7
+
8
+ One YAML per UI renderer under ``agentspecs/ui-renderers`` (AGENTIC_UI R8,
9
+ F-01): how a UI plugin's interface reaches a host that is not Datalayer's own
10
+ page — A2UI, MCP Apps, MCP UI. A UI plugin (``agentspecs/ui``) says the
11
+ renderers it may be exposed through; an agent's or an application's ``ui``
12
+ names, per plugin, the one it uses.
13
+
14
+ Usage:
15
+ python generate_ui_renderers.py \\
16
+ --specs-dir agentspecs/agentspecs/ui-renderers \\
17
+ --python-output agent_runtimes/specs/ui_renderers.py \\
18
+ --typescript-output src/specs/uiRenderers.ts
19
+ """
20
+
21
+ import argparse
22
+ import json
23
+ from pathlib import Path
24
+ from typing import Any
25
+
26
+ import yaml
27
+ from versioning import ensure_spec_version, version_suffix
28
+
29
+ FIELDS = {"id", "version", "name", "description", "docs_url", "enabled"}
30
+
31
+
32
+ def load_ui_renderer_specs(specs_dir: Path) -> list[dict[str, Any]]:
33
+ """Every UI renderer spec of a directory, each named for its id, with its fields and no other."""
34
+ specs = []
35
+ for yaml_file in sorted(specs_dir.glob("*.yaml")):
36
+ spec = yaml.safe_load(yaml_file.read_text()) or {}
37
+ ensure_spec_version(spec)
38
+ if spec["id"] != yaml_file.stem:
39
+ raise ValueError(
40
+ f"{yaml_file.name}: the file is named for {yaml_file.stem!r}, the spec says {spec['id']!r}"
41
+ )
42
+ if set(spec) != FIELDS:
43
+ raise ValueError(f"{yaml_file.name}: a UI renderer says {sorted(FIELDS)}")
44
+ specs.append(spec)
45
+ return specs
46
+
47
+
48
+ def _const(spec: dict[str, Any]) -> str:
49
+ return (
50
+ spec["id"].replace("-", "_").upper()
51
+ + "_UI_RENDERER"
52
+ + version_suffix(spec["version"])
53
+ )
54
+
55
+
56
+ def _s(value: Any) -> str:
57
+ return json.dumps(" ".join(str(value).split()), ensure_ascii=False)
58
+
59
+
60
+ def generate_python_code(specs: list[dict[str, Any]]) -> str:
61
+ """The Python catalogue of the UI renderers."""
62
+ lines = [
63
+ "# Copyright (c) 2025-2026 Datalayer, Inc.",
64
+ "# Distributed under the terms of the Modified BSD License.",
65
+ '"""',
66
+ "UI Renderer Catalog.",
67
+ "",
68
+ "How a UI plugin's interface reaches a host that is not Datalayer's own page",
69
+ "(AGENTIC_UI R8): A2UI, MCP Apps, MCP UI.",
70
+ "",
71
+ "This file is AUTO-GENERATED from YAML specifications.",
72
+ "DO NOT EDIT MANUALLY - run 'make specs' to regenerate.",
73
+ '"""',
74
+ "",
75
+ "from typing import Dict",
76
+ "",
77
+ "from agent_runtimes.types import UiRendererSpec",
78
+ "",
79
+ ]
80
+ for spec in specs:
81
+ lines += [
82
+ f"{_const(spec)} = UiRendererSpec(",
83
+ f" id={_s(spec['id'])},",
84
+ f" version={_s(spec['version'])},",
85
+ f" name={_s(spec['name'])},",
86
+ f" description={_s(spec['description'])},",
87
+ f" docs_url={_s(spec['docs_url'])},",
88
+ f" enabled={bool(spec['enabled'])},",
89
+ ")",
90
+ "",
91
+ ]
92
+ lines += ["UI_RENDERER_CATALOGUE: Dict[str, UiRendererSpec] = {"]
93
+ lines += [f" {_s(spec['id'])}: {_const(spec)}," for spec in specs]
94
+ lines += [
95
+ "}",
96
+ "",
97
+ "",
98
+ "def get_ui_renderer(renderer_id: str) -> UiRendererSpec | None:",
99
+ ' """The UI renderer a plugin\'s `renderers` or a `ui` choice names, or None."""',
100
+ " return UI_RENDERER_CATALOGUE.get(renderer_id)",
101
+ "",
102
+ "",
103
+ "def list_ui_renderers() -> list[UiRendererSpec]:",
104
+ " return list(UI_RENDERER_CATALOGUE.values())",
105
+ "",
106
+ ]
107
+ return "\n".join(lines)
108
+
109
+
110
+ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
111
+ """The TypeScript catalogue of the UI renderers."""
112
+ lines = [
113
+ "/*",
114
+ " * Copyright (c) 2025-2026 Datalayer, Inc.",
115
+ " * Distributed under the terms of the Modified BSD License.",
116
+ " */",
117
+ "",
118
+ "/**",
119
+ " * UI Renderer Catalog.",
120
+ " *",
121
+ " * How a UI plugin's interface reaches a host that is not Datalayer's own",
122
+ " * page (AGENTIC_UI R8): A2UI, MCP Apps, MCP UI.",
123
+ " *",
124
+ " * This file is AUTO-GENERATED from YAML specifications.",
125
+ " * DO NOT EDIT MANUALLY - run 'make specs' to regenerate.",
126
+ " */",
127
+ "",
128
+ "import type { UiRendererSpec } from '../types/agentspecs';",
129
+ "",
130
+ ]
131
+ for spec in specs:
132
+ lines += [
133
+ f"export const {_const(spec)}: UiRendererSpec = {{",
134
+ f" id: {_s(spec['id'])},",
135
+ f" version: {_s(spec['version'])},",
136
+ f" name: {_s(spec['name'])},",
137
+ f" description: {_s(spec['description'])},",
138
+ f" docsUrl: {_s(spec['docs_url'])},",
139
+ f" enabled: {'true' if spec['enabled'] else 'false'},",
140
+ "};",
141
+ "",
142
+ ]
143
+ lines += ["export const UI_RENDERER_CATALOGUE: Record<string, UiRendererSpec> = {"]
144
+ lines += [f" {_s(spec['id'])}: {_const(spec)}," for spec in specs]
145
+ lines += [
146
+ "};",
147
+ "",
148
+ "/** The UI renderer a plugin's `renderers` or a `ui` choice names, or undefined. */",
149
+ "export function getUiRenderer(rendererId: string): UiRendererSpec | undefined {",
150
+ " return UI_RENDERER_CATALOGUE[rendererId];",
151
+ "}",
152
+ "",
153
+ "export function listUiRenderers(): UiRendererSpec[] {",
154
+ " return Object.values(UI_RENDERER_CATALOGUE);",
155
+ "}",
156
+ "",
157
+ ]
158
+ return "\n".join(lines)
159
+
160
+
161
+ def main() -> None:
162
+ parser = argparse.ArgumentParser(description=__doc__)
163
+ parser.add_argument("--specs-dir", type=Path, required=True)
164
+ parser.add_argument("--python-output", type=Path, required=True)
165
+ parser.add_argument("--typescript-output", type=Path, required=True)
166
+ args = parser.parse_args()
167
+ specs = load_ui_renderer_specs(args.specs_dir)
168
+ args.python_output.write_text(generate_python_code(specs))
169
+ args.typescript_output.write_text(generate_typescript_code(specs))
170
+ print(
171
+ f"Generated {len(specs)} UI renderers: {args.python_output}, {args.typescript_output}"
172
+ )
173
+
174
+
175
+ if __name__ == "__main__":
176
+ main()
@@ -45,6 +45,7 @@ def _model(model: Any) -> dict[str, Any]:
45
45
  "id": model.id,
46
46
  "version": model.version,
47
47
  "name": model.name,
48
+ "description": " ".join(model.description.split()),
48
49
  "task": model.task,
49
50
  "engine": model.engine,
50
51
  "dtype": model.dtype,
@@ -120,7 +121,8 @@ def generate_python_code(
120
121
  " base = (language or '').strip()",
121
122
  " exact = [v for v in VOICE_CATALOGUE.values() if base in v['languages']]",
122
123
  " near = [v for v in VOICE_CATALOGUE.values() if voice_speaks(v, base.split('-')[0])]",
123
- " return (exact or near or [None])[0]",
124
+ " found = exact or near",
125
+ " return found[0] if found else None",
124
126
  "",
125
127
  ]
126
128
  )
@@ -191,6 +193,8 @@ def generate_typescript_code(
191
193
  " id: string;",
192
194
  " version: string;",
193
195
  " name: string;",
196
+ " /** What it is for, in a sentence or two. */",
197
+ " description: string;",
194
198
  " task: 'stt' | 'tts' | 'vad';",
195
199
  " engine: string;",
196
200
  " dtype: string;",
@@ -1,32 +0,0 @@
1
- import{E as N,eN as io,r as o,j as t,eO as ro,eP as lo,b_ as Sn,B as f,H as ct,T as H,c as G,cu as Pt,eu as Lt,eQ as ae,co as dt,e as co,eR as uo,eS as fo,e3 as po,eT as mo,aH as go,dX as An,dV as ho,dY as zt,eU as bo,eV as xo,eW as So,eX as vo,eY as vn,eZ as yo,e_ as Co,e$ as wo,d3 as ko,a_ as jo,f0 as Eo,f1 as Io,f2 as To,f3 as Ro,f4 as Ao,f5 as Po,x as Mt,f6 as Mo,f7 as $o,f8 as Uo,f9 as Oo,fa as Fo,fb as Lo,fc as zo,fd as _o,fe as No,ff as Bo,fg as Vo,fh as Ho,fi as Wo,fj as Do,fk as Go,fl as Ko,fm as Yo,fn as qo,fo as Jo,fp as Qo,fq as De,fr as Xo,fs as Zo,ft as es,fu as ts,fv as yn,fw as ns,fx as Ae,fy as os,fz as ss,a$ as ut,fA as as,fB as is,fC as Cn,fD as rs,fE as ls,eC as cs,fF as $t,fG as Se,fH as ds,fI as us,fJ as fs,fK as ps,fL as ms,fM as gs,fN as hs,fO as bs,fP as xs,fQ as Ss,fR as vs,fS as ys,fT as ft,fU as Cs,fV as ws,I as ks,fW as js,fX as Es,fY as wn,fZ as Is,f_ as Ts,f$ as Rs,g0 as _t,g1 as As,g2 as Ps,ek as Ut,g3 as Ms,g4 as $s}from"../datalayer-app-main.js";import{S as Us,E as Os,a as Fs}from"./SignInIcon-4HkE48mS.js";import{F as Ls,a as zs,b as _s}from"./LinkedInGreyIcon-BoWXE-HS.js";function Pn(){const n=N(io);return o.useMemo(()=>n.map(s=>s.value),[n])}const Ot={github:{name:"github",oauth2CallbackServerRoute:"jupyter_iam/oauth2/callback",oauth2CallbackUIRoute:"/iam/oauth2/github/callback"},google:{name:"google",oauth2CallbackServerRoute:"jupyter_iam/oauth2/callback",oauth2CallbackUIRoute:"/iam/oauth2/google/callback"},linkedin:{name:"linkedin",oauth2CallbackServerRoute:"jupyter_iam/oauth2/callback",oauth2CallbackUIRoute:"/iam/oauth2/linkedin/callback"}},kn=()=>{if(typeof document>"u")return"";const n=document.getElementById("datalayer-config-data");if(!n?.textContent)return"";try{const s=JSON.parse(n.textContent);return String(s?.iamUrl||"").replace(/\/$/,"")}catch{return""}},Ns=(n,s="Unable to start social sign-in.")=>{if(n instanceof Error&&n.message)return n.message;if(typeof n=="string"&&n.trim())return n;if(n&&typeof n=="object"&&"message"in n){const c=n.message;if(typeof c=="string"&&c.trim())return c}return s},Bs=mo`
2
- .signin-input-theme-scope input:-webkit-autofill,
3
- .signin-input-theme-scope input:-webkit-autofill:hover,
4
- .signin-input-theme-scope input:-webkit-autofill:focus,
5
- .signin-input-theme-scope input:-webkit-autofill:active,
6
- .signin-input-theme-scope input:-webkit-autofill:disabled,
7
- .signin-input-theme-scope textarea:-webkit-autofill,
8
- .signin-input-theme-scope textarea:-webkit-autofill:hover,
9
- .signin-input-theme-scope textarea:-webkit-autofill:focus,
10
- .signin-input-theme-scope textarea:-webkit-autofill:active,
11
- .signin-input-theme-scope textarea:-webkit-autofill:disabled {
12
- -webkit-text-fill-color: var(--fgColor-default) !important;
13
- caret-color: var(--fgColor-default) !important;
14
- -webkit-box-shadow: 0 0 0 1000px var(--bgColor-default) inset !important;
15
- box-shadow: 0 0 0 1000px var(--bgColor-default) inset !important;
16
- background-color: var(--bgColor-default) !important;
17
- transition: background-color 9999s ease-in-out 0s !important;
18
- }
19
-
20
- .signin-input-theme-scope input:disabled,
21
- .signin-input-theme-scope textarea:disabled {
22
- -webkit-text-fill-color: var(--fgColor-muted) !important;
23
- -webkit-box-shadow: 0 0 0 1000px var(--bgColor-default) inset !important;
24
- box-shadow: 0 0 0 1000px var(--bgColor-default) inset !important;
25
- background-color: var(--bgColor-default) !important;
26
- opacity: 1 !important;
27
- }
28
- `,Vs=({onSignIn:n,onApiKeySignIn:s,loginUrl:c,name:a,title:d="Datalayer OTEL",description:b="Sign in to access the observability dashboard.",icon:S,leadingIcon:C=t.jsx(po,{size:24}),github:p=!1,google:K=!1,linkedin:B=!1,apiKey:Ge=!1,signUp:F=!0,socialSignInNavigationTarget:Z,asDoc:v=!1,fillHeight:I=!0,hideHero:ee=!1,calloutTitle:Pe,calloutDescription:Ke,passwordToggleLabel:ie="Sign in with a password",signUpTitle:Nt="Don't have an account?",signUpDescription:Y="Create a free Datalayer account with your email address.",signUpLabel:pt="Sign up with email",signUpHref:Me="https://datalayer.ai/signup",onSignUp:V,forgotPasswordHref:q="/password",forgotPasswordLabel:$e="Forgot password?",showForgotPassword:mt=!0,socialButtonMarginTop:x=3,actionButtonMaxWidth:J=320})=>{const te=v&&!ee,Ye=a??(v&&d==="Datalayer OTEL"?"Datalayer Sign In":d),gt=S??(v?t.jsx(Us,{size:24}):C),L=o.useMemo(()=>{if(c)return c;const i=kn();return i?`${i}/api/iam/v1/login`:"/api/iam/v1/login"},[c]),[W,ve]=o.useState(""),[re,ht]=o.useState(""),[qe,le]=o.useState(!1),[ce,Je]=o.useState(!1),[k,ye]=o.useState(!1),[de,Ce]=o.useState(!1),[Ue,Qe]=o.useState(null),[z,we]=o.useState(null),[ne,Xe]=o.useState(""),[ue,Ze]=o.useState(null),[Oe,M]=o.useState(null),{enqueueToast:fe}=ro(),[pe,E]=o.useState(!1),[Q,oe]=o.useState(""),D=o.useRef(null),Fe=o.useCallback(i=>lo()?Sn.URLExt.join(Sn.PageConfig.getBaseUrl(),i.oauth2CallbackServerRoute):`${window.location.protocol}//${window.location.hostname}${window.location.port?`:${window.location.port}`:""}${i.oauth2CallbackUIRoute}`,[]),me=o.useMemo(()=>{if(typeof window>"u")return"/";const i=`${window.location.pathname}${window.location.search}${window.location.hash}`;return i.startsWith("/")?i:"/"},[]),ke=o.useCallback(async i=>{if(!de){M(null),Qe(i.name),Ce(!0);try{const g=kn(),m=new URLSearchParams({provider:i.name,callback_uri:Fe(i)}),R=Z===void 0?void 0:String(Z||"").trim(),y=R===void 0?me&&me!=="/"?me:void 0:R&&R.startsWith("/")&&!R.startsWith("//")?R:void 0;y&&m.set("post_auth_redirect",y);const ze=`${g||""}/api/iam/v1/oauth2/authz/url?${m.toString()}`,j=await fetch(ze),se=await j.json(),_e=se?.autorization_url;if(!j.ok||!_e)throw new Error(se?.message||"Unable to start social sign-in.");window.location.assign(_e)}catch(g){const m=Ns(g);M(m),fe(m,{variant:"error"}),Qe(null),Ce(!1)}}},[Fe,me,fe,de,Z]);o.useEffect(()=>{pe&&D.current?.focus()},[pe]);const $=o.useCallback(()=>{E(!1),oe("")},[]),bt=o.useCallback(()=>{!Q.trim()||!s||(s(Q.trim()),$())},[Q,s,$]),xt=o.useCallback(()=>{if(V){V();return}window.location.assign(Me)},[V,Me]),St=o.useCallback(()=>{if(q){if(q.startsWith("http://")||q.startsWith("https://")){window.open(q,"_blank","noopener,noreferrer");return}window.location.assign(q)}},[q]),Le=o.useCallback(async()=>{if(!(v||!W||!re||k)){ye(!0),M(null);try{const i=await fetch(L,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({handle:W,password:re})});if(!i.ok)throw new Error(`HTTP ${i.status}`);const g=await i.json();if(g.success&&g.token){const m=String(g?.user?.id||g?.user?.uid||"").trim();if(!!g?.user?.mfaUrl&&m){we(m),Ze(g.token),M(null);return}n&&n(g.token,W)}else M(g.message||"Invalid username or password.")}catch(i){M(i instanceof Error?i.message:String(i))}finally{ye(!1)}}},[v,W,re,k,L,n]),ge=o.useCallback(async()=>{if(!(v||k||!z||!ne.trim()||!ue)){ye(!0),M(null);try{const i=new URL(L,window.location.origin),g=i.pathname.endsWith("/api/iam/v1/login")?i.href.replace(/\/api\/iam\/v1\/login$/,""):`${i.origin}`,m=await fetch(`${g}/api/iam/v1/users/${z}/mfa/validate`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userUid:z,code:ne.trim()})}),R=await m.json();if(!m.ok||!R?.success)throw new Error(R?.message||"Failed to validate your MFA code.");n&&n(ue,W)}catch(i){const g=i instanceof Error?i.message:String(i);M(g),fe(g,{variant:"error"})}finally{ye(!1)}}},[v,fe,W,k,L,ne,ue,z,n]),je=o.useCallback(i=>{i.key==="Enter"&&(z?ge():Le())},[z,Le,ge]),he=de||k||v;return t.jsxs(f,{className:"signin-input-theme-scope",display:"flex",alignItems:ee||te||!I?"flex-start":"center",justifyContent:"center",minHeight:ee||te||!I?"auto":"100vh",bg:ee?"transparent":"canvas.default",color:"fg.default",py:ee?0:te?2:4,children:[t.jsx(Bs,{}),t.jsxs(f,{width:"100%",maxWidth:440,p:0,children:[!ee&&t.jsxs(t.Fragment,{children:[t.jsxs(f,{display:"flex",alignItems:"center",gap:2,mb:te?2:3,justifyContent:"center",children:[gt,t.jsx(ct,{sx:{fontSize:3},children:Ye})]}),t.jsx(H,{as:"p",sx:{fontSize:1,color:"fg.muted",mb:te?2:3,textAlign:"center"},children:b})]}),(Pe||Ke)&&t.jsxs(f,{mb:3,textAlign:"center",children:[Pe&&t.jsx(ct,{as:"h3",sx:{fontSize:2,mb:1},children:Pe}),Ke&&t.jsx(H,{sx:{color:"fg.muted",fontSize:1},children:Ke})]}),!z&&(p||K||B)&&t.jsxs(t.Fragment,{children:[p&&t.jsx(G,{block:!0,size:"large",leadingVisual:Ue==="github"?()=>t.jsx(Pt,{size:"small"}):Ls,disabled:he,onClick:()=>ke(Ot.github),sx:{mt:x,maxWidth:J,mx:"auto"},children:"Sign in with GitHub"}),K&&t.jsx(G,{block:!0,size:"large",leadingVisual:Ue==="google"?()=>t.jsx(Pt,{size:"small"}):zs,disabled:he,onClick:()=>ke(Ot.google),sx:{mt:x,maxWidth:J,mx:"auto"},children:"Sign in with Google"}),B&&t.jsx(G,{block:!0,size:"large",leadingVisual:Ue==="linkedin"?()=>t.jsx(Pt,{size:"small"}):_s,disabled:he,onClick:()=>ke(Ot.linkedin),sx:{mt:x,maxWidth:J,mx:"auto"},children:"Sign in with LinkedIn"})]}),!z&&!qe&&t.jsx(f,{mt:3,display:"flex",justifyContent:"center",children:t.jsx(G,{leadingVisual:Lt,size:"large",block:!0,disabled:v||k||de,onClick:()=>le(!0),sx:{maxWidth:J,mx:"auto"},children:ie})}),!z&&qe&&t.jsxs(f,{mt:4,children:[t.jsxs(ae,{required:!0,sx:{mb:3},children:[t.jsx(ae.Label,{children:"Username"}),t.jsx(dt,{autoFocus:!0,block:!0,placeholder:"Your username",value:W,disabled:k||v,onChange:i=>ve(i.target.value),onKeyDown:je})]}),t.jsxs(ae,{required:!0,sx:{mb:3},children:[t.jsx(ae.Label,{children:"Password"}),t.jsx(dt,{block:!0,placeholder:"Your password",type:ce?"text":"password",value:re,disabled:k||v,onChange:i=>ht(i.target.value),onKeyDown:je,trailingAction:t.jsx(dt.Action,{onClick:()=>Je(!ce),disabled:k||v,icon:ce?Os:Fs,"aria-label":ce?"Hide password":"Show password",sx:{color:"var(--fgColor-muted)"}})})]}),t.jsxs(f,{display:"flex",alignItems:"center",justifyContent:"space-between",mt:3,children:[t.jsx(G,{variant:"primary",disabled:k||v||!W||!re,onClick:Le,children:k?"Signing in…":"Sign In"}),mt&&t.jsx(co,{as:"button",sx:{fontSize:1,cursor:v?"not-allowed":"pointer",background:"none",border:"none",opacity:v?.6:1},onClick:()=>{v||k||St()},children:$e})]})]}),z&&t.jsxs(t.Fragment,{children:[t.jsxs(ae,{required:!0,sx:{mb:3,mt:2},children:[t.jsx(ae.Label,{children:"MFA Code"}),t.jsx(dt,{autoFocus:!0,block:!0,placeholder:"Your MFA code",value:ne,disabled:k||v,onChange:i=>Xe(i.target.value),onKeyDown:je})]}),t.jsx(G,{variant:"primary",block:!0,disabled:k||v||!ne.trim(),onClick:ge,sx:{maxWidth:J,mx:"auto"},children:k?"Validating…":"Validate MFA Code"})]}),Oe&&t.jsx(H,{sx:{color:"danger.fg",fontSize:1,mt:3,display:"block"},children:Oe}),F&&t.jsxs(f,{mt:4,pt:4,textAlign:"center",borderTop:"1px solid",borderColor:"border.muted",children:[t.jsx(ct,{as:"h3",sx:{fontSize:2,mb:2},children:Nt}),t.jsx(H,{as:"p",sx:{color:"fg.muted",fontSize:1,mb:3},children:Y}),t.jsx(f,{display:"flex",justifyContent:"center",children:t.jsx(G,{variant:"primary",size:"large",leadingVisual:uo,disabled:v||k,onClick:xt,children:pt})})]}),Ge&&s&&t.jsxs(t.Fragment,{children:[t.jsxs(f,{display:"flex",alignItems:"center",gap:2,my:3,children:[t.jsx(f,{flex:1,height:"1px",bg:"border.default"}),t.jsx(H,{sx:{fontSize:0,color:"fg.muted"},children:"or"}),t.jsx(f,{flex:1,height:"1px",bg:"border.default"})]}),t.jsx(G,{block:!0,leadingVisual:Lt,disabled:v||k||de,onClick:()=>E(!0),sx:{maxWidth:J,mx:"auto"},children:"Sign in with an API Key"}),pe&&t.jsx(f,{role:"dialog","aria-modal":"true","aria-labelledby":"signin-api-key-title",onKeyDown:i=>{i.key==="Escape"&&$()},onClick:$,position:"fixed",inset:0,zIndex:200,p:3,bg:"canvas.backdrop",display:"flex",alignItems:"center",justifyContent:"center",children:t.jsxs(f,{as:"form",onClick:i=>i.stopPropagation(),onSubmit:i=>{i.preventDefault(),bt()},width:"min(560px, 100%)",p:3,borderRadius:2,border:"1px solid",borderColor:"border.default",bg:"canvas.overlay",color:"fg.default",boxShadow:"shadow.large",children:[t.jsx(ct,{id:"signin-api-key-title",sx:{fontSize:2,mb:2},children:"Enter your API Key"}),t.jsxs(ae,{required:!0,children:[t.jsx(ae.Label,{children:"API Key"}),t.jsx(fo,{block:!0,required:!0,autoFocus:!0,placeholder:"Paste your API key here",value:Q,onInput:i=>oe(i.currentTarget.value),ref:D})]}),t.jsxs(f,{mt:3,display:"flex",justifyContent:"flex-end",gap:2,children:[t.jsx(G,{type:"button",onClick:$,children:"Cancel"}),t.jsx(G,{type:"submit",variant:"primary",disabled:!Q.trim(),children:"Authenticate"})]})]})})]})]})]})};function Hs(n){const{agentId:s,instructions:c,model:a,frontendTools:d,inference:b,subagents:S,sharing:C,onSubagentEvent:p,modeEffect:K}=n;return{type:"browser-vercel-ai",endpoint:"",agentId:s,enableConfigQuery:!1,options:{instructions:c,model:a,frontendTools:d,inference:b,subagents:S,sharing:C,onSubagentEvent:p,modeEffect:K}}}const jn=go((n,s)=>({pending:void 0,suggest:(c,a)=>{const d=c.trim();d&&n({pending:{text:d,submit:a?.submit??!1,nonce:(s().pending?.nonce??0)+1}})},consume:()=>n({pending:void 0})}));function Ws({agentName:n,sandboxStillRuns:s=!1,temporary:c=!0,onSignedIn:a,onSignUp:d}){const{configuration:b}=An(),S=o.useCallback(C=>{ho.getState().checkIAMToken(C),a?.()},[a]);return t.jsx(f,{height:"100%",minHeight:0,overflowY:"auto",bg:"canvas.default",px:4,py:4,children:t.jsxs(f,{maxWidth:440,mx:"auto",children:[t.jsxs(f,{display:"flex",alignItems:"center",justifyContent:"center",gap:2,color:"attention.fg",mb:2,children:[t.jsx(Lt,{size:20}),t.jsx(H,{sx:{fontSize:2,fontWeight:"semibold",color:"fg.default"},children:c?"This demo runs on a shared key":"Your key has expired"})]}),t.jsxs(H,{as:"p",sx:{fontSize:1,color:"fg.muted",textAlign:"center",mb:3},children:[c?`${n??"The agent"} has used the time this key allows. Sign in to point your own agent at it, use your own data, and drop the time limit.`:`${n??"The agent"} stopped because your session ran out.`,s?" Your notebook is still running in this page.":""]}),t.jsx(Vs,{hideHero:!0,fillHeight:!1,calloutTitle:"Sign in to keep going",github:!0,google:!0,linkedin:!0,socialSignInNavigationTarget:typeof window>"u"?void 0:`${window.location.pathname}${window.location.search}`,loginUrl:b?.iamUrl?`${b.iamUrl}/api/iam/v1/login`:void 0,onSignIn:S,onSignUp:d})]})})}const Ds="https://r1.datalayer.run";function Gs(n=!0){const{configuration:s}=An(),c=zt(C=>C.token),a=s?.aiInferenceUrl||Ds,d=bo(a,n&&!c),b=c||d.token,S=o.useMemo(()=>({inferenceUrl:a,token:b||void 0}),[a,b]);return{inference:S,needsSignIn:xo(S),anonymous:d,inferenceUrl:a}}const Ks={name:"general-purpose",description:"A capable generalist for a task none of the specialists covers: research, reasoning, drafting, checking.",instructions:"You are a capable general-purpose assistant. Carry out the task you are given completely and report the result plainly, saying what you could not do."};function En(n){const s=n?.subagents;if(!s)return[];const c=(s.subagents??[]).map(a=>{const d=a.ref?So(a.ref):void 0;return{name:a.name,description:a.description||d?.description||a.name,instructions:a.instructions??d?.systemPrompt,model:a.model??d?.model??s.defaultModel,icon:d?.icon}});return s.includeGeneralPurpose?[...c,Ks]:c}function Ys(n){return n.replace(/^datalayer_/,"").replace(/_lexical$/,"")}function qs(n){const s=Ys(n);return/^executeCodeIn(Notebook|Document)$/.test(s)||/^(read|list)[A-Z]/.test(s)}function Js(n,s){return n.filter(c=>s?.has(c.name)||qs(c.name))}function Qs(n,s){const c=a=>s&&a.value.id===`${s}-tools`?0:a.value.id==="notebook-tools"?1:2;return n.map((a,d)=>({entry:a,index:d,rank:c(a)})).sort((a,d)=>a.rank-d.rank||a.index-d.index).map(a=>a.entry)}function Xs(n,s,c){if(!c||!n.endsWith("-tools"))return!1;const a=n.slice(0,-6);return s.has(a)&&a!==c}const Zs={type:"object",properties:{}};function ea(n,s){const c=new Set(n.toolset);return n.commands.filter(a=>c.has(a.name)).map(a=>({name:a.name,description:a.description,parameters:a.parameters??Zs,location:"frontend",handler:async d=>{if(!s)throw new Error(`${a.name}: the ${n.plugin??n.id} plugin is not mounted on this page.`);const b=Object.keys(d??{}).length>0?d:void 0,S=await s.executeCommand(a.command,b);return S===void 0?{ok:!0,command:a.command,argument:b}:S}}))}function Mn(n,s){return n.flatMap(c=>ea(c,s))}function ta(){const n=vo(),s=Pn();return o.useMemo(()=>Mn(s,n),[s,n])}const In={opening:"Opening your conversation…",notOpened:n=>`Your conversation could not be opened, so this is a new one: ${n}`};function na(n){let s;for(const c of n.split(/\r?\n\r?\n/)){const a=c.split(/\r?\n/).filter(d=>d.startsWith("data:")).map(d=>d.slice(5).trim()).join("");if(a)try{const d=JSON.parse(a);d.type==="MESSAGES_SNAPSHOT"&&Array.isArray(d.messages)&&(s=d.messages)}catch{}}return s}async function Tn(n){try{const s=await n.json();if(typeof s.detail=="string"&&s.detail)return s.detail}catch{}return`${n.status}`}async function oa({agentBaseUrl:n,agentId:s,uid:c,token:a,fetcher:d=fetch}){const b=`${n.replace(/\/+$/,"")}/api/v1/apps/sessions/${encodeURIComponent(c)}`,S=a?{Authorization:`Bearer ${a}`}:{},C=await d(`${b}/messages`,{headers:S});if(C.ok){const B=await C.json();return vn(B.messages)}if(C.status!==404)throw new Error(await Tn(C));const p=await d(`${b}/resume`,{method:"POST",headers:{"Content-Type":"application/json",...S},body:JSON.stringify({agent:s})});if(!p.ok)throw new Error(await Tn(p));const K=na(await p.text());if(!K)throw new Error(`The runtime said nothing of session ${c}.`);return vn(K)}const sa="var(--theme-accent)";function $n({face:n,size:s}){return typeof n=="string"?t.jsx(yo,{emoji:n,size:s,label:""}):t.jsx(t.Fragment,{children:n})}function aa({face:n,size:s,state:c}){const a=c==="thinking"||c==="working",d=c==="paused";return t.jsxs(f,{as:"span","aria-hidden":!0,"data-presence":c,position:"relative",display:"inline-flex",alignItems:"center",justifyContent:"center",width:s+8,height:s+8,flexShrink:0,fontSize:s,lineHeight:1,children:[t.jsx(f,{as:"span",position:"absolute",inset:0,borderRadius:"50%",boxShadow:d?"none":`0 0 0 2px ${sa}`,border:d?"2px dashed":"none",borderColor:"border.default",opacity:a||c==="waiting"||d?.9:0,transition:"opacity var(--theme-motion-status, 0ms) var(--theme-motion-easing, ease)",animation:a?"loopPresenceBreath 1.8s ease-in-out infinite":"none",reducedMotion:{animation:"none"},sx:{"@keyframes loopPresenceBreath":{"0%, 100%":{transform:"scale(0.92)",opacity:.35},"50%":{transform:"scale(1.06)",opacity:.9}}}}),t.jsx(f,{as:"span",display:"inline-flex",opacity:d?.55:1,filter:d?"grayscale(0.6)":"none",transition:"opacity var(--theme-motion-status, 0ms) var(--theme-motion-easing, ease)",children:t.jsx($n,{face:n,size:s})})]})}function ia({state:n}){return t.jsx(H,{role:"status","aria-live":"polite","data-presence-line":n,sx:{fontSize:0,color:n==="waiting"?"fg.default":"fg.muted",fontWeight:n==="waiting"?"semibold":"normal",whiteSpace:"nowrap",flexShrink:0},children:Co[n]})}const ra=_t(void 0),la=_t(""),ca=_t({}),X="",da=1400,Rn=parseInt(Ms["--loop-face-large"],10);function ga({workspace:n}){const s=wo(),c=ko(),a=o.useRef(null),{setViewControls:d}=n,[b,S]=o.useState(null),C=jo(),p=C.getConfig(Eo),K=p?.placeholder||s.placeholder,B=p?.defaultSurface??"notebook",Ge=C.getConfig(Io),[F,Z]=o.useState(X),v=o.useRef(!1),I=N(To),ee=N(Ro),Pe=N(Ao),ie=N(Po)[0]?.value,Y=Mt(ie?.promptStance??ra)??ie?.prompt,pt=N(Mo),Me=$o(pt[0]?.value),V=o.useRef(Me);V.current=Me;const q=o.useRef(""),$e=N(Uo),mt=o.useMemo(()=>Oo(()=>$e.reduce((e,r)=>({...e,...r.value.extras.value}),{})),[$e]),x=Mt($e.length>0?mt:ca),J=o.useRef(new Set),te=Fo(As,n),Ye=!te.allowed,gt=Ye?te.reason??"Chat is unavailable for this sandbox":void 0,[L,W]=o.useState(!1),[ve,re]=o.useState(!1),[ht,qe]=o.useState({open:!1,pendingApproval:!1}),le=Lo(L,ht,p?.presence?.paused===!0),ce=p?.presence?.onPresence;o.useEffect(()=>{ce?.(le),V.current?.setPresence(le)},[ce,le]);const Je=o.useRef(p?.presence?.onSaying);Je.current=p?.presence?.onSaying;const k=o.useRef({answering:!1}),ye=o.useCallback(e=>{a.current=e,re(!!e)},[]),de=o.useCallback(e=>{const{open:r,pendingApproval:l}=zo(e);qe(xe=>xe.open===r&&xe.pendingApproval===l?xe:{open:r,pendingApproval:l});const h={saying:No(e),answering:_o(e)},u=k.current;(u.saying?.id!==h.saying?.id||u.saying?.text!==h.saying?.text||u.answering!==h.answering)&&(k.current=h,Je.current?.(h));const O=V.current;if(!O)return;O.items(e);const P=new Set(["complete","completed","done","error","failed","cancelled","canceled","rejected","denied","stopped"]),A={insertcell:"adding a cell",updatecell:"editing a cell",runcell:"running a cell",deletecells:"removing cells",readallcells:"reading the notebook",readcell:"reading a cell",executecode:"running code",insertblock:"adding a block",updateblock:"editing a block",runblock:"running a block",readdocument:"reading the document"};let w;for(let xe=e.length-1;xe>=0;xe-=1){const lt=e[xe];if(typeof lt.toolName=="string"&&lt.toolCallId){P.has(String(lt.status).toLowerCase())||(w=lt);break}}if(!w){O.activity(void 0);return}const At=w.toolName.toLowerCase().replace(/^datalayer_/,"").replace(/_lexical$/,"").replace(/[^a-z]/g,""),ao=A[At]??`using ${w.toolName}`;O.activity(`${q.current||"The agent"} is ${ao}…`)},[]),Ce=o.useRef(x);Ce.current=x;const Ue=o.useCallback(e=>{Hn(e),V.current?.usage(e),Ce.current.onUsage?.(e)},[]),Qe=o.useCallback(e=>{W(e),e||V.current?.end("done")},[]),z=o.useCallback(e=>{const r=V.current;if(!r)return;let l=-1;for(let u=e.length-1;u>=0;u-=1)if(e[u].role==="user"){l=u;break}const h=e.slice(l+1).filter(u=>u.role==="assistant").map(Bo).filter(u=>u.trim().length>0).join(`
29
-
30
- `);r.assistant(h)},[]),we=o.useRef([]),ne=o.useRef(!1),Xe=o.useRef(void 0),ue=o.useRef(void 0),Ze=N(Vo),Oe=o.useRef(Ze);Oe.current=Ze;const M=o.useCallback((e,r)=>{if(ue.current)return ue.current;const l=Ho(Oe.current.map(O=>O.value),r),h=l?.loop;if(ne.current&&h?.files&&h.files.length>0){const O=Xe.current;if(!O)return"A file is given to an application running on a runtime: run it on Datalayer or on your machine to give it one.";let P;try{P=h.files.map(A=>({file:Do(String(A.name??"")),base64:Wo(String(A.data_url??""))}))}catch(A){return A instanceof Error?A.message:String(A)}O.execute(Go(P)).then(A=>{if(!A.success){S(`The files could not be put in the sandbox: ${A.error??"it failed"}.`);return}M(`${e}
31
-
32
- ${Ko(P.map(w=>w.file))}`,{...l,loop:Object.fromEntries(Object.entries(h).filter(([w])=>w!=="files"))})});return}V.current?.begin(e,a.current?.thread());const u=a.current?.send;if(!u){we.current.push([e,l]);return}u(e,l)},[]);o.useEffect(()=>{d(ve?{busy:L,stop:a.current?.stop,newChat:a.current?.newChat,send:M}:null)},[L,ve,d,M]),o.useEffect(()=>()=>d(null),[d]),o.useEffect(()=>n.prompts.subscribe(M),[n.prompts,M]),o.useEffect(()=>{if(!ve||we.current.length===0)return;const e=we.current.splice(0,we.current.length);for(const[r,l]of e)a.current?.send(r,l)},[ve]);const fe=o.useRef(!1),pe=o.useCallback(async e=>{S(null);const r=await Yo(Ce.current,e);if(r){r.sent?ot(""):S(r.refused);return}fe.current||(fe.current=!0,Ge?.firstPromptHook?.());const l=await n.submit(e);if(!l.handled){S(l.reason??null);return}ot(""),l.result?.content&&S(l.result.content)},[n,Ge?.firstPromptHook]),E=o.useMemo(()=>I.find(e=>e.value.surfaceId===F)?.value,[I,F]),Q=o.useCallback(e=>{v.current=!0,Z(e)},[]);o.useEffect(()=>qo(Q),[Q]),o.useEffect(()=>{Jo(I.map(e=>e.value.surfaceId))},[I]),o.useEffect(()=>{Qo(F&&F!==X?F:$s)},[F]);const oe=o.useMemo(()=>B===X||B==="none"?void 0:I.find(e=>e.value.surfaceId===B),[I,B]);o.useEffect(()=>{v.current||!oe||De(oe.value,n)&&Z(B)},[oe,n,B]);const[D,Fe]=o.useState(null),me=o.useRef(null),ke=p?.fullScreenTopOffset??0,{fullScreen:$,usingApi:bt,toggle:xt,topOffsetPx:St}=Xo(me,{forceOverlay:!!ke,topOffset:ke}),[Le,ge]=o.useState(!1),je=o.useRef(!1);o.useEffect(()=>{!L||je.current||$||(je.current=!0,ge(!0))},[L,$]),o.useEffect(()=>{$&&ge(!1)},[$]),o.useEffect(()=>{E&&!De(E,n)&&(Fe(E.surfaceId),Z(X))},[E,n]);const he=o.useMemo(()=>{if(D)return I.find(e=>e.value.surfaceId===D)?.value;if(!v.current&&F===X)return oe?.value},[I,D,F,oe]);o.useEffect(()=>{if(!D||F!==X)return;const e=I.find(r=>r.value.surfaceId===D);e&&De(e.value,n)&&(Fe(null),Z(D))},[I,F,D,n]);const i=n.agentId?.trim()||"default",g=Zo(n.sandbox.target??"local");ne.current=g;const m=es(),R=Mt(m?.selected??la),y=m?.members.find(e=>e.id===R),vt=N(ts)[0]?.value,ze=vt?.specId,j=yn(y?.specId??i)??(ze?yn(ze):void 0),se=y?void 0:vt,_e=g&&!y?Rs(ze,j):void 0;q.current=y?.name??j?.name??i;const Bt=N(ns),Vt=x.hiddenOpeners,Ht=x.hideOpeners,yt=x.openers,Ct=o.useMemo(()=>{if(Ht)return[];const e=new Set(Vt??[]),r=w=>e.size===0?w:w.filter(At=>!e.has(At.text));if(yt)return r(yt);const l=Bt.flatMap(w=>w.value.suggestions);if(l.length>0)return r(l);const h=r(j?.suggestions??[]),u=r(m?.team.suggestions??[]);if(u.length===0)return h;const O=new Set(u.map(w=>w.text)),P=m?.team.name??"Team",A=y?.name??j?.name??i;return[...u.map(w=>({...w,group:P})),...h.filter(w=>!O.has(w.text)).map(w=>({...w,group:A}))]},[Bt,m,j,y,i,Vt,Ht,yt]),et=o.useMemo(()=>Ct.map(e=>({title:e.summary??e.text,message:e.message??e.text,group:e.group})),[Ct]),wt=Ae(j?.icon),_=p?.presence,Un=Ae(m?.team.icon),Wt=N(os),tt=o.useMemo(()=>{const e=[],r=new Map,l=new Set,h=new Set(I.map(u=>u.value.surfaceId));for(const u of Qs(Wt,E?.surfaceId)){if(Xs(u.value.id,h,E?.surfaceId))continue;let O;try{O=u.value.tools(n)}catch(P){console.warn(`[loop] frontend tools from '${u.plugin}' failed:`,P);continue}for(const P of O){const A=r.get(P.name);if(A){console.warn(`[loop] frontend tool '${P.name}' from '${u.plugin}' is shadowed by the one from '${A}'.`);continue}r.set(P.name,u.plugin),e.push(P),u.value.chatView&&l.add(P.name)}}for(const u of x.frontendTools??[])r.has(u.name)||(r.set(u.name,"chat-extras"),e.push(u),l.add(u.name));return E?e:Js(e,l)},[Wt,n.surfaceId,n.agentId,x.frontendTools,E?.surfaceId,I]),kt=ta(),Ne=o.useMemo(()=>{if(kt.length===0)return tt;const e=new Set(tt.map(r=>r.name));return[...tt,...kt.filter(r=>!e.has(r.name))]},[tt,kt]),Dt=Pn(),jt=x.agentToolBundles,On=o.useMemo(()=>{const e=x.frontendTools??[];if(!jt?.length)return x.frontendTools;const r=Mn(Dt.filter(h=>jt.includes(h.id)),C),l=new Set(e.map(h=>h.name));return[...e,...r.filter(h=>!l.has(h.name))]},[x.frontendTools,jt,Dt,C]);Xe.current=g&&Ne.some(e=>e.name===ss)?C.getOutput(ut)?.sandbox:void 0;const T=as(n.sandbox,n.serverUrl),Gt=N(is),Fn=o.useMemo(()=>Gt.filter(e=>e.value.composer).map(e=>({name:e.value.name,description:e.value.description})),[Gt]),Ln=o.useMemo(()=>{if(!m||!y)return En(j).map(l=>({name:l.name,description:l.description,icon:Ae(l.icon)}));const e=m.members.map(l=>({name:l.name,description:l.description,emoji:l.emoji,icon:Ae(l.icon),disabled:l.id===y.id,disabledReason:l.id===y.id?`You are already talking to ${l.name}`:void 0})),r=Cn(m.team,y.id).filter(l=>!m.members.some(h=>h.name===l.name)).map(l=>({name:l.name,description:l.description,icon:Ae(l.icon)}));return[...e,...r]},[m,y,j]),{inference:Kt,anonymous:zn}=Gs(g),_n=zt(e=>e.user),Et=g&&zn.status==="expired",Yt=!_n,Be=rs();ue.current=Be.disabled?Be.disableReason||"This conversation is closed here.":void 0;const It=T===void 0?ls(n.sandbox,s):void 0,nt=Ye||Et||!!_e||!!It||Be.disabled,qt=Et?Yt?s.demoKeyExpired:s.keyExpired:_e??It??gt??(Be.disabled?Be.disableReason:void 0),[Jt,ot]=o.useState(""),[Nn,Qt]=o.useState(),st=Nn??se?.model??j?.model??n.model??"",Ee=cs(),Xt=o.useRef(Ee),Zt=o.useRef(R),en=o.useRef(Ee);en.current=Ee,o.useEffect(()=>{Zt.current!==R&&(Zt.current=R,Xt.current=en.current,Qt(void 0))},[R]);const Bn=Ee&&Ee!==Xt.current?Ee:null,[Vn,Hn]=o.useState(),Wn=Bn??Vn??null,Dn=$t(Se.inpromptMenu),Gn=$t(Se.promptAction),tn=$t(Se.chatHeader),Kn=o.useMemo(()=>m?.members.map(e=>({id:e.id,name:e.name,description:e.description,icon:Ae(e.icon)}))??[],[m]),be=jn(e=>e.pending),[nn,Yn]=o.useState(0);o.useEffect(()=>ds(()=>Yn(e=>e+1)),[]),o.useEffect(()=>{be&&(ot(be.text),jn.getState().consume(),be.submit&&pe(be.text))},[be]);const Ie=!!(se?.createPayload?.app_spec||C.getConfig(ut)?.datalayerCreatePayload?.app_spec),qn=zt(e=>e.token),on=C.getConfig(ut)?.datalayerVisitors,Jn=us(on),Qn=C.getConfig(ut)?.embedToken,Ve=on?Jn.token:Qn||qn,U=p?.thread,[Te,sn]=o.useState(null),Xn=!!(U?.fromRuntime&&Te?.given!==U.id);o.useEffect(()=>{if(!U?.fromRuntime||!Ie||!T)return;let e=!0;return(async()=>{let r="";for(let l=0;l<4&&e;l+=1)try{const h=await oa({agentBaseUrl:T,agentId:i,uid:U.id,token:Ve});e&&sn({given:U.id,thread:{...U,fromRuntime:!1,messages:h}});return}catch(h){r=h instanceof Error?h.message:String(h),await new Promise(u=>setTimeout(u,1500))}e&&sn({given:U.id,thread:{id:fs(),messages:[],onStarted:U.onStarted},said:In.notOpened(r)})})(),()=>{e=!1}},[U?.id,U?.fromRuntime,Ie,T,i,Ve]);const an=U?.fromRuntime?Te?.given===U.id?Te.thread:void 0:U,Tt=o.useMemo(()=>g?Hs({agentId:y?.specId??i,instructions:ps(j,se?.instructions),model:st||void 0,inference:Kt,frontendTools:Ne,subagents:m&&y?Cn(m.team,y.id):En(j),sharing:m?.sharing,onSubagentEvent:e=>Ps.getState().appendSubagentEvent(e),modeEffect:se?.modeEffect}):T!==void 0?{type:"ag-ui",endpoint:Ie?`${T}/api/v1/apps/agents/${encodeURIComponent(i)}/ag-ui/`:`${T}/api/v1/ag-ui/${i}/`,...Ie&&Ve?{authToken:Ve}:{},...Ie?{uiSocket:`${T.replace(/^http/,"ws")}/api/v1/apps/ui`,uiFiles:`${T}/api/v1/apps/agents/${encodeURIComponent(i)}/files`}:{},agentId:i,configEndpoint:`${T}/api/v1/configure`,enableConfigQuery:!0}:void 0,[i,g,Kt,y,Ne,m,j,se,st,T,Ie,Ve]),at=ms(!g,Tt?.type==="ag-ui"?Tt.configEndpoint:void 0,void 0,i),He=gs(),it=hs(i),[rn,ln]=o.useState(void 0),[Zn,eo]=o.useState(void 0);o.useEffect(()=>{if(g||T===void 0)return;let e=!1;return fetch(`${T}/api/v1/configure/models?agent_id=${encodeURIComponent(i)}`).then(r=>r.ok?r.json():null).then(r=>{e||(ln(r?bs(r):[]),eo(r?xs(r):void 0))}).catch(()=>{e||ln([])}),()=>{e=!0}},[T,i,g]);const to=o.useMemo(()=>Ss(rn,()=>Object.values(vs).filter(e=>e.available&&ys(e)).map(e=>({id:e.id,name:e.name,provider:e.provider}))),[rn]),cn=o.useMemo(()=>{const e=at.data?.builtinTools??[],r=new Set(e.map(l=>l.name));return{runtime:e,frontend:Ne.filter(l=>!r.has(l.name)).map(l=>({id:l.name,name:l.name}))}},[at.data?.builtinTools,Ne]),dn=o.useMemo(()=>new Set((He.data?.skills??[]).filter(e=>e.status==="enabled"||e.status==="loaded").map(e=>e.id)),[He.data]),no=o.useCallback(async e=>{Qt(e),!(g||T===void 0)&&await fetch(`${T}/api/v1/configure/inference/provider`,{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify({model:e})}).catch(()=>{})},[T,g]),un=p?.promptPlacement==="bottom-chat",oo=p?.promptPlacement==="floating",Re=p?.promptPlacement==="top",We=p?.hidePrompt===!0||x.hidePrompt===!0,so={onSend:()=>{pe(Jt)},input:Jt,setInput:ot,focusTrigger:be||nn?(be?.nonce??0)+nn:void 0,placement:oo||Y==="floating"||Y==="floating-top"||Y==="floating-bottom"?"floating":"docked",floatingAnchor:Y==="floating-top"?"top":"bottom",isLoading:L,onStop:()=>n.viewControls.stop?.(),placeholder:qt??x.sendInstead?.says??K,typingSuggestions:Ct.map(e=>e.text),suggestions:et,disableInputPrompt:nt,connectionConfirmed:!nt,padding:Re||Y==="floating-top"||Y==="floating-bottom"||Y==="docked-top"?2:3,promptVariant:"lexical",autoFocus:p?.autoFocusPrompt??!0,mentionableAgents:Ln,promptCommands:Fn,headerContent:Dn.length>0?t.jsx(ft,{slot:Se.inpromptMenu,props:{workspace:n}}):void 0,footerExtras:Gn.length>0?t.jsx(ft,{slot:Se.promptAction,props:{workspace:n}}):void 0,showAgentsMenu:!_,showInlineAgentsMenu:!1,agents:Kn,selectedAgentId:R,onSelectAgent:e=>m?.select(e),showTokenUsage:x.showTokenUsage??p?.showTokenUsage??!0,showContextRing:!0,agentUsage:Wn??void 0,showModelSelector:!_,models:to,decisions:Zn,selectedModel:st,onModelSelect:e=>{no(e)},showToolsMenu:!_,availableTools:cn.runtime,availableFrontendTools:cn.frontend,mcpServers:at.data?.mcpServers??[],mcpStatusData:x.mcpStatusData??void 0,showSkillsMenu:!_,skills:He.data?.skills??[],skillsLoading:He.isLoading,enabledSkills:dn,onToggleSkill:e=>dn.has(e)?it.disableSkill(e):it.enableSkill(e),onToggleAllSkills:(e,r)=>e.forEach(l=>r?it.enableSkill(l):it.disableSkill(l)),codemodeEnabled:x.codemodeEnabled??!1,onToggleCodemode:x.onToggleCodemode,isA2AProtocol:!1,hasConfigData:!!at.data,hasSkillsData:!!He.data},fn=ee[0]?.value.Component,Rt=Pe[0]?.value.Component,pn=!p?.hideHeader&&!!Rt,rt=fn?t.jsx(fn,{workspace:n,composer:so}):null,mn=I.length>0&&p?.showSurfaceSelector!==!1?t.jsx(ua,{surfaces:I.map(e=>e.value),active:E?.surfaceId??he?.surfaceId??X,onChange:Q,workspace:n}):null,gn=t.jsxs(t.Fragment,{children:[I.map(e=>{const r=e.value,l=E?.surfaceId===r.surfaceId;return l||J.current.has(r.surfaceId)||De(r,n)?(J.current.add(r.surfaceId),t.jsx(f,{sx:l?{flex:"1 1 0",minWidth:0,minHeight:0}:{position:"absolute",inset:0,visibility:"hidden",pointerEvents:"none",zIndex:-1},children:t.jsx(Cs,{load:r.load,props:{surfaceId:r.surfaceId,workspace:n},fallback:t.jsxs(Ft,{children:["Loading ",r.title,"…"]}),errorFallback:u=>t.jsxs(Ft,{children:[r.title," failed to load: ",u.message]})})},r.surfaceId)):null}),!E&&he?t.jsx(f,{flex:"1 1 0",minWidth:0,minHeight:0,children:t.jsxs(Ft,{children:["Starting ",he.title,"…"]})}):null]}),hn=t.jsx(t.Fragment,{children:t.jsxs(f,{flex:Re&&E?"0 0 34%":"1 1 0",maxWidth:Re&&E?460:void 0,minWidth:0,minHeight:0,display:"flex",flexDirection:"column",borderLeft:E?"1px solid":void 0,borderColor:"border.default",position:"relative",children:[x.errorBanner?t.jsx(f,{flexShrink:0,px:3,py:2,fontSize:1,borderBottom:"1px solid",bg:x.errorBanner.variant==="warning"?"attention.subtle":"danger.subtle",color:x.errorBanner.variant==="warning"?"attention.fg":"danger.fg",borderColor:x.errorBanner.variant==="warning"?"attention.muted":"danger.muted",children:x.errorBanner.message}):null,Te?.said&&Te.given===U?.id?t.jsx(H,{as:"p",role:"status",sx:{m:0,px:3,py:2,fontSize:1,color:"fg.muted"},children:Te.said}):null,t.jsx(f,{flex:"1 1 auto",minHeight:0,display:"flex",children:Xn?t.jsx(H,{as:"p",role:"status",sx:{m:0,p:3,fontSize:1,color:"fg.muted"},children:In.opening}):t.jsx(ws,{themeVariant:p?.themeVariant,themeOverrides:p?.themeOverrides,colorMode:p?.colorMode,thread:an,disabled:nt,disableReason:qt,protocol:Tt,frontendTools:g?void 0:On,initialModel:st||void 0,title:_?.name??y?.name??j?.name??i,description:_?.welcome??j?.description,brandIcon:_?.face?t.jsx(aa,{face:_.face,size:20,state:le}):t.jsx(wt,{size:20}),headerContent:_&&!It?t.jsx(ia,{state:le}):void 0,emptyState:{icon:_?.face?t.jsx("span",{"aria-hidden":!0,style:{fontSize:Rn,lineHeight:1},children:t.jsx($n,{face:_.face,size:Rn})}):t.jsx(wt,{size:48}),title:_?.name??y?.name??j?.name??i,...m&&y?{sections:[{group:m.team.name,icon:t.jsx(Un,{size:48}),title:m.team.name,subtitle:m.team.description},{group:y.name,icon:t.jsx(wt,{size:32}),title:y.name,subtitle:j?.description}]}:null},suggestions:Re||ie||p?.suggestionLabels===!1?[]:et,showHeader:pn,headerButtons:{showNewChat:p?.headerButtons?.newChat??!1,showClear:p?.headerButtons?.clear??!1},renderHeader:Rt?e=>t.jsx(Rt,{workspace:n,header:n.chatViewModes?{...e,chatViewMode:n.chatViewModes.value,onChatViewModeChange:n.chatViewModes.onChange,offeredViewModes:n.chatViewModes.offered}:e}):void 0,showInformation:!0,headerActions:t.jsxs(f,{display:"inline-flex",alignItems:"center",gap:2,children:[n.chatHeaderActions,tn.length>0?t.jsx(ft,{slot:Se.chatHeader,props:{workspace:n}}):null,t.jsx(ks,{icon:$?js:Es,"aria-label":$?"Exit full screen":"Enter full screen",variant:"invisible",size:"small",onClick:()=>{ge(!1),xt()},sx:Le?{"@keyframes dla-fullscreen-hint":{"0%, 100%":{opacity:1},"50%":{opacity:.4}},"&&":{bg:`color-mix(in srgb, ${c.primary} 16%, transparent)`,boxShadow:`inset 0 0 0 1.5px ${c.primary}`,animation:`dla-fullscreen-hint ${da}ms ease-in-out infinite`},"@media (prefers-reduced-motion: reduce)":{"&&":{animation:"none"}}}:void 0})]}),showInput:!1,onSendReady:ye,notebookToolSurfacesId:E?void 0:n.surfaceId,showTurnFooter:x.showTokenUsage??p?.showTokenUsage??!0,onContextSnapshot:Ue,onLoadingChange:Qe,onItemsChange:z,onDisplayItemsChange:de,enableStreaming:!0},an?.id)}),!pn&&tn.length>0?t.jsx(f,{hidden:!0,children:t.jsx(ft,{slot:Se.chatHeader,props:{workspace:n}})}):null,un&&!We?rt:null]})}),bn=p?.suggestionLabels!==!1&&et.length>0?t.jsx(f,{"aria-label":s.suggestedPrompts,display:"flex",flexWrap:"wrap",gap:2,px:2,pb:"6px",children:et.map(e=>t.jsx(f,{as:"button",type:"button",title:e.message,disabled:L||nt,onClick:()=>{pe(e.message)},appearance:"none",font:"inherit",fontSize:0,fontWeight:"semibold",lineHeight:1.25,px:"10px",py:"5px",width:wn,flex:`0 0 ${wn}px`,borderRadius:"999px",border:"1px solid",bg:"canvas.subtle",whiteSpace:"nowrap",sx:{borderColor:"border.default",color:"fg.default",cursor:"pointer","&:hover:not(:disabled)":{borderColor:"accent.fg",color:"accent.fg"},"&:disabled":{opacity:.5,cursor:"default"}},children:t.jsx(Is,{title:e.title,maxWidth:"100%",sx:{minWidth:0},children:e.title})},e.title))}):null,xn=b?t.jsx(f,{flex:"0 0 auto",px:3,py:2,borderTop:"1px solid",borderColor:"border.default",bg:"canvas.subtle",fontSize:1,maxHeight:"40%",overflowY:"auto",children:b}):null;return t.jsxs(f,{ref:me,sx:{height:"100%",minHeight:0,display:"flex",flexDirection:"column",position:"relative",...$?{bg:"canvas.default"}:null,...$&&!bt.current?{position:"fixed",top:St,right:0,bottom:0,left:0,height:"auto",zIndex:1e3}:null},children:[ie?t.jsx(ie.Component,{workspace:n,editors:gn,hasEditor:!!E,transcript:hn,prompt:We?null:rt,chips:We?null:bn,picker:mn,transient:xn}):t.jsxs(t.Fragment,{children:[Re&&!We?t.jsxs(f,{flex:"0 0 auto",borderBottom:"1px solid",borderColor:"border.default",children:[rt,bn]}):null,mn,t.jsxs(f,{flex:"1 1 auto",minHeight:0,display:"flex",position:"relative",children:[gn,hn]}),xn,un||We||Re?null:rt]}),Et?t.jsx(f,{position:"absolute",inset:0,zIndex:5,bg:"canvas.default",display:"flex",flexDirection:"column",minHeight:0,children:t.jsx(Ws,{agentName:y?.name??j?.name,sandboxStillRuns:g,temporary:Yt,onSignedIn:()=>Ts.getState().clear()})}):null]})}function ua({surfaces:n,active:s,onChange:c,workspace:a}){const d=[...n].sort((b,S)=>(b.order??100)-(S.order??100));return t.jsxs(f,{flex:"0 0 auto",display:"flex",alignItems:"center",gap:2,px:3,py:2,borderBottom:"1px solid",borderColor:"border.default",children:[t.jsx(H,{sx:{fontSize:0,color:"fg.muted"},children:"Beside the chat"}),t.jsxs(Ut,{"aria-label":"Editor beside the chat",size:"small",children:[t.jsx(Ut.Button,{selected:s===X,onClick:()=>c(X),children:"Chat"}),d.map(b=>{const S=De(b,a),C=S?void 0:b.unavailableReason?.(a)??"Not available right now";return t.jsx(Ut.Button,{selected:s===b.surfaceId,"aria-disabled":!S,title:C??b.title,leadingIcon:b.icon,onClick:()=>{S&&c(b.surfaceId)},children:b.title},b.surfaceId)})]})]})}function Ft({children:n}){return t.jsx(f,{height:"100%",display:"flex",alignItems:"center",justifyContent:"center",color:"fg.muted",fontSize:1,px:3,textAlign:"center",children:n})}export{ga as default};