From 1e9b543f5e48b0ed42c929a755c41d53dabcba99 Mon Sep 17 00:00:00 2001 From: DBT Date: Tue, 24 Feb 2026 06:40:14 +0000 Subject: [PATCH] align tool naming and message action schema with openclaw compatibility --- pkg/agent/loop.go | 13 ++++++++++--- pkg/tools/compat_alias.go | 39 +++++++++++++++++++++++++++++++++++++++ pkg/tools/message.go | 38 ++++++++++++++++++++++++++++++++------ 3 files changed, 81 insertions(+), 9 deletions(-) create mode 100644 pkg/tools/compat_alias.go diff --git a/pkg/agent/loop.go b/pkg/agent/loop.go index 49b7c12..2a6fd8f 100644 --- a/pkg/agent/loop.go +++ b/pkg/agent/loop.go @@ -63,9 +63,16 @@ func NewAgentLoop(cfg *config.Config, msgBus *bus.MessageBus, provider providers sessionsManager := session.NewSessionManager(filepath.Join(filepath.Dir(cfg.WorkspacePath()), "sessions")) toolsRegistry := tools.NewToolRegistry() - toolsRegistry.Register(&tools.ReadFileTool{}) - toolsRegistry.Register(&tools.WriteFileTool{}) - toolsRegistry.Register(&tools.ListDirTool{}) + readTool := tools.NewReadFileTool(workspace) + writeTool := tools.NewWriteFileTool(workspace) + listTool := tools.NewListDirTool(workspace) + toolsRegistry.Register(readTool) + toolsRegistry.Register(writeTool) + toolsRegistry.Register(listTool) + // OpenClaw-compatible aliases + toolsRegistry.Register(tools.NewAliasTool("read", "Read file content (OpenClaw-compatible alias of read_file)", readTool, map[string]string{"file_path": "path"})) + toolsRegistry.Register(tools.NewAliasTool("write", "Write file content (OpenClaw-compatible alias of write_file)", writeTool, map[string]string{"file_path": "path"})) + toolsRegistry.Register(tools.NewAliasTool("edit", "Edit file content (OpenClaw-compatible alias of edit_file)", tools.NewEditFileTool(workspace), map[string]string{"file_path": "path", "old_string": "oldText", "new_string": "newText"})) toolsRegistry.Register(tools.NewExecTool(cfg.Tools.Shell, workspace)) if cs != nil { diff --git a/pkg/tools/compat_alias.go b/pkg/tools/compat_alias.go new file mode 100644 index 0000000..c6079f2 --- /dev/null +++ b/pkg/tools/compat_alias.go @@ -0,0 +1,39 @@ +package tools + +import ( + "context" +) + +// AliasTool exposes OpenClaw-compatible tool names while forwarding to existing implementations. +type AliasTool struct { + name string + description string + base Tool + argMap map[string]string +} + +func NewAliasTool(name, description string, base Tool, argMap map[string]string) *AliasTool { + return &AliasTool{name: name, description: description, base: base, argMap: argMap} +} + +func (t *AliasTool) Name() string { return t.name } +func (t *AliasTool) Description() string { + if t.description != "" { + return t.description + } + return t.base.Description() +} +func (t *AliasTool) Parameters() map[string]interface{} { return t.base.Parameters() } + +func (t *AliasTool) Execute(ctx context.Context, args map[string]interface{}) (string, error) { + if len(t.argMap) > 0 { + for from, to := range t.argMap { + if v, ok := args[from]; ok { + if _, exists := args[to]; !exists { + args[to] = v + } + } + } + } + return t.base.Execute(ctx, args) +} diff --git a/pkg/tools/message.go b/pkg/tools/message.go index 6fdaffd..a5a585e 100644 --- a/pkg/tools/message.go +++ b/pkg/tools/message.go @@ -23,16 +23,28 @@ func (t *MessageTool) Name() string { } func (t *MessageTool) Description() string { - return "Send a message to user on a chat channel. Use this when you want to communicate something." + return "Channel actions tool. Supports action=send (default). OpenClaw-compatible fields: action, message/content, to/chat_id, channel." } func (t *MessageTool) Parameters() map[string]interface{} { return map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ + "action": map[string]interface{}{ + "type": "string", + "description": "Action type: send (supported), edit/delete/react (reserved)", + }, + "message": map[string]interface{}{ + "type": "string", + "description": "The message content to send (OpenClaw-compatible)", + }, "content": map[string]interface{}{ "type": "string", - "description": "The message content to send", + "description": "Alias of message", + }, + "to": map[string]interface{}{ + "type": "string", + "description": "Optional target id (alias of chat_id)", }, "channel": map[string]interface{}{ "type": "string", @@ -58,7 +70,7 @@ func (t *MessageTool) Parameters() map[string]interface{} { }, }, }, - "required": []string{"content"}, + "required": []string{}, } } @@ -72,13 +84,27 @@ func (t *MessageTool) SetSendCallback(callback SendCallback) { } func (t *MessageTool) Execute(ctx context.Context, args map[string]interface{}) (string, error) { - content, ok := args["content"].(string) - if !ok { - return "", fmt.Errorf("content is required") + action, _ := args["action"].(string) + if action == "" { + action = "send" + } + if action != "send" { + return fmt.Sprintf("Unsupported action: %s (currently only send is implemented)", action), nil + } + + content, _ := args["content"].(string) + if msg, _ := args["message"].(string); msg != "" { + content = msg + } + if content == "" { + return "", fmt.Errorf("message/content is required for action=send") } channel, _ := args["channel"].(string) chatID, _ := args["chat_id"].(string) + if to, _ := args["to"].(string); to != "" { + chatID = to + } if channel == "" { channel = t.defaultChannel