@opensumi/ide-ai-native 3.8.2-next-1741622293.0 → 3.8.2
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-core.contribution.d.ts.map +1 -1
- package/lib/browser/ai-core.contribution.js +20 -0
- package/lib/browser/ai-core.contribution.js.map +1 -1
- package/lib/browser/chat/chat-manager.service.d.ts +2 -1
- package/lib/browser/chat/chat-manager.service.d.ts.map +1 -1
- package/lib/browser/chat/chat-manager.service.js +26 -7
- package/lib/browser/chat/chat-manager.service.js.map +1 -1
- package/lib/browser/chat/chat-model.d.ts +3 -3
- package/lib/browser/chat/chat-model.d.ts.map +1 -1
- package/lib/browser/chat/chat-model.js +22 -9
- package/lib/browser/chat/chat-model.js.map +1 -1
- package/lib/browser/chat/chat-proxy.service.d.ts +1 -0
- package/lib/browser/chat/chat-proxy.service.d.ts.map +1 -1
- package/lib/browser/chat/chat-proxy.service.js +2 -0
- package/lib/browser/chat/chat-proxy.service.js.map +1 -1
- package/lib/browser/chat/chat.view.d.ts.map +1 -1
- package/lib/browser/chat/chat.view.js +61 -5
- package/lib/browser/chat/chat.view.js.map +1 -1
- package/lib/browser/components/ApplyStatus.d.ts +7 -0
- package/lib/browser/components/ApplyStatus.d.ts.map +1 -0
- package/lib/browser/components/ApplyStatus.js +32 -0
- package/lib/browser/components/ApplyStatus.js.map +1 -0
- package/lib/browser/components/ChangeList.d.ts +17 -0
- package/lib/browser/components/ChangeList.d.ts.map +1 -0
- package/lib/browser/components/ChangeList.js +72 -0
- package/lib/browser/components/ChangeList.js.map +1 -0
- package/lib/browser/components/ChatToolRender.d.ts.map +1 -1
- package/lib/browser/components/ChatToolRender.js +18 -12
- package/lib/browser/components/ChatToolRender.js.map +1 -1
- package/lib/browser/components/ChatToolRender.module.less +27 -15
- package/lib/browser/components/change-list.module.less +126 -0
- package/lib/browser/components/chat-history.module.less +1 -1
- package/lib/browser/components/components.module.less +14 -0
- package/lib/browser/contrib/inline-completions/prompt/matcher.js +2 -2
- package/lib/browser/contrib/inline-completions/prompt/similarSnippets.d.ts +1 -1
- package/lib/browser/contrib/inline-completions/prompt/similarSnippets.js +2 -2
- package/lib/browser/contrib/intelligent-completions/view/default.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/view/default.js.map +1 -1
- package/lib/browser/index.d.ts.map +1 -1
- package/lib/browser/index.js +4 -4
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/mcp/base-apply.service.d.ts +14 -6
- package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
- package/lib/browser/mcp/base-apply.service.js +80 -52
- package/lib/browser/mcp/base-apply.service.js.map +1 -1
- package/lib/browser/mcp/config/components/mcp-config.view.d.ts.map +1 -1
- package/lib/browser/mcp/config/components/mcp-config.view.js +12 -8
- package/lib/browser/mcp/config/components/mcp-config.view.js.map +1 -1
- package/lib/browser/mcp/config/mcp-config.contribution.js.map +1 -1
- package/lib/browser/mcp/tools/components/EditFile.js +3 -24
- package/lib/browser/mcp/tools/components/EditFile.js.map +1 -1
- package/lib/browser/mcp/tools/components/ExpandableFileList.js +3 -2
- package/lib/browser/mcp/tools/components/ExpandableFileList.js.map +1 -1
- package/lib/browser/model/msg-history-manager.d.ts +0 -2
- package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
- package/lib/browser/model/msg-history-manager.js +1 -6
- package/lib/browser/model/msg-history-manager.js.map +1 -1
- package/lib/browser/preferences/schema.d.ts.map +1 -1
- package/lib/browser/preferences/schema.js +8 -0
- package/lib/browser/preferences/schema.js.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff-manager.d.ts.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff-manager.js +2 -2
- package/lib/browser/widget/inline-diff/inline-diff-manager.js.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff.controller.d.ts +1 -1
- package/lib/browser/widget/inline-diff/inline-diff.controller.d.ts.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff.controller.js.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff.service.d.ts +3 -2
- package/lib/browser/widget/inline-diff/inline-diff.service.d.ts.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff.service.js.map +1 -1
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts +1 -1
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts.map +1 -1
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts +0 -33
- package/lib/browser/widget/inline-stream-diff/live-preview.component.d.ts.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.component.js +1 -6
- package/lib/browser/widget/inline-stream-diff/live-preview.component.js.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js +15 -14
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js.map +1 -1
- package/lib/common/index.d.ts +7 -2
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js +3 -2
- package/lib/common/index.js.map +1 -1
- package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -1
- package/lib/common/prompts/context-prompt-provider.js +2 -4
- package/lib/common/prompts/context-prompt-provider.js.map +1 -1
- package/lib/common/types.d.ts +33 -0
- package/lib/common/types.d.ts.map +1 -1
- package/lib/common/types.js +6 -1
- package/lib/common/types.js.map +1 -1
- package/package.json +23 -23
- package/src/browser/ai-core.contribution.ts +28 -0
- package/src/browser/chat/chat-manager.service.ts +53 -31
- package/src/browser/chat/chat-model.ts +22 -8
- package/src/browser/chat/chat-proxy.service.ts +2 -0
- package/src/browser/chat/chat.view.tsx +80 -9
- package/src/browser/components/ApplyStatus.tsx +44 -0
- package/src/browser/components/ChangeList.tsx +131 -0
- package/src/browser/components/ChatToolRender.module.less +27 -15
- package/src/browser/components/ChatToolRender.tsx +14 -12
- package/src/browser/components/change-list.module.less +126 -0
- package/src/browser/components/chat-history.module.less +1 -1
- package/src/browser/components/components.module.less +14 -0
- package/src/browser/contrib/inline-completions/prompt/matcher.ts +2 -2
- package/src/browser/contrib/inline-completions/prompt/similarSnippets.ts +2 -2
- package/src/browser/contrib/intelligent-completions/view/default.ts +1 -0
- package/src/browser/index.ts +5 -4
- package/src/browser/mcp/base-apply.service.ts +84 -62
- package/src/browser/mcp/config/components/mcp-config.view.tsx +4 -0
- package/src/browser/mcp/config/mcp-config.contribution.ts +1 -1
- package/src/browser/mcp/tools/components/EditFile.tsx +3 -37
- package/src/browser/mcp/tools/components/ExpandableFileList.tsx +3 -1
- package/src/browser/model/msg-history-manager.ts +1 -8
- package/src/browser/preferences/schema.ts +8 -0
- package/src/browser/widget/inline-diff/inline-diff-manager.tsx +3 -2
- package/src/browser/widget/inline-diff/inline-diff.controller.ts +2 -1
- package/src/browser/widget/inline-diff/inline-diff.service.ts +3 -2
- package/src/browser/widget/inline-stream-diff/inline-stream-diff.handler.tsx +4 -4
- package/src/browser/widget/inline-stream-diff/live-preview.component.tsx +0 -34
- package/src/browser/widget/inline-stream-diff/live-preview.decoration.tsx +8 -9
- package/src/common/index.ts +9 -2
- package/src/common/prompts/context-prompt-provider.ts +2 -6
- package/src/common/types.ts +35 -0
|
@@ -26,17 +26,13 @@ import { Deferred, DisposableMap, Emitter, IDisposable, URI, path } from '@opens
|
|
|
26
26
|
import { SumiReadableStream } from '@opensumi/ide-utils/lib/stream';
|
|
27
27
|
import { EditOperation } from '@opensumi/monaco-editor-core/esm/vs/editor/common/core/editOperation';
|
|
28
28
|
|
|
29
|
-
import { IChatInternalService } from '../../common';
|
|
29
|
+
import { IChatInternalService, IInlineDiffService, InlineDiffServiceToken } from '../../common';
|
|
30
30
|
import { CodeBlockData, CodeBlockStatus } from '../../common/types';
|
|
31
31
|
import { ChatInternalService } from '../chat/chat.internal.service';
|
|
32
32
|
import { InlineChatController } from '../widget/inline-chat/inline-chat-controller';
|
|
33
|
-
import {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
InlineDiffService,
|
|
37
|
-
LiveInlineDiffPreviewer,
|
|
38
|
-
} from '../widget/inline-diff';
|
|
39
|
-
import { BaseInlineStreamDiffHandler } from '../widget/inline-stream-diff/inline-stream-diff.handler';
|
|
33
|
+
import { BaseInlineDiffPreviewer, InlineDiffController, LiveInlineDiffPreviewer } from '../widget/inline-diff';
|
|
34
|
+
|
|
35
|
+
import type { BaseInlineStreamDiffHandler } from '../widget/inline-stream-diff/inline-stream-diff.handler';
|
|
40
36
|
|
|
41
37
|
export abstract class BaseApplyService extends WithEventBus {
|
|
42
38
|
@Autowired(IChatInternalService)
|
|
@@ -48,8 +44,8 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
48
44
|
@Autowired(WorkbenchEditorService)
|
|
49
45
|
protected readonly editorService: WorkbenchEditorService;
|
|
50
46
|
|
|
51
|
-
@Autowired(
|
|
52
|
-
private readonly inlineDiffService:
|
|
47
|
+
@Autowired(InlineDiffServiceToken)
|
|
48
|
+
private readonly inlineDiffService: IInlineDiffService;
|
|
53
49
|
|
|
54
50
|
@Autowired(IMarkerService)
|
|
55
51
|
private readonly markerService: IMarkerService;
|
|
@@ -155,7 +151,7 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
155
151
|
// 使用最后一个版本内容渲染 apply 内容
|
|
156
152
|
if (filePendingApplies.length > 0 && filePendingApplies[0].updatedCode) {
|
|
157
153
|
const editor = event.payload.group.codeEditor.monacoEditor;
|
|
158
|
-
this.renderApplyResult(editor, filePendingApplies[0], filePendingApplies[0].updatedCode);
|
|
154
|
+
await this.renderApplyResult(editor, filePendingApplies[0], filePendingApplies[0].updatedCode);
|
|
159
155
|
}
|
|
160
156
|
}
|
|
161
157
|
|
|
@@ -183,9 +179,10 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
183
179
|
return sessionCodeBlocks.filter((block) => block.status === 'pending').map((block) => block.relativePath);
|
|
184
180
|
}
|
|
185
181
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
182
|
+
getSessionCodeBlocks(sessionId?: string) {
|
|
183
|
+
const sessionModel = sessionId
|
|
184
|
+
? this.chatInternalService.getSession(sessionId)
|
|
185
|
+
: this.chatInternalService.sessionModel;
|
|
189
186
|
if (!sessionModel) {
|
|
190
187
|
throw new Error(`Session ${sessionId} not found`);
|
|
191
188
|
}
|
|
@@ -301,22 +298,17 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
301
298
|
if (!result) {
|
|
302
299
|
throw new Error('Failed to open file');
|
|
303
300
|
}
|
|
304
|
-
|
|
305
|
-
codeBlock.updatedCode = fastApplyFileResult.result;
|
|
306
|
-
codeBlock.status = 'pending';
|
|
307
|
-
this.updateCodeBlock(codeBlock);
|
|
308
|
-
}
|
|
309
|
-
const applyResult = await this.renderApplyResult(
|
|
301
|
+
const res = await this.renderApplyResult(
|
|
310
302
|
result.group.codeEditor.monacoEditor,
|
|
311
303
|
codeBlock,
|
|
312
304
|
(fastApplyFileResult.result || fastApplyFileResult.stream)!,
|
|
313
305
|
fastApplyFileResult.range,
|
|
314
306
|
);
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
307
|
+
codeBlock.updatedCode = res.updatedCode;
|
|
308
|
+
codeBlock.status = 'pending';
|
|
309
|
+
// 用户实际接受的 apply 结果
|
|
310
|
+
codeBlock.applyResult = res.result;
|
|
311
|
+
this.updateCodeBlock(codeBlock);
|
|
320
312
|
|
|
321
313
|
return codeBlock;
|
|
322
314
|
} catch (err) {
|
|
@@ -328,31 +320,33 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
328
320
|
}
|
|
329
321
|
}
|
|
330
322
|
|
|
323
|
+
/**
|
|
324
|
+
* 渲染apply结果(支持流式和直接输出结果)
|
|
325
|
+
* 副作用:渲染时会添加accept、reject操作监听器,监听到结果时会自动更新codeBlock的result
|
|
326
|
+
*/
|
|
331
327
|
async renderApplyResult(
|
|
332
328
|
editor: ICodeEditor,
|
|
333
329
|
codeBlock: CodeBlockData,
|
|
334
330
|
updatedContentOrStream: string | SumiReadableStream<IChatProgress>,
|
|
335
331
|
range?: Range,
|
|
336
|
-
): Promise<{ diff: string; diagnosticInfos: IMarker[] }
|
|
337
|
-
const deferred = new Deferred<{ diff: string; diagnosticInfos: IMarker[] }>();
|
|
332
|
+
): Promise<{ result?: { diff: string; diagnosticInfos: IMarker[] }; updatedCode: string }> {
|
|
333
|
+
const deferred = new Deferred<{ result?: { diff: string; diagnosticInfos: IMarker[] }; updatedCode: string }>();
|
|
338
334
|
const inlineDiffController = InlineDiffController.get(editor)!;
|
|
339
335
|
range = range || editor.getModel()!.getFullModelRange();
|
|
340
336
|
|
|
341
337
|
if (typeof updatedContentOrStream === 'string') {
|
|
338
|
+
const updatedContent = updatedContentOrStream;
|
|
342
339
|
const editorCurrentContent = editor.getModel()!.getValue();
|
|
343
340
|
const uri = URI.file(path.join(this.appConfig.workspaceDir, codeBlock.relativePath));
|
|
344
341
|
const document = this.editorDocumentModelService.getModelReference(uri);
|
|
345
|
-
if (editorCurrentContent !==
|
|
346
|
-
editor.getModel()?.pushEditOperations([], [EditOperation.replace(range,
|
|
342
|
+
if (editorCurrentContent !== updatedContent || document?.instance.dirty) {
|
|
343
|
+
editor.getModel()?.pushEditOperations([], [EditOperation.replace(range, updatedContent)], () => null);
|
|
347
344
|
await this.editorService.save(uri);
|
|
348
345
|
}
|
|
349
346
|
const uriPendingCodeBlocks = this.getUriCodeBlocks(uri)?.filter((block) => block.status === 'pending');
|
|
350
347
|
const earlistPendingCodeBlock = uriPendingCodeBlocks?.[uriPendingCodeBlocks.length - 1];
|
|
351
|
-
if ((earlistPendingCodeBlock
|
|
352
|
-
|
|
353
|
-
this.updateCodeBlock(codeBlock);
|
|
354
|
-
deferred.resolve();
|
|
355
|
-
return;
|
|
348
|
+
if ((earlistPendingCodeBlock || codeBlock)?.originalCode === updatedContent) {
|
|
349
|
+
throw new Error('No changes applied');
|
|
356
350
|
}
|
|
357
351
|
// Create diff previewer
|
|
358
352
|
const previewer = inlineDiffController.createDiffPreviewer(
|
|
@@ -380,13 +374,16 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
380
374
|
|
|
381
375
|
const { diff, rangesFromDiffHunk } = this.getDiffResult(
|
|
382
376
|
codeBlock.originalCode,
|
|
383
|
-
|
|
377
|
+
updatedContent,
|
|
384
378
|
codeBlock.relativePath,
|
|
385
379
|
);
|
|
386
380
|
const diagnosticInfos = this.getDiagnosticInfos(editor.getModel()!.uri.toString(), rangesFromDiffHunk);
|
|
387
381
|
deferred.resolve({
|
|
388
|
-
|
|
389
|
-
|
|
382
|
+
result: {
|
|
383
|
+
diff,
|
|
384
|
+
diagnosticInfos,
|
|
385
|
+
},
|
|
386
|
+
updatedCode: updatedContent,
|
|
390
387
|
});
|
|
391
388
|
} else {
|
|
392
389
|
const controller = new InlineChatController();
|
|
@@ -414,21 +411,21 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
414
411
|
this.addDispose(
|
|
415
412
|
// 流式输出结束后,转为直接输出逻辑
|
|
416
413
|
previewer.getNode()!.onDiffFinished(async (diffModel) => {
|
|
417
|
-
codeBlock.updatedCode = diffModel.newFullRangeTextLines.join('\n');
|
|
418
414
|
// TODO: 添加 reapply
|
|
415
|
+
const updatedCode = diffModel.newFullRangeTextLines.join('\n');
|
|
419
416
|
// 实际应用结果为空,则取消
|
|
420
|
-
if (codeBlock.
|
|
421
|
-
codeBlock.status = 'failed';
|
|
422
|
-
this.updateCodeBlock(codeBlock);
|
|
417
|
+
if (codeBlock.originalCode === updatedCode) {
|
|
423
418
|
previewer.dispose();
|
|
424
419
|
deferred.reject(new Error('no changes applied'));
|
|
425
420
|
return;
|
|
426
421
|
}
|
|
427
|
-
codeBlock.status = 'pending';
|
|
428
|
-
this.updateCodeBlock(codeBlock);
|
|
429
422
|
previewer.dispose();
|
|
430
|
-
|
|
431
|
-
|
|
423
|
+
try {
|
|
424
|
+
const res = await this.renderApplyResult(editor, codeBlock, updatedCode);
|
|
425
|
+
deferred.resolve(res);
|
|
426
|
+
} catch (err) {
|
|
427
|
+
deferred.reject(err);
|
|
428
|
+
}
|
|
432
429
|
}),
|
|
433
430
|
);
|
|
434
431
|
this.activePreviewerMap.set(codeBlock.relativePath, previewer);
|
|
@@ -483,14 +480,36 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
483
480
|
}
|
|
484
481
|
}
|
|
485
482
|
|
|
486
|
-
processAll(
|
|
487
|
-
const codeBlocks =
|
|
483
|
+
processAll(type: 'accept' | 'reject', uri?: URI): void {
|
|
484
|
+
const codeBlocks = uri
|
|
485
|
+
? this.getUriCodeBlocks(uri)?.filter((block) => block.status === 'pending')
|
|
486
|
+
: this.getSessionCodeBlocks().filter((block) => block.status === 'pending');
|
|
488
487
|
if (!codeBlocks?.length) {
|
|
489
488
|
throw new Error('No pending code block found');
|
|
490
489
|
}
|
|
491
|
-
const
|
|
492
|
-
|
|
493
|
-
|
|
490
|
+
const relativePaths = uri
|
|
491
|
+
? [codeBlocks[0].relativePath]
|
|
492
|
+
: codeBlocks
|
|
493
|
+
.map((block) => block.relativePath)
|
|
494
|
+
.reduce((acc, cur) => {
|
|
495
|
+
if (acc.includes(cur)) {
|
|
496
|
+
return acc;
|
|
497
|
+
}
|
|
498
|
+
acc.push(cur);
|
|
499
|
+
return acc;
|
|
500
|
+
}, [] as string[]);
|
|
501
|
+
relativePaths.forEach((relativePath) => {
|
|
502
|
+
this.doProcess(type, relativePath);
|
|
503
|
+
});
|
|
504
|
+
codeBlocks.forEach((codeBlock) => {
|
|
505
|
+
codeBlock.status = type === 'accept' ? 'success' : 'cancelled';
|
|
506
|
+
// TODO: 批量更新
|
|
507
|
+
this.updateCodeBlock(codeBlock);
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
protected doProcess(type: 'accept' | 'reject', relativePath: string) {
|
|
512
|
+
const decorationModel = this.activePreviewerMap.get(relativePath)?.getNode()?.livePreviewDiffDecorationModel;
|
|
494
513
|
if (!decorationModel) {
|
|
495
514
|
throw new Error('No active previewer found');
|
|
496
515
|
}
|
|
@@ -499,19 +518,13 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
499
518
|
} else {
|
|
500
519
|
decorationModel.discardUnProcessed();
|
|
501
520
|
}
|
|
502
|
-
this.editorService.save(
|
|
503
|
-
codeBlocks.forEach((codeBlock) => {
|
|
504
|
-
codeBlock.status = type === 'accept' ? 'success' : 'cancelled';
|
|
505
|
-
// TODO: 批量更新
|
|
506
|
-
this.updateCodeBlock(codeBlock);
|
|
507
|
-
});
|
|
521
|
+
this.editorService.save(URI.file(path.join(this.appConfig.workspaceDir, relativePath)));
|
|
508
522
|
}
|
|
509
523
|
|
|
510
524
|
protected listenPartialEdit(model: ITextModel, codeBlock: CodeBlockData) {
|
|
511
525
|
const deferred = new Deferred<{ diff: string; diagnosticInfos: IMarker[] }>();
|
|
512
526
|
const uriString = model.uri.toString();
|
|
513
527
|
const toDispose = this.inlineDiffService.onPartialEdit((event) => {
|
|
514
|
-
// TODO 支持自动保存
|
|
515
528
|
if (
|
|
516
529
|
event.totalPartialEditCount === event.resolvedPartialEditCount &&
|
|
517
530
|
event.uri.path === model.uri.path.toString()
|
|
@@ -532,11 +545,19 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
532
545
|
actionSource: ActionSourceEnum.Chat,
|
|
533
546
|
sessionId: this.chatInternalService.sessionModel.sessionId,
|
|
534
547
|
isReceive: true,
|
|
535
|
-
|
|
536
|
-
|
|
548
|
+
// 是否有丢弃部分代码
|
|
549
|
+
isDrop: event.acceptPartialEditCount !== event.totalPartialEditCount,
|
|
550
|
+
code: appliedResult,
|
|
551
|
+
originCode: codeBlock.originalCode,
|
|
537
552
|
message: JSON.stringify({
|
|
538
553
|
diff,
|
|
539
554
|
diagnosticInfos,
|
|
555
|
+
instructions: codeBlock.instructions,
|
|
556
|
+
codeEdit: codeBlock.codeEdit,
|
|
557
|
+
partialEditCount: event.totalPartialEditCount,
|
|
558
|
+
acceptPartialEditCount: event.acceptPartialEditCount,
|
|
559
|
+
addedLinesCount: event.totalAddedLinesCount,
|
|
560
|
+
deletedLinesCount: event.totalDeletedLinesCount,
|
|
540
561
|
}),
|
|
541
562
|
});
|
|
542
563
|
deferred.resolve({
|
|
@@ -554,8 +575,11 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
554
575
|
sessionId: this.chatInternalService.sessionModel.sessionId,
|
|
555
576
|
isReceive: false,
|
|
556
577
|
isDrop: true,
|
|
557
|
-
code: codeBlock.codeEdit,
|
|
558
578
|
originCode: codeBlock.originalCode,
|
|
579
|
+
message: JSON.stringify({
|
|
580
|
+
instructions: codeBlock.instructions,
|
|
581
|
+
codeEdit: codeBlock.codeEdit,
|
|
582
|
+
}),
|
|
559
583
|
});
|
|
560
584
|
}
|
|
561
585
|
this.editorListenerMap.disposeKey(uriString);
|
|
@@ -593,8 +617,6 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
593
617
|
result?: string;
|
|
594
618
|
}>;
|
|
595
619
|
|
|
596
|
-
// FIXME: 貌似筛选逻辑不太对,需要重构
|
|
597
|
-
// TODO: 支持使用内存中的document获取诊断信息,实现并行apply accept
|
|
598
620
|
protected getDiagnosticInfos(uri: string, ranges: Range[]) {
|
|
599
621
|
const markers = this.markerService.getManager().getMarkers({ resource: uri });
|
|
600
622
|
return markers.filter(
|
|
@@ -5,6 +5,7 @@ import { Badge } from '@opensumi/ide-components';
|
|
|
5
5
|
import { AINativeSettingSectionsId, ILogger, useInjectable } from '@opensumi/ide-core-browser';
|
|
6
6
|
import { PreferenceService } from '@opensumi/ide-core-browser/lib/preferences';
|
|
7
7
|
import { localize } from '@opensumi/ide-core-common';
|
|
8
|
+
import { IMessageService } from '@opensumi/ide-overlay/lib/common';
|
|
8
9
|
|
|
9
10
|
import { BUILTIN_MCP_SERVER_NAME, ISumiMCPServerBackend, SumiMCPServerProxyServicePath } from '../../../../common';
|
|
10
11
|
import { MCPServerDescription } from '../../../../common/mcp-server-manager';
|
|
@@ -19,6 +20,7 @@ export const MCPConfigView: React.FC = () => {
|
|
|
19
20
|
const preferenceService = useInjectable<PreferenceService>(PreferenceService);
|
|
20
21
|
const sumiMCPServerBackendProxy = useInjectable<ISumiMCPServerBackend>(SumiMCPServerProxyServicePath);
|
|
21
22
|
const logger = useInjectable<ILogger>(ILogger);
|
|
23
|
+
const messageService = useInjectable<IMessageService>(IMessageService);
|
|
22
24
|
const [servers, setServers] = React.useState<MCPServer[]>([]);
|
|
23
25
|
const [formVisible, setFormVisible] = React.useState(false);
|
|
24
26
|
const [editingServer, setEditingServer] = React.useState<MCPServerFormData | undefined>();
|
|
@@ -88,7 +90,9 @@ export const MCPConfigView: React.FC = () => {
|
|
|
88
90
|
await preferenceService.set(AINativeSettingSectionsId.MCPServers, updatedServers);
|
|
89
91
|
await loadServers();
|
|
90
92
|
} catch (error) {
|
|
93
|
+
const msg = error.message || error;
|
|
91
94
|
logger.error(`Failed to ${start ? 'start' : 'stop'} server ${serverName}:`, error);
|
|
95
|
+
messageService.error(`Failed to ${start ? 'start' : 'stop'} server ${serverName}:` + msg);
|
|
92
96
|
}
|
|
93
97
|
},
|
|
94
98
|
[mcpServerProxyService, preferenceService, sumiMCPServerBackendProxy, loadServers],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Autowired } from '@opensumi/di';
|
|
2
2
|
import { LabelService } from '@opensumi/ide-core-browser/lib/services';
|
|
3
|
-
import { Domain,
|
|
3
|
+
import { Domain, URI } from '@opensumi/ide-core-common';
|
|
4
4
|
import {
|
|
5
5
|
BrowserEditorContribution,
|
|
6
6
|
EditorComponentRegistry,
|
|
@@ -12,13 +12,13 @@ import {
|
|
|
12
12
|
path,
|
|
13
13
|
useInjectable,
|
|
14
14
|
} from '@opensumi/ide-core-browser';
|
|
15
|
-
import { Loading } from '@opensumi/ide-core-browser/lib/components/ai-native';
|
|
16
15
|
import { WorkbenchEditorService } from '@opensumi/ide-editor';
|
|
17
16
|
import { ILanguageService } from '@opensumi/monaco-editor-core/esm/vs/editor/common/languages/language';
|
|
18
17
|
import { IModelService } from '@opensumi/monaco-editor-core/esm/vs/editor/common/services/model';
|
|
19
18
|
import { StandaloneServices } from '@opensumi/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices';
|
|
20
19
|
|
|
21
20
|
import { CodeBlockData } from '../../../../common/types';
|
|
21
|
+
import { ApplyStatus } from '../../../components/ApplyStatus';
|
|
22
22
|
import { ChatMarkdown } from '../../../components/ChatMarkdown';
|
|
23
23
|
import { IMCPServerToolComponentProps } from '../../../types';
|
|
24
24
|
import { BaseApplyService } from '../../base-apply.service';
|
|
@@ -76,7 +76,7 @@ export const EditFileToolComponent = (props: IMCPServerToolComponentProps) => {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
return [
|
|
79
|
-
instructions && <p>{instructions}</p>,
|
|
79
|
+
instructions && <p key={'edit-file-tool-instructions'}>{instructions}</p>,
|
|
80
80
|
<div className={styles['edit-file-tool']} key={'edit-file-tool'}>
|
|
81
81
|
<div
|
|
82
82
|
className={cls(styles['edit-file-tool-header'], {
|
|
@@ -96,7 +96,7 @@ export const EditFileToolComponent = (props: IMCPServerToolComponentProps) => {
|
|
|
96
96
|
{codeBlockData.iterationCount > 1 && (
|
|
97
97
|
<span className={styles['edit-file-tool-iteration-count']}>{codeBlockData.iterationCount}/3</span>
|
|
98
98
|
)}
|
|
99
|
-
{
|
|
99
|
+
<ApplyStatus status={codeBlockData.status} error={props.result} />
|
|
100
100
|
</div>
|
|
101
101
|
<div className={styles.right}>
|
|
102
102
|
<Popover title={'Show Code'} id={'edit-file-tool-show-code'}>
|
|
@@ -137,37 +137,3 @@ export const EditFileToolComponent = (props: IMCPServerToolComponentProps) => {
|
|
|
137
137
|
),
|
|
138
138
|
];
|
|
139
139
|
};
|
|
140
|
-
|
|
141
|
-
const renderStatus = (codeBlockData: CodeBlockData, error?: string) => {
|
|
142
|
-
const status = codeBlockData.status;
|
|
143
|
-
switch (status) {
|
|
144
|
-
case 'generating':
|
|
145
|
-
return <Loading />;
|
|
146
|
-
case 'pending':
|
|
147
|
-
return (
|
|
148
|
-
<Popover title='Pending' id={'edit-file-tool-status-pending'}>
|
|
149
|
-
<Icon iconClass='codicon codicon-circle-large' />
|
|
150
|
-
</Popover>
|
|
151
|
-
);
|
|
152
|
-
case 'success':
|
|
153
|
-
return (
|
|
154
|
-
<Popover title='Success' id={'edit-file-tool-status-success'}>
|
|
155
|
-
<Icon iconClass='codicon codicon-check-all' />
|
|
156
|
-
</Popover>
|
|
157
|
-
);
|
|
158
|
-
case 'failed':
|
|
159
|
-
return (
|
|
160
|
-
<Popover title={`Failed (${error})`} id={'edit-file-tool-status-failed'}>
|
|
161
|
-
<Icon iconClass='codicon codicon-error' style={{ color: 'var(--debugConsole-errorForeground)' }} />
|
|
162
|
-
</Popover>
|
|
163
|
-
);
|
|
164
|
-
case 'cancelled':
|
|
165
|
-
return (
|
|
166
|
-
<Popover title='Cancelled' id={'edit-file-tool-status-cancelled'}>
|
|
167
|
-
<Icon iconClass='codicon codicon-close' style={{ color: 'var(--input-placeholderForeground)' }} />
|
|
168
|
-
</Popover>
|
|
169
|
-
);
|
|
170
|
-
default:
|
|
171
|
-
return null;
|
|
172
|
-
}
|
|
173
|
-
};
|
|
@@ -71,7 +71,9 @@ const ExpandableFileList: React.FC<ExpandableFileListProps> = ({
|
|
|
71
71
|
|
|
72
72
|
useEffect(() => {
|
|
73
73
|
const toDispose = chatService.sessionModel.history.onMessageAdditionalChange((additional) => {
|
|
74
|
-
|
|
74
|
+
if (additional[toolCallId]) {
|
|
75
|
+
setFileList(additional[toolCallId].files || []);
|
|
76
|
+
}
|
|
75
77
|
});
|
|
76
78
|
return () => {
|
|
77
79
|
toDispose.dispose();
|
|
@@ -29,7 +29,6 @@ export class MsgHistoryManager extends Disposable {
|
|
|
29
29
|
public clearMessages() {
|
|
30
30
|
this.messageMap.clear();
|
|
31
31
|
this.messageAdditionalMap.clear();
|
|
32
|
-
this.startIndex = 0;
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
private doAddMessage(message: IExcludeMessage): string {
|
|
@@ -53,19 +52,13 @@ export class MsgHistoryManager extends Disposable {
|
|
|
53
52
|
return Array.from(this.messageMap.values()).sort((a, b) => a.order - b.order);
|
|
54
53
|
}
|
|
55
54
|
|
|
56
|
-
private startIndex = 0;
|
|
57
|
-
|
|
58
|
-
public get slicedMessageCount(): number {
|
|
59
|
-
return this.startIndex;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
55
|
public get lastMessageId(): string | undefined {
|
|
63
56
|
const list = this.messageList;
|
|
64
57
|
return list[list.length - 1]?.id;
|
|
65
58
|
}
|
|
66
59
|
|
|
67
60
|
public getMessages(): IHistoryChatMessage[] {
|
|
68
|
-
return this.messageList
|
|
61
|
+
return this.messageList;
|
|
69
62
|
}
|
|
70
63
|
|
|
71
64
|
public addUserMessage(
|
|
@@ -97,6 +97,14 @@ export const aiNativePreferenceSchema: PreferenceSchema = {
|
|
|
97
97
|
default: '',
|
|
98
98
|
description: localize('preference.ai.native.openai.baseURL.description'),
|
|
99
99
|
},
|
|
100
|
+
[AINativeSettingSectionsId.ContextWindow]: {
|
|
101
|
+
type: 'number',
|
|
102
|
+
description: localize('preference.ai.native.contextWindow.description'),
|
|
103
|
+
},
|
|
104
|
+
[AINativeSettingSectionsId.MaxTokens]: {
|
|
105
|
+
type: 'number',
|
|
106
|
+
description: localize('preference.ai.native.maxTokens.description'),
|
|
107
|
+
},
|
|
100
108
|
[AINativeSettingSectionsId.MCPServers]: {
|
|
101
109
|
type: 'array',
|
|
102
110
|
default: [],
|
|
@@ -3,6 +3,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
|
3
3
|
import { Icon, Popover } from '@opensumi/ide-components';
|
|
4
4
|
import { AppConfig, IDisposable, URI, localize, path, useInjectable } from '@opensumi/ide-core-browser';
|
|
5
5
|
import { IResource, WorkbenchEditorService } from '@opensumi/ide-editor';
|
|
6
|
+
import { Path } from '@opensumi/ide-utils/lib/path';
|
|
6
7
|
|
|
7
8
|
import { BaseApplyService } from '../../mcp/base-apply.service';
|
|
8
9
|
|
|
@@ -113,13 +114,13 @@ export const InlineDiffManager: React.FC<{ resource: IResource }> = (props) => {
|
|
|
113
114
|
<div className={styles.mid}>
|
|
114
115
|
<IconWithPopover
|
|
115
116
|
icon='codicon codicon-check'
|
|
116
|
-
onClick={() => applyService.processAll(props.resource.uri
|
|
117
|
+
onClick={() => applyService.processAll('accept', props.resource.uri)}
|
|
117
118
|
content={localize('aiNative.inlineDiff.acceptAll')}
|
|
118
119
|
id='inline-diff-manager-accept-all'
|
|
119
120
|
/>
|
|
120
121
|
<IconWithPopover
|
|
121
122
|
icon='codicon codicon-close'
|
|
122
|
-
onClick={() => applyService.processAll(props.resource.uri
|
|
123
|
+
onClick={() => applyService.processAll('reject', props.resource.uri)}
|
|
123
124
|
content={localize('aiNative.inlineDiff.rejectAll')}
|
|
124
125
|
id='inline-diff-manager-reject-all'
|
|
125
126
|
/>
|
|
@@ -23,7 +23,6 @@ import {
|
|
|
23
23
|
import { BaseAIMonacoEditorController } from '../../contrib/base';
|
|
24
24
|
import { EInlineDiffPreviewMode } from '../../preferences/schema';
|
|
25
25
|
import { InlineChatController } from '../inline-chat/inline-chat-controller';
|
|
26
|
-
import { EResultKind } from '../inline-chat/inline-chat.service';
|
|
27
26
|
import { BaseInlineStreamDiffHandler } from '../inline-stream-diff/inline-stream-diff.handler';
|
|
28
27
|
|
|
29
28
|
import {
|
|
@@ -34,6 +33,8 @@ import {
|
|
|
34
33
|
} from './inline-diff-previewer';
|
|
35
34
|
import { InlineDiffWidget } from './inline-diff-widget';
|
|
36
35
|
|
|
36
|
+
import type { EResultKind } from '../inline-chat/inline-chat.service';
|
|
37
|
+
|
|
37
38
|
type IInlineDiffPreviewer = BaseInlineDiffPreviewer<InlineDiffWidget | BaseInlineStreamDiffHandler>;
|
|
38
39
|
|
|
39
40
|
export class InlineDiffController extends BaseAIMonacoEditorController {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Injectable } from '@opensumi/di';
|
|
2
2
|
import { Emitter } from '@opensumi/ide-utils';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import type { IInlineDiffService } from '../../../common/index';
|
|
5
|
+
import type { IPartialEditEvent } from '../../../common/types';
|
|
5
6
|
|
|
6
7
|
@Injectable()
|
|
7
|
-
export class InlineDiffService {
|
|
8
|
+
export class InlineDiffService implements IInlineDiffService {
|
|
8
9
|
/**
|
|
9
10
|
* Used in `codeblitz`, do not remove it.
|
|
10
11
|
*/
|
|
@@ -11,13 +11,13 @@ import { IModelService } from '@opensumi/monaco-editor-core/esm/vs/editor/common
|
|
|
11
11
|
import { LineTokens } from '@opensumi/monaco-editor-core/esm/vs/editor/common/tokens/lineTokens';
|
|
12
12
|
import { UndoRedoGroup } from '@opensumi/monaco-editor-core/esm/vs/platform/undoRedo/common/undoRedo';
|
|
13
13
|
|
|
14
|
-
import { IDecorationSerializableState } from '../../model/enhanceDecorationsCollection';
|
|
15
|
-
import { IDiffPreviewerOptions, IInlineDiffPreviewerNode } from '../inline-diff/inline-diff-previewer';
|
|
16
|
-
|
|
17
14
|
import { InlineStreamDiffComputer } from './inline-stream-diff-computer';
|
|
18
|
-
import { IRemovedWidgetState } from './live-preview.component';
|
|
19
15
|
import { LivePreviewDiffDecorationModel } from './live-preview.decoration';
|
|
20
16
|
|
|
17
|
+
import type { IRemovedWidgetState } from './live-preview.component';
|
|
18
|
+
import type { IDecorationSerializableState } from '../../model/enhanceDecorationsCollection';
|
|
19
|
+
import type { IDiffPreviewerOptions, IInlineDiffPreviewerNode } from '../inline-diff/inline-diff-previewer';
|
|
20
|
+
|
|
21
21
|
interface IRangeChangeData {
|
|
22
22
|
removedTextLines: string[];
|
|
23
23
|
removedLinesOriginalRange: LineRange;
|
|
@@ -46,40 +46,6 @@ export interface IRemovedWidgetState {
|
|
|
46
46
|
position: IPosition;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
export enum EPartialEdit {
|
|
50
|
-
accept = 'accept',
|
|
51
|
-
discard = 'discard',
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export interface IPartialEditEvent {
|
|
55
|
-
uri: URI;
|
|
56
|
-
/**
|
|
57
|
-
* 总 diff 数
|
|
58
|
-
*/
|
|
59
|
-
totalPartialEditCount: number;
|
|
60
|
-
/**
|
|
61
|
-
* 已处理的个数
|
|
62
|
-
*/
|
|
63
|
-
resolvedPartialEditCount: number;
|
|
64
|
-
/**
|
|
65
|
-
* 已添加行数
|
|
66
|
-
*/
|
|
67
|
-
totalAddedLinesCount: number;
|
|
68
|
-
/**
|
|
69
|
-
* 已采纳的个数
|
|
70
|
-
*/
|
|
71
|
-
acceptPartialEditCount: number;
|
|
72
|
-
/**
|
|
73
|
-
* 已删除行数
|
|
74
|
-
*/
|
|
75
|
-
totalDeletedLinesCount: number;
|
|
76
|
-
currentPartialEdit: {
|
|
77
|
-
type: EPartialEdit;
|
|
78
|
-
addedLinesCount: number;
|
|
79
|
-
deletedLinesCount: number;
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
|
|
83
49
|
export interface ITextLinesTokens {
|
|
84
50
|
text: string;
|
|
85
51
|
lineTokens: LineTokens;
|
|
@@ -19,9 +19,10 @@ import { LineRange } from '@opensumi/monaco-editor-core/esm/vs/editor/common/cor
|
|
|
19
19
|
import { ModelDecorationOptions } from '@opensumi/monaco-editor-core/esm/vs/editor/common/model/textModel';
|
|
20
20
|
import { IUndoRedoService, UndoRedoGroup } from '@opensumi/monaco-editor-core/esm/vs/platform/undoRedo/common/undoRedo';
|
|
21
21
|
|
|
22
|
+
import { IInlineDiffService, InlineDiffServiceToken } from '../../../common';
|
|
23
|
+
import { EPartialEdit, IPartialEditEvent } from '../../../common/types';
|
|
22
24
|
import { AINativeContextKey } from '../../ai-core.contextkeys';
|
|
23
25
|
import { IDecorationSerializableState, IEnhanceModelDeltaDecoration } from '../../model/enhanceDecorationsCollection';
|
|
24
|
-
import { InlineDiffService } from '../inline-diff';
|
|
25
26
|
|
|
26
27
|
import styles from './inline-stream-diff.module.less';
|
|
27
28
|
import { InlineStreamDiffService } from './inline-stream-diff.service';
|
|
@@ -31,8 +32,6 @@ import {
|
|
|
31
32
|
ActiveLineDecoration,
|
|
32
33
|
AddedRangeDecoration,
|
|
33
34
|
AddedRangeDecorationsCollection,
|
|
34
|
-
EPartialEdit,
|
|
35
|
-
IPartialEditEvent,
|
|
36
35
|
IPartialEditWidgetOptions,
|
|
37
36
|
IRemovedWidgetState,
|
|
38
37
|
IRemovedZoneWidgetOptions,
|
|
@@ -66,8 +65,8 @@ export class LivePreviewDiffDecorationModel extends Disposable {
|
|
|
66
65
|
@Autowired(InlineStreamDiffService)
|
|
67
66
|
private readonly inlineStreamDiffService: InlineStreamDiffService;
|
|
68
67
|
|
|
69
|
-
@Autowired(
|
|
70
|
-
private readonly inlineDiffService:
|
|
68
|
+
@Autowired(InlineDiffServiceToken)
|
|
69
|
+
private readonly inlineDiffService: IInlineDiffService;
|
|
71
70
|
|
|
72
71
|
@Autowired(IMessageService)
|
|
73
72
|
private readonly messageService: IMessageService;
|
|
@@ -537,15 +536,15 @@ export class LivePreviewDiffDecorationModel extends Disposable {
|
|
|
537
536
|
}
|
|
538
537
|
|
|
539
538
|
public acceptUnProcessed(): void {
|
|
540
|
-
const
|
|
541
|
-
|
|
539
|
+
const pendingWidgets = this.partialEditWidgetList.filter((widget) => widget.isPending);
|
|
540
|
+
pendingWidgets.forEach((widget) => {
|
|
542
541
|
this.handlePartialEditAction(EPartialEdit.accept, widget, false);
|
|
543
542
|
});
|
|
544
543
|
}
|
|
545
544
|
|
|
546
545
|
public discardUnProcessed(): void {
|
|
547
|
-
const
|
|
548
|
-
|
|
546
|
+
const pendingWidgets = this.partialEditWidgetList.filter((widget) => widget.isPending);
|
|
547
|
+
pendingWidgets.forEach((widget) => {
|
|
549
548
|
this.handlePartialEditAction(EPartialEdit.discard, widget, false);
|
|
550
549
|
});
|
|
551
550
|
}
|
package/src/common/index.ts
CHANGED
|
@@ -16,7 +16,7 @@ import { DESIGN_MENUBAR_CONTAINER_VIEW_ID } from '@opensumi/ide-design/lib/commo
|
|
|
16
16
|
import { IPosition, ITextModel, InlineCompletionContext } from '@opensumi/ide-monaco/lib/common';
|
|
17
17
|
|
|
18
18
|
import { MCPServerDescription } from './mcp-server-manager';
|
|
19
|
-
import { MCPTool } from './types';
|
|
19
|
+
import { IPartialEditEvent, MCPTool } from './types';
|
|
20
20
|
|
|
21
21
|
import type { CoreMessage } from 'ai';
|
|
22
22
|
|
|
@@ -37,7 +37,7 @@ export const AI_CHAT_LOGO_AVATAR_ID = 'AI-Chat-Logo-Avatar';
|
|
|
37
37
|
export const AI_MENU_BAR_DEBUG_TOOLBAR = 'AI_MENU_BAR_DEBUG_TOOLBAR';
|
|
38
38
|
|
|
39
39
|
// 内置 MCP 服务器名称
|
|
40
|
-
export const BUILTIN_MCP_SERVER_NAME = '
|
|
40
|
+
export const BUILTIN_MCP_SERVER_NAME = 'builtin';
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
* @deprecated Use {@link DESIGN_MENUBAR_CONTAINER_VIEW_ID} instead
|
|
@@ -309,3 +309,10 @@ export interface IAIInlineCompletionsProvider {
|
|
|
309
309
|
): Promise<T>;
|
|
310
310
|
setVisibleCompletion(arg0: boolean): void;
|
|
311
311
|
}
|
|
312
|
+
|
|
313
|
+
export interface IInlineDiffService {
|
|
314
|
+
onPartialEdit: Event<IPartialEditEvent>;
|
|
315
|
+
firePartialEdit(event: IPartialEditEvent): void;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export const InlineDiffServiceToken = Symbol('InlineDiffService');
|
|
@@ -42,15 +42,11 @@ ${context.recentlyViewFiles.map((file, idx) => ` ${idx + 1}: ${file}`).join('
|
|
|
42
42
|
`,
|
|
43
43
|
)}
|
|
44
44
|
</attached_files>
|
|
45
|
-
${
|
|
46
|
-
currentModel
|
|
47
|
-
? `<current_opened_file>
|
|
45
|
+
${currentModel ? `<current_opened_file>
|
|
48
46
|
\`\`\`${currentModel.languageId} ${currentModel.uri.toString()}
|
|
49
47
|
${currentModel.getText()}
|
|
50
48
|
\`\`\`
|
|
51
|
-
</current_opened_file>`
|
|
52
|
-
: ''
|
|
53
|
-
}
|
|
49
|
+
</current_opened_file>` : ''}
|
|
54
50
|
</additional_data>
|
|
55
51
|
<user_query>
|
|
56
52
|
${userMessage}
|