@oxy.so/bloom 7.0.0 → 7.1.0

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 (517) hide show
  1. package/assets/character-runtime/README.md +55 -0
  2. package/assets/character-runtime/appearance-codec.mjs +149 -0
  3. package/assets/character-runtime/integrity.json +6 -0
  4. package/assets/character-runtime/legacy-engine.mjs +105 -0
  5. package/assets/character-runtime/legacy-geometry.mjs +166 -0
  6. package/assets/character-runtime/legacy-worker.mjs +85 -0
  7. package/assets/character-runtime/orbit-characters.data +0 -0
  8. package/assets/character-runtime/orbit-characters.mjs +30 -0
  9. package/assets/character-runtime/orbit-characters.wasm +0 -0
  10. package/assets/character-runtime/preparation-worker.mjs +19 -0
  11. package/assets/character-runtime/runtime.mjs +820 -0
  12. package/assets/character-runtime/thumbnails/eyes/crescent_inset.png +0 -0
  13. package/assets/character-runtime/thumbnails/eyes/dots.png +0 -0
  14. package/assets/character-runtime/thumbnails/eyes/double_highlights.png +0 -0
  15. package/assets/character-runtime/thumbnails/eyes/highlight_capsules.png +0 -0
  16. package/assets/character-runtime/thumbnails/eyes/oval.png +0 -0
  17. package/assets/character-runtime/thumbnails/eyes/round_inset.png +0 -0
  18. package/assets/character-runtime/thumbnails/eyes/sleepy_lids.png +0 -0
  19. package/assets/character-runtime/thumbnails/eyes/sparkle_capsules.png +0 -0
  20. package/assets/character-runtime/thumbnails/eyes/swept_lids.png +0 -0
  21. package/assets/character-runtime/thumbnails/shapes/capsule.png +0 -0
  22. package/assets/character-runtime/thumbnails/shapes/circle.png +0 -0
  23. package/assets/character-runtime/thumbnails/shapes/circle_two_ears.png +0 -0
  24. package/assets/character-runtime/thumbnails/shapes/four_lobed_butterfly.png +0 -0
  25. package/assets/character-runtime/thumbnails/shapes/heart.png +0 -0
  26. package/assets/character-runtime/thumbnails/shapes/rounded_cube.png +0 -0
  27. package/assets/character-runtime/thumbnails/shapes/rounded_diamond.png +0 -0
  28. package/assets/character-runtime/thumbnails/shapes/rounded_head_two_ears.png +0 -0
  29. package/assets/character-runtime/thumbnails/shapes/rounded_triangle.png +0 -0
  30. package/assets/character-runtime/thumbnails/shapes/six_lobed_flower.png +0 -0
  31. package/assets/character-runtime/thumbnails/shapes/twelve_scalloped_rosette.png +0 -0
  32. package/docs/adoption-matrix.mdx +9 -9
  33. package/docs/agent-avatar.mdx +35 -10
  34. package/docs/agent-creator.mdx +12 -4
  35. package/docs/multi-agent-chat.mdx +12 -0
  36. package/docs/project-board.mdx +3 -3
  37. package/lib/commonjs/agent-avatar/AgentAvatar.js +15 -203
  38. package/lib/commonjs/agent-avatar/AgentAvatar.js.map +1 -1
  39. package/lib/commonjs/agent-avatar/AgentAvatarProvider.js +64 -0
  40. package/lib/commonjs/agent-avatar/AgentAvatarProvider.js.map +1 -0
  41. package/lib/commonjs/agent-avatar/CharacterAvatar.js +211 -0
  42. package/lib/commonjs/agent-avatar/CharacterAvatar.js.map +1 -0
  43. package/lib/commonjs/agent-avatar/ProceduralAvatar.js +216 -0
  44. package/lib/commonjs/agent-avatar/ProceduralAvatar.js.map +1 -0
  45. package/lib/commonjs/agent-avatar/artwork.js +4 -3
  46. package/lib/commonjs/agent-avatar/artwork.js.map +1 -1
  47. package/lib/commonjs/agent-avatar/avatar-color.js +16 -0
  48. package/lib/commonjs/agent-avatar/avatar-color.js.map +1 -0
  49. package/lib/commonjs/agent-avatar/character-html.js +25 -0
  50. package/lib/commonjs/agent-avatar/character-html.js.map +1 -0
  51. package/lib/commonjs/agent-avatar/character-runtime-module.js +39 -0
  52. package/lib/commonjs/agent-avatar/character-runtime-module.js.map +1 -0
  53. package/lib/commonjs/agent-avatar/character-webview.js +18 -0
  54. package/lib/commonjs/agent-avatar/character-webview.js.map +1 -0
  55. package/lib/commonjs/agent-avatar/config-character.js +36 -0
  56. package/lib/commonjs/agent-avatar/config-character.js.map +1 -0
  57. package/lib/commonjs/agent-avatar/context.js +3 -1
  58. package/lib/commonjs/agent-avatar/context.js.map +1 -1
  59. package/lib/commonjs/agent-avatar/index.js +7 -0
  60. package/lib/commonjs/agent-avatar/index.js.map +1 -1
  61. package/lib/commonjs/agent-avatar/legacy-contours.js +57 -0
  62. package/lib/commonjs/agent-avatar/legacy-contours.js.map +1 -0
  63. package/lib/commonjs/agent-avatar/legacy-recipe.js +112 -0
  64. package/lib/commonjs/agent-avatar/legacy-recipe.js.map +1 -0
  65. package/lib/commonjs/agent-avatar/messages.js +2 -1
  66. package/lib/commonjs/agent-avatar/messages.js.map +1 -1
  67. package/lib/commonjs/agent-avatar/model.js +2 -0
  68. package/lib/commonjs/agent-avatar/model.js.map +1 -1
  69. package/lib/commonjs/agent-creator/AgentCreatorBase.js +245 -21
  70. package/lib/commonjs/agent-creator/AgentCreatorBase.js.map +1 -1
  71. package/lib/commonjs/agent-creator/CharacterControls.js +113 -0
  72. package/lib/commonjs/agent-creator/CharacterControls.js.map +1 -0
  73. package/lib/commonjs/agent-creator/EmotionPicker.js +51 -18
  74. package/lib/commonjs/agent-creator/EmotionPicker.js.map +1 -1
  75. package/lib/commonjs/agent-creator/ShapeArc.js +56 -26
  76. package/lib/commonjs/agent-creator/ShapeArc.js.map +1 -1
  77. package/lib/commonjs/agent-creator/ShapeSilhouette.js +62 -0
  78. package/lib/commonjs/agent-creator/ShapeSilhouette.js.map +1 -0
  79. package/lib/commonjs/agent-creator/constants.js +48 -1
  80. package/lib/commonjs/agent-creator/constants.js.map +1 -1
  81. package/lib/commonjs/agent-creator/messages.js +9 -0
  82. package/lib/commonjs/agent-creator/messages.js.map +1 -1
  83. package/lib/commonjs/agent-creator/shared.js +7 -10
  84. package/lib/commonjs/agent-creator/shared.js.map +1 -1
  85. package/lib/commonjs/agent-thinking/AgentThinking.js +4 -62
  86. package/lib/commonjs/agent-thinking/AgentThinking.js.map +1 -1
  87. package/lib/commonjs/agent-thinking/ThinkingLabel.js +77 -0
  88. package/lib/commonjs/agent-thinking/ThinkingLabel.js.map +1 -0
  89. package/lib/commonjs/chart-cards/TokensChartCard.js +20 -5
  90. package/lib/commonjs/chart-cards/TokensChartCard.js.map +1 -1
  91. package/lib/commonjs/locale/translations/ar.js +11 -1
  92. package/lib/commonjs/locale/translations/ar.js.map +1 -1
  93. package/lib/commonjs/locale/translations/bn.js +11 -1
  94. package/lib/commonjs/locale/translations/bn.js.map +1 -1
  95. package/lib/commonjs/locale/translations/ca.js +11 -1
  96. package/lib/commonjs/locale/translations/ca.js.map +1 -1
  97. package/lib/commonjs/locale/translations/de.js +11 -1
  98. package/lib/commonjs/locale/translations/de.js.map +1 -1
  99. package/lib/commonjs/locale/translations/es.js +11 -1
  100. package/lib/commonjs/locale/translations/es.js.map +1 -1
  101. package/lib/commonjs/locale/translations/fr.js +11 -1
  102. package/lib/commonjs/locale/translations/fr.js.map +1 -1
  103. package/lib/commonjs/locale/translations/hi.js +11 -1
  104. package/lib/commonjs/locale/translations/hi.js.map +1 -1
  105. package/lib/commonjs/locale/translations/id.js +11 -1
  106. package/lib/commonjs/locale/translations/id.js.map +1 -1
  107. package/lib/commonjs/locale/translations/it.js +11 -1
  108. package/lib/commonjs/locale/translations/it.js.map +1 -1
  109. package/lib/commonjs/locale/translations/ja.js +11 -1
  110. package/lib/commonjs/locale/translations/ja.js.map +1 -1
  111. package/lib/commonjs/locale/translations/pt.js +11 -1
  112. package/lib/commonjs/locale/translations/pt.js.map +1 -1
  113. package/lib/commonjs/locale/translations/ru.js +11 -1
  114. package/lib/commonjs/locale/translations/ru.js.map +1 -1
  115. package/lib/commonjs/locale/translations/tr.js +11 -1
  116. package/lib/commonjs/locale/translations/tr.js.map +1 -1
  117. package/lib/commonjs/locale/translations/zh.js +11 -1
  118. package/lib/commonjs/locale/translations/zh.js.map +1 -1
  119. package/lib/commonjs/multi-agent-chat/AvatarHandoff.js +12 -10
  120. package/lib/commonjs/multi-agent-chat/AvatarHandoff.js.map +1 -1
  121. package/lib/commonjs/multi-agent-chat/ChatAgentProfile.js +97 -0
  122. package/lib/commonjs/multi-agent-chat/ChatAgentProfile.js.map +1 -0
  123. package/lib/commonjs/multi-agent-chat/EditorRail.js +4 -0
  124. package/lib/commonjs/multi-agent-chat/EditorRail.js.map +1 -1
  125. package/lib/commonjs/multi-agent-chat/MultiAgentChatBase.js +89 -126
  126. package/lib/commonjs/multi-agent-chat/MultiAgentChatBase.js.map +1 -1
  127. package/lib/commonjs/multi-agent-chat/ReplyRow.js +8 -11
  128. package/lib/commonjs/multi-agent-chat/ReplyRow.js.map +1 -1
  129. package/lib/commonjs/multi-agent-chat/handoff.js +5 -5
  130. package/lib/commonjs/multi-agent-chat/handoff.js.map +1 -1
  131. package/lib/commonjs/project-board/CreateTicketDialog.js +33 -2
  132. package/lib/commonjs/project-board/CreateTicketDialog.js.map +1 -1
  133. package/lib/commonjs/project-board/ProjectBoardBase.js +137 -38
  134. package/lib/commonjs/project-board/ProjectBoardBase.js.map +1 -1
  135. package/lib/commonjs/project-board/TicketCornerGenieSurface.web.js +34 -28
  136. package/lib/commonjs/project-board/TicketCornerGenieSurface.web.js.map +1 -1
  137. package/lib/commonjs/project-board/TicketDetailDialog.js +6 -3
  138. package/lib/commonjs/project-board/TicketDetailDialog.js.map +1 -1
  139. package/lib/commonjs/project-board/TicketGenieSurface.js +17 -7
  140. package/lib/commonjs/project-board/TicketGenieSurface.js.map +1 -1
  141. package/lib/commonjs/project-board/TicketGenieSurface.web.js +1 -1
  142. package/lib/commonjs/project-board/TicketGenieSurface.web.js.map +1 -1
  143. package/lib/commonjs/project-board/TicketPresence.js +125 -0
  144. package/lib/commonjs/project-board/TicketPresence.js.map +1 -0
  145. package/lib/commonjs/project-board/TicketTokenChart.js +23 -0
  146. package/lib/commonjs/project-board/TicketTokenChart.js.map +1 -0
  147. package/lib/commonjs/project-board/context.js +3 -1
  148. package/lib/commonjs/project-board/context.js.map +1 -1
  149. package/lib/commonjs/search/Search.js +12 -3
  150. package/lib/commonjs/search/Search.js.map +1 -1
  151. package/lib/commonjs/sidebar/SidebarToolbar.js +35 -17
  152. package/lib/commonjs/sidebar/SidebarToolbar.js.map +1 -1
  153. package/lib/commonjs/text-field/TextField.js +13 -7
  154. package/lib/commonjs/text-field/TextField.js.map +1 -1
  155. package/lib/module/agent-avatar/AgentAvatar.js +16 -204
  156. package/lib/module/agent-avatar/AgentAvatar.js.map +1 -1
  157. package/lib/module/agent-avatar/AgentAvatarProvider.js +60 -0
  158. package/lib/module/agent-avatar/AgentAvatarProvider.js.map +1 -0
  159. package/lib/module/agent-avatar/CharacterAvatar.js +207 -0
  160. package/lib/module/agent-avatar/CharacterAvatar.js.map +1 -0
  161. package/lib/module/agent-avatar/ProceduralAvatar.js +212 -0
  162. package/lib/module/agent-avatar/ProceduralAvatar.js.map +1 -0
  163. package/lib/module/agent-avatar/artwork.js +3 -3
  164. package/lib/module/agent-avatar/artwork.js.map +1 -1
  165. package/lib/module/agent-avatar/avatar-color.js +12 -0
  166. package/lib/module/agent-avatar/avatar-color.js.map +1 -0
  167. package/lib/module/agent-avatar/character-html.js +19 -0
  168. package/lib/module/agent-avatar/character-html.js.map +1 -0
  169. package/lib/module/agent-avatar/character-runtime-module.js +35 -0
  170. package/lib/module/agent-avatar/character-runtime-module.js.map +1 -0
  171. package/lib/module/agent-avatar/character-webview.js +14 -0
  172. package/lib/module/agent-avatar/character-webview.js.map +1 -0
  173. package/lib/module/agent-avatar/config-character.js +32 -0
  174. package/lib/module/agent-avatar/config-character.js.map +1 -0
  175. package/lib/module/agent-avatar/context.js +2 -0
  176. package/lib/module/agent-avatar/context.js.map +1 -1
  177. package/lib/module/agent-avatar/index.js +1 -0
  178. package/lib/module/agent-avatar/index.js.map +1 -1
  179. package/lib/module/agent-avatar/legacy-contours.js +53 -0
  180. package/lib/module/agent-avatar/legacy-contours.js.map +1 -0
  181. package/lib/module/agent-avatar/legacy-recipe.js +104 -0
  182. package/lib/module/agent-avatar/legacy-recipe.js.map +1 -0
  183. package/lib/module/agent-avatar/messages.js +2 -1
  184. package/lib/module/agent-avatar/messages.js.map +1 -1
  185. package/lib/module/agent-avatar/model.js +2 -0
  186. package/lib/module/agent-avatar/model.js.map +1 -1
  187. package/lib/module/agent-creator/AgentCreatorBase.js +242 -18
  188. package/lib/module/agent-creator/AgentCreatorBase.js.map +1 -1
  189. package/lib/module/agent-creator/CharacterControls.js +110 -0
  190. package/lib/module/agent-creator/CharacterControls.js.map +1 -0
  191. package/lib/module/agent-creator/EmotionPicker.js +52 -19
  192. package/lib/module/agent-creator/EmotionPicker.js.map +1 -1
  193. package/lib/module/agent-creator/ShapeArc.js +58 -28
  194. package/lib/module/agent-creator/ShapeArc.js.map +1 -1
  195. package/lib/module/agent-creator/ShapeSilhouette.js +57 -0
  196. package/lib/module/agent-creator/ShapeSilhouette.js.map +1 -0
  197. package/lib/module/agent-creator/constants.js +47 -0
  198. package/lib/module/agent-creator/constants.js.map +1 -1
  199. package/lib/module/agent-creator/messages.js +9 -0
  200. package/lib/module/agent-creator/messages.js.map +1 -1
  201. package/lib/module/agent-creator/shared.js +1 -9
  202. package/lib/module/agent-creator/shared.js.map +1 -1
  203. package/lib/module/agent-thinking/AgentThinking.js +5 -63
  204. package/lib/module/agent-thinking/AgentThinking.js.map +1 -1
  205. package/lib/module/agent-thinking/ThinkingLabel.js +73 -0
  206. package/lib/module/agent-thinking/ThinkingLabel.js.map +1 -0
  207. package/lib/module/chart-cards/TokensChartCard.js +20 -5
  208. package/lib/module/chart-cards/TokensChartCard.js.map +1 -1
  209. package/lib/module/locale/translations/ar.js +11 -1
  210. package/lib/module/locale/translations/ar.js.map +1 -1
  211. package/lib/module/locale/translations/bn.js +11 -1
  212. package/lib/module/locale/translations/bn.js.map +1 -1
  213. package/lib/module/locale/translations/ca.js +11 -1
  214. package/lib/module/locale/translations/ca.js.map +1 -1
  215. package/lib/module/locale/translations/de.js +11 -1
  216. package/lib/module/locale/translations/de.js.map +1 -1
  217. package/lib/module/locale/translations/es.js +11 -1
  218. package/lib/module/locale/translations/es.js.map +1 -1
  219. package/lib/module/locale/translations/fr.js +11 -1
  220. package/lib/module/locale/translations/fr.js.map +1 -1
  221. package/lib/module/locale/translations/hi.js +11 -1
  222. package/lib/module/locale/translations/hi.js.map +1 -1
  223. package/lib/module/locale/translations/id.js +11 -1
  224. package/lib/module/locale/translations/id.js.map +1 -1
  225. package/lib/module/locale/translations/it.js +11 -1
  226. package/lib/module/locale/translations/it.js.map +1 -1
  227. package/lib/module/locale/translations/ja.js +11 -1
  228. package/lib/module/locale/translations/ja.js.map +1 -1
  229. package/lib/module/locale/translations/pt.js +11 -1
  230. package/lib/module/locale/translations/pt.js.map +1 -1
  231. package/lib/module/locale/translations/ru.js +11 -1
  232. package/lib/module/locale/translations/ru.js.map +1 -1
  233. package/lib/module/locale/translations/tr.js +11 -1
  234. package/lib/module/locale/translations/tr.js.map +1 -1
  235. package/lib/module/locale/translations/zh.js +11 -1
  236. package/lib/module/locale/translations/zh.js.map +1 -1
  237. package/lib/module/multi-agent-chat/AvatarHandoff.js +13 -11
  238. package/lib/module/multi-agent-chat/AvatarHandoff.js.map +1 -1
  239. package/lib/module/multi-agent-chat/ChatAgentProfile.js +94 -0
  240. package/lib/module/multi-agent-chat/ChatAgentProfile.js.map +1 -0
  241. package/lib/module/multi-agent-chat/EditorRail.js +4 -0
  242. package/lib/module/multi-agent-chat/EditorRail.js.map +1 -1
  243. package/lib/module/multi-agent-chat/MultiAgentChatBase.js +89 -126
  244. package/lib/module/multi-agent-chat/MultiAgentChatBase.js.map +1 -1
  245. package/lib/module/multi-agent-chat/ReplyRow.js +9 -12
  246. package/lib/module/multi-agent-chat/ReplyRow.js.map +1 -1
  247. package/lib/module/multi-agent-chat/handoff.js +4 -4
  248. package/lib/module/multi-agent-chat/handoff.js.map +1 -1
  249. package/lib/module/project-board/CreateTicketDialog.js +33 -2
  250. package/lib/module/project-board/CreateTicketDialog.js.map +1 -1
  251. package/lib/module/project-board/ProjectBoardBase.js +138 -39
  252. package/lib/module/project-board/ProjectBoardBase.js.map +1 -1
  253. package/lib/module/project-board/TicketCornerGenieSurface.web.js +35 -29
  254. package/lib/module/project-board/TicketCornerGenieSurface.web.js.map +1 -1
  255. package/lib/module/project-board/TicketDetailDialog.js +7 -4
  256. package/lib/module/project-board/TicketDetailDialog.js.map +1 -1
  257. package/lib/module/project-board/TicketGenieSurface.js +17 -7
  258. package/lib/module/project-board/TicketGenieSurface.js.map +1 -1
  259. package/lib/module/project-board/TicketGenieSurface.web.js +1 -1
  260. package/lib/module/project-board/TicketGenieSurface.web.js.map +1 -1
  261. package/lib/module/project-board/TicketPresence.js +119 -0
  262. package/lib/module/project-board/TicketPresence.js.map +1 -0
  263. package/lib/module/project-board/TicketTokenChart.js +20 -0
  264. package/lib/module/project-board/TicketTokenChart.js.map +1 -0
  265. package/lib/module/project-board/context.js +2 -0
  266. package/lib/module/project-board/context.js.map +1 -1
  267. package/lib/module/search/Search.js +12 -3
  268. package/lib/module/search/Search.js.map +1 -1
  269. package/lib/module/sidebar/SidebarToolbar.js +36 -18
  270. package/lib/module/sidebar/SidebarToolbar.js.map +1 -1
  271. package/lib/module/text-field/TextField.js +13 -7
  272. package/lib/module/text-field/TextField.js.map +1 -1
  273. package/lib/typescript/commonjs/agent-avatar/AgentAvatar.d.ts +2 -2
  274. package/lib/typescript/commonjs/agent-avatar/AgentAvatar.d.ts.map +1 -1
  275. package/lib/typescript/commonjs/agent-avatar/AgentAvatarProvider.d.ts +4 -0
  276. package/lib/typescript/commonjs/agent-avatar/AgentAvatarProvider.d.ts.map +1 -0
  277. package/lib/typescript/commonjs/agent-avatar/CharacterAvatar.d.ts +4 -0
  278. package/lib/typescript/commonjs/agent-avatar/CharacterAvatar.d.ts.map +1 -0
  279. package/lib/typescript/commonjs/agent-avatar/ProceduralAvatar.d.ts +6 -0
  280. package/lib/typescript/commonjs/agent-avatar/ProceduralAvatar.d.ts.map +1 -0
  281. package/lib/typescript/commonjs/agent-avatar/artwork.d.ts +2 -1
  282. package/lib/typescript/commonjs/agent-avatar/artwork.d.ts.map +1 -1
  283. package/lib/typescript/commonjs/agent-avatar/avatar-color.d.ts +3 -0
  284. package/lib/typescript/commonjs/agent-avatar/avatar-color.d.ts.map +1 -0
  285. package/lib/typescript/commonjs/agent-avatar/character-html.d.ts +4 -0
  286. package/lib/typescript/commonjs/agent-avatar/character-html.d.ts.map +1 -0
  287. package/lib/typescript/commonjs/agent-avatar/character-runtime-module.d.ts +2 -0
  288. package/lib/typescript/commonjs/agent-avatar/character-runtime-module.d.ts.map +1 -0
  289. package/lib/typescript/commonjs/agent-avatar/character-webview.d.ts +24 -0
  290. package/lib/typescript/commonjs/agent-avatar/character-webview.d.ts.map +1 -0
  291. package/lib/typescript/commonjs/agent-avatar/config-character.d.ts +11 -0
  292. package/lib/typescript/commonjs/agent-avatar/config-character.d.ts.map +1 -0
  293. package/lib/typescript/commonjs/agent-avatar/context.d.ts +12 -0
  294. package/lib/typescript/commonjs/agent-avatar/context.d.ts.map +1 -1
  295. package/lib/typescript/commonjs/agent-avatar/index.d.ts +3 -1
  296. package/lib/typescript/commonjs/agent-avatar/index.d.ts.map +1 -1
  297. package/lib/typescript/commonjs/agent-avatar/legacy-contours.d.ts +5 -0
  298. package/lib/typescript/commonjs/agent-avatar/legacy-contours.d.ts.map +1 -0
  299. package/lib/typescript/commonjs/agent-avatar/legacy-recipe.d.ts +40 -0
  300. package/lib/typescript/commonjs/agent-avatar/legacy-recipe.d.ts.map +1 -0
  301. package/lib/typescript/commonjs/agent-avatar/messages.d.ts +1 -0
  302. package/lib/typescript/commonjs/agent-avatar/messages.d.ts.map +1 -1
  303. package/lib/typescript/commonjs/agent-avatar/model.d.ts +3 -0
  304. package/lib/typescript/commonjs/agent-avatar/model.d.ts.map +1 -1
  305. package/lib/typescript/commonjs/agent-avatar/types.d.ts +10 -1
  306. package/lib/typescript/commonjs/agent-avatar/types.d.ts.map +1 -1
  307. package/lib/typescript/commonjs/agent-creator/AgentCreatorBase.d.ts.map +1 -1
  308. package/lib/typescript/commonjs/agent-creator/CharacterControls.d.ts +8 -0
  309. package/lib/typescript/commonjs/agent-creator/CharacterControls.d.ts.map +1 -0
  310. package/lib/typescript/commonjs/agent-creator/EmotionPicker.d.ts +12 -1
  311. package/lib/typescript/commonjs/agent-creator/EmotionPicker.d.ts.map +1 -1
  312. package/lib/typescript/commonjs/agent-creator/ShapeArc.d.ts +11 -2
  313. package/lib/typescript/commonjs/agent-creator/ShapeArc.d.ts.map +1 -1
  314. package/lib/typescript/commonjs/agent-creator/ShapeSilhouette.d.ts +6 -0
  315. package/lib/typescript/commonjs/agent-creator/ShapeSilhouette.d.ts.map +1 -0
  316. package/lib/typescript/commonjs/agent-creator/constants.d.ts +44 -0
  317. package/lib/typescript/commonjs/agent-creator/constants.d.ts.map +1 -1
  318. package/lib/typescript/commonjs/agent-creator/context.d.ts +9 -0
  319. package/lib/typescript/commonjs/agent-creator/context.d.ts.map +1 -1
  320. package/lib/typescript/commonjs/agent-creator/messages.d.ts +10 -0
  321. package/lib/typescript/commonjs/agent-creator/messages.d.ts.map +1 -1
  322. package/lib/typescript/commonjs/agent-creator/shared.d.ts +1 -1
  323. package/lib/typescript/commonjs/agent-creator/shared.d.ts.map +1 -1
  324. package/lib/typescript/commonjs/agent-thinking/AgentThinking.d.ts.map +1 -1
  325. package/lib/typescript/commonjs/agent-thinking/ThinkingLabel.d.ts +7 -0
  326. package/lib/typescript/commonjs/agent-thinking/ThinkingLabel.d.ts.map +1 -0
  327. package/lib/typescript/commonjs/chart-cards/TokensChartCard.d.ts +3 -1
  328. package/lib/typescript/commonjs/chart-cards/TokensChartCard.d.ts.map +1 -1
  329. package/lib/typescript/commonjs/locale/translations/ar.d.ts.map +1 -1
  330. package/lib/typescript/commonjs/locale/translations/bn.d.ts.map +1 -1
  331. package/lib/typescript/commonjs/locale/translations/ca.d.ts.map +1 -1
  332. package/lib/typescript/commonjs/locale/translations/de.d.ts.map +1 -1
  333. package/lib/typescript/commonjs/locale/translations/es.d.ts.map +1 -1
  334. package/lib/typescript/commonjs/locale/translations/fr.d.ts.map +1 -1
  335. package/lib/typescript/commonjs/locale/translations/hi.d.ts.map +1 -1
  336. package/lib/typescript/commonjs/locale/translations/id.d.ts.map +1 -1
  337. package/lib/typescript/commonjs/locale/translations/it.d.ts.map +1 -1
  338. package/lib/typescript/commonjs/locale/translations/ja.d.ts.map +1 -1
  339. package/lib/typescript/commonjs/locale/translations/pt.d.ts.map +1 -1
  340. package/lib/typescript/commonjs/locale/translations/ru.d.ts.map +1 -1
  341. package/lib/typescript/commonjs/locale/translations/tr.d.ts.map +1 -1
  342. package/lib/typescript/commonjs/locale/translations/zh.d.ts.map +1 -1
  343. package/lib/typescript/commonjs/multi-agent-chat/AvatarHandoff.d.ts.map +1 -1
  344. package/lib/typescript/commonjs/multi-agent-chat/ChatAgentProfile.d.ts +11 -0
  345. package/lib/typescript/commonjs/multi-agent-chat/ChatAgentProfile.d.ts.map +1 -0
  346. package/lib/typescript/commonjs/multi-agent-chat/EditorRail.d.ts.map +1 -1
  347. package/lib/typescript/commonjs/multi-agent-chat/MultiAgentChatBase.d.ts.map +1 -1
  348. package/lib/typescript/commonjs/multi-agent-chat/ReplyRow.d.ts.map +1 -1
  349. package/lib/typescript/commonjs/multi-agent-chat/handoff.d.ts +2 -2
  350. package/lib/typescript/commonjs/multi-agent-chat/handoff.d.ts.map +1 -1
  351. package/lib/typescript/commonjs/project-board/CreateTicketDialog.d.ts.map +1 -1
  352. package/lib/typescript/commonjs/project-board/ProjectBoardBase.d.ts.map +1 -1
  353. package/lib/typescript/commonjs/project-board/TicketCornerGenieSurface.web.d.ts.map +1 -1
  354. package/lib/typescript/commonjs/project-board/TicketDetailDialog.d.ts.map +1 -1
  355. package/lib/typescript/commonjs/project-board/TicketGenieSurface.d.ts.map +1 -1
  356. package/lib/typescript/commonjs/project-board/TicketPresence.d.ts +17 -0
  357. package/lib/typescript/commonjs/project-board/TicketPresence.d.ts.map +1 -0
  358. package/lib/typescript/commonjs/project-board/TicketTokenChart.d.ts +5 -0
  359. package/lib/typescript/commonjs/project-board/TicketTokenChart.d.ts.map +1 -0
  360. package/lib/typescript/commonjs/project-board/context.d.ts +2 -0
  361. package/lib/typescript/commonjs/project-board/context.d.ts.map +1 -1
  362. package/lib/typescript/commonjs/search/Search.d.ts.map +1 -1
  363. package/lib/typescript/commonjs/sidebar/SidebarToolbar.d.ts.map +1 -1
  364. package/lib/typescript/commonjs/text-field/TextField.d.ts.map +1 -1
  365. package/lib/typescript/module/agent-avatar/AgentAvatar.d.ts +2 -2
  366. package/lib/typescript/module/agent-avatar/AgentAvatar.d.ts.map +1 -1
  367. package/lib/typescript/module/agent-avatar/AgentAvatarProvider.d.ts +4 -0
  368. package/lib/typescript/module/agent-avatar/AgentAvatarProvider.d.ts.map +1 -0
  369. package/lib/typescript/module/agent-avatar/CharacterAvatar.d.ts +4 -0
  370. package/lib/typescript/module/agent-avatar/CharacterAvatar.d.ts.map +1 -0
  371. package/lib/typescript/module/agent-avatar/ProceduralAvatar.d.ts +6 -0
  372. package/lib/typescript/module/agent-avatar/ProceduralAvatar.d.ts.map +1 -0
  373. package/lib/typescript/module/agent-avatar/artwork.d.ts +2 -1
  374. package/lib/typescript/module/agent-avatar/artwork.d.ts.map +1 -1
  375. package/lib/typescript/module/agent-avatar/avatar-color.d.ts +3 -0
  376. package/lib/typescript/module/agent-avatar/avatar-color.d.ts.map +1 -0
  377. package/lib/typescript/module/agent-avatar/character-html.d.ts +4 -0
  378. package/lib/typescript/module/agent-avatar/character-html.d.ts.map +1 -0
  379. package/lib/typescript/module/agent-avatar/character-runtime-module.d.ts +2 -0
  380. package/lib/typescript/module/agent-avatar/character-runtime-module.d.ts.map +1 -0
  381. package/lib/typescript/module/agent-avatar/character-webview.d.ts +24 -0
  382. package/lib/typescript/module/agent-avatar/character-webview.d.ts.map +1 -0
  383. package/lib/typescript/module/agent-avatar/config-character.d.ts +11 -0
  384. package/lib/typescript/module/agent-avatar/config-character.d.ts.map +1 -0
  385. package/lib/typescript/module/agent-avatar/context.d.ts +12 -0
  386. package/lib/typescript/module/agent-avatar/context.d.ts.map +1 -1
  387. package/lib/typescript/module/agent-avatar/index.d.ts +3 -1
  388. package/lib/typescript/module/agent-avatar/index.d.ts.map +1 -1
  389. package/lib/typescript/module/agent-avatar/legacy-contours.d.ts +5 -0
  390. package/lib/typescript/module/agent-avatar/legacy-contours.d.ts.map +1 -0
  391. package/lib/typescript/module/agent-avatar/legacy-recipe.d.ts +40 -0
  392. package/lib/typescript/module/agent-avatar/legacy-recipe.d.ts.map +1 -0
  393. package/lib/typescript/module/agent-avatar/messages.d.ts +1 -0
  394. package/lib/typescript/module/agent-avatar/messages.d.ts.map +1 -1
  395. package/lib/typescript/module/agent-avatar/model.d.ts +3 -0
  396. package/lib/typescript/module/agent-avatar/model.d.ts.map +1 -1
  397. package/lib/typescript/module/agent-avatar/types.d.ts +10 -1
  398. package/lib/typescript/module/agent-avatar/types.d.ts.map +1 -1
  399. package/lib/typescript/module/agent-creator/AgentCreatorBase.d.ts.map +1 -1
  400. package/lib/typescript/module/agent-creator/CharacterControls.d.ts +8 -0
  401. package/lib/typescript/module/agent-creator/CharacterControls.d.ts.map +1 -0
  402. package/lib/typescript/module/agent-creator/EmotionPicker.d.ts +12 -1
  403. package/lib/typescript/module/agent-creator/EmotionPicker.d.ts.map +1 -1
  404. package/lib/typescript/module/agent-creator/ShapeArc.d.ts +11 -2
  405. package/lib/typescript/module/agent-creator/ShapeArc.d.ts.map +1 -1
  406. package/lib/typescript/module/agent-creator/ShapeSilhouette.d.ts +6 -0
  407. package/lib/typescript/module/agent-creator/ShapeSilhouette.d.ts.map +1 -0
  408. package/lib/typescript/module/agent-creator/constants.d.ts +44 -0
  409. package/lib/typescript/module/agent-creator/constants.d.ts.map +1 -1
  410. package/lib/typescript/module/agent-creator/context.d.ts +9 -0
  411. package/lib/typescript/module/agent-creator/context.d.ts.map +1 -1
  412. package/lib/typescript/module/agent-creator/messages.d.ts +10 -0
  413. package/lib/typescript/module/agent-creator/messages.d.ts.map +1 -1
  414. package/lib/typescript/module/agent-creator/shared.d.ts +1 -1
  415. package/lib/typescript/module/agent-creator/shared.d.ts.map +1 -1
  416. package/lib/typescript/module/agent-thinking/AgentThinking.d.ts.map +1 -1
  417. package/lib/typescript/module/agent-thinking/ThinkingLabel.d.ts +7 -0
  418. package/lib/typescript/module/agent-thinking/ThinkingLabel.d.ts.map +1 -0
  419. package/lib/typescript/module/chart-cards/TokensChartCard.d.ts +3 -1
  420. package/lib/typescript/module/chart-cards/TokensChartCard.d.ts.map +1 -1
  421. package/lib/typescript/module/locale/translations/ar.d.ts.map +1 -1
  422. package/lib/typescript/module/locale/translations/bn.d.ts.map +1 -1
  423. package/lib/typescript/module/locale/translations/ca.d.ts.map +1 -1
  424. package/lib/typescript/module/locale/translations/de.d.ts.map +1 -1
  425. package/lib/typescript/module/locale/translations/es.d.ts.map +1 -1
  426. package/lib/typescript/module/locale/translations/fr.d.ts.map +1 -1
  427. package/lib/typescript/module/locale/translations/hi.d.ts.map +1 -1
  428. package/lib/typescript/module/locale/translations/id.d.ts.map +1 -1
  429. package/lib/typescript/module/locale/translations/it.d.ts.map +1 -1
  430. package/lib/typescript/module/locale/translations/ja.d.ts.map +1 -1
  431. package/lib/typescript/module/locale/translations/pt.d.ts.map +1 -1
  432. package/lib/typescript/module/locale/translations/ru.d.ts.map +1 -1
  433. package/lib/typescript/module/locale/translations/tr.d.ts.map +1 -1
  434. package/lib/typescript/module/locale/translations/zh.d.ts.map +1 -1
  435. package/lib/typescript/module/multi-agent-chat/AvatarHandoff.d.ts.map +1 -1
  436. package/lib/typescript/module/multi-agent-chat/ChatAgentProfile.d.ts +11 -0
  437. package/lib/typescript/module/multi-agent-chat/ChatAgentProfile.d.ts.map +1 -0
  438. package/lib/typescript/module/multi-agent-chat/EditorRail.d.ts.map +1 -1
  439. package/lib/typescript/module/multi-agent-chat/MultiAgentChatBase.d.ts.map +1 -1
  440. package/lib/typescript/module/multi-agent-chat/ReplyRow.d.ts.map +1 -1
  441. package/lib/typescript/module/multi-agent-chat/handoff.d.ts +2 -2
  442. package/lib/typescript/module/multi-agent-chat/handoff.d.ts.map +1 -1
  443. package/lib/typescript/module/project-board/CreateTicketDialog.d.ts.map +1 -1
  444. package/lib/typescript/module/project-board/ProjectBoardBase.d.ts.map +1 -1
  445. package/lib/typescript/module/project-board/TicketCornerGenieSurface.web.d.ts.map +1 -1
  446. package/lib/typescript/module/project-board/TicketDetailDialog.d.ts.map +1 -1
  447. package/lib/typescript/module/project-board/TicketGenieSurface.d.ts.map +1 -1
  448. package/lib/typescript/module/project-board/TicketPresence.d.ts +17 -0
  449. package/lib/typescript/module/project-board/TicketPresence.d.ts.map +1 -0
  450. package/lib/typescript/module/project-board/TicketTokenChart.d.ts +5 -0
  451. package/lib/typescript/module/project-board/TicketTokenChart.d.ts.map +1 -0
  452. package/lib/typescript/module/project-board/context.d.ts +2 -0
  453. package/lib/typescript/module/project-board/context.d.ts.map +1 -1
  454. package/lib/typescript/module/search/Search.d.ts.map +1 -1
  455. package/lib/typescript/module/sidebar/SidebarToolbar.d.ts.map +1 -1
  456. package/lib/typescript/module/text-field/TextField.d.ts.map +1 -1
  457. package/package.json +8 -3
  458. package/src/agent-avatar/AgentAvatar.tsx +16 -296
  459. package/src/agent-avatar/AgentAvatarProvider.tsx +72 -0
  460. package/src/agent-avatar/CharacterAvatar.tsx +255 -0
  461. package/src/agent-avatar/ProceduralAvatar.tsx +303 -0
  462. package/src/agent-avatar/artwork.ts +3 -3
  463. package/src/agent-avatar/avatar-color.ts +17 -0
  464. package/src/agent-avatar/character-html.ts +21 -0
  465. package/src/agent-avatar/character-runtime-module.ts +37 -0
  466. package/src/agent-avatar/character-webview.ts +24 -0
  467. package/src/agent-avatar/config-character.ts +40 -0
  468. package/src/agent-avatar/context.ts +13 -0
  469. package/src/agent-avatar/index.ts +4 -1
  470. package/src/agent-avatar/legacy-contours.ts +76 -0
  471. package/src/agent-avatar/legacy-recipe.ts +123 -0
  472. package/src/agent-avatar/messages.ts +1 -0
  473. package/src/agent-avatar/model.ts +5 -0
  474. package/src/agent-avatar/types.ts +12 -1
  475. package/src/agent-creator/AgentCreatorBase.tsx +329 -38
  476. package/src/agent-creator/CharacterControls.tsx +146 -0
  477. package/src/agent-creator/EmotionPicker.tsx +43 -21
  478. package/src/agent-creator/ShapeArc.tsx +83 -29
  479. package/src/agent-creator/ShapeSilhouette.tsx +65 -0
  480. package/src/agent-creator/constants.ts +30 -0
  481. package/src/agent-creator/messages.ts +19 -0
  482. package/src/agent-creator/shared.ts +1 -15
  483. package/src/agent-thinking/AgentThinking.tsx +7 -70
  484. package/src/agent-thinking/ThinkingLabel.tsx +74 -0
  485. package/src/chart-cards/TokensChartCard.tsx +10 -6
  486. package/src/locale/translations/ar.ts +10 -1
  487. package/src/locale/translations/bn.ts +10 -1
  488. package/src/locale/translations/ca.ts +10 -1
  489. package/src/locale/translations/de.ts +10 -1
  490. package/src/locale/translations/es.ts +10 -1
  491. package/src/locale/translations/fr.ts +10 -1
  492. package/src/locale/translations/hi.ts +10 -1
  493. package/src/locale/translations/id.ts +10 -1
  494. package/src/locale/translations/it.ts +10 -1
  495. package/src/locale/translations/ja.ts +10 -1
  496. package/src/locale/translations/pt.ts +10 -1
  497. package/src/locale/translations/ru.ts +10 -1
  498. package/src/locale/translations/tr.ts +10 -1
  499. package/src/locale/translations/zh.ts +10 -1
  500. package/src/multi-agent-chat/AvatarHandoff.tsx +12 -11
  501. package/src/multi-agent-chat/ChatAgentProfile.tsx +116 -0
  502. package/src/multi-agent-chat/EditorRail.tsx +2 -0
  503. package/src/multi-agent-chat/MultiAgentChatBase.tsx +123 -175
  504. package/src/multi-agent-chat/ReplyRow.tsx +10 -9
  505. package/src/multi-agent-chat/handoff.ts +4 -4
  506. package/src/project-board/CreateTicketDialog.tsx +28 -4
  507. package/src/project-board/ProjectBoardBase.tsx +115 -21
  508. package/src/project-board/TicketCornerGenieSurface.web.tsx +11 -6
  509. package/src/project-board/TicketDetailDialog.tsx +5 -4
  510. package/src/project-board/TicketGenieSurface.tsx +9 -0
  511. package/src/project-board/TicketGenieSurface.web.tsx +1 -1
  512. package/src/project-board/TicketPresence.tsx +137 -0
  513. package/src/project-board/TicketTokenChart.tsx +14 -0
  514. package/src/project-board/context.ts +2 -0
  515. package/src/search/Search.tsx +6 -5
  516. package/src/sidebar/SidebarToolbar.tsx +33 -17
  517. package/src/text-field/TextField.tsx +12 -7
@@ -0,0 +1,820 @@
1
+ // Optional renderer adapter. The generated engine and data alongside it remain unmodified.
2
+ import createModule from './orbit-characters.mjs';
3
+ import { customizeAppearance, encodeAppearance } from './appearance-codec.mjs';
4
+ import { acquireLegacyEngine, legacyEngineStats } from './legacy-engine.mjs';
5
+
6
+ let modulePromise;
7
+ let serial = 0;
8
+ let frame = 0;
9
+ let lastFrame = -Infinity;
10
+ const clients = new Set();
11
+ const category = { shape: 0, color: 1, eyes: 2, eyewear: 3, accessory: 4 };
12
+ function engine() {
13
+ return (modulePromise ??= createModule({
14
+ locateFile: (file) => new URL(file, import.meta.url).href,
15
+ }).catch((error) => {
16
+ modulePromise = undefined;
17
+ throw error;
18
+ }));
19
+ }
20
+ function schedule() {
21
+ if (!frame && clients.size && !document.hidden)
22
+ frame = requestAnimationFrame(tick);
23
+ }
24
+ function tick(time) {
25
+ frame = 0;
26
+ if (document.hidden) return;
27
+ if (time - lastFrame >= 1000 / 30 - 1) {
28
+ lastFrame = time;
29
+ for (const client of [...clients]) client.render(time / 1000);
30
+ }
31
+ schedule();
32
+ }
33
+ function visibility() {
34
+ for (const client of instances) client.visibility();
35
+ schedule();
36
+ }
37
+ const instances = new Set();
38
+
39
+ /** Original engine and shared animation clock; contour caches are isolated by legacy-engine. */
40
+ export async function createAvatar(canvas, initial, callbacks = {}) {
41
+ if (!initial.config.character && !initial.legacy)
42
+ throw new Error('A recovered character recipe is required');
43
+ if (initial.portrait) return createPortrait(canvas, initial, callbacks);
44
+ if (initial.legacy) return createLegacyCharacter(canvas, initial, callbacks);
45
+ return createLiveCharacter(canvas, initial, callbacks);
46
+ }
47
+
48
+ async function createLiveCharacter(
49
+ canvas,
50
+ initial,
51
+ callbacks = {},
52
+ isCurrent = () => true,
53
+ previousImage = null,
54
+ ) {
55
+ const lease = initial.legacy?.points
56
+ ? await acquireLegacyEngine(initial.legacy.points)
57
+ : null;
58
+ const module = lease?.module ?? (await engine());
59
+ if (!isCurrent() || !canvas.isConnected) {
60
+ lease?.release();
61
+ return { update() {}, dispose() {}, diagnostics: () => ({ ready: false }) };
62
+ }
63
+ const id = `bloom-character-${++serial}`;
64
+ const output = canvas.getContext('2d');
65
+ if (!output) {
66
+ lease?.release();
67
+ throw new Error('Character output canvas is unavailable');
68
+ }
69
+ const makeSurface = () => {
70
+ const node = document.createElement('canvas');
71
+ node.id = id;
72
+ node.style.display = 'none';
73
+ node.setAttribute('aria-hidden', 'true');
74
+ canvas.parentElement.appendChild(node);
75
+ return node;
76
+ };
77
+ let surface = makeSurface();
78
+ let character;
79
+ try {
80
+ character = new module.Character(`#${id}`, 128, 128);
81
+ } catch (error) {
82
+ surface.remove();
83
+ lease?.release();
84
+ throw error;
85
+ }
86
+ let activityMode = false;
87
+ let props = initial,
88
+ fingerprint = '',
89
+ appliedRecipe,
90
+ ready = false,
91
+ dirty = true,
92
+ visible = true;
93
+ let fit = null,
94
+ transitionStarted;
95
+ let transitionImage = previousImage;
96
+ const measurement = document.createElement('canvas');
97
+ const measure = measurement.getContext('2d', { willReadFrequently: true });
98
+ let disposed = false,
99
+ sequence = 0n,
100
+ episode = 0n,
101
+ activity = 0;
102
+ let workTimer,
103
+ workDuration,
104
+ lastActivityResult,
105
+ previousWork,
106
+ hasWork = false;
107
+ let pointerId, pointerStart, previousReaction;
108
+ let lastReaction = null,
109
+ lastReactionKind = null;
110
+ character.setQuality(initial.portrait ? 1 : 0); // Original automatic quality; compact static thumbnails.
111
+ // Readiness means painted pixels, not merely an engine submission.
112
+ const play = (kind) => {
113
+ if (activity === kind) return;
114
+ const stopping = kind === 0;
115
+ lastActivityResult = character.applyActivity({
116
+ command: stopping ? 2 : 1,
117
+ sequence: ++sequence,
118
+ episodeId: stopping ? episode : ++episode,
119
+ episodeHighWater: 0n,
120
+ activity: stopping ? activity : kind,
121
+ outcome: 0,
122
+ entry: 0,
123
+ });
124
+ activity = kind;
125
+ };
126
+ const animate = () =>
127
+ !props.paused && !props.reduced && props.config.motion !== 0;
128
+ // A queued still must finish if its selector moves it offscreen mid-prepare;
129
+ // otherwise one clipped slot blocks every visible thumbnail until timeout.
130
+ const active = () => (visible || props.portrait) && !document.hidden;
131
+ const wake = () => {
132
+ if (disposed) return;
133
+ character.setActive(active());
134
+ if (active() && (dirty || !ready || animate())) clients.add(client);
135
+ else clients.delete(client);
136
+ schedule();
137
+ };
138
+ const client = {
139
+ visibility: wake,
140
+ render(time) {
141
+ try {
142
+ const submitted = character.render(time);
143
+ if (submitted) {
144
+ if (
145
+ !fit &&
146
+ !character.preparationStats().pending &&
147
+ !character.hasPendingUpdate()
148
+ ) {
149
+ measurement.width = canvas.width;
150
+ measurement.height = canvas.height;
151
+ measure.drawImage(surface, 0, 0, canvas.width, canvas.height);
152
+ const { data, width, height } = measure.getImageData(
153
+ 0,
154
+ 0,
155
+ canvas.width,
156
+ canvas.height,
157
+ );
158
+ let minX = width,
159
+ minY = height,
160
+ maxX = -1,
161
+ maxY = -1;
162
+ for (let y = 0; y < height; y++)
163
+ for (let x = 0; x < width; x++) {
164
+ if (data[(y * width + x) * 4 + 3] > 24) {
165
+ minX = Math.min(minX, x);
166
+ maxX = Math.max(maxX, x);
167
+ minY = Math.min(minY, y);
168
+ maxY = Math.max(maxY, y);
169
+ }
170
+ }
171
+ if (maxX >= minX) {
172
+ const extent = Math.max(maxX - minX + 1, maxY - minY + 1) * 1.22;
173
+ fit = [
174
+ (minX + maxX) / 2 - extent / 2,
175
+ (minY + maxY) / 2 - extent / 2,
176
+ extent,
177
+ ];
178
+ }
179
+ }
180
+ // Retain the previous portrait while a changed shape is preparing.
181
+ if (!fit) return;
182
+ output.clearRect(0, 0, canvas.width, canvas.height);
183
+ if (fit)
184
+ output.drawImage(
185
+ surface,
186
+ fit[0],
187
+ fit[1],
188
+ fit[2],
189
+ fit[2],
190
+ 0,
191
+ 0,
192
+ canvas.width,
193
+ canvas.height,
194
+ );
195
+ else output.drawImage(surface, 0, 0, canvas.width, canvas.height);
196
+ }
197
+ if (submitted && fit && transitionImage) {
198
+ // Geometry preparation keeps the previous image; blend only after the
199
+ // new original-engine surface has pixels. Reduced motion skips it.
200
+ transitionStarted ??= time;
201
+ const progress = animate()
202
+ ? Math.min(1, (time - transitionStarted) / 0.18)
203
+ : 1;
204
+ if (progress < 1) {
205
+ output.globalAlpha = 1 - progress;
206
+ output.drawImage(
207
+ transitionImage,
208
+ 0,
209
+ 0,
210
+ canvas.width,
211
+ canvas.height,
212
+ );
213
+ output.globalAlpha = 1;
214
+ } else transitionImage = null;
215
+ }
216
+ const renderError = character.renderError();
217
+ if (renderError || character.preparationStats().failed)
218
+ throw new Error(
219
+ renderError ||
220
+ character.preparationError() ||
221
+ 'Character preparation failed',
222
+ );
223
+ if (
224
+ submitted &&
225
+ fit &&
226
+ !character.preparationStats().pending &&
227
+ !character.hasPendingUpdate()
228
+ ) {
229
+ dirty = false;
230
+ if (!ready) {
231
+ ready = true;
232
+ callbacks.onReady?.();
233
+ }
234
+ callbacks.onPaint?.();
235
+ if (activityMode && workDuration && !workTimer) {
236
+ workTimer = setTimeout(() => {
237
+ workTimer = undefined;
238
+ workDuration = undefined;
239
+ play(0);
240
+ switchMode(false);
241
+ dirty = true;
242
+ wake();
243
+ }, workDuration);
244
+ }
245
+ if (!animate()) clients.delete(client);
246
+ }
247
+ } catch (error) {
248
+ clients.delete(client);
249
+ callbacks.onError?.(error);
250
+ }
251
+ },
252
+ };
253
+ const resize = () => {
254
+ const css = Math.max(1, Math.min(canvas.clientWidth, canvas.clientHeight));
255
+ const pixels = Math.max(
256
+ 64,
257
+ Math.min(512, Math.round(css * Math.min(devicePixelRatio || 1, 2))),
258
+ );
259
+ if (canvas.width !== pixels || canvas.height !== pixels) {
260
+ canvas.width = pixels;
261
+ canvas.height = pixels;
262
+ fit = null;
263
+ }
264
+ character.resize(pixels, pixels);
265
+ character.setDisplayScale(pixels / css);
266
+ dirty = true;
267
+ wake();
268
+ };
269
+ const switchMode = (next, resetAppearance = false) => {
270
+ if (activityMode === next && !resetAppearance) return;
271
+ const state = new Uint8Array(character.state());
272
+ character.delete();
273
+ surface.remove();
274
+ surface = makeSurface();
275
+ character = new module.Character(`#${id}`, 128, 128, { activities: next });
276
+ activityMode = next;
277
+ fit = null;
278
+ sequence = 0n;
279
+ episode = 0n;
280
+ activity = 0;
281
+ ready = false;
282
+ dirty = true;
283
+ character.setQuality(props.portrait ? 1 : 0);
284
+ character.restore(state);
285
+ // This recovered engine paints a transparent frame when reduced motion is
286
+ // enabled before its first appearance. Freeze our clock after a painted
287
+ // frame instead, preserving both initial visibility and reduced motion.
288
+ character.setReducedMotion(false);
289
+
290
+ if (next)
291
+ character.applyActivity({
292
+ command: 3,
293
+ sequence: 0n,
294
+ episodeId: 0n,
295
+ episodeHighWater: 0n,
296
+ activity: 0,
297
+ outcome: 0,
298
+ entry: 1,
299
+ });
300
+ resize();
301
+ };
302
+ const react = () => {
303
+ if (!ready || !animate()) return;
304
+ if (activityMode) return;
305
+ lastReactionKind = 2;
306
+ lastReaction = character.playReaction(lastReactionKind);
307
+ // Authored signatures belong to named presets. Catalog edits and migrated
308
+ // bodies use the same engine's Wave when that signature is unsupported.
309
+ if (lastReaction === 2) {
310
+ lastReactionKind = 1;
311
+ lastReaction = character.playReaction(lastReactionKind);
312
+ }
313
+ dirty = true;
314
+ wake();
315
+ };
316
+ let appearanceTimer, pendingFingerprint;
317
+ const applyAppearance = (value) => {
318
+ const recipe = value;
319
+ const nextFingerprint = JSON.stringify(recipe);
320
+ if (nextFingerprint !== fingerprint) {
321
+ // Catalog selection owns the engine's part transitions. Restoring the
322
+ // named preset on every selection needlessly resets the whole character.
323
+ const removedOverride = Object.keys(appliedRecipe?.selections ?? {}).some(
324
+ (key) => !recipe.selections?.[key],
325
+ );
326
+ if (
327
+ !appliedRecipe ||
328
+ recipe.preset !== appliedRecipe.preset ||
329
+ removedOverride ||
330
+ (appliedRecipe.bodyColor && !recipe.bodyColor)
331
+ ) {
332
+ const base = props.legacy
333
+ ? encodeAppearance({
334
+ version: 1,
335
+ shape: 'circle',
336
+ color: 'blue',
337
+ eyes: 'oval',
338
+ eyewear: 'none',
339
+ accessories: [],
340
+ accessoryColors: {},
341
+ constrained: 0,
342
+ depth: 0.5,
343
+ model: null,
344
+ rig: null,
345
+ hereCharacter: null,
346
+ })
347
+ : module.presetAppearance(recipe.preset);
348
+ if (character.restore(base))
349
+ throw new Error('Invalid character appearance');
350
+ }
351
+ for (const key of Object.keys(category)) {
352
+ const value = recipe.selections?.[key];
353
+ if (!value) continue;
354
+ if (key === 'accessory' && value === 'none') {
355
+ for (const item of module.catalog(4))
356
+ if (character.isSelected(4, item.id)) character.select(4, item.id);
357
+ continue;
358
+ }
359
+ if (
360
+ !character.isSelected(category[key], value) &&
361
+ !character.select(category[key], value)
362
+ )
363
+ throw new Error(`Unsupported character selection: ${key}`);
364
+ }
365
+ const patch =
366
+ props.legacy?.patch ??
367
+ (recipe.bodyColor ? { bodyColor: recipe.bodyColor } : null);
368
+ if (patch) {
369
+ // One authored preset uses an unnamed color. Enter the engine's normal
370
+ // editable palette before replacing that paint with an explicit RGB.
371
+ if (
372
+ patch.bodyColor &&
373
+ !module.catalog(1).some((item) => character.isSelected(1, item.id))
374
+ )
375
+ character.select(1, 'yellow');
376
+ // Explicit customization exits a named preset just like the engine's
377
+ // own catalog editor; untouched presets retain their original bytes.
378
+ const customized = customizeAppearance(
379
+ module,
380
+ new Uint8Array(character.state()),
381
+ patch,
382
+ { allowPresetDemotion: true },
383
+ );
384
+ if (character.restore(customized))
385
+ throw new Error('Invalid customized appearance');
386
+ }
387
+ if (
388
+ !appliedRecipe ||
389
+ recipe.preset !== appliedRecipe.preset ||
390
+ ['shape', 'accessory'].some(
391
+ (key) => recipe.selections?.[key] !== appliedRecipe.selections?.[key],
392
+ )
393
+ )
394
+ fit = null;
395
+ // A stopped render loop would freeze the engine's appearance blend at
396
+ // its first frame. Bind the edited state as a fresh appearance instead;
397
+ // retain the visible canvas until the new scene has painted pixels.
398
+ if (ready && !animate()) switchMode(activityMode, true);
399
+ appliedRecipe = structuredClone(recipe);
400
+ fingerprint = nextFingerprint;
401
+ const available = {};
402
+ const selected = {};
403
+ for (const [key, index] of Object.entries(category)) {
404
+ for (const item of module.catalog(index)) {
405
+ available[`${key}:${item.id}`] = character.isAvailable(
406
+ index,
407
+ item.id,
408
+ );
409
+ if (character.isSelected(index, item.id)) selected[key] = item.id;
410
+ }
411
+ }
412
+ available['accessory:none'] = true;
413
+ selected.accessory ??= 'none';
414
+ callbacks.onCapabilities?.({ key: fingerprint, available, selected });
415
+ dirty = true;
416
+ }
417
+ };
418
+ const update = (next) => {
419
+ if (disposed) return;
420
+ props = next;
421
+ const recipe = props.legacy
422
+ ? {
423
+ preset: 'legacy',
424
+ selections: {
425
+ shape: props.legacy.shape ?? 'circle',
426
+ eyes: props.legacy.eyes ?? 'oval',
427
+ ...props.legacy.selections,
428
+ },
429
+ ...props.legacy.patch,
430
+ }
431
+ : props.config.character;
432
+ const nextFingerprint = JSON.stringify(recipe);
433
+ // Dragging the shared color picker may emit dozens of values per second.
434
+ // Prepare only its latest value while retaining the existing painted frame.
435
+ if (pendingFingerprint !== nextFingerprint) {
436
+ clearTimeout(appearanceTimer);
437
+ pendingFingerprint = nextFingerprint;
438
+ if (
439
+ appliedRecipe &&
440
+ recipe.bodyColor &&
441
+ recipe.bodyColor !== appliedRecipe.bodyColor
442
+ ) {
443
+ appearanceTimer = setTimeout(() => {
444
+ if (disposed) return;
445
+ try {
446
+ applyAppearance(recipe);
447
+ wake();
448
+ } catch (error) {
449
+ callbacks.onError?.(error);
450
+ }
451
+ }, 80);
452
+ } else applyAppearance(recipe);
453
+ }
454
+ // The recovered engine needs its first appearance rendered with this off.
455
+ // Our scheduler freezes the completed frame instead.
456
+ character.setReducedMotion(false);
457
+ if (
458
+ hasWork &&
459
+ previousWork !== props.workingKey &&
460
+ props.workingKey !== undefined &&
461
+ animate()
462
+ ) {
463
+ clearTimeout(workTimer);
464
+ switchMode(true);
465
+ play(1);
466
+ workTimer = undefined;
467
+ // Count visible activity time, not time spent preparing its scene.
468
+ workDuration = 2200 * Math.max(1, Math.min(10, props.workingCycles || 1));
469
+ }
470
+ if (
471
+ hasWork &&
472
+ previousReaction !== props.reactionKey &&
473
+ props.reactionKey !== undefined
474
+ )
475
+ react();
476
+ previousReaction = props.reactionKey;
477
+ previousWork = props.workingKey;
478
+ hasWork = true;
479
+ const points = {
480
+ 'top-left': [0, 0],
481
+ top: [0.5, 0],
482
+ 'top-right': [1, 0],
483
+ left: [0, 0.5],
484
+ center: [0.5, 0.5],
485
+ right: [1, 0.5],
486
+ 'bottom-left': [0, 1],
487
+ bottom: [0.5, 1],
488
+ 'bottom-right': [1, 1],
489
+ };
490
+ const point = points[props.config.lookAt];
491
+ if (activityMode) {
492
+ if (point) character.setReadyGaze(...point, performance.now() / 1000);
493
+ else character.clearReadyGaze(performance.now() / 1000);
494
+ } else if (point)
495
+ character.pointer(1, 0, ...point, performance.now() / 1000);
496
+ dirty = true;
497
+ wake();
498
+ };
499
+ function pointer(event) {
500
+ if (!props.interactive || !animate()) return;
501
+ const phase = {
502
+ pointerdown: 0,
503
+ pointermove: 1,
504
+ pointerup: 2,
505
+ pointercancel: 3,
506
+ }[event.type];
507
+ if (event.type === 'pointerdown') {
508
+ if (event.button !== 0 || pointerId != null || !event.isPrimary) return;
509
+ pointerStart = [event.clientX, event.clientY];
510
+ pointerId = event.pointerId;
511
+ canvas.setPointerCapture(pointerId);
512
+ }
513
+ if (pointerId != null && pointerId !== event.pointerId) return;
514
+ if ((phase === 2 || phase === 3) && pointerId !== event.pointerId) return;
515
+ const r = canvas.getBoundingClientRect();
516
+ const localX = (event.clientX - r.left) / r.width,
517
+ localY = (event.clientY - r.top) / r.height;
518
+ const x = fit ? (fit[0] + localX * fit[2]) / canvas.width : localX;
519
+ const y = fit ? (fit[1] + localY * fit[2]) / canvas.height : localY;
520
+ if (activityMode && phase === 1)
521
+ character.setReadyGaze(x, y, performance.now() / 1000);
522
+ if (!activityMode)
523
+ character.pointer(phase, event.pointerId, x, y, performance.now() / 1000);
524
+ if (phase === 2 || phase === 3) {
525
+ if (
526
+ phase === 2 &&
527
+ pointerStart &&
528
+ Math.hypot(
529
+ event.clientX - pointerStart[0],
530
+ event.clientY - pointerStart[1],
531
+ ) < 6
532
+ )
533
+ react();
534
+ if (canvas.hasPointerCapture(event.pointerId))
535
+ canvas.releasePointerCapture(event.pointerId);
536
+ pointerId = undefined;
537
+ }
538
+ dirty = true;
539
+ wake();
540
+ }
541
+ const cancel = () => {
542
+ if (pointerId != null)
543
+ character.pointer(3, pointerId, 0.5, 0.5, performance.now() / 1000);
544
+ pointerId = undefined;
545
+ pointerStart = undefined;
546
+ };
547
+ const leave = () => {
548
+ if (pointerId == null) {
549
+ if (activityMode) character.clearReadyGaze(performance.now() / 1000);
550
+ else character.pointer(1, 0, 0.5, 0.5, performance.now() / 1000);
551
+ }
552
+ };
553
+ canvas.addEventListener('lostpointercapture', cancel);
554
+ canvas.addEventListener('pointerleave', leave);
555
+ window.addEventListener('blur', cancel);
556
+ const events = ['pointerdown', 'pointermove', 'pointerup', 'pointercancel'];
557
+ for (const name of events) canvas.addEventListener(name, pointer);
558
+ const resizeObserver = new ResizeObserver(resize);
559
+ resizeObserver.observe(canvas);
560
+ const intersection = new IntersectionObserver((entries) => {
561
+ visible = entries[0]?.isIntersecting !== false;
562
+ wake();
563
+ });
564
+ intersection.observe(canvas);
565
+ if (!instances.size)
566
+ document.addEventListener('visibilitychange', visibility);
567
+ instances.add(client);
568
+ const dispose = () => {
569
+ if (disposed) return;
570
+ disposed = true;
571
+ clearTimeout(workTimer);
572
+ clearTimeout(appearanceTimer);
573
+ clients.delete(client);
574
+ instances.delete(client);
575
+ resizeObserver.disconnect();
576
+ intersection.disconnect();
577
+ for (const name of events) canvas.removeEventListener(name, pointer);
578
+ canvas.removeEventListener('lostpointercapture', cancel);
579
+ canvas.removeEventListener('pointerleave', leave);
580
+ window.removeEventListener('blur', cancel);
581
+ character.delete();
582
+ surface.remove();
583
+ lease?.release();
584
+ if (!instances.size) {
585
+ document.removeEventListener('visibilitychange', visibility);
586
+ cancelAnimationFrame(frame);
587
+ frame = 0;
588
+ }
589
+ };
590
+ try {
591
+ update(initial);
592
+ resize();
593
+ } catch (error) {
594
+ dispose();
595
+ throw error;
596
+ }
597
+ return {
598
+ update,
599
+ dispose,
600
+ diagnostics: () => ({
601
+ lastReaction,
602
+ lastReactionKind,
603
+ lastActivityResult,
604
+ activityMode,
605
+ ready,
606
+ pending:
607
+ dirty ||
608
+ Boolean(character.preparationStats().pending) ||
609
+ character.hasPendingUpdate(),
610
+ }),
611
+ };
612
+ }
613
+
614
+ // A geometry cache must never serve a different silhouette under the same
615
+ // appearance key. Keep the old painted image while switching contour modules.
616
+ async function createLegacyCharacter(canvas, initial, callbacks) {
617
+ let controller,
618
+ shapeKey,
619
+ revision = 0,
620
+ disposed = false,
621
+ latest = initial;
622
+ const update = async (next) => {
623
+ if (disposed) return;
624
+ latest = next;
625
+ const key = JSON.stringify(next.legacy.points ?? null);
626
+ if (shapeKey === key) {
627
+ controller?.update(next);
628
+ return;
629
+ }
630
+ const snapshot = controller?.diagnostics().ready
631
+ ? document.createElement('canvas')
632
+ : null;
633
+ if (snapshot) {
634
+ snapshot.width = canvas.width;
635
+ snapshot.height = canvas.height;
636
+ snapshot.getContext('2d').drawImage(canvas, 0, 0);
637
+ }
638
+ shapeKey = key;
639
+ const generation = ++revision;
640
+ const current = () => !disposed && generation === revision;
641
+ const guardedCallbacks = Object.fromEntries(
642
+ Object.entries(callbacks).map(([name, callback]) => [
643
+ name,
644
+ (...args) => {
645
+ if (current()) callback?.(...args);
646
+ },
647
+ ]),
648
+ );
649
+ controller?.dispose();
650
+ controller = undefined;
651
+ try {
652
+ const created = await createLiveCharacter(
653
+ canvas,
654
+ next,
655
+ guardedCallbacks,
656
+ current,
657
+ snapshot,
658
+ );
659
+ if (!current()) {
660
+ created.dispose();
661
+ return;
662
+ }
663
+ controller = created;
664
+ controller.update(latest);
665
+ } catch (error) {
666
+ if (!current()) return;
667
+ shapeKey = undefined;
668
+ throw error;
669
+ }
670
+ };
671
+ await update(initial);
672
+ return {
673
+ update(next) {
674
+ void update(next).catch((error) => {
675
+ if (!disposed) callbacks.onError?.(error);
676
+ });
677
+ },
678
+ dispose() {
679
+ disposed = true;
680
+ ++revision;
681
+ controller?.dispose();
682
+ },
683
+ diagnostics: () => controller?.diagnostics(),
684
+ };
685
+ }
686
+
687
+ // Thumbnail preparation is serialized: the editor does not keep a WebGL context
688
+ // for every shape/eye choice. Completed pixels survive after the engine is freed.
689
+ const portraits = new Map();
690
+ let portraitQueue = Promise.resolve();
691
+ function createPortrait(canvas, initial, callbacks) {
692
+ let disposed = false,
693
+ generation = 0,
694
+ fingerprint = '',
695
+ cancel;
696
+ const update = (props) => {
697
+ if (disposed) return;
698
+ const pixels = Math.max(
699
+ 64,
700
+ Math.min(
701
+ 512,
702
+ Math.round(
703
+ Math.min(canvas.clientWidth, canvas.clientHeight) *
704
+ Math.min(devicePixelRatio || 1, 2),
705
+ ),
706
+ ),
707
+ );
708
+ const key = JSON.stringify([
709
+ props.config.character,
710
+ props.legacy,
711
+ props.config.lookAt,
712
+ pixels,
713
+ ]);
714
+ if (key === fingerprint) return;
715
+ fingerprint = key;
716
+ const revision = ++generation;
717
+ cancel?.();
718
+ const current = () =>
719
+ !disposed && generation === revision && canvas.isConnected;
720
+ const paintCached = () => {
721
+ const cached = portraits.get(key);
722
+ if (!cached) return false;
723
+ canvas.width = canvas.height = pixels;
724
+ canvas.getContext('2d').drawImage(cached.image, 0, 0, pixels, pixels);
725
+ callbacks.onCapabilities?.(cached.capabilities);
726
+ callbacks.onReady?.();
727
+ return true;
728
+ };
729
+ if (paintCached()) return;
730
+ portraitQueue = portraitQueue.then(async () => {
731
+ if (!current() || paintCached()) return;
732
+ let controller,
733
+ capabilities,
734
+ finished = false,
735
+ timer;
736
+ let complete;
737
+ const completion = new Promise((resolve) => {
738
+ complete = resolve;
739
+ });
740
+ const finish = () => {
741
+ if (finished) return;
742
+ finished = true;
743
+ clearTimeout(timer);
744
+ controller?.dispose();
745
+ complete();
746
+ };
747
+ cancel = finish;
748
+ try {
749
+ controller = await createLiveCharacter(
750
+ canvas,
751
+ { ...props, paused: true, interactive: false },
752
+ {
753
+ onCapabilities(value) {
754
+ capabilities = value;
755
+ if (current()) callbacks.onCapabilities?.(value);
756
+ },
757
+ onError(error) {
758
+ if (current()) callbacks.onError?.(error);
759
+ queueMicrotask(finish);
760
+ },
761
+ onPaint() {
762
+ if (current() && !finished) {
763
+ const image = document.createElement('canvas');
764
+ image.width = canvas.width;
765
+ image.height = canvas.height;
766
+ image.getContext('2d').drawImage(canvas, 0, 0);
767
+ portraits.set(key, { image, capabilities });
768
+ if (portraits.size > 64)
769
+ portraits.delete(portraits.keys().next().value);
770
+ callbacks.onReady?.();
771
+ }
772
+ queueMicrotask(finish);
773
+ },
774
+ },
775
+ );
776
+ if (finished || !current()) {
777
+ controller.dispose();
778
+ finish();
779
+ } else
780
+ timer = setTimeout(() => {
781
+ if (current())
782
+ callbacks.onError?.(
783
+ new Error('Character preview preparation timed out'),
784
+ );
785
+ finish();
786
+ }, 20000);
787
+ await completion;
788
+ } catch (error) {
789
+ if (current()) callbacks.onError?.(error);
790
+ finish();
791
+ } finally {
792
+ controller?.dispose();
793
+ if (cancel === finish) cancel = undefined;
794
+ }
795
+ });
796
+ };
797
+ update(initial);
798
+ return {
799
+ update,
800
+ dispose() {
801
+ disposed = true;
802
+ ++generation;
803
+ cancel?.();
804
+ },
805
+ };
806
+ }
807
+
808
+ const registryKey = Symbol.for('bloom.character.runtimes');
809
+ (globalThis[registryKey] ??= new Map()).set(import.meta.url, { createAvatar });
810
+
811
+ /** Diagnostics are read on demand; no DOM/debug updates run on the animation clock. */
812
+ export function runtimeStats() {
813
+ return {
814
+ instances: instances.size,
815
+ active: clients.size,
816
+ scheduled: !!frame,
817
+ cachedPortraits: portraits.size,
818
+ legacy: legacyEngineStats(),
819
+ };
820
+ }