🧙♂️ AutoDev: The AI-powered coding wizard with multilingual support 🌐, auto code generation 🏗️, and a helpful bug-slaying assistant 🐞! Customizable prompts 🎨 and a magic Auto Testing feature 🧪 included! 🚀
features:
- languages support: Java, Kotlin, Python, JavaScript, or others...
- Auto development mode. With DevTi Protocol (like
devti://story/github/1102
) will auto generate Model-Controller-Service-Repository code. - Smart code completion.
- Pattern specific.Based on your code context like (Controller, Service
import
), AutoDev will suggest you the best code. - Related code. Based on recently file changes, AutoDev will call calculate similar chunk to generate best code.
- Pattern specific.Based on your code context like (Controller, Service
- AI assistant. AutoDev will help you find bug, explain code, trace exception, generate commits, and more.
- Custom prompt. You can customize your prompt in
Settings
->Tools
->AutoDev
- Custom LLM Server. You can customize your LLM Server in
Settings
->Tools
->AutoDev
- Auto Testing. create unit test intention, auto run unit test and try to fix test.
- Install from JetBrains Plugin Repository: AutoDev
- Configure GitHub Token (optional) and OpenAI config in
Settings
->Tools
->AutoDev
You can:
- Right-click on the code editor, select
AutoDev
->CodeCompletion
->CodeComplete
- or use
Alt + Enter
to openIntention Actions
menu, selectAutoDev
->CodeCompletion
{
"auto_complete": {
"instruction": "",
"input": ""
},
"auto_comment": {
"instruction": "",
"input": ""
},
"code_review": {
"instruction": "",
"input": ""
},
"refactor": {
"instruction": "",
"input": ""
},
"write_test": {
"instruction": "",
"input": ""
},
"spec": {
"controller": "- 在 Controller 中使用 BeanUtils.copyProperties 进行 DTO 转换 Entity\n- 禁止使用 Autowired\n-使用 Swagger Annotation 表明 API 含义\n-Controller 方法应该捕获并处理业务异常,不应该抛出系统异常。",
"service": "- Service 层应该使用构造函数注入或者 setter 注入,不要使用 @Autowired 注解注入。",
"entity": "- Entity 类应该使用 JPA 注解进行数据库映射\n- 实体类名应该与对应的数据库表名相同。实体类应该使用注解标记主键和表名,例如:@Id、@GeneratedValue、@Table 等。",
"repository": "- Repository 接口应该继承 JpaRepository 接口,以获得基本的 CRUD 操作",
"ddl": "- 字段应该使用 NOT NULL 约束,确保数据的完整性"
}
}
- add
// devti://story/github/1
comments in your code. - configure GitHub repository for Run Configuration.
- click
AutoDev
button in the comments' left.
Run Screenshots:
Output Screenshots:
git clone https://github.com/unit-mesh/auto-dev/
- open in IntelliJ IDEA
./gradlew runIde
Key Concepts:
- Workflow flow design: DevFlowProvider
- Prompt Strategy design: PromptStrategyAdvisor
- change
pluginVersion
in gradle.properties - git tag
version
./gradlew publishPlugin
Your LLM API example:
POST http://127.0.0.1:8000/chat
Content-Type: application/json
{
"instruction": "code complete given code:\n```java public class Main {\n public static void main(String[] args) {",
"input":""
}
### Response:
### "Here's an explanation of the given code:\n\n```\npublic class Main {\n```\nThis line defines the name of the main class as `Main`.\n```\npublic static void main(String[] args) {\n```\nThis line defines the `main` method as the entry point of the program. The `public`, `static`, and `void` access modifiers indicate that this method can be accessed directly from outside the class, it is static in nature and it does not take arguments.\n```\n String[] args = new String[1];\n args[0] = \"Hello\";\n args[1] = \"World\";\n \n // Do something with the arguments\n}\n```\nThis line declares a variable `args` of type `String` and initializes it with an array of one element `String` object. The elements of the array are assigned the values \"Hello\" and \"World\" respectively.\n```\n String[] args = new String[1];\n args[0] = \"Hello\";\n args[1] = \"World\";\n \n // Do something with the arguments\n}\n```\nThis line declares a variable `args` of type `String` and initializes it with an array of one element `String` object. The elements of the array are assigned the values \"Hello\" and \"World\" respectively.\n```\n public static void main(String[] args) {\n```\nThis line refers to the `main` method defined in the previous class and passes it the argument array `args`.\n```\n String[] args = new String[1];\n args[0] = \"Hello\";\n args[1] = \"World\";\n \n // Do something with the arguments\n}\n```\nThis line refers to the `main` method defined in the previous class and passes it the argument array `args`.\n```\n}\n```\nThis curly brace closes the `main` method.\n```\n}\n```\nThis curly brace closes the `main` method.\n```\n```\n\nOverall, this code creates a variable `args` of type `String` and assigns it an array of one element with the values \"Hello\" and \"World\". The `main` method is called and passes the argument array `args` to it."
python code example: main.py
class MessageInput(BaseModel):
instruction: str
input: str
@app.post("/chat")
async def chat(data: MessageInput):
input = {} # your backend data
response = requests.post("your_llm_server", json={
# your backend data
}).json()
return response["data"][0]
We referenced the multi-language support implementation of JetBrains AI Assistant and combined it with the design principles of AutoDev to design a series of extension points.
We referenced the multi-target support implementation of Intellij Rust plugin and combined it with the design.
For a new language, you need to implement:
- create a new module in
settings.gradle.kts
, like:webstorm
,pycharm
..., - config in
build.gradle.kts
for new module, like:
project(":pycharm") {
intellij {
version.set(pycharmVersion)
plugins.set(pycharmPlugins)
}
dependencies {
implementation(project(":"))
}
}
- sync Gradle in Intellij IDEA
- create xml file in
resources/META-INF
likecc.unitmesh.pycharm.xml
, and import toplugin/src/main/resources/META-INF/plugin.xml
- create extension points
JetBrains AI Assistant Extension Points:
<extensionPoints>
<extensionPoint qualifiedName="cc.unitmesh.fileContextBuilder"
beanClass="com.intellij.lang.LanguageExtensionPoint" dynamic="true">
<with attribute="implementationClass"
implements="cc.unitmesh.devti.context.builder.FileContextBuilder"/>
</extensionPoint>
<extensionPoint qualifiedName="cc.unitmesh.classContextBuilder"
beanClass="com.intellij.lang.LanguageExtensionPoint" dynamic="true">
<with attribute="implementationClass"
implements="cc.unitmesh.devti.context.builder.ClassContextBuilder"/>
</extensionPoint>
<extensionPoint qualifiedName="cc.unitmesh.methodContextBuilder"
beanClass="com.intellij.lang.LanguageExtensionPoint" dynamic="true">
<with attribute="implementationClass"
implements="cc.unitmesh.devti.context.builder.MethodContextBuilder"/>
</extensionPoint>
<extensionPoint qualifiedName="cc.unitmesh.variableContextBuilder"
beanClass="com.intellij.lang.LanguageExtensionPoint" dynamic="true">
<with attribute="implementationClass"
implements="cc.unitmesh.devti.context.builder.VariableContextBuilder"/>
</extensionPoint>
</extensionPoints>
AutoDev Extension Points:
<extensionPoints>
<!-- AutoCRUD flow -->
<extensionPoint qualifiedName="cc.unitmesh.devFlowProvider"
interface="cc.unitmesh.devti.provider.DevFlowProvider"
dynamic="true"/>
<!-- custom context strategy for Auto CRUD -->
<extensionPoint qualifiedName="cc.unitmesh.contextPrompter"
interface="cc.unitmesh.devti.provider.ContextPrompter"
dynamic="true"/>
<!-- Others strategy, like token count -->
<extensionPoint qualifiedName="cc.unitmesh.promptStrategy"
interface="cc.unitmesh.devti.provider.PromptStrategy"
dynamic="true"/>
</extensionPoints>
<extensions defaultExtensionNs="cc.unitmesh">
<!-- Language support -->
<classContextBuilder language="JAVA"
implementationClass="cc.unitmesh.ide.idea.context.JavaClassContextBuilder"/>
<methodContextBuilder language="JAVA"
implementationClass="cc.unitmesh.ide.idea.context.JavaMethodContextBuilder"/>
<fileContextBuilder language="JAVA"
implementationClass="cc.unitmesh.ide.idea.context.JavaFileContextBuilder"/>
<variableContextBuilder language="JAVA"
implementationClass="cc.unitmesh.ide.idea.context.JavaVariableContextBuilder"/>
<!-- TechStack Binding -->
<extensionPoint qualifiedName="cc.unitmesh.contextPrompter"
interface="cc.unitmesh.devti.provider.ContextPrompter"
dynamic="true"/>
<extensionPoint qualifiedName="cc.unitmesh.promptStrategy"
interface="cc.unitmesh.devti.provider.PromptStrategy"
dynamic="true"/>
<extensionPoint qualifiedName="cc.unitmesh.testContextProvider"
interface="cc.unitmesh.devti.provider.WriteTestService"
dynamic="true"/>
<extensionPoint qualifiedName="cc.unitmesh.chatContextProvider"
interface="cc.unitmesh.devti.provider.context.ChatContextProvider"
dynamic="true"/>
</extensions>
simliar to JetBrains LLM and GitHub Copilot, will be implementation like this:
defaultPriorities.json = [
"BeforeCursor",
"SimilarFile",
"ImportedFile",
"PathMarker",
"LanguageMarker"
]
We currently support:
- BeforeCursor
- SimilarFile
- JaccardSimilarity Path and Chunks by JetBrains
- Cosine Similarity Chunk by MethodName
- ImportedFile
- Java, Kotlin
- all cases
- PathMarker
- LanguageMarker
- Copilot-Explorer Hacky repo to see what the Copilot extension sends to the server.
- Github Copilot a small part about Copilot Performance logs.
- 花了大半个月,我终于逆向分析了Github Copilot
- ChatUI based on: https://github.com/Cspeisman/chatgpt-intellij-plugin
- Multiple target inspired by: https://github.com/intellij-rust/intellij-rust
- SimilarFile inspired by: JetBrains and GitHub Copilot
Known License issues: JetBrain plugin development is no walk in the park! Oops, we cheekily borrowed some code from the GitHub Copilot, JetBrains Community version and the super cool JetBrains AI Assistant plugin in our codebase. But fret not, we are working our magic to clean it up diligently! 🧙♂️✨
This code is distributed under the MPL 2.0 license. See LICENSE
in this directory.