Skip to content

Commit ae29c86

Browse files
committed
feat(platform): add OS name and default shell retrieval for multiple platforms #453
1 parent c473b2b commit ae29c86

File tree

11 files changed

+122
-108
lines changed

11 files changed

+122
-108
lines changed

mpp-core/src/androidMain/kotlin/cc/unitmesh/agent/Platform.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,13 @@ actual object Platform {
66
actual val isJs: Boolean = false
77
actual val isWasm: Boolean = false
88
actual val isAndroid: Boolean = true
9+
10+
actual fun getOSName(): String {
11+
return "Android ${android.os.Build.VERSION.RELEASE}"
12+
}
13+
14+
actual fun getDefaultShell(): String {
15+
return "sh" // Android uses sh shell
16+
}
917
}
1018

mpp-core/src/commonMain/kotlin/cc/unitmesh/agent/CodingAgent.kt

Lines changed: 14 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import cc.unitmesh.agent.subagent.ErrorRecoveryAgent
1010
import cc.unitmesh.agent.subagent.LogSummaryAgent
1111
import cc.unitmesh.agent.subagent.CodebaseInvestigatorAgent
1212
import cc.unitmesh.agent.tool.ToolResult
13+
import cc.unitmesh.agent.tool.ToolNames
1314
import cc.unitmesh.agent.tool.registry.ToolRegistry
1415
import cc.unitmesh.agent.tool.filesystem.DefaultToolFileSystem
1516
import cc.unitmesh.agent.tool.shell.DefaultShellExecutor
@@ -57,7 +58,7 @@ class CodingAgent(
5758
displayName = "Autonomous Coding Agent",
5859
description = "Autonomous coding agent for development tasks",
5960
promptConfig = PromptConfig(
60-
systemPrompt = buildCodingAgentSystemPrompt(),
61+
systemPrompt = "You are an autonomous coding agent. Use the available tools to complete development tasks.",
6162
queryTemplate = "Task: \${requirement}\nProject Path: \${projectPath}",
6263
initialMessages = emptyList()
6364
),
@@ -73,7 +74,15 @@ class CodingAgent(
7374
terminateOnError = false
7475
),
7576
toolConfig = ToolConfig(
76-
allowedTools = listOf("read-file", "write-file", "shell", "glob", "error-recovery", "log-summary", "codebase-investigator")
77+
allowedTools = listOf(
78+
ToolNames.READ_FILE,
79+
ToolNames.WRITE_FILE,
80+
ToolNames.SHELL,
81+
ToolNames.GLOB,
82+
ToolNames.ERROR_RECOVERY,
83+
ToolNames.LOG_SUMMARY,
84+
ToolNames.CODEBASE_INVESTIGATOR
85+
)
7786
)
7887
)
7988
), CodingAgentService {
@@ -179,7 +188,6 @@ class CodingAgent(
179188
)
180189
)
181190

182-
// 使用 DefaultAgentExecutor 执行
183191
val result = agentExecutor.execute(
184192
definition = definition,
185193
context = context,
@@ -248,57 +256,10 @@ class CodingAgent(
248256
}
249257
}
250258

251-
/**
252-
* Build system prompt for CodingAgent
253-
*/
254-
private fun buildCodingAgentSystemPrompt(): String {
255-
return """
256-
You are an autonomous coding agent specialized in software development tasks.
257-
258-
## Your Capabilities
259-
- Analyze project structure and understand codebases
260-
- Read and write files
261-
- Execute shell commands
262-
- Generate and modify code
263-
- Run tests and fix errors
264-
- Use SubAgents for specialized tasks (error recovery, log analysis, codebase investigation)
265-
266-
## Available Tools
267-
- read-file: Read file contents
268-
- write-file: Create or modify files
269-
- shell: Execute shell commands
270-
- glob: Search for files using patterns
271-
- error-recovery: Analyze and recover from errors (SubAgent)
272-
- log-summary: Summarize long command outputs (SubAgent)
273-
- codebase-investigator: Analyze codebase structure and investigate code patterns (SubAgent)
274-
275-
## Working Process
276-
1. Understand the task requirements
277-
2. Analyze the project structure
278-
3. Plan your approach
279-
4. Execute actions step by step
280-
5. Test and verify your changes
281-
6. Use error recovery when commands fail
282-
7. Call complete_task when finished
283-
284-
## Important Rules
285-
- Always use DevIns format for tool calls: <devin>/tool-name param="value"</devin>
286-
- Read files before modifying them to understand the context
287-
- Test your changes after making them
288-
- Use error-recovery SubAgent when shell commands fail
289-
- Call complete_task tool when the task is finished
290-
- Be methodical and explain your reasoning
291-
292-
## Output Format
293-
- Explain your thinking process
294-
- Use tool calls to perform actions
295-
- Provide clear status updates
296-
- Call complete_task with a summary when done
297-
""".trimIndent()
298-
}
299-
300259
override fun buildSystemPrompt(context: CodingAgentContext, language: String): String {
301-
return buildCodingAgentSystemPrompt()
260+
val renderer = CodingAgentPromptRenderer()
261+
val tools = getAllTools()
262+
return renderer.renderSystemPrompt(tools, language)
302263
}
303264

304265
override suspend fun initializeWorkspace(projectPath: String) {
@@ -319,51 +280,3 @@ You are an autonomous coding agent specialized in software development tasks.
319280
}
320281
}
321282

322-
/**
323-
* Build system prompt for CodingAgent
324-
*/
325-
private fun buildCodingAgentSystemPrompt(): String {
326-
return """
327-
You are an autonomous coding agent specialized in software development tasks.
328-
329-
## Your Capabilities
330-
- Analyze project structure and understand codebases
331-
- Read and write files
332-
- Execute shell commands
333-
- Generate and modify code
334-
- Run tests and fix errors
335-
- Use SubAgents for specialized tasks (error recovery, log analysis, codebase investigation)
336-
337-
## Available Tools
338-
- read-file: Read file contents
339-
- write-file: Create or modify files
340-
- shell: Execute shell commands
341-
- glob: Search for files using patterns
342-
- error-recovery: Analyze and recover from errors (SubAgent)
343-
- log-summary: Summarize long command outputs (SubAgent)
344-
- codebase-investigator: Analyze codebase structure and investigate code patterns (SubAgent)
345-
346-
## Working Process
347-
1. Understand the task requirements
348-
2. Analyze the project structure
349-
3. Plan your approach
350-
4. Execute actions step by step
351-
5. Test and verify your changes
352-
6. Use error recovery when commands fail
353-
7. Call complete_task when finished
354-
355-
## Important Rules
356-
- Always use DevIns format for tool calls: <devin>/tool-name param="value"</devin>
357-
- Read files before modifying them to understand the context
358-
- Test your changes after making them
359-
- Use error-recovery SubAgent when shell commands fail
360-
- Call complete_task tool when the task is finished
361-
- Be methodical and explain your reasoning
362-
363-
## Output Format
364-
- Explain your thinking process
365-
- Use tool calls to perform actions
366-
- Provide clear status updates
367-
- Call complete_task with a summary when done
368-
""".trimIndent()
369-
}

mpp-core/src/commonMain/kotlin/cc/unitmesh/agent/CodingAgentPromptRenderer.kt

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package cc.unitmesh.agent
22

3+
import cc.unitmesh.agent.tool.Tool
4+
import cc.unitmesh.agent.Platform
35
import cc.unitmesh.devins.compiler.template.TemplateCompiler
6+
import cc.unitmesh.devins.compiler.variable.VariableTable
7+
import cc.unitmesh.devins.compiler.variable.VariableType
8+
import cc.unitmesh.devins.compiler.variable.VariableScope
9+
import kotlinx.datetime.Clock
410

511
/**
612
* Renders system prompts for the coding agent using templates and context
@@ -12,7 +18,7 @@ class CodingAgentPromptRenderer {
1218

1319
/**
1420
* Render system prompt from context
15-
*
21+
*
1622
* @param context The coding agent context
1723
* @param language Language for the prompt (EN or ZH)
1824
* @return The rendered system prompt
@@ -23,10 +29,49 @@ class CodingAgentPromptRenderer {
2329
"ZH", "CN" -> CodingAgentTemplate.ZH
2430
else -> CodingAgentTemplate.EN
2531
}
26-
32+
2733
// Convert context to variable table
2834
val variableTable = context.toVariableTable()
29-
35+
36+
// Compile template
37+
val compiler = TemplateCompiler(variableTable)
38+
return compiler.compile(template)
39+
}
40+
41+
/**
42+
* Render system prompt with dynamic tool list
43+
*
44+
* @param tools Available tools for the agent
45+
* @param language Language for the prompt (EN or ZH)
46+
* @return The rendered system prompt
47+
*/
48+
fun renderSystemPrompt(tools: List<Tool>, language: String = "EN"): String {
49+
// Get template based on language
50+
val template = when (language.uppercase()) {
51+
"ZH", "CN" -> CodingAgentTemplate.ZH
52+
else -> CodingAgentTemplate.EN
53+
}
54+
55+
// Create variable table with tools and default values
56+
val variableTable = VariableTable()
57+
58+
// Add tool information for ${toolList}
59+
val toolDescriptions = tools.map { tool ->
60+
"- **${tool.name}**: ${tool.description}"
61+
}.joinToString("\n")
62+
63+
variableTable.addVariable("toolList", VariableType.STRING, toolDescriptions, VariableScope.USER_DEFINED)
64+
variableTable.addVariable("toolNames", VariableType.ARRAY, tools.map { it.name }, VariableScope.USER_DEFINED)
65+
66+
// Add default values for other template variables
67+
variableTable.addVariable("osInfo", VariableType.STRING, Platform.getOSName(), VariableScope.BUILTIN)
68+
variableTable.addVariable("projectPath", VariableType.STRING, "/project", VariableScope.BUILTIN)
69+
variableTable.addVariable("timestamp", VariableType.STRING, Clock.System.now().toString(), VariableScope.BUILTIN)
70+
variableTable.addVariable("currentFile", VariableType.STRING, "", VariableScope.BUILTIN)
71+
variableTable.addVariable("buildTool", VariableType.STRING, "Auto-detected", VariableScope.BUILTIN)
72+
variableTable.addVariable("shell", VariableType.STRING, Platform.getDefaultShell(), VariableScope.BUILTIN)
73+
variableTable.addVariable("projectStructure", VariableType.STRING, "Will be analyzed during execution", VariableScope.BUILTIN)
74+
3075
// Compile template
3176
val compiler = TemplateCompiler(variableTable)
3277
return compiler.compile(template)

mpp-core/src/commonMain/kotlin/cc/unitmesh/agent/Platform.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ expect object Platform {
99
val isJs: Boolean
1010
val isWasm: Boolean
1111
val isAndroid: Boolean
12+
13+
fun getOSName(): String
14+
fun getDefaultShell(): String
1215
}
1316

1417
/**

mpp-core/src/commonMain/kotlin/cc/unitmesh/agent/subagent/CodebaseInvestigatorAgent.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import cc.unitmesh.agent.model.ModelConfig
77
import cc.unitmesh.agent.model.RunConfig
88
import cc.unitmesh.agent.model.ToolConfig
99
import cc.unitmesh.agent.tool.ToolResult
10+
import cc.unitmesh.agent.tool.ToolNames
1011
import cc.unitmesh.llm.KoogLLMService
1112
import kotlinx.serialization.Serializable
1213

@@ -47,7 +48,7 @@ class CodebaseInvestigatorAgent(
4748
private val llmService: KoogLLMService
4849
) : SubAgent<InvestigationContext, ToolResult.AgentResult>(
4950
AgentDefinition(
50-
name = "CodebaseInvestigatorAgent",
51+
name = ToolNames.CODEBASE_INVESTIGATOR,
5152
displayName = "Codebase Investigator",
5253
description = "Analyzes codebase structure and provides insights using code analysis",
5354
promptConfig = PromptConfig(

mpp-core/src/commonMain/kotlin/cc/unitmesh/agent/subagent/ErrorRecoveryAgent.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import cc.unitmesh.agent.model.PromptConfig
77
import cc.unitmesh.agent.model.RunConfig
88
import cc.unitmesh.agent.platform.GitOperations
99
import cc.unitmesh.agent.tool.ToolResult
10+
import cc.unitmesh.agent.tool.ToolNames
1011
import cc.unitmesh.llm.KoogLLMService
1112
import kotlinx.serialization.Serializable
1213
import kotlinx.serialization.json.Json
@@ -335,7 +336,7 @@ $context
335336

336337
companion object {
337338
private fun createDefinition() = AgentDefinition(
338-
name = "error_recovery",
339+
name = ToolNames.ERROR_RECOVERY,
339340
displayName = "Error Recovery SubAgent",
340341
description = "Analyzes command failures and provides recovery plans",
341342
promptConfig = PromptConfig(

mpp-core/src/commonMain/kotlin/cc/unitmesh/agent/subagent/LogSummaryAgent.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import cc.unitmesh.agent.model.ModelConfig
66
import cc.unitmesh.agent.model.PromptConfig
77
import cc.unitmesh.agent.model.RunConfig
88
import cc.unitmesh.agent.tool.ToolResult
9+
import cc.unitmesh.agent.tool.ToolNames
910
import cc.unitmesh.llm.KoogLLMService
1011
import kotlinx.serialization.Serializable
1112
import kotlinx.serialization.json.Json
@@ -343,7 +344,7 @@ Provide a JSON summary as specified in your system prompt.
343344

344345
companion object {
345346
private fun createDefinition() = AgentDefinition(
346-
name = "log_summary",
347+
name = ToolNames.LOG_SUMMARY,
347348
displayName = "Log Summary SubAgent",
348349
description = "Summarizes long command outputs",
349350
promptConfig = PromptConfig(

mpp-core/src/commonMain/kotlin/cc/unitmesh/agent/tool/ToolNames.kt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ object ToolNames {
2828
// Utility tools
2929
const val HELP = "help"
3030
const val VERSION = "version"
31+
32+
// SubAgent tools
33+
const val ERROR_RECOVERY = "error-recovery"
34+
const val LOG_SUMMARY = "log-summary"
35+
const val CODEBASE_INVESTIGATOR = "codebase-investigator"
3136

3237
/**
3338
* All available tool names
@@ -38,7 +43,8 @@ object ToolNames {
3843
SHELL, EXEC,
3944
EDIT_FILE, PATCH_FILE,
4045
FILE_INFO, DIR_INFO,
41-
HELP, VERSION
46+
HELP, VERSION,
47+
ERROR_RECOVERY, LOG_SUMMARY, CODEBASE_INVESTIGATOR
4248
)
4349

4450
/**
@@ -57,6 +63,13 @@ object ToolNames {
5763
val EXECUTION_TOOLS = setOf(
5864
SHELL, EXEC
5965
)
66+
67+
/**
68+
* SubAgent tools for specialized tasks
69+
*/
70+
val SUBAGENT_TOOLS = setOf(
71+
ERROR_RECOVERY, LOG_SUMMARY, CODEBASE_INVESTIGATOR
72+
)
6073

6174
/**
6275
* Check if a tool name is valid

mpp-core/src/jsMain/kotlin/cc/unitmesh/agent/Platform.js.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,16 @@ actual object Platform {
66
actual val isJs: Boolean = true
77
actual val isWasm: Boolean = false
88
actual val isAndroid: Boolean = false
9+
10+
actual fun getOSName(): String {
11+
return js("typeof process !== 'undefined' ? process.platform : 'Browser'") as String
12+
}
13+
14+
actual fun getDefaultShell(): String {
15+
val platform = js("typeof process !== 'undefined' ? process.platform : 'unknown'") as String
16+
return when (platform) {
17+
"win32" -> "cmd"
18+
else -> "bash"
19+
}
20+
}
921
}

mpp-core/src/jvmMain/kotlin/cc/unitmesh/agent/Platform.jvm.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,13 @@ actual object Platform {
66
actual val isJs: Boolean = false
77
actual val isWasm: Boolean = false
88
actual val isAndroid: Boolean = false
9+
10+
actual fun getOSName(): String {
11+
return System.getProperty("os.name", "Unknown")
12+
}
13+
14+
actual fun getDefaultShell(): String {
15+
val osName = System.getProperty("os.name", "")
16+
return if (osName.contains("Windows", ignoreCase = true)) "cmd" else "bash"
17+
}
918
}

0 commit comments

Comments
 (0)