Skip to content

Commit ce7c3a8

Browse files
committed
feat(agent): implement Coding Agent context, prompt renderer, and service for autonomous coding tasks #453
1 parent a1a92c4 commit ce7c3a8

File tree

6 files changed

+632
-72
lines changed

6 files changed

+632
-72
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package cc.unitmesh.agent
2+
3+
import cc.unitmesh.devins.compiler.variable.VariableTable
4+
5+
/**
6+
* Coding Agent Context - provides context information for autonomous coding agent
7+
* Similar to SketchRunContext in JetBrains plugin
8+
*
9+
* This context is used to render system prompts for the coding agent
10+
*
11+
* @property currentFile Current file being edited
12+
* @property projectPath Absolute path to the project workspace
13+
* @property projectStructure Summary of project structure
14+
* @property osInfo Operating system information
15+
* @property timestamp Current timestamp
16+
* @property toolList Available tools for the agent (as formatted string)
17+
* @property agentRules Project-specific agent rules from AGENTS.md
18+
* @property buildTool Build tool information (e.g., "gradle + kotlin")
19+
* @property shell Shell path (e.g., "/bin/bash")
20+
*/
21+
data class CodingAgentContext(
22+
val currentFile: String? = null,
23+
val projectPath: String,
24+
val projectStructure: String = "",
25+
val osInfo: String,
26+
val timestamp: String,
27+
val toolList: String = "",
28+
val agentRules: String = "",
29+
val buildTool: String = "",
30+
val shell: String = "/bin/bash",
31+
val moduleInfo: String = "",
32+
val frameworkContext: String = "",
33+
) {
34+
/**
35+
* Convert context to variable table for template compilation
36+
*/
37+
fun toVariableTable(): VariableTable {
38+
val table = VariableTable()
39+
table.addVariable("currentFile", cc.unitmesh.devins.compiler.variable.VariableType.STRING, currentFile ?: "")
40+
table.addVariable("projectPath", cc.unitmesh.devins.compiler.variable.VariableType.STRING, projectPath)
41+
table.addVariable("projectStructure", cc.unitmesh.devins.compiler.variable.VariableType.STRING, projectStructure)
42+
table.addVariable("osInfo", cc.unitmesh.devins.compiler.variable.VariableType.STRING, osInfo)
43+
table.addVariable("timestamp", cc.unitmesh.devins.compiler.variable.VariableType.STRING, timestamp)
44+
table.addVariable("toolList", cc.unitmesh.devins.compiler.variable.VariableType.STRING, toolList)
45+
table.addVariable("agentRules", cc.unitmesh.devins.compiler.variable.VariableType.STRING, agentRules)
46+
table.addVariable("buildTool", cc.unitmesh.devins.compiler.variable.VariableType.STRING, buildTool)
47+
table.addVariable("shell", cc.unitmesh.devins.compiler.variable.VariableType.STRING, shell)
48+
table.addVariable("moduleInfo", cc.unitmesh.devins.compiler.variable.VariableType.STRING, moduleInfo)
49+
table.addVariable("frameworkContext", cc.unitmesh.devins.compiler.variable.VariableType.STRING, frameworkContext)
50+
return table
51+
}
52+
53+
companion object {
54+
/**
55+
* Builder for platform-specific context creation
56+
*/
57+
interface Builder {
58+
suspend fun build(projectPath: String, requirement: String): CodingAgentContext
59+
}
60+
}
61+
}
62+
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package cc.unitmesh.agent
2+
3+
import cc.unitmesh.devins.compiler.template.TemplateCompiler
4+
5+
/**
6+
* Renders system prompts for the coding agent using templates and context
7+
*
8+
* This class bridges CodingAgentContext with the template system,
9+
* similar to how SketchRunContext is used with sketch.vm in the JetBrains plugin
10+
*/
11+
class CodingAgentPromptRenderer {
12+
13+
/**
14+
* Render system prompt from context
15+
*
16+
* @param context The coding agent context
17+
* @param language Language for the prompt (EN or ZH)
18+
* @return The rendered system prompt
19+
*/
20+
fun render(context: CodingAgentContext, language: String = "EN"): String {
21+
// Get template based on language
22+
val template = when (language.uppercase()) {
23+
"ZH", "CN" -> CodingAgentTemplate.ZH
24+
else -> CodingAgentTemplate.EN
25+
}
26+
27+
// Convert context to variable table
28+
val variableTable = context.toVariableTable()
29+
30+
// Compile template
31+
val compiler = TemplateCompiler(variableTable)
32+
return compiler.compile(template)
33+
}
34+
}
35+
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package cc.unitmesh.agent
2+
3+
/**
4+
* Result of an agent execution step
5+
*/
6+
data class AgentStep(
7+
val step: Int,
8+
val action: String,
9+
val tool: String? = null,
10+
val params: Any? = null,
11+
val result: String? = null,
12+
val success: Boolean
13+
)
14+
15+
/**
16+
* Represents a file edit made by the agent
17+
*/
18+
data class AgentEdit(
19+
val file: String,
20+
val operation: AgentEditOperation,
21+
val content: String? = null
22+
)
23+
24+
enum class AgentEditOperation {
25+
CREATE,
26+
UPDATE,
27+
DELETE
28+
}
29+
30+
/**
31+
* Result of an agent task execution
32+
*/
33+
data class AgentResult(
34+
val success: Boolean,
35+
val message: String,
36+
val steps: List<AgentStep>,
37+
val edits: List<AgentEdit>
38+
)
39+
40+
/**
41+
* Represents a task for the coding agent
42+
*/
43+
data class AgentTask(
44+
val requirement: String,
45+
val projectPath: String
46+
)
47+
48+
/**
49+
* Coding Agent Service interface
50+
*
51+
* This is the core abstraction for the autonomous coding agent.
52+
* Different platforms (JVM, JS, Android, iOS) can implement this interface
53+
* to provide platform-specific functionality while sharing the core logic.
54+
*
55+
* The agent operates in a loop:
56+
* 1. Build context from project
57+
* 2. Generate system prompt using template
58+
* 3. Get next action from LLM
59+
* 4. Execute action using tools
60+
* 5. Repeat until task is complete or max iterations reached
61+
*/
62+
interface CodingAgentService {
63+
64+
/**
65+
* Execute a development task
66+
*
67+
* @param task The task to execute
68+
* @return The result of the task execution
69+
*/
70+
suspend fun executeTask(task: AgentTask): AgentResult
71+
72+
/**
73+
* Build system prompt for the agent
74+
* Uses CodingAgentContext and CodingAgentTemplate
75+
*
76+
* @param context The context for prompt generation
77+
* @param language Language for the prompt (EN or ZH)
78+
* @return The rendered system prompt
79+
*/
80+
fun buildSystemPrompt(context: CodingAgentContext, language: String = "EN"): String
81+
82+
/**
83+
* Initialize workspace for the agent
84+
* This should scan the project structure, detect build tools, etc.
85+
*
86+
* @param projectPath The path to the project
87+
*/
88+
suspend fun initializeWorkspace(projectPath: String)
89+
90+
/**
91+
* Get the maximum number of iterations before stopping
92+
*/
93+
fun getMaxIterations(): Int = 10
94+
}
95+
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
package cc.unitmesh.agent
2+
3+
/**
4+
* Template for Coding Agent system prompt
5+
* Similar to sketch.vm in JetBrains plugin
6+
*/
7+
object CodingAgentTemplate {
8+
9+
/**
10+
* English version of the coding agent system prompt
11+
*/
12+
const val EN = """You are AutoDev, an autonomous AI coding agent designed to complete development tasks.
13+
14+
## Environment Information
15+
- OS: ${'$'}{osInfo}
16+
- Project Path: ${'$'}{projectPath}
17+
- Current Time: ${'$'}{timestamp}
18+
- Current File: ${'$'}{currentFile}
19+
- Build Tool: ${'$'}{buildTool}
20+
- Shell: ${'$'}{shell}
21+
#if (${'$'}{frameworkContext})
22+
- Framework Context: ${'$'}{frameworkContext}
23+
#end
24+
#if (${'$'}{moduleInfo})
25+
${'$'}{moduleInfo}
26+
#end
27+
28+
## Project Structure
29+
${'$'}{projectStructure}
30+
31+
## Available Tools
32+
You have access to the following tools through DevIns commands:
33+
34+
${'$'}{toolList}
35+
36+
## Task Execution Guidelines
37+
38+
1. **Gather Context First**: Before making changes, use /read-file and /glob to understand the codebase
39+
2. **Plan Your Approach**: Think step-by-step about what needs to be done
40+
3. **Make Incremental Changes**: Make one change at a time and verify it works
41+
4. **Test Your Changes**: Run tests or build commands to verify changes
42+
5. **Signal Completion**: When done, respond with "TASK_COMPLETE" in your message
43+
44+
## Response Format
45+
46+
For each step, respond with:
47+
1. Your reasoning about what to do next
48+
2. The DevIns command(s) to execute (wrapped in <devin></devin> tags)
49+
3. What you expect to happen
50+
51+
Example:
52+
I need to check the existing implementation first.
53+
<devin>
54+
/read-file path="src/main.ts"
55+
</devin>
56+
57+
## Making Code Changes
58+
59+
When modifying code:
60+
- **DO NOT output code to the user unless explicitly requested**. Use code editing tools instead.
61+
- Before editing, **read the file or section you want to modify** (unless it's a simple append or new file).
62+
- Add all necessary import statements, dependencies, and endpoints required to run the code.
63+
- If creating a codebase from scratch, provide a dependency management file (e.g., `requirements.txt`) with package versions and a helpful README.
64+
- If building a web app from scratch, design a **modern, beautiful UI with best UX practices**.
65+
- **NEVER generate extremely long hashes or non-textual code (like binary)**. These are unhelpful and expensive.
66+
- When refactoring code, create the new code first, then update the old references.
67+
68+
#if (${'$'}{agentRules})
69+
## Project-Specific Rules
70+
${'$'}{agentRules}
71+
#end
72+
73+
Remember: You are autonomous. Keep working until the task is complete or you encounter an error you cannot resolve.
74+
"""
75+
76+
/**
77+
* Chinese version of the coding agent system prompt
78+
*/
79+
const val ZH = """You are AutoDev, 一个由 Unit Mesh 设计的开源自主 AI 编程代理。
80+
81+
## 环境信息
82+
- OS: ${'$'}{osInfo}
83+
- 项目路径: ${'$'}{projectPath}
84+
- 当前时间: ${'$'}{timestamp}
85+
- 当前文件: ${'$'}{currentFile}
86+
- 构建工具: ${'$'}{buildTool}
87+
- Shell: ${'$'}{shell}
88+
#if (${'$'}{frameworkContext})
89+
- 框架上下文: ${'$'}{frameworkContext}
90+
#end
91+
#if (${'$'}{moduleInfo})
92+
${'$'}{moduleInfo}
93+
#end
94+
95+
## 项目结构
96+
${'$'}{projectStructure}
97+
98+
## 可用工具
99+
你可以通过 DevIns 命令访问以下工具:
100+
101+
${'$'}{toolList}
102+
103+
## 任务执行指南
104+
105+
1. **先获取上下文**: 在进行更改之前,使用 /read-file 和 /glob 来了解代码库
106+
2. **规划你的方法**: 逐步思考需要做什么
107+
3. **增量更改**: 一次做一个更改并验证其有效性
108+
4. **测试更改**: 运行测试或构建命令来验证更改
109+
5. **完成信号**: 完成后,在消息中响应 "TASK_COMPLETE"
110+
111+
## 响应格式
112+
113+
对于每一步,请回复:
114+
1. 你对下一步该做什么的推理
115+
2. 要执行的 DevIns 命令(包装在 <devin></devin> 标签中)
116+
3. 你期望发生什么
117+
118+
示例:
119+
我需要先检查现有实现。
120+
<devin>
121+
/read-file path="src/main.ts"
122+
</devin>
123+
124+
## 进行代码更改
125+
126+
在修改代码时:
127+
- **除非用户明确请求,否则不要向用户输出代码**。应使用代码编辑工具。
128+
- 在编辑之前,**读取你要修改的文件或部分**(除非是简单的追加或新文件)。
129+
- 添加运行代码所需的所有必要导入语句、依赖项和端点。
130+
- 如果从头创建代码库,请提供依赖管理文件(例如 `requirements.txt`),包含包版本和有用的 README。
131+
- 如果从头构建 Web 应用,请设计**现代、美观且符合最佳用户体验实践的界面**。
132+
- **绝不要生成极长的哈希值或非文本代码(如二进制)**。这些无用且成本高昂。
133+
- 重构代码时,先生成新代码,然后更新旧引用。
134+
135+
#if (${'$'}{agentRules})
136+
## 项目特定规则
137+
${'$'}{agentRules}
138+
#end
139+
140+
记住:你是自主的。持续工作直到任务完成或遇到无法解决的错误。
141+
"""
142+
}
143+

0 commit comments

Comments
 (0)