feat(p1): persist workflows and semantic learning artifacts
This commit is contained in:
@@ -134,13 +134,13 @@ def reset_vlm_model_cache():
|
||||
|
||||
|
||||
def is_thinking_model(model_name: str) -> bool:
|
||||
"""Détermine si un modèle est un modèle 'thinking' (qwen3).
|
||||
"""Détermine si un modèle est un modèle 'thinking' (qwen3, qwen3.5).
|
||||
|
||||
Les modèles thinking nécessitent un assistant prefill pour éviter
|
||||
le mode réflexion interne qui peut durer >180s avec des images.
|
||||
|
||||
Args:
|
||||
model_name: Nom du modèle (ex: "qwen3-vl:8b", "gemma4:e4b")
|
||||
model_name: Nom du modèle (ex: "qwen3-vl:8b", "qwen3.5:9b", "gemma4:e4b")
|
||||
|
||||
Returns:
|
||||
True si le modèle est de type thinking (nécessite prefill workaround)
|
||||
@@ -148,6 +148,92 @@ def is_thinking_model(model_name: str) -> bool:
|
||||
return "qwen3" in model_name.lower()
|
||||
|
||||
|
||||
# ────────────────────────────────────────────────────────────────────────────
|
||||
# D5-v2 (2026-05-25) : profil grounding dédié, centralisé, env-overridable
|
||||
# ────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
# Profil grounding par défaut — qwen3.5:9b avec ctx 4096 et prefill JSON.
|
||||
# Cohérent avec décision Codex après revue Gemini : empêcher rechauffe
|
||||
# qwen2.5vl en ctx 8192 et garantir un chemin grounding reproductible.
|
||||
DEFAULT_GROUNDING_MODEL = "qwen3.5:9b"
|
||||
DEFAULT_GROUNDING_CTX = 4096
|
||||
DEFAULT_GROUNDING_PREFILL = '{"x_pct":'
|
||||
DEFAULT_GROUNDING_TEMPERATURE = 0.0
|
||||
DEFAULT_GROUNDING_NUM_PREDICT = 96 # ~80 tokens suffisent pour `{x_pct,y_pct,confidence}`
|
||||
DEFAULT_GROUNDING_KEEP_ALIVE = "30m" # éviter cold reload entre actions
|
||||
|
||||
# Fallback grounding : qwen2.5vl conservé pour compat existante (rpa-tag).
|
||||
DEFAULT_GROUNDING_FALLBACK = "qwen2.5vl:7b-rpa"
|
||||
|
||||
|
||||
def get_grounding_profile(endpoint: str = DEFAULT_OLLAMA_ENDPOINT) -> dict:
|
||||
"""Retourne le profil VLM pour les appels de grounding **format JSON**
|
||||
(réponse `{"x_pct": ..., "y_pct": ..., "confidence": ...}`).
|
||||
|
||||
⚠️ ATTENTION SCOPE D5-v3a (2026-05-25) :
|
||||
Ce profil est destiné aux appels qui consomment la sortie via prefill JSON
|
||||
(typiquement qwen3.5:9b avec prefill `{"x_pct":`). Il n'est PAS adapté
|
||||
aux appels grounding **format bbox_2d natif** de qwen2.5vl (utilisés
|
||||
dans `agent_v0/server_v1/resolve_engine.py:959-1013, 3008-3045` avec
|
||||
parsing via `core.grounding.bbox_parser.parse_bbox_to_norm`).
|
||||
|
||||
Conflit env var connu : `resolve_engine.py:959` lit aussi
|
||||
`RPA_GROUNDING_MODEL` mais attend un modèle bbox_2d (qwen2.5vl).
|
||||
Si tu setes `RPA_GROUNDING_MODEL=qwen3.5:9b`, ce profil OK mais le
|
||||
site bbox legacy de resolve_engine va recevoir un modèle incompatible.
|
||||
Reporté à D5-v3b : renommer en `RPA_BBOX_GROUNDING_MODEL` côté legacy
|
||||
+ introduire `OllamaClient.generate_bbox_grounding()`.
|
||||
|
||||
Centralise la politique pour empêcher les chemins VLM de retomber sur
|
||||
qwen2.5vl en num_ctx=8192 (Modelfile). Sortie consommée par
|
||||
OllamaClient.generate_grounding().
|
||||
|
||||
Env vars supportées :
|
||||
- RPA_GROUNDING_MODEL : modèle principal (défaut qwen3.5:9b)
|
||||
- RPA_GROUNDING_CTX : context window (défaut 4096)
|
||||
- RPA_GROUNDING_FALLBACK : modèle fallback (défaut qwen2.5vl:7b-rpa)
|
||||
- RPA_VLM_PREFILL=false : désactive le prefill JSON (rare, debug)
|
||||
|
||||
Returns:
|
||||
dict avec clés :
|
||||
- model: str
|
||||
- num_ctx: int
|
||||
- prefill: str ou None
|
||||
- temperature: float
|
||||
- num_predict: int
|
||||
- think: bool (False pour qwen3 et qwen3.5)
|
||||
- keep_alive: str
|
||||
- fallback_model: str
|
||||
"""
|
||||
model = os.environ.get("RPA_GROUNDING_MODEL", DEFAULT_GROUNDING_MODEL).strip()
|
||||
try:
|
||||
num_ctx = int(os.environ.get("RPA_GROUNDING_CTX", str(DEFAULT_GROUNDING_CTX)))
|
||||
except (TypeError, ValueError):
|
||||
num_ctx = DEFAULT_GROUNDING_CTX
|
||||
fallback = os.environ.get(
|
||||
"RPA_GROUNDING_FALLBACK", DEFAULT_GROUNDING_FALLBACK
|
||||
).strip()
|
||||
prefill_enabled = os.environ.get("RPA_VLM_PREFILL", "true").strip().lower() not in (
|
||||
"0", "false", "no", "off"
|
||||
)
|
||||
prefill = DEFAULT_GROUNDING_PREFILL if prefill_enabled else None
|
||||
|
||||
# think=False obligatoire pour qwen3/qwen3.5 (prefill = mécanisme principal)
|
||||
# et gemma4 (sinon tokens vides Ollama >=0.20).
|
||||
think_false = is_thinking_model(model) or needs_think_false(model)
|
||||
|
||||
return {
|
||||
"model": model,
|
||||
"num_ctx": num_ctx,
|
||||
"prefill": prefill,
|
||||
"temperature": DEFAULT_GROUNDING_TEMPERATURE,
|
||||
"num_predict": DEFAULT_GROUNDING_NUM_PREDICT,
|
||||
"think": not think_false, # API Ollama : think=False → on envoie False
|
||||
"keep_alive": DEFAULT_GROUNDING_KEEP_ALIVE,
|
||||
"fallback_model": fallback,
|
||||
}
|
||||
|
||||
|
||||
def needs_think_false(model_name: str) -> bool:
|
||||
"""Détermine si un modèle nécessite think=false dans le payload.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user