← Back to home@2151649856sjs-create

joycode-proxy

OpenAI-compatible local proxy exposing JoyCode (JD Cloud JoyCoder) credits, plus a DSH model-provider plugin

Stars
0
Language
JavaScript
Created
Oct 16, 2026
Updated
Oct 16, 2026

Introduction

joycode-proxy

📘 English documentation: README.en.md

把 JoyCode(京东云 JoyCoder 积分) 反代成一个 OpenAI 兼容的 HTTP 服务,再通过一个 DSH provider 插件把它的积分池接进 DSH,当作 agent 的模型后端。整体思路与 qoder-proxy / dsh-llm-qoder 完全一致,只是后端换成了 JoyCode 的「color gateway」协议。

架构

DSH agent
  └─ ctx.llm.registerAdapter(["joycode"], adapter)   ← dsh-llm-joycode 插件
       └─ PiAiAdapter → openAICompletionsApi(baseUrl=本地 shim)
            └─ POST http://127.0.0.1:8318/v1/chat/completions
                 └─ joycode-proxy (server.mjs)
                      └─ POST https://api-ai.jd.com/api?appid=joycode_ide&functionId=chat_completions&t=...&sign=...
                           (HMAC-SHA256 签名 + ptKey 头)
                           └─ JoyCode 后端(同一账号的积分计费)

端点

方法路径说明
GET/v1/models返回 JoyCode 后端模型列表
POST/v1/chat/completionsOpenAI 兼容,支持 stream: true/false
GET/health探活 + 配置自检

为什么用「color gateway」而不是逆向

JoyCode IDE 的请求签名与鉴权都在它自带的 extension.js 里明文实现,核心只有三样东西:

  1. 网关地址:https://api-ai.jd.com/api(登录态里的 colorBaseUrl)。
  2. 鉴权头:ptKey(登录态里的 ptKey,即京东云账号票据)+ 可选 loginType/tenant。
  3. 签名:对 {appid, functionId, t} 排序后取非空值 & 拼接,用 HMAC-SHA256 + IDE 内置签名密钥算 hex,作为 sign 查询参数。

因此不需要逆向任何加密/WASM,直接把这段签名逻辑复刻成 server.mjs 里的 signQuery() / gatewayUrl() 即可。

关于那个签名密钥:它是 IDE 客户端内置的公开协议常量,随 IDE 分发给每个用户,不是账号凭据——单独拿到它无法发起任何有效请求。真正的凭据是 ptKey,只从环境变量读、永不入库。若上游轮换密钥,重新从 extension.js 提取,或用 JOYCODE_SIGN_KEY 覆盖。

配置(环境变量)

变量必需默认说明
JOYCODE_PT_KEY✅空账号票据(登录态 jdhLoginInfo.ptKey)
JOYCODE_TENANT⭕空租户 ID(登录态 tenant)
JOYCODE_COLOR_BASE_URL⭕https://api-ai.jd.com网关 origin(登录态 colorBaseUrl)
JOYCODE_MASTER_BASE_URL⭕空直连 origin(登录态 masterBaseUrl),网关不可用时兜底
JOYCODE_LOGIN_TYPE⭕PIN_JD_CLOUD登录类型
JOYCODE_SIGN_KEY⭕内置常量覆盖签名密钥(上游轮换时用)
JOYCODE_PROXY_PORT⭕8318本地监听端口
JOYCODE_PROXY_HOST⭕127.0.0.1监听地址
JOYCODE_PROXY_MODEL⭕JoyAI-Code-1.6缺省模型
JOYCODE_PROXY_API_KEY⭕空设置后要求 Authorization: Bearer <key>

怎么拿到自己的凭据:JoyCode IDE 的登录态存在一个 SQLite 库里 (Windows %APPDATA%\JoyCode\User\globalStorage\state.vscdb; macOS ~/Library/Application Support/JoyCode/User/globalStorage/state.vscdb; Linux ~/.config/JoyCode/User/globalStorage/state.vscdb)。 读 ItemTable 表里 key 为 JoyCoder.IDE 的那一行,其 JSON 的 joyCoderUser 里就有 ptKey / colorBaseUrl / masterBaseUrl / tenant。 把这些填进 .env(见 .env.example)。.env 已在 .gitignore 里,绝不要提交。

不想手动抠?跑 npm run setup,它会自动从本机 IDE 登录态读出凭据写进 .env。

模型列表(后端实时返回)

  • JoyAI-Code-1.6
  • GLM-5.3-agent(GLM-5.3)
  • Kimi-K2.6-agent(Kimi-K2.6,多模态)
  • MiniMax-M3-agent(MiniMax-M3,多模态)
  • Doubao-Seed-2.0-pro-agent(Doubao-Seed-2.0-pro,多模态)

启动

$env:JOYCODE_PT_KEY = "<ptKey>"
node server.mjs

验证:

curl.exe -s http://127.0.0.1:8318/v1/models
curl.exe -s http://127.0.0.1:8318/v1/chat/completions `
  -H "Content-Type: application/json" `
  -d '{\"model\":\"JoyAI-Code-1.6\",\"messages\":[{\"role\":\"user\",\"content\":\"reply exactly PONG\"}]}'

快速开始

git clone <this-repo> && cd joycode-proxy
npm run setup             # 自动从本机 JoyCode IDE 登录态读出 ptKey / tenant 写进 .env
npm start

没有装 JoyCode IDE?手动也行:

cp .env.example .env      # 然后填入你自己的 ptKey / tenant
npm start

验证:

curl -s http://127.0.0.1:8318/v1/models
curl -s http://127.0.0.1:8318/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"JoyAI-Code-1.6","messages":[{"role":"user","content":"reply exactly PONG"}]}'

零运行时依赖:只用 Node 内置的 node:http / node:crypto,npm install 不是必需的。

接 DSH

一条命令即可完成挂载(自动建 junction + 追加 patch 条目,幂等):

npm run install:dsh          # 等价于 node install-dsh-plugin.mjs
# 可选:指定 profile / DSH_HOME
DSH_PROFILE=web DSH_HOME=/path/to/.dsh node install-dsh-plugin.mjs

手动方式:

  1. 把 dsh-plugin/ 挂进你的 DSH profile(例如用 junction / symlink 放到 <DSH_HOME>/profiles/web/node_modules/dsh-llm-joycode,或直接 dsh plugin add 该目录)。

  2. 在 <DSH_HOME>/profiles/web/cordis.patch.yml 末尾追加:

    - insert:
        - id: llm-joycode
          name: dsh-llm-joycode
    
  3. 重启 DSH,模型选择器里应出现 joycode provider(5 个模型)。

已知限制

  • 无状态:把 OpenAI messages 拍平成单个 prompt,不保留跨请求会话(和 qoder-proxy 一致)。
  • 不支持 function calling / tools:JoyCode 网关的 chat completions 走纯文本路径。
  • 单账号串行:凭据来自一个登录态,多并发请求共享同一账号的积分。
  • 签名密钥可能轮换:密钥是 IDE 内置常量,上游更换后需重新提取,或用 JOYCODE_SIGN_KEY 覆盖。

免责声明

本项目仅用于在你自己的账号下、于本机把已有的 JoyCode 积分接到其它客户端, 便于个人开发使用。请自行确认你的用法符合服务商条款。作者不对账号封禁、 额度损失或任何间接损害负责。

License

MIT