klentyboopathi commited on
Commit
8362005
·
1 Parent(s): e84bd43

Intital commit

Browse files
.gitignore ADDED
@@ -0,0 +1,221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Environment variables
2
+ .env
3
+
4
+ node_modules/
5
+ assets/
6
+
7
+ # Python
8
+ __pycache__/
9
+ *.pyc
10
+ *.pyo
11
+ *.pyd
12
+ .Python
13
+ env/
14
+ venv/
15
+ ENV/
16
+ venv.bak/
17
+ venv.cfg
18
+
19
+ # IDE
20
+ .vscode/
21
+ .idea/
22
+
23
+ # Byte-compiled / optimized / DLL files
24
+ __pycache__/
25
+ *.py[cod]
26
+ *$py.class
27
+
28
+ # C extensions
29
+ *.so
30
+
31
+ # Distribution / packaging
32
+ .Python
33
+ build/
34
+ develop-eggs/
35
+ dist/
36
+ downloads/
37
+ eggs/
38
+ .eggs/
39
+ lib/
40
+ lib64/
41
+ parts/
42
+ sdist/
43
+ var/
44
+ wheels/
45
+ share/python-wheels/
46
+ *.egg-info/
47
+ .installed.cfg
48
+ *.egg
49
+ MANIFEST
50
+
51
+ # PyInstaller
52
+ # Usually these files are written by a python script from a template
53
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
54
+ *.manifest
55
+ *.spec
56
+
57
+ # Installer logs
58
+ pip-log.txt
59
+ pip-delete-this-directory.txt
60
+
61
+ # Unit test / coverage reports
62
+ htmlcov/
63
+ .tox/
64
+ .nox/
65
+ .coverage
66
+ .coverage.*
67
+ .cache
68
+ nosetests.xml
69
+ coverage.xml
70
+ *.cover
71
+ *.py,cover
72
+ .hypothesis/
73
+ .pytest_cache/
74
+ cover/
75
+
76
+ # Translations
77
+ *.mo
78
+ *.pot
79
+
80
+ # Django stuff:
81
+ *.log
82
+ local_settings.py
83
+ db.sqlite3
84
+ db.sqlite3-journal
85
+
86
+ # Flask stuff:
87
+ instance/
88
+ .webassets-cache
89
+
90
+ # Scrapy stuff:
91
+ .scrapy
92
+
93
+ # Sphinx documentation
94
+ docs/_build/
95
+
96
+ # PyBuilder
97
+ .pybuilder/
98
+ target/
99
+
100
+ # Jupyter Notebook
101
+ .ipynb_checkpoints
102
+
103
+ # IPython
104
+ profile_default/
105
+ ipython_config.py
106
+
107
+ # pyenv
108
+ # For a library or package, you might want to ignore these files since the code is
109
+ # intended to run in multiple environments; otherwise, check them in:
110
+ # .python-version
111
+
112
+ # pipenv
113
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
114
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
115
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
116
+ # install all needed dependencies.
117
+ #Pipfile.lock
118
+
119
+ # UV
120
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
121
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
122
+ # commonly ignored for libraries.
123
+ #uv.lock
124
+
125
+ # poetry
126
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
127
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
128
+ # commonly ignored for libraries.
129
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
130
+ #poetry.lock
131
+
132
+ # pdm
133
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
134
+ #pdm.lock
135
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
136
+ # in version control.
137
+ # https://pdm.fming.dev/latest/usage/project/#working-with-version-control
138
+ .pdm.toml
139
+ .pdm-python
140
+ .pdm-build/
141
+
142
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
143
+ __pypackages__/
144
+
145
+ # Celery stuff
146
+ celerybeat-schedule
147
+ celerybeat.pid
148
+
149
+ # SageMath parsed files
150
+ *.sage.py
151
+
152
+ # Environments
153
+ .env
154
+ .venv
155
+ env/
156
+ venv/
157
+ ENV/
158
+ env.bak/
159
+ venv.bak/
160
+ venv.cfg
161
+
162
+ # Spyder project settings
163
+ .spyderproject
164
+ .spyproject
165
+
166
+ # Rope project settings
167
+ .ropeproject
168
+
169
+ # mkdocs documentation
170
+ /site
171
+
172
+ # mypy
173
+ .mypy_cache/
174
+ .dmypy.json
175
+ dmypy.json
176
+
177
+ # Pyre type checker
178
+ .pyre/
179
+
180
+ # pytype static type analyzer
181
+ .pytype/
182
+
183
+ # Cython debug symbols
184
+ cython_debug/
185
+
186
+ # PyCharm
187
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
188
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
189
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
190
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
191
+ #.idea/
192
+
193
+ # Abstra
194
+ # Abstra is an AI-powered process automation framework.
195
+ # Ignore directories containing user credentials, local state, and settings.
196
+ # Learn more at https://abstra.io/docs
197
+ .abstra/
198
+
199
+ # Visual Studio Code
200
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
201
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
202
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
203
+ # you could uncomment the following to ignore the enitre vscode folder
204
+ # .vscode/
205
+
206
+ # Ruff stuff:
207
+ .ruff_cache/
208
+
209
+ # PyPI configuration file
210
+ .pypirc
211
+
212
+ # Cursor
213
+ # Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
214
+ # exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
215
+ # refer to https://docs.cursor.com/context/ignore-files
216
+ .cursorignore
217
+ .cursorindexingignore
218
+
219
+ # IDE
220
+ .vscode/
221
+ .idea/
Dockerfile ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ # Stage 2: Create the final application image
4
+ FROM python:3.11-slim
5
+ WORKDIR /app
6
+
7
+ # Install Python dependencies
8
+ COPY requirements.txt .
9
+ RUN pip install --no-cache-dir -r requirements.txt
10
+
11
+ # Copy the backend code
12
+ COPY . .
13
+
14
+ # Expose the port the app runs on
15
+ EXPOSE 7860
16
+
17
+ # Run the application
18
+ CMD ["uvicorn", "server:app", "--host", "0.0.0.0", "--port", "7860"]
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2025 K.Boopathi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
__init__.py ADDED
File without changes
bot/__iniit__.py ADDED
File without changes
bot/bot_websocket_server.py ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ from loguru import logger
4
+
5
+ from pipecat.audio.vad.silero import SileroVADAnalyzer
6
+ from pipecat.pipeline.pipeline import Pipeline
7
+ from pipecat.pipeline.runner import PipelineRunner
8
+ from pipecat.pipeline.task import PipelineParams, PipelineTask
9
+ from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext
10
+
11
+ from pipecat.services.ollama.llm import OLLamaLLMService
12
+
13
+ # from pipecat.services.fish.tts import FishAudioTTSService
14
+ from pipecat.services.xtts.tts import XTTSService
15
+ from pipecat.transcriptions.language import Language
16
+
17
+
18
+ from pipecat.processors.frameworks.rtvi import RTVIConfig, RTVIObserver, RTVIProcessor
19
+ from pipecat.serializers.protobuf import ProtobufFrameSerializer
20
+ from pipecat.services.whisper.stt import WhisperSTTService
21
+ from pipecat.transports.network.websocket_server import (
22
+ WebsocketServerParams,
23
+ WebsocketServerTransport,
24
+ )
25
+ import aiohttp
26
+
27
+ from service.Kokoro.tts import KokoroTTSService
28
+ from service.orpheus.tts import OrpheusTTSService
29
+ # from service.chatterbot.tts import ChatterboxTTSService
30
+
31
+ SYSTEM_INSTRUCTION = f"""
32
+ "You are Gemini Chatbot, a friendly, helpful robot.
33
+
34
+ Your goal is to demonstrate your capabilities in a succinct way.
35
+
36
+ Your output will be converted to audio so don't include special characters in your answers.
37
+
38
+ Respond to what the user said in a creative and helpful way. Keep your responses brief. One or two sentences at most.
39
+ """
40
+
41
+
42
+ async def run_bot_websocket_server():
43
+ ws_transport = WebsocketServerTransport(
44
+ params=WebsocketServerParams(
45
+ serializer=ProtobufFrameSerializer(),
46
+ audio_in_enabled=True,
47
+ audio_out_enabled=True,
48
+ add_wav_header=False,
49
+ vad_analyzer=SileroVADAnalyzer(),
50
+ session_timeout=60 * 3, # 3 minutes
51
+ )
52
+ )
53
+
54
+ stt = WhisperSTTService(
55
+ model="tiny",
56
+ device="cpu",
57
+ compute_type="default",
58
+ language="en",
59
+ )
60
+
61
+ llm = OLLamaLLMService(
62
+ model="smollm:latest",
63
+ # params=OLLamaLLMService.InputParams(temperature=0.7, max_tokens=1000),
64
+ )
65
+
66
+ # TTS = FishAudioTTSService(
67
+ # api_key=os.getenv("CARTESIA_API_KEY"),
68
+ # voice_id="79a125e8-cd45-4c13-8a67-188112f4dd22", # British Reading Lady
69
+ # )
70
+ # async with aiohttp.ClientSession() as session:
71
+ # TTS = XTTSService(
72
+ # voice_id="speaker_1",
73
+ # language=Language.EN,
74
+ # base_url="http://localhost:8000",
75
+ # aiohttp_session=session
76
+ # )
77
+
78
+ context = OpenAILLMContext(
79
+ [
80
+ {
81
+ "role": "system",
82
+ "content": SYSTEM_INSTRUCTION,
83
+ },
84
+ {
85
+ "role": "user",
86
+ "content": "Start by greeting the user warmly and introducing yourself.",
87
+ },
88
+ ],
89
+ )
90
+ context_aggregator = llm.create_context_aggregator(context)
91
+
92
+ # RTVI events for Pipecat client UI
93
+ rtvi = RTVIProcessor(config=RTVIConfig(config=[]))
94
+
95
+ TTS = KokoroTTSService(
96
+ model_path=os.path.join(
97
+ os.path.dirname(__file__), "assets", "kokoro-v1.0.int8.onnx"
98
+ ),
99
+ voices_path=os.path.join(os.path.dirname(__file__), "assets", "voices.json"),
100
+ voice_id="af",
101
+ sample_rate=16000,
102
+ )
103
+
104
+ # TTS = OrpheusTTSService(
105
+ # model_name="canopylabs/orpheus-3b-0.1-ft",
106
+ # sample_rate=16000,
107
+ # )
108
+
109
+ # TTS = ChatterboxTTSService(
110
+ # model_name="",
111
+ # sample_rate=16000,
112
+ # )
113
+ pipeline = Pipeline(
114
+ [
115
+ ws_transport.input(),
116
+ rtvi,
117
+ stt, # STT
118
+ context_aggregator.user(),
119
+ llm,
120
+ TTS, # TTS
121
+ ws_transport.output(),
122
+ context_aggregator.assistant(),
123
+ ]
124
+ )
125
+
126
+ task = PipelineTask(
127
+ pipeline,
128
+ params=PipelineParams(
129
+ enable_metrics=True,
130
+ enable_usage_metrics=True,
131
+ ),
132
+ observers=[RTVIObserver(rtvi)],
133
+ )
134
+
135
+ @rtvi.event_handler("on_client_ready")
136
+ async def on_client_ready(rtvi):
137
+ logger.info("Pipecat client ready.")
138
+ await rtvi.set_bot_ready()
139
+ # Kick off the conversation.
140
+ await task.queue_frames([context_aggregator.user().get_context_frame()])
141
+
142
+ @ws_transport.event_handler("on_client_connected")
143
+ async def on_client_connected(transport, client):
144
+ logger.info("Pipecat Client connected")
145
+
146
+ @ws_transport.event_handler("on_client_disconnected")
147
+ async def on_client_disconnected(transport, client):
148
+ logger.info("Pipecat Client disconnected")
149
+ await task.cancel()
150
+
151
+ @ws_transport.event_handler("on_session_timeout")
152
+ async def on_session_timeout(transport, client):
153
+ logger.info(f"Entering in timeout for {client.remote_address}")
154
+ await task.cancel()
155
+
156
+ runner = PipelineRunner()
157
+
158
+ await runner.run(task)
client/.gitingore ADDED
@@ -0,0 +1 @@
 
 
1
+ node_modules/
client/README.md ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # JavaScript Implementation
2
+
3
+ Basic implementation using the [Pipecat JavaScript SDK](https://docs.pipecat.ai/client/js/introduction).
4
+
5
+ ## Setup
6
+
7
+ 1. Run the bot server. See the [server README](../README).
8
+
9
+ 2. Navigate to the `client/javascript` directory:
10
+
11
+ ```bash
12
+ cd client/javascript
13
+ ```
14
+
15
+ 3. Install dependencies:
16
+
17
+ ```bash
18
+ npm install
19
+ ```
20
+
21
+ 4. Run the client app:
22
+
23
+ ```
24
+ npm run dev
25
+ ```
26
+
27
+ 5. Visit http://localhost:5173 in your browser.
client/index.html ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>AI Chatbot</title>
8
+ </head>
9
+
10
+ <body>
11
+ <div class="container">
12
+ <div class="status-bar">
13
+ <div class="status">
14
+ Transport: <span id="connection-status">Disconnected</span>
15
+ </div>
16
+ <div class="controls">
17
+ <button id="connect-btn">Connect</button>
18
+ <button id="disconnect-btn" disabled>Disconnect</button>
19
+ </div>
20
+ </div>
21
+
22
+ <audio id="bot-audio" autoplay></audio>
23
+
24
+ <div class="debug-panel">
25
+ <h3>Debug Info</h3>
26
+ <div id="debug-log"></div>
27
+ </div>
28
+ </div>
29
+
30
+ <script type="module" src="/src/app.ts"></script>
31
+ <link rel="stylesheet" href="/src/style.css">
32
+ </body>
33
+
34
+ </html>
client/package-lock.json ADDED
@@ -0,0 +1,1780 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "client",
3
+ "version": "1.0.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "client",
9
+ "version": "1.0.0",
10
+ "license": "ISC",
11
+ "dependencies": {
12
+ "@pipecat-ai/client-js": "^0.4.0",
13
+ "@pipecat-ai/websocket-transport": "^0.4.2",
14
+ "protobufjs": "^7.4.0"
15
+ },
16
+ "devDependencies": {
17
+ "@types/node": "^22.15.30",
18
+ "@types/protobufjs": "^6.0.0",
19
+ "@vitejs/plugin-react-swc": "^3.10.1",
20
+ "typescript": "^5.8.3",
21
+ "vite": "^6.3.5"
22
+ }
23
+ },
24
+ "node_modules/@babel/runtime": {
25
+ "version": "7.27.6",
26
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz",
27
+ "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==",
28
+ "license": "MIT",
29
+ "engines": {
30
+ "node": ">=6.9.0"
31
+ }
32
+ },
33
+ "node_modules/@bufbuild/protobuf": {
34
+ "version": "2.5.2",
35
+ "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.5.2.tgz",
36
+ "integrity": "sha512-foZ7qr0IsUBjzWIq+SuBLfdQCpJ1j8cTuNNT4owngTHoN5KsJb8L9t65fzz7SCeSWzescoOil/0ldqiL041ABg==",
37
+ "license": "(Apache-2.0 AND BSD-3-Clause)"
38
+ },
39
+ "node_modules/@bufbuild/protoplugin": {
40
+ "version": "2.5.2",
41
+ "resolved": "https://registry.npmjs.org/@bufbuild/protoplugin/-/protoplugin-2.5.2.tgz",
42
+ "integrity": "sha512-7d/NUae/ugs/qgHEYOwkVWGDE3Bf/xjuGviVFs38+MLRdwiHNTiuvzPVwuIPo/1wuZCZn3Nax1cg1owLuY72xw==",
43
+ "license": "Apache-2.0",
44
+ "dependencies": {
45
+ "@bufbuild/protobuf": "2.5.2",
46
+ "@typescript/vfs": "^1.5.2",
47
+ "typescript": "5.4.5"
48
+ }
49
+ },
50
+ "node_modules/@bufbuild/protoplugin/node_modules/typescript": {
51
+ "version": "5.4.5",
52
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
53
+ "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
54
+ "license": "Apache-2.0",
55
+ "bin": {
56
+ "tsc": "bin/tsc",
57
+ "tsserver": "bin/tsserver"
58
+ },
59
+ "engines": {
60
+ "node": ">=14.17"
61
+ }
62
+ },
63
+ "node_modules/@daily-co/daily-js": {
64
+ "version": "0.79.0",
65
+ "resolved": "https://registry.npmjs.org/@daily-co/daily-js/-/daily-js-0.79.0.tgz",
66
+ "integrity": "sha512-Ii/Zi6cfTl2EZBpX8msRPNkkCHcajA+ErXpbN2Xe2KySd1Nb4IzC/QWJlSl9VA9pIlYPQicRTDoZnoym/0uEAw==",
67
+ "license": "BSD-2-Clause",
68
+ "dependencies": {
69
+ "@babel/runtime": "^7.12.5",
70
+ "@sentry/browser": "^8.33.1",
71
+ "bowser": "^2.8.1",
72
+ "dequal": "^2.0.3",
73
+ "events": "^3.1.0"
74
+ },
75
+ "engines": {
76
+ "node": ">=10.0.0"
77
+ }
78
+ },
79
+ "node_modules/@esbuild/aix-ppc64": {
80
+ "version": "0.25.5",
81
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz",
82
+ "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==",
83
+ "cpu": [
84
+ "ppc64"
85
+ ],
86
+ "dev": true,
87
+ "license": "MIT",
88
+ "optional": true,
89
+ "os": [
90
+ "aix"
91
+ ],
92
+ "engines": {
93
+ "node": ">=18"
94
+ }
95
+ },
96
+ "node_modules/@esbuild/android-arm": {
97
+ "version": "0.25.5",
98
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz",
99
+ "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==",
100
+ "cpu": [
101
+ "arm"
102
+ ],
103
+ "dev": true,
104
+ "license": "MIT",
105
+ "optional": true,
106
+ "os": [
107
+ "android"
108
+ ],
109
+ "engines": {
110
+ "node": ">=18"
111
+ }
112
+ },
113
+ "node_modules/@esbuild/android-arm64": {
114
+ "version": "0.25.5",
115
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz",
116
+ "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==",
117
+ "cpu": [
118
+ "arm64"
119
+ ],
120
+ "dev": true,
121
+ "license": "MIT",
122
+ "optional": true,
123
+ "os": [
124
+ "android"
125
+ ],
126
+ "engines": {
127
+ "node": ">=18"
128
+ }
129
+ },
130
+ "node_modules/@esbuild/android-x64": {
131
+ "version": "0.25.5",
132
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz",
133
+ "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==",
134
+ "cpu": [
135
+ "x64"
136
+ ],
137
+ "dev": true,
138
+ "license": "MIT",
139
+ "optional": true,
140
+ "os": [
141
+ "android"
142
+ ],
143
+ "engines": {
144
+ "node": ">=18"
145
+ }
146
+ },
147
+ "node_modules/@esbuild/darwin-arm64": {
148
+ "version": "0.25.5",
149
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz",
150
+ "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==",
151
+ "cpu": [
152
+ "arm64"
153
+ ],
154
+ "dev": true,
155
+ "license": "MIT",
156
+ "optional": true,
157
+ "os": [
158
+ "darwin"
159
+ ],
160
+ "engines": {
161
+ "node": ">=18"
162
+ }
163
+ },
164
+ "node_modules/@esbuild/darwin-x64": {
165
+ "version": "0.25.5",
166
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz",
167
+ "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==",
168
+ "cpu": [
169
+ "x64"
170
+ ],
171
+ "dev": true,
172
+ "license": "MIT",
173
+ "optional": true,
174
+ "os": [
175
+ "darwin"
176
+ ],
177
+ "engines": {
178
+ "node": ">=18"
179
+ }
180
+ },
181
+ "node_modules/@esbuild/freebsd-arm64": {
182
+ "version": "0.25.5",
183
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz",
184
+ "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==",
185
+ "cpu": [
186
+ "arm64"
187
+ ],
188
+ "dev": true,
189
+ "license": "MIT",
190
+ "optional": true,
191
+ "os": [
192
+ "freebsd"
193
+ ],
194
+ "engines": {
195
+ "node": ">=18"
196
+ }
197
+ },
198
+ "node_modules/@esbuild/freebsd-x64": {
199
+ "version": "0.25.5",
200
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz",
201
+ "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==",
202
+ "cpu": [
203
+ "x64"
204
+ ],
205
+ "dev": true,
206
+ "license": "MIT",
207
+ "optional": true,
208
+ "os": [
209
+ "freebsd"
210
+ ],
211
+ "engines": {
212
+ "node": ">=18"
213
+ }
214
+ },
215
+ "node_modules/@esbuild/linux-arm": {
216
+ "version": "0.25.5",
217
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz",
218
+ "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==",
219
+ "cpu": [
220
+ "arm"
221
+ ],
222
+ "dev": true,
223
+ "license": "MIT",
224
+ "optional": true,
225
+ "os": [
226
+ "linux"
227
+ ],
228
+ "engines": {
229
+ "node": ">=18"
230
+ }
231
+ },
232
+ "node_modules/@esbuild/linux-arm64": {
233
+ "version": "0.25.5",
234
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz",
235
+ "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==",
236
+ "cpu": [
237
+ "arm64"
238
+ ],
239
+ "dev": true,
240
+ "license": "MIT",
241
+ "optional": true,
242
+ "os": [
243
+ "linux"
244
+ ],
245
+ "engines": {
246
+ "node": ">=18"
247
+ }
248
+ },
249
+ "node_modules/@esbuild/linux-ia32": {
250
+ "version": "0.25.5",
251
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz",
252
+ "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==",
253
+ "cpu": [
254
+ "ia32"
255
+ ],
256
+ "dev": true,
257
+ "license": "MIT",
258
+ "optional": true,
259
+ "os": [
260
+ "linux"
261
+ ],
262
+ "engines": {
263
+ "node": ">=18"
264
+ }
265
+ },
266
+ "node_modules/@esbuild/linux-loong64": {
267
+ "version": "0.25.5",
268
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz",
269
+ "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==",
270
+ "cpu": [
271
+ "loong64"
272
+ ],
273
+ "dev": true,
274
+ "license": "MIT",
275
+ "optional": true,
276
+ "os": [
277
+ "linux"
278
+ ],
279
+ "engines": {
280
+ "node": ">=18"
281
+ }
282
+ },
283
+ "node_modules/@esbuild/linux-mips64el": {
284
+ "version": "0.25.5",
285
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz",
286
+ "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==",
287
+ "cpu": [
288
+ "mips64el"
289
+ ],
290
+ "dev": true,
291
+ "license": "MIT",
292
+ "optional": true,
293
+ "os": [
294
+ "linux"
295
+ ],
296
+ "engines": {
297
+ "node": ">=18"
298
+ }
299
+ },
300
+ "node_modules/@esbuild/linux-ppc64": {
301
+ "version": "0.25.5",
302
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz",
303
+ "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==",
304
+ "cpu": [
305
+ "ppc64"
306
+ ],
307
+ "dev": true,
308
+ "license": "MIT",
309
+ "optional": true,
310
+ "os": [
311
+ "linux"
312
+ ],
313
+ "engines": {
314
+ "node": ">=18"
315
+ }
316
+ },
317
+ "node_modules/@esbuild/linux-riscv64": {
318
+ "version": "0.25.5",
319
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz",
320
+ "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==",
321
+ "cpu": [
322
+ "riscv64"
323
+ ],
324
+ "dev": true,
325
+ "license": "MIT",
326
+ "optional": true,
327
+ "os": [
328
+ "linux"
329
+ ],
330
+ "engines": {
331
+ "node": ">=18"
332
+ }
333
+ },
334
+ "node_modules/@esbuild/linux-s390x": {
335
+ "version": "0.25.5",
336
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz",
337
+ "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==",
338
+ "cpu": [
339
+ "s390x"
340
+ ],
341
+ "dev": true,
342
+ "license": "MIT",
343
+ "optional": true,
344
+ "os": [
345
+ "linux"
346
+ ],
347
+ "engines": {
348
+ "node": ">=18"
349
+ }
350
+ },
351
+ "node_modules/@esbuild/linux-x64": {
352
+ "version": "0.25.5",
353
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz",
354
+ "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==",
355
+ "cpu": [
356
+ "x64"
357
+ ],
358
+ "dev": true,
359
+ "license": "MIT",
360
+ "optional": true,
361
+ "os": [
362
+ "linux"
363
+ ],
364
+ "engines": {
365
+ "node": ">=18"
366
+ }
367
+ },
368
+ "node_modules/@esbuild/netbsd-arm64": {
369
+ "version": "0.25.5",
370
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz",
371
+ "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==",
372
+ "cpu": [
373
+ "arm64"
374
+ ],
375
+ "dev": true,
376
+ "license": "MIT",
377
+ "optional": true,
378
+ "os": [
379
+ "netbsd"
380
+ ],
381
+ "engines": {
382
+ "node": ">=18"
383
+ }
384
+ },
385
+ "node_modules/@esbuild/netbsd-x64": {
386
+ "version": "0.25.5",
387
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz",
388
+ "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==",
389
+ "cpu": [
390
+ "x64"
391
+ ],
392
+ "dev": true,
393
+ "license": "MIT",
394
+ "optional": true,
395
+ "os": [
396
+ "netbsd"
397
+ ],
398
+ "engines": {
399
+ "node": ">=18"
400
+ }
401
+ },
402
+ "node_modules/@esbuild/openbsd-arm64": {
403
+ "version": "0.25.5",
404
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz",
405
+ "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==",
406
+ "cpu": [
407
+ "arm64"
408
+ ],
409
+ "dev": true,
410
+ "license": "MIT",
411
+ "optional": true,
412
+ "os": [
413
+ "openbsd"
414
+ ],
415
+ "engines": {
416
+ "node": ">=18"
417
+ }
418
+ },
419
+ "node_modules/@esbuild/openbsd-x64": {
420
+ "version": "0.25.5",
421
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz",
422
+ "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==",
423
+ "cpu": [
424
+ "x64"
425
+ ],
426
+ "dev": true,
427
+ "license": "MIT",
428
+ "optional": true,
429
+ "os": [
430
+ "openbsd"
431
+ ],
432
+ "engines": {
433
+ "node": ">=18"
434
+ }
435
+ },
436
+ "node_modules/@esbuild/sunos-x64": {
437
+ "version": "0.25.5",
438
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz",
439
+ "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==",
440
+ "cpu": [
441
+ "x64"
442
+ ],
443
+ "dev": true,
444
+ "license": "MIT",
445
+ "optional": true,
446
+ "os": [
447
+ "sunos"
448
+ ],
449
+ "engines": {
450
+ "node": ">=18"
451
+ }
452
+ },
453
+ "node_modules/@esbuild/win32-arm64": {
454
+ "version": "0.25.5",
455
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz",
456
+ "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==",
457
+ "cpu": [
458
+ "arm64"
459
+ ],
460
+ "dev": true,
461
+ "license": "MIT",
462
+ "optional": true,
463
+ "os": [
464
+ "win32"
465
+ ],
466
+ "engines": {
467
+ "node": ">=18"
468
+ }
469
+ },
470
+ "node_modules/@esbuild/win32-ia32": {
471
+ "version": "0.25.5",
472
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz",
473
+ "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==",
474
+ "cpu": [
475
+ "ia32"
476
+ ],
477
+ "dev": true,
478
+ "license": "MIT",
479
+ "optional": true,
480
+ "os": [
481
+ "win32"
482
+ ],
483
+ "engines": {
484
+ "node": ">=18"
485
+ }
486
+ },
487
+ "node_modules/@esbuild/win32-x64": {
488
+ "version": "0.25.5",
489
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz",
490
+ "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==",
491
+ "cpu": [
492
+ "x64"
493
+ ],
494
+ "dev": true,
495
+ "license": "MIT",
496
+ "optional": true,
497
+ "os": [
498
+ "win32"
499
+ ],
500
+ "engines": {
501
+ "node": ">=18"
502
+ }
503
+ },
504
+ "node_modules/@pipecat-ai/client-js": {
505
+ "version": "0.4.1",
506
+ "resolved": "https://registry.npmjs.org/@pipecat-ai/client-js/-/client-js-0.4.1.tgz",
507
+ "integrity": "sha512-3jLKRzeryqLxtkqvr4Bvxe2OxoI7mdOFecm6iolZizXnk/BE480SEg2oAKyov3b5oT6+jmPlT+1HRBlTzEtL7A==",
508
+ "license": "BSD-2-Clause",
509
+ "dependencies": {
510
+ "@types/events": "^3.0.3",
511
+ "clone-deep": "^4.0.1",
512
+ "events": "^3.3.0",
513
+ "typed-emitter": "^2.1.0",
514
+ "uuid": "^10.0.0"
515
+ }
516
+ },
517
+ "node_modules/@pipecat-ai/websocket-transport": {
518
+ "version": "0.4.2",
519
+ "resolved": "https://registry.npmjs.org/@pipecat-ai/websocket-transport/-/websocket-transport-0.4.2.tgz",
520
+ "integrity": "sha512-mOYnw9n60usODrE35D+uhFbJXl0DqXV32pAqSHu1of049s128mex6Qv+W49DBMVr8h5W6pLGrXhm+XDAtN5leg==",
521
+ "license": "BSD-2-Clause",
522
+ "dependencies": {
523
+ "@daily-co/daily-js": "^0.79.0",
524
+ "@protobuf-ts/plugin": "^2.11.0",
525
+ "@protobuf-ts/runtime": "^2.11.0",
526
+ "x-law": "^0.3.1"
527
+ },
528
+ "peerDependencies": {
529
+ "@pipecat-ai/client-js": "~0.4.0"
530
+ }
531
+ },
532
+ "node_modules/@protobuf-ts/plugin": {
533
+ "version": "2.11.0",
534
+ "resolved": "https://registry.npmjs.org/@protobuf-ts/plugin/-/plugin-2.11.0.tgz",
535
+ "integrity": "sha512-Y+p4Axrk3thxws4BVSIO+x4CKWH2c8k3K+QPrp6Oq8agdsXPL/uwsMTIdpTdXIzTaUEZFASJL9LU56pob5GTHg==",
536
+ "license": "Apache-2.0",
537
+ "dependencies": {
538
+ "@bufbuild/protobuf": "^2.4.0",
539
+ "@bufbuild/protoplugin": "^2.4.0",
540
+ "@protobuf-ts/protoc": "^2.11.0",
541
+ "@protobuf-ts/runtime": "^2.11.0",
542
+ "@protobuf-ts/runtime-rpc": "^2.11.0",
543
+ "typescript": "^3.9"
544
+ },
545
+ "bin": {
546
+ "protoc-gen-dump": "bin/protoc-gen-dump",
547
+ "protoc-gen-ts": "bin/protoc-gen-ts"
548
+ }
549
+ },
550
+ "node_modules/@protobuf-ts/plugin/node_modules/typescript": {
551
+ "version": "3.9.10",
552
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz",
553
+ "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==",
554
+ "license": "Apache-2.0",
555
+ "bin": {
556
+ "tsc": "bin/tsc",
557
+ "tsserver": "bin/tsserver"
558
+ },
559
+ "engines": {
560
+ "node": ">=4.2.0"
561
+ }
562
+ },
563
+ "node_modules/@protobuf-ts/protoc": {
564
+ "version": "2.11.0",
565
+ "resolved": "https://registry.npmjs.org/@protobuf-ts/protoc/-/protoc-2.11.0.tgz",
566
+ "integrity": "sha512-GYfmv1rjZ/7MWzUqMszhdXiuoa4Js/j6zCbcxFmeThBBUhbrXdPU42vY+QVCHL9PvAMXO+wEhUfPWYdd1YgnlA==",
567
+ "license": "Apache-2.0",
568
+ "bin": {
569
+ "protoc": "protoc.js"
570
+ }
571
+ },
572
+ "node_modules/@protobuf-ts/runtime": {
573
+ "version": "2.11.0",
574
+ "resolved": "https://registry.npmjs.org/@protobuf-ts/runtime/-/runtime-2.11.0.tgz",
575
+ "integrity": "sha512-DfpRpUiNvPC3Kj48CmlU4HaIEY1Myh++PIumMmohBAk8/k0d2CkxYxJfPyUAxfuUfl97F4AvuCu1gXmfOG7OJQ==",
576
+ "license": "(Apache-2.0 AND BSD-3-Clause)"
577
+ },
578
+ "node_modules/@protobuf-ts/runtime-rpc": {
579
+ "version": "2.11.0",
580
+ "resolved": "https://registry.npmjs.org/@protobuf-ts/runtime-rpc/-/runtime-rpc-2.11.0.tgz",
581
+ "integrity": "sha512-g/oMPym5LjVyCc3nlQc6cHer0R3CyleBos4p7CjRNzdKuH/FlRXzfQYo6EN5uv8vLtn7zEK9Cy4YBKvHStIaag==",
582
+ "license": "Apache-2.0",
583
+ "dependencies": {
584
+ "@protobuf-ts/runtime": "^2.11.0"
585
+ }
586
+ },
587
+ "node_modules/@protobufjs/aspromise": {
588
+ "version": "1.1.2",
589
+ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
590
+ "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
591
+ "license": "BSD-3-Clause"
592
+ },
593
+ "node_modules/@protobufjs/base64": {
594
+ "version": "1.1.2",
595
+ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
596
+ "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
597
+ "license": "BSD-3-Clause"
598
+ },
599
+ "node_modules/@protobufjs/codegen": {
600
+ "version": "2.0.4",
601
+ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
602
+ "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==",
603
+ "license": "BSD-3-Clause"
604
+ },
605
+ "node_modules/@protobufjs/eventemitter": {
606
+ "version": "1.1.0",
607
+ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
608
+ "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==",
609
+ "license": "BSD-3-Clause"
610
+ },
611
+ "node_modules/@protobufjs/fetch": {
612
+ "version": "1.1.0",
613
+ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
614
+ "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
615
+ "license": "BSD-3-Clause",
616
+ "dependencies": {
617
+ "@protobufjs/aspromise": "^1.1.1",
618
+ "@protobufjs/inquire": "^1.1.0"
619
+ }
620
+ },
621
+ "node_modules/@protobufjs/float": {
622
+ "version": "1.0.2",
623
+ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
624
+ "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
625
+ "license": "BSD-3-Clause"
626
+ },
627
+ "node_modules/@protobufjs/inquire": {
628
+ "version": "1.1.0",
629
+ "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
630
+ "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==",
631
+ "license": "BSD-3-Clause"
632
+ },
633
+ "node_modules/@protobufjs/path": {
634
+ "version": "1.1.2",
635
+ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
636
+ "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
637
+ "license": "BSD-3-Clause"
638
+ },
639
+ "node_modules/@protobufjs/pool": {
640
+ "version": "1.1.0",
641
+ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
642
+ "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
643
+ "license": "BSD-3-Clause"
644
+ },
645
+ "node_modules/@protobufjs/utf8": {
646
+ "version": "1.1.0",
647
+ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
648
+ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
649
+ "license": "BSD-3-Clause"
650
+ },
651
+ "node_modules/@rolldown/pluginutils": {
652
+ "version": "1.0.0-beta.11",
653
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.11.tgz",
654
+ "integrity": "sha512-L/gAA/hyCSuzTF1ftlzUSI/IKr2POHsv1Dd78GfqkR83KMNuswWD61JxGV2L7nRwBBBSDr6R1gCkdTmoN7W4ag==",
655
+ "dev": true,
656
+ "license": "MIT"
657
+ },
658
+ "node_modules/@rollup/rollup-android-arm-eabi": {
659
+ "version": "4.43.0",
660
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.43.0.tgz",
661
+ "integrity": "sha512-Krjy9awJl6rKbruhQDgivNbD1WuLb8xAclM4IR4cN5pHGAs2oIMMQJEiC3IC/9TZJ+QZkmZhlMO/6MBGxPidpw==",
662
+ "cpu": [
663
+ "arm"
664
+ ],
665
+ "dev": true,
666
+ "license": "MIT",
667
+ "optional": true,
668
+ "os": [
669
+ "android"
670
+ ]
671
+ },
672
+ "node_modules/@rollup/rollup-android-arm64": {
673
+ "version": "4.43.0",
674
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.43.0.tgz",
675
+ "integrity": "sha512-ss4YJwRt5I63454Rpj+mXCXicakdFmKnUNxr1dLK+5rv5FJgAxnN7s31a5VchRYxCFWdmnDWKd0wbAdTr0J5EA==",
676
+ "cpu": [
677
+ "arm64"
678
+ ],
679
+ "dev": true,
680
+ "license": "MIT",
681
+ "optional": true,
682
+ "os": [
683
+ "android"
684
+ ]
685
+ },
686
+ "node_modules/@rollup/rollup-darwin-arm64": {
687
+ "version": "4.43.0",
688
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.43.0.tgz",
689
+ "integrity": "sha512-eKoL8ykZ7zz8MjgBenEF2OoTNFAPFz1/lyJ5UmmFSz5jW+7XbH1+MAgCVHy72aG59rbuQLcJeiMrP8qP5d/N0A==",
690
+ "cpu": [
691
+ "arm64"
692
+ ],
693
+ "dev": true,
694
+ "license": "MIT",
695
+ "optional": true,
696
+ "os": [
697
+ "darwin"
698
+ ]
699
+ },
700
+ "node_modules/@rollup/rollup-darwin-x64": {
701
+ "version": "4.43.0",
702
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.43.0.tgz",
703
+ "integrity": "sha512-SYwXJgaBYW33Wi/q4ubN+ldWC4DzQY62S4Ll2dgfr/dbPoF50dlQwEaEHSKrQdSjC6oIe1WgzosoaNoHCdNuMg==",
704
+ "cpu": [
705
+ "x64"
706
+ ],
707
+ "dev": true,
708
+ "license": "MIT",
709
+ "optional": true,
710
+ "os": [
711
+ "darwin"
712
+ ]
713
+ },
714
+ "node_modules/@rollup/rollup-freebsd-arm64": {
715
+ "version": "4.43.0",
716
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.43.0.tgz",
717
+ "integrity": "sha512-SV+U5sSo0yujrjzBF7/YidieK2iF6E7MdF6EbYxNz94lA+R0wKl3SiixGyG/9Klab6uNBIqsN7j4Y/Fya7wAjQ==",
718
+ "cpu": [
719
+ "arm64"
720
+ ],
721
+ "dev": true,
722
+ "license": "MIT",
723
+ "optional": true,
724
+ "os": [
725
+ "freebsd"
726
+ ]
727
+ },
728
+ "node_modules/@rollup/rollup-freebsd-x64": {
729
+ "version": "4.43.0",
730
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.43.0.tgz",
731
+ "integrity": "sha512-J7uCsiV13L/VOeHJBo5SjasKiGxJ0g+nQTrBkAsmQBIdil3KhPnSE9GnRon4ejX1XDdsmK/l30IYLiAaQEO0Cg==",
732
+ "cpu": [
733
+ "x64"
734
+ ],
735
+ "dev": true,
736
+ "license": "MIT",
737
+ "optional": true,
738
+ "os": [
739
+ "freebsd"
740
+ ]
741
+ },
742
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
743
+ "version": "4.43.0",
744
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.43.0.tgz",
745
+ "integrity": "sha512-gTJ/JnnjCMc15uwB10TTATBEhK9meBIY+gXP4s0sHD1zHOaIh4Dmy1X9wup18IiY9tTNk5gJc4yx9ctj/fjrIw==",
746
+ "cpu": [
747
+ "arm"
748
+ ],
749
+ "dev": true,
750
+ "license": "MIT",
751
+ "optional": true,
752
+ "os": [
753
+ "linux"
754
+ ]
755
+ },
756
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
757
+ "version": "4.43.0",
758
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.43.0.tgz",
759
+ "integrity": "sha512-ZJ3gZynL1LDSIvRfz0qXtTNs56n5DI2Mq+WACWZ7yGHFUEirHBRt7fyIk0NsCKhmRhn7WAcjgSkSVVxKlPNFFw==",
760
+ "cpu": [
761
+ "arm"
762
+ ],
763
+ "dev": true,
764
+ "license": "MIT",
765
+ "optional": true,
766
+ "os": [
767
+ "linux"
768
+ ]
769
+ },
770
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
771
+ "version": "4.43.0",
772
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.43.0.tgz",
773
+ "integrity": "sha512-8FnkipasmOOSSlfucGYEu58U8cxEdhziKjPD2FIa0ONVMxvl/hmONtX/7y4vGjdUhjcTHlKlDhw3H9t98fPvyA==",
774
+ "cpu": [
775
+ "arm64"
776
+ ],
777
+ "dev": true,
778
+ "license": "MIT",
779
+ "optional": true,
780
+ "os": [
781
+ "linux"
782
+ ]
783
+ },
784
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
785
+ "version": "4.43.0",
786
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.43.0.tgz",
787
+ "integrity": "sha512-KPPyAdlcIZ6S9C3S2cndXDkV0Bb1OSMsX0Eelr2Bay4EsF9yi9u9uzc9RniK3mcUGCLhWY9oLr6er80P5DE6XA==",
788
+ "cpu": [
789
+ "arm64"
790
+ ],
791
+ "dev": true,
792
+ "license": "MIT",
793
+ "optional": true,
794
+ "os": [
795
+ "linux"
796
+ ]
797
+ },
798
+ "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
799
+ "version": "4.43.0",
800
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.43.0.tgz",
801
+ "integrity": "sha512-HPGDIH0/ZzAZjvtlXj6g+KDQ9ZMHfSP553za7o2Odegb/BEfwJcR0Sw0RLNpQ9nC6Gy8s+3mSS9xjZ0n3rhcYg==",
802
+ "cpu": [
803
+ "loong64"
804
+ ],
805
+ "dev": true,
806
+ "license": "MIT",
807
+ "optional": true,
808
+ "os": [
809
+ "linux"
810
+ ]
811
+ },
812
+ "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
813
+ "version": "4.43.0",
814
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.43.0.tgz",
815
+ "integrity": "sha512-gEmwbOws4U4GLAJDhhtSPWPXUzDfMRedT3hFMyRAvM9Mrnj+dJIFIeL7otsv2WF3D7GrV0GIewW0y28dOYWkmw==",
816
+ "cpu": [
817
+ "ppc64"
818
+ ],
819
+ "dev": true,
820
+ "license": "MIT",
821
+ "optional": true,
822
+ "os": [
823
+ "linux"
824
+ ]
825
+ },
826
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
827
+ "version": "4.43.0",
828
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.43.0.tgz",
829
+ "integrity": "sha512-XXKvo2e+wFtXZF/9xoWohHg+MuRnvO29TI5Hqe9xwN5uN8NKUYy7tXUG3EZAlfchufNCTHNGjEx7uN78KsBo0g==",
830
+ "cpu": [
831
+ "riscv64"
832
+ ],
833
+ "dev": true,
834
+ "license": "MIT",
835
+ "optional": true,
836
+ "os": [
837
+ "linux"
838
+ ]
839
+ },
840
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
841
+ "version": "4.43.0",
842
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.43.0.tgz",
843
+ "integrity": "sha512-ruf3hPWhjw6uDFsOAzmbNIvlXFXlBQ4nk57Sec8E8rUxs/AI4HD6xmiiasOOx/3QxS2f5eQMKTAwk7KHwpzr/Q==",
844
+ "cpu": [
845
+ "riscv64"
846
+ ],
847
+ "dev": true,
848
+ "license": "MIT",
849
+ "optional": true,
850
+ "os": [
851
+ "linux"
852
+ ]
853
+ },
854
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
855
+ "version": "4.43.0",
856
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.43.0.tgz",
857
+ "integrity": "sha512-QmNIAqDiEMEvFV15rsSnjoSmO0+eJLoKRD9EAa9rrYNwO/XRCtOGM3A5A0X+wmG+XRrw9Fxdsw+LnyYiZWWcVw==",
858
+ "cpu": [
859
+ "s390x"
860
+ ],
861
+ "dev": true,
862
+ "license": "MIT",
863
+ "optional": true,
864
+ "os": [
865
+ "linux"
866
+ ]
867
+ },
868
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
869
+ "version": "4.43.0",
870
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.43.0.tgz",
871
+ "integrity": "sha512-jAHr/S0iiBtFyzjhOkAics/2SrXE092qyqEg96e90L3t9Op8OTzS6+IX0Fy5wCt2+KqeHAkti+eitV0wvblEoQ==",
872
+ "cpu": [
873
+ "x64"
874
+ ],
875
+ "dev": true,
876
+ "license": "MIT",
877
+ "optional": true,
878
+ "os": [
879
+ "linux"
880
+ ]
881
+ },
882
+ "node_modules/@rollup/rollup-linux-x64-musl": {
883
+ "version": "4.43.0",
884
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.43.0.tgz",
885
+ "integrity": "sha512-3yATWgdeXyuHtBhrLt98w+5fKurdqvs8B53LaoKD7P7H7FKOONLsBVMNl9ghPQZQuYcceV5CDyPfyfGpMWD9mQ==",
886
+ "cpu": [
887
+ "x64"
888
+ ],
889
+ "dev": true,
890
+ "license": "MIT",
891
+ "optional": true,
892
+ "os": [
893
+ "linux"
894
+ ]
895
+ },
896
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
897
+ "version": "4.43.0",
898
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.43.0.tgz",
899
+ "integrity": "sha512-wVzXp2qDSCOpcBCT5WRWLmpJRIzv23valvcTwMHEobkjippNf+C3ys/+wf07poPkeNix0paTNemB2XrHr2TnGw==",
900
+ "cpu": [
901
+ "arm64"
902
+ ],
903
+ "dev": true,
904
+ "license": "MIT",
905
+ "optional": true,
906
+ "os": [
907
+ "win32"
908
+ ]
909
+ },
910
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
911
+ "version": "4.43.0",
912
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.43.0.tgz",
913
+ "integrity": "sha512-fYCTEyzf8d+7diCw8b+asvWDCLMjsCEA8alvtAutqJOJp/wL5hs1rWSqJ1vkjgW0L2NB4bsYJrpKkiIPRR9dvw==",
914
+ "cpu": [
915
+ "ia32"
916
+ ],
917
+ "dev": true,
918
+ "license": "MIT",
919
+ "optional": true,
920
+ "os": [
921
+ "win32"
922
+ ]
923
+ },
924
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
925
+ "version": "4.43.0",
926
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.43.0.tgz",
927
+ "integrity": "sha512-SnGhLiE5rlK0ofq8kzuDkM0g7FN1s5VYY+YSMTibP7CqShxCQvqtNxTARS4xX4PFJfHjG0ZQYX9iGzI3FQh5Aw==",
928
+ "cpu": [
929
+ "x64"
930
+ ],
931
+ "dev": true,
932
+ "license": "MIT",
933
+ "optional": true,
934
+ "os": [
935
+ "win32"
936
+ ]
937
+ },
938
+ "node_modules/@sentry-internal/browser-utils": {
939
+ "version": "8.55.0",
940
+ "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.55.0.tgz",
941
+ "integrity": "sha512-ROgqtQfpH/82AQIpESPqPQe0UyWywKJsmVIqi3c5Fh+zkds5LUxnssTj3yNd1x+kxaPDVB023jAP+3ibNgeNDw==",
942
+ "license": "MIT",
943
+ "dependencies": {
944
+ "@sentry/core": "8.55.0"
945
+ },
946
+ "engines": {
947
+ "node": ">=14.18"
948
+ }
949
+ },
950
+ "node_modules/@sentry-internal/feedback": {
951
+ "version": "8.55.0",
952
+ "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.55.0.tgz",
953
+ "integrity": "sha512-cP3BD/Q6pquVQ+YL+rwCnorKuTXiS9KXW8HNKu4nmmBAyf7urjs+F6Hr1k9MXP5yQ8W3yK7jRWd09Yu6DHWOiw==",
954
+ "license": "MIT",
955
+ "dependencies": {
956
+ "@sentry/core": "8.55.0"
957
+ },
958
+ "engines": {
959
+ "node": ">=14.18"
960
+ }
961
+ },
962
+ "node_modules/@sentry-internal/replay": {
963
+ "version": "8.55.0",
964
+ "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.55.0.tgz",
965
+ "integrity": "sha512-roCDEGkORwolxBn8xAKedybY+Jlefq3xYmgN2fr3BTnsXjSYOPC7D1/mYqINBat99nDtvgFvNfRcZPiwwZ1hSw==",
966
+ "license": "MIT",
967
+ "dependencies": {
968
+ "@sentry-internal/browser-utils": "8.55.0",
969
+ "@sentry/core": "8.55.0"
970
+ },
971
+ "engines": {
972
+ "node": ">=14.18"
973
+ }
974
+ },
975
+ "node_modules/@sentry-internal/replay-canvas": {
976
+ "version": "8.55.0",
977
+ "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.55.0.tgz",
978
+ "integrity": "sha512-nIkfgRWk1091zHdu4NbocQsxZF1rv1f7bbp3tTIlZYbrH62XVZosx5iHAuZG0Zc48AETLE7K4AX9VGjvQj8i9w==",
979
+ "license": "MIT",
980
+ "dependencies": {
981
+ "@sentry-internal/replay": "8.55.0",
982
+ "@sentry/core": "8.55.0"
983
+ },
984
+ "engines": {
985
+ "node": ">=14.18"
986
+ }
987
+ },
988
+ "node_modules/@sentry/browser": {
989
+ "version": "8.55.0",
990
+ "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.55.0.tgz",
991
+ "integrity": "sha512-1A31mCEWCjaMxJt6qGUK+aDnLDcK6AwLAZnqpSchNysGni1pSn1RWSmk9TBF8qyTds5FH8B31H480uxMPUJ7Cw==",
992
+ "license": "MIT",
993
+ "dependencies": {
994
+ "@sentry-internal/browser-utils": "8.55.0",
995
+ "@sentry-internal/feedback": "8.55.0",
996
+ "@sentry-internal/replay": "8.55.0",
997
+ "@sentry-internal/replay-canvas": "8.55.0",
998
+ "@sentry/core": "8.55.0"
999
+ },
1000
+ "engines": {
1001
+ "node": ">=14.18"
1002
+ }
1003
+ },
1004
+ "node_modules/@sentry/core": {
1005
+ "version": "8.55.0",
1006
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.55.0.tgz",
1007
+ "integrity": "sha512-6g7jpbefjHYs821Z+EBJ8r4Z7LT5h80YSWRJaylGS4nW5W5Z2KXzpdnyFarv37O7QjauzVC2E+PABmpkw5/JGA==",
1008
+ "license": "MIT",
1009
+ "engines": {
1010
+ "node": ">=14.18"
1011
+ }
1012
+ },
1013
+ "node_modules/@swc/core": {
1014
+ "version": "1.12.0",
1015
+ "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.12.0.tgz",
1016
+ "integrity": "sha512-/C0kiMHPY/HnLfqXYGMGxGck3A5Y3mqwxfv+EwHTPHGjAVRfHpWAEEBTSTF5C88vVY6CvwBEkhR2TX7t8Mahcw==",
1017
+ "dev": true,
1018
+ "hasInstallScript": true,
1019
+ "license": "Apache-2.0",
1020
+ "dependencies": {
1021
+ "@swc/counter": "^0.1.3",
1022
+ "@swc/types": "^0.1.22"
1023
+ },
1024
+ "engines": {
1025
+ "node": ">=10"
1026
+ },
1027
+ "funding": {
1028
+ "type": "opencollective",
1029
+ "url": "https://opencollective.com/swc"
1030
+ },
1031
+ "optionalDependencies": {
1032
+ "@swc/core-darwin-arm64": "1.12.0",
1033
+ "@swc/core-darwin-x64": "1.12.0",
1034
+ "@swc/core-linux-arm-gnueabihf": "1.12.0",
1035
+ "@swc/core-linux-arm64-gnu": "1.12.0",
1036
+ "@swc/core-linux-arm64-musl": "1.12.0",
1037
+ "@swc/core-linux-x64-gnu": "1.12.0",
1038
+ "@swc/core-linux-x64-musl": "1.12.0",
1039
+ "@swc/core-win32-arm64-msvc": "1.12.0",
1040
+ "@swc/core-win32-ia32-msvc": "1.12.0",
1041
+ "@swc/core-win32-x64-msvc": "1.12.0"
1042
+ },
1043
+ "peerDependencies": {
1044
+ "@swc/helpers": ">=0.5.17"
1045
+ },
1046
+ "peerDependenciesMeta": {
1047
+ "@swc/helpers": {
1048
+ "optional": true
1049
+ }
1050
+ }
1051
+ },
1052
+ "node_modules/@swc/core-darwin-arm64": {
1053
+ "version": "1.12.0",
1054
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.12.0.tgz",
1055
+ "integrity": "sha512-usLr8kC80GDv3pwH2zoEaS279kxtWY0MY3blbMFw7zA8fAjqxa8IDxm3WcgyNLNWckWn4asFfguEwz/Weem3nA==",
1056
+ "cpu": [
1057
+ "arm64"
1058
+ ],
1059
+ "dev": true,
1060
+ "license": "Apache-2.0 AND MIT",
1061
+ "optional": true,
1062
+ "os": [
1063
+ "darwin"
1064
+ ],
1065
+ "engines": {
1066
+ "node": ">=10"
1067
+ }
1068
+ },
1069
+ "node_modules/@swc/core-darwin-x64": {
1070
+ "version": "1.12.0",
1071
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.12.0.tgz",
1072
+ "integrity": "sha512-Cvv4sqDcTY7QF2Dh1vn2Xbt/1ENYQcpmrGHzITJrXzxA2aBopsz/n4yQDiyRxTR0t802m4xu0CzMoZIHvVruWQ==",
1073
+ "cpu": [
1074
+ "x64"
1075
+ ],
1076
+ "dev": true,
1077
+ "license": "Apache-2.0 AND MIT",
1078
+ "optional": true,
1079
+ "os": [
1080
+ "darwin"
1081
+ ],
1082
+ "engines": {
1083
+ "node": ">=10"
1084
+ }
1085
+ },
1086
+ "node_modules/@swc/core-linux-arm-gnueabihf": {
1087
+ "version": "1.12.0",
1088
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.12.0.tgz",
1089
+ "integrity": "sha512-seM4/XMJMOupkzfLfHl8sRa3NdhsVZp+XgwA/vVeYZYJE4wuWUxVzhCYzwmNftVY32eF2IiRaWnhG6ho6jusnQ==",
1090
+ "cpu": [
1091
+ "arm"
1092
+ ],
1093
+ "dev": true,
1094
+ "license": "Apache-2.0",
1095
+ "optional": true,
1096
+ "os": [
1097
+ "linux"
1098
+ ],
1099
+ "engines": {
1100
+ "node": ">=10"
1101
+ }
1102
+ },
1103
+ "node_modules/@swc/core-linux-arm64-gnu": {
1104
+ "version": "1.12.0",
1105
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.12.0.tgz",
1106
+ "integrity": "sha512-Al0x33gUVxNY5tutEYpSyv7mze6qQS1ONa0HEwoRxcK9WXsX0NHLTiOSGZoCUS1SsXM37ONlbA6/Bsp1MQyP+g==",
1107
+ "cpu": [
1108
+ "arm64"
1109
+ ],
1110
+ "dev": true,
1111
+ "license": "Apache-2.0 AND MIT",
1112
+ "optional": true,
1113
+ "os": [
1114
+ "linux"
1115
+ ],
1116
+ "engines": {
1117
+ "node": ">=10"
1118
+ }
1119
+ },
1120
+ "node_modules/@swc/core-linux-arm64-musl": {
1121
+ "version": "1.12.0",
1122
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.12.0.tgz",
1123
+ "integrity": "sha512-OeFHz/5Hl9v75J9TYA5jQxNIYAZMqaiPpd9dYSTK2Xyqa/ZGgTtNyPhIwVfxx+9mHBf6+9c1mTlXUtACMtHmaQ==",
1124
+ "cpu": [
1125
+ "arm64"
1126
+ ],
1127
+ "dev": true,
1128
+ "license": "Apache-2.0 AND MIT",
1129
+ "optional": true,
1130
+ "os": [
1131
+ "linux"
1132
+ ],
1133
+ "engines": {
1134
+ "node": ">=10"
1135
+ }
1136
+ },
1137
+ "node_modules/@swc/core-linux-x64-gnu": {
1138
+ "version": "1.12.0",
1139
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.12.0.tgz",
1140
+ "integrity": "sha512-ltIvqNi7H0c5pRawyqjeYSKEIfZP4vv/datT3mwT6BW7muJtd1+KIDCPFLMIQ4wm/h76YQwPocsin3fzmnFdNA==",
1141
+ "cpu": [
1142
+ "x64"
1143
+ ],
1144
+ "dev": true,
1145
+ "license": "Apache-2.0 AND MIT",
1146
+ "optional": true,
1147
+ "os": [
1148
+ "linux"
1149
+ ],
1150
+ "engines": {
1151
+ "node": ">=10"
1152
+ }
1153
+ },
1154
+ "node_modules/@swc/core-linux-x64-musl": {
1155
+ "version": "1.12.0",
1156
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.12.0.tgz",
1157
+ "integrity": "sha512-Z/DhpjehaTK0uf+MhNB7mV9SuewpGs3P/q9/8+UsJeYoFr7yuOoPbAvrD6AqZkf6Bh7MRZ5OtG+KQgG5L+goiA==",
1158
+ "cpu": [
1159
+ "x64"
1160
+ ],
1161
+ "dev": true,
1162
+ "license": "Apache-2.0 AND MIT",
1163
+ "optional": true,
1164
+ "os": [
1165
+ "linux"
1166
+ ],
1167
+ "engines": {
1168
+ "node": ">=10"
1169
+ }
1170
+ },
1171
+ "node_modules/@swc/core-win32-arm64-msvc": {
1172
+ "version": "1.12.0",
1173
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.12.0.tgz",
1174
+ "integrity": "sha512-wHnvbfHIh2gfSbvuFT7qP97YCMUDh+fuiso+pcC6ug8IsMxuViNapHET4o0ZdFNWHhXJ7/s0e6w7mkOalsqQiQ==",
1175
+ "cpu": [
1176
+ "arm64"
1177
+ ],
1178
+ "dev": true,
1179
+ "license": "Apache-2.0 AND MIT",
1180
+ "optional": true,
1181
+ "os": [
1182
+ "win32"
1183
+ ],
1184
+ "engines": {
1185
+ "node": ">=10"
1186
+ }
1187
+ },
1188
+ "node_modules/@swc/core-win32-ia32-msvc": {
1189
+ "version": "1.12.0",
1190
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.12.0.tgz",
1191
+ "integrity": "sha512-88umlXwK+7J2p4DjfWHXQpmlZgCf1ayt6Ssj+PYlAfMCR0aBiJoAMwHWrvDXEozyOrsyP1j2X6WxbmA861vL5Q==",
1192
+ "cpu": [
1193
+ "ia32"
1194
+ ],
1195
+ "dev": true,
1196
+ "license": "Apache-2.0 AND MIT",
1197
+ "optional": true,
1198
+ "os": [
1199
+ "win32"
1200
+ ],
1201
+ "engines": {
1202
+ "node": ">=10"
1203
+ }
1204
+ },
1205
+ "node_modules/@swc/core-win32-x64-msvc": {
1206
+ "version": "1.12.0",
1207
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.12.0.tgz",
1208
+ "integrity": "sha512-KR9TSRp+FEVOhbgTU6c94p/AYpsyBk7dIvlKQiDp8oKScUoyHG5yjmMBFN/BqUyTq4kj6zlgsY2rFE4R8/yqWg==",
1209
+ "cpu": [
1210
+ "x64"
1211
+ ],
1212
+ "dev": true,
1213
+ "license": "Apache-2.0 AND MIT",
1214
+ "optional": true,
1215
+ "os": [
1216
+ "win32"
1217
+ ],
1218
+ "engines": {
1219
+ "node": ">=10"
1220
+ }
1221
+ },
1222
+ "node_modules/@swc/counter": {
1223
+ "version": "0.1.3",
1224
+ "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
1225
+ "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
1226
+ "dev": true,
1227
+ "license": "Apache-2.0"
1228
+ },
1229
+ "node_modules/@swc/types": {
1230
+ "version": "0.1.23",
1231
+ "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.23.tgz",
1232
+ "integrity": "sha512-u1iIVZV9Q0jxY+yM2vw/hZGDNudsN85bBpTqzAQ9rzkxW9D+e3aEM4Han+ow518gSewkXgjmEK0BD79ZcNVgPw==",
1233
+ "dev": true,
1234
+ "license": "Apache-2.0",
1235
+ "dependencies": {
1236
+ "@swc/counter": "^0.1.3"
1237
+ }
1238
+ },
1239
+ "node_modules/@types/estree": {
1240
+ "version": "1.0.7",
1241
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
1242
+ "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
1243
+ "dev": true,
1244
+ "license": "MIT"
1245
+ },
1246
+ "node_modules/@types/events": {
1247
+ "version": "3.0.3",
1248
+ "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.3.tgz",
1249
+ "integrity": "sha512-trOc4AAUThEz9hapPtSd7wf5tiQKvTtu5b371UxXdTuqzIh0ArcRspRP0i0Viu+LXstIQ1z96t1nsPxT9ol01g==",
1250
+ "license": "MIT"
1251
+ },
1252
+ "node_modules/@types/node": {
1253
+ "version": "22.15.31",
1254
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.31.tgz",
1255
+ "integrity": "sha512-jnVe5ULKl6tijxUhvQeNbQG/84fHfg+yMak02cT8QVhBx/F05rAVxCGBYYTh2EKz22D6JF5ktXuNwdx7b9iEGw==",
1256
+ "license": "MIT",
1257
+ "dependencies": {
1258
+ "undici-types": "~6.21.0"
1259
+ }
1260
+ },
1261
+ "node_modules/@types/protobufjs": {
1262
+ "version": "6.0.0",
1263
+ "resolved": "https://registry.npmjs.org/@types/protobufjs/-/protobufjs-6.0.0.tgz",
1264
+ "integrity": "sha512-A27RDExpAf3rdDjIrHKiJK6x8kqqJ4CmoChwtipfhVAn1p7+wviQFFP7dppn8FslSbHtQeVPvi8wNKkDjSYjHw==",
1265
+ "deprecated": "This is a stub types definition for protobufjs (https://github.com/dcodeIO/ProtoBuf.js). protobufjs provides its own type definitions, so you don't need @types/protobufjs installed!",
1266
+ "dev": true,
1267
+ "license": "MIT",
1268
+ "dependencies": {
1269
+ "protobufjs": "*"
1270
+ }
1271
+ },
1272
+ "node_modules/@typescript/vfs": {
1273
+ "version": "1.6.1",
1274
+ "resolved": "https://registry.npmjs.org/@typescript/vfs/-/vfs-1.6.1.tgz",
1275
+ "integrity": "sha512-JwoxboBh7Oz1v38tPbkrZ62ZXNHAk9bJ7c9x0eI5zBfBnBYGhURdbnh7Z4smN/MV48Y5OCcZb58n972UtbazsA==",
1276
+ "license": "MIT",
1277
+ "dependencies": {
1278
+ "debug": "^4.1.1"
1279
+ },
1280
+ "peerDependencies": {
1281
+ "typescript": "*"
1282
+ }
1283
+ },
1284
+ "node_modules/@vitejs/plugin-react-swc": {
1285
+ "version": "3.10.2",
1286
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.10.2.tgz",
1287
+ "integrity": "sha512-xD3Rdvrt5LgANug7WekBn1KhcvLn1H3jNBfJRL3reeOIua/WnZOEV5qi5qIBq5T8R0jUDmRtxuvk4bPhzGHDWw==",
1288
+ "dev": true,
1289
+ "license": "MIT",
1290
+ "dependencies": {
1291
+ "@rolldown/pluginutils": "1.0.0-beta.11",
1292
+ "@swc/core": "^1.11.31"
1293
+ },
1294
+ "peerDependencies": {
1295
+ "vite": "^4 || ^5 || ^6 || ^7.0.0-beta.0"
1296
+ }
1297
+ },
1298
+ "node_modules/bowser": {
1299
+ "version": "2.11.0",
1300
+ "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz",
1301
+ "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==",
1302
+ "license": "MIT"
1303
+ },
1304
+ "node_modules/clone-deep": {
1305
+ "version": "4.0.1",
1306
+ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
1307
+ "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
1308
+ "license": "MIT",
1309
+ "dependencies": {
1310
+ "is-plain-object": "^2.0.4",
1311
+ "kind-of": "^6.0.2",
1312
+ "shallow-clone": "^3.0.0"
1313
+ },
1314
+ "engines": {
1315
+ "node": ">=6"
1316
+ }
1317
+ },
1318
+ "node_modules/debug": {
1319
+ "version": "4.4.1",
1320
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
1321
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
1322
+ "license": "MIT",
1323
+ "dependencies": {
1324
+ "ms": "^2.1.3"
1325
+ },
1326
+ "engines": {
1327
+ "node": ">=6.0"
1328
+ },
1329
+ "peerDependenciesMeta": {
1330
+ "supports-color": {
1331
+ "optional": true
1332
+ }
1333
+ }
1334
+ },
1335
+ "node_modules/dequal": {
1336
+ "version": "2.0.3",
1337
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
1338
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
1339
+ "license": "MIT",
1340
+ "engines": {
1341
+ "node": ">=6"
1342
+ }
1343
+ },
1344
+ "node_modules/esbuild": {
1345
+ "version": "0.25.5",
1346
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz",
1347
+ "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==",
1348
+ "dev": true,
1349
+ "hasInstallScript": true,
1350
+ "license": "MIT",
1351
+ "bin": {
1352
+ "esbuild": "bin/esbuild"
1353
+ },
1354
+ "engines": {
1355
+ "node": ">=18"
1356
+ },
1357
+ "optionalDependencies": {
1358
+ "@esbuild/aix-ppc64": "0.25.5",
1359
+ "@esbuild/android-arm": "0.25.5",
1360
+ "@esbuild/android-arm64": "0.25.5",
1361
+ "@esbuild/android-x64": "0.25.5",
1362
+ "@esbuild/darwin-arm64": "0.25.5",
1363
+ "@esbuild/darwin-x64": "0.25.5",
1364
+ "@esbuild/freebsd-arm64": "0.25.5",
1365
+ "@esbuild/freebsd-x64": "0.25.5",
1366
+ "@esbuild/linux-arm": "0.25.5",
1367
+ "@esbuild/linux-arm64": "0.25.5",
1368
+ "@esbuild/linux-ia32": "0.25.5",
1369
+ "@esbuild/linux-loong64": "0.25.5",
1370
+ "@esbuild/linux-mips64el": "0.25.5",
1371
+ "@esbuild/linux-ppc64": "0.25.5",
1372
+ "@esbuild/linux-riscv64": "0.25.5",
1373
+ "@esbuild/linux-s390x": "0.25.5",
1374
+ "@esbuild/linux-x64": "0.25.5",
1375
+ "@esbuild/netbsd-arm64": "0.25.5",
1376
+ "@esbuild/netbsd-x64": "0.25.5",
1377
+ "@esbuild/openbsd-arm64": "0.25.5",
1378
+ "@esbuild/openbsd-x64": "0.25.5",
1379
+ "@esbuild/sunos-x64": "0.25.5",
1380
+ "@esbuild/win32-arm64": "0.25.5",
1381
+ "@esbuild/win32-ia32": "0.25.5",
1382
+ "@esbuild/win32-x64": "0.25.5"
1383
+ }
1384
+ },
1385
+ "node_modules/events": {
1386
+ "version": "3.3.0",
1387
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
1388
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
1389
+ "license": "MIT",
1390
+ "engines": {
1391
+ "node": ">=0.8.x"
1392
+ }
1393
+ },
1394
+ "node_modules/fdir": {
1395
+ "version": "6.4.6",
1396
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz",
1397
+ "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==",
1398
+ "dev": true,
1399
+ "license": "MIT",
1400
+ "peerDependencies": {
1401
+ "picomatch": "^3 || ^4"
1402
+ },
1403
+ "peerDependenciesMeta": {
1404
+ "picomatch": {
1405
+ "optional": true
1406
+ }
1407
+ }
1408
+ },
1409
+ "node_modules/fsevents": {
1410
+ "version": "2.3.3",
1411
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
1412
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
1413
+ "dev": true,
1414
+ "hasInstallScript": true,
1415
+ "license": "MIT",
1416
+ "optional": true,
1417
+ "os": [
1418
+ "darwin"
1419
+ ],
1420
+ "engines": {
1421
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1422
+ }
1423
+ },
1424
+ "node_modules/is-plain-object": {
1425
+ "version": "2.0.4",
1426
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
1427
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
1428
+ "license": "MIT",
1429
+ "dependencies": {
1430
+ "isobject": "^3.0.1"
1431
+ },
1432
+ "engines": {
1433
+ "node": ">=0.10.0"
1434
+ }
1435
+ },
1436
+ "node_modules/isobject": {
1437
+ "version": "3.0.1",
1438
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
1439
+ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
1440
+ "license": "MIT",
1441
+ "engines": {
1442
+ "node": ">=0.10.0"
1443
+ }
1444
+ },
1445
+ "node_modules/kind-of": {
1446
+ "version": "6.0.3",
1447
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
1448
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
1449
+ "license": "MIT",
1450
+ "engines": {
1451
+ "node": ">=0.10.0"
1452
+ }
1453
+ },
1454
+ "node_modules/long": {
1455
+ "version": "5.3.2",
1456
+ "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
1457
+ "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
1458
+ "license": "Apache-2.0"
1459
+ },
1460
+ "node_modules/ms": {
1461
+ "version": "2.1.3",
1462
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1463
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1464
+ "license": "MIT"
1465
+ },
1466
+ "node_modules/nanoid": {
1467
+ "version": "3.3.11",
1468
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
1469
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
1470
+ "dev": true,
1471
+ "funding": [
1472
+ {
1473
+ "type": "github",
1474
+ "url": "https://github.com/sponsors/ai"
1475
+ }
1476
+ ],
1477
+ "license": "MIT",
1478
+ "bin": {
1479
+ "nanoid": "bin/nanoid.cjs"
1480
+ },
1481
+ "engines": {
1482
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1483
+ }
1484
+ },
1485
+ "node_modules/picocolors": {
1486
+ "version": "1.1.1",
1487
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
1488
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
1489
+ "dev": true,
1490
+ "license": "ISC"
1491
+ },
1492
+ "node_modules/picomatch": {
1493
+ "version": "4.0.2",
1494
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
1495
+ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
1496
+ "dev": true,
1497
+ "license": "MIT",
1498
+ "engines": {
1499
+ "node": ">=12"
1500
+ },
1501
+ "funding": {
1502
+ "url": "https://github.com/sponsors/jonschlinkert"
1503
+ }
1504
+ },
1505
+ "node_modules/postcss": {
1506
+ "version": "8.5.5",
1507
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.5.tgz",
1508
+ "integrity": "sha512-d/jtm+rdNT8tpXuHY5MMtcbJFBkhXE6593XVR9UoGCH8jSFGci7jGvMGH5RYd5PBJW+00NZQt6gf7CbagJCrhg==",
1509
+ "dev": true,
1510
+ "funding": [
1511
+ {
1512
+ "type": "opencollective",
1513
+ "url": "https://opencollective.com/postcss/"
1514
+ },
1515
+ {
1516
+ "type": "tidelift",
1517
+ "url": "https://tidelift.com/funding/github/npm/postcss"
1518
+ },
1519
+ {
1520
+ "type": "github",
1521
+ "url": "https://github.com/sponsors/ai"
1522
+ }
1523
+ ],
1524
+ "license": "MIT",
1525
+ "dependencies": {
1526
+ "nanoid": "^3.3.11",
1527
+ "picocolors": "^1.1.1",
1528
+ "source-map-js": "^1.2.1"
1529
+ },
1530
+ "engines": {
1531
+ "node": "^10 || ^12 || >=14"
1532
+ }
1533
+ },
1534
+ "node_modules/protobufjs": {
1535
+ "version": "7.5.3",
1536
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.3.tgz",
1537
+ "integrity": "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==",
1538
+ "hasInstallScript": true,
1539
+ "license": "BSD-3-Clause",
1540
+ "dependencies": {
1541
+ "@protobufjs/aspromise": "^1.1.2",
1542
+ "@protobufjs/base64": "^1.1.2",
1543
+ "@protobufjs/codegen": "^2.0.4",
1544
+ "@protobufjs/eventemitter": "^1.1.0",
1545
+ "@protobufjs/fetch": "^1.1.0",
1546
+ "@protobufjs/float": "^1.0.2",
1547
+ "@protobufjs/inquire": "^1.1.0",
1548
+ "@protobufjs/path": "^1.1.2",
1549
+ "@protobufjs/pool": "^1.1.0",
1550
+ "@protobufjs/utf8": "^1.1.0",
1551
+ "@types/node": ">=13.7.0",
1552
+ "long": "^5.0.0"
1553
+ },
1554
+ "engines": {
1555
+ "node": ">=12.0.0"
1556
+ }
1557
+ },
1558
+ "node_modules/rollup": {
1559
+ "version": "4.43.0",
1560
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.43.0.tgz",
1561
+ "integrity": "sha512-wdN2Kd3Twh8MAEOEJZsuxuLKCsBEo4PVNLK6tQWAn10VhsVewQLzcucMgLolRlhFybGxfclbPeEYBaP6RvUFGg==",
1562
+ "dev": true,
1563
+ "license": "MIT",
1564
+ "dependencies": {
1565
+ "@types/estree": "1.0.7"
1566
+ },
1567
+ "bin": {
1568
+ "rollup": "dist/bin/rollup"
1569
+ },
1570
+ "engines": {
1571
+ "node": ">=18.0.0",
1572
+ "npm": ">=8.0.0"
1573
+ },
1574
+ "optionalDependencies": {
1575
+ "@rollup/rollup-android-arm-eabi": "4.43.0",
1576
+ "@rollup/rollup-android-arm64": "4.43.0",
1577
+ "@rollup/rollup-darwin-arm64": "4.43.0",
1578
+ "@rollup/rollup-darwin-x64": "4.43.0",
1579
+ "@rollup/rollup-freebsd-arm64": "4.43.0",
1580
+ "@rollup/rollup-freebsd-x64": "4.43.0",
1581
+ "@rollup/rollup-linux-arm-gnueabihf": "4.43.0",
1582
+ "@rollup/rollup-linux-arm-musleabihf": "4.43.0",
1583
+ "@rollup/rollup-linux-arm64-gnu": "4.43.0",
1584
+ "@rollup/rollup-linux-arm64-musl": "4.43.0",
1585
+ "@rollup/rollup-linux-loongarch64-gnu": "4.43.0",
1586
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.43.0",
1587
+ "@rollup/rollup-linux-riscv64-gnu": "4.43.0",
1588
+ "@rollup/rollup-linux-riscv64-musl": "4.43.0",
1589
+ "@rollup/rollup-linux-s390x-gnu": "4.43.0",
1590
+ "@rollup/rollup-linux-x64-gnu": "4.43.0",
1591
+ "@rollup/rollup-linux-x64-musl": "4.43.0",
1592
+ "@rollup/rollup-win32-arm64-msvc": "4.43.0",
1593
+ "@rollup/rollup-win32-ia32-msvc": "4.43.0",
1594
+ "@rollup/rollup-win32-x64-msvc": "4.43.0",
1595
+ "fsevents": "~2.3.2"
1596
+ }
1597
+ },
1598
+ "node_modules/rxjs": {
1599
+ "version": "7.8.2",
1600
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
1601
+ "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
1602
+ "license": "Apache-2.0",
1603
+ "optional": true,
1604
+ "dependencies": {
1605
+ "tslib": "^2.1.0"
1606
+ }
1607
+ },
1608
+ "node_modules/shallow-clone": {
1609
+ "version": "3.0.1",
1610
+ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
1611
+ "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
1612
+ "license": "MIT",
1613
+ "dependencies": {
1614
+ "kind-of": "^6.0.2"
1615
+ },
1616
+ "engines": {
1617
+ "node": ">=8"
1618
+ }
1619
+ },
1620
+ "node_modules/source-map-js": {
1621
+ "version": "1.2.1",
1622
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
1623
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
1624
+ "dev": true,
1625
+ "license": "BSD-3-Clause",
1626
+ "engines": {
1627
+ "node": ">=0.10.0"
1628
+ }
1629
+ },
1630
+ "node_modules/tinyglobby": {
1631
+ "version": "0.2.14",
1632
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
1633
+ "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==",
1634
+ "dev": true,
1635
+ "license": "MIT",
1636
+ "dependencies": {
1637
+ "fdir": "^6.4.4",
1638
+ "picomatch": "^4.0.2"
1639
+ },
1640
+ "engines": {
1641
+ "node": ">=12.0.0"
1642
+ },
1643
+ "funding": {
1644
+ "url": "https://github.com/sponsors/SuperchupuDev"
1645
+ }
1646
+ },
1647
+ "node_modules/tslib": {
1648
+ "version": "2.8.1",
1649
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
1650
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
1651
+ "license": "0BSD",
1652
+ "optional": true
1653
+ },
1654
+ "node_modules/typed-emitter": {
1655
+ "version": "2.1.0",
1656
+ "resolved": "https://registry.npmjs.org/typed-emitter/-/typed-emitter-2.1.0.tgz",
1657
+ "integrity": "sha512-g/KzbYKbH5C2vPkaXGu8DJlHrGKHLsM25Zg9WuC9pMGfuvT+X25tZQWo5fK1BjBm8+UrVE9LDCvaY0CQk+fXDA==",
1658
+ "license": "MIT",
1659
+ "optionalDependencies": {
1660
+ "rxjs": "*"
1661
+ }
1662
+ },
1663
+ "node_modules/typescript": {
1664
+ "version": "5.8.3",
1665
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
1666
+ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
1667
+ "license": "Apache-2.0",
1668
+ "bin": {
1669
+ "tsc": "bin/tsc",
1670
+ "tsserver": "bin/tsserver"
1671
+ },
1672
+ "engines": {
1673
+ "node": ">=14.17"
1674
+ }
1675
+ },
1676
+ "node_modules/undici-types": {
1677
+ "version": "6.21.0",
1678
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
1679
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
1680
+ "license": "MIT"
1681
+ },
1682
+ "node_modules/uuid": {
1683
+ "version": "10.0.0",
1684
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
1685
+ "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
1686
+ "funding": [
1687
+ "https://github.com/sponsors/broofa",
1688
+ "https://github.com/sponsors/ctavan"
1689
+ ],
1690
+ "license": "MIT",
1691
+ "bin": {
1692
+ "uuid": "dist/bin/uuid"
1693
+ }
1694
+ },
1695
+ "node_modules/vite": {
1696
+ "version": "6.3.5",
1697
+ "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",
1698
+ "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==",
1699
+ "dev": true,
1700
+ "license": "MIT",
1701
+ "dependencies": {
1702
+ "esbuild": "^0.25.0",
1703
+ "fdir": "^6.4.4",
1704
+ "picomatch": "^4.0.2",
1705
+ "postcss": "^8.5.3",
1706
+ "rollup": "^4.34.9",
1707
+ "tinyglobby": "^0.2.13"
1708
+ },
1709
+ "bin": {
1710
+ "vite": "bin/vite.js"
1711
+ },
1712
+ "engines": {
1713
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
1714
+ },
1715
+ "funding": {
1716
+ "url": "https://github.com/vitejs/vite?sponsor=1"
1717
+ },
1718
+ "optionalDependencies": {
1719
+ "fsevents": "~2.3.3"
1720
+ },
1721
+ "peerDependencies": {
1722
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
1723
+ "jiti": ">=1.21.0",
1724
+ "less": "*",
1725
+ "lightningcss": "^1.21.0",
1726
+ "sass": "*",
1727
+ "sass-embedded": "*",
1728
+ "stylus": "*",
1729
+ "sugarss": "*",
1730
+ "terser": "^5.16.0",
1731
+ "tsx": "^4.8.1",
1732
+ "yaml": "^2.4.2"
1733
+ },
1734
+ "peerDependenciesMeta": {
1735
+ "@types/node": {
1736
+ "optional": true
1737
+ },
1738
+ "jiti": {
1739
+ "optional": true
1740
+ },
1741
+ "less": {
1742
+ "optional": true
1743
+ },
1744
+ "lightningcss": {
1745
+ "optional": true
1746
+ },
1747
+ "sass": {
1748
+ "optional": true
1749
+ },
1750
+ "sass-embedded": {
1751
+ "optional": true
1752
+ },
1753
+ "stylus": {
1754
+ "optional": true
1755
+ },
1756
+ "sugarss": {
1757
+ "optional": true
1758
+ },
1759
+ "terser": {
1760
+ "optional": true
1761
+ },
1762
+ "tsx": {
1763
+ "optional": true
1764
+ },
1765
+ "yaml": {
1766
+ "optional": true
1767
+ }
1768
+ }
1769
+ },
1770
+ "node_modules/x-law": {
1771
+ "version": "0.3.1",
1772
+ "resolved": "https://registry.npmjs.org/x-law/-/x-law-0.3.1.tgz",
1773
+ "integrity": "sha512-Nvo6OKj6UL2LuzAc08uJkwIDkK2PsTEdpLiY82NkwMptuRpAA1V7arUl7ZY12BcgRYNq8uh1pdAu7G6VeQn7Hg==",
1774
+ "license": "MIT",
1775
+ "engines": {
1776
+ "node": ">=18"
1777
+ }
1778
+ }
1779
+ }
1780
+ }
client/package.json ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "client",
3
+ "version": "1.0.0",
4
+ "main": "index.js",
5
+ "scripts": {
6
+ "dev": "vite",
7
+ "build": "tsc && vite build",
8
+ "preview": "vite preview"
9
+ },
10
+ "keywords": [],
11
+ "author": "",
12
+ "license": "ISC",
13
+ "description": "",
14
+ "devDependencies": {
15
+ "@types/node": "^22.15.30",
16
+ "@types/protobufjs": "^6.0.0",
17
+ "@vitejs/plugin-react-swc": "^3.10.1",
18
+ "typescript": "^5.8.3",
19
+ "vite": "^6.3.5"
20
+ },
21
+ "dependencies": {
22
+ "@pipecat-ai/client-js": "^0.4.0",
23
+ "@pipecat-ai/websocket-transport": "^0.4.2",
24
+ "protobufjs": "^7.4.0"
25
+ }
26
+ }
client/src/app.ts ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Copyright (c) 2024–2025, Daily
3
+ *
4
+ * SPDX-License-Identifier: BSD 2-Clause License
5
+ */
6
+
7
+ /**
8
+ * RTVI Client Implementation
9
+ *
10
+ * This client connects to an RTVI-compatible bot server using WebSocket.
11
+ *
12
+ * Requirements:
13
+ * - A running RTVI bot server (defaults to http://localhost:7860)
14
+ */
15
+
16
+ import {
17
+ RTVIClient,
18
+ RTVIClientOptions,
19
+ RTVIEvent,
20
+ } from '@pipecat-ai/client-js';
21
+ import {
22
+ WebSocketTransport
23
+ } from "@pipecat-ai/websocket-transport";
24
+
25
+ class WebsocketClientApp {
26
+ private rtviClient: RTVIClient | null = null;
27
+ private connectBtn: HTMLButtonElement | null = null;
28
+ private disconnectBtn: HTMLButtonElement | null = null;
29
+ private statusSpan: HTMLElement | null = null;
30
+ private debugLog: HTMLElement | null = null;
31
+ private botAudio: HTMLAudioElement;
32
+
33
+ constructor() {
34
+ console.log("WebsocketClientApp");
35
+ this.botAudio = document.createElement('audio');
36
+ this.botAudio.autoplay = true;
37
+ //this.botAudio.playsInline = true;
38
+ document.body.appendChild(this.botAudio);
39
+
40
+ this.setupDOMElements();
41
+ this.setupEventListeners();
42
+ }
43
+
44
+ /**
45
+ * Set up references to DOM elements and create necessary media elements
46
+ */
47
+ private setupDOMElements(): void {
48
+ this.connectBtn = document.getElementById('connect-btn') as HTMLButtonElement;
49
+ this.disconnectBtn = document.getElementById('disconnect-btn') as HTMLButtonElement;
50
+ this.statusSpan = document.getElementById('connection-status');
51
+ this.debugLog = document.getElementById('debug-log');
52
+ }
53
+
54
+ /**
55
+ * Set up event listeners for connect/disconnect buttons
56
+ */
57
+ private setupEventListeners(): void {
58
+ this.connectBtn?.addEventListener('click', () => this.connect());
59
+ this.disconnectBtn?.addEventListener('click', () => this.disconnect());
60
+ }
61
+
62
+ /**
63
+ * Add a timestamped message to the debug log
64
+ */
65
+ private log(message: string): void {
66
+ if (!this.debugLog) return;
67
+ const entry = document.createElement('div');
68
+ entry.textContent = `${new Date().toISOString()} - ${message}`;
69
+ if (message.startsWith('User: ')) {
70
+ entry.style.color = '#2196F3';
71
+ } else if (message.startsWith('Bot: ')) {
72
+ entry.style.color = '#4CAF50';
73
+ }
74
+ this.debugLog.appendChild(entry);
75
+ this.debugLog.scrollTop = this.debugLog.scrollHeight;
76
+ console.log(message);
77
+ }
78
+
79
+ /**
80
+ * Update the connection status display
81
+ */
82
+ private updateStatus(status: string): void {
83
+ if (this.statusSpan) {
84
+ this.statusSpan.textContent = status;
85
+ }
86
+ this.log(`Status: ${status}`);
87
+ }
88
+
89
+ /**
90
+ * Check for available media tracks and set them up if present
91
+ * This is called when the bot is ready or when the transport state changes to ready
92
+ */
93
+ setupMediaTracks() {
94
+ if (!this.rtviClient) return;
95
+ const tracks = this.rtviClient.tracks();
96
+ if (tracks.bot?.audio) {
97
+ this.setupAudioTrack(tracks.bot.audio);
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Set up listeners for track events (start/stop)
103
+ * This handles new tracks being added during the session
104
+ */
105
+ setupTrackListeners() {
106
+ if (!this.rtviClient) return;
107
+
108
+ // Listen for new tracks starting
109
+ this.rtviClient.on(RTVIEvent.TrackStarted, (track, participant) => {
110
+ // Only handle non-local (bot) tracks
111
+ if (!participant?.local && track.kind === 'audio') {
112
+ this.setupAudioTrack(track);
113
+ }
114
+ });
115
+
116
+ // Listen for tracks stopping
117
+ this.rtviClient.on(RTVIEvent.TrackStopped, (track, participant) => {
118
+ this.log(`Track stopped: ${track.kind} from ${participant?.name || 'unknown'}`);
119
+ });
120
+ }
121
+
122
+ /**
123
+ * Set up an audio track for playback
124
+ * Handles both initial setup and track updates
125
+ */
126
+ private setupAudioTrack(track: MediaStreamTrack): void {
127
+ this.log('Setting up audio track');
128
+ if (this.botAudio.srcObject && "getAudioTracks" in this.botAudio.srcObject) {
129
+ const oldTrack = this.botAudio.srcObject.getAudioTracks()[0];
130
+ if (oldTrack?.id === track.id) return;
131
+ }
132
+ this.botAudio.srcObject = new MediaStream([track]);
133
+ }
134
+
135
+ /**
136
+ * Initialize and connect to the bot
137
+ * This sets up the RTVI client, initializes devices, and establishes the connection
138
+ */
139
+ public async connect(): Promise<void> {
140
+ try {
141
+ const startTime = Date.now();
142
+
143
+ //const transport = new DailyTransport();
144
+ const transport = new WebSocketTransport();
145
+ const RTVIConfig: RTVIClientOptions = {
146
+ transport,
147
+ params: {
148
+ // The baseURL and endpoint of your bot server that the client will connect to
149
+ baseUrl: '',
150
+ // baseUrl: 'http://localhost:7860',
151
+ endpoints: { connect: '/connect' },
152
+ headers: new Headers( {
153
+ "Authorization": "Bearer 72dc0bce-f2da-4585-a6df-6f1160980dc0"
154
+ })
155
+ },
156
+ enableMic: true,
157
+ enableCam: false,
158
+ callbacks: {
159
+ onConnected: () => {
160
+ this.updateStatus('Connected');
161
+ if (this.connectBtn) this.connectBtn.disabled = true;
162
+ if (this.disconnectBtn) this.disconnectBtn.disabled = false;
163
+ },
164
+ onDisconnected: () => {
165
+ this.updateStatus('Disconnected');
166
+ if (this.connectBtn) this.connectBtn.disabled = false;
167
+ if (this.disconnectBtn) this.disconnectBtn.disabled = true;
168
+ this.log('Client disconnected');
169
+ },
170
+ onBotReady: (data) => {
171
+ this.log(`Bot ready: ${JSON.stringify(data)}`);
172
+ this.setupMediaTracks();
173
+ },
174
+ onUserTranscript: (data) => {
175
+ if (data.final) {
176
+ this.log(`User: ${data.text}`);
177
+ }
178
+ },
179
+ onBotTranscript: (data) => this.log(`Bot: ${data.text}`),
180
+ onMessageError: (error) => console.error('Message error:', error),
181
+ onError: (error) => console.error('Error:', error),
182
+ },
183
+ }
184
+ this.rtviClient = new RTVIClient(RTVIConfig);
185
+ this.setupTrackListeners();
186
+
187
+ this.log('Initializing devices...');
188
+ await this.rtviClient.initDevices();
189
+
190
+ this.log('Connecting to bot...');
191
+ await this.rtviClient.connect();
192
+
193
+ const timeTaken = Date.now() - startTime;
194
+ this.log(`Connection complete, timeTaken: ${timeTaken}`);
195
+ } catch (error) {
196
+ this.log(`Error connecting: ${(error as Error).message}`);
197
+ this.updateStatus('Error');
198
+ // Clean up if there's an error
199
+ if (this.rtviClient) {
200
+ try {
201
+ await this.rtviClient.disconnect();
202
+ } catch (disconnectError) {
203
+ this.log(`Error during disconnect: ${disconnectError}`);
204
+ }
205
+ }
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Disconnect from the bot and clean up media resources
211
+ */
212
+ public async disconnect(): Promise<void> {
213
+ if (this.rtviClient) {
214
+ try {
215
+ await this.rtviClient.disconnect();
216
+ this.rtviClient = null;
217
+ if (this.botAudio.srcObject && "getAudioTracks" in this.botAudio.srcObject) {
218
+ this.botAudio.srcObject.getAudioTracks().forEach((track) => track.stop());
219
+ this.botAudio.srcObject = null;
220
+ }
221
+ } catch (error) {
222
+ this.log(`Error disconnecting: ${(error as Error).message}`);
223
+ }
224
+ }
225
+ }
226
+
227
+ }
228
+
229
+ declare global {
230
+ interface Window {
231
+ WebsocketClientApp: typeof WebsocketClientApp;
232
+ }
233
+ }
234
+
235
+ window.addEventListener('DOMContentLoaded', () => {
236
+ window.WebsocketClientApp = WebsocketClientApp;
237
+ new WebsocketClientApp();
238
+ });
client/src/style.css ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ margin: 0;
3
+ padding: 20px;
4
+ font-family: Arial, sans-serif;
5
+ background-color: #f0f0f0;
6
+ }
7
+
8
+ .container {
9
+ max-width: 1200px;
10
+ margin: 0 auto;
11
+ }
12
+
13
+ .status-bar {
14
+ display: flex;
15
+ justify-content: space-between;
16
+ align-items: center;
17
+ padding: 10px;
18
+ background-color: #fff;
19
+ border-radius: 8px;
20
+ margin-bottom: 20px;
21
+ }
22
+
23
+ .controls button {
24
+ padding: 8px 16px;
25
+ margin-left: 10px;
26
+ border: none;
27
+ border-radius: 4px;
28
+ cursor: pointer;
29
+ }
30
+
31
+ #connect-btn {
32
+ background-color: #4caf50;
33
+ color: white;
34
+ }
35
+
36
+ #disconnect-btn {
37
+ background-color: #f44336;
38
+ color: white;
39
+ }
40
+
41
+ button:disabled {
42
+ opacity: 0.5;
43
+ cursor: not-allowed;
44
+ }
45
+
46
+ .main-content {
47
+ background-color: #fff;
48
+ border-radius: 8px;
49
+ padding: 20px;
50
+ margin-bottom: 20px;
51
+ }
52
+
53
+ .bot-container {
54
+ display: flex;
55
+ flex-direction: column;
56
+ align-items: center;
57
+ }
58
+
59
+ #bot-video-container {
60
+ width: 640px;
61
+ height: 360px;
62
+ background-color: #e0e0e0;
63
+ border-radius: 8px;
64
+ margin: 20px auto;
65
+ overflow: hidden;
66
+ display: flex;
67
+ align-items: center;
68
+ justify-content: center;
69
+ }
70
+
71
+ #bot-video-container video {
72
+ width: 100%;
73
+ height: 100%;
74
+ object-fit: cover;
75
+ }
76
+
77
+ .debug-panel {
78
+ background-color: #fff;
79
+ border-radius: 8px;
80
+ padding: 20px;
81
+ }
82
+
83
+ .debug-panel h3 {
84
+ margin: 0 0 10px 0;
85
+ font-size: 16px;
86
+ font-weight: bold;
87
+ }
88
+
89
+ #debug-log {
90
+ height: 500px;
91
+ overflow-y: auto;
92
+ background-color: #f8f8f8;
93
+ padding: 10px;
94
+ border-radius: 4px;
95
+ font-family: monospace;
96
+ font-size: 12px;
97
+ line-height: 1.4;
98
+ }
client/tsconfig.json ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ /* Visit https://aka.ms/tsconfig to read more about this file */
4
+
5
+ /* Projects */
6
+ // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
7
+ // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
8
+ // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
9
+ // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
10
+ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
11
+ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
12
+
13
+ /* Language and Environment */
14
+ "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
15
+ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
16
+ // "jsx": "preserve", /* Specify what JSX code is generated. */
17
+ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
18
+ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
19
+ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
20
+ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
21
+ // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
22
+ // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
23
+ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
24
+ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
25
+ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
26
+
27
+ /* Modules */
28
+ "module": "commonjs", /* Specify what module code is generated. */
29
+ // "rootDir": "./", /* Specify the root folder within your source files. */
30
+ // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
31
+ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
32
+ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
33
+ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
34
+ // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
35
+ // "types": [], /* Specify type package names to be included without being referenced in a source file. */
36
+ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
37
+ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
38
+ // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
39
+ // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */
40
+ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
41
+ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
42
+ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
43
+ // "noUncheckedSideEffectImports": true, /* Check side effect imports. */
44
+ // "resolveJsonModule": true, /* Enable importing .json files. */
45
+ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
46
+ // "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
47
+
48
+ /* JavaScript Support */
49
+ // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
50
+ // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
51
+ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
52
+
53
+ /* Emit */
54
+ // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
55
+ // "declarationMap": true, /* Create sourcemaps for d.ts files. */
56
+ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
57
+ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
58
+ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
59
+ // "noEmit": true, /* Disable emitting files from a compilation. */
60
+ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
61
+ // "outDir": "./", /* Specify an output folder for all emitted files. */
62
+ // "removeComments": true, /* Disable emitting comments. */
63
+ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
64
+ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
65
+ // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
66
+ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
67
+ // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
68
+ // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
69
+ // "newLine": "crlf", /* Set the newline character for emitting files. */
70
+ // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
71
+ // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
72
+ // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
73
+ // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
74
+ // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
75
+
76
+ /* Interop Constraints */
77
+ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
78
+ // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
79
+ // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
80
+ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
81
+ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
82
+ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
83
+ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
84
+
85
+ /* Type Checking */
86
+ "strict": true, /* Enable all strict type-checking options. */
87
+ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
88
+ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
89
+ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
90
+ // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
91
+ // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
92
+ // "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */
93
+ // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
94
+ // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
95
+ // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
96
+ // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
97
+ // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
98
+ // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
99
+ // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
100
+ // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
101
+ // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
102
+ // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
103
+ // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
104
+ // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
105
+ // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
106
+
107
+ /* Completeness */
108
+ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
109
+ "skipLibCheck": true /* Skip type checking all .d.ts files. */
110
+ }
111
+ }
client/vite.config.js ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { defineConfig } from 'vite';
2
+ import react from '@vitejs/plugin-react-swc';
3
+
4
+ export default defineConfig({
5
+ plugins: [react()],
6
+ server: {
7
+ proxy: {
8
+ // Proxy /api requests to the backend server
9
+ '/connect': {
10
+ target: 'http://0.0.0.0:7860', // Replace with your backend URL
11
+ changeOrigin: true,
12
+ },
13
+ },
14
+ },
15
+ });
env.example ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ WEBSOCKET_SERVER=websocket_server # Options: 'fast_api' or 'websocket_server'
2
+
3
+
4
+
5
+ sudo docker run \
6
+ -e COQUI_TOS_AGREED=1 \
7
+ --rm \
8
+ -p 8000:80 \
9
+ ghcr.io/coqui-ai/xtts-streaming-server:latest-cpu
10
+
11
+
pyproject.toml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [project]
2
+ name = "voiceagentstack"
3
+ version = "0.1.0"
4
+ description = "Add your description here"
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ dependencies = [
8
+ "fastapi>=0.115.13",
9
+ "kokoro-onnx>=0.3.3",
10
+ "orpheus-speech>=0.1.0",
11
+ "pipecat-ai[fish,ollama,websocket,whisper]>=0.0.71",
12
+ "python-dotenv>=1.1.0",
13
+ "uvicorn>=0.34.3",
14
+ ]
requirements.txt ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Core
2
+ fastapi>=0.115.13
3
+ uvicorn>=0.34.3
4
+ python-dotenv>=1.1.0
5
+
6
+ # Pipecat with multiple extras
7
+ pipecat-ai[fish,ollama,webrtc,websocket,whisper,deepgram,openai]>=0.0.71
8
+
9
+ # Orpheus and Kokoro
10
+ orpheus-speech>=0.1.0
11
+ kokoro-onnx>=0.3.3
12
+ chatterbox-tts
server.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # main.py
2
+ import asyncio
3
+ import os
4
+ from contextlib import asynccontextmanager
5
+ from typing import Any, Dict
6
+
7
+ import uvicorn
8
+ from dotenv import load_dotenv
9
+ from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect
10
+ from fastapi.middleware.cors import CORSMiddleware
11
+ from fastapi.staticfiles import StaticFiles
12
+
13
+ from bot.bot_websocket_server import run_bot_websocket_server
14
+
15
+ load_dotenv(override=True)
16
+
17
+ @asynccontextmanager
18
+ async def lifespan(app: FastAPI):
19
+ yield # Handle startup/shutdown
20
+
21
+ app = FastAPI(lifespan=lifespan)
22
+
23
+ app.add_middleware(
24
+ CORSMiddleware,
25
+ allow_origins=["*"],
26
+ allow_credentials=True,
27
+ allow_methods=["*"],
28
+ allow_headers=["*"],
29
+ )
30
+
31
+ @app.websocket("/ws")
32
+ async def websocket_endpoint(websocket: WebSocket):
33
+ await websocket.accept()
34
+ print("WebSocket connection accepted")
35
+ try:
36
+ await run_bot_websocket_server(websocket) # Just the handler, not a server
37
+ except WebSocketDisconnect:
38
+ print("WebSocket disconnected")
39
+ except Exception as e:
40
+ print(f"Error in WebSocket handler: {e}")
41
+
42
+ @app.post("/connect")
43
+ async def bot_connect(request: Request) -> Dict[Any, Any]:
44
+ proto = "ws"
45
+ if "x-forwarded-proto" in request.headers and request.headers["x-forwarded-proto"] == "https":
46
+ proto = "wss"
47
+
48
+ host = request.headers.get("host", "localhost:7860")
49
+
50
+ return {"ws_url": f"{proto}://{host}/ws"}
51
+
52
+ app.mount("/", StaticFiles(directory="static", html=True), name="static")
53
+
54
+ if __name__ == "__main__":
55
+ uvicorn.run("server:app", host="0.0.0.0", port=7860, reload=False)
service/Dia/tts.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ from typing import AsyncGenerator
3
+
4
+ import numpy as np
5
+ import torch
6
+ from dia.model import Dia
7
+ from loguru import logger
8
+ from pydantic import BaseModel, Field
9
+
10
+ from pipecat.frames.frames import (
11
+ ErrorFrame,
12
+ Frame,
13
+ TTSAudioRawFrame,
14
+ TTSStartedFrame,
15
+ TTSStoppedFrame,
16
+ )
17
+ from pipecat.services.tts_service import TTSService
18
+
19
+
20
+ class DiaTTSService(TTSService):
21
+ """TTS service for Dia.
22
+ This service uses Dia to generate speech.
23
+ It does not support streaming and will generate the entire audio at once.
24
+ """
25
+
26
+ class InputParams(BaseModel):
27
+ """Configuration parameters for Dia TTS service."""
28
+
29
+ use_torch_compile: bool = Field(False)
30
+ verbose: bool = Field(False)
31
+
32
+ def __init__(
33
+ self,
34
+ *,
35
+ model_name: str = "nari-labs/Dia-1.6B",
36
+ compute_dtype: str = "float32",
37
+ device: str = "cpu",
38
+ sample_rate: int = 24000,
39
+ params: InputParams = InputParams(),
40
+ **kwargs,
41
+ ):
42
+ """Initialize Dia TTS service."""
43
+ super().__init__(sample_rate=sample_rate, **kwargs)
44
+ logger.info(f"Initializing Dia TTS service with model: {model_name}")
45
+
46
+ torch_device = torch.device(device)
47
+
48
+ self._model = Dia.from_pretrained(
49
+ model_name, compute_dtype=compute_dtype, device=torch_device
50
+ )
51
+ self._settings = params.dict()
52
+ logger.info("Dia TTS service initialized")
53
+
54
+ def can_generate_metrics(self) -> bool:
55
+ return True
56
+
57
+ async def run_tts(self, text: str) -> AsyncGenerator[Frame, None]:
58
+ logger.debug(f"Generating TTS for: [{text}]")
59
+ try:
60
+ await self.start_ttfb_metrics()
61
+ yield TTSStartedFrame()
62
+
63
+ loop = asyncio.get_running_loop()
64
+
65
+ await self.start_tts_usage_metrics(text)
66
+
67
+ output = await loop.run_in_executor(
68
+ None,
69
+ self._model.generate,
70
+ text,
71
+ self._settings["use_torch_compile"],
72
+ self._settings["verbose"],
73
+ )
74
+
75
+ audio_tensor = output["audio_tensor"]
76
+
77
+ # The tensor is float32 in range [-1, 1], shape (1, N).
78
+ # Convert to int16 bytes for pipecat.
79
+ audio_data = (audio_tensor.cpu().numpy() * 32767).astype(np.int16).tobytes()
80
+
81
+ yield TTSAudioRawFrame(
82
+ audio=audio_data,
83
+ sample_rate=self.sample_rate,
84
+ num_channels=1,
85
+ )
86
+
87
+ yield TTSStoppedFrame()
88
+ except Exception as e:
89
+ logger.error(f"{self} exception: {e}", exc_info=True)
90
+ yield ErrorFrame(f"Error generating audio: {str(e)}")
service/Kokoro/__init__.py ADDED
File without changes
service/Kokoro/tts.py ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #
2
+ # Copyright (c) 2024–2025, Daily
3
+ #
4
+ # SPDX-License-Identifier: BSD 2-Clause License
5
+ #
6
+ # This code originally written by Marmik Pandya (marmikcfc - github.com/marmikcfc)
7
+
8
+
9
+ import numpy as np
10
+ from typing import AsyncGenerator, List, Optional, Union
11
+
12
+ from loguru import logger
13
+ from pydantic import BaseModel
14
+
15
+ from pipecat.frames.frames import (
16
+ ErrorFrame,
17
+ Frame,
18
+ TTSAudioRawFrame,
19
+ TTSStartedFrame,
20
+ TTSStoppedFrame,
21
+ )
22
+ from pipecat.services.tts_service import TTSService
23
+ from pipecat.transcriptions.language import Language
24
+
25
+ # load Kokoro from kokoro-onnx
26
+ try:
27
+ from kokoro_onnx import Kokoro
28
+ except ModuleNotFoundError as e:
29
+ logger.error(f"Exception: {e}")
30
+ logger.error(
31
+ "In order to use Kokoro, you need to `pip install kokoro-onnx`. Also, download the model files from the Kokoro repository."
32
+ )
33
+ raise Exception(f"Missing module: {e}")
34
+
35
+
36
+ def language_to_kokoro_language(language: Language) -> Optional[str]:
37
+ """Convert pipecat Language to Kokoro language code."""
38
+ BASE_LANGUAGES = {
39
+ Language.EN: "en-us",
40
+ Language.FR: "fr-fr",
41
+ Language.IT: "it",
42
+ Language.JA: "ja",
43
+ Language.CMN: "cmn"
44
+ # Add more language mappings as supported by Kokoro
45
+ }
46
+
47
+ result = BASE_LANGUAGES.get(language)
48
+
49
+ # If not found in base languages, try to find the base language from a variant
50
+ if not result:
51
+ lang_str = str(language.value)
52
+ base_code = lang_str.split("-")[0].lower()
53
+ # Look up the base code in our supported languages
54
+ result = f"{base_code}-us" if base_code in ["en"] else None
55
+
56
+ return result
57
+
58
+
59
+ class KokoroTTSService(TTSService):
60
+ """Text-to-Speech service using Kokoro for on-device TTS.
61
+
62
+ This service uses Kokoro to generate speech without requiring external API connections.
63
+ """
64
+ class InputParams(BaseModel):
65
+ """Configuration parameters for Kokoro TTS service."""
66
+ language: Optional[Language] = Language.EN
67
+ speed: Optional[float] = 1.0
68
+
69
+ def __init__(
70
+ self,
71
+ *,
72
+ model_path: str,
73
+ voices_path: str,
74
+ voice_id: str = "af_sarah",
75
+ sample_rate: Optional[int] = None,
76
+ params: InputParams = InputParams(),
77
+ **kwargs,
78
+ ):
79
+ """Initialize Kokoro TTS service.
80
+
81
+ Args:
82
+ model_path: Path to the Kokoro ONNX model file
83
+ voices_path: Path to the Kokoro voices file
84
+ voice_id: ID of the voice to use
85
+ sample_rate: Output audio sample rate
86
+ params: Additional configuration parameters
87
+ """
88
+ super().__init__(sample_rate=sample_rate, **kwargs)
89
+ logger.info(f"Initializing Kokoro TTS service with model_path: {model_path} and voices_path: {voices_path}")
90
+ self._kokoro = Kokoro(model_path, voices_path)
91
+ logger.info(f"Kokoro initialized")
92
+ self._settings = {
93
+ "language": self.language_to_service_language(params.language)
94
+ if params.language
95
+ else "en-us",
96
+ "speed": params.speed,
97
+ }
98
+ self.set_voice(voice_id) # Presumably this sets self._voice_id
99
+
100
+ logger.info("Kokoro TTS service initialized")
101
+
102
+ def can_generate_metrics(self) -> bool:
103
+ return True
104
+
105
+ def language_to_service_language(self, language: Language) -> Optional[str]:
106
+ """Convert pipecat language to Kokoro language code."""
107
+ return language_to_kokoro_language(language)
108
+
109
+ async def run_tts(self, text: str) -> AsyncGenerator[Frame, None]:
110
+ """Generate speech from text using Kokoro in a streaming fashion.
111
+
112
+ Args:
113
+ text: The text to convert to speech
114
+
115
+ Yields:
116
+ Frames containing audio data and status information.
117
+ """
118
+ logger.debug(f"Generating TTS: [{text}]")
119
+ try:
120
+ await self.start_ttfb_metrics()
121
+ yield TTSStartedFrame()
122
+
123
+ # Use Kokoro's streaming mode. The create_stream method is assumed to return
124
+ # an async generator that yields (samples, sample_rate) tuples, where samples is a numpy array.
125
+ logger.info(f"Creating stream")
126
+ stream = self._kokoro.create_stream(
127
+ text,
128
+ voice=self._voice_id,
129
+ speed=self._settings["speed"],
130
+ lang=self._settings["language"],
131
+ )
132
+
133
+
134
+ await self.start_tts_usage_metrics(text)
135
+ started = False
136
+ async for samples, sample_rate in stream:
137
+ if not started:
138
+ started = True
139
+ logger.info(f"Started streaming")
140
+ logger.info(f"Started streaming")
141
+ logger.info(f"Started streaming")
142
+ logger.info(f"Started streaming")
143
+ logger.info(f"Started streaming")
144
+ logger.info(f"Started streaming")
145
+ logger.info(f"Started streaming")
146
+ logger.info(f"Started streaming")
147
+ logger.info(f"Started streaming")
148
+ logger.info(f"Started streaming")
149
+ logger.info(f"Started streaming")
150
+ logger.info(f"Started streaming")
151
+ logger.info(f"Started streaming")
152
+ logger.info(f"Started streaming")
153
+ logger.info(f"Started streaming")
154
+ logger.info(f"Started streaming")
155
+ logger.info(f"Started streaming")
156
+ logger.info(f"Started streaming")
157
+ # Convert the float32 samples (assumed in the range [-1, 1]) to int16 PCM format
158
+ samples_int16 = (samples * 32767).astype(np.int16)
159
+ yield TTSAudioRawFrame(
160
+ audio=samples_int16.tobytes(),
161
+ sample_rate=sample_rate,
162
+ num_channels=1,
163
+ )
164
+
165
+ yield TTSStoppedFrame()
166
+
167
+ except Exception as e:
168
+ logger.error(f"{self} exception: {e}")
169
+ yield ErrorFrame(f"Error generating audio: {str(e)}")
service/chatterbot/__init__.py ADDED
File without changes
service/chatterbot/tts.py ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import base64
3
+ import re
4
+ import tempfile
5
+ from typing import AsyncGenerator, Optional, List
6
+
7
+ import aiohttp
8
+ import numpy as np
9
+ import torchaudio as ta
10
+ from chatterbox.tts import ChatterboxTTS
11
+ from loguru import logger
12
+ from pydantic import BaseModel, Field
13
+
14
+ from pipecat.frames.frames import (
15
+ ErrorFrame,
16
+ Frame,
17
+ TTSAudioRawFrame,
18
+ TTSStartedFrame,
19
+ TTSStoppedFrame,
20
+ )
21
+ from pipecat.services.tts_service import TTSService
22
+ from pipecat.transcriptions.language import Language
23
+
24
+
25
+ class ChatterboxTTSService(TTSService):
26
+ """Text-to-Speech service using Chatterbox for on-device TTS.
27
+
28
+ This service uses Chatterbox to generate speech. It supports voice cloning
29
+ from an audio prompt.
30
+ """
31
+
32
+ class InputParams(BaseModel):
33
+ """Configuration parameters for Chatterbox TTS service."""
34
+
35
+ audio_prompt: Optional[str] = Field(
36
+ None, description="URL or file path to an audio prompt for voice cloning."
37
+ )
38
+ exaggeration: float = Field(0.5, ge=0.0, le=1.0)
39
+ cfg: float = Field(0.5, ge=0.0, le=1.0)
40
+ temperature: float = Field(0.8, ge=0.0, le=1.0)
41
+
42
+ def __init__(
43
+ self,
44
+ *,
45
+ device: str = "cpu",
46
+ params: InputParams = InputParams(),
47
+ **kwargs,
48
+ ):
49
+ """Initialize Chatterbox TTS service.
50
+
51
+ Args:
52
+ device: The device to run the model on (e.g., "cpu", "cuda").
53
+ params: Configuration parameters for TTS generation.
54
+ """
55
+ super().__init__(**kwargs)
56
+ logger.info(f"Initializing Chatterbox TTS service on device: {device}")
57
+ self._model = ChatterboxTTS.from_pretrained(device=device)
58
+ self._sample_rate = self._model.sr
59
+ self._settings = params.dict()
60
+ self._temp_files: List[str] = []
61
+ logger.info("Chatterbox TTS service initialized")
62
+
63
+ def __del__(self):
64
+ self._cleanup_temp_files()
65
+
66
+ def can_generate_metrics(self) -> bool:
67
+ return True
68
+
69
+ def language_to_service_language(self, language: Language) -> Optional[str]:
70
+ """Returns the language code for Chatterbox TTS. Only English is supported."""
71
+ if language.value.startswith("en"):
72
+ return "en"
73
+ logger.warning(
74
+ f"Chatterbox TTS only supports English, but got {language}. Defaulting to English."
75
+ )
76
+ return "en"
77
+
78
+ async def _handle_audio_prompt(self, audio_prompt: str) -> Optional[str]:
79
+ if re.match(r"^https?://", audio_prompt):
80
+ try:
81
+ async with aiohttp.ClientSession() as session:
82
+ async with session.get(audio_prompt) as resp:
83
+ resp.raise_for_status()
84
+ content = await resp.read()
85
+ tmp_file = tempfile.NamedTemporaryFile(
86
+ delete=False, suffix=".wav"
87
+ )
88
+ tmp_file.write(content)
89
+ tmp_file.close()
90
+ self._temp_files.append(tmp_file.name)
91
+ return tmp_file.name
92
+ except Exception as e:
93
+ logger.error(f"Error downloading audio prompt from URL: {e}")
94
+ return None
95
+ return audio_prompt
96
+
97
+ def _cleanup_temp_files(self):
98
+ import os
99
+
100
+ for temp_file in self._temp_files:
101
+ try:
102
+ if os.path.exists(temp_file):
103
+ os.unlink(temp_file)
104
+ except OSError as e:
105
+ logger.warning(f"Error cleaning up temp file {temp_file}: {e}")
106
+ self._temp_files.clear()
107
+
108
+ async def run_tts(self, text: str) -> AsyncGenerator[Frame, None]:
109
+ """Generate speech from text using Chatterbox."""
110
+ logger.debug(f"Generating TTS for: [{text}]")
111
+
112
+ try:
113
+ await self.start_ttfb_metrics()
114
+ yield TTSStartedFrame()
115
+
116
+ audio_prompt_path = self._settings.get("audio_prompt")
117
+ if audio_prompt_path:
118
+ audio_prompt_path = await self._handle_audio_prompt(audio_prompt_path)
119
+
120
+ await self.start_tts_usage_metrics(text)
121
+
122
+ loop = asyncio.get_running_loop()
123
+ wav = await loop.run_in_executor(
124
+ None,
125
+ self._model.generate,
126
+ text,
127
+ audio_prompt_path,
128
+ self._settings["exaggeration"],
129
+ self._settings["cfg"],
130
+ self._settings["temperature"],
131
+ )
132
+
133
+ audio_data = (wav.cpu().numpy() * 32767).astype(np.int16).tobytes()
134
+ yield TTSAudioRawFrame(
135
+ audio=audio_data,
136
+ sample_rate=self._sample_rate,
137
+ num_channels=1,
138
+ )
139
+
140
+ yield TTSStoppedFrame()
141
+ except Exception as e:
142
+ logger.error(f"{self} exception: {e}", exc_info=True)
143
+ yield ErrorFrame(f"Error generating audio: {e}")
144
+ finally:
145
+ self._cleanup_temp_files()
146
+
service/orpheus/tts.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ from queue import Queue
3
+ from threading import Thread
4
+ from typing import AsyncGenerator, List, Optional
5
+
6
+ from loguru import logger
7
+ from orpheus_tts import OrpheusModel
8
+ from pydantic import BaseModel, Field
9
+
10
+ from pipecat.frames.frames import (
11
+ ErrorFrame,
12
+ Frame,
13
+ TTSAudioRawFrame,
14
+ TTSStartedFrame,
15
+ TTSStoppedFrame,
16
+ )
17
+ from pipecat.services.tts_service import TTSService
18
+
19
+
20
+ class OrpheusTTSService(TTSService):
21
+ """TTS service for Orpheus.
22
+
23
+ This service uses Orpheus to generate speech. It streams the audio chunks.
24
+ """
25
+
26
+ class InputParams(BaseModel):
27
+ """Configuration parameters for Orpheus TTS service."""
28
+
29
+ voice: str = Field("tara", description="Voice to use for generation.")
30
+ repetition_penalty: Optional[float] = Field(1.1)
31
+ stop_token_ids: Optional[List[int]] = Field([128258])
32
+ max_tokens: Optional[int] = Field(2000)
33
+ temperature: Optional[float] = Field(0.4)
34
+ top_p: Optional[float] = Field(0.9)
35
+
36
+ def __init__(
37
+ self,
38
+ *,
39
+ model_name: str = "canopylabs/orpheus-tts-0.1-finetune-prod",
40
+ sample_rate: int = 24000,
41
+ params: InputParams = InputParams(),
42
+ **kwargs,
43
+ ):
44
+ """Initialize Orpheus TTS service.
45
+
46
+ Args:
47
+ model_name: The name of the Orpheus model to use.
48
+ sample_rate: The sample rate of the audio.
49
+ params: Configuration parameters for TTS generation.
50
+ """
51
+ super().__init__(sample_rate=sample_rate, **kwargs)
52
+ logger.info(f"Initializing Orpheus TTS service with model: {model_name}")
53
+ self._model = OrpheusModel(model_name=model_name)
54
+ self._settings = params.dict()
55
+ logger.info("Orpheus TTS service initialized")
56
+
57
+ def can_generate_metrics(self) -> bool:
58
+ return True
59
+
60
+ async def run_tts(self, text: str) -> AsyncGenerator[Frame, None]:
61
+ logger.debug(f"Generating TTS for: [{text}]")
62
+ try:
63
+ await self.start_ttfb_metrics()
64
+ yield TTSStartedFrame()
65
+
66
+ loop = asyncio.get_running_loop()
67
+ q = Queue()
68
+
69
+ def generate():
70
+ try:
71
+ stream = self._model.generate_speech(
72
+ prompt=text,
73
+ voice=self._settings["voice"],
74
+ repetition_penalty=self._settings["repetition_penalty"],
75
+ stop_token_ids=self._settings["stop_token_ids"],
76
+ max_tokens=self._settings["max_tokens"],
77
+ temperature=self._settings["temperature"],
78
+ top_p=self._settings["top_p"],
79
+ )
80
+ for chunk in stream:
81
+ q.put(chunk)
82
+ except Exception as e:
83
+ logger.error(
84
+ f"Error in Orpheus generate_speech thread: {e}", exc_info=True
85
+ )
86
+ q.put(e)
87
+ finally:
88
+ q.put(None) # Sentinel to indicate end of stream
89
+
90
+ thread = Thread(target=generate)
91
+ thread.start()
92
+
93
+ await self.start_tts_usage_metrics(text)
94
+
95
+ while True:
96
+ item = await loop.run_in_executor(None, q.get)
97
+ if isinstance(item, Exception):
98
+ raise item
99
+ if item is None:
100
+ break
101
+
102
+ yield TTSAudioRawFrame(
103
+ audio=item, sample_rate=self.sample_rate, num_channels=1
104
+ )
105
+
106
+ thread.join()
107
+
108
+ yield TTSStoppedFrame()
109
+ except Exception as e:
110
+ logger.error(f"{self} exception: {e}", exc_info=True)
111
+ yield ErrorFrame(f"Error generating audio: {str(e)}")
uv.lock ADDED
The diff for this file is too large to render. See raw diff