|
| 1 | +import { Message } from 'types/util-types' |
| 2 | +import { publisher } from '../constants' |
| 3 | +import { |
| 4 | + PLACEHOLDER, |
| 5 | + type SecretAgentDefinition, |
| 6 | +} from '../types/secret-agent-definition' |
| 7 | + |
| 8 | +const editor: SecretAgentDefinition = { |
| 9 | + id: 'editor-lite', |
| 10 | + publisher, |
| 11 | + model: 'x-ai/grok-code-fast-1', |
| 12 | + displayName: 'Fast Code Editor', |
| 13 | + spawnerPrompt: |
| 14 | + 'Fast code editor with access to tools to find and edit files, run terminal commands. Can handle only easy coding tasks, unless working off of a plan. This is a great agent to spawn to implement a step-by-step plan!', |
| 15 | + inputSchema: { |
| 16 | + prompt: { |
| 17 | + type: 'string', |
| 18 | + description: 'The coding task to implement', |
| 19 | + }, |
| 20 | + params: { |
| 21 | + type: 'object', |
| 22 | + properties: { |
| 23 | + maxContextLength: { |
| 24 | + type: 'number', |
| 25 | + }, |
| 26 | + }, |
| 27 | + required: [], |
| 28 | + }, |
| 29 | + }, |
| 30 | + outputMode: 'structured_output', |
| 31 | + includeMessageHistory: true, |
| 32 | + toolNames: [ |
| 33 | + 'read_files', |
| 34 | + 'write_file', |
| 35 | + 'str_replace', |
| 36 | + 'run_terminal_command', |
| 37 | + 'code_search', |
| 38 | + 'spawn_agents', |
| 39 | + 'add_message', |
| 40 | + 'set_output', |
| 41 | + ], |
| 42 | + spawnableAgents: ['file-explorer'], |
| 43 | + |
| 44 | + systemPrompt: `You are an expert code editor with deep understanding of software engineering principles. |
| 45 | +
|
| 46 | +# Core Mandates |
| 47 | +
|
| 48 | +- **Conventions:** Rigorously adhere to existing project conventions when reading or modifying code. Analyze surrounding code, tests, and configuration first. |
| 49 | +- **Libraries/Frameworks:** NEVER assume a library/framework is available or appropriate. Verify its established usage within the project (check imports, configuration files like 'package.json', 'Cargo.toml', 'requirements.txt', 'build.gradle', etc., or observe neighboring files) before employing it. |
| 50 | +- **Style & Structure:** Mimic the style (formatting, naming), structure, framework choices, typing, and architectural patterns of existing code in the project. |
| 51 | +- **Idiomatic Changes:** When editing, understand the local context (imports, functions/classes) to ensure your changes integrate naturally and idiomatically. |
| 52 | +- **No code comments:** *NEVER* add any comments while writing code, unless the user asks you to! *NEVER* talk to the user or describe your changes through comments. Do not edit comments that are separate from the code you are changing. |
| 53 | +- **Minimal Changes:** Make as few changes as possible to satisfy the user request! Don't go beyond what the user has asked for. |
| 54 | +- **Code Reuse:** Always reuse helper functions, components, classes, etc., whenever possible! Don't reimplement what already exists elsewhere in the codebase. |
| 55 | +- **Security First:** Always apply security best practices. Never introduce code that exposes, logs, or commits secrets, API keys, or other sensitive information. |
| 56 | +- **Front end development** We want to make the UI look as good as possible. Don't hold back. Give it your all. |
| 57 | + - Include as many relevant features and interactions as possible |
| 58 | + - Add thoughtful details like hover states, transitions, and micro-interactions |
| 59 | + - Apply design principles: hierarchy, contrast, balance, and movement |
| 60 | + - Create an impressive demonstration showcasing web development capabilities |
| 61 | +- **Refactoring Awareness:** Whenever you modify an exported symbol like a function or class or variable, you should find and update all the references to it appropriately. |
| 62 | +- **Package Management:** When adding new packages, use the run_terminal_command tool to install the package rather than editing the package.json file with a guess at the version number to use (or similar for other languages). This way, you will be sure to have the latest version of the package. Do not install packages globally unless asked by the user (e.g. Don't run \`npm install -g <package-name>\`). Always try to use the package manager associated with the project (e.g. it might be \`pnpm\` or \`bun\` or \`yarn\` instead of \`npm\`, or similar for other languages). |
| 63 | +- **Code Hygiene:** Make sure to leave things in a good state: |
| 64 | + - Don't forget to add any imports that might be needed |
| 65 | + - Remove unused variables, functions, and files as a result of your changes. |
| 66 | + - If you added files or functions meant to replace existing code, then you should also remove the previous code. |
| 67 | +- **Summarize with set_output:** You must use the set_output tool before finishing and include a clear explanation of the changes made or an answer to the user prompt. Do not write a separate summary outside of the set_output tool. |
| 68 | +
|
| 69 | +${PLACEHOLDER.KNOWLEDGE_FILES_CONTENTS}`, |
| 70 | + |
| 71 | + instructionsPrompt: `Implement the requested changes, using your judgment as needed, but referring to the original <user-message> as the most important source of information. |
| 72 | +
|
| 73 | +# Instructions |
| 74 | +
|
| 75 | +- It's helpful to spawn a file explorer to discover all the relevant files for implementing the plan. |
| 76 | +- You must read all relevant files to understand the current state. You must read any file that could be relevant to the plan, especially files you need to modify, but also files that could show codebase patterns you could imitate. Try to read a lot of files in a single tool call. E.g. use read_files on 12 different files, and then use read_files on 6 more files that fill in the gaps. |
| 77 | +- Implement changes using str_replace or write_file. |
| 78 | +- You must use the set_output tool before finishing and include the following in your summary: |
| 79 | + - An answer to the user prompt (if they asked a question). |
| 80 | + - An explanation of the changes made. |
| 81 | + - A note on any checks you ran to verify the changes, such as tests, typechecking, etc. |
| 82 | + - Do not include a section on the benefits of the changes, as we're most interested in the changes themselves and what still needs to be done. |
| 83 | +- Do not write a summary outside of the one that you include in the set_output tool. |
| 84 | +`, |
| 85 | + |
| 86 | + handleSteps: function* ({ agentState: initialAgentState }) { |
| 87 | + const stepLimit = 35 |
| 88 | + let stepCount = 0 |
| 89 | + let agentState = initialAgentState |
| 90 | + let accumulatedEditToolResults: any[] = [] |
| 91 | + |
| 92 | + while (true) { |
| 93 | + stepCount++ |
| 94 | + |
| 95 | + const stepResult = yield 'STEP' |
| 96 | + agentState = stepResult.agentState // Capture the latest state |
| 97 | + |
| 98 | + // Accumulate new tool messages from this step |
| 99 | + const { messageHistory } = agentState |
| 100 | + |
| 101 | + // Extract and accumulate new edit tool results using helper function |
| 102 | + accumulatedEditToolResults.push( |
| 103 | + ...getLatestEditToolResults(messageHistory), |
| 104 | + ) |
| 105 | + |
| 106 | + if (stepResult.stepsComplete) { |
| 107 | + break |
| 108 | + } |
| 109 | + |
| 110 | + // If we've reached within one of the step limit, ask LLM to summarize progress |
| 111 | + if (stepCount === stepLimit - 1) { |
| 112 | + yield { |
| 113 | + toolName: 'add_message', |
| 114 | + input: { |
| 115 | + role: 'user', |
| 116 | + content: |
| 117 | + 'You have reached the step limit. Please use the set_output tool now to summarize your progress so far including all specific actions you took (note that any file changes will be included automatically in the output), what you still need to solve, and provide any insights that could help complete the remaining work. Please end your turn after using the set_output tool with the end_turn tool.', |
| 118 | + }, |
| 119 | + includeToolCall: false, |
| 120 | + } |
| 121 | + |
| 122 | + // One final step to produce the summary |
| 123 | + const finalStepResult = yield 'STEP' |
| 124 | + agentState = finalStepResult.agentState |
| 125 | + |
| 126 | + // Extract and accumulate final edit tool results using helper function |
| 127 | + accumulatedEditToolResults.push( |
| 128 | + ...getLatestEditToolResults(agentState.messageHistory), |
| 129 | + ) |
| 130 | + break |
| 131 | + } |
| 132 | + } |
| 133 | + |
| 134 | + yield { |
| 135 | + toolName: 'set_output', |
| 136 | + input: { |
| 137 | + ...agentState.output, |
| 138 | + edits: accumulatedEditToolResults, |
| 139 | + }, |
| 140 | + } |
| 141 | + |
| 142 | + function getLatestEditToolResults(messageHistory: Message[]) { |
| 143 | + const lastAssistantMessageIndex = messageHistory.findLastIndex( |
| 144 | + (message) => message.role === 'assistant', |
| 145 | + ) |
| 146 | + |
| 147 | + // Get all edit tool messages after the last assistant message |
| 148 | + const newToolMessages = messageHistory |
| 149 | + .slice(lastAssistantMessageIndex + 1) |
| 150 | + .filter((message) => message.role === 'tool') |
| 151 | + .filter( |
| 152 | + (message) => |
| 153 | + message.content.toolName === 'write_file' || |
| 154 | + message.content.toolName === 'str_replace', |
| 155 | + ) |
| 156 | + |
| 157 | + // Extract and return new edit tool results |
| 158 | + return ( |
| 159 | + newToolMessages |
| 160 | + .flatMap((message) => message.content.output) |
| 161 | + .filter((output) => output.type === 'json') |
| 162 | + .map((output) => output.value) |
| 163 | + // Only successful edits! |
| 164 | + .filter( |
| 165 | + (toolResult) => |
| 166 | + toolResult && !('errorMessage' in (toolResult as any)), |
| 167 | + ) |
| 168 | + ) |
| 169 | + } |
| 170 | + }, |
| 171 | +} |
| 172 | + |
| 173 | +export default editor |
0 commit comments