Feat: todo tools
This commit is contained in:
303
tools.go
303
tools.go
@@ -543,6 +543,225 @@ func executeCommand(args map[string]string) []byte {
|
|||||||
|
|
||||||
// Helper functions for command execution
|
// Helper functions for command execution
|
||||||
|
|
||||||
|
// Todo structure
|
||||||
|
type TodoItem struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Task string `json:"task"`
|
||||||
|
Status string `json:"status"` // "pending", "in_progress", "completed"
|
||||||
|
}
|
||||||
|
|
||||||
|
type TodoList struct {
|
||||||
|
Items []TodoItem `json:"items"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Global todo list storage
|
||||||
|
var globalTodoList = TodoList{
|
||||||
|
Items: []TodoItem{},
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTodoList() TodoList {
|
||||||
|
return globalTodoList
|
||||||
|
}
|
||||||
|
|
||||||
|
func setTodoList(todoList TodoList) {
|
||||||
|
globalTodoList = todoList
|
||||||
|
}
|
||||||
|
|
||||||
|
// Todo Management Tools
|
||||||
|
func todoCreate(args map[string]string) []byte {
|
||||||
|
task, ok := args["task"]
|
||||||
|
if !ok || task == "" {
|
||||||
|
msg := "task not provided to todo_create tool"
|
||||||
|
logger.Error(msg)
|
||||||
|
return []byte(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate simple ID
|
||||||
|
id := fmt.Sprintf("todo_%d", len(globalTodoList.Items)+1)
|
||||||
|
|
||||||
|
newItem := TodoItem{
|
||||||
|
ID: id,
|
||||||
|
Task: task,
|
||||||
|
Status: "pending",
|
||||||
|
}
|
||||||
|
|
||||||
|
globalTodoList.Items = append(globalTodoList.Items, newItem)
|
||||||
|
|
||||||
|
result := map[string]string{
|
||||||
|
"message": "todo created successfully",
|
||||||
|
"id": id,
|
||||||
|
"task": task,
|
||||||
|
"status": "pending",
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonResult, err := json.Marshal(result)
|
||||||
|
if err != nil {
|
||||||
|
msg := "failed to marshal result; error: " + err.Error()
|
||||||
|
logger.Error(msg)
|
||||||
|
return []byte(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
func todoRead(args map[string]string) []byte {
|
||||||
|
id, ok := args["id"]
|
||||||
|
if ok && id != "" {
|
||||||
|
// Find specific todo by ID
|
||||||
|
for _, item := range globalTodoList.Items {
|
||||||
|
if item.ID == id {
|
||||||
|
result := map[string]interface{}{
|
||||||
|
"todo": item,
|
||||||
|
}
|
||||||
|
jsonResult, err := json.Marshal(result)
|
||||||
|
if err != nil {
|
||||||
|
msg := "failed to marshal result; error: " + err.Error()
|
||||||
|
logger.Error(msg)
|
||||||
|
return []byte(msg)
|
||||||
|
}
|
||||||
|
return jsonResult
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ID not found
|
||||||
|
result := map[string]string{
|
||||||
|
"error": fmt.Sprintf("todo with id %s not found", id),
|
||||||
|
}
|
||||||
|
jsonResult, err := json.Marshal(result)
|
||||||
|
if err != nil {
|
||||||
|
msg := "failed to marshal result; error: " + err.Error()
|
||||||
|
logger.Error(msg)
|
||||||
|
return []byte(msg)
|
||||||
|
}
|
||||||
|
return jsonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return all todos if no ID specified
|
||||||
|
result := map[string]interface{}{
|
||||||
|
"todos": globalTodoList.Items,
|
||||||
|
}
|
||||||
|
jsonResult, err := json.Marshal(result)
|
||||||
|
if err != nil {
|
||||||
|
msg := "failed to marshal result; error: " + err.Error()
|
||||||
|
logger.Error(msg)
|
||||||
|
return []byte(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
func todoUpdate(args map[string]string) []byte {
|
||||||
|
id, ok := args["id"]
|
||||||
|
if !ok || id == "" {
|
||||||
|
msg := "id not provided to todo_update tool"
|
||||||
|
logger.Error(msg)
|
||||||
|
return []byte(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
task, taskOk := args["task"]
|
||||||
|
status, statusOk := args["status"]
|
||||||
|
|
||||||
|
if !taskOk && !statusOk {
|
||||||
|
msg := "neither task nor status provided to todo_update tool"
|
||||||
|
logger.Error(msg)
|
||||||
|
return []byte(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find and update the todo
|
||||||
|
for i, item := range globalTodoList.Items {
|
||||||
|
if item.ID == id {
|
||||||
|
if taskOk {
|
||||||
|
globalTodoList.Items[i].Task = task
|
||||||
|
}
|
||||||
|
if statusOk {
|
||||||
|
// Validate status
|
||||||
|
if status == "pending" || status == "in_progress" || status == "completed" {
|
||||||
|
globalTodoList.Items[i].Status = status
|
||||||
|
} else {
|
||||||
|
result := map[string]string{
|
||||||
|
"error": "status must be one of: pending, in_progress, completed",
|
||||||
|
}
|
||||||
|
jsonResult, err := json.Marshal(result)
|
||||||
|
if err != nil {
|
||||||
|
msg := "failed to marshal result; error: " + err.Error()
|
||||||
|
logger.Error(msg)
|
||||||
|
return []byte(msg)
|
||||||
|
}
|
||||||
|
return jsonResult
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result := map[string]string{
|
||||||
|
"message": "todo updated successfully",
|
||||||
|
"id": id,
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonResult, err := json.Marshal(result)
|
||||||
|
if err != nil {
|
||||||
|
msg := "failed to marshal result; error: " + err.Error()
|
||||||
|
logger.Error(msg)
|
||||||
|
return []byte(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonResult
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ID not found
|
||||||
|
result := map[string]string{
|
||||||
|
"error": fmt.Sprintf("todo with id %s not found", id),
|
||||||
|
}
|
||||||
|
jsonResult, err := json.Marshal(result)
|
||||||
|
if err != nil {
|
||||||
|
msg := "failed to marshal result; error: " + err.Error()
|
||||||
|
logger.Error(msg)
|
||||||
|
return []byte(msg)
|
||||||
|
}
|
||||||
|
return jsonResult
|
||||||
|
}
|
||||||
|
|
||||||
|
func todoDelete(args map[string]string) []byte {
|
||||||
|
id, ok := args["id"]
|
||||||
|
if !ok || id == "" {
|
||||||
|
msg := "id not provided to todo_delete tool"
|
||||||
|
logger.Error(msg)
|
||||||
|
return []byte(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find and remove the todo
|
||||||
|
for i, item := range globalTodoList.Items {
|
||||||
|
if item.ID == id {
|
||||||
|
// Remove item from slice
|
||||||
|
globalTodoList.Items = append(globalTodoList.Items[:i], globalTodoList.Items[i+1:]...)
|
||||||
|
|
||||||
|
result := map[string]string{
|
||||||
|
"message": "todo deleted successfully",
|
||||||
|
"id": id,
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonResult, err := json.Marshal(result)
|
||||||
|
if err != nil {
|
||||||
|
msg := "failed to marshal result; error: " + err.Error()
|
||||||
|
logger.Error(msg)
|
||||||
|
return []byte(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonResult
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ID not found
|
||||||
|
result := map[string]string{
|
||||||
|
"error": fmt.Sprintf("todo with id %s not found", id),
|
||||||
|
}
|
||||||
|
jsonResult, err := json.Marshal(result)
|
||||||
|
if err != nil {
|
||||||
|
msg := "failed to marshal result; error: " + err.Error()
|
||||||
|
logger.Error(msg)
|
||||||
|
return []byte(msg)
|
||||||
|
}
|
||||||
|
return jsonResult
|
||||||
|
}
|
||||||
|
|
||||||
func isCommandAllowed(command string) bool {
|
func isCommandAllowed(command string) bool {
|
||||||
allowedCommands := map[string]bool{
|
allowedCommands := map[string]bool{
|
||||||
"grep": true,
|
"grep": true,
|
||||||
@@ -584,6 +803,10 @@ var fnMap = map[string]fnSig{
|
|||||||
"file_copy": fileCopy,
|
"file_copy": fileCopy,
|
||||||
"file_list": fileList,
|
"file_list": fileList,
|
||||||
"execute_command": executeCommand,
|
"execute_command": executeCommand,
|
||||||
|
"todo_create": todoCreate,
|
||||||
|
"todo_read": todoRead,
|
||||||
|
"todo_update": todoUpdate,
|
||||||
|
"todo_delete": todoDelete,
|
||||||
}
|
}
|
||||||
|
|
||||||
// openai style def
|
// openai style def
|
||||||
@@ -839,4 +1062,84 @@ var baseTools = []models.Tool{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// todo_create
|
||||||
|
models.Tool{
|
||||||
|
Type: "function",
|
||||||
|
Function: models.ToolFunc{
|
||||||
|
Name: "todo_create",
|
||||||
|
Description: "Create a new todo item with a task. Returns the created todo with its ID.",
|
||||||
|
Parameters: models.ToolFuncParams{
|
||||||
|
Type: "object",
|
||||||
|
Required: []string{"task"},
|
||||||
|
Properties: map[string]models.ToolArgProps{
|
||||||
|
"task": models.ToolArgProps{
|
||||||
|
Type: "string",
|
||||||
|
Description: "the task description to add to the todo list",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// todo_read
|
||||||
|
models.Tool{
|
||||||
|
Type: "function",
|
||||||
|
Function: models.ToolFunc{
|
||||||
|
Name: "todo_read",
|
||||||
|
Description: "Read todo items. Without ID returns all todos, with ID returns specific todo.",
|
||||||
|
Parameters: models.ToolFuncParams{
|
||||||
|
Type: "object",
|
||||||
|
Required: []string{},
|
||||||
|
Properties: map[string]models.ToolArgProps{
|
||||||
|
"id": models.ToolArgProps{
|
||||||
|
Type: "string",
|
||||||
|
Description: "optional id of the specific todo item to read",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// todo_update
|
||||||
|
models.Tool{
|
||||||
|
Type: "function",
|
||||||
|
Function: models.ToolFunc{
|
||||||
|
Name: "todo_update",
|
||||||
|
Description: "Update a todo item by ID with new task or status. Status must be one of: pending, in_progress, completed.",
|
||||||
|
Parameters: models.ToolFuncParams{
|
||||||
|
Type: "object",
|
||||||
|
Required: []string{"id"},
|
||||||
|
Properties: map[string]models.ToolArgProps{
|
||||||
|
"id": models.ToolArgProps{
|
||||||
|
Type: "string",
|
||||||
|
Description: "id of the todo item to update",
|
||||||
|
},
|
||||||
|
"task": models.ToolArgProps{
|
||||||
|
Type: "string",
|
||||||
|
Description: "new task description (optional)",
|
||||||
|
},
|
||||||
|
"status": models.ToolArgProps{
|
||||||
|
Type: "string",
|
||||||
|
Description: "new status for the todo: pending, in_progress, or completed (optional)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// todo_delete
|
||||||
|
models.Tool{
|
||||||
|
Type: "function",
|
||||||
|
Function: models.ToolFunc{
|
||||||
|
Name: "todo_delete",
|
||||||
|
Description: "Delete a todo item by ID. Returns success message.",
|
||||||
|
Parameters: models.ToolFuncParams{
|
||||||
|
Type: "object",
|
||||||
|
Required: []string{"id"},
|
||||||
|
Properties: map[string]models.ToolArgProps{
|
||||||
|
"id": models.ToolArgProps{
|
||||||
|
Type: "string",
|
||||||
|
Description: "id of the todo item to delete",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user