# @twork/dsh-openai-gateway

TWork OpenAI 兼容 API 网关（DSH host 插件，web profile 专用）。

在 DSH webServer 原生注册 `/v1` 前缀路由（与 17 个 TWork 插件的 `/twork/*` 同缝），
经 `sessionController` 直调驱动本进程会话引擎——业务系统用标准 OpenAI SDK
（base_url + Bearer api_key）即可调用 TWork 完整智能体（品牌/技能/MCP/云端模型全继承）。

## 端点

| 端点 | 鉴权 | 说明 |
|---|---|---|
| `GET /v1/health` | 无 | 探活（冒烟/就绪探测） |
| `GET /v1/models` | Bearer | 目录：`provider/model` 全限定 + 唯一裸 id + `twork` 别名 |
| `POST /v1/chat/completions` | Bearer | 非流式 + `stream:true` SSE（delta 帧 + `[DONE]`） |
| `POST/GET /v1/tokens`、`DELETE /v1/tokens/:id` | bootstrap | 签发/列表/吊销（明文一次回显，服务端只存 sha256） |

## 语义要点

- **model 解析**：空/`default`/`twork`/`twork-web` → 目录 `default`；`provider/model` 精确；裸 `model.id`；未命中 404
- **多轮**：`user` 字段（稳定业务键）→ sha256 派生固定会话 id 复用续聊（上下文由 TWork 会话承载，只投递末条消息）；缺省每次新会话、请求内整段转写投递（无状态）
- **system 消息**：以"调用方系统指令（冲突时以 TWork 规范为准）"前言注入
- **流式 delta**：订阅 `agent/assistant-stream` scoped 事件（会话格式 v2 起 `assistant/chunk` 不再持久化，勿订阅 session/event 的同名事件）
- **无人值守**：`agent/created` 钩子把 `openai-` 前缀会话审批策略置 `never`（需审批工具确定性拒绝）；`approval/asked` 看门狗 + 回合硬超时 + 客户端断连 cancel 三重保险
- **隔离**：每 token 独立工作区 `$DSH_HOME/openai/workspaces/<token-id>/`；同会话请求进程内互斥排队；per-token 滑动窗口限流

## 配置（env，读自 gateway 进程）

`TWORK_OPENAI_BOOTSTRAP_TOKEN`（管理凭据，空=管理面关闭）、`TWORK_OPENAI_RATE_LIMIT_PER_MINUTE=30`、
`TWORK_OPENAI_TURN_TIMEOUT_MS=1800000`、`TWORK_OPENAI_APPROVAL_WATCHDOG_MS=60000`、`TWORK_OPENAI_MAX_BODY_MB=4`。

## 已知限制（v1）

- 非流式 `content` 取末条 `assistant/message` 权威终稿；流式 delta 含中间步骤文本（与 GUI 转写一致）
- usage 为回合内累加（多步 agent 的 input 重复计上下文，是计费口径非单次请求口径）
- 与 Web GUI 单进程共享资源，定位内部中低并发集成，非公有多租户 API 网关
- API 会话无租户属主绑定（tenant-guard 只守 `/api`），GUI 全员可见

## 参考

方案与调研定案：`plan-31bb80749948.md`；接入文档：`deploy/web/README-部署.md`「对外 API」章节；
端到端冒烟：`deploy/web/smoke-openai.sh`。
