dsh-model 0.21.3 → 0.21.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +17 -8
- package/README.md +17 -8
- package/dist/cli.js +2 -2
- package/dist/commands/key.js +7 -7
- package/dist/daemon/core.js +6 -5
- package/dist/ops.js +32 -0
- package/package.json +16 -3
package/README.en.md
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
# dsh-model
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**One address for all your models: subscriptions, free tiers and local models, with daily check-in credits claimed for you.**
|
|
6
|
+
|
|
7
|
+
One OpenAI-compatible endpoint, one key, dozens of models. dsh, Cline, Continue, Cherry Studio, scripts: anything that speaks the OpenAI API just works.
|
|
6
8
|
|
|
7
9
|
<p>
|
|
8
10
|
<a href="LICENSE"><img src="https://img.shields.io/github/license/AIcivilization/dsh-model" alt="MIT license"></a>
|
|
@@ -17,18 +19,22 @@ English · [中文](README.md)
|
|
|
17
19
|
|
|
18
20
|
</div>
|
|
19
21
|
|
|
20
|
-
##
|
|
22
|
+
## Why
|
|
21
23
|
|
|
22
|
-
You may have several
|
|
24
|
+
You may have several at once: Codex from ChatGPT Plus, a Kimi coding plan, free WorkBuddy credits, free Gemini and Groq keys, and Ollama on your machine. Each has its own API and sign-in, every tool needs its own setup, and when a quota runs out you switch by hand.
|
|
23
25
|
|
|
24
26
|
dsh-model turns them into **one address and one kind of key**:
|
|
25
27
|
|
|
26
|
-
- **
|
|
27
|
-
- **
|
|
28
|
-
- **
|
|
29
|
-
- **
|
|
28
|
+
- 🔌 **Connect once, use everywhere**: every model shows up in dsh, grouped by source; any other tool uses the same address and key.
|
|
29
|
+
- 🆓 **Get the most from free tiers**: WorkBuddy credits, free Gemini / Groq / OpenRouter keys and local models; every source is tagged Free / Free · limited / Paid.
|
|
30
|
+
- 📅 **Daily check-in, credits claimed for you**: WorkBuddy (China), Qoder and Trae are checked in automatically every day.
|
|
31
|
+
- 🔁 **Rate limits are not the end**: when a model is offered by several sources, requests move to another one when the first is limited.
|
|
32
|
+
- 📊 **Know where you stand**: plan usage, remaining credits, success rate and speed per model, recent failures with advice, and a notice when quota runs low.
|
|
33
|
+
- 🔒 **Secure by default**: a key is always required, one per device, revocable at any time; every sign-in happens on your own machine.
|
|
34
|
+
- 🖥️ **Laptop or server**: Windows, macOS, Linux; on a VPS (with [dsh-vps](https://github.com/AIcivilization/dsh-vps)) it opens an https address you can use from anywhere.
|
|
35
|
+
- 🧹 **Installs in one command, uninstalls cleanly**: dsh's config is restored byte for byte.
|
|
30
36
|
|
|
31
|
-
|
|
37
|
+
No dsh? It still works: the command line manages everything; dsh just adds a management page.
|
|
32
38
|
|
|
33
39
|
## Quick start
|
|
34
40
|
|
|
@@ -54,6 +60,7 @@ On a dsh-vps server, use `sudo dsh-model setup`. On Windows, run it in a normal
|
|
|
54
60
|
| **Sources** | One switch per provider: on connects (and signs in if needed), off pauses and keeps the sign-in. Each row is tagged Free / Free · limited / Paid and shows plan usage or remaining credits |
|
|
55
61
|
| **Models** | Pick which models of each source appear in dsh (5 suggested per source by default); the rest stay available through the endpoint; a "Test" button per model |
|
|
56
62
|
| **Auto switch** | When a model is offered by several sources, dsh gets an "Auto switch (multiple sources)" group that moves to another source when one is rate-limited or failing |
|
|
63
|
+
| **Daily check-in** | WorkBuddy (China), Qoder and Trae are checked in automatically every day (or with one click); the card shows what you got today |
|
|
57
64
|
| **Recent failures** | Failed requests in the last 24 hours: which model, why, and what to do (no conversation content kept) |
|
|
58
65
|
| **API keys** | OpenAI-style, one per device. Requests, success rate, latency and speed over 24 hours; copy, rotate, revoke |
|
|
59
66
|
| **Model stats** | Success rate, latency and speed per model |
|
|
@@ -98,6 +105,7 @@ dsh-model only connects; it provides no quota of its own.
|
|
|
98
105
|
| `sources` | Sources: switch, cost, sign-in state, usage |
|
|
99
106
|
| `source enable\|disable\|logout <source>` | Turn on (signing in if needed) / off / sign out |
|
|
100
107
|
| `key list\|add\|revoke\|rotate <name>` | Access keys, one per device |
|
|
108
|
+
| `checkin` | Check in now (WorkBuddy China, Qoder, Trae; automatic daily by default) |
|
|
101
109
|
| `failures` | Failed requests in the last 24 hours, with advice |
|
|
102
110
|
| `stats` | Success rate, latency and speed by key, source and model |
|
|
103
111
|
| `status` / `doctor [--e2e]` | Overview / health checks |
|
|
@@ -127,6 +135,7 @@ See the [design doc](docs/DESIGN.md) (Chinese).
|
|
|
127
135
|
|
|
128
136
|
## Notes
|
|
129
137
|
|
|
138
|
+
- Meant for personal use: one account of your own per provider; do not use it to serve others.
|
|
130
139
|
- Using subscription and WorkBuddy credentials outside the official clients may break the providers' terms and put the account at risk. Decide for yourself.
|
|
131
140
|
- Windows 10 / 11 (x64, ARM64), macOS and Linux, Node ≥ 20.
|
|
132
141
|
- Windows: the background services start at sign-in with no window. If an antivirus blocks them (the program is gone or will not start), trust `%USERPROFILE%\.dsh-model` and run `dsh-model repair`.
|
package/README.md
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
# dsh-model
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**一个地址,用上你所有的模型:订阅、免费额度、本机模型,签到积分自动领。**
|
|
6
|
+
|
|
7
|
+
一个 OpenAI 兼容地址,一把 key,几十个模型。dsh、Cline、Continue、Cherry Studio、脚本……凡是支持 OpenAI 接口的软件都能直接用。
|
|
6
8
|
|
|
7
9
|
<p>
|
|
8
10
|
<a href="LICENSE"><img src="https://img.shields.io/github/license/AIcivilization/dsh-model" alt="MIT license"></a>
|
|
@@ -17,18 +19,22 @@
|
|
|
17
19
|
|
|
18
20
|
</div>
|
|
19
21
|
|
|
20
|
-
##
|
|
22
|
+
## 为什么用它
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
你手上可能有好几样:ChatGPT Plus 带的 Codex、Kimi 的编程套餐、WorkBuddy 的免费积分、Gemini 和 Groq 的免费 key,还有本机的 Ollama。每家接口和登录方式都不一样,每个软件都得分别配置,额度用完了还要手动换。
|
|
23
25
|
|
|
24
26
|
dsh-model 把它们合成**一个地址、一种 key**:
|
|
25
27
|
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
28
|
+
- 🔌 **一处接入,处处可用**:dsh 里自动出现全部模型,按来源分组;其他软件填上同一个地址和 key 就行。
|
|
29
|
+
- 🆓 **把免费的用足**:WorkBuddy 积分、Gemini / Groq / OpenRouter 免费 key、本机模型都能接;每个来源标出「免费 / 免费·额度少 / 需付费」。
|
|
30
|
+
- 📅 **每日签到,自动领积分**:WorkBuddy 国内版、Qoder、Trae 每天自动签到,不用记。
|
|
31
|
+
- 🔁 **不怕限流**:同一个模型在几个来源都有时自动切换,一个限流就换另一个。
|
|
32
|
+
- 📊 **心里有数**:套餐用量、剩余积分、每个模型的成功率和速度、最近失败的原因和建议;额度快用完时提醒。
|
|
33
|
+
- 🔒 **默认安全**:始终要求 key,每台设备一把,可随时吊销;登录全在本机完成,不经过第三方。
|
|
34
|
+
- 🖥️ **电脑和服务器都行**:Windows、macOS、Linux;装在 VPS 上(配合 [dsh-vps](https://github.com/AIcivilization/dsh-vps))自动开一个 https 地址,电脑、手机随处用。
|
|
35
|
+
- 🧹 **装得上,卸得净**:一条命令安装;卸载时把 dsh 的配置逐字节还原。
|
|
30
36
|
|
|
31
|
-
|
|
37
|
+
没有 dsh 也能用:命令行就能管理全部功能,dsh 里多一个图形管理页而已。
|
|
32
38
|
|
|
33
39
|
## 快速开始
|
|
34
40
|
|
|
@@ -54,6 +60,7 @@ dsh-model setup
|
|
|
54
60
|
| **来源** | 每家一个开关:打开就接入(没登录会弹出登录框),关闭只停用、保留登录。每行标出「免费 / 免费·额度少 / 需付费」,下面显示套餐用量或剩余积分 |
|
|
55
61
|
| **选模型** | 每个来源选哪些模型显示在 dsh 里,默认每家推荐 5 个,其余的经统一地址照样可用;每个模型旁边有「测一下」 |
|
|
56
62
|
| **自动切换** | 同一个模型在几个来源都有时,dsh 里多一组「自动切换(多来源)」,一个来源限流或出错就自动换另一个 |
|
|
63
|
+
| **每日签到** | WorkBuddy 国内版、Qoder、Trae 每天自动签到(也可一键签到),卡片显示今天领了多少 |
|
|
57
64
|
| **最近失败** | 最近 24 小时失败的请求:哪个模型、为什么、该怎么办(不记录对话内容) |
|
|
58
65
|
| **API key** | OpenAI 格式,每台设备一把。显示 24 小时内的请求数、成功率、延迟和速度,可复制、轮换、吊销 |
|
|
59
66
|
| **模型统计** | 按模型显示成功率、延迟和速度 |
|
|
@@ -98,6 +105,7 @@ dsh-model 只负责转接,不提供额度。
|
|
|
98
105
|
| `sources` | 来源列表:开关、费用、登录状态、用量 |
|
|
99
106
|
| `source enable\|disable\|logout <来源>` | 打开(需要时登录)/ 关闭 / 退出登录 |
|
|
100
107
|
| `key list\|add\|revoke\|rotate <名称>` | 访问 key,每台设备一把 |
|
|
108
|
+
| `checkin` | 现在签到一次(WorkBuddy 国内版、Qoder、Trae;默认每天自动签) |
|
|
101
109
|
| `failures` | 最近 24 小时失败的请求和建议 |
|
|
102
110
|
| `stats` | 按 key、来源、模型的成功率、延迟和速度 |
|
|
103
111
|
| `status` / `doctor [--e2e]` | 总览 / 逐项自检 |
|
|
@@ -127,6 +135,7 @@ dsh · 编辑器 · 脚本 ──Bearer key──▶ 引擎 127.0.0.1:8317/v1(
|
|
|
127
135
|
|
|
128
136
|
## 注意
|
|
129
137
|
|
|
138
|
+
- 适合个人使用:每家用自己的一个账号,不要拿来对外提供服务。
|
|
130
139
|
- 订阅和 WorkBuddy 的凭据在官方客户端之外使用,可能不符合服务商的条款,账号有风险,请自行判断。
|
|
131
140
|
- 支持 Windows 10 / 11(x64、ARM64)、macOS、Linux,需要 Node ≥ 20。
|
|
132
141
|
- Windows:后台服务登录后自动运行、不弹窗口。如果被杀毒软件拦下(程序不见了或启动不了),把 `%USERPROFILE%\.dsh-model` 加入信任,再执行 `dsh-model repair`。
|
package/dist/cli.js
CHANGED
|
@@ -69,7 +69,7 @@ function help() {
|
|
|
69
69
|
login <来源> / logout <来源> 同 source enable / source logout
|
|
70
70
|
stats 按 key / 来源 / 模型的成功率、延迟、速度
|
|
71
71
|
failures 最近 24 小时失败的请求,以及该怎么办
|
|
72
|
-
checkin 现在签到一次(WorkBuddy 国内版、Qoder;默认每天自动签)
|
|
72
|
+
checkin 现在签到一次(WorkBuddy 国内版、Qoder、Trae;默认每天自动签)
|
|
73
73
|
status 一屏总览
|
|
74
74
|
doctor [--e2e] [--all] [--model M] 逐项自检;--e2e 实测流式与工具调用
|
|
75
75
|
connect-dsh [--dry-run] [--force] 写入 / 刷新 dsh 配置
|
|
@@ -102,7 +102,7 @@ Usage: dsh-model <command> [options]
|
|
|
102
102
|
login <source> / logout <source> Same as source enable / source logout
|
|
103
103
|
stats Success rate, latency and speed by key / source / model
|
|
104
104
|
failures Failed requests in the last 24 hours, and what to do
|
|
105
|
-
checkin Check in now (WorkBuddy China, Qoder; automatic daily by default)
|
|
105
|
+
checkin Check in now (WorkBuddy China, Qoder, Trae; automatic daily by default)
|
|
106
106
|
status Overview
|
|
107
107
|
doctor [--e2e] [--all] [--model M] Health checks; --e2e tests streaming and tool calls
|
|
108
108
|
connect-dsh [--dry-run] [--force] Write / refresh dsh config
|
package/dist/commands/key.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { requireRootInVps } from '../context.js';
|
|
3
3
|
import { DshModelError } from '../errors.js';
|
|
4
4
|
import { L } from '../i18n.js';
|
|
5
|
-
import { DSH_KEY_NAME, addKey, revokeKey, rotateKey, saveKeys } from '../keys.js';
|
|
6
|
-
import {
|
|
5
|
+
import { DSH_KEY_NAME, addKey, findActive, revokeKey, rotateKey, saveKeys } from '../keys.js';
|
|
6
|
+
import { applyKeyChange, dshKey, loadAll, syncModels } from '../ops.js';
|
|
7
7
|
import { withLock } from '../state.js';
|
|
8
8
|
import { baseUrl } from '../engine/client.js';
|
|
9
9
|
import { bold, info, isJsonMode, ok, printJson, table, warn } from '../util/output.js';
|
|
@@ -20,7 +20,7 @@ export async function key(ctx, sub, name) {
|
|
|
20
20
|
if (sub === 'add') {
|
|
21
21
|
const entry = addKey(all.keys, name);
|
|
22
22
|
await saveKeys(ctx, all.keys);
|
|
23
|
-
await
|
|
23
|
+
await applyKeyChange(ctx, all, { accepts: entry.key });
|
|
24
24
|
if (isJsonMode())
|
|
25
25
|
printJson({ ok: true, name, key: entry.key, baseURL: `${baseUrl(all.config.port)}/v1` });
|
|
26
26
|
ok(L(`已新增 key:${name}(只显示这一次,请妥善保存)`, `Key added: ${name} (shown only once; keep it safe)`));
|
|
@@ -32,19 +32,19 @@ export async function key(ctx, sub, name) {
|
|
|
32
32
|
if (name === DSH_KEY_NAME) {
|
|
33
33
|
throw new DshModelError('cannot_revoke_dsh', L('dsh 用的 key 不能吊销,只能轮换', 'The dsh key cannot be revoked, only rotated'), L('dsh-model key rotate dsh', 'dsh-model key rotate dsh'));
|
|
34
34
|
}
|
|
35
|
+
const old = findActive(all.keys, name)?.key;
|
|
35
36
|
revokeKey(all.keys, name);
|
|
36
37
|
await saveKeys(ctx, all.keys);
|
|
37
|
-
await
|
|
38
|
+
await applyKeyChange(ctx, all, { rejects: old });
|
|
38
39
|
ok(L(`已吊销 key:${name}`, `Key revoked: ${name}`));
|
|
39
40
|
return 0;
|
|
40
41
|
}
|
|
41
42
|
if (sub === 'rotate') {
|
|
42
43
|
const entry = rotateKey(all.keys, name);
|
|
43
44
|
await saveKeys(ctx, all.keys);
|
|
44
|
-
|
|
45
|
+
// 等新 key 在引擎里生效后再改 dsh
|
|
46
|
+
await applyKeyChange(ctx, all, { accepts: entry.key });
|
|
45
47
|
if (name === DSH_KEY_NAME) {
|
|
46
|
-
// 引擎热重载约 1s:等新 key 生效后再改 dsh
|
|
47
|
-
await new Promise((r) => setTimeout(r, 1500));
|
|
48
48
|
await syncModels(ctx, all, { quiet: true });
|
|
49
49
|
ok(L('已轮换 dsh 用的 key,并同步到 dsh', 'Rotated the dsh key and updated dsh'));
|
|
50
50
|
}
|
package/dist/daemon/core.js
CHANGED
|
@@ -31,8 +31,8 @@ import { DshModelError, isDshModelError } from '../errors.js';
|
|
|
31
31
|
import { L } from '../i18n.js';
|
|
32
32
|
import { refreshOpencodeModels, removeOpencodeKey, saveOpencodeKey, validateKeyShape, verifyOpencodeKey } from '../integrations/opencode.js';
|
|
33
33
|
import { riskNotice as workbuddyRiskNotice } from '../integrations/workbuddy.js';
|
|
34
|
-
import { DSH_KEY_NAME, addKey, loadKeys, revokeKey, rotateKey, saveKeys } from '../keys.js';
|
|
35
|
-
import {
|
|
34
|
+
import { DSH_KEY_NAME, addKey, findActive, loadKeys, revokeKey, rotateKey, saveKeys } from '../keys.js';
|
|
35
|
+
import { applyKeyChange, dshCandidates, dshKey, loadAll, saveAll, syncAll } from '../ops.js';
|
|
36
36
|
import { defaultPick, pickedFor } from '../dsh/pick.js';
|
|
37
37
|
import { loadSecrets, saveSecrets } from '../secrets.js';
|
|
38
38
|
import { SOURCES, credsFor, findSource, paymentRequired } from '../sources.js';
|
|
@@ -929,7 +929,7 @@ export class Daemon {
|
|
|
929
929
|
const all = await loadAll(this.ctx);
|
|
930
930
|
const entry = addKey(all.keys, name);
|
|
931
931
|
await saveKeys(this.ctx, all.keys);
|
|
932
|
-
await
|
|
932
|
+
await applyKeyChange(this.ctx, all, { accepts: entry.key });
|
|
933
933
|
await this.reloadKeyNames();
|
|
934
934
|
return { name: entry.name, key: entry.key };
|
|
935
935
|
});
|
|
@@ -939,9 +939,10 @@ export class Daemon {
|
|
|
939
939
|
throw new DshModelError('cannot_revoke_dsh', L('dsh 用的 key 不能吊销,只能轮换', 'The dsh key cannot be revoked, only rotated'));
|
|
940
940
|
await withLock(this.ctx, async () => {
|
|
941
941
|
const all = await loadAll(this.ctx);
|
|
942
|
+
const old = findActive(all.keys, name)?.key;
|
|
942
943
|
revokeKey(all.keys, name);
|
|
943
944
|
await saveKeys(this.ctx, all.keys);
|
|
944
|
-
await
|
|
945
|
+
await applyKeyChange(this.ctx, all, { rejects: old });
|
|
945
946
|
});
|
|
946
947
|
await this.reloadKeyNames();
|
|
947
948
|
}
|
|
@@ -950,7 +951,7 @@ export class Daemon {
|
|
|
950
951
|
const all = await loadAll(this.ctx);
|
|
951
952
|
const e = rotateKey(all.keys, name);
|
|
952
953
|
await saveKeys(this.ctx, all.keys);
|
|
953
|
-
await
|
|
954
|
+
await applyKeyChange(this.ctx, all, { accepts: e.key });
|
|
954
955
|
return e;
|
|
955
956
|
});
|
|
956
957
|
await this.reloadKeyNames();
|
package/dist/ops.js
CHANGED
|
@@ -12,6 +12,7 @@ import { DSH_KEY_NAME, findActive, loadKeys } from './keys.js';
|
|
|
12
12
|
import { serviceFor } from './service/index.js';
|
|
13
13
|
import { loadConfig, loadState, saveConfig, saveState } from './state.js';
|
|
14
14
|
import { ok, skip, warn } from './util/output.js';
|
|
15
|
+
import { readText, writeInPlace } from './util/fs.js';
|
|
15
16
|
export async function loadAll(ctx) {
|
|
16
17
|
const [config, state, keys] = await Promise.all([loadConfig(ctx), loadState(ctx), loadKeys(ctx)]);
|
|
17
18
|
return { config, state, keys };
|
|
@@ -34,6 +35,37 @@ export function dshKey(keys) {
|
|
|
34
35
|
export async function applyEngineConfig(ctx, all) {
|
|
35
36
|
return writeEngineConfig(ctx, all.config, all.keys);
|
|
36
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* 改 key 后确认引擎真的换上了:热重载偶尔会漏掉一次变化(CI 上 macOS、Windows 都见过等 15 秒仍没生效)。
|
|
40
|
+
* 没生效就原样再写一次配置文件,还不行就重启引擎。引擎没在运行时只写文件。
|
|
41
|
+
*/
|
|
42
|
+
export async function applyKeyChange(ctx, all, probe) {
|
|
43
|
+
await writeEngineConfig(ctx, all.config, all.keys);
|
|
44
|
+
const port = all.config.port;
|
|
45
|
+
if (!(await waitHealthy(port, 1000)))
|
|
46
|
+
return;
|
|
47
|
+
const works = (key) => listModels(port, key).then(() => true, () => false);
|
|
48
|
+
const effective = async () => (!probe.accepts || (await works(probe.accepts))) && (!probe.rejects || !(await works(probe.rejects)));
|
|
49
|
+
const wait = async (ms) => {
|
|
50
|
+
const deadline = Date.now() + ms;
|
|
51
|
+
while (Date.now() < deadline) {
|
|
52
|
+
if (await effective())
|
|
53
|
+
return true;
|
|
54
|
+
await new Promise((r) => setTimeout(r, 250));
|
|
55
|
+
}
|
|
56
|
+
return effective();
|
|
57
|
+
};
|
|
58
|
+
if (await wait(5000))
|
|
59
|
+
return;
|
|
60
|
+
const text = await readText(ctx.paths.engineYaml);
|
|
61
|
+
if (text !== null)
|
|
62
|
+
await writeInPlace(ctx.paths.engineYaml, text, { owner: ctx.owner });
|
|
63
|
+
if (await wait(5000))
|
|
64
|
+
return;
|
|
65
|
+
if ((await restartEngineBestEffort(ctx, all)) && (await wait(5000)))
|
|
66
|
+
return;
|
|
67
|
+
warn(L('引擎还没换上这次的 key 改动;稍后执行 dsh-model repair', 'The engine has not picked up this key change yet; run dsh-model repair later'));
|
|
68
|
+
}
|
|
37
69
|
/**
|
|
38
70
|
* 兜底重启:热重载没生效时用。vps 模式下 bridge 以 dsh 用户运行,没有权限重启系统服务——
|
|
39
71
|
* 这时只记警告不失败(实测:bridge 写完配置后 systemctl restart 被拒)。
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-model",
|
|
3
|
-
"version": "0.21.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.21.5",
|
|
4
|
+
"description": "One OpenAI-compatible address for all your models: subscriptions (Codex, Kimi…), free tiers (WorkBuddy, Gemini, Groq, OpenRouter), local models (Ollama, LM Studio), daily check-in credits, auto failover. Works with DeepSeek Harness (dsh) and any OpenAI-compatible tool. 一个地址用上你所有的模型。",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh-plugin",
|
|
7
7
|
"dsh-plugins",
|
|
@@ -21,7 +21,20 @@
|
|
|
21
21
|
"opencode",
|
|
22
22
|
"cliproxyapi",
|
|
23
23
|
"self-hosted",
|
|
24
|
-
"llm-tools"
|
|
24
|
+
"llm-tools",
|
|
25
|
+
"ai-gateway",
|
|
26
|
+
"llm-router",
|
|
27
|
+
"openai-proxy",
|
|
28
|
+
"free-llm",
|
|
29
|
+
"gemini",
|
|
30
|
+
"groq",
|
|
31
|
+
"openrouter",
|
|
32
|
+
"ollama",
|
|
33
|
+
"lm-studio",
|
|
34
|
+
"qoder",
|
|
35
|
+
"trae",
|
|
36
|
+
"daily-checkin",
|
|
37
|
+
"failover"
|
|
25
38
|
],
|
|
26
39
|
"license": "MIT",
|
|
27
40
|
"type": "module",
|