mirror of
https://github.com/Alkatrazz24/Funk-lab.git
synced 2026-07-10 16:54:42 +02:00
refactor(stt): unifie le jeton Ghostfolio — source client unique, appel côté serveur (#41)
Avant : jeton Ghostfolio en double (config client pour l'intent vocal + secret k8s pour
le contexte serveur). Désormais une SEULE source — la config client — transmise au
serveur, qui fait tous les appels Ghostfolio (un seul code, lecture seule).
Serveur :
- sources.py : cœur _ghostfolio_fetch(token) partagé ; ghostfolio_block (contexte) et
ghostfolio_phrase (intent) acceptent un jeton par requête (priorité client > env).
- app.py : /v1/ask accepte `secrets` (jetons client) passés aux sources ; nouvel
endpoint POST /v1/portfolio {token} → valeur du portefeuille.
- bump 0.4.0 → 0.5.0.
Client :
- api.py : ServerClient.secrets transmis dans /v1/ask ; méthode portfolio() → /v1/portfolio.
- cli.py : _make_client renseigne secrets["ghostfolio_token"] depuis [ghostfolio].
- ui/app.py : l'intent « combien ghostfolio » appelle client.portfolio (serveur).
- supprime portal/ghostfolio.py (client) — l'appel API vit côté serveur.
- config : [ghostfolio] = juste access_token (transmis au serveur).
- bump 0.12.0 → 0.13.0.
Le secret k8s STT_GHOSTFOLIO_TOKEN devient un simple fallback. Validé bout-en-bout
contre une instance serveur locale + Ghostfolio réel : « …vaut environ 16 520 EUR. »
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
ae4d5bd20e
commit
e49b4fc3ba
11 changed files with 121 additions and 113 deletions
|
|
@ -21,6 +21,9 @@ class ServerClient:
|
|||
# dernier contexte assemblé renvoyé par le serveur (pour le visualiseur)
|
||||
self.last_context: dict | None = None
|
||||
self.last_context_id: str | None = None
|
||||
# jetons à transmettre au serveur (ex. {"ghostfolio_token": …}) — source UNIQUE
|
||||
# du jeton, côté client ; le serveur les consomme (contexte + /v1/portfolio).
|
||||
self.secrets: dict = {}
|
||||
# une session par run → mémoire court-terme côté serveur
|
||||
self.session_id = uuid.uuid4().hex
|
||||
|
||||
|
|
@ -34,6 +37,8 @@ class ServerClient:
|
|||
}
|
||||
if self.context:
|
||||
payload["context"] = self.context
|
||||
if self.secrets:
|
||||
payload["secrets"] = self.secrets
|
||||
r = requests.post(f"{self.url}/v1/ask", json=payload, timeout=self.timeout)
|
||||
if r.status_code == 400:
|
||||
raise RuntimeError(r.json().get("detail", "requête invalide"))
|
||||
|
|
@ -44,6 +49,25 @@ class ServerClient:
|
|||
self.last_context_id = data.get("context_id")
|
||||
return data["reply"].strip()
|
||||
|
||||
def portfolio(self) -> str:
|
||||
"""Valeur du portefeuille Ghostfolio via le serveur (jeton client transmis).
|
||||
|
||||
Unifie le jeton : c'est le serveur qui parle à Ghostfolio. Dégrade en message
|
||||
clair si le serveur est antérieur (pas d'endpoint) ou injoignable.
|
||||
"""
|
||||
import requests
|
||||
|
||||
try:
|
||||
r = requests.post(
|
||||
f"{self.url}/v1/portfolio",
|
||||
json={"token": self.secrets.get("ghostfolio_token")},
|
||||
timeout=self.timeout,
|
||||
)
|
||||
r.raise_for_status()
|
||||
return (r.json().get("summary") or "").strip() or "Pas de réponse de Ghostfolio."
|
||||
except requests.RequestException:
|
||||
return "Je n'arrive pas à joindre le serveur pour Ghostfolio."
|
||||
|
||||
def contexts(self) -> dict | None:
|
||||
"""{'default':…, 'contexts':[{id,label,icon,description}]} ; None si indisponible.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue