@springbrand/message-panel 0.1.3-alpha.9 → 0.2.0-alpha.37
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.
- package/cloud-os/README.md +4 -3
- package/cloud-os/assets/followup-arrow.svg +3 -0
- package/cloud-os/assets/loading-corner.svg +3 -0
- package/cloud-os/assets/loading-mark.svg +16 -0
- package/cloud-os/assets/loading-spark.svg +3 -0
- package/cloud-os/assets/model-selected.svg +5 -0
- package/cloud-os/assets/thinking-star.svg +9 -0
- package/cloud-os/capability-chip.tsx +1 -1
- package/cloud-os/chat/cloud-os-chat-messages.tsx +441 -98
- package/cloud-os/chat/code-runner.tsx +106 -0
- package/cloud-os/chat/image-generation.tsx +76 -0
- package/cloud-os/chat/loading-state.tsx +25 -0
- package/cloud-os/chat/markdown-message.tsx +144 -41
- package/cloud-os/chat/range.ts +8 -0
- package/cloud-os/chat/rich-blocks.tsx +285 -227
- package/cloud-os/chat/surfaces.tsx +90 -0
- package/cloud-os/chat/tool-call.tsx +94 -0
- package/cloud-os/chat/tool-presentation.ts +31 -22
- package/cloud-os/chat/tool-rows.tsx +195 -143
- package/cloud-os/chat/tool-timeline.tsx +123 -0
- package/cloud-os/chat/transcript-model.ts +258 -20
- package/cloud-os/chat/web-search.tsx +135 -0
- package/cloud-os/composer/cloud-os-chat-input.tsx +29 -88
- package/cloud-os/composer/cloud-os-model-select.tsx +105 -0
- package/cloud-os/file-view.tsx +195 -12
- package/cloud-os/index.ts +24 -3
- package/cloud-os/layout/cloud-os-workspace-split.tsx +60 -3
- package/cloud-os/primitives/collapsible.tsx +21 -0
- package/cloud-os/primitives/workshop-controls.tsx +2 -2
- package/cloud-os/styles/cloud-os.css +132 -1
- package/demo/camel-chat-showcase.tsx +21 -13
- package/demo/chat-scenarios.ts +214 -40
- package/demo/cloud-os-chat-showcase.tsx +37 -14
- package/demo/fixtures.ts +4 -5
- package/demo/message-panel-gallery.tsx +16 -2
- package/package.json +8 -4
- package/springbrand-pet/LICENSE.bloub +21 -0
- package/springbrand-pet/bot/cycles.test.ts +221 -0
- package/springbrand-pet/bot/cycles.ts +225 -0
- package/springbrand-pet/bot/decor.ts +285 -0
- package/springbrand-pet/bot/engine.test.ts +543 -0
- package/springbrand-pet/bot/engine.ts +558 -0
- package/springbrand-pet/bot/expressions.test.ts +135 -0
- package/springbrand-pet/bot/expressions.ts +192 -0
- package/springbrand-pet/bot/eyefit.ts +455 -0
- package/springbrand-pet/bot/face.test.ts +101 -0
- package/springbrand-pet/bot/face.ts +179 -0
- package/springbrand-pet/bot/math.ts +42 -0
- package/springbrand-pet/bot/profiles.ts +22 -0
- package/springbrand-pet/bot/repere.ts +31 -0
- package/springbrand-pet/bot/shape.test.ts +97 -0
- package/springbrand-pet/bot/shape.ts +310 -0
- package/springbrand-pet/bot/skins.test.ts +325 -0
- package/springbrand-pet/bot/skins.ts +161 -0
- package/springbrand-pet/bot/states.ts +616 -0
- package/springbrand-pet/drag.test.ts +19 -0
- package/springbrand-pet/index.tsx +569 -0
- package/springbrand-pet/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/springbrand-pet/vitest.config.ts +9 -0
- package/src/camel/camel-chat-messages.tsx +78 -78
- package/src/camel/camel-tool-presentation.tsx +19 -15
- package/src/camel/camel-turn.ts +1 -17
- package/src/composer/composer-attachments.tsx +1 -1
- package/src/composer/composer.tsx +2 -2
- package/src/contracts.ts +0 -2
- package/src/message-panel.tsx +1 -24
- package/src/parts/index.tsx +103 -64
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { PROFILE_SAMPLES } from './profiles'
|
|
2
|
+
import {
|
|
3
|
+
hullOfCircles,
|
|
4
|
+
profileFromPolygon,
|
|
5
|
+
regularPolygonProfile,
|
|
6
|
+
superellipseProfile,
|
|
7
|
+
unionOfCirclesProfile
|
|
8
|
+
} from './shape'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Formes et couleurs proposees par le personnalisateur du bot.
|
|
12
|
+
*
|
|
13
|
+
* A la difference des silhouettes d'animation (`profiles.ts`), celles-ci ne sont
|
|
14
|
+
* PAS relevees sur la video : elles sont construites analytiquement d'apres la
|
|
15
|
+
* grille du personnalisateur d'origine. Deux sources distinctes, donc, et c'est
|
|
16
|
+
* volontaire — les etats animes doivent rester fideles a la video, les formes de
|
|
17
|
+
* base sont un choix d'utilisateur.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Les identifiants sont enumeres plutot que deduits du tableau : c'est ce qui
|
|
22
|
+
* permet a la couche i18n de verifier A LA COMPILATION que chaque forme a bien
|
|
23
|
+
* sa traduction dans les trois langues (`t(\`shapes.${id}\`)` ne compile que si
|
|
24
|
+
* la cle existe). Un `as const` sur le tableau aurait le meme effet mais
|
|
25
|
+
* rendrait `radii` en lecture seule, alors que le moteur le passe tel quel.
|
|
26
|
+
*/
|
|
27
|
+
export type ShapeId =
|
|
28
|
+
| 'springbrand'
|
|
29
|
+
| 'cercle'
|
|
30
|
+
| 'galet'
|
|
31
|
+
| 'squircle'
|
|
32
|
+
| 'capsule'
|
|
33
|
+
| 'triangle'
|
|
34
|
+
| 'hexagone'
|
|
35
|
+
| 'nuage'
|
|
36
|
+
| 'goutte'
|
|
37
|
+
|
|
38
|
+
export interface BotShape {
|
|
39
|
+
id: ShapeId
|
|
40
|
+
radii: number[]
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Ramene le rayon maximal a `max` pour que toutes les formes pesent pareil a l'oeil. */
|
|
44
|
+
function normalize(radii: number[], max = 1): number[] {
|
|
45
|
+
const peak = Math.max(...radii)
|
|
46
|
+
if (peak <= 0) return radii
|
|
47
|
+
const k = max / peak
|
|
48
|
+
return radii.map((r) => r * k)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const ANGLES = Array.from({ length: PROFILE_SAMPLES }, (_, i) => (i / PROFILE_SAMPLES) * Math.PI * 2)
|
|
52
|
+
|
|
53
|
+
/** SpringBrand: soft spring tension, biased from top-right to bottom-left. */
|
|
54
|
+
const springbrand = normalize(
|
|
55
|
+
ANGLES.map(
|
|
56
|
+
(a) =>
|
|
57
|
+
1 +
|
|
58
|
+
0.055 * Math.cos(2 * a - 0.62) +
|
|
59
|
+
0.026 * Math.sin(3 * a + 0.8) +
|
|
60
|
+
0.012 * Math.sin(5 * a)
|
|
61
|
+
),
|
|
62
|
+
1.04
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
/** Galet : cercle deforme par deux harmoniques basses, donc irregulier mais lisse. */
|
|
66
|
+
const pebble = normalize(
|
|
67
|
+
ANGLES.map((a) => 1 + 0.075 * Math.cos(2 * a + 0.5) + 0.035 * Math.cos(3 * a + 2.1)),
|
|
68
|
+
1.02
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
/** Nuage : union de bosses, large en bas, deux lobes en haut. */
|
|
72
|
+
const cloud = normalize(
|
|
73
|
+
unionOfCirclesProfile([
|
|
74
|
+
{ x: -0.44, y: 0.2, r: 0.54 },
|
|
75
|
+
{ x: 0.46, y: 0.2, r: 0.5 },
|
|
76
|
+
{ x: 0.02, y: 0.3, r: 0.6 },
|
|
77
|
+
{ x: -0.24, y: -0.3, r: 0.48 },
|
|
78
|
+
{ x: 0.3, y: -0.24, r: 0.44 }
|
|
79
|
+
]),
|
|
80
|
+
1.02
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
/** Goutte : gros disque en bas, pointe effilee en haut. */
|
|
84
|
+
const droplet = normalize(
|
|
85
|
+
profileFromPolygon(hullOfCircles(0, 0.28, 0.66, 0, -0.96, 0.05), 0, 0),
|
|
86
|
+
1.04
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
/** Capsule couchee : enveloppe de deux disques cote a cote. */
|
|
90
|
+
const capsule = profileFromPolygon(hullOfCircles(-0.42, 0, 0.62, 0.42, 0, 0.62), 0, 0)
|
|
91
|
+
|
|
92
|
+
export const SHAPES: BotShape[] = [
|
|
93
|
+
{ id: 'springbrand', radii: springbrand },
|
|
94
|
+
{ id: 'cercle', radii: new Array(PROFILE_SAMPLES).fill(1) },
|
|
95
|
+
{ id: 'galet', radii: pebble },
|
|
96
|
+
// 1.15 et pas 1.02 : sur une superellipse le rayon maximal est la diagonale,
|
|
97
|
+
// donc normaliser dessus donne une forme qui parait plus petite que le cercle.
|
|
98
|
+
{ id: 'squircle', radii: normalize(superellipseProfile(4.2), 1.15) },
|
|
99
|
+
{ id: 'capsule', radii: capsule },
|
|
100
|
+
// -90deg : un sommet vers le haut de l'ecran (y est oriente vers le bas)
|
|
101
|
+
{ id: 'triangle', radii: regularPolygonProfile(3, 1.12, 0.34, -90) },
|
|
102
|
+
// 0deg : sommets a gauche et a droite, donc aretes du haut et du bas plates
|
|
103
|
+
{ id: 'hexagone', radii: regularPolygonProfile(6, 1.04, 0.26, 0) },
|
|
104
|
+
{ id: 'nuage', radii: cloud },
|
|
105
|
+
{ id: 'goutte', radii: droplet }
|
|
106
|
+
]
|
|
107
|
+
|
|
108
|
+
// Map indexee par `string` et non par `ShapeId` : les appelants interrogent avec
|
|
109
|
+
// une valeur relue du localStorage ou d'une prop, donc non validee.
|
|
110
|
+
export const SHAPE_BY_ID = new Map<string, BotShape>(SHAPES.map((s) => [s.id, s]))
|
|
111
|
+
export const DEFAULT_SHAPE = 'cercle'
|
|
112
|
+
|
|
113
|
+
export type ColorId =
|
|
114
|
+
| 'encre'
|
|
115
|
+
| 'creme'
|
|
116
|
+
| 'brun'
|
|
117
|
+
| 'rouge'
|
|
118
|
+
| 'orange'
|
|
119
|
+
| 'ambre'
|
|
120
|
+
| 'vert'
|
|
121
|
+
| 'turquoise'
|
|
122
|
+
| 'bleu'
|
|
123
|
+
| 'violet'
|
|
124
|
+
| 'rose'
|
|
125
|
+
| 'gris'
|
|
126
|
+
|
|
127
|
+
export interface BotColor {
|
|
128
|
+
id: ColorId
|
|
129
|
+
hex: string
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Palette du personnalisateur d'origine. */
|
|
133
|
+
export const COLORS: BotColor[] = [
|
|
134
|
+
{ id: 'encre', hex: '#0a0a0c' },
|
|
135
|
+
{ id: 'brun', hex: '#8b5e3c' },
|
|
136
|
+
{ id: 'rouge', hex: '#e8483f' },
|
|
137
|
+
{ id: 'orange', hex: '#f08a24' },
|
|
138
|
+
{ id: 'ambre', hex: '#f0b429' },
|
|
139
|
+
{ id: 'vert', hex: '#3ecf8e' },
|
|
140
|
+
{ id: 'turquoise', hex: '#2fbfa0' },
|
|
141
|
+
{ id: 'bleu', hex: '#3b93f0' },
|
|
142
|
+
{ id: 'violet', hex: '#8b5cf6' },
|
|
143
|
+
{ id: 'rose', hex: '#e152b0' },
|
|
144
|
+
{ id: 'gris', hex: '#a3a3a3' },
|
|
145
|
+
{ id: 'creme', hex: '#f1efe9' }
|
|
146
|
+
]
|
|
147
|
+
|
|
148
|
+
export const COLOR_BY_ID = new Map<string, BotColor>(COLORS.map((c) => [c.id, c]))
|
|
149
|
+
export const DEFAULT_COLOR = 'encre'
|
|
150
|
+
|
|
151
|
+
/** Melange deux couleurs hex. Sert a la brume de profondeur des particules. */
|
|
152
|
+
export function mixHex(from: string, to: string, t: number): string {
|
|
153
|
+
const parse = (h: string) => {
|
|
154
|
+
const v = parseInt(h.slice(1), 16)
|
|
155
|
+
return [(v >> 16) & 255, (v >> 8) & 255, v & 255]
|
|
156
|
+
}
|
|
157
|
+
const a = parse(from)
|
|
158
|
+
const b = parse(to)
|
|
159
|
+
const c = a.map((x, i) => Math.round(x + (b[i]! - x) * t))
|
|
160
|
+
return `#${c.map((x) => x.toString(16).padStart(2, '0')).join('')}`
|
|
161
|
+
}
|