({
query,
config,
addItem,
onDebugMessage,
messageId: userMessageTimestamp,
signal,
}: HandleAtCommandParams)
| 125 | * LLM call and the processed query parts (including file content). |
| 126 | */ |
| 127 | export async function handleAtCommand({ |
| 128 | query, |
| 129 | config, |
| 130 | addItem, |
| 131 | onDebugMessage, |
| 132 | messageId: userMessageTimestamp, |
| 133 | signal, |
| 134 | }: HandleAtCommandParams): Promise<HandleAtCommandResult> { |
| 135 | const commandParts = parseAllAtCommands(query); |
| 136 | const atPathCommandParts = commandParts.filter( |
| 137 | (part) => part.type === 'atPath', |
| 138 | ); |
| 139 | |
| 140 | if (atPathCommandParts.length === 0) { |
| 141 | addItem({ type: 'user', text: query }, userMessageTimestamp); |
| 142 | return { processedQuery: [{ text: query }], shouldProceed: true }; |
| 143 | } |
| 144 | |
| 145 | addItem({ type: 'user', text: query }, userMessageTimestamp); |
| 146 | |
| 147 | // Get centralized file discovery service |
| 148 | const fileDiscovery = config.getFileService(); |
| 149 | |
| 150 | const respectFileIgnore = config.getFileFilteringOptions(); |
| 151 | |
| 152 | const pathSpecsToRead: string[] = []; |
| 153 | const atPathToResolvedSpecMap = new Map<string, string>(); |
| 154 | const contentLabelsForDisplay: string[] = []; |
| 155 | const ignoredByReason: Record<string, string[]> = { |
| 156 | git: [], |
| 157 | anus: [], |
| 158 | both: [], |
| 159 | }; |
| 160 | |
| 161 | const toolRegistry = await config.getToolRegistry(); |
| 162 | const readManyFilesTool = toolRegistry.getTool('read_many_files'); |
| 163 | const globTool = toolRegistry.getTool('glob'); |
| 164 | |
| 165 | if (!readManyFilesTool) { |
| 166 | addItem( |
| 167 | { type: 'error', text: 'Error: read_many_files tool not found.' }, |
| 168 | userMessageTimestamp, |
| 169 | ); |
| 170 | return { processedQuery: null, shouldProceed: false }; |
| 171 | } |
| 172 | |
| 173 | for (const atPathPart of atPathCommandParts) { |
| 174 | const originalAtPath = atPathPart.content; // e.g., "@file.txt" or "@" |
| 175 | |
| 176 | if (originalAtPath === '@') { |
| 177 | onDebugMessage( |
| 178 | 'Lone @ detected, will be treated as text in the modified query.', |
| 179 | ); |
| 180 | continue; |
| 181 | } |
| 182 | |
| 183 | const pathName = originalAtPath.substring(1); |
| 184 | if (!pathName) { |
no test coverage detected