SIMON Master Console Rebuild
True command center for SIMON + WEB360
This rebuild gives you a cleaner production spine: interactive tree, live viewer, guarded editor, dynamic graphics, architecture map, and note storage. It is designed to sit beside your existing
console.php
and become the stronger replacement path.
Dashboard
Tree
Viewer
System Map
File Registry
Notes
Files
15,310
Folders
408
Scanned Size
3.84 GB
PHP Files
891
Editable Text Files
12,571
File viewer
guarded to /htdocs
/web360/Demo/engine/AIRouter.php
<?php require_once __DIR__ . '/../core/bootstrap.php'; final class AIRouter { public static function providers(): array { $defaults = [ 'freeai' => ['enabled'=>true,'label'=>'Free AI Local','type'=>'local','endpoint'=>'','api_key'=>'','api_key_env'=>'','model'=>'local-simon-scaffold'], 'openai' => ['enabled'=>false,'label'=>'OpenAI','type'=>'openai','endpoint'=>'https://api.openai.com/v1/chat/completions','api_key'=>'','api_key_env'=>'OPENAI_API_KEY','model'=>'gpt-4o-mini'], 'anthropic' => ['enabled'=>false,'label'=>'Claude','type'=>'anthropic','endpoint'=>'https://api.anthropic.com/v1/messages','api_key'=>'','api_key_env'=>'ANTHROPIC_API_KEY','model'=>'claude-3-5-sonnet-latest'], 'gemini' => ['enabled'=>false,'label'=>'Gemini','type'=>'gemini','endpoint'=>'https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent','api_key'=>'','api_key_env'=>'GEMINI_API_KEY','model'=>'gemini-1.5-flash'], 'grok' => ['enabled'=>false,'label'=>'Grok / xAI','type'=>'openai','endpoint'=>'https://api.x.ai/v1/chat/completions','api_key'=>'','api_key_env'=>'XAI_API_KEY','model'=>'grok-2-latest'], 'deepseek' => ['enabled'=>false,'label'=>'DeepSeek','type'=>'openai','endpoint'=>'https://api.deepseek.com/chat/completions','api_key'=>'','api_key_env'=>'DEEPSEEK_API_KEY','model'=>'deepseek-chat'], 'mistral' => ['enabled'=>false,'label'=>'Mistral','type'=>'openai','endpoint'=>'https://api.mistral.ai/v1/chat/completions','api_key'=>'','api_key_env'=>'MISTRAL_API_KEY','model'=>'mistral-large-latest'], 'openrouter' => ['enabled'=>false,'label'=>'OpenRouter','type'=>'openai','endpoint'=>'https://openrouter.ai/api/v1/chat/completions','api_key'=>'','api_key_env'=>'OPENROUTER_API_KEY','model'=>'openai/gpt-4o-mini'], 'ollama' => ['enabled'=>false,'label'=>'Ollama Local','type'=>'ollama','endpoint'=>'http://127.0.0.1:11434/api/generate','api_key'=>'','api_key_env'=>'','model'=>'llama3.1'], 'lmstudio' => ['enabled'=>false,'label'=>'LM Studio','type'=>'openai','endpoint'=>'http://127.0.0.1:1234/v1/chat/completions','api_key'=>'local','api_key_env'=>'','model'=>'local-model'], 'custom' => ['enabled'=>false,'label'=>'Custom OpenAI-Compatible','type'=>'openai','endpoint'=>'','api_key'=>'','api_key_env'=>'CUSTOM_AI_API_KEY','model'=>'custom-model'] ]; return array_replace_recursive($defaults, w360_read_json('providers', [])); } public static function save(array $providers): bool { return w360_write_json('providers', $providers); } public static function choose(string $jobType, string $requested = 'auto'): string { $providers = self::providers(); if ($requested !== 'auto' && !empty($providers[$requested]['enabled'])) return $requested; $order = [ 'code' => ['openai','deepseek','anthropic','openrouter','freeai'], 'debug' => ['openai','anthropic','deepseek','freeai'], 'design' => ['openai','gemini','anthropic','freeai'], 'seo' => ['gemini','openai','anthropic','freeai'], 'security' => ['anthropic','openai','deepseek','freeai'], 'vision' => ['openai','gemini','freeai'], 'voice' => ['openai','freeai'], 'general' => ['freeai','openai','anthropic','gemini'] ]; foreach (($order[$jobType] ?? $order['general']) as $id) { if (!empty($providers[$id]['enabled'])) return $id; } return 'freeai'; } public static function call(string $providerId, string $prompt, array $opts = []): array { $providers = self::providers(); $cfg = $providers[$providerId] ?? $providers['freeai']; if (($cfg['type'] ?? 'local') === 'local') { return ['ok'=>true,'provider'=>'freeai','text'=>self::local($prompt, $opts)]; } if (!function_exists('curl_init')) { return ['ok'=>false,'provider'=>$providerId,'error'=>'PHP cURL is missing']; } $key = getenv($cfg['api_key_env'] ?? '') ?: ($cfg['api_key'] ?? ''); if (($cfg['type'] ?? '') !== 'ollama' && $key === '') { return ['ok'=>false,'provider'=>$providerId,'error'=>'Missing API key for '.$providerId]; } if (($cfg['type'] ?? '') === 'anthropic') return self::anthropic($providerId, $cfg, $key, $prompt); if (($cfg['type'] ?? '') === 'gemini') return self::gemini($providerId, $cfg, $key, $prompt); if (($cfg['type'] ?? '') === 'ollama') return self::ollama($providerId, $cfg, $prompt); return self::openaiCompatible($providerId, $cfg, $key, $prompt); } private static function post(string $url, array $headers, array $body): array { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => $headers, CURLOPT_POSTFIELDS => json_encode($body), CURLOPT_TIMEOUT => 120 ]); $raw = curl_exec($ch); $err = curl_error($ch); $code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); $json = json_decode((string)$raw, true); return ['ok'=>$code >= 200 && $code < 300, 'http_code'=>$code, 'json'=>is_array($json)?$json:null, 'raw'=>$raw, 'error'=>$err]; } private static function openaiCompatible(string $id, array $cfg, string $key, string $prompt): array { $r = self::post($cfg['endpoint'], ['Content-Type: application/json','Authorization: Bearer '.$key], [ 'model'=>$cfg['model'], 'messages'=>[ ['role'=>'system','content'=>'You are WEB360 Professional SIMON AI. Return direct production-ready output.'], ['role'=>'user','content'=>$prompt] ], 'temperature'=>0.2 ]); return ['ok'=>$r['ok'], 'provider'=>$id, 'text'=>$r['json']['choices'][0]['message']['content'] ?? '', 'raw'=>$r]; } private static function anthropic(string $id, array $cfg, string $key, string $prompt): array { $r = self::post($cfg['endpoint'], ['Content-Type: application/json','x-api-key: '.$key,'anthropic-version: 2023-06-01'], [ 'model'=>$cfg['model'], 'max_tokens'=>4096, 'system'=>'You are WEB360 Professional SIMON AI.', 'messages'=>[['role'=>'user','content'=>$prompt]] ]); return ['ok'=>$r['ok'], 'provider'=>$id, 'text'=>$r['json']['content'][0]['text'] ?? '', 'raw'=>$r]; } private static function gemini(string $id, array $cfg, string $key, string $prompt): array { $url = str_replace('{model}', rawurlencode($cfg['model']), $cfg['endpoint']) . '?key=' . rawurlencode($key); $r = self::post($url, ['Content-Type: application/json'], [ 'contents'=>[['parts'=>[['text'=>$prompt]]]], 'generationConfig'=>['temperature'=>0.2] ]); return ['ok'=>$r['ok'], 'provider'=>$id, 'text'=>$r['json']['candidates'][0]['content']['parts'][0]['text'] ?? '', 'raw'=>$r]; } private static function ollama(string $id, array $cfg, string $prompt): array { $r = self::post($cfg['endpoint'], ['Content-Type: application/json'], [ 'model'=>$cfg['model'], 'prompt'=>$prompt, 'stream'=>false ]); return ['ok'=>$r['ok'], 'provider'=>$id, 'text'=>$r['json']['response'] ?? '', 'raw'=>$r]; } private static function local(string $prompt, array $opts = []): string { $lower = strtolower($prompt); if (w360_contains($lower, 'white screen')) { return "SIMON diagnosis: white screen usually means the iframe target returned HTTP 500, blocked headers, fatal PHP syntax, or the target is rendering outside the iframe. Use Viewer Pro's status check, run Diagnostics, then open the same file directly. If PHP lint fails, restore a checkpoint and repair the first fatal line."; } if (w360_contains($lower, 'canvas')) { return "SIMON canvas read: screenshot/canvas capture was received. Current local mode can store and describe the capture metadata. Enable OpenAI or Gemini vision support for true image interpretation."; } if (w360_contains($lower, 'php') || w360_contains($lower, 'code')) { return "SIMON Free AI code mode: I can scaffold, explain, and patch locally. For deep code rewrite, enable OpenAI, Claude, DeepSeek, or OpenRouter in AI Engines. Request received:\n\n".$prompt; } return "SIMON Free AI: ".$prompt."\n\nProvider keys unlock advanced reasoning, voice jobs, canvas analysis, and code review."; } }
Save file
Quick jump
open a path
Open