@praxisui/page-builder 8.0.0-beta.26 → 8.0.0-beta.28
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/README.md +1 -0
- package/fesm2022/praxisui-page-builder.mjs +1298 -113
- package/index.d.ts +35 -5
- package/package.json +4 -4
|
@@ -25,13 +25,13 @@ import * as i6$1 from '@angular/material/divider';
|
|
|
25
25
|
import { MatDividerModule } from '@angular/material/divider';
|
|
26
26
|
import * as i6$2 from '@angular/material/select';
|
|
27
27
|
import { MatSelectModule } from '@angular/material/select';
|
|
28
|
-
import { BehaviorSubject, merge, timeout, map, switchMap, Observable,
|
|
28
|
+
import { BehaviorSubject, merge, timeout, map, switchMap, Observable, from, firstValueFrom, concatMap, catchError, of, filter, take } from 'rxjs';
|
|
29
29
|
import { SETTINGS_PANEL_DATA } from '@praxisui/settings-panel';
|
|
30
30
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
31
31
|
import * as i7 from '@angular/material/tabs';
|
|
32
32
|
import { MatTabsModule } from '@angular/material/tabs';
|
|
33
33
|
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
|
34
|
-
import { AI_STREAM_EVENT_TYPES, toPraxisAssistantConversationMessages, PraxisAssistantTurnOrchestratorService, PraxisAssistantSessionRegistryService, PraxisAiAssistantShellComponent } from '@praxisui/ai';
|
|
34
|
+
import { AI_STREAM_EVENT_TYPES, toPraxisAssistantConversationMessages, PraxisAssistantTurnOrchestratorService, PraxisAssistantSessionRegistryService, createPraxisAssistantViewportLayout, PraxisAiAssistantShellComponent } from '@praxisui/ai';
|
|
35
35
|
|
|
36
36
|
const PLACEHOLDER = 1;
|
|
37
37
|
|
|
@@ -2401,13 +2401,14 @@ const PRAXIS_PAGE_BUILDER_EN_US = {
|
|
|
2401
2401
|
'praxis.pageBuilder.agentic.panelAria': 'AI page authoring',
|
|
2402
2402
|
'praxis.pageBuilder.agentic.title': 'Praxis semantic copilot',
|
|
2403
2403
|
'praxis.pageBuilder.agentic.subtitle': 'Author governed decisions with previews, confirmation, and runtime materialization.',
|
|
2404
|
-
'praxis.pageBuilder.agentic.header.title.page': 'Praxis page copilot',
|
|
2404
|
+
'praxis.pageBuilder.agentic.header.title.page': 'Praxis page decision copilot',
|
|
2405
2405
|
'praxis.pageBuilder.agentic.header.title.widget': 'Praxis widget copilot',
|
|
2406
2406
|
'praxis.pageBuilder.agentic.header.title.review': 'Praxis review copilot',
|
|
2407
2407
|
'praxis.pageBuilder.agentic.header.title.governed': 'Praxis governed copilot',
|
|
2408
|
-
'praxis.pageBuilder.agentic.header.subtitle.page': '
|
|
2408
|
+
'praxis.pageBuilder.agentic.header.subtitle.page': 'Turn intent into layout, widgets, and governed materializations.',
|
|
2409
2409
|
'praxis.pageBuilder.agentic.header.subtitle.route': 'Authoring page route {route}.',
|
|
2410
2410
|
'praxis.pageBuilder.agentic.header.subtitle.widget': 'Focused on {target}.',
|
|
2411
|
+
'praxis.pageBuilder.agentic.header.subtitle.reviewBlocked': 'Preview ready for governed review.',
|
|
2411
2412
|
'praxis.pageBuilder.agentic.header.subtitle.review': 'Preview ready for review and persistence.',
|
|
2412
2413
|
'praxis.pageBuilder.agentic.header.subtitle.governed': 'Continue the governed semantic-decision flow.',
|
|
2413
2414
|
'praxis.pageBuilder.agentic.header.mode.page': 'Page',
|
|
@@ -2429,7 +2430,9 @@ const PRAXIS_PAGE_BUILDER_EN_US = {
|
|
|
2429
2430
|
'praxis.pageBuilder.agentic.dock.summaryIdle': 'Conversation preserved. Continue where you stopped.',
|
|
2430
2431
|
'praxis.pageBuilder.agentic.promptLabel': 'Message',
|
|
2431
2432
|
'praxis.pageBuilder.agentic.promptPlaceholder': 'Describe the page, dashboard, form, or change you need.',
|
|
2432
|
-
'praxis.pageBuilder.agentic.emptyConversation': '
|
|
2433
|
+
'praxis.pageBuilder.agentic.emptyConversation': 'Describe the outcome you want. I will ground the context, prepare a governed preview, and wait for review before applying anything.',
|
|
2434
|
+
'praxis.pageBuilder.agentic.emptyConversation.blankGeneric': 'This host page is still blank. Tell me what decision or activity this app needs to support. I can suggest a dashboard, table, form, or review flow, then turn it into a governed preview for you to review before anything changes.',
|
|
2435
|
+
'praxis.pageBuilder.agentic.emptyConversation.existingPage': 'Tell me what you want to improve here. I can read the current layout, widgets, route, and governed context, then prepare a preview for you to review before anything changes.',
|
|
2433
2436
|
'praxis.pageBuilder.agentic.conversationAria': 'AI conversation',
|
|
2434
2437
|
'praxis.pageBuilder.agentic.quickRepliesAria': 'Quick replies',
|
|
2435
2438
|
'praxis.pageBuilder.agentic.contextAria': 'Active context',
|
|
@@ -2445,6 +2448,23 @@ const PRAXIS_PAGE_BUILDER_EN_US = {
|
|
|
2445
2448
|
'praxis.pageBuilder.agentic.context.governedDomainContextRequest': 'Requested context',
|
|
2446
2449
|
'praxis.pageBuilder.agentic.context.governedDomainContextSize': 'Grounding size',
|
|
2447
2450
|
'praxis.pageBuilder.agentic.context.sharedRuleTargetLayer': 'Target materialization',
|
|
2451
|
+
'praxis.pageBuilder.agentic.context.semanticDecisionResource': 'Source',
|
|
2452
|
+
'praxis.pageBuilder.agentic.context.semanticDecisionKind': 'Goal',
|
|
2453
|
+
'praxis.pageBuilder.agentic.context.semanticDecisionEvidence': 'Review',
|
|
2454
|
+
'praxis.pageBuilder.agentic.context.operationCreate': 'Create',
|
|
2455
|
+
'praxis.pageBuilder.agentic.context.operationUpdate': 'Adjust',
|
|
2456
|
+
'praxis.pageBuilder.agentic.context.operationRead': 'Explore',
|
|
2457
|
+
'praxis.pageBuilder.agentic.context.artifactDashboard': 'dashboard',
|
|
2458
|
+
'praxis.pageBuilder.agentic.context.artifactTable': 'table',
|
|
2459
|
+
'praxis.pageBuilder.agentic.context.artifactForm': 'form',
|
|
2460
|
+
'praxis.pageBuilder.agentic.context.artifactPage': 'screen',
|
|
2461
|
+
'praxis.pageBuilder.agentic.context.changeAnalytics': 'with analysis',
|
|
2462
|
+
'praxis.pageBuilder.agentic.context.changeDashboard': 'with dashboard view',
|
|
2463
|
+
'praxis.pageBuilder.agentic.context.changeTable': 'with details',
|
|
2464
|
+
'praxis.pageBuilder.agentic.context.changeForm': 'with editing',
|
|
2465
|
+
'praxis.pageBuilder.agentic.context.evidenceReviewRequired': 'Needs field review',
|
|
2466
|
+
'praxis.pageBuilder.agentic.context.evidenceLowConfidence': 'Needs source confirmation',
|
|
2467
|
+
'praxis.pageBuilder.agentic.context.evidenceGrounded': 'Source confirmed',
|
|
2448
2468
|
'praxis.pageBuilder.agentic.editMessage': 'Edit',
|
|
2449
2469
|
'praxis.pageBuilder.agentic.resendMessage': 'Resend',
|
|
2450
2470
|
'praxis.pageBuilder.agentic.removeAttachment': 'Remove attachment',
|
|
@@ -2454,7 +2474,7 @@ const PRAXIS_PAGE_BUILDER_EN_US = {
|
|
|
2454
2474
|
'praxis.pageBuilder.agentic.mode.diagnostic': 'Diagnostic',
|
|
2455
2475
|
'praxis.pageBuilder.agentic.mode.review': 'Review',
|
|
2456
2476
|
'praxis.pageBuilder.agentic.mode.inlineHelp': 'Help',
|
|
2457
|
-
'praxis.pageBuilder.agentic.state.idle': '
|
|
2477
|
+
'praxis.pageBuilder.agentic.state.idle': 'Ready',
|
|
2458
2478
|
'praxis.pageBuilder.agentic.state.listening': 'Ready',
|
|
2459
2479
|
'praxis.pageBuilder.agentic.state.processing': 'Processing',
|
|
2460
2480
|
'praxis.pageBuilder.agentic.state.clarification': 'Waiting for input',
|
|
@@ -2486,9 +2506,16 @@ const PRAXIS_PAGE_BUILDER_EN_US = {
|
|
|
2486
2506
|
'praxis.pageBuilder.agentic.exploratory.capability.table': 'tables',
|
|
2487
2507
|
'praxis.pageBuilder.agentic.exploratory.capability.form': 'forms',
|
|
2488
2508
|
'praxis.pageBuilder.agentic.exploratory.capability.masterDetail': 'master-detail pages',
|
|
2489
|
-
'praxis.pageBuilder.agentic.resourceDiscovery.found': 'I found
|
|
2509
|
+
'praxis.pageBuilder.agentic.resourceDiscovery.found': 'I found {sourceCount} for this screen. I recommend starting with {first} because it is the best fit for charts, KPIs, and drill-down. Review the cards below to see what each source is good for, what it returns, and what I will create after you select it.',
|
|
2510
|
+
'praxis.pageBuilder.agentic.resourceDiscovery.sourceCountSingular': '1 candidate source',
|
|
2511
|
+
'praxis.pageBuilder.agentic.resourceDiscovery.sourceCountPlural': '{count} candidate sources',
|
|
2490
2512
|
'praxis.pageBuilder.agentic.resourceDiscovery.empty': 'I did not find a matching API yet. Describe the business data this screen should use.',
|
|
2491
2513
|
'praxis.pageBuilder.agentic.resourceDiscovery.useResource': 'Use {resourcePath}',
|
|
2514
|
+
'praxis.pageBuilder.agentic.resourceDiscovery.defaultRecommendedLabel': 'the first option',
|
|
2515
|
+
'praxis.pageBuilder.agentic.resourceDiscovery.cardDescription': 'Recommended source for turning {label} into a dashboard: helps choose charts, lists, filters, and formats before materializing the screen.',
|
|
2516
|
+
'praxis.pageBuilder.agentic.resourceDiscovery.cardBestFor': 'Use when you want to understand whether {label} answers the business goal before creating widgets.',
|
|
2517
|
+
'praxis.pageBuilder.agentic.resourceDiscovery.cardReturns': 'Suggests metrics, dimensions, filters, value formats, charts, and detail lists compatible with the source.',
|
|
2518
|
+
'praxis.pageBuilder.agentic.resourceDiscovery.cardNextStep': 'Select it so I can propose a governed preview with rich cards, drill-down, and sensible default formats.',
|
|
2492
2519
|
'praxis.pageBuilder.agentic.diagnostics.title': 'LLM diagnostics',
|
|
2493
2520
|
'praxis.pageBuilder.agentic.diagnostics.badge': 'Debug',
|
|
2494
2521
|
'praxis.pageBuilder.agentic.diagnostics.description': 'Prompt, context bundle, and tool catalog returned by the backend for this turn.',
|
|
@@ -2510,10 +2537,12 @@ const PRAXIS_PAGE_BUILDER_EN_US = {
|
|
|
2510
2537
|
'praxis.pageBuilder.agentic.status.refinedCandidates': 'Reviewing the retrieved resources with the AI...',
|
|
2511
2538
|
'praxis.pageBuilder.agentic.status.projectKnowledgeRetrieved': 'Retrieved governed project knowledge for this authoring turn.',
|
|
2512
2539
|
'praxis.pageBuilder.agentic.status.projectKnowledgeRetrievedCount': 'Retrieved {count} governed project knowledge signals for this authoring turn.',
|
|
2513
|
-
'praxis.pageBuilder.agentic.status.projectKnowledgeAuditCited': '{cited} of {count}
|
|
2540
|
+
'praxis.pageBuilder.agentic.status.projectKnowledgeAuditCited': 'Governed knowledge cited: {cited} of {count}.',
|
|
2514
2541
|
'praxis.pageBuilder.agentic.status.previewing': 'Generating preview...',
|
|
2515
2542
|
'praxis.pageBuilder.agentic.status.previewCompile': 'Compiling preview...',
|
|
2516
2543
|
'praxis.pageBuilder.agentic.status.previewReady': 'Preview applied to the page.',
|
|
2544
|
+
'praxis.pageBuilder.agentic.status.reviewReady': 'Ready for review.',
|
|
2545
|
+
'praxis.pageBuilder.agentic.status.reviewNeedsAttention': 'Review the pending points before saving.',
|
|
2517
2546
|
'praxis.pageBuilder.agentic.status.acceptedAddLocalField': 'Local field added to the form.',
|
|
2518
2547
|
'praxis.pageBuilder.agentic.status.acceptedRemoveLocalField': 'Local field removed from the form.',
|
|
2519
2548
|
'praxis.pageBuilder.agentic.status.acceptedRelabelField': 'Field label updated.',
|
|
@@ -2820,9 +2849,10 @@ const PRAXIS_PAGE_BUILDER_PT_BR = {
|
|
|
2820
2849
|
'praxis.pageBuilder.agentic.header.title.widget': 'Copiloto de componente Praxis',
|
|
2821
2850
|
'praxis.pageBuilder.agentic.header.title.review': 'Copiloto de revisão Praxis',
|
|
2822
2851
|
'praxis.pageBuilder.agentic.header.title.governed': 'Copiloto governado Praxis',
|
|
2823
|
-
'praxis.pageBuilder.agentic.header.subtitle.page': '
|
|
2852
|
+
'praxis.pageBuilder.agentic.header.subtitle.page': 'Transforme intenção em layout, widgets e materializações governadas.',
|
|
2824
2853
|
'praxis.pageBuilder.agentic.header.subtitle.route': 'Autoria da rota {route}.',
|
|
2825
2854
|
'praxis.pageBuilder.agentic.header.subtitle.widget': 'Foco em {target}.',
|
|
2855
|
+
'praxis.pageBuilder.agentic.header.subtitle.reviewBlocked': 'Prévia pronta para revisão governada.',
|
|
2826
2856
|
'praxis.pageBuilder.agentic.header.subtitle.review': 'Prévia pronta para revisão e persistência.',
|
|
2827
2857
|
'praxis.pageBuilder.agentic.header.subtitle.governed': 'Continue o fluxo governado de decisão semântica.',
|
|
2828
2858
|
'praxis.pageBuilder.agentic.header.mode.page': 'Página',
|
|
@@ -2844,7 +2874,9 @@ const PRAXIS_PAGE_BUILDER_PT_BR = {
|
|
|
2844
2874
|
'praxis.pageBuilder.agentic.dock.summaryIdle': 'Conversa preservada. Continue de onde parou.',
|
|
2845
2875
|
'praxis.pageBuilder.agentic.promptLabel': 'Mensagem',
|
|
2846
2876
|
'praxis.pageBuilder.agentic.promptPlaceholder': 'Descreva a página, dashboard, formulário ou alteração que você precisa.',
|
|
2847
|
-
'praxis.pageBuilder.agentic.emptyConversation': '
|
|
2877
|
+
'praxis.pageBuilder.agentic.emptyConversation': 'Descreva o resultado que você quer. Vou fundamentar o contexto, preparar uma prévia governada e aguardar revisão antes de aplicar qualquer mudança.',
|
|
2878
|
+
'praxis.pageBuilder.agentic.emptyConversation.blankGeneric': 'Esta página do host ainda está em branco. Conte qual decisão ou atividade este app precisa apoiar. Posso sugerir um dashboard, tabela, formulário ou fluxo de revisão e transformar isso em uma prévia governada para você revisar antes de qualquer mudança.',
|
|
2879
|
+
'praxis.pageBuilder.agentic.emptyConversation.existingPage': 'Conte o que você quer melhorar aqui. Posso ler o layout atual, widgets, rota e contexto governado, depois preparar uma prévia para você revisar antes de qualquer mudança.',
|
|
2848
2880
|
'praxis.pageBuilder.agentic.conversationAria': 'Conversa com IA',
|
|
2849
2881
|
'praxis.pageBuilder.agentic.quickRepliesAria': 'Respostas rápidas',
|
|
2850
2882
|
'praxis.pageBuilder.agentic.contextAria': 'Contexto ativo',
|
|
@@ -2860,6 +2892,23 @@ const PRAXIS_PAGE_BUILDER_PT_BR = {
|
|
|
2860
2892
|
'praxis.pageBuilder.agentic.context.governedDomainContextRequest': 'Contexto solicitado',
|
|
2861
2893
|
'praxis.pageBuilder.agentic.context.governedDomainContextSize': 'Tamanho do grounding',
|
|
2862
2894
|
'praxis.pageBuilder.agentic.context.sharedRuleTargetLayer': 'Materialização alvo',
|
|
2895
|
+
'praxis.pageBuilder.agentic.context.semanticDecisionResource': 'Fonte',
|
|
2896
|
+
'praxis.pageBuilder.agentic.context.semanticDecisionKind': 'Objetivo',
|
|
2897
|
+
'praxis.pageBuilder.agentic.context.semanticDecisionEvidence': 'Revisão',
|
|
2898
|
+
'praxis.pageBuilder.agentic.context.operationCreate': 'Criar',
|
|
2899
|
+
'praxis.pageBuilder.agentic.context.operationUpdate': 'Ajustar',
|
|
2900
|
+
'praxis.pageBuilder.agentic.context.operationRead': 'Consultar',
|
|
2901
|
+
'praxis.pageBuilder.agentic.context.artifactDashboard': 'dashboard',
|
|
2902
|
+
'praxis.pageBuilder.agentic.context.artifactTable': 'tabela',
|
|
2903
|
+
'praxis.pageBuilder.agentic.context.artifactForm': 'formulário',
|
|
2904
|
+
'praxis.pageBuilder.agentic.context.artifactPage': 'tela',
|
|
2905
|
+
'praxis.pageBuilder.agentic.context.changeAnalytics': 'com análise',
|
|
2906
|
+
'praxis.pageBuilder.agentic.context.changeDashboard': 'com visão gerencial',
|
|
2907
|
+
'praxis.pageBuilder.agentic.context.changeTable': 'com detalhes',
|
|
2908
|
+
'praxis.pageBuilder.agentic.context.changeForm': 'com edição',
|
|
2909
|
+
'praxis.pageBuilder.agentic.context.evidenceReviewRequired': 'Precisa revisar campos',
|
|
2910
|
+
'praxis.pageBuilder.agentic.context.evidenceLowConfidence': 'Precisa confirmar fonte',
|
|
2911
|
+
'praxis.pageBuilder.agentic.context.evidenceGrounded': 'Fonte confirmada',
|
|
2863
2912
|
'praxis.pageBuilder.agentic.editMessage': 'Editar',
|
|
2864
2913
|
'praxis.pageBuilder.agentic.resendMessage': 'Reenviar',
|
|
2865
2914
|
'praxis.pageBuilder.agentic.removeAttachment': 'Remover anexo',
|
|
@@ -2869,7 +2918,7 @@ const PRAXIS_PAGE_BUILDER_PT_BR = {
|
|
|
2869
2918
|
'praxis.pageBuilder.agentic.mode.diagnostic': 'Diagnóstico',
|
|
2870
2919
|
'praxis.pageBuilder.agentic.mode.review': 'Revisão',
|
|
2871
2920
|
'praxis.pageBuilder.agentic.mode.inlineHelp': 'Ajuda',
|
|
2872
|
-
'praxis.pageBuilder.agentic.state.idle': '
|
|
2921
|
+
'praxis.pageBuilder.agentic.state.idle': 'Pronto',
|
|
2873
2922
|
'praxis.pageBuilder.agentic.state.listening': 'Pronto',
|
|
2874
2923
|
'praxis.pageBuilder.agentic.state.processing': 'Processando',
|
|
2875
2924
|
'praxis.pageBuilder.agentic.state.clarification': 'Aguardando resposta',
|
|
@@ -2901,9 +2950,16 @@ const PRAXIS_PAGE_BUILDER_PT_BR = {
|
|
|
2901
2950
|
'praxis.pageBuilder.agentic.exploratory.capability.table': 'tabelas',
|
|
2902
2951
|
'praxis.pageBuilder.agentic.exploratory.capability.form': 'formulários',
|
|
2903
2952
|
'praxis.pageBuilder.agentic.exploratory.capability.masterDetail': 'páginas master-detail',
|
|
2904
|
-
'praxis.pageBuilder.agentic.resourceDiscovery.found': 'Encontrei
|
|
2953
|
+
'praxis.pageBuilder.agentic.resourceDiscovery.found': 'Encontrei {sourceCount} para esta tela. Minha recomendação é começar por {first}, porque parece a melhor opção para gráficos, KPIs e drill-down. Revise os cards abaixo para entender quando usar cada fonte, o que ela retorna e o que eu vou criar depois da seleção.',
|
|
2954
|
+
'praxis.pageBuilder.agentic.resourceDiscovery.sourceCountSingular': '1 fonte candidata',
|
|
2955
|
+
'praxis.pageBuilder.agentic.resourceDiscovery.sourceCountPlural': '{count} fontes candidatas',
|
|
2905
2956
|
'praxis.pageBuilder.agentic.resourceDiscovery.empty': 'Ainda não encontrei uma API correspondente. Descreva quais dados de negócio esta tela deve usar.',
|
|
2906
2957
|
'praxis.pageBuilder.agentic.resourceDiscovery.useResource': 'Usar {resourcePath}',
|
|
2958
|
+
'praxis.pageBuilder.agentic.resourceDiscovery.defaultRecommendedLabel': 'a primeira opção',
|
|
2959
|
+
'praxis.pageBuilder.agentic.resourceDiscovery.cardDescription': 'Fonte recomendada para transformar {label} em painel: ajuda a escolher gráficos, listas, filtros e formatos antes de materializar a tela.',
|
|
2960
|
+
'praxis.pageBuilder.agentic.resourceDiscovery.cardBestFor': 'Quando você quer entender se {label} responde ao objetivo de negócio antes de criar widgets.',
|
|
2961
|
+
'praxis.pageBuilder.agentic.resourceDiscovery.cardReturns': 'Sugere métricas, dimensões, filtros, formatos de valor, gráficos e listas de detalhe compatíveis com a fonte.',
|
|
2962
|
+
'praxis.pageBuilder.agentic.resourceDiscovery.cardNextStep': 'Selecione para eu propor uma pré-visualização governada com cards ricos, drill-down e formatos adequados por padrão.',
|
|
2907
2963
|
'praxis.pageBuilder.agentic.diagnostics.title': 'Diagnóstico do LLM',
|
|
2908
2964
|
'praxis.pageBuilder.agentic.diagnostics.badge': 'Debug',
|
|
2909
2965
|
'praxis.pageBuilder.agentic.diagnostics.description': 'Prompt, pacote de contexto e catálogo de ferramentas retornados pelo backend para este turno.',
|
|
@@ -2925,10 +2981,12 @@ const PRAXIS_PAGE_BUILDER_PT_BR = {
|
|
|
2925
2981
|
'praxis.pageBuilder.agentic.status.refinedCandidates': 'Estou revisando os recursos encontrados com a IA...',
|
|
2926
2982
|
'praxis.pageBuilder.agentic.status.projectKnowledgeRetrieved': 'Recuperei conhecimento governado do projeto para este turno de autoria.',
|
|
2927
2983
|
'praxis.pageBuilder.agentic.status.projectKnowledgeRetrievedCount': 'Recuperei {count} sinais de conhecimento governado do projeto para este turno.',
|
|
2928
|
-
'praxis.pageBuilder.agentic.status.projectKnowledgeAuditCited': '{cited} de {count}
|
|
2984
|
+
'praxis.pageBuilder.agentic.status.projectKnowledgeAuditCited': 'Conhecimento governado citado: {cited} de {count}.',
|
|
2929
2985
|
'praxis.pageBuilder.agentic.status.previewing': 'Gerando pré-visualização...',
|
|
2930
2986
|
'praxis.pageBuilder.agentic.status.previewCompile': 'Compilando pré-visualização...',
|
|
2931
2987
|
'praxis.pageBuilder.agentic.status.previewReady': 'Pré-visualização aplicada à página.',
|
|
2988
|
+
'praxis.pageBuilder.agentic.status.reviewReady': 'Pronto para revisar.',
|
|
2989
|
+
'praxis.pageBuilder.agentic.status.reviewNeedsAttention': 'Revise os pontos pendentes antes de salvar.',
|
|
2932
2990
|
'praxis.pageBuilder.agentic.status.acceptedAddLocalField': 'Campo local adicionado ao formulário.',
|
|
2933
2991
|
'praxis.pageBuilder.agentic.status.acceptedRemoveLocalField': 'Campo local removido do formulário.',
|
|
2934
2992
|
'praxis.pageBuilder.agentic.status.acceptedRelabelField': 'Rótulo do campo atualizado.',
|
|
@@ -11134,7 +11192,7 @@ function providePageBuilderWidgetAiCatalogs() {
|
|
|
11134
11192
|
|
|
11135
11193
|
const DEFAULT_AGENTIC_AUTHORING_REQUEST_TIMEOUT_MS = 15000;
|
|
11136
11194
|
const DEFAULT_TURN_STREAM_START_TIMEOUT_MS = 10000;
|
|
11137
|
-
const DEFAULT_TURN_STREAM_TIMEOUT_MS =
|
|
11195
|
+
const DEFAULT_TURN_STREAM_TIMEOUT_MS = 240000;
|
|
11138
11196
|
const PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS = new InjectionToken('PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS');
|
|
11139
11197
|
class PageBuilderAgenticAuthoringService {
|
|
11140
11198
|
http = inject(HttpClient);
|
|
@@ -11166,6 +11224,7 @@ class PageBuilderAgenticAuthoringService {
|
|
|
11166
11224
|
scope: body.scope,
|
|
11167
11225
|
tags: body.tags,
|
|
11168
11226
|
compiledFormPatch: body.compiledFormPatch,
|
|
11227
|
+
semanticDecision: body.semanticDecision ?? null,
|
|
11169
11228
|
}, {
|
|
11170
11229
|
headers: this.buildHeaders(ifMatch ? { 'If-Match': this.formatEtag(ifMatch) } : undefined),
|
|
11171
11230
|
});
|
|
@@ -11345,10 +11404,11 @@ class PageBuilderAgenticAuthoringService {
|
|
|
11345
11404
|
}
|
|
11346
11405
|
createEventSource(url) {
|
|
11347
11406
|
const factory = this.options?.eventSourceFactory;
|
|
11407
|
+
const options = { withCredentials: true };
|
|
11348
11408
|
if (factory) {
|
|
11349
|
-
return factory(url);
|
|
11409
|
+
return factory(url, options);
|
|
11350
11410
|
}
|
|
11351
|
-
return new EventSource(url);
|
|
11411
|
+
return new EventSource(url, options);
|
|
11352
11412
|
}
|
|
11353
11413
|
async probeTurnStreamEndpoint(url, abort) {
|
|
11354
11414
|
if (typeof fetch === 'undefined') {
|
|
@@ -11543,7 +11603,7 @@ const PRAXIS_PAGE_BUILDER_AUTHORING_MANIFEST = {
|
|
|
11543
11603
|
{ name: 'pageChange', type: 'WidgetPageDefinition', description: 'Emitted after local apply/preview produces a renderable page.' },
|
|
11544
11604
|
{ name: 'agenticAuthoringEnableStreaming', type: 'boolean', description: 'Opt-in flag for the canonical streaming turn endpoints.' },
|
|
11545
11605
|
{ name: 'agenticAuthoringIncludeLlmDiagnostics', type: 'boolean', description: 'Opt-in flag that exposes governed diagnostics as cockpit evidence for validation and debugging.' },
|
|
11546
|
-
{ name: 'agenticAuthoringContextHints', type: 'Record<string, unknown>', description: 'Host-provided semantic hints, including governed domain-catalog references used to ground AI-authored decisions.' },
|
|
11606
|
+
{ name: 'agenticAuthoringContextHints', type: 'Record<string, unknown>', description: 'Host-provided semantic hints, including governed domain-catalog references and optional RAG-authored openingMessage used to ground AI-authored decisions.' },
|
|
11547
11607
|
],
|
|
11548
11608
|
editableTargets: [
|
|
11549
11609
|
{ kind: 'page', resolver: 'widget-page-definition-root', description: 'Root WidgetPageDefinition document: title, metadata, context and renderable page envelope.' },
|
|
@@ -12010,7 +12070,7 @@ function compileUiCompositionPlan(plan) {
|
|
|
12010
12070
|
layoutPreset: plan.layoutPreset,
|
|
12011
12071
|
canvas: clone(plan.canvas),
|
|
12012
12072
|
state: clone(plan.state),
|
|
12013
|
-
widgets: plan.widgets.map(toWidgetInstance),
|
|
12073
|
+
widgets: plan.widgets.map((widget) => toWidgetInstance(widget, plan.bindings ?? [])),
|
|
12014
12074
|
composition: {
|
|
12015
12075
|
version: '1.0.0',
|
|
12016
12076
|
links: (plan.bindings ?? []).map(toCompositionLink),
|
|
@@ -12170,17 +12230,32 @@ function validateNestedPath(nestedPath, diagnostics, path) {
|
|
|
12170
12230
|
});
|
|
12171
12231
|
}
|
|
12172
12232
|
}
|
|
12173
|
-
function toWidgetInstance(widget) {
|
|
12233
|
+
function toWidgetInstance(widget, bindings) {
|
|
12234
|
+
const outputs = linkedTopLevelOutputs(widget.key, widget.outputs, bindings);
|
|
12174
12235
|
return {
|
|
12175
12236
|
key: widget.key,
|
|
12176
12237
|
definition: {
|
|
12177
12238
|
id: widget.componentId,
|
|
12178
12239
|
bindingOrder: widget.bindingOrder,
|
|
12179
12240
|
inputs: clone(widget.inputs ?? {}),
|
|
12180
|
-
outputs
|
|
12241
|
+
outputs,
|
|
12181
12242
|
},
|
|
12182
12243
|
};
|
|
12183
12244
|
}
|
|
12245
|
+
function linkedTopLevelOutputs(widgetKey, declaredOutputs, bindings) {
|
|
12246
|
+
const outputs = clone(declaredOutputs ?? {});
|
|
12247
|
+
for (const binding of bindings) {
|
|
12248
|
+
const endpoint = binding.from;
|
|
12249
|
+
if (endpoint.kind !== 'component-port'
|
|
12250
|
+
|| endpoint.direction !== 'output'
|
|
12251
|
+
|| endpoint.widget !== widgetKey
|
|
12252
|
+
|| endpoint.nestedPath?.length) {
|
|
12253
|
+
continue;
|
|
12254
|
+
}
|
|
12255
|
+
outputs[endpoint.port] ??= 'emit';
|
|
12256
|
+
}
|
|
12257
|
+
return outputs;
|
|
12258
|
+
}
|
|
12184
12259
|
function toCompositionLink(binding) {
|
|
12185
12260
|
const transform = binding.transform ? toCompositionTransform(binding.transform) : undefined;
|
|
12186
12261
|
return {
|
|
@@ -12312,6 +12387,84 @@ function clone(value) {
|
|
|
12312
12387
|
}
|
|
12313
12388
|
}
|
|
12314
12389
|
|
|
12390
|
+
const RUNTIME_AUTHORING_METADATA_INPUTS = [
|
|
12391
|
+
'schemaVerification',
|
|
12392
|
+
'schemaEvidenceSource',
|
|
12393
|
+
'schemaEvidenceUrl',
|
|
12394
|
+
];
|
|
12395
|
+
function normalizePageBuilderRuntimePage(page) {
|
|
12396
|
+
if (!page?.widgets?.length) {
|
|
12397
|
+
return page;
|
|
12398
|
+
}
|
|
12399
|
+
return {
|
|
12400
|
+
...page,
|
|
12401
|
+
widgets: page.widgets.map((widget) => normalizePageBuilderRuntimeWidget(widget)),
|
|
12402
|
+
};
|
|
12403
|
+
}
|
|
12404
|
+
function normalizePageBuilderRuntimeWidget(widget) {
|
|
12405
|
+
const definition = widget.definition;
|
|
12406
|
+
if (!definition?.inputs) {
|
|
12407
|
+
return widget;
|
|
12408
|
+
}
|
|
12409
|
+
const inputs = { ...definition.inputs };
|
|
12410
|
+
for (const key of RUNTIME_AUTHORING_METADATA_INPUTS) {
|
|
12411
|
+
delete inputs[key];
|
|
12412
|
+
}
|
|
12413
|
+
if (definition.id === 'praxis-rich-content') {
|
|
12414
|
+
if (inputs['kpis'] !== undefined) {
|
|
12415
|
+
const document = isRecord(inputs['document']) ? inputs['document'] : {};
|
|
12416
|
+
inputs['document'] = {
|
|
12417
|
+
...document,
|
|
12418
|
+
kpis: document['kpis'] ?? inputs['kpis'],
|
|
12419
|
+
};
|
|
12420
|
+
}
|
|
12421
|
+
delete inputs['kpis'];
|
|
12422
|
+
delete inputs['resourcePath'];
|
|
12423
|
+
delete inputs['schemaUrl'];
|
|
12424
|
+
}
|
|
12425
|
+
if (definition.id === 'praxis-filter') {
|
|
12426
|
+
if (!String(inputs['resourcePath'] || '').trim()) {
|
|
12427
|
+
const inferredResourcePath = inferResourcePathFromSchemaUrl(inputs['schemaUrl']);
|
|
12428
|
+
if (inferredResourcePath) {
|
|
12429
|
+
inputs['resourcePath'] = inferredResourcePath;
|
|
12430
|
+
}
|
|
12431
|
+
}
|
|
12432
|
+
delete inputs['schemaUrl'];
|
|
12433
|
+
}
|
|
12434
|
+
if (definition.id === 'praxis-table') {
|
|
12435
|
+
delete inputs['title'];
|
|
12436
|
+
delete inputs['schemaUrl'];
|
|
12437
|
+
delete inputs['submitUrl'];
|
|
12438
|
+
delete inputs['submitMethod'];
|
|
12439
|
+
}
|
|
12440
|
+
return {
|
|
12441
|
+
...widget,
|
|
12442
|
+
definition: {
|
|
12443
|
+
...definition,
|
|
12444
|
+
inputs,
|
|
12445
|
+
},
|
|
12446
|
+
};
|
|
12447
|
+
}
|
|
12448
|
+
function inferResourcePathFromSchemaUrl(schemaUrl) {
|
|
12449
|
+
const raw = String(schemaUrl || '').trim();
|
|
12450
|
+
if (!raw)
|
|
12451
|
+
return undefined;
|
|
12452
|
+
try {
|
|
12453
|
+
const url = new URL(raw, 'http://praxis.local');
|
|
12454
|
+
const path = url.searchParams.get('path') || url.searchParams.get('resourcePath');
|
|
12455
|
+
if (path)
|
|
12456
|
+
return path;
|
|
12457
|
+
}
|
|
12458
|
+
catch {
|
|
12459
|
+
// Keep the fallback below for partial schema URLs.
|
|
12460
|
+
}
|
|
12461
|
+
const match = raw.match(/[?&](?:path|resourcePath)=([^&]+)/);
|
|
12462
|
+
return match?.[1] ? decodeURIComponent(match[1]) : undefined;
|
|
12463
|
+
}
|
|
12464
|
+
function isRecord(value) {
|
|
12465
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
12466
|
+
}
|
|
12467
|
+
|
|
12315
12468
|
const LEGACY_OPTIONS_KEY = 'options';
|
|
12316
12469
|
const LEGACY_LAYOUT_KEY = 'layout';
|
|
12317
12470
|
class PageBuilderAiAdapter {
|
|
@@ -12436,7 +12589,8 @@ class PageBuilderAiAdapter {
|
|
|
12436
12589
|
return page;
|
|
12437
12590
|
const cloned = this.clone(page);
|
|
12438
12591
|
const { [LEGACY_OPTIONS_KEY]: _legacyOptions, ...rest } = cloned;
|
|
12439
|
-
const widgets = (cloned.widgets || [])
|
|
12592
|
+
const widgets = (cloned.widgets || [])
|
|
12593
|
+
.map((w) => normalizePageBuilderRuntimeWidget(this.stripLegacyLayoutFields(w)));
|
|
12440
12594
|
return {
|
|
12441
12595
|
...rest,
|
|
12442
12596
|
widgets,
|
|
@@ -12456,7 +12610,8 @@ class PageBuilderAiAdapter {
|
|
|
12456
12610
|
return page;
|
|
12457
12611
|
const cloned = this.clone(page);
|
|
12458
12612
|
const { [LEGACY_OPTIONS_KEY]: _legacyOptions, ...rest } = cloned;
|
|
12459
|
-
const widgets = (cloned.widgets || [])
|
|
12613
|
+
const widgets = (cloned.widgets || [])
|
|
12614
|
+
.map((w) => normalizePageBuilderRuntimeWidget(this.stripLegacyLayoutFields(w)));
|
|
12460
12615
|
return {
|
|
12461
12616
|
...rest,
|
|
12462
12617
|
widgets,
|
|
@@ -12830,6 +12985,10 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
12830
12985
|
phase: 'capture',
|
|
12831
12986
|
});
|
|
12832
12987
|
}
|
|
12988
|
+
const contextualActionContext = this.contextualPreviewActionContextFromRequest(request);
|
|
12989
|
+
if (contextualActionContext) {
|
|
12990
|
+
return from(this.submitContextualPreviewAction(request, prompt, contextualActionContext));
|
|
12991
|
+
}
|
|
12833
12992
|
if (this.context.enableTurnStream?.() === true && this.service.streamTurn) {
|
|
12834
12993
|
return this.submitWithTurnStream(request, prompt);
|
|
12835
12994
|
}
|
|
@@ -12847,9 +13006,10 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
12847
13006
|
const componentCapabilities = await this.context.loadComponentCapabilities();
|
|
12848
13007
|
const selectedWidgetKey = this.context.selectedWidgetKey();
|
|
12849
13008
|
const intentResolution = await firstValueFrom(this.service.resolveIntent(this.buildIntentResolutionRequest(prompt, selectedWidgetKey, componentCapabilities, authoringContext)));
|
|
12850
|
-
const
|
|
13009
|
+
const intentQuickReplies = this.resolveShellQuickReplies(intentResolution);
|
|
13010
|
+
const intentAssistantMessage = this.normalizeAssistantMessageForQuickReplies(this.resolveIntentAssistantMessage(intentResolution), intentQuickReplies);
|
|
12851
13011
|
if (intentAssistantMessage) {
|
|
12852
|
-
const quickReplies =
|
|
13012
|
+
const quickReplies = intentQuickReplies;
|
|
12853
13013
|
const explicitPendingClarification = this.toShellPendingClarification(intentResolution.pendingClarification);
|
|
12854
13014
|
const intentClarification = this.resolveIntentClarification(intentResolution);
|
|
12855
13015
|
const routeRequiredClarification = this.resolveSharedRuleRouteClarification(intentResolution, this.resolveEffectivePrompt(intentResolution, prompt), request.clientTurnId);
|
|
@@ -12857,10 +13017,13 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
12857
13017
|
?? (intentClarification
|
|
12858
13018
|
? this.buildPendingClarificationForNextTurn(request, this.resolveEffectivePrompt(intentResolution, prompt), intentClarification)
|
|
12859
13019
|
: routeRequiredClarification);
|
|
13020
|
+
const consultativeCatalogIntent = this.isConsultativeCatalogIntent(intentResolution);
|
|
12860
13021
|
const shouldAutoGenerateGuidedPreview = this.shouldAutoGenerateGuidedPreview(intentResolution, quickReplies, prompt) && !this.hasPendingClarificationQuestion(pendingClarification);
|
|
12861
|
-
const mustPauseForClarification = (!this.isExecutableIntent(intentResolution) && !shouldAutoGenerateGuidedPreview)
|
|
13022
|
+
const mustPauseForClarification = (!this.isExecutableIntent(intentResolution, request) && !shouldAutoGenerateGuidedPreview)
|
|
12862
13023
|
|| this.hasPendingClarificationQuestion(pendingClarification);
|
|
12863
|
-
if (mustPauseForClarification
|
|
13024
|
+
if (mustPauseForClarification
|
|
13025
|
+
&& !this.hasPendingClarificationQuestion(pendingClarification)
|
|
13026
|
+
&& (quickReplies.length === 0 || consultativeCatalogIntent)) {
|
|
12864
13027
|
return {
|
|
12865
13028
|
state: 'success',
|
|
12866
13029
|
phase: 'summarize',
|
|
@@ -12909,7 +13072,7 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
12909
13072
|
state: 'clarification',
|
|
12910
13073
|
phase: 'clarify',
|
|
12911
13074
|
assistantMessage: clarification,
|
|
12912
|
-
quickReplies: this.
|
|
13075
|
+
quickReplies: this.resolveShellQuickReplies(intentResolution),
|
|
12913
13076
|
canApply: false,
|
|
12914
13077
|
statusText: '',
|
|
12915
13078
|
errorText: '',
|
|
@@ -12937,7 +13100,7 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
12937
13100
|
model: this.context.model(),
|
|
12938
13101
|
apiKey: this.context.apiKey(),
|
|
12939
13102
|
currentPage: this.context.currentPage(),
|
|
12940
|
-
selectedWidgetKey,
|
|
13103
|
+
selectedWidgetKey: this.resolveSelectedWidgetKey(selectedWidgetKey, authoringContext.contextHints),
|
|
12941
13104
|
intentResolution,
|
|
12942
13105
|
componentCapabilities,
|
|
12943
13106
|
...authoringContext,
|
|
@@ -12970,14 +13133,13 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
12970
13133
|
};
|
|
12971
13134
|
}
|
|
12972
13135
|
const status = this.context.describePreviewStatus(preview);
|
|
12973
|
-
const statusText = this.withProjectKnowledgeAuditStatus(status, preview);
|
|
12974
13136
|
return {
|
|
12975
13137
|
state: 'review',
|
|
12976
13138
|
phase: 'review',
|
|
12977
13139
|
assistantMessage: status,
|
|
12978
13140
|
quickReplies: [],
|
|
12979
13141
|
canApply: true,
|
|
12980
|
-
statusText,
|
|
13142
|
+
statusText: this.reviewStatusText(status, true),
|
|
12981
13143
|
errorText: '',
|
|
12982
13144
|
preview,
|
|
12983
13145
|
diagnostics: { intentResolution },
|
|
@@ -13019,21 +13181,68 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13019
13181
|
pendingPatch: null,
|
|
13020
13182
|
};
|
|
13021
13183
|
}
|
|
13184
|
+
async submitContextualPreviewAction(request, prompt, contextHints) {
|
|
13185
|
+
const componentId = this.readString(contextHints, 'targetComponentId')
|
|
13186
|
+
|| this.readString(contextHints, 'selectedComponentId');
|
|
13187
|
+
const artifactKind = this.readString(contextHints, 'artifactKind')
|
|
13188
|
+
|| (componentId === 'praxis-table' ? 'table' : componentId === 'praxis-dynamic-form' ? 'form' : 'chart');
|
|
13189
|
+
const changeKind = this.readString(contextHints, 'changeKind') || 'contextual_component_action';
|
|
13190
|
+
const intentResolution = {
|
|
13191
|
+
valid: true,
|
|
13192
|
+
operationKind: 'modify',
|
|
13193
|
+
artifactKind,
|
|
13194
|
+
changeKind,
|
|
13195
|
+
authoringProfile: 'component-capability-catalog',
|
|
13196
|
+
targetApp: this.context.targetApp,
|
|
13197
|
+
targetComponentId: this.context.targetComponentId,
|
|
13198
|
+
target: componentId
|
|
13199
|
+
? {
|
|
13200
|
+
componentId,
|
|
13201
|
+
widgetKey: this.readString(contextHints, 'targetWidgetKey')
|
|
13202
|
+
|| this.readString(contextHints, 'selectedWidgetKey')
|
|
13203
|
+
|| this.context.selectedWidgetKey()
|
|
13204
|
+
|| '',
|
|
13205
|
+
resourcePath: this.readString(contextHints, 'resourcePath'),
|
|
13206
|
+
schemaUrl: this.readString(contextHints, 'schemaUrl'),
|
|
13207
|
+
submitUrl: this.readString(contextHints, 'submitUrl'),
|
|
13208
|
+
submitMethod: this.readString(contextHints, 'submitMethod'),
|
|
13209
|
+
}
|
|
13210
|
+
: null,
|
|
13211
|
+
selectedCandidate: this.contextualActionCandidate(contextHints),
|
|
13212
|
+
candidates: [],
|
|
13213
|
+
gate: {
|
|
13214
|
+
gateId: 'component-capability-catalog',
|
|
13215
|
+
status: 'eligible',
|
|
13216
|
+
messages: [],
|
|
13217
|
+
},
|
|
13218
|
+
effectivePrompt: prompt,
|
|
13219
|
+
assistantMessage: null,
|
|
13220
|
+
quickReplies: [],
|
|
13221
|
+
pendingClarification: null,
|
|
13222
|
+
clarificationQuestions: [],
|
|
13223
|
+
warnings: [],
|
|
13224
|
+
failureCodes: [],
|
|
13225
|
+
currentPageSummary: {},
|
|
13226
|
+
contextHints,
|
|
13227
|
+
};
|
|
13228
|
+
return this.completeExecutableStreamPreview(request, prompt, intentResolution, undefined);
|
|
13229
|
+
}
|
|
13022
13230
|
async buildTurnStreamRequest(request, prompt) {
|
|
13023
13231
|
const componentCapabilities = await this.context.loadComponentCapabilities();
|
|
13024
13232
|
const selectedWidgetKey = this.context.selectedWidgetKey();
|
|
13233
|
+
const authoringContext = this.buildAuthoringContext(request);
|
|
13025
13234
|
return {
|
|
13026
13235
|
userPrompt: prompt,
|
|
13027
13236
|
targetApp: this.context.targetApp,
|
|
13028
13237
|
targetComponentId: this.context.targetComponentId,
|
|
13029
13238
|
currentRoute: null,
|
|
13030
13239
|
currentPage: this.context.currentPage(),
|
|
13031
|
-
selectedWidgetKey,
|
|
13240
|
+
selectedWidgetKey: this.resolveSelectedWidgetKey(selectedWidgetKey, authoringContext.contextHints),
|
|
13032
13241
|
provider: this.context.provider(),
|
|
13033
13242
|
model: this.context.model(),
|
|
13034
13243
|
apiKey: this.context.apiKey(),
|
|
13035
13244
|
componentCapabilities,
|
|
13036
|
-
...
|
|
13245
|
+
...authoringContext,
|
|
13037
13246
|
};
|
|
13038
13247
|
}
|
|
13039
13248
|
async toTurnResultFromStreamEvent(event, request, prompt) {
|
|
@@ -13092,14 +13301,21 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13092
13301
|
preview: null,
|
|
13093
13302
|
};
|
|
13094
13303
|
}
|
|
13095
|
-
const
|
|
13304
|
+
const rawAssistantMessage = this.readString(payload, 'assistantMessage')
|
|
13096
13305
|
|| this.resolveIntentAssistantMessage(intentResolution)
|
|
13097
13306
|
|| (preview ? this.context.describePreviewStatus(preview) : '');
|
|
13098
13307
|
const rawQuickReplies = Array.isArray(payload['quickReplies'])
|
|
13099
13308
|
? payload['quickReplies']
|
|
13100
13309
|
: intentResolution.quickReplies ?? [];
|
|
13101
|
-
const quickReplies = this.
|
|
13310
|
+
const quickReplies = this.resolveShellQuickReplies(intentResolution, rawQuickReplies);
|
|
13311
|
+
const assistantMessage = this.normalizeAssistantMessageForQuickReplies(rawAssistantMessage, quickReplies);
|
|
13102
13312
|
const canApply = payload['canApply'] === true && !!preview?.valid;
|
|
13313
|
+
const contextualExecutableIntent = request
|
|
13314
|
+
? this.toExecutableContextualComponentIntent(intentResolution, request)
|
|
13315
|
+
: null;
|
|
13316
|
+
if (!canApply && contextualExecutableIntent && request && prompt) {
|
|
13317
|
+
return this.completeExecutableStreamPreview(request, prompt, contextualExecutableIntent, preview);
|
|
13318
|
+
}
|
|
13103
13319
|
if (canApply
|
|
13104
13320
|
&& request
|
|
13105
13321
|
&& prompt
|
|
@@ -13107,17 +13323,54 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13107
13323
|
return this.completeExecutableStreamPreview(request, prompt, intentResolution, undefined);
|
|
13108
13324
|
}
|
|
13109
13325
|
if (!canApply) {
|
|
13326
|
+
if (preview && this.hasMaterializablePreview(preview) && this.isGovernedBlockedStreamPreview(payload, preview)) {
|
|
13327
|
+
const applied = await this.context.applyLocalPreview(preview);
|
|
13328
|
+
if (!applied.success) {
|
|
13329
|
+
const message = applied.error || this.context.tx('agentic.errors.applyLocal', 'Preview could not be applied.');
|
|
13330
|
+
return {
|
|
13331
|
+
state: 'error',
|
|
13332
|
+
phase: 'preview',
|
|
13333
|
+
assistantMessage: message,
|
|
13334
|
+
canApply: false,
|
|
13335
|
+
statusText: '',
|
|
13336
|
+
errorText: message,
|
|
13337
|
+
preview: null,
|
|
13338
|
+
diagnostics: {
|
|
13339
|
+
intentResolution,
|
|
13340
|
+
preview,
|
|
13341
|
+
decisionDiagnostics: this.toJsonObject(payload['decisionDiagnostics']),
|
|
13342
|
+
toolLoopTrace: Array.isArray(payload['toolLoopTrace']) ? payload['toolLoopTrace'] : undefined,
|
|
13343
|
+
},
|
|
13344
|
+
};
|
|
13345
|
+
}
|
|
13346
|
+
return {
|
|
13347
|
+
state: 'review',
|
|
13348
|
+
phase: 'review',
|
|
13349
|
+
assistantMessage,
|
|
13350
|
+
quickReplies,
|
|
13351
|
+
canApply: false,
|
|
13352
|
+
statusText: this.reviewStatusText(assistantMessage, false),
|
|
13353
|
+
errorText: '',
|
|
13354
|
+
preview,
|
|
13355
|
+
diagnostics: {
|
|
13356
|
+
intentResolution,
|
|
13357
|
+
preview,
|
|
13358
|
+
decisionDiagnostics: this.toJsonObject(payload['decisionDiagnostics']),
|
|
13359
|
+
toolLoopTrace: Array.isArray(payload['toolLoopTrace']) ? payload['toolLoopTrace'] : undefined,
|
|
13360
|
+
},
|
|
13361
|
+
};
|
|
13362
|
+
}
|
|
13110
13363
|
const pendingClarification = this.toShellPendingClarification(intentResolution?.pendingClarification)
|
|
13111
13364
|
?? this.resolveSharedRuleRouteClarification(intentResolution, this.resolveEffectivePrompt(intentResolution, assistantMessage));
|
|
13112
13365
|
if (!pendingClarification
|
|
13113
|
-
&& (this.isExecutableIntent(intentResolution)
|
|
13366
|
+
&& (this.isExecutableIntent(intentResolution, request)
|
|
13114
13367
|
|| (!!prompt && this.shouldAutoGenerateGuidedPreview(intentResolution, quickReplies, prompt)))
|
|
13115
13368
|
&& !this.hasBlockingResourceQuickReply(quickReplies)
|
|
13116
13369
|
&& request
|
|
13117
13370
|
&& prompt) {
|
|
13118
13371
|
return this.completeExecutableStreamPreview(request, prompt, intentResolution, preview);
|
|
13119
13372
|
}
|
|
13120
|
-
const requiresChoice = quickReplies.length > 0;
|
|
13373
|
+
const requiresChoice = quickReplies.length > 0 && !this.isConsultativeCatalogIntent(intentResolution);
|
|
13121
13374
|
return {
|
|
13122
13375
|
state: pendingClarification || requiresChoice ? 'clarification' : 'success',
|
|
13123
13376
|
phase: pendingClarification || requiresChoice ? 'clarify' : 'summarize',
|
|
@@ -13146,14 +13399,13 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13146
13399
|
};
|
|
13147
13400
|
}
|
|
13148
13401
|
const status = assistantMessage || this.context.describePreviewStatus(preview);
|
|
13149
|
-
const statusText = this.withProjectKnowledgeAuditStatus(status, preview);
|
|
13150
13402
|
return {
|
|
13151
13403
|
state: 'review',
|
|
13152
13404
|
phase: 'review',
|
|
13153
13405
|
assistantMessage: status,
|
|
13154
|
-
quickReplies
|
|
13406
|
+
quickReplies,
|
|
13155
13407
|
canApply: true,
|
|
13156
|
-
statusText,
|
|
13408
|
+
statusText: this.reviewStatusText(status, true),
|
|
13157
13409
|
errorText: '',
|
|
13158
13410
|
preview,
|
|
13159
13411
|
diagnostics: { intentResolution, preview },
|
|
@@ -13166,7 +13418,10 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13166
13418
|
return false;
|
|
13167
13419
|
}
|
|
13168
13420
|
const contextHints = this.toJsonObject(reply.contextHints);
|
|
13169
|
-
|
|
13421
|
+
if (this.isContextualPreviewActionReply(reply, contextHints)) {
|
|
13422
|
+
return false;
|
|
13423
|
+
}
|
|
13424
|
+
return !!this.readString(contextHints, 'resourcePath') || this.isResourceQuickReply(reply);
|
|
13170
13425
|
});
|
|
13171
13426
|
}
|
|
13172
13427
|
async completeExecutableStreamPreview(request, prompt, intentResolution, streamPreview) {
|
|
@@ -13174,6 +13429,7 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13174
13429
|
const authoringContext = this.buildAuthoringContext(request);
|
|
13175
13430
|
const componentCapabilities = await this.context.loadComponentCapabilities();
|
|
13176
13431
|
const selectedWidgetKey = this.context.selectedWidgetKey();
|
|
13432
|
+
const effectiveSelectedWidgetKey = this.resolveSelectedWidgetKey(selectedWidgetKey, authoringContext.contextHints);
|
|
13177
13433
|
const reusableStreamPreview = streamPreview?.valid
|
|
13178
13434
|
&& !this.shouldRegenerateStreamPreview(intentResolution, streamPreview);
|
|
13179
13435
|
const preview = reusableStreamPreview
|
|
@@ -13184,7 +13440,7 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13184
13440
|
model: this.context.model(),
|
|
13185
13441
|
apiKey: this.context.apiKey(),
|
|
13186
13442
|
currentPage: this.context.currentPage(),
|
|
13187
|
-
selectedWidgetKey,
|
|
13443
|
+
selectedWidgetKey: effectiveSelectedWidgetKey,
|
|
13188
13444
|
intentResolution,
|
|
13189
13445
|
componentCapabilities,
|
|
13190
13446
|
...authoringContext,
|
|
@@ -13217,14 +13473,13 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13217
13473
|
};
|
|
13218
13474
|
}
|
|
13219
13475
|
const status = this.context.describePreviewStatus(preview);
|
|
13220
|
-
const statusText = this.withProjectKnowledgeAuditStatus(status, preview);
|
|
13221
13476
|
return {
|
|
13222
13477
|
state: 'review',
|
|
13223
13478
|
phase: 'review',
|
|
13224
13479
|
assistantMessage: status,
|
|
13225
13480
|
quickReplies: [],
|
|
13226
13481
|
canApply: true,
|
|
13227
|
-
statusText,
|
|
13482
|
+
statusText: this.reviewStatusText(status, true),
|
|
13228
13483
|
errorText: '',
|
|
13229
13484
|
preview,
|
|
13230
13485
|
diagnostics: { intentResolution, preview },
|
|
@@ -13256,6 +13511,43 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13256
13511
|
}
|
|
13257
13512
|
return true;
|
|
13258
13513
|
}
|
|
13514
|
+
isGovernedBlockedStreamPreview(payload, preview) {
|
|
13515
|
+
const previewDiagnostics = this.toJsonObject(preview.diagnostics);
|
|
13516
|
+
const decisionDiagnostics = this.toJsonObject(payload['decisionDiagnostics'])
|
|
13517
|
+
?? this.toJsonObject(previewDiagnostics?.['decisionDiagnostics']);
|
|
13518
|
+
if (decisionDiagnostics) {
|
|
13519
|
+
if (decisionDiagnostics['requiresReview'] === true) {
|
|
13520
|
+
return true;
|
|
13521
|
+
}
|
|
13522
|
+
if (decisionDiagnostics['decisionValid'] === false) {
|
|
13523
|
+
return true;
|
|
13524
|
+
}
|
|
13525
|
+
if (this.readString(decisionDiagnostics, 'reviewReason')) {
|
|
13526
|
+
return true;
|
|
13527
|
+
}
|
|
13528
|
+
}
|
|
13529
|
+
const warnings = Array.isArray(preview.warnings)
|
|
13530
|
+
? preview.warnings.map((warning) => `${warning}`)
|
|
13531
|
+
: [];
|
|
13532
|
+
const failureCodes = Array.isArray(preview.failureCodes)
|
|
13533
|
+
? preview.failureCodes.map((code) => `${code}`)
|
|
13534
|
+
: [];
|
|
13535
|
+
return warnings.some((warning) => warning === 'semantic-preview-materialization-mismatch'
|
|
13536
|
+
|| warning === 'semantic-axis-schema-verification-pending')
|
|
13537
|
+
|| failureCodes.some((code) => code === 'semantic-decision-required'
|
|
13538
|
+
|| code.startsWith('semantic-preview-'));
|
|
13539
|
+
}
|
|
13540
|
+
hasMaterializablePreview(preview) {
|
|
13541
|
+
if (!preview) {
|
|
13542
|
+
return false;
|
|
13543
|
+
}
|
|
13544
|
+
if (preview.uiCompositionPlan) {
|
|
13545
|
+
return true;
|
|
13546
|
+
}
|
|
13547
|
+
const patch = this.toJsonObject(preview.compiledFormPatch)?.['patch'];
|
|
13548
|
+
const page = this.toJsonObject(patch)?.['page'];
|
|
13549
|
+
return !!this.toJsonObject(page);
|
|
13550
|
+
}
|
|
13259
13551
|
phaseForStreamPayload(payload) {
|
|
13260
13552
|
const phase = this.readString(payload, 'phase');
|
|
13261
13553
|
if (phase === 'intent.resolve')
|
|
@@ -13306,21 +13598,22 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13306
13598
|
}
|
|
13307
13599
|
return base;
|
|
13308
13600
|
}
|
|
13309
|
-
|
|
13310
|
-
const
|
|
13311
|
-
if (!
|
|
13312
|
-
return
|
|
13313
|
-
}
|
|
13314
|
-
const influenceCount = this.readNumber(audit, 'influenceCount');
|
|
13315
|
-
const citedCount = this.readNumber(audit, 'citedCount');
|
|
13316
|
-
if (!influenceCount || influenceCount <= 0 || citedCount === null || citedCount < 0) {
|
|
13317
|
-
return status;
|
|
13601
|
+
reviewStatusText(status, canApply) {
|
|
13602
|
+
const normalized = status.trim();
|
|
13603
|
+
if (normalized && !this.shouldReplaceReviewStatus(normalized)) {
|
|
13604
|
+
return normalized;
|
|
13318
13605
|
}
|
|
13319
|
-
|
|
13320
|
-
.tx('agentic.status.
|
|
13321
|
-
.
|
|
13322
|
-
|
|
13323
|
-
|
|
13606
|
+
return canApply
|
|
13607
|
+
? this.context.tx('agentic.status.reviewReady', 'Ready for review.')
|
|
13608
|
+
: this.context.tx('agentic.status.reviewNeedsAttention', 'Review the pending points before saving.');
|
|
13609
|
+
}
|
|
13610
|
+
shouldReplaceReviewStatus(status) {
|
|
13611
|
+
const normalized = status.toLocaleLowerCase();
|
|
13612
|
+
return status.length > 80
|
|
13613
|
+
|| normalized.includes('preview applied')
|
|
13614
|
+
|| normalized.includes('pré-visualização')
|
|
13615
|
+
|| normalized.includes('pre-visualizacao')
|
|
13616
|
+
|| normalized.includes('sourcerefs');
|
|
13324
13617
|
}
|
|
13325
13618
|
isBackendResourceDiscoveryPayload(payload) {
|
|
13326
13619
|
const diagnostics = this.toJsonObject(payload['diagnostics']);
|
|
@@ -13358,7 +13651,7 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13358
13651
|
}
|
|
13359
13652
|
shouldFallbackFromTurnStreamError(error) {
|
|
13360
13653
|
if (this.isTurnStreamConnectionError(error)) {
|
|
13361
|
-
return
|
|
13654
|
+
return true;
|
|
13362
13655
|
}
|
|
13363
13656
|
if (this.isTurnStreamStartTimeout(error)) {
|
|
13364
13657
|
return true;
|
|
@@ -13503,10 +13796,9 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13503
13796
|
const quickReplies = result.quickReplies?.length
|
|
13504
13797
|
? this.toShellQuickReplies(result.quickReplies)
|
|
13505
13798
|
: this.toResourceCandidateQuickReplies(result.candidates, result.artifactKind);
|
|
13506
|
-
const assistantMessage =
|
|
13507
|
-
|
|
13508
|
-
|
|
13509
|
-
: this.context.tx('agentic.resourceDiscovery.empty', 'I did not find a matching API yet. Describe the business data this screen should use.'));
|
|
13799
|
+
const assistantMessage = quickReplies.length
|
|
13800
|
+
? this.resourceDiscoveryAssistantMessage(result.assistantMessage, quickReplies)
|
|
13801
|
+
: this.context.tx('agentic.resourceDiscovery.empty', 'I did not find a matching API yet. Describe the business data this screen should use.');
|
|
13510
13802
|
const intentResult = await this.resolveIntentAfterResourceDiscovery(request, request.pendingClarification?.sourcePrompt || prompt, contextHints, result, assistantMessage, quickReplies);
|
|
13511
13803
|
if (intentResult) {
|
|
13512
13804
|
return intentResult;
|
|
@@ -13553,12 +13845,16 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13553
13845
|
...authoringContext,
|
|
13554
13846
|
contextHints: this.resourceDiscoveryContextHints(contextHints, result),
|
|
13555
13847
|
})));
|
|
13556
|
-
const
|
|
13848
|
+
const resolvedAssistantMessage = this.resolveIntentAssistantMessage(intentResolution)
|
|
13557
13849
|
|| this.resolveIntentClarification(intentResolution)
|
|
13558
13850
|
|| fallbackAssistantMessage;
|
|
13559
13851
|
const quickReplies = intentResolution.quickReplies?.length
|
|
13560
13852
|
? this.toShellQuickReplies(intentResolution.quickReplies)
|
|
13561
13853
|
: fallbackQuickReplies;
|
|
13854
|
+
const assistantMessage = quickReplies.some((reply) => this.isResourceQuickReply(reply))
|
|
13855
|
+
&& this.isGenericResourceDiscoveryMessage(resolvedAssistantMessage)
|
|
13856
|
+
? fallbackAssistantMessage
|
|
13857
|
+
: resolvedAssistantMessage;
|
|
13562
13858
|
const explicitPendingClarification = this.toShellPendingClarification(intentResolution.pendingClarification);
|
|
13563
13859
|
const routeRequiredClarification = this.resolveSharedRuleRouteClarification(intentResolution, this.resolveEffectivePrompt(intentResolution, prompt), request.clientTurnId);
|
|
13564
13860
|
const pendingClarification = explicitPendingClarification
|
|
@@ -13621,6 +13917,37 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13621
13917
|
const contextHints = this.toJsonObject(request.action?.contextHints);
|
|
13622
13918
|
return this.readString(contextHints, 'tool') === 'searchApiResources';
|
|
13623
13919
|
}
|
|
13920
|
+
resourceDiscoveryAssistantMessage(backendMessage, quickReplies) {
|
|
13921
|
+
const backendText = backendMessage?.trim() ?? '';
|
|
13922
|
+
if (backendText && !this.isGenericResourceDiscoveryMessage(backendText)) {
|
|
13923
|
+
return backendText;
|
|
13924
|
+
}
|
|
13925
|
+
const firstLabel = quickReplies[0]?.label?.trim()
|
|
13926
|
+
|| this.context.tx('agentic.resourceDiscovery.defaultRecommendedLabel', 'the first option');
|
|
13927
|
+
const sourceCount = this.resourceDiscoverySourceCountLabel(quickReplies.length);
|
|
13928
|
+
return this.context.tx('agentic.resourceDiscovery.found', 'I found {sourceCount} for this screen. I recommend starting with {first} because it is the best fit for charts, KPIs, and drill-down. Review the cards below to see what each source is good for, what it returns, and what I will create after you select it.')
|
|
13929
|
+
.replace('{sourceCount}', sourceCount)
|
|
13930
|
+
.replace('{first}', firstLabel);
|
|
13931
|
+
}
|
|
13932
|
+
resourceDiscoverySourceCountLabel(count) {
|
|
13933
|
+
const key = count === 1
|
|
13934
|
+
? 'agentic.resourceDiscovery.sourceCountSingular'
|
|
13935
|
+
: 'agentic.resourceDiscovery.sourceCountPlural';
|
|
13936
|
+
const fallback = count === 1 ? '1 candidate source' : '{count} candidate sources';
|
|
13937
|
+
return this.context.tx(key, fallback).replace('{count}', String(count));
|
|
13938
|
+
}
|
|
13939
|
+
normalizeAssistantMessageForQuickReplies(assistantMessage, quickReplies) {
|
|
13940
|
+
const message = assistantMessage?.trim() ?? '';
|
|
13941
|
+
return quickReplies.some((reply) => this.isResourceQuickReply(reply))
|
|
13942
|
+
? this.resourceDiscoveryAssistantMessage(message, quickReplies)
|
|
13943
|
+
: message;
|
|
13944
|
+
}
|
|
13945
|
+
isGenericResourceDiscoveryMessage(message) {
|
|
13946
|
+
return /(?:encontrei|found).*(?:apis?|fontes?|sources?).*(?:escolha|choose)/iu.test(message)
|
|
13947
|
+
|| /(?:encontrei|found).*(?:fontes?|sources?).*(?:candidatas?|candidate)/iu.test(message)
|
|
13948
|
+
|| /(?:fonte|source).*(?:encontrada|found).*(?:escolha|choose)/iu.test(message)
|
|
13949
|
+
|| /(?:fonte|source).*(?:encontrada|found).*(?:catalogo|catalog)/iu.test(message);
|
|
13950
|
+
}
|
|
13624
13951
|
toResourceCandidateQuickReplies(candidates, artifactKind) {
|
|
13625
13952
|
return candidates
|
|
13626
13953
|
.filter((candidate) => !!candidate.resourcePath?.trim())
|
|
@@ -13680,20 +14007,184 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13680
14007
|
const message = intentResolution.assistantMessage?.trim();
|
|
13681
14008
|
return message || null;
|
|
13682
14009
|
}
|
|
13683
|
-
isExecutableIntent(intentResolution) {
|
|
14010
|
+
isExecutableIntent(intentResolution, request) {
|
|
13684
14011
|
const operationKind = intentResolution.operationKind;
|
|
13685
14012
|
const artifactKind = intentResolution.artifactKind;
|
|
13686
14013
|
const allowsMaterializedArtifactOperation = operationKind === 'create'
|
|
13687
14014
|
|| operationKind === 'modify'
|
|
13688
14015
|
|| operationKind === 'remove';
|
|
13689
14016
|
return !!intentResolution.valid
|
|
13690
|
-
&& intentResolution
|
|
13691
|
-
|
|
13692
|
-
|
|
13693
|
-
|
|
13694
|
-
|
|
13695
|
-
|
|
13696
|
-
|
|
14017
|
+
&& (this.isExecutableContextualComponentIntent(intentResolution, request)
|
|
14018
|
+
|| (intentResolution.gate?.status === 'eligible'
|
|
14019
|
+
&& ((allowsMaterializedArtifactOperation
|
|
14020
|
+
&& !!intentResolution.selectedCandidate
|
|
14021
|
+
&& (artifactKind === 'form'
|
|
14022
|
+
|| artifactKind === 'dashboard'
|
|
14023
|
+
|| artifactKind === 'table'
|
|
14024
|
+
|| artifactKind === 'chart'))
|
|
14025
|
+
|| this.isExecutablePageCompositionIntent(intentResolution))));
|
|
14026
|
+
}
|
|
14027
|
+
isExecutableContextualComponentIntent(intentResolution, request) {
|
|
14028
|
+
const operationKind = intentResolution.operationKind;
|
|
14029
|
+
const requestContextHints = this.contextualPreviewActionContextFromRequest(request)
|
|
14030
|
+
?? this.toJsonObject(request?.action?.contextHints)
|
|
14031
|
+
?? this.toJsonObject(request?.contextHints);
|
|
14032
|
+
const requestIsContextualPreviewAction = this.isContextualPreviewActionContext(requestContextHints);
|
|
14033
|
+
if (!requestIsContextualPreviewAction
|
|
14034
|
+
&& operationKind !== 'create'
|
|
14035
|
+
&& operationKind !== 'modify'
|
|
14036
|
+
&& operationKind !== 'remove') {
|
|
14037
|
+
return false;
|
|
14038
|
+
}
|
|
14039
|
+
const contextHints = this.toJsonObject(intentResolution.contextHints)
|
|
14040
|
+
?? requestContextHints;
|
|
14041
|
+
if (!this.isContextualPreviewActionContext(contextHints) && !requestIsContextualPreviewAction) {
|
|
14042
|
+
return false;
|
|
14043
|
+
}
|
|
14044
|
+
const componentId = this.readString(contextHints, 'targetComponentId')
|
|
14045
|
+
|| this.readString(contextHints, 'selectedComponentId')
|
|
14046
|
+
|| this.readString(requestContextHints, 'targetComponentId')
|
|
14047
|
+
|| this.readString(requestContextHints, 'selectedComponentId')
|
|
14048
|
+
|| intentResolution.target?.componentId
|
|
14049
|
+
|| '';
|
|
14050
|
+
return componentId === 'praxis-chart'
|
|
14051
|
+
|| componentId === 'praxis-table'
|
|
14052
|
+
|| componentId === 'praxis-dynamic-form';
|
|
14053
|
+
}
|
|
14054
|
+
toExecutableContextualComponentIntent(intentResolution, request) {
|
|
14055
|
+
const requestContextHints = this.contextualPreviewActionContextFromRequest(request)
|
|
14056
|
+
?? this.toJsonObject(request.action?.contextHints)
|
|
14057
|
+
?? this.toJsonObject(request.contextHints);
|
|
14058
|
+
if (!this.isContextualPreviewActionContext(requestContextHints)) {
|
|
14059
|
+
return null;
|
|
14060
|
+
}
|
|
14061
|
+
const intentContextHints = this.toJsonObject(intentResolution.contextHints);
|
|
14062
|
+
const contextHints = {
|
|
14063
|
+
...(requestContextHints ?? {}),
|
|
14064
|
+
...(intentContextHints ?? {}),
|
|
14065
|
+
};
|
|
14066
|
+
const componentId = this.readString(contextHints, 'targetComponentId')
|
|
14067
|
+
|| this.readString(contextHints, 'selectedComponentId')
|
|
14068
|
+
|| intentResolution.target?.componentId
|
|
14069
|
+
|| '';
|
|
14070
|
+
if (componentId !== 'praxis-chart'
|
|
14071
|
+
&& componentId !== 'praxis-table'
|
|
14072
|
+
&& componentId !== 'praxis-dynamic-form') {
|
|
14073
|
+
return null;
|
|
14074
|
+
}
|
|
14075
|
+
const currentOperation = intentResolution.operationKind;
|
|
14076
|
+
const operationKind = currentOperation === 'create'
|
|
14077
|
+
|| currentOperation === 'modify'
|
|
14078
|
+
|| currentOperation === 'remove'
|
|
14079
|
+
? currentOperation
|
|
14080
|
+
: 'modify';
|
|
14081
|
+
const artifactKind = intentResolution.artifactKind
|
|
14082
|
+
|| this.readString(contextHints, 'artifactKind')
|
|
14083
|
+
|| (componentId === 'praxis-chart'
|
|
14084
|
+
? 'chart'
|
|
14085
|
+
: componentId === 'praxis-table'
|
|
14086
|
+
? 'table'
|
|
14087
|
+
: 'form');
|
|
14088
|
+
const changeKind = this.readString(contextHints, 'changeKind')
|
|
14089
|
+
|| intentResolution.changeKind
|
|
14090
|
+
|| 'contextual_component_action';
|
|
14091
|
+
return {
|
|
14092
|
+
...intentResolution,
|
|
14093
|
+
valid: true,
|
|
14094
|
+
operationKind,
|
|
14095
|
+
artifactKind,
|
|
14096
|
+
changeKind,
|
|
14097
|
+
gate: {
|
|
14098
|
+
...(intentResolution.gate ?? { gateId: '', status: '', messages: [] }),
|
|
14099
|
+
status: 'eligible',
|
|
14100
|
+
messages: [],
|
|
14101
|
+
},
|
|
14102
|
+
pendingClarification: null,
|
|
14103
|
+
clarificationQuestions: [],
|
|
14104
|
+
failureCodes: [],
|
|
14105
|
+
contextHints,
|
|
14106
|
+
};
|
|
14107
|
+
}
|
|
14108
|
+
isContextualPreviewActionContext(contextHints) {
|
|
14109
|
+
const hints = contextHints ?? null;
|
|
14110
|
+
const hintSource = this.readString(hints, 'source');
|
|
14111
|
+
const hintKind = this.readString(hints, 'kind');
|
|
14112
|
+
return hintSource === 'component-capability-catalog'
|
|
14113
|
+
|| hintKind === 'contextual-preview-action';
|
|
14114
|
+
}
|
|
14115
|
+
contextualPreviewActionContextFromRequest(request) {
|
|
14116
|
+
const explicit = this.toJsonObject(request?.action?.contextHints);
|
|
14117
|
+
if (this.isContextualPreviewActionContext(explicit)) {
|
|
14118
|
+
return explicit;
|
|
14119
|
+
}
|
|
14120
|
+
const actionId = request?.action?.id?.trim();
|
|
14121
|
+
if (!actionId) {
|
|
14122
|
+
return null;
|
|
14123
|
+
}
|
|
14124
|
+
const base = {
|
|
14125
|
+
source: 'component-capability-catalog',
|
|
14126
|
+
kind: 'contextual-preview-action',
|
|
14127
|
+
operationKind: 'modify',
|
|
14128
|
+
};
|
|
14129
|
+
if (actionId === 'chart-change-line' || actionId === 'chart-change-donut') {
|
|
14130
|
+
return {
|
|
14131
|
+
...base,
|
|
14132
|
+
artifactKind: 'chart',
|
|
14133
|
+
changeKind: 'set_chart_type',
|
|
14134
|
+
chartType: actionId === 'chart-change-donut' ? 'donut' : 'line',
|
|
14135
|
+
capabilityId: 'praxis-chart.type.set@0.1.0',
|
|
14136
|
+
targetComponentId: 'praxis-chart',
|
|
14137
|
+
selectedComponentId: 'praxis-chart',
|
|
14138
|
+
};
|
|
14139
|
+
}
|
|
14140
|
+
if (actionId === 'chart-add-detail-table' || actionId === 'chart-add-detail-modal') {
|
|
14141
|
+
return {
|
|
14142
|
+
...base,
|
|
14143
|
+
artifactKind: 'chart',
|
|
14144
|
+
changeKind: 'enable_chart_drilldown',
|
|
14145
|
+
capabilityId: 'praxis-chart.drilldown.enable@0.1.0',
|
|
14146
|
+
targetComponentId: 'praxis-chart',
|
|
14147
|
+
selectedComponentId: 'praxis-chart',
|
|
14148
|
+
...(actionId === 'chart-add-detail-modal'
|
|
14149
|
+
? {
|
|
14150
|
+
surfacePresentation: 'modal',
|
|
14151
|
+
surfaceActionId: 'surface.open',
|
|
14152
|
+
surfaceWidgetId: 'praxis-table',
|
|
14153
|
+
}
|
|
14154
|
+
: {}),
|
|
14155
|
+
};
|
|
14156
|
+
}
|
|
14157
|
+
if (actionId === 'table-export-selected-rows') {
|
|
14158
|
+
return {
|
|
14159
|
+
...base,
|
|
14160
|
+
artifactKind: 'table',
|
|
14161
|
+
changeKind: 'configure_export',
|
|
14162
|
+
capabilityId: 'praxis-table.export.selected-rows@0.1.0',
|
|
14163
|
+
targetComponentId: 'praxis-table',
|
|
14164
|
+
selectedComponentId: 'praxis-table',
|
|
14165
|
+
};
|
|
14166
|
+
}
|
|
14167
|
+
return null;
|
|
14168
|
+
}
|
|
14169
|
+
contextualActionCandidate(contextHints) {
|
|
14170
|
+
const resourcePath = this.readString(contextHints, 'resourcePath');
|
|
14171
|
+
if (!resourcePath) {
|
|
14172
|
+
return null;
|
|
14173
|
+
}
|
|
14174
|
+
const submitUrl = this.readString(contextHints, 'submitUrl') || resourcePath;
|
|
14175
|
+
const submitMethod = this.readString(contextHints, 'submitMethod')
|
|
14176
|
+
|| this.readString(contextHints, 'operation')
|
|
14177
|
+
|| 'get';
|
|
14178
|
+
return {
|
|
14179
|
+
resourcePath,
|
|
14180
|
+
operation: submitMethod,
|
|
14181
|
+
schemaUrl: this.readString(contextHints, 'schemaUrl'),
|
|
14182
|
+
submitUrl,
|
|
14183
|
+
submitMethod,
|
|
14184
|
+
score: 1,
|
|
14185
|
+
reason: 'component capability context',
|
|
14186
|
+
evidence: ['component-capability-catalog'],
|
|
14187
|
+
};
|
|
13697
14188
|
}
|
|
13698
14189
|
shouldAutoGenerateGuidedPreview(intentResolution, quickReplies, prompt) {
|
|
13699
14190
|
if (!this.isGuidedPreviewIntent(intentResolution)) {
|
|
@@ -13705,16 +14196,74 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13705
14196
|
return this.isExplicitPreviewCreationPrompt(prompt);
|
|
13706
14197
|
}
|
|
13707
14198
|
isGuidedPreviewIntent(intentResolution) {
|
|
13708
|
-
if (!intentResolution.valid || intentResolution.gate?.status !== 'eligible'
|
|
14199
|
+
if (!intentResolution.valid || intentResolution.gate?.status !== 'eligible') {
|
|
13709
14200
|
return false;
|
|
13710
14201
|
}
|
|
13711
14202
|
if (this.isExecutableIntent(intentResolution)) {
|
|
13712
14203
|
return true;
|
|
13713
14204
|
}
|
|
14205
|
+
if (!intentResolution.selectedCandidate) {
|
|
14206
|
+
return false;
|
|
14207
|
+
}
|
|
13714
14208
|
const artifactKind = intentResolution.artifactKind;
|
|
13715
14209
|
return (artifactKind === 'dashboard' || artifactKind === 'page' || artifactKind === 'table' || artifactKind === 'form')
|
|
13716
14210
|
&& (intentResolution.operationKind === 'compose' || intentResolution.operationKind === 'explore');
|
|
13717
14211
|
}
|
|
14212
|
+
isConsultativeCatalogIntent(intentResolution) {
|
|
14213
|
+
if (!intentResolution) {
|
|
14214
|
+
return false;
|
|
14215
|
+
}
|
|
14216
|
+
const operationKind = intentResolution.operationKind;
|
|
14217
|
+
const changeKind = intentResolution.changeKind;
|
|
14218
|
+
return (operationKind === 'explore' || operationKind === 'explain')
|
|
14219
|
+
&& intentResolution.artifactKind === 'api_catalog'
|
|
14220
|
+
&& (changeKind === 'answer_api_catalog_question'
|
|
14221
|
+
|| changeKind === 'answer_catalog_question'
|
|
14222
|
+
|| changeKind === 'api_catalog_followup'
|
|
14223
|
+
|| intentResolution.authoringProfile === 'api-catalog-qa');
|
|
14224
|
+
}
|
|
14225
|
+
resolveShellQuickReplies(intentResolution, quickReplies = intentResolution.quickReplies ?? []) {
|
|
14226
|
+
const effectiveQuickReplies = this.isConsultativeCatalogIntent(intentResolution)
|
|
14227
|
+
? quickReplies.filter((reply) => !this.isResourceCandidateQuickReply(reply))
|
|
14228
|
+
: this.shouldSuppressWorkflowQuickReplies(intentResolution)
|
|
14229
|
+
? quickReplies.filter((reply) => !this.isWorkflowQuickReply(reply))
|
|
14230
|
+
: quickReplies;
|
|
14231
|
+
const shellQuickReplies = this.toShellQuickReplies(effectiveQuickReplies);
|
|
14232
|
+
if (shellQuickReplies.length) {
|
|
14233
|
+
return shellQuickReplies;
|
|
14234
|
+
}
|
|
14235
|
+
return this.contextualCapabilityFallbackQuickReplies(intentResolution);
|
|
14236
|
+
}
|
|
14237
|
+
shouldSuppressWorkflowQuickReplies(intentResolution) {
|
|
14238
|
+
if (intentResolution.selectedCandidate || this.isConsultativeCatalogIntent(intentResolution)) {
|
|
14239
|
+
return false;
|
|
14240
|
+
}
|
|
14241
|
+
const operationKind = (intentResolution.operationKind ?? '').trim().toLowerCase();
|
|
14242
|
+
const artifactKind = (intentResolution.artifactKind ?? '').trim().toLowerCase();
|
|
14243
|
+
const changeKind = (intentResolution.changeKind ?? '').trim().toLowerCase();
|
|
14244
|
+
return artifactKind === 'unknown'
|
|
14245
|
+
|| operationKind === 'unknown'
|
|
14246
|
+
|| changeKind === 'unknown';
|
|
14247
|
+
}
|
|
14248
|
+
isWorkflowQuickReply(reply) {
|
|
14249
|
+
const kind = (reply.kind ?? '').trim().toLowerCase();
|
|
14250
|
+
return kind === 'revise' || kind === 'cancel' || kind === 'confirm';
|
|
14251
|
+
}
|
|
14252
|
+
isResourceCandidateQuickReply(reply) {
|
|
14253
|
+
const kind = (reply.kind ?? '').trim().toLowerCase();
|
|
14254
|
+
if (kind !== 'suggestion') {
|
|
14255
|
+
return false;
|
|
14256
|
+
}
|
|
14257
|
+
const contextHints = this.toJsonObject(reply.contextHints);
|
|
14258
|
+
if (this.isContextualPreviewActionReply(reply, contextHints)) {
|
|
14259
|
+
return false;
|
|
14260
|
+
}
|
|
14261
|
+
return !!contextHints
|
|
14262
|
+
&& (!!contextHints['resourcePath']
|
|
14263
|
+
|| !!contextHints['resourceKey']
|
|
14264
|
+
|| !!contextHints['submitUrl']
|
|
14265
|
+
|| !!contextHints['schemaUrl']);
|
|
14266
|
+
}
|
|
13718
14267
|
isExplicitPreviewCreationPrompt(prompt) {
|
|
13719
14268
|
const normalized = prompt
|
|
13720
14269
|
.normalize('NFD')
|
|
@@ -13759,9 +14308,19 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13759
14308
|
return action && artifact;
|
|
13760
14309
|
}
|
|
13761
14310
|
isExecutablePageCompositionIntent(intentResolution) {
|
|
13762
|
-
|
|
13763
|
-
|
|
13764
|
-
|
|
14311
|
+
if (intentResolution.artifactKind !== 'page') {
|
|
14312
|
+
return false;
|
|
14313
|
+
}
|
|
14314
|
+
if ((intentResolution.operationKind === 'compose' || intentResolution.operationKind === 'modify')
|
|
14315
|
+
&& intentResolution.authoringProfile === 'ui-composition-plan@0.1.0') {
|
|
14316
|
+
return true;
|
|
14317
|
+
}
|
|
14318
|
+
if (intentResolution.operationKind !== 'create') {
|
|
14319
|
+
return false;
|
|
14320
|
+
}
|
|
14321
|
+
return intentResolution.changeKind === 'create_master_detail'
|
|
14322
|
+
|| intentResolution.changeKind === 'create_tabbed_master_detail_form'
|
|
14323
|
+
|| intentResolution.changeKind === 'create_artifact';
|
|
13765
14324
|
}
|
|
13766
14325
|
resolveIntentClarification(intentResolution) {
|
|
13767
14326
|
const questions = this.readIntentResolutionStringList(intentResolution?.clarificationQuestions);
|
|
@@ -13809,7 +14368,7 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13809
14368
|
toShellQuickReplies(quickReplies) {
|
|
13810
14369
|
return quickReplies
|
|
13811
14370
|
.filter((reply) => !!reply.id && !!reply.label && (!!reply.prompt || reply.kind === 'cancel'))
|
|
13812
|
-
.map((reply) => ({
|
|
14371
|
+
.map((reply) => this.enrichShellQuickReply({
|
|
13813
14372
|
id: reply.id,
|
|
13814
14373
|
kind: reply.kind,
|
|
13815
14374
|
label: reply.label,
|
|
@@ -13817,9 +14376,334 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13817
14376
|
description: reply.description,
|
|
13818
14377
|
icon: reply.icon,
|
|
13819
14378
|
tone: reply.tone,
|
|
14379
|
+
presentation: null,
|
|
13820
14380
|
contextHints: this.toJsonObject(reply.contextHints),
|
|
13821
14381
|
}));
|
|
13822
14382
|
}
|
|
14383
|
+
contextualCapabilityFallbackQuickReplies(intentResolution) {
|
|
14384
|
+
if (!this.shouldOfferContextualCapabilityActions(intentResolution)) {
|
|
14385
|
+
return [];
|
|
14386
|
+
}
|
|
14387
|
+
const componentContext = this.resolveCurrentComponentContext(intentResolution);
|
|
14388
|
+
if (componentContext?.componentId !== 'praxis-chart') {
|
|
14389
|
+
return [];
|
|
14390
|
+
}
|
|
14391
|
+
return [
|
|
14392
|
+
this.contextualCapabilityQuickReply({
|
|
14393
|
+
id: 'chart-change-line',
|
|
14394
|
+
label: this.context.tx('agentic.quickReplies.chartChangeLine.label', 'Trocar para linhas'),
|
|
14395
|
+
prompt: this.context.tx('agentic.quickReplies.chartChangeLine.prompt', 'Altere o gráfico selecionado para linhas.'),
|
|
14396
|
+
icon: 'show_chart',
|
|
14397
|
+
changeKind: 'set_chart_type',
|
|
14398
|
+
chartType: 'line',
|
|
14399
|
+
capabilityId: 'praxis-chart.type.set@0.1.0',
|
|
14400
|
+
widgetKey: componentContext.widgetKey,
|
|
14401
|
+
}),
|
|
14402
|
+
this.contextualCapabilityQuickReply({
|
|
14403
|
+
id: 'chart-change-donut',
|
|
14404
|
+
label: this.context.tx('agentic.quickReplies.chartChangeDonut.label', 'Ver como donut'),
|
|
14405
|
+
prompt: this.context.tx('agentic.quickReplies.chartChangeDonut.prompt', 'Altere o gráfico selecionado para donut.'),
|
|
14406
|
+
icon: 'donut_large',
|
|
14407
|
+
changeKind: 'set_chart_type',
|
|
14408
|
+
chartType: 'donut',
|
|
14409
|
+
capabilityId: 'praxis-chart.type.set@0.1.0',
|
|
14410
|
+
widgetKey: componentContext.widgetKey,
|
|
14411
|
+
}),
|
|
14412
|
+
this.contextualCapabilityQuickReply({
|
|
14413
|
+
id: 'chart-add-detail-table',
|
|
14414
|
+
label: this.context.tx('agentic.quickReplies.chartAddDetailTable.label', 'Detalhes em tabela'),
|
|
14415
|
+
prompt: this.context.tx('agentic.quickReplies.chartAddDetailTable.prompt', 'Adicione uma tabela de detalhes para a seleção do gráfico.'),
|
|
14416
|
+
icon: 'table_view',
|
|
14417
|
+
changeKind: 'enable_chart_drilldown',
|
|
14418
|
+
capabilityId: 'praxis-chart.drilldown.enable@0.1.0',
|
|
14419
|
+
widgetKey: componentContext.widgetKey,
|
|
14420
|
+
}),
|
|
14421
|
+
];
|
|
14422
|
+
}
|
|
14423
|
+
contextualCapabilityQuickReply(options) {
|
|
14424
|
+
return this.enrichContextualActionQuickReply({
|
|
14425
|
+
id: options.id,
|
|
14426
|
+
kind: 'suggestion',
|
|
14427
|
+
label: options.label,
|
|
14428
|
+
prompt: options.prompt,
|
|
14429
|
+
icon: options.icon,
|
|
14430
|
+
tone: 'analytics',
|
|
14431
|
+
contextHints: {
|
|
14432
|
+
source: 'component-capability-catalog',
|
|
14433
|
+
kind: 'contextual-preview-action',
|
|
14434
|
+
operationKind: 'modify',
|
|
14435
|
+
artifactKind: 'chart',
|
|
14436
|
+
changeKind: options.changeKind,
|
|
14437
|
+
...(options.chartType ? { chartType: options.chartType } : {}),
|
|
14438
|
+
capabilityId: options.capabilityId,
|
|
14439
|
+
targetComponentId: 'praxis-chart',
|
|
14440
|
+
selectedComponentId: 'praxis-chart',
|
|
14441
|
+
...(options.widgetKey ? { selectedWidgetKey: options.widgetKey } : {}),
|
|
14442
|
+
},
|
|
14443
|
+
});
|
|
14444
|
+
}
|
|
14445
|
+
shouldOfferContextualCapabilityActions(intentResolution) {
|
|
14446
|
+
if (this.isConsultativeCatalogIntent(intentResolution)) {
|
|
14447
|
+
return false;
|
|
14448
|
+
}
|
|
14449
|
+
const operationKind = (intentResolution.operationKind ?? '').trim().toLowerCase();
|
|
14450
|
+
const artifactKind = (intentResolution.artifactKind ?? '').trim().toLowerCase();
|
|
14451
|
+
const changeKind = (intentResolution.changeKind ?? '').trim().toLowerCase();
|
|
14452
|
+
if (operationKind !== 'explore' && operationKind !== 'explain') {
|
|
14453
|
+
return false;
|
|
14454
|
+
}
|
|
14455
|
+
if (artifactKind === 'chart') {
|
|
14456
|
+
return true;
|
|
14457
|
+
}
|
|
14458
|
+
return changeKind.includes('chart')
|
|
14459
|
+
|| changeKind.includes('component')
|
|
14460
|
+
|| !!this.resolveCurrentComponentContext(intentResolution);
|
|
14461
|
+
}
|
|
14462
|
+
resolveCurrentComponentContext(intentResolution) {
|
|
14463
|
+
const contextHints = this.toJsonObject(intentResolution.contextHints);
|
|
14464
|
+
const targetComponentId = this.readString(contextHints, 'targetComponentId')
|
|
14465
|
+
|| this.readString(contextHints, 'selectedComponentId')
|
|
14466
|
+
|| intentResolution.target?.componentId
|
|
14467
|
+
|| '';
|
|
14468
|
+
const targetWidgetKey = this.readString(contextHints, 'selectedWidgetKey')
|
|
14469
|
+
|| intentResolution.target?.widgetKey
|
|
14470
|
+
|| this.context.selectedWidgetKey()
|
|
14471
|
+
|| '';
|
|
14472
|
+
if (targetComponentId) {
|
|
14473
|
+
return { componentId: targetComponentId, widgetKey: targetWidgetKey || null };
|
|
14474
|
+
}
|
|
14475
|
+
const page = this.currentPageRecord();
|
|
14476
|
+
const widgets = Array.isArray(page?.['widgets']) ? page['widgets'] : [];
|
|
14477
|
+
const selectedWidget = targetWidgetKey
|
|
14478
|
+
? widgets.find((widget) => this.readWidgetKey(widget) === targetWidgetKey)
|
|
14479
|
+
: null;
|
|
14480
|
+
const selectedComponentId = selectedWidget ? this.readWidgetComponentId(selectedWidget) : '';
|
|
14481
|
+
if (selectedComponentId) {
|
|
14482
|
+
return { componentId: selectedComponentId, widgetKey: targetWidgetKey || null };
|
|
14483
|
+
}
|
|
14484
|
+
const chartWidget = widgets.find((widget) => this.readWidgetComponentId(widget) === 'praxis-chart');
|
|
14485
|
+
if (chartWidget) {
|
|
14486
|
+
return {
|
|
14487
|
+
componentId: 'praxis-chart',
|
|
14488
|
+
widgetKey: this.readWidgetKey(chartWidget) || null,
|
|
14489
|
+
};
|
|
14490
|
+
}
|
|
14491
|
+
return null;
|
|
14492
|
+
}
|
|
14493
|
+
currentPageRecord() {
|
|
14494
|
+
const page = this.context.currentPage();
|
|
14495
|
+
return page && typeof page === 'object' && !Array.isArray(page)
|
|
14496
|
+
? page
|
|
14497
|
+
: null;
|
|
14498
|
+
}
|
|
14499
|
+
readWidgetKey(widget) {
|
|
14500
|
+
const record = widget && typeof widget === 'object' && !Array.isArray(widget)
|
|
14501
|
+
? widget
|
|
14502
|
+
: null;
|
|
14503
|
+
const key = record?.['key'];
|
|
14504
|
+
return typeof key === 'string' ? key.trim() : '';
|
|
14505
|
+
}
|
|
14506
|
+
readWidgetComponentId(widget) {
|
|
14507
|
+
const record = widget && typeof widget === 'object' && !Array.isArray(widget)
|
|
14508
|
+
? widget
|
|
14509
|
+
: null;
|
|
14510
|
+
const definition = record?.['definition'];
|
|
14511
|
+
const definitionRecord = definition && typeof definition === 'object' && !Array.isArray(definition)
|
|
14512
|
+
? definition
|
|
14513
|
+
: null;
|
|
14514
|
+
const id = definitionRecord?.['id'];
|
|
14515
|
+
return typeof id === 'string' ? id.trim() : '';
|
|
14516
|
+
}
|
|
14517
|
+
enrichShellQuickReply(reply) {
|
|
14518
|
+
if (this.isContextualPreviewActionReply(reply, this.toJsonObject(reply.contextHints))) {
|
|
14519
|
+
return this.enrichContextualActionQuickReply(reply);
|
|
14520
|
+
}
|
|
14521
|
+
if (!this.isResourceQuickReply(reply)) {
|
|
14522
|
+
return reply;
|
|
14523
|
+
}
|
|
14524
|
+
const contextHints = { ...(reply.contextHints ?? {}) };
|
|
14525
|
+
if (!this.hasQuickReplyPresentation(contextHints)) {
|
|
14526
|
+
contextHints['presentation'] = this.resourceQuickReplyPresentation(reply);
|
|
14527
|
+
}
|
|
14528
|
+
return {
|
|
14529
|
+
...reply,
|
|
14530
|
+
description: this.resourceQuickReplyDescription(reply),
|
|
14531
|
+
icon: reply.icon || 'dataset',
|
|
14532
|
+
tone: reply.tone || 'resource',
|
|
14533
|
+
contextHints,
|
|
14534
|
+
};
|
|
14535
|
+
}
|
|
14536
|
+
enrichContextualActionQuickReply(reply) {
|
|
14537
|
+
const contextHints = this.toJsonObject(reply.contextHints) ?? {};
|
|
14538
|
+
const presentation = {
|
|
14539
|
+
kind: 'contextual-action',
|
|
14540
|
+
categoryLabel: this.context.tx('agentic.quickReplies.contextualAction.category', 'Ação sugerida'),
|
|
14541
|
+
description: this.contextualActionDescription(reply, contextHints),
|
|
14542
|
+
ctaLabel: this.context.tx('agentic.quickReplies.contextualAction.cta', 'Pré-visualizar ajuste'),
|
|
14543
|
+
icon: reply.icon || this.contextualActionIcon(reply, contextHints),
|
|
14544
|
+
tone: reply.tone || 'analytics',
|
|
14545
|
+
evidence: this.contextualActionEvidence(contextHints),
|
|
14546
|
+
};
|
|
14547
|
+
return {
|
|
14548
|
+
...reply,
|
|
14549
|
+
description: presentation.description,
|
|
14550
|
+
icon: presentation.icon,
|
|
14551
|
+
tone: presentation.tone,
|
|
14552
|
+
presentation,
|
|
14553
|
+
};
|
|
14554
|
+
}
|
|
14555
|
+
contextualActionDescription(reply, contextHints) {
|
|
14556
|
+
const existing = reply.description?.trim() ?? '';
|
|
14557
|
+
if (existing && !this.isGenericContextualActionDescription(existing)) {
|
|
14558
|
+
return existing;
|
|
14559
|
+
}
|
|
14560
|
+
const changeKind = this.readString(contextHints, 'changeKind');
|
|
14561
|
+
switch (changeKind) {
|
|
14562
|
+
case 'set_chart_type':
|
|
14563
|
+
return this.context.tx('agentic.quickReplies.contextualAction.chartType.description', 'Altera apenas a apresentação do gráfico selecionado e mantém a fonte de dados atual.');
|
|
14564
|
+
case 'enable_chart_drilldown':
|
|
14565
|
+
return this.context.tx('agentic.quickReplies.contextualAction.chartDrilldown.description', 'Adiciona uma superfície de detalhe a partir da seleção do gráfico, preservando o contexto do dado.');
|
|
14566
|
+
case 'configure_export':
|
|
14567
|
+
return this.context.tx('agentic.quickReplies.contextualAction.export.description', 'Configura uma ação operacional para exportar a seleção atual sem mudar a consulta base.');
|
|
14568
|
+
default:
|
|
14569
|
+
return this.context.tx('agentic.quickReplies.contextualAction.default.description', 'Prepara um ajuste compatível com as capacidades confirmadas do componente selecionado.');
|
|
14570
|
+
}
|
|
14571
|
+
}
|
|
14572
|
+
contextualActionIcon(reply, contextHints) {
|
|
14573
|
+
const changeKind = this.readString(contextHints, 'changeKind');
|
|
14574
|
+
const chartType = this.readString(contextHints, 'chartType')
|
|
14575
|
+
|| this.readString(contextHints, 'targetChartType');
|
|
14576
|
+
const actionId = reply.id?.trim() ?? '';
|
|
14577
|
+
if (changeKind === 'set_chart_type') {
|
|
14578
|
+
return chartType === 'donut' || actionId === 'chart-change-donut'
|
|
14579
|
+
? 'donut_large'
|
|
14580
|
+
: 'show_chart';
|
|
14581
|
+
}
|
|
14582
|
+
if (changeKind === 'enable_chart_drilldown')
|
|
14583
|
+
return 'table_view';
|
|
14584
|
+
if (changeKind === 'configure_export')
|
|
14585
|
+
return 'ios_share';
|
|
14586
|
+
return 'auto_fix_high';
|
|
14587
|
+
}
|
|
14588
|
+
contextualActionEvidence(contextHints) {
|
|
14589
|
+
const evidence = [];
|
|
14590
|
+
const targetComponentId = this.readString(contextHints, 'targetComponentId')
|
|
14591
|
+
|| this.readString(contextHints, 'selectedComponentId');
|
|
14592
|
+
const changeKind = this.readString(contextHints, 'changeKind');
|
|
14593
|
+
const capabilityId = this.readString(contextHints, 'capabilityId');
|
|
14594
|
+
const selectedWidgetKey = this.readString(contextHints, 'selectedWidgetKey');
|
|
14595
|
+
if (targetComponentId) {
|
|
14596
|
+
evidence.push({
|
|
14597
|
+
icon: 'widgets',
|
|
14598
|
+
value: this.shortTechnicalLabel(targetComponentId),
|
|
14599
|
+
ariaLabel: this.context.tx('agentic.quickReplies.contextualAction.componentEvidence', 'Componente {value}').replace('{value}', targetComponentId),
|
|
14600
|
+
});
|
|
14601
|
+
}
|
|
14602
|
+
if (changeKind) {
|
|
14603
|
+
evidence.push({
|
|
14604
|
+
icon: 'rule',
|
|
14605
|
+
value: this.shortTechnicalLabel(changeKind),
|
|
14606
|
+
ariaLabel: this.context.tx('agentic.quickReplies.contextualAction.changeEvidence', 'Mudança {value}').replace('{value}', changeKind),
|
|
14607
|
+
});
|
|
14608
|
+
}
|
|
14609
|
+
if (capabilityId) {
|
|
14610
|
+
evidence.push({
|
|
14611
|
+
icon: 'verified',
|
|
14612
|
+
value: this.context.tx('agentic.quickReplies.contextualAction.capabilityEvidence', 'capability'),
|
|
14613
|
+
ariaLabel: capabilityId,
|
|
14614
|
+
});
|
|
14615
|
+
}
|
|
14616
|
+
if (!capabilityId && selectedWidgetKey) {
|
|
14617
|
+
evidence.push({
|
|
14618
|
+
icon: 'ads_click',
|
|
14619
|
+
value: this.context.tx('agentic.quickReplies.contextualAction.selectionEvidence', 'seleção atual'),
|
|
14620
|
+
ariaLabel: selectedWidgetKey,
|
|
14621
|
+
});
|
|
14622
|
+
}
|
|
14623
|
+
return evidence.slice(0, 4);
|
|
14624
|
+
}
|
|
14625
|
+
isResourceQuickReply(reply) {
|
|
14626
|
+
const kind = (reply.kind || '').trim().toLowerCase();
|
|
14627
|
+
const id = (reply.id || '').trim().toLowerCase();
|
|
14628
|
+
const contextHints = this.toJsonObject(reply.contextHints);
|
|
14629
|
+
if (this.isContextualPreviewActionReply(reply, contextHints)) {
|
|
14630
|
+
return false;
|
|
14631
|
+
}
|
|
14632
|
+
return kind === 'resource'
|
|
14633
|
+
|| id.startsWith('resource-')
|
|
14634
|
+
|| !!this.readString(contextHints, 'resourcePath');
|
|
14635
|
+
}
|
|
14636
|
+
isContextualPreviewActionReply(reply, contextHints) {
|
|
14637
|
+
const hintSource = typeof contextHints?.['source'] === 'string'
|
|
14638
|
+
? contextHints['source'].trim()
|
|
14639
|
+
: '';
|
|
14640
|
+
const hintKind = typeof contextHints?.['kind'] === 'string'
|
|
14641
|
+
? contextHints['kind'].trim()
|
|
14642
|
+
: '';
|
|
14643
|
+
return hintSource === 'component-capability-catalog'
|
|
14644
|
+
|| hintKind === 'contextual-preview-action'
|
|
14645
|
+
|| (reply.id ?? '').startsWith('chart-')
|
|
14646
|
+
|| (reply.id ?? '').startsWith('table-export-');
|
|
14647
|
+
}
|
|
14648
|
+
hasQuickReplyPresentation(contextHints) {
|
|
14649
|
+
const presentation = contextHints['presentation'];
|
|
14650
|
+
if (!presentation || Array.isArray(presentation) || typeof presentation !== 'object') {
|
|
14651
|
+
return false;
|
|
14652
|
+
}
|
|
14653
|
+
return ['bestFor', 'returns', 'nextStep']
|
|
14654
|
+
.some((key) => typeof presentation[key] === 'string'
|
|
14655
|
+
&& !!String(presentation[key]).trim());
|
|
14656
|
+
}
|
|
14657
|
+
resourceQuickReplyDescription(reply) {
|
|
14658
|
+
const description = reply.description?.trim() ?? '';
|
|
14659
|
+
if (description
|
|
14660
|
+
&& !this.isTechnicalResourceDescription(description)
|
|
14661
|
+
&& !this.isGenericResourceDescription(description)) {
|
|
14662
|
+
return description;
|
|
14663
|
+
}
|
|
14664
|
+
return this.context.tx('agentic.resourceDiscovery.cardDescription', 'Fonte recomendada para transformar {label} em painel: ajuda a escolher graficos, listas, filtros e formatos antes de materializar a tela.').replace('{label}', reply.label);
|
|
14665
|
+
}
|
|
14666
|
+
resourceQuickReplyPresentation(reply) {
|
|
14667
|
+
const contextHints = this.toJsonObject(reply.contextHints);
|
|
14668
|
+
const artifactKind = this.readString(contextHints, 'artifactKind');
|
|
14669
|
+
if (artifactKind === 'table') {
|
|
14670
|
+
return {
|
|
14671
|
+
bestFor: `Boa quando voce quer transformar ${reply.label} em uma tabela navegavel.`,
|
|
14672
|
+
returns: 'Retorna uma pre-visualizacao com colunas, filtros e fonte semantica preservada.',
|
|
14673
|
+
nextStep: 'Clique para criar a tabela e revisar antes de salvar.',
|
|
14674
|
+
};
|
|
14675
|
+
}
|
|
14676
|
+
return {
|
|
14677
|
+
bestFor: this.context.tx('agentic.resourceDiscovery.cardBestFor', 'Quando voce quer entender se {label} responde ao objetivo de negocio antes de criar widgets.').replace('{label}', reply.label),
|
|
14678
|
+
returns: this.context.tx('agentic.resourceDiscovery.cardReturns', 'Sugere metricas, dimensoes, filtros, formatos de valor, graficos e listas de detalhe compativeis com a fonte.'),
|
|
14679
|
+
nextStep: this.context.tx('agentic.resourceDiscovery.cardNextStep', 'Selecione para eu propor uma pre-visualizacao governada com cards ricos, drill-down e formatos adequados por padrao.'),
|
|
14680
|
+
};
|
|
14681
|
+
}
|
|
14682
|
+
isTechnicalResourceDescription(description) {
|
|
14683
|
+
return /(?:^|\s)(?:GET|POST|PUT|PATCH|DELETE)\s+\//iu.test(description)
|
|
14684
|
+
|| /\/api\//iu.test(description)
|
|
14685
|
+
|| /\/schemas\//iu.test(description);
|
|
14686
|
+
}
|
|
14687
|
+
isGenericResourceDescription(description) {
|
|
14688
|
+
return /op(?:c|ç)ao encontrada no cat(?:a|á)logo sem(?:a|â)ntico/iu.test(description)
|
|
14689
|
+
|| /fonte candidata encontrada no cat(?:a|á)logo/iu.test(description);
|
|
14690
|
+
}
|
|
14691
|
+
isGenericContextualActionDescription(description) {
|
|
14692
|
+
const normalized = description
|
|
14693
|
+
.normalize('NFD')
|
|
14694
|
+
.replace(/[\u0300-\u036f]/g, '')
|
|
14695
|
+
.toLocaleLowerCase('pt-BR');
|
|
14696
|
+
return normalized.includes('acao sugerida')
|
|
14697
|
+
&& normalized.includes('capacidades confirmadas');
|
|
14698
|
+
}
|
|
14699
|
+
shortTechnicalLabel(value) {
|
|
14700
|
+
return value
|
|
14701
|
+
.trim()
|
|
14702
|
+
.replace(/^praxis-/u, '')
|
|
14703
|
+
.replace(/@.*$/u, '')
|
|
14704
|
+
.replace(/[_-]+/gu, ' ')
|
|
14705
|
+
.trim();
|
|
14706
|
+
}
|
|
13823
14707
|
buildPendingClarificationForNextTurn(request, sourcePrompt, clarification) {
|
|
13824
14708
|
return this.buildPendingClarification(sourcePrompt, clarification, request.clientTurnId);
|
|
13825
14709
|
}
|
|
@@ -13894,7 +14778,7 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13894
14778
|
targetApp: this.context.targetApp,
|
|
13895
14779
|
targetComponentId: this.context.targetComponentId,
|
|
13896
14780
|
currentPage: this.context.currentPage(),
|
|
13897
|
-
selectedWidgetKey,
|
|
14781
|
+
selectedWidgetKey: this.resolveSelectedWidgetKey(selectedWidgetKey, authoringContext.contextHints),
|
|
13898
14782
|
provider: this.context.provider(),
|
|
13899
14783
|
model: this.context.model(),
|
|
13900
14784
|
apiKey: this.context.apiKey(),
|
|
@@ -13902,6 +14786,12 @@ class PageBuilderAgenticAuthoringTurnFlow {
|
|
|
13902
14786
|
...authoringContext,
|
|
13903
14787
|
};
|
|
13904
14788
|
}
|
|
14789
|
+
resolveSelectedWidgetKey(selectedWidgetKey, contextHints) {
|
|
14790
|
+
const hints = this.toJsonObject(contextHints) ?? null;
|
|
14791
|
+
return this.readString(hints, 'selectedWidgetKey')
|
|
14792
|
+
|| this.readString(hints, 'targetWidgetKey')
|
|
14793
|
+
|| selectedWidgetKey;
|
|
14794
|
+
}
|
|
13905
14795
|
buildContextHints(request) {
|
|
13906
14796
|
const base = this.toJsonObject(request.action?.contextHints)
|
|
13907
14797
|
?? this.toJsonObject(request.contextHints);
|
|
@@ -14094,6 +14984,7 @@ function projectKnowledgeTarget(changeSet, conceptKey) {
|
|
|
14094
14984
|
};
|
|
14095
14985
|
}
|
|
14096
14986
|
|
|
14987
|
+
const AGENTIC_PAGE_COMPOSITION_REQUEST_OUTPUT = 'agenticPageCompositionRequested';
|
|
14097
14988
|
class DynamicPageBuilderComponent {
|
|
14098
14989
|
dialog;
|
|
14099
14990
|
settingsPanel;
|
|
@@ -14129,6 +15020,7 @@ class DynamicPageBuilderComponent {
|
|
|
14129
15020
|
pageLifecycleBusy = false;
|
|
14130
15021
|
pageLifecycleResetRevision = null;
|
|
14131
15022
|
pageChange = new EventEmitter();
|
|
15023
|
+
pageSaveRequested = new EventEmitter();
|
|
14132
15024
|
agenticAuthoringApplied = new EventEmitter();
|
|
14133
15025
|
agenticAuthoringSharedRuleHandoff = new EventEmitter();
|
|
14134
15026
|
pageRestart = new EventEmitter();
|
|
@@ -14142,6 +15034,8 @@ class DynamicPageBuilderComponent {
|
|
|
14142
15034
|
agenticAuthoringStatus = signal('', ...(ngDevMode ? [{ debugName: "agenticAuthoringStatus" }] : []));
|
|
14143
15035
|
agenticAuthoringError = signal('', ...(ngDevMode ? [{ debugName: "agenticAuthoringError" }] : []));
|
|
14144
15036
|
agenticAuthoringPreviewResult = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringPreviewResult" }] : []));
|
|
15037
|
+
agenticAuthoringSemanticDecision = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringSemanticDecision" }] : []));
|
|
15038
|
+
agenticAuthoringCanApply = signal(false, ...(ngDevMode ? [{ debugName: "agenticAuthoringCanApply" }] : []));
|
|
14145
15039
|
agenticAuthoringLastEtag = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringLastEtag" }] : []));
|
|
14146
15040
|
agenticAuthoringConversation = signal([], ...(ngDevMode ? [{ debugName: "agenticAuthoringConversation" }] : []));
|
|
14147
15041
|
agenticAuthoringQuickReplies = signal([], ...(ngDevMode ? [{ debugName: "agenticAuthoringQuickReplies" }] : []));
|
|
@@ -14167,17 +15061,18 @@ class DynamicPageBuilderComponent {
|
|
|
14167
15061
|
agenticAuthoringEditingMessageId = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringEditingMessageId" }] : []));
|
|
14168
15062
|
selectedWidgetKey = signal(null, ...(ngDevMode ? [{ debugName: "selectedWidgetKey" }] : []));
|
|
14169
15063
|
agenticAuthoringWidgetContextKey = signal(null, ...(ngDevMode ? [{ debugName: "agenticAuthoringWidgetContextKey" }] : []));
|
|
14170
|
-
agenticAuthoringPanelLayout = signal({
|
|
14171
|
-
left: 16,
|
|
14172
|
-
top: 16,
|
|
15064
|
+
agenticAuthoringPanelLayout = signal(createPraxisAssistantViewportLayout({
|
|
14173
15065
|
width: 440,
|
|
14174
|
-
height:
|
|
14175
|
-
|
|
15066
|
+
height: 620,
|
|
15067
|
+
top: 96,
|
|
15068
|
+
margin: 24,
|
|
15069
|
+
}), ...(ngDevMode ? [{ debugName: "agenticAuthoringPanelLayout" }] : []));
|
|
14176
15070
|
previewMode = false;
|
|
14177
15071
|
agenticComponentCapabilities;
|
|
14178
15072
|
agenticComponentCapabilitiesPromise;
|
|
14179
15073
|
agenticTurnController;
|
|
14180
15074
|
sharedRuleHandoffRevision = 0;
|
|
15075
|
+
agenticAuthoringPanelLayoutTouched = false;
|
|
14181
15076
|
constructor(dialog, settingsPanel) {
|
|
14182
15077
|
this.dialog = dialog;
|
|
14183
15078
|
this.settingsPanel = settingsPanel;
|
|
@@ -14206,6 +15101,24 @@ class DynamicPageBuilderComponent {
|
|
|
14206
15101
|
this.clearSelectedWidgetIfMissing(cloned);
|
|
14207
15102
|
this.pageChange.emit(cloned);
|
|
14208
15103
|
}
|
|
15104
|
+
onRuntimeWidgetEvent(event) {
|
|
15105
|
+
if (event.output !== AGENTIC_PAGE_COMPOSITION_REQUEST_OUTPUT) {
|
|
15106
|
+
return;
|
|
15107
|
+
}
|
|
15108
|
+
const payload = this.toRecord(event.payload);
|
|
15109
|
+
const prompt = typeof payload?.['prompt'] === 'string' ? payload['prompt'].trim() : '';
|
|
15110
|
+
if (!prompt) {
|
|
15111
|
+
return;
|
|
15112
|
+
}
|
|
15113
|
+
const ownerWidgetKey = typeof event.ownerWidgetKey === 'string' ? event.ownerWidgetKey.trim() : '';
|
|
15114
|
+
if (ownerWidgetKey && this.resolveWidgetByKey(ownerWidgetKey)) {
|
|
15115
|
+
this.selectedWidgetKey.set(ownerWidgetKey);
|
|
15116
|
+
this.agenticAuthoringWidgetContextKey.set(ownerWidgetKey);
|
|
15117
|
+
}
|
|
15118
|
+
this.agenticAuthoringPrompt.set(prompt);
|
|
15119
|
+
this.openAgenticAuthoring();
|
|
15120
|
+
void this.previewAgenticAuthoring();
|
|
15121
|
+
}
|
|
14209
15122
|
onConnectionEditorPageChange(next) {
|
|
14210
15123
|
const cloned = this.clonePage(next);
|
|
14211
15124
|
this.currentPage.set(cloned);
|
|
@@ -14214,7 +15127,7 @@ class DynamicPageBuilderComponent {
|
|
|
14214
15127
|
}
|
|
14215
15128
|
onRuntimeWidgetSelectionChange(widgetKey) {
|
|
14216
15129
|
this.selectedWidgetKey.set(widgetKey);
|
|
14217
|
-
if (this.agenticAuthoringWidgetContextKey()) {
|
|
15130
|
+
if (widgetKey && this.agenticAuthoringWidgetContextKey()) {
|
|
14218
15131
|
this.agenticAuthoringWidgetContextKey.set(widgetKey);
|
|
14219
15132
|
}
|
|
14220
15133
|
}
|
|
@@ -14257,7 +15170,7 @@ class DynamicPageBuilderComponent {
|
|
|
14257
15170
|
const type = resolved.componentId;
|
|
14258
15171
|
const next = this.clonePage(this.currentPage());
|
|
14259
15172
|
const key = `${type}-${generateId()}`;
|
|
14260
|
-
const inputs = this.defaultInputsFor(type, resolved.inputs);
|
|
15173
|
+
const inputs = this.defaultInputsFor(type, resolved.inputs, key);
|
|
14261
15174
|
const widgets = [...(next.widgets || []), { key, definition: { id: type, inputs } }];
|
|
14262
15175
|
next.widgets = widgets;
|
|
14263
15176
|
if (next.canvas) {
|
|
@@ -14284,9 +15197,11 @@ class DynamicPageBuilderComponent {
|
|
|
14284
15197
|
this.runtime?.openPageSettings();
|
|
14285
15198
|
}
|
|
14286
15199
|
saveCurrentPage() {
|
|
14287
|
-
const
|
|
15200
|
+
const runtimeSnapshot = this.runtime?.getPageSnapshot();
|
|
15201
|
+
const cloned = this.clonePage(runtimeSnapshot || this.currentPage());
|
|
14288
15202
|
this.currentPage.set(cloned);
|
|
14289
15203
|
this.pageChange.emit(cloned);
|
|
15204
|
+
this.pageSaveRequested.emit(this.clonePage(cloned));
|
|
14290
15205
|
}
|
|
14291
15206
|
applyConfigFromAdapter(config) {
|
|
14292
15207
|
if (!config.page)
|
|
@@ -14338,6 +15253,17 @@ class DynamicPageBuilderComponent {
|
|
|
14338
15253
|
this.agenticAuthoringError.set('');
|
|
14339
15254
|
this.syncAgenticAuthoringSession('minimized');
|
|
14340
15255
|
}
|
|
15256
|
+
onAgenticAuthoringLayoutChange(layout) {
|
|
15257
|
+
this.agenticAuthoringPanelLayoutTouched = true;
|
|
15258
|
+
this.agenticAuthoringPanelLayout.set(layout);
|
|
15259
|
+
}
|
|
15260
|
+
agenticAuthoringReviewRailActive() {
|
|
15261
|
+
return this.showSettings()
|
|
15262
|
+
&& this.enableAgenticAuthoring
|
|
15263
|
+
&& this.agenticAuthoringOpen()
|
|
15264
|
+
&& !!this.agenticAuthoringPreviewResult()?.valid
|
|
15265
|
+
&& !this.agenticAuthoringPanelLayoutTouched;
|
|
15266
|
+
}
|
|
14341
15267
|
showAgenticAuthoringDock() {
|
|
14342
15268
|
return this.showSettings()
|
|
14343
15269
|
&& this.enableAgenticAuthoring
|
|
@@ -14366,7 +15292,7 @@ class DynamicPageBuilderComponent {
|
|
|
14366
15292
|
if (this.resolveSelectedWidgetKey()) {
|
|
14367
15293
|
return this.tx('agentic.header.title.widget', 'Praxis widget copilot');
|
|
14368
15294
|
}
|
|
14369
|
-
return this.tx('agentic.header.title.page', 'Praxis page copilot');
|
|
15295
|
+
return this.tx('agentic.header.title.page', 'Praxis page decision copilot');
|
|
14370
15296
|
}
|
|
14371
15297
|
agenticAuthoringHeaderSubtitle() {
|
|
14372
15298
|
const selectedWidgetLabel = this.resolveSelectedWidgetLabel();
|
|
@@ -14374,6 +15300,9 @@ class DynamicPageBuilderComponent {
|
|
|
14374
15300
|
return this.tx('agentic.header.subtitle.governed', 'Continue the governed semantic-decision flow.');
|
|
14375
15301
|
}
|
|
14376
15302
|
if (this.agenticAuthoringPreviewResult()?.valid) {
|
|
15303
|
+
if (!this.agenticAuthoringCanApply()) {
|
|
15304
|
+
return this.tx('agentic.header.subtitle.reviewBlocked', 'Preview ready for governed review.');
|
|
15305
|
+
}
|
|
14377
15306
|
return this.tx('agentic.header.subtitle.review', 'Preview ready for review and persistence.');
|
|
14378
15307
|
}
|
|
14379
15308
|
if (selectedWidgetLabel) {
|
|
@@ -14385,7 +15314,7 @@ class DynamicPageBuilderComponent {
|
|
|
14385
15314
|
return this.tx('agentic.header.subtitle.route', 'Authoring page route {route}.')
|
|
14386
15315
|
.replace('{route}', routePath);
|
|
14387
15316
|
}
|
|
14388
|
-
return this.tx('agentic.header.subtitle.page', '
|
|
15317
|
+
return this.tx('agentic.header.subtitle.page', 'Turn intent into layout, widgets, and governed materializations.');
|
|
14389
15318
|
}
|
|
14390
15319
|
agenticAuthoringHeaderModeLabel() {
|
|
14391
15320
|
if (this.agenticAuthoringSharedRuleHandoffState()) {
|
|
@@ -14403,7 +15332,7 @@ class DynamicPageBuilderComponent {
|
|
|
14403
15332
|
close: this.tx('agentic.minimize', 'Minimize'),
|
|
14404
15333
|
prompt: this.tx('agentic.promptLabel', 'Message'),
|
|
14405
15334
|
promptPlaceholder: this.tx('agentic.promptPlaceholder', 'Describe the page, dashboard, form or change you need.'),
|
|
14406
|
-
emptyConversation: this.
|
|
15335
|
+
emptyConversation: this.agenticAuthoringEmptyConversationMessage(),
|
|
14407
15336
|
submit: this.tx('agentic.preview', 'Generate preview'),
|
|
14408
15337
|
apply: this.tx('agentic.persist', 'Save'),
|
|
14409
15338
|
conversationAria: this.tx('agentic.conversationAria', 'AI conversation'),
|
|
@@ -14422,7 +15351,7 @@ class DynamicPageBuilderComponent {
|
|
|
14422
15351
|
modeDiagnostic: this.tx('agentic.mode.diagnostic', 'Diagnostic'),
|
|
14423
15352
|
modeReview: this.tx('agentic.mode.review', 'Review'),
|
|
14424
15353
|
modeInlineHelp: this.tx('agentic.mode.inlineHelp', 'Help'),
|
|
14425
|
-
stateIdle: this.tx('agentic.state.idle', '
|
|
15354
|
+
stateIdle: this.tx('agentic.state.idle', 'Ready'),
|
|
14426
15355
|
stateListening: this.tx('agentic.state.listening', 'Ready'),
|
|
14427
15356
|
stateProcessing: this.tx('agentic.state.processing', 'Processing'),
|
|
14428
15357
|
stateClarification: this.tx('agentic.state.clarification', 'Waiting for input'),
|
|
@@ -14432,6 +15361,39 @@ class DynamicPageBuilderComponent {
|
|
|
14432
15361
|
stateError: this.tx('agentic.state.error', 'Error'),
|
|
14433
15362
|
};
|
|
14434
15363
|
}
|
|
15364
|
+
agenticAuthoringEmptyConversationMessage() {
|
|
15365
|
+
const authoredOpening = this.resolveAgenticAuthoredOpeningMessage();
|
|
15366
|
+
if (authoredOpening) {
|
|
15367
|
+
return authoredOpening;
|
|
15368
|
+
}
|
|
15369
|
+
if (this.isAgenticAuthoringPageBlank()) {
|
|
15370
|
+
return this.tx('agentic.emptyConversation.blankGeneric', 'This host page is still blank. Tell me what decision or activity this app needs to support. I can suggest a dashboard, table, form, or review flow, then turn it into a governed preview for you to review before anything changes.');
|
|
15371
|
+
}
|
|
15372
|
+
return this.tx('agentic.emptyConversation.existingPage', 'Tell me what you want to improve here. I can read the current layout, widgets, route, and governed context, then prepare a preview for you to review before anything changes.');
|
|
15373
|
+
}
|
|
15374
|
+
resolveAgenticAuthoredOpeningMessage() {
|
|
15375
|
+
const hints = this.toRecord(this.agenticAuthoringContextHints);
|
|
15376
|
+
if (!hints)
|
|
15377
|
+
return null;
|
|
15378
|
+
const candidateRecords = [
|
|
15379
|
+
hints,
|
|
15380
|
+
this.toRecord(hints['domainOpening']),
|
|
15381
|
+
this.toRecord(hints['ragOpening']),
|
|
15382
|
+
this.toRecord(hints['opening']),
|
|
15383
|
+
this.toRecord(hints['domainSummary']),
|
|
15384
|
+
];
|
|
15385
|
+
for (const record of candidateRecords) {
|
|
15386
|
+
const message = this.trimmedString(record?.['openingMessage'])
|
|
15387
|
+
|| this.trimmedString(record?.['message']);
|
|
15388
|
+
if (message)
|
|
15389
|
+
return message;
|
|
15390
|
+
}
|
|
15391
|
+
return null;
|
|
15392
|
+
}
|
|
15393
|
+
isAgenticAuthoringPageBlank() {
|
|
15394
|
+
const widgets = this.currentPage().widgets;
|
|
15395
|
+
return !Array.isArray(widgets) || widgets.length === 0;
|
|
15396
|
+
}
|
|
14435
15397
|
agenticAuthoringSubmitAction() {
|
|
14436
15398
|
const label = this.tx('agentic.preview', 'Generate preview');
|
|
14437
15399
|
return {
|
|
@@ -14522,6 +15484,8 @@ class DynamicPageBuilderComponent {
|
|
|
14522
15484
|
this.agenticAuthoringStatus.set('');
|
|
14523
15485
|
this.agenticAuthoringError.set('');
|
|
14524
15486
|
this.agenticAuthoringPreviewResult.set(null);
|
|
15487
|
+
this.agenticAuthoringSemanticDecision.set(null);
|
|
15488
|
+
this.agenticAuthoringCanApply.set(false);
|
|
14525
15489
|
this.agenticAuthoringConversation.set([]);
|
|
14526
15490
|
this.agenticAuthoringQuickReplies.set([]);
|
|
14527
15491
|
this.agenticAuthoringAttachments.set([]);
|
|
@@ -14767,6 +15731,7 @@ class DynamicPageBuilderComponent {
|
|
|
14767
15731
|
});
|
|
14768
15732
|
}
|
|
14769
15733
|
}
|
|
15734
|
+
items.push(...this.agenticAuthoringSemanticDecisionContextItems());
|
|
14770
15735
|
const handoff = this.agenticAuthoringSharedRuleHandoffState();
|
|
14771
15736
|
if (handoff) {
|
|
14772
15737
|
items.push({
|
|
@@ -14858,6 +15823,138 @@ class DynamicPageBuilderComponent {
|
|
|
14858
15823
|
}
|
|
14859
15824
|
return items;
|
|
14860
15825
|
}
|
|
15826
|
+
agenticAuthoringSemanticDecisionContextItems() {
|
|
15827
|
+
const semanticDecision = this.toRecord(this.agenticAuthoringSemanticDecision());
|
|
15828
|
+
if (!semanticDecision) {
|
|
15829
|
+
return [];
|
|
15830
|
+
}
|
|
15831
|
+
const items = [];
|
|
15832
|
+
const selectedResource = this.toRecord(semanticDecision['selectedResource']);
|
|
15833
|
+
const resourcePath = this.trimmedString(selectedResource?.['resourcePath']);
|
|
15834
|
+
const operationKind = this.trimmedString(semanticDecision['operationKind']);
|
|
15835
|
+
const artifactKind = this.trimmedString(semanticDecision['artifactKind']);
|
|
15836
|
+
const changeKind = this.trimmedString(semanticDecision['changeKind']);
|
|
15837
|
+
if (this.shouldHideSemanticDecisionContextItems(operationKind, artifactKind, changeKind, resourcePath)) {
|
|
15838
|
+
return items;
|
|
15839
|
+
}
|
|
15840
|
+
if (resourcePath) {
|
|
15841
|
+
items.push({
|
|
15842
|
+
id: 'semantic-decision-resource',
|
|
15843
|
+
kind: 'custom',
|
|
15844
|
+
label: this.tx('agentic.context.semanticDecisionResource', 'Fonte'),
|
|
15845
|
+
value: this.humanizeAgenticResourcePath(resourcePath),
|
|
15846
|
+
icon: 'dataset',
|
|
15847
|
+
});
|
|
15848
|
+
}
|
|
15849
|
+
const decisionSummary = [operationKind, artifactKind, changeKind]
|
|
15850
|
+
.filter((value) => !!value)
|
|
15851
|
+
.join(' · ');
|
|
15852
|
+
if (decisionSummary) {
|
|
15853
|
+
items.push({
|
|
15854
|
+
id: 'semantic-decision-kind',
|
|
15855
|
+
kind: 'custom',
|
|
15856
|
+
label: this.tx('agentic.context.semanticDecisionKind', 'Objetivo'),
|
|
15857
|
+
value: this.humanizeAgenticDecisionSummary(operationKind ?? '', artifactKind ?? '', changeKind ?? ''),
|
|
15858
|
+
icon: 'account_tree',
|
|
15859
|
+
});
|
|
15860
|
+
}
|
|
15861
|
+
const retrievedEvidence = this.toRecord(semanticDecision['retrievedEvidence']);
|
|
15862
|
+
const retrievalEvidence = this.toRecord(semanticDecision['retrievalEvidence']);
|
|
15863
|
+
const retrievalSource = this.trimmedString(retrievedEvidence?.['retrievalSource'])
|
|
15864
|
+
|| this.trimmedString(retrievalEvidence?.['retrievalSource']);
|
|
15865
|
+
const reviewReason = this.trimmedString(semanticDecision['reviewReason']);
|
|
15866
|
+
const confidence = typeof semanticDecision['confidence'] === 'number'
|
|
15867
|
+
? semanticDecision['confidence']
|
|
15868
|
+
: null;
|
|
15869
|
+
const evidenceSummary = this.humanizeAgenticDecisionEvidence(retrievalSource ?? '', reviewReason ?? '', confidence);
|
|
15870
|
+
if (evidenceSummary) {
|
|
15871
|
+
items.push({
|
|
15872
|
+
id: 'semantic-decision-evidence',
|
|
15873
|
+
kind: 'custom',
|
|
15874
|
+
label: this.tx('agentic.context.semanticDecisionEvidence', 'Revisão'),
|
|
15875
|
+
value: evidenceSummary,
|
|
15876
|
+
icon: reviewReason ? 'policy' : 'verified',
|
|
15877
|
+
});
|
|
15878
|
+
}
|
|
15879
|
+
return items;
|
|
15880
|
+
}
|
|
15881
|
+
shouldHideSemanticDecisionContextItems(operationKind, artifactKind, changeKind, resourcePath) {
|
|
15882
|
+
const operation = (operationKind ?? '').trim().toLowerCase();
|
|
15883
|
+
const artifact = (artifactKind ?? '').trim().toLowerCase();
|
|
15884
|
+
const change = (changeKind ?? '').trim().toLowerCase();
|
|
15885
|
+
return artifact === 'unknown'
|
|
15886
|
+
|| artifact === 'api_catalog'
|
|
15887
|
+
|| operation === 'explore'
|
|
15888
|
+
|| operation === 'explain'
|
|
15889
|
+
|| change === 'answer_api_catalog_question'
|
|
15890
|
+
|| change === 'answer_catalog_question'
|
|
15891
|
+
|| change === 'api_catalog_followup';
|
|
15892
|
+
}
|
|
15893
|
+
humanizeAgenticResourcePath(resourcePath) {
|
|
15894
|
+
const lastSegment = resourcePath.split('?')[0].split('/').filter(Boolean).pop() || resourcePath;
|
|
15895
|
+
return lastSegment
|
|
15896
|
+
.replace(/^vw[-_]/i, '')
|
|
15897
|
+
.replace(/[-_]+/g, ' ')
|
|
15898
|
+
.replace(/\b\w/g, (char) => char.toUpperCase());
|
|
15899
|
+
}
|
|
15900
|
+
humanizeAgenticDecisionSummary(operationKind, artifactKind, changeKind) {
|
|
15901
|
+
const operation = this.humanizeAgenticOperationKind(operationKind);
|
|
15902
|
+
const artifact = this.humanizeAgenticArtifactKind(artifactKind);
|
|
15903
|
+
const change = this.humanizeAgenticChangeKind(changeKind);
|
|
15904
|
+
return [operation, artifact, change].filter((value) => !!value).join(' · ');
|
|
15905
|
+
}
|
|
15906
|
+
humanizeAgenticOperationKind(value) {
|
|
15907
|
+
const normalized = value.trim().toLowerCase();
|
|
15908
|
+
if (normalized === 'create')
|
|
15909
|
+
return this.tx('agentic.context.operationCreate', 'Criar');
|
|
15910
|
+
if (normalized === 'update')
|
|
15911
|
+
return this.tx('agentic.context.operationUpdate', 'Ajustar');
|
|
15912
|
+
if (normalized === 'read')
|
|
15913
|
+
return this.tx('agentic.context.operationRead', 'Consultar');
|
|
15914
|
+
return this.humanizeAgenticToken(value);
|
|
15915
|
+
}
|
|
15916
|
+
humanizeAgenticArtifactKind(value) {
|
|
15917
|
+
const normalized = value.trim().toLowerCase();
|
|
15918
|
+
if (normalized === 'dashboard')
|
|
15919
|
+
return this.tx('agentic.context.artifactDashboard', 'dashboard');
|
|
15920
|
+
if (normalized === 'table')
|
|
15921
|
+
return this.tx('agentic.context.artifactTable', 'tabela');
|
|
15922
|
+
if (normalized === 'form')
|
|
15923
|
+
return this.tx('agentic.context.artifactForm', 'formulário');
|
|
15924
|
+
if (normalized === 'page')
|
|
15925
|
+
return this.tx('agentic.context.artifactPage', 'tela');
|
|
15926
|
+
return this.humanizeAgenticToken(value).toLowerCase();
|
|
15927
|
+
}
|
|
15928
|
+
humanizeAgenticChangeKind(value) {
|
|
15929
|
+
const normalized = value.trim().toLowerCase();
|
|
15930
|
+
if (normalized.includes('analytics'))
|
|
15931
|
+
return this.tx('agentic.context.changeAnalytics', 'com análise');
|
|
15932
|
+
if (normalized.includes('dashboard'))
|
|
15933
|
+
return this.tx('agentic.context.changeDashboard', 'com visão gerencial');
|
|
15934
|
+
if (normalized.includes('table'))
|
|
15935
|
+
return this.tx('agentic.context.changeTable', 'com detalhes');
|
|
15936
|
+
if (normalized.includes('form'))
|
|
15937
|
+
return this.tx('agentic.context.changeForm', 'com edição');
|
|
15938
|
+
return this.humanizeAgenticToken(value).toLowerCase();
|
|
15939
|
+
}
|
|
15940
|
+
humanizeAgenticDecisionEvidence(retrievalSource, reviewReason, confidence) {
|
|
15941
|
+
if (reviewReason) {
|
|
15942
|
+
return this.tx('agentic.context.evidenceReviewRequired', 'Precisa revisar campos');
|
|
15943
|
+
}
|
|
15944
|
+
if (confidence !== null && confidence < 0.7) {
|
|
15945
|
+
return this.tx('agentic.context.evidenceLowConfidence', 'Precisa confirmar fonte');
|
|
15946
|
+
}
|
|
15947
|
+
if (retrievalSource) {
|
|
15948
|
+
return this.tx('agentic.context.evidenceGrounded', 'Fonte confirmada');
|
|
15949
|
+
}
|
|
15950
|
+
return '';
|
|
15951
|
+
}
|
|
15952
|
+
humanizeAgenticToken(value) {
|
|
15953
|
+
return value
|
|
15954
|
+
.trim()
|
|
15955
|
+
.replace(/[-_]+/g, ' ')
|
|
15956
|
+
.replace(/\b\w/g, (char) => char.toUpperCase());
|
|
15957
|
+
}
|
|
14861
15958
|
async previewAgenticAuthoring() {
|
|
14862
15959
|
const prompt = this.agenticAuthoringPrompt().trim();
|
|
14863
15960
|
if (!prompt || this.agenticAuthoringBusy())
|
|
@@ -14865,6 +15962,7 @@ class DynamicPageBuilderComponent {
|
|
|
14865
15962
|
this.agenticAuthoringBusy.set(true);
|
|
14866
15963
|
this.agenticAuthoringError.set('');
|
|
14867
15964
|
this.agenticAuthoringPreviewResult.set(null);
|
|
15965
|
+
this.agenticAuthoringCanApply.set(false);
|
|
14868
15966
|
this.agenticAuthoringSharedRuleHandoffState.set(null);
|
|
14869
15967
|
this.clearSharedRuleCockpitState();
|
|
14870
15968
|
this.clearProjectKnowledgeCockpitState();
|
|
@@ -14876,6 +15974,7 @@ class DynamicPageBuilderComponent {
|
|
|
14876
15974
|
? controller.submitEditedMessage(editingMessageId, prompt)
|
|
14877
15975
|
: controller.submitPrompt(prompt));
|
|
14878
15976
|
this.agenticAuthoringEditingMessageId.set(null);
|
|
15977
|
+
this.agenticAuthoringPrompt.set('');
|
|
14879
15978
|
}
|
|
14880
15979
|
catch (error) {
|
|
14881
15980
|
this.agenticAuthoringStatus.set('');
|
|
@@ -14912,6 +16011,7 @@ class DynamicPageBuilderComponent {
|
|
|
14912
16011
|
this.agenticAuthoringBusy.set(true);
|
|
14913
16012
|
this.agenticAuthoringError.set('');
|
|
14914
16013
|
this.agenticAuthoringPreviewResult.set(null);
|
|
16014
|
+
this.agenticAuthoringCanApply.set(false);
|
|
14915
16015
|
this.agenticAuthoringSharedRuleHandoffState.set(null);
|
|
14916
16016
|
this.clearSharedRuleCockpitState();
|
|
14917
16017
|
this.clearProjectKnowledgeCockpitState();
|
|
@@ -14929,6 +16029,7 @@ class DynamicPageBuilderComponent {
|
|
|
14929
16029
|
displayPrompt: visiblePrompt,
|
|
14930
16030
|
contextHints,
|
|
14931
16031
|
}));
|
|
16032
|
+
this.agenticAuthoringPrompt.set('');
|
|
14932
16033
|
}
|
|
14933
16034
|
catch (error) {
|
|
14934
16035
|
this.agenticAuthoringStatus.set('');
|
|
@@ -14975,9 +16076,10 @@ class DynamicPageBuilderComponent {
|
|
|
14975
16076
|
if (this.isGenericDataSourceQuickReplyPrompt(prompt) && this.isConfirmationQuickReply(reply)) {
|
|
14976
16077
|
return this.agenticQuickReplyGovernedConfirmationPrompt(contextHints, visiblePrompt);
|
|
14977
16078
|
}
|
|
14978
|
-
|
|
14979
|
-
|
|
14980
|
-
|
|
16079
|
+
if (this.isHumanSafeResourceQuickReplyPrompt(prompt, contextHints)) {
|
|
16080
|
+
return prompt;
|
|
16081
|
+
}
|
|
16082
|
+
return this.agenticQuickReplyClarificationConfirmationPrompt(pendingClarification, visiblePrompt);
|
|
14981
16083
|
}
|
|
14982
16084
|
agenticQuickReplyClarificationConfirmationPrompt(pendingClarification, confirmationText) {
|
|
14983
16085
|
const sourcePrompt = (pendingClarification?.sourcePrompt || '').trim();
|
|
@@ -15031,9 +16133,25 @@ class DynamicPageBuilderComponent {
|
|
|
15031
16133
|
return visiblePrompt;
|
|
15032
16134
|
}
|
|
15033
16135
|
isResourceQuickReply(reply, contextHints) {
|
|
16136
|
+
if (this.isContextualPreviewActionQuickReply(reply, contextHints)) {
|
|
16137
|
+
return false;
|
|
16138
|
+
}
|
|
15034
16139
|
return this.hasResourceContextHint(contextHints)
|
|
15035
16140
|
&& !['cancel', 'revise'].includes((reply.kind || '').trim().toLowerCase());
|
|
15036
16141
|
}
|
|
16142
|
+
isContextualPreviewActionQuickReply(reply, contextHints) {
|
|
16143
|
+
const source = typeof contextHints?.['source'] === 'string'
|
|
16144
|
+
? contextHints['source'].trim()
|
|
16145
|
+
: '';
|
|
16146
|
+
const kind = typeof contextHints?.['kind'] === 'string'
|
|
16147
|
+
? contextHints['kind'].trim()
|
|
16148
|
+
: '';
|
|
16149
|
+
const id = (reply.id || '').trim();
|
|
16150
|
+
return source === 'component-capability-catalog'
|
|
16151
|
+
|| kind === 'contextual-preview-action'
|
|
16152
|
+
|| id.startsWith('chart-')
|
|
16153
|
+
|| id.startsWith('table-export-');
|
|
16154
|
+
}
|
|
15037
16155
|
isGovernedConfirmationQuickReply(reply, contextHints) {
|
|
15038
16156
|
return this.isConfirmationQuickReply(reply)
|
|
15039
16157
|
&& this.hasResourceContextHint(contextHints);
|
|
@@ -15101,6 +16219,7 @@ class DynamicPageBuilderComponent {
|
|
|
15101
16219
|
this.agenticAuthoringStatus.set(this.tx('agentic.status.resolvingIntent', 'Resolving intent...'));
|
|
15102
16220
|
this.agenticAuthoringError.set('');
|
|
15103
16221
|
this.agenticAuthoringPreviewResult.set(null);
|
|
16222
|
+
this.agenticAuthoringCanApply.set(false);
|
|
15104
16223
|
this.clearProjectKnowledgeCockpitState();
|
|
15105
16224
|
try {
|
|
15106
16225
|
await this.consumeAgenticTurn(this.ensureAgenticTurnController().resendMessage(message.id));
|
|
@@ -15141,6 +16260,8 @@ class DynamicPageBuilderComponent {
|
|
|
15141
16260
|
this.agenticAuthoringEditingMessageId.set(null);
|
|
15142
16261
|
this.agenticAuthoringPrompt.set('');
|
|
15143
16262
|
this.agenticAuthoringPreviewResult.set(null);
|
|
16263
|
+
this.agenticAuthoringSemanticDecision.set(null);
|
|
16264
|
+
this.agenticAuthoringCanApply.set(false);
|
|
15144
16265
|
this.agenticAuthoringSharedRuleHandoffState.set(null);
|
|
15145
16266
|
this.clearSharedRuleCockpitState();
|
|
15146
16267
|
this.clearProjectKnowledgeCockpitState();
|
|
@@ -15148,7 +16269,7 @@ class DynamicPageBuilderComponent {
|
|
|
15148
16269
|
}
|
|
15149
16270
|
async persistAgenticAuthoring() {
|
|
15150
16271
|
const preview = this.agenticAuthoringPreviewResult();
|
|
15151
|
-
if (!preview || this.agenticAuthoringBusy())
|
|
16272
|
+
if (!preview || !this.agenticAuthoringCanApply() || this.agenticAuthoringBusy())
|
|
15152
16273
|
return;
|
|
15153
16274
|
const componentId = this.resolveAgenticComponentId();
|
|
15154
16275
|
if (!componentId) {
|
|
@@ -15168,10 +16289,17 @@ class DynamicPageBuilderComponent {
|
|
|
15168
16289
|
tags: {
|
|
15169
16290
|
source: 'page-builder-agentic-authoring',
|
|
15170
16291
|
},
|
|
16292
|
+
semanticDecision: this.agenticAuthoringSemanticDecision(),
|
|
15171
16293
|
}));
|
|
15172
16294
|
this.agenticAuthoringLastEtag.set(result.etag ?? null);
|
|
15173
16295
|
this.agenticAuthoringApplied.emit(result);
|
|
16296
|
+
this.agenticAuthoringPreviewResult.set(null);
|
|
16297
|
+
this.agenticAuthoringSemanticDecision.set(null);
|
|
16298
|
+
this.agenticAuthoringCanApply.set(false);
|
|
16299
|
+
this.agenticAuthoringQuickReplies.set([]);
|
|
16300
|
+
this.agenticAuthoringPrompt.set('');
|
|
15174
16301
|
this.agenticAuthoringStatus.set(this.tx('agentic.status.saved', 'Page saved.'));
|
|
16302
|
+
this.syncAgenticAuthoringSession();
|
|
15175
16303
|
}
|
|
15176
16304
|
catch (error) {
|
|
15177
16305
|
this.agenticAuthoringStatus.set('');
|
|
@@ -15733,6 +16861,7 @@ class DynamicPageBuilderComponent {
|
|
|
15733
16861
|
this.agenticAuthoringStatus.set(this.tx('agentic.status.sharedRuleTargetSelected', 'Shared-rule target selected. Continue by creating the governed definition.'));
|
|
15734
16862
|
this.agenticAuthoringError.set('');
|
|
15735
16863
|
this.agenticAuthoringPreviewResult.set(null);
|
|
16864
|
+
this.agenticAuthoringCanApply.set(false);
|
|
15736
16865
|
this.agenticAuthoringSharedRuleHandoffState.set(next);
|
|
15737
16866
|
this.agenticAuthoringSharedRuleHandoff.emit(next);
|
|
15738
16867
|
this.appendAgenticMessage('user', visiblePrompt);
|
|
@@ -15999,12 +17128,15 @@ class DynamicPageBuilderComponent {
|
|
|
15999
17128
|
const handoff = this.resolveAgenticSharedRuleHandoff(state);
|
|
16000
17129
|
const previousHandoff = this.agenticAuthoringSharedRuleHandoffState();
|
|
16001
17130
|
this.agenticAuthoringConversation.set(state.messages);
|
|
16002
|
-
this.agenticAuthoringQuickReplies.set(
|
|
17131
|
+
this.agenticAuthoringQuickReplies.set(state.quickReplies);
|
|
16003
17132
|
this.agenticAuthoringStatus.set(handoff && !preview?.valid
|
|
16004
17133
|
? this.tx('agentic.status.sharedRuleHandoff', 'Continue this request in the shared-rules flow.')
|
|
16005
17134
|
: state.statusText);
|
|
16006
17135
|
this.agenticAuthoringError.set(state.errorText);
|
|
16007
17136
|
this.agenticAuthoringPreviewResult.set(preview);
|
|
17137
|
+
this.agenticAuthoringSemanticDecision.set(this.resolveAgenticSemanticDecision(state.diagnostics));
|
|
17138
|
+
this.agenticAuthoringCanApply.set(!!preview?.valid && !!state.canApply);
|
|
17139
|
+
this.moveAgenticAuthoringPanelToReviewSidecar(preview);
|
|
16008
17140
|
this.agenticAuthoringAttachments.set(state.attachments);
|
|
16009
17141
|
if (!this.sameSharedRuleHandoffIdentity(previousHandoff, handoff)) {
|
|
16010
17142
|
this.clearSharedRuleCockpitState();
|
|
@@ -16053,6 +17185,17 @@ class DynamicPageBuilderComponent {
|
|
|
16053
17185
|
this.agenticAuthoringSharedRuleHandoff.emit(resolved);
|
|
16054
17186
|
}
|
|
16055
17187
|
}
|
|
17188
|
+
moveAgenticAuthoringPanelToReviewSidecar(preview) {
|
|
17189
|
+
if (!preview?.valid || this.agenticAuthoringPanelLayoutTouched) {
|
|
17190
|
+
return;
|
|
17191
|
+
}
|
|
17192
|
+
this.agenticAuthoringPanelLayout.set(createPraxisAssistantViewportLayout({
|
|
17193
|
+
width: 440,
|
|
17194
|
+
height: 620,
|
|
17195
|
+
top: 96,
|
|
17196
|
+
margin: 24,
|
|
17197
|
+
}));
|
|
17198
|
+
}
|
|
16056
17199
|
resolveAgenticSharedRuleHandoff(state) {
|
|
16057
17200
|
const diagnostics = this.toRecord(state.diagnostics);
|
|
16058
17201
|
const intentResolution = this.toRecord(diagnostics?.['intentResolution']);
|
|
@@ -16190,7 +17333,14 @@ class DynamicPageBuilderComponent {
|
|
|
16190
17333
|
return Object.keys(merged).length ? merged : undefined;
|
|
16191
17334
|
}
|
|
16192
17335
|
consumeAgenticTurn(states$) {
|
|
16193
|
-
return
|
|
17336
|
+
return firstValueFrom(states$.pipe(concatMap((state) => from(this.applyAgenticTurnState(state)).pipe(map(() => state))), filter((state) => this.isAgenticTurnTerminalState(state)), take(1)));
|
|
17337
|
+
}
|
|
17338
|
+
isAgenticTurnTerminalState(state) {
|
|
17339
|
+
return state.state === 'review'
|
|
17340
|
+
|| state.state === 'clarification'
|
|
17341
|
+
|| state.state === 'error'
|
|
17342
|
+
|| state.state === 'success'
|
|
17343
|
+
|| state.state === 'listening';
|
|
16194
17344
|
}
|
|
16195
17345
|
agenticAuthoringDiagnosticsTop() {
|
|
16196
17346
|
return Math.max(16, this.agenticAuthoringPanelLayout().top);
|
|
@@ -16209,6 +17359,11 @@ class DynamicPageBuilderComponent {
|
|
|
16209
17359
|
const intentResolution = this.toRecord(diagnostics?.['intentResolution']);
|
|
16210
17360
|
return this.toRecord(intentResolution?.['llmDiagnostics']);
|
|
16211
17361
|
}
|
|
17362
|
+
resolveAgenticSemanticDecision(diagnostics) {
|
|
17363
|
+
const intentResolution = this.toRecord(diagnostics?.['intentResolution']);
|
|
17364
|
+
const semanticDecision = this.toRecord(intentResolution?.['semanticDecision']);
|
|
17365
|
+
return semanticDecision ? semanticDecision : null;
|
|
17366
|
+
}
|
|
16212
17367
|
cloneAgenticContextHints(contextHints) {
|
|
16213
17368
|
if (!contextHints || typeof contextHints !== 'object' || Array.isArray(contextHints)) {
|
|
16214
17369
|
return undefined;
|
|
@@ -16254,8 +17409,10 @@ class DynamicPageBuilderComponent {
|
|
|
16254
17409
|
}
|
|
16255
17410
|
resolvePreviewCompiledFormPatch(preview) {
|
|
16256
17411
|
if (preview.uiCompositionPlan || preview.compiledFormPatch?.patch?.page) {
|
|
17412
|
+
const planDiagnostics = this.toRecord(this.toRecord(preview.uiCompositionPlan)?.['diagnostics']);
|
|
16257
17413
|
return {
|
|
16258
17414
|
...preview.compiledFormPatch,
|
|
17415
|
+
diagnostics: planDiagnostics ?? preview.compiledFormPatch?.['diagnostics'],
|
|
16259
17416
|
patch: {
|
|
16260
17417
|
...(preview.compiledFormPatch?.patch ?? {}),
|
|
16261
17418
|
page: this.clonePage(this.currentPage()),
|
|
@@ -16283,7 +17440,7 @@ class DynamicPageBuilderComponent {
|
|
|
16283
17440
|
return this.clonePage(input);
|
|
16284
17441
|
}
|
|
16285
17442
|
clonePage(page) {
|
|
16286
|
-
return JSON.parse(JSON.stringify(page));
|
|
17443
|
+
return normalizePageBuilderRuntimePage(JSON.parse(JSON.stringify(page)));
|
|
16287
17444
|
}
|
|
16288
17445
|
clearSelectedWidgetIfMissing(page) {
|
|
16289
17446
|
const selected = this.selectedWidgetKey();
|
|
@@ -16295,7 +17452,7 @@ class DynamicPageBuilderComponent {
|
|
|
16295
17452
|
this.agenticAuthoringWidgetContextKey.set(null);
|
|
16296
17453
|
}
|
|
16297
17454
|
}
|
|
16298
|
-
defaultInputsFor(type, presetInputs) {
|
|
17455
|
+
defaultInputsFor(type, presetInputs, widgetKey) {
|
|
16299
17456
|
const metadata = this.componentMetadata.get(type);
|
|
16300
17457
|
const inputs = {};
|
|
16301
17458
|
for (const input of metadata?.inputs ?? []) {
|
|
@@ -16303,6 +17460,12 @@ class DynamicPageBuilderComponent {
|
|
|
16303
17460
|
inputs[input.name] = this.cloneValue(input.default);
|
|
16304
17461
|
}
|
|
16305
17462
|
}
|
|
17463
|
+
if (metadata?.authoringManifestRef?.componentId
|
|
17464
|
+
&& metadata.inputs?.some((input) => input.name === 'enableCustomization')
|
|
17465
|
+
&& presetInputs?.['enableCustomization'] === undefined) {
|
|
17466
|
+
inputs['enableCustomization'] = true;
|
|
17467
|
+
}
|
|
17468
|
+
this.applyWidgetIdentityDefaults(metadata?.inputs, inputs, presetInputs, widgetKey);
|
|
16306
17469
|
if (!presetInputs) {
|
|
16307
17470
|
return inputs;
|
|
16308
17471
|
}
|
|
@@ -16311,6 +17474,18 @@ class DynamicPageBuilderComponent {
|
|
|
16311
17474
|
...this.cloneValue(presetInputs),
|
|
16312
17475
|
};
|
|
16313
17476
|
}
|
|
17477
|
+
applyWidgetIdentityDefaults(metadataInputs, inputs, presetInputs, widgetKey) {
|
|
17478
|
+
if (!metadataInputs?.length || !widgetKey)
|
|
17479
|
+
return;
|
|
17480
|
+
const inputNames = new Set(metadataInputs.map((input) => input.name));
|
|
17481
|
+
for (const identityInput of ['componentInstanceId', 'tabsId', 'formId']) {
|
|
17482
|
+
if (inputNames.has(identityInput)
|
|
17483
|
+
&& inputs[identityInput] === undefined
|
|
17484
|
+
&& presetInputs?.[identityInput] === undefined) {
|
|
17485
|
+
inputs[identityInput] = widgetKey;
|
|
17486
|
+
}
|
|
17487
|
+
}
|
|
17488
|
+
}
|
|
16314
17489
|
resolveAgenticComponentId() {
|
|
16315
17490
|
const explicit = this.agenticAuthoringComponentId?.trim();
|
|
16316
17491
|
if (explicit)
|
|
@@ -16321,9 +17496,9 @@ class DynamicPageBuilderComponent {
|
|
|
16321
17496
|
return null;
|
|
16322
17497
|
}
|
|
16323
17498
|
resolveSelectedWidgetKey() {
|
|
16324
|
-
const
|
|
16325
|
-
if (
|
|
16326
|
-
return
|
|
17499
|
+
const pinnedSelection = this.agenticAuthoringWidgetContextKey();
|
|
17500
|
+
if (pinnedSelection && this.resolveWidgetByKey(pinnedSelection)) {
|
|
17501
|
+
return pinnedSelection;
|
|
16327
17502
|
}
|
|
16328
17503
|
return null;
|
|
16329
17504
|
}
|
|
@@ -16435,17 +17610,20 @@ class DynamicPageBuilderComponent {
|
|
|
16435
17610
|
return resolvePraxisPageBuilderText(this.i18n, key, fallback);
|
|
16436
17611
|
}
|
|
16437
17612
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DynamicPageBuilderComponent, deps: [{ token: i1.MatDialog }, { token: SETTINGS_PANEL_BRIDGE, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
16438
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: DynamicPageBuilderComponent, isStandalone: true, selector: "praxis-dynamic-page-builder", inputs: { page: "page", context: "context", strictValidation: "strictValidation", autoPersist: "autoPersist", enableCustomization: "enableCustomization", showSettingsButton: "showSettingsButton", pageIdentity: "pageIdentity", componentInstanceId: "componentInstanceId", pageEditorComponent: "pageEditorComponent", enableAgenticAuthoring: "enableAgenticAuthoring", agenticAuthoringProvider: "agenticAuthoringProvider", agenticAuthoringModel: "agenticAuthoringModel", agenticAuthoringApiKey: "agenticAuthoringApiKey", agenticAuthoringComponentId: "agenticAuthoringComponentId", agenticAuthoringScope: "agenticAuthoringScope", agenticAuthoringEtag: "agenticAuthoringEtag", agenticAuthoringIncludeLlmDiagnostics: "agenticAuthoringIncludeLlmDiagnostics", agenticAuthoringEnableStreaming: "agenticAuthoringEnableStreaming", agenticAuthoringContextHints: "agenticAuthoringContextHints", showPageLifecycleActions: "showPageLifecycleActions", canDeleteSavedPage: "canDeleteSavedPage", pageLifecycleBusy: "pageLifecycleBusy", pageLifecycleResetRevision: "pageLifecycleResetRevision" }, outputs: { pageChange: "pageChange", agenticAuthoringApplied: "agenticAuthoringApplied", agenticAuthoringSharedRuleHandoff: "agenticAuthoringSharedRuleHandoff", pageRestart: "pageRestart", savedPageDeleteRequested: "savedPageDeleteRequested" }, providers: [
|
|
17613
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: DynamicPageBuilderComponent, isStandalone: true, selector: "praxis-dynamic-page-builder", inputs: { page: "page", context: "context", strictValidation: "strictValidation", autoPersist: "autoPersist", enableCustomization: "enableCustomization", showSettingsButton: "showSettingsButton", pageIdentity: "pageIdentity", componentInstanceId: "componentInstanceId", pageEditorComponent: "pageEditorComponent", enableAgenticAuthoring: "enableAgenticAuthoring", agenticAuthoringProvider: "agenticAuthoringProvider", agenticAuthoringModel: "agenticAuthoringModel", agenticAuthoringApiKey: "agenticAuthoringApiKey", agenticAuthoringComponentId: "agenticAuthoringComponentId", agenticAuthoringScope: "agenticAuthoringScope", agenticAuthoringEtag: "agenticAuthoringEtag", agenticAuthoringIncludeLlmDiagnostics: "agenticAuthoringIncludeLlmDiagnostics", agenticAuthoringEnableStreaming: "agenticAuthoringEnableStreaming", agenticAuthoringContextHints: "agenticAuthoringContextHints", showPageLifecycleActions: "showPageLifecycleActions", canDeleteSavedPage: "canDeleteSavedPage", pageLifecycleBusy: "pageLifecycleBusy", pageLifecycleResetRevision: "pageLifecycleResetRevision" }, outputs: { pageChange: "pageChange", pageSaveRequested: "pageSaveRequested", agenticAuthoringApplied: "agenticAuthoringApplied", agenticAuthoringSharedRuleHandoff: "agenticAuthoringSharedRuleHandoff", pageRestart: "pageRestart", savedPageDeleteRequested: "savedPageDeleteRequested" }, providers: [
|
|
16439
17614
|
providePraxisPageBuilderI18n(),
|
|
16440
17615
|
{ provide: DYNAMIC_PAGE_SHELL_EDITOR, useValue: WidgetShellEditorComponent },
|
|
16441
17616
|
], viewQueries: [{ propertyName: "runtime", first: true, predicate: ["runtime"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
16442
|
-
<div
|
|
17617
|
+
<div
|
|
17618
|
+
class="builder-shell"
|
|
17619
|
+
[class.builder-shell--agentic-review-rail]="agenticAuthoringReviewRailActive()"
|
|
17620
|
+
>
|
|
16443
17621
|
<praxis-dynamic-page
|
|
16444
17622
|
#runtime
|
|
16445
17623
|
[page]="currentPage()"
|
|
16446
17624
|
[context]="context"
|
|
16447
17625
|
[strictValidation]="strictValidation"
|
|
16448
|
-
[autoPersist]="
|
|
17626
|
+
[autoPersist]="false"
|
|
16449
17627
|
[enableCustomization]="showSettings()"
|
|
16450
17628
|
[showPageSettingsButton]="false"
|
|
16451
17629
|
[pageIdentity]="pageIdentity"
|
|
@@ -16453,6 +17631,7 @@ class DynamicPageBuilderComponent {
|
|
|
16453
17631
|
[pageEditorComponent]="pageEditorComponent"
|
|
16454
17632
|
[showWidgetAssistantButton]="enableAgenticAuthoring"
|
|
16455
17633
|
(pageChange)="onRuntimePageChange($event)"
|
|
17634
|
+
(widgetEvent)="onRuntimeWidgetEvent($event)"
|
|
16456
17635
|
(widgetSelectionChange)="onRuntimeWidgetSelectionChange($event)"
|
|
16457
17636
|
(widgetAssistantRequested)="openAgenticAuthoringForWidget($event)"
|
|
16458
17637
|
/>
|
|
@@ -16482,7 +17661,7 @@ class DynamicPageBuilderComponent {
|
|
|
16482
17661
|
[statusText]="agenticAuthoringStatus()"
|
|
16483
17662
|
[errorText]="agenticAuthoringError()"
|
|
16484
17663
|
[busy]="agenticAuthoringBusy()"
|
|
16485
|
-
[canApply]="
|
|
17664
|
+
[canApply]="agenticAuthoringCanApply()"
|
|
16486
17665
|
[primaryAction]="agenticAuthoringSubmitAction()"
|
|
16487
17666
|
[showAttachAction]="false"
|
|
16488
17667
|
[enablePastedAttachments]="false"
|
|
@@ -16500,7 +17679,7 @@ class DynamicPageBuilderComponent {
|
|
|
16500
17679
|
(removeAttachment)="removeAgenticAttachment($event)"
|
|
16501
17680
|
(editMessage)="editAgenticMessage($event)"
|
|
16502
17681
|
(resendMessage)="resendAgenticMessage($event)"
|
|
16503
|
-
(layoutChange)="
|
|
17682
|
+
(layoutChange)="onAgenticAuthoringLayoutChange($event)"
|
|
16504
17683
|
(close)="minimizeAgenticAuthoring()"
|
|
16505
17684
|
/>
|
|
16506
17685
|
|
|
@@ -16778,7 +17957,7 @@ class DynamicPageBuilderComponent {
|
|
|
16778
17957
|
[visible]="showSettings()"
|
|
16779
17958
|
[canUndo]="false"
|
|
16780
17959
|
[canRedo]="false"
|
|
16781
|
-
[showSave]="
|
|
17960
|
+
[showSave]="hasPageWidgets()"
|
|
16782
17961
|
[showPreview]="hasPageWidgets()"
|
|
16783
17962
|
(add)="onAddComponent()"
|
|
16784
17963
|
(settings)="openPageSettings()"
|
|
@@ -16841,7 +18020,7 @@ class DynamicPageBuilderComponent {
|
|
|
16841
18020
|
</button>
|
|
16842
18021
|
</praxis-floating-toolbar>
|
|
16843
18022
|
</div>
|
|
16844
|
-
`, isInline: true, styles: [":host{display:block;position:relative;min-height:var(--pdx-page-builder-min-height, 420px)}.builder-shell{display:block;position:relative;min-height:inherit;height:100%}.agentic-diagnostics-panel{position:absolute;z-index:21;right:16px;width:min(520px,calc(100% - 32px));max-height:min(440px,calc(100% - 32px));overflow:auto;padding:12px;border:1px solid rgba(107,114,128,.28);border-radius:8px;background:#fffffff5;color:#111827;box-shadow:0 14px 36px #0000003d}.agentic-diagnostics-panel--collapsed{width:min(280px,calc(100% - 32px));max-height:58px;overflow:hidden;padding:10px 12px;pointer-events:auto}.agentic-diagnostics-panel__header{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:13px;font-weight:700}.agentic-diagnostics-panel__header-actions{display:flex;align-items:center;gap:8px}.agentic-diagnostics-panel__badge{padding:2px 6px;border:1px solid rgba(107,114,128,.28);border-radius:8px;font-size:11px;font-weight:600;color:#4b5563}.agentic-diagnostics-panel__toggle,.shared-rule-cockpit__toggle{appearance:none;border:1px solid rgba(30,64,175,.18);border-radius:999px;background:#ffffffd6;color:#1e3a8a;cursor:pointer;font-size:11px;font-weight:700;line-height:1;padding:6px 9px;white-space:nowrap}.agentic-diagnostics-panel__description{margin:8px 0 10px;color:#4b5563;font-size:12px;line-height:1.4}.agentic-diagnostics-panel pre{margin:0;white-space:pre-wrap;overflow-wrap:anywhere;font-size:11px;line-height:1.45;color:#1f2937}praxis-ai-assistant-shell{position:relative;z-index:140}.builder-shell__agentic-toggle{position:relative}.builder-shell__agentic-toggle--open,.builder-shell__agentic-toggle--minimized{outline:2px solid rgba(96,165,250,.52);outline-offset:2px}.builder-shell__agentic-toggle--minimized:after{content:\"\";position:absolute;top:6px;right:6px;width:8px;height:8px;border:2px solid var(--md-sys-color-surface, #111827);border-radius:999px;background:#34d399}.shared-rule-cockpit{position:absolute;z-index:120;left:16px;bottom:88px;width:min(720px,calc(100% - 32px));max-height:min(560px,calc(100vh - 140px));padding:14px;border:1px solid rgba(30,64,175,.22);border-radius:12px;background:linear-gradient(135deg,#eff6fffa,#fffbebf5);color:#172554;box-shadow:0 18px 46px #0f172a38;overflow:auto;overscroll-behavior:contain}.shared-rule-cockpit--collapsed{width:min(360px,calc(100% - 32px));max-height:72px;overflow:hidden;padding:10px 12px}.shared-rule-cockpit__header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.shared-rule-cockpit__header-actions{display:flex;align-items:center;gap:8px}.shared-rule-cockpit__header div{display:grid;gap:2px}.shared-rule-cockpit__header strong{font-size:14px;line-height:1.2}.shared-rule-cockpit__header span{color:#475569;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__badge{flex:0 0 auto;max-width:220px;padding:3px 8px;border:1px solid rgba(30,64,175,.2);border-radius:999px;background:#ffffffbd;color:#1e3a8a;font-size:11px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.shared-rule-cockpit__description,.shared-rule-cockpit__status,.shared-rule-cockpit__error{margin:10px 0 0;color:#334155;font-size:12px;line-height:1.45}.shared-rule-cockpit__error{color:#991b1b;font-weight:600}.shared-rule-cockpit__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.shared-rule-cockpit__facts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:12px 0 0}.shared-rule-cockpit__facts div{min-width:0;padding:8px;border-radius:10px;background:#ffffffb8}.shared-rule-cockpit__facts dt{color:#64748b;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em}.shared-rule-cockpit__facts dd{margin:4px 0 0;color:#0f172a;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__enforcement-matrix{display:grid;gap:10px;margin-top:12px;padding:10px;border:1px solid rgba(30,64,175,.14);border-radius:12px;background:#ffffff94}.shared-rule-cockpit__matrix-header{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.shared-rule-cockpit__matrix-header div{display:grid;gap:2px}.shared-rule-cockpit__matrix-header strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__matrix-header span,.shared-rule-cockpit__matrix-source{color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-badge{flex:0 0 auto;padding:3px 8px;border-radius:999px;background:#16a34a1f;color:#166534;font-weight:800;white-space:nowrap}.shared-rule-cockpit__projection-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.shared-rule-cockpit__projection{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid rgba(15,23,42,.08);border-radius:11px;background:#f8fafcd1}.shared-rule-cockpit__projection[data-status=ready]{border-color:#16a34a33;background:#f0fdf4d1}.shared-rule-cockpit__projection span{color:#1d4ed8;font-size:10px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;overflow-wrap:anywhere}.shared-rule-cockpit__projection strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__projection small,.shared-rule-cockpit__projection em{color:#475569;font-size:11px;font-style:normal;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-source{margin:0}.shared-rule-cockpit__timeline{display:grid;gap:8px;max-height:190px;margin:12px 0 0;padding:0;overflow:auto;list-style:none}.shared-rule-cockpit__timeline-item{display:grid;grid-template-columns:auto minmax(0,1fr);gap:10px;padding:10px;border:1px solid rgba(30,64,175,.12);border-radius:12px;background:#ffffffc2}.shared-rule-cockpit__timeline-icon{display:grid;width:24px;height:24px;place-items:center;border-radius:999px;background:#1e40af1a;color:#1e3a8a;font-family:Material Icons;font-size:16px;line-height:1}.shared-rule-cockpit__timeline-item strong{color:#0f172a;font-size:12px;line-height:1.35}.shared-rule-cockpit__timeline-item p,.shared-rule-cockpit__timeline-item small,.shared-rule-cockpit__timeline-item time,.shared-rule-cockpit__timeline-empty{display:block;margin:3px 0 0;color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__timeline-badge{display:inline-flex;margin-left:6px;padding:2px 6px;border-radius:999px;background:#0ea5e91f;color:#075985;font-size:10px;font-weight:700}.shared-rule-cockpit__timeline-empty{padding:10px;border-radius:12px;background:#ffffffa3}@media(max-width:720px){.shared-rule-cockpit{bottom:72px;max-height:calc(100vh - 112px)}.shared-rule-cockpit__facts,.shared-rule-cockpit__projection-grid{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: DynamicWidgetPageComponent, selector: "praxis-dynamic-page", inputs: ["page", "context", "strictValidation", "enableCustomization", "showPageSettingsButton", "shellEditorComponent", "pageEditorComponent", "autoPersist", "pageIdentity", "componentInstanceId", "showWidgetAssistantButton"], outputs: ["pageChange", "widgetEvent", "widgetSelectionChange", "widgetAssistantRequested", "widgetDiagnosticsChange"] }, { kind: "component", type: FloatingToolbarComponent, selector: "praxis-floating-toolbar", inputs: ["visible", "canUndo", "canRedo", "showSave", "showPreview"], outputs: ["add", "undo", "redo", "settings", "preview", "save"] }, { kind: "component", type: ConnectionEditorComponent, selector: "praxis-connection-editor", inputs: ["open", "page"], outputs: ["pageChange", "focusWidget", "openPageSettings"] }, { kind: "component", type: PraxisAiAssistantShellComponent, selector: "praxis-ai-assistant-shell", inputs: ["labels", "mode", "state", "contextItems", "attachments", "messages", "quickReplies", "prompt", "statusText", "errorText", "testIdPrefix", "panelTestId", "submitTestId", "applyTestId", "primaryAction", "secondaryActions", "governanceActions", "busy", "canSubmit", "canApply", "submitOnEnter", "showAttachAction", "enablePastedAttachments", "enableFileAttachments", "attachmentAccept", "attachmentMultiple", "draggable", "resizable", "minWidth", "minHeight", "margin", "layout"], outputs: ["promptChange", "submitPrompt", "apply", "retryTurn", "cancelTurn", "shellAction", "close", "attach", "attachmentsPasted", "attachmentsSelected", "removeAttachment", "messageAction", "editMessage", "resendMessage", "quickReply", "layoutChange"] }] });
|
|
18023
|
+
`, isInline: true, styles: [":host{display:block;position:relative;min-height:var(--pdx-page-builder-min-height, 420px)}.builder-shell{display:block;position:relative;min-height:inherit;height:100%}.agentic-diagnostics-panel{position:absolute;z-index:21;right:16px;width:min(520px,calc(100% - 32px));max-height:min(440px,calc(100% - 32px));overflow:auto;padding:12px;border:1px solid rgba(107,114,128,.28);border-radius:8px;background:#fffffff5;color:#111827;box-shadow:0 14px 36px #0000003d}.agentic-diagnostics-panel--collapsed{width:min(280px,calc(100% - 32px));max-height:58px;overflow:hidden;padding:10px 12px;pointer-events:auto}.agentic-diagnostics-panel__header{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:13px;font-weight:700}.agentic-diagnostics-panel__header-actions{display:flex;align-items:center;gap:8px}.agentic-diagnostics-panel__badge{padding:2px 6px;border:1px solid rgba(107,114,128,.28);border-radius:8px;font-size:11px;font-weight:600;color:#4b5563}.agentic-diagnostics-panel__toggle,.shared-rule-cockpit__toggle{appearance:none;border:1px solid rgba(30,64,175,.18);border-radius:999px;background:#ffffffd6;color:#1e3a8a;cursor:pointer;font-size:11px;font-weight:700;line-height:1;padding:6px 9px;white-space:nowrap}.agentic-diagnostics-panel__description{margin:8px 0 10px;color:#4b5563;font-size:12px;line-height:1.4}.agentic-diagnostics-panel pre{margin:0;white-space:pre-wrap;overflow-wrap:anywhere;font-size:11px;line-height:1.45;color:#1f2937}praxis-ai-assistant-shell{position:relative;z-index:140}@media(min-width:1100px){.builder-shell--agentic-review-rail{box-sizing:border-box;padding-right:464px}}.builder-shell__agentic-toggle{position:relative}.builder-shell__agentic-toggle--open,.builder-shell__agentic-toggle--minimized{outline:2px solid rgba(96,165,250,.52);outline-offset:2px}.builder-shell__agentic-toggle--minimized:after{content:\"\";position:absolute;top:6px;right:6px;width:8px;height:8px;border:2px solid var(--md-sys-color-surface, #111827);border-radius:999px;background:#34d399}.shared-rule-cockpit{position:absolute;z-index:120;left:16px;bottom:88px;width:min(720px,calc(100% - 32px));max-height:min(560px,calc(100vh - 140px));padding:14px;border:1px solid rgba(30,64,175,.22);border-radius:12px;background:linear-gradient(135deg,#eff6fffa,#fffbebf5);color:#172554;box-shadow:0 18px 46px #0f172a38;overflow:auto;overscroll-behavior:contain}.shared-rule-cockpit--collapsed{width:min(360px,calc(100% - 32px));max-height:72px;overflow:hidden;padding:10px 12px}.shared-rule-cockpit__header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.shared-rule-cockpit__header-actions{display:flex;align-items:center;gap:8px}.shared-rule-cockpit__header div{display:grid;gap:2px}.shared-rule-cockpit__header strong{font-size:14px;line-height:1.2}.shared-rule-cockpit__header span{color:#475569;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__badge{flex:0 0 auto;max-width:220px;padding:3px 8px;border:1px solid rgba(30,64,175,.2);border-radius:999px;background:#ffffffbd;color:#1e3a8a;font-size:11px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.shared-rule-cockpit__description,.shared-rule-cockpit__status,.shared-rule-cockpit__error{margin:10px 0 0;color:#334155;font-size:12px;line-height:1.45}.shared-rule-cockpit__error{color:#991b1b;font-weight:600}.shared-rule-cockpit__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.shared-rule-cockpit__facts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:12px 0 0}.shared-rule-cockpit__facts div{min-width:0;padding:8px;border-radius:10px;background:#ffffffb8}.shared-rule-cockpit__facts dt{color:#64748b;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em}.shared-rule-cockpit__facts dd{margin:4px 0 0;color:#0f172a;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__enforcement-matrix{display:grid;gap:10px;margin-top:12px;padding:10px;border:1px solid rgba(30,64,175,.14);border-radius:12px;background:#ffffff94}.shared-rule-cockpit__matrix-header{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.shared-rule-cockpit__matrix-header div{display:grid;gap:2px}.shared-rule-cockpit__matrix-header strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__matrix-header span,.shared-rule-cockpit__matrix-source{color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-badge{flex:0 0 auto;padding:3px 8px;border-radius:999px;background:#16a34a1f;color:#166534;font-weight:800;white-space:nowrap}.shared-rule-cockpit__projection-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.shared-rule-cockpit__projection{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid rgba(15,23,42,.08);border-radius:11px;background:#f8fafcd1}.shared-rule-cockpit__projection[data-status=ready]{border-color:#16a34a33;background:#f0fdf4d1}.shared-rule-cockpit__projection span{color:#1d4ed8;font-size:10px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;overflow-wrap:anywhere}.shared-rule-cockpit__projection strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__projection small,.shared-rule-cockpit__projection em{color:#475569;font-size:11px;font-style:normal;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-source{margin:0}.shared-rule-cockpit__timeline{display:grid;gap:8px;max-height:190px;margin:12px 0 0;padding:0;overflow:auto;list-style:none}.shared-rule-cockpit__timeline-item{display:grid;grid-template-columns:auto minmax(0,1fr);gap:10px;padding:10px;border:1px solid rgba(30,64,175,.12);border-radius:12px;background:#ffffffc2}.shared-rule-cockpit__timeline-icon{display:grid;width:24px;height:24px;place-items:center;border-radius:999px;background:#1e40af1a;color:#1e3a8a;font-family:Material Icons;font-size:16px;line-height:1}.shared-rule-cockpit__timeline-item strong{color:#0f172a;font-size:12px;line-height:1.35}.shared-rule-cockpit__timeline-item p,.shared-rule-cockpit__timeline-item small,.shared-rule-cockpit__timeline-item time,.shared-rule-cockpit__timeline-empty{display:block;margin:3px 0 0;color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__timeline-badge{display:inline-flex;margin-left:6px;padding:2px 6px;border-radius:999px;background:#0ea5e91f;color:#075985;font-size:10px;font-weight:700}.shared-rule-cockpit__timeline-empty{padding:10px;border-radius:12px;background:#ffffffa3}@media(max-width:720px){.shared-rule-cockpit{bottom:72px;max-height:calc(100vh - 112px)}.shared-rule-cockpit__facts,.shared-rule-cockpit__projection-grid{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: DynamicWidgetPageComponent, selector: "praxis-dynamic-page", inputs: ["page", "context", "strictValidation", "enableCustomization", "showPageSettingsButton", "shellEditorComponent", "pageEditorComponent", "autoPersist", "pageIdentity", "componentInstanceId", "showWidgetAssistantButton"], outputs: ["pageChange", "widgetEvent", "widgetSelectionChange", "widgetAssistantRequested", "widgetDiagnosticsChange"] }, { kind: "component", type: FloatingToolbarComponent, selector: "praxis-floating-toolbar", inputs: ["visible", "canUndo", "canRedo", "showSave", "showPreview"], outputs: ["add", "undo", "redo", "settings", "preview", "save"] }, { kind: "component", type: ConnectionEditorComponent, selector: "praxis-connection-editor", inputs: ["open", "page"], outputs: ["pageChange", "focusWidget", "openPageSettings"] }, { kind: "component", type: PraxisAiAssistantShellComponent, selector: "praxis-ai-assistant-shell", inputs: ["labels", "mode", "state", "contextItems", "attachments", "messages", "quickReplies", "prompt", "statusText", "errorText", "testIdPrefix", "panelTestId", "submitTestId", "applyTestId", "primaryAction", "secondaryActions", "governanceActions", "busy", "canSubmit", "canApply", "submitOnEnter", "showAttachAction", "enablePastedAttachments", "enableFileAttachments", "attachmentAccept", "attachmentMultiple", "draggable", "resizable", "minWidth", "minHeight", "margin", "layout"], outputs: ["promptChange", "submitPrompt", "apply", "retryTurn", "cancelTurn", "shellAction", "close", "attach", "attachmentsPasted", "attachmentsSelected", "removeAttachment", "messageAction", "editMessage", "resendMessage", "quickReply", "layoutChange"] }] });
|
|
16845
18024
|
}
|
|
16846
18025
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: DynamicPageBuilderComponent, decorators: [{
|
|
16847
18026
|
type: Component,
|
|
@@ -16859,13 +18038,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
16859
18038
|
providePraxisPageBuilderI18n(),
|
|
16860
18039
|
{ provide: DYNAMIC_PAGE_SHELL_EDITOR, useValue: WidgetShellEditorComponent },
|
|
16861
18040
|
], template: `
|
|
16862
|
-
<div
|
|
18041
|
+
<div
|
|
18042
|
+
class="builder-shell"
|
|
18043
|
+
[class.builder-shell--agentic-review-rail]="agenticAuthoringReviewRailActive()"
|
|
18044
|
+
>
|
|
16863
18045
|
<praxis-dynamic-page
|
|
16864
18046
|
#runtime
|
|
16865
18047
|
[page]="currentPage()"
|
|
16866
18048
|
[context]="context"
|
|
16867
18049
|
[strictValidation]="strictValidation"
|
|
16868
|
-
[autoPersist]="
|
|
18050
|
+
[autoPersist]="false"
|
|
16869
18051
|
[enableCustomization]="showSettings()"
|
|
16870
18052
|
[showPageSettingsButton]="false"
|
|
16871
18053
|
[pageIdentity]="pageIdentity"
|
|
@@ -16873,6 +18055,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
16873
18055
|
[pageEditorComponent]="pageEditorComponent"
|
|
16874
18056
|
[showWidgetAssistantButton]="enableAgenticAuthoring"
|
|
16875
18057
|
(pageChange)="onRuntimePageChange($event)"
|
|
18058
|
+
(widgetEvent)="onRuntimeWidgetEvent($event)"
|
|
16876
18059
|
(widgetSelectionChange)="onRuntimeWidgetSelectionChange($event)"
|
|
16877
18060
|
(widgetAssistantRequested)="openAgenticAuthoringForWidget($event)"
|
|
16878
18061
|
/>
|
|
@@ -16902,7 +18085,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
16902
18085
|
[statusText]="agenticAuthoringStatus()"
|
|
16903
18086
|
[errorText]="agenticAuthoringError()"
|
|
16904
18087
|
[busy]="agenticAuthoringBusy()"
|
|
16905
|
-
[canApply]="
|
|
18088
|
+
[canApply]="agenticAuthoringCanApply()"
|
|
16906
18089
|
[primaryAction]="agenticAuthoringSubmitAction()"
|
|
16907
18090
|
[showAttachAction]="false"
|
|
16908
18091
|
[enablePastedAttachments]="false"
|
|
@@ -16920,7 +18103,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
16920
18103
|
(removeAttachment)="removeAgenticAttachment($event)"
|
|
16921
18104
|
(editMessage)="editAgenticMessage($event)"
|
|
16922
18105
|
(resendMessage)="resendAgenticMessage($event)"
|
|
16923
|
-
(layoutChange)="
|
|
18106
|
+
(layoutChange)="onAgenticAuthoringLayoutChange($event)"
|
|
16924
18107
|
(close)="minimizeAgenticAuthoring()"
|
|
16925
18108
|
/>
|
|
16926
18109
|
|
|
@@ -17198,7 +18381,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
17198
18381
|
[visible]="showSettings()"
|
|
17199
18382
|
[canUndo]="false"
|
|
17200
18383
|
[canRedo]="false"
|
|
17201
|
-
[showSave]="
|
|
18384
|
+
[showSave]="hasPageWidgets()"
|
|
17202
18385
|
[showPreview]="hasPageWidgets()"
|
|
17203
18386
|
(add)="onAddComponent()"
|
|
17204
18387
|
(settings)="openPageSettings()"
|
|
@@ -17261,7 +18444,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
17261
18444
|
</button>
|
|
17262
18445
|
</praxis-floating-toolbar>
|
|
17263
18446
|
</div>
|
|
17264
|
-
`, styles: [":host{display:block;position:relative;min-height:var(--pdx-page-builder-min-height, 420px)}.builder-shell{display:block;position:relative;min-height:inherit;height:100%}.agentic-diagnostics-panel{position:absolute;z-index:21;right:16px;width:min(520px,calc(100% - 32px));max-height:min(440px,calc(100% - 32px));overflow:auto;padding:12px;border:1px solid rgba(107,114,128,.28);border-radius:8px;background:#fffffff5;color:#111827;box-shadow:0 14px 36px #0000003d}.agentic-diagnostics-panel--collapsed{width:min(280px,calc(100% - 32px));max-height:58px;overflow:hidden;padding:10px 12px;pointer-events:auto}.agentic-diagnostics-panel__header{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:13px;font-weight:700}.agentic-diagnostics-panel__header-actions{display:flex;align-items:center;gap:8px}.agentic-diagnostics-panel__badge{padding:2px 6px;border:1px solid rgba(107,114,128,.28);border-radius:8px;font-size:11px;font-weight:600;color:#4b5563}.agentic-diagnostics-panel__toggle,.shared-rule-cockpit__toggle{appearance:none;border:1px solid rgba(30,64,175,.18);border-radius:999px;background:#ffffffd6;color:#1e3a8a;cursor:pointer;font-size:11px;font-weight:700;line-height:1;padding:6px 9px;white-space:nowrap}.agentic-diagnostics-panel__description{margin:8px 0 10px;color:#4b5563;font-size:12px;line-height:1.4}.agentic-diagnostics-panel pre{margin:0;white-space:pre-wrap;overflow-wrap:anywhere;font-size:11px;line-height:1.45;color:#1f2937}praxis-ai-assistant-shell{position:relative;z-index:140}.builder-shell__agentic-toggle{position:relative}.builder-shell__agentic-toggle--open,.builder-shell__agentic-toggle--minimized{outline:2px solid rgba(96,165,250,.52);outline-offset:2px}.builder-shell__agentic-toggle--minimized:after{content:\"\";position:absolute;top:6px;right:6px;width:8px;height:8px;border:2px solid var(--md-sys-color-surface, #111827);border-radius:999px;background:#34d399}.shared-rule-cockpit{position:absolute;z-index:120;left:16px;bottom:88px;width:min(720px,calc(100% - 32px));max-height:min(560px,calc(100vh - 140px));padding:14px;border:1px solid rgba(30,64,175,.22);border-radius:12px;background:linear-gradient(135deg,#eff6fffa,#fffbebf5);color:#172554;box-shadow:0 18px 46px #0f172a38;overflow:auto;overscroll-behavior:contain}.shared-rule-cockpit--collapsed{width:min(360px,calc(100% - 32px));max-height:72px;overflow:hidden;padding:10px 12px}.shared-rule-cockpit__header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.shared-rule-cockpit__header-actions{display:flex;align-items:center;gap:8px}.shared-rule-cockpit__header div{display:grid;gap:2px}.shared-rule-cockpit__header strong{font-size:14px;line-height:1.2}.shared-rule-cockpit__header span{color:#475569;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__badge{flex:0 0 auto;max-width:220px;padding:3px 8px;border:1px solid rgba(30,64,175,.2);border-radius:999px;background:#ffffffbd;color:#1e3a8a;font-size:11px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.shared-rule-cockpit__description,.shared-rule-cockpit__status,.shared-rule-cockpit__error{margin:10px 0 0;color:#334155;font-size:12px;line-height:1.45}.shared-rule-cockpit__error{color:#991b1b;font-weight:600}.shared-rule-cockpit__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.shared-rule-cockpit__facts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:12px 0 0}.shared-rule-cockpit__facts div{min-width:0;padding:8px;border-radius:10px;background:#ffffffb8}.shared-rule-cockpit__facts dt{color:#64748b;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em}.shared-rule-cockpit__facts dd{margin:4px 0 0;color:#0f172a;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__enforcement-matrix{display:grid;gap:10px;margin-top:12px;padding:10px;border:1px solid rgba(30,64,175,.14);border-radius:12px;background:#ffffff94}.shared-rule-cockpit__matrix-header{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.shared-rule-cockpit__matrix-header div{display:grid;gap:2px}.shared-rule-cockpit__matrix-header strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__matrix-header span,.shared-rule-cockpit__matrix-source{color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-badge{flex:0 0 auto;padding:3px 8px;border-radius:999px;background:#16a34a1f;color:#166534;font-weight:800;white-space:nowrap}.shared-rule-cockpit__projection-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.shared-rule-cockpit__projection{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid rgba(15,23,42,.08);border-radius:11px;background:#f8fafcd1}.shared-rule-cockpit__projection[data-status=ready]{border-color:#16a34a33;background:#f0fdf4d1}.shared-rule-cockpit__projection span{color:#1d4ed8;font-size:10px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;overflow-wrap:anywhere}.shared-rule-cockpit__projection strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__projection small,.shared-rule-cockpit__projection em{color:#475569;font-size:11px;font-style:normal;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-source{margin:0}.shared-rule-cockpit__timeline{display:grid;gap:8px;max-height:190px;margin:12px 0 0;padding:0;overflow:auto;list-style:none}.shared-rule-cockpit__timeline-item{display:grid;grid-template-columns:auto minmax(0,1fr);gap:10px;padding:10px;border:1px solid rgba(30,64,175,.12);border-radius:12px;background:#ffffffc2}.shared-rule-cockpit__timeline-icon{display:grid;width:24px;height:24px;place-items:center;border-radius:999px;background:#1e40af1a;color:#1e3a8a;font-family:Material Icons;font-size:16px;line-height:1}.shared-rule-cockpit__timeline-item strong{color:#0f172a;font-size:12px;line-height:1.35}.shared-rule-cockpit__timeline-item p,.shared-rule-cockpit__timeline-item small,.shared-rule-cockpit__timeline-item time,.shared-rule-cockpit__timeline-empty{display:block;margin:3px 0 0;color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__timeline-badge{display:inline-flex;margin-left:6px;padding:2px 6px;border-radius:999px;background:#0ea5e91f;color:#075985;font-size:10px;font-weight:700}.shared-rule-cockpit__timeline-empty{padding:10px;border-radius:12px;background:#ffffffa3}@media(max-width:720px){.shared-rule-cockpit{bottom:72px;max-height:calc(100vh - 112px)}.shared-rule-cockpit__facts,.shared-rule-cockpit__projection-grid{grid-template-columns:1fr}}\n"] }]
|
|
18447
|
+
`, styles: [":host{display:block;position:relative;min-height:var(--pdx-page-builder-min-height, 420px)}.builder-shell{display:block;position:relative;min-height:inherit;height:100%}.agentic-diagnostics-panel{position:absolute;z-index:21;right:16px;width:min(520px,calc(100% - 32px));max-height:min(440px,calc(100% - 32px));overflow:auto;padding:12px;border:1px solid rgba(107,114,128,.28);border-radius:8px;background:#fffffff5;color:#111827;box-shadow:0 14px 36px #0000003d}.agentic-diagnostics-panel--collapsed{width:min(280px,calc(100% - 32px));max-height:58px;overflow:hidden;padding:10px 12px;pointer-events:auto}.agentic-diagnostics-panel__header{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:13px;font-weight:700}.agentic-diagnostics-panel__header-actions{display:flex;align-items:center;gap:8px}.agentic-diagnostics-panel__badge{padding:2px 6px;border:1px solid rgba(107,114,128,.28);border-radius:8px;font-size:11px;font-weight:600;color:#4b5563}.agentic-diagnostics-panel__toggle,.shared-rule-cockpit__toggle{appearance:none;border:1px solid rgba(30,64,175,.18);border-radius:999px;background:#ffffffd6;color:#1e3a8a;cursor:pointer;font-size:11px;font-weight:700;line-height:1;padding:6px 9px;white-space:nowrap}.agentic-diagnostics-panel__description{margin:8px 0 10px;color:#4b5563;font-size:12px;line-height:1.4}.agentic-diagnostics-panel pre{margin:0;white-space:pre-wrap;overflow-wrap:anywhere;font-size:11px;line-height:1.45;color:#1f2937}praxis-ai-assistant-shell{position:relative;z-index:140}@media(min-width:1100px){.builder-shell--agentic-review-rail{box-sizing:border-box;padding-right:464px}}.builder-shell__agentic-toggle{position:relative}.builder-shell__agentic-toggle--open,.builder-shell__agentic-toggle--minimized{outline:2px solid rgba(96,165,250,.52);outline-offset:2px}.builder-shell__agentic-toggle--minimized:after{content:\"\";position:absolute;top:6px;right:6px;width:8px;height:8px;border:2px solid var(--md-sys-color-surface, #111827);border-radius:999px;background:#34d399}.shared-rule-cockpit{position:absolute;z-index:120;left:16px;bottom:88px;width:min(720px,calc(100% - 32px));max-height:min(560px,calc(100vh - 140px));padding:14px;border:1px solid rgba(30,64,175,.22);border-radius:12px;background:linear-gradient(135deg,#eff6fffa,#fffbebf5);color:#172554;box-shadow:0 18px 46px #0f172a38;overflow:auto;overscroll-behavior:contain}.shared-rule-cockpit--collapsed{width:min(360px,calc(100% - 32px));max-height:72px;overflow:hidden;padding:10px 12px}.shared-rule-cockpit__header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.shared-rule-cockpit__header-actions{display:flex;align-items:center;gap:8px}.shared-rule-cockpit__header div{display:grid;gap:2px}.shared-rule-cockpit__header strong{font-size:14px;line-height:1.2}.shared-rule-cockpit__header span{color:#475569;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__badge{flex:0 0 auto;max-width:220px;padding:3px 8px;border:1px solid rgba(30,64,175,.2);border-radius:999px;background:#ffffffbd;color:#1e3a8a;font-size:11px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.shared-rule-cockpit__description,.shared-rule-cockpit__status,.shared-rule-cockpit__error{margin:10px 0 0;color:#334155;font-size:12px;line-height:1.45}.shared-rule-cockpit__error{color:#991b1b;font-weight:600}.shared-rule-cockpit__actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.shared-rule-cockpit__facts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:12px 0 0}.shared-rule-cockpit__facts div{min-width:0;padding:8px;border-radius:10px;background:#ffffffb8}.shared-rule-cockpit__facts dt{color:#64748b;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.04em}.shared-rule-cockpit__facts dd{margin:4px 0 0;color:#0f172a;font-size:12px;overflow-wrap:anywhere}.shared-rule-cockpit__enforcement-matrix{display:grid;gap:10px;margin-top:12px;padding:10px;border:1px solid rgba(30,64,175,.14);border-radius:12px;background:#ffffff94}.shared-rule-cockpit__matrix-header{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.shared-rule-cockpit__matrix-header div{display:grid;gap:2px}.shared-rule-cockpit__matrix-header strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__matrix-header span,.shared-rule-cockpit__matrix-source{color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-badge{flex:0 0 auto;padding:3px 8px;border-radius:999px;background:#16a34a1f;color:#166534;font-weight:800;white-space:nowrap}.shared-rule-cockpit__projection-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.shared-rule-cockpit__projection{display:grid;gap:3px;min-width:0;padding:9px;border:1px solid rgba(15,23,42,.08);border-radius:11px;background:#f8fafcd1}.shared-rule-cockpit__projection[data-status=ready]{border-color:#16a34a33;background:#f0fdf4d1}.shared-rule-cockpit__projection span{color:#1d4ed8;font-size:10px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;overflow-wrap:anywhere}.shared-rule-cockpit__projection strong{color:#0f172a;font-size:12px}.shared-rule-cockpit__projection small,.shared-rule-cockpit__projection em{color:#475569;font-size:11px;font-style:normal;overflow-wrap:anywhere}.shared-rule-cockpit__matrix-source{margin:0}.shared-rule-cockpit__timeline{display:grid;gap:8px;max-height:190px;margin:12px 0 0;padding:0;overflow:auto;list-style:none}.shared-rule-cockpit__timeline-item{display:grid;grid-template-columns:auto minmax(0,1fr);gap:10px;padding:10px;border:1px solid rgba(30,64,175,.12);border-radius:12px;background:#ffffffc2}.shared-rule-cockpit__timeline-icon{display:grid;width:24px;height:24px;place-items:center;border-radius:999px;background:#1e40af1a;color:#1e3a8a;font-family:Material Icons;font-size:16px;line-height:1}.shared-rule-cockpit__timeline-item strong{color:#0f172a;font-size:12px;line-height:1.35}.shared-rule-cockpit__timeline-item p,.shared-rule-cockpit__timeline-item small,.shared-rule-cockpit__timeline-item time,.shared-rule-cockpit__timeline-empty{display:block;margin:3px 0 0;color:#475569;font-size:11px;line-height:1.35;overflow-wrap:anywhere}.shared-rule-cockpit__timeline-badge{display:inline-flex;margin-left:6px;padding:2px 6px;border-radius:999px;background:#0ea5e91f;color:#075985;font-size:10px;font-weight:700}.shared-rule-cockpit__timeline-empty{padding:10px;border-radius:12px;background:#ffffffa3}@media(max-width:720px){.shared-rule-cockpit{bottom:72px;max-height:calc(100vh - 112px)}.shared-rule-cockpit__facts,.shared-rule-cockpit__projection-grid{grid-template-columns:1fr}}\n"] }]
|
|
17265
18448
|
}], ctorParameters: () => [{ type: i1.MatDialog }, { type: undefined, decorators: [{
|
|
17266
18449
|
type: Optional
|
|
17267
18450
|
}, {
|
|
@@ -17318,6 +18501,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
|
|
|
17318
18501
|
type: Input
|
|
17319
18502
|
}], pageChange: [{
|
|
17320
18503
|
type: Output
|
|
18504
|
+
}], pageSaveRequested: [{
|
|
18505
|
+
type: Output
|
|
17321
18506
|
}], agenticAuthoringApplied: [{
|
|
17322
18507
|
type: Output
|
|
17323
18508
|
}], agenticAuthoringSharedRuleHandoff: [{
|