@mmmbuto/zai-codex-bridge 0.4.4 → 0.4.5

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/CHANGELOG.md CHANGED
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.4.5] - 2026-01-16
9
+
10
+ ### Fixed
11
+ - Handle streaming tool_calls without `index` by assigning a stable fallback index
12
+ - Improve tool name logging when tools define top-level `name`
13
+
8
14
  ## [0.4.4] - 2026-01-16
9
15
 
10
16
  ### Fixed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mmmbuto/zai-codex-bridge",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "description": "Local proxy that translates OpenAI Responses API format to Z.AI Chat Completions format for Codex",
5
5
  "main": "src/server.js",
6
6
  "bin": {
package/src/server.js CHANGED
@@ -130,7 +130,7 @@ function summarizeTools(tools, limit = 8) {
130
130
  types[type] = (types[type] || 0) + 1;
131
131
  if (names.length < limit) {
132
132
  if (type === 'function') {
133
- names.push(tool?.function?.name || '(missing_name)');
133
+ names.push(tool?.function?.name || tool?.name || '(missing_name)');
134
134
  } else {
135
135
  names.push(type);
136
136
  }
@@ -530,7 +530,9 @@ async function streamChatToResponses(upstreamBody, res, responsesRequest, ids, a
530
530
 
531
531
  // Tool call tracking (only if allowTools)
532
532
  const toolCallsMap = new Map(); // index -> { callId, name, outputIndex, arguments, partialArgs }
533
+ const toolCallsById = new Map(); // callId -> index
533
534
  const TOOL_BASE_INDEX = 1; // After message item
535
+ let nextToolIndex = 0;
534
536
 
535
537
  while (true) {
536
538
  const { done, value } = await reader.read();
@@ -563,12 +565,22 @@ async function streamChatToResponses(upstreamBody, res, responsesRequest, ids, a
563
565
  // Handle tool_calls (only if allowTools)
564
566
  if (allowTools && delta.tool_calls && Array.isArray(delta.tool_calls)) {
565
567
  for (const tc of delta.tool_calls) {
566
- const index = tc.index;
567
- if (index == null) continue;
568
+ let index = tc.index;
569
+ const tcId = tc.id;
570
+
571
+ if (index == null) {
572
+ if (tcId && toolCallsById.has(tcId)) {
573
+ index = toolCallsById.get(tcId);
574
+ } else {
575
+ index = nextToolIndex++;
576
+ }
577
+ } else if (index >= nextToolIndex) {
578
+ nextToolIndex = index + 1;
579
+ }
568
580
 
569
581
  if (!toolCallsMap.has(index)) {
570
582
  // New tool call - send output_item.added
571
- const callId = tc.id || `call_${randomUUID().replace(/-/g, '')}`;
583
+ const callId = tcId || `call_${randomUUID().replace(/-/g, '')}`;
572
584
  const name = tc.function?.name || '';
573
585
  const outputIndex = TOOL_BASE_INDEX + index;
574
586
 
@@ -579,6 +591,7 @@ async function streamChatToResponses(upstreamBody, res, responsesRequest, ids, a
579
591
  arguments: '',
580
592
  partialArgs: ''
581
593
  });
594
+ if (callId) toolCallsById.set(callId, index);
582
595
 
583
596
  const fnItemInProgress = {
584
597
  id: callId,