@opensumi/ide-ai-native 3.8.1-next-1741250387.0 → 3.8.1-next-1741251026.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.
- package/lib/browser/ai-core.contextkeys.d.ts +1 -1
- package/lib/browser/ai-core.contextkeys.d.ts.map +1 -1
- package/lib/browser/ai-core.contextkeys.js +1 -1
- package/lib/browser/ai-core.contextkeys.js.map +1 -1
- package/lib/browser/ai-core.contribution.d.ts +5 -0
- package/lib/browser/ai-core.contribution.d.ts.map +1 -1
- package/lib/browser/ai-core.contribution.js +71 -9
- package/lib/browser/ai-core.contribution.js.map +1 -1
- package/lib/browser/chat/chat-agent.service.d.ts +11 -3
- package/lib/browser/chat/chat-agent.service.d.ts.map +1 -1
- package/lib/browser/chat/chat-agent.service.js +43 -5
- package/lib/browser/chat/chat-agent.service.js.map +1 -1
- package/lib/browser/chat/chat-manager.service.d.ts +1 -0
- package/lib/browser/chat/chat-manager.service.d.ts.map +1 -1
- package/lib/browser/chat/chat-manager.service.js +6 -8
- package/lib/browser/chat/chat-manager.service.js.map +1 -1
- package/lib/browser/chat/chat-model.d.ts +4 -1
- package/lib/browser/chat/chat-model.d.ts.map +1 -1
- package/lib/browser/chat/chat-model.js +57 -2
- package/lib/browser/chat/chat-model.js.map +1 -1
- package/lib/browser/chat/chat-proxy.service.d.ts.map +1 -1
- package/lib/browser/chat/chat-proxy.service.js +13 -6
- package/lib/browser/chat/chat-proxy.service.js.map +1 -1
- package/lib/browser/chat/chat.api.service.d.ts +1 -2
- package/lib/browser/chat/chat.api.service.d.ts.map +1 -1
- package/lib/browser/chat/chat.api.service.js +0 -4
- package/lib/browser/chat/chat.api.service.js.map +1 -1
- package/lib/browser/chat/chat.internal.service.d.ts +2 -0
- package/lib/browser/chat/chat.internal.service.d.ts.map +1 -1
- package/lib/browser/chat/chat.internal.service.js +3 -0
- package/lib/browser/chat/chat.internal.service.js.map +1 -1
- package/lib/browser/chat/chat.module.less +1 -2
- package/lib/browser/chat/chat.view.d.ts.map +1 -1
- package/lib/browser/chat/chat.view.js +46 -29
- package/lib/browser/chat/chat.view.js.map +1 -1
- package/lib/browser/components/ChatContext/index.js +2 -2
- package/lib/browser/components/ChatContext/index.js.map +1 -1
- package/lib/browser/components/ChatInput.d.ts.map +1 -1
- package/lib/browser/components/ChatInput.js +29 -1
- package/lib/browser/components/ChatInput.js.map +1 -1
- package/lib/browser/components/ChatReply.js +6 -1
- package/lib/browser/components/ChatReply.js.map +1 -1
- package/lib/browser/components/ChatThinking.d.ts +0 -2
- package/lib/browser/components/ChatThinking.d.ts.map +1 -1
- package/lib/browser/components/ChatThinking.js +2 -10
- package/lib/browser/components/ChatThinking.js.map +1 -1
- package/lib/browser/components/ChatToolRender.d.ts.map +1 -1
- package/lib/browser/components/ChatToolRender.js +2 -3
- package/lib/browser/components/ChatToolRender.js.map +1 -1
- package/lib/browser/components/WelcomeMsg.js +1 -1
- package/lib/browser/components/WelcomeMsg.js.map +1 -1
- package/lib/browser/components/chat-history.module.less +2 -1
- package/lib/browser/components/components.module.less +22 -0
- package/lib/browser/context/llm-context.service.d.ts +18 -5
- package/lib/browser/context/llm-context.service.d.ts.map +1 -1
- package/lib/browser/context/llm-context.service.js +80 -47
- package/lib/browser/context/llm-context.service.js.map +1 -1
- package/lib/browser/contrib/inline-completions/inline-completions.controller.js +1 -1
- package/lib/browser/contrib/inline-completions/inline-completions.controller.js.map +1 -1
- package/lib/browser/contrib/inline-completions/prompt/matcher.js +2 -2
- package/lib/browser/contrib/inline-completions/prompt/similarSnippets.d.ts +1 -1
- package/lib/browser/contrib/inline-completions/prompt/similarSnippets.js +2 -2
- package/lib/browser/contrib/intelligent-completions/index.d.ts +2 -1
- package/lib/browser/contrib/intelligent-completions/index.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/index.js +4 -1
- package/lib/browser/contrib/intelligent-completions/index.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js +2 -2
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.contribution.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js +6 -5
- package/lib/browser/contrib/intelligent-completions/intelligent-completions.controller.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/view/code-edits-previewer.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/view/code-edits-previewer.js +4 -2
- package/lib/browser/contrib/intelligent-completions/view/code-edits-previewer.js.map +1 -1
- package/lib/browser/contrib/intelligent-completions/view/default.d.ts.map +1 -1
- package/lib/browser/contrib/intelligent-completions/view/default.js +23 -11
- package/lib/browser/contrib/intelligent-completions/view/default.js.map +1 -1
- package/lib/browser/index.d.ts.map +1 -1
- package/lib/browser/index.js +4 -0
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/layout/layout.module.less +4 -4
- package/lib/browser/mcp/base-apply.service.d.ts +26 -11
- package/lib/browser/mcp/base-apply.service.d.ts.map +1 -1
- package/lib/browser/mcp/base-apply.service.js +255 -103
- package/lib/browser/mcp/base-apply.service.js.map +1 -1
- package/lib/browser/mcp/config/components/mcp-config.module.less +178 -0
- package/lib/browser/mcp/config/components/mcp-config.view.d.ts +3 -0
- package/lib/browser/mcp/config/components/mcp-config.view.d.ts.map +1 -0
- package/lib/browser/mcp/config/components/mcp-config.view.js +150 -0
- package/lib/browser/mcp/config/components/mcp-config.view.js.map +1 -0
- package/lib/browser/mcp/config/components/mcp-server-form.d.ts +16 -0
- package/lib/browser/mcp/config/components/mcp-server-form.d.ts.map +1 -0
- package/lib/browser/mcp/config/components/mcp-server-form.js +84 -0
- package/lib/browser/mcp/config/components/mcp-server-form.js.map +1 -0
- package/lib/browser/mcp/config/components/mcp-server-form.module.less +78 -0
- package/lib/browser/mcp/config/mcp-config.commands.d.ts +10 -0
- package/lib/browser/mcp/config/mcp-config.commands.d.ts.map +1 -0
- package/lib/browser/mcp/config/mcp-config.commands.js +35 -0
- package/lib/browser/mcp/config/mcp-config.commands.js.map +1 -0
- package/lib/browser/mcp/config/mcp-config.contribution.d.ts +16 -0
- package/lib/browser/mcp/config/mcp-config.contribution.d.ts.map +1 -0
- package/lib/browser/mcp/config/mcp-config.contribution.js +62 -0
- package/lib/browser/mcp/config/mcp-config.contribution.js.map +1 -0
- package/lib/browser/mcp/mcp-server-proxy.service.d.ts +6 -0
- package/lib/browser/mcp/mcp-server-proxy.service.d.ts.map +1 -1
- package/lib/browser/mcp/mcp-server-proxy.service.js +10 -1
- package/lib/browser/mcp/mcp-server-proxy.service.js.map +1 -1
- package/lib/browser/mcp/mcp-server.feature.registry.d.ts +8 -0
- package/lib/browser/mcp/mcp-server.feature.registry.d.ts.map +1 -1
- package/lib/browser/mcp/mcp-server.feature.registry.js +28 -3
- package/lib/browser/mcp/mcp-server.feature.registry.js.map +1 -1
- package/lib/browser/mcp/tools/components/EditFile.d.ts.map +1 -1
- package/lib/browser/mcp/tools/components/EditFile.js +15 -9
- package/lib/browser/mcp/tools/components/EditFile.js.map +1 -1
- package/lib/browser/mcp/tools/components/ExpandableFileList.d.ts +13 -0
- package/lib/browser/mcp/tools/components/ExpandableFileList.d.ts.map +1 -0
- package/lib/browser/mcp/tools/components/{SearchResult.js → ExpandableFileList.js} +29 -19
- package/lib/browser/mcp/tools/components/ExpandableFileList.js.map +1 -0
- package/lib/browser/mcp/tools/components/Terminal.d.ts.map +1 -1
- package/lib/browser/mcp/tools/components/Terminal.js +10 -2
- package/lib/browser/mcp/tools/components/Terminal.js.map +1 -1
- package/lib/browser/mcp/tools/components/index.module.less +4 -0
- package/lib/browser/mcp/tools/createNewFileWithText.d.ts +1 -0
- package/lib/browser/mcp/tools/createNewFileWithText.d.ts.map +1 -1
- package/lib/browser/mcp/tools/createNewFileWithText.js +19 -11
- package/lib/browser/mcp/tools/createNewFileWithText.js.map +1 -1
- package/lib/browser/mcp/tools/fileSearch.d.ts +1 -0
- package/lib/browser/mcp/tools/fileSearch.d.ts.map +1 -1
- package/lib/browser/mcp/tools/fileSearch.js +14 -5
- package/lib/browser/mcp/tools/fileSearch.js.map +1 -1
- package/lib/browser/mcp/tools/getDiagnosticsByPath.d.ts.map +1 -1
- package/lib/browser/mcp/tools/getDiagnosticsByPath.js +1 -0
- package/lib/browser/mcp/tools/getDiagnosticsByPath.js.map +1 -1
- package/lib/browser/mcp/tools/grepSearch.d.ts.map +1 -1
- package/lib/browser/mcp/tools/grepSearch.js +6 -3
- package/lib/browser/mcp/tools/grepSearch.js.map +1 -1
- package/lib/browser/mcp/tools/handlers/EditFile.js +1 -1
- package/lib/browser/mcp/tools/handlers/EditFile.js.map +1 -1
- package/lib/browser/mcp/tools/handlers/ListDir.d.ts +1 -0
- package/lib/browser/mcp/tools/handlers/ListDir.d.ts.map +1 -1
- package/lib/browser/mcp/tools/handlers/ListDir.js +3 -0
- package/lib/browser/mcp/tools/handlers/ListDir.js.map +1 -1
- package/lib/browser/mcp/tools/handlers/RunCommand.d.ts.map +1 -1
- package/lib/browser/mcp/tools/handlers/RunCommand.js +2 -0
- package/lib/browser/mcp/tools/handlers/RunCommand.js.map +1 -1
- package/lib/browser/mcp/tools/listDir.d.ts +1 -0
- package/lib/browser/mcp/tools/listDir.d.ts.map +1 -1
- package/lib/browser/mcp/tools/listDir.js +35 -4
- package/lib/browser/mcp/tools/listDir.js.map +1 -1
- package/lib/browser/mcp/tools/runTerminalCmd.d.ts.map +1 -1
- package/lib/browser/mcp/tools/runTerminalCmd.js +1 -0
- package/lib/browser/mcp/tools/runTerminalCmd.js.map +1 -1
- package/lib/browser/model/msg-history-manager.d.ts +2 -2
- package/lib/browser/model/msg-history-manager.d.ts.map +1 -1
- package/lib/browser/model/msg-history-manager.js +4 -10
- package/lib/browser/model/msg-history-manager.js.map +1 -1
- package/lib/browser/preferences/schema.d.ts.map +1 -1
- package/lib/browser/preferences/schema.js +22 -2
- package/lib/browser/preferences/schema.js.map +1 -1
- package/lib/browser/types.d.ts +4 -0
- package/lib/browser/types.d.ts.map +1 -1
- package/lib/browser/widget/inline-chat/inline-chat-controller.d.ts.map +1 -1
- package/lib/browser/widget/inline-chat/inline-chat-controller.js +6 -1
- package/lib/browser/widget/inline-chat/inline-chat-controller.js.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff-manager.d.ts.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff-manager.js +68 -8
- package/lib/browser/widget/inline-diff/inline-diff-manager.js.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts +10 -4
- package/lib/browser/widget/inline-diff/inline-diff-previewer.d.ts.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff-previewer.js +14 -3
- package/lib/browser/widget/inline-diff/inline-diff-previewer.js.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff-widget.module.less +25 -4
- package/lib/browser/widget/inline-diff/inline-diff.controller.d.ts +3 -3
- package/lib/browser/widget/inline-diff/inline-diff.controller.d.ts.map +1 -1
- package/lib/browser/widget/inline-diff/inline-diff.controller.js +10 -5
- package/lib/browser/widget/inline-diff/inline-diff.controller.js.map +1 -1
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts +46 -17
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.d.ts.map +1 -1
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js +110 -53
- package/lib/browser/widget/inline-stream-diff/inline-stream-diff.handler.js.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts +4 -0
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.d.ts.map +1 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js +26 -1
- package/lib/browser/widget/inline-stream-diff/live-preview.decoration.js.map +1 -1
- package/lib/common/index.d.ts +13 -4
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js +5 -1
- package/lib/common/index.js.map +1 -1
- package/lib/common/llm-context.d.ts +13 -9
- package/lib/common/llm-context.d.ts.map +1 -1
- package/lib/common/llm-context.js.map +1 -1
- package/lib/common/mcp-server-manager.d.ts +17 -1
- package/lib/common/mcp-server-manager.d.ts.map +1 -1
- package/lib/common/mcp-server-manager.js.map +1 -1
- package/lib/common/model.d.ts +12 -0
- package/lib/common/model.d.ts.map +1 -0
- package/lib/common/model.js +83 -0
- package/lib/common/model.js.map +1 -0
- package/lib/common/prompts/context-prompt-provider.d.ts +4 -3
- package/lib/common/prompts/context-prompt-provider.d.ts.map +1 -1
- package/lib/common/prompts/context-prompt-provider.js +33 -22
- package/lib/common/prompts/context-prompt-provider.js.map +1 -1
- package/lib/common/tool-invocation-registry.d.ts +2 -2
- package/lib/common/tool-invocation-registry.d.ts.map +1 -1
- package/lib/common/tool-invocation-registry.js +1 -1
- package/lib/common/tool-invocation-registry.js.map +1 -1
- package/lib/common/types.d.ts +8 -0
- package/lib/common/types.d.ts.map +1 -1
- package/lib/common/utils.d.ts.map +1 -1
- package/lib/common/utils.js +2 -1
- package/lib/common/utils.js.map +1 -1
- package/lib/node/anthropic/anthropic-language-model.d.ts +3 -1
- package/lib/node/anthropic/anthropic-language-model.d.ts.map +1 -1
- package/lib/node/anthropic/anthropic-language-model.js +6 -2
- package/lib/node/anthropic/anthropic-language-model.js.map +1 -1
- package/lib/node/base-language-model.d.ts +6 -3
- package/lib/node/base-language-model.d.ts.map +1 -1
- package/lib/node/base-language-model.js +14 -31
- package/lib/node/base-language-model.js.map +1 -1
- package/lib/node/deepseek/deepseek-language-model.d.ts +3 -1
- package/lib/node/deepseek/deepseek-language-model.d.ts.map +1 -1
- package/lib/node/deepseek/deepseek-language-model.js +6 -2
- package/lib/node/deepseek/deepseek-language-model.js.map +1 -1
- package/lib/node/mcp/sumi-mcp-server.d.ts +17 -3
- package/lib/node/mcp/sumi-mcp-server.d.ts.map +1 -1
- package/lib/node/mcp/sumi-mcp-server.js +59 -6
- package/lib/node/mcp/sumi-mcp-server.js.map +1 -1
- package/lib/node/mcp-server-manager-impl.d.ts +4 -3
- package/lib/node/mcp-server-manager-impl.d.ts.map +1 -1
- package/lib/node/mcp-server-manager-impl.js +26 -6
- package/lib/node/mcp-server-manager-impl.js.map +1 -1
- package/lib/node/mcp-server.d.ts +5 -16
- package/lib/node/mcp-server.d.ts.map +1 -1
- package/lib/node/mcp-server.js +12 -6
- package/lib/node/mcp-server.js.map +1 -1
- package/lib/node/openai/openai-language-model.d.ts +4 -2
- package/lib/node/openai/openai-language-model.d.ts.map +1 -1
- package/lib/node/openai/openai-language-model.js +6 -4
- package/lib/node/openai/openai-language-model.js.map +1 -1
- package/lib/node/openai-compatible/openai-compatible-language-model.d.ts +10 -0
- package/lib/node/openai-compatible/openai-compatible-language-model.d.ts.map +1 -0
- package/lib/node/openai-compatible/openai-compatible-language-model.js +32 -0
- package/lib/node/openai-compatible/openai-compatible-language-model.js.map +1 -0
- package/package.json +27 -26
- package/src/browser/ai-core.contextkeys.ts +3 -3
- package/src/browser/ai-core.contribution.ts +89 -12
- package/src/browser/chat/chat-agent.service.ts +53 -9
- package/src/browser/chat/chat-manager.service.ts +10 -8
- package/src/browser/chat/chat-model.ts +63 -5
- package/src/browser/chat/chat-proxy.service.ts +16 -8
- package/src/browser/chat/chat.api.service.ts +1 -5
- package/src/browser/chat/chat.internal.service.ts +4 -0
- package/src/browser/chat/chat.module.less +1 -2
- package/src/browser/chat/chat.view.tsx +63 -69
- package/src/browser/components/ChatContext/index.tsx +2 -2
- package/src/browser/components/ChatInput.tsx +81 -6
- package/src/browser/components/ChatReply.tsx +6 -6
- package/src/browser/components/ChatThinking.tsx +3 -9
- package/src/browser/components/ChatToolRender.tsx +1 -2
- package/src/browser/components/WelcomeMsg.tsx +1 -1
- package/src/browser/components/chat-history.module.less +2 -1
- package/src/browser/components/components.module.less +22 -0
- package/src/browser/context/llm-context.service.ts +93 -54
- package/src/browser/contrib/inline-completions/inline-completions.controller.ts +1 -1
- package/src/browser/contrib/inline-completions/prompt/matcher.ts +2 -2
- package/src/browser/contrib/inline-completions/prompt/similarSnippets.ts +2 -2
- package/src/browser/contrib/intelligent-completions/index.ts +5 -1
- package/src/browser/contrib/intelligent-completions/intelligent-completions.contribution.ts +3 -3
- package/src/browser/contrib/intelligent-completions/intelligent-completions.controller.ts +7 -6
- package/src/browser/contrib/intelligent-completions/view/code-edits-previewer.ts +4 -2
- package/src/browser/contrib/intelligent-completions/view/default.ts +34 -19
- package/src/browser/index.ts +4 -0
- package/src/browser/layout/layout.module.less +4 -4
- package/src/browser/mcp/base-apply.service.ts +306 -109
- package/src/browser/mcp/config/components/mcp-config.module.less +178 -0
- package/src/browser/mcp/config/components/mcp-config.view.tsx +215 -0
- package/src/browser/mcp/config/components/mcp-server-form.module.less +78 -0
- package/src/browser/mcp/config/components/mcp-server-form.tsx +144 -0
- package/src/browser/mcp/config/mcp-config.commands.ts +29 -0
- package/src/browser/mcp/config/mcp-config.contribution.ts +65 -0
- package/src/browser/mcp/mcp-server-proxy.service.ts +14 -2
- package/src/browser/mcp/mcp-server.feature.registry.ts +35 -4
- package/src/browser/mcp/tools/components/EditFile.tsx +16 -9
- package/src/browser/mcp/tools/components/ExpandableFileList.tsx +133 -0
- package/src/browser/mcp/tools/components/Terminal.tsx +13 -2
- package/src/browser/mcp/tools/components/index.module.less +4 -0
- package/src/browser/mcp/tools/createNewFileWithText.ts +21 -12
- package/src/browser/mcp/tools/fileSearch.ts +14 -4
- package/src/browser/mcp/tools/getDiagnosticsByPath.ts +1 -0
- package/src/browser/mcp/tools/grepSearch.ts +6 -3
- package/src/browser/mcp/tools/handlers/EditFile.ts +1 -1
- package/src/browser/mcp/tools/handlers/ListDir.ts +4 -0
- package/src/browser/mcp/tools/handlers/RunCommand.ts +2 -0
- package/src/browser/mcp/tools/listDir.ts +36 -5
- package/src/browser/mcp/tools/runTerminalCmd.ts +1 -0
- package/src/browser/model/msg-history-manager.ts +5 -11
- package/src/browser/preferences/schema.ts +22 -2
- package/src/browser/types.ts +1 -0
- package/src/browser/widget/inline-chat/inline-chat-controller.ts +5 -1
- package/src/browser/widget/inline-diff/inline-diff-manager.tsx +143 -21
- package/src/browser/widget/inline-diff/inline-diff-previewer.ts +25 -7
- package/src/browser/widget/inline-diff/inline-diff-widget.module.less +25 -4
- package/src/browser/widget/inline-diff/inline-diff.controller.ts +16 -8
- package/src/browser/widget/inline-stream-diff/inline-stream-diff.handler.tsx +139 -68
- package/src/browser/widget/inline-stream-diff/live-preview.decoration.tsx +30 -1
- package/src/common/index.ts +15 -4
- package/src/common/llm-context.ts +10 -4
- package/src/common/mcp-server-manager.ts +17 -1
- package/src/common/model.ts +90 -0
- package/src/common/prompts/context-prompt-provider.ts +38 -29
- package/src/common/tool-invocation-registry.ts +2 -2
- package/src/common/types.ts +8 -0
- package/src/common/utils.ts +3 -1
- package/src/node/anthropic/anthropic-language-model.ts +7 -2
- package/src/node/base-language-model.ts +25 -38
- package/src/node/deepseek/deepseek-language-model.ts +7 -2
- package/src/node/mcp/sumi-mcp-server.ts +67 -9
- package/src/node/mcp-server-manager-impl.ts +30 -9
- package/src/node/mcp-server.ts +11 -14
- package/src/node/openai/openai-language-model.ts +8 -4
- package/src/node/openai-compatible/openai-compatible-language-model.ts +30 -0
- package/lib/browser/mcp/tools/components/SearchResult.d.ts +0 -11
- package/lib/browser/mcp/tools/components/SearchResult.d.ts.map +0 -1
- package/lib/browser/mcp/tools/components/SearchResult.js.map +0 -1
- package/src/browser/mcp/tools/components/SearchResult.tsx +0 -92
|
@@ -1,17 +1,30 @@
|
|
|
1
1
|
import { createPatch } from 'diff';
|
|
2
2
|
|
|
3
3
|
import { Autowired } from '@opensumi/di';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
AIServiceType,
|
|
6
|
+
ActionSourceEnum,
|
|
7
|
+
ActionTypeEnum,
|
|
8
|
+
AppConfig,
|
|
9
|
+
IAIReporter,
|
|
10
|
+
IChatProgress,
|
|
11
|
+
IMarker,
|
|
12
|
+
MarkerSeverity,
|
|
13
|
+
OnEvent,
|
|
14
|
+
WithEventBus,
|
|
15
|
+
} from '@opensumi/ide-core-browser';
|
|
5
16
|
import { WorkbenchEditorService } from '@opensumi/ide-editor';
|
|
6
17
|
import {
|
|
7
18
|
EditorGroupCloseEvent,
|
|
8
19
|
EditorGroupOpenEvent,
|
|
20
|
+
IEditorDocumentModelService,
|
|
9
21
|
RegisterEditorSideComponentEvent,
|
|
10
22
|
} from '@opensumi/ide-editor/lib/browser';
|
|
11
23
|
import { IMarkerService } from '@opensumi/ide-markers';
|
|
12
|
-
import { ICodeEditor, Position, Range, Selection, SelectionDirection } from '@opensumi/ide-monaco';
|
|
13
|
-
import { Deferred, Emitter, URI, path } from '@opensumi/ide-utils';
|
|
24
|
+
import { ICodeEditor, ITextModel, Position, Range, Selection, SelectionDirection } from '@opensumi/ide-monaco';
|
|
25
|
+
import { Deferred, DisposableMap, Emitter, IDisposable, URI, path } from '@opensumi/ide-utils';
|
|
14
26
|
import { SumiReadableStream } from '@opensumi/ide-utils/lib/stream';
|
|
27
|
+
import { EditOperation } from '@opensumi/monaco-editor-core/esm/vs/editor/common/core/editOperation';
|
|
15
28
|
|
|
16
29
|
import { IChatInternalService } from '../../common';
|
|
17
30
|
import { CodeBlockData, CodeBlockStatus } from '../../common/types';
|
|
@@ -23,15 +36,9 @@ import {
|
|
|
23
36
|
InlineDiffService,
|
|
24
37
|
LiveInlineDiffPreviewer,
|
|
25
38
|
} from '../widget/inline-diff';
|
|
26
|
-
import {
|
|
27
|
-
|
|
28
|
-
import { FileHandler } from './tools/handlers/ReadFile';
|
|
39
|
+
import { BaseInlineStreamDiffHandler } from '../widget/inline-stream-diff/inline-stream-diff.handler';
|
|
29
40
|
|
|
30
|
-
// 提供代码块的唯一索引,迭代轮次,生成状态管理(包括取消),关联文件位置这些信息的记录,后续并行 apply 的支持
|
|
31
41
|
export abstract class BaseApplyService extends WithEventBus {
|
|
32
|
-
@Autowired(FileHandler)
|
|
33
|
-
protected fileHandler: FileHandler;
|
|
34
|
-
|
|
35
42
|
@Autowired(IChatInternalService)
|
|
36
43
|
protected chatInternalService: ChatInternalService;
|
|
37
44
|
|
|
@@ -47,14 +54,41 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
47
54
|
@Autowired(IMarkerService)
|
|
48
55
|
private readonly markerService: IMarkerService;
|
|
49
56
|
|
|
57
|
+
@Autowired(IEditorDocumentModelService)
|
|
58
|
+
private readonly editorDocumentModelService: IEditorDocumentModelService;
|
|
59
|
+
|
|
60
|
+
@Autowired(IAIReporter)
|
|
61
|
+
private readonly aiReporter: IAIReporter;
|
|
62
|
+
|
|
50
63
|
private onCodeBlockUpdateEmitter = new Emitter<CodeBlockData>();
|
|
51
64
|
public onCodeBlockUpdate = this.onCodeBlockUpdateEmitter.event;
|
|
52
65
|
|
|
66
|
+
private currentSessionId?: string;
|
|
67
|
+
|
|
53
68
|
constructor() {
|
|
54
69
|
super();
|
|
55
70
|
this.addDispose(
|
|
56
71
|
this.chatInternalService.onCancelRequest(() => {
|
|
57
|
-
this.
|
|
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
|
+
});
|
|
83
|
+
}),
|
|
84
|
+
);
|
|
85
|
+
this.currentSessionId = this.chatInternalService.sessionModel.sessionId;
|
|
86
|
+
this.addDispose(
|
|
87
|
+
this.chatInternalService.onChangeSession((sessionId) => {
|
|
88
|
+
if (sessionId !== this.currentSessionId) {
|
|
89
|
+
this.cancelAllApply();
|
|
90
|
+
this.currentSessionId = sessionId;
|
|
91
|
+
}
|
|
58
92
|
}),
|
|
59
93
|
);
|
|
60
94
|
this.addDispose(
|
|
@@ -70,6 +104,11 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
70
104
|
});
|
|
71
105
|
}),
|
|
72
106
|
);
|
|
107
|
+
this.addDispose(
|
|
108
|
+
this.chatInternalService.onWillClearSession((sessionId) => {
|
|
109
|
+
this.cancelAllApply(sessionId);
|
|
110
|
+
}),
|
|
111
|
+
);
|
|
73
112
|
}
|
|
74
113
|
|
|
75
114
|
private getMessageCodeBlocks(
|
|
@@ -85,46 +124,80 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
85
124
|
return message?.codeBlockMap;
|
|
86
125
|
}
|
|
87
126
|
|
|
88
|
-
private
|
|
127
|
+
private activePreviewerMap = this.registerDispose(
|
|
128
|
+
new DisposableMap<string, BaseInlineDiffPreviewer<BaseInlineStreamDiffHandler>>(),
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
private editorListenerMap = this.registerDispose(new DisposableMap<string, IDisposable>());
|
|
89
132
|
|
|
90
133
|
@OnEvent(EditorGroupCloseEvent)
|
|
91
134
|
onEditorGroupClose(event: EditorGroupCloseEvent) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
135
|
+
const relativePath = path.relative(this.appConfig.workspaceDir, event.payload.resource.uri.path.toString());
|
|
136
|
+
const activePreviewer = this.activePreviewerMap.get(relativePath);
|
|
137
|
+
if (activePreviewer) {
|
|
138
|
+
this.activePreviewerMap.disposeKey(relativePath);
|
|
95
139
|
}
|
|
140
|
+
this.editorListenerMap.disposeKey(event.payload.resource.uri.toString());
|
|
96
141
|
}
|
|
97
142
|
|
|
98
143
|
@OnEvent(EditorGroupOpenEvent)
|
|
99
144
|
async onEditorGroupOpen(event: EditorGroupOpenEvent) {
|
|
100
|
-
|
|
145
|
+
const relativePath = path.relative(this.appConfig.workspaceDir, event.payload.resource.uri.path.toString());
|
|
146
|
+
if (
|
|
147
|
+
this.duringApply ||
|
|
148
|
+
this.activePreviewerMap.has(relativePath) ||
|
|
149
|
+
!this.chatInternalService.sessionModel.history.getMessages().length
|
|
150
|
+
) {
|
|
101
151
|
return;
|
|
102
152
|
}
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if (filePendingApplies.length > 0) {
|
|
110
|
-
this.renderApplyResult(filePendingApplies[0], filePendingApplies[0].updatedCode!);
|
|
153
|
+
const filePendingApplies =
|
|
154
|
+
this.getUriCodeBlocks(event.payload.resource.uri)?.filter((block) => block.status === 'pending') || [];
|
|
155
|
+
// 使用最后一个版本内容渲染 apply 内容
|
|
156
|
+
if (filePendingApplies.length > 0 && filePendingApplies[0].updatedCode) {
|
|
157
|
+
const editor = event.payload.group.codeEditor.monacoEditor;
|
|
158
|
+
this.renderApplyResult(editor, filePendingApplies[0], filePendingApplies[0].updatedCode);
|
|
111
159
|
}
|
|
112
160
|
}
|
|
113
161
|
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
if (!
|
|
162
|
+
get currentPreviewer() {
|
|
163
|
+
const currentUri = this.editorService.currentEditor?.currentUri;
|
|
164
|
+
if (!currentUri) {
|
|
117
165
|
return undefined;
|
|
118
166
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
167
|
+
return this.activePreviewerMap.get(path.relative(this.appConfig.workspaceDir, currentUri.path.toString()));
|
|
168
|
+
}
|
|
169
|
+
|
|
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);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
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
|
+
sessionId = sessionId || this.chatInternalService.sessionModel.sessionId;
|
|
188
|
+
const sessionModel = this.chatInternalService.getSession(sessionId);
|
|
189
|
+
if (!sessionModel) {
|
|
190
|
+
throw new Error(`Session ${sessionId} not found`);
|
|
122
191
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
192
|
+
const sessionAdditionals = sessionModel.history.sessionAdditionals;
|
|
193
|
+
return Array.from(sessionAdditionals.values())
|
|
194
|
+
.map((additional) => (additional.codeBlockMap || {}) as { [toolCallId: string]: CodeBlockData })
|
|
195
|
+
.reduce((acc, cur) => {
|
|
196
|
+
Object.values(cur).forEach((block) => {
|
|
197
|
+
acc.push(block);
|
|
198
|
+
});
|
|
199
|
+
return acc;
|
|
200
|
+
}, [] as CodeBlockData[]);
|
|
128
201
|
}
|
|
129
202
|
|
|
130
203
|
getCodeBlock(toolCallId: string, messageId?: string): CodeBlockData | undefined {
|
|
@@ -139,11 +212,8 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
139
212
|
return codeBlockMap[toolCallId];
|
|
140
213
|
}
|
|
141
214
|
|
|
142
|
-
protected updateCodeBlock(codeBlock: CodeBlockData
|
|
143
|
-
messageId = messageId
|
|
144
|
-
if (!messageId) {
|
|
145
|
-
throw new Error('Message ID is required');
|
|
146
|
-
}
|
|
215
|
+
protected updateCodeBlock(codeBlock: CodeBlockData) {
|
|
216
|
+
const messageId = codeBlock.messageId;
|
|
147
217
|
const codeBlockMap = this.getMessageCodeBlocks(messageId);
|
|
148
218
|
if (!codeBlockMap) {
|
|
149
219
|
throw new Error('Code block not found');
|
|
@@ -155,9 +225,12 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
155
225
|
this.onCodeBlockUpdateEmitter.fire(codeBlock);
|
|
156
226
|
}
|
|
157
227
|
|
|
158
|
-
registerCodeBlock(relativePath: string, content: string, toolCallId: string): CodeBlockData {
|
|
228
|
+
async registerCodeBlock(relativePath: string, content: string, toolCallId: string): Promise<CodeBlockData> {
|
|
159
229
|
const lastMessageId = this.chatInternalService.sessionModel.history.lastMessageId!;
|
|
160
|
-
const
|
|
230
|
+
const uriCodeBlocks = this.getUriCodeBlocks(URI.file(path.join(this.appConfig.workspaceDir, relativePath)));
|
|
231
|
+
const originalModelRef = await this.editorDocumentModelService.createModelReference(
|
|
232
|
+
URI.file(path.join(this.appConfig.workspaceDir, relativePath)),
|
|
233
|
+
);
|
|
161
234
|
const newBlock: CodeBlockData = {
|
|
162
235
|
codeEdit: content,
|
|
163
236
|
relativePath,
|
|
@@ -166,11 +239,13 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
166
239
|
version: 1,
|
|
167
240
|
createdAt: Date.now(),
|
|
168
241
|
toolCallId,
|
|
242
|
+
messageId: lastMessageId,
|
|
243
|
+
// TODO: 支持range
|
|
244
|
+
originalCode: originalModelRef.instance.getText(),
|
|
169
245
|
};
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
for (const block of samePathCodeBlocks.sort((a, b) => b.version - a.version)) {
|
|
246
|
+
if (uriCodeBlocks?.length) {
|
|
247
|
+
newBlock.version = uriCodeBlocks.length;
|
|
248
|
+
for (const block of uriCodeBlocks) {
|
|
174
249
|
// 如果连续的上一个同文件apply结果存在LintError,则iterationCount++
|
|
175
250
|
if (block.relativePath === relativePath && block.applyResult?.diagnosticInfos?.length) {
|
|
176
251
|
newBlock.iterationCount++;
|
|
@@ -179,6 +254,7 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
179
254
|
}
|
|
180
255
|
}
|
|
181
256
|
}
|
|
257
|
+
const savedCodeBlockMap = this.getMessageCodeBlocks(lastMessageId) || {};
|
|
182
258
|
savedCodeBlockMap[toolCallId] = newBlock;
|
|
183
259
|
this.chatInternalService.sessionModel.history.setMessageAdditional(lastMessageId, {
|
|
184
260
|
codeBlockMap: savedCodeBlockMap,
|
|
@@ -187,21 +263,45 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
187
263
|
return newBlock;
|
|
188
264
|
}
|
|
189
265
|
|
|
266
|
+
private duringApply?: boolean;
|
|
267
|
+
|
|
190
268
|
/**
|
|
191
269
|
* Apply changes of a code block
|
|
192
270
|
*/
|
|
193
271
|
async apply(codeBlock: CodeBlockData): Promise<CodeBlockData> {
|
|
194
272
|
try {
|
|
273
|
+
this.duringApply = true;
|
|
195
274
|
if (codeBlock.iterationCount > 3) {
|
|
196
275
|
throw new Error('Lint error max iteration count exceeded');
|
|
197
276
|
}
|
|
198
|
-
|
|
277
|
+
// 新建文件场景,直接返回codeEdit
|
|
278
|
+
const fastApplyFileResult = !codeBlock.originalCode
|
|
279
|
+
? {
|
|
280
|
+
result: codeBlock.codeEdit,
|
|
281
|
+
}
|
|
282
|
+
: await this.doApply(codeBlock);
|
|
199
283
|
if (!fastApplyFileResult.stream && !fastApplyFileResult.result) {
|
|
200
284
|
throw new Error('No apply content provided');
|
|
201
285
|
}
|
|
202
286
|
|
|
287
|
+
if (this.activePreviewerMap.has(codeBlock.relativePath)) {
|
|
288
|
+
// 有正在进行的 apply,则取消(但不更新block状态,只清理副作用)
|
|
289
|
+
this.cancelApply(codeBlock, true);
|
|
290
|
+
}
|
|
203
291
|
// trigger diffPreivewer & return expected diff result directly
|
|
292
|
+
const result = await this.editorService.open(
|
|
293
|
+
URI.file(path.join(this.appConfig.workspaceDir, codeBlock.relativePath)),
|
|
294
|
+
);
|
|
295
|
+
if (!result) {
|
|
296
|
+
throw new Error('Failed to open file');
|
|
297
|
+
}
|
|
298
|
+
if (typeof fastApplyFileResult.result === 'string') {
|
|
299
|
+
codeBlock.updatedCode = fastApplyFileResult.result;
|
|
300
|
+
codeBlock.status = 'pending';
|
|
301
|
+
this.updateCodeBlock(codeBlock);
|
|
302
|
+
}
|
|
204
303
|
const applyResult = await this.renderApplyResult(
|
|
304
|
+
result.group.codeEditor.monacoEditor,
|
|
205
305
|
codeBlock,
|
|
206
306
|
(fastApplyFileResult.result || fastApplyFileResult.stream)!,
|
|
207
307
|
fastApplyFileResult.range,
|
|
@@ -217,31 +317,37 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
217
317
|
codeBlock.status = 'failed';
|
|
218
318
|
this.updateCodeBlock(codeBlock);
|
|
219
319
|
throw err;
|
|
320
|
+
} finally {
|
|
321
|
+
this.duringApply = false;
|
|
220
322
|
}
|
|
221
323
|
}
|
|
222
324
|
|
|
223
325
|
async renderApplyResult(
|
|
326
|
+
editor: ICodeEditor,
|
|
224
327
|
codeBlock: CodeBlockData,
|
|
225
328
|
updatedContentOrStream: string | SumiReadableStream<IChatProgress>,
|
|
226
329
|
range?: Range,
|
|
227
330
|
): Promise<{ diff: string; diagnosticInfos: IMarker[] } | undefined> {
|
|
228
|
-
const {
|
|
229
|
-
const openResult = await this.editorService.open(URI.file(path.join(this.appConfig.workspaceDir, relativePath)));
|
|
230
|
-
if (!openResult) {
|
|
231
|
-
throw new Error('Failed to open editor');
|
|
232
|
-
}
|
|
233
|
-
const editor = openResult.group.codeEditor.monacoEditor;
|
|
331
|
+
const deferred = new Deferred<{ diff: string; diagnosticInfos: IMarker[] }>();
|
|
234
332
|
const inlineDiffController = InlineDiffController.get(editor)!;
|
|
235
|
-
|
|
236
|
-
// 强刷展示 manager 视图
|
|
237
|
-
this.eventBus.fire(new RegisterEditorSideComponentEvent());
|
|
238
|
-
this.updateCodeBlock(codeBlock);
|
|
239
|
-
|
|
240
|
-
const fullOriginalContent = editor.getModel()!.getValue();
|
|
241
|
-
range = range || editor.getModel()?.getFullModelRange()!;
|
|
242
|
-
// const savedRangeContent = editor.getModel()!.getValueInRange(range);
|
|
333
|
+
range = range || editor.getModel()!.getFullModelRange();
|
|
243
334
|
|
|
244
335
|
if (typeof updatedContentOrStream === 'string') {
|
|
336
|
+
const editorCurrentContent = editor.getModel()!.getValue();
|
|
337
|
+
const uri = URI.file(path.join(this.appConfig.workspaceDir, codeBlock.relativePath));
|
|
338
|
+
const document = this.editorDocumentModelService.getModelReference(uri);
|
|
339
|
+
if (editorCurrentContent !== updatedContentOrStream || document?.instance.dirty) {
|
|
340
|
+
editor.getModel()?.pushEditOperations([], [EditOperation.replace(range, updatedContentOrStream)], () => null);
|
|
341
|
+
await this.editorService.save(uri);
|
|
342
|
+
}
|
|
343
|
+
const uriPendingCodeBlocks = this.getUriCodeBlocks(uri)?.filter((block) => block.status === 'pending');
|
|
344
|
+
const earlistPendingCodeBlock = uriPendingCodeBlocks?.[uriPendingCodeBlocks.length - 1];
|
|
345
|
+
if ((earlistPendingCodeBlock?.originalCode || codeBlock.originalCode) === updatedContentOrStream) {
|
|
346
|
+
codeBlock.status = 'cancelled';
|
|
347
|
+
this.updateCodeBlock(codeBlock);
|
|
348
|
+
deferred.resolve();
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
245
351
|
// Create diff previewer
|
|
246
352
|
const previewer = inlineDiffController.createDiffPreviewer(
|
|
247
353
|
editor,
|
|
@@ -249,18 +355,38 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
249
355
|
{
|
|
250
356
|
disposeWhenEditorClosed: true,
|
|
251
357
|
renderRemovedWidgetImmediately: true,
|
|
358
|
+
reverse: true,
|
|
252
359
|
},
|
|
253
360
|
) as LiveInlineDiffPreviewer;
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
codeBlock.
|
|
257
|
-
|
|
361
|
+
this.activePreviewerMap.set(codeBlock.relativePath, previewer);
|
|
362
|
+
// 新建文件场景,为避免model为空,加一个空行
|
|
363
|
+
previewer.setValue(earlistPendingCodeBlock?.originalCode || codeBlock.originalCode || '\n');
|
|
364
|
+
// 强刷展示 manager 视图
|
|
365
|
+
this.eventBus.fire(new RegisterEditorSideComponentEvent());
|
|
366
|
+
|
|
367
|
+
this.listenPartialEdit(editor.getModel()!, codeBlock).then((result) => {
|
|
368
|
+
if (result) {
|
|
369
|
+
codeBlock.applyResult = result;
|
|
370
|
+
}
|
|
371
|
+
this.updateCodeBlock(codeBlock);
|
|
372
|
+
this.editorService.save(URI.file(path.join(this.appConfig.workspaceDir, codeBlock.relativePath)));
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
const { diff, rangesFromDiffHunk } = this.getDiffResult(
|
|
376
|
+
codeBlock.originalCode,
|
|
377
|
+
codeBlock.updatedCode || updatedContentOrStream,
|
|
378
|
+
codeBlock.relativePath,
|
|
379
|
+
);
|
|
380
|
+
const diagnosticInfos = this.getDiagnosticInfos(editor.getModel()!.uri.toString(), rangesFromDiffHunk);
|
|
381
|
+
deferred.resolve({
|
|
382
|
+
diff,
|
|
383
|
+
diagnosticInfos,
|
|
384
|
+
});
|
|
258
385
|
} else {
|
|
259
386
|
const controller = new InlineChatController();
|
|
260
387
|
controller.mountReadable(updatedContentOrStream);
|
|
261
|
-
const inlineDiffHandler = InlineDiffController.get(editor)!;
|
|
262
388
|
|
|
263
|
-
|
|
389
|
+
const previewer = inlineDiffController.showPreviewerByStream(editor, {
|
|
264
390
|
crossSelection: Selection.fromRange(range, SelectionDirection.LTR),
|
|
265
391
|
chatResponse: controller,
|
|
266
392
|
previewerOptions: {
|
|
@@ -268,39 +394,68 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
268
394
|
renderRemovedWidgetImmediately: false,
|
|
269
395
|
},
|
|
270
396
|
}) as LiveInlineDiffPreviewer;
|
|
397
|
+
|
|
271
398
|
this.addDispose(
|
|
272
|
-
|
|
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
|
+
this.addDispose(
|
|
409
|
+
// 流式输出结束后,转为直接输出逻辑
|
|
410
|
+
previewer.getNode()!.onDiffFinished(async (diffModel) => {
|
|
273
411
|
codeBlock.updatedCode = diffModel.newFullRangeTextLines.join('\n');
|
|
412
|
+
// TODO: 添加 reapply
|
|
413
|
+
// 实际应用结果为空,则取消
|
|
414
|
+
if (codeBlock.updatedCode === codeBlock.originalCode) {
|
|
415
|
+
codeBlock.status = 'failed';
|
|
416
|
+
this.updateCodeBlock(codeBlock);
|
|
417
|
+
previewer.dispose();
|
|
418
|
+
deferred.reject(new Error('no changes applied'));
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
codeBlock.status = 'pending';
|
|
274
422
|
this.updateCodeBlock(codeBlock);
|
|
423
|
+
previewer.dispose();
|
|
424
|
+
const result = await this.renderApplyResult(editor, codeBlock, codeBlock.updatedCode);
|
|
425
|
+
deferred.resolve(result);
|
|
275
426
|
}),
|
|
276
427
|
);
|
|
428
|
+
this.activePreviewerMap.set(codeBlock.relativePath, previewer);
|
|
277
429
|
}
|
|
278
|
-
|
|
279
|
-
return this.listenPartialEdit(editor, codeBlock, fullOriginalContent);
|
|
430
|
+
return deferred.promise;
|
|
280
431
|
}
|
|
281
432
|
|
|
282
433
|
/**
|
|
283
434
|
* Cancel an ongoing apply operation
|
|
284
435
|
*/
|
|
285
|
-
cancelApply(blockData: CodeBlockData): void {
|
|
436
|
+
cancelApply(blockData: CodeBlockData, keepStatus?: boolean): void {
|
|
286
437
|
if (blockData.status === 'generating' || blockData.status === 'pending') {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
this.
|
|
438
|
+
// 先取消掉相关的监听器
|
|
439
|
+
this.editorListenerMap.disposeKey(
|
|
440
|
+
URI.file(path.join(this.appConfig.workspaceDir, blockData.relativePath)).toString(),
|
|
441
|
+
);
|
|
442
|
+
if (this.activePreviewerMap.has(blockData.relativePath)) {
|
|
443
|
+
this.activePreviewerMap
|
|
444
|
+
.get(blockData.relativePath)
|
|
445
|
+
?.getNode()
|
|
446
|
+
?.livePreviewDiffDecorationModel.discardUnProcessed();
|
|
447
|
+
this.activePreviewerMap.disposeKey(blockData.relativePath);
|
|
448
|
+
}
|
|
449
|
+
if (!keepStatus) {
|
|
450
|
+
blockData.status = 'cancelled';
|
|
451
|
+
this.updateCodeBlock(blockData);
|
|
290
452
|
}
|
|
291
|
-
blockData.status = 'cancelled';
|
|
292
|
-
this.updateCodeBlock(blockData);
|
|
293
453
|
}
|
|
294
454
|
}
|
|
295
455
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
const codeBlockMap = this.getMessageCodeBlocks(messageId);
|
|
300
|
-
if (!codeBlockMap) {
|
|
301
|
-
return;
|
|
302
|
-
}
|
|
303
|
-
Object.values(codeBlockMap).forEach((blockData) => {
|
|
456
|
+
cancelAllApply(sessionId?: string): void {
|
|
457
|
+
const sessionCodeBlocks = this.getSessionCodeBlocks(sessionId);
|
|
458
|
+
sessionCodeBlocks.forEach((blockData) => {
|
|
304
459
|
this.cancelApply(blockData);
|
|
305
460
|
});
|
|
306
461
|
}
|
|
@@ -323,11 +478,13 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
323
478
|
}
|
|
324
479
|
|
|
325
480
|
processAll(uri: URI, type: 'accept' | 'reject'): void {
|
|
326
|
-
const
|
|
327
|
-
if (!
|
|
481
|
+
const codeBlocks = this.getUriCodeBlocks(uri)?.filter((block) => block.status === 'pending');
|
|
482
|
+
if (!codeBlocks?.length) {
|
|
328
483
|
throw new Error('No pending code block found');
|
|
329
484
|
}
|
|
330
|
-
const decorationModel = this.
|
|
485
|
+
const decorationModel = this.activePreviewerMap
|
|
486
|
+
.get(codeBlocks[0].relativePath)
|
|
487
|
+
?.getNode()?.livePreviewDiffDecorationModel;
|
|
331
488
|
if (!decorationModel) {
|
|
332
489
|
throw new Error('No active previewer found');
|
|
333
490
|
}
|
|
@@ -337,49 +494,89 @@ export abstract class BaseApplyService extends WithEventBus {
|
|
|
337
494
|
decorationModel.discardUnProcessed();
|
|
338
495
|
}
|
|
339
496
|
this.editorService.save(uri);
|
|
340
|
-
codeBlock
|
|
341
|
-
|
|
497
|
+
codeBlocks.forEach((codeBlock) => {
|
|
498
|
+
codeBlock.status = type === 'accept' ? 'success' : 'cancelled';
|
|
499
|
+
// TODO: 批量更新
|
|
500
|
+
this.updateCodeBlock(codeBlock);
|
|
501
|
+
});
|
|
342
502
|
}
|
|
343
503
|
|
|
344
|
-
protected listenPartialEdit(
|
|
504
|
+
protected listenPartialEdit(model: ITextModel, codeBlock: CodeBlockData) {
|
|
345
505
|
const deferred = new Deferred<{ diff: string; diagnosticInfos: IMarker[] }>();
|
|
506
|
+
const uriString = model.uri.toString();
|
|
346
507
|
const toDispose = this.inlineDiffService.onPartialEdit((event) => {
|
|
347
508
|
// TODO 支持自动保存
|
|
348
|
-
if (
|
|
509
|
+
if (
|
|
510
|
+
event.totalPartialEditCount === event.resolvedPartialEditCount &&
|
|
511
|
+
event.uri.path === model.uri.path.toString()
|
|
512
|
+
) {
|
|
349
513
|
if (event.acceptPartialEditCount > 0) {
|
|
350
514
|
codeBlock.status = 'success';
|
|
351
|
-
const appliedResult =
|
|
352
|
-
const
|
|
353
|
-
.
|
|
354
|
-
|
|
355
|
-
.
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
.map((line) => {
|
|
359
|
-
if (line.startsWith('@@')) {
|
|
360
|
-
const [, , , start, end] = line.match(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/)!;
|
|
361
|
-
return new Range(parseInt(start, 10), 0, parseInt(end, 10), 0);
|
|
362
|
-
}
|
|
363
|
-
return null;
|
|
364
|
-
})
|
|
365
|
-
.filter((range) => range !== null);
|
|
366
|
-
const diagnosticInfos = this.getDiagnosticInfos(editor.getModel()!.uri.toString(), rangesFromDiffHunk);
|
|
515
|
+
const appliedResult = model.getValue();
|
|
516
|
+
const { diff, rangesFromDiffHunk } = this.getDiffResult(
|
|
517
|
+
codeBlock.originalCode,
|
|
518
|
+
appliedResult,
|
|
519
|
+
codeBlock.relativePath,
|
|
520
|
+
);
|
|
521
|
+
const diagnosticInfos = this.getDiagnosticInfos(model.uri.toString(), rangesFromDiffHunk);
|
|
367
522
|
// 移除开头的几个固定信息,避免浪费 tokens
|
|
523
|
+
this.aiReporter.send({
|
|
524
|
+
msgType: AIServiceType.Chat,
|
|
525
|
+
actionType: ActionTypeEnum.Accept,
|
|
526
|
+
actionSource: ActionSourceEnum.Chat,
|
|
527
|
+
sessionId: this.chatInternalService.sessionModel.sessionId,
|
|
528
|
+
isReceive: true,
|
|
529
|
+
isDrop: false,
|
|
530
|
+
code: codeBlock.codeEdit,
|
|
531
|
+
message: JSON.stringify({
|
|
532
|
+
diff,
|
|
533
|
+
diagnosticInfos,
|
|
534
|
+
}),
|
|
535
|
+
});
|
|
368
536
|
deferred.resolve({
|
|
369
|
-
diff
|
|
537
|
+
diff,
|
|
370
538
|
diagnosticInfos,
|
|
371
539
|
});
|
|
372
540
|
} else {
|
|
373
541
|
// 用户全部取消
|
|
374
542
|
codeBlock.status = 'cancelled';
|
|
375
543
|
deferred.resolve();
|
|
544
|
+
this.aiReporter.send({
|
|
545
|
+
msgType: AIServiceType.Chat,
|
|
546
|
+
actionType: ActionTypeEnum.Discard,
|
|
547
|
+
actionSource: ActionSourceEnum.Chat,
|
|
548
|
+
sessionId: this.chatInternalService.sessionModel.sessionId,
|
|
549
|
+
isReceive: false,
|
|
550
|
+
isDrop: true,
|
|
551
|
+
code: codeBlock.codeEdit,
|
|
552
|
+
originCode: codeBlock.originalCode,
|
|
553
|
+
});
|
|
376
554
|
}
|
|
377
|
-
|
|
555
|
+
this.editorListenerMap.disposeKey(uriString);
|
|
378
556
|
}
|
|
379
557
|
});
|
|
558
|
+
this.editorListenerMap.set(uriString, toDispose);
|
|
380
559
|
return deferred.promise;
|
|
381
560
|
}
|
|
382
561
|
|
|
562
|
+
protected getDiffResult(originalContent: string, appliedResult: string, relativePath: string) {
|
|
563
|
+
const diffResult = createPatch(relativePath, originalContent, appliedResult).split('\n').slice(4).join('\n');
|
|
564
|
+
const rangesFromDiffHunk = diffResult
|
|
565
|
+
.split('\n')
|
|
566
|
+
.map((line) => {
|
|
567
|
+
if (line.startsWith('@@')) {
|
|
568
|
+
const [, , , start, end] = line.match(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/)!;
|
|
569
|
+
return new Range(parseInt(start, 10), 0, parseInt(end, 10), 0);
|
|
570
|
+
}
|
|
571
|
+
return null;
|
|
572
|
+
})
|
|
573
|
+
.filter((range) => range !== null);
|
|
574
|
+
return {
|
|
575
|
+
diff: diffResult,
|
|
576
|
+
rangesFromDiffHunk,
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
|
|
383
580
|
/**
|
|
384
581
|
* Apply changes of a code block, return stream to render inline diff in stream mode, result to render inline diff directly
|
|
385
582
|
* range is optional, if not provided, the result will be applied to the the full file
|