@opensumi/ide-ai-native 3.8.1-next-1741164072.0 → 3.8.1-next-1741180711.0

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.
Files changed (66) hide show
  1. package/lib/browser/ai-core.contribution.d.ts.map +1 -1
  2. package/lib/browser/ai-core.contribution.js +1 -3
  3. package/lib/browser/ai-core.contribution.js.map +1 -1
  4. package/lib/browser/chat/chat-agent.service.d.ts +2 -3
  5. package/lib/browser/chat/chat-agent.service.d.ts.map +1 -1
  6. package/lib/browser/chat/chat-agent.service.js.map +1 -1
  7. package/lib/browser/chat/chat-manager.service.d.ts +1 -0
  8. package/lib/browser/chat/chat-manager.service.d.ts.map +1 -1
  9. package/lib/browser/chat/chat-manager.service.js +2 -8
  10. package/lib/browser/chat/chat-manager.service.js.map +1 -1
  11. package/lib/browser/chat/chat-model.d.ts +4 -1
  12. package/lib/browser/chat/chat-model.d.ts.map +1 -1
  13. package/lib/browser/chat/chat-model.js +54 -0
  14. package/lib/browser/chat/chat-model.js.map +1 -1
  15. package/lib/browser/chat/chat-proxy.service.d.ts.map +1 -1
  16. package/lib/browser/chat/chat-proxy.service.js +2 -3
  17. package/lib/browser/chat/chat-proxy.service.js.map +1 -1
  18. package/lib/browser/chat/chat.api.service.d.ts +1 -2
  19. package/lib/browser/chat/chat.api.service.d.ts.map +1 -1
  20. package/lib/browser/chat/chat.api.service.js +0 -4
  21. package/lib/browser/chat/chat.api.service.js.map +1 -1
  22. package/lib/browser/chat/chat.internal.service.d.ts +0 -2
  23. package/lib/browser/chat/chat.internal.service.d.ts.map +1 -1
  24. package/lib/browser/chat/chat.internal.service.js +0 -3
  25. package/lib/browser/chat/chat.internal.service.js.map +1 -1
  26. package/lib/browser/components/components.module.less +0 -2
  27. package/lib/browser/mcp/base-apply.service.d.ts +5 -8
  28. package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
  29. package/lib/browser/mcp/base-apply.service.js +76 -81
  30. package/lib/browser/mcp/base-apply.service.js.map +1 -1
  31. package/lib/browser/model/msg-history-manager.d.ts +1 -2
  32. package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
  33. package/lib/browser/model/msg-history-manager.js +1 -10
  34. package/lib/browser/model/msg-history-manager.js.map +1 -1
  35. package/lib/browser/widget/inline-chat/inline-chat-controller.d.ts.map +1 -1
  36. package/lib/browser/widget/inline-chat/inline-chat-controller.js +1 -6
  37. package/lib/browser/widget/inline-chat/inline-chat-controller.js.map +1 -1
  38. package/lib/browser/widget/inline-diff/inline-diff-manager.js +1 -1
  39. package/lib/browser/widget/inline-diff/inline-diff-manager.js.map +1 -1
  40. package/lib/browser/widget/inline-diff/inline-diff-widget.module.less +3 -3
  41. package/lib/common/index.d.ts +4 -3
  42. package/lib/common/index.d.ts.map +1 -1
  43. package/lib/common/index.js.map +1 -1
  44. package/lib/common/types.d.ts +0 -1
  45. package/lib/common/types.d.ts.map +1 -1
  46. package/lib/node/base-language-model.d.ts +3 -3
  47. package/lib/node/base-language-model.d.ts.map +1 -1
  48. package/lib/node/base-language-model.js +1 -21
  49. package/lib/node/base-language-model.js.map +1 -1
  50. package/package.json +23 -23
  51. package/src/browser/ai-core.contribution.ts +1 -4
  52. package/src/browser/chat/chat-agent.service.ts +2 -2
  53. package/src/browser/chat/chat-manager.service.ts +4 -8
  54. package/src/browser/chat/chat-model.ts +59 -6
  55. package/src/browser/chat/chat-proxy.service.ts +6 -5
  56. package/src/browser/chat/chat.api.service.ts +1 -5
  57. package/src/browser/chat/chat.internal.service.ts +0 -4
  58. package/src/browser/components/components.module.less +0 -2
  59. package/src/browser/mcp/base-apply.service.ts +84 -89
  60. package/src/browser/model/msg-history-manager.ts +1 -11
  61. package/src/browser/widget/inline-chat/inline-chat-controller.ts +1 -5
  62. package/src/browser/widget/inline-diff/inline-diff-manager.tsx +1 -1
  63. package/src/browser/widget/inline-diff/inline-diff-widget.module.less +3 -3
  64. package/src/common/index.ts +6 -3
  65. package/src/common/types.ts +0 -1
  66. package/src/node/base-language-model.ts +3 -24
@@ -69,17 +69,7 @@ export abstract class BaseApplyService extends WithEventBus {
69
69
  super();
70
70
  this.addDispose(
71
71
  this.chatInternalService.onCancelRequest(() => {
72
- const currentMessageId = this.chatInternalService.sessionModel.history.lastMessageId;
73
- if (!currentMessageId) {
74
- return;
75
- }
76
- const codeBlockMap = this.getMessageCodeBlocks(currentMessageId);
77
- if (!codeBlockMap) {
78
- return;
79
- }
80
- Object.values(codeBlockMap).forEach((blockData) => {
81
- this.cancelApply(blockData);
82
- });
72
+ this.cancelAllApply();
83
73
  }),
84
74
  );
85
75
  this.currentSessionId = this.chatInternalService.sessionModel.sessionId;
@@ -104,11 +94,6 @@ export abstract class BaseApplyService extends WithEventBus {
104
94
  });
105
95
  }),
106
96
  );
107
- this.addDispose(
108
- this.chatInternalService.onWillClearSession((sessionId) => {
109
- this.cancelAllApply(sessionId);
110
- }),
111
- );
112
97
  }
113
98
 
114
99
  private getMessageCodeBlocks(
@@ -124,6 +109,27 @@ export abstract class BaseApplyService extends WithEventBus {
124
109
  return message?.codeBlockMap;
125
110
  }
126
111
 
112
+ private getSessionCodeBlocksForPath(relativePath: string, sessionId?: string) {
113
+ sessionId = sessionId || this.chatInternalService.sessionModel.sessionId;
114
+ const sessionModel = this.chatInternalService.getSession(sessionId);
115
+ if (!sessionModel) {
116
+ throw new Error(`Session ${sessionId} not found`);
117
+ }
118
+ const sessionAdditionals = sessionModel.history.sessionAdditionals;
119
+ const codeBlocks: CodeBlockData[] = Array.from(sessionAdditionals.values())
120
+ .map((additional) => additional.codeBlockMap as { [toolCallId: string]: CodeBlockData })
121
+ .reduce((acc, cur) => {
122
+ Object.values(cur).forEach((block) => {
123
+ if (block.relativePath === relativePath) {
124
+ acc.push(block);
125
+ }
126
+ });
127
+ return acc;
128
+ }, [] as CodeBlockData[])
129
+ .sort((a, b) => b.version - a.version);
130
+ return codeBlocks;
131
+ }
132
+
127
133
  private activePreviewerMap = this.registerDispose(
128
134
  new DisposableMap<string, BaseInlineDiffPreviewer<BaseInlineStreamDiffHandler>>(),
129
135
  );
@@ -150,9 +156,10 @@ export abstract class BaseApplyService extends WithEventBus {
150
156
  ) {
151
157
  return;
152
158
  }
153
- const filePendingApplies =
154
- this.getUriCodeBlocks(event.payload.resource.uri)?.filter((block) => block.status === 'pending') || [];
155
- // 使用最后一个版本内容渲染 apply 内容
159
+ const filePendingApplies = Object.values(
160
+ this.getMessageCodeBlocks(this.chatInternalService.sessionModel.history.lastMessageId!) || {},
161
+ ).filter((block) => block.relativePath === relativePath && block.status === 'pending');
162
+ // TODO: 刷新后重新应用,事件无法恢复 & 恢复继续请求,需要改造成批量apply形式
156
163
  if (filePendingApplies.length > 0 && filePendingApplies[0].updatedCode) {
157
164
  const editor = event.payload.group.codeEditor.monacoEditor;
158
165
  this.renderApplyResult(editor, filePendingApplies[0], filePendingApplies[0].updatedCode);
@@ -167,23 +174,23 @@ export abstract class BaseApplyService extends WithEventBus {
167
174
  return this.activePreviewerMap.get(path.relative(this.appConfig.workspaceDir, currentUri.path.toString()));
168
175
  }
169
176
 
170
- /**
171
- * 获取指定uri的 code block,按version降序排序
172
- */
173
- getUriCodeBlocks(uri: URI): CodeBlockData[] | undefined {
174
- const sessionCodeBlocks = this.getSessionCodeBlocks();
175
- const relativePath = path.relative(this.appConfig.workspaceDir, uri.path.toString());
176
- return sessionCodeBlocks
177
- .filter((block) => block.relativePath === relativePath)
178
- .sort((a, b) => b.version - a.version);
177
+ getUriPendingCodeBlock(uri: URI): CodeBlockData | undefined {
178
+ const messageId = this.chatInternalService.sessionModel.history.lastMessageId;
179
+ if (!messageId) {
180
+ return undefined;
181
+ }
182
+ const codeBlockMap = this.getMessageCodeBlocks(messageId);
183
+ if (!codeBlockMap) {
184
+ return undefined;
185
+ }
186
+ return Object.values(codeBlockMap).find(
187
+ (block) =>
188
+ block.relativePath === path.relative(this.appConfig.workspaceDir, uri.path.toString()) &&
189
+ block.status === 'pending',
190
+ );
179
191
  }
180
192
 
181
193
  getPendingPaths(sessionId?: string): string[] {
182
- const sessionCodeBlocks = this.getSessionCodeBlocks(sessionId);
183
- return sessionCodeBlocks.filter((block) => block.status === 'pending').map((block) => block.relativePath);
184
- }
185
-
186
- protected getSessionCodeBlocks(sessionId?: string) {
187
194
  sessionId = sessionId || this.chatInternalService.sessionModel.sessionId;
188
195
  const sessionModel = this.chatInternalService.getSession(sessionId);
189
196
  if (!sessionModel) {
@@ -191,13 +198,15 @@ export abstract class BaseApplyService extends WithEventBus {
191
198
  }
192
199
  const sessionAdditionals = sessionModel.history.sessionAdditionals;
193
200
  return Array.from(sessionAdditionals.values())
194
- .map((additional) => (additional.codeBlockMap || {}) as { [toolCallId: string]: CodeBlockData })
201
+ .map((additional) => additional.codeBlockMap as { [toolCallId: string]: CodeBlockData })
195
202
  .reduce((acc, cur) => {
196
203
  Object.values(cur).forEach((block) => {
197
- acc.push(block);
204
+ if (block.status === 'pending' && !acc.includes(block.relativePath)) {
205
+ acc.push(block.relativePath);
206
+ }
198
207
  });
199
208
  return acc;
200
- }, [] as CodeBlockData[]);
209
+ }, [] as string[]);
201
210
  }
202
211
 
203
212
  getCodeBlock(toolCallId: string, messageId?: string): CodeBlockData | undefined {
@@ -212,8 +221,11 @@ export abstract class BaseApplyService extends WithEventBus {
212
221
  return codeBlockMap[toolCallId];
213
222
  }
214
223
 
215
- protected updateCodeBlock(codeBlock: CodeBlockData) {
216
- const messageId = codeBlock.messageId;
224
+ protected updateCodeBlock(codeBlock: CodeBlockData, messageId?: string) {
225
+ messageId = messageId || this.chatInternalService.sessionModel.history.lastMessageId;
226
+ if (!messageId) {
227
+ throw new Error('Message ID is required');
228
+ }
217
229
  const codeBlockMap = this.getMessageCodeBlocks(messageId);
218
230
  if (!codeBlockMap) {
219
231
  throw new Error('Code block not found');
@@ -227,7 +239,7 @@ export abstract class BaseApplyService extends WithEventBus {
227
239
 
228
240
  async registerCodeBlock(relativePath: string, content: string, toolCallId: string): Promise<CodeBlockData> {
229
241
  const lastMessageId = this.chatInternalService.sessionModel.history.lastMessageId!;
230
- const uriCodeBlocks = this.getUriCodeBlocks(URI.file(path.join(this.appConfig.workspaceDir, relativePath)));
242
+ const savedCodeBlockMap = this.getMessageCodeBlocks(lastMessageId) || {};
231
243
  const originalModelRef = await this.editorDocumentModelService.createModelReference(
232
244
  URI.file(path.join(this.appConfig.workspaceDir, relativePath)),
233
245
  );
@@ -239,13 +251,13 @@ export abstract class BaseApplyService extends WithEventBus {
239
251
  version: 1,
240
252
  createdAt: Date.now(),
241
253
  toolCallId,
242
- messageId: lastMessageId,
243
254
  // TODO: 支持range
244
255
  originalCode: originalModelRef.instance.getText(),
245
256
  };
246
- if (uriCodeBlocks?.length) {
247
- newBlock.version = uriCodeBlocks.length;
248
- for (const block of uriCodeBlocks) {
257
+ const samePathCodeBlocks = Object.values(savedCodeBlockMap).filter((block) => block.relativePath === relativePath);
258
+ if (samePathCodeBlocks.length > 0) {
259
+ newBlock.version = samePathCodeBlocks.length;
260
+ for (const block of samePathCodeBlocks.sort((a, b) => a.version - b.version)) {
249
261
  // 如果连续的上一个同文件apply结果存在LintError,则iterationCount++
250
262
  if (block.relativePath === relativePath && block.applyResult?.diagnosticInfos?.length) {
251
263
  newBlock.iterationCount++;
@@ -254,7 +266,6 @@ export abstract class BaseApplyService extends WithEventBus {
254
266
  }
255
267
  }
256
268
  }
257
- const savedCodeBlockMap = this.getMessageCodeBlocks(lastMessageId) || {};
258
269
  savedCodeBlockMap[toolCallId] = newBlock;
259
270
  this.chatInternalService.sessionModel.history.setMessageAdditional(lastMessageId, {
260
271
  codeBlockMap: savedCodeBlockMap,
@@ -285,9 +296,9 @@ export abstract class BaseApplyService extends WithEventBus {
285
296
  }
286
297
 
287
298
  if (this.activePreviewerMap.has(codeBlock.relativePath)) {
288
- // 有正在进行的 apply,则取消(但不更新block状态,只清理副作用)
289
- this.cancelApply(codeBlock, true);
299
+ this.activePreviewerMap.disposeKey(codeBlock.relativePath);
290
300
  }
301
+ // FIXME: 同一个bubble单个文件多次写入(如迭代)兼容
291
302
  // trigger diffPreivewer & return expected diff result directly
292
303
  const result = await this.editorService.open(
293
304
  URI.file(path.join(this.appConfig.workspaceDir, codeBlock.relativePath)),
@@ -295,11 +306,6 @@ export abstract class BaseApplyService extends WithEventBus {
295
306
  if (!result) {
296
307
  throw new Error('Failed to open file');
297
308
  }
298
- if (typeof fastApplyFileResult.result === 'string') {
299
- codeBlock.updatedCode = fastApplyFileResult.result;
300
- codeBlock.status = 'pending';
301
- this.updateCodeBlock(codeBlock);
302
- }
303
309
  const applyResult = await this.renderApplyResult(
304
310
  result.group.codeEditor.monacoEditor,
305
311
  codeBlock,
@@ -334,14 +340,16 @@ export abstract class BaseApplyService extends WithEventBus {
334
340
 
335
341
  if (typeof updatedContentOrStream === 'string') {
336
342
  const editorCurrentContent = editor.getModel()!.getValue();
337
- const uri = URI.file(path.join(this.appConfig.workspaceDir, codeBlock.relativePath));
338
- const document = this.editorDocumentModelService.getModelReference(uri);
343
+ const document = this.editorDocumentModelService.getModelReference(
344
+ URI.file(path.join(this.appConfig.workspaceDir, codeBlock.relativePath)),
345
+ );
339
346
  if (editorCurrentContent !== updatedContentOrStream || document?.instance.dirty) {
340
347
  editor.getModel()?.pushEditOperations([], [EditOperation.replace(range, updatedContentOrStream)], () => null);
341
- await this.editorService.save(uri);
348
+ await this.editorService.save(URI.file(path.join(this.appConfig.workspaceDir, codeBlock.relativePath)));
342
349
  }
343
- const uriPendingCodeBlocks = this.getUriCodeBlocks(uri)?.filter((block) => block.status === 'pending');
344
- const earlistPendingCodeBlock = uriPendingCodeBlocks?.[uriPendingCodeBlocks.length - 1];
350
+ const earlistPendingCodeBlock = this.getSessionCodeBlocksForPath(codeBlock.relativePath).find(
351
+ (block) => block.status === 'pending',
352
+ );
345
353
  if ((earlistPendingCodeBlock?.originalCode || codeBlock.originalCode) === updatedContentOrStream) {
346
354
  codeBlock.status = 'cancelled';
347
355
  this.updateCodeBlock(codeBlock);
@@ -359,6 +367,9 @@ export abstract class BaseApplyService extends WithEventBus {
359
367
  },
360
368
  ) as LiveInlineDiffPreviewer;
361
369
  this.activePreviewerMap.set(codeBlock.relativePath, previewer);
370
+ codeBlock.updatedCode = updatedContentOrStream;
371
+ codeBlock.status = 'pending';
372
+ this.updateCodeBlock(codeBlock);
362
373
  // 新建文件场景,为避免model为空,加一个空行
363
374
  previewer.setValue(earlistPendingCodeBlock?.originalCode || codeBlock.originalCode || '\n');
364
375
  // 强刷展示 manager 视图
@@ -374,7 +385,7 @@ export abstract class BaseApplyService extends WithEventBus {
374
385
 
375
386
  const { diff, rangesFromDiffHunk } = this.getDiffResult(
376
387
  codeBlock.originalCode,
377
- codeBlock.updatedCode || updatedContentOrStream,
388
+ codeBlock.updatedCode,
378
389
  codeBlock.relativePath,
379
390
  );
380
391
  const diagnosticInfos = this.getDiagnosticInfos(editor.getModel()!.uri.toString(), rangesFromDiffHunk);
@@ -394,17 +405,6 @@ export abstract class BaseApplyService extends WithEventBus {
394
405
  renderRemovedWidgetImmediately: false,
395
406
  },
396
407
  }) as LiveInlineDiffPreviewer;
397
-
398
- this.addDispose(
399
- controller.onError((err) => {
400
- deferred.reject(err);
401
- }),
402
- );
403
- this.addDispose(
404
- controller.onAbort(() => {
405
- deferred.reject(new Error('Apply aborted'));
406
- }),
407
- );
408
408
  this.addDispose(
409
409
  // 流式输出结束后,转为直接输出逻辑
410
410
  previewer.getNode()!.onDiffFinished(async (diffModel) => {
@@ -418,7 +418,6 @@ export abstract class BaseApplyService extends WithEventBus {
418
418
  deferred.resolve();
419
419
  return;
420
420
  }
421
- codeBlock.status = 'pending';
422
421
  this.updateCodeBlock(codeBlock);
423
422
  previewer.dispose();
424
423
  const result = await this.renderApplyResult(editor, codeBlock, codeBlock.updatedCode);
@@ -433,12 +432,8 @@ export abstract class BaseApplyService extends WithEventBus {
433
432
  /**
434
433
  * Cancel an ongoing apply operation
435
434
  */
436
- cancelApply(blockData: CodeBlockData, keepStatus?: boolean): void {
435
+ cancelApply(blockData: CodeBlockData): void {
437
436
  if (blockData.status === 'generating' || blockData.status === 'pending') {
438
- // 先取消掉相关的监听器
439
- this.editorListenerMap.disposeKey(
440
- URI.file(path.join(this.appConfig.workspaceDir, blockData.relativePath)).toString(),
441
- );
442
437
  if (this.activePreviewerMap.has(blockData.relativePath)) {
443
438
  this.activePreviewerMap
444
439
  .get(blockData.relativePath)
@@ -446,16 +441,19 @@ export abstract class BaseApplyService extends WithEventBus {
446
441
  ?.livePreviewDiffDecorationModel.discardUnProcessed();
447
442
  this.activePreviewerMap.disposeKey(blockData.relativePath);
448
443
  }
449
- if (!keepStatus) {
450
- blockData.status = 'cancelled';
451
- this.updateCodeBlock(blockData);
452
- }
444
+ blockData.status = 'cancelled';
445
+ this.updateCodeBlock(blockData);
453
446
  }
454
447
  }
455
448
 
456
- cancelAllApply(sessionId?: string): void {
457
- const sessionCodeBlocks = this.getSessionCodeBlocks(sessionId);
458
- sessionCodeBlocks.forEach((blockData) => {
449
+ // TODO: 目前的设计下,有一个工具 apply 没返回,是不会触发下一个的(cursor 是会全部自动 apply 的),所以这个方法目前还没有必要
450
+ cancelAllApply(): void {
451
+ const messageId = this.chatInternalService.sessionModel.history.lastMessageId!;
452
+ const codeBlockMap = this.getMessageCodeBlocks(messageId);
453
+ if (!codeBlockMap) {
454
+ return;
455
+ }
456
+ Object.values(codeBlockMap).forEach((blockData) => {
459
457
  this.cancelApply(blockData);
460
458
  });
461
459
  }
@@ -478,12 +476,12 @@ export abstract class BaseApplyService extends WithEventBus {
478
476
  }
479
477
 
480
478
  processAll(uri: URI, type: 'accept' | 'reject'): void {
481
- const codeBlocks = this.getUriCodeBlocks(uri)?.filter((block) => block.status === 'pending');
482
- if (!codeBlocks?.length) {
479
+ const codeBlock = this.getUriPendingCodeBlock(uri);
480
+ if (!codeBlock) {
483
481
  throw new Error('No pending code block found');
484
482
  }
485
483
  const decorationModel = this.activePreviewerMap
486
- .get(codeBlocks[0].relativePath)
484
+ .get(codeBlock.relativePath)
487
485
  ?.getNode()?.livePreviewDiffDecorationModel;
488
486
  if (!decorationModel) {
489
487
  throw new Error('No active previewer found');
@@ -494,11 +492,8 @@ export abstract class BaseApplyService extends WithEventBus {
494
492
  decorationModel.discardUnProcessed();
495
493
  }
496
494
  this.editorService.save(uri);
497
- codeBlocks.forEach((codeBlock) => {
498
- codeBlock.status = type === 'accept' ? 'success' : 'cancelled';
499
- // TODO: 批量更新
500
- this.updateCodeBlock(codeBlock);
501
- });
495
+ codeBlock.status = type === 'accept' ? 'success' : 'cancelled';
496
+ this.updateCodeBlock(codeBlock);
502
497
  }
503
498
 
504
499
  protected listenPartialEdit(model: ITextModel, codeBlock: CodeBlockData) {
@@ -57,11 +57,6 @@ export class MsgHistoryManager extends Disposable {
57
57
 
58
58
  private startIndex = 0;
59
59
 
60
- private get totalTokens(): number {
61
- const list = this.messageList.slice(this.startIndex);
62
- return list.reduce((acc, msg) => acc + (msg.content.length || 0), 0) / 3;
63
- }
64
-
65
60
  public get slicedMessageCount(): number {
66
61
  return this.startIndex;
67
62
  }
@@ -71,12 +66,7 @@ export class MsgHistoryManager extends Disposable {
71
66
  return list[list.length - 1]?.id;
72
67
  }
73
68
 
74
- public getMessages(maxTokens?: number): IHistoryChatMessage[] {
75
- if (maxTokens && this.totalTokens > maxTokens) {
76
- while (this.totalTokens > maxTokens) {
77
- this.startIndex++;
78
- }
79
- }
69
+ public getMessages(): IHistoryChatMessage[] {
80
70
  return this.messageList.slice(this.startIndex);
81
71
  }
82
72
 
@@ -83,11 +83,7 @@ export class InlineChatController {
83
83
  this._onData.fire(reply);
84
84
  },
85
85
  onEnd: () => {
86
- if (!wholeContent) {
87
- this._onError.fire(new ErrorResponse(new Error('No content')));
88
- } else {
89
- this._onEnd.fire();
90
- }
86
+ this._onEnd.fire();
91
87
  },
92
88
  onError: (error) => {
93
89
  if (AbortError.is(error)) {
@@ -29,7 +29,7 @@ export const InlineDiffManager: React.FC<{ resource: IResource }> = (props) => {
29
29
  const [show, setShow] = useState(true);
30
30
  const [changesCount, setChangesCount] = useState(0);
31
31
  const [currentChangeIndex, setCurrentChangeIndex] = useState(0);
32
- const [filePaths, setFilePaths] = useState<string[]>(applyService.getPendingPaths());
32
+ const [filePaths, setFilePaths] = useState<string[]>([]);
33
33
 
34
34
  const currentFilePath = useMemo(
35
35
  () => path.relative(appConfig.workspaceDir, resource.uri.path.toString()),
@@ -22,7 +22,7 @@
22
22
 
23
23
  .inlineDiffManager {
24
24
  display: flex;
25
- border-radius: 14px;
25
+ border-radius: 13px;
26
26
  align-items: center;
27
27
  position: absolute;
28
28
  bottom: 18px;
@@ -38,7 +38,7 @@
38
38
  border-right: 1px solid var(--design-borderColor);
39
39
  }
40
40
  :global(.codicon) {
41
- font-size: 16px;
41
+ font-size: 20px;
42
42
  padding: 6px;
43
43
  color: var(--kt-primaryButton-foreground);
44
44
  background-color: var(--kt-primaryButton-hoverBackground);
@@ -48,7 +48,7 @@
48
48
  }
49
49
  }
50
50
  .disabled {
51
- color: var(--kt-button-disableForeground) !important;
51
+ // color: var(--kt-button-disableForeground) !important;
52
52
  background-color: var(--kt-button-disableBackground) !important;
53
53
  cursor: not-allowed;
54
54
  }
@@ -12,13 +12,16 @@ import {
12
12
  IMarkdownString,
13
13
  Uri,
14
14
  } from '@opensumi/ide-core-common';
15
- import { IChatMessage } from '@opensumi/ide-core-common/lib/types/ai-native';
16
15
  import { DESIGN_MENUBAR_CONTAINER_VIEW_ID } from '@opensumi/ide-design/lib/common/constants';
17
16
  import { IPosition, ITextModel, InlineCompletionContext } from '@opensumi/ide-monaco/lib/common';
18
17
 
19
18
  import { MCPServerDescription } from './mcp-server-manager';
20
19
  import { MCPTool } from './types';
21
20
 
21
+ import type { CoreMessage } from 'ai';
22
+
23
+ export type { CoreMessage };
24
+
22
25
  export * from './model';
23
26
 
24
27
  export const IAINativeService = Symbol('IAINativeService');
@@ -146,7 +149,7 @@ export interface IChatAgentService {
146
149
  id: string,
147
150
  request: IChatAgentRequest,
148
151
  progress: (part: IChatProgress) => void,
149
- history: IChatMessage[],
152
+ history: CoreMessage[],
150
153
  token: CancellationToken,
151
154
  ): Promise<IChatAgentResult>;
152
155
  getAgents(): Array<IChatAgent>;
@@ -167,7 +170,7 @@ export interface IChatAgent extends IChatAgentData {
167
170
  invoke(
168
171
  request: IChatAgentRequest,
169
172
  progress: (part: IChatProgress) => void,
170
- history: IChatMessage[],
173
+ history: CoreMessage[],
171
174
  token: CancellationToken,
172
175
  ): Promise<IChatAgentResult>;
173
176
  provideFollowups?(sessionId: string, token: CancellationToken): Promise<IChatFollowup[]>;
@@ -50,7 +50,6 @@ export interface MCPTool {
50
50
  }
51
51
 
52
52
  export interface CodeBlockData {
53
- messageId: string;
54
53
  toolCallId: string;
55
54
  codeEdit: string;
56
55
  originalCode: string;
@@ -1,7 +1,7 @@
1
1
  import { CoreMessage, ToolExecutionOptions, jsonSchema, streamText, tool } from 'ai';
2
2
 
3
3
  import { Autowired, Injectable } from '@opensumi/di';
4
- import { ChatMessageRole, IAIBackServiceOption, IChatMessage } from '@opensumi/ide-core-common';
4
+ import { IAIBackServiceOption } from '@opensumi/ide-core-common';
5
5
  import { ChatReadableStream } from '@opensumi/ide-core-node';
6
6
  import { CancellationToken } from '@opensumi/ide-utils';
7
7
 
@@ -21,21 +21,6 @@ export abstract class BaseLanguageModel {
21
21
 
22
22
  protected abstract initializeProvider(options: IAIBackServiceOption): any;
23
23
 
24
- private convertChatMessageRole(role: ChatMessageRole) {
25
- switch (role) {
26
- case ChatMessageRole.System:
27
- return 'system';
28
- case ChatMessageRole.User:
29
- return 'user';
30
- case ChatMessageRole.Assistant:
31
- return 'assistant';
32
- case ChatMessageRole.Function:
33
- return 'tool';
34
- default:
35
- return 'user';
36
- }
37
- }
38
-
39
24
  async request(
40
25
  request: string,
41
26
  chatReadableStream: ChatReadableStream,
@@ -86,7 +71,7 @@ export abstract class BaseLanguageModel {
86
71
  request: string,
87
72
  tools: ToolRequest[],
88
73
  chatReadableStream: ChatReadableStream,
89
- history: IChatMessage[] = [],
74
+ history: CoreMessage[] = [],
90
75
  modelId?: string,
91
76
  providerOptions?: Record<string, any>,
92
77
  trimTexts?: [string, string],
@@ -104,13 +89,7 @@ export abstract class BaseLanguageModel {
104
89
  });
105
90
  }
106
91
 
107
- const messages: CoreMessage[] = [
108
- ...history.map((msg) => ({
109
- role: this.convertChatMessageRole(msg.role) as any, // 这个 SDK 包里的类型不太好完全对应,
110
- content: msg.content,
111
- })),
112
- { role: 'user', content: request },
113
- ];
92
+ const messages: CoreMessage[] = [...history, { role: 'user', content: request }];
114
93
  const modelInfo = modelId ? this.getModelInfo(modelId) : undefined;
115
94
  const stream = streamText({
116
95
  model: this.getModelIdentifier(provider, modelId),