opencodekit 0.18.19 → 0.18.20
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/index.js
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -360,49 +360,66 @@ function swapModelInBody(
|
|
|
360
360
|
|
|
361
361
|
// Maximum length for item IDs in the OpenAI Responses API
|
|
362
362
|
const MAX_RESPONSE_API_ID_LENGTH = 64;
|
|
363
|
+
// OpenAI Responses API only allows: letters, numbers, underscores, dashes
|
|
364
|
+
const INVALID_ID_CHARS = /[^a-zA-Z0-9_-]/g;
|
|
365
|
+
|
|
366
|
+
/** Check if an ID contains characters not allowed by the Responses API */
|
|
367
|
+
function hasInvalidIdChars(id: string): boolean {
|
|
368
|
+
// Use a non-global regex for .test() to avoid lastIndex state bug
|
|
369
|
+
return /[^a-zA-Z0-9_-]/.test(id);
|
|
370
|
+
}
|
|
371
|
+
|
|
363
372
|
/**
|
|
364
|
-
* Sanitize an ID
|
|
365
|
-
*
|
|
366
|
-
*
|
|
367
|
-
*
|
|
368
|
-
*
|
|
373
|
+
* Sanitize an ID for the Responses API.
|
|
374
|
+
* Handles three issues from GitHub Copilot:
|
|
375
|
+
* 1. Invalid characters — Copilot IDs contain +, |, /, = (base64-like encoding)
|
|
376
|
+
* 2. Wrong prefix — GPT models return "h_" instead of "fc_" for function_call items
|
|
377
|
+
* 3. Excessive length — Copilot returns 400+ char IDs (max is 64)
|
|
378
|
+
*
|
|
379
|
+
* Approach matches anomalyco/opencode: replace invalid chars with "_", preserve prefix,
|
|
380
|
+
* truncate to 64 chars, strip trailing underscores.
|
|
369
381
|
*
|
|
370
382
|
* @param id - The original ID to sanitize
|
|
371
383
|
* @param forcedPrefix - If provided, use this prefix instead of the detected one.
|
|
372
|
-
* Used when the original prefix is wrong (e.g., Copilot returns "h_" instead of "fc_").
|
|
373
384
|
* See: https://github.com/vercel/ai/issues/5171
|
|
374
385
|
*/
|
|
375
386
|
function sanitizeResponseId(id: string, forcedPrefix?: string): string {
|
|
387
|
+
if (!id) return id;
|
|
388
|
+
|
|
376
389
|
// Detect the original prefix (e.g., "fc_", "msg_", "call_", "resp_", "h_")
|
|
377
390
|
const prefixMatch = id.match(/^([a-z]+_)/);
|
|
378
391
|
const detectedPrefix = prefixMatch ? prefixMatch[1] : "";
|
|
379
392
|
const prefix = forcedPrefix ?? detectedPrefix;
|
|
380
393
|
|
|
381
|
-
// If no forced prefix and within length, return as-is
|
|
382
|
-
if (!forcedPrefix && (!id || id.length <= MAX_RESPONSE_API_ID_LENGTH)) {
|
|
383
|
-
return id;
|
|
384
|
-
}
|
|
385
|
-
|
|
386
394
|
// Strip the original prefix to get the core ID
|
|
387
|
-
const
|
|
395
|
+
const rawCore = id.slice(detectedPrefix.length);
|
|
396
|
+
// Replace invalid characters with underscores (same as anomalyco/opencode)
|
|
397
|
+
const cleanCore = rawCore.replace(INVALID_ID_CHARS, "_").replace(/_+$/g, "");
|
|
398
|
+
|
|
399
|
+
// Check if any sanitization is actually needed
|
|
400
|
+
const needsSanitization = forcedPrefix || hasInvalidIdChars(rawCore) ||
|
|
401
|
+
id.length > MAX_RESPONSE_API_ID_LENGTH;
|
|
402
|
+
|
|
403
|
+
if (!needsSanitization) return id;
|
|
388
404
|
|
|
389
|
-
// If
|
|
390
|
-
if (
|
|
391
|
-
return `${prefix}${
|
|
405
|
+
// If result fits within length and core is non-empty, use cleaned core directly
|
|
406
|
+
if (cleanCore.length > 0 && (prefix.length + cleanCore.length) <= MAX_RESPONSE_API_ID_LENGTH) {
|
|
407
|
+
return `${prefix}${cleanCore}`;
|
|
392
408
|
}
|
|
393
409
|
|
|
394
|
-
// Hash the full original ID for deterministic uniqueness
|
|
410
|
+
// Hash the full original ID for deterministic uniqueness when truncating
|
|
395
411
|
let hash = 0;
|
|
396
412
|
for (let i = 0; i < id.length; i++) {
|
|
397
413
|
hash = ((hash << 5) - hash + id.charCodeAt(i)) | 0;
|
|
398
414
|
}
|
|
399
415
|
const hashStr = Math.abs(hash).toString(36);
|
|
400
|
-
// Take some chars from the core for additional uniqueness
|
|
401
416
|
const maxMiddleLen =
|
|
402
417
|
MAX_RESPONSE_API_ID_LENGTH - prefix.length - hashStr.length - 1;
|
|
403
|
-
const middle =
|
|
418
|
+
const middle = cleanCore.slice(0, Math.max(0, maxMiddleLen));
|
|
404
419
|
// Format: prefix + middle + "_" + hash (ensure total <= 64)
|
|
405
|
-
|
|
420
|
+
const result = `${prefix}${middle}_${hashStr}`.slice(0, MAX_RESPONSE_API_ID_LENGTH);
|
|
421
|
+
// Strip trailing underscores from truncation
|
|
422
|
+
return result.replace(/_+$/, "");
|
|
406
423
|
}
|
|
407
424
|
|
|
408
425
|
/**
|
|
@@ -419,16 +436,21 @@ function getExpectedPrefix(item: any): string | null {
|
|
|
419
436
|
return null;
|
|
420
437
|
}
|
|
421
438
|
|
|
439
|
+
/** Check if a string ID needs sanitization (invalid chars or too long) */
|
|
440
|
+
function idNeedsSanitization(id: string): boolean {
|
|
441
|
+
return id.length > MAX_RESPONSE_API_ID_LENGTH || hasInvalidIdChars(id);
|
|
442
|
+
}
|
|
443
|
+
|
|
422
444
|
/**
|
|
423
445
|
* Sanitize all IDs in a Responses API input array.
|
|
424
446
|
*
|
|
425
|
-
* Handles
|
|
426
|
-
* 1.
|
|
427
|
-
*
|
|
428
|
-
*
|
|
447
|
+
* Handles THREE classes of invalid IDs:
|
|
448
|
+
* 1. Invalid characters — Copilot IDs contain +, |, /, = (only [a-zA-Z0-9_-] allowed)
|
|
449
|
+
* 2. Wrong prefix — Copilot GPT models return IDs like "h_xxx" instead of "fc_xxx"
|
|
450
|
+
* 3. Excessive length — Copilot returns 400+ char IDs that exceed the 64-char limit.
|
|
429
451
|
*
|
|
430
452
|
* Uses a two-pass approach:
|
|
431
|
-
* - Pass 1: Build an ID remap for all invalid IDs
|
|
453
|
+
* - Pass 1: Build an ID remap for all invalid IDs
|
|
432
454
|
* - Pass 2: Apply the remap to both `id` and `call_id` fields consistently,
|
|
433
455
|
* so function_call_output.call_id stays in sync with function_call.id
|
|
434
456
|
*/
|
|
@@ -448,10 +470,10 @@ function sanitizeResponseInputIds(input: any[]): any[] {
|
|
|
448
470
|
}
|
|
449
471
|
}
|
|
450
472
|
|
|
451
|
-
// Check for excessive length on id
|
|
473
|
+
// Check for invalid chars or excessive length on id
|
|
452
474
|
if (
|
|
453
475
|
typeof item.id === "string" &&
|
|
454
|
-
item.id
|
|
476
|
+
idNeedsSanitization(item.id) &&
|
|
455
477
|
!idRemap.has(item.id)
|
|
456
478
|
) {
|
|
457
479
|
idRemap.set(item.id, sanitizeResponseId(item.id));
|
|
@@ -471,10 +493,10 @@ function sanitizeResponseInputIds(input: any[]): any[] {
|
|
|
471
493
|
}
|
|
472
494
|
}
|
|
473
495
|
|
|
474
|
-
// Check for excessive length on call_id
|
|
496
|
+
// Check for invalid chars or excessive length on call_id
|
|
475
497
|
if (
|
|
476
498
|
typeof item.call_id === "string" &&
|
|
477
|
-
item.call_id
|
|
499
|
+
idNeedsSanitization(item.call_id) &&
|
|
478
500
|
!idRemap.has(item.call_id)
|
|
479
501
|
) {
|
|
480
502
|
idRemap.set(item.call_id, sanitizeResponseId(item.call_id));
|