# Lokalne API LAYA Adres: http://127.0.0.1:8787 (zmiana: zmienna `LAYA_BIND`, np. `0.0.0.0:8787`). Serwer musi być wcześniej zbudowany (`cargo build --release`) i uruchomiony przez `./run.sh service.py start`. ## Autoryzacja `POST /v1/decide` wymaga nagłówka: ``` Authorization: Bearer ``` Token jest zaszyty w kodzie (`API_TOKEN` w `src/auth.rs`); zmiana wymaga przebudowania serwera. Brak lub zły token: HTTP 401. `/`, `/docs` i `/health` nie wymagają tokenu. Domyślny model to multilingual (`convaiinnovations/laya-multilingual`), obsługujący m.in. polski i angielski. Opcjonalny wariant English-only wymaga tekstu, instrukcji i opisów opcji po angielsku. ## GET /health Zwraca status, nazwę i rewizję modelu, urządzenie `mps` lub `cpu`, tryb offline oraz limity tokenów. Gotowość jest zgłaszana dopiero po załadowaniu modelu i rozgrzewce. ## POST /v1/decide Nagłówki: `Content-Type: application/json` oraz `Authorization: Bearer `. ```json { "state": "I was charged twice. Please refund the duplicate payment.", "questions": { "dzial": { "type": "choice", "instructions": "Which department should handle this message?", "criteria": { "billing": "invoices, payments and refunds", "technical": "software bugs and outages" } }, "zwrot": { "type": "noul", "instructions": "Does the customer request a refund?" }, "pilnosc": { "type": "score", "instructions": "How urgent is this issue?", "criteria": ["routine request", "urgent issue", "critical outage"] } } } ``` `state` może być tekstem, obiektem JSON albo listą. Złożony stan jest serializowany jako JSON przed tokenizacją. ### Odpowiedź - `answers..choice`: wybrany klucz kategorii. - `answers..noul`: oszacowane prawdopodobieństwo „tak”, od 0 do 1. - `answers..score`: oczekiwana wartość indeksu na podanej skali; dla trzech kryteriów zakres wynosi 0–2. - `probabilities`, `confidence` i `action`: surowe wyniki SDK LAYA. Wymagają oceny i ewentualnej kalibracji; nie są gwarancją poprawności. - `usage.input_tokens`: liczba tokenów zsumowana po wszystkich pytaniach. `output_tokens` wynosi 0, ponieważ model nie generuje tekstu. - `local.model`, `local.revision`, `local.device`: rzeczywiście używany model i urządzenie. - `local.inference_ms`: zmierzony czas tokenizacji i wnioskowania, z synchronizacją GPU; bez czasu HTTP. - `local.input_truncated`: zawsze `false` dla zaakceptowanej odpowiedzi. Serwer odrzuca wejście wymagające obcięcia **przed** wnioskowaniem. - `local.tokenization`: raport `tokenization-v1` z `max_len`, `head_max_len` oraz mapą `questions` pod tymi samymi identyfikatorami co `answers`. Każde pytanie ma `state_tokens`, `instruction_tokens`, `option_tokens` (lista długości), `head_tokens`, `input_tokens` (pełna sekwencja), `used_tokens` i `truncated: false`. Suma `input_tokens` pytań musi zgadzać się z `usage.input_tokens`. ### Limity lokalnego serwera - 1–8 pytań w żądaniu. - 2–10 opcji dla `choice` i `score`. - `choice`: kryteria jako słownik tekstowych opisów albo lista tekstów; `score`: lista tekstów. - Maksymalnie 1200 znaków instrukcji pytania, 2400 znaków JSON kryteriów i 16000 znaków JSON stanu. - Limity znaków chronią lokalny interfejs; nie zastępują kontekstu modelu. English-only ma **512 tokenów na każde pytanie**, z budżetem 192 na instrukcje i opcje. Multilingual ma odpowiednio **1024 i 256**. Pełna sekwencja obejmuje instrukcje, opcje, stan i znaczniki specjalne. Dwa pytania multilingual mogą łącznie zużyć 2048 tokenów, o ile każde mieści się we własnym kontekście. Opis pojedynczej opcji ma dodatkowy limit SDK: 48 tokenów. - Walidacja używa tokenizatora załadowanego modelu i porównuje pełną sekwencję z faktyczną sekwencją SDK. Obcięcie stanu, instrukcji lub opcji powoduje **HTTP 422**, `detail.code: "LAYA_CONTEXT_EXCEEDED"`, wraz z raportem `detail.tokenization`. Żadne wnioskowanie nie jest wtedy wykonywane i żadne dane nie są po cichu skracane. `/health` zwraca `input_validation: "tokenization-v1"`. - Jedno wnioskowanie naraz. Równoległe żądanie: HTTP 429. - Niepoprawne dane: HTTP 422 z polem `detail`. Brak tokenu: HTTP 401. Proces modelu nie działa: HTTP 503. ## Przykład w terminalu ```bash cd /Volumes/ICYBOX/flippico/laya curl -sS http://127.0.0.1:8787/v1/decide \ -H 'Authorization: Bearer 3b01570b051186e05534ea42be037e0273eb9cd243fc123b' \ -H 'Content-Type: application/json' \ --data-binary @sample.json ``` ## Przykład w JavaScript / Node.js ```javascript const response = await fetch('http://127.0.0.1:8787/v1/decide', { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${process.env.LAYA_TOKEN}` }, body: JSON.stringify({ state: 'Please refund the duplicate invoice payment.', questions: { zwrot: { type: 'noul', instructions: 'Does the customer request a refund?' } } }) }); if (!response.ok) throw new Error(await response.text()); console.log(await response.json()); ``` Token trzymaj po stronie backendu. Serwer nie wysyła nagłówków CORS, więc przeglądarka innej aplikacji i tak powinna iść przez własny backend. ## Pozostałe ścieżki - `/`: lokalny interfejs testowy. - `/docs`: ten plik w przeglądarce, bez zewnętrznych bibliotek. - `/health`: status modelu (publiczny, dla sond i `service.py`). <<<<<<< HEAD Pliki źródłowe: `src/` (serwer actix-web: HTTP, token, walidacja, blokada 429), `worker.py` (proces Python trzymający model w pamięci), `runtime.py`, `index.html`. ======= Pliki źródłowe: `server.py`, `runtime.py`, `index.html`. Walidacja kontekstu: `input_validation.py`. Testy bez ładowania wag: `./run.sh test_input_validation.py`; obejmują 1024/1025 tokenów, sumę 2048 dla dwóch pytań, osobną kontrolę pytań i opcji oraz rzeczywisty tokenizer multilingual. ## Trader plans: POST /v2/decide One `request_id`, and 1–8 `items`, each with its own `symbol`, `state`, `context` and `question`. Context contains `snapshot_id`, `position_revision`, `risk_revision`, `source_time_ms`, `received_at_ms`, `deadline_ms`. Deadlines are checked before inference. All items are tokenized independently and evaluated in one forward pass on the one resident model. There is no HTTP inference queue; busy returns 429. Choice criteria are the feasible plan IDs: OPEN_LONG / OPEN_SHORT / HOLD when flat, CLOSE / HOLD when held. Every item must include HOLD. Trader computes quantities, prices and risk limits; the model selects a plan. The response echoes the request ID and every context unchanged, with an answer for each item and complete token accounting. Trader must still enforce versions, deadline, price collar, available quantity and current risk before submitting an order. A response never schedules an autonomous future stop. `/v1/decide` remains compatible for research clients. `/health` additionally reports v2 support, busy status, the last success/error, inference p95 (128 samples), peak RSS and MPS allocation. Device changes invalidate inference. V2 OOM errors open a 30-second breaker and never silently move the model to CPU. Model identity and revision remain pinned by Trader to multilingual. Tests without weights or GPU: `./run.sh -m unittest test_plan_batch test_input_validation`. >>>>>>> a9fab03623be16177a0136fc17bc5c1617eb8627