Skip to content

Commit 1704b8f

Browse files
committed
feat(logging): add log summary and error recovery agents #453
Introduce LogSummaryAgent and ErrorRecoveryAgent services, update related UI and core logic, and add utilities for output formatting and testing.
1 parent ce7c3a8 commit 1704b8f

File tree

9 files changed

+1277
-62
lines changed

9 files changed

+1277
-62
lines changed

mpp-core/src/commonMain/kotlin/cc/unitmesh/devins/compiler/context/CompilerContext.kt

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -135,21 +135,36 @@ data class CompilerOptions(
135135
class CompilerLogger {
136136

137137
private val logs = mutableListOf<LogEntry>()
138+
var enableDebug: Boolean = false // 默认关闭 debug 日志
139+
var minLevel: LogLevel = LogLevel.ERROR // 最小日志级别,默认只显示错误
140+
141+
fun debug(message: String) {
142+
if (enableDebug && minLevel <= LogLevel.DEBUG) {
143+
logs.add(LogEntry(LogLevel.DEBUG, message))
144+
println("[DEBUG] $message")
145+
}
146+
}
138147

139148
fun info(message: String) {
140-
logs.add(LogEntry(LogLevel.INFO, message))
141-
println("[INFO] $message")
149+
if (minLevel <= LogLevel.INFO) {
150+
logs.add(LogEntry(LogLevel.INFO, message))
151+
println("[INFO] $message")
152+
}
142153
}
143154

144155
fun warn(message: String) {
145-
logs.add(LogEntry(LogLevel.WARN, message))
146-
println("[WARN] $message")
156+
if (minLevel <= LogLevel.WARN) {
157+
logs.add(LogEntry(LogLevel.WARN, message))
158+
println("[WARN] $message")
159+
}
147160
}
148161

149162
fun error(message: String, throwable: Throwable? = null) {
150-
logs.add(LogEntry(LogLevel.ERROR, message, throwable))
151-
println("[ERROR] $message")
152-
throwable?.printStackTrace()
163+
if (minLevel <= LogLevel.ERROR) {
164+
logs.add(LogEntry(LogLevel.ERROR, message, throwable))
165+
println("[ERROR] $message")
166+
throwable?.printStackTrace()
167+
}
153168
}
154169

155170
fun getLogs(): List<LogEntry> = logs.toList()
@@ -173,7 +188,7 @@ data class LogEntry(
173188
* 日志级别
174189
*/
175190
enum class LogLevel {
176-
INFO, WARN, ERROR
191+
DEBUG, INFO, WARN, ERROR
177192
}
178193

179194
/**

mpp-core/src/commonMain/kotlin/cc/unitmesh/devins/compiler/processor/DevInsNodeProcessor.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,10 @@ abstract class BaseDevInsNodeProcessor : DevInsNodeProcessor {
145145

146146
/**
147147
* 记录处理信息
148+
* 默认使用 debug 级别,避免污染用户输出
148149
*/
149150
protected fun logProcessing(node: DevInsNode, context: CompilerContext, message: String? = null) {
150151
val msg = message ?: "Processing ${node.nodeType}"
151-
context.logger.info("[$name] $msg")
152+
context.logger.debug("[$name] $msg")
152153
}
153154
}

mpp-ui/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"@js-joda/core": "^5.6.5",
4242
"chalk": "^5.3.0",
4343
"commander": "^12.1.0",
44+
"diff": "^7.0.0",
4445
"dotenv": "^16.4.5",
4546
"ink": "^5.0.1",
4647
"ink-select-input": "^6.0.0",
@@ -50,6 +51,7 @@
5051
"yaml": "^2.6.1"
5152
},
5253
"devDependencies": {
54+
"@types/diff": "^6.0.0",
5355
"@types/node": "^20.11.24",
5456
"@types/react": "^18.3.12",
5557
"ink-testing-library": "^4.0.0",

mpp-ui/src/jsMain/typescript/index.tsx

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import * as fs from 'fs';
1919
/**
2020
* Run in coding agent mode
2121
*/
22-
async function runCodingAgent(projectPath: string, task: string) {
22+
async function runCodingAgent(projectPath: string, task: string, quiet: boolean = false) {
2323
try {
2424
// Resolve project path
2525
const resolvedPath = path.resolve(projectPath);
@@ -40,24 +40,19 @@ async function runCodingAgent(projectPath: string, task: string) {
4040
process.exit(1);
4141
}
4242

43-
console.log(`\n🚀 AutoDev Coding Agent`);
44-
console.log(`📦 Provider: ${activeConfig.provider}`);
45-
console.log(`🤖 Model: ${activeConfig.model}\n`);
43+
if (!quiet) {
44+
console.log(`\n🚀 AutoDev Coding Agent`);
45+
console.log(`📦 Provider: ${activeConfig.provider}`);
46+
console.log(`🤖 Model: ${activeConfig.model}\n`);
47+
}
4648

4749
// Create and run coding agent
48-
const agent = new CodingAgentService(resolvedPath, activeConfig);
50+
const agent = new CodingAgentService(resolvedPath, activeConfig, quiet);
4951
const result = await agent.executeTask({
5052
requirement: task,
5153
projectPath: resolvedPath,
5254
});
5355

54-
// Print summary
55-
console.log('\n' + '='.repeat(60));
56-
console.log(result.message);
57-
console.log(`Total steps: ${result.steps.length}`);
58-
console.log(`Total edits: ${result.edits.length}`);
59-
console.log('='.repeat(60) + '\n');
60-
6156
process.exit(result.success ? 0 : 1);
6257

6358
} catch (error) {
@@ -105,9 +100,11 @@ async function main() {
105100
.requiredOption('-p, --path <path>', 'Project path (e.g., /path/to/project or . for current directory)')
106101
.requiredOption('-t, --task <task>', 'Development task or requirement to complete')
107102
.option('-m, --max-iterations <number>', 'Maximum iterations', '10')
103+
.option('-q, --quiet', 'Quiet mode - only show important messages', false)
104+
.option('-v, --verbose', 'Verbose mode - show all debug information', false)
108105
.action(async (options) => {
109106
const projectPath = options.path === '.' ? process.cwd() : options.path;
110-
await runCodingAgent(projectPath, options.task);
107+
await runCodingAgent(projectPath, options.task, options.quiet && !options.verbose);
111108
});
112109

113110
// Parse arguments

0 commit comments

Comments
 (0)