npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

llm_proxy_pro

v1.0.0

Published

Multi-provider LLM proxy for claude code / codex with load balancing, failover and training-data recording

Readme

llm_proxy

面向 Claude Code / Codex 等客户端的 LLM 代理。零 npm 依赖,纯 Node.js(>= 18,依赖内置 fetch)实现。

功能简介

  • 多 provider 配置:一个 config.json 里配置多个上游 OpenAI 兼容 provider。
  • 负载均衡:provider 的每个 api_key 是一个独立槽位(slot),多个 key = 同一模型多倍并发。
  • 故障切换(failover)与自动恢复:上游超时/报错自动切到下一个槽位/模型,故障槽位后台重试恢复。
  • 全宕报警:所有槽位不可用时向 stderr 输出 ⚠ ALL PROVIDERS DOWN(去重,恢复后重置)并返回 HTTP 503。
  • 训练数据记录:每个成功请求记录一条 OpenAI fine-tune 格式的 JSONL(data/sessions-YYYYMMDD.jsonl)。
  • 协议转换:Anthropic /v1/messages ⇄ OpenAI /v1/chat/completions 双向转换,含 SSE 流式。

config.json 说明

对象形式(推荐,见 config.example.json):

{
  "port": 8787,
  "timeout_ms": 300000,
  "providers": [
    {
      "name": "provider-a",
      "base_url": "https://your-provider.example.com",
      "api_keys": ["sk-your-key-1", "sk-your-key-2"],
      "models": ["model-a", "model-b"]
    }
  ]
}

也兼容 llm-proxy-py 的数组形式(顶层直接是 provider 数组,此时 port/timeout_ms 用默认值或 CLI 指定)。

字段说明:

| 字段 | 说明 | |---|---| | port | 监听端口,默认 8787(CLI --port 可覆盖) | | timeout_ms | 上游读写超时,默认 300000(5 分钟);0 表示不限制 | | providers[].name | provider 名称(用于训练数据 metadata),缺省用 base_url | | providers[].base_url | 上游 OpenAI 兼容地址(会自动去掉尾部 /) | | providers[].api_keys | key 数组;每个 key 是一个独立槽位,多 key = 该模型更高并发 | | providers[].models | 该 provider 提供的模型列表;必须显式列出,不会调用上游 /v1/models 自动发现 |

启动方式

# 方式一:npx(推荐)
CONFIG_FILE=config.json npx llm_proxy@latest

# 方式二:本地运行
node bin/llm-proxy.js --config config.json
  • CLI 参数:--port <n>、--host <addr>、--config <file>(也可用环境变量 CONFIG_FILE,默认 config.json)。
  • 默认监听 127.0.0.1:8787。
  • 环境变量 DATA_DIR 可覆盖训练数据目录,默认 data/。

客户端接入

代理的鉴权很简单:客户端带的 key 只要求非空,实际用哪个上游 key 由代理的槽位调度决定。

Claude Code(走 Anthropic 协议 /v1/messages,由代理转换为 OpenAI):

export ANTHROPIC_BASE_URL=http://127.0.0.1:8787
export ANTHROPIC_API_KEY=sk-anything   # 任意非空即可

Codex(走 OpenAI 协议 /v1/chat/completions):

export OPENAI_BASE_URL=http://127.0.0.1:8787/v1
export OPENAI_API_KEY=sk-anything      # 任意非空即可

注意:Codex 还需在 ~/.codex/config.toml 中设置 wire_api = "chat":

wire_api = "chat"

因为代理未实现 Responses API(/v1/responses),必须让 Codex 走 Chat Completions 协议。

端点列表

| 端点 | 说明 | |---|---| | POST /v1/chat/completions | OpenAI 协议透传(含 SSE 流式);响应中的 model 字段回显客户端请求名 | | POST /v1/messages | Anthropic 协议,内部转换为 OpenAI 调用(含 SSE 流式) | | GET /v1/models | 返回资源池中的模型列表(来自 config,非上游发现) | | GET /health | 各槽位状态(IDLE/IN_USE/UNAVAILABLE)与 last_error |

注意:客户端请求里的 model 名仅用于回显,代理实际会从资源池中选择可用的真实模型转发。

训练数据格式

每个成功请求写入一行 JSONL,路径为 data/sessions-YYYYMMDD.jsonl(或 DATA_DIR 目录下),格式为 OpenAI fine-tune 格式:

{"messages":[{"role":"system","content":"..."},{"role":"user","content":"..."},{"role":"assistant","content":"..."}],"metadata":{"model":"上游真实模型","provider":"a","requested_model":"客户端请求名","endpoint":"chat","timestamp":"2026-09-18T04:00:00.000Z","usage":{"prompt_tokens":10,"completion_tokens":20}}}

说明:

  • messages 为完整对话(system/user/assistant),metadata 记录上游真实模型、provider、客户端请求的模型名、端点、时间戳与 token 用量。
  • 只记录成功请求:失败请求、failover 中间尝试、上游断流(未收到 [DONE])均不记录。

故障切换行为

  • 上游超时 / 连接错误 / 400 / 401 / 403 / 429 / 5xx → 该槽位标记为 UNAVAILABLE,请求自动切换到同模型的其他槽位,再切到其他模型。
  • 不可用槽位会被持续重试,成功后自动恢复为 IDLE。
  • 所有槽位均不可用时:向 stderr 输出 ⚠ ALL PROVIDERS DOWN(连续报警去重,任一槽位恢复后重置),并向客户端返回 HTTP 503。

测试

npm test
# 或
node --test "test/*.test.js"