terminal-smart-cli 0.94.0 → 0.94.2
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/lib/eval.js +42 -10
- package/lib/intelligence-core.js +3 -3
- package/package.json +2 -2
package/lib/eval.js
CHANGED
|
@@ -20,6 +20,7 @@ const fs = require('fs');
|
|
|
20
20
|
const path = require('path');
|
|
21
21
|
const { api } = require('./api');
|
|
22
22
|
const agent = require('./agent');
|
|
23
|
+
const intelligence = require('./intelligence-core');
|
|
23
24
|
|
|
24
25
|
// modelo default do JUIZ: barato e suficiente pra avaliar critério objetivo.
|
|
25
26
|
const DEFAULT_JUDGE = 'deepseek-v4-flash';
|
|
@@ -163,6 +164,7 @@ async function runSuite(suite, opts = {}) {
|
|
|
163
164
|
let sandbox = null;
|
|
164
165
|
let evidence = { text: '', error: null, diff: { criados: [], alterados: [], removidos: [] } };
|
|
165
166
|
let runCredits = 0, runSteps = 0, verdict = null, judgeTin = 0, judgeTout = 0;
|
|
167
|
+
let actualModel = null, substituted = false;
|
|
166
168
|
const t0 = Date.now();
|
|
167
169
|
try {
|
|
168
170
|
// sandbox DENTRO do try: se mkdtempSync falhar (EMFILE/disco cheio/permissão) o caso
|
|
@@ -192,17 +194,33 @@ async function runSuite(suite, opts = {}) {
|
|
|
192
194
|
evidence.error = String((e && e.message) || e).slice(0, 300);
|
|
193
195
|
out = null;
|
|
194
196
|
}
|
|
195
|
-
if (out) {
|
|
197
|
+
if (out) {
|
|
198
|
+
evidence.text = out.text || '';
|
|
199
|
+
runCredits = out.credits || 0;
|
|
200
|
+
runSteps = out.steps || 0;
|
|
201
|
+
actualModel = out.model || null;
|
|
202
|
+
substituted = !_sameRequestedModel(model, actualModel);
|
|
203
|
+
if (substituted) {
|
|
204
|
+
evidence.error = `model_substituted: requested=${model}; actual=${actualModel || 'unknown'}`;
|
|
205
|
+
verdict = {
|
|
206
|
+
pass: false,
|
|
207
|
+
score: 0,
|
|
208
|
+
reason: `modelo solicitado "${model}" foi substituído por "${actualModel || 'desconhecido'}"; resultado não é comparável`,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
}
|
|
196
212
|
const after = _snap(sandbox);
|
|
197
213
|
evidence.diff = _diff(before, after);
|
|
198
214
|
// julga (mesmo com erro fatal — o juiz vê o erro e reprova com motivo)
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
215
|
+
if (!substituted) {
|
|
216
|
+
onCase({ i, total, id: c.id, phase: 'judge' });
|
|
217
|
+
try {
|
|
218
|
+
verdict = await judge({ key: k.key, baseUrl: k.baseUrl, model: judgeModel, caseObj: c, evidence });
|
|
219
|
+
judgeTin = verdict._tin || 0; judgeTout = verdict._tout || 0;
|
|
220
|
+
} catch (e) {
|
|
221
|
+
if (e && (e.code === 'no_credits' || e.status === 402)) throw e;
|
|
222
|
+
verdict = { pass: false, score: 0, reason: 'juiz falhou: ' + String((e && e.message) || e).slice(0, 120) };
|
|
223
|
+
}
|
|
206
224
|
}
|
|
207
225
|
} catch (e) {
|
|
208
226
|
// teto de IA → aborta a suíte inteira (o finally limpa o sandbox antes de propagar).
|
|
@@ -219,6 +237,7 @@ async function runSuite(suite, opts = {}) {
|
|
|
219
237
|
results.push({
|
|
220
238
|
id: c.id, pass: verdict.pass, score: verdict.score, reason: verdict.reason,
|
|
221
239
|
error: evidence.error, steps: runSteps, credits: runCredits,
|
|
240
|
+
requestedModel: model, actualModel, substituted,
|
|
222
241
|
changed: evidence.diff.criados.length + evidence.diff.alterados.length,
|
|
223
242
|
judgeTokens: judgeTin + judgeTout, ms: Date.now() - t0, judgeRaw: verdict._raw || null,
|
|
224
243
|
});
|
|
@@ -235,6 +254,8 @@ async function runSuite(suite, opts = {}) {
|
|
|
235
254
|
// exibidos à parte pra o custo do relatório ser honesto).
|
|
236
255
|
judgeTokens: results.reduce((a, r) => a + (r.judgeTokens || 0), 0),
|
|
237
256
|
ms: results.reduce((a, r) => a + (r.ms || 0), 0),
|
|
257
|
+
actualModels: [...new Set(results.map(r => r.actualModel).filter(Boolean))],
|
|
258
|
+
substitutions: results.filter(r => r.substituted).length,
|
|
238
259
|
};
|
|
239
260
|
return { summary, results };
|
|
240
261
|
}
|
|
@@ -242,6 +263,12 @@ async function runSuite(suite, opts = {}) {
|
|
|
242
263
|
// ── MODEL LAB: roda a MESMA suíte em VÁRIOS executores e compara (bake-off automático) ──
|
|
243
264
|
// Automatiza o "veredito modelo X" que antes era manual. O JUIZ é fixo (mesmo pra todos =
|
|
244
265
|
// comparação justa); só o EXECUTOR muda. Ranqueia por qualidade VERIFICADA e depois por custo.
|
|
266
|
+
function _sameRequestedModel(requested, actual) {
|
|
267
|
+
if (!requested) return true;
|
|
268
|
+
if (!actual) return false;
|
|
269
|
+
return intelligence.normalizeModelId(requested) === intelligence.normalizeModelId(actual);
|
|
270
|
+
}
|
|
271
|
+
|
|
245
272
|
function _rankModels(rows) {
|
|
246
273
|
// ordena: mais casos aprovados (passRate) → maior score médio → MENOR custo → mais rápido.
|
|
247
274
|
const sorted = [...rows].sort((a, b) =>
|
|
@@ -264,7 +291,12 @@ async function runMatrix(suite, opts = {}) {
|
|
|
264
291
|
if (e && (e.code === 'no_credits' || e.status === 402)) throw e; // teto → aborta o bake-off
|
|
265
292
|
sum = { name: suite.name, total: suite.cases.length, passed: 0, failed: suite.cases.length, passRate: 0, avgScore: 0, credits: 0, judgeTokens: 0, ms: 0, error: String((e && e.message) || e).slice(0, 160) };
|
|
266
293
|
}
|
|
267
|
-
const row = {
|
|
294
|
+
const row = {
|
|
295
|
+
model, passRate: sum.passRate, avgScore: sum.avgScore, passed: sum.passed, total: sum.total,
|
|
296
|
+
credits: sum.credits, judgeTokens: sum.judgeTokens, ms: sum.ms,
|
|
297
|
+
actualModels: sum.actualModels || [], substitutions: sum.substitutions || 0,
|
|
298
|
+
error: sum.error || null,
|
|
299
|
+
};
|
|
268
300
|
rows.push(row);
|
|
269
301
|
onModel({ model, phase: 'done', row });
|
|
270
302
|
}
|
|
@@ -273,4 +305,4 @@ async function runMatrix(suite, opts = {}) {
|
|
|
273
305
|
}
|
|
274
306
|
|
|
275
307
|
module.exports = { loadSuite, normCases, runSuite, runMatrix, judge, smokeSuite, EXAMPLE,
|
|
276
|
-
_test: { _diff, _snap, _extractJson, normCases, _rankModels } };
|
|
308
|
+
_test: { _diff, _snap, _extractJson, normCases, _rankModels, _sameRequestedModel } };
|
package/lib/intelligence-core.js
CHANGED
|
@@ -79,17 +79,17 @@ const MODEL_CATALOG = Object.freeze({
|
|
|
79
79
|
'laguna-s-2.1': {
|
|
80
80
|
upstreamId: 'poolside/laguna-s-2.1',
|
|
81
81
|
provider: 'openrouter', contextWindow: 1048576, price: { input: 0.10, output: 0.20, cachedInput: 0.01 },
|
|
82
|
-
capabilities: ['
|
|
82
|
+
capabilities: ['code', 'review', 'long-context'], toolReliability: 0.25, quality: 0.75,
|
|
83
83
|
},
|
|
84
84
|
'gpt-oss-120b': {
|
|
85
85
|
upstreamId: 'openai/gpt-oss-120b',
|
|
86
86
|
provider: 'openrouter', contextWindow: 131072, price: { input: 0.037, output: 0.17, cachedInput: 0.037 },
|
|
87
|
-
capabilities: ['tools', 'code', 'review'], toolReliability: 0.
|
|
87
|
+
capabilities: ['tools', 'code', 'review'], toolReliability: 0.75, quality: 0.78,
|
|
88
88
|
},
|
|
89
89
|
'ling-2.6-flash': {
|
|
90
90
|
upstreamId: 'inclusionai/ling-2.6-flash',
|
|
91
91
|
provider: 'openrouter', contextWindow: 262144, price: { input: 0.01, output: 0.03, cachedInput: 0.002 },
|
|
92
|
-
capabilities: ['tools', 'classification', 'summarization'], toolReliability: 0.
|
|
92
|
+
capabilities: ['tools', 'classification', 'summarization'], toolReliability: 0.70, quality: 0.60,
|
|
93
93
|
},
|
|
94
94
|
});
|
|
95
95
|
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "terminal-smart-cli",
|
|
3
|
-
"version": "0.94.
|
|
3
|
+
"version": "0.94.2",
|
|
4
4
|
"description": "Terminal Smart no seu terminal — pergunte, analise logs por pipe e orquestre agentes de IA. Comando: ts",
|
|
5
5
|
"bin": {
|
|
6
6
|
"ts": "bin/ts.js"
|
|
7
7
|
},
|
|
8
8
|
"scripts": {
|
|
9
|
-
"test": "node test/core.test.js && node test/intelligence-core.test.js && node test/project-cache.test.js && node test/memory-bus.test.js && node test/capabilities.test.js && node test/mcp-e2e.test.js && node test/erros.test.js"
|
|
9
|
+
"test": "node test/core.test.js && node test/intelligence-core.test.js && node test/eval-model.test.js && node test/project-cache.test.js && node test/memory-bus.test.js && node test/capabilities.test.js && node test/mcp-e2e.test.js && node test/erros.test.js"
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
12
|
"bin",
|