|
4 | 4 | *--------------------------------------------------------------------------------------------*/ |
5 | 5 |
|
6 | 6 | import assert from 'assert'; |
| 7 | +import { CancellationToken } from '../../../../../../../base/common/cancellation.js'; |
| 8 | +import { Event } from '../../../../../../../base/common/event.js'; |
| 9 | +import { URI } from '../../../../../../../base/common/uri.js'; |
7 | 10 | import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../../../base/test/common/utils.js'; |
8 | | -import { createManageTodoListToolData } from '../../../../common/tools/builtinTools/manageTodoListTool.js'; |
9 | | -import { IToolData } from '../../../../common/tools/languageModelToolsService.js'; |
| 11 | +import { NullLogService } from '../../../../../../../platform/log/common/log.js'; |
| 12 | +import { NullTelemetryService } from '../../../../../../../platform/telemetry/common/telemetryUtils.js'; |
| 13 | +import { createManageTodoListToolData, ManageTodoListTool } from '../../../../common/tools/builtinTools/manageTodoListTool.js'; |
| 14 | +import { IChatTodo, IChatTodoListService } from '../../../../common/tools/chatTodoListService.js'; |
| 15 | +import { IToolData, ToolInvocationPresentation } from '../../../../common/tools/languageModelToolsService.js'; |
10 | 16 | import { IJSONSchema } from '../../../../../../../base/common/jsonSchema.js'; |
11 | 17 |
|
12 | 18 | suite('ManageTodoListTool Schema', () => { |
@@ -59,3 +65,83 @@ suite('ManageTodoListTool Schema', () => { |
59 | 65 | assert.deepStrictEqual(statusProperty.enum, ['not-started', 'in-progress', 'completed'], 'Status should have correct enum values'); |
60 | 66 | }); |
61 | 67 | }); |
| 68 | + |
| 69 | +suite('ManageTodoListTool prepareToolInvocation', () => { |
| 70 | + const store = ensureNoDisposablesAreLeakedInTestSuite(); |
| 71 | + const sessionResource = URI.parse('vscode-chat://session/1'); |
| 72 | + |
| 73 | + function createMockTodoListService(todos: IChatTodo[] = []): IChatTodoListService { |
| 74 | + return { |
| 75 | + _serviceBrand: undefined, |
| 76 | + onDidUpdateTodos: Event.None, |
| 77 | + getTodos: () => todos, |
| 78 | + setTodos: () => { }, |
| 79 | + migrateTodos: () => { }, |
| 80 | + }; |
| 81 | + } |
| 82 | + |
| 83 | + function createTool(todos: IChatTodo[] = []): ManageTodoListTool { |
| 84 | + return store.add(new ManageTodoListTool( |
| 85 | + createMockTodoListService(todos), |
| 86 | + new NullLogService(), |
| 87 | + NullTelemetryService, |
| 88 | + )); |
| 89 | + } |
| 90 | + |
| 91 | + test('presentation is Hidden when todoList param is empty', async () => { |
| 92 | + const tool = createTool(); |
| 93 | + const result = await tool.prepareToolInvocation({ |
| 94 | + parameters: { todoList: [] }, |
| 95 | + toolCallId: 'call-1', |
| 96 | + chatSessionResource: sessionResource, |
| 97 | + }, CancellationToken.None); |
| 98 | + |
| 99 | + assert.strictEqual(result?.presentation, ToolInvocationPresentation.Hidden); |
| 100 | + }); |
| 101 | + |
| 102 | + test('presentation is undefined when todoList param has items', async () => { |
| 103 | + const tool = createTool(); |
| 104 | + const result = await tool.prepareToolInvocation({ |
| 105 | + parameters: { |
| 106 | + todoList: [{ id: 1, title: 'Task 1', status: 'not-started' }], |
| 107 | + }, |
| 108 | + toolCallId: 'call-1', |
| 109 | + chatSessionResource: sessionResource, |
| 110 | + }, CancellationToken.None); |
| 111 | + |
| 112 | + assert.strictEqual(result?.presentation, undefined); |
| 113 | + }); |
| 114 | + |
| 115 | + test('presentation is Hidden for read operation with no existing todos', async () => { |
| 116 | + const tool = createTool([]); |
| 117 | + const result = await tool.prepareToolInvocation({ |
| 118 | + parameters: { operation: 'read' }, |
| 119 | + toolCallId: 'call-1', |
| 120 | + chatSessionResource: sessionResource, |
| 121 | + }, CancellationToken.None); |
| 122 | + |
| 123 | + assert.strictEqual(result?.presentation, ToolInvocationPresentation.Hidden); |
| 124 | + }); |
| 125 | + |
| 126 | + test('presentation is undefined for read operation with existing todos', async () => { |
| 127 | + const tool = createTool([{ id: 1, title: 'Existing', status: 'in-progress' }]); |
| 128 | + const result = await tool.prepareToolInvocation({ |
| 129 | + parameters: { operation: 'read' }, |
| 130 | + toolCallId: 'call-1', |
| 131 | + chatSessionResource: sessionResource, |
| 132 | + }, CancellationToken.None); |
| 133 | + |
| 134 | + assert.strictEqual(result?.presentation, undefined); |
| 135 | + }); |
| 136 | + |
| 137 | + test('returns undefined when no chatSessionResource is provided', async () => { |
| 138 | + const tool = createTool(); |
| 139 | + const result = await tool.prepareToolInvocation({ |
| 140 | + parameters: { todoList: [{ id: 1, title: 'Task', status: 'not-started' }] }, |
| 141 | + toolCallId: 'call-1', |
| 142 | + chatSessionResource: undefined, |
| 143 | + }, CancellationToken.None); |
| 144 | + |
| 145 | + assert.strictEqual(result, undefined); |
| 146 | + }); |
| 147 | +}); |
0 commit comments