@tuned-tensor/cli 0.13.1-beta.0 → 0.13.1-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 +2 -2
- package/dist/index.js +35 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -84,7 +84,7 @@ such as `runs list` and `doctor` work immediately. Chat waits until you choose
|
|
|
84
84
|
a provider and model from inside the shell:
|
|
85
85
|
|
|
86
86
|
```text
|
|
87
|
-
tt v0.13.1-beta.
|
|
87
|
+
tt v0.13.1-beta.1
|
|
88
88
|
agent not configured · workflow model base
|
|
89
89
|
ctrl+c stop/clear · ctrl+d exit · /help commands · tab complete
|
|
90
90
|
|
|
@@ -113,7 +113,7 @@ After a model is selected, the banner shows it and ordinary sentences go to
|
|
|
113
113
|
the agent:
|
|
114
114
|
|
|
115
115
|
```text
|
|
116
|
-
tt v0.13.1-beta.
|
|
116
|
+
tt v0.13.1-beta.1
|
|
117
117
|
agent anthropic/claude-sonnet-4-5 · workflow model base
|
|
118
118
|
ctrl+c stop/clear · ctrl+d exit · /help commands · tab complete
|
|
119
119
|
|
package/dist/index.js
CHANGED
|
@@ -660,8 +660,8 @@ function getAgentSelection(env = process.env) {
|
|
|
660
660
|
}
|
|
661
661
|
|
|
662
662
|
// src/agent-model.ts
|
|
663
|
-
function missingProviderAuthMessage(
|
|
664
|
-
return
|
|
663
|
+
function missingProviderAuthMessage() {
|
|
664
|
+
return "No API key is saved for the selected model. Run /login, or /model to pick a different one.";
|
|
665
665
|
}
|
|
666
666
|
function unknownAgentProviderMessage(provider) {
|
|
667
667
|
return `Unknown provider "${provider}". Use /login <id> or /model <id>.`;
|
|
@@ -676,6 +676,29 @@ function pushSecret(secrets, value) {
|
|
|
676
676
|
if (secret.length < MIN_REDACTED_SECRET_LENGTH) return;
|
|
677
677
|
if (!secrets.includes(secret)) secrets.push(secret);
|
|
678
678
|
}
|
|
679
|
+
function persistProviderApiKey(provider, apiKey, authPath = getAgentAuthPath()) {
|
|
680
|
+
const key = apiKey.trim();
|
|
681
|
+
if (!key) {
|
|
682
|
+
throw new Error("API key cannot be empty.");
|
|
683
|
+
}
|
|
684
|
+
let stored = {};
|
|
685
|
+
if (existsSync2(authPath)) {
|
|
686
|
+
let parsed;
|
|
687
|
+
try {
|
|
688
|
+
parsed = JSON.parse(readFileSync2(authPath, "utf-8"));
|
|
689
|
+
} catch (error) {
|
|
690
|
+
throw new Error(
|
|
691
|
+
`Failed to read ${authPath}: ${error instanceof Error ? error.message : String(error)}`
|
|
692
|
+
);
|
|
693
|
+
}
|
|
694
|
+
if (!isRecord(parsed)) {
|
|
695
|
+
throw new Error(`Invalid auth.json: expected an object at ${authPath}`);
|
|
696
|
+
}
|
|
697
|
+
stored = parsed;
|
|
698
|
+
}
|
|
699
|
+
stored[provider] = { type: "api_key", key };
|
|
700
|
+
writePrivateJson(authPath, stored);
|
|
701
|
+
}
|
|
679
702
|
function readStoredProviderSecrets(authPath = getAgentAuthPath()) {
|
|
680
703
|
if (!existsSync2(authPath)) return [];
|
|
681
704
|
let parsed;
|
|
@@ -700,7 +723,7 @@ function readStoredProviderSecrets(authPath = getAgentAuthPath()) {
|
|
|
700
723
|
function resolveAgentModel(runtime, selection) {
|
|
701
724
|
const resolved = resolveAgentModelDefinition(runtime, selection);
|
|
702
725
|
if (!runtime.hasConfiguredAuth(selection.provider)) {
|
|
703
|
-
throw new Error(missingProviderAuthMessage(
|
|
726
|
+
throw new Error(missingProviderAuthMessage());
|
|
704
727
|
}
|
|
705
728
|
return resolved;
|
|
706
729
|
}
|
|
@@ -1970,7 +1993,6 @@ function formatShellStatus(context) {
|
|
|
1970
1993
|
}
|
|
1971
1994
|
|
|
1972
1995
|
// src/agent-control.ts
|
|
1973
|
-
import { chmodSync as chmodSync3, existsSync as existsSync3 } from "fs";
|
|
1974
1996
|
var FEATURED_AGENT_PROVIDERS = [
|
|
1975
1997
|
"openai",
|
|
1976
1998
|
"openrouter"
|
|
@@ -2089,12 +2111,10 @@ async function loginAgentProvider(runtime, provider, apiKey) {
|
|
|
2089
2111
|
if (!key) {
|
|
2090
2112
|
throw new Error("API key cannot be empty.");
|
|
2091
2113
|
}
|
|
2092
|
-
|
|
2093
|
-
|
|
2114
|
+
persistProviderApiKey(choice.id, key);
|
|
2115
|
+
if (typeof runtime.setRuntimeApiKey === "function") {
|
|
2116
|
+
await runtime.setRuntimeApiKey(choice.id, key);
|
|
2094
2117
|
}
|
|
2095
|
-
await runtime.setRuntimeApiKey(choice.id, key);
|
|
2096
|
-
const authPath = getAgentAuthPath();
|
|
2097
|
-
if (existsSync3(authPath)) chmodSync3(authPath, 384);
|
|
2098
2118
|
return { provider: choice.id };
|
|
2099
2119
|
}
|
|
2100
2120
|
function setAgentModel(runtime, env, provider, model, options = {}) {
|
|
@@ -3568,7 +3588,7 @@ ${chalk3.yellow.bold("Approval required")} ${chalk3.dim(action.id.slice(0, 8))}
|
|
|
3568
3588
|
import { constants as osConstants } from "os";
|
|
3569
3589
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
3570
3590
|
import { spawn } from "child_process";
|
|
3571
|
-
import { existsSync as
|
|
3591
|
+
import { existsSync as existsSync3 } from "fs";
|
|
3572
3592
|
import { fileURLToPath } from "url";
|
|
3573
3593
|
import {
|
|
3574
3594
|
readFile as readFile3,
|
|
@@ -4388,7 +4408,7 @@ async function projectSpecArguments(originalArgs, cwd) {
|
|
|
4388
4408
|
}
|
|
4389
4409
|
function resolveLocalCliEntrypoint() {
|
|
4390
4410
|
const entrypoint = fileURLToPath(new URL("./local-runtime.js", import.meta.url));
|
|
4391
|
-
if (!
|
|
4411
|
+
if (!existsSync3(entrypoint)) {
|
|
4392
4412
|
throw new Error(
|
|
4393
4413
|
"The bundled local runtime is missing. Rebuild or reinstall @tuned-tensor/cli."
|
|
4394
4414
|
);
|
|
@@ -4718,7 +4738,7 @@ function registerAgentCommands(parent, options) {
|
|
|
4718
4738
|
}
|
|
4719
4739
|
|
|
4720
4740
|
// src/commands/pipeline.ts
|
|
4721
|
-
import { existsSync as
|
|
4741
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
4722
4742
|
import { resolve as resolve4 } from "path";
|
|
4723
4743
|
var DEFAULT_PIPELINE_FILE = "tunedtensor.pipeline.json";
|
|
4724
4744
|
function parseList(value) {
|
|
@@ -4729,7 +4749,7 @@ function parseList(value) {
|
|
|
4729
4749
|
}
|
|
4730
4750
|
function loadPipeline(path) {
|
|
4731
4751
|
const resolved = resolve4(path);
|
|
4732
|
-
if (!
|
|
4752
|
+
if (!existsSync4(resolved)) throw new Error(`Pipeline file not found: ${path}. Run \`tt pipeline init\` to create one.`);
|
|
4733
4753
|
try {
|
|
4734
4754
|
return JSON.parse(readFileSync4(resolved, "utf8"));
|
|
4735
4755
|
} catch (error) {
|
|
@@ -4748,7 +4768,7 @@ function registerPipelineCommands(parent) {
|
|
|
4748
4768
|
const pipeline = parent.command("pipeline").description("Create, validate, inspect, and safely dry-run ordered pipeline recipes");
|
|
4749
4769
|
pipeline.command("init").description("Write a canonical v1 pipeline recipe").option("-f, --file <path>", "Output file", DEFAULT_PIPELINE_FILE).action((options) => {
|
|
4750
4770
|
const path = resolve4(options.file);
|
|
4751
|
-
if (
|
|
4771
|
+
if (existsSync4(path)) throw new Error(`Pipeline file already exists: ${options.file}.`);
|
|
4752
4772
|
const recipe = canonicalPipeline("local");
|
|
4753
4773
|
writeFileSync3(path, `${JSON.stringify(recipe, null, 2)}
|
|
4754
4774
|
`);
|
|
@@ -5186,7 +5206,7 @@ async function runCli(version, runtime = {}) {
|
|
|
5186
5206
|
}
|
|
5187
5207
|
|
|
5188
5208
|
// src/index.ts
|
|
5189
|
-
runCli("0.13.1-beta.
|
|
5209
|
+
runCli("0.13.1-beta.1").catch((err) => {
|
|
5190
5210
|
reportError(err);
|
|
5191
5211
|
process.exit(1);
|
|
5192
5212
|
});
|