@tuned-tensor/cli 0.7.0 → 0.8.1
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/index.js +310 -98
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { spawn as spawn4 } from "child_process";
|
|
5
5
|
import { constants as osConstants2 } from "os";
|
|
6
6
|
import { Command } from "commander";
|
|
7
|
-
import
|
|
7
|
+
import chalk9 from "chalk";
|
|
8
8
|
|
|
9
9
|
// src/client.ts
|
|
10
10
|
import { readFileSync as readFileSync2, statSync } from "fs";
|
|
@@ -345,7 +345,7 @@ function createAgentClient(opts) {
|
|
|
345
345
|
}
|
|
346
346
|
|
|
347
347
|
// src/agent.ts
|
|
348
|
-
import
|
|
348
|
+
import chalk3 from "chalk";
|
|
349
349
|
|
|
350
350
|
// src/shell.ts
|
|
351
351
|
import chalk from "chalk";
|
|
@@ -353,6 +353,7 @@ import { stat as stat2 } from "fs/promises";
|
|
|
353
353
|
import { homedir as homedir3 } from "os";
|
|
354
354
|
import { isAbsolute as isAbsolute2, resolve as resolve2 } from "path";
|
|
355
355
|
import { createInterface } from "readline";
|
|
356
|
+
import { stripVTControlCharacters } from "util";
|
|
356
357
|
|
|
357
358
|
// src/command-catalog.ts
|
|
358
359
|
var CLOUD = ["cloud"];
|
|
@@ -948,6 +949,34 @@ function errorMessage(error) {
|
|
|
948
949
|
var successMark = () => chalk.green("\u2713");
|
|
949
950
|
var errorMark = () => chalk.red("\u2717");
|
|
950
951
|
var accent = chalk.hex("#8B5CF6");
|
|
952
|
+
var ANSI_BOLD = "\x1B[1m";
|
|
953
|
+
var ANSI_BOLD_OFF = "\x1B[22m";
|
|
954
|
+
var ANSI_CLEAR_LINE = "\x1B[2K";
|
|
955
|
+
var ANSI_CLEAR_TO_END = "\x1B[K";
|
|
956
|
+
var ANSI_CURSOR_UP = "\x1B[1A";
|
|
957
|
+
var ANSI_RESET = "\x1B[0m";
|
|
958
|
+
function inputColorCodes() {
|
|
959
|
+
if (chalk.level === 0) return null;
|
|
960
|
+
if (chalk.level === 1) {
|
|
961
|
+
return {
|
|
962
|
+
background: "\x1B[100m",
|
|
963
|
+
accent: "\x1B[95m",
|
|
964
|
+
text: "\x1B[97m"
|
|
965
|
+
};
|
|
966
|
+
}
|
|
967
|
+
if (chalk.level === 2) {
|
|
968
|
+
return {
|
|
969
|
+
background: "\x1B[48;5;238m",
|
|
970
|
+
accent: "\x1B[38;5;183m",
|
|
971
|
+
text: "\x1B[38;5;255m"
|
|
972
|
+
};
|
|
973
|
+
}
|
|
974
|
+
return {
|
|
975
|
+
background: "\x1B[48;2;50;52;67m",
|
|
976
|
+
accent: "\x1B[38;2;196;181;253m",
|
|
977
|
+
text: "\x1B[38;2;245;243;255m"
|
|
978
|
+
};
|
|
979
|
+
}
|
|
951
980
|
var DETAIL_LABEL_WIDTH = 15;
|
|
952
981
|
function styleDetailLines(lines) {
|
|
953
982
|
return lines.map((line) => {
|
|
@@ -1012,30 +1041,49 @@ function helpText(mode, query, palette = false) {
|
|
|
1012
1041
|
function activeModelLabel(snapshot) {
|
|
1013
1042
|
return snapshot.mode === "local" ? snapshot.context.local.activeModelId ?? "base" : snapshot.context.spec?.baseModel ?? "\u2014";
|
|
1014
1043
|
}
|
|
1015
|
-
function logoRows() {
|
|
1016
|
-
const muted = chalk.dim("\u2588\u2588");
|
|
1017
|
-
return [
|
|
1018
|
-
`${chalk.hex("#A78BFA")("\u2588\u2588")} ${muted} ${muted}`,
|
|
1019
|
-
`${muted} ${accent("\u2588\u2588")} ${muted}`,
|
|
1020
|
-
`${muted} ${muted} ${chalk.hex("#7C3AED")("\u2588\u2588")}`
|
|
1021
|
-
];
|
|
1022
|
-
}
|
|
1023
1044
|
function renderShellBanner(snapshot) {
|
|
1024
1045
|
const spec = snapshot.context.spec?.name ?? snapshot.context.spec?.path ?? "no spec";
|
|
1025
|
-
const heading = snapshot.version ? `${accent.bold("
|
|
1026
|
-
const
|
|
1046
|
+
const heading = snapshot.version ? `${accent.bold("tt")} ${chalk.dim(`v${snapshot.version}`)}` : accent.bold("tt");
|
|
1047
|
+
const lines = [
|
|
1027
1048
|
heading,
|
|
1028
|
-
|
|
1029
|
-
|
|
1049
|
+
chalk.dim(
|
|
1050
|
+
`${snapshot.mode} \xB7 ${snapshot.context.projectName} \xB7 ${spec} \xB7 model ${activeModelLabel(snapshot)}`
|
|
1051
|
+
),
|
|
1052
|
+
chalk.dim("ctrl+c stop/clear \xB7 ctrl+d exit \xB7 /help commands \xB7 tab complete"),
|
|
1053
|
+
"",
|
|
1054
|
+
chalk.dim("Ask TT anything. Known commands run directly.")
|
|
1030
1055
|
];
|
|
1031
|
-
const logo = logoRows();
|
|
1032
|
-
const lines = textRows.map((row, index) => `${logo[index]} ${row}`);
|
|
1033
1056
|
return `${lines.join("\n")}
|
|
1034
1057
|
|
|
1035
1058
|
`;
|
|
1036
1059
|
}
|
|
1037
|
-
function renderShellPrompt(
|
|
1038
|
-
return `${accent("
|
|
1060
|
+
function renderShellPrompt() {
|
|
1061
|
+
return `${accent.bold("\u203A")} `;
|
|
1062
|
+
}
|
|
1063
|
+
function renderSubmittedShellInput(input, columns) {
|
|
1064
|
+
const colors = inputColorCodes();
|
|
1065
|
+
if (!colors) return "";
|
|
1066
|
+
const safeInput = stripVTControlCharacters(input).replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f-\u009f]/g, "");
|
|
1067
|
+
if (columns && Array.from(`\u203A ${safeInput}`).length >= columns) return "";
|
|
1068
|
+
return [
|
|
1069
|
+
ANSI_CURSOR_UP,
|
|
1070
|
+
"\r",
|
|
1071
|
+
ANSI_CLEAR_LINE,
|
|
1072
|
+
colors.background,
|
|
1073
|
+
colors.accent,
|
|
1074
|
+
ANSI_BOLD,
|
|
1075
|
+
"\u203A",
|
|
1076
|
+
ANSI_BOLD_OFF,
|
|
1077
|
+
colors.text,
|
|
1078
|
+
" ",
|
|
1079
|
+
safeInput,
|
|
1080
|
+
ANSI_CLEAR_TO_END,
|
|
1081
|
+
ANSI_RESET,
|
|
1082
|
+
"\r\n"
|
|
1083
|
+
].join("");
|
|
1084
|
+
}
|
|
1085
|
+
function resetShellPromptStyle() {
|
|
1086
|
+
return "";
|
|
1039
1087
|
}
|
|
1040
1088
|
var TunedTensorShellSession = class _TunedTensorShellSession {
|
|
1041
1089
|
constructor(runner, io, agent, env, contextProvider, version, initialContext) {
|
|
@@ -1082,7 +1130,7 @@ var TunedTensorShellSession = class _TunedTensorShellSession {
|
|
|
1082
1130
|
};
|
|
1083
1131
|
}
|
|
1084
1132
|
prompt() {
|
|
1085
|
-
return renderShellPrompt(
|
|
1133
|
+
return renderShellPrompt();
|
|
1086
1134
|
}
|
|
1087
1135
|
banner() {
|
|
1088
1136
|
return renderShellBanner(this.snapshot());
|
|
@@ -1312,10 +1360,12 @@ async function startInteractiveShell(options) {
|
|
|
1312
1360
|
});
|
|
1313
1361
|
readline.on("SIGINT", () => {
|
|
1314
1362
|
if (session.interruptAgent()) {
|
|
1315
|
-
output.write(
|
|
1363
|
+
output.write(`${resetShellPromptStyle()}
|
|
1364
|
+
`);
|
|
1316
1365
|
return;
|
|
1317
1366
|
}
|
|
1318
|
-
output.write(
|
|
1367
|
+
output.write(`${resetShellPromptStyle()}
|
|
1368
|
+
`);
|
|
1319
1369
|
readline?.setPrompt(session.prompt());
|
|
1320
1370
|
readline?.write(null, { ctrl: true, name: "u" });
|
|
1321
1371
|
});
|
|
@@ -1324,15 +1374,21 @@ async function startInteractiveShell(options) {
|
|
|
1324
1374
|
readline.prompt();
|
|
1325
1375
|
try {
|
|
1326
1376
|
for await (const line of readline) {
|
|
1377
|
+
output.write(renderSubmittedShellInput(
|
|
1378
|
+
line,
|
|
1379
|
+
output.columns
|
|
1380
|
+
));
|
|
1327
1381
|
const action = await session.handleLine(line);
|
|
1328
1382
|
if (action === "exit") {
|
|
1329
1383
|
readline.close();
|
|
1330
1384
|
break;
|
|
1331
1385
|
}
|
|
1386
|
+
output.write("\n");
|
|
1332
1387
|
readline.setPrompt(session.prompt());
|
|
1333
1388
|
readline.prompt();
|
|
1334
1389
|
}
|
|
1335
1390
|
} finally {
|
|
1391
|
+
output.write(resetShellPromptStyle());
|
|
1336
1392
|
readline.close();
|
|
1337
1393
|
}
|
|
1338
1394
|
}
|
|
@@ -1345,10 +1401,127 @@ function shouldStartInteractiveShell(options) {
|
|
|
1345
1401
|
return options.args.length === 0 && options.stdinIsTTY === true && options.stdoutIsTTY === true && !ciEnabled(env.CI) && env.TERM !== "dumb";
|
|
1346
1402
|
}
|
|
1347
1403
|
|
|
1348
|
-
// src/
|
|
1404
|
+
// src/terminal-markdown.ts
|
|
1405
|
+
import chalk2 from "chalk";
|
|
1406
|
+
import { stripVTControlCharacters as stripVTControlCharacters2 } from "util";
|
|
1349
1407
|
var accent2 = chalk2.hex("#8B5CF6");
|
|
1350
|
-
|
|
1351
|
-
|
|
1408
|
+
function sanitizeTerminalText(text2) {
|
|
1409
|
+
return stripVTControlCharacters2(text2).replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f-\u009f]/g, "");
|
|
1410
|
+
}
|
|
1411
|
+
function closingDelimiter(text2, delimiter, from) {
|
|
1412
|
+
return text2.indexOf(delimiter, from + delimiter.length);
|
|
1413
|
+
}
|
|
1414
|
+
function renderInlineMarkdown(text2) {
|
|
1415
|
+
let rendered = "";
|
|
1416
|
+
let index = 0;
|
|
1417
|
+
while (index < text2.length) {
|
|
1418
|
+
if (text2[index] === "\\" && index + 1 < text2.length) {
|
|
1419
|
+
rendered += text2[index + 1];
|
|
1420
|
+
index += 2;
|
|
1421
|
+
continue;
|
|
1422
|
+
}
|
|
1423
|
+
if (text2[index] === "[") {
|
|
1424
|
+
const link = text2.slice(index).match(/^\[([^\]]+)]\(([^)]+)\)/);
|
|
1425
|
+
if (link) {
|
|
1426
|
+
rendered += `${chalk2.underline(renderInlineMarkdown(link[1]))}${chalk2.dim(` (${link[2]})`)}`;
|
|
1427
|
+
index += link[0].length;
|
|
1428
|
+
continue;
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
const strong = text2.startsWith("**", index) ? "**" : text2.startsWith("__", index) ? "__" : null;
|
|
1432
|
+
if (strong) {
|
|
1433
|
+
const close = closingDelimiter(text2, strong, index);
|
|
1434
|
+
if (close > index + strong.length) {
|
|
1435
|
+
rendered += chalk2.bold(
|
|
1436
|
+
renderInlineMarkdown(text2.slice(index + strong.length, close))
|
|
1437
|
+
);
|
|
1438
|
+
index = close + strong.length;
|
|
1439
|
+
continue;
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
if (text2[index] === "`") {
|
|
1443
|
+
const close = closingDelimiter(text2, "`", index);
|
|
1444
|
+
if (close > index + 1) {
|
|
1445
|
+
rendered += chalk2.cyan(text2.slice(index + 1, close));
|
|
1446
|
+
index = close + 1;
|
|
1447
|
+
continue;
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
const emphasis = text2[index] === "*" || text2[index] === "_" ? text2[index] : null;
|
|
1451
|
+
if (emphasis) {
|
|
1452
|
+
const close = closingDelimiter(text2, emphasis, index);
|
|
1453
|
+
if (close > index + 1) {
|
|
1454
|
+
rendered += chalk2.italic(
|
|
1455
|
+
renderInlineMarkdown(text2.slice(index + 1, close))
|
|
1456
|
+
);
|
|
1457
|
+
index = close + 1;
|
|
1458
|
+
continue;
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
rendered += text2[index];
|
|
1462
|
+
index += 1;
|
|
1463
|
+
}
|
|
1464
|
+
return rendered;
|
|
1465
|
+
}
|
|
1466
|
+
function renderMarkdownLine(line, inCodeBlock) {
|
|
1467
|
+
if (inCodeBlock) return chalk2.cyan(` ${line}`);
|
|
1468
|
+
const heading = line.match(/^\s{0,3}#{1,6}\s+(.+)$/);
|
|
1469
|
+
if (heading) return chalk2.bold(renderInlineMarkdown(heading[1]));
|
|
1470
|
+
const bullet = line.match(/^(\s*)[-+*]\s+(.+)$/);
|
|
1471
|
+
if (bullet) {
|
|
1472
|
+
return `${bullet[1]}${accent2("\u2022")} ${renderInlineMarkdown(bullet[2])}`;
|
|
1473
|
+
}
|
|
1474
|
+
const numbered = line.match(/^(\s*)(\d+)[.)]\s+(.+)$/);
|
|
1475
|
+
if (numbered) {
|
|
1476
|
+
return `${numbered[1]}${accent2(`${numbered[2]}.`)} ${renderInlineMarkdown(numbered[3])}`;
|
|
1477
|
+
}
|
|
1478
|
+
const quote = line.match(/^\s*>\s?(.*)$/);
|
|
1479
|
+
if (quote) return `${chalk2.dim("\u2502")} ${chalk2.italic(renderInlineMarkdown(quote[1]))}`;
|
|
1480
|
+
if (/^\s{0,3}([-*_])(?:\s*\1){2,}\s*$/.test(line)) {
|
|
1481
|
+
return chalk2.dim("\u2500".repeat(32));
|
|
1482
|
+
}
|
|
1483
|
+
return renderInlineMarkdown(line);
|
|
1484
|
+
}
|
|
1485
|
+
var StreamingTerminalMarkdown = class {
|
|
1486
|
+
pending = "";
|
|
1487
|
+
inCodeBlock = false;
|
|
1488
|
+
push(delta) {
|
|
1489
|
+
this.pending += delta;
|
|
1490
|
+
let rendered = "";
|
|
1491
|
+
let newline = this.pending.indexOf("\n");
|
|
1492
|
+
while (newline !== -1) {
|
|
1493
|
+
const line = this.pending.slice(0, newline).replace(/\r$/, "");
|
|
1494
|
+
this.pending = this.pending.slice(newline + 1);
|
|
1495
|
+
rendered += `${this.renderLine(line)}
|
|
1496
|
+
`;
|
|
1497
|
+
newline = this.pending.indexOf("\n");
|
|
1498
|
+
}
|
|
1499
|
+
return rendered;
|
|
1500
|
+
}
|
|
1501
|
+
flush() {
|
|
1502
|
+
if (!this.pending) return "";
|
|
1503
|
+
const line = this.pending.replace(/\r$/, "");
|
|
1504
|
+
this.pending = "";
|
|
1505
|
+
return this.renderLine(line);
|
|
1506
|
+
}
|
|
1507
|
+
reset() {
|
|
1508
|
+
this.pending = "";
|
|
1509
|
+
this.inCodeBlock = false;
|
|
1510
|
+
}
|
|
1511
|
+
renderLine(line) {
|
|
1512
|
+
const safeLine = sanitizeTerminalText(line);
|
|
1513
|
+
if (/^\s*```/.test(safeLine)) {
|
|
1514
|
+
this.inCodeBlock = !this.inCodeBlock;
|
|
1515
|
+
return "";
|
|
1516
|
+
}
|
|
1517
|
+
return renderMarkdownLine(safeLine, this.inCodeBlock);
|
|
1518
|
+
}
|
|
1519
|
+
};
|
|
1520
|
+
|
|
1521
|
+
// src/agent.ts
|
|
1522
|
+
var accent3 = chalk3.hex("#8B5CF6");
|
|
1523
|
+
var successMark2 = () => chalk3.green("\u2713");
|
|
1524
|
+
var errorMark2 = () => chalk3.red("\u2717");
|
|
1352
1525
|
function isRecord(value) {
|
|
1353
1526
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1354
1527
|
}
|
|
@@ -1357,25 +1530,25 @@ function stringValue2(value) {
|
|
|
1357
1530
|
}
|
|
1358
1531
|
function helpText2() {
|
|
1359
1532
|
return [
|
|
1360
|
-
|
|
1533
|
+
accent3.bold("Agent commands"),
|
|
1361
1534
|
"",
|
|
1362
|
-
` ${
|
|
1363
|
-
` ${
|
|
1364
|
-
` ${
|
|
1365
|
-
` ${
|
|
1366
|
-
` ${
|
|
1367
|
-
` ${
|
|
1368
|
-
` ${
|
|
1369
|
-
` ${
|
|
1535
|
+
` ${accent3("/new".padEnd(22))} Start a new conversation.`,
|
|
1536
|
+
` ${accent3("/threads".padEnd(22))} List recent conversations.`,
|
|
1537
|
+
` ${accent3("/resume <id>".padEnd(22))} Resume a conversation by ID or prefix.`,
|
|
1538
|
+
` ${accent3("/approve [id]".padEnd(22))} Approve a proposed action.`,
|
|
1539
|
+
` ${accent3("/reject [id]".padEnd(22))} Reject a proposed action.`,
|
|
1540
|
+
` ${accent3("/status".padEnd(22))} Show the active conversation.`,
|
|
1541
|
+
` ${accent3("/clear".padEnd(22))} Clear the terminal.`,
|
|
1542
|
+
` ${accent3("/exit".padEnd(22))} Exit the agent.`,
|
|
1370
1543
|
"",
|
|
1371
|
-
|
|
1544
|
+
chalk3.dim(
|
|
1372
1545
|
"Everything else is sent to the Tuned Tensor agent; known TT commands still run directly in the shell."
|
|
1373
1546
|
),
|
|
1374
1547
|
""
|
|
1375
1548
|
].join("\n");
|
|
1376
1549
|
}
|
|
1377
1550
|
function formatThread(thread, activeId) {
|
|
1378
|
-
const active = thread.id === activeId ?
|
|
1551
|
+
const active = thread.id === activeId ? accent3("\u25CF") : chalk3.dim("\u25CB");
|
|
1379
1552
|
const time = thread.last_message_at ?? thread.updated_at ?? thread.created_at;
|
|
1380
1553
|
const date = new Date(time);
|
|
1381
1554
|
const dateLabel = Number.isNaN(date.getTime()) ? "" : date.toLocaleString([], {
|
|
@@ -1384,7 +1557,7 @@ function formatThread(thread, activeId) {
|
|
|
1384
1557
|
hour: "2-digit",
|
|
1385
1558
|
minute: "2-digit"
|
|
1386
1559
|
});
|
|
1387
|
-
return `${active} ${
|
|
1560
|
+
return `${active} ${chalk3.dim(thread.id.slice(0, 8))} ${thread.title} ${chalk3.dim(dateLabel)}`;
|
|
1388
1561
|
}
|
|
1389
1562
|
function actionFromPayload(payload) {
|
|
1390
1563
|
const value = isRecord(payload.action) ? payload.action : isRecord(payload.approval) ? payload.approval : payload;
|
|
@@ -1422,7 +1595,9 @@ var TunedTensorAgentSession = class {
|
|
|
1422
1595
|
pendingActions = /* @__PURE__ */ new Map();
|
|
1423
1596
|
activeRequest = null;
|
|
1424
1597
|
responseStarted = false;
|
|
1598
|
+
reasoningActive = false;
|
|
1425
1599
|
lineOpen = false;
|
|
1600
|
+
responseMarkdown = new StreamingTerminalMarkdown();
|
|
1426
1601
|
get busy() {
|
|
1427
1602
|
return this.activeRequest !== null;
|
|
1428
1603
|
}
|
|
@@ -1440,15 +1615,29 @@ var TunedTensorAgentSession = class {
|
|
|
1440
1615
|
endOpenLine() {
|
|
1441
1616
|
if (this.lineOpen) this.options.io.write("\n");
|
|
1442
1617
|
this.lineOpen = false;
|
|
1618
|
+
this.reasoningActive = false;
|
|
1619
|
+
}
|
|
1620
|
+
writeRenderedResponse(rendered) {
|
|
1621
|
+
if (!rendered) return;
|
|
1622
|
+
if (!this.responseStarted) {
|
|
1623
|
+
this.options.io.write(`
|
|
1624
|
+
${accent3.bold("tt")} `);
|
|
1625
|
+
this.responseStarted = true;
|
|
1626
|
+
}
|
|
1627
|
+
this.options.io.write(rendered);
|
|
1628
|
+
this.lineOpen = !rendered.endsWith("\n");
|
|
1629
|
+
}
|
|
1630
|
+
flushResponse() {
|
|
1631
|
+
this.writeRenderedResponse(this.responseMarkdown.flush());
|
|
1443
1632
|
}
|
|
1444
1633
|
renderAction(action) {
|
|
1445
1634
|
this.endOpenLine();
|
|
1446
1635
|
this.options.io.write(
|
|
1447
1636
|
`
|
|
1448
|
-
${
|
|
1637
|
+
${chalk3.yellow.bold("Approval required")} ${chalk3.dim(action.id.slice(0, 8))}
|
|
1449
1638
|
`
|
|
1450
1639
|
);
|
|
1451
|
-
this.options.io.write(`${
|
|
1640
|
+
this.options.io.write(`${chalk3.bold(action.title)} ${chalk3.yellow(`[${action.risk} risk]`)}
|
|
1452
1641
|
`);
|
|
1453
1642
|
if (action.summary) this.options.io.write(`${action.summary}
|
|
1454
1643
|
`);
|
|
@@ -1459,12 +1648,12 @@ ${chalk2.yellow.bold("Approval required")} ${chalk2.dim(action.id.slice(0, 8))}
|
|
|
1459
1648
|
arguments: action.arguments ?? null,
|
|
1460
1649
|
preview: action.preview ?? null
|
|
1461
1650
|
};
|
|
1462
|
-
this.options.io.write(`${
|
|
1651
|
+
this.options.io.write(`${chalk3.bold("Proposed action")}
|
|
1463
1652
|
`);
|
|
1464
1653
|
this.options.io.write(`${formatJson(technical)}
|
|
1465
1654
|
`);
|
|
1466
1655
|
this.options.io.write(
|
|
1467
|
-
|
|
1656
|
+
chalk3.dim("Use /approve or /reject. The action will not run without approval.") + "\n"
|
|
1468
1657
|
);
|
|
1469
1658
|
}
|
|
1470
1659
|
renderEvent(event) {
|
|
@@ -1472,32 +1661,46 @@ ${chalk2.yellow.bold("Approval required")} ${chalk2.dim(action.id.slice(0, 8))}
|
|
|
1472
1661
|
if (event.type === "text_delta") {
|
|
1473
1662
|
const delta = stringValue2(payload.delta) ?? stringValue2(payload.text) ?? stringValue2(payload.content);
|
|
1474
1663
|
if (!delta) return;
|
|
1475
|
-
if (
|
|
1476
|
-
this.
|
|
1477
|
-
this.
|
|
1478
|
-
this.lineOpen = true;
|
|
1664
|
+
if (this.reasoningActive) {
|
|
1665
|
+
this.endOpenLine();
|
|
1666
|
+
this.options.io.write("\n");
|
|
1479
1667
|
}
|
|
1480
|
-
this.
|
|
1668
|
+
this.writeRenderedResponse(this.responseMarkdown.push(delta));
|
|
1669
|
+
return;
|
|
1670
|
+
}
|
|
1671
|
+
if (event.type === "reasoning_delta") {
|
|
1672
|
+
const delta = stringValue2(payload.delta) ?? stringValue2(payload.text) ?? stringValue2(payload.content);
|
|
1673
|
+
if (!delta) return;
|
|
1674
|
+
if (!this.reasoningActive) {
|
|
1675
|
+
this.flushResponse();
|
|
1676
|
+
this.endOpenLine();
|
|
1677
|
+
this.options.io.write("\n");
|
|
1678
|
+
this.reasoningActive = true;
|
|
1679
|
+
}
|
|
1680
|
+
this.options.io.write(chalk3.dim.italic(delta));
|
|
1481
1681
|
this.lineOpen = !delta.endsWith("\n");
|
|
1482
1682
|
return;
|
|
1483
1683
|
}
|
|
1484
1684
|
if (event.type === "tool_call") {
|
|
1685
|
+
this.flushResponse();
|
|
1485
1686
|
this.endOpenLine();
|
|
1486
1687
|
const name = stringValue2(payload.name) ?? stringValue2(isRecord(payload.tool_call) ? payload.tool_call.name : null) ?? "tool";
|
|
1487
|
-
this.options.io.write(
|
|
1688
|
+
this.options.io.write(chalk3.dim(` \u25CB ${name}
|
|
1488
1689
|
`));
|
|
1489
1690
|
return;
|
|
1490
1691
|
}
|
|
1491
1692
|
if (event.type === "tool_result") {
|
|
1693
|
+
this.flushResponse();
|
|
1492
1694
|
this.endOpenLine();
|
|
1493
1695
|
const failed = payload.status === "error" || Boolean(payload.error);
|
|
1494
1696
|
this.options.io.write(
|
|
1495
|
-
|
|
1697
|
+
chalk3.dim(` ${failed ? chalk3.red("\u2717") : chalk3.green("\u2713")} Tool ${failed ? "failed" : "complete"}
|
|
1496
1698
|
`)
|
|
1497
1699
|
);
|
|
1498
1700
|
return;
|
|
1499
1701
|
}
|
|
1500
1702
|
if (event.type === "approval_required") {
|
|
1703
|
+
this.flushResponse();
|
|
1501
1704
|
const action = actionFromPayload(payload);
|
|
1502
1705
|
if (!action) return;
|
|
1503
1706
|
this.pendingActions.set(action.id, action);
|
|
@@ -1505,11 +1708,13 @@ ${chalk2.yellow.bold("Approval required")} ${chalk2.dim(action.id.slice(0, 8))}
|
|
|
1505
1708
|
return;
|
|
1506
1709
|
}
|
|
1507
1710
|
if (event.type === "action_started") {
|
|
1711
|
+
this.flushResponse();
|
|
1508
1712
|
this.endOpenLine();
|
|
1509
|
-
this.options.io.write(
|
|
1713
|
+
this.options.io.write(chalk3.dim(" \u25CB Running approved action\u2026\n"));
|
|
1510
1714
|
return;
|
|
1511
1715
|
}
|
|
1512
1716
|
if (event.type === "action_result") {
|
|
1717
|
+
this.flushResponse();
|
|
1513
1718
|
this.endOpenLine();
|
|
1514
1719
|
const failed = payload.status === "failed" || Boolean(payload.error);
|
|
1515
1720
|
this.options.io.write(
|
|
@@ -1519,6 +1724,7 @@ ${chalk2.yellow.bold("Approval required")} ${chalk2.dim(action.id.slice(0, 8))}
|
|
|
1519
1724
|
return;
|
|
1520
1725
|
}
|
|
1521
1726
|
if (event.type === "error") {
|
|
1727
|
+
this.flushResponse();
|
|
1522
1728
|
this.endOpenLine();
|
|
1523
1729
|
const message = stringValue2(payload.message) ?? stringValue2(payload.error) ?? "The agent could not complete this request.";
|
|
1524
1730
|
this.options.io.writeError(`${errorMark2()} ${message}
|
|
@@ -1538,25 +1744,31 @@ ${chalk2.yellow.bold("Approval required")} ${chalk2.dim(action.id.slice(0, 8))}
|
|
|
1538
1744
|
const controller = new AbortController();
|
|
1539
1745
|
this.activeRequest = controller;
|
|
1540
1746
|
this.responseStarted = false;
|
|
1747
|
+
this.reasoningActive = false;
|
|
1541
1748
|
this.lineOpen = false;
|
|
1749
|
+
this.responseMarkdown.reset();
|
|
1542
1750
|
try {
|
|
1543
1751
|
const result = await operation(controller.signal);
|
|
1752
|
+
this.flushResponse();
|
|
1544
1753
|
this.endOpenLine();
|
|
1545
1754
|
for (const action of result.actions) {
|
|
1546
1755
|
this.pendingActions.set(action.id, action);
|
|
1547
1756
|
}
|
|
1548
1757
|
return result;
|
|
1549
1758
|
} catch (error) {
|
|
1759
|
+
this.flushResponse();
|
|
1550
1760
|
this.endOpenLine();
|
|
1551
1761
|
if (controller.signal.aborted) {
|
|
1552
|
-
this.options.io.write(
|
|
1762
|
+
this.options.io.write(chalk3.dim("Response stopped.\n"));
|
|
1553
1763
|
return null;
|
|
1554
1764
|
}
|
|
1555
1765
|
throw error;
|
|
1556
1766
|
} finally {
|
|
1557
1767
|
this.activeRequest = null;
|
|
1558
1768
|
this.responseStarted = false;
|
|
1769
|
+
this.reasoningActive = false;
|
|
1559
1770
|
this.lineOpen = false;
|
|
1771
|
+
this.responseMarkdown.reset();
|
|
1560
1772
|
}
|
|
1561
1773
|
}
|
|
1562
1774
|
async send(prompt) {
|
|
@@ -1634,7 +1846,7 @@ ${chalk2.yellow.bold("Approval required")} ${chalk2.dim(action.id.slice(0, 8))}
|
|
|
1634
1846
|
if (args.length > 0) throw new Error("/threads does not accept arguments.");
|
|
1635
1847
|
const threads = await this.options.client.listThreads();
|
|
1636
1848
|
if (threads.length === 0) {
|
|
1637
|
-
this.options.io.write(
|
|
1849
|
+
this.options.io.write(chalk3.dim("No conversations yet.\n"));
|
|
1638
1850
|
return "continue";
|
|
1639
1851
|
}
|
|
1640
1852
|
this.options.io.write(
|
|
@@ -1672,10 +1884,10 @@ ${chalk2.yellow.bold("Approval required")} ${chalk2.dim(action.id.slice(0, 8))}
|
|
|
1672
1884
|
if (args.length > 0) throw new Error("/status does not accept arguments.");
|
|
1673
1885
|
this.options.io.write(
|
|
1674
1886
|
this.thread ? `${formatThread(this.thread, this.thread.id)}
|
|
1675
|
-
` :
|
|
1887
|
+
` : chalk3.dim("New conversation; send a message to create it.\n")
|
|
1676
1888
|
);
|
|
1677
1889
|
this.options.io.write(
|
|
1678
|
-
|
|
1890
|
+
chalk3.dim(`${this.pendingActions.size} pending approval(s).
|
|
1679
1891
|
`)
|
|
1680
1892
|
);
|
|
1681
1893
|
return "continue";
|
|
@@ -1860,7 +2072,7 @@ function unknownProjectSpecKeys(raw) {
|
|
|
1860
2072
|
}
|
|
1861
2073
|
|
|
1862
2074
|
// src/output.ts
|
|
1863
|
-
import
|
|
2075
|
+
import chalk4 from "chalk";
|
|
1864
2076
|
import Table from "cli-table3";
|
|
1865
2077
|
var jsonMode = false;
|
|
1866
2078
|
function setJsonMode(enabled) {
|
|
@@ -1874,7 +2086,7 @@ function printJson(data) {
|
|
|
1874
2086
|
}
|
|
1875
2087
|
function printTable(headers, rows2, meta) {
|
|
1876
2088
|
const table = new Table({
|
|
1877
|
-
head: headers.map((h) =>
|
|
2089
|
+
head: headers.map((h) => chalk4.bold.cyan(h)),
|
|
1878
2090
|
style: { head: [], border: [] }
|
|
1879
2091
|
});
|
|
1880
2092
|
for (const row of rows2) {
|
|
@@ -1884,7 +2096,7 @@ function printTable(headers, rows2, meta) {
|
|
|
1884
2096
|
if (meta) {
|
|
1885
2097
|
const totalPages = Math.ceil(meta.total / meta.per_page);
|
|
1886
2098
|
console.log(
|
|
1887
|
-
|
|
2099
|
+
chalk4.dim(
|
|
1888
2100
|
`
|
|
1889
2101
|
Page ${meta.page}/${totalPages} (${meta.total} total)`
|
|
1890
2102
|
)
|
|
@@ -1895,17 +2107,17 @@ function printDetail(fields) {
|
|
|
1895
2107
|
const maxLabel = Math.max(...fields.map(([l]) => l.length));
|
|
1896
2108
|
for (const [label, value] of fields) {
|
|
1897
2109
|
const paddedLabel = label.padEnd(maxLabel);
|
|
1898
|
-
console.log(`${
|
|
2110
|
+
console.log(`${chalk4.bold.cyan(paddedLabel)} ${value ?? chalk4.dim("\u2014")}`);
|
|
1899
2111
|
}
|
|
1900
2112
|
}
|
|
1901
2113
|
function printSuccess(message) {
|
|
1902
|
-
console.log(
|
|
2114
|
+
console.log(chalk4.green("\u2713") + " " + message);
|
|
1903
2115
|
}
|
|
1904
2116
|
function printWarning(message) {
|
|
1905
|
-
console.log(
|
|
2117
|
+
console.log(chalk4.yellow("!") + " " + message);
|
|
1906
2118
|
}
|
|
1907
2119
|
function printError(message) {
|
|
1908
|
-
console.error(
|
|
2120
|
+
console.error(chalk4.red("\u2717") + " " + message);
|
|
1909
2121
|
}
|
|
1910
2122
|
function reportError(err) {
|
|
1911
2123
|
const isApi = err instanceof ApiError;
|
|
@@ -1930,19 +2142,19 @@ function formatDate(iso) {
|
|
|
1930
2142
|
}
|
|
1931
2143
|
function formatStatus(status2) {
|
|
1932
2144
|
const map = {
|
|
1933
|
-
completed:
|
|
1934
|
-
running:
|
|
1935
|
-
training:
|
|
1936
|
-
evaluating:
|
|
1937
|
-
preparing:
|
|
1938
|
-
pending:
|
|
1939
|
-
uploading:
|
|
1940
|
-
failed:
|
|
1941
|
-
cancelled:
|
|
1942
|
-
validated:
|
|
1943
|
-
invalid:
|
|
2145
|
+
completed: chalk4.green,
|
|
2146
|
+
running: chalk4.blue,
|
|
2147
|
+
training: chalk4.blue,
|
|
2148
|
+
evaluating: chalk4.blue,
|
|
2149
|
+
preparing: chalk4.yellow,
|
|
2150
|
+
pending: chalk4.yellow,
|
|
2151
|
+
uploading: chalk4.yellow,
|
|
2152
|
+
failed: chalk4.red,
|
|
2153
|
+
cancelled: chalk4.dim,
|
|
2154
|
+
validated: chalk4.green,
|
|
2155
|
+
invalid: chalk4.red
|
|
1944
2156
|
};
|
|
1945
|
-
const colorFn = map[status2] ||
|
|
2157
|
+
const colorFn = map[status2] || chalk4.white;
|
|
1946
2158
|
return colorFn(status2);
|
|
1947
2159
|
}
|
|
1948
2160
|
function truncate(str, max) {
|
|
@@ -2785,7 +2997,7 @@ async function executeLocalCommand(args, options = {}) {
|
|
|
2785
2997
|
import { createInterface as createInterface2 } from "readline/promises";
|
|
2786
2998
|
import { stdin, stdout } from "process";
|
|
2787
2999
|
import { Writable } from "stream";
|
|
2788
|
-
import
|
|
3000
|
+
import chalk5 from "chalk";
|
|
2789
3001
|
async function promptForApiKey(input = stdin, output = stdout) {
|
|
2790
3002
|
if (input.isTTY !== true || output.isTTY !== true) {
|
|
2791
3003
|
throw new Error(
|
|
@@ -2827,9 +3039,9 @@ function registerAuthCommands(parent) {
|
|
|
2827
3039
|
const settingsUrl = `${DEFAULT_BASE_URL}/dashboard/settings`;
|
|
2828
3040
|
console.log();
|
|
2829
3041
|
console.log(
|
|
2830
|
-
` To get your API key, go to ${
|
|
3042
|
+
` To get your API key, go to ${chalk5.bold("Settings \u2192 API Keys")} in the Tuned Tensor dashboard:`
|
|
2831
3043
|
);
|
|
2832
|
-
console.log(` ${
|
|
3044
|
+
console.log(` ${chalk5.cyan.underline(settingsUrl)}`);
|
|
2833
3045
|
console.log();
|
|
2834
3046
|
apiKey = await promptForApiKey();
|
|
2835
3047
|
}
|
|
@@ -6293,7 +6505,7 @@ function registerModelsCommands(parent) {
|
|
|
6293
6505
|
}
|
|
6294
6506
|
|
|
6295
6507
|
// src/commands/balance.ts
|
|
6296
|
-
import
|
|
6508
|
+
import chalk6 from "chalk";
|
|
6297
6509
|
var KIND_LABELS = {
|
|
6298
6510
|
signup_bonus: "Signup bonus",
|
|
6299
6511
|
topup: "Top-up",
|
|
@@ -6308,8 +6520,8 @@ function formatCents3(cents) {
|
|
|
6308
6520
|
return `${sign}$${(abs / 100).toFixed(2)}`;
|
|
6309
6521
|
}
|
|
6310
6522
|
function formatSigned(cents) {
|
|
6311
|
-
if (cents > 0) return
|
|
6312
|
-
if (cents < 0) return
|
|
6523
|
+
if (cents > 0) return chalk6.green(`+${formatCents3(cents)}`);
|
|
6524
|
+
if (cents < 0) return chalk6.red(formatCents3(cents));
|
|
6313
6525
|
return formatCents3(cents);
|
|
6314
6526
|
}
|
|
6315
6527
|
function registerBalanceCommands(parent) {
|
|
@@ -6324,7 +6536,7 @@ function registerBalanceCommands(parent) {
|
|
|
6324
6536
|
return printJson({ balance, transactions });
|
|
6325
6537
|
}
|
|
6326
6538
|
const lowBalance = balance.balance_cents < 100;
|
|
6327
|
-
const balanceLine = lowBalance ?
|
|
6539
|
+
const balanceLine = lowBalance ? chalk6.red(formatCents3(balance.balance_cents)) + chalk6.dim(" (low)") : chalk6.bold.green(formatCents3(balance.balance_cents));
|
|
6328
6540
|
printDetail([
|
|
6329
6541
|
["Credits", balanceLine],
|
|
6330
6542
|
[
|
|
@@ -6339,7 +6551,7 @@ function registerBalanceCommands(parent) {
|
|
|
6339
6551
|
]);
|
|
6340
6552
|
if (transactions && transactions.length > 0) {
|
|
6341
6553
|
console.log(`
|
|
6342
|
-
${
|
|
6554
|
+
${chalk6.bold("Recent transactions")}`);
|
|
6343
6555
|
printTable(
|
|
6344
6556
|
["Date", "Type", "Amount", "Balance", "Reference"],
|
|
6345
6557
|
transactions.map((row) => [
|
|
@@ -6347,19 +6559,19 @@ ${chalk5.bold("Recent transactions")}`);
|
|
|
6347
6559
|
KIND_LABELS[row.kind] ?? row.kind,
|
|
6348
6560
|
formatSigned(row.amount_cents),
|
|
6349
6561
|
formatCents3(row.balance_after_cents),
|
|
6350
|
-
row.reference_id ? shortId(row.reference_id) :
|
|
6562
|
+
row.reference_id ? shortId(row.reference_id) : chalk6.dim("\u2014")
|
|
6351
6563
|
])
|
|
6352
6564
|
);
|
|
6353
6565
|
} else {
|
|
6354
6566
|
console.log(
|
|
6355
6567
|
`
|
|
6356
|
-
${
|
|
6568
|
+
${chalk6.dim("No transactions yet \u2014 run `tt topup` to add credits.")}`
|
|
6357
6569
|
);
|
|
6358
6570
|
}
|
|
6359
6571
|
if (lowBalance) {
|
|
6360
6572
|
console.log(
|
|
6361
6573
|
`
|
|
6362
|
-
${formatStatus("preparing")} ${
|
|
6574
|
+
${formatStatus("preparing")} ${chalk6.yellow(
|
|
6363
6575
|
"Run `tt topup` to add more credits before starting a run."
|
|
6364
6576
|
)}`
|
|
6365
6577
|
);
|
|
@@ -6368,7 +6580,7 @@ ${formatStatus("preparing")} ${chalk5.yellow(
|
|
|
6368
6580
|
}
|
|
6369
6581
|
|
|
6370
6582
|
// src/commands/topup.ts
|
|
6371
|
-
import
|
|
6583
|
+
import chalk7 from "chalk";
|
|
6372
6584
|
import open from "open";
|
|
6373
6585
|
var PRESETS_USD = [10, 25, 50, 100];
|
|
6374
6586
|
var MIN_USD = 5;
|
|
@@ -6407,9 +6619,9 @@ function registerTopupCommands(parent) {
|
|
|
6407
6619
|
"amount is required in --json mode (use --amount <usd>)"
|
|
6408
6620
|
);
|
|
6409
6621
|
}
|
|
6410
|
-
console.log(
|
|
6622
|
+
console.log(chalk7.bold("Add credits via Stripe Checkout"));
|
|
6411
6623
|
console.log(
|
|
6412
|
-
|
|
6624
|
+
chalk7.dim(
|
|
6413
6625
|
`Quick picks: ${PRESETS_USD.map((n) => `$${n}`).join(", ")}`
|
|
6414
6626
|
)
|
|
6415
6627
|
);
|
|
@@ -6436,8 +6648,8 @@ function registerTopupCommands(parent) {
|
|
|
6436
6648
|
}
|
|
6437
6649
|
const url = data.checkout_url;
|
|
6438
6650
|
console.log(
|
|
6439
|
-
`${
|
|
6440
|
-
` +
|
|
6651
|
+
`${chalk7.bold("Checkout URL:")} ${chalk7.cyan(url)}
|
|
6652
|
+
` + chalk7.dim("Complete the payment to credit your account.")
|
|
6441
6653
|
);
|
|
6442
6654
|
if (options.open !== false) {
|
|
6443
6655
|
try {
|
|
@@ -6445,7 +6657,7 @@ function registerTopupCommands(parent) {
|
|
|
6445
6657
|
printSuccess("Opened Stripe Checkout in your browser.");
|
|
6446
6658
|
} catch {
|
|
6447
6659
|
console.log(
|
|
6448
|
-
|
|
6660
|
+
chalk7.yellow(
|
|
6449
6661
|
"Could not open browser automatically \u2014 copy the URL above."
|
|
6450
6662
|
)
|
|
6451
6663
|
);
|
|
@@ -6455,7 +6667,7 @@ function registerTopupCommands(parent) {
|
|
|
6455
6667
|
}
|
|
6456
6668
|
|
|
6457
6669
|
// src/commands/eval.ts
|
|
6458
|
-
import
|
|
6670
|
+
import chalk8 from "chalk";
|
|
6459
6671
|
|
|
6460
6672
|
// src/eval/rules.ts
|
|
6461
6673
|
function validateSpec(spec) {
|
|
@@ -6620,7 +6832,7 @@ function registerEvalCommand(parent) {
|
|
|
6620
6832
|
const spec = loadSpec(cmdOpts.file);
|
|
6621
6833
|
const validation = validateSpec(spec);
|
|
6622
6834
|
if (!isJsonMode()) {
|
|
6623
|
-
console.log(
|
|
6835
|
+
console.log(chalk8.dim(`
|
|
6624
6836
|
Spec: ${cmdOpts.file}
|
|
6625
6837
|
`));
|
|
6626
6838
|
}
|
|
@@ -6635,10 +6847,10 @@ Spec: ${cmdOpts.file}
|
|
|
6635
6847
|
});
|
|
6636
6848
|
}
|
|
6637
6849
|
function printValidation(checks) {
|
|
6638
|
-
console.log(
|
|
6850
|
+
console.log(chalk8.bold("Spec Validation"));
|
|
6639
6851
|
for (const check of checks) {
|
|
6640
|
-
const icon = check.passed ?
|
|
6641
|
-
const msg = check.message ?
|
|
6852
|
+
const icon = check.passed ? chalk8.green("\u2713") : chalk8.red("\u2717");
|
|
6853
|
+
const msg = check.message ? chalk8.dim(` \u2014 ${check.message}`) : "";
|
|
6642
6854
|
console.log(` ${icon} ${check.name}${msg}`);
|
|
6643
6855
|
}
|
|
6644
6856
|
}
|
|
@@ -6823,7 +7035,7 @@ function createProgram(version, runtime = {}) {
|
|
|
6823
7035
|
if (root.json) setJsonMode(true);
|
|
6824
7036
|
if (root.color === false) {
|
|
6825
7037
|
process.env.FORCE_COLOR = "0";
|
|
6826
|
-
|
|
7038
|
+
chalk9.level = 0;
|
|
6827
7039
|
}
|
|
6828
7040
|
});
|
|
6829
7041
|
registerAuthCommands(program);
|
|
@@ -6856,12 +7068,12 @@ function createProgram(version, runtime = {}) {
|
|
|
6856
7068
|
`);
|
|
6857
7069
|
return;
|
|
6858
7070
|
}
|
|
6859
|
-
output.write(`${
|
|
7071
|
+
output.write(`${chalk9.bold.cyan("Tuned Tensor status")}
|
|
6860
7072
|
`);
|
|
6861
7073
|
output.write(`${formatShellStatus(context, target).join("\n")}
|
|
6862
7074
|
|
|
6863
7075
|
`);
|
|
6864
|
-
output.write(`${
|
|
7076
|
+
output.write(`${chalk9.bold("Context")}
|
|
6865
7077
|
`);
|
|
6866
7078
|
output.write(
|
|
6867
7079
|
`${formatShellContext(
|
|
@@ -6875,7 +7087,7 @@ function createProgram(version, runtime = {}) {
|
|
|
6875
7087
|
program.command("local").description("Run the local CUDA training and model workflow").helpOption(false).allowUnknownOption().argument("[args...]", "TT Local command and arguments").action(async (args) => {
|
|
6876
7088
|
const root = program.opts();
|
|
6877
7089
|
const passthrough = extractPassthroughOptions(args, root);
|
|
6878
|
-
if (!passthrough.color)
|
|
7090
|
+
if (!passthrough.color) chalk9.level = 0;
|
|
6879
7091
|
const result = await invokeLocal(
|
|
6880
7092
|
passthrough.args.length > 0 ? passthrough.args : ["--help"],
|
|
6881
7093
|
{
|
|
@@ -6989,7 +7201,7 @@ async function runCli(version, runtime = {}) {
|
|
|
6989
7201
|
}
|
|
6990
7202
|
|
|
6991
7203
|
// src/index.ts
|
|
6992
|
-
runCli("0.
|
|
7204
|
+
runCli("0.8.1").catch((err) => {
|
|
6993
7205
|
reportError(err);
|
|
6994
7206
|
process.exit(1);
|
|
6995
7207
|
});
|