151 lines
8.1 KiB
PHP
151 lines
8.1 KiB
PHP
<?php
|
|
// ╔═══════════════════════════════════════════════════════════════════════════╗
|
|
// ║ WEVIA COGNITIVE OPUS 4.6 BOOTSTRAP — wires 118 advanced fns ║
|
|
// ║ Created 2026-04-21 — Opus session ║
|
|
// ║ Effect: makes self-correction, tool planning, ethical reasoning, etc. ║
|
|
// ║ available to wevia-master-api.php ║
|
|
// ║ ║
|
|
// ║ ROLLBACK: just delete this file — master-api uses @require_once ║
|
|
// ║ so absence is silently ignored, zero regression. ║
|
|
// ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
|
|
// Guard: idempotent (safe to include multiple times)
|
|
if (defined('WEVIA_COGNITIVE_OPUS46_BOOTSTRAPPED')) return;
|
|
define('WEVIA_COGNITIVE_OPUS46_BOOTSTRAPPED', 1);
|
|
|
|
// Wire core cognitive modules (silent if missing)
|
|
@require_once '/opt/wevia-brain/cognitive-opus46-advanced.php';
|
|
@require_once '/opt/wevia-brain/cognitive-opus46.php';
|
|
|
|
// Optional advanced modules (auto-load if present)
|
|
@require_once '/opt/wevia-brain/modules/chain-of-thought.php';
|
|
@require_once '/opt/wevia-brain/modules/opus-orchestrator.php';
|
|
@require_once '/opt/wevia-brain/modules/rag-engine.php';
|
|
@require_once '/opt/wevia-brain/modules/tool-use-engine.php';
|
|
|
|
// Load Opus master system prompt (10KB master directives)
|
|
$GLOBALS['OPUS46_SYSTEM_PROMPT'] = @file_get_contents('/opt/wevia-brain/prompts/opus-master-system.md') ?: '';
|
|
|
|
// Load master directives
|
|
$_dir_json = @file_get_contents('/opt/wevia-brain/master-directives.json');
|
|
$GLOBALS['OPUS46_MASTER_DIRECTIVES'] = $_dir_json ? @json_decode($_dir_json, true) : [];
|
|
|
|
// Status flags accessible by other modules
|
|
$GLOBALS['OPUS46_LOADED'] = function_exists('selfCorrectionShouldActivate');
|
|
$GLOBALS['OPUS46_FNS_AVAILABLE'] = [
|
|
'self_correction' => function_exists('selfCorrectionPipeline'),
|
|
'tool_planning' => function_exists('selectBestGPUModel'),
|
|
'ollama_inventory' => function_exists('getOllamaModelInventory'),
|
|
'detect_hallucination' => function_exists('detectHallucinatedNumbers'),
|
|
'detect_contradiction' => function_exists('detectLogicalContradiction'),
|
|
'detect_truncation' => function_exists('detectTruncatedResponse'),
|
|
];
|
|
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
// SELF-CORRECTION HELPER (V94 extension — added 2026-04-21)
|
|
// Usage: wevia_self_correct_response($data, $msg, $intent)
|
|
// Returns corrected data or original if no correction needed/safe
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
if (!function_exists('wevia_self_correct_response')) {
|
|
function wevia_self_correct_response($data, $msg = '', $intent = 'generic') {
|
|
// Safety: must be loaded + array
|
|
if (empty($GLOBALS['OPUS46_LOADED'])) return $data;
|
|
if (!is_array($data)) return $data;
|
|
if (!function_exists('selfCorrectionPipeline') || !function_exists('selfCorrectionShouldActivate')) return $data;
|
|
|
|
// Find response text (common keys)
|
|
$resp_key = null;
|
|
foreach (['response', 'content', 'output', 'text', 'message'] as $k) {
|
|
if (isset($data[$k]) && is_string($data[$k])) { $resp_key = $k; break; }
|
|
}
|
|
if (!$resp_key) return $data;
|
|
$resp = $data[$resp_key];
|
|
|
|
// Skip if too short or greeting/conversational
|
|
if (mb_strlen($resp) < 200) return $data;
|
|
if (!selfCorrectionShouldActivate($resp, $intent)) return $data;
|
|
|
|
// Run pipeline with strict error containment
|
|
try {
|
|
$corrected = @selfCorrectionPipeline($resp, $msg, $intent);
|
|
if ($corrected && is_string($corrected) && $corrected !== $resp && mb_strlen($corrected) >= mb_strlen($resp) * 0.5) {
|
|
$data[$resp_key] = $corrected;
|
|
$data['_self_correction_applied'] = true;
|
|
$data['_self_correction_delta'] = mb_strlen($corrected) - mb_strlen($resp);
|
|
}
|
|
} catch (\Throwable $e) {
|
|
// Silent fail — never break the response
|
|
$data['_self_correction_error'] = 'pipeline_throw';
|
|
}
|
|
return $data;
|
|
}
|
|
}
|
|
|
|
// Light diagnostic: detect issues without modifying (log only)
|
|
if (!function_exists('wevia_diag_response')) {
|
|
function wevia_diag_response($response_text) {
|
|
$issues = [];
|
|
if (!is_string($response_text) || mb_strlen($response_text) < 50) return $issues;
|
|
|
|
try {
|
|
if (function_exists('detectTruncatedResponse') && @detectTruncatedResponse($response_text)) $issues[] = 'truncated';
|
|
if (function_exists('detectLogicalContradiction')) {
|
|
$c = @detectLogicalContradiction($response_text);
|
|
if (!empty($c)) $issues[] = 'contradiction';
|
|
}
|
|
if (function_exists('detectExcessiveRepetition') && @detectExcessiveRepetition($response_text)) $issues[] = 'repetition';
|
|
} catch (\Throwable $e) {
|
|
return ['diag_error'];
|
|
}
|
|
return $issues;
|
|
}
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
// AUTO-HOOK: Apply self-correction on JSON responses (V94)
|
|
// Only active if OPUS46_LOADED and output is JSON (not SSE).
|
|
// Ultra-safe: any error → pass through original buffer unchanged.
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
if (!defined('WEVIA_OPUS46_OBHOOK_INSTALLED')) {
|
|
define('WEVIA_OPUS46_OBHOOK_INSTALLED', 1);
|
|
@ob_start(function($buffer) {
|
|
try {
|
|
if (empty($GLOBALS['OPUS46_LOADED'])) return $buffer;
|
|
if (empty($buffer) || strlen($buffer) < 50) return $buffer;
|
|
|
|
// Skip SSE (content-type or data: prefix)
|
|
$hdrs = function_exists('headers_list') ? headers_list() : [];
|
|
foreach ($hdrs as $h) {
|
|
if (stripos($h, 'text/event-stream') !== false) return $buffer;
|
|
if (stripos($h, 'text/html') !== false) return $buffer;
|
|
if (stripos($h, 'text/plain') !== false) return $buffer;
|
|
}
|
|
if (strncmp(trim($buffer), 'data:', 5) === 0) return $buffer;
|
|
|
|
// Must be valid JSON object
|
|
$trimmed = ltrim($buffer);
|
|
if (substr($trimmed, 0, 1) !== '{') return $buffer;
|
|
|
|
$data = @json_decode($buffer, true);
|
|
if (!is_array($data)) return $buffer;
|
|
|
|
// Extract message for context
|
|
$msg = '';
|
|
if (!empty($_SERVER['HTTP_X_USER_MSG'])) $msg = $_SERVER['HTTP_X_USER_MSG'];
|
|
elseif (!empty($data['input_message'])) $msg = $data['input_message'];
|
|
$intent = $data['intent'] ?? 'generic';
|
|
|
|
// Apply correction via helper (has its own safety)
|
|
if (function_exists('wevia_self_correct_response')) {
|
|
$corrected = wevia_self_correct_response($data, $msg, $intent);
|
|
if (!empty($corrected['_self_correction_applied'])) {
|
|
return json_encode($corrected, JSON_UNESCAPED_UNICODE);
|
|
}
|
|
}
|
|
return $buffer;
|
|
} catch (\Throwable $e) {
|
|
return $buffer; // Never break the response
|
|
}
|
|
});
|
|
}
|