@trazum/cli 1.50.8 → 1.50.9
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/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +34 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/es.d.ts.map +1 -1
- package/dist/i18n/es.js +34 -0
- package/dist/i18n/es.js.map +1 -1
- package/dist/i18n/types.d.ts +14 -0
- package/dist/i18n/types.d.ts.map +1 -1
- package/dist/index.js +94 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/i18n/en.ts +42 -0
- package/src/i18n/es.ts +42 -0
- package/src/i18n/types.ts +15 -0
- package/src/index.ts +128 -0
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { open, readdir, readFile, stat, writeFile } from 'node:fs/promises';
|
|
|
4
4
|
import { dirname, join, resolve as resolvePath } from 'node:path';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
6
|
import { gunzipSync } from 'node:zlib';
|
|
7
|
-
import { applyRewrites, BASELINE_FILENAME, BASELINE_VERSION, breaches, cacheableMinimum, analyzeCachePrefix, billLevers, bucketedCacheEconomics, bucketedProfile, buildHistory, buildPlan, connectorFor, CONNECTORS, normalizeAnthropicUsage, normalizeOpenAIUsage, bucketsFromRecords, evaluateWatch, firedKey, pruneRecords, recordsFromBuckets, storeInventory, storedReportFrom, verifyPlan, cacheEconomics, cacheHitRate, contextPressure, comparePrompts, compareToBaseline, computeSavings, countTokensAnthropic, DEFAULT_USAGE, budgetPositions, conform, BREAK_EVEN_BAND, runExperiment, qualityGate, ladderPosition, validateLadder, outcomeReport, rankPerOutcome, FAILURE_POLICIES, detectFromSource, matchLocale, parsePlanDocument, waiverDay, waiverHistory, proposeInit, MIN_RATE_DAYS, parseConfig, coverageDrift, driversBetween, explainGateFailure, assignSources, fleetRollup, labelCoverage, measuredUsage, gateMargin, GATE_MARGIN_TIGHT, estimateTokens, evaluate, extractPrompts, findExamples, formatBaseline, formatSignedUsd, formatUsd, getMessages, getModel, hasMarker, LOCALES, MAX_BASELINE_BYTES, moneyIsComparable, mostSpecificMatch, nearestName, optimize, parseBaseline, PHRASE_LANGUAGES, plannedCalls, profilePrompt, profileToCsv, profileUsage, promptId, providerFromEnv, pruneExamples, refineWithLlm, rejectionText, reorderForCache, repriceProfile, reviewAgeDays, reviewExamples, RULES, sharedPrefixes, sharesOf, SOURCE_EXTENSIONS, suggestRewrites, toOtlpMetrics, toPromptfoo, TTL_1H_MS, UNLABELLED, withExactTokenCounts, } from '@trazum/core';
|
|
7
|
+
import { applyRewrites, BASELINE_FILENAME, BASELINE_VERSION, breaches, cacheableMinimum, analyzeCachePrefix, billLevers, bucketedCacheEconomics, bucketedProfile, buildHistory, buildPlan, connectorFor, CONNECTORS, normalizeAnthropicUsage, normalizeOpenAIUsage, bucketsFromRecords, evaluateWatch, firedKey, pruneRecords, recordsFromBuckets, storeInventory, storedReportFrom, verifyPlan, cacheEconomics, cacheHitRate, contextPressure, comparePrompts, compareToBaseline, computeSavings, countTokensAnthropic, DEFAULT_USAGE, budgetPositions, conform, BREAK_EVEN_BAND, runExperiment, qualityGate, semanticPassCost, verifySemanticProposals, SEMANTIC_SYSTEM_PROMPT, ladderPosition, validateLadder, outcomeReport, rankPerOutcome, FAILURE_POLICIES, detectFromSource, matchLocale, parsePlanDocument, waiverDay, waiverHistory, proposeInit, MIN_RATE_DAYS, parseConfig, coverageDrift, driversBetween, explainGateFailure, assignSources, fleetRollup, labelCoverage, measuredUsage, gateMargin, GATE_MARGIN_TIGHT, estimateTokens, evaluate, extractPrompts, findExamples, formatBaseline, formatSignedUsd, formatUsd, getMessages, getModel, hasMarker, LOCALES, MAX_BASELINE_BYTES, moneyIsComparable, mostSpecificMatch, nearestName, optimize, parseBaseline, PHRASE_LANGUAGES, plannedCalls, profilePrompt, profileToCsv, profileUsage, promptId, providerFromEnv, pruneExamples, refineWithLlm, rejectionText, reorderForCache, repriceProfile, reviewAgeDays, reviewExamples, RULES, sharedPrefixes, sharesOf, SOURCE_EXTENSIONS, suggestRewrites, toOtlpMetrics, toPromptfoo, TTL_1H_MS, UNLABELLED, withExactTokenCounts, } from '@trazum/core';
|
|
8
8
|
import { cacheDir, cacheStats, cachingProvider, clearCache } from './suggest-cache.js';
|
|
9
9
|
import { dayOf, formatGap, median, spanDays } from './time.js';
|
|
10
10
|
// Everything that reads the filesystem, on its own entry point so the web
|
|
@@ -326,6 +326,7 @@ const COMMAND_FLAGS = {
|
|
|
326
326
|
ladder: ['pricing', 'pricing-live', 'since', 'until', 'label'],
|
|
327
327
|
experiment: ['a', 'b', 'min-outcomes', 'pricing', 'pricing-live'],
|
|
328
328
|
quality: ['label', 'at', 'gate', 'pricing', 'pricing-live'],
|
|
329
|
+
semantic: ['yes', 'model', 'pricing', 'pricing-live'],
|
|
329
330
|
where: [],
|
|
330
331
|
rules: [],
|
|
331
332
|
blame: ['limit', 'model', 'calls', 'output-tokens', 'batch', 'prompt', 'markdown-out'],
|
|
@@ -1966,6 +1967,95 @@ async function commandQuality(args, config, pricing, t) {
|
|
|
1966
1967
|
}
|
|
1967
1968
|
console.log();
|
|
1968
1969
|
}
|
|
1970
|
+
/**
|
|
1971
|
+
* `trazum semantic <prompt> [--yes]` — the findings a dictionary cannot see.
|
|
1972
|
+
*
|
|
1973
|
+
* The rules engine has deferred these since 0.1.0 for one honest reason: a
|
|
1974
|
+
* dictionary cannot see meaning, and a model that hallucinates a finding is
|
|
1975
|
+
* worse than a rule that misses one.
|
|
1976
|
+
*
|
|
1977
|
+
* **The price is printed before anything is sent, and `--yes` is required.** A
|
|
1978
|
+
* tool that spends somebody's money to tell them how to spend less has to be
|
|
1979
|
+
* the first thing audited by its own arithmetic, and it has to ask.
|
|
1980
|
+
*/
|
|
1981
|
+
async function commandSemantic(args, config, pricing, t) {
|
|
1982
|
+
const prompt = await readInput(args.positional[0], t);
|
|
1983
|
+
const modelId = stringFlag(args, 'model') ?? config.usage?.model ?? DEFAULT_USAGE.model;
|
|
1984
|
+
const model = pricing.byId.get(modelId) ?? getModel(DEFAULT_USAGE.model);
|
|
1985
|
+
const rates = { inputPerMTok: model.inputPerMTok, outputPerMTok: model.outputPerMTok };
|
|
1986
|
+
const cost = semanticPassCost(prompt, rates);
|
|
1987
|
+
const n = (value) => value.toLocaleString(t.numberLocale);
|
|
1988
|
+
console.log();
|
|
1989
|
+
console.log(c.bold(t.semantic.heading(args.positional[0] ?? '-')));
|
|
1990
|
+
console.log();
|
|
1991
|
+
console.log(` ${wrap(t.semantic.willCost(formatUsd(cost.usd), n(cost.inputTokens), n(cost.outputTokens), model.displayName), 74, ' ')}`);
|
|
1992
|
+
if (!boolFlag(args, 'yes')) {
|
|
1993
|
+
// Nothing has been sent at this point, and nothing will be. The price
|
|
1994
|
+
// above is the whole output of a run without --yes.
|
|
1995
|
+
console.log();
|
|
1996
|
+
console.log(` ${c.dim(t.semantic.needsYes())}`);
|
|
1997
|
+
console.log();
|
|
1998
|
+
return;
|
|
1999
|
+
}
|
|
2000
|
+
const provider = providerFromEnv();
|
|
2001
|
+
if (!provider)
|
|
2002
|
+
throw new Error(t.errors.llmNotConfigured());
|
|
2003
|
+
const answer = await provider.complete({ system: SEMANTIC_SYSTEM_PROMPT, user: prompt });
|
|
2004
|
+
let proposals = [];
|
|
2005
|
+
try {
|
|
2006
|
+
const parsed = JSON.parse(/^(?:```|~~~)[a-zA-Z]*\n([\s\S]*?)\n?(?:```|~~~)$/.exec(answer.trim())?.[1] ?? answer.trim());
|
|
2007
|
+
/**
|
|
2008
|
+
* A response that is not the shape asked for is **no proposals**, never a
|
|
2009
|
+
* crash and never a partial read. The model was told exactly what to
|
|
2010
|
+
* return; anything else is a response this layer cannot check, and an
|
|
2011
|
+
* unchecked finding is the one thing this whole module exists to prevent.
|
|
2012
|
+
*/
|
|
2013
|
+
if (Array.isArray(parsed)) {
|
|
2014
|
+
proposals = parsed.filter((entry) => typeof entry === 'object' &&
|
|
2015
|
+
entry !== null &&
|
|
2016
|
+
Array.isArray(entry.spans) &&
|
|
2017
|
+
entry.spans.length === 2 &&
|
|
2018
|
+
entry.spans.every((span) => typeof span === 'string'));
|
|
2019
|
+
}
|
|
2020
|
+
}
|
|
2021
|
+
catch {
|
|
2022
|
+
proposals = [];
|
|
2023
|
+
}
|
|
2024
|
+
const result = verifySemanticProposals(prompt, proposals);
|
|
2025
|
+
const lineOf = (offset) => prompt.slice(0, offset).split('\n').length;
|
|
2026
|
+
console.log();
|
|
2027
|
+
if (result.findings.length === 0) {
|
|
2028
|
+
console.log(` ${c.dim(t.semantic.nothingFound())}`);
|
|
2029
|
+
}
|
|
2030
|
+
for (const finding of result.findings) {
|
|
2031
|
+
console.log(` ${c.bold(t.semantic.finding(finding.kind, finding.because))}`);
|
|
2032
|
+
finding.spans.forEach((span, index) => {
|
|
2033
|
+
const shown = span.length > 90 ? `${span.slice(0, 87)}…` : span;
|
|
2034
|
+
console.log(` ${c.dim(t.semantic.span(String(lineOf(finding.offsets[index] ?? 0)), shown))}`);
|
|
2035
|
+
});
|
|
2036
|
+
console.log(` ${c.dim(wrap(finding.ceilingTokens > 0 ? t.semantic.ceiling(n(finding.ceilingTokens)) : t.semantic.noCeiling(), 70, ' '))}`);
|
|
2037
|
+
console.log();
|
|
2038
|
+
}
|
|
2039
|
+
/**
|
|
2040
|
+
* What did **not** survive, counted and reasoned.
|
|
2041
|
+
*
|
|
2042
|
+
* A pass that showed only its accepted findings would hide its own hit
|
|
2043
|
+
* rate, and the hit rate is the most useful thing a reader can know about
|
|
2044
|
+
* whether to run it again.
|
|
2045
|
+
*/
|
|
2046
|
+
if (result.rejected.length > 0) {
|
|
2047
|
+
console.log(` ${c.dim(t.semantic.rejected(n(result.rejected.length)))}`);
|
|
2048
|
+
for (const { proposal, reason } of result.rejected.slice(0, 5)) {
|
|
2049
|
+
const span = proposal.spans[0];
|
|
2050
|
+
const shown = span.length > 50 ? `${span.slice(0, 47)}…` : span;
|
|
2051
|
+
console.log(` ${c.dim(t.semantic.rejectedLine(reason, shown))}`);
|
|
2052
|
+
}
|
|
2053
|
+
console.log();
|
|
2054
|
+
}
|
|
2055
|
+
console.log(` ${c.dim(wrap(t.semantic.disposes(), 74, ' '))}`);
|
|
2056
|
+
console.log(` ${c.dim(wrap(t.semantic.optIn(), 74, ' '))}`);
|
|
2057
|
+
console.log();
|
|
2058
|
+
}
|
|
1969
2059
|
function commandModels(t, pricing) {
|
|
1970
2060
|
const n = (value) => value.toLocaleString(t.numberLocale);
|
|
1971
2061
|
const col = t.models.columns;
|
|
@@ -7013,6 +7103,9 @@ async function main() {
|
|
|
7013
7103
|
case 'models':
|
|
7014
7104
|
commandModels(t, pricing);
|
|
7015
7105
|
break;
|
|
7106
|
+
case 'semantic':
|
|
7107
|
+
await commandSemantic(args, config, pricing, t);
|
|
7108
|
+
break;
|
|
7016
7109
|
case 'quality':
|
|
7017
7110
|
await commandQuality(args, config, pricing, t);
|
|
7018
7111
|
break;
|