@classicicn/codex-transfer 0.3.2 → 0.3.3
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.en.md +5 -0
- package/README.md +5 -0
- package/dist/codex-transfer.mjs +88 -39
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -375,6 +375,11 @@ const { app, port } = createTransfer({
|
|
|
375
375
|
|
|
376
376
|
## Changelog
|
|
377
377
|
|
|
378
|
+
### v0.3.3 (2026-05-09)
|
|
379
|
+
|
|
380
|
+
- **Non-streaming tool call support**: `fromChatResponse()` now correctly handles `tool_calls`, generating `function_call` output items (previously the non-streaming path ignored tool calls entirely)
|
|
381
|
+
- **Streaming arguments incremental delivery**: `response.output_item.added` and `response.function_call_arguments.delta` events are now emitted in real time during streaming, instead of being sent in batch after stream completion
|
|
382
|
+
|
|
378
383
|
### v0.3.0 (2026-05-08)
|
|
379
384
|
|
|
380
385
|
- **Token usage**: Extract usage from upstream streaming responses — Codex now correctly displays context utilization (fixes 0% display issue)
|
package/README.md
CHANGED
|
@@ -375,6 +375,11 @@ const { app, port } = createTransfer({
|
|
|
375
375
|
|
|
376
376
|
## 更新日志
|
|
377
377
|
|
|
378
|
+
### v0.3.3 (2026-05-09)
|
|
379
|
+
|
|
380
|
+
- **非流式工具调用支持**:`fromChatResponse()` 现在正确处理 `tool_calls`,生成 `function_call` 输出项(此前非流式路径完全忽略工具调用)
|
|
381
|
+
- **流式 arguments 增量推送**:函数调用的 `response.output_item.added` 和 `response.function_call_arguments.delta` 事件在流式过程中实时发出,而非流结束后一次性发送
|
|
382
|
+
|
|
378
383
|
### v0.3.0 (2026-05-08)
|
|
379
384
|
|
|
380
385
|
- **Token 用量**:从上游流式响应中提取 usage,Codex 可正确显示上下文占用率(修复 0% 问题)
|
package/dist/codex-transfer.mjs
CHANGED
|
@@ -2903,6 +2903,7 @@ var SessionStore = class {
|
|
|
2903
2903
|
};
|
|
2904
2904
|
|
|
2905
2905
|
// src/translate.ts
|
|
2906
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
2906
2907
|
function toChatRequest(req, history, sessions) {
|
|
2907
2908
|
const messages = [...history];
|
|
2908
2909
|
const systemText = req.instructions ?? req.system;
|
|
@@ -3019,13 +3020,33 @@ function fromChatResponse(id, model, chat) {
|
|
|
3019
3020
|
completion_tokens: 0,
|
|
3020
3021
|
total_tokens: 0
|
|
3021
3022
|
};
|
|
3022
|
-
const output = [
|
|
3023
|
-
|
|
3023
|
+
const output = [];
|
|
3024
|
+
if (text) {
|
|
3025
|
+
output.push({
|
|
3024
3026
|
type: "message",
|
|
3025
3027
|
role: "assistant",
|
|
3026
3028
|
content: [{ type: "output_text", text }]
|
|
3027
|
-
}
|
|
3028
|
-
|
|
3029
|
+
});
|
|
3030
|
+
}
|
|
3031
|
+
for (const tc of choice.message.tool_calls ?? []) {
|
|
3032
|
+
const tcRecord = tc;
|
|
3033
|
+
const func = tcRecord.function;
|
|
3034
|
+
output.push({
|
|
3035
|
+
type: "function_call",
|
|
3036
|
+
id: `fc_${randomUUID2().replace(/-/g, "")}`,
|
|
3037
|
+
call_id: tcRecord.id ?? "",
|
|
3038
|
+
name: func?.name ?? "",
|
|
3039
|
+
arguments: func?.arguments ?? "{}",
|
|
3040
|
+
status: "completed"
|
|
3041
|
+
});
|
|
3042
|
+
}
|
|
3043
|
+
if (output.length === 0) {
|
|
3044
|
+
output.push({
|
|
3045
|
+
type: "message",
|
|
3046
|
+
role: "assistant",
|
|
3047
|
+
content: [{ type: "output_text", text: "" }]
|
|
3048
|
+
});
|
|
3049
|
+
}
|
|
3029
3050
|
const respUsage = mapUsage(usage);
|
|
3030
3051
|
const response = {
|
|
3031
3052
|
id,
|
|
@@ -3107,7 +3128,7 @@ function reorderForToolCalls(messages) {
|
|
|
3107
3128
|
}
|
|
3108
3129
|
|
|
3109
3130
|
// src/stream.ts
|
|
3110
|
-
import { randomUUID as
|
|
3131
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
3111
3132
|
async function* translateStream(args2, signal) {
|
|
3112
3133
|
const {
|
|
3113
3134
|
url,
|
|
@@ -3120,7 +3141,7 @@ async function* translateStream(args2, signal) {
|
|
|
3120
3141
|
model
|
|
3121
3142
|
} = args2;
|
|
3122
3143
|
try {
|
|
3123
|
-
const msgItemId = `msg_${
|
|
3144
|
+
const msgItemId = `msg_${randomUUID3().replace(/-/g, "")}`;
|
|
3124
3145
|
const createdAt = Math.floor(Date.now() / 1e3);
|
|
3125
3146
|
yield formatSSE("response.created", {
|
|
3126
3147
|
type: "response.created",
|
|
@@ -3251,13 +3272,45 @@ async function* translateStream(args2, signal) {
|
|
|
3251
3272
|
for (const dc of deltaCalls) {
|
|
3252
3273
|
let entry = toolCalls.get(dc.index);
|
|
3253
3274
|
if (!entry) {
|
|
3254
|
-
entry = {
|
|
3275
|
+
entry = {
|
|
3276
|
+
id: "",
|
|
3277
|
+
name: "",
|
|
3278
|
+
arguments: "",
|
|
3279
|
+
fcItemId: `fc_${randomUUID3().replace(/-/g, "")}`,
|
|
3280
|
+
emittedAdded: false
|
|
3281
|
+
};
|
|
3255
3282
|
toolCalls.set(dc.index, entry);
|
|
3256
3283
|
}
|
|
3257
3284
|
if (dc.id) entry.id = dc.id;
|
|
3258
3285
|
if (dc.function?.name) entry.name += dc.function.name;
|
|
3259
|
-
if (
|
|
3286
|
+
if (!entry.emittedAdded && entry.id && entry.name) {
|
|
3287
|
+
const fcOutputIndex = (emittedMessageItem ? 1 : 0) + dc.index;
|
|
3288
|
+
yield formatSSE("response.output_item.added", {
|
|
3289
|
+
type: "response.output_item.added",
|
|
3290
|
+
output_index: fcOutputIndex,
|
|
3291
|
+
item: {
|
|
3292
|
+
type: "function_call",
|
|
3293
|
+
id: entry.fcItemId,
|
|
3294
|
+
call_id: entry.id,
|
|
3295
|
+
name: entry.name,
|
|
3296
|
+
arguments: "",
|
|
3297
|
+
status: "in_progress"
|
|
3298
|
+
}
|
|
3299
|
+
});
|
|
3300
|
+
entry.emittedAdded = true;
|
|
3301
|
+
}
|
|
3302
|
+
if (dc.function?.arguments) {
|
|
3260
3303
|
entry.arguments += dc.function.arguments;
|
|
3304
|
+
if (entry.emittedAdded) {
|
|
3305
|
+
const fcOutputIndex = (emittedMessageItem ? 1 : 0) + dc.index;
|
|
3306
|
+
yield formatSSE("response.function_call_arguments.delta", {
|
|
3307
|
+
type: "response.function_call_arguments.delta",
|
|
3308
|
+
item_id: entry.fcItemId,
|
|
3309
|
+
output_index: fcOutputIndex,
|
|
3310
|
+
delta: dc.function.arguments
|
|
3311
|
+
});
|
|
3312
|
+
}
|
|
3313
|
+
}
|
|
3261
3314
|
}
|
|
3262
3315
|
}
|
|
3263
3316
|
if (choice.finish_reason) {
|
|
@@ -3294,43 +3347,39 @@ async function* translateStream(args2, signal) {
|
|
|
3294
3347
|
const fcItems = [];
|
|
3295
3348
|
let relIdx = 0;
|
|
3296
3349
|
for (const [, tc] of toolCalls) {
|
|
3297
|
-
const fcItemId = `fc_${randomUUID2().replace(/-/g, "")}`;
|
|
3298
3350
|
const outputIndex = baseIndex + relIdx;
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
item: {
|
|
3303
|
-
type: "function_call",
|
|
3304
|
-
id: fcItemId,
|
|
3305
|
-
call_id: tc.id,
|
|
3306
|
-
name: tc.name,
|
|
3307
|
-
arguments: "",
|
|
3308
|
-
status: "in_progress"
|
|
3309
|
-
}
|
|
3310
|
-
});
|
|
3311
|
-
if (tc.arguments) {
|
|
3312
|
-
yield formatSSE("response.function_call_arguments.delta", {
|
|
3313
|
-
type: "response.function_call_arguments.delta",
|
|
3314
|
-
item_id: fcItemId,
|
|
3351
|
+
if (!tc.emittedAdded && tc.id && tc.name) {
|
|
3352
|
+
yield formatSSE("response.output_item.added", {
|
|
3353
|
+
type: "response.output_item.added",
|
|
3315
3354
|
output_index: outputIndex,
|
|
3316
|
-
|
|
3355
|
+
item: {
|
|
3356
|
+
type: "function_call",
|
|
3357
|
+
id: tc.fcItemId,
|
|
3358
|
+
call_id: tc.id,
|
|
3359
|
+
name: tc.name,
|
|
3360
|
+
arguments: "",
|
|
3361
|
+
status: "in_progress"
|
|
3362
|
+
}
|
|
3363
|
+
});
|
|
3364
|
+
tc.emittedAdded = true;
|
|
3365
|
+
}
|
|
3366
|
+
if (tc.emittedAdded) {
|
|
3367
|
+
yield formatSSE("response.output_item.done", {
|
|
3368
|
+
type: "response.output_item.done",
|
|
3369
|
+
output_index: outputIndex,
|
|
3370
|
+
item: {
|
|
3371
|
+
type: "function_call",
|
|
3372
|
+
id: tc.fcItemId,
|
|
3373
|
+
call_id: tc.id,
|
|
3374
|
+
name: tc.name,
|
|
3375
|
+
arguments: tc.arguments,
|
|
3376
|
+
status: "completed"
|
|
3377
|
+
}
|
|
3317
3378
|
});
|
|
3318
3379
|
}
|
|
3319
|
-
yield formatSSE("response.output_item.done", {
|
|
3320
|
-
type: "response.output_item.done",
|
|
3321
|
-
output_index: outputIndex,
|
|
3322
|
-
item: {
|
|
3323
|
-
type: "function_call",
|
|
3324
|
-
id: fcItemId,
|
|
3325
|
-
call_id: tc.id,
|
|
3326
|
-
name: tc.name,
|
|
3327
|
-
arguments: tc.arguments,
|
|
3328
|
-
status: "completed"
|
|
3329
|
-
}
|
|
3330
|
-
});
|
|
3331
3380
|
fcItems.push({
|
|
3332
3381
|
type: "function_call",
|
|
3333
|
-
id: fcItemId,
|
|
3382
|
+
id: tc.fcItemId,
|
|
3334
3383
|
call_id: tc.id,
|
|
3335
3384
|
name: tc.name,
|
|
3336
3385
|
arguments: tc.arguments,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@classicicn/codex-transfer",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Responses API ↔ Chat Completions translation bridge for Codex — use DeepSeek, Kimi, Qwen, and other providers with Codex",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/codex-transfer.mjs",
|