Skip to content

Commit 9cc5268

Browse files
committed
feat(agent): add Dify API support and enhance custom agent config #251
- Added Dify API support with updated request and response formats. - Enhanced custom agent configuration with new fields and validation tests. - Added a link to open documents in the CoUnitToolConfigurable UI. - Updated error logging in ResponseBodyCallback to include request details.
1 parent ba50600 commit 9cc5268

File tree

6 files changed

+134
-8
lines changed

6 files changed

+134
-8
lines changed

core/src/main/kotlin/cc/unitmesh/devti/agent/configurable/CoUnitToolConfigurable.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cc.unitmesh.devti.agent.configurable
22

33
import cc.unitmesh.devti.AutoDevBundle
44
import cc.unitmesh.devti.custom.schema.CUSTOM_AGENT_FILE_NAME
5+
import cc.unitmesh.devti.fullHeight
56
import cc.unitmesh.devti.fullWidthCell
67
import cc.unitmesh.devti.gui.component.JsonLanguageField
78
import cc.unitmesh.devti.settings.LanguageChangedCallback.componentStateChanged
@@ -22,6 +23,10 @@ class CoUnitToolConfigurable(val project: Project) : BoundConfigurable(AutoDevBu
2223
checkBox(AutoDevBundle.message("counit.agent.enable.label")).bindSelected(state::enableCustomRag)
2324
.apply { componentStateChanged("counit.agent.enable.label", this.component){ c,k ->
2425
c.text = k} }
26+
27+
link(AutoDevBundle.message("open documents"), {
28+
com.intellij.ide.BrowserUtil.browse("https://ide.unitmesh.cc/agent/custom-ai-agent")
29+
});
2530
}
2631

2732
row {
@@ -35,6 +40,7 @@ class CoUnitToolConfigurable(val project: Project) : BoundConfigurable(AutoDevBu
3540
placeholder("counit.agent.json.placeholder", this)
3641
}
3742
fullWidthCell(languageField)
43+
.fullHeight()
3844
.bind(
3945
componentGet = { it.text },
4046
componentSet = { component, value -> component.text = value },

core/src/main/kotlin/cc/unitmesh/devti/llms/custom/ResponseBodyCallback.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ class ResponseBodyCallback(private val emitter: FlowableEmitter<SSE>, private va
121121
emitter.onComplete()
122122
} catch (t: Throwable) {
123123
logger<ResponseBodyCallback>().error("Error while reading SSE", t)
124+
logger<ResponseBodyCallback>().error("Request: ${call.request()}")
124125
onFailure(call, IOException(t))
125126
} finally {
126127
if (reader != null) {

core/src/main/resources/messages/AutoDevBundle_en.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,3 +198,4 @@ settings.autodev.coder.enableRenameSuggestion=Enable Rename suggestion
198198
shell.command.suggestion.action.default.text=How to checkout a branch?
199199
batch.nothing.to.testing=No thing to AutoTest
200200
intentions.chat.code.test.verify=Verify test
201+
open\ documents=Open Documents

core/src/main/resources/messages/AutoDevBundle_zh.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,4 @@ settings.autodev.coder.enableRenameSuggestion=启用重命名建议
197197
shell.command.suggestion.action.default.text=如何创建一个新的分支?
198198
batch.nothing.to.testing=没有要 AutoTest 的内容
199199
intentions.chat.code.test.verify=验证测试中
200+
open\ documents=Open Documents
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package cc.unitmesh.devti.agent.model
2+
3+
import cc.unitmesh.devti.custom.team.InteractionType
4+
import junit.framework.TestCase.assertEquals
5+
import junit.framework.TestCase.assertTrue
6+
import kotlinx.serialization.json.Json
7+
import org.junit.Test
8+
9+
class CustomAgentConfigTest {
10+
11+
@Test
12+
fun should_load_enabled_agents_from_valid_json_config() {
13+
// Given
14+
val result = mockProjectWithJsonConfig("""
15+
[
16+
{
17+
"name": "CustomAgent1",
18+
"enabled": true
19+
},
20+
{
21+
"name": "CustomAgent2",
22+
"enabled": false
23+
}
24+
]
25+
""")
26+
27+
// Then
28+
assertEquals(2, result.size)
29+
assertEquals("CustomAgent1", result[0].name)
30+
}
31+
32+
@Test
33+
fun should_load_all_fields_from_valid_json_config() {
34+
// Given
35+
val result = mockProjectWithJsonConfig("""
36+
[
37+
{
38+
"name": "CustomAgent",
39+
"description": "This is a custom agent configuration example.",
40+
"url": "https://custom-agent.example.com",
41+
"icon": "https://custom-agent.example.com/icon.png",
42+
"responseAction": "Direct",
43+
"transition": [
44+
{
45+
"source": "$.from",
46+
"target": "$.to"
47+
}
48+
],
49+
"interactive": "ChatPanel",
50+
"auth": {
51+
"type": "Bearer",
52+
"token": "<PASSWORD>"
53+
},
54+
"defaultTimeout": 20,
55+
"enabled": true
56+
}
57+
]
58+
""")
59+
// Then
60+
assertEquals(1, result.size)
61+
val config = result[0]
62+
assertEquals("CustomAgent", config.name)
63+
assertEquals("This is a custom agent configuration example.", config.description)
64+
assertEquals("https://custom-agent.example.com", config.url)
65+
assertEquals("https://custom-agent.example.com/icon.png", config.icon)
66+
assertEquals(CustomAgentResponseAction.Direct, config.responseAction)
67+
assertEquals(1, config.transition.size)
68+
assertEquals("$.from", config.transition[0].source)
69+
assertEquals("$.to", config.transition[0].target)
70+
assertEquals(InteractionType.ChatPanel, config.interactive)
71+
assertEquals(AuthType.Bearer, config.auth?.type)
72+
assertEquals("<PASSWORD>", config.auth?.token)
73+
assertEquals(20, config.defaultTimeout)
74+
assertEquals(true, config.enabled)
75+
}
76+
77+
@Test
78+
fun should_load_all_fields_from_valid_json_config_with_connector() {
79+
// Given
80+
val result = mockProjectWithJsonConfig("""
81+
[
82+
{
83+
"name": "dify",
84+
"description": "Dify Example",
85+
"url": "https://api.dify.ai/v1/completion-messages",
86+
"auth": {
87+
"type": "Bearer",
88+
"token": "app-abc"
89+
},
90+
"connector": {
91+
"requestFormat": "{\"fields\": {\"inputs\": {\"feature\": \"${'$'}content\"}, \"response_mode\": \"streaming\" }}",
92+
"responseFormat": "$.answer"
93+
},
94+
"responseAction": "Stream",
95+
"defaultTimeout": 20
96+
}
97+
]
98+
""")
99+
100+
assertEquals(1, result.size)
101+
val config = result[0]
102+
assertEquals("dify", config.name)
103+
assertEquals("Dify Example", config.description)
104+
assertEquals("https://api.dify.ai/v1/completion-messages", config.url)
105+
assertEquals(AuthType.Bearer, config.auth?.type)
106+
assertEquals("app-abc", config.auth?.token)
107+
assertEquals("{\"fields\": {\"inputs\": {\"feature\": \"\$content\"}, \"response_mode\": \"streaming\" }}", config.connector?.requestFormat)
108+
assertEquals("$.answer", config.connector?.responseFormat)
109+
assertEquals(CustomAgentResponseAction.Stream, config.responseAction)
110+
assertEquals(20, config.defaultTimeout)
111+
}
112+
113+
private fun mockProjectWithJsonConfig(jsonConfig: String): List<CustomAgentConfig> {
114+
return Json.decodeFromString(jsonConfig)
115+
}
116+
}

docs/agent/custom-ai-agent.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,23 +56,24 @@ Demo:
5656
"defaultTimeout": 20
5757
},
5858
{
59-
"name": "AIStream",
60-
"description": "AI Stream",
61-
"url": "http://127.0.0.1:8765/api/agent/devins-sample",
59+
"name": "DifyAI",
60+
"description": "Dify Example",
61+
"url": "https://api.dify.ai/v1/completion-messages",
6262
"auth": {
6363
"type": "Bearer",
64-
"token": "eyJhbGci"
64+
"token": "app-abcd"
6565
},
6666
"connector": {
67-
"requestFormat": "{\"customFields\": {\"model\": \"yi-34b-chat\", \"stream\": true}}",
68-
"responseFormat": "$.choices[0].delta.content"
67+
"requestFormat": "{\"fields\": {\"inputs\": {\"feature\": \"$content\"}, \"response_mode\": \"streaming\", \"user\": \"phodal\" }}",
68+
"responseFormat": "$.answer"
6969
},
70-
"responseAction": "Stream",
71-
"defaultTimeout": 20
70+
"responseAction": "Stream"
7271
}
7372
]
7473
```
7574

75+
Notes: Dify API support by [#251](https://github.com/unit-mesh/auto-dev/issues/251), since 1.8.18 version
76+
7677
### responseAction
7778

7879
```kotlin

0 commit comments

Comments
 (0)