aitoken-conversions
v0.4.2
Published
Unified AI API format conversion engine: Claude Messages / OpenAI Responses / OpenAI Chat Completions / Gemini GenerateContent (request, response and SSE streaming)
Maintainers
Readme
aitoken-conversions
统一的 AI API 格式转换引擎,在 4 种 API 格式之间进行请求 / 响应 / SSE 流式转换:
| Format | 说明 | 端点路径 |
|--------|------|---------|
| claude | Anthropic Claude Messages API | /v1/messages |
| responses | OpenAI Responses API | /v1/responses |
| completions | OpenAI Chat Completions API | /v1/chat/completions |
| gemini | Google Gemini GenerateContent API | /v1beta/models/{model}:{generateContent\|streamGenerateContent} |
- 零运行时依赖(仅 Node.js 内置
crypto/stream) - 12 个单向转换 pair(
pairs/{client}-{upstream}),provider 推理后处理(DeepSeek / Moonshot / Qwen / GLM 等的reasoning_content)由ReasoningConfig驱动 - 引擎内部结构与完整 API 文档见 src/README.md
安装
npm install aitoken-conversions用法
import { transformRequest, transformResponse, detectRequestFormat } from 'aitoken-conversions';
import { createStreamPipeline } from 'aitoken-conversions/pipeline';
import { buildUpstreamUrl } from 'aitoken-conversions/url-normalizer';
import type { Format } from 'aitoken-conversions/types';
// 请求转换:claude 客户端 → completions 上游
const { body, headers } = transformRequest({
fromFormat: 'claude',
toFormat: 'completions',
body: claudeRequestBody,
});
// 响应转换:上游响应 → 客户端格式
const clientResponse = transformResponse({
fromFormat: 'completions',
toFormat: 'claude',
response: upstreamResponse,
});
// SSE 流式管线(解析 → 转换 → 序列化)
for await (const chunk of createStreamPipeline(res.body, {
fromFormat: 'completions',
toFormat: 'claude',
})) {
// chunk 为客户端格式的 SSE 文本
}子路径导出
| 导出 | 内容 |
|------|------|
| . | transformRequest / transformResponse / createStreamConverter / detectRequestFormat / getReasoningConfig / compact 全家桶 等(见 src/index.ts) |
| ./pipeline | createStreamPipeline / SSEEventParser / serializeSSE / StreamPipelineOptions |
| ./url-normalizer | buildUpstreamUrl / normalizeApiUrl |
| ./types | Format / SSEEvent / StreamConverter / ReasoningConfig 等类型 |
| ./compact | compact 对话压缩全套函数(prepareCompactRequest / processCompactResponse 等) |
| ./stream-converter-adapter | StreamConverterAdapter(StreamConverter → Node Transform 桥接) |
TODO:thinking/reasoning 已知缺口
2026-08-27 全链路审查(server 代理 + client 三引擎 + 本包)遗留,按优先级排列;修复后勾选并同步更新 src/README.md 的 Thinking/Reasoning 子系统章节。
- [ ] P1 ·
<think>标签格式零支持 —— QwQ、部分 vLLM / llama.cpp 部署、OpenRouter 免费档模型把推理内容以<think>…</think>内嵌在content输出。全包无解析(<think零命中),标签原文透出到客户端正文。修法方向:completions 响应 + 流式侧前置剥离,归一为标准 thinking 输出(与其他 pair 的reasoning_content处理对齐)。 - [ ] P1 · Gemini thinking 全链路缺失(工作量最大,建议独立里程碑):
- 请求侧:
claude→gemini/responses→gemini无thinkingConfig映射(现仅completions↔gemini有 budget 双向映射)→ Gemini 2.5/3 上游思考开关不可控(2.5 Pro 关不掉、Flash 该关时没关); - 响应侧:
parts[].thought=true在所有 pair 均未转换(thought/includeThoughts零命中)→ Gemini 上游思考内容全丢; - 流式:thought parts 流式转换缺失。
- 请求侧:
- [ ] P1 · 跨池 fallback 的 thinking signature 失效 ——
signature/signature_delta跨格式全链路丢弃(completions 系无对应字段,本身合理);但同格式 claude→claude passthrough 原样保留 A 供应商的 signature,会话中途路由换池时打到 B 供应商 claude 端点 → signature 校验 400。修法方向:本包提供 strip 历史 thinking 块的 helper,网关 fallback 换上游时调用。 - [ ] P1 ·
reasoning_text.delta事件未监听 ——pairs/claude-responses/streaming.ts只处理response.reasoning.delta/reasoning_summary_text.delta;gpt-oss 等经部分网关输出的原生response.reasoning_text.delta被静默丢弃。 - [ ] P1 · Responses
encrypted_content不往返 —— 仅responses→responses透传层面涉及,跨格式 pair 均不处理;Codex 走非官方 Responses 上游(include: ["reasoning.encrypted_content"])时多轮推理上下文丢失。 - [ ] P2 · budget↔effort 映射对称化 —— 正向
claudeThinkingToReasoningEffort(<4000 low / <16000 medium / ≥16000 high)与反向reasoningEffortToClaudeThinking(2048 / 8192 / 32000)阈值不一致,completions→gemini又用 2048 / 8192 / 24576 —— 跨格式往返数值漂移(无功能影响,仅档位偏差)。 - [ ] P2 · 测试空白 —— 本包零测试。至少补:effort 分档与往返、流式 thinking 事件序列(claude↔completions↔responses 三角)、redacted_thinking 适配、
<think>剥离、deriveClaudeThinking(completions→claude,2026-08-27 新增)的用例,防止缺口回归。
包外遗留(不在本包范围,记录待跟进):client claude-code 引擎 redacted_thinking 块无 UI 占位展示;server LevelDB 日志 thinking 全文无截断/脱敏;client/src/switch(aicodeswitch 移植)自带一套平行 reasoning 逻辑未审查。
双格式构建(ESM + CJS)
构建产物同时输出 dist/(ESM,供 import)与 dist/cjs/(CJS,供 require,含 {"type":"commonjs"} 标记)。exports 按条件分发:import → ESM、require → CJS、development → TS 源码(monorepo 内 tsx 开发用)。另附 typesVersions 映射,兼容 moduleResolution: "node"(node10)的老式 TypeScript 配置(如 aicodeswitch 服务端)。
License
GPL-3.0 — 源自 aicodeswitch 项目。
