@jsonstudio/rcc 0.89.932 → 0.89.935

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.
@@ -1,6 +1,6 @@
1
1
  export const buildInfo = {
2
2
  mode: 'release',
3
- version: '0.89.932',
4
- buildTime: '2026-01-11T14:44:43.501Z'
3
+ version: '0.89.935',
4
+ buildTime: '2026-01-11T15:36:09.036Z'
5
5
  };
6
6
  //# sourceMappingURL=build-info.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsonstudio/rcc",
3
- "version": "0.89.932",
3
+ "version": "0.89.935",
4
4
  "description": "Multi-provider OpenAI proxy server with anthropic/responses/chat support (release)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -130,7 +130,7 @@
130
130
  },
131
131
  "dependencies": {
132
132
  "@anthropic-ai/sdk": "^0.65.0",
133
- "@jsonstudio/llms": "^0.6.626",
133
+ "@jsonstudio/llms": "^0.6.631",
134
134
  "@jsonstudio/rcc": "^0.89.555",
135
135
  "@lmstudio/sdk": "^1.5.0",
136
136
  "@radix-ui/react-switch": "^1.2.6",
@@ -300,6 +300,67 @@ function collectInvalidNames(payload) {
300
300
  return failures;
301
301
  }
302
302
 
303
+ function validateToolCallIds(payload, sample, tagSet) {
304
+ const errors = [];
305
+ if (!payload || typeof payload !== 'object') {
306
+ return errors;
307
+ }
308
+ const wantsFcIds =
309
+ tagSet.has('require_fc_call_ids') ||
310
+ tagSet.has('missing_tool_call_id') ||
311
+ tagSet.has('regression');
312
+
313
+ const allToolCallIds = new Set();
314
+ if (Array.isArray(payload.output)) {
315
+ payload.output.forEach((entry, oi) => {
316
+ if (!entry || typeof entry !== 'object') return;
317
+ const toolCalls = Array.isArray(entry.tool_calls) ? entry.tool_calls : [];
318
+ toolCalls.forEach((tc, ti) => {
319
+ if (!tc || typeof tc !== 'object') return;
320
+ const rawId = typeof tc.id === 'string' ? tc.id.trim() : '';
321
+ if (!rawId) {
322
+ errors.push(`output[${oi}].tool_calls[${ti}].id missing`);
323
+ return;
324
+ }
325
+ allToolCallIds.add(rawId);
326
+ if (wantsFcIds && !/^call_[A-Za-z0-9]+$/.test(rawId)) {
327
+ errors.push(`output[${oi}].tool_calls[${ti}].id has invalid format: ${rawId}`);
328
+ }
329
+ });
330
+ });
331
+ }
332
+
333
+ const requiredAction = payload.required_action;
334
+ const submit = requiredAction && typeof requiredAction === 'object'
335
+ ? requiredAction.submit_tool_outputs
336
+ : undefined;
337
+ const submitCalls = submit && typeof submit === 'object'
338
+ ? submit.tool_calls
339
+ : undefined;
340
+ if (Array.isArray(submitCalls)) {
341
+ submitCalls.forEach((tc, i) => {
342
+ if (!tc || typeof tc !== 'object') return;
343
+ const rawId = typeof tc.tool_call_id === 'string' ? tc.tool_call_id.trim() : '';
344
+ if (!rawId) {
345
+ errors.push(`required_action.submit_tool_outputs.tool_calls[${i}].tool_call_id missing`);
346
+ return;
347
+ }
348
+ if (wantsFcIds && !/^call_[A-Za-z0-9]+$/.test(rawId)) {
349
+ errors.push(
350
+ `required_action.submit_tool_outputs.tool_calls[${i}].tool_call_id has invalid format: ${rawId}`
351
+ );
352
+ }
353
+ if (allToolCallIds.size > 0 && !allToolCallIds.has(rawId)) {
354
+ errors.push(
355
+ `required_action.submit_tool_outputs.tool_calls[${i}].tool_call_id=${rawId} has no matching output.tool_calls entry`
356
+ );
357
+ }
358
+ });
359
+ }
360
+
361
+ return errors;
362
+ }
363
+
303
364
  function extractRequestBody(doc) {
304
365
  const body = doc && typeof doc === 'object' ? doc.body : undefined;
305
366
  if (!body || typeof body !== 'object') {
@@ -379,6 +440,7 @@ async function runSample(sample, index) {
379
440
  return undefined;
380
441
  }
381
442
  })();
443
+ const tags = new Set(Array.isArray(sample.tags) ? sample.tags : []);
382
444
  if (body && Array.isArray(body.output)) {
383
445
  const invalid = collectInvalidNames(body);
384
446
  if (invalid.length) {
@@ -388,6 +450,14 @@ async function runSample(sample, index) {
388
450
  .join('\n')}`
389
451
  );
390
452
  }
453
+ const idErrors = validateToolCallIds(body, sample, tags);
454
+ if (idErrors.length) {
455
+ throw new Error(
456
+ `[${sample.reqId}] tool_call_id invariants failed:\n${idErrors
457
+ .map((msg) => ` - ${msg}`)
458
+ .join('\n')}`
459
+ );
460
+ }
391
461
  }
392
462
  } catch (error) {
393
463
  const logs = server.logs();