feat: Phase 2 — Intel Protocol + Iron Protocol

Arc Reactor v2.0:
- research handler: DDG search → async page fetch → trafilatura extraction → Claude synthesis
- tool_loop handler: multi-step agent loop (up to 200 iter) with web_search, fetch_url, jarvis_agents, jarvis_alerts, current_time tools
- llm handler: multi-provider router (Claude/Groq/Ollama)
- /jobs/recent endpoint for HUD polling
- Phase 1 handlers preserved (ping/echo/shell)

chat.php — Tier 0.9 Intel Protocol (before KB intent engine):
- Detects: research/investigate/deep-dive/look up/find out about → research job
- Detects: step-by-step/figure out/analyze and report → tool_loop job
- Returns arc_job ID in response for UI polling
- Depth modifiers: quick/standard/deep

index.html:
- INTEL tab in right panel tab bar
- Research result cards with expand/collapse, synthesis, sources, status
- Live polling (4s) when INTEL tab is active + active jobs present
- Auto-switches to INTEL tab when research is triggered from chat
- intelPrompt() pre-fills chat input for new research

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-11 04:16:29 +00:00
parent 7013a80428
commit 9ea43c852b
2 changed files with 219 additions and 0 deletions
+63
View File
@@ -1063,6 +1063,67 @@ if (!$reply && preg_match('/\b(news|headlines|latest|what.?s happening|current e
}
}
// ── Tier 0.9: Intel Protocol — research & tool_loop detection ────────────
$arcJobId = null;
// Detect "research X", "look up X", "deep dive X", "investigate X", "find out about X"
$intelPatterns = [
'/^(?:jarvis[,\s]+)?(?:research|investigate|deep[- ]dive|deep dive)\s+(.+)/i' => 'research',
'/^(?:jarvis[,\s]+)?(?:look\s+(?:up|into)|find\s+out\s+(?:about)?)\s+(.+)/i' => 'research',
'/^(?:jarvis[,\s]+)?(?:step[- ]by[- ]step|figure\s+out|analyze\s+and\s+report|work\s+through)\s+(.+)/i' => 'tool_loop',
'/^(?:jarvis[,\s]+)?(?:run\s+a\s+research\s+(?:job|task)\s+on)\s+(.+)/i' => 'research',
];
if (!$reply) {
foreach ($intelPatterns as $pattern => $jobType) {
if (preg_match($pattern, $message, $m)) {
$queryOrTask = trim($m[1]);
if (strlen($queryOrTask) < 3) break;
$depth = 'standard';
if (preg_match('/\b(?:quick|brief)\b/i', $message)) $depth = 'quick';
if (preg_match('/\b(?:deep|thorough|comprehensive|full)\b/i', $message)) $depth = 'deep';
$jobPayload = $jobType === 'research'
? ['query' => $queryOrTask, 'depth' => $depth, 'provider' => 'claude']
: ['task' => $queryOrTask, 'max_iterations' => 12, 'provider' => 'claude'];
// Submit to Arc Reactor
$arcCh = curl_init('http://127.0.0.1:7474/job');
curl_setopt_array($arcCh, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode([
'type' => $jobType,
'payload' => $jobPayload,
'priority' => 7,
'created_by' => 'chat:' . $sessionId,
]),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_TIMEOUT => 5,
CURLOPT_CONNECTTIMEOUT => 3,
]);
$arcRes = json_decode(curl_exec($arcCh), true);
curl_close($arcCh);
if (isset($arcRes['job_id'])) {
$arcJobId = $arcRes['job_id'];
if ($jobType === 'research') {
$depthLabel = strtoupper($depth);
$reply = "◈ INTEL PROTOCOL ACTIVATED — Running {$depthLabel} research on **{$queryOrTask}** (Job #{$arcJobId}). I'm searching sources, extracting content, and synthesizing a briefing now, {$userAddr}. Switch to the INTEL tab to watch live progress.";
} else {
$reply = "◈ IRON PROTOCOL ACTIVATED — Multi-step analysis initiated for **{$queryOrTask}** (Job #{$arcJobId}). I'll work through this systematically using available tools, {$userAddr}. Results will appear in the INTEL tab.";
}
$source = "arc:{$jobType}";
} else {
$reply = "Intel Protocol is offline, {$userAddr}. Arc Reactor may be unavailable — I'll try to answer directly.";
$source = 'arc:offline';
}
break;
}
}
}
// ── Tier 1: Intent Engine (instant, no LLM) ───────────────────────────────
if (!$reply) {
$matched = KBEngine::match($message);
@@ -1193,6 +1254,7 @@ if (!$reply) {
}
}
// ── Tier 2: Ollama local LLM (fast local fallback) ───────────────────────
if (!$reply && defined('OLLAMA_HOST') && OLLAMA_HOST) {
$ollamaHost = OLLAMA_HOST;
@@ -1413,4 +1475,5 @@ echo json_encode([
'source' => $source,
'session_id' => $sessionId,
'timestamp' => date('c'),
'arc_job' => $arcJobId,
]);