@salsita-ai/sdk 0.50.0-develop.b9eb39baf0 → 0.50.0-develop.bc4bdb2ffc

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 (572) 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 +34 -34
  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/webhook-builders.js +4 -3
  8. package/dist/application-spec/generate-application/code/templates/webhooks-config.js +2 -2
  9. package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-schema.js +1 -1
  10. package/dist/client/authorized-client.d.ts +3 -1
  11. package/dist/client/authorized-client.js +1 -1
  12. package/dist/client/contract.d.ts +34 -0
  13. package/dist/client/contract.js +1 -1
  14. package/dist/client/index.d.ts +2 -2
  15. package/dist/client/index.js +1 -1
  16. package/dist/client/local-authorized-client.d.ts +3 -1
  17. package/dist/client/local-authorized-client.js +1 -1
  18. package/dist/client/memory-authorized-client.d.ts +3 -1
  19. package/dist/client/memory-authorized-client.js +1 -1
  20. package/dist/client/phoenix-api.d.ts +212 -1
  21. package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.d.ts +56 -2
  22. package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.js +1 -1
  23. package/dist/configurator/application-runtime/extensions/systems/graphql-system/entity-meta.js +1 -1
  24. package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.js +1 -1
  25. package/dist/configurator/application-runtime/extensions/systems/index.d.ts +1 -1
  26. package/dist/configurator/ui/assistant/AssistantComposer.d.ts +2 -1
  27. package/dist/configurator/ui/assistant/AssistantComposer.js +1 -1
  28. package/dist/configurator/ui/assistant/AssistantThread.d.ts +6 -2
  29. package/dist/configurator/ui/assistant/AssistantThread.js +1 -1
  30. package/dist/configurator/ui/assistant/thread-items.d.ts +13 -2
  31. package/dist/configurator/ui/assistant/thread-items.js +1 -1
  32. package/dist/docs/index.json +1 -1
  33. package/dist/docs/phoenix/deployments.mdx +1 -1
  34. package/dist/docs/phoenix/expression-context.mdx +11 -3
  35. package/dist/docs/phoenix/phoenix-cli.mdx +24 -21
  36. package/dist/docs/phoenix/sdk-builder-workflow.mdx +6 -6
  37. package/dist/domain/admin-domain/__generated/enhanced-model.d.ts +1 -2
  38. package/dist/domain/admin-domain/implementation/common-admin-expressions.d.ts +10 -11
  39. package/dist/domain/admin-domain/index.d.ts +4 -5
  40. package/dist/domain/admin-domain/index.js +1 -1
  41. package/dist/domain/application/assistant/assistant-manifest.d.ts +2 -0
  42. package/dist/domain/application/assistant/assistant-value-type.js +1 -1
  43. package/dist/domain/application/assistant/build-assistant-manifest.js +1 -1
  44. package/dist/domain/application/assistant/generate-assistant-prompt.d.ts +1 -11
  45. package/dist/domain/application/assistant/generate-assistant-prompt.js +1 -1
  46. package/dist/domain/application/assistant-mutations.d.ts +1 -2
  47. package/dist/domain/application/assistant-mutations.js +1 -1
  48. package/dist/domain/application/assistant-recipe-groups.d.ts +1 -3
  49. package/dist/domain/application/index.d.ts +1 -1
  50. package/dist/domain/application/index.js +1 -1
  51. package/dist/domain/available-system-components.js +1 -1
  52. package/dist/domain/{actions → core/action}/action-factory.d.ts +3 -2
  53. package/dist/domain/core/{action.d.ts → action/action.d.ts} +15 -15
  54. package/dist/domain/core/action/index.d.ts +2 -0
  55. package/dist/domain/core/action/index.js +1 -0
  56. package/dist/domain/{components → core/component}/component-reader-types.d.ts +1 -1
  57. package/dist/domain/{components → core/component}/debug-state-component.d.ts +1 -1
  58. package/dist/domain/core/component/debug-state-component.js +1 -0
  59. package/dist/domain/{components → core/component}/domain-component-optic.d.ts +37 -36
  60. package/dist/domain/core/component/domain-component-optic.js +16 -0
  61. package/dist/domain/{components → core/component}/drag-state-component.d.ts +1 -1
  62. package/dist/domain/core/component/drag-state-component.js +1 -0
  63. package/dist/domain/{components → core/component}/export-state-component.d.ts +1 -1
  64. package/dist/domain/core/component/export-state-component.js +1 -0
  65. package/dist/domain/{components → core/component}/fullscreen-state-component.d.ts +1 -1
  66. package/dist/domain/core/component/fullscreen-state-component.js +1 -0
  67. package/dist/domain/{components → core/component}/group-components-by-entity-id-and-name.d.ts +1 -1
  68. package/dist/domain/core/component/group-components-by-entity-id-and-name.js +1 -0
  69. package/dist/domain/{components → core/component}/hover-state-component.d.ts +1 -1
  70. package/dist/domain/core/component/hover-state-component.js +1 -0
  71. package/dist/domain/core/component/index.d.ts +18 -0
  72. package/dist/domain/core/component/index.js +1 -0
  73. package/dist/domain/{components → core/component}/legacy-filter.d.ts +2 -1
  74. package/dist/domain/{components → core/component}/navigation-state-component.d.ts +1 -1
  75. package/dist/domain/core/component/navigation-state-component.js +1 -0
  76. package/dist/domain/{components → core/component}/selection-state-component.d.ts +1 -1
  77. package/dist/domain/core/component/selection-state-component.js +1 -0
  78. package/dist/domain/{components → core/component}/system-component-builder.d.ts +1 -1
  79. package/dist/domain/core/component/system-component-builder.js +1 -0
  80. package/dist/domain/{components → core/component}/system-component-filter.d.ts +19 -17
  81. package/dist/domain/core/component/system-virtual-entity.js +1 -0
  82. package/dist/domain/{components → core/component}/tool-state-component.d.ts +1 -1
  83. package/dist/domain/core/component/tool-state-component.js +1 -0
  84. package/dist/domain/{components → core/component}/updates.d.ts +1 -1
  85. package/dist/domain/{components → core/component}/view-state-component.d.ts +1 -1
  86. package/dist/domain/core/component/view-state-component.js +1 -0
  87. package/dist/domain/{components → core/component}/viewport-state-component.d.ts +1 -1
  88. package/dist/domain/core/component/viewport-state-component.js +1 -0
  89. package/dist/domain/core/domain-factory.d.ts +3 -3
  90. package/dist/domain/core/domain.d.ts +3 -3
  91. package/dist/domain/core/expression/aliased-expressions.d.ts +10 -0
  92. package/dist/domain/{expressions → core/expression}/constant-expressions.d.ts +2 -1
  93. package/dist/domain/core/expression/constant-expressions.js +1 -0
  94. package/dist/domain/{expressions → core/expression}/custom-expression.d.ts +9 -7
  95. package/dist/domain/core/expression/custom-expression.js +1 -0
  96. package/dist/domain/core/{expression.d.ts → expression/expression.d.ts} +17 -19
  97. package/dist/domain/core/expression/index.d.ts +4 -0
  98. package/dist/domain/core/expression/index.js +1 -0
  99. package/dist/domain/core/index.d.ts +7 -4
  100. package/dist/domain/core/index.js +1 -1
  101. package/dist/domain/{invariants → core/invariant}/builtin-invariant.d.ts +2 -1
  102. package/dist/domain/{invariants → core/invariant}/custom-invariants.d.ts +7 -7
  103. package/dist/domain/core/invariant/custom-invariants.js +1 -0
  104. package/dist/domain/core/invariant/index.d.ts +5 -0
  105. package/dist/domain/core/invariant/index.js +1 -0
  106. package/dist/domain/{invariants → core/invariant}/invariants.d.ts +6 -4
  107. package/dist/domain/core/invariant/invariants.js +1 -0
  108. package/dist/domain/core/invariant/violation-component.js +1 -0
  109. package/dist/domain/{invariants → core/invariant}/violation.d.ts +2 -2
  110. package/dist/domain/core/recipe/index.d.ts +1 -0
  111. package/dist/domain/core/recipe/index.js +1 -0
  112. package/dist/domain/{domain-context/recipe-system → core/recipe}/recipes.d.ts +1 -1
  113. package/dist/domain/core/recipe/recipes.js +1 -0
  114. package/dist/domain/{relations → core/relation}/all-of-type-relation.d.ts +3 -1
  115. package/dist/domain/core/relation/all-of-type-relation.js +1 -0
  116. package/dist/domain/{relations → core/relation}/component-factories.d.ts +1 -1
  117. package/dist/domain/core/relation/component-factories.js +1 -0
  118. package/dist/domain/{relations → core/relation}/composed-of.d.ts +1 -1
  119. package/dist/domain/core/relation/composed-of.js +1 -0
  120. package/dist/domain/{relations → core/relation}/direct-relation.d.ts +2 -1
  121. package/dist/domain/core/relation/index.d.ts +9 -0
  122. package/dist/domain/core/relation/index.js +1 -0
  123. package/dist/domain/{relations → core/relation}/indirect-relation.d.ts +3 -1
  124. package/dist/domain/core/relation/indirect-relation.js +1 -0
  125. package/dist/domain/{relations → core/relation}/reference-component.d.ts +4 -4
  126. package/dist/domain/core/relation/reference-component.js +1 -0
  127. package/dist/domain/{relations → core/relation}/reference-field.d.ts +1 -1
  128. package/dist/domain/{relations → core/relation}/relation-factory.d.ts +2 -1
  129. package/dist/domain/{relations → core/relation}/relation-implementation.d.ts +3 -1
  130. package/dist/domain/core/relation/relation-implementation.js +1 -0
  131. package/dist/domain/core/state/id-sequence.d.ts +15 -0
  132. package/dist/domain/core/state/id-sequence.js +1 -0
  133. package/dist/domain/core/state/index.d.ts +3 -0
  134. package/dist/domain/core/state/index.js +1 -0
  135. package/dist/domain/core/{migrations.d.ts → state/migrations.d.ts} +1 -1
  136. package/dist/domain/core/{state.d.ts → state/state.d.ts} +1 -1
  137. package/dist/domain/domain-builder.d.ts +1 -4
  138. package/dist/domain/domain-context/action-system/action-system.d.ts +2 -2
  139. package/dist/domain/domain-context/action-system/action-system.js +1 -1
  140. package/dist/domain/domain-context/dimension-system/dimension-state.js +1 -1
  141. package/dist/domain/domain-context/dimension-system/dimension-system.d.ts +1 -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/navigation-system/navigation-system.d.ts +3 -4
  145. package/dist/domain/domain-context/navigation-system/navigation-system.js +1 -1
  146. package/dist/domain/domain-context/navigation-system/navigation-updates.d.ts +1 -12
  147. package/dist/domain/domain-context/navigation-system/navigation-updates.js +1 -1
  148. package/dist/domain/domain-context/recipe-system/recipe-cooker-system.d.ts +1 -3
  149. package/dist/domain/domain-context/recipe-system/recipe-cooker-system.js +1 -1
  150. package/dist/domain/domain-context/relation-transformers/cascade-deletes.js +1 -1
  151. package/dist/domain/domain-context/relation-transformers/cascade-ref-pruning.d.ts +1 -1
  152. package/dist/domain/domain-context/relation-transformers/cascade-ref-pruning.js +1 -1
  153. package/dist/domain/domain-context/relation-transformers/create-entity-refs.d.ts +1 -1
  154. package/dist/domain/domain-context/relation-transformers/create-entity-refs.js +2 -2
  155. package/dist/domain/domain-context/relation-transformers/replace-refs.d.ts +1 -1
  156. package/dist/domain/domain-context/relation-transformers/replace-refs.js +1 -1
  157. package/dist/domain/domain-context/store-system/apply-updates.d.ts +1 -2
  158. package/dist/domain/domain-context/store-system/next-domain-entity-id.d.ts +1 -12
  159. package/dist/domain/domain-context/store-system/reconcile-projected-entities.d.ts +1 -2
  160. package/dist/domain/domain-context/store-system/reconcile-projected-entities.js +1 -1
  161. package/dist/domain/domain-context/store-system/store-system.d.ts +1 -3
  162. package/dist/domain/domain-context/store-system/store-system.js +2 -2
  163. package/dist/domain/domain-context/store-system/system-state.d.ts +1 -1
  164. package/dist/domain/domain-context/store-system/system-state.js +1 -1
  165. package/dist/domain/domain-context/transformers/actions-builder.d.ts +1 -2
  166. package/dist/domain/domain-context/transformers/auto-snap-transformer.d.ts +1 -2
  167. package/dist/domain/domain-context/transformers/context.d.ts +1 -4
  168. package/dist/domain/domain-context/transformers/entity-builder.d.ts +1 -5
  169. package/dist/domain/domain-context/transformers/then-builder.d.ts +1 -2
  170. package/dist/domain/domain-context/transformers/when-builder.d.ts +1 -5
  171. package/dist/domain/domain-runtime/domain-context/component-reader.d.ts +1 -2
  172. package/dist/domain/domain-runtime/domain-context/component-reader.js +1 -1
  173. package/dist/domain/domain-runtime/domain-context/expression-context.d.ts +8 -0
  174. package/dist/domain/domain-runtime/domain-context/expression-context.js +1 -0
  175. package/dist/domain/domain-runtime/domain-context/index.d.ts +2 -0
  176. package/dist/domain/domain-runtime/domain-context/runtime-expression-context.d.ts +18 -0
  177. package/dist/domain/domain-runtime/domain-context/runtime-expression-context.js +1 -0
  178. package/dist/domain/domain-runtime/domain-context/selectors.d.ts +3 -3
  179. package/dist/domain/domain-runtime/domain-context/selectors.js +1 -1
  180. package/dist/domain/domain-runtime/domain-runtime.d.ts +8 -8
  181. package/dist/domain/domain-runtime/spec/index.d.ts +3 -0
  182. package/dist/domain/domain-runtime/spec/index.js +1 -1
  183. package/dist/domain/domain-runtime/spec/initialize.js +1 -1
  184. package/dist/domain/{expressions → domain-runtime/spec}/memoize-expression.d.ts +1 -1
  185. package/dist/domain/{actions → domain-runtime/spec}/prepare-action-implementations.d.ts +1 -1
  186. package/dist/domain/domain-runtime/spec/prepare-action-implementations.js +5 -0
  187. package/dist/domain/{expressions → domain-runtime/spec}/prepare-domain-expressions.d.ts +1 -1
  188. package/dist/domain/domain-runtime/spec/types.d.ts +1 -2
  189. package/dist/domain/extensions/angle-indicator.js +1 -0
  190. package/dist/domain/extensions/attribute-switch.js +1 -0
  191. package/dist/domain/{system-components → extensions}/autorotate-camera-component.d.ts +1 -1
  192. package/dist/domain/extensions/autorotate-camera-component.js +1 -0
  193. package/dist/domain/extensions/basic-sidebar-footer.js +1 -0
  194. package/dist/domain/extensions/camera-based-hidden-entity-object.js +1 -0
  195. package/dist/domain/extensions/camera-based-hidden-entity.js +1 -0
  196. package/dist/domain/extensions/canvas-config.js +1 -0
  197. package/dist/domain/extensions/canvas-custom-environment.js +1 -0
  198. package/dist/domain/extensions/canvas-padding.js +1 -0
  199. package/dist/domain/extensions/canvas-preset-environment.js +1 -0
  200. package/dist/domain/{system-components → extensions}/child-entity-recipe-hierarchy.d.ts +2 -2
  201. package/dist/domain/extensions/child-entity-recipe-hierarchy.js +1 -0
  202. package/dist/domain/extensions/client-side-image.js +1 -0
  203. package/dist/domain/extensions/color-value.js +1 -0
  204. package/dist/domain/{system-components → extensions}/common/angle-indicator-schema.d.ts +1 -1
  205. package/dist/domain/extensions/common/angle-indicator-schema.js +1 -0
  206. package/dist/domain/extensions/common/index.d.ts +4 -0
  207. package/dist/domain/extensions/common/index.js +1 -0
  208. package/dist/domain/{system-components → extensions}/custom-header.d.ts +1 -1
  209. package/dist/domain/extensions/custom-header.js +1 -0
  210. package/dist/domain/extensions/custom-price-footer.js +1 -0
  211. package/dist/domain/{system-components → extensions}/custom-sidebar-footer.d.ts +1 -1
  212. package/dist/domain/extensions/custom-sidebar-footer.js +1 -0
  213. package/dist/domain/extensions/dimension-indicator.js +1 -0
  214. package/dist/domain/{system-components → extensions}/editable-angle-indicator.d.ts +2 -1
  215. package/dist/domain/extensions/editable-angle-indicator.js +1 -0
  216. package/dist/domain/{system-components → extensions}/editable-distance-dimension-indicator.d.ts +2 -1
  217. package/dist/domain/extensions/editable-distance-dimension-indicator.js +1 -0
  218. package/dist/domain/{system-components → extensions}/editable-offset-indicator.d.ts +2 -1
  219. package/dist/domain/extensions/editable-offset-indicator.js +1 -0
  220. package/dist/domain/{system-components → extensions}/editable-size-indicator.d.ts +2 -1
  221. package/dist/domain/extensions/editable-size-indicator.js +1 -0
  222. package/dist/domain/{system-components → extensions}/entity-header.d.ts +1 -1
  223. package/dist/domain/extensions/entity-header.js +1 -0
  224. package/dist/domain/extensions/exit-tool-mode-fab.js +1 -0
  225. package/dist/domain/extensions/finalize-action.js +1 -0
  226. package/dist/domain/extensions/finalize-component.js +1 -0
  227. package/dist/domain/extensions/fit-selection-orthographic-camera-component.js +1 -0
  228. package/dist/domain/extensions/fit-selection-perspective-camera-component.js +1 -0
  229. package/dist/domain/extensions/fixed-header.js +1 -0
  230. package/dist/domain/extensions/floating-header.js +1 -0
  231. package/dist/domain/extensions/hidden-header.js +1 -0
  232. package/dist/domain/extensions/hidden-sidebar-footer.js +1 -0
  233. package/dist/domain/extensions/horizontal-tabs.js +1 -0
  234. package/dist/domain/extensions/index.d.ts +69 -0
  235. package/dist/domain/extensions/index.js +1 -0
  236. package/dist/domain/{system-components → extensions}/list-selector-dimension-indicator.d.ts +2 -1
  237. package/dist/domain/extensions/list-selector-dimension-indicator.js +1 -0
  238. package/dist/domain/extensions/multilingual-text-value.js +1 -0
  239. package/dist/domain/extensions/navigation-steps.js +1 -0
  240. package/dist/domain/extensions/offset-anchors.js +1 -0
  241. package/dist/domain/extensions/offset-indicator.js +1 -0
  242. package/dist/domain/extensions/offset.js +1 -0
  243. package/dist/domain/extensions/other-action.js +1 -0
  244. package/dist/domain/{system-components → extensions}/property-page.d.ts +1 -1
  245. package/dist/domain/extensions/property-page.js +1 -0
  246. package/dist/domain/extensions/read-sidebar-footer.js +1 -0
  247. package/dist/domain/{system-components → extensions}/replace-entity-recipe-hierarchy.d.ts +2 -2
  248. package/dist/domain/extensions/replace-entity-recipe-hierarchy.js +1 -0
  249. package/dist/domain/extensions/rotatable.js +1 -0
  250. package/dist/domain/extensions/rotation-handle.js +1 -0
  251. package/dist/domain/extensions/save-template-thumbnail.js +1 -0
  252. package/dist/domain/{system-components → extensions}/scene-entity-add-fab.d.ts +1 -1
  253. package/dist/domain/extensions/scene-entity-add-fab.js +1 -0
  254. package/dist/domain/extensions/scene-entity-animation.js +1 -0
  255. package/dist/domain/extensions/scene-entity-control.js +1 -0
  256. package/dist/domain/{system-components → extensions}/scene-entity-delete-fab.d.ts +1 -1
  257. package/dist/domain/extensions/scene-entity-delete-fab.js +1 -0
  258. package/dist/domain/extensions/scene-entity-floor-object.js +1 -0
  259. package/dist/domain/{system-components → extensions}/scene-entity-html-hotspot.d.ts +1 -1
  260. package/dist/domain/extensions/scene-entity-html-hotspot.js +1 -0
  261. package/dist/domain/{system-components → extensions}/scene-entity-navigation-hotspot.d.ts +1 -1
  262. package/dist/domain/extensions/scene-entity-navigation-hotspot.js +1 -0
  263. package/dist/domain/{system-components → extensions}/scene-entity-object-html-hotspot.d.ts +1 -1
  264. package/dist/domain/extensions/scene-entity-object-html-hotspot.js +1 -0
  265. package/dist/domain/{system-components → extensions}/scene-entity-select-hotspot.d.ts +1 -1
  266. package/dist/domain/extensions/scene-entity-select-hotspot.js +1 -0
  267. package/dist/domain/extensions/scene-entity-wall-object.js +1 -0
  268. package/dist/domain/extensions/selectable-component.js +1 -0
  269. package/dist/domain/extensions/sidebar-tabs.js +1 -0
  270. package/dist/domain/extensions/simple-summary.js +1 -0
  271. package/dist/domain/extensions/size.js +1 -0
  272. package/dist/domain/extensions/sketching-draw.js +1 -0
  273. package/dist/domain/{system-components → extensions}/sketching-edit.d.ts +1 -1
  274. package/dist/domain/extensions/sketching-edit.js +1 -0
  275. package/dist/domain/extensions/summary-component.js +1 -0
  276. package/dist/domain/extensions/text-value.js +1 -0
  277. package/dist/domain/extensions/tool-controls.js +1 -0
  278. package/dist/domain/{system-components → extensions}/tool-menu-fab.d.ts +1 -1
  279. package/dist/domain/extensions/tool-menu-fab.js +1 -0
  280. package/dist/domain/{system-components → extensions}/toolbar.d.ts +1 -1
  281. package/dist/domain/extensions/toolbar.js +1 -0
  282. package/dist/domain/extensions/universal-sidebar-footer.js +1 -0
  283. package/dist/domain/extensions/view-controls.js +1 -0
  284. package/dist/domain/index.d.ts +2 -32
  285. package/dist/domain/index.js +1 -1
  286. package/dist/domain/projections/blender-projections/blender-projections.d.ts +1 -1
  287. package/dist/domain/projections/blender-projections/blender-projections.js +1 -1
  288. package/dist/domain/projections/composition-projections.js +1 -1
  289. package/dist/domain/projections/validation-projections.d.ts +1 -2
  290. package/dist/domain/projections/validation-projections.js +1 -1
  291. package/dist/domain/system-components/admin-sidebar.js +1 -1
  292. package/dist/domain/system-components/angle-dimension.js +1 -1
  293. package/dist/domain/system-components/application-config.js +1 -1
  294. package/dist/domain/system-components/attribute-selection.js +1 -1
  295. package/dist/domain/system-components/bounding-box-component.d.ts +1 -1
  296. package/dist/domain/system-components/bounding-box-component.js +1 -1
  297. package/dist/domain/system-components/bounding-sphere-component.d.ts +1 -1
  298. package/dist/domain/system-components/bounding-sphere-component.js +1 -1
  299. package/dist/domain/system-components/child-entity-recipes.d.ts +1 -1
  300. package/dist/domain/system-components/child-entity-recipes.js +1 -1
  301. package/dist/domain/system-components/child-entity-selection.d.ts +1 -2
  302. package/dist/domain/system-components/child-entity-selection.js +1 -1
  303. package/dist/domain/system-components/collision-box-geometry.d.ts +1 -1
  304. package/dist/domain/system-components/collision-box-geometry.js +1 -1
  305. package/dist/domain/system-components/collision-geometry.d.ts +1 -1
  306. package/dist/domain/system-components/collision-geometry.js +1 -1
  307. package/dist/domain/system-components/collision-point-geometry.d.ts +1 -1
  308. package/dist/domain/system-components/collision-point-geometry.js +1 -1
  309. package/dist/domain/system-components/common/index.d.ts +0 -4
  310. package/dist/domain/system-components/common/index.js +1 -1
  311. package/dist/domain/system-components/common/recipes.d.ts +1 -2
  312. package/dist/domain/system-components/constraint.d.ts +1 -1
  313. package/dist/domain/system-components/constraint.js +1 -1
  314. package/dist/domain/system-components/custom-scene-entity.js +1 -1
  315. package/dist/domain/system-components/detail.js +1 -1
  316. package/dist/domain/system-components/distance-dimension-select.js +1 -1
  317. package/dist/domain/system-components/distance-dimension.js +1 -1
  318. package/dist/domain/system-components/drag-handle.js +1 -1
  319. package/dist/domain/system-components/fit-entity-orthographic-camera-component.js +1 -1
  320. package/dist/domain/system-components/fit-entity-perspective-camera-component.js +1 -1
  321. package/dist/domain/system-components/fit-root-orthographic-camera-component.js +1 -1
  322. package/dist/domain/system-components/fit-root-perspective-camera-component.js +1 -1
  323. package/dist/domain/system-components/generic-dimension.js +1 -1
  324. package/dist/domain/system-components/hidden-entity.js +1 -1
  325. package/dist/domain/system-components/hotspot-drag-handle.d.ts +1 -2
  326. package/dist/domain/system-components/hotspot-drag-handle.js +1 -1
  327. package/dist/domain/system-components/index.d.ts +0 -68
  328. package/dist/domain/system-components/index.js +1 -1
  329. package/dist/domain/system-components/material-override-property-transition.js +1 -1
  330. package/dist/domain/system-components/material-override-transformer.js +1 -1
  331. package/dist/domain/system-components/material-swatch.js +1 -1
  332. package/dist/domain/system-components/navigation-page.js +1 -1
  333. package/dist/domain/system-components/navigation-panel-list.js +1 -1
  334. package/dist/domain/system-components/pivot-point.js +1 -1
  335. package/dist/domain/system-components/price.js +1 -1
  336. package/dist/domain/system-components/projected-entities.js +1 -1
  337. package/dist/domain/system-components/replace-entity-recipes.d.ts +1 -1
  338. package/dist/domain/system-components/replace-entity-recipes.js +1 -1
  339. package/dist/domain/system-components/scene-entity-ambient-light.js +1 -1
  340. package/dist/domain/system-components/scene-entity-box-object.js +1 -1
  341. package/dist/domain/system-components/scene-entity-directional-light.js +1 -1
  342. package/dist/domain/system-components/scene-entity-local-material-override.js +1 -1
  343. package/dist/domain/system-components/scene-entity-material-override.js +1 -1
  344. package/dist/domain/system-components/scene-entity-object-clip.js +1 -1
  345. package/dist/domain/system-components/scene-entity-object-decal.js +1 -1
  346. package/dist/domain/system-components/scene-entity-object-group.js +1 -1
  347. package/dist/domain/system-components/scene-entity-object-local-material-override.js +1 -1
  348. package/dist/domain/system-components/scene-entity-object-material-override.js +1 -1
  349. package/dist/domain/system-components/scene-entity-object-properties.js +1 -1
  350. package/dist/domain/system-components/scene-entity-object-remote-material-override.js +1 -1
  351. package/dist/domain/system-components/scene-entity-object-text-decal.js +1 -1
  352. package/dist/domain/system-components/scene-entity-object-transformer.js +1 -1
  353. package/dist/domain/system-components/scene-entity-object-transimissive-material-override.js +1 -1
  354. package/dist/domain/system-components/scene-entity-object.js +1 -1
  355. package/dist/domain/system-components/scene-entity-point-light.js +1 -1
  356. package/dist/domain/system-components/scene-entity-properties.js +1 -1
  357. package/dist/domain/system-components/scene-entity-rect-area-light.js +1 -1
  358. package/dist/domain/system-components/scene-entity-remote-material-override.js +1 -1
  359. package/dist/domain/system-components/scene-entity-remote-object.js +1 -1
  360. package/dist/domain/system-components/scene-entity-spot-light.js +1 -1
  361. package/dist/domain/system-components/scene-entity-transimissive-material-override.js +1 -1
  362. package/dist/domain/system-components/sketching-line.js +1 -1
  363. package/dist/domain/system-components/sketching-rectangle.js +1 -1
  364. package/dist/domain/system-components/sketching.js +1 -1
  365. package/dist/domain/system-components/snap-axis.js +1 -1
  366. package/dist/domain/system-components/snap-edge.js +1 -1
  367. package/dist/domain/system-components/snap-plane.js +1 -1
  368. package/dist/domain/system-components/snap-point.js +1 -1
  369. package/dist/domain/system-components/static-orthographic-camera-component.d.ts +1 -1
  370. package/dist/domain/system-components/static-orthographic-camera-component.js +1 -1
  371. package/dist/domain/system-components/static-perspective-camera-component.d.ts +1 -1
  372. package/dist/domain/system-components/static-perspective-camera-component.js +1 -1
  373. package/dist/domain/utils/memo-eval.d.ts +2 -2
  374. package/dist/i18n/locales/cs/messages.js +1 -1
  375. package/dist/i18n/locales/da/messages.js +1 -1
  376. package/dist/i18n/locales/de/messages.js +1 -1
  377. package/dist/i18n/locales/de-AT/messages.js +1 -1
  378. package/dist/i18n/locales/en/messages.js +1 -1
  379. package/dist/i18n/locales/en-AU/messages.js +1 -1
  380. package/dist/i18n/locales/en-GB/messages.js +1 -1
  381. package/dist/i18n/locales/es/messages.js +1 -1
  382. package/dist/i18n/locales/fr/messages.js +1 -1
  383. package/dist/i18n/locales/hu/messages.js +1 -1
  384. package/dist/i18n/locales/it/messages.js +1 -1
  385. package/dist/i18n/locales/nl/messages.js +1 -1
  386. package/dist/i18n/locales/pl/messages.js +1 -1
  387. package/dist/i18n/locales/pt/messages.js +1 -1
  388. package/dist/i18n/locales/ro/messages.js +1 -1
  389. package/dist/i18n/locales/sk/messages.js +1 -1
  390. package/dist/i18n/locales/tr/messages.js +1 -1
  391. package/dist/legacy/domain-cli/gen/implementation.js +5 -5
  392. package/dist/legacy/domain-cli/gen/invariants.js +5 -3
  393. package/dist/legacy/domain-cli/utils/cache.d.ts +1 -1
  394. package/dist/legacy/domain-cli/utils/cache.js +1 -1
  395. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/env-example.d.ts +1 -1
  396. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/env-example.js +4 -0
  397. package/dist/phoenix/scripts/build-admin.js +1 -1
  398. package/dist/ui-sdk/theme/types.d.ts +1 -1
  399. package/dist/webhook/builders/common.d.ts +5 -0
  400. package/dist/webhook/builders/webhook-builder.js +1 -1
  401. package/package.json +3 -3
  402. package/dist/domain/actions/prepare-action-implementations.js +0 -5
  403. package/dist/domain/components/debug-state-component.js +0 -1
  404. package/dist/domain/components/domain-component-optic.js +0 -16
  405. package/dist/domain/components/drag-state-component.js +0 -1
  406. package/dist/domain/components/export-state-component.js +0 -1
  407. package/dist/domain/components/fullscreen-state-component.js +0 -1
  408. package/dist/domain/components/group-components-by-entity-id-and-name.js +0 -1
  409. package/dist/domain/components/hover-state-component.js +0 -1
  410. package/dist/domain/components/index.d.ts +0 -2
  411. package/dist/domain/components/index.js +0 -1
  412. package/dist/domain/components/navigation-state-component.js +0 -1
  413. package/dist/domain/components/selection-state-component.js +0 -1
  414. package/dist/domain/components/system-component-builder.js +0 -1
  415. package/dist/domain/components/system-virtual-entity.js +0 -1
  416. package/dist/domain/components/tool-state-component.js +0 -1
  417. package/dist/domain/components/view-state-component.js +0 -1
  418. package/dist/domain/components/viewport-state-component.js +0 -1
  419. package/dist/domain/domain-context/recipe-system/recipes.js +0 -1
  420. package/dist/domain/expressions/constant-expressions.js +0 -1
  421. package/dist/domain/expressions/custom-expression.js +0 -1
  422. package/dist/domain/expressions/index.d.ts +0 -1
  423. package/dist/domain/expressions/index.js +0 -1
  424. package/dist/domain/invariants/custom-invariants.js +0 -1
  425. package/dist/domain/invariants/invariants.js +0 -1
  426. package/dist/domain/invariants/violation-component.js +0 -1
  427. package/dist/domain/relations/all-of-type-relation.js +0 -1
  428. package/dist/domain/relations/component-factories.js +0 -1
  429. package/dist/domain/relations/composed-of.js +0 -1
  430. package/dist/domain/relations/indirect-relation.js +0 -1
  431. package/dist/domain/relations/reference-component.js +0 -1
  432. package/dist/domain/system-components/angle-indicator.js +0 -1
  433. package/dist/domain/system-components/attribute-switch.js +0 -1
  434. package/dist/domain/system-components/autorotate-camera-component.js +0 -1
  435. package/dist/domain/system-components/basic-sidebar-footer.js +0 -1
  436. package/dist/domain/system-components/camera-based-hidden-entity-object.js +0 -1
  437. package/dist/domain/system-components/camera-based-hidden-entity.js +0 -1
  438. package/dist/domain/system-components/canvas-config.js +0 -1
  439. package/dist/domain/system-components/canvas-custom-environment.js +0 -1
  440. package/dist/domain/system-components/canvas-padding.js +0 -1
  441. package/dist/domain/system-components/canvas-preset-environment.js +0 -1
  442. package/dist/domain/system-components/child-entity-recipe-hierarchy.js +0 -1
  443. package/dist/domain/system-components/client-side-image.js +0 -1
  444. package/dist/domain/system-components/color-value.js +0 -1
  445. package/dist/domain/system-components/common/angle-indicator-schema.js +0 -1
  446. package/dist/domain/system-components/custom-header.js +0 -1
  447. package/dist/domain/system-components/custom-price-footer.js +0 -1
  448. package/dist/domain/system-components/custom-sidebar-footer.js +0 -1
  449. package/dist/domain/system-components/dimension-indicator.js +0 -1
  450. package/dist/domain/system-components/editable-angle-indicator.js +0 -1
  451. package/dist/domain/system-components/editable-distance-dimension-indicator.js +0 -1
  452. package/dist/domain/system-components/editable-offset-indicator.js +0 -1
  453. package/dist/domain/system-components/editable-size-indicator.js +0 -1
  454. package/dist/domain/system-components/entity-header.js +0 -1
  455. package/dist/domain/system-components/exit-tool-mode-fab.js +0 -1
  456. package/dist/domain/system-components/finalize-action.js +0 -1
  457. package/dist/domain/system-components/finalize-component.js +0 -1
  458. package/dist/domain/system-components/fit-selection-orthographic-camera-component.js +0 -1
  459. package/dist/domain/system-components/fit-selection-perspective-camera-component.js +0 -1
  460. package/dist/domain/system-components/fixed-header.js +0 -1
  461. package/dist/domain/system-components/floating-header.js +0 -1
  462. package/dist/domain/system-components/hidden-header.js +0 -1
  463. package/dist/domain/system-components/hidden-sidebar-footer.js +0 -1
  464. package/dist/domain/system-components/horizontal-tabs.js +0 -1
  465. package/dist/domain/system-components/list-selector-dimension-indicator.js +0 -1
  466. package/dist/domain/system-components/multilingual-text-value.js +0 -1
  467. package/dist/domain/system-components/navigation-steps.js +0 -1
  468. package/dist/domain/system-components/offset-anchors.js +0 -1
  469. package/dist/domain/system-components/offset-indicator.js +0 -1
  470. package/dist/domain/system-components/offset.js +0 -1
  471. package/dist/domain/system-components/other-action.js +0 -1
  472. package/dist/domain/system-components/property-page.js +0 -1
  473. package/dist/domain/system-components/read-sidebar-footer.js +0 -1
  474. package/dist/domain/system-components/replace-entity-recipe-hierarchy.js +0 -1
  475. package/dist/domain/system-components/rotatable.js +0 -1
  476. package/dist/domain/system-components/rotation-handle.js +0 -1
  477. package/dist/domain/system-components/save-template-thumbnail.js +0 -1
  478. package/dist/domain/system-components/scene-entity-add-fab.js +0 -1
  479. package/dist/domain/system-components/scene-entity-animation.js +0 -1
  480. package/dist/domain/system-components/scene-entity-control.js +0 -1
  481. package/dist/domain/system-components/scene-entity-delete-fab.js +0 -1
  482. package/dist/domain/system-components/scene-entity-floor-object.js +0 -1
  483. package/dist/domain/system-components/scene-entity-html-hotspot.js +0 -1
  484. package/dist/domain/system-components/scene-entity-navigation-hotspot.js +0 -1
  485. package/dist/domain/system-components/scene-entity-object-html-hotspot.js +0 -1
  486. package/dist/domain/system-components/scene-entity-select-hotspot.js +0 -1
  487. package/dist/domain/system-components/scene-entity-wall-object.js +0 -1
  488. package/dist/domain/system-components/selectable-component.js +0 -1
  489. package/dist/domain/system-components/sidebar-tabs.js +0 -1
  490. package/dist/domain/system-components/simple-summary.js +0 -1
  491. package/dist/domain/system-components/size.js +0 -1
  492. package/dist/domain/system-components/sketching-draw.js +0 -1
  493. package/dist/domain/system-components/sketching-edit.js +0 -1
  494. package/dist/domain/system-components/summary-component.js +0 -1
  495. package/dist/domain/system-components/text-value.js +0 -1
  496. package/dist/domain/system-components/tool-controls.js +0 -1
  497. package/dist/domain/system-components/tool-menu-fab.js +0 -1
  498. package/dist/domain/system-components/toolbar.js +0 -1
  499. package/dist/domain/system-components/universal-sidebar-footer.js +0 -1
  500. package/dist/domain/system-components/view-controls.js +0 -1
  501. /package/dist/domain/{actions → core/action}/action-factory.js +0 -0
  502. /package/dist/domain/core/{action.js → action/action.js} +0 -0
  503. /package/dist/domain/{components → core/component}/component-reader-types.js +0 -0
  504. /package/dist/domain/{components → core/component}/legacy-filter.js +0 -0
  505. /package/dist/domain/{components → core/component}/system-component-filter.js +0 -0
  506. /package/dist/domain/{components → core/component}/system-virtual-entity.d.ts +0 -0
  507. /package/dist/domain/{components → core/component}/updates.js +0 -0
  508. /package/dist/domain/core/{expression.js → expression/aliased-expressions.js} +0 -0
  509. /package/dist/domain/{relations/reference-field.js → core/expression/expression.js} +0 -0
  510. /package/dist/domain/{invariants → core/invariant}/builtin-invariant.js +0 -0
  511. /package/dist/domain/{invariants → core/invariant}/violation-component.d.ts +0 -0
  512. /package/dist/domain/{invariants → core/invariant}/violation.js +0 -0
  513. /package/dist/domain/{relations → core/relation}/direct-relation.js +0 -0
  514. /package/dist/domain/{relations/relation-implementation.js → core/relation/reference-field.js} +0 -0
  515. /package/dist/domain/{relations → core/relation}/relation-factory.js +0 -0
  516. /package/dist/domain/core/{migrations.js → state/migrations.js} +0 -0
  517. /package/dist/domain/core/{state.js → state/state.js} +0 -0
  518. /package/dist/domain/{expressions → domain-runtime/spec}/memoize-expression.js +0 -0
  519. /package/dist/domain/{expressions → domain-runtime/spec}/prepare-domain-expressions.js +0 -0
  520. /package/dist/domain/{system-components → extensions}/angle-indicator.d.ts +0 -0
  521. /package/dist/domain/{system-components → extensions}/attribute-switch.d.ts +0 -0
  522. /package/dist/domain/{system-components → extensions}/basic-sidebar-footer.d.ts +0 -0
  523. /package/dist/domain/{system-components → extensions}/camera-based-hidden-entity-object.d.ts +0 -0
  524. /package/dist/domain/{system-components → extensions}/camera-based-hidden-entity.d.ts +0 -0
  525. /package/dist/domain/{system-components → extensions}/canvas-config.d.ts +0 -0
  526. /package/dist/domain/{system-components → extensions}/canvas-custom-environment.d.ts +0 -0
  527. /package/dist/domain/{system-components → extensions}/canvas-padding.d.ts +0 -0
  528. /package/dist/domain/{system-components → extensions}/canvas-preset-environment.d.ts +0 -0
  529. /package/dist/domain/{system-components → extensions}/client-side-image.d.ts +0 -0
  530. /package/dist/domain/{system-components → extensions}/color-value.d.ts +0 -0
  531. /package/dist/domain/{system-components → extensions}/common/dimension-indicator-schema.d.ts +0 -0
  532. /package/dist/domain/{system-components → extensions}/common/dimension-indicator-schema.js +0 -0
  533. /package/dist/domain/{system-components → extensions}/common/dimension-indicators.d.ts +0 -0
  534. /package/dist/domain/{system-components → extensions}/common/dimension-indicators.js +0 -0
  535. /package/dist/domain/{system-components → extensions}/common/editable-indicator-button-variant.d.ts +0 -0
  536. /package/dist/domain/{system-components → extensions}/common/editable-indicator-button-variant.js +0 -0
  537. /package/dist/domain/{system-components → extensions}/custom-price-footer.d.ts +0 -0
  538. /package/dist/domain/{system-components → extensions}/dimension-indicator.d.ts +0 -0
  539. /package/dist/domain/{system-components → extensions}/exit-tool-mode-fab.d.ts +0 -0
  540. /package/dist/domain/{system-components → extensions}/finalize-action.d.ts +0 -0
  541. /package/dist/domain/{system-components → extensions}/finalize-component.d.ts +0 -0
  542. /package/dist/domain/{system-components → extensions}/fit-selection-orthographic-camera-component.d.ts +0 -0
  543. /package/dist/domain/{system-components → extensions}/fit-selection-perspective-camera-component.d.ts +0 -0
  544. /package/dist/domain/{system-components → extensions}/fixed-header.d.ts +0 -0
  545. /package/dist/domain/{system-components → extensions}/floating-header.d.ts +0 -0
  546. /package/dist/domain/{system-components → extensions}/hidden-header.d.ts +0 -0
  547. /package/dist/domain/{system-components → extensions}/hidden-sidebar-footer.d.ts +0 -0
  548. /package/dist/domain/{system-components → extensions}/horizontal-tabs.d.ts +0 -0
  549. /package/dist/domain/{system-components → extensions}/multilingual-text-value.d.ts +0 -0
  550. /package/dist/domain/{system-components → extensions}/navigation-steps.d.ts +0 -0
  551. /package/dist/domain/{system-components → extensions}/offset-anchors.d.ts +0 -0
  552. /package/dist/domain/{system-components → extensions}/offset-indicator.d.ts +0 -0
  553. /package/dist/domain/{system-components → extensions}/offset.d.ts +0 -0
  554. /package/dist/domain/{system-components → extensions}/other-action.d.ts +0 -0
  555. /package/dist/domain/{system-components → extensions}/read-sidebar-footer.d.ts +0 -0
  556. /package/dist/domain/{system-components → extensions}/rotatable.d.ts +0 -0
  557. /package/dist/domain/{system-components → extensions}/rotation-handle.d.ts +0 -0
  558. /package/dist/domain/{system-components → extensions}/save-template-thumbnail.d.ts +0 -0
  559. /package/dist/domain/{system-components → extensions}/scene-entity-animation.d.ts +0 -0
  560. /package/dist/domain/{system-components → extensions}/scene-entity-control.d.ts +0 -0
  561. /package/dist/domain/{system-components → extensions}/scene-entity-floor-object.d.ts +0 -0
  562. /package/dist/domain/{system-components → extensions}/scene-entity-wall-object.d.ts +0 -0
  563. /package/dist/domain/{system-components → extensions}/selectable-component.d.ts +0 -0
  564. /package/dist/domain/{system-components → extensions}/sidebar-tabs.d.ts +0 -0
  565. /package/dist/domain/{system-components → extensions}/simple-summary.d.ts +0 -0
  566. /package/dist/domain/{system-components → extensions}/size.d.ts +0 -0
  567. /package/dist/domain/{system-components → extensions}/sketching-draw.d.ts +0 -0
  568. /package/dist/domain/{system-components → extensions}/summary-component.d.ts +0 -0
  569. /package/dist/domain/{system-components → extensions}/text-value.d.ts +0 -0
  570. /package/dist/domain/{system-components → extensions}/tool-controls.d.ts +0 -0
  571. /package/dist/domain/{system-components → extensions}/universal-sidebar-footer.d.ts +0 -0
  572. /package/dist/domain/{system-components → extensions}/view-controls.d.ts +0 -0
@@ -201,7 +201,7 @@ export interface paths {
201
201
  readonly path?: never
202
202
  readonly cookie?: never
203
203
  }
204
- /** @description Load the caller's latest assistant thread on the configuration with its active run, newest window first. The `x-assistant-thread-continuable` response header is `false` when the thread has a different setup or is closed; a chat request then answers 409. */
204
+ /** @description Load the caller's latest assistant thread on the configuration with its active run, newest window first. The `x-assistant-thread-continuable` response header is `false` when the thread cannot be continued with this setup or is closed; a chat request then answers 409, and the thread continues once it is compacted. The `x-assistant-previous-thread` response header carries the id of the closed thread this one continues, when there is one. */
205
205
  readonly get: operations['getAssistantThread']
206
206
  readonly put?: never
207
207
  /** @description Run the experimental assistant on the caller's thread of the configuration, or replay the run when the request carries `Last-Event-ID`. Answers 409 when the thread cannot be continued with this setup or another run is still answering, and 503 while the server shuts down; sent again, the message reaches another instance. Answers 403 unless the customer has the AI Assistant feature flag on. */
@@ -212,6 +212,23 @@ export interface paths {
212
212
  readonly patch?: never
213
213
  readonly trace?: never
214
214
  }
215
+ readonly '/configurations/{configurationId}/assistant/chat/compact': {
216
+ readonly parameters: {
217
+ readonly query?: never
218
+ readonly header?: never
219
+ readonly path?: never
220
+ readonly cookie?: never
221
+ }
222
+ readonly get?: never
223
+ readonly put?: never
224
+ /** @description Continue the caller's latest assistant thread on the configuration, which cannot be continued with this setup, in a new one: the thread is summarized and closed, and its successor starts from the summary. Answers 409 when there is no thread, the latest one can be continued as it is, or one of its runs is still running, and 502 when the summary could not be made; nothing is closed then and the request can be sent again. */
225
+ readonly post: operations['compactAssistantThread']
226
+ readonly delete?: never
227
+ readonly options?: never
228
+ readonly head?: never
229
+ readonly patch?: never
230
+ readonly trace?: never
231
+ }
215
232
  readonly '/configurations/{configurationId}/assistant/chat/runs': {
216
233
  readonly parameters: {
217
234
  readonly query?: never
@@ -246,6 +263,23 @@ export interface paths {
246
263
  readonly patch?: never
247
264
  readonly trace?: never
248
265
  }
266
+ readonly '/configurations/{configurationId}/assistant/chat/threads/{threadId}': {
267
+ readonly parameters: {
268
+ readonly query?: never
269
+ readonly header?: never
270
+ readonly path?: never
271
+ readonly cookie?: never
272
+ }
273
+ /** @description Load one of the caller's assistant threads on the configuration by the id a thread read named in `x-assistant-previous-thread`, newest window first. The response carries that header again when the thread itself continues an earlier one. Answers 404 for a thread that is not the caller's on this configuration. */
274
+ readonly get: operations['getAssistantEarlierThread']
275
+ readonly put?: never
276
+ readonly post?: never
277
+ readonly delete?: never
278
+ readonly options?: never
279
+ readonly head?: never
280
+ readonly patch?: never
281
+ readonly trace?: never
282
+ }
249
283
  readonly '/configurations/{configurationId}/chat': {
250
284
  readonly parameters: {
251
285
  readonly query?: never
@@ -2571,6 +2605,97 @@ export interface operations {
2571
2605
  }
2572
2606
  }
2573
2607
  }
2608
+ readonly compactAssistantThread: {
2609
+ readonly parameters: {
2610
+ readonly query?: never
2611
+ readonly header?: never
2612
+ readonly path: {
2613
+ /** @description The configuration on which the caller's assistant thread is used. */
2614
+ readonly configurationId: components['schemas']['ConfigurationUuid']
2615
+ }
2616
+ readonly cookie?: never
2617
+ }
2618
+ readonly requestBody?: never
2619
+ readonly responses: {
2620
+ /** @description The thread was closed and its successor opened. */
2621
+ readonly 200: {
2622
+ headers: {
2623
+ readonly [name: string]: unknown
2624
+ }
2625
+ content: {
2626
+ readonly 'application/json': {
2627
+ /** @description The closed thread the new one continues. */
2628
+ readonly previousThreadId: string
2629
+ /** @description The new thread, which the next chat request runs on. */
2630
+ readonly threadId: string
2631
+ }
2632
+ }
2633
+ }
2634
+ /** @description Bad Request! */
2635
+ readonly 400: {
2636
+ headers: {
2637
+ readonly [name: string]: unknown
2638
+ }
2639
+ content: {
2640
+ readonly 'application/json': components['schemas']['BadRequestError']
2641
+ }
2642
+ }
2643
+ /** @description Unauthorized! */
2644
+ readonly 401: {
2645
+ headers: {
2646
+ readonly [name: string]: unknown
2647
+ }
2648
+ content: {
2649
+ readonly 'application/json': components['schemas']['UnauthorizedError']
2650
+ }
2651
+ }
2652
+ /** @description Forbidden! */
2653
+ readonly 403: {
2654
+ headers: {
2655
+ readonly [name: string]: unknown
2656
+ }
2657
+ content: {
2658
+ readonly 'application/json': components['schemas']['ForbiddenError']
2659
+ }
2660
+ }
2661
+ /** @description Not Found! */
2662
+ readonly 404: {
2663
+ headers: {
2664
+ readonly [name: string]: unknown
2665
+ }
2666
+ content: {
2667
+ readonly 'application/json': components['schemas']['NotFoundError']
2668
+ }
2669
+ }
2670
+ /** @description Conflict! */
2671
+ readonly 409: {
2672
+ headers: {
2673
+ readonly [name: string]: unknown
2674
+ }
2675
+ content: {
2676
+ readonly 'application/json': components['schemas']['ConflictError']
2677
+ }
2678
+ }
2679
+ /** @description Bad Gateway! */
2680
+ readonly 502: {
2681
+ headers: {
2682
+ readonly [name: string]: unknown
2683
+ }
2684
+ content: {
2685
+ readonly 'application/json': components['schemas']['BadGatewayError']
2686
+ }
2687
+ }
2688
+ /** @description An unexpected error occurred! */
2689
+ readonly default: {
2690
+ headers: {
2691
+ readonly [name: string]: unknown
2692
+ }
2693
+ content: {
2694
+ readonly 'application/json': components['schemas']['DefaultResponse']
2695
+ }
2696
+ }
2697
+ }
2698
+ }
2574
2699
  readonly replayAssistantRun: {
2575
2700
  readonly parameters: {
2576
2701
  readonly query: {
@@ -2723,6 +2848,92 @@ export interface operations {
2723
2848
  }
2724
2849
  }
2725
2850
  }
2851
+ readonly getAssistantEarlierThread: {
2852
+ readonly parameters: {
2853
+ readonly query?: {
2854
+ /** @description Cursor of the next older window. */
2855
+ readonly before?: string
2856
+ /** @description Newest window size of the thread; the whole thread when omitted. */
2857
+ readonly limit?: number
2858
+ }
2859
+ readonly header?: never
2860
+ readonly path: {
2861
+ /** @description The configuration on which the caller's assistant thread is used. */
2862
+ readonly configurationId: components['schemas']['ConfigurationUuid']
2863
+ /** @description The thread to read. */
2864
+ readonly threadId: string
2865
+ }
2866
+ readonly cookie?: never
2867
+ }
2868
+ readonly requestBody?: never
2869
+ readonly responses: {
2870
+ /** @description The thread transcript. */
2871
+ readonly 200: {
2872
+ headers: {
2873
+ readonly [name: string]: unknown
2874
+ }
2875
+ content: {
2876
+ readonly 'application/json': {
2877
+ readonly [key: string]: unknown
2878
+ }
2879
+ }
2880
+ }
2881
+ /** @description Bad Request! */
2882
+ readonly 400: {
2883
+ headers: {
2884
+ readonly [name: string]: unknown
2885
+ }
2886
+ content: {
2887
+ readonly 'application/json': components['schemas']['BadRequestError']
2888
+ }
2889
+ }
2890
+ /** @description Unauthorized! */
2891
+ readonly 401: {
2892
+ headers: {
2893
+ readonly [name: string]: unknown
2894
+ }
2895
+ content: {
2896
+ readonly 'application/json': components['schemas']['UnauthorizedError']
2897
+ }
2898
+ }
2899
+ /** @description Forbidden! */
2900
+ readonly 403: {
2901
+ headers: {
2902
+ readonly [name: string]: unknown
2903
+ }
2904
+ content: {
2905
+ readonly 'application/json': components['schemas']['ForbiddenError']
2906
+ }
2907
+ }
2908
+ /** @description Not Found! */
2909
+ readonly 404: {
2910
+ headers: {
2911
+ readonly [name: string]: unknown
2912
+ }
2913
+ content: {
2914
+ readonly 'application/json': components['schemas']['NotFoundError']
2915
+ }
2916
+ }
2917
+ /** @description Bad Gateway! */
2918
+ readonly 502: {
2919
+ headers: {
2920
+ readonly [name: string]: unknown
2921
+ }
2922
+ content: {
2923
+ readonly 'application/json': components['schemas']['BadGatewayError']
2924
+ }
2925
+ }
2926
+ /** @description An unexpected error occurred! */
2927
+ readonly default: {
2928
+ headers: {
2929
+ readonly [name: string]: unknown
2930
+ }
2931
+ content: {
2932
+ readonly 'application/json': components['schemas']['DefaultResponse']
2933
+ }
2934
+ }
2935
+ }
2936
+ }
2726
2937
  readonly getChatConversation: {
2727
2938
  readonly parameters: {
2728
2939
  readonly query?: never
@@ -1,7 +1,7 @@
1
1
  import type { AnyClientTool } from '@tanstack/ai';
2
2
  import { type UIMessage } from '@tanstack/ai-client';
3
3
  import { type ObservableWithLastValue } from '@salsita-ai/common/utils';
4
- import type { AuthorizedPhoenixApiClient } from '#package/client';
4
+ import { type AuthorizedPhoenixApiClient } from '#package/client';
5
5
  import type { DomainContextSelectors, DomainServicesSelectors, InitializableSystem, SpecSelectors } from '#package/domain';
6
6
  import type { ConfiguratorExtensionSelectors } from '../../selectors.js';
7
7
  /** A tool of the assistant that the model calls and the browser runs, as the chat client accepts it. */
@@ -39,6 +39,25 @@ export interface AssistantChatSnapshot {
39
39
  readonly isContinuable: boolean;
40
40
  /** False until the first request of the chat, the thread read, was answered or failed. */
41
41
  readonly isLoaded: boolean;
42
+ /**
43
+ * True while a thread this session may not continue is being continued in a new one, which the
44
+ * user's next message starts; see {@link AssistantSystem.resume}.
45
+ */
46
+ readonly isResuming: boolean;
47
+ /**
48
+ * The closed threads the painted thread continues, oldest first: the ones that were resumed while
49
+ * the chat was open, and the ones loaded with {@link AssistantSystem.loadEarlierThread}.
50
+ */
51
+ readonly earlierThreads: ReadonlyArray<AssistantEarlierThreadSnapshot>;
52
+ /** True when the server holds a thread older than the oldest painted one. */
53
+ readonly hasEarlierThread: boolean;
54
+ /** True while that older thread is being loaded. */
55
+ readonly isLoadingEarlierThread: boolean;
56
+ }
57
+ /** A closed thread of the conversation as the panel paints it above the thread that continues it. */
58
+ export interface AssistantEarlierThreadSnapshot {
59
+ readonly threadId: string;
60
+ readonly messages: ReadonlyArray<UIMessage>;
42
61
  }
43
62
  /**
44
63
  * The built-in assistant panel as a layout and the toolbar button see it: whether it is open, and
@@ -77,6 +96,20 @@ export declare class AssistantSystem implements InitializableSystem {
77
96
  * background. Each leaves the set when its reply ends or when a new chat takes its thread over.
78
97
  */
79
98
  private readonly _finishing;
99
+ /**
100
+ * The thread before the oldest painted one, as the server named it; nothing when the painted
101
+ * threads start the conversation. `hasEarlierThread` of the chat says whether it is set.
102
+ */
103
+ private _olderThreadId;
104
+ /** The resume that is running, so two sends that find the thread locked share one. */
105
+ private _resuming;
106
+ /**
107
+ * Identity of the chain of threads that is painted. A resumed chat keeps it, because its new
108
+ * thread continues the same chain; any other new chat starts another one.
109
+ */
110
+ private _chain;
111
+ /** The earlier thread that is being loaded, so a second press loads nothing twice. */
112
+ private _loadingThreadId;
80
113
  private readonly _recorder;
81
114
  /** The recorder's subscription to the committed emissions of the store; made by the first `initialize()`. */
82
115
  private _recording;
@@ -118,7 +151,7 @@ export declare class AssistantSystem implements InitializableSystem {
118
151
  * not interrupted, so an `apply` that has started may still commit. The background reply keeps
119
152
  * the configuration and the authorized client it started with.
120
153
  *
121
- * The background reply ends early when a new chat starts for the same configuration, which is
154
+ * The background reply is disconnected when a new chat starts for the same configuration, which is
122
155
  * what opening the configuration again does: see `_takeOverThread`.
123
156
  */
124
157
  activate: () => (() => void);
@@ -132,9 +165,29 @@ export declare class AssistantSystem implements InitializableSystem {
132
165
  * send while it waits on such a call, so the wait is given up first, and the server records for
133
166
  * the model that the call got no result.
134
167
  *
168
+ * A thread this session may not continue is resumed first, in a new thread; see `resume`. When
169
+ * that fails the message is not sent.
170
+ *
135
171
  * It never rejects: a message the client could not send is reported as the error of the chat.
136
172
  */
137
173
  send: (content: string) => Promise<void>;
174
+ /**
175
+ * Makes the chat ready for the next message. A thread the server no longer lets this session
176
+ * continue, because the assistant's setup changed since it was started, is compacted there: the
177
+ * server closes it and opens a thread that starts from its summary. The messages painted so far
178
+ * move to `earlierThreads`, and a new client takes the new thread over.
179
+ *
180
+ * Resolves to whether a message can be sent now: at once for a thread that can continue, and
181
+ * `false` when there is no chat or the compaction failed, which is reported as the error of the
182
+ * chat. It never rejects. Calling it again runs the compaction again. A compaction the server
183
+ * refuses with a conflict is not a failure: the thread is read again and `false` is returned.
184
+ */
185
+ resume: () => Promise<boolean>;
186
+ /**
187
+ * Loads the thread before the oldest painted one and paints it above. Does nothing when there is
188
+ * none or one is being loaded. A load that fails is logged and can be asked for again.
189
+ */
190
+ loadEarlierThread: () => Promise<void>;
138
191
  /**
139
192
  * Stops the reply on both sides. Closing the stream alone keeps the server run going, because a
140
193
  * closed connection is also how a reload looks and a reload must be able to rejoin the run.
@@ -148,6 +201,7 @@ export declare class AssistantSystem implements InitializableSystem {
148
201
  reloadThread: () => void;
149
202
  setOpen: (open: boolean) => void;
150
203
  setInputFocused: (isInputFocused: boolean) => void;
204
+ private _resume;
151
205
  private _committedState;
152
206
  private _patchPanel;
153
207
  /**
@@ -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 a}from"rxjs/operators";import{isShallowEqual as s}from"@salsita-ai/common/utils";import{AssistantRequestError as r}from"#package/client";import{createBrowserDetailsClientTool as n}from"./browser-details.js";import{ChangeRecorder as o}from"./change-recorder.js";import{createApplyClientTool as h,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;_chain={};_loadingThreadId=null;_recorder;_recording=null;constructor(e){this._context=e;let{configuratorExtensionSelectors:t,domainContextSelectors:i,domainServicesSelectors:a,specSelectors:s}=e;this._recorder=new o({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:()=>s.getAssistant()?.fields??u,resolveLocalizable:e=>a.getResolveLocalizable()(e)});let r={getGraphQLSystem:()=>t.getGraphQLSystem(),getStoreSystem:()=>i.getStoreSystem(),getActiveMode:()=>i.getActiveMode(),clearChanges:()=>this._recorder.clear(this._committedState())};this._tools=[n(),l(r),h(r)]}chat$=this._chat;panel$=this._panel;initialize=()=>{let{committed:e}=this._context.domainContextSelectors.getStoreSystem().stateSlices;this._recording??=e.pipe(a(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{client:i}=t;i.getIsLoading()||null===i.getResumeState()||i.stop();let a={changes:this._recorder.take(this._committedState())};try{await i.sendMessage({content:e,metadata:a})}catch(i){let e=i instanceof Error?i:Error(String(i));t.generation.active&&this._chat.next({...this._chat.value,error:e}),this._context.domainServicesSelectors.getLogger().error("The assistant message could not be sent",{},e)}};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 a=await e.authorizedClient.getAssistantEarlierThread(e.configurationId,t,50);if(this._chain!==i||this._olderThreadId!==t)return;this._olderThreadId=a.previousThreadId,this._chat.next({...this._chat.value,earlierThreads:[{threadId:t,messages:a.messages},...this._chat.value.earlierThreads],hasEarlierThread:null!==a.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})};_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:a,hasEarlierThread:s}=this._chat.value;return e.generation.active=!1,this._current=null,e.client.stop(),e.dispose(),this._chat.next({...c,earlierThreads:[...a,{threadId:t,messages:i}],hasEarlierThread:s,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};s(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},a=this._context.getConfigurationId();this._takeOverThread(a);let r=this._context.getAuthorizedClient(),n=()=>r.getAssistantChatConnection(a),o=e=>{if(!i.active)return;let t={...this._chat.value,...e};s(t,this._chat.value)||this._chat.next(t)},h=async(e,t)=>{let a=await fetch(e,t).finally(()=>o({isLoaded:!0})),s=a.headers.get("x-assistant-thread-continuable");return null!=s&&i.active&&0===this._chat.value.earlierThreads.length&&(this._olderThreadId=a.headers.get("x-assistant-previous-thread")),o({failedStatus:a.ok?void 0:a.status,...null!=s&&{isContinuable:"false"!==s,hasEarlierThread:null!==this._olderThreadId}}),a},l=async()=>({headers:await n().headers(),fetchClient:h}),c=t(()=>n().url,l),d=t(()=>`${n().url}/runs`,l),u=this._tools.map(e=>({...e,execute:(t,a)=>i.active?e.execute?.(t,a):_})),m=new e({threadId:`assistant:${a}`,connection:{...c,joinRun:d.joinRun},persistence:!0,history:{pageSize:50},tools:u,onMessagesChange:e=>o({messages:e}),onLoadingChange:e=>{let t=i.active&&this._chat.value.isLoading;o({isLoading:e}),!e&&g(m)&&(i.active?t&&!this._panel.value.open&&this._patchPanel({hasUnreadReply:!0}):f())},onErrorChange:e=>{i.active&&e!==this._chat.value.error&&(o({error:e}),e&&this._context.domainServicesSelectors.getLogger().error("The assistant request failed",{status:this._chat.value.failedStatus},e))}}),v=!1,f=()=>{v||(v=!0,this._finishing.delete(p),m.dispose())},p={client:m,configurationId:a,generation:i,authorizedClient:r,getConnection:n,dispose:f};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._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-13T05:23:14.254Z",
2
+ "generatedAt": "2026-10-13T14:26:25.287Z",
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