feat: add RequestPermissionTool for user permission prompts

This commit is contained in:
anthrodjear 2026-05-05 06:27:49 +03:00
parent cf494c7b9a
commit 7804b12087

View file

@ -1,7 +1,11 @@
package tools package tools
import ( import (
"context"
"fmt"
"sync" "sync"
"github.com/sipeed/picoclaw/pkg/logger"
) )
type PermissionCache struct { type PermissionCache struct {
@ -46,3 +50,58 @@ func (pc *PermissionCache) Revoke(path string) {
defer pc.mu.Unlock() defer pc.mu.Unlock()
delete(pc.perms, path) delete(pc.perms, path)
} }
// RequestPermissionTool prompts user for permission when exec tool needs access outside workspace.
type RequestPermissionTool struct {
cache *PermissionCache
}
func NewRequestPermissionTool(cache *PermissionCache) *RequestPermissionTool {
return &RequestPermissionTool{cache: cache}
}
func (t *RequestPermissionTool) Name() string {
return "request_permission"
}
func (t *RequestPermissionTool) Description() string {
return "Request user permission for accessing paths outside workspace. Returns prompt for user."
}
func (t *RequestPermissionTool) PromptMetadata() PromptMetadata {
return PromptMetadata{
Layer: ToolPromptLayerCapability,
Slot: ToolPromptSlotTooling,
Source: ToolPromptSourceRegistry,
}
}
func (t *RequestPermissionTool) Parameters() map[string]any {
return map[string]any{
"type": "object",
"properties": map[string]any{
"path": map[string]any{
"type": "string",
"description": "Path that needs permission",
},
"command": map[string]any{
"type": "string",
"description": "Original command (for context)",
},
},
"required": []string{"path"},
}
}
func (t *RequestPermissionTool) Execute(ctx context.Context, args map[string]any) *ToolResult {
path, _ := args["path"].(string)
command, _ := args["command"].(string)
logger.InfoCF("permission", "Permission request", map[string]any{"path": path, "command": command})
// Return structured prompt that LLM will show to user
return &ToolResult{
ForLLM: fmt.Sprintf("User permission needed for %s. Ask user: 'Allow once' or 'Allow for session'?", path),
ForUser: fmt.Sprintf("⚠️ **Permission Required**\n\nPicoClaw wants to execute: `%s`\nThis accesses `%s` which is outside your workspace.\n\n**How would you like to proceed?**\n- Type `once` for one-time access\n- Type `session` to allow all access to this path for this session\n- Type `no` to deny", command, path),
}
}