stream: strip <think> blocks + broaden meta-leak filter for Nemotron reasoning output
Browse files- game/stream.py +23 -0
game/stream.py
CHANGED
|
@@ -18,6 +18,7 @@ context-appropriate canned monologue.
|
|
| 18 |
|
| 19 |
from __future__ import annotations
|
| 20 |
|
|
|
|
| 21 |
import traceback
|
| 22 |
|
| 23 |
from backend.factory import get_llm
|
|
@@ -102,8 +103,19 @@ def _short(args: dict) -> str:
|
|
| 102 |
return ", ".join(out)
|
| 103 |
|
| 104 |
|
|
|
|
|
|
|
|
|
|
| 105 |
def _clean(text: str) -> str:
|
| 106 |
text = (text or "").strip()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
# Strip markdown code fences if the model wrapped its reply in them.
|
| 108 |
if text.startswith("```"):
|
| 109 |
text = text.lstrip("`").lstrip()
|
|
@@ -118,8 +130,19 @@ def _clean(text: str) -> str:
|
|
| 118 |
META_MARKERS = (
|
| 119 |
"the user wants",
|
| 120 |
"we need to produce",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
"i'll write",
|
| 122 |
"i will write",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
"2-3 sentence",
|
| 124 |
"2 to 3 sentence",
|
| 125 |
"inner monologue",
|
|
|
|
| 18 |
|
| 19 |
from __future__ import annotations
|
| 20 |
|
| 21 |
+
import re
|
| 22 |
import traceback
|
| 23 |
|
| 24 |
from backend.factory import get_llm
|
|
|
|
| 103 |
return ", ".join(out)
|
| 104 |
|
| 105 |
|
| 106 |
+
_THINK_RX = re.compile(r"<think>.*?</think>", re.DOTALL | re.IGNORECASE)
|
| 107 |
+
|
| 108 |
+
|
| 109 |
def _clean(text: str) -> str:
|
| 110 |
text = (text or "").strip()
|
| 111 |
+
# Nemotron 3 Nano and other reasoning models wrap chain-of-thought in
|
| 112 |
+
# <think>...</think> blocks; the final answer follows. Drop the block.
|
| 113 |
+
text = _THINK_RX.sub("", text).strip()
|
| 114 |
+
# If the reply was truncated mid-reasoning (open tag, no close), drop
|
| 115 |
+
# everything before the dangling opener so we don't surface meta-text.
|
| 116 |
+
if "<think>" in text.lower():
|
| 117 |
+
idx = text.lower().rfind("<think>")
|
| 118 |
+
text = text[idx + len("<think>"):].lstrip()
|
| 119 |
# Strip markdown code fences if the model wrapped its reply in them.
|
| 120 |
if text.startswith("```"):
|
| 121 |
text = text.lstrip("`").lstrip()
|
|
|
|
| 130 |
META_MARKERS = (
|
| 131 |
"the user wants",
|
| 132 |
"we need to produce",
|
| 133 |
+
"we need to output",
|
| 134 |
+
"i need to output",
|
| 135 |
+
"i need to write",
|
| 136 |
+
"i need to craft",
|
| 137 |
+
"i need to produce",
|
| 138 |
"i'll write",
|
| 139 |
"i will write",
|
| 140 |
+
"let me craft",
|
| 141 |
+
"let me write",
|
| 142 |
+
"let's craft",
|
| 143 |
+
"let's write",
|
| 144 |
+
"should reflect",
|
| 145 |
+
"should be in",
|
| 146 |
"2-3 sentence",
|
| 147 |
"2 to 3 sentence",
|
| 148 |
"inner monologue",
|