Skip to content

Commit ab7dea3

Browse files
committed
feat(agent): enhance DevIns agent context handling #379
Extend CustomAgentContext with filePath and initVariables to support file-based execution. Refactor DevInsPromptProcessor to handle both direct text and file-based compilation, improving flexibility in agent execution. Also optimize message handling in CustomAgentExecutor.
1 parent 3c71382 commit ab7dea3

File tree

4 files changed

+46
-20
lines changed

4 files changed

+46
-20
lines changed

core/src/main/kotlin/cc/unitmesh/devti/agent/custom/CustomAgentChatProcessor.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class CustomAgentChatProcessor(val project: Project) {
2929

3030
fun handleChat(prompter: ContextPrompter, ui: NormalChatCodingPanel, llmProvider: LLMProvider): String? {
3131
val originPrompt = prompter.requestPrompt()
32-
ui.addMessage(originPrompt, true, originPrompt)
32+
val displayMessage = originPrompt
3333

3434
val request = originPrompt.trim()
3535
val selectedAgent: CustomAgentConfig = ui.getSelectedCustomAgent()
@@ -42,6 +42,8 @@ class CustomAgentChatProcessor(val project: Project) {
4242
return null
4343
}
4444

45+
ui.addMessage(originPrompt, true, displayMessage)
46+
4547
var llmResponse = ""
4648
selectedAgent.state = CustomAgentState.FINISHED
4749

core/src/main/kotlin/cc/unitmesh/devti/agent/custom/CustomAgentExecutor.kt

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,25 @@ class CustomAgentExecutor(val project: Project) : CustomSSEProcessor(project) {
3333
override var responseFormat: String = ""
3434

3535
fun execute(promptText: String, agent: CustomAgentConfig): Flow<String>? {
36-
messages.add(Message("user", promptText))
37-
3836
var prompt = promptText
3937

4038
if (agent.isFromDevIns) {
4139
val devin = LanguageProcessor.devin()!!
4240
val file = project.baseDir.findFileByRelativePath(agent.devinScriptPath)!!
43-
val content = file.readText().replace("${'$'}input", promptText)
4441
prompt = runBlocking {
45-
devin.execute(project, CustomAgentContext(agent, content))
42+
val context = CustomAgentContext(
43+
agent, "", filePath = file,
44+
initVariables = mapOf("input" to promptText)
45+
)
46+
devin.execute(project, context)
4647
}
4748

49+
messages.add(Message("user", prompt))
4850
return LlmFactory.create(project).stream(prompt, "")
4951
}
5052

53+
messages.add(Message("user", promptText))
54+
5155
this.requestFormat = agent.connector?.requestFormat ?: this.requestFormat
5256
this.responseFormat = agent.connector?.responseFormat ?: this.responseFormat
5357

@@ -69,12 +73,14 @@ class CustomAgentExecutor(val project: Project) : CustomSSEProcessor(project) {
6973
builder.addHeader("Authorization", "Bearer ${auth.token}")
7074
builder.addHeader("Content-Type", "application/json")
7175
}
76+
7277
null -> {
7378
logger.info("No auth type found for agent ${agent.name}")
7479
}
7580
}
7681

77-
client = client.newBuilder().connectTimeout(agent.defaultTimeout, TimeUnit.SECONDS).readTimeout(agent.defaultTimeout, TimeUnit.SECONDS).build()
82+
client = client.newBuilder().connectTimeout(agent.defaultTimeout, TimeUnit.SECONDS)
83+
.readTimeout(agent.defaultTimeout, TimeUnit.SECONDS).build()
7884
val call = client.newCall(builder.url(agent.url).post(body).build())
7985

8086
return when (agent.responseAction) {
@@ -97,7 +103,7 @@ class CustomAgentExecutor(val project: Project) : CustomSSEProcessor(project) {
97103
*/
98104
fun replacePlaceholders(request: String, promptText: String): String {
99105
var result = request
100-
106+
101107
// Replace simple content placeholder
102108
if (result.contains(SIMPLE_CONTENT_PLACEHOLDER)) {
103109
result = result.replace(SIMPLE_CONTENT_PLACEHOLDER, "\"content\": \"$promptText\"")
@@ -109,7 +115,7 @@ class CustomAgentExecutor(val project: Project) : CustomSSEProcessor(project) {
109115
if (result.contains(regex)) {
110116
result = regex.replace(result, ": \"$promptText\"")
111117
}
112-
118+
113119
return result
114120
}
115121
}

core/src/main/kotlin/cc/unitmesh/devti/provider/devins/LanguageProcessor.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@ import cc.unitmesh.devti.agent.custom.model.CustomAgentConfig
44
import cc.unitmesh.devti.command.dataprovider.BuiltinCommand
55
import com.intellij.openapi.extensions.ExtensionPointName
66
import com.intellij.openapi.project.Project
7+
import com.intellij.openapi.vfs.VirtualFile
78
import com.intellij.psi.PsiFile
89
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
910

1011
data class CustomAgentContext(
1112
val config: CustomAgentConfig,
12-
val response: String
13+
val response: String,
14+
val filePath: VirtualFile? = null,
15+
var initVariables: Map<String, String> = mapOf()
1316
)
1417

1518
/**

exts/devins-lang/src/main/kotlin/cc/unitmesh/devti/language/provider/DevInsPromptProcessor.kt

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,43 +5,58 @@ import cc.unitmesh.devti.command.dataprovider.BuiltinCommand
55
import cc.unitmesh.devti.language.DevInLanguage
66
import cc.unitmesh.devti.language.compiler.DevInsCompiler
77
import cc.unitmesh.devti.language.psi.DevInFile
8+
import cc.unitmesh.devti.language.run.runner.ShireRunner
89
import cc.unitmesh.devti.provider.devins.CustomAgentContext
910
import cc.unitmesh.devti.provider.devins.LanguageProcessor
1011
import cc.unitmesh.devti.util.parser.CodeFence
1112
import com.intellij.openapi.application.runInEdt
13+
import com.intellij.openapi.application.runReadAction
1214
import com.intellij.openapi.editor.Editor
1315
import com.intellij.openapi.fileEditor.FileEditorManager
1416
import com.intellij.openapi.project.Project
1517
import com.intellij.psi.PsiElement
1618
import com.intellij.psi.PsiFile
19+
import com.intellij.psi.PsiManager
1720
import com.intellij.psi.PsiWhiteSpace
1821
import com.intellij.psi.util.PsiUtilBase
1922

20-
2123
class DevInsPromptProcessor : LanguageProcessor {
2224
override val name: String = DevInLanguage.displayName
2325

2426
override suspend fun execute(project: Project, context: CustomAgentContext): String {
2527
var text = context.response
26-
// re-check the language of the code
28+
2729
CodeFence.parse(text).let {
2830
if (it.language == DevInLanguage.INSTANCE) {
2931
text = it.text
3032
}
3133
}
3234

33-
val devInsCompiler = createCompiler(project, text)
34-
val result = devInsCompiler.compile()
35-
AutoDevNotifications.notify(project, result.output)
35+
var compileResult: String? = null
36+
if (context.filePath != null) {
37+
val psiFile = runReadAction { PsiManager.getInstance(project).findFile(context.filePath!!) as? DevInFile }
38+
if (psiFile != null) {
39+
compileResult = ShireRunner.compileOnly(project, psiFile, context.initVariables).finalPrompt
40+
}
41+
}
42+
43+
if (compileResult == null) {
44+
val devInsCompiler = createCompiler(project, text)
45+
val result = devInsCompiler.compile()
46+
compileResult = result.output
47+
48+
if (result.nextJob != null) {
49+
AutoDevNotifications.notify(project, compileResult)
3650

37-
if (result.nextJob != null) {
38-
val nextJob = result.nextJob!!
39-
val nextResult = createCompiler(project, nextJob).compile()
40-
AutoDevNotifications.notify(project, nextResult.output)
41-
return nextResult.output
51+
val nextJob = result.nextJob!!
52+
val nextResult = createCompiler(project, nextJob).compile()
53+
AutoDevNotifications.notify(project, nextResult.output)
54+
return nextResult.output
55+
}
4256
}
4357

44-
return result.output
58+
AutoDevNotifications.notify(project, compileResult)
59+
return compileResult
4560
}
4661

4762
override suspend fun compile(project: Project, text: String): String {

0 commit comments

Comments
 (0)