@adia-ai/gen-ui 0.8.63 → 0.8.64

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
@@ -1,5 +1,16 @@
1
1
  # Changelog — @adia-ai/gen-ui
2
2
 
3
+ ## [0.8.64] — 2026-09-13
4
+
5
+ ### Fixed
6
+
7
+ - fix: generateUIStream() now wires currentCanvas through to buildCanvasDiffPrompt() the same way generatePro() does, instead of discarding it, so a thinking-mode iteration turn diffs against the prior canvas instead of regenerating fresh every time (ticket 10032) (local ticket 10032)
8
+ - fix: generateUIStream() now merges its diff-shaped LLM response against the prior canvas via mergeCanvasDiff before repair, instead of treating the diff as the complete canvas, so components the LLM left out of a partial-diff response above the 300-component threshold are carried forward instead of silently dropped, matching generatePro's mergeCanvasDiffDetailed behavior (ticket 10050) (local ticket 10050)
9
+
10
+ ### Maintenance
11
+ - **`compose/` touched in this release window** (2 file(s), e.g. `core/generator.js`): carried by the entries above.
12
+ - **`corpus/` touched in this release window** (1 file(s), e.g. `chunks/_source-hashes.json`): carried by the entries above.
13
+
3
14
  ## [0.8.63] — 2026-09-12
4
15
 
5
16
  ### Changed
@@ -270,11 +270,19 @@ export async function generateUI({ intent, engine: engineName = 'monolithic', mo
270
270
  * @yields {object}
271
271
  */
272
272
  export async function* generateUIStream({ intent, executionId, llmAdapter, model, search, currentCanvas, context, signal }) {
273
- // currentCanvas accepted for API parity with generateUI. The streaming
274
- // path's downstream consumers don't yet read it, but parity prevents the
275
- // client from having to branch its call shape per mode. Tier-2 will
276
- // wire it through the same way generatePro does.
277
- void currentCanvas;
273
+ // ticket 10032: normalize the client-owned canvas payload into a flat
274
+ // prior-components array, the same shape collapse generateUI() does
275
+ // (above) before dispatching to generatePro. Pre-fix this path discarded
276
+ // `currentCanvas` entirely (`void currentCanvas;`), so thinking-mode
277
+ // iteration never diffed against the prior canvas at all.
278
+ let priorComponentsFromPayload = null;
279
+ if (currentCanvas) {
280
+ if (Array.isArray(currentCanvas.components)) {
281
+ priorComponentsFromPayload = currentCanvas.components;
282
+ } else if (Array.isArray(currentCanvas.messages)) {
283
+ priorComponentsFromPayload = currentCanvas.messages.flatMap((m) => m?.components || []);
284
+ }
285
+ }
278
286
  // ── Intent gate: reject non-UI prompts before entering the pipeline ──
279
287
  // Same iteration bypass as generateUI() — modifiers don't need to clear the
280
288
  // conversational gate when there's a prior turn to refine.
@@ -480,7 +488,19 @@ export async function* generateUIStream({ intent, executionId, llmAdapter, model
480
488
 
481
489
  // ── Stage 4: Generate via LLM stream ──
482
490
  const systemPrompt = await buildSystemPrompt(catalogContext, patterns, researchContext, intent, null, context);
483
- const chatMessages = buildChatMessages(intent, previousExecId || executionId);
491
+ // ticket 10032: when the client sent a canvas payload, diff against it
492
+ // (same helper generatePro uses) instead of the legacy store-lookup path
493
+ // buildChatMessages() takes: the payload is the source of truth (it may
494
+ // be running stateless, across a server restart, or in a different tab).
495
+ const hasPriorCanvasFromPayload = Array.isArray(priorComponentsFromPayload) && priorComponentsFromPayload.length > 0;
496
+ const chatMessages = hasPriorCanvasFromPayload
497
+ ? [{
498
+ role: 'user',
499
+ content: buildCanvasDiffPrompt(intent, priorComponentsFromPayload, {
500
+ originalIntent: store.getOriginalIntent(previousExecId || executionId) || null,
501
+ }),
502
+ }]
503
+ : buildChatMessages(intent, previousExecId || executionId);
484
504
 
485
505
  yield { type: 'status', stage: 'generate', message: 'Streaming from LLM...' };
486
506
 
@@ -517,6 +537,23 @@ export async function* generateUIStream({ intent, executionId, llmAdapter, model
517
537
 
518
538
  // ── Stage 5: Parse final + validate ──
519
539
  let messages = parseA2UIResponse(fullText, { executionId, mode: 'stream', intent });
540
+
541
+ // ticket 10050: above the 300-component threshold, buildCanvasDiffPrompt
542
+ // (monolithic/_shared.js) switches to asking for a sparse diff instead of
543
+ // the full canvas, the same threshold generatePro uses. Unlike generatePro
544
+ // (generate-pro.js's own mergeCanvasDiffDetailed call), this path never
545
+ // reconstituted the diff against the prior canvas, so components the LLM
546
+ // left out of the diff were silently dropped instead of carried forward.
547
+ // Merge here, before repair, so validation/storage below see the same
548
+ // full canvas generatePro would produce.
549
+ if (hasPriorCanvasFromPayload && messages && messages.length > 0) {
550
+ for (const msg of messages) {
551
+ if (msg.type === 'updateComponents' && msg.components) {
552
+ msg.components = mergeCanvasDiff(priorComponentsFromPayload, msg.components);
553
+ }
554
+ }
555
+ }
556
+
520
557
  engine.submitStage(executionId, 'generate', {
521
558
  messages, source: 'llm-stream', confidence: 0.8,
522
559
  });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schema": "genui-chunk-index@2",
3
- "captured_at": "2026-09-09T16:07:52.181Z",
3
+ "captured_at": "2026-09-13T22:07:39.419Z",
4
4
  "total_instances": 746,
5
5
  "unique_names": 591,
6
6
  "by_kind": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema": "genui-chunk-output-hashes@1",
3
3
  "algo": "sha256",
4
- "capturedAt": "2026-09-13T00:34:01.593Z",
4
+ "capturedAt": "2026-09-13T22:07:39.419Z",
5
5
  "aggregateDigest": "9eaca6f62e9dc45f78ebb2d22889b53071405a51a9bcd4410c737f076e57e8d3",
6
6
  "harvestEnv": {
7
7
  "nodeMajor": "24",
@@ -283,7 +283,7 @@
283
283
  "catalog/ui-patterns/v050-marketing-blocks/v050-marketing-blocks.html": "7833b21ee84643978cd3ca0e6ff20caa20ec8cbc9a55e371aa295a532f8ed48a",
284
284
  "catalog/ui-patterns/v050-nav-blocks/v050-nav-blocks.contents.html": "86f492db19b8aafc2bf25620f52377cd7a6cb92cfa2d0d3bc9dd4c5ade3e88c6",
285
285
  "catalog/ui-patterns/v050-nav-blocks/v050-nav-blocks.html": "196862f06f495547d85f542e6a0eee152ab40a40ca969c93b0cbd0733de5a5e2",
286
- "packages/gen-ui/a2ui/catalog/tier-index.json": "39372f0840c4564b24f999a01eda6f9024788011b72ead9c0c75593c70f6d799",
286
+ "packages/gen-ui/a2ui/catalog/tier-index.json": "850ec77e8b2f33ea9756e22e27976cd1011ccce618d92b7e9ecf0461501302bd",
287
287
  "packages/web-components/components/accordion/accordion.examples.html": "0218a098bc9db38f6ad5a73b7fbbd8755882d92f47790488928384b79b2e7868",
288
288
  "packages/web-components/components/action-list/action-list.examples.html": "abcb4897fc8143a4c32b15bf82eb3340304cfa22d8498198328c1570102d7bc2",
289
289
  "packages/web-components/components/adia-mark/adia-mark.examples.html": "2124ad37660d157e7a85fdc57eb7725ac02d629a76a47a58ff53703ed5b06238",
@@ -23,7 +23,7 @@
23
23
  "agent"
24
24
  ]
25
25
  },
26
- "captured_at": "2026-09-07T13:06:17.368Z",
26
+ "captured_at": "2026-09-13T22:07:39.419Z",
27
27
  "template": [
28
28
  {
29
29
  "id": "text",
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2026-09-09T16:07:52.181Z",
2
+ "timestamp": "2026-09-13T22:07:39.419Z",
3
3
  "pages": 221,
4
4
  "chunks": 591,
5
5
  "skipped": 1680
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adia-ai/gen-ui",
3
- "version": "0.8.63",
3
+ "version": "0.8.64",
4
4
  "description": "AdiaUI generative-UI system — compose strategies, retrieval, the harvested training corpus, and catalog-aware + LLM-judge validation. Emits A2UI protocol messages; pairs with @adia-ai/a2ui (the protocol runtime). Folded from @adia-ai/a2ui-{compose,retrieval,corpus} + the catalog/semantic halves of the former @adia-ai/a2ui-validator (ADR-0048).",
5
5
  "type": "module",
6
6
  "main": "./compose/index.js",