@praxisui/page-builder 8.0.0-beta.85 → 8.0.0-beta.87

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.
@@ -11374,6 +11374,11 @@ const PAGE_BUILDER_AI_CAPABILITIES = {
11374
11374
  { path: 'uiCompositionPlan.version', category: 'page', valueKind: 'string', description: 'Versao do plano. Valor atual: 1.0.' },
11375
11375
  { path: 'uiCompositionPlan.kind', category: 'page', valueKind: 'string', description: 'Discriminador do plano. Valor atual: praxis.ui-composition-plan.' },
11376
11376
  { path: 'uiCompositionPlan.layoutPreset', category: 'layout', valueKind: 'string', description: 'Preset semantico opcional da composicao planejada.' },
11377
+ { path: 'uiCompositionPlan.layoutPresetOptions', category: 'layout', valueKind: 'object', description: 'Opcoes semanticas opcionais do preset, como familia visual, estrategia responsiva e politica de densidade.' },
11378
+ { path: 'uiCompositionPlan.grouping', category: 'layout', valueKind: 'array', description: 'Agrupamentos semanticos opcionais para organizar widgets em hero, section, tabs ou rail no runtime.' },
11379
+ { path: 'uiCompositionPlan.slotAssignments', category: 'layout', valueKind: 'object', description: 'Mapa opcional widgetKey -> slot semantico para alinhar widgets gerados a presets de layout sem depender de dominio.' },
11380
+ { path: 'uiCompositionPlan.deviceLayouts', category: 'layout', valueKind: 'object', description: 'Variantes responsivas opcionais para desktop, tablet e mobile, incluindo canvas, groupingOverrides e widgetOverrides.' },
11381
+ { path: 'uiCompositionPlan.themePreset', category: 'layout', valueKind: 'string', description: 'Preset visual opcional do runtime, por exemplo analytics-calm, workspace-balanced ou ops-monitoring.' },
11377
11382
  { path: 'uiCompositionPlan.state', category: 'state', valueKind: 'object', description: 'Estado inicial/declarativo que sera compilado para page.state.' },
11378
11383
  { path: 'uiCompositionPlan.widgets', category: 'widgets', valueKind: 'array', description: 'Widgets planejados antes da compilacao para page.widgets.' },
11379
11384
  { path: 'uiCompositionPlan.widgets[].key', category: 'widgets', valueKind: 'string', description: 'ID estavel do widget planejado.', critical: true },
@@ -12047,9 +12052,10 @@ const PAGE_BUILDER_COMPONENT_CONTEXT_PACK = {
12047
12052
  ],
12048
12053
  };
12049
12054
 
12050
- const DEFAULT_AGENTIC_AUTHORING_REQUEST_TIMEOUT_MS = 15000;
12055
+ const DEFAULT_AGENTIC_AUTHORING_REQUEST_TIMEOUT_MS = 120000;
12051
12056
  const DEFAULT_TURN_STREAM_START_TIMEOUT_MS = 10000;
12052
12057
  const DEFAULT_TURN_STREAM_TIMEOUT_MS = 240000;
12058
+ const DEFAULT_TURN_STREAM_RESULT_FALLBACK_MS = 90000;
12053
12059
  const PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS = new InjectionToken('PAGE_BUILDER_AGENTIC_AUTHORING_OPTIONS');
12054
12060
  class PageBuilderAgenticAuthoringService {
12055
12061
  http = inject(HttpClient);
@@ -12110,7 +12116,9 @@ class PageBuilderAgenticAuthoringService {
12110
12116
  let source = null;
12111
12117
  let closed = false;
12112
12118
  let streamTimeout = null;
12119
+ let resultFallbackTimeout = null;
12113
12120
  const streamTimeoutMs = this.streamTurnTimeoutMs();
12121
+ const resultFallbackMs = this.streamResultFallbackMs();
12114
12122
  let probeAbort = typeof AbortController !== 'undefined'
12115
12123
  ? new AbortController()
12116
12124
  : null;
@@ -12121,16 +12129,41 @@ class PageBuilderAgenticAuthoringService {
12121
12129
  streamTimeout = null;
12122
12130
  }
12123
12131
  };
12132
+ const clearResultFallbackTimeout = () => {
12133
+ if (resultFallbackTimeout) {
12134
+ clearTimeout(resultFallbackTimeout);
12135
+ resultFallbackTimeout = null;
12136
+ }
12137
+ };
12124
12138
  const closeSource = () => {
12125
12139
  if (closed) {
12126
12140
  return;
12127
12141
  }
12128
12142
  closed = true;
12129
12143
  clearStreamTimeout();
12144
+ clearResultFallbackTimeout();
12130
12145
  streamAbort?.abort();
12131
12146
  streamAbort = null;
12132
12147
  source?.close();
12133
12148
  };
12149
+ const startResultFallbackTimer = () => {
12150
+ clearResultFallbackTimeout();
12151
+ if (resultFallbackMs <= 0)
12152
+ return;
12153
+ resultFallbackTimeout = setTimeout(() => {
12154
+ if (closed)
12155
+ return;
12156
+ streamAbort?.abort();
12157
+ streamAbort = null;
12158
+ source?.close();
12159
+ observer.error(this.streamConnectionError({
12160
+ code: 'agentic-authoring-result-fallback',
12161
+ message: `Agentic authoring stream did not deliver a result after ${resultFallbackMs}ms.`,
12162
+ fallbackAuthoringUrl: start.fallbackAuthoringUrl ?? null,
12163
+ }));
12164
+ closeSource();
12165
+ }, resultFallbackMs);
12166
+ };
12134
12167
  streamTimeout = setTimeout(() => {
12135
12168
  if (closed) {
12136
12169
  return;
@@ -12154,6 +12187,7 @@ class PageBuilderAgenticAuthoringService {
12154
12187
  }
12155
12188
  observer.next(parsed);
12156
12189
  if (parsed.type === 'result' || parsed.type === 'error' || parsed.type === 'cancelled') {
12190
+ clearResultFallbackTimeout();
12157
12191
  observer.complete();
12158
12192
  closeSource();
12159
12193
  }
@@ -12171,6 +12205,7 @@ class PageBuilderAgenticAuthoringService {
12171
12205
  }
12172
12206
  if (!this.options?.eventSourceFactory && typeof fetch === 'function' && typeof TextDecoder !== 'undefined') {
12173
12207
  streamAbort = typeof AbortController !== 'undefined' ? new AbortController() : null;
12208
+ startResultFallbackTimer();
12174
12209
  void this.consumeFetchTurnStream(url, streamAbort, handleMessage, () => closed).catch((error) => {
12175
12210
  if (closed) {
12176
12211
  return;
@@ -12188,6 +12223,7 @@ class PageBuilderAgenticAuthoringService {
12188
12223
  observer.error(this.streamConnectionError(error));
12189
12224
  return;
12190
12225
  }
12226
+ startResultFallbackTimer();
12191
12227
  source.onmessage = handleMessage;
12192
12228
  if (source.addEventListener) {
12193
12229
  for (const type of AI_STREAM_EVENT_TYPES) {
@@ -12222,6 +12258,7 @@ class PageBuilderAgenticAuthoringService {
12222
12258
  streamAbort?.abort();
12223
12259
  streamAbort = null;
12224
12260
  clearStreamTimeout();
12261
+ clearResultFallbackTimeout();
12225
12262
  };
12226
12263
  });
12227
12264
  }
@@ -12293,6 +12330,9 @@ class PageBuilderAgenticAuthoringService {
12293
12330
  streamTurnTimeoutMs() {
12294
12331
  return Math.max(1, this.options?.streamTurnTimeoutMs ?? DEFAULT_TURN_STREAM_TIMEOUT_MS);
12295
12332
  }
12333
+ streamResultFallbackMs() {
12334
+ return Math.max(0, this.options?.streamResultFallbackMs ?? DEFAULT_TURN_STREAM_RESULT_FALLBACK_MS);
12335
+ }
12296
12336
  requestTimeoutMs() {
12297
12337
  return Math.max(1, this.options?.requestTimeoutMs ?? DEFAULT_AGENTIC_AUTHORING_REQUEST_TIMEOUT_MS);
12298
12338
  }
@@ -12986,8 +13026,13 @@ function compileUiCompositionPlan(plan) {
12986
13026
  valid: true,
12987
13027
  page: {
12988
13028
  layoutPreset: plan.layoutPreset,
13029
+ layoutPresetOptions: clone(plan.layoutPresetOptions),
12989
13030
  canvas: clone(plan.canvas),
13031
+ deviceLayouts: clone(plan.deviceLayouts),
13032
+ grouping: clone(plan.grouping),
13033
+ slotAssignments: clone(plan.slotAssignments),
12990
13034
  state: clone(plan.state),
13035
+ themePreset: plan.themePreset,
12991
13036
  widgets: plan.widgets.map((widget) => toWidgetInstance(widget, plan.bindings ?? [])),
12992
13037
  composition: {
12993
13038
  version: '1.0.0',
@@ -13051,6 +13096,9 @@ function validateUiCompositionPlan(plan) {
13051
13096
  }
13052
13097
  }
13053
13098
  validateCanvas(plan.canvas, widgetKeys, diagnostics);
13099
+ validateGrouping(plan.grouping, widgetKeys, diagnostics);
13100
+ validateDeviceLayouts(plan.deviceLayouts, widgetKeys, diagnostics);
13101
+ validateSlotAssignments(plan.slotAssignments, widgetKeys, diagnostics);
13054
13102
  return diagnostics;
13055
13103
  }
13056
13104
  function validateCanvas(canvas, widgetKeys, diagnostics) {
@@ -13066,6 +13114,107 @@ function validateCanvas(canvas, widgetKeys, diagnostics) {
13066
13114
  }
13067
13115
  }
13068
13116
  }
13117
+ function validateSlotAssignments(slotAssignments, widgetKeys, diagnostics) {
13118
+ if (!slotAssignments || typeof slotAssignments !== 'object')
13119
+ return;
13120
+ for (const [widgetKey, slotId] of Object.entries(slotAssignments)) {
13121
+ if (!widgetKeys.has(widgetKey)) {
13122
+ diagnostics.push({
13123
+ code: 'slot-assignment-widget-not-found',
13124
+ message: `Slot assignment references unknown widget "${widgetKey}".`,
13125
+ path: `slotAssignments.${widgetKey}`,
13126
+ });
13127
+ }
13128
+ if (!String(slotId || '').trim()) {
13129
+ diagnostics.push({
13130
+ code: 'slot-assignment-slot-required',
13131
+ message: `Slot assignment for widget "${widgetKey}" must declare a slot id.`,
13132
+ path: `slotAssignments.${widgetKey}`,
13133
+ });
13134
+ }
13135
+ }
13136
+ }
13137
+ function validateDeviceLayouts(deviceLayouts, widgetKeys, diagnostics) {
13138
+ if (!deviceLayouts)
13139
+ return;
13140
+ for (const [device, variant] of Object.entries(deviceLayouts)) {
13141
+ for (const key of Object.keys(variant?.canvas?.items ?? {})) {
13142
+ if (!widgetKeys.has(key)) {
13143
+ diagnostics.push({
13144
+ code: 'device-layout-widget-not-found',
13145
+ message: `Device layout "${device}" references unknown widget "${key}".`,
13146
+ path: `deviceLayouts.${device}.canvas.items.${key}`,
13147
+ });
13148
+ }
13149
+ }
13150
+ for (const key of Object.keys(variant?.widgetOverrides ?? {})) {
13151
+ if (!widgetKeys.has(key)) {
13152
+ diagnostics.push({
13153
+ code: 'device-layout-widget-override-not-found',
13154
+ message: `Device layout "${device}" overrides unknown widget "${key}".`,
13155
+ path: `deviceLayouts.${device}.widgetOverrides.${key}`,
13156
+ });
13157
+ }
13158
+ }
13159
+ for (const [groupIndex, override] of (variant?.groupingOverrides ?? []).entries()) {
13160
+ for (const widgetKey of override.widgetKeys ?? []) {
13161
+ if (!widgetKeys.has(widgetKey)) {
13162
+ diagnostics.push({
13163
+ code: 'device-layout-grouping-widget-not-found',
13164
+ message: `Device layout "${device}" grouping override references unknown widget "${widgetKey}".`,
13165
+ path: `deviceLayouts.${device}.groupingOverrides.${groupIndex}.widgetKeys`,
13166
+ });
13167
+ }
13168
+ }
13169
+ for (const [tabIndex, tab] of (override.tabs ?? []).entries()) {
13170
+ for (const widgetKey of tab.widgetKeys ?? []) {
13171
+ if (!widgetKeys.has(widgetKey)) {
13172
+ diagnostics.push({
13173
+ code: 'device-layout-grouping-widget-not-found',
13174
+ message: `Device layout "${device}" tab override references unknown widget "${widgetKey}".`,
13175
+ path: `deviceLayouts.${device}.groupingOverrides.${groupIndex}.tabs.${tabIndex}.widgetKeys`,
13176
+ });
13177
+ }
13178
+ }
13179
+ }
13180
+ }
13181
+ }
13182
+ }
13183
+ function validateGrouping(grouping, widgetKeys, diagnostics) {
13184
+ if (!Array.isArray(grouping))
13185
+ return;
13186
+ const groupIds = new Set();
13187
+ grouping.forEach((group, index) => {
13188
+ if (!group?.id?.trim()) {
13189
+ diagnostics.push({
13190
+ code: 'group-id-required',
13191
+ message: 'Every planned group must declare a stable id.',
13192
+ path: `grouping.${index}.id`,
13193
+ });
13194
+ return;
13195
+ }
13196
+ if (groupIds.has(group.id)) {
13197
+ diagnostics.push({
13198
+ code: 'group-id-duplicated',
13199
+ message: `Group id "${group.id}" is duplicated.`,
13200
+ path: `grouping.${index}.id`,
13201
+ });
13202
+ }
13203
+ groupIds.add(group.id);
13204
+ const references = group.kind === 'tabs'
13205
+ ? group.tabs.flatMap((tab) => tab.widgetKeys ?? [])
13206
+ : group.widgetKeys ?? [];
13207
+ references.forEach((widgetKey) => {
13208
+ if (!widgetKeys.has(widgetKey)) {
13209
+ diagnostics.push({
13210
+ code: 'grouping-widget-not-found',
13211
+ message: `Grouping "${group.id}" references unknown widget "${widgetKey}".`,
13212
+ path: `grouping.${index}.widgetKeys`,
13213
+ });
13214
+ }
13215
+ });
13216
+ });
13217
+ }
13069
13218
  function validateEndpoint(endpoint, widgetKeys, diagnostics, path, allowGlobalAction) {
13070
13219
  if (!endpoint || typeof endpoint !== 'object') {
13071
13220
  diagnostics.push({
@@ -13999,7 +14148,10 @@ class PageBuilderAgenticAuthoringTurnFlow {
13999
14148
  diagnostics: { intentResolution },
14000
14149
  };
14001
14150
  }
14002
- const intentFailure = this.describeIntentResolutionFailure(intentResolution);
14151
+ const shouldGenerateGuidedPreview = this.shouldAutoGenerateGuidedPreview(intentResolution, intentQuickReplies, prompt);
14152
+ const intentFailure = shouldGenerateGuidedPreview
14153
+ ? null
14154
+ : this.describeIntentResolutionFailure(intentResolution);
14003
14155
  if (intentFailure) {
14004
14156
  return {
14005
14157
  state: 'error',
@@ -15209,6 +15361,9 @@ class PageBuilderAgenticAuthoringTurnFlow {
15209
15361
  'adicione',
15210
15362
  'adicionar',
15211
15363
  'faca',
15364
+ 'quero',
15365
+ 'preciso',
15366
+ 'necessito',
15212
15367
  ].some((term) => normalized.includes(term));
15213
15368
  const artifact = [
15214
15369
  'preview',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@praxisui/page-builder",
3
- "version": "8.0.0-beta.85",
3
+ "version": "8.0.0-beta.87",
4
4
  "description": "Page and widget builder utilities for Praxis UI (grid, dynamic widgets, editors).",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
@@ -8,9 +8,9 @@
8
8
  "@angular/forms": "^21.0.0",
9
9
  "@angular/cdk": "^21.0.0",
10
10
  "@angular/material": "^21.0.0",
11
- "@praxisui/ai": "^8.0.0-beta.85",
12
- "@praxisui/core": "^8.0.0-beta.85",
13
- "@praxisui/settings-panel": "^8.0.0-beta.85",
11
+ "@praxisui/ai": "^8.0.0-beta.87",
12
+ "@praxisui/core": "^8.0.0-beta.87",
13
+ "@praxisui/settings-panel": "^8.0.0-beta.87",
14
14
  "rxjs": "~7.8.0"
15
15
  },
16
16
  "dependencies": {
@@ -1,7 +1,7 @@
1
1
  import { MatDialogRef, MatDialog } from '@angular/material/dialog';
2
2
  import * as _angular_core from '@angular/core';
3
3
  import { EventEmitter, OnInit, WritableSignal, InjectionToken, Provider, OnChanges, Type, SimpleChanges } from '@angular/core';
4
- import { ComponentDocMeta, ComponentMetadataRegistry, WidgetShellConfig, WidgetShellAction, EndpointRef, ComponentPortPathSegment, LinkIntent, CompositionLink, WidgetPageDefinition, TransformKind, SurfaceOpenPayload, SettingsValueProvider as SettingsValueProvider$1, WidgetPageGroupingDefinition, BUILTIN_PAGE_LAYOUT_PRESETS, BUILTIN_PAGE_THEME_PRESETS, PageIdentity, WidgetStateNode, WidgetDerivedStateNode, AiCapability, AiCapabilityCategory, AiCapabilityCatalog, AiValueKind, DomainKnowledgeChangeSetRequest, DomainKnowledgeChangeSet, DomainKnowledgeChangeSetTimelineResponse, DomainKnowledgeChangeSetFilters, DomainKnowledgeValidationResponse, DomainKnowledgeStatusTransitionRequest, DomainRuleIntakeRequest, DomainRuleIntakeResponse, DomainRuleDefinitionRequest, DomainRuleDefinition, DomainRuleSimulationRequest, DomainRuleSimulationResponse, DomainRuleStatusTransitionRequest, DomainRulePublicationRequest, DomainRulePublicationResponse, DomainRuleMaterializationFilters, DomainRuleMaterialization, DomainRuleTimelineResponse, WidgetPageCanvasLayout, WidgetPageStateInput, WidgetInstance, ComponentContextPack, ComponentAuthoringManifest, DynamicWidgetPageComponent, SettingsPanelBridge, WidgetEventEnvelope, RichTimelineItem } from '@praxisui/core';
4
+ import { ComponentDocMeta, ComponentMetadataRegistry, WidgetShellConfig, WidgetShellAction, EndpointRef, ComponentPortPathSegment, LinkIntent, CompositionLink, WidgetPageDefinition, TransformKind, SurfaceOpenPayload, SettingsValueProvider as SettingsValueProvider$1, WidgetPageGroupingDefinition, BUILTIN_PAGE_LAYOUT_PRESETS, BUILTIN_PAGE_THEME_PRESETS, PageIdentity, WidgetStateNode, WidgetDerivedStateNode, AiCapability, AiCapabilityCategory, AiCapabilityCatalog, AiValueKind, DomainKnowledgeChangeSetRequest, DomainKnowledgeChangeSet, DomainKnowledgeChangeSetTimelineResponse, DomainKnowledgeChangeSetFilters, DomainKnowledgeValidationResponse, DomainKnowledgeStatusTransitionRequest, DomainRuleIntakeRequest, DomainRuleIntakeResponse, DomainRuleDefinitionRequest, DomainRuleDefinition, DomainRuleSimulationRequest, DomainRuleSimulationResponse, DomainRuleStatusTransitionRequest, DomainRulePublicationRequest, DomainRulePublicationResponse, DomainRuleMaterializationFilters, DomainRuleMaterialization, DomainRuleTimelineResponse, WidgetPageCanvasLayout, WidgetPageDeviceLayouts, WidgetPageSlotAssignments, WidgetPageStateInput, WidgetInstance, ComponentContextPack, ComponentAuthoringManifest, DynamicWidgetPageComponent, SettingsPanelBridge, WidgetEventEnvelope, RichTimelineItem } from '@praxisui/core';
5
5
  export { WidgetShellComponent } from '@praxisui/core';
6
6
  import * as rxjs from 'rxjs';
7
7
  import { BehaviorSubject, Observable } from 'rxjs';
@@ -1164,6 +1164,7 @@ interface PageBuilderAgenticAuthoringOptions {
1164
1164
  requestTimeoutMs?: number;
1165
1165
  streamStartTimeoutMs?: number;
1166
1166
  streamTurnTimeoutMs?: number;
1167
+ streamResultFallbackMs?: number;
1167
1168
  streamConnectionErrorGraceMs?: number;
1168
1169
  }
1169
1170
  interface PageBuilderAgenticAuthoringEventSource {
@@ -1395,6 +1396,7 @@ declare class PageBuilderAgenticAuthoringService {
1395
1396
  private findSseFrameBoundary;
1396
1397
  private streamStartTimeoutMs;
1397
1398
  private streamTurnTimeoutMs;
1399
+ private streamResultFallbackMs;
1398
1400
  private requestTimeoutMs;
1399
1401
  private streamConnectionError;
1400
1402
  private buildStreamUrl;
@@ -1475,8 +1477,13 @@ interface UiCompositionPlan {
1475
1477
  version: '1.0';
1476
1478
  kind: 'praxis.ui-composition-plan';
1477
1479
  layoutPreset?: string;
1480
+ layoutPresetOptions?: Record<string, unknown>;
1478
1481
  canvas?: WidgetPageCanvasLayout;
1482
+ deviceLayouts?: WidgetPageDeviceLayouts;
1483
+ grouping?: WidgetPageGroupingDefinition[];
1484
+ slotAssignments?: WidgetPageSlotAssignments;
1479
1485
  state?: WidgetPageStateInput;
1486
+ themePreset?: string;
1480
1487
  widgets: UiCompositionPlanWidget[];
1481
1488
  bindings?: UiCompositionPlanBinding[];
1482
1489
  }