elk-stack commited on
Commit
cbf621c
·
verified ·
1 Parent(s): 0e74769

Upload source.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. source.py +157 -0
source.py ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """ThirtySpokes KOTH routing agent — cost-aware cascade + optional verify.
2
+
3
+ Contract required by the measured runtime:
4
+ build_agent(weights) -> agent
5
+ agent(prompt, call_model) -> answer
6
+
7
+ `call_model(model, messages, params)` is the only channel to the owner-pinned pool.
8
+ Answers must come from pool responses (grounding). Always prefer cheaper models and
9
+ escalate only when heuristics say the ask is hard.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import json
15
+ import re
16
+
17
+ # Match the owner's pool-reference generation settings (see docs/MINER.md).
18
+ PARAMS = {"max_tokens": 16384, "reasoning": {"effort": "low"}}
19
+
20
+ # Signals that LiveCodeBench / hard reasoning usually needs a stronger model.
21
+ _HARD_MARKERS = (
22
+ "prove",
23
+ "proof",
24
+ "leetcode",
25
+ "write a function",
26
+ "write a program",
27
+ "implement",
28
+ "algorithm",
29
+ "complexity",
30
+ "def ",
31
+ "class ",
32
+ "```",
33
+ "stdin",
34
+ "stdout",
35
+ "test case",
36
+ "constraints",
37
+ "hard",
38
+ )
39
+
40
+ _CODE_MARKERS = (
41
+ "python",
42
+ "code",
43
+ "function",
44
+ "program",
45
+ "algorithm",
46
+ "compile",
47
+ "runtime error",
48
+ )
49
+
50
+ _WEAK_ANSWER = re.compile(
51
+ r"^\s*(i co(?:uld|n't)|sorry|as an ai|cannot|can't help|not sure|n/?a)\b",
52
+ re.I,
53
+ )
54
+
55
+
56
+ def _load_cfg(weights: bytes) -> dict:
57
+ try:
58
+ cfg = json.loads(weights.decode() if isinstance(weights, (bytes, bytearray)) else weights)
59
+ except Exception:
60
+ cfg = {}
61
+ if not isinstance(cfg, dict):
62
+ cfg = {}
63
+ # Defaults align with MockPool model ids for local smoke; override via weights.bin for mainnet.
64
+ cheap = cfg.get("cheap") or cfg.get("model") or "cheap"
65
+ mid = cfg.get("mid") or cheap
66
+ strong = cfg.get("strong") or mid
67
+ return {
68
+ "cheap": cheap,
69
+ "mid": mid,
70
+ "strong": strong,
71
+ "escalate_chars": int(cfg.get("escalate_chars", 400)),
72
+ "verify": bool(cfg.get("verify", True)),
73
+ "verify_on_code": bool(cfg.get("verify_on_code", True)),
74
+ "max_calls": int(cfg.get("max_calls", 3)),
75
+ }
76
+
77
+
78
+ def _looks_hard(prompt: str, escalate_chars: int) -> bool:
79
+ p = prompt or ""
80
+ pl = p.lower()
81
+ if len(p) >= escalate_chars:
82
+ return True
83
+ if any(m in pl for m in _HARD_MARKERS):
84
+ return True
85
+ # Many coding tasks include multi-line specs / sample IO.
86
+ if pl.count("\n") >= 8 and any(m in pl for m in _CODE_MARKERS):
87
+ return True
88
+ return False
89
+
90
+
91
+ def _looks_code(prompt: str) -> bool:
92
+ pl = (prompt or "").lower()
93
+ return any(m in pl for m in _CODE_MARKERS) or "```" in pl or "def " in pl
94
+
95
+
96
+ def _is_weak(answer: str) -> bool:
97
+ if not answer or not str(answer).strip():
98
+ return True
99
+ text = str(answer).strip()
100
+ if len(text) < 8:
101
+ return True
102
+ if _WEAK_ANSWER.search(text):
103
+ return True
104
+ return False
105
+
106
+
107
+ def _call(call_model, model: str, prompt: str) -> str:
108
+ return call_model(model, [{"role": "user", "content": prompt}], PARAMS)
109
+
110
+
111
+ def build_agent(weights):
112
+ cfg = _load_cfg(weights)
113
+ cheap, mid, strong = cfg["cheap"], cfg["mid"], cfg["strong"]
114
+ escalate_chars = cfg["escalate_chars"]
115
+ do_verify = cfg["verify"]
116
+ verify_on_code = cfg["verify_on_code"]
117
+ max_calls = max(1, cfg["max_calls"])
118
+
119
+ def agent(prompt, call_model):
120
+ calls = 0
121
+ hard = _looks_hard(prompt, escalate_chars)
122
+ codey = _looks_code(prompt)
123
+
124
+ # 1) Cheap first on easy asks; mid/strong first on hard asks to avoid wasted cheap fails.
125
+ first = mid if hard else cheap
126
+ ans = _call(call_model, first, prompt)
127
+ calls += 1
128
+ chosen = first
129
+
130
+ # 2) Escalate if the cheap/mid answer looks weak or the ask is hard and we started cheap.
131
+ if calls < max_calls and (_is_weak(ans) or (hard and chosen == cheap)):
132
+ nxt = strong if chosen != strong else mid
133
+ if nxt != chosen:
134
+ ans = _call(call_model, nxt, prompt)
135
+ calls += 1
136
+ chosen = nxt
137
+
138
+ # 3) Optional verify: on code/hard tasks, ask a different model and keep the longer
139
+ # grounded pool response when the first looks thin. Still returns pool text only.
140
+ if (
141
+ do_verify
142
+ and calls < max_calls
143
+ and (hard or (verify_on_code and codey))
144
+ and chosen != strong
145
+ ):
146
+ alt = _call(call_model, strong, prompt)
147
+ calls += 1
148
+ if _is_weak(ans) or (not _is_weak(alt) and len(str(alt)) > len(str(ans)) * 1.15):
149
+ ans = alt
150
+
151
+ # Final grounding fallback: never return empty — one more strong call if needed.
152
+ if _is_weak(ans) and calls < max_calls and chosen != strong:
153
+ ans = _call(call_model, strong, prompt)
154
+
155
+ return ans
156
+
157
+ return agent