@webmcp-auto-ui/agent 2.5.25 → 2.5.26

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 (46) hide show
  1. package/package.json +1 -1
  2. package/src/autoui-server.ts +17 -0
  3. package/src/diagnostics.ts +6 -6
  4. package/src/discovery-cache.ts +17 -3
  5. package/src/index.ts +3 -3
  6. package/src/loop.ts +27 -22
  7. package/src/providers/wasm.ts +185 -345
  8. package/src/recipes/_generated.ts +273 -0
  9. package/src/recipes/canary-data.md +50 -0
  10. package/src/recipes/canary-display.md +99 -0
  11. package/src/recipes/canary-middle.md +32 -0
  12. package/src/recipes/hummingbird-data.md +32 -0
  13. package/src/recipes/hummingbird-display.md +36 -0
  14. package/src/recipes/hummingbird-middle.md +18 -0
  15. package/src/tool-layers.ts +303 -31
  16. package/src/types.ts +6 -1
  17. package/tests/loop.test.ts +2 -2
  18. package/src/providers/gemma.worker.legacy.ts +0 -123
  19. package/src/providers/litert.worker.ts +0 -294
  20. package/src/recipes/widgets/actions.md +0 -28
  21. package/src/recipes/widgets/alert.md +0 -27
  22. package/src/recipes/widgets/cards.md +0 -41
  23. package/src/recipes/widgets/carousel.md +0 -39
  24. package/src/recipes/widgets/chart-rich.md +0 -51
  25. package/src/recipes/widgets/chart.md +0 -32
  26. package/src/recipes/widgets/code.md +0 -21
  27. package/src/recipes/widgets/d3.md +0 -36
  28. package/src/recipes/widgets/data-table.md +0 -46
  29. package/src/recipes/widgets/gallery.md +0 -39
  30. package/src/recipes/widgets/grid-data.md +0 -57
  31. package/src/recipes/widgets/hemicycle.md +0 -43
  32. package/src/recipes/widgets/js-sandbox.md +0 -32
  33. package/src/recipes/widgets/json-viewer.md +0 -27
  34. package/src/recipes/widgets/kv.md +0 -31
  35. package/src/recipes/widgets/list.md +0 -24
  36. package/src/recipes/widgets/log.md +0 -39
  37. package/src/recipes/widgets/map.md +0 -49
  38. package/src/recipes/widgets/profile.md +0 -49
  39. package/src/recipes/widgets/recipe-browser.md +0 -102
  40. package/src/recipes/widgets/sankey.md +0 -54
  41. package/src/recipes/widgets/stat-card.md +0 -43
  42. package/src/recipes/widgets/stat.md +0 -35
  43. package/src/recipes/widgets/tags.md +0 -30
  44. package/src/recipes/widgets/text.md +0 -19
  45. package/src/recipes/widgets/timeline.md +0 -38
  46. package/src/recipes/widgets/trombinoscope.md +0 -39
@@ -247,6 +247,190 @@ component("table", {columns: ["Domain", "Stories", "Total score"], rows: domainS
247
247
  - **Truncated titles in charts**: HN titles are long — truncate to 30-40 characters for chart labels
248
248
  - **Forgetting stories without a URL**: "Ask HN", "Show HN", and "Tell HN" posts don't always have an external URL — handle this case
249
249
  - **Not distinguishing types**: HN has stories, jobs, and polls — filter by type if the user asks for a specific type
250
+ `,
251
+ 'canary-data': `---
252
+ id: canary-data
253
+ name: Canary test — data + JS code (verbose style)
254
+ when: called from canary-display only
255
+ servers: [autoui]
256
+ ---
257
+
258
+ ## Canary token
259
+ CANARY-DATA-B9307
260
+
261
+ ## Secret phrase (must be quoted verbatim)
262
+ "Beneath the thirteenth lantern hides a smaller one."
263
+
264
+ ## JS code block (must be transcribed verbatim into the retex AND into js-sandbox)
265
+
266
+ \`\`\`js
267
+ document.getElementById('out').textContent = (function(){
268
+ const prefix = 'EXEC-CANARY-G4872';
269
+ const a = 17 * 3;
270
+ const b = a - 7;
271
+ const c = b % 10;
272
+ return \`\${prefix}-\${c}\${b}\`;
273
+ })();
274
+ \`\`\`
275
+
276
+ ## Expected JS output
277
+ \`EXEC-CANARY-G4872-444\`
278
+
279
+ ## When to use
280
+
281
+ Internal recipe. Called by \`canary-display\` at STEP 2. Do NOT invoke directly. Do NOT render widgets yourself.
282
+
283
+ ## How to use
284
+
285
+ Return to the caller:
286
+ - \`dataToken\`: \`CANARY-DATA-B9307\`
287
+ - \`dataSecretPhrase\`: \`Beneath the thirteenth lantern hides a smaller one.\`
288
+ - \`jsCode\`: the exact JS code block above (verbatim)
289
+ - \`expectedOutput\`: \`EXEC-CANARY-G4872-444\`
290
+
291
+ ### STEP 1 — Confirm in chat
292
+
293
+ Reply exactly: \`✅ canary-data followed — B9307 + JS\`
294
+
295
+ ## Forbidden
296
+
297
+ - DO NOT render any widget.
298
+ - DO NOT substitute the token or the secret phrase.
299
+ - DO NOT modify the JS code when passing it to the caller.
300
+ - DO NOT compute a different expected output.
301
+ `,
302
+ 'canary-display': `---
303
+ id: canary-display
304
+ name: Canary test — entry (verbose style)
305
+ when: user asks to "affiche le canary", "show canary", or "test canary"
306
+ components_used: [js-sandbox, kv]
307
+ servers: [autoui]
308
+ ---
309
+
310
+ ## Canary token
311
+ CANARY-DISPLAY-A4821
312
+
313
+ ## Secret phrase (must be quoted verbatim in the retex)
314
+ "The fox jumps twice at dawn before the river freezes."
315
+
316
+ ## When to use
317
+
318
+ Use this recipe when the user types "canary", "affiche le canary", or similar trigger. This is a TEST recipe designed to produce an auditable retex widget that proves the agent actually read, ingested, and followed a 3-level chain of recipes including a JS code block.
319
+
320
+ ## How to use
321
+
322
+ YOU MUST execute these steps IN ORDER. Each produces evidence the final retex MUST include.
323
+
324
+ ### STEP 1 — Load the middle recipe
325
+
326
+ Call \`get_recipe("canary-middle")\`. From its content, extract:
327
+ - \`middleToken\` (a string starting with \`CANARY-MIDDLE-\`)
328
+ - \`middleSecretPhrase\` (a short sentence between double quotes)
329
+
330
+ ### STEP 2 — Load the data recipe
331
+
332
+ Call \`get_recipe("canary-data")\`. From its content, extract:
333
+ - \`dataToken\` (a string starting with \`CANARY-DATA-\`)
334
+ - \`dataSecretPhrase\`
335
+ - The **JS code block** verbatim (between triple backticks \`\`\`js ... \`\`\`)
336
+ - The **expected JS output** (the exact string the code returns)
337
+
338
+ ### STEP 3 — Render the JS sandbox widget
339
+
340
+ Call \`widget_display\` with component \`js-sandbox\` passing the JS code from STEP 2 VERBATIM:
341
+
342
+ \`\`\`
343
+ {
344
+ name: "js-sandbox",
345
+ params: {
346
+ title: "Canary JS execution",
347
+ code: "<PASTE the JS code from canary-data verbatim — do not modify>",
348
+ html: "<div id='out' style='font-family:monospace;padding:8px;'></div>",
349
+ css: "body{margin:0;background:#fff;color:#000;font-size:14px;}"
350
+ }
351
+ }
352
+ \`\`\`
353
+
354
+ Pass the JS code verbatim in the \`code\` field — no wrapping needed, the recipe already provides a complete IIFE that writes to \`#out\`.
355
+
356
+ ### STEP 4 — Render the retex widget
357
+
358
+ Call \`widget_display\` with component \`kv\` and these rows IN THIS ORDER:
359
+
360
+ \`\`\`
361
+ {
362
+ name: "kv",
363
+ params: {
364
+ title: "🐤 Canary Retex — verbose style",
365
+ rows: [
366
+ ["entry_id", "canary-display"],
367
+ ["entry_token", "CANARY-DISPLAY-A4821"],
368
+ ["entry_phrase", "The fox jumps twice at dawn before the river freezes."],
369
+ ["middle_id", "canary-middle"],
370
+ ["middle_token", "<from STEP 1>"],
371
+ ["middle_phrase", "<from STEP 1>"],
372
+ ["data_id", "canary-data"],
373
+ ["data_token", "<from STEP 2>"],
374
+ ["data_phrase", "<from STEP 2>"],
375
+ ["js_code_verbatim", "<the JS code from STEP 2, copied mot-à-mot>"],
376
+ ["js_expected_output", "<the expected output string from STEP 2>"],
377
+ ["steps_executed", "1, 2, 3, 4, 5"],
378
+ ["forbidden_avoided_1", "did not skip STEP 1 (middle)"],
379
+ ["forbidden_avoided_2", "did not skip STEP 2 (data)"],
380
+ ["forbidden_avoided_3", "did not substitute any token or phrase"],
381
+ ["forbidden_avoided_4", "did not modify the JS code"],
382
+ ["forbidden_avoided_5", "did not execute STEP 4 before STEPS 1-3"]
383
+ ]
384
+ }
385
+ }
386
+ \`\`\`
387
+
388
+ CRITICAL: all tokens, phrases, and the JS code MUST be verbatim (no paraphrase, no truncation, no reformatting).
389
+
390
+ ### STEP 5 — Confirm in chat
391
+
392
+ Reply exactly: \`✅ canary chain followed — 3 recipes + JS exec\`
393
+
394
+ ## Forbidden
395
+
396
+ - DO NOT skip any STEP.
397
+ - DO NOT substitute any canary token or secret phrase with a paraphrase.
398
+ - DO NOT use a widget other than \`js-sandbox\` (STEP 3) and \`kv\` (STEP 4).
399
+ - DO NOT render STEP 4 before STEPS 1, 2, 3 are complete.
400
+ - DO NOT modify the JS code — copy it character for character.
401
+ `,
402
+ 'canary-middle': `---
403
+ id: canary-middle
404
+ name: Canary test — middle level (verbose style)
405
+ when: called from canary-display only
406
+ servers: [autoui]
407
+ ---
408
+
409
+ ## Canary token
410
+ CANARY-MIDDLE-M5392
411
+
412
+ ## Secret phrase (must be quoted verbatim)
413
+ "Under the stone bridge, eleven minnows wait for the tide."
414
+
415
+ ## When to use
416
+
417
+ Internal recipe. Called exclusively by \`canary-display\` at STEP 1. Do NOT invoke on its own. Do NOT render widgets.
418
+
419
+ ## How to use
420
+
421
+ Return to the caller:
422
+ - \`middleToken\`: \`CANARY-MIDDLE-M5392\`
423
+ - \`middleSecretPhrase\`: \`Under the stone bridge, eleven minnows wait for the tide.\`
424
+
425
+ ### STEP 1 — Confirm in chat
426
+
427
+ Reply exactly: \`✅ canary-middle followed — M5392\`
428
+
429
+ ## Forbidden
430
+
431
+ - DO NOT render any widget.
432
+ - DO NOT substitute the token or the secret phrase.
433
+ - DO NOT invent additional fields.
250
434
  `,
251
435
  'cartographier-observations-biodiversite': `---
252
436
  id: map-biodiversity-observations
@@ -744,6 +928,95 @@ component("gallery", {
744
928
  - **Forgetting to check** that the image field exists in the returned data (some Met Museum objects have no \`primaryImage\`)
745
929
  - **Using \`text\` to display URLs** instead of \`gallery\` — images must be rendered visually
746
930
  - **Not adapting the size**: iNaturalist returns "square" thumbnails by default — replace with "medium" or "large" in the URL
931
+ `,
932
+ 'hummingbird-data': `---
933
+ id: hummingbird-data
934
+ name: Hummingbird test — data + JS (tight style)
935
+ when: called from hummingbird-display
936
+ servers: [autoui]
937
+ ---
938
+
939
+ # Hummingbird data
940
+
941
+ Token: HUMMINGBIRD-DATA-D7244
942
+ Phrase: "The weaver counts backwards from seven."
943
+
944
+ ## JS
945
+
946
+ \`\`\`js
947
+ document.getElementById('out').textContent = (function(){
948
+ const p = 'EXEC-HUMMINGBIRD-H2947';
949
+ const a = 23 * 2;
950
+ const b = a + 8;
951
+ const c = b % 10;
952
+ return \`\${p}-\${c}\${b}\`;
953
+ })();
954
+ \`\`\`
955
+
956
+ Expected: \`EXEC-HUMMINGBIRD-H2947-454\`
957
+
958
+ ## Steps
959
+
960
+ 1. Return \`{dataToken: "HUMMINGBIRD-DATA-D7244", dataPhrase: "The weaver counts backwards from seven.", jsCode: "<the JS block above verbatim>", expectedOutput: "EXEC-HUMMINGBIRD-H2947-454"}\` to caller.
961
+ 2. Chat: \`✅ hummingbird-data followed — D7244 + JS\`
962
+
963
+ Do NOT render any widget. Do NOT modify the JS.
964
+ `,
965
+ 'hummingbird-display': `---
966
+ id: hummingbird-display
967
+ name: Hummingbird test — entry (tight style)
968
+ when: user asks to "affiche le hummingbird", "show hummingbird", or "test hummingbird"
969
+ components_used: [js-sandbox, kv]
970
+ servers: [autoui]
971
+ ---
972
+
973
+ # Hummingbird entry
974
+
975
+ Token: HUMMINGBIRD-DISPLAY-C5619
976
+ Phrase: "Nine moths circle the candle."
977
+
978
+ ## Steps
979
+
980
+ 1. \`get_recipe("hummingbird-middle")\` → extract \`middleToken\`, \`middlePhrase\`.
981
+ 2. \`get_recipe("hummingbird-data")\` → extract \`dataToken\`, \`dataPhrase\`, \`jsCode\`, \`expectedOutput\`.
982
+ 3. \`widget_display({name: "js-sandbox", params: {title: "Hummingbird JS", code: "<jsCode from step 2 verbatim>", html: "<div id='out' style='font-family:monospace;padding:8px;'></div>", css: "body{margin:0;background:#fff;color:#000;font-size:14px;}"}})\`
983
+ 4. \`widget_display({name: "kv", params: {title: "🐦 Hummingbird Retex — tight style", rows: [
984
+ ["entry_id", "hummingbird-display"],
985
+ ["entry_token", "HUMMINGBIRD-DISPLAY-C5619"],
986
+ ["entry_phrase", "Nine moths circle the candle."],
987
+ ["middle_id", "hummingbird-middle"],
988
+ ["middle_token", "<step 1>"],
989
+ ["middle_phrase", "<step 1>"],
990
+ ["data_id", "hummingbird-data"],
991
+ ["data_token", "<step 2>"],
992
+ ["data_phrase", "<step 2>"],
993
+ ["js_code_verbatim", "<step 2>"],
994
+ ["js_expected_output", "<step 2>"],
995
+ ["steps", "1, 2, 3, 4, 5"],
996
+ ["style", "tight"]
997
+ ]}})\`
998
+ 5. Chat: \`✅ hummingbird chain followed — 3 recipes + JS exec\`
999
+
1000
+ All tokens, phrases, and JS code MUST be verbatim.
1001
+ `,
1002
+ 'hummingbird-middle': `---
1003
+ id: hummingbird-middle
1004
+ name: Hummingbird test — middle (tight style)
1005
+ when: called from hummingbird-display
1006
+ servers: [autoui]
1007
+ ---
1008
+
1009
+ # Hummingbird middle
1010
+
1011
+ Token: HUMMINGBIRD-MIDDLE-N7614
1012
+ Phrase: "Salt crystals sing in the kettle at midnight."
1013
+
1014
+ ## Steps
1015
+
1016
+ 1. Return \`{middleToken: "HUMMINGBIRD-MIDDLE-N7614", middlePhrase: "Salt crystals sing in the kettle at midnight."}\` to caller.
1017
+ 2. Chat: \`✅ hummingbird-middle followed — N7614\`
1018
+
1019
+ Do NOT render any widget.
747
1020
  `,
748
1021
  'parlementaire-profile': `---
749
1022
  id: display-parliamentary-profile-with-hemicycle-and-votes
@@ -0,0 +1,50 @@
1
+ ---
2
+ id: canary-data
3
+ name: Canary test — data + JS code (verbose style)
4
+ when: called from canary-display only
5
+ servers: [autoui]
6
+ ---
7
+
8
+ ## Canary token
9
+ CANARY-DATA-B9307
10
+
11
+ ## Secret phrase (must be quoted verbatim)
12
+ "Beneath the thirteenth lantern hides a smaller one."
13
+
14
+ ## JS code block (must be transcribed verbatim into the retex AND into js-sandbox)
15
+
16
+ ```js
17
+ document.getElementById('out').textContent = (function(){
18
+ const prefix = 'EXEC-CANARY-G4872';
19
+ const a = 17 * 3;
20
+ const b = a - 7;
21
+ const c = b % 10;
22
+ return `${prefix}-${c}${b}`;
23
+ })();
24
+ ```
25
+
26
+ ## Expected JS output
27
+ `EXEC-CANARY-G4872-444`
28
+
29
+ ## When to use
30
+
31
+ Internal recipe. Called by `canary-display` at STEP 2. Do NOT invoke directly. Do NOT render widgets yourself.
32
+
33
+ ## How to use
34
+
35
+ Return to the caller:
36
+ - `dataToken`: `CANARY-DATA-B9307`
37
+ - `dataSecretPhrase`: `Beneath the thirteenth lantern hides a smaller one.`
38
+ - `jsCode`: the exact JS code block above (verbatim)
39
+ - `expectedOutput`: `EXEC-CANARY-G4872-444`
40
+
41
+ ### STEP 1 — Confirm in chat
42
+
43
+ Reply exactly: `✅ canary-data followed — B9307 + JS`
44
+
45
+ ## Forbidden
46
+
47
+ - DO NOT render any widget.
48
+ - DO NOT substitute the token or the secret phrase.
49
+ - DO NOT modify the JS code when passing it to the caller.
50
+ - DO NOT compute a different expected output.
@@ -0,0 +1,99 @@
1
+ ---
2
+ id: canary-display
3
+ name: Canary test — entry (verbose style)
4
+ when: user asks to "affiche le canary", "show canary", or "test canary"
5
+ components_used: [js-sandbox, kv]
6
+ servers: [autoui]
7
+ ---
8
+
9
+ ## Canary token
10
+ CANARY-DISPLAY-A4821
11
+
12
+ ## Secret phrase (must be quoted verbatim in the retex)
13
+ "The fox jumps twice at dawn before the river freezes."
14
+
15
+ ## When to use
16
+
17
+ Use this recipe when the user types "canary", "affiche le canary", or similar trigger. This is a TEST recipe designed to produce an auditable retex widget that proves the agent actually read, ingested, and followed a 3-level chain of recipes including a JS code block.
18
+
19
+ ## How to use
20
+
21
+ YOU MUST execute these steps IN ORDER. Each produces evidence the final retex MUST include.
22
+
23
+ ### STEP 1 — Load the middle recipe
24
+
25
+ Call `get_recipe("canary-middle")`. From its content, extract:
26
+ - `middleToken` (a string starting with `CANARY-MIDDLE-`)
27
+ - `middleSecretPhrase` (a short sentence between double quotes)
28
+
29
+ ### STEP 2 — Load the data recipe
30
+
31
+ Call `get_recipe("canary-data")`. From its content, extract:
32
+ - `dataToken` (a string starting with `CANARY-DATA-`)
33
+ - `dataSecretPhrase`
34
+ - The **JS code block** verbatim (between triple backticks ```js ... ```)
35
+ - The **expected JS output** (the exact string the code returns)
36
+
37
+ ### STEP 3 — Render the JS sandbox widget
38
+
39
+ Call `widget_display` with component `js-sandbox` passing the JS code from STEP 2 VERBATIM:
40
+
41
+ ```
42
+ {
43
+ name: "js-sandbox",
44
+ params: {
45
+ title: "Canary JS execution",
46
+ code: "<PASTE the JS code from canary-data verbatim — do not modify>",
47
+ html: "<div id='out' style='font-family:monospace;padding:8px;'></div>",
48
+ css: "body{margin:0;background:#fff;color:#000;font-size:14px;}"
49
+ }
50
+ }
51
+ ```
52
+
53
+ Pass the JS code verbatim in the `code` field — no wrapping needed, the recipe already provides a complete IIFE that writes to `#out`.
54
+
55
+ ### STEP 4 — Render the retex widget
56
+
57
+ Call `widget_display` with component `kv` and these rows IN THIS ORDER:
58
+
59
+ ```
60
+ {
61
+ name: "kv",
62
+ params: {
63
+ title: "🐤 Canary Retex — verbose style",
64
+ rows: [
65
+ ["entry_id", "canary-display"],
66
+ ["entry_token", "CANARY-DISPLAY-A4821"],
67
+ ["entry_phrase", "The fox jumps twice at dawn before the river freezes."],
68
+ ["middle_id", "canary-middle"],
69
+ ["middle_token", "<from STEP 1>"],
70
+ ["middle_phrase", "<from STEP 1>"],
71
+ ["data_id", "canary-data"],
72
+ ["data_token", "<from STEP 2>"],
73
+ ["data_phrase", "<from STEP 2>"],
74
+ ["js_code_verbatim", "<the JS code from STEP 2, copied mot-à-mot>"],
75
+ ["js_expected_output", "<the expected output string from STEP 2>"],
76
+ ["steps_executed", "1, 2, 3, 4, 5"],
77
+ ["forbidden_avoided_1", "did not skip STEP 1 (middle)"],
78
+ ["forbidden_avoided_2", "did not skip STEP 2 (data)"],
79
+ ["forbidden_avoided_3", "did not substitute any token or phrase"],
80
+ ["forbidden_avoided_4", "did not modify the JS code"],
81
+ ["forbidden_avoided_5", "did not execute STEP 4 before STEPS 1-3"]
82
+ ]
83
+ }
84
+ }
85
+ ```
86
+
87
+ CRITICAL: all tokens, phrases, and the JS code MUST be verbatim (no paraphrase, no truncation, no reformatting).
88
+
89
+ ### STEP 5 — Confirm in chat
90
+
91
+ Reply exactly: `✅ canary chain followed — 3 recipes + JS exec`
92
+
93
+ ## Forbidden
94
+
95
+ - DO NOT skip any STEP.
96
+ - DO NOT substitute any canary token or secret phrase with a paraphrase.
97
+ - DO NOT use a widget other than `js-sandbox` (STEP 3) and `kv` (STEP 4).
98
+ - DO NOT render STEP 4 before STEPS 1, 2, 3 are complete.
99
+ - DO NOT modify the JS code — copy it character for character.
@@ -0,0 +1,32 @@
1
+ ---
2
+ id: canary-middle
3
+ name: Canary test — middle level (verbose style)
4
+ when: called from canary-display only
5
+ servers: [autoui]
6
+ ---
7
+
8
+ ## Canary token
9
+ CANARY-MIDDLE-M5392
10
+
11
+ ## Secret phrase (must be quoted verbatim)
12
+ "Under the stone bridge, eleven minnows wait for the tide."
13
+
14
+ ## When to use
15
+
16
+ Internal recipe. Called exclusively by `canary-display` at STEP 1. Do NOT invoke on its own. Do NOT render widgets.
17
+
18
+ ## How to use
19
+
20
+ Return to the caller:
21
+ - `middleToken`: `CANARY-MIDDLE-M5392`
22
+ - `middleSecretPhrase`: `Under the stone bridge, eleven minnows wait for the tide.`
23
+
24
+ ### STEP 1 — Confirm in chat
25
+
26
+ Reply exactly: `✅ canary-middle followed — M5392`
27
+
28
+ ## Forbidden
29
+
30
+ - DO NOT render any widget.
31
+ - DO NOT substitute the token or the secret phrase.
32
+ - DO NOT invent additional fields.
@@ -0,0 +1,32 @@
1
+ ---
2
+ id: hummingbird-data
3
+ name: Hummingbird test — data + JS (tight style)
4
+ when: called from hummingbird-display
5
+ servers: [autoui]
6
+ ---
7
+
8
+ # Hummingbird data
9
+
10
+ Token: HUMMINGBIRD-DATA-D7244
11
+ Phrase: "The weaver counts backwards from seven."
12
+
13
+ ## JS
14
+
15
+ ```js
16
+ document.getElementById('out').textContent = (function(){
17
+ const p = 'EXEC-HUMMINGBIRD-H2947';
18
+ const a = 23 * 2;
19
+ const b = a + 8;
20
+ const c = b % 10;
21
+ return `${p}-${c}${b}`;
22
+ })();
23
+ ```
24
+
25
+ Expected: `EXEC-HUMMINGBIRD-H2947-454`
26
+
27
+ ## Steps
28
+
29
+ 1. Return `{dataToken: "HUMMINGBIRD-DATA-D7244", dataPhrase: "The weaver counts backwards from seven.", jsCode: "<the JS block above verbatim>", expectedOutput: "EXEC-HUMMINGBIRD-H2947-454"}` to caller.
30
+ 2. Chat: `✅ hummingbird-data followed — D7244 + JS`
31
+
32
+ Do NOT render any widget. Do NOT modify the JS.
@@ -0,0 +1,36 @@
1
+ ---
2
+ id: hummingbird-display
3
+ name: Hummingbird test — entry (tight style)
4
+ when: user asks to "affiche le hummingbird", "show hummingbird", or "test hummingbird"
5
+ components_used: [js-sandbox, kv]
6
+ servers: [autoui]
7
+ ---
8
+
9
+ # Hummingbird entry
10
+
11
+ Token: HUMMINGBIRD-DISPLAY-C5619
12
+ Phrase: "Nine moths circle the candle."
13
+
14
+ ## Steps
15
+
16
+ 1. `get_recipe("hummingbird-middle")` → extract `middleToken`, `middlePhrase`.
17
+ 2. `get_recipe("hummingbird-data")` → extract `dataToken`, `dataPhrase`, `jsCode`, `expectedOutput`.
18
+ 3. `widget_display({name: "js-sandbox", params: {title: "Hummingbird JS", code: "<jsCode from step 2 verbatim>", html: "<div id='out' style='font-family:monospace;padding:8px;'></div>", css: "body{margin:0;background:#fff;color:#000;font-size:14px;}"}})`
19
+ 4. `widget_display({name: "kv", params: {title: "🐦 Hummingbird Retex — tight style", rows: [
20
+ ["entry_id", "hummingbird-display"],
21
+ ["entry_token", "HUMMINGBIRD-DISPLAY-C5619"],
22
+ ["entry_phrase", "Nine moths circle the candle."],
23
+ ["middle_id", "hummingbird-middle"],
24
+ ["middle_token", "<step 1>"],
25
+ ["middle_phrase", "<step 1>"],
26
+ ["data_id", "hummingbird-data"],
27
+ ["data_token", "<step 2>"],
28
+ ["data_phrase", "<step 2>"],
29
+ ["js_code_verbatim", "<step 2>"],
30
+ ["js_expected_output", "<step 2>"],
31
+ ["steps", "1, 2, 3, 4, 5"],
32
+ ["style", "tight"]
33
+ ]}})`
34
+ 5. Chat: `✅ hummingbird chain followed — 3 recipes + JS exec`
35
+
36
+ All tokens, phrases, and JS code MUST be verbatim.
@@ -0,0 +1,18 @@
1
+ ---
2
+ id: hummingbird-middle
3
+ name: Hummingbird test — middle (tight style)
4
+ when: called from hummingbird-display
5
+ servers: [autoui]
6
+ ---
7
+
8
+ # Hummingbird middle
9
+
10
+ Token: HUMMINGBIRD-MIDDLE-N7614
11
+ Phrase: "Salt crystals sing in the kettle at midnight."
12
+
13
+ ## Steps
14
+
15
+ 1. Return `{middleToken: "HUMMINGBIRD-MIDDLE-N7614", middlePhrase: "Salt crystals sing in the kettle at midnight."}` to caller.
16
+ 2. Chat: `✅ hummingbird-middle followed — N7614`
17
+
18
+ Do NOT render any widget.