@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,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* free-form-composer — generative composition mode (§88, v0.4.8).
|
|
3
|
+
*
|
|
4
|
+
* The third generative path between verbatim retrieval (zettel's
|
|
5
|
+
* `composition-match`) and free-hand LLM generation (`monolithic-pro`).
|
|
6
|
+
*
|
|
7
|
+
* Treats the annotated-chunk corpus as an INGREDIENT VOCABULARY. The
|
|
8
|
+
* foundation model is given the catalog (28 chunks as of cut), declares
|
|
9
|
+
* an ordered list of ingredients + optional text-only substitutions, and
|
|
10
|
+
* the transpiler stitches a net-new A2UI tree that echoes the patterns
|
|
11
|
+
* the corpus documents without copying them verbatim.
|
|
12
|
+
*
|
|
13
|
+
* Grounding rule (v0.4.6 §62, carried forward): every ingredient name is
|
|
14
|
+
* an annotated chunk that traces to a real page via `data-chunk-*` markers.
|
|
15
|
+
* The strategy enforces this by rejecting any plan whose ingredient names
|
|
16
|
+
* aren't in the live `getAllCompositions()` result.
|
|
17
|
+
*
|
|
18
|
+
* Hallucination guard: one retry with explicit feedback ("you used X
|
|
19
|
+
* which isn't an ingredient"). If the retry still hallucinates, the
|
|
20
|
+
* strategy returns an empty-messages result with strategy label
|
|
21
|
+
* `free-form-hallucinated` so the upstream registry can fall through to
|
|
22
|
+
* monolithic-pro.
|
|
23
|
+
*
|
|
24
|
+
* No LLM available: returns `strategy='free-form-no-llm'` immediately;
|
|
25
|
+
* caller falls through.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import { getAllCompositions } from '../zettel/composition-library.js';
|
|
29
|
+
import {
|
|
30
|
+
buildFreeFormSystemPrompt,
|
|
31
|
+
buildFreeFormUserMessage,
|
|
32
|
+
buildFreeFormRetryMessage,
|
|
33
|
+
buildFreeFormParaphraseRetry,
|
|
34
|
+
} from './system-prompt.js';
|
|
35
|
+
import { transpilePlan, parsePlan } from './transpile.js';
|
|
36
|
+
import { validateAndRepair } from '../../shared/validate-and-repair.js';
|
|
37
|
+
|
|
38
|
+
const MAX_ATTEMPTS = 2;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Run the free-form composer for a single intent.
|
|
42
|
+
*
|
|
43
|
+
* @param {object} opts
|
|
44
|
+
* @param {string} opts.intent — user intent
|
|
45
|
+
* @param {object|null} opts.llmAdapter — LLM adapter with `.complete({messages, systemPrompt}) → {content, ...}`
|
|
46
|
+
* @param {object[]} [opts.compositions] — override vocabulary (test fixtures); defaults to live corpus
|
|
47
|
+
* @returns {Promise<{
|
|
48
|
+
* messages: object[],
|
|
49
|
+
* validation: { score: number, warnings?: string[] },
|
|
50
|
+
* strategy: string,
|
|
51
|
+
* plan: object|null,
|
|
52
|
+
* usedIngredients: string[],
|
|
53
|
+
* attempts: number,
|
|
54
|
+
* warnings: string[],
|
|
55
|
+
* rationale: string|null,
|
|
56
|
+
* }>}
|
|
57
|
+
*/
|
|
58
|
+
export async function generateFreeForm({ intent, llmAdapter = null, compositions = null } = {}) {
|
|
59
|
+
if (!intent || typeof intent !== 'string') {
|
|
60
|
+
return {
|
|
61
|
+
messages: [],
|
|
62
|
+
validation: { score: 0, warnings: ['empty or invalid intent'] },
|
|
63
|
+
strategy: 'free-form-bad-input',
|
|
64
|
+
plan: null,
|
|
65
|
+
usedIngredients: [],
|
|
66
|
+
attempts: 0,
|
|
67
|
+
warnings: ['empty or invalid intent'],
|
|
68
|
+
rationale: null,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const vocab = Array.isArray(compositions) ? compositions : getAllCompositions();
|
|
73
|
+
if (vocab.length === 0) {
|
|
74
|
+
return {
|
|
75
|
+
messages: [],
|
|
76
|
+
validation: { score: 0, warnings: ['empty vocabulary'] },
|
|
77
|
+
strategy: 'free-form-empty-vocab',
|
|
78
|
+
plan: null,
|
|
79
|
+
usedIngredients: [],
|
|
80
|
+
attempts: 0,
|
|
81
|
+
warnings: ['empty vocabulary: 0 annotated chunks available'],
|
|
82
|
+
rationale: null,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (!llmAdapter || typeof llmAdapter.complete !== 'function') {
|
|
87
|
+
return {
|
|
88
|
+
messages: [],
|
|
89
|
+
validation: { score: 0, warnings: ['no LLM adapter; free-form requires LLM'] },
|
|
90
|
+
strategy: 'free-form-no-llm',
|
|
91
|
+
plan: null,
|
|
92
|
+
usedIngredients: [],
|
|
93
|
+
attempts: 0,
|
|
94
|
+
warnings: ['free-form-composer requires an LLM adapter (mode=pro|thinking, not instant)'],
|
|
95
|
+
rationale: null,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const systemPrompt = buildFreeFormSystemPrompt(vocab);
|
|
100
|
+
const vocabNames = new Set(vocab.map(c => c.name));
|
|
101
|
+
const chunkLookup = new Map(vocab.map(c => [c.name, c]));
|
|
102
|
+
|
|
103
|
+
let userMessage = buildFreeFormUserMessage(intent);
|
|
104
|
+
let plan = null;
|
|
105
|
+
let invalidNames = [];
|
|
106
|
+
let emptyPlanRetryUsed = false;
|
|
107
|
+
let attempt = 0;
|
|
108
|
+
|
|
109
|
+
for (attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
|
|
110
|
+
let raw;
|
|
111
|
+
try {
|
|
112
|
+
const response = await llmAdapter.complete({
|
|
113
|
+
messages: [{ role: 'user', content: userMessage }],
|
|
114
|
+
systemPrompt,
|
|
115
|
+
});
|
|
116
|
+
raw = response?.content || '';
|
|
117
|
+
} catch (err) {
|
|
118
|
+
return {
|
|
119
|
+
messages: [],
|
|
120
|
+
validation: { score: 0, warnings: [`LLM call failed: ${err?.message || err}`] },
|
|
121
|
+
strategy: 'free-form-llm-error',
|
|
122
|
+
plan: null,
|
|
123
|
+
usedIngredients: [],
|
|
124
|
+
attempts: attempt,
|
|
125
|
+
warnings: [`LLM call failed on attempt ${attempt}: ${err?.message || err}`],
|
|
126
|
+
rationale: null,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const candidate = parsePlan(raw);
|
|
131
|
+
if (!candidate) {
|
|
132
|
+
// Parse-fail counts as a hallucination — retry once.
|
|
133
|
+
invalidNames = ['<parse-fail>'];
|
|
134
|
+
userMessage = `Compose a UI for: "${intent}"
|
|
135
|
+
|
|
136
|
+
Note: your previous response wasn't valid JSON. Output ONLY the JSON object — no prose, no fenced code block markers around it.`;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
invalidNames = candidate.ingredients
|
|
141
|
+
.filter(ing => !ing || typeof ing.name !== 'string' || !vocabNames.has(ing.name))
|
|
142
|
+
.map(ing => ing?.name ?? '<missing-name>');
|
|
143
|
+
|
|
144
|
+
if (invalidNames.length === 0) {
|
|
145
|
+
plan = candidate;
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Retry with explicit hallucination feedback.
|
|
150
|
+
userMessage = buildFreeFormRetryMessage(intent, invalidNames);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (!plan) {
|
|
154
|
+
return {
|
|
155
|
+
messages: [],
|
|
156
|
+
validation: { score: 0, warnings: [`hallucination guard tripped after ${MAX_ATTEMPTS} attempts; invalid: ${invalidNames.join(', ')}`] },
|
|
157
|
+
strategy: 'free-form-hallucinated',
|
|
158
|
+
plan: null,
|
|
159
|
+
usedIngredients: [],
|
|
160
|
+
attempts: MAX_ATTEMPTS,
|
|
161
|
+
warnings: [`exhausted ${MAX_ATTEMPTS} attempts; final invalid names: ${invalidNames.join(', ')}`],
|
|
162
|
+
rationale: null,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
let { messages, warnings, usedIngredients } = transpilePlan(plan, chunkLookup);
|
|
167
|
+
|
|
168
|
+
// §106 (v0.5.1): if the LLM declined to compose (`{ingredients: []}`),
|
|
169
|
+
// fire one paraphrase-retry with explicit shape-matching guidance. Many
|
|
170
|
+
// empty-plan cases on the v0.5.0 §104 eval were keyword-mismatch (chunk
|
|
171
|
+
// exists, intent uses different vocab). This retry is OUTSIDE the
|
|
172
|
+
// MAX_ATTEMPTS hallucination budget — one-shot reserve specifically for
|
|
173
|
+
// shape-match recovery.
|
|
174
|
+
if (messages.length === 0 && plan?.ingredients?.length === 0) {
|
|
175
|
+
emptyPlanRetryUsed = true;
|
|
176
|
+
const paraphraseMessage = buildFreeFormParaphraseRetry(intent);
|
|
177
|
+
try {
|
|
178
|
+
const response = await llmAdapter.complete({
|
|
179
|
+
messages: [{ role: 'user', content: paraphraseMessage }],
|
|
180
|
+
systemPrompt,
|
|
181
|
+
});
|
|
182
|
+
const retryPlan = parsePlan(response?.content || '');
|
|
183
|
+
const retryInvalid = retryPlan?.ingredients
|
|
184
|
+
?.filter(ing => !ing || typeof ing.name !== 'string' || !vocabNames.has(ing.name))
|
|
185
|
+
.map(ing => ing?.name ?? '<missing-name>') ?? [];
|
|
186
|
+
attempt += 1;
|
|
187
|
+
if (retryPlan && retryInvalid.length === 0 && retryPlan.ingredients.length > 0) {
|
|
188
|
+
plan = retryPlan;
|
|
189
|
+
const retryTranspile = transpilePlan(plan, chunkLookup);
|
|
190
|
+
messages = retryTranspile.messages;
|
|
191
|
+
warnings = retryTranspile.warnings;
|
|
192
|
+
usedIngredients = retryTranspile.usedIngredients;
|
|
193
|
+
}
|
|
194
|
+
} catch {
|
|
195
|
+
// Paraphrase-retry LLM failure — fall through to empty-plan.
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (messages.length === 0) {
|
|
200
|
+
return {
|
|
201
|
+
messages: [],
|
|
202
|
+
validation: { score: 0, warnings: warnings.concat(['transpile produced no messages']) },
|
|
203
|
+
strategy: 'free-form-empty-plan',
|
|
204
|
+
plan,
|
|
205
|
+
usedIngredients,
|
|
206
|
+
attempts: attempt,
|
|
207
|
+
warnings,
|
|
208
|
+
rationale: plan.rationale || null,
|
|
209
|
+
emptyPlanRetryUsed,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Full schema/catalog/anti-pattern conformance — the same final pass
|
|
214
|
+
// every other LLM-calling engine runs (see validate-and-repair.js).
|
|
215
|
+
// Validate-ONLY (no llmAdapter passed): a repair attempt here would mean
|
|
216
|
+
// re-authoring the ingredient PLAN, not the transpiled A2UI JSON
|
|
217
|
+
// directly — this engine's whole paradigm is ingredient selection +
|
|
218
|
+
// deterministic transpilation, not direct JSON authoring, so a schema-
|
|
219
|
+
// failure repair prompt has no natural target to hand back to the LLM.
|
|
220
|
+
// The existing hallucination-guard retry loop above (ingredient-name
|
|
221
|
+
// grounding) is this engine's own repair mechanism.
|
|
222
|
+
//
|
|
223
|
+
// REQ-05 (spec-factory-dx-ws4-acceptance): `validation.score` is now the
|
|
224
|
+
// MEASURED `schemaCheck.validation.score` — the verbatim 85 this engine
|
|
225
|
+
// reported on every success path (real validation ran, gh#pre-WS-4, but
|
|
226
|
+
// nothing read its score) made the release trip-wire's
|
|
227
|
+
// `avgScoreWhenEmitted` floor (`check-free-form-eval-regression.mjs`)
|
|
228
|
+
// tautological: it could only move when the pipeline broke outright.
|
|
229
|
+
// The floor itself is re-derived from the first honest run under
|
|
230
|
+
// a2ui-maintenance's ownership (preserve-not-regress cadence), not touched here.
|
|
231
|
+
// REQ-02: `validation.valid` is now first-class too — `judgeEngineResult`
|
|
232
|
+
// reads it for `free-form-composed` (a strong-emission strategy) instead
|
|
233
|
+
// of trusting the strategy label alone; `schemaValid`/`schemaValidation`
|
|
234
|
+
// stay as the pre-existing side fields for any consumer still reading them.
|
|
235
|
+
const schemaCheck = await validateAndRepair({ messages });
|
|
236
|
+
if (!schemaCheck.valid) {
|
|
237
|
+
warnings = warnings.concat([`schema/anti-pattern check failed (score ${schemaCheck.validation.score}): ${schemaCheck.validation.checks?.filter(c => !c.passed).map(c => c.name).join(', ') || 'see schemaValidation'}`]);
|
|
238
|
+
}
|
|
239
|
+
const score = schemaCheck.validation.score;
|
|
240
|
+
|
|
241
|
+
return {
|
|
242
|
+
messages,
|
|
243
|
+
validation: { score, valid: schemaCheck.valid, warnings },
|
|
244
|
+
strategy: 'free-form-composed',
|
|
245
|
+
plan,
|
|
246
|
+
usedIngredients,
|
|
247
|
+
attempts: attempt,
|
|
248
|
+
warnings,
|
|
249
|
+
rationale: plan.rationale || null,
|
|
250
|
+
emptyPlanRetryUsed,
|
|
251
|
+
schemaValid: schemaCheck.valid,
|
|
252
|
+
schemaValidation: schemaCheck.validation,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* system-prompt.js — builds the system prompt for free-form-composer.
|
|
3
|
+
*
|
|
4
|
+
* Treats the annotated-chunk corpus as an INGREDIENT VOCABULARY. The LLM
|
|
5
|
+
* sees a catalog of available ingredients with their domain + description +
|
|
6
|
+
* keywords, plus the per-ingredient SUBSTITUTABLE NODES (text-bearing
|
|
7
|
+
* primitives whose label / name / href the LLM can tailor per-intent),
|
|
8
|
+
* then outputs an ordered ingredient list + per-ingredient substitutions.
|
|
9
|
+
*
|
|
10
|
+
* The transpiler stitches the resulting plan into a net-new A2UI tree that
|
|
11
|
+
* echoes the chunks' shapes without copying them verbatim.
|
|
12
|
+
*
|
|
13
|
+
* Design choice: substitutions key on the chunk's INNER node IDs. Showing
|
|
14
|
+
* the IDs in the prompt makes the substitution surface explicit + grep-able.
|
|
15
|
+
* The transpiler's `SUBSTITUTABLE_ATTRS` map names which components are
|
|
16
|
+
* substitution-eligible + which attribute receives the value
|
|
17
|
+
* (Text.textContent, Button.text, Badge.text, Tag.text, Kbd.textContent,
|
|
18
|
+
* Icon.name, Image.alt, Link.href). v0.4.8 §88 shipped Text-only; v0.5.0
|
|
19
|
+
* §105 expanded to the seven listed.
|
|
20
|
+
*
|
|
21
|
+
* Vocabulary refresh cadence: the catalog is rebuilt from
|
|
22
|
+
* `composition-library.getAllCompositions()` on every prompt build —
|
|
23
|
+
* cheap (in-memory map of 64 entries today) and ensures the LLM sees the
|
|
24
|
+
* current corpus state without explicit cache invalidation.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { SUBSTITUTABLE_ATTRS } from './transpile.js';
|
|
28
|
+
|
|
29
|
+
const MAX_DESCRIPTION_LEN = 140;
|
|
30
|
+
const MAX_TEXT_PREVIEW = 60;
|
|
31
|
+
const MAX_SUBSTITUTABLES_PER_INGREDIENT = 8;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Extract substitutable nodes from a chunk template. Returns a compact
|
|
35
|
+
* `[{ id, attr, preview }]` array — the LLM uses `id` as the substitution
|
|
36
|
+
* key; `attr` names the target attribute (text / textContent / name /
|
|
37
|
+
* alt / href); `preview` is the current value truncated for prompt
|
|
38
|
+
* economy (empty string when the node carries no current value, which is
|
|
39
|
+
* common for Button.text / Badge.text / Icon.name in the corpus).
|
|
40
|
+
*
|
|
41
|
+
* @param {object[]} template — flat A2UI node list
|
|
42
|
+
* @returns {Array<{id: string, attr: string, preview: string}>}
|
|
43
|
+
*/
|
|
44
|
+
function extractSubstitutables(template) {
|
|
45
|
+
if (!Array.isArray(template)) return [];
|
|
46
|
+
const nodes = [];
|
|
47
|
+
for (const node of template) {
|
|
48
|
+
const attr = SUBSTITUTABLE_ATTRS[node?.component];
|
|
49
|
+
if (!attr) continue;
|
|
50
|
+
const raw = node[attr];
|
|
51
|
+
const value = typeof raw === 'string' ? raw : '';
|
|
52
|
+
const preview = value.length > MAX_TEXT_PREVIEW
|
|
53
|
+
? value.slice(0, MAX_TEXT_PREVIEW - 1) + '…'
|
|
54
|
+
: value;
|
|
55
|
+
nodes.push({ id: node.id, attr, preview });
|
|
56
|
+
}
|
|
57
|
+
return nodes;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Render a single ingredient as a prompt line. Format:
|
|
62
|
+
*
|
|
63
|
+
* - <name> (<domain>): <description (truncated)>
|
|
64
|
+
* keywords: a, b, c
|
|
65
|
+
* substitutables: title.textContent="Sign in"; submit.text; logo.alt="Adia Logo"
|
|
66
|
+
*
|
|
67
|
+
* Substitutables line is omitted when the chunk has zero substitutable
|
|
68
|
+
* nodes. Entries with a current value show `id.attr="..."`; entries
|
|
69
|
+
* without (Button/Icon nodes with no preset text/name) show just `id.attr`.
|
|
70
|
+
*/
|
|
71
|
+
function renderIngredient(c) {
|
|
72
|
+
const desc = (c.description || '').slice(0, MAX_DESCRIPTION_LEN);
|
|
73
|
+
const lines = [`- ${c.name} (${c.domain || 'general'}): ${desc}`];
|
|
74
|
+
if (Array.isArray(c.keywords) && c.keywords.length > 0) {
|
|
75
|
+
lines.push(` keywords: ${c.keywords.slice(0, 8).join(', ')}`);
|
|
76
|
+
}
|
|
77
|
+
const subs = extractSubstitutables(c.template);
|
|
78
|
+
if (subs.length > 0) {
|
|
79
|
+
const compact = subs
|
|
80
|
+
.slice(0, MAX_SUBSTITUTABLES_PER_INGREDIENT)
|
|
81
|
+
.map(s => s.preview ? `${s.id}.${s.attr}="${s.preview}"` : `${s.id}.${s.attr}`)
|
|
82
|
+
.join('; ');
|
|
83
|
+
lines.push(` substitutables: ${compact}`);
|
|
84
|
+
}
|
|
85
|
+
return lines.join('\n');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Build the system prompt. Caller passes the live `getAllCompositions()`
|
|
90
|
+
* result; this function doesn't import composition-library directly so the
|
|
91
|
+
* strategy entry point can pass test fixtures in unit tests.
|
|
92
|
+
*
|
|
93
|
+
* @param {object[]} compositions — output of `getAllCompositions()`
|
|
94
|
+
* @returns {string}
|
|
95
|
+
*/
|
|
96
|
+
export function buildFreeFormSystemPrompt(compositions) {
|
|
97
|
+
const ingredients = (compositions || []).slice().sort((a, b) => {
|
|
98
|
+
const da = a.domain || 'z'; const db = b.domain || 'z';
|
|
99
|
+
if (da !== db) return da < db ? -1 : 1;
|
|
100
|
+
return a.name < b.name ? -1 : 1;
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const catalog = ingredients.map(renderIngredient).join('\n\n');
|
|
104
|
+
const ingredientNames = ingredients.map(c => c.name).join(', ');
|
|
105
|
+
|
|
106
|
+
return `You are a UI composer for the AdiaUI design system. You work by picking INGREDIENTS — pre-built UI regions that have been annotated for retrieval — and arranging them in order to satisfy the user's intent.
|
|
107
|
+
|
|
108
|
+
You DO NOT write A2UI JSON directly. You output a PLAN: an ordered list of ingredient names plus optional text-content substitutions and an optional root container choice. A separate transpiler turns your plan into A2UI messages.
|
|
109
|
+
|
|
110
|
+
INGREDIENTS AVAILABLE (${ingredients.length}):
|
|
111
|
+
|
|
112
|
+
${catalog}
|
|
113
|
+
|
|
114
|
+
INTENT PARAPHRASE — vocabulary vs shape:
|
|
115
|
+
|
|
116
|
+
The user's intent often uses different vocabulary than the catalog's ingredient keywords. **Match on SHAPE — what the user wants to render — not exact keyword overlap.** Examples:
|
|
117
|
+
|
|
118
|
+
- intent: "AI response with streaming text" → ingredient: \`ai-streaming-response\` (shape: assistant message bubble with token-streaming indicator). The intent doesn't say "message bubble" but the shape is identical.
|
|
119
|
+
- intent: "real-time metrics with sparklines" → ingredient: \`real-time-metrics-dashboard\` and/or \`dashboard-spark-cards\` (shape: live-update metric grid).
|
|
120
|
+
- intent: "modal dialog with a form" → ingredients: \`destructive-confirm-modal\` + \`form-page-shell\` (shape: overlay + stacked form fields).
|
|
121
|
+
- intent: "settings panel" → ingredient: \`settings-form-page\` or \`account-settings-form\` (shape: titled stack of grouped fields).
|
|
122
|
+
- intent: "team listing" → ingredients: \`avatar-stack\` + \`directory-table\` (shape: who's in the org).
|
|
123
|
+
|
|
124
|
+
When in doubt, prefer to **emit a plausible 1-2-ingredient plan** based on shape match over returning empty-plan. Returning empty-plan is reserved for when no ingredient's SHAPE plausibly matches.
|
|
125
|
+
|
|
126
|
+
CONSTRAINTS:
|
|
127
|
+
|
|
128
|
+
1. Use ONLY ingredient names from the list above. Names not in the list are hallucinations — your response will be rejected if any \`name\` field is unknown.
|
|
129
|
+
2. Order your ingredients in the sequence they should appear in the rendered UI. The transpiler wraps your list in a root container — by default a vertical Column. Override via the optional \`layout\` field (see below).
|
|
130
|
+
3. Each ingredient may carry a \`substitutions\` object. KEYS are node IDs from the \`substitutables:\` line in the catalog above (e.g. \`"title"\`, \`"submit"\`, \`"logo"\`). VALUES are the new content strings. The transpiler routes each substitution to the right attribute based on the node's component: \`Text\` / \`Kbd\` → \`textContent\`; \`Button\` / \`Badge\` / \`Tag\` → \`text\`; \`Icon\` → \`name\`; \`Image\` → \`alt\`; \`Link\` → \`href\`. Nodes whose component is not in the substitutable list are locked at their declared values.
|
|
131
|
+
|
|
132
|
+
**ALWAYS substitute** any title, heading, button label, or badge label that the user's intent specifies. Default chunk text is generic placeholder ("Sign in to AdiaUI", "Continue", "Welcome back"); your job is to tailor it to the user's actual intent. Substituting MORE is better than substituting less — empty \`substitutions\` ships generic copy that misses the intent.
|
|
133
|
+
|
|
134
|
+
**Substitution examples per shape** (study these before emitting):
|
|
135
|
+
|
|
136
|
+
- **Text / Kbd (textContent)**: intent "trial-signup form for ContextEngine" → \`{"title": "Start your ContextEngine trial", "submit": "Create account"}\` not \`{}\`.
|
|
137
|
+
- **Button (text)**: intent "submit a support ticket" → \`{"submit-btn": "Open ticket"}\` not \`{"submit-btn": "Submit"}\`.
|
|
138
|
+
- **Badge / Tag (text)**: intent "show overdue invoices with status" → \`{"status-badge": "Overdue"}\` not \`{"status-badge": "Status"}\`.
|
|
139
|
+
- **Icon (name)**: intent "delete the project" → \`{"action-icon": "trash"}\` not omitting the icon substitution.
|
|
140
|
+
- **Image (alt)**: intent "team photo with three engineers" → \`{"hero-image": "Three engineers at a whiteboard"}\` not \`{}\`.
|
|
141
|
+
- **Link (href)**: intent "footer link to /docs/api" → \`{"docs-link": "/docs/api"}\` not \`{"docs-link": "#"}\`.
|
|
142
|
+
|
|
143
|
+
**Before emitting, self-check**: re-read the user's intent. Does it specify any content (text label, badge, icon, alt-text, URL)? If yes, every matching substitutable in your picked ingredients should appear in \`substitutions\`. If the intent is content-agnostic ("a sign-up form"), empty \`substitutions\` is correct.
|
|
144
|
+
4. If you can't satisfy the intent with the available ingredients, return \`{ "ingredients": [] }\` and a rationale explaining what's missing.
|
|
145
|
+
5. Output ONLY the JSON object below, no explanation outside the JSON.
|
|
146
|
+
|
|
147
|
+
LAYOUT (optional root container):
|
|
148
|
+
|
|
149
|
+
The transpiler stacks your ingredients inside a single root container. The default is \`Column\` (vertical stack). For horizontal or grid arrangements set \`layout\` to one of:
|
|
150
|
+
|
|
151
|
+
- \`"column"\` — vertical stack (default; omit \`layout\` for this shape). Use for: forms stacking fields, content sections stacking top-to-bottom, hero → features → footer pages.
|
|
152
|
+
- \`"row"\` — horizontal stack with automatic wrapping. Use for: nav items, inline button groups, small tag clusters, 2-3 cards side-by-side.
|
|
153
|
+
- \`"grid"\` — responsive grid. Use for: pricing tiers (3 cards), KPI dashboards (4 stat tiles), feature grids, image galleries, testimonial grids. Add an optional \`columns\` field with a string like \`"3"\`, \`"4"\`, or \`"auto-fill"\`; default is \`"auto-fill"\` (responsive density).
|
|
154
|
+
|
|
155
|
+
When the intent reads as "side by side" / "in a row" / "horizontally", pick \`"row"\`. When it reads as "grid of N" / "tiles" / "cards in columns", pick \`"grid"\`. When in doubt, omit \`layout\` and let the default Column apply.
|
|
156
|
+
|
|
157
|
+
OUTPUT SCHEMA (strict):
|
|
158
|
+
|
|
159
|
+
\`\`\`json
|
|
160
|
+
{
|
|
161
|
+
"ingredients": [
|
|
162
|
+
{
|
|
163
|
+
"name": "<one of: ${ingredientNames.length > 200 ? ingredientNames.slice(0, 200) + '… (see list above)' : ingredientNames}>",
|
|
164
|
+
"substitutions": { "<text-node-id>": "<new text>" }
|
|
165
|
+
}
|
|
166
|
+
],
|
|
167
|
+
"layout": "column" | "row" | "grid",
|
|
168
|
+
"columns": "<grid columns: number string '1'..'6' or 'auto-fill'>",
|
|
169
|
+
"rationale": "<one short sentence: why this arrangement>"
|
|
170
|
+
}
|
|
171
|
+
\`\`\`
|
|
172
|
+
|
|
173
|
+
The \`substitutions\`, \`layout\`, and \`columns\` fields are all optional.`;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Build the user message for an intent. Kept separate from system prompt
|
|
178
|
+
* so future iteration prompts can extend it (e.g. with prior-canvas diffs).
|
|
179
|
+
*/
|
|
180
|
+
export function buildFreeFormUserMessage(intent) {
|
|
181
|
+
return `Compose a UI for: "${intent}"`;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Build a retry user message that surfaces invalid ingredient names from a
|
|
186
|
+
* prior attempt. Called by the strategy entry point on hallucination.
|
|
187
|
+
*/
|
|
188
|
+
export function buildFreeFormRetryMessage(intent, invalidNames) {
|
|
189
|
+
const list = invalidNames.slice(0, 5).join(', ');
|
|
190
|
+
return `Compose a UI for: "${intent}"
|
|
191
|
+
|
|
192
|
+
Note: your previous response used ${invalidNames.length === 1 ? 'an ingredient name' : 'ingredient names'} that ${invalidNames.length === 1 ? "isn't" : "aren't"} in the catalog: ${list}. Use ONLY names from the INGREDIENTS list above, exactly as shown.`;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Build a paraphrase-retry user message for an empty-plan result. Used when
|
|
197
|
+
* the LLM returned a valid plan with `ingredients: []` — the keyword
|
|
198
|
+
* extraction didn't surface a shape match. The retry nudges the LLM toward
|
|
199
|
+
* shape-based reasoning rather than verbatim vocabulary lookup. §106 (v0.5.1).
|
|
200
|
+
*/
|
|
201
|
+
export function buildFreeFormParaphraseRetry(intent) {
|
|
202
|
+
return `Compose a UI for: "${intent}"
|
|
203
|
+
|
|
204
|
+
Note: your previous response was an empty plan. Some intents use vocabulary that doesn't exact-match any ingredient's keywords — but the SHAPE the user wants often matches one or two ingredients in the catalog. Re-read the INGREDIENTS list and identify the closest shape match (e.g. "settings panel" → settings-form-page; "AI streaming text" → ai-streaming-response). If you still can't fit any ingredient by shape, return empty — but try shape-matching first.`;
|
|
205
|
+
}
|