@lovelace_lol/polymer 0.0.7 → 0.0.8

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 (95) hide show
  1. package/README.md +434 -12
  2. package/dist/index.d.ts +1945 -244
  3. package/dist/index.js +1686 -1017
  4. package/dist/vision/face-worker.js +296 -0
  5. package/dist/vision/face_landmarker.task +0 -0
  6. package/dist/vision/manifest.edn +1 -0
  7. package/dist/vision/vision_bundle.js +2 -0
  8. package/dist/vision/wasm/vision_wasm_internal.js +8841 -0
  9. package/dist/vision/wasm/vision_wasm_internal.wasm +0 -0
  10. package/dist/vision/wasm/vision_wasm_module_internal.js +8837 -0
  11. package/dist/vision/wasm/vision_wasm_module_internal.wasm +0 -0
  12. package/dist/vision/wasm/vision_wasm_nosimd_internal.js +8832 -0
  13. package/dist/vision/wasm/vision_wasm_nosimd_internal.wasm +0 -0
  14. package/dist/worker/agency-worker.js +1276 -962
  15. package/dist/worker/manifest.edn +1 -1
  16. package/package.json +33 -20
  17. package/dist/test.cjs +0 -1519
  18. package/shadow-cljs.edn +0 -173
  19. package/src/polymer/animation/agency.cljs +0 -84
  20. package/src/polymer/animation/domain.cljs +0 -110
  21. package/src/polymer/animation/planner.cljs +0 -88
  22. package/src/polymer/animation/runtime.cljs +0 -137
  23. package/src/polymer/animation/scheduler.cljs +0 -178
  24. package/src/polymer/animation/service.cljs +0 -981
  25. package/src/polymer/animation/state.cljs +0 -112
  26. package/src/polymer/blink/agency.cljs +0 -131
  27. package/src/polymer/blink/planner.cljs +0 -115
  28. package/src/polymer/blink/scheduler.cljs +0 -90
  29. package/src/polymer/blink/snippet.cljs +0 -50
  30. package/src/polymer/blink/state.cljs +0 -102
  31. package/src/polymer/camera_context/agency.cljs +0 -132
  32. package/src/polymer/camera_context/domain.cljs +0 -186
  33. package/src/polymer/camera_context/planner.cljs +0 -50
  34. package/src/polymer/camera_context/scheduler.cljs +0 -113
  35. package/src/polymer/camera_context/state.cljs +0 -121
  36. package/src/polymer/character.cljs +0 -403
  37. package/src/polymer/conversation/agency.cljs +0 -83
  38. package/src/polymer/conversation/domain.cljs +0 -35
  39. package/src/polymer/conversation/effector.cljs +0 -130
  40. package/src/polymer/conversation/planner.cljs +0 -178
  41. package/src/polymer/conversation/scheduler.cljs +0 -202
  42. package/src/polymer/conversation/service.cljs +0 -329
  43. package/src/polymer/conversation/state.cljs +0 -186
  44. package/src/polymer/core.cljs +0 -172
  45. package/src/polymer/eye_head/agency.cljs +0 -75
  46. package/src/polymer/eye_head/domain.cljs +0 -133
  47. package/src/polymer/eye_head/goap.cljs +0 -106
  48. package/src/polymer/eye_head/scheduler.cljs +0 -176
  49. package/src/polymer/eye_head/service.cljs +0 -259
  50. package/src/polymer/eye_head/snippet.cljs +0 -92
  51. package/src/polymer/eye_head/state.cljs +0 -167
  52. package/src/polymer/gaze/agency.cljs +0 -85
  53. package/src/polymer/gaze/domain.cljs +0 -211
  54. package/src/polymer/gaze/goap.cljs +0 -208
  55. package/src/polymer/gaze/scheduler.cljs +0 -184
  56. package/src/polymer/gaze/state.cljs +0 -202
  57. package/src/polymer/gesture/agency.cljs +0 -185
  58. package/src/polymer/gesture/goap.cljs +0 -461
  59. package/src/polymer/gesture/scheduler.cljs +0 -122
  60. package/src/polymer/gesture/snippet.cljs +0 -198
  61. package/src/polymer/gesture/state.cljs +0 -273
  62. package/src/polymer/lipsync/agency.cljs +0 -593
  63. package/src/polymer/lipsync/articulation/jaw.cljs +0 -258
  64. package/src/polymer/lipsync/articulation/snippet.cljs +0 -605
  65. package/src/polymer/lipsync/articulation/tongue.cljs +0 -418
  66. package/src/polymer/lipsync/articulation/visemes.cljs +0 -429
  67. package/src/polymer/lipsync/goap.cljs +0 -132
  68. package/src/polymer/lipsync/pronunciation/effector.cljs +0 -51
  69. package/src/polymer/lipsync/scheduler.cljs +0 -302
  70. package/src/polymer/lipsync/state.cljs +0 -202
  71. package/src/polymer/nlp/phonemes.cljs +0 -164
  72. package/src/polymer/prosodic/agency.cljs +0 -196
  73. package/src/polymer/prosodic/goap.cljs +0 -122
  74. package/src/polymer/prosodic/scheduler.cljs +0 -99
  75. package/src/polymer/prosodic/snippet.cljs +0 -106
  76. package/src/polymer/prosodic/state.cljs +0 -139
  77. package/src/polymer/runtime/embody.cljs +0 -117
  78. package/src/polymer/runtime/embody_wasm.cljs +0 -177
  79. package/src/polymer/runtime/rust_embody_host.cljs +0 -647
  80. package/src/polymer/society.cljs +0 -253
  81. package/src/polymer/stream.cljs +0 -130
  82. package/src/polymer/transcription/agency.cljs +0 -69
  83. package/src/polymer/transcription/domain.cljs +0 -68
  84. package/src/polymer/transcription/effector.cljs +0 -611
  85. package/src/polymer/transcription/planner.cljs +0 -203
  86. package/src/polymer/transcription/scheduler.cljs +0 -225
  87. package/src/polymer/transcription/service.cljs +0 -209
  88. package/src/polymer/transcription/state.cljs +0 -239
  89. package/src/polymer/tts/agency.cljs +0 -503
  90. package/src/polymer/tts/azure.cljs +0 -290
  91. package/src/polymer/tts/planner.cljs +0 -178
  92. package/src/polymer/tts/runtime.cljs +0 -624
  93. package/src/polymer/tts/scheduler.cljs +0 -162
  94. package/src/polymer/tts/state.cljs +0 -191
  95. package/src/polymer/worker.cljs +0 -81
@@ -1,203 +0,0 @@
1
- (ns polymer.transcription.planner
2
- (:require [polymer.transcription.domain :as domain]
3
- [polymer.transcription.state :as state]))
4
-
5
- ;; The planner turns recognition commands and provider callbacks into explicit
6
- ;; actions. Provider APIs are not called here; the scheduler passes accepted
7
- ;; provider work to the agency's private effector.
8
-
9
- (def supported-command-types
10
- #{"configure"
11
- "start"
12
- "stop"
13
- "cancel"
14
- "reset"
15
- "providerStarted"
16
- "providerEnded"
17
- "providerPartial"
18
- "partialTranscript"
19
- "providerFinal"
20
- "finalTranscript"
21
- "providerError"
22
- "providerAudioInterruption"
23
- "tts.status"
24
- "ttsSpeechStarted"
25
- "ttsSpeechStopped"
26
- "ttsSpeechEnded"
27
- "agentSpeechPrepared"
28
- "agentSpeechObserved"
29
- "agentSpeechWord"
30
- "agentSpeechEnded"})
31
-
32
- (defn confidence
33
- [command]
34
- (state/clamp 0 1 (state/number-or (:confidence command) 1)))
35
-
36
- (defn allowed-confidence?
37
- [command current-state]
38
- (>= (confidence command) (get-in current-state [:config :minConfidence])))
39
-
40
- (defn retry-available?
41
- [current-state]
42
- (< (:retryCount current-state) (get-in current-state [:config :maxRetries])))
43
-
44
- (defn failure-step
45
- [command current-state]
46
- (cond
47
- (not (contains? supported-command-types (:type command)))
48
- {:op "fail" :reason "unsupported-command" :commandType (:type command)}
49
-
50
- (and (#{"providerPartial" "partialTranscript" "providerFinal" "finalTranscript"} (:type command))
51
- (not (domain/transcript-text command)))
52
- {:op "ignore" :reason "empty-transcript" :commandType (:type command)}
53
-
54
- (and (#{"providerPartial" "partialTranscript" "providerFinal" "finalTranscript"} (:type command))
55
- (not (allowed-confidence? command current-state)))
56
- {:op "ignore" :reason "low-confidence" :commandType (:type command)}
57
-
58
- (and (get-in current-state [:config :agentFilteringEnabled])
59
- (:agentSpeaking current-state)
60
- (#{"providerPartial" "partialTranscript" "providerFinal" "finalTranscript"} (:type command))
61
- (or (domain/agent-source? command)
62
- (domain/agent-echo? command current-state)))
63
- {:op "ignore" :reason "agent-speech" :commandType (:type command)}))
64
-
65
- (def provider-callback-types
66
- #{"providerStarted" "providerEnded" "providerPartial" "providerFinal" "providerError"})
67
-
68
- (defn stale-provider-callback?
69
- [command current-state]
70
- (and (contains? provider-callback-types (:type command))
71
- (:sessionId command)
72
- (or (not (:active current-state))
73
- (not= (:sessionId command) (:sessionId current-state)))))
74
-
75
- (defn tts-status-fact
76
- [command now-ms]
77
- (let [status (or (:status command)
78
- (:stateStatus command)
79
- (get-in command [:state :status])
80
- (case (:type command)
81
- "ttsSpeechStarted" "speaking"
82
- ("ttsSpeechStopped" "ttsSpeechEnded") "idle"
83
- "idle"))]
84
- {:type "transcription.ttsStatus"
85
- :agency "transcription"
86
- :sourceAgency "tts"
87
- :status status
88
- :speaking (or (:speaking command)
89
- (= "speaking" status)
90
- (= "ttsSpeechStarted" (:type command)))
91
- :phrase (or (:phrase command) (:text command))
92
- :words (:words command)
93
- :ttsEventType (:type command)
94
- :at now-ms}))
95
-
96
- (defn command-steps
97
- [command current-state now-ms]
98
- (if (stale-provider-callback? command current-state)
99
- [{:op "ignore"
100
- :reason "stale-provider-callback"
101
- :commandType (:type command)}]
102
- (if-let [failure (failure-step command current-state)]
103
- [failure]
104
- (case (:type command)
105
- "configure" [{:op "apply-config"}
106
- {:op "configure-provider"}
107
- {:op "publish-status" :status (:status current-state)}]
108
- "start" (if (:active current-state)
109
- [{:op "ignore" :reason "already-active" :commandType "start"}]
110
- [{:op "start-session"}
111
- {:op "request-provider-start"}])
112
- ("stop" "cancel") [{:op "request-provider-stop"
113
- :method (if (= "cancel" (:type command)) "abort" "stop")
114
- :reason (or (:reason command) (:type command))}
115
- {:op "stop-session"
116
- :reason (or (:reason command) (:type command))}]
117
- "reset" [{:op "request-provider-stop"
118
- :method "abort"
119
- :reason "reset"}
120
- {:op "reset-state"}]
121
- "providerStarted" [{:op "record-provider-started"}]
122
- "providerEnded" (if (= "retrying" (:status current-state))
123
- [{:op "ignore"
124
- :reason "provider-ended-during-retry"
125
- :commandType "providerEnded"}]
126
- [{:op "stop-session" :reason "provider-ended"}])
127
- ("providerPartial" "partialTranscript")
128
- (let [interrupt? (and (:agentSpeaking current-state)
129
- (get-in current-state [:config :interruptDetectionEnabled])
130
- (not (domain/agent-source? command)))]
131
- (cond-> []
132
- interrupt?
133
- (conj {:op "publish-interruption"
134
- :text (domain/transcript-text command)
135
- :confidence (confidence command)
136
- :source (or (:source command) "provider")})
137
-
138
- true
139
- (conj {:op "publish-partial"
140
- :text (domain/transcript-text command)
141
- :confidence (confidence command)
142
- :source (or (:source command) "provider")})))
143
- ("providerFinal" "finalTranscript")
144
- (let [interrupt? (and (:agentSpeaking current-state)
145
- (get-in current-state [:config :interruptDetectionEnabled])
146
- (not (domain/agent-source? command)))]
147
- (cond-> []
148
- interrupt?
149
- (conj {:op "publish-interruption"
150
- :text (domain/transcript-text command)
151
- :confidence (confidence command)
152
- :source (or (:source command) "provider")})
153
-
154
- true
155
- (conj {:op "publish-final"
156
- :text (domain/transcript-text command)
157
- :confidence (confidence command)
158
- :source (or (:source command) "provider")})))
159
- "providerError"
160
- (let [message (or (:message command) (:error command) "provider-error")
161
- retry? (and (:active current-state)
162
- (:continuous (:config current-state))
163
- (retry-available? current-state))]
164
- (cond-> [{:op "record-error"
165
- :message message
166
- :retry retry?}]
167
- retry? (conj {:op "request-provider-retry"
168
- :message message
169
- :retryAfterMs (get-in current-state [:config :retryDelayMs])})
170
- (not retry?) (conj {:op "stop-session"
171
- :reason "provider-error"})))
172
- "providerAudioInterruption"
173
- [{:op "publish-audio-interruption"
174
- :timestamp (:timestamp command)
175
- :microphoneLevel (:microphoneLevel command)
176
- :referenceLevel (:referenceLevel command)
177
- :requiredLevel (:requiredLevel command)}]
178
- ("tts.status" "ttsSpeechStarted" "ttsSpeechStopped" "ttsSpeechEnded")
179
- [{:op "record-tts-status"
180
- :fact (tts-status-fact command now-ms)}]
181
- "agentSpeechPrepared" [{:op "prepare-agent-speech"
182
- :text (:text command)
183
- :append false}]
184
- "agentSpeechObserved" [{:op "prepare-agent-speech"
185
- :text (:text command)
186
- :append true}]
187
- "agentSpeechWord" [{:op "record-agent-word"
188
- :word (:word command)}]
189
- "agentSpeechEnded" [{:op "record-tts-status"
190
- :fact (tts-status-fact
191
- {:type "ttsSpeechEnded"
192
- :status "idle"
193
- :speaking false}
194
- now-ms)}]))))
195
-
196
- (defn plan-command
197
- [command current-state now-ms]
198
- (let [steps (command-steps command current-state now-ms)]
199
- {:agency "transcription"
200
- :commandType (:type command)
201
- :createdAt now-ms
202
- :ok (not (#{"fail"} (:op (first steps))))
203
- :steps steps}))
@@ -1,225 +0,0 @@
1
- (ns polymer.transcription.scheduler
2
- (:require [polymer.transcription.state :as state]))
3
-
4
- ;; The scheduler owns ordering for provider lifecycle and transcript facts. It
5
- ;; executes accepted steps immediately, invokes the private provider effector,
6
- ;; and preserves lifecycle request events as observable diagnostics.
7
-
8
- (defn now-ms
9
- []
10
- (.now js/Date))
11
-
12
- (defn queue-entry
13
- [step index plan]
14
- (assoc step
15
- :agency "transcription"
16
- :queueIndex index
17
- :commandType (:commandType plan)
18
- :queuedAt (now-ms)))
19
-
20
- (defn provider-request
21
- [state-atom action extra]
22
- (merge {:type "transcription.requestProvider"
23
- :agency "transcription"
24
- :targetAgency "transcription-provider"
25
- :action action
26
- :provider (get-in @state-atom [:config :provider])
27
- :sessionId (:sessionId @state-atom)}
28
- extra))
29
-
30
- (defn transcript-fact
31
- [state-atom kind step now]
32
- {:type (str "transcription." kind)
33
- :agency "transcription"
34
- :targetAgency "conversation"
35
- :text (:text step)
36
- :confidence (:confidence step)
37
- :isFinal (= kind "final")
38
- :sequence (state/next-sequence @state-atom)
39
- :source (:source step)
40
- :sessionId (:sessionId @state-atom)
41
- :at now})
42
-
43
- (defn emit-status!
44
- [emit-event state-atom status reason]
45
- (emit-event (cond-> {:type "transcription.status"
46
- :agency "transcription"
47
- :status status
48
- :sessionId (:sessionId @state-atom)
49
- :at (now-ms)}
50
- reason (assoc :reason reason))))
51
-
52
- (defn create-scheduler
53
- [{:keys [state-atom emit-event effector]}]
54
- (let [queue (atom [])
55
- disposed? (atom false)]
56
- (letfn [(enqueue! [step plan]
57
- (let [entry (queue-entry step (count @queue) plan)]
58
- (swap! queue conj entry)
59
- entry))
60
-
61
- (execute-step! [step command plan]
62
- (let [now (now-ms)]
63
- (enqueue! step plan)
64
- (case (:op step)
65
- "apply-config"
66
- (do
67
- (swap! state-atom state/configure (:config command))
68
- (emit-status! emit-event state-atom (:status @state-atom) "configured"))
69
-
70
- "configure-provider"
71
- ((:configure effector) (:config @state-atom))
72
-
73
- "start-session"
74
- (do
75
- (swap! state-atom state/start-session now)
76
- (emit-status! emit-event state-atom "starting" nil))
77
-
78
- "request-provider-start"
79
- (do
80
- (emit-event (provider-request state-atom "start"
81
- {:config (:config @state-atom)
82
- :requestedAt now}))
83
- ((:start effector) (:sessionId @state-atom) (:config @state-atom)))
84
-
85
- "record-provider-started"
86
- (do
87
- (swap! state-atom state/provider-started now)
88
- (emit-status! emit-event state-atom "listening" "provider-started"))
89
-
90
- "stop-session"
91
- (do
92
- (swap! state-atom state/stop-session now (:reason step))
93
- (emit-status! emit-event state-atom "idle" (:reason step)))
94
-
95
- "request-provider-stop"
96
- (do
97
- (emit-event (provider-request state-atom "stop"
98
- {:reason (:reason step)
99
- :requestedAt now}))
100
- (if (= "abort" (:method step))
101
- ((:abort effector))
102
- ((:stop effector))))
103
-
104
- "reset-state"
105
- (do
106
- (swap! state-atom state/reset-state)
107
- (emit-status! emit-event state-atom "idle" "reset"))
108
-
109
- "publish-partial"
110
- (let [fact (transcript-fact state-atom "partial" step now)]
111
- (swap! state-atom state/record-partial fact)
112
- (emit-event fact))
113
-
114
- "publish-final"
115
- (let [fact (transcript-fact state-atom "final" step now)]
116
- (swap! state-atom state/record-final fact)
117
- (emit-event fact))
118
-
119
- "publish-interruption"
120
- (let [fact {:type "transcription.interruption"
121
- :agency "transcription"
122
- :targetAgency "conversation"
123
- :text (:text step)
124
- :confidence (:confidence step)
125
- :source (:source step)
126
- :sessionId (:sessionId @state-atom)
127
- :at now}]
128
- (swap! state-atom state/record-interruption fact)
129
- (emit-event fact))
130
-
131
- "publish-audio-interruption"
132
- (let [fact {:type "transcription.audioInterruption"
133
- :agency "transcription"
134
- :targetAgency "conversation"
135
- :timestamp (:timestamp step)
136
- :microphoneLevel (:microphoneLevel step)
137
- :referenceLevel (:referenceLevel step)
138
- :requiredLevel (:requiredLevel step)
139
- :at now}]
140
- (swap! state-atom state/record-interruption fact)
141
- (emit-event fact))
142
-
143
- "record-error"
144
- (do
145
- (swap! state-atom state/record-error (:message step) now (:retry step))
146
- (emit-event {:type "transcription.error"
147
- :agency "transcription"
148
- :message (:message step)
149
- :retrying (:retry step)
150
- :sessionId (:sessionId @state-atom)
151
- :at now}))
152
-
153
- "request-provider-retry"
154
- (do
155
- (emit-event (provider-request state-atom "retry"
156
- {:message (:message step)
157
- :retryAfterMs (:retryAfterMs step)
158
- :retryCount (:retryCount @state-atom)
159
- :requestedAt now}))
160
- ((:retry effector)
161
- (:sessionId @state-atom)
162
- (:retryAfterMs step)))
163
-
164
- "publish-status"
165
- (emit-status! emit-event state-atom (:status step) (:reason step))
166
-
167
- "ignore"
168
- (let [ignored {:type "transcription.ignored"
169
- :agency "transcription"
170
- :reason (:reason step)
171
- :commandType (:commandType step)
172
- :at now}]
173
- (swap! state-atom state/record-ignored ignored)
174
- (emit-event ignored))
175
-
176
- "record-tts-status"
177
- (let [fact (:fact step)]
178
- (swap! state-atom state/record-tts-status fact)
179
- ((:sync-agent-speaking effector)
180
- (:agentSpeaking @state-atom))
181
- (emit-event fact))
182
-
183
- "prepare-agent-speech"
184
- (do
185
- (swap! state-atom state/prepare-agent-speech
186
- (:text step)
187
- (:append step))
188
- ((:sync-agent-speaking effector)
189
- (:agentSpeaking @state-atom)))
190
-
191
- "record-agent-word"
192
- (swap! state-atom state/record-agent-word (:word step))
193
-
194
- "fail"
195
- (emit-event {:type "error"
196
- :agency "transcription"
197
- :message (:reason step)
198
- :commandType (:commandType step)
199
- :at now})
200
-
201
- nil)))]
202
- {:schedule
203
- (fn [command plan]
204
- (when-not @disposed?
205
- (last (mapv #(execute-step! % command plan) (:steps plan)))))
206
-
207
- :queue
208
- (fn []
209
- @queue)
210
-
211
- :set-reference-track
212
- (fn [track]
213
- (when-not @disposed?
214
- (let [plan {:agency "transcription"
215
- :commandType "setAgentAudioReferenceTrack"
216
- :createdAt (now-ms)}
217
- step {:op "set-reference-track"}]
218
- (enqueue! step plan)
219
- ((:set-reference-track effector) track))))
220
-
221
- :dispose
222
- (fn []
223
- (reset! disposed? true)
224
- (reset! queue [])
225
- ((:dispose effector)))})))
@@ -1,209 +0,0 @@
1
- (ns polymer.transcription.service
2
- (:require [clojure.string :as str]
3
- [polymer.transcription.agency :as transcription-agency]
4
- [polymer.transcription.domain :as domain]))
5
-
6
- ;; Compatibility adapter for LoomLarge's historical TranscriptionService API.
7
- ;; Recognition, microphone acquisition, AudioContext analysis, playback-reference
8
- ;; comparison, and frame monitoring all remain private to the agency effector.
9
-
10
- (defn data-map
11
- [value]
12
- (cond
13
- (map? value) value
14
- value (js->clj value :keywordize-keys true)
15
- :else {}))
16
-
17
- (defn js-call
18
- [target method-name & args]
19
- (when target
20
- (when-let [method (aget target method-name)]
21
- (when (fn? method)
22
- (.apply method target (to-array args))))))
23
-
24
- (defn emit-set!
25
- [listeners & args]
26
- (doseq [listener @listeners]
27
- (.apply listener nil (to-array args))))
28
-
29
- (defn promise-resolve
30
- [value]
31
- (.resolve js/Promise value))
32
-
33
- (defn compatibility-config
34
- [config]
35
- ;; Preserve the active LoomLarge barge-in defaults explicitly at the adapter
36
- ;; boundary. Direct agency construction uses the same normalized defaults.
37
- (merge {:agentFilteringEnabled true
38
- :interruptDetectionEnabled true
39
- :requireAgentReferenceForInterruption true}
40
- (data-map config)))
41
-
42
- (defn create-service
43
- [config callbacks]
44
- (let [agency (transcription-agency/create-transcription-agency
45
- (compatibility-config config))
46
- transcript-listeners (atom #{})
47
- boundary-listeners (atom #{})
48
- interruption-listeners (atom #{})
49
- disposed? (atom false)
50
- last-status (atom "idle")
51
- unsubscribe (atom nil)]
52
- (letfn [(dispatch! [command]
53
- (js-call agency "dispatch" (clj->js command)))
54
-
55
- (emit-transcript! [event]
56
- (let [text (:text event)
57
- final? (boolean (:isFinal event))]
58
- (js-call callbacks "onTranscript" text final?)
59
- (emit-set! transcript-listeners text final?)
60
- (when final?
61
- (doseq [boundary
62
- (domain/boundary-events text (:at event))]
63
- (let [payload (clj->js boundary)]
64
- (js-call callbacks "onBoundary" payload)
65
- (emit-set! boundary-listeners payload))))))
66
-
67
- (emit-status! [event]
68
- (let [status (:status event)
69
- previous @last-status]
70
- (reset! last-status status)
71
- (when (and (= "listening" status)
72
- (not= "listening" previous))
73
- (js-call callbacks "onStart"))
74
- (when (and (= "idle" status)
75
- (not= "idle" previous))
76
- (js-call callbacks "onEnd"))))
77
-
78
- (emit-audio-interruption! [event]
79
- (let [payload (clj->js
80
- (select-keys
81
- event
82
- [:timestamp
83
- :microphoneLevel
84
- :referenceLevel
85
- :requiredLevel]))]
86
- (js-call callbacks "onInterruption" payload)
87
- (emit-set! interruption-listeners payload)))
88
-
89
- (handle-event! [value]
90
- (when-not @disposed?
91
- (let [event (data-map value)]
92
- (case (:type event)
93
- ("transcription.partial" "transcription.final")
94
- (emit-transcript! event)
95
-
96
- "transcription.audioInterruption"
97
- (emit-audio-interruption! event)
98
-
99
- "transcription.error"
100
- (js-call callbacks "onError"
101
- (js/Error. (:message event)))
102
-
103
- "transcription.status"
104
- (emit-status! event)
105
-
106
- nil))))
107
-
108
- (handle-agent-speech! [value]
109
- (let [event (data-map value)
110
- text (or (:phrase event)
111
- (when (seq (:words event))
112
- (str/join " " (:words event))))]
113
- (case (:type event)
114
- "AGENT_SCRIPT"
115
- (dispatch! {:type "agentSpeechPrepared" :text text})
116
-
117
- "AGENT_START"
118
- (dispatch! {:type "agentSpeechObserved" :text text})
119
-
120
- ("END" "AGENT_DONE" "PLAYBACK_ENDED")
121
- (dispatch! {:type "agentSpeechEnded"})
122
-
123
- "WORD"
124
- (dispatch! {:type "agentSpeechWord" :word (:word event)})
125
-
126
- nil)))]
127
- (reset! unsubscribe
128
- (js-call agency "subscribeEvents" handle-event!))
129
- #js {:startListening
130
- (fn []
131
- (if @disposed?
132
- (.reject js/Promise
133
- (js/Error. "Transcription service is disposed"))
134
- (let [result (js-call agency "start")
135
- snapshot (data-map (js-call agency "snapshot"))]
136
- (if (:lastError snapshot)
137
- (.reject js/Promise
138
- (js/Error.
139
- (or (:lastError snapshot)
140
- "speech-recognition-start-error")))
141
- (promise-resolve result)))))
142
-
143
- :stopListening
144
- (fn []
145
- (js-call agency "stop"))
146
-
147
- :handleAgentSpeech handle-agent-speech!
148
-
149
- :prepareAgentSpeech
150
- (fn [text]
151
- (dispatch! {:type "agentSpeechPrepared" :text text}))
152
-
153
- :notifyAgentSpeech
154
- (fn [text]
155
- (dispatch! {:type "agentSpeechObserved" :text text}))
156
-
157
- :notifyAgentSpeechEnd
158
- (fn []
159
- (dispatch! {:type "agentSpeechEnded"}))
160
-
161
- :setAgentAudioReferenceTrack
162
- (fn [track]
163
- (js-call agency "setAgentAudioReferenceTrack" track))
164
-
165
- :onBoundary
166
- (fn [listener]
167
- (swap! boundary-listeners conj listener)
168
- (fn [] (swap! boundary-listeners disj listener)))
169
-
170
- :onTranscript
171
- (fn [listener]
172
- (swap! transcript-listeners conj listener)
173
- (fn [] (swap! transcript-listeners disj listener)))
174
-
175
- :onInterruption
176
- (fn [listener]
177
- (swap! interruption-listeners conj listener)
178
- (fn [] (swap! interruption-listeners disj listener)))
179
-
180
- :getState
181
- (fn []
182
- (js-call agency "snapshot"))
183
-
184
- :updateConfig
185
- (fn [updates]
186
- (dispatch! {:type "configure"
187
- :config (data-map updates)}))
188
-
189
- :dispose
190
- (fn []
191
- (when-not @disposed?
192
- (reset! disposed? true)
193
- (when-let [stop @unsubscribe]
194
- (stop)
195
- (reset! unsubscribe nil))
196
- (reset! transcript-listeners #{})
197
- (reset! boundary-listeners #{})
198
- (reset! interruption-listeners #{})
199
- (js-call agency "dispose")))})))
200
-
201
- (defn TranscriptionService
202
- ([] (create-service nil nil))
203
- ([config] (create-service config nil))
204
- ([config callbacks] (create-service config callbacks)))
205
-
206
- (defn createTranscriptionService
207
- ([] (TranscriptionService nil nil))
208
- ([config] (TranscriptionService config nil))
209
- ([config callbacks] (TranscriptionService config callbacks)))