9router/open-sse/providers/registry/qoder.js
mannnrachman d433c0b295 feat(qoder): support PAT (Personal Access Token) connections end-to-end
Adds pt-... token auth as an alternative to OAuth device flow. A PAT can't
sign COSY requests directly, so it's exchanged for a short-lived job token
(jt-...) plus userId via openapi.qoder.sh, then used for signing.

Also fixes job-token traffic (jt-...) being rejected by api3.qoder.sh with
403 "Login expired" — the official qodercli serves jt- traffic from
api2.qoder.sh instead, so buildUrl/model-list routing now branches on it.

Quota usage and the dashboard add-key modal are updated to resolve PAT
credentials and label the field correctly, and bulk-add now validates
each key so it gets a real testStatus instead of a hardcoded "unknown".
2026-08-05 11:16:50 +07:00

58 lines
1.9 KiB
JavaScript

export default {
id: "qoder",
priority: 30,
alias: "qd",
uiAlias: "qd",
display: {
name: "Qoder",
icon: "water_drop",
color: "#EC4899",
website: "https://qoder.com",
notice: {
signupUrl: "https://qoder.com",
},
},
category: "oauth",
authModes: ["oauth", "apikey"],
hasOAuth: true,
authHint: "Personal Access Token (pt-...) từ https://qoder.com/account/integrations",
transport: {
baseUrl: "https://api3.qoder.sh/algo/api/v2/service/pro/sse/agent_chat_generation",
headers: {},
timeoutMs: 120000,
stallTimeoutMs: 120000,
usage: {
url: "https://openapi.qoder.sh/api/v2/quota/usage",
},
},
models: [
{ id: "ultimate", name: "Ultimate" },
{ id: "auto", name: "Auto" },
{ id: "performance", name: "Performance" },
{ id: "efficient", name: "Efficient" },
{ id: "qmodel_preview", name: "Qwen3.8-Max-Preview" },
{ id: "qmodel_latest", name: "Qwen3.7-Max" },
{ id: "qmodel", name: "Qwen3.7-Plus" },
{ id: "kmodel_latest", name: "Kimi-K3" },
{ id: "kmodel", name: "Kimi-K2.7-Code" },
{ id: "gm51model", name: "GLM-5.2" },
{ id: "dmodel", name: "DeepSeek-V4-Pro" },
{ id: "dfmodel", name: "DeepSeek-V4-Flash" },
{ id: "mmodel", name: "MiniMax-M3" },
],
oauth: {
openApiBaseUrl: "https://openapi.qoder.sh",
centerBaseUrl: "https://center.qoder.sh",
chatBaseUrl: "https://api3.qoder.sh",
deviceTokenUrl: "https://openapi.qoder.sh/api/v1/deviceToken/poll",
refreshUrl: "https://center.qoder.sh/algo/api/v3/user/refresh_token",
userInfoUrl: "https://openapi.qoder.sh/api/v1/userinfo",
quotaUsageUrl: "https://openapi.qoder.sh/api/v2/quota/usage",
loginUrl: "https://qoder.com/device/selectAccounts",
},
features: {
usage: true,
// PAT (apikey) connections also carry quota usage (via job-token exchange).
usageApikey: true,
},
};