Spaces:
Configuration error
Configuration error
File size: 3,188 Bytes
e23172f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | """LM Studio model integration for Trifecta-Bro.
Model id: Brettapps/trifecta-bro/v1
This module is the bridge between Trifecta-Bro and LM Studio's `lms` server
(OpenAI-compatible API on http://localhost:1234/v1). It is installed here now;
the Obsidian-vault backend wiring is added later once the model weights / prompt
pipeline are ready.
Responsibilities today:
- Resolve the LM Studio server base URL.
- Expose `Brettapps/trifecta-bro/v1` as the canonical model identifier.
- Provide a health check so the rest of the app can detect when the model
is unavailable and fall back to the open-source `TrifectaPredictor`.
Responsibilities later (vault backend):
- Load the *Fields & Form* note from the Obsidian vault.
- Build the Hermes trifecta prompt.
- Call the LM Studio model and parse the response back into predictions.
"""
from __future__ import annotations
import os
import urllib.request
from dataclasses import dataclass
# Canonical model identifier used by Trifecta-Bro against LM Studio.
MODEL_ID = "Brettapps/trifecta-bro/v1"
# LM Studio serves an OpenAI-compatible API by default on this port.
DEFAULT_LMSTUDIO_BASE_URL = "http://localhost:1234/v1"
# The `lms` server only accepts a chat/completions call for a model that is
# loaded. We expose the id here so the server can be primed with:
# lms load Brettapps/trifecta-bro/v1
# (or by importing the GGUF into LM Studio's model library).
@dataclass
class LMStudioStatus:
reachable: bool
base_url: str
model_id: str
detail: str = ""
def resolve_base_url() -> str:
"""Return the LM Studio base URL, allowing override via env."""
return os.environ.get("LMSTUDIO_BASE_URL", DEFAULT_LMSTUDIO_BASE_URL).rstrip("/")
def get_model_id() -> str:
"""Canonical model identifier for Trifecta-Bro v1."""
return MODEL_ID
def health_check(base_url: str | None = None, timeout: float = 3.0) -> LMStudioStatus:
"""Check whether the LM Studio server is up and lists our model.
This is a lightweight probe of the /v1/models endpoint. It does not require
the model to be loaded to report reachability.
"""
url = (base_url or resolve_base_url()) + "/models"
try:
req = urllib.request.Request(url, headers={"Accept": "application/json"})
with urllib.request.urlopen(req, timeout=timeout) as resp:
body = resp.read().decode("utf-8", "ignore")
reachable = resp.status == 200 # type: ignore[attr-defined]
detail = "ok" if reachable else f"status {getattr(resp, 'status', '?')}"
# Peek whether our model id is present (non-fatal if not).
if reachable and MODEL_ID not in body:
detail = "server up; model not loaded"
return LMStudioStatus(
reachable=reachable,
base_url=(base_url or resolve_base_url()),
model_id=MODEL_ID,
detail=detail,
)
except Exception as exc: # noqa: BLE001 - network probe, report failure
return LMStudioStatus(
reachable=False,
base_url=(base_url or resolve_base_url()),
model_id=MODEL_ID,
detail=str(exc) or "unreachable",
)
|