@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,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dual-environment chunk loader — Node + browser.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the dual-environment loading approach historically used by
|
|
5
|
+
* pattern-library.js (retired §64) so the gen-UI training chunks at
|
|
6
|
+
* packages/gen-ui/corpus/chunks/*.json are reachable from BOTH server-side
|
|
7
|
+
* engines (monolithic-pro via /api/generate's Node process) AND
|
|
8
|
+
* browser-side engines (monolithic-pro called directly from
|
|
9
|
+
* gen-ui playground's IIFE).
|
|
10
|
+
*
|
|
11
|
+
* The existing packages/gen-ui/corpus/scripts/chunk-library.js is Node-only
|
|
12
|
+
* (uses node:fs / readdirSync). This module exists so monolithic-pro can
|
|
13
|
+
* search + fetch chunks WITHOUT pulling node:fs into the browser bundle.
|
|
14
|
+
*
|
|
15
|
+
* Surface:
|
|
16
|
+
* - searchChunks(query, { kind, limit }): keyword-ranked chunk matches
|
|
17
|
+
* - getChunk(name): full chunk record by name
|
|
18
|
+
*
|
|
19
|
+
* Both are async because the browser path uses dynamic imports.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
const IS_NODE =
|
|
23
|
+
typeof process !== 'undefined' &&
|
|
24
|
+
typeof process.versions?.node === 'string';
|
|
25
|
+
|
|
26
|
+
// ── State ──────────────────────────────────────────────────────────
|
|
27
|
+
let _state = null; // { chunks: Map<name, record>, byKind: Map<kind, Set<name>> }
|
|
28
|
+
let _loadPromise = null;
|
|
29
|
+
|
|
30
|
+
// ── Browser glob ───────────────────────────────────────────────────
|
|
31
|
+
// Vite rewrites this CALL at transform time. On the static deploy (raw
|
|
32
|
+
// source, no Vite) the call hits the real `import.meta.glob` — which is
|
|
33
|
+
// undefined at runtime — and throws → caught → `_globModules` null → fetch
|
|
34
|
+
// branch. `import.meta.glob` is a compile-time macro, NOT a runtime
|
|
35
|
+
// function, so `typeof import.meta.glob` is undefined in BOTH Vite and
|
|
36
|
+
// static — the only reliable discriminator is whether this CALL yielded
|
|
37
|
+
// loaders. See composition-library.js for the full tri-mode rationale.
|
|
38
|
+
let _globModules = null;
|
|
39
|
+
if (!IS_NODE) {
|
|
40
|
+
try {
|
|
41
|
+
_globModules = import.meta.glob('../../../corpus/chunks/*.json', {
|
|
42
|
+
query: '?raw',
|
|
43
|
+
import: 'default',
|
|
44
|
+
});
|
|
45
|
+
} catch {
|
|
46
|
+
// No Vite transform here (static deploy) — fall back to the fetch branch.
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const HAS_VITE_GLOB =
|
|
50
|
+
!IS_NODE && !!_globModules && Object.keys(_globModules).length > 0;
|
|
51
|
+
|
|
52
|
+
// Relative-to-module corpus base for the static branch (same path the glob
|
|
53
|
+
// trusts; mount-point-independent). Verified 2026-06-10.
|
|
54
|
+
const _CORPUS_CHUNKS_BASE =
|
|
55
|
+
!IS_NODE && !HAS_VITE_GLOB
|
|
56
|
+
? new URL('../../../corpus/chunks/', import.meta.url)
|
|
57
|
+
: null;
|
|
58
|
+
|
|
59
|
+
// ── Public API ─────────────────────────────────────────────────────
|
|
60
|
+
async function _load() {
|
|
61
|
+
if (_state) return _state;
|
|
62
|
+
if (_loadPromise) return _loadPromise;
|
|
63
|
+
_loadPromise = (async () => {
|
|
64
|
+
if (IS_NODE) {
|
|
65
|
+
_state = await _loadNode();
|
|
66
|
+
} else if (HAS_VITE_GLOB) {
|
|
67
|
+
_state = await _loadBrowser();
|
|
68
|
+
} else {
|
|
69
|
+
_state = await _loadStatic();
|
|
70
|
+
}
|
|
71
|
+
return _state;
|
|
72
|
+
})();
|
|
73
|
+
return _loadPromise;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Static-browser loader — fetch `_index.json` for keyword scoring. The
|
|
78
|
+
* index carries name/kind/primary/nested/pages (everything `searchChunks`
|
|
79
|
+
* ranks on); chunk BODIES (html / template) are fetched lazily by
|
|
80
|
+
* `getChunk` so page-load is one request, not 339. Degrades to an empty
|
|
81
|
+
* corpus (not a throw) on fetch / parse failure.
|
|
82
|
+
*/
|
|
83
|
+
async function _loadStatic() {
|
|
84
|
+
const chunks = new Map();
|
|
85
|
+
const byKind = new Map();
|
|
86
|
+
if (!_CORPUS_CHUNKS_BASE) return { chunks, byKind };
|
|
87
|
+
let index;
|
|
88
|
+
try {
|
|
89
|
+
const res = await fetch(new URL('_index.json', _CORPUS_CHUNKS_BASE));
|
|
90
|
+
if (!res.ok) return { chunks, byKind };
|
|
91
|
+
index = await res.json();
|
|
92
|
+
} catch {
|
|
93
|
+
return { chunks, byKind };
|
|
94
|
+
}
|
|
95
|
+
const entries = Array.isArray(index?.chunks) ? index.chunks : [];
|
|
96
|
+
for (const entry of entries) {
|
|
97
|
+
if (!entry?.name) continue;
|
|
98
|
+
// Normalize the index entry to the per-chunk record shape `searchChunks`
|
|
99
|
+
// expects: `pages` (array) → `source`/`page` (string). `_bodyUrl` +
|
|
100
|
+
// `_hydrated` mark the record for lazy body-fetch in getChunk.
|
|
101
|
+
const rec = {
|
|
102
|
+
...entry,
|
|
103
|
+
source: Array.isArray(entry.pages) ? entry.pages[0] : (entry.source || entry.page || ''),
|
|
104
|
+
_bodyUrl: new URL(`${entry.name}.json`, _CORPUS_CHUNKS_BASE).href,
|
|
105
|
+
_hydrated: false,
|
|
106
|
+
};
|
|
107
|
+
chunks.set(rec.name, rec);
|
|
108
|
+
const kind = rec.kind || 'block';
|
|
109
|
+
if (!byKind.has(kind)) byKind.set(kind, new Set());
|
|
110
|
+
byKind.get(kind).add(rec.name);
|
|
111
|
+
}
|
|
112
|
+
return { chunks, byKind };
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async function _loadNode() {
|
|
116
|
+
const fs = await import(/* @vite-ignore */ 'node:fs/promises');
|
|
117
|
+
const path = await import(/* @vite-ignore */ 'node:path');
|
|
118
|
+
const url = await import(/* @vite-ignore */ 'node:url');
|
|
119
|
+
|
|
120
|
+
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
|
|
121
|
+
const chunksDir = path.resolve(__dirname, '..', '..', '..', 'corpus', 'chunks');
|
|
122
|
+
|
|
123
|
+
const chunks = new Map();
|
|
124
|
+
const byKind = new Map();
|
|
125
|
+
let entries;
|
|
126
|
+
try {
|
|
127
|
+
entries = await fs.readdir(chunksDir);
|
|
128
|
+
} catch {
|
|
129
|
+
return { chunks, byKind };
|
|
130
|
+
}
|
|
131
|
+
for (const file of entries) {
|
|
132
|
+
if (file === '_index.json' || !file.endsWith('.json')) continue;
|
|
133
|
+
try {
|
|
134
|
+
const raw = await fs.readFile(path.join(chunksDir, file), 'utf8');
|
|
135
|
+
const rec = JSON.parse(raw);
|
|
136
|
+
if (!rec?.name) continue;
|
|
137
|
+
chunks.set(rec.name, rec);
|
|
138
|
+
const kind = rec.kind || 'block';
|
|
139
|
+
if (!byKind.has(kind)) byKind.set(kind, new Set());
|
|
140
|
+
byKind.get(kind).add(rec.name);
|
|
141
|
+
} catch {
|
|
142
|
+
// Skip malformed chunks rather than fail the whole load
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return { chunks, byKind };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async function _loadBrowser() {
|
|
149
|
+
const chunks = new Map();
|
|
150
|
+
const byKind = new Map();
|
|
151
|
+
if (!_globModules) return { chunks, byKind };
|
|
152
|
+
|
|
153
|
+
await Promise.all(
|
|
154
|
+
Object.entries(_globModules).map(async ([path, loader]) => {
|
|
155
|
+
if (path.endsWith('/_index.json')) return;
|
|
156
|
+
try {
|
|
157
|
+
const raw = await loader();
|
|
158
|
+
const rec = JSON.parse(raw);
|
|
159
|
+
if (!rec?.name) return;
|
|
160
|
+
chunks.set(rec.name, rec);
|
|
161
|
+
const kind = rec.kind || 'block';
|
|
162
|
+
if (!byKind.has(kind)) byKind.set(kind, new Set());
|
|
163
|
+
byKind.get(kind).add(rec.name);
|
|
164
|
+
} catch {
|
|
165
|
+
// Skip malformed
|
|
166
|
+
}
|
|
167
|
+
})
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
return { chunks, byKind };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Keyword-rank chunks against a query. Mirrors the scoring shape of
|
|
175
|
+
* corpus/scripts/chunk-library.js so behavior is consistent regardless
|
|
176
|
+
* of which loader was used.
|
|
177
|
+
*
|
|
178
|
+
* Scoring (per chunk):
|
|
179
|
+
* +3 query word in name (exact part match)
|
|
180
|
+
* +2 query word in primary tag
|
|
181
|
+
* +1 query word in nested chunk name
|
|
182
|
+
* +1 query word in source page path
|
|
183
|
+
*
|
|
184
|
+
* @param {string} query — user intent
|
|
185
|
+
* @param {object} [opts] — { kind?: 'block'|'page'|'panel', limit?: number }
|
|
186
|
+
* @returns {Promise<Array<{ name, score, kind, primary, record }>>}
|
|
187
|
+
*/
|
|
188
|
+
export async function searchChunks(query, { kind, limit = 20 } = {}) {
|
|
189
|
+
if (!query || typeof query !== 'string') return [];
|
|
190
|
+
const { chunks } = await _load();
|
|
191
|
+
if (!chunks.size) return [];
|
|
192
|
+
|
|
193
|
+
const words = query.toLowerCase().split(/\s+/).filter((w) => w.length > 2);
|
|
194
|
+
if (!words.length) return [];
|
|
195
|
+
|
|
196
|
+
const candidates = [];
|
|
197
|
+
for (const [name, rec] of chunks) {
|
|
198
|
+
if (kind && rec.kind !== kind) continue;
|
|
199
|
+
let score = 0;
|
|
200
|
+
const nameLow = name.toLowerCase();
|
|
201
|
+
const primary = (rec.primary || '').toLowerCase();
|
|
202
|
+
const source = (rec.source || rec.page || '').toLowerCase();
|
|
203
|
+
const nested = (rec.nested || []).map((n) => n.toLowerCase());
|
|
204
|
+
|
|
205
|
+
for (const w of words) {
|
|
206
|
+
if (nameLow.includes(w)) score += 3;
|
|
207
|
+
if (primary && primary.includes(w)) score += 2;
|
|
208
|
+
for (const n of nested) {
|
|
209
|
+
if (n.includes(w)) {
|
|
210
|
+
score += 1;
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (source && source.includes(w)) score += 1;
|
|
215
|
+
}
|
|
216
|
+
if (score > 0) {
|
|
217
|
+
candidates.push({ name, score, kind: rec.kind, primary: rec.primary, record: rec });
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
candidates.sort((a, b) => b.score - a.score);
|
|
222
|
+
return candidates.slice(0, limit);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Fetch a chunk record by name.
|
|
227
|
+
* @param {string} name
|
|
228
|
+
* @returns {Promise<object|null>}
|
|
229
|
+
*/
|
|
230
|
+
export async function getChunk(name) {
|
|
231
|
+
if (!name) return null;
|
|
232
|
+
const { chunks } = await _load();
|
|
233
|
+
const rec = chunks.get(name) || null;
|
|
234
|
+
if (!rec) return null;
|
|
235
|
+
// Static-browser: the record came from `_index.json` (scoring fields only).
|
|
236
|
+
// Fetch + merge the full body (html / template / slots / attrs) on first
|
|
237
|
+
// access, then cache. No-op in Node / Vite (full record already loaded).
|
|
238
|
+
if (rec._bodyUrl && !rec._hydrated) {
|
|
239
|
+
try {
|
|
240
|
+
const res = await fetch(rec._bodyUrl);
|
|
241
|
+
if (res.ok) {
|
|
242
|
+
const body = await res.json();
|
|
243
|
+
Object.assign(rec, body);
|
|
244
|
+
}
|
|
245
|
+
} catch {
|
|
246
|
+
// Leave the scoring-only record; consumers must tolerate a missing body.
|
|
247
|
+
}
|
|
248
|
+
rec._hydrated = true; // don't retry on every access, even if the fetch failed
|
|
249
|
+
}
|
|
250
|
+
return rec;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Recursively expand a chunk's nested-chunk references into a flat array
|
|
255
|
+
* of chunk records. Useful for materializing the "full structural context"
|
|
256
|
+
* of a top-level chunk into a single prompt-injection payload.
|
|
257
|
+
*
|
|
258
|
+
* Cycle-safe: tracks visited names. Depth-limited to prevent runaway.
|
|
259
|
+
*
|
|
260
|
+
* @param {string|object} nameOrRecord
|
|
261
|
+
* @param {object} [opts] — { maxDepth?: 4 }
|
|
262
|
+
* @returns {Promise<Array<object>>} — flat list of resolved chunk records, root first
|
|
263
|
+
*/
|
|
264
|
+
export async function expandChunkGraph(nameOrRecord, { maxDepth = 4 } = {}) {
|
|
265
|
+
const visited = new Set();
|
|
266
|
+
const out = [];
|
|
267
|
+
|
|
268
|
+
async function walk(item, depth) {
|
|
269
|
+
if (depth > maxDepth) return;
|
|
270
|
+
const rec = typeof item === 'string' ? await getChunk(item) : item;
|
|
271
|
+
if (!rec || visited.has(rec.name)) return;
|
|
272
|
+
visited.add(rec.name);
|
|
273
|
+
out.push(rec);
|
|
274
|
+
|
|
275
|
+
for (const childName of rec.nested || []) {
|
|
276
|
+
await walk(childName, depth + 1);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
await walk(nameOrRecord, 0);
|
|
281
|
+
return out;
|
|
282
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/** The engine context registry.js's adapters take. */
|
|
2
|
+
export interface EngineContext {
|
|
3
|
+
intent: string;
|
|
4
|
+
executionId?: string;
|
|
5
|
+
storeId?: string | null;
|
|
6
|
+
llmAdapter?: unknown;
|
|
7
|
+
sessionId?: string | null;
|
|
8
|
+
analysis?: unknown;
|
|
9
|
+
priorComponentsFromPayload?: unknown[] | null;
|
|
10
|
+
context?: unknown;
|
|
11
|
+
model?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface CascadeOptions {
|
|
15
|
+
/** Engine names, cheapest first. Defaults to ENGINE_LADDER. */
|
|
16
|
+
ladder?: string[];
|
|
17
|
+
/** Extra async accept check for a result the escalation rule accepted. */
|
|
18
|
+
gate?: (result: any, ctx: EngineContext) => boolean | Promise<boolean>;
|
|
19
|
+
name?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface CascadeAttempt {
|
|
23
|
+
step: string;
|
|
24
|
+
accepted: boolean;
|
|
25
|
+
result: any;
|
|
26
|
+
/** The verdict code that rejected this attempt — a `judgeEngineResult`
|
|
27
|
+
* feedback code, or `'gate-rejected'` from the workflow exit gate. */
|
|
28
|
+
reason?: string;
|
|
29
|
+
detail?: string;
|
|
30
|
+
data?: unknown;
|
|
31
|
+
round: number;
|
|
32
|
+
gateRejected?: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface CascadeOutcome {
|
|
36
|
+
result: any;
|
|
37
|
+
step: string | null;
|
|
38
|
+
accepted: boolean;
|
|
39
|
+
attempts: CascadeAttempt[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface Escalation {
|
|
43
|
+
from: string;
|
|
44
|
+
to: string;
|
|
45
|
+
trigger: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const ENGINE_LADDER: string[];
|
|
49
|
+
|
|
50
|
+
export function defineCascade(opts?: CascadeOptions): {
|
|
51
|
+
name: string;
|
|
52
|
+
steps: Array<{
|
|
53
|
+
name: string;
|
|
54
|
+
run: (ctx: any) => any;
|
|
55
|
+
until?: (result: any, ctx: any) => { accepted: boolean; reason?: string; detail?: string; data?: unknown };
|
|
56
|
+
}>;
|
|
57
|
+
/** Present only when a `gate` was supplied — the workflow-level exit gate
|
|
58
|
+
* every non-terminal accepted result passes through. */
|
|
59
|
+
exitGate?: (result: any, ctx: any) => Promise<{ accepted: boolean; reason?: string }>;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export function runCascade(
|
|
63
|
+
ctx: EngineContext,
|
|
64
|
+
opts?: CascadeOptions & { emit?: (event: unknown) => void },
|
|
65
|
+
): Promise<CascadeOutcome>;
|
|
66
|
+
|
|
67
|
+
export function escalationsOf(outcome: CascadeOutcome): Escalation[];
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The engine escalation ladder, declared as an `@adia-ai/agent` workflow
|
|
3
|
+
* (gh#664).
|
|
4
|
+
*
|
|
5
|
+
* zettel → free-form → monolithic-instant → monolithic-pro, cheapest first,
|
|
6
|
+
* each step's `until` predicate carrying the escalation rule
|
|
7
|
+
* (`escalation.js`'s `accepts`) and the last step terminal. The ladder is
|
|
8
|
+
* DATA — `ENGINE_LADDER` — so a consumer can read the order without running
|
|
9
|
+
* it, and the harness's `WorkflowResult.attempts` is the escalation trace.
|
|
10
|
+
*
|
|
11
|
+
* Reserved engine names (registry.js's `RESERVED`) are the step names
|
|
12
|
+
* verbatim: a step IS the engine, never a reinterpretation of it. Engines
|
|
13
|
+
* are resolved out of `ENGINES` at RUN time, not at module load, so a
|
|
14
|
+
* `registerMonolithicEngines()` that happens later (core/generator.js does
|
|
15
|
+
* it at ITS load) still wires up.
|
|
16
|
+
*
|
|
17
|
+
* The optional `gate` — an async accept check the caller supplies, e.g. the
|
|
18
|
+
* schema + catalog exit gate — runs after the strategy rule for a step that
|
|
19
|
+
* would otherwise be accepted. That is why the harness's `until` had to
|
|
20
|
+
* become awaitable (gh#664 contract change): the real acceptance test for a
|
|
21
|
+
* generated surface reads catalog JSON off disk.
|
|
22
|
+
*
|
|
23
|
+
* gh#665: the gate is no longer restated inside every step's `until` — it
|
|
24
|
+
* is declared ONCE as the workflow's `exitGate`, the seam the harness grew
|
|
25
|
+
* for exactly this. The ladder's floor keeps its floor property: a terminal
|
|
26
|
+
* step (no `until`) is not exit-gated, matching the pre-harness cascades,
|
|
27
|
+
* which returned monolithic-pro's output whatever it was. Rejections now
|
|
28
|
+
* carry a REASON (`judgeEngineResult`'s feedback code, or `gate-rejected`)
|
|
29
|
+
* on the attempt, so `escalationsOf` reads the recorded trigger instead of
|
|
30
|
+
* recomputing it.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import { defineWorkflow, runWorkflow } from '@adia-ai/agent';
|
|
34
|
+
|
|
35
|
+
import { ENGINES } from './registry.js';
|
|
36
|
+
import { judgeEngineResult } from './escalation.js';
|
|
37
|
+
|
|
38
|
+
/** The ladder, cheapest tier first. Names are reserved engine names. */
|
|
39
|
+
export const ENGINE_LADDER = ['zettel', 'free-form', 'monolithic-instant', 'monolithic-pro'];
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {string} name
|
|
43
|
+
* @param {import('@adia-ai/agent').WorkflowContext} wctx — the harness
|
|
44
|
+
* context: `input` is what the run is ABOUT (intent, prior components),
|
|
45
|
+
* `services` is what it may USE (the LLM adapter). Engines still take one
|
|
46
|
+
* flat ctx, so this is where the two channels are recombined; the adapter
|
|
47
|
+
* falls back to `input.llmAdapter` for a caller that hasn't moved yet.
|
|
48
|
+
*/
|
|
49
|
+
function runEngine(name, wctx) {
|
|
50
|
+
const fn = ENGINES[name];
|
|
51
|
+
if (typeof fn !== 'function') {
|
|
52
|
+
throw new Error(`cascade: ENGINES["${name}"] is not registered`);
|
|
53
|
+
}
|
|
54
|
+
const ctx = wctx.input;
|
|
55
|
+
return fn({
|
|
56
|
+
intent: ctx.intent,
|
|
57
|
+
executionId: ctx.executionId,
|
|
58
|
+
storeId: ctx.storeId ?? ctx.executionId,
|
|
59
|
+
llmAdapter: wctx.services?.llmAdapter ?? ctx.llmAdapter ?? null,
|
|
60
|
+
sessionId: ctx.sessionId,
|
|
61
|
+
analysis: ctx.analysis ?? null,
|
|
62
|
+
priorComponentsFromPayload: ctx.priorComponentsFromPayload ?? null,
|
|
63
|
+
context: ctx.context,
|
|
64
|
+
model: ctx.model,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Build the cascade workflow.
|
|
70
|
+
*
|
|
71
|
+
* @param {object} [opts]
|
|
72
|
+
* @param {string[]} [opts.ladder=ENGINE_LADDER] — engine names, cheapest first.
|
|
73
|
+
* @param {(result: object, ctx: object) => boolean | Promise<boolean>} [opts.gate]
|
|
74
|
+
* — extra accept check for a step the strategy rule already accepted
|
|
75
|
+
* (the schema + catalog exit gate lives here).
|
|
76
|
+
* @param {string} [opts.name='generate-ui']
|
|
77
|
+
*/
|
|
78
|
+
export function defineCascade({ ladder = ENGINE_LADDER, gate, name = 'generate-ui' } = {}) {
|
|
79
|
+
const steps = ladder.map((engineName, i) => {
|
|
80
|
+
const terminal = i === ladder.length - 1;
|
|
81
|
+
return {
|
|
82
|
+
name: engineName,
|
|
83
|
+
run: (ctx) => runEngine(engineName, ctx),
|
|
84
|
+
// The terminal step is the ladder's floor: its result is returned
|
|
85
|
+
// whatever it is, exactly as the pre-harness cascades did when
|
|
86
|
+
// monolithic-pro was reached. Omitting `until` is how the harness
|
|
87
|
+
// spells that — and it also exempts the floor from the exit gate.
|
|
88
|
+
...(terminal ? {} : {
|
|
89
|
+
// The strategy rule, as a VERDICT: the feedback code that made the
|
|
90
|
+
// ladder climb travels with the attempt (gh#665) instead of being
|
|
91
|
+
// recomputed downstream.
|
|
92
|
+
until: (result) => {
|
|
93
|
+
const judged = judgeEngineResult(result);
|
|
94
|
+
return judged.ok
|
|
95
|
+
? { accepted: true }
|
|
96
|
+
: {
|
|
97
|
+
accepted: false,
|
|
98
|
+
reason: judged.feedback[0]?.code ?? 'rejected',
|
|
99
|
+
detail: judged.feedback[0]?.message,
|
|
100
|
+
data: judged.feedback,
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
}),
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
return defineWorkflow(name, steps, gate
|
|
107
|
+
? {
|
|
108
|
+
exitGate: async (result, ctx) => {
|
|
109
|
+
const passed = !!(await gate(result, ctx.input));
|
|
110
|
+
return passed ? { accepted: true } : { accepted: false, reason: 'gate-rejected' };
|
|
111
|
+
},
|
|
112
|
+
}
|
|
113
|
+
: {});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Run the ladder once for one intent.
|
|
118
|
+
*
|
|
119
|
+
* @param {object} ctx — the engine context registry.js's adapters take:
|
|
120
|
+
* `{ intent, executionId, storeId, llmAdapter, sessionId, analysis,
|
|
121
|
+
* priorComponentsFromPayload, context, model }`
|
|
122
|
+
* @param {object} [opts] — `defineCascade` options, plus:
|
|
123
|
+
* @param {(event: object) => void} [opts.emit] — step events.
|
|
124
|
+
* @returns {Promise<import('@adia-ai/agent').WorkflowResult>} — `result` is
|
|
125
|
+
* the winning engine's own result shape; `step` is the engine that won;
|
|
126
|
+
* `attempts` is the full escalation trace.
|
|
127
|
+
*/
|
|
128
|
+
export async function runCascade(ctx, opts = {}) {
|
|
129
|
+
const { emit, ...defineOpts } = opts;
|
|
130
|
+
return runWorkflow(defineCascade(defineOpts), {
|
|
131
|
+
input: ctx,
|
|
132
|
+
// The dependency the ladder USES, on the channel that means "may use"
|
|
133
|
+
// (gh#665). `input` still carries it too, so an engine context assembled
|
|
134
|
+
// by an older caller keeps working.
|
|
135
|
+
services: { llmAdapter: ctx.llmAdapter ?? null },
|
|
136
|
+
sessionId: ctx.sessionId ?? ctx.executionId ?? 'cascade',
|
|
137
|
+
...(emit ? { emit } : {}),
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* The escalation trace in the `{from, to, trigger}` shape trace-rendering
|
|
143
|
+
* consumers already speak (handleAuto.js's reasoning strip).
|
|
144
|
+
*
|
|
145
|
+
* The trigger is the REASON the rejecting verdict recorded (gh#665) — no
|
|
146
|
+
* longer re-judged here, so a gate rejection reads as `gate-rejected`
|
|
147
|
+
* because that is what happened, not because re-judging found nothing else.
|
|
148
|
+
* The re-judge survives only as the fallback for an attempt produced by a
|
|
149
|
+
* boolean-returning predicate, which records no reason.
|
|
150
|
+
*
|
|
151
|
+
* @param {import('@adia-ai/agent').WorkflowResult} outcome
|
|
152
|
+
*/
|
|
153
|
+
export function escalationsOf(outcome) {
|
|
154
|
+
const out = [];
|
|
155
|
+
for (let i = 0; i < outcome.attempts.length - 1; i++) {
|
|
156
|
+
const from = outcome.attempts[i];
|
|
157
|
+
const to = outcome.attempts[i + 1];
|
|
158
|
+
out.push({
|
|
159
|
+
from: from.step,
|
|
160
|
+
to: to.step,
|
|
161
|
+
trigger: from.reason ?? judgeEngineResult(from.result).feedback?.[0]?.code ?? 'rejected',
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
return out;
|
|
165
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface EngineFeedback {
|
|
2
|
+
code: 'no-emission' | 'non-emission-strategy' | 'schema-invalid' | 'strong-emission-invalid';
|
|
3
|
+
message: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export type EngineVerdict =
|
|
7
|
+
| { ok: true }
|
|
8
|
+
| { ok: false; feedback: EngineFeedback[] };
|
|
9
|
+
|
|
10
|
+
export function isNonEmissionStrategy(strategy: string | undefined): boolean;
|
|
11
|
+
export function isStrongEmissionStrategy(strategy: string | undefined): boolean;
|
|
12
|
+
export function judgeEngineResult(result: unknown): EngineVerdict;
|
|
13
|
+
export function accepts(result: unknown): boolean;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Escalation rules — the ONE answer to "did this engine's attempt count as
|
|
3
|
+
* a hit, or should the ladder climb?"
|
|
4
|
+
*
|
|
5
|
+
* The rules used to live in `@genui/adia-producer/outcome-to-verdict.js`
|
|
6
|
+
* (gh#583), one layer above compose, even though every fact they read
|
|
7
|
+
* (`strategy` labels, the uniform `{messages, validation}` result shape) is
|
|
8
|
+
* authored HERE by `strategies/registry.js`'s adapters. gh#664 moves them
|
|
9
|
+
* down to the layer that owns the shape: compose's own cascade
|
|
10
|
+
* (`strategies/cascade.js`) and the producer bridge now consult the same
|
|
11
|
+
* function, so a new strategy label is declared once, next to the adapter
|
|
12
|
+
* that emits it. `outcome-to-verdict.js` re-exports this module verbatim —
|
|
13
|
+
* its public name and behavior are unchanged.
|
|
14
|
+
*
|
|
15
|
+
* This module is deliberately dependency-free and browser-safe: it reads a
|
|
16
|
+
* plain result object and returns a verdict. Anything needing disk (the
|
|
17
|
+
* schema + catalog exit gate) stays with the caller.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
// Strategies an engine returns when it deliberately emitted NOTHING
|
|
21
|
+
// grounded — the zettel/free-form/chunk-zettel equivalent of a hard
|
|
22
|
+
// validation failure. Compiled from registry.js's own adapters and their
|
|
23
|
+
// sibling generator modules' documented strategy labels.
|
|
24
|
+
const NON_EMISSION_STRATEGIES = new Set([
|
|
25
|
+
'fragment-candidates', // zettel: retrieval ran, nothing strong enough to emit verbatim
|
|
26
|
+
'free-form-empty-plan', // free-form: LLM picked zero ingredients
|
|
27
|
+
'free-form-hallucinated', // free-form: LLM named ingredients outside the corpus vocabulary
|
|
28
|
+
'free-form-no-llm', // free-form: no adapter available, picker never ran
|
|
29
|
+
'chunk-zettel-empty', // chunk-zettel: composeFromIntent produced no template/html
|
|
30
|
+
]);
|
|
31
|
+
|
|
32
|
+
/** @param {string|undefined} strategy */
|
|
33
|
+
export function isNonEmissionStrategy(strategy) {
|
|
34
|
+
return NON_EMISSION_STRATEGIES.has(strategy);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A strategy treated as a strong-enough hit to accept before any exit gate
|
|
39
|
+
* runs — the labels the pre-gh#583 consumer cascades checked as
|
|
40
|
+
* `isStrongMatch` / `freeFormComposed`. An exit gate, where the caller has
|
|
41
|
+
* one, still runs afterward; this only decides whether the LADDER treats
|
|
42
|
+
* the round as a hit.
|
|
43
|
+
*/
|
|
44
|
+
const STRONG_EMISSION_STRATEGIES = new Set([
|
|
45
|
+
'composition-match',
|
|
46
|
+
'composition-iterated',
|
|
47
|
+
'free-form-composed',
|
|
48
|
+
]);
|
|
49
|
+
|
|
50
|
+
/** @param {string|undefined} strategy */
|
|
51
|
+
export function isStrongEmissionStrategy(strategy) {
|
|
52
|
+
return STRONG_EMISSION_STRATEGIES.has(strategy);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Maps one ENGINES[*] adapter result (registry.js's uniform return shape:
|
|
57
|
+
* `{ executionId, messages, validation, strategy, engine, ... }`) to a
|
|
58
|
+
* ladder verdict.
|
|
59
|
+
*
|
|
60
|
+
* @param {object} result
|
|
61
|
+
* @returns {{ ok: true } | { ok: false, feedback: {code: string, message: string}[] }}
|
|
62
|
+
*/
|
|
63
|
+
export function judgeEngineResult(result) {
|
|
64
|
+
const engineName = result?.engine ?? 'unknown';
|
|
65
|
+
const strategy = result?.strategy;
|
|
66
|
+
|
|
67
|
+
if (!Array.isArray(result?.messages) || result.messages.length === 0) {
|
|
68
|
+
return {
|
|
69
|
+
ok: false,
|
|
70
|
+
feedback: [{
|
|
71
|
+
code: 'no-emission',
|
|
72
|
+
message: `engine "${engineName}" emitted no messages (strategy: ${strategy ?? 'none'})`,
|
|
73
|
+
}],
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (isNonEmissionStrategy(strategy)) {
|
|
78
|
+
return {
|
|
79
|
+
ok: false,
|
|
80
|
+
feedback: [{
|
|
81
|
+
code: 'non-emission-strategy',
|
|
82
|
+
message: `engine "${engineName}" signaled non-emission strategy "${strategy}"`,
|
|
83
|
+
}],
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// A strong-match strategy skips the generic no-emission/non-emission
|
|
88
|
+
// checks above, but REQ-02 (spec-factory-dx-ws4-acceptance) still judges
|
|
89
|
+
// it on its OWN reported verdict when the engine normalized one — a
|
|
90
|
+
// strong-emission strategy is no longer a blanket bypass, only a bypass
|
|
91
|
+
// of the WEAKER schema-invalid fallback below. An engine with no
|
|
92
|
+
// `validation.valid` field (zettel's strong-emission strategies, until
|
|
93
|
+
// they normalize one — see the SPEC's REQ-02 non-goal) rides the same
|
|
94
|
+
// no-valid-field pass-through it always did, caught instead by the
|
|
95
|
+
// default acceptance gate (registry.js's `generateAutoAdapter`).
|
|
96
|
+
if (isStrongEmissionStrategy(strategy)) {
|
|
97
|
+
if (result.validation && result.validation.valid === false) {
|
|
98
|
+
return {
|
|
99
|
+
ok: false,
|
|
100
|
+
feedback: [{
|
|
101
|
+
code: 'strong-emission-invalid',
|
|
102
|
+
message: `engine "${engineName}" strong-emission strategy "${strategy}" failed its own validation (score ${result.validation.score ?? 0}/100)`,
|
|
103
|
+
}],
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return { ok: true };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (result.validation && result.validation.valid === false) {
|
|
110
|
+
return {
|
|
111
|
+
ok: false,
|
|
112
|
+
feedback: [{
|
|
113
|
+
code: 'schema-invalid',
|
|
114
|
+
message: `engine "${engineName}" result failed its own validation (score ${result.validation.score ?? 0}/100)`,
|
|
115
|
+
}],
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return { ok: true };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* The boolean form — a workflow `until` predicate. `judgeEngineResult` when
|
|
124
|
+
* you need the feedback entries, this when you only need the fall-through
|
|
125
|
+
* decision.
|
|
126
|
+
*
|
|
127
|
+
* @param {object} result
|
|
128
|
+
* @returns {boolean}
|
|
129
|
+
*/
|
|
130
|
+
export function accepts(result) {
|
|
131
|
+
return judgeEngineResult(result).ok === true;
|
|
132
|
+
}
|