@datalayer/agent-runtimes 1.3.94 → 1.3.96

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 (44) hide show
  1. package/dist-embed/chunks/AgentInspector-DaMCROPs.js +1 -0
  2. package/dist-embed/chunks/{AgentInspectorDialog-LBbHMnDa.js → AgentInspectorDialog-zGMiFR5z.js} +1 -1
  3. package/dist-embed/chunks/ChatView-DE-jo1oJ.js +288 -0
  4. package/dist-embed/datalayer-app-main.js +110 -110
  5. package/dist-embed/datalayer-app.js +1 -1
  6. package/lib/apps/__tests__/fixtures/sceneCheckCases.json +352 -0
  7. package/lib/apps/apps/computer.d.ts +25 -1
  8. package/lib/apps/apps/computer.js +45 -2
  9. package/lib/apps/apps/sceneChecks.d.ts +92 -0
  10. package/lib/apps/apps/sceneChecks.js +649 -0
  11. package/lib/apps/apps/sceneShape.d.ts +8 -0
  12. package/lib/apps/apps/sceneShape.js +191 -0
  13. package/lib/apps/apps/sceneYaml.d.ts +64 -0
  14. package/lib/apps/apps/sceneYaml.js +253 -0
  15. package/lib/apps/core/canvasParts.d.ts +28 -0
  16. package/lib/apps/core/canvasParts.js +14 -0
  17. package/lib/apps/core/index.d.ts +1 -0
  18. package/lib/apps/core/index.js +2 -0
  19. package/lib/apps/embed/loader.js +10 -0
  20. package/lib/apps/plugins/agents/SandboxSelector.js +13 -2
  21. package/lib/apps/plugins/agents/host.d.ts +2 -0
  22. package/lib/apps/plugins/agents/host.js +16 -0
  23. package/lib/apps/plugins/agents/plugin.js +10 -2
  24. package/lib/apps/plugins/agents/switchable.d.ts +12 -0
  25. package/lib/apps/plugins/agents/switchable.js +23 -0
  26. package/lib/apps/plugins/app-computer/AppComputer.js +18 -2
  27. package/lib/apps/plugins/canvas-parts/index.d.ts +44 -0
  28. package/lib/apps/plugins/canvas-parts/index.js +209 -0
  29. package/lib/components/teams/useA2ATeam.js +1 -1
  30. package/lib/examples/HomeExample.js +1 -1
  31. package/lib/examples/ScenesExample.d.ts +1 -1
  32. package/lib/examples/example-selector.js +1 -1
  33. package/lib/hooks/useAgUi.js +4 -1
  34. package/lib/protocols/AGUIAdapter.js +5 -1
  35. package/lib/protocols/agUiRefusal.d.ts +47 -0
  36. package/lib/protocols/agUiRefusal.js +87 -0
  37. package/lib/specs/apps.js +32 -24
  38. package/lib/specs/scenes.js +147 -142
  39. package/lib/specs/teams/teams.js +13 -13
  40. package/package.json +3 -1
  41. package/scripts/dist-embed.mjs +116 -0
  42. package/scripts/record-scene-checks.py +600 -0
  43. package/dist-embed/chunks/AgentInspector-DfPciQ79.js +0 -1
  44. package/dist-embed/chunks/ChatView-BzFbN_mp.js +0 -288
@@ -0,0 +1,600 @@
1
+ #!/usr/bin/env python3
2
+ # Copyright (c) 2025-2026 Datalayer, Inc.
3
+ # Distributed under the terms of the Modified BSD License.
4
+
5
+ """Record what ``loop`` refuses of a scene, for every editor of a scene to be held to it.
6
+
7
+ plans/STUDIO.md S-10: one validation over the three — what the spec editor
8
+ refuses, the stage refuses and ``loop`` refuses, in the same words. The
9
+ browser's half is ``src/apps/apps/sceneChecks.ts``; this script
10
+ writes down what agentspecs itself says of the same scenes, and
11
+ ``src/apps/__tests__/scene-checks.test.ts`` holds it to it sentence by
12
+ sentence. Two copies of a rule drift unless something compares them.
13
+
14
+ Each case is a scene as a person writes it, in agentspecs' own spelling, so
15
+ the table also exercises the editor's reader (``sceneOfYaml``).
16
+
17
+ Usage:
18
+ python3 scripts/record-scene-checks.py \
19
+ --agentspecs agentspecs \
20
+ --output src/apps/__tests__/fixtures/sceneCheckCases.json
21
+ """
22
+
23
+ from __future__ import annotations
24
+
25
+ import argparse
26
+ import json
27
+ import sys
28
+ from pathlib import Path
29
+ from typing import Any, Dict, List
30
+
31
+ #: A cast, a setting and a script that parse, as pieces the cases lay over.
32
+ HEAD = """schema: loop.scene/v1
33
+ id: probe
34
+ version: 0.0.1
35
+ name: Probe
36
+ """
37
+
38
+ SALES = """ - member: sales
39
+ app: sales
40
+ role: initiator
41
+ runs_in: runtime
42
+ persona:
43
+ name: Sales
44
+ """
45
+
46
+ BOOKS = """ - member: books
47
+ app: accounting
48
+ role: contributor
49
+ runs_in: runtime
50
+ persona:
51
+ name: Accounting
52
+ """
53
+
54
+ ODOO = """ - member: odoo
55
+ server: odoo-accounting
56
+ persona:
57
+ name: Odoo
58
+ """
59
+
60
+ #: One member reaching one system of the setting, for the tool cases.
61
+ TOOL_SCENE = (
62
+ HEAD
63
+ + "entry: {member}\ncast:\n - member: {member}\n app: {app}\n role: contributor\n"
64
+ + " runs_in: runtime\n persona:\n name: {persona}\n"
65
+ + "setting:\n systems:\n - server: {server}\n as: Odoo\n"
66
+ )
67
+
68
+ #: Each case: its name, and the scene as it is written.
69
+ CASES: List[Dict[str, str]] = [
70
+ {
71
+ "name": "a scene with nobody on stage",
72
+ "yaml": HEAD,
73
+ },
74
+ {
75
+ "name": "the entry is not in the cast",
76
+ "yaml": HEAD + "entry: nobody\ncast:\n" + SALES,
77
+ },
78
+ {
79
+ "name": "the entry is a system",
80
+ "yaml": HEAD + "entry: odoo\ncast:\n" + ODOO,
81
+ },
82
+ {
83
+ "name": "a system asks",
84
+ "yaml": HEAD
85
+ + "entry: sales\ncast:\n"
86
+ + SALES
87
+ + ODOO
88
+ + " talks_to:\n - member: sales\n over: a2a\n",
89
+ },
90
+ {
91
+ "name": "a member talks to itself",
92
+ "yaml": HEAD
93
+ + "entry: sales\ncast:\n"
94
+ + SALES
95
+ + " talks_to:\n - member: sales\n over: a2a\n",
96
+ },
97
+ {
98
+ "name": "a member talks to nobody of the cast",
99
+ "yaml": HEAD
100
+ + "entry: sales\ncast:\n"
101
+ + SALES
102
+ + " talks_to:\n - member: ghost\n over: a2a\n",
103
+ },
104
+ {
105
+ "name": "a system asked over a2a",
106
+ "yaml": HEAD
107
+ + "entry: sales\ncast:\n"
108
+ + SALES
109
+ + " talks_to:\n - member: odoo\n over: a2a\n"
110
+ + ODOO,
111
+ },
112
+ {
113
+ "name": "an agent asked over mcp",
114
+ "yaml": HEAD
115
+ + "entry: sales\ncast:\n"
116
+ + SALES
117
+ + " talks_to:\n - member: books\n over: mcp\n"
118
+ + BOOKS,
119
+ },
120
+ {
121
+ "name": "a member named twice",
122
+ "yaml": HEAD + "entry: sales\ncast:\n" + SALES + SALES,
123
+ },
124
+ {
125
+ "name": "two beats with one name",
126
+ "yaml": HEAD
127
+ + "entry: sales\ncast:\n"
128
+ + SALES
129
+ + """script:
130
+ - id: open
131
+ cue:
132
+ say: Show the books
133
+ expect: The books are read
134
+ moves:
135
+ - who: sales
136
+ answers: words
137
+ - id: open
138
+ cue:
139
+ say: Show them again
140
+ expect: The books are read again
141
+ moves:
142
+ - who: sales
143
+ answers: words
144
+ """,
145
+ },
146
+ {
147
+ "name": "a member placed outside the box",
148
+ "yaml": HEAD
149
+ + "entry: sales\ncast:\n"
150
+ + SALES
151
+ + "stage:\n positions:\n sales:\n x: 40\n y: 0.5\n",
152
+ },
153
+ {
154
+ "name": "a member that is nothing at all",
155
+ "yaml": HEAD + "entry: sales\ncast:\n" + SALES + " - member: ghost\n",
156
+ },
157
+ {
158
+ "name": "the scene wears a member's face",
159
+ "yaml": HEAD
160
+ + "emoji: \U0001f9ee\nentry: sales\ncast:\n"
161
+ + SALES
162
+ + " face: \U0001f9ee\n",
163
+ },
164
+ {
165
+ "name": "a system of the setting that is no server",
166
+ "yaml": HEAD
167
+ + "entry: sales\ncast:\n"
168
+ + SALES
169
+ + "setting:\n systems:\n - server: nosuch\n as: Nope\n",
170
+ },
171
+ {
172
+ "name": "a system nobody reaches",
173
+ "yaml": HEAD
174
+ + "entry: sales\ncast:\n"
175
+ + SALES
176
+ + "setting:\n systems:\n - server: odoo-accounting\n as: Odoo\n",
177
+ },
178
+ {
179
+ "name": "a system reached through a connection",
180
+ "yaml": HEAD
181
+ + "entry: books\ncast:\n"
182
+ + BOOKS
183
+ + "setting:\n systems:\n - server: odoo-accounting\n as: Odoo\n",
184
+ },
185
+ {
186
+ "name": "a Frame the catalogue has not",
187
+ "yaml": HEAD + "entry: sales\ncast:\n" + SALES + "setting:\n frames:\n - nosuch\n",
188
+ },
189
+ {
190
+ "name": "the stage places someone not in the cast",
191
+ "yaml": HEAD
192
+ + "entry: sales\ncast:\n"
193
+ + SALES
194
+ + "stage:\n positions:\n ghost:\n x: 0.2\n y: 0.4\n",
195
+ },
196
+ {
197
+ "name": "a balloon opens first for someone not in the cast",
198
+ "yaml": HEAD + "entry: sales\ncast:\n" + SALES + "stage:\n opens_first: ghost\n",
199
+ },
200
+ {
201
+ "name": "an address for someone not in the cast",
202
+ "yaml": HEAD
203
+ + "entry: sales\ncast:\n"
204
+ + SALES
205
+ + "deployment:\n addresses:\n ghost: GHOST_URL\n",
206
+ },
207
+ {
208
+ "name": "an address for a member in the browser",
209
+ "yaml": HEAD
210
+ + "entry: sales\ncast:\n"
211
+ + SALES.replace("runs_in: runtime", "runs_in: browser")
212
+ + "deployment:\n addresses:\n sales: SALES_URL\n",
213
+ },
214
+ {
215
+ "name": "visitors may watch and a member has no address",
216
+ "yaml": HEAD + "entry: sales\ncast:\n" + SALES + "audience:\n who: visitors\n",
217
+ },
218
+ {
219
+ "name": "a beat its entry does not answer",
220
+ "yaml": HEAD
221
+ + "entry: sales\ncast:\n"
222
+ + SALES
223
+ + BOOKS
224
+ + """script:
225
+ - id: open
226
+ cue:
227
+ say: Show the books
228
+ expect: The books are read
229
+ moves:
230
+ - who: books
231
+ answers: table
232
+ """,
233
+ },
234
+ {
235
+ "name": "a beat moved by someone not in the cast",
236
+ "yaml": HEAD
237
+ + "entry: sales\ncast:\n"
238
+ + SALES
239
+ + """script:
240
+ - id: open
241
+ cue:
242
+ say: Show the books
243
+ expect: The books are read
244
+ moves:
245
+ - who: sales
246
+ answers: words
247
+ - who: ghost
248
+ answers: words
249
+ """,
250
+ },
251
+ {
252
+ "name": "a beat moved by a system",
253
+ "yaml": HEAD
254
+ + "entry: sales\ncast:\n"
255
+ + SALES
256
+ + ODOO
257
+ + """script:
258
+ - id: open
259
+ cue:
260
+ say: Show the books
261
+ expect: The books are read
262
+ moves:
263
+ - who: sales
264
+ answers: words
265
+ - who: odoo
266
+ answers: words
267
+ """,
268
+ },
269
+ {
270
+ "name": "a move that asks someone not in the cast",
271
+ "yaml": HEAD
272
+ + "entry: sales\ncast:\n"
273
+ + SALES
274
+ + """script:
275
+ - id: open
276
+ cue:
277
+ say: Show the books
278
+ expect: The books are read
279
+ moves:
280
+ - who: sales
281
+ asks: ghost
282
+ over: a2a
283
+ what: the books
284
+ """,
285
+ },
286
+ {
287
+ "name": "a move over mcp that asks no system",
288
+ "yaml": HEAD
289
+ + "entry: sales\ncast:\n"
290
+ + SALES
291
+ + BOOKS
292
+ + """script:
293
+ - id: open
294
+ cue:
295
+ say: Show the books
296
+ expect: The books are read
297
+ moves:
298
+ - who: sales
299
+ asks: books
300
+ over: mcp
301
+ what: the books
302
+ """,
303
+ },
304
+ {
305
+ "name": "a move over a2a that asks a system",
306
+ "yaml": HEAD
307
+ + "entry: sales\ncast:\n"
308
+ + SALES
309
+ + ODOO
310
+ + """script:
311
+ - id: open
312
+ cue:
313
+ say: Show the books
314
+ expect: The books are read
315
+ moves:
316
+ - who: sales
317
+ asks: odoo
318
+ over: a2a
319
+ what: the books
320
+ """,
321
+ },
322
+ {
323
+ "name": "a move that asks a member it does not talk to",
324
+ "yaml": HEAD
325
+ + "entry: sales\ncast:\n"
326
+ + SALES
327
+ + BOOKS
328
+ + """script:
329
+ - id: open
330
+ cue:
331
+ say: Show the books
332
+ expect: The books are read
333
+ moves:
334
+ - who: sales
335
+ asks: books
336
+ over: a2a
337
+ what: the books
338
+ """,
339
+ },
340
+ {
341
+ "name": "a branch that goes on to no beat",
342
+ "yaml": HEAD
343
+ + "entry: sales\ncast:\n"
344
+ + SALES
345
+ + """script:
346
+ - id: open
347
+ cue:
348
+ say: Show the books
349
+ expect: The books are read
350
+ moves:
351
+ - who: sales
352
+ answers: words
353
+ branch:
354
+ - decision: there is nothing to read
355
+ expect: it says so
356
+ then: nowhere
357
+ """,
358
+ },
359
+ {
360
+ "name": "a rehearsal of a beat that is not in the script",
361
+ "yaml": HEAD
362
+ + "entry: sales\ncast:\n"
363
+ + SALES
364
+ + """rehearsal:
365
+ beats:
366
+ - beat: nowhere
367
+ lines:
368
+ - 'You → Sales'
369
+ """,
370
+ },
371
+ {
372
+ "name": "a rehearsal that names a beat twice",
373
+ "yaml": HEAD
374
+ + "entry: sales\ncast:\n"
375
+ + SALES
376
+ + """script:
377
+ - id: open
378
+ cue:
379
+ say: Show the books
380
+ expect: The books are read
381
+ moves:
382
+ - who: sales
383
+ answers: words
384
+ rehearsal:
385
+ beats:
386
+ - beat: open
387
+ lines:
388
+ - 'You → Sales'
389
+ - beat: open
390
+ lines:
391
+ - 'Sales: a table'
392
+ """,
393
+ },
394
+ {
395
+ "name": "a rehearsal that names someone not on stage",
396
+ "yaml": HEAD
397
+ + "entry: sales\ncast:\n"
398
+ + SALES
399
+ + """script:
400
+ - id: open
401
+ cue:
402
+ say: Show the books
403
+ expect: The books are read
404
+ moves:
405
+ - who: sales
406
+ answers: words
407
+ rehearsal:
408
+ beats:
409
+ - beat: open
410
+ lines:
411
+ - 'You → Stranger'
412
+ """,
413
+ },
414
+ {
415
+ "name": "a scene that plays",
416
+ "yaml": HEAD
417
+ + "entry: sales\ncast:\n"
418
+ + SALES
419
+ + " talks_to:\n - member: books\n over: a2a\n"
420
+ + BOOKS
421
+ + """setting:
422
+ systems:
423
+ - server: odoo-accounting
424
+ as: Odoo
425
+ holds: Datalayer's books
426
+ stage:
427
+ positions:
428
+ sales:
429
+ x: 0
430
+ y: 0
431
+ books:
432
+ x: 0.5
433
+ y: 0
434
+ opens_first: sales
435
+ script:
436
+ - id: open
437
+ cue:
438
+ say: Show the books
439
+ expect: The books are read
440
+ moves:
441
+ - who: sales
442
+ asks: books
443
+ over: a2a
444
+ what: the open invoices
445
+ - who: sales
446
+ answers: table
447
+ rehearsal:
448
+ beats:
449
+ - beat: open
450
+ lines:
451
+ - 'You → Sales'
452
+ - 'Sales → Accounting'
453
+ - 'Sales: a table'
454
+ """,
455
+ },
456
+ # --- a cast under a team of the catalogue: personas and briefs only ---
457
+ # The team says who its members are; a scene that names it says how each
458
+ # is played, and nothing of what each is (`scene_problems`).
459
+ {
460
+ "name": "a scene of a team that plays",
461
+ "yaml": HEAD + "team: sales-and-accounting\ncast:\n - member: sales\n persona:\n name: Sales\n brief: Ask for the open invoices.\n",
462
+ },
463
+ {
464
+ "name": "a cast under a team names someone not in it",
465
+ "yaml": HEAD + "team: sales-and-accounting\ncast:\n - member: ghost\n persona:\n name: Ghost\n",
466
+ },
467
+ {
468
+ "name": "a cast under a team says what a member is",
469
+ "yaml": HEAD + "team: sales-and-accounting\ncast:\n - member: sales\n app: sales\n persona:\n name: Sales\n",
470
+ },
471
+ # --- a tool a system is asked for: offered, offered for this, reached ---
472
+ # What agentspecs reads of the catalogue's servers and connections
473
+ # (`_tool_problem`): on a move of the script, and on a rehearsal's line.
474
+ {
475
+ "name": "a move asks a system for a tool it does not offer",
476
+ "yaml": TOOL_SCENE.format(member="books", app="accounting", persona="Accounting", server="odoo-accounting")
477
+ + "script:\n - id: open\n cue:\n say: Show the books\n expect: It is answered\n moves:\n"
478
+ + " - who: books\n asks: odoo-accounting\n over: mcp\n tool: odoo_accounting_burn_the_books\n",
479
+ },
480
+ {
481
+ "name": "a move asks for a tool to do what it does not",
482
+ "yaml": TOOL_SCENE.format(member="crop", app="crop-monitoring", persona="Crop", server="earthdata")
483
+ + "script:\n - id: look\n cue:\n say: What is there\n expect: It is answered\n moves:\n"
484
+ + " - who: crop\n asks: earthdata\n over: mcp\n tool: download_earth_data_granules\n does: read\n",
485
+ },
486
+ {
487
+ "name": "a move asks for a tool no connection of the member offers",
488
+ "yaml": TOOL_SCENE.format(member="inbox", app="inbox-triage", persona="Inbox", server="google-workspace")
489
+ + "script:\n - id: mail\n cue:\n say: What came in\n expect: It is answered\n moves:\n"
490
+ + " - who: inbox\n asks: google-workspace\n over: mcp\n tool: list_calendar_events\n",
491
+ },
492
+ {
493
+ "name": "a rehearsal expects a tool a system does not offer",
494
+ "yaml": TOOL_SCENE.format(member="books", app="accounting", persona="Accounting", server="odoo-accounting")
495
+ + "script:\n - id: open\n cue:\n say: Show the books\n expect: It is answered\n moves:\n"
496
+ + " - who: books\n answers: table\n"
497
+ + "rehearsal:\n beats:\n - beat: open\n lines:\n"
498
+ + " - 'Accounting → Odoo: odoo_accounting_burn_the_books'\n"
499
+ + " - 'Accounting: a table'\n",
500
+ },
501
+ # --- the shape of a scene: what pydantic refuses before any rule is read ---
502
+ # Each mistyped once, as a person typing a scene by hand does. agentspecs
503
+ # reports every issue pydantic finds, joined by "; ", and its after
504
+ # validators never run on a scene of the wrong shape.
505
+ {
506
+ "name": "a cast that is a word",
507
+ "yaml": HEAD + "entry: sales\ncast: sales\n",
508
+ },
509
+ {
510
+ "name": "a name that is a number",
511
+ "yaml": HEAD.replace("name: Probe", "name: 123") + "entry: sales\ncast:\n" + SALES,
512
+ },
513
+ {
514
+ "name": "a scene with no name",
515
+ "yaml": HEAD.replace("name: Probe\n", "") + "entry: sales\ncast:\n" + SALES,
516
+ },
517
+ {
518
+ "name": "a field the spec does not have",
519
+ "yaml": HEAD + "colour: red\nentry: sales\ncast:\n" + SALES,
520
+ },
521
+ {
522
+ "name": "a member with a field it does not have",
523
+ "yaml": HEAD + "entry: sales\ncast:\n" + SALES + " mood: happy\n",
524
+ },
525
+ {
526
+ "name": "a member running nowhere",
527
+ "yaml": HEAD + "entry: sales\ncast:\n" + SALES.replace("runs_in: runtime", "runs_in: nowhere"),
528
+ },
529
+ {
530
+ "name": "a member's role nobody plays",
531
+ "yaml": HEAD + "entry: sales\ncast:\n" + SALES.replace("role: initiator", "role: boss"),
532
+ },
533
+ {
534
+ "name": "an audience that is a word",
535
+ "yaml": HEAD + "entry: sales\ncast:\n" + SALES + "audience: everyone\n",
536
+ },
537
+ {
538
+ "name": "an audience nobody can be",
539
+ "yaml": HEAD + "entry: sales\ncast:\n" + SALES + "audience:\n who: nobody-at-all\n",
540
+ },
541
+ {
542
+ "name": "a ceiling below nothing",
543
+ "yaml": HEAD + "entry: sales\ncast:\n" + SALES + "audience:\n ceiling_per_ask: -1\n",
544
+ },
545
+ {
546
+ "name": "a ceiling that is no number",
547
+ "yaml": HEAD + "entry: sales\ncast:\n" + SALES + "audience:\n ceiling_per_ask: lots\n",
548
+ },
549
+ {
550
+ "name": "a rehearsal bound that is no duration",
551
+ "yaml": HEAD + "entry: sales\ncast:\n" + SALES + "rehearsal:\n within: soon\n",
552
+ },
553
+ {
554
+ "name": "a stage that is a list",
555
+ "yaml": HEAD + "entry: sales\ncast:\n" + SALES + "stage: []\n",
556
+ },
557
+ {
558
+ "name": "places that are a word",
559
+ "yaml": HEAD + "entry: sales\ncast:\n" + SALES + "stage:\n positions: everywhere\n",
560
+ },
561
+ {
562
+ "name": "two things wrong at once",
563
+ "yaml": HEAD + "entry: sales\ncast: sales\nrehearsal:\n within: soon\n",
564
+ },
565
+ ]
566
+
567
+
568
+ def main() -> int:
569
+ parser = argparse.ArgumentParser(description=__doc__)
570
+ parser.add_argument("--agentspecs", type=Path, required=True, help="The agentspecs clone to read the checks from")
571
+ parser.add_argument("--output", type=Path, required=True, help="The JSON table the browser's checks are held to")
572
+ args = parser.parse_args()
573
+
574
+ sys.path.insert(0, str(args.agentspecs.resolve()))
575
+ import yaml # noqa: PLC0415
576
+ from agentspecs.scenes import SceneError, parse_scene, scene_problems # noqa: PLC0415
577
+
578
+ recorded: List[Dict[str, Any]] = []
579
+ for case in CASES:
580
+ data = yaml.safe_load(case["yaml"])
581
+ try:
582
+ scene = parse_scene(data)
583
+ except SceneError as error:
584
+ says = [str(error)]
585
+ else:
586
+ says = scene_problems(scene)
587
+ recorded.append({"name": case["name"], "yaml": case["yaml"], "says": says})
588
+
589
+ table = {
590
+ "says": "What `loop` refuses of a scene, recorded from agentspecs (plans/STUDIO.md S-10).",
591
+ "recordedWith": "scripts/record-scene-checks.py",
592
+ "cases": recorded,
593
+ }
594
+ args.output.write_text(json.dumps(table, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
595
+ print(f"{len(recorded)} cases written to {args.output}")
596
+ return 0
597
+
598
+
599
+ if __name__ == "__main__":
600
+ raise SystemExit(main())
@@ -1 +0,0 @@
1
- import{r as f,j as e,bp as l,cP as re,eI as ie,T as c,bm as W,cO as F,L as D,I as oe,eJ as le,eK as V,c as U,P as ae,eL as de,k as ce,eM as ue,dw as H,bd as M,eN as xe,eO as fe,eP as K,eQ as pe,eR as he}from"../datalayer-app-main.js";import{B as $,U as B}from"./index-Begrz6qi.js";function E(t){const n=Number(t);return!isNaN(n)&&n>1e15?n/1e6:!isNaN(n)&&n>1e12?n/1e3:isNaN(n)?new Date(String(t)).getTime():n}function J(t){return t==null?"—":t<.001?"<1µs":t<1?`${(t*1e3).toFixed(0)}µs`:t<1e3?`${t.toFixed(1)}ms`:t<6e4?`${(t/1e3).toFixed(2)}s`:`${(t/6e4).toFixed(1)}m`}function me(t){if(t==null||t==="")return"—";try{const n=E(t),s=new Date(n);return isNaN(s.getTime())?String(t):s.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",second:"2-digit",fractionalSecondDigits:3})}catch{return String(t)}}const X=["#0969da","#1a7f37","#cf222e","#8250df","#bf8700","#0550ae","#116329","#a40e26","#6639ba","#953800","#0e8a16","#e36209"];function ge(t){let n=0;for(let s=0;s<t.length;s++)n=n*31+t.charCodeAt(s)|0;return X[Math.abs(n)%X.length]}function Q(t){const n=new Map,s=t.map(o=>({...o,children:[],depth:0}));for(const o of s)n.set(o.span_id,o);const r=[];for(const o of s)if(o.parent_span_id&&n.has(o.parent_span_id)){const x=n.get(o.parent_span_id);x.children=x.children??[],x.children.push(o)}else r.push(o);function a(o,x){o.depth=x;for(const p of o.children??[])a(p,x+1)}for(const o of r)a(o,0);return r}const be="peer.service";function je(t,n){return t.service_name===n||t.attributes?.[be]===n}function Se(t,n){return n?t.filter(s=>je(s,n)):[...t]}const Y=[],_e=()=>()=>{};function we(t){return f.useSyncExternalStore(t?t.subscribe:_e,()=>t?t.spans():Y,()=>t?t.spans():Y)}const ye="140px 1fr 160px 90px",ve="96px minmax(0, 1fr) 96px 64px";function ke(t){const n=t.attributes;if(!n)return null;const s=n["gen_ai.usage.input_tokens"]!=null?Number(n["gen_ai.usage.input_tokens"]):void 0,r=n["gen_ai.usage.output_tokens"]!=null?Number(n["gen_ai.usage.output_tokens"]):void 0;return s==null&&r==null?null:{input:s,output:r}}const Ce=({spans:t,loading:n,selectedSpanId:s,onSelectSpan:r,emptyText:a,compact:o=!1,defaultExpanded:x=!1,renderSpanMark:p,describeSpan:u})=>{const[h,d]=f.useState(new Set),m=f.useMemo(()=>({has:i=>x?!h.has(i):h.has(i)}),[h,x]),j=o?ve:ye,S=f.useMemo(()=>Q(t),[t]),g=f.useMemo(()=>{const i=[];function y(b,A){const v=b.children??[];if(i.push({span:b,depth:A,hasChildren:v.length>0}),m.has(b.span_id))for(const T of v)y(T,A+1)}for(const b of S)y(b,0);return i},[S,m]),O=f.useCallback(i=>{d(y=>{const b=new Set(y);return b.has(i)?b.delete(i):b.add(i),b})},[]);return n?e.jsx(l,{sx:{display:"flex",justifyContent:"center",p:5},children:e.jsx(re,{size:"medium"})}):t.length===0?e.jsxs($,{children:[e.jsx($.Visual,{children:e.jsx(ie,{size:24})}),e.jsx($.Heading,{children:"No traces found"}),e.jsx($.Description,{children:a??"Send some telemetry data first."})]}):e.jsxs(l,{sx:{width:"100%",flex:1,minHeight:0,overflow:"auto"},children:[e.jsx(l,{sx:{display:"grid",gridTemplateColumns:j,gap:2,px:3,position:"sticky",top:0,bg:"canvas.subtle",zIndex:1,borderBottom:"2px solid",borderColor:"border.default"},children:["Time","Message","Scope","Duration"].map(i=>e.jsx(c,{sx:{fontWeight:"bold",fontSize:0,color:"fg.muted",textTransform:"uppercase",letterSpacing:"0.05em",py:2,...i==="Duration"?{textAlign:"right"}:{}},children:i},i))}),g.map(({span:i,depth:y,hasChildren:b},A)=>{const v=s===i.span_id,T=m.has(i.span_id),C=y*(o?12:20),k=u?.(i);return e.jsxs(l,{"data-otel-span":i.span_id,"data-otel-span-name":i.span_name,onClick:()=>{b&&O(i.span_id),r?.(i)},sx:{display:"grid",gridTemplateColumns:j,gap:2,px:3,py:"5px",cursor:"pointer",bg:v?"accent.subtle":y>0?"canvas.inset":"canvas.default",borderBottom:"1px solid",borderColor:"border.muted",":hover":{bg:v?"accent.subtle":"canvas.subtle"}},children:[e.jsx(c,{sx:{fontSize:o?0:1,fontFamily:"mono",color:"fg.muted",whiteSpace:"nowrap",lineHeight:"22px"},children:me(i.start_time)}),e.jsxs(l,{sx:{display:"flex",alignItems:"center",gap:1,overflow:"hidden",lineHeight:"22px",pl:`${C}px`},children:[b?e.jsx(l,{sx:{flexShrink:0,color:"fg.muted",display:"flex",alignItems:"center"},children:T?e.jsx(W,{size:14}):e.jsx(F,{size:14})}):y>0?e.jsx(l,{sx:{flexShrink:0,width:"14px",display:"flex",alignItems:"center",justifyContent:"center",color:"fg.subtle",fontSize:0},children:"─"}):null,p?.(i),e.jsx(c,{sx:{fontSize:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",flexShrink:k?0:1,maxWidth:k?"60%":void 0},title:i.span_name,children:i.span_name}),i.in_progress&&e.jsx(D,{variant:"attention",size:"small",children:"running"}),i.status_code==="ERROR"&&e.jsx(D,{variant:"danger",size:"small",children:"ERROR"}),(()=>{const I=ke(i);return I?e.jsxs(l,{sx:{display:"inline-flex",alignItems:"center",gap:"2px",border:"1px solid",borderColor:"border.default",borderRadius:2,px:1,fontSize:"10px",fontFamily:"mono",color:"fg.muted",flexShrink:0,lineHeight:"16px"},children:[I.input!=null&&e.jsxs(l,{sx:{display:"inline-flex",alignItems:"center",gap:"1px"},children:[e.jsx(c,{sx:{fontSize:"9px",color:"fg.subtle"},children:"↗"}),e.jsx(c,{children:I.input})]}),I.output!=null&&e.jsxs(l,{sx:{display:"inline-flex",alignItems:"center",gap:"1px"},children:[e.jsx(c,{sx:{fontSize:"9px",color:"fg.subtle"},children:"↙"}),e.jsx(c,{children:I.output})]})]}):null})(),k&&e.jsx(c,{sx:{fontSize:1,color:"fg.muted",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",minWidth:0},title:k,"data-otel-span-description":"",children:k}),i.otel_scope_name&&!o&&e.jsx(D,{size:"small",variant:"secondary",sx:{flexShrink:0,fontSize:"10px"},children:i.otel_scope_name})]}),e.jsx(c,{sx:{fontSize:1,color:"fg.muted",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",lineHeight:"22px"},title:`${i.service_name} / ${i.otel_scope_name??""}`,children:i.service_name}),e.jsx(c,{sx:{fontSize:1,fontFamily:"mono",textAlign:"right",lineHeight:"22px",color:i.duration_ms!=null&&i.duration_ms>1e3?"danger.fg":"fg.default"},children:i.in_progress?"…":J(i.duration_ms)})]},`${i.trace_id}-${i.span_id}-${A}`)})]})},ze=20,Z=({span:t,depth:n,selectedSpanId:s,onSelectSpan:r,expandedIds:a,toggleExpanded:o,traceMinTime:x,traceDuration:p})=>{const u=(t.children?.length??0)>0,h=a.has(t.span_id),d=s===t.span_id,m=ge(t.service_name),j=(E(t.start_time)-x)/p*100,S=Math.max((t.duration_ms||0)/p*100,.5);return e.jsxs(e.Fragment,{children:[e.jsxs(l,{sx:{display:"flex",alignItems:"center",height:28,pl:`${n*ze}px`,pr:2,cursor:"pointer",bg:d?"accent.subtle":"canvas.default",borderBottom:"1px solid",borderColor:"border.muted",":hover":{bg:d?"accent.subtle":"canvas.subtle"}},onClick:()=>r?.(t),children:[e.jsx(l,{sx:{width:20,textAlign:"center",color:"fg.muted",userSelect:"none",flexShrink:0,cursor:u?"pointer":"default"},onClick:g=>{g.stopPropagation(),u&&o(t.span_id)},children:u?h?e.jsx(W,{size:12}):e.jsx(F,{size:12}):e.jsx(c,{sx:{color:"fg.subtle",fontSize:0},children:"·"})}),e.jsx(l,{sx:{width:8,height:8,borderRadius:"50%",bg:m,flexShrink:0,mr:1}}),e.jsx(c,{sx:{flex:"0 0 200px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",fontSize:1,fontWeight:d?"bold":"normal"},title:`${t.service_name} / ${t.span_name}`,children:t.span_name}),e.jsx(l,{sx:{flex:1,position:"relative",height:12,bg:"canvas.subtle",borderRadius:1,mx:2,overflow:"hidden"},children:e.jsx(l,{sx:{position:"absolute",left:`${j}%`,width:`${S}%`,height:"100%",bg:m,borderRadius:1,opacity:d?1:.7}})}),e.jsx(c,{sx:{minWidth:60,textAlign:"right",fontSize:0,fontFamily:"mono",color:"fg.muted",flexShrink:0},children:J(t.duration_ms)})]}),u&&h&&t.children.map(g=>e.jsx(Z,{span:g,depth:n+1,selectedSpanId:s,onSelectSpan:r,expandedIds:a,toggleExpanded:o,traceMinTime:x,traceDuration:p},g.span_id))]})},Ie=({spans:t,selectedSpanId:n,onSelectSpan:s,defaultExpandDepth:r=2})=>{const a=f.useMemo(()=>{const d=new Set;function m(j,S){for(const g of j)S<r&&d.add(g.span_id),g.children&&m(g.children,S+1)}return m(t,0),d},[t,r]),[o,x]=f.useState(a),p=f.useCallback(d=>{x(m=>{const j=new Set(m);return j.has(d)?j.delete(d):j.add(d),j})},[]),{traceMinTime:u,traceDuration:h}=f.useMemo(()=>{let d=1/0,m=-1/0;function j(S){for(const g of S){const O=E(g.start_time),i=E(g.end_time);O<d&&(d=O),i>m&&(m=i),g.children&&j(g.children)}}return j(t),d===1/0?{traceMinTime:0,traceDuration:1}:{traceMinTime:d,traceDuration:m-d||1}},[t]);return t.length===0?e.jsx(l,{sx:{p:3,color:"fg.muted",textAlign:"center"},children:e.jsx(c,{children:"No span tree to display."})}):e.jsxs(l,{sx:{width:"100%",overflow:"auto"},children:[e.jsxs(l,{sx:{display:"flex",alignItems:"center",height:28,px:2,borderBottom:"2px solid",borderColor:"border.default",bg:"canvas.subtle"},children:[e.jsx(l,{sx:{width:20}}),e.jsx(l,{sx:{width:8,mr:1}}),e.jsx(c,{sx:{flex:"0 0 200px",fontSize:0,fontWeight:"bold",color:"fg.muted",textTransform:"uppercase",letterSpacing:"0.05em"},children:"Span"}),e.jsx(c,{sx:{flex:1,mx:2,fontSize:0,fontWeight:"bold",color:"fg.muted",textTransform:"uppercase",letterSpacing:"0.05em"},children:"Timeline"}),e.jsx(c,{sx:{minWidth:60,textAlign:"right",fontSize:0,fontWeight:"bold",color:"fg.muted",textTransform:"uppercase",letterSpacing:"0.05em"},children:"Duration"})]}),t.map(d=>e.jsx(Z,{span:d,depth:0,selectedSpanId:n,onSelectSpan:s,expandedIds:o,toggleExpanded:p,traceMinTime:u,traceDuration:h},d.span_id))]})},w=({label:t,value:n,mono:s=!1})=>n==null||n===""?null:e.jsxs(l,{sx:{display:"flex",py:1,borderBottom:"1px solid",borderColor:"border.muted",gap:2},children:[e.jsx(c,{sx:{width:140,minWidth:140,color:"fg.muted",fontSize:1,fontWeight:"bold"},children:t}),e.jsx(c,{sx:{fontSize:1,fontFamily:s?"mono":"normal",wordBreak:"break-all"},children:String(n)})]}),q=({title:t,data:n,defaultOpen:s=!1})=>{const[r,a]=f.useState(s);return!n||Object.keys(n).length===0?null:e.jsxs(l,{sx:{mt:3},children:[e.jsxs(l,{sx:{display:"flex",alignItems:"center",gap:1,cursor:"pointer",py:1,userSelect:"none"},onClick:()=>a(!r),children:[r?e.jsx(W,{size:16}):e.jsx(F,{size:16}),e.jsx(c,{sx:{fontSize:1,fontWeight:"bold"},children:t}),e.jsx(V,{children:Object.keys(n).length})]}),r&&e.jsx(l,{sx:{bg:"canvas.subtle",borderRadius:2,border:"1px solid",borderColor:"border.default",p:2,mt:1,overflowX:"auto"},children:Object.entries(n).map(([o,x])=>e.jsx(L,{attrKey:o,value:x,depth:0},o))})]})};function Te(t){if(typeof t!="string")return t;const n=t.trim();if(!/^[[{]/.test(n))return t;try{const s=JSON.parse(n);return typeof s=="object"&&s!==null?s:t}catch{return t}}const L=({attrKey:t,value:n,depth:s})=>{const r=f.useMemo(()=>Te(n),[n]),[a,o]=f.useState(s<1),x=typeof r=="object"&&r!==null&&!Array.isArray(r),p=Array.isArray(r),u=x||p;return e.jsxs(l,{sx:{borderBottom:s===0?"1px solid":"none",borderColor:"border.muted",pb:s===0?1:0,mb:s===0?1:0},children:[e.jsxs(l,{sx:{display:"flex",gap:2,py:1,pl:s*16+"px",alignItems:"flex-start"},children:[u?e.jsx(l,{sx:{cursor:"pointer",color:"fg.muted",userSelect:"none",width:16,flexShrink:0},onClick:()=>o(!a),children:a?e.jsx(W,{size:12}):e.jsx(F,{size:12})}):e.jsx(l,{sx:{width:16,flexShrink:0}}),e.jsx(c,{sx:{color:"accent.fg",fontSize:1,fontFamily:"mono",minWidth:180,wordBreak:"break-all",flexShrink:0},children:t}),!u&&e.jsx(c,{sx:{fontSize:1,fontFamily:"mono",whiteSpace:"pre-wrap",wordBreak:"break-word",color:typeof r=="string"?"accent.emphasis":"attention.fg"},children:typeof r=="string"?r:JSON.stringify(r)}),u&&!a&&e.jsx(c,{sx:{fontSize:0,color:"fg.muted",fontFamily:"mono"},children:p?`[${r.length} items]`:`{${Object.keys(r).length} keys}`})]}),u&&a&&e.jsx(l,{children:p?r.map((h,d)=>e.jsx(L,{attrKey:`[${d}]`,value:h,depth:s+1},d)):Object.entries(r).map(([h,d])=>e.jsx(L,{attrKey:h,value:d,depth:s+1},h))})]})},Oe=({span:t,traceSpans:n,onClose:s})=>{const[r,a]=f.useState("details");if(!t)return e.jsx(l,{sx:{p:5,color:"fg.muted",textAlign:"center"},children:e.jsx(c,{children:"Select a span to view details."})});const o={},x={};if(t.attributes)for(const[u,h]of Object.entries(t.attributes))u.startsWith("gen_ai.")||u.startsWith("model_request")?o[u]=h:x[u]=h;const p=n&&n.length>0?Q(n):void 0;return e.jsxs(l,{sx:{height:"100%",overflow:"auto",borderLeft:"1px solid",borderColor:"border.default",bg:"canvas.default",display:"flex",flexDirection:"column"},children:[e.jsxs(l,{sx:{px:3,py:2,borderBottom:"1px solid",borderColor:"border.default",display:"flex",justifyContent:"space-between",alignItems:"center",bg:"canvas.subtle",flexShrink:0},children:[e.jsx(c,{sx:{fontSize:2,fontWeight:"bold"},children:t.span_name}),s&&e.jsx(oe,{icon:le,"aria-label":"Close detail panel",variant:"invisible",size:"small",onClick:s})]}),e.jsxs(B,{"aria-label":"Span detail tabs",children:[e.jsx(B.Item,{"aria-current":r==="details"?"page":void 0,onClick:()=>a("details"),children:"Details"}),p&&e.jsx(B.Item,{"aria-current":r==="tree"?"page":void 0,onClick:()=>a("tree"),children:"Trace Tree"}),e.jsx(B.Item,{"aria-current":r==="raw"?"page":void 0,onClick:()=>a("raw"),children:"Raw Data"})]}),e.jsxs(l,{sx:{flex:1,overflow:"auto"},children:[r==="details"&&e.jsxs(l,{sx:{p:3},children:[e.jsx(w,{label:"span_name",value:t.span_name}),e.jsx(w,{label:"service_name",value:t.service_name}),e.jsx(w,{label:"otel_scope_name",value:t.otel_scope_name}),e.jsx(w,{label:"kind",value:t.kind}),e.jsx(w,{label:"trace_id",value:t.trace_id,mono:!0}),e.jsx(w,{label:"span_id",value:t.span_id,mono:!0}),e.jsx(w,{label:"parent_span_id",value:t.parent_span_id,mono:!0}),e.jsx(w,{label:"duration",value:J(t.duration_ms)}),e.jsx(w,{label:"start_time",value:t.start_time,mono:!0}),e.jsx(w,{label:"end_time",value:t.end_time,mono:!0}),e.jsx(w,{label:"status_code",value:t.status_code}),e.jsx(w,{label:"status_message",value:t.status_message}),e.jsx(q,{title:"Arguments",data:o,defaultOpen:Object.keys(o).length>0}),e.jsx(q,{title:"Attributes",data:x}),t.events&&t.events.length>0&&e.jsxs(l,{sx:{mt:3},children:[e.jsxs(l,{sx:{display:"flex",alignItems:"center",gap:1},children:[e.jsx(c,{sx:{fontWeight:"bold",fontSize:1},children:"Events"}),e.jsx(V,{children:t.events.length})]}),t.events.map((u,h)=>e.jsxs(l,{sx:{bg:"canvas.subtle",borderRadius:2,border:"1px solid",borderColor:"border.default",p:2,mt:2},children:[e.jsxs(l,{sx:{display:"flex",gap:2},children:[e.jsx(D,{children:u.name}),e.jsx(c,{sx:{fontSize:0,color:"fg.muted",fontFamily:"mono"},children:u.timestamp})]}),u.attributes&&Object.keys(u.attributes).length>0&&e.jsx(l,{sx:{mt:1},children:Object.entries(u.attributes).map(([d,m])=>e.jsx(L,{attrKey:d,value:m,depth:0},d))})]},h))]}),t.links&&t.links.length>0&&e.jsxs(l,{sx:{mt:3},children:[e.jsxs(l,{sx:{display:"flex",alignItems:"center",gap:1},children:[e.jsx(c,{sx:{fontWeight:"bold",fontSize:1},children:"Links"}),e.jsx(V,{children:t.links.length})]}),t.links.map((u,h)=>e.jsxs(c,{sx:{display:"block",fontSize:1,fontFamily:"mono",py:1,borderBottom:"1px solid",borderColor:"border.muted"},children:["trace: ",u.trace_id," → span: ",u.span_id]},h))]})]}),r==="tree"&&p&&e.jsx(Ie,{spans:p,selectedSpanId:t.span_id,defaultExpandDepth:4}),r==="raw"&&e.jsx(l,{as:"pre",sx:{p:3,fontSize:0,fontFamily:"mono",whiteSpace:"pre-wrap",wordBreak:"break-word",m:0,bg:"canvas.subtle"},children:JSON.stringify(t,null,2)})]})]})},Ae=[{label:"Service",value:t=>t.service_name},{label:"Kind",value:t=>t.kind}];function Ne(t,n,s){return t.filter(r=>n.every((a,o)=>{const x=s[o];if(!x?.size)return!0;const p=a.value(r);return p!==void 0&&x.has(p)}))}function Re(t,n){const s=new Set(t);return s.has(n)?s.delete(n):s.add(n),s}function Ee({facet:t,options:n,selected:s,onChange:r}){const a=t.name??(o=>o);return e.jsxs(H,{children:[e.jsxs(H.Button,{size:"small","data-otel-facet":t.label.toLowerCase(),children:[t.label,s.size?` · ${s.size}`:""]}),e.jsx(H.Overlay,{width:"auto",children:e.jsxs(M,{selectionVariant:"multiple","aria-label":t.label,children:[e.jsx(M.Item,{selected:!s.size,onSelect:()=>r(new Set),children:"All"}),e.jsx(M.Divider,{}),n.map(o=>e.jsx(M.Item,{selected:s.has(o),onSelect:()=>r(Re(s,o)),children:a(o)},o))]})})]})}function Me(t,n){const s=new Blob([JSON.stringify(n,null,2)],{type:"application/json"}),r=URL.createObjectURL(s),a=document.createElement("a");a.href=r,a.download=`${t}.json`,a.click(),setTimeout(()=>URL.revokeObjectURL(r),1e3)}const $e=({tracer:t,spans:n,service:s,facets:r=Ae,compact:a=!1,maxHeight:o=420,detailPlacement:x="below",emptyText:p="Nothing recorded yet.",exportName:u="otel-spans",label:h="Spans",renderSpanMark:d,describeSpan:m})=>{const j=we(n?null:t),S=n??j,[g,O]=f.useState(0),[i,y]=f.useState(null),[b,A]=f.useState(()=>r.map(()=>new Set)),[v,T]=f.useState(null),C=f.useMemo(()=>{const _=Se(S,s);return g?_.filter(z=>E(z.start_time)>=g):_},[S,s,g]),k=i??C,I=i?C.length-i.length:0,ee=f.useMemo(()=>r.map(_=>[...new Set(C.map(z=>_.value(z)).filter(z=>z!==void 0))].sort()),[r,C]),N=f.useMemo(()=>Ne(k,r,b),[k,r,b]),R=f.useMemo(()=>v?S.find(_=>_.span_id===v)??null:null,[S,v]),te=f.useMemo(()=>R?S.filter(_=>_.trace_id===R.trace_id):[],[S,R]),P=x==="side"&&!a;return e.jsxs(l,{"data-otel-live-spans":"",sx:{border:"1px solid",borderColor:"border.default",borderRadius:2,bg:"canvas.default",color:"fg.default",minWidth:0},children:[e.jsxs(l,{role:"toolbar","aria-label":h,sx:{display:"flex",flexWrap:"wrap",gap:2,alignItems:"center",p:2,borderBottom:"1px solid",borderColor:"border.default"},children:[r.map((_,z)=>e.jsx(Ee,{facet:_,options:ee[z]??[],selected:b[z]??new Set,onChange:ne=>A(se=>r.map((Le,G)=>G===z?ne:se[G]??new Set))},_.label)),e.jsx(l,{sx:{flex:1}}),e.jsxs(c,{sx:{fontSize:0,color:"fg.muted"},"data-otel-span-count":"",children:[N.length===k.length?`${N.length} ${N.length===1?"span":"spans"}`:`${N.length} of ${k.length}`,I>0?` · ${I} new`:""]}),e.jsx(U,{size:"small",leadingVisual:i?ae:de,"aria-pressed":i!==null,onClick:()=>y(i?null:C),"data-otel-pause":"",children:i?"Resume":"Pause"}),e.jsx(U,{size:"small",leadingVisual:ce,onClick:()=>{y(null),T(null),t&&!n&&!s?t.clear():O(Date.now())},"data-otel-clear":"",children:"Clear"}),e.jsx(U,{size:"small",leadingVisual:ue,disabled:!C.length,onClick:()=>Me(u,{exportedAt:new Date().toISOString(),spans:[...C]}),"data-otel-export":"",children:"Export"})]}),e.jsxs(l,{sx:{display:P?"grid":"block",gridTemplateColumns:P?"minmax(0, 3fr) minmax(0, 2fr)":void 0},children:[e.jsx(l,{sx:{maxHeight:o,overflowY:"auto",minWidth:0},children:e.jsx(Ce,{spans:N,selectedSpanId:v,onSelectSpan:_=>T(_.span_id),emptyText:p,compact:a,defaultExpanded:!0,renderSpanMark:d,describeSpan:m})}),R&&e.jsx(l,{"data-otel-live-detail":"",sx:{maxHeight:o,overflowY:"auto",minWidth:0,borderTop:P?"none":"1px solid",borderColor:"border.default"},children:e.jsx(Oe,{span:R,traceSpans:te,onClose:()=>T(null)})})]})]})},Be=[{label:"Source",value:fe,name:t=>xe[t]??t},{label:"Operation",value:t=>{const n=t.attributes??{},s=n[K.operation]??n["rpc.method"];return s===void 0?void 0:String(s)}},{label:"Agent",value:t=>t.service_name}];function De(t){const n=t.attributes?.[K.markIcon],s=t.attributes?.[K.markEmoji];return n||s?e.jsx(he,{icon:typeof n=="string"?n:void 0,emoji:typeof s=="string"?s:void 0,size:14}):null}function Pe({tracer:t,spans:n,agent:s,maxHeight:r=420,compact:a=!1,emptyText:o="Nothing recorded yet.",exportName:x="agent-inspector"}){return e.jsx("div",{"data-agent-inspector":s??"",children:e.jsx($e,{tracer:t,spans:n,service:s,facets:Be,compact:a,maxHeight:r,detailPlacement:"side",emptyText:o,exportName:x,label:s?`${s}'s Agent Inspector`:"Agent Inspector",renderSpanMark:De,describeSpan:pe})})}export{Be as AGENT_INSPECTOR_FACETS,Pe as AgentInspector,Pe as default};