package tools import ( "context" "fmt" ) // Executor executes tools type Executor struct { registry *Registry auditLog AuditLogger } // NewExecutor creates a new tool executor func NewExecutor(registry *Registry, auditLog AuditLogger) *Executor { return &Executor{ registry: registry, auditLog: auditLog, } } // Execute executes a tool func (e *Executor) Execute(ctx context.Context, toolName string, params map[string]interface{}, userID, tenantID string) (*ToolResult, error) { tool, err := e.registry.Get(toolName) if err != nil { return nil, err } // Log execution attempt e.auditLog.LogToolExecution(ctx, &ToolExecutionLog{ ToolName: toolName, UserID: userID, TenantID: tenantID, Params: params, Status: "executing", }) // Execute tool result, err := tool.Execute(ctx, params) if err != nil { e.auditLog.LogToolExecution(ctx, &ToolExecutionLog{ ToolName: toolName, UserID: userID, TenantID: tenantID, Params: params, Status: "failed", Error: err.Error(), }) return nil, err } // Log result e.auditLog.LogToolExecution(ctx, &ToolExecutionLog{ ToolName: toolName, UserID: userID, TenantID: tenantID, Params: params, Status: "completed", Result: result.Data, }) return result, nil } // AuditLogger logs tool executions type AuditLogger interface { LogToolExecution(ctx context.Context, log *ToolExecutionLog) } // ToolExecutionLog represents a tool execution log entry type ToolExecutionLog struct { ToolName string UserID string TenantID string Params map[string]interface{} Status string Error string Result interface{} } // MockAuditLogger is a mock audit logger type MockAuditLogger struct{} // LogToolExecution logs a tool execution func (m *MockAuditLogger) LogToolExecution(ctx context.Context, log *ToolExecutionLog) { // Mock implementation - in production, write to database fmt.Printf("Tool execution: %s by %s (%s) - %s\n", log.ToolName, log.UserID, log.TenantID, log.Status) }