codebot-ai 1.2.1 → 1.2.2

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/agent.d.ts CHANGED
@@ -28,6 +28,10 @@ export declare class Agent {
28
28
  after: number;
29
29
  };
30
30
  getMessages(): Message[];
31
+ /** Ensure every assistant message with tool_calls has matching tool response messages.
32
+ * OpenAI returns 400 if any tool_call_id lacks a response. This can happen if
33
+ * a previous LLM call errored out mid-flow. */
34
+ private repairToolCallMessages;
31
35
  private buildSystemPrompt;
32
36
  }
33
37
  //# sourceMappingURL=agent.d.ts.map
package/dist/agent.js CHANGED
@@ -93,6 +93,9 @@ class Agent {
93
93
  yield { type: 'compaction', text: result.summary || 'Context compacted to fit budget.' };
94
94
  }
95
95
  for (let i = 0; i < this.maxIterations; i++) {
96
+ // Validate message integrity: ensure every tool_call has a matching tool response
97
+ // This prevents cascading 400 errors from OpenAI when a previous call failed
98
+ this.repairToolCallMessages();
96
99
  const supportsTools = (0, registry_1.getModelInfo)(this.model).supportsToolCalling;
97
100
  const toolSchemas = supportsTools ? this.tools.getSchemas() : undefined;
98
101
  let fullText = '';
@@ -211,6 +214,39 @@ class Agent {
211
214
  getMessages() {
212
215
  return [...this.messages];
213
216
  }
217
+ /** Ensure every assistant message with tool_calls has matching tool response messages.
218
+ * OpenAI returns 400 if any tool_call_id lacks a response. This can happen if
219
+ * a previous LLM call errored out mid-flow. */
220
+ repairToolCallMessages() {
221
+ const toolResponseIds = new Set();
222
+ for (const msg of this.messages) {
223
+ if (msg.role === 'tool' && msg.tool_call_id) {
224
+ toolResponseIds.add(msg.tool_call_id);
225
+ }
226
+ }
227
+ for (let i = 0; i < this.messages.length; i++) {
228
+ const msg = this.messages[i];
229
+ if (msg.role === 'assistant' && msg.tool_calls?.length) {
230
+ for (const tc of msg.tool_calls) {
231
+ if (!toolResponseIds.has(tc.id)) {
232
+ // Missing tool response — inject one right after the assistant message
233
+ const repairMsg = {
234
+ role: 'tool',
235
+ content: 'Error: tool call was not executed (interrupted).',
236
+ tool_call_id: tc.id,
237
+ };
238
+ // Find the right position: after the assistant message and any existing tool responses
239
+ let insertAt = i + 1;
240
+ while (insertAt < this.messages.length && this.messages[insertAt].role === 'tool') {
241
+ insertAt++;
242
+ }
243
+ this.messages.splice(insertAt, 0, repairMsg);
244
+ toolResponseIds.add(tc.id);
245
+ }
246
+ }
247
+ }
248
+ }
249
+ }
214
250
  buildSystemPrompt(supportsTools) {
215
251
  let repoMap = '';
216
252
  try {
package/dist/cli.js CHANGED
@@ -44,7 +44,7 @@ const setup_1 = require("./setup");
44
44
  const banner_1 = require("./banner");
45
45
  const tools_1 = require("./tools");
46
46
  const scheduler_1 = require("./scheduler");
47
- const VERSION = '1.2.0';
47
+ const VERSION = '1.2.2';
48
48
  // Session-wide token tracking
49
49
  let sessionTokens = { input: 0, output: 0, total: 0 };
50
50
  const C = {
@@ -221,8 +221,13 @@ class OpenAIProvider {
221
221
  }
222
222
  formatMessage(msg) {
223
223
  const formatted = { role: msg.role, content: msg.content };
224
- if (msg.tool_calls)
224
+ if (msg.tool_calls) {
225
225
  formatted.tool_calls = msg.tool_calls;
226
+ // OpenAI (especially GPT-4.1) requires content: null when tool_calls are present
227
+ // and there's no actual text content. Empty string "" causes 400 errors.
228
+ if (!msg.content)
229
+ formatted.content = null;
230
+ }
226
231
  if (msg.tool_call_id)
227
232
  formatted.tool_call_id = msg.tool_call_id;
228
233
  if (msg.name)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codebot-ai",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "Local-first AI coding assistant. Zero dependencies. Works with Ollama, LM Studio, vLLM, Claude, GPT, Gemini, and more.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",