ai-zero-token 1.0.7 → 1.0.9
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 +8 -0
- package/README.md +146 -395
- package/README.zh-CN.md +258 -0
- package/dist/cli/commands/serve.js +1 -0
- package/dist/core/providers/http-client.js +1 -1
- package/dist/core/services/auth-service.js +98 -7
- package/dist/core/services/config-service.js +15 -3
- package/dist/core/services/image-service.js +2 -7
- package/dist/core/services/version-service.js +18 -13
- package/dist/core/store/settings-store.js +6 -0
- package/dist/server/admin-page.js +1018 -103
- package/dist/server/app.js +68 -2
- package/dist/server/index.js +17 -2
- package/package.json +2 -1
package/dist/server/app.js
CHANGED
|
@@ -4,6 +4,7 @@ import Fastify from "fastify";
|
|
|
4
4
|
import cors from "@fastify/cors";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { createGatewayContext } from "../core/context.js";
|
|
7
|
+
import { requestText } from "../core/providers/http-client.js";
|
|
7
8
|
import { renderAdminPage } from "./admin-page.js";
|
|
8
9
|
const inputPartSchema = z.object({
|
|
9
10
|
type: z.string().optional(),
|
|
@@ -72,8 +73,18 @@ const settingsUpdateSchema = z.object({
|
|
|
72
73
|
enabled: z.boolean(),
|
|
73
74
|
url: z.string().optional(),
|
|
74
75
|
noProxy: z.string().optional()
|
|
76
|
+
}).optional(),
|
|
77
|
+
autoSwitch: z.object({
|
|
78
|
+
enabled: z.boolean()
|
|
75
79
|
}).optional()
|
|
76
80
|
});
|
|
81
|
+
const proxyTestSchema = z.object({
|
|
82
|
+
networkProxy: z.object({
|
|
83
|
+
enabled: z.boolean(),
|
|
84
|
+
url: z.string().optional(),
|
|
85
|
+
noProxy: z.string().optional()
|
|
86
|
+
})
|
|
87
|
+
});
|
|
77
88
|
const profileActionSchema = z.object({
|
|
78
89
|
profileId: z.string().min(1)
|
|
79
90
|
});
|
|
@@ -416,7 +427,8 @@ function getErrorStatusCode(error) {
|
|
|
416
427
|
}
|
|
417
428
|
function createApp(params) {
|
|
418
429
|
const app = Fastify({
|
|
419
|
-
logger: false
|
|
430
|
+
logger: false,
|
|
431
|
+
bodyLimit: params?.bodyLimit
|
|
420
432
|
});
|
|
421
433
|
const ctx = createGatewayContext();
|
|
422
434
|
void app.register(cors, {
|
|
@@ -550,7 +562,8 @@ function createApp(params) {
|
|
|
550
562
|
}
|
|
551
563
|
await ctx.authService.activateProfile(parsed.data.profileId);
|
|
552
564
|
await ctx.authService.syncActiveProfileQuota("openai-codex", {
|
|
553
|
-
suppressErrors: true
|
|
565
|
+
suppressErrors: true,
|
|
566
|
+
skipAutoSwitch: true
|
|
554
567
|
});
|
|
555
568
|
return buildAdminConfig(request);
|
|
556
569
|
});
|
|
@@ -648,8 +661,61 @@ function createApp(params) {
|
|
|
648
661
|
if (parsed.data.networkProxy) {
|
|
649
662
|
await ctx.configService.setNetworkProxy(parsed.data.networkProxy);
|
|
650
663
|
}
|
|
664
|
+
if (parsed.data.autoSwitch) {
|
|
665
|
+
await ctx.configService.setAutoSwitch(parsed.data.autoSwitch);
|
|
666
|
+
}
|
|
651
667
|
return buildAdminConfig(request);
|
|
652
668
|
});
|
|
669
|
+
app.post("/_gateway/admin/settings/proxy-test", async (request, reply) => {
|
|
670
|
+
const parsed = proxyTestSchema.safeParse(request.body);
|
|
671
|
+
if (!parsed.success) {
|
|
672
|
+
reply.code(400);
|
|
673
|
+
return {
|
|
674
|
+
error: {
|
|
675
|
+
type: "validation_error",
|
|
676
|
+
message: parsed.error.issues[0]?.message ?? "\u8BF7\u6C42\u4F53\u683C\u5F0F\u9519\u8BEF"
|
|
677
|
+
}
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
const proxy = {
|
|
681
|
+
enabled: parsed.data.networkProxy.enabled,
|
|
682
|
+
url: parsed.data.networkProxy.url?.trim() ?? "",
|
|
683
|
+
noProxy: parsed.data.networkProxy.noProxy?.trim() || "localhost,127.0.0.1,::1"
|
|
684
|
+
};
|
|
685
|
+
if (proxy.enabled && !proxy.url) {
|
|
686
|
+
reply.code(400);
|
|
687
|
+
return {
|
|
688
|
+
error: {
|
|
689
|
+
type: "validation_error",
|
|
690
|
+
message: "\u542F\u7528\u4EE3\u7406\u65F6\u5FC5\u987B\u586B\u5199\u4EE3\u7406\u5730\u5740\u3002"
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
const startedAt = performance.now();
|
|
695
|
+
try {
|
|
696
|
+
const response = await requestText({
|
|
697
|
+
method: "GET",
|
|
698
|
+
url: "https://chatgpt.com/",
|
|
699
|
+
timeoutMs: 8e3,
|
|
700
|
+
proxyOverride: proxy
|
|
701
|
+
});
|
|
702
|
+
return {
|
|
703
|
+
ok: response.status >= 200 && response.status < 500,
|
|
704
|
+
status: response.status,
|
|
705
|
+
elapsedMs: Math.round(performance.now() - startedAt),
|
|
706
|
+
target: "https://chatgpt.com/",
|
|
707
|
+
transport: response.transport
|
|
708
|
+
};
|
|
709
|
+
} catch (error) {
|
|
710
|
+
reply.code(502);
|
|
711
|
+
return {
|
|
712
|
+
error: {
|
|
713
|
+
type: "proxy_test_failed",
|
|
714
|
+
message: error instanceof Error ? error.message : String(error)
|
|
715
|
+
}
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
});
|
|
653
719
|
app.get("/v1/models", async () => ({
|
|
654
720
|
object: "list",
|
|
655
721
|
data: (await ctx.modelService.listModels()).map((model) => ({
|
package/dist/server/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { ConfigService } from "../core/services/config-service.js";
|
|
3
3
|
import { createApp } from "./app.js";
|
|
4
|
+
const DEFAULT_BODY_LIMIT_MB = 32;
|
|
4
5
|
function resolveCorsOrigin() {
|
|
5
6
|
const raw = process.env.AZT_CORS_ORIGIN?.trim();
|
|
6
7
|
if (!raw || raw === "*") {
|
|
@@ -9,9 +10,22 @@ function resolveCorsOrigin() {
|
|
|
9
10
|
const values = raw.split(",").map((item) => item.trim()).filter(Boolean);
|
|
10
11
|
return values.length <= 1 ? values[0] ?? true : values;
|
|
11
12
|
}
|
|
13
|
+
function resolveBodyLimitBytes() {
|
|
14
|
+
const raw = process.env.AZT_BODY_LIMIT_MB?.trim();
|
|
15
|
+
if (!raw) {
|
|
16
|
+
return DEFAULT_BODY_LIMIT_MB * 1024 * 1024;
|
|
17
|
+
}
|
|
18
|
+
const value = Number(raw);
|
|
19
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
20
|
+
return DEFAULT_BODY_LIMIT_MB * 1024 * 1024;
|
|
21
|
+
}
|
|
22
|
+
return Math.floor(value * 1024 * 1024);
|
|
23
|
+
}
|
|
12
24
|
async function startServer(params) {
|
|
25
|
+
const bodyLimit = resolveBodyLimitBytes();
|
|
13
26
|
const app = createApp({
|
|
14
|
-
corsOrigin: resolveCorsOrigin()
|
|
27
|
+
corsOrigin: resolveCorsOrigin(),
|
|
28
|
+
bodyLimit
|
|
15
29
|
});
|
|
16
30
|
const configService = new ConfigService();
|
|
17
31
|
const defaults = await configService.getServerConfig();
|
|
@@ -25,7 +39,8 @@ async function startServer(params) {
|
|
|
25
39
|
app,
|
|
26
40
|
host,
|
|
27
41
|
port,
|
|
28
|
-
corsOrigin: process.env.AZT_CORS_ORIGIN?.trim() || "*"
|
|
42
|
+
corsOrigin: process.env.AZT_CORS_ORIGIN?.trim() || "*",
|
|
43
|
+
bodyLimit
|
|
29
44
|
};
|
|
30
45
|
}
|
|
31
46
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-zero-token",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "Local-first OpenAI-compatible AI CLI and gateway with Codex OAuth, multi-account management, and gpt-image-2 image generation/editing.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
"CHANGELOG.md",
|
|
61
61
|
"docs/API_USAGE.md",
|
|
62
62
|
"README.md",
|
|
63
|
+
"README.zh-CN.md",
|
|
63
64
|
"package.json"
|
|
64
65
|
]
|
|
65
66
|
}
|