Files
lingma-openai-gateway/README.md
GitHub Actions dfdb7087dc perf: session reuse for multi-turn latency
- Add SessionCache (LRU + TTL, per-API-key scoped) mapping
  conversation-prefix hash -> upstream Lingma sessionId.
- Hash only user/system/developer turns so client-side
  assistant reformatting doesn't invalidate the key.
- On cache hit: reuse sessionId, send only the latest user
  message with isReply=true, and stick the request to the
  instance that originally served it.
- LingmaGatewayClient.chat_complete/chat_stream accept
  session_id/is_reply and report the real finish.sessionId
  via out_meta so we persist what Lingma actually allocated.
- Invalidate cache on non-stream failure; skip writes on
  cancelled/partial streams.
- Expose cache stats in /internal/stats and /metrics.
- Configurable via SESSION_REUSE_ENABLED / SESSION_CACHE_MAX_ENTRIES
  / SESSION_CACHE_TTL_SEC (documented in README + .env.example).

Made-with: Cursor
2026-04-18 08:10:39 +08:00

236 lines
7.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Lingma OpenAI Gateway
把本地 Lingma 能力封装为 OpenAI 兼容接口,支持:
- `GET /v1/models`
- `POST /v1/chat/completions`
- `stream=true`SSE
- Bearer API Key 鉴权
## 1. 准备目录
```bash
mkdir -p data
```
说明:
- 启动时会自动获取最新插件并提取 `Lingma``data/bin`
- 默认通过 VSCode Marketplace 查询最新版本,再下载对应 VSIX。
- 登录态与运行数据统一写入 `data/.lingma`
## 2. 配置环境变量
```bash
cp .env.example .env
```
至少修改:
- `API_KEYS`
- `LINGMA_USERNAME`
- `LINGMA_PASSWORD`
如果你的 Lingma 路径不同,修改:
- `LINGMA_BIN`
可选(企业专属域):
- `DEDICATED_DOMAIN_URL`
### `.env` 字段说明(简版)
- `HOST`:网关监听地址(通常 `0.0.0.0`
- `PORT`:网关监听端口(外部调用端口)
- `API_KEYS`Bearer Key多个用逗号分隔
- `LINGMA_BIN`:容器内 Lingma 路径
- `LINGMA_SOURCE_TYPE`:二进制来源(`marketplace`/`vsix`
- `LINGMA_MARKETPLACE_PUBLISHER`Marketplace 发布者
- `LINGMA_MARKETPLACE_EXTENSION`Marketplace 扩展名
- `LINGMA_VSIX_URL`VSIX 下载地址(最新优先)
- `LINGMA_BOOTSTRAP_ALWAYS`:启动时是否总尝试刷新 Lingma
- `LINGMA_FORCE_REFRESH`:是否强制刷新(忽略本地缓存)
- `LINGMA_WORK_DIR`Lingma 工作目录(登录与会话数据)
- `LINGMA_SOCKET_PORT`Lingma 本地 WS 端口
- `LINGMA_STARTUP_TIMEOUT`Lingma 启动等待秒数
- `LINGMA_RPC_TIMEOUT`:单次 RPC 超时秒数
- `DEFAULT_MODEL`:默认模型(无法映射时兜底)
- `DEFAULT_ASK_MODE`:默认模式(`chat`/`agent`
- `DEDICATED_DOMAIN_URL`:企业专属域(可留空)
- `AUTO_LOGIN_ENABLED`:未登录时自动登录开关
- `AUTO_LOGIN_HEADLESS`:自动登录是否无头浏览器
- `AUTO_LOGIN_TIMEOUT`:自动登录超时秒数
- `AUTO_LOGIN_MAX_RETRY`:自动登录重试次数
- `LINGMA_USERNAME`Lingma 登录用户名
- `LINGMA_PASSWORD`Lingma 登录密码
- `METRICS_TOKEN``/metrics` 独立鉴权 token留空则 `API_KEYS` 也可访问;两者都留空时 `/metrics` 为公开)
- `LOG_LEVEL`:日志级别(默认 `INFO`,输出结构化 JSON包含 `request_id`
- `GATEWAY_MAX_IN_FLIGHT``/v1/chat/completions` 并发上限(默认 4`<=0` 表示不限流)
- `GATEWAY_QUEUE_TIMEOUT_SEC`:排队等待超时秒数(默认 30超过后直接 429 + `Retry-After`
- `LINGMA_ACCOUNTS`:多账号实例池,格式 `u1:p1,u2:p2` 或 JSON 数组;配置后每个账号起一个独立 Lingma 子进程
- `LINGMA_INSTANCE_COUNT`:实例数(默认等于账号数;显式指定且不足时账号会循环复用)
- `SESSION_REUSE_ENABLED`:多轮对话复用上游 sessionId默认 `true`)。命中时只把最新一条 user 消息发给 Lingma命中上游 KV cache显著降低第 2 轮及以后的首 token 延迟
- `SESSION_CACHE_MAX_ENTRIES`会话缓存容量LRU默认 256
- `SESSION_CACHE_TTL_SEC`:会话缓存 TTL 秒数(默认 1800超时自动失效避免复用到已被 Lingma 回收的 session
### `.env` 最小必填示例
```env
PORT=8317
API_KEYS=sk-your-api-key
LINGMA_USERNAME=your-username
LINGMA_PASSWORD=your-password
LINGMA_BIN=/app/data/bin/Lingma
LINGMA_WORK_DIR=/app/data/.lingma/vscode/sharedClientCache
LINGMA_SOURCE_TYPE=marketplace
LINGMA_MARKETPLACE_PUBLISHER=Alibaba-Cloud
LINGMA_MARKETPLACE_EXTENSION=tongyi-lingma
LINGMA_VSIX_URL=https://tongyi-code.oss-cn-hangzhou.aliyuncs.com/vscode/tongyi-lingma-latest.vsix
DEDICATED_DOMAIN_URL=
```
### 数据目录说明
- 本项目所有持久化数据都在 `./data`
- `data/bin/Lingma`:自动提取的 Lingma 二进制
- `data/.lingma/...`Lingma 登录态、缓存、日志(单实例模式)
- `data/.lingma/pool/inst-<i>/...`:多实例模式下每个实例独立的登录态/缓存
### 多实例池(方案乙:多账号)
启用方式:在 `.env` 里配置 `LINGMA_ACCOUNTS=u1:p1,u2:p2`,重启容器即可。
- 每个账号对应一个独立 Lingma 子进程,各自独立登录、独立 workDir。
- 路由策略:同一 `user` 字段或同一 system prompt 的请求粘性路由到同一实例;其余按 least-in-flight 分配。
- 一个实例挂了/断连不影响整体,`/healthz` 汇报 `pool_ready` 计数。
- `/internal/stats.pool` 按实例粒度暴露状态,`/metrics` 增加 `gateway_pool_instance_in_flight{name}` / `gateway_pool_instance_ready{name}`
- 未配置 `LINGMA_ACCOUNTS` 时自动退化为单实例模式(沿用 `LINGMA_USERNAME/LINGMA_PASSWORD`),向下兼容。
## 3. Docker 运行
```bash
docker compose up -d --build
```
说明:
- 构建阶段已默认使用腾讯云 PyPI 镜像(`mirrors.cloud.tencent.com`)。
- 如需自定义镜像源,可在 `docker-compose.yml``build.args` 中修改。
查看日志:
```bash
docker compose logs -f
```
## 4. 调用示例
### 模型列表
```bash
curl -s http://127.0.0.1:8317/v1/models \
-H "Authorization: Bearer sk-your-api-key"
```
说明:
- `id` 保持 Lingma 原始模型 key兼容 OpenAI 客户端)
- `name` 提供可读名称(如 `qwen3.6-plus`
- 调用 `/v1/chat/completions` 时,`model` 既可传 `id`,也可直接传 `name`
### 非流式聊天
```bash
curl -s http://127.0.0.1:8317/v1/chat/completions \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"model": "dashscope_qmodel",
"messages": [
{"role": "user", "content": "写一个 python hello world"}
]
}'
```
### 流式聊天
```bash
curl -N http://127.0.0.1:8317/v1/chat/completions \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"model": "dashscope_qmodel",
"stream": true,
"messages": [
{"role": "user", "content": "介绍一下你自己"}
]
}'
```
## 5. 统计与监控
支持调用次数与 token估算值统计
- `GET /internal/stats`(需 Bearer
- `GET /metrics`Prometheus 文本格式)
示例:
```bash
curl -s http://127.0.0.1:8317/internal/stats \
-H "Authorization: Bearer sk-xxx"
```
```bash
curl -s http://127.0.0.1:8317/metrics \
-H "Authorization: Bearer ${METRICS_TOKEN:-sk-your-api-key}"
```
说明:
- `usage.prompt_tokens/completion_tokens` 为估算值(按字节近似换算)。
- 非流式响应里会附带 `usage` 字段。
- 流式响应可传 `stream_options: {"include_usage": true}` 让最后一帧返回 `usage`
- `/metrics` 默认需要 Bearer 鉴权:优先匹配 `METRICS_TOKEN`,否则接受 `API_KEYS` 里任意一个;两者都未配置时保持公开。
## 6. 容器内自动登录
已内置自动登录能力Playwright + Chromium
你可以主动触发:
```bash
curl -s -X POST http://127.0.0.1:8317/internal/auto-login/start \
-H "Authorization: Bearer sk-your-api-key"
```
查看状态:
```bash
curl -s http://127.0.0.1:8317/internal/auto-login/status \
-H "Authorization: Bearer sk-your-api-key"
```
说明:
- 若未登录,`/v1/models``/v1/chat/completions` 也会尝试自动登录。
- 账号密码来自 `.env``LINGMA_USERNAME` / `LINGMA_PASSWORD`)。
- 建议仅在受控环境使用,并妥善保护 `.env`
## 7. agent 模式
在 v1 中,若 `model``agent``lingma-agent`,会走 agent 模式。
```bash
curl -s http://127.0.0.1:8317/v1/chat/completions \
-H "Authorization: Bearer sk-xxx" \
-H "Content-Type: application/json" \
-d '{
"model": "agent",
"messages": [
{"role": "user", "content": "分析这个项目目录结构"}
]
}'
```