livekit-plugins-groq 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- livekit/plugins/groq/__init__.py +30 -0
- livekit/plugins/groq/log.py +3 -0
- livekit/plugins/groq/models.py +54 -0
- livekit/plugins/groq/services.py +80 -0
- livekit/plugins/groq/tts.py +212 -0
- livekit/plugins/groq/version.py +15 -0
- livekit_plugins_groq-0.1.1.dist-info/METADATA +47 -0
- livekit_plugins_groq-0.1.1.dist-info/RECORD +10 -0
- livekit_plugins_groq-0.1.1.dist-info/WHEEL +5 -0
- livekit_plugins_groq-0.1.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Copyright 2023 LiveKit, Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from livekit.agents import Plugin
|
|
16
|
+
|
|
17
|
+
from .log import logger
|
|
18
|
+
from .services import LLM, STT
|
|
19
|
+
from .tts import TTS
|
|
20
|
+
from .version import __version__
|
|
21
|
+
|
|
22
|
+
__all__ = ["TTS", "LLM", "STT", "__version__"]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class GroqPlugin(Plugin):
|
|
26
|
+
def __init__(self):
|
|
27
|
+
super().__init__(__name__, __version__, __package__, logger)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
Plugin.register_plugin(GroqPlugin())
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from typing import Literal
|
|
2
|
+
|
|
3
|
+
# listing production models from https://console.groq.com/docs/models
|
|
4
|
+
|
|
5
|
+
STTModels = Literal[
|
|
6
|
+
"whisper-large-v3",
|
|
7
|
+
"whisper-large-v3-turbo",
|
|
8
|
+
"distil-whisper-large-v3-en",
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
LLMModels = Literal[
|
|
12
|
+
"llama3-8b-8192",
|
|
13
|
+
"llama3-70b-8192",
|
|
14
|
+
"llama-guard-3-8b",
|
|
15
|
+
"llama-3.1-8b-instant",
|
|
16
|
+
"llama-3.3-70b-versatile",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
TTSModels = Literal[
|
|
20
|
+
"playai-tts",
|
|
21
|
+
"playai-tts-arabic",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
TTSVoices = Literal[
|
|
25
|
+
"Aaliyah-PlayAI",
|
|
26
|
+
"Abigail-PlayAI",
|
|
27
|
+
"Angelo-PlayAI",
|
|
28
|
+
"Arthur-PlayAI",
|
|
29
|
+
"Aurora-PlayAI",
|
|
30
|
+
"Autumn-PlayAI",
|
|
31
|
+
"Ayla-Meditation-PlayAI",
|
|
32
|
+
"Ayla-Advertising-PlayAI",
|
|
33
|
+
"Bryan-PlayAI",
|
|
34
|
+
"Chuck-PlayAI",
|
|
35
|
+
"Darrell-PlayAI",
|
|
36
|
+
"Dexter-PlayAI",
|
|
37
|
+
"Donovan-PlayAI",
|
|
38
|
+
"Eileen-PlayAI",
|
|
39
|
+
"Eleanor-PlayAI",
|
|
40
|
+
"Erasmo-PlayAI",
|
|
41
|
+
"Hudson-PlayAI",
|
|
42
|
+
"Inara-PlayAI",
|
|
43
|
+
"Luna-PlayAI",
|
|
44
|
+
"Nia-PlayAI",
|
|
45
|
+
"Phoebe-PlayAI",
|
|
46
|
+
"Ranger-PlayAI",
|
|
47
|
+
"Sophia-PlayAI",
|
|
48
|
+
"Waylon-PlayAI",
|
|
49
|
+
"William-Training-PlayAI",
|
|
50
|
+
"Nasser-PlayAI",
|
|
51
|
+
"Khalid-PlayAI",
|
|
52
|
+
"Amira-PlayAI",
|
|
53
|
+
"Ahmad-PlayAI",
|
|
54
|
+
]
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Literal, Union
|
|
3
|
+
|
|
4
|
+
import openai
|
|
5
|
+
from livekit.agents.llm import ToolChoice
|
|
6
|
+
from livekit.plugins.openai import LLM as OpenAILLM
|
|
7
|
+
from livekit.plugins.openai import STT as OpenAISTT
|
|
8
|
+
|
|
9
|
+
from .models import LLMModels, STTModels
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class LLM(OpenAILLM):
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
*,
|
|
16
|
+
model: str | LLMModels = "llama-3.3-70b-versatile",
|
|
17
|
+
api_key: str | None = None,
|
|
18
|
+
user: str | None = None,
|
|
19
|
+
temperature: float | None = None,
|
|
20
|
+
parallel_tool_calls: bool | None = None,
|
|
21
|
+
tool_choice: Union[ToolChoice, Literal["auto", "required", "none"]] = "auto",
|
|
22
|
+
max_tokens: int | None = None,
|
|
23
|
+
base_url: str | None = "https://api.groq.com/openai/v1",
|
|
24
|
+
client: openai.AsyncClient | None = None,
|
|
25
|
+
):
|
|
26
|
+
"""
|
|
27
|
+
Create a new instance of Groq LLM.
|
|
28
|
+
|
|
29
|
+
``api_key`` must be set to your Groq API key, either using the argument or by setting
|
|
30
|
+
the ``GROQ_API_KEY`` environmental variable.
|
|
31
|
+
"""
|
|
32
|
+
super().__init__(
|
|
33
|
+
model=model,
|
|
34
|
+
api_key=_get_api_key(api_key),
|
|
35
|
+
base_url=base_url,
|
|
36
|
+
client=client,
|
|
37
|
+
user=user,
|
|
38
|
+
temperature=temperature,
|
|
39
|
+
parallel_tool_calls=parallel_tool_calls,
|
|
40
|
+
tool_choice=tool_choice,
|
|
41
|
+
max_tokens=max_tokens,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class STT(OpenAISTT):
|
|
46
|
+
def __init__(
|
|
47
|
+
self,
|
|
48
|
+
*,
|
|
49
|
+
model: STTModels | str = "whisper-large-v3-turbo",
|
|
50
|
+
api_key: str | None = None,
|
|
51
|
+
base_url: str | None = "https://api.groq.com/openai/v1",
|
|
52
|
+
client: openai.AsyncClient | None = None,
|
|
53
|
+
language: str = "en",
|
|
54
|
+
prompt: str | None = None,
|
|
55
|
+
detect_language: bool = False,
|
|
56
|
+
):
|
|
57
|
+
"""
|
|
58
|
+
Create a new instance of Groq STT.
|
|
59
|
+
|
|
60
|
+
``api_key`` must be set to your Groq API key, either using the argument or by setting
|
|
61
|
+
the ``GROQ_API_KEY`` environmental variable.
|
|
62
|
+
"""
|
|
63
|
+
super().__init__(
|
|
64
|
+
model=model,
|
|
65
|
+
api_key=_get_api_key(api_key),
|
|
66
|
+
base_url=base_url,
|
|
67
|
+
client=client,
|
|
68
|
+
language=language,
|
|
69
|
+
detect_language=detect_language,
|
|
70
|
+
prompt=prompt,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _get_api_key(key: str | None) -> str:
|
|
75
|
+
key = key or os.environ.get("GROQ_API_KEY")
|
|
76
|
+
if not key:
|
|
77
|
+
raise ValueError(
|
|
78
|
+
"GROQ_API_KEY is required, either as argument or set GROQ_API_KEY environmental variable"
|
|
79
|
+
)
|
|
80
|
+
return key
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# Copyright 2023 LiveKit, Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import asyncio
|
|
18
|
+
import os
|
|
19
|
+
from dataclasses import dataclass
|
|
20
|
+
from typing import Optional
|
|
21
|
+
|
|
22
|
+
import aiohttp
|
|
23
|
+
from livekit.agents import (
|
|
24
|
+
APIConnectionError,
|
|
25
|
+
APIConnectOptions,
|
|
26
|
+
APIStatusError,
|
|
27
|
+
APITimeoutError,
|
|
28
|
+
tts,
|
|
29
|
+
utils,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
from .log import logger
|
|
33
|
+
from .models import TTSModels, TTSVoices
|
|
34
|
+
|
|
35
|
+
DEFAULT_BASE_URL = "https://api.groq.com/openai/v1"
|
|
36
|
+
SAMPLE_RATE = 48000
|
|
37
|
+
NUM_CHANNELS = 1
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclass
|
|
41
|
+
class _TTSOptions:
|
|
42
|
+
model: TTSModels | str
|
|
43
|
+
voice: TTSVoices | str
|
|
44
|
+
api_key: str
|
|
45
|
+
base_url: str
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class TTS(tts.TTS):
|
|
49
|
+
def __init__(
|
|
50
|
+
self,
|
|
51
|
+
*,
|
|
52
|
+
base_url: str | None = None,
|
|
53
|
+
model: TTSModels | str = "playai-tts",
|
|
54
|
+
voice: TTSVoices | str = "Eileen-PlayAI",
|
|
55
|
+
api_key: str | None = None,
|
|
56
|
+
http_session: aiohttp.ClientSession | None = None,
|
|
57
|
+
) -> None:
|
|
58
|
+
"""
|
|
59
|
+
Create a new instance of Groq TTS.
|
|
60
|
+
|
|
61
|
+
if `api_key` is not provided, it will be read from the ``GROQ_API_KEY``
|
|
62
|
+
environmental variable.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
model (SpeechModels | str, optional): Model to use. Default is "playai-tts".
|
|
66
|
+
voice (SpeechVoices | str, optional): Voice to use. Default is "Autumn-PlayAI".
|
|
67
|
+
api_key (str | None, optional): API key to use. Default is None.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
super().__init__(
|
|
71
|
+
capabilities=tts.TTSCapabilities(
|
|
72
|
+
streaming=False,
|
|
73
|
+
),
|
|
74
|
+
sample_rate=SAMPLE_RATE,
|
|
75
|
+
num_channels=1,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
self._session = http_session
|
|
79
|
+
|
|
80
|
+
if not base_url:
|
|
81
|
+
base_url = DEFAULT_BASE_URL
|
|
82
|
+
|
|
83
|
+
if not api_key:
|
|
84
|
+
api_key = os.getenv("GROQ_API_KEY")
|
|
85
|
+
if not api_key:
|
|
86
|
+
raise ValueError("GROQ_API_KEY is not set")
|
|
87
|
+
|
|
88
|
+
self._opts = _TTSOptions(
|
|
89
|
+
model=model,
|
|
90
|
+
voice=voice,
|
|
91
|
+
api_key=api_key,
|
|
92
|
+
base_url=base_url,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
def _ensure_session(self) -> aiohttp.ClientSession:
|
|
96
|
+
if not self._session:
|
|
97
|
+
self._session = utils.http_context.http_session()
|
|
98
|
+
|
|
99
|
+
return self._session
|
|
100
|
+
|
|
101
|
+
def update_options(
|
|
102
|
+
self,
|
|
103
|
+
*,
|
|
104
|
+
model: TTSModels | None = None,
|
|
105
|
+
voice: TTSVoices | None = None,
|
|
106
|
+
) -> None:
|
|
107
|
+
"""
|
|
108
|
+
Update the TTS options.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
model (SpeechModels | str, optional): Model to use. Default is None.
|
|
112
|
+
voice (SpeechVoices | str, optional): Voice to use. Default is None.
|
|
113
|
+
"""
|
|
114
|
+
if model:
|
|
115
|
+
self._opts.model = model
|
|
116
|
+
if voice:
|
|
117
|
+
self._opts.voice = voice
|
|
118
|
+
|
|
119
|
+
def synthesize(
|
|
120
|
+
self,
|
|
121
|
+
text: str,
|
|
122
|
+
*,
|
|
123
|
+
conn_options: Optional[APIConnectOptions] = None,
|
|
124
|
+
segment_id: str | None = None,
|
|
125
|
+
) -> "ChunkedStream":
|
|
126
|
+
return ChunkedStream(
|
|
127
|
+
tts=self,
|
|
128
|
+
input_text=text,
|
|
129
|
+
conn_options=conn_options,
|
|
130
|
+
opts=self._opts,
|
|
131
|
+
session=self._ensure_session(),
|
|
132
|
+
segment_id=segment_id,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class ChunkedStream(tts.ChunkedStream):
|
|
137
|
+
def __init__(
|
|
138
|
+
self,
|
|
139
|
+
*,
|
|
140
|
+
tts: TTS,
|
|
141
|
+
input_text: str,
|
|
142
|
+
conn_options: Optional[APIConnectOptions] = None,
|
|
143
|
+
opts: _TTSOptions,
|
|
144
|
+
session: aiohttp.ClientSession,
|
|
145
|
+
segment_id: str | None = None,
|
|
146
|
+
) -> None:
|
|
147
|
+
super().__init__(tts=tts, input_text=input_text, conn_options=conn_options)
|
|
148
|
+
self._opts = opts
|
|
149
|
+
self._session = session
|
|
150
|
+
self._segment_id = segment_id
|
|
151
|
+
|
|
152
|
+
async def _run(self) -> None:
|
|
153
|
+
request_id = utils.shortuuid()
|
|
154
|
+
headers = {
|
|
155
|
+
"Authorization": f"Bearer {self._opts.api_key}",
|
|
156
|
+
"Content-Type": "application/json",
|
|
157
|
+
}
|
|
158
|
+
payload = {
|
|
159
|
+
"model": self._opts.model,
|
|
160
|
+
"voice": self._opts.voice,
|
|
161
|
+
"input": self._input_text,
|
|
162
|
+
"response_format": "wav",
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
decoder = utils.codecs.AudioStreamDecoder(
|
|
166
|
+
sample_rate=SAMPLE_RATE,
|
|
167
|
+
num_channels=NUM_CHANNELS,
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
decode_task: Optional[asyncio.Task] = None
|
|
171
|
+
api_url = f"{self._opts.base_url}/audio/speech"
|
|
172
|
+
try:
|
|
173
|
+
async with self._session.post(
|
|
174
|
+
api_url, headers=headers, json=payload
|
|
175
|
+
) as response:
|
|
176
|
+
if not response.content_type.startswith("audio"):
|
|
177
|
+
content = await response.text()
|
|
178
|
+
logger.error("Groq returned non-audio data: %s", content)
|
|
179
|
+
return
|
|
180
|
+
|
|
181
|
+
async def _decode_loop():
|
|
182
|
+
try:
|
|
183
|
+
async for bytes_data, _ in response.content.iter_chunks():
|
|
184
|
+
decoder.push(bytes_data)
|
|
185
|
+
finally:
|
|
186
|
+
decoder.end_input()
|
|
187
|
+
|
|
188
|
+
decode_task = asyncio.create_task(_decode_loop())
|
|
189
|
+
emitter = tts.SynthesizedAudioEmitter(
|
|
190
|
+
event_ch=self._event_ch,
|
|
191
|
+
request_id=request_id,
|
|
192
|
+
segment_id=self._segment_id,
|
|
193
|
+
)
|
|
194
|
+
async for frame in decoder:
|
|
195
|
+
emitter.push(frame)
|
|
196
|
+
emitter.flush()
|
|
197
|
+
|
|
198
|
+
except asyncio.TimeoutError as e:
|
|
199
|
+
raise APITimeoutError() from e
|
|
200
|
+
except aiohttp.ClientResponseError as e:
|
|
201
|
+
raise APIStatusError(
|
|
202
|
+
message=e.message,
|
|
203
|
+
status_code=e.status,
|
|
204
|
+
request_id=request_id,
|
|
205
|
+
body=None,
|
|
206
|
+
) from e
|
|
207
|
+
except Exception as e:
|
|
208
|
+
raise APIConnectionError() from e
|
|
209
|
+
finally:
|
|
210
|
+
if decode_task:
|
|
211
|
+
await utils.aio.gracefully_cancel(decode_task)
|
|
212
|
+
await decoder.aclose()
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Copyright 2023 LiveKit, Inc.
|
|
2
|
+
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
__version__ = "0.1.1"
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: livekit-plugins-groq
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Groq inference plugin for LiveKit
|
|
5
|
+
Home-page: https://github.com/livekit/agents
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Documentation, https://docs.livekit.io
|
|
8
|
+
Project-URL: Website, https://livekit.io/
|
|
9
|
+
Project-URL: Source, https://github.com/livekit/agents
|
|
10
|
+
Keywords: groq,llm,stt,tts,webrtc,livekit
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
13
|
+
Classifier: Topic :: Multimedia :: Sound/Audio
|
|
14
|
+
Classifier: Topic :: Multimedia :: Video
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
+
Requires-Python: >=3.9.0
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
Requires-Dist: livekit-agents<1.0.0,>=0.12.16
|
|
23
|
+
Requires-Dist: livekit-plugins-openai<1.0.0,>=0.11.2
|
|
24
|
+
Dynamic: classifier
|
|
25
|
+
Dynamic: description
|
|
26
|
+
Dynamic: description-content-type
|
|
27
|
+
Dynamic: home-page
|
|
28
|
+
Dynamic: keywords
|
|
29
|
+
Dynamic: license
|
|
30
|
+
Dynamic: project-url
|
|
31
|
+
Dynamic: requires-dist
|
|
32
|
+
Dynamic: requires-python
|
|
33
|
+
Dynamic: summary
|
|
34
|
+
|
|
35
|
+
# LiveKit Plugins Groq
|
|
36
|
+
|
|
37
|
+
Agent Framework plugin for services from Groq. Currently supporting STT, and LLM
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install livekit-plugins-groq
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Pre-requisites
|
|
46
|
+
|
|
47
|
+
For credentials, you'll need a Groq Cloud account and obtain the correct credentials. Credentials can be passed directly or via GROQ_API_KEY environment variable
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
livekit/plugins/groq/__init__.py,sha256=3FCdFGFsZtZnoWLJfPQPh8tzt44chzmrpXzCckIldGg,930
|
|
2
|
+
livekit/plugins/groq/log.py,sha256=nCRNT6C52cMuAbBzdH15Fz933CLPZNkSZ1JPJyVdI1Y,67
|
|
3
|
+
livekit/plugins/groq/models.py,sha256=TyU9m3NrdtZi7UxgiKPgNGiZIsJiJQLdtbZkQEqzDAU,1086
|
|
4
|
+
livekit/plugins/groq/services.py,sha256=5vZv9E8UkrGpFyI5oFcddfks38MHpfTHm5VmIbvQEqA,2472
|
|
5
|
+
livekit/plugins/groq/tts.py,sha256=ZKNox2WI3PzPGS0HFtcIHSz4oLEx4F45udtC-fL6vBE,6315
|
|
6
|
+
livekit/plugins/groq/version.py,sha256=IK31lfqSqfmET1Eqg7jx5fIpK4f_5uvSS80S-StV7zA,599
|
|
7
|
+
livekit_plugins_groq-0.1.1.dist-info/METADATA,sha256=T2tTOhRl5PDp5aJ2ybdgp2s5yyKaaw-ap5cUojAhkeM,1564
|
|
8
|
+
livekit_plugins_groq-0.1.1.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
|
|
9
|
+
livekit_plugins_groq-0.1.1.dist-info/top_level.txt,sha256=OoDok3xUmXbZRvOrfvvXB-Juu4DX79dlq188E19YHoo,8
|
|
10
|
+
livekit_plugins_groq-0.1.1.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
livekit
|