@theoremjs/react 0.0.0-stage → 0.3.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 (320) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +772 -2
  3. package/client/attachment-hover-preview.d.ts +11 -0
  4. package/client/attachment-hover-preview.js +36 -0
  5. package/client/audio-level.d.ts +5 -0
  6. package/client/audio-level.js +24 -0
  7. package/client/composer-attachments.d.ts +30 -0
  8. package/client/composer-attachments.js +33 -0
  9. package/client/composer-drawer.d.ts +19 -0
  10. package/client/composer-drawer.js +15 -0
  11. package/client/composer-hints.d.ts +25 -0
  12. package/client/composer-hints.js +20 -0
  13. package/client/composer-primary.d.ts +16 -0
  14. package/client/composer-primary.js +25 -0
  15. package/client/decision-images.d.ts +76 -0
  16. package/client/decision-images.js +139 -0
  17. package/client/decision-transport.d.ts +70 -0
  18. package/client/decision-transport.js +175 -0
  19. package/client/decode-composer-draft.d.ts +11 -0
  20. package/client/decode-composer-draft.js +12 -0
  21. package/client/embedding-input.d.ts +84 -0
  22. package/client/embedding-input.js +194 -0
  23. package/client/embedding-space.d.ts +82 -0
  24. package/client/embedding-space.js +389 -0
  25. package/client/embedding-transport.d.ts +40 -0
  26. package/client/embedding-transport.js +71 -0
  27. package/client/encode-composer-draft.d.ts +9 -0
  28. package/client/encode-composer-draft.js +34 -0
  29. package/client/encode-files.d.ts +18 -0
  30. package/client/encode-files.js +54 -0
  31. package/client/failure.d.ts +29 -0
  32. package/client/failure.js +34 -0
  33. package/client/generation-selection.d.ts +15 -0
  34. package/client/generation-selection.js +24 -0
  35. package/client/host-call.d.ts +51 -0
  36. package/client/host-call.js +47 -0
  37. package/client/host-transport.d.ts +70 -0
  38. package/client/host-transport.js +75 -0
  39. package/client/image-output.d.ts +6 -0
  40. package/client/image-output.js +13 -0
  41. package/client/index.d.ts +28 -0
  42. package/client/index.js +22 -0
  43. package/client/ink-waveform.d.ts +17 -0
  44. package/client/ink-waveform.js +68 -0
  45. package/client/live/apply-live-turn-tool-event.d.ts +14 -0
  46. package/client/live/apply-live-turn-tool-event.js +39 -0
  47. package/client/live/live-captions.d.ts +53 -0
  48. package/client/live/live-captions.js +174 -0
  49. package/client/live/live-mic-forward.d.ts +30 -0
  50. package/client/live/live-mic-forward.js +46 -0
  51. package/client/live/live-page-tool.d.ts +34 -0
  52. package/client/live/live-page-tool.js +11 -0
  53. package/client/live/live-state.d.ts +13 -0
  54. package/client/live/live-state.js +22 -0
  55. package/client/live/live-tool.d.ts +11 -0
  56. package/client/live/live-tool.js +1 -0
  57. package/client/live/live-video.d.ts +10 -0
  58. package/client/live/live-video.js +71 -0
  59. package/client/live/run-live-tool-call.d.ts +22 -0
  60. package/client/live/run-live-tool-call.js +70 -0
  61. package/client/live/use-live-caption-log.d.ts +17 -0
  62. package/client/live/use-live-caption-log.js +51 -0
  63. package/client/live-client.d.ts +189 -0
  64. package/client/live-client.js +829 -0
  65. package/client/live-errors.d.ts +2 -0
  66. package/client/live-errors.js +9 -0
  67. package/client/live-messages.d.ts +148 -0
  68. package/client/live-messages.js +100 -0
  69. package/client/mic-capture.d.ts +4 -0
  70. package/client/mic-capture.js +6 -0
  71. package/client/oauth-popup.d.ts +26 -0
  72. package/client/oauth-popup.js +30 -0
  73. package/client/page-dispatch.d.ts +15 -0
  74. package/client/page-dispatch.js +63 -0
  75. package/client/pcm-downsample.d.ts +4 -0
  76. package/client/pcm-downsample.js +45 -0
  77. package/client/run-commit.d.ts +34 -0
  78. package/client/run-commit.js +49 -0
  79. package/client/run-session.d.ts +79 -0
  80. package/client/run-session.js +207 -0
  81. package/client/schema-fields.d.ts +63 -0
  82. package/client/schema-fields.js +199 -0
  83. package/client/shaped-data.d.ts +118 -0
  84. package/client/shaped-data.js +343 -0
  85. package/client/source-citations.d.ts +13 -0
  86. package/client/source-citations.js +56 -0
  87. package/client/space-geometry.d.ts +39 -0
  88. package/client/space-geometry.js +183 -0
  89. package/client/state-fields.d.ts +16 -0
  90. package/client/state-fields.js +44 -0
  91. package/client/tool-result.d.ts +78 -0
  92. package/client/tool-result.js +293 -0
  93. package/client/tool-resume.d.ts +50 -0
  94. package/client/tool-resume.js +14 -0
  95. package/client/trace-feed.d.ts +13 -0
  96. package/client/trace-feed.js +18 -0
  97. package/client/trace-story.d.ts +163 -0
  98. package/client/trace-story.js +440 -0
  99. package/client/trace-view.d.ts +130 -0
  100. package/client/trace-view.js +333 -0
  101. package/client/transcript-groups.d.ts +140 -0
  102. package/client/transcript-groups.js +217 -0
  103. package/client/transcript-schema.d.ts +10 -0
  104. package/client/transcript-schema.js +120 -0
  105. package/client/transcript-scroll.d.ts +7 -0
  106. package/client/transcript-scroll.js +6 -0
  107. package/client/transport.d.ts +264 -0
  108. package/client/transport.js +330 -0
  109. package/client/turn-client.d.ts +44 -0
  110. package/client/turn-client.js +88 -0
  111. package/client/voice-label.d.ts +2 -0
  112. package/client/voice-label.js +15 -0
  113. package/client/voice-recorder.d.ts +27 -0
  114. package/client/voice-recorder.js +162 -0
  115. package/client/wire-line.d.ts +56 -0
  116. package/client/wire-line.js +90 -0
  117. package/client/worklets/mic-capture.js +16 -0
  118. package/components/InkWaveform.d.ts +21 -0
  119. package/components/InkWaveform.js +131 -0
  120. package/components/live/use-live-runner-controls.d.ts +47 -0
  121. package/components/live/use-live-runner-controls.js +96 -0
  122. package/components/live/use-live-runner-model.d.ts +49 -0
  123. package/components/live/use-live-runner-model.js +190 -0
  124. package/components/live/use-live-runner-ui.d.ts +67 -0
  125. package/components/live/use-live-runner-ui.js +167 -0
  126. package/components/live/use-live-session-client.d.ts +41 -0
  127. package/components/live/use-live-session-client.js +126 -0
  128. package/components/use-composer-voice.d.ts +28 -0
  129. package/components/use-composer-voice.js +90 -0
  130. package/components/use-editor-selection.d.ts +3 -0
  131. package/components/use-editor-selection.js +19 -0
  132. package/components/use-voice-playback.d.ts +17 -0
  133. package/components/use-voice-playback.js +68 -0
  134. package/hooks/use-described.d.ts +12 -0
  135. package/hooks/use-described.js +25 -0
  136. package/hooks/use-embedding-index.d.ts +27 -0
  137. package/hooks/use-embedding-index.js +43 -0
  138. package/hooks/use-one-call.d.ts +31 -0
  139. package/hooks/use-one-call.js +76 -0
  140. package/hooks/use-page-tool-warnings.d.ts +6 -0
  141. package/hooks/use-page-tool-warnings.js +25 -0
  142. package/hooks/use-second-ticker.d.ts +2 -0
  143. package/hooks/use-second-ticker.js +13 -0
  144. package/hooks/use-theorem-chat-actions.d.ts +79 -0
  145. package/hooks/use-theorem-chat-actions.js +287 -0
  146. package/hooks/use-theorem-chat-state.d.ts +66 -0
  147. package/hooks/use-theorem-chat-state.js +122 -0
  148. package/hooks/use-theorem-chat.d.ts +97 -0
  149. package/hooks/use-theorem-chat.js +528 -0
  150. package/hooks/use-theorem-decision.d.ts +18 -0
  151. package/hooks/use-theorem-decision.js +12 -0
  152. package/hooks/use-theorem-embedding.d.ts +18 -0
  153. package/hooks/use-theorem-embedding.js +12 -0
  154. package/hooks/use-theorem-host.d.ts +45 -0
  155. package/hooks/use-theorem-host.js +135 -0
  156. package/hooks/use-theorem-interface.d.ts +22 -0
  157. package/hooks/use-theorem-interface.js +15 -0
  158. package/hooks/use-trace-records.d.ts +4 -0
  159. package/hooks/use-trace-records.js +7 -0
  160. package/index.d.ts +17 -0
  161. package/index.js +17 -0
  162. package/live.d.ts +9 -0
  163. package/live.js +10 -0
  164. package/package.json +74 -4
  165. package/server/checkpoint-ownership.d.ts +6 -0
  166. package/server/checkpoint-ownership.js +42 -0
  167. package/server/conversation-store.d.ts +92 -0
  168. package/server/conversation-store.js +131 -0
  169. package/server/conversation.d.ts +193 -0
  170. package/server/conversation.js +552 -0
  171. package/server/credential-store.d.ts +24 -0
  172. package/server/credential-store.js +14 -0
  173. package/server/decision-handler.d.ts +42 -0
  174. package/server/decision-handler.js +46 -0
  175. package/server/embedding-handler.d.ts +33 -0
  176. package/server/embedding-handler.js +45 -0
  177. package/server/handler.d.ts +152 -0
  178. package/server/handler.js +771 -0
  179. package/server/json-response.d.ts +2 -0
  180. package/server/json-response.js +7 -0
  181. package/server/mod.d.ts +25 -0
  182. package/server/mod.js +23 -0
  183. package/server/page-dispatch.d.ts +22 -0
  184. package/server/page-dispatch.js +127 -0
  185. package/server/request-body.d.ts +2 -0
  186. package/server/request-body.js +42 -0
  187. package/server/request-check.d.ts +21 -0
  188. package/server/request-check.js +49 -0
  189. package/server/session-authority.d.ts +8 -0
  190. package/server/session-authority.js +78 -0
  191. package/server/session-boundary.d.ts +26 -0
  192. package/server/session-boundary.js +64 -0
  193. package/server/session-identity.d.ts +16 -0
  194. package/server/session-identity.js +41 -0
  195. package/server/session-limits.d.ts +12 -0
  196. package/server/session-limits.js +59 -0
  197. package/server/session-store.d.ts +123 -0
  198. package/server/session-store.js +264 -0
  199. package/server/single-action.d.ts +21 -0
  200. package/server/single-action.js +30 -0
  201. package/server/steer-inbox.d.ts +35 -0
  202. package/server/steer-inbox.js +52 -0
  203. package/server/tool-operations.d.ts +6 -0
  204. package/server/tool-operations.js +132 -0
  205. package/server/turn-input.d.ts +10 -0
  206. package/server/turn-input.js +29 -0
  207. package/styles/ink-controls.css +134 -0
  208. package/ui/CardWall.d.ts +10 -0
  209. package/ui/CardWall.js +61 -0
  210. package/ui/ChatComposerBar.d.ts +62 -0
  211. package/ui/ChatComposerBar.js +306 -0
  212. package/ui/ChatTranscript.d.ts +43 -0
  213. package/ui/ChatTranscript.js +527 -0
  214. package/ui/ConsoleFrame.d.ts +104 -0
  215. package/ui/ConsoleFrame.js +146 -0
  216. package/ui/DecisionAnswers.d.ts +53 -0
  217. package/ui/DecisionAnswers.js +233 -0
  218. package/ui/DecisionImages.d.ts +16 -0
  219. package/ui/DecisionImages.js +46 -0
  220. package/ui/EmbeddingDocuments.d.ts +78 -0
  221. package/ui/EmbeddingDocuments.js +278 -0
  222. package/ui/EmbeddingQuery.d.ts +27 -0
  223. package/ui/EmbeddingQuery.js +95 -0
  224. package/ui/EmbeddingResults.d.ts +41 -0
  225. package/ui/EmbeddingResults.js +165 -0
  226. package/ui/EmbeddingSpace.d.ts +26 -0
  227. package/ui/EmbeddingSpace.js +106 -0
  228. package/ui/LiveCaptionsPanel.d.ts +22 -0
  229. package/ui/LiveCaptionsPanel.js +27 -0
  230. package/ui/LiveRunner.d.ts +30 -0
  231. package/ui/LiveRunner.js +180 -0
  232. package/ui/PaneState.d.ts +33 -0
  233. package/ui/PaneState.js +50 -0
  234. package/ui/SchemaFields.d.ts +10 -0
  235. package/ui/SchemaFields.js +150 -0
  236. package/ui/ShapedData.d.ts +11 -0
  237. package/ui/ShapedData.js +196 -0
  238. package/ui/SidePanel.d.ts +126 -0
  239. package/ui/SidePanel.js +123 -0
  240. package/ui/StateFields.d.ts +44 -0
  241. package/ui/StateFields.js +139 -0
  242. package/ui/TheoremChat.d.ts +122 -0
  243. package/ui/TheoremChat.js +134 -0
  244. package/ui/TheoremDecision.d.ts +30 -0
  245. package/ui/TheoremDecision.js +130 -0
  246. package/ui/TheoremEmbedding.d.ts +27 -0
  247. package/ui/TheoremEmbedding.js +122 -0
  248. package/ui/TheoremHost.d.ts +55 -0
  249. package/ui/TheoremHost.js +240 -0
  250. package/ui/ToolGateCard.d.ts +32 -0
  251. package/ui/ToolGateCard.js +107 -0
  252. package/ui/ToolResult.d.ts +10 -0
  253. package/ui/ToolResult.js +62 -0
  254. package/ui/ToolResultCharts.d.ts +5 -0
  255. package/ui/ToolResultCharts.js +103 -0
  256. package/ui/TraceCharts.d.ts +13 -0
  257. package/ui/TraceCharts.js +266 -0
  258. package/ui/TraceGuardrails.d.ts +11 -0
  259. package/ui/TraceGuardrails.js +74 -0
  260. package/ui/TraceInspector.d.ts +16 -0
  261. package/ui/TraceInspector.js +206 -0
  262. package/ui/TraceInspectorPanel.d.ts +46 -0
  263. package/ui/TraceInspectorPanel.js +95 -0
  264. package/ui/TraceOverview.d.ts +38 -0
  265. package/ui/TraceOverview.js +126 -0
  266. package/ui/TraceSpanDetail.d.ts +10 -0
  267. package/ui/TraceSpanDetail.js +190 -0
  268. package/ui/TraceStory.d.ts +20 -0
  269. package/ui/TraceStory.js +108 -0
  270. package/ui/TraceValues.d.ts +36 -0
  271. package/ui/TraceValues.js +123 -0
  272. package/ui/TraceWaterfall.d.ts +13 -0
  273. package/ui/TraceWaterfall.js +135 -0
  274. package/ui/VoiceNote.d.ts +12 -0
  275. package/ui/VoiceNote.js +28 -0
  276. package/ui/approval-heading.d.ts +4 -0
  277. package/ui/approval-heading.js +9 -0
  278. package/ui/arrive.d.ts +18 -0
  279. package/ui/arrive.js +46 -0
  280. package/ui/built/theme.css +792 -0
  281. package/ui/built/theme.css.d.ts +9 -0
  282. package/ui/built/theorem.d.ts +13 -0
  283. package/ui/built/theorem.js +660 -0
  284. package/ui/built/theorem.variants.d.ts +22 -0
  285. package/ui/code-language.d.ts +12 -0
  286. package/ui/code-language.js +50 -0
  287. package/ui/disclosure-motion.d.ts +6 -0
  288. package/ui/disclosure-motion.js +207 -0
  289. package/ui/embedding-space-gl.d.ts +37 -0
  290. package/ui/embedding-space-gl.js +663 -0
  291. package/ui/embedding-space-view.d.ts +8 -0
  292. package/ui/embedding-space-view.js +8 -0
  293. package/ui/glide.d.ts +7 -0
  294. package/ui/glide.js +44 -0
  295. package/ui/icons.d.ts +4 -0
  296. package/ui/icons.js +38 -0
  297. package/ui/index.d.ts +36 -0
  298. package/ui/index.js +39 -0
  299. package/ui/labels-provider.d.ts +16 -0
  300. package/ui/labels-provider.js +64 -0
  301. package/ui/labels.d.ts +1442 -0
  302. package/ui/labels.js +1443 -0
  303. package/ui/markdown-plugins.d.ts +9 -0
  304. package/ui/markdown-plugins.js +13 -0
  305. package/ui/mcp-icon.d.ts +6 -0
  306. package/ui/mcp-icon.js +8 -0
  307. package/ui/row-keys.d.ts +19 -0
  308. package/ui/row-keys.js +33 -0
  309. package/ui/theme.d.ts +10 -0
  310. package/ui/theme.js +13 -0
  311. package/ui/theorem-theme.d.ts +10 -0
  312. package/ui/theorem-theme.js +105 -0
  313. package/ui/trace-palette.d.ts +10 -0
  314. package/ui/trace-palette.js +10 -0
  315. package/ui/trace-patterns.d.ts +40 -0
  316. package/ui/trace-patterns.js +57 -0
  317. package/ui/transcript-copy-text.d.ts +4 -0
  318. package/ui/transcript-copy-text.js +40 -0
  319. package/ui/wall-columns.d.ts +8 -0
  320. package/ui/wall-columns.js +19 -0
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Every value that reaches the browser over a wire (NDJSON lines, live
3
+ * envelopes) is checked against its schema here. A line or event of a kind the
4
+ * client does not know is reported as `unsupported`, and one that fails its
5
+ * check (not JSON, no kind, or a known kind that fails its schema) as
6
+ * `malformed`; either way the reply goes on. A whole reply that fails its check
7
+ * (the profile description) is `bad_response`.
8
+ *
9
+ * @module
10
+ */
11
+ import { TheoremError, z } from '@theoremjs/agents';
12
+ /**
13
+ * A line or envelope of a kind the client does not know. The server never
14
+ * sends it; the client's parser makes it so the host sees what arrived. Theorem
15
+ * shows nothing for it.
16
+ */
17
+ export type UnsupportedEvent = {
18
+ type: 'unsupported';
19
+ received: string;
20
+ raw: unknown;
21
+ };
22
+ /**
23
+ * A line or event that failed its wire check. The server never sends it; the
24
+ * client's reader makes it, leaves the line out, and the reply goes on. `error`
25
+ * is `bad_response`: its message names what broke, never the value, and the
26
+ * user reads `session.part_skipped`.
27
+ */
28
+ export type MalformedEvent = {
29
+ type: 'malformed';
30
+ error: TheoremError;
31
+ };
32
+ /** Every kind a wire carries, and the schema a value of that kind must pass. */
33
+ export type WireLines<Line extends {
34
+ type: string;
35
+ }> = {
36
+ readonly [K in Line['type']]: z.ZodType<Extract<Line, {
37
+ type: K;
38
+ }>>;
39
+ };
40
+ /**
41
+ * Issue paths and codes only: a failure names what broke, never the value. A
42
+ * union that matched no branch lists each branch's issues.
43
+ */
44
+ export declare function issueSummary(error: z.ZodError): string;
45
+ /** `raw` as `schema` reads it; one that fails is `bad_response`, naming `what`. */
46
+ export declare function checkWire<T>(schema: z.ZodType<T>, raw: unknown, what: string): T;
47
+ /** One wire value: a known kind that passed its schema, `unsupported`, or `malformed`. */
48
+ export declare function readWireValue<Line extends {
49
+ type: string;
50
+ }>(lines: WireLines<Line>, raw: unknown): Line | UnsupportedEvent | MalformedEvent;
51
+ /** One wire line's text: {@link readWireValue} of its JSON, or `malformed` when it is not JSON. */
52
+ export declare function readWireLine<Line extends {
53
+ type: string;
54
+ }>(lines: WireLines<Line>, text: string): Line | UnsupportedEvent | MalformedEvent;
55
+ /** A whole reply's JSON text as a value; text that is not JSON is `bad_response`. */
56
+ export declare function parseWireJson(text: string): unknown;
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Every value that reaches the browser over a wire (NDJSON lines, live
3
+ * envelopes) is checked against its schema here. A line or event of a kind the
4
+ * client does not know is reported as `unsupported`, and one that fails its
5
+ * check (not JSON, no kind, or a known kind that fails its schema) as
6
+ * `malformed`; either way the reply goes on. A whole reply that fails its check
7
+ * (the profile description) is `bad_response`.
8
+ *
9
+ * @module
10
+ */
11
+ import { TheoremError, z } from '@theoremjs/agents';
12
+ const wireKind = z.object({ type: z.string() });
13
+ function isKnown(lines, type) {
14
+ return Object.hasOwn(lines, type);
15
+ }
16
+ function issuesSummary(issues, at) {
17
+ return issues
18
+ .map((issue) => {
19
+ const path = [...at, ...issue.path];
20
+ const head = `${path.map(String).join('.') || '(root)'} ${issue.code}`;
21
+ if (issue.code !== 'invalid_union' || issue.errors.length === 0)
22
+ return head;
23
+ return `${head} [${issue.errors.map((branch) => issuesSummary(branch, path)).join(' | ')}]`;
24
+ })
25
+ .join('; ');
26
+ }
27
+ /**
28
+ * Issue paths and codes only: a failure names what broke, never the value. A
29
+ * union that matched no branch lists each branch's issues.
30
+ */
31
+ export function issueSummary(error) {
32
+ return issuesSummary(error.issues, []);
33
+ }
34
+ function badResponse(what, error) {
35
+ // labels-exempt: internal diagnostic; the user reads error.bad_response
36
+ return new TheoremError('bad_response', `${what} failed its wire check: ${issueSummary(error)}`);
37
+ }
38
+ /** `raw` as `schema` reads it; one that fails is `bad_response`, naming `what`. */
39
+ export function checkWire(schema, raw, what) {
40
+ const parsed = schema.safeParse(raw);
41
+ if (!parsed.success)
42
+ throw badResponse(what, parsed.error);
43
+ return parsed.data;
44
+ }
45
+ function malformed(message) {
46
+ return {
47
+ type: 'malformed',
48
+ error: new TheoremError('bad_response', message, { copy: { key: 'session.part_skipped' } }),
49
+ };
50
+ }
51
+ /** One wire value: a known kind that passed its schema, `unsupported`, or `malformed`. */
52
+ export function readWireValue(lines, raw) {
53
+ const kind = wireKind.safeParse(raw);
54
+ // labels-exempt: internal diagnostic; the user reads session.part_skipped
55
+ if (!kind.success)
56
+ return malformed(`a line without a kind failed its wire check: ${issueSummary(kind.error)}`);
57
+ const { type } = kind.data;
58
+ if (!isKnown(lines, type))
59
+ return { type: 'unsupported', received: type, raw };
60
+ const line = lines[type].safeParse(raw);
61
+ if (line.success)
62
+ return line.data;
63
+ // labels-exempt: internal diagnostic; the user reads session.part_skipped
64
+ return malformed(`a '${type}' line failed its wire check: ${issueSummary(line.error)}`);
65
+ }
66
+ /** JSON text as a value, or undefined when it is not JSON. The parser's own error quotes the text, so it is not kept. */
67
+ function jsonValue(text) {
68
+ try {
69
+ return { value: JSON.parse(text) };
70
+ }
71
+ catch (err) {
72
+ if (err instanceof SyntaxError)
73
+ return undefined;
74
+ throw err;
75
+ }
76
+ }
77
+ /** One wire line's text: {@link readWireValue} of its JSON, or `malformed` when it is not JSON. */
78
+ export function readWireLine(lines, text) {
79
+ const json = jsonValue(text);
80
+ // labels-exempt: internal diagnostic; the user reads session.part_skipped
81
+ return json ? readWireValue(lines, json.value) : malformed('a line is not JSON');
82
+ }
83
+ /** A whole reply's JSON text as a value; text that is not JSON is `bad_response`. */
84
+ export function parseWireJson(text) {
85
+ const json = jsonValue(text);
86
+ // labels-exempt: internal diagnostic; the user reads error.bad_response
87
+ if (!json)
88
+ throw new TheoremError('bad_response', 'a line is not JSON');
89
+ return json.value;
90
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * AudioWorklet processor that forwards mono mic frames to the main thread.
3
+ * Plain JS: it runs in the AudioWorkletGlobalScope as its own module, loaded
4
+ * by URL (see `../mic-capture.ts`), so it imports nothing and ships as is.
5
+ */
6
+ registerProcessor(
7
+ 'mic-capture-processor',
8
+ class MicCaptureProcessor extends AudioWorkletProcessor {
9
+ process(inputs) {
10
+ const channel = inputs[0][0];
11
+ const copy = new Float32Array(channel);
12
+ this.port.postMessage(copy, [copy.buffer]);
13
+ return true;
14
+ }
15
+ },
16
+ );
@@ -0,0 +1,21 @@
1
+ import { type RefObject } from 'react';
2
+ import { type InkWaveStatus } from '../client/ink-waveform.ts';
3
+ /** Mic and speaker levels. A host on the audio clock writes this; the bars read it each frame. */
4
+ export type InkWaveLevels = {
5
+ input: number;
6
+ output: number;
7
+ };
8
+ export type InkWaveformProps = {
9
+ status?: InkWaveStatus;
10
+ inputLevel?: number;
11
+ outputLevel?: number;
12
+ /**
13
+ * Latest levels, read each frame. When set, it wins over `inputLevel` and
14
+ * `outputLevel`, so a host can move the bars without rendering.
15
+ */
16
+ levelsRef?: RefObject<InkWaveLevels>;
17
+ toolActive?: boolean;
18
+ frozen?: boolean;
19
+ variant?: 'default' | 'hero' | 'pill' | 'strip';
20
+ };
21
+ export declare function InkWaveform({ status, inputLevel, outputLevel, levelsRef, toolActive, frozen, variant, }: InkWaveformProps): import("react").JSX.Element;
@@ -0,0 +1,131 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useRef } from 'react';
3
+ import { computeInkBarTargets, INK_WAVE_BAR_COUNT, INK_WAVE_HERO_BAR_COUNT, inkWaveDriver, inkWavePhases, } from "../client/ink-waveform.js";
4
+ const REST_HEIGHT = 0.06;
5
+ const WAVE_CONFIG = {
6
+ hero: {
7
+ viewWidth: 960,
8
+ viewHeight: 720,
9
+ preserveAspect: 'xMidYMax slice',
10
+ strokeWidth: 2,
11
+ barCount: INK_WAVE_HERO_BAR_COUNT,
12
+ },
13
+ pill: {
14
+ viewWidth: 480,
15
+ viewHeight: 120,
16
+ preserveAspect: 'none',
17
+ strokeWidth: 3,
18
+ barCount: INK_WAVE_BAR_COUNT,
19
+ },
20
+ strip: {
21
+ viewWidth: 1600,
22
+ viewHeight: 48,
23
+ preserveAspect: 'none',
24
+ strokeWidth: 2,
25
+ barCount: 120,
26
+ },
27
+ default: {
28
+ viewWidth: 480,
29
+ viewHeight: 320,
30
+ preserveAspect: 'xMidYMax meet',
31
+ strokeWidth: 2,
32
+ barCount: INK_WAVE_BAR_COUNT,
33
+ },
34
+ };
35
+ function resolveWaveDimensions(variant) {
36
+ const cfg = WAVE_CONFIG[variant] ?? WAVE_CONFIG.default;
37
+ const gap = (cfg.viewWidth - cfg.strokeWidth * cfg.barCount) / (cfg.barCount + 1);
38
+ return { ...cfg, gap };
39
+ }
40
+ /** One frame's bar targets. The live ref's levels win over the last render's; a frozen wave moves to none. */
41
+ function frameTargets(snap, phases, timeMs) {
42
+ const { input, output } = snap.levelsRef?.current ?? {
43
+ input: snap.inputLevel,
44
+ output: snap.outputLevel,
45
+ };
46
+ const heard = snap.frozen ? { input: 0, output: 0 } : { input, output };
47
+ return computeInkBarTargets({
48
+ phases,
49
+ timeMs,
50
+ driver: inkWaveDriver(snap.status, snap.toolActive, input, output, snap.frozen),
51
+ inputLevel: heard.input,
52
+ outputLevel: heard.output,
53
+ frozen: snap.frozen,
54
+ });
55
+ }
56
+ /**
57
+ * Paints bar heights onto the mounted lines. The motion is the same as
58
+ * `computeInkBarTargets` plus the per-frame ease; React never sees a frame,
59
+ * so a strip of bars does not reconcile on the audio clock.
60
+ */
61
+ function usePaintedWave(svgRef, snapRef, phases, barCount, viewHeight) {
62
+ useEffect(() => {
63
+ const svg = svgRef.current;
64
+ if (!svg)
65
+ return;
66
+ const lines = svg.children;
67
+ const count = Math.min(barCount, lines.length);
68
+ const heights = new Float64Array(count);
69
+ heights.fill(REST_HEIGHT);
70
+ const restY = viewHeight - REST_HEIGHT * (viewHeight - 4);
71
+ for (let index = 0; index < count; index++) {
72
+ lines[index].y2.baseVal.value = restY;
73
+ }
74
+ let frame = 0;
75
+ const tick = (time) => {
76
+ const snap = snapRef.current;
77
+ const targets = frameTargets(snap, phases, time);
78
+ const alpha = snap.frozen ? 0.2 : 0.14;
79
+ for (let index = 0; index < count; index++) {
80
+ const height = heights[index] + (targets[index] - heights[index]) * alpha;
81
+ heights[index] = height;
82
+ lines[index].y2.baseVal.value = viewHeight - height * (viewHeight - 4);
83
+ }
84
+ frame = requestAnimationFrame(tick);
85
+ };
86
+ frame = requestAnimationFrame(tick);
87
+ return () => {
88
+ cancelAnimationFrame(frame);
89
+ };
90
+ }, [svgRef, snapRef, phases, barCount, viewHeight]);
91
+ }
92
+ export function InkWaveform({ status = 'disconnected', inputLevel = 0, outputLevel = 0, levelsRef, toolActive = false, frozen = false, variant = 'default', }) {
93
+ const { viewWidth, viewHeight, preserveAspect, strokeWidth, barCount, gap } = resolveWaveDimensions(variant);
94
+ const phases = useMemo(() => inkWavePhases(barCount), [barCount]);
95
+ const xs = useMemo(() => {
96
+ const next = new Array(barCount);
97
+ for (let index = 0; index < barCount; index++) {
98
+ next[index] = gap + index * (strokeWidth + gap) + strokeWidth / 2;
99
+ }
100
+ return next;
101
+ }, [barCount, gap, strokeWidth]);
102
+ const svgRef = useRef(null);
103
+ const snapRef = useRef({
104
+ status,
105
+ inputLevel,
106
+ outputLevel,
107
+ levelsRef,
108
+ toolActive,
109
+ frozen,
110
+ });
111
+ snapRef.current.status = status;
112
+ snapRef.current.inputLevel = inputLevel;
113
+ snapRef.current.outputLevel = outputLevel;
114
+ snapRef.current.levelsRef = levelsRef;
115
+ snapRef.current.toolActive = toolActive;
116
+ snapRef.current.frozen = frozen;
117
+ usePaintedWave(svgRef, snapRef, phases, barCount, viewHeight);
118
+ const className = [
119
+ 'ink-wave',
120
+ variant === 'hero' ? 'ink-wave--hero' : '',
121
+ variant === 'pill' ? 'ink-wave--pill' : '',
122
+ variant === 'strip' ? 'ink-wave--strip' : '',
123
+ ]
124
+ .filter(Boolean)
125
+ .join(' ');
126
+ const restY = viewHeight - REST_HEIGHT * (viewHeight - 4);
127
+ return (_jsx("svg", { ref: svgRef, className: className, "aria-hidden": "true", viewBox: `0 0 ${String(viewWidth)} ${String(viewHeight)}`, preserveAspectRatio: preserveAspect,
128
+ // why: Attribute defaults for hosts without ink-controls.css (the Astryx UI);
129
+ // the live stylesheet overrides them where it loads.
130
+ width: "100%", height: "100%", children: xs.map((x) => (_jsx("line", { className: "ink-wave__bar", x1: x, x2: x, y1: viewHeight, y2: restY, strokeWidth: strokeWidth, stroke: "currentColor", strokeLinecap: "square" }, x))) }));
131
+ }
@@ -0,0 +1,47 @@
1
+ import { type Dispatch, type MutableRefObject, type SetStateAction } from 'react';
2
+ import { type LiveCaptionState } from '../../client/live/live-captions.ts';
3
+ import type { LiveConnectPhase, LiveSessionStatus } from '../../client/live/live-state.ts';
4
+ import { type LiveFacingMode, type LiveVideoCapture } from '../../client/live/live-video.ts';
5
+ import type { LiveConnection, LiveSessionClient } from '../../client/live-client.ts';
6
+ /** Media + session lifecycle handlers for LiveRunner. */
7
+ export declare function useLiveRunnerControls(args: {
8
+ clientRef: MutableRefObject<LiveSessionClient | null>;
9
+ videoCaptureRef: MutableRefObject<LiveVideoCapture | null>;
10
+ connectionRef: MutableRefObject<() => LiveConnection | Promise<LiveConnection>>;
11
+ statusRef: MutableRefObject<LiveSessionStatus>;
12
+ isMutedRef: MutableRefObject<boolean>;
13
+ sessionPermissionsRef: MutableRefObject<string[]>;
14
+ ensureClient: (connection: LiveConnection) => LiveSessionClient;
15
+ clearClient: () => void;
16
+ cancelGateDecision: (reason?: string) => void;
17
+ stopVideo: () => void;
18
+ resetCaptions: () => void;
19
+ sessionActive: boolean;
20
+ textAvailable: boolean;
21
+ videoAvailable: boolean;
22
+ voiceAvailable: boolean;
23
+ isVideoOn: boolean;
24
+ textDraft: string;
25
+ setTextDraft: Dispatch<SetStateAction<string>>;
26
+ setCaptions: Dispatch<SetStateAction<LiveCaptionState>>;
27
+ reportFailure: (err: unknown) => void;
28
+ clearFailure: () => void;
29
+ setIsMuted: Dispatch<SetStateAction<boolean>>;
30
+ setSessionActive: Dispatch<SetStateAction<boolean>>;
31
+ setSessionPermissions: Dispatch<SetStateAction<string[]>>;
32
+ setStatus: Dispatch<SetStateAction<LiveSessionStatus>>;
33
+ setConnectPhase: Dispatch<SetStateAction<LiveConnectPhase | null>>;
34
+ setInputLevel: Dispatch<SetStateAction<number>>;
35
+ setOutputLevel: Dispatch<SetStateAction<number>>;
36
+ setVideoPreview: Dispatch<SetStateAction<HTMLVideoElement | null>>;
37
+ setVideoFacingMode: Dispatch<SetStateAction<LiveFacingMode>>;
38
+ setIsVideoOn: Dispatch<SetStateAction<boolean>>;
39
+ }): {
40
+ teardownSession: () => void;
41
+ startSession: () => Promise<void>;
42
+ handleSendText: (text?: string) => void;
43
+ handleToggleVideo: () => Promise<void>;
44
+ handleFlipCamera: () => Promise<void>;
45
+ handleToggleMic: () => void;
46
+ handleRestart: () => Promise<void>;
47
+ };
@@ -0,0 +1,96 @@
1
+ import { useCallback } from 'react';
2
+ import { applyLiveTranscript } from "../../client/live/live-captions.js";
3
+ import { startLiveVideoCapture, } from "../../client/live/live-video.js";
4
+ /** Media + session lifecycle handlers for LiveRunner. */
5
+ export function useLiveRunnerControls(args) {
6
+ const teardownSession = useCallback(() => {
7
+ args.cancelGateDecision();
8
+ args.clearClient();
9
+ args.stopVideo();
10
+ args.setIsMuted(false);
11
+ args.isMutedRef.current = false;
12
+ args.setSessionActive(false);
13
+ args.setSessionPermissions([]);
14
+ args.sessionPermissionsRef.current = [];
15
+ args.statusRef.current = 'disconnected';
16
+ args.setStatus('disconnected');
17
+ args.setConnectPhase(null);
18
+ args.setInputLevel(0);
19
+ args.setOutputLevel(0);
20
+ }, [args]);
21
+ const startSession = useCallback(async () => {
22
+ args.clearFailure();
23
+ args.resetCaptions();
24
+ try {
25
+ const liveClient = args.ensureClient(await args.connectionRef.current());
26
+ if (args.statusRef.current === 'disconnected' || args.statusRef.current === 'error') {
27
+ await liveClient.connect();
28
+ }
29
+ }
30
+ catch (err) {
31
+ args.reportFailure(err);
32
+ }
33
+ }, [args]);
34
+ const handleSendText = useCallback((text) => {
35
+ const message = (typeof text === 'string' ? text : args.textDraft).trim();
36
+ if (!message || !args.clientRef.current || !args.sessionActive || !args.textAvailable)
37
+ return;
38
+ args.clientRef.current.sendText(message);
39
+ args.setTextDraft('');
40
+ args.setCaptions((prev) => applyLiveTranscript(prev, message, true, false, { forceNew: true }));
41
+ }, [args]);
42
+ const handleToggleVideo = useCallback(async () => {
43
+ if (!args.clientRef.current || !args.sessionActive || !args.videoAvailable)
44
+ return;
45
+ if (args.isVideoOn) {
46
+ args.stopVideo();
47
+ return;
48
+ }
49
+ try {
50
+ const capture = await startLiveVideoCapture((base64) => {
51
+ args.clientRef.current?.sendVideo(base64);
52
+ });
53
+ args.videoCaptureRef.current = capture;
54
+ args.setVideoPreview(capture.video);
55
+ args.setVideoFacingMode(capture.facingMode());
56
+ args.setIsVideoOn(true);
57
+ }
58
+ catch (err) {
59
+ args.reportFailure(err);
60
+ args.stopVideo();
61
+ }
62
+ }, [args]);
63
+ const handleFlipCamera = useCallback(async () => {
64
+ const capture = args.videoCaptureRef.current;
65
+ if (!capture || !args.sessionActive || !args.isVideoOn)
66
+ return;
67
+ try {
68
+ const facing = await capture.flip();
69
+ args.setVideoFacingMode(facing);
70
+ args.setVideoPreview(capture.video);
71
+ }
72
+ catch (err) {
73
+ args.reportFailure(err);
74
+ }
75
+ }, [args]);
76
+ const handleToggleMic = useCallback(() => {
77
+ if (!args.clientRef.current || !args.sessionActive || !args.voiceAvailable)
78
+ return;
79
+ const muted = args.clientRef.current.toggleMute();
80
+ args.isMutedRef.current = muted;
81
+ args.setIsMuted(muted);
82
+ }, [args]);
83
+ const handleRestart = useCallback(async () => {
84
+ teardownSession();
85
+ await startSession();
86
+ }, [startSession, teardownSession]);
87
+ return {
88
+ teardownSession,
89
+ startSession,
90
+ handleSendText,
91
+ handleToggleVideo,
92
+ handleFlipCamera,
93
+ handleToggleMic,
94
+ handleRestart,
95
+ };
96
+ }
@@ -0,0 +1,49 @@
1
+ import type { LiveProfileInterface } from '@theoremjs/agents/interface';
2
+ import { type LiveCaptionState, type LiveCaptionTurn } from '../../client/live/live-captions.ts';
3
+ import type { LiveCallOptions } from '../../client/live/live-page-tool.ts';
4
+ import type { LiveConnection } from '../../client/live-client.ts';
5
+ /**
6
+ * Owns LiveRunner state, session client, and stage callbacks.
7
+ * `connection` resolves what the call opens: a host with a fixed profile returns
8
+ * its id; the studio returns its draft as the relay's open message. `options`
9
+ * are the host's part in the call: its slots, the page's context, and its page tools.
10
+ */
11
+ export declare function useLiveRunnerModel(iface: LiveProfileInterface, connection: () => LiveConnection | Promise<LiveConnection>, options?: LiveCallOptions): {
12
+ handle: string;
13
+ traces: import("../../index.ts").TraceFeed;
14
+ callStarted: boolean;
15
+ pastCalls: LiveCaptionTurn[][];
16
+ captions: LiveCaptionState;
17
+ failure: import("../../index.ts").ClientFailure | null;
18
+ sessionEnded: string | null;
19
+ levelsRef: import("react").RefObject<{
20
+ input: number;
21
+ output: number;
22
+ }>;
23
+ isMuted: boolean;
24
+ isVideoOn: boolean;
25
+ sessionActive: boolean;
26
+ liveState: import("../../index.ts").LiveState;
27
+ activeTool: string | null;
28
+ status: import("../../index.ts").LiveSessionStatus;
29
+ textAvailable: boolean;
30
+ textDraft: string;
31
+ toolActive: boolean;
32
+ videoAvailable: boolean;
33
+ videoFacingMode: import("../../client/live/live-video.ts").LiveFacingMode;
34
+ videoPreview: HTMLVideoElement | null;
35
+ voiceAvailable: boolean;
36
+ canRestart: boolean;
37
+ gatePrompt: import("../../index.ts").LiveToolGatePrompt | null;
38
+ setTextDraft: import("react").Dispatch<import("react").SetStateAction<string>>;
39
+ handleEnd: () => void;
40
+ startCall: (options: {
41
+ video: boolean;
42
+ }) => void;
43
+ handleRestart: () => Promise<void>;
44
+ handleSendText: (text?: string) => void;
45
+ handleToggleMic: () => void;
46
+ handleFlipCamera: () => Promise<void>;
47
+ handleToggleVideo: () => Promise<void>;
48
+ resolveGateDecision: (resolution: import("../../index.ts").ToolGateResolution) => void;
49
+ };