@oxy.so/bloom 7.0.1 → 7.1.1

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