AI model aspects — sensory mapping for agentic Spark
Engineer map of the Spark / SparkLang AI model as a whole system: how text, tools, memory, and optional senses plug into bytecode + weights + serve. Not marketing. Not God/Loom metaphors.
Eval scores are measurement only, not marketing wins. Prefer CPU or a consumer GPU for opt-in large local work.
Factory hub: Factory hub. Knowledge hive: Knowledge (agents/tools · multimodal · eval). Voice surface: VOICE.md. Voice easy train: Voice easy. Voice ask (dump Q&A): VOICE_ASK.md. Methods vs OpenBin: Methods vs OpenBin. Coder: Spark coder. Weights: Weight gallery. Architecture: Architecture. Attention / forward: Attention / forward. Live ask: ASK_LIVE.md. Diagrams: Diagrams.
Forge nav: this page lives under Forge → Model aspects on sparklang.dev. Sibling Forge entries: Diagrams, Builder, Build models, Train loop, Spark coder, Weight gallery, AI models, Voice / STT / TTS.
Category map
| Category | Subcategories (on this page) |
|---|---|
| Senses | Ears / STT · Eyes / vision · Speaking / TTS |
| Models | Thinking / generation · Memory · Status table |
| Train / ops | Training & adaptation · Eval & benchmarks · Runtime / serve |
| Behaviors | Behaviors · Tools & actions |
Nav: Forge → Models → Model aspects (with Senses / Train siblings).
Why sensory mapping matters (hero)
Agentic systems are not “a chat box with a bigger context window.” They are closed loops: perceive → decide → act → speak → perceive again. If you only document the LLM forward pass, you hide the failure modes that dominate real agents:
| Without a sense map | What goes wrong |
|---|---|
| Ears undefined | STT stubs look “smart” in dry CI; live mic / vendor paths surprise ops |
| Eyes pretended | Screenshots or CDPs get sold as “vision” — they are not |
| Speaking bolted on | TTS latency / net gates / stub WAVs leak into demos as “product voice” |
| Thinking oversold | Fixture-scale MLP gets narrated as a frontier model |
| Behaviors implicit | Tools, SoT, abstain, turn policy — the actual agent — stay tribal knowledge |
Sensory mapping is the contract between plain language
(“ears / eyes / speaking / thinking / behaviors”) and engineering
(STT sidecar, vision stub, TTS PCM, tiny CPU forward, .spark
policies). It is how Spark stays a local SoT language instead of
a vague “AI platform” claim.
For agentic AI specifically:
- Each sense is a boundary. Fail-closed net gates
(
SPARK_STT_NET,SPARK_TTS_NET, inventable-IDK onask) live at the sense edges — not buried in marketing copy. - Behaviors own the loop. Tools and reply packs are first-class, not afterthoughts bolted onto logits.
- Tiny vs large is explicit. CI stays tiny; large is opt-in on a consumer GPU or CPU.
- Comparison without cloning. OpenBin Ask / production phone voice stacks solve different jobs; Spark documents its loop and refuses to fake theirs.
This page keeps the summary status table (below), then expands ~100× into diagrams, how-tos, opcode/CLI maps, gaps, and roadmap.
Sensory mapping (summary table)
| Sense (plain) | Engineering meaning | Spark today |
|---|---|---|
| Ears | STT / audio in | Language listen + ./spark-stt-tts (dry stub / live sidecar) |
| Eyes | Vision / image in | Not in runtime — thin Python interface stub only |
| Speaking | TTS / audio out | Language speak + PCM synth / optional HTTP TTS |
| Thinking | LLM forward / generation | Tiny CPU embed→attention→MLP→RMSNorm→lm_head; fixture-scale |
| Behaviors | Policies, tools, turn-taking, safety, train/eval | .spark language + reply packs + tool / dry ask |
Jump: Ears · Eyes · Speaking · Thinking · Behaviors · System diagram · Comparison · How-to lab · Capability status.
Status table (engineering aspects)
| Aspect | Status | Where / notes |
|---|---|---|
| Tokenizer (byte BPE seed) | implemented | TOKENIZER.md; python/sparklang/tokenize/ |
Token embed (spark.embed) |
implemented | Init + serve; optional STEP grads |
| Layers / MLP (SwiGLU) | implemented (serve) | Serve; MLP in forward |
| Attention (QKVO / GQA) | implemented | Single-layer causal MHA train+serve; no rotary embeddings |
RMSNorm / lm_head |
implemented | Serve path after attention/MLP |
| Memory / context window | partial | Script bindings + dry fixtures; no KV-cache decode |
| Tools / actions | implemented (dry) | tool / with tools; live tool bus planned |
| Ears / STT | implemented (surface) | Dry stub; live sidecar / whisper / gated HTTP |
| Eyes / vision | planned | Stub module only — no look opcode yet |
| Speaking / TTS | implemented (surface) | Dry WAV marker; live PCM synth / gated HTTP |
| Behaviors / policies | partial | spark_reply_pack, abstain, expect, ./spark-ground; no full SM |
| Train / adaptation | implemented (CPU) | STEP SGD + owned TinyCoder |
| Eval / benchmarks | implemented | make spark-eval; optional frontier-API baseline — measurement only |
| Runtime serve | implemented | spark-serve / spark-serve-api attention+MLP CPU |
| Multimodal fused I/O | planned | Text+voice demos exist; no joint vision+LM tensors |
| Knowledge hive | implemented (docs) | Knowledge → /docs/knowledge.html; multimodal / agents topic pages |
System diagram — ears → brain → voice ↔ tools
flowchart LR
EAR["Ears — listen / STT
spark-stt-tts"]
TOK["Tokenizer / bindings"]
BRN["Thinking — tiny CPU forward
embed → attention → MLP → lm_head"]
TOOL["Tools / behaviors
classify · ask · reply pack"]
VOC["Speaking — speak / TTS
PCM or SPARK_TTS_*"]
EAR --> TOK --> BRN
BRN --> TOOL
TOOL --> VOC
VOC -.->|next turn transcript| EAR
TOOL -.->|tool result text| BRN
EYE["Eyes — vision
not available"] -.->|not wired| BRN
Loop reading (plain): ears (or typed text) become tokens → thinking
produces logits / ask text → behaviors pick tools, SoT, or abstain →
speaking (or print) leaves the system → the next turn may listen
again. Eyes stay dashed: planned contract only.
Ears — STT / audio in
Plain language
Ears turn sound into text the rest of Spark can bind (->) and
pipe (|). Without ears, agent demos stay keyboard-only.
Engineering stack
| Layer | Piece |
|---|---|
| Language | listen "file.wav" -> transcript · bare listen -> user (mic) |
| Asm | asm/voice_ops.s — voice_listen_live_dispatch |
| Companion | tools/voice/spark_stt_tts.c → ./spark-stt-tts |
| Dry path | Stub transcript; no mic; no vendor |
| Live path | RIFF/WAVE → sidecar .intent.txt / .txt, SPARK_STT_CMD, local openai-whisper, or HTTP if gated |
| Mic | --mic → arecord (S16_LE 16 kHz mono) then same STT path |
Dataflow
flowchart TB
WAV["WAV file or arecord mic"]
SIDE["sidecar .txt / .intent.txt"]
CMD["SPARK_STT_CMD (%i → stdout)"]
WH["openai-whisper tiny.en"]
HTTP["HTTP STT — only if SPARK_STT_NET=1"]
BIND["VM binds transcript -> var"]
WAV --> SIDE
WAV --> CMD
WAV --> WH
WAV --> HTTP
SIDE --> BIND
CMD --> BIND
WH --> BIND
HTTP --> BIND
Opcodes / CLI / makefile today
make # builds spark-stt-tts
./spark --dry-run examples/voice_turn.spark
./spark --live examples/voice_live.spark
./spark-stt-tts status
./spark-stt-tts listen --in examples/fixtures/audio/sample_review.wav
make voice-test # local companion smoke
| Env / flag | Meaning |
|---|---|
--dry-run |
Stub ears — CI default |
--live |
Fork ./spark-stt-tts |
SPARK_STT_NET=1 + SPARK_STT_URL |
HTTP STT (fail closed without gate) |
SPARK_STT_CMD |
Local shell STT (%i in) |
SPARK_WHISPER_MODEL |
Whisper model id (default tiny.en) |
SPARK_STT_WHISPER=0 |
Disable whisper probe |
Tiny vs large
| Path | Scale | Device |
|---|---|---|
| Dry stub / CI whisper tiny | tiny | CPU |
| Live sidecar + local whisper | small local | CPU |
| Opt-in owned voice heads | tiny / large via Voice easy | Consumer GPU or CPU |
Large STT heads are owned experiments, not a claim of vendor ASR parity. See VOICE.md tiny-vs-large table.
Gaps vs roadmap
| Gap | Status |
|---|---|
| Barge-in / EOU / silence | Not shipped as production |
| Streaming partial transcripts into VM | Not a product claim |
| Multi-mic / telephony codec matrix | PSTN gated separately — not “ears done” |
| Neural ASR training as default CI | No — dry stub is SoT for make test |
Links
VOICE.md · Spark coder (sibling train discipline) · Weight gallery · CI_PAGES.md.
Eyes — vision / image in
Plain language
Eyes would turn images into captions or visual tokens the brain can use. Spark does not have working eyes today.
Engineering stack
| Claim | Reality |
|---|---|
| Vision encoder | None |
Image tokens into spark.embed |
None |
Language look opcode |
None |
| Browser CDP screenshot | Writes PNG for humans — not a vision model |
| Ship today | python/sparklang/senses/vision.py — VisionRequest / VisionResult, status=planned |
make test-senses
python3 -m unittest python/sparklang/senses/test_senses.py
Dataflow (planned — dashed)
flowchart LR
IMG["PNG / JPEG path"]
ENC["Vision encoder — planned"]
TOK["Image / caption tokens — planned"]
EMB["spark.embed — not wired"]
IMG -.-> ENC -.-> TOK -.-> EMB
Tiny vs large
N/A for runtime. Any future large vision experiment follows the same consumer-GPU-or-CPU discipline as coder / weights.
Gaps vs roadmap
| Item | Status |
|---|---|
look "path.png" -> caption |
Planned — same fail-closed net gates as STT |
| Fused vision+LM tensors | Planned multimodal row above |
| “Eyes fully working” marketing | Forbidden — this page exists to prevent that lie |
Links
Senses package under python/sparklang/senses/ · Factory status in
Factory hub · Adoption: ADOPTION_BAR.md.
Speaking — TTS / audio out
Plain language
Speaking turns text (or the last bound value) into audio the user can hear — or a dry WAV marker CI can hash.
Engineering stack
| Layer | Piece |
|---|---|
| Language | speak "Hello" -> "out.wav" · speak reply · speak with model NAME |
| Asm | voice_speak_live_dispatch / voice_speak_model_dispatch |
| Companion | ./spark-stt-tts speak … |
| Dry | write_stub_wav / tiny WAV marker |
| Live | Built-in PCM synthesizer → 16-bit WAV; or SPARK_TTS_CMD; or HTTP if gated; optional aplay |
speak with model NAME loads a written voice model under
out/voice_models/ (timbre/prosody params) — config / features,
not a claim of neural clone training inside Spark.
spark_reply_pack can store spoken scripts for speak reply on
text-only bases — still not voice-GPU / LoRA TTS.
Dataflow
flowchart TB
TXT["Text / last_val / reply pack"]
PCM["Local PCM synth"]
CMD["SPARK_TTS_CMD (%o out)"]
HTTP["HTTP TTS — SPARK_TTS_NET=1"]
WAV["WAV path / aplay"]
TXT --> PCM --> WAV
TXT --> CMD --> WAV
TXT --> HTTP --> WAV
Opcodes / CLI / makefile
./spark --dry-run examples/voice_turn.spark
./spark-stt-tts speak --text "hi" --out /tmp/spark-voice-test.wav
./spark --dry-run examples/voice_copy.spark # written model path
./spark --dry-run examples/model_train_reply.spark
| Gate | Enables |
|---|---|
SPARK_TTS_NET=1 + SPARK_TTS_URL |
HTTP TTS |
SPARK_SPEECH_NET=1 |
Both STT + TTS net |
SPARK_TTS_PLAY=1 / --play |
Play after speak |
| URL without gate | exit 2 — fail closed |
Tiny vs large
| Path | What it is |
|---|---|
| Dry stub WAV | CI SoT |
| Live PCM synth | Local, not vendor quality |
| Written voice models | Features under out/voice_models/ |
| Opt-in owned TTS heads | Consumer GPU or CPU |
Gaps vs roadmap
Production telephony gaps (barge-in, call SM, latency budgets) are documented in VOICE.md — Spark speaking is a language/demo surface, not a call-center product.
Links
VOICE.md · MODEL_TRAINING.md
(reply pack) · templates under templates/voice_models/.
Thinking — LLM forward / generation
Plain language
Thinking is how Spark turns tokens into the next token / ask text
— either the owned tiny CPU serve path or an optional live
gateway ask (not required for dry demos).
Engineering stack — tiny CPU serve (weights)
When MLP tensors exist (Serve):
embed (mean pool) → attention (single-layer causal MHA)
→ MLP (SwiGLU) → RMSNorm → lm_head
Code: python/sparklang/model_lab/serve.py. HTTP/stdio:
./spark-serve-api (/v1/predict, /v1/embeddings).
| Piece | Status |
|---|---|
| Embed + lm_head | yes |
| MLP (SwiGLU) | yes in serve |
| Single-layer causal attention | yes train + serve |
| Multi-layer attn decode | no |
| Rotary embeddings / KV cache | sparkasm macros / shape check — not in Python path |
Language ask / classify / extract
| Mode | Behavior |
|---|---|
| Dry | Fixtures / heuristics — CI safe |
| Live | ./spark-ask-http + AI_GATEWAY_URL — ASK_LIVE.md |
| Grounding | Inventable prompts IDK unless --sot-ok |
the AI gateway is one optional backend, not a Spark requirement. Spark is not a the AI gateway plugin.
Dataflow
flowchart LR
IN["Tokens / prompt"]
EMB["embed"]
AT["attention"]
MLP["MLP"]
HN["RMSNorm"]
LH["lm_head"]
OUT["logits / text"]
IN --> EMB --> AT --> MLP --> HN --> LH --> OUT
GW["Optional gateway ask"] -.-> OUT
CLI / makefile
make spark-serve
./spark-serve docs/examples/spark-builder.sparkbc /tmp/serve-dry-001
make spark-serve-api
./spark-serve-api --weights …/weights.safetensors --http \
--host 127.0.0.1 --port 8765
make spark-ask-http
./spark-ask-http --dry --model fixtures/tiny-lm --prompt "Reply: pong"
make test-ask-gateway
Tiny vs large
| Scale | Thinking path |
|---|---|
| tiny | Fixture dims; CI SGD; TinyCoder default (Spark coder) |
| large | Opt-in ./spark-code train --scale large / weight gallery large+xl stubs — consumer GPU |
Stub / gallery weights are not production LLMs and do measurement only. Catalog: Weight gallery.
Gaps vs roadmap
| Gap | Status |
|---|---|
| Multi-layer decode + KV cache | No |
| Rotary embeddings in Python serve | No |
| Competitive AI win claim | Forbidden claim — eval scores only (Eval) |
Links
Attention / forward · Architecture · Serve · Spark coder · Weight gallery · ASK_LIVE.md.
Behaviors — policies, tools, turn-taking
Plain language
Behaviors are the policies and control flow around the model — not the tensor math. This is where agentic systems win or fail: tools, SoT, abstain, expect, reply locking, train/eval feedback.
What Spark does today
| Behavior | What Spark does today | Limit |
|---|---|---|
| Turn scripts | .spark statements bind vars (->), chain with \| |
No barge-in / EOU SM |
| Intent routing | classify dry fixtures + live ask |
Heuristic / gateway — not a trained NLU stack claim |
| Reply locking | spark_reply_pack (replies.json + gate.json) |
Overlay scripts on text-only bases; not neural TTS |
| Inventable safety | SoT refs or IDK / abstain heads | Fail loud — never fabricate |
| Grounded / anti-guess | ./spark-ground verify-before-speak |
Wrong expect → abstain (exit 2); not “impossible to lie” |
| Tool use | tool name(…) { stub } + with tools […] |
Dry returns [tool:…] stub:local; no agentic loop claim |
| Shell escape | shell / run allowlist dry; live --allow-shell |
Never system() |
| Expect / eval gate | expect equal / contains |
Pass/fail on scripts |
| Receptionist goal | examples/receptionist_goal.spark [goal] |
Sketch — not production telephony |
Language tools (behaviors)
tool weather(city: string) -> string { "stub:local" }
with tools [weather] {
ask "Weather in DSM?" -> answer
}
Dry ask inside an active scope returns [tool:<name>] stub:local.
Separate from factory helper tools (I/K): spark-helper-*,
shadows, SDK pack — those wrap compile/decompile/serve for authors.
See Diagrams and TOOLS_HELPERS.md.
Model behaviors stay in .spark; helpers do not silently become
policy.
Dataflow
flowchart TB
IN["User / fixture text or transcript"]
POL["Behavior policy
reply pack · abstain · expect"]
ASK["ask / classify / extract"]
TL["tool registry
with tools scope"]
OUT["print / speak / http"]
TR["Train STEP / model train"]
EV["spark-eval"]
IN --> POL --> ASK
ASK --> TL
TL --> ASK
ASK --> OUT
TR --> EV
EV -.->|scores only; never win claim| POL
Train / eval (behavior adjacent)
| Path | Status | Status |
|---|---|---|
SPARK_BC TRAIN / STEP |
implemented | Multi-pass CPU SGD |
| Five HTTP train methods | implemented | distill / pref / playbook / FAQ / reply pack — CPU |
| Owned TinyCoder | implemented | tiny CI + large opt-in |
| LoRA / voice-GPU | won't (claim) | Not sold on sparklang.dev |
make spark-eval |
implemented | Exit 0 = harness ran — measurement only |
Train loop · BUILD_MODELS.md · MODEL_TRAINING.md · Eval.
Gaps vs roadmap
| Gap | Status |
|---|---|
| Full turn state machine | Partial — no production SM |
| Live tool bus | Planned |
| Helpers ≠ policy | Keep separate forever |
Links
LANGUAGE.md · VOICE.md · knowledge/SAFETY_LIMITS.md (grounded / anti-guess) · ADOPTION_BAR.md · Spark coder.
Memory & context (cross-cutting)
| Mechanism | Status | Notes |
|---|---|---|
Statement bindings (->) |
implemented | In-script memory for one run |
Pipeline \| chaining |
implemented | Passes last values |
| Gateway chat history | external | Only if the live gateway keeps it — not Spark KV |
| Transformer KV cache | not | Single-layer attention only; no KV cache |
RAG retrieve / embed |
implemented (dry + live companion) | Project fixtures / spark-rag-http |
| Long-term episodic store | planned | Not a shipped product claim |
Do not invent a context-window size for production marketing — read live dims from weights / control asm when measuring.
Comparison — Spark local SoT vs OpenBin Ask / production voice stacks
Spark is the local language + bytecode + weights SoT. Other products are related reading — not clones and not substitutes for Spark recovery / serve proofs.
| Dimension | Spark (this repo / sparklang.dev) | OpenBin Ask (openbin.ai) | Production phone / voice products |
|---|---|---|---|
| Job | Language + SPARK_BC factory + optional senses | Online AI reverse-engineering / agent Q&A on binaries | Live telephony, STT/TTS, transfers |
| SoT | Local dump.py / --compile / --run-bc / dry fixtures |
Cloud project + Ghidra-backed decompile — not SPARK_BC | Carrier + product journals — not Spark VM |
| Ask path | Dry fixtures or optional ./spark-ask-http + gateway (ASK_LIVE.md); dump/binary Q&A via VOICE_ASK.md (./spark-ask / ./spark-speak-ask) — not OpenBin SaaS |
Agent loop over RE tools / BYOK LLMs | Prompt + tools inside the voice worker |
| Ears / speaking | Language listen/speak + spark-stt-tts (gated) |
N/A (RE product) | Always-on production STT/TTS |
| Eyes | Not available | Screenshots ≠ Spark vision | Optional vision elsewhere — not claimed here |
| Trust | Binaries stay local; fail-closed net gates | Upload / login trust surface — use a gated lab if at all | Product-specific privacy / retention — out of scope here |
| GPU | Train: CPU or consumer GPU | Vendor / cloud | Vendor-managed — out of scope |
| Status | Measurement only; eyes not claimed | Not Spark decompile SoT | Not a Spark clone — do not reimplement here |
Do not:
- Treat OpenBin output as verified Spark recovery
- Clone OpenBin UX into sparklang.dev
- Sell Spark voice as a phone stack
Decompile research context (OpenBin cited carefully): research/LLM_DECOMPILE.md → /docs/llm-decompile.html.
How-to lab (15 minutes)
Prove the sensory map without inventing live vendor calls:
# 0) Bootstrap
make spark-bootstrap spark
# 1) Ears + speaking dry (CI SoT)
./spark --dry-run examples/voice_turn.spark
# 2) Companion smoke (local PCM / stub listen)
make voice-test
# 3) Eyes status gate (stub)
make test-senses
# 4) Thinking — tiny serve dry
make spark-serve
./spark-serve docs/examples/spark-builder.sparkbc /tmp/serve-dry-001
# 5) Behaviors — dry tools + expect
./spark --dry-run examples/tool_agent.spark
# 6) Optional live ask — dry companion only
make spark-ask-http
./spark-ask-http --dry --model fixtures/tiny-lm --prompt "pong"
# 7) Docs regen when you edit this file
make docs-check
Live STT/TTS/PSTN and live gateway ask need explicit gates — see VOICE.md and ASK_LIVE.md. Prefer passive / dry proofs when PSTN guards or missing keys apply.
Runtime / serve wiring (thinking surface)
make spark-serve-api
./spark-serve-api --weights …/weights.safetensors --http \
--host 127.0.0.1 --port 8765
Voice companions are not inside serve_api — ears/speaking fork
./spark-stt-tts from the language VM under --live. Predict API
stays token-id JSON for the tiny CPU stack.
Serve · CI_PAGES.md.
Capability status
| Claim | Allowed? |
|---|---|
| Ears/speaking language surface + gated live companions | Yes |
| Eyes fully working / vision encoder shipped | No |
| Marketing win banners | Out of scope |
| Opt-in large on a consumer GPU / CPU | Yes |
| OpenBin clone / phone-stack clone | No |
| Spark local SPARK_BC SoT | Yes |
Adoption checklist: ADOPTION_BAR.md. Roadmap sketches: ROADMAP.md.
Related docs
| Topic | Relation to this page |
|---|---|
| Factory hub + diagrams | Extended context — Factory hub / Diagrams |
| Decompile / OpenBin methods | Cross-link — Decompile / Methods vs OpenBin |
| SDK / helpers / shadows | Authoring tools — IDE.md / TOOLS_HELPERS.md |
| Attention math | Single-layer causal MHA — Attention / forward |
| Eval / scale / serve | Linked above — Eval / Train loop / Serve |
| Owned spark-coder | Tiny + large discipline — Spark coder |
| This sensory map | Expanded status on this page |
Quick links (Forge + Bench)
- Factory hub · Diagrams · Knowledge
- VOICE.md · AI_MODELS.md · ASK_LIVE.md
- Spark coder · Weight gallery
- Architecture · TOKENIZER.md
- LANGUAGE.md · ROADMAP.md
- Site: /docs/model-aspects.html · /docs/knowledge.html · /docs/voice.html · /docs/voice-easy.html · /docs/voice-ask.html · /docs/methods-openbin.html · /docs/spark-coder.html · /docs/weight-gallery.html