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?