Instructions to use patdev/k3-a40-bootstrap with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use patdev/k3-a40-bootstrap with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf patdev/k3-a40-bootstrap:BF16 # Run inference directly in the terminal: llama cli -hf patdev/k3-a40-bootstrap:BF16
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf patdev/k3-a40-bootstrap:BF16 # Run inference directly in the terminal: llama cli -hf patdev/k3-a40-bootstrap:BF16
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf patdev/k3-a40-bootstrap:BF16 # Run inference directly in the terminal: ./llama-cli -hf patdev/k3-a40-bootstrap:BF16
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf patdev/k3-a40-bootstrap:BF16 # Run inference directly in the terminal: ./build/bin/llama-cli -hf patdev/k3-a40-bootstrap:BF16
Use Docker
docker model run hf.co/patdev/k3-a40-bootstrap:BF16
- LM Studio
- Jan
- Ollama
How to use patdev/k3-a40-bootstrap with Ollama:
ollama run hf.co/patdev/k3-a40-bootstrap:BF16
- Unsloth Desktop
- Docker Model Runner
How to use patdev/k3-a40-bootstrap with Docker Model Runner:
docker model run hf.co/patdev/k3-a40-bootstrap:BF16
- Lemonade
How to use patdev/k3-a40-bootstrap with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull patdev/k3-a40-bootstrap:BF16
Run and chat with the model
lemonade run user.k3-a40-bootstrap-BF16
List all available models
lemonade list
- Atomic Chat
protocole passerelle: erreurs amont intactes (reprise auto) + decouverte sous 3s
Browse files- anthropic_proxy.py +27 -18
anthropic_proxy.py
CHANGED
|
@@ -323,6 +323,21 @@ def to_anthropic(oai: dict, req_model: str) -> dict:
|
|
| 323 |
}
|
| 324 |
|
| 325 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 326 |
def _sse(event: str, data: dict) -> bytes:
|
| 327 |
return f"event: {event}\ndata: {json.dumps(data, separators=(',', ':'))}\n\n".encode()
|
| 328 |
|
|
@@ -384,22 +399,16 @@ async def stream_anthropic(payload: dict, req_model: str):
|
|
| 384 |
roles = "/".join(m.get("role", "?") for m in payload.get("messages", []))
|
| 385 |
print(f"[amont {r.status_code}] {body}", flush=True)
|
| 386 |
print(f"[amont] roles={roles}", flush=True)
|
| 387 |
-
|
| 388 |
-
|
| 389 |
-
|
| 390 |
-
|
| 391 |
-
|
| 392 |
-
|
| 393 |
-
|
| 394 |
-
|
| 395 |
-
|
| 396 |
-
yield _sse("
|
| 397 |
-
{"type": "content_block_stop", "index": idx})
|
| 398 |
-
yield _sse("message_delta", {
|
| 399 |
-
"type": "message_delta",
|
| 400 |
-
"delta": {"stop_reason": "end_turn", "stop_sequence": None},
|
| 401 |
-
"usage": {"input_tokens": 0, "output_tokens": 0}})
|
| 402 |
-
yield _sse("message_stop", {"type": "message_stop"})
|
| 403 |
return
|
| 404 |
async for line in r.aiter_lines():
|
| 405 |
if not line.startswith("data: "):
|
|
@@ -612,7 +621,7 @@ async def models(request: Request):
|
|
| 612 |
"""
|
| 613 |
if "anthropic-version" not in request.headers:
|
| 614 |
try:
|
| 615 |
-
r = await _client.get("/v1/models", timeout=
|
| 616 |
if r.status_code == 200:
|
| 617 |
return JSONResponse(r.json())
|
| 618 |
except Exception:
|
|
@@ -620,7 +629,7 @@ async def models(request: Request):
|
|
| 620 |
|
| 621 |
ctx = None
|
| 622 |
try:
|
| 623 |
-
r = await _client.get("/v1/models", timeout=
|
| 624 |
if r.status_code == 200:
|
| 625 |
ctx = (r.json().get("data") or [{}])[0].get("max_model_len")
|
| 626 |
except Exception:
|
|
|
|
| 323 |
}
|
| 324 |
|
| 325 |
|
| 326 |
+
def _err_of(body: str, status: int) -> dict:
|
| 327 |
+
"""Renvoie l'objet d'erreur amont intact, ou en fabrique un equivalent.
|
| 328 |
+
|
| 329 |
+
Le libelle compte : c'est sur lui que le client decide s'il peut retenter.
|
| 330 |
+
"""
|
| 331 |
+
try:
|
| 332 |
+
d = json.loads(body)
|
| 333 |
+
e = d.get("error")
|
| 334 |
+
if isinstance(e, dict) and e.get("message"):
|
| 335 |
+
return {"type": e.get("type") or "api_error", "message": e["message"]}
|
| 336 |
+
except (json.JSONDecodeError, AttributeError):
|
| 337 |
+
pass
|
| 338 |
+
return {"type": "api_error", "message": body or f"upstream {status}"}
|
| 339 |
+
|
| 340 |
+
|
| 341 |
def _sse(event: str, data: dict) -> bytes:
|
| 342 |
return f"event: {event}\ndata: {json.dumps(data, separators=(',', ':'))}\n\n".encode()
|
| 343 |
|
|
|
|
| 399 |
roles = "/".join(m.get("role", "?") for m in payload.get("messages", []))
|
| 400 |
print(f"[amont {r.status_code}] {body}", flush=True)
|
| 401 |
print(f"[amont] roles={roles}", flush=True)
|
| 402 |
+
# Le corps d'erreur repart TEL QUEL, dans un evenement SSE `error`.
|
| 403 |
+
# La documentation du protocole de passerelle est explicite : Claude
|
| 404 |
+
# Code se remet tout seul de certains refus -- champ `thinking`,
|
| 405 |
+
# signatures de raisonnement, et justement les messages systeme en
|
| 406 |
+
# milieu de conversation -- mais "la logique de reprise s'appuie sur
|
| 407 |
+
# le libelle de l'erreur amont", et "une passerelle qui enveloppe
|
| 408 |
+
# les erreurs dans son propre format casse la reprise meme si elle
|
| 409 |
+
# preserve le code de statut". Emballer l'erreur dans un bloc texte,
|
| 410 |
+
# comme je le faisais, empechait donc cette reprise.
|
| 411 |
+
yield _sse("error", {"type": "error", "error": _err_of(body, r.status_code)})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 412 |
return
|
| 413 |
async for line in r.aiter_lines():
|
| 414 |
if not line.startswith("data: "):
|
|
|
|
| 621 |
"""
|
| 622 |
if "anthropic-version" not in request.headers:
|
| 623 |
try:
|
| 624 |
+
r = await _client.get("/v1/models", timeout=2.0)
|
| 625 |
if r.status_code == 200:
|
| 626 |
return JSONResponse(r.json())
|
| 627 |
except Exception:
|
|
|
|
| 629 |
|
| 630 |
ctx = None
|
| 631 |
try:
|
| 632 |
+
r = await _client.get("/v1/models", timeout=2.0)
|
| 633 |
if r.status_code == 200:
|
| 634 |
ctx = (r.json().get("data") or [{}])[0].get("max_model_len")
|
| 635 |
except Exception:
|