@jsonstudio/rcc 0.89.873 → 0.89.932
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.md +44 -0
- package/dist/build-info.js +2 -2
- package/dist/providers/core/runtime/gemini-cli-http-provider.js +15 -7
- package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -1
- package/dist/providers/core/runtime/responses-provider.js +17 -19
- package/dist/providers/core/runtime/responses-provider.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/credentials-handler.d.ts +3 -0
- package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js +138 -0
- package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js.map +1 -0
- package/dist/server/runtime/http-server/daemon-admin/providers-handler.d.ts +3 -0
- package/dist/server/runtime/http-server/daemon-admin/providers-handler.js +166 -0
- package/dist/server/runtime/http-server/daemon-admin/providers-handler.js.map +1 -0
- package/dist/server/runtime/http-server/daemon-admin/quota-handler.d.ts +3 -0
- package/dist/server/runtime/http-server/daemon-admin/quota-handler.js +109 -0
- package/dist/server/runtime/http-server/daemon-admin/quota-handler.js.map +1 -0
- package/dist/server/runtime/http-server/daemon-admin/status-handler.d.ts +3 -0
- package/dist/server/runtime/http-server/daemon-admin/status-handler.js +43 -0
- package/dist/server/runtime/http-server/daemon-admin/status-handler.js.map +1 -0
- package/dist/server/runtime/http-server/daemon-admin-routes.d.ts +19 -0
- package/dist/server/runtime/http-server/daemon-admin-routes.js +27 -0
- package/dist/server/runtime/http-server/daemon-admin-routes.js.map +1 -0
- package/dist/server/runtime/http-server/index.d.ts +5 -0
- package/dist/server/runtime/http-server/index.js +34 -1
- package/dist/server/runtime/http-server/index.js.map +1 -1
- package/dist/server/runtime/http-server/request-executor.d.ts +3 -0
- package/dist/server/runtime/http-server/request-executor.js +68 -2
- package/dist/server/runtime/http-server/request-executor.js.map +1 -1
- package/dist/server/runtime/http-server/routes.d.ts +3 -0
- package/dist/server/runtime/http-server/routes.js +12 -0
- package/dist/server/runtime/http-server/routes.js.map +1 -1
- package/package.json +4 -3
- package/scripts/analyze-codex-error-failures.mjs +4 -2
- package/scripts/analyze-usage-estimate.mjs +240 -0
- package/scripts/tests/apply-patch-loop.mjs +266 -7
- package/scripts/tests/exec-command-loop.mjs +165 -0
- package/scripts/tool-classification-report.ts +281 -0
- package/scripts/verification/samples/openai-chat-list-local-files.json +1 -1
- package/scripts/verify-codex-error-samples.mjs +4 -1
- package/scripts/verify-e2e-toolcall.mjs +52 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { isLocalRequest } from '../daemon-admin-routes.js';
|
|
2
|
+
import { loadProviderConfigsV2 } from '../../../../config/provider-v2-loader.js';
|
|
3
|
+
export function registerProviderRoutes(app, options) {
|
|
4
|
+
app.get('/providers/runtimes', (req, res) => {
|
|
5
|
+
if (!isLocalRequest(req)) {
|
|
6
|
+
res.status(403).json({ error: { message: 'forbidden', code: 'forbidden' } });
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
try {
|
|
10
|
+
const artifacts = options.getVirtualRouterArtifacts();
|
|
11
|
+
const targetRuntime = artifacts?.targetRuntime ?? {};
|
|
12
|
+
const items = [];
|
|
13
|
+
for (const [runtimeKey, runtime] of Object.entries(targetRuntime)) {
|
|
14
|
+
const providerKey = typeof runtime.providerKey === 'string'
|
|
15
|
+
? runtime.providerKey
|
|
16
|
+
: runtimeKey;
|
|
17
|
+
const family = typeof runtime.providerFamily === 'string'
|
|
18
|
+
? runtime.providerFamily
|
|
19
|
+
: undefined;
|
|
20
|
+
const protocol = typeof runtime.providerProtocol === 'string'
|
|
21
|
+
? runtime.providerProtocol
|
|
22
|
+
: undefined;
|
|
23
|
+
const series = typeof runtime.series === 'string'
|
|
24
|
+
? runtime.series
|
|
25
|
+
: undefined;
|
|
26
|
+
items.push({
|
|
27
|
+
providerKey,
|
|
28
|
+
runtimeKey,
|
|
29
|
+
family,
|
|
30
|
+
protocol,
|
|
31
|
+
series,
|
|
32
|
+
enabled: true
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
res.status(200).json(items);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
39
|
+
res.status(500).json({ error: { message } });
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
// Config V2 Provider 视图:基于 ~/.routecodex/provider/*/config.v2.json 的声明性配置。
|
|
43
|
+
app.get('/config/providers/v2', async (req, res) => {
|
|
44
|
+
if (!isLocalRequest(req)) {
|
|
45
|
+
res.status(403).json({ error: { message: 'forbidden', code: 'forbidden' } });
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const configs = await loadProviderConfigsV2();
|
|
50
|
+
const items = Object.values(configs).map((cfg) => {
|
|
51
|
+
const provider = cfg.provider;
|
|
52
|
+
const family = typeof provider.providerType === 'string'
|
|
53
|
+
? provider.providerType
|
|
54
|
+
: undefined;
|
|
55
|
+
const protocol = typeof provider.compatibilityProfile === 'string'
|
|
56
|
+
? provider.compatibilityProfile
|
|
57
|
+
: undefined;
|
|
58
|
+
const enabled = typeof provider.enabled === 'boolean'
|
|
59
|
+
? provider.enabled
|
|
60
|
+
: true;
|
|
61
|
+
const defaultModels = extractDefaultModels(provider);
|
|
62
|
+
const credentialsRef = extractCredentialsRef(provider);
|
|
63
|
+
return {
|
|
64
|
+
id: cfg.providerId,
|
|
65
|
+
family,
|
|
66
|
+
protocol,
|
|
67
|
+
enabled,
|
|
68
|
+
defaultModels,
|
|
69
|
+
credentialsRef,
|
|
70
|
+
version: cfg.version
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
res.status(200).json(items);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
77
|
+
res.status(500).json({ error: { message } });
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
app.get('/config/providers/v2/:id', async (req, res) => {
|
|
81
|
+
if (!isLocalRequest(req)) {
|
|
82
|
+
res.status(403).json({ error: { message: 'forbidden', code: 'forbidden' } });
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const id = String(req.params.id || '').trim();
|
|
86
|
+
if (!id) {
|
|
87
|
+
res.status(400).json({ error: { message: 'id is required' } });
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const configs = await loadProviderConfigsV2();
|
|
92
|
+
const cfg = configs[id];
|
|
93
|
+
if (!cfg) {
|
|
94
|
+
res.status(404).json({ error: { message: 'provider config not found', code: 'not_found' } });
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const provider = scrubProviderConfig(cfg.provider);
|
|
98
|
+
res.status(200).json({
|
|
99
|
+
id: cfg.providerId,
|
|
100
|
+
version: cfg.version,
|
|
101
|
+
provider
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
106
|
+
res.status(500).json({ error: { message } });
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
app.get('/config/providers/v2/:id/preview-route', (req, res) => {
|
|
110
|
+
if (!isLocalRequest(req)) {
|
|
111
|
+
res.status(403).json({ error: { message: 'forbidden', code: 'forbidden' } });
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const id = String(req.params.id || '').trim();
|
|
115
|
+
if (!id) {
|
|
116
|
+
res.status(400).json({ error: { message: 'id is required' } });
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
res.status(200).json({
|
|
120
|
+
id,
|
|
121
|
+
route: null,
|
|
122
|
+
series: null,
|
|
123
|
+
description: [
|
|
124
|
+
'Route preview is not yet implemented for Config V2; virtual router builder does not expose a stable description API.'
|
|
125
|
+
]
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function extractDefaultModels(provider) {
|
|
130
|
+
const modelsNode = provider.models;
|
|
131
|
+
if (!modelsNode || typeof modelsNode !== 'object' || Array.isArray(modelsNode)) {
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
const keys = Object.keys(modelsNode);
|
|
135
|
+
return keys.length ? keys : undefined;
|
|
136
|
+
}
|
|
137
|
+
function extractCredentialsRef(provider) {
|
|
138
|
+
const auth = provider.auth;
|
|
139
|
+
if (!auth || typeof auth !== 'object' || Array.isArray(auth)) {
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
const entries = auth.entries;
|
|
143
|
+
if (!Array.isArray(entries) || entries.length === 0) {
|
|
144
|
+
return undefined;
|
|
145
|
+
}
|
|
146
|
+
const first = entries[0];
|
|
147
|
+
if (typeof first.tokenFile === 'string' && first.tokenFile.trim()) {
|
|
148
|
+
return first.tokenFile.trim();
|
|
149
|
+
}
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
function scrubProviderConfig(provider) {
|
|
153
|
+
const clone = { ...provider };
|
|
154
|
+
const auth = clone.auth;
|
|
155
|
+
if (auth && typeof auth === 'object' && !Array.isArray(auth)) {
|
|
156
|
+
const safeAuth = { ...auth };
|
|
157
|
+
// 删除潜在的敏感字段(目前 v2 配置中一般不存在这些字段,此处为防御性实现)。
|
|
158
|
+
delete safeAuth.apiKey;
|
|
159
|
+
delete safeAuth.api_key;
|
|
160
|
+
delete safeAuth.clientSecret;
|
|
161
|
+
delete safeAuth.secret;
|
|
162
|
+
clone.auth = safeAuth;
|
|
163
|
+
}
|
|
164
|
+
return clone;
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=providers-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providers-handler.js","sourceRoot":"","sources":["../../../../../src/server/runtime/http-server/daemon-admin/providers-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { isLocalRequest } from '../daemon-admin-routes.js';
|
|
2
|
+
function getQuotaModule(options) {
|
|
3
|
+
const daemon = options.getManagerDaemon();
|
|
4
|
+
if (!daemon) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
const mod = typeof daemon.getModule === 'function' ? daemon.getModule('quota') : undefined;
|
|
8
|
+
if (!mod) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
return mod;
|
|
12
|
+
}
|
|
13
|
+
export function registerQuotaRoutes(app, options) {
|
|
14
|
+
app.get('/quota/summary', (req, res) => {
|
|
15
|
+
if (!isLocalRequest(req)) {
|
|
16
|
+
res.status(403).json({ error: { message: 'forbidden', code: 'forbidden' } });
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const quotaModule = getQuotaModule(options);
|
|
21
|
+
const snapshot = quotaModule ? quotaModule.getRawSnapshot() : {};
|
|
22
|
+
const records = Object.entries(snapshot).map(([key, value]) => ({
|
|
23
|
+
key,
|
|
24
|
+
remainingFraction: value.remainingFraction,
|
|
25
|
+
resetAt: value.resetAt ?? null,
|
|
26
|
+
fetchedAt: value.fetchedAt
|
|
27
|
+
}));
|
|
28
|
+
res.status(200).json({
|
|
29
|
+
updatedAt: Date.now(),
|
|
30
|
+
records
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
35
|
+
res.status(500).json({ error: { message } });
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
app.get('/quota/runtime', (req, res) => {
|
|
39
|
+
if (!isLocalRequest(req)) {
|
|
40
|
+
res.status(403).json({ error: { message: 'forbidden', code: 'forbidden' } });
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const runtimeKey = typeof req.query.runtimeKey === 'string' ? req.query.runtimeKey : undefined;
|
|
44
|
+
const providerKey = typeof req.query.providerKey === 'string' ? req.query.providerKey : undefined;
|
|
45
|
+
try {
|
|
46
|
+
const quotaModule = getQuotaModule(options);
|
|
47
|
+
const snapshot = quotaModule ? quotaModule.getRawSnapshot() : {};
|
|
48
|
+
// 当前仅针对 antigravity 语义;snapshot 键格式为 "antigravity://alias/modelId"
|
|
49
|
+
const items = [];
|
|
50
|
+
for (const [key, record] of Object.entries(snapshot)) {
|
|
51
|
+
const parsed = parseAntigravityKey(key);
|
|
52
|
+
if (!parsed) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (runtimeKey && !runtimeKey.includes(parsed.alias)) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (providerKey && !providerKey.includes(parsed.alias)) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
items.push({
|
|
62
|
+
key,
|
|
63
|
+
alias: parsed.alias,
|
|
64
|
+
modelId: parsed.modelId,
|
|
65
|
+
remainingFraction: record.remainingFraction,
|
|
66
|
+
resetAt: record.resetAt,
|
|
67
|
+
fetchedAt: record.fetchedAt
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
res.status(200).json({
|
|
71
|
+
runtimeKey: runtimeKey ?? null,
|
|
72
|
+
providerKey: providerKey ?? null,
|
|
73
|
+
items
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
78
|
+
res.status(500).json({ error: { message } });
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
app.get('/quota/cooldowns', (req, res) => {
|
|
82
|
+
if (!isLocalRequest(req)) {
|
|
83
|
+
res.status(403).json({ error: { message: 'forbidden', code: 'forbidden' } });
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// 目前 VirtualRouter 的 series cooldown 状态未通过稳定 API 暴露;
|
|
87
|
+
// 为避免与核心路由实现交叉,先返回空列表,占位以便前端视图对接。
|
|
88
|
+
res.status(200).json([]);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
function parseAntigravityKey(key) {
|
|
92
|
+
// 形如 "antigravity://alias/modelId"
|
|
93
|
+
const prefix = 'antigravity://';
|
|
94
|
+
if (!key.startsWith(prefix)) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
const rest = key.slice(prefix.length);
|
|
98
|
+
const idx = rest.indexOf('/');
|
|
99
|
+
if (idx <= 0) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
const alias = rest.slice(0, idx);
|
|
103
|
+
const modelId = rest.slice(idx + 1);
|
|
104
|
+
if (!alias || !modelId) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
return { alias, modelId };
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=quota-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quota-handler.js","sourceRoot":"","sources":["../../../../../src/server/runtime/http-server/daemon-admin/quota-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { isLocalRequest } from '../daemon-admin-routes.js';
|
|
2
|
+
export function registerStatusRoutes(app, options) {
|
|
3
|
+
app.get('/daemon/status', (req, res) => {
|
|
4
|
+
if (!isLocalRequest(req)) {
|
|
5
|
+
res.status(403).json({ error: { message: 'forbidden', code: 'forbidden' } });
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
const manager = options.getManagerDaemon();
|
|
9
|
+
const modules = [];
|
|
10
|
+
if (manager) {
|
|
11
|
+
// 当前 ManagerDaemon 没有统一的 introspection 接口,这里仅基于已知 id 做轻量推断。
|
|
12
|
+
const knownModuleIds = ['token', 'quota', 'health', 'routing'];
|
|
13
|
+
for (const id of knownModuleIds) {
|
|
14
|
+
const mod = typeof manager.getModule === 'function' ? manager.getModule(id) : undefined;
|
|
15
|
+
if (!mod) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
const base = { id, status: 'running' };
|
|
19
|
+
if (id === 'token') {
|
|
20
|
+
// TokenManagerModule 暴露 isLeader 字段;但出于类型约束,我们只做 best-effort 读取。
|
|
21
|
+
const anyMod = mod;
|
|
22
|
+
if (anyMod.isLeader === true) {
|
|
23
|
+
base.status = 'leader';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
modules.push(base);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const uptimeSec = process.uptime();
|
|
30
|
+
const version = String(process.env.ROUTECODEX_VERSION || 'dev');
|
|
31
|
+
res.status(200).json({
|
|
32
|
+
ok: true,
|
|
33
|
+
serverId: options.getServerId(),
|
|
34
|
+
version,
|
|
35
|
+
uptimeSec,
|
|
36
|
+
manager: {
|
|
37
|
+
active: Boolean(manager),
|
|
38
|
+
modules
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=status-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-handler.js","sourceRoot":"","sources":["../../../../../src/server/runtime/http-server/daemon-admin/status-handler.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAQ3D,MAAM,UAAU,oBAAoB,CAAC,GAAgB,EAAE,OAAgC;IACrF,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;QACxD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;YAC7E,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,OAAO,CAAC,gBAAgB,EAIhC,CAAC;QACT,MAAM,OAAO,GAAuB,EAAE,CAAC;QAEvC,IAAI,OAAO,EAAE,CAAC;YACZ,4DAA4D;YAC5D,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;YAC/D,KAAK,MAAM,EAAE,IAAI,cAAc,EAAE,CAAC;gBAChC,MAAM,GAAG,GAAG,OAAO,OAAO,CAAC,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBACxF,IAAI,CAAC,GAAG,EAAE,CAAC;oBACT,SAAS;gBACX,CAAC;gBACD,MAAM,IAAI,GAAqB,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;gBACzD,IAAI,EAAE,KAAK,OAAO,EAAE,CAAC;oBACnB,iEAAiE;oBACjE,MAAM,MAAM,GAAG,GAAwC,CAAC;oBACxD,IAAI,MAAM,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;wBAC7B,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;oBACzB,CAAC;gBACH,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,KAAK,CAAC,CAAC;QAEhE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,EAAE,EAAE,IAAI;YACR,QAAQ,EAAE,OAAO,CAAC,WAAW,EAAE;YAC/B,OAAO;YACP,SAAS;YACT,OAAO,EAAE;gBACP,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC;gBACxB,OAAO;aACR;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Application, Request, Response } from 'express';
|
|
2
|
+
export interface DaemonAdminRouteOptions {
|
|
3
|
+
app: Application;
|
|
4
|
+
/**
|
|
5
|
+
* Lazily resolve ManagerDaemon 实例;可能为 null(例如初始化早期或关闭中)。
|
|
6
|
+
*/
|
|
7
|
+
getManagerDaemon: () => unknown | null;
|
|
8
|
+
/**
|
|
9
|
+
* 返回当前 HTTP 服务器标识(通常为 host:port)。
|
|
10
|
+
*/
|
|
11
|
+
getServerId: () => string;
|
|
12
|
+
/**
|
|
13
|
+
* 返回当前虚拟路由构建产物;用于 Providers 运行时视图。
|
|
14
|
+
*/
|
|
15
|
+
getVirtualRouterArtifacts: () => unknown | null;
|
|
16
|
+
}
|
|
17
|
+
export declare function isLocalRequest(req: Request): boolean;
|
|
18
|
+
export declare function rejectNonLocal(req: Request, res: Response): boolean;
|
|
19
|
+
export declare function registerDaemonAdminRoutes(options: DaemonAdminRouteOptions): void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { registerStatusRoutes } from './daemon-admin/status-handler.js';
|
|
2
|
+
import { registerCredentialRoutes } from './daemon-admin/credentials-handler.js';
|
|
3
|
+
import { registerQuotaRoutes } from './daemon-admin/quota-handler.js';
|
|
4
|
+
import { registerProviderRoutes } from './daemon-admin/providers-handler.js';
|
|
5
|
+
export function isLocalRequest(req) {
|
|
6
|
+
const ip = req.socket?.remoteAddress || '';
|
|
7
|
+
return ip === '127.0.0.1' || ip === '::1' || ip === '::ffff:127.0.0.1';
|
|
8
|
+
}
|
|
9
|
+
export function rejectNonLocal(req, res) {
|
|
10
|
+
if (isLocalRequest(req)) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
res.status(403).json({ error: { message: 'forbidden', code: 'forbidden' } });
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
export function registerDaemonAdminRoutes(options) {
|
|
17
|
+
const { app } = options;
|
|
18
|
+
// Daemon / manager 状态
|
|
19
|
+
registerStatusRoutes(app, options);
|
|
20
|
+
// Credentials / token 视图
|
|
21
|
+
registerCredentialRoutes(app, options);
|
|
22
|
+
// Quota / 429 冷却视图
|
|
23
|
+
registerQuotaRoutes(app, options);
|
|
24
|
+
// Providers 运行时 + Config V2 视图
|
|
25
|
+
registerProviderRoutes(app, options);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=daemon-admin-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon-admin-routes.js","sourceRoot":"","sources":["../../../../src/server/runtime/http-server/daemon-admin-routes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAkB7E,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,aAAa,IAAI,EAAE,CAAC;IAC3C,OAAO,EAAE,KAAK,WAAW,IAAI,EAAE,KAAK,KAAK,IAAI,EAAE,KAAK,kBAAkB,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAY,EAAE,GAAa;IACxD,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;IAC7E,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,OAAgC;IACxE,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IAExB,sBAAsB;IACtB,oBAAoB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAEnC,yBAAyB;IACzB,wBAAwB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAEvC,mBAAmB;IACnB,mBAAmB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAElC,+BAA+B;IAC/B,sBAAsB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -41,6 +41,11 @@ export declare class RouteCodexHttpServer {
|
|
|
41
41
|
constructor(config: ServerConfigV2);
|
|
42
42
|
private resolveVirtualRouterInput;
|
|
43
43
|
private getModuleDependencies;
|
|
44
|
+
/**
|
|
45
|
+
* Register Daemon Admin UI route.
|
|
46
|
+
* Serves docs/daemon-admin-ui.html as a static page; localhost-only.
|
|
47
|
+
*/
|
|
48
|
+
private registerDaemonAdminUiRoute;
|
|
44
49
|
private getErrorHandlingShim;
|
|
45
50
|
private createDebugCenterShim;
|
|
46
51
|
private updateProviderProfiles;
|
|
@@ -82,6 +82,7 @@ export class RouteCodexHttpServer {
|
|
|
82
82
|
// This ensures OAuth Portal is available when providers check token validity
|
|
83
83
|
registerDefaultMiddleware(this.app);
|
|
84
84
|
registerOAuthPortalRoute(this.app);
|
|
85
|
+
this.registerDaemonAdminUiRoute();
|
|
85
86
|
console.log('[RouteCodexHttpServer] OAuth Portal route registered (early initialization)');
|
|
86
87
|
console.log('[RouteCodexHttpServer] Initialized (pipeline=hub)');
|
|
87
88
|
}
|
|
@@ -101,6 +102,35 @@ export class RouteCodexHttpServer {
|
|
|
101
102
|
}
|
|
102
103
|
return this.moduleDependencies;
|
|
103
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Register Daemon Admin UI route.
|
|
107
|
+
* Serves docs/daemon-admin-ui.html as a static page; localhost-only.
|
|
108
|
+
*/
|
|
109
|
+
registerDaemonAdminUiRoute() {
|
|
110
|
+
this.app.get('/daemon/admin', async (req, res) => {
|
|
111
|
+
try {
|
|
112
|
+
const ip = req.socket?.remoteAddress || '';
|
|
113
|
+
const allowed = ip === '127.0.0.1' || ip === '::1' || ip === '::ffff:127.0.0.1';
|
|
114
|
+
if (!allowed) {
|
|
115
|
+
res.status(403).json({ error: { message: 'forbidden', code: 'forbidden' } });
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const filePath = new URL('../../../../docs/daemon-admin-ui.html', import.meta.url);
|
|
119
|
+
const fs = await import('node:fs/promises');
|
|
120
|
+
const html = await fs.readFile(filePath, 'utf8');
|
|
121
|
+
res.setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
122
|
+
res.send(html);
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
126
|
+
res.status(500).json({
|
|
127
|
+
error: {
|
|
128
|
+
message: `Daemon admin UI not available: ${message}`
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}
|
|
104
134
|
getErrorHandlingShim() {
|
|
105
135
|
if (!this.errorHandlingShim) {
|
|
106
136
|
this.errorHandlingShim = {
|
|
@@ -352,7 +382,10 @@ export class RouteCodexHttpServer {
|
|
|
352
382
|
}
|
|
353
383
|
const key = sessionId && sessionId.trim() ? `session:${sessionId.trim()}` : '';
|
|
354
384
|
return key ? store.loadSync(key) : null;
|
|
355
|
-
}
|
|
385
|
+
},
|
|
386
|
+
getManagerDaemon: () => this.managerDaemon,
|
|
387
|
+
getVirtualRouterArtifacts: () => this.currentRouterArtifacts,
|
|
388
|
+
getServerId: () => `${this.config.server.host}:${this.config.server.port}`
|
|
356
389
|
});
|
|
357
390
|
this._isInitialized = true;
|
|
358
391
|
console.log('[RouteCodexHttpServer] Initialization completed successfully');
|