Skip to content

Commit 0beb87e

Browse files
committed
WIP
1 parent 071a345 commit 0beb87e

1 file changed

Lines changed: 143 additions & 0 deletions

File tree

src/test/common/sessionParsing.test.ts

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ import {
1313
} from '../../../common/sessionParsing';
1414
import { diffHeaders, diffNoAts, simpleDiff } from './fixtures/gitdiff/sessionParsing';
1515

16+
// Helper to construct a toolCall object
17+
function makeToolCall(name: string, args: any): any {
18+
return {
19+
function: { name, arguments: JSON.stringify(args) },
20+
id: 'id_' + name + '_' + Math.random().toString(36).slice(2),
21+
type: 'function',
22+
index: 0
23+
};
24+
}
25+
1626
describe('sessionParsing', function () {
1727
describe('parseSessionLogs()', function () {
1828
it('should parse valid session logs', function () {
@@ -206,6 +216,139 @@ another non-data line`;
206216
assert.strictEqual(result.toolName, 'Read repository');
207217
assert.strictEqual(result.invocationMessage, 'Read repository');
208218
});
219+
220+
it('handles str_replace_editor view with diff-parsed content (empty file label -> repository)', function () {
221+
const diff = [
222+
'diff --git a/src/file.ts b/src/file.ts',
223+
'index 1111111..2222222 100644',
224+
'--- a/src/file.ts',
225+
'+++ b/src/file.ts',
226+
'@@ -1,2 +1,2 @@',
227+
'-old line',
228+
'+new line'
229+
].join('\n');
230+
const toolCall = makeToolCall('str_replace_editor', { command: 'view', view_range: [1, 10] });
231+
const result = parseToolCallDetails(toolCall, diff);
232+
assert.strictEqual(result.toolName, 'Read repository');
233+
assert.strictEqual(result.invocationMessage, 'Read repository');
234+
});
235+
236+
it('handles str_replace_editor view with diff-parsed content (non-empty file label)', function () {
237+
const diff = [
238+
'diff --git a/home/runner/work/repo/repo/src/deep/file.ts b/home/runner/work/repo/repo/src/deep/file.ts',
239+
'index 1111111..2222222 100644',
240+
'--- a/home/runner/work/repo/repo/src/deep/file.ts',
241+
'+++ b/home/runner/work/repo/repo/src/deep/file.ts',
242+
'@@ -1,2 +1,2 @@',
243+
'-old line',
244+
'+new line'
245+
].join('\n');
246+
const toolCall = makeToolCall('str_replace_editor', { command: 'view', view_range: [2, 8] });
247+
const result = parseToolCallDetails(toolCall, diff);
248+
assert.strictEqual(result.toolName, 'Read');
249+
assert.ok(result.invocationMessage.includes('src/deep/file.ts'));
250+
assert.ok(result.invocationMessage.includes('lines 2 to 8'));
251+
assert.ok(result.toolSpecificData && 'command' in result.toolSpecificData);
252+
});
253+
254+
it('handles str_replace_editor view with path but unparsable diff content (no diff headers)', function () {
255+
const content = 'just some file content without diff headers';
256+
const toolCall = makeToolCall('str_replace_editor', { command: 'view', path: '/home/runner/work/repo/repo/src/other.ts' });
257+
const result = parseToolCallDetails(toolCall, content);
258+
assert.strictEqual(result.toolName, 'Read');
259+
assert.strictEqual(result.invocationMessage, 'Read src/other.ts');
260+
});
261+
262+
it('handles str_replace_editor view with undefined path (no label)', function () {
263+
const toolCall = makeToolCall('str_replace_editor', { command: 'view' });
264+
const result = parseToolCallDetails(toolCall, 'plain content');
265+
assert.strictEqual(result.toolName, 'Read repository');
266+
assert.strictEqual(result.invocationMessage, 'Read repository');
267+
});
268+
269+
it('handles str_replace_editor view with root repository path empty label branch', function () {
270+
const toolCall = makeToolCall('str_replace_editor', { command: 'view', path: '/home/runner/work/repo/repo/' });
271+
const result = parseToolCallDetails(toolCall, 'content');
272+
assert.strictEqual(result.toolName, 'Read repository');
273+
});
274+
275+
it('handles str_replace_editor edit with range', function () {
276+
const toolCall = makeToolCall('str_replace_editor', { command: 'edit', path: '/home/runner/work/repo/repo/src/editMe.ts', view_range: [5, 15] });
277+
const result = parseToolCallDetails(toolCall, '');
278+
assert.strictEqual(result.toolName, 'Edit');
279+
assert.ok(result.invocationMessage.includes('lines 5 to 15'));
280+
});
281+
282+
it('handles str_replace (non-editor) path missing label fallback', function () {
283+
// Provide a path that toFileLabel will still shorten; assert structure
284+
const toolCall = makeToolCall('str_replace', { path: '/home/runner/work/repo/repo/src/x.ts' });
285+
const result = parseToolCallDetails(toolCall, '');
286+
assert.strictEqual(result.toolName, 'Edit');
287+
assert.strictEqual(result.invocationMessage, 'Edit [](src/x.ts)');
288+
});
289+
290+
it('handles create tool call', function () {
291+
const toolCall = makeToolCall('create', { path: '/home/runner/work/repo/repo/new/file.txt' });
292+
const result = parseToolCallDetails(toolCall, '');
293+
assert.strictEqual(result.toolName, 'Create');
294+
assert.strictEqual(result.invocationMessage, 'Create [](new/file.txt)');
295+
});
296+
297+
it('handles view tool call (non str_replace_editor) with range and root path giving repository label', function () {
298+
const toolCall = makeToolCall('view', { path: '/home/runner/work/repo/repo/', view_range: [2, 3] });
299+
const result = parseToolCallDetails(toolCall, '');
300+
assert.strictEqual(result.toolName, 'Read repository');
301+
assert.strictEqual(result.invocationMessage, 'Read repository');
302+
});
303+
304+
it('handles view tool call (non str_replace_editor) with file path and range', function () {
305+
const toolCall = makeToolCall('view', { path: '/home/runner/work/repo/repo/src/app.ts', view_range: [3, 7] });
306+
const result = parseToolCallDetails(toolCall, '');
307+
assert.strictEqual(result.toolName, 'Read');
308+
assert.ok(result.invocationMessage.includes('lines 3 to 7'));
309+
});
310+
311+
it('handles bash tool call without command (only content)', function () {
312+
const toolCall = makeToolCall('bash', {});
313+
const result = parseToolCallDetails(toolCall, 'only output');
314+
assert.strictEqual(result.toolName, 'Run Bash command');
315+
assert.strictEqual(result.invocationMessage, 'only output');
316+
assert.ok(!result.toolSpecificData); // no command so no toolSpecificData
317+
});
318+
319+
it('handles read_bash tool call', function () {
320+
const toolCall = makeToolCall('read_bash', {});
321+
const result = parseToolCallDetails(toolCall, 'ignored');
322+
assert.strictEqual(result.toolName, 'read_bash');
323+
assert.strictEqual(result.invocationMessage, 'Read logs from Bash session');
324+
});
325+
326+
it('handles stop_bash tool call', function () {
327+
const toolCall = makeToolCall('stop_bash', {});
328+
const result = parseToolCallDetails(toolCall, 'ignored');
329+
assert.strictEqual(result.toolName, 'stop_bash');
330+
assert.strictEqual(result.invocationMessage, 'Stop Bash session');
331+
});
332+
333+
it('handles unknown tool call with empty content falling back to name', function () {
334+
const toolCall = makeToolCall('mystery_tool', { some: 'arg' });
335+
const result = parseToolCallDetails(toolCall, '');
336+
assert.strictEqual(result.toolName, 'mystery_tool');
337+
assert.strictEqual(result.invocationMessage, 'mystery_tool');
338+
});
339+
340+
it('gracefully handles invalid JSON arguments for non-view str_replace_editor (edit path undefined)', function () {
341+
const toolCall = {
342+
function: { name: 'str_replace_editor', arguments: '{"command": "edit", invalid' },
343+
id: 'bad_json',
344+
type: 'function',
345+
index: 0
346+
};
347+
// Since JSON parse fails, args becomes {} and we are in else branch -> toolName Edit without file label
348+
const result = parseToolCallDetails(toolCall as any, '');
349+
assert.strictEqual(result.toolName, 'Edit');
350+
assert.strictEqual(result.invocationMessage, 'Edit');
351+
});
209352
});
210353

211354
describe('parseDiff()', function () {

0 commit comments

Comments
 (0)