| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
|
|
| 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'
|
|
|
|
|
|
|
| const args = process.argv.slice(2)
|
|
|
|
|
| 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'
|
|
|
|
|
|
|
| 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 || ''
|
|
|
|
|
| setTavilyKey(TAVILY_KEY)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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,
|
| },
|
| }
|
|
|
|
|
| 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
|
|
|
|
|
|
|
| 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
|
| }
|
| }
|
|
|
|
|
|
|
| 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`
|
| },
|
| }
|
|
|
|
|
|
|
| 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' }
|
| }
|
|
|
|
|
|
|
| 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}` }
|
| }
|
|
|
|
|
|
|
|
|
|
|
| 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
|
|
|
|
|
| const ret = ans => ({ answer: ans, theorem, chunkChar })
|
|
|
|
|
| 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'))
|
| }
|
|
|
| }
|
|
|
|
|
| const dictAnswer = sovereignAnswer(input, word, seq)
|
| if (dictAnswer) return ret(dictAnswer)
|
|
|
|
|
| const genAnswer = topicAnswer(input, word, seq)
|
| if (genAnswer) return ret(genAnswer)
|
|
|
|
|
| if (route.action === 'sovereign_step' && tavilyReady()) {
|
| const webAnswer = await tavilyAnswer(input, word, seq)
|
| if (webAnswer) return ret(webAnswer)
|
| }
|
|
|
|
|
| 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'))
|
|
|
|
|
| const fromOracle = oracleAnswer(word, seq)
|
| if (fromOracle) return ret(fromOracle)
|
|
|
|
|
| const synthesis = synthesizeTopic(input, word, seq)
|
| if (synthesis) return ret(synthesis)
|
|
|
|
|
| return ret([
|
| `${word} ${seq}`,
|
| ``,
|
| `The oracle speaks "${word}".`,
|
| `WORM sealed · Ada cleared.`,
|
| ].join('\n'))
|
| }
|
|
|
|
|
|
|
| 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)
|
|
|
|
|
| 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 }
|
| }
|
|
|
|
|
|
|
| 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 } }
|
| }
|
|
|
|
|
| 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 } }
|
| }
|
|
|
|
|
|
|
|
|
|
|
| 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 }
|
| }
|
| }
|
|
|
|
|
|
|
| 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`)
|
| }
|
|
|
|
|
|
|
|
|
|
|
| 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 }
|
|
|
|
|
| const m = rawLine.match(/^(\s*)(.*)$/)
|
| const indent = m[1]
|
| const content = m[2]
|
|
|
| const extra = content.startsWith('· ') ? ' ' : ''
|
| const firstPfx = prefix + indent
|
| const contPfx = prefix + indent + extra
|
|
|
| const words = content.split(' ')
|
| let cur = firstPfx
|
| let fresh = true
|
|
|
| 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'
|
| const C = '\x1b[36m'
|
| const DIM= '\x1b[2m'
|
| const R = '\x1b[0m'
|
| const Y = '\x1b[33m'
|
|
|
|
|
| process.stdout.write(`\n ${G}╔══ BOB${R}${hr.slice(6)}\n`)
|
|
|
| const answerText = wrapText(bob.answer, ` ${G}║${R} `, w)
|
| process.stdout.write(answerText + '\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)} 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`)
|
|
|
|
|
| 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`)
|
| }
|
|
|
|
|
|
|
| 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 })
|
|
|
|
|
|
|
| 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()
|
|
|
| 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
|
| }
|
|
|
|
|
| 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
|
| }
|
|
|
|
|
| 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())
|
|
|