Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/chat/test/common/chatHandoffs.test.ts
13406 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import assert from 'assert';
7
import { constObservable, observableValue } from '../../../../../base/common/observable.js';
8
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
9
import { buildCustomAgentHandoffsInfo, getHandoffId, IChatMode } from '../../common/chatModes.js';
10
import { ChatModeKind } from '../../common/constants.js';
11
import { IHandOff } from '../../common/promptSyntax/promptFileParser.js';
12
import { Target } from '../../common/promptSyntax/promptTypes.js';
13
14
function createMockMode(overrides: Partial<IChatMode> & { id: string; kind: ChatModeKind }): IChatMode {
15
return {
16
name: constObservable(overrides.id),
17
label: constObservable(overrides.id),
18
icon: constObservable(undefined),
19
description: constObservable(undefined),
20
isBuiltin: overrides.isBuiltin ?? false,
21
target: constObservable(Target.Undefined),
22
...overrides,
23
} as IChatMode;
24
}
25
26
suite('getHandoffId', () => {
27
ensureNoDisposablesAreLeakedInTestSuite();
28
29
test('should generate a stable id from agent and label', () => {
30
const handoff: IHandOff = { agent: 'agent', label: 'Start Implementation', prompt: 'go' };
31
assert.strictEqual(getHandoffId(handoff), 'agent:start-implementation');
32
});
33
34
test('should handle special characters in label', () => {
35
const handoff: IHandOff = { agent: 'edit', label: 'Open in Editor!', prompt: '' };
36
assert.strictEqual(getHandoffId(handoff), 'edit:open-in-editor');
37
});
38
39
test('should handle single-word label', () => {
40
const handoff: IHandOff = { agent: 'agent', label: 'Continue', prompt: '' };
41
assert.strictEqual(getHandoffId(handoff), 'agent:continue');
42
});
43
});
44
45
suite('buildCustomAgentHandoffsInfo', () => {
46
ensureNoDisposablesAreLeakedInTestSuite();
47
48
test('should return empty handoffs for modes without handOffs', () => {
49
const mode = createMockMode({
50
id: 'ask',
51
kind: ChatModeKind.Ask,
52
isBuiltin: true,
53
});
54
55
const result = buildCustomAgentHandoffsInfo([mode]);
56
assert.deepStrictEqual(result, [{
57
id: 'ask',
58
name: 'ask',
59
isBuiltin: true,
60
visibility: { userInvocable: true, agentInvocable: true },
61
handoffs: [],
62
}]);
63
});
64
65
test('should map handoffs with all fields', () => {
66
const handoffs: IHandOff[] = [
67
{ agent: 'agent', label: 'Start Implementation', prompt: 'Start implementation', send: true, model: 'gpt-4o' },
68
{ agent: 'agent', label: 'Open in Editor', prompt: 'Open the plan', showContinueOn: false },
69
];
70
const mode = createMockMode({
71
id: 'plan-mode',
72
kind: ChatModeKind.Agent,
73
handOffs: observableValue('handOffs', handoffs),
74
visibility: observableValue('visibility', { userInvocable: true, agentInvocable: false }),
75
});
76
77
const result = buildCustomAgentHandoffsInfo([mode]);
78
assert.deepStrictEqual(result, [{
79
id: 'plan-mode',
80
name: 'plan-mode',
81
isBuiltin: false,
82
visibility: { userInvocable: true, agentInvocable: false },
83
handoffs: [
84
{ id: 'agent:start-implementation', label: 'Start Implementation', agent: 'agent', prompt: 'Start implementation', send: true, model: 'gpt-4o' },
85
{ id: 'agent:open-in-editor', label: 'Open in Editor', agent: 'agent', prompt: 'Open the plan', showContinueOn: false },
86
],
87
}]);
88
});
89
90
test('should handle multiple modes', () => {
91
const askMode = createMockMode({ id: 'ask', kind: ChatModeKind.Ask, isBuiltin: true });
92
const agentMode = createMockMode({ id: 'agent', kind: ChatModeKind.Agent, isBuiltin: true });
93
94
const result = buildCustomAgentHandoffsInfo([askMode, agentMode]);
95
assert.deepStrictEqual(result, [
96
{
97
id: 'ask',
98
name: 'ask',
99
isBuiltin: true,
100
visibility: { userInvocable: true, agentInvocable: true },
101
handoffs: [],
102
},
103
{
104
id: 'agent',
105
name: 'agent',
106
isBuiltin: true,
107
visibility: { userInvocable: true, agentInvocable: true },
108
handoffs: [],
109
},
110
]);
111
});
112
113
test('should omit optional handoff fields when undefined', () => {
114
const handoffs: IHandOff[] = [
115
{ agent: 'agent', label: 'Go', prompt: 'do it' },
116
];
117
const mode = createMockMode({
118
id: 'test',
119
kind: ChatModeKind.Agent,
120
handOffs: observableValue('handOffs', handoffs),
121
});
122
123
const result = buildCustomAgentHandoffsInfo([mode]);
124
const info = result[0].handoffs[0];
125
assert.strictEqual(info.id, 'agent:go');
126
assert.strictEqual(info.send, undefined);
127
assert.strictEqual(info.showContinueOn, undefined);
128
assert.strictEqual(info.model, undefined);
129
});
130
});
131
132