# local-ai-bridge-manager — Quick start

Piattaforma gestita da **local-ai-bridge-manager**.  
Base pubblica: `https://local-ai-bridge-manager.srv1663152.hstgr.cloud`  
Host: `local-ai-bridge-manager.srv1663152.hstgr.cloud`

```
Client  --Bearer lab_sk_…-->  Manager /v1/*  -->  lab-relay  <==tunnel==  lab-agent  -->  AI locale
```

Config runtime (non-secret): `https://local-ai-bridge-manager.srv1663152.hstgr.cloud/config.json`

---

## 1 · Ottieni l’accesso (client)

1. Apri [Richiedi accesso](https://local-ai-bridge-manager.srv1663152.hstgr.cloud/register) **oppure** chiedi all’admin di creare l’utente.
2. Copia la **private key** monouso `lab_sk_…` (mostrata una sola volta).
3. Attendi che l’admin **Accetti** la richiesta (stato `approved`). Finché è `pending` l’API risponde `401`.

---

## 2 · Connessione standard (URL + secret token)

API **OpenAI-compatible**. Qualsiasi client che accetta *Base URL* + *API key* (Hermes Agent, Cursor, Continue, OpenWebUI, LiteLLM, SDK OpenAI, …).

| Campo | Valore |
|-------|--------|
| **API Base URL** / OpenAI Base URL | `https://local-ai-bridge-manager.srv1663152.hstgr.cloud/v1` |
| **API Key** / Secret / Token | `lab_sk_…` (la private key approvata) |
| **Model** | id da `GET /v1/models` nel formato **`server-name:model-name`** (es. `home-gpu:qwen3.6-35b`) |

Header HTTP equivalenti:

```http
Authorization: Bearer lab_sk_…
# oppure
X-Api-Key: lab_sk_…
```

Server AI preferito (se l’admin ti ha assegnato più nodi):

```http
X-Lab-Server: NOME_SERVER
```

oppure query `?server=NOME_SERVER`.

**Preferito:** scegli il modello già qualificato da `/v1/models` — il prefisso `server-name:` seleziona il nodo e viene rimosso prima dell’upstream:

```json
{"model":"home-gpu:qwen3.6-35b","messages":[{"role":"user","content":"ping"}]}
```

### `GET /v1/models` (aggregato per ACL)

Con la tua `lab_sk_…` il manager elenca **automaticamente tutti i modelli di tutti i server a cui la key ha accesso**, con id:

```
server-name:model-name
```

| Accesso key | Cosa vedi in `/v1/models` |
|-------------|---------------------------|
| `all` (o inherit→all) | tutti i server non `disabled` |
| `selected` | solo i server in dual-list |
| `none` | `403` |

Risposta OpenAI-compatible:

```json
{
  "object": "list",
  "data": [
    {
      "id": "home-gpu:qwen3.6-35b-a3b-gptq",
      "object": "model",
      "owned_by": "home-gpu",
      "root": "qwen3.6-35b-a3b-gptq"
    },
    {
      "id": "kesi-node-1:laguna-s-2.1",
      "object": "model",
      "owned_by": "kesi-node-1",
      "root": "laguna-s-2.1"
    }
  ]
}
```

Se un server non risponde, gli altri restano in `data`; eventuali errori per-server compaiono in `errors` (campo extra).

Chat / completions / embeddings: usa l’`id` completo come `model`. Header `X-Lab-Server` resta supportato ma non serve se l’id è già `server:model`.

### Hermes Agent

In `~/.hermes/config.yaml` (o profilo) un provider custom OpenAI-compatible:

```yaml
# esempio — adatta nomi al tuo profilo Hermes
model_providers:
  lab-bridge:
    type: openai   # o openai_compatible / custom a seconda versione
    base_url: "https://local-ai-bridge-manager.srv1663152.hstgr.cloud/v1"
    api_key: "lab_sk_…"   # meglio env: ${LAB_CLIENT_TOKEN}
```

O via env (molti setup Hermes/OpenAI leggono queste):

```bash
export OPENAI_BASE_URL="https://local-ai-bridge-manager.srv1663152.hstgr.cloud/v1"
export OPENAI_API_KEY="lab_sk_…"
# opzionale se il client le rispetta:
export LAB_BASE_URL="https://local-ai-bridge-manager.srv1663152.hstgr.cloud/v1"
export LAB_CLIENT_TOKEN="lab_sk_…"
```

Poi seleziona modello = id restituito da `/v1/models`.

### Cursor (e IDE simili)

Settings → Models → **OpenAI-compatible** / override:

| Setting | Valore |
|---------|--------|
| Override OpenAI Base URL | `https://local-ai-bridge-manager.srv1663152.hstgr.cloud/v1` |
| OpenAI API Key | `lab_sk_…` |
| Model name | id da `/v1/models` |

Stesso schema per **Continue.dev**, **Cline**, **Windsurf**, client che chiedono solo *Base URL* + *API Key*.

### curl / SDK

```bash
# models
curl -sS -H "Authorization: Bearer lab_sk_…" \
  "https://local-ai-bridge-manager.srv1663152.hstgr.cloud/v1/models"

# chat
curl -sS -H "Authorization: Bearer lab_sk_…" \
  -H "Content-Type: application/json" \
  "https://local-ai-bridge-manager.srv1663152.hstgr.cloud/v1/chat/completions" \
  -d '{"model":"MODEL_ID","messages":[{"role":"user","content":"ping"}],"max_tokens":32}'
```

Python (`openai` package):

```python
from openai import OpenAI
client = OpenAI(
    base_url="https://local-ai-bridge-manager.srv1663152.hstgr.cloud/v1",
    api_key="lab_sk_…",
)
print(client.models.list())
```

**Non usare** token agent `lab_ag_…` nei client IDE — solo `lab_sk_…`.

---

## 3 · Install client CLI (opzionale)

Sostituisci `YOUR_LAB_SK` con la private key approvata:

```bash
curl -fsSL "https://local-ai-bridge-manager.srv1663152.hstgr.cloud/install/client.sh" | bash -s -- --token 'YOUR_LAB_SK'
```

Cosa fa: scrive `~/.config/local-ai-bridge/client.env` (`OPENAI_BASE_URL` + `OPENAI_API_KEY`) e il wrapper `lab-ai`.

```bash
lab-ai models
lab-ai chat "ping"
source ~/.config/local-ai-bridge/client.env   # esporta OPENAI_* per altri tool
```

---

## 4 · Install server / agent (un comando, interattivo)

Sull’host **GPU** (accanto a vLLM/Ollama o altro AI su loopback).  
Il manager assegna da solo il token `lab_ag_…` e ti chiede **nome** + **porta locale** da pubblicare via tunnel.

```bash
curl -fsSL "https://local-ai-bridge-manager.srv1663152.hstgr.cloud/install/server-setup.sh" | bash
```

Durante il setup scegli:

1. **Nome server** (default = hostname)
2. **Porta locale AI** (tunnel target su `127.0.0.1`):
   - default consigliato: `18000` (poco conflitto)
   - alt 1: `11434` (Ollama tipica)
   - alt 2: `8000` (vLLM tipica)
   - oppure porta custom / rilevata in ascolto
3. Relay control (default `127.0.0.1:17422` — spesso SSH LocalForward)

Lo script **verifica** che sulla porta ci sia un’API AI (`/v1/models`, Ollama `/api/tags`, …): mostra engine/modelli.  
Se non trova nulla → errore + scan porte + suggerimenti (AI spenta / altra porta).  
Poi enroll, install agent e **smoke passo-passo** (manager, AI locale, relay TCP, processo agent, gateway 401).

Avanzato / non-interattivo:

```bash
curl -fsSL "https://local-ai-bridge-manager.srv1663152.hstgr.cloud/install/server-setup.sh" | bash -s -- \
  --yes --name 'home-gpu' --port 18000
```

Oppure token già creato in Admin:

```bash
curl -fsSL "https://local-ai-bridge-manager.srv1663152.hstgr.cloud/install/server.sh" | bash -s -- \
  --token 'YOUR_LAB_AG' \
  --name 'home-gpu' \
  --local '127.0.0.1:18000' \
  --relay '127.0.0.1:17422'
```

| Flag setup | Default | Significato |
|------------|---------|-------------|
| (interattivo) | — | enroll API + domande nome/porta |
| `--port` | `18000` | porta AI locale → tunnel |
| `--local` | `127.0.0.1:PORT` | host:port esplicito |
| `--relay` | `127.0.0.1:17422` | control relay |
| `--enroll-code` | *(se admin lo richiede)* | codice condiviso |

Il relay pubblico e il tunnel SSH vanno già operativi (vedi deploy `local-ai-bridge`). L’agent fa solo **outbound** verso il relay.  
Upstream manager (data plane): `http://176.9.10.220/lab-ai`  
API enroll: `https://local-ai-bridge-manager.srv1663152.hstgr.cloud/api/enroll/server`

---

## 5 · Quick test

```bash
curl -sS -H "Authorization: Bearer lab_sk_…" \
  "https://local-ai-bridge-manager.srv1663152.hstgr.cloud/v1/models" | head

curl -sS -H "Authorization: Bearer lab_sk_…" \
  -H "Content-Type: application/json" \
  "https://local-ai-bridge-manager.srv1663152.hstgr.cloud/v1/chat/completions" \
  -d '{"model":"MODEL_ID","messages":[{"role":"user","content":"ping"}],"max_tokens":32}'
```

---

## 6 · Admin

| Azione | URL |
|--------|-----|
| Login | [https://local-ai-bridge-manager.srv1663152.hstgr.cloud/login](https://local-ai-bridge-manager.srv1663152.hstgr.cloud/login) |
| Utenti (vedi tutti / accetta / revoca) | [https://local-ai-bridge-manager.srv1663152.hstgr.cloud/admin](https://local-ai-bridge-manager.srv1663152.hstgr.cloud/admin) |
| Cambia password | [https://local-ai-bridge-manager.srv1663152.hstgr.cloud/admin/password](https://local-ai-bridge-manager.srv1663152.hstgr.cloud/admin/password) |
| Tutorial (questa pagina) | [https://local-ai-bridge-manager.srv1663152.hstgr.cloud/tutorial](https://local-ai-bridge-manager.srv1663152.hstgr.cloud/tutorial) |
| Config pubblica JSON | [https://local-ai-bridge-manager.srv1663152.hstgr.cloud/config.json](https://local-ai-bridge-manager.srv1663152.hstgr.cloud/config.json) |

Sicurezza:

- Cookie admin: `HttpOnly` + `Secure` + `SameSite=Strict`
- Private key: hash SHA-256 in DB, plain solo monouso in UI
- Gateway: solo utenti `approved`
- Non mettere mai `LAB_AGENT_TOKEN` / `lab_ag_…` nei client

---

## 7 · Troubleshooting

| Sintomo | Causa tipica |
|---------|----------------|
| `401 unauthorized` | Key sbagliata, utente `pending`/`revoked`, header mancante |
| `404` su `/v1/...` | Base URL senza `/v1` oppure path doppio (`/v1/v1`) |
| Client “invalid URL” | Usa `https://local-ai-bridge-manager.srv1663152.hstgr.cloud/v1` (con `/v1`), non solo l’host |
| `502` / upstream unreachable | lab-agent offline o relay non raggiunto |
| `503` upstream not configured | `LAB_UPSTREAM_TOKEN` assente sul manager |
| Cert / “not secure” | Usa solo HTTPS su questo host (reverse proxy + certificato), non HTTP o IP grezzo |

Health manager:

```bash
curl -fsS "https://local-ai-bridge-manager.srv1663152.hstgr.cloud/healthz"
```
