MCPcopy Create free account
hub / github.com/CommonstackAI/UncommonRoute / classify_clawrouter_v2

Function classify_clawrouter_v2

bench/clawrouter_v2_compat.py:149–206  ·  view source on GitHub ↗

Replicate ClawRouter v2 classifyByRules logic.

(prompt: str, system_prompt: str | None = None)

Source from the content-addressed store, hash-verified

147
148
149def classify_clawrouter_v2(prompt: str, system_prompt: str | None = None) -> tuple[str, float]:
150 """Replicate ClawRouter v2 classifyByRules logic."""
151 full_text = f"{system_prompt or ''} {prompt}"
152 estimated_tokens = max(1, len(full_text) // 4) # original: Math.ceil(length / 4)
153 user_text = prompt.lower()
154
155 # Score dimensions
156 dims: dict[str, float] = {}
157
158 tc_score, _ = _score_token_count(estimated_tokens)
159 dims["tokenCount"] = tc_score
160 dims["codePresence"] = _score_keywords(user_text, CODE_KEYWORDS, 1, 2, 0.5, 1.0)
161 dims["reasoningMarkers"] = _score_keywords(user_text, REASONING_KEYWORDS, 1, 2, 0.7, 1.0)
162 dims["technicalTerms"] = _score_keywords(user_text, TECHNICAL_KEYWORDS, 2, 4, 0.5, 1.0)
163 dims["creativeMarkers"] = _score_keywords(user_text, CREATIVE_KEYWORDS, 1, 2, 0.5, 0.7)
164 dims["simpleIndicators"] = _score_keywords(user_text, SIMPLE_KEYWORDS, 1, 2, -1.0, -1.0)
165 dims["multiStepPatterns"] = _score_multi_step(user_text)
166 dims["questionComplexity"] = _score_question_complexity(prompt)
167 dims["imperativeVerbs"] = _score_keywords(user_text, IMPERATIVE_KEYWORDS, 1, 2, 0.3, 0.5)
168 dims["constraintCount"] = _score_keywords(user_text, CONSTRAINT_KEYWORDS, 1, 3, 0.3, 0.7)
169 dims["outputFormat"] = _score_keywords(user_text, OUTPUT_FORMAT_KEYWORDS, 1, 2, 0.4, 0.7)
170 dims["referenceComplexity"] = _score_keywords(user_text, REFERENCE_KEYWORDS, 1, 2, 0.3, 0.5)
171 dims["negationComplexity"] = _score_keywords(user_text, NEGATION_KEYWORDS, 2, 3, 0.3, 0.5)
172 dims["domainSpecificity"] = _score_keywords(user_text, DOMAIN_KEYWORDS, 1, 2, 0.5, 0.8)
173 dims["agenticTask"] = _score_keywords(user_text, AGENTIC_KEYWORDS, 1, 2, 0.2, 0.5)
174
175 # Reasoning override (from rules.ts)
176 reasoning_matches = sum(1 for kw in REASONING_KEYWORDS if kw.lower() in user_text)
177 if reasoning_matches >= 2:
178 return "REASONING", 0.85
179
180 # Weighted score
181 weighted_score = sum(dims[k] * DIMENSION_WEIGHTS.get(k, 0) for k in dims)
182
183 # Tier mapping
184 sm = TIER_BOUNDARIES["simpleMedium"]
185 mc = TIER_BOUNDARIES["mediumComplex"]
186 cr = TIER_BOUNDARIES["complexReasoning"]
187
188 if weighted_score < sm:
189 tier = "SIMPLE"
190 dist = sm - weighted_score
191 elif weighted_score < mc:
192 tier = "MEDIUM"
193 dist = min(weighted_score - sm, mc - weighted_score)
194 elif weighted_score < cr:
195 tier = "COMPLEX"
196 dist = min(weighted_score - mc, cr - weighted_score)
197 else:
198 tier = "REASONING"
199 dist = weighted_score - cr
200
201 confidence = 1 / (1 + math.exp(-CONFIDENCE_STEEPNESS * dist))
202
203 if confidence < CONFIDENCE_THRESHOLD:
204 tier = "MEDIUM" # ambiguous default
205
206 return tier, confidence

Callers

nothing calls this directly

Calls 5

_score_token_countFunction · 0.85
_score_keywordsFunction · 0.85
_score_multi_stepFunction · 0.85
getMethod · 0.45

Tested by

no test coverage detected