@opensumi/ide-ai-native 3.8.1-next-1740726474.0 → 3.8.1-next-1740735952.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 (127) hide show
  1. package/lib/browser/ai-core.contribution.d.ts +1 -4
  2. package/lib/browser/ai-core.contribution.d.ts.map +1 -1
  3. package/lib/browser/ai-core.contribution.js +1 -20
  4. package/lib/browser/ai-core.contribution.js.map +1 -1
  5. package/lib/browser/chat/chat-manager.service.d.ts +0 -6
  6. package/lib/browser/chat/chat-manager.service.d.ts.map +1 -1
  7. package/lib/browser/chat/chat-manager.service.js +1 -31
  8. package/lib/browser/chat/chat-manager.service.js.map +1 -1
  9. package/lib/browser/chat/chat-model.d.ts +0 -2
  10. package/lib/browser/chat/chat-model.d.ts.map +1 -1
  11. package/lib/browser/chat/chat-model.js +2 -8
  12. package/lib/browser/chat/chat-model.js.map +1 -1
  13. package/lib/browser/chat/chat.internal.service.d.ts +0 -1
  14. package/lib/browser/chat/chat.internal.service.d.ts.map +1 -1
  15. package/lib/browser/chat/chat.internal.service.js +0 -3
  16. package/lib/browser/chat/chat.internal.service.js.map +1 -1
  17. package/lib/browser/chat/chat.module.less +2 -1
  18. package/lib/browser/chat/chat.view.d.ts.map +1 -1
  19. package/lib/browser/chat/chat.view.js +38 -6
  20. package/lib/browser/chat/chat.view.js.map +1 -1
  21. package/lib/browser/components/ChatContext/index.js +2 -2
  22. package/lib/browser/components/ChatContext/index.js.map +1 -1
  23. package/lib/browser/components/ChatHistory.d.ts +1 -0
  24. package/lib/browser/components/ChatHistory.d.ts.map +1 -1
  25. package/lib/browser/components/ChatHistory.js +14 -14
  26. package/lib/browser/components/ChatHistory.js.map +1 -1
  27. package/lib/browser/components/ChatInput.d.ts.map +1 -1
  28. package/lib/browser/components/ChatInput.js +1 -25
  29. package/lib/browser/components/ChatInput.js.map +1 -1
  30. package/lib/browser/components/ChatToolRender.d.ts.map +1 -1
  31. package/lib/browser/components/ChatToolRender.js +3 -2
  32. package/lib/browser/components/ChatToolRender.js.map +1 -1
  33. package/lib/browser/components/{chat-history.module.less → chat-history.css} +1 -1
  34. package/lib/browser/components/components.module.less +0 -20
  35. package/lib/browser/context/llm-context.service.d.ts +5 -16
  36. package/lib/browser/context/llm-context.service.d.ts.map +1 -1
  37. package/lib/browser/context/llm-context.service.js +47 -78
  38. package/lib/browser/context/llm-context.service.js.map +1 -1
  39. package/lib/browser/layout/layout.module.less +4 -4
  40. package/lib/browser/mcp/base-apply.service.d.ts +40 -31
  41. package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
  42. package/lib/browser/mcp/base-apply.service.js +167 -233
  43. package/lib/browser/mcp/base-apply.service.js.map +1 -1
  44. package/lib/browser/mcp/tools/components/EditFile.d.ts.map +1 -1
  45. package/lib/browser/mcp/tools/components/EditFile.js +41 -55
  46. package/lib/browser/mcp/tools/components/EditFile.js.map +1 -1
  47. package/lib/browser/mcp/tools/components/index.module.less +3 -23
  48. package/lib/browser/mcp/tools/createNewFileWithText.d.ts.map +1 -1
  49. package/lib/browser/mcp/tools/createNewFileWithText.js +0 -1
  50. package/lib/browser/mcp/tools/createNewFileWithText.js.map +1 -1
  51. package/lib/browser/mcp/tools/editFile.js +1 -1
  52. package/lib/browser/mcp/tools/editFile.js.map +1 -1
  53. package/lib/browser/mcp/tools/getDiagnosticsByPath.d.ts.map +1 -1
  54. package/lib/browser/mcp/tools/getDiagnosticsByPath.js +0 -1
  55. package/lib/browser/mcp/tools/getDiagnosticsByPath.js.map +1 -1
  56. package/lib/browser/mcp/tools/handlers/EditFile.d.ts +1 -5
  57. package/lib/browser/mcp/tools/handlers/EditFile.d.ts.map +1 -1
  58. package/lib/browser/mcp/tools/handlers/EditFile.js +4 -4
  59. package/lib/browser/mcp/tools/handlers/EditFile.js.map +1 -1
  60. package/lib/browser/mcp/tools/handlers/RunCommand.d.ts.map +1 -1
  61. package/lib/browser/mcp/tools/handlers/RunCommand.js +0 -2
  62. package/lib/browser/mcp/tools/handlers/RunCommand.js.map +1 -1
  63. package/lib/browser/mcp/tools/runTerminalCmd.d.ts.map +1 -1
  64. package/lib/browser/mcp/tools/runTerminalCmd.js +0 -1
  65. package/lib/browser/mcp/tools/runTerminalCmd.js.map +1 -1
  66. package/lib/browser/model/msg-history-manager.d.ts +0 -1
  67. package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
  68. package/lib/browser/model/msg-history-manager.js +2 -12
  69. package/lib/browser/model/msg-history-manager.js.map +1 -1
  70. package/lib/browser/types.d.ts +1 -1
  71. package/lib/browser/types.d.ts.map +1 -1
  72. package/lib/browser/widget/inline-diff/inline-diff-widget.module.less +0 -12
  73. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts +0 -2
  74. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts.map +1 -1
  75. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js +4 -11
  76. package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js.map +1 -1
  77. package/lib/common/llm-context.d.ts +9 -12
  78. package/lib/common/llm-context.d.ts.map +1 -1
  79. package/lib/common/llm-context.js.map +1 -1
  80. package/lib/common/prompts/context-prompt-provider.d.ts +3 -4
  81. package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -1
  82. package/lib/common/prompts/context-prompt-provider.js +22 -33
  83. package/lib/common/prompts/context-prompt-provider.js.map +1 -1
  84. package/lib/common/types.d.ts +0 -17
  85. package/lib/common/types.d.ts.map +1 -1
  86. package/lib/common/types.js.map +1 -1
  87. package/lib/node/base-language-model.d.ts +1 -1
  88. package/lib/node/base-language-model.d.ts.map +1 -1
  89. package/lib/node/base-language-model.js +3 -54
  90. package/lib/node/base-language-model.js.map +1 -1
  91. package/package.json +23 -23
  92. package/src/browser/ai-core.contribution.ts +1 -25
  93. package/src/browser/chat/chat-manager.service.ts +1 -29
  94. package/src/browser/chat/chat-model.ts +3 -18
  95. package/src/browser/chat/chat.internal.service.ts +0 -4
  96. package/src/browser/chat/chat.module.less +2 -1
  97. package/src/browser/chat/chat.view.tsx +70 -7
  98. package/src/browser/components/ChatContext/index.tsx +2 -2
  99. package/src/browser/components/ChatHistory.tsx +15 -21
  100. package/src/browser/components/ChatInput.tsx +4 -67
  101. package/src/browser/components/ChatToolRender.tsx +2 -1
  102. package/src/browser/components/{chat-history.module.less → chat-history.css} +1 -1
  103. package/src/browser/components/components.module.less +0 -20
  104. package/src/browser/context/llm-context.service.ts +54 -90
  105. package/src/browser/layout/layout.module.less +4 -4
  106. package/src/browser/mcp/base-apply.service.ts +213 -266
  107. package/src/browser/mcp/tools/components/EditFile.tsx +60 -82
  108. package/src/browser/mcp/tools/components/index.module.less +3 -23
  109. package/src/browser/mcp/tools/createNewFileWithText.ts +0 -1
  110. package/src/browser/mcp/tools/editFile.ts +2 -2
  111. package/src/browser/mcp/tools/getDiagnosticsByPath.ts +0 -1
  112. package/src/browser/mcp/tools/handlers/EditFile.ts +4 -4
  113. package/src/browser/mcp/tools/handlers/RunCommand.ts +0 -2
  114. package/src/browser/mcp/tools/runTerminalCmd.ts +0 -1
  115. package/src/browser/model/msg-history-manager.ts +2 -12
  116. package/src/browser/types.ts +1 -1
  117. package/src/browser/widget/inline-diff/inline-diff-widget.module.less +0 -12
  118. package/src/browser/widget/inline-stream-diff/inline-stream-diff.handler.tsx +4 -13
  119. package/src/common/llm-context.ts +4 -10
  120. package/src/common/prompts/context-prompt-provider.ts +29 -38
  121. package/src/common/types.ts +0 -20
  122. package/src/node/base-language-model.ts +1 -63
  123. package/lib/browser/widget/inline-diff/inline-diff-manager.d.ts +0 -6
  124. package/lib/browser/widget/inline-diff/inline-diff-manager.d.ts.map +0 -1
  125. package/lib/browser/widget/inline-diff/inline-diff-manager.js +0 -27
  126. package/lib/browser/widget/inline-diff/inline-diff-manager.js.map +0 -1
  127. package/src/browser/widget/inline-diff/inline-diff-manager.tsx +0 -38
@@ -1,5 +1,5 @@
1
1
  import cls from 'classnames';
2
- import React, { useEffect, useMemo, useState } from 'react';
2
+ import React, { useEffect, useMemo } from 'react';
3
3
 
4
4
  import { Icon, Popover } from '@opensumi/ide-components';
5
5
  import {
@@ -10,6 +10,7 @@ import {
10
10
  Uri,
11
11
  detectModeId,
12
12
  path,
13
+ useAutorun,
13
14
  useInjectable,
14
15
  } from '@opensumi/ide-core-browser';
15
16
  import { Loading } from '@opensumi/ide-core-browser/lib/components/ai-native';
@@ -17,24 +18,61 @@ import { ILanguageService } from '@opensumi/monaco-editor-core/esm/vs/editor/com
17
18
  import { IModelService } from '@opensumi/monaco-editor-core/esm/vs/editor/common/services/model';
18
19
  import { StandaloneServices } from '@opensumi/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices';
19
20
 
20
- import { CodeBlockData } from '../../../../common/types';
21
21
  import { ChatMarkdown } from '../../../components/ChatMarkdown';
22
22
  import { IMCPServerToolComponentProps } from '../../../types';
23
- import { BaseApplyService } from '../../base-apply.service';
23
+ import { BaseApplyService, CodeBlockData } from '../../base-apply.service';
24
24
 
25
25
  import styles from './index.module.less';
26
26
 
27
+ const renderStatus = (codeBlockData: CodeBlockData) => {
28
+ const status = codeBlockData.status;
29
+ switch (status) {
30
+ case 'generating':
31
+ return <Loading />;
32
+ case 'pending':
33
+ return (
34
+ <Popover title={status} id={'edit-file-tool-status-pending'}>
35
+ <Icon iconClass='codicon codicon-circle-large' />
36
+ </Popover>
37
+ );
38
+ case 'success':
39
+ return (
40
+ <Popover title={status} id={'edit-file-tool-status-success'}>
41
+ <Icon iconClass='codicon codicon-check-all' />
42
+ </Popover>
43
+ );
44
+ case 'failed':
45
+ return (
46
+ <Popover title={status} id={'edit-file-tool-status-failed'}>
47
+ <Icon iconClass='codicon codicon-error' color='var(--vscode-input-errorForeground)' />
48
+ </Popover>
49
+ );
50
+ case 'cancelled':
51
+ return (
52
+ <Popover title={status} id={'edit-file-tool-status-cancelled'}>
53
+ <Icon iconClass='codicon codicon-close' color='var(--vscode-input-placeholderForeground)' />
54
+ </Popover>
55
+ );
56
+ default:
57
+ return null;
58
+ }
59
+ };
60
+
27
61
  export const EditFileToolComponent = (props: IMCPServerToolComponentProps) => {
28
62
  const { args, messageId, toolCallId } = props;
29
- const [mode, setMode] = useState<'code' | 'diff'>('code');
30
63
  const labelService = useInjectable(LabelService);
31
64
  const appConfig = useInjectable<AppConfig>(AppConfig);
32
65
  const applyService = useInjectable<BaseApplyService>(BaseApplyService);
33
66
  const { target_file = '', code_edit, instructions } = args || {};
34
67
  const absolutePath = path.join(appConfig.workspaceDir, target_file);
35
- const [codeBlockData, setCodeBlockData] = useState<CodeBlockData | undefined>(
36
- applyService.getCodeBlock(toolCallId, messageId),
37
- );
68
+
69
+ const codeBlockData = applyService.getCodeBlock(absolutePath, messageId);
70
+
71
+ useAutorun(applyService.codeBlockMapObservable);
72
+
73
+ if (toolCallId && codeBlockData) {
74
+ applyService.initToolCallId(codeBlockData.id, toolCallId);
75
+ }
38
76
 
39
77
  const icon = useMemo(() => {
40
78
  if (!target_file) {
@@ -53,66 +91,40 @@ export const EditFileToolComponent = (props: IMCPServerToolComponentProps) => {
53
91
  return detectedModeId;
54
92
  }, [target_file, absolutePath]);
55
93
 
56
- useEffect(() => {
57
- const disposable = applyService.onCodeBlockUpdate((codeBlockData) => {
58
- setCodeBlockData({ ...codeBlockData });
59
- });
60
- return () => {
61
- disposable.dispose();
62
- };
63
- }, []);
64
-
65
94
  // 多次迭代时,仅在首处tool组件中展示
66
- // FIXME: 这个优化有必要吗?每次都展示也挺好?
67
- if (!args || !codeBlockData) {
95
+ if (!args || !codeBlockData || (toolCallId && toolCallId !== codeBlockData.initToolCallId)) {
68
96
  return null;
69
97
  }
70
98
 
71
99
  return [
72
100
  instructions && <p>{instructions}</p>,
73
- <div className={styles['edit-file-tool']} key={'edit-file-tool'}>
101
+ <div className={styles['edit-file-tool']} key={`edit-file-tool-${codeBlockData.id}`}>
74
102
  <div
75
103
  className={cls(styles['edit-file-tool-header'], {
76
104
  clickable: codeBlockData.status === 'pending' || codeBlockData.status === 'success',
77
105
  })}
78
106
  onClick={() => {
79
107
  if (codeBlockData.status === 'pending') {
80
- applyService.renderApplyResult(codeBlockData, codeBlockData.updatedCode!);
108
+ applyService.reRenderPendingApply();
81
109
  } else if (codeBlockData.status === 'success') {
82
- applyService.revealApplyPosition(codeBlockData);
110
+ applyService.revealApplyPosition(codeBlockData.id);
83
111
  }
84
112
  }}
85
113
  >
86
- <div className={styles.left}>
87
- {icon && <span className={icon}></span>}
88
- <span className={styles['edit-file-tool-file-name']}>{target_file}</span>
89
- {codeBlockData.iterationCount > 1 && (
90
- <span className={styles['edit-file-tool-iteration-count']}>{codeBlockData.iterationCount}/3</span>
91
- )}
92
- {renderStatus(codeBlockData)}
93
- </div>
94
- <div className={styles.right}>
95
- <Popover title={'Show Code'} id={'edit-file-tool-show-code'}>
96
- <Icon iconClass='codicon codicon-file-code' onClick={() => setMode('code')} />
97
- </Popover>
98
- {codeBlockData.applyResult?.diff && (
99
- <Popover title={'Show Diff'} id={'edit-file-tool-show-diff'}>
100
- <Icon iconClass='codicon codicon-diff-multiple' onClick={() => setMode('diff')} />
101
- </Popover>
102
- )}
103
- </div>
114
+ {icon && <span className={icon}></span>}
115
+ <span className={styles['edit-file-tool-file-name']}>{target_file}</span>
116
+ {codeBlockData.iterationCount > 1 && (
117
+ <span className={styles['edit-file-tool-iteration-count']}>{codeBlockData.iterationCount}/3</span>
118
+ )}
119
+ {renderStatus(codeBlockData)}
104
120
  </div>
105
- <ChatMarkdown
106
- markdown={
107
- mode === 'code'
108
- ? `\`\`\`${languageId || ''}\n${code_edit}\n\`\`\``
109
- : `\`\`\`diff\n${codeBlockData.applyResult?.diff}\n\`\`\``
110
- }
111
- hideInsert={true}
112
- />
121
+ <ChatMarkdown markdown={`\`\`\`${languageId || ''}\n${code_edit}\n\`\`\``} hideInsert={true} />
113
122
  </div>,
114
123
  codeBlockData.applyResult && codeBlockData.applyResult.diagnosticInfos.length > 0 && (
115
- <div className={styles['edit-file-tool-diagnostic-errors']} key={'edit-file-tool-diagnostic-errors'}>
124
+ <div
125
+ className={styles['edit-file-tool-diagnostic-errors']}
126
+ key={`edit-file-tool-diagnostic-errors-${codeBlockData.id}`}
127
+ >
116
128
  <div className={styles['title']}>Found Lints:</div>
117
129
  {codeBlockData.applyResult?.diagnosticInfos.map((info) => (
118
130
  <div
@@ -130,37 +142,3 @@ export const EditFileToolComponent = (props: IMCPServerToolComponentProps) => {
130
142
  ),
131
143
  ];
132
144
  };
133
-
134
- const renderStatus = (codeBlockData: CodeBlockData) => {
135
- const status = codeBlockData.status;
136
- switch (status) {
137
- case 'generating':
138
- return <Loading />;
139
- case 'pending':
140
- return (
141
- <Popover title='Pending' id={'edit-file-tool-status-pending'}>
142
- <Icon iconClass='codicon codicon-circle-large' />
143
- </Popover>
144
- );
145
- case 'success':
146
- return (
147
- <Popover title='Success' id={'edit-file-tool-status-success'}>
148
- <Icon iconClass='codicon codicon-check-all' />
149
- </Popover>
150
- );
151
- case 'failed':
152
- return (
153
- <Popover title='Failed' id={'edit-file-tool-status-failed'}>
154
- <Icon iconClass='codicon codicon-error' style={{ color: 'var(--debugConsole-errorForeground)' }} />
155
- </Popover>
156
- );
157
- case 'cancelled':
158
- return (
159
- <Popover title='Cancelled' id={'edit-file-tool-status-cancelled'}>
160
- <Icon iconClass='codicon codicon-close' style={{ color: 'var(--input-placeholderForeground)' }} />
161
- </Popover>
162
- );
163
- default:
164
- return null;
165
- }
166
- };
@@ -1,14 +1,15 @@
1
1
  .edit-file-tool-header {
2
2
  display: flex;
3
3
  align-items: center;
4
- justify-content: space-between;
5
4
  padding: 2px 8px;
6
5
  border-bottom: 1px solid var(--vscode-commandCenter-inactiveBorder);
7
6
  background-color: var(--design-block-background);
8
7
  font-size: 10px;
9
8
  margin-bottom: -4px;
10
9
  border-radius: 8px 8px 0 0;
11
- white-space: nowrap;
10
+ > span {
11
+ margin-right: 4px;
12
+ }
12
13
  :global(span.codicon) {
13
14
  font-size: 12px;
14
15
  }
@@ -17,26 +18,6 @@
17
18
  align-items: center;
18
19
  justify-content: center;
19
20
  }
20
- .left,
21
- .right {
22
- display: flex;
23
- align-items: center;
24
- }
25
- &::after {
26
- display: none;
27
- }
28
- .left {
29
- > span {
30
- margin-right: 4px;
31
- }
32
- }
33
- .right > div {
34
- margin-left: 4px;
35
- }
36
- }
37
- .edit-file-tool-file-name {
38
- text-overflow: ellipsis;
39
- overflow: hidden;
40
21
  }
41
22
  .edit-file-tool {
42
23
  border: 1px solid var(--vscode-commandCenter-inactiveBorder);
@@ -154,7 +135,6 @@
154
135
  background-color: var(--design-chatInput-background);
155
136
  padding: 10px;
156
137
  border-radius: 4px;
157
- margin: 10px 0px;
158
138
 
159
139
  .command_title {
160
140
  display: flex;
@@ -27,7 +27,6 @@ export class CreateNewFileWithTextTool implements MCPServerContribution {
27
27
  getToolDefinition(): MCPToolDefinition {
28
28
  return {
29
29
  name: 'create_new_file_with_text',
30
- label: 'Create File',
31
30
  description:
32
31
  'Creates a new file at the specified path within the project directory and populates it with the provided text. ' +
33
32
  'Use this tool to generate new files in your project structure. ' +
@@ -69,8 +69,8 @@ You should specify the following arguments before the others: [target_file]`,
69
69
  };
70
70
  }
71
71
 
72
- private async handler(args: z.infer<typeof inputSchema> & { toolCallId: string }, logger: MCPLogger) {
73
- const result = await this.editFileHandler.handler(args, args.toolCallId);
72
+ private async handler(args: z.infer<typeof inputSchema>, logger: MCPLogger) {
73
+ const result = await this.editFileHandler.handler(args.targetFile, args.codeEdit, args.instructions);
74
74
  return {
75
75
  content: [
76
76
  {
@@ -29,7 +29,6 @@ export class GetDiagnosticsByPathTool implements MCPServerContribution {
29
29
  getToolDefinition(): MCPToolDefinition {
30
30
  return {
31
31
  name: 'get_diagnostics_by_path',
32
- label: 'Get Diagnostics',
33
32
  description:
34
33
  'Retrieves diagnostic information (errors, warnings, etc.) from a specific file in the project. ' +
35
34
  'Use this tool to get information about problems in any project file. ' +
@@ -12,10 +12,10 @@ export class EditFileHandler {
12
12
  @Autowired(BaseApplyService)
13
13
  private applyService: BaseApplyService;
14
14
 
15
- async handler(params: { targetFile: string; codeEdit: string; instructions?: string }, toolCallId: string) {
16
- const { targetFile, codeEdit } = params;
17
- const block = this.applyService.registerCodeBlock(targetFile, codeEdit, toolCallId);
18
- const blockData = await this.applyService.apply(block);
15
+ async handler(relativePath: string, updateContent: string, instructions?: string) {
16
+ // TODO: ignore file
17
+ this.applyService.registerCodeBlock(relativePath, updateContent);
18
+ const blockData = await this.applyService.apply(relativePath, updateContent, instructions);
19
19
  return blockData;
20
20
  }
21
21
  }
@@ -49,7 +49,6 @@ export class RunCommandHandler {
49
49
  }
50
50
 
51
51
  async handler(args: z.infer<typeof inputSchema> & { toolCallId: string }, logger: MCPLogger) {
52
- logger.appendLine(`Executing command: ${args.command}`);
53
52
  if (args.require_user_approval) {
54
53
  const def = new Deferred<boolean>();
55
54
  this.approvalDeferredMap.set(args.toolCallId, def);
@@ -90,7 +89,6 @@ export class RunCommandHandler {
90
89
  content: result,
91
90
  });
92
91
 
93
- logger.appendLine(`Command ${args.command} finished with exit code: ${e.code}`);
94
92
  terminalClient.term.writeln(
95
93
  `\n${color.italic}> Command ${args.command} executed successfully. Terminal will close in ${
96
94
  3000 / 1000
@@ -32,7 +32,6 @@ export class RunTerminalCommandTool implements MCPServerContribution {
32
32
  getToolDefinition(): MCPToolDefinition {
33
33
  return {
34
34
  name: 'run_terminal_cmd',
35
- label: 'Run Command',
36
35
  description:
37
36
  "PROPOSE a command to run on behalf of the user.\nIf you have this tool, note that you DO have the ability to run commands directly on the USER's system.\n\nAdhere to these rules:\n1. Based on the contents of the conversation, you will be told if you are in the same shell as a previous step or a new shell.\n2. If in a new shell, you should `cd` to the right directory and do necessary setup in addition to running the command.\n3. If in the same shell, the state will persist, no need to do things like `cd` to the same directory.\n4. For ANY commands that would use a pager, you should append ` | cat` to the command (or whatever is appropriate). You MUST do this for: git, less, head, tail, more, etc.\n5. For commands that are long running/expected to run indefinitely until interruption, please run them in the background. To run jobs in the background, set `is_background` to true rather than changing the details of the command.\n6. Dont include any newlines in the command.",
38
37
  inputSchema,
@@ -66,11 +66,6 @@ export class MsgHistoryManager extends Disposable {
66
66
  return this.startIndex;
67
67
  }
68
68
 
69
- public get lastMessageId(): string | undefined {
70
- const list = this.messageList;
71
- return list[list.length - 1]?.id;
72
- }
73
-
74
69
  public getMessages(maxTokens?: number): IHistoryChatMessage[] {
75
70
  if (maxTokens && this.totalTokens > maxTokens) {
76
71
  while (this.totalTokens > maxTokens) {
@@ -114,14 +109,9 @@ export class MsgHistoryManager extends Disposable {
114
109
  return;
115
110
  }
116
111
 
117
- const oldAdditional = this.messageAdditionalMap.get(id) || {};
118
- const newAdditional = {
119
- ...oldAdditional,
120
- ...additional,
121
- };
112
+ this.messageAdditionalMap.set(id, additional);
122
113
 
123
- this.messageAdditionalMap.set(id, newAdditional);
124
- this._onMessageAdditionalChange.fire(newAdditional);
114
+ this._onMessageAdditionalChange.fire(additional);
125
115
  }
126
116
 
127
117
  public getMessageAdditional(id: string): Record<string, any> {
@@ -368,7 +368,7 @@ export interface IMCPServerToolComponentProps {
368
368
  result?: any;
369
369
  index?: number;
370
370
  messageId?: string;
371
- toolCallId: string;
371
+ toolCallId?: string;
372
372
  }
373
373
 
374
374
  export interface IMCPServerRegistry {
@@ -19,15 +19,3 @@
19
19
  display: flex;
20
20
  position: relative;
21
21
  }
22
-
23
- .inlineDiffManager {
24
- display: flex;
25
- padding: 12px 16px;
26
- justify-content: center;
27
- position: absolute;
28
- bottom: 0;
29
- left: 50%;
30
- transform: translateX(-50%);
31
- gap: 12px;
32
- z-index: 999;
33
- }
@@ -52,9 +52,6 @@ export class InlineStreamDiffHandler extends Disposable implements IInlineDiffPr
52
52
  protected readonly _onDidEditChange = this.registerDispose(new Emitter<void>());
53
53
  public readonly onDidEditChange: Event<void> = this._onDidEditChange.event;
54
54
 
55
- protected readonly onDiffFinishedEmitter = this.registerDispose(new Emitter<IComputeDiffData>());
56
- public readonly onDiffFinished: Event<IComputeDiffData> = this.onDiffFinishedEmitter.event;
57
-
58
55
  public previewerOptions: IDiffPreviewerOptions;
59
56
 
60
57
  private originalModel: ITextModel;
@@ -448,8 +445,6 @@ export class InlineStreamDiffHandler extends Disposable implements IInlineDiffPr
448
445
  this.diffModel.set(currentDiffModel, tx);
449
446
  });
450
447
 
451
- this.onDiffFinishedEmitter.fire(currentDiffModel);
452
-
453
448
  if (this.originalModel.id === this.monacoEditor.getModel()?.id) {
454
449
  this.renderDiffEdits(currentDiffModel);
455
450
  }
@@ -476,13 +471,10 @@ export class InlineStreamDiffHandler extends Disposable implements IInlineDiffPr
476
471
  }
477
472
 
478
473
  public pushRateFinallyDiffStack(diffModel: IComputeDiffData): void {
479
- transaction((tx) => {
480
- this.finallyDiffModel.set(diffModel, tx);
481
- // 可能存在 rate editor controller 处理完之后接口层流式才结束
482
- if (this.isEditing === false) {
483
- this.finallyRender(diffModel);
484
- }
485
- });
474
+ // 可能存在 rate editor controller 处理完之后接口层流式才结束
475
+ if (this.isEditing === false) {
476
+ this.finallyRender(diffModel);
477
+ }
486
478
  }
487
479
 
488
480
  public finallyRender(diffModel: IComputeDiffData): void {
@@ -495,7 +487,6 @@ export class InlineStreamDiffHandler extends Disposable implements IInlineDiffPr
495
487
  return;
496
488
  }
497
489
 
498
- this.onDiffFinishedEmitter.fire(diffModel);
499
490
  this.renderPartialEditWidgets(diffModel);
500
491
  this.renderDiffEdits(diffModel);
501
492
  this.pushStackElement();
@@ -15,13 +15,13 @@ export interface LLMContextService {
15
15
  */
16
16
  cleanFileContext(): void;
17
17
 
18
- onDidContextFilesChangeEvent: Event<{ viewed: FileContext[]; attached: FileContext[] }>;
18
+ onDidContextFilesChangeEvent: Event<FileContext[]>;
19
19
 
20
20
  /**
21
21
  * 从 context 中移除文件
22
22
  * @param uri URI
23
23
  */
24
- removeFileFromContext(uri: URI, isManual?: boolean): void;
24
+ removeFileFromContext(uri: URI): void;
25
25
 
26
26
  /** 导出为可序列化格式 */
27
27
  serialize(): SerializedContext;
@@ -30,18 +30,12 @@ export interface LLMContextService {
30
30
  export interface FileContext {
31
31
  uri: URI;
32
32
  selection?: [number, number];
33
+ isManual: boolean;
33
34
  }
34
35
 
35
36
  export const LLMContextServiceToken = Symbol('LLMContextService');
36
37
 
37
- export interface AttachFileContext {
38
- content: string;
39
- lineErrors: string[];
40
- path: string;
41
- language: string;
42
- }
43
-
44
38
  export interface SerializedContext {
45
39
  recentlyViewFiles: string[];
46
- attachedFiles: Array<AttachFileContext>;
40
+ attachedFiles: Array<{ content: string; lineErrors: string[]; path: string; language: string }>;
47
41
  }
@@ -1,5 +1,5 @@
1
- import { Autowired, Injectable } from '@opensumi/di';
2
- import { WorkbenchEditorService } from '@opensumi/ide-editor/lib/common/editor';
1
+ import { Injectable } from '@opensumi/di';
2
+ import { MaybePromise } from '@opensumi/ide-core-common/lib/utils';
3
3
 
4
4
  import { SerializedContext } from '../llm-context';
5
5
 
@@ -10,46 +10,37 @@ export interface ChatAgentPromptProvider {
10
10
  * 提供上下文提示
11
11
  * @param context 上下文
12
12
  */
13
- provideContextPrompt(context: SerializedContext, userMessage: string): string;
13
+ provideContextPrompt(context: SerializedContext, userMessage: string): MaybePromise<string>;
14
14
  }
15
15
 
16
16
  @Injectable()
17
17
  export class DefaultChatAgentPromptProvider implements ChatAgentPromptProvider {
18
- @Autowired(WorkbenchEditorService)
19
- protected readonly workbenchEditorService: WorkbenchEditorService;
20
-
21
- provideContextPrompt(context: SerializedContext, userMessage: string): string {
22
- const editor = this.workbenchEditorService.currentEditor;
23
- const currentModel = editor?.currentDocumentModel;
18
+ provideContextPrompt(context: SerializedContext, userMessage: string): MaybePromise<string> {
24
19
  return `
25
- <additional_data>
26
- Below are some potentially helpful/relevant pieces of information for figuring out to respond
27
- <recently_viewed_files>
28
- ${context.recentlyViewFiles.map((file, idx) => ` ${idx + 1}: ${file}`).join('\n')}
29
- </recently_viewed_files>
30
- <attached_files>
31
- ${context.attachedFiles.map(
32
- (file) =>
33
- `
34
- <file_contents>
35
- \`\`\`${file.language} ${file.path}
36
- ${file.content}
37
- \`\`\`
38
- </file_contents>
39
- <linter_errors>
40
- ${file.lineErrors.join('\n')}
41
- </linter_errors>
42
- `,
43
- )}
44
- </attached_files>
45
- ${currentModel ? `<current_opened_file>
46
- \`\`\`${currentModel.languageId} ${currentModel.uri.toString()}
47
- ${currentModel.getText()}
48
- \`\`\`
49
- </current_opened_file>` : ''}
50
- </additional_data>
51
- <user_query>
52
- ${userMessage}
53
- </user_query>`;
20
+ <additional_data>
21
+ Below are some potentially helpful/relevant pieces of information for figuring out to respond
22
+ <recently_viewed_files>
23
+ ${context.recentlyViewFiles.map((file, idx) => `${idx + 1} : ${file}`)}
24
+ </recently_viewed_files>
25
+ <attached_files>
26
+ ${context.attachedFiles.map(
27
+ (file) =>
28
+ `
29
+ <file_contents>
30
+ \`\`\`${file.language} ${file.path}
31
+ ${file.content}
32
+ \`\`\`
33
+ </file_contents>
34
+ <linter_errors>
35
+ ${file.lineErrors.join('\n')}
36
+ </linter_errors>
37
+ `,
38
+ )}
39
+
40
+ </attached_files>
41
+ </additional_data>
42
+ <user_query>
43
+ ${userMessage}
44
+ </user_query>`;
54
45
  }
55
46
  }
@@ -1,5 +1,3 @@
1
- import { IMarker } from '@opensumi/ide-core-browser';
2
-
3
1
  export enum NearestCodeBlockType {
4
2
  Block = 'block',
5
3
  Line = 'line',
@@ -48,21 +46,3 @@ export interface MCPTool {
48
46
  inputSchema: any;
49
47
  providerName: string;
50
48
  }
51
-
52
- export interface CodeBlockData {
53
- toolCallId: string;
54
- codeEdit: string;
55
- updatedCode?: string;
56
- relativePath: string;
57
- status: CodeBlockStatus;
58
- iterationCount: number;
59
- createdAt: number;
60
- version: number;
61
- instructions?: string;
62
- applyResult?: {
63
- diff: string;
64
- diagnosticInfos: IMarker[];
65
- };
66
- }
67
-
68
- export type CodeBlockStatus = 'generating' | 'pending' | 'success' | 'rejected' | 'failed' | 'cancelled';
@@ -60,7 +60,6 @@ export abstract class BaseLanguageModel {
60
60
  options.topP,
61
61
  options.topK,
62
62
  options.providerOptions,
63
- options.trimTexts,
64
63
  cancellationToken,
65
64
  );
66
65
  }
@@ -88,7 +87,6 @@ export abstract class BaseLanguageModel {
88
87
  topP?: number,
89
88
  topK?: number,
90
89
  providerOptions?: Record<string, any>,
91
- trimTexts?: [string, string],
92
90
  cancellationToken?: CancellationToken,
93
91
  ): Promise<any> {
94
92
  try {
@@ -122,42 +120,9 @@ export abstract class BaseLanguageModel {
122
120
  providerOptions,
123
121
  });
124
122
 
125
- // 状态跟踪变量
126
- let isFirstChunk = true;
127
- let bufferedText = '';
128
- const pendingLines: string[] = [];
129
123
  for await (const chunk of stream.fullStream) {
130
124
  if (chunk.type === 'text-delta') {
131
- if (trimTexts?.length) {
132
- // 将收到的文本追加到缓冲区
133
- bufferedText += chunk.textDelta;
134
-
135
- // 处理第一个文本块的前缀(只处理一次)
136
- if (isFirstChunk && bufferedText.includes(trimTexts[0])) {
137
- bufferedText = bufferedText.substring(bufferedText.indexOf(trimTexts[0]) + trimTexts[0].length);
138
- isFirstChunk = false;
139
- }
140
-
141
- // 检查是否有完整的行,并将它们添加到待发送行队列
142
- const lines = bufferedText.split('\n');
143
-
144
- // 最后一个元素可能是不完整的行,保留在缓冲区
145
- bufferedText = lines.pop() || '';
146
-
147
- // 将完整的行添加到待发送队列
148
- if (lines.length > 0) {
149
- pendingLines.push(...lines);
150
- }
151
-
152
- // 发送除最后几行外的所有行(保留足够的行以处理后缀)
153
- while (pendingLines.length > 3) {
154
- // 保留最后3行以确保能完整识别后缀
155
- const lineToSend = pendingLines.shift() + '\n';
156
- chatReadableStream.emitData({ kind: 'content', content: lineToSend });
157
- }
158
- } else {
159
- chatReadableStream.emitData({ kind: 'content', content: chunk.textDelta });
160
- }
125
+ chatReadableStream.emitData({ kind: 'content', content: chunk.textDelta });
161
126
  } else if (chunk.type === 'tool-call') {
162
127
  chatReadableStream.emitData({
163
128
  kind: 'toolCall',
@@ -204,33 +169,6 @@ export abstract class BaseLanguageModel {
204
169
  }
205
170
  }
206
171
 
207
- if (trimTexts?.[1]) {
208
- // 完成处理所有块后,检查并发送剩余文本
209
-
210
- // 将剩余缓冲区加入待发送行
211
- if (bufferedText) {
212
- pendingLines.push(bufferedText);
213
- }
214
-
215
- // 处理最后一行可能存在的后缀
216
- if (pendingLines.length > 0) {
217
- let lastLine = pendingLines[pendingLines.length - 1];
218
-
219
- if (lastLine.endsWith(trimTexts[1])) {
220
- // 移除后缀
221
- lastLine = lastLine.substring(0, lastLine.length - trimTexts[1].length);
222
- pendingLines[pendingLines.length - 1] = lastLine;
223
- }
224
- }
225
-
226
- // 发送所有剩余的行
227
- for (let i = 0; i < pendingLines.length; i++) {
228
- const isLastLine = i === pendingLines.length - 1;
229
- const lineToSend = pendingLines[i] + (isLastLine ? '' : '\n');
230
- chatReadableStream.emitData({ kind: 'content', content: lineToSend });
231
- }
232
- }
233
-
234
172
  chatReadableStream.end();
235
173
  } catch (error) {
236
174
  // Use a logger service in production instead of console