lynkr 9.9.0 → 9.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -23
- package/bin/cli.js +13 -7
- package/bin/lynkr-init.js +34 -12
- package/bin/lynkr-reset.js +71 -0
- package/config/model-tiers.json +199 -52
- package/package.json +3 -3
- package/scripts/build-eval-set.js +256 -0
- package/scripts/mine-difficulty-anchors.js +288 -0
- package/scripts/validate-difficulty-classifier.js +144 -0
- package/scripts/validate-intent-anchors.js +186 -0
- package/src/api/providers-handler.js +0 -1
- package/src/api/router.js +292 -160
- package/src/clients/databricks.js +95 -6
- package/src/config/index.js +3 -43
- package/src/context/tool-result-compressor.js +883 -40
- package/src/orchestrator/index.js +117 -1235
- package/src/orchestrator/passthrough-stream.js +382 -0
- package/src/orchestrator/sse-transformer.js +408 -0
- package/src/routing/affinity-store.js +17 -3
- package/src/routing/classifier-setup.js +207 -0
- package/src/routing/complexity-analyzer.js +40 -4
- package/src/routing/difficulty-classifier.js +261 -0
- package/src/routing/index.js +70 -7
- package/src/routing/intent-score.js +132 -12
- package/src/routing/session-affinity.js +8 -1
- package/src/routing/side-channel-detector.js +103 -0
- package/src/server.js +20 -46
- package/src/agents/context-manager.js +0 -236
- package/src/agents/decomposition/dispatcher.js +0 -185
- package/src/agents/decomposition/gate.js +0 -136
- package/src/agents/decomposition/index.js +0 -183
- package/src/agents/decomposition/model-call.js +0 -75
- package/src/agents/decomposition/planner.js +0 -223
- package/src/agents/decomposition/synthesizer.js +0 -89
- package/src/agents/decomposition/telemetry.js +0 -55
- package/src/agents/definitions/loader.js +0 -653
- package/src/agents/executor.js +0 -457
- package/src/agents/index.js +0 -165
- package/src/agents/parallel-coordinator.js +0 -68
- package/src/agents/reflector.js +0 -331
- package/src/agents/skillbook.js +0 -331
- package/src/agents/store.js +0 -259
- package/src/edits/index.js +0 -171
- package/src/indexer/babel-parser.js +0 -213
- package/src/indexer/index.js +0 -1629
- package/src/indexer/navigation/index.js +0 -32
- package/src/indexer/navigation/providers/treeSitter.js +0 -36
- package/src/indexer/parser.js +0 -443
- package/src/tasks/store.js +0 -349
- package/src/tests/coverage.js +0 -173
- package/src/tests/index.js +0 -171
- package/src/tests/store.js +0 -213
- package/src/tools/agent-task.js +0 -145
- package/src/tools/code-mode.js +0 -304
- package/src/tools/decompose.js +0 -91
- package/src/tools/edits.js +0 -94
- package/src/tools/execution.js +0 -171
- package/src/tools/git.js +0 -1346
- package/src/tools/index.js +0 -306
- package/src/tools/indexer.js +0 -360
- package/src/tools/lazy-loader.js +0 -366
- package/src/tools/mcp-remote.js +0 -88
- package/src/tools/mcp.js +0 -116
- package/src/tools/process.js +0 -167
- package/src/tools/smart-selection.js +0 -180
- package/src/tools/stubs.js +0 -55
- package/src/tools/tasks.js +0 -260
- package/src/tools/tests.js +0 -132
- package/src/tools/tinyfish.js +0 -358
- package/src/tools/truncate.js +0 -106
- package/src/tools/web-client.js +0 -71
- package/src/tools/web.js +0 -415
- package/src/tools/workspace.js +0 -204
package/config/model-tiers.json
CHANGED
|
@@ -2,80 +2,226 @@
|
|
|
2
2
|
"tiers": {
|
|
3
3
|
"SIMPLE": {
|
|
4
4
|
"description": "Greetings, simple Q&A, confirmations, basic lookups",
|
|
5
|
-
"range": [
|
|
5
|
+
"range": [
|
|
6
|
+
0,
|
|
7
|
+
25
|
|
8
|
+
],
|
|
6
9
|
"priority": 1,
|
|
7
10
|
"preferred": {
|
|
8
|
-
"ollama": [
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
|
|
11
|
+
"ollama": [
|
|
12
|
+
"llama3.2",
|
|
13
|
+
"gemma2",
|
|
14
|
+
"phi3",
|
|
15
|
+
"qwen2.5:7b",
|
|
16
|
+
"mistral"
|
|
17
|
+
],
|
|
18
|
+
"llamacpp": [
|
|
19
|
+
"default"
|
|
20
|
+
],
|
|
21
|
+
"lmstudio": [
|
|
22
|
+
"default"
|
|
23
|
+
],
|
|
24
|
+
"openai": [
|
|
25
|
+
"gpt-4o-mini",
|
|
26
|
+
"gpt-3.5-turbo"
|
|
27
|
+
],
|
|
28
|
+
"azure-openai": [
|
|
29
|
+
"gpt-4o-mini",
|
|
30
|
+
"gpt-35-turbo"
|
|
31
|
+
],
|
|
32
|
+
"anthropic": [
|
|
33
|
+
"claude-3-haiku-20240307",
|
|
34
|
+
"claude-3-5-haiku-20241022"
|
|
35
|
+
],
|
|
36
|
+
"bedrock": [
|
|
37
|
+
"anthropic.claude-3-haiku-20240307-v1:0",
|
|
38
|
+
"amazon.nova-lite-v1:0"
|
|
39
|
+
],
|
|
40
|
+
"databricks": [
|
|
41
|
+
"databricks-claude-haiku-4-5",
|
|
42
|
+
"databricks-gpt-5-nano"
|
|
43
|
+
],
|
|
44
|
+
"google": [
|
|
45
|
+
"gemini-2.0-flash",
|
|
46
|
+
"gemini-1.5-flash"
|
|
47
|
+
],
|
|
48
|
+
"openrouter": [
|
|
49
|
+
"google/gemini-flash-1.5",
|
|
50
|
+
"deepseek/deepseek-chat"
|
|
51
|
+
],
|
|
52
|
+
"zai": [
|
|
53
|
+
"GLM-4-Flash"
|
|
54
|
+
],
|
|
55
|
+
"moonshot": [
|
|
56
|
+
"kimi-k2-turbo-preview"
|
|
57
|
+
]
|
|
20
58
|
}
|
|
21
59
|
},
|
|
22
60
|
"MEDIUM": {
|
|
23
61
|
"description": "Code reading, simple edits, research, documentation",
|
|
24
|
-
"range": [
|
|
62
|
+
"range": [
|
|
63
|
+
26,
|
|
64
|
+
50
|
|
65
|
+
],
|
|
25
66
|
"priority": 2,
|
|
26
67
|
"preferred": {
|
|
27
|
-
"ollama": [
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"
|
|
68
|
+
"ollama": [
|
|
69
|
+
"qwen2.5:32b",
|
|
70
|
+
"deepseek-coder:33b",
|
|
71
|
+
"codellama:34b"
|
|
72
|
+
],
|
|
73
|
+
"llamacpp": [
|
|
74
|
+
"default"
|
|
75
|
+
],
|
|
76
|
+
"lmstudio": [
|
|
77
|
+
"default"
|
|
78
|
+
],
|
|
79
|
+
"openai": [
|
|
80
|
+
"gpt-4o",
|
|
81
|
+
"gpt-4-turbo"
|
|
82
|
+
],
|
|
83
|
+
"azure-openai": [
|
|
84
|
+
"gpt-4o",
|
|
85
|
+
"gpt-4"
|
|
86
|
+
],
|
|
87
|
+
"anthropic": [
|
|
88
|
+
"claude-sonnet-4-20250514",
|
|
89
|
+
"claude-3-5-sonnet-20241022"
|
|
90
|
+
],
|
|
91
|
+
"bedrock": [
|
|
92
|
+
"anthropic.claude-3-5-sonnet-20241022-v2:0",
|
|
93
|
+
"amazon.nova-pro-v1:0"
|
|
94
|
+
],
|
|
95
|
+
"databricks": [
|
|
96
|
+
"databricks-claude-sonnet-4-5",
|
|
97
|
+
"databricks-gpt-5-1"
|
|
98
|
+
],
|
|
99
|
+
"google": [
|
|
100
|
+
"gemini-1.5-pro",
|
|
101
|
+
"gemini-2.0-pro"
|
|
102
|
+
],
|
|
103
|
+
"openrouter": [
|
|
104
|
+
"anthropic/claude-3.5-sonnet",
|
|
105
|
+
"openai/gpt-4o"
|
|
106
|
+
],
|
|
107
|
+
"zai": [
|
|
108
|
+
"GLM-4.7"
|
|
109
|
+
],
|
|
110
|
+
"moonshot": [
|
|
111
|
+
"kimi-k2-turbo-preview"
|
|
112
|
+
]
|
|
39
113
|
}
|
|
40
114
|
},
|
|
41
115
|
"COMPLEX": {
|
|
42
116
|
"description": "Multi-file changes, debugging, architecture, refactoring",
|
|
43
|
-
"range": [
|
|
117
|
+
"range": [
|
|
118
|
+
51,
|
|
119
|
+
75
|
|
120
|
+
],
|
|
44
121
|
"priority": 3,
|
|
45
122
|
"preferred": {
|
|
46
|
-
"ollama": [
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
123
|
+
"ollama": [
|
|
124
|
+
"qwen2.5:72b",
|
|
125
|
+
"llama3.1:70b",
|
|
126
|
+
"deepseek-coder-v2:236b"
|
|
127
|
+
],
|
|
128
|
+
"openai": [
|
|
129
|
+
"o1-mini",
|
|
130
|
+
"o3-mini",
|
|
131
|
+
"gpt-4o"
|
|
132
|
+
],
|
|
133
|
+
"azure-openai": [
|
|
134
|
+
"o1-mini",
|
|
135
|
+
"gpt-4o"
|
|
136
|
+
],
|
|
137
|
+
"anthropic": [
|
|
138
|
+
"claude-sonnet-4-20250514",
|
|
139
|
+
"claude-3-5-sonnet-20241022"
|
|
140
|
+
],
|
|
141
|
+
"bedrock": [
|
|
142
|
+
"anthropic.claude-3-5-sonnet-20241022-v2:0"
|
|
143
|
+
],
|
|
144
|
+
"databricks": [
|
|
145
|
+
"databricks-claude-sonnet-4-5",
|
|
146
|
+
"databricks-gpt-5-1-codex-max"
|
|
147
|
+
],
|
|
148
|
+
"google": [
|
|
149
|
+
"gemini-2.5-pro",
|
|
150
|
+
"gemini-1.5-pro"
|
|
151
|
+
],
|
|
152
|
+
"openrouter": [
|
|
153
|
+
"anthropic/claude-3.5-sonnet",
|
|
154
|
+
"meta-llama/llama-3.1-405b"
|
|
155
|
+
],
|
|
156
|
+
"zai": [
|
|
157
|
+
"GLM-4.7"
|
|
158
|
+
],
|
|
159
|
+
"moonshot": [
|
|
160
|
+
"kimi-k2-turbo-preview"
|
|
161
|
+
]
|
|
56
162
|
}
|
|
57
163
|
},
|
|
58
164
|
"REASONING": {
|
|
59
165
|
"description": "Complex analysis, security audits, novel problems, deep thinking",
|
|
60
|
-
"range": [
|
|
166
|
+
"range": [
|
|
167
|
+
76,
|
|
168
|
+
100
|
|
169
|
+
],
|
|
61
170
|
"priority": 4,
|
|
62
171
|
"preferred": {
|
|
63
|
-
"openai": [
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
"
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
172
|
+
"openai": [
|
|
173
|
+
"o1",
|
|
174
|
+
"o1-pro",
|
|
175
|
+
"o3"
|
|
176
|
+
],
|
|
177
|
+
"azure-openai": [
|
|
178
|
+
"o1",
|
|
179
|
+
"o1-pro"
|
|
180
|
+
],
|
|
181
|
+
"anthropic": [
|
|
182
|
+
"claude-opus-4-20250514",
|
|
183
|
+
"claude-3-opus-20240229"
|
|
184
|
+
],
|
|
185
|
+
"bedrock": [
|
|
186
|
+
"anthropic.claude-3-opus-20240229-v1:0"
|
|
187
|
+
],
|
|
188
|
+
"databricks": [
|
|
189
|
+
"databricks-claude-opus-4-6",
|
|
190
|
+
"databricks-claude-opus-4-5",
|
|
191
|
+
"databricks-gpt-5-2"
|
|
192
|
+
],
|
|
193
|
+
"google": [
|
|
194
|
+
"gemini-2.5-pro"
|
|
195
|
+
],
|
|
196
|
+
"openrouter": [
|
|
197
|
+
"anthropic/claude-3-opus",
|
|
198
|
+
"deepseek/deepseek-reasoner",
|
|
199
|
+
"openai/o1"
|
|
200
|
+
],
|
|
201
|
+
"deepseek": [
|
|
202
|
+
"deepseek-reasoner",
|
|
203
|
+
"deepseek-r1"
|
|
204
|
+
],
|
|
205
|
+
"moonshot": [
|
|
206
|
+
"kimi-k2-thinking",
|
|
207
|
+
"kimi-k2-turbo-preview"
|
|
208
|
+
]
|
|
72
209
|
}
|
|
73
210
|
}
|
|
74
211
|
},
|
|
75
212
|
"localProviders": {
|
|
76
|
-
"ollama": {
|
|
77
|
-
|
|
78
|
-
|
|
213
|
+
"ollama": {
|
|
214
|
+
"free": true,
|
|
215
|
+
"defaultTier": "SIMPLE"
|
|
216
|
+
},
|
|
217
|
+
"llamacpp": {
|
|
218
|
+
"free": true,
|
|
219
|
+
"defaultTier": "SIMPLE"
|
|
220
|
+
},
|
|
221
|
+
"lmstudio": {
|
|
222
|
+
"free": true,
|
|
223
|
+
"defaultTier": "SIMPLE"
|
|
224
|
+
}
|
|
79
225
|
},
|
|
80
226
|
"providerAliases": {
|
|
81
227
|
"azure": "azure-openai",
|
|
@@ -84,6 +230,7 @@
|
|
|
84
230
|
"claude": "anthropic",
|
|
85
231
|
"gemini": "google",
|
|
86
232
|
"vertex": "google",
|
|
87
|
-
"kimi": "moonshot"
|
|
233
|
+
"kimi": "moonshot",
|
|
234
|
+
"z-ai": "zai"
|
|
88
235
|
}
|
|
89
|
-
}
|
|
236
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lynkr",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.10.0",
|
|
4
4
|
"files": [
|
|
5
5
|
"index.js",
|
|
6
6
|
"install.sh",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"dev": "nodemon index.js",
|
|
37
37
|
"lint": "eslint src index.js",
|
|
38
38
|
"test": "npm run test:unit && npm run test:performance",
|
|
39
|
-
"test:unit": "DATABRICKS_API_KEY=test-key DATABRICKS_API_BASE=http://test.com LOG_FILE_ENABLED=false node --test test/routing.test.js test/hybrid-routing-integration.test.js test/
|
|
39
|
+
"test:unit": "DATABRICKS_API_KEY=test-key DATABRICKS_API_BASE=http://test.com LOG_FILE_ENABLED=false node --test test/routing.test.js test/hybrid-routing-integration.test.js test/retry-logic.test.js test/sse-transformer.test.js test/passthrough-stream.test.js test/passthrough-mode.test.js test/openrouter-error-resilience.test.js test/format-conversion.test.js test/azure-openai-config.test.js test/azure-openai-format-conversion.test.js test/azure-openai-routing.test.js test/azure-openai-streaming.test.js test/azure-openai-error-resilience.test.js test/azure-openai-integration.test.js test/openai-integration.test.js test/toon-compression.test.js test/gcf-compression.test.js test/llamacpp-integration.test.js test/resilience.test.js test/telemetry-routing.test.js test/memory/store.test.js test/memory/surprise.test.js test/memory/extractor.test.js test/memory/search.test.js test/memory/retriever.test.js test/distill.test.js test/large-payload.test.js test/prompt-cache-injection.test.js test/risk-analyzer.test.js test/interaction-block.test.js test/preflight.test.js test/token-reduction.test.js test/session-affinity.test.js test/model-registry-cost.test.js test/output-format-guard.test.js test/tier-fallback.test.js test/wrap.test.js test/init.test.js test/tool-call-response-metadata.test.js test/degradation.test.js test/routing-telemetry-columns.test.js test/sticky-routing.test.js test/knn-ambiguous-escalate.test.js test/deescalator.test.js test/client-profiles.test.js test/strip-internal-fields.test.js test/complexity-tool-subtraction.test.js test/bandit.test.js test/routing-propensity.test.js test/reward-pipeline.test.js test/knn-cold-start.test.js test/calibration.test.js test/feedback-loop.test.js test/session-fingerprint.test.js test/side-request-guards.test.js test/verifier.test.js test/intent-score.test.js test/difficulty-classifier.test.js test/classifier-setup.test.js test/usage-stats.test.js test/loop-guard.test.js",
|
|
40
40
|
"test:memory": "DATABRICKS_API_KEY=test-key DATABRICKS_API_BASE=http://test.com node --test test/memory/store.test.js test/memory/surprise.test.js test/memory/extractor.test.js test/memory/search.test.js test/memory/retriever.test.js",
|
|
41
41
|
"test:new-features": "DATABRICKS_API_KEY=test-key DATABRICKS_API_BASE=http://test.com node --test test/passthrough-mode.test.js test/openrouter-error-resilience.test.js test/format-conversion.test.js",
|
|
42
42
|
"test:performance": "DATABRICKS_API_KEY=test-key DATABRICKS_API_BASE=http://test.com node test/hybrid-routing-performance.test.js && DATABRICKS_API_KEY=test-key DATABRICKS_API_BASE=http://test.com node test/performance-tests.js",
|
|
@@ -124,4 +124,4 @@
|
|
|
124
124
|
"nodemon": "^3.1.0",
|
|
125
125
|
"pino-pretty": "^10.2.0"
|
|
126
126
|
}
|
|
127
|
-
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Build the difficulty-classifier evaluation set.
|
|
4
|
+
*
|
|
5
|
+
* Sources (all zero-cost, no LLM judge required):
|
|
6
|
+
* 1. RouterArena unused rows — native empirical difficulty labels
|
|
7
|
+
* (easy/medium/hard from 42-model pass rate). No LLM involved.
|
|
8
|
+
* 2. routellm/gpt4_dataset unused rows — native mixtral_score 1–5
|
|
9
|
+
* (GPT-4-judged when the dataset was built). No LLM involved.
|
|
10
|
+
* 3. Hand-crafted coding-agent-flavored prompts — representative of
|
|
11
|
+
* Lynkr's real traffic (real logs proved too thin, ~7 unique prompts).
|
|
12
|
+
*
|
|
13
|
+
* Leak avoidance: skip any text already in data/difficulty-anchors.provenance.json
|
|
14
|
+
* (the mined anchor set) so eval and anchors don't overlap.
|
|
15
|
+
*
|
|
16
|
+
* Label → tier mapping:
|
|
17
|
+
* RouterArena easy → MEDIUM (any competent model handles)
|
|
18
|
+
* RouterArena medium → COMPLEX (needs strong general model)
|
|
19
|
+
* RouterArena hard → REASONING (frontier model territory)
|
|
20
|
+
* gpt4_dataset score 5 → MEDIUM (Mixtral got it right — trivially easy)
|
|
21
|
+
* gpt4_dataset score 3–4 → COMPLEX (Mixtral partial — real difficulty)
|
|
22
|
+
* gpt4_dataset score 1–2 → REASONING (Mixtral failed — top-tier work)
|
|
23
|
+
*
|
|
24
|
+
* Output: data/difficulty-eval.jsonl (gitignored)
|
|
25
|
+
* Usage: node scripts/build-eval-set.js
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
const fs = require("fs");
|
|
29
|
+
const path = require("path");
|
|
30
|
+
|
|
31
|
+
const DS_SERVER = "https://datasets-server.huggingface.co/rows";
|
|
32
|
+
const OUT_FILE = path.join(__dirname, "../data/difficulty-eval.jsonl");
|
|
33
|
+
const PROVENANCE = path.join(__dirname, "../data/difficulty-anchors.provenance.json");
|
|
34
|
+
|
|
35
|
+
const TARGETS = { routerarena: 200, gpt4_dataset: 200 };
|
|
36
|
+
|
|
37
|
+
function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
|
|
38
|
+
|
|
39
|
+
async function fetchRows(dataset, config, split, offset, length) {
|
|
40
|
+
const url = `${DS_SERVER}?dataset=${encodeURIComponent(dataset)}&config=${config}&split=${split}&offset=${offset}&length=${length}`;
|
|
41
|
+
for (let a = 0; a < 5; a++) {
|
|
42
|
+
try {
|
|
43
|
+
const res = await fetch(url);
|
|
44
|
+
if (res.status === 429) { await sleep(3000 * (a + 1)); continue; }
|
|
45
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
46
|
+
return (await res.json()).rows?.map(r => r.row) || [];
|
|
47
|
+
} catch (err) {
|
|
48
|
+
if (a === 4) return [];
|
|
49
|
+
await sleep(1500 * (a + 1));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function clean(text) {
|
|
56
|
+
if (typeof text !== "string") return null;
|
|
57
|
+
const t = text.replace(/\s+/g, " ").trim();
|
|
58
|
+
if (t.length < 15 || t.length > 400) return null;
|
|
59
|
+
if (/\(\s*\)/.test(t) || /_{3,}/.test(t)) return null;
|
|
60
|
+
if (/\b[A-D]\)\s/.test(t) || /which of the following/i.test(t)) return null;
|
|
61
|
+
if (/\b(premise|hypothesis)\b/i.test(t) && /\b(entail|inference|contradict)\b/i.test(t)) return null;
|
|
62
|
+
if (/NAME_\d|\{\{.*\}\}/.test(t)) return null;
|
|
63
|
+
const nonAscii = (t.match(/[^\x20-\x7E]/g) || []).length;
|
|
64
|
+
if (nonAscii > t.length * 0.1) return null;
|
|
65
|
+
return t;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function isQuizbowlStyle(t) {
|
|
69
|
+
return /^(this |one |a \d{4} (book|work|paper)|fictional |in one (work|section))/i.test(t) ||
|
|
70
|
+
/\([A-Za-z]+-[A-Z][A-Za-z-]+\)/.test(t);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Hand-crafted coding-agent-flavored prompts by tier. Reflects real Lynkr
|
|
74
|
+
// traffic shape (imperatives, technical vocabulary, mix of simple/mechanical/
|
|
75
|
+
// systemic/rigorous). Labels are mine — the honest reviewer for this session.
|
|
76
|
+
const HAND_EVAL = [
|
|
77
|
+
// SIMPLE — casual/acks
|
|
78
|
+
{ text: "hi", tier: "SIMPLE" },
|
|
79
|
+
{ text: "hello", tier: "SIMPLE" },
|
|
80
|
+
{ text: "ok thanks", tier: "SIMPLE" },
|
|
81
|
+
{ text: "yes continue", tier: "SIMPLE" },
|
|
82
|
+
{ text: "no skip that", tier: "SIMPLE" },
|
|
83
|
+
{ text: "got it", tier: "SIMPLE" },
|
|
84
|
+
{ text: "sure go ahead", tier: "SIMPLE" },
|
|
85
|
+
{ text: "what time is it", tier: "SIMPLE" },
|
|
86
|
+
{ text: "cool", tier: "SIMPLE" },
|
|
87
|
+
{ text: "makes sense", tier: "SIMPLE" },
|
|
88
|
+
{ text: "thanks a lot", tier: "SIMPLE" },
|
|
89
|
+
{ text: "hey there", tier: "SIMPLE" },
|
|
90
|
+
{ text: "yep proceed", tier: "SIMPLE" },
|
|
91
|
+
{ text: "great work", tier: "SIMPLE" },
|
|
92
|
+
{ text: "no worries", tier: "SIMPLE" },
|
|
93
|
+
// MEDIUM — one specific mechanical task
|
|
94
|
+
{ text: "list the exports from src/router.js", tier: "MEDIUM" },
|
|
95
|
+
{ text: "run the unit tests and summarize failures", tier: "MEDIUM" },
|
|
96
|
+
{ text: "show me the git diff for this file", tier: "MEDIUM" },
|
|
97
|
+
{ text: "what does this function do", tier: "MEDIUM" },
|
|
98
|
+
{ text: "explain this regex pattern to me", tier: "MEDIUM" },
|
|
99
|
+
{ text: "add error handling to this try block", tier: "MEDIUM" },
|
|
100
|
+
{ text: "fix the linter warnings in this file", tier: "MEDIUM" },
|
|
101
|
+
{ text: "write a unit test for the login helper", tier: "MEDIUM" },
|
|
102
|
+
{ text: "convert this callback to async/await", tier: "MEDIUM" },
|
|
103
|
+
{ text: "add a null check before this dereference", tier: "MEDIUM" },
|
|
104
|
+
{ text: "rename this variable to something more descriptive", tier: "MEDIUM" },
|
|
105
|
+
{ text: "extract this into a helper function", tier: "MEDIUM" },
|
|
106
|
+
{ text: "add a docstring to this method", tier: "MEDIUM" },
|
|
107
|
+
{ text: "check if this file has any TODO comments", tier: "MEDIUM" },
|
|
108
|
+
{ text: "search the codebase for uses of deprecated API", tier: "MEDIUM" },
|
|
109
|
+
{ text: "install the axios package as a dev dependency", tier: "MEDIUM" },
|
|
110
|
+
{ text: "revert the last commit but keep the working tree", tier: "MEDIUM" },
|
|
111
|
+
{ text: "delete unused imports from this file", tier: "MEDIUM" },
|
|
112
|
+
{ text: "format this JSON blob nicely", tier: "MEDIUM" },
|
|
113
|
+
{ text: "which files were changed in the last commit", tier: "MEDIUM" },
|
|
114
|
+
{ text: "how do I use the fetch API with timeouts", tier: "MEDIUM" },
|
|
115
|
+
{ text: "what's the difference between let and const in JavaScript", tier: "MEDIUM" },
|
|
116
|
+
{ text: "add a rate limit to this endpoint", tier: "MEDIUM" },
|
|
117
|
+
{ text: "grep for TODO in the routing folder", tier: "MEDIUM" },
|
|
118
|
+
{ text: "make this loop use Promise.all instead of sequential awaits", tier: "MEDIUM" },
|
|
119
|
+
// COMPLEX — systemic / design / multi-file
|
|
120
|
+
{ text: "do an architecture review of the orchestrator", tier: "COMPLEX" },
|
|
121
|
+
{ text: "review this retry helper for bugs and race conditions", tier: "COMPLEX" },
|
|
122
|
+
{ text: "refactor the entire ingestion pipeline and give me a plan", tier: "COMPLEX" },
|
|
123
|
+
{ text: "design a horizontally scalable architecture for the router with failure-mode analysis", tier: "COMPLEX" },
|
|
124
|
+
{ text: "code review the PR #84 routing hardening changes", tier: "COMPLEX" },
|
|
125
|
+
{ text: "analyze every module in src/ for circular dependencies", tier: "COMPLEX" },
|
|
126
|
+
{ text: "debug this complex race condition in the connection pool", tier: "COMPLEX" },
|
|
127
|
+
{ text: "plan a zero-downtime migration to the new schema", tier: "COMPLEX" },
|
|
128
|
+
{ text: "implement a distributed rate limiter with Redis backing", tier: "COMPLEX" },
|
|
129
|
+
{ text: "design the caching strategy for this API gateway including invalidation rules", tier: "COMPLEX" },
|
|
130
|
+
{ text: "trace through the request lifecycle end to end and identify bottlenecks", tier: "COMPLEX" },
|
|
131
|
+
{ text: "restructure the module boundaries to reduce coupling between core and plugins", tier: "COMPLEX" },
|
|
132
|
+
{ text: "propose a testing strategy for the new streaming pipeline covering edge cases", tier: "COMPLEX" },
|
|
133
|
+
{ text: "identify all the places in the codebase that depend on the legacy auth flow and plan the deprecation", tier: "COMPLEX" },
|
|
134
|
+
{ text: "walk me through how the tier routing decision cascade works and highlight the weak points", tier: "COMPLEX" },
|
|
135
|
+
{ text: "compare our current queueing implementation against BullMQ and recommend a migration path", tier: "COMPLEX" },
|
|
136
|
+
{ text: "extract the shared session logic into a separate package and update all consumers", tier: "COMPLEX" },
|
|
137
|
+
{ text: "design the observability layer for the multi-tenant deployment with per-tenant metrics", tier: "COMPLEX" },
|
|
138
|
+
{ text: "diagnose why the latency P99 spiked yesterday afternoon across the fleet", tier: "COMPLEX" },
|
|
139
|
+
{ text: "plan the sharding strategy for the telemetry database as we scale to 10x traffic", tier: "COMPLEX" },
|
|
140
|
+
{ text: "audit the codebase for uses of unsafe eval and propose safe replacements", tier: "COMPLEX" },
|
|
141
|
+
{ text: "propose a graceful degradation plan for when the primary embedding model is unavailable", tier: "COMPLEX" },
|
|
142
|
+
{ text: "review the error handling across the client SDK and standardize on a single pattern", tier: "COMPLEX" },
|
|
143
|
+
{ text: "outline the migration from the monolith to a services split with backwards compatibility", tier: "COMPLEX" },
|
|
144
|
+
{ text: "reason about whether this cache invalidation scheme is correct under concurrent writes", tier: "COMPLEX" },
|
|
145
|
+
// REASONING — proof / audit / formal / deep
|
|
146
|
+
{ text: "prove the correctness of this lock-free queue implementation and identify any ABA hazards", tier: "REASONING" },
|
|
147
|
+
{ text: "security audit the authentication middleware for token reuse vulnerabilities", tier: "REASONING" },
|
|
148
|
+
{ text: "derive the optimal cache eviction policy for this access pattern and prove its competitive ratio", tier: "REASONING" },
|
|
149
|
+
{ text: "formally verify that this state machine can never deadlock or produce a counterexample trace", tier: "REASONING" },
|
|
150
|
+
{ text: "from first principles design a Byzantine-fault-tolerant consensus variant tolerating f faults with 2f+1 replicas", tier: "REASONING" },
|
|
151
|
+
{ text: "think deeply about why this floating-point summation loses precision at scale and derive the compensated algorithm", tier: "REASONING" },
|
|
152
|
+
{ text: "prove this rate limiter is fair under concurrent refill or construct the starvation schedule that breaks it", tier: "REASONING" },
|
|
153
|
+
{ text: "reason through the exact memory ordering constraints this concurrent hashmap needs on ARM and justify each barrier", tier: "REASONING" },
|
|
154
|
+
{ text: "given these heap dumps reason to the retention path causing the leak and rule out the two most plausible alternatives", tier: "REASONING" },
|
|
155
|
+
{ text: "ultrathink: analyze whether this online schema migration can preserve every invariant the application relies on", tier: "REASONING" },
|
|
156
|
+
{ text: "verify no path in this state machine violates the safety property that read never observes a partial write", tier: "REASONING" },
|
|
157
|
+
{ text: "derive the amortized complexity bound for this splay tree under this adversarial access pattern and prove it tight", tier: "REASONING" },
|
|
158
|
+
{ text: "prove that this distributed algorithm makes progress under fair scheduling regardless of message reordering", tier: "REASONING" },
|
|
159
|
+
{ text: "penetration test the session token handling and enumerate every replay attack vector", tier: "REASONING" },
|
|
160
|
+
{ text: "formal proof that this compensation transaction preserves ACID under partial-failure scenarios", tier: "REASONING" },
|
|
161
|
+
{ text: "reason from first principles about whether exactly-once semantics are achievable on top of this at-least-once queue", tier: "REASONING" },
|
|
162
|
+
{ text: "vulnerability scan the recently-added crypto path for downgrade attacks and misuse of primitives", tier: "REASONING" },
|
|
163
|
+
{ text: "prove that this garbage collector will always terminate on any input given the described root set", tier: "REASONING" },
|
|
164
|
+
{ text: "verify the linearizability of this concurrent skip list using the linearization-point argument", tier: "REASONING" },
|
|
165
|
+
{ text: "think hard about which of these three algorithms actually preserves invariant I under crash recovery and which only appears to", tier: "REASONING" },
|
|
166
|
+
];
|
|
167
|
+
|
|
168
|
+
async function main() {
|
|
169
|
+
const seenTexts = new Set();
|
|
170
|
+
try {
|
|
171
|
+
const prov = JSON.parse(fs.readFileSync(PROVENANCE, "utf8"));
|
|
172
|
+
for (const text of Object.keys(prov)) seenTexts.add(text);
|
|
173
|
+
console.log(`Loaded ${seenTexts.size} anchor texts from provenance (excluded from eval)`);
|
|
174
|
+
} catch { /* first run may have no provenance */ }
|
|
175
|
+
|
|
176
|
+
const eval_ = [];
|
|
177
|
+
const seen = new Set([...seenTexts].map(t => t.slice(0, 80)));
|
|
178
|
+
|
|
179
|
+
const add = (text, tier, source, label) => {
|
|
180
|
+
const key = text.slice(0, 80);
|
|
181
|
+
if (seen.has(key)) return false;
|
|
182
|
+
seen.add(key);
|
|
183
|
+
eval_.push({ text, tier, source, label });
|
|
184
|
+
return true;
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
// 1. Hand-crafted prompts (canary + real-traffic representative)
|
|
188
|
+
for (const item of HAND_EVAL) {
|
|
189
|
+
add(item.text, item.tier, "hand", "author-labeled");
|
|
190
|
+
}
|
|
191
|
+
console.log(`Hand-crafted: ${eval_.length} added`);
|
|
192
|
+
|
|
193
|
+
// 2. RouterArena — technical domains only, empirical difficulty labels
|
|
194
|
+
console.log("Fetching RouterArena rows...");
|
|
195
|
+
const TECH_DOMAIN_RE = /computer science|technology|engineering|mathematic|science/i;
|
|
196
|
+
const DATASET_EXCLUDE_RE = /superglue|cloze|entailment/i;
|
|
197
|
+
let raAdded = 0;
|
|
198
|
+
outer: for (let offset = 4000; offset < 8400; offset += 100) {
|
|
199
|
+
const rows = await fetchRows("RouteWorks/RouterArena", "default", "full", offset, 100);
|
|
200
|
+
for (const row of rows) {
|
|
201
|
+
if (raAdded >= TARGETS.routerarena) break outer;
|
|
202
|
+
if (row.Context && String(row.Context).trim()) continue;
|
|
203
|
+
if (Array.isArray(row.Options) && row.Options.length > 0) continue;
|
|
204
|
+
if (DATASET_EXCLUDE_RE.test(String(row["Dataset name"] || ""))) continue;
|
|
205
|
+
const text = clean(row.Question);
|
|
206
|
+
if (!text || isQuizbowlStyle(text)) continue;
|
|
207
|
+
const technical = TECH_DOMAIN_RE.test(String(row.Domain || ""));
|
|
208
|
+
const diff = String(row.Difficulty || "").toLowerCase();
|
|
209
|
+
let tier = null;
|
|
210
|
+
if (diff === "easy") tier = "MEDIUM";
|
|
211
|
+
else if (diff === "medium" && technical) tier = "COMPLEX";
|
|
212
|
+
else if (diff === "hard" && technical) tier = "REASONING";
|
|
213
|
+
if (!tier) continue;
|
|
214
|
+
if (add(text, tier, "RouterArena", `${diff}/${row["Dataset name"]}`)) raAdded++;
|
|
215
|
+
}
|
|
216
|
+
await sleep(200);
|
|
217
|
+
}
|
|
218
|
+
console.log(`RouterArena: +${raAdded}`);
|
|
219
|
+
|
|
220
|
+
// 3. gpt4_dataset — skip pages we mined for anchors (offset 0, 1817, 3634...)
|
|
221
|
+
console.log("Fetching gpt4_dataset rows...");
|
|
222
|
+
let gpAdded = 0;
|
|
223
|
+
outer2: for (let offset = 60000; offset < 109000; offset += 500) {
|
|
224
|
+
const rows = await fetchRows("routellm/gpt4_dataset", "default", "train", offset, 100);
|
|
225
|
+
for (const row of rows) {
|
|
226
|
+
if (gpAdded >= TARGETS.gpt4_dataset) break outer2;
|
|
227
|
+
const text = clean(row.prompt);
|
|
228
|
+
if (!text) continue;
|
|
229
|
+
const score = Number(row.mixtral_score);
|
|
230
|
+
let tier = null;
|
|
231
|
+
if (score === 5) tier = "MEDIUM";
|
|
232
|
+
else if (score === 3 || score === 4) tier = "COMPLEX";
|
|
233
|
+
else if (score === 1 || score === 2) tier = text.length < 60 ? null : "REASONING";
|
|
234
|
+
if (!tier) continue;
|
|
235
|
+
if (add(text, tier, "gpt4_dataset", `mixtral_score=${score}`)) gpAdded++;
|
|
236
|
+
}
|
|
237
|
+
await sleep(200);
|
|
238
|
+
}
|
|
239
|
+
console.log(`gpt4_dataset: +${gpAdded}`);
|
|
240
|
+
|
|
241
|
+
// Shuffle deterministically (session-repro via fixed permutation)
|
|
242
|
+
eval_.sort((a, b) => a.text.length - b.text.length);
|
|
243
|
+
const shuffled = [];
|
|
244
|
+
for (let i = 0; i < eval_.length; i++) {
|
|
245
|
+
const j = (i * 37 + 11) % eval_.length;
|
|
246
|
+
shuffled.push(eval_[j]);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
fs.writeFileSync(OUT_FILE, shuffled.map(r => JSON.stringify(r)).join("\n") + "\n");
|
|
250
|
+
console.log(`\nWrote ${OUT_FILE}: ${shuffled.length} rows`);
|
|
251
|
+
const perTier = {};
|
|
252
|
+
for (const r of shuffled) perTier[r.tier] = (perTier[r.tier] || 0) + 1;
|
|
253
|
+
console.log("Per-tier:", JSON.stringify(perTier));
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
main().catch(err => { console.error(err); process.exit(1); });
|