smart-model-run 0.1.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 +47 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/model-rankings.d.ts +44 -0
- package/dist/model-rankings.d.ts.map +1 -0
- package/dist/model-rankings.js +259 -0
- package/dist/model-rankings.js.map +1 -0
- package/dist/smart-run.d.ts +126 -0
- package/dist/smart-run.d.ts.map +1 -0
- package/dist/smart-run.js +336 -0
- package/dist/smart-run.js.map +1 -0
- package/package.json +41 -0
package/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# smart-model-run
|
|
2
|
+
|
|
3
|
+
Benchmark-driven smart model selection and fallback execution for agent workloads.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
pnpm add smart-model-run
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
For local development from `the-watch`:
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"smart-model-run": "file:../smart-model-run"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { smartRun } from "smart-model-run";
|
|
25
|
+
|
|
26
|
+
const result = await smartRun({
|
|
27
|
+
budget: "cheap",
|
|
28
|
+
ceiling: "mid",
|
|
29
|
+
thinking: "low",
|
|
30
|
+
prompt: "Review this diff for correctness issues.",
|
|
31
|
+
tools: ["read", "grep", "find", "ls"],
|
|
32
|
+
needs: ["tools", "correctness", "codeQuality"],
|
|
33
|
+
cwd: process.cwd(),
|
|
34
|
+
runner: async (input) => runYourAgent(input),
|
|
35
|
+
fallbackSelectors: ["openai/gpt-4o-mini"],
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The library fetches model benchmark metadata from `aistupidlevel.info`, caches it at `~/.pi/agent/model-rankings.json` for 6 hours, and falls back to cached rankings on network failure.
|
|
40
|
+
|
|
41
|
+
## Core exports
|
|
42
|
+
|
|
43
|
+
- `smartRun()` — select ranked candidates, run them, and fallback on failure.
|
|
44
|
+
- `pickModels()` — rank models within a budget tier.
|
|
45
|
+
- `pickModelsAcrossBudget()` — escalate across allowed budget tiers when no model meets `minMatch`.
|
|
46
|
+
- `getRankings()` / `forceRefreshRankings()` — fetch and cache live benchmark rankings.
|
|
47
|
+
- `formatSmartRunSummary()` / `formatRankings()` — human-readable summaries.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export type ModelAxes = {
|
|
2
|
+
correctness: number;
|
|
3
|
+
spec: number;
|
|
4
|
+
codeQuality: number;
|
|
5
|
+
efficiency: number;
|
|
6
|
+
stability: number;
|
|
7
|
+
refusal: number;
|
|
8
|
+
recovery: number;
|
|
9
|
+
};
|
|
10
|
+
export type ModelRanking = {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
vendor: string;
|
|
14
|
+
score: number;
|
|
15
|
+
confidenceLower: number;
|
|
16
|
+
confidenceUpper: number;
|
|
17
|
+
trend: string;
|
|
18
|
+
costInput: number | null;
|
|
19
|
+
costOutput: number | null;
|
|
20
|
+
costNote: string;
|
|
21
|
+
axes: ModelAxes;
|
|
22
|
+
supportsToolCalling: boolean;
|
|
23
|
+
toolCallReliability: number;
|
|
24
|
+
maxToolsPerCall: number;
|
|
25
|
+
usesReasoningEffort: boolean;
|
|
26
|
+
};
|
|
27
|
+
export type AxisName = keyof ModelAxes;
|
|
28
|
+
export type RankingsTable = {
|
|
29
|
+
fetchedAt: string;
|
|
30
|
+
models: ModelRanking[];
|
|
31
|
+
};
|
|
32
|
+
export declare function loadRankings(): Promise<RankingsTable | null>;
|
|
33
|
+
/**
|
|
34
|
+
* Returns the current rankings table, refreshing from aistupidlevel.info
|
|
35
|
+
* if stale (>6h). Only one Pi instance refreshes at a time (lockfile).
|
|
36
|
+
* Never throws — returns cached data on fetch failure, null if nothing cached.
|
|
37
|
+
*/
|
|
38
|
+
export declare function getRankings(): Promise<RankingsTable | null>;
|
|
39
|
+
/**
|
|
40
|
+
* Force a refresh regardless of staleness (still respects the lock).
|
|
41
|
+
*/
|
|
42
|
+
export declare function forceRefreshRankings(): Promise<RankingsTable | null>;
|
|
43
|
+
export declare function formatRankings(table: RankingsTable): string;
|
|
44
|
+
//# sourceMappingURL=model-rankings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-rankings.d.ts","sourceRoot":"","sources":["../src/model-rankings.ts"],"names":[],"mappings":"AAyBA,MAAM,MAAM,SAAS,GAAG;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;IAChB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,OAAO,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC;AAEvC,MAAM,MAAM,aAAa,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,YAAY,EAAE,CAAC;CACvB,CAAC;AA6LF,wBAAsB,YAAY,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAOlE;AAeD;;;;GAIG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAcjE;AAED;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAW1E;AAuBD,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAyB3D"}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { closeSync, existsSync, mkdirSync, openSync, statSync, unlinkSync, writeSync, } from "node:fs";
|
|
2
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
const RANKINGS_DIR = join(homedir(), ".pi", "agent");
|
|
6
|
+
const RANKINGS_PATH = join(RANKINGS_DIR, "model-rankings.json");
|
|
7
|
+
const LOCK_PATH = join(RANKINGS_DIR, "model-rankings.lock");
|
|
8
|
+
const REFRESH_INTERVAL_MS = 8 * 60 * 60_000; // 8 hours
|
|
9
|
+
const LOCK_STALE_MS = 5 * 60_000; // lock expires after 5 min (crashed process)
|
|
10
|
+
const FETCH_TIMEOUT_MS = 15_000;
|
|
11
|
+
const SCORES_URL = "https://aistupidlevel.info/dashboard/scores";
|
|
12
|
+
const MODELS_URL = "https://aistupidlevel.info/api/models";
|
|
13
|
+
// ── Cost parsing ──
|
|
14
|
+
const COST_PATTERN = /\$([0-9.]+)\s*\/\s*\$([0-9.]+)\s*(?:per\s+)?(?:M\s*Tok|MTok)/i;
|
|
15
|
+
function parseCosts(notes) {
|
|
16
|
+
const match = notes.match(COST_PATTERN);
|
|
17
|
+
if (!match)
|
|
18
|
+
return { input: null, output: null, raw: notes };
|
|
19
|
+
return {
|
|
20
|
+
input: Number.parseFloat(match[1]),
|
|
21
|
+
output: Number.parseFloat(match[2]),
|
|
22
|
+
raw: match[0],
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
// ── Lockfile (cross-instance debounce) ──
|
|
26
|
+
function acquireLock() {
|
|
27
|
+
mkdirSync(RANKINGS_DIR, { recursive: true });
|
|
28
|
+
if (existsSync(LOCK_PATH)) {
|
|
29
|
+
try {
|
|
30
|
+
const age = Date.now() - statSync(LOCK_PATH).mtimeMs;
|
|
31
|
+
if (age < LOCK_STALE_MS)
|
|
32
|
+
return false; // another instance is updating
|
|
33
|
+
unlinkSync(LOCK_PATH); // stale lock from a crashed process
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
const fd = openSync(LOCK_PATH, "wx");
|
|
41
|
+
writeSync(fd, String(process.pid));
|
|
42
|
+
closeSync(fd);
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function releaseLock() {
|
|
50
|
+
try {
|
|
51
|
+
unlinkSync(LOCK_PATH);
|
|
52
|
+
}
|
|
53
|
+
catch { }
|
|
54
|
+
}
|
|
55
|
+
async function fetchJson(url) {
|
|
56
|
+
const res = await fetch(url, {
|
|
57
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
|
|
58
|
+
headers: { Accept: "application/json" },
|
|
59
|
+
});
|
|
60
|
+
if (!res.ok)
|
|
61
|
+
throw new Error(`${url} returned ${res.status}`);
|
|
62
|
+
return (await res.json());
|
|
63
|
+
}
|
|
64
|
+
// ── Core: fetch, merge, rank ──
|
|
65
|
+
const DETAIL_URL = (id) => `https://aistupidlevel.info/api/models/${id}`;
|
|
66
|
+
const DEFAULT_AXES = {
|
|
67
|
+
correctness: 0,
|
|
68
|
+
spec: 0,
|
|
69
|
+
codeQuality: 0,
|
|
70
|
+
efficiency: 0,
|
|
71
|
+
stability: 0,
|
|
72
|
+
refusal: 0,
|
|
73
|
+
recovery: 0,
|
|
74
|
+
};
|
|
75
|
+
function parseAxes(raw) {
|
|
76
|
+
if (!raw)
|
|
77
|
+
return { ...DEFAULT_AXES };
|
|
78
|
+
return {
|
|
79
|
+
correctness: raw.correctness ?? 0,
|
|
80
|
+
spec: raw.spec ?? 0,
|
|
81
|
+
codeQuality: raw.codeQuality ?? 0,
|
|
82
|
+
efficiency: raw.efficiency ?? 0,
|
|
83
|
+
stability: raw.stability ?? 0,
|
|
84
|
+
refusal: raw.refusal ?? 0,
|
|
85
|
+
recovery: raw.recovery ?? 0,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
async function fetchModelDetail(id) {
|
|
89
|
+
try {
|
|
90
|
+
return await fetchJson(DETAIL_URL(id));
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async function fetchRankings() {
|
|
97
|
+
const [scoresRes, modelsRes] = await Promise.all([
|
|
98
|
+
fetchJson(SCORES_URL),
|
|
99
|
+
fetchJson(MODELS_URL),
|
|
100
|
+
]);
|
|
101
|
+
const modelMap = new Map(modelsRes.map((m) => [String(m.id), m]));
|
|
102
|
+
const scores = scoresRes.data ?? scoresRes;
|
|
103
|
+
// Fetch per-model details in parallel (for axes) — batch of 6 at a time
|
|
104
|
+
const scoreList = scores;
|
|
105
|
+
const detailMap = new Map();
|
|
106
|
+
const batches = [];
|
|
107
|
+
for (let i = 0; i < scoreList.length; i += 6) {
|
|
108
|
+
batches.push(scoreList.slice(i, i + 6));
|
|
109
|
+
}
|
|
110
|
+
for (const batch of batches) {
|
|
111
|
+
const results = await Promise.all(batch.map((s) => fetchModelDetail(s.id)));
|
|
112
|
+
for (let i = 0; i < batch.length; i++) {
|
|
113
|
+
const detail = results[i];
|
|
114
|
+
if (detail)
|
|
115
|
+
detailMap.set(batch[i].id, detail);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const models = scoreList.map((s) => {
|
|
119
|
+
const listDetail = modelMap.get(s.id);
|
|
120
|
+
const fullDetail = detailMap.get(s.id);
|
|
121
|
+
const detail = fullDetail ?? listDetail;
|
|
122
|
+
const costs = parseCosts(detail?.notes ?? "");
|
|
123
|
+
return {
|
|
124
|
+
id: s.id,
|
|
125
|
+
name: s.name,
|
|
126
|
+
vendor: s.provider ?? detail?.vendor ?? "unknown",
|
|
127
|
+
score: s.currentScore,
|
|
128
|
+
confidenceLower: s.confidenceLower ?? 0,
|
|
129
|
+
confidenceUpper: s.confidenceUpper ?? 100,
|
|
130
|
+
trend: s.trend ?? "stable",
|
|
131
|
+
costInput: costs.input,
|
|
132
|
+
costOutput: costs.output,
|
|
133
|
+
costNote: costs.raw,
|
|
134
|
+
axes: parseAxes(fullDetail?.latestScore?.axes),
|
|
135
|
+
supportsToolCalling: detail?.supportsToolCalling ?? false,
|
|
136
|
+
toolCallReliability: detail?.toolCallReliability ?? 0,
|
|
137
|
+
maxToolsPerCall: detail?.maxToolsPerCall ?? 0,
|
|
138
|
+
usesReasoningEffort: s.usesReasoningEffort ?? false,
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
// Sort: accuracy first (descending), then cheapest output cost
|
|
142
|
+
models.sort((a, b) => {
|
|
143
|
+
if (b.score !== a.score)
|
|
144
|
+
return b.score - a.score;
|
|
145
|
+
const aCost = a.costOutput ?? Number.MAX_SAFE_INTEGER;
|
|
146
|
+
const bCost = b.costOutput ?? Number.MAX_SAFE_INTEGER;
|
|
147
|
+
return aCost - bCost;
|
|
148
|
+
});
|
|
149
|
+
return { fetchedAt: new Date().toISOString(), models };
|
|
150
|
+
}
|
|
151
|
+
// ── Persistence ──
|
|
152
|
+
export async function loadRankings() {
|
|
153
|
+
if (!existsSync(RANKINGS_PATH))
|
|
154
|
+
return null;
|
|
155
|
+
try {
|
|
156
|
+
return JSON.parse(await readFile(RANKINGS_PATH, "utf8"));
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
async function saveRankings(table) {
|
|
163
|
+
mkdirSync(RANKINGS_DIR, { recursive: true });
|
|
164
|
+
await writeFile(RANKINGS_PATH, JSON.stringify(table, null, 2) + "\n");
|
|
165
|
+
}
|
|
166
|
+
function isStale(table) {
|
|
167
|
+
if (!table)
|
|
168
|
+
return true;
|
|
169
|
+
const age = Date.now() - new Date(table.fetchedAt).getTime();
|
|
170
|
+
return age >= REFRESH_INTERVAL_MS;
|
|
171
|
+
}
|
|
172
|
+
// ── Public API ──
|
|
173
|
+
/**
|
|
174
|
+
* Returns the current rankings table, refreshing from aistupidlevel.info
|
|
175
|
+
* if stale (>6h). Only one Pi instance refreshes at a time (lockfile).
|
|
176
|
+
* Never throws — returns cached data on fetch failure, null if nothing cached.
|
|
177
|
+
*/
|
|
178
|
+
export async function getRankings() {
|
|
179
|
+
const cached = await loadRankings();
|
|
180
|
+
if (!isStale(cached))
|
|
181
|
+
return cached;
|
|
182
|
+
if (!acquireLock())
|
|
183
|
+
return cached; // another instance is refreshing
|
|
184
|
+
try {
|
|
185
|
+
const fresh = await fetchRankings();
|
|
186
|
+
await saveRankings(fresh);
|
|
187
|
+
return fresh;
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
return cached; // network failure — serve stale
|
|
191
|
+
}
|
|
192
|
+
finally {
|
|
193
|
+
releaseLock();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Force a refresh regardless of staleness (still respects the lock).
|
|
198
|
+
*/
|
|
199
|
+
export async function forceRefreshRankings() {
|
|
200
|
+
if (!acquireLock())
|
|
201
|
+
return loadRankings();
|
|
202
|
+
try {
|
|
203
|
+
const fresh = await fetchRankings();
|
|
204
|
+
await saveRankings(fresh);
|
|
205
|
+
return fresh;
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
return loadRankings();
|
|
209
|
+
}
|
|
210
|
+
finally {
|
|
211
|
+
releaseLock();
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Format the rankings table as a concise summary for display.
|
|
216
|
+
*/
|
|
217
|
+
function formatTags(m) {
|
|
218
|
+
const tags = [];
|
|
219
|
+
if (m.supportsToolCalling)
|
|
220
|
+
tags.push(`tools(${m.maxToolsPerCall})`);
|
|
221
|
+
if (m.usesReasoningEffort)
|
|
222
|
+
tags.push("thinking");
|
|
223
|
+
if (m.toolCallReliability >= 0.9)
|
|
224
|
+
tags.push("reliable-tools");
|
|
225
|
+
const best = bestAxes(m.axes, 2);
|
|
226
|
+
if (best.length > 0)
|
|
227
|
+
tags.push(...best.map(([k, v]) => `${k}:${(v * 100).toFixed(0)}`));
|
|
228
|
+
return tags.join(" ");
|
|
229
|
+
}
|
|
230
|
+
function bestAxes(axes, n) {
|
|
231
|
+
return Object.entries(axes)
|
|
232
|
+
.filter(([, v]) => v > 0)
|
|
233
|
+
.sort(([, a], [, b]) => b - a)
|
|
234
|
+
.slice(0, n);
|
|
235
|
+
}
|
|
236
|
+
export function formatRankings(table) {
|
|
237
|
+
const age = Date.now() - new Date(table.fetchedAt).getTime();
|
|
238
|
+
const ageH = (age / 3_600_000).toFixed(1);
|
|
239
|
+
const lines = [
|
|
240
|
+
`Model rankings (fetched ${ageH}h ago from aistupidlevel.info)`,
|
|
241
|
+
`Sorted by: accuracy (score) ↓, then cost ↑`,
|
|
242
|
+
"",
|
|
243
|
+
" # Score Cost (in/out MTok) Trend Model",
|
|
244
|
+
" ── ───── ────────────────── ────── ─────",
|
|
245
|
+
];
|
|
246
|
+
for (let i = 0; i < table.models.length; i++) {
|
|
247
|
+
const m = table.models[i];
|
|
248
|
+
const rank = String(i + 1).padStart(3);
|
|
249
|
+
const score = String(m.score).padStart(5);
|
|
250
|
+
const cost = m.costInput !== null && m.costOutput !== null
|
|
251
|
+
? `$${m.costInput}/$${m.costOutput}`
|
|
252
|
+
: "n/a";
|
|
253
|
+
const trend = m.trend.padEnd(6);
|
|
254
|
+
const tags = formatTags(m);
|
|
255
|
+
lines.push(`${rank} ${score} ${cost.padEnd(18)} ${trend} ${m.name}${tags ? ` [${tags}]` : ""}`);
|
|
256
|
+
}
|
|
257
|
+
return lines.join("\n");
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=model-rankings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-rankings.js","sourceRoot":"","sources":["../src/model-rankings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* smart-run: benchmark-driven sub-agent execution.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* const result = await smartRun({
|
|
6
|
+
* budget: "cheap",
|
|
7
|
+
* ceiling: "mid", // highest tier allowed if cheap has no match
|
|
8
|
+
* thinking: "low",
|
|
9
|
+
* prompt: "Review this diff for correctness issues.",
|
|
10
|
+
* tools: ["read", "grep", "find", "ls"],
|
|
11
|
+
* needs: ["tools", "correctness", "codeQuality"],
|
|
12
|
+
* cwd: "/path/to/repo",
|
|
13
|
+
* runner: spawnPiAgent,
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* Picks the closest-matching model from live aistupidlevel.info benchmarks.
|
|
17
|
+
* Starts at the requested budget tier; if nothing matches well enough,
|
|
18
|
+
* escalates up to the ceiling. Falls back through the ranked list on failure.
|
|
19
|
+
*/
|
|
20
|
+
import { type AxisName, type ModelRanking, type RankingsTable } from "./model-rankings.js";
|
|
21
|
+
export type Tier = "cheap" | "mid" | "high";
|
|
22
|
+
export type Need = "tools" | "reliable-tools" | "thinking" | AxisName;
|
|
23
|
+
export type ModelMatch = {
|
|
24
|
+
selector: string;
|
|
25
|
+
model: ModelRanking;
|
|
26
|
+
matchScore: number;
|
|
27
|
+
met: Need[];
|
|
28
|
+
partial: Need[];
|
|
29
|
+
unmet: Need[];
|
|
30
|
+
};
|
|
31
|
+
export type SmartRunInput = {
|
|
32
|
+
cwd: string;
|
|
33
|
+
prompt: string;
|
|
34
|
+
model: string;
|
|
35
|
+
thinking: string;
|
|
36
|
+
tools: string[];
|
|
37
|
+
timeoutMs: number;
|
|
38
|
+
signal?: AbortSignal;
|
|
39
|
+
extensionPaths?: string[];
|
|
40
|
+
};
|
|
41
|
+
export type SmartRunResult = {
|
|
42
|
+
exitCode: number;
|
|
43
|
+
stdout: string;
|
|
44
|
+
stderr: string;
|
|
45
|
+
timedOut?: boolean;
|
|
46
|
+
finalText: string;
|
|
47
|
+
errorMessage?: string;
|
|
48
|
+
durationMs?: number;
|
|
49
|
+
inputTokens?: number;
|
|
50
|
+
outputTokens?: number;
|
|
51
|
+
};
|
|
52
|
+
export type AgentRunner = (input: SmartRunInput) => Promise<SmartRunResult>;
|
|
53
|
+
type ModelRegistryLike = {
|
|
54
|
+
find?: (provider: string, id: string) => unknown;
|
|
55
|
+
};
|
|
56
|
+
export declare function pickModels(table: RankingsTable, tier: Tier, opts?: {
|
|
57
|
+
registry?: ModelRegistryLike;
|
|
58
|
+
needs?: Need[];
|
|
59
|
+
}): ModelMatch[];
|
|
60
|
+
/**
|
|
61
|
+
* Start at `budget`, escalate up to `ceiling` if nothing meets `minMatch`.
|
|
62
|
+
* If no ceiling, stays in the budget tier.
|
|
63
|
+
*/
|
|
64
|
+
export declare function pickModelsAcrossBudget(table: RankingsTable, budget: Tier, opts?: {
|
|
65
|
+
ceiling?: Tier;
|
|
66
|
+
registry?: ModelRegistryLike;
|
|
67
|
+
needs?: Need[];
|
|
68
|
+
minMatch?: number;
|
|
69
|
+
}): {
|
|
70
|
+
tier: Tier;
|
|
71
|
+
escalated: boolean;
|
|
72
|
+
models: ModelMatch[];
|
|
73
|
+
};
|
|
74
|
+
export type SmartRunOptions = {
|
|
75
|
+
/** Preferred budget tier */
|
|
76
|
+
budget: Tier;
|
|
77
|
+
/** Highest tier allowed if budget tier has no match (omit = stay in budget) */
|
|
78
|
+
ceiling?: Tier;
|
|
79
|
+
thinking: string;
|
|
80
|
+
prompt: string;
|
|
81
|
+
tools: string[];
|
|
82
|
+
cwd: string;
|
|
83
|
+
runner: AgentRunner;
|
|
84
|
+
/** What capabilities/strengths the model should have */
|
|
85
|
+
needs?: Need[];
|
|
86
|
+
/** Minimum match quality 0..1 (default 0.5) */
|
|
87
|
+
minMatch?: number;
|
|
88
|
+
timeoutMs?: number;
|
|
89
|
+
signal?: AbortSignal;
|
|
90
|
+
extensionPaths?: string[];
|
|
91
|
+
modelRegistry?: ModelRegistryLike;
|
|
92
|
+
/** Safety-net selectors tried after all ranked models */
|
|
93
|
+
fallbackSelectors?: string[];
|
|
94
|
+
/** Inject rankings (for testing); undefined = fetch live, null = skip */
|
|
95
|
+
_rankings?: RankingsTable | null;
|
|
96
|
+
};
|
|
97
|
+
export type SmartRunAttempt = {
|
|
98
|
+
selector: string;
|
|
99
|
+
score: number | null;
|
|
100
|
+
cost: number | null;
|
|
101
|
+
matchScore: number | null;
|
|
102
|
+
status: "success" | "failed" | "skipped";
|
|
103
|
+
errorMessage?: string;
|
|
104
|
+
durationMs?: number;
|
|
105
|
+
inputTokens?: number;
|
|
106
|
+
outputTokens?: number;
|
|
107
|
+
};
|
|
108
|
+
export type SmartRunOutput = {
|
|
109
|
+
ok: boolean;
|
|
110
|
+
finalModel: string | null;
|
|
111
|
+
output: string;
|
|
112
|
+
attempts: SmartRunAttempt[];
|
|
113
|
+
/** Which tier was actually used */
|
|
114
|
+
tier: Tier | null;
|
|
115
|
+
/** Whether it escalated beyond the first requested tier */
|
|
116
|
+
escalated: boolean;
|
|
117
|
+
rankings: {
|
|
118
|
+
fetchedAt: string;
|
|
119
|
+
candidateCount: number;
|
|
120
|
+
} | null;
|
|
121
|
+
noMatchReason?: string;
|
|
122
|
+
};
|
|
123
|
+
export declare function smartRun(opts: SmartRunOptions): Promise<SmartRunOutput>;
|
|
124
|
+
export declare function formatSmartRunSummary(result: SmartRunOutput): string;
|
|
125
|
+
export {};
|
|
126
|
+
//# sourceMappingURL=smart-run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-run.d.ts","sourceRoot":"","sources":["../src/smart-run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* smart-run: benchmark-driven sub-agent execution.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* const result = await smartRun({
|
|
6
|
+
* budget: "cheap",
|
|
7
|
+
* ceiling: "mid", // highest tier allowed if cheap has no match
|
|
8
|
+
* thinking: "low",
|
|
9
|
+
* prompt: "Review this diff for correctness issues.",
|
|
10
|
+
* tools: ["read", "grep", "find", "ls"],
|
|
11
|
+
* needs: ["tools", "correctness", "codeQuality"],
|
|
12
|
+
* cwd: "/path/to/repo",
|
|
13
|
+
* runner: spawnPiAgent,
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* Picks the closest-matching model from live aistupidlevel.info benchmarks.
|
|
17
|
+
* Starts at the requested budget tier; if nothing matches well enough,
|
|
18
|
+
* escalates up to the ceiling. Falls back through the ranked list on failure.
|
|
19
|
+
*/
|
|
20
|
+
import { getRankings, } from "./model-rankings.js";
|
|
21
|
+
const OUTPUT_COST_CEILING = {
|
|
22
|
+
cheap: 5,
|
|
23
|
+
mid: 15,
|
|
24
|
+
high: Number.MAX_SAFE_INTEGER,
|
|
25
|
+
};
|
|
26
|
+
const TIER_ORDER = ["cheap", "mid", "high"];
|
|
27
|
+
function tiersInRange(budget, ceiling) {
|
|
28
|
+
const start = TIER_ORDER.indexOf(budget);
|
|
29
|
+
const end = ceiling ? TIER_ORDER.indexOf(ceiling) : start;
|
|
30
|
+
if (start < 0 || end < start)
|
|
31
|
+
return [budget];
|
|
32
|
+
return TIER_ORDER.slice(start, end + 1);
|
|
33
|
+
}
|
|
34
|
+
// ── Needs: what the caller wants from a model ──
|
|
35
|
+
const AXIS_NAMES = new Set([
|
|
36
|
+
"correctness",
|
|
37
|
+
"spec",
|
|
38
|
+
"codeQuality",
|
|
39
|
+
"efficiency",
|
|
40
|
+
"stability",
|
|
41
|
+
"refusal",
|
|
42
|
+
"recovery",
|
|
43
|
+
]);
|
|
44
|
+
const AXIS_STRONG_THRESHOLD = 0.7;
|
|
45
|
+
function needScore(m, need) {
|
|
46
|
+
switch (need) {
|
|
47
|
+
case "tools":
|
|
48
|
+
return m.supportsToolCalling ? 1 : 0;
|
|
49
|
+
case "reliable-tools":
|
|
50
|
+
return m.toolCallReliability >= 0.9 ? 1 : m.toolCallReliability;
|
|
51
|
+
case "thinking":
|
|
52
|
+
return m.usesReasoningEffort ? 1 : 0;
|
|
53
|
+
default:
|
|
54
|
+
if (AXIS_NAMES.has(need))
|
|
55
|
+
return m.axes[need] ?? 0;
|
|
56
|
+
return 0;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function scoreModel(m, needs) {
|
|
60
|
+
if (needs.length === 0)
|
|
61
|
+
return { matchScore: 1, met: [], partial: [], unmet: [] };
|
|
62
|
+
const met = [];
|
|
63
|
+
const partial = [];
|
|
64
|
+
const unmet = [];
|
|
65
|
+
let total = 0;
|
|
66
|
+
for (const need of needs) {
|
|
67
|
+
const s = needScore(m, need);
|
|
68
|
+
total += s;
|
|
69
|
+
if (AXIS_NAMES.has(need)) {
|
|
70
|
+
if (s >= AXIS_STRONG_THRESHOLD)
|
|
71
|
+
met.push(need);
|
|
72
|
+
else if (s > 0)
|
|
73
|
+
partial.push(need);
|
|
74
|
+
else
|
|
75
|
+
unmet.push(need);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
if (s >= 1)
|
|
79
|
+
met.push(need);
|
|
80
|
+
else if (s > 0)
|
|
81
|
+
partial.push(need);
|
|
82
|
+
else
|
|
83
|
+
unmet.push(need);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return { matchScore: total / needs.length, met, partial, unmet };
|
|
87
|
+
}
|
|
88
|
+
// ── Vendor → Pi provider mapping ──
|
|
89
|
+
const VENDOR_TO_PROVIDER = {
|
|
90
|
+
anthropic: "anthropic",
|
|
91
|
+
openai: "openai",
|
|
92
|
+
google: "google",
|
|
93
|
+
deepseek: "deepseek",
|
|
94
|
+
kimi: "openrouter",
|
|
95
|
+
glm: "openrouter",
|
|
96
|
+
};
|
|
97
|
+
function toPiSelector(model) {
|
|
98
|
+
const provider = VENDOR_TO_PROVIDER[model.vendor] ?? "openrouter";
|
|
99
|
+
return `${provider}/${model.name}`;
|
|
100
|
+
}
|
|
101
|
+
function splitSelector(selector) {
|
|
102
|
+
const slash = selector.indexOf("/");
|
|
103
|
+
if (slash <= 0 || slash === selector.length - 1)
|
|
104
|
+
return undefined;
|
|
105
|
+
return { provider: selector.slice(0, slash), id: selector.slice(slash + 1) };
|
|
106
|
+
}
|
|
107
|
+
function isAvailable(selector, registry) {
|
|
108
|
+
if (!registry?.find)
|
|
109
|
+
return true;
|
|
110
|
+
const split = splitSelector(selector);
|
|
111
|
+
if (!split)
|
|
112
|
+
return false;
|
|
113
|
+
return Boolean(registry.find(split.provider, split.id));
|
|
114
|
+
}
|
|
115
|
+
// ── Core: pick + rank models in a single tier ──
|
|
116
|
+
export function pickModels(table, tier, opts) {
|
|
117
|
+
const ceiling = OUTPUT_COST_CEILING[tier];
|
|
118
|
+
const needs = opts?.needs ?? [];
|
|
119
|
+
const inBudget = table.models.filter((m) => {
|
|
120
|
+
if (m.costOutput === null)
|
|
121
|
+
return tier === "high";
|
|
122
|
+
return m.costOutput <= ceiling;
|
|
123
|
+
});
|
|
124
|
+
const scored = inBudget.map((m) => {
|
|
125
|
+
const { matchScore, met, partial, unmet } = scoreModel(m, needs);
|
|
126
|
+
return {
|
|
127
|
+
selector: toPiSelector(m),
|
|
128
|
+
model: m,
|
|
129
|
+
matchScore,
|
|
130
|
+
met,
|
|
131
|
+
partial,
|
|
132
|
+
unmet,
|
|
133
|
+
};
|
|
134
|
+
});
|
|
135
|
+
scored.sort((a, b) => {
|
|
136
|
+
if (b.matchScore !== a.matchScore)
|
|
137
|
+
return b.matchScore - a.matchScore;
|
|
138
|
+
if (b.model.score !== a.model.score)
|
|
139
|
+
return b.model.score - a.model.score;
|
|
140
|
+
const aCost = a.model.costOutput ?? Number.MAX_SAFE_INTEGER;
|
|
141
|
+
const bCost = b.model.costOutput ?? Number.MAX_SAFE_INTEGER;
|
|
142
|
+
return aCost - bCost;
|
|
143
|
+
});
|
|
144
|
+
return scored.filter((entry) => isAvailable(entry.selector, opts?.registry));
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Start at `budget`, escalate up to `ceiling` if nothing meets `minMatch`.
|
|
148
|
+
* If no ceiling, stays in the budget tier.
|
|
149
|
+
*/
|
|
150
|
+
export function pickModelsAcrossBudget(table, budget, opts) {
|
|
151
|
+
const tiers = tiersInRange(budget, opts?.ceiling);
|
|
152
|
+
const needs = opts?.needs ?? [];
|
|
153
|
+
const minMatch = opts?.minMatch ?? 0.5;
|
|
154
|
+
for (const tier of tiers) {
|
|
155
|
+
const models = pickModels(table, tier, { registry: opts?.registry, needs });
|
|
156
|
+
const acceptable = models.filter((m) => m.matchScore >= minMatch);
|
|
157
|
+
if (acceptable.length > 0) {
|
|
158
|
+
return { tier, escalated: tier !== budget, models: acceptable };
|
|
159
|
+
}
|
|
160
|
+
if (needs.length === 0 && models.length > 0) {
|
|
161
|
+
return { tier, escalated: tier !== budget, models };
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Nothing acceptable at any allowed tier — return best-effort from budget tier
|
|
165
|
+
const fallback = pickModels(table, budget, {
|
|
166
|
+
registry: opts?.registry,
|
|
167
|
+
needs,
|
|
168
|
+
});
|
|
169
|
+
return { tier: budget, escalated: false, models: fallback };
|
|
170
|
+
}
|
|
171
|
+
const DEFAULT_TIMEOUT_MS = 3 * 60_000;
|
|
172
|
+
export async function smartRun(opts) {
|
|
173
|
+
const attempts = [];
|
|
174
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
175
|
+
const table = opts._rankings !== undefined ? opts._rankings : await getRankings();
|
|
176
|
+
let candidates = [];
|
|
177
|
+
let tier = null;
|
|
178
|
+
let escalated = false;
|
|
179
|
+
if (table) {
|
|
180
|
+
const pick = pickModelsAcrossBudget(table, opts.budget, {
|
|
181
|
+
ceiling: opts.ceiling,
|
|
182
|
+
registry: opts.modelRegistry,
|
|
183
|
+
needs: opts.needs,
|
|
184
|
+
minMatch: opts.minMatch,
|
|
185
|
+
});
|
|
186
|
+
tier = pick.tier;
|
|
187
|
+
escalated = pick.escalated;
|
|
188
|
+
candidates = pick.models.map((p) => ({
|
|
189
|
+
selector: p.selector,
|
|
190
|
+
score: p.model.score,
|
|
191
|
+
cost: p.model.costOutput,
|
|
192
|
+
matchScore: p.matchScore,
|
|
193
|
+
}));
|
|
194
|
+
const minMatch = opts.minMatch ?? 0.5;
|
|
195
|
+
const bestMatch = candidates[0]?.matchScore ?? 0;
|
|
196
|
+
if (opts.needs && opts.needs.length > 0 && bestMatch < minMatch) {
|
|
197
|
+
const allModels = pickModels(table, "high", { needs: opts.needs });
|
|
198
|
+
const bestAvailable = allModels[0];
|
|
199
|
+
const reason = bestAvailable
|
|
200
|
+
? `Best match across all tiers: ${bestAvailable.selector} (match=${(bestAvailable.matchScore * 100).toFixed(0)}%, unmet: ${bestAvailable.unmet.join(", ")})`
|
|
201
|
+
: `No models have: ${opts.needs.join(", ")}`;
|
|
202
|
+
if (!opts.fallbackSelectors?.length) {
|
|
203
|
+
return {
|
|
204
|
+
ok: false,
|
|
205
|
+
finalModel: null,
|
|
206
|
+
output: "",
|
|
207
|
+
attempts: [],
|
|
208
|
+
tier,
|
|
209
|
+
escalated,
|
|
210
|
+
rankings: { fetchedAt: table.fetchedAt, candidateCount: 0 },
|
|
211
|
+
noMatchReason: reason,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
candidates = [];
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (opts.fallbackSelectors) {
|
|
218
|
+
const seen = new Set(candidates.map((c) => c.selector));
|
|
219
|
+
for (const sel of opts.fallbackSelectors) {
|
|
220
|
+
if (!seen.has(sel)) {
|
|
221
|
+
candidates.push({
|
|
222
|
+
selector: sel,
|
|
223
|
+
score: null,
|
|
224
|
+
cost: null,
|
|
225
|
+
matchScore: null,
|
|
226
|
+
});
|
|
227
|
+
seen.add(sel);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
if (candidates.length === 0) {
|
|
232
|
+
return {
|
|
233
|
+
ok: false,
|
|
234
|
+
finalModel: null,
|
|
235
|
+
output: "",
|
|
236
|
+
attempts: [],
|
|
237
|
+
tier,
|
|
238
|
+
escalated,
|
|
239
|
+
rankings: null,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
for (const candidate of candidates) {
|
|
243
|
+
if (opts.signal?.aborted)
|
|
244
|
+
break;
|
|
245
|
+
const result = await opts.runner({
|
|
246
|
+
cwd: opts.cwd,
|
|
247
|
+
prompt: opts.prompt,
|
|
248
|
+
model: candidate.selector,
|
|
249
|
+
thinking: opts.thinking,
|
|
250
|
+
tools: opts.tools,
|
|
251
|
+
timeoutMs,
|
|
252
|
+
signal: opts.signal,
|
|
253
|
+
extensionPaths: opts.extensionPaths,
|
|
254
|
+
});
|
|
255
|
+
const failed = result.exitCode !== 0 || result.timedOut || Boolean(result.errorMessage);
|
|
256
|
+
let errorMessage;
|
|
257
|
+
if (failed) {
|
|
258
|
+
errorMessage = result.errorMessage;
|
|
259
|
+
if (!errorMessage && result.timedOut)
|
|
260
|
+
errorMessage = "timeout";
|
|
261
|
+
if (!errorMessage)
|
|
262
|
+
errorMessage = `exit ${result.exitCode}`;
|
|
263
|
+
}
|
|
264
|
+
attempts.push({
|
|
265
|
+
selector: candidate.selector,
|
|
266
|
+
score: candidate.score,
|
|
267
|
+
cost: candidate.cost,
|
|
268
|
+
matchScore: candidate.matchScore,
|
|
269
|
+
status: failed ? "failed" : "success",
|
|
270
|
+
errorMessage,
|
|
271
|
+
durationMs: result.durationMs,
|
|
272
|
+
inputTokens: result.inputTokens,
|
|
273
|
+
outputTokens: result.outputTokens,
|
|
274
|
+
});
|
|
275
|
+
if (!failed) {
|
|
276
|
+
return {
|
|
277
|
+
ok: true,
|
|
278
|
+
finalModel: candidate.selector,
|
|
279
|
+
output: result.finalText || result.stdout,
|
|
280
|
+
attempts,
|
|
281
|
+
tier,
|
|
282
|
+
escalated,
|
|
283
|
+
rankings: table
|
|
284
|
+
? { fetchedAt: table.fetchedAt, candidateCount: candidates.length }
|
|
285
|
+
: null,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return {
|
|
290
|
+
ok: false,
|
|
291
|
+
finalModel: null,
|
|
292
|
+
output: "",
|
|
293
|
+
attempts,
|
|
294
|
+
tier,
|
|
295
|
+
escalated,
|
|
296
|
+
rankings: table
|
|
297
|
+
? { fetchedAt: table.fetchedAt, candidateCount: candidates.length }
|
|
298
|
+
: null,
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
export function formatSmartRunSummary(result) {
|
|
302
|
+
const lines = [];
|
|
303
|
+
if (result.ok) {
|
|
304
|
+
lines.push(`Model: ${result.finalModel}`);
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
lines.push("All models failed.");
|
|
308
|
+
}
|
|
309
|
+
if (result.escalated) {
|
|
310
|
+
lines.push(`Escalated to tier: ${result.tier}`);
|
|
311
|
+
}
|
|
312
|
+
if (result.noMatchReason) {
|
|
313
|
+
lines.push(`No match: ${result.noMatchReason}`);
|
|
314
|
+
}
|
|
315
|
+
if (result.rankings) {
|
|
316
|
+
lines.push(`Rankings: ${result.rankings.candidateCount} candidates (cached ${result.rankings.fetchedAt})`);
|
|
317
|
+
}
|
|
318
|
+
if (result.attempts.length > 1 || !result.ok) {
|
|
319
|
+
lines.push("Attempts:");
|
|
320
|
+
for (const a of result.attempts) {
|
|
321
|
+
const cost = a.cost !== null ? `$${a.cost}/MTok` : "n/a";
|
|
322
|
+
const match = a.matchScore !== null
|
|
323
|
+
? `match=${(a.matchScore * 100).toFixed(0)}%`
|
|
324
|
+
: "";
|
|
325
|
+
const dur = a.durationMs !== undefined
|
|
326
|
+
? `${(a.durationMs / 1000).toFixed(1)}s`
|
|
327
|
+
: "";
|
|
328
|
+
let status = a.errorMessage ?? "failed";
|
|
329
|
+
if (a.status === "success")
|
|
330
|
+
status = "ok";
|
|
331
|
+
lines.push(` ${a.selector} score=${a.score ?? "?"} ${match} cost=${cost} ${dur} → ${status}`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return lines.join("\n");
|
|
335
|
+
}
|
|
336
|
+
//# sourceMappingURL=smart-run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-run.js","sourceRoot":"","sources":["../src/smart-run.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "smart-model-run",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Benchmark-driven smart model selection and fallback runner for agent workloads.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "b-koop",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist/",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./smart-run": {
|
|
18
|
+
"types": "./dist/smart-run.d.ts",
|
|
19
|
+
"import": "./dist/smart-run.js"
|
|
20
|
+
},
|
|
21
|
+
"./model-rankings": {
|
|
22
|
+
"types": "./dist/model-rankings.d.ts",
|
|
23
|
+
"import": "./dist/model-rankings.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc -p tsconfig.build.json",
|
|
29
|
+
"typecheck": "tsc --noEmit",
|
|
30
|
+
"test": "pnpm typecheck && vitest run",
|
|
31
|
+
"vitest": "vitest run",
|
|
32
|
+
"prepare": "pnpm build",
|
|
33
|
+
"prepublishOnly": "pnpm build && pnpm test",
|
|
34
|
+
"pack:check": "npm pack --dry-run"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^25.9.2",
|
|
38
|
+
"typescript": "^5.9.3",
|
|
39
|
+
"vitest": "latest"
|
|
40
|
+
}
|
|
41
|
+
}
|