Skip to content

feat: 实现 Code Edits #56

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 48 additions & 3 deletions src/ai/browser/ai-native.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import {
IAIBackService,
CancellationToken,
ChatResponse,
ECodeEditsSourceTyping,
} from '@opensumi/ide-core-common';
import { ClientAppContribution, Domain, getIcon } from '@opensumi/ide-core-browser';
import { ComponentContribution, ComponentRegistry } from '@opensumi/ide-core-browser/lib/layout';
import { AINativeCoreContribution, ERunStrategy, IChatFeatureRegistry, IInlineChatFeatureRegistry, IProblemFixContext, IProblemFixProviderRegistry, IRenameCandidatesProviderRegistry, ITerminalProviderRegistry, TChatSlashCommandSend, TerminalSuggestionReadableStream } from '@opensumi/ide-ai-native/lib/browser/types';
import { ICodeEditor, MarkdownString, NewSymbolNameTag } from '@opensumi/ide-monaco';
import { AINativeCoreContribution, ERunStrategy, IChatFeatureRegistry, IInlineChatFeatureRegistry, IIntelligentCompletionsRegistry, IProblemFixContext, IProblemFixProviderRegistry, IRenameCandidatesProviderRegistry, ITerminalProviderRegistry, TChatSlashCommandSend, TerminalSuggestionReadableStream } from '@opensumi/ide-ai-native/lib/browser/types';
import { ICodeEditor, MarkdownString, NewSymbolNameTag, Range } from '@opensumi/ide-monaco';
import { MessageService } from '@opensumi/ide-overlay/lib/browser/message.service';
import { BaseTerminalDetectionLineMatcher, JavaMatcher, MatcherType, NodeMatcher, NPMMatcher, ShellMatcher, TSCMatcher } from '@opensumi/ide-ai-native/lib/browser/contrib/terminal/matcher';
import { ChatService } from '@opensumi/ide-ai-native/lib/browser/chat/chat.api.service';
Expand All @@ -22,12 +23,13 @@ import { listenReadable } from '@opensumi/ide-utils/lib/stream';

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

@Domain(ComponentContribution, AINativeCoreContribution)
export class AINativeContribution implements ComponentContribution, AINativeCoreContribution {
Expand Down Expand Up @@ -551,4 +553,47 @@ ${editor.getModel()!.getValueInRange(editRange)}
},
});
}

registerIntelligentCompletionFeature(registry: IIntelligentCompletionsRegistry): void {
registry.registerCodeEditsProvider(async (editor, _position, bean, token) => {
const model = editor.getModel();
if (!model) {
return;
}

if (bean.typing === ECodeEditsSourceTyping.LinterErrors) {
const errors = (bean.data as ILinterErrorData).errors;

if (errors.length === 0) {
return;
}

const lastItem = errors[errors.length - 1];
const lastRange = lastItem.range;

const waringRange = Range.fromPositions(
{ lineNumber: errors[0].range.startPosition.lineNumber, column: 1 },
{ lineNumber: lastRange.endPosition.lineNumber, column: model!.getLineMaxColumn(lastRange.endPosition.lineNumber) }
);

const prompt = codeEditsLintErrorPrompt(model.getValueInRange(waringRange), errors);
const response = await this.aiBackService.request(prompt, {}, token);

if (response.data) {
const controller = new InlineChatController({ enableCodeblockRender: true });
const codeData = controller['calculateCodeBlocks'](response.data);

return {
items: [
{
insertText: codeData,
range: waringRange
}
]
};
}
}
return undefined;
});
}
}
38 changes: 38 additions & 0 deletions src/ai/browser/prompt.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { IMarkerErrorData } from '@opensumi/ide-ai-native/lib/browser/contrib/intelligent-completions/source/lint-error.source';
import { EInlineOperation } from './constants'

export const explainPrompt = (language: string, code: string) => {
Expand Down Expand Up @@ -87,3 +88,40 @@ ${below.slice(0, 500)}
return lines;
}
}


export const codeEditsLintErrorPrompt = (text: string, errors: IMarkerErrorData[]) => {
return `
#Role: 代码领域的 IDE 专家

#Profile:
- description: 熟悉各种编程语言并擅长解决由语言服务引起的各种问题,能够快速定位问题并提供解决方案,专注于代码质量和错误修复的专家

##Goals:
- 修复代码中的 error 错误,提升代码质量

##Constrains:
- 仅修改必要的代码以修复错误
- 保持代码的原始功能和逻辑不变
- 保持代码的缩进规则不变,这是强规定,你需要检查代码的缩进规则,并保持这个缩进规则

##Skills:
- 熟悉 Java/TypeScript/JavaScript/Python 等语言
- 能够根据错误信息快速定位问题并提供解决方案

##Workflows:
- 分析提供的代码和错误信息
- 提供修复步骤和修改后的代码

##CodeSnippet:
- 以下是有问题的代码片段
\`\`\`
${text}
\`\`\`

##LintErrors:
${JSON.stringify(errors.map(e => ({ message: e.message })))}

请根据上述错误信息,直接提供修复后的代码,不需要解释
`;
};