Skip to content

Commit cca5fdb

Browse files
authored
feat: 实现 Code Edits (#56)
1 parent 17c4a92 commit cca5fdb

File tree

2 files changed

+86
-3
lines changed

2 files changed

+86
-3
lines changed

src/ai/browser/ai-native.contribution.ts

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@ import {
88
IAIBackService,
99
CancellationToken,
1010
ChatResponse,
11+
ECodeEditsSourceTyping,
1112
} from '@opensumi/ide-core-common';
1213
import { ClientAppContribution, Domain, getIcon } from '@opensumi/ide-core-browser';
1314
import { ComponentContribution, ComponentRegistry } from '@opensumi/ide-core-browser/lib/layout';
14-
import { AINativeCoreContribution, ERunStrategy, IChatFeatureRegistry, IInlineChatFeatureRegistry, IProblemFixContext, IProblemFixProviderRegistry, IRenameCandidatesProviderRegistry, ITerminalProviderRegistry, TChatSlashCommandSend, TerminalSuggestionReadableStream } from '@opensumi/ide-ai-native/lib/browser/types';
15-
import { ICodeEditor, MarkdownString, NewSymbolNameTag } from '@opensumi/ide-monaco';
15+
import { AINativeCoreContribution, ERunStrategy, IChatFeatureRegistry, IInlineChatFeatureRegistry, IIntelligentCompletionsRegistry, IProblemFixContext, IProblemFixProviderRegistry, IRenameCandidatesProviderRegistry, ITerminalProviderRegistry, TChatSlashCommandSend, TerminalSuggestionReadableStream } from '@opensumi/ide-ai-native/lib/browser/types';
16+
import { ICodeEditor, MarkdownString, NewSymbolNameTag, Range } from '@opensumi/ide-monaco';
1617
import { MessageService } from '@opensumi/ide-overlay/lib/browser/message.service';
1718
import { BaseTerminalDetectionLineMatcher, JavaMatcher, MatcherType, NodeMatcher, NPMMatcher, ShellMatcher, TSCMatcher } from '@opensumi/ide-ai-native/lib/browser/contrib/terminal/matcher';
1819
import { ChatService } from '@opensumi/ide-ai-native/lib/browser/chat/chat.api.service';
@@ -22,12 +23,13 @@ import { listenReadable } from '@opensumi/ide-utils/lib/stream';
2223

2324
import { AI_MENU_BAR_LEFT_ACTION, EInlineOperation } from './constants'
2425
import { LeftToolbar } from './components/left-toolbar'
25-
import { explainPrompt, testPrompt, optimizePrompt, detectIntentPrompt, RenamePromptManager, terminalCommandSuggestionPrompt } from './prompt'
26+
import { explainPrompt, testPrompt, optimizePrompt, detectIntentPrompt, RenamePromptManager, terminalCommandSuggestionPrompt, codeEditsLintErrorPrompt } from './prompt'
2627
import { CommandRender } from './command/command-render'
2728
import { AITerminalDebugService } from './ai-terminal-debug.service'
2829
import { InlineChatOperationModel } from './inline-chat-operation'
2930
import { AICommandService } from './command/command.service'
3031
import hiPng from './assets/hi.png'
32+
import { ILinterErrorData } from '@opensumi/ide-ai-native/lib/browser/contrib/intelligent-completions/source/lint-error.source';
3133

3234
@Domain(ComponentContribution, AINativeCoreContribution)
3335
export class AINativeContribution implements ComponentContribution, AINativeCoreContribution {
@@ -551,4 +553,47 @@ ${editor.getModel()!.getValueInRange(editRange)}
551553
},
552554
});
553555
}
556+
557+
registerIntelligentCompletionFeature(registry: IIntelligentCompletionsRegistry): void {
558+
registry.registerCodeEditsProvider(async (editor, _position, bean, token) => {
559+
const model = editor.getModel();
560+
if (!model) {
561+
return;
562+
}
563+
564+
if (bean.typing === ECodeEditsSourceTyping.LinterErrors) {
565+
const errors = (bean.data as ILinterErrorData).errors;
566+
567+
if (errors.length === 0) {
568+
return;
569+
}
570+
571+
const lastItem = errors[errors.length - 1];
572+
const lastRange = lastItem.range;
573+
574+
const waringRange = Range.fromPositions(
575+
{ lineNumber: errors[0].range.startPosition.lineNumber, column: 1 },
576+
{ lineNumber: lastRange.endPosition.lineNumber, column: model!.getLineMaxColumn(lastRange.endPosition.lineNumber) }
577+
);
578+
579+
const prompt = codeEditsLintErrorPrompt(model.getValueInRange(waringRange), errors);
580+
const response = await this.aiBackService.request(prompt, {}, token);
581+
582+
if (response.data) {
583+
const controller = new InlineChatController({ enableCodeblockRender: true });
584+
const codeData = controller['calculateCodeBlocks'](response.data);
585+
586+
return {
587+
items: [
588+
{
589+
insertText: codeData,
590+
range: waringRange
591+
}
592+
]
593+
};
594+
}
595+
}
596+
return undefined;
597+
});
598+
}
554599
}

src/ai/browser/prompt.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { IMarkerErrorData } from '@opensumi/ide-ai-native/lib/browser/contrib/intelligent-completions/source/lint-error.source';
12
import { EInlineOperation } from './constants'
23

34
export const explainPrompt = (language: string, code: string) => {
@@ -87,3 +88,40 @@ ${below.slice(0, 500)}
8788
return lines;
8889
}
8990
}
91+
92+
93+
export const codeEditsLintErrorPrompt = (text: string, errors: IMarkerErrorData[]) => {
94+
return `
95+
#Role: 代码领域的 IDE 专家
96+
97+
#Profile:
98+
- description: 熟悉各种编程语言并擅长解决由语言服务引起的各种问题,能够快速定位问题并提供解决方案,专注于代码质量和错误修复的专家
99+
100+
##Goals:
101+
- 修复代码中的 error 错误,提升代码质量
102+
103+
##Constrains:
104+
- 仅修改必要的代码以修复错误
105+
- 保持代码的原始功能和逻辑不变
106+
- 保持代码的缩进规则不变,这是强规定,你需要检查代码的缩进规则,并保持这个缩进规则
107+
108+
##Skills:
109+
- 熟悉 Java/TypeScript/JavaScript/Python 等语言
110+
- 能够根据错误信息快速定位问题并提供解决方案
111+
112+
##Workflows:
113+
- 分析提供的代码和错误信息
114+
- 提供修复步骤和修改后的代码
115+
116+
##CodeSnippet:
117+
- 以下是有问题的代码片段
118+
\`\`\`
119+
${text}
120+
\`\`\`
121+
122+
##LintErrors:
123+
${JSON.stringify(errors.map(e => ({ message: e.message })))}
124+
125+
请根据上述错误信息,直接提供修复后的代码,不需要解释
126+
`;
127+
};

0 commit comments

Comments
 (0)