mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-11 17:26:57 +02:00
Ajoute un interrupteur « Mode réflexion » (think) pour les modèles thinking
Certains modèles « thinking » ne renvoyaient que du raisonnement, sans reponse finale -> erreur. Nouvel interrupteur global `think` (Reglages > Generation) : - think=false envoie `think:false` a Ollama pour desactiver le raisonnement - repli automatique si le modele refuse le parametre (does not support thinking) - message d'erreur mis a jour pour pointer vers l'interrupteur Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
b4fc8cee3d
commit
5c1b92daa3
7 files changed
+41
-3
No files matched your search
+21
-3
@@ -44,6 +44,12 @@ def _tools_not_supported(exc: OllamaError) -> bool:
|
||||
)
|
||||
|
||||
|
||||
def _thinking_not_supported(exc: OllamaError) -> bool:
|
||||
"""Le modèle (ou son template) refuse le paramètre ``think``."""
|
||||
message = str(exc).lower()
|
||||
return "does not support thinking" in message or "thinking is not supported" in message
|
||||
|
||||
|
||||
def _invalid_tool_arguments(exc: OllamaError) -> bool:
|
||||
message = str(exc).lower()
|
||||
return (
|
||||
@@ -71,6 +77,7 @@ async def run_agent(
|
||||
options: dict | None = None,
|
||||
enabled_tools: list[str] | None = None,
|
||||
confirm_shell: bool = True,
|
||||
think: bool = True,
|
||||
) -> AsyncIterator[dict]:
|
||||
# enabled_tools=None -> tous les outils ; liste vide -> aucun outil.
|
||||
if enabled_tools is None:
|
||||
@@ -88,6 +95,9 @@ async def run_agent(
|
||||
tool_fallback_used = False
|
||||
tool_repair_attempts = 0
|
||||
request_options = dict(options or {})
|
||||
# On n'envoie ``think`` que pour le DÉSACTIVER (False) ; laissé à None, le
|
||||
# modèle garde son comportement par défaut. Repli si le modèle le refuse.
|
||||
request_think: bool | None = None if think else False
|
||||
|
||||
# Métriques cumulées sur tous les appels Ollama du tour agentique : Ollama
|
||||
# les renvoie dans le chunk final (done=true) de chaque génération.
|
||||
@@ -114,6 +124,7 @@ async def run_agent(
|
||||
convo,
|
||||
tools=active_tools,
|
||||
options=request_options,
|
||||
think=request_think,
|
||||
stream=True,
|
||||
):
|
||||
msg = chunk.get("message", {})
|
||||
@@ -191,6 +202,11 @@ async def run_agent(
|
||||
),
|
||||
}
|
||||
continue
|
||||
if request_think is not None and _thinking_not_supported(exc):
|
||||
# Le modèle n'accepte pas qu'on désactive sa réflexion :
|
||||
# on retire le paramètre et on relance.
|
||||
request_think = None
|
||||
continue
|
||||
raise
|
||||
|
||||
assistant_turn: dict = {"role": "assistant", "content": content_buf}
|
||||
@@ -270,7 +286,8 @@ async def run_agent(
|
||||
# Laisse le modèle conclure son tour (message d'attente).
|
||||
final_chunk = ""
|
||||
async for chunk in ollama.chat(
|
||||
model, convo, options=request_options, stream=True
|
||||
model, convo, options=request_options,
|
||||
think=request_think, stream=True
|
||||
):
|
||||
tok = chunk.get("message", {}).get("content", "")
|
||||
if tok:
|
||||
@@ -299,8 +316,9 @@ async def run_agent(
|
||||
yield {
|
||||
"type": "error",
|
||||
"message": (
|
||||
"Le modèle a terminé sans renvoyer de texte. Essayez un modèle "
|
||||
"de chat récent ou désactivez son mode de réflexion avancée."
|
||||
"Le modèle a terminé sans renvoyer de texte (il n'a produit que "
|
||||
"du raisonnement). Désactive « Mode réflexion » dans les Réglages, "
|
||||
"ou essaie un modèle de chat plus récent."
|
||||
),
|
||||
}
|
||||
return
|
||||
|
||||
@@ -72,6 +72,9 @@ DEFAULT_CONFIG: dict = {
|
||||
"tools": dict(DEFAULT_TOOL_STATE),
|
||||
# Demander une validation utilisateur avant toute commande shell.
|
||||
"confirm_shell": True,
|
||||
# Mode réflexion des modèles « thinking ». Désactiver (False) évite qu'un
|
||||
# modèle ne renvoie que du raisonnement sans réponse finale.
|
||||
"think": True,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -106,6 +106,7 @@ class OllamaClient:
|
||||
*,
|
||||
tools: list[dict] | None = None,
|
||||
options: dict | None = None,
|
||||
think: bool | None = None,
|
||||
stream: bool = True,
|
||||
) -> AsyncIterator[dict]:
|
||||
"""Conversation avec le modèle, en streaming token par token."""
|
||||
@@ -114,6 +115,9 @@ class OllamaClient:
|
||||
payload["tools"] = tools
|
||||
if options:
|
||||
payload["options"] = options
|
||||
# think=False désactive le raisonnement des modèles « thinking ».
|
||||
if think is not None:
|
||||
payload["think"] = think
|
||||
|
||||
async with httpx.AsyncClient(
|
||||
timeout=_STREAM_TIMEOUT, follow_redirects=True
|
||||
|
||||
@@ -72,6 +72,7 @@ async def chat(req: ChatRequest) -> StreamingResponse:
|
||||
options=agent_config.ollama_options(cfg),
|
||||
enabled_tools=agent_config.enabled_tool_names(cfg),
|
||||
confirm_shell=cfg.get("confirm_shell", True),
|
||||
think=cfg.get("think", True),
|
||||
):
|
||||
await queue.put(event)
|
||||
except Exception as exc:
|
||||
|
||||
@@ -20,6 +20,7 @@ class ConfigPatch(BaseModel):
|
||||
num_batch: int | None = None
|
||||
tools: dict[str, bool] | None = None
|
||||
confirm_shell: bool | None = None
|
||||
think: bool | None = None
|
||||
|
||||
|
||||
@router.get("")
|
||||
|
||||
@@ -72,6 +72,7 @@ export interface AgentConfig {
|
||||
num_batch: number;
|
||||
tools: Record<string, boolean>;
|
||||
confirm_shell: boolean;
|
||||
think: boolean;
|
||||
}
|
||||
|
||||
export async function runShell(
|
||||
|
||||
@@ -289,6 +289,16 @@ export function SettingsView() {
|
||||
onChange={(v) => set("num_batch", Math.round(v))}
|
||||
last
|
||||
/>
|
||||
<div className="mt-4 flex items-center gap-3 border-2 border-line bg-base px-3 py-2.5">
|
||||
<div className="flex-1">
|
||||
<div className="text-[14px] text-ink">Mode réflexion</div>
|
||||
<div className="text-[12px] text-muted-2">
|
||||
Désactive si le modèle ne renvoie que du raisonnement sans
|
||||
réponse.
|
||||
</div>
|
||||
</div>
|
||||
<Toggle on={draft.think} onClick={() => set("think", !draft.think)} />
|
||||
</div>
|
||||
<div className="mt-3 border-2 border-line bg-card-soft px-3 py-2 text-[12px] leading-relaxed text-muted-2">
|
||||
La précision KV (<code>f16</code>/<code>q8_0</code>) est un
|
||||
réglage global du serveur Ollama et nécessite son redémarrage.
|
||||
|
||||
Reference in new issue
Block a user