@pipedog/core 0.1.0 → 0.2.0

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 (63) hide show
  1. package/dist/audio/resamplers/engine.d.ts +60 -0
  2. package/dist/audio/resamplers/engine.js +89 -0
  3. package/dist/audio/resamplers/sinc_engine.d.ts +10 -0
  4. package/dist/audio/resamplers/sinc_engine.js +235 -0
  5. package/dist/audio/resamplers/soxr_resampler.d.ts +10 -6
  6. package/dist/audio/resamplers/soxr_resampler.js +17 -7
  7. package/dist/audio/resamplers/soxr_stream_resampler.d.ts +9 -6
  8. package/dist/audio/resamplers/soxr_stream_resampler.js +24 -11
  9. package/dist/audio/turn/smart_turn/local_smart_turn_v3.js +16 -8
  10. package/dist/audio/vad/vad_analyzer.d.ts +11 -3
  11. package/dist/audio/vad/vad_analyzer.js +72 -34
  12. package/dist/pipeline/worker.d.ts +7 -0
  13. package/dist/pipeline/worker.js +40 -23
  14. package/dist/utils/file_storage.d.ts +37 -21
  15. package/dist/utils/file_storage.js +87 -9
  16. package/dist/utils/frame_queue.js +2 -2
  17. package/dist/utils/image.d.ts +0 -1
  18. package/dist/utils/image.js +37 -4
  19. package/dist/utils/jpeg_encoder.d.ts +14 -0
  20. package/dist/utils/jpeg_encoder.js +315 -0
  21. package/dist/utils/text/transforms/acronyms.d.ts +21 -0
  22. package/dist/utils/text/transforms/acronyms.js +31 -0
  23. package/dist/utils/text/transforms/currency.d.ts +16 -0
  24. package/dist/utils/text/transforms/currency.js +56 -0
  25. package/dist/utils/text/transforms/dates.d.ts +18 -0
  26. package/dist/utils/text/transforms/dates.js +102 -0
  27. package/dist/utils/text/transforms/email.d.ts +17 -0
  28. package/dist/utils/text/transforms/email.js +35 -0
  29. package/dist/utils/text/transforms/index.d.ts +37 -0
  30. package/dist/utils/text/transforms/index.js +42 -0
  31. package/dist/utils/text/transforms/numbers.d.ts +25 -0
  32. package/dist/utils/text/transforms/numbers.js +59 -0
  33. package/dist/utils/text/transforms/percentages.d.ts +16 -0
  34. package/dist/utils/text/transforms/percentages.js +32 -0
  35. package/dist/utils/text/transforms/phone.d.ts +21 -0
  36. package/dist/utils/text/transforms/phone.js +39 -0
  37. package/dist/utils/text/transforms/pronunciations.js +2 -1
  38. package/dist/utils/text/transforms/replacements.d.ts +39 -0
  39. package/dist/utils/text/transforms/replacements.js +46 -0
  40. package/dist/utils/text/transforms/strip_markdown.d.ts +25 -0
  41. package/dist/utils/text/transforms/strip_markdown.js +60 -0
  42. package/dist/utils/text/transforms/units.d.ts +22 -0
  43. package/dist/utils/text/transforms/units.js +81 -0
  44. package/dist/utils/text/transforms/voice_formatter.d.ts +86 -0
  45. package/dist/utils/text/transforms/voice_formatter.js +98 -0
  46. package/dist/utils/text/unicode_digits.d.ts +3 -0
  47. package/dist/utils/text/unicode_digits.js +34 -0
  48. package/dist/utils/tracing/service_decorators.js +2 -2
  49. package/dist/utils/tracing/setup.d.ts +18 -6
  50. package/dist/utils/tracing/setup.js +63 -13
  51. package/dist/utils/tracing/turn_trace_observer.d.ts +5 -0
  52. package/dist/utils/tracing/turn_trace_observer.js +18 -4
  53. package/dist/utils/yaml.d.ts +151 -36
  54. package/dist/utils/yaml.js +527 -12
  55. package/dist/version.d.ts +1 -1
  56. package/dist/version.js +1 -1
  57. package/dist/workers/proxy/index.d.ts +3 -0
  58. package/dist/workers/proxy/index.js +9 -0
  59. package/dist/workers/proxy/websocket/client.d.ts +110 -0
  60. package/dist/workers/proxy/websocket/client.js +196 -0
  61. package/dist/workers/proxy/websocket/index.d.ts +3 -0
  62. package/dist/workers/proxy/websocket/index.js +10 -0
  63. package/package.json +18 -3
@@ -0,0 +1,110 @@
1
+ /**
2
+ * WebSocket client proxy that forwards bus messages to a remote server.
3
+ *
4
+ * Porting notes: upstream connects with the `websockets` library; this port
5
+ * uses `websocketConnect` / `WebsocketClientConnection` from
6
+ * `services/websocket_service.ts`, the stand-in for its asyncio client.
7
+ */
8
+ import { type Task } from "@pipedog/asyncio";
9
+ import { type BusMessage } from "../../../bus/messages.ts";
10
+ import type { MessageSerializer } from "../../../bus/serializers/base.ts";
11
+ import { type WebsocketClientConnection } from "../../../services/websocket_service.ts";
12
+ import { BaseWorker, type BaseWorkerOptions } from "../../base_worker.ts";
13
+ type Dict = Record<string, unknown>;
14
+ /** A bus message class, as listed in `forwardMessages`. */
15
+ export type BusMessageType = abstract new (...args: any[]) => BusMessage;
16
+ export interface WebSocketProxyClientOptions extends Omit<BaseWorkerOptions, "name" | "active"> {
17
+ /** Unique name for this worker. */
18
+ name: string;
19
+ /** The WebSocket URL to connect to. */
20
+ url: string;
21
+ /**
22
+ * Name of the worker on the remote server. Only messages targeted at this
23
+ * worker are forwarded.
24
+ */
25
+ remoteWorkerName: string;
26
+ /**
27
+ * Name of the local worker that should receive responses. Only inbound
28
+ * messages targeted at this worker are accepted.
29
+ */
30
+ localWorkerName: string;
31
+ /**
32
+ * Additional message types to forward from the local worker (e.g.
33
+ * `[BusFrameMessage]` for frame routing). These are forwarded based on
34
+ * source worker name only, regardless of target.
35
+ */
36
+ forwardMessages?: readonly BusMessageType[];
37
+ /** Optional HTTP headers sent with the WebSocket handshake (e.g. for authentication). */
38
+ headers?: Record<string, string> | null;
39
+ /** Serializer for bus messages. Defaults to `JSONMessageSerializer`. */
40
+ serializer?: MessageSerializer | null;
41
+ /**
42
+ * Whether the worker starts active. Defaults to false because
43
+ * `onActivated` opens the WebSocket connection, which is almost always a
44
+ * deliberate action triggered by an upstream event (e.g. the local client
45
+ * connecting). Pass true to connect as soon as the worker starts.
46
+ */
47
+ active?: boolean;
48
+ }
49
+ /**
50
+ * Forwards bus messages to a remote worker over WebSocket.
51
+ *
52
+ * Connects to a WebSocket URL and forwards messages between a local
53
+ * worker and a remote worker. Only messages targeted at the remote worker
54
+ * are sent. Only messages targeted at the local worker are accepted.
55
+ *
56
+ * Event handlers available:
57
+ *
58
+ * - on_connected: Fired when the WebSocket connection is established.
59
+ * - on_disconnected: Fired when the WebSocket connection is closed.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * const proxy = new WebSocketProxyClient({
64
+ * name: "proxy",
65
+ * url: "ws://remote-server:8765/ws",
66
+ * remoteWorkerName: "worker",
67
+ * localWorkerName: "voice",
68
+ * });
69
+ *
70
+ * proxy.eventHandler("on_connected", async (worker, websocket) => {
71
+ * logger.info("Connected to remote server");
72
+ * });
73
+ *
74
+ * proxy.eventHandler("on_disconnected", async (worker, websocket) => {
75
+ * logger.info("Disconnected from remote server");
76
+ * });
77
+ *
78
+ * await runner.addWorkers(proxy);
79
+ * ```
80
+ */
81
+ export declare class WebSocketProxyClient extends BaseWorker {
82
+ protected _url: string;
83
+ protected _remoteWorkerName: string;
84
+ protected _localWorkerName: string;
85
+ protected _forwardMessages: readonly BusMessageType[];
86
+ protected _headers: Record<string, string>;
87
+ protected _serializer: MessageSerializer;
88
+ protected _ws: WebsocketClientConnection | null;
89
+ protected _receiveTask: Task<void> | null;
90
+ /** Initialize the WebSocketProxyClient. */
91
+ constructor(options: WebSocketProxyClientOptions);
92
+ /** Connect to the remote WebSocket server. */
93
+ onActivated(args: Dict | null): Promise<void>;
94
+ /** Cancel the receive loop and close the WebSocket connection. */
95
+ stop(): Promise<void>;
96
+ /**
97
+ * Forward messages targeted at the remote worker.
98
+ *
99
+ * @param message The bus message to process.
100
+ */
101
+ onBusMessage(message: BusMessage): Promise<void>;
102
+ /** Whether `message` is one of the `forwardMessages` types. */
103
+ protected _isForwardMessage(message: BusMessage): boolean;
104
+ /** Serialize and send a message over the WebSocket. */
105
+ protected _sendWs(message: BusMessage): Promise<void>;
106
+ /** Read messages from the WebSocket and put them on the local bus. */
107
+ protected _receiveLoop(): Promise<void>;
108
+ }
109
+ export {};
110
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1,196 @@
1
+ // Copyright (c) 2024-2026, Daily
2
+ // Copyright (c) 2026, pipedog contributors
3
+ // SPDX-License-Identifier: BSD-2-Clause
4
+ //
5
+ // Ported from pipecat: src/pipecat/workers/proxy/websocket/client.py
6
+ /**
7
+ * WebSocket client proxy that forwards bus messages to a remote server.
8
+ *
9
+ * Porting notes: upstream connects with the `websockets` library; this port
10
+ * uses `websocketConnect` / `WebsocketClientConnection` from
11
+ * `services/websocket_service.ts`, the stand-in for its asyncio client.
12
+ */
13
+ import { CancelledError, rethrowIfCancelled, sleep } from "@pipedog/asyncio";
14
+ import { BusLocalMessage, BusWorkerRegistryMessage, } from "../../../bus/messages.js";
15
+ import { JSONMessageSerializer } from "../../../bus/serializers/json.js";
16
+ import { ConnectionClosed, websocketConnect, } from "../../../services/websocket_service.js";
17
+ import { logger } from "../../../utils/logger.js";
18
+ import { BaseWorker } from "../../base_worker.js";
19
+ /**
20
+ * Forwards bus messages to a remote worker over WebSocket.
21
+ *
22
+ * Connects to a WebSocket URL and forwards messages between a local
23
+ * worker and a remote worker. Only messages targeted at the remote worker
24
+ * are sent. Only messages targeted at the local worker are accepted.
25
+ *
26
+ * Event handlers available:
27
+ *
28
+ * - on_connected: Fired when the WebSocket connection is established.
29
+ * - on_disconnected: Fired when the WebSocket connection is closed.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * const proxy = new WebSocketProxyClient({
34
+ * name: "proxy",
35
+ * url: "ws://remote-server:8765/ws",
36
+ * remoteWorkerName: "worker",
37
+ * localWorkerName: "voice",
38
+ * });
39
+ *
40
+ * proxy.eventHandler("on_connected", async (worker, websocket) => {
41
+ * logger.info("Connected to remote server");
42
+ * });
43
+ *
44
+ * proxy.eventHandler("on_disconnected", async (worker, websocket) => {
45
+ * logger.info("Disconnected from remote server");
46
+ * });
47
+ *
48
+ * await runner.addWorkers(proxy);
49
+ * ```
50
+ */
51
+ export class WebSocketProxyClient extends BaseWorker {
52
+ _url;
53
+ _remoteWorkerName;
54
+ _localWorkerName;
55
+ _forwardMessages;
56
+ _headers;
57
+ _serializer;
58
+ _ws = null;
59
+ _receiveTask = null;
60
+ /** Initialize the WebSocketProxyClient. */
61
+ constructor(options) {
62
+ super({ ...options, name: options.name, active: options.active ?? false });
63
+ this._url = options.url;
64
+ this._remoteWorkerName = options.remoteWorkerName;
65
+ this._localWorkerName = options.localWorkerName;
66
+ this._forwardMessages = options.forwardMessages ?? [];
67
+ this._headers = options.headers ?? {};
68
+ this._serializer = options.serializer ?? new JSONMessageSerializer();
69
+ this._registerEventHandler("on_connected");
70
+ this._registerEventHandler("on_disconnected");
71
+ }
72
+ /** Connect to the remote WebSocket server. */
73
+ async onActivated(args) {
74
+ await super.onActivated(args);
75
+ logger.debug(`Worker '${this}': connecting to ${this._url}`);
76
+ this._ws = await websocketConnect(this._url, { additionalHeaders: this._headers });
77
+ logger.debug(`Worker '${this}': connected to ${this._url}`);
78
+ await this._callEventHandler("on_connected", this._ws);
79
+ this._receiveTask = this.createTask(() => this._receiveLoop());
80
+ // Schedule worker right away.
81
+ await sleep(0);
82
+ }
83
+ /** Cancel the receive loop and close the WebSocket connection. */
84
+ async stop() {
85
+ if (this._receiveTask) {
86
+ await this.cancelTask(this._receiveTask);
87
+ this._receiveTask = null;
88
+ }
89
+ if (this._ws) {
90
+ await this._ws.close();
91
+ logger.debug(`Worker '${this}': WebSocket connection closed`);
92
+ this._ws = null;
93
+ }
94
+ await super.stop();
95
+ }
96
+ /**
97
+ * Forward messages targeted at the remote worker.
98
+ *
99
+ * @param message The bus message to process.
100
+ */
101
+ async onBusMessage(message) {
102
+ await super.onBusMessage(message);
103
+ if (!this._ws)
104
+ return;
105
+ if (message instanceof BusLocalMessage)
106
+ return;
107
+ // Forward targeted messages to the remote worker.
108
+ if (message.target === this._remoteWorkerName) {
109
+ await this._sendWs(message);
110
+ }
111
+ // Forward additional message types from the local worker.
112
+ else if (this._isForwardMessage(message)) {
113
+ if (message.source === this._localWorkerName) {
114
+ await this._sendWs(message);
115
+ }
116
+ }
117
+ }
118
+ /** Whether `message` is one of the `forwardMessages` types. */
119
+ _isForwardMessage(message) {
120
+ return this._forwardMessages.some((type) => message instanceof type);
121
+ }
122
+ /** Serialize and send a message over the WebSocket. */
123
+ async _sendWs(message) {
124
+ if (!this._ws)
125
+ return;
126
+ try {
127
+ const data = this._serializer.serialize(message);
128
+ await this._ws.send(data);
129
+ logger.trace(`Worker '${this}': sent ${message}`);
130
+ }
131
+ catch (e) {
132
+ if (!(e instanceof ConnectionClosed))
133
+ throw e;
134
+ logger.warning(`Worker '${this}': connection closed, stopping forwarding`);
135
+ const ws = this._ws;
136
+ this._ws = null;
137
+ await this._callEventHandler("on_disconnected", ws);
138
+ }
139
+ }
140
+ /** Read messages from the WebSocket and put them on the local bus. */
141
+ async _receiveLoop() {
142
+ if (this._ws === null) {
143
+ throw new Error("onActivated() must run before _receiveLoop");
144
+ }
145
+ const encoder = new TextEncoder();
146
+ try {
147
+ for await (const data of this._ws) {
148
+ try {
149
+ const payload = typeof data === "string" ? encoder.encode(data) : data;
150
+ const message = this._serializer.deserialize(payload);
151
+ if (!message)
152
+ continue;
153
+ // Accept registry messages (target=None) for worker discovery.
154
+ if (message instanceof BusWorkerRegistryMessage) {
155
+ logger.trace(`Worker '${this}': received registry from remote: ${JSON.stringify(message.workers)}`);
156
+ await this.sendBusMessage(message);
157
+ continue;
158
+ }
159
+ // Accept additional message types (e.g. BusFrameMessage).
160
+ if (this._forwardMessages.length > 0 && this._isForwardMessage(message)) {
161
+ logger.trace(`Worker '${this}': received ${message} from remote`);
162
+ await this.sendBusMessage(message);
163
+ continue;
164
+ }
165
+ // Only accept other messages targeted at the local worker.
166
+ if (message.target !== this._localWorkerName) {
167
+ logger.warning(`Worker '${this}': dropped inbound message with ` +
168
+ `unexpected target '${message.target}'`);
169
+ continue;
170
+ }
171
+ logger.trace(`Worker '${this}': received ${message} from remote`);
172
+ await this.sendBusMessage(message);
173
+ }
174
+ catch (e) {
175
+ rethrowIfCancelled(e);
176
+ logger.error(`Worker '${this}': failed to deserialize remote message`, e);
177
+ }
178
+ }
179
+ }
180
+ catch (e) {
181
+ if (e instanceof ConnectionClosed) {
182
+ logger.warning(`Worker '${this}': WebSocket connection closed`);
183
+ const ws = this._ws;
184
+ this._ws = null;
185
+ await this._callEventHandler("on_disconnected", ws);
186
+ }
187
+ else if (e instanceof CancelledError) {
188
+ // except asyncio.CancelledError: pass (upstream ends the loop quietly).
189
+ }
190
+ else {
191
+ throw e;
192
+ }
193
+ }
194
+ }
195
+ }
196
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1,3 @@
1
+ /** WebSocket proxy workers for forwarding bus messages. */
2
+ export { WebSocketProxyClient } from "./client.ts";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,10 @@
1
+ // Copyright (c) 2024-2026, Daily
2
+ // Copyright (c) 2026, pipedog contributors
3
+ // SPDX-License-Identifier: BSD-2-Clause
4
+ //
5
+ // Ported from pipecat: src/pipecat/workers/proxy/websocket/__init__.py
6
+ /** WebSocket proxy workers for forwarding bus messages. */
7
+ export { WebSocketProxyClient } from "./client.js";
8
+ // WebSocketProxyServer depends on a server framework (Starlette upstream), so it
9
+ // lives in its own package: import it from `@pipedog/worker-proxy`.
10
+ //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipedog/core",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Unofficial TypeScript port of the Pipecat core: frames, processors, pipelines, workers, observers, RTVI.",
5
5
  "license": "BSD-2-Clause",
6
6
  "repository": {
@@ -30,8 +30,23 @@
30
30
  "NOTICE"
31
31
  ],
32
32
  "dependencies": {
33
- "@pipedog/asyncio": "0.1.0",
34
- "@pipedog/sentencex-wasm": "0.1.0"
33
+ "@pipedog/asyncio": "0.2.0",
34
+ "@pipedog/resampler-wasm": "0.2.0",
35
+ "@pipedog/sentencex-wasm": "0.2.0",
36
+ "num2words-ts": "1.0.2",
37
+ "yaml": "2.9.1"
38
+ },
39
+ "peerDependencies": {
40
+ "@opentelemetry/api": "^1.3.0"
41
+ },
42
+ "peerDependenciesMeta": {
43
+ "@opentelemetry/api": {
44
+ "optional": true
45
+ }
46
+ },
47
+ "devDependencies": {
48
+ "@opentelemetry/api": "1.9.1",
49
+ "@opentelemetry/sdk-trace-base": "2.11.0"
35
50
  },
36
51
  "pipecat": {
37
52
  "runtimes": [