coder-agent 2.4.0 → 2.5.1

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.js CHANGED
@@ -244,7 +244,9 @@ async function callGeminiAPIWithRotation(apiKey, params, maxRetries = 3, initial
244
244
  "gemini-2.5-flash",
245
245
  "gemini-2.5-pro",
246
246
  "gemini-3.5-flash",
247
- "gemini-3.1-flash-lite"
247
+ "gemini-3.1-flash-lite",
248
+ "gemma-4-31b-it",
249
+ "gemma-4-26b-a4b-it"
248
250
  ];
249
251
  let currentModel = params.model;
250
252
  let modelIndex = rotationList.indexOf(currentModel);
@@ -529,9 +531,15 @@ export class Agent {
529
531
  else {
530
532
  statusLines.push(`${chalk.hex('#30d158')('✓')} ${chalk.gray(getToolSuccessSummary(name, args, result))}`);
531
533
  }
534
+ // Truncate result if it is extremely large to prevent context/token overflow
535
+ const MAX_TOOL_OUTPUT = 60000;
536
+ let toolResult = result;
537
+ if (toolResult.length > MAX_TOOL_OUTPUT) {
538
+ toolResult = toolResult.slice(0, MAX_TOOL_OUTPUT) + `\n\n... [Tool output truncated: total length was ${toolResult.length} characters] ...`;
539
+ }
532
540
  this.memory.add({
533
541
  role: "tool",
534
- content: result,
542
+ content: toolResult,
535
543
  tool_call_id: toolCall.id,
536
544
  name,
537
545
  });
package/dist/index.js CHANGED
@@ -10,7 +10,9 @@ const VALID_MODELS = [
10
10
  "gemini-3.5-flash",
11
11
  "gemini-3.1-flash-lite",
12
12
  "gemini-2.0-flash",
13
- "gemini-2.0-pro-exp"
13
+ "gemini-2.0-pro-exp",
14
+ "gemma-4-31b-it",
15
+ "gemma-4-26b-a4b-it"
14
16
  ];
15
17
  function printBanner(modelName) {
16
18
  console.clear();
@@ -67,11 +69,13 @@ function printHelp() {
67
69
  console.log(chalk.white(" --set-key <api_key> — Save your Gemini API Key globally"));
68
70
  console.log(chalk.white(" --set-gemini-key <api_key> — Save your Gemini API Key globally (alias)"));
69
71
  console.log("");
70
- console.log(chalk.gray(" Popular Gemini Models:"));
72
+ console.log(chalk.gray(" Popular Gemini & Gemma Models:"));
71
73
  console.log(chalk.white(" gemini-3.5-flash — Newest, highly capable & fast"));
72
74
  console.log(chalk.white(" gemini-2.5-flash — Default, highly capable & fast"));
73
75
  console.log(chalk.white(" gemini-2.5-pro — Reasoning model, excellent coding"));
74
76
  console.log(chalk.white(" gemini-3.1-flash-lite — Light-weight, high volume"));
77
+ console.log(chalk.white(" gemma-4-31b-it — Gemma 4 31B instruction-tuned"));
78
+ console.log(chalk.white(" gemma-4-26b-a4b-it — Gemma 4 26B Mixture-of-Experts"));
75
79
  console.log(chalk.white(" gemini-2.0-flash — (Deprecated) Ultra-fast, lightweight"));
76
80
  console.log(chalk.white(" gemini-2.0-pro-exp — (Deprecated) Experimental reasoning"));
77
81
  console.log("");
package/dist/memory.js CHANGED
@@ -220,10 +220,11 @@ ${topLevelStructure || "(empty)"}
220
220
  `;
221
221
  }
222
222
  function pruneMessages(messages, maxMessages) {
223
- if (messages.length <= maxMessages + 1) {
223
+ if (messages.length <= 1) {
224
224
  return messages;
225
225
  }
226
226
  const systemPrompt = messages[0];
227
+ const systemPromptLen = systemPrompt.content?.length || 0;
227
228
  const history = messages.slice(1);
228
229
  // Group history into turns, where each turn starts with role === "user"
229
230
  const turns = [];
@@ -242,14 +243,22 @@ function pruneMessages(messages, maxMessages) {
242
243
  if (currentTurn.length > 0) {
243
244
  turns.push(currentTurn);
244
245
  }
245
- // Keep turns from the end (most recent) until we hit the maxMessages limit
246
+ // Keep turns from the end (most recent) until we hit the maxMessages limit or character limit
246
247
  const keptTurns = [];
247
248
  let currentCount = 0;
249
+ let currentChars = systemPromptLen;
250
+ const MAX_CHARS = 500000; // ~125k tokens (very safe limit for 256k context models)
248
251
  for (let i = turns.length - 1; i >= 0; i--) {
249
252
  const turn = turns[i];
250
- if (currentCount + turn.length <= maxMessages) {
253
+ const turnChars = turn.reduce((sum, msg) => {
254
+ const contentLen = msg.content?.length || 0;
255
+ const toolCallsLen = msg.tool_calls ? JSON.stringify(msg.tool_calls).length : 0;
256
+ return sum + contentLen + toolCallsLen;
257
+ }, 0);
258
+ if ((currentCount + turn.length <= maxMessages) && (currentChars + turnChars <= MAX_CHARS)) {
251
259
  keptTurns.unshift(turn);
252
260
  currentCount += turn.length;
261
+ currentChars += turnChars;
253
262
  }
254
263
  else {
255
264
  // If we can't fit this turn, but we have kept nothing so far (e.g. a single giant turn),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coder-agent",
3
- "version": "2.4.0",
3
+ "version": "2.5.1",
4
4
  "description": "CLI coding agent powered by Google Gemini",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",