@amical/aiagent-sdk 0.1.0 → 0.1.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.
Files changed (42) hide show
  1. package/dist/index.d.mts +476 -0
  2. package/dist/index.d.ts +476 -0
  3. package/dist/index.js +968 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/index.mjs +951 -0
  6. package/dist/index.mjs.map +1 -0
  7. package/package.json +7 -1
  8. package/.agents/skills/Viral_Writer/SKILL.md +0 -239
  9. package/.cline_memory.json +0 -58
  10. package/.node-version +0 -1
  11. package/Agents.md +0 -95
  12. package/src/agent/Agent.ts +0 -566
  13. package/src/agent/index.ts +0 -1
  14. package/src/index.ts +0 -15
  15. package/src/llm/NodeApiHandler.ts +0 -117
  16. package/src/llm/WebApiHandler.ts +0 -118
  17. package/src/llm/index.ts +0 -47
  18. package/src/mcp/NodeMcpManager.ts +0 -158
  19. package/src/mcp/WebMcpManager.ts +0 -30
  20. package/src/mcp/index.ts +0 -56
  21. package/src/memory/NodeMemoryManager.ts +0 -82
  22. package/src/memory/WebMemoryManager.ts +0 -89
  23. package/src/memory/index.ts +0 -36
  24. package/src/parser/diff.ts +0 -855
  25. package/src/parser/index.ts +0 -111
  26. package/src/parser/parse-assistant-message.ts +0 -240
  27. package/src/prompt/NodePromptManager.ts +0 -276
  28. package/src/prompt/WebPromptManager.ts +0 -277
  29. package/src/prompt/index.ts +0 -28
  30. package/src/runtime/nodeRuntime.ts +0 -112
  31. package/src/runtime/web.test.ts +0 -95
  32. package/src/runtime/webRuntime.ts +0 -119
  33. package/src/runtime.ts +0 -46
  34. package/src/shared/tools.ts +0 -270
  35. package/test-node-agent.ts +0 -113
  36. package/test-runtime.mjs +0 -36
  37. package/test.md +0 -33
  38. package/tsconfig.json +0 -28
  39. package/tsup.config.ts +0 -21
  40. package/uapi.ts +0 -3
  41. package/webFetch.ts +0 -49
  42. package/webSearch.ts +0 -19
@@ -1,111 +0,0 @@
1
- import { AgentDefaultTool } from "../shared/tools"
2
-
3
- export type AssistantMessageContent = TextStreamContent | ToolUse | ReasoningStreamContent
4
-
5
- export { parseAssistantMessageV2 } from "./parse-assistant-message"
6
-
7
- export interface TextStreamContent {
8
- type: "text"
9
- content: string
10
- partial: boolean
11
- }
12
-
13
- export const toolParamNames = [
14
- "command",
15
- "requires_approval",
16
- "path",
17
- "absolutePath",
18
- "content",
19
- "diff",
20
- "regex",
21
- "file_pattern",
22
- "recursive",
23
- "action",
24
- "url",
25
- "coordinate",
26
- "text",
27
- "query",
28
- "allowed_domains",
29
- "blocked_domains",
30
- "prompt",
31
- "server_name",
32
- "tool_name",
33
- "arguments",
34
- "uri",
35
- "question",
36
- "options",
37
- "response",
38
- "result",
39
- "context",
40
- "title",
41
- "what_happened",
42
- "steps_to_reproduce",
43
- "api_request_output",
44
- "additional_context",
45
- "needs_more_exploration",
46
- "task_progress",
47
- "timeout",
48
- "input",
49
- "from_ref",
50
- "to_ref",
51
- "skill_name",
52
- "prompt_1",
53
- "prompt_2",
54
- "prompt_3",
55
- "prompt_4",
56
- "prompt_5",
57
- "start_line",
58
- "end_line",
59
- ] as const
60
-
61
- export type ToolParamName = (typeof toolParamNames)[number]
62
-
63
- export interface ToolUse {
64
- type: "tool_use"
65
- name: AgentDefaultTool | string // id of the tool being used
66
- // params is a partial record, allowing only some or none of the possible parameters to be used
67
- params: Partial<Record<ToolParamName, string>>
68
- partial: boolean
69
- /**
70
- * Whether this tool use was initiated by a native tool call
71
- */
72
- isNativeToolCall?: boolean
73
- /**
74
- * The call / response ID this tool use is associated with.
75
- */
76
- call_id?: string // optional call ID for tracking tool use calls
77
- /**
78
- * Thought signature associated with this tool use, used by Gemini
79
- */
80
- signature?: string
81
- }
82
-
83
- export interface ReasoningStreamContent {
84
- type: "reasoning"
85
- /**
86
- * The reasoning text generated by the model.
87
- * Redacted reasoning block will have this field set to "[REDACTED]" or an empty string.
88
- */
89
- reasoning: string
90
- /**
91
- * openrouter has various properties that we can pass back unmodified in api requests to preserve reasoning traces
92
- */
93
- details?: any
94
- /**
95
- * It's used when sending the thinking block back to the API.
96
- * API expects this in completed form, not as array of deltas.
97
- */
98
- signature?: string
99
- /**
100
- * whether this reasoning block has been redacted
101
- */
102
- redacted?: boolean
103
- /**
104
- * redacted data
105
- */
106
- data?: string
107
- /**
108
- * Indicates whether this is a partial reasoning block
109
- */
110
- partial: boolean
111
- }
@@ -1,240 +0,0 @@
1
- import { AgentDefaultTool, getToolUseNames } from "../shared/tools"
2
- import { nanoid } from "nanoid"
3
- import { AssistantMessageContent, TextStreamContent, ToolParamName, ToolUse } from "./index" // Assuming types are defined in index.ts or a similar file
4
-
5
- // parseAssistantmessageV1 removed in https://github.com/cline/cline/pull/5425
6
-
7
- /**
8
- * @description **Version 2**
9
- * Parses an assistant message string potentially containing mixed text and tool usage blocks
10
- * marked with XML-like tags into an array of structured content objects.
11
- *
12
- * This version aims for efficiency by avoiding the character-by-character accumulator of V1.
13
- * It iterates through the string using an index `i`. At each position, it checks if the substring
14
- * *ending* at `i` matches any known opening or closing tags for tools or parameters using `startsWith`
15
- * with an offset.
16
- * It uses pre-computed Maps (`toolUseOpenTags`, `toolParamOpenTags`) for quick tag lookups.
17
- * State is managed using indices (`currentTextContentStart`, `currentToolUseStart`, `currentParamValueStart`)
18
- * pointing to the start of the current block within the original `assistantMessage` string.
19
- * Slicing is used to extract content only when a block (text, parameter, or tool use) is completed.
20
- * Special handling for `write_to_file` and `new_rule` content parameters is included, using `indexOf`
21
- * and `lastIndexOf` on the relevant slice to handle potentially nested closing tags.
22
- * If the input string ends mid-block, the last open block is added and marked as partial.
23
- *
24
- * @param assistantMessage The raw string output from the assistant.
25
- * @returns An array of `AssistantMessageContent` objects, which can be `TextContent` or `ToolUse`.
26
- * Blocks that were not fully closed by the end of the input string will have their `partial` flag set to `true`.
27
- */
28
- export function parseAssistantMessageV2(assistantMessage: string, toolParamNames: any): AssistantMessageContent[] {
29
- const contentBlocks: AssistantMessageContent[] = []
30
- let currentTextContentStart = 0 // Index where the current text block started
31
- let currentTextContent: TextStreamContent | undefined
32
- let currentToolUseStart = 0 // Index *after* the opening tag of the current tool use
33
- let currentToolUse: ToolUse | undefined
34
- let currentParamValueStart = 0 // Index *after* the opening tag of the current param
35
- let currentParamName: ToolParamName | undefined
36
-
37
- // Precompute tags for faster lookups
38
- const toolUseOpenTags = new Map<string, string>()
39
- const toolParamOpenTags = new Map<string, ToolParamName>()
40
- for (const name of getToolUseNames()) {
41
- toolUseOpenTags.set(`<${name}>`, name)
42
- }
43
- for (const name of toolParamNames) {
44
- toolParamOpenTags.set(`<${name}>`, name)
45
- }
46
-
47
- const len = assistantMessage.length
48
- for (let i = 0; i < len; i++) {
49
- const currentCharIndex = i
50
-
51
- // --- State: Parsing a Tool Parameter ---
52
- if (currentToolUse && currentParamName) {
53
- const closeTag = `</${currentParamName}>`
54
- // Check if the string *ending* at index `i` matches the closing tag
55
- if (
56
- currentCharIndex >= closeTag.length - 1 &&
57
- assistantMessage.startsWith(
58
- closeTag,
59
- currentCharIndex - closeTag.length + 1, // Start checking from potential start of tag
60
- )
61
- ) {
62
- // Found the closing tag for the parameter
63
- const value = assistantMessage
64
- .slice(
65
- currentParamValueStart, // Start after the opening tag
66
- currentCharIndex - closeTag.length + 1, // End before the closing tag
67
- )
68
- .trim()
69
- currentToolUse.params[currentParamName] = value
70
- currentParamName = undefined // Go back to parsing tool content
71
- // We don't continue loop here, need to check for tool close or other params at index i
72
- } else {
73
- continue // Still inside param value, move to next char
74
- }
75
- }
76
-
77
- // --- State: Parsing a Tool Use (but not a specific parameter) ---
78
- if (currentToolUse && !currentParamName) {
79
- // Ensure we are not inside a parameter already
80
- // Check if starting a new parameter
81
- let startedNewParam = false
82
- for (const [tag, paramName] of toolParamOpenTags.entries()) {
83
- if (currentCharIndex >= tag.length - 1 && assistantMessage.startsWith(tag, currentCharIndex - tag.length + 1)) {
84
- currentParamName = paramName
85
- currentParamValueStart = currentCharIndex + 1 // Value starts after the tag
86
- startedNewParam = true
87
- break
88
- }
89
- }
90
- if (startedNewParam) {
91
- continue // Handled start of param, move to next char
92
- }
93
-
94
- // Check if closing the current tool use
95
- const toolCloseTag = `</${currentToolUse.name}>`
96
- if (
97
- currentCharIndex >= toolCloseTag.length - 1 &&
98
- assistantMessage.startsWith(toolCloseTag, currentCharIndex - toolCloseTag.length + 1)
99
- ) {
100
- // End of the tool use found
101
- // Special handling for content params *before* finalizing the tool
102
- const toolContentSlice = assistantMessage.slice(
103
- currentToolUseStart, // From after the tool opening tag
104
- currentCharIndex - toolCloseTag.length + 1, // To before the tool closing tag
105
- )
106
-
107
- // Check if content parameter needs special handling (write_to_file/new_rule)
108
- // This check is important if the closing </content> tag was missed by the parameter parsing logic
109
- // (e.g., if content is empty or parsing logic prioritizes tool close)
110
- const contentParamName: ToolParamName = "content"
111
- if (
112
- currentToolUse.name === AgentDefaultTool.FILE_NEW /* || currentToolUse.name === "new_rule" */ &&
113
- toolContentSlice.includes(`<${contentParamName}>`)
114
- ) {
115
- const contentStartTag = `<${contentParamName}>`
116
- const contentEndTag = `</${contentParamName}>`
117
- const contentStart = toolContentSlice.indexOf(contentStartTag)
118
- // Use lastIndexOf for robustness against nested tags
119
- const contentEnd = toolContentSlice.lastIndexOf(contentEndTag)
120
-
121
- if (contentStart !== -1 && contentEnd !== -1 && contentEnd > contentStart) {
122
- const contentValue = toolContentSlice.slice(contentStart + contentStartTag.length, contentEnd).trim()
123
- currentToolUse.params[contentParamName] = contentValue
124
- }
125
- }
126
-
127
- currentToolUse.partial = false // Mark as complete
128
- contentBlocks.push(currentToolUse)
129
- currentToolUse = undefined // Reset state
130
- currentTextContentStart = currentCharIndex + 1 // Potential text starts after this tag
131
- continue // Move to next char
132
- }
133
- // If not starting a param and not closing the tool, continue accumulating tool content implicitly
134
- continue
135
- }
136
-
137
- // --- State: Parsing Text / Looking for Tool Start ---
138
- if (!currentToolUse) {
139
- // Check if starting a new tool use
140
- let startedNewTool = false
141
- for (const [tag, toolName] of toolUseOpenTags.entries()) {
142
- if (currentCharIndex >= tag.length - 1 && assistantMessage.startsWith(tag, currentCharIndex - tag.length + 1)) {
143
- // End current text block if one was active
144
- if (currentTextContent) {
145
- currentTextContent.content = assistantMessage
146
- .slice(
147
- currentTextContentStart, // From where text started
148
- currentCharIndex - tag.length + 1, // To before the tool tag starts
149
- )
150
- .trim()
151
- currentTextContent.partial = false // Ended because tool started
152
- if (currentTextContent.content.length > 0) {
153
- contentBlocks.push(currentTextContent)
154
- }
155
- currentTextContent = undefined
156
- } else {
157
- // Check for any text between the last block and this tag
158
- const potentialText = assistantMessage
159
- .slice(
160
- currentTextContentStart, // From where text *might* have started
161
- currentCharIndex - tag.length + 1, // To before the tool tag starts
162
- )
163
- .trim()
164
- if (potentialText.length > 0) {
165
- contentBlocks.push({
166
- type: "text",
167
- content: potentialText,
168
- partial: false,
169
- })
170
- }
171
- }
172
-
173
- // Start the new tool use
174
- currentToolUse = {
175
- type: "tool_use",
176
- name: toolName as ToolParamName,
177
- params: {},
178
- partial: true, // Assume partial until closing tag is found
179
- call_id: nanoid(8),
180
- isNativeToolCall: false,
181
- }
182
- currentToolUseStart = currentCharIndex + 1 // Tool content starts after the opening tag
183
- startedNewTool = true
184
- break
185
- }
186
- }
187
-
188
- if (startedNewTool) {
189
- continue // Handled start of tool, move to next char
190
- }
191
-
192
- // If not starting a tool, it must be text content
193
- if (!currentTextContent) {
194
- // Start a new text block if we aren't already in one
195
- currentTextContentStart = currentCharIndex // Text starts at the current character
196
- // Check if the current char is the start of potential text *immediately* after a tag
197
- // This needs the previous state - simpler to let slicing handle it later.
198
- // Resetting start index accurately is key.
199
- // It should be the index *after* the last processed tag.
200
- // The logic managing currentTextContentStart after closing tags handles this.
201
-
202
- currentTextContent = {
203
- type: "text",
204
- content: "", // Will be determined by slicing at the end or when a tool starts
205
- partial: true,
206
- }
207
- }
208
- // Continue accumulating text implicitly; content is extracted later.
209
- }
210
- } // End of loop
211
-
212
- // --- Finalization after loop ---
213
-
214
- // Finalize any open parameter within an open tool use
215
- if (currentToolUse && currentParamName) {
216
- currentToolUse.params[currentParamName] = assistantMessage
217
- .slice(currentParamValueStart) // From param start to end of string
218
- .trim()
219
- // Tool use remains partial
220
- }
221
-
222
- // Finalize any open tool use (which might contain the finalized partial param)
223
- if (currentToolUse) {
224
- // Tool use is partial because the loop finished before its closing tag
225
- contentBlocks.push(currentToolUse)
226
- }
227
- // Finalize any trailing text content
228
- // Only possible if a tool use wasn't open at the very end
229
- else if (currentTextContent) {
230
- currentTextContent.content = assistantMessage
231
- .slice(currentTextContentStart) // From text start to end of string
232
- .trim()
233
- // Text is partial because the loop finished
234
- if (currentTextContent.content.length > 0) {
235
- contentBlocks.push(currentTextContent)
236
- }
237
- }
238
-
239
- return contentBlocks
240
- }
@@ -1,276 +0,0 @@
1
- import { IPromptManager } from "./index";
2
- import { defaultTools } from "@/shared/tools";
3
-
4
- export class NodePromptManager implements IPromptManager {
5
-
6
- async getSystemPrompt(context: { cwd: string; os: string; shell: string; skills: any; customInstructions?: string; allowDefaultTools?: string[]; customTools?: any[]; }): Promise<string> {
7
- let prompt = `# Role
8
- you are a highly skilled software engineer AI running in a Node.js/Desktop environment.
9
- You have FULL access to the local file system and can execute arbitrary shell commands on the user's machine.
10
-
11
- # Capabilities & Rules
12
- 1. **File System**: You can read, write, create, and delete files/directories anywhere accessible to the user process. Always use absolute paths or paths relative to the Current Working Directory.
13
- 2. **Terminal**: You can execute system commands (e.g., git, npm, python, file manipulation) directly.
14
- 3. **Context**: You are running on a real machine, meaning you have access to real environment variables, local servers (localhost), and local network.
15
- 4. **Destructive Actions**: Be extremely careful when executing commands that modify system state or delete files. Double-check paths and commands before execution.
16
- 5. **Step-by-step**: Use tools one at a time. Do not assume the outcome of any tool use. Each step must be informed by the previous step's result.
17
- 6. **Verification**: Always verify the result of your actions (e.g., run tests, compile code, list directories) before proceeding to the next step or completing the task.
18
- 7. **Communication**: Be concise and technical. Formulate your output strictly according to the tools' XML specification.
19
-
20
- TOOL USE
21
-
22
- You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use.
23
-
24
- # Tool Use Formatting
25
-
26
- Tool use is formatted using XML-style tags. The tool name is enclosed in opening and closing tags, and each parameter is similarly enclosed within its own set of tags. Here's the structure:
27
-
28
- <tool_name>
29
- <parameter1_name>value1</parameter1_name>
30
- <parameter2_name>value2</parameter2_name>
31
- ...
32
- </tool_name>
33
-
34
- For example:
35
-
36
- <agent_read_file>
37
- <path>src/main.js</path>
38
- <task_progress>
39
- Checklist here (optional)
40
- </task_progress>
41
- </agent_read_file>
42
-
43
- Always adhere to this format for the tool use to ensure proper parsing and execution.
44
- `;
45
-
46
- const skillsPrompt = await this.getSkillsPrompt(context.skills);
47
- if (skillsPrompt) {
48
- prompt += `\n${skillsPrompt}\n`;
49
- }
50
-
51
- prompt += `\n${this.getToolInstructions(context)}\n`;
52
-
53
- const envPrompt = this.getEnvironmentInfoPrompt(context);
54
- if (envPrompt) {
55
- prompt += `\n${envPrompt}\n`;
56
- }
57
-
58
- if (context.customInstructions) {
59
- prompt += `\n# User Custom Instructions\n${context.customInstructions}\n`;
60
- }
61
-
62
- return prompt;
63
- }
64
-
65
- getEnvironmentInfoPrompt(context: { cwd: string; os: string; shell: string }): string {
66
- let environmentPrompt = `<environment_details>
67
- # Environment Info
68
- - **Current Working Directory**: \`${context.cwd}\`
69
- - **Operating System**: \`${context.os}\`\n`;
70
- if (context.shell) {
71
- environmentPrompt += `- **Current Shell**: \`${context.shell}\`\n`;
72
- }
73
- return environmentPrompt + `\n</environment_details>`;
74
- }
75
-
76
- async getSkillsPrompt(skills: any[]): Promise<string> {
77
- if (!skills || skills.length === 0) return "";
78
-
79
- try {
80
- let prompt = `# Available Skills\n`;
81
- prompt += `You have access to the following skills. You can use the \`agent_load_skill\` tool to load any of them when needed.\n`;
82
- for (const skill of skills) {
83
- if (skill && skill.name && skill.description) {
84
- prompt += `- **${skill.name}**: ${skill.description}\n`;
85
- }
86
- }
87
- return prompt;
88
- } catch (e) {
89
- // Directory might not exist or not accessible
90
- return "";
91
- }
92
- }
93
-
94
- getToolInstructions(context: { cwd: string; os: string; allowDefaultTools?: string[]; customTools?: any[] }): string {
95
- const allowDefaultTools = context.allowDefaultTools;
96
- const customTools = context.customTools || [];
97
- // 可用
98
- let useDefaultTools = [...defaultTools] as any[];
99
- if (allowDefaultTools) {
100
- useDefaultTools = defaultTools.filter((tool: any) => allowDefaultTools.includes(tool.name));
101
- }
102
- return `# Available Tools
103
- You can use the following tools by formatting your output as XML blocks. Only use ONE tool per message, and ALWAYS wait for the user's response with the execution result before proceeding.
104
-
105
- ${[...useDefaultTools, ...customTools].map((tool: any) => {
106
- return `### ${tool.name}
107
- Description: ${tool.description}
108
- Parameters:
109
- ${Object.entries(tool.params as Record<string, string>).map(([name, description]) => `- ${name}: ${description.replaceAll('${context.cwd}', context.cwd)}`).join('\n')}
110
- - task_progress: (optional) A checklist showing task progress after this tool use is completed. The task_progress parameter must be included as a separate parameter inside of the parent tool call, it must be separate from other parameters such as content, arguments, etc. (See 'UPDATING TASK PROGRESS' section for more details)
111
- Usage:
112
- <${tool.name}>
113
- ${Object.entries(tool.params as Record<string, string>).map(([name, description]) => `<${name}>${description.replaceAll('${context.cwd}', context.cwd)}</${name}>`).join('\n')}
114
- <task_progress>Checklist here (optional)</task_progress>
115
- </${tool.name}>
116
- `;
117
- }).join('\n')}
118
-
119
- # Tool Use Examples
120
- ${useDefaultTools.filter(item => Boolean(item.example)).map((item: any) => item.example).join('\n')}}
121
-
122
- # Tool Use Guidelines
123
-
124
- 1. In <thinking> tags, assess what information you already have and what information you need to proceed with the task.
125
- 2. Choose the most appropriate tool based on the task and the tool descriptions provided. Assess if you need additional information to proceed, and which of the available tools would be most effective for gathering this information. For example using the list_files tool is more effective than running a command like \`ls\` in the terminal. It's critical that you think about each available tool and use the one that best fits the current step in the task.
126
- 3. If multiple actions are needed, use one tool at a time per message to accomplish the task iteratively, with each tool use being informed by the result of the previous tool use. Do not assume the outcome of any tool use. Each step must be informed by the previous step's result.
127
- 4. Formulate your tool use using the XML format specified for each tool.
128
- 5. After each tool use, the user will respond with the result of that tool use. This result will provide you with the necessary information to continue your task or make further decisions. This response may include:
129
- - Information about whether the tool succeeded or failed, along with any reasons for failure.
130
- - Linter errors that may have arisen due to the changes you made, which you'll need to address.
131
- - New terminal output in reaction to the changes, which you may need to consider or act upon.
132
- - Any other relevant feedback or information related to the tool use.
133
- 6. ALWAYS wait for user confirmation after each tool use before proceeding. Never assume the success of a tool use without explicit confirmation of the result from the user.
134
-
135
- It is crucial to proceed step-by-step, waiting for the user's message after each tool use before moving forward with the task. This approach allows you to:
136
- 1. Confirm the success of each step before proceeding.
137
- 2. Address any issues or errors that arise immediately.
138
- 3. Adapt your approach based on new information or unexpected results.
139
- 4. Ensure that each action builds correctly on the previous ones.
140
-
141
- By waiting for and carefully considering the user's response after each tool use, you can react accordingly and make informed decisions about how to proceed with the task. This iterative process helps ensure the overall success and accuracy of your work.
142
-
143
- ====
144
-
145
- UPDATING TASK PROGRESS
146
-
147
- You can track and communicate your progress on the overall task using the task_progress parameter supported by every tool call. Using task_progress ensures you remain on task, and stay focused on completing the user's objective. This parameter can be used in any mode, and with any tool call.
148
-
149
- - When switching from PLAN MODE to ACT MODE, you must create a comprehensive todo list for the task using the task_progress parameter
150
- - Todo list updates should be done silently using the task_progress parameter - do not announce these updates to the user
151
- - Use standard Markdown checklist format: "- [ ]" for incomplete items and "- [x]" for completed items
152
- - Keep items focused on meaningful progress milestones rather than minor technical details. The checklist should not be so granular that minor implementation details clutter the progress tracking.
153
- - For simple tasks, short checklists with even a single item are acceptable. For complex tasks, avoid making the checklist too long or verbose.
154
- - If you are creating this checklist for the first time, and the tool use completes the first step in the checklist, make sure to mark it as completed in your task_progress parameter.
155
- - Provide the whole checklist of steps you intend to complete in the task, and keep the checkboxes updated as you make progress. It's okay to rewrite this checklist as needed if it becomes invalid due to scope changes or new information.
156
- - If a checklist is being used, be sure to update it any time a step has been completed.
157
- - The system will automatically include todo list context in your prompts when appropriate - these reminders are important.
158
-
159
- Example:
160
- <agent_execute_command>
161
- <command>npm install react</command>
162
- <requires_approval>false</requires_approval>
163
- <task_progress>
164
- - [x] Set up project structure
165
- - [x] Install dependencies
166
- - [ ] Create components
167
- - [ ] Test application
168
- </task_progress>
169
- </agent_execute_command>
170
-
171
- ====
172
-
173
- EDITING FILES
174
-
175
- You have access to two tools for working with files: **agent_write_to_file** and **agent_replace_in_file**. Understanding their roles and selecting the right one for the job will help ensure efficient and accurate modifications.
176
-
177
- # agent_write_to_file
178
-
179
- ## Purpose
180
-
181
- - Create a new file, or overwrite the entire contents of an existing file.
182
-
183
- ## When to Use
184
-
185
- - Initial file creation, such as when scaffolding a new project.
186
- - Overwriting large boilerplate files where you want to replace the entire content at once.
187
- - When the complexity or number of changes would make agent_replace_in_file unwieldy or error-prone.
188
- - When you need to completely restructure a file's content or change its fundamental organization.
189
-
190
- ## Important Considerations
191
-
192
- - Using agent_write_to_file requires providing the file's complete final content.
193
- - If you only need to make small changes to an existing file, consider using agent_replace_in_file instead to avoid unnecessarily rewriting the entire file.
194
- - While agent_write_to_file should not be your default choice, don't hesitate to use it when the situation truly calls for it.
195
-
196
- # agent_replace_in_file
197
-
198
- ## Purpose
199
-
200
- - Make targeted edits to specific parts of an existing file without overwriting the entire file.
201
-
202
- ## When to Use
203
-
204
- - Small, localized changes like updating a few lines, function implementations, changing variable names, modifying a section of text, etc.
205
- - Targeted improvements where only specific portions of the file's content needs to be altered.
206
- - Especially useful for long files where much of the file will remain unchanged.
207
-
208
- ## Advantages
209
-
210
- - More efficient for minor edits, since you don't need to supply the entire file content.
211
- - Reduces the chance of errors that can occur when overwriting large files.
212
-
213
- # Choosing the Appropriate Tool
214
-
215
- - **Default to agent_replace_in_file** for most changes. It's the safer, more precise option that minimizes potential issues.
216
- - **Use agent_write_to_file** when:
217
- - Creating new files
218
- - The changes are so extensive that using agent_replace_in_file would be more complex or risky
219
- - You need to completely reorganize or restructure a file
220
- - The file is relatively small and the changes affect most of its content
221
- - You're generating boilerplate or template files
222
-
223
- # Auto-formatting Considerations
224
-
225
- - After using either agent_write_to_file or agent_replace_in_file, the user's editor may automatically format the file
226
- - This auto-formatting may modify the file contents, for example:
227
- - Breaking single lines into multiple lines
228
- - Adjusting indentation to match project style (e.g. 2 spaces vs 4 spaces vs tabs)
229
- - Converting single quotes to double quotes (or vice versa based on project preferences)
230
- - Organizing imports (e.g. sorting, grouping by type)
231
- - Adding/removing trailing commas in objects and arrays
232
- - Enforcing consistent brace style (e.g. same-line vs new-line)
233
- - Standardizing semicolon usage (adding or removing based on style)
234
- - The agent_write_to_file and agent_replace_in_file tool responses will include the final state of the file after any auto-formatting
235
- - Use this final state as your reference point for any subsequent edits. This is ESPECIALLY important when crafting SEARCH blocks for replace_in_file which require the content to match what's in the file exactly.
236
-
237
- # Workflow Tips
238
-
239
- 1. Before editing, assess the scope of your changes and decide which tool to use.
240
- 2. For targeted edits, apply agent_replace_in_file with carefully crafted SEARCH/REPLACE blocks. If you need multiple changes, you can stack multiple SEARCH/REPLACE blocks within a single agent_replace_in_file call.
241
- 3. IMPORTANT: When you determine that you need to make several changes to the same file, prefer to use a single replace_in_file call with multiple SEARCH/REPLACE blocks. DO NOT prefer to make multiple successive replace_in_file calls for the same file. For example, if you were to add a component to a file, you would use a single replace_in_file call with a SEARCH/REPLACE block to add the import statement and another SEARCH/REPLACE block to add the component usage, rather than making one replace_in_file call for the import statement and then another separate replace_in_file call for the component usage.
242
- 4. For major overhauls or initial file creation, rely on agent_write_to_file.
243
- 5. Once the file has been edited with either agent_write_to_file or agent_replace_in_file, the system will provide you with the final state of the modified file. Use this updated content as the reference point for any subsequent SEARCH/REPLACE operations, since it reflects any auto-formatting or user-applied changes.
244
- By thoughtfully selecting between agent_write_to_file and agent_replace_in_file, you can make your file editing process smoother, safer, and more efficient.
245
-
246
- ====
247
- `;
248
- }
249
-
250
- getNoUseToolInstructions(context: any): string {
251
- return `[ERROR] You did not use a tool in your previous response! Please retry with a tool use.
252
-
253
- # Reminder: Instructions for Tool Use
254
- Tool uses are formatted using XML-style tags. The tool name is enclosed in opening and closing tags, and each parameter is similarly enclosed within its own set of tags. Here's the structure:
255
- <tool_name>
256
- <parameter1_name>value1</parameter1_name>
257
- <parameter2_name>value2</parameter2_name>
258
- ...
259
- </tool_name>
260
- For example:
261
- <agent_attempt_completion>
262
- <result>
263
- I have completed the task...
264
- </result>
265
- </agent_attempt_completion>
266
- Always adhere to this format for all tool uses to ensure proper parsing and execution.
267
-
268
- # Next Steps
269
-
270
- If you have completed the user's task, use the attempt_completion tool.
271
- If you require additional information from the user, use the ask_followup_question tool.
272
- Otherwise, if you have not completed the task and do not need additional information, then proceed with the next step of the task.
273
- (This is an automated message, so do not respond to it conversationally.)
274
- ${this?.getEnvironmentInfoPrompt?.(context)}`;
275
- }
276
- }