@jsonstudio/rcc 0.89.683 → 0.89.912
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/cli.js +164 -116
- package/dist/cli.js.map +1 -1
- package/dist/client/anthropic/anthropic-protocol-client.js +42 -1
- package/dist/client/anthropic/anthropic-protocol-client.js.map +1 -1
- package/dist/client/gemini-cli/gemini-cli-protocol-client.js +4 -1
- package/dist/client/gemini-cli/gemini-cli-protocol-client.js.map +1 -1
- package/dist/commands/camoufox-backfill.d.ts +2 -0
- package/dist/commands/camoufox-backfill.js +33 -0
- package/dist/commands/camoufox-backfill.js.map +1 -0
- package/dist/commands/camoufox-fp.d.ts +2 -0
- package/dist/commands/camoufox-fp.js +86 -0
- package/dist/commands/camoufox-fp.js.map +1 -0
- package/dist/commands/oauth.d.ts +2 -0
- package/dist/commands/oauth.js +170 -0
- package/dist/commands/oauth.js.map +1 -0
- package/dist/commands/provider-update.js +439 -2
- package/dist/commands/provider-update.js.map +1 -1
- package/dist/commands/quota-status.d.ts +2 -0
- package/dist/commands/quota-status.js +80 -0
- package/dist/commands/quota-status.js.map +1 -0
- package/dist/commands/token-daemon.js +12 -1
- package/dist/commands/token-daemon.js.map +1 -1
- package/dist/config/provider-v2-loader.d.ts +16 -0
- package/dist/config/provider-v2-loader.js +84 -0
- package/dist/config/provider-v2-loader.js.map +1 -0
- package/dist/config/routecodex-config-loader.js +27 -4
- package/dist/config/routecodex-config-loader.js.map +1 -1
- package/dist/config/system-prompts/codex-cli.txt +1 -0
- package/dist/config/virtual-router-builder.d.ts +9 -0
- package/dist/config/virtual-router-builder.js +34 -0
- package/dist/config/virtual-router-builder.js.map +1 -0
- package/dist/config/virtual-router-types.d.ts +25 -0
- package/dist/config/virtual-router-types.js +30 -0
- package/dist/config/virtual-router-types.js.map +1 -0
- package/dist/manager/index.d.ts +10 -0
- package/dist/manager/index.js +27 -0
- package/dist/manager/index.js.map +1 -0
- package/dist/manager/modules/health/index.d.ts +22 -0
- package/dist/manager/modules/health/index.js +82 -0
- package/dist/manager/modules/health/index.js.map +1 -0
- package/dist/manager/modules/quota/index.d.ts +57 -0
- package/dist/manager/modules/quota/index.js +426 -0
- package/dist/manager/modules/quota/index.js.map +1 -0
- package/dist/manager/modules/routing/index.d.ts +17 -0
- package/dist/manager/modules/routing/index.js +61 -0
- package/dist/manager/modules/routing/index.js.map +1 -0
- package/dist/manager/modules/token/index.d.ts +10 -0
- package/dist/manager/modules/token/index.js +58 -0
- package/dist/manager/modules/token/index.js.map +1 -0
- package/dist/manager/storage/base-store.d.ts +6 -0
- package/dist/manager/storage/base-store.js +2 -0
- package/dist/manager/storage/base-store.js.map +1 -0
- package/dist/manager/storage/file-store.d.ts +25 -0
- package/dist/manager/storage/file-store.js +117 -0
- package/dist/manager/storage/file-store.js.map +1 -0
- package/dist/manager/types.d.ts +9 -0
- package/dist/manager/types.js +2 -0
- package/dist/manager/types.js.map +1 -0
- package/dist/message-center/index.d.ts +5 -0
- package/dist/message-center/index.js +6 -0
- package/dist/message-center/index.js.map +1 -0
- package/dist/message-center/message-center.d.ts +93 -0
- package/dist/message-center/message-center.js +189 -0
- package/dist/message-center/message-center.js.map +1 -0
- package/dist/providers/auth/antigravity-userinfo-helper.d.ts +2 -0
- package/dist/providers/auth/antigravity-userinfo-helper.js +102 -0
- package/dist/providers/auth/antigravity-userinfo-helper.js.map +1 -1
- package/dist/providers/auth/iflow-cookie-auth.d.ts +27 -0
- package/dist/providers/auth/iflow-cookie-auth.js +209 -0
- package/dist/providers/auth/iflow-cookie-auth.js.map +1 -0
- package/dist/providers/auth/oauth-lifecycle.js +29 -22
- package/dist/providers/auth/oauth-lifecycle.js.map +1 -1
- package/dist/providers/auth/token-scanner/index.js +16 -1
- package/dist/providers/auth/token-scanner/index.js.map +1 -1
- package/dist/providers/core/config/camoufox-launcher.d.ts +16 -0
- package/dist/providers/core/config/camoufox-launcher.js +314 -0
- package/dist/providers/core/config/camoufox-launcher.js.map +1 -0
- package/dist/providers/core/config/oauth-flows.d.ts +9 -0
- package/dist/providers/core/config/oauth-flows.js +50 -19
- package/dist/providers/core/config/oauth-flows.js.map +1 -1
- package/dist/providers/core/config/provider-oauth-configs.d.ts +6 -0
- package/dist/providers/core/config/provider-oauth-configs.js +12 -0
- package/dist/providers/core/config/provider-oauth-configs.js.map +1 -1
- package/dist/providers/core/config/service-profiles.js +26 -3
- package/dist/providers/core/config/service-profiles.js.map +1 -1
- package/dist/providers/core/runtime/antigravity-quota-client.d.ts +10 -0
- package/dist/providers/core/runtime/antigravity-quota-client.js +88 -0
- package/dist/providers/core/runtime/antigravity-quota-client.js.map +1 -0
- package/dist/providers/core/runtime/base-provider.d.ts +2 -1
- package/dist/providers/core/runtime/base-provider.js +93 -34
- package/dist/providers/core/runtime/base-provider.js.map +1 -1
- package/dist/providers/core/runtime/gemini-cli-http-provider.js +42 -10
- package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -1
- package/dist/providers/core/runtime/http-request-executor.js +24 -0
- package/dist/providers/core/runtime/http-request-executor.js.map +1 -1
- package/dist/providers/core/runtime/http-transport-provider.d.ts +0 -3
- package/dist/providers/core/runtime/http-transport-provider.js +32 -136
- package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
- package/dist/providers/core/runtime/provider-error-classifier.js +18 -10
- package/dist/providers/core/runtime/provider-error-classifier.js.map +1 -1
- package/dist/providers/core/runtime/rate-limit-manager.d.ts +6 -0
- package/dist/providers/core/runtime/rate-limit-manager.js +23 -0
- package/dist/providers/core/runtime/rate-limit-manager.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/providers/core/strategies/oauth-auth-code-flow.d.ts +1 -0
- package/dist/providers/core/strategies/oauth-auth-code-flow.js +3 -2
- package/dist/providers/core/strategies/oauth-auth-code-flow.js.map +1 -1
- package/dist/providers/core/strategies/oauth-device-flow.d.ts +1 -0
- package/dist/providers/core/strategies/oauth-device-flow.js +3 -2
- package/dist/providers/core/strategies/oauth-device-flow.js.map +1 -1
- package/dist/providers/core/strategies/oauth-hybrid-flow.d.ts +1 -0
- package/dist/providers/core/strategies/oauth-hybrid-flow.js +3 -2
- package/dist/providers/core/strategies/oauth-hybrid-flow.js.map +1 -1
- package/dist/providers/core/utils/http-client.js +43 -1
- package/dist/providers/core/utils/http-client.js.map +1 -1
- package/dist/providers/mock/mock-provider-runtime.js +4 -4
- package/dist/providers/mock/mock-provider-runtime.js.map +1 -1
- package/dist/providers/profile/provider-profile-loader.js +13 -1
- package/dist/providers/profile/provider-profile-loader.js.map +1 -1
- package/dist/providers/profile/provider-profile.d.ts +5 -0
- package/dist/scripts/camoufox/gen-fingerprint-env.py +171 -0
- package/dist/scripts/camoufox/launch-auth.mjs +617 -0
- 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/executor-provider.d.ts +1 -0
- package/dist/server/runtime/http-server/executor-provider.js +26 -0
- package/dist/server/runtime/http-server/executor-provider.js.map +1 -1
- package/dist/server/runtime/http-server/executor-response.d.ts +16 -0
- package/dist/server/runtime/http-server/executor-response.js +164 -0
- package/dist/server/runtime/http-server/executor-response.js.map +1 -0
- package/dist/server/runtime/http-server/index.d.ts +6 -0
- package/dist/server/runtime/http-server/index.js +121 -53
- 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 +73 -21
- package/dist/server/runtime/http-server/request-executor.js.map +1 -1
- package/dist/server/runtime/http-server/routes.d.ts +5 -0
- package/dist/server/runtime/http-server/routes.js +45 -1
- package/dist/server/runtime/http-server/routes.js.map +1 -1
- package/dist/server/runtime/http-server/types.d.ts +1 -0
- package/dist/server/utils/client-connection-state.d.ts +8 -0
- package/dist/server/utils/client-connection-state.js +52 -0
- package/dist/server/utils/client-connection-state.js.map +1 -0
- package/dist/server/utils/request-id-manager.js +21 -3
- package/dist/server/utils/request-id-manager.js.map +1 -1
- package/dist/token-daemon/history-store.d.ts +2 -0
- package/dist/token-daemon/history-store.js +6 -2
- package/dist/token-daemon/history-store.js.map +1 -1
- package/dist/token-daemon/index.js +36 -5
- package/dist/token-daemon/index.js.map +1 -1
- package/dist/token-daemon/leader-lock.d.ts +11 -0
- package/dist/token-daemon/leader-lock.js +79 -0
- package/dist/token-daemon/leader-lock.js.map +1 -0
- package/dist/token-daemon/message-bus-integrator.d.ts +98 -0
- package/dist/token-daemon/message-bus-integrator.js +144 -0
- package/dist/token-daemon/message-bus-integrator.js.map +1 -0
- package/dist/token-daemon/provider-registry.d.ts +22 -0
- package/dist/token-daemon/provider-registry.js +201 -0
- package/dist/token-daemon/provider-registry.js.map +1 -0
- package/dist/token-daemon/token-daemon.d.ts +8 -0
- package/dist/token-daemon/token-daemon.js +196 -11
- package/dist/token-daemon/token-daemon.js.map +1 -1
- package/dist/token-portal/local-token-portal.d.ts +1 -0
- package/dist/token-portal/local-token-portal.js +18 -0
- package/dist/token-portal/local-token-portal.js.map +1 -1
- package/dist/token-portal/render.js +1 -0
- package/dist/token-portal/render.js.map +1 -1
- package/dist/tools/error-log.d.ts +31 -0
- package/dist/tools/error-log.js +117 -0
- package/dist/tools/error-log.js.map +1 -0
- package/dist/tools/stats-request-events.d.ts +2 -0
- package/dist/tools/stats-request-events.js +16 -0
- package/dist/tools/stats-request-events.js.map +1 -0
- package/dist/tools/stats-usage.d.ts +31 -0
- package/dist/tools/stats-usage.js +206 -0
- package/dist/tools/stats-usage.js.map +1 -0
- package/package.json +9 -4
- package/scripts/analyze-codex-error-failures.mjs +111 -0
- package/scripts/analyze-usage-estimate.mjs +240 -0
- package/scripts/camoufox/gen-fingerprint-env.py +171 -0
- package/scripts/camoufox/launch-auth.mjs +617 -0
- package/scripts/classify-codex-samples.mjs +251 -0
- package/scripts/cleanup-codex-error-samples.mjs +88 -0
- package/scripts/compare-codex-rccx.mjs +268 -0
- package/scripts/copy-compat-assets.mjs +18 -0
- package/scripts/install-release.sh +1 -1
- package/scripts/local-replay-openai-response.mjs +1 -2
- package/scripts/pack-mode.mjs +16 -6
- package/scripts/replay-codex-sample.mjs +24 -2
- package/scripts/responses-compare-server.mjs +119 -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-apply-patch.mjs +28 -17
- package/scripts/verify-codex-error-samples.mjs +102 -0
- package/scripts/verify-e2e-toolcall.mjs +71 -4
- package/scripts/virtual-router-shadow-v2-real.mjs +143 -0
- package/scripts/virtual-router-shadow-v2.mjs +122 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// classify-codex-samples.mjs
|
|
3
|
+
// 按照 Virtual Router classifier 分类 codex 样本
|
|
4
|
+
// 支持 providerKey、工具类型、tool_calls 结构识别
|
|
5
|
+
|
|
6
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
7
|
+
import { join, dirname, basename } from 'node:path';
|
|
8
|
+
import { fileURLToPath } from 'node:url';
|
|
9
|
+
|
|
10
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const SAMPLES_ROOT = join(__dirname, '..', 'samples', 'mock-provider');
|
|
12
|
+
|
|
13
|
+
// Virtual Router classifier 规则
|
|
14
|
+
const PROVIDER_KEYS = {
|
|
15
|
+
'glm.default': 'glm',
|
|
16
|
+
'glm.key1': 'glm',
|
|
17
|
+
'gemini.default': 'gemini',
|
|
18
|
+
'openai.default': 'openai',
|
|
19
|
+
'anthropic.default': 'anthropic',
|
|
20
|
+
'kimi.key1': 'kimi',
|
|
21
|
+
'qwen.key1': 'qwen',
|
|
22
|
+
'iflow.key1': 'iflow',
|
|
23
|
+
'tab.key1': 'tab',
|
|
24
|
+
'crs.key1': 'crs',
|
|
25
|
+
'fai.key1': 'fai',
|
|
26
|
+
'modelscope.default': 'modelscope',
|
|
27
|
+
'unknown': 'unknown'
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const TOOL_TYPES = {
|
|
31
|
+
'apply_patch': 'apply_patch',
|
|
32
|
+
'shell': 'shell_command',
|
|
33
|
+
'toon': 'toon_tool',
|
|
34
|
+
'submit_tool_outputs': 'tool_loop',
|
|
35
|
+
'list_files': 'file_operation',
|
|
36
|
+
'write_file': 'file_operation',
|
|
37
|
+
'read_file': 'file_operation'
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// 样本分类结果
|
|
41
|
+
class SampleClassifier {
|
|
42
|
+
constructor() {
|
|
43
|
+
this.samples = [];
|
|
44
|
+
this.stats = {
|
|
45
|
+
total: 0,
|
|
46
|
+
byProvider: {},
|
|
47
|
+
byToolType: {},
|
|
48
|
+
withToolCalls: 0,
|
|
49
|
+
withToon: 0,
|
|
50
|
+
errors: 0
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 从路径提取 provider key
|
|
55
|
+
extractProviderKey(filePath) {
|
|
56
|
+
const parts = filePath.split('/');
|
|
57
|
+
const providerPart = parts.find(part => Object.keys(PROVIDER_KEYS).some(key => part.includes(key)));
|
|
58
|
+
|
|
59
|
+
if (!providerPart) return 'unknown';
|
|
60
|
+
|
|
61
|
+
for (const [key, value] of Object.entries(PROVIDER_KEYS)) {
|
|
62
|
+
if (providerPart.includes(key)) return value;
|
|
63
|
+
}
|
|
64
|
+
return 'unknown';
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 识别工具类型
|
|
68
|
+
identifyToolType(toolCall) {
|
|
69
|
+
const funcName = toolCall.function?.name || '';
|
|
70
|
+
|
|
71
|
+
// 检查 TOON 格式
|
|
72
|
+
if (this.isToonTool(toolCall)) return 'toon_tool';
|
|
73
|
+
|
|
74
|
+
// 检查已知工具名称
|
|
75
|
+
for (const [pattern, type] of Object.entries(TOOL_TYPES)) {
|
|
76
|
+
if (funcName.toLowerCase().includes(pattern)) return type;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// 默认分类
|
|
80
|
+
if (funcName.includes('patch')) return 'apply_patch';
|
|
81
|
+
if (funcName.includes('shell')) return 'shell_command';
|
|
82
|
+
if (funcName.includes('file')) return 'file_operation';
|
|
83
|
+
|
|
84
|
+
return 'unknown_tool';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 检查是否为 TOON 工具
|
|
88
|
+
isToonTool(toolCall) {
|
|
89
|
+
const args = toolCall.function?.arguments;
|
|
90
|
+
if (!args) return false;
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
const parsed = JSON.parse(args);
|
|
94
|
+
return parsed && typeof parsed.toon === 'string';
|
|
95
|
+
} catch {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 分析单个样本
|
|
101
|
+
async analyzeSample(filePath) {
|
|
102
|
+
try {
|
|
103
|
+
const content = await readFile(filePath, 'utf-8');
|
|
104
|
+
const data = JSON.parse(content);
|
|
105
|
+
|
|
106
|
+
const providerKey = this.extractProviderKey(filePath);
|
|
107
|
+
const sampleId = basename(dirname(filePath)) + '/' + basename(filePath, '.json');
|
|
108
|
+
|
|
109
|
+
let toolCalls = [];
|
|
110
|
+
let hasToon = false;
|
|
111
|
+
|
|
112
|
+
// 提取 tool_calls
|
|
113
|
+
if (data.tool_calls) {
|
|
114
|
+
toolCalls = data.tool_calls;
|
|
115
|
+
} else if (data.choices?.[0]?.message?.tool_calls) {
|
|
116
|
+
toolCalls = data.choices[0].message.tool_calls;
|
|
117
|
+
} else if (data.messages) {
|
|
118
|
+
// 查找最后一条用户消息中的工具调用
|
|
119
|
+
const lastMessage = data.messages[data.messages.length - 1];
|
|
120
|
+
if (lastMessage.tool_calls) {
|
|
121
|
+
toolCalls = lastMessage.tool_calls;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 分析工具调用
|
|
126
|
+
const toolTypes = [];
|
|
127
|
+
for (const toolCall of toolCalls) {
|
|
128
|
+
const toolType = this.identifyToolType(toolCall);
|
|
129
|
+
toolTypes.push(toolType);
|
|
130
|
+
|
|
131
|
+
if (toolType === 'toon_tool') hasToon = true;
|
|
132
|
+
|
|
133
|
+
// 更新统计
|
|
134
|
+
this.stats.byToolType[toolType] = (this.stats.byToolType[toolType] || 0) + 1;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const sample = {
|
|
138
|
+
id: sampleId,
|
|
139
|
+
provider: providerKey,
|
|
140
|
+
filePath,
|
|
141
|
+
hasToolCalls: toolCalls.length > 0,
|
|
142
|
+
toolTypes,
|
|
143
|
+
hasToon,
|
|
144
|
+
toolCallCount: toolCalls.length
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
this.samples.push(sample);
|
|
148
|
+
|
|
149
|
+
// 更新统计
|
|
150
|
+
this.stats.total++;
|
|
151
|
+
this.stats.byProvider[providerKey] = (this.stats.byProvider[providerKey] || 0) + 1;
|
|
152
|
+
if (toolCalls.length > 0) this.stats.withToolCalls++;
|
|
153
|
+
if (hasToon) this.stats.withToon++;
|
|
154
|
+
|
|
155
|
+
} catch (error) {
|
|
156
|
+
console.error(`Error analyzing ${filePath}:`, error.message);
|
|
157
|
+
this.stats.errors++;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// 递归查找 JSON 文件
|
|
162
|
+
async findJsonFiles(dir) {
|
|
163
|
+
const files = [];
|
|
164
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
165
|
+
|
|
166
|
+
for (const entry of entries) {
|
|
167
|
+
const fullPath = join(dir, entry.name);
|
|
168
|
+
if (entry.isDirectory()) {
|
|
169
|
+
files.push(...await this.findJsonFiles(fullPath));
|
|
170
|
+
} else if (entry.isFile() && entry.name.endsWith('.json')) {
|
|
171
|
+
files.push(fullPath);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return files;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// 运行分类
|
|
179
|
+
async run() {
|
|
180
|
+
console.log('🔍 开始分析 samples/mock-provider 目录...');
|
|
181
|
+
|
|
182
|
+
const jsonFiles = await this.findJsonFiles(SAMPLES_ROOT);
|
|
183
|
+
console.log(`📁 找到 ${jsonFiles.length} 个 JSON 文件`);
|
|
184
|
+
|
|
185
|
+
for (const file of jsonFiles) {
|
|
186
|
+
await this.analyzeSample(file);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
this.printResults();
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// 打印结果
|
|
193
|
+
printResults() {
|
|
194
|
+
console.log('\n📊 分类结果统计:');
|
|
195
|
+
console.log('==================');
|
|
196
|
+
|
|
197
|
+
console.log(`总样本数: ${this.stats.total}`);
|
|
198
|
+
console.log(`包含工具调用: ${this.stats.withToolCalls}`);
|
|
199
|
+
console.log(`包含 TOON: ${this.stats.withToon}`);
|
|
200
|
+
console.log(`错误数: ${this.stats.errors}`);
|
|
201
|
+
|
|
202
|
+
console.log('\n按 Provider 分布:');
|
|
203
|
+
for (const [provider, count] of Object.entries(this.stats.byProvider)) {
|
|
204
|
+
console.log(` ${provider}: ${count}`);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
console.log('\n按工具类型分布:');
|
|
208
|
+
for (const [toolType, count] of Object.entries(this.stats.byToolType)) {
|
|
209
|
+
console.log(` ${toolType}: ${count}`);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// 详细样本列表
|
|
213
|
+
console.log('\n📋 详细样本分类:');
|
|
214
|
+
console.log('==================');
|
|
215
|
+
|
|
216
|
+
for (const sample of this.samples) {
|
|
217
|
+
if (sample.hasToolCalls) {
|
|
218
|
+
console.log(`${sample.provider.padEnd(12)} | ${sample.toolTypes.join(', ').padEnd(20)} | ${sample.id}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// 识别未覆盖场景
|
|
223
|
+
console.log('\n⚠️ 未覆盖场景:');
|
|
224
|
+
console.log('==================');
|
|
225
|
+
|
|
226
|
+
const hasApplyPatch = this.stats.byToolType['apply_patch'] > 0;
|
|
227
|
+
const hasToon = this.stats.byToolType['toon_tool'] > 0;
|
|
228
|
+
const hasShell = this.stats.byToolType['shell_command'] > 0;
|
|
229
|
+
|
|
230
|
+
if (!hasApplyPatch) console.log(' - 缺少 apply_patch 样本');
|
|
231
|
+
if (!hasToon) console.log(' - 缺少 TOON 工具样本');
|
|
232
|
+
if (!hasShell) console.log(' - 缺少 shell command 样本');
|
|
233
|
+
|
|
234
|
+
// TOON 样本详情
|
|
235
|
+
if (this.stats.withToon > 0) {
|
|
236
|
+
console.log('\n🔧 TOON 工具样本:');
|
|
237
|
+
const toonSamples = this.samples.filter(s => s.hasToon);
|
|
238
|
+
for (const sample of toonSamples) {
|
|
239
|
+
console.log(` - ${sample.provider}: ${sample.id}`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// 主函数
|
|
246
|
+
async function main() {
|
|
247
|
+
const classifier = new SampleClassifier();
|
|
248
|
+
await classifier.run();
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Cleanup stale Codex error samples so that后续运行只记录新的失败。
|
|
5
|
+
*
|
|
6
|
+
* 行为:
|
|
7
|
+
* - 扫描 ~/.routecodex/codex-samples/openai-responses 下所有 *.json;
|
|
8
|
+
* - 如果包含以下任一错误模式,则视为“旧错误样本”,移动到归档目录:
|
|
9
|
+
* ~/.routecodex/codex-samples-archive/openai-responses
|
|
10
|
+
* - "apply_patch verification failed"
|
|
11
|
+
* - "failed to parse exec_command arguments"
|
|
12
|
+
* - "Instructions are not valid"
|
|
13
|
+
*
|
|
14
|
+
* 注意:
|
|
15
|
+
* - 只做移动(rename),不直接删除文件,方便必要时回溯;
|
|
16
|
+
* - 归档目录不参与当前 verify:errorsamples/分析脚本。
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import fs from 'node:fs/promises';
|
|
20
|
+
import path from 'node:path';
|
|
21
|
+
import os from 'node:os';
|
|
22
|
+
|
|
23
|
+
const HOME = os.homedir();
|
|
24
|
+
const RESPONSES_DIR = path.join(HOME, '.routecodex', 'codex-samples', 'openai-responses');
|
|
25
|
+
|
|
26
|
+
const PATTERNS = [
|
|
27
|
+
'apply_patch verification failed',
|
|
28
|
+
'failed to parse exec_command arguments',
|
|
29
|
+
'Instructions are not valid'
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
async function listJsonFiles(root) {
|
|
33
|
+
const entries = await fs.readdir(root);
|
|
34
|
+
return entries
|
|
35
|
+
.filter((name) => name.toLowerCase().endsWith('.json'))
|
|
36
|
+
.map((name) => path.join(root, name));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function hasErrorPattern(filePath) {
|
|
40
|
+
const text = await fs.readFile(filePath, 'utf-8');
|
|
41
|
+
return PATTERNS.some((p) => text.includes(p));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function main() {
|
|
45
|
+
try {
|
|
46
|
+
const st = await fs.stat(RESPONSES_DIR);
|
|
47
|
+
if (!st.isDirectory()) {
|
|
48
|
+
console.log('[cleanup-codex-error-samples] no codex-samples directory:', RESPONSES_DIR);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
} catch {
|
|
52
|
+
console.log('[cleanup-codex-error-samples] no codex-samples directory:', RESPONSES_DIR);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const files = await listJsonFiles(RESPONSES_DIR);
|
|
57
|
+
if (!files.length) {
|
|
58
|
+
console.log('[cleanup-codex-error-samples] no JSON files under', RESPONSES_DIR);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
console.log(`[cleanup-codex-error-samples] scanning ${files.length} file(s) under ${RESPONSES_DIR}`);
|
|
63
|
+
|
|
64
|
+
let removed = 0;
|
|
65
|
+
for (const file of files) {
|
|
66
|
+
try {
|
|
67
|
+
const shouldMove = await hasErrorPattern(file);
|
|
68
|
+
if (!shouldMove) continue;
|
|
69
|
+
await fs.unlink(file);
|
|
70
|
+
removed += 1;
|
|
71
|
+
if (removed <= 10) {
|
|
72
|
+
console.log(` removed: ${path.basename(file)}`);
|
|
73
|
+
}
|
|
74
|
+
} catch {
|
|
75
|
+
// best-effort: skip problematic file
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
console.log(`[cleanup-codex-error-samples] removed ${removed} file(s) matching error patterns.`);
|
|
80
|
+
if (removed > 10) {
|
|
81
|
+
console.log(' (only first 10 shown above)');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
main().catch((error) => {
|
|
86
|
+
console.error('[cleanup-codex-error-samples] failed:', error);
|
|
87
|
+
process.exit(99);
|
|
88
|
+
});
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* 黑盒对比:使用 codex-samples 中的一条样本,
|
|
4
|
+
* 分别通过 RouteCodex(dev) 和 rccx(wasm 引擎) 重放,
|
|
5
|
+
* 然后对比 HTTP 元数据和基础响应结构。
|
|
6
|
+
*
|
|
7
|
+
* 前提:
|
|
8
|
+
* - 已经有 RouteCodex 服务在某个端口运行(默认 http://127.0.0.1:5555);
|
|
9
|
+
* - 已经有 rccx 服务在另一个端口运行(默认 http://127.0.0.1:5556);
|
|
10
|
+
* - codex 样本是由 RouteCodex 捕获的 client-request JSON(~/.routecodex/codex-samples/...)。
|
|
11
|
+
*
|
|
12
|
+
* 使用方式(示例):
|
|
13
|
+
* node scripts/compare-codex-rccx.mjs \\
|
|
14
|
+
* --sample ~/.routecodex/codex-samples/openai-responses/xxx_client-request.json \\
|
|
15
|
+
* --route-base http://127.0.0.1:5555 \\
|
|
16
|
+
* --rccx-base http://127.0.0.1:5556
|
|
17
|
+
*
|
|
18
|
+
* 脚本会调用 scripts/replay-codex-sample.mjs 对同一条样本重放两次:
|
|
19
|
+
* - label=routecodex,base = --route-base;
|
|
20
|
+
* - label=rccx, base = --rccx-base;
|
|
21
|
+
*
|
|
22
|
+
* 然后读取各自 runs/<requestId>/<label>/response.* 进行对比。
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import fs from 'node:fs';
|
|
26
|
+
import path from 'node:path';
|
|
27
|
+
import { spawn } from 'node:child_process';
|
|
28
|
+
|
|
29
|
+
const DEFAULT_ROUTE_BASE = process.env.ROUTECODEX_BASE || 'http://127.0.0.1:5555';
|
|
30
|
+
const DEFAULT_RCCX_BASE = process.env.RCCX_BASE || 'http://127.0.0.1:5556';
|
|
31
|
+
const DEFAULT_API_KEY = process.env.ROUTECODEX_API_KEY || 'routecodex-test';
|
|
32
|
+
|
|
33
|
+
function usage() {
|
|
34
|
+
console.log(`Usage:
|
|
35
|
+
node scripts/compare-codex-rccx.mjs --sample <file> [--route-base URL] [--rccx-base URL] [--key TOKEN]
|
|
36
|
+
|
|
37
|
+
Environment:
|
|
38
|
+
ROUTECODEX_BASE 默认 RouteCodex 基础 URL (默认 ${DEFAULT_ROUTE_BASE})
|
|
39
|
+
RCCX_BASE 默认 rccx 基础 URL (默认 ${DEFAULT_RCCX_BASE})
|
|
40
|
+
ROUTECODEX_API_KEY 默认 API key (默认 ${DEFAULT_API_KEY})
|
|
41
|
+
`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function parseArgs() {
|
|
45
|
+
const args = process.argv.slice(2);
|
|
46
|
+
const opts = {
|
|
47
|
+
routeBase: DEFAULT_ROUTE_BASE,
|
|
48
|
+
rccxBase: DEFAULT_RCCX_BASE,
|
|
49
|
+
key: DEFAULT_API_KEY,
|
|
50
|
+
routeLabel: 'routecodex',
|
|
51
|
+
rccxLabel: 'rccx'
|
|
52
|
+
};
|
|
53
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
54
|
+
const a = args[i];
|
|
55
|
+
if (a === '--sample') opts.sample = args[++i];
|
|
56
|
+
else if (a === '--route-base') opts.routeBase = args[++i];
|
|
57
|
+
else if (a === '--rccx-base') opts.rccxBase = args[++i];
|
|
58
|
+
else if (a === '--key') opts.key = args[++i];
|
|
59
|
+
else if (a === '--route-label') opts.routeLabel = args[++i];
|
|
60
|
+
else if (a === '--rccx-label') opts.rccxLabel = args[++i];
|
|
61
|
+
else if (a === '--help' || a === '-h') {
|
|
62
|
+
usage();
|
|
63
|
+
process.exit(0);
|
|
64
|
+
} else {
|
|
65
|
+
console.error(`Unknown arg: ${a}`);
|
|
66
|
+
usage();
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (!opts.sample) {
|
|
71
|
+
usage();
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
return opts;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function readJson(file) {
|
|
78
|
+
return JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function computeRequestId(sample) {
|
|
82
|
+
return (
|
|
83
|
+
sample?.requestId ||
|
|
84
|
+
sample?.data?.meta?.requestId ||
|
|
85
|
+
sample?.meta?.requestId ||
|
|
86
|
+
`sample_${Date.now()}`
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function computeRunDir(samplePath, requestId, label) {
|
|
91
|
+
const baseDir = path.dirname(path.resolve(samplePath));
|
|
92
|
+
return path.join(baseDir, 'runs', requestId, label);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function runReplay({ base, label, samplePath, key }) {
|
|
96
|
+
return new Promise((resolve, reject) => {
|
|
97
|
+
const args = [
|
|
98
|
+
'scripts/replay-codex-sample.mjs',
|
|
99
|
+
'--sample',
|
|
100
|
+
samplePath,
|
|
101
|
+
'--label',
|
|
102
|
+
label,
|
|
103
|
+
'--base',
|
|
104
|
+
base,
|
|
105
|
+
'--key',
|
|
106
|
+
key
|
|
107
|
+
];
|
|
108
|
+
const repoRoot = path.resolve(path.dirname(new URL(import.meta.url).pathname), '..');
|
|
109
|
+
const child = spawn(process.execPath, args, {
|
|
110
|
+
cwd: repoRoot,
|
|
111
|
+
stdio: 'inherit'
|
|
112
|
+
});
|
|
113
|
+
child.on('exit', (code) => {
|
|
114
|
+
if (code === 0) resolve();
|
|
115
|
+
else reject(new Error(`replay-codex-sample failed for label=${label} (exit ${code})`));
|
|
116
|
+
});
|
|
117
|
+
child.on('error', (err) => reject(err));
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function loadRunResult(runDir) {
|
|
122
|
+
const metaPath = path.join(runDir, 'response.meta.json');
|
|
123
|
+
if (!fs.existsSync(metaPath)) {
|
|
124
|
+
return { error: `missing response.meta.json in ${runDir}` };
|
|
125
|
+
}
|
|
126
|
+
const meta = readJson(metaPath);
|
|
127
|
+
|
|
128
|
+
const jsonPath = path.join(runDir, 'response.json');
|
|
129
|
+
const errorPath = path.join(runDir, 'response.error.txt');
|
|
130
|
+
const ssePath = path.join(runDir, 'response.sse.ndjson');
|
|
131
|
+
|
|
132
|
+
let bodyKind = 'none';
|
|
133
|
+
let bodySample = null;
|
|
134
|
+
|
|
135
|
+
if (fs.existsSync(jsonPath)) {
|
|
136
|
+
bodyKind = 'json';
|
|
137
|
+
try {
|
|
138
|
+
bodySample = readJson(jsonPath);
|
|
139
|
+
} catch {
|
|
140
|
+
bodySample = null;
|
|
141
|
+
}
|
|
142
|
+
} else if (fs.existsSync(errorPath)) {
|
|
143
|
+
bodyKind = 'error-text';
|
|
144
|
+
try {
|
|
145
|
+
const txt = fs.readFileSync(errorPath, 'utf8');
|
|
146
|
+
bodySample = txt.slice(0, 1024);
|
|
147
|
+
} catch {
|
|
148
|
+
bodySample = null;
|
|
149
|
+
}
|
|
150
|
+
} else if (fs.existsSync(ssePath)) {
|
|
151
|
+
bodyKind = 'sse';
|
|
152
|
+
try {
|
|
153
|
+
const txt = fs.readFileSync(ssePath, 'utf8');
|
|
154
|
+
const lines = txt.split('\n').filter(Boolean);
|
|
155
|
+
bodySample = lines.slice(0, 5);
|
|
156
|
+
} catch {
|
|
157
|
+
bodySample = null;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return { meta, bodyKind, bodySample };
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function stableSubset(meta) {
|
|
165
|
+
if (!meta || typeof meta !== 'object') return null;
|
|
166
|
+
return {
|
|
167
|
+
status: meta.status,
|
|
168
|
+
statusText: meta.statusText,
|
|
169
|
+
endpoint: meta.endpoint,
|
|
170
|
+
targetUrl: meta.targetUrl,
|
|
171
|
+
wantsSse: meta.wantsSse,
|
|
172
|
+
contentType: meta.headers && meta.headers['content-type'],
|
|
173
|
+
routeHint:
|
|
174
|
+
(meta.headers && (meta.headers['x-route-hint'] || meta.headers['X-Route-Hint'])) || undefined
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function stableStringify(value) {
|
|
179
|
+
return JSON.stringify(
|
|
180
|
+
value,
|
|
181
|
+
(key, val) => {
|
|
182
|
+
if (val && typeof val === 'object' && !Array.isArray(val)) {
|
|
183
|
+
const out = {};
|
|
184
|
+
for (const k of Object.keys(val).sort()) {
|
|
185
|
+
out[k] = val[k];
|
|
186
|
+
}
|
|
187
|
+
return out;
|
|
188
|
+
}
|
|
189
|
+
return val;
|
|
190
|
+
}
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
async function main() {
|
|
195
|
+
const opts = parseArgs();
|
|
196
|
+
const samplePath = path.resolve(opts.sample);
|
|
197
|
+
const sample = readJson(samplePath);
|
|
198
|
+
const requestId = computeRequestId(sample);
|
|
199
|
+
|
|
200
|
+
console.log(
|
|
201
|
+
`[compare-codex-rccx] sample=${samplePath} requestId=${requestId} routeBase=${opts.routeBase} rccxBase=${opts.rccxBase}`
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
// RouteCodex 路径
|
|
205
|
+
console.log('[compare-codex-rccx] ▶ routecodex replay...');
|
|
206
|
+
await runReplay({
|
|
207
|
+
base: opts.routeBase,
|
|
208
|
+
label: opts.routeLabel,
|
|
209
|
+
samplePath,
|
|
210
|
+
key: opts.key
|
|
211
|
+
});
|
|
212
|
+
const routeRunDir = computeRunDir(samplePath, requestId, opts.routeLabel);
|
|
213
|
+
const routeResult = loadRunResult(routeRunDir);
|
|
214
|
+
|
|
215
|
+
// rccx 路径
|
|
216
|
+
console.log('[compare-codex-rccx] ▶ rccx replay...');
|
|
217
|
+
await runReplay({
|
|
218
|
+
base: opts.rccxBase,
|
|
219
|
+
label: opts.rccxLabel,
|
|
220
|
+
samplePath,
|
|
221
|
+
key: opts.key
|
|
222
|
+
});
|
|
223
|
+
const rccxRunDir = computeRunDir(samplePath, requestId, opts.rccxLabel);
|
|
224
|
+
const rccxResult = loadRunResult(rccxRunDir);
|
|
225
|
+
|
|
226
|
+
if (routeResult.error || rccxResult.error) {
|
|
227
|
+
console.error('[compare-codex-rccx] ❌ missing run artifacts:', {
|
|
228
|
+
routeRunDir,
|
|
229
|
+
routeError: routeResult.error || null,
|
|
230
|
+
rccxRunDir,
|
|
231
|
+
rccxError: rccxResult.error || null
|
|
232
|
+
});
|
|
233
|
+
process.exitCode = 1;
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const routeMeta = stableSubset(routeResult.meta);
|
|
238
|
+
const rccxMeta = stableSubset(rccxResult.meta);
|
|
239
|
+
|
|
240
|
+
const metaEqual = stableStringify(routeMeta) === stableStringify(rccxMeta);
|
|
241
|
+
const bodyKindEqual = routeResult.bodyKind === rccxResult.bodyKind;
|
|
242
|
+
|
|
243
|
+
console.log('[compare-codex-rccx] routecodex.meta =', routeMeta);
|
|
244
|
+
console.log('[compare-codex-rccx] rccx.meta =', rccxMeta);
|
|
245
|
+
console.log('[compare-codex-rccx] routecodex.bodyKind =', routeResult.bodyKind);
|
|
246
|
+
console.log('[compare-codex-rccx] rccx.bodyKind =', rccxResult.bodyKind);
|
|
247
|
+
|
|
248
|
+
if (!metaEqual || !bodyKindEqual) {
|
|
249
|
+
console.log('[compare-codex-rccx] ❌ mismatch detected between RouteCodex and rccx');
|
|
250
|
+
console.log('[compare-codex-rccx] routecodex runDir =', routeRunDir);
|
|
251
|
+
console.log('[compare-codex-rccx] rccx runDir =', rccxRunDir);
|
|
252
|
+
// 为了调试 429 / 系列冷却问题,额外打印一小段 body 样本。
|
|
253
|
+
console.log('[compare-codex-rccx] routecodex.bodySample =', routeResult.bodySample);
|
|
254
|
+
console.log('[compare-codex-rccx] rccx.bodySample =', rccxResult.bodySample);
|
|
255
|
+
process.exitCode = 1;
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
console.log('[compare-codex-rccx] ✅ meta/bodyKind aligned for this sample');
|
|
260
|
+
console.log('[compare-codex-rccx] routecodex runDir =', routeRunDir);
|
|
261
|
+
console.log('[compare-codex-rccx] rccx runDir =', rccxRunDir);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
main().catch((err) => {
|
|
265
|
+
console.error('[compare-codex-rccx] fatal error:', err);
|
|
266
|
+
process.exitCode = 1;
|
|
267
|
+
});
|
|
268
|
+
|
|
@@ -17,7 +17,10 @@ async function ensureDir(p) {
|
|
|
17
17
|
async function main() {
|
|
18
18
|
const PROMPT_SRC = path.resolve(process.cwd(), 'src/config/system-prompts');
|
|
19
19
|
const PROMPT_DIST = path.resolve(process.cwd(), 'dist/config/system-prompts');
|
|
20
|
+
const CAMOUFOX_SRC = path.resolve(process.cwd(), 'scripts/camoufox');
|
|
21
|
+
const CAMOUFOX_DIST = path.resolve(process.cwd(), 'dist/scripts/camoufox');
|
|
20
22
|
const promptCopied = [];
|
|
23
|
+
const camoufoxCopied = [];
|
|
21
24
|
try {
|
|
22
25
|
// copy system prompt artifacts only; provider compat assets are owned by llmswitch-core
|
|
23
26
|
try {
|
|
@@ -35,7 +38,22 @@ async function main() {
|
|
|
35
38
|
if (promptErr && promptErr.code !== 'ENOENT') throw promptErr;
|
|
36
39
|
}
|
|
37
40
|
// 不再复制 provider compat 资产;兼容层由 sharedmodule/llmswitch-core 提供
|
|
41
|
+
try {
|
|
42
|
+
for await (const file of walk(CAMOUFOX_SRC)) {
|
|
43
|
+
const stats = await fs.stat(file);
|
|
44
|
+
if (stats.isFile()) {
|
|
45
|
+
const rel = path.relative(CAMOUFOX_SRC, file);
|
|
46
|
+
const dest = path.join(CAMOUFOX_DIST, rel);
|
|
47
|
+
await ensureDir(path.dirname(dest));
|
|
48
|
+
await fs.copyFile(file, dest);
|
|
49
|
+
camoufoxCopied.push(rel);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
} catch (camoufoxErr) {
|
|
53
|
+
if (camoufoxErr && camoufoxErr.code !== 'ENOENT') throw camoufoxErr;
|
|
54
|
+
}
|
|
38
55
|
console.log(`[copy-compat-assets] prompts copied: ${promptCopied.length}`);
|
|
56
|
+
console.log(`[copy-compat-assets] camoufox assets copied: ${camoufoxCopied.length}`);
|
|
39
57
|
} catch (err) {
|
|
40
58
|
console.error('[copy-compat-assets] failed:', err?.message || String(err));
|
|
41
59
|
process.exit(1);
|
|
@@ -85,7 +85,7 @@ else
|
|
|
85
85
|
fi
|
|
86
86
|
|
|
87
87
|
verify_server_request() {
|
|
88
|
-
local VERIFY_CONFIG=${ROUTECODEX_INSTALL_VERIFY_CONFIG:-"$HOME/.routecodex/
|
|
88
|
+
local VERIFY_CONFIG=${ROUTECODEX_INSTALL_VERIFY_CONFIG:-"$HOME/.routecodex/config.json"}
|
|
89
89
|
local VERIFY_TIMEOUT=${ROUTECODEX_INSTALL_VERIFY_TIMEOUT:-240}
|
|
90
90
|
local VERIFY_LOG="/tmp/routecodex-release-verify-$(date +%s).log"
|
|
91
91
|
local TIMEOUT_BIN=""
|
|
@@ -25,7 +25,7 @@ async function main() {
|
|
|
25
25
|
const payload = obj?.data || obj; // accept wrapped
|
|
26
26
|
const requestId = (obj?.requestId) || `replay_${Date.now()}`;
|
|
27
27
|
|
|
28
|
-
const codecUrl = pathToFileURL(path.join(process.cwd(), 'sharedmodule', 'llmswitch-core', 'dist', '
|
|
28
|
+
const codecUrl = pathToFileURL(path.join(process.cwd(), 'sharedmodule', 'llmswitch-core', 'dist', 'conversion', 'codecs', 'openai-openai-codec.js')).href;
|
|
29
29
|
const { OpenAIOpenAIConversionCodec } = await import(codecUrl);
|
|
30
30
|
const codec = new OpenAIOpenAIConversionCodec({});
|
|
31
31
|
const profile = { outgoingProtocol: 'openai-chat' };
|
|
@@ -38,4 +38,3 @@ async function main() {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
main().catch(err => { console.error(err); process.exit(1); });
|
|
41
|
-
|
package/scripts/pack-mode.mjs
CHANGED
|
@@ -77,14 +77,24 @@ try {
|
|
|
77
77
|
'@jsonstudio/llms': llmsVersion
|
|
78
78
|
};
|
|
79
79
|
} else if (isRccx) {
|
|
80
|
-
// rccx: wasm-backed llms
|
|
80
|
+
// rccx: wasm-backed llms 核心,通过 npm alias 将 @jsonstudio/llms 指向 wasm 引擎包。
|
|
81
81
|
mutated.bundledDependencies = [];
|
|
82
82
|
mutated.bundleDependencies = [];
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
|
|
84
|
+
const deps = { ...(original.dependencies || {}) };
|
|
85
|
+
// 移除原有 TS 版 llms 直连依赖
|
|
86
|
+
if (deps['@jsonstudio/llms']) {
|
|
87
|
+
delete deps['@jsonstudio/llms'];
|
|
88
|
+
}
|
|
89
|
+
// 推断 wasm 引擎版本,若未声明则使用本地 llms-engine 缺省版本
|
|
90
|
+
const engineVersion = deps['@jsonstudio/llms-engine'] || '^0.3.0';
|
|
91
|
+
deps['@jsonstudio/llms-engine'] = engineVersion;
|
|
92
|
+
// 通过 npm alias 保持 import 形状不变
|
|
93
|
+
deps['@jsonstudio/llms'] = `npm:@jsonstudio/llms-engine@${engineVersion}`;
|
|
94
|
+
deps.ajv = deps.ajv || '^8.17.1';
|
|
95
|
+
deps.zod = deps.zod || '^3.23.8';
|
|
96
|
+
|
|
97
|
+
mutated.dependencies = deps;
|
|
88
98
|
}
|
|
89
99
|
fs.writeFileSync(pkgPath, JSON.stringify(mutated, null, 2));
|
|
90
100
|
|