parseToolCommands finds all !tool_name(...) patterns in the instruction.
(instruction string)
| 136 | |
| 137 | // parseToolCommands finds all !tool_name(...) patterns in the instruction. |
| 138 | func parseToolCommands(instruction string) []toolCommand { |
| 139 | var commands []toolCommand |
| 140 | |
| 141 | for i := 0; i < len(instruction); i++ { |
| 142 | if instruction[i] != '!' { |
| 143 | continue |
| 144 | } |
| 145 | |
| 146 | start := i |
| 147 | i++ |
| 148 | |
| 149 | // Parse tool name |
| 150 | nameStart := i |
| 151 | for i < len(instruction) && isWordChar(instruction[i]) { |
| 152 | i++ |
| 153 | } |
| 154 | if i == nameStart || i >= len(instruction) || instruction[i] != '(' { |
| 155 | continue |
| 156 | } |
| 157 | toolName := instruction[nameStart:i] |
| 158 | |
| 159 | // Find matching ')' |
| 160 | argsStart := i + 1 |
| 161 | end, ok := findMatchingParen(instruction, i) |
| 162 | if !ok { |
| 163 | continue |
| 164 | } |
| 165 | |
| 166 | commands = append(commands, toolCommand{ |
| 167 | start: start, |
| 168 | end: end, |
| 169 | toolName: toolName, |
| 170 | argsStr: instruction[argsStart : end-1], |
| 171 | }) |
| 172 | i = end - 1 // -1 because loop will increment |
| 173 | } |
| 174 | |
| 175 | return commands |
| 176 | } |
| 177 | |
| 178 | // findMatchingParen finds the index after the matching closing parenthesis. |
| 179 | // It handles nested parentheses and quoted strings. |