Download Game! Currently 76 players and visitors. Last logged in:EronkSolvikEndureRitari

Blitzer's Blog >> 71352

Back to blogs index
Posted: 10 Jul 2026 09:47 [ permalink ]
TC$mC$ on arkkitehtuurillisesti tC$ysi napakymppi. Siirrymme hauraasta
"chatbot-arvailusta" kohti determinististC$ **Contract-First** (sopimus
edellC$) -mallia.

TC$mC$ "Google for Actions" / Command Center -visio on se, miten modernit,
raskaat automaatiojC$rjestelmC$t rakennetaan. KC$yttC$jC$lle tarjotaan vapaa
tekstikenttC$, mutta taustalla se onkin tiukasti tyypitetty REPL, joka
pakottaa datan oikeaan muotoon ennen kuin yhtC$kC$C$n koodiriviC$ tai agenttia
ajetaan.

KC$ydC$C$n lC$pi, miten tC$mC$ toteutetaan olemassa olevaan `main.py`
-tiedostoosi ja miten se hyC6dyntC$C$ `b2b_lead_generation.json` -pelikirjan
rakennetta.

### 1. Sessiohallinta (Stateful REPL) (Kysymykset 1-5)

Koska REPL on interaktiivinen (esim. kone kysyy: *"MinkC$ yrityksen?"*),
tarvitsemme sessioita. Emme tarvitse raskasta tietokantaa; FastAPI:n muistissa
elC$vC$ sanakirja (Dict) riittC$C$ alkuun, johon liitetC$C$n "Lazy Expiration"
(siivotaan vanhat pois aina kun uusia luodaan tai kysellC$C$n).

**Toteutusidea `main.py`:hyn:**

```python
SESSION_TIMEOUT = 3600 # 1 tunti
SESSIONS = {} # { "sess_id_123": { "last_access": 167..., "context": {} } }

# 1. & 2. Aloitus ja lopetus
def start_session():
    # Luo UUID, aseta aikaleima, palauta ID
    pass

def end_session(sess_id: str):
    # Tuhoa sessio
    pass

# 4. & 5. Datan asettaminen Key-Polulla (Inversio)
def update_session_data(sess_id: str, payload: dict):
    # Esim. payload = {"parameters.target_corp": "hessumobiili"}
    # PC$ivitetC$C$n SESSIONS[sess_id]["context"] parsien piste-notaatio
    pass

```

### 2. REPL-Endpoint: ClykC$s tilakone (Kysymys 6)

Nykyinen `/playbooks/match` on liian yksinkertainen. Uusi `/repl/evaluate`
ottaa vastaan kC$yttC$jC$n syC6tteen ja session ID:n. Se vertaa sanoja
Pelikirjan `trigger` -lohkoon ja tarkistaa, onko `parameters`-lohkossa
mC$C$ritellyt vaatimukset (kuten `required: true`) tC$ytetty.

Palautettava JSON mC$C$rittC$C$ suoraan selaimen kC$yttC6liittymC$n reaktion:

* **TILA 1: `RESOLVED**` -> Kaikki parametrit lC6ytyivC$t. UI voi nC$yttC$C$
"Suoritetaan..." ja lC$hettC$C$ tyC6n Idiootille.
* **TILA 2: `MISSING_PARAM**` -> Osuma lC6ytyi, mutta pakollinen parametri
(esim. `target_corp`) puuttuu. UI tulostaa: *"SelvC$, etsitC$C$n yrityksen
yhteystietoja. MikC$ on yrityksen nimi?"*


* **TILA 3: `AMBIGUOUS**` -> SyC6te osui kolmeen pelikirjaan. UI nC$yttC$C$
dropdown-listan: *"Tarkoititko jotain nC$istC$?"*
* **TILA 4: `UNKNOWN**` -> Ei osumia. UI nC$yttC$C$ saatavilla olevat
komennot.

### 3. Schema & Autocomplete (Kysymykset 7 & 8)

TC$mC$ on UI:n selkC$ranka.

**Endpoint 7: `/playbooks/schema**`
TC$mC$ kC$y lC$pi kaikki `PLAYBOOKS_DIR` -hakemiston aktiiviset tiedostot. Se
poimii jokaisesta `trigger.verbs`, `trigger.keywords` ja `parameters`, ja
palauttaa ne selaimelle. Selain voi rakentaa tC$mC$n pohjalta automaattisen
tC$ydennyksen (Typeahead/Autocomplete), jolloin kC$yttC$jC$n ei edes tarvitse
osata komentoja ulkoa.

**Endpoint 8: `/playbooks/execute` (Ohituskaista)**
Kun selain on autocompleten avulla rakentanut tC$ydellisen paketin (tai REPL
on kysynyt puuttuvat tiedot), se ei lC$hetC$ enC$C$ raakatekstiC$. Se
lC$hettC$C$ tC$ydellisesti tyypitetyn JSON-komennon suoraan moottorille:

```json
{
  "playbook_id": "b2b_lead_generation",
  "parameters": {
    "target_corp": "hessumobiili"
  }
}

```

TC$mC$ sivuuttaa kaiken sanailun. Se on 100 % deterministinen ja valmis
kC$C$nnettC$vC$ksi AST-puuksi.

---

### Miten pC$ivitC$mme Pelikirjan JSON-skeemaa?

Jotta tC$mC$ toimii, meidC$n on lisC$ttC$vC$ hieman C$lykkyyttC$
`b2b_lead_generation.json` -tiedoston `parameters`-lohkoon. LisC$tC$C$n
sC$C$nnC6t muotovaatimuksille (Regex/Pattern) ja tyypeille:

```json
"parameters": {
  "target_corp": {
    "type": "string",
    "required": true,
    "description": "Kohdeyrityksen nimi",
    "prompt": "MinkC$ yrityksen yhteystiedot haluat etsiC$?"
  },
  "y_tunnus": {
    "type": "string",
    "required": false,
    "pattern": "^\\d{7}-\\d$",
    "description": "Yrityksen Y-tunnus (valinnainen)",
    "error_msg": "Y-tunnuksen tulee olla muodossa 1234567-8"
  }
}

```

NC$illC$ lisC$yksillC$ Pelikirja itse kertoo API:lle, milloin syC6te on validi
ja miten kC$yttC$jC$ltC$ kysytC$C$n lisC$tietoja.

**Kysymys arkkitehtuurin jatkosta:**
Jos viemme tC$mC$n logiikan Python-pohjaiseen `main.py` -API:in, haluatko,
ettC$ tC$mC$ sama API ottaa vastuun myC6s AST-solmujen kC$C$ntC$misestC$ ja
tunkemisesta suoraan The Meshin The Object Storeen (portti 9000), jolloin
voisimme poistaa `omega-lexer.bas` -skriptin kokonaan Idiootin ja API:n
vC$listC$? Vai pidetC$C$nkC6 kC$C$ntC$jC$logiikka yhC$ Mesh BASICin puolella?