aigetwey 1.0.1
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/CHANGELOG.md +84 -0
- package/LICENSE +21 -0
- package/README.md +302 -0
- package/assets/logo.svg +8 -0
- package/assets/screenshot.png +0 -0
- package/assets/wordmark.svg +9 -0
- package/config.example.yaml +56 -0
- package/dashboard/.env.example +12 -0
- package/dashboard/next-env.d.ts +6 -0
- package/dashboard/next.config.ts +12 -0
- package/dashboard/package-lock.json +1771 -0
- package/dashboard/package.json +29 -0
- package/dashboard/postcss.config.mjs +5 -0
- package/dashboard/src/app/(console)/combos/page.tsx +10 -0
- package/dashboard/src/app/(console)/config/page.tsx +5 -0
- package/dashboard/src/app/(console)/console/page.tsx +92 -0
- package/dashboard/src/app/(console)/endpoint/page.tsx +5 -0
- package/dashboard/src/app/(console)/layout.tsx +17 -0
- package/dashboard/src/app/(console)/page.tsx +8 -0
- package/dashboard/src/app/(console)/providers/[id]/page.tsx +6 -0
- package/dashboard/src/app/(console)/providers/page.tsx +5 -0
- package/dashboard/src/app/(console)/quota/page.tsx +5 -0
- package/dashboard/src/app/(console)/tools/[id]/page.tsx +6 -0
- package/dashboard/src/app/(console)/tools/page.tsx +5 -0
- package/dashboard/src/app/(console)/usage/page.tsx +24 -0
- package/dashboard/src/app/api/cli-detect/[tool]/route.ts +253 -0
- package/dashboard/src/app/api/gw/[...path]/route.ts +89 -0
- package/dashboard/src/app/api/login/route.ts +30 -0
- package/dashboard/src/app/api/logout/route.ts +9 -0
- package/dashboard/src/app/api/password/route.ts +34 -0
- package/dashboard/src/app/globals.css +340 -0
- package/dashboard/src/app/icon.svg +8 -0
- package/dashboard/src/app/layout.tsx +28 -0
- package/dashboard/src/app/login/page.tsx +60 -0
- package/dashboard/src/components/AreaChart.tsx +115 -0
- package/dashboard/src/components/Badge.tsx +32 -0
- package/dashboard/src/components/Button.tsx +60 -0
- package/dashboard/src/components/CapacityBadges.tsx +40 -0
- package/dashboard/src/components/Checkbox.tsx +40 -0
- package/dashboard/src/components/CliToolConfig.tsx +63 -0
- package/dashboard/src/components/ConfigEditor.tsx +199 -0
- package/dashboard/src/components/ConfirmModal.tsx +36 -0
- package/dashboard/src/components/CooldownTimer.tsx +42 -0
- package/dashboard/src/components/EndpointView.tsx +439 -0
- package/dashboard/src/components/Icon.tsx +25 -0
- package/dashboard/src/components/KeyReveal.tsx +78 -0
- package/dashboard/src/components/Lamp.tsx +8 -0
- package/dashboard/src/components/LogTable.tsx +223 -0
- package/dashboard/src/components/LogoutButton.tsx +20 -0
- package/dashboard/src/components/ModelPicker.tsx +121 -0
- package/dashboard/src/components/ModelSelectModal.tsx +126 -0
- package/dashboard/src/components/PasswordEditor.tsx +86 -0
- package/dashboard/src/components/PricingEditor.tsx +171 -0
- package/dashboard/src/components/ProviderDetail.tsx +566 -0
- package/dashboard/src/components/ProviderManager.tsx +311 -0
- package/dashboard/src/components/QuotaView.tsx +78 -0
- package/dashboard/src/components/Rail.tsx +82 -0
- package/dashboard/src/components/RichCard.tsx +46 -0
- package/dashboard/src/components/RoutingView.tsx +329 -0
- package/dashboard/src/components/ThemeProvider.tsx +36 -0
- package/dashboard/src/components/ToastProvider.tsx +58 -0
- package/dashboard/src/components/ToolDetail.tsx +475 -0
- package/dashboard/src/components/TopBar.tsx +128 -0
- package/dashboard/src/components/UsageView.tsx +151 -0
- package/dashboard/src/components/ui.tsx +54 -0
- package/dashboard/src/lib/capabilities.ts +318 -0
- package/dashboard/src/lib/cliTools.ts +120 -0
- package/dashboard/src/lib/client.ts +190 -0
- package/dashboard/src/lib/gateway.ts +269 -0
- package/dashboard/src/lib/session.ts +71 -0
- package/dashboard/src/middleware.ts +37 -0
- package/dashboard/tsconfig.json +21 -0
- package/dist/adapters/anthropic.js +289 -0
- package/dist/adapters/anthropic.js.map +1 -0
- package/dist/adapters/gemini.js +268 -0
- package/dist/adapters/gemini.js.map +1 -0
- package/dist/adapters/index.js +8 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/openai.js +13 -0
- package/dist/adapters/openai.js.map +1 -0
- package/dist/cli/tray/autostart.js +152 -0
- package/dist/cli/tray/autostart.js.map +1 -0
- package/dist/cli/tray/icon.js +4 -0
- package/dist/cli/tray/icon.js.map +1 -0
- package/dist/cli/tray/tray.js +141 -0
- package/dist/cli/tray/tray.js.map +1 -0
- package/dist/cli/tray/trayRuntime.js +91 -0
- package/dist/cli/tray/trayRuntime.js.map +1 -0
- package/dist/cli.js +361 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.js +728 -0
- package/dist/config.js.map +1 -0
- package/dist/core/authStore.js +78 -0
- package/dist/core/authStore.js.map +1 -0
- package/dist/core/canonical.js +9 -0
- package/dist/core/canonical.js.map +1 -0
- package/dist/core/console-buffer.js +25 -0
- package/dist/core/console-buffer.js.map +1 -0
- package/dist/core/fallback.js +62 -0
- package/dist/core/fallback.js.map +1 -0
- package/dist/core/handler.js +174 -0
- package/dist/core/handler.js.map +1 -0
- package/dist/core/keypool.js +105 -0
- package/dist/core/keypool.js.map +1 -0
- package/dist/core/quota.js +165 -0
- package/dist/core/quota.js.map +1 -0
- package/dist/core/state.js +52 -0
- package/dist/core/state.js.map +1 -0
- package/dist/db.js +193 -0
- package/dist/db.js.map +1 -0
- package/dist/headroom/compress.js +44 -0
- package/dist/headroom/compress.js.map +1 -0
- package/dist/headroom/detect.js +108 -0
- package/dist/headroom/detect.js.map +1 -0
- package/dist/headroom/process.js +158 -0
- package/dist/headroom/process.js.map +1 -0
- package/dist/inject/caveman.js +30 -0
- package/dist/inject/caveman.js.map +1 -0
- package/dist/inject/index.js +24 -0
- package/dist/inject/index.js.map +1 -0
- package/dist/inject/ponytail.js +19 -0
- package/dist/inject/ponytail.js.map +1 -0
- package/dist/middleware/auth.js +66 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/providers/capabilities.js +246 -0
- package/dist/providers/capabilities.js.map +1 -0
- package/dist/providers/free.js +43 -0
- package/dist/providers/free.js.map +1 -0
- package/dist/providers/pricing.js +224 -0
- package/dist/providers/pricing.js.map +1 -0
- package/dist/providers/vertex.js +97 -0
- package/dist/providers/vertex.js.map +1 -0
- package/dist/routes/admin.js +622 -0
- package/dist/routes/admin.js.map +1 -0
- package/dist/routes/health.js +4 -0
- package/dist/routes/health.js.map +1 -0
- package/dist/routes/index.js +12 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/v1.js +75 -0
- package/dist/routes/v1.js.map +1 -0
- package/dist/rtk/detect.js +50 -0
- package/dist/rtk/detect.js.map +1 -0
- package/dist/rtk/filters.js +85 -0
- package/dist/rtk/filters.js.map +1 -0
- package/dist/rtk/index.js +39 -0
- package/dist/rtk/index.js.map +1 -0
- package/dist/server.js +100 -0
- package/dist/server.js.map +1 -0
- package/dist/stream/anthropic-stream.js +239 -0
- package/dist/stream/anthropic-stream.js.map +1 -0
- package/dist/stream/chunk.js +7 -0
- package/dist/stream/chunk.js.map +1 -0
- package/dist/stream/gemini-stream.js +135 -0
- package/dist/stream/gemini-stream.js.map +1 -0
- package/dist/stream/index.js +12 -0
- package/dist/stream/index.js.map +1 -0
- package/dist/stream/openai-stream.js +34 -0
- package/dist/stream/openai-stream.js.map +1 -0
- package/dist/stream/sse.js +64 -0
- package/dist/stream/sse.js.map +1 -0
- package/dist/translator/thinking.js +70 -0
- package/dist/translator/thinking.js.map +1 -0
- package/dist/translator/thinkingUnified.js +322 -0
- package/dist/translator/thinkingUnified.js.map +1 -0
- package/dist/upstream/client.js +120 -0
- package/dist/upstream/client.js.map +1 -0
- package/package.json +76 -0
- package/run.sh +27 -0
- package/src/adapters/anthropic.ts +377 -0
- package/src/adapters/gemini.ts +341 -0
- package/src/adapters/index.ts +17 -0
- package/src/adapters/openai.ts +22 -0
- package/src/cli/tray/autostart.ts +133 -0
- package/src/cli/tray/icon.ts +4 -0
- package/src/cli/tray/tray.ts +156 -0
- package/src/cli/tray/trayRuntime.ts +90 -0
- package/src/cli.ts +379 -0
- package/src/config.ts +777 -0
- package/src/core/authStore.ts +86 -0
- package/src/core/canonical.ts +93 -0
- package/src/core/console-buffer.ts +39 -0
- package/src/core/fallback.ts +116 -0
- package/src/core/handler.ts +236 -0
- package/src/core/keypool.ts +152 -0
- package/src/core/quota.ts +214 -0
- package/src/core/state.ts +65 -0
- package/src/db.ts +280 -0
- package/src/headroom/compress.ts +78 -0
- package/src/headroom/detect.ts +119 -0
- package/src/headroom/process.ts +166 -0
- package/src/inject/caveman.ts +35 -0
- package/src/inject/index.ts +46 -0
- package/src/inject/ponytail.ts +31 -0
- package/src/middleware/auth.ts +76 -0
- package/src/providers/capabilities.ts +297 -0
- package/src/providers/free.ts +53 -0
- package/src/providers/pricing.ts +261 -0
- package/src/providers/vertex.ts +117 -0
- package/src/routes/admin.ts +716 -0
- package/src/routes/health.ts +5 -0
- package/src/routes/index.ts +24 -0
- package/src/routes/v1.ts +87 -0
- package/src/rtk/detect.ts +55 -0
- package/src/rtk/filters.ts +94 -0
- package/src/rtk/index.ts +58 -0
- package/src/server.ts +108 -0
- package/src/stream/anthropic-stream.ts +310 -0
- package/src/stream/chunk.ts +46 -0
- package/src/stream/gemini-stream.ts +158 -0
- package/src/stream/index.ts +23 -0
- package/src/stream/openai-stream.ts +41 -0
- package/src/stream/sse.ts +72 -0
- package/src/translator/thinking.ts +64 -0
- package/src/translator/thinkingUnified.ts +319 -0
- package/src/upstream/client.ts +155 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified thinking normalization: extract client intent → apply provider-native format.
|
|
3
|
+
* Config-driven: thinking format/limits come from capabilities.ts, never hardcoded
|
|
4
|
+
* per-model here.
|
|
5
|
+
*
|
|
6
|
+
* aigetwey's own implementation. The one
|
|
7
|
+
* adaptation for aigetwey: there is no provider registry carrying a thinkingFormat,
|
|
8
|
+
* so resolveFormat relies on the capabilities table + the wire format alone, and
|
|
9
|
+
* FORMAT_TO_NATIVE also maps aigetwey's "anthropic" wire format. See
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
import { getCapabilitiesForModel } from "../providers/capabilities.js";
|
|
13
|
+
import { LEVEL_TO_BUDGET, budgetToLevel, effortToBudget } from "./thinking.js";
|
|
14
|
+
// Map a target wire-format to its native thinking format (when capability has none).
|
|
15
|
+
const FORMAT_TO_NATIVE = {
|
|
16
|
+
openai: "openai",
|
|
17
|
+
"openai-responses": "openai",
|
|
18
|
+
"openai-response": "openai",
|
|
19
|
+
codex: "openai",
|
|
20
|
+
claude: "claude-budget",
|
|
21
|
+
anthropic: "claude-budget",
|
|
22
|
+
gemini: "gemini-budget",
|
|
23
|
+
"gemini-cli": "gemini-budget",
|
|
24
|
+
vertex: "gemini-budget",
|
|
25
|
+
antigravity: "gemini-budget",
|
|
26
|
+
kiro: "kiro",
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Parse model-name suffix "model(value)" → { cleanModel, override }.
|
|
30
|
+
* value: level name (high) | number (8192) | auto | none. null override when absent.
|
|
31
|
+
*/
|
|
32
|
+
export function parseSuffix(model) {
|
|
33
|
+
if (typeof model !== "string")
|
|
34
|
+
return { cleanModel: model, override: null };
|
|
35
|
+
const m = model.match(/^(.*)\(([^()]+)\)\s*$/);
|
|
36
|
+
if (!m)
|
|
37
|
+
return { cleanModel: model, override: null };
|
|
38
|
+
const cleanModel = m[1].trim();
|
|
39
|
+
const raw = m[2].trim().toLowerCase();
|
|
40
|
+
if (raw === "none" || raw === "off")
|
|
41
|
+
return { cleanModel, override: { mode: "none" } };
|
|
42
|
+
if (raw === "auto")
|
|
43
|
+
return { cleanModel, override: { mode: "auto" } };
|
|
44
|
+
if (/^\d+$/.test(raw))
|
|
45
|
+
return { cleanModel, override: { mode: "budget", budget: Number(raw) } };
|
|
46
|
+
if (LEVEL_TO_BUDGET[raw] !== undefined)
|
|
47
|
+
return { cleanModel, override: { mode: "level", level: raw } };
|
|
48
|
+
return { cleanModel, override: null };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Extract unified thinking intent from a request body (post-translation, mixed shapes).
|
|
52
|
+
* Returns { mode, budget?, level? } or null when no thinking intent present.
|
|
53
|
+
*/
|
|
54
|
+
export function extractThinking(body) {
|
|
55
|
+
if (!body || typeof body !== "object")
|
|
56
|
+
return null;
|
|
57
|
+
// Claude output_config.effort (explicit) — priority over adaptive thinking
|
|
58
|
+
const oc = body.output_config?.effort;
|
|
59
|
+
if (typeof oc === "string" && oc) {
|
|
60
|
+
const e = oc.toLowerCase();
|
|
61
|
+
if (e === "none" || e === "off")
|
|
62
|
+
return { mode: "none" };
|
|
63
|
+
if (e === "auto")
|
|
64
|
+
return { mode: "auto" };
|
|
65
|
+
return { mode: "level", level: e };
|
|
66
|
+
}
|
|
67
|
+
// Claude shape
|
|
68
|
+
const t = body.thinking;
|
|
69
|
+
if (t && typeof t === "object") {
|
|
70
|
+
if (t.type === "disabled")
|
|
71
|
+
return { mode: "none" };
|
|
72
|
+
if (t.type === "adaptive" || t.type === "enabled") {
|
|
73
|
+
const budget = Number(t.budget_tokens);
|
|
74
|
+
if (Number.isFinite(budget) && budget > 0)
|
|
75
|
+
return { mode: "budget", budget };
|
|
76
|
+
return { mode: "auto" };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// OpenAI chat / Responses shape
|
|
80
|
+
const effort = body.reasoning_effort ?? (typeof body.reasoning === "object" ? body.reasoning?.effort : null);
|
|
81
|
+
if (typeof effort === "string" && effort) {
|
|
82
|
+
const e = effort.toLowerCase();
|
|
83
|
+
if (e === "none" || e === "off")
|
|
84
|
+
return { mode: "none" };
|
|
85
|
+
if (e === "auto")
|
|
86
|
+
return { mode: "auto" };
|
|
87
|
+
return { mode: "level", level: e };
|
|
88
|
+
}
|
|
89
|
+
// Gemini shape (top-level, generationConfig, or request envelope)
|
|
90
|
+
const tc = body.thinkingConfig || body.generationConfig?.thinkingConfig || body.request?.generationConfig?.thinkingConfig;
|
|
91
|
+
if (tc && typeof tc === "object") {
|
|
92
|
+
if (typeof tc.thinkingLevel === "string")
|
|
93
|
+
return { mode: "level", level: tc.thinkingLevel.toLowerCase() };
|
|
94
|
+
const tb = Number(tc.thinkingBudget);
|
|
95
|
+
if (Number.isFinite(tb)) {
|
|
96
|
+
if (tb === 0)
|
|
97
|
+
return { mode: "none" };
|
|
98
|
+
if (tb < 0)
|
|
99
|
+
return { mode: "auto" };
|
|
100
|
+
return { mode: "budget", budget: tb };
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Qwen shape
|
|
104
|
+
if (body.enable_thinking === false)
|
|
105
|
+
return { mode: "none" };
|
|
106
|
+
if (body.enable_thinking === true) {
|
|
107
|
+
const tb = Number(body.thinking_budget);
|
|
108
|
+
if (Number.isFinite(tb) && tb > 0)
|
|
109
|
+
return { mode: "budget", budget: tb };
|
|
110
|
+
return { mode: "auto" };
|
|
111
|
+
}
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Capture thinking intent from a body. Alias of extractThinking, named for clarity
|
|
116
|
+
* at the call-site where intent is snapshotted before format translation.
|
|
117
|
+
*/
|
|
118
|
+
export const captureThinking = extractThinking;
|
|
119
|
+
// Resolve thinking format: capability > derive(targetFormat).
|
|
120
|
+
function resolveFormat(targetFormat, model, provider) {
|
|
121
|
+
const caps = getCapabilitiesForModel(provider, model);
|
|
122
|
+
if (caps.thinkingFormat)
|
|
123
|
+
return caps.thinkingFormat;
|
|
124
|
+
return FORMAT_TO_NATIVE[targetFormat] || "openai";
|
|
125
|
+
}
|
|
126
|
+
// Convert unified config to a budget number (for budget-based formats).
|
|
127
|
+
function toBudget(cfg, range) {
|
|
128
|
+
let budget;
|
|
129
|
+
if (cfg.mode === "budget")
|
|
130
|
+
budget = cfg.budget;
|
|
131
|
+
else if (cfg.mode === "level")
|
|
132
|
+
budget = effortToBudget(cfg.level);
|
|
133
|
+
else if (cfg.mode === "auto")
|
|
134
|
+
return -1;
|
|
135
|
+
if (!Number.isFinite(budget))
|
|
136
|
+
return undefined;
|
|
137
|
+
if (range) {
|
|
138
|
+
if (range.min != null && budget < range.min)
|
|
139
|
+
budget = range.min;
|
|
140
|
+
if (range.max != null && budget > range.max)
|
|
141
|
+
budget = range.max;
|
|
142
|
+
}
|
|
143
|
+
return budget;
|
|
144
|
+
}
|
|
145
|
+
// Convert unified config to a discrete level string.
|
|
146
|
+
function toLevel(cfg) {
|
|
147
|
+
if (cfg.mode === "level")
|
|
148
|
+
return cfg.level ?? null;
|
|
149
|
+
if (cfg.mode === "budget")
|
|
150
|
+
return budgetToLevel(cfg.budget ?? 0) || "medium";
|
|
151
|
+
if (cfg.mode === "auto")
|
|
152
|
+
return "auto";
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
// Gemini nests thinkingConfig under generationConfig.
|
|
156
|
+
function setGeminiThinking(body, tc) {
|
|
157
|
+
const gc = body.request?.generationConfig
|
|
158
|
+
? body.request.generationConfig
|
|
159
|
+
: body.generationConfig && typeof body.generationConfig === "object"
|
|
160
|
+
? body.generationConfig
|
|
161
|
+
: (body.generationConfig = {});
|
|
162
|
+
gc.thinkingConfig = tc;
|
|
163
|
+
}
|
|
164
|
+
// Strip every known thinking field from a body (used before re-applying / when unsupported).
|
|
165
|
+
function stripAll(body) {
|
|
166
|
+
delete body.thinking;
|
|
167
|
+
delete body.reasoning_effort;
|
|
168
|
+
delete body.reasoning;
|
|
169
|
+
delete body.thinkingConfig;
|
|
170
|
+
delete body.enable_thinking;
|
|
171
|
+
delete body.thinking_budget;
|
|
172
|
+
delete body.output_config;
|
|
173
|
+
if (body.generationConfig)
|
|
174
|
+
delete body.generationConfig.thinkingConfig;
|
|
175
|
+
if (body.request?.generationConfig)
|
|
176
|
+
delete body.request.generationConfig.thinkingConfig;
|
|
177
|
+
}
|
|
178
|
+
// Apply unified thinking config to body in the resolved provider-native format.
|
|
179
|
+
function applyFormat(fmt, body, cfg, caps) {
|
|
180
|
+
const none = cfg.mode === "none";
|
|
181
|
+
const canDisable = caps.thinkingCanDisable !== false;
|
|
182
|
+
// Model cannot disable thinking → clamp "none" to minimal effort instead.
|
|
183
|
+
const eff = none && !canDisable ? { mode: "level", level: "minimal" } : cfg;
|
|
184
|
+
switch (fmt) {
|
|
185
|
+
case "openai": {
|
|
186
|
+
if (none && canDisable) {
|
|
187
|
+
body.reasoning_effort = "none";
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
const level = toLevel(eff);
|
|
191
|
+
if (level)
|
|
192
|
+
body.reasoning_effort = level === "xhigh" || level === "max" ? "high" : level;
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
case "claude-adaptive": {
|
|
196
|
+
if (none && canDisable) {
|
|
197
|
+
body.thinking = { type: "disabled" };
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
const level = toLevel(eff);
|
|
201
|
+
body.output_config = { effort: level === "xhigh" ? "high" : level };
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
case "claude-budget": {
|
|
205
|
+
if (none && canDisable) {
|
|
206
|
+
body.thinking = { type: "disabled" };
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
const budget = toBudget(eff, caps.thinkingRange);
|
|
210
|
+
body.thinking = budget === -1 ? { type: "enabled" } : { type: "enabled", budget_tokens: budget || 8192 };
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
case "gemini-level": {
|
|
214
|
+
const level = none ? "minimal" : toLevel(eff) || "high";
|
|
215
|
+
setGeminiThinking(body, { thinkingLevel: level, includeThoughts: level !== "minimal" });
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
case "gemini-budget": {
|
|
219
|
+
if (none && canDisable) {
|
|
220
|
+
setGeminiThinking(body, { thinkingBudget: 0, includeThoughts: false });
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
const budget = toBudget(eff, caps.thinkingRange);
|
|
224
|
+
setGeminiThinking(body, { thinkingBudget: budget ?? -1, includeThoughts: true });
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
case "zai": {
|
|
228
|
+
// Z.ai ignores thinking.disabled → must use enable_thinking:false to turn off.
|
|
229
|
+
if (none && canDisable) {
|
|
230
|
+
body.enable_thinking = false;
|
|
231
|
+
delete body.thinking;
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
body.thinking = { type: "enabled" };
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
case "qwen": {
|
|
238
|
+
if (none && canDisable) {
|
|
239
|
+
body.enable_thinking = false;
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
body.enable_thinking = true;
|
|
243
|
+
const budget = toBudget(eff, caps.thinkingRange);
|
|
244
|
+
if (Number.isFinite(budget) && budget > 0)
|
|
245
|
+
body.thinking_budget = budget;
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
case "deepseek": {
|
|
249
|
+
if (none && canDisable) {
|
|
250
|
+
body.thinking = { type: "disabled" };
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
body.thinking = { type: "enabled" };
|
|
254
|
+
// DeepSeek: low/medium→high, xhigh/max→max.
|
|
255
|
+
const level = toLevel(eff);
|
|
256
|
+
body.reasoning_effort = level === "xhigh" || level === "max" ? "max" : "high";
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
case "kimi": {
|
|
260
|
+
if (none && canDisable) {
|
|
261
|
+
body.thinking = { type: "disabled" };
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
const level = toLevel(eff);
|
|
265
|
+
if (level)
|
|
266
|
+
body.reasoning_effort = level === "max" ? "high" : level;
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
case "minimax": {
|
|
270
|
+
// M3 adaptive; M2.x cannot disable (handled via canDisable clamp).
|
|
271
|
+
body.thinking = { type: none && canDisable ? "disabled" : "adaptive" };
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
case "hunyuan": {
|
|
275
|
+
if (none && canDisable) {
|
|
276
|
+
body.thinking = { type: "disabled" };
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
const budget = toBudget(eff, caps.thinkingRange);
|
|
280
|
+
body.thinking = budget === -1 ? { type: "enabled" } : { type: "enabled", budget_tokens: budget || 8192 };
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
case "step": {
|
|
284
|
+
if (none && canDisable)
|
|
285
|
+
break;
|
|
286
|
+
const level = toLevel(eff);
|
|
287
|
+
if (level)
|
|
288
|
+
body.reasoning_effort = level === "xhigh" || level === "max" ? "high" : level;
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
case "kiro":
|
|
292
|
+
// Kiro thinking handled via system-tag injection elsewhere; no body field here.
|
|
293
|
+
break;
|
|
294
|
+
default:
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Public entry: normalize thinking for the resolved target format.
|
|
300
|
+
* Mutates and returns body. No-op when model has no reasoning capability.
|
|
301
|
+
* `intent` is a pre-captured config (from captureThinking on the original body);
|
|
302
|
+
* falls back to extracting from the current body when omitted.
|
|
303
|
+
*/
|
|
304
|
+
export function applyThinking(targetFormat, model, body, provider = null, intent = undefined) {
|
|
305
|
+
if (!body || typeof body !== "object")
|
|
306
|
+
return body;
|
|
307
|
+
const { cleanModel, override } = parseSuffix(model);
|
|
308
|
+
const cfg = override || intent || extractThinking(body);
|
|
309
|
+
const caps = getCapabilitiesForModel(provider, cleanModel);
|
|
310
|
+
// Model cannot reason → strip any stray thinking fields.
|
|
311
|
+
if (!caps.reasoning) {
|
|
312
|
+
stripAll(body);
|
|
313
|
+
return body;
|
|
314
|
+
}
|
|
315
|
+
if (!cfg)
|
|
316
|
+
return body;
|
|
317
|
+
const fmt = resolveFormat(targetFormat, cleanModel, provider);
|
|
318
|
+
stripAll(body);
|
|
319
|
+
applyFormat(fmt, body, cfg, caps);
|
|
320
|
+
return body;
|
|
321
|
+
}
|
|
322
|
+
//# sourceMappingURL=thinkingUnified.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thinkingUnified.js","sourceRoot":"","sources":["../../src/translator/thinkingUnified.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upstream provider client. Translates a canonical request into the provider's
|
|
3
|
+
* native format, calls it, and returns either a parsed canonical response
|
|
4
|
+
* (non-stream) or the raw byte stream (stream — consumed in Phase 3).
|
|
5
|
+
*/
|
|
6
|
+
import { request } from "undici";
|
|
7
|
+
import { adapterFor } from "../adapters/index.js";
|
|
8
|
+
import { applyThinking } from "../translator/thinkingUnified.js";
|
|
9
|
+
/**
|
|
10
|
+
* Retryable = an availability problem another key/provider could clear: rate
|
|
11
|
+
* limits (429), server errors (5xx), network/timeout (no status). Non-retryable
|
|
12
|
+
* = the request itself is bad (400/401/403/404/422) — falling back just wastes
|
|
13
|
+
* time and spams other providers.
|
|
14
|
+
*/
|
|
15
|
+
function classifyRetryable(status) {
|
|
16
|
+
if (status === undefined)
|
|
17
|
+
return true; // network error / timeout / abort
|
|
18
|
+
if (status === 429)
|
|
19
|
+
return true;
|
|
20
|
+
if (status >= 500)
|
|
21
|
+
return true;
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
function buildHeaders(provider, key) {
|
|
25
|
+
const headers = {
|
|
26
|
+
"content-type": "application/json",
|
|
27
|
+
...(provider.headers ?? {}),
|
|
28
|
+
};
|
|
29
|
+
if (provider.format === "anthropic") {
|
|
30
|
+
if (key)
|
|
31
|
+
headers["x-api-key"] = key;
|
|
32
|
+
headers["anthropic-version"] ??= "2023-06-01";
|
|
33
|
+
}
|
|
34
|
+
else if (provider.format === "gemini") {
|
|
35
|
+
if (key)
|
|
36
|
+
headers["x-goog-api-key"] = key;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
if (key)
|
|
40
|
+
headers["authorization"] = `Bearer ${key}`;
|
|
41
|
+
}
|
|
42
|
+
return headers;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* OpenAI/Anthropic use a fixed path on base_url; Gemini puts the model and
|
|
46
|
+
* stream mode in the path (:generateContent | :streamGenerateContent?alt=sse).
|
|
47
|
+
*/
|
|
48
|
+
function buildUrl(provider, model, stream) {
|
|
49
|
+
const base = provider.base_url.replace(/\/$/, "");
|
|
50
|
+
if (provider.format === "gemini") {
|
|
51
|
+
const method = stream ? "streamGenerateContent?alt=sse" : "generateContent";
|
|
52
|
+
return `${base}/models/${encodeURIComponent(model)}:${method}`;
|
|
53
|
+
}
|
|
54
|
+
return base + (provider.format === "anthropic" ? "/messages" : "/chat/completions");
|
|
55
|
+
}
|
|
56
|
+
function buildBody(provider, req, model, stream, thinkingIntent) {
|
|
57
|
+
const adapter = adapterFor(provider.format);
|
|
58
|
+
const upstreamReq = { ...req, model, stream };
|
|
59
|
+
const out = adapter.requestFromCanonical(upstreamReq);
|
|
60
|
+
// Normalize thinking into THIS provider's native format, keyed by the upstream
|
|
61
|
+
// model's capabilities. No-op for non-reasoning models. Runs per-attempt so each
|
|
62
|
+
// provider in a fallback chain gets the right shape.
|
|
63
|
+
applyThinking(provider.format, model, out, provider.id, thinkingIntent);
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
export async function callUpstream(provider, req, model, opts) {
|
|
67
|
+
const url = buildUrl(provider, model, opts.stream);
|
|
68
|
+
const headers = buildHeaders(provider, opts.key);
|
|
69
|
+
const body = buildBody(provider, req, model, opts.stream, opts.thinkingIntent);
|
|
70
|
+
let res;
|
|
71
|
+
try {
|
|
72
|
+
res = await request(url, {
|
|
73
|
+
method: "POST",
|
|
74
|
+
headers,
|
|
75
|
+
body: JSON.stringify(body),
|
|
76
|
+
signal: opts.signal,
|
|
77
|
+
// providers can be slow to first byte on long generations
|
|
78
|
+
headersTimeout: 600_000,
|
|
79
|
+
bodyTimeout: 600_000,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
const err = new Error(`upstream ${provider.id} request failed: ${e.message}`);
|
|
84
|
+
err.retryable = true;
|
|
85
|
+
throw err;
|
|
86
|
+
}
|
|
87
|
+
if (res.statusCode >= 400) {
|
|
88
|
+
const text = await res.body.text();
|
|
89
|
+
const err = new Error(`upstream ${provider.id} returned ${res.statusCode}`);
|
|
90
|
+
err.status = res.statusCode;
|
|
91
|
+
err.body = text;
|
|
92
|
+
err.retryable = classifyRetryable(res.statusCode);
|
|
93
|
+
throw err;
|
|
94
|
+
}
|
|
95
|
+
if (opts.stream)
|
|
96
|
+
return { stream: true, body: res.body };
|
|
97
|
+
const json = await res.body.json();
|
|
98
|
+
const adapter = adapterFor(provider.format);
|
|
99
|
+
return { stream: false, response: adapter.responseToCanonical(json) };
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Lightweight connectivity check: GET {base}/models with the provider's auth.
|
|
103
|
+
* Any HTTP status means the host is reachable; 2xx means the key is accepted.
|
|
104
|
+
* Never throws — returns a structured result for the dashboard.
|
|
105
|
+
*/
|
|
106
|
+
export async function pingProvider(provider, key) {
|
|
107
|
+
const base = provider.base_url.replace(/\/$/, "");
|
|
108
|
+
const url = `${base}/models`;
|
|
109
|
+
const headers = buildHeaders(provider, key);
|
|
110
|
+
try {
|
|
111
|
+
const res = await request(url, { method: "GET", headers, headersTimeout: 10_000, bodyTimeout: 10_000 });
|
|
112
|
+
await res.body.dump();
|
|
113
|
+
return { reachable: true, status: res.statusCode, ok: res.statusCode >= 200 && res.statusCode < 300 };
|
|
114
|
+
}
|
|
115
|
+
catch (e) {
|
|
116
|
+
return { reachable: false, ok: false, error: e.message };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
export { buildHeaders, buildUrl };
|
|
120
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/upstream/client.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "aigetwey",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Personal AI gateway — route, translate and track requests across Anthropic / OpenAI / Gemini-compatible providers, with a built-in dashboard.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"ai",
|
|
8
|
+
"gateway",
|
|
9
|
+
"llm",
|
|
10
|
+
"proxy",
|
|
11
|
+
"anthropic",
|
|
12
|
+
"openai",
|
|
13
|
+
"gemini",
|
|
14
|
+
"router",
|
|
15
|
+
"claude",
|
|
16
|
+
"dashboard"
|
|
17
|
+
],
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"author": "xk1ko <221650117+xk1ko@users.noreply.github.com>",
|
|
20
|
+
"homepage": "https://github.com/xk1ko/aigetwey#readme",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/xk1ko/aigetwey.git"
|
|
24
|
+
},
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/xk1ko/aigetwey/issues"
|
|
27
|
+
},
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=22"
|
|
30
|
+
},
|
|
31
|
+
"bin": {
|
|
32
|
+
"aigetwey": "./dist/cli.js"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"src",
|
|
37
|
+
"dashboard",
|
|
38
|
+
"assets",
|
|
39
|
+
"config.example.yaml",
|
|
40
|
+
"tsconfig.json",
|
|
41
|
+
"run.sh",
|
|
42
|
+
"README.md",
|
|
43
|
+
"CHANGELOG.md",
|
|
44
|
+
"LICENSE"
|
|
45
|
+
],
|
|
46
|
+
"scripts": {
|
|
47
|
+
"dev": "tsx watch src/server.ts",
|
|
48
|
+
"start": "node dist/server.js",
|
|
49
|
+
"run:all": "tsx src/cli.ts",
|
|
50
|
+
"build": "tsc -p tsconfig.json",
|
|
51
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
52
|
+
"test": "vitest run",
|
|
53
|
+
"test:watch": "vitest",
|
|
54
|
+
"prepublishOnly": "npm run build && npm --prefix dashboard run build"
|
|
55
|
+
},
|
|
56
|
+
"publishConfig": {
|
|
57
|
+
"access": "public"
|
|
58
|
+
},
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"@fastify/http-proxy": "^11.5.0",
|
|
61
|
+
"fastify": "^5.2.0",
|
|
62
|
+
"undici": "^7.2.0",
|
|
63
|
+
"yaml": "^2.6.1",
|
|
64
|
+
"zod": "^3.24.1"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@types/node": "^22.10.0",
|
|
68
|
+
"tsx": "^4.19.2",
|
|
69
|
+
"typescript": "^5.7.2",
|
|
70
|
+
"vitest": "^2.1.8"
|
|
71
|
+
},
|
|
72
|
+
"allowScripts": {
|
|
73
|
+
"esbuild@0.28.1": true,
|
|
74
|
+
"esbuild@0.21.5": true
|
|
75
|
+
}
|
|
76
|
+
}
|
package/run.sh
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# aigetwey — bring up gateway + dashboard with one command.
|
|
3
|
+
# ./run.sh
|
|
4
|
+
# Built (production): npm run build && npm --prefix dashboard run build && ./run.sh
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
cd "$(dirname "$0")"
|
|
7
|
+
|
|
8
|
+
# zero-config local defaults (override by exporting before running).
|
|
9
|
+
export AIGETWEY_ADMIN_PASSWORD="${AIGETWEY_ADMIN_PASSWORD:-123456}"
|
|
10
|
+
# stable secret so the dashboard login cookie survives restarts.
|
|
11
|
+
export SESSION_SECRET="${SESSION_SECRET:-aigetwey-local-session-secret}"
|
|
12
|
+
|
|
13
|
+
# seed a working config.yaml on first run (gitignored; holds keys).
|
|
14
|
+
if [ ! -f config.yaml ]; then
|
|
15
|
+
cp config.example.yaml config.yaml
|
|
16
|
+
echo " seeded config.yaml from the example — edit it to add providers."
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
# one-time dependency install.
|
|
20
|
+
[ -d node_modules ] || npm install
|
|
21
|
+
[ -d dashboard/node_modules ] || npm install --prefix dashboard
|
|
22
|
+
|
|
23
|
+
if [ -f dist/cli.js ]; then
|
|
24
|
+
exec node dist/cli.js
|
|
25
|
+
else
|
|
26
|
+
exec npx tsx src/cli.ts
|
|
27
|
+
fi
|