codeep 1.2.88 → 1.2.89

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.
@@ -38,6 +38,7 @@ interface ConfigSchema {
38
38
  agentMaxIterations: number;
39
39
  agentMaxDuration: number;
40
40
  agentApiTimeout: number;
41
+ agentInteractive: boolean;
41
42
  projectPermissions: ProjectPermission[];
42
43
  providerApiKeys: ProviderApiKey[];
43
44
  }
@@ -148,9 +148,10 @@ function createConfig() {
148
148
  agentAutoCommitBranch: false,
149
149
  agentAutoVerify: 'off',
150
150
  agentMaxFixAttempts: 3,
151
- agentMaxIterations: 200,
152
- agentMaxDuration: 20,
153
- agentApiTimeout: 180000,
151
+ agentMaxIterations: 10000,
152
+ agentMaxDuration: 480,
153
+ agentApiTimeout: 600000,
154
+ agentInteractive: true,
154
155
  protocol: 'openai',
155
156
  plan: 'lite',
156
157
  language: 'en',
@@ -159,8 +160,8 @@ function createConfig() {
159
160
  temperature: 0.7,
160
161
  maxTokens: 8192,
161
162
  apiTimeout: 60000,
162
- rateLimitApi: 30,
163
- rateLimitCommands: 100,
163
+ rateLimitApi: 10000,
164
+ rateLimitCommands: 10000,
164
165
  projectPermissions: [],
165
166
  providerApiKeys: [],
166
167
  };
@@ -41,8 +41,8 @@ export const SETTINGS = [
41
41
  getValue: () => config.get('rateLimitApi'),
42
42
  type: 'number',
43
43
  min: 1,
44
- max: 300,
45
- step: 5,
44
+ max: 10000,
45
+ step: 50,
46
46
  },
47
47
  {
48
48
  key: 'rateLimitCommands',
@@ -50,8 +50,8 @@ export const SETTINGS = [
50
50
  getValue: () => config.get('rateLimitCommands'),
51
51
  type: 'number',
52
52
  min: 10,
53
- max: 1000,
54
- step: 10,
53
+ max: 10000,
54
+ step: 100,
55
55
  },
56
56
  {
57
57
  key: 'autoSave',
@@ -91,8 +91,8 @@ export const SETTINGS = [
91
91
  getValue: () => config.get('agentApiTimeout'),
92
92
  type: 'number',
93
93
  min: 30000,
94
- max: 300000,
95
- step: 10000,
94
+ max: 3600000,
95
+ step: 30000,
96
96
  },
97
97
  {
98
98
  key: 'agentMaxDuration',
@@ -100,8 +100,8 @@ export const SETTINGS = [
100
100
  getValue: () => config.get('agentMaxDuration'),
101
101
  type: 'number',
102
102
  min: 5,
103
- max: 60,
104
- step: 5,
103
+ max: 1440,
104
+ step: 30,
105
105
  },
106
106
  {
107
107
  key: 'agentMaxIterations',
@@ -109,8 +109,8 @@ export const SETTINGS = [
109
109
  getValue: () => config.get('agentMaxIterations'),
110
110
  type: 'number',
111
111
  min: 10,
112
- max: 500,
113
- step: 10,
112
+ max: 100000,
113
+ step: 100,
114
114
  },
115
115
  {
116
116
  key: 'agentAutoVerify',
@@ -4,9 +4,9 @@
4
4
  * Private chat/stream logic lives in agentChat.ts and agentStream.ts.
5
5
  */
6
6
  import { ProjectContext } from './project';
7
- import { loadProjectRules, formatChatHistoryForAgent } from './agentChat';
7
+ import { loadProjectRules, loadProgressLog, writeProgressLog, formatChatHistoryForAgent } from './agentChat';
8
8
  import type { AgentChatResponse } from './agentChat';
9
- export { loadProjectRules, formatChatHistoryForAgent };
9
+ export { loadProjectRules, loadProgressLog, writeProgressLog, formatChatHistoryForAgent };
10
10
  export type { AgentChatResponse };
11
11
  import { ToolCall, ToolResult, ActionLog } from './tools';
12
12
  import { undoLastAction, undoAllActions, getCurrentSession, getRecentSessions, formatSession, ActionSession } from './history';
@@ -10,9 +10,9 @@ const debug = (...args) => {
10
10
  }
11
11
  };
12
12
  // Import chat layer (prompt building + API calls)
13
- import { agentChat, getAgentSystemPrompt, getFallbackSystemPrompt, loadProjectRules, formatChatHistoryForAgent, } from './agentChat.js';
13
+ import { agentChat, getAgentSystemPrompt, getFallbackSystemPrompt, loadProjectRules, loadProgressLog, writeProgressLog, formatChatHistoryForAgent, } from './agentChat.js';
14
14
  import { ApiError } from '../api/index.js';
15
- export { loadProjectRules, formatChatHistoryForAgent };
15
+ export { loadProjectRules, loadProgressLog, writeProgressLog, formatChatHistoryForAgent };
16
16
  /**
17
17
  * Calculate dynamic timeout based on task complexity
18
18
  * Complex tasks (creating pages, multiple files) need more time
@@ -28,9 +28,9 @@ function calculateDynamicTimeout(iteration, baseTimeout) {
28
28
  if (iteration > 8) {
29
29
  multiplier = 1.5;
30
30
  }
31
- // Minimum 120 seconds, maximum 5 minutes for a single API call
31
+ // Minimum 120 seconds, no hard upper cap let agentApiTimeout setting be the real ceiling
32
32
  const calculatedTimeout = baseTimeout * multiplier;
33
- return Math.min(Math.max(calculatedTimeout, 120000), 300000);
33
+ return Math.max(calculatedTimeout, 120000);
34
34
  }
35
35
  import { parseToolCalls, executeTool, createActionLog } from './tools.js';
36
36
  import { config } from '../config/index.js';
@@ -157,6 +157,11 @@ export async function runAgent(prompt, projectContext, options = {}) {
157
157
  if (projectRules) {
158
158
  systemPrompt += projectRules;
159
159
  }
160
+ // Inject previous session progress (from .codeep/progress.md)
161
+ const progressLog = loadProgressLog(projectContext.root);
162
+ if (progressLog) {
163
+ systemPrompt += progressLog;
164
+ }
160
165
  if (smartContextStr) {
161
166
  systemPrompt += '\n\n' + smartContextStr;
162
167
  }
@@ -176,13 +181,13 @@ export async function runAgent(prompt, projectContext, options = {}) {
176
181
  let result;
177
182
  let consecutiveTimeouts = 0;
178
183
  let incompleteWorkRetries = 0;
179
- const maxIncompleteWorkRetries = 2;
184
+ const maxIncompleteWorkRetries = 5;
180
185
  // Track tools permanently allowed this session via allow_always
181
186
  const alwaysAllowedTools = new Set();
182
187
  // Tools that require permission when onRequestPermission is set
183
188
  const dangerousTools = new Set(['delete_file', 'execute_command']);
184
189
  const maxTimeoutRetries = 3;
185
- const maxConsecutiveTimeouts = 9; // Allow more consecutive timeouts before giving up
190
+ const maxConsecutiveTimeouts = 30; // Allow more consecutive timeouts before giving up
186
191
  const baseTimeout = config.get('agentApiTimeout');
187
192
  // Infinite loop detection: track last write hash per file path
188
193
  const lastWriteHashByPath = new Map();
@@ -208,6 +213,7 @@ export async function runAgent(prompt, projectContext, options = {}) {
208
213
  finalResponse: partialLines.join('\n'),
209
214
  error: `Exceeded maximum duration of ${durationMin} min`,
210
215
  };
216
+ writeProgressLog(projectContext.root || '', prompt, result);
211
217
  return result;
212
218
  }
213
219
  // Check abort signal
@@ -519,7 +525,7 @@ export async function runAgent(prompt, projectContext, options = {}) {
519
525
  // Add tool results to messages
520
526
  messages.push({
521
527
  role: 'user',
522
- content: `Tool results:\n\n${toolResults.join('\n\n')}\n\nContinue with the task. If this subtask is complete, provide a summary without tool calls.`,
528
+ content: `Tool results:\n\n${toolResults.join('\n\n')}\n\nContinue with the task. Keep working until everything is fully done.`,
523
529
  });
524
530
  }
525
531
  // Check if we hit max iterations — build partial summary from actions log
@@ -538,6 +544,7 @@ export async function runAgent(prompt, projectContext, options = {}) {
538
544
  finalResponse: partialLines.join('\n'),
539
545
  error: `Exceeded maximum of ${opts.maxIterations} iterations`,
540
546
  };
547
+ writeProgressLog(projectContext.root || '', prompt, result);
541
548
  return result;
542
549
  }
543
550
  // Self-verification: Run build/test and fix errors if needed
@@ -669,6 +676,7 @@ export async function runAgent(prompt, projectContext, options = {}) {
669
676
  actions,
670
677
  finalResponse,
671
678
  };
679
+ writeProgressLog(projectContext.root || '', prompt, result);
672
680
  return result;
673
681
  }
674
682
  catch (error) {
@@ -25,6 +25,24 @@ export declare class TimeoutError extends Error {
25
25
  * Load project rules from .codeep/rules.md or CODEEP.md
26
26
  */
27
27
  export declare function loadProjectRules(projectRoot: string): string;
28
+ /**
29
+ * Load agent progress log from .codeep/progress.md
30
+ * Injected into system prompt so agent knows what was previously done.
31
+ */
32
+ export declare function loadProgressLog(projectRoot: string): string;
33
+ /**
34
+ * Write agent progress log to .codeep/progress.md
35
+ * Called after each agent run so the next session has context.
36
+ */
37
+ export declare function writeProgressLog(projectRoot: string, prompt: string, result: {
38
+ success: boolean;
39
+ iterations: number;
40
+ actions: Array<{
41
+ type: string;
42
+ target: string;
43
+ }>;
44
+ finalResponse: string;
45
+ }): void;
28
46
  /**
29
47
  * Format chat session history for inclusion in agent system prompt.
30
48
  * Keeps the most recent messages within a character budget.
@@ -11,7 +11,7 @@
11
11
  * AgentChatResponse — response type (re-export from agentStream)
12
12
  * TimeoutError — distinguishes timeout from user abort
13
13
  */
14
- import { existsSync, readFileSync } from 'fs';
14
+ import { existsSync, readFileSync, writeFileSync } from 'fs';
15
15
  import { join } from 'path';
16
16
  import { config, getApiKey } from '../config/index.js';
17
17
  import { getProviderBaseUrl, getProviderAuthHeader, supportsNativeTools, getEffectiveMaxTokens } from '../config/providers.js';
@@ -57,6 +57,85 @@ export function loadProjectRules(projectRoot) {
57
57
  }
58
58
  return '';
59
59
  }
60
+ /**
61
+ * Load agent progress log from .codeep/progress.md
62
+ * Injected into system prompt so agent knows what was previously done.
63
+ */
64
+ export function loadProgressLog(projectRoot) {
65
+ if (!projectRoot)
66
+ return '';
67
+ const progressFile = join(projectRoot, '.codeep', 'progress.md');
68
+ if (!existsSync(progressFile))
69
+ return '';
70
+ try {
71
+ const content = readFileSync(progressFile, 'utf-8').trim();
72
+ if (content) {
73
+ return `\n\n## Previous Session Progress\nThe agent has previously worked on this project. Read this to understand what was already done and what still needs to be done:\n\n${content}`;
74
+ }
75
+ }
76
+ catch (err) {
77
+ debug('Failed to read progress log from', progressFile, err);
78
+ }
79
+ return '';
80
+ }
81
+ /**
82
+ * Write agent progress log to .codeep/progress.md
83
+ * Called after each agent run so the next session has context.
84
+ */
85
+ export function writeProgressLog(projectRoot, prompt, result) {
86
+ if (!projectRoot)
87
+ return;
88
+ const codeepDir = join(projectRoot, '.codeep');
89
+ if (!existsSync(codeepDir))
90
+ return; // Only write if .codeep already exists (initialized project)
91
+ try {
92
+ const now = new Date().toISOString();
93
+ const fileWrites = result.actions.filter(a => a.type === 'write' || a.type === 'edit');
94
+ const fileDeletes = result.actions.filter(a => a.type === 'delete');
95
+ const commands = result.actions.filter(a => a.type === 'command');
96
+ const lines = [
97
+ `# Agent Progress Log`,
98
+ ``,
99
+ `## Last Session: ${now}`,
100
+ ``,
101
+ `### Task`,
102
+ `${prompt}`,
103
+ ``,
104
+ `### Status`,
105
+ result.success ? `✓ Completed (${result.iterations} iterations)` : `⚠ Incomplete — task may need to be continued`,
106
+ ``,
107
+ ];
108
+ if (fileWrites.length > 0) {
109
+ lines.push(`### Files Written/Edited`);
110
+ [...new Set(fileWrites.map(a => a.target))].forEach(f => lines.push(`- ${f}`));
111
+ lines.push('');
112
+ }
113
+ if (fileDeletes.length > 0) {
114
+ lines.push(`### Files Deleted`);
115
+ [...new Set(fileDeletes.map(a => a.target))].forEach(f => lines.push(`- ${f}`));
116
+ lines.push('');
117
+ }
118
+ if (commands.length > 0) {
119
+ lines.push(`### Commands Run`);
120
+ commands.forEach(a => lines.push(`- ${a.target}`));
121
+ lines.push('');
122
+ }
123
+ if (result.finalResponse) {
124
+ lines.push(`### Summary`);
125
+ lines.push(result.finalResponse.slice(0, 3000));
126
+ lines.push('');
127
+ }
128
+ if (!result.success) {
129
+ lines.push(`### What Still Needs to Be Done`);
130
+ lines.push(`The task was not fully completed in the last session. Run the agent again on the same project to continue from where it left off.`);
131
+ lines.push('');
132
+ }
133
+ writeFileSync(join(codeepDir, 'progress.md'), lines.join('\n'), 'utf-8');
134
+ }
135
+ catch (err) {
136
+ debug('Failed to write progress log:', err);
137
+ }
138
+ }
60
139
  /**
61
140
  * Format chat session history for inclusion in agent system prompt.
62
141
  * Keeps the most recent messages within a character budget.
@@ -76,11 +76,11 @@ class RateLimiter {
76
76
  }
77
77
  // Default rate limiters - configs are loaded from user settings
78
78
  let apiRateLimiter = new RateLimiter({
79
- maxRequests: config.get('rateLimitApi') || 30,
79
+ maxRequests: config.get('rateLimitApi') || 1000000,
80
80
  windowMs: 60 * 1000, // per minute
81
81
  });
82
82
  let commandRateLimiter = new RateLimiter({
83
- maxRequests: config.get('rateLimitCommands') || 100,
83
+ maxRequests: config.get('rateLimitCommands') || 10000,
84
84
  windowMs: 60 * 1000, // per minute
85
85
  });
86
86
  /**
@@ -88,11 +88,11 @@ let commandRateLimiter = new RateLimiter({
88
88
  */
89
89
  export function updateRateLimits() {
90
90
  apiRateLimiter = new RateLimiter({
91
- maxRequests: config.get('rateLimitApi') || 30,
91
+ maxRequests: config.get('rateLimitApi') || 1000000,
92
92
  windowMs: 60 * 1000,
93
93
  });
94
94
  commandRateLimiter = new RateLimiter({
95
- maxRequests: config.get('rateLimitCommands') || 100,
95
+ maxRequests: config.get('rateLimitCommands') || 10000,
96
96
  windowMs: 60 * 1000,
97
97
  });
98
98
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeep",
3
- "version": "1.2.88",
3
+ "version": "1.2.89",
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",