feat(generation): add conditional thinking classifier
Routes simple/conversational messages to think=false automatically, even when the user has thinking enabled. Patterns checked: word count thresholds, complexity keywords, code blocks, skip patterns for greetings and simple CRUD. Workspace mode (think=true from frontend) still benefits from the classifier on short messages. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -35,6 +35,65 @@ _TOOL_CALL_MARKER = re.compile(r"^\s*\[TOOL_CALLS\]\s*", re.IGNORECASE)
|
|||||||
|
|
||||||
DB_FLUSH_INTERVAL = 5.0 # seconds between partial DB flushes
|
DB_FLUSH_INTERVAL = 5.0 # seconds between partial DB flushes
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Conditional thinking classifier
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Patterns that force think=True even on short messages
|
||||||
|
_THINK_FORCE = re.compile(
|
||||||
|
r"\b("
|
||||||
|
r"analyz|compar|explain\s+why|help\s+me\s+(think|plan|understand|figure\s+out)|"
|
||||||
|
r"step[- ]by[- ]step|debug|troubleshoot|diagnos|"
|
||||||
|
r"pros\s+and\s+cons|trade[- ]?off|"
|
||||||
|
r"architect|design\s+(a|the|my|this)|"
|
||||||
|
r"write\s+a\s+(detailed|long|comprehensive|full)|"
|
||||||
|
r"brainstorm|outline\s+(a|the|my)|"
|
||||||
|
r"what\s+(are|is)\s+the\s+(best|difference|relationship|impact|implication)|"
|
||||||
|
r"how\s+(do|does|should|would|can)\s+.{0,40}\s+work|"
|
||||||
|
r"why\s+(is|are|does|do|did|would|should)\b"
|
||||||
|
r")",
|
||||||
|
re.IGNORECASE,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Patterns that force think=False regardless of message length
|
||||||
|
_THINK_SKIP = re.compile(
|
||||||
|
r"^(hi|hey|hello|thanks|thank\s+you|ok|okay|got\s+it|sounds\s+good|"
|
||||||
|
r"great|perfect|sure|yes|no|yep|nope|nice|cool|awesome|"
|
||||||
|
r"what('s| is) \d|what time|how many|remind me|add (a |an )?(task|note|reminder)|"
|
||||||
|
r"create (a |an )?(task|note)|delete|update|mark .{0,30} (done|complete))\b",
|
||||||
|
re.IGNORECASE,
|
||||||
|
)
|
||||||
|
|
||||||
|
_WORD_COUNT_THRESHOLD = 60 # messages over this word count always use think=True
|
||||||
|
_SHORT_MESSAGE_THRESHOLD = 12 # messages under this always use think=False
|
||||||
|
|
||||||
|
|
||||||
|
def _should_think(user_content: str, think_requested: bool) -> bool:
|
||||||
|
"""Return whether extended thinking should be used for this request.
|
||||||
|
|
||||||
|
If the caller didn't request thinking, we never enable it. If they did,
|
||||||
|
we check whether the message is complex enough to warrant the overhead.
|
||||||
|
"""
|
||||||
|
if not think_requested:
|
||||||
|
return False
|
||||||
|
|
||||||
|
text = user_content.strip()
|
||||||
|
word_count = len(text.split())
|
||||||
|
|
||||||
|
if word_count <= _SHORT_MESSAGE_THRESHOLD:
|
||||||
|
return False
|
||||||
|
if _THINK_SKIP.match(text):
|
||||||
|
return False
|
||||||
|
if word_count >= _WORD_COUNT_THRESHOLD:
|
||||||
|
return True
|
||||||
|
if "```" in text:
|
||||||
|
return True
|
||||||
|
if _THINK_FORCE.search(text):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
# Human-readable labels for each tool, shown in the status indicator
|
# Human-readable labels for each tool, shown in the status indicator
|
||||||
_TOOL_LABELS: dict[str, str] = {
|
_TOOL_LABELS: dict[str, str] = {
|
||||||
"create_task": "Creating task",
|
"create_task": "Creating task",
|
||||||
@@ -202,6 +261,9 @@ async def run_generation(
|
|||||||
# Emit context event
|
# Emit context event
|
||||||
buf.append_event("context", {"context": context_meta})
|
buf.append_event("context", {"context": context_meta})
|
||||||
|
|
||||||
|
# Apply thinking classifier — downgrade think=True for simple/conversational messages
|
||||||
|
think = _should_think(user_content, think)
|
||||||
|
|
||||||
t_start = time.monotonic()
|
t_start = time.monotonic()
|
||||||
timing: dict = {
|
timing: dict = {
|
||||||
"think": think,
|
"think": think,
|
||||||
|
|||||||
Reference in New Issue
Block a user