@tuned-tensor/cli 0.12.0-beta.0 → 0.12.0-beta.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/README.md +33 -28
- package/dist/index.js +253 -138
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -583,7 +583,7 @@ function resolveAgentModel(runtime, selection) {
|
|
|
583
583
|
const resolved = resolveAgentModelDefinition(runtime, selection);
|
|
584
584
|
if (!runtime.hasConfiguredAuth(selection.provider)) {
|
|
585
585
|
throw new Error(
|
|
586
|
-
`Authenticate
|
|
586
|
+
`Authenticate provider "${selection.provider}" first, then retry. Provider secrets are never accepted by tt flags.`
|
|
587
587
|
);
|
|
588
588
|
}
|
|
589
589
|
return resolved;
|
|
@@ -594,7 +594,7 @@ function resolveAgentModelDefinition(runtime, selection) {
|
|
|
594
594
|
);
|
|
595
595
|
if (!provider) {
|
|
596
596
|
throw new Error(
|
|
597
|
-
`Unknown
|
|
597
|
+
`Unknown provider "${selection.provider}". Run \`tt agent models --all\` to list providers and models.`
|
|
598
598
|
);
|
|
599
599
|
}
|
|
600
600
|
const model = runtime.getModel(selection.provider, selection.model);
|
|
@@ -1127,7 +1127,7 @@ You have no general filesystem tools. The only workspace-scoped local spec capab
|
|
|
1127
1127
|
}
|
|
1128
1128
|
function defaultAgent(options) {
|
|
1129
1129
|
if (!options.streamSimple) {
|
|
1130
|
-
throw new Error("The configured
|
|
1130
|
+
throw new Error("The configured model runtime cannot stream this model.");
|
|
1131
1131
|
}
|
|
1132
1132
|
let calls = 0;
|
|
1133
1133
|
return new Agent({
|
|
@@ -1570,6 +1570,10 @@ function readConfig() {
|
|
|
1570
1570
|
return {};
|
|
1571
1571
|
}
|
|
1572
1572
|
}
|
|
1573
|
+
var configRevision = 0;
|
|
1574
|
+
function getConfigRevision() {
|
|
1575
|
+
return configRevision;
|
|
1576
|
+
}
|
|
1573
1577
|
function writeConfig(config) {
|
|
1574
1578
|
const dir = getConfigDir();
|
|
1575
1579
|
if (!existsSync2(dir)) mkdirSync2(dir, { recursive: true, mode: 448 });
|
|
@@ -1579,6 +1583,7 @@ function writeConfig(config) {
|
|
|
1579
1583
|
mode: 384
|
|
1580
1584
|
});
|
|
1581
1585
|
chmodSync(path, 384);
|
|
1586
|
+
configRevision += 1;
|
|
1582
1587
|
}
|
|
1583
1588
|
function updateConfig(partial) {
|
|
1584
1589
|
const current = readConfig();
|
|
@@ -1770,11 +1775,7 @@ var SLASH_COMMANDS = [
|
|
|
1770
1775
|
{ path: "/help", description: "Show commands; add a word to filter." },
|
|
1771
1776
|
{ path: "/status", description: "Show lightweight workflow status." },
|
|
1772
1777
|
{ path: "/context", description: "Show the current project and backend context." },
|
|
1773
|
-
{ path: "/
|
|
1774
|
-
{ path: "/local", description: "Switch to the local GPU workflow." },
|
|
1775
|
-
{ path: "/mode cloud", description: "Alias for /cloud." },
|
|
1776
|
-
{ path: "/mode local", description: "Alias for /local." },
|
|
1777
|
-
{ path: "/model", description: "Show the active model; /model <id> activates a local model." },
|
|
1778
|
+
{ path: "/model", description: "Show or change the TT agent model." },
|
|
1778
1779
|
{ path: "/cd", description: "Change the shell's working directory." },
|
|
1779
1780
|
{ path: "/clear", description: "Clear the terminal." },
|
|
1780
1781
|
{ path: "/exit", description: "Exit the TT shell." }
|
|
@@ -1994,8 +1995,8 @@ async function discoverShellContext(options = {}) {
|
|
|
1994
1995
|
if (env.TT_TARGET && !environmentTarget) {
|
|
1995
1996
|
warnings.push(`Ignoring invalid TT_TARGET=${JSON.stringify(env.TT_TARGET)}; use cloud or local.`);
|
|
1996
1997
|
}
|
|
1997
|
-
const inferredTarget = environmentTarget ??
|
|
1998
|
-
const targetSource = environmentTarget ? "environment" :
|
|
1998
|
+
const inferredTarget = environmentTarget ?? "local";
|
|
1999
|
+
const targetSource = environmentTarget ? "environment" : "default-local";
|
|
1999
2000
|
const [activeModelId, latestRun] = await Promise.all([
|
|
2000
2001
|
readActiveModelId(storeRoot),
|
|
2001
2002
|
readLatestRun(storeRoot)
|
|
@@ -2037,15 +2038,13 @@ function targetSourceLabel(source) {
|
|
|
2037
2038
|
switch (source) {
|
|
2038
2039
|
case "environment":
|
|
2039
2040
|
return "TT_TARGET";
|
|
2040
|
-
case "adjacent-config":
|
|
2041
|
-
return "adjacent local-runner.json";
|
|
2042
2041
|
default:
|
|
2043
2042
|
return "default";
|
|
2044
2043
|
}
|
|
2045
2044
|
}
|
|
2046
2045
|
function formatShellContext(context, selectedTarget, targetSource) {
|
|
2047
2046
|
const specLabel = context.spec ? context.spec.parseError ? `${context.spec.path} (invalid JSON)` : context.spec.path : "not found";
|
|
2048
|
-
const sourceLabel = targetSource === "
|
|
2047
|
+
const sourceLabel = targetSource === "command-option" ? "--target" : targetSourceLabel(targetSource);
|
|
2049
2048
|
const lines = [
|
|
2050
2049
|
`Target ${selectedTarget} (${sourceLabel})`,
|
|
2051
2050
|
`Project ${context.projectName}`,
|
|
@@ -2087,6 +2086,103 @@ function formatShellStatus(context, selectedTarget) {
|
|
|
2087
2086
|
return lines;
|
|
2088
2087
|
}
|
|
2089
2088
|
|
|
2089
|
+
// src/agent-control.ts
|
|
2090
|
+
function modelKey(model) {
|
|
2091
|
+
return `${model.provider}/${model.id}`;
|
|
2092
|
+
}
|
|
2093
|
+
function modelRelevance(model, query) {
|
|
2094
|
+
const q = query.trim().toLowerCase();
|
|
2095
|
+
if (!q) return void 0;
|
|
2096
|
+
const fullId = modelKey(model).toLowerCase();
|
|
2097
|
+
const bareId = model.id.toLowerCase();
|
|
2098
|
+
const name = model.name.toLowerCase();
|
|
2099
|
+
if (fullId === q || bareId === q) return 0;
|
|
2100
|
+
if (fullId.startsWith(q)) return 1;
|
|
2101
|
+
if (bareId.startsWith(q)) return 2;
|
|
2102
|
+
if (fullId.includes(q)) return 3;
|
|
2103
|
+
if (name.includes(q)) return 4;
|
|
2104
|
+
return void 0;
|
|
2105
|
+
}
|
|
2106
|
+
function listAgentModels(runtime, options = {}) {
|
|
2107
|
+
let models = runtime.getModels(options.provider).filter(
|
|
2108
|
+
(model) => options.includeUnauthenticated || runtime.hasConfiguredAuth(model.provider)
|
|
2109
|
+
).map((model) => ({
|
|
2110
|
+
provider: model.provider,
|
|
2111
|
+
id: model.id,
|
|
2112
|
+
name: model.name ?? model.id,
|
|
2113
|
+
authenticated: runtime.hasConfiguredAuth(model.provider),
|
|
2114
|
+
thinking: model.reasoning !== false
|
|
2115
|
+
}));
|
|
2116
|
+
const query = options.query?.trim().toLowerCase();
|
|
2117
|
+
if (query) {
|
|
2118
|
+
const scored = [];
|
|
2119
|
+
for (const model of models) {
|
|
2120
|
+
const score = modelRelevance(model, query);
|
|
2121
|
+
if (score !== void 0) scored.push({ model, score });
|
|
2122
|
+
}
|
|
2123
|
+
scored.sort(
|
|
2124
|
+
(left, right) => left.score - right.score || modelKey(left.model).localeCompare(modelKey(right.model))
|
|
2125
|
+
);
|
|
2126
|
+
models = scored.map((entry) => entry.model);
|
|
2127
|
+
} else {
|
|
2128
|
+
models.sort((left, right) => modelKey(left).localeCompare(modelKey(right)));
|
|
2129
|
+
}
|
|
2130
|
+
if (options.limit !== void 0 && options.limit > 0) {
|
|
2131
|
+
models = models.slice(0, options.limit);
|
|
2132
|
+
}
|
|
2133
|
+
return models;
|
|
2134
|
+
}
|
|
2135
|
+
function describeAgentModel(runtime, env) {
|
|
2136
|
+
const selection = getAgentSelection(env);
|
|
2137
|
+
if (!selection) return void 0;
|
|
2138
|
+
const resolved = resolveAgentModelDefinition(runtime, selection);
|
|
2139
|
+
const providerName = runtime.getProviders().find((provider) => provider.id === selection.provider)?.name;
|
|
2140
|
+
return {
|
|
2141
|
+
provider: selection.provider,
|
|
2142
|
+
providerName,
|
|
2143
|
+
model: selection.model,
|
|
2144
|
+
modelName: resolved.model.name,
|
|
2145
|
+
thinking: selection.thinking,
|
|
2146
|
+
authenticated: runtime.hasConfiguredAuth(selection.provider),
|
|
2147
|
+
supportsThinking: resolved.model.reasoning !== false
|
|
2148
|
+
};
|
|
2149
|
+
}
|
|
2150
|
+
function setAgentModel(runtime, env, provider, model, options = {}) {
|
|
2151
|
+
const current = getAgentSelection(env);
|
|
2152
|
+
const requestedThinking = options.thinking ?? current?.thinking ?? "medium";
|
|
2153
|
+
if (!AGENT_THINKING_LEVELS.includes(requestedThinking)) {
|
|
2154
|
+
throw new Error(
|
|
2155
|
+
`Agent thinking must be one of: ${AGENT_THINKING_LEVELS.join(", ")}`
|
|
2156
|
+
);
|
|
2157
|
+
}
|
|
2158
|
+
const adjust = options.adjustThinking ?? true;
|
|
2159
|
+
if (!adjust) {
|
|
2160
|
+
const selection2 = {
|
|
2161
|
+
provider,
|
|
2162
|
+
model,
|
|
2163
|
+
thinking: requestedThinking
|
|
2164
|
+
};
|
|
2165
|
+
resolveAgentModel(runtime, selection2);
|
|
2166
|
+
updateConfig({ agent: selection2 });
|
|
2167
|
+
return { selection: selection2, adjustedThinking: false };
|
|
2168
|
+
}
|
|
2169
|
+
const definition = resolveAgentModelDefinition(runtime, {
|
|
2170
|
+
provider,
|
|
2171
|
+
model,
|
|
2172
|
+
thinking: "off"
|
|
2173
|
+
});
|
|
2174
|
+
const supportsThinking = definition.model.reasoning !== false;
|
|
2175
|
+
const effectiveThinking = supportsThinking ? requestedThinking : "off";
|
|
2176
|
+
const selection = {
|
|
2177
|
+
provider,
|
|
2178
|
+
model,
|
|
2179
|
+
thinking: effectiveThinking
|
|
2180
|
+
};
|
|
2181
|
+
resolveAgentModel(runtime, selection);
|
|
2182
|
+
updateConfig({ agent: selection });
|
|
2183
|
+
return { selection, adjustedThinking: effectiveThinking !== requestedThinking };
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2090
2186
|
// src/shell.ts
|
|
2091
2187
|
var AGENT_SLASH_COMMANDS = /* @__PURE__ */ new Set([
|
|
2092
2188
|
"new",
|
|
@@ -2217,7 +2313,7 @@ function routeShellCommand(input, activeMode) {
|
|
|
2217
2313
|
const override = args2[0];
|
|
2218
2314
|
if (override === "cloud" || override === "local") {
|
|
2219
2315
|
if (args2.length === 1) {
|
|
2220
|
-
throw new ShellParseError(`Add a ${override} command,
|
|
2316
|
+
throw new ShellParseError(`Add a ${override} command, e.g. \`${override} runs list\`.`);
|
|
2221
2317
|
}
|
|
2222
2318
|
return { target: override, args: args2.slice(1) };
|
|
2223
2319
|
}
|
|
@@ -2246,9 +2342,6 @@ var SLASH_NAMES = /* @__PURE__ */ new Set([
|
|
|
2246
2342
|
"help",
|
|
2247
2343
|
"status",
|
|
2248
2344
|
"context",
|
|
2249
|
-
"mode",
|
|
2250
|
-
"cloud",
|
|
2251
|
-
"local",
|
|
2252
2345
|
"model",
|
|
2253
2346
|
"clear",
|
|
2254
2347
|
"cd",
|
|
@@ -2410,7 +2503,7 @@ function helpText(mode, query, palette = false) {
|
|
|
2410
2503
|
`;
|
|
2411
2504
|
}
|
|
2412
2505
|
function activeModelLabel(snapshot) {
|
|
2413
|
-
return snapshot.
|
|
2506
|
+
return snapshot.context.local.activeModelId ?? "base";
|
|
2414
2507
|
}
|
|
2415
2508
|
function agentModelLabel(context) {
|
|
2416
2509
|
const agent = context.agent;
|
|
@@ -2465,20 +2558,19 @@ function resetShellPromptStyle() {
|
|
|
2465
2558
|
return "";
|
|
2466
2559
|
}
|
|
2467
2560
|
var TunedTensorShellSession = class _TunedTensorShellSession {
|
|
2468
|
-
constructor(runner, io, agent, env, contextProvider, version, initialContext) {
|
|
2561
|
+
constructor(runner, io, agent, env, contextProvider, version, agentModelRuntime, initialContext) {
|
|
2469
2562
|
this.runner = runner;
|
|
2470
2563
|
this.io = io;
|
|
2471
2564
|
this.agent = agent;
|
|
2472
2565
|
this.env = env;
|
|
2473
2566
|
this.contextProvider = contextProvider;
|
|
2474
2567
|
this.version = version;
|
|
2475
|
-
this.
|
|
2476
|
-
this.modeSource = initialContext.targetSource;
|
|
2568
|
+
this.agentModelRuntime = agentModelRuntime;
|
|
2477
2569
|
this.cwd = initialContext.cwd;
|
|
2478
2570
|
this.context = initialContext;
|
|
2479
2571
|
}
|
|
2480
|
-
mode;
|
|
2481
|
-
modeSource;
|
|
2572
|
+
mode = "local";
|
|
2573
|
+
modeSource = "default-local";
|
|
2482
2574
|
cwd;
|
|
2483
2575
|
context;
|
|
2484
2576
|
static async create(options) {
|
|
@@ -2493,6 +2585,7 @@ var TunedTensorShellSession = class _TunedTensorShellSession {
|
|
|
2493
2585
|
env,
|
|
2494
2586
|
contextProvider,
|
|
2495
2587
|
options.version,
|
|
2588
|
+
options.agentModelRuntime,
|
|
2496
2589
|
initialContext
|
|
2497
2590
|
);
|
|
2498
2591
|
}
|
|
@@ -2517,26 +2610,67 @@ var TunedTensorShellSession = class _TunedTensorShellSession {
|
|
|
2517
2610
|
async refreshContext() {
|
|
2518
2611
|
this.context = await this.contextProvider({ cwd: this.cwd, env: this.env });
|
|
2519
2612
|
this.cwd = this.context.cwd;
|
|
2520
|
-
if (this.modeSource !== "session" && this.modeSource !== "environment") {
|
|
2521
|
-
this.mode = this.context.inferredTarget;
|
|
2522
|
-
this.modeSource = this.context.targetSource;
|
|
2523
|
-
}
|
|
2524
2613
|
}
|
|
2525
2614
|
writeLines(lines) {
|
|
2526
2615
|
this.io.write(`${lines.join("\n")}
|
|
2527
2616
|
`);
|
|
2528
2617
|
}
|
|
2529
|
-
|
|
2530
|
-
if (this.
|
|
2531
|
-
|
|
2532
|
-
detailLine("Active model", this.context.local.activeModelId ?? "base"),
|
|
2533
|
-
detailLine("Change", "/model <id> to activate a verified local model")
|
|
2534
|
-
]);
|
|
2618
|
+
async requireAgentModelRuntime() {
|
|
2619
|
+
if (!this.agentModelRuntime) {
|
|
2620
|
+
throw new ShellParseError("The local agent model runtime is unavailable.");
|
|
2535
2621
|
}
|
|
2536
|
-
return
|
|
2537
|
-
|
|
2538
|
-
|
|
2622
|
+
return await this.agentModelRuntime();
|
|
2623
|
+
}
|
|
2624
|
+
renderAgentModel(runtime, query) {
|
|
2625
|
+
let summary;
|
|
2626
|
+
try {
|
|
2627
|
+
summary = describeAgentModel(runtime, this.env);
|
|
2628
|
+
} catch {
|
|
2629
|
+
summary = void 0;
|
|
2630
|
+
}
|
|
2631
|
+
const label = summary ? `${summary.provider}/${summary.model}${summary.modelName && summary.modelName !== summary.model ? ` (${summary.modelName})` : ""} \u2014 thinking ${summary.thinking}, auth ${summary.authenticated ? "configured" : "required"}` : "not configured";
|
|
2632
|
+
const lines = styleDetailLines([
|
|
2633
|
+
detailLine("Agent model", label),
|
|
2634
|
+
detailLine("Change", "/model <provider>/<model>"),
|
|
2635
|
+
detailLine("Search", "/model <query>")
|
|
2539
2636
|
]);
|
|
2637
|
+
const all = listAgentModels(runtime);
|
|
2638
|
+
if (all.length === 0) {
|
|
2639
|
+
lines.push("", chalk.dim(" no authenticated models \u2014 run `tt agent models --all` for the full catalog"));
|
|
2640
|
+
return lines;
|
|
2641
|
+
}
|
|
2642
|
+
if (query) {
|
|
2643
|
+
const matches = listAgentModels(runtime, { query });
|
|
2644
|
+
lines.push("", chalk.bold(`Models matching ${JSON.stringify(query)}`));
|
|
2645
|
+
if (matches.length === 0) {
|
|
2646
|
+
lines.push(chalk.dim(" no matches"));
|
|
2647
|
+
} else {
|
|
2648
|
+
const shown2 = matches.slice(0, 10);
|
|
2649
|
+
for (const model of shown2) {
|
|
2650
|
+
lines.push(this.formatAgentModelChoice(model, summary));
|
|
2651
|
+
}
|
|
2652
|
+
if (matches.length > shown2.length) {
|
|
2653
|
+
lines.push(chalk.dim(` \u2026 ${matches.length - shown2.length} more \u2014 refine the query`));
|
|
2654
|
+
}
|
|
2655
|
+
}
|
|
2656
|
+
return lines;
|
|
2657
|
+
}
|
|
2658
|
+
const preferred = summary ? all.filter((model) => model.provider === summary.provider) : [];
|
|
2659
|
+
const rest = summary ? all.filter((model) => model.provider !== summary.provider) : all;
|
|
2660
|
+
const shown = [...preferred, ...rest].slice(0, 8);
|
|
2661
|
+
lines.push("", chalk.bold(summary ? "Suggestions" : "Available models"));
|
|
2662
|
+
for (const model of shown) {
|
|
2663
|
+
lines.push(this.formatAgentModelChoice(model, summary));
|
|
2664
|
+
}
|
|
2665
|
+
if (all.length > shown.length) {
|
|
2666
|
+
lines.push(chalk.dim(` \u2026 ${all.length - shown.length} more \u2014 /model <query> to search`));
|
|
2667
|
+
}
|
|
2668
|
+
return lines;
|
|
2669
|
+
}
|
|
2670
|
+
formatAgentModelChoice(model, summary) {
|
|
2671
|
+
const active = summary?.provider === model.provider && summary?.model === model.id;
|
|
2672
|
+
const displayName = model.name !== model.id ? ` ${model.name}` : "";
|
|
2673
|
+
return ` ${accent(`${model.provider}/${model.id}`)}${displayName}${active ? chalk.dim(" (active)") : ""}`;
|
|
2540
2674
|
}
|
|
2541
2675
|
async handleSlash(command) {
|
|
2542
2676
|
switch (command.name) {
|
|
@@ -2558,49 +2692,37 @@ var TunedTensorShellSession = class _TunedTensorShellSession {
|
|
|
2558
2692
|
formatShellContext(this.context, this.mode, this.modeSource)
|
|
2559
2693
|
));
|
|
2560
2694
|
return "continue";
|
|
2561
|
-
case "mode": {
|
|
2562
|
-
if (command.args.length === 0) {
|
|
2563
|
-
this.io.write(`Current workflow: ${this.mode}
|
|
2564
|
-
`);
|
|
2565
|
-
return "continue";
|
|
2566
|
-
}
|
|
2567
|
-
if (command.args.length !== 1 || !["cloud", "local"].includes(command.args[0])) {
|
|
2568
|
-
throw new ShellParseError("Usage: /mode cloud|local");
|
|
2569
|
-
}
|
|
2570
|
-
this.mode = command.args[0];
|
|
2571
|
-
this.modeSource = "session";
|
|
2572
|
-
this.io.write(`${successMark()} Workflow switched to ${this.mode}.
|
|
2573
|
-
`);
|
|
2574
|
-
return "continue";
|
|
2575
|
-
}
|
|
2576
|
-
case "cloud":
|
|
2577
|
-
case "local":
|
|
2578
|
-
assertNoArgs(command.name, command.args);
|
|
2579
|
-
this.mode = command.name;
|
|
2580
|
-
this.modeSource = "session";
|
|
2581
|
-
this.io.write(`${successMark()} Workflow switched to ${this.mode}.
|
|
2582
|
-
`);
|
|
2583
|
-
return "continue";
|
|
2584
2695
|
case "model": {
|
|
2696
|
+
const runtime = await this.requireAgentModelRuntime();
|
|
2585
2697
|
if (command.args.length === 0) {
|
|
2586
2698
|
await this.refreshContext();
|
|
2587
|
-
this.writeLines(this.
|
|
2699
|
+
this.writeLines(this.renderAgentModel(runtime));
|
|
2588
2700
|
return "continue";
|
|
2589
2701
|
}
|
|
2590
2702
|
if (command.args.length !== 1) {
|
|
2591
|
-
throw new ShellParseError("Usage: /model [model
|
|
2703
|
+
throw new ShellParseError("Usage: /model [<query> | <provider>/<model>]");
|
|
2592
2704
|
}
|
|
2593
|
-
|
|
2705
|
+
const target = command.args[0];
|
|
2706
|
+
const slash = target.indexOf("/");
|
|
2707
|
+
if (slash <= 0) {
|
|
2708
|
+
await this.refreshContext();
|
|
2709
|
+
this.writeLines(this.renderAgentModel(runtime, target));
|
|
2710
|
+
return "continue";
|
|
2711
|
+
}
|
|
2712
|
+
if (slash === target.length - 1) {
|
|
2594
2713
|
throw new ShellParseError(
|
|
2595
|
-
"
|
|
2714
|
+
"Usage: /model <provider>/<model>, e.g. /model anthropic/claude-sonnet-4-5"
|
|
2596
2715
|
);
|
|
2597
2716
|
}
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
cwd: this.cwd
|
|
2602
|
-
});
|
|
2717
|
+
const provider = target.slice(0, slash);
|
|
2718
|
+
const model = target.slice(slash + 1);
|
|
2719
|
+
const result2 = setAgentModel(runtime, this.env, provider, model);
|
|
2603
2720
|
await this.refreshContext();
|
|
2721
|
+
const note = result2.adjustedThinking ? " \u2014 thinking set to off for this model" : "";
|
|
2722
|
+
this.io.write(
|
|
2723
|
+
`${successMark()} Agent model: ${result2.selection.provider}/${result2.selection.model} (thinking ${result2.selection.thinking})${note}.
|
|
2724
|
+
`
|
|
2725
|
+
);
|
|
2604
2726
|
return "continue";
|
|
2605
2727
|
}
|
|
2606
2728
|
case "clear":
|
|
@@ -2740,7 +2862,8 @@ async function startInteractiveShell(options) {
|
|
|
2740
2862
|
agent: options.agent,
|
|
2741
2863
|
cwd: options.cwd,
|
|
2742
2864
|
env: options.env,
|
|
2743
|
-
version: options.version
|
|
2865
|
+
version: options.version,
|
|
2866
|
+
agentModelRuntime: options.agentModelRuntime
|
|
2744
2867
|
});
|
|
2745
2868
|
const completer = createCommandCompleter(() => session.snapshot().mode);
|
|
2746
2869
|
readline = createInterface({
|
|
@@ -8110,61 +8233,47 @@ function registerPushCommand(parent) {
|
|
|
8110
8233
|
}
|
|
8111
8234
|
|
|
8112
8235
|
// src/commands/agent.ts
|
|
8113
|
-
function selectionOrHint(env) {
|
|
8114
|
-
const selection = getAgentSelection(env);
|
|
8115
|
-
if (!selection) {
|
|
8116
|
-
throw new Error(
|
|
8117
|
-
"The local agent is not configured. Run `tt agent configure --provider <provider> --model <model>`."
|
|
8118
|
-
);
|
|
8119
|
-
}
|
|
8120
|
-
return selection;
|
|
8121
|
-
}
|
|
8122
8236
|
function registerAgentCommands(parent, options) {
|
|
8123
|
-
const agent = parent.command("agent").description("Configure the laptop-local
|
|
8237
|
+
const agent = parent.command("agent").description("Configure the laptop-local TT agent");
|
|
8124
8238
|
agent.command("status").description("Show the selected local provider, model, thinking, and auth state").action(async () => {
|
|
8125
|
-
const selection = selectionOrHint(options.env);
|
|
8126
8239
|
const runtime = await options.getRuntime();
|
|
8127
|
-
const
|
|
8128
|
-
|
|
8129
|
-
|
|
8130
|
-
|
|
8131
|
-
|
|
8240
|
+
const summary = describeAgentModel(runtime, options.env);
|
|
8241
|
+
if (!summary) {
|
|
8242
|
+
throw new Error(
|
|
8243
|
+
"The local agent is not configured. Run `tt agent configure --provider <provider> --model <model>`."
|
|
8244
|
+
);
|
|
8245
|
+
}
|
|
8132
8246
|
const value = {
|
|
8133
8247
|
execution: "local",
|
|
8134
|
-
provider:
|
|
8135
|
-
provider_name: providerName,
|
|
8136
|
-
model:
|
|
8137
|
-
model_name:
|
|
8138
|
-
thinking:
|
|
8139
|
-
authenticated,
|
|
8140
|
-
supports_thinking:
|
|
8248
|
+
provider: summary.provider,
|
|
8249
|
+
provider_name: summary.providerName,
|
|
8250
|
+
model: summary.model,
|
|
8251
|
+
model_name: summary.modelName,
|
|
8252
|
+
thinking: summary.thinking,
|
|
8253
|
+
authenticated: summary.authenticated,
|
|
8254
|
+
supports_thinking: summary.supportsThinking
|
|
8141
8255
|
};
|
|
8142
|
-
const modelLabel =
|
|
8256
|
+
const modelLabel = summary.modelName && summary.modelName !== summary.model ? `${summary.modelName} (${summary.provider}/${summary.model})` : `${summary.provider}/${summary.model}`;
|
|
8143
8257
|
options.output.write(isJsonMode() ? `${JSON.stringify(value, null, 2)}
|
|
8144
|
-
` : `Local agent: ${modelLabel} (thinking: ${value.thinking}, auth: ${authenticated ? "configured" : "required"})
|
|
8258
|
+
` : `Local agent: ${modelLabel} (thinking: ${value.thinking}, auth: ${value.authenticated ? "configured" : "required"})
|
|
8145
8259
|
`);
|
|
8146
8260
|
});
|
|
8147
|
-
agent.command("models").description("List
|
|
8261
|
+
agent.command("models").description("List provider models available to the local agent").option("--provider <provider>", "Filter by provider ID").option("--all", "Include models whose provider auth is not configured").action(async (commandOptions) => {
|
|
8148
8262
|
const runtime = await options.getRuntime();
|
|
8149
8263
|
if (commandOptions.provider && !runtime.getProviders().some((provider) => provider.id === commandOptions.provider)) {
|
|
8150
|
-
throw new Error(`Unknown
|
|
8151
|
-
}
|
|
8152
|
-
const models = runtime
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
|
|
8156
|
-
id: model.id,
|
|
8157
|
-
name: model.name ?? model.id,
|
|
8158
|
-
authenticated: runtime.hasConfiguredAuth(model.provider),
|
|
8159
|
-
thinking: model.reasoning !== false
|
|
8160
|
-
}));
|
|
8264
|
+
throw new Error(`Unknown provider "${commandOptions.provider}".`);
|
|
8265
|
+
}
|
|
8266
|
+
const models = listAgentModels(runtime, {
|
|
8267
|
+
provider: commandOptions.provider,
|
|
8268
|
+
includeUnauthenticated: commandOptions.all
|
|
8269
|
+
});
|
|
8161
8270
|
if (isJsonMode()) {
|
|
8162
8271
|
options.output.write(`${JSON.stringify({ data: models }, null, 2)}
|
|
8163
8272
|
`);
|
|
8164
8273
|
return;
|
|
8165
8274
|
}
|
|
8166
8275
|
if (models.length === 0) {
|
|
8167
|
-
options.output.write("No matching authenticated
|
|
8276
|
+
options.output.write("No matching authenticated models. Use --all to inspect the full catalog.\n");
|
|
8168
8277
|
return;
|
|
8169
8278
|
}
|
|
8170
8279
|
for (const model of models) {
|
|
@@ -8172,20 +8281,17 @@ function registerAgentCommands(parent, options) {
|
|
|
8172
8281
|
`);
|
|
8173
8282
|
}
|
|
8174
8283
|
});
|
|
8175
|
-
agent.command("configure").description("Select the local
|
|
8176
|
-
|
|
8177
|
-
|
|
8178
|
-
|
|
8179
|
-
|
|
8180
|
-
|
|
8181
|
-
|
|
8182
|
-
|
|
8183
|
-
};
|
|
8184
|
-
resolveAgentModel(await options.getRuntime(), selection);
|
|
8185
|
-
updateConfig({ agent: selection });
|
|
8186
|
-
const value = { execution: "local", ...selection };
|
|
8284
|
+
agent.command("configure").description("Select the local provider, model, and thinking level").requiredOption("--provider <provider>", "Provider ID").requiredOption("--model <model>", "Model ID").option("--thinking <level>", "off, minimal, low, medium, high, xhigh, or max", "medium").action(async (commandOptions) => {
|
|
8285
|
+
const result2 = setAgentModel(
|
|
8286
|
+
await options.getRuntime(),
|
|
8287
|
+
options.env,
|
|
8288
|
+
commandOptions.provider,
|
|
8289
|
+
commandOptions.model,
|
|
8290
|
+
{ thinking: commandOptions.thinking, adjustThinking: false }
|
|
8291
|
+
);
|
|
8292
|
+
const value = { execution: "local", ...result2.selection };
|
|
8187
8293
|
options.output.write(isJsonMode() ? `${JSON.stringify(value, null, 2)}
|
|
8188
|
-
` : `Configured local agent: ${selection.provider}/${selection.model} (thinking: ${selection.thinking}).
|
|
8294
|
+
` : `Configured local agent: ${result2.selection.provider}/${result2.selection.model} (thinking: ${result2.selection.thinking}).
|
|
8189
8295
|
`);
|
|
8190
8296
|
});
|
|
8191
8297
|
}
|
|
@@ -8355,14 +8461,14 @@ function formatCliUpdateNotice(update) {
|
|
|
8355
8461
|
}
|
|
8356
8462
|
|
|
8357
8463
|
// src/cli.ts
|
|
8358
|
-
async function createDefaultAgentClient(runtime, env, cloud, workspaceRoot) {
|
|
8464
|
+
async function createDefaultAgentClient(runtime, env, cloud, workspaceRoot, getModelRuntime) {
|
|
8359
8465
|
const selection = getAgentSelection(env);
|
|
8360
8466
|
if (!selection) {
|
|
8361
8467
|
throw new Error(
|
|
8362
8468
|
"The laptop-local agent is not configured. Run `tt agent models --all`, then `tt agent configure --provider <provider> --model <model>`."
|
|
8363
8469
|
);
|
|
8364
8470
|
}
|
|
8365
|
-
const modelRuntime =
|
|
8471
|
+
const modelRuntime = await getModelRuntime();
|
|
8366
8472
|
const clientOpts = { apiKey: cloud.apiKey, baseUrl: cloud.baseUrl };
|
|
8367
8473
|
const toolApi = runtime.agentToolApi ?? {
|
|
8368
8474
|
get: async (path, query) => await get(path, query, clientOpts),
|
|
@@ -8395,11 +8501,23 @@ async function createDefaultAgentClient(runtime, env, cloud, workspaceRoot) {
|
|
|
8395
8501
|
createAgent: runtime.createPiAgent
|
|
8396
8502
|
});
|
|
8397
8503
|
}
|
|
8398
|
-
function
|
|
8504
|
+
function createModelRuntimeGetter(runtime) {
|
|
8505
|
+
const injected = runtime.modelRuntime;
|
|
8506
|
+
let promise;
|
|
8507
|
+
return async () => {
|
|
8508
|
+
if (injected) return injected;
|
|
8509
|
+
promise ??= createPiModelRuntime();
|
|
8510
|
+
return await promise;
|
|
8511
|
+
};
|
|
8512
|
+
}
|
|
8513
|
+
function createLazyDefaultAgentClient(runtime, env, cloud, workspaceRoot, getModelRuntime) {
|
|
8399
8514
|
let pending;
|
|
8515
|
+
let builtRevision = -1;
|
|
8400
8516
|
const client = () => {
|
|
8401
|
-
|
|
8402
|
-
|
|
8517
|
+
const revision = getConfigRevision();
|
|
8518
|
+
if (!pending || builtRevision !== revision) {
|
|
8519
|
+
builtRevision = revision;
|
|
8520
|
+
const attempt = createDefaultAgentClient(runtime, env, cloud, workspaceRoot, getModelRuntime);
|
|
8403
8521
|
pending = attempt;
|
|
8404
8522
|
attempt.catch(() => {
|
|
8405
8523
|
if (pending === attempt) pending = void 0;
|
|
@@ -8499,13 +8617,7 @@ function createProgram(version, runtime = {}) {
|
|
|
8499
8617
|
const invokeLocal = runtime.runLocalCommand ?? executeLocalCommand;
|
|
8500
8618
|
const launchShell = runtime.startShell ?? startInteractiveShell;
|
|
8501
8619
|
const cwd = runtime.cwd ?? process.cwd();
|
|
8502
|
-
const
|
|
8503
|
-
let modelRuntimePromise;
|
|
8504
|
-
const getModelRuntime = async () => {
|
|
8505
|
-
if (injectedModelRuntime) return injectedModelRuntime;
|
|
8506
|
-
modelRuntimePromise ??= createPiModelRuntime();
|
|
8507
|
-
return await modelRuntimePromise;
|
|
8508
|
-
};
|
|
8620
|
+
const getModelRuntime = createModelRuntimeGetter(runtime);
|
|
8509
8621
|
const shellRunner = async (request2) => {
|
|
8510
8622
|
const root = program.opts();
|
|
8511
8623
|
const args2 = request2.target === "local" ? ["local", ...request2.args] : request2.args;
|
|
@@ -8524,7 +8636,7 @@ function createProgram(version, runtime = {}) {
|
|
|
8524
8636
|
client: runtime.agentClient ?? createLazyDefaultAgentClient(runtime, shellEnvironment, {
|
|
8525
8637
|
apiKey: root.apiKey ?? shellEnvironment.TUNED_TENSOR_API_KEY,
|
|
8526
8638
|
baseUrl: root.baseUrl ?? shellEnvironment.TUNED_TENSOR_URL
|
|
8527
|
-
}, cwd),
|
|
8639
|
+
}, cwd, getModelRuntime),
|
|
8528
8640
|
output,
|
|
8529
8641
|
error
|
|
8530
8642
|
});
|
|
@@ -8536,7 +8648,8 @@ function createProgram(version, runtime = {}) {
|
|
|
8536
8648
|
error,
|
|
8537
8649
|
cwd,
|
|
8538
8650
|
env: shellEnvironment,
|
|
8539
|
-
version
|
|
8651
|
+
version,
|
|
8652
|
+
agentModelRuntime: getModelRuntime
|
|
8540
8653
|
});
|
|
8541
8654
|
};
|
|
8542
8655
|
program.name("tt").description("Tuned Tensor \u2014 converse, train, and inspect from one terminal").version(version).option("-k, --api-key <key>", "API key (overrides stored key)").option(
|
|
@@ -8640,7 +8753,7 @@ function createProgram(version, runtime = {}) {
|
|
|
8640
8753
|
});
|
|
8641
8754
|
applyExitCode(result2);
|
|
8642
8755
|
});
|
|
8643
|
-
program.command("shell").description("Open the
|
|
8756
|
+
program.command("shell").description("Open the conversational terminal (local by default)").action(openShell);
|
|
8644
8757
|
program.addHelpText(
|
|
8645
8758
|
"after",
|
|
8646
8759
|
`
|
|
@@ -8697,11 +8810,12 @@ async function runCli(version, runtime = {}) {
|
|
|
8697
8810
|
`);
|
|
8698
8811
|
}
|
|
8699
8812
|
const invokeSelf = runtime.runSelfCommand ?? runSelfCommand;
|
|
8813
|
+
const getModelRuntime = createModelRuntimeGetter(runtime);
|
|
8700
8814
|
const agent = createShellAgent({
|
|
8701
8815
|
client: runtime.agentClient ?? createLazyDefaultAgentClient(runtime, env, {
|
|
8702
8816
|
apiKey: env.TUNED_TENSOR_API_KEY,
|
|
8703
8817
|
baseUrl: env.TUNED_TENSOR_URL
|
|
8704
|
-
}, runtime.cwd ?? process.cwd()),
|
|
8818
|
+
}, runtime.cwd ?? process.cwd(), getModelRuntime),
|
|
8705
8819
|
output,
|
|
8706
8820
|
error
|
|
8707
8821
|
});
|
|
@@ -8720,7 +8834,8 @@ async function runCli(version, runtime = {}) {
|
|
|
8720
8834
|
error,
|
|
8721
8835
|
cwd: runtime.cwd ?? process.cwd(),
|
|
8722
8836
|
env,
|
|
8723
|
-
version
|
|
8837
|
+
version,
|
|
8838
|
+
agentModelRuntime: getModelRuntime
|
|
8724
8839
|
});
|
|
8725
8840
|
return;
|
|
8726
8841
|
}
|
|
@@ -8729,7 +8844,7 @@ async function runCli(version, runtime = {}) {
|
|
|
8729
8844
|
}
|
|
8730
8845
|
|
|
8731
8846
|
// src/index.ts
|
|
8732
|
-
runCli("0.12.0-beta.
|
|
8847
|
+
runCli("0.12.0-beta.1").catch((err) => {
|
|
8733
8848
|
reportError(err);
|
|
8734
8849
|
process.exit(1);
|
|
8735
8850
|
});
|