@datalayer/agent-runtimes 1.3.62 → 1.3.64

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 (64) hide show
  1. package/lib/chat/ChatFloating.d.ts +9 -1
  2. package/lib/chat/ChatFloating.js +69 -18
  3. package/lib/chat/assistant/AssistantStage.d.ts +14 -1
  4. package/lib/chat/assistant/AssistantStage.js +53 -1
  5. package/lib/chat/assistant/SpriteCharacter.js +1 -1
  6. package/lib/chat/assistant/characters.js +1 -5
  7. package/lib/chat/assistant/state.d.ts +7 -1
  8. package/lib/chat/assistant/state.js +3 -2
  9. package/lib/chat/base/ChatBase.js +32 -4
  10. package/lib/chat/messages/ChatMessageList.d.ts +0 -6
  11. package/lib/chat/messages/ChatMessageList.js +8 -2
  12. package/lib/config/AgentConfiguration.js +0 -6
  13. package/lib/examples/AgentA2ATeamExample.js +19 -2
  14. package/lib/examples/ChatAssistantExample.d.ts +3 -1
  15. package/lib/examples/ChatAssistantExample.js +75 -7
  16. package/lib/examples/ChatAssistantGalleryExample.d.ts +3 -2
  17. package/lib/examples/ChatAssistantGalleryExample.js +11 -6
  18. package/lib/examples/DecksAgent.js +4 -2
  19. package/lib/examples/LoopShellExample.js +4 -2
  20. package/lib/examples/VoiceChatExample.d.ts +20 -0
  21. package/lib/examples/VoiceChatExample.js +64 -0
  22. package/lib/examples/example-selector.js +1 -0
  23. package/lib/examples/main.js +12 -7
  24. package/lib/examples/utils/clippyJsCharacters.d.ts +18 -0
  25. package/lib/examples/utils/clippyJsCharacters.js +129 -0
  26. package/lib/loop/apps/appspec.d.ts +3 -1
  27. package/lib/loop/apps/appspec.js +31 -0
  28. package/lib/loop/apps/checks.js +1 -1
  29. package/lib/protocols/VercelAIAdapter.js +5 -0
  30. package/lib/specs/apps.js +112 -0
  31. package/lib/specs/appspecSchema.js +65 -0
  32. package/lib/specs/index.d.ts +1 -0
  33. package/lib/specs/index.js +1 -0
  34. package/lib/specs/voices.d.ts +72 -0
  35. package/lib/specs/voices.js +344 -0
  36. package/lib/types/agents.d.ts +1 -1
  37. package/lib/types/agentspecs.d.ts +16 -0
  38. package/lib/types/chat.d.ts +11 -0
  39. package/lib/voice/VoiceInput.d.ts +35 -0
  40. package/lib/voice/VoiceInput.js +233 -0
  41. package/lib/voice/capture.d.ts +30 -0
  42. package/lib/voice/capture.js +113 -0
  43. package/lib/voice/consent.d.ts +6 -0
  44. package/lib/voice/consent.js +34 -0
  45. package/lib/voice/hearing.d.ts +37 -0
  46. package/lib/voice/hearing.js +168 -0
  47. package/lib/voice/index.d.ts +47 -0
  48. package/lib/voice/index.js +13 -0
  49. package/lib/voice/pinned.d.ts +28 -0
  50. package/lib/voice/pinned.js +75 -0
  51. package/lib/voice/sentences.d.ts +26 -0
  52. package/lib/voice/sentences.js +71 -0
  53. package/lib/voice/speaker.d.ts +66 -0
  54. package/lib/voice/speaker.js +168 -0
  55. package/lib/voice/types.d.ts +92 -0
  56. package/lib/voice/types.js +5 -0
  57. package/lib/voice/useSpokenAnswers.d.ts +12 -0
  58. package/lib/voice/useSpokenAnswers.js +90 -0
  59. package/package.json +7 -3
  60. package/scripts/codegen/generate_voices.py +279 -0
  61. package/scripts/voice/measure.py +244 -0
  62. package/scripts/voice/pin_store.py +159 -0
  63. package/scripts/voice/serve_store.py +70 -0
  64. package/scripts/voice/transcribe.mjs +58 -0
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env python3
2
+ # Copyright (c) 2025-2026 Datalayer, Inc.
3
+ # Distributed under the terms of the Modified BSD License.
4
+
5
+ """Serve the pinned store to a page on this machine, as Datalayer's origin serves it (VOICE.md VO-49).
6
+
7
+ python scripts/voice/serve_store.py --store ~/.cache/speech-store [--port 8770]
8
+
9
+ The browser's models at ``/<model id>/<path>`` and onnxruntime-web's own
10
+ files at ``/onnxruntime-web/<version>/``, from the onnxruntime-web the page
11
+ bundles (``--node-modules`` when it is not this checkout's), with the CORS
12
+ headers a page on another port needs. For a local run only: in production
13
+ the same layout is on Datalayer's storage.
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import argparse
19
+ import functools
20
+ import json
21
+ from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
22
+ from pathlib import Path
23
+
24
+ ROOT = Path(__file__).resolve().parents[2]
25
+
26
+
27
+ class StoreHandler(SimpleHTTPRequestHandler):
28
+ runtime: Path = Path()
29
+ version: str = ""
30
+
31
+ def translate_path(self, path: str) -> str:
32
+ prefix = f"/onnxruntime-web/{self.version}/"
33
+ if path.startswith(prefix):
34
+ return str(self.runtime / path[len(prefix) :].split("?")[0])
35
+ return super().translate_path(path)
36
+
37
+ def end_headers(self) -> None:
38
+ self.send_header("Access-Control-Allow-Origin", "*")
39
+ self.send_header("Cross-Origin-Resource-Policy", "cross-origin")
40
+ super().end_headers()
41
+
42
+ def log_message(self, format: str, *args: object) -> None: # noqa: A002
43
+ pass
44
+
45
+
46
+ def main() -> int:
47
+ parser = argparse.ArgumentParser(description=__doc__.split("\n\n")[0])
48
+ parser.add_argument("--store", type=Path, required=True)
49
+ parser.add_argument("--port", type=int, default=8770)
50
+ parser.add_argument(
51
+ "--node-modules", type=Path, default=ROOT.parent.parent / "node_modules"
52
+ )
53
+ args = parser.parse_args()
54
+ runtime = args.node_modules / "onnxruntime-web"
55
+ if not (runtime / "package.json").is_file():
56
+ raise SystemExit(
57
+ f"No onnxruntime-web in {args.node_modules}: install the voice packages first."
58
+ )
59
+ StoreHandler.runtime = runtime / "dist"
60
+ StoreHandler.version = json.loads((runtime / "package.json").read_text())["version"]
61
+ handler = functools.partial(StoreHandler, directory=str(args.store))
62
+ print(
63
+ f"http://127.0.0.1:{args.port}/ serves {args.store} and onnxruntime-web {StoreHandler.version}"
64
+ )
65
+ ThreadingHTTPServer(("127.0.0.1", args.port), handler).serve_forever()
66
+ return 0
67
+
68
+
69
+ if __name__ == "__main__":
70
+ raise SystemExit(main())
@@ -0,0 +1,58 @@
1
+ /*
2
+ * Copyright (c) 2025-2026 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+
6
+ /**
7
+ * Transcribe WAV files with a speech-to-text model of the catalogue, as the
8
+ * browser runs it: transformers.js, the same ONNX files, read from the
9
+ * pinned store (VOICE.md VO-05, VO-51). Prints one JSON line.
10
+ *
11
+ * node scripts/voice/transcribe.mjs <store> <model id> <language> <file.wav>...
12
+ *
13
+ * In Node the runtime is onnxruntime-node on the CPU, not the browser's
14
+ * WASM: the words are the model's, the timings are not the browser's.
15
+ */
16
+
17
+ import { readFileSync } from 'node:fs';
18
+ import { env, pipeline } from '@huggingface/transformers';
19
+
20
+ const [, , store, model, language, ...files] = process.argv;
21
+ env.allowRemoteModels = false;
22
+ env.localModelPath = store.endsWith('/') ? store : `${store}/`;
23
+
24
+ /** A 16-bit PCM mono WAV, as samples between -1 and 1. */
25
+ function readWav(path) {
26
+ const bytes = readFileSync(path);
27
+ const at = bytes.indexOf('data') + 8;
28
+ const count = (bytes.length - at) / 2;
29
+ const samples = new Float32Array(count);
30
+ for (let index = 0; index < count; index += 1) {
31
+ samples[index] = bytes.readInt16LE(at + 2 * index) / 32768;
32
+ }
33
+ return samples;
34
+ }
35
+
36
+ const loading = performance.now();
37
+ const transcribe = await pipeline('automatic-speech-recognition', model, {
38
+ dtype: 'q8',
39
+ device: 'cpu',
40
+ });
41
+ const loadMs = Math.round(performance.now() - loading);
42
+ // Whisper is told the language; Moonshine hears English only.
43
+ const options = model.startsWith('whisper')
44
+ ? { language: language === 'fr' ? 'french' : 'english', task: 'transcribe' }
45
+ : {};
46
+ const results = [];
47
+ for (const file of files) {
48
+ const audio = readWav(file);
49
+ const started = performance.now();
50
+ const output = await transcribe(audio, options);
51
+ results.push({
52
+ file: file.split('/').pop(),
53
+ text: output.text.trim(),
54
+ ms: Math.round(performance.now() - started),
55
+ audio_s: Math.round((audio.length / 16000) * 100) / 100,
56
+ });
57
+ }
58
+ console.log(JSON.stringify({ model, language, load_ms: loadMs, results }));