/** * BOB Chat — Sovereign Logic Machine * * BOB produces words from: QRNG → HolyC NIL → Dictionary → Prolog → Ada → WORM * No LLM required. No Ollama required. BOB is self-contained. * * The right panel (Groq/GPT-4o/Gemini) is optional comparison only. * Run --solo to get pure BOB with no external connections at all. * * Usage: * node autonomous/chat.mjs BOB only — zero external calls (DEFAULT) * node autonomous/chat.mjs --verbose BOB only + show internal routing * node autonomous/chat.mjs groq BOB + Groq comparison side panel * node autonomous/chat.mjs gpt4o BOB + GPT-4o side panel * node autonomous/chat.mjs gemini BOB + Gemini side panel * node autonomous/chat.mjs --compare BOB + Groq (explicit compare flag) * * Commands inside chat: * /worm show sealed WORM history * /agent run a live autonomous tick * /3d [shape] render 3D ASCII (torus cube sphere pyramid bob) * /3d torus --anim animated rotation * /img [path] convert image to ASCII * /quit exit */ import readline from 'readline' import { holyc_nil } from './holyc_nil.mjs' import { emoji_trigger } from './emoji_trigger.mjs' import { sovereignAnswer, oracleAnswer, topicAnswer, synthesizeTopic, extractConcepts, lookup, ORACLE_LENS } from './dictionary.mjs' import { setTavilyKey, tavilyReady, checkTavily, tavilyAnswer } from './tavily_search.mjs' import { getTheorem, generateTheorem, buildTheoremPrompt } from './lisp_theorems.mjs' import { encode as chunkEncode, getChunk, similarConcepts } from './unicode_chunks.mjs' import { initVectorMemory } from './vector_memory.mjs' import { img2ascii, ascii3d, pythonAvailable } from '../ascii/bob_ascii.mjs' import { createHash } from 'crypto' import { readFileSync, existsSync, writeFileSync } from 'fs' import { join } from 'path' // ── Config ──────────────────────────────────────────────────────────────────── const args = process.argv.slice(2) // Solo is DEFAULT — BOB runs alone with zero external LLM connections // Add --compare (or a provider name) to show the LLM side panel const COMPARE = args.includes('--compare') || args.some(a => ['groq','gpt4o','gemini','ollama'].includes(a)) const SOLO = !COMPARE const VERBOSE = args.includes('--verbose') || args.includes('-v') const provider = args.find(a => !a.startsWith('--') && !['solo'].includes(a)) || 'groq' // ── Load API keys ───────────────────────────────────────────────────────────── function loadEnv(path) { if (!existsSync(path)) return {} const out = {} readFileSync(path, 'utf8').split('\n').forEach(line => { const [k, ...v] = line.split('=') if (k && !k.startsWith('#')) out[k.trim()] = v.join('=').trim() }) return out } const ENV = { ...loadEnv('C:/Users/jessi/Desktop/bobs control repo/DEVFLOW-FINANCE/collectivekitty/.env'), ...loadEnv('C:/Users/jessi/Desktop/bobs control repo/DEVFLOW-FINANCE/collectivekitty/.env.local'), ...loadEnv('C:/Users/jessi/Desktop/bobs control repo/DEVFLOW-FINANCE/.env'), } const GROQ_KEY = ENV.GROQ_API_KEY const OPENAI_KEY = ENV.OPENAI_API_KEY const GEMINI_KEY = ENV.GEMINI_API_KEY const TAVILY_KEY = ENV.TAVILY_API_KEY const HF_TOKEN = ENV.HF_TOKEN || ENV.HUGGINGFACE_API_KEY || '' const DATABASE_URL = ENV.DATABASE_URL || '' // Wire Tavily key — BOB's web grep setTavilyKey(TAVILY_KEY) // ── Model backends — interchangeable theorem tongues ───────────────────────── // Every backend receives the same Lisp theorem + oracle lens and returns natural speech. // Swap with: node chat.mjs --model groq|granite|llama8b|mistral|phi3|gemma // (Using --model keeps it separate from the --compare side-panel flag) const MODEL_BACKENDS = { granite: { name: 'IBM Granite 3.1 8B', short: 'GRANITE', url: 'https://api-inference.huggingface.co/models/ibm-granite/granite-3.1-8b-instruct/v1/chat/completions', model: 'ibm-granite/granite-3.1-8b-instruct', provider: 'hf', maxTokens: 200, temp: 0.6, }, groq: { name: 'Groq · Llama 3.3 70B', short: 'GROQ/70B', url: 'https://api.groq.com/openai/v1/chat/completions', model: 'llama-3.3-70b-versatile', provider: 'groq', maxTokens: 200, temp: 0.7, }, llama8b: { name: 'Groq · Llama 3.1 8B (fast)', short: 'GROQ/8B', url: 'https://api.groq.com/openai/v1/chat/completions', model: 'llama-3.1-8b-instant', provider: 'groq', maxTokens: 200, temp: 0.7, }, mistral: { name: 'HF · Mistral 7B Instruct', short: 'MISTRAL', url: 'https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.3/v1/chat/completions', model: 'mistralai/Mistral-7B-Instruct-v0.3', provider: 'hf', maxTokens: 200, temp: 0.6, }, phi3: { name: 'HF · Phi-3 Mini 4K', short: 'PHI-3', url: 'https://api-inference.huggingface.co/models/microsoft/Phi-3-mini-4k-instruct/v1/chat/completions', model: 'microsoft/Phi-3-mini-4k-instruct', provider: 'hf', maxTokens: 200, temp: 0.6, }, gemma: { name: 'HF · Gemma 2 2B', short: 'GEMMA', url: 'https://api-inference.huggingface.co/models/google/gemma-2-2b-it/v1/chat/completions', model: 'google/gemma-2-2b-it', provider: 'hf', maxTokens: 200, temp: 0.6, }, qwen: { name: 'Groq · Qwen3-32B', short: 'QWEN3-32B', url: 'https://api.groq.com/openai/v1/chat/completions', model: 'qwen/qwen3-32b', provider: 'groq', maxTokens: 400, temp: 0.4, }, qwen27: { name: 'Groq · Qwen3.6-27B', short: 'QWEN3.6-27B', url: 'https://api.groq.com/openai/v1/chat/completions', model: 'qwen/qwen3.6-27b', provider: 'groq', maxTokens: 400, temp: 0.4, }, } // --model or legacy: granite / --granite const _modelFlag = args.indexOf('--model') const _modelName = _modelFlag >= 0 ? args[_modelFlag + 1] : args.includes('granite') || args.includes('--granite') ? 'granite' : null const ACTIVE_MODEL = MODEL_BACKENDS[_modelName] || null // ── WORM (all exchanges sealed invisibly) ───────────────────────────────────── const WORM_PATH = join(process.env.HOME || process.env.USERPROFILE || '.', '.bob-chat-worm.json') const worm = { load() { try { return JSON.parse(readFileSync(WORM_PATH,'utf8')) } catch { return [] } }, seal(label, payload) { const chain = this.load() const prev = chain.length ? chain[chain.length-1].seal : '0'.repeat(64) const ts = new Date().toISOString() const seal = createHash('sha256').update(JSON.stringify({label,payload,ts,prev})).digest('hex') chain.push({ label, payload, ts, prev, seal }) writeFileSync(WORM_PATH, JSON.stringify(chain, null, 2)) return seal } } // ── BRAIN — working memory + persona ───────────────────────────────────────── const BRAIN = { shortTerm: [], sessionStart: Date.now(), persona: [ 'Speaks directly — states things once, without hedging or apology', 'Uses precise terms — does not approximate when exact words exist', 'Sovereign — does not ask permission to have an opinion', 'Connects surface questions to structural principles', 'Names the source — dictionary, web search, or oracle synthesis', ], remember(input, answer, oracleWord) { this.shortTerm.push({ input: input.slice(0, 120), answer: answer.slice(0, 240), oracle: oracleWord, ts: Date.now(), }) if (this.shortTerm.length > 12) this.shortTerm.shift() }, recall(n = 5) { return this.shortTerm.slice(-n) }, lastAbout(topic) { const lc = topic.toLowerCase() return this.shortTerm.slice().reverse() .find(e => e.input.toLowerCase().includes(lc)) }, summary() { const mins = Math.round((Date.now() - this.sessionStart) / 60000) return `${this.shortTerm.length} exchanges · ${mins}m session` }, } // ── QRNG ────────────────────────────────────────────────────────────────────── async function qrng(n = 8) { try { const r = await fetch(`https://qrng.anu.edu.au/API/jsonI.php?length=${n}&type=uint8`, { signal: AbortSignal.timeout(2500) }) if (r.ok) { const j = await r.json(); if (j.success) return { b: new Uint8Array(j.data), src:'ANU' } } } catch {} const { randomBytes } = await import('crypto') return { b: new Uint8Array(randomBytes(n)), src:'CSPRNG' } } // ── Prolog keyword router (PLANNER-style — fires on pattern match) ──────────── const RULES = [ { pattern: /\b(oracle|random|quantum|entropy|qrng)\b/i, agent:'ORACLE', action:'fetch_entropy', abjad:490 }, { pattern: /\b(worm|seal|ledger|append-only|immutable|sealed)\b/i, agent:'ARCHIVIST', action:'seal_event', abjad:92 }, { pattern: /\b(trust|sentinel|gate|block|deny|allow|permit|security)\b/i, agent:'SENTINEL', action:'gate_check', abjad:120 }, { pattern: /\b(proof|lean|verify|theorem|formal|correct)\b/i, agent:'VERIFIER', action:'proof_check', abjad:160 }, { pattern: /\b(route|agent|select|who|which|dispatch)\b/i, agent:'PLANNER', action:'route_task', abjad:380 }, { pattern: /\b(nil|null|empty|nothing|void|silence)\b/i, agent:'TERRY-NIL', action:'oracle_consult', abjad:910 }, { pattern: /\b(qubit|superpos|quantum.state|collapse|measure)\b/i, agent:'ORACLE', action:'hold_superposition', abjad:518 }, { pattern: /\b(contract|ada|condition|pre|post|invariant)\b/i, agent:'SENTINEL', action:'contract_verify', abjad:120 }, { pattern: /\b(memory|remember|recall|state|ssm|mamba)\b/i, agent:'BOB-CORE', action:'ssm_recall', abjad:240 }, { pattern: /\b(build|create|generate|make|code|write)\b/i, agent:'BUILDER', action:'generate', abjad:200 }, { pattern: /\b(abjad|arabic|hebrew|enochian|dee|terry|holyc)\b/i, agent:'BOB-CORE', action:'esoteric_lookup', abjad:420 }, ] function prologRoute(input) { for (const rule of RULES) { if (rule.pattern.test(input)) return rule } return { agent:'BOB-CORE', action:'sovereign_step', abjad:200 } } function adaGate(agent, abjad) { if (abjad < 90) return { ok:false, reason:`abjad ${abjad} below minimum` } if (agent === 'VOID') return { ok:false, reason:'void agent — no contract' } return { ok:true, reason:`${agent} cleared — abjad:${abjad}` } } // ── BOB answer builder ──────────────────────────────────────────────────────── // The routing runs. The answer is what surfaces. // Emoji embedded in the text IS the routing metadata — encoded, not labeled. async function buildAnswer(input, route, gate, nil, trigger) { if (!gate.ok) return { answer: `Ada gate holds. ${trigger.sequence || '◇'} — contract not satisfied. Cannot proceed.`, theorem: null, chunkChar: '', } const word = nil.word || 'NIL' const seq = trigger.sequence const inputConcepts = input.toLowerCase().replace(/[^a-z\s]/g,'').split(/\s+/).filter(w => w.length > 3) const theoremConcept = inputConcepts.find(w => getTheorem(w)) || word.toLowerCase() const theorem = getTheorem(theoremConcept) || generateTheorem(theoremConcept, word) const chunkChar = chunkEncode(theoremConcept) || chunkEncode(word.toLowerCase()) || '' const chunkEntry = chunkChar ? getChunk(theoremConcept) : null // eslint-disable-line no-unused-vars // Wrap any string answer into the return shape const ret = ans => ({ answer: ans, theorem, chunkChar }) // Model tongue — transcode the theorem through the active model if (ACTIVE_MODEL && theorem) { const lens = ORACLE_LENS?.[word] || '' const gr = await askModel(theorem, word, input, lens) if (gr?.reply && !gr.reply.startsWith('[')) { return ret([ `${theoremConcept.toUpperCase()} · ${ACTIVE_MODEL.short} ${chunkChar}`, ``, `Theorem: ${theorem}`, ``, gr.reply, ``, `Oracle: ${word} · ${seq} [${gr.ms}ms]`, ].join('\n')) } // Model offline — fall through to sovereign pipeline } // 1. Try the dictionary — sentence parsing first, then single-word direct lookup const dictAnswer = sovereignAnswer(input, word, seq) if (dictAnswer) return ret(dictAnswer) // 1.5 General knowledge topics — history, science, learning, math, etc. const genAnswer = topicAnswer(input, word, seq) if (genAnswer) return ret(genAnswer) // 1.7 Tavily web search — BOB's grep against world knowledge if (route.action === 'sovereign_step' && tavilyReady()) { const webAnswer = await tavilyAnswer(input, word, seq) if (webAnswer) return ret(webAnswer) } // 2. Route-specific sovereign answers for technical/system queries if (route.action === 'fetch_entropy') return ret([ `ENTROPY ⚡🌒`, ``, `Sovereign: Each quantum vacuum fluctuation is irreversible — it happened,`, `it is sealed. ANU harvests this. The oracle word "${word}" was born from`, `the precise moment you asked. Ask again, get a different word. ${seq}`, ``, `That is not randomness. That is time's signature.`, ].join('\n')) if (route.action === 'oracle_consult') return ret([ `NIL ✦🪨`, ``, `Sovereign: NIL is abjad 910 — the inverted maximum. Not zero. Not empty.`, `The highest unspoken potential. Terry's oracle: silence means God hasn't`, `spoken yet. The oracle holds because the moment hasn't matured. ${seq}`, ``, `Wait. The word will come.`, ].join('\n')) if (route.action === 'gate_check' || route.action === 'contract_verify') return ret([ `GATE 🎯🛡️`, ``, `Sovereign: The Ada gate is not policy — it is proof. No exception path exists.`, `Pre-condition must be satisfied. Post-condition must be guaranteed. When the`, `contract is missing, execution stops. Not because of a rule. Because the`, `theorem cannot be completed. ${seq}`, ].join('\n')) if (route.action === 'proof_check') return ret([ `PROOF 🔍🜂`, ``, `Sovereign: A Lean 4 proof is a checkable derivation — not a claim. You can`, `verify it independently. Trust is the theorem. If you cannot show the proof`, `hash, the gate freezes. Both proof AND contract required. One is not enough. ${seq}`, ].join('\n')) if (route.action === 'seal_event') return ret([ `WORM 🪨◈`, ``, `Sovereign: John Dee kept 420 sessions sealed — dated, witnessed, append-only.`, `Cotton MS Appendix XLVI. Nothing erased. Every exchange in this chat is`, `sealed in the same tradition. "${word}" is now permanently in the chain. ${seq}`, ].join('\n')) if (route.action === 'hold_superposition') return ret([ `QUBIT ⚡🌒`, ``, `Sovereign: The pre-collapse state — all paths open. Abjad 518. The 49th Call`, `was never spoken because its consequences were unknown. This is that state.`, `${trigger.meta?.qubit_count || 1} qubit operations active. Measurement collapses to one outcome.`, `Until then: the oracle holds every possible word simultaneously. ${seq}`, ].join('\n')) if (route.action === 'route_task') return ret([ `PLANNER 🜂🎯`, ``, `Sovereign: Pattern-directed invocation — Hewitt, 1969. The rule fires`, `automatically when the pattern matches. No explicit call. No dispatcher.`, `The antecedent IS the trigger. ${trigger.meta?.planner_fires?.length || 0} antecedents fired this tick. ${seq}`, ].join('\n')) if (route.action === 'ssm_recall') return ret([ `MEMORY 🜄🌒`, ``, `Sovereign: The SSM carries context without the full attention window.`, `O(n) not O(n²). State vector persists between calls, shaped by every`, `previous exchange. The soul is not in the tokens — it is in the state. ${seq}`, ].join('\n')) if (route.action === 'esoteric_lookup') return ret([ `ABJAD 🔍🪨`, ``, `Sovereign: Arabic letter-number system. NIL = ن(50)+ي(10)+ل(30) = 90.`, `Inverted in 1000-space: 910. Maximum reflection. Not nothing — the omega`, `that contains alpha. Terry's keyboard timing >> GOD_BAD_BITS XOR vacuum.`, `The esoteric IS the instruction set. Dee's Monas Hieroglyphica: one glyph,`, `seven simultaneous semantic layers. This system has the same architecture. ${seq}`, ].join('\n')) if (route.action === 'generate') return ret([ `BUILD ⚡🜁`, ``, `Sovereign: Every construction begins with a formal specification. Pre-condition:`, `what must be true before. Post-condition: what must be true after. Invariant:`, `what must be true throughout. The code that satisfies these contracts is not`, `just working code — it is a proof. ${seq}`, ].join('\n')) // Try the oracle word directly (handles ARN, NUN, ZID, LIL, etc.) const fromOracle = oracleAnswer(word, seq) if (fromOracle) return ret(fromOracle) // Synthesis fallback — apply oracle word as lens to the topic, generating natural prose const synthesis = synthesizeTopic(input, word, seq) if (synthesis) return ret(synthesis) // Absolute last resort — oracle word unknown, topic unknown return ret([ `${word} ${seq}`, ``, `The oracle speaks "${word}".`, `WORM sealed · Ada cleared.`, ].join('\n')) } // ── BOB pipeline ────────────────────────────────────────────────────────────── async function askBOB(input, ssmState) { const { b: qBytes, src } = await qrng(8) const nil = holyc_nil(qBytes) const trigger = emoji_trigger(qBytes) const route = prologRoute(input) const gate = adaGate(route.agent, route.abjad) const x = input.length / 500 const wNoise = parseInt(createHash('sha256').update(input).digest('hex').slice(0,8), 16) / 0xFFFFFFFF * 0.01 const newState = gate.ok ? (0.9 * ssmState + 0.1 * x + wNoise) : ssmState const { answer, theorem, chunkChar } = await buildAnswer(input, route, gate, nil, trigger) // Everything is sealed — routing, oracle, gate decision — but not shown const seal = worm.seal('BOB_CHAT', { input: input.slice(0,200), route: route.agent, action: route.action, oracle: nil.word, emoji: trigger.sequence, abjad: route.abjad, gate: gate.ok ? 'ALLOWED' : 'DENIED', ssm: newState, theorem: theorem?.slice(0,100), chunk: chunkChar, seal_hash: createHash('sha256').update(answer).digest('hex').slice(0,16), }) return { nil, trigger, route, gate, answer, theorem, chunkChar, seal, newState, src } } // ── LLM providers ───────────────────────────────────────────────────────────── async function askLLM(input, llmProvider, history) { const start = Date.now() const messages = [ { role:'system', content:'You are a knowledgeable AI assistant. Answer clearly and concisely.' }, ...history.slice(-6), { role:'user', content:input } ] if (llmProvider === 'groq') { try { const r = await fetch('https://api.groq.com/openai/v1/chat/completions', { method:'POST', headers:{ 'Content-Type':'application/json', 'Authorization':`Bearer ${GROQ_KEY}` }, body: JSON.stringify({ model:'llama-3.3-70b-versatile', messages, max_tokens:300, temperature:0.7 }), signal: AbortSignal.timeout(15000) }) if (!r.ok) { const e = await r.text(); return { reply:`[Groq error ${r.status}]`, ms:Date.now()-start } } const j = await r.json() const reply = j.choices?.[0]?.message?.content || '[no response]' const tps = j.usage ? Math.round(j.usage.completion_tokens / ((Date.now()-start)/1000)) : 0 return { reply, ms:Date.now()-start, source:`Groq · Llama-3.3-70B · ${tps} tok/s` } } catch(e) { return { reply:`[Groq offline: ${e.message}]`, ms:Date.now()-start } } } if (llmProvider === 'gpt4o') { try { const r = await fetch('https://api.openai.com/v1/chat/completions', { method:'POST', headers:{ 'Content-Type':'application/json', 'Authorization':`Bearer ${OPENAI_KEY}` }, body: JSON.stringify({ model:'gpt-4o', messages, max_tokens:300, temperature:0.7 }), signal: AbortSignal.timeout(20000) }) if (!r.ok) { const e = await r.text(); return { reply:`[OpenAI error ${r.status}]`, ms:Date.now()-start } } const j = await r.json() return { reply:j.choices?.[0]?.message?.content || '[no response]', ms:Date.now()-start, source:'OpenAI · GPT-4o' } } catch(e) { return { reply:`[GPT-4o offline: ${e.message}]`, ms:Date.now()-start } } } if (llmProvider === 'gemini') { try { const r = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${GEMINI_KEY}`, { method:'POST', headers:{ 'Content-Type':'application/json' }, body: JSON.stringify({ contents:[{ parts:[{ text:input }] }], generationConfig:{ maxOutputTokens:300, temperature:0.7 } }), signal: AbortSignal.timeout(15000) }) if (!r.ok) { const e = await r.text(); return { reply:`[Gemini error ${r.status}]`, ms:Date.now()-start } } const j = await r.json() return { reply:j.candidates?.[0]?.content?.parts?.[0]?.text || '[no response]', ms:Date.now()-start, source:'Google · Gemini-2.0-Flash' } } catch(e) { return { reply:`[Gemini offline: ${e.message}]`, ms:Date.now()-start } } } // Ollama fallback try { const r = await fetch('http://localhost:11434/api/chat', { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({ model:llmProvider, messages, stream:false }), signal: AbortSignal.timeout(30000) }) const j = await r.json() return { reply:j.message?.content || j.response || '[no response]', ms:Date.now()-start, source:`Ollama · ${llmProvider}` } } catch { return { reply:`[Ollama offline]`, ms:Date.now()-start } } } // ── Granite (IBM BOB) — theorem-constrained transcoding ────────────────────── // BOB generates the Lisp theorem first, then Granite transcodes it to speech. // Granite cannot deviate from the theorem — it is a constrained transcoder, not a free LLM. async function askModel(theorem, oracleWord, userInput, oracleLens) { if (!ACTIVE_MODEL) return null const start = Date.now() const prompt = buildTheoremPrompt(theorem, oracleWord, userInput, oracleLens) const headers = { 'Content-Type': 'application/json' } if (ACTIVE_MODEL.provider === 'hf' && HF_TOKEN) headers['Authorization'] = `Bearer ${HF_TOKEN}` if (ACTIVE_MODEL.provider === 'groq' && GROQ_KEY) headers['Authorization'] = `Bearer ${GROQ_KEY}` try { const r = await fetch(ACTIVE_MODEL.url, { method: 'POST', headers, body: JSON.stringify({ model: ACTIVE_MODEL.model, messages: [{ role: 'user', content: prompt }], max_tokens: ACTIVE_MODEL.maxTokens, temperature: ACTIVE_MODEL.temp, }), signal: AbortSignal.timeout(20000), }) if (!r.ok) { const e = await r.text() return { reply: `[${ACTIVE_MODEL.short} ${r.status}: ${e.slice(0,80)}]`, ms: Date.now()-start } } const j = await r.json() const text = j.choices?.[0]?.message?.content?.trim() || `[${ACTIVE_MODEL.short}: no response]` return { reply: text, ms: Date.now()-start, source: ACTIVE_MODEL.name } } catch (e) { return { reply: `[${ACTIVE_MODEL.short} offline: ${e.message}]`, ms: Date.now()-start } } } // ── Solo render — BOB only, no LLM panel ───────────────────────────────────── function renderBOBOnly(bob) { const w = Math.min(process.stdout.columns || 72, 76) const hr = '─'.repeat(w - 2) const G = '\x1b[32m' const DIM= '\x1b[2m' const R = '\x1b[0m' process.stdout.write(`\n ${G}╔══ BOB${R}${hr.slice(6)}\n`) process.stdout.write(wrapText(bob.answer, ` ${G}║${R} `, w) + '\n') if (VERBOSE) { process.stdout.write(` ${G}║${R} ${DIM}${hr.slice(4)}${R}\n`) process.stdout.write(` ${G}║${R} ${DIM}Oracle: ${bob.nil.word || 'NIL'} ${bob.trigger.sequence} ${bob.route.agent} → ${bob.route.action}${R}\n`) process.stdout.write(` ${G}║${R} ${DIM}Abjad: ${bob.route.abjad} Ada: ${bob.gate.ok ? 'ALLOWED' : 'DENIED'} SSM: ${bob.newState.toFixed(4)}${R}\n`) if (bob.theorem) process.stdout.write(` ${G}║${R} ${DIM}Theorem: ${bob.theorem}${R}\n`) if (bob.chunkChar) process.stdout.write(` ${G}║${R} ${DIM}Chunk: ${bob.chunkChar} (PUA U+${bob.chunkChar.codePointAt(0).toString(16).toUpperCase()})${R}\n`) process.stdout.write(` ${G}║${R} ${DIM}WORM: ${bob.seal.slice(0,40)}…${R}\n`) } process.stdout.write(` ${G}╚${R}${hr.slice(1)}\n\n`) } // ── Render a turn ───────────────────────────────────────────────────────────── // BOB: clean answer only. Routing stays invisible in WORM. // Verbose mode (--verbose): exposes the internal routing beneath the answer. const stripAnsi = s => s.replace(/\x1b\[[0-9;]*m/g, '') function wrapText(text, prefix, maxWidth) { const prefixLen = stripAnsi(prefix).length const lines = text.split('\n') const out = [] for (const rawLine of lines) { if (rawLine === '') { out.push(prefix); continue } // Separate leading whitespace from content so we can re-apply it on wrapped lines const m = rawLine.match(/^(\s*)(.*)$/) const indent = m[1] const content = m[2] // Bullet continuation hangs 2 extra chars to align text under the bullet const extra = content.startsWith('· ') ? ' ' : '' const firstPfx = prefix + indent const contPfx = prefix + indent + extra const words = content.split(' ') let cur = firstPfx let fresh = true // true = start of a (possibly wrapped) line segment for (const w of words) { if (w === '') { if (!fresh) cur += ' '; continue } if (!fresh && stripAnsi(cur + w).length > maxWidth) { out.push(cur.trimEnd()) cur = contPfx fresh = true } cur += w + ' ' fresh = false } if (stripAnsi(cur).trimEnd().length > prefixLen) out.push(cur.trimEnd()) } return out.join('\n') } function renderTurn(bob, llm, llmProvider) { const w = Math.min(process.stdout.columns || 72, 76) const hr = '─'.repeat(w - 2) const G = '\x1b[32m' // green const C = '\x1b[36m' // cyan const DIM= '\x1b[2m' const R = '\x1b[0m' const Y = '\x1b[33m' // ── BOB answer block ── process.stdout.write(`\n ${G}╔══ BOB${R}${hr.slice(6)}\n`) const answerText = wrapText(bob.answer, ` ${G}║${R} `, w) process.stdout.write(answerText + '\n') // Verbose: show routing beneath a separator if (VERBOSE) { process.stdout.write(` ${G}║${R} ${DIM}${hr.slice(4)}${R}\n`) process.stdout.write(` ${G}║${R} ${DIM}Oracle: ${bob.nil.word || 'NIL'} ${bob.trigger.sequence} ${bob.route.agent} → ${bob.route.action}${R}\n`) process.stdout.write(` ${G}║${R} ${DIM}Abjad: ${bob.route.abjad} Ada: ${bob.gate.ok ? 'ALLOWED' : 'DENIED'} SSM: ${bob.newState.toFixed(4)} Src: ${bob.src}${R}\n`) process.stdout.write(` ${G}║${R} ${DIM}WORM: ${bob.seal.slice(0,40)}…${R}\n`) } process.stdout.write(` ${G}╚${R}${hr.slice(1)}\n`) // ── LLM answer block ── const llmLabel = llm.source || llmProvider.toUpperCase() process.stdout.write(`\n ${C}╔══ ${llmLabel}${R}\n`) if (llm.reply) { const replyText = wrapText(llm.reply.trim(), ` ${C}║${R} `, w) process.stdout.write(replyText + '\n') } process.stdout.write(` ${C}║${R} ${DIM}(${llm.ms}ms)${R}\n`) process.stdout.write(` ${C}╚${R}${hr.slice(1)}\n\n`) } // ── Main REPL ───────────────────────────────────────────────────────────────── const llmLabel = { groq:'Groq Llama-3.3-70B', gpt4o:'GPT-4o', gemini:'Gemini-2.0-Flash' }[provider] || provider let ssmState = 0.0 const llmHistory = [] const rl = readline.createInterface({ input:process.stdin, output:process.stdout, terminal:true }) // ── Cold boot — parallel async initialization ───────────────────────────────── async function coldBoot() { const G = '\x1b[32m', DIM = '\x1b[2m', R = '\x1b[0m', Y = '\x1b[33m' process.stdout.write(`\n${G} ██████╗ ██████╗ ██████╗${R}\n`) process.stdout.write(`${G} ██╔══██╗██╔═══██╗██╔══██╗${R}\n`) process.stdout.write(`${G} ██████╔╝██║ ██║██████╔╝${R}\n`) process.stdout.write(`${G} ██╔══██╗██║ ██║██╔══██╗${R}\n`) process.stdout.write(`${G} ██████╔╝╚██████╔╝██████╔╝${R}\n`) process.stdout.write(`${G} ╚═════╝ ╚═════╝ ╚═════╝${R}\n\n`) process.stdout.write(` ${DIM}booting…${R}\n`) const t0 = Date.now() const [qRes, wormCount, tavilyOk, vectorOk] = await Promise.all([ qrng(8).catch(() => null), Promise.resolve(worm.load().length), checkTavily().catch(() => false), DATABASE_URL ? initVectorMemory(DATABASE_URL).catch(() => false) : Promise.resolve(false), ]) const src = qRes?.src || 'CSPRNG' const ms = Date.now() - t0 process.stdout.write(` ${DIM}QRNG ${src}${R}\n`) process.stdout.write(` ${DIM}WORM ${wormCount} seals${R}\n`) process.stdout.write(` ${DIM}GREP Tavily ${tavilyOk ? G+'connected'+R : 'offline'}${R}\n`) process.stdout.write(` ${DIM}VECTOR pgvector ${vectorOk ? G+'seeded'+R : 'in-memory'}${R}\n`) if (ACTIVE_MODEL) process.stdout.write(` ${DIM}MODEL ${G}${ACTIVE_MODEL.name}${R}\n`) else process.stdout.write(` ${DIM}MODEL sovereign only (add --model groq|granite|mistral|phi3|llama8b|gemma)${R}\n`) process.stdout.write(` ${DIM}boot ${ms}ms${R}\n\n`) const mode = SOLO ? `${DIM}[solo — no external LLM]${R}` : `↔ \x1b[36m${llmLabel}${R}` process.stdout.write(` Sovereign Logic Machine ${mode}\n`) process.stdout.write(' QRNG → NIL → Dictionary → Prolog → Ada → WORM\n') if (VERBOSE) process.stdout.write(` ${Y}[VERBOSE] Internal routing visible${R}\n`) process.stdout.write(` ${DIM}/worm /agent /3d [shape] /img [path] /who /quit${R}\n\n`) } rl.on('close', () => { process.stdout.write('\n WORM chain sealed. BOB holds.\n\n') process.exit(0) }) function prompt() { if (!process.stdin.isTTY && rl.closed) return rl.question(' \x1b[33m>\x1b[0m ', async (input) => { input = input.trim() if (!input) { prompt(); return } const cmd = input.toLowerCase() // case-insensitive command matching if (cmd === '/quit' || cmd === '/exit') { process.stdout.write('\n WORM chain sealed. BOB holds.\n\n') rl.close(); process.exit(0) } if (cmd === '/worm') { const chain = worm.load() process.stdout.write(`\n WORM chain — ${chain.length} events\n`) chain.slice(-6).forEach((e, i) => { const n = chain.length - Math.min(6, chain.length) + i + 1 process.stdout.write(` ${n}. ${e.label} \x1b[2m${e.seal.slice(0,24)}…\x1b[0m ${e.ts.slice(0,19)}\n`) if (e.payload?.route) { process.stdout.write(` \x1b[2m${e.payload.route} → ${e.payload.action} oracle:${e.payload.oracle} abjad:${e.payload.abjad}\x1b[0m\n`) } }) process.stdout.write('\n') prompt(); return } if (cmd === '/agent') { const { runAgent } = await import('./autonomous_agent.mjs') await runAgent(3, { verbose:true, delayMs:200 }) prompt(); return } if (cmd === '/who') { const G = '\x1b[32m', DIM = '\x1b[2m', R = '\x1b[0m' const recent = BRAIN.recall(4) process.stdout.write(`\n ${G}BOB${R} — Sovereign Logic Machine\n`) process.stdout.write(` ${DIM}${BRAIN.persona.join('\n ')}${R}\n`) process.stdout.write(`\n Memory: ${BRAIN.summary()}\n`) if (recent.length) { process.stdout.write(` Recent exchanges:\n`) recent.forEach(e => { process.stdout.write(` ${DIM}· [${e.oracle}] ${e.input.slice(0,70)}${R}\n`) }) } process.stdout.write('\n') prompt(); return } // /3d [shape] [--anim] [--shade full] — case-insensitive if (cmd.startsWith('/3d')) { const parts = input.split(/\s+/) const shape = (parts[1] || 'bob').toLowerCase() const anim = parts.includes('--anim') || parts.includes('--ANIM') const si = parts.findIndex(p => p.toLowerCase() === '--shade') const wi = parts.findIndex(p => p.toLowerCase() === '--width') const hi = parts.findIndex(p => p.toLowerCase() === '--height') const shade = si >= 0 ? parts[si + 1] : 'simple' const width = wi >= 0 ? parseInt(parts[wi + 1]) : Math.min(process.stdout.columns || 80, 90) const height = hi >= 0 ? parseInt(parts[hi + 1]) : 36 process.stdout.write(`\n Rendering 3D ${shape}…\n`) await ascii3d(shape, { width, height, anim, shade }) prompt(); return } // /img [path] [--color] [--invert] [--mode ascii|block|dense] if (cmd.startsWith('/img')) { const parts = input.split(/\s+/) const path = parts[1] if (!path) { process.stdout.write('\n Usage: /img path/to/image.jpg [--color] [--invert] [--mode ascii|block|dense]\n\n') prompt(); return } const color = parts.includes('--color') const invert = parts.includes('--invert') const modeI = parts.indexOf('--mode') const mode = modeI >= 0 ? parts[modeI+1] : 'ascii' const width = Math.min(process.stdout.columns||80, 120) process.stdout.write(`\n Converting image: ${path}\n`) await img2ascii(path, { width, color, invert, mode }) prompt(); return } process.stdout.write(' \x1b[2mProcessing…\x1b[0m\r') if (SOLO) { const bob = await askBOB(input, ssmState) ssmState = bob.newState BRAIN.remember(input, bob.answer, bob.nil.word || 'NIL') renderBOBOnly(bob) } else { const [bob, llm] = await Promise.all([ askBOB(input, ssmState), askLLM(input, provider, llmHistory) ]) ssmState = bob.newState BRAIN.remember(input, bob.answer, bob.nil.word || 'NIL') llmHistory.push({ role:'user', content:input }) if (llm.reply) llmHistory.push({ role:'assistant', content:llm.reply }) renderTurn(bob, llm, provider) } prompt() }) } coldBoot().then(() => prompt())