Sesiuni partajate
O conversație, mai multe dispozitive — gateway-ul păstrează jurnalul ordonat de evenimente; dispozitivul cu uneltele execută; toți ceilalți urmăresc sau ghidează.
O sesiune partajată este o conversație ținută pe server. Store-ul gateway-ului este sursa de adevăr pentru jurnalul ordonat de evenimente; fiecare dispozitiv păstrează un cache local și se reconciliază după seq. Conversația călătorește; execuția rămâne acolo unde sunt uneltele — laptopul tău rulează shell-ul, telefonul urmărește și răspunde la întrebările agentului, un coleg citește în paralel.
Acesta este protocolul din spatele lui „continuă pe telefon”, al vizualizării de sesiuni din hub și al oglinzii live de pe desktop. Este public, versionat (v1, stabil) și publicat cu JSON Schema-uri la github.com/codai-ro/codai-protocol.
Piesele în mișcare
┌──────────────── gateway (ai.codai.ro) ────────────────┐
│ sesiune ──▶ events[seq 1..n] controls lease │
└──────▲──────────────┬──────────────▲────────┬────────┘
adaugă events POST │ │ SSE / WS │ POST │ push (FCM)
ia lease-ul │ ▼ │ ▼
┌────────────────┐ ┌───────────┐ ┌───────────┐ ┌────────────┐
│ EXECUTOR │ │ VIEWER │ │ EDITOR │ │ DISPATCHED │
│ desktop / CLI │ │ hub, web │ │ telefon │ │ dispozitiv │
│ deține lease-ul│ │ read-only │ │ trimite │ │ trezit cu │
│ rulează unelte │ │ urmărește │ │ controls │ │ un `send` │
└────────────────┘ └───────────┘ └───────────┘ └────────────┘| Obiect | Ce este |
|---|---|
| Session | Containerul. Are un id (UUID de server) și propriul tău session_key, un owner, un titlu, last_seq și cine deține lease-ul. |
| Event | O intrare în jurnal, cu un seq dens atribuit de server, un kind (turn_start, tool_call, ask, assistant, …) și un payload opac. Doar executorul adaugă. |
| Control | O instrucțiune către executor — send, answer, approve, deny, cancel, steer, inject. Persistată, ca un executor întârziat să le poată consuma; ecou în jurnal, ca fiecare viewer să le vadă. |
| Lease | Dreptul de a adăuga. Exact un dispozitiv îl deține, câte 30 de secunde, reînnoit prin heartbeat la fiecare 10 secunde. |
| Device | Orice instalare de client — un UUID ales de tine, trimis ca x-codai-device, înregistrat lazy sub contul tău. |
| Share | O acordare de viewer, editor sau owner pe o sesiune către un utilizator, o organizație sau un token de link. |
| Presence | Cine este conectat acum și dacă conduce. Doar în memorie. |
| Dispatch | Un send țintit către unul dintre dispozitivele tale, plus o notificare push care să-l trezească. |
Roluri
| Rol | Poate |
|---|---|
viewer | Să citească sesiunea, evenimentele și controls; să urmărească stream-ul live. |
editor | Tot ce poate un viewer, plus să trimită controls și dispatch. |
owner | Totul, plus redenumire, arhivare, ștergere, gestionarea share-urilor și preluarea lease-ului. |
Ești owner pe sesiunile create de tine. Pe o sesiune partajată rolul tău este cel mai înalt dintre share-urile care ți se potrivesc — direct, printr-o organizație din care faci parte sau printr-un token de link pe care îl prezinți.
Un round trip minimal
Fiecare request poartă cheia ta și, la scrieri, id-ul dispozitivului:
export DEV=$(uuidgen) # o dată per instalare; refolosește-l
# 1. creezi (sau redeschizi) o sesiune după propria cheie
curl -X POST https://ai.codai.ro/v1/sessions \
-H "Authorization: Bearer $CODAI_API_KEY" \
-H "x-codai-device: $DEV" -H "x-codai-device-platform: cli" \
-H "Content-Type: application/json" \
-d '{ "session_key": "laptop-2026-09-23", "title": "Fix the flaky test" }'
# 2. iei lease-ul — acum ești executorul
curl -X POST https://ai.codai.ro/v1/sessions/laptop-2026-09-23/lease \
-H "Authorization: Bearer $CODAI_API_KEY" -H "x-codai-device: $DEV"
# 3. adaugi ce s-a întâmplat
curl -X POST https://ai.codai.ro/v1/sessions/laptop-2026-09-23/events \
-H "Authorization: Bearer $CODAI_API_KEY" -H "x-codai-device: $DEV" \
-H "Content-Type: application/json" \
-d '{ "events": [
{ "kind": "turn_start", "turn_id": "t1", "client_event_id": "t1-start", "payload": { "text": "Fix the flaky test" } },
{ "kind": "assistant", "turn_id": "t1", "client_event_id": "t1-a1", "payload": { "text": "Reading test_retry.py…" } }
] }'
# 4. de pe orice alt dispozitiv: urmărești
curl -N "https://ai.codai.ro/v1/sessions/laptop-2026-09-23/stream?after=0" \
-H "Authorization: Bearer $CODAI_API_KEY" -H "x-codai-device: $(uuidgen)"Stream-ul redă cele două evenimente, apoi un frame lease care numește laptopul tău ca deținător, apoi rămâne deschis pentru ce urmează.
Unde mergi mai departe
Referința protocolului
Fiecare obiect, rută, eroare și limită din v1.
Streaming
Frame-uri SSE și WebSocket, reluare cu ?after=, scrieri idempotente.
Partajare și organizații
Invită o persoană, o echipă sau un link; gestionează organizațiile.
Releul de host-uri
Rulează o comandă shell sau citește un fișier pe desktopul tău de pe telefon.
Stocarea și streaming-ul propriilor sesiuni sunt disponibile pe orice tier plătit. Entitlement-ul persistent_memory condiționează doar memoria și căutarea pe server, nu acest protocol. O sesiune creată cu e2e: true este criptată pe client (HIDE — experimental, neauditat) și gateway-ul stochează ciphertext.