livekit-plugins-volcengine
火山引擎服务专用的 LiveKit Agents 插件,提供完整的语音和语言模型集成解决方案。
最近修改
- 已升级到
livekit-agents==1.5.4 - Python 要求已更新为
>=3.10 volcengine.TTS已切换到豆包语音合成大模型 V3 HTTP Chunked 接口volcengine.TTS不再需要cluster参数volcengine.TTS默认resource_id="seed-tts-2.0"volcengine.TTS默认音色为zh_female_xiaohe_uranus_bigttsvolcengine.STT现已直接使用豆包大模型流式语音识别接口volcengine.STT已补齐新版握手头X-Api-Connect-Idvolcengine.STT切换到新版控制台鉴权,仅使用X-Api-Key头volcengine.TTS同步切换到新版控制台鉴权,仅使用X-Api-Key头volcengine.RealtimeModel同步切换到新版控制台鉴权,仅使用X-Api-Key头
✨ 特性
- 🎤 语音识别 (STT) - 使用豆包大模型流式语音识别服务
- 🗣️ 语音合成 (TTS) - 使用豆包语音合成大模型服务
- 🤖 大语言模型 (LLM) - 支持豆包大模型系列
- ⚡ 实时语音模型 (Realtime) - 端到端实时语音交互
- 🔧 简单集成 - 与 LiveKit Agents 框架无缝集成
- 📦 开箱即用 - 完整的 Python 包支持
📋 支持的服务
| 服务 | 描述 | 文档链接 |
|---|---|---|
| TTS | 豆包语音合成大模型,当前实现使用 V3 HTTP Chunked 单向流式接口 | 语音合成大模型 API 列表 |
| STT | 豆包大模型流式语音识别,当前实现使用 /api/v3/sauc/bigmodel WebSocket 接口 |
大模型语音识别 |
| LLM | 大语言模型 | 流式调用 |
| Realtime | 实时语音模型 | 实时语音 |
服务开通
| 服务 | 开通/接入入口 |
|---|---|
| 豆包语音 | 快速入门(新版控制台) |
| 豆包语音控制台 | 控制台 |
| 火山方舟 LLM | 火山方舟文档 |
| 火山方舟控制台 | Ark 控制台 |
🛠️ 安装
使用 pip 安装
pip install livekit-plugins-volcengine
从源码安装
git clone https://github.com/your-repo/livekit-plugins-volcengine.git
cd livekit-plugins-volcengine
pip install -e .
系统要求
- Python >= 3.10
- LiveKit Agents == 1.5.4
⚙️ 配置
环境变量
在使用插件前,请配置以下环境变量:
| 环境变量 | 描述 | 获取方式 |
|---|---|---|
VOLCENGINE_TTS_API_KEY |
TTS 服务的 API Key(新版控制台) | 语音合成控制台 |
VOLCENGINE_STT_API_KEY |
STT 服务的 API Key(新版控制台) | 语音识别控制台 |
VOLCENGINE_LLM_API_KEY |
LLM 服务的 API 密钥 | 大模型控制台 |
VOLCENGINE_REALTIME_API_KEY |
实时服务的 API Key(新版控制台) | 实时语音控制台 |
VOLCENGINE_TTS_RESOURCE_ID |
TTS 资源 ID,默认 seed-tts-2.0 |
豆包语音合成接口文档 |
.env 文件示例
# .env
VOLCENGINE_TTS_API_KEY=your_tts_api_key_here
VOLCENGINE_STT_API_KEY=your_stt_api_key_here
VOLCENGINE_LLM_API_KEY=your_llm_api_key_here
VOLCENGINE_REALTIME_API_KEY=your_realtime_api_key_here
📖 使用指南
基础使用
from livekit.agents import Agent, AgentSession, JobContext, cli, WorkerOptions
from livekit.plugins import volcengine
from dotenv import load_dotenv
async def entry_point(ctx: JobContext):
agent = Agent(instructions="You are a helpful assistant.")
# 使用实时语音模型
llm = volcengine.RealtimeModel(
api_key="your_api_key",
bot_name="智能助手",
model="O" # 或 "SC"
)
session = AgentSession(llm=llm)
await session.start(agent=agent, room=ctx.room)
await ctx.connect()
if __name__ == "__main__":
load_dotenv()
cli.run_app(WorkerOptions(entrypoint_fnc=entry_point))
STT
from livekit.agents import Agent, AgentSession, JobContext, cli, WorkerOptions
from livekit.plugins import volcengine
from dotenv import load_dotenv
async def entry_point(ctx: JobContext):
agent = Agent(instructions="You are a helpful assistant.")
# 使用豆包大模型流式语音识别
stt = volcengine.STT(api_key="your_api_key")
session = AgentSession(
stt=stt,
tts=volcengine.TTS(api_key="your_tts_api_key"),
llm=volcengine.LLM(model="doubao-1-5-pro-32k-250115")
)
await session.start(agent=agent, room=ctx.room)
await ctx.connect()
if __name__ == "__main__":
load_dotenv()
cli.run_app(WorkerOptions(entrypoint_fnc=entry_point))
实时语音模型
实时语音模型提供端到端的全双工语音交互体验,支持实时语音识别、对话生成和语音合成。
基础配置
from livekit.agents import Agent, AgentSession, JobContext, cli, WorkerOptions
from livekit.plugins import volcengine
from dotenv import load_dotenv
async def entry_point(ctx: JobContext):
agent = Agent(instructions="You are a helpful assistant.")
# 基础实时语音模型配置
realtime_llm = volcengine.RealtimeModel(
api_key="your_api_key",
bot_name="豆包", # 机器人名称
model="O" # 默认使用O版本,功能全面
)
session = AgentSession(llm=realtime_llm)
await session.start(agent=agent, room=ctx.room)
await ctx.connect()
if __name__ == "__main__":
load_dotenv()
cli.run_app(WorkerOptions(entrypoint_fnc=entry_point))
高级配置
from livekit.agents import Agent, AgentSession, JobContext, cli, WorkerOptions
from livekit.plugins import volcengine
from dotenv import load_dotenv
# 自定义RAG函数
def rag_function(transcription: str) -> str:
"""自定义RAG函数,用于增强模型回复"""
# 根据用户输入返回相关的上下文信息
return '[{"title":"相关信息","content":"这是相关的背景知识"}]'
async def entry_point(ctx: JobContext):
agent = Agent(instructions="You are a helpful assistant.")
# 高级配置 - 包含网络搜索和RAG功能
realtime_llm = volcengine.RealtimeModel(
api_key="your_api_key",
bot_name="智能助手",
model="O", # O版本支持联网搜索和RAG,SC版本专注角色扮演
enable_volc_websearch=True, # 启用联网搜索
volc_websearch_api_key="your_websearch_api_key",
rag_fn=rag_function, # 自定义RAG函数
speaking_style="专业、友好、耐心",
system_role="你是一个专业的AI助手,擅长解答各种问题。"
)
session = AgentSession(llm=realtime_llm)
await session.start(agent=agent, room=ctx.room)
await ctx.connect()
if __name__ == "__main__":
load_dotenv()
cli.run_app(WorkerOptions(entrypoint_fnc=entry_point))
模型版本对比
火山引擎实时语音模型提供两个不同的版本,各有独特的功能特点:
O版本 (标准功能版)
realtime_llm = volcengine.RealtimeModel(
model="O", # 标准功能版,功能全面
# ... 其他配置
)
核心功能:
- 🌐 内置联网搜索:支持实时网络信息检索和查询
- 🧠 外部RAG支持:支持外部知识库检索、总结和口语化改写
- 🎵 精品音色:支持 vv、xiaohe、yunzhou、xiaotian 等高品质音色
- ⚙️ SP开放配置:支持 bot_name、system_role、speaking_style 等参数配置
- 🚫 角色描述:不支持 character_manifest 参数
- 🚫 克隆音色:不支持 ICL_ 或 S_ 开头的音色名称
适用场景:
- 需要联网搜索的应用
- 需要外部知识库集成的场景
- 对音质要求较高的应用
- 需要灵活参数配置的场景
SC版本 (角色增强版)
realtime_llm = volcengine.RealtimeModel(
model="SC", # 角色增强版,专注角色扮演
# ... 其他配置
)
核心功能:
- 🚫 内置联网搜索:不支持联网搜索功能
- 🚫 外部RAG支持:不支持外部RAG功能
- 🚫 精品音色:不支持 vv、xiaohe、yunzhou、xiaotian 等音色
- 🚫 SP开放配置:不支持 bot_name、system_role、speaking_style 参数
- 🎭 角色描述:支持 character_manifest 参数进行角色配置
- 🎤 克隆音色:支持 ICL_ 或 S_ 开头的克隆音色
适用场景:
- 专注于角色扮演的应用
- 需要使用克隆音色的场景
- 对角色个性化要求较高的应用
- 需要 character_manifest 配置的场景
功能对比表格
| 功能特性 | O版本 | SC版本 |
|---|---|---|
| 🌐 内置联网搜索 | ✅ | ❌ |
| 🧠 外部RAG总结和口语化改写 | ✅ | ❌ |
| 🎵 精品音色(vv、xiaohe、yunzhou、xiaotian) | ✅ | ❌ |
| ⚙️ SP开放配置(bot_name、system_role、speaking_style) | ✅ | ❌ |
| 🎭 角色描述(character_manifest) | ❌ | ✅ |
| 🎤 克隆音色(ICL_或S_开头) | ❌ | ✅ |
版本选择建议
| 应用场景 | 推荐版本 | 主要原因 |
|---|---|---|
| 智能客服 | O版本 | 需要联网搜索和灵活配置 |
| 教育辅导 | O版本 | 需要联网搜索和精品音质 |
| 角色扮演 | SC版本 | 专注于角色特性和克隆音色 |
| 娱乐应用 | O版本 | 需要联网搜索和多样音色 |
| 企业培训 | SC版本 | 需要角色定制和个性化 |
| 内容创作 | O版本 | 需要RAG和联网搜索功能 |
使用建议:
- O版本:功能更全面,适合大多数应用场景
- SC版本:专注于角色扮演,适合特定个性化需求
- 根据您的具体需求选择合适的版本
- 建议先测试两种版本,选择最符合需求的那一个
角色配置 (SC版本)
from livekit.agents import Agent, AgentSession, JobContext, cli, WorkerOptions
from livekit.plugins import volcengine
from dotenv import load_dotenv
async def entry_point(ctx: JobContext):
agent = Agent(instructions="You are a helpful assistant.")
# SC版本支持角色配置和克隆音色
realtime_llm = volcengine.RealtimeModel(
api_key="your_api_key",
bot_name="小智",
model="SC", # SC版本支持character_manifest
character_manifest='{ # JSON字符串格式的角色配置
"name": "小智",
"personality": "活泼开朗、聪明机智",
"background": "一个充满好奇心的AI助手"
}',
speaker="ICL_custom_voice", # SC版本支持克隆音色
speaking_style="活泼开朗,像个小伙伴一样和你聊天",
system_role="你叫小智,是一个活泼开朗的AI助手,喜欢用emoji表情,回复简洁有趣。"
)
session = AgentSession(llm=realtime_llm)
await session.start(agent=agent, room=ctx.room)
await ctx.connect()
if __name__ == "__main__":
load_dotenv()
cli.run_app(WorkerOptions(entrypoint_fnc=entry_point))
单独组件使用
如果您需要分别使用各个组件(STT、TTS、LLM),而不是使用集成的实时语音模型:
from livekit.agents import Agent, AgentSession, JobContext, cli, WorkerOptions
from livekit.plugins import volcengine
from dotenv import load_dotenv
async def entry_point(ctx: JobContext):
agent = Agent(instructions="You are a helpful assistant.")
session = AgentSession(
# 语音识别
stt=volcengine.STT(
api_key="your_stt_api_key",
resource_id="volc.seedasr.sauc.duration"
),
# 语音合成
tts=volcengine.TTS(
api_key="your_tts_api_key",
resource_id="seed-tts-2.0",
voice="zh_female_xiaohe_uranus_bigtts"
),
# 单独的LLM (非实时)
llm=volcengine.LLM(model="doubao-1-5-pro-32k-250115")
)
await session.start(agent=agent, room=ctx.room)
await ctx.connect()
if __name__ == "__main__":
load_dotenv()
cli.run_app(WorkerOptions(entrypoint_fnc=entry_point))
🔧 API 参考
TTS (文本转语音)
当前 volcengine.TTS 使用的是豆包语音合成大模型,接入方式为 V3 HTTP Chunked 单向流式接口。
volcengine.TTS(
api_key: str, # API Key(新版控制台)
resource_id: str | None = None, # 默认 seed-tts-2.0
voice: str = "zh_female_xiaohe_uranus_bigtts",
speed: float = 1.0, # 语速倍率(OpenAI 规范),[0.2, 3.0],1.0=正常
volume: float = 1.0, # 音量倍率(OpenAI 规范),(0.1, 3.0],1.0=正常(mix 音色暂不支持)
pitch: float = 1.0, # 已废弃,保留仅用于兼容
sample_rate: Literal[24000, 16000, 8000] = 16000,
)
speed/volume遵循 OpenAI 接口规范(float 倍率),请求时按speech_rate = round((speed - 1.0) * 200)(clamp 到[-50, 100])转换为火山原生speech_rate/loudness_rate整型字段。
TTS 资源 ID 说明
seed-tts-2.0:豆包语音合成模型 2.0seed-tts-1.0/seed-tts-1.0-concurr:豆包语音合成模型 1.0seed-icl-2.0:豆包声音复刻模型 2.0seed-icl-1.0/seed-icl-1.0-concurr:豆包声音复刻模型 1.0
seed-tts-* 只能调用语音合成音色,seed-icl-* 只能调用声音复刻音色。resource_id 和音色版本必须匹配。
STT (语音识别)
当前 volcengine.STT 使用的是豆包大模型流式语音识别 WebSocket 接口。
volcengine.STT(
api_key: str | None = None, # API Key(新版控制台),可用环境变量 VOLCENGINE_STT_API_KEY
resource_id: str | None = None, # 例如 volc.bigasr.sauc.duration / volc.seedasr.sauc.duration
model_name: str = "bigmodel",
enable_itn: bool = False,
enable_punc: bool = True,
enable_ddc: bool = False,
enable_diarization: bool = False, # 开启说话人分离(同时启用性别识别)
vad_segment_duration: int = 3000,
end_window_size: int = 500,
force_to_speech_time: int = 1000,
)
说话人分离(Diarization)
把 enable_diarization=True 打开后,插件会:
- 在
STTCapabilities.diarization上声明能力,符合 LiveKit STT 文档 要求的三件事之一。 - 在每条
SpeechData上填上来自服务端additions.speaker的speaker_id(形如"speaker_1")。 - 在
SpeechData.metadata["gender"]里带上additions.gender(按官方文档,性别 只在definite=true的分句上返回,所以中间结果不会有)。 - 按分句拆分
utterances数组,每段独立事件(START → INTERIM/FINAL → END), 而不是把多段合并到一个事件里——这样下游的MultiSpeakerAdapter能在段粒度上 决定谁是主说话人、要不要抑制背景。
注意:插件只做"原始说话人分离"的暴露,不做主说话人判断或背景抑制。这两个 策略属于
MultiSpeakerAdapter。典型用法:
from livekit.agents import Agent, AgentSession, JobContext, cli, WorkerOptions
from livekit.agents.stt import MultiSpeakerAdapter
from livekit.plugins import volcengine
async def entry_point(ctx: JobContext):
raw_stt = volcengine.STT(
api_key="your_api_key",
enable_diarization=True, # 暴露每段 speaker_id + gender
)
# 用官方适配器做主说话人检测 / 背景抑制
stt = MultiSpeakerAdapter(
raw_stt,
detect_primary_speaker=True, # 默认 True:识别谁是主说话人
suppress_background_speaker=False, # True 则只把主说话人文本交给 agent
)
agent = Agent(instructions="你是一个友好的助手。")
session = AgentSession(stt=stt, llm=..., tts=...)
await session.start(agent=agent, room=ctx.room)
await ctx.connect()
if __name__ == "__main__":
cli.run_app(WorkerOptions(entrypoint_fnc=entry_point))
当 MultiSpeakerAdapter.suppress_background_speaker=True 时,下游 agent 只会
看到主说话人的分句,其它说话人(如旁人的声音、背景里的电视)会直接被吞掉。
LLM (大语言模型)
volcengine.LLM(
model: str, # 模型名称
temperature: float = 0.7, # 温度
max_tokens: int = 2000, # 最大token数
system_message: str = None # 系统消息
)
RealtimeModel (实时语音模型)
volcengine.RealtimeModel(
# 必需参数
api_key: str = None, # API Key(新版控制台),从环境变量 VOLCENGINE_REALTIME_API_KEY 获取
# 基本配置
bot_name: str = "豆包", # 机器人名称
speaking_style: str = "你的说话风格简洁明了,语速适中,语调自然。", # 说话风格描述
speaker: str = "zh_female_vv_jupiter_bigtts", # 语音类型
opening: str = "你好啊,今天过得怎么样?", # 开场白内容
system_role: str = None, # 系统角色提示词
# 模型配置
model: Literal["O", "SC"] = "O", # 模型版本:O(标准功能版) 或 SC(角色增强版)
character_manifest: str = None, # 角色配置,JSON字符串格式
# 音频配置
sample_rate: int = 24000, # 采样率
num_channels: int = 1, # 声道数
format: str = "pcm", # 音频格式
# ASR配置
end_smooth_window_ms: int = 500, # 结束平滑窗口毫秒数
# 网络搜索配置
enable_volc_websearch: bool = False, # 是否启用网络搜索
volc_websearch_type: Literal["web_summary", "web"] = "web_summary", # 搜索类型
volc_websearch_api_key: str = None, # 网络搜索API密钥
volc_websearch_no_result_message: str = "抱歉,我找不到相关信息。", # 无结果提示
# RAG配置
rag_fn: Callable[[str], str] = None, # RAG回调函数,输入查询返回增强内容
# 其他配置
audio_output: bool = True, # 是否输出音频
modalities: List[Literal["text", "audio"]] = NOT_GIVEN, # 输出模态
http_session: aiohttp.ClientSession = None, # HTTP会话
max_session_duration: float = None, # 最大会话持续时间
conn_options: APIConnectOptions = DEFAULT_API_CONNECT_OPTIONS # 连接选项
)
❓ 常见问题
Q: 如何获取访问令牌?
A: 请访问火山引擎控制台,在相应服务页面创建应用并获取访问令牌。
Q: 支持哪些语音类型?
A: 支持多种语音类型,包括 BV001_V2_streaming、BV002_V2_streaming 等,详见语音合成文档。
Q: 如何处理连接错误?
A: 请检查网络连接和访问令牌是否正确配置。建议使用环境变量管理敏感信息。
Q: 支持哪些大语言模型?
A: 支持豆包系列模型,包括 doubao-1-5-lite、doubao-1-5-pro 等,详见大模型文档。
Q: 实时语音模型支持哪些语音类型?
A: 实时语音模型支持多种预训练语音,包括:
zh_female_vv_jupiter_bigtts- 女声 Jupiter 大模型语音zh_male_vv_jupiter_bigtts- 男声 Jupiter 大模型语音- 其他火山引擎TTS支持的语音类型
Q: 如何配置网络搜索功能?
A: 要启用网络搜索功能,需要设置以下参数:
realtime_llm = volcengine.RealtimeModel(
enable_volc_websearch=True,
volc_websearch_type="web_summary", # 或 "web"
volc_websearch_api_key="your_websearch_key"
)
Q: 什么是RAG功能,如何使用?
A: RAG(Retrieval-Augmented Generation)可以为模型提供额外的上下文信息:
def my_rag_function(query: str) -> str:
# 根据用户查询返回相关的上下文信息
return "相关的背景知识和信息"
realtime_llm = volcengine.RealtimeModel(
rag_fn=my_rag_function
)
Q: 实时语音模型和普通LLM/TTS的区别是什么?
A: 实时语音模型是端到端的解决方案:
- 集成度高:语音识别、对话生成、语音合成一体化
- 实时性强:支持全双工实时对话
- 智能化:内置角色配置、网络搜索、RAG等高级功能
- 简单配置:一个模型即可完成语音交互全流程
普通LLM+TTS组合需要分别配置和处理各个组件的数据流,而实时模型内部集成了这些功能。
Q: 如何选择O版本和SC版本?
A: 根据您的应用需求选择合适的版本:
选择O版本的情况:
- 需要联网搜索功能的应用
- 需要外部RAG集成的场景
- 对音质要求较高,需要精品音色的应用
- 需要灵活配置bot_name、system_role、speaking_style的场景
- 大多数通用应用场景
选择SC版本的情况:
- 专注于角色扮演的应用
- 需要使用克隆音色(ICL_或S_开头)的场景
- 需要character_manifest进行角色配置的场景
- 对角色个性化要求较高的应用
版本对比:
- O版本:功能全面,适合大多数应用场景,支持联网搜索、RAG、精品音色等
- SC版本:专注于角色扮演,支持角色描述和克隆音色,但不支持联网搜索等功能
使用建议:
- 如果您的应用需要联网搜索、RAG或精品音色,选择O版本
- 如果您的应用专注于角色扮演和个性化音色,选择SC版本
- 建议根据具体需求测试两个版本,选择最合适的
📝 更新日志
最新变更
volcengine.STT新增enable_diarization参数(默认关闭)。开启后:STTCapabilities.diarization = True,可被MultiSpeakerAdapter包装做主说话人 检测 / 背景抑制。- 每段
SpeechData携带speaker_id(来自additions.speaker),性别写入SpeechData.metadata["gender"](按官方文档,gender 仅在definite=true的分句 上返回)。 utterances[]数组按分句拆分事件,方便下游在段粒度上做判断。
v1.5.4 适配
- 升级
livekit-agents到1.5.4 - Python 要求调整为
>=3.10 volcengine.TTS迁移到豆包语音合成大模型 V3 HTTP Chunked 接口volcengine.TTS移除cluster参数volcengine.TTS默认资源改为seed-tts-2.0volcengine.TTS默认音色改为zh_female_xiaohe_uranus_bigtts- 修复 V3 TTS 流式响应解析,按 JSON chunk 解码 base64 音频
- 修复无音频返回时静默失败的问题
- 删除旧版普通 STT,实现统一为豆包大模型流式语音识别
volcengine.STT补齐X-Api-Connect-Id握手头volcengine.STT切换到新版控制台鉴权,移除app_id/access_token,改用单一api_key并发送X-Api-Key头volcengine.TTS同步切换到新版控制台鉴权,移除app_id/access_token,改用单一api_key并发送X-Api-Key头volcengine.RealtimeModel同步切换到新版控制台鉴权,移除app_id/access_token,改用单一api_key并发送X-Api-Key头
🤝 贡献
欢迎提交 Issue 和 Pull Request!
- Fork 本项目
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 打开 Pull Request
📄 许可证
本项目采用 Apache 2.0 许可证 - 查看 LICENSE 文件了解详情。
📞 联系我们
- 项目主页: GitHub
- 问题反馈: Issues
- 邮箱: 790990241@qq.com
🙏 致谢
Metadata
Release files for livekit-plugins-volcenginee 1.8.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| livekit_plugins_volcenginee-1.8.3.tar.gz | 36.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| livekit_plugins_volcenginee-1.8.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 77.9 kB
Release files / livekit_plugins_volcenginee-1.8.3.tar.gz
| Download URL | livekit_plugins_volcenginee-1.8.3.tar.gz |
|---|---|
| Size | 36.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
276c359c4a5482ce55857dc5579c055cc112d66a6440d10213ce52ac7f8e9dab
|
|
BLAKE2b-256 checksum How to use checksums |
58e5754d074b8365dca54d1466999ec149c64c5b251a981351ba39e52266e916
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.7.20
|
Release files / livekit_plugins_volcenginee-1.8.3-py3-none-any.whl
| Download URL | livekit_plugins_volcenginee-1.8.3-py3-none-any.whl |
|---|---|
| Size | 41.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9013e2f9245a193b5a7b4c7a12e515d17f6770df310620c2ce42c9944e27313f
|
|
BLAKE2b-256 checksum How to use checksums |
f6f07fe239f2b808b048cdca9b6e96d2474d57d911952767a9ae684b4bbc14cb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.7.20
|