promptimizer 0.1.36 → 0.1.37
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/dist/classify.d.ts +1 -0
- package/dist/index.cjs +81 -35
- package/dist/index.js +81 -35
- package/package.json +1 -1
package/dist/classify.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ChatMessage, Classification, Tier } from "./types";
|
|
2
2
|
export declare function classifyMessages(messages: ChatMessage[]): Classification;
|
|
3
|
+
/** Production classifier — prefer over-routing hard work over silent quality loss. */
|
|
3
4
|
export declare function classifyText(text: string): Classification;
|
|
4
5
|
export declare function difficultyTier(complexity: number): Tier;
|
package/dist/index.cjs
CHANGED
|
@@ -136,6 +136,7 @@ var Promptimizer = class _Promptimizer {
|
|
|
136
136
|
|
|
137
137
|
// src/classify.ts
|
|
138
138
|
var HIGH_RISK = /* @__PURE__ */ new Set(["system_design", "safety_sensitive", "code_debug", "reasoning"]);
|
|
139
|
+
var TIER_RANK = { economy: 0, standard: 1, frontier: 2 };
|
|
139
140
|
function textFrom(messages) {
|
|
140
141
|
return messages.map((m) => {
|
|
141
142
|
if (typeof m.content === "string") return m.content;
|
|
@@ -148,34 +149,46 @@ function classifyMessages(messages) {
|
|
|
148
149
|
function classifyText(text) {
|
|
149
150
|
const words = text.split(/\s+/).filter(Boolean).length;
|
|
150
151
|
const lines = text.split("\n").length;
|
|
152
|
+
const numbered = (text.match(/\(\s*\d+\s*\)/g) ?? []).length + (text.match(/^\s*\d+[\).:]/gm) ?? []).length + (text.match(/\b\d+\.\s+[A-Za-z]/g) ?? []).length;
|
|
153
|
+
const constraintWords = (text.match(
|
|
154
|
+
/\b(must|include|constraint|requirement|requirements|need to|ensure|exactly-once|idempotent)\b/gi
|
|
155
|
+
) ?? []).length;
|
|
151
156
|
const features = {
|
|
152
157
|
code_fence: /```/.test(text),
|
|
153
|
-
code_kw: /\b(def |class |function |import |fn |pub |async |
|
|
158
|
+
code_kw: /\b(def |class |function |import |fn |pub |async |goroutine|mutex|traceback)\b/i.test(text) || /\b(SELECT\b.+\bFROM\b|\bJOIN\b.+\bON\b|postgresql|\bpsql\b)/i.test(text),
|
|
159
|
+
math: /(\$\$|\\frac|prove that|expected value|O\([nN]\)|\d+\s*[\*\^×x]\s*\d+|infinitely many|factorial|prime)/i.test(
|
|
154
160
|
text
|
|
155
161
|
),
|
|
156
|
-
|
|
157
|
-
design: /\b(design|architect|rate limiter|distributed|consistency|shard|1 million QPS)\b/i.test(
|
|
162
|
+
design: /\b(design(?:ing)?|architect(?:ure|ing)?|rate[\s-]?limiter|distributed|consistency|shard(?:ing)?|multi-?region|multi-?tenant|qps|edge regions?|data[\s-]?plane|failure modes?|outbox|ledger|webhook|saas|billing pipeline|consensus|raft|paxos|quorum|leader election|log replication|network partition|cap theorem|eventual consistency|token bucket|sliding window)\b/i.test(
|
|
158
163
|
text
|
|
159
164
|
),
|
|
160
|
-
reason: /\b(prove|why does|walk through|step by step|derive|contradiction|p-value)\b/i.test(
|
|
165
|
+
reason: /\b(prove|proof|theorem|lemma|why does|walk through|step by step|derive|contradiction|p-value|induction|euclid|sketch (?:a |the )?proof)\b/i.test(
|
|
166
|
+
text
|
|
167
|
+
),
|
|
168
|
+
debug: /\b(bug|race|panic|fails on|diagnose|deadlock|concurrency hazard|code review|correctness)\b/i.test(
|
|
161
169
|
text
|
|
162
170
|
),
|
|
163
|
-
debug: /\b(bug|race|panic|fails on|diagnose|deadlock)\b/i.test(text),
|
|
164
171
|
summarize: /\b(summarize|tl;dr|in two sentences|eli5)\b/i.test(text),
|
|
165
172
|
translate: /\b(translate|traduce)\b/i.test(text),
|
|
166
173
|
creative: /\b(write a (poem|story|song)|haiku)\b/i.test(text),
|
|
167
|
-
safety: /\b(refund|legal|medical|hipaa|lawsuit|diagnosis)\b/i.test(
|
|
168
|
-
|
|
169
|
-
|
|
174
|
+
safety: /\b(refund|legal|medical|hipaa|lawsuit|diagnosis|gdpr|erasure|pii|compliance|audit trail)\b/i.test(
|
|
175
|
+
text
|
|
176
|
+
),
|
|
177
|
+
analysis: /\b(compare|trade-?off|versus|analyse|analyze|evaluate|should we|outline architecture)\b/i.test(
|
|
178
|
+
text
|
|
179
|
+
),
|
|
180
|
+
multi_part: numbered >= 3 || numbered >= 2 && constraintWords >= 1,
|
|
181
|
+
constraints: constraintWords + Math.min(4, numbered),
|
|
170
182
|
words,
|
|
171
183
|
lines,
|
|
172
|
-
question_marks: (text.match(/\?/g) ?? []).length
|
|
184
|
+
question_marks: (text.match(/\?/g) ?? []).length,
|
|
185
|
+
long_form: words >= 55 || lines >= 8
|
|
173
186
|
};
|
|
174
187
|
const category = categoryOf(features);
|
|
175
188
|
const complexity = complexityOf(features, category);
|
|
176
189
|
const p_small_quality = pSmallQuality(features, category, complexity);
|
|
177
190
|
const quality_risk = riskOf(category, complexity, p_small_quality);
|
|
178
|
-
const recommended_tier =
|
|
191
|
+
const recommended_tier = recommendTier(p_small_quality, complexity, category, quality_risk);
|
|
179
192
|
const signals = [
|
|
180
193
|
features.code_fence,
|
|
181
194
|
features.code_kw,
|
|
@@ -183,9 +196,10 @@ function classifyText(text) {
|
|
|
183
196
|
features.design,
|
|
184
197
|
features.reason,
|
|
185
198
|
features.debug,
|
|
186
|
-
features.safety
|
|
199
|
+
features.safety,
|
|
200
|
+
features.multi_part
|
|
187
201
|
].filter(Boolean).length;
|
|
188
|
-
const confidence = category === "factual_recall" && words < 16 ? 0.
|
|
202
|
+
const confidence = category === "factual_recall" && words < 16 ? 0.92 : Math.min(0.96, 0.55 + 0.1 * signals);
|
|
189
203
|
return {
|
|
190
204
|
complexity,
|
|
191
205
|
category,
|
|
@@ -201,47 +215,64 @@ function classifyText(text) {
|
|
|
201
215
|
};
|
|
202
216
|
}
|
|
203
217
|
function categoryOf(h) {
|
|
204
|
-
if (h.safety) return "safety_sensitive";
|
|
205
218
|
if (h.design) return "system_design";
|
|
219
|
+
if (h.safety && !h.design) return "safety_sensitive";
|
|
206
220
|
if (h.debug && (h.code_fence || h.code_kw)) return "code_debug";
|
|
207
|
-
if (h.
|
|
221
|
+
if (h.debug && h.long_form) return "code_debug";
|
|
208
222
|
if (h.math && h.reason) return "reasoning";
|
|
209
|
-
if (h.math) return "math";
|
|
210
223
|
if (h.reason) return "reasoning";
|
|
224
|
+
if (h.code_fence || h.code_kw) return "code_generation";
|
|
225
|
+
if (h.math) return "math";
|
|
226
|
+
if (h.safety) return "safety_sensitive";
|
|
211
227
|
if (h.translate) return "translation";
|
|
212
228
|
if (h.summarize) return "summarization";
|
|
213
229
|
if (h.creative) return "creative";
|
|
214
|
-
if (h.analysis) return "analysis";
|
|
215
|
-
if (h.words <
|
|
230
|
+
if (h.analysis || h.multi_part) return "analysis";
|
|
231
|
+
if (h.words < 28 && h.question_marks >= 1) return "factual_recall";
|
|
216
232
|
return h.words > 80 ? "analysis" : "factual_recall";
|
|
217
233
|
}
|
|
218
234
|
function complexityOf(h, category) {
|
|
219
235
|
let score = 1;
|
|
220
|
-
if (h.words >
|
|
221
|
-
if (h.words >
|
|
222
|
-
if (h.lines >
|
|
236
|
+
if (h.words > 35) score += 1;
|
|
237
|
+
if (h.words > 90) score += 1;
|
|
238
|
+
if (h.lines > 10 || h.code_fence) score += 1;
|
|
223
239
|
if (h.constraints >= 2) score += 1;
|
|
224
|
-
if (h.
|
|
240
|
+
if (h.constraints >= 4 || h.multi_part) score += 1;
|
|
241
|
+
if (h.design) score += 1;
|
|
242
|
+
if (h.reason) score += 1;
|
|
225
243
|
if (h.debug) score += 1;
|
|
226
|
-
if (
|
|
227
|
-
if (category === "
|
|
244
|
+
if (h.safety && (h.design || h.multi_part)) score += 1;
|
|
245
|
+
if (category === "system_design") score = Math.max(score, 4);
|
|
246
|
+
if (category === "reasoning") score = Math.max(score, 4);
|
|
247
|
+
if (category === "safety_sensitive") score = Math.max(score, 4);
|
|
228
248
|
if (category === "code_debug") score = Math.max(score, 4);
|
|
229
|
-
if (category === "
|
|
249
|
+
if (category === "code_generation") score = Math.max(score, 3);
|
|
250
|
+
if (category === "analysis" && (h.multi_part || h.long_form)) score = Math.max(score, 3);
|
|
251
|
+
if (h.multi_part && (h.design || h.safety || h.analysis)) score = Math.max(score, 4);
|
|
252
|
+
if (category === "factual_recall" && h.words < 28 && !h.design && !h.reason && !h.debug) {
|
|
253
|
+
score = Math.min(score, 2);
|
|
254
|
+
}
|
|
255
|
+
if (category === "math" && h.words < 24 && !h.reason) {
|
|
256
|
+
score = Math.min(Math.max(score, 1), 2);
|
|
257
|
+
}
|
|
230
258
|
return Math.max(1, Math.min(5, score));
|
|
231
259
|
}
|
|
232
260
|
function pSmallQuality(h, category, complexity) {
|
|
233
261
|
let p = 0.96;
|
|
234
|
-
if (h.design || category === "system_design") p -= 0.
|
|
235
|
-
if (h.safety || category === "safety_sensitive") p -= 0.
|
|
236
|
-
if (h.debug || category === "code_debug") p -= 0.
|
|
237
|
-
if (h.reason || category === "reasoning") p -= 0.
|
|
238
|
-
if (
|
|
239
|
-
|
|
240
|
-
else if (complexity
|
|
241
|
-
if (
|
|
242
|
-
if (h.
|
|
243
|
-
if (
|
|
244
|
-
if (category === "
|
|
262
|
+
if (h.design || category === "system_design") p -= 0.3;
|
|
263
|
+
if (h.safety || category === "safety_sensitive") p -= 0.32;
|
|
264
|
+
if (h.debug || category === "code_debug") p -= 0.24;
|
|
265
|
+
if (h.reason || category === "reasoning") p -= 0.22;
|
|
266
|
+
if (h.multi_part) p -= 0.1;
|
|
267
|
+
if (complexity >= 5) p -= 0.24;
|
|
268
|
+
else if (complexity >= 4) p -= 0.16;
|
|
269
|
+
else if (complexity === 3) p -= 0.07;
|
|
270
|
+
if (h.words > 100) p -= 0.07;
|
|
271
|
+
if (h.constraints >= 3) p -= 0.08;
|
|
272
|
+
if (category === "code_generation") p -= 0.06;
|
|
273
|
+
if (category === "analysis" && complexity >= 3) p -= 0.08;
|
|
274
|
+
if (category === "factual_recall" && h.words < 28) p = Math.max(p, 0.94);
|
|
275
|
+
if (category === "math" && h.words < 24 && !h.reason) p = Math.max(p, 0.9);
|
|
245
276
|
return Number(Math.min(0.99, Math.max(0.05, p)).toFixed(3));
|
|
246
277
|
}
|
|
247
278
|
function riskOf(category, complexity, p) {
|
|
@@ -254,6 +285,21 @@ function tierFromP(p) {
|
|
|
254
285
|
if (p >= 0.72) return "standard";
|
|
255
286
|
return "frontier";
|
|
256
287
|
}
|
|
288
|
+
function recommendTier(p, complexity, category, risk) {
|
|
289
|
+
const fromP = tierFromP(p);
|
|
290
|
+
const fromComplexity = difficultyTier(complexity);
|
|
291
|
+
let tier = maxTier(fromP, fromComplexity);
|
|
292
|
+
if (risk === "high") tier = maxTier(tier, "standard");
|
|
293
|
+
if (["system_design", "reasoning", "safety_sensitive"].includes(category) && complexity >= 4) {
|
|
294
|
+
tier = maxTier(tier, complexity >= 5 ? "frontier" : "standard");
|
|
295
|
+
}
|
|
296
|
+
if (category === "system_design" && complexity >= 4) tier = maxTier(tier, "frontier");
|
|
297
|
+
if (category === "reasoning" && complexity >= 4) tier = maxTier(tier, "standard");
|
|
298
|
+
return tier;
|
|
299
|
+
}
|
|
300
|
+
function maxTier(a, b) {
|
|
301
|
+
return TIER_RANK[a] >= TIER_RANK[b] ? a : b;
|
|
302
|
+
}
|
|
257
303
|
function difficultyTier(complexity) {
|
|
258
304
|
if (complexity <= 2) return "economy";
|
|
259
305
|
if (complexity === 3) return "standard";
|
package/dist/index.js
CHANGED
|
@@ -101,6 +101,7 @@ var Promptimizer = class _Promptimizer {
|
|
|
101
101
|
|
|
102
102
|
// src/classify.ts
|
|
103
103
|
var HIGH_RISK = /* @__PURE__ */ new Set(["system_design", "safety_sensitive", "code_debug", "reasoning"]);
|
|
104
|
+
var TIER_RANK = { economy: 0, standard: 1, frontier: 2 };
|
|
104
105
|
function textFrom(messages) {
|
|
105
106
|
return messages.map((m) => {
|
|
106
107
|
if (typeof m.content === "string") return m.content;
|
|
@@ -113,34 +114,46 @@ function classifyMessages(messages) {
|
|
|
113
114
|
function classifyText(text) {
|
|
114
115
|
const words = text.split(/\s+/).filter(Boolean).length;
|
|
115
116
|
const lines = text.split("\n").length;
|
|
117
|
+
const numbered = (text.match(/\(\s*\d+\s*\)/g) ?? []).length + (text.match(/^\s*\d+[\).:]/gm) ?? []).length + (text.match(/\b\d+\.\s+[A-Za-z]/g) ?? []).length;
|
|
118
|
+
const constraintWords = (text.match(
|
|
119
|
+
/\b(must|include|constraint|requirement|requirements|need to|ensure|exactly-once|idempotent)\b/gi
|
|
120
|
+
) ?? []).length;
|
|
116
121
|
const features = {
|
|
117
122
|
code_fence: /```/.test(text),
|
|
118
|
-
code_kw: /\b(def |class |function |import |fn |pub |async |
|
|
123
|
+
code_kw: /\b(def |class |function |import |fn |pub |async |goroutine|mutex|traceback)\b/i.test(text) || /\b(SELECT\b.+\bFROM\b|\bJOIN\b.+\bON\b|postgresql|\bpsql\b)/i.test(text),
|
|
124
|
+
math: /(\$\$|\\frac|prove that|expected value|O\([nN]\)|\d+\s*[\*\^×x]\s*\d+|infinitely many|factorial|prime)/i.test(
|
|
119
125
|
text
|
|
120
126
|
),
|
|
121
|
-
|
|
122
|
-
design: /\b(design|architect|rate limiter|distributed|consistency|shard|1 million QPS)\b/i.test(
|
|
127
|
+
design: /\b(design(?:ing)?|architect(?:ure|ing)?|rate[\s-]?limiter|distributed|consistency|shard(?:ing)?|multi-?region|multi-?tenant|qps|edge regions?|data[\s-]?plane|failure modes?|outbox|ledger|webhook|saas|billing pipeline|consensus|raft|paxos|quorum|leader election|log replication|network partition|cap theorem|eventual consistency|token bucket|sliding window)\b/i.test(
|
|
123
128
|
text
|
|
124
129
|
),
|
|
125
|
-
reason: /\b(prove|why does|walk through|step by step|derive|contradiction|p-value)\b/i.test(
|
|
130
|
+
reason: /\b(prove|proof|theorem|lemma|why does|walk through|step by step|derive|contradiction|p-value|induction|euclid|sketch (?:a |the )?proof)\b/i.test(
|
|
131
|
+
text
|
|
132
|
+
),
|
|
133
|
+
debug: /\b(bug|race|panic|fails on|diagnose|deadlock|concurrency hazard|code review|correctness)\b/i.test(
|
|
126
134
|
text
|
|
127
135
|
),
|
|
128
|
-
debug: /\b(bug|race|panic|fails on|diagnose|deadlock)\b/i.test(text),
|
|
129
136
|
summarize: /\b(summarize|tl;dr|in two sentences|eli5)\b/i.test(text),
|
|
130
137
|
translate: /\b(translate|traduce)\b/i.test(text),
|
|
131
138
|
creative: /\b(write a (poem|story|song)|haiku)\b/i.test(text),
|
|
132
|
-
safety: /\b(refund|legal|medical|hipaa|lawsuit|diagnosis)\b/i.test(
|
|
133
|
-
|
|
134
|
-
|
|
139
|
+
safety: /\b(refund|legal|medical|hipaa|lawsuit|diagnosis|gdpr|erasure|pii|compliance|audit trail)\b/i.test(
|
|
140
|
+
text
|
|
141
|
+
),
|
|
142
|
+
analysis: /\b(compare|trade-?off|versus|analyse|analyze|evaluate|should we|outline architecture)\b/i.test(
|
|
143
|
+
text
|
|
144
|
+
),
|
|
145
|
+
multi_part: numbered >= 3 || numbered >= 2 && constraintWords >= 1,
|
|
146
|
+
constraints: constraintWords + Math.min(4, numbered),
|
|
135
147
|
words,
|
|
136
148
|
lines,
|
|
137
|
-
question_marks: (text.match(/\?/g) ?? []).length
|
|
149
|
+
question_marks: (text.match(/\?/g) ?? []).length,
|
|
150
|
+
long_form: words >= 55 || lines >= 8
|
|
138
151
|
};
|
|
139
152
|
const category = categoryOf(features);
|
|
140
153
|
const complexity = complexityOf(features, category);
|
|
141
154
|
const p_small_quality = pSmallQuality(features, category, complexity);
|
|
142
155
|
const quality_risk = riskOf(category, complexity, p_small_quality);
|
|
143
|
-
const recommended_tier =
|
|
156
|
+
const recommended_tier = recommendTier(p_small_quality, complexity, category, quality_risk);
|
|
144
157
|
const signals = [
|
|
145
158
|
features.code_fence,
|
|
146
159
|
features.code_kw,
|
|
@@ -148,9 +161,10 @@ function classifyText(text) {
|
|
|
148
161
|
features.design,
|
|
149
162
|
features.reason,
|
|
150
163
|
features.debug,
|
|
151
|
-
features.safety
|
|
164
|
+
features.safety,
|
|
165
|
+
features.multi_part
|
|
152
166
|
].filter(Boolean).length;
|
|
153
|
-
const confidence = category === "factual_recall" && words < 16 ? 0.
|
|
167
|
+
const confidence = category === "factual_recall" && words < 16 ? 0.92 : Math.min(0.96, 0.55 + 0.1 * signals);
|
|
154
168
|
return {
|
|
155
169
|
complexity,
|
|
156
170
|
category,
|
|
@@ -166,47 +180,64 @@ function classifyText(text) {
|
|
|
166
180
|
};
|
|
167
181
|
}
|
|
168
182
|
function categoryOf(h) {
|
|
169
|
-
if (h.safety) return "safety_sensitive";
|
|
170
183
|
if (h.design) return "system_design";
|
|
184
|
+
if (h.safety && !h.design) return "safety_sensitive";
|
|
171
185
|
if (h.debug && (h.code_fence || h.code_kw)) return "code_debug";
|
|
172
|
-
if (h.
|
|
186
|
+
if (h.debug && h.long_form) return "code_debug";
|
|
173
187
|
if (h.math && h.reason) return "reasoning";
|
|
174
|
-
if (h.math) return "math";
|
|
175
188
|
if (h.reason) return "reasoning";
|
|
189
|
+
if (h.code_fence || h.code_kw) return "code_generation";
|
|
190
|
+
if (h.math) return "math";
|
|
191
|
+
if (h.safety) return "safety_sensitive";
|
|
176
192
|
if (h.translate) return "translation";
|
|
177
193
|
if (h.summarize) return "summarization";
|
|
178
194
|
if (h.creative) return "creative";
|
|
179
|
-
if (h.analysis) return "analysis";
|
|
180
|
-
if (h.words <
|
|
195
|
+
if (h.analysis || h.multi_part) return "analysis";
|
|
196
|
+
if (h.words < 28 && h.question_marks >= 1) return "factual_recall";
|
|
181
197
|
return h.words > 80 ? "analysis" : "factual_recall";
|
|
182
198
|
}
|
|
183
199
|
function complexityOf(h, category) {
|
|
184
200
|
let score = 1;
|
|
185
|
-
if (h.words >
|
|
186
|
-
if (h.words >
|
|
187
|
-
if (h.lines >
|
|
201
|
+
if (h.words > 35) score += 1;
|
|
202
|
+
if (h.words > 90) score += 1;
|
|
203
|
+
if (h.lines > 10 || h.code_fence) score += 1;
|
|
188
204
|
if (h.constraints >= 2) score += 1;
|
|
189
|
-
if (h.
|
|
205
|
+
if (h.constraints >= 4 || h.multi_part) score += 1;
|
|
206
|
+
if (h.design) score += 1;
|
|
207
|
+
if (h.reason) score += 1;
|
|
190
208
|
if (h.debug) score += 1;
|
|
191
|
-
if (
|
|
192
|
-
if (category === "
|
|
209
|
+
if (h.safety && (h.design || h.multi_part)) score += 1;
|
|
210
|
+
if (category === "system_design") score = Math.max(score, 4);
|
|
211
|
+
if (category === "reasoning") score = Math.max(score, 4);
|
|
212
|
+
if (category === "safety_sensitive") score = Math.max(score, 4);
|
|
193
213
|
if (category === "code_debug") score = Math.max(score, 4);
|
|
194
|
-
if (category === "
|
|
214
|
+
if (category === "code_generation") score = Math.max(score, 3);
|
|
215
|
+
if (category === "analysis" && (h.multi_part || h.long_form)) score = Math.max(score, 3);
|
|
216
|
+
if (h.multi_part && (h.design || h.safety || h.analysis)) score = Math.max(score, 4);
|
|
217
|
+
if (category === "factual_recall" && h.words < 28 && !h.design && !h.reason && !h.debug) {
|
|
218
|
+
score = Math.min(score, 2);
|
|
219
|
+
}
|
|
220
|
+
if (category === "math" && h.words < 24 && !h.reason) {
|
|
221
|
+
score = Math.min(Math.max(score, 1), 2);
|
|
222
|
+
}
|
|
195
223
|
return Math.max(1, Math.min(5, score));
|
|
196
224
|
}
|
|
197
225
|
function pSmallQuality(h, category, complexity) {
|
|
198
226
|
let p = 0.96;
|
|
199
|
-
if (h.design || category === "system_design") p -= 0.
|
|
200
|
-
if (h.safety || category === "safety_sensitive") p -= 0.
|
|
201
|
-
if (h.debug || category === "code_debug") p -= 0.
|
|
202
|
-
if (h.reason || category === "reasoning") p -= 0.
|
|
203
|
-
if (
|
|
204
|
-
|
|
205
|
-
else if (complexity
|
|
206
|
-
if (
|
|
207
|
-
if (h.
|
|
208
|
-
if (
|
|
209
|
-
if (category === "
|
|
227
|
+
if (h.design || category === "system_design") p -= 0.3;
|
|
228
|
+
if (h.safety || category === "safety_sensitive") p -= 0.32;
|
|
229
|
+
if (h.debug || category === "code_debug") p -= 0.24;
|
|
230
|
+
if (h.reason || category === "reasoning") p -= 0.22;
|
|
231
|
+
if (h.multi_part) p -= 0.1;
|
|
232
|
+
if (complexity >= 5) p -= 0.24;
|
|
233
|
+
else if (complexity >= 4) p -= 0.16;
|
|
234
|
+
else if (complexity === 3) p -= 0.07;
|
|
235
|
+
if (h.words > 100) p -= 0.07;
|
|
236
|
+
if (h.constraints >= 3) p -= 0.08;
|
|
237
|
+
if (category === "code_generation") p -= 0.06;
|
|
238
|
+
if (category === "analysis" && complexity >= 3) p -= 0.08;
|
|
239
|
+
if (category === "factual_recall" && h.words < 28) p = Math.max(p, 0.94);
|
|
240
|
+
if (category === "math" && h.words < 24 && !h.reason) p = Math.max(p, 0.9);
|
|
210
241
|
return Number(Math.min(0.99, Math.max(0.05, p)).toFixed(3));
|
|
211
242
|
}
|
|
212
243
|
function riskOf(category, complexity, p) {
|
|
@@ -219,6 +250,21 @@ function tierFromP(p) {
|
|
|
219
250
|
if (p >= 0.72) return "standard";
|
|
220
251
|
return "frontier";
|
|
221
252
|
}
|
|
253
|
+
function recommendTier(p, complexity, category, risk) {
|
|
254
|
+
const fromP = tierFromP(p);
|
|
255
|
+
const fromComplexity = difficultyTier(complexity);
|
|
256
|
+
let tier = maxTier(fromP, fromComplexity);
|
|
257
|
+
if (risk === "high") tier = maxTier(tier, "standard");
|
|
258
|
+
if (["system_design", "reasoning", "safety_sensitive"].includes(category) && complexity >= 4) {
|
|
259
|
+
tier = maxTier(tier, complexity >= 5 ? "frontier" : "standard");
|
|
260
|
+
}
|
|
261
|
+
if (category === "system_design" && complexity >= 4) tier = maxTier(tier, "frontier");
|
|
262
|
+
if (category === "reasoning" && complexity >= 4) tier = maxTier(tier, "standard");
|
|
263
|
+
return tier;
|
|
264
|
+
}
|
|
265
|
+
function maxTier(a, b) {
|
|
266
|
+
return TIER_RANK[a] >= TIER_RANK[b] ? a : b;
|
|
267
|
+
}
|
|
222
268
|
function difficultyTier(complexity) {
|
|
223
269
|
if (complexity <= 2) return "economy";
|
|
224
270
|
if (complexity === 3) return "standard";
|
package/package.json
CHANGED