@webmcp-auto-ui/agent 2.5.25 → 2.5.27

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 (73) hide show
  1. package/package.json +1 -1
  2. package/src/autoui-server.ts +44 -0
  3. package/src/diagnostics.ts +6 -6
  4. package/src/discovery-cache.ts +17 -3
  5. package/src/index.ts +18 -4
  6. package/src/loop.ts +31 -34
  7. package/src/notebook-widgets/compact.ts +312 -0
  8. package/src/notebook-widgets/document.ts +372 -0
  9. package/src/notebook-widgets/editorial.ts +348 -0
  10. package/src/notebook-widgets/recipes/compact.md +104 -0
  11. package/src/notebook-widgets/recipes/document.md +100 -0
  12. package/src/notebook-widgets/recipes/editorial.md +104 -0
  13. package/src/notebook-widgets/recipes/workspace.md +94 -0
  14. package/src/notebook-widgets/shared.ts +1064 -0
  15. package/src/notebook-widgets/workspace.ts +328 -0
  16. package/src/prompts/claude-prompt-builder.ts +81 -0
  17. package/src/prompts/gemma4-prompt-builder.ts +205 -0
  18. package/src/prompts/index.ts +55 -0
  19. package/src/prompts/mistral-prompt-builder.ts +90 -0
  20. package/src/prompts/qwen-prompt-builder.ts +90 -0
  21. package/src/prompts/tool-call-parsers.ts +322 -0
  22. package/src/prompts/tool-refs.ts +196 -0
  23. package/src/providers/factory.ts +20 -3
  24. package/src/providers/transformers-models.ts +143 -0
  25. package/src/providers/transformers-serialize.ts +81 -0
  26. package/src/providers/transformers.ts +329 -0
  27. package/src/providers/transformers.worker.ts +667 -0
  28. package/src/providers/wasm.ts +150 -510
  29. package/src/recipes/_generated.ts +515 -0
  30. package/src/recipes/canary-data.md +50 -0
  31. package/src/recipes/canary-display.md +99 -0
  32. package/src/recipes/canary-middle.md +32 -0
  33. package/src/recipes/hackathon-assemblee-nationale.md +111 -0
  34. package/src/recipes/hummingbird-data.md +32 -0
  35. package/src/recipes/hummingbird-display.md +36 -0
  36. package/src/recipes/hummingbird-middle.md +18 -0
  37. package/src/recipes/notebook-playbook.md +129 -0
  38. package/src/tool-layers.ts +33 -157
  39. package/src/trace-observer.ts +669 -0
  40. package/src/types.ts +20 -5
  41. package/src/util/opfs-cache.ts +265 -0
  42. package/tests/gemma-prompt.test.ts +472 -0
  43. package/tests/loop.test.ts +5 -5
  44. package/tests/transformers-serialize.test.ts +103 -0
  45. package/src/providers/gemma.worker.legacy.ts +0 -123
  46. package/src/providers/litert.worker.ts +0 -294
  47. package/src/recipes/widgets/actions.md +0 -28
  48. package/src/recipes/widgets/alert.md +0 -27
  49. package/src/recipes/widgets/cards.md +0 -41
  50. package/src/recipes/widgets/carousel.md +0 -39
  51. package/src/recipes/widgets/chart-rich.md +0 -51
  52. package/src/recipes/widgets/chart.md +0 -32
  53. package/src/recipes/widgets/code.md +0 -21
  54. package/src/recipes/widgets/d3.md +0 -36
  55. package/src/recipes/widgets/data-table.md +0 -46
  56. package/src/recipes/widgets/gallery.md +0 -39
  57. package/src/recipes/widgets/grid-data.md +0 -57
  58. package/src/recipes/widgets/hemicycle.md +0 -43
  59. package/src/recipes/widgets/js-sandbox.md +0 -32
  60. package/src/recipes/widgets/json-viewer.md +0 -27
  61. package/src/recipes/widgets/kv.md +0 -31
  62. package/src/recipes/widgets/list.md +0 -24
  63. package/src/recipes/widgets/log.md +0 -39
  64. package/src/recipes/widgets/map.md +0 -49
  65. package/src/recipes/widgets/profile.md +0 -49
  66. package/src/recipes/widgets/recipe-browser.md +0 -102
  67. package/src/recipes/widgets/sankey.md +0 -54
  68. package/src/recipes/widgets/stat-card.md +0 -43
  69. package/src/recipes/widgets/stat.md +0 -35
  70. package/src/recipes/widgets/tags.md +0 -30
  71. package/src/recipes/widgets/text.md +0 -19
  72. package/src/recipes/widgets/timeline.md +0 -38
  73. 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,337 @@ 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
+ 'hackathon-assemblee-nationale': `---
933
+ id: hackathon-assemblee-nationale-mcp-webmcp
934
+ name: Hackathon Assemblée Nationale · MCP & WebMCP starter
935
+ components_used: [notebook-document, notebook-compact]
936
+ when: the user mentions the Assemblée Nationale hackathon, wants to experiment with parliamentary data (Tricoteuses, Legifrance), or asks for a starter notebook to explore deputies, votes, amendments, or legislative texts in a hackathon context. Keywords include "hackathon Assemblée Nationale", "MCP WebMCP hackathon", "tricoteuses playbook", "parlement playground", "hackathon parlementaire".
937
+ servers: [autoui, tricoteuses]
938
+ layout:
939
+ type: single
940
+ ---
941
+
942
+ ## When to use
943
+
944
+ The user is participating in (or preparing for) the Assemblée Nationale hackathon around MCP and WebMCP. They want a ready-to-fork notebook with:
945
+ - A clear onboarding (what the hackathon is about, what data is available)
946
+ - Seed queries against Tricoteuses (parliamentary database) that return meaningful results immediately
947
+ - A visualization or transformation cell that the participant can iterate on
948
+ - A closing "your turn" note inviting them to modify, run, and share
949
+
950
+ This recipe is a **specialization** of the generic \`notebook-playbook\` recipe — pre-filled with parliamentary-specific seed cells and tailored to the hackathon narrative.
951
+
952
+ ## How to use
953
+
954
+ ### Step 1 — Pick the document layout
955
+
956
+ Default to \`notebook-document\` for the hackathon. Reasons:
957
+ - Participants expect to collaborate and leave traces for each other (avatars, comments)
958
+ - The document layout reads naturally as "hackathon brief + starter code" rather than "dev tool"
959
+ - Margin comments can be seeded to hint at directions to explore
960
+
961
+ If the participant asks for a minimal dev-focused playground instead, fall back to \`notebook-compact\`.
962
+
963
+ ### Step 2 — Seed the cells
964
+
965
+ The notebook should contain 5–7 cells covering:
966
+
967
+ 1. **Intro markdown** — title, one-line context of the hackathon, link to relevant docs
968
+ 2. **Challenge markdown** — a few axes of exploration suggested by the hackathon organizers (replace placeholders with actual challenges when known)
969
+ 3. **Starter SQL** — a safe, visibly meaningful query on Tricoteuses (e.g. recent votes, most active deputies, amendments on a specific text)
970
+ 4. **Transform JS** — a small JS cell that post-processes the SQL result (grouping, counting, chart prep)
971
+ 5. **Visualization hint** — a markdown cell pointing at available visualization widgets (\`hemicycle\`, \`profile\`, \`timeline\`)
972
+ 6. **Your turn** — a closing markdown inviting the participant to fork and edit
973
+
974
+ Example template (to be refined with actual hackathon organizers' briefs):
975
+
976
+ \`\`\`
977
+ widget_display({name: "notebook-document", params: {
978
+ title: "Hackathon Assemblée Nationale · starter",
979
+ cells: [
980
+ {
981
+ type: "md",
982
+ content: "### Bienvenue au hackathon IA de l'Assemblée Nationale\\n\\nCe notebook est votre point de départ. Les données parlementaires proviennent du serveur <mark>Tricoteuses</mark>. Forkez, éditez, partagez."
983
+ },
984
+ {
985
+ type: "md",
986
+ content: "### Pistes d'exploration\\n\\n- Profil d'un parlementaire et son activité\\n- Cartographie des votes par groupe politique\\n- Amendements sur un texte précis\\n- Enrichissement Wikipedia des parlementaires\\n- Croisement entre circonscription et données externes"
987
+ },
988
+ {
989
+ type: "sql",
990
+ content: "-- 10 scrutins les plus récents\\nSELECT id, date, intitule, pour, contre, abstention\\nFROM scrutins\\nORDER BY date DESC\\nLIMIT 10",
991
+ comment: {
992
+ who: "organizers",
993
+ when: "start",
994
+ body: "Remplacez par une requête sur un texte qui vous intéresse (LIMIT important)."
995
+ }
996
+ },
997
+ {
998
+ type: "js",
999
+ content: "// Regroupe les scrutins par mois\\nconst byMonth = {};\\nfor (const s of rows) {\\n const m = s.date.slice(0, 7);\\n byMonth[m] = (byMonth[m] || 0) + 1;\\n}\\nconsole.table(byMonth);"
1000
+ },
1001
+ {
1002
+ type: "md",
1003
+ content: "### Visualiser\\n\\nPour afficher un profil parlementaire : \`widget_display({name: \\"profile\\", params: {...}})\`.\\nPour un hémicycle : \`widget_display({name: \\"hemicycle\\", params: {groups, result}})\`.\\nPour une timeline de mandats : \`widget_display({name: \\"timeline\\", params: {events}})\`."
1004
+ },
1005
+ {
1006
+ type: "md",
1007
+ content: "### À vous\\n\\nAjoutez des cellules avec \`+ sql / + code\`, réarrangez, exécutez. Quand vous avez quelque chose d'intéressant, cliquez \`share\` pour partager le lien hyperskill avec votre équipe ou les organisateurs."
1008
+ }
1009
+ ]
1010
+ }})
1011
+ \`\`\`
1012
+
1013
+ ### Step 3 — Adapt to what the user knows
1014
+
1015
+ - If the user has no background in the Tricoteuses schema, mention they can use \`list_tables\` and \`describe_table\` on the Tricoteuses server to discover the data model before writing queries.
1016
+ - If the user already has a specific question ("I want to look at votes on the 2024 budget"), rewrite the starter SQL to target that question directly.
1017
+ - If the user asks for a minimal playground without the hackathon framing, fall back to the generic \`notebook-playbook\` recipe instead.
1018
+
1019
+ ### Step 4 — Share
1020
+
1021
+ After creating the notebook, remind the user that they can:
1022
+ - Use \`share\` → \`Hyperskill link\` to generate a fork-friendly URL to paste into their team's channel
1023
+ - Switch to \`view\` mode when demoing to organizers
1024
+ - Consult \`⟲ history\` to see their iteration trace and restore cells deleted by mistake
1025
+
1026
+ ## Notes
1027
+
1028
+ This recipe is intended as a **starting skeleton** — the concrete hackathon brief (dates, prizes, specific challenges, dataset access restrictions) will be refined in a dedicated session with the organizers. Placeholders in the example above (axes of exploration, comments) should be replaced with the actual material provided by the hackathon team when it is available.
1029
+
1030
+ For parliamentary profile pages, vote results with hemicycles, and legislative file browsing, prefer the dedicated recipes:
1031
+ - \`display-parliamentary-profile-with-hemicycle-and-votes\`
1032
+ - \`explorer-dossiers-legislatifs-parcours-texte\`
1033
+ - \`rechercher-textes-juridiques-legifrance\`
1034
+
1035
+ These recipes produce more specialized layouts than a generic notebook, and are better suited when the output is a single focused page rather than a multi-cell playbook.
1036
+
1037
+ ## Common mistakes
1038
+
1039
+ - **Forgetting the hackathon framing**: without the "bienvenue" and "à vous" markdown cells, participants land on a bare notebook and lose the playbook feeling.
1040
+ - **SQL without LIMIT**: Tricoteuses queries without \`LIMIT\` can return thousands of rows and slow down the first impression.
1041
+ - **Inventing data**: do not seed with fake French parliamentary content (fake deputies, fake votes). If the actual data is not known at seed time, use generic queries (\`SELECT * FROM scrutins LIMIT 5\`) and let the user discover from there.
1042
+ - **Picking the wrong layout**: if the user is solo and wants to code fast, \`notebook-compact\` is better than \`notebook-document\`. Default to document for hackathon context because of the collaborative framing, not as a hard rule.
1043
+ `,
1044
+ 'hummingbird-data': `---
1045
+ id: hummingbird-data
1046
+ name: Hummingbird test — data + JS (tight style)
1047
+ when: called from hummingbird-display
1048
+ servers: [autoui]
1049
+ ---
1050
+
1051
+ # Hummingbird data
1052
+
1053
+ Token: HUMMINGBIRD-DATA-D7244
1054
+ Phrase: "The weaver counts backwards from seven."
1055
+
1056
+ ## JS
1057
+
1058
+ \`\`\`js
1059
+ document.getElementById('out').textContent = (function(){
1060
+ const p = 'EXEC-HUMMINGBIRD-H2947';
1061
+ const a = 23 * 2;
1062
+ const b = a + 8;
1063
+ const c = b % 10;
1064
+ return \`\${p}-\${c}\${b}\`;
1065
+ })();
1066
+ \`\`\`
1067
+
1068
+ Expected: \`EXEC-HUMMINGBIRD-H2947-454\`
1069
+
1070
+ ## Steps
1071
+
1072
+ 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.
1073
+ 2. Chat: \`✅ hummingbird-data followed — D7244 + JS\`
1074
+
1075
+ Do NOT render any widget. Do NOT modify the JS.
1076
+ `,
1077
+ 'hummingbird-display': `---
1078
+ id: hummingbird-display
1079
+ name: Hummingbird test — entry (tight style)
1080
+ when: user asks to "affiche le hummingbird", "show hummingbird", or "test hummingbird"
1081
+ components_used: [js-sandbox, kv]
1082
+ servers: [autoui]
1083
+ ---
1084
+
1085
+ # Hummingbird entry
1086
+
1087
+ Token: HUMMINGBIRD-DISPLAY-C5619
1088
+ Phrase: "Nine moths circle the candle."
1089
+
1090
+ ## Steps
1091
+
1092
+ 1. \`get_recipe("hummingbird-middle")\` → extract \`middleToken\`, \`middlePhrase\`.
1093
+ 2. \`get_recipe("hummingbird-data")\` → extract \`dataToken\`, \`dataPhrase\`, \`jsCode\`, \`expectedOutput\`.
1094
+ 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;}"}})\`
1095
+ 4. \`widget_display({name: "kv", params: {title: "🐦 Hummingbird Retex — tight style", rows: [
1096
+ ["entry_id", "hummingbird-display"],
1097
+ ["entry_token", "HUMMINGBIRD-DISPLAY-C5619"],
1098
+ ["entry_phrase", "Nine moths circle the candle."],
1099
+ ["middle_id", "hummingbird-middle"],
1100
+ ["middle_token", "<step 1>"],
1101
+ ["middle_phrase", "<step 1>"],
1102
+ ["data_id", "hummingbird-data"],
1103
+ ["data_token", "<step 2>"],
1104
+ ["data_phrase", "<step 2>"],
1105
+ ["js_code_verbatim", "<step 2>"],
1106
+ ["js_expected_output", "<step 2>"],
1107
+ ["steps", "1, 2, 3, 4, 5"],
1108
+ ["style", "tight"]
1109
+ ]}})\`
1110
+ 5. Chat: \`✅ hummingbird chain followed — 3 recipes + JS exec\`
1111
+
1112
+ All tokens, phrases, and JS code MUST be verbatim.
1113
+ `,
1114
+ 'hummingbird-middle': `---
1115
+ id: hummingbird-middle
1116
+ name: Hummingbird test — middle (tight style)
1117
+ when: called from hummingbird-display
1118
+ servers: [autoui]
1119
+ ---
1120
+
1121
+ # Hummingbird middle
1122
+
1123
+ Token: HUMMINGBIRD-MIDDLE-N7614
1124
+ Phrase: "Salt crystals sing in the kettle at midnight."
1125
+
1126
+ ## Steps
1127
+
1128
+ 1. Return \`{middleToken: "HUMMINGBIRD-MIDDLE-N7614", middlePhrase: "Salt crystals sing in the kettle at midnight."}\` to caller.
1129
+ 2. Chat: \`✅ hummingbird-middle followed — N7614\`
1130
+
1131
+ Do NOT render any widget.
1132
+ `,
1133
+ 'notebook-playbook': `---
1134
+ id: create-interactive-notebook-playbook
1135
+ name: Create an interactive notebook playbook
1136
+ components_used: [notebook-compact, notebook-workspace, notebook-document, notebook-editorial]
1137
+ when: the user wants to experiment with data, prototype a small analysis, share a reusable scenario, let others fork and try a dataset, or prepare a hackathon-ready playground. Keywords include "playground", "playbook", "experiment", "try", "prototype", "hackathon", "share a notebook", "template", "starter".
1138
+ servers: [autoui]
1139
+ layout:
1140
+ type: single
1141
+ ---
1142
+
1143
+ ## When to use
1144
+
1145
+ The user asks for a **notebook-like interactive playground** that combines text, queries, and code cells. Typical triggers:
1146
+ - "Give me a playground for exploring X"
1147
+ - "Prepare a notebook I can share with my team"
1148
+ - "I want to prototype a small analysis"
1149
+ - "Set up a hackathon starter"
1150
+ - "Make a reusable template for exploring CSVs / this API / these tables"
1151
+
1152
+ This recipe applies across domains (parliamentary data, biodiversity, news, business datasets, etc.) — it only prescribes the **shape** of the answer, not its content.
1153
+
1154
+ ## How to use
1155
+
1156
+ ### Step 1 — Pick the right notebook layout
1157
+
1158
+ Choose one of the four \`notebook-*\` widgets based on the user's implicit intent:
1159
+
1160
+ | Layout | Use when |
1161
+ |---|---|
1162
+ | \`notebook-compact\` | Quick data exploration, reactive dataflow with named outputs, minimal chrome. **Default for most "playground" and "hackathon" requests.** |
1163
+ | \`notebook-workspace\` | The user expects a multi-cell analyst workspace with sources, cell navigation, and a "publish" step. Use when they mention "dashboard", "app", "workspace". |
1164
+ | \`notebook-document\` | The user plans to share and discuss with a team. Use when "collaborate", "review", "comment" appear. |
1165
+ | \`notebook-editorial\` | The user wants a polished, article-like final deliverable mixing prose and code. Use for "memo", "report", "writeup", "blog-style". |
1166
+
1167
+ When in doubt, pick \`notebook-compact\`.
1168
+
1169
+ ### Step 2 — Pre-fill the cells with context-aware seeds
1170
+
1171
+ Never create an empty notebook. Always seed with 3–5 cells that give the user an immediate starting point:
1172
+
1173
+ 1. **First cell: markdown** — title + one-sentence context of what the notebook is for
1174
+ 2. **Second cell: markdown or code** — if an MCP data source is connected, a starter query that returns something visible (e.g. \`SELECT * FROM {table} LIMIT 10\`). Otherwise a markdown cell describing the next step
1175
+ 3. **Third cell: code** — a transformation or a visualization that uses the output of step 2. Use \`varname\` on the SQL cell (\`varname: "rows"\`) and reference it in the JS cell
1176
+ 4. **Last cell: markdown** — a short "to you to play" note inviting the user to add cells, edit, or fork
1177
+
1178
+ Example seed for a generic data playground:
1179
+
1180
+ \`\`\`
1181
+ widget_display({name: "notebook-compact", params: {
1182
+ title: "Exploration playground",
1183
+ cells: [
1184
+ {type: "md", content: "### Exploration playground\\n\\nStart by running the first SQL cell, then iterate."},
1185
+ {type: "sql", content: "select * from source limit 10", varname: "rows"},
1186
+ {type: "js", content: "// explore rows here\\nconsole.table(rows)"},
1187
+ {type: "md", content: "### Your turn\\n\\nAdd cells with \`+ sql\` or \`+ js\`, reorder via the drag handle, and share via the header button."}
1188
+ ]
1189
+ }})
1190
+ \`\`\`
1191
+
1192
+ ### Step 3 — Adapt seeds to the connected MCP server
1193
+
1194
+ If a specific MCP server is connected, replace the generic \`source\` and \`select *\` placeholders with actual tables and queries from that server:
1195
+ - For a parliamentary server (Tricoteuses): use actual tables like \`acteurs\`, \`scrutins\`, \`amendements\` with meaningful LIMIT
1196
+ - For a biodiversity server (iNaturalist): use the server's typical queries to return observations
1197
+ - For a generic SQL server: list tables first (\`list_tables\` or \`describe_table\`), then seed with a \`SELECT * FROM {first_table} LIMIT 10\`
1198
+
1199
+ Always keep queries **short** and **limited** so the first run returns quickly and visually.
1200
+
1201
+ ### Step 4 — Share and fork
1202
+
1203
+ After creating the notebook, mention to the user that they can:
1204
+ - Click \`share\` in the toolbar to open the export modal (hyperskill link for in-session sharing, markdown/png/json for external export)
1205
+ - Switch to \`view\` mode (read-only, no controls visible) when presenting to someone
1206
+ - Access the \`⟲ history\` panel to see the trace of edits, and restore deleted cells
1207
+
1208
+ For hackathon contexts, prefer seeding a **document** layout (comments + avatars) so participants feel they are joining a shared space.
1209
+
1210
+ ## Examples
1211
+
1212
+ ### Generic CSV / table playground
1213
+ \`\`\`
1214
+ // user: "I need a playground to play with this CSV"
1215
+ widget_display({name: "notebook-compact", params: {
1216
+ title: "CSV playground",
1217
+ cells: [
1218
+ {type: "md", content: "### CSV playground\\n\\nRun the SQL cell to see the first rows, then iterate."},
1219
+ {type: "sql", content: "select * from source limit 20", varname: "rows"},
1220
+ {type: "js", content: "// summarize, chart, or filter rows here"}
1221
+ ]
1222
+ }})
1223
+ \`\`\`
1224
+
1225
+ ### Collaborative analysis
1226
+ \`\`\`
1227
+ // user: "Set up a notebook my team can edit together"
1228
+ widget_display({name: "notebook-document", params: {
1229
+ title: "Team analysis",
1230
+ cells: [
1231
+ {type: "md", content: "Kick-off: describe the question here."},
1232
+ {type: "sql", content: "select * from source limit 10"},
1233
+ {type: "md", content: "Your findings: add thoughts, highlights (<mark>key sentence</mark>), and comments on the code cells above."}
1234
+ ]
1235
+ }})
1236
+ \`\`\`
1237
+
1238
+ ### Final memo
1239
+ \`\`\`
1240
+ // user: "Prepare a short memo of my findings"
1241
+ widget_display({name: "notebook-editorial", params: {
1242
+ title: "Findings memo",
1243
+ kicker: "memo",
1244
+ cells: [
1245
+ {type: "md", content: "Three observations from last week's data."},
1246
+ {type: "md", content: "First, the volume is up. Here is the query:"},
1247
+ {type: "sql", content: "select count(*) from source"},
1248
+ {type: "md", content: "Second, the distribution has shifted."},
1249
+ {type: "js", content: "// chart distribution"},
1250
+ {type: "md", content: "We conclude that..."}
1251
+ ]
1252
+ }})
1253
+ \`\`\`
1254
+
1255
+ ## Common mistakes
1256
+
1257
+ - **Empty notebook**: never call \`widget_display\` without at least 3 seed cells. The user expects something they can immediately run.
1258
+ - **Wrong layout for the intent**: do not use \`notebook-editorial\` for quick exploration — it signals "finished article" and intimidates. Use \`notebook-compact\` unless the user explicitly asks for a publication feel.
1259
+ - **Heavy initial queries**: always \`LIMIT 10\` or \`LIMIT 20\` in seed SQL cells. Users will expand later if needed.
1260
+ - **Missing \`varname\` on SQL cells** (in compact layout): the named output is what the compact layout showcases. Without it, the notebook loses half its reactive story.
1261
+ - **Inventing UUIDs or fork IDs**: leave \`id\` and \`forkId\` unset — the widget generates sensible defaults. Only pass \`id\` when restoring an existing notebook.
747
1262
  `,
748
1263
  'parlementaire-profile': `---
749
1264
  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.