Skip to content

Commit 794adc3

Browse files
authored
Simply complex if statement and reduce duplicate code (#7821)
1 parent c80b4a6 commit 794adc3

File tree

1 file changed

+125
-138
lines changed

1 file changed

+125
-138
lines changed

common/sessionParsing.ts

Lines changed: 125 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -160,169 +160,156 @@ export function parseToolCallDetails(
160160
},
161161
content: string
162162
): ParsedToolCallDetails {
163+
// Parse arguments once with graceful fallback
163164
let args: { command?: string, path?: string, prDescription?: string, commitMessage?: string, view_range?: unknown } = {};
164-
try {
165-
args = toolCall.function.arguments ? JSON.parse(toolCall.function.arguments) : {};
166-
} catch {
167-
// fallback to empty args
168-
}
165+
try { args = toolCall.function.arguments ? JSON.parse(toolCall.function.arguments) : {}; } catch { /* ignore */ }
169166

170167
const name = toolCall.function.name;
171168

172-
if (name === 'str_replace_editor') {
173-
if (args.command === 'view') {
174-
const parsedContent = parseDiff(content);
175-
const parsedRange = parseRange(args.view_range);
176-
if (parsedContent) {
177-
const file = parsedContent.fileA ?? parsedContent.fileB;
178-
const fileLabel = file && toFileLabel(file);
179-
return {
180-
toolName: fileLabel === '' ? 'Read repository' : 'Read',
181-
invocationMessage: fileLabel ? (`Read [](${fileLabel})` + (parsedRange ? `, lines ${parsedRange.start} to ${parsedRange.end}` : '')) : 'Read repository',
182-
pastTenseMessage: fileLabel ? (`Read [](${fileLabel})` + (parsedRange ? `, lines ${parsedRange.start} to ${parsedRange.end}` : '')) : 'Read repository',
183-
toolSpecificData: fileLabel ? {
184-
command: 'view',
185-
filePath: file,
186-
fileLabel: fileLabel,
187-
parsedContent: parsedContent,
188-
viewRange: parsedRange
189-
} : undefined
190-
};
191-
} else {
192-
const filePath = args.path;
193-
let fileLabel = filePath ? toFileLabel(filePath) : undefined;
194-
195-
if (fileLabel === undefined || fileLabel === '') {
196-
return {
197-
toolName: 'Read repository',
198-
invocationMessage: 'Read repository',
199-
pastTenseMessage: 'Read repository',
200-
};
201-
} else {
202-
return {
203-
toolName: `Read`,
204-
invocationMessage: (`Read ${fileLabel}` + (parsedRange ? `, lines ${parsedRange.start} to ${parsedRange.end}` : '')),
205-
pastTenseMessage: (`Read ${fileLabel}` + (parsedRange ? `, lines ${parsedRange.start} to ${parsedRange.end}` : '')),
206-
toolSpecificData: {
207-
command: 'view',
208-
filePath: filePath,
209-
fileLabel: fileLabel,
210-
viewRange: parsedRange
211-
}
212-
};
213-
}
214-
}
215-
} else {
216-
const filePath = args.path;
217-
const fileLabel = filePath && toFileLabel(filePath);
218-
const parsedRange = parseRange(args.view_range);
219-
220-
return {
221-
toolName: 'Edit',
222-
invocationMessage: fileLabel ? (`Edit [](${fileLabel})` + (parsedRange ? `, lines ${parsedRange.start} to ${parsedRange.end}` : '')) : 'Edit',
223-
pastTenseMessage: fileLabel ? (`Edit [](${fileLabel})` + (parsedRange ? `, lines ${parsedRange.start} to ${parsedRange.end}` : '')) : 'Edit',
224-
toolSpecificData: fileLabel ? {
225-
command: args.command || 'edit',
226-
filePath: filePath,
227-
fileLabel: fileLabel,
228-
viewRange: parsedRange
229-
} : undefined
230-
};
231-
}
232-
} else if (name === 'str_replace') {
233-
const filePath = args.path;
169+
// Small focused helpers to remove duplication while preserving behavior
170+
const buildReadDetails = (filePath: string | undefined, parsedRange: { start: number, end: number } | undefined, opts?: { parsedContent?: { content: string; fileA: string | undefined; fileB: string | undefined; } }): ParsedToolCallDetails => {
234171
const fileLabel = filePath && toFileLabel(filePath);
235-
172+
if (fileLabel === undefined || fileLabel === '') {
173+
return { toolName: 'Read repository', invocationMessage: 'Read repository', pastTenseMessage: 'Read repository' };
174+
}
175+
const rangeSuffix = parsedRange ? `, lines ${parsedRange.start} to ${parsedRange.end}` : '';
176+
// Default helper returns bracket variant (used for generic view). Plain variant handled separately for str_replace_editor non-diff.
236177
return {
237-
toolName: 'Edit',
238-
invocationMessage: fileLabel ? `Edit [](${fileLabel})` : `Edit ${filePath}`,
239-
pastTenseMessage: fileLabel ? `Edit [](${fileLabel})` : `Edit ${filePath}`,
240-
toolSpecificData: fileLabel ? {
241-
command: 'str_replace',
178+
toolName: 'Read',
179+
invocationMessage: `Read [](${fileLabel})${rangeSuffix}`,
180+
pastTenseMessage: `Read [](${fileLabel})${rangeSuffix}`,
181+
toolSpecificData: {
182+
command: 'view',
242183
filePath: filePath,
243184
fileLabel: fileLabel,
244-
} : undefined
185+
parsedContent: opts?.parsedContent,
186+
viewRange: parsedRange
187+
}
245188
};
246-
} else if (name === 'create') {
247-
const filePath = args.path;
248-
const fileLabel = filePath && toFileLabel(filePath);
189+
};
249190

250-
return {
251-
toolName: 'Create',
252-
invocationMessage: fileLabel ? `Create [](${fileLabel})` : `Create File ${filePath}`,
253-
pastTenseMessage: fileLabel ? `Create [](${fileLabel})` : `Create File ${filePath}`,
254-
toolSpecificData: fileLabel ? {
255-
command: 'create',
256-
filePath: filePath,
257-
fileLabel: fileLabel,
258-
} : undefined
259-
};
260-
} else if (name === 'view') {
261-
const filePath = args.path;
191+
const buildEditDetails = (filePath: string | undefined, command: string, parsedRange: { start: number, end: number } | undefined, opts?: { defaultName?: string }): ParsedToolCallDetails => {
262192
const fileLabel = filePath && toFileLabel(filePath);
263-
const parsedRange = parseRange(args.view_range);
193+
const rangeSuffix = parsedRange ? `, lines ${parsedRange.start} to ${parsedRange.end}` : '';
194+
let invocationMessage: string;
195+
let pastTenseMessage: string;
196+
if (fileLabel) {
197+
invocationMessage = `Edit [](${fileLabel})${rangeSuffix}`;
198+
pastTenseMessage = `Edit [](${fileLabel})${rangeSuffix}`;
199+
} else {
200+
if (opts?.defaultName === 'Create') {
201+
invocationMessage = pastTenseMessage = `Create File ${filePath}`;
202+
} else {
203+
invocationMessage = pastTenseMessage = (opts?.defaultName || 'Edit');
204+
}
205+
invocationMessage += rangeSuffix;
206+
pastTenseMessage += rangeSuffix;
207+
}
264208

265209
return {
266-
toolName: fileLabel === '' ? 'Read repository' : 'Read',
267-
invocationMessage: fileLabel ? (`Read [](${fileLabel})` + (parsedRange ? `, lines ${parsedRange.start} to ${parsedRange.end}` : '')) : 'Read repository',
268-
pastTenseMessage: fileLabel ? (`Read [](${fileLabel})` + (parsedRange ? `, lines ${parsedRange.start} to ${parsedRange.end}` : '')) : 'Read repository',
210+
toolName: opts?.defaultName || 'Edit',
211+
invocationMessage,
212+
pastTenseMessage,
269213
toolSpecificData: fileLabel ? {
270-
command: 'view',
214+
command: command || (opts?.defaultName === 'Create' ? 'create' : (command || 'edit')),
271215
filePath: filePath,
272216
fileLabel: fileLabel,
273217
viewRange: parsedRange
274218
} : undefined
275219
};
276-
} else if (name === 'think') {
277-
const thought = (args as unknown as { thought?: string }).thought || content || 'Thought';
220+
};
221+
222+
const buildStrReplaceDetails = (filePath: string | undefined): ParsedToolCallDetails => {
223+
const fileLabel = filePath && toFileLabel(filePath);
224+
const message = fileLabel ? `Edit [](${fileLabel})` : `Edit ${filePath}`;
278225
return {
279-
toolName: 'think',
280-
invocationMessage: thought,
226+
toolName: 'Edit',
227+
invocationMessage: message,
228+
pastTenseMessage: message,
229+
toolSpecificData: fileLabel ? { command: 'str_replace', filePath, fileLabel } : undefined
281230
};
282-
} else if (name === 'report_progress') {
283-
const details: ParsedToolCallDetails = {
284-
toolName: 'Progress Update',
285-
invocationMessage: `${args.prDescription}` || content || 'Progress Update'
231+
};
232+
233+
const buildCreateDetails = (filePath: string | undefined): ParsedToolCallDetails => {
234+
const fileLabel = filePath && toFileLabel(filePath);
235+
const message = fileLabel ? `Create [](${fileLabel})` : `Create File ${filePath}`;
236+
return {
237+
toolName: 'Create',
238+
invocationMessage: message,
239+
pastTenseMessage: message,
240+
toolSpecificData: fileLabel ? { command: 'create', filePath, fileLabel } : undefined
286241
};
287-
if (args.commitMessage) {
288-
details.originMessage = `Commit: ${args.commitMessage}`;
289-
}
242+
};
243+
244+
const buildBashDetails = (bashArgs: typeof args, contentStr: string): ParsedToolCallDetails => {
245+
const command = bashArgs.command ? `$ ${bashArgs.command}` : undefined;
246+
const bashContent = [command, contentStr].filter(Boolean).join('\n');
247+
const details: ParsedToolCallDetails = { toolName: 'Run Bash command', invocationMessage: bashContent || 'Run Bash command' };
248+
if (bashArgs.command) { details.toolSpecificData = { commandLine: { original: bashArgs.command }, language: 'bash' }; }
290249
return details;
291-
} else if (name === 'bash') {
292-
const command = args.command ? `$ ${args.command}` : undefined;
293-
const bashContent = [command, content].filter(Boolean).join('\n');
294-
const details: ParsedToolCallDetails = {
295-
toolName: 'Run Bash command',
296-
invocationMessage: bashContent || 'Run Bash command',
297-
};
250+
};
298251

299-
// Use the terminal-specific data for bash commands
300-
if (args.command) {
301-
const bashToolData: BashToolData = {
302-
commandLine: {
303-
original: args.command,
304-
},
305-
language: 'bash'
306-
};
307-
details.toolSpecificData = bashToolData;
252+
switch (name) {
253+
case 'str_replace_editor': {
254+
if (args.command === 'view') {
255+
const parsedContent = parseDiff(content);
256+
const parsedRange = parseRange(args.view_range);
257+
if (parsedContent) {
258+
const file = parsedContent.fileA ?? parsedContent.fileB;
259+
const fileLabel = file && toFileLabel(file);
260+
if (fileLabel === '') {
261+
return { toolName: 'Read repository', invocationMessage: 'Read repository', pastTenseMessage: 'Read repository' };
262+
} else if (fileLabel === undefined) {
263+
return { toolName: 'Read', invocationMessage: 'Read repository', pastTenseMessage: 'Read repository' };
264+
} else {
265+
const rangeSuffix = parsedRange ? `, lines ${parsedRange.start} to ${parsedRange.end}` : '';
266+
return {
267+
toolName: 'Read',
268+
invocationMessage: `Read [](${fileLabel})${rangeSuffix}`,
269+
pastTenseMessage: `Read [](${fileLabel})${rangeSuffix}`,
270+
toolSpecificData: { command: 'view', filePath: file, fileLabel, parsedContent, viewRange: parsedRange }
271+
};
272+
}
273+
}
274+
// No diff parsed: use PLAIN (non-bracket) variant for str_replace_editor views
275+
const plainRange = parseRange(args.view_range);
276+
const fp = args.path; const fl = fp && toFileLabel(fp);
277+
if (fl === undefined || fl === '') {
278+
return { toolName: 'Read repository', invocationMessage: 'Read repository', pastTenseMessage: 'Read repository' };
279+
}
280+
const suffix = plainRange ? `, lines ${plainRange.start} to ${plainRange.end}` : '';
281+
return {
282+
toolName: 'Read',
283+
invocationMessage: `Read ${fl}${suffix}`,
284+
pastTenseMessage: `Read ${fl}${suffix}`,
285+
toolSpecificData: { command: 'view', filePath: fp, fileLabel: fl, viewRange: plainRange }
286+
};
287+
}
288+
return buildEditDetails(args.path, args.command || 'edit', parseRange(args.view_range));
308289
}
309-
return details;
310-
} else if (name === 'read_bash') {
311-
return {
312-
toolName: 'read_bash',
313-
invocationMessage: 'Read logs from Bash session'
314-
};
315-
} else if (name === 'stop_bash') {
316-
return {
317-
toolName: 'stop_bash',
318-
invocationMessage: 'Stop Bash session'
319-
};
320-
} else {
321-
// Unknown tool type
322-
return {
323-
toolName: name || 'unknown',
324-
invocationMessage: content || name || 'unknown'
325-
};
290+
case 'str_replace':
291+
return buildStrReplaceDetails(args.path);
292+
case 'create':
293+
return buildCreateDetails(args.path);
294+
case 'view':
295+
return buildReadDetails(args.path, parseRange(args.view_range)); // generic view always bracket variant
296+
case 'think': {
297+
const thought = (args as unknown as { thought?: string }).thought || content || 'Thought';
298+
return { toolName: 'think', invocationMessage: thought };
299+
}
300+
case 'report_progress': {
301+
const details: ParsedToolCallDetails = { toolName: 'Progress Update', invocationMessage: `${args.prDescription}` || content || 'Progress Update' };
302+
if (args.commitMessage) { details.originMessage = `Commit: ${args.commitMessage}`; }
303+
return details;
304+
}
305+
case 'bash':
306+
return buildBashDetails(args, content);
307+
case 'read_bash':
308+
return { toolName: 'read_bash', invocationMessage: 'Read logs from Bash session' };
309+
case 'stop_bash':
310+
return { toolName: 'stop_bash', invocationMessage: 'Stop Bash session' };
311+
default:
312+
return { toolName: name || 'unknown', invocationMessage: content || name || 'unknown' };
326313
}
327314
}
328315

0 commit comments

Comments
 (0)