@codeproxy/core 0.1.6 → 0.1.7
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/README.md +3 -0
- package/README.zh-CN.md +3 -0
- package/dist/index.cjs +50 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +50 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -23,6 +23,8 @@ interface CreateResponsesFetchOptions {
|
|
|
23
23
|
passthroughFetch?: typeof fetch;
|
|
24
24
|
/** Drop image/file parts from user messages (e.g. DeepSeek text-only models). */
|
|
25
25
|
dropImages?: boolean;
|
|
26
|
+
/** Fallback thought signature for Gemini OpenAI-compatible tool histories. */
|
|
27
|
+
fallbackThoughtSignature?: string;
|
|
26
28
|
/** Optional callback to receive cache statistics. */
|
|
27
29
|
onCacheStats?: (stats: CacheStats) => void;
|
|
28
30
|
/** Override reasoning_effort sent to the upstream model (OpenAI Chat / Anthropic). */
|
|
@@ -94,6 +96,7 @@ interface ResponsesFunctionCallItem {
|
|
|
94
96
|
call_id?: string;
|
|
95
97
|
name?: string;
|
|
96
98
|
arguments?: string | Record<string, unknown>;
|
|
99
|
+
thought_signature?: string;
|
|
97
100
|
[key: string]: unknown;
|
|
98
101
|
}
|
|
99
102
|
interface ResponsesFunctionCallOutputItem {
|
|
@@ -239,6 +242,7 @@ interface ResponsesOutputFunctionCall {
|
|
|
239
242
|
name?: string;
|
|
240
243
|
arguments?: string;
|
|
241
244
|
call_id?: string;
|
|
245
|
+
thought_signature?: string;
|
|
242
246
|
action?: {
|
|
243
247
|
type?: string;
|
|
244
248
|
command?: string[];
|
|
@@ -488,10 +492,18 @@ declare namespace index$2 {
|
|
|
488
492
|
interface OpenAiChatToolCall {
|
|
489
493
|
id?: string;
|
|
490
494
|
type?: 'function' | string;
|
|
495
|
+
extra_content?: {
|
|
496
|
+
google?: {
|
|
497
|
+
thought_signature?: string;
|
|
498
|
+
[key: string]: unknown;
|
|
499
|
+
};
|
|
500
|
+
[key: string]: unknown;
|
|
501
|
+
};
|
|
491
502
|
function?: {
|
|
492
503
|
name?: string;
|
|
493
504
|
arguments?: string | Record<string, unknown>;
|
|
494
505
|
};
|
|
506
|
+
thought_signature?: string;
|
|
495
507
|
}
|
|
496
508
|
interface OpenAiChatMessage {
|
|
497
509
|
role: 'system' | 'user' | 'assistant' | 'tool' | string;
|
|
@@ -575,10 +587,12 @@ interface OpenAiChatStreamDeltaToolCall {
|
|
|
575
587
|
index: number;
|
|
576
588
|
id?: string;
|
|
577
589
|
type?: string;
|
|
590
|
+
extra_content?: OpenAiChatToolCall['extra_content'];
|
|
578
591
|
function?: {
|
|
579
592
|
name?: string;
|
|
580
593
|
arguments?: string | Record<string, unknown>;
|
|
581
594
|
};
|
|
595
|
+
thought_signature?: string;
|
|
582
596
|
}
|
|
583
597
|
interface OpenAiChatStreamDelta {
|
|
584
598
|
role?: string;
|
|
@@ -613,6 +627,8 @@ interface TranslateRequestOptions {
|
|
|
613
627
|
/** If true, strip `strict` from function tools (some upstreams reject it). */
|
|
614
628
|
/** If true, drop image/file parts from user messages (e.g. DeepSeek text-only models). */
|
|
615
629
|
dropImages?: boolean;
|
|
630
|
+
/** Fallback signature for Gemini OpenAI histories that lack returned signatures. */
|
|
631
|
+
fallbackThoughtSignature?: string;
|
|
616
632
|
}
|
|
617
633
|
interface TranslateRequestResult {
|
|
618
634
|
request: OpenAiChatRequest;
|
package/dist/index.d.ts
CHANGED
|
@@ -23,6 +23,8 @@ interface CreateResponsesFetchOptions {
|
|
|
23
23
|
passthroughFetch?: typeof fetch;
|
|
24
24
|
/** Drop image/file parts from user messages (e.g. DeepSeek text-only models). */
|
|
25
25
|
dropImages?: boolean;
|
|
26
|
+
/** Fallback thought signature for Gemini OpenAI-compatible tool histories. */
|
|
27
|
+
fallbackThoughtSignature?: string;
|
|
26
28
|
/** Optional callback to receive cache statistics. */
|
|
27
29
|
onCacheStats?: (stats: CacheStats) => void;
|
|
28
30
|
/** Override reasoning_effort sent to the upstream model (OpenAI Chat / Anthropic). */
|
|
@@ -94,6 +96,7 @@ interface ResponsesFunctionCallItem {
|
|
|
94
96
|
call_id?: string;
|
|
95
97
|
name?: string;
|
|
96
98
|
arguments?: string | Record<string, unknown>;
|
|
99
|
+
thought_signature?: string;
|
|
97
100
|
[key: string]: unknown;
|
|
98
101
|
}
|
|
99
102
|
interface ResponsesFunctionCallOutputItem {
|
|
@@ -239,6 +242,7 @@ interface ResponsesOutputFunctionCall {
|
|
|
239
242
|
name?: string;
|
|
240
243
|
arguments?: string;
|
|
241
244
|
call_id?: string;
|
|
245
|
+
thought_signature?: string;
|
|
242
246
|
action?: {
|
|
243
247
|
type?: string;
|
|
244
248
|
command?: string[];
|
|
@@ -488,10 +492,18 @@ declare namespace index$2 {
|
|
|
488
492
|
interface OpenAiChatToolCall {
|
|
489
493
|
id?: string;
|
|
490
494
|
type?: 'function' | string;
|
|
495
|
+
extra_content?: {
|
|
496
|
+
google?: {
|
|
497
|
+
thought_signature?: string;
|
|
498
|
+
[key: string]: unknown;
|
|
499
|
+
};
|
|
500
|
+
[key: string]: unknown;
|
|
501
|
+
};
|
|
491
502
|
function?: {
|
|
492
503
|
name?: string;
|
|
493
504
|
arguments?: string | Record<string, unknown>;
|
|
494
505
|
};
|
|
506
|
+
thought_signature?: string;
|
|
495
507
|
}
|
|
496
508
|
interface OpenAiChatMessage {
|
|
497
509
|
role: 'system' | 'user' | 'assistant' | 'tool' | string;
|
|
@@ -575,10 +587,12 @@ interface OpenAiChatStreamDeltaToolCall {
|
|
|
575
587
|
index: number;
|
|
576
588
|
id?: string;
|
|
577
589
|
type?: string;
|
|
590
|
+
extra_content?: OpenAiChatToolCall['extra_content'];
|
|
578
591
|
function?: {
|
|
579
592
|
name?: string;
|
|
580
593
|
arguments?: string | Record<string, unknown>;
|
|
581
594
|
};
|
|
595
|
+
thought_signature?: string;
|
|
582
596
|
}
|
|
583
597
|
interface OpenAiChatStreamDelta {
|
|
584
598
|
role?: string;
|
|
@@ -613,6 +627,8 @@ interface TranslateRequestOptions {
|
|
|
613
627
|
/** If true, strip `strict` from function tools (some upstreams reject it). */
|
|
614
628
|
/** If true, drop image/file parts from user messages (e.g. DeepSeek text-only models). */
|
|
615
629
|
dropImages?: boolean;
|
|
630
|
+
/** Fallback signature for Gemini OpenAI histories that lack returned signatures. */
|
|
631
|
+
fallbackThoughtSignature?: string;
|
|
616
632
|
}
|
|
617
633
|
interface TranslateRequestResult {
|
|
618
634
|
request: OpenAiChatRequest;
|
package/dist/index.js
CHANGED
|
@@ -525,9 +525,14 @@ function ensureEndsWithUser(messages) {
|
|
|
525
525
|
return [...messages, { role: "user", content: [{ type: "text", text: "Continue." }] }];
|
|
526
526
|
}
|
|
527
527
|
function markBlocksForCache(blocks) {
|
|
528
|
+
let count = 0;
|
|
528
529
|
for (const block of blocks) {
|
|
529
530
|
if (!block.cache_control) {
|
|
530
531
|
block.cache_control = { type: "ephemeral" };
|
|
532
|
+
count++;
|
|
533
|
+
if (count >= 3) {
|
|
534
|
+
break;
|
|
535
|
+
}
|
|
531
536
|
}
|
|
532
537
|
}
|
|
533
538
|
return blocks;
|
|
@@ -836,6 +841,8 @@ var StreamTranslator = class {
|
|
|
836
841
|
*finalize() {
|
|
837
842
|
const items = [];
|
|
838
843
|
if (this.textItem) {
|
|
844
|
+
this.textItem.status = "completed";
|
|
845
|
+
this.textItem.content[0].text = this.textBuffer;
|
|
839
846
|
items.push({ index: this.textItemIndex, item: this.textItem });
|
|
840
847
|
}
|
|
841
848
|
for (const block of this.blocks.values()) {
|
|
@@ -947,15 +954,22 @@ var StreamTranslator = class {
|
|
|
947
954
|
if (btype === "tool_use") {
|
|
948
955
|
const outputIndex = this.outputCounter++;
|
|
949
956
|
const callId = block.id ?? makeId("call");
|
|
957
|
+
const initialInput = typeof block.input === "object" && block.input !== null ? jsonStringifySafe(block.input) : "";
|
|
958
|
+
const hasInitialInput = initialInput !== "" && initialInput !== "{}";
|
|
950
959
|
const item = {
|
|
951
960
|
id: callId,
|
|
952
961
|
type: "function_call",
|
|
953
962
|
status: "in_progress",
|
|
954
963
|
name: block.name ?? "",
|
|
955
|
-
arguments: "",
|
|
964
|
+
arguments: hasInitialInput ? initialInput : "",
|
|
956
965
|
call_id: callId
|
|
957
966
|
};
|
|
958
|
-
this.blocks.set(index, {
|
|
967
|
+
this.blocks.set(index, {
|
|
968
|
+
type: "tool_use",
|
|
969
|
+
outputIndex,
|
|
970
|
+
item,
|
|
971
|
+
buffer: hasInitialInput ? initialInput : ""
|
|
972
|
+
});
|
|
959
973
|
yield this.makeEvent("response.output_item.added", {
|
|
960
974
|
response_id: this.responseId,
|
|
961
975
|
output_index: outputIndex,
|
|
@@ -1074,7 +1088,7 @@ function translateRequest2(data, options = {}) {
|
|
|
1074
1088
|
continue;
|
|
1075
1089
|
}
|
|
1076
1090
|
const rawItem = raw;
|
|
1077
|
-
processInputItem(rawItem, messages, options
|
|
1091
|
+
processInputItem(rawItem, messages, options);
|
|
1078
1092
|
}
|
|
1079
1093
|
const request = {
|
|
1080
1094
|
model: data.model,
|
|
@@ -1134,7 +1148,7 @@ function buildSystemContent(instructions) {
|
|
|
1134
1148
|
}
|
|
1135
1149
|
return out;
|
|
1136
1150
|
}
|
|
1137
|
-
function processInputItem(item, messages,
|
|
1151
|
+
function processInputItem(item, messages, options) {
|
|
1138
1152
|
const itemType = String(item.type) || "message";
|
|
1139
1153
|
const getLastAssistant = () => {
|
|
1140
1154
|
const last = messages[messages.length - 1];
|
|
@@ -1196,7 +1210,7 @@ function processInputItem(item, messages, dropImages) {
|
|
|
1196
1210
|
} else if (contentPart.type === "reasoning_text") {
|
|
1197
1211
|
reasoningContent += String(contentPart.text ?? "");
|
|
1198
1212
|
} else if (contentPart.type === "input_image" || contentPart.type === "image" || contentPart.type === "image_url") {
|
|
1199
|
-
if (dropImages) {
|
|
1213
|
+
if (options.dropImages) {
|
|
1200
1214
|
continue;
|
|
1201
1215
|
}
|
|
1202
1216
|
let url = "";
|
|
@@ -1271,7 +1285,7 @@ function processInputItem(item, messages, dropImages) {
|
|
|
1271
1285
|
return;
|
|
1272
1286
|
}
|
|
1273
1287
|
if (itemType === "function_call" || itemType === "commandExecution" || itemType === "local_shell_call" || itemType === "fileChange" || itemType === "custom_tool_call" || itemType === "web_search_call") {
|
|
1274
|
-
processToolCall(item, messages, getLastAssistant);
|
|
1288
|
+
processToolCall(item, messages, getLastAssistant, options.fallbackThoughtSignature);
|
|
1275
1289
|
return;
|
|
1276
1290
|
}
|
|
1277
1291
|
if (itemType === "function_call_output" || itemType === "commandExecutionOutput" || itemType === "fileChangeOutput" || itemType === "custom_tool_call_output") {
|
|
@@ -1279,7 +1293,7 @@ function processInputItem(item, messages, dropImages) {
|
|
|
1279
1293
|
return;
|
|
1280
1294
|
}
|
|
1281
1295
|
}
|
|
1282
|
-
function processToolCall(item, messages, getLastAssistant) {
|
|
1296
|
+
function processToolCall(item, messages, getLastAssistant, fallbackThoughtSignature) {
|
|
1283
1297
|
const callId = String(item.call_id ?? "") || String(item.id ?? "") || makeId("call");
|
|
1284
1298
|
let name = item.name === void 0 ? void 0 : String(item.name);
|
|
1285
1299
|
const itemType = item.type === void 0 ? void 0 : String(item.type);
|
|
@@ -1325,16 +1339,18 @@ function processToolCall(item, messages, getLastAssistant) {
|
|
|
1325
1339
|
if (!amsg.tool_calls) {
|
|
1326
1340
|
amsg.tool_calls = [];
|
|
1327
1341
|
}
|
|
1328
|
-
|
|
1342
|
+
const toolCall = {
|
|
1329
1343
|
id: callId,
|
|
1330
1344
|
type: "function",
|
|
1331
1345
|
function: { name, arguments: argsStr }
|
|
1332
|
-
}
|
|
1333
|
-
const sig = item.thought_signature;
|
|
1346
|
+
};
|
|
1347
|
+
const sig = item.thought_signature ?? fallbackThoughtSignature;
|
|
1334
1348
|
const thought = item.thought;
|
|
1335
1349
|
if (typeof sig === "string" && sig) {
|
|
1350
|
+
toolCall.extra_content = { google: { thought_signature: sig } };
|
|
1336
1351
|
amsg.thought_signature = sig;
|
|
1337
1352
|
}
|
|
1353
|
+
amsg.tool_calls.push(toolCall);
|
|
1338
1354
|
if (typeof thought === "string" && thought) {
|
|
1339
1355
|
amsg.reasoning_content = (amsg.reasoning_content ?? "") + thought;
|
|
1340
1356
|
}
|
|
@@ -1538,6 +1554,10 @@ function mapToolCallToOutput(tc) {
|
|
|
1538
1554
|
arguments: args,
|
|
1539
1555
|
call_id: callId
|
|
1540
1556
|
};
|
|
1557
|
+
const thoughtSignature = getThoughtSignature(tc);
|
|
1558
|
+
if (thoughtSignature) {
|
|
1559
|
+
item.thought_signature = thoughtSignature;
|
|
1560
|
+
}
|
|
1541
1561
|
if (SHELL_TOOL_NAMES3.has(name)) {
|
|
1542
1562
|
item.type = "local_shell_call";
|
|
1543
1563
|
const parsed = safeJsonParse(args);
|
|
@@ -1545,6 +1565,10 @@ function mapToolCallToOutput(tc) {
|
|
|
1545
1565
|
}
|
|
1546
1566
|
return item;
|
|
1547
1567
|
}
|
|
1568
|
+
function getThoughtSignature(tc) {
|
|
1569
|
+
const sig = tc.extra_content?.google?.thought_signature ?? tc.thought_signature;
|
|
1570
|
+
return typeof sig === "string" && sig ? sig : void 0;
|
|
1571
|
+
}
|
|
1548
1572
|
|
|
1549
1573
|
// src/translate/openai/translateStream.ts
|
|
1550
1574
|
var SHELL_TOOL_NAMES4 = /* @__PURE__ */ new Set(["shell", "container.exec", "shell_command"]);
|
|
@@ -1647,6 +1671,10 @@ var StreamTranslator2 = class {
|
|
|
1647
1671
|
});
|
|
1648
1672
|
}
|
|
1649
1673
|
const fn = tc.function;
|
|
1674
|
+
const thoughtSignature = getThoughtSignature2(tc);
|
|
1675
|
+
if (thoughtSignature) {
|
|
1676
|
+
state.item.thought_signature = thoughtSignature;
|
|
1677
|
+
}
|
|
1650
1678
|
if (fn?.name) {
|
|
1651
1679
|
state.item.name = (state.item.name ?? "") + fn.name;
|
|
1652
1680
|
}
|
|
@@ -1758,6 +1786,10 @@ var StreamTranslator2 = class {
|
|
|
1758
1786
|
};
|
|
1759
1787
|
}
|
|
1760
1788
|
};
|
|
1789
|
+
function getThoughtSignature2(tc) {
|
|
1790
|
+
const sig = tc.extra_content?.google?.thought_signature ?? tc.thought_signature;
|
|
1791
|
+
return typeof sig === "string" && sig ? sig : void 0;
|
|
1792
|
+
}
|
|
1761
1793
|
|
|
1762
1794
|
// src/fetch.ts
|
|
1763
1795
|
function createResponsesFetch(options) {
|
|
@@ -1765,7 +1797,7 @@ function createResponsesFetch(options) {
|
|
|
1765
1797
|
throw new Error("baseUrl is required");
|
|
1766
1798
|
}
|
|
1767
1799
|
const rawFormat = options.upstreamFormat;
|
|
1768
|
-
const format = rawFormat ? normalizeFormat(rawFormat) : inferFormatFromUrl(options.baseUrl) ?? "openai-chat";
|
|
1800
|
+
const format = rawFormat ? normalizeFormat(rawFormat) : inferFormatFromUrl(options.baseUrl) ?? inferFormatFromModel(options.model) ?? "openai-chat";
|
|
1769
1801
|
if (!format) {
|
|
1770
1802
|
throw new Error(
|
|
1771
1803
|
`Unsupported upstream format: ${options.upstreamFormat}. Use 'anthropic' or 'openai-chat'`
|
|
@@ -1936,7 +1968,8 @@ async function handleResponses(request, format, options, baseFetch, incomingHead
|
|
|
1936
1968
|
options.baseUrl,
|
|
1937
1969
|
dropImages,
|
|
1938
1970
|
options.reasoning_effort,
|
|
1939
|
-
options.thinking
|
|
1971
|
+
options.thinking,
|
|
1972
|
+
options.fallbackThoughtSignature
|
|
1940
1973
|
);
|
|
1941
1974
|
const upstreamHeaders = buildUpstreamHeaders(format, options, incomingHeaders);
|
|
1942
1975
|
const upstream = await baseFetch(resolvedUrl, {
|
|
@@ -1992,7 +2025,7 @@ function buildRequestMetadata(request, temperature, top_p) {
|
|
|
1992
2025
|
metadata: request.metadata ?? {}
|
|
1993
2026
|
};
|
|
1994
2027
|
}
|
|
1995
|
-
function buildUpstreamBody(request, format, streaming, baseUrl, dropImages, reasoning_effort, thinking) {
|
|
2028
|
+
function buildUpstreamBody(request, format, streaming, baseUrl, dropImages, reasoning_effort, thinking, fallbackThoughtSignature) {
|
|
1996
2029
|
if (format === "anthropic") {
|
|
1997
2030
|
const { request: ar } = translateRequest(request);
|
|
1998
2031
|
ar.stream = streaming;
|
|
@@ -2023,7 +2056,10 @@ function buildUpstreamBody(request, format, streaming, baseUrl, dropImages, reas
|
|
|
2023
2056
|
requestMetadata: buildRequestMetadata(request, ar.temperature, ar.top_p)
|
|
2024
2057
|
};
|
|
2025
2058
|
}
|
|
2026
|
-
const { request: cr } = translateRequest2(request, {
|
|
2059
|
+
const { request: cr } = translateRequest2(request, {
|
|
2060
|
+
dropImages,
|
|
2061
|
+
fallbackThoughtSignature
|
|
2062
|
+
});
|
|
2027
2063
|
cr.stream = streaming;
|
|
2028
2064
|
if (streaming) {
|
|
2029
2065
|
cr.stream_options = { include_usage: true };
|