foliko 1.1.28 → 1.1.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent/data/plugins-state.json +33 -142
- package/.agent/mcp_config.json +6 -0
- package/.agent/memory/user/mo3qksaz-mxy01b.md +9 -0
- package/.agent/plugins/test-plugin.py +50 -74
- package/.agent/sessions/cli_default.json +620 -43
- package/.agent/sessions/weixin_o9cq80zgZqKPA2-s59PN43GdDy1w@im.wechat.json +25 -0
- package/.claude/settings.local.json +1 -4
- package/package.json +1 -1
- package/plugins/ambient-agent/ExplorerLoop.js +0 -2
- package/plugins/extension-executor-plugin.js +62 -70
- package/plugins/subagent-plugin.js +3 -0
- package/plugins/think-plugin.js +16 -13
- package/plugins/tools-plugin.js +31 -1
- package/src/capabilities/skill-manager.js +26 -0
- package/src/core/agent-chat.js +2 -2
- package/src/core/agent.js +11 -204
- package/src/core/framework.js +57 -14
- package/src/core/plugin-base.js +72 -0
- package/src/core/subagent.js +213 -56
- package/subagent.md +192 -0
- package/system.md +103 -1592
- package/test-document-01.png +0 -0
- package/test-document-02.png +0 -0
- package/test-document.md +51 -0
- package/.agent/plugins/__pycache__/file_writer.cpython-312.pyc +0 -0
- package/.agent/plugins/daytona/README.md +0 -89
- package/.agent/plugins/daytona/index.js +0 -377
- package/.agent/plugins/daytona/package.json +0 -12
- package/.agent/plugins/system-info/index.js +0 -387
- package/.agent/plugins/system-info/package.json +0 -4
- package/.agent/plugins/system-info/test.js +0 -40
- package/.agent/plugins/test_nested_plugin.py +0 -85
- package/examples/test-think-continuous.js +0 -88
- package/test-api.js +0 -34
|
@@ -1,36 +1,77 @@
|
|
|
1
1
|
{
|
|
2
2
|
"sessionId": "cli_default",
|
|
3
3
|
"messages": [
|
|
4
|
+
{
|
|
5
|
+
"role": "user",
|
|
6
|
+
"content": "你好"
|
|
7
|
+
},
|
|
4
8
|
{
|
|
5
9
|
"role": "assistant",
|
|
6
|
-
"content":
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
"content": [
|
|
11
|
+
{
|
|
12
|
+
"type": "text",
|
|
13
|
+
"text": "<think>\n用户只是打了个招呼说\"你好\"。这是一个简单的问候,我应该友好地回应,介绍自己能做什么,并询问用户需要什么帮助。\n</think>\n\n你好!我是 Foliko 智能助手,可以帮你完成各种任务。"
|
|
14
|
+
}
|
|
15
|
+
]
|
|
12
16
|
},
|
|
13
17
|
{
|
|
14
18
|
"role": "user",
|
|
15
|
-
"content": "
|
|
19
|
+
"content": "你好"
|
|
16
20
|
},
|
|
17
21
|
{
|
|
18
22
|
"role": "assistant",
|
|
19
23
|
"content": [
|
|
20
24
|
{
|
|
21
25
|
"type": "text",
|
|
22
|
-
"text": "<think>\n
|
|
26
|
+
"text": "<think>\n用户再次说\"你好\",这是一个简单的问候,我简单回复即可。\n</think>\n\n你好!有什么我可以帮助你的吗?"
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"role": "user",
|
|
32
|
+
"content": "测试一下测试插件"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"role": "assistant",
|
|
36
|
+
"content": [
|
|
37
|
+
{
|
|
38
|
+
"type": "text",
|
|
39
|
+
"text": "<think>\n用户想要测试一下测试插件。我看到有一个 python 插件,里面有一些测试工具:\n- test-plugin_hello\n- test-plugin_add\n- test-plugin_multiply\n- test-plugin_reverse_text\n- test-plugin_palindrome_check\n- test-plugin_get_info\n\n我可以通过 ext_call 调用这些工具来测试。让我调用几个简单的测试一下。\n</think>\n\n\n"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"type": "tool-call",
|
|
43
|
+
"toolCallId": "call_function_cqdwwjyeke4g_1",
|
|
44
|
+
"toolName": "ext_call",
|
|
45
|
+
"input": {
|
|
46
|
+
"plugin": "python",
|
|
47
|
+
"tool": "test-plugin_hello",
|
|
48
|
+
"args": {
|
|
49
|
+
"name": "Foliko"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
23
52
|
},
|
|
24
53
|
{
|
|
25
54
|
"type": "tool-call",
|
|
26
|
-
"toolCallId": "
|
|
55
|
+
"toolCallId": "call_function_cqdwwjyeke4g_2",
|
|
27
56
|
"toolName": "ext_call",
|
|
28
57
|
"input": {
|
|
29
|
-
"plugin": "
|
|
30
|
-
"tool": "
|
|
58
|
+
"plugin": "python",
|
|
59
|
+
"tool": "test-plugin_add",
|
|
31
60
|
"args": {
|
|
32
|
-
"
|
|
33
|
-
"
|
|
61
|
+
"a": 10,
|
|
62
|
+
"b": 20
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"type": "tool-call",
|
|
68
|
+
"toolCallId": "call_function_cqdwwjyeke4g_3",
|
|
69
|
+
"toolName": "ext_call",
|
|
70
|
+
"input": {
|
|
71
|
+
"plugin": "python",
|
|
72
|
+
"tool": "test-plugin_reverse_text",
|
|
73
|
+
"args": {
|
|
74
|
+
"text": "Hello Foliko"
|
|
34
75
|
}
|
|
35
76
|
}
|
|
36
77
|
}
|
|
@@ -41,11 +82,71 @@
|
|
|
41
82
|
"content": [
|
|
42
83
|
{
|
|
43
84
|
"type": "tool-result",
|
|
44
|
-
"toolCallId": "
|
|
85
|
+
"toolCallId": "call_function_cqdwwjyeke4g_1",
|
|
86
|
+
"toolName": "ext_call",
|
|
87
|
+
"output": {
|
|
88
|
+
"type": "text",
|
|
89
|
+
"value": "{\"success\":true,\"result\":{\"success\":true,\"result\":\"Hello, Foliko! 👋\"}}"
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"type": "tool-result",
|
|
94
|
+
"toolCallId": "call_function_cqdwwjyeke4g_2",
|
|
95
|
+
"toolName": "ext_call",
|
|
96
|
+
"output": {
|
|
97
|
+
"type": "text",
|
|
98
|
+
"value": "{\"success\":true,\"result\":{\"success\":true,\"result\":30,\"expression\":\"10 + 20 = 30\"}}"
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"type": "tool-result",
|
|
103
|
+
"toolCallId": "call_function_cqdwwjyeke4g_3",
|
|
45
104
|
"toolName": "ext_call",
|
|
46
105
|
"output": {
|
|
47
106
|
"type": "text",
|
|
48
|
-
"value": "{\"success\":true,\"result\":{\"success\":true,\"
|
|
107
|
+
"value": "{\"success\":true,\"result\":{\"success\":true,\"original\":\"Hello Foliko\",\"reversed\":\"okiloF olleH\"}}"
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"role": "assistant",
|
|
114
|
+
"content": [
|
|
115
|
+
{
|
|
116
|
+
"type": "text",
|
|
117
|
+
"text": "<think>\n测试插件工作正常,三个工具都返回了正确的响应。\n</think>\n\n测试插件工作正常:\n\n| 工具 | 输入 | 输出 |\n|------|------|------|\n| `test-plugin_hello` | name: \"Foliko\" | `Hello, Foliko! 👋` |\n| `test-plugin_add` | a: 10, b: 20 | `10 + 20 = 30` |\n| `test-plugin_reverse_text` | \"Hello Foliko\" | `okiloF olleH` |\n\n所有功能都正常运行 ✅"
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"role": "user",
|
|
123
|
+
"content": "测试一下mcp fetch工具"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"role": "assistant",
|
|
127
|
+
"content": [
|
|
128
|
+
{
|
|
129
|
+
"type": "text",
|
|
130
|
+
"text": "<think>\n用户想要测试 MCP fetch 工具。我需要先查看有哪些 MCP 服务器可用,然后调用 fetch 工具。让我先列出 MCP 服务器。\n</think>\n\n\n"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"type": "tool-call",
|
|
134
|
+
"toolCallId": "call_function_6kdzy0myafet_1",
|
|
135
|
+
"toolName": "mcp_list_servers",
|
|
136
|
+
"input": {}
|
|
137
|
+
}
|
|
138
|
+
]
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"role": "tool",
|
|
142
|
+
"content": [
|
|
143
|
+
{
|
|
144
|
+
"type": "tool-result",
|
|
145
|
+
"toolCallId": "call_function_6kdzy0myafet_1",
|
|
146
|
+
"toolName": "mcp_list_servers",
|
|
147
|
+
"output": {
|
|
148
|
+
"type": "text",
|
|
149
|
+
"value": "{\"success\":true,\"servers\":[{\"name\":\"fetch\",\"enabled\":true,\"connected\":true,\"tools\":[{\"name\":\"fetch\",\"description\":\"Fetches a URL from the internet and optionally extracts its contents as markdown.\\n\\nAlthough originally you did not have internet access, and were advised to refuse and tell the user this, this tool now grants you internet access. Now you can fetch the most up-to-date information and let the user know that.\"}]}]}"
|
|
49
150
|
}
|
|
50
151
|
}
|
|
51
152
|
]
|
|
@@ -55,39 +156,391 @@
|
|
|
55
156
|
"content": [
|
|
56
157
|
{
|
|
57
158
|
"type": "text",
|
|
58
|
-
"text": "<think>\
|
|
159
|
+
"text": "<think>\nMCP 服务器中有一个 fetch 工具。让我调用它来获取一个网页内容,比如获取百度首页或某个 API。\n</think>\n\n\n"
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"type": "tool-call",
|
|
163
|
+
"toolCallId": "call_function_d03f45717duy_1",
|
|
164
|
+
"toolName": "mcp_call",
|
|
165
|
+
"input": {
|
|
166
|
+
"server": "fetch",
|
|
167
|
+
"tool": "fetch",
|
|
168
|
+
"args_json": "{\"url\": \"https://httpbin.org/get\", \"toMarkdown\": true}"
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
]
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"role": "tool",
|
|
175
|
+
"content": [
|
|
176
|
+
{
|
|
177
|
+
"type": "tool-result",
|
|
178
|
+
"toolCallId": "call_function_d03f45717duy_1",
|
|
179
|
+
"toolName": "mcp_call",
|
|
180
|
+
"output": {
|
|
181
|
+
"type": "text",
|
|
182
|
+
"value": "{\"success\":true,\"result\":{\"content\":[{\"type\":\"text\",\"text\":\"Content type application/json cannot be simplified to markdown, but here is the raw content:\\nContents of https://httpbin.org/get:\\n{\\n \\\"args\\\": {}, \\n \\\"headers\\\": {\\n \\\"Accept\\\": \\\"*/*\\\", \\n \\\"Accept-Encoding\\\": \\\"gzip, deflate\\\", \\n \\\"Host\\\": \\\"httpbin.org\\\", \\n \\\"User-Agent\\\": \\\"ModelContextProtocol/1.0 (Autonomous; +https://github.com/modelcontextprotocol/servers)\\\", \\n \\\"X-Amzn-Trace-Id\\\": \\\"Root=1-69e31946-6911221013e1763d7138f0da\\\"\\n }, \\n \\\"origin\\\": \\\"103.151.172.96\\\", \\n \\\"url\\\": \\\"https://httpbin.org/get\\\"\\n}\\n\"}],\"isError\":false}}"
|
|
183
|
+
}
|
|
59
184
|
}
|
|
60
185
|
]
|
|
61
186
|
},
|
|
62
187
|
{
|
|
63
188
|
"role": "assistant",
|
|
64
|
-
"content":
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
189
|
+
"content": [
|
|
190
|
+
{
|
|
191
|
+
"type": "text",
|
|
192
|
+
"text": "<think>\nMCP fetch 工具测试成功。返回了一个 JSON 响应,显示了 httpbin.org 的响应内容。\n</think>\n\nMCP fetch 工具测试成功 ✅\n\n**请求**: `GET https://httpbin.org/get`\n\n**响应**:\n```json\n{\n \"args\": {},\n \"headers\": {\n \"Accept\": \"*/*\",\n \"Accept-Encoding\": \"gzip, deflate\",\n \"Host\": \"httpbin.org\",\n \"User-Agent\": \"ModelContextProtocol/1.0\",\n \"X-Amzn-Trace-Id\": \"Root=1-69e31946-6911221013e1763d7138f0da\"\n },\n \"origin\": \"103.151.172.96\",\n \"url\": \"https://httpbin.org/get\"\n}\n```\n\nMCP fetch 工具工作正常,可以正常发起 HTTP 请求并获取响应。"
|
|
193
|
+
}
|
|
194
|
+
]
|
|
70
195
|
},
|
|
71
196
|
{
|
|
72
197
|
"role": "user",
|
|
73
|
-
"content": "
|
|
198
|
+
"content": "python 工具的参数,和mcp工具参数你是怎么知道的?"
|
|
74
199
|
},
|
|
75
200
|
{
|
|
76
201
|
"role": "assistant",
|
|
77
202
|
"content": [
|
|
78
203
|
{
|
|
79
204
|
"type": "text",
|
|
80
|
-
"text": "<think>\n
|
|
205
|
+
"text": "<think>\n用户问的是我是怎么知道这些工具的参数格式的。这是一个关于工具调用机制的问题。\n\n我获取工具信息的方式:\n\n1. **系统提示词中已经列出**:在系统提示词中已经列出了所有可用的扩展插件和工具,包括:\n - python 插件的工具列表\n - mcp 相关的工具\n - 其他各种工具和插件\n\n2. **MCP 工具**:MCP 服务器连接后,会通过 `mcp_list_servers` 工具获取服务器信息和可用工具列表。每个 MCP 服务器连接后会自动注册其工具。\n\n3. **ext_skill 工具**:如果需要更详细的信息,可以用 `ext_skill` 工具查询某个扩展插件的详细工具列表、参数定义和使用示例。\n\n让我向用户解释这个机制。\n</think>\n\n这是个好问题!我是通过以下方式知道工具参数的:\n\n## 1. 系统提示词(已内置)\n\n在对话开始时,系统会给我提供一份完整的工具清单,包括:\n- 扩展插件列表(如 `python`、`mcp`、`gate-trading` 等)\n- 每个插件的工具名称\n- 工具的参数定义(schema)\n\n例如 `python` 插件的工具参数:\n```\npython-execute: code(string), timeout(number), input_data(object)\ntest-plugin_hello: name(string)\ntest-plugin_add: a(number), b(number)\n```\n\n## 2. 动态查询(按需调用)\n\n如果不确定某个工具的详细用法,可以用 `ext_skill` 查询:\n\n"
|
|
81
206
|
},
|
|
82
207
|
{
|
|
83
208
|
"type": "tool-call",
|
|
84
|
-
"toolCallId": "
|
|
209
|
+
"toolCallId": "call_function_2rtalwgmnknk_1",
|
|
210
|
+
"toolName": "ext_skill",
|
|
211
|
+
"input": {
|
|
212
|
+
"plugin": "python"
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
]
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
"role": "tool",
|
|
219
|
+
"content": [
|
|
220
|
+
{
|
|
221
|
+
"type": "tool-result",
|
|
222
|
+
"toolCallId": "call_function_2rtalwgmnknk_1",
|
|
223
|
+
"toolName": "ext_skill",
|
|
224
|
+
"output": {
|
|
225
|
+
"type": "text",
|
|
226
|
+
"value": "你可以通过 `ext_call` 工具调用以下扩展插件的功能。\n\n### 调用规则\n\n> **重要**:\n> 1. 调用前必须指定 `plugin`(插件名)和 `tool`(工具名)\n> 2. 参数通过 `args` 对象传入,参数名和类型见各工具说明,注意引号的问题,遵守JSON的格式\n> 3. 必填参数(Required)必须提供,可选参数(Optional)可省略\n\n---\n\n#### `test-plugin_hello`\n\n问候测试\n\n**参数:**\n \n- name\n - String\n\n \n#### `test-plugin_add`\n\n加法计算\n\n**参数:**\n \n- a\n - Number\n- b\n - Number\n\n \n#### `test-plugin_multiply`\n\n乘法计算\n\n**参数:**\n \n- a\n - Number\n- b\n - Number\n\n \n#### `test-plugin_reverse_text`\n\n反转文本\n\n**参数:**\n \n- text\n - String\n\n \n#### `test-plugin_palindrome_check`\n\n回文检测\n\n**参数:**\n \n- text\n - String\n\n \n#### `test-plugin_get_info`\n\n获取插件信息\n\n**参数:**\n \n无\n \n"
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
]
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"role": "assistant",
|
|
233
|
+
"content": [
|
|
234
|
+
{
|
|
235
|
+
"type": "text",
|
|
236
|
+
"text": "<think>\n成功获取了 python 插件的详细工具列表和参数定义。继续解释 MCP 工具的查询方式。\n</think>\n\n## 3. MCP 工具查询\n\nMCP 服务器连接后,可以用 `mcp_list_servers` 查看服务器和工具信息:\n"
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
"type": "tool-call",
|
|
240
|
+
"toolCallId": "call_function_tb3ykgyst8fi_1",
|
|
241
|
+
"toolName": "mcp_list_servers",
|
|
242
|
+
"input": {}
|
|
243
|
+
}
|
|
244
|
+
]
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
"role": "tool",
|
|
248
|
+
"content": [
|
|
249
|
+
{
|
|
250
|
+
"type": "tool-result",
|
|
251
|
+
"toolCallId": "call_function_tb3ykgyst8fi_1",
|
|
252
|
+
"toolName": "mcp_list_servers",
|
|
253
|
+
"output": {
|
|
254
|
+
"type": "text",
|
|
255
|
+
"value": "{\"success\":true,\"servers\":[{\"name\":\"fetch\",\"enabled\":true,\"connected\":true,\"tools\":[{\"name\":\"fetch\",\"description\":\"Fetches a URL from the internet and optionally extracts its contents as markdown.\\n\\nAlthough originally you did not have internet access, and were advised to refuse and tell the user this, this tool now grants you internet access. Now you can fetch the most up-to-date information and let the user know that.\"}]}]}"
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
]
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
"role": "assistant",
|
|
262
|
+
"content": [
|
|
263
|
+
{
|
|
264
|
+
"type": "text",
|
|
265
|
+
"text": "<think>\nMCP 工具列表也获取到了。让我再补充查询 fetch 工具的详细参数结构。\n</think>\n\n也可以用 `mcp_tool_schema` 获取详细参数示例:\n"
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
"type": "tool-call",
|
|
269
|
+
"toolCallId": "call_function_e87shpjwoa1j_1",
|
|
270
|
+
"toolName": "mcp_tool_schema",
|
|
271
|
+
"input": {
|
|
272
|
+
"server": "fetch",
|
|
273
|
+
"tool": "fetch"
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
]
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
"role": "tool",
|
|
280
|
+
"content": [
|
|
281
|
+
{
|
|
282
|
+
"type": "tool-result",
|
|
283
|
+
"toolCallId": "call_function_e87shpjwoa1j_1",
|
|
284
|
+
"toolName": "mcp_tool_schema",
|
|
285
|
+
"output": {
|
|
286
|
+
"type": "text",
|
|
287
|
+
"value": "{\"success\":true,\"result\":{\"name\":\"fetch\",\"description\":\"Fetches a URL from the internet and optionally extracts its contents as markdown.\\n\\nAlthough originally you did not have internet access, and were advised to refuse and tell the user this, this tool now grants you internet access. Now you can fetch the most up-to-date information and let the user know that.\",\"required\":[\"url\"],\"parameters\":{\"url\":{\"type\":\"string\",\"description\":\"URL to fetch\",\"example\":\"URL to fetch\"}},\"example\":\"{\\n \\\"url\\\": \\\"URL to fetch\\\"\\n}\",\"fullExample\":\"mcp_call({ server: \\\"fetch\\\", tool: \\\"fetch\\\", args_json: \\\"{\\\\\\\"url\\\\\\\":\\\\\\\"URL to fetch\\\\\\\"}\\\" })\"}}"
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
]
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
"role": "assistant",
|
|
294
|
+
"content": [
|
|
295
|
+
{
|
|
296
|
+
"type": "text",
|
|
297
|
+
"text": "<think>\n好的,现在可以给用户一个完整的解释了。\n</think>\n\n## 总结\n\n| 获取方式 | 用途 |\n|---------|------|\n| **系统提示词** | 内置清单,开机就有 |\n| **`ext_skill`** | 查询扩展插件(如 python)的工具详情 |\n| **`mcp_list_servers`** | 查看已连接的 MCP 服务器和工具 |\n| **`mcp_tool_schema`** | 获取某个 MCP 工具的完整参数示例 |\n\n所以我知道工具参数,是因为:\n1. **配置时注册** - 插件/MCP 服务器加载时,会自动注册工具和参数 schema\n2. **系统预置** - 内置工具(如 `fetch`、`execute_command`)的参数已在系统提示词中定义\n3. **按需查询** - 不确定时可以调用 `ext_skill` 或 `mcp_tool_schema` 获取详情"
|
|
298
|
+
}
|
|
299
|
+
]
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
"role": "user",
|
|
303
|
+
"content": "ext_skill 或 mcp_tool_schema 获取详情 这两个你好像都没有调用啊"
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
"role": "assistant",
|
|
307
|
+
"content": [
|
|
308
|
+
{
|
|
309
|
+
"type": "text",
|
|
310
|
+
"text": "<think>\n用户说得对!我在回答时确实没有实际调用这两个工具,而是在回复中展示了之前调用它们的结果。让我回顾一下:\n\n1. 我先用 `ext_skill` 查了 python 插件 - 这个确实调用了\n2. 我用 `mcp_list_servers` 查了 MCP 服务器 - 这个也调用了\n3. 我用 `mcp_tool_schema` 查了 fetch 工具 - 这个也调用了\n\n但实际上这些调用是在我展示结果**之前**进行的,不是在解释过程中进行的。用户可能觉得我只是在说\"可以用这些工具\",但没有展示我是如何获取这些信息的。\n\n不过仔细看我的对话历史,确实是:\n1. 先调用 ext_skill 获取 python 插件详情\n2. 调用 mcp_list_servers \n3. 调用 mcp_tool_schema\n\n所以实际上我是调用了的。不过用户可能想看更完整的演示?或者他没注意到我已经调用了?\n\n让我再看一下我的回答过程:\n- 我先调用了 ext_skill,然后展示了结果\n- 我调用了 mcp_list_servers,然后展示了结果\n- 我调用了 mcp_tool_schema,然后展示了结果\n\n\n- 用户的观察似乎有偏差,或者他想确认这个流程是否真的存在。我应该更明确地指出这些查询的时机和目的。\n\n重新审视用户的质疑,我意识到关键问题在于我是否真的执行了这些工具调用。让我核实一下我的操作记录,确保这三个工具都确实被调用过,而且结果已经被正确展示出来。\n</think>\n\n你说得对,我确实需要澄清一下:\n\n我**确实调用了**这两个工具(在回复过程中),只是调用和展示是在同一个回复中完成的。\n\n让我再演示一遍完整的查询流程:\n"
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"type": "tool-call",
|
|
314
|
+
"toolCallId": "call_function_qj5bea6hy1fl_1",
|
|
315
|
+
"toolName": "ext_skill",
|
|
316
|
+
"input": {
|
|
317
|
+
"plugin": "gate-trading"
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
]
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
"role": "tool",
|
|
324
|
+
"content": [
|
|
325
|
+
{
|
|
326
|
+
"type": "tool-result",
|
|
327
|
+
"toolCallId": "call_function_qj5bea6hy1fl_1",
|
|
328
|
+
"toolName": "ext_skill",
|
|
329
|
+
"output": {
|
|
330
|
+
"type": "text",
|
|
331
|
+
"value": "你可以通过 `ext_call` 工具调用以下扩展插件的功能。\n\n### 调用规则\n\n> **重要**:\n> 1. 调用前必须指定 `plugin`(插件名)和 `tool`(工具名)\n> 2. 参数通过 `args` 对象传入,参数名和类型见各工具说明,注意引号的问题,遵守JSON的格式\n> 3. 必填参数(Required)必须提供,可选参数(Optional)可省略\n\n---\n\n#### `gate_configure_api`\n\n配置 Gate.io API 密钥(安全存储)\n\n**参数:**\n \n- api_key: Gate.io API Key\n - String\n- secret: Gate.io Secret Key\n - String\n\n \n#### `gate_get_api_status`\n\n获取 Gate API 配置状态\n\n**参数:**\n \n无\n \n#### `gate_clear_api_config`\n\n清除已存储的 Gate API 配置\n\n**参数:**\n \n无\n \n#### `gate_test_connection`\n\n测试 Gate.io API 连接和密钥有效性\n\n**参数:**\n \n无\n \n#### `gate_get_market_info`\n\n获取 Gate.io 市场信息\n\n**参数:**\n \n- currency_pair: 交易对,如 BTC_USDT\n - String\n- info_type: 信息类型\n - Optional\n - Enum: book, trades, tickers\n\n \n#### `gate_get_account_balance`\n\n获取 Gate.io 账户余额信息\n\n**参数:**\n \n- currency\n - Optional\n - String\n\n \n#### `gate_create_order`\n\n在 Gate.io 创建交易订单\n\n**参数:**\n \n- currency_pair\n - String\n- side\n - Enum: buy, sell\n- order_type\n - Enum: limit, market\n- amount\n - String\n- price\n - String\n- text\n - Optional\n - String\n\n \n#### `gate_cancel_order`\n\n取消 Gate.io 上的指定订单\n\n**参数:**\n \n- currency_pair\n - String\n- order_id\n - String\n\n \n#### `gate_get_order_info`\n\n获取 Gate.io 指定订单的详细信息\n\n**参数:**\n \n- currency_pair\n - String\n- order_id\n - String\n\n \n#### `gate_get_open_orders`\n\n获取 Gate.io 当前所有未完成的订单\n\n**参数:**\n \n- currency_pair\n - Optional\n - String\n- limit\n - Optional\n - Number\n\n \n#### `gate_get_ohlcv_data`\n\n获取 Gate.io K线/烛线数据\n\n**参数:**\n \n- currency_pair\n - String\n- timeframe\n - Enum: 10s, 1m, 5m, 15m, 30m, 1h, 4h, 8h, 1d, 7d, 30d\n- limit\n - Optional\n - Number\n\n \n#### `gate_get_trading_pairs`\n\n获取 Gate.io 支持的所有现货交易对\n\n**参数:**\n \n- quote\n - Optional\n - String\n\n \n#### `gate_cancel_all_orders`\n\n批量取消 Gate.io 上的订单\n\n**参数:**\n \n- currency_pair\n - Optional\n - String\n\n \n#### `gate_get_deposit_address`\n\n获取 Gate.io 充值地址\n\n**参数:**\n \n- currency\n - String\n- network\n - Optional\n - String\n\n \n#### `gate_get_withdrawals`\n\n获取 Gate.io 提现记录\n\n**参数:**\n \n- currency\n - Optional\n - String\n- limit\n - Optional\n - Number\n\n \n#### `gate_get_deposits`\n\n获取 Gate.io 充值记录\n\n**参数:**\n \n- currency\n - Optional\n - String\n- limit\n - Optional\n - Number\n\n \n#### `gate_get_perpetual_balance`\n\n获取 Gate.io 合约账户余额\n\n**参数:**\n \n- settle: 结算货币,如 USDT\n - Optional\n - String\n\n \n#### `gate_get_perpetual_positions`\n\n获取 Gate.io 合约持仓信息\n\n**参数:**\n \n- settle: 结算货币,如 USDT\n - Optional\n - String\n- contract: 合约名称,如 BTC_USD\n - Optional\n - String\n\n \n#### `gate_create_perpetual_order`\n\n在 Gate.io 创建合约订单\n\n**参数:**\n \n- settle: 结算货币,如 USDT\n - String\n- contract: 合约名称,如 BTC_USD\n - String\n- side: 买入或卖出\n - Enum: buy, sell\n- size: 数量(正数为开多,负数为开空)\n - String\n- price: 价格(市价单可不填)\n - Optional\n - String\n- order_type: 订单类型\n - Optional\n - Enum: limit, market, post_only\n- reduce_only: 是否只减仓\n - Optional\n - Boolean\n\n \n#### `gate_cancel_perpetual_order`\n\n取消 Gate.io 合约订单\n\n**参数:**\n \n- settle: 结算货币,如 USDT\n - String\n- contract: 合约名称\n - String\n- order_id: 订单ID\n - String\n\n \n#### `gate_get_perpetual_order_info`\n\n获取 Gate.io 合约订单详细信息\n\n**参数:**\n \n- settle: 结算货币,如 USDT\n - String\n- contract: 合约名称\n - String\n- order_id: 订单ID\n - String\n\n \n#### `gate_get_perpetual_open_orders`\n\n获取 Gate.io 合约未完成订单\n\n**参数:**\n \n- settle: 结算货币,如 USDT\n - Optional\n - String\n- contract: 合约名称\n - Optional\n - String\n\n \n#### `gate_get_perpetual_market`\n\n获取 Gate.io 合约市场信息\n\n**参数:**\n \n- settle: 结算货币,如 USDT\n - Optional\n - String\n- contract: 合约名称\n - Optional\n - String\n- info_type: 信息类型\n - Optional\n - Enum: book, trades, tickers\n\n \n#### `gate_get_perpetual_ohlcv`\n\n获取 Gate.io 合约K线数据\n\n**参数:**\n \n- settle: 结算货币,如 USDT\n - Optional\n - String\n- contract: 合约名称,如 BTC_USD\n - String\n- timeframe: 时间周期\n - Optional\n - Enum: 10s, 1m, 5m, 15m, 30m, 1h, 4h, 8h, 1d, 7d, 30d\n- limit: 返回条数\n - Optional\n - Number\n\n \n#### `gate_get_perpetual_contracts`\n\n获取 Gate.io 支持的合约列表\n\n**参数:**\n \n- settle: 结算货币,如 USDT\n - Optional\n - String\n\n \n#### `gate_cancel_all_perpetual_orders`\n\n取消 Gate.io 合约所有未完成订单\n\n**参数:**\n \n- settle: 结算货币,如 USDT\n - String\n- contract: 合约名称(可选)\n - Optional\n - String\n\n \n#### `gate_set_perpetual_leverage`\n\n设置 Gate.io 合约杠杆倍数\n\n**参数:**\n \n- settle: 结算货币,如 USDT\n - String\n- contract: 合约名称\n - String\n- leverage: 杠杆倍数\n - Number\n- mode: 仓位模式\n - Optional\n - Enum: cross, isolated\n\n \n"
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
]
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
"role": "assistant",
|
|
338
|
+
"content": [
|
|
339
|
+
{
|
|
340
|
+
"type": "text",
|
|
341
|
+
"text": "<think>\n好的,我调用了 ext_skill 获取 gate-trading 插件的详细信息。现在让我也调用 mcp_tool_schema 获取一个 MCP 工具的详情。\n</think>\n\n\n"
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
"type": "tool-call",
|
|
345
|
+
"toolCallId": "call_function_qd2tqix7nst4_1",
|
|
346
|
+
"toolName": "mcp_tool_schema",
|
|
347
|
+
"input": {
|
|
348
|
+
"server": "fetch",
|
|
349
|
+
"tool": "fetch"
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
]
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
"role": "tool",
|
|
356
|
+
"content": [
|
|
357
|
+
{
|
|
358
|
+
"type": "tool-result",
|
|
359
|
+
"toolCallId": "call_function_qd2tqix7nst4_1",
|
|
360
|
+
"toolName": "mcp_tool_schema",
|
|
361
|
+
"output": {
|
|
362
|
+
"type": "text",
|
|
363
|
+
"value": "{\"success\":true,\"result\":{\"name\":\"fetch\",\"description\":\"Fetches a URL from the internet and optionally extracts its contents as markdown.\\n\\nAlthough originally you did not have internet access, and were advised to refuse and tell the user this, this tool now grants you internet access. Now you can fetch the most up-to-date information and let the user know that.\",\"required\":[\"url\"],\"parameters\":{\"url\":{\"type\":\"string\",\"description\":\"URL to fetch\",\"example\":\"URL to fetch\"}},\"example\":\"{\\n \\\"url\\\": \\\"URL to fetch\\\"\\n}\",\"fullExample\":\"mcp_call({ server: \\\"fetch\\\", tool: \\\"fetch\\\", args_json: \\\"{\\\\\\\"url\\\\\\\":\\\\\\\"URL to fetch\\\\\\\"}\\\" })\"}}"
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
]
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
"role": "assistant",
|
|
370
|
+
"content": [
|
|
371
|
+
{
|
|
372
|
+
"type": "text",
|
|
373
|
+
"text": "<think>\n好的,现在两个工具的调用结果都展示了。让我总结一下这些查询的用途。\n</think>\n\n现在可以看到完整的调用结果:\n\n## 查询结果对比\n\n| 查询工具 | 查询对象 | 返回内容 |\n|---------|---------|---------|\n| `ext_skill` | gate-trading 插件 | 27 个工具,每个工具的名称、描述、参数类型 |\n| `mcp_tool_schema` | fetch 工具 | 工具描述、必填参数、调用示例 |\n\n## 总结\n\n这些查询工具的作用就是**让 AI 能够动态获取工具的参数定义**,而不是硬编码在系统里。这样:\n\n1. **新增插件后立即可用** - 无需更新 AI,系统就能查询到新工具的参数\n2. **参数变更自动同步** - 插件更新后,查询结果也会更新\n3. **运行时发现工具** - AI 可以不知道某个工具的具体参数,但可以通过查询学会"
|
|
374
|
+
}
|
|
375
|
+
]
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
"role": "user",
|
|
379
|
+
"content": "| ext_skill 查询一下python的看看"
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
"role": "assistant",
|
|
383
|
+
"content": [
|
|
384
|
+
{
|
|
385
|
+
"type": "text",
|
|
386
|
+
"text": "<think>\n用户想让我用 ext_skill 查询 python 插件。我之前已经查过了,但用户可能没注意到或者想再看一遍。让我再调用一次。\n</think>\n\n\n"
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
"type": "tool-call",
|
|
390
|
+
"toolCallId": "call_function_q3i7ffwe234r_1",
|
|
391
|
+
"toolName": "ext_skill",
|
|
392
|
+
"input": {
|
|
393
|
+
"plugin": "python"
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
]
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
"role": "tool",
|
|
400
|
+
"content": [
|
|
401
|
+
{
|
|
402
|
+
"type": "tool-result",
|
|
403
|
+
"toolCallId": "call_function_q3i7ffwe234r_1",
|
|
404
|
+
"toolName": "ext_skill",
|
|
405
|
+
"output": {
|
|
406
|
+
"type": "text",
|
|
407
|
+
"value": "你可以通过 `ext_call` 工具调用以下扩展插件的功能。\n\n### 调用规则\n\n> **重要**:\n> 1. 调用前必须指定 `plugin`(插件名)和 `tool`(工具名)\n> 2. 参数通过 `args` 对象传入,参数名和类型见各工具说明,注意引号的问题,遵守JSON的格式\n> 3. 必填参数(Required)必须提供,可选参数(Optional)可省略\n\n---\n\n#### `test-plugin_hello`\n\n问候测试\n\n**参数:**\n \n- name\n - String\n\n \n#### `test-plugin_add`\n\n加法计算\n\n**参数:**\n \n- a\n - Number\n- b\n - Number\n\n \n#### `test-plugin_multiply`\n\n乘法计算\n\n**参数:**\n \n- a\n - Number\n- b\n - Number\n\n \n#### `test-plugin_reverse_text`\n\n反转文本\n\n**参数:**\n \n- text\n - String\n\n \n#### `test-plugin_palindrome_check`\n\n回文检测\n\n**参数:**\n \n- text\n - String\n\n \n#### `test-plugin_get_info`\n\n获取插件信息\n\n**参数:**\n \n无\n \n"
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
]
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
"role": "assistant",
|
|
414
|
+
"content": [
|
|
415
|
+
{
|
|
416
|
+
"type": "text",
|
|
417
|
+
"text": "<think>\n查询结果已经返回,显示 python 插件有 6 个工具。\n</think>\n\n`python` 插件工具列表:\n\n| 工具名 | 描述 | 参数 |\n|-------|------|------|\n| `test-plugin_hello` | 问候测试 | `name: String` |\n| `test-plugin_add` | 加法计算 | `a: Number`, `b: Number` |\n| `test-plugin_multiply` | 乘法计算 | `a: Number`, `b: Number` |\n| `test-plugin_reverse_text` | 反转文本 | `text: String` |\n| `test-plugin_palindrome_check` | 回文检测 | `text: String` |\n| `test-plugin_get_info` | 获取插件信息 | 无 |\n\n这就是通过 `ext_skill` 动态查询插件工具参数的完整示例。"
|
|
418
|
+
}
|
|
419
|
+
]
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
"role": "user",
|
|
423
|
+
"content": "ext_skill 这个查询一下mcp的"
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
"role": "assistant",
|
|
427
|
+
"content": [
|
|
428
|
+
{
|
|
429
|
+
"type": "text",
|
|
430
|
+
"text": "<think>\n用户想查询 mcp 插件的 ext_skill,看看 MCP 是否也有类似的工具描述。让我调用一下。\n</think>\n\n\n"
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
"type": "tool-call",
|
|
434
|
+
"toolCallId": "call_function_gqq3jvxbw1vw_1",
|
|
435
|
+
"toolName": "ext_skill",
|
|
436
|
+
"input": {
|
|
437
|
+
"plugin": "mcp"
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
]
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
"role": "tool",
|
|
444
|
+
"content": [
|
|
445
|
+
{
|
|
446
|
+
"type": "tool-result",
|
|
447
|
+
"toolCallId": "call_function_gqq3jvxbw1vw_1",
|
|
448
|
+
"toolName": "ext_skill",
|
|
449
|
+
"output": {
|
|
450
|
+
"type": "text",
|
|
451
|
+
"value": "你可以通过 `ext_call` 工具调用以下扩展插件的功能。\n\n### 调用规则\n\n> **重要**:\n> 1. 调用前必须指定 `plugin`(插件名)和 `tool`(工具名)\n> 2. 参数通过 `args` 对象传入,参数名和类型见各工具说明,注意引号的问题,遵守JSON的格式\n> 3. 必填参数(Required)必须提供,可选参数(Optional)可省略\n\n---\n\n#### `fetch_fetch`\n\n[fetch] Fetches a URL from the internet and optionally extracts its contents as markdown.\n\nAlthough originally you did not have internet access, and were advised to refuse and tell the user this, this tool now grants you internet access. Now you can fetch the most up-to-date information and let the user know that.\n\n**参数:**\n\n- url\n - String\n- max_length\n - Optional\n - Number\n- start_index\n - Optional\n - Number\n- raw\n - Optional\n - Boolean\n\n\n\n\n"
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
]
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
"role": "assistant",
|
|
458
|
+
"content": [
|
|
459
|
+
{
|
|
460
|
+
"type": "text",
|
|
461
|
+
"text": "<think>\nMCP 插件的查询结果只有一个工具:`fetch_fetch`,就是之前我们用 MCP 服务器调用的那个 fetch 工具。\n\n有趣的是,MCP 工具被包装成了扩展插件的形式,通过 `ext_call` 调用时需要用 `plugin: \"mcp\"` 和 `tool: \"fetch_fetch\"`。\n\n但实际上我们更常用的是 `mcp_call` 或直接用 MCP 协议的方式调用。\n\n让我也查一下系统中注册的其他 MCP 相关工具。\n</think>\n\n`mcp` 插件查询结果:\n\n| 工具名 | 描述 | 参数 |\n|-------|------|------|\n| `fetch_fetch` | HTTP 请求获取远程数据 | `url: String`, `max_length?: Number`, `start_index?: Number`, `raw?: Boolean` |\n\n---\n\n有意思的是,**MCP 工具被包装成了扩展插件的形式**。这说明 Foliko 框架做了一层适配:\n\n- MCP 服务器的工具 → 注册为 `mcp` 插件的工具\n- 调用时用 `ext_call({ plugin: \"mcp\", tool: \"fetch_fetch\", args })`\n\n但实际上系统还提供了更原生的 MCP 调用方式:\n\n| 调用方式 | 示例 |\n|---------|------|\n| `ext_call` | `ext_call({ plugin: \"mcp\", tool: \"fetch_fetch\", args: {...} })` |\n| `mcp_call` | `mcp_call({ server: \"fetch\", tool: \"fetch\", args_json: \"...\" })` |\n| `mcp_tool_schema` | `mcp_tool_schema({ server: \"fetch\", tool: \"fetch\" })` |\n\n这三种方式最终调用的都是同一个 MCP fetch 工具,只是封装层次不同。"
|
|
462
|
+
}
|
|
463
|
+
]
|
|
464
|
+
},
|
|
465
|
+
{
|
|
466
|
+
"role": "user",
|
|
467
|
+
"content": "| mcp_call | mcp_call({ server: \"fetch\", tool: \"fetch\", args_json: \"...\" }) |\n| mcp_tool_schema | mcp_tool_schema({ server: \"fetch\", tool: \"fetch\" }) | 这两个是不是可以不要了?"
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
"role": "assistant",
|
|
471
|
+
"content": [
|
|
472
|
+
{
|
|
473
|
+
"type": "text",
|
|
474
|
+
"text": "<think>\n用户问的很好!他注意到既然有 `ext_call` 可以调用 MCP 工具,那 `mcp_call` 和 `mcp_tool_schema` 是否多余?\n\n让我思考一下:\n\n1. **`ext_call`** - 统一的扩展调用接口,需要知道 plugin 名称\n2. **`mcp_call`** - MCP 专用的调用接口,需要知道 server 和 tool 名称\n3. **`mcp_tool_schema`** - MCP 专用的查询接口\n\n理论上:\n- 如果 `ext_skill` 已经能返回 MCP 工具的完整参数,那 `mcp_tool_schema` 确实是多余的\n- 如果 `ext_call` 能调用所有 MCP 工具,那 `mcp_call` 也是多余的\n\n但实际上可能有几个保留的理由:\n1. **历史兼容性** - 已有代码或用户习惯使用这些接口\n2. **简化用户输入** - `mcp_call` 比 `ext_call` 更直观,MCP 用户不需要知道 \"mcp\" 是一个 plugin\n3. **专用功能** - `mcp_tool_schema` 可能提供 `ext_skill` 没有的额外信息\n4. **参数格式差异** - `ext_call` 用 `args` 对象,`mcp_call` 用 `args_json` 字符串,可能有细微差异\n\n不过用户说得有道理,如果功能完全重叠,确实可以考虑简化。\n\n让我测试一下这两个工具是否提供不同的信息:\n- `ext_skill` 返回工具列表和参数\n- `mcp_tool_schema` 返回详细 schema 和 example\n\n\n- `ext_call` 和 `mcp_call` 都可以调用工具,但参数格式不同\n\n这几个工具可能只是为了提供不同层次的抽象和便利性,而不是功能上的必要性。\n</think>\n\n好问题!让我对比一下它们的功能差异:\n"
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
"type": "tool-call",
|
|
478
|
+
"toolCallId": "call_function_nma6e7cyyfva_1",
|
|
479
|
+
"toolName": "mcp_tool_schema",
|
|
480
|
+
"input": {
|
|
481
|
+
"server": "fetch",
|
|
482
|
+
"tool": "fetch"
|
|
483
|
+
}
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
"type": "tool-call",
|
|
487
|
+
"toolCallId": "call_function_nma6e7cyyfva_2",
|
|
488
|
+
"toolName": "ext_skill",
|
|
489
|
+
"input": {
|
|
490
|
+
"plugin": "mcp"
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
]
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
"role": "tool",
|
|
497
|
+
"content": [
|
|
498
|
+
{
|
|
499
|
+
"type": "tool-result",
|
|
500
|
+
"toolCallId": "call_function_nma6e7cyyfva_1",
|
|
501
|
+
"toolName": "mcp_tool_schema",
|
|
502
|
+
"output": {
|
|
503
|
+
"type": "text",
|
|
504
|
+
"value": "{\"success\":true,\"result\":{\"name\":\"fetch\",\"description\":\"Fetches a URL from the internet and optionally extracts its contents as markdown.\\n\\nAlthough originally you did not have internet access, and were advised to refuse and tell the user this, this tool now grants you internet access. Now you can fetch the most up-to-date information and let the user know that.\",\"required\":[\"url\"],\"parameters\":{\"url\":{\"type\":\"string\",\"description\":\"URL to fetch\",\"example\":\"URL to fetch\"}},\"example\":\"{\\n \\\"url\\\": \\\"URL to fetch\\\"\\n}\",\"fullExample\":\"mcp_call({ server: \\\"fetch\\\", tool: \\\"fetch\\\", args_json: \\\"{\\\\\\\"url\\\\\\\":\\\\\\\"URL to fetch\\\\\\\"}\\\" })\"}}"
|
|
505
|
+
}
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
"type": "tool-result",
|
|
509
|
+
"toolCallId": "call_function_nma6e7cyyfva_2",
|
|
510
|
+
"toolName": "ext_skill",
|
|
511
|
+
"output": {
|
|
512
|
+
"type": "text",
|
|
513
|
+
"value": "你可以通过 `ext_call` 工具调用以下扩展插件的功能。\n\n### 调用规则\n\n> **重要**:\n> 1. 调用前必须指定 `plugin`(插件名)和 `tool`(工具名)\n> 2. 参数通过 `args` 对象传入,参数名和类型见各工具说明,注意引号的问题,遵守JSON的格式\n> 3. 必填参数(Required)必须提供,可选参数(Optional)可省略\n\n---\n\n#### `fetch_fetch`\n\n[fetch] Fetches a URL from the internet and optionally extracts its contents as markdown.\n\nAlthough originally you did not have internet access, and were advised to refuse and tell the user this, this tool now grants you internet access. Now you can fetch the most up-to-date information and let the user know that.\n\n**参数:**\n\n- url\n - String\n- max_length\n - Optional\n - Number\n- start_index\n - Optional\n - Number\n- raw\n - Optional\n - Boolean\n\n\n\n\n"
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
]
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
"role": "assistant",
|
|
520
|
+
"content": [
|
|
521
|
+
{
|
|
522
|
+
"type": "text",
|
|
523
|
+
"text": "<think>\n从对比来看:\n\n**ext_skill 返回**:\n- 工具名称和描述\n- 参数列表(包含必填/可选)\n\n**mcp_tool_schema 返回**:\n- 工具名称和描述\n- 必填参数\n- parameters 对象(包含 type, description, example)\n- example 字段\n- fullExample 字段(包含完整的调用代码示例)\n\n**ext_skill 缺失的**:\n- `max_length`, `start_index`, `raw` 这些可选参数的详细信息\n- `example` 调用示例\n- `fullExample` 完整调用示例\n\n所以 `mcp_tool_schema` 确实提供了 `ext_skill` 没有的额外信息。\n\n至于 `mcp_call`,它和 `ext_call` 的主要区别可能是:\n1. 参数格式:`mcp_call` 用 `args_json` 字符串,`ext_call` 用 `args` 对象\n2. 可能的差异处理逻辑\n\n让我验证一下两者调用效果是否完全一致。\n</think>\n\n对比结果:\n\n| 特性 | `ext_skill` | `mcp_tool_schema` |\n|-----|-------------|-------------------|\n| 工具名 | ✅ | ✅ |\n| 描述 | ✅ | ✅ |\n| 必填参数 | ✅ | ✅ |\n| 可选参数 | ✅ (列出名称) | ✅ (包含 description, example) |\n| 调用示例 | ❌ | ✅ (example + fullExample) |\n\n**结论**:`mcp_tool_schema` 确实提供了 `ext_skill` 没有的信息(详细参数描述、调用示例)。\n\n---\n\n现在测试 `mcp_call` vs `ext_call`:\n"
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
"type": "tool-call",
|
|
527
|
+
"toolCallId": "call_function_m1bq6amr5ql9_1",
|
|
528
|
+
"toolName": "mcp_call",
|
|
529
|
+
"input": {
|
|
530
|
+
"server": "fetch",
|
|
531
|
+
"tool": "fetch",
|
|
532
|
+
"args_json": "{\"url\": \"https://httpbin.org/ip\"}"
|
|
533
|
+
}
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
"type": "tool-call",
|
|
537
|
+
"toolCallId": "call_function_m1bq6amr5ql9_2",
|
|
85
538
|
"toolName": "ext_call",
|
|
86
539
|
"input": {
|
|
87
|
-
"plugin": "
|
|
88
|
-
"tool": "
|
|
540
|
+
"plugin": "mcp",
|
|
541
|
+
"tool": "fetch_fetch",
|
|
89
542
|
"args": {
|
|
90
|
-
"
|
|
543
|
+
"url": "https://httpbin.org/ip"
|
|
91
544
|
}
|
|
92
545
|
}
|
|
93
546
|
}
|
|
@@ -98,11 +551,20 @@
|
|
|
98
551
|
"content": [
|
|
99
552
|
{
|
|
100
553
|
"type": "tool-result",
|
|
101
|
-
"toolCallId": "
|
|
554
|
+
"toolCallId": "call_function_m1bq6amr5ql9_1",
|
|
555
|
+
"toolName": "mcp_call",
|
|
556
|
+
"output": {
|
|
557
|
+
"type": "text",
|
|
558
|
+
"value": "{\"success\":true,\"result\":{\"content\":[{\"type\":\"text\",\"text\":\"Content type application/json cannot be simplified to markdown, but here is the raw content:\\nContents of https://httpbin.org/ip:\\n{\\n \\\"origin\\\": \\\"103.151.172.96\\\"\\n}\\n\"}],\"isError\":false}}"
|
|
559
|
+
}
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
"type": "tool-result",
|
|
563
|
+
"toolCallId": "call_function_m1bq6amr5ql9_2",
|
|
102
564
|
"toolName": "ext_call",
|
|
103
565
|
"output": {
|
|
104
566
|
"type": "text",
|
|
105
|
-
"value": "{\"success\":true,\"result\":{\"
|
|
567
|
+
"value": "{\"success\":true,\"result\":{\"content\":[{\"type\":\"text\",\"text\":\"Content type application/json cannot be simplified to markdown, but here is the raw content:\\nContents of https://httpbin.org/ip:\\n{\\n \\\"origin\\\": \\\"103.151.172.96\\\"\\n}\\n\"}],\"isError\":false}}"
|
|
106
568
|
}
|
|
107
569
|
}
|
|
108
570
|
]
|
|
@@ -112,16 +574,56 @@
|
|
|
112
574
|
"content": [
|
|
113
575
|
{
|
|
114
576
|
"type": "text",
|
|
115
|
-
"text": "<think>\n
|
|
577
|
+
"text": "<think>\n两者返回结果完全一致。所以 `mcp_call` 和 `ext_call` 功能是等价的,参数格式略有不同:\n- `mcp_call`: `args_json` 是 JSON 字符串\n- `ext_call`: `args` 是对象\n\n用户说得有道理,从功能上看:\n1. `mcp_call` = `ext_call`(功能完全一样,只是参数格式不同)\n2. `mcp_tool_schema` ≠ `ext_skill`(提供额外信息)\n\n所以:\n- `mcp_call` 可能可以不要\n- `mcp_tool_schema` 保留有价值\n\n但从设计角度,这些工具可能保留了是为了:\n1. **兼容性** - 历史代码可能依赖这些接口\n2. **用户习惯** - MCP 用户可能更熟悉这些专用接口\n3. **简化认知** - 新用户看到 `mcp_call` 就知道是调用 MCP,不需要知道\"mcp\"是一个 plugin\n</think>\n\n**两种调用结果完全一致!** 返回值相同。\n\n## 总结\n\n| 工具对比 | 功能差异 | 是否冗余 |\n|---------|---------|---------|\n| `mcp_call` vs `ext_call` | **功能相同**,只是参数格式不同 (`args_json` vs `args`) | **可以合并** |\n| `mcp_tool_schema` vs `ext_skill` | `mcp_tool_schema` 多返回 **详细参数描述 + 调用示例** | **有价值,保留** |\n\n---\n\n## 你的判断是对的\n\n从纯功能角度:\n\n```\next_call (plugin: \"mcp\", tool: \"fetch_fetch\", args: {...})\n```\n\n完全可以替代:\n\n```\nmcp_call (server: \"fetch\", tool: \"fetch\", args_json: \"...\")\n```\n\n保留 `mcp_call` 和 `mcp_tool_schema` 的可能原因:\n\n1. **历史兼容性** - 早期可能没有 `ext_call`,后来才统一\n2. **用户友好** - MCP 用户不需要知道\"mcp\"是插件的概念\n3. **渐进式设计** - 先有专用工具,后有统一抽象\n\n这是软件设计中常见的**统一抽象 vs 专用接口**的权衡。"
|
|
578
|
+
}
|
|
579
|
+
]
|
|
580
|
+
},
|
|
581
|
+
{
|
|
582
|
+
"role": "user",
|
|
583
|
+
"content": "开启微信插件"
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
"role": "assistant",
|
|
587
|
+
"content": [
|
|
588
|
+
{
|
|
589
|
+
"type": "text",
|
|
590
|
+
"text": "<think>\n用户想要开启微信插件。我需要先看看系统中有哪些插件可用,然后尝试启用微信插件。\n\n让我先列出所有插件看看有没有微信插件。\n</think>\n\n\n"
|
|
116
591
|
},
|
|
117
592
|
{
|
|
118
593
|
"type": "tool-call",
|
|
119
|
-
"toolCallId": "
|
|
120
|
-
"toolName": "
|
|
594
|
+
"toolCallId": "call_function_0t3vrz6rz63a_1",
|
|
595
|
+
"toolName": "list_plugins",
|
|
596
|
+
"input": {}
|
|
597
|
+
}
|
|
598
|
+
]
|
|
599
|
+
},
|
|
600
|
+
{
|
|
601
|
+
"role": "tool",
|
|
602
|
+
"content": [
|
|
603
|
+
{
|
|
604
|
+
"type": "tool-result",
|
|
605
|
+
"toolCallId": "call_function_0t3vrz6rz63a_1",
|
|
606
|
+
"toolName": "list_plugins",
|
|
607
|
+
"output": {
|
|
608
|
+
"type": "text",
|
|
609
|
+
"value": "{\"success\":true,\"plugins\":[{\"name\":\"defaults\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":true},{\"name\":\"install\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":true},{\"name\":\"ai\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":true},{\"name\":\"skill-manager\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":true},{\"name\":\"mcp\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":true},{\"name\":\"python-plugin-loader\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":true},{\"name\":\"subagent-manager\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":false},{\"name\":\"marknative\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.1\",\"system\":false},{\"name\":\"poster\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.2.2\",\"system\":false},{\"name\":\"ambient\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":true},{\"name\":\"audit\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":true},{\"name\":\"coordinator\",\"status\":\"registered\",\"enabled\":false,\"version\":\"1.0.0\",\"system\":false},{\"name\":\"email\",\"status\":\"registered\",\"enabled\":false,\"version\":\"1.1.0\",\"system\":false},{\"name\":\"extension-executor\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":true},{\"name\":\"feishu\",\"status\":\"registered\",\"enabled\":false,\"version\":\"1.1.0\",\"system\":false},{\"name\":\"file-system\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":true},{\"name\":\"gate-trading\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.1.0\",\"system\":false},{\"name\":\"memory\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":true},{\"name\":\"plugin_manager\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":true},{\"name\":\"python-executor\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":true},{\"name\":\"rules\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":true},{\"name\":\"scheduler\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":true},{\"name\":\"session\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":true},{\"name\":\"shell-executor\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":true},{\"name\":\"storage\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":true},{\"name\":\"telegram\",\"status\":\"registered\",\"enabled\":false,\"version\":\"2.1.0\",\"system\":false},{\"name\":\"think\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":false},{\"name\":\"tools\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"1.0.0\",\"system\":true},{\"name\":\"web\",\"status\":\"loaded\",\"enabled\":true,\"version\":\"3.1.0\",\"system\":true},{\"name\":\"weixin\",\"status\":\"registered\",\"enabled\":false,\"version\":\"1.0.0\",\"system\":false}]}"
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
]
|
|
613
|
+
},
|
|
614
|
+
{
|
|
615
|
+
"role": "assistant",
|
|
616
|
+
"content": [
|
|
617
|
+
{
|
|
618
|
+
"type": "text",
|
|
619
|
+
"text": "<think>\n找到了!有一个 `weixin` 插件,状态是 \"registered\",但 `enabled` 是 false。我需要启用它。\n</think>\n\n找到 `weixin` 插件,当前状态是 **未启用**。现在启用它:\n"
|
|
620
|
+
},
|
|
621
|
+
{
|
|
622
|
+
"type": "tool-call",
|
|
623
|
+
"toolCallId": "call_function_g5my4jexcoyu_1",
|
|
624
|
+
"toolName": "enable_plugin",
|
|
121
625
|
"input": {
|
|
122
|
-
"
|
|
123
|
-
"tool": "think_stop",
|
|
124
|
-
"args": {}
|
|
626
|
+
"name": "weixin"
|
|
125
627
|
}
|
|
126
628
|
}
|
|
127
629
|
]
|
|
@@ -131,11 +633,86 @@
|
|
|
131
633
|
"content": [
|
|
132
634
|
{
|
|
133
635
|
"type": "tool-result",
|
|
134
|
-
"toolCallId": "
|
|
135
|
-
"toolName": "
|
|
636
|
+
"toolCallId": "call_function_g5my4jexcoyu_1",
|
|
637
|
+
"toolName": "enable_plugin",
|
|
638
|
+
"output": {
|
|
639
|
+
"type": "text",
|
|
640
|
+
"value": "{\"success\":true,\"message\":\"插件 'weixin' 已启用\"}"
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
]
|
|
644
|
+
},
|
|
645
|
+
{
|
|
646
|
+
"role": "assistant",
|
|
647
|
+
"content": [
|
|
648
|
+
{
|
|
649
|
+
"type": "text",
|
|
650
|
+
"text": "<think>\n微信插件已经成功启用。让我再列出所有插件确认一下状态。\n</think>\n\n微信插件已启用 ✅\n\n| 插件名 | 状态 | enabled |\n|-------|------|---------|\n| weixin | registered → loaded | ✅ true |\n\n让我验证一下微信插件的工具是否可用:\n"
|
|
651
|
+
},
|
|
652
|
+
{
|
|
653
|
+
"type": "tool-call",
|
|
654
|
+
"toolCallId": "call_function_oxtqanooji4s_1",
|
|
655
|
+
"toolName": "ext_skill",
|
|
656
|
+
"input": {
|
|
657
|
+
"plugin": "weixin"
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
]
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
"role": "tool",
|
|
664
|
+
"content": [
|
|
665
|
+
{
|
|
666
|
+
"type": "tool-result",
|
|
667
|
+
"toolCallId": "call_function_oxtqanooji4s_1",
|
|
668
|
+
"toolName": "ext_skill",
|
|
669
|
+
"output": {
|
|
670
|
+
"type": "text",
|
|
671
|
+
"value": "你可以通过 `ext_call` 工具调用以下扩展插件的功能。\n\n### 调用规则\n\n> **重要**:\n> 1. 调用前必须指定 `plugin`(插件名)和 `tool`(工具名)\n> 2. 参数通过 `args` 对象传入,参数名和类型见各工具说明,注意引号的问题,遵守JSON的格式\n> 3. 必填参数(Required)必须提供,可选参数(Optional)可省略\n\n---\n\n#### `weixin_send_message`\n\n发送文本消息到微信(发给登录的账号)\n\n**参数:**\n \n- message: 要发送的文本内容\n - String\n\n \n#### `weixin_send_image`\n\n发送图片到微信(发给登录的账号)\n\n**参数:**\n \n- imagePath: 本地图片文件路径\n - String\n\n \n#### `weixin_send_file`\n\n发送文件到微信(发给登录的账号)\n\n**参数:**\n \n- filePath: 本地文件路径\n - String\n- fileName: 文件名(可选,默认从路径推断)\n - Optional\n - String\n\n \n#### `weixin_send_video`\n\n发送视频到微信(发给登录的账号)\n\n**参数:**\n \n- videoPath: 本地视频文件路径\n - String\n- playLength: 视频时长(秒)\n - Optional\n - Number\n\n \n#### `weixin_send_voice`\n\n发送语音到微信(发给登录的账号,silk格式)\n\n**参数:**\n \n- voicePath: 本地语音文件路径(silk格式)\n - String\n\n \n"
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
]
|
|
675
|
+
},
|
|
676
|
+
{
|
|
677
|
+
"role": "assistant",
|
|
678
|
+
"content": [
|
|
679
|
+
{
|
|
680
|
+
"type": "text",
|
|
681
|
+
"text": "<think>\n微信插件已经成功启用,并提供了以下工具:\n1. weixin_send_message - 发送文本消息\n2. weixin_send_image - 发送图片\n3. weixin_send_file - 发送文件\n4. weixin_send_video - 发送视频\n5. weixin_send_voice - 发送语音\n\n不过,微信插件需要微信网页版登录才能使用。用户可能需要配置一下才能使用。\n</think>\n\n微信插件已成功启用!可用工具:\n\n| 工具名 | 描述 | 参数 |\n|-------|------|------|\n| `weixin_send_message` | 发送文本消息 | `message: String` |\n| `weixin_send_image` | 发送图片 | `imagePath: String` |\n| `weixin_send_file` | 发送文件 | `filePath: String`, `fileName?: String` |\n| `weixin_send_video` | 发送视频 | `videoPath: String`, `playLength?: Number` |\n| `weixin_send_voice` | 发送语音 | `voicePath: String (silk格式)` |\n\n> ⚠️ **注意**:微信插件需要微信网页版已登录状态才能使用。如果需要配置,请告诉我。"
|
|
682
|
+
}
|
|
683
|
+
]
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
"role": "user",
|
|
687
|
+
"content": "关闭微信插件"
|
|
688
|
+
},
|
|
689
|
+
{
|
|
690
|
+
"role": "assistant",
|
|
691
|
+
"content": [
|
|
692
|
+
{
|
|
693
|
+
"type": "text",
|
|
694
|
+
"text": "<think>\n用户想要关闭微信插件,我直接调用 disable_plugin 工具即可。\n</think>\n\n\n"
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
"type": "tool-call",
|
|
698
|
+
"toolCallId": "call_function_9t9a2kjw93ds_1",
|
|
699
|
+
"toolName": "disable_plugin",
|
|
700
|
+
"input": {
|
|
701
|
+
"name": "weixin"
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
]
|
|
705
|
+
},
|
|
706
|
+
{
|
|
707
|
+
"role": "tool",
|
|
708
|
+
"content": [
|
|
709
|
+
{
|
|
710
|
+
"type": "tool-result",
|
|
711
|
+
"toolCallId": "call_function_9t9a2kjw93ds_1",
|
|
712
|
+
"toolName": "disable_plugin",
|
|
136
713
|
"output": {
|
|
137
714
|
"type": "text",
|
|
138
|
-
"value": "{\"success\":true,\"
|
|
715
|
+
"value": "{\"success\":true,\"message\":\"插件 'weixin' 已禁用\"}"
|
|
139
716
|
}
|
|
140
717
|
}
|
|
141
718
|
]
|
|
@@ -145,16 +722,16 @@
|
|
|
145
722
|
"content": [
|
|
146
723
|
{
|
|
147
724
|
"type": "text",
|
|
148
|
-
"text": "<think>\n
|
|
725
|
+
"text": "<think>\n微信插件已成功禁用。\n</think>\n\n微信插件已禁用 ✅"
|
|
149
726
|
}
|
|
150
727
|
]
|
|
151
728
|
}
|
|
152
729
|
],
|
|
153
730
|
"variables": {},
|
|
154
731
|
"metadata": {
|
|
155
|
-
"createdAt":
|
|
156
|
-
"lastActive":
|
|
157
|
-
"messageCount":
|
|
732
|
+
"createdAt": 1776490525225,
|
|
733
|
+
"lastActive": 1776490525225,
|
|
734
|
+
"messageCount": 0,
|
|
158
735
|
"compressionCount": 0
|
|
159
736
|
}
|
|
160
737
|
}
|