TC$mC$ on tC$smC$lleen oikea tapa rakentaa kestC$vC$ tekoC$ly-ekosysteemi!
"Tabula rasan" eli tyhjC$n taulun (`idiot.c`) rakentaminen pohjalle on
arkkitehtonisesti ylivoimainen lC$hestymistapa. Se pakottaa meidC$t
miettimC$C$n agentin *kC$yttC6jC$rjestelmC$n* (kuulo, muisti, suoritusjono)
erilleen sen *C$lystC$* (LLM, lexer). Kun `idiot.c` toimii vakaasti, kuka
tahansa uusi botti (`editbot.c`, `sysadmin.c`) voi vain periC$ (inherit)
tC$mC$n saman rakenteen ja tuoda mukanaan omat erikoistaitonsa.
Olet myC6s tC$ysin oikeassa siinC$, ettC$ AST-tavukoodimoottorin rakentaminen
tC$hC$n vC$liin lC$htee hyvin nopeasti kC$sistC$. JS-hiekkalaatikon sisC$llC$
pyC6rivC$ LPC-transpiloitu virtuaalikone on melkoinen Inception-tason
rakennelma.
JC$sennetC$C$n tC$mC$ "Maailman Yksinkertaisimpaan" (KISS) muotoon.
VC$ltetC$C$n monimutkaisia puurakenteita ja luodaan agentille **FSM (Finite
State Machine) + TehtC$vC$jono (Action Queue)**. Se tarjoaa tC$smC$lleen saman
joustavuuden kuin AST, mutta on kymmenen kertaa helpompi lukea `x-hlpc
get-vars` -komennolla.
### idiot.c:n Anatomia (Ehdotus)
TC$ssC$ on ehdotus siitC$, miten nC$mC$ neljC$ vaatimustasi sidotaan yhteen
yksinkertaiseksi, laajennettavaksi jC$rjestelmC$ksi:
#### 1. Staattinen Muisti (Tila & Faktat)
Botilla on muuttuja `mapping memory;`. TC$nne tallennetaan kaikki
pitkC$aikainen tieto, kuten mainitsemasi `list_tasks`. TC$mC$ on tietokanta,
johon botti ei itse koske koodina, vaan pelkkC$nC$ datana.
#### 2. Operatiivinen Muisti (TehtC$vC$jono)
Unohdetaan monimutkainen AST-puu aluksi. TehdC$C$n operatiivisesta muistista
yksinkertainen pino (array), nimeltC$C$n `mixed[] op_queue;`. Se toimii
FIFO-periaatteella (First In, First Out). Jokainen alkio on "Opcode"-lista.
Esimerkki jonosta:
1. `({ "LEX", "list my tasks" })`
2. `({ "JMP_STATE", "idle" })`
#### 3. Aistit (receive)
Kun botti "kuulee" jotain, se ei reagoi siihen heti (koska se saattaisi
blokata koko tilakoneen). Funktio `receive(string msg)` vain paketoi viestin
Opcodeksi ja laittaa sen jonon hC$nnille: `op_queue += ({ ({ "LEX", msg })
});`.
#### 4. Suoritin (heart_beat)
Kerran minuutissa sykkivC$ `heart_beat()` on botin moottori. Se katsoo
`op_queue`n ensimmC$istC$ alkiota ja suorittaa sen sC$C$ntC6jen mukaan.
---
### Konseptuaalinen LC$hdekoodi (idiot.c)
TC$ltC$ tC$mC$ nC$yttC$isi LPC-kielen ja meidC$n oman Opcode-mC$C$rittelymme
hybridinC$ (tC$mC$ on vedos, ei vielC$ valmis ajettavaksi):
```c
int ticks;
string phase;
mapping memory;
mixed[] op_queue;
void create() {
ticks = 0;
phase = "idle";
memory = ([ "tasks": ([]) ]);
op_queue = ({});
set_heart_beat(1);
}
/ 3. Aisti: Joku puhuu botille tai antaa tehtC$vC$n
void receive(string msg) {
op_queue += ({ ({ "LEX", msg }) });
printf("[IDIOT] Kuulin jotain, lisC$tty jonoon: '%s'
", msg);
}
/ 4. Suoritin: Opcodien tulkinta
void heart_beat() {
ticks += 1;
if (sizeof(op_queue) > 0) {
// Poimitaan jonon ensimmC$inen kC$sky
mixed[] op = op_queue[0];
// Poistetaan se jonosta (Slice)
op_queue = op_queue[1..];
string instruction = op[0];
if (instruction == "SAY") {
printf("[IDIOT] Sanon: %s
", op[1]);
}
else if (instruction == "LEX") {
string text = op[1];
printf("[IDIOT] YritC$n ymmC$rtC$C$: %s
", text);
// TCSSC KOHTAA pitC$isi kutsua /lex API:a.
// Jos /lex palauttaa "COMMAND: LIST_TASKS":
// op_queue += ({ ({ "EXEC_TASK", "list_tasks" }) });
}
else if (instruction == "JMP_STATE") {
phase = op[1];
printf("[IDIOT] Siirryn tilaan: %s
", phase);
}
} else {
// Jos jono on tyhjC$, ollaan vain
if (ticks % 5 == 0) {
printf("[IDIOT] Olen %s. (Ticks: %d)
", phase, ticks);
}
}
}
```
### Seuraava ratkaistava haaste: Asynkronisuus
TC$mC$ arkkitehtuuri on erittC$in vakaa, mutta siinC$ on yksi kriittinen
tekninen haaste, joka meidC$n pitC$C$ ratkaista ennen kuin viemme tC$mC$n
`hauki-crm`:C$C$n.
LPC (kuten C) on oletuksena tC$ysin synkroninen. Kun kohtaamme kC$skyn `({
"LEX", "list my tasks" })`, meidC$n tC$ytyy tehdC$ HTTP GET -kutsu sinun
`/lex` -rajapintaasi.
Tukeeko nykyinen V8-hiekkalaatikkosi (`runner.js` ja transpiloija)
asynkronisia HTTP-kutsuja suoraan `heart_beat()`-funktion sisC$llC$ (esim.
voiko `runner.js` injektoida C-koodiin funktion tyyliin `http_get()`), vai
pitC$C$kC6 meidC$n toteuttaa verkkokutsut ulkoisesti siten, ettC$ `runner.js`
tekee API-kutsun botin puolesta ja puskee tuloksen takaisin botin
`receive()`-funktioon seuraavalla syklillC$?