@jsonstudio/rcc 0.89.1121 → 0.89.1136

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 (79) hide show
  1. package/dist/build-info.js +2 -2
  2. package/dist/cli.js +39 -1
  3. package/dist/cli.js.map +1 -1
  4. package/dist/client/gemini/gemini-protocol-client.js +5 -0
  5. package/dist/client/gemini/gemini-protocol-client.js.map +1 -1
  6. package/dist/commands/provider-update.js +355 -5
  7. package/dist/commands/provider-update.js.map +1 -1
  8. package/dist/docs/daemon-admin-ui.html +583 -87
  9. package/dist/index.js +32 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/manager/modules/quota/index.d.ts +19 -1
  12. package/dist/manager/modules/quota/index.js +109 -1
  13. package/dist/manager/modules/quota/index.js.map +1 -1
  14. package/dist/manager/types.d.ts +5 -0
  15. package/dist/providers/core/config/service-profiles.js +1 -1
  16. package/dist/providers/core/config/service-profiles.js.map +1 -1
  17. package/dist/providers/core/runtime/gemini-cli-http-provider.js +0 -1
  18. package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -1
  19. package/dist/providers/core/runtime/http-transport-provider.js +26 -38
  20. package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
  21. package/dist/server/handlers/handler-utils.d.ts +1 -1
  22. package/dist/server/handlers/handler-utils.js +4 -4
  23. package/dist/server/handlers/handler-utils.js.map +1 -1
  24. package/dist/server/handlers/responses-handler.js +2 -1
  25. package/dist/server/handlers/responses-handler.js.map +1 -1
  26. package/dist/server/handlers/sse-dispatcher.js +1 -4
  27. package/dist/server/handlers/sse-dispatcher.js.map +1 -1
  28. package/dist/server/runtime/http-server/colored-logger.d.ts +1 -1
  29. package/dist/server/runtime/http-server/colored-logger.js +22 -10
  30. package/dist/server/runtime/http-server/colored-logger.js.map +1 -1
  31. package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js +12 -6
  32. package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js.map +1 -1
  33. package/dist/server/runtime/http-server/daemon-admin/providers-handler.js +116 -98
  34. package/dist/server/runtime/http-server/daemon-admin/providers-handler.js.map +1 -1
  35. package/dist/server/runtime/http-server/daemon-admin/quota-handler.js +108 -15
  36. package/dist/server/runtime/http-server/daemon-admin/quota-handler.js.map +1 -1
  37. package/dist/server/runtime/http-server/daemon-admin/restart-handler.js +2 -1
  38. package/dist/server/runtime/http-server/daemon-admin/restart-handler.js.map +1 -1
  39. package/dist/server/runtime/http-server/daemon-admin/stats-handler.d.ts +3 -0
  40. package/dist/server/runtime/http-server/daemon-admin/stats-handler.js +56 -0
  41. package/dist/server/runtime/http-server/daemon-admin/stats-handler.js.map +1 -0
  42. package/dist/server/runtime/http-server/daemon-admin/status-handler.js +8 -4
  43. package/dist/server/runtime/http-server/daemon-admin/status-handler.js.map +1 -1
  44. package/dist/server/runtime/http-server/daemon-admin-routes.d.ts +9 -0
  45. package/dist/server/runtime/http-server/daemon-admin-routes.js +3 -0
  46. package/dist/server/runtime/http-server/daemon-admin-routes.js.map +1 -1
  47. package/dist/server/runtime/http-server/executor-provider.js +74 -0
  48. package/dist/server/runtime/http-server/executor-provider.js.map +1 -1
  49. package/dist/server/runtime/http-server/index.d.ts +1 -0
  50. package/dist/server/runtime/http-server/index.js +42 -11
  51. package/dist/server/runtime/http-server/index.js.map +1 -1
  52. package/dist/server/runtime/http-server/request-executor.js +9 -10
  53. package/dist/server/runtime/http-server/request-executor.js.map +1 -1
  54. package/dist/server/runtime/http-server/routes.d.ts +5 -0
  55. package/dist/server/runtime/http-server/routes.js +9 -0
  56. package/dist/server/runtime/http-server/routes.js.map +1 -1
  57. package/dist/server/runtime/http-server/stats-manager.d.ts +7 -0
  58. package/dist/server/runtime/http-server/stats-manager.js +22 -3
  59. package/dist/server/runtime/http-server/stats-manager.js.map +1 -1
  60. package/dist/server/runtime/http-server/types.d.ts +5 -0
  61. package/dist/server/utils/http-error-mapper.js +70 -9
  62. package/dist/server/utils/http-error-mapper.js.map +1 -1
  63. package/dist/server/utils/request-id-manager.js +9 -5
  64. package/dist/server/utils/request-id-manager.js.map +1 -1
  65. package/dist/server/utils/sse-request-parser.js +2 -1
  66. package/dist/server/utils/sse-request-parser.js.map +1 -1
  67. package/dist/server/utils/utf8-chunk-buffer.d.ts +15 -30
  68. package/dist/server/utils/utf8-chunk-buffer.js +78 -88
  69. package/dist/server/utils/utf8-chunk-buffer.js.map +1 -1
  70. package/dist/server/utils/warmup-storm-tracker.js +1 -1
  71. package/dist/server/utils/warmup-storm-tracker.js.map +1 -1
  72. package/dist/tools/provider-update/fetch-models.js +8 -5
  73. package/dist/tools/provider-update/fetch-models.js.map +1 -1
  74. package/dist/tools/provider-update/probe-context.d.ts +24 -0
  75. package/dist/tools/provider-update/probe-context.js +199 -0
  76. package/dist/tools/provider-update/probe-context.js.map +1 -0
  77. package/dist/tools/provider-update/types.d.ts +1 -0
  78. package/package.json +3 -3
  79. package/scripts/scan-apply-patch-samples.mjs +148 -7
@@ -17,6 +17,7 @@
17
17
  import fs from 'node:fs/promises';
18
18
  import path from 'node:path';
19
19
  import os from 'node:os';
20
+ import crypto from 'node:crypto';
20
21
  import { fileURLToPath, pathToFileURL } from 'node:url';
21
22
 
22
23
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -27,8 +28,13 @@ const coreLoaderUrl = pathToFileURL(coreLoaderPath).href;
27
28
 
28
29
  const HOME = os.homedir();
29
30
  const USER_CODEX_ROOT = path.join(HOME, '.routecodex', 'codex-samples');
31
+ const USER_CODEX_ROOT_ALT = path.join(HOME, '.routecodex', 'codex samples');
30
32
  const USER_CODEX_PENDING = path.join(USER_CODEX_ROOT, 'openai-chat', '__pending__');
31
33
  const REPO_GOLDENS_ROOT = path.join(repoRoot, 'samples', 'ci-goldens');
34
+ const ERROR_SAMPLES_ROOT = path.join(HOME, '.routecodex', 'errorsamples', 'apply_patch');
35
+
36
+ const DEFAULT_CAPTURE_TOTAL_LIMIT = 5000;
37
+ const DEFAULT_CAPTURE_PER_REASON_LIMIT = 250;
32
38
 
33
39
  async function fileExists(p) {
34
40
  try {
@@ -111,6 +117,74 @@ function extractApplyPatchArgs(doc, { allowRegressionOriginalArgs } = { allowReg
111
117
  return out;
112
118
  }
113
119
 
120
+ function isContextMismatchReason(reason) {
121
+ // We only capture/repair shape issues; context mismatches are not actionable here.
122
+ // Keep this conservative: if a new reason is introduced, we still capture it unless
123
+ // it clearly indicates a context mismatch.
124
+ if (!reason) return false;
125
+ const r = String(reason);
126
+ return (
127
+ r.includes('context') ||
128
+ r.includes('expected') ||
129
+ r.includes('hunk') ||
130
+ r.includes('no_match') ||
131
+ r.includes('not_found')
132
+ );
133
+ }
134
+
135
+ function stableHash(input) {
136
+ return crypto.createHash('sha256').update(input).digest('hex').slice(0, 16);
137
+ }
138
+
139
+ async function captureFailure({
140
+ destRoot,
141
+ label,
142
+ sourceFile,
143
+ reason,
144
+ originalArgs,
145
+ validationResult,
146
+ captureState,
147
+ }) {
148
+ if (isContextMismatchReason(reason)) return;
149
+ if (captureState?.reasonAllowList && !captureState.reasonAllowList.has(reason)) return;
150
+ if (!destRoot) return;
151
+
152
+ const totalLimit = captureState.totalLimit ?? DEFAULT_CAPTURE_TOTAL_LIMIT;
153
+ const perReasonLimit = captureState.perReasonLimit ?? DEFAULT_CAPTURE_PER_REASON_LIMIT;
154
+ if (captureState.totalCaptured >= totalLimit) return;
155
+
156
+ const currentReasonCount = captureState.byReason.get(reason) ?? 0;
157
+ if (currentReasonCount >= perReasonLimit) return;
158
+
159
+ const key = `${label}\n${reason}\n${sourceFile}\n${originalArgs}`;
160
+ const filename = `sample_${stableHash(key)}.json`;
161
+ const folder = path.join(destRoot, reason);
162
+ const outPath = path.join(folder, filename);
163
+
164
+ try {
165
+ await fs.access(outPath);
166
+ return;
167
+ } catch {
168
+ // continue
169
+ }
170
+
171
+ await fs.mkdir(folder, { recursive: true });
172
+ const payload = {
173
+ tool: 'apply_patch',
174
+ label,
175
+ reason,
176
+ capturedAt: new Date().toISOString(),
177
+ sourceFile,
178
+ argsSha256: crypto.createHash('sha256').update(originalArgs).digest('hex'),
179
+ originalArgs,
180
+ validationResult,
181
+ };
182
+ await fs.writeFile(outPath, JSON.stringify(payload, null, 2), 'utf-8');
183
+
184
+ captureState.totalCaptured += 1;
185
+ captureState.byReason.set(reason, currentReasonCount + 1);
186
+ }
187
+
114
188
  async function loadValidator() {
115
189
  if (!(await fileExists(coreLoaderPath))) {
116
190
  throw new Error(`core-loader missing at ${coreLoaderPath} (run npm run build:dev first)`);
@@ -123,7 +197,7 @@ async function loadValidator() {
123
197
  return { validateToolCall };
124
198
  }
125
199
 
126
- async function scanRoot(label, rootDir, validateToolCall) {
200
+ async function scanRoot(label, rootDir, validateToolCall, capture) {
127
201
  if (!(await fileExists(rootDir))) {
128
202
  return { label, rootDir, files: 0, calls: 0, ok: 0, byReason: new Map(), examples: [] };
129
203
  }
@@ -168,6 +242,17 @@ async function scanRoot(label, rootDir, validateToolCall) {
168
242
  const cur = byReason.get(reason) || { count: 0 };
169
243
  cur.count += 1;
170
244
  byReason.set(reason, cur);
245
+ if (capture?.enabled) {
246
+ await captureFailure({
247
+ destRoot: capture.destRoot,
248
+ label,
249
+ sourceFile: filePath,
250
+ reason,
251
+ originalArgs: args,
252
+ validationResult: res,
253
+ captureState: capture.state,
254
+ });
255
+ }
171
256
  if (examples.length < 12) {
172
257
  examples.push({ file: filePath, reason });
173
258
  }
@@ -200,17 +285,73 @@ function printReport(report) {
200
285
  async function main() {
201
286
  const { validateToolCall } = await loadValidator();
202
287
 
203
- const repo = await scanRoot('repo samples/ci-goldens', REPO_GOLDENS_ROOT, validateToolCall);
288
+ const captureEnabled = process.argv.slice(2).includes('--capture') || process.env.ROUTECODEX_SCAN_CAPTURE === '1';
289
+ const captureRepo = process.argv.slice(2).includes('--capture-repo') || process.env.ROUTECODEX_SCAN_CAPTURE_REPO === '1';
290
+ const captureRoot = process.env.ROUTECODEX_ERRORSAMPLES_DIR || ERROR_SAMPLES_ROOT;
291
+ const totalLimit = Number.parseInt(process.env.ROUTECODEX_CAPTURE_TOTAL_LIMIT || '', 10);
292
+ const perReasonLimit = Number.parseInt(process.env.ROUTECODEX_CAPTURE_PER_REASON_LIMIT || '', 10);
293
+ const reasonsArg = process.argv
294
+ .slice(2)
295
+ .find((arg) => arg.startsWith('--capture-reasons='))
296
+ ?.split('=')[1];
297
+ const reasonsEnv = process.env.ROUTECODEX_CAPTURE_REASONS;
298
+ const reasonAllowListRaw = (reasonsArg || reasonsEnv || '').trim();
299
+ const reasonAllowList = reasonAllowListRaw
300
+ ? new Set(
301
+ reasonAllowListRaw
302
+ .split(',')
303
+ .map((s) => s.trim())
304
+ .filter(Boolean)
305
+ )
306
+ : null;
307
+ const captureState = {
308
+ totalCaptured: 0,
309
+ totalLimit: Number.isFinite(totalLimit) ? totalLimit : DEFAULT_CAPTURE_TOTAL_LIMIT,
310
+ perReasonLimit: Number.isFinite(perReasonLimit) ? perReasonLimit : DEFAULT_CAPTURE_PER_REASON_LIMIT,
311
+ byReason: new Map(),
312
+ reasonAllowList,
313
+ };
314
+
315
+ const repo = await scanRoot('repo samples/ci-goldens', REPO_GOLDENS_ROOT, validateToolCall, {
316
+ enabled: captureEnabled && captureRepo,
317
+ destRoot: captureRoot,
318
+ state: captureState,
319
+ });
204
320
  printReport(repo);
205
321
 
206
322
  const userAll = process.argv.slice(2).includes('--user-all');
207
- const userRoot = userAll && (await fileExists(USER_CODEX_ROOT)) ? USER_CODEX_ROOT : (await fileExists(USER_CODEX_PENDING)) ? USER_CODEX_PENDING : USER_CODEX_ROOT;
208
- const user = await scanRoot(`user ${userAll ? '~/.routecodex/codex-samples (all)' : '~/.routecodex/codex-samples/openai-chat/__pending__'}`, userRoot, validateToolCall);
209
- printReport(user);
323
+ const userRoots = [];
324
+ if (userAll) {
325
+ if (await fileExists(USER_CODEX_ROOT)) userRoots.push({ label: 'user ~/.routecodex/codex-samples (all)', root: USER_CODEX_ROOT });
326
+ if (await fileExists(USER_CODEX_ROOT_ALT))
327
+ userRoots.push({ label: 'user ~/.routecodex/codex samples (all)', root: USER_CODEX_ROOT_ALT });
328
+ } else {
329
+ const pending = (await fileExists(USER_CODEX_PENDING)) ? USER_CODEX_PENDING : null;
330
+ if (pending) userRoots.push({ label: 'user ~/.routecodex/codex-samples/openai-chat/__pending__', root: pending });
331
+ else if (await fileExists(USER_CODEX_ROOT)) userRoots.push({ label: 'user ~/.routecodex/codex-samples', root: USER_CODEX_ROOT });
332
+ else if (await fileExists(USER_CODEX_ROOT_ALT)) userRoots.push({ label: 'user ~/.routecodex/codex samples', root: USER_CODEX_ROOT_ALT });
333
+ else userRoots.push({ label: 'user ~/.routecodex/codex-samples', root: USER_CODEX_ROOT });
334
+ }
210
335
 
211
- const totalCalls = repo.calls + user.calls;
212
- const totalOk = repo.ok + user.ok;
336
+ const userReports = [];
337
+ for (const entry of userRoots) {
338
+ const report = await scanRoot(entry.label, entry.root, validateToolCall, {
339
+ enabled: captureEnabled,
340
+ destRoot: captureRoot,
341
+ state: captureState,
342
+ });
343
+ userReports.push(report);
344
+ printReport(report);
345
+ }
346
+
347
+ const totalCalls = repo.calls + userReports.reduce((sum, r) => sum + r.calls, 0);
348
+ const totalOk = repo.ok + userReports.reduce((sum, r) => sum + r.ok, 0);
213
349
  console.log(`\n[scan] TOTAL apply_patch_calls=${totalCalls} ok=${totalOk} fail=${totalCalls - totalOk}`);
350
+ if (captureEnabled) {
351
+ console.log(
352
+ `[scan] captured_failures=${captureState.totalCaptured} dest=${captureRoot} (per_reason<=${captureState.perReasonLimit}, total<=${captureState.totalLimit})`
353
+ );
354
+ }
214
355
 
215
356
  process.exitCode = totalCalls - totalOk > 0 ? 1 : 0;
216
357
  }