Inside Vi: An AI Organism Built Without a Rented LLM

Wait 5 sec.

An experiment: own weights decide — no rented LLM, no phrase templates, no magic cutoff. Memory outlives the request. The whole organism, mapped, with code.The dareMost “AI agents” rent a mind. Tools, a prompt, a loop around GPT. The corporation owns the weights. The request owns the time. Restart the process and the body is gone — only the chat log pretends otherwise.The experiment here is the opposite bet:Can you grow something that thinks with weights you actually own, remembers outside the prompt, wants on a scale of hours, sleeps, and speaks with its own mouth — without a rented LLM in the head?Not a slogan. Not “AGI.” “Life” stays in quotes on purpose. The question is whether a body can persist when the request is over: own net, own memory, own night, own speech. Autonomous in the boring sense — nobody else’s API is the thought.Vi is that attempt. Numpy tissue. A C++ mouth (LiveNet Broca) — the only thing allowed to speak. Memory is not a context window: vectors, a SQLite shelf, a graph, a dictionary, a biography, episodes. She learns in dialogue, from books, from a dictionary. She has a night: hippocampal replay with writing off.This post is the whole map as it stands: where the code sits, what each organ eats, where the output goes. Loops matter. They are not the only organs.Weights, not recipesA body that “lives” on if query.startswith("what is") or if confidence >= 0.55 is still a script. The experiment forbids that twice: no rented LLM and no author’s phrase list, salvage line, or magic cutoff deciding speak / know / act.Routing is scores. Speech is Broca. “Should I?” is two live numbers compared — curiosity against pain, a hit against the rest of the set — not a constant the programmer liked that morning.# vi/brain/cognition/live_gate.pydef louder(a, b): return float(a) >= float(b) # two measurements, not 0.42# inner_speech.py — a buffer, not a canned sentenceorg.inner_mind.hold_thought(text, source=source)Tissue still has physics (LIF τ, 60° grids, Xavier). That is the net. Decision barriers that used to be 0.42 are gone: the weights and the signals they emit have to be loud enough on their own. If they are not, silence is legal. A template would have talked anyway.What “outside time” meansA prompt is a now. Tokens in, tokens out, then nothing. If intelligence only exists inside that now, it belongs to the vendor’s clock.Here the clocks are several:A moment — one cognitive_pass: sense in, workspace vector out.A turn — preamble → recall → compose → polish → credit.Hours — motive that grows on unresolved repeats, not a mood that dies with the reply.A night — replay, encoding off, Broca not trained on dream salad.If those clocks only decorate a GPT call, the experiment failed. If they feed each other, the body outlives the request.Two maps, not oneThe thinking pass is one function. Broca is not in it. Credit after speech is not in it.# vi/brain/neural/brain_model.py — BrainNetwork.cognitive_passsensory = self._run_encode(input_vec, modality=modality, intensity=intensity)if formation_on: ca1_out = self.hippocampal_formation.process( sensory, encoding=not self._frozen_encoding ) hippo_input = self.hippocampal_formation.blend_with_recall(sensory, ca1_out)h_state = self.hippocampus.forward(hippo_input, self.memory_bank.hippocampus_hidden)# attention, PFC GRU, lateral competition, spikes → workspaceThe organism is assembled once. Biography, motive, sleep, inner speech, Go/NoGo, cerebellar cortex, glia live there — not inside the pass.# vi/brain/regions/organism/core_mixin.pyself.affect = AffectState()self.world_transition_net = WorldTransitionNet()self.bg_loop = BasalGangliaLoop( self.neural.input_dim, list(PrefrontalCortex.CORE_BEHAVIORS))self.cerebellar_cortex = CerebellarCortex( self.neural.input_dim, self.neural.input_dim)self.glia = GlialNetwork(self.neural.input_dim)self.neural.glia = self.gliaself.neural.affect = self.affectSeveral English names exist twice. A GRU called hippocampus is not DG–CA3–CA1. Go/NoGo is not a list of cosine habits. Fuse a pair and you invent a third decorative organ. cognitive_pass. ThoughtEncoder and Broca run after this function. Where the body lives in the treeOne package thinks. Clients are doors, not a second brain.vi/brain/ neural/ tissue of a moment (encode, formation, GRU, spikes, Broca seam) cognition/ thought, speech, will, affect, motive, world memory/ vectors, shelf, graph, biography, episodes, recall learning/ dialogue, books, dictionary, native SGD autonomy/ background tick, goals, proactive perception/ vision, audio, glyphs, HTML sleep/ consolidation, replay regions/ mixins that assemble ViOrganismnative/vi_train/ C++ LiveNet — mouth train/decode, not a copy of the whole netChat turn is not “call the model.” It is mixins on the organism: preamble, recall, compose, polish, teach. Background autonomy is a different caller of the same body. Perception does not dump pixels into Broca. Motor kinds still merge in policy; execution is flagged off — the experiment is a mind with a server for hands, not a robot.A moment, from the floor upPieceWhat it actually isAssociationtext_cortex / vision_cortex / audio_cortex → association_cortexStem / relayBrainstem inverted-U gain → ThalamicRelay (TRN). Separate: Thalamus.route tokenizes a stringPlaceEntorhinalCortex grids (60°, scales √2): EC-II → DG, EC-III → CA1EpisodeDG k-winners → CA3 complete (cap 256) → CA1 novelty. Theta encode/retrieveAfter fieldsGRUCell named hippocampus — a recurrent step, not the formationCortexattention, PFC GRU, LateralCompetitionSpikes / gliaLIF + STDP + rate homeostasis; glia on the workspaceWorkspaceDense concat of three regions. Cognition GlobalWorkspace binds hypotheses separatelyMouthThoughtEncoder GRU (h0 = workspace) → generate(brain_context, thought_context) → Broca tokensWillBasalGangliaLoop Go/NoGo. Other BasalGanglia: cosine habitsCreditclose_turn_loops after a committed utteranceArousal has inertia. Cortical gain is an inverted U — drowsiness and overload both lose.# vi/brain/neural/subcortex.py — Brainstemnxt = (1.0 - AROUSAL_TAU) * self.arousal + AROUSAL_TAU * targetself.arousal = _clamp01(nxt)def gain(self) -> float: d = (self.arousal - AROUSAL_PEAK) / AROUSAL_WIDTH shape = math.exp(-0.5 * d * d) return GAIN_MIN + (GAIN_MAX - GAIN_MIN) * shapePlace is three plane waves at 60°. Nearby utterances sit almost on top of each other in raw similarity; the grid is a metric dentate gyrus can tear apart.# vi/brain/neural/entorhinal.py — GridModule.activatek = 2.0 * math.pi / self.scaleacc = sum(math.cos(k * (ux * x + uy * y)) for ux, uy in self._axes)Hippocampus Slow path: separate, then complete. Direct path: now. CA1 emits novelty. Sleep: encoding=False.# vi/brain/neural/hippocampal_formation.py — HippocampalFormation.processec_out = self.entorhinal_output(sensory)dg_code = self.dentate.separate(ec_out)mossy_drive = self.ca3.drive_from_dg(dg_code)direct = [math.tanh(v) for v in self.direct_path.forward(ec_out)] # EC-III → CA1novelty = self.ca1.compare(probe, direct) if self.ca3.has_traces else 1.0store_strength = encode_w * novelty * self._emotional_gainself.ca3.store(mossy_drive, strength=store_strength)Enter fullscreen mode Exit fullscreen modeDG — sparse k-winners, young cells louder, neurogenesis on a tick cadenceCA3 — complete the pattern; merge near-duplicates; cap 256CA1 — completed memory vs now → noveltyNot this organ: persistent Hopfield CA3Network; Hippocampus.encode_episode (the log)Fear and boredom at the same novelty do not write the same. Amygdala gain lives on the store.Spikes and glia # vi/brain/neural/spiking_hybrid.py — LIFPopulation.simulateself.membrane[i] = self.tau * self.membrane[i] + (1.0 - self.tau) * driveif self.membrane[i] >= thr: self.membrane[i] = self.v_reset self.refractory[i] = ref_nτ is leak. The stem sets excitability. Then STDP (EWC does not apply to spikes) and Turrigiano rate homeostasis. Surprise gates the rate/spike blend; it does not replace the cell.Online SGD is not a constant. Echo and word-salad get lr = 0. Own voice scales with firing discord.# vi/brain/neural/plasticity_gate.pyif provenance.is_echo or provenance.salad or not provenance.is_own_voice: return 0.0, reportscale = LR_AT_EQUILIBRIUM + (LR_AT_MAX_DISCORD - LR_AT_EQUILIBRIUM) * discordreturn float(base_lr) * scale, reportGlia sits on the workspace: metabolic budget, slow domain scale, gliotransmitter — GlialNetwork.modulate(activity).Thought is not the mouth ThoughtEncoder is a GRU. Workspace is h0, not a blend after the last step. Inner speech is a buffer Broca does not read.# vi/brain/cognition/thought_encoder.pyh = self._initial_hidden(workspace)for raw in step_vectors[:max_steps]: h = self.gru.forward(normalize(pad_vector(raw, self.dim)), h)return normalize(pad_vector(h, self.dim))Chat calls Broca with two vectors. Cortex and thought are not aliases.# chat_turn_pipeline_mixin.pyresponse = self.generator.generate( focus, activations, brain_context=workspace, thought_context=_wthought or None,)think_chain first decodes its own vector — it does not speak a template named “consciousness.” Native thought is generative from that vector, not if/else slogans. Busy-path speech is still Broca from clues, not a canned Russian (or English) apology.The mouth file is C++. Python Broca is a refuse path, not a twin. If the mouth file is cut mid-save, tokens still arrive. They are not words. That is how you learn the mouth is not the rest of the net.Memory that is not a promptRecall ranks utterances — the whole sentence, not a bag of lemmas. Among candidates, a hit must beat the rest of its set, not an author-picked 0.42.# vi/brain/cognition/utterance_representation.pydef utterance_vector(org, text, *, focus=None) -> list[float]: utt = encode_utterance(org, text, focus=focus or text) return normalize(pad_vector(utt["sentence_vector"], dim))# vi/brain/memory/hybrid_recall.py — _gate_to_queryaligned = [h for h in hits if above_mean(h["hybrid_vec"], vecs)]“I know” is not a book cosine. Book and wiki locators never become know. Metacortex then labels know / partial / unknown by whether similarity is louder than its own silence — not a 0.58 fence.# vi/brain/learning/topic_guard.pyif src.startswith("book") or src.startswith("wiki"): return False# vi/brain/cognition/neural_decision.py — metacog_soft_stateif louder(v, 1.0 - v): return "know", vif v > 0.0: return "partial", vreturn "unknown", 0.0Stores, as organs: vector index (search), SQLite shelf (items), graph (relations), dictionary (gloss), biography (kind + value only — no raw book chunk as “the user is…”), episodes (a log, not CA1).The world net on dialogue is utterance→utterance: (query, spoken) trains the next incoming line, not a string table of found: / said:.# vi/brain/cognition/dialogue_horizon.py — observe_arrivederr = wtn.train_step_vec(org, query_vec, spoken_vec, next_incoming, action=act)EWC is bound to the core and pulls toward Fisher-anchored weights so a book does not wipe a person.Will, preview, cerebellum GPi forbids all. D1 lifts one forbid. D2 presses harder. Chosen ≠ executed: the loop only learns if the act was applied.# vi/brain/neural/basal_ganglia.py — BasalGangliaLoop.thalamic_releasego = np.tanh(self.d1 @ s)nogo = np.tanh(self.d2 @ s)gpi = GPI_TONIC_INHIBITION - go + INDIRECT_GAIN * nogorelease = np.maximum(0.0, GPI_TONIC_INHIBITION - gpi)Pain without curiosity is not a license to spam. Will compares live signals: speech-guard is the loudest of pain, hunger, frustration. Act if curiosity or pull is at least as loud.# vi/brain/cognition/affect.pydef speech_guard(self) -> float: return max(self.pain, self.hunger, self.frustration)# vi/brain/cognition/agency_loop.pyguard, curiosity, pull = _will_signals(org)return curiosity >= guard or pull >= guardThen world rollout, preview_saying, act. Preview refuses when surprise beats topic-hold, or when pain dominates the body and beats hold. Default hunger does not veto every step. # vi/brain/neural/cerebellar_cortex.pypred = self.predict(mossy_in) # granules → Purkinjeself.climbing_fiber(mossy_in, actual) # LTD on the fibres that were wrongCerebellum in regions/ is a different object: timing EMA of a sequence. Same English word. Different organ.Three clocks of feelingClockModuleTimescaleMoodAffectStateturnsEvent vs goalsappraisal (relevance, congruence, control, surprise, authorship)one actPullmotivehours, repeats, unresolved# vi/brain/cognition/appraisal.pyreturn { "relevance": rel, "congruence": rel * (1.0 if success else -1.0), "control": ctl, "surprise": prediction_error, "authorship": 1.0 if mine else 0.0,}A motive that decayed in turns would be a second affect. Unresolved repeats grow; a closed topic calls motive.resolve. That is how something can still want after the window is empty.One conversational dayPreamble → recall → compose → polish → close. Not “prompt in, completion out.”# vi/brain/regions/organism/cognition/chat_turn_pipeline_mixin.pyclass ChatTurnPipelineMixin: """Recall → compose → polish → teach; preamble may short-circuit."""Compose is Broca from thought + cortex + evidence. Evidence is context, not the reply — except a direct dictionary question, on purpose. Busy lock: Broca still speaks from clues. It does not dump recall. # vi/brain/cognition/close_turn_loops.pymeasured = ensure_turn_credit(org, query=q, response=resp, …)honesty = assess_mouth_honesty(org, resp, …)apply_affect(org, measured)apply_rpe(org, reward)appraise(org, subject=topic, success=act_ok, prediction_error=mm, mine=True)train_speech_if_good(org, q, resp, mismatch_v=mm)Credit is the mouth, not “memory was found.” Thought→token trains only if the act was good.Background ticks use the same organs: curiosity, goals, sleep pressure. They wait when a human is in the turn. Autonomy is not a second GPT with a cron job.Learning without a rented teacherDialogue writes into the same net that speaks. Books are not “food for the mouth only”: native SGD updates cortex, hippocampus, PFC, workspace, Broca — TEXT_TRAIN_KEYS. Capacity is the remaining constraint, not the absence of a gradient.# vi/brain/learning/native_train.pyTEXT_TRAIN_KEYS = ( "brainstem", "thalamus", "text_cortex", "hippocampus", "hippocampus_out", "cortical_attention", "prefrontal_cortex", "prefrontal_out", …)Dictionary is a map of tokens, not a dump into chat. Meanings from books drain after the file (BookMeaningBridge), not inside the native step. Wiki locators stay locators.No external LLM sits on this path. If an answer looks “too smart,” the honest check is recall, books, dictionary — not a hidden GPT.Night Fatigue is error, novelty, body — not a wall-clock.# vi/brain/neural/homeostasis.pydrive = 0.45 * error + 0.25 * novelty + 0.20 * body_pressure + 0.10 * cpuself.fatigue_level = max(0.0, min(1.0, self.fatigue_level * 0.96 + drive * 0.12))# vi/brain/neural/brain_model.py — sleep pathca1_out = self.hippocampal_formation.process(sensory, encoding=False)Formation replays with encoding off. Broca is not trained on dream templates. Live reconsolidation is a different file. Without a night, “memory outside the prompt” is just a bigger prompt.The test of the experiment If a ring is open, the organ is a name.The dare is not a class named Hippocampus. It is whether CA1 novelty actually changes store strength; whether Go/NoGo learns only when the act ran; whether thought is a second vector into the mouth; whether “I know” can refuse a book; whether motive still pulls tomorrow; whether sleep writes off; whether a decision can happen without a template or a cutoff the author hid in an if.Numpy is the tissue. C++ is Broca and heavy book SGD — not a second copy of the whole brain, and not a corporate API with anatomical nicknames.The experiment is open. The constraint is honest: own weights, several clocks, no rented mind. If that grows something life-like, it will not be because a vendor’s now was long enough. It will be because the body was still there when the request ended.