alys-akusa 0.1.2 → 0.1.3
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 +1 -1
- package/dist/index.cjs +239 -44
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -4928,6 +4928,8 @@ function printBanner() {
|
|
|
4928
4928
|
function printHelp() {
|
|
4929
4929
|
printBanner();
|
|
4930
4930
|
console.log(`
|
|
4931
|
+
Alys runs in your terminal. The dashboard tracks what it generates.
|
|
4932
|
+
|
|
4931
4933
|
Usage:
|
|
4932
4934
|
npx alys-akusa
|
|
4933
4935
|
npx alys-akusa login
|
|
@@ -5014,7 +5016,7 @@ async function requestJson(pathname, init = {}, token) {
|
|
|
5014
5016
|
const response = await fetch(apiUrl(pathname), { ...init, headers });
|
|
5015
5017
|
const payload = await response.json().catch(() => ({}));
|
|
5016
5018
|
if (!response.ok) {
|
|
5017
|
-
const message = typeof payload?.error === "string" ? payload.error : `Alys
|
|
5019
|
+
const message = typeof payload?.error === "string" ? payload.error : `Alys request failed (${response.status}).`;
|
|
5018
5020
|
throw new CliApiError(message, response.status, payload);
|
|
5019
5021
|
}
|
|
5020
5022
|
return payload;
|
|
@@ -5078,6 +5080,19 @@ function parseDepth(value) {
|
|
|
5078
5080
|
if (value === "shallow" || value === "medium" || value === "deep") return value;
|
|
5079
5081
|
return void 0;
|
|
5080
5082
|
}
|
|
5083
|
+
function normalizeTopicInput(value) {
|
|
5084
|
+
if (typeof value !== "string") return "";
|
|
5085
|
+
let topic = value.replace(/\[[^\]]+\][^\n\r]*/g, "").replace(/\s+/g, " ").trim();
|
|
5086
|
+
const commandMatch = topic.match(/^(?:npx\s+)?(?:alys-akusa(?:@latest)?|alys)\s+generate\s+(.+)$/i);
|
|
5087
|
+
if (commandMatch) {
|
|
5088
|
+
topic = commandMatch[1].trim();
|
|
5089
|
+
}
|
|
5090
|
+
const quoted = topic.match(/^"([^"]+)"|^'([^']+)'/);
|
|
5091
|
+
if (quoted) {
|
|
5092
|
+
return (quoted[1] || quoted[2] || "").trim();
|
|
5093
|
+
}
|
|
5094
|
+
return topic.replace(/\s+--(?:format|type|datasets|depth|sources|rows|workspace)\s+\S.*$/i, "").replace(/\s+--(?:verify|no-verify|yes)\b.*$/i, "").trim();
|
|
5095
|
+
}
|
|
5081
5096
|
function resolveHome(p) {
|
|
5082
5097
|
if (p.startsWith("~/")) return import_node_path.default.join(import_node_os.default.homedir(), p.slice(2));
|
|
5083
5098
|
return p;
|
|
@@ -5085,14 +5100,94 @@ function resolveHome(p) {
|
|
|
5085
5100
|
function formatInt(value) {
|
|
5086
5101
|
return new Intl.NumberFormat("en-US").format(value);
|
|
5087
5102
|
}
|
|
5103
|
+
function formatPercent(value) {
|
|
5104
|
+
if (!Number.isFinite(value) || value <= 0) return "pending";
|
|
5105
|
+
return `${Math.round(value * 100)}%`;
|
|
5106
|
+
}
|
|
5107
|
+
function formatScore(value) {
|
|
5108
|
+
if (!Number.isFinite(value) || value <= 0) return "pending";
|
|
5109
|
+
return `${Math.round(value)}/100`;
|
|
5110
|
+
}
|
|
5111
|
+
function average(values) {
|
|
5112
|
+
const filtered = values.filter((value) => Number.isFinite(value) && value > 0);
|
|
5113
|
+
return filtered.length ? filtered.reduce((sum, value) => sum + value, 0) / filtered.length : 0;
|
|
5114
|
+
}
|
|
5115
|
+
function truncate(value, max = 88) {
|
|
5116
|
+
const normalized = value.replace(/\s+/g, " ").trim();
|
|
5117
|
+
return normalized.length > max ? `${normalized.slice(0, max - 1)}\u2026` : normalized;
|
|
5118
|
+
}
|
|
5119
|
+
function getMetrics(dataset) {
|
|
5120
|
+
const metrics = dataset.manifest.metrics;
|
|
5121
|
+
return metrics && typeof metrics === "object" ? metrics : {};
|
|
5122
|
+
}
|
|
5123
|
+
function getSummary(dataset) {
|
|
5124
|
+
const summary = dataset.manifest.generationSummary;
|
|
5125
|
+
return summary && typeof summary === "object" ? summary : {};
|
|
5126
|
+
}
|
|
5127
|
+
function getQualityMetrics(dataset) {
|
|
5128
|
+
const metrics = dataset.manifest.qualityMetrics;
|
|
5129
|
+
return metrics && typeof metrics === "object" ? metrics : {};
|
|
5130
|
+
}
|
|
5131
|
+
function getEvaluation(dataset) {
|
|
5132
|
+
const evaluation = dataset.manifest.evaluation;
|
|
5133
|
+
return evaluation && typeof evaluation === "object" ? evaluation : {};
|
|
5134
|
+
}
|
|
5135
|
+
function printStage(code, status, label, metric) {
|
|
5136
|
+
const tint = status === "DONE" || status === "OK" ? "green" : status === "WARN" ? "yellow" : "cyan";
|
|
5137
|
+
const prefix = `${paint(`[${code.padEnd(4).slice(0, 4)}]`, "gray")} ${paint(status.padEnd(4), tint)}`;
|
|
5138
|
+
console.log(`${prefix} ${label}${metric ? ` ${paint(metric, "gray")}` : ""}`);
|
|
5139
|
+
}
|
|
5140
|
+
async function withSpinner(label, task) {
|
|
5141
|
+
if (!process.stdout.isTTY) {
|
|
5142
|
+
printStage("RUN", "RUN", label);
|
|
5143
|
+
return task;
|
|
5144
|
+
}
|
|
5145
|
+
const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
5146
|
+
let index = 0;
|
|
5147
|
+
process.stdout.write(`${paint(frames[index], "yellow")} ${label}`);
|
|
5148
|
+
const interval = setInterval(() => {
|
|
5149
|
+
index = (index + 1) % frames.length;
|
|
5150
|
+
process.stdout.write(`\r${paint(frames[index], "yellow")} ${label}`);
|
|
5151
|
+
}, 90);
|
|
5152
|
+
try {
|
|
5153
|
+
const result = await task;
|
|
5154
|
+
clearInterval(interval);
|
|
5155
|
+
process.stdout.write(`\r${paint("\u2713", "green")} ${label}
|
|
5156
|
+
`);
|
|
5157
|
+
return result;
|
|
5158
|
+
} catch (error) {
|
|
5159
|
+
clearInterval(interval);
|
|
5160
|
+
process.stdout.write(`\r${paint("\xD7", "red")} ${label}
|
|
5161
|
+
`);
|
|
5162
|
+
throw error;
|
|
5163
|
+
}
|
|
5164
|
+
}
|
|
5165
|
+
function previewRecord(dataset) {
|
|
5166
|
+
const file = dataset.files.find((item) => item.format === "jsonl" || item.format === "instruction" || item.format === "rag");
|
|
5167
|
+
const firstLine = file?.content.split(/\r?\n/).find((line) => line.trim().length > 0);
|
|
5168
|
+
if (!firstLine) return null;
|
|
5169
|
+
try {
|
|
5170
|
+
const parsed = JSON.parse(firstLine);
|
|
5171
|
+
const input = typeof parsed.input === "string" ? parsed.input : typeof parsed.instruction === "string" ? parsed.instruction : typeof parsed.question === "string" ? parsed.question : "";
|
|
5172
|
+
const output = typeof parsed.output === "string" ? parsed.output : typeof parsed.answer === "string" ? parsed.answer : typeof parsed.completion === "string" ? parsed.completion : typeof parsed.text === "string" ? parsed.text : "";
|
|
5173
|
+
if (!input && !output) return null;
|
|
5174
|
+
const metadata = parsed.metadata && typeof parsed.metadata === "object" ? parsed.metadata : {};
|
|
5175
|
+
const explanation = Array.isArray(metadata.acceptance_explanation) ? metadata.acceptance_explanation.filter((item) => typeof item === "string") : Array.isArray(metadata.acceptance_reasons) ? metadata.acceptance_reasons.filter((item) => typeof item === "string") : [];
|
|
5176
|
+
return { input: truncate(input, 92), output: truncate(output, 120), why: explanation.slice(0, 2).map((item) => truncate(item, 112)) };
|
|
5177
|
+
} catch {
|
|
5178
|
+
return null;
|
|
5179
|
+
}
|
|
5180
|
+
}
|
|
5088
5181
|
function depthMultiplier(depth) {
|
|
5089
5182
|
if (depth === "deep") return 1.6;
|
|
5090
5183
|
if (depth === "shallow") return 0.75;
|
|
5091
5184
|
return 1;
|
|
5092
5185
|
}
|
|
5093
5186
|
function printUsage(profile) {
|
|
5094
|
-
const name = profile.user.name ||
|
|
5095
|
-
|
|
5187
|
+
const name = profile.user.name || "Alys user";
|
|
5188
|
+
const email = profile.user.email;
|
|
5189
|
+
const account = email && email !== name ? `${name} <${email}>` : name;
|
|
5190
|
+
console.log(paint(`Account: ${account}`, "white"));
|
|
5096
5191
|
console.log(
|
|
5097
5192
|
profile.usage.isUnlimited ? paint("Generations: unlimited", "green") : paint(`Generations: ${profile.usage.used}/${profile.usage.limit} used, ${profile.usage.remaining} remaining`, "yellow")
|
|
5098
5193
|
);
|
|
@@ -5102,9 +5197,13 @@ function printRunPlan(args) {
|
|
|
5102
5197
|
const effectiveSources = Math.max(1, Math.floor(args.sourceLimit * multiplier));
|
|
5103
5198
|
const effectiveRows = Math.max(1, Math.floor(args.targetRows * multiplier));
|
|
5104
5199
|
const totalRows = effectiveRows * args.datasetCount;
|
|
5105
|
-
|
|
5200
|
+
const name = args.profile.user.name || "Alys user";
|
|
5201
|
+
const email = args.profile.user.email;
|
|
5202
|
+
const account = email && email !== name ? `${name} <${email}>` : name;
|
|
5203
|
+
console.log(paint("\n\u250C\u2500 Alys run plan \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510", "gray"));
|
|
5106
5204
|
console.log(`${paint("\u2502", "gray")} Topic ${paint(args.topic.slice(0, 58), "white")}`);
|
|
5107
|
-
console.log(`${paint("\u2502", "gray")}
|
|
5205
|
+
console.log(`${paint("\u2502", "gray")} Account ${paint(account.slice(0, 58), "white")}`);
|
|
5206
|
+
console.log(`${paint("\u2502", "gray")} Type ${paint(args.datasetType, "cyan")} Depth ${paint(args.depth, "cyan")} Mode ${paint("Alys runtime", "yellow")}`);
|
|
5108
5207
|
console.log(`${paint("\u2502", "gray")} Datasets ${formatInt(args.datasetCount)} / ${MAX_DATASETS_PER_RUN} max Rows/dataset ${formatInt(effectiveRows)}`);
|
|
5109
5208
|
console.log(`${paint("\u2502", "gray")} Total rows ${paint(formatInt(totalRows), "green")} Formats ${args.exportFormats.join(", ")}`);
|
|
5110
5209
|
console.log(`${paint("\u2502", "gray")} Credits ${args.profile.usage.isUnlimited ? "Unlimited" : `${args.profile.usage.remaining ?? 0} remaining before run`}`);
|
|
@@ -5121,7 +5220,7 @@ async function confirmRun(args) {
|
|
|
5121
5220
|
const response = await (0, import_prompts.default)({
|
|
5122
5221
|
type: "toggle",
|
|
5123
5222
|
name: "continueRun",
|
|
5124
|
-
message: "
|
|
5223
|
+
message: "Start this Alys run?",
|
|
5125
5224
|
initial: true,
|
|
5126
5225
|
active: "Yes",
|
|
5127
5226
|
inactive: "No"
|
|
@@ -5144,6 +5243,108 @@ async function writeGeneratedDatasets(workspaceRoot, datasets) {
|
|
|
5144
5243
|
);
|
|
5145
5244
|
}
|
|
5146
5245
|
}
|
|
5246
|
+
function printGenerationSummary(response, workspaceRoot) {
|
|
5247
|
+
const root = resolveHome(workspaceRoot);
|
|
5248
|
+
const totals = response.datasets.reduce(
|
|
5249
|
+
(acc, dataset) => {
|
|
5250
|
+
const metrics = getMetrics(dataset);
|
|
5251
|
+
const summary = getSummary(dataset);
|
|
5252
|
+
acc.records += Number(metrics.recordsGenerated ?? summary.recordsAccepted ?? 0);
|
|
5253
|
+
acc.sources += Number(metrics.sourcesDiscovered ?? 0);
|
|
5254
|
+
acc.documents += Number(metrics.documentsExtracted ?? 0);
|
|
5255
|
+
acc.findings += Number(metrics.findingsVerified ?? 0);
|
|
5256
|
+
acc.duplicates += Number(metrics.duplicatesRemoved ?? summary.duplicatesRemoved ?? 0);
|
|
5257
|
+
const quality = getQualityMetrics(dataset);
|
|
5258
|
+
acc.contradictions += Number(quality.contradictionResolutionCount ?? 0);
|
|
5259
|
+
acc.lowTrustFiltered += Number(quality.lowTrustSourceFilterRate ?? 0);
|
|
5260
|
+
acc.citationCoverage.push(Number(quality.citationCoverage ?? 0));
|
|
5261
|
+
acc.uniqueness.push(Number(quality.recordUniqueness ?? 0));
|
|
5262
|
+
acc.relevance.push(Number(quality.relevanceScore ?? 0));
|
|
5263
|
+
const suitability = getEvaluation(dataset).suitability ?? getEvaluation(dataset).summary?.scores ?? {};
|
|
5264
|
+
acc.ragSuitability.push(Number(suitability.ragSuitability ?? 0));
|
|
5265
|
+
acc.instructionTuning.push(Number(suitability.instructionTuning ?? 0));
|
|
5266
|
+
acc.factualGrounding.push(Number(suitability.factualGrounding ?? 0));
|
|
5267
|
+
acc.humanUsefulness.push(Number(suitability.humanUsefulness ?? 0));
|
|
5268
|
+
const confidence2 = Number(metrics.averageConfidence ?? summary.averageConfidence ?? 0);
|
|
5269
|
+
if (confidence2 > 0) acc.confidences.push(confidence2);
|
|
5270
|
+
return acc;
|
|
5271
|
+
},
|
|
5272
|
+
{
|
|
5273
|
+
records: 0,
|
|
5274
|
+
sources: 0,
|
|
5275
|
+
documents: 0,
|
|
5276
|
+
findings: 0,
|
|
5277
|
+
duplicates: 0,
|
|
5278
|
+
contradictions: 0,
|
|
5279
|
+
lowTrustFiltered: 0,
|
|
5280
|
+
confidences: [],
|
|
5281
|
+
citationCoverage: [],
|
|
5282
|
+
uniqueness: [],
|
|
5283
|
+
relevance: [],
|
|
5284
|
+
ragSuitability: [],
|
|
5285
|
+
instructionTuning: [],
|
|
5286
|
+
factualGrounding: [],
|
|
5287
|
+
humanUsefulness: []
|
|
5288
|
+
}
|
|
5289
|
+
);
|
|
5290
|
+
const confidence = totals.confidences.length ? totals.confidences.reduce((sum, value) => sum + value, 0) / totals.confidences.length : 0;
|
|
5291
|
+
const citationCoverage = average(totals.citationCoverage);
|
|
5292
|
+
const uniqueness = average(totals.uniqueness);
|
|
5293
|
+
const relevance = average(totals.relevance);
|
|
5294
|
+
const ragSuitability = average(totals.ragSuitability);
|
|
5295
|
+
const instructionTuning = average(totals.instructionTuning);
|
|
5296
|
+
const factualGrounding = average(totals.factualGrounding);
|
|
5297
|
+
const humanUsefulness = average(totals.humanUsefulness);
|
|
5298
|
+
console.log("");
|
|
5299
|
+
console.log(paint("Alys run complete", "green"));
|
|
5300
|
+
printStage("SRC", "DONE", "Authoritative sources ranked", formatInt(totals.sources));
|
|
5301
|
+
printStage("SRC", "DONE", "Low-trust source filter applied", `${Math.round(totals.lowTrustFiltered / Math.max(1, response.datasets.length) * 100)}% avg filtered`);
|
|
5302
|
+
printStage("EXT", "DONE", "Source documents normalized", formatInt(totals.documents));
|
|
5303
|
+
printStage("CHK", "DONE", "Findings verified", formatInt(totals.findings));
|
|
5304
|
+
printStage("CHK", "DONE", "Contradictory claims resolved", formatInt(totals.contradictions));
|
|
5305
|
+
printStage("DED", "DONE", "Duplicate candidates removed", formatInt(totals.duplicates));
|
|
5306
|
+
printStage("GEN", "DONE", "Canonical records accepted", formatInt(totals.records));
|
|
5307
|
+
printStage("EVAL", "DONE", "Average confidence", formatPercent(confidence));
|
|
5308
|
+
printStage("EVAL", "DONE", "Citation coverage", formatPercent(citationCoverage));
|
|
5309
|
+
printStage("EVAL", "DONE", "Record uniqueness", formatPercent(uniqueness));
|
|
5310
|
+
printStage("EVAL", "DONE", "Topic relevance", formatPercent(relevance));
|
|
5311
|
+
printStage("EVAL", "DONE", "RAG suitability", formatScore(ragSuitability));
|
|
5312
|
+
printStage("EVAL", "DONE", "Instruction tuning suitability", formatScore(instructionTuning));
|
|
5313
|
+
printStage("EVAL", "DONE", "Factual grounding", formatScore(factualGrounding));
|
|
5314
|
+
printStage("EVAL", "DONE", "Human usefulness proxy", formatScore(humanUsefulness));
|
|
5315
|
+
printStage("OUT", "DONE", "Exports written", root);
|
|
5316
|
+
console.log("");
|
|
5317
|
+
console.log(paint("Datasets", "white"));
|
|
5318
|
+
for (const dataset of response.datasets) {
|
|
5319
|
+
const metrics = getMetrics(dataset);
|
|
5320
|
+
const summary = getSummary(dataset);
|
|
5321
|
+
const quality = getQualityMetrics(dataset);
|
|
5322
|
+
const suitability = getEvaluation(dataset).suitability ?? getEvaluation(dataset).summary?.scores ?? {};
|
|
5323
|
+
const records = Number(metrics.recordsGenerated ?? summary.recordsAccepted ?? 0);
|
|
5324
|
+
const sources = Number(metrics.sourcesDiscovered ?? 0);
|
|
5325
|
+
const confidenceValue = Number(metrics.averageConfidence ?? summary.averageConfidence ?? 0);
|
|
5326
|
+
const outputDir = import_node_path.default.join(root, "datasets", dataset.id);
|
|
5327
|
+
console.log(`${paint("\u2022", "yellow")} ${paint(dataset.id, "white")} ${formatInt(records)} records ${formatInt(sources)} sources ${formatPercent(confidenceValue)} confidence`);
|
|
5328
|
+
console.log(` ${truncate(dataset.topic, 110)}`);
|
|
5329
|
+
console.log(` ${paint(outputDir, "cyan")}`);
|
|
5330
|
+
console.log(` quality ${formatPercent(Number(quality.citationCoverage ?? 0))} citations \xB7 ${formatPercent(Number(quality.recordUniqueness ?? 0))} unique \xB7 ${formatPercent(Number(quality.sourceDiversity ?? 0))} source diversity`);
|
|
5331
|
+
console.log(` suitability RAG ${formatScore(Number(suitability.ragSuitability ?? 0))} \xB7 tuning ${formatScore(Number(suitability.instructionTuning ?? 0))} \xB7 usefulness ${formatScore(Number(suitability.humanUsefulness ?? 0))}`);
|
|
5332
|
+
const preview = previewRecord(dataset);
|
|
5333
|
+
if (preview) {
|
|
5334
|
+
console.log(paint(" preview", "gray"));
|
|
5335
|
+
if (preview.input) console.log(` in ${paint(preview.input, "gray")}`);
|
|
5336
|
+
if (preview.output) console.log(` out ${preview.output}`);
|
|
5337
|
+
for (const reason of preview.why) {
|
|
5338
|
+
console.log(` why ${paint(reason, "gray")}`);
|
|
5339
|
+
}
|
|
5340
|
+
}
|
|
5341
|
+
}
|
|
5342
|
+
console.log("");
|
|
5343
|
+
console.log(
|
|
5344
|
+
response.usage.isUnlimited ? paint("Generations remaining: unlimited", "green") : paint(`Generations remaining: ${response.usage.remaining ?? 0}`, "yellow")
|
|
5345
|
+
);
|
|
5346
|
+
console.log(paint(`Dashboard: ${appUrl()}/dashboard`, "cyan"));
|
|
5347
|
+
}
|
|
5147
5348
|
async function handleStatus() {
|
|
5148
5349
|
printBanner();
|
|
5149
5350
|
const { profile } = await ensureAuthenticated();
|
|
@@ -5171,6 +5372,9 @@ async function handleLogout() {
|
|
|
5171
5372
|
}
|
|
5172
5373
|
async function handleGenerate(args, command) {
|
|
5173
5374
|
const { config, profile } = await ensureAuthenticated();
|
|
5375
|
+
printBanner();
|
|
5376
|
+
printUsage(profile);
|
|
5377
|
+
console.log("");
|
|
5174
5378
|
const { values, positionals } = (0, import_node_util.parseArgs)({
|
|
5175
5379
|
args: command === "generate" ? args.slice(1) : args,
|
|
5176
5380
|
allowPositionals: true,
|
|
@@ -5187,13 +5391,13 @@ async function handleGenerate(args, command) {
|
|
|
5187
5391
|
yes: { type: "boolean" }
|
|
5188
5392
|
}
|
|
5189
5393
|
});
|
|
5190
|
-
const topicFromArgs = positionals.join(" ")
|
|
5191
|
-
const topic = topicFromArgs ? topicFromArgs : (await (0, import_prompts.default)({
|
|
5394
|
+
const topicFromArgs = normalizeTopicInput(positionals.join(" "));
|
|
5395
|
+
const topic = topicFromArgs ? topicFromArgs : normalizeTopicInput((await (0, import_prompts.default)({
|
|
5192
5396
|
type: "text",
|
|
5193
5397
|
name: "topic",
|
|
5194
5398
|
message: "What do you want to generate?",
|
|
5195
5399
|
validate: (v) => v.trim().length ? true : "Please enter a topic."
|
|
5196
|
-
})).topic;
|
|
5400
|
+
})).topic);
|
|
5197
5401
|
if (!topic) throw new Error("Missing topic.");
|
|
5198
5402
|
const datasetType = parseDatasetType(values.type) ?? (await (0, import_prompts.default)({
|
|
5199
5403
|
type: "select",
|
|
@@ -5265,13 +5469,11 @@ async function handleGenerate(args, command) {
|
|
|
5265
5469
|
const verificationEnabled = values.verify === true ? true : values["no-verify"] === true ? false : (await (0, import_prompts.default)({
|
|
5266
5470
|
type: "toggle",
|
|
5267
5471
|
name: "verificationEnabled",
|
|
5268
|
-
message: "Enable verification
|
|
5472
|
+
message: "Enable verification checks?",
|
|
5269
5473
|
initial: true,
|
|
5270
5474
|
active: "Yes",
|
|
5271
5475
|
inactive: "No"
|
|
5272
5476
|
})).verificationEnabled;
|
|
5273
|
-
printBanner();
|
|
5274
|
-
printUsage(profile);
|
|
5275
5477
|
printRunPlan({
|
|
5276
5478
|
topic,
|
|
5277
5479
|
datasetType,
|
|
@@ -5292,39 +5494,32 @@ async function handleGenerate(args, command) {
|
|
|
5292
5494
|
console.log(paint("Run cancelled. No generations spent.", "green"));
|
|
5293
5495
|
return;
|
|
5294
5496
|
}
|
|
5295
|
-
console.log(
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
for (const dataset of response.datasets) {
|
|
5319
|
-
const records = Number(dataset.manifest?.metrics && typeof dataset.manifest.metrics === "object" ? dataset.manifest.metrics.recordsGenerated ?? 0 : 0);
|
|
5320
|
-
console.log(`${paint("\u2022", "yellow")} ${dataset.id} records: ${formatInt(records)}`);
|
|
5321
|
-
console.log(` ${import_node_path.default.join(resolveHome(workspaceRoot), "datasets", dataset.id)}`);
|
|
5322
|
-
}
|
|
5323
|
-
console.log("");
|
|
5324
|
-
console.log(
|
|
5325
|
-
response.usage.isUnlimited ? paint("Generations remaining: unlimited", "green") : paint(`Generations remaining: ${response.usage.remaining ?? 0}`, "yellow")
|
|
5497
|
+
console.log(paint("Runtime", "white"));
|
|
5498
|
+
printStage("AUTH", "OK", "Usage linked", appUrl());
|
|
5499
|
+
printStage("PLAN", "OK", "Generations reserved only after successful completion", `${datasetCount} requested`);
|
|
5500
|
+
printStage("SRC", "RUN", "Research pipeline starting", `${sourceLimit} source target`);
|
|
5501
|
+
const response = await withSpinner(
|
|
5502
|
+
"Alys research runtime executing",
|
|
5503
|
+
requestJson(
|
|
5504
|
+
"/api/cli/generate",
|
|
5505
|
+
{
|
|
5506
|
+
method: "POST",
|
|
5507
|
+
body: JSON.stringify({
|
|
5508
|
+
topic,
|
|
5509
|
+
datasetType,
|
|
5510
|
+
datasetCount,
|
|
5511
|
+
formats: exportFormats,
|
|
5512
|
+
sourceLimit,
|
|
5513
|
+
targetRows,
|
|
5514
|
+
depth,
|
|
5515
|
+
verificationEnabled
|
|
5516
|
+
})
|
|
5517
|
+
},
|
|
5518
|
+
config.token
|
|
5519
|
+
)
|
|
5326
5520
|
);
|
|
5327
|
-
|
|
5521
|
+
await withSpinner("Writing local exports", writeGeneratedDatasets(workspaceRoot, response.datasets));
|
|
5522
|
+
printGenerationSummary(response, workspaceRoot);
|
|
5328
5523
|
}
|
|
5329
5524
|
function printFailure(error) {
|
|
5330
5525
|
const message = error instanceof Error ? error.message : "Alys failed.";
|