@salsita-ai/sdk 0.50.0-develop.6d8967bc99 → 0.50.0-develop.71209819cd

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.
Files changed (410) hide show
  1. package/README.md +1 -1
  2. package/dist/admin/create-admin-pages-from-spec.d.ts +1 -1
  3. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-domain-block.js +36 -36
  4. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-invariants.d.ts +1 -1
  5. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-invariants.js +1 -1
  6. package/dist/application-spec/generate-application/code/templates/env-example.js +4 -0
  7. package/dist/application-spec/generate-application/code/templates/skills/phoenix-create-configurator-skill.js +66 -42
  8. package/dist/application-spec/generate-application/code/templates/skills/sdk-content.d.ts +4 -4
  9. package/dist/application-spec/generate-application/code/templates/skills/sdk-content.js +4 -4
  10. package/dist/application-spec/generate-application/code/templates/webhook-builders.js +4 -3
  11. package/dist/application-spec/generate-application/code/templates/webhooks-config.js +2 -2
  12. package/dist/application-spec/parse-application-files/raw-spec/raw-assistant.js +1 -1
  13. package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-schema.js +1 -1
  14. package/dist/client/authorized-client.d.ts +3 -1
  15. package/dist/client/authorized-client.js +1 -1
  16. package/dist/client/contract.d.ts +34 -0
  17. package/dist/client/contract.js +1 -1
  18. package/dist/client/index.d.ts +2 -2
  19. package/dist/client/index.js +1 -1
  20. package/dist/client/local-authorized-client.d.ts +3 -1
  21. package/dist/client/local-authorized-client.js +1 -1
  22. package/dist/client/memory-authorized-client.d.ts +3 -1
  23. package/dist/client/memory-authorized-client.js +1 -1
  24. package/dist/client/phoenix-api.d.ts +215 -2
  25. package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.d.ts +89 -2
  26. package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.js +1 -1
  27. package/dist/configurator/application-runtime/extensions/systems/graphql-system/entity-meta.js +1 -1
  28. package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.js +1 -1
  29. package/dist/configurator/application-runtime/extensions/systems/index.d.ts +1 -1
  30. package/dist/configurator/ui/assistant/AssistantComposer.d.ts +2 -1
  31. package/dist/configurator/ui/assistant/AssistantComposer.js +1 -1
  32. package/dist/configurator/ui/assistant/AssistantThread.d.ts +6 -2
  33. package/dist/configurator/ui/assistant/AssistantThread.js +1 -1
  34. package/dist/configurator/ui/assistant/thread-items.d.ts +13 -2
  35. package/dist/configurator/ui/assistant/thread-items.js +1 -1
  36. package/dist/docs/index.json +1 -1
  37. package/dist/docs/phoenix/deployments.mdx +1 -1
  38. package/dist/docs/phoenix/expression-context.mdx +11 -3
  39. package/dist/docs/phoenix/phoenix-cli.mdx +24 -21
  40. package/dist/docs/phoenix/sdk-builder-workflow.mdx +6 -6
  41. package/dist/docs/ux-guidelines/choosing-a-control.mdx +11 -0
  42. package/dist/domain/admin-domain/implementation/common-admin-expressions.d.ts +10 -10
  43. package/dist/domain/admin-domain/index.d.ts +8 -3
  44. package/dist/domain/admin-domain/index.js +1 -1
  45. package/dist/domain/application/admin-page-factories.d.ts +1 -2
  46. package/dist/domain/application/application-config.d.ts +1 -21
  47. package/dist/domain/application/assistant/assistant-manifest.d.ts +2 -0
  48. package/dist/domain/application/assistant/assistant-value-type.js +1 -1
  49. package/dist/domain/application/assistant/build-assistant-manifest.js +1 -1
  50. package/dist/domain/application/assistant/generate-assistant-prompt.d.ts +1 -11
  51. package/dist/domain/application/assistant/generate-assistant-prompt.js +1 -1
  52. package/dist/domain/application/assistant-mutations.d.ts +2 -1
  53. package/dist/domain/application/assistant-mutations.js +1 -1
  54. package/dist/domain/application/index.d.ts +2 -2
  55. package/dist/domain/application/index.js +1 -1
  56. package/dist/domain/application/published-data/build-legend-data.d.ts +1 -1
  57. package/dist/domain/application/published-data/format-field-type.d.ts +1 -1
  58. package/dist/domain/application/published-data/map-data-to-sheet.d.ts +1 -1
  59. package/dist/domain/application/published-data/map-published-chunked-data.d.ts +2 -2
  60. package/dist/domain/application/published-data/validate-sheet-data.d.ts +1 -1
  61. package/dist/domain/available-system-components.js +1 -1
  62. package/dist/domain/core/action/action-factory.d.ts +11 -0
  63. package/dist/domain/core/{action.d.ts → action/action.d.ts} +21 -16
  64. package/dist/domain/core/action/index.d.ts +2 -0
  65. package/dist/domain/core/action/index.js +1 -0
  66. package/dist/domain/core/component/domain-component-optic.d.ts +34 -37
  67. package/dist/domain/core/component/domain-component-optic.js +2 -2
  68. package/dist/domain/core/component/system-component-filter.d.ts +17 -17
  69. package/dist/domain/core/data-schema/data-cell-value.d.ts +4 -0
  70. package/dist/domain/core/data-schema/data-schema-array-field.d.ts +5 -0
  71. package/dist/domain/core/data-schema/data-schema-field-object.d.ts +4 -0
  72. package/dist/domain/core/data-schema/data-schema-field-object.js +1 -0
  73. package/dist/domain/core/data-schema/data-schema-field.d.ts +2 -0
  74. package/dist/domain/core/data-schema/data-schema-field.js +1 -0
  75. package/dist/domain/core/data-schema/data-schema-localized-field.d.ts +4 -0
  76. package/dist/domain/core/data-schema/data-schema-localized-field.js +1 -0
  77. package/dist/domain/core/data-schema/data-schema-primitive-field.d.ts +5 -0
  78. package/dist/domain/core/data-schema/data-schema-primitive-field.js +1 -0
  79. package/dist/domain/core/data-schema/data-schema.d.ts +2 -0
  80. package/dist/domain/core/data-schema/data-schema.js +1 -0
  81. package/dist/domain/core/data-schema/index.d.ts +7 -0
  82. package/dist/domain/core/data-schema/index.js +1 -0
  83. package/dist/domain/core/domain-factory.d.ts +1 -1
  84. package/dist/domain/core/domain.d.ts +2 -2
  85. package/dist/domain/core/emission/index.d.ts +8 -0
  86. package/dist/domain/core/emission/index.js +1 -0
  87. package/dist/domain/core/emission/reset-state-emission.d.ts +12 -0
  88. package/dist/domain/core/emission/reset-state-emission.js +1 -0
  89. package/dist/domain/core/emission/state-emission.d.ts +4 -0
  90. package/dist/domain/core/emission/state-emission.js +1 -0
  91. package/dist/domain/core/emission/state-update-emission.d.ts +14 -0
  92. package/dist/domain/core/emission/state-update-emission.js +1 -0
  93. package/dist/domain/core/emission/state-validation-result.d.ts +18 -0
  94. package/dist/domain/core/emission/state-validation-result.js +1 -0
  95. package/dist/domain/core/emission/transformation-log.d.ts +2 -0
  96. package/dist/domain/core/emission/transformation-log.js +1 -0
  97. package/dist/domain/core/emission/transformer-log-entry.d.ts +6 -0
  98. package/dist/domain/core/emission/transformer-log-entry.js +1 -0
  99. package/dist/domain/core/emission/transformer-log.d.ts +11 -0
  100. package/dist/domain/core/emission/transformer-log.js +1 -0
  101. package/dist/domain/core/emission/transformer-phase.d.ts +1 -0
  102. package/dist/domain/core/emission/transformer-phase.js +1 -0
  103. package/dist/domain/core/expression/aliased-expressions.d.ts +10 -0
  104. package/dist/domain/core/expression/aliased-expressions.js +1 -0
  105. package/dist/domain/core/expression/custom-expression.d.ts +7 -7
  106. package/dist/domain/core/expression/expression.d.ts +14 -15
  107. package/dist/domain/core/expression/index.d.ts +1 -2
  108. package/dist/domain/core/expression/index.js +1 -1
  109. package/dist/domain/core/index.d.ts +5 -1
  110. package/dist/domain/core/index.js +1 -1
  111. package/dist/domain/core/invariant/custom-invariants.d.ts +5 -5
  112. package/dist/domain/core/invariant/index.d.ts +1 -1
  113. package/dist/domain/core/invariant/index.js +1 -1
  114. package/dist/domain/core/invariant/invariants.d.ts +4 -67
  115. package/dist/domain/core/invariant/invariants.js +1 -1
  116. package/dist/domain/core/invariant/violation.d.ts +1 -1
  117. package/dist/domain/core/recipe/index.d.ts +1 -0
  118. package/dist/domain/core/recipe/index.js +1 -0
  119. package/dist/domain/{domain-context/recipe-system → core/recipe}/recipes.d.ts +1 -1
  120. package/dist/domain/core/recipe/recipes.js +1 -0
  121. package/dist/domain/{relations → core/relation}/all-of-type-relation.d.ts +3 -1
  122. package/dist/domain/core/relation/all-of-type-relation.js +1 -0
  123. package/dist/domain/{relations → core/relation}/component-factories.d.ts +1 -1
  124. package/dist/domain/core/relation/component-factories.js +1 -0
  125. package/dist/domain/{relations → core/relation}/composed-of.d.ts +1 -1
  126. package/dist/domain/core/relation/composed-of.js +1 -0
  127. package/dist/domain/{relations → core/relation}/direct-relation.d.ts +2 -1
  128. package/dist/domain/core/relation/index.d.ts +9 -0
  129. package/dist/domain/core/relation/index.js +1 -0
  130. package/dist/domain/{relations → core/relation}/indirect-relation.d.ts +3 -1
  131. package/dist/domain/core/relation/indirect-relation.js +1 -0
  132. package/dist/domain/{relations → core/relation}/reference-component.d.ts +4 -3
  133. package/dist/domain/core/relation/reference-component.js +1 -0
  134. package/dist/domain/{relations → core/relation}/reference-field.d.ts +1 -1
  135. package/dist/domain/core/relation/reference-field.js +1 -0
  136. package/dist/domain/{relations → core/relation}/relation-factory.d.ts +2 -1
  137. package/dist/domain/{relations → core/relation}/relation-implementation.d.ts +3 -1
  138. package/dist/domain/core/relation/relation-implementation.js +1 -0
  139. package/dist/domain/domain-builder.d.ts +2 -5
  140. package/dist/domain/domain-builder.js +1 -1
  141. package/dist/domain/domain-context/action-system/action-system.d.ts +2 -2
  142. package/dist/domain/domain-context/index.d.ts +1 -2
  143. package/dist/domain/domain-context/index.js +1 -1
  144. package/dist/domain/domain-context/recipe-system/recipe-cooker-system.d.ts +1 -2
  145. package/dist/domain/domain-context/recipe-system/recipe-cooker-system.js +1 -1
  146. package/dist/domain/domain-context/relation-transformers/cascade-ref-pruning.js +1 -1
  147. package/dist/domain/domain-context/relation-transformers/create-entity-refs.js +2 -2
  148. package/dist/domain/domain-context/relation-transformers/replace-refs.js +1 -1
  149. package/dist/domain/domain-context/store-system/store-system.d.ts +1 -32
  150. package/dist/domain/domain-context/transformers/context.d.ts +1 -2
  151. package/dist/domain/domain-context/undo-system.d.ts +1 -2
  152. package/dist/domain/domain-runtime/domain-context/action-context.d.ts +11 -0
  153. package/dist/domain/domain-runtime/domain-context/action-context.js +1 -0
  154. package/dist/domain/domain-runtime/domain-context/expression-context.d.ts +8 -0
  155. package/dist/domain/domain-runtime/domain-context/expression-context.js +1 -0
  156. package/dist/domain/domain-runtime/domain-context/index.d.ts +3 -0
  157. package/dist/domain/domain-runtime/domain-context/runtime-expression-context.d.ts +18 -0
  158. package/dist/domain/domain-runtime/domain-context/runtime-expression-context.js +1 -0
  159. package/dist/domain/domain-runtime/domain-context/selectors.d.ts +3 -2
  160. package/dist/domain/domain-runtime/domain-context/selectors.js +1 -1
  161. package/dist/domain/domain-runtime/domain-runtime.d.ts +8 -8
  162. package/dist/domain/domain-runtime/spec/index.d.ts +8 -0
  163. package/dist/domain/domain-runtime/spec/index.js +1 -1
  164. package/dist/domain/domain-runtime/spec/initialize.js +1 -1
  165. package/dist/domain/domain-runtime/spec/invariant-builder.d.ts +61 -0
  166. package/dist/domain/domain-runtime/spec/invariant-builder.js +1 -0
  167. package/dist/domain/{core/expression → domain-runtime/spec}/memoize-expression.d.ts +1 -2
  168. package/dist/domain/{actions → domain-runtime/spec}/prepare-action-implementations.d.ts +1 -1
  169. package/dist/domain/domain-runtime/spec/prepare-action-implementations.js +5 -0
  170. package/dist/domain/{core/expression → domain-runtime/spec}/prepare-domain-expressions.d.ts +1 -1
  171. package/dist/domain/domain-runtime/spec/resolve-action-modules.d.ts +4 -0
  172. package/dist/domain/domain-runtime/spec/resolve-action-modules.js +1 -0
  173. package/dist/domain/domain-runtime/spec/resolve-component-optic-modules.d.ts +4 -0
  174. package/dist/domain/domain-runtime/spec/resolve-component-optic-modules.js +1 -0
  175. package/dist/domain/domain-runtime/spec/resolve-expression-modules.d.ts +15 -0
  176. package/dist/domain/domain-runtime/spec/resolve-expression-modules.js +1 -0
  177. package/dist/domain/domain-runtime/spec/resolve-invariant-modules.d.ts +6 -0
  178. package/dist/domain/domain-runtime/spec/resolve-invariant-modules.js +1 -0
  179. package/dist/domain/{system-components → extensions}/child-entity-recipe-hierarchy.d.ts +1 -1
  180. package/dist/domain/extensions/child-entity-recipe-hierarchy.js +1 -0
  181. package/dist/domain/{system-components → extensions}/common/angle-indicator-schema.d.ts +1 -1
  182. package/dist/domain/extensions/common/angle-indicator-schema.js +1 -0
  183. package/dist/domain/extensions/common/index.d.ts +4 -0
  184. package/dist/domain/extensions/common/index.js +1 -0
  185. package/dist/domain/{system-components → extensions}/custom-header.d.ts +1 -1
  186. package/dist/domain/extensions/custom-header.js +1 -0
  187. package/dist/domain/{system-components → extensions}/custom-price-footer.js +1 -1
  188. package/dist/domain/{system-components → extensions}/custom-sidebar-footer.d.ts +1 -1
  189. package/dist/domain/extensions/custom-sidebar-footer.js +1 -0
  190. package/dist/domain/{system-components → extensions}/editable-angle-indicator.d.ts +2 -1
  191. package/dist/domain/extensions/editable-angle-indicator.js +1 -0
  192. package/dist/domain/{system-components → extensions}/editable-distance-dimension-indicator.d.ts +2 -1
  193. package/dist/domain/extensions/editable-distance-dimension-indicator.js +1 -0
  194. package/dist/domain/{system-components → extensions}/editable-offset-indicator.d.ts +2 -1
  195. package/dist/domain/extensions/editable-offset-indicator.js +1 -0
  196. package/dist/domain/{system-components → extensions}/editable-size-indicator.d.ts +2 -1
  197. package/dist/domain/extensions/editable-size-indicator.js +1 -0
  198. package/dist/domain/{system-components → extensions}/entity-header.d.ts +1 -1
  199. package/dist/domain/extensions/entity-header.js +1 -0
  200. package/dist/domain/{system-components → extensions}/finalize-component.js +1 -1
  201. package/dist/domain/extensions/index.d.ts +69 -0
  202. package/dist/domain/extensions/index.js +1 -0
  203. package/dist/domain/{system-components → extensions}/list-selector-dimension-indicator.d.ts +2 -1
  204. package/dist/domain/extensions/list-selector-dimension-indicator.js +1 -0
  205. package/dist/domain/{system-components → extensions}/property-page.d.ts +1 -1
  206. package/dist/domain/extensions/property-page.js +1 -0
  207. package/dist/domain/{system-components → extensions}/replace-entity-recipe-hierarchy.d.ts +1 -1
  208. package/dist/domain/extensions/replace-entity-recipe-hierarchy.js +1 -0
  209. package/dist/domain/{system-components → extensions}/scene-entity-add-fab.d.ts +1 -1
  210. package/dist/domain/extensions/scene-entity-add-fab.js +1 -0
  211. package/dist/domain/{system-components → extensions}/scene-entity-delete-fab.d.ts +1 -1
  212. package/dist/domain/extensions/scene-entity-delete-fab.js +1 -0
  213. package/dist/domain/{system-components → extensions}/scene-entity-html-hotspot.d.ts +1 -1
  214. package/dist/domain/extensions/scene-entity-html-hotspot.js +1 -0
  215. package/dist/domain/{system-components → extensions}/scene-entity-navigation-hotspot.d.ts +1 -1
  216. package/dist/domain/extensions/scene-entity-navigation-hotspot.js +1 -0
  217. package/dist/domain/{system-components → extensions}/scene-entity-object-html-hotspot.d.ts +1 -1
  218. package/dist/domain/extensions/scene-entity-object-html-hotspot.js +1 -0
  219. package/dist/domain/{system-components → extensions}/scene-entity-select-hotspot.d.ts +1 -1
  220. package/dist/domain/extensions/scene-entity-select-hotspot.js +1 -0
  221. package/dist/domain/{system-components → extensions}/sketching-edit.d.ts +1 -1
  222. package/dist/domain/extensions/sketching-edit.js +1 -0
  223. package/dist/domain/{system-components → extensions}/summary-component.js +1 -1
  224. package/dist/domain/{system-components → extensions}/tool-menu-fab.d.ts +1 -1
  225. package/dist/domain/extensions/tool-menu-fab.js +1 -0
  226. package/dist/domain/{system-components → extensions}/toolbar.d.ts +1 -1
  227. package/dist/domain/extensions/toolbar.js +1 -0
  228. package/dist/domain/index.d.ts +3 -8
  229. package/dist/domain/index.js +1 -1
  230. package/dist/domain/project-modules/index.d.ts +1 -1
  231. package/dist/domain/project-modules/index.js +1 -1
  232. package/dist/domain/project-modules/project-modules.d.ts +0 -16
  233. package/dist/domain/project-modules/project-modules.js +1 -1
  234. package/dist/domain/projections/composition-projections.js +1 -1
  235. package/dist/domain/projections/index.d.ts +1 -1
  236. package/dist/domain/projections/validation-projections.d.ts +1 -17
  237. package/dist/domain/system-components/child-entity-selection.d.ts +1 -2
  238. package/dist/domain/system-components/common/index.d.ts +0 -4
  239. package/dist/domain/system-components/common/index.js +1 -1
  240. package/dist/domain/system-components/common/recipes.d.ts +1 -2
  241. package/dist/domain/system-components/index.d.ts +0 -68
  242. package/dist/domain/system-components/index.js +1 -1
  243. package/dist/domain/system-components/phoenix-entity-elements/admin-data-table-sidebar.d.ts +1 -1
  244. package/dist/domain/system-components/phoenix-layout-elements/admin-connected-resource-page.d.ts +1 -1
  245. package/dist/domain/system-components/phoenix-layout-elements/admin-data-table-actions.d.ts +1 -1
  246. package/dist/domain/system-components/phoenix-layout-elements/admin-data-table-page.d.ts +1 -1
  247. package/dist/domain/utils/memo-eval.d.ts +2 -2
  248. package/dist/i18n/locales/cs/messages.js +1 -1
  249. package/dist/i18n/locales/da/messages.js +1 -1
  250. package/dist/i18n/locales/de/messages.js +1 -1
  251. package/dist/i18n/locales/de-AT/messages.js +1 -1
  252. package/dist/i18n/locales/en/messages.js +1 -1
  253. package/dist/i18n/locales/en-AU/messages.js +1 -1
  254. package/dist/i18n/locales/en-GB/messages.js +1 -1
  255. package/dist/i18n/locales/es/messages.js +1 -1
  256. package/dist/i18n/locales/fr/messages.js +1 -1
  257. package/dist/i18n/locales/hu/messages.js +1 -1
  258. package/dist/i18n/locales/it/messages.js +1 -1
  259. package/dist/i18n/locales/nl/messages.js +1 -1
  260. package/dist/i18n/locales/pl/messages.js +1 -1
  261. package/dist/i18n/locales/pt/messages.js +1 -1
  262. package/dist/i18n/locales/ro/messages.js +1 -1
  263. package/dist/i18n/locales/sk/messages.js +1 -1
  264. package/dist/i18n/locales/tr/messages.js +1 -1
  265. package/dist/legacy/domain-cli/gen/implementation.js +5 -5
  266. package/dist/legacy/domain-cli/gen/invariants.js +5 -3
  267. package/dist/legacy/domain-cli/utils/cache.d.ts +1 -1
  268. package/dist/legacy/domain-cli/utils/cache.js +1 -1
  269. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/env-example.d.ts +1 -1
  270. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/env-example.js +4 -0
  271. package/dist/ui-sdk/theme/types.d.ts +1 -1
  272. package/dist/webhook/builders/common.d.ts +5 -0
  273. package/dist/webhook/builders/webhook-builder.js +1 -1
  274. package/package.json +3 -3
  275. package/dist/domain/actions/action-factory.d.ts +0 -10
  276. package/dist/domain/actions/prepare-action-implementations.js +0 -5
  277. package/dist/domain/domain-context/recipe-system/recipes.js +0 -1
  278. package/dist/domain/relations/all-of-type-relation.js +0 -1
  279. package/dist/domain/relations/component-factories.js +0 -1
  280. package/dist/domain/relations/composed-of.js +0 -1
  281. package/dist/domain/relations/indirect-relation.js +0 -1
  282. package/dist/domain/relations/reference-component.js +0 -1
  283. package/dist/domain/system-components/child-entity-recipe-hierarchy.js +0 -1
  284. package/dist/domain/system-components/common/angle-indicator-schema.js +0 -1
  285. package/dist/domain/system-components/custom-header.js +0 -1
  286. package/dist/domain/system-components/custom-sidebar-footer.js +0 -1
  287. package/dist/domain/system-components/editable-angle-indicator.js +0 -1
  288. package/dist/domain/system-components/editable-distance-dimension-indicator.js +0 -1
  289. package/dist/domain/system-components/editable-offset-indicator.js +0 -1
  290. package/dist/domain/system-components/editable-size-indicator.js +0 -1
  291. package/dist/domain/system-components/entity-header.js +0 -1
  292. package/dist/domain/system-components/list-selector-dimension-indicator.js +0 -1
  293. package/dist/domain/system-components/property-page.js +0 -1
  294. package/dist/domain/system-components/replace-entity-recipe-hierarchy.js +0 -1
  295. package/dist/domain/system-components/scene-entity-add-fab.js +0 -1
  296. package/dist/domain/system-components/scene-entity-delete-fab.js +0 -1
  297. package/dist/domain/system-components/scene-entity-html-hotspot.js +0 -1
  298. package/dist/domain/system-components/scene-entity-navigation-hotspot.js +0 -1
  299. package/dist/domain/system-components/scene-entity-object-html-hotspot.js +0 -1
  300. package/dist/domain/system-components/scene-entity-select-hotspot.js +0 -1
  301. package/dist/domain/system-components/sketching-edit.js +0 -1
  302. package/dist/domain/system-components/tool-menu-fab.js +0 -1
  303. package/dist/domain/system-components/toolbar.js +0 -1
  304. /package/dist/domain/{actions → core/action}/action-factory.js +0 -0
  305. /package/dist/domain/core/{action.js → action/action.js} +0 -0
  306. /package/dist/domain/{relations/reference-field.js → core/data-schema/data-cell-value.js} +0 -0
  307. /package/dist/domain/{relations/relation-implementation.js → core/data-schema/data-schema-array-field.js} +0 -0
  308. /package/dist/domain/{relations → core/relation}/direct-relation.js +0 -0
  309. /package/dist/domain/{relations → core/relation}/relation-factory.js +0 -0
  310. /package/dist/domain/{core/expression → domain-runtime/spec}/memoize-expression.js +0 -0
  311. /package/dist/domain/{core/expression → domain-runtime/spec}/prepare-domain-expressions.js +0 -0
  312. /package/dist/domain/{system-components → extensions}/angle-indicator.d.ts +0 -0
  313. /package/dist/domain/{system-components → extensions}/angle-indicator.js +0 -0
  314. /package/dist/domain/{system-components → extensions}/attribute-switch.d.ts +0 -0
  315. /package/dist/domain/{system-components → extensions}/attribute-switch.js +0 -0
  316. /package/dist/domain/{system-components → extensions}/autorotate-camera-component.d.ts +0 -0
  317. /package/dist/domain/{system-components → extensions}/autorotate-camera-component.js +0 -0
  318. /package/dist/domain/{system-components → extensions}/basic-sidebar-footer.d.ts +0 -0
  319. /package/dist/domain/{system-components → extensions}/basic-sidebar-footer.js +0 -0
  320. /package/dist/domain/{system-components → extensions}/camera-based-hidden-entity-object.d.ts +0 -0
  321. /package/dist/domain/{system-components → extensions}/camera-based-hidden-entity-object.js +0 -0
  322. /package/dist/domain/{system-components → extensions}/camera-based-hidden-entity.d.ts +0 -0
  323. /package/dist/domain/{system-components → extensions}/camera-based-hidden-entity.js +0 -0
  324. /package/dist/domain/{system-components → extensions}/canvas-config.d.ts +0 -0
  325. /package/dist/domain/{system-components → extensions}/canvas-config.js +0 -0
  326. /package/dist/domain/{system-components → extensions}/canvas-custom-environment.d.ts +0 -0
  327. /package/dist/domain/{system-components → extensions}/canvas-custom-environment.js +0 -0
  328. /package/dist/domain/{system-components → extensions}/canvas-padding.d.ts +0 -0
  329. /package/dist/domain/{system-components → extensions}/canvas-padding.js +0 -0
  330. /package/dist/domain/{system-components → extensions}/canvas-preset-environment.d.ts +0 -0
  331. /package/dist/domain/{system-components → extensions}/canvas-preset-environment.js +0 -0
  332. /package/dist/domain/{system-components → extensions}/client-side-image.d.ts +0 -0
  333. /package/dist/domain/{system-components → extensions}/client-side-image.js +0 -0
  334. /package/dist/domain/{system-components → extensions}/color-value.d.ts +0 -0
  335. /package/dist/domain/{system-components → extensions}/color-value.js +0 -0
  336. /package/dist/domain/{system-components → extensions}/common/dimension-indicator-schema.d.ts +0 -0
  337. /package/dist/domain/{system-components → extensions}/common/dimension-indicator-schema.js +0 -0
  338. /package/dist/domain/{system-components → extensions}/common/dimension-indicators.d.ts +0 -0
  339. /package/dist/domain/{system-components → extensions}/common/dimension-indicators.js +0 -0
  340. /package/dist/domain/{system-components → extensions}/common/editable-indicator-button-variant.d.ts +0 -0
  341. /package/dist/domain/{system-components → extensions}/common/editable-indicator-button-variant.js +0 -0
  342. /package/dist/domain/{system-components → extensions}/custom-price-footer.d.ts +0 -0
  343. /package/dist/domain/{system-components → extensions}/dimension-indicator.d.ts +0 -0
  344. /package/dist/domain/{system-components → extensions}/dimension-indicator.js +0 -0
  345. /package/dist/domain/{system-components → extensions}/exit-tool-mode-fab.d.ts +0 -0
  346. /package/dist/domain/{system-components → extensions}/exit-tool-mode-fab.js +0 -0
  347. /package/dist/domain/{system-components → extensions}/finalize-action.d.ts +0 -0
  348. /package/dist/domain/{system-components → extensions}/finalize-action.js +0 -0
  349. /package/dist/domain/{system-components → extensions}/finalize-component.d.ts +0 -0
  350. /package/dist/domain/{system-components → extensions}/fit-selection-orthographic-camera-component.d.ts +0 -0
  351. /package/dist/domain/{system-components → extensions}/fit-selection-orthographic-camera-component.js +0 -0
  352. /package/dist/domain/{system-components → extensions}/fit-selection-perspective-camera-component.d.ts +0 -0
  353. /package/dist/domain/{system-components → extensions}/fit-selection-perspective-camera-component.js +0 -0
  354. /package/dist/domain/{system-components → extensions}/fixed-header.d.ts +0 -0
  355. /package/dist/domain/{system-components → extensions}/fixed-header.js +0 -0
  356. /package/dist/domain/{system-components → extensions}/floating-header.d.ts +0 -0
  357. /package/dist/domain/{system-components → extensions}/floating-header.js +0 -0
  358. /package/dist/domain/{system-components → extensions}/hidden-header.d.ts +0 -0
  359. /package/dist/domain/{system-components → extensions}/hidden-header.js +0 -0
  360. /package/dist/domain/{system-components → extensions}/hidden-sidebar-footer.d.ts +0 -0
  361. /package/dist/domain/{system-components → extensions}/hidden-sidebar-footer.js +0 -0
  362. /package/dist/domain/{system-components → extensions}/horizontal-tabs.d.ts +0 -0
  363. /package/dist/domain/{system-components → extensions}/horizontal-tabs.js +0 -0
  364. /package/dist/domain/{system-components → extensions}/multilingual-text-value.d.ts +0 -0
  365. /package/dist/domain/{system-components → extensions}/multilingual-text-value.js +0 -0
  366. /package/dist/domain/{system-components → extensions}/navigation-steps.d.ts +0 -0
  367. /package/dist/domain/{system-components → extensions}/navigation-steps.js +0 -0
  368. /package/dist/domain/{system-components → extensions}/offset-anchors.d.ts +0 -0
  369. /package/dist/domain/{system-components → extensions}/offset-anchors.js +0 -0
  370. /package/dist/domain/{system-components → extensions}/offset-indicator.d.ts +0 -0
  371. /package/dist/domain/{system-components → extensions}/offset-indicator.js +0 -0
  372. /package/dist/domain/{system-components → extensions}/offset.d.ts +0 -0
  373. /package/dist/domain/{system-components → extensions}/offset.js +0 -0
  374. /package/dist/domain/{system-components → extensions}/other-action.d.ts +0 -0
  375. /package/dist/domain/{system-components → extensions}/other-action.js +0 -0
  376. /package/dist/domain/{system-components → extensions}/read-sidebar-footer.d.ts +0 -0
  377. /package/dist/domain/{system-components → extensions}/read-sidebar-footer.js +0 -0
  378. /package/dist/domain/{system-components → extensions}/rotatable.d.ts +0 -0
  379. /package/dist/domain/{system-components → extensions}/rotatable.js +0 -0
  380. /package/dist/domain/{system-components → extensions}/rotation-handle.d.ts +0 -0
  381. /package/dist/domain/{system-components → extensions}/rotation-handle.js +0 -0
  382. /package/dist/domain/{system-components → extensions}/save-template-thumbnail.d.ts +0 -0
  383. /package/dist/domain/{system-components → extensions}/save-template-thumbnail.js +0 -0
  384. /package/dist/domain/{system-components → extensions}/scene-entity-animation.d.ts +0 -0
  385. /package/dist/domain/{system-components → extensions}/scene-entity-animation.js +0 -0
  386. /package/dist/domain/{system-components → extensions}/scene-entity-control.d.ts +0 -0
  387. /package/dist/domain/{system-components → extensions}/scene-entity-control.js +0 -0
  388. /package/dist/domain/{system-components → extensions}/scene-entity-floor-object.d.ts +0 -0
  389. /package/dist/domain/{system-components → extensions}/scene-entity-floor-object.js +0 -0
  390. /package/dist/domain/{system-components → extensions}/scene-entity-wall-object.d.ts +0 -0
  391. /package/dist/domain/{system-components → extensions}/scene-entity-wall-object.js +0 -0
  392. /package/dist/domain/{system-components → extensions}/selectable-component.d.ts +0 -0
  393. /package/dist/domain/{system-components → extensions}/selectable-component.js +0 -0
  394. /package/dist/domain/{system-components → extensions}/sidebar-tabs.d.ts +0 -0
  395. /package/dist/domain/{system-components → extensions}/sidebar-tabs.js +0 -0
  396. /package/dist/domain/{system-components → extensions}/simple-summary.d.ts +0 -0
  397. /package/dist/domain/{system-components → extensions}/simple-summary.js +0 -0
  398. /package/dist/domain/{system-components → extensions}/size.d.ts +0 -0
  399. /package/dist/domain/{system-components → extensions}/size.js +0 -0
  400. /package/dist/domain/{system-components → extensions}/sketching-draw.d.ts +0 -0
  401. /package/dist/domain/{system-components → extensions}/sketching-draw.js +0 -0
  402. /package/dist/domain/{system-components → extensions}/summary-component.d.ts +0 -0
  403. /package/dist/domain/{system-components → extensions}/text-value.d.ts +0 -0
  404. /package/dist/domain/{system-components → extensions}/text-value.js +0 -0
  405. /package/dist/domain/{system-components → extensions}/tool-controls.d.ts +0 -0
  406. /package/dist/domain/{system-components → extensions}/tool-controls.js +0 -0
  407. /package/dist/domain/{system-components → extensions}/universal-sidebar-footer.d.ts +0 -0
  408. /package/dist/domain/{system-components → extensions}/universal-sidebar-footer.js +0 -0
  409. /package/dist/domain/{system-components → extensions}/view-controls.d.ts +0 -0
  410. /package/dist/domain/{system-components → extensions}/view-controls.js +0 -0
@@ -1 +1 @@
1
- import{ChatClient as t,fetchServerSentEvents as e}from"@tanstack/ai-client";import{BehaviorSubject as i}from"rxjs";import{skip as s}from"rxjs/operators";import{isShallowEqual as a}from"@salsita-ai/common/utils";import{createBrowserDetailsClientTool as r}from"./browser-details.js";import{ChangeRecorder as n}from"./change-recorder.js";import{createApplyClientTool as o,createQueryClientTool as c}from"./graphql-tools.js";let l=Object.freeze({messages:Object.freeze([]),isLoading:!1,error:void 0,failedStatus:void 0,isContinuable:!0,isLoaded:!1}),h=Object.freeze({open:!1,hasUnreadReply:!1,isInputFocused:!1}),d=Object.freeze({}),g=Object.freeze({results:Object.freeze([]),committed:!1,sideEffects:Object.freeze([]),message:"Nothing was run, because the user closed the configurator while this reply was being written. Do not call any more tools in this reply and end it now. The tools work again as soon as the user writes the next message."}),u=t=>{if(t.getError())return!0;let e=t.getMessages().at(-1)?.parts.at(-1);return e?.type!=="tool-call"&&e?.type!=="tool-result"};export class AssistantSystem{_context;_tools;_chat=new i(l);_panel=new i(h);_activation=null;_current=null;_finishing=new Set;_recorder;_recording=null;constructor(t){this._context=t;let{configuratorExtensionSelectors:e,domainContextSelectors:i,domainServicesSelectors:s,specSelectors:a}=t;this._recorder=new n({maxEntities:30},{readers:{selectedEntityId:t=>i.getNavigationSystem().getActiveSelectionState(t),navigationState:t=>i.getNavigationSystem().getActiveNavigationState(t),viewState:t=>i.getNavigationSystem().getActiveViewState(t),toolState:t=>i.getNavigationSystem().getActiveToolState(t)},getExposedFields:()=>a.getAssistant()?.fields??d,resolveLocalizable:t=>s.getResolveLocalizable()(t)});let l={getGraphQLSystem:()=>e.getGraphQLSystem(),getStoreSystem:()=>i.getStoreSystem(),getActiveMode:()=>i.getActiveMode(),clearChanges:()=>this._recorder.clear(this._committedState())};this._tools=[r(),c(l),o(l)]}chat$=this._chat;panel$=this._panel;initialize=()=>{let{committed:t}=this._context.domainContextSelectors.getStoreSystem().stateSlices;this._recording??=t.pipe(s(1)).subscribe(this._recorder.record),this._recorder.reset(t.value.state),this._endChat(),this._patchPanel(h),this._activation&&this._startClient()};activate=()=>{this._endChat();let t={};return this._activation=t,this._startClient(),()=>{this._activation===t&&(this._activation=null,this._endChat())}};send=async t=>{let e=this._current;if(!e)return;let{client:i}=e;i.getIsLoading()||null===i.getResumeState()||i.stop();let s={changes:this._recorder.take(this._committedState())};try{await i.sendMessage({content:t,metadata:s})}catch(i){let t=i instanceof Error?i:Error(String(i));e.generation.active&&this._chat.next({...this._chat.value,error:t}),this._context.domainServicesSelectors.getLogger().error("The assistant message could not be sent",{},t)}};stop=async()=>{let t=this._current;if(!t)return;let e=t.client.getCurrentRunId();if(t.client.stop(),null!=e)try{let i=t.getConnection();await fetch(`${i.url}/runs/${encodeURIComponent(e)}/cancel`,{method:"POST",headers:await i.headers()})}catch(t){this._context.domainServicesSelectors.getLogger().warn("Could not cancel the assistant run on the server",{error:t})}};reloadThread=()=>{if(!this._activation)return;let t=this._retireChat();t?.client.stop(),t?.dispose(),this._recorder.reset(this._committedState()),this._startClient()};setOpen=t=>{this._patchPanel(t?{open:t,hasUnreadReply:!1}:{open:t,isInputFocused:!1})};setInputFocused=t=>{this._patchPanel({isInputFocused:t})};_committedState=()=>this._context.domainContextSelectors.getStoreSystem().stateSlices.committed.value.state;_patchPanel=t=>{let e={...this._panel.value,...t};a(e,this._panel.value)||this._panel.next(e)};_takeOverThread=t=>{for(let e of this._finishing)e.configurationId===t&&(e.client.stop(),e.dispose())};_startClient=()=>{let i={active:!0},s=this._context.getConfigurationId();this._takeOverThread(s);let r=this._context.getAuthorizedClient(),n=()=>r.getAssistantChatConnection(s),o=t=>{if(!i.active)return;let e={...this._chat.value,...t};a(e,this._chat.value)||this._chat.next(e)},c=async(t,e)=>{let i=await fetch(t,e).finally(()=>o({isLoaded:!0})),s=i.headers.get("x-assistant-thread-continuable");return o({failedStatus:i.ok?void 0:i.status,...null!=s&&{isContinuable:"false"!==s}}),i},l=async()=>({headers:await n().headers(),fetchClient:c}),h=e(()=>n().url,l),d=e(()=>`${n().url}/runs`,l),_=this._tools.map(t=>({...t,execute:(e,s)=>i.active?t.execute?.(e,s):g})),m=new t({threadId:`assistant:${s}`,connection:{...h,joinRun:d.joinRun},persistence:!0,history:{pageSize:50},tools:_,onMessagesChange:t=>o({messages:t}),onLoadingChange:t=>{let e=i.active&&this._chat.value.isLoading;o({isLoading:t}),!t&&u(m)&&(i.active?e&&!this._panel.value.open&&this._patchPanel({hasUnreadReply:!0}):v())},onErrorChange:t=>{i.active&&t!==this._chat.value.error&&(o({error:t}),t&&this._context.domainServicesSelectors.getLogger().error("The assistant request failed",{status:this._chat.value.failedStatus},t))}}),p=!1,v=()=>{p||(p=!0,this._finishing.delete(S),m.dispose())},S={client:m,configurationId:s,generation:i,getConnection:n,dispose:v};this._current=S,m.attach()};_retireChat=()=>{let t=this._current;return this._current=null,t&&(t.generation.active=!1),this._chat.value!==l&&this._chat.next(l),t};_endChat=()=>{let t=this._retireChat();if(t){if(!t.client.getIsLoading()&&u(t.client))return void t.dispose();this._finishing.add(t)}}}
1
+ import{ChatClient as e,fetchServerSentEvents as t}from"@tanstack/ai-client";import{BehaviorSubject as i}from"rxjs";import{skip as s}from"rxjs/operators";import{isShallowEqual as a}from"@salsita-ai/common/utils";import{AssistantRequestError as r}from"#package/client";import{createBrowserDetailsClientTool as n}from"./browser-details.js";import{ChangeRecorder as h}from"./change-recorder.js";import{createApplyClientTool as o,createQueryClientTool as l}from"./graphql-tools.js";let c=Object.freeze({messages:Object.freeze([]),isLoading:!1,error:void 0,failedStatus:void 0,isContinuable:!0,isLoaded:!1,isResuming:!1,earlierThreads:Object.freeze([]),hasEarlierThread:!1,isLoadingEarlierThread:!1}),d=Object.freeze({open:!1,hasUnreadReply:!1,isInputFocused:!1}),u=Object.freeze({}),_=Object.freeze({results:Object.freeze([]),committed:!1,sideEffects:Object.freeze([]),message:"Nothing was run, because the user closed the configurator while this reply was being written. Do not call any more tools in this reply and end it now. The tools work again as soon as the user writes the next message."}),g=e=>{if(e.getError())return!0;let t=e.getMessages().at(-1)?.parts.at(-1);return t?.type!=="tool-call"&&t?.type!=="tool-result"};export class AssistantSystem{_context;_tools;_chat=new i(c);_panel=new i(d);_activation=null;_current=null;_finishing=new Set;_olderThreadId=null;_resuming=null;_refused=null;_firstAttempt=null;_chain={};_loadingThreadId=null;_recorder;_recording=null;constructor(e){this._context=e;let{configuratorExtensionSelectors:t,domainContextSelectors:i,domainServicesSelectors:s,specSelectors:a}=e;this._recorder=new h({maxEntities:30},{readers:{selectedEntityId:e=>i.getNavigationSystem().getActiveSelectionState(e),navigationState:e=>i.getNavigationSystem().getActiveNavigationState(e),viewState:e=>i.getNavigationSystem().getActiveViewState(e),toolState:e=>i.getNavigationSystem().getActiveToolState(e)},getExposedFields:()=>a.getAssistant()?.fields??u,resolveLocalizable:e=>s.getResolveLocalizable()(e)});let r={getGraphQLSystem:()=>t.getGraphQLSystem(),getStoreSystem:()=>i.getStoreSystem(),getActiveMode:()=>i.getActiveMode(),clearChanges:()=>this._recorder.clear(this._committedState())};this._tools=[n(),l(r),o(r)]}chat$=this._chat;panel$=this._panel;initialize=()=>{let{committed:e}=this._context.domainContextSelectors.getStoreSystem().stateSlices;this._recording??=e.pipe(s(1)).subscribe(this._recorder.record),this._recorder.reset(e.value.state),this._endChat(),this._patchPanel(d),this._activation&&this._startClient()};activate=()=>{this._endChat();let e={};return this._activation=e,this._startClient(),()=>{this._activation===e&&(this._activation=null,this._endChat())}};send=async e=>{if(!this._chat.value.isContinuable&&!await this.resume())return;let t=this._current;if(!t)return;let i={changes:this._recorder.take(this._committedState())};this._firstAttempt=t;try{await this._sendOn(t,e,i);let s=this._findRefusedMessageIndex(t);if(-1===s)return;this._refused={chat:t,index:s}}finally{this._firstAttempt===t&&(this._firstAttempt=null)}if(!await this.resume())return;let s=this._current;s&&await this._sendOn(s,e,i)};resume=async()=>{let e=this._current;if(!e)return!1;if(this._chat.value.isContinuable)return!0;if(this._resuming)return this._resuming;let t=this._resume(e).finally(()=>{this._resuming===t&&(this._resuming=null)});return this._resuming=t,t};loadEarlierThread=async()=>{let e=this._current,t=this._olderThreadId;if(!e||null===t||this._loadingThreadId===t)return;let i=this._chain;this._loadingThreadId=t,this._chat.next({...this._chat.value,isLoadingEarlierThread:!0});try{let s=await e.authorizedClient.getAssistantEarlierThread(e.configurationId,t,50);if(this._chain!==i||this._olderThreadId!==t)return;this._olderThreadId=s.previousThreadId,this._chat.next({...this._chat.value,earlierThreads:[{threadId:t,messages:s.messages},...this._chat.value.earlierThreads],hasEarlierThread:null!==s.previousThreadId})}catch(e){this._context.domainServicesSelectors.getLogger().warn("Could not load the earlier assistant conversation",{error:e})}finally{this._chain===i&&this._loadingThreadId===t&&(this._loadingThreadId=null,this._chat.next({...this._chat.value,isLoadingEarlierThread:!1}))}};stop=async()=>{let e=this._current;if(!e)return;let t=e.client.getCurrentRunId();if(e.client.stop(),null!=t)try{let i=e.getConnection();await fetch(`${i.url}/runs/${encodeURIComponent(t)}/cancel`,{method:"POST",headers:await i.headers()})}catch(e){this._context.domainServicesSelectors.getLogger().warn("Could not cancel the assistant run on the server",{error:e})}};reloadThread=()=>{if(!this._activation)return;let e=this._retireChat();e?.client.stop(),e?.dispose(),this._recorder.reset(this._committedState()),this._startClient()};setOpen=e=>{this._patchPanel(e?{open:e,hasUnreadReply:!1}:{open:e,isInputFocused:!1})};setInputFocused=e=>{this._patchPanel({isInputFocused:e})};_findRefusedMessageIndex=e=>{var t;let i,{failedStatus:s,isContinuable:a}=this._chat.value;return this._firstAttempt===e&&e.generation.active&&409===s&&!a?(i=(t=e.client.getMessages()).map(e=>e.role).lastIndexOf("user"),t.slice(i+1).every(e=>0===e.parts.length)?i:-1):-1};_sendOn=async(e,t,i)=>{let{client:s}=e;s.getIsLoading()||null===s.getResumeState()||s.stop();try{await s.sendMessage({content:t,metadata:i})}catch(i){let t=i instanceof Error?i:Error(String(i));e.generation.active&&this._chat.next({...this._chat.value,error:t}),this._context.domainServicesSelectors.getLogger().error("The assistant message could not be sent",{},t)}};_resume=async e=>{this._chat.next({...this._chat.value,isResuming:!0,error:void 0,failedStatus:void 0});try{let{previousThreadId:t}=await e.authorizedClient.compactAssistantThread(e.configurationId);if(!e.generation.active)return!1;let{messages:i,earlierThreads:s,hasEarlierThread:a}=this._chat.value,r=this._refused?.chat===e?i.slice(0,this._refused.index):i;return e.generation.active=!1,this._current=null,e.client.stop(),e.dispose(),this._chat.next({...c,earlierThreads:[...s,{threadId:t,messages:r}],hasEarlierThread:a,isLoadingEarlierThread:null!==this._loadingThreadId}),this._startClient(),!0}catch(i){let t=i instanceof Error?i:Error(String(i));if(t instanceof r&&409===t.status)return e.generation.active&&this.reloadThread(),!1;return e.generation.active&&this._chat.next({...this._chat.value,isResuming:!1,error:t,failedStatus:t instanceof r?t.status:void 0}),this._context.domainServicesSelectors.getLogger().error("The assistant thread could not be resumed",{},t),!1}};_committedState=()=>this._context.domainContextSelectors.getStoreSystem().stateSlices.committed.value.state;_patchPanel=e=>{let t={...this._panel.value,...e};a(t,this._panel.value)||this._panel.next(t)};_takeOverThread=e=>{for(let t of this._finishing)t.configurationId===e&&(t.client.stop(),t.dispose())};_startClient=()=>{let i={active:!0},s=this._context.getConfigurationId();this._takeOverThread(s);let r=this._context.getAuthorizedClient(),n=()=>r.getAssistantChatConnection(s),h=e=>{if(!i.active)return;let t={...this._chat.value,...e};a(t,this._chat.value)||this._chat.next(t)},o=async(e,t)=>{let s=await fetch(e,t).finally(()=>h({isLoaded:!0})),a=s.headers.get("x-assistant-thread-continuable");return null!=a&&s.ok&&i.active&&0===this._chat.value.earlierThreads.length&&(this._olderThreadId=s.headers.get("x-assistant-previous-thread")),h({failedStatus:s.ok?void 0:s.status,...null!=a&&{isContinuable:"false"!==a,hasEarlierThread:null!==this._olderThreadId}}),s},l=async()=>({headers:await n().headers(),fetchClient:o}),c=t(()=>n().url,l),d=t(()=>`${n().url}/runs`,l),u=this._tools.map(e=>({...e,execute:(t,s)=>i.active?e.execute?.(t,s):_})),m=new e({threadId:`assistant:${s}`,connection:{...c,joinRun:d.joinRun},persistence:!0,history:{pageSize:50},tools:u,onMessagesChange:e=>h({messages:e}),onLoadingChange:e=>{let t=i.active&&this._chat.value.isLoading;h({isLoading:e}),!e&&g(m)&&(i.active?t&&!this._panel.value.open&&this._patchPanel({hasUnreadReply:!0}):v())},onErrorChange:e=>{i.active&&e!==this._chat.value.error&&(!e||-1===this._findRefusedMessageIndex(p))&&(h({error:e}),e&&this._context.domainServicesSelectors.getLogger().error("The assistant request failed",{status:this._chat.value.failedStatus},e))}}),f=!1,v=()=>{f||(f=!0,this._finishing.delete(p),m.dispose())},p={client:m,configurationId:s,generation:i,authorizedClient:r,getConnection:n,dispose:v};this._current=p,m.attach()};_retireChat=()=>{let e=this._current;return this._current=null,e&&(e.generation.active=!1),this._chain={},this._olderThreadId=null,this._resuming=null,this._refused=null,this._loadingThreadId=null,this._chat.value!==c&&this._chat.next(c),e};_endChat=()=>{let e=this._retireChat();if(e){if(!e.client.getIsLoading()&&g(e.client))return void e.dispose();this._finishing.add(e)}}}
@@ -1 +1 @@
1
- import{findAssistantFieldOptions as e,findAssistantRecipeGroups as t,modifyEntityUpdateTag as i,prepareAssistantRecipeUpdates as r,readAssistantFieldOptions as n,readAssistantRecipeGroup as s,systemUpdateFactory as a}from"#package/domain";import{readSideEffects as o}from"./side-effects.js";let d=e=>({ok:!1,root:null,changedEntities:[],deletedEntityIds:[],sideEffects:[],errors:e}),l=(e,{state:t},{recipes:i,prepareStateEmission:r,find$Entity:n})=>{let{validity:s,state:a,updates:l}=r(e,t,"committed");if(s.valid){let e=new Map(t.entities.map(e=>[e.id,e])),r=new Set(a.entities.map(e=>e.id));return{ok:!0,root:n(a.rootEntityId,a),changedEntities:a.entities.filter(t=>e.get(t.id)!==t).flatMap(e=>n(e.id,a)??[]),deletedEntityIds:t.entities.map(e=>e.id).filter(e=>!r.has(e)),sideEffects:o(l,i.resolveLocalizable),errors:[]}}return d("uncaught"===s.severity?[{type:"uncaught",entityId:null,message:s.error.message}]:s.entityViolations.filter(({violation:e})=>e.severity===s.severity).map(({entityId:e,violation:t})=>({type:t.type,entityId:e,message:void 0===t.message?null:i.resolveLocalizable(t.message)})))};export const createEntityMeta=(o,c)=>{let p=e=>()=>t(c.manifest,e,o.entity.type).flatMap(t=>{let i=s(e,t,o.entity.id,o.state,c.recipes);return i?[((e,t,i)=>{let{group:n,label:s,description:a,recipes:o}=e,{resolveLocalizable:c}=i.recipes;return{groupId:n.groupId,name:void 0===s?n.instanceName:c(s),description:n.description??(void 0===a?null:c(a)),recipes:o.map(n=>((e,t,i,n)=>{let{key:s,item:a}=e,{resolveLocalizable:o}=n.recipes;return{key:s,name:o(a.title),description:void 0===a.description?null:o(a.description),imageUrl:void 0===a.thumbnailUrl?null:o(a.thumbnailUrl),dryRun:()=>t.group.dryRuns?((e,t,i,n)=>{let{updates:s,error:a}=((e,t,{entity:i,state:n},{recipes:s})=>{try{return{updates:r(e,t,i.id,n,s),error:void 0}}catch(e){if("child"===t.target.kind)throw e;return{updates:void 0,error:e instanceof Error?e.message:String(e)}}})(e,t,i,n);return void 0===s?d([{type:"uncaught",entityId:null,message:a}]):l(s,i,n)})(e,t,i,n):null}})(n,e,t,i))}})(i,o,c)]:[]});return{...Object.fromEntries(e(c.manifest,o.entity.type).map(e=>[e.edgeName,()=>n(e,o.entity.id,o.state,c.recipes)?.map(t=>({...t,dryRun:()=>e.dryRuns?(({field:e},{value:t},r,n)=>{let{entity:s}=r,o=Object.entries(Object.entries(n.manifest.writableFields??{}).find(([e])=>e===s.type)?.[1]??{}).find(([t])=>t===e)?.[1];if(void 0===o)throw Error(`The options of "${e}" on "${s.id}" cannot be dry-run: the schema lists them, but the configurator has no writable field "${e}" on ${s.type}. Regenerate the application so the schema matches the configurator.`);let c=r.state.entities.find(e=>e.id===s.id),p={[o]:t},u=c?n.validateEntity({...c,...p}):{success:!0};return u.success?l([a.DomainEntityModification({entityId:s.id,stateDelta:p,updateTag:i})],r,n):d([{type:"uncaught",entityId:s.id,message:`Writing ${JSON.stringify(t)} to "${e}" would make "${s.id}" an invalid ${s.type}: ${u.errors.join("; ")}.${e===o?"":` The message names the stored property: ${e} is stored as ${o}.`} The option comes from the configurator and cannot be corrected from here, so do not write it.`}])})(e,t,o,c):null}))??null])),childRecipes:p("child"),replaceRecipes:p("replace")}};
1
+ import{findAssistantFieldOptions as e,findAssistantRecipeGroups as t,modifyEntityUpdateTag as i,prepareAssistantRecipeUpdates as r,readAssistantFieldOptions as n,readAssistantRecipeGroup as o,systemUpdateFactory as s}from"#package/domain";import{readSideEffects as a}from"./side-effects.js";let d=e=>({ok:!1,root:null,changedEntities:[],deletedEntityIds:[],sideEffects:[],errors:e}),l=(e,{state:t},{recipes:i,prepareStateEmission:r,find$Entity:n})=>{let{validity:o,state:s,updates:l}=r(e,t,"committed");if(o.valid){let e=new Map(t.entities.map(e=>[e.id,e])),r=new Set(s.entities.map(e=>e.id));return{ok:!0,root:n(s.rootEntityId,s),changedEntities:s.entities.filter(t=>e.get(t.id)!==t).flatMap(e=>n(e.id,s)??[]),deletedEntityIds:t.entities.map(e=>e.id).filter(e=>!r.has(e)),sideEffects:a(l,i.resolveLocalizable),errors:[]}}return d("uncaught"===o.severity?[{type:"uncaught",entityId:null,message:o.error.message}]:o.entityViolations.filter(({violation:e})=>e.severity===o.severity).map(({entityId:e,violation:t})=>({type:t.type,entityId:e,message:void 0===t.message?null:i.resolveLocalizable(t.message)})))};export const createEntityMeta=(a,u)=>{let c=e=>()=>t(u.manifest,e,a.entity.type).flatMap(t=>{let i=o(e,t,a.entity.id,a.state,u.recipes);return i?[((e,t,i)=>{let{group:n,label:o,description:s,recipes:a}=e,{resolveLocalizable:u}=i.recipes;return{groupId:n.groupId,name:void 0===o?n.instanceName:u(o),description:n.description??(void 0===s?null:u(s)),recipes:a.map(n=>((e,t,i,n)=>{let{key:o,item:s}=e,{resolveLocalizable:a}=n.recipes;return{key:o,name:a(s.title),description:void 0===s.description?null:a(s.description),imageUrl:void 0===s.thumbnailUrl?null:a(s.thumbnailUrl),dryRun:()=>t.group.dryRuns?((e,t,i,n)=>{let{updates:o,error:s}=((e,t,{entity:i,state:n},{recipes:o})=>{try{return{updates:r(e,t,i.id,n,o),error:void 0}}catch(e){if("child"===t.target.kind)throw e;return{updates:void 0,error:e instanceof Error?e.message:String(e)}}})(e,t,i,n);return void 0===o?d([{type:"uncaught",entityId:null,message:s}]):l(o,i,n)})(e,t,i,n):null}})(n,e,t,i))}})(i,a,u)]:[]});return{...Object.fromEntries(e(u.manifest,a.entity.type).map(e=>[e.edgeName,()=>n(e,a.entity.id,a.state,u.recipes)?.map(t=>({...t,dryRun:()=>e.dryRuns?(({field:e},{value:t},r,n)=>{let{entity:o}=r,a=Object.entries(Object.entries(n.manifest.writableFields??{}).find(([e])=>e===o.type)?.[1]??{}).find(([t])=>t===e)?.[1];if(void 0===a)throw Error(`The options of "${e}" on "${o.id}" cannot be dry-run: the schema lists them, but the configurator has no writable field "${e}" on ${o.type}. This is a fault in the configurator, not in your request. Tell the user this is not available.`);let u=r.state.entities.find(e=>e.id===o.id);if(!u)throw Error(`The options of "${e}" on "${o.id}" cannot be dry-run: entity "${o.id}" does not exist. It may have been deleted by an earlier operation or field. Query the current entities and use an id they return.`);let c={[a]:t},p=n.validateEntity({...u,...c});return p.success?l([s.DomainEntityModification({entityId:o.id,stateDelta:c,updateTag:i})],r,n):d([{type:"uncaught",entityId:o.id,message:`Writing ${JSON.stringify(t)} to "${e}" would make "${o.id}" an invalid ${o.type}: ${p.errors.join("; ")}. The option comes from the configurator and cannot be corrected from here, so do not write it.`}])})(e,t,a,u):null}))??null])),childRecipes:c("child"),replaceRecipes:c("replace")}};
@@ -1 +1 @@
1
- import{GraphQLError as e,buildSchema as t,defaultFieldResolver as i,getNamedType as o,graphql as a,validateSchema as n}from"graphql";import{assertExistence as r,createSelector as s,isMessageDescriptor as l,isMultilingualString as c}from"@salsita-ai/common/utils";import{DomainEntityIdSchema as h,findAssistantMutation as d}from"#package/domain";import{createEntityMeta as m}from"./entity-meta.js";import{readSideEffects as p}from"./side-effects.js";let f={errors:[new e('No assistant manifest in the application spec. The GraphQL schema is generated from the "assistant" section. Add an "assistant" section to a spec file to expose a schema.')]},u={errors:[new e("The configuration is not loaded yet, so there is no state to query. Run the query again once the configurator has finished loading.")]},y=new RegExp(h.pattern),g=e=>"object"==typeof e&&null!==e&&"type"in e&&"string"==typeof e.type&&"id"in e&&"string"==typeof e.id,v=(e,t)=>"object"==typeof e&&null!==e?Reflect.get(e,t):void 0,S=e=>e instanceof Error?e.message:String(e),x=e=>/[.!?]$/.test(e)?e:`${e}.`,_=e=>"object"==typeof e&&null!==e&&Object.getPrototypeOf(e)===Object.prototype,w=(e,t)=>{let i=_(e)?e._raw:void 0;if(g(i))return i;if(!Array.isArray(e)&&!_(e))return e;if(t.has(e))throw Error("The value contains itself. Return ids or copies of the values instead of objects that reference each other.");let o=new Set([...t,e]);return Array.isArray(e)?e.map(e=>w(e,o)):Object.fromEntries(Object.entries(e).map(([e,t])=>[e,w(t,o)]))};export const localize=(e,t)=>Array.isArray(e)?e.map(e=>localize(e,t)):"string"==typeof e||l(e)||c(e)?t(e):e;let E=t=>new e(`The GraphQL schema generated from the "assistant" manifest is invalid: ${x(t)} Regenerate the application so the schema is rebuilt from the current spec.`),$=e=>(e.errors?.length??0)>0,b=t=>({errors:[new e(`Not run: operation ${t+1} failed, so the operations after it were skipped and no change of the list takes effect. Fix the failing operation and send the whole list again.`)]});export class GraphQLSystem{_context;_selectSchema=s([s.leaf(e=>e)],e=>{try{let i=t(e),o=n(i);return o.length>0?E(o.map(e=>e.message).join(" ")):i}catch(e){return E(S(e))}});_selectFieldResolver=s([s.leaf(e=>e)],t=>(a,n,r,s)=>{if(s.parentType===s.schema.getQueryType())return i(a,n,r,s);if(s.parentType===s.schema.getMutationType())return this._resolveMutation(s.fieldName,String(s.path.key),n,r);if(!g(a))return i(a,n,r,s);if("meta"===s.fieldName){let e;return m({entity:a,state:("object"==typeof(e=v(a,"_state"))&&null!==e&&"entities"in e&&"rootEntityId"in e?e:void 0)??r.state},{manifest:r.manifest,recipes:this._recipeContext(),prepareStateEmission:(e,t,i)=>this._context.domainContextSelectors.getStoreSystem().prepareStateEmission(e,t,i),find$Entity:(e,t)=>this._find$Entity(e,t),validateEntity:e=>this._context.domainContextSelectors.getDomain().validateEntity(e)})}let{source:l,localized:c}=t[s.parentType.name]?.[s.fieldName]??{source:s.fieldName},h=((t,i)=>{try{return v(t,i)}catch(o){throw new e(`Expression "${i}" failed on ${g(t)?t.id:"an entity"}: ${x(S(o))} The expression threw while the query read it; fix the expression or the configuration state it reads.`,{originalError:o instanceof Error?o:void 0})}})(a,l);return c?localize(h,this._context.domainServicesSelectors.getResolveLocalizable()):l.startsWith("$")&&"JSON"===o(s.returnType).name?((t,i,o)=>{try{return w(o,new Set)}catch(o){throw new e(`Expression "${i}" returned a value that is not plain serializable data on ${g(t)?t.id:"an entity"}: ${x(S(o))} A JSON field can only return data that serializes to JSON.`,{originalError:o instanceof Error?o:void 0})}})(a,l,h):h});constructor(e){this._context=e}_get$Entity=(e,t)=>this._context.domainContextSelectors.getDomain().get$Entity(e,t);_find$Entity=(e,t)=>this._context.domainContextSelectors.getDomain().getEntity(e,t)?this._get$Entity(e,t):null;_recipeContext=()=>({componentReader:this._context.domainContextSelectors.getComponentReader(),recipeCooker:this._context.domainContextSelectors.getRecipeCookerSystem(),resolveLocalizable:this._context.domainServicesSelectors.getResolveLocalizable()});_rootValue={root:(e,{state:t})=>this._get$Entity(t.rootEntityId,t),entities:({ids:t},{state:i})=>{if(null==t)return i.entities.map(e=>this._get$Entity(e.id,i));var o=i.rootEntityId;let a=t.filter(e=>!y.test(e));if(a.length>0)throw new e(`${a.map(e=>`"${e}"`).join(", ")} ${1===a.length?"is not an entity id":"are not entity ids"}. Entity ids have the form "<Type>-<number>", e.g. "${o}". Use ids as returned by the "id" field.`);return t.map(e=>y.test(e)?this._find$Entity(e,i):null)},selectedEntity:(e,{state:t})=>this._find$Entity(this._context.domainContextSelectors.getNavigationSystem().getActiveSelectionState(t),t),navigation:(e,{state:t})=>{let i=this._context.domainContextSelectors.getNavigationSystem();return{navigationState:i.getActiveNavigationState(t),viewState:i.getActiveViewState(t),toolState:i.getActiveToolState(t)}}};_resolveType=e=>g(e)?e.type:void 0;initialize=()=>{};_resolveMutation=(t,i,o,a)=>{if(void 0!==a.failedMutationField)throw new e(`Not run: the earlier field "${a.failedMutationField}" of this operation failed, so "${i}" was skipped and no change of the operation takes effect. Fix the failing field and send the operation again.`);try{return this._runMutation(t,o,a)}catch(e){throw a.failedMutationField=i,e}};_runMutation=(t,i,o)=>{let a=d(t,o.manifest);if(!a)throw new e(`The schema declares the mutation "${t}", but the configurator has no implementation for it. Regenerate the application so the schema matches the configurator.`);let n=o.state,r=a.implementation(i,n,{manifest:o.manifest,action:this._context.domainContextSelectors.getActionSystem().createContext(n),resolveLocalizable:this._context.domainServicesSelectors.getResolveLocalizable()});if(r.updates.length>0){let i=this._context.domainContextSelectors.getStoreSystem().prepareStateEmission(r.updates,n,"committed");if(!i.validity.valid)throw new e(`The changes of "${t}" were not applied, because the resulting configuration is invalid: ${(e=>{if("uncaught"===e.severity)return`validating it threw: ${x(S(e.error))}`;let t=[...new Set(e.entityViolations.filter(({violation:t})=>t.severity===e.severity).map(({entityId:e})=>e))];return`it has ${e.severity} violations on ${t.join(", ")}.`})(i.validity)} Change the request so the configuration stays valid.`);o.emissions.push(i),o.state=i.state}return r.readResult({previousState:n,state:o.state})};_setup=()=>{let t=this._context.specSelectors.getAssistant();if(!t)return{ready:!1,result:f};let i=this._selectSchema(t.sdl);return i instanceof e?{ready:!1,result:{errors:[i]}}:{ready:!0,assistant:t,schema:i,fieldResolver:this._selectFieldResolver(t.fields)}};prepare=async(e,t)=>{let i,o=this._setup();if(!o.ready)return t.map(()=>({result:o.result,emissions:[]}));let n={manifest:o.assistant,state:e,emissions:[],failedMutationField:void 0},r=[];for(let[e,s]of t.entries())if(void 0===i){let t=n.emissions.length;n.failedMutationField=void 0;let l=await a({schema:o.schema,source:s.document,rootValue:this._rootValue,contextValue:n,variableValues:s.variables,operationName:s.operationName,fieldResolver:o.fieldResolver,typeResolver:this._resolveType});r.push({result:l,emissions:n.emissions.slice(t)}),$(l)&&(i=e)}else r.push({result:b(i),emissions:[]});return r};readSideEffects=e=>{let t=this._context.domainServicesSelectors.getResolveLocalizable();return e.flatMap(({emissions:e})=>e.flatMap(e=>p(e.updates,t)))};_prepareAndCommit=async e=>{let t,i,o,a=this._context.domainContextSelectors.getStoreSystem(),n=await this.prepare(a.stateSlices.committed.value.state,e),s=n.map(({result:e})=>e),l=this.readSideEffects(n),c=n.flatMap(e=>e.emissions);return s.some($)||0===c.length?{results:s,sideEffects:l,outcome:"none"}:{results:s,sideEffects:l,outcome:a.commitPrepared((t=r(c[0]),i=r(c[c.length-1]),o=c.some(e=>void 0!==e.transformationLog),{kind:"committed",previousState:t.previousState,state:i.state,updates:c.flatMap(e=>e.updates),validity:i.validity,transformationLog:o?c.flatMap(e=>e.transformationLog??[]):void 0}))}};execute=async e=>{if(!this._context.domainContextSelectors.getStoreSystem().isInitialized)return{results:e.map(()=>u),committed:!1,sideEffects:[]};let t=await this._prepareAndCommit(e),{results:i,sideEffects:o,outcome:a}="conflict"===t.outcome?await this._prepareAndCommit(e):t;return"committed"===a?{results:i,committed:!0,sideEffects:o}:"held"===a?{results:i,committed:!1,message:"The changes were not committed yet: the application held them, usually to ask the user for approval. They may still be applied once the user approves, and the next turn shows whether they were. Do not send the operations again.",sideEffects:o}:"conflict"===a?{results:i,committed:!1,message:"The changes were not committed, because the configuration changed while they were being applied. The results describe a state that was discarded. Query the current configuration and send the operations again if they still make sense.",sideEffects:o}:{results:i,committed:!1,sideEffects:o}}}
1
+ import{GraphQLError as e,buildSchema as t,defaultFieldResolver as i,getNamedType as o,graphql as n,validateSchema as a}from"graphql";import{assertExistence as r,createSelector as s,isMessageDescriptor as l,isMultilingualString as c}from"@salsita-ai/common/utils";import{DomainEntityIdSchema as d,findAssistantMutation as h}from"#package/domain";import{createEntityMeta as u}from"./entity-meta.js";import{readSideEffects as m}from"./side-effects.js";let f={errors:[new e("The configurator does not provide this request. This is a fault in the configurator, not in your request. Tell the user this is not available.")]},p={errors:[new e("The configuration is not loaded yet, so there is no state to query. Run the query again once the configurator has finished loading.")]},y=new RegExp(d.pattern),g=e=>"object"==typeof e&&null!==e&&"type"in e&&"string"==typeof e.type&&"id"in e&&"string"==typeof e.id,v=(e,t)=>"object"==typeof e&&null!==e?Reflect.get(e,t):void 0,S=e=>e instanceof Error?e.message:String(e),_=e=>/[.!?]$/.test(e)?e:`${e}.`,x=e=>"object"==typeof e&&null!==e&&Object.getPrototypeOf(e)===Object.prototype,w=(e,t)=>{let i=x(e)?e._raw:void 0;if(g(i))return i;if(!Array.isArray(e)&&!x(e))return e;if(t.has(e))throw Error("The value contains itself.");let o=new Set([...t,e]);return Array.isArray(e)?e.map(e=>w(e,o)):Object.fromEntries(Object.entries(e).map(([e,t])=>[e,w(t,o)]))};export const localize=(e,t)=>Array.isArray(e)?e.map(e=>localize(e,t)):"string"==typeof e||l(e)||c(e)?t(e):e;let E=t=>new e(`The configurator cannot handle this request: ${_(t)} This is a fault in the configurator, not in your request. Tell the user this is not available.`),$=e=>(e.errors?.length??0)>0,b=t=>({errors:[new e(`Not run: operation ${t+1} failed, so the operations after it were skipped and no change of the list takes effect. Fix the failing operation and send the whole list again.`)]});export class GraphQLSystem{_context;_selectSchema=s([s.leaf(e=>e)],e=>{try{let i=t(e),o=a(i);return o.length>0?E(o.map(e=>e.message).join(" ")):i}catch(e){return E(S(e))}});_selectFieldResolver=s([s.leaf(e=>e)],t=>(n,a,r,s)=>{if(s.parentType===s.schema.getQueryType())return i(n,a,r,s);if(s.parentType===s.schema.getMutationType())return this._resolveMutation(s.fieldName,String(s.path.key),a,r);if(!g(n))return i(n,a,r,s);if("meta"===s.fieldName){let e;return u({entity:n,state:("object"==typeof(e=v(n,"_state"))&&null!==e&&"entities"in e&&"rootEntityId"in e?e:void 0)??r.state},{manifest:r.manifest,recipes:this._recipeContext(),prepareStateEmission:(e,t,i)=>this._context.domainContextSelectors.getStoreSystem().prepareStateEmission(e,t,i),find$Entity:(e,t)=>this._find$Entity(e,t),validateEntity:e=>this._context.domainContextSelectors.getDomain().validateEntity(e)})}let{source:l,localized:c}=t[s.parentType.name]?.[s.fieldName]??{source:s.fieldName},d=((t,i)=>{try{return v(t,i)}catch(o){throw new e(`Expression "${i}" failed on ${g(t)?t.id:"an entity"}: ${_(S(o))} This is a fault in the configurator, not in your request. Tell the user this is not available.`,{originalError:o instanceof Error?o:void 0})}})(n,l);return c?localize(d,this._context.domainServicesSelectors.getResolveLocalizable()):l.startsWith("$")&&"JSON"===o(s.returnType).name?((t,i,o)=>{try{return w(o,new Set)}catch(o){throw new e(`Expression "${i}" returned a value that is not plain serializable data on ${g(t)?t.id:"an entity"}: ${_(S(o))} This is a fault in the configurator, not in your request. Tell the user this is not available.`,{originalError:o instanceof Error?o:void 0})}})(n,l,d):d});constructor(e){this._context=e}_get$Entity=(e,t)=>this._context.domainContextSelectors.getDomain().get$Entity(e,t);_find$Entity=(e,t)=>this._context.domainContextSelectors.getDomain().getEntity(e,t)?this._get$Entity(e,t):null;_recipeContext=()=>({componentReader:this._context.domainContextSelectors.getComponentReader(),recipeCooker:this._context.domainContextSelectors.getRecipeCookerSystem(),resolveLocalizable:this._context.domainServicesSelectors.getResolveLocalizable()});_rootValue={root:(e,{state:t})=>this._get$Entity(t.rootEntityId,t),entities:({ids:t},{state:i})=>{if(null==t)return i.entities.map(e=>this._get$Entity(e.id,i));var o=i.rootEntityId;let n=t.filter(e=>!y.test(e));if(n.length>0)throw new e(`${n.map(e=>`"${e}"`).join(", ")} ${1===n.length?"is not an entity id":"are not entity ids"}. Entity ids have the form "<Type>-<number>", e.g. "${o}". Use ids as returned by the "id" field.`);return t.map(e=>y.test(e)?this._find$Entity(e,i):null)},selectedEntity:(e,{state:t})=>this._find$Entity(this._context.domainContextSelectors.getNavigationSystem().getActiveSelectionState(t),t),navigation:(e,{state:t})=>{let i=this._context.domainContextSelectors.getNavigationSystem();return{navigationState:i.getActiveNavigationState(t),viewState:i.getActiveViewState(t),toolState:i.getActiveToolState(t)}}};_resolveType=e=>g(e)?e.type:void 0;initialize=()=>{};_resolveMutation=(t,i,o,n)=>{if(void 0!==n.failedMutationField)throw new e(`Not run: the earlier field "${n.failedMutationField}" of this operation failed, so "${i}" was skipped and no change of the operation takes effect. Fix the failing field and send the operation again.`);try{return this._runMutation(t,o,n)}catch(e){throw n.failedMutationField=i,e}};_runMutation=(t,i,o)=>{let n=h(t,o.manifest);if(!n)throw new e(`The schema declares the mutation "${t}", but the configurator has no implementation for it. This is a fault in the configurator, not in your request. Tell the user this is not available.`);let a=o.state,r=n.implementation(i,a,{manifest:o.manifest,action:this._context.domainContextSelectors.getActionSystem().createContext(a),resolveLocalizable:this._context.domainServicesSelectors.getResolveLocalizable()});if(r.updates.length>0){let i=this._context.domainContextSelectors.getStoreSystem().prepareStateEmission(r.updates,a,"committed");if(!i.validity.valid)throw new e(`The changes of "${t}" were not applied, because the resulting configuration is invalid: ${(e=>{if("uncaught"===e.severity)return`validating it threw: ${_(S(e.error))}`;let t=[...new Set(e.entityViolations.filter(({violation:t})=>t.severity===e.severity).map(({entityId:e})=>e))];return`it has ${e.severity} violations on ${t.join(", ")}.`})(i.validity)} Change the request so the configuration stays valid.`);o.emissions.push(i),o.state=i.state}return r.readResult({previousState:a,state:o.state})};_setup=()=>{let t=this._context.specSelectors.getAssistant();if(!t)return{ready:!1,result:f};let i=this._selectSchema(t.sdl);return i instanceof e?{ready:!1,result:{errors:[i]}}:{ready:!0,assistant:t,schema:i,fieldResolver:this._selectFieldResolver(t.fields)}};prepare=async(e,t)=>{let i,o=this._setup();if(!o.ready)return t.map(()=>({result:o.result,emissions:[]}));let a={manifest:o.assistant,state:e,emissions:[],failedMutationField:void 0},r=[];for(let[e,s]of t.entries())if(void 0===i){let t=a.emissions.length;a.failedMutationField=void 0;let l=await n({schema:o.schema,source:s.document,rootValue:this._rootValue,contextValue:a,variableValues:s.variables,operationName:s.operationName,fieldResolver:o.fieldResolver,typeResolver:this._resolveType});r.push({result:l,emissions:a.emissions.slice(t)}),$(l)&&(i=e)}else r.push({result:b(i),emissions:[]});return r};readSideEffects=e=>{let t=this._context.domainServicesSelectors.getResolveLocalizable();return e.flatMap(({emissions:e})=>e.flatMap(e=>m(e.updates,t)))};_prepareAndCommit=async e=>{let t,i,o,n=this._context.domainContextSelectors.getStoreSystem(),a=await this.prepare(n.stateSlices.committed.value.state,e),s=a.map(({result:e})=>e),l=this.readSideEffects(a),c=a.flatMap(e=>e.emissions);return s.some($)||0===c.length?{results:s,sideEffects:l,outcome:"none"}:{results:s,sideEffects:l,outcome:n.commitPrepared((t=r(c[0]),i=r(c[c.length-1]),o=c.some(e=>void 0!==e.transformationLog),{kind:"committed",previousState:t.previousState,state:i.state,updates:c.flatMap(e=>e.updates),validity:i.validity,transformationLog:o?c.flatMap(e=>e.transformationLog??[]):void 0}))}};execute=async e=>{if(!this._context.domainContextSelectors.getStoreSystem().isInitialized)return{results:e.map(()=>p),committed:!1,sideEffects:[]};let t=await this._prepareAndCommit(e),{results:i,sideEffects:o,outcome:n}="conflict"===t.outcome?await this._prepareAndCommit(e):t;return"committed"===n?{results:i,committed:!0,sideEffects:o}:"held"===n?{results:i,committed:!1,message:"The changes wait for the user's approval and are not applied yet. Do not send them again; the next `[changes]` block lists them once approved.",sideEffects:o}:"conflict"===n?{results:i,committed:!1,message:"The changes were not committed, because the configuration changed while they were being applied. The results describe a state that was discarded. Query the current configuration and send the operations again if they still make sense.",sideEffects:o}:{results:i,committed:!1,sideEffects:o}}}
@@ -1,5 +1,5 @@
1
1
  export { AnimationSystem, type AnimationSystemContext } from './animation-system.js';
2
- export { type AssistantChatSnapshot, type AssistantClientTool, type AssistantPanelSnapshot, AssistantSystem, type AssistantSystemContext, } from './assistant-system/assistant-system.js';
2
+ export { type AssistantChatSnapshot, type AssistantEarlierThreadSnapshot, type AssistantClientTool, type AssistantPanelSnapshot, AssistantSystem, type AssistantSystemContext, } from './assistant-system/assistant-system.js';
3
3
  export { CameraControlSystem, CameraControlType } from './camera-control-system/camera-control-system.js';
4
4
  export { type AnyCameraSystem, CameraSystem, type CameraSystemContext } from './camera-control-system/camera-system.js';
5
5
  export { createCameraControls } from './camera-control-system/create-camera-controls.js';
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * The message input of the panel. Enter sends and Shift+Enter adds a line. While a reply runs the
3
3
  * send control is a Stop control and the input stays editable, so the next message can be written.
4
- * A thread this session may not continue disables the input and says why.
4
+ * A thread this session may not continue takes a message like any other: it is resumed first, with
5
+ * the input read-only meanwhile, and the message stays in the input when that fails.
5
6
  */
6
7
  export declare const AssistantComposer: () => import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- import{jsx as e,jsxs as a}from"react/jsx-runtime";import{Trans as i}from"@lingui/react";import{IconButton as o,InputBase as r,Tooltip as t,styled as n}from"@mui/material";import{useCallback as s,useRef as d,useState as l}from"react";import{useEagerObservableSelector as m,useLocalizable as c}from"#package/react-sdk";import{PhxIcon as p,useResponsive as u}from"#package/ui-sdk";import{useConfigurator as b}from"../../application-runtime/index.js";import{AssistantPanelName as g}from"./theme.js";let h={id:"sdk.assistant.composer.placeholder",message:"Ask or tell me what to change…"},k={id:"sdk.assistant.composer.send.label",message:"Send"},f={id:"sdk.assistant.composer.stop.label",message:"Stop"},x=n("form",{name:g,slot:"composer"})(({theme:{palette:e,spacing:a}})=>({borderBlockStart:`1px solid ${e.divider}`,display:"grid",gap:a(.75),paddingBlock:a(1.25),paddingInline:`var(--phx-sidebar-padding, ${a(2)})`})),y=n("div",{name:g,slot:"inputFrame"})(({theme:{palette:e,spacing:a}})=>({alignItems:"flex-end",border:`1px solid ${e.divider}`,borderRadius:12,display:"flex",gap:a(1),paddingBlock:a(.5),paddingInline:`${a(1.5)} ${a(.5)}`,"&:focus-within":{borderColor:e.primary.main},"&:has(textarea:disabled)":{background:e.action.disabledBackground}})),v=n(r,{name:g,slot:"input"})(({theme:{spacing:e,typography:a}})=>({...a.body2,flex:1,paddingBlock:e(.75)})),B=n(o,{name:g,slot:"sendButton"})(({theme:{palette:e}})=>({background:e.primary.main,borderRadius:8,color:e.primary.contrastText,"&:hover":{background:e.primary.dark},"&.Mui-disabled":{background:e.action.disabledBackground,color:e.action.disabled}})),C=n(o,{name:g,slot:"stopButton"})(({theme:{palette:e}})=>({background:e.text.primary,borderRadius:8,color:e.background.paper,"&:hover":{background:e.text.secondary}})),R=n("span")({background:"currentColor",blockSize:10,borderRadius:2,inlineSize:10,margin:5}),S=n("div",{name:g,slot:"hint"})(({theme:{palette:e,typography:a}})=>({...a.caption,color:e.text.secondary}));export const AssistantComposer=()=>{let{assistantSystem:o}=b(),[r,n]=l(""),g=d(null),{isDesktop:I}=u(),$=c(h),j=c(k),w=c(f),{isReplying:z,isContinuable:F}=m(o.chat$,e=>({isReplying:e.isLoading,isContinuable:e.isContinuable}),[]),A=r.trim(),D=F&&!z&&A.length>0,P=s(()=>{D&&(n(""),o.send(A),I||g.current?.blur())},[o,D,A,I]),T=s(e=>{e.preventDefault(),P()},[P]),E=s(e=>{"Enter"!==e.key||e.shiftKey||e.nativeEvent.isComposing||(e.preventDefault(),P())},[P]),K=s(()=>{o.stop()},[o]);return a(x,{onSubmit:T,children:[!F&&e(S,{role:"status",children:e(i,{id:"sdk.assistant.composer.notContinuable",message:"This conversation can be read here, but it can no longer be continued."})}),a(y,{children:[e(v,{multiline:!0,maxRows:6,placeholder:$,value:r,disabled:!F,inputRef:g,onChange:e=>n(e.target.value),onKeyDown:E,onFocus:()=>o.setInputFocused(!0),onBlur:()=>o.setInputFocused(!1),inputProps:{"aria-label":$}}),z?e(t,{title:w,placement:"top",children:e(C,{size:"small","aria-label":w,onClick:K,children:e(R,{})})}):e(t,{title:j,placement:"top",children:e("span",{children:e(B,{type:"submit",size:"small","aria-label":j,disabled:!D,children:e(p,{name:"PaperPlaneRightBold",fontSize:"small"})})})})]}),e(S,{children:e(i,{id:"sdk.assistant.composer.disclaimer",message:"AI can be wrong. Check the result."})})]})};
1
+ import{jsx as e,jsxs as a}from"react/jsx-runtime";import{Trans as r}from"@lingui/react";import{IconButton as i,InputBase as o,Tooltip as t,styled as n}from"@mui/material";import{useCallback as s,useRef as l,useState as d}from"react";import{useEagerObservableSelector as m,useLocalizable as p}from"#package/react-sdk";import{PhxIcon as c,useResponsive as u}from"#package/ui-sdk";import{useConfigurator as g}from"../../application-runtime/index.js";import{AssistantPanelName as h}from"./theme.js";let b={id:"sdk.assistant.composer.placeholder",message:"Ask or tell me what to change…"},k={id:"sdk.assistant.composer.send.label",message:"Send"},f={id:"sdk.assistant.composer.stop.label",message:"Stop"},y=n("form",{name:h,slot:"composer"})(({theme:{palette:e,spacing:a}})=>({borderBlockStart:`1px solid ${e.divider}`,display:"grid",gap:a(.75),paddingBlock:a(1.25),paddingInline:`var(--phx-sidebar-padding, ${a(2)})`})),x=n("div",{name:h,slot:"inputFrame"})(({theme:{palette:e,spacing:a}})=>({alignItems:"flex-end",border:`1px solid ${e.divider}`,borderRadius:12,display:"flex",gap:a(1),paddingBlock:a(.5),paddingInline:`${a(1.5)} ${a(.5)}`,"&:focus-within":{borderColor:e.primary.main}})),v=n(o,{name:h,slot:"input"})(({theme:{spacing:e,typography:a}})=>({...a.body2,flex:1,paddingBlock:e(.75)})),R=n(i,{name:h,slot:"sendButton"})(({theme:{palette:e}})=>({background:e.primary.main,borderRadius:8,color:e.primary.contrastText,"&:hover":{background:e.primary.dark},"&.Mui-disabled":{background:e.action.disabledBackground,color:e.action.disabled}})),B=n(i,{name:h,slot:"stopButton"})(({theme:{palette:e}})=>({background:e.text.primary,borderRadius:8,color:e.background.paper,"&:hover":{background:e.text.secondary}})),C=n("span")({background:"currentColor",blockSize:10,borderRadius:2,inlineSize:10,margin:5}),S=n("div",{name:h,slot:"hint"})(({theme:{palette:e,typography:a}})=>({...a.caption,color:e.text.secondary}));export const AssistantComposer=()=>{let{assistantSystem:i}=g(),[o,n]=d(""),h=l(null),{isDesktop:w}=u(),I=p(b),$=p(k),j=p(f),{isReplying:z,isResuming:F}=m(i.chat$,e=>({isReplying:e.isLoading,isResuming:e.isResuming}),[]),A=o.trim(),D=!z&&!F&&A.length>0,P=s(async()=>{!D||(w||h.current?.blur(),await i.resume()&&(n(""),i.send(A)))},[i,D,A,w]),E=s(e=>{e.preventDefault(),P()},[P]),K=s(e=>{"Enter"!==e.key||e.shiftKey||e.nativeEvent.isComposing||(e.preventDefault(),P())},[P]),T=s(()=>{i.stop()},[i]);return a(y,{onSubmit:E,children:[a(x,{children:[e(v,{multiline:!0,maxRows:6,placeholder:I,value:o,readOnly:F,inputRef:h,onChange:e=>n(e.target.value),onKeyDown:K,onFocus:()=>i.setInputFocused(!0),onBlur:()=>i.setInputFocused(!1),inputProps:{"aria-label":I}}),z?e(t,{title:j,placement:"top",children:e(B,{size:"small","aria-label":j,onClick:T,children:e(C,{})})}):e(t,{title:$,placement:"top",children:e("span",{children:e(R,{type:"submit",size:"small","aria-label":$,disabled:!D,children:e(c,{name:"PaperPlaneRightBold",fontSize:"small"})})})})]}),e(S,{children:e(r,{id:"sdk.assistant.composer.disclaimer",message:"AI can be wrong. Check the result."})})]})};
@@ -1,6 +1,10 @@
1
1
  /**
2
2
  * The conversation: user bubbles, assistant Markdown, tool chips, and what the panel
3
- * has to say itself, which is a greeting for an empty thread, a "Thinking…" line and a failure with
4
- * its way out. It follows a streaming reply until the user scrolls up.
3
+ * has to say itself, which is a line while the thread loads, a greeting for an empty thread, a
4
+ * "Thinking…" line and a failure with its way out. It follows a streaming reply until the user scrolls up.
5
+ *
6
+ * A conversation the assistant continued from a summary is painted whole: the threads that were
7
+ * closed come first, each ended by a separator, and the ones still on the server are loaded one at a
8
+ * time from a control above them.
5
9
  */
6
10
  export declare const AssistantThread: () => import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- import{jsx as e,jsxs as i}from"react/jsx-runtime";import{Trans as a}from"@lingui/react";import{Button as t,styled as s}from"@mui/material";import{useMemo as r}from"react";import{match as n}from"ts-pattern";import{useEagerObservableValue as o}from"#package/react-sdk";import{PhxIcon as l}from"#package/ui-sdk";import{useConfigurator as d}from"../../application-runtime/index.js";import{AssistantToolChips as m}from"./AssistantChips.js";import{AssistantMarkdown as p}from"./AssistantMarkdown.js";import{describeAssistantFailure as c}from"./assistant-failure.js";import{AssistantPanelName as h}from"./theme.js";import{buildThreadView as g}from"./thread-items.js";import{useFollowStream as u}from"./use-follow-stream.js";let f=s("div",{name:h,slot:"thread"})({display:"grid",position:"relative"}),k=s("div",{name:h,slot:"messages"})(({theme:{spacing:e,typography:i}})=>({...i.body2,display:"flex",flexDirection:"column",gap:e(1.5),overflowY:"auto",overscrollBehavior:"contain",paddingBlock:e(2),paddingInline:`var(--phx-sidebar-padding, ${e(2)})`,"& > :first-child":{marginBlockStart:"auto"}})),v=s("div",{name:h,slot:"userMessage"})(({theme:{palette:e,spacing:i}})=>({alignSelf:"flex-end",background:`hsl(from ${e.primary.main} h s l / 12%)`,borderRadius:"14px 14px 4px 14px",maxInlineSize:"85%",overflowWrap:"anywhere",paddingBlock:i(1),paddingInline:i(1.5),whiteSpace:"pre-wrap"})),w=s("div",{name:h,slot:"greeting"})({}),b=s("div",{name:h,slot:"status"})(({theme:{palette:e,typography:i}})=>({...i.caption,color:e.text.secondary})),x=s("div",{name:h,slot:"notice"})(({theme:{palette:e,shape:i,spacing:a}})=>({alignItems:"center",background:e.action.hover,borderRadius:i.borderRadius,display:"flex",flexWrap:"wrap",gap:a(1),justifyContent:"space-between",paddingBlock:a(1),paddingInline:a(1.5)})),y=s(t,{name:h,slot:"newReplyButton"})(({theme:{palette:e,spacing:i}})=>({background:e.text.primary,borderRadius:"calc(infinity * 1px)",color:e.background.paper,insetBlockEnd:i(1),insetInlineStart:"50%",position:"absolute",translate:"-50% 0","&:hover":{background:e.text.secondary}})),j=({item:i,isActive:a})=>n(i).with({kind:"user"},({text:i})=>e(v,{children:i})).with({kind:"text"},({markdown:i,isStreaming:a})=>e(p,{markdown:i,isStreaming:a})).with({kind:"tools"},({tools:i})=>e(m,{tools:i,isActive:a})).exhaustive();export const AssistantThread=()=>{let{assistantSystem:s}=d(),m=o(s.chat$),{messages:p,isLoading:h}=m,{items:v,isThinking:T}=r(()=>g(p,h),[p,h]),I=r(()=>v.filter(({kind:e})=>"user"===e).length,[v]),S=m.error?c(m.failedStatus):void 0,{scrollerRef:A,hasUnseenContent:B,handleScroll:R,scrollToEnd:C}=u(r(()=>({messages:p,isThinking:T,failure:S?.kind}),[p,T,S?.kind]),I);return i(f,{children:[i(k,{ref:A,onScroll:R,role:"log","aria-live":"polite",children:[m.isLoaded&&0===v.length&&!h&&!S&&e(w,{children:e(a,{id:"sdk.assistant.thread.greeting",message:"Hi. I can answer questions about this design and change it with you. Tell me what you need."})}),v.map(i=>e(j,{item:i,isActive:h&&i===v.at(-1)},i.id)),T&&e(b,{children:e(a,{id:"sdk.assistant.thread.thinking",message:"Thinking…"})}),S&&i(x,{role:"alert",children:[e("span",{children:n(S.kind).with("notAvailable",()=>e(a,{id:"sdk.assistant.failure.notAvailable",message:"The assistant is not available here."})).with("busy",()=>e(a,{id:"sdk.assistant.failure.busy",message:"The assistant is still working on an earlier message."})).with("unavailable",()=>e(a,{id:"sdk.assistant.failure.unavailable",message:"The assistant is unavailable right now."})).exhaustive()}),S.canRetry&&e(t,{size:"small",variant:"outlined",color:"inherit",onClick:s.reloadThread,children:e(a,{id:"sdk.assistant.failure.retry.label",message:"Try again"})})]})]}),B&&e(y,{size:"small",onClick:C,endIcon:e(l,{name:"CaretDown"}),children:e(a,{id:"sdk.assistant.thread.newReply.label",message:"New reply"})})]})};
1
+ import{jsx as e,jsxs as a}from"react/jsx-runtime";import{Trans as i}from"@lingui/react";import{Button as s,styled as t}from"@mui/material";import{useMemo as r}from"react";import{match as n}from"ts-pattern";import{useEagerObservableValue as o}from"#package/react-sdk";import{PhxIcon as l}from"#package/ui-sdk";import{useConfigurator as d}from"../../application-runtime/index.js";import{AssistantToolChips as m}from"./AssistantChips.js";import{AssistantMarkdown as h}from"./AssistantMarkdown.js";import{describeAssistantFailure as c}from"./assistant-failure.js";import{AssistantPanelName as p}from"./theme.js";import{buildEarlierThreadItems as g,buildThreadView as u}from"./thread-items.js";import{useFollowStream as k}from"./use-follow-stream.js";let f=t("div",{name:p,slot:"thread"})({display:"grid",position:"relative"}),v=t("div",{name:p,slot:"messages"})(({theme:{spacing:e,typography:a}})=>({...a.body2,display:"flex",flexDirection:"column",gap:e(1.5),overflowY:"auto",overscrollBehavior:"contain",paddingBlock:e(2),paddingInline:`var(--phx-sidebar-padding, ${e(2)})`,"& > :first-child":{marginBlockStart:"auto"}})),w=t("div",{name:p,slot:"userMessage"})(({theme:{palette:e,spacing:a}})=>({alignSelf:"flex-end",background:`hsl(from ${e.primary.main} h s l / 12%)`,borderRadius:"14px 14px 4px 14px",maxInlineSize:"85%",overflowWrap:"anywhere",paddingBlock:a(1),paddingInline:a(1.5),whiteSpace:"pre-wrap"})),b=t("div",{name:p,slot:"greeting"})({}),x=t("div",{name:p,slot:"status"})(({theme:{palette:e,typography:a}})=>({...a.caption,color:e.text.secondary})),y=t("div",{name:p,slot:"separator"})(({theme:{palette:e,spacing:a,typography:i}})=>({...i.caption,alignItems:"center",color:e.text.secondary,display:"flex",gap:a(1),"&::before, &::after":{borderBlockStart:`1px solid ${e.divider}`,content:'""',flex:1}})),T=t(s,{name:p,slot:"earlierButton"})({alignSelf:"center"}),S=t("div",{name:p,slot:"notice"})(({theme:{palette:e,shape:a,spacing:i}})=>({alignItems:"center",background:e.action.hover,borderRadius:a.borderRadius,display:"flex",flexWrap:"wrap",gap:i(1),justifyContent:"space-between",paddingBlock:i(1),paddingInline:i(1.5)})),j=t(s,{name:p,slot:"newReplyButton"})(({theme:{palette:e,spacing:a}})=>({background:e.text.primary,borderRadius:"calc(infinity * 1px)",color:e.background.paper,insetBlockEnd:a(1),insetInlineStart:"50%",position:"absolute",translate:"-50% 0","&:hover":{background:e.text.secondary}})),B=({item:a,isActive:s})=>n(a).with({kind:"user"},({text:a})=>e(w,{children:a})).with({kind:"text"},({markdown:a,isStreaming:i})=>e(h,{markdown:a,isStreaming:i})).with({kind:"tools"},({tools:a})=>e(m,{tools:a,isActive:s})).with({kind:"separator"},()=>e(y,{role:"separator",children:e(i,{id:"sdk.assistant.thread.earlierSummarized",message:"Earlier conversation summarized"})})).exhaustive();export const AssistantThread=()=>{let{assistantSystem:t}=d(),m=o(t.chat$),{messages:h,isLoading:p,isResuming:w,earlierThreads:y}=m,{items:I,isThinking:A}=r(()=>u(h,p),[h,p]),E=r(()=>g(y),[y]),R=r(()=>I.filter(({kind:e})=>"user"===e).length,[I]),L=m.error?c(m.failedStatus):void 0,{scrollerRef:z,hasUnseenContent:C,handleScroll:$,scrollToEnd:D}=k(r(()=>({messages:h,isThinking:A,isResuming:w,failure:L?.kind}),[h,A,w,L?.kind]),R),M=!m.isLoaded&&0===E.length&&!w&&!L;return a(f,{children:[a(v,{ref:z,onScroll:$,role:"log","aria-live":"polite",children:[m.isLoaded&&0===I.length&&0===E.length&&!p&&!w&&!L&&e(b,{children:e(i,{id:"sdk.assistant.thread.greeting",message:"Hi. I can answer questions about this design and change it with you. Tell me what you need."})}),M&&e(x,{children:e(i,{id:"sdk.assistant.thread.loading",message:"Loading the conversation…"})}),m.isLoadingEarlierThread&&e(x,{children:e(i,{id:"sdk.assistant.thread.loadingEarlier",message:"Loading the earlier conversation…"})}),m.hasEarlierThread&&!m.isLoadingEarlierThread&&e(T,{size:"small",color:"inherit",onClick:t.loadEarlierThread,children:e(i,{id:"sdk.assistant.thread.showEarlier.label",message:"Show earlier conversation"})}),E.map(a=>e(B,{item:a,isActive:!1},a.id)),I.map(a=>e(B,{item:a,isActive:p&&a===I.at(-1)},a.id)),w&&e(x,{children:e(i,{id:"sdk.assistant.thread.resuming",message:"Resuming the conversation…"})}),A&&e(x,{children:e(i,{id:"sdk.assistant.thread.thinking",message:"Thinking…"})}),L&&a(S,{role:"alert",children:[e("span",{children:n(L.kind).with("notAvailable",()=>e(i,{id:"sdk.assistant.failure.notAvailable",message:"The assistant is not available here."})).with("busy",()=>e(i,{id:"sdk.assistant.failure.busy",message:"The assistant is still working on an earlier message."})).with("unavailable",()=>e(i,{id:"sdk.assistant.failure.unavailable",message:"The assistant is unavailable right now."})).exhaustive()}),L.canRetry&&e(s,{size:"small",variant:"outlined",color:"inherit",onClick:t.reloadThread,children:e(i,{id:"sdk.assistant.failure.retry.label",message:"Try again"})})]})]}),C&&e(j,{size:"small",onClick:D,endIcon:e(l,{name:"CaretDown"}),children:e(i,{id:"sdk.assistant.thread.newReply.label",message:"New reply"})})]})};
@@ -1,4 +1,5 @@
1
1
  import type { UIMessage } from '@tanstack/ai-client';
2
+ import type { AssistantEarlierThreadSnapshot } from '../../application-runtime/index.js';
2
3
  import { type AssistantToolChip } from './tool-chip.js';
3
4
  /** A tool call of the thread, with what its chip shows and what a click on the chip logs. */
4
5
  export interface AssistantToolItem {
@@ -8,8 +9,9 @@ export interface AssistantToolItem {
8
9
  readonly result: unknown;
9
10
  }
10
11
  /**
11
- * One block of the thread, in reading order: a user bubble, a stretch of assistant Markdown, or a
12
- * row of chips for the tool calls that follow each other without text in between.
12
+ * One block of the thread, in reading order: a user bubble, a stretch of assistant Markdown, a row
13
+ * of chips for the tool calls that follow each other without text in between, or the line that
14
+ * ends a closed thread of the conversation.
13
15
  */
14
16
  export type AssistantThreadItem = {
15
17
  readonly kind: 'user';
@@ -24,6 +26,9 @@ export type AssistantThreadItem = {
24
26
  readonly kind: 'tools';
25
27
  readonly id: string;
26
28
  readonly tools: readonly AssistantToolItem[];
29
+ } | {
30
+ readonly kind: 'separator';
31
+ readonly id: string;
27
32
  };
28
33
  export interface AssistantThreadView {
29
34
  readonly items: readonly AssistantThreadItem[];
@@ -35,3 +40,9 @@ export interface AssistantThreadView {
35
40
  * results are not shown on their own but decide the state of the chip of their call.
36
41
  */
37
42
  export declare const buildThreadView: (messages: ReadonlyArray<UIMessage>, isReplying: boolean) => AssistantThreadView;
43
+ /**
44
+ * Lays the closed threads of the conversation out above the thread that continues them, oldest
45
+ * first, each ended by a separator: the assistant read on from a summary of it, not from the
46
+ * messages themselves.
47
+ */
48
+ export declare const buildEarlierThreadItems: (earlierThreads: ReadonlyArray<AssistantEarlierThreadSnapshot>) => readonly AssistantThreadItem[];
@@ -1 +1 @@
1
- import{describeToolCall as t}from"./tool-chip.js";let e=t=>{try{return JSON.parse(t)}catch{return t}},r=t=>t.map(t=>"text"===t.type?t.content:"").join("").trim();export const buildThreadView=(o,n)=>{let l=(t=>{let r=new Map;for(let o of t)for(let t of o.parts)"tool-result"===t.type&&r.set(t.toolCallId,{result:"string"==typeof t.content?e(t.content):t.content,error:"error"===t.state?t.error??"The tool call failed.":void 0});return r})(o),i=[],s=o.at(-1),a=t=>{let e=i.at(-1);e?.kind==="tools"?i[i.length-1]={...e,tools:[...e.tools,t]}:i.push({kind:"tools",id:t.id,tools:[t]})};for(let e of o){if("user"===e.role){let t=r(e.parts);t&&i.push({kind:"user",id:e.id,text:t});continue}let o=n&&e===s;e.parts.forEach((r,n)=>{let s=`${e.id}:${n}`;if("text"===r.type){if(r.content.trim()){let t=o&&n===e.parts.length-1;i.push({kind:"text",id:s,markdown:r.content,isStreaming:t})}return}if("tool-call"!==r.type)return;let p=l.get(r.id),d=r.input,u=r.output??p?.result;a({id:r.id,input:d,result:u,chip:t({name:r.name,input:d,result:u,error:p?.error,isReplyRunning:o})})})}let p=i.at(-1),d=s?.role==="assistant"&&(p?.kind==="text"&&p.isStreaming||p?.kind==="tools");return{items:i,isThinking:n&&!d}};
1
+ import{describeToolCall as t}from"./tool-chip.js";let e=t=>{try{return JSON.parse(t)}catch{return t}},r=t=>t.map(t=>"text"===t.type?t.content:"").join("").trim();export const buildThreadView=(o,i)=>{let l=(t=>{let r=new Map;for(let o of t)for(let t of o.parts)"tool-result"===t.type&&r.set(t.toolCallId,{result:"string"==typeof t.content?e(t.content):t.content,error:"error"===t.state?t.error??"The tool call failed.":void 0});return r})(o),n=[],a=o.at(-1),s=t=>{let e=n.at(-1);e?.kind==="tools"?n[n.length-1]={...e,tools:[...e.tools,t]}:n.push({kind:"tools",id:t.id,tools:[t]})};for(let e of o){if("user"===e.role){let t=r(e.parts);t&&n.push({kind:"user",id:e.id,text:t});continue}let o=i&&e===a;e.parts.forEach((r,i)=>{let a=`${e.id}:${i}`;if("text"===r.type){if(r.content.trim()){let t=o&&i===e.parts.length-1;n.push({kind:"text",id:a,markdown:r.content,isStreaming:t})}return}if("tool-call"!==r.type)return;let d=l.get(r.id),p=r.input,u=r.output??d?.result;s({id:r.id,input:p,result:u,chip:t({name:r.name,input:p,result:u,error:d?.error,isReplyRunning:o})})})}let d=n.at(-1),p=a?.role==="assistant"&&(d?.kind==="text"&&d.isStreaming||d?.kind==="tools");return{items:n,isThinking:i&&!p}};export const buildEarlierThreadItems=t=>t.flatMap(({threadId:t,messages:e})=>[...buildThreadView(e,!1).items.map(e=>({...e,id:`${t}:${e.id}`})),{kind:"separator",id:`${t}:separator`}]);
@@ -1,5 +1,5 @@
1
1
  {
2
- "generatedAt": "2026-10-13T07:24:40.854Z",
2
+ "generatedAt": "2026-10-13T16:11:48.414Z",
3
3
  "categories": [
4
4
  {
5
5
  "name": "Phoenix",
@@ -464,7 +464,7 @@ Error: Failed to upload to S3
464
464
 
465
465
  - Run `deployment:prepare` again to get fresh presigned URLs
466
466
  - Check that `.upload-links.json` exists and is readable
467
- - Use `--skipUpload` / `-su` flag to test without uploading assets
467
+ - Use `--skipUpload` / `--su` flag to test without uploading assets
468
468
 
469
469
  ### "Server URL is required"
470
470
 
@@ -35,15 +35,23 @@ interface ExpressionContext<
35
35
 
36
36
  // System services
37
37
  readonly domain: Domain // Access to domain model and other entities
38
- readonly componentReader: ComponentReader // Read component states across all entities
39
38
  readonly migrate: MigrateFunction // Data migration utilities
40
- readonly sketchingProjections: SketchingProjections // Sketching system projections
41
- readonly collisionProjections: CollisionProjections // Collision detection projections
39
+ readonly componentReader: ComponentReader // Read component states across all entities
40
+
41
+ // Projections
42
+ readonly positionProjections: PositionProjections // World matrices of scene entities
43
+ readonly sketchingProjections: SketchingProjections // Shapes and connections of a sketch
44
+ readonly collisionProjections: CollisionProjections // Collision meshes and collisions between entities
45
+ readonly constraintProjections: ConstraintProjections // Spatial constraints an entity violates
46
+ readonly snappingProjections: SnappingProjections // Snap points, edges, planes and matches
47
+ readonly projectedEntitiesProjections: ProjectedEntitiesProjections // Data of projected entities
42
48
  }
43
49
  ```
44
50
 
45
51
  The context includes data sources (session, published, frontend, backend), system services (domain access, component reader, projections), and application state (mode, role). Each part serves a different purpose in expression calculations.
46
52
 
53
+ The SDK declares the context in two parts. `CoreExpressionContext` holds the mode, the role, the data sources, `domain` and `migrate`. `RuntimeExpressionContext` holds the component reader and the projections. An editor hover or a type error therefore shows `ctx` as `OpenExpressionContext<..., RuntimeExpressionContext<AnyDomainEntity>>`, which has the members listed above. A helper of your own that takes the context declares its parameter as `ExpressionContext` with the five types of your project.
54
+
47
55
  ### Configurator Modes
48
56
 
49
57
  The `mode` property indicates the current operational context of the configurator. Different modes enable different functionality and access levels. Expressions can check the mode to change their behavior.
@@ -257,11 +257,14 @@ The frontend reads these at runtime from the generated config:
257
257
  | Variable | Required | Default |
258
258
  | -------------------------------- | -------- | ----------------------- |
259
259
  | `IS_DEV` | No | `false` (`true` in dev) |
260
+ | `ASSISTANT_STRICT_THREADS` | No | `false` |
260
261
  | `AWS_S3_PUBLIC_RESOURCES_BUCKET` | Yes | — |
261
262
  | `AWS_S3_RESOURCES_REGION` | Yes | — |
262
263
  | `DEPLOYMENT_RESOURCES_PATH` | No | `deployment-resources` |
263
264
  | Clerk vars (if enabled) | Yes | — |
264
265
 
266
+ A development environment keeps the AI assistant's conversation when the assistant setup (manifest, instructions, AI settings) changes, and applies the new setup from the next message on. Set `ASSISTANT_STRICT_THREADS=true` in `.env` to try the behavior of every other environment locally, where a changed setup locks the conversation and the next message continues it in a summarized one. The variable has no effect outside a development environment.
267
+
265
268
  ### Precedence
266
269
 
267
270
  Environment variables are resolved in this order (highest to lowest priority):
@@ -283,20 +286,20 @@ The Phoenix CLI auto-generates config files that read these variables:
283
286
 
284
287
  Starts the full development environment: Vite dev server, development webhook tunnel, domain-cli watcher, and editor WebSocket server.
285
288
 
286
- | Flag | Env Variable | Default | Description |
287
- | ---------------------- | ------------------ | -------------------- | ------------------------------------------------------------------------------- |
288
- | `--workspace` | — | from `.phoenix.json` | Override workspace mode |
289
- | `--editor` | `ENABLE_EDITOR` | `true` | Enable editor file generation |
290
- | `--editorWsPort` | `EDITOR_WS_PORT` | `3020` | Editor WebSocket port |
291
- | `--debug` | `DEBUG` | `false` | Verbose logging |
292
- | `--projectSlug` | `PROJECT_SLUG` | `local` | Project slug |
293
- | `--environmentSlug` | `ENVIRONMENT_SLUG` | package.json name | Environment slug |
294
- | `--withLingui` | `WITH_LINGUI` | `false` | Enable i18n extraction/compilation and watch i18n sources during dev |
295
- | `--persistence` | `PERSISTENCE_MODE` | `server` | Persistence mode |
296
- | `--force` / `-f` | `FORCE_REBUILD` | `false` | Force full rebuild, skip cache |
297
- | `--serverUrl` | `SERVER_URL` | the region's server | Phoenix server URL |
298
- | `--region` | `PHOENIX_REGION` | `eu` | Region of the signed-in workspace, used when no server URL is set |
299
- | `--skipUpload` / `-su` | `SKIP_UPLOAD` | `false` | Skip the S3 asset upload when the development deployment is prepared at startup |
289
+ | Flag | Env Variable | Default | Description |
290
+ | ----------------------- | ------------------ | -------------------- | ------------------------------------------------------------------------------- |
291
+ | `--workspace` | — | from `.phoenix.json` | Override workspace mode |
292
+ | `--editor` | `ENABLE_EDITOR` | `true` | Enable editor file generation |
293
+ | `--editorWsPort` | `EDITOR_WS_PORT` | `3020` | Editor WebSocket port |
294
+ | `--debug` | `DEBUG` | `false` | Verbose logging |
295
+ | `--projectSlug` | `PROJECT_SLUG` | `local` | Project slug |
296
+ | `--environmentSlug` | `ENVIRONMENT_SLUG` | package.json name | Environment slug |
297
+ | `--withLingui` | `WITH_LINGUI` | `false` | Enable i18n extraction/compilation and watch i18n sources during dev |
298
+ | `--persistence` | `PERSISTENCE_MODE` | `server` | Persistence mode |
299
+ | `--force` / `-f` | `FORCE_REBUILD` | `false` | Force full rebuild, skip cache |
300
+ | `--serverUrl` | `SERVER_URL` | the region's server | Phoenix server URL |
301
+ | `--region` | `PHOENIX_REGION` | `eu` | Region of the signed-in workspace, used when no server URL is set |
302
+ | `--skipUpload` / `--su` | `SKIP_UPLOAD` | `false` | Skip the S3 asset upload when the development deployment is prepared at startup |
300
303
 
301
304
  In `server` persistence mode the project comes from `--projectSlug`, `PROJECT_SLUG` or `project` in the spec, and the credential from `DEVELOPMENT_KEY` or the `phoenix login` sign-in; see [Starting a New Project](#starting-a-new-project). When signed in, the environment is always your own development environment and `--environmentSlug` is ignored.
302
305
 
@@ -690,12 +693,12 @@ Signs the CLI in to the SDK-builder workspace `<customer>`:
690
693
 
691
694
  The token is stored in `~/.phoenix/credentials.json`, readable only by you, per server, together with the Studio URL of the sign-in; `PHOENIX_CREDENTIALS_FILE` moves the file. The token works until you revoke it. Signing in again to the same server revokes the token it replaces; the CLI warns if the server could not revoke it.
692
695
 
693
- | Flag | Default | Description |
694
- | --------------------- | ------------------------------------ | ------------------------------------------------ |
695
- | `--region` | `eu` | Phoenix region of the workspace: `eu` or `us` |
696
- | `--serverUrl` / `-su` | the region's server | Phoenix server URL, for a local or custom server |
697
- | `--studioUrl` | the workspace's Studio in the region | Studio URL of the workspace |
698
- | `--open` | `true` | Open the approval page in your browser |
696
+ | Flag | Default | Description |
697
+ | ---------------------- | ------------------------------------ | ------------------------------------------------ |
698
+ | `--region` | `eu` | Phoenix region of the workspace: `eu` or `us` |
699
+ | `--serverUrl` / `--su` | the region's server | Phoenix server URL, for a local or custom server |
700
+ | `--studioUrl` | the workspace's Studio in the region | Studio URL of the workspace |
701
+ | `--open` | `true` | Open the approval page in your browser |
699
702
 
700
703
  The sign-in follows the region, not the `SERVER_URL` in a project's `.env`: that variable names the server of the project's own environment. The CLI prints the server it signs in to.
701
704
 
@@ -728,7 +731,7 @@ Pass the message as the argument for a short note, or `--file` for a longer repo
728
731
  | `--agent` | — | — | Name of the coding agent that writes the feedback |
729
732
  | `--projectSlug` / `-p` | `PROJECT_SLUG` | `project` of the spec, if any | Workspace project the feedback is about |
730
733
  | `--region` | — | `eu` | Phoenix region of the workspace: `eu` or `us` |
731
- | `--serverUrl` / `-su` | — | the region's server | Phoenix server URL, for a local or custom server |
734
+ | `--serverUrl` / `--su` | — | the region's server | Phoenix server URL, for a local or custom server |
732
735
 
733
736
  A message holds at most 100,000 characters, from the argument or from the file. Besides the message and the flags, the CLI sends only the SDK version, the operating system and the Node.js version; no file of the project is attached, and the Phoenix team reads a build's sources through the build's page in Studio. The project must belong to the signed-in workspace, otherwise the server refuses the feedback; without a project, the feedback is sent on its own.
734
737
 
@@ -44,12 +44,12 @@ The CLI stores the token in `~/.phoenix/credentials.json`, readable only by you,
44
44
 
45
45
  `login`, `logout` and `deploy` follow the region, not the `SERVER_URL` in the project's `.env`. `dev` follows the region too when `.env` has no `SERVER_URL`:
46
46
 
47
- | Flag | Default | Description |
48
- | --------------------- | ------------------------------------ | ------------------------------------------------ |
49
- | `--region` | `eu` | Phoenix region of the workspace: `eu` or `us` |
50
- | `--serverUrl` / `-su` | the region's server | Phoenix server URL, for a local or custom server |
51
- | `--studioUrl` | the workspace's Studio in the region | Studio URL of the workspace (`login`) |
52
- | `--open` | `true` | Open the approval page in your browser (`login`) |
47
+ | Flag | Default | Description |
48
+ | ---------------------- | ------------------------------------ | ------------------------------------------------ |
49
+ | `--region` | `eu` | Phoenix region of the workspace: `eu` or `us` |
50
+ | `--serverUrl` / `--su` | the region's server | Phoenix server URL, for a local or custom server |
51
+ | `--studioUrl` | the workspace's Studio in the region | Studio URL of the workspace (`login`) |
52
+ | `--open` | `true` | Open the approval page in your browser (`login`) |
53
53
 
54
54
  ## 3. Develop
55
55
 
@@ -13,6 +13,15 @@ Choose the control from how users understand the options.
13
13
  - Long labels or descriptions: list selector.
14
14
  - Many text options or tight space: select dropdown.
15
15
 
16
+ ## Adding, removing, and placing
17
+
18
+ The controls above choose a value for a property. A decision that changes which parts exist is a different kind of choice, and where its control lives is part of the decision.
19
+
20
+ - Put the control in the scene when position carries the meaning of the action: where the next part goes, what sits on top of this one, which part this removes. An add FAB stands at the place the new part will occupy, and a delete FAB sits on the part it removes.
21
+ - Put the control in the sidebar when the choice is a catalogue pick and position is incidental, or when the scene offers no obvious place for the control to stand.
22
+ - A product the user assembles or arranges is the first case. A sidebar list for it turns building into list-keeping and leaves the scene a picture of the result rather than the place the user works.
23
+ - Both forms offer the same recipes, so this chooses where the user acts, not what they can add.
24
+
16
25
  ## Common control guidance
17
26
 
18
27
  - Order properties in the sequence users naturally make the decisions.
@@ -31,3 +40,5 @@ Choose the control from how users understand the options.
31
40
  - [Select dropdown](?path=/docs/controls-select-attribute-select--docs)
32
41
  - [Text input](?path=/docs/design-system-inputs-textinput--docs)
33
42
  - [Color picker](?path=/docs/controls-color-picker-input--docs)
43
+ - [Scene add and delete FABs](?path=/docs/fabs-basic--docs)
44
+ - [Recipe panel in the sidebar](?path=/docs/recipes-delete-simple--docs)
@@ -1,4 +1,4 @@
1
- import type { DomainEntity, DomainState, ExpressionContext, Violation } from '../../core/index.js';
1
+ import type { DomainEntity, DomainState, OpenExpressionContext, Violation } from '../../core/index.js';
2
2
  import type { ChildEntitySelectionOption } from '../../system-components/child-entity-selection.js';
3
3
  import type { RecipeListItem } from '../../system-components/index.js';
4
4
  import type { SwatchOptionMap } from '../../system-components/material-swatch.js';
@@ -18,10 +18,10 @@ export declare const commonAdminCustomExpressions: {
18
18
  };
19
19
  };
20
20
  export declare const CommonAdminExpressionBuilder: {
21
- createConstantSwatchExpression: <ENTITIES extends DomainEntity<string>, ALLOWED_ROOT_ENTITIES extends ENTITIES, PUBLISHED_DATA extends Record<string, unknown>, SESSION_DATA extends Record<string, unknown>, FRONTEND_DATA extends Record<string, unknown>, SELF extends ENTITIES>(swatches: SwatchOptionMap) => ((self: SELF, state: DomainState<ENTITIES>, ctx: ExpressionContext<ENTITIES, ALLOWED_ROOT_ENTITIES, PUBLISHED_DATA, SESSION_DATA, FRONTEND_DATA>) => SwatchOptionMap);
22
- createConstantRecipeExpression: <ENTITIES extends DomainEntity<string>, ALLOWED_ROOT_ENTITIES extends ENTITIES, PUBLISHED_DATA extends Record<string, unknown>, SESSION_DATA extends Record<string, unknown>, FRONTEND_DATA extends Record<string, unknown>, SELF extends ENTITIES>(recipes: RecipeListItem[]) => ((self: SELF, state: DomainState<ENTITIES>, ctx: ExpressionContext<ENTITIES, ALLOWED_ROOT_ENTITIES, PUBLISHED_DATA, SESSION_DATA, FRONTEND_DATA>) => RecipeListItem[]);
23
- createConstantChildEntitySelectionExpression: <ENTITIES extends DomainEntity<string>, ALLOWED_ROOT_ENTITIES extends ENTITIES, PUBLISHED_DATA extends Record<string, unknown>, SESSION_DATA extends Record<string, unknown>, FRONTEND_DATA extends Record<string, unknown>, SELF extends ENTITIES>(entities: ChildEntitySelectionOption[]) => ((self: SELF, state: DomainState<ENTITIES>, ctx: ExpressionContext<ENTITIES, ALLOWED_ROOT_ENTITIES, PUBLISHED_DATA, SESSION_DATA, FRONTEND_DATA>) => ChildEntitySelectionOption[]);
24
- createRecipeExpression: <ENTITIES extends DomainEntity<string>, ALLOWED_ROOT_ENTITIES extends ENTITIES, PUBLISHED_DATA extends CommonAdminPublishedData, SESSION_DATA extends Record<string, unknown>, FRONTEND_DATA extends Record<string, unknown>, SELF extends ENTITIES>(collection: string, defaults: RecipeListItem[]) => ((self: SELF, state: DomainState<ENTITIES>, ctx: ExpressionContext<ENTITIES, ALLOWED_ROOT_ENTITIES, PUBLISHED_DATA, SESSION_DATA, FRONTEND_DATA>) => RecipeListItem[]);
21
+ createConstantSwatchExpression: <ENTITIES extends DomainEntity<string>, ALLOWED_ROOT_ENTITIES extends ENTITIES, PUBLISHED_DATA extends Record<string, unknown>, SESSION_DATA extends Record<string, unknown>, FRONTEND_DATA extends Record<string, unknown>, SELF extends ENTITIES>(swatches: SwatchOptionMap) => ((self: SELF, state: DomainState<ENTITIES>, ctx: OpenExpressionContext<ENTITIES, ALLOWED_ROOT_ENTITIES, PUBLISHED_DATA, SESSION_DATA, FRONTEND_DATA>) => SwatchOptionMap);
22
+ createConstantRecipeExpression: <ENTITIES extends DomainEntity<string>, ALLOWED_ROOT_ENTITIES extends ENTITIES, PUBLISHED_DATA extends Record<string, unknown>, SESSION_DATA extends Record<string, unknown>, FRONTEND_DATA extends Record<string, unknown>, SELF extends ENTITIES>(recipes: RecipeListItem[]) => ((self: SELF, state: DomainState<ENTITIES>, ctx: OpenExpressionContext<ENTITIES, ALLOWED_ROOT_ENTITIES, PUBLISHED_DATA, SESSION_DATA, FRONTEND_DATA>) => RecipeListItem[]);
23
+ createConstantChildEntitySelectionExpression: <ENTITIES extends DomainEntity<string>, ALLOWED_ROOT_ENTITIES extends ENTITIES, PUBLISHED_DATA extends Record<string, unknown>, SESSION_DATA extends Record<string, unknown>, FRONTEND_DATA extends Record<string, unknown>, SELF extends ENTITIES>(entities: ChildEntitySelectionOption[]) => ((self: SELF, state: DomainState<ENTITIES>, ctx: OpenExpressionContext<ENTITIES, ALLOWED_ROOT_ENTITIES, PUBLISHED_DATA, SESSION_DATA, FRONTEND_DATA>) => ChildEntitySelectionOption[]);
24
+ createRecipeExpression: <ENTITIES extends DomainEntity<string>, ALLOWED_ROOT_ENTITIES extends ENTITIES, PUBLISHED_DATA extends CommonAdminPublishedData, SESSION_DATA extends Record<string, unknown>, FRONTEND_DATA extends Record<string, unknown>, SELF extends ENTITIES>(collection: string, defaults: RecipeListItem[]) => ((self: SELF, state: DomainState<ENTITIES>, ctx: OpenExpressionContext<ENTITIES, ALLOWED_ROOT_ENTITIES, PUBLISHED_DATA, SESSION_DATA, FRONTEND_DATA>) => RecipeListItem[]);
25
25
  };
26
26
  /**
27
27
  * Expression helpers for projects with chunked published data.
@@ -30,13 +30,13 @@ export declare const CommonAdminExpressionBuilder: {
30
30
  * Use {@link CommonAdminExpressionBuilder} for projects with flat published data.
31
31
  */
32
32
  export declare const ChunkedCommonAdminExpressionBuilder: {
33
- createConstantSwatchExpression: <ENTITIES extends DomainEntity<string>, ALLOWED_ROOT_ENTITIES extends ENTITIES, PUBLISHED_DATA extends Record<string, unknown>, SESSION_DATA extends Record<string, unknown>, FRONTEND_DATA extends Record<string, unknown>, SELF extends ENTITIES>(swatches: SwatchOptionMap) => ((self: SELF, state: DomainState<ENTITIES>, ctx: ExpressionContext<ENTITIES, ALLOWED_ROOT_ENTITIES, PUBLISHED_DATA, SESSION_DATA, FRONTEND_DATA>) => SwatchOptionMap);
34
- createConstantRecipeExpression: <ENTITIES extends DomainEntity<string>, ALLOWED_ROOT_ENTITIES extends ENTITIES, PUBLISHED_DATA extends Record<string, unknown>, SESSION_DATA extends Record<string, unknown>, FRONTEND_DATA extends Record<string, unknown>, SELF extends ENTITIES>(recipes: RecipeListItem[]) => ((self: SELF, state: DomainState<ENTITIES>, ctx: ExpressionContext<ENTITIES, ALLOWED_ROOT_ENTITIES, PUBLISHED_DATA, SESSION_DATA, FRONTEND_DATA>) => RecipeListItem[]);
35
- createConstantChildEntitySelectionExpression: <ENTITIES extends DomainEntity<string>, ALLOWED_ROOT_ENTITIES extends ENTITIES, PUBLISHED_DATA extends Record<string, unknown>, SESSION_DATA extends Record<string, unknown>, FRONTEND_DATA extends Record<string, unknown>, SELF extends ENTITIES>(entities: ChildEntitySelectionOption[]) => ((self: SELF, state: DomainState<ENTITIES>, ctx: ExpressionContext<ENTITIES, ALLOWED_ROOT_ENTITIES, PUBLISHED_DATA, SESSION_DATA, FRONTEND_DATA>) => ChildEntitySelectionOption[]);
33
+ createConstantSwatchExpression: <ENTITIES extends DomainEntity<string>, ALLOWED_ROOT_ENTITIES extends ENTITIES, PUBLISHED_DATA extends Record<string, unknown>, SESSION_DATA extends Record<string, unknown>, FRONTEND_DATA extends Record<string, unknown>, SELF extends ENTITIES>(swatches: SwatchOptionMap) => ((self: SELF, state: DomainState<ENTITIES>, ctx: OpenExpressionContext<ENTITIES, ALLOWED_ROOT_ENTITIES, PUBLISHED_DATA, SESSION_DATA, FRONTEND_DATA>) => SwatchOptionMap);
34
+ createConstantRecipeExpression: <ENTITIES extends DomainEntity<string>, ALLOWED_ROOT_ENTITIES extends ENTITIES, PUBLISHED_DATA extends Record<string, unknown>, SESSION_DATA extends Record<string, unknown>, FRONTEND_DATA extends Record<string, unknown>, SELF extends ENTITIES>(recipes: RecipeListItem[]) => ((self: SELF, state: DomainState<ENTITIES>, ctx: OpenExpressionContext<ENTITIES, ALLOWED_ROOT_ENTITIES, PUBLISHED_DATA, SESSION_DATA, FRONTEND_DATA>) => RecipeListItem[]);
35
+ createConstantChildEntitySelectionExpression: <ENTITIES extends DomainEntity<string>, ALLOWED_ROOT_ENTITIES extends ENTITIES, PUBLISHED_DATA extends Record<string, unknown>, SESSION_DATA extends Record<string, unknown>, FRONTEND_DATA extends Record<string, unknown>, SELF extends ENTITIES>(entities: ChildEntitySelectionOption[]) => ((self: SELF, state: DomainState<ENTITIES>, ctx: OpenExpressionContext<ENTITIES, ALLOWED_ROOT_ENTITIES, PUBLISHED_DATA, SESSION_DATA, FRONTEND_DATA>) => ChildEntitySelectionOption[]);
36
36
  createRecipeExpression: <ENTITIES extends DomainEntity<string>, ALLOWED_ROOT_ENTITIES extends ENTITIES, PUBLISHED_DATA extends {
37
37
  readonly system?: CommonAdminPublishedData;
38
- }, SESSION_DATA extends Record<string, unknown>, FRONTEND_DATA extends Record<string, unknown>, SELF extends ENTITIES>(collection: string, defaults: RecipeListItem[]) => ((self: SELF, state: DomainState<ENTITIES>, ctx: ExpressionContext<ENTITIES, ALLOWED_ROOT_ENTITIES, PUBLISHED_DATA, SESSION_DATA, FRONTEND_DATA>) => RecipeListItem[]);
38
+ }, SESSION_DATA extends Record<string, unknown>, FRONTEND_DATA extends Record<string, unknown>, SELF extends ENTITIES>(collection: string, defaults: RecipeListItem[]) => ((self: SELF, state: DomainState<ENTITIES>, ctx: OpenExpressionContext<ENTITIES, ALLOWED_ROOT_ENTITIES, PUBLISHED_DATA, SESSION_DATA, FRONTEND_DATA>) => RecipeListItem[]);
39
39
  };
40
40
  export declare const createDataSwatchMap: (tableName: string, chunkKey?: string) => {
41
- bind: <ENTITIES extends DomainEntity<string>, ALLOWED_ROOT_ENTITIES extends ENTITIES, PUBLISHED_DATA extends Record<string, unknown>, SESSION_DATA extends Record<string, unknown>, FRONTEND_DATA extends Record<string, unknown>, SELF extends ENTITIES>() => (_self: SELF, _state: DomainState<ENTITIES>, ctx: ExpressionContext<ENTITIES, ALLOWED_ROOT_ENTITIES, PUBLISHED_DATA, SESSION_DATA, FRONTEND_DATA>) => SwatchOptionMap;
41
+ bind: <ENTITIES extends DomainEntity<string>, ALLOWED_ROOT_ENTITIES extends ENTITIES, PUBLISHED_DATA extends Record<string, unknown>, SESSION_DATA extends Record<string, unknown>, FRONTEND_DATA extends Record<string, unknown>, SELF extends ENTITIES>() => (_self: SELF, _state: DomainState<ENTITIES>, ctx: OpenExpressionContext<ENTITIES, ALLOWED_ROOT_ENTITIES, PUBLISHED_DATA, SESSION_DATA, FRONTEND_DATA>) => SwatchOptionMap;
42
42
  };
@@ -10,9 +10,14 @@ export * from './__generated/model/index.js';
10
10
  export * from './implementation/common-admin-expressions.js';
11
11
  export * from './implementation/common-admin-publish.js';
12
12
  export * from './schema/index.js';
13
- export declare const createCommonAdminRecipe: import("../domain-context/recipe-system/recipes.js").RecipeFactory<AnyDomainEntity>;
14
- export declare const attachCommonAdminDomainComponent: DomainComponentOpticBuilder<AnyDomainEntity, import("./index.js").Admin, $Map, PublishedData, SessionData, Record<string, unknown>, Aliases, never, never, never>;
15
- export declare const commonAdminComponents: import("../index.js").DomainComponentSimpleOptic<AnyDomainEntity, import("./index.js").Admin, PublishedData, SessionData, Record<string, unknown>, import("./index.js").Preset, import("../index.js").SystemComponentType<"attributeSelection", import("../index.js").AttributeSelectionComponentState, "value">>[];
13
+ export declare const createCommonAdminRecipe: import("../index.js").RecipeFactory<AnyDomainEntity>;
14
+ /**
15
+ * Closed with core's part of the expression context only: `admin-domain/` counts as core and may
16
+ * not import the runtime. A callback that needs the component reader or a projection is written
17
+ * through a builder closed with `RuntimeExpressionContext`.
18
+ */
19
+ export declare const attachCommonAdminDomainComponent: DomainComponentOpticBuilder<AnyDomainEntity, import("./index.js").Admin, $Map, PublishedData, SessionData, Record<string, unknown>, Aliases, never, never, never, unknown>;
20
+ export declare const commonAdminComponents: import("../index.js").DomainComponentSimpleOptic<AnyDomainEntity, import("./index.js").Admin, PublishedData, SessionData, Record<string, unknown>, import("./index.js").Preset, import("../index.js").SystemComponentType<"attributeSelection", import("../index.js").AttributeSelectionComponentState, "value">, unknown>[];
16
21
  /**
17
22
  * Type-level carrier for the common-admin builder shape consumed by `createAdminInterface`.
18
23
  *
@@ -1 +1 @@
1
- import{DomainComponentOpticBuilder as o}from"../core/index.js";import{RecipeFactoryBuilder as e}from"../domain-context/index.js";import{attributeSelectionComponent as n}from"../system-components/index.js";import{AnyDomainEntity as m,PresetCategory as t,aliases as i}from"./__generated/model/index.js";import{DraftId as a}from"./implementation/common-admin-expressions.js";export{migrateCommonAdminDomain}from"./implementation/common-admin-migrations.js";export*from"./__generated/model/index.js";export*from"./implementation/common-admin-expressions.js";export*from"./implementation/common-admin-publish.js";export*from"./schema/index.js";export const createCommonAdminRecipe=e.forAliases(i).forEntities(m.reflections).withDefaults({}).build();export const attachCommonAdminDomainComponent=o.from(i);export const commonAdminComponents=[attachCommonAdminDomainComponent.withEntity("Preset").withComponent(n,"category").attach((o,e)=>{let n=e.entities.filter(t.is);return null===o.categoryId?{value:a,options:n.map(o=>({value:o.id,label:o.name})).concat([{value:a,label:{$lang:{en:"Draft"}}}])}:{value:o.categoryId,options:n.map(o=>({value:o.id,label:o.name}))}},o=>({categoryId:o.value===a?null:o.value}))];export const configuratorBuilder=null;
1
+ import{DomainComponentOpticBuilder as o,RecipeFactoryBuilder as e}from"../core/index.js";import{attributeSelectionComponent as n}from"../system-components/index.js";import{AnyDomainEntity as m,PresetCategory as t,aliases as i}from"./__generated/model/index.js";import{DraftId as a}from"./implementation/common-admin-expressions.js";export{migrateCommonAdminDomain}from"./implementation/common-admin-migrations.js";export*from"./__generated/model/index.js";export*from"./implementation/common-admin-expressions.js";export*from"./implementation/common-admin-publish.js";export*from"./schema/index.js";export const createCommonAdminRecipe=e.forAliases(i).forEntities(m.reflections).withDefaults({}).build();export const attachCommonAdminDomainComponent=o.from(i);export const commonAdminComponents=[attachCommonAdminDomainComponent.withEntity("Preset").withComponent(n,"category").attach((o,e)=>{let n=e.entities.filter(t.is);return null===o.categoryId?{value:a,options:n.map(o=>({value:o.id,label:o.name})).concat([{value:a,label:{$lang:{en:"Draft"}}}])}:{value:o.categoryId,options:n.map(o=>({value:o.id,label:o.name}))}},o=>({categoryId:o.value===a?null:o.value}))];export const configuratorBuilder=null;
@@ -1,7 +1,6 @@
1
- import type { DomainEntityId } from '../core/index.js';
1
+ import type { DataCellValue, DataSchema, DomainEntityId } from '../core/index.js';
2
2
  import type { AttributeSelectionComponentState } from '../system-components/attribute-selection.js';
3
3
  import type { NavigationListItem, NestedNavigationListItem } from '../system-components/navigation-panel-list.js';
4
- import type { DataCellValue, DataSchema } from './application-config.js';
5
4
  interface PresetPagesConfig {
6
5
  readonly categoryNavigationState: string;
7
6
  readonly presetNavigationState: string;
@@ -6,7 +6,7 @@ import type { Logger } from '@salsita-ai/common/utils';
6
6
  import type { SessionRole, SessionTokenPayload } from '@salsita-ai/contracts/api';
7
7
  import type { CellValue } from '@salsita-ai/contracts/webhook';
8
8
  import type { AdminIntegrationService } from '#package/react-sdk';
9
- import type { $DomainEntity, DomainEntity, DomainFactory, ProductPreset } from '../core/index.js';
9
+ import type { $DomainEntity, DataCellValue, DataSchema, DomainEntity, DomainFactory, ProductPreset } from '../core/index.js';
10
10
  import type { AnalyticsSystem, TransformerFactory } from '../domain-context/index.js';
11
11
  import type { RegistrableTransformer } from '../domain-context/transformers/index.js';
12
12
  import type { ProjectModule } from '../project-modules/index.js';
@@ -32,26 +32,6 @@ export interface TransformersConfig {
32
32
  readonly importedTransformers: readonly ProjectModule[];
33
33
  readonly specTransformers: readonly SpecTransformer[];
34
34
  }
35
- export interface DataSchemaPrimitiveField {
36
- readonly type: 'string' | 'number' | 'integer' | 'boolean';
37
- readonly enum?: ReadonlyArray<string | number>;
38
- readonly description?: string;
39
- }
40
- export interface DataSchemaLocalizedField {
41
- readonly type: 'localized';
42
- readonly description?: string;
43
- }
44
- export interface DataSchemaArrayField {
45
- readonly type: 'array';
46
- readonly items: 'string' | 'number' | 'boolean';
47
- readonly description?: string;
48
- }
49
- export type DataSchemaFieldObject = DataSchemaPrimitiveField | DataSchemaLocalizedField | DataSchemaArrayField;
50
- export type DataSchemaField = 'string' | 'number' | 'boolean' | readonly ['string', 'null'] | readonly ['number', 'null'] | readonly ['boolean', 'null'] | DataSchemaFieldObject;
51
- export type DataSchema = Record<string, DataSchemaField>;
52
- export type DataCellValue = CellValue | null | {
53
- readonly $lang: Record<string, string>;
54
- } | readonly CellValue[];
55
35
  export type DataSpecEntry = {
56
36
  readonly definition: DataSchema;
57
37
  readonly chunk?: string;
@@ -51,6 +51,8 @@ export interface AssistantFieldOptions {
51
51
  */
52
52
  export interface AssistantManifest {
53
53
  readonly sdl: string;
54
+ /** Navigation state fields exposed by the schema; absent means none. Values stay in the SDL. */
55
+ readonly navigationFields?: ReadonlyArray<'navigationState' | 'viewState' | 'toolState'>;
54
56
  readonly fields: Readonly<Record<string, Readonly<Record<string, AssistantFieldSource>>>>;
55
57
  readonly deletableTypes?: readonly string[];
56
58
  readonly writableFields?: Readonly<Record<string, Readonly<Record<string, string>>>>;