@opensumi/ide-ai-native 3.8.3-next-1741685617.0 → 3.8.3-next-1741747748.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 (79) hide show
  1. package/lib/browser/chat/chat-agent.service.d.ts.map +1 -1
  2. package/lib/browser/chat/chat-agent.service.js +4 -4
  3. package/lib/browser/chat/chat-agent.service.js.map +1 -1
  4. package/lib/browser/chat/chat.view.d.ts.map +1 -1
  5. package/lib/browser/chat/chat.view.js +46 -16
  6. package/lib/browser/chat/chat.view.js.map +1 -1
  7. package/lib/browser/components/ChatMentionInput.d.ts +25 -0
  8. package/lib/browser/components/ChatMentionInput.d.ts.map +1 -0
  9. package/lib/browser/components/ChatMentionInput.js +221 -0
  10. package/lib/browser/components/ChatMentionInput.js.map +1 -0
  11. package/lib/browser/components/{ChatContext/ContextSelector.d.ts → chat-context/context-selector.d.ts} +1 -1
  12. package/lib/browser/components/chat-context/context-selector.d.ts.map +1 -0
  13. package/lib/browser/components/{ChatContext/ContextSelector.js → chat-context/context-selector.js} +1 -1
  14. package/lib/browser/components/chat-context/context-selector.js.map +1 -0
  15. package/lib/browser/components/chat-context/index.d.ts.map +1 -0
  16. package/lib/browser/components/{ChatContext → chat-context}/index.js +2 -2
  17. package/lib/browser/components/chat-context/index.js.map +1 -0
  18. package/lib/browser/components/components.module.less +1 -0
  19. package/lib/browser/components/mention-input/mention-input.d.ts +5 -0
  20. package/lib/browser/components/mention-input/mention-input.d.ts.map +1 -0
  21. package/lib/browser/components/mention-input/mention-input.js +734 -0
  22. package/lib/browser/components/mention-input/mention-input.js.map +1 -0
  23. package/lib/browser/components/mention-input/mention-input.module.less +309 -0
  24. package/lib/browser/components/mention-input/mention-item.d.ts +10 -0
  25. package/lib/browser/components/mention-input/mention-item.d.ts.map +1 -0
  26. package/lib/browser/components/mention-input/mention-item.js +16 -0
  27. package/lib/browser/components/mention-input/mention-item.js.map +1 -0
  28. package/lib/browser/components/mention-input/mention-panel.d.ts +15 -0
  29. package/lib/browser/components/mention-input/mention-panel.d.ts.map +1 -0
  30. package/lib/browser/components/mention-input/mention-panel.js +49 -0
  31. package/lib/browser/components/mention-input/mention-panel.js.map +1 -0
  32. package/lib/browser/components/mention-input/types.d.ts +74 -0
  33. package/lib/browser/components/mention-input/types.d.ts.map +1 -0
  34. package/lib/browser/components/mention-input/types.js +16 -0
  35. package/lib/browser/components/mention-input/types.js.map +1 -0
  36. package/lib/browser/context/llm-context.service.d.ts +10 -2
  37. package/lib/browser/context/llm-context.service.d.ts.map +1 -1
  38. package/lib/browser/context/llm-context.service.js +71 -2
  39. package/lib/browser/context/llm-context.service.js.map +1 -1
  40. package/lib/browser/mcp/config/components/mcp-config.view.d.ts.map +1 -1
  41. package/lib/browser/mcp/config/components/mcp-config.view.js +28 -18
  42. package/lib/browser/mcp/config/components/mcp-config.view.js.map +1 -1
  43. package/lib/browser/mcp/config/components/mcp-server-form.d.ts.map +1 -1
  44. package/lib/browser/mcp/config/components/mcp-server-form.js +33 -25
  45. package/lib/browser/mcp/config/components/mcp-server-form.js.map +1 -1
  46. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts.map +1 -1
  47. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js +10 -5
  48. package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js.map +1 -1
  49. package/lib/common/llm-context.d.ts +15 -1
  50. package/lib/common/llm-context.d.ts.map +1 -1
  51. package/lib/common/llm-context.js.map +1 -1
  52. package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -1
  53. package/lib/common/prompts/context-prompt-provider.js +23 -20
  54. package/lib/common/prompts/context-prompt-provider.js.map +1 -1
  55. package/package.json +23 -23
  56. package/src/browser/chat/chat-agent.service.ts +4 -4
  57. package/src/browser/chat/chat.view.tsx +47 -19
  58. package/src/browser/components/ChatMentionInput.tsx +267 -0
  59. package/src/browser/components/{ChatContext → chat-context}/index.tsx +1 -1
  60. package/src/browser/components/components.module.less +1 -0
  61. package/src/browser/components/mention-input/mention-input.module.less +309 -0
  62. package/src/browser/components/mention-input/mention-input.tsx +913 -0
  63. package/src/browser/components/mention-input/mention-item.tsx +24 -0
  64. package/src/browser/components/mention-input/mention-panel.tsx +89 -0
  65. package/src/browser/components/mention-input/types.ts +79 -0
  66. package/src/browser/context/llm-context.service.ts +83 -3
  67. package/src/browser/mcp/config/components/mcp-config.view.tsx +23 -12
  68. package/src/browser/mcp/config/components/mcp-server-form.tsx +68 -54
  69. package/src/browser/widget/inline-stream-diff/live-preview.decoration.tsx +9 -5
  70. package/src/common/llm-context.ts +16 -1
  71. package/src/common/prompts/context-prompt-provider.ts +26 -23
  72. package/lib/browser/components/ChatContext/ContextSelector.d.ts.map +0 -1
  73. package/lib/browser/components/ChatContext/ContextSelector.js.map +0 -1
  74. package/lib/browser/components/ChatContext/index.d.ts.map +0 -1
  75. package/lib/browser/components/ChatContext/index.js.map +0 -1
  76. /package/lib/browser/components/{ChatContext → chat-context}/index.d.ts +0 -0
  77. /package/lib/browser/components/{ChatContext → chat-context}/style.module.less +0 -0
  78. /package/src/browser/components/{ChatContext/ContextSelector.tsx → chat-context/context-selector.tsx} +0 -0
  79. /package/src/browser/components/{ChatContext → chat-context}/style.module.less +0 -0
@@ -1,15 +1,28 @@
1
1
  import { Event, URI } from '@opensumi/ide-core-common/lib/utils';
2
2
  export interface LLMContextService {
3
+ /**
4
+ * 开始自动收集
5
+ */
3
6
  startAutoCollection(): void;
7
+ /**
8
+ * 停止自动收集
9
+ */
4
10
  stopAutoCollection(): void;
5
11
  /**
6
12
  * 添加文件到 context 中
7
13
  */
8
14
  addFileToContext(uri: URI, selection?: [number, number], isManual?: boolean): void;
15
+ /**
16
+ * 添加文件夹到 context 中
17
+ */
18
+ addFolderToContext(uri: URI, isManual?: boolean): void;
9
19
  /**
10
20
  * 清除上下文
11
21
  */
12
22
  cleanFileContext(): void;
23
+ /**
24
+ * 上下文文件变化事件
25
+ */
13
26
  onDidContextFilesChangeEvent: Event<{
14
27
  viewed: FileContext[];
15
28
  attached: FileContext[];
@@ -21,7 +34,7 @@ export interface LLMContextService {
21
34
  */
22
35
  removeFileFromContext(uri: URI, isManual?: boolean): void;
23
36
  /** 导出为可序列化格式 */
24
- serialize(): SerializedContext;
37
+ serialize(): Promise<SerializedContext>;
25
38
  }
26
39
  export interface FileContext {
27
40
  uri: URI;
@@ -37,5 +50,6 @@ export interface AttachFileContext {
37
50
  export interface SerializedContext {
38
51
  recentlyViewFiles: string[];
39
52
  attachedFiles: Array<AttachFileContext>;
53
+ attachedFolders: string[];
40
54
  }
41
55
  //# sourceMappingURL=llm-context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"llm-context.d.ts","sourceRoot":"","sources":["../../src/common/llm-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAEjE,MAAM,WAAW,iBAAiB;IAChC,mBAAmB,IAAI,IAAI,CAAC;IAE5B,kBAAkB,IAAI,IAAI,CAAC;IAE3B;;OAEG;IACH,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAEnF;;OAEG;IACH,gBAAgB,IAAI,IAAI,CAAC;IAEzB,4BAA4B,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,WAAW,EAAE,CAAC;QAAC,QAAQ,EAAE,WAAW,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAEzG;;;OAGG;IACH,qBAAqB,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAE1D,gBAAgB;IAChB,SAAS,IAAI,iBAAiB,CAAC;CAChC;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,GAAG,CAAC;IACT,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,eAAO,MAAM,sBAAsB,eAA8B,CAAC;AAElE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,aAAa,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;CACzC"}
1
+ {"version":3,"file":"llm-context.d.ts","sourceRoot":"","sources":["../../src/common/llm-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAEjE,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,mBAAmB,IAAI,IAAI,CAAC;IAE5B;;OAEG;IACH,kBAAkB,IAAI,IAAI,CAAC;IAE3B;;OAEG;IACH,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAEnF;;OAEG;IACH,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAEvD;;OAEG;IACH,gBAAgB,IAAI,IAAI,CAAC;IAEzB;;OAEG;IACH,4BAA4B,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,WAAW,EAAE,CAAC;QAAC,QAAQ,EAAE,WAAW,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAEzG;;;OAGG;IACH,qBAAqB,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAE1D,gBAAgB;IAChB,SAAS,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,GAAG,CAAC;IACT,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,eAAO,MAAM,sBAAsB,eAA8B,CAAC;AAElE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,aAAa,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACxC,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B"}
@@ -1 +1 @@
1
- {"version":3,"file":"llm-context.js","sourceRoot":"","sources":["../../src/common/llm-context.ts"],"names":[],"mappings":";;;AAkCa,QAAA,sBAAsB,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC"}
1
+ {"version":3,"file":"llm-context.js","sourceRoot":"","sources":["../../src/common/llm-context.ts"],"names":[],"mappings":";;;AAgDa,QAAA,sBAAsB,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"context-prompt-provider.d.ts","sourceRoot":"","sources":["../../../src/common/prompts/context-prompt-provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAEhF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,eAAO,MAAM,uBAAuB,eAAoC,CAAC;AAEzE,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;CAC/E;AAED,qBACa,8BAA+B,YAAW,uBAAuB;IAE5E,SAAS,CAAC,QAAQ,CAAC,sBAAsB,EAAE,sBAAsB,CAAC;IAElE,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;CAsC9E"}
1
+ {"version":3,"file":"context-prompt-provider.d.ts","sourceRoot":"","sources":["../../../src/common/prompts/context-prompt-provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAEhF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,eAAO,MAAM,uBAAuB,eAAoC,CAAC;AAEzE,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;CAC/E;AAED,qBACa,8BAA+B,YAAW,uBAAuB;IAE5E,SAAS,CAAC,QAAQ,CAAC,sBAAsB,EAAE,sBAAsB,CAAC;IAElE,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;CAyC9E"}
@@ -9,30 +9,33 @@ let DefaultChatAgentPromptProvider = class DefaultChatAgentPromptProvider {
9
9
  provideContextPrompt(context, userMessage) {
10
10
  const editor = this.workbenchEditorService.currentEditor;
11
11
  const currentModel = editor === null || editor === void 0 ? void 0 : editor.currentDocumentModel;
12
- return `
13
- <additional_data>
14
- Below are some potentially helpful/relevant pieces of information for figuring out to respond
15
- <recently_viewed_files>
12
+ return `<additional_data>
13
+ Below are some potentially helpful/relevant pieces of information for figuring out to respond
14
+ <recently_viewed_files>
16
15
  ${context.recentlyViewFiles.map((file, idx) => ` ${idx + 1}: ${file}`).join('\n')}
17
- </recently_viewed_files>
18
- <attached_files>
19
- ${context.attachedFiles.map((file) => `
20
- <file_contents>
21
- \`\`\`${file.path}
22
- ${file.content}
23
- \`\`\`
24
- </file_contents>
25
- <linter_errors>
26
- ${file.lineErrors.join('\n')}
27
- </linter_errors>
28
- `)}
29
- </attached_files>
16
+ </recently_viewed_files>
17
+ <attached_files>
18
+ ${context.attachedFiles.map((file) => `
19
+ <file_contents>
20
+ \`\`\`${file.path}
21
+ ${file.content}
22
+ \`\`\`
23
+ </file_contents>
24
+ <linter_errors>
25
+ ${file.lineErrors.join('\n')}
26
+ </linter_errors>
27
+ `)}
28
+ </attached_files>
29
+ <attached_folders>
30
+
31
+ ${context.attachedFolders.join('\n')}
32
+ </attached_folders>
30
33
  ${currentModel
31
34
  ? `<current_opened_file>
32
- \`\`\`${currentModel.languageId} ${currentModel.uri.toString()}
35
+ \`\`\`${currentModel.languageId} ${currentModel.uri.toString()}
33
36
  ${currentModel.getText()}
34
- \`\`\`
35
- </current_opened_file>`
37
+ \`\`\`
38
+ </current_opened_file>`
36
39
  : ''}
37
40
  </additional_data>
38
41
  <user_query>
@@ -1 +1 @@
1
- {"version":3,"file":"context-prompt-provider.js","sourceRoot":"","sources":["../../../src/common/prompts/context-prompt-provider.ts"],"names":[],"mappings":";;;;AAAA,qCAAqD;AACrD,mEAAgF;AAInE,QAAA,uBAAuB,GAAG,MAAM,CAAC,yBAAyB,CAAC,CAAC;AAWlE,IAAM,8BAA8B,GAApC,MAAM,8BAA8B;IAIzC,oBAAoB,CAAC,OAA0B,EAAE,WAAmB;QAClE,MAAM,MAAM,GAAG,IAAI,CAAC,sBAAsB,CAAC,aAAa,CAAC;QACzD,MAAM,YAAY,GAAG,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,oBAAoB,CAAC;QAClD,OAAO;;;;EAIT,OAAO,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,GAAG,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;;MAG9E,OAAO,CAAC,aAAa,CAAC,GAAG,CACzB,CAAC,IAAI,EAAE,EAAE,CACP;;YAEI,IAAI,CAAC,IAAI;MACf,IAAI,CAAC,OAAO;;;;MAIZ,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;;eAEjB,CACV;;EAGH,YAAY;YACV,CAAC,CAAC;UACI,YAAY,CAAC,UAAU,IAAI,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE;EAC9D,YAAY,CAAC,OAAO,EAAE;;yBAEC;YACrB,CAAC,CAAC,EACN;;;EAGE,WAAW;cACC,CAAC;IACb,CAAC;CACF,CAAA;AA1CY,wEAA8B;AAEtB;IADlB,IAAA,cAAS,EAAC,+BAAsB,CAAC;sCACS,+BAAsB;8EAAC;yCAFvD,8BAA8B;IAD1C,IAAA,eAAU,GAAE;GACA,8BAA8B,CA0C1C"}
1
+ {"version":3,"file":"context-prompt-provider.js","sourceRoot":"","sources":["../../../src/common/prompts/context-prompt-provider.ts"],"names":[],"mappings":";;;;AAAA,qCAAqD;AACrD,mEAAgF;AAInE,QAAA,uBAAuB,GAAG,MAAM,CAAC,yBAAyB,CAAC,CAAC;AAWlE,IAAM,8BAA8B,GAApC,MAAM,8BAA8B;IAIzC,oBAAoB,CAAC,OAA0B,EAAE,WAAmB;QAClE,MAAM,MAAM,GAAG,IAAI,CAAC,sBAAsB,CAAC,aAAa,CAAC;QACzD,MAAM,YAAY,GAAG,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,oBAAoB,CAAC;QAClD,OAAO;;;EAGT,OAAO,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,GAAG,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;;EAGlF,OAAO,CAAC,aAAa,CAAC,GAAG,CACzB,CAAC,IAAI,EAAE,EAAE,CACP;;QAEI,IAAI,CAAC,IAAI;EACf,IAAI,CAAC,OAAO;;;;EAIZ,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;;CAE3B,CACA;;;;EAIC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;;EAGlC,YAAY;YACV,CAAC,CAAC;QACE,YAAY,CAAC,UAAU,IAAI,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE;EAC5D,YAAY,CAAC,OAAO,EAAE;;uBAED;YACnB,CAAC,CAAC,EACN;;;EAGE,WAAW;cACC,CAAC;IACb,CAAC;CACF,CAAA;AA7CY,wEAA8B;AAEtB;IADlB,IAAA,cAAS,EAAC,+BAAsB,CAAC;sCACS,+BAAsB;8EAAC;yCAFvD,8BAA8B;IAD1C,IAAA,eAAU,GAAE;GACA,8BAA8B,CA6C1C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opensumi/ide-ai-native",
3
- "version": "3.8.3-next-1741685617.0",
3
+ "version": "3.8.3-next-1741747748.0",
4
4
  "files": [
5
5
  "lib",
6
6
  "src"
@@ -24,26 +24,26 @@
24
24
  "@ai-sdk/openai": "^1.1.9",
25
25
  "@ai-sdk/openai-compatible": "^0.1.11",
26
26
  "@modelcontextprotocol/sdk": "^1.3.1",
27
- "@opensumi/ide-addons": "3.8.3-next-1741685617.0",
28
- "@opensumi/ide-components": "3.8.3-next-1741685617.0",
29
- "@opensumi/ide-connection": "3.8.3-next-1741685617.0",
30
- "@opensumi/ide-core-common": "3.8.3-next-1741685617.0",
31
- "@opensumi/ide-core-node": "3.8.3-next-1741685617.0",
32
- "@opensumi/ide-debug": "3.8.3-next-1741685617.0",
33
- "@opensumi/ide-design": "3.8.3-next-1741685617.0",
34
- "@opensumi/ide-editor": "3.8.3-next-1741685617.0",
35
- "@opensumi/ide-file-search": "3.8.3-next-1741685617.0",
36
- "@opensumi/ide-file-service": "3.8.3-next-1741685617.0",
37
- "@opensumi/ide-main-layout": "3.8.3-next-1741685617.0",
38
- "@opensumi/ide-markers": "3.8.3-next-1741685617.0",
39
- "@opensumi/ide-monaco": "3.8.3-next-1741685617.0",
40
- "@opensumi/ide-overlay": "3.8.3-next-1741685617.0",
41
- "@opensumi/ide-preferences": "3.8.3-next-1741685617.0",
42
- "@opensumi/ide-search": "3.8.3-next-1741685617.0",
43
- "@opensumi/ide-terminal-next": "3.8.3-next-1741685617.0",
44
- "@opensumi/ide-theme": "3.8.3-next-1741685617.0",
45
- "@opensumi/ide-utils": "3.8.3-next-1741685617.0",
46
- "@opensumi/ide-workspace": "3.8.3-next-1741685617.0",
27
+ "@opensumi/ide-addons": "3.8.3-next-1741747748.0",
28
+ "@opensumi/ide-components": "3.8.3-next-1741747748.0",
29
+ "@opensumi/ide-connection": "3.8.3-next-1741747748.0",
30
+ "@opensumi/ide-core-common": "3.8.3-next-1741747748.0",
31
+ "@opensumi/ide-core-node": "3.8.3-next-1741747748.0",
32
+ "@opensumi/ide-debug": "3.8.3-next-1741747748.0",
33
+ "@opensumi/ide-design": "3.8.3-next-1741747748.0",
34
+ "@opensumi/ide-editor": "3.8.3-next-1741747748.0",
35
+ "@opensumi/ide-file-search": "3.8.3-next-1741747748.0",
36
+ "@opensumi/ide-file-service": "3.8.3-next-1741747748.0",
37
+ "@opensumi/ide-main-layout": "3.8.3-next-1741747748.0",
38
+ "@opensumi/ide-markers": "3.8.3-next-1741747748.0",
39
+ "@opensumi/ide-monaco": "3.8.3-next-1741747748.0",
40
+ "@opensumi/ide-overlay": "3.8.3-next-1741747748.0",
41
+ "@opensumi/ide-preferences": "3.8.3-next-1741747748.0",
42
+ "@opensumi/ide-search": "3.8.3-next-1741747748.0",
43
+ "@opensumi/ide-terminal-next": "3.8.3-next-1741747748.0",
44
+ "@opensumi/ide-theme": "3.8.3-next-1741747748.0",
45
+ "@opensumi/ide-utils": "3.8.3-next-1741747748.0",
46
+ "@opensumi/ide-workspace": "3.8.3-next-1741747748.0",
47
47
  "@xterm/xterm": "5.5.0",
48
48
  "ai": "^4.1.45",
49
49
  "ansi-regex": "^2.0.0",
@@ -60,7 +60,7 @@
60
60
  "zod-to-json-schema": "^3.24.1"
61
61
  },
62
62
  "devDependencies": {
63
- "@opensumi/ide-core-browser": "3.8.3-next-1741685617.0"
63
+ "@opensumi/ide-core-browser": "3.8.3-next-1741747748.0"
64
64
  },
65
- "gitHead": "c9e531966224c3c14c03f6c87acae8934d7d177b"
65
+ "gitHead": "69de97d49d2139933c62f60ab7662f5e6cfca5f5"
66
66
  }
@@ -152,9 +152,9 @@ export class ChatAgentService extends Disposable implements IChatAgentService {
152
152
  if (!this.initialUserMessageMap.has(request.sessionId)) {
153
153
  this.initialUserMessageMap.set(request.sessionId, request.message);
154
154
  const rawMessage = request.message;
155
- request.message = this.provideContextMessage(rawMessage, request.sessionId);
155
+ request.message = await this.provideContextMessage(rawMessage, request.sessionId);
156
156
  } else if (this.shouldUpdateContext || request.regenerate || history.length === 0) {
157
- request.message = this.provideContextMessage(request.message, request.sessionId);
157
+ request.message = await this.provideContextMessage(request.message, request.sessionId);
158
158
  this.shouldUpdateContext = false;
159
159
  }
160
160
 
@@ -162,8 +162,8 @@ export class ChatAgentService extends Disposable implements IChatAgentService {
162
162
  return result;
163
163
  }
164
164
 
165
- private provideContextMessage(message: string, sessionId: string) {
166
- const context = this.contextService.serialize();
165
+ private async provideContextMessage(message: string, sessionId: string) {
166
+ const context = await this.contextService.serialize();
167
167
  const fullMessage = this.promptProvider.provideContextPrompt(context, message);
168
168
  this.aiReporter.send({
169
169
  msgType: AIServiceType.Chat,
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { MessageList } from 'react-chat-elements';
3
3
 
4
- import { AppConfig, getIcon, useInjectable, useUpdateOnEvent } from '@opensumi/ide-core-browser';
4
+ import { AINativeConfigService, AppConfig, getIcon, useInjectable, useUpdateOnEvent } from '@opensumi/ide-core-browser';
5
5
  import { Popover, PopoverPosition } from '@opensumi/ide-core-browser/lib/components';
6
6
  import { EnhanceIcon } from '@opensumi/ide-core-browser/lib/components/ai-native';
7
7
  import {
@@ -31,13 +31,14 @@ import { IMessageService } from '@opensumi/ide-overlay';
31
31
 
32
32
  import 'react-chat-elements/dist/main.css';
33
33
  import { AI_CHAT_VIEW_ID, IChatAgentService, IChatInternalService, IChatMessageStructure } from '../../common';
34
+ import { LLMContextService, LLMContextServiceToken } from '../../common/llm-context';
34
35
  import { CodeBlockData } from '../../common/types';
35
36
  import { FileChange, FileListDisplay } from '../components/ChangeList';
36
- import { ChatContext } from '../components/ChatContext';
37
37
  import { CodeBlockWrapperInput } from '../components/ChatEditor';
38
38
  import ChatHistory, { IChatHistoryItem } from '../components/ChatHistory';
39
39
  import { ChatInput } from '../components/ChatInput';
40
40
  import { ChatMarkdown } from '../components/ChatMarkdown';
41
+ import { ChatMentionInput } from '../components/ChatMentionInput';
41
42
  import { ChatNotify, ChatReply } from '../components/ChatReply';
42
43
  import { SlashCustomRender } from '../components/SlashCustomRender';
43
44
  import { MessageData, createMessageByAI, createMessageByUser } from '../components/utils';
@@ -105,6 +106,8 @@ export const AIChatView = () => {
105
106
  const chatFeatureRegistry = useInjectable<ChatFeatureRegistry>(ChatFeatureRegistryToken);
106
107
  const chatRenderRegistry = useInjectable<ChatRenderRegistry>(ChatRenderRegistryToken);
107
108
  const mcpServerRegistry = useInjectable<IMCPServerRegistry>(TokenMCPServerRegistry);
109
+ const aiNativeConfigService = useInjectable<AINativeConfigService>(AINativeConfigService);
110
+ const llmContextService = useInjectable<LLMContextService>(LLMContextServiceToken);
108
111
 
109
112
  const layoutService = useInjectable<IMainLayoutService>(IMainLayoutService);
110
113
  const msgHistoryManager = aiChatService.sessionModel.history;
@@ -184,6 +187,9 @@ export const AIChatView = () => {
184
187
  if (chatRenderRegistry.chatInputRender) {
185
188
  return chatRenderRegistry.chatInputRender;
186
189
  }
190
+ if (aiNativeConfigService.capabilities.supportsMCP) {
191
+ return ChatMentionInput;
192
+ }
187
193
  return ChatInput;
188
194
  }, [chatRenderRegistry.chatInputRender]);
189
195
 
@@ -262,7 +268,7 @@ export const AIChatView = () => {
262
268
  if (loading) {
263
269
  return;
264
270
  }
265
- await handleSend(message);
271
+ await handleSend(message.message, message.agentId, message.command);
266
272
  } else {
267
273
  if (message.agentId) {
268
274
  setAgentId(message.agentId);
@@ -638,11 +644,44 @@ export const AIChatView = () => {
638
644
  );
639
645
 
640
646
  const handleSend = React.useCallback(
641
- async (value: IChatMessageStructure) => {
642
- const { message, command, reportExtra } = value;
647
+ async (message: string, agentId?: string, command?: string) => {
648
+ const reportExtra = {
649
+ actionSource: ActionSourceEnum.Chat,
650
+ actionType: ActionTypeEnum.Send,
651
+ };
652
+ agentId = agentId ? agentId : ChatProxyService.AGENT_ID;
653
+ // 提取并替换 {{@file:xxx}} 中的文件内容
654
+ let processedContent = message;
655
+ const filePattern = /\{\{@file:(.*?)\}\}/g;
656
+ const fileMatches = message.match(filePattern);
657
+ let isCleanContext = false;
658
+ if (fileMatches) {
659
+ for (const match of fileMatches) {
660
+ const filePath = match.replace(/\{\{@file:(.*?)\}\}/, '$1');
661
+ if (filePath && !isCleanContext) {
662
+ isCleanContext = true;
663
+ llmContextService.cleanFileContext();
664
+ }
665
+ const fileUri = new URI(filePath);
666
+ llmContextService.addFileToContext(fileUri, undefined, true);
667
+ // 获取文件内容
668
+ // 替换占位符,后续支持自定义渲染时可替换为自定义渲染标签
669
+ processedContent = processedContent.replace(match, `\`File:${fileUri.displayName}\``);
670
+ }
671
+ }
643
672
 
644
- const agentId = value.agentId ? value.agentId : ChatProxyService.AGENT_ID;
645
- return handleAgentReply({ message, agentId, command, reportExtra });
673
+ const folderPattern = /\{\{@folder:(.*?)\}\}/g;
674
+ const folderMatches = processedContent.match(folderPattern);
675
+ if (folderMatches) {
676
+ for (const match of folderMatches) {
677
+ const folderPath = match.replace(/\{\{@folder:(.*?)\}\}/, '$1');
678
+ const folderUri = new URI(folderPath);
679
+ llmContextService.addFolderToContext(folderUri);
680
+ // 替换占位符,后续支持自定义渲染时可替换为自定义渲染标签
681
+ processedContent = processedContent.replace(match, `\`Folder:${folderUri.displayName}\``);
682
+ }
683
+ }
684
+ return handleAgentReply({ message: processedContent, agentId, command, reportExtra });
646
685
  },
647
686
  [handleAgentReply],
648
687
  );
@@ -759,7 +798,6 @@ export const AIChatView = () => {
759
798
  </div>
760
799
  ) : null}
761
800
  <div className={styles.chat_input_wrap}>
762
- <ChatContext />
763
801
  <div className={styles.header_operate}>
764
802
  <div className={styles.header_operate_left}>
765
803
  {shortcutCommands.map((command) => (
@@ -790,17 +828,7 @@ export const AIChatView = () => {
790
828
  />
791
829
  )}
792
830
  <ChatInputWrapperRender
793
- onSend={(value, agentId, command) =>
794
- handleSend({
795
- message: value,
796
- agentId,
797
- command,
798
- reportExtra: {
799
- actionSource: ActionSourceEnum.Chat,
800
- actionType: ActionTypeEnum.Send,
801
- },
802
- })
803
- }
831
+ onSend={handleSend}
804
832
  disabled={loading}
805
833
  enableOptions={true}
806
834
  theme={theme}
@@ -0,0 +1,267 @@
1
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
2
+
3
+ import { LabelService, RecentFilesManager, useInjectable } from '@opensumi/ide-core-browser';
4
+ import { getIcon } from '@opensumi/ide-core-browser/lib/components';
5
+ import { URI, localize } from '@opensumi/ide-core-common';
6
+ import { CommandService } from '@opensumi/ide-core-common/lib/command';
7
+ import { WorkbenchEditorService } from '@opensumi/ide-editor';
8
+ import { FileSearchServicePath, IFileSearchService } from '@opensumi/ide-file-search';
9
+ import { IWorkspaceService } from '@opensumi/ide-workspace';
10
+
11
+ import { IChatInternalService } from '../../common';
12
+ import { ChatInternalService } from '../chat/chat.internal.service';
13
+ import { OPEN_MCP_CONFIG_COMMAND } from '../mcp/config/mcp-config.commands';
14
+
15
+ import styles from './components.module.less';
16
+ import { MentionInput } from './mention-input/mention-input';
17
+ import { FooterButtonPosition, FooterConfig, MentionItem, MentionType } from './mention-input/types';
18
+
19
+ export interface IChatMentionInputProps {
20
+ onSend: (value: string, agentId?: string, command?: string, option?: { model: string; [key: string]: any }) => void;
21
+ onValueChange?: (value: string) => void;
22
+ onExpand?: (value: boolean) => void;
23
+ placeholder?: string;
24
+ enableOptions?: boolean;
25
+ disabled?: boolean;
26
+ sendBtnClassName?: string;
27
+ defaultHeight?: number;
28
+ value?: string;
29
+ autoFocus?: boolean;
30
+ theme?: string | null;
31
+ setTheme: (theme: string | null) => void;
32
+ agentId: string;
33
+ setAgentId: (id: string) => void;
34
+ defaultAgentId?: string;
35
+ command: string;
36
+ setCommand: (command: string) => void;
37
+ }
38
+
39
+ // 指令命令激活组件
40
+ export const ChatMentionInput = React.forwardRef((props: IChatMentionInputProps) => {
41
+ const { onSend, disabled = false } = props;
42
+
43
+ const [value, setValue] = useState(props.value || '');
44
+ const aiChatService = useInjectable<ChatInternalService>(IChatInternalService);
45
+ const commandService = useInjectable<CommandService>(CommandService);
46
+ const searchService = useInjectable<IFileSearchService>(FileSearchServicePath);
47
+ const recentFilesManager = useInjectable<RecentFilesManager>(RecentFilesManager);
48
+ const workspaceService = useInjectable<IWorkspaceService>(IWorkspaceService);
49
+ const editorService = useInjectable<WorkbenchEditorService>(WorkbenchEditorService);
50
+ const labelService = useInjectable<LabelService>(LabelService);
51
+
52
+ const handleShowMCPConfig = React.useCallback(() => {
53
+ commandService.executeCommand(OPEN_MCP_CONFIG_COMMAND.id);
54
+ }, [commandService]);
55
+
56
+ useEffect(() => {
57
+ if (props.value !== value) {
58
+ setValue(props.value || '');
59
+ }
60
+ }, [props.value]);
61
+
62
+ // 默认菜单项
63
+ const defaultMenuItems: MentionItem[] = [
64
+ // {
65
+ // id: 'code',
66
+ // type: 'code',
67
+ // text: 'Code',
68
+ // icon: getIcon('codebraces'),
69
+ // getHighestLevelItems: () => [],
70
+ // getItems: async (searchText: string) => {
71
+ // const currentEditor = editorService.currentEditor;
72
+ // if (!currentEditor) {
73
+ // return [];
74
+ // }
75
+ // const currentDocumentModel = currentEditor.currentDocumentModel;
76
+ // if (!currentDocumentModel) {
77
+ // return [];
78
+ // }
79
+ // const symbols = await commandService.executeCommand('_executeFormatDocumentProvider', currentDocumentModel.uri.codeUri);
80
+ // return [];
81
+ // },
82
+ // },
83
+ {
84
+ id: MentionType.FILE,
85
+ type: MentionType.FILE,
86
+ text: 'File',
87
+ icon: getIcon('file'),
88
+ getHighestLevelItems: () => {
89
+ const currentEditor = editorService.currentEditor;
90
+ const currentUri = currentEditor?.currentUri;
91
+ if (!currentUri) {
92
+ return [];
93
+ }
94
+ return [
95
+ {
96
+ id: currentUri.codeUri.fsPath,
97
+ type: MentionType.FILE,
98
+ text: currentUri.displayName,
99
+ value: currentUri.codeUri.fsPath,
100
+ description: `(${localize('aiNative.chat.defaultContextFile')})`,
101
+ contextId: currentUri.codeUri.fsPath,
102
+ icon: labelService.getIcon(currentUri),
103
+ },
104
+ ];
105
+ },
106
+ getItems: async (searchText: string) => {
107
+ if (!searchText) {
108
+ const recentFile = await recentFilesManager.getMostRecentlyOpenedFiles();
109
+ return Promise.all(
110
+ recentFile.map(async (file) => {
111
+ const uri = new URI(file);
112
+ return {
113
+ id: uri.codeUri.fsPath,
114
+ type: MentionType.FILE,
115
+ text: uri.displayName,
116
+ value: uri.codeUri.fsPath,
117
+ description: (await workspaceService.asRelativePath(uri.parent))?.path || '',
118
+ contextId: uri.codeUri.fsPath,
119
+ icon: labelService.getIcon(uri),
120
+ };
121
+ }),
122
+ );
123
+ } else {
124
+ const rootUris = (await workspaceService.roots).map((root) => new URI(root.uri).codeUri.fsPath.toString());
125
+ const results = await searchService.find(searchText, {
126
+ rootUris,
127
+ useGitIgnore: true,
128
+ noIgnoreParent: true,
129
+ fuzzyMatch: true,
130
+ limit: 10,
131
+ });
132
+ return Promise.all(
133
+ results.map(async (file) => {
134
+ const uri = new URI(file);
135
+ return {
136
+ id: uri.codeUri.fsPath,
137
+ type: MentionType.FILE,
138
+ text: uri.displayName,
139
+ value: uri.codeUri.fsPath,
140
+ description: (await workspaceService.asRelativePath(uri.parent))?.path || '',
141
+ contextId: uri.codeUri.fsPath,
142
+ icon: labelService.getIcon(uri),
143
+ };
144
+ }),
145
+ );
146
+ }
147
+ },
148
+ },
149
+ {
150
+ id: MentionType.FOLDER,
151
+ type: MentionType.FOLDER,
152
+ text: 'Folder',
153
+ icon: getIcon('folder'),
154
+ getHighestLevelItems: () => {
155
+ const currentEditor = editorService.currentEditor;
156
+ const currentFolderUri = currentEditor?.currentUri?.parent;
157
+ if (!currentFolderUri) {
158
+ return [];
159
+ }
160
+ return [
161
+ {
162
+ id: currentFolderUri.codeUri.fsPath,
163
+ type: MentionType.FOLDER,
164
+ text: currentFolderUri.displayName,
165
+ value: currentFolderUri.codeUri.fsPath,
166
+ description: `(${localize('aiNative.chat.defaultContextFolder')})`,
167
+ contextId: currentFolderUri.codeUri.fsPath,
168
+ icon: getIcon('folder'),
169
+ },
170
+ ];
171
+ },
172
+ getItems: async (searchText: string) => {
173
+ if (!searchText) {
174
+ const recentFile = await recentFilesManager.getMostRecentlyOpenedFiles();
175
+ const recentFolder = Array.from(new Set(recentFile.map((file) => new URI(file).parent.codeUri.fsPath)));
176
+ return Promise.all(
177
+ recentFolder.map(async (folder) => {
178
+ const uri = new URI(folder);
179
+ const relativePath = await workspaceService.asRelativePath(uri);
180
+ return {
181
+ id: uri.codeUri.fsPath,
182
+ type: MentionType.FOLDER,
183
+ text: uri.displayName,
184
+ value: uri.codeUri.fsPath,
185
+ description: relativePath?.root ? relativePath.path : '',
186
+ contextId: uri.codeUri.fsPath,
187
+ icon: getIcon('folder'),
188
+ };
189
+ }),
190
+ );
191
+ } else {
192
+ const rootUris = (await workspaceService.roots).map((root) => new URI(root.uri).codeUri.fsPath.toString());
193
+ const results = await searchService.find(searchText, {
194
+ rootUris,
195
+ useGitIgnore: true,
196
+ noIgnoreParent: true,
197
+ fuzzyMatch: true,
198
+ limit: 10,
199
+ onlyFolders: true,
200
+ });
201
+ return Promise.all(
202
+ results.map(async (folder) => {
203
+ const uri = new URI(folder);
204
+ return {
205
+ id: uri.codeUri.fsPath,
206
+ type: MentionType.FOLDER,
207
+ text: uri.displayName,
208
+ value: uri.codeUri.fsPath,
209
+ description: (await workspaceService.asRelativePath(uri.parent))?.path || '',
210
+ contextId: uri.codeUri.fsPath,
211
+ icon: getIcon('folder'),
212
+ };
213
+ }),
214
+ );
215
+ }
216
+ },
217
+ },
218
+ ];
219
+
220
+ const defaultMentionInputFooterOptions: FooterConfig = useMemo(
221
+ () => ({
222
+ modelOptions: [
223
+ { label: 'QWQ 32B', value: 'qwq-32b' },
224
+ { label: 'DeepSeek R1', value: 'deepseek-r1' },
225
+ ],
226
+ defaultModel: 'deepseek-r1',
227
+ buttons: [
228
+ {
229
+ id: 'mcp-server',
230
+ icon: 'mcp',
231
+ title: 'MCP Server',
232
+ onClick: handleShowMCPConfig,
233
+ position: FooterButtonPosition.LEFT,
234
+ },
235
+ ],
236
+ showModelSelector: true,
237
+ }),
238
+ [handleShowMCPConfig],
239
+ );
240
+
241
+ const handleStop = useCallback(() => {
242
+ aiChatService.cancelRequest();
243
+ }, []);
244
+
245
+ const handleSend = useCallback(
246
+ async (content: string, option?: { model: string; [key: string]: any }) => {
247
+ if (disabled) {
248
+ return;
249
+ }
250
+ onSend(content, undefined, undefined, option);
251
+ },
252
+ [onSend, editorService, disabled],
253
+ );
254
+
255
+ return (
256
+ <div className={styles.chat_input_container}>
257
+ <MentionInput
258
+ mentionItems={defaultMenuItems}
259
+ onSend={handleSend}
260
+ onStop={handleStop}
261
+ loading={disabled}
262
+ placeholder={localize('aiNative.chat.input.placeholder.default')}
263
+ footerConfig={defaultMentionInputFooterOptions}
264
+ />
265
+ </div>
266
+ );
267
+ });
@@ -15,7 +15,7 @@ import { WorkbenchEditorService } from '@opensumi/ide-editor/lib/browser/types';
15
15
 
16
16
  import { FileContext, LLMContextService, LLMContextServiceToken } from '../../../common/llm-context';
17
17
 
18
- import { ContextSelector } from './ContextSelector';
18
+ import { ContextSelector } from './context-selector';
19
19
  import styles from './style.module.less';
20
20
 
21
21
  const getCollapsedHeight = () => ({ height: 0, opacity: 0 });
@@ -519,6 +519,7 @@
519
519
  display: flex;
520
520
  font-size: 11px;
521
521
  align-items: center;
522
+ min-width: 150px;
522
523
  }
523
524
 
524
525
  .mcp_desc {