@adia-ai/a2ui-compose 0.5.5 → 0.5.6
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.
package/CHANGELOG.md
CHANGED
|
@@ -7,11 +7,46 @@ transpiler, evals. Retrieval + validation now ship as sibling
|
|
|
7
7
|
packages (`@adia-ai/a2ui-retrieval`, `@adia-ai/a2ui-validator`) so
|
|
8
8
|
non-compose consumers can depend on them without pulling the
|
|
9
9
|
generator graph.
|
|
10
|
-
|
|
11
10
|
## [Unreleased]
|
|
12
11
|
|
|
13
12
|
_No pending changes._
|
|
14
|
-
|
|
13
|
+
## [0.5.6] - 2026-05-14
|
|
14
|
+
|
|
15
|
+
### Removed — §195 (v0.5.6) — retired fragment-graph iteration codepath
|
|
16
|
+
|
|
17
|
+
Deleted `packages/a2ui/compose/strategies/zettel/synthesizer.js`. The
|
|
18
|
+
file shipped the `synthesizeComposition` function as a throwing stub
|
|
19
|
+
since §37 (v0.4.7, 2026-05-12, fragment retirement). The dangling
|
|
20
|
+
caller in `generator-adapter.js` (iteration branch, turn ≥ 2 + LLM
|
|
21
|
+
present) caught the throw and auto-fired an `iteration-synthesis-failure`
|
|
22
|
+
issue ticket on every multi-turn refinement — surfaced as an auto-fired
|
|
23
|
+
bug at `.brain/audit-history/issues/2026-05-14-iteration-synthesis-failed-on-turn-3-for-4bfb.json`.
|
|
24
|
+
|
|
25
|
+
### Changed — §195 (v0.5.6) — weak-retrieval branch bridges to chunk-zettel
|
|
26
|
+
|
|
27
|
+
Replaced the `synthesizeComposition()` call in `generateZettel`'s
|
|
28
|
+
weak-retrieval-with-LLM branch with a bridge to
|
|
29
|
+
`chunk-synthesizer.js::composeFromIntent` (the §37 successor codepath).
|
|
30
|
+
Return shape is preserved (`messages`, `validation`, `strategy:
|
|
31
|
+
'composition-synthesized'`, `fragments_used: []`, `synthesized_template`,
|
|
32
|
+
`synthesis`). Fragment instances are no longer tracked on this path —
|
|
33
|
+
the chunk-bridge emits a single html-bearing component. Consumers that
|
|
34
|
+
need fragment-level resolution should wire via `engine: 'chunk-zettel'`
|
|
35
|
+
directly.
|
|
36
|
+
|
|
37
|
+
The `composition-iterated` strategy is retired — turn ≥ 2 on
|
|
38
|
+
`engine: 'zettel'` now takes the same path as turn 1. True
|
|
39
|
+
history-aware iteration lives in `chunk-refiner.js::refineFromIntent`
|
|
40
|
+
behind `engine: 'chunk-zettel'`.
|
|
41
|
+
|
|
42
|
+
### Added — §195 (v0.5.6) — smoke probe
|
|
43
|
+
|
|
44
|
+
NEW `scripts/smoke-iteration-synthesis.mjs` (npm run
|
|
45
|
+
`smoke:iteration-synthesis`) verifies the §195 invariants at three
|
|
46
|
+
layers: filesystem (`synthesizer.js` deleted), source
|
|
47
|
+
(`generator-adapter.js` has no surviving reference to the retired
|
|
48
|
+
identifiers), and runtime (4 sequential turns against the same
|
|
49
|
+
sessionId neither throw nor emit `composition-iterated`).
|
|
15
50
|
## [0.5.5] - 2026-05-14
|
|
16
51
|
|
|
17
52
|
### Changed — §179 (v0.5.5) — principled `deprecated:` yaml field
|
|
@@ -27,7 +62,6 @@ Build pipeline (`scripts/build/components.mjs::compileProp`) collects deprecatio
|
|
|
27
62
|
Demonstrated on `Avatar.name`. Verified via `buildSystemPrompt`: `name:String[] (deprecated, do not use)` surfaces in CORPUS CONTEXT.
|
|
28
63
|
|
|
29
64
|
Commit `0379dd498`. See root CHANGELOG and journal §179 for full context.
|
|
30
|
-
|
|
31
65
|
## [0.5.4] - 2026-05-14
|
|
32
66
|
|
|
33
67
|
### Fixed — §163 transpiler prop-fidelity; catalog-driven extractor closes the harvester drop class (v0.5.4)
|
|
@@ -201,7 +235,6 @@ No compose source change in §173/§175 — both detect future drift in compose'
|
|
|
201
235
|
catalog-vs-prompt + registry-vs-catalog invariants.
|
|
202
236
|
|
|
203
237
|
### Changed — `version`: `0.5.3` → `0.5.4`.
|
|
204
|
-
|
|
205
238
|
## [0.5.3] - 2026-05-14
|
|
206
239
|
|
|
207
240
|
### Fixed — Deterministic chunk-loading order in zettel composition library (§160, v0.5.3)
|
|
@@ -224,7 +257,6 @@ Finalizes the v0.6.0 deprecation schedule for the last two `_debug.*` fields tha
|
|
|
224
257
|
**Scheduled removal**: v0.6.0 drops the `_debug` block entirely from the free-form-composed result shape. The dialog-recorder will read first-class fields directly. v0.5.3 is the **migration window** — any external consumers reading `_debug.attempts` / `_debug.warnings` should switch to the first-class fields before v0.6.0 ships.
|
|
225
258
|
|
|
226
259
|
**Internal verification**: zero live in-repo consumers (`grep -rn '_debug\?\.attempts\|_debug\.attempts\|_debug\?\.warnings\|_debug\.warnings' apps/ playgrounds/ catalog/ packages/` returns only the deprecation comment itself).
|
|
227
|
-
|
|
228
260
|
## [0.5.2] - 2026-05-13
|
|
229
261
|
|
|
230
262
|
### Changed — `plan` graduates from `_debug.*` to first-class on free-form-composed result (§107a infra, v0.5.2)
|
|
@@ -259,7 +291,6 @@ Expected impact: lifts substitution ratio 27.4% → ~35-40% (target ≥30%); F1
|
|
|
259
291
|
`strategies/registry.js` reads model priority chain at call-time (not module-load): `ctx.model` > `process.env.FREE_FORM_MODEL_OVERRIDE` > `FREE_FORM_MODEL_DEFAULT` (Haiku 4.5). Enables `eval-diff.mjs --model <id>` to run the Haiku-vs-Opus A/B for §127 without env-dance or static-import-ordering hazards. `FREE_FORM_MODEL` constant renamed to `FREE_FORM_MODEL_DEFAULT` to reflect the new priority chain.
|
|
260
292
|
|
|
261
293
|
Default behavior unchanged when no override set — the v0.5.1 §108 Haiku pin holds for every consumer that doesn't explicitly override.
|
|
262
|
-
|
|
263
294
|
## [0.5.1] - 2026-05-13
|
|
264
295
|
|
|
265
296
|
### Added — Free-form composer INTENT-PARAPHRASE block + paraphrase-retry (§106, v0.5.1)
|
|
@@ -281,7 +312,6 @@ Consumers passing `ctx.llmAdapter` keep getting their adapter via the mint-failu
|
|
|
281
312
|
### Coverage at v0.5.1 cut
|
|
282
313
|
|
|
283
314
|
Post-§106 prompt-tuning + §108 picker pin + §109 first-class graduation, free-form composer coverage measured at **~96-97%** on the 100-intent held-out set (up from §104's 92%). New AGENTS.md regression threshold floor: `cov≥96%, avg≥85, F1≥0.60` (§115 trip-wire baseline).
|
|
284
|
-
|
|
285
315
|
## [0.5.0] - 2026-05-13
|
|
286
316
|
|
|
287
317
|
### Added — Free-form composer auto-grouping (§103, v0.5.0)
|
|
@@ -299,17 +329,14 @@ Schema validation rejects unknown target keys; downgrade warnings fire when a ta
|
|
|
299
329
|
### Coverage at v0.5.0 cut
|
|
300
330
|
|
|
301
331
|
After §93 (layout regrowth) + §94 (forms regrowth) + §103 (auto-grouping) + §104 (structural substitutions + v0.5.1 deferred regrowth fold-in), free-form composer coverage measured at **92% on the 100-intent held-out set** (up from 21% at §92 baseline). New AGENTS.md regression threshold floor: `cov≥80%, avg≥85, F1≥0.45` (§97 rebaseline).
|
|
302
|
-
|
|
303
332
|
## [0.4.9] - 2026-05-13
|
|
304
333
|
|
|
305
334
|
_No pending changes._
|
|
306
|
-
|
|
307
335
|
## [0.4.8] - 2026-05-12
|
|
308
336
|
|
|
309
337
|
### Fixed — `strategies/zettel/generator-adapter.js` `ensureBooted()` race (§87a, v0.4.8)
|
|
310
338
|
|
|
311
339
|
The zettel composition library's lazy boot had a race condition where concurrent `ensureBooted()` calls could each kick off a separate boot promise. Under contention (multiple requests landing simultaneously at server cold-start), the composition map could be partially populated when consumers reached the synchronous getters. Fix: memoize the boot promise on first call so all subsequent callers await the same promise. Pairs with the v0.4.8 §87 honest-floor eval threshold rebaseline — without the boot race fix, the 1% rebaseline was actually undercounting due to occasional empty-map reads.
|
|
312
|
-
|
|
313
340
|
## [0.4.7] - 2026-05-12
|
|
314
341
|
|
|
315
342
|
### Changed — `strategies/monolithic/_shared.js` `getComponentCatalog()` reads canonical catalog (§72)
|
|
@@ -317,7 +344,6 @@ The zettel composition library's lazy boot had a race condition where concurrent
|
|
|
317
344
|
The legacy reader of `@adia-ai/a2ui-corpus/patterns/_components.json` has been migrated to read `@adia-ai/a2ui-corpus/catalog-a2ui_0_9.json` (the canonical v0.9 catalog, already the package root export). Per-component aliases are now lifted from `components[name].x-adiaui.synonyms.tags`. Same legacy output shape (`{ <Name>: { aliases: string[] } }`); zero behavior change for downstream callers.
|
|
318
345
|
|
|
319
346
|
Closes the §65 carry-over from v0.4.6 — `@adia-ai/a2ui-corpus` `patterns/` + `compositions/` are now deleted from disk + tarball.
|
|
320
|
-
|
|
321
347
|
## [0.4.6] - 2026-05-12
|
|
322
348
|
|
|
323
349
|
### Changed — `core/` retirement follow-through (§64, v0.4.6)
|
|
@@ -353,7 +379,6 @@ Closes the catalog-drift surface that §56 explicitly deferred ("different schem
|
|
|
353
379
|
5. `const` fields (e.g. `{const: 'Button'}`) are discriminator-only. Skip.
|
|
354
380
|
|
|
355
381
|
Source: `packages/a2ui/compose/strategies/monolithic/_shared.js` (+91, -2 lines, commit `afda98f5`).
|
|
356
|
-
|
|
357
382
|
## [0.4.5] - 2026-05-12
|
|
358
383
|
|
|
359
384
|
### Changed — GenUI overhaul prompt-engineering (§56, v0.4.5)
|
|
@@ -369,7 +394,6 @@ Source: `packages/a2ui/compose/strategies/monolithic/_shared.js` (+91, -2 lines,
|
|
|
369
394
|
- **`strategies/monolithic/generate-pro.js` — STRUCTURAL REFERENCE prose enriched.** Prior copy: "a real production block from the codebase matched this intent." New copy: "this chunk was retrieved from the AdiaUI training corpus (annotated production HTML, harvested from real app pages). It matched your intent on keyword/domain ranking." Threads chunk `metadata.domain`, `metadata.description`, `metadata.keywords` into the prompt when present. Reframes "do not copy the HTML" as "the chunk represents the SHAPE the user wants; instantiate it with their content" — more actionable framing.
|
|
370
395
|
|
|
371
396
|
See root [CHANGELOG.md `[Unreleased]`](../../../CHANGELOG.md) for the v0.4.5 overhaul arc + apps/genui/CHANGELOG.md `[Unreleased]` for the per-§ rollup.
|
|
372
|
-
|
|
373
397
|
## [0.4.4] - 2026-05-12
|
|
374
398
|
|
|
375
399
|
### Changed
|
|
@@ -386,7 +410,6 @@ See root [CHANGELOG.md `[Unreleased]`](../../../CHANGELOG.md) for the v0.4.5 ove
|
|
|
386
410
|
- **MCP server `mcp/server.js` (§37).** Removed `get_fragment` tool, simplified `zettel_stats`, updated imports + boot logs + engine description to reflect the post-fragment world.
|
|
387
411
|
|
|
388
412
|
See root [CHANGELOG.md `[Unreleased]`](../../../CHANGELOG.md) for the cross-cutting arc narrative + [docs/journal/2026/05/2026-05-12.md](../../../docs/journal/2026/05/2026-05-12.md) §§ 37 / 38 / 41 / 47 for per-§ details.
|
|
389
|
-
|
|
390
413
|
## [0.4.3] - 2026-05-11
|
|
391
414
|
|
|
392
415
|
### Fixed
|
|
@@ -396,7 +419,6 @@ See root [CHANGELOG.md `[Unreleased]`](../../../CHANGELOG.md) for the cross-cutt
|
|
|
396
419
|
### Lockstep
|
|
397
420
|
|
|
398
421
|
9-package coordinated PATCH cut to v0.4.3 (per [`docs/specs/package-architecture.md` § 15](../../../docs/specs/package-architecture.md#15-versioning-policy)). Internal `@adia-ai/*` dep ranges stay at `^0.4.0` (patch-cut asymmetry — `^0.4.0` covers `0.4.x` under semver). Source change scoped to `core/generator.js` + `strategies/zettel/state-cache.js`. Rides alongside `@adia-ai/web-components` v0.4.3 (input-ui locale + thousands grouping + hold-to-repeat). See root [CHANGELOG.md `## [0.4.3]`](../../../CHANGELOG.md) for the cut narrative.
|
|
399
|
-
|
|
400
422
|
## [0.4.2] - 2026-05-11
|
|
401
423
|
|
|
402
424
|
### Ride-along (no source changes)
|
|
@@ -404,7 +426,6 @@ See root [CHANGELOG.md `[Unreleased]`](../../../CHANGELOG.md) for the cross-cutt
|
|
|
404
426
|
Lockstep PATCH cut alongside `@adia-ai/web-components@0.4.2` (`<input-ui type="number">` rewrite drops native `<input type=number>` wrapping) + `@adia-ai/web-modules@0.4.2` (`<editor-sidebar>` grid-track width-mirror fix). Source byte-identical to v0.4.1.
|
|
405
427
|
|
|
406
428
|
Internal `@adia-ai/*` dep ranges stay at `^0.4.0` (patch-cut asymmetry — `^0.4.0` covers `0.4.x` under semver). See root [CHANGELOG.md `## [0.4.2]`](../../../CHANGELOG.md) for the cut narrative.
|
|
407
|
-
|
|
408
429
|
## [0.4.1] - 2026-05-10
|
|
409
430
|
|
|
410
431
|
### Ride-along (no source changes)
|
|
@@ -412,7 +433,6 @@ Internal `@adia-ai/*` dep ranges stay at `^0.4.0` (patch-cut asymmetry — `^0.4
|
|
|
412
433
|
Lockstep PATCH cut alongside `@adia-ai/web-modules@0.4.1` (simple cluster) + `@adia-ai/a2ui-validator@0.4.1` (Phase 3 foundation) + `@adia-ai/a2ui-corpus@0.4.1` (fragment metrics reconciliation). Source byte-identical to v0.4.0.
|
|
413
434
|
|
|
414
435
|
Internal `@adia-ai/*` dep ranges bumped from `^0.4.0` to `^0.4.1`. See root [CHANGELOG.md `## [0.4.1]`](../../../CHANGELOG.md) for the cut narrative.
|
|
415
|
-
|
|
416
436
|
## [0.4.0] - 2026-05-10
|
|
417
437
|
|
|
418
438
|
### Ride-along (no source changes)
|
|
@@ -420,25 +440,21 @@ Internal `@adia-ai/*` dep ranges bumped from `^0.4.0` to `^0.4.1`. See root [CHA
|
|
|
420
440
|
Lockstep MINOR cut alongside `@adia-ai/web-modules@0.4.0` (ADR-0024 legacy shell shapes retired). Source byte-identical to v0.3.6.
|
|
421
441
|
|
|
422
442
|
Internal `@adia-ai/*` dep ranges bumped from `^0.3.0` to `^0.4.0`. See root [CHANGELOG.md `## [0.4.0]`](../../../CHANGELOG.md) for the cut narrative.
|
|
423
|
-
|
|
424
443
|
## [0.3.6] - 2026-05-10
|
|
425
444
|
|
|
426
445
|
### Ride-along (no source changes)
|
|
427
446
|
|
|
428
447
|
Lockstep version bump only — source byte-identical to v0.3.5. Internal `@adia-ai/*` dep ranges remain at `^0.3.0`. See root [CHANGELOG.md `## [0.3.6]`](../../../CHANGELOG.md) for the cut narrative.
|
|
429
|
-
|
|
430
448
|
## [0.3.5] - 2026-05-07
|
|
431
449
|
|
|
432
450
|
### Ride-along (no source changes)
|
|
433
451
|
|
|
434
452
|
Lockstep version bump only — source byte-identical to v0.3.4. Internal `@adia-ai/*` dep ranges remain at `^0.3.0`. See root [CHANGELOG.md `## [0.3.5]`](../../../CHANGELOG.md) for the cut narrative.
|
|
435
|
-
|
|
436
453
|
## [0.3.4] - 2026-05-07
|
|
437
454
|
|
|
438
455
|
### Ride-along (no source changes)
|
|
439
456
|
|
|
440
457
|
Lockstep version bump only — source byte-identical to v0.3.3. Internal `@adia-ai/*` dep ranges remain at `^0.3.0`. See root [CHANGELOG.md `## [0.3.4]`](../../../CHANGELOG.md) for the cut narrative.
|
|
441
|
-
|
|
442
458
|
## [0.3.3] - 2026-05-07
|
|
443
459
|
|
|
444
460
|
**Lockstep cut.** All 9 published `@adia-ai/*` packages now share version `0.3.3`, governed by [`docs/specs/package-architecture.md` § 15](../../../docs/specs/package-architecture.md#15-versioning-policy). Internal `@adia-ai/*` ranges stay at `^0.3.0` (patch-cut asymmetry — caret floats `0.3.x`).
|
|
@@ -483,7 +499,6 @@ Lockstep version bump only — source byte-identical to v0.3.3. Internal `@adia-
|
|
|
483
499
|
for the lifetime of the process. Trade-offs: good for long-running
|
|
484
500
|
MCP, bad for tests/hot-reload. To force a reload, call `loadAll()`
|
|
485
501
|
directly. (closes backlog #100)
|
|
486
|
-
|
|
487
502
|
## [0.3.2] - 2026-05-06
|
|
488
503
|
|
|
489
504
|
**9-package lockstep patch cut to v0.3.2.** All lockstep members share
|
|
@@ -510,7 +525,6 @@ Internal `@adia-ai/*` dep ranges unchanged at `^0.3.0`.
|
|
|
510
525
|
### Changed
|
|
511
526
|
|
|
512
527
|
- `version`: `0.3.1` → `0.3.2`.
|
|
513
|
-
|
|
514
528
|
## [0.3.1] - 2026-05-06
|
|
515
529
|
|
|
516
530
|
**9-package lockstep patch cut.** All 9 published `@adia-ai/*` packages bump 0.3.0 → 0.3.1 per [`docs/specs/package-architecture.md` § 15](../../../docs/specs/package-architecture.md#15-versioning-policy). Internal `@adia-ai/*` dep ranges remain at `^0.3.0` (covers `0.3.1` under semver — patch-cut asymmetry).
|
|
@@ -521,7 +535,6 @@ This package itself ships **no source changes** in v0.3.1. The cut bumps version
|
|
|
521
535
|
|
|
522
536
|
- `version`: `0.3.0` → `0.3.1`.
|
|
523
537
|
- Internal `@adia-ai/*` dep ranges: unchanged at `^0.3.0` (covers `0.3.1` under semver — patch-cut asymmetry).
|
|
524
|
-
|
|
525
538
|
## [0.3.0] - 2026-05-05
|
|
526
539
|
|
|
527
540
|
**9-package lockstep cut + LLM subpath dropped.** All 9 published `@adia-ai/*` packages bump 0.2.5 → 0.3.0 per [`docs/specs/package-architecture.md` § 15](../../../docs/specs/package-architecture.md#15-versioning-policy). Internal `@adia-ai/*` dep ranges bump `^0.2.0` → `^0.3.0`.
|
|
@@ -567,7 +580,6 @@ This is a **minor cut on top of v0.2.5 with one BREAKING change**: the `./llm` s
|
|
|
567
580
|
```
|
|
568
581
|
|
|
569
582
|
Plus rewrite imports as shown above. The change is mechanical.
|
|
570
|
-
|
|
571
583
|
## [0.2.5] - 2026-05-04
|
|
572
584
|
|
|
573
585
|
**8-package lockstep cut.** All 8 published `@adia-ai/*` packages bump 0.2.4 → 0.2.5 per [`docs/specs/package-architecture.md` § 15](../../../docs/specs/package-architecture.md#15-versioning-policy). Internal `@adia-ai/*` dep ranges remain at `^0.2.0` (covers 0.2.5 under semver — patch-cut asymmetry).
|
|
@@ -578,7 +590,6 @@ This is a **patch cut on top of v0.2.4, no BREAKING changes.** Substantive conte
|
|
|
578
590
|
|
|
579
591
|
- `version`: `0.2.4` → `0.2.5`.
|
|
580
592
|
- Internal `@adia-ai/*` dep ranges: unchanged at `^0.2.0` (covers `0.2.5` under semver — patch-cut asymmetry).
|
|
581
|
-
|
|
582
593
|
## [0.2.4] - 2026-05-04
|
|
583
594
|
|
|
584
595
|
**8-package lockstep cut.** All 8 published `@adia-ai/*` packages bump 0.2.3 → 0.2.4 per [`docs/specs/package-architecture.md` § 15](../../../docs/specs/package-architecture.md#15-versioning-policy). Internal `@adia-ai/*` dep ranges remain at `^0.2.0` (covers 0.2.4 under semver — patch-cut asymmetry).
|
|
@@ -597,7 +608,6 @@ _Nothing yet._
|
|
|
597
608
|
---
|
|
598
609
|
|
|
599
610
|
---
|
|
600
|
-
|
|
601
611
|
## [0.2.3] - 2026-05-04
|
|
602
612
|
|
|
603
613
|
**Lockstep cut.** All 8 published `@adia-ai/*` packages bump
|
|
@@ -615,7 +625,6 @@ Patch cut — no breaking changes.
|
|
|
615
625
|
### No source changes
|
|
616
626
|
|
|
617
627
|
`@adia-ai/a2ui-compose` source is byte-identical to `0.2.2`. The cut bumps version + the internal dep range entries only.
|
|
618
|
-
|
|
619
628
|
## [0.2.2] - 2026-05-02
|
|
620
629
|
|
|
621
630
|
**Lockstep cut + reasoning-panel emission fixes.** All 8 published `@adia-ai/*` packages bump 0.2.1 → 0.2.2 per [`docs/specs/package-architecture.md` § 15](../../../../docs/specs/package-architecture.md#15-versioning-policy). Patch cut — no breaking changes.
|
|
@@ -639,7 +648,6 @@ Patch cut — no breaking changes.
|
|
|
639
648
|
Companion fix in `@adia-ai/a2ui-retrieval` Unreleased (web-research.js EXPLICIT/IMPLICIT pattern split). Both surfaces feed the same reasoning-panel deception class — five distinct bugs caught + fixed in commit `9986c71e`.
|
|
640
649
|
|
|
641
650
|
---
|
|
642
|
-
|
|
643
651
|
## [0.2.1] - 2026-05-02
|
|
644
652
|
|
|
645
653
|
**Lockstep cut + scope-drift gate at composer time + skeleton harvest + Tier-1 block filter + high-resolution session ticket trace.** All 8 published `@adia-ai/*` packages bump 0.2.0 → 0.2.1 per [`docs/specs/package-architecture.md` § 15](../../../../docs/specs/package-architecture.md#15-versioning-policy). Patch cut — no breaking changes.
|
|
@@ -678,7 +686,6 @@ The synthesizer now captures a `retrievalTrace` per attempt: Tier-1 hits with sc
|
|
|
678
686
|
`issue-reporter.js` renders this as a sibling Markdown ticket alongside the JSON; sections cover header, description, reproduction, component count, retrieval log table, LLM attempts (raw responses), user prompt, composer plan, generated HTML preview, warnings, ops history, environment. A maintainer can replay any flagged session from the ticket alone.
|
|
679
687
|
|
|
680
688
|
---
|
|
681
|
-
|
|
682
689
|
## [0.2.0] - 2026-05-02
|
|
683
690
|
|
|
684
691
|
**Lockstep cut + boundary cleanup.** All 8 published `@adia-ai/*`
|
|
@@ -733,7 +740,6 @@ cycle, but should update on next touch:
|
|
|
733
740
|
```
|
|
734
741
|
|
|
735
742
|
---
|
|
736
|
-
|
|
737
743
|
## [0.1.0] - 2026-04-28
|
|
738
744
|
|
|
739
745
|
**Multi-turn refinement engine (Phase A).** Adds three new modules to the
|
|
@@ -820,7 +826,6 @@ Additive surface; no breaking changes. Existing consumers calling
|
|
|
820
826
|
`composeFromIntent` continue to work unchanged.
|
|
821
827
|
|
|
822
828
|
---
|
|
823
|
-
|
|
824
829
|
## [0.0.1] - 2026-04-24
|
|
825
830
|
|
|
826
831
|
First public release. Framework-agnostic compose engine for the
|
|
@@ -879,7 +884,6 @@ behind a plug-in engine registry.
|
|
|
879
884
|
- Stale internal-identifier references in comments + doc strings swept to the current naming.
|
|
880
885
|
|
|
881
886
|
---
|
|
882
|
-
|
|
883
887
|
## [0.1.0] — internal baseline (unreleased)
|
|
884
888
|
|
|
885
889
|
Initial version at the time the monorepo was established. Contains:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adia-ai/a2ui-compose",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.6",
|
|
4
4
|
"description": "AdiaUI A2UI compose engine \u2014 framework-agnostic. Takes natural-language intents + a catalog and produces A2UI protocol messages. Pairs with `@adia-ai/a2ui-retrieval` (intent classification, catalog lookup) and `@adia-ai/a2ui-validator` (schema + semantic checks).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -903,6 +903,15 @@ export function mergeCanvasDiff(priorComponents, diffComponents) {
|
|
|
903
903
|
const modifiedIds = new Set();
|
|
904
904
|
const newComponents = [];
|
|
905
905
|
|
|
906
|
+
// §190b (v0.5.6) — Aggregate blocked-layout-type-change warnings.
|
|
907
|
+
// The for-loop below can fire `console.warn` once per blocked component,
|
|
908
|
+
// producing 5-10 line bursts when the LLM tries to restructure a form's
|
|
909
|
+
// fields (typical case: 5 Field→Column blocks for a 5-field form).
|
|
910
|
+
// Collect blocks into an array; emit a single aggregated warning after
|
|
911
|
+
// the loop. Closes the 2026-05-14 user-reported "buglabels" intent
|
|
912
|
+
// emitting 6 consecutive blocks.
|
|
913
|
+
const blockedLayoutChanges = [];
|
|
914
|
+
|
|
906
915
|
for (const dc of diffComponents) {
|
|
907
916
|
if (!dc || !dc.id) continue;
|
|
908
917
|
|
|
@@ -920,7 +929,7 @@ export function mergeCanvasDiff(priorComponents, diffComponents) {
|
|
|
920
929
|
const LAYOUT_CONTAINERS = new Set(['Grid', 'Row', 'Column', 'Stack']);
|
|
921
930
|
if (dc.component && dc.component !== existing.component &&
|
|
922
931
|
(LAYOUT_CONTAINERS.has(existing.component) || LAYOUT_CONTAINERS.has(dc.component))) {
|
|
923
|
-
|
|
932
|
+
blockedLayoutChanges.push({ id: dc.id, from: existing.component, to: dc.component });
|
|
924
933
|
delete dc.component;
|
|
925
934
|
}
|
|
926
935
|
const merged = { ...existing, ...dc };
|
|
@@ -934,6 +943,14 @@ export function mergeCanvasDiff(priorComponents, diffComponents) {
|
|
|
934
943
|
}
|
|
935
944
|
}
|
|
936
945
|
|
|
946
|
+
// §190b — single aggregated warning for blocked layout changes.
|
|
947
|
+
if (blockedLayoutChanges.length > 0) {
|
|
948
|
+
const summary = blockedLayoutChanges
|
|
949
|
+
.map(b => `${b.from}→${b.to} on id="${b.id}"`)
|
|
950
|
+
.join(', ');
|
|
951
|
+
console.warn(`[mergeCanvasDiff] Blocked ${blockedLayoutChanges.length} layout type change${blockedLayoutChanges.length === 1 ? '' : 's'}: ${summary}. Preserving original types.`);
|
|
952
|
+
}
|
|
953
|
+
|
|
937
954
|
// Build result: prior components (minus deleted) + new components
|
|
938
955
|
const result = [];
|
|
939
956
|
for (const c of priorComponents) {
|
|
@@ -197,8 +197,12 @@ describe('§168 mergeCanvasDiff — iteration handoff invariants', () => {
|
|
|
197
197
|
const result = mergeCanvasDiff(prior, llmOutput);
|
|
198
198
|
// Grid type preserved despite LLM's attempted change
|
|
199
199
|
expect(result.find(c => c.id === 'root').component).toBe('Grid');
|
|
200
|
+
// §190b — warning is aggregated: "Blocked N layout type change(s): …"
|
|
200
201
|
expect(warn).toHaveBeenCalledWith(
|
|
201
|
-
expect.stringContaining('Blocked layout type change')
|
|
202
|
+
expect.stringContaining('Blocked 1 layout type change')
|
|
203
|
+
);
|
|
204
|
+
expect(warn).toHaveBeenCalledWith(
|
|
205
|
+
expect.stringContaining('Grid→Column on id="root"')
|
|
202
206
|
);
|
|
203
207
|
warn.mockRestore();
|
|
204
208
|
});
|
|
@@ -3,35 +3,66 @@
|
|
|
3
3
|
*
|
|
4
4
|
* generate({ intent, mode, llmAdapter, sessionId }) -> { messages, validation, strategy, ...extra }
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* Two reasoning layers (post-§195, v0.5.6):
|
|
7
7
|
* 1. Retrieval (always available) — keyword-rank the corpus, resolve top composition.
|
|
8
|
-
* 2. LLM synthesis (when llmAdapter provided AND retrieval weak) —
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
8
|
+
* 2. LLM synthesis (when llmAdapter provided AND retrieval weak) — bridge to
|
|
9
|
+
* chunk-zettel's `composeFromIntent` (the §37 successor codepath) which
|
|
10
|
+
* produces a single-shot html composition from the chunk corpus.
|
|
11
|
+
*
|
|
12
|
+
* Session iteration is currently NOT history-aware in this engine. Prior turns
|
|
13
|
+
* are recorded for analytics + drift tracking, but turn≥2 takes the same code
|
|
14
|
+
* path as turn 1 (fresh retrieval → fresh synthesis). Full history-aware
|
|
15
|
+
* iteration (multi-turn refinement modifying an existing canvas) lives in the
|
|
16
|
+
* `chunk-zettel` engine via `chunk-refiner.js::refineFromIntent` — wire it via
|
|
17
|
+
* `engine: 'chunk-zettel'` rather than `engine: 'zettel'`.
|
|
18
|
+
*
|
|
19
|
+
* The prior fragment-graph iteration codepath (`synthesizeComposition` with
|
|
20
|
+
* `historySummary`) was retired in §37 (2026-05-12) when fragments retired.
|
|
21
|
+
* §195 (v0.5.6) cleaned up the dangling caller — turn≥2 no longer throws +
|
|
22
|
+
* auto-fires a `iteration-synthesis-failure` issue on every multi-turn turn.
|
|
13
23
|
*
|
|
14
24
|
* Strategy labels in the return:
|
|
15
25
|
* - composition-match — fresh retrieval, strong match, emitted verbatim
|
|
16
|
-
* - composition-synthesized —
|
|
17
|
-
* - composition-iterated — LLM modified prior turn's template
|
|
26
|
+
* - composition-synthesized — chunk-zettel single-shot synthesis
|
|
18
27
|
* - fragment-candidates — retrieval weak + no LLM, returning atoms only
|
|
19
|
-
* - synthesis-failed —
|
|
28
|
+
* - synthesis-failed — chunk-zettel tried and failed validation
|
|
20
29
|
*/
|
|
21
30
|
import {
|
|
22
31
|
getComposition,
|
|
23
32
|
searchAll,
|
|
24
33
|
} from './composition-library.js';
|
|
25
34
|
import { resolveComposition, templateToMessages } from './composer.js';
|
|
26
|
-
import { synthesizeComposition } from './synthesizer.js';
|
|
27
35
|
import {
|
|
28
36
|
recordTurn,
|
|
29
37
|
getTurns,
|
|
30
|
-
buildHistorySummary,
|
|
31
38
|
} from './session-store.js';
|
|
32
|
-
import { autoReport } from './issue-reporter.js';
|
|
33
39
|
import { validateSchema } from '../../../validator/validator.js';
|
|
34
40
|
|
|
41
|
+
// Lazy-load the chunk-synthesizer bridge. It imports chunk-corpus data
|
|
42
|
+
// via composition-library's dual-mode loader, which is already top-level
|
|
43
|
+
// awaited; importing it here statically would not break anything but the
|
|
44
|
+
// async-import keeps the cold-start surface tight for the strong-match
|
|
45
|
+
// (no-LLM) path that doesn't need synthesis at all.
|
|
46
|
+
async function bridgeToChunkSynthesis({ intent, llmAdapter }) {
|
|
47
|
+
const { composeFromIntent } = await import('./chunk-synthesizer.js');
|
|
48
|
+
const result = await composeFromIntent({ intent, llmAdapter, maxAttempts: 2 });
|
|
49
|
+
// Shape-adapt chunk-synthesizer's `{ html, plan, source, ... }` to the
|
|
50
|
+
// synthesis-branch's prior `{ messages, template, synthesis }` contract.
|
|
51
|
+
const messages = result.html
|
|
52
|
+
? [{ type: 'updateComponents', components: [{ id: 'chunk-root', component: 'article', html: result.html }] }]
|
|
53
|
+
: [];
|
|
54
|
+
return {
|
|
55
|
+
messages,
|
|
56
|
+
template: result.plan ? [{ $chunk: 'composeFromIntent', plan: result.plan }] : [],
|
|
57
|
+
synthesis: {
|
|
58
|
+
source: result.source,
|
|
59
|
+
score: result.score,
|
|
60
|
+
warnings: result.warnings || [],
|
|
61
|
+
scopeDrift: result.scopeDrift || null,
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
35
66
|
// Composition library auto-loads at module import time via top-level `await
|
|
36
67
|
// loadAll()` in composition-library.js (§72 dual-mode loader, commit
|
|
37
68
|
// `76dbcff2`). The previous `ensureBooted()` here called `loadAll()` WITHOUT
|
|
@@ -72,62 +103,17 @@ function toUpdateComponentsMessages(template) {
|
|
|
72
103
|
}
|
|
73
104
|
|
|
74
105
|
export async function generateZettel({ intent, mode = 'instant', llmAdapter = null, sessionId = null } = {}) {
|
|
75
|
-
// ── Session
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
//
|
|
106
|
+
// ── Session iteration note (post-§195, v0.5.6) ──
|
|
107
|
+
// Fragment-graph history-aware iteration (`synthesizeComposition` with
|
|
108
|
+
// `historySummary`) was retired in §37 when fragments retired. Turn≥2 now
|
|
109
|
+
// takes the same path as turn 1 — fresh retrieval → fresh chunk-synthesis.
|
|
110
|
+
// For true history-aware iteration (modify-an-existing-canvas), wire the
|
|
111
|
+
// request via `engine: 'chunk-zettel'` which uses `chunk-refiner.js`.
|
|
112
|
+
//
|
|
113
|
+
// Prior turns are still recorded (analytics + drift tracking via `getDrift`)
|
|
114
|
+
// but the iteration BRANCH is gone — no more spurious
|
|
115
|
+
// `iteration-synthesis-failure` auto-fires on every multi-turn request.
|
|
79
116
|
const priorTurns = sessionId ? getTurns(sessionId) : [];
|
|
80
|
-
const hasHistory = priorTurns.length > 0;
|
|
81
|
-
|
|
82
|
-
if (hasHistory && llmAdapter) {
|
|
83
|
-
try {
|
|
84
|
-
const historySummary = buildHistorySummary(sessionId, 3);
|
|
85
|
-
const synth = await synthesizeComposition({ intent, llmAdapter, historySummary });
|
|
86
|
-
const validation = validateSchema(synth.messages, { intent });
|
|
87
|
-
const fragments = (synth.template || []).filter((n) => n.$fragment).map((n) => n.$fragment);
|
|
88
|
-
recordTurn(sessionId, {
|
|
89
|
-
intent,
|
|
90
|
-
messages: synth.messages,
|
|
91
|
-
template: synth.template,
|
|
92
|
-
composition: null,
|
|
93
|
-
strategy: 'composition-iterated',
|
|
94
|
-
fragments,
|
|
95
|
-
validation,
|
|
96
|
-
});
|
|
97
|
-
return {
|
|
98
|
-
messages: synth.messages,
|
|
99
|
-
validation,
|
|
100
|
-
strategy: 'composition-iterated',
|
|
101
|
-
retrieval: { hit: false, rank: null, candidate: null, reason: `iteration on turn ${priorTurns.length + 1}` },
|
|
102
|
-
composition: null,
|
|
103
|
-
fragments_used: fragments,
|
|
104
|
-
synthesized_template: synth.template,
|
|
105
|
-
synthesis: synth.synthesis,
|
|
106
|
-
sessionTurns: priorTurns.length + 1,
|
|
107
|
-
};
|
|
108
|
-
} catch (err) {
|
|
109
|
-
// If iteration synthesis fails, fall through to the normal path. Record
|
|
110
|
-
// the failure so the next turn can see we tried, and auto-fire an issue
|
|
111
|
-
// ticket so synthesis-owners can investigate the failure post-hoc.
|
|
112
|
-
console.error('[zettel] iteration synthesis failed:', err.message);
|
|
113
|
-
try {
|
|
114
|
-
await autoReport(
|
|
115
|
-
'iteration-synthesis-failure',
|
|
116
|
-
{
|
|
117
|
-
intent,
|
|
118
|
-
turn: priorTurns.length + 1,
|
|
119
|
-
state_id: sessionId,
|
|
120
|
-
body: `Auto-fired by generator-adapter. Iteration synthesis threw on turn ${priorTurns.length + 1}.\n\nError: \`${err.message}\``,
|
|
121
|
-
tags: ['generator-adapter', `turn-${priorTurns.length + 1}`],
|
|
122
|
-
},
|
|
123
|
-
{ evalMode: mode === 'eval' }
|
|
124
|
-
);
|
|
125
|
-
} catch (reportErr) {
|
|
126
|
-
// Never let issue-reporting crash the request path.
|
|
127
|
-
console.error('[zettel] autoReport failed:', reportErr.message);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
117
|
|
|
132
118
|
const hits = searchAll(intent, { limit: 5 });
|
|
133
119
|
const composition = hits.find((h) => h.type === 'composition');
|
|
@@ -163,19 +149,22 @@ export async function generateZettel({ intent, mode = 'instant', llmAdapter = nu
|
|
|
163
149
|
};
|
|
164
150
|
}
|
|
165
151
|
|
|
166
|
-
// ── Weak/no retrieval:
|
|
152
|
+
// ── Weak/no retrieval: bridge to chunk-zettel synthesis (the §37 successor) ──
|
|
167
153
|
if (llmAdapter && mode !== 'instant-only') {
|
|
168
154
|
try {
|
|
169
|
-
const synth = await
|
|
155
|
+
const synth = await bridgeToChunkSynthesis({ intent, llmAdapter });
|
|
170
156
|
const validation = validateSchema(synth.messages, { intent });
|
|
171
|
-
|
|
157
|
+
// Chunk-bridge produces an html-bearing single component, not
|
|
158
|
+
// resolved fragment instances. `fragments_used` is empty by design;
|
|
159
|
+
// consumers tracking fragment usage should switch to the
|
|
160
|
+
// chunk-zettel engine which surfaces `_debug.plan` directly.
|
|
172
161
|
recordTurn(sessionId, {
|
|
173
162
|
intent,
|
|
174
163
|
messages: synth.messages,
|
|
175
164
|
template: synth.template,
|
|
176
165
|
composition: null,
|
|
177
166
|
strategy: 'composition-synthesized',
|
|
178
|
-
fragments,
|
|
167
|
+
fragments: [],
|
|
179
168
|
validation,
|
|
180
169
|
});
|
|
181
170
|
return {
|
|
@@ -189,7 +178,7 @@ export async function generateZettel({ intent, mode = 'instant', llmAdapter = nu
|
|
|
189
178
|
reason: composition ? `top score ${composition.score} below threshold ${STRONG_MATCH_THRESHOLD}` : 'no composition retrieved',
|
|
190
179
|
},
|
|
191
180
|
composition: null,
|
|
192
|
-
fragments_used:
|
|
181
|
+
fragments_used: [],
|
|
193
182
|
synthesized_template: synth.template,
|
|
194
183
|
synthesis: synth.synthesis,
|
|
195
184
|
candidates: hits,
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Composition synthesizer — RETIRED (§37, 2026-05-12).
|
|
3
|
-
*
|
|
4
|
-
* Previously: when zettel retrieval was weak, this called the LLM to
|
|
5
|
-
* assemble a NEW composition from the fragment catalog (technique B/C
|
|
6
|
-
* fragment-graph synthesis). Fragments are retired and there's no
|
|
7
|
-
* fragment catalog to draw from anymore. The deterministic path
|
|
8
|
-
* (`resolveComposition` on a retrieved composition) still works.
|
|
9
|
-
*
|
|
10
|
-
* Until a chunk-based synthesis fallback lands, this export throws on
|
|
11
|
-
* call. Callers should catch and fall through to monolithic-pro's
|
|
12
|
-
* generation path. generator-adapter.js handles this gracefully.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
export async function synthesizeComposition() {
|
|
16
|
-
const err = new Error(
|
|
17
|
-
'synthesizeComposition is retired (§37 fragment retirement). ' +
|
|
18
|
-
'Use chunk-zettel or monolithic-pro for LLM-driven composition.'
|
|
19
|
-
);
|
|
20
|
-
err.code = 'SYNTHESIZER_RETIRED';
|
|
21
|
-
throw err;
|
|
22
|
-
}
|