['name' => 'GPTBot', 'company' => 'OpenAI', 'type' => 'crawler', 'category' => 'llm'], 'chatgpt-user' => ['name' => 'ChatGPT-User', 'company' => 'OpenAI', 'type' => 'agent', 'category' => 'llm'], 'oai-searchbot' => ['name' => 'OAI-SearchBot', 'company' => 'OpenAI', 'type' => 'crawler', 'category' => 'search'], 'openai' => ['name' => 'OpenAI', 'company' => 'OpenAI', 'type' => 'agent', 'category' => 'llm'], // Anthropic 'claudebot' => ['name' => 'ClaudeBot', 'company' => 'Anthropic', 'type' => 'crawler', 'category' => 'llm'], 'claude-user' => ['name' => 'Claude-User', 'company' => 'Anthropic', 'type' => 'agent', 'category' => 'llm'], // ← add this 'claude-web' => ['name' => 'Claude-Web', 'company' => 'Anthropic', 'type' => 'crawler', 'category' => 'llm'], 'anthropic-ai' => ['name' => 'Anthropic-AI', 'company' => 'Anthropic', 'type' => 'crawler', 'category' => 'llm'], // Google 'google-extended' => ['name' => 'Google-Extended', 'company' => 'Google', 'type' => 'crawler', 'category' => 'llm'], 'googleother' => ['name' => 'GoogleOther', 'company' => 'Google', 'type' => 'crawler', 'category' => 'llm'], 'google-cloudvertexbot' => ['name' => 'Google-CloudVertexBot', 'company' => 'Google', 'type' => 'crawler', 'category' => 'embedding'], // Perplexity 'perplexitybot' => ['name' => 'PerplexityBot', 'company' => 'Perplexity', 'type' => 'crawler', 'category' => 'search'], // Microsoft 'bingbot' => ['name' => 'BingBot', 'company' => 'Microsoft', 'type' => 'crawler', 'category' => 'search'], 'bingpreview' => ['name' => 'BingPreview', 'company' => 'Microsoft', 'type' => 'preview', 'category' => 'search'], // Meta 'meta-externalagent' => ['name' => 'Meta-ExternalAgent', 'company' => 'Meta', 'type' => 'crawler', 'category' => 'llm'], 'meta-externalfetcher' => ['name' => 'Meta-ExternalFetcher', 'company' => 'Meta', 'type' => 'crawler', 'category' => 'llm'], 'meta-webindexer' => ['name' => 'Meta-WebIndexer', 'company' => 'Meta', 'type' => 'agent', 'category' => 'llm'], 'facebookbot' => ['name' => 'FacebookBot', 'company' => 'Meta', 'type' => 'crawler', 'category' => 'embedding'], // Apple 'applebot-extended' => ['name' => 'AppleBot-Extended', 'company' => 'Apple', 'type' => 'crawler', 'category' => 'llm'], 'applebot' => ['name' => 'AppleBot', 'company' => 'Apple', 'type' => 'crawler', 'category' => 'search'], // Amazon 'amazonbot' => ['name' => 'AmazonBot', 'company' => 'Amazon', 'type' => 'crawler', 'category' => 'search'], // Cohere 'cohere-ai' => ['name' => 'Cohere-AI', 'company' => 'Cohere', 'type' => 'crawler', 'category' => 'llm'], // AI21 'ai2bot' => ['name' => 'AI2Bot', 'company' => 'AI21', 'type' => 'crawler', 'category' => 'llm'], // Common Crawl 'ccbot' => ['name' => 'CCBot', 'company' => 'Common Crawl', 'type' => 'crawler', 'category' => 'embedding'], // ByteDance 'bytespider' => ['name' => 'ByteSpider', 'company' => 'ByteDance', 'type' => 'crawler', 'category' => 'llm'], // Diffbot 'diffbot' => ['name' => 'Diffbot', 'company' => 'Diffbot', 'type' => 'crawler', 'category' => 'embedding'], // You.com 'youbot' => ['name' => 'YouBot', 'company' => 'You.com', 'type' => 'crawler', 'category' => 'search'], ]; public function detect($user_agent) { $signals = []; $ua_lower = strtolower($user_agent); // Only detect known AI agents foreach ($this->ai_bot_signatures as $signature => $agent) { if (strpos($ua_lower, $signature) !== false) { $signals[] = "ua_match:{$signature}"; return [ 'is_ai_agent' => true, 'agent' => $agent, 'confidence' => 'high', 'signals' => $signals, ]; } } // Not a known AI agent return [ 'is_ai_agent' => false, 'agent' => null, 'confidence' => 'high', 'signals' => $signals, ]; } public function is_ai_agent($user_agent) { $ua_lower = strtolower($user_agent); foreach ($this->ai_bot_signatures as $signature => $agent) { if (strpos($ua_lower, $signature) !== false) { return true; } } return false; } public function get_known_agents() { return $this->ai_bot_signatures; } public function add_signature($signature, $agent) { $this->ai_bot_signatures[strtolower($signature)] = $agent; } }