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,025
Folders
377
Scanned Size
3.79 GB
PHP Files
791
Editable Text Files
12,309
File viewer
guarded to /htdocs
/api/search.php
<?php declare(strict_types=1); /** * /api/search.php — SIMON Web360 OpenAI Proxy (Responses API) * * Expects JSON: * { * "q": "prompt text", * "model": "gpt-4o-mini", * "temperature": 0.4, * "max_tokens": 2600, * "sys_instruction": "...optional...", * "api_key": "...optional, NOT recommended..." * } * * Returns JSON: * { "ok": true, "answer": "..." } */ header('Content-Type: application/json; charset=utf-8'); header('Cache-Control: no-store'); function out(int $code, array $payload): void { http_response_code($code); echo json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); exit; } function read_json(): array { $raw = file_get_contents('php://input') ?: ''; $data = json_decode($raw, true); if (!is_array($data)) return []; return $data; } function pick_api_key(array $in): string { // Prefer server-side key. Put this in a file OUTSIDE web root if possible. // Option A (recommended): environment variable $env = getenv('OPENAI_API_KEY'); if (is_string($env) && trim($env) !== '') return trim($env); // Option B: include a private config file (place in /htdocs/_inc/ and deny web access) $cfgPath = __DIR__ . '/../_inc/openai_key.php'; if (is_file($cfgPath)) { $k = (string) (require $cfgPath); if (trim($k) !== '') return trim($k); } // Option C: accept api_key from client (NOT recommended; exposed to browser/devtools) if (isset($in['api_key']) && is_string($in['api_key']) && trim($in['api_key']) !== '') { return trim($in['api_key']); } // Option D: Authorization header "Bearer sk-..." $hdr = $_SERVER['HTTP_AUTHORIZATION'] ?? ''; if (is_string($hdr) && preg_match('/Bearer\s+(.+)/i', $hdr, $m)) { $k = trim($m[1]); if ($k !== '') return $k; } return ''; } function curl_json(string $url, array $payload, string $apiKey): array { $ch = curl_init($url); $headers = [ 'Content-Type: application/json', 'Authorization: Bearer ' . $apiKey, ]; curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_HTTPHEADER => $headers, CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 8, CURLOPT_TIMEOUT => 30, ]); $body = curl_exec($ch); $err = curl_error($ch); $code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return [$code, $body, $err]; } /** * Responses API output can include multiple items. We extract assistant text safely. * Docs: POST https://api.openai.com/v1/responses supports `input`, `instructions`, `model`, etc. :contentReference[oaicite:0]{index=0} */ function extract_answer(array $resp): string { // Best effort: walk output -> message -> content -> output_text $out = $resp['output'] ?? null; if (is_array($out)) { $chunks = []; foreach ($out as $item) { if (!is_array($item)) continue; if (($item['type'] ?? '') !== 'message') continue; $content = $item['content'] ?? []; if (!is_array($content)) continue; foreach ($content as $c) { if (!is_array($c)) continue; if (($c['type'] ?? '') === 'output_text' && isset($c['text']) && is_string($c['text'])) { $chunks[] = $c['text']; } } } $text = trim(implode("\n", $chunks)); if ($text !== '') return $text; } // Fallbacks (some SDKs expose a convenience string) if (isset($resp['output_text']) && is_string($resp['output_text'])) return trim($resp['output_text']); if (isset($resp['text']) && is_string($resp['text'])) return trim($resp['text']); return ''; } $in = read_json(); $q = isset($in['q']) ? trim((string)$in['q']) : ''; if ($q === '') out(400, ['ok'=>false, 'error'=>'Missing q']); $apiKey = pick_api_key($in); if ($apiKey === '') out(401, ['ok'=>false, 'error'=>'No OpenAI API key on server. Set OPENAI_API_KEY or /_inc/openai_key.php']); $model = isset($in['model']) && is_string($in['model']) && trim($in['model']) !== '' ? trim($in['model']) : 'gpt-4o-mini'; $temp = 0.4; if (isset($in['temperature'])) { $temp = (float)$in['temperature']; if ($temp < 0) $temp = 0; if ($temp > 2) $temp = 2; } $maxOut = 2600; if (isset($in['max_tokens'])) { $maxOut = (int)$in['max_tokens']; if ($maxOut < 256) $maxOut = 256; if ($maxOut > 8192) $maxOut = 8192; } // Optional “system” instruction your UI passes $instr = ''; if (isset($in['sys_instruction']) && is_string($in['sys_instruction'])) { $instr = trim($in['sys_instruction']); } $payload = [ 'model' => $model, 'input' => $q, 'temperature' => $temp, 'max_output_tokens' => $maxOut, ]; if ($instr !== '') { $payload['instructions'] = $instr; } [$code, $body, $err] = curl_json('https://api.openai.com/v1/responses', $payload, $apiKey); if ($err) out(502, ['ok'=>false, 'error'=>'Proxy curl error: '.$err]); if ($code < 200 || $code >= 300) { // Try decode error payload, else return body snippet $j = json_decode((string)$body, true); $msg = $j['error']['message'] ?? $j['error'] ?? null; if (!is_string($msg) || $msg === '') $msg = substr((string)$body, 0, 1800); out($code, ['ok'=>false, 'error'=>$msg]); } $j = json_decode((string)$body, true); if (!is_array($j)) out(502, ['ok'=>false, 'error'=>'Bad JSON from OpenAI']); $answer = extract_answer($j); if ($answer === '') $answer = '[No text output returned]'; out(200, ['ok'=>true, 'answer'=>$answer, 'model'=>$model]);
Save file
Quick jump
open a path
Open