@jsonstudio/rcc 0.89.1121 → 0.89.1189
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/dist/build-info.js +2 -2
- package/dist/cli/commands/clean.d.ts +16 -0
- package/dist/cli/commands/clean.js +58 -0
- package/dist/cli/commands/clean.js.map +1 -0
- package/dist/cli/commands/code.d.ts +55 -0
- package/dist/cli/commands/code.js +376 -0
- package/dist/cli/commands/code.js.map +1 -0
- package/dist/cli/commands/config.d.ts +31 -0
- package/dist/cli/commands/config.js +168 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/env.d.ts +20 -0
- package/dist/cli/commands/env.js +73 -0
- package/dist/cli/commands/env.js.map +1 -0
- package/dist/cli/commands/examples.d.ts +5 -0
- package/dist/cli/commands/examples.js +66 -0
- package/dist/cli/commands/examples.js.map +1 -0
- package/dist/cli/commands/port.d.ts +24 -0
- package/dist/cli/commands/port.js +85 -0
- package/dist/cli/commands/port.js.map +1 -0
- package/dist/cli/commands/restart.d.ts +50 -0
- package/dist/cli/commands/restart.js +176 -0
- package/dist/cli/commands/restart.js.map +1 -0
- package/dist/cli/commands/start.d.ts +68 -0
- package/dist/cli/commands/start.js +295 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.d.ts +16 -0
- package/dist/cli/commands/status.js +104 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/stop.d.ts +35 -0
- package/dist/cli/commands/stop.js +95 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/logger.d.ts +8 -0
- package/dist/cli/logger.js +9 -0
- package/dist/cli/logger.js.map +1 -0
- package/dist/cli/main.d.ts +6 -0
- package/dist/cli/main.js +16 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/program.d.ts +8 -0
- package/dist/cli/program.js +16 -0
- package/dist/cli/program.js.map +1 -0
- package/dist/cli/register/basic-commands.d.ts +30 -0
- package/dist/cli/register/basic-commands.js +11 -0
- package/dist/cli/register/basic-commands.js.map +1 -0
- package/dist/cli/register/code-command.d.ts +3 -0
- package/dist/cli/register/code-command.js +5 -0
- package/dist/cli/register/code-command.js.map +1 -0
- package/dist/cli/register/restart-command.d.ts +3 -0
- package/dist/cli/register/restart-command.js +5 -0
- package/dist/cli/register/restart-command.js.map +1 -0
- package/dist/cli/register/start-command.d.ts +3 -0
- package/dist/cli/register/start-command.js +5 -0
- package/dist/cli/register/start-command.js.map +1 -0
- package/dist/cli/register/status-config-commands.d.ts +16 -0
- package/dist/cli/register/status-config-commands.js +7 -0
- package/dist/cli/register/status-config-commands.js.map +1 -0
- package/dist/cli/register/stop-command.d.ts +3 -0
- package/dist/cli/register/stop-command.js +5 -0
- package/dist/cli/register/stop-command.js.map +1 -0
- package/dist/cli/runtime.d.ts +5 -0
- package/dist/cli/runtime.js +11 -0
- package/dist/cli/runtime.js.map +1 -0
- package/dist/cli/server/port-utils.d.ts +52 -0
- package/dist/cli/server/port-utils.js +193 -0
- package/dist/cli/server/port-utils.js.map +1 -0
- package/dist/cli/spinner.d.ts +10 -0
- package/dist/cli/spinner.js +59 -0
- package/dist/cli/spinner.js.map +1 -0
- package/dist/cli/utils/normalize.d.ts +2 -0
- package/dist/cli/utils/normalize.js +22 -0
- package/dist/cli/utils/normalize.js.map +1 -0
- package/dist/cli/utils/safe-read-json.d.ts +1 -0
- package/dist/cli/utils/safe-read-json.js +11 -0
- package/dist/cli/utils/safe-read-json.js.map +1 -0
- package/dist/cli.js +149 -1738
- package/dist/cli.js.map +1 -1
- package/dist/client/anthropic/anthropic-protocol-client.js +4 -3
- package/dist/client/anthropic/anthropic-protocol-client.js.map +1 -1
- package/dist/client/gemini/gemini-protocol-client.js +5 -0
- package/dist/client/gemini/gemini-protocol-client.js.map +1 -1
- package/dist/client/gemini-cli/gemini-cli-protocol-client.d.ts +1 -1
- package/dist/client/gemini-cli/gemini-cli-protocol-client.js +10 -3
- package/dist/client/gemini-cli/gemini-cli-protocol-client.js.map +1 -1
- package/dist/commands/provider-update.js +355 -5
- package/dist/commands/provider-update.js.map +1 -1
- package/dist/commands/quota-daemon.js +2 -2
- package/dist/commands/quota-daemon.js.map +1 -1
- package/dist/config/provider-v2-loader.js +4 -2
- package/dist/config/provider-v2-loader.js.map +1 -1
- package/dist/docs/daemon-admin-ui.html +583 -87
- package/dist/index.js +32 -1
- package/dist/index.js.map +1 -1
- package/dist/manager/modules/quota/index.d.ts +19 -1
- package/dist/manager/modules/quota/index.js +130 -5
- package/dist/manager/modules/quota/index.js.map +1 -1
- package/dist/manager/modules/routing/index.js.map +1 -1
- package/dist/manager/storage/file-store.js +1 -1
- package/dist/manager/storage/file-store.js.map +1 -1
- package/dist/manager/types.d.ts +5 -0
- package/dist/providers/auth/oauth-lifecycle.js +2 -2
- package/dist/providers/auth/oauth-lifecycle.js.map +1 -1
- package/dist/providers/core/api/provider-config.d.ts +2 -0
- package/dist/providers/core/api/provider-types.d.ts +2 -0
- package/dist/providers/core/config/service-profiles.js +1 -1
- package/dist/providers/core/config/service-profiles.js.map +1 -1
- package/dist/providers/core/runtime/base-provider.js +21 -27
- package/dist/providers/core/runtime/base-provider.js.map +1 -1
- package/dist/providers/core/runtime/gemini-cli-http-provider.d.ts +1 -0
- package/dist/providers/core/runtime/gemini-cli-http-provider.js +37 -6
- package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -1
- package/dist/providers/core/runtime/http-request-executor.js +23 -29
- package/dist/providers/core/runtime/http-request-executor.js.map +1 -1
- package/dist/providers/core/runtime/http-transport-provider.js +46 -38
- package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
- package/dist/providers/core/utils/http-client.d.ts +9 -0
- package/dist/providers/core/utils/http-client.js +9 -11
- package/dist/providers/core/utils/http-client.js.map +1 -1
- package/dist/providers/core/utils/provider-error-reporter.js +2 -6
- package/dist/providers/core/utils/provider-error-reporter.js.map +1 -1
- package/dist/providers/mock/mock-provider-runtime.js +19 -5
- package/dist/providers/mock/mock-provider-runtime.js.map +1 -1
- package/dist/server/handlers/handler-utils.d.ts +1 -1
- package/dist/server/handlers/handler-utils.js +4 -4
- package/dist/server/handlers/handler-utils.js.map +1 -1
- package/dist/server/handlers/responses-handler.js +2 -1
- package/dist/server/handlers/responses-handler.js.map +1 -1
- package/dist/server/handlers/sse-dispatcher.js +1 -4
- package/dist/server/handlers/sse-dispatcher.js.map +1 -1
- package/dist/server/runtime/http-server/colored-logger.d.ts +1 -1
- package/dist/server/runtime/http-server/colored-logger.js +22 -10
- package/dist/server/runtime/http-server/colored-logger.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js +12 -6
- package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/providers-handler.js +116 -98
- package/dist/server/runtime/http-server/daemon-admin/providers-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/quota-handler.js +108 -15
- package/dist/server/runtime/http-server/daemon-admin/quota-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/restart-handler.js +2 -1
- package/dist/server/runtime/http-server/daemon-admin/restart-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/stats-handler.d.ts +3 -0
- package/dist/server/runtime/http-server/daemon-admin/stats-handler.js +56 -0
- package/dist/server/runtime/http-server/daemon-admin/stats-handler.js.map +1 -0
- package/dist/server/runtime/http-server/daemon-admin/status-handler.js +8 -4
- package/dist/server/runtime/http-server/daemon-admin/status-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin-routes.d.ts +9 -0
- package/dist/server/runtime/http-server/daemon-admin-routes.js +3 -0
- package/dist/server/runtime/http-server/daemon-admin-routes.js.map +1 -1
- package/dist/server/runtime/http-server/executor-provider.js +74 -0
- package/dist/server/runtime/http-server/executor-provider.js.map +1 -1
- package/dist/server/runtime/http-server/index.d.ts +2 -0
- package/dist/server/runtime/http-server/index.js +107 -17
- package/dist/server/runtime/http-server/index.js.map +1 -1
- package/dist/server/runtime/http-server/request-executor.js +18 -11
- 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 +17 -4
- package/dist/server/runtime/http-server/routes.js.map +1 -1
- package/dist/server/runtime/http-server/stats-manager.d.ts +7 -0
- package/dist/server/runtime/http-server/stats-manager.js +31 -6
- package/dist/server/runtime/http-server/stats-manager.js.map +1 -1
- package/dist/server/runtime/http-server/types.d.ts +5 -0
- package/dist/server/utils/http-error-mapper.js +70 -9
- package/dist/server/utils/http-error-mapper.js.map +1 -1
- package/dist/server/utils/request-id-manager.js +9 -5
- package/dist/server/utils/request-id-manager.js.map +1 -1
- package/dist/server/utils/sse-request-parser.js +2 -1
- package/dist/server/utils/sse-request-parser.js.map +1 -1
- package/dist/server/utils/utf8-chunk-buffer.d.ts +15 -30
- package/dist/server/utils/utf8-chunk-buffer.js +78 -88
- package/dist/server/utils/utf8-chunk-buffer.js.map +1 -1
- package/dist/server/utils/warmup-storm-tracker.js +1 -1
- package/dist/server/utils/warmup-storm-tracker.js.map +1 -1
- package/dist/tools/provider-update/fetch-models.js +8 -5
- package/dist/tools/provider-update/fetch-models.js.map +1 -1
- package/dist/tools/provider-update/probe-context.d.ts +24 -0
- package/dist/tools/provider-update/probe-context.js +199 -0
- package/dist/tools/provider-update/probe-context.js.map +1 -0
- package/dist/tools/provider-update/types.d.ts +1 -0
- package/package.json +10 -4
- package/scripts/anthropic-compare-modes.mjs +40 -3
- package/scripts/antigravity-smoke.mjs +180 -0
- package/scripts/backfill-apply-patch-exec-errorsamples.mjs +225 -0
- package/scripts/compare-codex-rccx.mjs +59 -1
- package/scripts/compare-responses-request.mjs +50 -4
- package/scripts/lib/errorsamples.mjs +23 -0
- package/scripts/mock-provider/run-regressions.mjs +12 -2
- package/scripts/policy-violations-report.mjs +257 -0
- package/scripts/publish-rcc.mjs +16 -2
- package/scripts/scan-apply-patch-samples.mjs +148 -7
- package/scripts/tests/unified-hub-responses-enforce-safe.mjs +37 -0
- package/scripts/tests/unified-hub-shadow-regression.mjs +55 -0
- package/scripts/unified-hub-shadow-compare.mjs +359 -0
- package/scripts/verify-e2e-gemini-followup-sample.mjs +269 -0
- package/scripts/virtual-router-shadow-v2-real.mjs +71 -1
- package/scripts/virtual-router-shadow-v2.mjs +41 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { encoding_for_model } from 'tiktoken';
|
|
2
|
+
const encoderCache = new Map();
|
|
3
|
+
function getEncoder(model) {
|
|
4
|
+
const key = model.trim() || 'gpt-4o';
|
|
5
|
+
const existing = encoderCache.get(key);
|
|
6
|
+
if (existing) {
|
|
7
|
+
return existing;
|
|
8
|
+
}
|
|
9
|
+
// tiktoken's TS types restrict this to a known model union; allow override for local experiments.
|
|
10
|
+
const created = encoding_for_model(key);
|
|
11
|
+
encoderCache.set(key, created);
|
|
12
|
+
return created;
|
|
13
|
+
}
|
|
14
|
+
const UNIT_TEXT = 'a ';
|
|
15
|
+
export function buildTextForExactTokenCount(targetTokens, encoderModel = 'gpt-4o') {
|
|
16
|
+
if (!Number.isFinite(targetTokens) || targetTokens <= 0) {
|
|
17
|
+
throw new Error(`Invalid targetTokens: ${targetTokens}`);
|
|
18
|
+
}
|
|
19
|
+
// We deliberately generate text from plain strings (not decode(tokens)) because
|
|
20
|
+
// decode() is not guaranteed to round-trip back to the same token count via encode().
|
|
21
|
+
//
|
|
22
|
+
// Empirically for tiktoken (e.g. 'gpt-4o'), UNIT_TEXT repeat has stable linear growth:
|
|
23
|
+
// encode('a '.repeat(n)).length == n + k
|
|
24
|
+
// We detect k at runtime and compute n to hit targetTokens exactly.
|
|
25
|
+
const encoder = getEncoder(encoderModel);
|
|
26
|
+
if (Math.floor(targetTokens) === 1) {
|
|
27
|
+
return 'a';
|
|
28
|
+
}
|
|
29
|
+
const f1 = encoder.encode(UNIT_TEXT).length;
|
|
30
|
+
const f99 = encoder.encode(UNIT_TEXT.repeat(99)).length;
|
|
31
|
+
const f100 = encoder.encode(UNIT_TEXT.repeat(100)).length;
|
|
32
|
+
const slope = f100 - f99;
|
|
33
|
+
const offset = slope === 1 ? (f1 - 1) : 0;
|
|
34
|
+
let repeats = slope === 1 ? Math.max(1, Math.floor(targetTokens) - offset) : Math.max(1, Math.floor(targetTokens));
|
|
35
|
+
// Fine-tune with minimal extra encodes (should converge immediately for slope=1).
|
|
36
|
+
for (let i = 0; i < 20; i++) {
|
|
37
|
+
const text = UNIT_TEXT.repeat(repeats);
|
|
38
|
+
const tokens = encoder.encode(text).length;
|
|
39
|
+
if (tokens === Math.floor(targetTokens)) {
|
|
40
|
+
return text;
|
|
41
|
+
}
|
|
42
|
+
if (tokens < Math.floor(targetTokens)) {
|
|
43
|
+
repeats += Math.max(1, Math.floor(targetTokens) - tokens);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
repeats -= Math.max(1, tokens - Math.floor(targetTokens));
|
|
47
|
+
if (repeats <= 0) {
|
|
48
|
+
repeats = 1;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Last resort: return best-effort (caller will validate).
|
|
53
|
+
return UNIT_TEXT.repeat(repeats);
|
|
54
|
+
}
|
|
55
|
+
export function countTokens(text, encoderModel = 'gpt-4o') {
|
|
56
|
+
const encoder = getEncoder(encoderModel);
|
|
57
|
+
return encoder.encode(text).length;
|
|
58
|
+
}
|
|
59
|
+
function sleep(ms) {
|
|
60
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
61
|
+
}
|
|
62
|
+
async function requestOnce(modelId, threshold, text, opts) {
|
|
63
|
+
const fetcher = opts.fetcher ?? fetch;
|
|
64
|
+
const controller = new AbortController();
|
|
65
|
+
const timeout = setTimeout(() => controller.abort(), opts.timeoutMs);
|
|
66
|
+
try {
|
|
67
|
+
const headers = {
|
|
68
|
+
'Content-Type': 'application/json',
|
|
69
|
+
Accept: 'application/json'
|
|
70
|
+
};
|
|
71
|
+
const key = typeof opts.apiKey === 'string' ? opts.apiKey.trim() : '';
|
|
72
|
+
if (key) {
|
|
73
|
+
headers.Authorization = `Bearer ${key}`;
|
|
74
|
+
}
|
|
75
|
+
const body = {
|
|
76
|
+
model: modelId,
|
|
77
|
+
input: [
|
|
78
|
+
{
|
|
79
|
+
role: 'user',
|
|
80
|
+
content: [
|
|
81
|
+
{
|
|
82
|
+
type: 'input_text',
|
|
83
|
+
text
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
],
|
|
88
|
+
stream: false,
|
|
89
|
+
max_output_tokens: 1
|
|
90
|
+
};
|
|
91
|
+
return await fetcher(opts.endpoint, {
|
|
92
|
+
method: 'POST',
|
|
93
|
+
headers,
|
|
94
|
+
body: JSON.stringify(body),
|
|
95
|
+
signal: controller.signal
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
clearTimeout(timeout);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async function requestWithRetries(modelId, threshold, text, opts) {
|
|
103
|
+
let lastError = null;
|
|
104
|
+
for (let attempt = 0; attempt <= opts.maxRetries; attempt++) {
|
|
105
|
+
try {
|
|
106
|
+
const resp = await requestOnce(modelId, threshold, text, opts);
|
|
107
|
+
if (resp.status !== 429 && resp.status !== 503 && resp.status !== 504) {
|
|
108
|
+
return resp;
|
|
109
|
+
}
|
|
110
|
+
lastError = new Error(`HTTP ${resp.status}`);
|
|
111
|
+
// Drain body to free sockets.
|
|
112
|
+
try {
|
|
113
|
+
await resp.text();
|
|
114
|
+
}
|
|
115
|
+
catch { /* ignore */ }
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
lastError = err;
|
|
119
|
+
}
|
|
120
|
+
if (attempt < opts.maxRetries) {
|
|
121
|
+
await sleep(500 * (attempt + 1));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
throw lastError instanceof Error ? lastError : new Error(String(lastError ?? 'request failed'));
|
|
125
|
+
}
|
|
126
|
+
export async function probeContextForModel(modelId, thresholds, { endpoint, apiKey, timeoutMs = 60_000, fetcher, maxRetries = 2, encoderModel = 'gpt-4o' }) {
|
|
127
|
+
const model = (modelId || '').trim();
|
|
128
|
+
if (!model) {
|
|
129
|
+
throw new Error('probeContextForModel: modelId is required');
|
|
130
|
+
}
|
|
131
|
+
const normalizedEndpoint = (endpoint || '').trim();
|
|
132
|
+
if (!normalizedEndpoint) {
|
|
133
|
+
throw new Error('probeContextForModel: endpoint is required');
|
|
134
|
+
}
|
|
135
|
+
const sorted = thresholds
|
|
136
|
+
.map((value) => Math.floor(Number(value)))
|
|
137
|
+
.filter((value) => Number.isFinite(value) && value > 0);
|
|
138
|
+
if (!sorted.length) {
|
|
139
|
+
throw new Error('probeContextForModel: thresholds must be non-empty');
|
|
140
|
+
}
|
|
141
|
+
const passed = [];
|
|
142
|
+
let firstFailure;
|
|
143
|
+
for (const threshold of sorted) {
|
|
144
|
+
const text = buildTextForExactTokenCount(threshold, encoderModel);
|
|
145
|
+
const check = countTokens(text, encoderModel);
|
|
146
|
+
if (check !== threshold) {
|
|
147
|
+
throw new Error(`probeContextForModel: internal token mismatch: want=${threshold} got=${check}`);
|
|
148
|
+
}
|
|
149
|
+
let resp;
|
|
150
|
+
try {
|
|
151
|
+
resp = await requestWithRetries(model, threshold, text, {
|
|
152
|
+
endpoint: normalizedEndpoint,
|
|
153
|
+
apiKey,
|
|
154
|
+
timeoutMs,
|
|
155
|
+
fetcher,
|
|
156
|
+
maxRetries
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
firstFailure = {
|
|
161
|
+
threshold,
|
|
162
|
+
status: 0,
|
|
163
|
+
message: err instanceof Error ? err.message : String(err)
|
|
164
|
+
};
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
if (resp.ok) {
|
|
168
|
+
passed.push(threshold);
|
|
169
|
+
// Drain body to reuse socket; but keep it small.
|
|
170
|
+
try {
|
|
171
|
+
await resp.text();
|
|
172
|
+
}
|
|
173
|
+
catch { /* ignore */ }
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
let responseText = '';
|
|
177
|
+
try {
|
|
178
|
+
responseText = await resp.text();
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
responseText = '';
|
|
182
|
+
}
|
|
183
|
+
firstFailure = {
|
|
184
|
+
threshold,
|
|
185
|
+
status: resp.status,
|
|
186
|
+
statusText: resp.statusText,
|
|
187
|
+
responseSnippet: responseText ? responseText.slice(0, 2000) : undefined
|
|
188
|
+
};
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
modelId: model,
|
|
193
|
+
thresholds: sorted,
|
|
194
|
+
passed,
|
|
195
|
+
maxPassedTokens: passed.length ? passed[passed.length - 1] : null,
|
|
196
|
+
...(firstFailure ? { firstFailure } : {})
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=probe-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe-context.js","sourceRoot":"","sources":["../../../src/tools/provider-update/probe-context.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsonstudio/rcc",
|
|
3
|
-
"version": "0.89.
|
|
3
|
+
"version": "0.89.1189",
|
|
4
4
|
"description": "Multi-provider OpenAI proxy server with anthropic/responses/chat support (release)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"scripts": {
|
|
30
30
|
"build": "npm run llmswitch:ensure && node scripts/build-core.mjs && node scripts/vendor-core.mjs && npm run clean && node scripts/gen-build-info.mjs && tsc && node scripts/copy-compat-assets.mjs && node scripts/copy-modules-config.mjs",
|
|
31
|
-
"build:dev": "BUILD_MODE=dev npm run build && npm run verify:e2e-toolcall && npm run verify:apply-patch && npm run verify:apply-patch-regressions && npm run verify:exec-command && npm run test:routing-instructions && npm run install:global && npm run mock:regressions && npm run verify:errorsamples",
|
|
31
|
+
"build:dev": "BUILD_MODE=dev npm run build && npm run verify:e2e-toolcall && npm run verify:apply-patch && npm run verify:apply-patch-regressions && npm run verify:exec-command && npm run test:routing-instructions && npm run test:cli && npm run install:global && npm run mock:regressions && npm run verify:errorsamples && npm run verify:e2e-gemini-followup-sample",
|
|
32
32
|
"build:min": "npm run llmswitch:ensure && node scripts/build-core.mjs && node scripts/vendor-core.mjs && npm run clean && node scripts/gen-build-info.mjs && tsc && node scripts/copy-compat-assets.mjs && node scripts/copy-modules-config.mjs",
|
|
33
33
|
"prepack": "echo skip-prepack",
|
|
34
34
|
"postbuild": "chmod +x dist/cli.js || true",
|
|
@@ -37,7 +37,8 @@
|
|
|
37
37
|
"dev": "tsx watch src/index.ts",
|
|
38
38
|
"jest:run": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js",
|
|
39
39
|
"test": "npm run test:routing-instructions && npm run mock:regressions",
|
|
40
|
-
"test:routing-instructions": "npm run jest:run -- --runTestsByPath tests/server/runtime/request-executor.single-attempt.spec.ts tests/servertool/virtual-router-series-cooldown.spec.ts tests/servertool/virtual-router-quota-routing.spec.ts tests/servertool/virtual-router-engine-update-deps.spec.ts tests/manager/quota/provider-quota-center.spec.ts tests/manager/quota/provider-quota-store.spec.ts tests/server/http-server/daemon-admin.e2e.spec.ts tests/server/http-server/quota-view-injection.spec.ts tests/server/handlers/sse-timeout.spec.ts tests/utils/is-direct-execution.test.ts tests/utils/windows-netstat.test.ts",
|
|
40
|
+
"test:routing-instructions": "npm run jest:run -- --runTestsByPath tests/server/runtime/request-executor.single-attempt.spec.ts tests/server/runtime/executor-provider.retryable.spec.ts tests/providers/core/runtime/gemini-cli-http-provider.unit.test.ts tests/sharedmodule/gemini-mapper-functioncall-args.spec.ts tests/unified-hub/policy-observe-shadow.spec.ts tests/servertool/stop-message-auto.spec.ts tests/servertool/gemini-empty-reply-continue.spec.ts tests/servertool/apply-patch-guard.spec.ts tests/servertool/exec-command-guard.spec.ts tests/servertool/server-side-web-search.spec.ts tests/servertool/vision-flow.spec.ts tests/servertool/iflow-model-error-retry.spec.ts tests/servertool/virtual-router-routing-instructions.spec.ts tests/servertool/virtual-router-series-cooldown.spec.ts tests/servertool/virtual-router-quota-routing.spec.ts tests/servertool/virtual-router-engine-update-deps.spec.ts tests/manager/quota/provider-quota-center.spec.ts tests/manager/quota/provider-quota-store.spec.ts tests/server/http-server/daemon-admin.e2e.spec.ts tests/server/http-server/quota-view-injection.spec.ts tests/server/http-server/hub-policy-injection.spec.ts tests/server/handlers/sse-timeout.spec.ts tests/utils/is-direct-execution.test.ts tests/utils/windows-netstat.test.ts",
|
|
41
|
+
"test:cli": "npm run jest:run -- --runTestsByPath tests/cli/clean-command.spec.ts tests/cli/code-command.spec.ts tests/cli/config-command.spec.ts tests/cli/env-command.spec.ts tests/cli/env-output.spec.ts tests/cli/examples-command.spec.ts tests/cli/port-command.spec.ts tests/cli/port-utils.spec.ts tests/cli/restart-command.spec.ts tests/cli/smoke.spec.ts tests/cli/start-command.spec.ts tests/cli/status-command.spec.ts tests/cli/stop-command.spec.ts",
|
|
41
42
|
"test:watch": "npm run jest:run -- --watch",
|
|
42
43
|
"test:coverage": "npm run jest:run -- --coverage",
|
|
43
44
|
"test:integration": "npm run jest:run -- --testPathPattern=integration",
|
|
@@ -46,6 +47,8 @@
|
|
|
46
47
|
"test:protocol": "npm run jest:run -- --testPathPattern=protocol-tools-e2e.spec.ts --runInBand --detectOpenHandles --forceExit",
|
|
47
48
|
"test:dry-run": "node tests/basic-dry-run.mjs",
|
|
48
49
|
"test:lmstudio-dryrun": "node tests/lmstudio-tools-bidir-dry-run.mjs",
|
|
50
|
+
"test:unified-hub-shadow": "node scripts/tests/unified-hub-shadow-regression.mjs",
|
|
51
|
+
"test:unified-hub-responses-enforce": "node scripts/tests/unified-hub-responses-enforce-safe.mjs",
|
|
49
52
|
"lint": "eslint --no-eslintrc -c .eslintrc.json src --ext .ts --no-cache",
|
|
50
53
|
"lint:fix": "eslint --no-eslintrc -c .eslintrc.json src --ext .ts --fix --no-cache",
|
|
51
54
|
"lint:strict": "eslint --no-eslintrc -c .eslintrc.json src --ext .ts --max-warnings 0 --no-cache",
|
|
@@ -57,6 +60,7 @@
|
|
|
57
60
|
"verify:apply-patch-regressions": "node scripts/verify-apply-patch-regressions.mjs",
|
|
58
61
|
"verify:exec-command": "node scripts/tests/exec-command-loop.mjs",
|
|
59
62
|
"verify:errorsamples": "node scripts/verify-codex-error-samples.mjs",
|
|
63
|
+
"verify:e2e-gemini-followup-sample": "node scripts/verify-e2e-gemini-followup-sample.mjs",
|
|
60
64
|
"install:global": "./scripts/install-global.sh",
|
|
61
65
|
"install:release": "./scripts/install-release.sh",
|
|
62
66
|
"audit:tool-text": "node scripts/audit-tool-text.mjs",
|
|
@@ -65,6 +69,7 @@
|
|
|
65
69
|
"start:verify": "node scripts/start-verify.mjs --mode bg --timeout 180",
|
|
66
70
|
"build:verify": "npm run build && npm run -s start:verify",
|
|
67
71
|
"smoke:protocol": "node scripts/protocol-smoke.mjs",
|
|
72
|
+
"smoke:antigravity": "node scripts/antigravity-smoke.mjs",
|
|
68
73
|
"monitor:diff": "node scripts/monitor-diff.mjs",
|
|
69
74
|
"monitor:capture:responses": "node scripts/upstream-multiturn-capture.mjs",
|
|
70
75
|
"monitor:embed": "node scripts/monitor-embed-keys.mjs",
|
|
@@ -73,6 +78,7 @@
|
|
|
73
78
|
"build:smoke": "npm run build && node scripts/protocol-smoke.mjs",
|
|
74
79
|
"verify:sse-loop": "node scripts/verify-sse-loop.mjs",
|
|
75
80
|
"snapshot:inspect": "node scripts/snapshot-inspect.mjs",
|
|
81
|
+
"policy:report": "node scripts/policy-violations-report.mjs",
|
|
76
82
|
"debug:responses": "tsx tools/responses-debug-client/src/index.ts",
|
|
77
83
|
"debug:responses:lmstudio:text": "tsx tools/responses-debug-client/src/index.ts --file tools/responses-debug-client/payloads/lmstudio-text.json --baseURL ${LMSTUDIO_BASEURL:-http://127.0.0.1:1234/v1}",
|
|
78
84
|
"debug:responses:lmstudio:tool": "tsx tools/responses-debug-client/src/index.ts --file tools/responses-debug-client/payloads/lmstudio-tool.json --baseURL ${LMSTUDIO_BASEURL:-http://127.0.0.1:1234/v1}",
|
|
@@ -131,7 +137,7 @@
|
|
|
131
137
|
},
|
|
132
138
|
"dependencies": {
|
|
133
139
|
"@anthropic-ai/sdk": "^0.65.0",
|
|
134
|
-
"@jsonstudio/llms": "^0.6.
|
|
140
|
+
"@jsonstudio/llms": "^0.6.938",
|
|
135
141
|
"@jsonstudio/rcc": "^0.89.555",
|
|
136
142
|
"@lmstudio/sdk": "^1.5.0",
|
|
137
143
|
"@radix-ui/react-switch": "^1.2.6",
|
|
@@ -19,6 +19,7 @@ import fs from 'fs';
|
|
|
19
19
|
import path from 'path';
|
|
20
20
|
import os from 'os';
|
|
21
21
|
import url from 'url';
|
|
22
|
+
import { writeErrorSampleJson } from './lib/errorsamples.mjs';
|
|
22
23
|
|
|
23
24
|
const __filename = url.fileURLToPath(import.meta.url);
|
|
24
25
|
const __dirname = path.dirname(__filename);
|
|
@@ -92,6 +93,7 @@ function diffViews(label, a, b) {
|
|
|
92
93
|
} else {
|
|
93
94
|
console.log('[DIFF]', diffs);
|
|
94
95
|
}
|
|
96
|
+
return diffs;
|
|
95
97
|
}
|
|
96
98
|
|
|
97
99
|
async function main() {
|
|
@@ -140,7 +142,7 @@ async function main() {
|
|
|
140
142
|
|
|
141
143
|
const viewReqA = viewRequestAnth(anthReq);
|
|
142
144
|
const viewReqB = viewRequestAnth(anthReqChat);
|
|
143
|
-
diffViews('REQUEST COMPARISON', viewReqA, viewReqB);
|
|
145
|
+
const reqDiffs = diffViews('REQUEST COMPARISON', viewReqA, viewReqB);
|
|
144
146
|
|
|
145
147
|
// 响应:A 直通 vs B 编解码
|
|
146
148
|
// 使用与 anthropic-snapshot-closed-loop 相同路径:
|
|
@@ -199,12 +201,47 @@ async function main() {
|
|
|
199
201
|
|
|
200
202
|
const viewRespA = viewResponseAnth(anthResp);
|
|
201
203
|
const viewRespB = viewResponseAnth(anthRespChat);
|
|
202
|
-
diffViews('RESPONSE COMPARISON', viewRespA, viewRespB);
|
|
204
|
+
const respDiffs = diffViews('RESPONSE COMPARISON', viewRespA, viewRespB);
|
|
205
|
+
|
|
206
|
+
if (reqDiffs.length || respDiffs.length) {
|
|
207
|
+
const record = {
|
|
208
|
+
kind: 'anthropic-compare-modes-diff',
|
|
209
|
+
requestFile: reqFile,
|
|
210
|
+
responseFile: respFile,
|
|
211
|
+
requestDiffs: reqDiffs,
|
|
212
|
+
responseDiffs: respDiffs,
|
|
213
|
+
requestView: { passthrough: viewReqA, chatBridge: viewReqB },
|
|
214
|
+
responseView: { passthrough: viewRespA, chatBridge: viewRespB }
|
|
215
|
+
};
|
|
216
|
+
try {
|
|
217
|
+
const file = await writeErrorSampleJson({
|
|
218
|
+
group: 'anthropic-compare-modes',
|
|
219
|
+
kind: 'diff',
|
|
220
|
+
payload: record
|
|
221
|
+
});
|
|
222
|
+
console.error(`[anthropic-compare-modes] wrote errorsample: ${file}`);
|
|
223
|
+
} catch (err) {
|
|
224
|
+
console.error('[anthropic-compare-modes] failed to write errorsample:', err);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
203
227
|
}
|
|
204
228
|
|
|
205
229
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
206
|
-
main().catch(err => {
|
|
230
|
+
main().catch(async (err) => {
|
|
207
231
|
console.error('anthropic-compare-modes failed:', err);
|
|
232
|
+
try {
|
|
233
|
+
const file = await writeErrorSampleJson({
|
|
234
|
+
group: 'anthropic-compare-modes',
|
|
235
|
+
kind: 'fatal',
|
|
236
|
+
payload: {
|
|
237
|
+
kind: 'anthropic-compare-modes-fatal',
|
|
238
|
+
stamp: new Date().toISOString(),
|
|
239
|
+
argv: process.argv.slice(2),
|
|
240
|
+
error: String(err?.stack || err)
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
console.error(`[anthropic-compare-modes] wrote errorsample: ${file}`);
|
|
244
|
+
} catch {}
|
|
208
245
|
process.exit(1);
|
|
209
246
|
});
|
|
210
247
|
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Antigravity upstream smoke test (direct provider call).
|
|
4
|
+
*
|
|
5
|
+
* Purpose:
|
|
6
|
+
* - Hit Antigravity (Cloud Code Assist) upstream using Gemini CLI HTTP provider.
|
|
7
|
+
* - Validate request shaping is accepted (especially "no body.request.request.*").
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* node scripts/antigravity-smoke.mjs
|
|
11
|
+
*
|
|
12
|
+
* Required:
|
|
13
|
+
* - A valid Antigravity OAuth token file (JSON), e.g.
|
|
14
|
+
* ~/.routecodex/auth/antigravity-oauth-1-<alias>.json
|
|
15
|
+
* - Export env:
|
|
16
|
+
* ANTIGRAVITY_TOKEN_FILE=/absolute/path/to/token.json
|
|
17
|
+
*
|
|
18
|
+
* Optional:
|
|
19
|
+
* ANTIGRAVITY_BASEURL=https://daily-cloudcode-pa.sandbox.googleapis.com
|
|
20
|
+
* ANTIGRAVITY_MODEL=gemini-3-pro-high
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import fs from 'node:fs';
|
|
24
|
+
import os from 'node:os';
|
|
25
|
+
import path from 'node:path';
|
|
26
|
+
|
|
27
|
+
import { GeminiCLIHttpProvider } from '../dist/providers/core/runtime/gemini-cli-http-provider.js';
|
|
28
|
+
import { GeminiSseToJsonConverter } from '../sharedmodule/llmswitch-core/dist/sse/sse-to-json/index.js';
|
|
29
|
+
|
|
30
|
+
function resolveTokenFile() {
|
|
31
|
+
const raw =
|
|
32
|
+
(process.env.ANTIGRAVITY_TOKEN_FILE && process.env.ANTIGRAVITY_TOKEN_FILE.trim()) ||
|
|
33
|
+
(process.env.ROUTECODEX_ANTIGRAVITY_TOKEN_FILE && process.env.ROUTECODEX_ANTIGRAVITY_TOKEN_FILE.trim()) ||
|
|
34
|
+
(process.env.RCC_ANTIGRAVITY_TOKEN_FILE && process.env.RCC_ANTIGRAVITY_TOKEN_FILE.trim()) ||
|
|
35
|
+
'';
|
|
36
|
+
if (raw) {
|
|
37
|
+
const expanded = raw.startsWith('~/') ? path.join(os.homedir(), raw.slice(2)) : raw;
|
|
38
|
+
return path.isAbsolute(expanded) ? expanded : path.resolve(expanded);
|
|
39
|
+
}
|
|
40
|
+
const authDir = path.join(os.homedir(), '.routecodex', 'auth');
|
|
41
|
+
const defaultPath = path.join(authDir, 'antigravity-oauth.json');
|
|
42
|
+
if (fs.existsSync(defaultPath)) {
|
|
43
|
+
return defaultPath;
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const candidates = fs
|
|
47
|
+
.readdirSync(authDir)
|
|
48
|
+
.filter((name) => name.startsWith('antigravity-oauth-') && name.endsWith('.json'))
|
|
49
|
+
.map((name) => path.join(authDir, name));
|
|
50
|
+
if (!candidates.length) {
|
|
51
|
+
return defaultPath;
|
|
52
|
+
}
|
|
53
|
+
candidates.sort((a, b) => {
|
|
54
|
+
try {
|
|
55
|
+
return fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs;
|
|
56
|
+
} catch {
|
|
57
|
+
return 0;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
return candidates[0];
|
|
61
|
+
} catch {
|
|
62
|
+
return defaultPath;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function extractTextFromGeminiResponse(payload) {
|
|
67
|
+
const candidates = Array.isArray(payload?.candidates) ? payload.candidates : [];
|
|
68
|
+
const primary = candidates[0] && typeof candidates[0] === 'object' ? candidates[0] : null;
|
|
69
|
+
const parts = primary?.content?.parts;
|
|
70
|
+
if (!Array.isArray(parts)) return '';
|
|
71
|
+
return parts
|
|
72
|
+
.map((p) => (p && typeof p === 'object' && typeof p.text === 'string' ? p.text : ''))
|
|
73
|
+
.filter((s) => s.trim().length > 0)
|
|
74
|
+
.join('')
|
|
75
|
+
.trim();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function decodeGeminiSse(stream, requestId) {
|
|
79
|
+
const converter = new GeminiSseToJsonConverter();
|
|
80
|
+
return await converter.convertSseToJson(stream, { requestId });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function main() {
|
|
84
|
+
const tokenFile = resolveTokenFile();
|
|
85
|
+
if (!fs.existsSync(tokenFile)) {
|
|
86
|
+
console.error(`[antigravity-smoke] Missing token file: ${tokenFile}`);
|
|
87
|
+
console.error('[antigravity-smoke] Create one via: `node scripts/auth-antigravity-token.mjs`');
|
|
88
|
+
process.exit(2);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const baseUrl =
|
|
92
|
+
(process.env.ANTIGRAVITY_BASEURL && process.env.ANTIGRAVITY_BASEURL.trim()) ||
|
|
93
|
+
'https://daily-cloudcode-pa.sandbox.googleapis.com';
|
|
94
|
+
const model =
|
|
95
|
+
(process.env.ANTIGRAVITY_MODEL && process.env.ANTIGRAVITY_MODEL.trim()) || 'gemini-3-pro-high';
|
|
96
|
+
|
|
97
|
+
const config = {
|
|
98
|
+
id: 'antigravity-smoke',
|
|
99
|
+
config: {
|
|
100
|
+
// IMPORTANT: Antigravity uses Gemini CLI protocol (Cloud Code Assist v1internal).
|
|
101
|
+
providerType: 'gemini',
|
|
102
|
+
providerId: 'antigravity',
|
|
103
|
+
baseUrl,
|
|
104
|
+
auth: {
|
|
105
|
+
type: 'antigravity-oauth',
|
|
106
|
+
apiKey: '',
|
|
107
|
+
tokenFile
|
|
108
|
+
},
|
|
109
|
+
overrides: { maxRetries: 0 }
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const dependencies = {
|
|
114
|
+
logger: { logModule: () => {}, logProviderRequest: () => {} },
|
|
115
|
+
errorHandlingCenter: { handleError: async () => {} }
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const provider = new GeminiCLIHttpProvider(config, dependencies);
|
|
119
|
+
await provider.initialize();
|
|
120
|
+
|
|
121
|
+
const buildPayload = ({ nestedRequest }) => {
|
|
122
|
+
const core = {
|
|
123
|
+
model,
|
|
124
|
+
contents: [{ role: 'user', parts: [{ text: 'Reply with exactly: pong' }] }],
|
|
125
|
+
// Antigravity agent runtime may spend a portion of maxOutputTokens on internal thoughts.
|
|
126
|
+
// Use a sufficiently high value so we can reliably observe a visible text response.
|
|
127
|
+
generationConfig: { maxOutputTokens: 256 }
|
|
128
|
+
};
|
|
129
|
+
if (nestedRequest) {
|
|
130
|
+
// This intentionally mimics an illegal intermediate shape that used to produce
|
|
131
|
+
// `body.request.request.*` after protocol-client wrapping. Provider preprocess
|
|
132
|
+
// must flatten it before sending upstream.
|
|
133
|
+
return { model, request: { contents: core.contents, generationConfig: core.generationConfig } };
|
|
134
|
+
}
|
|
135
|
+
return core;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
for (const variant of [
|
|
139
|
+
{ name: 'top_level_contents', nestedRequest: false },
|
|
140
|
+
{ name: 'nested_request_container', nestedRequest: true }
|
|
141
|
+
]) {
|
|
142
|
+
const maxAttempts = 3;
|
|
143
|
+
let lastDecoded = null;
|
|
144
|
+
let okText = '';
|
|
145
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
146
|
+
const requestId = `antigravity-smoke-${variant.name}-a${attempt}-${Date.now()}`;
|
|
147
|
+
const request = { data: buildPayload(variant) };
|
|
148
|
+
const res = await provider.sendRequest(request);
|
|
149
|
+
const stream = res?.__sse_responses || res?.data?.__sse_responses;
|
|
150
|
+
if (!stream) {
|
|
151
|
+
console.error(`[antigravity-smoke] Missing SSE stream for ${variant.name} (attempt ${attempt}/${maxAttempts})`);
|
|
152
|
+
console.error(JSON.stringify(res?.data ?? res).slice(0, 800));
|
|
153
|
+
process.exit(3);
|
|
154
|
+
}
|
|
155
|
+
const decoded = await decodeGeminiSse(stream, requestId);
|
|
156
|
+
lastDecoded = decoded;
|
|
157
|
+
const text = extractTextFromGeminiResponse(decoded);
|
|
158
|
+
if (text && text.toLowerCase().includes('pong')) {
|
|
159
|
+
okText = text;
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
if (attempt < maxAttempts) {
|
|
163
|
+
await new Promise((r) => setTimeout(r, 250));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (!okText) {
|
|
167
|
+
console.error(`[antigravity-smoke] Unexpected response for ${variant.name}`);
|
|
168
|
+
console.error(JSON.stringify(lastDecoded).slice(0, 1200));
|
|
169
|
+
process.exit(4);
|
|
170
|
+
}
|
|
171
|
+
console.log(`[antigravity-smoke] OK ${variant.name}: ${JSON.stringify(okText).slice(0, 120)}`);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
console.log('[antigravity-smoke] done');
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
main().catch((err) => {
|
|
178
|
+
console.error('[antigravity-smoke] Error:', err instanceof Error ? err.stack || err.message : String(err));
|
|
179
|
+
process.exit(1);
|
|
180
|
+
});
|