@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.
Files changed (194) hide show
  1. package/dist/build-info.js +2 -2
  2. package/dist/cli/commands/clean.d.ts +16 -0
  3. package/dist/cli/commands/clean.js +58 -0
  4. package/dist/cli/commands/clean.js.map +1 -0
  5. package/dist/cli/commands/code.d.ts +55 -0
  6. package/dist/cli/commands/code.js +376 -0
  7. package/dist/cli/commands/code.js.map +1 -0
  8. package/dist/cli/commands/config.d.ts +31 -0
  9. package/dist/cli/commands/config.js +168 -0
  10. package/dist/cli/commands/config.js.map +1 -0
  11. package/dist/cli/commands/env.d.ts +20 -0
  12. package/dist/cli/commands/env.js +73 -0
  13. package/dist/cli/commands/env.js.map +1 -0
  14. package/dist/cli/commands/examples.d.ts +5 -0
  15. package/dist/cli/commands/examples.js +66 -0
  16. package/dist/cli/commands/examples.js.map +1 -0
  17. package/dist/cli/commands/port.d.ts +24 -0
  18. package/dist/cli/commands/port.js +85 -0
  19. package/dist/cli/commands/port.js.map +1 -0
  20. package/dist/cli/commands/restart.d.ts +50 -0
  21. package/dist/cli/commands/restart.js +176 -0
  22. package/dist/cli/commands/restart.js.map +1 -0
  23. package/dist/cli/commands/start.d.ts +68 -0
  24. package/dist/cli/commands/start.js +295 -0
  25. package/dist/cli/commands/start.js.map +1 -0
  26. package/dist/cli/commands/status.d.ts +16 -0
  27. package/dist/cli/commands/status.js +104 -0
  28. package/dist/cli/commands/status.js.map +1 -0
  29. package/dist/cli/commands/stop.d.ts +35 -0
  30. package/dist/cli/commands/stop.js +95 -0
  31. package/dist/cli/commands/stop.js.map +1 -0
  32. package/dist/cli/logger.d.ts +8 -0
  33. package/dist/cli/logger.js +9 -0
  34. package/dist/cli/logger.js.map +1 -0
  35. package/dist/cli/main.d.ts +6 -0
  36. package/dist/cli/main.js +16 -0
  37. package/dist/cli/main.js.map +1 -0
  38. package/dist/cli/program.d.ts +8 -0
  39. package/dist/cli/program.js +16 -0
  40. package/dist/cli/program.js.map +1 -0
  41. package/dist/cli/register/basic-commands.d.ts +30 -0
  42. package/dist/cli/register/basic-commands.js +11 -0
  43. package/dist/cli/register/basic-commands.js.map +1 -0
  44. package/dist/cli/register/code-command.d.ts +3 -0
  45. package/dist/cli/register/code-command.js +5 -0
  46. package/dist/cli/register/code-command.js.map +1 -0
  47. package/dist/cli/register/restart-command.d.ts +3 -0
  48. package/dist/cli/register/restart-command.js +5 -0
  49. package/dist/cli/register/restart-command.js.map +1 -0
  50. package/dist/cli/register/start-command.d.ts +3 -0
  51. package/dist/cli/register/start-command.js +5 -0
  52. package/dist/cli/register/start-command.js.map +1 -0
  53. package/dist/cli/register/status-config-commands.d.ts +16 -0
  54. package/dist/cli/register/status-config-commands.js +7 -0
  55. package/dist/cli/register/status-config-commands.js.map +1 -0
  56. package/dist/cli/register/stop-command.d.ts +3 -0
  57. package/dist/cli/register/stop-command.js +5 -0
  58. package/dist/cli/register/stop-command.js.map +1 -0
  59. package/dist/cli/runtime.d.ts +5 -0
  60. package/dist/cli/runtime.js +11 -0
  61. package/dist/cli/runtime.js.map +1 -0
  62. package/dist/cli/server/port-utils.d.ts +52 -0
  63. package/dist/cli/server/port-utils.js +193 -0
  64. package/dist/cli/server/port-utils.js.map +1 -0
  65. package/dist/cli/spinner.d.ts +10 -0
  66. package/dist/cli/spinner.js +59 -0
  67. package/dist/cli/spinner.js.map +1 -0
  68. package/dist/cli/utils/normalize.d.ts +2 -0
  69. package/dist/cli/utils/normalize.js +22 -0
  70. package/dist/cli/utils/normalize.js.map +1 -0
  71. package/dist/cli/utils/safe-read-json.d.ts +1 -0
  72. package/dist/cli/utils/safe-read-json.js +11 -0
  73. package/dist/cli/utils/safe-read-json.js.map +1 -0
  74. package/dist/cli.js +149 -1738
  75. package/dist/cli.js.map +1 -1
  76. package/dist/client/anthropic/anthropic-protocol-client.js +4 -3
  77. package/dist/client/anthropic/anthropic-protocol-client.js.map +1 -1
  78. package/dist/client/gemini/gemini-protocol-client.js +5 -0
  79. package/dist/client/gemini/gemini-protocol-client.js.map +1 -1
  80. package/dist/client/gemini-cli/gemini-cli-protocol-client.d.ts +1 -1
  81. package/dist/client/gemini-cli/gemini-cli-protocol-client.js +10 -3
  82. package/dist/client/gemini-cli/gemini-cli-protocol-client.js.map +1 -1
  83. package/dist/commands/provider-update.js +355 -5
  84. package/dist/commands/provider-update.js.map +1 -1
  85. package/dist/commands/quota-daemon.js +2 -2
  86. package/dist/commands/quota-daemon.js.map +1 -1
  87. package/dist/config/provider-v2-loader.js +4 -2
  88. package/dist/config/provider-v2-loader.js.map +1 -1
  89. package/dist/docs/daemon-admin-ui.html +583 -87
  90. package/dist/index.js +32 -1
  91. package/dist/index.js.map +1 -1
  92. package/dist/manager/modules/quota/index.d.ts +19 -1
  93. package/dist/manager/modules/quota/index.js +130 -5
  94. package/dist/manager/modules/quota/index.js.map +1 -1
  95. package/dist/manager/modules/routing/index.js.map +1 -1
  96. package/dist/manager/storage/file-store.js +1 -1
  97. package/dist/manager/storage/file-store.js.map +1 -1
  98. package/dist/manager/types.d.ts +5 -0
  99. package/dist/providers/auth/oauth-lifecycle.js +2 -2
  100. package/dist/providers/auth/oauth-lifecycle.js.map +1 -1
  101. package/dist/providers/core/api/provider-config.d.ts +2 -0
  102. package/dist/providers/core/api/provider-types.d.ts +2 -0
  103. package/dist/providers/core/config/service-profiles.js +1 -1
  104. package/dist/providers/core/config/service-profiles.js.map +1 -1
  105. package/dist/providers/core/runtime/base-provider.js +21 -27
  106. package/dist/providers/core/runtime/base-provider.js.map +1 -1
  107. package/dist/providers/core/runtime/gemini-cli-http-provider.d.ts +1 -0
  108. package/dist/providers/core/runtime/gemini-cli-http-provider.js +37 -6
  109. package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -1
  110. package/dist/providers/core/runtime/http-request-executor.js +23 -29
  111. package/dist/providers/core/runtime/http-request-executor.js.map +1 -1
  112. package/dist/providers/core/runtime/http-transport-provider.js +46 -38
  113. package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
  114. package/dist/providers/core/utils/http-client.d.ts +9 -0
  115. package/dist/providers/core/utils/http-client.js +9 -11
  116. package/dist/providers/core/utils/http-client.js.map +1 -1
  117. package/dist/providers/core/utils/provider-error-reporter.js +2 -6
  118. package/dist/providers/core/utils/provider-error-reporter.js.map +1 -1
  119. package/dist/providers/mock/mock-provider-runtime.js +19 -5
  120. package/dist/providers/mock/mock-provider-runtime.js.map +1 -1
  121. package/dist/server/handlers/handler-utils.d.ts +1 -1
  122. package/dist/server/handlers/handler-utils.js +4 -4
  123. package/dist/server/handlers/handler-utils.js.map +1 -1
  124. package/dist/server/handlers/responses-handler.js +2 -1
  125. package/dist/server/handlers/responses-handler.js.map +1 -1
  126. package/dist/server/handlers/sse-dispatcher.js +1 -4
  127. package/dist/server/handlers/sse-dispatcher.js.map +1 -1
  128. package/dist/server/runtime/http-server/colored-logger.d.ts +1 -1
  129. package/dist/server/runtime/http-server/colored-logger.js +22 -10
  130. package/dist/server/runtime/http-server/colored-logger.js.map +1 -1
  131. package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js +12 -6
  132. package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js.map +1 -1
  133. package/dist/server/runtime/http-server/daemon-admin/providers-handler.js +116 -98
  134. package/dist/server/runtime/http-server/daemon-admin/providers-handler.js.map +1 -1
  135. package/dist/server/runtime/http-server/daemon-admin/quota-handler.js +108 -15
  136. package/dist/server/runtime/http-server/daemon-admin/quota-handler.js.map +1 -1
  137. package/dist/server/runtime/http-server/daemon-admin/restart-handler.js +2 -1
  138. package/dist/server/runtime/http-server/daemon-admin/restart-handler.js.map +1 -1
  139. package/dist/server/runtime/http-server/daemon-admin/stats-handler.d.ts +3 -0
  140. package/dist/server/runtime/http-server/daemon-admin/stats-handler.js +56 -0
  141. package/dist/server/runtime/http-server/daemon-admin/stats-handler.js.map +1 -0
  142. package/dist/server/runtime/http-server/daemon-admin/status-handler.js +8 -4
  143. package/dist/server/runtime/http-server/daemon-admin/status-handler.js.map +1 -1
  144. package/dist/server/runtime/http-server/daemon-admin-routes.d.ts +9 -0
  145. package/dist/server/runtime/http-server/daemon-admin-routes.js +3 -0
  146. package/dist/server/runtime/http-server/daemon-admin-routes.js.map +1 -1
  147. package/dist/server/runtime/http-server/executor-provider.js +74 -0
  148. package/dist/server/runtime/http-server/executor-provider.js.map +1 -1
  149. package/dist/server/runtime/http-server/index.d.ts +2 -0
  150. package/dist/server/runtime/http-server/index.js +107 -17
  151. package/dist/server/runtime/http-server/index.js.map +1 -1
  152. package/dist/server/runtime/http-server/request-executor.js +18 -11
  153. package/dist/server/runtime/http-server/request-executor.js.map +1 -1
  154. package/dist/server/runtime/http-server/routes.d.ts +5 -0
  155. package/dist/server/runtime/http-server/routes.js +17 -4
  156. package/dist/server/runtime/http-server/routes.js.map +1 -1
  157. package/dist/server/runtime/http-server/stats-manager.d.ts +7 -0
  158. package/dist/server/runtime/http-server/stats-manager.js +31 -6
  159. package/dist/server/runtime/http-server/stats-manager.js.map +1 -1
  160. package/dist/server/runtime/http-server/types.d.ts +5 -0
  161. package/dist/server/utils/http-error-mapper.js +70 -9
  162. package/dist/server/utils/http-error-mapper.js.map +1 -1
  163. package/dist/server/utils/request-id-manager.js +9 -5
  164. package/dist/server/utils/request-id-manager.js.map +1 -1
  165. package/dist/server/utils/sse-request-parser.js +2 -1
  166. package/dist/server/utils/sse-request-parser.js.map +1 -1
  167. package/dist/server/utils/utf8-chunk-buffer.d.ts +15 -30
  168. package/dist/server/utils/utf8-chunk-buffer.js +78 -88
  169. package/dist/server/utils/utf8-chunk-buffer.js.map +1 -1
  170. package/dist/server/utils/warmup-storm-tracker.js +1 -1
  171. package/dist/server/utils/warmup-storm-tracker.js.map +1 -1
  172. package/dist/tools/provider-update/fetch-models.js +8 -5
  173. package/dist/tools/provider-update/fetch-models.js.map +1 -1
  174. package/dist/tools/provider-update/probe-context.d.ts +24 -0
  175. package/dist/tools/provider-update/probe-context.js +199 -0
  176. package/dist/tools/provider-update/probe-context.js.map +1 -0
  177. package/dist/tools/provider-update/types.d.ts +1 -0
  178. package/package.json +10 -4
  179. package/scripts/anthropic-compare-modes.mjs +40 -3
  180. package/scripts/antigravity-smoke.mjs +180 -0
  181. package/scripts/backfill-apply-patch-exec-errorsamples.mjs +225 -0
  182. package/scripts/compare-codex-rccx.mjs +59 -1
  183. package/scripts/compare-responses-request.mjs +50 -4
  184. package/scripts/lib/errorsamples.mjs +23 -0
  185. package/scripts/mock-provider/run-regressions.mjs +12 -2
  186. package/scripts/policy-violations-report.mjs +257 -0
  187. package/scripts/publish-rcc.mjs +16 -2
  188. package/scripts/scan-apply-patch-samples.mjs +148 -7
  189. package/scripts/tests/unified-hub-responses-enforce-safe.mjs +37 -0
  190. package/scripts/tests/unified-hub-shadow-regression.mjs +55 -0
  191. package/scripts/unified-hub-shadow-compare.mjs +359 -0
  192. package/scripts/verify-e2e-gemini-followup-sample.mjs +269 -0
  193. package/scripts/virtual-router-shadow-v2-real.mjs +71 -1
  194. 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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"}
@@ -3,6 +3,7 @@ export type AuthConfig = {
3
3
  apiKey?: string;
4
4
  headerName?: string;
5
5
  prefix?: string;
6
+ tokenFile?: string;
6
7
  clientId?: string;
7
8
  clientSecret?: string;
8
9
  tokenUrl?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsonstudio/rcc",
3
- "version": "0.89.1121",
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.795",
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
+ });