@adia-ai/gen-ui 0.8.37
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 +26 -0
- package/README.md +77 -0
- package/compose/CHANGELOG.md +1707 -0
- package/compose/README.md +215 -0
- package/compose/core/artifacts.js +262 -0
- package/compose/core/context-store.js +218 -0
- package/compose/core/generator.d.ts +4 -0
- package/compose/core/generator.js +602 -0
- package/compose/core/pipeline/engine.js +289 -0
- package/compose/core/pipeline/types.js +91 -0
- package/compose/core/plan-primitives.js +120 -0
- package/compose/core/plan-turn.js +145 -0
- package/compose/core/reference.js +150 -0
- package/compose/core/state.js +15 -0
- package/compose/evals/harness.d.ts +4 -0
- package/compose/evals/harness.mjs +193 -0
- package/compose/index.d.ts +4 -0
- package/compose/index.js +16 -0
- package/compose/shared/validate-and-repair.js +122 -0
- package/compose/strategies/_shared/chunk-loader.js +282 -0
- package/compose/strategies/cascade.d.ts +67 -0
- package/compose/strategies/cascade.js +165 -0
- package/compose/strategies/escalation.d.ts +13 -0
- package/compose/strategies/escalation.js +132 -0
- package/compose/strategies/free-form-composer/index.js +254 -0
- package/compose/strategies/free-form-composer/system-prompt.js +205 -0
- package/compose/strategies/free-form-composer/transpile.js +279 -0
- package/compose/strategies/monolithic/_shared.js +1619 -0
- package/compose/strategies/monolithic/generate-instant.js +228 -0
- package/compose/strategies/monolithic/generate-pro.js +490 -0
- package/compose/strategies/monolithic/generate-thinking.js +206 -0
- package/compose/strategies/registry.d.ts +20 -0
- package/compose/strategies/registry.js +495 -0
- package/compose/strategies/zettel/_smoke.js +27 -0
- package/compose/strategies/zettel/chunk-composer.js +214 -0
- package/compose/strategies/zettel/chunk-refiner.js +582 -0
- package/compose/strategies/zettel/chunk-synthesizer.js +458 -0
- package/compose/strategies/zettel/composer.js +78 -0
- package/compose/strategies/zettel/composition-library.js +418 -0
- package/compose/strategies/zettel/generate.js +15 -0
- package/compose/strategies/zettel/generator-adapter.d.ts +4 -0
- package/compose/strategies/zettel/generator-adapter.js +242 -0
- package/compose/strategies/zettel/issue-reporter.js +607 -0
- package/compose/strategies/zettel/session-store.js +121 -0
- package/compose/strategies/zettel/state-cache.js +158 -0
- package/compose/transpiler/transpiler-maps.js +675 -0
- package/compose/transpiler/transpiler.d.ts +4 -0
- package/compose/transpiler/transpiler.js +962 -0
- package/corpus/CHANGELOG.md +1957 -0
- package/corpus/README.md +279 -0
- package/corpus/catalog-a2ui_0_9.d.ts +4 -0
- package/corpus/catalog-a2ui_0_9.json +29571 -0
- package/corpus/catalog-a2ui_0_9_rules.txt +1215 -0
- package/corpus/chunk-embeddings.d.ts +4 -0
- package/corpus/chunk-embeddings.json +1 -0
- package/corpus/chunks/_index.json +16658 -0
- package/corpus/chunks/_source-hashes.json +571 -0
- package/corpus/chunks/access-denied-with-request.json +124 -0
- package/corpus/chunks/access-request-form.json +166 -0
- package/corpus/chunks/access-request-pending.json +133 -0
- package/corpus/chunks/accordion-settings.json +176 -0
- package/corpus/chunks/achievement-badges.json +413 -0
- package/corpus/chunks/achievement-unlock.json +104 -0
- package/corpus/chunks/action-list-record-actions.json +84 -0
- package/corpus/chunks/activity-feed.json +390 -0
- package/corpus/chunks/admin-page-header-flush.json +83 -0
- package/corpus/chunks/admin-page-header-title-description.json +80 -0
- package/corpus/chunks/admin-page-header-with-actions.json +107 -0
- package/corpus/chunks/admin-page-header-with-tabs.json +144 -0
- package/corpus/chunks/admin-shell-rounded-borderless.json +287 -0
- package/corpus/chunks/admin-shell-standard.json +310 -0
- package/corpus/chunks/admin-sidebar-brand-signin.json +158 -0
- package/corpus/chunks/admin-sidebar-brand-version.json +130 -0
- package/corpus/chunks/admin-sidebar-flat-nav.json +131 -0
- package/corpus/chunks/admin-sidebar-nav-dividers.json +150 -0
- package/corpus/chunks/admin-sidebar-nav-groups.json +171 -0
- package/corpus/chunks/admin-sidebar-workspace-switcher.json +139 -0
- package/corpus/chunks/admin-topbar-breadcrumb-actions.json +130 -0
- package/corpus/chunks/admin-topbar-breadcrumb-minimal.json +79 -0
- package/corpus/chunks/admin-topbar-deep-breadcrumb.json +129 -0
- package/corpus/chunks/admin-topbar-search.json +104 -0
- package/corpus/chunks/admin-topbar-status-indicator.json +122 -0
- package/corpus/chunks/admin-topbar-trailing-toggle.json +114 -0
- package/corpus/chunks/agent-activity-feed.json +163 -0
- package/corpus/chunks/agent-artifact-stub-card.json +115 -0
- package/corpus/chunks/agent-canvas-shell.json +305 -0
- package/corpus/chunks/agent-citations-source-chips.json +82 -0
- package/corpus/chunks/agent-command-palette-search.json +120 -0
- package/corpus/chunks/agent-cost-detailed.json +260 -0
- package/corpus/chunks/agent-cost-inline.json +78 -0
- package/corpus/chunks/agent-memory-detail.json +181 -0
- package/corpus/chunks/agent-memory-editor.json +173 -0
- package/corpus/chunks/agent-memory-list.json +207 -0
- package/corpus/chunks/agent-pipeline-status-stages.json +61 -0
- package/corpus/chunks/agent-prompt-card.json +179 -0
- package/corpus/chunks/agent-prompt-library-grid.json +341 -0
- package/corpus/chunks/agent-prompt-picker.json +282 -0
- package/corpus/chunks/agent-rate-limit.json +100 -0
- package/corpus/chunks/agent-reasoning-collapsed.json +128 -0
- package/corpus/chunks/agent-tool-call-accordion.json +109 -0
- package/corpus/chunks/agent-tool-call-collapsed.json +98 -0
- package/corpus/chunks/agent-tool-call-error.json +112 -0
- package/corpus/chunks/agent-tool-call-result.json +145 -0
- package/corpus/chunks/agent-tool-call-running.json +85 -0
- package/corpus/chunks/agent-tool-call-success.json +137 -0
- package/corpus/chunks/agent-trace-timeline.json +244 -0
- package/corpus/chunks/ai-streaming-response.json +147 -0
- package/corpus/chunks/alert-banner-stack.json +78 -0
- package/corpus/chunks/alert-banner.json +55 -0
- package/corpus/chunks/alert-dialog-simple.json +72 -0
- package/corpus/chunks/alert-dialog-typed.json +107 -0
- package/corpus/chunks/alert-dialog-unsaved.json +81 -0
- package/corpus/chunks/analytics-chart.json +213 -0
- package/corpus/chunks/analytics-sparklines-dashboard.json +259 -0
- package/corpus/chunks/anchor-bar-selection-bar.json +226 -0
- package/corpus/chunks/api-key-table.json +148 -0
- package/corpus/chunks/api-keys-create.json +140 -0
- package/corpus/chunks/api-keys-list.json +271 -0
- package/corpus/chunks/app-nav-badges-counts.json +77 -0
- package/corpus/chunks/app-nav-badges-group-rollup-badges.json +100 -0
- package/corpus/chunks/app-nav-badges-plan-tiers.json +76 -0
- package/corpus/chunks/app-nav-badges-status-callouts.json +75 -0
- package/corpus/chunks/app-nav-full-example.json +195 -0
- package/corpus/chunks/app-nav-groups.json +103 -0
- package/corpus/chunks/app-nav-items.json +74 -0
- package/corpus/chunks/app-nav-labels-and-dividers.json +92 -0
- package/corpus/chunks/app-nav-spacer.json +77 -0
- package/corpus/chunks/app-product-listing-card.json +214 -0
- package/corpus/chunks/approvals-detail.json +240 -0
- package/corpus/chunks/approvals-queue.json +321 -0
- package/corpus/chunks/audit-log-basic.json +184 -0
- package/corpus/chunks/audit-log.json +174 -0
- package/corpus/chunks/auth-account-deleted-actions.json +51 -0
- package/corpus/chunks/auth-account-deleted.json +202 -0
- package/corpus/chunks/auth-card-content.json +260 -0
- package/corpus/chunks/auth-card-header.json +205 -0
- package/corpus/chunks/auth-email-entry.json +65 -0
- package/corpus/chunks/auth-email-verify-confirm.json +52 -0
- package/corpus/chunks/auth-email-verify.json +196 -0
- package/corpus/chunks/auth-forbidden-actions.json +59 -0
- package/corpus/chunks/auth-forbidden.json +203 -0
- package/corpus/chunks/auth-invite-actions.json +49 -0
- package/corpus/chunks/auth-invite-team-card.json +86 -0
- package/corpus/chunks/auth-link-expired-form.json +65 -0
- package/corpus/chunks/auth-link-expired.json +196 -0
- package/corpus/chunks/auth-locked-account.json +211 -0
- package/corpus/chunks/auth-locked-recovery-options.json +60 -0
- package/corpus/chunks/auth-mfa-enrollment-submit.json +54 -0
- package/corpus/chunks/auth-mfa-enrollment.json +284 -0
- package/corpus/chunks/auth-mfa-fallback-actions.json +52 -0
- package/corpus/chunks/auth-mfa-recovery.json +61 -0
- package/corpus/chunks/auth-new-password-form.json +75 -0
- package/corpus/chunks/auth-new-password.json +217 -0
- package/corpus/chunks/auth-oauth-fallback-actions.json +52 -0
- package/corpus/chunks/auth-oauth-interstitial.json +160 -0
- package/corpus/chunks/auth-password-challenge.json +94 -0
- package/corpus/chunks/auth-password-reset-form.json +64 -0
- package/corpus/chunks/auth-password-reset.json +195 -0
- package/corpus/chunks/auth-profile-form.json +72 -0
- package/corpus/chunks/auth-profile-setup.json +194 -0
- package/corpus/chunks/auth-reset-sent.json +188 -0
- package/corpus/chunks/auth-session-expired-actions.json +52 -0
- package/corpus/chunks/auth-session-expired.json +201 -0
- package/corpus/chunks/auth-signin-card-email.json +245 -0
- package/corpus/chunks/auth-signin-card-magic-link.json +147 -0
- package/corpus/chunks/auth-signin-card-mfa.json +231 -0
- package/corpus/chunks/auth-signin-card-otp.json +205 -0
- package/corpus/chunks/auth-signin-card-password.json +264 -0
- package/corpus/chunks/auth-signin-card-recovery.json +218 -0
- package/corpus/chunks/auth-signout-actions.json +51 -0
- package/corpus/chunks/auth-signout.json +184 -0
- package/corpus/chunks/auth-signup-email-entry.json +66 -0
- package/corpus/chunks/auth-signup-entry.json +281 -0
- package/corpus/chunks/auth-signup-social-auths.json +54 -0
- package/corpus/chunks/auth-signup-verify.json +227 -0
- package/corpus/chunks/auth-social-auths.json +62 -0
- package/corpus/chunks/auth-sso-providers.json +55 -0
- package/corpus/chunks/auth-sso-required.json +213 -0
- package/corpus/chunks/auth-team-invite.json +288 -0
- package/corpus/chunks/avatar-group-overflow.json +137 -0
- package/corpus/chunks/avatar-stack-overflow.json +124 -0
- package/corpus/chunks/banner-announcement-beta.json +99 -0
- package/corpus/chunks/banner-announcement-promo.json +102 -0
- package/corpus/chunks/banner-live-update.json +102 -0
- package/corpus/chunks/banner-system-maintenance.json +101 -0
- package/corpus/chunks/banner-system-offline.json +85 -0
- package/corpus/chunks/banner-system-update.json +102 -0
- package/corpus/chunks/bell-menu-empty.json +107 -0
- package/corpus/chunks/bell-menu-unread.json +395 -0
- package/corpus/chunks/billing-cancel-subscription-danger.json +61 -0
- package/corpus/chunks/billing-invoice-history-table.json +75 -0
- package/corpus/chunks/billing-overview.json +202 -0
- package/corpus/chunks/billing-payment-method-card-on-file.json +157 -0
- package/corpus/chunks/billing-progress-label.json +101 -0
- package/corpus/chunks/blog-post-card.json +212 -0
- package/corpus/chunks/breadcrumb-navigation.json +72 -0
- package/corpus/chunks/bulk-action-toolbar-floating.json +199 -0
- package/corpus/chunks/bulk-action-toolbar-swap.json +158 -0
- package/corpus/chunks/bulk-selection-actions-bar.json +162 -0
- package/corpus/chunks/business-address-form.json +953 -0
- package/corpus/chunks/calendar-month-view.json +74 -0
- package/corpus/chunks/card-grid-images.json +459 -0
- package/corpus/chunks/card-header-with-description.json +47 -0
- package/corpus/chunks/card-with-empty-state.json +96 -0
- package/corpus/chunks/card-with-form.json +143 -0
- package/corpus/chunks/card-with-sparkline.json +90 -0
- package/corpus/chunks/card-with-stat-kpi.json +86 -0
- package/corpus/chunks/changelog-feed-basic.json +470 -0
- package/corpus/chunks/chart-in-card-chart-plus-breakdown.json +188 -0
- package/corpus/chunks/chart-in-card-chart-plus-stat.json +89 -0
- package/corpus/chunks/chart-in-card-chart-with-filter-pills.json +124 -0
- package/corpus/chunks/chart-in-card-full-bleed-legend.json +116 -0
- package/corpus/chunks/chart-in-card-full-chart.json +107 -0
- package/corpus/chunks/chart-in-card-sparkline-tile.json +93 -0
- package/corpus/chunks/chart-in-card-stat-with-sparkline.json +73 -0
- package/corpus/chunks/chart-in-card-trend-footer.json +115 -0
- package/corpus/chunks/chart-with-filter-pills.json +169 -0
- package/corpus/chunks/chat-empty-state-hero.json +102 -0
- package/corpus/chunks/chat-message-assistant-byline.json +85 -0
- package/corpus/chunks/chat-message-user-byline.json +84 -0
- package/corpus/chunks/chat-page-shell.json +379 -0
- package/corpus/chunks/chat-streaming-surface.json +169 -0
- package/corpus/chunks/checkout-order-summary-card.json +140 -0
- package/corpus/chunks/code-snippet.json +107 -0
- package/corpus/chunks/col-form-stack.json +93 -0
- package/corpus/chunks/col-heading-body-action.json +79 -0
- package/corpus/chunks/col-stat-label.json +63 -0
- package/corpus/chunks/color-picker-swatches.json +153 -0
- package/corpus/chunks/command-palette.json +327 -0
- package/corpus/chunks/comments-composer.json +158 -0
- package/corpus/chunks/comments-mention-menu.json +237 -0
- package/corpus/chunks/comments-thread.json +344 -0
- package/corpus/chunks/commerce-pricing-tiers.json +401 -0
- package/corpus/chunks/comparison-table.json +246 -0
- package/corpus/chunks/contact-form-card.json +197 -0
- package/corpus/chunks/contact-form.json +157 -0
- package/corpus/chunks/contact-support-form.json +702 -0
- package/corpus/chunks/conversion-funnel-4-step-funnel.json +139 -0
- package/corpus/chunks/conversion-funnel-6step.json +151 -0
- package/corpus/chunks/conversion-funnel-wide-summary.json +192 -0
- package/corpus/chunks/conversion-funnel-with-segment-compare.json +202 -0
- package/corpus/chunks/cta-banner-centered.json +102 -0
- package/corpus/chunks/dashboard-acquisition-panel.json +212 -0
- package/corpus/chunks/dashboard-admin-page.json +104 -0
- package/corpus/chunks/dashboard-audience-kpis.json +165 -0
- package/corpus/chunks/dashboard-audience-panel.json +756 -0
- package/corpus/chunks/dashboard-behavior-panel.json +114 -0
- package/corpus/chunks/dashboard-chart-recent.json +566 -0
- package/corpus/chunks/dashboard-cohort-retention.json +83 -0
- package/corpus/chunks/dashboard-conversion-panel.json +234 -0
- package/corpus/chunks/dashboard-country-list.json +304 -0
- package/corpus/chunks/dashboard-filter-bar.json +118 -0
- package/corpus/chunks/dashboard-funnel.json +142 -0
- package/corpus/chunks/dashboard-notifications-panel.json +423 -0
- package/corpus/chunks/dashboard-overview-panel.json +1644 -0
- package/corpus/chunks/dashboard-page-header.json +166 -0
- package/corpus/chunks/dashboard-pages-table.json +86 -0
- package/corpus/chunks/dashboard-quick-actions.json +116 -0
- package/corpus/chunks/dashboard-reports-panel.json +166 -0
- package/corpus/chunks/dashboard-reports-table.json +138 -0
- package/corpus/chunks/dashboard-storage-card.json +117 -0
- package/corpus/chunks/dashboard-tabs.json +86 -0
- package/corpus/chunks/dashboard-team-actions-storage.json +605 -0
- package/corpus/chunks/dashboard-team-list.json +334 -0
- package/corpus/chunks/dashboard-traffic-channels.json +184 -0
- package/corpus/chunks/dashboard-transactions-table.json +145 -0
- package/corpus/chunks/data-export-history.json +192 -0
- package/corpus/chunks/data-export-request.json +197 -0
- package/corpus/chunks/data-import-wizard.json +391 -0
- package/corpus/chunks/date-range-picker.json +156 -0
- package/corpus/chunks/date-time-picker-form.json +222 -0
- package/corpus/chunks/departments-checkbox-form.json +390 -0
- package/corpus/chunks/destructive-confirm-modal.json +149 -0
- package/corpus/chunks/diff-inline.json +84 -0
- package/corpus/chunks/diff-side-by-side.json +131 -0
- package/corpus/chunks/diff-structured.json +216 -0
- package/corpus/chunks/digest-email-preview.json +374 -0
- package/corpus/chunks/divider-text-label.json +87 -0
- package/corpus/chunks/doc-editor-shell.json +356 -0
- package/corpus/chunks/drawer-2fa-key.json +273 -0
- package/corpus/chunks/drawer-2fa-sms.json +261 -0
- package/corpus/chunks/drawer-2fa-totp.json +385 -0
- package/corpus/chunks/drawer-cancel-sub.json +636 -0
- package/corpus/chunks/drawer-change-plan.json +561 -0
- package/corpus/chunks/drawer-custom-roles.json +696 -0
- package/corpus/chunks/drawer-data-start.json +171 -0
- package/corpus/chunks/drawer-delete-account.json +341 -0
- package/corpus/chunks/drawer-delete-workspace.json +362 -0
- package/corpus/chunks/drawer-discord.json +434 -0
- package/corpus/chunks/drawer-figma.json +401 -0
- package/corpus/chunks/drawer-first-dashboard.json +220 -0
- package/corpus/chunks/drawer-gcal.json +475 -0
- package/corpus/chunks/drawer-github.json +589 -0
- package/corpus/chunks/drawer-invite.json +397 -0
- package/corpus/chunks/drawer-record-detail.json +44 -0
- package/corpus/chunks/drawer-report.json +528 -0
- package/corpus/chunks/drawer-revoke-session.json +331 -0
- package/corpus/chunks/drawer-role.json +190 -0
- package/corpus/chunks/drawer-slack.json +429 -0
- package/corpus/chunks/drawer-smtp.json +476 -0
- package/corpus/chunks/drawer-source.json +294 -0
- package/corpus/chunks/drawer-transaction.json +493 -0
- package/corpus/chunks/drawer-with-create-form.json +43 -0
- package/corpus/chunks/editor-code-pane.json +204 -0
- package/corpus/chunks/editor-page-shell.json +149 -0
- package/corpus/chunks/editor-preview-pane.json +136 -0
- package/corpus/chunks/editor-statusbar-ready.json +99 -0
- package/corpus/chunks/editor-toolbar-import-export.json +195 -0
- package/corpus/chunks/email-inbox-list.json +678 -0
- package/corpus/chunks/empty-state-danger.json +58 -0
- package/corpus/chunks/empty-state-minimal.json +44 -0
- package/corpus/chunks/empty-state-warning.json +53 -0
- package/corpus/chunks/empty-state.json +65 -0
- package/corpus/chunks/error-404-actions.json +54 -0
- package/corpus/chunks/error-404.json +204 -0
- package/corpus/chunks/error-500-actions.json +61 -0
- package/corpus/chunks/error-500.json +220 -0
- package/corpus/chunks/error-maintenance-actions.json +53 -0
- package/corpus/chunks/error-maintenance.json +203 -0
- package/corpus/chunks/error-page-shell.json +132 -0
- package/corpus/chunks/export-flow-async.json +210 -0
- package/corpus/chunks/export-flow-delivery.json +163 -0
- package/corpus/chunks/export-flow-sync.json +162 -0
- package/corpus/chunks/extended-profile-form.json +512 -0
- package/corpus/chunks/faq-accordion.json +123 -0
- package/corpus/chunks/feature-grid-icons.json +314 -0
- package/corpus/chunks/feature-grid-three-cards.json +187 -0
- package/corpus/chunks/feature-toggle-switch-grid.json +213 -0
- package/corpus/chunks/file-upload-dnd.json +166 -0
- package/corpus/chunks/file-upload-field.json +97 -0
- package/corpus/chunks/file-upload-form.json +251 -0
- package/corpus/chunks/filter-bar-active-filters.json +176 -0
- package/corpus/chunks/filter-bar-filter-bar-with-table.json +113 -0
- package/corpus/chunks/filter-bar-saved-views.json +117 -0
- package/corpus/chunks/filter-popover-form.json +137 -0
- package/corpus/chunks/footer-multi-column.json +270 -0
- package/corpus/chunks/footer-primary-only.json +41 -0
- package/corpus/chunks/form-checkbox-group.json +65 -0
- package/corpus/chunks/form-drawer-edit-form.json +178 -0
- package/corpus/chunks/form-drawer-simple-form.json +151 -0
- package/corpus/chunks/form-drawer-tall-form.json +325 -0
- package/corpus/chunks/form-field-email-hint.json +53 -0
- package/corpus/chunks/form-field-range.json +54 -0
- package/corpus/chunks/form-field-required.json +52 -0
- package/corpus/chunks/form-field-select.json +66 -0
- package/corpus/chunks/form-field-textarea.json +51 -0
- package/corpus/chunks/form-field-with-error.json +151 -0
- package/corpus/chunks/form-fields-two-column.json +69 -0
- package/corpus/chunks/form-page-shell.json +146 -0
- package/corpus/chunks/form-switch-toggle.json +41 -0
- package/corpus/chunks/form-system-live-demo.json +123 -0
- package/corpus/chunks/forms-address-autocomplete.json +277 -0
- package/corpus/chunks/forms-address-fields.json +221 -0
- package/corpus/chunks/forms-conditional-reveal.json +195 -0
- package/corpus/chunks/gallery-page-shell.json +444 -0
- package/corpus/chunks/grid-2col-entry-cards.json +140 -0
- package/corpus/chunks/grid-kpi-4col.json +164 -0
- package/corpus/chunks/grid-responsive-kpi.json +165 -0
- package/corpus/chunks/hero-cta-simple.json +107 -0
- package/corpus/chunks/hero-cta-split.json +183 -0
- package/corpus/chunks/hero-section-split.json +111 -0
- package/corpus/chunks/icon-text-row.json +60 -0
- package/corpus/chunks/image-caption-tile.json +99 -0
- package/corpus/chunks/image-carousel.json +156 -0
- package/corpus/chunks/image-thumbnail-grid.json +77 -0
- package/corpus/chunks/image-upload-preview.json +118 -0
- package/corpus/chunks/import-mapping-flow.json +972 -0
- package/corpus/chunks/inline-dialog-rename.json +128 -0
- package/corpus/chunks/inline-dialog-schedule.json +154 -0
- package/corpus/chunks/inline-dialog-status.json +179 -0
- package/corpus/chunks/integrations-api-keys-card-list.json +475 -0
- package/corpus/chunks/integrations-connect-form.json +550 -0
- package/corpus/chunks/integrations-grid.json +141 -0
- package/corpus/chunks/integrations-webhooks-empty-state.json +66 -0
- package/corpus/chunks/inventory-list-stock.json +137 -0
- package/corpus/chunks/invite-members.json +153 -0
- package/corpus/chunks/invoice-line-items.json +493 -0
- package/corpus/chunks/kanban-board-3col.json +713 -0
- package/corpus/chunks/kanban-page-shell.json +671 -0
- package/corpus/chunks/key-value-detail-list.json +242 -0
- package/corpus/chunks/keyboard-shortcut-display.json +250 -0
- package/corpus/chunks/labeled-textarea.json +45 -0
- package/corpus/chunks/leaderboard-table.json +140 -0
- package/corpus/chunks/library-browser-search-filter.json +109 -0
- package/corpus/chunks/linked-record-row.json +61 -0
- package/corpus/chunks/loading-skeleton-placeholder.json +387 -0
- package/corpus/chunks/login-form-card.json +207 -0
- package/corpus/chunks/logo-cloud-trusted-by.json +235 -0
- package/corpus/chunks/map-with-location-list.json +293 -0
- package/corpus/chunks/marketing-hero-cta.json +102 -0
- package/corpus/chunks/marketing-page-shell.json +352 -0
- package/corpus/chunks/masonry-gallery.json +154 -0
- package/corpus/chunks/member-edit-drawer.json +236 -0
- package/corpus/chunks/members-active-table-search-filter.json +184 -0
- package/corpus/chunks/members-pending-invites-cards.json +251 -0
- package/corpus/chunks/members-roles-permissions-list.json +146 -0
- package/corpus/chunks/menu-context-actions.json +113 -0
- package/corpus/chunks/metadata-description-list.json +178 -0
- package/corpus/chunks/modal-create-project-form.json +133 -0
- package/corpus/chunks/modal-preferences-tabs.json +147 -0
- package/corpus/chunks/multi-field-form-validation.json +394 -0
- package/corpus/chunks/nav-menu-icons.json +74 -0
- package/corpus/chunks/newsletter-subscription.json +190 -0
- package/corpus/chunks/notification-badges-feed.json +411 -0
- package/corpus/chunks/notification-preferences-panel.json +238 -0
- package/corpus/chunks/onb-completion.json +139 -0
- package/corpus/chunks/onb-extension-install.json +172 -0
- package/corpus/chunks/onb-hero-welcome.json +156 -0
- package/corpus/chunks/onb-import-picker.json +86 -0
- package/corpus/chunks/onb-mobile-handoff.json +121 -0
- package/corpus/chunks/onb-notification-prefs.json +83 -0
- package/corpus/chunks/onb-persona-picker.json +82 -0
- package/corpus/chunks/onb-provider-tiles.json +137 -0
- package/corpus/chunks/onb-settings-review.json +257 -0
- package/corpus/chunks/onb-step-footer.json +121 -0
- package/corpus/chunks/onb-step-header.json +121 -0
- package/corpus/chunks/onb-step-progress.json +140 -0
- package/corpus/chunks/onb-step-shell.json +380 -0
- package/corpus/chunks/onb-story-pane.json +121 -0
- package/corpus/chunks/onb-tutorial-steps.json +193 -0
- package/corpus/chunks/order-confirmation-success-card.json +177 -0
- package/corpus/chunks/order-tracking-timeline.json +131 -0
- package/corpus/chunks/pagination-controls.json +82 -0
- package/corpus/chunks/pane-settings-sidebar.json +204 -0
- package/corpus/chunks/patient-visit-shell.json +191 -0
- package/corpus/chunks/payment-checkout-form.json +341 -0
- package/corpus/chunks/payment-method-form.json +328 -0
- package/corpus/chunks/period-comparison.json +236 -0
- package/corpus/chunks/permission-matrix-table.json +438 -0
- package/corpus/chunks/permissions-matrix-grid.json +111 -0
- package/corpus/chunks/permissions-matrix-summary.json +157 -0
- package/corpus/chunks/permissions-role-picker-radio.json +107 -0
- package/corpus/chunks/permissions-role-picker-select.json +101 -0
- package/corpus/chunks/permissions-share-link.json +256 -0
- package/corpus/chunks/permissions-share-people.json +297 -0
- package/corpus/chunks/permissions-sharing-scopes.json +109 -0
- package/corpus/chunks/plan-selection-form.json +529 -0
- package/corpus/chunks/playground-a2ui.json +181 -0
- package/corpus/chunks/playground-agent-admin.json +117 -0
- package/corpus/chunks/playground-agent-chat.json +126 -0
- package/corpus/chunks/playground-app-shell.json +488 -0
- package/corpus/chunks/playground-chat.json +265 -0
- package/corpus/chunks/playground-construct-canvas.json +118 -0
- package/corpus/chunks/playground-css-channel.json +487 -0
- package/corpus/chunks/playground-gen-ui.json +224 -0
- package/corpus/chunks/playground-render-preview.json +369 -0
- package/corpus/chunks/playground-streams-bridge.json +437 -0
- package/corpus/chunks/playground-table-toolbar.json +38 -0
- package/corpus/chunks/popover-with-content.json +118 -0
- package/corpus/chunks/pricing-tiers.json +561 -0
- package/corpus/chunks/product-tour.json +158 -0
- package/corpus/chunks/profile-public.json +297 -0
- package/corpus/chunks/progress-tracker-milestones.json +294 -0
- package/corpus/chunks/radio-button-group.json +83 -0
- package/corpus/chunks/rating-stars-review-summary.json +259 -0
- package/corpus/chunks/reactions-bar.json +75 -0
- package/corpus/chunks/reactions-picker.json +245 -0
- package/corpus/chunks/real-time-metrics-dashboard.json +344 -0
- package/corpus/chunks/record-detail-drawer-simple-detail.json +296 -0
- package/corpus/chunks/record-detail-drawer-tabbed-detail.json +443 -0
- package/corpus/chunks/referral-share-link.json +128 -0
- package/corpus/chunks/referral-status.json +243 -0
- package/corpus/chunks/reg-address-form.json +825 -0
- package/corpus/chunks/reg-billing-card.json +210 -0
- package/corpus/chunks/reg-brand-scrape.json +599 -0
- package/corpus/chunks/reg-departments-toggle.json +259 -0
- package/corpus/chunks/reg-extended-profile.json +356 -0
- package/corpus/chunks/reg-final-done.json +457 -0
- package/corpus/chunks/reg-helpdesk-grid.json +571 -0
- package/corpus/chunks/reg-import-picker.json +112 -0
- package/corpus/chunks/reg-integrations-grid.json +418 -0
- package/corpus/chunks/reg-invite-form.json +245 -0
- package/corpus/chunks/reg-legal-entity.json +260 -0
- package/corpus/chunks/reg-org-chart-review.json +891 -0
- package/corpus/chunks/reg-profile-identity.json +188 -0
- package/corpus/chunks/reg-step-footer.json +201 -0
- package/corpus/chunks/reg-step-header.json +201 -0
- package/corpus/chunks/reg-step-progress.json +236 -0
- package/corpus/chunks/reg-step-shell.json +605 -0
- package/corpus/chunks/reg-story-pane.json +201 -0
- package/corpus/chunks/reg-success-summary.json +257 -0
- package/corpus/chunks/reg-team-size.json +128 -0
- package/corpus/chunks/reg-usecase-picker.json +104 -0
- package/corpus/chunks/reg-workspace-name.json +159 -0
- package/corpus/chunks/responsive-grid-pattern.json +71 -0
- package/corpus/chunks/responsive-kpi-grid.json +166 -0
- package/corpus/chunks/responsive-row-pattern.json +71 -0
- package/corpus/chunks/responsive-shell-sidebar.json +308 -0
- package/corpus/chunks/responsive-wrap-at-pattern.json +124 -0
- package/corpus/chunks/retention-cohort-default-retention.json +80 -0
- package/corpus/chunks/retention-cohort-stat-pair.json +163 -0
- package/corpus/chunks/retention-cohort-with-legend.json +135 -0
- package/corpus/chunks/revenue-heatmap.json +82 -0
- package/corpus/chunks/role-management.json +272 -0
- package/corpus/chunks/row-action-cluster.json +54 -0
- package/corpus/chunks/row-avatar-name-role.json +71 -0
- package/corpus/chunks/row-icon-label.json +52 -0
- package/corpus/chunks/row-spread-label-value.json +54 -0
- package/corpus/chunks/row-wrap-tags.json +72 -0
- package/corpus/chunks/schedule-meeting-form-card.json +229 -0
- package/corpus/chunks/search-recents-menu.json +195 -0
- package/corpus/chunks/search-results-grouped.json +357 -0
- package/corpus/chunks/search-results-list.json +202 -0
- package/corpus/chunks/search-saved-views.json +356 -0
- package/corpus/chunks/search-with-filters.json +311 -0
- package/corpus/chunks/searchable-picker-modal.json +164 -0
- package/corpus/chunks/section-with-stack.json +48 -0
- package/corpus/chunks/security-active-sessions-devices.json +287 -0
- package/corpus/chunks/security-change-password-form.json +102 -0
- package/corpus/chunks/security-delete-account-danger.json +79 -0
- package/corpus/chunks/segmented-control-billing-tabs.json +164 -0
- package/corpus/chunks/select-multiple-preselected.json +70 -0
- package/corpus/chunks/settings-2fa-setup.json +307 -0
- package/corpus/chunks/settings-admin-page.json +1205 -0
- package/corpus/chunks/settings-appearance-primitives.json +145 -0
- package/corpus/chunks/settings-appearance-theme-panel.json +55 -0
- package/corpus/chunks/settings-appearance.json +81 -0
- package/corpus/chunks/settings-danger-zone-delete-workspace.json +93 -0
- package/corpus/chunks/settings-general-form.json +69 -0
- package/corpus/chunks/settings-integrations.json +298 -0
- package/corpus/chunks/settings-members-invite.json +112 -0
- package/corpus/chunks/settings-notification-activity-checkboxes.json +108 -0
- package/corpus/chunks/settings-notification-channels-switches.json +101 -0
- package/corpus/chunks/settings-page-shell.json +190 -0
- package/corpus/chunks/settings-privacy.json +83 -0
- package/corpus/chunks/settings-profile-security.json +122 -0
- package/corpus/chunks/settings-toggle-switches.json +66 -0
- package/corpus/chunks/sidebar-nav.json +120 -0
- package/corpus/chunks/sidebar-navigation-panel.json +165 -0
- package/corpus/chunks/signup-form-card.json +218 -0
- package/corpus/chunks/signup-team-size-form.json +259 -0
- package/corpus/chunks/single-select-card-form.json +231 -0
- package/corpus/chunks/slider-range-controls.json +119 -0
- package/corpus/chunks/social-media-post-card.json +159 -0
- package/corpus/chunks/sortable-list.json +307 -0
- package/corpus/chunks/sortable-search-paginate-table.json +162 -0
- package/corpus/chunks/split-pane-editor.json +146 -0
- package/corpus/chunks/stack-avatar-badge-overlay.json +53 -0
- package/corpus/chunks/stack-image-shimmer.json +51 -0
- package/corpus/chunks/stat-cards-kpi-dashboard.json +178 -0
- package/corpus/chunks/stats-band-big-numbers.json +175 -0
- package/corpus/chunks/status-dashboard.json +282 -0
- package/corpus/chunks/stepper-form-wizard.json +165 -0
- package/corpus/chunks/subscription-status-renewal-card.json +285 -0
- package/corpus/chunks/survey-rating-form.json +165 -0
- package/corpus/chunks/swiper-product-carousel.json +349 -0
- package/corpus/chunks/swiper-testimonial-carousel.json +279 -0
- package/corpus/chunks/table-empty-state.json +116 -0
- package/corpus/chunks/table-inline-edit-row.json +269 -0
- package/corpus/chunks/table-spreadsheet-cells.json +334 -0
- package/corpus/chunks/table-toolbar-no-search.json +42 -0
- package/corpus/chunks/table-toolbar-with-table.json +208 -0
- package/corpus/chunks/table-with-toolbar-card.json +80 -0
- package/corpus/chunks/tabs-with-panels.json +187 -0
- package/corpus/chunks/tag-chips-filter.json +100 -0
- package/corpus/chunks/team-invite-form.json +380 -0
- package/corpus/chunks/team-members-list.json +341 -0
- package/corpus/chunks/testimonial-grid.json +269 -0
- package/corpus/chunks/testimonial-pull-quote.json +137 -0
- package/corpus/chunks/testimonials-avatar-cards.json +286 -0
- package/corpus/chunks/timeline-events.json +89 -0
- package/corpus/chunks/timezone-selector-basic.json +99 -0
- package/corpus/chunks/timezone-selector-preview.json +104 -0
- package/corpus/chunks/toolbar-icons.json +216 -0
- package/corpus/chunks/toolbar-rich-text-editor.json +230 -0
- package/corpus/chunks/toolbar-tooltips.json +191 -0
- package/corpus/chunks/tooltip-hover-button.json +106 -0
- package/corpus/chunks/tree-file-explorer.json +136 -0
- package/corpus/chunks/tree-table-basic.json +171 -0
- package/corpus/chunks/trial-banner.json +158 -0
- package/corpus/chunks/url-import-form.json +728 -0
- package/corpus/chunks/usage-quota-meter-card.json +217 -0
- package/corpus/chunks/user-identity-row.json +81 -0
- package/corpus/chunks/user-onboarding-checklist.json +301 -0
- package/corpus/chunks/user-profile-card.json +192 -0
- package/corpus/chunks/users-table-badge.json +135 -0
- package/corpus/chunks/verification-document-upload.json +179 -0
- package/corpus/chunks/verification-status.json +97 -0
- package/corpus/chunks/verification-stepper.json +111 -0
- package/corpus/chunks/video-player-controls.json +120 -0
- package/corpus/chunks/webhook-config.json +209 -0
- package/corpus/chunks/webhooks-list.json +204 -0
- package/corpus/chunks/wizard-drawer-three-step-wizard.json +443 -0
- package/corpus/manifest.d.ts +4 -0
- package/corpus/manifest.json +6 -0
- package/corpus/scripts/chunk-library.d.ts +4 -0
- package/corpus/scripts/chunk-library.js +335 -0
- package/node-shims.d.ts +48 -0
- package/package.json +215 -0
- package/retrieval/CHANGELOG.md +1073 -0
- package/retrieval/README.md +71 -0
- package/retrieval/anti-patterns.js +189 -0
- package/retrieval/authoring/index.d.ts +4 -0
- package/retrieval/authoring/index.js +9 -0
- package/retrieval/authoring/web-research.js +220 -0
- package/retrieval/catalog.js +250 -0
- package/retrieval/component-catalog.js +168 -0
- package/retrieval/component-entry.js +80 -0
- package/retrieval/context-assembler.js +174 -0
- package/retrieval/domain-router.js +417 -0
- package/retrieval/embedding/chunk-embedding-retriever.js +117 -0
- package/retrieval/embedding/embedding-provider.js +72 -0
- package/retrieval/embedding/index.d.ts +4 -0
- package/retrieval/embedding/index.js +2 -0
- package/retrieval/feedback/dialog-recorder.js +107 -0
- package/retrieval/feedback/feedback-analyzer.js +180 -0
- package/retrieval/feedback/feedback-store.js +194 -0
- package/retrieval/feedback/feedback.js +117 -0
- package/retrieval/feedback/gap-registry.js +80 -0
- package/retrieval/feedback/human-signal.js +113 -0
- package/retrieval/feedback/index.d.ts +4 -0
- package/retrieval/feedback/index.js +24 -0
- package/retrieval/feedback/submit-feedback.js +45 -0
- package/retrieval/index.d.ts +4 -0
- package/retrieval/index.js +53 -0
- package/retrieval/intent/clarity.js +139 -0
- package/retrieval/intent/decomposer.js +124 -0
- package/retrieval/intent/index.d.ts +4 -0
- package/retrieval/intent/index.js +18 -0
- package/retrieval/intent/intent-alignment.js +172 -0
- package/retrieval/intent/intent-categorizer.js +69 -0
- package/retrieval/intent/intent-gate.js +96 -0
- package/retrieval/intent/prompt-analyzer.js +162 -0
- package/retrieval/wiring-catalog.js +168 -0
- package/validate/catalog-validator.d.ts +4 -0
- package/validate/catalog-validator.js +327 -0
- package/validate/semantic/cache.js +54 -0
- package/validate/semantic/classify-intent.js +128 -0
- package/validate/semantic/index.js +163 -0
- package/validate/semantic/intent-specs.js +162 -0
- package/validate/semantic/judge.js +180 -0
|
@@ -0,0 +1,602 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* generate_ui — UI generation from natural language intent.
|
|
3
|
+
*
|
|
4
|
+
* Four modes:
|
|
5
|
+
* instant — pattern matching, no LLM (synchronous)
|
|
6
|
+
* pro — pattern search + LLM adaptation (async, blocking)
|
|
7
|
+
* thinking — A003 intelligence + LLM adapter (async, blocking)
|
|
8
|
+
* stream — same as thinking but yields progressive updates via async generator
|
|
9
|
+
*
|
|
10
|
+
* Multi-turn: pass executionId from a previous run to iterate on the same surface.
|
|
11
|
+
* The previous A2UI output is fed back as assistant context so the LLM can refine.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { validateSchema } from '@adia-ai/a2ui/validate';
|
|
15
|
+
import { getContext, searchBlocks, searchBlocksSemantic, lookupDomain, listPatterns } from './reference.js';
|
|
16
|
+
import { store, engine } from './state.js';
|
|
17
|
+
import { checkIntentAlignment } from '../../retrieval/intent/intent-alignment.js';
|
|
18
|
+
import { decomposeIntent, composeSubtasks } from '../../retrieval/intent/decomposer.js';
|
|
19
|
+
import { getWiringCatalog } from '../../retrieval/wiring-catalog.js';
|
|
20
|
+
|
|
21
|
+
import { StubLLMAdapter } from '@adia-ai/llm/stub';
|
|
22
|
+
import { createAdapter } from '@adia-ai/llm/bridge';
|
|
23
|
+
import { assessClarity } from '../../retrieval/intent/clarity.js';
|
|
24
|
+
import { isConversational } from '../../retrieval/intent/intent-gate.js';
|
|
25
|
+
import { classifyIntent } from '../../retrieval/domain-router.js';
|
|
26
|
+
import { researchIntent, detectReferences } from '../../retrieval/authoring/web-research.js';
|
|
27
|
+
import { feedbackStore } from '../../retrieval/feedback/feedback-store.js';
|
|
28
|
+
import { pick as pickEngine, registerMonolithicEngines } from '../strategies/registry.js';
|
|
29
|
+
import { analyzePrompt } from '../../retrieval/intent/prompt-analyzer.js';
|
|
30
|
+
import { recordTurn, isRecording } from '../../retrieval/feedback/dialog-recorder.js';
|
|
31
|
+
import {
|
|
32
|
+
buildSystemPrompt,
|
|
33
|
+
buildChatMessages,
|
|
34
|
+
tryParsePartial,
|
|
35
|
+
mergeCanvasDiff,
|
|
36
|
+
buildCanvasDiffPrompt,
|
|
37
|
+
parseA2UIResponse,
|
|
38
|
+
buildRepairPrompt,
|
|
39
|
+
generateSuggestions,
|
|
40
|
+
foldInAntiPatterns,
|
|
41
|
+
} from '../strategies/monolithic/_shared.js';
|
|
42
|
+
import { validateAndRepair } from '../shared/validate-and-repair.js';
|
|
43
|
+
import { generateInstant } from '../strategies/monolithic/generate-instant.js';
|
|
44
|
+
import { generatePro } from '../strategies/monolithic/generate-pro.js';
|
|
45
|
+
import { generateThinking } from '../strategies/monolithic/generate-thinking.js';
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Generate a UI surface from a natural language intent.
|
|
50
|
+
*
|
|
51
|
+
* @param {object} opts
|
|
52
|
+
* @param {string} opts.intent — Natural language intent
|
|
53
|
+
* @param {'instant'|'pro'|'thinking'|'stream'} [opts.mode='instant'] — Generation mode
|
|
54
|
+
* @param {string} [opts.executionId] — Existing execution ID (for multi-turn iteration)
|
|
55
|
+
* @param {object} [opts.currentCanvas] — Client-owned canvas state, enables
|
|
56
|
+
* stateless iteration. Shape is a discriminated union:
|
|
57
|
+
* { components: A2UIComponent[] } — flat component array
|
|
58
|
+
* { messages: A2UIMessage[] } — full message sequence
|
|
59
|
+
* When provided, the pipeline uses this as the iteration baseline instead
|
|
60
|
+
* of looking up prior turns in the ArtifactStore. This makes generation
|
|
61
|
+
* stateless — the client can iterate across server restarts, multiple tabs,
|
|
62
|
+
* or from a saved-canvas JSON file. Backward compatible: if omitted, the
|
|
63
|
+
* store lookup via `executionId` still works.
|
|
64
|
+
* @param {object} [opts.llmAdapter] — LLM adapter (defaults to auto-detected)
|
|
65
|
+
* @param {object} [opts.context] — Ontology context parsed by plan_app_state:
|
|
66
|
+
* the four-block shape { intent, domain, tasks, experience } validated by
|
|
67
|
+
* @adia-ai/mcp's gen-ui surface's ontologyContextSchema (REQ-03, gh#1208). Only
|
|
68
|
+
* domain.entities, domain.metrics, tasks.primary, experience.mode, and
|
|
69
|
+
* experience.shell are currently interpolated into the monolithic system
|
|
70
|
+
* prompt (strategies/monolithic/_shared.js); intent.* and tasks.inspection
|
|
71
|
+
* validate but are not yet read downstream (gh#1208 review finding 4/6).
|
|
72
|
+
* @returns {Promise<{ executionId: string, messages: object[], validation: object, suggestions: string[] }>}
|
|
73
|
+
*/
|
|
74
|
+
export async function generateUI({ intent, engine: engineName = 'monolithic', mode = 'instant', executionId, currentCanvas, llmAdapter, model, sessionId, context }) {
|
|
75
|
+
// Iteration signal: either an executionId (server-stateful path) OR a
|
|
76
|
+
// currentCanvas (client-stateless path). Both mean "refine existing UI".
|
|
77
|
+
const hasClientCanvas = !!(currentCanvas && (currentCanvas.components?.length || currentCanvas.messages?.length));
|
|
78
|
+
const isIteration = !!executionId || hasClientCanvas;
|
|
79
|
+
|
|
80
|
+
// ── Intent gate: reject non-UI prompts before entering the pipeline ──
|
|
81
|
+
// This prevents the LLM from hallucinating UIs from vague/abstract text.
|
|
82
|
+
// EXCEPTION: skip the gate on iteration turns. Modifiers like "make it 3D",
|
|
83
|
+
// "remove the avatar", "try a rose theme" rarely contain UI nouns the gate
|
|
84
|
+
// recognizes — they're refinements of the prior canvas, not fresh intents.
|
|
85
|
+
if (!isIteration) {
|
|
86
|
+
const classification = classifyIntent(intent);
|
|
87
|
+
const intentCheck = isConversational(intent, classification);
|
|
88
|
+
if (intentCheck.conversational) {
|
|
89
|
+
const clarity = assessClarity(intent, classification);
|
|
90
|
+
return {
|
|
91
|
+
executionId: executionId || 'rejected',
|
|
92
|
+
messages: [],
|
|
93
|
+
validation: { score: 0, valid: false, errors: [`Intent rejected: ${intentCheck.reason}`] },
|
|
94
|
+
suggestions: clarity.questions.map(q => q.text),
|
|
95
|
+
rejected: true,
|
|
96
|
+
reason: intentCheck.reason,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// For multi-turn: keep the old executionId for artifact history,
|
|
102
|
+
// but always start a fresh pipeline execution for stage tracking.
|
|
103
|
+
const previousExecId = executionId;
|
|
104
|
+
executionId = engine.start({ intent, mode, previousExecId });
|
|
105
|
+
|
|
106
|
+
// ── Engine dispatch (Phase 5) ──
|
|
107
|
+
// Zettel engine: single mode (instant), fragment-graph composition.
|
|
108
|
+
// Monolithic engine: three modes (instant | pro | thinking | stream→thinking).
|
|
109
|
+
// Analyzer is BASELINE for every reasoning level — every mode gets an LLM
|
|
110
|
+
// adapter (instant included). The analyzer call adds ~1-2s to the floor but
|
|
111
|
+
// the structured signals it produces (steelman, concepts, impliedComponents)
|
|
112
|
+
// dramatically improve downstream pattern retrieval and LLM generation
|
|
113
|
+
// quality. Adapter is always created upfront so all modes can analyze.
|
|
114
|
+
const effectiveMode = mode === 'stream' ? 'thinking' : mode;
|
|
115
|
+
const adapter = llmAdapter || await createAdapter({ model });
|
|
116
|
+
|
|
117
|
+
// ── Stage 0: Prompt Analysis (baseline ingestion) ──
|
|
118
|
+
// Extract structured signals from the raw prompt so every downstream stage
|
|
119
|
+
// — pattern search, concept-mapping retrieval, system prompt construction
|
|
120
|
+
// — reasons against an enriched brief instead of the raw text.
|
|
121
|
+
// Skipped on iteration turns where the user's modifier ("make it 3D") is
|
|
122
|
+
// most useful as-is for the LLM iteration prompt.
|
|
123
|
+
let analysis = null;
|
|
124
|
+
if (!isIteration) {
|
|
125
|
+
analysis = await analyzePrompt({ intent, llmAdapter: adapter });
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ── Normalize currentCanvas into a uniform priorComponents array ──
|
|
129
|
+
// Engines consume a single array; the shape union is collapsed here so
|
|
130
|
+
// engine code doesn't branch on input form.
|
|
131
|
+
let priorComponentsFromPayload = null;
|
|
132
|
+
if (hasClientCanvas) {
|
|
133
|
+
if (Array.isArray(currentCanvas.components)) {
|
|
134
|
+
priorComponentsFromPayload = currentCanvas.components;
|
|
135
|
+
} else if (Array.isArray(currentCanvas.messages)) {
|
|
136
|
+
priorComponentsFromPayload = currentCanvas.messages.flatMap(m => m?.components || []);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const fn = pickEngine({ engine: engineName, mode: effectiveMode });
|
|
141
|
+
const t0 = Date.now();
|
|
142
|
+
const result = await fn({
|
|
143
|
+
intent,
|
|
144
|
+
executionId,
|
|
145
|
+
storeId: previousExecId || executionId,
|
|
146
|
+
llmAdapter: adapter,
|
|
147
|
+
sessionId,
|
|
148
|
+
analysis,
|
|
149
|
+
priorComponentsFromPayload,
|
|
150
|
+
context, // Pass the ontology context to the engine
|
|
151
|
+
});
|
|
152
|
+
const totalMs = Date.now() - t0;
|
|
153
|
+
|
|
154
|
+
// ── Dialog recording (fire-and-forget, gated by ADIA_LOG_DIALOGS) ──
|
|
155
|
+
// Captures the entire turn — intent, analysis, system prompt, raw LLM
|
|
156
|
+
// response, parsed messages, validation, drift, telemetry — to disk for
|
|
157
|
+
// debugging, regression analysis, and training-data bootstrapping. The
|
|
158
|
+
// recorder no-ops when the env var is unset; the engine's _debug payload
|
|
159
|
+
// is also only populated when recording is on (see generate-pro.js).
|
|
160
|
+
if (isRecording()) {
|
|
161
|
+
const debug = result._debug || {};
|
|
162
|
+
// Anything the engine put on _debug beyond the canonical fields lands
|
|
163
|
+
// in engineDebug — useful for engine-specific reasoning (zettel strategy
|
|
164
|
+
// / composition / fragmentsUsed; instant patternName / strategy).
|
|
165
|
+
const { systemPrompt, rawLLMResponse, tokens, patterns, ...engineDebug } = debug;
|
|
166
|
+
recordTurn({
|
|
167
|
+
sessionId: previousExecId || result.executionId || null,
|
|
168
|
+
intent,
|
|
169
|
+
mode: effectiveMode,
|
|
170
|
+
engine: engineName,
|
|
171
|
+
model: model || null,
|
|
172
|
+
analysis,
|
|
173
|
+
currentCanvas: hasClientCanvas ? currentCanvas : null,
|
|
174
|
+
patterns: patterns || [],
|
|
175
|
+
systemPrompt: systemPrompt || null,
|
|
176
|
+
rawLLMResponse: rawLLMResponse || null,
|
|
177
|
+
messages: result.messages || [],
|
|
178
|
+
validation: result.validation || null,
|
|
179
|
+
drift: result.drift || null,
|
|
180
|
+
suggestions: result.suggestions || [],
|
|
181
|
+
timing: { totalMs },
|
|
182
|
+
tokens: tokens || null,
|
|
183
|
+
engineDebug: Object.keys(engineDebug).length ? engineDebug : null,
|
|
184
|
+
isIteration,
|
|
185
|
+
}).catch(() => { /* logger swallows internally; this is just last-resort */ });
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Strip the _debug payload before returning — it's an internal collaboration
|
|
189
|
+
// channel between engines and the recorder, not part of the public API.
|
|
190
|
+
// Without this strip the proxy would echo a 12KB+ system prompt to clients.
|
|
191
|
+
//
|
|
192
|
+
// Compose-trace flag: A2UI_COMPOSE_TRACE=<dir> writes the full debug payload
|
|
193
|
+
// (system prompt, raw LLM response, retrieval log, strategy decisions) to
|
|
194
|
+
// a per-request JSON file BEFORE the strip. Useful for debugging
|
|
195
|
+
// strategy-label decisions or reproducing eval failures. Off by default;
|
|
196
|
+
// file writes happen synchronously and add ~1-5ms per request.
|
|
197
|
+
//
|
|
198
|
+
// Node-only: `process` is undefined in the browser. Guard the env lookup
|
|
199
|
+
// so the post-await codepath doesn't throw `ReferenceError: process is
|
|
200
|
+
// not defined` when generator.js runs in the gen-ui playground. The
|
|
201
|
+
// dynamic node:fs/path imports below would also fail in the browser, but
|
|
202
|
+
// the guard short-circuits before we get there.
|
|
203
|
+
const IS_NODE = typeof process !== 'undefined' && process.versions?.node;
|
|
204
|
+
const traceDir = IS_NODE ? process.env.A2UI_COMPOSE_TRACE : null;
|
|
205
|
+
if (traceDir && result._debug) {
|
|
206
|
+
try {
|
|
207
|
+
const { writeFile, mkdir } = await import('node:fs/promises');
|
|
208
|
+
const { join: pathJoin } = await import('node:path');
|
|
209
|
+
await mkdir(traceDir, { recursive: true });
|
|
210
|
+
const ts = new Date().toISOString().replace(/[:.]/g, '-');
|
|
211
|
+
const safeIntent = String(intent || 'unknown').slice(0, 40).replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
212
|
+
const tracePath = pathJoin(traceDir, `${ts}-${engineName}-${safeIntent}.json`);
|
|
213
|
+
await writeFile(tracePath, JSON.stringify({
|
|
214
|
+
timestamp: ts,
|
|
215
|
+
intent,
|
|
216
|
+
engine: engineName,
|
|
217
|
+
mode: effectiveMode,
|
|
218
|
+
executionId: result.executionId,
|
|
219
|
+
strategy: result.strategy || null,
|
|
220
|
+
validation: result.validation || null,
|
|
221
|
+
messageCount: result.messages?.length || 0,
|
|
222
|
+
debug: result._debug,
|
|
223
|
+
}, null, 2));
|
|
224
|
+
} catch (err) {
|
|
225
|
+
// Tracing is diagnostic — never let it break the request path.
|
|
226
|
+
console.error('[compose:trace] failed to write trace:', err.message);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (result._debug) delete result._debug;
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Streaming UI generation — yields progressive events as the LLM generates.
|
|
235
|
+
*
|
|
236
|
+
* Events:
|
|
237
|
+
* { type: 'status', stage, message } — pipeline stage transition
|
|
238
|
+
* { type: 'clarify', questions, score, dimensions } — intent needs clarification (consumer should pause)
|
|
239
|
+
* { type: 'text_delta', text, snapshot } — raw LLM text chunk
|
|
240
|
+
* { type: 'partial', messages } — parseable partial A2UI (render immediately)
|
|
241
|
+
* { type: 'complete', messages, validation, suggestions, executionId } — final result
|
|
242
|
+
* { type: 'error', error } — generation error
|
|
243
|
+
*
|
|
244
|
+
* @param {object} opts
|
|
245
|
+
* @param {string} opts.intent
|
|
246
|
+
* @param {string} [opts.executionId]
|
|
247
|
+
* @param {object} [opts.llmAdapter]
|
|
248
|
+
* @param {(query: string) => Promise<{ results: { title: string, snippet: string, url: string }[] }>} [opts.search] — Web search function
|
|
249
|
+
* @param {object} [opts.context] — Ontology context parsed by plan_app_state:
|
|
250
|
+
* the four-block shape { intent, domain, tasks, experience } validated by
|
|
251
|
+
* @adia-ai/mcp's gen-ui surface's ontologyContextSchema (REQ-03, gh#1208). Only
|
|
252
|
+
* domain.entities, domain.metrics, tasks.primary, experience.mode, and
|
|
253
|
+
* experience.shell are currently interpolated into the monolithic system
|
|
254
|
+
* prompt (strategies/monolithic/_shared.js); intent.* and tasks.inspection
|
|
255
|
+
* validate but are not yet read downstream (gh#1208 review finding 4/6).
|
|
256
|
+
* @yields {object}
|
|
257
|
+
*/
|
|
258
|
+
export async function* generateUIStream({ intent, executionId, llmAdapter, model, search, currentCanvas, context }) {
|
|
259
|
+
// currentCanvas accepted for API parity with generateUI. The streaming
|
|
260
|
+
// path's downstream consumers don't yet read it, but parity prevents the
|
|
261
|
+
// client from having to branch its call shape per mode. Tier-2 will
|
|
262
|
+
// wire it through the same way generatePro does.
|
|
263
|
+
void currentCanvas;
|
|
264
|
+
// ── Intent gate: reject non-UI prompts before entering the pipeline ──
|
|
265
|
+
// Same iteration bypass as generateUI() — modifiers don't need to clear the
|
|
266
|
+
// conversational gate when there's a prior turn to refine.
|
|
267
|
+
const isIteration = !!executionId;
|
|
268
|
+
if (!isIteration) {
|
|
269
|
+
const classification = classifyIntent(intent);
|
|
270
|
+
const intentCheck = isConversational(intent, classification);
|
|
271
|
+
if (intentCheck.conversational) {
|
|
272
|
+
const clarity = assessClarity(intent, classification);
|
|
273
|
+
yield {
|
|
274
|
+
type: 'clarify',
|
|
275
|
+
questions: clarity.questions.length > 0
|
|
276
|
+
? clarity.questions
|
|
277
|
+
: [{ text: 'What would you like me to build?', dimension: 'domain', priority: 1 }],
|
|
278
|
+
score: clarity.score,
|
|
279
|
+
dimensions: clarity.dimensions,
|
|
280
|
+
summary: `Not a UI request (${intentCheck.reason}). ${clarity.summary}`,
|
|
281
|
+
rejected: true,
|
|
282
|
+
reason: intentCheck.reason,
|
|
283
|
+
};
|
|
284
|
+
return; // Do NOT continue to generation pipeline
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const adapter = llmAdapter || await createAdapter({ model });
|
|
289
|
+
// For multi-turn: keep the old executionId for artifact history lookup,
|
|
290
|
+
// but always start a fresh pipeline execution for stage tracking.
|
|
291
|
+
const previousExecId = executionId;
|
|
292
|
+
executionId = engine.start({ intent, mode: 'stream', previousExecId });
|
|
293
|
+
|
|
294
|
+
// ── Stage 1: Interpret ──
|
|
295
|
+
// Include confidence + matched signals in the status message so a reader can
|
|
296
|
+
// distinguish a strong domain match from a 3% tie-breaker. The bare label
|
|
297
|
+
// "Domain: data" is indistinguishable between "build a data dashboard" (high
|
|
298
|
+
// confidence, many signals) and "tier pricing page" (0.03 confidence, one
|
|
299
|
+
// weak signal) — same text, very different reliability.
|
|
300
|
+
const domain = lookupDomain(intent);
|
|
301
|
+
engine.submitStage(executionId, 'interpret', { domain, intent, confidence: domain.confidence });
|
|
302
|
+
const conf = domain.confidence != null ? Math.round(domain.confidence * 100) : null;
|
|
303
|
+
const signals = Array.isArray(domain.matchedSignals) && domain.matchedSignals.length
|
|
304
|
+
? domain.matchedSignals.slice(0, 4)
|
|
305
|
+
: null;
|
|
306
|
+
yield {
|
|
307
|
+
type: 'status',
|
|
308
|
+
stage: 'interpret',
|
|
309
|
+
message: `Domain: ${domain.domain}${conf != null ? ` (${conf}% confidence)` : ''}`,
|
|
310
|
+
outcomes: signals ? [`Matched signals: ${signals.join(', ')}`] : [],
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
// ── Clarity gate: yield clarify event if intent is vague ──
|
|
314
|
+
// Only for fresh intents (not multi-turn iterations which have prior context)
|
|
315
|
+
if (!previousExecId) {
|
|
316
|
+
const clarity = assessClarity(intent, domain);
|
|
317
|
+
if (!clarity.clear && clarity.questions.length > 0) {
|
|
318
|
+
yield {
|
|
319
|
+
type: 'clarify',
|
|
320
|
+
questions: clarity.questions,
|
|
321
|
+
score: clarity.score,
|
|
322
|
+
dimensions: clarity.dimensions,
|
|
323
|
+
summary: clarity.summary,
|
|
324
|
+
};
|
|
325
|
+
// The consumer decides whether to pause or continue.
|
|
326
|
+
// If they continue iterating, generation proceeds with what we have.
|
|
327
|
+
// If they stop iterating and re-submit with more detail, a new stream starts.
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// ── Stage 2: Analyze ──
|
|
332
|
+
// Surface the actual top-N retrieval candidates with scores. Two reasons the
|
|
333
|
+
// previous `${...patterns.length} patterns` line was misleading:
|
|
334
|
+
// (a) `getContext(intent, 2)` runs at tier=2, but the context-assembler
|
|
335
|
+
// only populates `result.patterns` at tier≥3 — so `context.patterns`
|
|
336
|
+
// was STRUCTURALLY empty. "0 patterns" wasn't a retrieval result; it
|
|
337
|
+
// was a tier mismatch. Fixed by running a fast keyword search here.
|
|
338
|
+
// (b) The synthesizer composes from below-threshold patterns too; "0
|
|
339
|
+
// patterns" reading as "nothing relevant" actively misleads the user.
|
|
340
|
+
const catalogContext = await getContext(intent, 2);
|
|
341
|
+
const topPatternsRaw = searchBlocks(intent).slice(0, 5);
|
|
342
|
+
const candidateLines = topPatternsRaw.length
|
|
343
|
+
? topPatternsRaw.map(p => {
|
|
344
|
+
const score = p.score != null ? ` · ${Number(p.score).toFixed(2)}` : '';
|
|
345
|
+
const domainTag = p.domain ? ` (${p.domain})` : '';
|
|
346
|
+
return ` • ${p.name}${domainTag}${score}`;
|
|
347
|
+
})
|
|
348
|
+
: [' (no keyword match — synthesizer will compose from components)'];
|
|
349
|
+
engine.submitStage(executionId, 'analyze', {
|
|
350
|
+
context: catalogContext, componentCount: catalogContext.components.length, patternCount: topPatternsRaw.length,
|
|
351
|
+
topPatterns: topPatternsRaw.map(p => ({ name: p.name, score: p.score, domain: p.domain })),
|
|
352
|
+
confidence: catalogContext.components.length > 0 ? 0.85 : 0.5,
|
|
353
|
+
});
|
|
354
|
+
yield {
|
|
355
|
+
type: 'status',
|
|
356
|
+
stage: 'analyze',
|
|
357
|
+
message: `${catalogContext.components.length} components inspected · ${topPatternsRaw.length} pattern candidate${topPatternsRaw.length === 1 ? '' : 's'}`,
|
|
358
|
+
outcomes: ['Top retrievals:', ...candidateLines],
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
// ── Research: web search enrichment (optional) ──
|
|
362
|
+
let researchContext = '';
|
|
363
|
+
const { references } = detectReferences(intent);
|
|
364
|
+
if (references.length > 0 || search) {
|
|
365
|
+
yield { type: 'status', stage: 'research', message: references.length > 0 ? `Researching: ${references.join(', ')}` : 'Searching for patterns...' };
|
|
366
|
+
try {
|
|
367
|
+
const research = await researchIntent(intent, { search, llmAdapter: adapter });
|
|
368
|
+
researchContext = research.context;
|
|
369
|
+
if (research.references.length > 0) {
|
|
370
|
+
yield { type: 'research', references: research.references, insights: research.insights };
|
|
371
|
+
}
|
|
372
|
+
} catch {
|
|
373
|
+
// Research failed — continue without it
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// ── Stage 3: Plan ──
|
|
378
|
+
// Use semantic search in LLM modes — feeds pattern index to LLM for conceptual matching
|
|
379
|
+
const { matches: patterns, remix: remixSuggestion } = await searchBlocksSemantic(intent, { llmAdapter: adapter, remix: true });
|
|
380
|
+
engine.submitStage(executionId, 'plan', {
|
|
381
|
+
patterns: patterns.map(p => p.name),
|
|
382
|
+
strategy: patterns.length > 0 ? 'adapt-pattern' : 'generate-fresh',
|
|
383
|
+
confidence: patterns.length > 0 ? 0.9 : 0.7,
|
|
384
|
+
hasRemix: !!remixSuggestion,
|
|
385
|
+
});
|
|
386
|
+
yield { type: 'status', stage: 'plan', message: patterns.length > 0 ? `Adapting: ${patterns[0].name}${remixSuggestion ? ' (with remix)' : ''}` : 'Generating fresh' };
|
|
387
|
+
|
|
388
|
+
// ── Decomposition: split complex intents into subtasks ──
|
|
389
|
+
// Skip decomposition when a pattern match exists — the pattern already handles composition
|
|
390
|
+
const decomposition = patterns.length === 0 ? decomposeIntent(intent) : { shouldDecompose: false, subtasks: [], layout: null, original: intent };
|
|
391
|
+
if (decomposition.shouldDecompose && decomposition.subtasks.length >= 3) {
|
|
392
|
+
yield { type: 'status', stage: 'decompose', message: `Splitting into ${decomposition.subtasks.length} subtasks: ${decomposition.subtasks.map(s => s.label).join(', ')}` };
|
|
393
|
+
yield { type: 'decompose', subtasks: decomposition.subtasks, layout: decomposition.layout };
|
|
394
|
+
|
|
395
|
+
// Generate each subtask independently
|
|
396
|
+
const subtaskResults = [];
|
|
397
|
+
for (const subtask of decomposition.subtasks) {
|
|
398
|
+
yield { type: 'status', stage: 'generate', message: `Generating: ${subtask.label}...` };
|
|
399
|
+
try {
|
|
400
|
+
const subResult = await adapter.complete({
|
|
401
|
+
messages: [{ role: 'user', content: subtask.intent }],
|
|
402
|
+
systemPrompt: await buildSystemPrompt(catalogContext, patterns, researchContext, intent, null, context),
|
|
403
|
+
});
|
|
404
|
+
const subMessages = parseA2UIResponse(subResult.content, { executionId, mode: 'stream', intent: subtask.intent });
|
|
405
|
+
subtaskResults.push({ label: subtask.label, messages: subMessages });
|
|
406
|
+
} catch {
|
|
407
|
+
// Failed subtask — skip it
|
|
408
|
+
subtaskResults.push({ label: subtask.label, messages: [{ type: 'updateComponents', surfaceId: 'default', components: [{ id: 'root', component: 'Text', variant: 'body', textContent: `${subtask.label} (generation failed)` }] }] });
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// Compose into layout
|
|
413
|
+
const composed = composeSubtasks(decomposition.layout, subtaskResults);
|
|
414
|
+
|
|
415
|
+
engine.submitStage(executionId, 'generate', {
|
|
416
|
+
messages: composed, source: 'decomposed', decomposed: true,
|
|
417
|
+
subtasks: decomposition.subtasks.length, confidence: 0.8,
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
const composedValidation = validateSchema(composed, { intent, context });
|
|
421
|
+
|
|
422
|
+
engine.submitStage(executionId, 'validate', {
|
|
423
|
+
...composedValidation, confidence: composedValidation.score / 100,
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
// Alignment check
|
|
427
|
+
const alignment = checkIntentAlignment(intent, composed[0]?.components || []);
|
|
428
|
+
|
|
429
|
+
const storeId = previousExecId || executionId;
|
|
430
|
+
store.record(storeId, { messages: composed, summary: intent, validation: composedValidation, intent });
|
|
431
|
+
engine.submitStage(executionId, 'render', { stored: true, decomposed: true, subtasks: decomposition.subtasks.length });
|
|
432
|
+
|
|
433
|
+
// Fire-and-forget feedback logging (decomposed stream)
|
|
434
|
+
feedbackStore.logExecution({
|
|
435
|
+
executionId: storeId, intent, mode: 'stream',
|
|
436
|
+
domain: domain.domain, patternMatch: null,
|
|
437
|
+
score: composedValidation?.score, componentCount: composed[0]?.components?.length || 0,
|
|
438
|
+
}).catch(() => {});
|
|
439
|
+
|
|
440
|
+
yield {
|
|
441
|
+
type: 'complete',
|
|
442
|
+
executionId: storeId,
|
|
443
|
+
messages: composed,
|
|
444
|
+
validation: composedValidation,
|
|
445
|
+
alignment,
|
|
446
|
+
suggestions: generateSuggestions(intent, domain, composed),
|
|
447
|
+
pipeline: engine.getState(executionId),
|
|
448
|
+
};
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// ── Stage 4: Generate via LLM stream ──
|
|
453
|
+
const systemPrompt = await buildSystemPrompt(catalogContext, patterns, researchContext, intent, null, context);
|
|
454
|
+
const chatMessages = buildChatMessages(intent, previousExecId || executionId);
|
|
455
|
+
|
|
456
|
+
yield { type: 'status', stage: 'generate', message: 'Streaming from LLM...' };
|
|
457
|
+
|
|
458
|
+
let fullText = '';
|
|
459
|
+
let lastPartialRender = '';
|
|
460
|
+
|
|
461
|
+
try {
|
|
462
|
+
if (typeof adapter.stream === 'function') {
|
|
463
|
+
for await (const chunk of adapter.stream({ messages: chatMessages, systemPrompt })) {
|
|
464
|
+
if (chunk.type === 'text') {
|
|
465
|
+
fullText += chunk.content;
|
|
466
|
+
yield { type: 'text_delta', text: chunk.content, snapshot: fullText };
|
|
467
|
+
|
|
468
|
+
// Try to parse partial JSON and render incrementally
|
|
469
|
+
const partial = tryParsePartial(fullText);
|
|
470
|
+
if (partial && JSON.stringify(partial) !== lastPartialRender) {
|
|
471
|
+
lastPartialRender = JSON.stringify(partial);
|
|
472
|
+
yield { type: 'partial', messages: partial };
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
} else {
|
|
477
|
+
// Fallback: non-streaming adapter
|
|
478
|
+
const response = await adapter.complete({ messages: chatMessages, systemPrompt });
|
|
479
|
+
fullText = response.content;
|
|
480
|
+
yield { type: 'text_delta', text: fullText, snapshot: fullText };
|
|
481
|
+
}
|
|
482
|
+
} catch (err) {
|
|
483
|
+
yield { type: 'error', error: err };
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// ── Stage 5: Parse final + validate ──
|
|
488
|
+
let messages = parseA2UIResponse(fullText, { executionId, mode: 'stream', intent });
|
|
489
|
+
engine.submitStage(executionId, 'generate', {
|
|
490
|
+
messages, source: 'llm-stream', confidence: 0.8,
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
// gh#583 (GK-3): this used to be a hand-rolled ONE-shot repair calling
|
|
494
|
+
// `adapter.complete()` directly and re-running only `validateSchema` — it
|
|
495
|
+
// never ran the catalog check, so a schema-valid-but-catalog-invalid
|
|
496
|
+
// candidate (unknown component, prop the YAML contract doesn't declare)
|
|
497
|
+
// could reach the wire from this streaming path alone, unlike every other
|
|
498
|
+
// engine (see validate-and-repair.js's docstring: this generator was the
|
|
499
|
+
// only one skipping it). Routing through the shared loop closes that gap
|
|
500
|
+
// and gets the same bounded multi-attempt retry every other LLM-calling
|
|
501
|
+
// engine already has, instead of exactly one attempt.
|
|
502
|
+
const repairResult = await validateAndRepair({
|
|
503
|
+
messages,
|
|
504
|
+
llmAdapter: adapter,
|
|
505
|
+
buildRepairPrompt,
|
|
506
|
+
parseResponse: (repairResponse) => parseA2UIResponse(
|
|
507
|
+
repairResponse.content,
|
|
508
|
+
{ executionId, mode: 'stream', intent },
|
|
509
|
+
),
|
|
510
|
+
systemPrompt,
|
|
511
|
+
validateContext: { intent, context },
|
|
512
|
+
foldInAntiPatterns,
|
|
513
|
+
maxAttempts: 3,
|
|
514
|
+
onAttempt: () => {
|
|
515
|
+
// No dialog-recorder hook here (unlike generate-thinking.js) — the
|
|
516
|
+
// streaming path already emits its own `text_delta`/`partial` events
|
|
517
|
+
// as the primary trace surface; adding a second capture point would
|
|
518
|
+
// duplicate, not improve, that record.
|
|
519
|
+
},
|
|
520
|
+
});
|
|
521
|
+
messages = repairResult.messages;
|
|
522
|
+
let validation = repairResult.validation;
|
|
523
|
+
if (repairResult.attempts > 0) {
|
|
524
|
+
yield { type: 'status', stage: 'validate', message: `Score ${validation.score}/100 — repaired in ${repairResult.attempts} attempt(s)` };
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
engine.submitStage(executionId, 'validate', {
|
|
528
|
+
...validation, confidence: validation.score / 100,
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
// ── Stage 6: Store artifact ──
|
|
532
|
+
// Store under the previous execution ID if iterating (keeps multi-turn history together)
|
|
533
|
+
const storeId = previousExecId || executionId;
|
|
534
|
+
store.record(storeId, { messages, summary: intent, validation, intent });
|
|
535
|
+
engine.submitStage(executionId, 'render', { stored: true, success: validation.valid, confidence: validation.valid ? 1 : 0.5 });
|
|
536
|
+
|
|
537
|
+
// ── Intent alignment check ──
|
|
538
|
+
const alignment = checkIntentAlignment(intent, messages[0]?.components || []);
|
|
539
|
+
|
|
540
|
+
const suggestions = generateSuggestions(intent, domain, messages);
|
|
541
|
+
|
|
542
|
+
// Fire-and-forget feedback logging (stream mode)
|
|
543
|
+
feedbackStore.logExecution({
|
|
544
|
+
executionId: storeId, intent, mode: 'stream',
|
|
545
|
+
domain: domain.domain, patternMatch: patterns[0]?.name,
|
|
546
|
+
score: validation?.score, componentCount: messages[0]?.components?.length || 0,
|
|
547
|
+
}).catch(() => {});
|
|
548
|
+
|
|
549
|
+
// ── Drift detection ──
|
|
550
|
+
const driftMetrics = store.getDriftMetrics(storeId);
|
|
551
|
+
|
|
552
|
+
yield {
|
|
553
|
+
type: 'complete',
|
|
554
|
+
executionId: storeId,
|
|
555
|
+
messages,
|
|
556
|
+
validation,
|
|
557
|
+
alignment,
|
|
558
|
+
drift: driftMetrics,
|
|
559
|
+
suggestions,
|
|
560
|
+
pipeline: engine.getState(executionId),
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// ── Pro mode (pattern-aware LLM adaptation) ─────────────────────────
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
568
|
+
// SYSTEM PROMPT (Feature 2: improved with card-ui rules)
|
|
569
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Build a concise system prompt for the LLM with component catalog,
|
|
573
|
+
* card-ui content model, layout rules, and example patterns.
|
|
574
|
+
*
|
|
575
|
+
* @param {object} context — Assembled context from A003
|
|
576
|
+
* @param {object[]} patterns — Matched patterns from pattern library
|
|
577
|
+
* @returns {string}
|
|
578
|
+
*/
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Get the shared artifact store (for external inspection).
|
|
582
|
+
* @returns {ArtifactStore}
|
|
583
|
+
*/
|
|
584
|
+
export function getArtifactStore() {
|
|
585
|
+
return store;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
* Get the shared pipeline engine (for external inspection).
|
|
590
|
+
* @returns {PipelineEngine}
|
|
591
|
+
*/
|
|
592
|
+
export function getPipelineEngine() {
|
|
593
|
+
return engine;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
// ── Register the three monolithic engines with the dispatcher ──
|
|
597
|
+
// Done at module load so the registry is ready before the first generateUI() call.
|
|
598
|
+
registerMonolithicEngines({
|
|
599
|
+
instant: generateInstant,
|
|
600
|
+
pro: generatePro,
|
|
601
|
+
thinking: generateThinking,
|
|
602
|
+
});
|