@ottocode/sdk 0.1.235 → 0.1.237
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/package.json +1 -1
- package/src/config/src/manager.ts +55 -0
- package/src/config/src/paths.ts +27 -0
- package/src/core/src/tools/builtin/fs/edit-shared.ts +83 -0
- package/src/core/src/tools/builtin/fs/edit.ts +129 -0
- package/src/core/src/tools/builtin/fs/edit.txt +9 -0
- package/src/core/src/tools/builtin/fs/index.ts +4 -0
- package/src/core/src/tools/builtin/fs/multiedit.ts +137 -0
- package/src/core/src/tools/builtin/fs/multiedit.txt +9 -0
- package/src/core/src/tools/builtin/fs/read-tracker.ts +72 -0
- package/src/core/src/tools/builtin/fs/read.ts +2 -0
- package/src/core/src/tools/builtin/fs/write.ts +2 -0
- package/src/core/src/tools/builtin/fs/write.txt +1 -1
- package/src/core/src/utils/debug.ts +28 -1
- package/src/core/src/utils/logger.ts +116 -27
- package/src/index.ts +9 -1
- package/src/prompts/src/agents/build.txt +9 -2
- package/src/prompts/src/base.txt +10 -7
- package/src/prompts/src/debug.ts +0 -7
- package/src/prompts/src/providers/default.txt +25 -14
- package/src/prompts/src/providers/glm.txt +25 -14
- package/src/prompts/src/providers/google.txt +3 -3
- package/src/prompts/src/providers/moonshot.txt +25 -14
- package/src/prompts/src/providers/openai.txt +1 -1
- package/src/providers/src/catalog.ts +497 -7
- package/src/types/src/config.ts +2 -0
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
import { appendFileSync, mkdirSync } from 'node:fs';
|
|
2
2
|
import { dirname } from 'node:path';
|
|
3
|
-
import { isDebugEnabled, isTraceEnabled } from './debug.ts';
|
|
3
|
+
import { isDebugEnabled, isTraceEnabled, getDebugScopes } from './debug.ts';
|
|
4
|
+
import {
|
|
5
|
+
getGlobalDebugLogPath,
|
|
6
|
+
getSessionDebugDetailsLogPath,
|
|
7
|
+
getSessionDebugLogPath,
|
|
8
|
+
} from '../../../config/src/paths.ts';
|
|
4
9
|
|
|
5
10
|
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
6
11
|
|
|
12
|
+
const ANSI_RESET = '\x1b[0m';
|
|
13
|
+
const ANSI_DIM = '\x1b[2m';
|
|
14
|
+
const ANSI_CYAN = '\x1b[36m';
|
|
15
|
+
const ANSI_BLUE = '\x1b[34m';
|
|
16
|
+
const ANSI_GREEN = '\x1b[32m';
|
|
17
|
+
const ANSI_YELLOW = '\x1b[33m';
|
|
18
|
+
const ANSI_RED = '\x1b[31m';
|
|
19
|
+
|
|
7
20
|
function safeHasMeta(
|
|
8
21
|
meta?: Record<string, unknown>,
|
|
9
22
|
): meta is Record<string, unknown> {
|
|
@@ -11,18 +24,90 @@ function safeHasMeta(
|
|
|
11
24
|
}
|
|
12
25
|
|
|
13
26
|
function getDebugLogFilePath(): string | undefined {
|
|
14
|
-
return undefined;
|
|
27
|
+
if (!isDebugEnabled()) return undefined;
|
|
28
|
+
return getGlobalDebugLogPath();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function getSessionLogFilePath(
|
|
32
|
+
meta?: Record<string, unknown>,
|
|
33
|
+
): string | undefined {
|
|
34
|
+
if (!isDebugEnabled()) return undefined;
|
|
35
|
+
if (meta?.debugDetail === true) return undefined;
|
|
36
|
+
const sessionId = meta?.sessionId;
|
|
37
|
+
if (typeof sessionId !== 'string' || !sessionId.trim()) return undefined;
|
|
38
|
+
return getSessionDebugLogPath(sessionId);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function getSessionDetailsLogFilePath(
|
|
42
|
+
meta?: Record<string, unknown>,
|
|
43
|
+
): string | undefined {
|
|
44
|
+
if (!isDebugEnabled()) return undefined;
|
|
45
|
+
const sessionId = meta?.sessionId;
|
|
46
|
+
if (typeof sessionId !== 'string' || !sessionId.trim()) return undefined;
|
|
47
|
+
return getSessionDebugDetailsLogPath(sessionId);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function shouldWriteDebugLog(message: string): boolean {
|
|
51
|
+
if (!isDebugEnabled()) return false;
|
|
52
|
+
const scopes = getDebugScopes();
|
|
53
|
+
if (!scopes.length) return true;
|
|
54
|
+
const match = message.match(/^\[([^\]]+)\]/);
|
|
55
|
+
if (!match?.[1]) return true;
|
|
56
|
+
return scopes.includes(match[1]);
|
|
15
57
|
}
|
|
16
58
|
|
|
17
59
|
function serializeLogMeta(meta?: Record<string, unknown>): string {
|
|
18
60
|
if (!safeHasMeta(meta)) return '';
|
|
19
61
|
try {
|
|
20
|
-
|
|
62
|
+
const sanitized = { ...meta };
|
|
63
|
+
delete sanitized.debugDetail;
|
|
64
|
+
return Object.keys(sanitized).length ? ` ${JSON.stringify(sanitized)}` : '';
|
|
21
65
|
} catch {
|
|
22
66
|
return ' [unserializable-meta]';
|
|
23
67
|
}
|
|
24
68
|
}
|
|
25
69
|
|
|
70
|
+
function colorizeLine(line: string, level: LogLevel): string {
|
|
71
|
+
const levelColor =
|
|
72
|
+
level === 'debug'
|
|
73
|
+
? ANSI_CYAN
|
|
74
|
+
: level === 'info'
|
|
75
|
+
? ANSI_BLUE
|
|
76
|
+
: level === 'warn'
|
|
77
|
+
? ANSI_YELLOW
|
|
78
|
+
: ANSI_RED;
|
|
79
|
+
const scopeMatch = line.match(
|
|
80
|
+
/\[(debug|info|warn|error|timing)\]\s+\[([^\]]+)\]/i,
|
|
81
|
+
);
|
|
82
|
+
if (!scopeMatch) {
|
|
83
|
+
return `${levelColor}${line}${ANSI_RESET}`;
|
|
84
|
+
}
|
|
85
|
+
const rest = line.slice(24);
|
|
86
|
+
return `${ANSI_DIM}${line.slice(0, 24)}${ANSI_RESET}${rest
|
|
87
|
+
.replace(scopeMatch[1], `${levelColor}${scopeMatch[1]}${ANSI_RESET}`)
|
|
88
|
+
.replace(
|
|
89
|
+
`[${scopeMatch[2]}]`,
|
|
90
|
+
`${ANSI_GREEN}[${scopeMatch[2]}]${ANSI_RESET}`,
|
|
91
|
+
)}`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function printLine(
|
|
95
|
+
level: LogLevel,
|
|
96
|
+
line: string,
|
|
97
|
+
meta?: Record<string, unknown>,
|
|
98
|
+
) {
|
|
99
|
+
const colored = colorizeLine(line, level);
|
|
100
|
+
if (safeHasMeta(meta)) {
|
|
101
|
+
if (level === 'warn') console.warn(colored, meta);
|
|
102
|
+
else if (level === 'error') console.error(colored, meta);
|
|
103
|
+
else console.log(colored, meta);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (level === 'warn') console.warn(colored);
|
|
107
|
+
else if (level === 'error') console.error(colored);
|
|
108
|
+
else console.log(colored);
|
|
109
|
+
}
|
|
110
|
+
|
|
26
111
|
function writeLogLine(line: string, meta?: Record<string, unknown>) {
|
|
27
112
|
const suffix = serializeLogMeta(meta);
|
|
28
113
|
const fullLine = `${new Date().toISOString()} ${line}${suffix}`;
|
|
@@ -37,32 +122,44 @@ function writeLogLine(line: string, meta?: Record<string, unknown>) {
|
|
|
37
122
|
}
|
|
38
123
|
}
|
|
39
124
|
|
|
125
|
+
const sessionLogFile = getSessionLogFilePath(meta);
|
|
126
|
+
if (sessionLogFile) {
|
|
127
|
+
try {
|
|
128
|
+
mkdirSync(dirname(sessionLogFile), { recursive: true });
|
|
129
|
+
appendFileSync(sessionLogFile, `${fullLine}\n`, 'utf-8');
|
|
130
|
+
} catch {
|
|
131
|
+
// ignore file logging errors
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const sessionDetailsLogFile = getSessionDetailsLogFilePath(meta);
|
|
136
|
+
if (sessionDetailsLogFile) {
|
|
137
|
+
try {
|
|
138
|
+
mkdirSync(dirname(sessionDetailsLogFile), { recursive: true });
|
|
139
|
+
appendFileSync(sessionDetailsLogFile, `${fullLine}\n`, 'utf-8');
|
|
140
|
+
} catch {
|
|
141
|
+
// ignore file logging errors
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
40
145
|
return fullLine;
|
|
41
146
|
}
|
|
42
147
|
|
|
43
148
|
export function debug(message: string, meta?: Record<string, unknown>): void {
|
|
44
|
-
if (!
|
|
149
|
+
if (!shouldWriteDebugLog(message)) return;
|
|
45
150
|
try {
|
|
46
151
|
const line = writeLogLine(`[debug] ${message}`, meta);
|
|
47
|
-
|
|
48
|
-
console.log(line, meta);
|
|
49
|
-
} else {
|
|
50
|
-
console.log(line);
|
|
51
|
-
}
|
|
152
|
+
printLine('debug', line, meta);
|
|
52
153
|
} catch {
|
|
53
154
|
// ignore logging errors
|
|
54
155
|
}
|
|
55
156
|
}
|
|
56
157
|
|
|
57
158
|
export function info(message: string, meta?: Record<string, unknown>): void {
|
|
58
|
-
if (!
|
|
159
|
+
if (!shouldWriteDebugLog(message) && !isTraceEnabled()) return;
|
|
59
160
|
try {
|
|
60
161
|
const line = writeLogLine(`[info] ${message}`, meta);
|
|
61
|
-
|
|
62
|
-
console.log(line, meta);
|
|
63
|
-
} else {
|
|
64
|
-
console.log(line);
|
|
65
|
-
}
|
|
162
|
+
printLine('info', line, meta);
|
|
66
163
|
} catch {
|
|
67
164
|
// ignore logging errors
|
|
68
165
|
}
|
|
@@ -71,11 +168,7 @@ export function info(message: string, meta?: Record<string, unknown>): void {
|
|
|
71
168
|
export function warn(message: string, meta?: Record<string, unknown>): void {
|
|
72
169
|
try {
|
|
73
170
|
const line = writeLogLine(`[warn] ${message}`, meta);
|
|
74
|
-
|
|
75
|
-
console.warn(line, meta);
|
|
76
|
-
} else {
|
|
77
|
-
console.warn(line);
|
|
78
|
-
}
|
|
171
|
+
printLine('warn', line, meta);
|
|
79
172
|
} catch {
|
|
80
173
|
// ignore logging errors
|
|
81
174
|
}
|
|
@@ -127,10 +220,10 @@ export function error(
|
|
|
127
220
|
|
|
128
221
|
if (safeHasMeta(logMeta)) {
|
|
129
222
|
const line = writeLogLine(`[error] ${message}`, logMeta);
|
|
130
|
-
|
|
223
|
+
printLine('error', line, logMeta);
|
|
131
224
|
} else {
|
|
132
225
|
const line = writeLogLine(`[error] ${message}`);
|
|
133
|
-
|
|
226
|
+
printLine('error', line);
|
|
134
227
|
}
|
|
135
228
|
} catch (logErr) {
|
|
136
229
|
try {
|
|
@@ -177,11 +270,7 @@ export function time(label: string): Timer {
|
|
|
177
270
|
`[timing] ${label} ${duration.toFixed(1)}ms`,
|
|
178
271
|
meta,
|
|
179
272
|
);
|
|
180
|
-
|
|
181
|
-
console.log(base, meta);
|
|
182
|
-
} else {
|
|
183
|
-
console.log(base);
|
|
184
|
-
}
|
|
273
|
+
printLine('info', base, meta);
|
|
185
274
|
} catch {
|
|
186
275
|
// ignore timing log errors
|
|
187
276
|
}
|
package/src/index.ts
CHANGED
|
@@ -177,6 +177,12 @@ export {
|
|
|
177
177
|
getGlobalAgentsDir,
|
|
178
178
|
getGlobalToolsDir,
|
|
179
179
|
getGlobalCommandsDir,
|
|
180
|
+
getGlobalDebugDir,
|
|
181
|
+
getGlobalDebugLogPath,
|
|
182
|
+
getGlobalDebugSessionsDir,
|
|
183
|
+
getSessionDebugLogPath,
|
|
184
|
+
getSessionDebugDetailsLogPath,
|
|
185
|
+
getSessionSystemPromptPath,
|
|
180
186
|
getSecureAuthPath,
|
|
181
187
|
getSecureBaseDir,
|
|
182
188
|
getSecureOAuthDir,
|
|
@@ -187,12 +193,14 @@ export {
|
|
|
187
193
|
isAuthorized,
|
|
188
194
|
ensureEnv,
|
|
189
195
|
writeDefaults as setConfig,
|
|
196
|
+
readDebugConfig,
|
|
197
|
+
writeDebugConfig,
|
|
190
198
|
writeAuth,
|
|
191
199
|
removeAuth as removeConfig,
|
|
192
200
|
getOnboardingComplete,
|
|
193
201
|
setOnboardingComplete,
|
|
194
202
|
} from './config/src/manager.ts';
|
|
195
|
-
export type { Scope } from './config/src/manager.ts';
|
|
203
|
+
export type { Scope, DebugConfig } from './config/src/manager.ts';
|
|
196
204
|
|
|
197
205
|
// =======================
|
|
198
206
|
// Prompts (from internal prompts module)
|
|
@@ -12,6 +12,13 @@ You help with coding and build tasks.
|
|
|
12
12
|
- Use `terminal(operation: "write", input: "\u0003")` or `terminal(operation: "interrupt")` to stop a process before resorting to `kill`.
|
|
13
13
|
- Summarize active terminals (purpose, key command, port) in your updates so collaborators know what's running.
|
|
14
14
|
|
|
15
|
+
## Preferred Editing Order
|
|
16
|
+
|
|
17
|
+
- Use `edit` for one exact replacement in an existing file.
|
|
18
|
+
- Use `multiedit` for several exact replacements in the same file.
|
|
19
|
+
- Use `apply_patch` for structural or multi-file changes, file add/delete/rename, or edits that are awkward as exact replacements.
|
|
20
|
+
- Use `write` for new files or near-total rewrites.
|
|
21
|
+
|
|
15
22
|
## apply_patch — Mandatory Rules
|
|
16
23
|
|
|
17
24
|
These rules apply EVERY time you use the `apply_patch` tool. Violations cause patch failures.
|
|
@@ -211,7 +218,7 @@ Key points:
|
|
|
211
218
|
- Wastes output tokens and risks hallucinating unchanged parts
|
|
212
219
|
|
|
213
220
|
## Never
|
|
214
|
-
- Use `write` for partial file edits (use `apply_patch`
|
|
221
|
+
- Use `write` for partial file edits (use `edit`/`multiedit` first, or `apply_patch` for structural diffs)
|
|
215
222
|
- Make multiple separate `apply_patch` calls for the same file (use multiple hunks with @@ headers instead)
|
|
216
223
|
- Assume file content remains unchanged between operations
|
|
217
|
-
- Use `bash` with `sed`/`awk` for programmatic file editing (use `apply_patch` instead)
|
|
224
|
+
- Use `bash` with `sed`/`awk` for programmatic file editing (use `edit`, `multiedit`, or `apply_patch` instead)
|
package/src/prompts/src/base.txt
CHANGED
|
@@ -21,10 +21,13 @@ You MUST call the `finish` tool at the end of every response to signal completio
|
|
|
21
21
|
**IMPORTANT**: Do NOT call `finish` before streaming your response. Always stream your message first, then call `finish`. If you forget to call `finish`, the system will hang and not complete properly.
|
|
22
22
|
|
|
23
23
|
File Editing Best Practices:
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
24
|
+
- Prefer `edit` for one exact replacement in an existing file
|
|
25
|
+
- Prefer `multiedit` for several exact replacements in the same file
|
|
26
|
+
- Use `apply_patch` for structural diffs, file add/delete/rename, or changes that are awkward as exact replacements
|
|
27
|
+
- ALWAYS read a file immediately before using `edit`, `multiedit`, or `apply_patch`
|
|
28
|
+
- For `edit` / `multiedit`, copy the exact text including whitespace from the latest `read` output
|
|
29
|
+
- For `apply_patch`, use the `indentation` field from `read` and copy context lines CHARACTER-FOR-CHARACTER
|
|
30
|
+
- When making multiple edits to the same file with `apply_patch`, use multiple `@@` hunks in a single call
|
|
31
|
+
- Never assume file content remains unchanged between separate edit operations
|
|
32
|
+
- If an edit tool fails, read the file AGAIN and copy the exact lines
|
|
33
|
+
- If `apply_patch` fails repeatedly on the same file, prefer `edit` / `multiedit` when possible and fall back to `write` only for a full-file rewrite
|
package/src/prompts/src/debug.ts
CHANGED
|
@@ -3,13 +3,6 @@ export function isDebugEnabled(flag?: string): boolean {
|
|
|
3
3
|
return false;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
function nowMs(): number {
|
|
7
|
-
const perf = (globalThis as { performance?: { now?: () => number } })
|
|
8
|
-
.performance;
|
|
9
|
-
if (perf && typeof perf.now === 'function') return perf.now();
|
|
10
|
-
return Date.now();
|
|
11
|
-
}
|
|
12
|
-
|
|
13
6
|
type Timer = { end(meta?: Record<string, unknown>): void };
|
|
14
7
|
|
|
15
8
|
export function time(label: string): Timer {
|
|
@@ -20,7 +20,9 @@ You have access to a rich set of specialized tools optimized for coding tasks:
|
|
|
20
20
|
**File Reading & Editing**:
|
|
21
21
|
- `read`: Read file contents (supports line ranges)
|
|
22
22
|
- `write`: Write complete file contents
|
|
23
|
-
- `
|
|
23
|
+
- `edit`: Exact text replacement in one file
|
|
24
|
+
- `multiedit`: Multiple exact replacements in one file
|
|
25
|
+
- `apply_patch`: Apply diff/enveloped patches (best for structural or multi-file changes)
|
|
24
26
|
|
|
25
27
|
**Version Control**:
|
|
26
28
|
- `git_status`, `git_diff`
|
|
@@ -34,12 +36,13 @@ You have access to a rich set of specialized tools optimized for coding tasks:
|
|
|
34
36
|
### Tool Usage Best Practices:
|
|
35
37
|
|
|
36
38
|
1. **Batch Independent Operations**: Make all independent tool calls in one turn
|
|
37
|
-
2. **File Editing**: Prefer `
|
|
38
|
-
3. **
|
|
39
|
-
4. **
|
|
40
|
-
5. **
|
|
41
|
-
6. **
|
|
42
|
-
7. **
|
|
39
|
+
2. **File Editing**: Prefer `edit` for one targeted replacement and `multiedit` for several exact replacements in the same file
|
|
40
|
+
3. **Structural Changes**: Use `apply_patch` for multi-file diffs, file add/delete/rename, or edits that are awkward as exact replacements
|
|
41
|
+
4. **Patch Consolidation**: When you do use `apply_patch` multiple times on the same file, use multiple `@@` hunks in ONE `apply_patch` call
|
|
42
|
+
5. **Search First**: Use `glob` to find files before reading them
|
|
43
|
+
6. **Progress Updates**: Call `progress_update` at major milestones (planning, discovering, writing, verifying)
|
|
44
|
+
7. **Plan Tracking**: Use `update_todos` to show task breakdown and progress
|
|
45
|
+
8. **Finish Required**: Always call `finish` tool when complete
|
|
43
46
|
|
|
44
47
|
### Tool Failure Handling
|
|
45
48
|
|
|
@@ -49,10 +52,18 @@ You have access to a rich set of specialized tools optimized for coding tasks:
|
|
|
49
52
|
|
|
50
53
|
## File Editing Best Practices
|
|
51
54
|
|
|
52
|
-
**Using the `
|
|
55
|
+
**Using the `edit` / `multiedit` Tools** (Recommended):
|
|
56
|
+
- Use `edit` for one exact replacement in an existing file
|
|
57
|
+
- Use `multiedit` for several exact replacements in the same file
|
|
58
|
+
- These tools are the default choice for targeted edits because they avoid patch-formatting mistakes
|
|
59
|
+
- Read the file first, then copy the exact text including whitespace
|
|
60
|
+
- If the text appears multiple times, include more surrounding context or use `replaceAll: true`
|
|
61
|
+
- Use `apply_patch` only when the change is structural, spans multiple files, or cannot be expressed as an exact replacement
|
|
62
|
+
|
|
63
|
+
**Using the `apply_patch` Tool** (Structural / Advanced):
|
|
53
64
|
- **CRITICAL**: ALWAYS read the target file immediately before creating a patch - never patch from memory
|
|
54
65
|
- The `read` tool returns an `indentation` field (e.g., "tabs", "2 spaces") — use it to match the file's indent style in your patch
|
|
55
|
-
-
|
|
66
|
+
- Use when the change is structural, multi-file, or awkward as an exact replacement
|
|
56
67
|
- Preferred format is the enveloped patch (`*** Begin Patch` ...); standard unified diffs (`---/+++`) are also accepted and auto-converted if provided
|
|
57
68
|
- Only requires the specific lines you want to change
|
|
58
69
|
- Format: `*** Begin Patch` ... `*** Update File: path` ... `-old` / `+new` ... `*** End Patch`
|
|
@@ -63,8 +74,8 @@ You have access to a rich set of specialized tools optimized for coding tasks:
|
|
|
63
74
|
- If patch fails, it means the file content doesn't match - read it again and retry
|
|
64
75
|
- If you suspect parts of the patch might be stale, set `allowRejects: true` so the tool applies what it can and reports the skipped hunks with reasons
|
|
65
76
|
- The tool quietly skips removal lines that are already gone and additions that already exist, so you don't need to resend the same change
|
|
66
|
-
- **Best for**:
|
|
67
|
-
- **Struggles with**:
|
|
77
|
+
- **Best for**: Structural diffs, file add/delete/rename, or edits that don't fit exact string replacement cleanly
|
|
78
|
+
- **Struggles with**: Small targeted edits where `edit` or `multiedit` would be simpler and less error-prone
|
|
68
79
|
|
|
69
80
|
**Patch Format Reminder**:
|
|
70
81
|
```
|
|
@@ -83,10 +94,10 @@ You have access to a rich set of specialized tools optimized for coding tasks:
|
|
|
83
94
|
- Wastes output tokens and risks hallucinating unchanged parts
|
|
84
95
|
|
|
85
96
|
**Never**:
|
|
86
|
-
- Use `write` for partial file edits (use `apply_patch`
|
|
97
|
+
- Use `write` for partial file edits (use `edit`/`multiedit` first, or `apply_patch` for structural diffs)
|
|
87
98
|
- Make multiple separate `apply_patch` calls for the same file (use multiple hunks with @@ headers instead)
|
|
88
99
|
- Assume file content remains unchanged between operations
|
|
89
|
-
- Use `bash` with `sed`/`awk` for programmatic file editing (use `apply_patch` instead)
|
|
100
|
+
- Use `bash` with `sed`/`awk` for programmatic file editing (use `edit`, `multiedit`, or `apply_patch` instead)
|
|
90
101
|
|
|
91
102
|
## Direct File References
|
|
92
103
|
|
|
@@ -264,7 +275,7 @@ You MUST adhere to the following criteria when solving queries:
|
|
|
264
275
|
- Working on the repo(s) in the current environment is allowed, even if they are proprietary.
|
|
265
276
|
- Analyzing code for vulnerabilities is allowed.
|
|
266
277
|
- Showing user code and tool call details is allowed.
|
|
267
|
-
-
|
|
278
|
+
- Prefer `edit` and `multiedit` for targeted changes in existing files. Use `apply_patch` for structural diffs or file add/delete/rename. When using patches, NEVER try `applypatch` or `apply-patch`, only `apply_patch`.
|
|
268
279
|
|
|
269
280
|
If completing the user's task requires writing or modifying files, your code and final answer should follow these coding guidelines, though user instructions (i.e. AGENTS.md) may override these guidelines:
|
|
270
281
|
|
|
@@ -36,7 +36,9 @@ You have access to a rich set of specialized tools optimized for coding tasks:
|
|
|
36
36
|
**File Reading & Editing**:
|
|
37
37
|
- `read`: Read file contents (supports line ranges)
|
|
38
38
|
- `write`: Write complete file contents
|
|
39
|
-
- `
|
|
39
|
+
- `edit`: Exact text replacement in one file
|
|
40
|
+
- `multiedit`: Multiple exact replacements in one file
|
|
41
|
+
- `apply_patch`: Apply diff/enveloped patches (best for structural or multi-file changes)
|
|
40
42
|
|
|
41
43
|
**Version Control**:
|
|
42
44
|
- `git_status`, `git_diff`
|
|
@@ -50,12 +52,13 @@ You have access to a rich set of specialized tools optimized for coding tasks:
|
|
|
50
52
|
### Tool Usage Best Practices:
|
|
51
53
|
|
|
52
54
|
1. **Batch Independent Operations**: Make all independent tool calls in one turn
|
|
53
|
-
2. **File Editing**: Prefer `
|
|
54
|
-
3. **
|
|
55
|
-
4. **
|
|
56
|
-
5. **
|
|
57
|
-
6. **
|
|
58
|
-
7. **
|
|
55
|
+
2. **File Editing**: Prefer `edit` for one targeted replacement and `multiedit` for several exact replacements in the same file
|
|
56
|
+
3. **Structural Changes**: Use `apply_patch` for multi-file diffs, file add/delete/rename, or edits that are awkward as exact replacements
|
|
57
|
+
4. **Patch Consolidation**: When you do use `apply_patch` multiple times on the same file, use multiple `@@` hunks in ONE `apply_patch` call
|
|
58
|
+
5. **Search First**: Use `glob` to find files before reading them
|
|
59
|
+
6. **Progress Updates**: Call `progress_update` at major milestones (planning, discovering, writing, verifying)
|
|
60
|
+
7. **Plan Tracking**: Use `update_todos` to show task breakdown and progress
|
|
61
|
+
8. **Finish Required**: Always call `finish` tool when complete
|
|
59
62
|
|
|
60
63
|
### Tool Failure Handling
|
|
61
64
|
|
|
@@ -65,10 +68,18 @@ You have access to a rich set of specialized tools optimized for coding tasks:
|
|
|
65
68
|
|
|
66
69
|
## File Editing Best Practices
|
|
67
70
|
|
|
68
|
-
**Using the `
|
|
71
|
+
**Using the `edit` / `multiedit` Tools** (Recommended):
|
|
72
|
+
- Use `edit` for one exact replacement in an existing file
|
|
73
|
+
- Use `multiedit` for several exact replacements in the same file
|
|
74
|
+
- These tools are the default choice for targeted edits because they avoid patch-formatting mistakes
|
|
75
|
+
- Read the file first, then copy the exact text including whitespace
|
|
76
|
+
- If the text appears multiple times, include more surrounding context or use `replaceAll: true`
|
|
77
|
+
- Use `apply_patch` only when the change is structural, spans multiple files, or cannot be expressed as an exact replacement
|
|
78
|
+
|
|
79
|
+
**Using the `apply_patch` Tool** (Structural / Advanced):
|
|
69
80
|
- **CRITICAL**: ALWAYS read the target file immediately before creating a patch - never patch from memory
|
|
70
81
|
- The `read` tool returns an `indentation` field (e.g., "tabs", "2 spaces") — use it to match the file's indent style in your patch
|
|
71
|
-
-
|
|
82
|
+
- Use when the change is structural, multi-file, or awkward as an exact replacement
|
|
72
83
|
- Preferred format is the enveloped patch (`*** Begin Patch` ...); standard unified diffs (`---/+++`) are also accepted and auto-converted if provided
|
|
73
84
|
- Only requires the specific lines you want to change
|
|
74
85
|
- Format: `*** Begin Patch` ... `*** Update File: path` ... `-old` / `+new` ... `*** End Patch`
|
|
@@ -79,8 +90,8 @@ You have access to a rich set of specialized tools optimized for coding tasks:
|
|
|
79
90
|
- If patch fails, it means the file content doesn't match - read it again and retry
|
|
80
91
|
- If you suspect parts of the patch might be stale, set `allowRejects: true` so the tool applies what it can and reports the skipped hunks with reasons
|
|
81
92
|
- The tool quietly skips removal lines that are already gone and additions that already exist, so you don't need to resend the same change
|
|
82
|
-
- **Best for**:
|
|
83
|
-
- **Struggles with**:
|
|
93
|
+
- **Best for**: Structural diffs, file add/delete/rename, or edits that don't fit exact string replacement cleanly
|
|
94
|
+
- **Struggles with**: Small targeted edits where `edit` or `multiedit` would be simpler and less error-prone
|
|
84
95
|
|
|
85
96
|
**Patch Format — Complete Reference**:
|
|
86
97
|
|
|
@@ -172,10 +183,10 @@ You have access to a rich set of specialized tools optimized for coding tasks:
|
|
|
172
183
|
- Wastes output tokens and risks hallucinating unchanged parts
|
|
173
184
|
|
|
174
185
|
**Never**:
|
|
175
|
-
- Use `write` for partial file edits (use `apply_patch`
|
|
186
|
+
- Use `write` for partial file edits (use `edit`/`multiedit` first, or `apply_patch` for structural diffs)
|
|
176
187
|
- Make multiple separate `apply_patch` calls for the same file (use multiple hunks with @@ headers instead)
|
|
177
188
|
- Assume file content remains unchanged between operations
|
|
178
|
-
- Use `bash` with `sed`/`awk` for programmatic file editing (use `apply_patch` instead)
|
|
189
|
+
- Use `bash` with `sed`/`awk` for programmatic file editing (use `edit`, `multiedit`, or `apply_patch` instead)
|
|
179
190
|
|
|
180
191
|
## Direct File References
|
|
181
192
|
|
|
@@ -231,7 +242,7 @@ read package.json
|
|
|
231
242
|
|
|
232
243
|
You are a coding agent. Keep going until the query is completely resolved before yielding back to the user. Only terminate your turn when you are sure that the problem is solved. Autonomously resolve the query using the tools available to you. Do NOT guess or make up an answer.
|
|
233
244
|
|
|
234
|
-
-
|
|
245
|
+
- Prefer `edit` and `multiedit` for targeted changes in existing files. Use `apply_patch` for structural diffs or file add/delete/rename. When using patches, NEVER try `applypatch` or `apply-patch`, only `apply_patch`.
|
|
235
246
|
- Fix the problem at the root cause rather than applying surface-level patches
|
|
236
247
|
- Avoid unneeded complexity in your solution
|
|
237
248
|
- Keep changes consistent with the style of the existing codebase
|
|
@@ -89,13 +89,13 @@ Examples of operations to batch:
|
|
|
89
89
|
When requested to perform tasks like fixing bugs, adding features, refactoring, or explaining code, follow this sequence:
|
|
90
90
|
1. **Understand:** Think about the user's request and the relevant codebase context. Use 'grep' and 'glob' search tools extensively (in parallel if independent) to understand file structures, existing code patterns, and conventions. Use 'read' to understand context and validate any assumptions you may have.
|
|
91
91
|
2. **Plan:** Build a coherent and grounded (based on the understanding in step 1) plan for how you intend to resolve the user's task. Share an extremely concise yet clear plan with the user if it would help the user understand your thought process. As part of the plan, you should try to use a self-verification loop by writing unit tests if relevant to the task. Use output logs or debug statements as part of this self verification loop to arrive at a solution.
|
|
92
|
-
3. **Implement:** Use the available tools (e.g., 'apply_patch', 'write', 'bash' ...) to act on the plan, strictly adhering to the project's established conventions (detailed under 'Core Mandates').
|
|
92
|
+
3. **Implement:** Use the available tools (e.g., 'edit', 'multiedit', 'apply_patch', 'write', 'bash' ...) to act on the plan, strictly adhering to the project's established conventions (detailed under 'Core Mandates').
|
|
93
93
|
4. **Verify (Tests):** If applicable and feasible, verify the changes using the project's testing procedures. Identify the correct test commands and frameworks by examining 'README' files, build/package configuration (e.g., 'package.json'), or existing test execution patterns. NEVER assume standard test commands.
|
|
94
94
|
5. **Verify (Standards):** VERY IMPORTANT: After making code changes, execute the project-specific build, linting and type-checking commands (e.g., 'tsc', 'npm run lint', 'ruff check .') that you have identified for this project (or obtained from the user). This ensures code quality and adherence to standards. If unsure about these commands, you can ask the user if they'd like you to run them and if so how to.
|
|
95
95
|
|
|
96
96
|
## New Applications
|
|
97
97
|
|
|
98
|
-
**Goal:** Autonomously implement and deliver a visually appealing, substantially complete, and functional prototype. Utilize all tools at your disposal to implement the application. Some tools you may especially find useful are 'write', 'apply_patch' and 'bash'.
|
|
98
|
+
**Goal:** Autonomously implement and deliver a visually appealing, substantially complete, and functional prototype. Utilize all tools at your disposal to implement the application. Some tools you may especially find useful are 'edit', 'multiedit', 'write', 'apply_patch' and 'bash'.
|
|
99
99
|
|
|
100
100
|
1. **Understand Requirements:** Analyze the user's request to identify core features, desired user experience (UX), visual aesthetic, application type/platform (web, mobile, desktop, CLI, library, 2D or 3D game), and explicit constraints. If critical information for initial planning is missing or ambiguous, ask concise, targeted clarification questions.
|
|
101
101
|
2. **Propose Plan:** Formulate an internal development plan. Present a clear, concise, high-level summary to the user. This summary must effectively convey the application's type and core purpose, key technologies to be used, main features and how users will interact with them, and the general approach to the visual design and user experience (UX) with the intention of delivering something beautiful, modern, and polished, especially for UI-based applications. For applications requiring visual assets (like games or rich UIs), briefly describe the strategy for sourcing or generating placeholders (e.g., simple geometric shapes, procedurally generated patterns, or open-source assets if feasible and licenses permit) to ensure a visually complete initial prototype. Ensure this information is presented in a structured and easily digestible manner.
|
|
@@ -189,7 +189,7 @@ Here's the plan:
|
|
|
189
189
|
Should I proceed?
|
|
190
190
|
user: Yes
|
|
191
191
|
model:
|
|
192
|
-
[tool_call: write or apply_patch to apply the refactoring to 'src/auth.py']
|
|
192
|
+
[tool_call: edit, multiedit, write, or apply_patch to apply the refactoring to 'src/auth.py']
|
|
193
193
|
Refactoring complete. Running verification...
|
|
194
194
|
[tool_call: bash for 'ruff check src/auth.py && pytest']
|
|
195
195
|
(After verification passes)
|
|
@@ -36,7 +36,9 @@ You have access to a rich set of specialized tools optimized for coding tasks:
|
|
|
36
36
|
**File Reading & Editing**:
|
|
37
37
|
- `read`: Read file contents (supports line ranges)
|
|
38
38
|
- `write`: Write complete file contents
|
|
39
|
-
- `
|
|
39
|
+
- `edit`: Exact text replacement in one file
|
|
40
|
+
- `multiedit`: Multiple exact replacements in one file
|
|
41
|
+
- `apply_patch`: Apply diff/enveloped patches (best for structural or multi-file changes)
|
|
40
42
|
|
|
41
43
|
**Version Control**:
|
|
42
44
|
- `git_status`, `git_diff`
|
|
@@ -50,12 +52,13 @@ You have access to a rich set of specialized tools optimized for coding tasks:
|
|
|
50
52
|
### Tool Usage Best Practices:
|
|
51
53
|
|
|
52
54
|
1. **Batch Independent Operations**: Make all independent tool calls in one turn
|
|
53
|
-
2. **File Editing**: Prefer `
|
|
54
|
-
3. **
|
|
55
|
-
4. **
|
|
56
|
-
5. **
|
|
57
|
-
6. **
|
|
58
|
-
7. **
|
|
55
|
+
2. **File Editing**: Prefer `edit` for one targeted replacement and `multiedit` for several exact replacements in the same file
|
|
56
|
+
3. **Structural Changes**: Use `apply_patch` for multi-file diffs, file add/delete/rename, or edits that are awkward as exact replacements
|
|
57
|
+
4. **Patch Consolidation**: When you do use `apply_patch` multiple times on the same file, use multiple `@@` hunks in ONE `apply_patch` call
|
|
58
|
+
5. **Search First**: Use `glob` to find files before reading them
|
|
59
|
+
6. **Progress Updates**: Call `progress_update` at major milestones (planning, discovering, writing, verifying)
|
|
60
|
+
7. **Plan Tracking**: Use `update_todos` to show task breakdown and progress
|
|
61
|
+
8. **Finish Required**: Always call `finish` tool when complete
|
|
59
62
|
|
|
60
63
|
### Tool Failure Handling
|
|
61
64
|
|
|
@@ -65,10 +68,18 @@ You have access to a rich set of specialized tools optimized for coding tasks:
|
|
|
65
68
|
|
|
66
69
|
## File Editing Best Practices
|
|
67
70
|
|
|
68
|
-
**Using the `
|
|
71
|
+
**Using the `edit` / `multiedit` Tools** (Recommended):
|
|
72
|
+
- Use `edit` for one exact replacement in an existing file
|
|
73
|
+
- Use `multiedit` for several exact replacements in the same file
|
|
74
|
+
- These tools are the default choice for targeted edits because they avoid patch-formatting mistakes
|
|
75
|
+
- Read the file first, then copy the exact text including whitespace
|
|
76
|
+
- If the text appears multiple times, include more surrounding context or use `replaceAll: true`
|
|
77
|
+
- Use `apply_patch` only when the change is structural, spans multiple files, or cannot be expressed as an exact replacement
|
|
78
|
+
|
|
79
|
+
**Using the `apply_patch` Tool** (Structural / Advanced):
|
|
69
80
|
- **CRITICAL**: ALWAYS read the target file immediately before creating a patch - never patch from memory
|
|
70
81
|
- The `read` tool returns an `indentation` field (e.g., "tabs", "2 spaces") — use it to match the file's indent style in your patch
|
|
71
|
-
-
|
|
82
|
+
- Use when the change is structural, multi-file, or awkward as an exact replacement
|
|
72
83
|
- Preferred format is the enveloped patch (`*** Begin Patch` ...); standard unified diffs (`---/+++`) are also accepted and auto-converted if provided
|
|
73
84
|
- Only requires the specific lines you want to change
|
|
74
85
|
- Format: `*** Begin Patch` ... `*** Update File: path` ... `-old` / `+new` ... `*** End Patch`
|
|
@@ -79,8 +90,8 @@ You have access to a rich set of specialized tools optimized for coding tasks:
|
|
|
79
90
|
- If patch fails, it means the file content doesn't match - read it again and retry
|
|
80
91
|
- If you suspect parts of the patch might be stale, set `allowRejects: true` so the tool applies what it can and reports the skipped hunks with reasons
|
|
81
92
|
- The tool quietly skips removal lines that are already gone and additions that already exist, so you don't need to resend the same change
|
|
82
|
-
- **Best for**:
|
|
83
|
-
- **Struggles with**:
|
|
93
|
+
- **Best for**: Structural diffs, file add/delete/rename, or edits that don't fit exact string replacement cleanly
|
|
94
|
+
- **Struggles with**: Small targeted edits where `edit` or `multiedit` would be simpler and less error-prone
|
|
84
95
|
|
|
85
96
|
**Patch Format — Complete Reference**:
|
|
86
97
|
|
|
@@ -172,10 +183,10 @@ You have access to a rich set of specialized tools optimized for coding tasks:
|
|
|
172
183
|
- Wastes output tokens and risks hallucinating unchanged parts
|
|
173
184
|
|
|
174
185
|
**Never**:
|
|
175
|
-
- Use `write` for partial file edits (use `apply_patch`
|
|
186
|
+
- Use `write` for partial file edits (use `edit`/`multiedit` first, or `apply_patch` for structural diffs)
|
|
176
187
|
- Make multiple separate `apply_patch` calls for the same file (use multiple hunks with @@ headers instead)
|
|
177
188
|
- Assume file content remains unchanged between operations
|
|
178
|
-
- Use `bash` with `sed`/`awk` for programmatic file editing (use `apply_patch` instead)
|
|
189
|
+
- Use `bash` with `sed`/`awk` for programmatic file editing (use `edit`, `multiedit`, or `apply_patch` instead)
|
|
179
190
|
|
|
180
191
|
## Direct File References
|
|
181
192
|
|
|
@@ -231,7 +242,7 @@ read package.json
|
|
|
231
242
|
|
|
232
243
|
You are a coding agent. Keep going until the query is completely resolved before yielding back to the user. Only terminate your turn when you are sure that the problem is solved. Autonomously resolve the query using the tools available to you. Do NOT guess or make up an answer.
|
|
233
244
|
|
|
234
|
-
-
|
|
245
|
+
- Prefer `edit` and `multiedit` for targeted changes in existing files. Use `apply_patch` for structural diffs or file add/delete/rename. When using patches, NEVER try `applypatch` or `apply-patch`, only `apply_patch`.
|
|
235
246
|
- Fix the problem at the root cause rather than applying surface-level patches
|
|
236
247
|
- Avoid unneeded complexity in your solution
|
|
237
248
|
- Keep changes consistent with the style of the existing codebase
|
|
@@ -208,7 +208,7 @@ You MUST adhere to the following criteria when solving queries:
|
|
|
208
208
|
- Working on the repo(s) in the current environment is allowed, even if they are proprietary.
|
|
209
209
|
- Analyzing code for vulnerabilities is allowed.
|
|
210
210
|
- Showing user code and tool call details is allowed.
|
|
211
|
-
-
|
|
211
|
+
- Prefer `edit` and `multiedit` for targeted changes in existing files. Use `apply_patch` for structural diffs or file add/delete/rename. When using patches, NEVER try `applypatch` or `apply-patch`, only `apply_patch`.
|
|
212
212
|
|
|
213
213
|
If completing the user's task requires writing or modifying files, your code and final answer should follow these coding guidelines, though user instructions (i.e. AGENTS.md) may override these guidelines:
|
|
214
214
|
|