Compare commits
10 Commits
f25673b882
...
9a5cc3e6a0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a5cc3e6a0 | ||
|
|
d420d9cec3 | ||
|
|
78ce629ac3 | ||
|
|
eff27a7c81 | ||
|
|
05c934deba | ||
|
|
a5ee31a8d0 | ||
|
|
aa939691f8 | ||
|
|
3e59ed9173 | ||
|
|
64585e60c5 | ||
|
|
22e1d32415 |
117
.gitignore
vendored
@ -1,33 +1,104 @@
|
|||||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
# =====================
|
||||||
|
# 依赖 / Dependencies
|
||||||
# dependencies
|
# =====================
|
||||||
/node_modules
|
node_modules/
|
||||||
/.pnp
|
.pnp
|
||||||
.pnp.js
|
.pnp.js
|
||||||
.vscode
|
.pnp.cjs
|
||||||
# testing
|
|
||||||
/coverage
|
|
||||||
|
|
||||||
# production
|
# =====================
|
||||||
|
# 构建输出 / Build
|
||||||
|
# =====================
|
||||||
/build
|
/build
|
||||||
|
dist/
|
||||||
|
out/
|
||||||
|
.next/
|
||||||
|
.nuxt/
|
||||||
|
|
||||||
# misc
|
# =====================
|
||||||
.DS_Store
|
# 包管理器锁文件 & 缓存
|
||||||
.env.local
|
# =====================
|
||||||
.env.development.local
|
yarn.lock
|
||||||
.env.test.local
|
pnpm-lock.yaml
|
||||||
.env.production.local
|
.yarn/
|
||||||
|
.npm/
|
||||||
|
.eslintcache
|
||||||
|
.stylelintcache
|
||||||
|
.prettiercache
|
||||||
|
|
||||||
|
# =====================
|
||||||
|
# 环境变量 / Env
|
||||||
|
# =====================
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
|
||||||
|
# =====================
|
||||||
|
# 日志 / Logs
|
||||||
|
# =====================
|
||||||
|
log/
|
||||||
|
logs/
|
||||||
|
*.log
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
.eslintcache
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
/Server/node_modules
|
# =====================
|
||||||
|
# 测试覆盖率 / Testing
|
||||||
|
# =====================
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# =====================
|
||||||
|
# 编辑器 & IDE
|
||||||
|
# =====================
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
*.sublime-project
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
|
# =====================
|
||||||
|
# 系统文件 / OS
|
||||||
|
# =====================
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
ehthumbs.db
|
||||||
|
Desktop.ini
|
||||||
|
._*
|
||||||
|
|
||||||
|
# =====================
|
||||||
|
# Python (backend)
|
||||||
|
# =====================
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
*.so
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
env/
|
||||||
|
*.egg-info/
|
||||||
|
*.egg
|
||||||
|
.eggs/
|
||||||
|
.mypy_cache/
|
||||||
|
.ruff_cache/
|
||||||
|
.pytest_cache/
|
||||||
|
.pytype/
|
||||||
|
htmlcov/
|
||||||
|
*.pyo
|
||||||
|
|
||||||
|
# =====================
|
||||||
|
# Node.js Server
|
||||||
|
# =====================
|
||||||
/Server/log
|
/Server/log
|
||||||
/log
|
|
||||||
yarn.lock
|
# =====================
|
||||||
.eslintcache
|
# 其他 / Misc
|
||||||
pnpm-lock.yaml
|
# =====================
|
||||||
dist/
|
*.tsbuildinfo
|
||||||
log/
|
.turbo/
|
||||||
|
.vercel/
|
||||||
|
.output/
|
||||||
63
CLAUDE.md
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## 项目概述
|
||||||
|
|
||||||
|
RTC AIGC Demo — 基于火山引擎 RTC SDK 的实时 AI 语音对话演示应用,前后端分离架构。前端 React + TypeScript,后端 Python FastAPI。
|
||||||
|
|
||||||
|
## 常用命令
|
||||||
|
|
||||||
|
### 前端 (frontend/)
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
npm install # 安装依赖
|
||||||
|
npm run dev # 开发服务器 (localhost:3000)
|
||||||
|
npm run build # 生产构建
|
||||||
|
npm run eslint # ESLint 检查并修复
|
||||||
|
npm run stylelint # LESS 样式检查
|
||||||
|
npm run prettier # 代码格式化
|
||||||
|
npm run test # 运行测试
|
||||||
|
```
|
||||||
|
|
||||||
|
### 后端 (backend/)
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
cp .env.example .env # 首次需复制环境变量配置
|
||||||
|
uv sync # 安装依赖(使用 uv 包管理器)
|
||||||
|
uv run uvicorn server:app --host 0.0.0.0 --port 3001 --reload # 启动开发服务器
|
||||||
|
```
|
||||||
|
|
||||||
|
## 架构
|
||||||
|
|
||||||
|
### 前后端通信
|
||||||
|
- 前端默认连接 `http://localhost:3001`(配置在 `frontend/src/config/index.ts` 的 `AIGC_PROXY_HOST`)
|
||||||
|
- 后端 FastAPI 入口:`backend/server.py`
|
||||||
|
|
||||||
|
### 前端核心模块
|
||||||
|
- **状态管理**: Redux Toolkit,两个 slice:`store/slices/room.ts`(房间状态)、`store/slices/device.ts`(设备状态)
|
||||||
|
- **RTC 封装**: `src/lib/RtcClient.ts` 封装 `@volcengine/rtc` SDK
|
||||||
|
- **API 层**: `src/app/api.ts` 定义 `getScenes`、`StartVoiceChat`、`StopVoiceChat` 接口
|
||||||
|
- **页面结构**: `pages/MainPage/` 包含 Room(通话中)和 Antechamber(通话前)两个主要区域
|
||||||
|
- **路径别名**: `@/` → `src/`(通过 craco + tsconfig paths 配置)
|
||||||
|
- **UI 组件库**: Arco Design
|
||||||
|
- **CSS**: LESS
|
||||||
|
|
||||||
|
### 后端核心模块
|
||||||
|
- **场景配置**: `config/custom_scene.py` — 从环境变量构建场景配置,自动生成 RoomId/UserId/Token
|
||||||
|
- **API 代理**: `/proxy` 端点转发请求到火山引擎 RTC OpenAPI(含请求签名)
|
||||||
|
- **LLM 集成**: `services/local_llm_service.py` — Ark SDK 对接,SSE 流式响应
|
||||||
|
- **请求签名**: `security/signer.py`
|
||||||
|
- **Token 生成**: `security/rtc_token.py`
|
||||||
|
|
||||||
|
### LLM 模式
|
||||||
|
通过 `CUSTOM_LLM_MODE` 环境变量切换:
|
||||||
|
- `ArkV3`: 直接使用火山方舟 LLM
|
||||||
|
- `CustomLLM`: 自定义 LLM 回调(`/api/chat_callback` 端点)
|
||||||
|
|
||||||
|
### 关键环境变量(backend/.env)
|
||||||
|
- `CUSTOM_ACCESS_KEY_ID` / `CUSTOM_SECRET_KEY`: 火山引擎凭证
|
||||||
|
- `CUSTOM_RTC_APP_ID` / `CUSTOM_RTC_APP_KEY`: RTC 应用配置
|
||||||
|
- `CUSTOM_LLM_MODE` + 对应 LLM 配置
|
||||||
|
- `CUSTOM_ASR_APP_ID` / `CUSTOM_TTS_APP_ID`: 语音识别/合成配置
|
||||||
|
- `CUSTOM_AVATAR_*`: 数字人配置(可选)
|
||||||
18
LICENSE
@ -1,18 +0,0 @@
|
|||||||
Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved.
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
||||||
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
======
|
|
||||||
======
|
|
||||||
THE FOLLOWING SETS FORTH ATTRIBUTION NOTICES FOR THIRD PARTY SOFTWARE THAT MAY BE CONTAINED IN PORTIONS OF RTC AIGC DEMO.
|
|
||||||
======
|
|
||||||
WebRTC
|
|
||||||
Copyright (c) 2011, The WebRTC project authors. All rights reserved.
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
||||||
3. Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
======
|
|
||||||
91
README.md
@ -1,7 +1,7 @@
|
|||||||
# 交互式AIGC场景 AIGC Demo
|
# 交互式AIGC场景 AIGC Demo
|
||||||
|
|
||||||
此 Demo 为简化版本, 如您有 1.5.x 版本 UI 的诉求, 可切换至 1.5.1 分支。
|
此 Demo 为简化版本, 如您有 1.5.x 版本 UI 的诉求, 可切换至 1.5.1 分支。
|
||||||
跑通阶段时, 无须关心代码实现,仅需按需完成 `Server/scenes/*.json` 的场景信息填充即可。
|
跑通阶段时, 无须关心代码实现。当前推荐直接使用 `backend/.env` + `backend/config/custom_scene.py` 完成 `Custom` 场景配置。
|
||||||
|
|
||||||
## 简介
|
## 简介
|
||||||
- 在 AIGC 对话场景下,火山引擎 AIGC-RTC Server 云端服务,通过整合 RTC 音视频流处理,ASR 语音识别,大模型接口调用集成,以及 TTS 语音生成等能力,提供基于流式语音的端到端AIGC能力链路。
|
- 在 AIGC 对话场景下,火山引擎 AIGC-RTC Server 云端服务,通过整合 RTC 音视频流处理,ASR 语音识别,大模型接口调用集成,以及 TTS 语音生成等能力,提供基于流式语音的端到端AIGC能力链路。
|
||||||
@ -9,68 +9,101 @@
|
|||||||
- 同时火山引擎 RTC拥有成熟的音频 3A 处理、视频处理等技术以及大规模音视频聊天能力,可支持 AIGC 产品更便捷的支持多模态交互、多人互动等场景能力,保持交互的自然性和高效性。
|
- 同时火山引擎 RTC拥有成熟的音频 3A 处理、视频处理等技术以及大规模音视频聊天能力,可支持 AIGC 产品更便捷的支持多模态交互、多人互动等场景能力,保持交互的自然性和高效性。
|
||||||
|
|
||||||
## 【必看】环境准备
|
## 【必看】环境准备
|
||||||
**Node 版本: 16.0+**
|
|
||||||
|
> 本项目已重构为 monorepo 结构,前端位于 `frontend/`,Python 后端位于 `backend/`。
|
||||||
|
|
||||||
|
**前端环境:Node 16.0+**
|
||||||
|
**后端环境:Python 3.13+**
|
||||||
|
|
||||||
### 1. 运行环境
|
### 1. 运行环境
|
||||||
需要准备两个 Terminal,分别启动服务端和前端页面。
|
需要准备两个 Terminal,分别启动后端服务和前端页面。
|
||||||
|
|
||||||
### 2. 服务开通
|
### 2. 服务开通
|
||||||
开通 ASR、TTS、LLM、RTC 等服务,可参考 [开通服务](https://www.volcengine.com/docs/6348/1315561?s=g) 进行相关服务的授权与开通。
|
开通 ASR、TTS、LLM、RTC 等服务,可参考 [开通服务](https://www.volcengine.com/docs/6348/1315561?s=g) 进行相关服务的授权与开通。
|
||||||
|
|
||||||
### 3. 场景配置
|
### 3. 场景配置
|
||||||
`Server/scenes/*.json`
|
当前真正生效的主配置入口是 `backend/.env` + `backend/config/custom_scene.py`。
|
||||||
|
|
||||||
您可以自定义具体场景, 并按需根据模版填充 `SceneConfig`、`AccountConfig`、`RTCConfig`、`VoiceChat` 中需要的参数。
|
您可以自定义具体场景, 并按需根据模版填充 `SceneConfig`、`AccountConfig`、`RTCConfig`、`VoiceChat` 中需要的参数。
|
||||||
|
|
||||||
Demo 中以 `Custom` 场景为例,您可以自行新增场景。
|
Demo 中以 `Custom` 场景为例,您也可以自行新增其他 JSON 场景。
|
||||||
|
|
||||||
|
`Custom` 场景建议先执行以下步骤:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cp backend/.env.example backend/.env
|
||||||
|
```
|
||||||
|
|
||||||
注意:
|
注意:
|
||||||
- `SceneConfig`:场景的信息,例如名称、头像等。
|
- `SceneConfig`:场景的信息,例如名称、头像等。
|
||||||
- `AccountConfig`:场景下的账号信息,https://console.volcengine.com/iam/keymanage/ 获取 AK/SK。
|
- `AccountConfig`:`Custom` 场景默认从 `backend/.env` 读取 AK/SK,其他场景仍在 JSON 中配置。
|
||||||
- `RTCConfig`:场景下的 RTC 配置。
|
- `RTCConfig`:场景下的 RTC 配置。
|
||||||
- AppId、AppKey 可从 https://console.volcengine.com/rtc/aigc/listRTC 中获取。
|
- AppId、AppKey 可从 https://console.volcengine.com/rtc/aigc/listRTC 中获取。
|
||||||
|
- `Custom` 场景的 AppId、AppKey、RoomId、UserId、Token 可通过 `backend/.env` 注入。
|
||||||
- RoomId、UserId 可自定义也可不填,交由服务端生成。
|
- RoomId、UserId 可自定义也可不填,交由服务端生成。
|
||||||
- `VoiceChat`: 场景下的 AIGC 配置。
|
- `VoiceChat`: 场景下的 AIGC 配置。
|
||||||
|
- `Custom` 场景的 TaskId、Agent 用户信息、欢迎语、System Message 以及 LLM 模式参数均通过 `backend/.env` 注入。
|
||||||
|
- 支持 `ArkV3` 与 `CustomLLM` 两种模式;`CustomLLM` 当前推荐“当前 backend 内置本地回调 + ngrok 暴露公网地址”这条接法。
|
||||||
- 可参考 https://www.volcengine.com/docs/6348/1558163 中参数描述,完整填写参数内容。
|
- 可参考 https://www.volcengine.com/docs/6348/1558163 中参数描述,完整填写参数内容。
|
||||||
- 可通过 [快速跑通 Demo](https://console.volcengine.com/rtc/aigc/run?s=g) 快速获取参数, 跑通后点击右上角 `接入 API` 按钮复制相关代码贴到 JSON 配置文件中即可。
|
- `ASRConfig`、`TTSConfig`、`AvatarConfig` 等复杂结构由 `backend/config/custom_scene.py` 维护默认值,并从 `backend/.env` 读取关键运行参数。
|
||||||
|
- 当前首版默认不启用 RAG 主链路,`backend/services/rag_service.py` 仅保留为后续扩展位。
|
||||||
|
- 可通过 [快速跑通 Demo](https://console.volcengine.com/rtc/aigc/run?s=g) 快速获取参数,再分别填入 `backend/.env` 和 `backend/config/custom_scene.py` 的默认结构中。
|
||||||
|
|
||||||
|
### 第三方 CustomLLM 接入
|
||||||
|
|
||||||
|
如果你要把本地服务接成 `CustomLLM`,推荐直接让当前 `backend` 自己提供回调接口:
|
||||||
|
|
||||||
|
```dotenv
|
||||||
|
CUSTOM_LLM_MODE=CustomLLM
|
||||||
|
CUSTOM_LLM_URL=http://127.0.0.1:3001/api/chat_callback
|
||||||
|
CUSTOM_LLM_MODEL_NAME=my-model
|
||||||
|
CUSTOM_LLM_API_KEY=your-callback-token
|
||||||
|
ARK_API_KEY=your-ark-api-key
|
||||||
|
ARK_ENDPOINT_ID=your-ark-endpoint-id
|
||||||
|
```
|
||||||
|
|
||||||
|
本地起好 `backend` 以后,用 `ngrok` 暴露 `3001` 端口,再把 `CUSTOM_LLM_URL` 改成公网地址:
|
||||||
|
|
||||||
|
```dotenv
|
||||||
|
CUSTOM_LLM_URL=https://your-ngrok-domain.ngrok-free.app/api/chat_callback
|
||||||
|
```
|
||||||
|
|
||||||
|
说明:
|
||||||
|
|
||||||
|
- `CUSTOM_LLM_URL` 是写进 `StartVoiceChat.LLMConfig.Url` 的地址
|
||||||
|
- 默认可以先用本地地址启动服务,等 `ngrok` 跑起来后再改成公网 `https` 地址
|
||||||
|
- 当前 backend 内置的固定回调路由是 `POST /api/chat_callback`
|
||||||
|
- `RTC_OPENAPI_VERSION` 默认使用 `2025-06-01`
|
||||||
## 快速开始
|
## 快速开始
|
||||||
请注意,服务端和 Web 端都需要启动, 启动步骤如下:
|
请注意,服务端和 Web 端都需要启动, 启动步骤如下:
|
||||||
### 服务端
|
### 后端服务(Python FastAPI)
|
||||||
进到项目根目录
|
|
||||||
#### 安装依赖
|
|
||||||
```shell
|
```shell
|
||||||
cd Server
|
cd backend
|
||||||
yarn
|
cp .env.example .env
|
||||||
```
|
uv sync
|
||||||
#### 运行项目
|
uv run uvicorn server:app --host 0.0.0.0 --port 3001 --reload
|
||||||
```shell
|
|
||||||
yarn dev
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 前端页面
|
### 前端页面
|
||||||
进到项目根目录
|
|
||||||
#### 安装依赖
|
|
||||||
```shell
|
```shell
|
||||||
yarn
|
cd frontend
|
||||||
```
|
npm install
|
||||||
#### 运行项目
|
npm run dev
|
||||||
```shell
|
|
||||||
yarn dev
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 常见问题
|
### 常见问题
|
||||||
| 问题 | 解决方案 |
|
| 问题 | 解决方案 |
|
||||||
| :-- | :-- |
|
| :-- | :-- |
|
||||||
| 如何使用第三方模型、Coze Bot | 模型相关配置代码对应目录 `src/config/scenes/` 下json 文件,填写对应官方模型/ Coze/ 第三方模型的参数后,可点击页面上的 "修改 AI 人设" 进行切换。 |
|
| 如何使用第三方模型、Coze Bot | 当前主配置入口是 `backend/.env` + `backend/config/custom_scene.py`。如果接自己的模型,推荐使用当前 backend 内置的 `/api/chat_callback` 作为 `CustomLLM` 回调接口,再通过 `ngrok` 暴露公网地址,并把它填到 `CUSTOM_LLM_URL`。 |
|
||||||
| **启动智能体之后, 对话无反馈,或者一直停留在 "AI 准备中, 请稍侯"** | <li>可能因为控制台中相关权限没有正常授予,请参考[流程](https://www.volcengine.com/docs/6348/1315561?s=g)再次确认下是否完成相关操作。此问题的可能性较大,建议仔细对照是否已经将相应的权限开通。</li><li>参数传递可能有问题, 例如参数大小写、类型等问题,请再次确认下这类型问题是否存在。</li><li>相关资源可能未开通或者用量不足/欠费,请再次确认。</li><li>**请检查当前使用的模型 ID 等内容都是正确且可用的。**</li> |
|
| **启动智能体之后, 对话无反馈,或者一直停留在 "AI 准备中, 请稍侯";在启用数字人的情况下,一直停留在“数字人准备中,请稍候”** | <li>可能因为控制台中相关权限没有正常授予,请参考[流程](https://www.volcengine.com/docs/6348/1315561?s=g)再次确认下是否完成相关操作。此问题的可能性较大,建议仔细对照是否已经将相应的权限开通。</li><li>参数传递可能有问题, 例如参数大小写、类型等问题,请再次确认下这类型问题是否存在。</li><li>相关资源可能未开通或者用量不足/欠费,请再次确认。</li><li>**请检查当前使用的模型 ID / 数字人 AppId / Token 等内容都是正确且可用的。**</li><li>数字人服务有并发限制,当达到并发限制时,同样会表现为一直停留在“数字人准备中”状态</li> |
|
||||||
| **浏览器报了 `Uncaught (in promise) r: token_error` 错误** | 请检查您填在项目中的 RTC Token 是否合法,检测用于生成 Token 的 UserId、RoomId 以及 Token 本身是否与项目中填写的一致;或者 Token 可能过期, 可尝试重新生成下。 |
|
| **浏览器报了 `Uncaught (in promise) r: token_error` 错误** | 请检查您填在项目中的 RTC Token 是否合法,检测用于生成 Token 的 UserId、RoomId 以及 Token 本身是否与项目中填写的一致;或者 Token 可能过期, 可尝试重新生成下。 |
|
||||||
| **[StartVoiceChat]Failed(Reason: The task has been started. Please do not call the startup task interface repeatedly.)** 报错 | 如果设置的 RoomId、UserId 为固定值,重复调用 startAgent 会导致出错,只需先调用 stopAgent 后再重新 startAgent 即可。 |
|
| **[StartVoiceChat]Failed(Reason: The task has been started. Please do not call the startup task interface repeatedly.)** 报错 | 如果设置的 RoomId、UserId 为固定值,重复调用 startAgent 会导致出错,只需先调用 stopAgent 后再重新 startAgent 即可。 |
|
||||||
|
| 为什么麦克风、摄像头开启失败?浏览器报了`TypeError: Cannot read properties of undefined (reading 'getUserMedia')` | 检查当前页面是否为[安全上下文](https://developer.mozilla.org/zh-CN/docs/Web/Security/Secure_Contexts)(简单来说,检查当前页面是否为 `localhost` 或者 是否为 https 协议)。浏览器[限制](https://developer.mozilla.org/zh-CN/docs/Web/Security/Secure_Contexts/features_restricted_to_secure_contexts) `getUserMedia` 只能在安全上下文中使用。 |
|
||||||
| 为什么我的麦克风正常、摄像头也正常,但是设备没有正常工作? | 可能是设备权限未授予,详情可参考 [Web 排查设备权限获取失败问题](https://www.volcengine.com/docs/6348/1356355?s=g)。 |
|
| 为什么我的麦克风正常、摄像头也正常,但是设备没有正常工作? | 可能是设备权限未授予,详情可参考 [Web 排查设备权限获取失败问题](https://www.volcengine.com/docs/6348/1356355?s=g)。 |
|
||||||
| 接口调用时, 返回 "Invalid 'Authorization' header, Pls check your authorization header" 错误 | `Server/app.js` 中的 AK/SK 不正确 |
|
| 接口调用时, 返回 "Invalid 'Authorization' header, Pls check your authorization header" 错误 | `Custom` 场景请检查 `backend/.env` 中的 `CUSTOM_ACCESS_KEY_ID` / `CUSTOM_SECRET_KEY`;其他场景请检查对应 `backend/scenes/*.json` 中的 AK/SK |
|
||||||
| 什么是 RTC | **R**eal **T**ime **C**ommunication, RTC 的概念可参考[官网文档](https://www.volcengine.com/docs/6348/66812?s=g)。 |
|
| 什么是 RTC | **R**eal **T**ime **C**ommunication, RTC 的概念可参考[官网文档](https://www.volcengine.com/docs/6348/66812?s=g)。 |
|
||||||
| 不清楚什么是主账号,什么是子账号 | 可以参考[官方概念](https://www.volcengine.com/docs/6257/64963?hyperlink_open_type=lark.open_in_browser&s=g) 。|
|
| 不清楚什么是主账号,什么是子账号 | 可以参考[官方概念](https://www.volcengine.com/docs/6257/64963?hyperlink_open_type=lark.open_in_browser&s=g) 。|
|
||||||
| 我有自己的服务端了, 我应该怎么让前端调用我的服务端呢 | 修改 `src/config/index.ts` 中的 `AIGC_PROXY_HOST` 请求域名和接口并在 `src/app/api.ts` 中修改接口参数配置 `APIS_CONFIG` |
|
| 我有自己的服务端了, 我应该怎么让前端调用我的服务端呢 | 修改 `frontend/src/config/index.ts` 中的 `AIGC_PROXY_HOST` 请求域名;如需同步调整接口路由,可再看 `frontend/src/app/api.ts` 里的 `BasicAPIs` / `AigcAPIs` |
|
||||||
|
|
||||||
如果有上述以外的问题,欢迎联系我们反馈。
|
如果有上述以外的问题,欢迎联系我们反馈。
|
||||||
|
|
||||||
@ -87,6 +120,8 @@ yarn dev
|
|||||||
### Demo 更新
|
### Demo 更新
|
||||||
|
|
||||||
#### [1.6.0]
|
#### [1.6.0]
|
||||||
|
- 2025-09-30
|
||||||
|
- 更新数字人场景相关配置
|
||||||
- 2025-07-08
|
- 2025-07-08
|
||||||
- 更新 RTC Web SDK 版本至 4.66.20
|
- 更新 RTC Web SDK 版本至 4.66.20
|
||||||
- 2025-06-26
|
- 2025-06-26
|
||||||
@ -100,4 +135,4 @@ yarn dev
|
|||||||
- 更新 UI 和参数配置方式
|
- 更新 UI 和参数配置方式
|
||||||
- 更新 Readme 文档
|
- 更新 Readme 文档
|
||||||
- 追加 Node 服务的参数检测能力
|
- 追加 Node 服务的参数检测能力
|
||||||
- 追加 Node 服务的 Token 生成能力
|
- 追加 Node 服务的 Token 生成能力
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
registry = 'https://registry.npmjs.org/'
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
# Node Server
|
|
||||||
|
|
||||||
## 启动命令
|
|
||||||
```
|
|
||||||
yarn
|
|
||||||
|
|
||||||
yarn dev
|
|
||||||
```
|
|
||||||
|
|
||||||
## 使用须知
|
|
||||||
Node 服务启动时会自动读取 `Server/scenes` 下的所有文件作为可用的场景, 并通过接口 API 返回相关信息。
|
|
||||||
|
|
||||||
因此,您需要:
|
|
||||||
1. 在 `Server/scenes` 目录下参考其它 JSON 的格式, 自定义创建一个 `xxxx.json` 文件,用于描述您的场景,其中 xxxx 为场景名称。
|
|
||||||
2. 确保您的 `.json` 文件符合模版定义(可参考 Custom.json), 大小写敏感。
|
|
||||||
3. 新增场景 JSON 后须重启 Node 服务,保证场景信息被正常读取。
|
|
||||||
4. JSON 文件中, 若 `RTCConfig.RoomId`、`RTCConfig.UserId`、`RTCConfig.Token` 其中之一未填写, Node 服务将自动生成对应的值以保证对话可以正常启动。
|
|
||||||
|
|
||||||
|
|
||||||
## 相关参数获取
|
|
||||||
- AccountConfig
|
|
||||||
- 可在 https://console.volcengine.com/iam/keymanage/ 获取 AK/SK。
|
|
||||||
- RTCConfig
|
|
||||||
- AppId、AppKey 可从 https://console.volcengine.com/rtc/aigc/listRTC 中获取。
|
|
||||||
- RoomId、UserId 可自定义也可不填,交由服务端生成。
|
|
||||||
- VoiceChat
|
|
||||||
- 可参考 https://www.volcengine.com/docs/6348/1558163 中参数描述
|
|
||||||
- 可通过 [快速跑通 Demo](https://console.volcengine.com/rtc/aigc/run?s=g) 快速获取参数, 跑通后点击右上角 `接入 API` 按钮复制相关代码贴到 JSON 配置文件中即可。
|
|
||||||
|
|
||||||
|
|
||||||
## 注意
|
|
||||||
- 相关错误会通过服务端接口返回。
|
|
||||||
- Node 服务会根据您配置的 `VoiceChat` 中是否存在视觉模型相关的配置返回相关信息给前端页面, 从而控制相关 UI 是否展示。
|
|
||||||
- 使用时请留意相关服务已开通。
|
|
||||||
135
Server/app.js
@ -1,135 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved.
|
|
||||||
* SPDX-license-identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
const Koa = require('koa');
|
|
||||||
const uuid = require('uuid');
|
|
||||||
const bodyParser = require('koa-bodyparser');
|
|
||||||
const cors = require('koa2-cors');
|
|
||||||
const { Signer } = require('@volcengine/openapi');
|
|
||||||
const fetch = require('node-fetch');
|
|
||||||
const { wrapper, assert, readFiles } = require('./util');
|
|
||||||
const TokenManager = require('./token');
|
|
||||||
const Privileges = require('./token').privileges;
|
|
||||||
|
|
||||||
const Scenes = readFiles('./scenes', '.json');
|
|
||||||
|
|
||||||
const app = new Koa();
|
|
||||||
|
|
||||||
app.use(cors({
|
|
||||||
origin: '*'
|
|
||||||
}));
|
|
||||||
|
|
||||||
app.use(bodyParser());
|
|
||||||
|
|
||||||
app.use(async ctx => {
|
|
||||||
/**
|
|
||||||
* @brief 代理 AIGC 的 OpenAPI 请求
|
|
||||||
*/
|
|
||||||
await wrapper({
|
|
||||||
ctx,
|
|
||||||
apiName: 'proxy',
|
|
||||||
containResponseMetadata: false,
|
|
||||||
logic: async () => {
|
|
||||||
const { Action, Version = '2024-12-01' } = ctx.query || {};
|
|
||||||
assert(Action, 'Action 不能为空');
|
|
||||||
assert(Version, 'Version 不能为空');
|
|
||||||
|
|
||||||
const { SceneID } = ctx.request.body;
|
|
||||||
|
|
||||||
assert(SceneID, 'SceneID 不能为空, SceneID 用于指定场景的 JSON');
|
|
||||||
|
|
||||||
const JSONData = Scenes[SceneID];
|
|
||||||
assert(JSONData, `${SceneID} 不存在, 请先在 Server/scenes 下定义该场景的 JSON.`);
|
|
||||||
|
|
||||||
const { VoiceChat = {}, AccountConfig = {} } = JSONData;
|
|
||||||
assert(AccountConfig.accessKeyId, 'AccountConfig.accessKeyId 不能为空');
|
|
||||||
assert(AccountConfig.secretKey, 'AccountConfig.secretKey 不能为空');
|
|
||||||
|
|
||||||
let body = {};
|
|
||||||
switch(Action) {
|
|
||||||
case 'StartVoiceChat':
|
|
||||||
body = VoiceChat;
|
|
||||||
break;
|
|
||||||
case 'StopVoiceChat':
|
|
||||||
const { AppId, RoomId, TaskId } = VoiceChat;
|
|
||||||
assert(AppId, 'VoiceChat.AppId 不能为空');
|
|
||||||
assert(RoomId, 'VoiceChat.RoomId 不能为空');
|
|
||||||
assert(TaskId, 'VoiceChat.TaskId 不能为空');
|
|
||||||
body = {
|
|
||||||
AppId, RoomId, TaskId
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 参考 https://github.com/volcengine/volc-sdk-nodejs 可获取更多 火山 TOP 网关 SDK 的使用方式 */
|
|
||||||
const openApiRequestData = {
|
|
||||||
region: 'cn-north-1',
|
|
||||||
method: 'POST',
|
|
||||||
params: {
|
|
||||||
Action,
|
|
||||||
Version,
|
|
||||||
},
|
|
||||||
headers: {
|
|
||||||
Host: 'rtc.volcengineapi.com',
|
|
||||||
'Content-type': 'application/json',
|
|
||||||
},
|
|
||||||
body,
|
|
||||||
};
|
|
||||||
const signer = new Signer(openApiRequestData, "rtc");
|
|
||||||
signer.addAuthorization(AccountConfig);
|
|
||||||
|
|
||||||
/** 参考 https://www.volcengine.com/docs/6348/69828 可获取更多 OpenAPI 的信息 */
|
|
||||||
const result = await fetch(`https://rtc.volcengineapi.com?Action=${Action}&Version=${Version}`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: openApiRequestData.headers,
|
|
||||||
body: JSON.stringify(body),
|
|
||||||
});
|
|
||||||
return result.json();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
wrapper({
|
|
||||||
ctx,
|
|
||||||
apiName: 'getScenes',
|
|
||||||
logic: () => {
|
|
||||||
const scenes = Object.keys(Scenes).map((scene) => {
|
|
||||||
const { SceneConfig, RTCConfig = {}, VoiceChat } = Scenes[scene];
|
|
||||||
const { AppId, RoomId, UserId, AppKey, Token } = RTCConfig;
|
|
||||||
assert(AppId, `${scene} 场景的 RTCConfig.AppId 不能为空`);
|
|
||||||
if (AppId && (!Token || !UserId || !RoomId)) {
|
|
||||||
RTCConfig.RoomId = VoiceChat.RoomId = RoomId || uuid.v4();
|
|
||||||
RTCConfig.UserId = VoiceChat.AgentConfig.TargetUserId[0] = UserId || uuid.v4();
|
|
||||||
|
|
||||||
assert(AppKey, `自动生成 Token 时, ${scene} 场景的 AppKey 不可为空`);
|
|
||||||
const key = new TokenManager.AccessToken(AppId, AppKey, RTCConfig.RoomId, RTCConfig.UserId);
|
|
||||||
key.addPrivilege(Privileges.PrivSubscribeStream, 0);
|
|
||||||
key.addPrivilege(Privileges.PrivPublishStream, 0);
|
|
||||||
key.expireTime(Math.floor(new Date() / 1000) + (24 * 3600));
|
|
||||||
RTCConfig.Token = key.serialize();
|
|
||||||
}
|
|
||||||
SceneConfig.id = scene;
|
|
||||||
SceneConfig.botName = VoiceChat?.AgentConfig?.UserId;
|
|
||||||
SceneConfig.isInterruptMode = VoiceChat?.Config?.InterruptMode === 0;
|
|
||||||
SceneConfig.isVision = VoiceChat?.Config?.LLMConfig?.VisionConfig?.Enable;
|
|
||||||
SceneConfig.isScreenMode = VoiceChat?.Config?.LLMConfig?.VisionConfig?.SnapshoutConfig?.StreamType === 1;
|
|
||||||
delete RTCConfig.AppKey;
|
|
||||||
return {
|
|
||||||
scene: SceneConfig || {},
|
|
||||||
rtc: RTCConfig,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
return {
|
|
||||||
scenes,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
app.listen(3001, () => {
|
|
||||||
console.log('AIGC Server is running at http://localhost:3001');
|
|
||||||
});
|
|
||||||
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"watch": ["."],
|
|
||||||
"ext": "js,json",
|
|
||||||
"ignore": ["node_modules/*"]
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "AIGCServer",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "Server for demo to call open api",
|
|
||||||
"main": "app.js",
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"private": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@volcengine/openapi": "^1.22.0",
|
|
||||||
"koa": "^2.15.3",
|
|
||||||
"koa-bodyparser": "^4.4.1",
|
|
||||||
"koa2-cors": "^2.0.6",
|
|
||||||
"lodash": "^4.17.21",
|
|
||||||
"node-fetch": "^2.3.2",
|
|
||||||
"uuid": "^11.1.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"nodemon": "^3.1.10"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"dev": "nodemon app.js",
|
|
||||||
"start": "nodemon app.js"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
{
|
|
||||||
"SceneConfig": {
|
|
||||||
"icon": "https://lf3-rtc-demo.volccdn.com/obj/rtc-aigc-assets/DoubaoAvatar.png",
|
|
||||||
"name": "自定义助手"
|
|
||||||
},
|
|
||||||
"AccountConfig": {
|
|
||||||
"accessKeyId": "",
|
|
||||||
"secretKey": ""
|
|
||||||
},
|
|
||||||
"RTCConfig": {
|
|
||||||
"AppId": "",
|
|
||||||
"AppKey": "",
|
|
||||||
"RoomId": "",
|
|
||||||
"UserId": "",
|
|
||||||
"Token": ""
|
|
||||||
},
|
|
||||||
"VoiceChat": {
|
|
||||||
"AppId": "",
|
|
||||||
"RoomId": "",
|
|
||||||
"TaskId": "",
|
|
||||||
"AgentConfig": {
|
|
||||||
"TargetUserId": [
|
|
||||||
""
|
|
||||||
],
|
|
||||||
"WelcomeMessage": "你好,我是小宁,有什么需要帮忙的吗?",
|
|
||||||
"UserId": "",
|
|
||||||
"EnableConversationStateCallback": true
|
|
||||||
},
|
|
||||||
"Config": {
|
|
||||||
"ASRConfig": {
|
|
||||||
"Provider": "volcano",
|
|
||||||
"ProviderParams": {
|
|
||||||
"Mode": "smallmodel",
|
|
||||||
"AppId": "",
|
|
||||||
"Cluster": "volcengine_streaming_common"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"TTSConfig": {
|
|
||||||
"Provider": "volcano",
|
|
||||||
"ProviderParams": {
|
|
||||||
"app": {
|
|
||||||
"appid": "",
|
|
||||||
"cluster": "volcano_tts"
|
|
||||||
},
|
|
||||||
"audio": {
|
|
||||||
"voice_type": "BV001_streaming",
|
|
||||||
"speed_ratio": 1,
|
|
||||||
"pitch_ratio": 1,
|
|
||||||
"volume_ratio": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"LLMConfig": {
|
|
||||||
"Mode": "ArkV3",
|
|
||||||
"EndPointId": "",
|
|
||||||
"SystemMessages": [
|
|
||||||
"你是小宁,性格幽默又善解人意。你在表达时需简明扼要,有自己的观点。"
|
|
||||||
],
|
|
||||||
"VisionConfig": {
|
|
||||||
"Enable": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"InterruptMode": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
244
Server/token.js
@ -1,244 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved.
|
|
||||||
* SPDX-license-identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
var crypto = require('crypto');
|
|
||||||
|
|
||||||
var randomInt = Math.floor(Math.random() * 0xFFFFFFFF);
|
|
||||||
|
|
||||||
const VERSION = "001";
|
|
||||||
const VERSION_LENGTH = 3;
|
|
||||||
|
|
||||||
const APP_ID_LENGTH = 24;
|
|
||||||
|
|
||||||
privileges = {
|
|
||||||
PrivPublishStream: 0,
|
|
||||||
|
|
||||||
// not exported, do not use directly
|
|
||||||
privPublishAudioStream: 1,
|
|
||||||
privPublishVideoStream: 2,
|
|
||||||
privPublishDataStream: 3,
|
|
||||||
|
|
||||||
PrivSubscribeStream: 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
module.exports.privileges = privileges;
|
|
||||||
|
|
||||||
// Initializes token struct by required parameters.
|
|
||||||
var AccessToken = function (appID, appKey, roomID, userID) {
|
|
||||||
let token = this;
|
|
||||||
this.appID = appID;
|
|
||||||
this.appKey = appKey;
|
|
||||||
this.roomID = roomID;
|
|
||||||
this.userID = userID;
|
|
||||||
this.issuedAt = Math.floor(new Date() / 1000);
|
|
||||||
this.nonce = randomInt;
|
|
||||||
this.expireAt = 0;
|
|
||||||
this.privileges = {};
|
|
||||||
|
|
||||||
// AddPrivilege adds permission for token with an expiration.
|
|
||||||
this.addPrivilege = function (privilege, expireTimestamp) {
|
|
||||||
if (token.privileges === undefined) {
|
|
||||||
token.privileges = {}
|
|
||||||
}
|
|
||||||
token.privileges[privilege] = expireTimestamp;
|
|
||||||
|
|
||||||
if (privilege === privileges.PrivPublishStream) {
|
|
||||||
token.privileges[privileges.privPublishVideoStream] = expireTimestamp;
|
|
||||||
token.privileges[privileges.privPublishAudioStream] = expireTimestamp;
|
|
||||||
token.privileges[privileges.privPublishDataStream] = expireTimestamp;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// ExpireTime sets token expire time, won't expire by default.
|
|
||||||
// The token will be invalid after expireTime no matter what privilege's expireTime is.
|
|
||||||
this.expireTime = function (expireTimestamp) {
|
|
||||||
token.expireAt = expireTimestamp;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.packMsg = function () {
|
|
||||||
var bufM = new ByteBuf();
|
|
||||||
bufM.putUint32(token.nonce);
|
|
||||||
bufM.putUint32(token.issuedAt);
|
|
||||||
bufM.putUint32(token.expireAt);
|
|
||||||
bufM.putString(token.roomID);
|
|
||||||
bufM.putString(token.userID);
|
|
||||||
bufM.putTreeMapUInt32(token.privileges);
|
|
||||||
return bufM.pack()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Serialize generates the token string
|
|
||||||
this.serialize = function () {
|
|
||||||
var bytesM = this.packMsg();
|
|
||||||
|
|
||||||
var signature = encodeHMac(token.appKey, bytesM);
|
|
||||||
var content = new ByteBuf().putBytes(bytesM).putBytes(signature).pack();
|
|
||||||
|
|
||||||
return (VERSION + token.appID + content.toString('base64'));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Verify checks if this token valid, called by server side.
|
|
||||||
this.verify = function (key) {
|
|
||||||
if (token.expireAt > 0 && Math.floor(new Date() / 1000) > token.expireAt) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
token.appKey = key;
|
|
||||||
return encodeHMac(token.appKey, this.packMsg()).toString() === token.signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// Parse retrieves token information from raw string
|
|
||||||
var Parse = function (raw) {
|
|
||||||
try {
|
|
||||||
if (raw.length <= VERSION_LENGTH + APP_ID_LENGTH) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (raw.substr(0, VERSION_LENGTH) !== VERSION) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var token = new AccessToken("", "", "", "");
|
|
||||||
token.appID = raw.substr(VERSION_LENGTH, APP_ID_LENGTH);
|
|
||||||
|
|
||||||
var contentBuf = Buffer.from(raw.substr(VERSION_LENGTH + APP_ID_LENGTH), 'base64');
|
|
||||||
var readbuf = new ReadByteBuf(contentBuf);
|
|
||||||
|
|
||||||
var msg = readbuf.getString();
|
|
||||||
token.signature = readbuf.getString().toString();
|
|
||||||
|
|
||||||
// parse msg
|
|
||||||
var msgBuf = new ReadByteBuf(msg);
|
|
||||||
token.nonce = msgBuf.getUint32();
|
|
||||||
token.issuedAt = msgBuf.getUint32();
|
|
||||||
token.expireAt = msgBuf.getUint32();
|
|
||||||
token.roomID = msgBuf.getString().toString();
|
|
||||||
token.userID = msgBuf.getString().toString();
|
|
||||||
token.privileges = msgBuf.getTreeMapUInt32();
|
|
||||||
|
|
||||||
return token
|
|
||||||
} catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
module.exports.version = VERSION;
|
|
||||||
module.exports.AccessToken = AccessToken;
|
|
||||||
module.exports.Parse = Parse;
|
|
||||||
|
|
||||||
var encodeHMac = function (key, message) {
|
|
||||||
return crypto.createHmac('sha256', key).update(message).digest();
|
|
||||||
};
|
|
||||||
|
|
||||||
var ByteBuf = function () {
|
|
||||||
var that = {
|
|
||||||
buffer: Buffer.alloc(1024)
|
|
||||||
, position: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
that.pack = function () {
|
|
||||||
var out = Buffer.alloc(that.position);
|
|
||||||
that.buffer.copy(out, 0, 0, out.length);
|
|
||||||
return out;
|
|
||||||
};
|
|
||||||
|
|
||||||
that.putUint16 = function (v) {
|
|
||||||
that.buffer.writeUInt16LE(v, that.position);
|
|
||||||
that.position += 2;
|
|
||||||
return that;
|
|
||||||
};
|
|
||||||
|
|
||||||
that.putUint32 = function (v) {
|
|
||||||
that.buffer.writeUInt32LE(v, that.position);
|
|
||||||
that.position += 4;
|
|
||||||
return that;
|
|
||||||
};
|
|
||||||
|
|
||||||
that.putBytes = function (bytes) {
|
|
||||||
that.putUint16(bytes.length);
|
|
||||||
bytes.copy(that.buffer, that.position);
|
|
||||||
that.position += bytes.length;
|
|
||||||
return that;
|
|
||||||
};
|
|
||||||
|
|
||||||
that.putString = function (str) {
|
|
||||||
return that.putBytes(Buffer.from(str));
|
|
||||||
};
|
|
||||||
|
|
||||||
that.putTreeMap = function (map) {
|
|
||||||
if (!map) {
|
|
||||||
that.putUint16(0);
|
|
||||||
return that;
|
|
||||||
}
|
|
||||||
|
|
||||||
that.putUint16(Object.keys(map).length);
|
|
||||||
for (var key in map) {
|
|
||||||
that.putUint16(key);
|
|
||||||
that.putString(map[key]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return that;
|
|
||||||
};
|
|
||||||
|
|
||||||
that.putTreeMapUInt32 = function (map) {
|
|
||||||
if (!map) {
|
|
||||||
that.putUint16(0);
|
|
||||||
return that;
|
|
||||||
}
|
|
||||||
|
|
||||||
that.putUint16(Object.keys(map).length);
|
|
||||||
for (var key in map) {
|
|
||||||
that.putUint16(key);
|
|
||||||
that.putUint32(map[key]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return that;
|
|
||||||
};
|
|
||||||
|
|
||||||
return that;
|
|
||||||
};
|
|
||||||
|
|
||||||
var ReadByteBuf = function (bytes) {
|
|
||||||
var that = {
|
|
||||||
buffer: bytes
|
|
||||||
, position: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
that.getUint16 = function () {
|
|
||||||
var ret = that.buffer.readUInt16LE(that.position);
|
|
||||||
that.position += 2;
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
that.getUint32 = function () {
|
|
||||||
var ret = that.buffer.readUInt32LE(that.position);
|
|
||||||
that.position += 4;
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
that.getString = function () {
|
|
||||||
var len = that.getUint16();
|
|
||||||
|
|
||||||
var out = Buffer.alloc(len);
|
|
||||||
that.buffer.copy(out, 0, that.position, (that.position + len));
|
|
||||||
that.position += len;
|
|
||||||
return out;
|
|
||||||
};
|
|
||||||
|
|
||||||
that.getTreeMapUInt32 = function () {
|
|
||||||
var map = {};
|
|
||||||
var len = that.getUint16();
|
|
||||||
for (var i = 0; i < len; i++) {
|
|
||||||
var key = that.getUint16();
|
|
||||||
var value = that.getUint32();
|
|
||||||
map[key] = value;
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
};
|
|
||||||
|
|
||||||
return that;
|
|
||||||
};
|
|
||||||
@ -1,68 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved.
|
|
||||||
* SPDX-license-identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
const judgeMethodPath = (method) => {
|
|
||||||
return (ctx, pathname) => ctx.method.toLowerCase() === method && ctx.url.startsWith(`/${pathname}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const readFiles = (dir, suffix) => {
|
|
||||||
const scenes = {};
|
|
||||||
fs.readdirSync(path.join(__dirname, dir)).map((p) => {
|
|
||||||
const data = JSON.parse(fs.readFileSync(path.join(__dirname, dir, p)));
|
|
||||||
scenes[p.replace(suffix, '')] = data;
|
|
||||||
});
|
|
||||||
return scenes;
|
|
||||||
}
|
|
||||||
|
|
||||||
const assert = (expression, msg) => {
|
|
||||||
if (!!!expression || expression?.includes?.(' ')) {
|
|
||||||
console.log(`\x1b[31m校验失败: ${msg}\x1b[0m`)
|
|
||||||
throw new Error(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const wrapper = async ({
|
|
||||||
ctx,
|
|
||||||
method = 'post',
|
|
||||||
apiName,
|
|
||||||
logic,
|
|
||||||
containResponseMetadata = true,
|
|
||||||
}) => {
|
|
||||||
if (judgeMethodPath(method)(ctx, apiName)) {
|
|
||||||
const ResponseMetadata = { Action: apiName };
|
|
||||||
try {
|
|
||||||
const res = await logic();
|
|
||||||
ctx.body = containResponseMetadata ? {
|
|
||||||
ResponseMetadata,
|
|
||||||
Result: res,
|
|
||||||
} : res;
|
|
||||||
} catch (e) {
|
|
||||||
ResponseMetadata.Error = {
|
|
||||||
Code: -1,
|
|
||||||
Message: e?.toString(),
|
|
||||||
};
|
|
||||||
ctx.body = {
|
|
||||||
ResponseMetadata,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const deepAssert = (params = {}, prefix = '') => {
|
|
||||||
if (typeof params === 'object') {
|
|
||||||
Object.keys(params).forEach(key => {
|
|
||||||
assert(params[key], `${prefix}: ${key} 不能为空, 请修改 /Server/sensitive.js`);
|
|
||||||
deepAssert(params[key], `${prefix}: ${key}.`);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
wrapper,
|
|
||||||
assert,
|
|
||||||
readFiles,
|
|
||||||
}
|
|
||||||
879
Server/yarn.lock
@ -1,879 +0,0 @@
|
|||||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
|
||||||
# yarn lockfile v1
|
|
||||||
|
|
||||||
|
|
||||||
"@hapi/bourne@^3.0.0":
|
|
||||||
version "3.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-3.0.0.tgz#f11fdf7dda62fe8e336fa7c6642d9041f30356d7"
|
|
||||||
integrity sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w==
|
|
||||||
|
|
||||||
"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
|
|
||||||
version "1.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
|
|
||||||
integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==
|
|
||||||
|
|
||||||
"@protobufjs/base64@^1.1.2":
|
|
||||||
version "1.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735"
|
|
||||||
integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==
|
|
||||||
|
|
||||||
"@protobufjs/codegen@^2.0.4":
|
|
||||||
version "2.0.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb"
|
|
||||||
integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==
|
|
||||||
|
|
||||||
"@protobufjs/eventemitter@^1.1.0":
|
|
||||||
version "1.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70"
|
|
||||||
integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==
|
|
||||||
|
|
||||||
"@protobufjs/fetch@^1.1.0":
|
|
||||||
version "1.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45"
|
|
||||||
integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==
|
|
||||||
dependencies:
|
|
||||||
"@protobufjs/aspromise" "^1.1.1"
|
|
||||||
"@protobufjs/inquire" "^1.1.0"
|
|
||||||
|
|
||||||
"@protobufjs/float@^1.0.2":
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1"
|
|
||||||
integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==
|
|
||||||
|
|
||||||
"@protobufjs/inquire@^1.1.0":
|
|
||||||
version "1.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089"
|
|
||||||
integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==
|
|
||||||
|
|
||||||
"@protobufjs/path@^1.1.2":
|
|
||||||
version "1.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d"
|
|
||||||
integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==
|
|
||||||
|
|
||||||
"@protobufjs/pool@^1.1.0":
|
|
||||||
version "1.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54"
|
|
||||||
integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==
|
|
||||||
|
|
||||||
"@protobufjs/utf8@^1.1.0":
|
|
||||||
version "1.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
|
|
||||||
integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
|
|
||||||
|
|
||||||
"@types/node@>=13.7.0":
|
|
||||||
version "22.7.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.5.tgz#cfde981727a7ab3611a481510b473ae54442b92b"
|
|
||||||
integrity sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==
|
|
||||||
dependencies:
|
|
||||||
undici-types "~6.19.2"
|
|
||||||
|
|
||||||
"@volcengine/openapi@^1.22.0":
|
|
||||||
version "1.22.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@volcengine/openapi/-/openapi-1.22.0.tgz#e2f76b4811b1739605ca4e935e7f0a40cce5000c"
|
|
||||||
integrity sha512-FtXc9Hbb+MhysU8y+SjkC84Hpnv9FFUNLbJmdGRpmlo8a6GmRY2c5kMTgY8M2Ai+O7+o1OebhYJ2GUWBN4kRFg==
|
|
||||||
dependencies:
|
|
||||||
axios "^0.21.1"
|
|
||||||
crc "^4.1.0"
|
|
||||||
crypto-js "^4.2.0"
|
|
||||||
dayjs "^1.11.5"
|
|
||||||
debug "^4.3.1"
|
|
||||||
form-data "^3.0.0"
|
|
||||||
lodash.get "^4.4.2"
|
|
||||||
p-limit "^3.0.0"
|
|
||||||
protobufjs "7.2.4"
|
|
||||||
uuid "^8.3.2"
|
|
||||||
|
|
||||||
accepts@^1.3.5:
|
|
||||||
version "1.3.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
|
|
||||||
integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
|
|
||||||
dependencies:
|
|
||||||
mime-types "~2.1.34"
|
|
||||||
negotiator "0.6.3"
|
|
||||||
|
|
||||||
anymatch@~3.1.2:
|
|
||||||
version "3.1.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
|
|
||||||
integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
|
|
||||||
dependencies:
|
|
||||||
normalize-path "^3.0.0"
|
|
||||||
picomatch "^2.0.4"
|
|
||||||
|
|
||||||
asynckit@^0.4.0:
|
|
||||||
version "0.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
|
||||||
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
|
|
||||||
|
|
||||||
axios@^0.21.1:
|
|
||||||
version "0.21.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575"
|
|
||||||
integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==
|
|
||||||
dependencies:
|
|
||||||
follow-redirects "^1.14.0"
|
|
||||||
|
|
||||||
balanced-match@^1.0.0:
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
|
||||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
|
||||||
|
|
||||||
binary-extensions@^2.0.0:
|
|
||||||
version "2.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
|
|
||||||
integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
|
|
||||||
|
|
||||||
brace-expansion@^1.1.7:
|
|
||||||
version "1.1.12"
|
|
||||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.12.tgz#ab9b454466e5a8cc3a187beaad580412a9c5b843"
|
|
||||||
integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==
|
|
||||||
dependencies:
|
|
||||||
balanced-match "^1.0.0"
|
|
||||||
concat-map "0.0.1"
|
|
||||||
|
|
||||||
braces@~3.0.2:
|
|
||||||
version "3.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
|
|
||||||
integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
|
|
||||||
dependencies:
|
|
||||||
fill-range "^7.1.1"
|
|
||||||
|
|
||||||
bytes@3.1.2:
|
|
||||||
version "3.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
|
|
||||||
integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
|
|
||||||
|
|
||||||
cache-content-type@^1.0.0:
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/cache-content-type/-/cache-content-type-1.0.1.tgz#035cde2b08ee2129f4a8315ea8f00a00dba1453c"
|
|
||||||
integrity sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==
|
|
||||||
dependencies:
|
|
||||||
mime-types "^2.1.18"
|
|
||||||
ylru "^1.2.0"
|
|
||||||
|
|
||||||
call-bind@^1.0.7:
|
|
||||||
version "1.0.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9"
|
|
||||||
integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==
|
|
||||||
dependencies:
|
|
||||||
es-define-property "^1.0.0"
|
|
||||||
es-errors "^1.3.0"
|
|
||||||
function-bind "^1.1.2"
|
|
||||||
get-intrinsic "^1.2.4"
|
|
||||||
set-function-length "^1.2.1"
|
|
||||||
|
|
||||||
chokidar@^3.5.2:
|
|
||||||
version "3.6.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b"
|
|
||||||
integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==
|
|
||||||
dependencies:
|
|
||||||
anymatch "~3.1.2"
|
|
||||||
braces "~3.0.2"
|
|
||||||
glob-parent "~5.1.2"
|
|
||||||
is-binary-path "~2.1.0"
|
|
||||||
is-glob "~4.0.1"
|
|
||||||
normalize-path "~3.0.0"
|
|
||||||
readdirp "~3.6.0"
|
|
||||||
optionalDependencies:
|
|
||||||
fsevents "~2.3.2"
|
|
||||||
|
|
||||||
co-body@^6.0.0:
|
|
||||||
version "6.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/co-body/-/co-body-6.2.0.tgz#afd776d60e5659f4eee862df83499698eb1aea1b"
|
|
||||||
integrity sha512-Kbpv2Yd1NdL1V/V4cwLVxraHDV6K8ayohr2rmH0J87Er8+zJjcTa6dAn9QMPC9CRgU8+aNajKbSf1TzDB1yKPA==
|
|
||||||
dependencies:
|
|
||||||
"@hapi/bourne" "^3.0.0"
|
|
||||||
inflation "^2.0.0"
|
|
||||||
qs "^6.5.2"
|
|
||||||
raw-body "^2.3.3"
|
|
||||||
type-is "^1.6.16"
|
|
||||||
|
|
||||||
co@^4.6.0:
|
|
||||||
version "4.6.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
|
|
||||||
integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==
|
|
||||||
|
|
||||||
combined-stream@^1.0.8:
|
|
||||||
version "1.0.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
|
||||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
|
||||||
dependencies:
|
|
||||||
delayed-stream "~1.0.0"
|
|
||||||
|
|
||||||
concat-map@0.0.1:
|
|
||||||
version "0.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
|
||||||
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
|
|
||||||
|
|
||||||
content-disposition@~0.5.2:
|
|
||||||
version "0.5.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe"
|
|
||||||
integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==
|
|
||||||
dependencies:
|
|
||||||
safe-buffer "5.2.1"
|
|
||||||
|
|
||||||
content-type@^1.0.4:
|
|
||||||
version "1.0.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
|
|
||||||
integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
|
|
||||||
|
|
||||||
cookies@~0.9.0:
|
|
||||||
version "0.9.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.9.1.tgz#3ffed6f60bb4fb5f146feeedba50acc418af67e3"
|
|
||||||
integrity sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==
|
|
||||||
dependencies:
|
|
||||||
depd "~2.0.0"
|
|
||||||
keygrip "~1.1.0"
|
|
||||||
|
|
||||||
copy-to@^2.0.1:
|
|
||||||
version "2.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/copy-to/-/copy-to-2.0.1.tgz#2680fbb8068a48d08656b6098092bdafc906f4a5"
|
|
||||||
integrity sha512-3DdaFaU/Zf1AnpLiFDeNCD4TOWe3Zl2RZaTzUvWiIk5ERzcCodOE20Vqq4fzCbNoHURFHT4/us/Lfq+S2zyY4w==
|
|
||||||
|
|
||||||
crc@^4.1.0:
|
|
||||||
version "4.3.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/crc/-/crc-4.3.2.tgz#49b7821cbf2cf61dfd079ed93863bbebd5469b9a"
|
|
||||||
integrity sha512-uGDHf4KLLh2zsHa8D8hIQ1H/HtFQhyHrc0uhHBcoKGol/Xnb+MPYfUMw7cvON6ze/GUESTudKayDcJC5HnJv1A==
|
|
||||||
|
|
||||||
crypto-js@^4.2.0:
|
|
||||||
version "4.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631"
|
|
||||||
integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==
|
|
||||||
|
|
||||||
dayjs@^1.11.5:
|
|
||||||
version "1.11.13"
|
|
||||||
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c"
|
|
||||||
integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==
|
|
||||||
|
|
||||||
debug@^4:
|
|
||||||
version "4.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b"
|
|
||||||
integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==
|
|
||||||
dependencies:
|
|
||||||
ms "^2.1.3"
|
|
||||||
|
|
||||||
debug@^4.3.1, debug@^4.3.2:
|
|
||||||
version "4.3.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52"
|
|
||||||
integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==
|
|
||||||
dependencies:
|
|
||||||
ms "^2.1.3"
|
|
||||||
|
|
||||||
deep-equal@~1.0.1:
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
|
|
||||||
integrity sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==
|
|
||||||
|
|
||||||
define-data-property@^1.1.4:
|
|
||||||
version "1.1.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
|
|
||||||
integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
|
|
||||||
dependencies:
|
|
||||||
es-define-property "^1.0.0"
|
|
||||||
es-errors "^1.3.0"
|
|
||||||
gopd "^1.0.1"
|
|
||||||
|
|
||||||
delayed-stream@~1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
|
||||||
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
|
|
||||||
|
|
||||||
delegates@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
|
|
||||||
integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==
|
|
||||||
|
|
||||||
depd@2.0.0, depd@^2.0.0, depd@~2.0.0:
|
|
||||||
version "2.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
|
|
||||||
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
|
|
||||||
|
|
||||||
depd@~1.1.2:
|
|
||||||
version "1.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
|
|
||||||
integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==
|
|
||||||
|
|
||||||
destroy@^1.0.4:
|
|
||||||
version "1.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
|
|
||||||
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
|
|
||||||
|
|
||||||
ee-first@1.1.1:
|
|
||||||
version "1.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
|
|
||||||
integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
|
|
||||||
|
|
||||||
encodeurl@^1.0.2:
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
|
||||||
integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
|
|
||||||
|
|
||||||
es-define-property@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845"
|
|
||||||
integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==
|
|
||||||
dependencies:
|
|
||||||
get-intrinsic "^1.2.4"
|
|
||||||
|
|
||||||
es-errors@^1.3.0:
|
|
||||||
version "1.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
|
|
||||||
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
|
|
||||||
|
|
||||||
escape-html@^1.0.3:
|
|
||||||
version "1.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
|
|
||||||
integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
|
|
||||||
|
|
||||||
fill-range@^7.1.1:
|
|
||||||
version "7.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
|
|
||||||
integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
|
|
||||||
dependencies:
|
|
||||||
to-regex-range "^5.0.1"
|
|
||||||
|
|
||||||
follow-redirects@^1.14.0:
|
|
||||||
version "1.15.9"
|
|
||||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1"
|
|
||||||
integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==
|
|
||||||
|
|
||||||
form-data@^3.0.0:
|
|
||||||
version "3.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.2.tgz#83ad9ced7c03feaad97e293d6f6091011e1659c8"
|
|
||||||
integrity sha512-sJe+TQb2vIaIyO783qN6BlMYWMw3WBOHA1Ay2qxsnjuafEOQFJ2JakedOQirT6D5XPRxDvS7AHYyem9fTpb4LQ==
|
|
||||||
dependencies:
|
|
||||||
asynckit "^0.4.0"
|
|
||||||
combined-stream "^1.0.8"
|
|
||||||
mime-types "^2.1.12"
|
|
||||||
|
|
||||||
fresh@~0.5.2:
|
|
||||||
version "0.5.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
|
|
||||||
integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
|
|
||||||
|
|
||||||
fsevents@~2.3.2:
|
|
||||||
version "2.3.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
|
|
||||||
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
|
|
||||||
|
|
||||||
function-bind@^1.1.2:
|
|
||||||
version "1.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
|
|
||||||
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
|
|
||||||
|
|
||||||
get-intrinsic@^1.1.3, get-intrinsic@^1.2.4:
|
|
||||||
version "1.2.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd"
|
|
||||||
integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==
|
|
||||||
dependencies:
|
|
||||||
es-errors "^1.3.0"
|
|
||||||
function-bind "^1.1.2"
|
|
||||||
has-proto "^1.0.1"
|
|
||||||
has-symbols "^1.0.3"
|
|
||||||
hasown "^2.0.0"
|
|
||||||
|
|
||||||
glob-parent@~5.1.2:
|
|
||||||
version "5.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
|
||||||
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
|
||||||
dependencies:
|
|
||||||
is-glob "^4.0.1"
|
|
||||||
|
|
||||||
gopd@^1.0.1:
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
|
|
||||||
integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==
|
|
||||||
dependencies:
|
|
||||||
get-intrinsic "^1.1.3"
|
|
||||||
|
|
||||||
has-flag@^3.0.0:
|
|
||||||
version "3.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
|
||||||
integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
|
|
||||||
|
|
||||||
has-property-descriptors@^1.0.2:
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854"
|
|
||||||
integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==
|
|
||||||
dependencies:
|
|
||||||
es-define-property "^1.0.0"
|
|
||||||
|
|
||||||
has-proto@^1.0.1:
|
|
||||||
version "1.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd"
|
|
||||||
integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==
|
|
||||||
|
|
||||||
has-symbols@^1.0.3:
|
|
||||||
version "1.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
|
|
||||||
integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
|
|
||||||
|
|
||||||
has-tostringtag@^1.0.0:
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc"
|
|
||||||
integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
|
|
||||||
dependencies:
|
|
||||||
has-symbols "^1.0.3"
|
|
||||||
|
|
||||||
hasown@^2.0.0:
|
|
||||||
version "2.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
|
|
||||||
integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
|
|
||||||
dependencies:
|
|
||||||
function-bind "^1.1.2"
|
|
||||||
|
|
||||||
http-assert@^1.3.0:
|
|
||||||
version "1.5.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.5.0.tgz#c389ccd87ac16ed2dfa6246fd73b926aa00e6b8f"
|
|
||||||
integrity sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==
|
|
||||||
dependencies:
|
|
||||||
deep-equal "~1.0.1"
|
|
||||||
http-errors "~1.8.0"
|
|
||||||
|
|
||||||
http-errors@2.0.0:
|
|
||||||
version "2.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
|
|
||||||
integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==
|
|
||||||
dependencies:
|
|
||||||
depd "2.0.0"
|
|
||||||
inherits "2.0.4"
|
|
||||||
setprototypeof "1.2.0"
|
|
||||||
statuses "2.0.1"
|
|
||||||
toidentifier "1.0.1"
|
|
||||||
|
|
||||||
http-errors@^1.6.3, http-errors@~1.8.0:
|
|
||||||
version "1.8.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c"
|
|
||||||
integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==
|
|
||||||
dependencies:
|
|
||||||
depd "~1.1.2"
|
|
||||||
inherits "2.0.4"
|
|
||||||
setprototypeof "1.2.0"
|
|
||||||
statuses ">= 1.5.0 < 2"
|
|
||||||
toidentifier "1.0.1"
|
|
||||||
|
|
||||||
iconv-lite@0.4.24:
|
|
||||||
version "0.4.24"
|
|
||||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
|
||||||
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
|
||||||
dependencies:
|
|
||||||
safer-buffer ">= 2.1.2 < 3"
|
|
||||||
|
|
||||||
ignore-by-default@^1.0.1:
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09"
|
|
||||||
integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==
|
|
||||||
|
|
||||||
inflation@^2.0.0:
|
|
||||||
version "2.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/inflation/-/inflation-2.1.0.tgz#9214db11a47e6f756d111c4f9df96971c60f886c"
|
|
||||||
integrity sha512-t54PPJHG1Pp7VQvxyVCJ9mBbjG3Hqryges9bXoOO6GExCPa+//i/d5GSuFtpx3ALLd7lgIAur6zrIlBQyJuMlQ==
|
|
||||||
|
|
||||||
inherits@2.0.4:
|
|
||||||
version "2.0.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
|
||||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
|
||||||
|
|
||||||
is-binary-path@~2.1.0:
|
|
||||||
version "2.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
|
|
||||||
integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
|
|
||||||
dependencies:
|
|
||||||
binary-extensions "^2.0.0"
|
|
||||||
|
|
||||||
is-extglob@^2.1.1:
|
|
||||||
version "2.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
|
||||||
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
|
|
||||||
|
|
||||||
is-generator-function@^1.0.7:
|
|
||||||
version "1.0.10"
|
|
||||||
resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72"
|
|
||||||
integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==
|
|
||||||
dependencies:
|
|
||||||
has-tostringtag "^1.0.0"
|
|
||||||
|
|
||||||
is-glob@^4.0.1, is-glob@~4.0.1:
|
|
||||||
version "4.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
|
||||||
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
|
||||||
dependencies:
|
|
||||||
is-extglob "^2.1.1"
|
|
||||||
|
|
||||||
is-number@^7.0.0:
|
|
||||||
version "7.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
|
|
||||||
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
|
|
||||||
|
|
||||||
keygrip@~1.1.0:
|
|
||||||
version "1.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226"
|
|
||||||
integrity sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==
|
|
||||||
dependencies:
|
|
||||||
tsscmp "1.0.6"
|
|
||||||
|
|
||||||
koa-bodyparser@^4.4.1:
|
|
||||||
version "4.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/koa-bodyparser/-/koa-bodyparser-4.4.1.tgz#a908d848e142cc57d9eece478e932bf00dce3029"
|
|
||||||
integrity sha512-kBH3IYPMb+iAXnrxIhXnW+gXV8OTzCu8VPDqvcDHW9SQrbkHmqPQtiZwrltNmSq6/lpipHnT7k7PsjlVD7kK0w==
|
|
||||||
dependencies:
|
|
||||||
co-body "^6.0.0"
|
|
||||||
copy-to "^2.0.1"
|
|
||||||
type-is "^1.6.18"
|
|
||||||
|
|
||||||
koa-compose@^4.1.0:
|
|
||||||
version "4.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877"
|
|
||||||
integrity sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==
|
|
||||||
|
|
||||||
koa-convert@^2.0.0:
|
|
||||||
version "2.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/koa-convert/-/koa-convert-2.0.0.tgz#86a0c44d81d40551bae22fee6709904573eea4f5"
|
|
||||||
integrity sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==
|
|
||||||
dependencies:
|
|
||||||
co "^4.6.0"
|
|
||||||
koa-compose "^4.1.0"
|
|
||||||
|
|
||||||
koa2-cors@^2.0.6:
|
|
||||||
version "2.0.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/koa2-cors/-/koa2-cors-2.0.6.tgz#9ad23df3a0b9bb84530b46f5944f3fb576086554"
|
|
||||||
integrity sha512-JRCcSM4lamM+8kvKGDKlesYk2ASrmSTczDtGUnIadqMgnHU4Ct5Gw7Bxt3w3m6d6dy3WN0PU4oMP43HbddDEWg==
|
|
||||||
|
|
||||||
koa@^2.15.3:
|
|
||||||
version "2.15.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/koa/-/koa-2.15.3.tgz#062809266ee75ce0c75f6510a005b0e38f8c519a"
|
|
||||||
integrity sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==
|
|
||||||
dependencies:
|
|
||||||
accepts "^1.3.5"
|
|
||||||
cache-content-type "^1.0.0"
|
|
||||||
content-disposition "~0.5.2"
|
|
||||||
content-type "^1.0.4"
|
|
||||||
cookies "~0.9.0"
|
|
||||||
debug "^4.3.2"
|
|
||||||
delegates "^1.0.0"
|
|
||||||
depd "^2.0.0"
|
|
||||||
destroy "^1.0.4"
|
|
||||||
encodeurl "^1.0.2"
|
|
||||||
escape-html "^1.0.3"
|
|
||||||
fresh "~0.5.2"
|
|
||||||
http-assert "^1.3.0"
|
|
||||||
http-errors "^1.6.3"
|
|
||||||
is-generator-function "^1.0.7"
|
|
||||||
koa-compose "^4.1.0"
|
|
||||||
koa-convert "^2.0.0"
|
|
||||||
on-finished "^2.3.0"
|
|
||||||
only "~0.0.2"
|
|
||||||
parseurl "^1.3.2"
|
|
||||||
statuses "^1.5.0"
|
|
||||||
type-is "^1.6.16"
|
|
||||||
vary "^1.1.2"
|
|
||||||
|
|
||||||
lodash.get@^4.4.2:
|
|
||||||
version "4.4.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
|
|
||||||
integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==
|
|
||||||
|
|
||||||
lodash@^4.17.21:
|
|
||||||
version "4.17.21"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
|
||||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
|
||||||
|
|
||||||
long@^5.0.0:
|
|
||||||
version "5.2.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1"
|
|
||||||
integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==
|
|
||||||
|
|
||||||
media-typer@0.3.0:
|
|
||||||
version "0.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
|
||||||
integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
|
|
||||||
|
|
||||||
mime-db@1.52.0:
|
|
||||||
version "1.52.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
|
|
||||||
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
|
|
||||||
|
|
||||||
mime-types@^2.1.12, mime-types@^2.1.18, mime-types@~2.1.24, mime-types@~2.1.34:
|
|
||||||
version "2.1.35"
|
|
||||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
|
|
||||||
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
|
|
||||||
dependencies:
|
|
||||||
mime-db "1.52.0"
|
|
||||||
|
|
||||||
minimatch@^3.1.2:
|
|
||||||
version "3.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
|
||||||
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
|
|
||||||
dependencies:
|
|
||||||
brace-expansion "^1.1.7"
|
|
||||||
|
|
||||||
ms@^2.1.3:
|
|
||||||
version "2.1.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
|
||||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
|
||||||
|
|
||||||
negotiator@0.6.3:
|
|
||||||
version "0.6.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
|
|
||||||
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
|
|
||||||
|
|
||||||
node-fetch@^2.3.2:
|
|
||||||
version "2.7.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
|
|
||||||
integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
|
|
||||||
dependencies:
|
|
||||||
whatwg-url "^5.0.0"
|
|
||||||
|
|
||||||
nodemon@^3.1.10:
|
|
||||||
version "3.1.10"
|
|
||||||
resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-3.1.10.tgz#5015c5eb4fffcb24d98cf9454df14f4fecec9bc1"
|
|
||||||
integrity sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==
|
|
||||||
dependencies:
|
|
||||||
chokidar "^3.5.2"
|
|
||||||
debug "^4"
|
|
||||||
ignore-by-default "^1.0.1"
|
|
||||||
minimatch "^3.1.2"
|
|
||||||
pstree.remy "^1.1.8"
|
|
||||||
semver "^7.5.3"
|
|
||||||
simple-update-notifier "^2.0.0"
|
|
||||||
supports-color "^5.5.0"
|
|
||||||
touch "^3.1.0"
|
|
||||||
undefsafe "^2.0.5"
|
|
||||||
|
|
||||||
normalize-path@^3.0.0, normalize-path@~3.0.0:
|
|
||||||
version "3.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
|
||||||
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
|
||||||
|
|
||||||
object-inspect@^1.13.1:
|
|
||||||
version "1.13.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff"
|
|
||||||
integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==
|
|
||||||
|
|
||||||
on-finished@^2.3.0:
|
|
||||||
version "2.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
|
|
||||||
integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
|
|
||||||
dependencies:
|
|
||||||
ee-first "1.1.1"
|
|
||||||
|
|
||||||
only@~0.0.2:
|
|
||||||
version "0.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4"
|
|
||||||
integrity sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==
|
|
||||||
|
|
||||||
p-limit@^3.0.0:
|
|
||||||
version "3.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
|
|
||||||
integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
|
|
||||||
dependencies:
|
|
||||||
yocto-queue "^0.1.0"
|
|
||||||
|
|
||||||
parseurl@^1.3.2:
|
|
||||||
version "1.3.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
|
|
||||||
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
|
|
||||||
|
|
||||||
picomatch@^2.0.4, picomatch@^2.2.1:
|
|
||||||
version "2.3.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
|
|
||||||
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
|
|
||||||
|
|
||||||
protobufjs@7.2.4:
|
|
||||||
version "7.2.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.4.tgz#3fc1ec0cdc89dd91aef9ba6037ba07408485c3ae"
|
|
||||||
integrity sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ==
|
|
||||||
dependencies:
|
|
||||||
"@protobufjs/aspromise" "^1.1.2"
|
|
||||||
"@protobufjs/base64" "^1.1.2"
|
|
||||||
"@protobufjs/codegen" "^2.0.4"
|
|
||||||
"@protobufjs/eventemitter" "^1.1.0"
|
|
||||||
"@protobufjs/fetch" "^1.1.0"
|
|
||||||
"@protobufjs/float" "^1.0.2"
|
|
||||||
"@protobufjs/inquire" "^1.1.0"
|
|
||||||
"@protobufjs/path" "^1.1.2"
|
|
||||||
"@protobufjs/pool" "^1.1.0"
|
|
||||||
"@protobufjs/utf8" "^1.1.0"
|
|
||||||
"@types/node" ">=13.7.0"
|
|
||||||
long "^5.0.0"
|
|
||||||
|
|
||||||
pstree.remy@^1.1.8:
|
|
||||||
version "1.1.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a"
|
|
||||||
integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==
|
|
||||||
|
|
||||||
qs@^6.5.2:
|
|
||||||
version "6.13.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906"
|
|
||||||
integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==
|
|
||||||
dependencies:
|
|
||||||
side-channel "^1.0.6"
|
|
||||||
|
|
||||||
raw-body@^2.3.3:
|
|
||||||
version "2.5.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a"
|
|
||||||
integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==
|
|
||||||
dependencies:
|
|
||||||
bytes "3.1.2"
|
|
||||||
http-errors "2.0.0"
|
|
||||||
iconv-lite "0.4.24"
|
|
||||||
unpipe "1.0.0"
|
|
||||||
|
|
||||||
readdirp@~3.6.0:
|
|
||||||
version "3.6.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
|
|
||||||
integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
|
|
||||||
dependencies:
|
|
||||||
picomatch "^2.2.1"
|
|
||||||
|
|
||||||
safe-buffer@5.2.1:
|
|
||||||
version "5.2.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
|
||||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
|
||||||
|
|
||||||
"safer-buffer@>= 2.1.2 < 3":
|
|
||||||
version "2.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
|
||||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
|
||||||
|
|
||||||
semver@^7.5.3:
|
|
||||||
version "7.7.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58"
|
|
||||||
integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==
|
|
||||||
|
|
||||||
set-function-length@^1.2.1:
|
|
||||||
version "1.2.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449"
|
|
||||||
integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==
|
|
||||||
dependencies:
|
|
||||||
define-data-property "^1.1.4"
|
|
||||||
es-errors "^1.3.0"
|
|
||||||
function-bind "^1.1.2"
|
|
||||||
get-intrinsic "^1.2.4"
|
|
||||||
gopd "^1.0.1"
|
|
||||||
has-property-descriptors "^1.0.2"
|
|
||||||
|
|
||||||
setprototypeof@1.2.0:
|
|
||||||
version "1.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
|
|
||||||
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
|
|
||||||
|
|
||||||
side-channel@^1.0.6:
|
|
||||||
version "1.0.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2"
|
|
||||||
integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==
|
|
||||||
dependencies:
|
|
||||||
call-bind "^1.0.7"
|
|
||||||
es-errors "^1.3.0"
|
|
||||||
get-intrinsic "^1.2.4"
|
|
||||||
object-inspect "^1.13.1"
|
|
||||||
|
|
||||||
simple-update-notifier@^2.0.0:
|
|
||||||
version "2.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz#d70b92bdab7d6d90dfd73931195a30b6e3d7cebb"
|
|
||||||
integrity sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==
|
|
||||||
dependencies:
|
|
||||||
semver "^7.5.3"
|
|
||||||
|
|
||||||
statuses@2.0.1:
|
|
||||||
version "2.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
|
|
||||||
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
|
|
||||||
|
|
||||||
"statuses@>= 1.5.0 < 2", statuses@^1.5.0:
|
|
||||||
version "1.5.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
|
|
||||||
integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==
|
|
||||||
|
|
||||||
supports-color@^5.5.0:
|
|
||||||
version "5.5.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
|
||||||
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
|
|
||||||
dependencies:
|
|
||||||
has-flag "^3.0.0"
|
|
||||||
|
|
||||||
to-regex-range@^5.0.1:
|
|
||||||
version "5.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
|
|
||||||
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
|
|
||||||
dependencies:
|
|
||||||
is-number "^7.0.0"
|
|
||||||
|
|
||||||
toidentifier@1.0.1:
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
|
|
||||||
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
|
|
||||||
|
|
||||||
touch@^3.1.0:
|
|
||||||
version "3.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.1.tgz#097a23d7b161476435e5c1344a95c0f75b4a5694"
|
|
||||||
integrity sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==
|
|
||||||
|
|
||||||
tr46@~0.0.3:
|
|
||||||
version "0.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
|
||||||
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
|
|
||||||
|
|
||||||
tsscmp@1.0.6:
|
|
||||||
version "1.0.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb"
|
|
||||||
integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==
|
|
||||||
|
|
||||||
type-is@^1.6.16, type-is@^1.6.18:
|
|
||||||
version "1.6.18"
|
|
||||||
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
|
|
||||||
integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
|
|
||||||
dependencies:
|
|
||||||
media-typer "0.3.0"
|
|
||||||
mime-types "~2.1.24"
|
|
||||||
|
|
||||||
undefsafe@^2.0.5:
|
|
||||||
version "2.0.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c"
|
|
||||||
integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==
|
|
||||||
|
|
||||||
undici-types@~6.19.2:
|
|
||||||
version "6.19.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02"
|
|
||||||
integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==
|
|
||||||
|
|
||||||
unpipe@1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
|
||||||
integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
|
|
||||||
|
|
||||||
uuid@^11.1.0:
|
|
||||||
version "11.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-11.1.0.tgz#9549028be1753bb934fc96e2bca09bb4105ae912"
|
|
||||||
integrity sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==
|
|
||||||
|
|
||||||
uuid@^8.3.2:
|
|
||||||
version "8.3.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
|
|
||||||
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
|
|
||||||
|
|
||||||
vary@^1.1.2:
|
|
||||||
version "1.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
|
||||||
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
|
|
||||||
|
|
||||||
webidl-conversions@^3.0.0:
|
|
||||||
version "3.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
|
|
||||||
integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
|
|
||||||
|
|
||||||
whatwg-url@^5.0.0:
|
|
||||||
version "5.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
|
|
||||||
integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
|
|
||||||
dependencies:
|
|
||||||
tr46 "~0.0.3"
|
|
||||||
webidl-conversions "^3.0.0"
|
|
||||||
|
|
||||||
ylru@^1.2.0:
|
|
||||||
version "1.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.4.0.tgz#0cf0aa57e9c24f8a2cbde0cc1ca2c9592ac4e0f6"
|
|
||||||
integrity sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA==
|
|
||||||
|
|
||||||
yocto-queue@^0.1.0:
|
|
||||||
version "0.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
|
|
||||||
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
|
|
||||||
84
backend/.env.example
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
# RTC OpenAPI 版本
|
||||||
|
RTC_OPENAPI_VERSION=2025-06-01
|
||||||
|
|
||||||
|
# Custom 场景基础配置
|
||||||
|
CUSTOM_ACCESS_KEY_ID=your-access-key-id
|
||||||
|
CUSTOM_SECRET_KEY=your-secret-key
|
||||||
|
CUSTOM_RTC_APP_ID=your-rtc-app-id
|
||||||
|
CUSTOM_RTC_APP_KEY=
|
||||||
|
|
||||||
|
# 留空时由服务端自动生成 RoomId / UserId / Token
|
||||||
|
CUSTOM_RTC_ROOM_ID=
|
||||||
|
CUSTOM_RTC_USER_ID=
|
||||||
|
CUSTOM_RTC_TOKEN=
|
||||||
|
|
||||||
|
# Custom 场景业务配置
|
||||||
|
CUSTOM_TASK_ID=your-task-id
|
||||||
|
CUSTOM_AGENT_USER_ID=your-agent-user-id
|
||||||
|
CUSTOM_AGENT_TARGET_USER_ID=
|
||||||
|
CUSTOM_AGENT_WELCOME_MESSAGE=你好,我是小乖,有什么需要帮忙的吗?
|
||||||
|
CUSTOM_SCENE_NAME=自定义助手
|
||||||
|
CUSTOM_SCENE_ICON=https://lf3-rtc-demo.volccdn.com/obj/rtc-aigc-assets/DoubaoAvatar.png
|
||||||
|
CUSTOM_INTERRUPT_MODE=0
|
||||||
|
|
||||||
|
# LLM 公共配置
|
||||||
|
CUSTOM_LLM_MODE=ArkV3
|
||||||
|
CUSTOM_LLM_SYSTEM_MESSAGE=你是小乖,性格幽默又善解人意。你在表达时需简明扼要,有自己的观点。
|
||||||
|
CUSTOM_LLM_VISION_ENABLE=false
|
||||||
|
CUSTOM_LLM_THINKING_TYPE=disabled
|
||||||
|
|
||||||
|
# ArkV3 模式
|
||||||
|
CUSTOM_LLM_ENDPOINT_ID=your-ark-endpoint-id
|
||||||
|
|
||||||
|
# CustomLLM 模式
|
||||||
|
# 本地调试时,可先保持默认本地回调地址。
|
||||||
|
# 等 ngrok 跑起来后,再把 CUSTOM_LLM_URL 改成公网 https 地址,例如:
|
||||||
|
# https://your-ngrok-domain.ngrok-free.app/api/chat_callback
|
||||||
|
CUSTOM_LLM_URL=http://127.0.0.1:3001/api/chat_callback
|
||||||
|
# 火山调用当前 backend 的 /api/chat_callback 时使用的 Bearer Token,可留空
|
||||||
|
CUSTOM_LLM_API_KEY=
|
||||||
|
CUSTOM_LLM_MODEL_NAME=
|
||||||
|
CUSTOM_LLM_HISTORY_LENGTH=
|
||||||
|
CUSTOM_LLM_PREFILL=
|
||||||
|
CUSTOM_LLM_CUSTOM=
|
||||||
|
CUSTOM_LLM_EXTRA_HEADER_JSON=
|
||||||
|
CUSTOM_LLM_ENABLE_PARALLEL_TOOL_CALLS=
|
||||||
|
CUSTOM_LLM_TEMPERATURE=
|
||||||
|
CUSTOM_LLM_TOP_P=
|
||||||
|
CUSTOM_LLM_MAX_TOKENS=
|
||||||
|
|
||||||
|
# 当前 backend 内置的本地 Ark 回调配置
|
||||||
|
# /api/chat_callback 会直接使用这组配置调用方舟
|
||||||
|
ARK_API_KEY=
|
||||||
|
ARK_ENDPOINT_ID=
|
||||||
|
ARK_BASE_URL=https://ark.cn-beijing.volces.com/api/v3
|
||||||
|
ARK_TIMEOUT_SECONDS=1800
|
||||||
|
LOCAL_LLM_SYSTEM_PROMPT= "你是一个测试助手。如果别人问你是谁,你就说你是哈哈哈。"
|
||||||
|
LOCAL_LLM_TEMPERATURE=0.3
|
||||||
|
|
||||||
|
# 可选 RAG 占位配置
|
||||||
|
# 当前首版默认未启用主链路 RAG,如需后续接入,可再填写这两个配置
|
||||||
|
RAG_STATIC_CONTEXT=
|
||||||
|
RAG_CONTEXT_FILE=
|
||||||
|
|
||||||
|
# ASR / TTS
|
||||||
|
CUSTOM_ASR_APP_ID=your-asr-app-id
|
||||||
|
CUSTOM_TTS_APP_ID=your-tts-app-id
|
||||||
|
CUSTOM_ASR_PROVIDER=volcano
|
||||||
|
CUSTOM_ASR_MODE=smallmodel
|
||||||
|
CUSTOM_ASR_CLUSTER=volcengine_streaming_common
|
||||||
|
CUSTOM_TTS_PROVIDER=volcano
|
||||||
|
CUSTOM_TTS_CLUSTER=volcano_tts
|
||||||
|
CUSTOM_TTS_VOICE_TYPE=BV001_streaming
|
||||||
|
CUSTOM_TTS_SPEED_RATIO=1
|
||||||
|
CUSTOM_TTS_PITCH_RATIO=1
|
||||||
|
CUSTOM_TTS_VOLUME_RATIO=1
|
||||||
|
|
||||||
|
# 数字人配置
|
||||||
|
CUSTOM_AVATAR_ENABLED=false
|
||||||
|
CUSTOM_AVATAR_TYPE=3min
|
||||||
|
CUSTOM_AVATAR_ROLE=250623-zhibo-linyunzhi
|
||||||
|
CUSTOM_AVATAR_BACKGROUND_URL=
|
||||||
|
CUSTOM_AVATAR_VIDEO_BITRATE=2000
|
||||||
|
CUSTOM_AVATAR_APP_ID=
|
||||||
|
CUSTOM_AVATAR_TOKEN=
|
||||||
190
backend/README.md
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
# AIGC Backend(Python FastAPI)
|
||||||
|
|
||||||
|
这是当前 Demo 的后端服务,负责三件事:
|
||||||
|
|
||||||
|
- 根据 `backend/.env` 与 `backend/config/custom_scene.py` 构建 `Custom` 场景配置
|
||||||
|
- 代理调用火山 RTC OpenAPI
|
||||||
|
- 在同一个 FastAPI 进程里提供本地 `CustomLLM` 回调接口 `/api/chat_callback`
|
||||||
|
|
||||||
|
## 环境要求
|
||||||
|
|
||||||
|
- Python 3.13+
|
||||||
|
|
||||||
|
## 安装依赖
|
||||||
|
|
||||||
|
```shell
|
||||||
|
uv sync
|
||||||
|
```
|
||||||
|
|
||||||
|
## 启动方式
|
||||||
|
|
||||||
|
```shell
|
||||||
|
uv run uvicorn server:app --host 0.0.0.0 --port 3001 --reload
|
||||||
|
```
|
||||||
|
|
||||||
|
服务默认监听 `http://localhost:3001`。
|
||||||
|
|
||||||
|
## 配置方式
|
||||||
|
|
||||||
|
`Custom` 场景固定使用:
|
||||||
|
|
||||||
|
- `backend/.env`
|
||||||
|
- `backend/config/custom_scene.py`
|
||||||
|
|
||||||
|
不再依赖 `backend/scenes/Custom.json`。
|
||||||
|
|
||||||
|
先复制示例配置:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
### 必填基础配置
|
||||||
|
|
||||||
|
| 变量名 | 说明 |
|
||||||
|
| --- | --- |
|
||||||
|
| `CUSTOM_ACCESS_KEY_ID` | 火山引擎 AK |
|
||||||
|
| `CUSTOM_SECRET_KEY` | 火山引擎 SK |
|
||||||
|
| `CUSTOM_RTC_APP_ID` | RTC 应用 ID,同时作为 `RTCConfig.AppId` 和 `VoiceChat.AppId` |
|
||||||
|
| `CUSTOM_TASK_ID` | AIGC 任务 ID |
|
||||||
|
| `CUSTOM_AGENT_USER_ID` | 智能体用户 ID |
|
||||||
|
| `CUSTOM_AGENT_WELCOME_MESSAGE` | 智能体欢迎语 |
|
||||||
|
| `CUSTOM_LLM_SYSTEM_MESSAGE` | System Message |
|
||||||
|
| `CUSTOM_ASR_APP_ID` | ASR 应用 ID |
|
||||||
|
| `CUSTOM_TTS_APP_ID` | TTS 应用 ID |
|
||||||
|
|
||||||
|
### RTC 相关配置
|
||||||
|
|
||||||
|
| 变量名 | 说明 |
|
||||||
|
| --- | --- |
|
||||||
|
| `CUSTOM_RTC_APP_KEY` | 未提供 `CUSTOM_RTC_TOKEN` 时,用于自动生成 Token |
|
||||||
|
| `CUSTOM_RTC_ROOM_ID` | 房间 ID,留空时服务端自动生成 |
|
||||||
|
| `CUSTOM_RTC_USER_ID` | 用户 ID,留空时服务端自动生成 |
|
||||||
|
| `CUSTOM_RTC_TOKEN` | RTC Token;留空时服务端会自动生成 |
|
||||||
|
| `RTC_OPENAPI_VERSION` | `StartVoiceChat/StopVoiceChat` 使用的 OpenAPI 版本,默认 `2025-06-01` |
|
||||||
|
|
||||||
|
### LLM 模式一:ArkV3
|
||||||
|
|
||||||
|
```dotenv
|
||||||
|
CUSTOM_LLM_MODE=ArkV3
|
||||||
|
CUSTOM_LLM_ENDPOINT_ID=your-ark-endpoint-id
|
||||||
|
```
|
||||||
|
|
||||||
|
### LLM 模式二:CustomLLM 本地回调
|
||||||
|
|
||||||
|
这个模式不是再起一个额外代理服务,而是直接由当前 `backend` 自己对外提供回调接口:
|
||||||
|
|
||||||
|
```dotenv
|
||||||
|
CUSTOM_LLM_MODE=CustomLLM
|
||||||
|
CUSTOM_LLM_URL=http://127.0.0.1:3001/api/chat_callback
|
||||||
|
CUSTOM_LLM_API_KEY=your-callback-token
|
||||||
|
CUSTOM_LLM_MODEL_NAME=my-model
|
||||||
|
```
|
||||||
|
|
||||||
|
推荐调试流程:
|
||||||
|
|
||||||
|
1. 先启动当前 `backend`
|
||||||
|
2. 用 `ngrok` 暴露 `3001` 端口
|
||||||
|
3. 把 `CUSTOM_LLM_URL` 改成公网地址,例如:
|
||||||
|
|
||||||
|
```dotenv
|
||||||
|
CUSTOM_LLM_URL=https://your-ngrok-domain.ngrok-free.app/api/chat_callback
|
||||||
|
```
|
||||||
|
|
||||||
|
`CUSTOM_LLM_API_KEY` 是火山调用你这个本地回调接口时带上的 Bearer Token;如果你不需要这层鉴权,可以留空。
|
||||||
|
|
||||||
|
### 当前 backend 内置的 Ark 配置
|
||||||
|
|
||||||
|
`/api/chat_callback` 内部会直接调用方舟 SDK,因此还需要:
|
||||||
|
|
||||||
|
```dotenv
|
||||||
|
ARK_API_KEY=your-ark-api-key
|
||||||
|
ARK_ENDPOINT_ID=your-ark-endpoint-id
|
||||||
|
ARK_BASE_URL=https://ark.cn-beijing.volces.com/api/v3
|
||||||
|
ARK_TIMEOUT_SECONDS=1800
|
||||||
|
LOCAL_LLM_SYSTEM_PROMPT=
|
||||||
|
LOCAL_LLM_TEMPERATURE=0.3
|
||||||
|
```
|
||||||
|
|
||||||
|
如果 `LOCAL_LLM_SYSTEM_PROMPT` 留空,会回退使用 `CUSTOM_LLM_SYSTEM_MESSAGE`。
|
||||||
|
|
||||||
|
### 可选 RAG 占位配置
|
||||||
|
|
||||||
|
当前仓库内置了一个最小 RAG 占位实现,但首版默认不接入主链路,支持两种输入来源:
|
||||||
|
|
||||||
|
```dotenv
|
||||||
|
RAG_STATIC_CONTEXT=
|
||||||
|
RAG_CONTEXT_FILE=
|
||||||
|
```
|
||||||
|
|
||||||
|
- `RAG_STATIC_CONTEXT`:直接写死一段知识文本
|
||||||
|
- `RAG_CONTEXT_FILE`:从本地文件读取全文作为知识上下文
|
||||||
|
|
||||||
|
后续如果你要接真实向量检索,直接替换 `services/rag_service.py` 里的 `retrieve`,再把 `server.py` 主链路接回去即可。
|
||||||
|
|
||||||
|
### CustomLLM 可选参数
|
||||||
|
|
||||||
|
| 变量名 | 说明 |
|
||||||
|
| --- | --- |
|
||||||
|
| `CUSTOM_LLM_HISTORY_LENGTH` | 历史轮数 |
|
||||||
|
| `CUSTOM_LLM_PREFILL` | 是否开启 Prefill |
|
||||||
|
| `CUSTOM_LLM_CUSTOM` | 透传到请求体的 `custom` 字段 |
|
||||||
|
| `CUSTOM_LLM_EXTRA_HEADER_JSON` | 额外请求头,JSON 对象字符串 |
|
||||||
|
| `CUSTOM_LLM_ENABLE_PARALLEL_TOOL_CALLS` | 是否开启并行工具调用 |
|
||||||
|
| `CUSTOM_LLM_TEMPERATURE` | 透传温度参数 |
|
||||||
|
| `CUSTOM_LLM_TOP_P` | 透传 `top_p` |
|
||||||
|
| `CUSTOM_LLM_MAX_TOKENS` | 透传 `max_tokens` |
|
||||||
|
|
||||||
|
其余 ASR、TTS、数字人相关可选字段,请直接参考 `backend/.env.example`。
|
||||||
|
|
||||||
|
## 接口说明
|
||||||
|
|
||||||
|
### `POST /getScenes`
|
||||||
|
|
||||||
|
返回场景列表,并自动补齐:
|
||||||
|
|
||||||
|
- `RoomId`
|
||||||
|
- `UserId`
|
||||||
|
- `Token`
|
||||||
|
|
||||||
|
### `POST /proxy?Action={Action}&Version={Version}`
|
||||||
|
|
||||||
|
代理转发到火山 RTC OpenAPI。
|
||||||
|
|
||||||
|
支持:
|
||||||
|
|
||||||
|
- `StartVoiceChat`
|
||||||
|
- `StopVoiceChat`
|
||||||
|
|
||||||
|
请求体必须包含 `SceneID`。
|
||||||
|
|
||||||
|
版本优先级如下:
|
||||||
|
|
||||||
|
1. 查询参数里的 `Version`
|
||||||
|
2. 环境变量 `RTC_OPENAPI_VERSION`
|
||||||
|
3. 默认值 `2025-06-01`
|
||||||
|
|
||||||
|
### `POST /api/chat_callback`
|
||||||
|
|
||||||
|
这是当前 backend 内置的 `CustomLLM` 回调接口,也是你配置给火山 `LLMConfig.Url` 的目标地址。
|
||||||
|
|
||||||
|
行为说明:
|
||||||
|
|
||||||
|
- 接收火山传入的 `messages`
|
||||||
|
- 可选校验 `Authorization: Bearer <CUSTOM_LLM_API_KEY>`
|
||||||
|
- 内部调用 `services/local_llm_service.py` 里的 Ark SDK
|
||||||
|
- 按火山要求返回 `text/event-stream`
|
||||||
|
- 结束时一定补 `data: [DONE]`
|
||||||
|
|
||||||
|
### `POST /debug/chat`
|
||||||
|
|
||||||
|
本地调试 LLM 文本流,不经过 RTC。
|
||||||
|
|
||||||
|
### `GET /debug/rag?query=...`
|
||||||
|
|
||||||
|
本地调试 RAG 返回结果。
|
||||||
|
|
||||||
|
## 说明
|
||||||
|
|
||||||
|
- 当前前端不会直接决定模型供应商,模型切换统一由后端环境变量控制。
|
||||||
|
- 如果缺少关键 `CUSTOM_*` 或 `ARK_*` 配置,服务会在启动阶段直接报错,而不是进入半可用状态。
|
||||||
1
backend/config/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
"""Backend config package."""
|
||||||
225
backend/config/custom_scene.py
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
"""
|
||||||
|
Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved.
|
||||||
|
SPDX-license-identifier: BSD-3-Clause
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from utils.env import (
|
||||||
|
env_bool,
|
||||||
|
env_int,
|
||||||
|
env_json_object,
|
||||||
|
env_list,
|
||||||
|
env_number,
|
||||||
|
env_optional_bool,
|
||||||
|
env_optional_int,
|
||||||
|
env_optional_number,
|
||||||
|
env_str,
|
||||||
|
require_env,
|
||||||
|
set_if_present,
|
||||||
|
)
|
||||||
|
|
||||||
|
CUSTOM_SCENE_ID = "Custom"
|
||||||
|
|
||||||
|
DEFAULT_SCENE_NAME = "自定义助手"
|
||||||
|
DEFAULT_SCENE_ICON = (
|
||||||
|
"https://lf3-rtc-demo.volccdn.com/obj/rtc-aigc-assets/DoubaoAvatar.png"
|
||||||
|
)
|
||||||
|
DEFAULT_LLM_MODE = "ArkV3"
|
||||||
|
DEFAULT_LLM_THINKING_TYPE = "disabled"
|
||||||
|
DEFAULT_RTC_OPENAPI_VERSION = "2025-06-01"
|
||||||
|
DEFAULT_CUSTOM_LLM_CALLBACK_URL = "http://127.0.0.1:3001/api/chat_callback"
|
||||||
|
SUPPORTED_LLM_MODES = {"ArkV3", "CustomLLM"}
|
||||||
|
DEFAULT_ASR_PROVIDER = "volcano"
|
||||||
|
DEFAULT_ASR_MODE = "smallmodel"
|
||||||
|
DEFAULT_ASR_CLUSTER = "volcengine_streaming_common"
|
||||||
|
DEFAULT_TTS_PROVIDER = "volcano"
|
||||||
|
DEFAULT_TTS_CLUSTER = "volcano_tts"
|
||||||
|
DEFAULT_TTS_VOICE_TYPE = "BV001_streaming"
|
||||||
|
DEFAULT_AVATAR_TYPE = "3min"
|
||||||
|
DEFAULT_AVATAR_ROLE = "250623-zhibo-linyunzhi"
|
||||||
|
DEFAULT_AVATAR_VIDEO_BITRATE = 2000
|
||||||
|
|
||||||
|
|
||||||
|
def get_rtc_openapi_version() -> str:
|
||||||
|
return env_str("RTC_OPENAPI_VERSION", DEFAULT_RTC_OPENAPI_VERSION)
|
||||||
|
|
||||||
|
|
||||||
|
def build_llm_settings_from_env(missing: list[str]) -> dict[str, Any]:
|
||||||
|
llm_mode = env_str("CUSTOM_LLM_MODE", DEFAULT_LLM_MODE)
|
||||||
|
if llm_mode not in SUPPORTED_LLM_MODES:
|
||||||
|
modes = ", ".join(sorted(SUPPORTED_LLM_MODES))
|
||||||
|
raise ValueError(f"CUSTOM_LLM_MODE 仅支持以下取值: {modes}")
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
"mode": llm_mode,
|
||||||
|
"system_message": require_env("CUSTOM_LLM_SYSTEM_MESSAGE", missing),
|
||||||
|
"vision_enable": env_bool("CUSTOM_LLM_VISION_ENABLE", False),
|
||||||
|
"thinking_type": env_str(
|
||||||
|
"CUSTOM_LLM_THINKING_TYPE", DEFAULT_LLM_THINKING_TYPE
|
||||||
|
),
|
||||||
|
"api_key": env_str("CUSTOM_LLM_API_KEY"),
|
||||||
|
"model_name": env_str("CUSTOM_LLM_MODEL_NAME"),
|
||||||
|
"history_length": env_optional_int("CUSTOM_LLM_HISTORY_LENGTH"),
|
||||||
|
"prefill": env_optional_bool("CUSTOM_LLM_PREFILL"),
|
||||||
|
"custom": env_str("CUSTOM_LLM_CUSTOM"),
|
||||||
|
"extra_header": env_json_object("CUSTOM_LLM_EXTRA_HEADER_JSON"),
|
||||||
|
"enable_parallel_tool_calls": env_optional_bool(
|
||||||
|
"CUSTOM_LLM_ENABLE_PARALLEL_TOOL_CALLS"
|
||||||
|
),
|
||||||
|
"temperature": env_optional_number("CUSTOM_LLM_TEMPERATURE"),
|
||||||
|
"top_p": env_optional_number("CUSTOM_LLM_TOP_P"),
|
||||||
|
"max_tokens": env_optional_int("CUSTOM_LLM_MAX_TOKENS"),
|
||||||
|
}
|
||||||
|
|
||||||
|
if llm_mode == "ArkV3":
|
||||||
|
settings["endpoint_id"] = require_env("CUSTOM_LLM_ENDPOINT_ID", missing)
|
||||||
|
return settings
|
||||||
|
|
||||||
|
settings["url"] = env_str("CUSTOM_LLM_URL", DEFAULT_CUSTOM_LLM_CALLBACK_URL)
|
||||||
|
settings["endpoint_id"] = env_str("CUSTOM_LLM_ENDPOINT_ID")
|
||||||
|
require_env("ARK_API_KEY", missing)
|
||||||
|
require_env("ARK_ENDPOINT_ID", missing)
|
||||||
|
|
||||||
|
return settings
|
||||||
|
|
||||||
|
|
||||||
|
def build_llm_config(llm_settings: dict[str, Any]) -> dict[str, Any]:
|
||||||
|
llm_config = {
|
||||||
|
"Mode": llm_settings["mode"],
|
||||||
|
"SystemMessages": [llm_settings["system_message"]],
|
||||||
|
"VisionConfig": {
|
||||||
|
"Enable": llm_settings["vision_enable"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if llm_settings["mode"] == "ArkV3":
|
||||||
|
llm_config["EndPointId"] = llm_settings["endpoint_id"]
|
||||||
|
llm_config["ThinkingType"] = llm_settings["thinking_type"]
|
||||||
|
return llm_config
|
||||||
|
|
||||||
|
llm_config["Url"] = llm_settings["url"]
|
||||||
|
|
||||||
|
if llm_settings["api_key"]:
|
||||||
|
llm_config["APIKey"] = llm_settings["api_key"]
|
||||||
|
|
||||||
|
optional_fields = {
|
||||||
|
"ModelName": llm_settings["model_name"],
|
||||||
|
"HistoryLength": llm_settings["history_length"],
|
||||||
|
"Prefill": llm_settings["prefill"],
|
||||||
|
"Custom": llm_settings["custom"],
|
||||||
|
"ExtraHeader": llm_settings["extra_header"],
|
||||||
|
"EnableParallelToolCalls": llm_settings["enable_parallel_tool_calls"],
|
||||||
|
"Temperature": llm_settings["temperature"],
|
||||||
|
"TopP": llm_settings["top_p"],
|
||||||
|
"MaxTokens": llm_settings["max_tokens"],
|
||||||
|
}
|
||||||
|
for key, value in optional_fields.items():
|
||||||
|
set_if_present(llm_config, key, value)
|
||||||
|
|
||||||
|
return llm_config
|
||||||
|
|
||||||
|
|
||||||
|
def build_custom_scene_from_env() -> dict[str, Any]:
|
||||||
|
missing: list[str] = []
|
||||||
|
|
||||||
|
access_key_id = require_env("CUSTOM_ACCESS_KEY_ID", missing)
|
||||||
|
secret_key = require_env("CUSTOM_SECRET_KEY", missing)
|
||||||
|
rtc_app_id = require_env("CUSTOM_RTC_APP_ID", missing)
|
||||||
|
task_id = require_env("CUSTOM_TASK_ID", missing)
|
||||||
|
agent_user_id = require_env("CUSTOM_AGENT_USER_ID", missing)
|
||||||
|
welcome_message = require_env("CUSTOM_AGENT_WELCOME_MESSAGE", missing)
|
||||||
|
asr_app_id = require_env("CUSTOM_ASR_APP_ID", missing)
|
||||||
|
tts_app_id = require_env("CUSTOM_TTS_APP_ID", missing)
|
||||||
|
llm_settings = build_llm_settings_from_env(missing)
|
||||||
|
|
||||||
|
rtc_app_key = env_str("CUSTOM_RTC_APP_KEY")
|
||||||
|
rtc_room_id = env_str("CUSTOM_RTC_ROOM_ID")
|
||||||
|
rtc_user_id = env_str("CUSTOM_RTC_USER_ID")
|
||||||
|
rtc_token = env_str("CUSTOM_RTC_TOKEN")
|
||||||
|
|
||||||
|
if not rtc_token and not rtc_app_key:
|
||||||
|
missing.append("CUSTOM_RTC_APP_KEY")
|
||||||
|
|
||||||
|
if missing:
|
||||||
|
missing_str = ", ".join(dict.fromkeys(missing))
|
||||||
|
raise ValueError(f"Custom 场景缺少以下环境变量: {missing_str}")
|
||||||
|
|
||||||
|
interrupt_mode = env_int("CUSTOM_INTERRUPT_MODE", 0)
|
||||||
|
avatar_enabled = env_bool("CUSTOM_AVATAR_ENABLED", False)
|
||||||
|
|
||||||
|
target_user_ids = env_list("CUSTOM_AGENT_TARGET_USER_ID")
|
||||||
|
if not target_user_ids:
|
||||||
|
target_user_ids = [rtc_user_id or ""]
|
||||||
|
|
||||||
|
return {
|
||||||
|
"SceneConfig": {
|
||||||
|
"icon": env_str("CUSTOM_SCENE_ICON", DEFAULT_SCENE_ICON),
|
||||||
|
"name": env_str("CUSTOM_SCENE_NAME", DEFAULT_SCENE_NAME),
|
||||||
|
},
|
||||||
|
"AccountConfig": {
|
||||||
|
"accessKeyId": access_key_id,
|
||||||
|
"secretKey": secret_key,
|
||||||
|
},
|
||||||
|
"RTCConfig": {
|
||||||
|
"AppId": rtc_app_id,
|
||||||
|
"AppKey": rtc_app_key,
|
||||||
|
"RoomId": rtc_room_id,
|
||||||
|
"UserId": rtc_user_id,
|
||||||
|
"Token": rtc_token,
|
||||||
|
},
|
||||||
|
"VoiceChat": {
|
||||||
|
"AppId": rtc_app_id,
|
||||||
|
"RoomId": rtc_room_id,
|
||||||
|
"TaskId": task_id,
|
||||||
|
"AgentConfig": {
|
||||||
|
"TargetUserId": target_user_ids,
|
||||||
|
"WelcomeMessage": welcome_message,
|
||||||
|
"UserId": agent_user_id,
|
||||||
|
"EnableConversationStateCallback": True,
|
||||||
|
},
|
||||||
|
"Config": {
|
||||||
|
"ASRConfig": {
|
||||||
|
"Provider": env_str("CUSTOM_ASR_PROVIDER", DEFAULT_ASR_PROVIDER),
|
||||||
|
"ProviderParams": {
|
||||||
|
"Mode": env_str("CUSTOM_ASR_MODE", DEFAULT_ASR_MODE),
|
||||||
|
"AppId": asr_app_id,
|
||||||
|
"Cluster": env_str("CUSTOM_ASR_CLUSTER", DEFAULT_ASR_CLUSTER),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"TTSConfig": {
|
||||||
|
"Provider": env_str("CUSTOM_TTS_PROVIDER", DEFAULT_TTS_PROVIDER),
|
||||||
|
"ProviderParams": {
|
||||||
|
"app": {
|
||||||
|
"appid": tts_app_id,
|
||||||
|
"cluster": env_str(
|
||||||
|
"CUSTOM_TTS_CLUSTER", DEFAULT_TTS_CLUSTER
|
||||||
|
),
|
||||||
|
},
|
||||||
|
"audio": {
|
||||||
|
"voice_type": env_str(
|
||||||
|
"CUSTOM_TTS_VOICE_TYPE", DEFAULT_TTS_VOICE_TYPE
|
||||||
|
),
|
||||||
|
"speed_ratio": env_number("CUSTOM_TTS_SPEED_RATIO", 1),
|
||||||
|
"pitch_ratio": env_number("CUSTOM_TTS_PITCH_RATIO", 1),
|
||||||
|
"volume_ratio": env_number("CUSTOM_TTS_VOLUME_RATIO", 1),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"LLMConfig": build_llm_config(llm_settings),
|
||||||
|
"InterruptMode": interrupt_mode,
|
||||||
|
},
|
||||||
|
"AvatarConfig": {
|
||||||
|
"Enabled": avatar_enabled,
|
||||||
|
"AvatarType": env_str("CUSTOM_AVATAR_TYPE", DEFAULT_AVATAR_TYPE),
|
||||||
|
"AvatarRole": env_str("CUSTOM_AVATAR_ROLE", DEFAULT_AVATAR_ROLE),
|
||||||
|
"BackgroundUrl": env_str("CUSTOM_AVATAR_BACKGROUND_URL"),
|
||||||
|
"VideoBitrate": env_int(
|
||||||
|
"CUSTOM_AVATAR_VIDEO_BITRATE", DEFAULT_AVATAR_VIDEO_BITRATE
|
||||||
|
),
|
||||||
|
"AvatarAppID": env_str("CUSTOM_AVATAR_APP_ID"),
|
||||||
|
"AvatarToken": env_str("CUSTOM_AVATAR_TOKEN"),
|
||||||
|
},
|
||||||
|
"InterruptMode": interrupt_mode,
|
||||||
|
},
|
||||||
|
}
|
||||||
14
backend/main.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
"""
|
||||||
|
兼容入口。
|
||||||
|
|
||||||
|
推荐使用:
|
||||||
|
uv run uvicorn server:app --host 0.0.0.0 --port 3001 --reload
|
||||||
|
"""
|
||||||
|
|
||||||
|
from server import app
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import uvicorn
|
||||||
|
|
||||||
|
uvicorn.run("server:app", host="0.0.0.0", port=3001, reload=True)
|
||||||
16
backend/pyproject.toml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[project]
|
||||||
|
name = "aigc-backend"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "AIGC Backend - FastAPI server for RTC AIGC Demo"
|
||||||
|
requires-python = ">=3.13"
|
||||||
|
dependencies = [
|
||||||
|
"fastapi>=0.110.0",
|
||||||
|
"uvicorn[standard]>=0.29.0",
|
||||||
|
"httpx>=0.27.0",
|
||||||
|
"python-dotenv>=1.2.2",
|
||||||
|
"python-multipart>=0.0.9",
|
||||||
|
"volcengine-python-sdk[ark]>=4.0.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.uv]
|
||||||
|
dev-dependencies = []
|
||||||
1
backend/routes/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
"""路由模块"""
|
||||||
108
backend/routes/chat_callback.py
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
"""
|
||||||
|
POST /api/chat_callback — 自定义 LLM 回调(SSE 流式响应)
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
from fastapi import APIRouter, Request
|
||||||
|
from fastapi.responses import StreamingResponse
|
||||||
|
|
||||||
|
from services.local_llm_service import local_llm_service
|
||||||
|
from services.scene_service import ensure_custom_llm_authorized, get_custom_llm_callback_settings
|
||||||
|
from utils.responses import custom_llm_error_response
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/api/chat_callback")
|
||||||
|
async def chat_callback(request: Request):
|
||||||
|
try:
|
||||||
|
settings = get_custom_llm_callback_settings()
|
||||||
|
ensure_custom_llm_authorized(request, settings["api_key"])
|
||||||
|
payload = await request.json()
|
||||||
|
except PermissionError as exc:
|
||||||
|
return custom_llm_error_response(
|
||||||
|
str(exc),
|
||||||
|
code="AuthenticationError",
|
||||||
|
status_code=401,
|
||||||
|
)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
return custom_llm_error_response(
|
||||||
|
"请求体必须是合法的 JSON",
|
||||||
|
code="BadRequest",
|
||||||
|
status_code=400,
|
||||||
|
)
|
||||||
|
except ValueError as exc:
|
||||||
|
return custom_llm_error_response(str(exc))
|
||||||
|
except Exception as exc:
|
||||||
|
return custom_llm_error_response(
|
||||||
|
f"解析请求失败: {exc}",
|
||||||
|
code="InternalError",
|
||||||
|
status_code=500,
|
||||||
|
)
|
||||||
|
|
||||||
|
messages = payload.get("messages")
|
||||||
|
if not isinstance(messages, list) or not messages:
|
||||||
|
return custom_llm_error_response(
|
||||||
|
"messages 不能为空",
|
||||||
|
code="BadRequest",
|
||||||
|
status_code=400,
|
||||||
|
)
|
||||||
|
|
||||||
|
last_message = messages[-1]
|
||||||
|
if last_message.get("role") != "user":
|
||||||
|
return custom_llm_error_response(
|
||||||
|
"最后一条消息必须是用户消息",
|
||||||
|
code="BadRequest",
|
||||||
|
status_code=400,
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
stream_iterator = local_llm_service.chat_stream(
|
||||||
|
history_messages=messages,
|
||||||
|
request_options={
|
||||||
|
"temperature": payload.get("temperature"),
|
||||||
|
"max_tokens": payload.get("max_tokens"),
|
||||||
|
"top_p": payload.get("top_p"),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
except Exception as exc:
|
||||||
|
return custom_llm_error_response(
|
||||||
|
f"初始化本地 LLM 流式调用失败: {exc}",
|
||||||
|
code="InternalError",
|
||||||
|
status_code=500,
|
||||||
|
)
|
||||||
|
|
||||||
|
def generate_sse():
|
||||||
|
has_error = False
|
||||||
|
try:
|
||||||
|
for chunk in stream_iterator:
|
||||||
|
if chunk is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if hasattr(chunk, "model_dump_json"):
|
||||||
|
chunk_json = chunk.model_dump_json()
|
||||||
|
else:
|
||||||
|
chunk_json = json.dumps(chunk, ensure_ascii=False)
|
||||||
|
yield f"data: {chunk_json}\n\n"
|
||||||
|
except GeneratorExit:
|
||||||
|
raise
|
||||||
|
except Exception as exc:
|
||||||
|
has_error = True
|
||||||
|
print(f"❌ /api/chat_callback 流式输出失败: {exc}")
|
||||||
|
|
||||||
|
if has_error:
|
||||||
|
print("⚠️ 已提前结束当前 SSE 流")
|
||||||
|
|
||||||
|
yield "data: [DONE]\n\n"
|
||||||
|
|
||||||
|
return StreamingResponse(
|
||||||
|
generate_sse(),
|
||||||
|
status_code=200,
|
||||||
|
media_type="text/event-stream",
|
||||||
|
headers={
|
||||||
|
"Cache-Control": "no-cache",
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"Access-Control-Allow-Origin": "*",
|
||||||
|
},
|
||||||
|
)
|
||||||
85
backend/routes/debug.py
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
"""
|
||||||
|
调试端点:POST /debug/chat, GET /debug/rag
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
|
||||||
|
from fastapi import APIRouter
|
||||||
|
from fastapi.responses import StreamingResponse
|
||||||
|
|
||||||
|
from schemas.chat import DebugChatRequest
|
||||||
|
from services.local_llm_service import local_llm_service
|
||||||
|
from services.rag_service import rag_service
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/debug")
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/chat")
|
||||||
|
async def debug_chat(request: DebugChatRequest):
|
||||||
|
current_messages = [
|
||||||
|
{"role": message.role, "content": message.content} for message in request.history
|
||||||
|
]
|
||||||
|
current_messages.append({"role": "user", "content": request.question})
|
||||||
|
|
||||||
|
start_time = time.time()
|
||||||
|
stream_iterator = local_llm_service.chat_stream(
|
||||||
|
history_messages=current_messages,
|
||||||
|
)
|
||||||
|
|
||||||
|
def generate_text():
|
||||||
|
full_ai_response = ""
|
||||||
|
total_usage = None
|
||||||
|
|
||||||
|
for chunk in stream_iterator:
|
||||||
|
if chunk is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
choices = getattr(chunk, "choices", None) or []
|
||||||
|
if choices:
|
||||||
|
delta = getattr(choices[0], "delta", None)
|
||||||
|
content = getattr(delta, "content", None)
|
||||||
|
if content:
|
||||||
|
full_ai_response += content
|
||||||
|
yield content
|
||||||
|
|
||||||
|
usage = getattr(chunk, "usage", None)
|
||||||
|
if usage:
|
||||||
|
total_usage = usage
|
||||||
|
|
||||||
|
print(f"DEBUG: LLM 调用耗时: {time.time() - start_time:.2f}s")
|
||||||
|
if total_usage:
|
||||||
|
print(
|
||||||
|
"🎫 Token 统计: "
|
||||||
|
f"Total={total_usage.total_tokens} "
|
||||||
|
f"(P:{total_usage.prompt_tokens}, C:{total_usage.completion_tokens})"
|
||||||
|
)
|
||||||
|
|
||||||
|
new_history = [
|
||||||
|
{"role": message.role, "content": message.content}
|
||||||
|
for message in request.history
|
||||||
|
]
|
||||||
|
new_history.append({"role": "user", "content": request.question})
|
||||||
|
new_history.append({"role": "assistant", "content": full_ai_response})
|
||||||
|
|
||||||
|
print("\n" + "=" * 50)
|
||||||
|
print("🐞 调试完成!以下是可用于下次请求的 history 结构:")
|
||||||
|
print(json.dumps({"history": new_history}, ensure_ascii=False, indent=2))
|
||||||
|
print("=" * 50 + "\n")
|
||||||
|
|
||||||
|
return StreamingResponse(generate_text(), media_type="text/plain")
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/rag")
|
||||||
|
async def debug_rag(query: str):
|
||||||
|
if not query:
|
||||||
|
return {"error": "请提供 query 参数"}
|
||||||
|
|
||||||
|
print(f"🔍 [Debug] 正在检索知识库: {query}")
|
||||||
|
context = await rag_service.retrieve(query)
|
||||||
|
return {
|
||||||
|
"query": query,
|
||||||
|
"retrieved_context": context,
|
||||||
|
"length": len(context) if context else 0,
|
||||||
|
"status": "success" if context else "no_results_or_error",
|
||||||
|
}
|
||||||
81
backend/routes/proxy.py
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
"""
|
||||||
|
POST /proxy — RTC OpenAPI 代理(含请求签名)
|
||||||
|
"""
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
from fastapi import APIRouter, Request
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
from config.custom_scene import get_rtc_openapi_version
|
||||||
|
from security.signer import Signer
|
||||||
|
from services.scene_service import Scenes, prepare_scene_runtime
|
||||||
|
from utils.responses import error_response
|
||||||
|
from utils.validation import assert_scene_value, assert_value
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/proxy")
|
||||||
|
async def proxy(request: Request):
|
||||||
|
action = request.query_params.get("Action", "")
|
||||||
|
version = request.query_params.get("Version") or get_rtc_openapi_version()
|
||||||
|
|
||||||
|
try:
|
||||||
|
assert_value(action, "Action 不能为空")
|
||||||
|
assert_value(version, "Version 不能为空")
|
||||||
|
|
||||||
|
body = await request.json()
|
||||||
|
scene_id = body.get("SceneID", "")
|
||||||
|
assert_value(scene_id, "SceneID 不能为空,SceneID 用于指定场景配置")
|
||||||
|
|
||||||
|
json_data = Scenes.get(scene_id)
|
||||||
|
if not json_data:
|
||||||
|
raise ValueError(f"{scene_id} 不存在,请先配置对应场景。")
|
||||||
|
|
||||||
|
_, _, voice_chat = prepare_scene_runtime(scene_id, json_data)
|
||||||
|
account_config = json_data.get("AccountConfig", {})
|
||||||
|
assert_scene_value(
|
||||||
|
scene_id, "AccountConfig.accessKeyId", account_config.get("accessKeyId")
|
||||||
|
)
|
||||||
|
assert_scene_value(
|
||||||
|
scene_id, "AccountConfig.secretKey", account_config.get("secretKey")
|
||||||
|
)
|
||||||
|
|
||||||
|
if action == "StartVoiceChat":
|
||||||
|
req_body = voice_chat
|
||||||
|
elif action == "StopVoiceChat":
|
||||||
|
app_id = voice_chat.get("AppId", "")
|
||||||
|
room_id = voice_chat.get("RoomId", "")
|
||||||
|
task_id = voice_chat.get("TaskId", "")
|
||||||
|
assert_scene_value(scene_id, "VoiceChat.AppId", app_id)
|
||||||
|
assert_scene_value(scene_id, "VoiceChat.RoomId", room_id)
|
||||||
|
assert_scene_value(scene_id, "VoiceChat.TaskId", task_id)
|
||||||
|
req_body = {"AppId": app_id, "RoomId": room_id, "TaskId": task_id}
|
||||||
|
else:
|
||||||
|
req_body = {}
|
||||||
|
|
||||||
|
request_data = {
|
||||||
|
"region": "cn-north-1",
|
||||||
|
"method": "POST",
|
||||||
|
"params": {"Action": action, "Version": version},
|
||||||
|
"headers": {
|
||||||
|
"Host": "rtc.volcengineapi.com",
|
||||||
|
"Content-type": "application/json",
|
||||||
|
},
|
||||||
|
"body": req_body,
|
||||||
|
}
|
||||||
|
signer = Signer(request_data, "rtc")
|
||||||
|
signer.add_authorization(account_config)
|
||||||
|
|
||||||
|
async with httpx.AsyncClient() as client:
|
||||||
|
resp = await client.post(
|
||||||
|
f"https://rtc.volcengineapi.com?Action={action}&Version={version}",
|
||||||
|
headers=request_data["headers"],
|
||||||
|
json=req_body,
|
||||||
|
)
|
||||||
|
return JSONResponse(resp.json())
|
||||||
|
|
||||||
|
except ValueError as e:
|
||||||
|
return error_response(action, str(e))
|
||||||
|
except Exception as e:
|
||||||
|
return error_response(action, str(e))
|
||||||
74
backend/routes/scenes.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
"""
|
||||||
|
POST /getScenes — 场景列表
|
||||||
|
"""
|
||||||
|
|
||||||
|
from fastapi import APIRouter
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
from services.scene_service import Scenes, prepare_scene_runtime
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/getScenes")
|
||||||
|
async def get_scenes():
|
||||||
|
try:
|
||||||
|
scenes_list = []
|
||||||
|
for scene_name, data in Scenes.items():
|
||||||
|
scene_config, rtc_config, voice_chat = prepare_scene_runtime(
|
||||||
|
scene_name, data
|
||||||
|
)
|
||||||
|
|
||||||
|
scene_config["id"] = scene_name
|
||||||
|
scene_config["botName"] = voice_chat.get("AgentConfig", {}).get("UserId")
|
||||||
|
scene_config["isInterruptMode"] = (
|
||||||
|
voice_chat.get("Config", {}).get("InterruptMode") == 0
|
||||||
|
)
|
||||||
|
scene_config["isVision"] = (
|
||||||
|
voice_chat.get("Config", {})
|
||||||
|
.get("LLMConfig", {})
|
||||||
|
.get("VisionConfig", {})
|
||||||
|
.get("Enable")
|
||||||
|
)
|
||||||
|
scene_config["isScreenMode"] = (
|
||||||
|
voice_chat.get("Config", {})
|
||||||
|
.get("LLMConfig", {})
|
||||||
|
.get("VisionConfig", {})
|
||||||
|
.get("SnapshotConfig", {})
|
||||||
|
.get("StreamType")
|
||||||
|
== 1
|
||||||
|
)
|
||||||
|
scene_config["isAvatarScene"] = (
|
||||||
|
voice_chat.get("Config", {}).get("AvatarConfig", {}).get("Enabled")
|
||||||
|
)
|
||||||
|
scene_config["avatarBgUrl"] = (
|
||||||
|
voice_chat.get("Config", {})
|
||||||
|
.get("AvatarConfig", {})
|
||||||
|
.get("BackgroundUrl")
|
||||||
|
)
|
||||||
|
|
||||||
|
rtc_out = {k: v for k, v in rtc_config.items() if k != "AppKey"}
|
||||||
|
|
||||||
|
scenes_list.append(
|
||||||
|
{
|
||||||
|
"scene": scene_config,
|
||||||
|
"rtc": rtc_out,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return JSONResponse(
|
||||||
|
{
|
||||||
|
"ResponseMetadata": {"Action": "getScenes"},
|
||||||
|
"Result": {"scenes": scenes_list},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
except ValueError as e:
|
||||||
|
return JSONResponse(
|
||||||
|
{
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"Action": "getScenes",
|
||||||
|
"Error": {"Code": -1, "Message": str(e)},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
1
backend/schemas/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
"""Pydantic 请求/响应模型"""
|
||||||
15
backend/schemas/chat.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
"""
|
||||||
|
聊天相关的请求模型
|
||||||
|
"""
|
||||||
|
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
|
|
||||||
|
class ChatMessage(BaseModel):
|
||||||
|
role: str
|
||||||
|
content: str
|
||||||
|
|
||||||
|
|
||||||
|
class DebugChatRequest(BaseModel):
|
||||||
|
history: list[ChatMessage] = Field(default_factory=list)
|
||||||
|
question: str
|
||||||
1
backend/security/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
"""Backend security package."""
|
||||||
103
backend/security/rtc_token.py
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
"""
|
||||||
|
Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved.
|
||||||
|
SPDX-license-identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
Migrated from Server/token.js
|
||||||
|
"""
|
||||||
|
|
||||||
|
import base64
|
||||||
|
import hashlib
|
||||||
|
import hmac
|
||||||
|
import random
|
||||||
|
import struct
|
||||||
|
import time
|
||||||
|
|
||||||
|
VERSION = "001"
|
||||||
|
VERSION_LENGTH = 3
|
||||||
|
APP_ID_LENGTH = 24
|
||||||
|
|
||||||
|
privileges = {
|
||||||
|
"PrivPublishStream": 0,
|
||||||
|
"privPublishAudioStream": 1,
|
||||||
|
"privPublishVideoStream": 2,
|
||||||
|
"privPublishDataStream": 3,
|
||||||
|
"PrivSubscribeStream": 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ByteBuf:
|
||||||
|
def __init__(self):
|
||||||
|
self._buf = bytearray()
|
||||||
|
|
||||||
|
def put_uint16(self, v: int) -> "ByteBuf":
|
||||||
|
self._buf += struct.pack("<H", v)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def put_uint32(self, v: int) -> "ByteBuf":
|
||||||
|
self._buf += struct.pack("<I", v)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def put_bytes(self, b: bytes) -> "ByteBuf":
|
||||||
|
self.put_uint16(len(b))
|
||||||
|
self._buf += b
|
||||||
|
return self
|
||||||
|
|
||||||
|
def put_string(self, s: str) -> "ByteBuf":
|
||||||
|
return self.put_bytes(s.encode("utf-8"))
|
||||||
|
|
||||||
|
def put_tree_map_uint32(self, m: dict) -> "ByteBuf":
|
||||||
|
if not m:
|
||||||
|
self.put_uint16(0)
|
||||||
|
return self
|
||||||
|
sorted_items = sorted(m.items(), key=lambda x: int(x[0]))
|
||||||
|
self.put_uint16(len(sorted_items))
|
||||||
|
for key, value in sorted_items:
|
||||||
|
self.put_uint16(int(key))
|
||||||
|
self.put_uint32(int(value))
|
||||||
|
return self
|
||||||
|
|
||||||
|
def pack(self) -> bytes:
|
||||||
|
return bytes(self._buf)
|
||||||
|
|
||||||
|
|
||||||
|
def _encode_hmac(key: str, message: bytes) -> bytes:
|
||||||
|
return hmac.new(key.encode("utf-8"), message, hashlib.sha256).digest()
|
||||||
|
|
||||||
|
|
||||||
|
class AccessToken:
|
||||||
|
def __init__(self, app_id: str, app_key: str, room_id: str, user_id: str):
|
||||||
|
self.app_id = app_id
|
||||||
|
self.app_key = app_key
|
||||||
|
self.room_id = room_id
|
||||||
|
self.user_id = user_id
|
||||||
|
self.issued_at = int(time.time())
|
||||||
|
random.seed(time.time())
|
||||||
|
self.nonce = random.randint(1, 99999999)
|
||||||
|
self.expire_at = 0
|
||||||
|
self._privileges: dict = {}
|
||||||
|
|
||||||
|
def add_privilege(self, privilege: int, expire_timestamp: int):
|
||||||
|
self._privileges[privilege] = expire_timestamp
|
||||||
|
if privilege == privileges["PrivPublishStream"]:
|
||||||
|
self._privileges[privileges["privPublishVideoStream"]] = expire_timestamp
|
||||||
|
self._privileges[privileges["privPublishAudioStream"]] = expire_timestamp
|
||||||
|
self._privileges[privileges["privPublishDataStream"]] = expire_timestamp
|
||||||
|
|
||||||
|
def expire_time(self, expire_timestamp: int):
|
||||||
|
self.expire_at = expire_timestamp
|
||||||
|
|
||||||
|
def _pack_msg(self) -> bytes:
|
||||||
|
buf = ByteBuf()
|
||||||
|
buf.put_uint32(self.nonce)
|
||||||
|
buf.put_uint32(self.issued_at)
|
||||||
|
buf.put_uint32(self.expire_at)
|
||||||
|
buf.put_string(self.room_id)
|
||||||
|
buf.put_string(self.user_id)
|
||||||
|
buf.put_tree_map_uint32(self._privileges)
|
||||||
|
return buf.pack()
|
||||||
|
|
||||||
|
def serialize(self) -> str:
|
||||||
|
msg = self._pack_msg()
|
||||||
|
signature = _encode_hmac(self.app_key, msg)
|
||||||
|
content = ByteBuf().put_bytes(msg).put_bytes(signature).pack()
|
||||||
|
return VERSION + self.app_id + base64.b64encode(content).decode("utf-8")
|
||||||
114
backend/security/signer.py
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
"""
|
||||||
|
Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved.
|
||||||
|
SPDX-license-identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
Migrated from @volcengine/openapi Signer (AWS SigV4 compatible)
|
||||||
|
Reference: https://www.volcengine.com/docs/6348/69828
|
||||||
|
"""
|
||||||
|
|
||||||
|
import hashlib
|
||||||
|
import hmac
|
||||||
|
import json
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
from urllib.parse import quote
|
||||||
|
|
||||||
|
|
||||||
|
def _sha256_hex(data: bytes) -> str:
|
||||||
|
return hashlib.sha256(data).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def _hmac_sha256(key: bytes, data: str) -> bytes:
|
||||||
|
return hmac.new(key, data.encode("utf-8"), hashlib.sha256).digest()
|
||||||
|
|
||||||
|
|
||||||
|
def _get_signing_key(secret_key: str, date_str: str, region: str, service: str) -> bytes:
|
||||||
|
k_date = _hmac_sha256(secret_key.encode("utf-8"), date_str)
|
||||||
|
k_region = _hmac_sha256(k_date, region)
|
||||||
|
k_service = _hmac_sha256(k_region, service)
|
||||||
|
k_signing = _hmac_sha256(k_service, "request")
|
||||||
|
return k_signing
|
||||||
|
|
||||||
|
|
||||||
|
class Signer:
|
||||||
|
"""
|
||||||
|
Signs requests to Volcengine OpenAPI using AWS SigV4-compatible signing.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, request_data: dict, service: str):
|
||||||
|
"""
|
||||||
|
request_data: {
|
||||||
|
region: str,
|
||||||
|
method: str,
|
||||||
|
params: dict,
|
||||||
|
headers: dict,
|
||||||
|
body: dict,
|
||||||
|
}
|
||||||
|
service: e.g. "rtc"
|
||||||
|
"""
|
||||||
|
self.region = request_data.get("region", "cn-north-1")
|
||||||
|
self.method = request_data.get("method", "POST").upper()
|
||||||
|
self.params = request_data.get("params", {})
|
||||||
|
self.headers = request_data.get("headers", {})
|
||||||
|
self.body = request_data.get("body", {})
|
||||||
|
self.service = service
|
||||||
|
|
||||||
|
def add_authorization(self, account_config: dict):
|
||||||
|
access_key = account_config["accessKeyId"]
|
||||||
|
secret_key = account_config["secretKey"]
|
||||||
|
|
||||||
|
now = datetime.now(timezone.utc)
|
||||||
|
date_str = now.strftime("%Y%m%d")
|
||||||
|
datetime_str = now.strftime("%Y%m%dT%H%M%SZ")
|
||||||
|
|
||||||
|
self.headers["X-Date"] = datetime_str
|
||||||
|
self.headers["X-Content-Sha256"] = _sha256_hex(
|
||||||
|
json.dumps(self.body, separators=(",", ":"), ensure_ascii=False).encode(
|
||||||
|
"utf-8"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
signed_header_names = sorted(k.lower() for k in self.headers)
|
||||||
|
canonical_headers = "".join(
|
||||||
|
f"{k}:{self.headers[next(h for h in self.headers if h.lower() == k)]}\n"
|
||||||
|
for k in signed_header_names
|
||||||
|
)
|
||||||
|
signed_headers_str = ";".join(signed_header_names)
|
||||||
|
|
||||||
|
sorted_params = sorted(self.params.items())
|
||||||
|
canonical_qs = "&".join(
|
||||||
|
f"{quote(str(k), safe='')}={quote(str(v), safe='')}"
|
||||||
|
for k, v in sorted_params
|
||||||
|
)
|
||||||
|
|
||||||
|
body_hash = self.headers["X-Content-Sha256"]
|
||||||
|
canonical_request = "\n".join(
|
||||||
|
[
|
||||||
|
self.method,
|
||||||
|
"/",
|
||||||
|
canonical_qs,
|
||||||
|
canonical_headers,
|
||||||
|
signed_headers_str,
|
||||||
|
body_hash,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
credential_scope = f"{date_str}/{self.region}/{self.service}/request"
|
||||||
|
string_to_sign = "\n".join(
|
||||||
|
[
|
||||||
|
"HMAC-SHA256",
|
||||||
|
datetime_str,
|
||||||
|
credential_scope,
|
||||||
|
_sha256_hex(canonical_request.encode("utf-8")),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
signing_key = _get_signing_key(secret_key, date_str, self.region, self.service)
|
||||||
|
signature = hmac.new(
|
||||||
|
signing_key, string_to_sign.encode("utf-8"), hashlib.sha256
|
||||||
|
).hexdigest()
|
||||||
|
|
||||||
|
self.headers["Authorization"] = (
|
||||||
|
f"HMAC-SHA256 Credential={access_key}/{credential_scope}, "
|
||||||
|
f"SignedHeaders={signed_headers_str}, "
|
||||||
|
f"Signature={signature}"
|
||||||
|
)
|
||||||
34
backend/server.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
|
BASE_DIR = Path(__file__).parent
|
||||||
|
load_dotenv(BASE_DIR / ".env", override=False)
|
||||||
|
|
||||||
|
# 路由必须在 load_dotenv 之后导入,因为模块级代码会读取环境变量
|
||||||
|
from routes.chat_callback import router as chat_callback_router # noqa: E402
|
||||||
|
from routes.debug import router as debug_router # noqa: E402
|
||||||
|
from routes.proxy import router as proxy_router # noqa: E402
|
||||||
|
from routes.scenes import router as scenes_router # noqa: E402
|
||||||
|
|
||||||
|
from fastapi import FastAPI # noqa: E402
|
||||||
|
from fastapi.middleware.cors import CORSMiddleware # noqa: E402
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
app.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
allow_origins=["*"],
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"],
|
||||||
|
)
|
||||||
|
|
||||||
|
app.include_router(proxy_router)
|
||||||
|
app.include_router(scenes_router)
|
||||||
|
app.include_router(chat_callback_router)
|
||||||
|
app.include_router(debug_router)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import uvicorn
|
||||||
|
|
||||||
|
uvicorn.run("server:app", host="0.0.0.0", port=3001, reload=True)
|
||||||
1
backend/services/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
"""本地 LLM 与知识检索服务。"""
|
||||||
139
backend/services/local_llm_service.py
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
"""
|
||||||
|
本地 CustomLLM 服务。
|
||||||
|
|
||||||
|
当前实现直接在同一个 FastAPI 进程内调用方舟 SDK,
|
||||||
|
并由 /api/chat_callback 对外提供火山要求的 SSE 回调接口。
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Any, Iterator
|
||||||
|
|
||||||
|
from utils.env import env_float, env_int, env_str
|
||||||
|
|
||||||
|
DEFAULT_ARK_BASE_URL = "https://ark.cn-beijing.volces.com/api/v3"
|
||||||
|
DEFAULT_ARK_TIMEOUT_SECONDS = 1800
|
||||||
|
DEFAULT_ARK_TEMPERATURE = 0
|
||||||
|
|
||||||
|
|
||||||
|
def _coalesce(*values):
|
||||||
|
for value in values:
|
||||||
|
if value is not None:
|
||||||
|
return value
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class LocalLLMSettings:
|
||||||
|
api_key: str
|
||||||
|
endpoint_id: str
|
||||||
|
base_url: str
|
||||||
|
timeout_seconds: int
|
||||||
|
system_prompt: str
|
||||||
|
default_temperature: float
|
||||||
|
|
||||||
|
|
||||||
|
def _load_settings() -> LocalLLMSettings:
|
||||||
|
api_key = env_str("ARK_API_KEY")
|
||||||
|
endpoint_id = env_str("ARK_ENDPOINT_ID")
|
||||||
|
|
||||||
|
if not api_key:
|
||||||
|
raise ValueError("ARK_API_KEY 不能为空")
|
||||||
|
if not endpoint_id:
|
||||||
|
raise ValueError("ARK_ENDPOINT_ID 不能为空")
|
||||||
|
|
||||||
|
return LocalLLMSettings(
|
||||||
|
api_key=api_key,
|
||||||
|
endpoint_id=endpoint_id,
|
||||||
|
base_url=env_str("ARK_BASE_URL", DEFAULT_ARK_BASE_URL),
|
||||||
|
timeout_seconds=env_int("ARK_TIMEOUT_SECONDS", DEFAULT_ARK_TIMEOUT_SECONDS),
|
||||||
|
system_prompt=env_str(
|
||||||
|
"LOCAL_LLM_SYSTEM_PROMPT",
|
||||||
|
env_str("CUSTOM_LLM_SYSTEM_MESSAGE"),
|
||||||
|
),
|
||||||
|
default_temperature=env_float(
|
||||||
|
"LOCAL_LLM_TEMPERATURE", DEFAULT_ARK_TEMPERATURE
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class LocalLLMService:
|
||||||
|
def __init__(self):
|
||||||
|
self._client = None
|
||||||
|
self._settings: LocalLLMSettings | None = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def settings(self) -> LocalLLMSettings:
|
||||||
|
if self._settings is None:
|
||||||
|
self._settings = _load_settings()
|
||||||
|
return self._settings
|
||||||
|
|
||||||
|
def _get_client(self):
|
||||||
|
if self._client is not None:
|
||||||
|
return self._client
|
||||||
|
|
||||||
|
try:
|
||||||
|
from volcenginesdkarkruntime import Ark
|
||||||
|
except ImportError as exc:
|
||||||
|
raise RuntimeError(
|
||||||
|
"未安装 volcenginesdkarkruntime,请先执行 uv sync 安装依赖"
|
||||||
|
) from exc
|
||||||
|
|
||||||
|
s = self.settings
|
||||||
|
self._client = Ark(
|
||||||
|
base_url=s.base_url,
|
||||||
|
api_key=s.api_key,
|
||||||
|
timeout=s.timeout_seconds,
|
||||||
|
)
|
||||||
|
return self._client
|
||||||
|
|
||||||
|
def chat_stream(
|
||||||
|
self,
|
||||||
|
history_messages: list[dict[str, Any]],
|
||||||
|
rag_context: str = "",
|
||||||
|
request_options: dict[str, Any] | None = None,
|
||||||
|
) -> Iterator[Any]:
|
||||||
|
settings = self.settings
|
||||||
|
client = self._get_client()
|
||||||
|
request_options = request_options or {}
|
||||||
|
|
||||||
|
system_blocks = [settings.system_prompt]
|
||||||
|
if rag_context:
|
||||||
|
system_blocks.append(f"### 参考知识库(绝对准则)\n{rag_context.strip()}")
|
||||||
|
|
||||||
|
messages = [
|
||||||
|
{
|
||||||
|
"role": "system",
|
||||||
|
"content": "\n\n".join(block for block in system_blocks if block),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
messages.extend(history_messages)
|
||||||
|
|
||||||
|
payload: dict[str, Any] = {
|
||||||
|
"model": settings.endpoint_id,
|
||||||
|
"messages": messages,
|
||||||
|
"temperature": _coalesce(
|
||||||
|
request_options.get("temperature"),
|
||||||
|
settings.default_temperature,
|
||||||
|
),
|
||||||
|
"stream": True,
|
||||||
|
"stream_options": {"include_usage": True},
|
||||||
|
}
|
||||||
|
|
||||||
|
if request_options.get("max_tokens") is not None:
|
||||||
|
payload["max_tokens"] = request_options["max_tokens"]
|
||||||
|
if request_options.get("top_p") is not None:
|
||||||
|
payload["top_p"] = request_options["top_p"]
|
||||||
|
|
||||||
|
print(f"🚀 发起流式调用 (Endpoint: {settings.endpoint_id})")
|
||||||
|
try:
|
||||||
|
stream = client.chat.completions.create(**payload)
|
||||||
|
for chunk in stream:
|
||||||
|
yield chunk
|
||||||
|
except Exception as exc:
|
||||||
|
print(f"❌ LLM 调用失败: {exc}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
local_llm_service = LocalLLMService()
|
||||||
30
backend/services/rag_service.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
"""
|
||||||
|
最小可用的 RAG 服务占位实现。
|
||||||
|
|
||||||
|
当前版本支持两种简单来源:
|
||||||
|
- RAG_STATIC_CONTEXT:直接写在环境变量中的固定知识
|
||||||
|
- RAG_CONTEXT_FILE:读取本地文件全文作为知识上下文
|
||||||
|
|
||||||
|
后续如果要接真正的向量检索,可以直接替换 retrieve 方法实现。
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from utils.env import env_str
|
||||||
|
|
||||||
|
|
||||||
|
class RagService:
|
||||||
|
async def retrieve(self, query: str) -> str:
|
||||||
|
_ = query
|
||||||
|
context_file = env_str("RAG_CONTEXT_FILE")
|
||||||
|
if context_file:
|
||||||
|
path = Path(context_file).expanduser()
|
||||||
|
if path.exists() and path.is_file():
|
||||||
|
return path.read_text(encoding="utf-8")
|
||||||
|
|
||||||
|
return env_str("RAG_STATIC_CONTEXT")
|
||||||
|
|
||||||
|
|
||||||
|
rag_service = RagService()
|
||||||
99
backend/services/scene_service.py
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
"""
|
||||||
|
场景配置加载与运行时准备
|
||||||
|
"""
|
||||||
|
|
||||||
|
import copy
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import uuid
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from fastapi import Request
|
||||||
|
|
||||||
|
from config.custom_scene import (
|
||||||
|
CUSTOM_SCENE_ID,
|
||||||
|
build_custom_scene_from_env,
|
||||||
|
build_llm_settings_from_env,
|
||||||
|
)
|
||||||
|
from security.rtc_token import AccessToken, privileges
|
||||||
|
from utils.validation import assert_scene_value, assert_token_generation_ready
|
||||||
|
|
||||||
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
|
SCENES_DIR = BASE_DIR / "scenes"
|
||||||
|
|
||||||
|
|
||||||
|
def load_scenes() -> dict:
|
||||||
|
scenes = {
|
||||||
|
CUSTOM_SCENE_ID: build_custom_scene_from_env(),
|
||||||
|
}
|
||||||
|
for p in sorted(SCENES_DIR.glob("*.json")):
|
||||||
|
if p.stem == CUSTOM_SCENE_ID:
|
||||||
|
continue
|
||||||
|
with open(p, encoding="utf-8") as f:
|
||||||
|
scenes[p.stem] = json.load(f)
|
||||||
|
return scenes
|
||||||
|
|
||||||
|
|
||||||
|
def prepare_scene_runtime(scene_name: str, data: dict[str, Any]):
|
||||||
|
data = copy.deepcopy(data)
|
||||||
|
scene_config = data.get("SceneConfig", {})
|
||||||
|
rtc_config = data.get("RTCConfig", {})
|
||||||
|
voice_chat = data.get("VoiceChat", {})
|
||||||
|
|
||||||
|
app_id = rtc_config.get("AppId", "")
|
||||||
|
assert_scene_value(scene_name, "RTCConfig.AppId", app_id)
|
||||||
|
|
||||||
|
token = rtc_config.get("Token", "")
|
||||||
|
user_id = rtc_config.get("UserId", "")
|
||||||
|
room_id = rtc_config.get("RoomId", "")
|
||||||
|
app_key = rtc_config.get("AppKey", "")
|
||||||
|
|
||||||
|
if app_id and (not token or not user_id or not room_id):
|
||||||
|
rtc_config["RoomId"] = voice_chat["RoomId"] = room_id or str(uuid.uuid4())
|
||||||
|
rtc_config["UserId"] = user_id = user_id or str(uuid.uuid4())
|
||||||
|
|
||||||
|
agent_config = voice_chat.get("AgentConfig", {})
|
||||||
|
target_user_ids = agent_config.get("TargetUserId")
|
||||||
|
if target_user_ids:
|
||||||
|
target_user_ids[0] = rtc_config["UserId"]
|
||||||
|
|
||||||
|
assert_token_generation_ready(scene_name, app_key)
|
||||||
|
key = AccessToken(app_id, app_key, rtc_config["RoomId"], rtc_config["UserId"])
|
||||||
|
key.add_privilege(privileges["PrivSubscribeStream"], 0)
|
||||||
|
key.add_privilege(privileges["PrivPublishStream"], 0)
|
||||||
|
key.expire_time(int(time.time()) + 24 * 3600)
|
||||||
|
rtc_config["Token"] = key.serialize()
|
||||||
|
|
||||||
|
return scene_config, rtc_config, voice_chat
|
||||||
|
|
||||||
|
|
||||||
|
def get_custom_llm_callback_settings() -> dict[str, Any]:
|
||||||
|
missing: list[str] = []
|
||||||
|
settings = build_llm_settings_from_env(missing)
|
||||||
|
if missing:
|
||||||
|
missing_str = ", ".join(dict.fromkeys(missing))
|
||||||
|
raise ValueError(f"Custom 场景缺少以下环境变量: {missing_str}")
|
||||||
|
|
||||||
|
if settings["mode"] != "CustomLLM":
|
||||||
|
raise ValueError("当前 CUSTOM_LLM_MODE 不是 CustomLLM,无法使用本地回调接口")
|
||||||
|
|
||||||
|
return settings
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_custom_llm_authorized(request: Request, api_key: str):
|
||||||
|
if not api_key:
|
||||||
|
return
|
||||||
|
|
||||||
|
authorization = request.headers.get("authorization", "")
|
||||||
|
expected_value = f"Bearer {api_key}"
|
||||||
|
if authorization == expected_value:
|
||||||
|
return
|
||||||
|
|
||||||
|
raise PermissionError("自定义 LLM 回调鉴权失败,请检查 CUSTOM_LLM_API_KEY")
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
Scenes = load_scenes()
|
||||||
|
except ValueError as exc:
|
||||||
|
raise RuntimeError(f"Custom 场景配置错误:{exc}") from exc
|
||||||
0
backend/utils/__init__.py
Normal file
134
backend/utils/env.py
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
"""
|
||||||
|
环境变量读取工具函数。
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
TRUTHY_VALUES = {"1", "true", "yes", "on"}
|
||||||
|
FALSY_VALUES = {"0", "false", "no", "off"}
|
||||||
|
|
||||||
|
|
||||||
|
def env_str(name: str, default: str = "") -> str:
|
||||||
|
value = os.getenv(name)
|
||||||
|
if value is None:
|
||||||
|
return default
|
||||||
|
value = value.strip()
|
||||||
|
return value if value else default
|
||||||
|
|
||||||
|
|
||||||
|
def require_env(name: str, missing: list[str]) -> str:
|
||||||
|
value = env_str(name)
|
||||||
|
if not value:
|
||||||
|
missing.append(name)
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def env_bool(name: str, default: bool) -> bool:
|
||||||
|
raw_value = os.getenv(name)
|
||||||
|
if raw_value is None or not raw_value.strip():
|
||||||
|
return default
|
||||||
|
|
||||||
|
value = raw_value.strip().lower()
|
||||||
|
if value in TRUTHY_VALUES:
|
||||||
|
return True
|
||||||
|
if value in FALSY_VALUES:
|
||||||
|
return False
|
||||||
|
|
||||||
|
raise ValueError(f"{name} 必须是布尔值,可选 true/false/1/0")
|
||||||
|
|
||||||
|
|
||||||
|
def env_optional_bool(name: str) -> bool | None:
|
||||||
|
raw_value = os.getenv(name)
|
||||||
|
if raw_value is None or not raw_value.strip():
|
||||||
|
return None
|
||||||
|
return env_bool(name, False)
|
||||||
|
|
||||||
|
|
||||||
|
def env_int(name: str, default: int) -> int:
|
||||||
|
raw_value = os.getenv(name)
|
||||||
|
if raw_value is None or not raw_value.strip():
|
||||||
|
return default
|
||||||
|
|
||||||
|
try:
|
||||||
|
return int(raw_value.strip())
|
||||||
|
except ValueError as exc:
|
||||||
|
raise ValueError(f"{name} 必须是整数") from exc
|
||||||
|
|
||||||
|
|
||||||
|
def env_optional_int(name: str) -> int | None:
|
||||||
|
raw_value = os.getenv(name)
|
||||||
|
if raw_value is None or not raw_value.strip():
|
||||||
|
return None
|
||||||
|
return env_int(name, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def env_float(name: str, default: float) -> float:
|
||||||
|
raw_value = os.getenv(name)
|
||||||
|
if raw_value is None or not raw_value.strip():
|
||||||
|
return default
|
||||||
|
|
||||||
|
try:
|
||||||
|
return float(raw_value.strip())
|
||||||
|
except ValueError as exc:
|
||||||
|
raise ValueError(f"{name} 必须是浮点数") from exc
|
||||||
|
|
||||||
|
|
||||||
|
def env_number(name: str, default: int | float) -> int | float:
|
||||||
|
raw_value = os.getenv(name)
|
||||||
|
if raw_value is None or not raw_value.strip():
|
||||||
|
return default
|
||||||
|
|
||||||
|
try:
|
||||||
|
value = float(raw_value.strip())
|
||||||
|
except ValueError as exc:
|
||||||
|
raise ValueError(f"{name} 必须是数字") from exc
|
||||||
|
|
||||||
|
if value.is_integer():
|
||||||
|
return int(value)
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def env_optional_number(name: str) -> int | float | None:
|
||||||
|
raw_value = os.getenv(name)
|
||||||
|
if raw_value is None or not raw_value.strip():
|
||||||
|
return None
|
||||||
|
return env_number(name, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def env_json_object(name: str) -> dict[str, str]:
|
||||||
|
raw_value = os.getenv(name)
|
||||||
|
if raw_value is None or not raw_value.strip():
|
||||||
|
return {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
value = json.loads(raw_value)
|
||||||
|
except json.JSONDecodeError as exc:
|
||||||
|
raise ValueError(f"{name} 必须是合法的 JSON 对象字符串") from exc
|
||||||
|
|
||||||
|
if not isinstance(value, dict):
|
||||||
|
raise ValueError(f"{name} 必须是 JSON 对象")
|
||||||
|
|
||||||
|
invalid_keys = [key for key in value.keys() if not isinstance(key, str)]
|
||||||
|
if invalid_keys:
|
||||||
|
raise ValueError(f"{name} 的所有键必须是字符串")
|
||||||
|
|
||||||
|
return {key: str(val) for key, val in value.items()}
|
||||||
|
|
||||||
|
|
||||||
|
def env_list(name: str) -> list[str]:
|
||||||
|
raw_value = os.getenv(name)
|
||||||
|
if raw_value is None or not raw_value.strip():
|
||||||
|
return []
|
||||||
|
return [item.strip() for item in raw_value.split(",") if item.strip()]
|
||||||
|
|
||||||
|
|
||||||
|
def set_if_present(target: dict[str, Any], key: str, value: Any):
|
||||||
|
if value is None:
|
||||||
|
return
|
||||||
|
if isinstance(value, str) and not value:
|
||||||
|
return
|
||||||
|
if isinstance(value, dict) and not value:
|
||||||
|
return
|
||||||
|
target[key] = value
|
||||||
33
backend/utils/responses.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
"""
|
||||||
|
统一错误响应格式
|
||||||
|
"""
|
||||||
|
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
|
||||||
|
def error_response(action: str, message: str):
|
||||||
|
return JSONResponse(
|
||||||
|
{
|
||||||
|
"ResponseMetadata": {
|
||||||
|
"Action": action,
|
||||||
|
"Error": {"Code": -1, "Message": message},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def custom_llm_error_response(
|
||||||
|
message: str,
|
||||||
|
*,
|
||||||
|
code: str = "InvalidConfiguration",
|
||||||
|
status_code: int = 400,
|
||||||
|
):
|
||||||
|
return JSONResponse(
|
||||||
|
{
|
||||||
|
"Error": {
|
||||||
|
"Code": code,
|
||||||
|
"Message": message,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
status_code=status_code,
|
||||||
|
)
|
||||||
31
backend/utils/validation.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
"""
|
||||||
|
校验工具函数
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from config.custom_scene import CUSTOM_SCENE_ID
|
||||||
|
|
||||||
|
|
||||||
|
def assert_value(value, msg: str):
|
||||||
|
if not value:
|
||||||
|
raise ValueError(msg)
|
||||||
|
|
||||||
|
|
||||||
|
def assert_scene_value(scene_name: str, field_name: str, value: Any):
|
||||||
|
if value:
|
||||||
|
return
|
||||||
|
|
||||||
|
raise ValueError(f"{scene_name} 场景的 {field_name} 不能为空")
|
||||||
|
|
||||||
|
|
||||||
|
def assert_token_generation_ready(scene_name: str, app_key: str):
|
||||||
|
if app_key:
|
||||||
|
return
|
||||||
|
|
||||||
|
if scene_name == CUSTOM_SCENE_ID:
|
||||||
|
raise ValueError(
|
||||||
|
"Custom 场景未提供 CUSTOM_RTC_TOKEN 时,必须配置 CUSTOM_RTC_APP_KEY 用于自动生成 Token"
|
||||||
|
)
|
||||||
|
|
||||||
|
raise ValueError(f"自动生成 Token 时,{scene_name} 场景的 RTCConfig.AppKey 不可为空")
|
||||||
631
backend/uv.lock
generated
Normal file
@ -0,0 +1,631 @@
|
|||||||
|
version = 1
|
||||||
|
revision = 1
|
||||||
|
requires-python = ">=3.13"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aigc-backend"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = { virtual = "." }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "fastapi" },
|
||||||
|
{ name = "httpx" },
|
||||||
|
{ name = "python-dotenv" },
|
||||||
|
{ name = "python-multipart" },
|
||||||
|
{ name = "uvicorn", extra = ["standard"] },
|
||||||
|
{ name = "volcengine-python-sdk", extra = ["ark"] },
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [
|
||||||
|
{ name = "fastapi", specifier = ">=0.110.0" },
|
||||||
|
{ name = "httpx", specifier = ">=0.27.0" },
|
||||||
|
{ name = "python-dotenv", specifier = ">=1.2.2" },
|
||||||
|
{ name = "python-multipart", specifier = ">=0.0.9" },
|
||||||
|
{ name = "uvicorn", extras = ["standard"], specifier = ">=0.29.0" },
|
||||||
|
{ name = "volcengine-python-sdk", extras = ["ark"], specifier = ">=4.0.6" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.metadata.requires-dev]
|
||||||
|
dev = []
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "annotated-doc"
|
||||||
|
version = "0.0.4"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "annotated-types"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyio"
|
||||||
|
version = "4.13.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "idna" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/19/14/2c5dd9f512b66549ae92767a9c7b330ae88e1932ca57876909410251fe13/anyio-4.13.0.tar.gz", hash = "sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc", size = 231622 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708", size = 114353 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "certifi"
|
||||||
|
version = "2026.2.25"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cffi"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "pycparser", marker = "implementation_name != 'PyPy'" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "click"
|
||||||
|
version = "8.3.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorama"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cryptography"
|
||||||
|
version = "46.0.6"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/a4/ba/04b1bd4218cbc58dc90ce967106d51582371b898690f3ae0402876cc4f34/cryptography-46.0.6.tar.gz", hash = "sha256:27550628a518c5c6c903d84f637fbecf287f6cb9ced3804838a1295dc1fd0759", size = 750542 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/47/23/9285e15e3bc57325b0a72e592921983a701efc1ee8f91c06c5f0235d86d9/cryptography-46.0.6-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:64235194bad039a10bb6d2d930ab3323baaec67e2ce36215fd0952fad0930ca8", size = 7176401 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/60/f8/e61f8f13950ab6195b31913b42d39f0f9afc7d93f76710f299b5ec286ae6/cryptography-46.0.6-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:26031f1e5ca62fcb9d1fcb34b2b60b390d1aacaa15dc8b895a9ed00968b97b30", size = 4275275 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/19/69/732a736d12c2631e140be2348b4ad3d226302df63ef64d30dfdb8db7ad1c/cryptography-46.0.6-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9a693028b9cbe51b5a1136232ee8f2bc242e4e19d456ded3fa7c86e43c713b4a", size = 4425320 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d4/12/123be7292674abf76b21ac1fc0e1af50661f0e5b8f0ec8285faac18eb99e/cryptography-46.0.6-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:67177e8a9f421aa2d3a170c3e56eca4e0128883cf52a071a7cbf53297f18b175", size = 4278082 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/5b/ba/d5e27f8d68c24951b0a484924a84c7cdaed7502bac9f18601cd357f8b1d2/cryptography-46.0.6-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:d9528b535a6c4f8ff37847144b8986a9a143585f0540fbcb1a98115b543aa463", size = 4926514 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/34/71/1ea5a7352ae516d5512d17babe7e1b87d9db5150b21f794b1377eac1edc0/cryptography-46.0.6-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:22259338084d6ae497a19bae5d4c66b7ca1387d3264d1c2c0e72d9e9b6a77b97", size = 4457766 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/01/59/562be1e653accee4fdad92c7a2e88fced26b3fdfce144047519bbebc299e/cryptography-46.0.6-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:760997a4b950ff00d418398ad73fbc91aa2894b5c1db7ccb45b4f68b42a63b3c", size = 3986535 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d6/8b/b1ebfeb788bf4624d36e45ed2662b8bd43a05ff62157093c1539c1288a18/cryptography-46.0.6-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:3dfa6567f2e9e4c5dceb8ccb5a708158a2a871052fa75c8b78cb0977063f1507", size = 4277618 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/dd/52/a005f8eabdb28df57c20f84c44d397a755782d6ff6d455f05baa2785bd91/cryptography-46.0.6-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:cdcd3edcbc5d55757e5f5f3d330dd00007ae463a7e7aa5bf132d1f22a4b62b19", size = 4890802 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ec/4d/8e7d7245c79c617d08724e2efa397737715ca0ec830ecb3c91e547302555/cryptography-46.0.6-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:d4e4aadb7fc1f88687f47ca20bb7227981b03afaae69287029da08096853b738", size = 4457425 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1d/5c/f6c3596a1430cec6f949085f0e1a970638d76f81c3ea56d93d564d04c340/cryptography-46.0.6-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2b417edbe8877cda9022dde3a008e2deb50be9c407eef034aeeb3a8b11d9db3c", size = 4405530 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7e/c9/9f9cea13ee2dbde070424e0c4f621c091a91ffcc504ffea5e74f0e1daeff/cryptography-46.0.6-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:380343e0653b1c9d7e1f55b52aaa2dbb2fdf2730088d48c43ca1c7c0abb7cc2f", size = 4667896 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ad/b5/1895bc0821226f129bc74d00eccfc6a5969e2028f8617c09790bf89c185e/cryptography-46.0.6-cp311-abi3-win32.whl", hash = "sha256:bcb87663e1f7b075e48c3be3ecb5f0b46c8fc50b50a97cf264e7f60242dca3f2", size = 3026348 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c3/f8/c9bcbf0d3e6ad288b9d9aa0b1dee04b063d19e8c4f871855a03ab3a297ab/cryptography-46.0.6-cp311-abi3-win_amd64.whl", hash = "sha256:6739d56300662c468fddb0e5e291f9b4d084bead381667b9e654c7dd81705124", size = 3483896 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/01/41/3a578f7fd5c70611c0aacba52cd13cb364a5dee895a5c1d467208a9380b0/cryptography-46.0.6-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:2ef9e69886cbb137c2aef9772c2e7138dc581fad4fcbcf13cc181eb5a3ab6275", size = 7117147 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/fa/87/887f35a6fca9dde90cad08e0de0c89263a8e59b2d2ff904fd9fcd8025b6f/cryptography-46.0.6-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7f417f034f91dcec1cb6c5c35b07cdbb2ef262557f701b4ecd803ee8cefed4f4", size = 4266221 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/aa/a8/0a90c4f0b0871e0e3d1ed126aed101328a8a57fd9fd17f00fb67e82a51ca/cryptography-46.0.6-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d24c13369e856b94892a89ddf70b332e0b70ad4a5c43cf3e9cb71d6d7ffa1f7b", size = 4408952 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/16/0b/b239701eb946523e4e9f329336e4ff32b1247e109cbab32d1a7b61da8ed7/cryptography-46.0.6-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:aad75154a7ac9039936d50cf431719a2f8d4ed3d3c277ac03f3339ded1a5e707", size = 4270141 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0f/a8/976acdd4f0f30df7b25605f4b9d3d89295351665c2091d18224f7ad5cdbf/cryptography-46.0.6-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:3c21d92ed15e9cfc6eb64c1f5a0326db22ca9c2566ca46d845119b45b4400361", size = 4904178 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b1/1b/bf0e01a88efd0e59679b69f42d4afd5bced8700bb5e80617b2d63a3741af/cryptography-46.0.6-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:4668298aef7cddeaf5c6ecc244c2302a2b8e40f384255505c22875eebb47888b", size = 4441812 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bb/8b/11df86de2ea389c65aa1806f331cae145f2ed18011f30234cc10ca253de8/cryptography-46.0.6-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:8ce35b77aaf02f3b59c90b2c8a05c73bac12cea5b4e8f3fbece1f5fddea5f0ca", size = 3963923 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/91/e0/207fb177c3a9ef6a8108f234208c3e9e76a6aa8cf20d51932916bd43bda0/cryptography-46.0.6-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:c89eb37fae9216985d8734c1afd172ba4927f5a05cfd9bf0e4863c6d5465b013", size = 4269695 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/21/5e/19f3260ed1e95bced52ace7501fabcd266df67077eeb382b79c81729d2d3/cryptography-46.0.6-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:ed418c37d095aeddf5336898a132fba01091f0ac5844e3e8018506f014b6d2c4", size = 4869785 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/10/38/cd7864d79aa1d92ef6f1a584281433419b955ad5a5ba8d1eb6c872165bcb/cryptography-46.0.6-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:69cf0056d6947edc6e6760e5f17afe4bea06b56a9ac8a06de9d2bd6b532d4f3a", size = 4441404 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/09/0a/4fe7a8d25fed74419f91835cf5829ade6408fd1963c9eae9c4bce390ecbb/cryptography-46.0.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e7304c4f4e9490e11efe56af6713983460ee0780f16c63f219984dab3af9d2d", size = 4397549 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/5f/a0/7d738944eac6513cd60a8da98b65951f4a3b279b93479a7e8926d9cd730b/cryptography-46.0.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b928a3ca837c77a10e81a814a693f2295200adb3352395fad024559b7be7a736", size = 4651874 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/cb/f1/c2326781ca05208845efca38bf714f76939ae446cd492d7613808badedf1/cryptography-46.0.6-cp314-cp314t-win32.whl", hash = "sha256:97c8115b27e19e592a05c45d0dd89c57f81f841cc9880e353e0d3bf25b2139ed", size = 3001511 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c9/57/fe4a23eb549ac9d903bd4698ffda13383808ef0876cc912bcb2838799ece/cryptography-46.0.6-cp314-cp314t-win_amd64.whl", hash = "sha256:c797e2517cb7880f8297e2c0f43bb910e91381339336f75d2c1c2cbf811b70b4", size = 3471692 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c4/cc/f330e982852403da79008552de9906804568ae9230da8432f7496ce02b71/cryptography-46.0.6-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:12cae594e9473bca1a7aceb90536060643128bb274fcea0fc459ab90f7d1ae7a", size = 7162776 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/49/b3/dc27efd8dcc4bff583b3f01d4a3943cd8b5821777a58b3a6a5f054d61b79/cryptography-46.0.6-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:639301950939d844a9e1c4464d7e07f902fe9a7f6b215bb0d4f28584729935d8", size = 4270529 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e6/05/e8d0e6eb4f0d83365b3cb0e00eb3c484f7348db0266652ccd84632a3d58d/cryptography-46.0.6-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ed3775295fb91f70b4027aeba878d79b3e55c0b3e97eaa4de71f8f23a9f2eb77", size = 4414827 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2f/97/daba0f5d2dc6d855e2dcb70733c812558a7977a55dd4a6722756628c44d1/cryptography-46.0.6-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:8927ccfbe967c7df312ade694f987e7e9e22b2425976ddbf28271d7e58845290", size = 4271265 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/89/06/fe1fce39a37ac452e58d04b43b0855261dac320a2ebf8f5260dd55b201a9/cryptography-46.0.6-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:b12c6b1e1651e42ab5de8b1e00dc3b6354fdfd778e7fa60541ddacc27cd21410", size = 4916800 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ff/8a/b14f3101fe9c3592603339eb5d94046c3ce5f7fc76d6512a2d40efd9724e/cryptography-46.0.6-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:063b67749f338ca9c5a0b7fe438a52c25f9526b851e24e6c9310e7195aad3b4d", size = 4448771 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/01/b3/0796998056a66d1973fd52ee89dc1bb3b6581960a91ad4ac705f182d398f/cryptography-46.0.6-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:02fad249cb0e090b574e30b276a3da6a149e04ee2f049725b1f69e7b8351ec70", size = 3978333 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c5/3d/db200af5a4ffd08918cd55c08399dc6c9c50b0bc72c00a3246e099d3a849/cryptography-46.0.6-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:7e6142674f2a9291463e5e150090b95a8519b2fb6e6aaec8917dd8d094ce750d", size = 4271069 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d7/18/61acfd5b414309d74ee838be321c636fe71815436f53c9f0334bf19064fa/cryptography-46.0.6-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:456b3215172aeefb9284550b162801d62f5f264a081049a3e94307fe20792cfa", size = 4878358 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8b/65/5bf43286d566f8171917cae23ac6add941654ccf085d739195a4eacf1674/cryptography-46.0.6-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:341359d6c9e68834e204ceaf25936dffeafea3829ab80e9503860dcc4f4dac58", size = 4448061 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e0/25/7e49c0fa7205cf3597e525d156a6bce5b5c9de1fd7e8cb01120e459f205a/cryptography-46.0.6-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9a9c42a2723999a710445bc0d974e345c32adfd8d2fac6d8a251fa829ad31cfb", size = 4399103 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/44/46/466269e833f1c4718d6cd496ffe20c56c9c8d013486ff66b4f69c302a68d/cryptography-46.0.6-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6617f67b1606dfd9fe4dbfa354a9508d4a6d37afe30306fe6c101b7ce3274b72", size = 4659255 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0a/09/ddc5f630cc32287d2c953fc5d32705e63ec73e37308e5120955316f53827/cryptography-46.0.6-cp38-abi3-win32.whl", hash = "sha256:7f6690b6c55e9c5332c0b59b9c8a3fb232ebf059094c17f9019a51e9827df91c", size = 3010660 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1b/82/ca4893968aeb2709aacfb57a30dec6fa2ab25b10fa9f064b8882ce33f599/cryptography-46.0.6-cp38-abi3-win_amd64.whl", hash = "sha256:79e865c642cfc5c0b3eb12af83c35c5aeff4fa5c672dc28c43721c2c9fdd2f0f", size = 3471160 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fastapi"
|
||||||
|
version = "0.135.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "annotated-doc" },
|
||||||
|
{ name = "pydantic" },
|
||||||
|
{ name = "starlette" },
|
||||||
|
{ name = "typing-extensions" },
|
||||||
|
{ name = "typing-inspection" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/c4/73/5903c4b13beae98618d64eb9870c3fac4f605523dd0312ca5c80dadbd5b9/fastapi-0.135.2.tar.gz", hash = "sha256:88a832095359755527b7f63bb4c6bc9edb8329a026189eed83d6c1afcf419d56", size = 395833 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8f/ea/18f6d0457f9efb2fc6fa594857f92810cadb03024975726db6546b3d6fcf/fastapi-0.135.2-py3-none-any.whl", hash = "sha256:0af0447d541867e8db2a6a25c23a8c4bd80e2394ac5529bd87501bbb9e240ca5", size = 117407 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "h11"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "httpcore"
|
||||||
|
version = "1.0.9"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "certifi" },
|
||||||
|
{ name = "h11" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "httptools"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/b5/46/120a669232c7bdedb9d52d4aeae7e6c7dfe151e99dc70802e2fc7a5e1993/httptools-0.7.1.tar.gz", hash = "sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9", size = 258961 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/09/8f/c77b1fcbfd262d422f12da02feb0d218fa228d52485b77b953832105bb90/httptools-0.7.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3", size = 202889 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0a/1a/22887f53602feaa066354867bc49a68fc295c2293433177ee90870a7d517/httptools-0.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca", size = 108180 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/32/6a/6aaa91937f0010d288d3d124ca2946d48d60c3a5ee7ca62afe870e3ea011/httptools-0.7.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c", size = 478596 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6d/70/023d7ce117993107be88d2cbca566a7c1323ccbaf0af7eabf2064fe356f6/httptools-0.7.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66", size = 473268 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/32/4d/9dd616c38da088e3f436e9a616e1d0cc66544b8cdac405cc4e81c8679fc7/httptools-0.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346", size = 455517 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1d/3a/a6c595c310b7df958e739aae88724e24f9246a514d909547778d776799be/httptools-0.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650", size = 458337 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/fd/82/88e8d6d2c51edc1cc391b6e044c6c435b6aebe97b1abc33db1b0b24cd582/httptools-0.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6", size = 85743 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/34/50/9d095fcbb6de2d523e027a2f304d4551855c2f46e0b82befd718b8b20056/httptools-0.7.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270", size = 203619 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/07/f0/89720dc5139ae54b03f861b5e2c55a37dba9a5da7d51e1e824a1f343627f/httptools-0.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3", size = 108714 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b3/cb/eea88506f191fb552c11787c23f9a405f4c7b0c5799bf73f2249cd4f5228/httptools-0.7.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1", size = 472909 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e0/4a/a548bdfae6369c0d078bab5769f7b66f17f1bfaa6fa28f81d6be6959066b/httptools-0.7.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b", size = 470831 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4d/31/14df99e1c43bd132eec921c2e7e11cda7852f65619bc0fc5bdc2d0cb126c/httptools-0.7.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60", size = 452631 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/22/d2/b7e131f7be8d854d48cb6d048113c30f9a46dca0c9a8b08fcb3fcd588cdc/httptools-0.7.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca", size = 452910 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/53/cf/878f3b91e4e6e011eff6d1fa9ca39f7eb17d19c9d7971b04873734112f30/httptools-0.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96", size = 88205 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "httpx"
|
||||||
|
version = "0.28.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "anyio" },
|
||||||
|
{ name = "certifi" },
|
||||||
|
{ name = "httpcore" },
|
||||||
|
{ name = "idna" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna"
|
||||||
|
version = "3.11"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pycparser"
|
||||||
|
version = "3.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pydantic"
|
||||||
|
version = "2.12.5"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "annotated-types" },
|
||||||
|
{ name = "pydantic-core" },
|
||||||
|
{ name = "typing-extensions" },
|
||||||
|
{ name = "typing-inspection" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pydantic-core"
|
||||||
|
version = "2.41.5"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "typing-extensions" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9", size = 2120403 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34", size = 1896206 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/15/df/a4c740c0943e93e6500f9eb23f4ca7ec9bf71b19e608ae5b579678c8d02f/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0", size = 1919307 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9a/e3/6324802931ae1d123528988e0e86587c2072ac2e5394b4bc2bc34b61ff6e/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33", size = 2063258 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c9/d4/2230d7151d4957dd79c3044ea26346c148c98fbf0ee6ebd41056f2d62ab5/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e", size = 2214917 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e6/9f/eaac5df17a3672fef0081b6c1bb0b82b33ee89aa5cec0d7b05f52fd4a1fa/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2", size = 2332186 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586", size = 2073164 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bf/e3/f6e262673c6140dd3305d144d032f7bd5f7497d3871c1428521f19f9efa2/pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d", size = 2179146 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/75/c7/20bd7fc05f0c6ea2056a4565c6f36f8968c0924f19b7d97bbfea55780e73/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740", size = 2137788 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3a/8d/34318ef985c45196e004bc46c6eab2eda437e744c124ef0dbe1ff2c9d06b/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e", size = 2340133 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9c/59/013626bf8c78a5a5d9350d12e7697d3d4de951a75565496abd40ccd46bee/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858", size = 2324852 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1a/d9/c248c103856f807ef70c18a4f986693a46a8ffe1602e5d361485da502d20/pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36", size = 1994679 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11", size = 2019766 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/73/7d/f2f9db34af103bea3e09735bb40b021788a5e834c81eedb541991badf8f5/pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd", size = 1981005 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "python-dateutil"
|
||||||
|
version = "2.9.0.post0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "six" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "python-dotenv"
|
||||||
|
version = "1.2.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/82/ed/0301aeeac3e5353ef3d94b6ec08bbcabd04a72018415dcb29e588514bba8/python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3", size = 50135 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a", size = 22101 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "python-multipart"
|
||||||
|
version = "0.0.22"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/94/01/979e98d542a70714b0cb2b6728ed0b7c46792b695e3eaec3e20711271ca3/python_multipart-0.0.22.tar.gz", hash = "sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58", size = 37612 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1b/d0/397f9626e711ff749a95d96b7af99b9c566a9bb5129b8e4c10fc4d100304/python_multipart-0.0.22-py3-none-any.whl", hash = "sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155", size = 24579 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pyyaml"
|
||||||
|
version = "6.0.3"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "six"
|
||||||
|
version = "1.17.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "starlette"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "anyio" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/81/69/17425771797c36cded50b7fe44e850315d039f28b15901ab44839e70b593/starlette-1.0.0.tar.gz", hash = "sha256:6a4beaf1f81bb472fd19ea9b918b50dc3a77a6f2e190a12954b25e6ed5eea149", size = 2655289 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0b/c9/584bc9651441b4ba60cc4d557d8a547b5aff901af35bda3a4ee30c819b82/starlette-1.0.0-py3-none-any.whl", hash = "sha256:d3ec55e0bb321692d275455ddfd3df75fff145d009685eb40dc91fc66b03d38b", size = 72651 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typing-extensions"
|
||||||
|
version = "4.15.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typing-inspection"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "typing-extensions" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "urllib3"
|
||||||
|
version = "2.6.3"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uvicorn"
|
||||||
|
version = "0.42.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "click" },
|
||||||
|
{ name = "h11" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/e3/ad/4a96c425be6fb67e0621e62d86c402b4a17ab2be7f7c055d9bd2f638b9e2/uvicorn-0.42.0.tar.gz", hash = "sha256:9b1f190ce15a2dd22e7758651d9b6d12df09a13d51ba5bf4fc33c383a48e1775", size = 85393 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0a/89/f8827ccff89c1586027a105e5630ff6139a64da2515e24dafe860bd9ae4d/uvicorn-0.42.0-py3-none-any.whl", hash = "sha256:96c30f5c7abe6f74ae8900a70e92b85ad6613b745d4879eb9b16ccad15645359", size = 68830 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.optional-dependencies]
|
||||||
|
standard = [
|
||||||
|
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||||
|
{ name = "httptools" },
|
||||||
|
{ name = "python-dotenv" },
|
||||||
|
{ name = "pyyaml" },
|
||||||
|
{ name = "uvloop", marker = "platform_python_implementation != 'PyPy' and sys_platform != 'cygwin' and sys_platform != 'win32'" },
|
||||||
|
{ name = "watchfiles" },
|
||||||
|
{ name = "websockets" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uvloop"
|
||||||
|
version = "0.22.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/06/f0/18d39dbd1971d6d62c4629cc7fa67f74821b0dc1f5a77af43719de7936a7/uvloop-0.22.1.tar.gz", hash = "sha256:6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f", size = 2443250 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/89/8c/182a2a593195bfd39842ea68ebc084e20c850806117213f5a299dfc513d9/uvloop-0.22.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:561577354eb94200d75aca23fbde86ee11be36b00e52a4eaf8f50fb0c86b7705", size = 1358611 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d2/14/e301ee96a6dc95224b6f1162cd3312f6d1217be3907b79173b06785f2fe7/uvloop-0.22.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cdf5192ab3e674ca26da2eada35b288d2fa49fdd0f357a19f0e7c4e7d5077c8", size = 751811 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b7/02/654426ce265ac19e2980bfd9ea6590ca96a56f10c76e63801a2df01c0486/uvloop-0.22.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2ea3d6190a2968f4a14a23019d3b16870dd2190cd69c8180f7c632d21de68d", size = 4288562 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e", size = 4366890 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d2/53/8369e5219a5855869bcee5f4d317f6da0e2c669aecf0ef7d371e3d084449/uvloop-0.22.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e", size = 4119472 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f8/ba/d69adbe699b768f6b29a5eec7b47dd610bd17a69de51b251126a801369ea/uvloop-0.22.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad", size = 4239051 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/90/cd/b62bdeaa429758aee8de8b00ac0dd26593a9de93d302bff3d21439e9791d/uvloop-0.22.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3879b88423ec7e97cd4eba2a443aa26ed4e59b45e6b76aabf13fe2f27023a142", size = 1362067 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0d/f8/a132124dfda0777e489ca86732e85e69afcd1ff7686647000050ba670689/uvloop-0.22.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4baa86acedf1d62115c1dc6ad1e17134476688f08c6efd8a2ab076e815665c74", size = 752423 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a3/94/94af78c156f88da4b3a733773ad5ba0b164393e357cc4bd0ab2e2677a7d6/uvloop-0.22.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:297c27d8003520596236bdb2335e6b3f649480bd09e00d1e3a99144b691d2a35", size = 4272437 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b5/35/60249e9fd07b32c665192cec7af29e06c7cd96fa1d08b84f012a56a0b38e/uvloop-0.22.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1955d5a1dd43198244d47664a5858082a3239766a839b2102a269aaff7a4e25", size = 4292101 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/02/62/67d382dfcb25d0a98ce73c11ed1a6fba5037a1a1d533dcbb7cab033a2636/uvloop-0.22.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b31dc2fccbd42adc73bc4e7cdbae4fc5086cf378979e53ca5d0301838c5682c6", size = 4114158 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f0/7a/f1171b4a882a5d13c8b7576f348acfe6074d72eaf52cccef752f748d4a9f/uvloop-0.22.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:93f617675b2d03af4e72a5333ef89450dfaa5321303ede6e67ba9c9d26878079", size = 4177360 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/79/7b/b01414f31546caf0919da80ad57cbfe24c56b151d12af68cee1b04922ca8/uvloop-0.22.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:37554f70528f60cad66945b885eb01f1bb514f132d92b6eeed1c90fd54ed6289", size = 1454790 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d4/31/0bb232318dd838cad3fa8fb0c68c8b40e1145b32025581975e18b11fab40/uvloop-0.22.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b76324e2dc033a0b2f435f33eb88ff9913c156ef78e153fb210e03c13da746b3", size = 796783 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/42/38/c9b09f3271a7a723a5de69f8e237ab8e7803183131bc57c890db0b6bb872/uvloop-0.22.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:badb4d8e58ee08dad957002027830d5c3b06aea446a6a3744483c2b3b745345c", size = 4647548 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c1/37/945b4ca0ac27e3dc4952642d4c900edd030b3da6c9634875af6e13ae80e5/uvloop-0.22.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b91328c72635f6f9e0282e4a57da7470c7350ab1c9f48546c0f2866205349d21", size = 4467065 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/97/cc/48d232f33d60e2e2e0b42f4e73455b146b76ebe216487e862700457fbf3c/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:daf620c2995d193449393d6c62131b3fbd40a63bf7b307a1527856ace637fe88", size = 4328384 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e4/16/c1fd27e9549f3c4baf1dc9c20c456cd2f822dbf8de9f463824b0c0357e06/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6cde23eeda1a25c75b2e07d39970f3374105d5eafbaab2a4482be82f272d5a5e", size = 4296730 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "volcengine-python-sdk"
|
||||||
|
version = "5.0.21"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "certifi" },
|
||||||
|
{ name = "python-dateutil" },
|
||||||
|
{ name = "six" },
|
||||||
|
{ name = "urllib3" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/0a/5e/1d1c1ffc27cd552df55bd75e43b5160d5a5224c2459f8cafe04982921340/volcengine_python_sdk-5.0.21.tar.gz", hash = "sha256:324eded08082fcc65c55c304aca62f5bf1bc5dc472d8ed0bb9b50bdffb768a9b", size = 8283723 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/41/0e/4fdb25614ba83c42135b5eeb5d182ac22493bd7c221dd3477090c3c15897/volcengine_python_sdk-5.0.21-py2.py3-none-any.whl", hash = "sha256:a478bdf3036d8b2e42c19b04c9b708018316a4daac8d8cd58b882074e9d03546", size = 32571307 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.optional-dependencies]
|
||||||
|
ark = [
|
||||||
|
{ name = "anyio" },
|
||||||
|
{ name = "cryptography" },
|
||||||
|
{ name = "httpx" },
|
||||||
|
{ name = "pydantic" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "watchfiles"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "anyio" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/c2/c9/8869df9b2a2d6c59d79220a4db37679e74f807c559ffe5265e08b227a210/watchfiles-1.1.1.tar.gz", hash = "sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2", size = 94440 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bb/f4/f750b29225fe77139f7ae5de89d4949f5a99f934c65a1f1c0b248f26f747/watchfiles-1.1.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18", size = 404321 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2b/f9/f07a295cde762644aa4c4bb0f88921d2d141af45e735b965fb2e87858328/watchfiles-1.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a", size = 391783 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bc/11/fc2502457e0bea39a5c958d86d2cb69e407a4d00b85735ca724bfa6e0d1a/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219", size = 449279 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e3/1f/d66bc15ea0b728df3ed96a539c777acfcad0eb78555ad9efcaa1274688f0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428", size = 459405 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/be/90/9f4a65c0aec3ccf032703e6db02d89a157462fbb2cf20dd415128251cac0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0", size = 488976 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/37/57/ee347af605d867f712be7029bb94c8c071732a4b44792e3176fa3c612d39/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150", size = 595506 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a8/78/cc5ab0b86c122047f75e8fc471c67a04dee395daf847d3e59381996c8707/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae", size = 474936 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/62/da/def65b170a3815af7bd40a3e7010bf6ab53089ef1b75d05dd5385b87cf08/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d", size = 456147 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/57/99/da6573ba71166e82d288d4df0839128004c67d2778d3b566c138695f5c0b/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b", size = 630007 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a8/51/7439c4dd39511368849eb1e53279cd3454b4a4dbace80bab88feeb83c6b5/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374", size = 622280 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/95/9c/8ed97d4bba5db6fdcdb2b298d3898f2dd5c20f6b73aee04eabe56c59677e/watchfiles-1.1.1-cp313-cp313-win32.whl", hash = "sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0", size = 272056 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1f/f3/c14e28429f744a260d8ceae18bf58c1d5fa56b50d006a7a9f80e1882cb0d/watchfiles-1.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42", size = 288162 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/dc/61/fe0e56c40d5cd29523e398d31153218718c5786b5e636d9ae8ae79453d27/watchfiles-1.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18", size = 277909 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/79/42/e0a7d749626f1e28c7108a99fb9bf524b501bbbeb9b261ceecde644d5a07/watchfiles-1.1.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da", size = 403389 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/15/49/08732f90ce0fbbc13913f9f215c689cfc9ced345fb1bcd8829a50007cc8d/watchfiles-1.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051", size = 389964 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/27/0d/7c315d4bd5f2538910491a0393c56bf70d333d51bc5b34bee8e68e8cea19/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e", size = 448114 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c3/24/9e096de47a4d11bc4df41e9d1e61776393eac4cb6eb11b3e23315b78b2cc/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70", size = 460264 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/cc/0f/e8dea6375f1d3ba5fcb0b3583e2b493e77379834c74fd5a22d66d85d6540/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261", size = 487877 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ac/5b/df24cfc6424a12deb41503b64d42fbea6b8cb357ec62ca84a5a3476f654a/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620", size = 595176 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8f/b5/853b6757f7347de4e9b37e8cc3289283fb983cba1ab4d2d7144694871d9c/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04", size = 473577 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e1/f7/0a4467be0a56e80447c8529c9fce5b38eab4f513cb3d9bf82e7392a5696b/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77", size = 455425 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8e/e0/82583485ea00137ddf69bc84a2db88bd92ab4a6e3c405e5fb878ead8d0e7/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef", size = 628826 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/28/9a/a785356fccf9fae84c0cc90570f11702ae9571036fb25932f1242c82191c/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf", size = 622208 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c3/f4/0872229324ef69b2c3edec35e84bd57a1289e7d3fe74588048ed8947a323/watchfiles-1.1.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5", size = 404315 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7b/22/16d5331eaed1cb107b873f6ae1b69e9ced582fcf0c59a50cd84f403b1c32/watchfiles-1.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd", size = 390869 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b2/7e/5643bfff5acb6539b18483128fdc0ef2cccc94a5b8fbda130c823e8ed636/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb", size = 449919 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/51/2e/c410993ba5025a9f9357c376f48976ef0e1b1aefb73b97a5ae01a5972755/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5", size = 460845 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8e/a4/2df3b404469122e8680f0fcd06079317e48db58a2da2950fb45020947734/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3", size = 489027 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ea/84/4587ba5b1f267167ee715b7f66e6382cca6938e0a4b870adad93e44747e6/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33", size = 595615 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6a/0f/c6988c91d06e93cd0bb3d4a808bcf32375ca1904609835c3031799e3ecae/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510", size = 474836 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b4/36/ded8aebea91919485b7bbabbd14f5f359326cb5ec218cd67074d1e426d74/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05", size = 455099 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/98/e0/8c9bdba88af756a2fce230dd365fab2baf927ba42cd47521ee7498fd5211/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6", size = 630626 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2a/84/a95db05354bf2d19e438520d92a8ca475e578c647f78f53197f5a2f17aaf/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81", size = 622519 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1d/ce/d8acdc8de545de995c339be67711e474c77d643555a9bb74a9334252bd55/watchfiles-1.1.1-cp314-cp314-win32.whl", hash = "sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b", size = 272078 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c4/c9/a74487f72d0451524be827e8edec251da0cc1fcf111646a511ae752e1a3d/watchfiles-1.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a", size = 287664 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/df/b8/8ac000702cdd496cdce998c6f4ee0ca1f15977bba51bdf07d872ebdfc34c/watchfiles-1.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02", size = 277154 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/47/a8/e3af2184707c29f0f14b1963c0aace6529f9d1b8582d5b99f31bbf42f59e/watchfiles-1.1.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21", size = 403820 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c0/ec/e47e307c2f4bd75f9f9e8afbe3876679b18e1bcec449beca132a1c5ffb2d/watchfiles-1.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5", size = 390510 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d5/a0/ad235642118090f66e7b2f18fd5c42082418404a79205cdfca50b6309c13/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7", size = 448408 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/df/85/97fa10fd5ff3332ae17e7e40e20784e419e28521549780869f1413742e9d/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101", size = 458968 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/47/c2/9059c2e8966ea5ce678166617a7f75ecba6164375f3b288e50a40dc6d489/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44", size = 488096 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/94/44/d90a9ec8ac309bc26db808a13e7bfc0e4e78b6fc051078a554e132e80160/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c", size = 596040 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/95/68/4e3479b20ca305cfc561db3ed207a8a1c745ee32bf24f2026a129d0ddb6e/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc", size = 473847 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4f/55/2af26693fd15165c4ff7857e38330e1b61ab8c37d15dc79118cdba115b7a/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c", size = 455072 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/66/1d/d0d200b10c9311ec25d2273f8aad8c3ef7cc7ea11808022501811208a750/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099", size = 629104 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e3/bd/fa9bb053192491b3867ba07d2343d9f2252e00811567d30ae8d0f78136fe/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01", size = 622112 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "websockets"
|
||||||
|
version = "16.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/04/24/4b2031d72e840ce4c1ccb255f693b15c334757fc50023e4db9537080b8c4/websockets-16.0.tar.gz", hash = "sha256:5f6261a5e56e8d5c42a4497b364ea24d94d9563e8fbd44e78ac40879c60179b5", size = 179346 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/cc/9c/baa8456050d1c1b08dd0ec7346026668cbc6f145ab4e314d707bb845bf0d/websockets-16.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:878b336ac47938b474c8f982ac2f7266a540adc3fa4ad74ae96fea9823a02cc9", size = 177364 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7e/0c/8811fc53e9bcff68fe7de2bcbe75116a8d959ac699a3200f4847a8925210/websockets-16.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:52a0fec0e6c8d9a784c2c78276a48a2bdf099e4ccc2a4cad53b27718dbfd0230", size = 175039 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/aa/82/39a5f910cb99ec0b59e482971238c845af9220d3ab9fa76dd9162cda9d62/websockets-16.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e6578ed5b6981005df1860a56e3617f14a6c307e6a71b4fff8c48fdc50f3ed2c", size = 175323 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bd/28/0a25ee5342eb5d5f297d992a77e56892ecb65e7854c7898fb7d35e9b33bd/websockets-16.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:95724e638f0f9c350bb1c2b0a7ad0e83d9cc0c9259f3ea94e40d7b02a2179ae5", size = 184975 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f9/66/27ea52741752f5107c2e41fda05e8395a682a1e11c4e592a809a90c6a506/websockets-16.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0204dc62a89dc9d50d682412c10b3542d748260d743500a85c13cd1ee4bde82", size = 186203 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/37/e5/8e32857371406a757816a2b471939d51c463509be73fa538216ea52b792a/websockets-16.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:52ac480f44d32970d66763115edea932f1c5b1312de36df06d6b219f6741eed8", size = 185653 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9b/67/f926bac29882894669368dc73f4da900fcdf47955d0a0185d60103df5737/websockets-16.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6e5a82b677f8f6f59e8dfc34ec06ca6b5b48bc4fcda346acd093694cc2c24d8f", size = 184920 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3c/a1/3d6ccdcd125b0a42a311bcd15a7f705d688f73b2a22d8cf1c0875d35d34a/websockets-16.0-cp313-cp313-win32.whl", hash = "sha256:abf050a199613f64c886ea10f38b47770a65154dc37181bfaff70c160f45315a", size = 178255 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6b/ae/90366304d7c2ce80f9b826096a9e9048b4bb760e44d3b873bb272cba696b/websockets-16.0-cp313-cp313-win_amd64.whl", hash = "sha256:3425ac5cf448801335d6fdc7ae1eb22072055417a96cc6b31b3861f455fbc156", size = 178689 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f3/1d/e88022630271f5bd349ed82417136281931e558d628dd52c4d8621b4a0b2/websockets-16.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8cc451a50f2aee53042ac52d2d053d08bf89bcb31ae799cb4487587661c038a0", size = 177406 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f2/78/e63be1bf0724eeb4616efb1ae1c9044f7c3953b7957799abb5915bffd38e/websockets-16.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:daa3b6ff70a9241cf6c7fc9e949d41232d9d7d26fd3522b1ad2b4d62487e9904", size = 175085 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bb/f4/d3c9220d818ee955ae390cf319a7c7a467beceb24f05ee7aaaa2414345ba/websockets-16.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4", size = 175328 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/63/bc/d3e208028de777087e6fb2b122051a6ff7bbcca0d6df9d9c2bf1dd869ae9/websockets-16.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:781caf5e8eee67f663126490c2f96f40906594cb86b408a703630f95550a8c3e", size = 185044 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ad/6e/9a0927ac24bd33a0a9af834d89e0abc7cfd8e13bed17a86407a66773cc0e/websockets-16.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:caab51a72c51973ca21fa8a18bd8165e1a0183f1ac7066a182ff27107b71e1a4", size = 186279 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b9/ca/bf1c68440d7a868180e11be653c85959502efd3a709323230314fda6e0b3/websockets-16.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:19c4dc84098e523fd63711e563077d39e90ec6702aff4b5d9e344a60cb3c0cb1", size = 185711 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c4/f8/fdc34643a989561f217bb477cbc47a3a07212cbda91c0e4389c43c296ebf/websockets-16.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a5e18a238a2b2249c9a9235466b90e96ae4795672598a58772dd806edc7ac6d3", size = 184982 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/dd/d1/574fa27e233764dbac9c52730d63fcf2823b16f0856b3329fc6268d6ae4f/websockets-16.0-cp314-cp314-win32.whl", hash = "sha256:a069d734c4a043182729edd3e9f247c3b2a4035415a9172fd0f1b71658a320a8", size = 177915 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8a/f1/ae6b937bf3126b5134ce1f482365fde31a357c784ac51852978768b5eff4/websockets-16.0-cp314-cp314-win_amd64.whl", hash = "sha256:c0ee0e63f23914732c6d7e0cce24915c48f3f1512ec1d079ed01fc629dab269d", size = 178381 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/06/9b/f791d1db48403e1f0a27577a6beb37afae94254a8c6f08be4a23e4930bc0/websockets-16.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:a35539cacc3febb22b8f4d4a99cc79b104226a756aa7400adc722e83b0d03244", size = 177737 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bd/40/53ad02341fa33b3ce489023f635367a4ac98b73570102ad2cdd770dacc9a/websockets-16.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:b784ca5de850f4ce93ec85d3269d24d4c82f22b7212023c974c401d4980ebc5e", size = 175268 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/74/9b/6158d4e459b984f949dcbbb0c5d270154c7618e11c01029b9bbd1bb4c4f9/websockets-16.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:569d01a4e7fba956c5ae4fc988f0d4e187900f5497ce46339c996dbf24f17641", size = 175486 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e5/2d/7583b30208b639c8090206f95073646c2c9ffd66f44df967981a64f849ad/websockets-16.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:50f23cdd8343b984957e4077839841146f67a3d31ab0d00e6b824e74c5b2f6e8", size = 185331 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/45/b0/cce3784eb519b7b5ad680d14b9673a31ab8dcb7aad8b64d81709d2430aa8/websockets-16.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:152284a83a00c59b759697b7f9e9cddf4e3c7861dd0d964b472b70f78f89e80e", size = 186501 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/19/60/b8ebe4c7e89fb5f6cdf080623c9d92789a53636950f7abacfc33fe2b3135/websockets-16.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bc59589ab64b0022385f429b94697348a6a234e8ce22544e3681b2e9331b5944", size = 186062 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/88/a8/a080593f89b0138b6cba1b28f8df5673b5506f72879322288b031337c0b8/websockets-16.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:32da954ffa2814258030e5a57bc73a3635463238e797c7375dc8091327434206", size = 185356 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c2/b6/b9afed2afadddaf5ebb2afa801abf4b0868f42f8539bfe4b071b5266c9fe/websockets-16.0-cp314-cp314t-win32.whl", hash = "sha256:5a4b4cc550cb665dd8a47f868c8d04c8230f857363ad3c9caf7a0c3bf8c61ca6", size = 178085 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9f/3e/28135a24e384493fa804216b79a6a6759a38cc4ff59118787b9fb693df93/websockets-16.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b14dc141ed6d2dde437cddb216004bcac6a1df0935d79656387bd41632ba0bbd", size = 178531 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6f/28/258ebab549c2bf3e64d2b0217b973467394a9cea8c42f70418ca2c5d0d2e/websockets-16.0-py3-none-any.whl", hash = "sha256:1637db62fad1dc833276dded54215f2c7fa46912301a24bd94d45d46a011ceec", size = 171598 },
|
||||||
|
]
|
||||||
20491
frontend/package-lock.json
generated
Normal file
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 841 B After Width: | Height: | Size: 841 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 965 B After Width: | Height: | Size: 965 B |
|
Before Width: | Height: | Size: 440 B After Width: | Height: | Size: 440 B |
|
Before Width: | Height: | Size: 758 B After Width: | Height: | Size: 758 B |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 332 KiB After Width: | Height: | Size: 332 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
26
frontend/src/components/AIAvatarLoading/index.module.less
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatarContainer {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatarSvg {
|
||||||
|
max-width: 80%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 加载文字样式 */
|
||||||
|
.loadingText {
|
||||||
|
margin-top: 30px;
|
||||||
|
font-size: 18px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
76
frontend/src/components/AIAvatarLoading/index.tsx
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved.
|
||||||
|
* SPDX-license-identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
import styles from './index.module.less';
|
||||||
|
|
||||||
|
function AIAvatarReadying() {
|
||||||
|
return (
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.avatarContainer}>
|
||||||
|
{/* SVG 包含人型轮廓和流光效果 */}
|
||||||
|
<svg
|
||||||
|
className={styles.avatarSvg}
|
||||||
|
width="35vh"
|
||||||
|
height="42vh"
|
||||||
|
viewBox="0 0 457 549"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
{/* 原始人型轮廓 */}
|
||||||
|
<path
|
||||||
|
d="M175.137 244.821C175.12 240.915 174.986 232.095 174.729 228.127L174.727 228.106L174.726 228.087L174.668 227.474C174.045 221.385 171.924 216.347 168.181 212.481L167.801 212.098C164.091 208.429 159.982 204.706 155.477 200.929C153.336 198.887 151.625 196.437 150.444 193.724L150.433 193.697L150.42 193.671L149.841 192.422C148.509 189.52 147.278 186.572 146.149 183.585C144.846 179.572 143.541 175.295 142.214 170.751L141.912 169.719L140.886 169.401L140.555 169.295C138.934 168.753 137.41 167.955 136.041 166.931C134.262 165.342 132.653 163.572 131.238 161.651C129.191 158.679 127.692 155.364 126.813 151.863L126.785 151.752L126.745 151.645L126.492 150.944C125.279 147.431 124.799 143.704 125.085 139.994C125.478 136.364 126.156 133.326 127.121 130.858L127.127 130.842L127.133 130.826C128.206 127.935 129.823 125.278 131.897 122.997L132.438 122.403L132.418 121.6C132.157 111.445 132.679 101.284 133.98 91.2086C135.184 81.8895 137.078 72.6727 139.647 63.6344L139.651 63.6207L139.654 63.608C142.166 54.2848 146.286 45.4712 151.827 37.5641L151.84 37.5446L151.854 37.525C156.768 30.1535 162.226 24.1949 168.194 19.6344C174.287 15.0104 180.474 11.3978 186.775 8.77893L186.779 8.77698C192.676 6.31057 198.595 4.59753 204.487 3.63049L205.665 3.4469C212.051 2.52917 218.207 2.07191 224.173 2.0719H226.075C232.924 2.20416 239.709 3.04996 246.463 4.62952L246.472 4.63147C253.613 6.26715 260.58 8.59178 267.272 11.5719V11.5709C273.733 14.4735 279.477 17.7844 284.513 21.4576C289.542 25.1405 293.399 28.7986 296.171 32.3785L296.179 32.3893L296.188 32.4C302.893 40.8262 307.772 50.094 310.875 60.2135L310.878 60.2203C313.858 69.819 316.08 79.6371 317.523 89.5836C318.827 100.26 319.489 111.077 319.489 122.036V123.048L320.306 123.648C321.902 124.82 323.183 126.369 324.034 128.157L324.062 128.216L324.095 128.273C325.021 129.93 325.815 132.135 326.456 134.989V134.99C327.041 137.657 327.136 141.06 326.627 145.227L326.624 145.255L326.621 145.285C326.108 150.808 325.015 155.025 323.453 158.076L323.449 158.082L323.446 158.089C321.83 161.302 320.045 163.696 318.165 165.395L318.148 165.41L318.133 165.425C316.207 167.244 313.9 168.612 311.381 169.429L310.377 169.755L310.079 170.768C308.749 175.302 307.465 179.574 306.145 183.578C304.848 187.009 303.364 190.366 301.697 193.633L301.694 193.639C300.082 196.825 298.307 199.225 296.446 200.897C292.063 204.433 288.379 207.515 285.397 210.127L284.158 211.221C280.486 214.496 278.291 219.798 277.187 226.703C276.335 231 276.102 240.098 276.349 244.339L276.35 244.348V244.357C276.652 248.822 277.859 253.232 279.914 257.618L279.917 257.625L279.921 257.631C282.032 262.048 285.236 266.234 289.477 270.139C293.797 274.118 299.755 277.607 307.276 280.617V280.618C313.953 283.342 321.212 285.795 329.068 287.978L329.071 287.979C331.164 288.557 334.747 289.129 338.918 289.705C343.13 290.286 348.095 290.889 353.013 291.508C357.944 292.129 362.834 292.768 366.946 293.424C371.118 294.091 374.29 294.746 375.915 295.364V295.365C377.947 296.146 381.43 296.926 385.408 297.711C389.43 298.504 394.194 299.346 398.827 300.216C403.491 301.092 408.052 302.002 411.788 302.947C413.656 303.419 415.286 303.893 416.601 304.365C417.952 304.85 418.829 305.283 419.296 305.629L419.3 305.631C424.589 309.523 428.393 314.851 430.644 321.74C445.731 382.021 453.785 439.764 454.411 481.881C454.725 502.978 453.172 520 449.79 531.429C448.096 537.155 445.996 541.291 443.602 543.85C441.281 546.33 438.717 547.314 435.77 546.913L435.755 546.911L435.741 546.91L433.611 546.654C388.296 541.315 305.942 536.993 226.451 532.245C145.556 527.413 67.7489 522.144 34.3936 514.951H34.3926C31.4052 514.293 29.0212 513.642 27.2168 513.005C25.3611 512.349 24.3001 511.77 23.8018 511.342L23.7822 511.325L23.7617 511.309L23.4365 511.037C20.0453 508.119 15.7049 502.035 11.8477 492.491C7.88642 482.689 4.49264 469.376 3.15625 452.444C0.490903 418.673 6.01322 370.536 31.4814 307.264C34.9856 304.532 39.8152 302.214 45.5293 300.212C51.4403 298.14 58.1707 296.444 65.1162 294.954C72.0624 293.463 79.164 292.19 85.8398 290.95C92.4891 289.714 98.7347 288.507 103.871 287.155C108.374 285.97 118.591 284.526 128.896 282.753C133.986 281.877 139.052 280.926 143.308 279.9C147.458 278.899 151.135 277.76 153.242 276.407L153.243 276.408C158.848 272.856 163.246 269.382 166.311 265.953C169.34 262.586 171.586 259.177 173.007 255.68C174.418 252.207 175.137 248.593 175.137 244.83V244.821Z"
|
||||||
|
stroke="url(#paint0_linear)"
|
||||||
|
strokeWidth="4"
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* 渐变定义 */}
|
||||||
|
<defs>
|
||||||
|
{/* 原始渐变 */}
|
||||||
|
<linearGradient
|
||||||
|
id="paint0_linear"
|
||||||
|
x1="142.5"
|
||||||
|
y1="83.5"
|
||||||
|
x2="299.5"
|
||||||
|
y2="401.5"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
>
|
||||||
|
<stop stopColor="#6792FF" />
|
||||||
|
<stop offset="0.138788" stopColor="#D093FF" />
|
||||||
|
<stop offset="0.282833" stopColor="#9DFFE3" stopOpacity="0.318618" />
|
||||||
|
<stop offset="0.519953" stopColor="white" stopOpacity="0" />
|
||||||
|
<stop offset="1" stopColor="white" stopOpacity="0" />
|
||||||
|
|
||||||
|
{/* 添加动画效果,使渐变沿着路径运动 */}
|
||||||
|
<animate attributeName="x1" values="0; 457; 0" dur="4s" repeatCount="indefinite" />
|
||||||
|
<animate
|
||||||
|
attributeName="y1"
|
||||||
|
values="549; 157; 549"
|
||||||
|
dur="4s"
|
||||||
|
repeatCount="indefinite"
|
||||||
|
/>
|
||||||
|
<animate
|
||||||
|
attributeName="x2"
|
||||||
|
values="157; 614; 614"
|
||||||
|
dur="4s"
|
||||||
|
repeatCount="indefinite"
|
||||||
|
/>
|
||||||
|
<animate
|
||||||
|
attributeName="y2"
|
||||||
|
values="157; 706; 157"
|
||||||
|
dur="4s"
|
||||||
|
repeatCount="indefinite"
|
||||||
|
/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
{/* 加载文字 */}
|
||||||
|
<div className={styles.loadingText}>数字人准备中,请稍候...</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AIAvatarReadying;
|
||||||
@ -10,7 +10,6 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-align: center;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -23,4 +22,16 @@
|
|||||||
left: 16px;
|
left: 16px;
|
||||||
top: 16px;
|
top: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.blur-bg {
|
||||||
|
background-position: center;
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
filter: blur(20px);
|
||||||
|
transform: scale(1.1);
|
||||||
}
|
}
|
||||||
39
frontend/src/components/FullScreenCard/index.tsx
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved.
|
||||||
|
* SPDX-license-identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
|
import UserTag from '../UserTag';
|
||||||
|
import { RootState } from '@/store';
|
||||||
|
import style from './index.module.less';
|
||||||
|
import { useScene } from '@/lib/useCommon';
|
||||||
|
import { isMobile } from '@/utils/utils';
|
||||||
|
|
||||||
|
export const LocalFullID = 'local-full-player';
|
||||||
|
export const RemoteFullID = 'remote-full-player';
|
||||||
|
|
||||||
|
function FullScreenCard() {
|
||||||
|
const isFullScreen = useSelector((state: RootState) => state.room.isFullScreen);
|
||||||
|
const scene = useScene();
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className={`${style.card} ${!isFullScreen ? style.hidden : ''}`} id={LocalFullID}>
|
||||||
|
<UserTag name="我" className={style.tag} />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={`${style.card} ${isFullScreen ? style.hidden : ''} ${style['blur-bg']}`}
|
||||||
|
style={{ backgroundImage: `url(${scene.avatarBgUrl})` }}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className={`${style.card} ${isFullScreen ? style.hidden : ''}`}
|
||||||
|
style={{ background: 'unset' }}
|
||||||
|
>
|
||||||
|
<div id={RemoteFullID} style={{ width: '60%', height: '100%' }} />
|
||||||
|
{!isMobile() ? <UserTag name="AI" className={style.tag} /> : null}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FullScreenCard;
|
||||||