codeep 1.0.25 → 1.0.26

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.
@@ -205,7 +205,7 @@ async function agentChat(messages, systemPrompt, onChunk, abortSignal, dynamicTi
205
205
  tools: getOpenAITools(),
206
206
  tool_choice: 'auto',
207
207
  temperature: config.get('temperature'),
208
- max_tokens: config.get('maxTokens'),
208
+ max_tokens: Math.max(config.get('maxTokens'), 16384), // Ensure enough tokens for large file generation
209
209
  };
210
210
  }
211
211
  else {
@@ -216,7 +216,7 @@ async function agentChat(messages, systemPrompt, onChunk, abortSignal, dynamicTi
216
216
  messages: messages,
217
217
  tools: getAnthropicTools(),
218
218
  temperature: config.get('temperature'),
219
- max_tokens: config.get('maxTokens'),
219
+ max_tokens: Math.max(config.get('maxTokens'), 16384), // Ensure enough tokens for large file generation
220
220
  };
221
221
  }
222
222
  const response = await fetch(endpoint, {
@@ -210,13 +210,23 @@ export function parseOpenAIToolCalls(toolCalls) {
210
210
  if (!toolName)
211
211
  continue;
212
212
  let parameters = {};
213
+ const rawArgs = tc.function?.arguments || '{}';
213
214
  try {
214
- parameters = JSON.parse(tc.function?.arguments || '{}');
215
+ parameters = JSON.parse(rawArgs);
215
216
  }
216
217
  catch (e) {
217
218
  // JSON parsing failed - likely truncated response
218
- console.error(`[DEBUG] Failed to parse tool arguments for ${toolName}:`, tc.function?.arguments?.substring(0, 100));
219
- continue; // Skip this tool call entirely
219
+ // Try to extract what we can from partial JSON
220
+ console.error(`[DEBUG] Failed to parse tool arguments for ${toolName}, attempting partial extraction...`);
221
+ const partialParams = extractPartialToolParams(toolName, rawArgs);
222
+ if (partialParams) {
223
+ parameters = partialParams;
224
+ console.error(`[DEBUG] Successfully extracted partial params for ${toolName}`);
225
+ }
226
+ else {
227
+ console.error(`[DEBUG] Could not extract params, skipping ${toolName}`);
228
+ continue;
229
+ }
220
230
  }
221
231
  // Validate required parameters for specific tools
222
232
  if (toolName === 'write_file' && (!parameters.path || parameters.content === undefined)) {
@@ -239,6 +249,88 @@ export function parseOpenAIToolCalls(toolCalls) {
239
249
  }
240
250
  return parsed;
241
251
  }
252
+ /**
253
+ * Extract parameters from truncated/partial JSON for tool calls
254
+ * This is a fallback when JSON.parse fails due to API truncation
255
+ */
256
+ function extractPartialToolParams(toolName, rawArgs) {
257
+ try {
258
+ // For write_file, try to extract path and content
259
+ if (toolName === 'write_file') {
260
+ const pathMatch = rawArgs.match(/"path"\s*:\s*"([^"]+)"/);
261
+ const contentMatch = rawArgs.match(/"content"\s*:\s*"([\s\S]*?)(?:"|$)/);
262
+ if (pathMatch && contentMatch) {
263
+ // Unescape the content
264
+ let content = contentMatch[1];
265
+ content = content
266
+ .replace(/\\n/g, '\n')
267
+ .replace(/\\t/g, '\t')
268
+ .replace(/\\r/g, '\r')
269
+ .replace(/\\"/g, '"')
270
+ .replace(/\\\\/g, '\\');
271
+ // If content appears truncated (doesn't end properly), add a comment
272
+ if (!content.endsWith('\n') && !content.endsWith('}') && !content.endsWith(';') && !content.endsWith('>')) {
273
+ content += '\n<!-- Content may be truncated -->\n';
274
+ }
275
+ return { path: pathMatch[1], content };
276
+ }
277
+ }
278
+ // For read_file, just need path
279
+ if (toolName === 'read_file') {
280
+ const pathMatch = rawArgs.match(/"path"\s*:\s*"([^"]+)"/);
281
+ if (pathMatch) {
282
+ return { path: pathMatch[1] };
283
+ }
284
+ }
285
+ // For list_files, just need path
286
+ if (toolName === 'list_files') {
287
+ const pathMatch = rawArgs.match(/"path"\s*:\s*"([^"]+)"/);
288
+ if (pathMatch) {
289
+ return { path: pathMatch[1] };
290
+ }
291
+ }
292
+ // For create_directory, just need path
293
+ if (toolName === 'create_directory') {
294
+ const pathMatch = rawArgs.match(/"path"\s*:\s*"([^"]+)"/);
295
+ if (pathMatch) {
296
+ return { path: pathMatch[1] };
297
+ }
298
+ }
299
+ // For edit_file, need path, old_text, new_text
300
+ if (toolName === 'edit_file') {
301
+ const pathMatch = rawArgs.match(/"path"\s*:\s*"([^"]+)"/);
302
+ const oldTextMatch = rawArgs.match(/"old_text"\s*:\s*"([\s\S]*?)(?:"|$)/);
303
+ const newTextMatch = rawArgs.match(/"new_text"\s*:\s*"([\s\S]*?)(?:"|$)/);
304
+ if (pathMatch && oldTextMatch && newTextMatch) {
305
+ return {
306
+ path: pathMatch[1],
307
+ old_text: oldTextMatch[1].replace(/\\n/g, '\n').replace(/\\"/g, '"'),
308
+ new_text: newTextMatch[1].replace(/\\n/g, '\n').replace(/\\"/g, '"'),
309
+ };
310
+ }
311
+ }
312
+ // For execute_command
313
+ if (toolName === 'execute_command') {
314
+ const commandMatch = rawArgs.match(/"command"\s*:\s*"([^"]+)"/);
315
+ if (commandMatch) {
316
+ const argsMatch = rawArgs.match(/"args"\s*:\s*\[([\s\S]*?)\]/);
317
+ let args = [];
318
+ if (argsMatch) {
319
+ const argStrings = argsMatch[1].match(/"([^"]+)"/g);
320
+ if (argStrings) {
321
+ args = argStrings.map(s => s.replace(/"/g, ''));
322
+ }
323
+ }
324
+ return { command: commandMatch[1], args };
325
+ }
326
+ }
327
+ return null;
328
+ }
329
+ catch (e) {
330
+ console.error(`[DEBUG] Error in extractPartialToolParams:`, e);
331
+ return null;
332
+ }
333
+ }
242
334
  /**
243
335
  * Parse tool calls from Anthropic response
244
336
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeep",
3
- "version": "1.0.25",
3
+ "version": "1.0.26",
4
4
  "description": "AI-powered coding assistant built for the terminal. Multiple LLM providers, project-aware context, and a seamless development workflow.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",