'array', 'result_summary' => 'array', 'success' => 'boolean', 'duration_ms' => 'integer', ]; // Relationships public function workspace(): BelongsTo { return $this->belongsTo(Workspace::class); } // Scopes public function scopeForServer(Builder $query, string $serverId): Builder { return $query->where('server_id', $serverId); } public function scopeForTool(Builder $query, string $toolName): Builder { return $query->where('tool_name', $toolName); } public function scopeSuccessful(Builder $query): Builder { return $query->where('success', true); } public function scopeFailed(Builder $query): Builder { return $query->where('success', false); } public function scopeRecent(Builder $query, int $hours = 24): Builder { return $query->where('created_at', '>=', now()->subHours($hours)); } public function scopeToday(Builder $query): Builder { return $query->whereDate('created_at', today()); } public function scopeThisWeek(Builder $query): Builder { return $query->where('created_at', '>=', now()->startOfWeek()); } /** * Log a tool call and update daily stats. */ public static function log( string $serverId, string $toolName, array $params = [], bool $success = true, ?int $durationMs = null, ?string $errorMessage = null, ?string $errorCode = null, ?array $resultSummary = null, ?string $sessionId = null, ?string $agentType = null, ?string $planSlug = null, ?int $workspaceId = null ): self { $call = static::create([ 'workspace_id' => $workspaceId, 'server_id' => $serverId, 'tool_name' => $toolName, 'input_params' => $params, 'success' => $success, 'duration_ms' => $durationMs, 'error_message' => $errorMessage, 'error_code' => $errorCode, 'result_summary' => $resultSummary, 'session_id' => $sessionId, 'agent_type' => $agentType, 'plan_slug' => $planSlug, ]); // Update daily stats McpToolCallStat::incrementForCall($call); return $call; } // Helpers public function getDurationForHumans(): string { if (! $this->duration_ms) { return '-'; } if ($this->duration_ms < 1000) { return $this->duration_ms.'ms'; } return round($this->duration_ms / 1000, 2).'s'; } public function getStatusBadge(): string { return $this->success ? 'Success' : 'Failed'; } }