@oxy.so/bloom 7.1.2 → 7.1.4

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 (236) hide show
  1. package/assets/character-runtime/README.md +114 -19
  2. package/assets/character-runtime/authored-parts.mjs +754 -0
  3. package/assets/character-runtime/catalog-parts.mjs +362 -0
  4. package/assets/character-runtime/character-recipe.mjs +247 -0
  5. package/assets/character-runtime/clippo-geometry.mjs +679 -0
  6. package/assets/character-runtime/controller-mode.mjs +208 -0
  7. package/assets/character-runtime/cyclops-geometry.mjs +180 -0
  8. package/assets/character-runtime/legacy-engine.mjs +406 -54
  9. package/assets/character-runtime/legacy-geometry.mjs +242 -85
  10. package/assets/character-runtime/legacy-worker.mjs +82 -23
  11. package/assets/character-runtime/managed-avatar.mjs +12 -17
  12. package/assets/character-runtime/migrated-contours.mjs +2067 -0
  13. package/assets/character-runtime/migrated-faces.mjs +59 -0
  14. package/assets/character-runtime/pose-transition.mjs +523 -0
  15. package/assets/character-runtime/preparation-cache.mjs +60 -0
  16. package/assets/character-runtime/render-budget.mjs +5 -3
  17. package/assets/character-runtime/render-errors.mjs +180 -0
  18. package/assets/character-runtime/resolution.mjs +10 -0
  19. package/assets/character-runtime/runtime.mjs +744 -295
  20. package/assets/character-runtime/sha256.mjs +44 -0
  21. package/assets/character-runtime/shared-programs.mjs +534 -0
  22. package/assets/character-runtime/shared-surface.mjs +490 -0
  23. package/assets/character-runtime/shared-textures.mjs +420 -0
  24. package/assets/character-runtime/thumbnails/eyes/todd.png +0 -0
  25. package/docs/agent-avatar.mdx +45 -8
  26. package/docs/agent-creator.mdx +13 -3
  27. package/lib/commonjs/agent-avatar/AgentAvatar.js +1 -1
  28. package/lib/commonjs/agent-avatar/AgentAvatar.js.map +1 -1
  29. package/lib/commonjs/agent-avatar/CharacterAvatar.js +2 -1
  30. package/lib/commonjs/agent-avatar/CharacterAvatar.js.map +1 -1
  31. package/lib/commonjs/agent-avatar/character-colors.js +19 -0
  32. package/lib/commonjs/agent-avatar/character-colors.js.map +1 -0
  33. package/lib/commonjs/agent-avatar/character-shapes.js +106 -0
  34. package/lib/commonjs/agent-avatar/character-shapes.js.map +1 -0
  35. package/lib/commonjs/agent-avatar/config-character.js +4 -0
  36. package/lib/commonjs/agent-avatar/config-character.js.map +1 -1
  37. package/lib/commonjs/agent-avatar/legacy-recipe.js +19 -6
  38. package/lib/commonjs/agent-avatar/legacy-recipe.js.map +1 -1
  39. package/lib/commonjs/agent-creator/AgentCreatorBase.js +67 -107
  40. package/lib/commonjs/agent-creator/AgentCreatorBase.js.map +1 -1
  41. package/lib/commonjs/agent-creator/CharacterControls.js +23 -5
  42. package/lib/commonjs/agent-creator/CharacterControls.js.map +1 -1
  43. package/lib/commonjs/agent-creator/ClippoArtwork.js +63 -0
  44. package/lib/commonjs/agent-creator/ClippoArtwork.js.map +1 -0
  45. package/lib/commonjs/agent-creator/CyclopsArtwork.js +45 -0
  46. package/lib/commonjs/agent-creator/CyclopsArtwork.js.map +1 -0
  47. package/lib/commonjs/agent-creator/EmotionPicker.js +8 -1
  48. package/lib/commonjs/agent-creator/EmotionPicker.js.map +1 -1
  49. package/lib/commonjs/agent-creator/ShapeSilhouette.js +8 -1
  50. package/lib/commonjs/agent-creator/ShapeSilhouette.js.map +1 -1
  51. package/lib/commonjs/agent-creator/ToddArtwork.js +29 -0
  52. package/lib/commonjs/agent-creator/ToddArtwork.js.map +1 -0
  53. package/lib/commonjs/agent-creator/constants.js +16 -17
  54. package/lib/commonjs/agent-creator/constants.js.map +1 -1
  55. package/lib/commonjs/agent-creator/messages.js +1 -1
  56. package/lib/commonjs/agent-creator/messages.js.map +1 -1
  57. package/lib/commonjs/locale/translations/ar.js +1 -1
  58. package/lib/commonjs/locale/translations/ar.js.map +1 -1
  59. package/lib/commonjs/locale/translations/bn.js +1 -1
  60. package/lib/commonjs/locale/translations/bn.js.map +1 -1
  61. package/lib/commonjs/locale/translations/ca.js +1 -1
  62. package/lib/commonjs/locale/translations/ca.js.map +1 -1
  63. package/lib/commonjs/locale/translations/de.js +1 -1
  64. package/lib/commonjs/locale/translations/de.js.map +1 -1
  65. package/lib/commonjs/locale/translations/es.js +1 -1
  66. package/lib/commonjs/locale/translations/es.js.map +1 -1
  67. package/lib/commonjs/locale/translations/fr.js +1 -1
  68. package/lib/commonjs/locale/translations/fr.js.map +1 -1
  69. package/lib/commonjs/locale/translations/hi.js +1 -1
  70. package/lib/commonjs/locale/translations/hi.js.map +1 -1
  71. package/lib/commonjs/locale/translations/id.js +1 -1
  72. package/lib/commonjs/locale/translations/id.js.map +1 -1
  73. package/lib/commonjs/locale/translations/it.js +1 -1
  74. package/lib/commonjs/locale/translations/it.js.map +1 -1
  75. package/lib/commonjs/locale/translations/ja.js +1 -1
  76. package/lib/commonjs/locale/translations/ja.js.map +1 -1
  77. package/lib/commonjs/locale/translations/pt.js +1 -1
  78. package/lib/commonjs/locale/translations/pt.js.map +1 -1
  79. package/lib/commonjs/locale/translations/ru.js +1 -1
  80. package/lib/commonjs/locale/translations/ru.js.map +1 -1
  81. package/lib/commonjs/locale/translations/tr.js +1 -1
  82. package/lib/commonjs/locale/translations/tr.js.map +1 -1
  83. package/lib/commonjs/locale/translations/zh.js +1 -1
  84. package/lib/commonjs/locale/translations/zh.js.map +1 -1
  85. package/lib/module/agent-avatar/AgentAvatar.js +1 -1
  86. package/lib/module/agent-avatar/AgentAvatar.js.map +1 -1
  87. package/lib/module/agent-avatar/CharacterAvatar.js +2 -1
  88. package/lib/module/agent-avatar/CharacterAvatar.js.map +1 -1
  89. package/lib/module/agent-avatar/character-colors.js +15 -0
  90. package/lib/module/agent-avatar/character-colors.js.map +1 -0
  91. package/lib/module/agent-avatar/character-shapes.js +97 -0
  92. package/lib/module/agent-avatar/character-shapes.js.map +1 -0
  93. package/lib/module/agent-avatar/config-character.js +4 -0
  94. package/lib/module/agent-avatar/config-character.js.map +1 -1
  95. package/lib/module/agent-avatar/legacy-recipe.js +19 -6
  96. package/lib/module/agent-avatar/legacy-recipe.js.map +1 -1
  97. package/lib/module/agent-creator/AgentCreatorBase.js +69 -109
  98. package/lib/module/agent-creator/AgentCreatorBase.js.map +1 -1
  99. package/lib/module/agent-creator/CharacterControls.js +24 -6
  100. package/lib/module/agent-creator/CharacterControls.js.map +1 -1
  101. package/lib/module/agent-creator/ClippoArtwork.js +59 -0
  102. package/lib/module/agent-creator/ClippoArtwork.js.map +1 -0
  103. package/lib/module/agent-creator/CyclopsArtwork.js +41 -0
  104. package/lib/module/agent-creator/CyclopsArtwork.js.map +1 -0
  105. package/lib/module/agent-creator/EmotionPicker.js +8 -1
  106. package/lib/module/agent-creator/EmotionPicker.js.map +1 -1
  107. package/lib/module/agent-creator/ShapeSilhouette.js +8 -1
  108. package/lib/module/agent-creator/ShapeSilhouette.js.map +1 -1
  109. package/lib/module/agent-creator/ToddArtwork.js +25 -0
  110. package/lib/module/agent-creator/ToddArtwork.js.map +1 -0
  111. package/lib/module/agent-creator/constants.js +8 -16
  112. package/lib/module/agent-creator/constants.js.map +1 -1
  113. package/lib/module/agent-creator/messages.js +1 -1
  114. package/lib/module/agent-creator/messages.js.map +1 -1
  115. package/lib/module/locale/translations/ar.js +1 -1
  116. package/lib/module/locale/translations/ar.js.map +1 -1
  117. package/lib/module/locale/translations/bn.js +1 -1
  118. package/lib/module/locale/translations/bn.js.map +1 -1
  119. package/lib/module/locale/translations/ca.js +1 -1
  120. package/lib/module/locale/translations/ca.js.map +1 -1
  121. package/lib/module/locale/translations/de.js +1 -1
  122. package/lib/module/locale/translations/de.js.map +1 -1
  123. package/lib/module/locale/translations/es.js +1 -1
  124. package/lib/module/locale/translations/es.js.map +1 -1
  125. package/lib/module/locale/translations/fr.js +1 -1
  126. package/lib/module/locale/translations/fr.js.map +1 -1
  127. package/lib/module/locale/translations/hi.js +1 -1
  128. package/lib/module/locale/translations/hi.js.map +1 -1
  129. package/lib/module/locale/translations/id.js +1 -1
  130. package/lib/module/locale/translations/id.js.map +1 -1
  131. package/lib/module/locale/translations/it.js +1 -1
  132. package/lib/module/locale/translations/it.js.map +1 -1
  133. package/lib/module/locale/translations/ja.js +1 -1
  134. package/lib/module/locale/translations/ja.js.map +1 -1
  135. package/lib/module/locale/translations/pt.js +1 -1
  136. package/lib/module/locale/translations/pt.js.map +1 -1
  137. package/lib/module/locale/translations/ru.js +1 -1
  138. package/lib/module/locale/translations/ru.js.map +1 -1
  139. package/lib/module/locale/translations/tr.js +1 -1
  140. package/lib/module/locale/translations/tr.js.map +1 -1
  141. package/lib/module/locale/translations/zh.js +1 -1
  142. package/lib/module/locale/translations/zh.js.map +1 -1
  143. package/lib/typescript/commonjs/agent-avatar/CharacterAvatar.d.ts.map +1 -1
  144. package/lib/typescript/commonjs/agent-avatar/character-colors.d.ts +13 -0
  145. package/lib/typescript/commonjs/agent-avatar/character-colors.d.ts.map +1 -0
  146. package/lib/typescript/commonjs/agent-avatar/character-shapes.d.ts +19 -0
  147. package/lib/typescript/commonjs/agent-avatar/character-shapes.d.ts.map +1 -0
  148. package/lib/typescript/commonjs/agent-avatar/config-character.d.ts +4 -0
  149. package/lib/typescript/commonjs/agent-avatar/config-character.d.ts.map +1 -1
  150. package/lib/typescript/commonjs/agent-avatar/legacy-recipe.d.ts +2 -10
  151. package/lib/typescript/commonjs/agent-avatar/legacy-recipe.d.ts.map +1 -1
  152. package/lib/typescript/commonjs/agent-creator/AgentCreatorBase.d.ts.map +1 -1
  153. package/lib/typescript/commonjs/agent-creator/CharacterControls.d.ts +2 -1
  154. package/lib/typescript/commonjs/agent-creator/CharacterControls.d.ts.map +1 -1
  155. package/lib/typescript/commonjs/agent-creator/ClippoArtwork.d.ts +6 -0
  156. package/lib/typescript/commonjs/agent-creator/ClippoArtwork.d.ts.map +1 -0
  157. package/lib/typescript/commonjs/agent-creator/CyclopsArtwork.d.ts +5 -0
  158. package/lib/typescript/commonjs/agent-creator/CyclopsArtwork.d.ts.map +1 -0
  159. package/lib/typescript/commonjs/agent-creator/EmotionPicker.d.ts +1 -0
  160. package/lib/typescript/commonjs/agent-creator/EmotionPicker.d.ts.map +1 -1
  161. package/lib/typescript/commonjs/agent-creator/ShapeSilhouette.d.ts.map +1 -1
  162. package/lib/typescript/commonjs/agent-creator/ToddArtwork.d.ts +6 -0
  163. package/lib/typescript/commonjs/agent-creator/ToddArtwork.d.ts.map +1 -0
  164. package/lib/typescript/commonjs/agent-creator/constants.d.ts +7 -15
  165. package/lib/typescript/commonjs/agent-creator/constants.d.ts.map +1 -1
  166. package/lib/typescript/commonjs/agent-creator/messages.d.ts.map +1 -1
  167. package/lib/typescript/module/agent-avatar/CharacterAvatar.d.ts.map +1 -1
  168. package/lib/typescript/module/agent-avatar/character-colors.d.ts +13 -0
  169. package/lib/typescript/module/agent-avatar/character-colors.d.ts.map +1 -0
  170. package/lib/typescript/module/agent-avatar/character-shapes.d.ts +19 -0
  171. package/lib/typescript/module/agent-avatar/character-shapes.d.ts.map +1 -0
  172. package/lib/typescript/module/agent-avatar/config-character.d.ts +4 -0
  173. package/lib/typescript/module/agent-avatar/config-character.d.ts.map +1 -1
  174. package/lib/typescript/module/agent-avatar/legacy-recipe.d.ts +2 -10
  175. package/lib/typescript/module/agent-avatar/legacy-recipe.d.ts.map +1 -1
  176. package/lib/typescript/module/agent-creator/AgentCreatorBase.d.ts.map +1 -1
  177. package/lib/typescript/module/agent-creator/CharacterControls.d.ts +2 -1
  178. package/lib/typescript/module/agent-creator/CharacterControls.d.ts.map +1 -1
  179. package/lib/typescript/module/agent-creator/ClippoArtwork.d.ts +6 -0
  180. package/lib/typescript/module/agent-creator/ClippoArtwork.d.ts.map +1 -0
  181. package/lib/typescript/module/agent-creator/CyclopsArtwork.d.ts +5 -0
  182. package/lib/typescript/module/agent-creator/CyclopsArtwork.d.ts.map +1 -0
  183. package/lib/typescript/module/agent-creator/EmotionPicker.d.ts +1 -0
  184. package/lib/typescript/module/agent-creator/EmotionPicker.d.ts.map +1 -1
  185. package/lib/typescript/module/agent-creator/ShapeSilhouette.d.ts.map +1 -1
  186. package/lib/typescript/module/agent-creator/ToddArtwork.d.ts +6 -0
  187. package/lib/typescript/module/agent-creator/ToddArtwork.d.ts.map +1 -0
  188. package/lib/typescript/module/agent-creator/constants.d.ts +7 -15
  189. package/lib/typescript/module/agent-creator/constants.d.ts.map +1 -1
  190. package/lib/typescript/module/agent-creator/messages.d.ts.map +1 -1
  191. package/package.json +1 -1
  192. package/src/agent-avatar/AgentAvatar.tsx +1 -1
  193. package/src/agent-avatar/CharacterAvatar.tsx +4 -1
  194. package/src/agent-avatar/character-colors.ts +12 -0
  195. package/src/agent-avatar/character-shapes.ts +122 -0
  196. package/src/agent-avatar/config-character.ts +39 -6
  197. package/src/agent-avatar/legacy-recipe.ts +34 -6
  198. package/src/agent-creator/AgentCreatorBase.tsx +121 -152
  199. package/src/agent-creator/CharacterControls.tsx +39 -14
  200. package/src/agent-creator/ClippoArtwork.tsx +49 -0
  201. package/src/agent-creator/CyclopsArtwork.tsx +27 -0
  202. package/src/agent-creator/EmotionPicker.tsx +55 -16
  203. package/src/agent-creator/ShapeSilhouette.tsx +16 -1
  204. package/src/agent-creator/ToddArtwork.tsx +24 -0
  205. package/src/agent-creator/constants.ts +47 -14
  206. package/src/agent-creator/messages.ts +2 -1
  207. package/src/locale/translations/ar.ts +1 -1
  208. package/src/locale/translations/bn.ts +1 -1
  209. package/src/locale/translations/ca.ts +1 -1
  210. package/src/locale/translations/de.ts +1 -1
  211. package/src/locale/translations/es.ts +1 -1
  212. package/src/locale/translations/fr.ts +1 -1
  213. package/src/locale/translations/hi.ts +1 -1
  214. package/src/locale/translations/id.ts +1 -1
  215. package/src/locale/translations/it.ts +1 -1
  216. package/src/locale/translations/ja.ts +1 -1
  217. package/src/locale/translations/pt.ts +1 -1
  218. package/src/locale/translations/ru.ts +1 -1
  219. package/src/locale/translations/tr.ts +1 -1
  220. package/src/locale/translations/zh.ts +1 -1
  221. package/src/__tests__/support/adoption-matrix.ts +0 -683
  222. package/src/__tests__/support/card-surface.ts +0 -25
  223. package/src/__tests__/support/collision-fixture-barrel.ts +0 -20
  224. package/src/__tests__/support/commerce-harness.tsx +0 -97
  225. package/src/__tests__/support/composite.ts +0 -68
  226. package/src/__tests__/support/constructed-style-sheets.ts +0 -68
  227. package/src/__tests__/support/messages-in.ts +0 -10
  228. package/src/__tests__/support/press-host.ts +0 -30
  229. package/src/__tests__/support/rendered-style.ts +0 -99
  230. package/src/__tests__/support/unread-hook-fixture.ts +0 -33
  231. package/src/__tests__/support/worklet-capture-fixture.tsx +0 -28
  232. package/src/agent-avatar/__tests__/artwork-golden.json +0 -774
  233. package/src/agent-creator/__tests__/support/character-runtime-fixture.tsx +0 -26
  234. package/src/theme/__tests__/__fixtures__/golden-resolved-tokens.json +0 -9346
  235. package/src/theme/__tests__/__fixtures__/tonal-glass-primary-failures.json +0 -69
  236. package/src/theme/__tests__/fixtures/color-engine-golden.json +0 -1
@@ -1,4 +1,4 @@
1
- import { useContext } from 'react';
1
+ import { useContext, useRef } from 'react';
2
2
  import {
3
3
  CharacterRuntimeContext,
4
4
  CharacterCapabilitiesContext,
@@ -16,10 +16,12 @@ import { useAgentCreatorBindings, useAgentCreatorMessages } from './context';
16
16
  export function CharacterControls({
17
17
  character,
18
18
  capabilitiesKey,
19
+ selected,
19
20
  onChange,
20
21
  }: {
21
22
  character?: AvatarCharacterConfig;
22
23
  capabilitiesKey?: string;
24
+ selected?: Readonly<Record<string, string>>;
23
25
  onChange: (character: AvatarCharacterConfig | undefined) => void;
24
26
  }) {
25
27
  const messages = useAgentCreatorMessages();
@@ -36,11 +38,21 @@ export function CharacterControls({
36
38
  SelectItem,
37
39
  SelectItemText,
38
40
  } = useAgentCreatorBindings();
39
- if (!runtimeUrl) return null;
40
41
  const key = capabilitiesKey ?? JSON.stringify(character);
41
- const resolved =
42
+ const current =
42
43
  capabilitiesByKey?.get(key) ??
43
44
  (character && capabilities?.key === key ? capabilities : undefined);
45
+ const retained = useRef<{
46
+ preset?: string;
47
+ selected: Readonly<Record<string, string>>;
48
+ }>({ selected: {} });
49
+ if (retained.current.preset !== character?.preset)
50
+ retained.current = { preset: character?.preset, selected: {} };
51
+ if (current) retained.current.selected = current.selected;
52
+ const resolved = {
53
+ selected: selected ?? current?.selected ?? retained.current.selected,
54
+ };
55
+ if (!runtimeUrl) return null;
44
56
  const row = (
45
57
  label: string,
46
58
  value: string,
@@ -90,11 +102,14 @@ export function CharacterControls({
90
102
  if (character && !presets.some((item) => item.id === character.preset))
91
103
  presets.push({
92
104
  id: character.preset,
93
- title: messages.characterOption(
94
- 'preset',
95
- character.preset,
96
- character.preset,
97
- ),
105
+ title:
106
+ character.preset === 'legacy'
107
+ ? messages.proceduralAvatar
108
+ : messages.characterOption(
109
+ 'preset',
110
+ character.preset,
111
+ character.preset,
112
+ ),
98
113
  });
99
114
  const labels: Record<AvatarCharacterCategory, string> = {
100
115
  shape: messages.shape,
@@ -120,8 +135,8 @@ export function CharacterControls({
120
135
  (category) =>
121
136
  row(
122
137
  labels[category],
123
- resolved?.selected[category] ??
124
- character.selections?.[category] ??
138
+ character.selections?.[category] ??
139
+ resolved?.selected[category] ??
125
140
  'none',
126
141
  (category === 'accessory'
127
142
  ? [
@@ -132,14 +147,24 @@ export function CharacterControls({
132
147
  ).map(([id, title]) => ({
133
148
  id,
134
149
  title: messages.characterOption(category, id, title),
135
- disabled:
136
- !resolved ||
137
- resolved.available[`${category}:${id}`] === false,
150
+ disabled: false,
138
151
  })),
139
152
  (id) => {
140
153
  onChange({
141
154
  ...character,
142
- selections: { ...character.selections, [category]: id },
155
+ selections: {
156
+ ...(['eyes', 'eyewear', 'accessory'] as const).reduce(
157
+ (parts, part) => ({
158
+ ...parts,
159
+ ...(resolved?.selected[part]
160
+ ? { [part]: resolved.selected[part] }
161
+ : {}),
162
+ }),
163
+ {},
164
+ ),
165
+ ...character.selections,
166
+ [category]: id,
167
+ },
143
168
  });
144
169
  },
145
170
  labels[category],
@@ -0,0 +1,49 @@
1
+ import Svg, { Circle, Path } from 'react-native-svg';
2
+ import { CHARACTER_COLORS } from './constants';
3
+
4
+ /** Selector artwork only. The avatar itself uses Clippo's actual 3D meshes. */
5
+ export function ClippoArtwork({
6
+ kind,
7
+ opacity = 1,
8
+ }: {
9
+ kind: 'shape' | 'eyes';
10
+ opacity?: number;
11
+ }) {
12
+ const eyes = kind === 'eyes';
13
+ return (
14
+ <Svg
15
+ width={eyes ? 27 : 56}
16
+ height={eyes ? 27 : 56}
17
+ viewBox={eyes ? '0 0 104 100' : '0 -4 90 170'}
18
+ preserveAspectRatio="xMidYMid meet"
19
+ opacity={opacity}
20
+ accessible={false}
21
+ pointerEvents="none"
22
+ >
23
+ {eyes ? (
24
+ <>
25
+ <Circle cx={27} cy={44} r={21} fill="#f4f3ee" />
26
+ <Circle cx={77} cy={58} r={21} fill="#f4f3ee" />
27
+ <Circle cx={27} cy={44} r={15} fill="#3c2b2d" />
28
+ <Circle cx={77} cy={58} r={15} fill="#3c2b2d" />
29
+ <Path
30
+ d="M11 8 C18 5 29 5 38 9 M63 21 C72 21 82 26 88 32"
31
+ fill="none"
32
+ stroke="#3c2b2d"
33
+ strokeWidth={12}
34
+ strokeLinecap="round"
35
+ />
36
+ </>
37
+ ) : (
38
+ <Path
39
+ d="M25.4 79 C23 102 24 115 35 120 C46 125 53 119 52 105 C48 84 46 63 56 40 C67 16 63 6 46 3 C27 -1 20 15 14 30 C5 51 2 70 5 91 C8 128 19 151 40 157 C57 162 72 153 75 134 C80 114 69 107 72 93 C73 83 76 75 80 71"
40
+ fill="none"
41
+ stroke={CHARACTER_COLORS.pink}
42
+ strokeWidth={8.5}
43
+ strokeLinecap="round"
44
+ strokeLinejoin="round"
45
+ />
46
+ )}
47
+ </Svg>
48
+ );
49
+ }
@@ -0,0 +1,27 @@
1
+ import Svg, { Circle, Ellipse, Path } from 'react-native-svg';
2
+
3
+ /** Static selector artwork; the runtime renders the fitted single-eye mesh. */
4
+ export function CyclopsArtwork({ opacity = 1 }: { opacity?: number }) {
5
+ return (
6
+ <Svg
7
+ width={27}
8
+ height={27}
9
+ viewBox="0 0 100 100"
10
+ opacity={opacity}
11
+ accessible={false}
12
+ pointerEvents="none"
13
+ >
14
+ <Ellipse cx={50} cy={50} rx={46} ry={44} fill="#f4f5ee" />
15
+ <Circle
16
+ cx={50}
17
+ cy={50}
18
+ r={24}
19
+ fill="#148a78"
20
+ stroke="#174e45"
21
+ strokeWidth={3}
22
+ />
23
+ <Circle cx={50} cy={50} r={14} fill="#101918" />
24
+ <Path d="M61 31 L71 38 L65 46 L57 40 Z" fill="#ffffff" />
25
+ </Svg>
26
+ );
27
+ }
@@ -12,13 +12,26 @@ import Animated, {
12
12
  } from 'react-native-reanimated';
13
13
  import { EYES, type AvatarConfig } from '../agent-avatar';
14
14
  import { AgentFace } from '../agent-avatar/AgentFace';
15
- import { StyledImage, StyledPressable, StyledView } from '../styles/styled-primitives';
15
+ import { ClippoArtwork } from './ClippoArtwork';
16
+ import { CyclopsArtwork } from './CyclopsArtwork';
17
+ import {
18
+ StyledImage,
19
+ StyledPressable,
20
+ StyledView,
21
+ } from '../styles/styled-primitives';
16
22
  import { useTheme } from '../theme/use-theme';
17
23
  import { useAgentCreatorMessages } from './context';
18
24
  import { useTrackEvents } from './use-track-events';
19
25
 
20
26
  const AnimatedView = Animated.createAnimatedComponent(StyledView);
21
- export type EmotionChoice = { id: string; label: string; config: AvatarConfig; disabled?: boolean; thumbnail?: string };
27
+ export type EmotionChoice = {
28
+ id: string;
29
+ label: string;
30
+ config: AvatarConfig;
31
+ disabled?: boolean;
32
+ thumbnail?: string;
33
+ artwork?: 'clippo' | 'cyclops';
34
+ };
22
35
  function Emotion({
23
36
  config,
24
37
  choice,
@@ -71,21 +84,40 @@ function Emotion({
71
84
  pointerEvents="auto"
72
85
  className={`pointer-events-auto flex size-[34px] cursor-pointer items-center justify-center overflow-hidden rounded-full border-2 outline-none transition-[border-color,box-shadow] hover:ring-2 hover:ring-border-button-hover focus-visible:ring-2 focus-visible:ring-border-focus-ring ${active ? 'border-foreground-icon-secondary' : 'border-transparent'}`}
73
86
  style={{
74
- backgroundColor: backgroundColor ?? `hsl(${config.hue}, ${config.saturation}%, ${config.lightness ?? 80}%)`,
87
+ backgroundColor:
88
+ backgroundColor ??
89
+ `hsl(${config.hue}, ${config.saturation}%, ${config.lightness ?? 80}%)`,
75
90
  borderColor: active ? colors.icon : 'transparent',
76
91
  }}
77
92
  >
78
- {choice.thumbnail ? <StyledImage source={{ uri: choice.thumbnail }} resizeMode="contain" accessible={false} style={{ width: 27, height: 27, opacity: choice.disabled ? 0.35 : 1 }} /> : <AgentFace
79
- config={{
80
- ...choice.config,
81
- eyeSize: 24,
82
- eyeGap: 36,
83
- lookAt: 'center',
84
- motion: 0,
85
- idle: false,
86
- }}
87
- size={34}
88
- />}
93
+ {choice.artwork === 'cyclops' ? (
94
+ <CyclopsArtwork opacity={choice.disabled ? 0.35 : 1} />
95
+ ) : choice.artwork === 'clippo' ? (
96
+ <ClippoArtwork kind="eyes" opacity={choice.disabled ? 0.35 : 1} />
97
+ ) : choice.thumbnail ? (
98
+ <StyledImage
99
+ source={{ uri: choice.thumbnail }}
100
+ resizeMode="contain"
101
+ accessible={false}
102
+ style={{
103
+ width: 27,
104
+ height: 27,
105
+ opacity: choice.disabled ? 0.35 : 1,
106
+ }}
107
+ />
108
+ ) : (
109
+ <AgentFace
110
+ config={{
111
+ ...choice.config,
112
+ eyeSize: 24,
113
+ eyeGap: 36,
114
+ lookAt: 'center',
115
+ motion: 0,
116
+ idle: false,
117
+ }}
118
+ size={34}
119
+ />
120
+ )}
89
121
  </StyledPressable>
90
122
  </AnimatedView>
91
123
  </StyledView>
@@ -109,9 +141,16 @@ export function EmotionPicker({
109
141
  onChange: (eyes: AvatarConfig['eyes']) => void;
110
142
  }) {
111
143
  const messages = useAgentCreatorMessages();
112
- const choices = choicesProp ?? EYES.map((eyes) => ({ id: eyes, label: messages.emotions[eyes], config: { ...config, eyes } }));
144
+ const choices =
145
+ choicesProp ??
146
+ EYES.map((eyes) => ({
147
+ id: eyes,
148
+ label: messages.emotions[eyes],
149
+ config: { ...config, eyes },
150
+ }));
113
151
  const value = valueProp ?? config.eyes;
114
- const emit = (id: string) => onSelect ? onSelect(id) : onChange(id as AvatarConfig['eyes']);
152
+ const emit = (id: string) =>
153
+ onSelect ? onSelect(id) : onChange(id as AvatarConfig['eyes']);
115
154
  const ref = useRef<View>(null);
116
155
  const visible = useSharedValue(true);
117
156
  const target = useSharedValue(0);
@@ -1,9 +1,12 @@
1
+ import { characterShapeGeometry } from '../agent-avatar/character-shapes';
1
2
  import { memo } from 'react';
2
3
  import Svg, { Path } from 'react-native-svg';
3
4
  import { legacyContours } from '../agent-avatar/legacy-contours';
4
5
  import { radialContour } from '../agent-avatar/legacy-recipe';
5
6
  import type { AvatarConfig } from '../agent-avatar/model';
6
7
  import { CHARACTER_COLORS } from './constants';
8
+ import { ClippoArtwork } from './ClippoArtwork';
9
+ import { ToddArtwork } from './ToddArtwork';
7
10
 
8
11
  const silhouettes = new Map<string, { path: string; viewBox: string }>();
9
12
 
@@ -49,7 +52,19 @@ export const ShapeSilhouette = memo(function ShapeSilhouette({
49
52
  }: {
50
53
  config: AvatarConfig;
51
54
  }) {
52
- const { path, viewBox } = silhouette(config);
55
+ if (
56
+ config.character?.selections?.shape === 'todd' ||
57
+ (config.character?.preset === 'lime_frog' &&
58
+ !config.character.selections?.shape)
59
+ )
60
+ return <ToddArtwork />;
61
+ if (
62
+ config.character?.selections?.shape === 'clippo' ||
63
+ (config.character?.preset === 'clippo' &&
64
+ !config.character.selections?.shape)
65
+ )
66
+ return <ClippoArtwork kind="shape" />;
67
+ const { path, viewBox } = silhouette(characterShapeGeometry(config));
53
68
  return (
54
69
  <Svg
55
70
  width={56}
@@ -0,0 +1,24 @@
1
+ import Svg, { Path } from 'react-native-svg';
2
+ import { CHARACTER_COLORS } from './constants';
3
+
4
+ /** Static Todd body outline: 128 projected triangle intersections from the
5
+ * original lime_frog mesh (2,502 vertices), with engine Y-up reflected for SVG.
6
+ * This selector does not load the renderer or substitute another body shape.
7
+ */
8
+ export function ToddArtwork() {
9
+ return (
10
+ <Svg
11
+ width={56}
12
+ height={56}
13
+ viewBox="-1.04785 -0.86450 2.09611 1.69982"
14
+ preserveAspectRatio="xMidYMid meet"
15
+ accessible={false}
16
+ pointerEvents="none"
17
+ >
18
+ <Path
19
+ d="M0.9822 0.0000 L0.9686 -0.0476 L0.9504 -0.0936 L0.9289 -0.1378 L0.8988 -0.1788 L0.8645 -0.2165 L0.8334 -0.2528 L0.8060 -0.2884 L0.7878 -0.3263 L0.7842 -0.3709 L0.7896 -0.4221 L0.7977 -0.4781 L0.7977 -0.5330 L0.7882 -0.5845 L0.7697 -0.6317 L0.7439 -0.6742 L0.7120 -0.7120 L0.6747 -0.7444 L0.6333 -0.7717 L0.5869 -0.7914 L0.5384 -0.8058 L0.4878 -0.8139 L0.4348 -0.8135 L0.3814 -0.8063 L0.3272 -0.7900 L0.2726 -0.7618 L0.2193 -0.7230 L0.1675 -0.6686 L0.1242 -0.6245 L0.0877 -0.5910 L0.0565 -0.5733 L0.0277 -0.5641 L0.0000 -0.5610 L-0.0277 -0.5636 L-0.0563 -0.5720 L-0.0876 -0.5906 L-0.1236 -0.6212 L-0.1670 -0.6665 L-0.2181 -0.7190 L-0.2733 -0.7638 L-0.3269 -0.7893 L-0.3814 -0.8064 L-0.4354 -0.8146 L-0.4878 -0.8139 L-0.5385 -0.8060 L-0.5874 -0.7921 L-0.6331 -0.7714 L-0.6751 -0.7449 L-0.7120 -0.7120 L-0.7443 -0.6746 L-0.7697 -0.6316 L-0.7875 -0.5840 L-0.7971 -0.5326 L-0.7983 -0.4785 L-0.7901 -0.4223 L-0.7830 -0.3703 L-0.7880 -0.3264 L-0.8071 -0.2888 L-0.8338 -0.2529 L-0.8655 -0.2168 L-0.8995 -0.1789 L-0.9306 -0.1380 L-0.9510 -0.0937 L-0.9680 -0.0476 L-0.9814 -0.0000 L-0.9905 0.0487 L-0.9963 0.0981 L-0.9977 0.1480 L-0.9949 0.1979 L-0.9894 0.2478 L-0.9778 0.2966 L-0.9633 0.3447 L-0.9445 0.3912 L-0.9222 0.4362 L-0.8967 0.4793 L-0.8671 0.5197 L-0.8348 0.5578 L-0.8002 0.5934 L-0.7633 0.6264 L-0.7239 0.6561 L-0.6831 0.6831 L-0.6404 0.7066 L-0.5966 0.7269 L-0.5520 0.7443 L-0.5063 0.7578 L-0.4614 0.7698 L-0.4151 0.7766 L-0.3696 0.7816 L-0.3252 0.7850 L-0.2809 0.7851 L-0.2382 0.7851 L-0.1967 0.7851 L-0.1562 0.7851 L-0.1165 0.7852 L-0.0773 0.7852 L-0.0386 0.7852 L-0.0000 0.7852 L0.0386 0.7853 L0.0773 0.7853 L0.1165 0.7853 L0.1562 0.7853 L0.1967 0.7854 L0.2382 0.7854 L0.2810 0.7854 L0.3247 0.7840 L0.3699 0.7820 L0.4151 0.7766 L0.4614 0.7697 L0.5064 0.7578 L0.5522 0.7446 L0.5960 0.7262 L0.6403 0.7064 L0.6829 0.6829 L0.7237 0.6559 L0.7631 0.6262 L0.8002 0.5935 L0.8348 0.5578 L0.8675 0.5200 L0.8963 0.4791 L0.9217 0.4359 L0.9446 0.3913 L0.9632 0.3447 L0.9779 0.2966 L0.9887 0.2477 L0.9951 0.1979 L0.9977 0.1480 L0.9961 0.0981 L0.9912 0.0487Z"
20
+ fill={CHARACTER_COLORS.pink}
21
+ />
22
+ </Svg>
23
+ );
24
+ }
@@ -1,3 +1,4 @@
1
+ import { NATIVE_CHARACTER_SHAPES } from '../agent-avatar/character-shapes';
1
2
  import type { AgentLanguage, AgentPreferences } from './types';
2
3
  export const AGENT_LANGUAGES = [
3
4
  { id: 'auto', label: 'Auto-detect' },
@@ -58,6 +59,7 @@ export const PREVIEW_TEXT: Record<AgentLanguage, string> = {
58
59
 
59
60
  // Recovered engine catalog metadata. IDs are renderer selections; titles retain the beta catalog's English defaults.
60
61
  export const CHARACTER_PRESETS = [
62
+ { id: 'clippo', title: 'Clippo' },
61
63
  { id: 'blue_beret', title: 'Felipe' },
62
64
  { id: 'alfred', title: 'Alfred' },
63
65
  { id: 'purple_heart', title: 'Jojo' },
@@ -68,20 +70,51 @@ export const CHARACTER_PRESETS = [
68
70
  { id: 'lime_headphones', title: 'Iggy' },
69
71
  ] as const;
70
72
  export const CHARACTER_OPTIONS = {
71
- shape: [
72
- ['circle', 'Circle'], ['rounded_triangle', 'Rounded triangle'], ['capsule', 'Capsule'],
73
- ['rounded_head_two_ears', 'Rounded head with two ears'], ['six_lobed_flower', 'Six lobed flower'],
74
- ['heart', 'Heart'], ['four_lobed_butterfly', 'Four lobed butterfly'], ['circle_two_ears', 'Circle with two ears'],
75
- ['twelve_scalloped_rosette', 'Twelve scalloped rosette'], ['rounded_cube', 'Hexagon'], ['rounded_diamond', 'Rounded diamond'],
73
+ shape: NATIVE_CHARACTER_SHAPES,
74
+ color: [
75
+ ['pink', 'Pink'],
76
+ ['orchid', 'Orchid'],
77
+ ['violet', 'Violet'],
78
+ ['blue', 'Blue'],
79
+ ['cyan', 'Cyan'],
80
+ ['teal', 'Teal'],
81
+ ['lime', 'Lime'],
82
+ ['yellow', 'Yellow'],
83
+ ['coral', 'Coral'],
84
+ ],
85
+ eyes: [
86
+ ['cyclops', 'Single eye'],
87
+ ['clippo', 'Clippo'],
88
+ ['todd', 'Todd'],
89
+ ['swept_lids', 'Swept lids'],
90
+ ['oval', 'Oval'],
91
+ ['sparkle_capsules', 'Sparkle capsules'],
92
+ ['highlight_capsules', 'Highlight capsules'],
93
+ ['dots', 'Dots'],
94
+ ['double_highlights', 'Round highlights'],
95
+ ['round_inset', 'Round inset'],
96
+ ['crescent_inset', 'Crescent inset'],
97
+ ['sleepy_lids', 'Sleepy lids'],
98
+ ],
99
+ eyewear: [
100
+ ['none', 'None'],
101
+ ['monocle', 'Monocle'],
102
+ ['tall_oval_frames', 'Tall oval frames'],
103
+ ['separate_trapezoid_lenses', 'Separate trapezoid lenses'],
104
+ ['classic_sunglasses', 'Classic sunglasses'],
105
+ ['round_sunglasses', 'Round sunglasses'],
106
+ ],
107
+ accessory: [
108
+ ['headphones', 'Headphones'],
109
+ ['bow', 'Bow tie'],
110
+ ['beanie', 'Beanie'],
111
+ ['hat', 'Hat'],
112
+ ['beret', 'Beret'],
113
+ ['felipe_beret', 'Felipe’s beret'],
114
+ ['orb', 'Bulb'],
115
+ ['three_lobe', 'Tuft'],
116
+ ['crown', 'Crown'],
76
117
  ],
77
- color: [['pink', 'Pink'], ['orchid', 'Orchid'], ['violet', 'Violet'], ['blue', 'Blue'], ['cyan', 'Cyan'], ['teal', 'Teal'], ['lime', 'Lime'], ['yellow', 'Yellow'], ['coral', 'Coral']],
78
- eyes: [['swept_lids', 'Swept lids'], ['oval', 'Oval'], ['sparkle_capsules', 'Sparkle capsules'], ['highlight_capsules', 'Highlight capsules'], ['dots', 'Dots'], ['double_highlights', 'Round highlights'], ['round_inset', 'Round inset'], ['crescent_inset', 'Crescent inset'], ['sleepy_lids', 'Sleepy lids']],
79
- eyewear: [['none', 'None'], ['monocle', 'Monocle'], ['tall_oval_frames', 'Tall oval frames'], ['separate_trapezoid_lenses', 'Separate trapezoid lenses'], ['classic_sunglasses', 'Classic sunglasses'], ['round_sunglasses', 'Round sunglasses']],
80
- accessory: [['headphones', 'Headphones'], ['bow', 'Bow tie'], ['beanie', 'Beanie'], ['hat', 'Hat'], ['beret', 'Beret'], ['orb', 'Bulb'], ['three_lobe', 'Tuft'], ['crown', 'Crown']],
81
118
  } as const;
82
119
 
83
- /** RGB swatches returned by the recovered engine's Color catalog. */
84
- export const CHARACTER_COLORS = {
85
- pink: '#fa70ab', orchid: '#dd6adc', violet: '#a25bff', blue: '#4778ff', cyan: '#00b1ff',
86
- teal: '#04bb9f', lime: '#b6d80b', yellow: '#ffcc38', coral: '#ff8066',
87
- } as const;
120
+ export { CHARACTER_COLORS } from '../agent-avatar/character-colors';
@@ -114,7 +114,8 @@ export const AGENT_CREATOR_MESSAGES: MessageCatalog<AgentCreatorMessages> =
114
114
  betaEyes: 'Eye style',
115
115
  eyewear: 'Eyewear',
116
116
  accessory: 'Accessory',
117
- characterOption: (_category, _id, title) => String(title),
117
+ characterOption: (category, id, title) =>
118
+ category === 'eyes' && id === 'cyclops' ? 'Single eye' : String(title),
118
119
  editor: 'Agent editor',
119
120
  newBot: 'New bot',
120
121
  closeEditor: 'Close agent editor',
@@ -34,7 +34,7 @@ const AGENT_CREATOR_MESSAGES: Translations['AGENT_CREATOR_MESSAGES'] = {
34
34
  betaEyes: "نمط العيون",
35
35
  eyewear: "نظارات",
36
36
  accessory: "إكسسوار",
37
- characterOption: (_category, _id, title) => String(title),
37
+ characterOption: (category, id, title) => category === "eyes" && id === "cyclops" ? "عين واحدة" : String(title),
38
38
  editor: "محرر الوكيل",
39
39
  newBot: "روبوت جديد",
40
40
  closeEditor: "إغلاق محرر الوكيل",
@@ -24,7 +24,7 @@ const AGENT_CREATOR_MESSAGES: Translations['AGENT_CREATOR_MESSAGES'] = {
24
24
  betaEyes: "চোখের ধরন",
25
25
  eyewear: "চশমা",
26
26
  accessory: "অনুষঙ্গ",
27
- characterOption: (_category, _id, title) => String(title),
27
+ characterOption: (category, id, title) => category === "eyes" && id === "cyclops" ? "একটি চোখ" : String(title),
28
28
  editor: "এজেন্ট সম্পাদক",
29
29
  newBot: "নতুন বট",
30
30
  closeEditor: "এজেন্ট সম্পাদক বন্ধ করুন",
@@ -31,7 +31,7 @@ const AGENT_CREATOR_MESSAGES: Translations['AGENT_CREATOR_MESSAGES'] = {
31
31
  betaEyes: "Estil dels ulls",
32
32
  eyewear: "Ulleres",
33
33
  accessory: "Accessori",
34
- characterOption: (_category, _id, title) => String(title),
34
+ characterOption: (category, id, title) => category === "eyes" && id === "cyclops" ? "Un sol ull" : String(title),
35
35
  editor: "Editor de l’agent",
36
36
  newBot: "Bot nou",
37
37
  closeEditor: "Tanca l’editor de l’agent",
@@ -26,7 +26,7 @@ const AGENT_CREATOR_MESSAGES: Translations['AGENT_CREATOR_MESSAGES'] = {
26
26
  betaEyes: "Augenstil",
27
27
  eyewear: "Brille",
28
28
  accessory: "Accessoire",
29
- characterOption: (_category, _id, title) => String(title),
29
+ characterOption: (category, id, title) => category === "eyes" && id === "cyclops" ? "Einzelnes Auge" : String(title),
30
30
  editor: "Agenten-Editor",
31
31
  newBot: "Neuer Bot",
32
32
  closeEditor: "Agenten-Editor schließen",
@@ -31,7 +31,7 @@ const AGENT_CREATOR_MESSAGES: Translations['AGENT_CREATOR_MESSAGES'] = {
31
31
  betaEyes: "Estilo de ojos",
32
32
  eyewear: "Gafas",
33
33
  accessory: "Accesorio",
34
- characterOption: (_category, _id, title) => String(title),
34
+ characterOption: (category, id, title) => category === "eyes" && id === "cyclops" ? "Un solo ojo" : String(title),
35
35
  editor: "Editor del agente",
36
36
  newBot: "Nuevo bot",
37
37
  closeEditor: "Cerrar editor del agente",
@@ -31,7 +31,7 @@ const AGENT_CREATOR_MESSAGES: Translations['AGENT_CREATOR_MESSAGES'] = {
31
31
  betaEyes: "Style des yeux",
32
32
  eyewear: "Lunettes",
33
33
  accessory: "Accessoire",
34
- characterOption: (_category, _id, title) => String(title),
34
+ characterOption: (category, id, title) => category === "eyes" && id === "cyclops" ? "Œil unique" : String(title),
35
35
  editor: "Éditeur de l’agent",
36
36
  newBot: "Nouveau bot",
37
37
  closeEditor: "Fermer l’éditeur de l’agent",
@@ -24,7 +24,7 @@ const AGENT_CREATOR_MESSAGES: Translations['AGENT_CREATOR_MESSAGES'] = {
24
24
  betaEyes: "आँखों की शैली",
25
25
  eyewear: "चश्मा",
26
26
  accessory: "सहायक वस्तु",
27
- characterOption: (_category, _id, title) => String(title),
27
+ characterOption: (category, id, title) => category === "eyes" && id === "cyclops" ? "एक आँख" : String(title),
28
28
  editor: "एजेंट संपादक",
29
29
  newBot: "नया बॉट",
30
30
  closeEditor: "एजेंट संपादक बंद करें",
@@ -24,7 +24,7 @@ const AGENT_CREATOR_MESSAGES: Translations['AGENT_CREATOR_MESSAGES'] = {
24
24
  betaEyes: "Gaya mata",
25
25
  eyewear: "Kacamata",
26
26
  accessory: "Aksesori",
27
- characterOption: (_category, _id, title) => String(title),
27
+ characterOption: (category, id, title) => category === "eyes" && id === "cyclops" ? "Satu mata" : String(title),
28
28
  editor: "Editor agen",
29
29
  newBot: "Bot baru",
30
30
  closeEditor: "Tutup editor agen",
@@ -31,7 +31,7 @@ const AGENT_CREATOR_MESSAGES: Translations['AGENT_CREATOR_MESSAGES'] = {
31
31
  betaEyes: "Stile degli occhi",
32
32
  eyewear: "Occhiali",
33
33
  accessory: "Accessorio",
34
- characterOption: (_category, _id, title) => String(title),
34
+ characterOption: (category, id, title) => category === "eyes" && id === "cyclops" ? "Occhio singolo" : String(title),
35
35
  editor: "Editor dell’agente",
36
36
  newBot: "Nuovo bot",
37
37
  closeEditor: "Chiudi l’editor dell’agente",
@@ -24,7 +24,7 @@ const AGENT_CREATOR_MESSAGES: Translations['AGENT_CREATOR_MESSAGES'] = {
24
24
  betaEyes: "目のスタイル",
25
25
  eyewear: "眼鏡",
26
26
  accessory: "アクセサリー",
27
- characterOption: (_category, _id, title) => String(title),
27
+ characterOption: (category, id, title) => category === "eyes" && id === "cyclops" ? "一つ目" : String(title),
28
28
  editor: "エージェント編集",
29
29
  newBot: "新しいボット",
30
30
  closeEditor: "エージェント編集を閉じる",
@@ -31,7 +31,7 @@ const AGENT_CREATOR_MESSAGES: Translations['AGENT_CREATOR_MESSAGES'] = {
31
31
  betaEyes: "Estilo dos olhos",
32
32
  eyewear: "Óculos",
33
33
  accessory: "Acessório",
34
- characterOption: (_category, _id, title) => String(title),
34
+ characterOption: (category, id, title) => category === "eyes" && id === "cyclops" ? "Olho único" : String(title),
35
35
  editor: "Editor do agente",
36
36
  newBot: "Novo bot",
37
37
  closeEditor: "Fechar editor do agente",
@@ -27,7 +27,7 @@ const AGENT_CREATOR_MESSAGES: Translations['AGENT_CREATOR_MESSAGES'] = {
27
27
  betaEyes: "Стиль глаз",
28
28
  eyewear: "Очки",
29
29
  accessory: "Аксессуар",
30
- characterOption: (_category, _id, title) => String(title),
30
+ characterOption: (category, id, title) => category === "eyes" && id === "cyclops" ? "Один глаз" : String(title),
31
31
  editor: "Редактор агента",
32
32
  newBot: "Новый бот",
33
33
  closeEditor: "Закрыть редактор агента",
@@ -24,7 +24,7 @@ const AGENT_CREATOR_MESSAGES: Translations['AGENT_CREATOR_MESSAGES'] = {
24
24
  betaEyes: "Göz stili",
25
25
  eyewear: "Gözlük",
26
26
  accessory: "Aksesuar",
27
- characterOption: (_category, _id, title) => String(title),
27
+ characterOption: (category, id, title) => category === "eyes" && id === "cyclops" ? "Tek göz" : String(title),
28
28
  editor: "Ajan düzenleyici",
29
29
  newBot: "Yeni bot",
30
30
  closeEditor: "Ajan düzenleyiciyi kapat",
@@ -24,7 +24,7 @@ const AGENT_CREATOR_MESSAGES: Translations['AGENT_CREATOR_MESSAGES'] = {
24
24
  betaEyes: "眼睛风格",
25
25
  eyewear: "眼镜",
26
26
  accessory: "配饰",
27
- characterOption: (_category, _id, title) => String(title),
27
+ characterOption: (category, id, title) => category === "eyes" && id === "cyclops" ? "单眼" : String(title),
28
28
  editor: "智能体编辑器",
29
29
  newBot: "新机器人",
30
30
  closeEditor: "关闭智能体编辑器",