All checks were successful
Beta Release / beta (push) Successful in 40s
Changes:
- Hide <think> tags from user in Studio chat
- Add tool call detection [TOOL_CALL:{...}] in AI responses
- Execute crush tool when requested by AI
- Show loading animation while AI is thinking
The AI can now:
1. Respond directly to user
2. Request tool execution via [TOOL_CALL:{"tool":"crush","task":"..."}]
The system automatically executes the tool and includes results.
Assisted-by: MiniMax-M2.7 via Crush <crush@charm.land>
80 lines
1.6 KiB
Go
80 lines
1.6 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"os/exec"
|
|
"strings"
|
|
)
|
|
|
|
type toolCallRequest struct {
|
|
Tool string `json:"tool"`
|
|
Task string `json:"task"`
|
|
}
|
|
|
|
type toolResult struct {
|
|
Success bool `json:"success"`
|
|
Output string `json:"output"`
|
|
Error string `json:"error,omitempty"`
|
|
}
|
|
|
|
func (s *Server) handleToolCall(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != "POST" {
|
|
writeError(w, "POST only", http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
|
|
var req toolCallRequest
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
|
writeError(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
if req.Tool != "crush" {
|
|
writeError(w, "unsupported tool: "+req.Tool, http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
if req.Task == "" {
|
|
writeError(w, "task is required", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
result := executeTool(req.Tool, req.Task)
|
|
writeJSON(w, result)
|
|
}
|
|
|
|
func executeTool(tool, task string) toolResult {
|
|
var cmd *exec.Cmd
|
|
|
|
switch tool {
|
|
case "crush":
|
|
cmd = exec.Command("crush", "run", task)
|
|
default:
|
|
return toolResult{Success: false, Error: "unknown tool: " + tool}
|
|
}
|
|
|
|
output, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
return toolResult{
|
|
Success: false,
|
|
Output: string(output),
|
|
Error: err.Error(),
|
|
}
|
|
}
|
|
|
|
return toolResult{
|
|
Success: true,
|
|
Output: string(output),
|
|
}
|
|
}
|
|
|
|
func buildToolMessage(tool, task string, history []string) string {
|
|
var b strings.Builder
|
|
b.WriteString("TASK: " + task + "\n\n")
|
|
b.WriteString("CONVERSATION HISTORY:\n")
|
|
for _, msg := range history {
|
|
b.WriteString(strings.Repeat(" ", 4) + strings.Join(strings.Split(msg, "\n"), "\n"+strings.Repeat(" ", 4)) + "\n")
|
|
}
|
|
return b.String()
|
|
} |