@opensumi/ide-ai-native 3.9.1-next-1748435481.0 → 3.9.1-next-1748523870.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 (36) hide show
  1. package/lib/browser/ai-core.contribution.d.ts.map +1 -1
  2. package/lib/browser/ai-core.contribution.js +4 -12
  3. package/lib/browser/ai-core.contribution.js.map +1 -1
  4. package/lib/browser/chat/apply.service.d.ts +3 -0
  5. package/lib/browser/chat/apply.service.d.ts.map +1 -1
  6. package/lib/browser/chat/apply.service.js +47 -0
  7. package/lib/browser/chat/apply.service.js.map +1 -1
  8. package/lib/browser/chat/chat.feature.registry.d.ts +4 -1
  9. package/lib/browser/chat/chat.feature.registry.d.ts.map +1 -1
  10. package/lib/browser/chat/chat.feature.registry.js +6 -0
  11. package/lib/browser/chat/chat.feature.registry.js.map +1 -1
  12. package/lib/browser/chat/chat.view.d.ts.map +1 -1
  13. package/lib/browser/chat/chat.view.js +22 -1
  14. package/lib/browser/chat/chat.view.js.map +1 -1
  15. package/lib/browser/layout/ai-layout.js +3 -3
  16. package/lib/browser/layout/ai-layout.js.map +1 -1
  17. package/lib/browser/layout/tabbar.view.d.ts +1 -1
  18. package/lib/browser/layout/tabbar.view.d.ts.map +1 -1
  19. package/lib/browser/layout/tabbar.view.js +12 -5
  20. package/lib/browser/layout/tabbar.view.js.map +1 -1
  21. package/lib/browser/mcp/base-apply.service.d.ts +3 -2
  22. package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
  23. package/lib/browser/mcp/base-apply.service.js +23 -5
  24. package/lib/browser/mcp/base-apply.service.js.map +1 -1
  25. package/lib/browser/types.d.ts +8 -1
  26. package/lib/browser/types.d.ts.map +1 -1
  27. package/lib/browser/types.js.map +1 -1
  28. package/package.json +24 -24
  29. package/src/browser/ai-core.contribution.ts +4 -17
  30. package/src/browser/chat/apply.service.ts +62 -1
  31. package/src/browser/chat/chat.feature.registry.ts +17 -1
  32. package/src/browser/chat/chat.view.tsx +21 -3
  33. package/src/browser/layout/ai-layout.tsx +4 -4
  34. package/src/browser/layout/tabbar.view.tsx +23 -10
  35. package/src/browser/mcp/base-apply.service.ts +30 -9
  36. package/src/browser/types.ts +12 -0
@@ -1,5 +1,5 @@
1
1
  import cls from 'classnames';
2
- import React, { useCallback, useMemo } from 'react';
2
+ import React, { useCallback, useEffect, useMemo } from 'react';
3
3
 
4
4
  import {
5
5
  ComponentRegistryInfo,
@@ -29,18 +29,25 @@ import {
29
29
  TabbarViewBase,
30
30
  } from '@opensumi/ide-main-layout/lib/browser/tabbar/bar.view';
31
31
  import { BaseTabPanelView, ContainerView } from '@opensumi/ide-main-layout/lib/browser/tabbar/panel.view';
32
- import { TabRendererBase } from '@opensumi/ide-main-layout/lib/browser/tabbar/renderer.view';
32
+ import { TabRendererBase, TabbarConfig } from '@opensumi/ide-main-layout/lib/browser/tabbar/renderer.view';
33
33
  import { TabbarService, TabbarServiceFactory } from '@opensumi/ide-main-layout/lib/browser/tabbar/tabbar.service';
34
34
 
35
35
  import { AI_CHAT_VIEW_ID } from '../../common';
36
36
 
37
37
  import styles from './layout.module.less';
38
38
 
39
- const ChatTabbarRenderer: React.FC = () => (
40
- <div style={{ width: 0 }}>
41
- <TabbarViewBase tabSize={0} MoreTabView={IconElipses} TabView={IconTabView} barSize={0} panelBorderSize={1} />
42
- </div>
43
- );
39
+ const ChatTabbarRenderer: React.FC = () => {
40
+ const { side } = React.useContext(TabbarConfig);
41
+ const tabbarService: TabbarService = useInjectable(TabbarServiceFactory)(side);
42
+ useEffect(() => {
43
+ tabbarService.setIsLatter(true);
44
+ }, [tabbarService]);
45
+ return (
46
+ <div style={{ width: 0 }}>
47
+ <TabbarViewBase tabSize={0} MoreTabView={IconElipses} TabView={IconTabView} barSize={0} panelBorderSize={1} />
48
+ </div>
49
+ );
50
+ };
44
51
 
45
52
  export const AIChatTabRenderer = ({
46
53
  className,
@@ -103,7 +110,7 @@ export const AILeftTabRenderer = ({
103
110
  const AILeftTabbarRenderer: React.FC = () => {
104
111
  const layoutService = useInjectable<IMainLayoutService>(IMainLayoutService);
105
112
 
106
- const tabbarService: TabbarService = useInjectable(TabbarServiceFactory)(SlotLocation.extendView);
113
+ const tabbarService: TabbarService = useInjectable(TabbarServiceFactory)(SlotLocation.right);
107
114
  const currentContainerId = useAutorun(tabbarService.currentContainerId);
108
115
 
109
116
  const extraMenus = React.useMemo(() => layoutService.getExtraMenu(), [layoutService]);
@@ -147,8 +154,14 @@ const AILeftTabbarRenderer: React.FC = () => {
147
154
  );
148
155
  };
149
156
 
150
- export const AIRightTabRenderer = ({ components }: { className: string; components: ComponentRegistryInfo[] }) => {
151
- const tabbarService: TabbarService = useInjectable(TabbarServiceFactory)(SlotLocation.extendView);
157
+ export const AIRightTabRenderer = ({
158
+ className,
159
+ components,
160
+ }: {
161
+ className: string;
162
+ components: ComponentRegistryInfo[];
163
+ }) => {
164
+ const tabbarService: TabbarService = useInjectable(TabbarServiceFactory)(SlotLocation.right);
152
165
  const designLayoutConfig = useInjectable<DesignLayoutConfig>(DesignLayoutConfig);
153
166
 
154
167
  const handleClose = useCallback(() => {
@@ -63,6 +63,8 @@ export abstract class BaseApplyService extends WithEventBus {
63
63
 
64
64
  private currentSessionId?: string;
65
65
 
66
+ protected abstract postApplyHandler(editor: ICodeEditor): Promise<void>;
67
+
66
68
  constructor() {
67
69
  super();
68
70
  this.addDispose(
@@ -313,10 +315,26 @@ export abstract class BaseApplyService extends WithEventBus {
313
315
  );
314
316
  codeBlock.updatedCode = res.updatedCode;
315
317
  codeBlock.status = 'pending';
318
+
319
+ // apply 结果流式输出完成后,自动尝试修复代码中的 lint 错误
320
+ if (this.postApplyHandler && typeof this.postApplyHandler === 'function') {
321
+ try {
322
+ await this.postApplyHandler(result.group.codeEditor.monacoEditor);
323
+ } catch (error) {}
324
+ }
325
+
326
+ const textModel = result.group.codeEditor.monacoEditor.getModel();
327
+ const diagnosticInfos = this.getDiagnosticInfos(textModel!.uri.toString(), res.result?.rangesFromDiffHunk || []);
328
+
316
329
  // 用户实际接受的 apply 结果
317
- codeBlock.applyResult = res.result;
318
- this.updateCodeBlock(codeBlock);
330
+ if (res.result) {
331
+ codeBlock.applyResult = {
332
+ diff: res.result?.diff,
333
+ diagnosticInfos,
334
+ };
335
+ }
319
336
 
337
+ this.updateCodeBlock(codeBlock);
320
338
  return codeBlock;
321
339
  } catch (err) {
322
340
  codeBlock.status = 'failed';
@@ -336,8 +354,8 @@ export abstract class BaseApplyService extends WithEventBus {
336
354
  codeBlock: CodeBlockData,
337
355
  updatedContentOrStream: string | SumiReadableStream<IChatProgress>,
338
356
  range?: Range,
339
- ): Promise<{ result?: { diff: string; diagnosticInfos: IMarker[] }; updatedCode: string }> {
340
- const deferred = new Deferred<{ result?: { diff: string; diagnosticInfos: IMarker[] }; updatedCode: string }>();
357
+ ): Promise<{ result?: { diff: string; rangesFromDiffHunk: Range[] }; updatedCode: string }> {
358
+ const deferred = new Deferred<{ result?: { diff: string; rangesFromDiffHunk: Range[] }; updatedCode: string }>();
341
359
  const inlineDiffController = InlineDiffController.get(editor)!;
342
360
  range = range || editor.getModel()!.getFullModelRange();
343
361
 
@@ -373,7 +391,11 @@ export abstract class BaseApplyService extends WithEventBus {
373
391
 
374
392
  this.listenPartialEdit(editor.getModel()!, codeBlock).then((result) => {
375
393
  if (result) {
376
- codeBlock.applyResult = result;
394
+ const diagnosticInfos = this.getDiagnosticInfos(editor.getModel()!.uri.toString(), rangesFromDiffHunk);
395
+ codeBlock.applyResult = {
396
+ diff: result.diff,
397
+ diagnosticInfos,
398
+ };
377
399
  }
378
400
  this.updateCodeBlock(codeBlock);
379
401
  this.editorService.save(URI.file(path.join(this.appConfig.workspaceDir, codeBlock.relativePath)));
@@ -384,11 +406,10 @@ export abstract class BaseApplyService extends WithEventBus {
384
406
  updatedContent,
385
407
  codeBlock.relativePath,
386
408
  );
387
- const diagnosticInfos = this.getDiagnosticInfos(editor.getModel()!.uri.toString(), rangesFromDiffHunk);
388
409
  deferred.resolve({
389
410
  result: {
390
411
  diff,
391
- diagnosticInfos,
412
+ rangesFromDiffHunk,
392
413
  },
393
414
  updatedCode: updatedContent,
394
415
  });
@@ -534,7 +555,7 @@ export abstract class BaseApplyService extends WithEventBus {
534
555
  }
535
556
 
536
557
  protected listenPartialEdit(model: ITextModel, codeBlock: CodeBlockData) {
537
- const deferred = new Deferred<{ diff: string; diagnosticInfos: IMarker[] }>();
558
+ const deferred = new Deferred<{ diff: string; rangesFromDiffHunk: Range[] }>();
538
559
  const uriString = model.uri.toString();
539
560
  const toDispose = this.inlineDiffService.onPartialEdit((event) => {
540
561
  if (
@@ -574,7 +595,7 @@ export abstract class BaseApplyService extends WithEventBus {
574
595
  });
575
596
  deferred.resolve({
576
597
  diff,
577
- diagnosticInfos,
598
+ rangesFromDiffHunk,
578
599
  });
579
600
  } else {
580
601
  // 用户全部取消
@@ -5,6 +5,7 @@ import { ZodSchema } from 'zod';
5
5
  import { AIActionItem } from '@opensumi/ide-core-browser/lib/components/ai-native/index';
6
6
  import {
7
7
  CancellationToken,
8
+ ChatMessageRole,
8
9
  ChatResponse,
9
10
  Deferred,
10
11
  IAICompletionOption,
@@ -134,6 +135,8 @@ export interface IChatFeatureRegistry {
134
135
  registerImageUploadProvider(provider: IImageUploadProvider): void;
135
136
  registerWelcome(content: IChatWelcomeMessageContent | React.ReactNode, sampleQuestions?: ISampleQuestions[]): void;
136
137
  registerSlashCommand(command: IChatSlashCommandItem, handler: IChatSlashCommandHandler): void;
138
+
139
+ registerMessageSummaryProvider(provider: IMessageSummaryProvider): void;
137
140
  }
138
141
 
139
142
  export type ChatWelcomeRender = (props: {
@@ -298,6 +301,15 @@ export interface IImageUploadProvider {
298
301
  imageUpload(file: File): Promise<DataContent | URL>;
299
302
  }
300
303
 
304
+ export interface IMessageSummaryProvider {
305
+ getMessageSummary(
306
+ messages: Array<{
307
+ role: ChatMessageRole;
308
+ content: string;
309
+ }>,
310
+ ): Promise<string | undefined>;
311
+ }
312
+
301
313
  export const AINativeCoreContribution = Symbol('AINativeCoreContribution');
302
314
 
303
315
  export interface AINativeCoreContribution {