thinyai 0.1.8 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +146 -15
- package/package.json +6 -6
package/dist/bin.js
CHANGED
|
@@ -1829,11 +1829,14 @@ function applyConfig(cfg) {
|
|
|
1829
1829
|
const set = (k, v) => {
|
|
1830
1830
|
if (v && !process.env[k]) process.env[k] = v;
|
|
1831
1831
|
};
|
|
1832
|
-
|
|
1833
|
-
if (
|
|
1834
|
-
set(
|
|
1832
|
+
const prov = activeProvider(cfg);
|
|
1833
|
+
if (prov) {
|
|
1834
|
+
set("THINY_MODEL", prov.model);
|
|
1835
|
+
if (prov.apiKey) {
|
|
1836
|
+
set(prov.model.startsWith("anthropic") ? "THINY_ANTHROPIC_API_KEY" : "THINY_OPENAI_API_KEY", prov.apiKey);
|
|
1837
|
+
}
|
|
1838
|
+
set("THINY_OPENAI_BASE_URL", prov.baseUrl);
|
|
1835
1839
|
}
|
|
1836
|
-
set("THINY_OPENAI_BASE_URL", cfg.baseUrl);
|
|
1837
1840
|
set("THINY_PERSONA_NAME", cfg.agentName);
|
|
1838
1841
|
set("THINY_USER_ID", cfg.userId);
|
|
1839
1842
|
if (cfg.sui?.network) {
|
|
@@ -1872,6 +1875,37 @@ function saveSuiWallet(cfg, network, wallet, makeActive) {
|
|
|
1872
1875
|
if (makeActive || !cfg.sui.activeAddress) cfg.sui.activeAddress = wallet.address;
|
|
1873
1876
|
saveConfig(cfg);
|
|
1874
1877
|
}
|
|
1878
|
+
function providersOf(cfg) {
|
|
1879
|
+
if (!cfg) return [];
|
|
1880
|
+
if (cfg.providers && cfg.providers.length > 0) return cfg.providers;
|
|
1881
|
+
if (cfg.model) {
|
|
1882
|
+
const id = cfg.model.startsWith("anthropic") ? "anthropic" : cfg.baseUrl ? "custom" : "openai";
|
|
1883
|
+
return [{ id, label: cfg.model, model: cfg.model, apiKey: cfg.apiKey, baseUrl: cfg.baseUrl }];
|
|
1884
|
+
}
|
|
1885
|
+
return [];
|
|
1886
|
+
}
|
|
1887
|
+
function activeProvider(cfg) {
|
|
1888
|
+
const all = providersOf(cfg);
|
|
1889
|
+
return all.find((x) => x.id === cfg?.activeProviderId) ?? all[0];
|
|
1890
|
+
}
|
|
1891
|
+
function saveProvider(cfg, provider, makeActive) {
|
|
1892
|
+
const all = providersOf(cfg).filter((x) => x.id !== provider.id);
|
|
1893
|
+
all.push(provider);
|
|
1894
|
+
cfg.providers = all;
|
|
1895
|
+
delete cfg.model;
|
|
1896
|
+
delete cfg.apiKey;
|
|
1897
|
+
delete cfg.baseUrl;
|
|
1898
|
+
if (makeActive || !cfg.activeProviderId) cfg.activeProviderId = provider.id;
|
|
1899
|
+
saveConfig(cfg);
|
|
1900
|
+
}
|
|
1901
|
+
function setActiveProvider(cfg, id) {
|
|
1902
|
+
const prov = providersOf(cfg).find((x) => x.id === id);
|
|
1903
|
+
if (!prov) return void 0;
|
|
1904
|
+
cfg.providers = providersOf(cfg);
|
|
1905
|
+
cfg.activeProviderId = id;
|
|
1906
|
+
saveConfig(cfg);
|
|
1907
|
+
return prov;
|
|
1908
|
+
}
|
|
1875
1909
|
function bail(v) {
|
|
1876
1910
|
if (p.isCancel(v)) {
|
|
1877
1911
|
p.cancel("Cancelled.");
|
|
@@ -1897,25 +1931,28 @@ async function baseSetup() {
|
|
|
1897
1931
|
);
|
|
1898
1932
|
const pick = MODELS.find((m) => m.value === choice);
|
|
1899
1933
|
if (!pick) throw new Error(`unknown model choice: ${choice}`);
|
|
1900
|
-
const cfg =
|
|
1934
|
+
const cfg = loadConfig() ?? {};
|
|
1935
|
+
cfg.agentName = agentName;
|
|
1936
|
+
cfg.userId ??= "default";
|
|
1937
|
+
let provider;
|
|
1901
1938
|
if (pick.custom) {
|
|
1902
|
-
|
|
1939
|
+
const model = bail(
|
|
1903
1940
|
await p.text({ message: "Model id", placeholder: "e.g. MiniMax-M3", validate: (v) => v ? void 0 : "Required" })
|
|
1904
1941
|
);
|
|
1905
|
-
|
|
1942
|
+
const baseUrl = bail(
|
|
1906
1943
|
await p.text({
|
|
1907
1944
|
message: "Base URL (OpenAI-compatible)",
|
|
1908
1945
|
placeholder: "https://api.example.com/v1",
|
|
1909
1946
|
validate: (v) => v && /^https?:\/\//.test(v) ? void 0 : "Must start with http(s)://"
|
|
1910
1947
|
})
|
|
1911
1948
|
);
|
|
1912
|
-
|
|
1949
|
+
const apiKey = bail(await p.password({ message: "API key" }));
|
|
1950
|
+
provider = { id: model, label: model, model, baseUrl, apiKey };
|
|
1913
1951
|
} else {
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
cfg.apiKey = pick.apiKey ?? (pick.needsKey ? bail(await p.password({ message: "API key" })) : void 0);
|
|
1952
|
+
const apiKey = pick.apiKey ?? (pick.needsKey ? bail(await p.password({ message: "API key" })) : void 0);
|
|
1953
|
+
provider = { id: pick.value, label: pick.label, model: pick.model ?? "", baseUrl: pick.baseUrl, apiKey };
|
|
1917
1954
|
}
|
|
1918
|
-
|
|
1955
|
+
saveProvider(cfg, provider, true);
|
|
1919
1956
|
p.outro(`Saved ${CONFIG} \u2014 run \`thiny\` to start, or \`thiny sui init\` for Sui.`);
|
|
1920
1957
|
return cfg;
|
|
1921
1958
|
}
|
|
@@ -2352,9 +2389,22 @@ async function runCli() {
|
|
|
2352
2389
|
const turn = { inputTokens: 0, outputTokens: 0, toolCalls: 0, modelCalls: 0 };
|
|
2353
2390
|
const session = { inputTokens: 0, outputTokens: 0, toolCalls: 0, turns: 0 };
|
|
2354
2391
|
const logger = captureStats(fileLogger, turn);
|
|
2355
|
-
const activeModelName = process.env.THINY_MODEL ?? process.env.AGENT_MODEL ?? "openai:gpt-4o-mini";
|
|
2356
2392
|
const personaName = process.env.THINY_PERSONA_NAME ?? "Thiny";
|
|
2357
|
-
const
|
|
2393
|
+
const buildModel = (p2) => aiSdkModel({
|
|
2394
|
+
model: p2.model,
|
|
2395
|
+
openai: { baseURL: p2.baseUrl, apiKey: p2.apiKey },
|
|
2396
|
+
anthropic: { apiKey: p2.apiKey }
|
|
2397
|
+
});
|
|
2398
|
+
const startProvider = activeProvider(loadConfig());
|
|
2399
|
+
let activeModel = startProvider ? buildModel(startProvider) : loadThinyConfig();
|
|
2400
|
+
let activeModelName = startProvider?.model ?? process.env.THINY_MODEL ?? process.env.AGENT_MODEL ?? "openai:gpt-4o-mini";
|
|
2401
|
+
const model = {
|
|
2402
|
+
generate: (m, t, s) => activeModel.generate(m, t, s),
|
|
2403
|
+
stream: (m, t, s) => {
|
|
2404
|
+
if (!activeModel.stream) throw new Error("active model has no streaming");
|
|
2405
|
+
return activeModel.stream(m, t, s);
|
|
2406
|
+
}
|
|
2407
|
+
};
|
|
2358
2408
|
const network = process.env.WALRUS_NETWORK === "mainnet" ? "mainnet" : "testnet";
|
|
2359
2409
|
const walrus = walrusClient({
|
|
2360
2410
|
network,
|
|
@@ -2725,6 +2775,76 @@ YOUR TOOLS:
|
|
|
2725
2775
|
});
|
|
2726
2776
|
} else memoryRefs.push(ref);
|
|
2727
2777
|
};
|
|
2778
|
+
const handleConnect = async (arg) => {
|
|
2779
|
+
const cfg = loadConfig() ?? {};
|
|
2780
|
+
const provs = providersOf(cfg);
|
|
2781
|
+
if (provs.length === 0) {
|
|
2782
|
+
renderInfo("No providers configured \u2014 run `thiny init` to add one.");
|
|
2783
|
+
return;
|
|
2784
|
+
}
|
|
2785
|
+
let id = arg;
|
|
2786
|
+
if (!id) {
|
|
2787
|
+
renderInfo("\nProviders:");
|
|
2788
|
+
provs.forEach((pr, i) => {
|
|
2789
|
+
renderInfo(
|
|
2790
|
+
` ${String(i + 1)}. ${pr.label} (${pr.model})${pr.id === cfg.activeProviderId ? " \xB7 active" : ""}`
|
|
2791
|
+
);
|
|
2792
|
+
});
|
|
2793
|
+
const ans = (await rl.question("Switch to (number, blank to cancel): ")).trim();
|
|
2794
|
+
if (!ans) return;
|
|
2795
|
+
const idx = Number(ans) - 1;
|
|
2796
|
+
const chosen = provs[idx];
|
|
2797
|
+
if (!chosen) {
|
|
2798
|
+
renderWarning("Invalid choice.");
|
|
2799
|
+
return;
|
|
2800
|
+
}
|
|
2801
|
+
id = chosen.id;
|
|
2802
|
+
}
|
|
2803
|
+
const match = provs.find((pr) => pr.id === id || pr.label === id || pr.model === id);
|
|
2804
|
+
const prov = match ? setActiveProvider(cfg, match.id) : void 0;
|
|
2805
|
+
if (!prov) {
|
|
2806
|
+
renderWarning(`No provider "${id}".`);
|
|
2807
|
+
return;
|
|
2808
|
+
}
|
|
2809
|
+
activeModel = buildModel(prov);
|
|
2810
|
+
activeModelName = prov.model;
|
|
2811
|
+
renderInfo(`Connected: ${prov.label} \xB7 ${prov.model}`);
|
|
2812
|
+
};
|
|
2813
|
+
const handleModels = async (arg) => {
|
|
2814
|
+
const cfg = loadConfig() ?? {};
|
|
2815
|
+
const prov = activeProvider(cfg);
|
|
2816
|
+
if (!prov) {
|
|
2817
|
+
renderInfo("No provider configured \u2014 run `thiny init`.");
|
|
2818
|
+
return;
|
|
2819
|
+
}
|
|
2820
|
+
let modelId = arg;
|
|
2821
|
+
if (!modelId) {
|
|
2822
|
+
renderInfo(`
|
|
2823
|
+
Active: ${prov.label} \xB7 current model: ${prov.model}`);
|
|
2824
|
+
renderInfo("Configured providers:");
|
|
2825
|
+
providersOf(cfg).forEach((pr) => {
|
|
2826
|
+
renderInfo(` \u2022 ${pr.label}: ${pr.model}`);
|
|
2827
|
+
});
|
|
2828
|
+
modelId = (await rl.question("New model id for the active provider (blank to cancel): ")).trim();
|
|
2829
|
+
if (!modelId) return;
|
|
2830
|
+
}
|
|
2831
|
+
prov.model = modelId;
|
|
2832
|
+
saveProvider(cfg, prov, true);
|
|
2833
|
+
activeModel = buildModel(prov);
|
|
2834
|
+
activeModelName = modelId;
|
|
2835
|
+
renderInfo(`Model set: ${modelId}`);
|
|
2836
|
+
};
|
|
2837
|
+
const showSlashMenu = () => {
|
|
2838
|
+
renderInfo(
|
|
2839
|
+
"\nCommands: /new \xB7 /connect \xB7 /models \xB7 /tools \xB7 /skills \xB7 /session \xB7 /stats \xB7 /verify <blobId> \xB7 /clear \xB7 /help"
|
|
2840
|
+
);
|
|
2841
|
+
renderInfo(`Tools: ${agent.registry.all().map((t) => t.name).join(", ")}`);
|
|
2842
|
+
const cats = [...defaultRegistry.byCategory()].map(
|
|
2843
|
+
([cat, defs]) => `${cat}(${defs.map((d) => d.id).join(",")})`
|
|
2844
|
+
);
|
|
2845
|
+
renderInfo(`Skills: ${cats.join(" ")}
|
|
2846
|
+
`);
|
|
2847
|
+
};
|
|
2728
2848
|
try {
|
|
2729
2849
|
for (; ; ) {
|
|
2730
2850
|
for (const ref of memoryRefs.splice(0))
|
|
@@ -2738,7 +2858,18 @@ YOUR TOOLS:
|
|
|
2738
2858
|
if (trimmed.startsWith("/")) {
|
|
2739
2859
|
const parts = trimmed.slice(1).split(" ");
|
|
2740
2860
|
const cmd = parts[0];
|
|
2861
|
+
const arg = parts.slice(1).join(" ").trim() || void 0;
|
|
2741
2862
|
switch (cmd) {
|
|
2863
|
+
case "":
|
|
2864
|
+
showSlashMenu();
|
|
2865
|
+
break;
|
|
2866
|
+
case "connect":
|
|
2867
|
+
await handleConnect(arg);
|
|
2868
|
+
break;
|
|
2869
|
+
case "models":
|
|
2870
|
+
case "model":
|
|
2871
|
+
await handleModels(arg);
|
|
2872
|
+
break;
|
|
2742
2873
|
case "new": {
|
|
2743
2874
|
currentSessionId = `cli-${(/* @__PURE__ */ new Date()).getTime().toString()}`;
|
|
2744
2875
|
renderInfo("New session started \u2014 long-term memory carries over");
|
|
@@ -2809,7 +2940,7 @@ Audit trail ${blobId}
|
|
|
2809
2940
|
break;
|
|
2810
2941
|
case "help":
|
|
2811
2942
|
renderInfo(
|
|
2812
|
-
"\n/new \xB7 /tools \xB7 /skills \xB7 /stats \xB7 /session \xB7 /verify <blobId> \xB7 /clear \xB7 /help\n"
|
|
2943
|
+
"\n/new \xB7 /connect \xB7 /models \xB7 /tools \xB7 /skills \xB7 /stats \xB7 /session \xB7 /verify <blobId> \xB7 /clear \xB7 /help\n(type just `/` to see commands + all tools + skills)\n"
|
|
2813
2944
|
);
|
|
2814
2945
|
break;
|
|
2815
2946
|
default:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thinyai",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Thiny AI — a beautiful terminal agent: interactive chat, tools, Walrus memory, and Sui execution.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,17 +37,17 @@
|
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"tsup": "^8.5.1",
|
|
39
39
|
"typescript": "^5.5.0",
|
|
40
|
-
"@thiny/memory-memwal": "0.1.0",
|
|
41
40
|
"@thiny/core": "0.1.0",
|
|
42
|
-
"@thiny/mcp": "0.1.0",
|
|
43
|
-
"@thiny/logger-pino": "0.1.0",
|
|
44
41
|
"@thiny/model-aisdk": "0.1.0",
|
|
42
|
+
"@thiny/logger-pino": "0.1.0",
|
|
43
|
+
"@thiny/mcp": "0.1.0",
|
|
44
|
+
"@thiny/walrus": "0.1.0",
|
|
45
45
|
"@thiny/plugin-agents": "0.1.0",
|
|
46
46
|
"@thiny/plugin-web-search": "0.1.0",
|
|
47
|
-
"@thiny/walrus": "0.1.0",
|
|
48
47
|
"@thiny/signer-sui": "0.1.0",
|
|
48
|
+
"@thiny/plugin-sui": "0.1.0",
|
|
49
49
|
"@thiny/skills": "0.1.0",
|
|
50
|
-
"@thiny/
|
|
50
|
+
"@thiny/memory-memwal": "0.1.0"
|
|
51
51
|
},
|
|
52
52
|
"author": "Thiny AI",
|
|
53
53
|
"engines": {
|