@lovelace_lol/polymer 0.0.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 (85) hide show
  1. package/README.md +226 -0
  2. package/dist/index.d.ts +2603 -0
  3. package/dist/index.js +1031 -0
  4. package/dist/test.cjs +1519 -0
  5. package/dist/worker/agency-worker.js +972 -0
  6. package/dist/worker/manifest.edn +1 -0
  7. package/package.json +57 -0
  8. package/shadow-cljs.edn +173 -0
  9. package/src/polymer/animation/agency.cljs +84 -0
  10. package/src/polymer/animation/domain.cljs +110 -0
  11. package/src/polymer/animation/planner.cljs +88 -0
  12. package/src/polymer/animation/runtime.cljs +137 -0
  13. package/src/polymer/animation/scheduler.cljs +178 -0
  14. package/src/polymer/animation/service.cljs +981 -0
  15. package/src/polymer/animation/state.cljs +112 -0
  16. package/src/polymer/blink/agency.cljs +131 -0
  17. package/src/polymer/blink/planner.cljs +115 -0
  18. package/src/polymer/blink/scheduler.cljs +90 -0
  19. package/src/polymer/blink/snippet.cljs +50 -0
  20. package/src/polymer/blink/state.cljs +102 -0
  21. package/src/polymer/camera_context/agency.cljs +132 -0
  22. package/src/polymer/camera_context/domain.cljs +186 -0
  23. package/src/polymer/camera_context/planner.cljs +50 -0
  24. package/src/polymer/camera_context/scheduler.cljs +113 -0
  25. package/src/polymer/camera_context/state.cljs +121 -0
  26. package/src/polymer/character.cljs +471 -0
  27. package/src/polymer/conversation/agency.cljs +83 -0
  28. package/src/polymer/conversation/domain.cljs +35 -0
  29. package/src/polymer/conversation/effector.cljs +130 -0
  30. package/src/polymer/conversation/planner.cljs +178 -0
  31. package/src/polymer/conversation/scheduler.cljs +202 -0
  32. package/src/polymer/conversation/service.cljs +329 -0
  33. package/src/polymer/conversation/state.cljs +186 -0
  34. package/src/polymer/core.cljs +172 -0
  35. package/src/polymer/eye_head/agency.cljs +75 -0
  36. package/src/polymer/eye_head/domain.cljs +133 -0
  37. package/src/polymer/eye_head/goap.cljs +106 -0
  38. package/src/polymer/eye_head/scheduler.cljs +176 -0
  39. package/src/polymer/eye_head/service.cljs +259 -0
  40. package/src/polymer/eye_head/snippet.cljs +92 -0
  41. package/src/polymer/eye_head/state.cljs +167 -0
  42. package/src/polymer/gaze/agency.cljs +85 -0
  43. package/src/polymer/gaze/domain.cljs +211 -0
  44. package/src/polymer/gaze/goap.cljs +208 -0
  45. package/src/polymer/gaze/scheduler.cljs +184 -0
  46. package/src/polymer/gaze/state.cljs +202 -0
  47. package/src/polymer/gesture/agency.cljs +185 -0
  48. package/src/polymer/gesture/goap.cljs +461 -0
  49. package/src/polymer/gesture/scheduler.cljs +122 -0
  50. package/src/polymer/gesture/snippet.cljs +198 -0
  51. package/src/polymer/gesture/state.cljs +273 -0
  52. package/src/polymer/lipsync/agency.cljs +593 -0
  53. package/src/polymer/lipsync/articulation/jaw.cljs +258 -0
  54. package/src/polymer/lipsync/articulation/snippet.cljs +605 -0
  55. package/src/polymer/lipsync/articulation/tongue.cljs +418 -0
  56. package/src/polymer/lipsync/articulation/visemes.cljs +429 -0
  57. package/src/polymer/lipsync/goap.cljs +132 -0
  58. package/src/polymer/lipsync/pronunciation/effector.cljs +51 -0
  59. package/src/polymer/lipsync/scheduler.cljs +302 -0
  60. package/src/polymer/lipsync/state.cljs +202 -0
  61. package/src/polymer/nlp/phonemes.cljs +164 -0
  62. package/src/polymer/prosodic/agency.cljs +196 -0
  63. package/src/polymer/prosodic/goap.cljs +122 -0
  64. package/src/polymer/prosodic/scheduler.cljs +99 -0
  65. package/src/polymer/prosodic/snippet.cljs +106 -0
  66. package/src/polymer/prosodic/state.cljs +139 -0
  67. package/src/polymer/runtime/embody.cljs +117 -0
  68. package/src/polymer/runtime/embody_wasm.cljs +177 -0
  69. package/src/polymer/runtime/rust_embody_host.cljs +645 -0
  70. package/src/polymer/society.cljs +239 -0
  71. package/src/polymer/stream.cljs +130 -0
  72. package/src/polymer/transcription/agency.cljs +69 -0
  73. package/src/polymer/transcription/domain.cljs +68 -0
  74. package/src/polymer/transcription/effector.cljs +611 -0
  75. package/src/polymer/transcription/planner.cljs +203 -0
  76. package/src/polymer/transcription/scheduler.cljs +225 -0
  77. package/src/polymer/transcription/service.cljs +209 -0
  78. package/src/polymer/transcription/state.cljs +239 -0
  79. package/src/polymer/tts/agency.cljs +503 -0
  80. package/src/polymer/tts/azure.cljs +290 -0
  81. package/src/polymer/tts/planner.cljs +178 -0
  82. package/src/polymer/tts/runtime.cljs +624 -0
  83. package/src/polymer/tts/scheduler.cljs +162 -0
  84. package/src/polymer/tts/state.cljs +191 -0
  85. package/src/polymer/worker.cljs +70 -0
package/README.md ADDED
@@ -0,0 +1,226 @@
1
+ # Polymer
2
+
3
+ Clean ClojureScript character agency package for Character Loom.
4
+
5
+ Production releases publish to npm as `@lovelace_lol/polymer` on every push to `main`. Hosts should depend on the npm package (`latest` or a semver range). PR staging may still use git SHA pins or `Depends-on` / pkg.pr.new preview URLs.
6
+
7
+ Polymer is intentionally separate from Latticework and Polyester. It is built as
8
+ a Society of Mind agency system: small CLJS agencies collaborate through streams,
9
+ plan locally, schedule their own work, and keep side effects inside the agencies
10
+ responsible for performing them.
11
+
12
+ See [docs/agency-architecture.md](docs/agency-architecture.md) for the agency
13
+ collaboration, scheduler, side-effect, stream, and runtime-target rules.
14
+
15
+ ## Agency API
16
+
17
+ The package exposes an agency system:
18
+
19
+ ```js
20
+ const agencies = createCharacterAgencies();
21
+ agencies.dispatch({ agency: "blink", command: { type: "enable" } });
22
+
23
+ agencies.events.subscribe((message) => {});
24
+ agencies.snapshot();
25
+ ```
26
+
27
+ Agencies communicate through incoming and outgoing streams of plain data.
28
+ Messages may be facts, goals, requests, constraints, priorities, status, or
29
+ diagnostics. Requests that imply side effects are handled by the receiving
30
+ agency's local planner, scheduler, and effector path.
31
+
32
+ Host applications may dispatch external commands, observe outgoing streams, and
33
+ read snapshots for diagnostics or configuration. Host applications should not
34
+ serve as the normal message bus between Polymer agencies.
35
+
36
+ ## Current Agencies
37
+
38
+ Polymer currently includes early Blink, Animation, Gaze, Eye/Head Tracking,
39
+ TTS, LipSync, Prosodic Expression, and Gesture agencies, plus first slices for
40
+ Conversation, Camera Context, and Transcription. These are implementation
41
+ milestones, not the limits of the architecture. Each agency should follow the
42
+ same local GOAP/planner, scheduler, stream, transform, and effector pattern as
43
+ the package grows.
44
+
45
+ The text-only LipSync pronunciation fallback and its accuracy limits are
46
+ documented in [`docs/lipsync-pronunciation-fallback.md`](docs/lipsync-pronunciation-fallback.md).
47
+
48
+ Runtime-specific work belongs at the edge. The current animation path can target
49
+ the existing web runtime, but Polymer core should remain able to support other
50
+ runtime targets such as Babylon, Unity, Godot, robotics, or future animation
51
+ libraries through separate runtime-specific boundaries.
52
+
53
+ Hair appearance and physics are model/runtime capabilities rather than
54
+ character-behavior agencies. Polymer therefore does not expose a Hair agency,
55
+ Hair planner, or Hair scheduler. It continues to re-export Embody's hair color,
56
+ material-normalization, and Wasm physics APIs so hosts can configure the
57
+ character runtime without importing Embody directly.
58
+
59
+ ## Gesture Agency
60
+
61
+ Gesture is the arm/hand gesticulation agency. It accepts LoomLarge-authored
62
+ gesture snapshots as plain data and turns them into typed bone-channel animation
63
+ snippets. It does not call scene bones, host UI state, storage, or the animation
64
+ runtime.
65
+ Gesture snapshots are compatible with the Gestures tab profile shape: id/name,
66
+ optional description or text representation, emoji trigger, left/right/both/custom
67
+ scope, captured source metadata, duration, priority, affected bones, static bone
68
+ targets, and optional time-based keyframes.
69
+
70
+ Gesture commands can still name an exact gesture or emoji, but the planner also
71
+ accepts gesture goals. A goal asks Gesture to choose from the authored library by
72
+ intent, tags, scope, required or avoided effectors, cooldown, active conflicts,
73
+ and capacity before it emits Animation requests.
74
+
75
+ ### Gesture GOAP Planning
76
+
77
+ Gesture GOAP plans for one local world-state transition: a suitable authored
78
+ arm/hand gesture is selected and safely scheduled through Animation, or the
79
+ agency records why that goal cannot be satisfied. It is not a second public
80
+ playback API.
81
+
82
+ The planner uses the incoming command, the gesture library, active snippets, and
83
+ Gesture config to decide:
84
+
85
+ - which gesture best satisfies an explicit gesture id, emoji mapping, intent,
86
+ tags, text hints, scope, and bone constraints
87
+ - whether the selected gesture is valid motion and is out of cooldown
88
+ - whether active snippets conflict on affected bones
89
+ - whether capacity is available under `maxActive`
90
+ - whether to ignore, remove only conflicting snippets, remove the oldest snippets
91
+ needed for capacity, build a snippet, schedule Animation, and record the result
92
+
93
+ Host integrations should prefer the character agency network so Gesture's
94
+ animation requests are routed to Animation inside Polymer:
95
+
96
+ ```js
97
+ const agencies = createCharacterAgencies({
98
+ animation: { engine },
99
+ gesture: {
100
+ gestures: profile.characterGestures,
101
+ emojiMappings: profile.gestureEmojiMappings,
102
+ },
103
+ });
104
+
105
+ agencies.dispatch({ agency: "gesture", command: { type: "playEmoji", emoji: "👋" } });
106
+ agencies.dispatch({
107
+ agency: "gesture",
108
+ command: {
109
+ type: "gesture.goal",
110
+ goal: {
111
+ intent: "greeting",
112
+ tags: ["wave"],
113
+ scope: "right",
114
+ avoidBones: ["HAND_L"],
115
+ },
116
+ },
117
+ });
118
+ ```
119
+
120
+ The host supplies the gesture library and may observe streams for diagnostics,
121
+ but Gesture's own scheduler is responsible for replacement, cancellation, and
122
+ completion cleanup before Animation owns the runtime side effect.
123
+
124
+ ## Character host (Embody scene + model loading)
125
+
126
+ Polymer re-exports Embody's character host so LoomLarge and other hosts can set
127
+ up a character without depending on Embody directly.
128
+
129
+ Default path — pass a container element and a character URL:
130
+
131
+ ```js
132
+ import {
133
+ createCharacterHost,
134
+ createCharacterAgencies,
135
+ } from '@lovelace_lol/polymer';
136
+
137
+ const host = await createCharacterHost({
138
+ container: document.getElementById('viewport'),
139
+ character: {
140
+ modelUrl: '/characters/jonathan.glb',
141
+ presetType: 'cc4',
142
+ },
143
+ });
144
+
145
+ const agencies = createCharacterAgencies({
146
+ animation: { engine: host.engine },
147
+ });
148
+ ```
149
+
150
+ Named scene types (`studio`, `showcase`, `inspection`, `void`) bundle
151
+ background, lighting preset, and shadow-plane defaults; enumerate them via
152
+ `CHARACTER_SCENE_TYPES` / `CHARACTER_SCENE_TYPE_IDS`:
153
+
154
+ ```js
155
+ const host = await createCharacterHost({
156
+ container,
157
+ character: { modelUrl: '/characters/jonathan.glb' },
158
+ scene: { type: 'showcase' },
159
+ });
160
+ ```
161
+
162
+ Advanced path — inject an existing Three.js scene:
163
+
164
+ ```js
165
+ const host = await createCharacterHost({
166
+ container: mountEl,
167
+ character: { modelUrl: '/characters/jonathan.glb', presetType: 'cc4' },
168
+ external: { scene, renderer, camera },
169
+ });
170
+ ```
171
+
172
+ Polymer stays agency-oriented: it does not own the render loop. Use
173
+ `createCharacterHost` / `loadCharacterModel` for scene+model setup, then inject
174
+ `host.engine` into `createCharacterAgencies`.
175
+
176
+ For an already-managed Three.js scene, Polymer also exposes a CLJS-owned host
177
+ that talks directly to Embody's Rust/Wasm `RuntimeCore`:
178
+
179
+ ```js
180
+ import {
181
+ createRustEmbodyHostUnbound,
182
+ initEmbodyCore,
183
+ supportsRustEmbodyPreset,
184
+ } from '@lovelace_lol/polymer';
185
+
186
+ await initEmbodyCore();
187
+ if (supportsRustEmbodyPreset('cc4')) {
188
+ const engine = createRustEmbodyHostUnbound({
189
+ presetType: 'cc4',
190
+ profile: characterProfileOverrides,
191
+ });
192
+ engine.onReady({ model, meshes });
193
+ engine.start();
194
+ }
195
+ ```
196
+
197
+ The CLJS host owns the JavaScript API and render-loop bridge. Rust owns preset
198
+ lookup, profile merge and intake, compiled bindings, transitions, and packed
199
+ frame evaluation. Unsupported presets must stay on the compatibility host until
200
+ they are explicitly embedded; they are never treated as CC4 aliases.
201
+
202
+ ## Git Install Contract
203
+
204
+ Polymer Git-SHA consumers should import checked-in JavaScript artifacts from
205
+ `dist`. They should not need Java, Shadow CLJS, or a local Polymer build during
206
+ application install.
207
+
208
+ The package intentionally has no `prepare`, `install`, or `postinstall` build
209
+ lifecycle. Polymer CI runs the CLJS build, verifies that `dist` exposes the
210
+ browser ESM API that Git-SHA consumers import, and `prepublishOnly` repeats the
211
+ build/test/API check before an npm publish.
212
+
213
+ ## Worker Protocol Artifact
214
+
215
+ The package also ships `@lovelace_lol/polymer/worker/agency-worker.js` as an
216
+ opt-in transport around the complete character agency API. It accepts
217
+ `createCharacterAgencies`, `dispatch`, `snapshot`, and `dispose` messages and
218
+ returns character events, snapshots, and lifecycle messages as plain data. The
219
+ Worker does not add another planner or route between agencies; Polymer's
220
+ character network keeps that responsibility.
221
+
222
+ CI executes the compiled artifact in a real Node worker thread. LoomLarge does
223
+ not use this artifact yet, and this PR does not decide which agencies should be
224
+ placed in workers. Selective placement, profiling, transferables, and worker
225
+ pool decisions remain tracked in
226
+ [issue #62](https://github.com/meekmachine/Polymer/issues/62).