feat: 后端代理层(Jev 透传 + ASR 预留端点),前端支持代理模式
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
# 后端代理层(server/)
|
||||
|
||||
为浏览器/Tauri 前端代理 TypeSafe AI(Jev)与 ASR 请求。key 只存在于服务端,
|
||||
前端不需要 `VITE_TYPESAFE_API_KEY`,也解决了浏览器直连 `api.typesafe.ai` 的 CORS 问题。
|
||||
|
||||
独立子包:自己的 `package.json` 与 lockfile,与根仓库前端互不干扰。Node ≥ 22。
|
||||
|
||||
## 怎么跑
|
||||
|
||||
```bash
|
||||
pnpm --dir server install
|
||||
cp server/.env.example server/.env # 填入 TYPESAFE_API_KEY
|
||||
pnpm --dir server dev # tsx watch,默认 http://localhost:8787
|
||||
pnpm --dir server smoke # 冒烟:代理调一次真实 Jev + /api/asr 自测
|
||||
```
|
||||
|
||||
前端侧在根 `.env` 里加一行即切换到代理模式(此时前端无需 key):
|
||||
|
||||
```
|
||||
VITE_JEV_PROXY_URL=http://localhost:8787
|
||||
```
|
||||
|
||||
## 环境变量
|
||||
|
||||
| 变量 | 说明 |
|
||||
| --- | --- |
|
||||
| `TYPESAFE_API_KEY` | Jev API key,**只在服务端**,绝不下发前端、不打印日志 |
|
||||
| `PORT` | 监听端口,默认 `8787` |
|
||||
|
||||
## 路由
|
||||
|
||||
- `POST /api/jev`:请求体原样透传到 `https://api.typesafe.ai/v1/systemone`,
|
||||
上游状态码(401/422/429/529 等)与响应体原样返回。
|
||||
- `POST /api/asr`:multipart/form-data,文件字段名 `audio`,返回
|
||||
`{ transcript, prosody }`。`prosody` 暂为空数组占位,后续接声学特征提取
|
||||
(语速/停顿/音高/能量等,见 ADR-0004)。
|
||||
- `GET /healthz`:存活检查。
|
||||
|
||||
CORS 仅放行 `http://localhost:1420`(Tauri dev)与 `http://localhost:5173`(Vite dev)。
|
||||
|
||||
## 接入真实 ASR provider
|
||||
|
||||
当前 `/api/asr` 走 `MockAsrProvider`(占位转写)。换真实 provider 只需两步:
|
||||
|
||||
1. 在 `src/asr/provider.ts` 新增实现 `AsrProvider` 接口的类,输入是
|
||||
`input.data`(内存 buffer,**不要写盘**——ADR-0004"特征提取后即焚"):
|
||||
- **阿里云 NLS**:一句话识别 RESTful API,`input.data` 直接作请求体,
|
||||
appkey/token 从 `process.env` 读(加到 `server/.env`);
|
||||
- **讯飞语音听写**:WebSocket/REST 端点,同样以 `input.data` 为输入;
|
||||
- **Whisper 兼容端点**(OpenAI / Groq / 自托管 faster-whisper):
|
||||
`fetch(url, { method: 'POST', body: FormData(file=Blob(input.data)) })`,
|
||||
取返回 JSON 的 `text` 字段。
|
||||
2. 在 `src/routes/asr.ts` 把 `new MockAsrProvider()` 换成新 provider 实例。
|
||||
|
||||
韵律特征提取(ADR-0004 的 (b) 类产物)接入点同上:在 provider 内对
|
||||
`input.data` 提取统计向量填入 `prosody`,音频 buffer 在请求结束后即弃。
|
||||
Reference in New Issue
Block a user