@theia/ai-chat 1.61.0-next.8 → 1.61.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/ai-chat-frontend-contribution.d.ts +11 -0
- package/lib/browser/ai-chat-frontend-contribution.d.ts.map +1 -0
- package/lib/browser/ai-chat-frontend-contribution.js +56 -0
- package/lib/browser/ai-chat-frontend-contribution.js.map +1 -0
- package/lib/browser/ai-chat-frontend-module.d.ts.map +1 -1
- package/lib/browser/ai-chat-frontend-module.js +21 -3
- package/lib/browser/ai-chat-frontend-module.js.map +1 -1
- package/lib/browser/change-set-decorator-service.d.ts +24 -0
- package/lib/browser/change-set-decorator-service.d.ts.map +1 -0
- package/lib/browser/change-set-decorator-service.js +66 -0
- package/lib/browser/change-set-decorator-service.js.map +1 -0
- package/lib/browser/change-set-file-element.d.ts +7 -4
- package/lib/browser/change-set-file-element.d.ts.map +1 -1
- package/lib/browser/change-set-file-element.js +20 -12
- package/lib/browser/change-set-file-element.js.map +1 -1
- package/lib/browser/change-set-file-resource.d.ts +1 -42
- package/lib/browser/change-set-file-resource.d.ts.map +1 -1
- package/lib/browser/change-set-file-resource.js +1 -136
- package/lib/browser/change-set-file-resource.js.map +1 -1
- package/lib/browser/change-set-variable.d.ts.map +1 -1
- package/lib/browser/change-set-variable.js +13 -4
- package/lib/browser/change-set-variable.js.map +1 -1
- package/lib/browser/context-file-variable-label-provider.js +1 -1
- package/lib/browser/context-file-variable-label-provider.js.map +1 -1
- package/lib/browser/file-chat-variable-contribution.d.ts.map +1 -1
- package/lib/browser/file-chat-variable-contribution.js +29 -27
- package/lib/browser/file-chat-variable-contribution.js.map +1 -1
- package/lib/browser/task-context-service.d.ts +40 -0
- package/lib/browser/task-context-service.d.ts.map +1 -0
- package/lib/browser/task-context-service.js +148 -0
- package/lib/browser/task-context-service.js.map +1 -0
- package/lib/browser/task-context-storage-service.d.ts +18 -0
- package/lib/browser/task-context-storage-service.d.ts.map +1 -0
- package/lib/browser/task-context-storage-service.js +77 -0
- package/lib/browser/task-context-storage-service.js.map +1 -0
- package/lib/browser/task-context-variable-contribution.d.ts +20 -0
- package/lib/browser/task-context-variable-contribution.d.ts.map +1 -0
- package/lib/browser/task-context-variable-contribution.js +101 -0
- package/lib/browser/task-context-variable-contribution.js.map +1 -0
- package/lib/browser/task-context-variable-label-provider.d.ts +21 -0
- package/lib/browser/task-context-variable-label-provider.d.ts.map +1 -0
- package/lib/browser/task-context-variable-label-provider.js +83 -0
- package/lib/browser/task-context-variable-label-provider.js.map +1 -0
- package/lib/browser/task-context-variable.d.ts +3 -0
- package/lib/browser/task-context-variable.d.ts.map +1 -0
- package/lib/browser/task-context-variable.js +29 -0
- package/lib/browser/task-context-variable.js.map +1 -0
- package/lib/common/chat-agents.d.ts +2 -1
- package/lib/common/chat-agents.d.ts.map +1 -1
- package/lib/common/chat-agents.js +5 -0
- package/lib/common/chat-agents.js.map +1 -1
- package/lib/common/chat-model.d.ts +173 -8
- package/lib/common/chat-model.d.ts.map +1 -1
- package/lib/common/chat-model.js +329 -17
- package/lib/common/chat-model.js.map +1 -1
- package/lib/common/chat-request-parser.d.ts +1 -1
- package/lib/common/chat-request-parser.d.ts.map +1 -1
- package/lib/common/chat-request-parser.js +1 -1
- package/lib/common/chat-request-parser.js.map +1 -1
- package/lib/common/chat-service.d.ts +2 -0
- package/lib/common/chat-service.d.ts.map +1 -1
- package/lib/common/chat-service.js +18 -25
- package/lib/common/chat-service.js.map +1 -1
- package/lib/common/chat-session-naming-service.d.ts.map +1 -1
- package/lib/common/chat-session-naming-service.js +3 -3
- package/lib/common/chat-session-naming-service.js.map +1 -1
- package/lib/common/chat-session-summary-agent-prompt.d.ts +5 -0
- package/lib/common/chat-session-summary-agent-prompt.d.ts.map +1 -0
- package/lib/common/chat-session-summary-agent-prompt.js +30 -0
- package/lib/common/chat-session-summary-agent-prompt.js.map +1 -0
- package/lib/common/chat-session-summary-agent.d.ts +17 -0
- package/lib/common/chat-session-summary-agent.d.ts.map +1 -0
- package/lib/common/chat-session-summary-agent.js +48 -0
- package/lib/common/chat-session-summary-agent.js.map +1 -0
- package/lib/common/context-summary-variable.js +1 -1
- package/lib/common/context-summary-variable.js.map +1 -1
- package/package.json +11 -11
- package/src/browser/ai-chat-frontend-contribution.ts +49 -0
- package/src/browser/ai-chat-frontend-module.ts +25 -4
- package/src/browser/change-set-decorator-service.ts +72 -0
- package/src/browser/change-set-file-element.ts +18 -13
- package/src/browser/change-set-file-resource.ts +1 -138
- package/src/browser/change-set-variable.ts +14 -6
- package/src/browser/context-file-variable-label-provider.ts +1 -1
- package/src/browser/file-chat-variable-contribution.ts +26 -29
- package/src/browser/task-context-service.ts +144 -0
- package/src/browser/task-context-storage-service.ts +75 -0
- package/src/browser/task-context-variable-contribution.ts +93 -0
- package/src/browser/task-context-variable-label-provider.ts +67 -0
- package/src/browser/task-context-variable.ts +28 -0
- package/src/common/chat-agents.ts +6 -1
- package/src/common/chat-model.ts +507 -18
- package/src/common/chat-request-parser.ts +2 -2
- package/src/common/chat-service.ts +17 -26
- package/src/common/chat-session-naming-service.ts +4 -3
- package/src/common/chat-session-summary-agent-prompt.ts +28 -0
- package/src/common/chat-session-summary-agent.ts +42 -0
- package/src/common/context-summary-variable.ts +1 -1
package/src/common/chat-model.ts
CHANGED
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
*--------------------------------------------------------------------------------------------*/
|
|
20
20
|
// Partially copied from https://github.com/microsoft/vscode/blob/a2cab7255c0df424027be05d58e1b7b941f4ea60/src/vs/workbench/contrib/chat/common/chatModel.ts
|
|
21
21
|
|
|
22
|
-
import {
|
|
22
|
+
import { AIVariableResolutionRequest, LanguageModelMessage, ResolvedAIContextVariable, TextMessage, ThinkingMessage, ToolResultMessage, ToolUseMessage } from '@theia/ai-core';
|
|
23
|
+
import { CancellationToken, CancellationTokenSource, Command, Disposable, DisposableCollection, Emitter, Event, generateUuid, URI } from '@theia/core';
|
|
23
24
|
import { MarkdownString, MarkdownStringImpl } from '@theia/core/lib/common/markdown-rendering';
|
|
24
25
|
import { Position } from '@theia/core/shared/vscode-languageserver-protocol';
|
|
25
26
|
import { ChatAgentLocation } from './chat-agents';
|
|
26
27
|
import { ParsedChatRequest } from './parsed-chat-request';
|
|
27
|
-
import { AIVariableResolutionRequest, LanguageModelMessage, ResolvedAIContextVariable, TextMessage, ThinkingMessage, ToolResultMessage, ToolUseMessage } from '@theia/ai-core';
|
|
28
28
|
|
|
29
29
|
/**********************
|
|
30
30
|
* INTERFACES AND TYPE GUARDS
|
|
@@ -35,16 +35,46 @@ export type ChatChangeEvent =
|
|
|
35
35
|
| ChatAddResponseEvent
|
|
36
36
|
| ChatAddVariableEvent
|
|
37
37
|
| ChatRemoveVariableEvent
|
|
38
|
+
| ChatSetVariablesEvent
|
|
38
39
|
| ChatRemoveRequestEvent
|
|
39
40
|
| ChatSetChangeSetEvent
|
|
41
|
+
| ChatSuggestionsChangedEvent
|
|
40
42
|
| ChatUpdateChangeSetEvent
|
|
41
|
-
| ChatRemoveChangeSetEvent
|
|
43
|
+
| ChatRemoveChangeSetEvent
|
|
44
|
+
| ChatEditRequestEvent
|
|
45
|
+
| ChatEditCancelEvent
|
|
46
|
+
| ChatEditSubmitEvent
|
|
47
|
+
| ChatChangeHierarchyBranchEvent;
|
|
42
48
|
|
|
43
49
|
export interface ChatAddRequestEvent {
|
|
44
50
|
kind: 'addRequest';
|
|
45
51
|
request: ChatRequestModel;
|
|
46
52
|
}
|
|
47
53
|
|
|
54
|
+
export interface ChatEditRequestEvent {
|
|
55
|
+
kind: 'enableEdit';
|
|
56
|
+
request: EditableChatRequestModel;
|
|
57
|
+
branch: ChatHierarchyBranch<ChatRequestModel>;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface ChatEditCancelEvent {
|
|
61
|
+
kind: 'cancelEdit';
|
|
62
|
+
request: EditableChatRequestModel;
|
|
63
|
+
branch: ChatHierarchyBranch<ChatRequestModel>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface ChatEditSubmitEvent {
|
|
67
|
+
kind: 'submitEdit';
|
|
68
|
+
request: EditableChatRequestModel;
|
|
69
|
+
branch: ChatHierarchyBranch<ChatRequestModel>;
|
|
70
|
+
newRequest: ChatRequest;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface ChatChangeHierarchyBranchEvent {
|
|
74
|
+
kind: 'changeHierarchyBranch';
|
|
75
|
+
branch: ChatHierarchyBranch<ChatRequestModel>;
|
|
76
|
+
}
|
|
77
|
+
|
|
48
78
|
export interface ChatAddResponseEvent {
|
|
49
79
|
kind: 'addResponse';
|
|
50
80
|
response: ChatResponseModel;
|
|
@@ -74,6 +104,15 @@ export interface ChatRemoveVariableEvent {
|
|
|
74
104
|
kind: 'removeVariable';
|
|
75
105
|
}
|
|
76
106
|
|
|
107
|
+
export interface ChatSetVariablesEvent {
|
|
108
|
+
kind: 'setVariables';
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface ChatSuggestionsChangedEvent {
|
|
112
|
+
kind: 'suggestionsChanged';
|
|
113
|
+
suggestions: ChatSuggestion[];
|
|
114
|
+
}
|
|
115
|
+
|
|
77
116
|
export namespace ChatChangeEvent {
|
|
78
117
|
export function isChangeSetEvent(event: ChatChangeEvent): event is ChatSetChangeSetEvent | ChatUpdateChangeSetEvent | ChatRemoveChangeSetEvent {
|
|
79
118
|
return event.kind === 'setChangeSet' || event.kind === 'removeChangeSet' || event.kind === 'updateChangeSet';
|
|
@@ -89,14 +128,76 @@ export interface ChatRemoveRequestEvent {
|
|
|
89
128
|
reason: ChatRequestRemovalReason;
|
|
90
129
|
}
|
|
91
130
|
|
|
131
|
+
/**
|
|
132
|
+
* A model that contains information about a chat request that may branch off.
|
|
133
|
+
*
|
|
134
|
+
* The hierarchy of requests is represented by a tree structure.
|
|
135
|
+
* - The root of the tree is the initial request
|
|
136
|
+
* - Within each branch, the requests are stored in a list. Those requests are the alternatives to the original request.
|
|
137
|
+
* Each of those items can have a next branch, which is the next request in the hierarchy.
|
|
138
|
+
*/
|
|
139
|
+
export interface ChatRequestHierarchy<TRequest extends ChatRequestModel = ChatRequestModel> {
|
|
140
|
+
readonly branch: ChatHierarchyBranch<TRequest>
|
|
141
|
+
|
|
142
|
+
onDidChange: Event<ChangeActiveBranchEvent<TRequest>>;
|
|
143
|
+
|
|
144
|
+
append(request: TRequest): ChatHierarchyBranch<TRequest>;
|
|
145
|
+
activeRequests(): TRequest[];
|
|
146
|
+
activeBranches(): ChatHierarchyBranch<TRequest>[];
|
|
147
|
+
findRequest(requestId: string): TRequest | undefined;
|
|
148
|
+
findBranch(requestId: string): ChatHierarchyBranch<TRequest> | undefined;
|
|
149
|
+
|
|
150
|
+
notifyChange(event: ChangeActiveBranchEvent<TRequest>): void
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export interface ChangeActiveBranchEvent<TRequest extends ChatRequestModel = ChatRequestModel> {
|
|
154
|
+
branch: ChatHierarchyBranch<TRequest>,
|
|
155
|
+
item: ChatHierarchyBranchItem<TRequest>
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* A branch of the chat request hierarchy.
|
|
160
|
+
* It contains a list of items, each representing a request.
|
|
161
|
+
* Those items can have a next branch, which is the next request in the hierarchy.
|
|
162
|
+
*/
|
|
163
|
+
export interface ChatHierarchyBranch<TRequest extends ChatRequestModel = ChatRequestModel> {
|
|
164
|
+
readonly id: string;
|
|
165
|
+
readonly hierarchy: ChatRequestHierarchy<TRequest>;
|
|
166
|
+
readonly previous?: ChatHierarchyBranch<TRequest>;
|
|
167
|
+
readonly items: ChatHierarchyBranchItem<TRequest>[];
|
|
168
|
+
readonly activeBranchIndex: number;
|
|
169
|
+
|
|
170
|
+
next(): ChatHierarchyBranch<TRequest> | undefined;
|
|
171
|
+
get(): TRequest;
|
|
172
|
+
add(request: TRequest): void;
|
|
173
|
+
remove(request: TRequest | string): void;
|
|
174
|
+
/**
|
|
175
|
+
* Create a new branch by inserting it as the next branch of the active item.
|
|
176
|
+
*/
|
|
177
|
+
continue(request: TRequest): ChatHierarchyBranch<TRequest>;
|
|
178
|
+
|
|
179
|
+
enable(request: TRequest): ChatHierarchyBranchItem<TRequest>;
|
|
180
|
+
enablePrevious(): ChatHierarchyBranchItem<TRequest>;
|
|
181
|
+
enableNext(): ChatHierarchyBranchItem<TRequest>;
|
|
182
|
+
|
|
183
|
+
succeedingBranches(): ChatHierarchyBranch<TRequest>[];
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export interface ChatHierarchyBranchItem<TRequest extends ChatRequestModel = ChatRequestModel> {
|
|
187
|
+
readonly element: TRequest;
|
|
188
|
+
readonly next?: ChatHierarchyBranch<TRequest>;
|
|
189
|
+
}
|
|
190
|
+
|
|
92
191
|
export interface ChatModel {
|
|
93
192
|
readonly onDidChange: Event<ChatChangeEvent>;
|
|
94
193
|
readonly id: string;
|
|
95
194
|
readonly location: ChatAgentLocation;
|
|
96
195
|
readonly changeSet?: ChangeSet;
|
|
97
196
|
readonly context: ChatContextManager;
|
|
197
|
+
readonly suggestions: readonly ChatSuggestion[];
|
|
98
198
|
readonly settings?: { [key: string]: unknown };
|
|
99
199
|
getRequests(): ChatRequestModel[];
|
|
200
|
+
getBranches(): ChatHierarchyBranch<ChatRequestModel>[];
|
|
100
201
|
isEmpty(): boolean;
|
|
101
202
|
}
|
|
102
203
|
|
|
@@ -107,8 +208,26 @@ export interface ChangeSet extends Disposable {
|
|
|
107
208
|
dispose(): void;
|
|
108
209
|
}
|
|
109
210
|
|
|
211
|
+
export interface ChatSuggestionCallback {
|
|
212
|
+
kind: 'callback',
|
|
213
|
+
callback: () => unknown;
|
|
214
|
+
content: string | MarkdownString;
|
|
215
|
+
}
|
|
216
|
+
export namespace ChatSuggestionCallback {
|
|
217
|
+
export function is(candidate: ChatSuggestion): candidate is ChatSuggestionCallback {
|
|
218
|
+
return typeof candidate === 'object' && 'callback' in candidate;
|
|
219
|
+
}
|
|
220
|
+
export function containsCallbackLink(candidate: ChatSuggestion): candidate is ChatSuggestionCallback {
|
|
221
|
+
if (!is(candidate)) { return false; }
|
|
222
|
+
const text = typeof candidate.content === 'string' ? candidate.content : candidate.content.value;
|
|
223
|
+
return text.includes('](_callback)');
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export type ChatSuggestion = | string | MarkdownString | ChatSuggestionCallback;
|
|
228
|
+
|
|
110
229
|
export interface ChatContextManager {
|
|
111
|
-
onDidChange: Event<ChatAddVariableEvent | ChatRemoveVariableEvent>;
|
|
230
|
+
onDidChange: Event<ChatAddVariableEvent | ChatRemoveVariableEvent | ChatSetVariablesEvent>;
|
|
112
231
|
getVariables(): readonly AIVariableResolutionRequest[]
|
|
113
232
|
addVariables(...variables: AIVariableResolutionRequest[]): void;
|
|
114
233
|
deleteVariables(...indices: number[]): void;
|
|
@@ -134,9 +253,21 @@ export interface ChangeSetElement {
|
|
|
134
253
|
dispose?(): void;
|
|
135
254
|
}
|
|
136
255
|
|
|
256
|
+
export interface ChangeSetDecoration {
|
|
257
|
+
readonly priority?: number;
|
|
258
|
+
readonly additionalInfoSuffixIcon?: string[];
|
|
259
|
+
}
|
|
260
|
+
|
|
137
261
|
export interface ChatRequest {
|
|
138
262
|
readonly text: string;
|
|
139
263
|
readonly displayText?: string;
|
|
264
|
+
/**
|
|
265
|
+
* If the request has been triggered in the context of
|
|
266
|
+
* an existing request, this id will be set to the id of the
|
|
267
|
+
* referenced request.
|
|
268
|
+
*/
|
|
269
|
+
readonly referencedRequestId?: string;
|
|
270
|
+
readonly variables?: readonly AIVariableResolutionRequest[];
|
|
140
271
|
}
|
|
141
272
|
|
|
142
273
|
export interface ChatContext {
|
|
@@ -180,6 +311,29 @@ export namespace ChatRequestModel {
|
|
|
180
311
|
}
|
|
181
312
|
}
|
|
182
313
|
|
|
314
|
+
export interface EditableChatRequestModel extends ChatRequestModel {
|
|
315
|
+
readonly isEditing: boolean;
|
|
316
|
+
editContextManager: ChatContextManagerImpl;
|
|
317
|
+
enableEdit(): void;
|
|
318
|
+
cancelEdit(): void;
|
|
319
|
+
submitEdit(newRequest: ChatRequest): void;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
export namespace EditableChatRequestModel {
|
|
323
|
+
export function is(request: unknown): request is EditableChatRequestModel {
|
|
324
|
+
return !!(
|
|
325
|
+
ChatRequestModel.is(request) &&
|
|
326
|
+
'enableEdit' in request &&
|
|
327
|
+
'cancelEdit' in request &&
|
|
328
|
+
'submitEdit' in request
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export function isEditing(request: unknown): request is EditableChatRequestModel {
|
|
333
|
+
return is(request) && request.isEditing;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
183
337
|
export interface ChatProgressMessage {
|
|
184
338
|
kind: 'progressMessage';
|
|
185
339
|
id: string;
|
|
@@ -536,25 +690,44 @@ export class MutableChatModel implements ChatModel, Disposable {
|
|
|
536
690
|
protected readonly _onDidChangeEmitter = new Emitter<ChatChangeEvent>();
|
|
537
691
|
onDidChange: Event<ChatChangeEvent> = this._onDidChangeEmitter.event;
|
|
538
692
|
|
|
539
|
-
protected
|
|
693
|
+
protected readonly toDispose = new DisposableCollection();
|
|
694
|
+
|
|
695
|
+
protected _hierarchy: ChatRequestHierarchy<MutableChatRequestModel>;
|
|
540
696
|
protected _id: string;
|
|
541
697
|
protected _changeSet?: ChangeSetImpl;
|
|
698
|
+
protected _suggestions: readonly ChatSuggestion[] = [];
|
|
542
699
|
protected readonly _contextManager = new ChatContextManagerImpl();
|
|
543
700
|
protected _settings: { [key: string]: unknown };
|
|
544
701
|
|
|
545
702
|
constructor(public readonly location = ChatAgentLocation.Panel) {
|
|
546
703
|
// TODO accept serialized data as a parameter to restore a previously saved ChatModel
|
|
547
|
-
this.
|
|
704
|
+
this._hierarchy = new ChatRequestHierarchyImpl<MutableChatRequestModel>();
|
|
548
705
|
this._id = generateUuid();
|
|
549
|
-
|
|
706
|
+
|
|
707
|
+
this.toDispose.pushAll([
|
|
708
|
+
this._onDidChangeEmitter,
|
|
709
|
+
this._contextManager.onDidChange(e => this._onDidChangeEmitter.fire(e)),
|
|
710
|
+
this._hierarchy.onDidChange(event => this._onDidChangeEmitter.fire({
|
|
711
|
+
kind: 'changeHierarchyBranch',
|
|
712
|
+
branch: event.branch,
|
|
713
|
+
})),
|
|
714
|
+
]);
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
getBranches(): ChatHierarchyBranch<ChatRequestModel>[] {
|
|
718
|
+
return this._hierarchy.activeBranches();
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
getBranch(requestId: string): ChatHierarchyBranch<ChatRequestModel> | undefined {
|
|
722
|
+
return this._hierarchy.findBranch(requestId);
|
|
550
723
|
}
|
|
551
724
|
|
|
552
725
|
getRequests(): MutableChatRequestModel[] {
|
|
553
|
-
return this.
|
|
726
|
+
return this._hierarchy.activeRequests();
|
|
554
727
|
}
|
|
555
728
|
|
|
556
729
|
getRequest(id: string): MutableChatRequestModel | undefined {
|
|
557
|
-
return this.
|
|
730
|
+
return this.getRequests().find(request => request.id === id);
|
|
558
731
|
}
|
|
559
732
|
|
|
560
733
|
get id(): string {
|
|
@@ -565,6 +738,10 @@ export class MutableChatModel implements ChatModel, Disposable {
|
|
|
565
738
|
return this._changeSet;
|
|
566
739
|
}
|
|
567
740
|
|
|
741
|
+
get suggestions(): readonly ChatSuggestion[] {
|
|
742
|
+
return this._suggestions;
|
|
743
|
+
}
|
|
744
|
+
|
|
568
745
|
get context(): ChatContextManager {
|
|
569
746
|
return this._contextManager;
|
|
570
747
|
}
|
|
@@ -610,8 +787,13 @@ export class MutableChatModel implements ChatModel, Disposable {
|
|
|
610
787
|
}
|
|
611
788
|
|
|
612
789
|
addRequest(parsedChatRequest: ParsedChatRequest, agentId?: string, context: ChatContext = { variables: [] }): MutableChatRequestModel {
|
|
790
|
+
if (parsedChatRequest.request.referencedRequestId) {
|
|
791
|
+
return this.applyEdit(parsedChatRequest, agentId, context);
|
|
792
|
+
}
|
|
793
|
+
|
|
613
794
|
const requestModel = new MutableChatRequestModel(this, parsedChatRequest, agentId, context);
|
|
614
|
-
this.
|
|
795
|
+
this.toDispose.push(requestModel);
|
|
796
|
+
this._hierarchy.append(requestModel);
|
|
615
797
|
this._onDidChangeEmitter.fire({
|
|
616
798
|
kind: 'addRequest',
|
|
617
799
|
request: requestModel,
|
|
@@ -619,13 +801,217 @@ export class MutableChatModel implements ChatModel, Disposable {
|
|
|
619
801
|
return requestModel;
|
|
620
802
|
}
|
|
621
803
|
|
|
804
|
+
setSuggestions(suggestions: ChatSuggestion[]): void {
|
|
805
|
+
this._suggestions = Object.freeze(suggestions);
|
|
806
|
+
this._onDidChangeEmitter.fire({
|
|
807
|
+
kind: 'suggestionsChanged',
|
|
808
|
+
suggestions
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
|
|
622
812
|
isEmpty(): boolean {
|
|
623
|
-
return this.
|
|
813
|
+
return this.getRequests().length === 0;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
applyEdit(parsedChatRequest: ParsedChatRequest, agentId?: string, context: ChatContext = { variables: [] }): MutableChatRequestModel {
|
|
817
|
+
const requestId = parsedChatRequest.request.referencedRequestId!;
|
|
818
|
+
const branch = this._hierarchy.findBranch(requestId);
|
|
819
|
+
if (!branch) {
|
|
820
|
+
throw new Error(`Cannot find branch for requestId: ${requestId}`);
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
const requestModel = new MutableChatRequestModel(this, parsedChatRequest, agentId, context);
|
|
824
|
+
this.toDispose.push(requestModel);
|
|
825
|
+
branch.add(requestModel);
|
|
826
|
+
this.removeChangeSet();
|
|
827
|
+
|
|
828
|
+
this._onDidChangeEmitter.fire({
|
|
829
|
+
kind: 'addRequest',
|
|
830
|
+
request: requestModel,
|
|
831
|
+
});
|
|
832
|
+
|
|
833
|
+
return requestModel;
|
|
624
834
|
}
|
|
625
835
|
|
|
626
836
|
dispose(): void {
|
|
627
837
|
this.removeChangeSet(); // Signal disposal of last change set.
|
|
628
|
-
this.
|
|
838
|
+
this.toDispose.dispose();
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
emit(event: ChatChangeEvent): void {
|
|
842
|
+
this._onDidChangeEmitter.fire(event);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
export class ChatRequestHierarchyImpl<TRequest extends ChatRequestModel = ChatRequestModel> implements ChatRequestHierarchy<TRequest> {
|
|
847
|
+
protected readonly onDidChangeActiveBranchEmitter = new Emitter<ChangeActiveBranchEvent<TRequest>>();
|
|
848
|
+
readonly onDidChange = this.onDidChangeActiveBranchEmitter.event;
|
|
849
|
+
|
|
850
|
+
readonly branch: ChatHierarchyBranch<TRequest> = new ChatRequestHierarchyBranchImpl<TRequest>(this);
|
|
851
|
+
|
|
852
|
+
append(request: TRequest): ChatHierarchyBranch<TRequest> {
|
|
853
|
+
const branches = this.activeBranches();
|
|
854
|
+
|
|
855
|
+
if (branches.length === 0) {
|
|
856
|
+
this.branch.add(request);
|
|
857
|
+
return this.branch;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
return branches.at(-1)!.continue(request);
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
activeRequests(): TRequest[] {
|
|
864
|
+
return this.activeBranches().map(h => h.get());
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
activeBranches(): ChatHierarchyBranch<TRequest>[] {
|
|
868
|
+
return Array.from(this.iterateBranches());
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
protected *iterateBranches(): Generator<ChatHierarchyBranch<TRequest>> {
|
|
872
|
+
let current: ChatHierarchyBranch<TRequest> | undefined = this.branch;
|
|
873
|
+
while (current) {
|
|
874
|
+
if (current.items.length > 0) {
|
|
875
|
+
yield current;
|
|
876
|
+
current = current.next();
|
|
877
|
+
} else {
|
|
878
|
+
break;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
findRequest(requestId: string): TRequest | undefined {
|
|
884
|
+
const branch = this.findInBranch(this.branch, requestId);
|
|
885
|
+
return branch?.items.find(item => item.element.id === requestId)?.element;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
findBranch(requestId: string): ChatHierarchyBranch<TRequest> | undefined {
|
|
889
|
+
return this.findInBranch(this.branch, requestId);
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
protected findInBranch(branch: ChatHierarchyBranch<TRequest>, requestId: string): ChatHierarchyBranch<TRequest> | undefined {
|
|
893
|
+
for (const item of branch.items) {
|
|
894
|
+
if (item.element.id === requestId) {
|
|
895
|
+
return branch;
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
for (const item of branch.items) {
|
|
899
|
+
if (item.next) {
|
|
900
|
+
const found = this.findInBranch(item.next, requestId);
|
|
901
|
+
if (found) {
|
|
902
|
+
return found;
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
return undefined;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
notifyChange(event: ChangeActiveBranchEvent<TRequest>): void {
|
|
910
|
+
this.onDidChangeActiveBranchEmitter.fire(event);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
export class ChatRequestHierarchyBranchImpl<TRequest extends ChatRequestModel> implements ChatHierarchyBranch<TRequest> {
|
|
915
|
+
readonly id = generateUuid();
|
|
916
|
+
|
|
917
|
+
constructor(
|
|
918
|
+
readonly hierarchy: ChatRequestHierarchy<TRequest>,
|
|
919
|
+
readonly previous?: ChatHierarchyBranch<TRequest>,
|
|
920
|
+
readonly items: ChatHierarchyBranchItem<TRequest>[] = [],
|
|
921
|
+
protected _activeIndex = -1
|
|
922
|
+
) { }
|
|
923
|
+
|
|
924
|
+
get activeBranchIndex(): number {
|
|
925
|
+
return this._activeIndex;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
protected set activeBranchIndex(value: number) {
|
|
929
|
+
this._activeIndex = value;
|
|
930
|
+
this.hierarchy.notifyChange({
|
|
931
|
+
branch: this,
|
|
932
|
+
item: this.items[this._activeIndex]
|
|
933
|
+
});
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
next(): ChatHierarchyBranch<TRequest> | undefined {
|
|
937
|
+
return this.items[this.activeBranchIndex]?.next;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
get(): TRequest {
|
|
941
|
+
return this.items[this.activeBranchIndex].element;
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
add(request: TRequest): void {
|
|
945
|
+
const branch: ChatHierarchyBranchItem<TRequest> = {
|
|
946
|
+
element: request
|
|
947
|
+
};
|
|
948
|
+
this.items.push(branch);
|
|
949
|
+
this.activeBranchIndex = this.items.length - 1;
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
remove(request: TRequest | string): void {
|
|
953
|
+
const requestId = typeof request === 'string' ? request : request.id;
|
|
954
|
+
const index = this.items.findIndex(version => version.element.id === requestId);
|
|
955
|
+
if (index !== -1) {
|
|
956
|
+
this.items.splice(index, 1);
|
|
957
|
+
if (this.activeBranchIndex >= index) {
|
|
958
|
+
this.activeBranchIndex--;
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
continue(request: TRequest): ChatHierarchyBranch<TRequest> {
|
|
964
|
+
if (this.items.length === 0) {
|
|
965
|
+
this.add(request);
|
|
966
|
+
return this;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
const item = this.items[this.activeBranchIndex];
|
|
970
|
+
|
|
971
|
+
if (item) {
|
|
972
|
+
const next = new ChatRequestHierarchyBranchImpl(this.hierarchy, this, [{ element: request }], 0);
|
|
973
|
+
this.items[this.activeBranchIndex] = {
|
|
974
|
+
...item,
|
|
975
|
+
next
|
|
976
|
+
};
|
|
977
|
+
return next;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
throw new Error(`No current branch to continue from. Active Index: ${this.activeBranchIndex}`);
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
enable(request: TRequest): ChatHierarchyBranchItem<TRequest> {
|
|
984
|
+
this.activeBranchIndex = this.items.findIndex(pred => pred.element.id === request.id);
|
|
985
|
+
return this.items[this.activeBranchIndex];
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
enablePrevious(): ChatHierarchyBranchItem<TRequest> {
|
|
989
|
+
if (this.activeBranchIndex > 0) {
|
|
990
|
+
this.activeBranchIndex--;
|
|
991
|
+
return this.items[this.activeBranchIndex];
|
|
992
|
+
}
|
|
993
|
+
return this.items[0];
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
enableNext(): ChatHierarchyBranchItem<TRequest> {
|
|
997
|
+
if (this.activeBranchIndex < this.items.length - 1) {
|
|
998
|
+
this.activeBranchIndex++;
|
|
999
|
+
return this.items[this.activeBranchIndex];
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
return this.items[this.activeBranchIndex];
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
succeedingBranches(): ChatHierarchyBranch<TRequest>[] {
|
|
1006
|
+
const branches: ChatHierarchyBranch<TRequest>[] = [];
|
|
1007
|
+
|
|
1008
|
+
let current: ChatHierarchyBranch<TRequest> | undefined = this;
|
|
1009
|
+
while (current !== undefined) {
|
|
1010
|
+
branches.push(current);
|
|
1011
|
+
current = current.next();
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
return branches;
|
|
629
1015
|
}
|
|
630
1016
|
}
|
|
631
1017
|
|
|
@@ -693,11 +1079,17 @@ export class ChangeSetImpl implements ChangeSet {
|
|
|
693
1079
|
|
|
694
1080
|
export class ChatContextManagerImpl implements ChatContextManager {
|
|
695
1081
|
protected readonly variables = new Array<AIVariableResolutionRequest>();
|
|
696
|
-
protected readonly onDidChangeEmitter = new Emitter<ChatAddVariableEvent | ChatRemoveVariableEvent>();
|
|
697
|
-
get onDidChange(): Event<ChatAddVariableEvent | ChatRemoveVariableEvent> {
|
|
1082
|
+
protected readonly onDidChangeEmitter = new Emitter<ChatAddVariableEvent | ChatRemoveVariableEvent | ChatSetVariablesEvent>();
|
|
1083
|
+
get onDidChange(): Event<ChatAddVariableEvent | ChatRemoveVariableEvent | ChatSetVariablesEvent> {
|
|
698
1084
|
return this.onDidChangeEmitter.event;
|
|
699
1085
|
}
|
|
700
1086
|
|
|
1087
|
+
constructor(context?: ChatContext) {
|
|
1088
|
+
if (context) {
|
|
1089
|
+
this.variables.push(...context.variables.map(AIVariableResolutionRequest.fromResolved));
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
|
|
701
1093
|
getVariables(): readonly AIVariableResolutionRequest[] {
|
|
702
1094
|
const result = this.variables.slice();
|
|
703
1095
|
Object.freeze(result);
|
|
@@ -728,6 +1120,17 @@ export class ChatContextManagerImpl implements ChatContextManager {
|
|
|
728
1120
|
}
|
|
729
1121
|
}
|
|
730
1122
|
|
|
1123
|
+
setVariables(variables: AIVariableResolutionRequest[]): void {
|
|
1124
|
+
this.variables.length = 0;
|
|
1125
|
+
variables.forEach(variable => {
|
|
1126
|
+
if (this.variables.some(existing => existing.variable.id === variable.variable.id && existing.arg === variable.arg)) {
|
|
1127
|
+
return;
|
|
1128
|
+
}
|
|
1129
|
+
this.variables.push(variable);
|
|
1130
|
+
});
|
|
1131
|
+
this.onDidChangeEmitter.fire({ kind: 'setVariables' });
|
|
1132
|
+
}
|
|
1133
|
+
|
|
731
1134
|
clear(): void {
|
|
732
1135
|
if (this.variables.length) {
|
|
733
1136
|
this.variables.length = 0;
|
|
@@ -736,7 +1139,7 @@ export class ChatContextManagerImpl implements ChatContextManager {
|
|
|
736
1139
|
}
|
|
737
1140
|
}
|
|
738
1141
|
|
|
739
|
-
export class MutableChatRequestModel implements ChatRequestModel {
|
|
1142
|
+
export class MutableChatRequestModel implements ChatRequestModel, EditableChatRequestModel, Disposable {
|
|
740
1143
|
protected readonly _id: string;
|
|
741
1144
|
protected _session: MutableChatModel;
|
|
742
1145
|
protected _request: ChatRequest;
|
|
@@ -744,6 +1147,10 @@ export class MutableChatRequestModel implements ChatRequestModel {
|
|
|
744
1147
|
protected _context: ChatContext;
|
|
745
1148
|
protected _agentId?: string;
|
|
746
1149
|
protected _data: { [key: string]: unknown };
|
|
1150
|
+
protected _isEditing = false;
|
|
1151
|
+
|
|
1152
|
+
protected readonly toDispose = new DisposableCollection();
|
|
1153
|
+
readonly editContextManager: ChatContextManagerImpl;
|
|
747
1154
|
|
|
748
1155
|
constructor(session: MutableChatModel, public readonly message: ParsedChatRequest, agentId?: string,
|
|
749
1156
|
context: ChatContext = { variables: [] }, data: { [key: string]: unknown } = {}) {
|
|
@@ -755,6 +1162,20 @@ export class MutableChatRequestModel implements ChatRequestModel {
|
|
|
755
1162
|
this._context = context;
|
|
756
1163
|
this._agentId = agentId;
|
|
757
1164
|
this._data = data;
|
|
1165
|
+
|
|
1166
|
+
this.editContextManager = new ChatContextManagerImpl(context);
|
|
1167
|
+
this.toDispose.pushAll([
|
|
1168
|
+
this.editContextManager.onDidChange(e => this.session.emit(e))
|
|
1169
|
+
]);
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
get isEditing(): boolean {
|
|
1173
|
+
return this._isEditing;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
enableEdit(): void {
|
|
1177
|
+
this._isEditing = true;
|
|
1178
|
+
this.emitEditRequest(this);
|
|
758
1179
|
}
|
|
759
1180
|
|
|
760
1181
|
get data(): { [key: string]: unknown } | undefined {
|
|
@@ -793,9 +1214,78 @@ export class MutableChatRequestModel implements ChatRequestModel {
|
|
|
793
1214
|
return this._agentId;
|
|
794
1215
|
}
|
|
795
1216
|
|
|
1217
|
+
cancelEdit(): void {
|
|
1218
|
+
if (this.isEditing) {
|
|
1219
|
+
this._isEditing = false;
|
|
1220
|
+
this.emitCancelEdit(this);
|
|
1221
|
+
|
|
1222
|
+
this.clearEditContext();
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
submitEdit(newRequest: ChatRequest): void {
|
|
1227
|
+
if (this.isEditing) {
|
|
1228
|
+
this._isEditing = false;
|
|
1229
|
+
const variables = this.editContextManager.getVariables() ?? [];
|
|
1230
|
+
|
|
1231
|
+
this.emitSubmitEdit(this, {
|
|
1232
|
+
...newRequest,
|
|
1233
|
+
referencedRequestId: this.id,
|
|
1234
|
+
variables
|
|
1235
|
+
});
|
|
1236
|
+
|
|
1237
|
+
this.clearEditContext();
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
|
|
796
1241
|
cancel(): void {
|
|
797
1242
|
this.response.cancel();
|
|
798
1243
|
}
|
|
1244
|
+
|
|
1245
|
+
dispose(): void {
|
|
1246
|
+
this.toDispose.dispose();
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
protected clearEditContext(): void {
|
|
1250
|
+
this.editContextManager.setVariables(this.context.variables.map(AIVariableResolutionRequest.fromResolved));
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
protected emitEditRequest(request: MutableChatRequestModel): void {
|
|
1254
|
+
const branch = this.session.getBranch(request.id);
|
|
1255
|
+
if (!branch) {
|
|
1256
|
+
throw new Error(`Cannot find hierarchy for requestId: ${request.id}`);
|
|
1257
|
+
}
|
|
1258
|
+
this.session.emit({
|
|
1259
|
+
kind: 'enableEdit',
|
|
1260
|
+
request,
|
|
1261
|
+
branch,
|
|
1262
|
+
});
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
protected emitCancelEdit(request: MutableChatRequestModel): void {
|
|
1266
|
+
const branch = this.session.getBranch(request.id);
|
|
1267
|
+
if (!branch) {
|
|
1268
|
+
throw new Error(`Cannot find branch for requestId: ${request.id}`);
|
|
1269
|
+
}
|
|
1270
|
+
this.session.emit({
|
|
1271
|
+
kind: 'cancelEdit',
|
|
1272
|
+
request,
|
|
1273
|
+
branch,
|
|
1274
|
+
});
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
protected emitSubmitEdit(request: MutableChatRequestModel, newRequest: ChatRequest): void {
|
|
1278
|
+
const branch = this.session.getBranch(request.id);
|
|
1279
|
+
if (!branch) {
|
|
1280
|
+
throw new Error(`Cannot find branch for requestId: ${request.id}`);
|
|
1281
|
+
}
|
|
1282
|
+
this.session.emit({
|
|
1283
|
+
kind: 'submitEdit',
|
|
1284
|
+
request,
|
|
1285
|
+
branch,
|
|
1286
|
+
newRequest
|
|
1287
|
+
});
|
|
1288
|
+
}
|
|
799
1289
|
}
|
|
800
1290
|
|
|
801
1291
|
export class ErrorChatResponseContentImpl implements ErrorChatResponseContent {
|
|
@@ -1043,7 +1533,7 @@ export class ToolCallChatResponseContentImpl implements ToolCallChatResponseCont
|
|
|
1043
1533
|
actor: 'ai',
|
|
1044
1534
|
type: 'tool_use',
|
|
1045
1535
|
id: this.id ?? '',
|
|
1046
|
-
input:
|
|
1536
|
+
input: this.arguments && this.arguments.length !== 0 ? JSON.parse(this.arguments) : {},
|
|
1047
1537
|
name: this.name ?? ''
|
|
1048
1538
|
}, {
|
|
1049
1539
|
actor: 'user',
|
|
@@ -1061,8 +1551,7 @@ export const COMMAND_CHAT_RESPONSE_COMMAND: Command = {
|
|
|
1061
1551
|
export class CommandChatResponseContentImpl implements CommandChatResponseContent {
|
|
1062
1552
|
readonly kind = 'command';
|
|
1063
1553
|
|
|
1064
|
-
constructor(public command?: Command, public customCallback?: CustomCallback, protected args?: unknown[]) {
|
|
1065
|
-
}
|
|
1554
|
+
constructor(public command?: Command, public customCallback?: CustomCallback, protected args?: unknown[]) { }
|
|
1066
1555
|
|
|
1067
1556
|
get arguments(): unknown[] {
|
|
1068
1557
|
return this.args ?? [];
|