Skip to content

Commit 87a4ca6

Browse files
authored
feat: the model supports the ability to invoke built-in tools (casibase#1708)
1 parent 0f29aab commit 87a4ca6

File tree

5 files changed

+92
-29
lines changed

5 files changed

+92
-29
lines changed

agent/agent_util.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package agent
2+
3+
import (
4+
"errors"
5+
"strings"
6+
7+
"github.com/ThinkInAIXYZ/go-mcp/protocol"
8+
"github.com/casibase/casibase/agent/builtin_tool"
9+
)
10+
11+
func GetServerNameAndToolNameFromId(id string) (string, string) {
12+
tokens := strings.Split(id, "__")
13+
14+
if len(tokens) == 1 {
15+
return "", tokens[0]
16+
}
17+
18+
if len(tokens) > 2 {
19+
panic(errors.New("GetServerNameAndToolNameFromName() error, wrong token count for ID: " + id))
20+
}
21+
22+
return tokens[0], tokens[1]
23+
}
24+
25+
func GetIdFromServerNameAndToolName(ServerName, toolName string) string {
26+
return ServerName + "__" + toolName
27+
}
28+
29+
func MergeBuiltinTools(agentClients *AgentClients, selectedTools []string) *AgentClients {
30+
if len(selectedTools) == 0 {
31+
return agentClients
32+
}
33+
34+
builtinToolReg := builtin_tool.NewToolRegistry()
35+
allBuiltinTools := builtinToolReg.GetToolsAsProtocolTools()
36+
37+
toolMap := make(map[string]*protocol.Tool, len(allBuiltinTools))
38+
for _, tool := range allBuiltinTools {
39+
toolMap[tool.Name] = tool
40+
}
41+
42+
selectedBuiltinTools := make([]*protocol.Tool, 0, len(selectedTools))
43+
for _, selectedName := range selectedTools {
44+
if tool, ok := toolMap[selectedName]; ok {
45+
selectedBuiltinTools = append(selectedBuiltinTools, tool)
46+
}
47+
}
48+
49+
if len(selectedBuiltinTools) == 0 {
50+
return agentClients
51+
}
52+
53+
if agentClients == nil {
54+
return &AgentClients{
55+
Tools: selectedBuiltinTools,
56+
BuiltinToolReg: builtinToolReg,
57+
}
58+
}
59+
60+
agentClients.Tools = append(agentClients.Tools, selectedBuiltinTools...)
61+
agentClients.BuiltinToolReg = builtinToolReg
62+
return agentClients
63+
}

agent/mcp_util.go

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ package agent
33
import (
44
"context"
55
"encoding/json"
6-
"errors"
76
"fmt"
8-
"strings"
97
"time"
108

119
"github.com/ThinkInAIXYZ/go-mcp/client"
@@ -115,16 +113,3 @@ func GetMCPClientMap(config string, toolsMap map[string]bool) (map[string]*clien
115113

116114
return clients, nil
117115
}
118-
119-
func GetServerNameAndToolNameFromId(id string) (string, string) {
120-
tokens := strings.Split(id, "__")
121-
if len(tokens) != 2 {
122-
panic(errors.New("GetServerNameAndToolNameFromName() error, wrong token count for ID: " + id))
123-
}
124-
125-
return tokens[0], tokens[1]
126-
}
127-
128-
func GetIdFromServerNameAndToolName(ServerName, toolName string) string {
129-
return ServerName + "__" + toolName
130-
}

agent/provider.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919

2020
"github.com/ThinkInAIXYZ/go-mcp/client"
2121
"github.com/ThinkInAIXYZ/go-mcp/protocol"
22+
"github.com/casibase/casibase/agent/builtin_tool"
2223
"github.com/casibase/casibase/i18n"
2324
)
2425

@@ -27,8 +28,9 @@ type AgentProvider interface {
2728
}
2829

2930
type AgentClients struct {
30-
Clients map[string]*client.Client
31-
Tools []*protocol.Tool
31+
Clients map[string]*client.Client
32+
Tools []*protocol.Tool
33+
BuiltinToolReg *builtin_tool.ToolRegistry
3234
}
3335

3436
func GetAgentProvider(typ string, subType string, text string, mcpTools []*McpTools, lang string) (AgentProvider, error) {

controllers/message_answer.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"fmt"
1919
"strings"
2020

21+
"github.com/casibase/casibase/agent"
2122
"github.com/casibase/casibase/conf"
2223
"github.com/casibase/casibase/embedding"
2324
"github.com/casibase/casibase/model"
@@ -166,6 +167,8 @@ func (c *ApiController) GetMessageAnswer() {
166167
return
167168
}
168169

170+
agentClients = agent.MergeBuiltinTools(agentClients, store.BuiltinTools)
171+
169172
knowledgeCount := store.KnowledgeCount
170173
if knowledgeCount <= 0 {
171174
knowledgeCount = 10

model/mcp.go

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"fmt"
2121
"io"
2222

23-
"github.com/ThinkInAIXYZ/go-mcp/client"
2423
"github.com/ThinkInAIXYZ/go-mcp/protocol"
2524
"github.com/casibase/casibase/agent"
2625
"github.com/casibase/casibase/i18n"
@@ -133,18 +132,13 @@ func QueryTextWithTools(p ModelProvider, question string, writer io.Writer, hist
133132
for _, toolCall := range toolCalls {
134133
serverName, toolName := agent.GetServerNameAndToolNameFromId(toolCall.Function.Name)
135134

136-
mcpClient, ok := agentInfo.AgentClients.Clients[serverName]
137-
if !ok {
138-
continue
139-
}
140-
141135
messages = append(messages, &RawMessage{
142136
Text: "Call result from " + toolCall.Function.Name,
143137
Author: "AI",
144138
ToolCall: toolCall,
145139
})
146140

147-
messages, err = callTools(toolCall, toolName, mcpClient, messages, lang)
141+
messages, err = callTools(toolCall, serverName, toolName, agentInfo.AgentClients, messages, lang)
148142
if err != nil {
149143
return nil, err
150144
}
@@ -182,20 +176,36 @@ func createToolMessage(toolCall openai.ToolCall, text string) *RawMessage {
182176
}
183177
}
184178

185-
func callTools(toolCall openai.ToolCall, functionName string, mcpClient *client.Client, messages []*RawMessage, lang string) ([]*RawMessage, error) {
179+
func callTools(toolCall openai.ToolCall, serverName, toolName string, agentClients *agent.AgentClients, messages []*RawMessage, lang string) ([]*RawMessage, error) {
186180
var arguments map[string]interface{}
187181
ctx := context.Background()
188182

189183
if err := json.Unmarshal([]byte(toolCall.Function.Arguments), &arguments); err != nil {
190184
return nil, fmt.Errorf(i18n.Translate(lang, "model:failed to parse tool arguments: %v"), err)
191185
}
192186

193-
req := &protocol.CallToolRequest{
194-
Name: functionName,
195-
Arguments: arguments,
187+
var result *protocol.CallToolResult
188+
var err error
189+
190+
if serverName == "" {
191+
// builtin tools
192+
if agentClients.BuiltinToolReg == nil {
193+
return messages, nil
194+
}
195+
result, err = agentClients.BuiltinToolReg.ExecuteTool(ctx, toolName, arguments)
196+
} else {
197+
// MCP tools
198+
mcpClient, ok := agentClients.Clients[serverName]
199+
if !ok {
200+
return messages, nil
201+
}
202+
req := &protocol.CallToolRequest{
203+
Name: toolName,
204+
Arguments: arguments,
205+
}
206+
result, err = mcpClient.CallTool(ctx, req)
196207
}
197208

198-
result, err := mcpClient.CallTool(ctx, req)
199209
response := &ToolCallResponse{
200210
ToolName: toolCall.Function.Name,
201211
}

0 commit comments

Comments
 (0)