traderclaw-cli 1.0.65 → 1.0.66
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/bin/installer-step-engine.mjs +20 -9
- package/bin/openclaw-trader.mjs +68 -234
- package/package.json +2 -2
|
@@ -308,17 +308,25 @@ function privilegeRemediationMessage(cmd, args = [], customLines = []) {
|
|
|
308
308
|
|
|
309
309
|
function gatewayTimeoutRemediation() {
|
|
310
310
|
return [
|
|
311
|
-
"Gateway
|
|
312
|
-
"
|
|
313
|
-
"
|
|
314
|
-
"
|
|
311
|
+
"Gateway failed to start: service stayed stopped and health checks did not pass.",
|
|
312
|
+
"This usually means the gateway service is misconfigured, crashed at launch, or the system is out of resources.",
|
|
313
|
+
"",
|
|
314
|
+
"Run these commands in your VPS terminal to diagnose and recover:",
|
|
315
|
+
"1) openclaw gateway status --json || true # check current state",
|
|
316
|
+
"2) journalctl --user -u openclaw-gateway -n 50 --no-pager || true # check service logs",
|
|
315
317
|
"3) openclaw gateway stop || true",
|
|
316
318
|
"4) openclaw gateway install",
|
|
317
319
|
"5) openclaw gateway restart",
|
|
318
|
-
"6) openclaw gateway status --json",
|
|
320
|
+
"6) openclaw gateway status --json # should show running + rpc.ok=true",
|
|
319
321
|
"7) tailscale funnel --bg 18789",
|
|
320
322
|
"8) tailscale funnel status",
|
|
321
|
-
"
|
|
323
|
+
"",
|
|
324
|
+
"If the gateway still fails:",
|
|
325
|
+
"- Check RAM: openclaw gateway requires >=512MB free (>=2GB total recommended)",
|
|
326
|
+
"- Check disk: df -h ~/.openclaw",
|
|
327
|
+
"- Try: openclaw config validate && openclaw gateway doctor || true",
|
|
328
|
+
"- If config schema error appears, run: npm install -g openclaw@latest",
|
|
329
|
+
"Once the gateway shows 'running' in status, click Start Installation again.",
|
|
322
330
|
].join("\n");
|
|
323
331
|
}
|
|
324
332
|
|
|
@@ -1875,12 +1883,15 @@ export class InstallerStepEngine {
|
|
|
1875
1883
|
} catch (err) {
|
|
1876
1884
|
const text = `${err?.message || ""}\n${err?.stderr || ""}\n${err?.stdout || ""}`.toLowerCase();
|
|
1877
1885
|
const gatewayModeUnset = text.includes("gateway.mode=local") && text.includes("current: unset");
|
|
1878
|
-
|
|
1886
|
+
const gatewayStartFailed =
|
|
1879
1887
|
text.includes("gateway restart timed out")
|
|
1880
1888
|
|| text.includes("timed out after 60s waiting for health checks")
|
|
1881
1889
|
|| text.includes("waiting for gateway port")
|
|
1882
|
-
|
|
1883
|
-
|
|
1890
|
+
// OpenClaw ≥ current: shorter-timeout variant of the same class of failure
|
|
1891
|
+
|| (text.includes("gateway restart failed") && text.includes("service stayed stopped"))
|
|
1892
|
+
|| text.includes("health checks never came up")
|
|
1893
|
+
|| text.includes("service stayed stopped");
|
|
1894
|
+
if (gatewayStartFailed || gatewayModeUnset) {
|
|
1884
1895
|
const recovered = await this.tryAutoRecoverGatewayMode("gateway_bootstrap");
|
|
1885
1896
|
if (recovered.success) {
|
|
1886
1897
|
return this.runFunnel();
|
package/bin/openclaw-trader.mjs
CHANGED
|
@@ -9,27 +9,23 @@ import { randomUUID, createPrivateKey, sign as cryptoSign } from "crypto";
|
|
|
9
9
|
import { execFile, execSync } from "child_process";
|
|
10
10
|
import { promisify } from "util";
|
|
11
11
|
import { createServer } from "http";
|
|
12
|
-
import { sortModelsByPreference, MAX_MODELS_PER_PROVIDER_SORT } from "./llm-model-preference.mjs";
|
|
13
12
|
import { resolvePluginPackageRoot } from "./resolve-plugin-root.mjs";
|
|
14
13
|
|
|
15
14
|
const execFileAsync = promisify(execFile);
|
|
16
15
|
|
|
17
16
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* (no credentials yet) so we want to fail fast and show the curated fallback list
|
|
21
|
-
* rather than making the user wait 10+ seconds. Target total: ≤ 5 s.
|
|
17
|
+
* Ordered list of providers for display in the wizard dropdown.
|
|
18
|
+
* The most commonly used providers appear first.
|
|
22
19
|
*/
|
|
23
|
-
const
|
|
24
|
-
const OPENCLAW_MODELS_PER_PROVIDER_TIMEOUT_MS = 2_500;
|
|
25
|
-
const WIZARD_PRIORITY_PROVIDERS = [
|
|
20
|
+
const WIZARD_PROVIDER_PRIORITY = [
|
|
26
21
|
"anthropic",
|
|
27
22
|
"openai",
|
|
28
23
|
"google",
|
|
29
24
|
"openrouter",
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
"xai",
|
|
26
|
+
"deepseek",
|
|
27
|
+
"groq",
|
|
28
|
+
"mistral",
|
|
33
29
|
"perplexity",
|
|
34
30
|
"together",
|
|
35
31
|
"openai-codex",
|
|
@@ -44,14 +40,6 @@ const WIZARD_PROVIDER_PRIORITY = [
|
|
|
44
40
|
];
|
|
45
41
|
let wizardLlmCatalogPromise = null;
|
|
46
42
|
|
|
47
|
-
function compareWizardProviderPriority(a, b) {
|
|
48
|
-
const ai = WIZARD_PROVIDER_PRIORITY.indexOf(a);
|
|
49
|
-
const bi = WIZARD_PROVIDER_PRIORITY.indexOf(b);
|
|
50
|
-
const aRank = ai >= 0 ? ai : Number.MAX_SAFE_INTEGER;
|
|
51
|
-
const bRank = bi >= 0 ? bi : Number.MAX_SAFE_INTEGER;
|
|
52
|
-
return aRank - bRank || a.localeCompare(b);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
43
|
const PLUGIN_ROOT = resolvePluginPackageRoot(import.meta.url);
|
|
56
44
|
const PLUGIN_PACKAGE_JSON = JSON.parse(readFileSync(join(PLUGIN_ROOT, "package.json"), "utf-8"));
|
|
57
45
|
const PLUGIN_VERSION =
|
|
@@ -1917,35 +1905,29 @@ function parseJsonBody(req) {
|
|
|
1917
1905
|
});
|
|
1918
1906
|
}
|
|
1919
1907
|
|
|
1908
|
+
/**
|
|
1909
|
+
* Returns the wizard LLM catalog immediately from the curated static list.
|
|
1910
|
+
*
|
|
1911
|
+
* WHY we no longer call `openclaw models list --all`:
|
|
1912
|
+
* The OpenClaw CLI enumerates models by making live network calls to each
|
|
1913
|
+
* provider's API (provider plugins inject catalogs via network). The wizard
|
|
1914
|
+
* runs BEFORE any API credentials have been configured, so every probe will
|
|
1915
|
+
* always ETIMEDOUT — there is nothing to authenticate with yet. Calling the
|
|
1916
|
+
* CLI here is architecturally wrong for this stage of setup.
|
|
1917
|
+
*
|
|
1918
|
+
* The curated list below is the correct source for the wizard: it covers all
|
|
1919
|
+
* supported providers with their recommended models and loads in < 1 ms.
|
|
1920
|
+
* After installation the user can run `openclaw models list` to see the full
|
|
1921
|
+
* live catalog for their configured providers.
|
|
1922
|
+
*/
|
|
1920
1923
|
async function loadWizardLlmCatalogAsync() {
|
|
1921
|
-
|
|
1922
|
-
"
|
|
1923
|
-
"openai",
|
|
1924
|
-
"openai-codex",
|
|
1925
|
-
"openrouter",
|
|
1926
|
-
"groq",
|
|
1927
|
-
"mistral",
|
|
1928
|
-
"google",
|
|
1929
|
-
"google-vertex",
|
|
1930
|
-
"xai",
|
|
1931
|
-
"deepseek",
|
|
1932
|
-
"together",
|
|
1933
|
-
"perplexity",
|
|
1934
|
-
"amazon-bedrock",
|
|
1935
|
-
"vercel-ai-gateway",
|
|
1936
|
-
"minimax",
|
|
1937
|
-
"moonshot",
|
|
1938
|
-
"nvidia",
|
|
1939
|
-
"qwen",
|
|
1940
|
-
"cerebras",
|
|
1941
|
-
]);
|
|
1942
|
-
const fallback = {
|
|
1943
|
-
source: "fallback",
|
|
1924
|
+
return {
|
|
1925
|
+
source: "curated",
|
|
1944
1926
|
providers: [
|
|
1945
1927
|
{
|
|
1946
1928
|
id: "anthropic",
|
|
1947
1929
|
models: [
|
|
1948
|
-
{ id: "anthropic/claude-sonnet-4-6", name: "Claude Sonnet 4.6 (recommended
|
|
1930
|
+
{ id: "anthropic/claude-sonnet-4-6", name: "Claude Sonnet 4.6 (recommended)" },
|
|
1949
1931
|
{ id: "anthropic/claude-opus-4-6", name: "Claude Opus 4.6" },
|
|
1950
1932
|
{ id: "anthropic/claude-haiku-4-5", name: "Claude Haiku 4.5" },
|
|
1951
1933
|
],
|
|
@@ -1953,7 +1935,7 @@ async function loadWizardLlmCatalogAsync() {
|
|
|
1953
1935
|
{
|
|
1954
1936
|
id: "openai",
|
|
1955
1937
|
models: [
|
|
1956
|
-
{ id: "openai/gpt-5.4", name: "GPT-5.4 (recommended
|
|
1938
|
+
{ id: "openai/gpt-5.4", name: "GPT-5.4 (recommended)" },
|
|
1957
1939
|
{ id: "openai/gpt-5.4-mini", name: "GPT-5.4 mini" },
|
|
1958
1940
|
{ id: "openai/gpt-5.4-nano", name: "GPT-5.4 nano" },
|
|
1959
1941
|
],
|
|
@@ -1962,29 +1944,48 @@ async function loadWizardLlmCatalogAsync() {
|
|
|
1962
1944
|
id: "openai-codex",
|
|
1963
1945
|
models: [{ id: "openai-codex/gpt-5-codex", name: "GPT-5 Codex" }],
|
|
1964
1946
|
},
|
|
1947
|
+
{
|
|
1948
|
+
id: "google",
|
|
1949
|
+
models: [
|
|
1950
|
+
{ id: "google/gemini-2.5-flash", name: "Gemini 2.5 Flash (recommended)" },
|
|
1951
|
+
{ id: "google/gemini-2.5-pro", name: "Gemini 2.5 Pro" },
|
|
1952
|
+
],
|
|
1953
|
+
},
|
|
1965
1954
|
{
|
|
1966
1955
|
id: "xai",
|
|
1967
|
-
models: [
|
|
1956
|
+
models: [
|
|
1957
|
+
{ id: "xai/grok-4", name: "Grok 4 (recommended)" },
|
|
1958
|
+
{ id: "xai/grok-3", name: "Grok 3" },
|
|
1959
|
+
],
|
|
1968
1960
|
},
|
|
1969
1961
|
{
|
|
1970
1962
|
id: "deepseek",
|
|
1971
|
-
models: [
|
|
1963
|
+
models: [
|
|
1964
|
+
{ id: "deepseek/deepseek-chat", name: "DeepSeek Chat V3 (recommended)" },
|
|
1965
|
+
{ id: "deepseek/deepseek-reasoner", name: "DeepSeek Reasoner R1" },
|
|
1966
|
+
],
|
|
1972
1967
|
},
|
|
1973
1968
|
{
|
|
1974
|
-
id: "
|
|
1975
|
-
models: [
|
|
1969
|
+
id: "openrouter",
|
|
1970
|
+
models: [
|
|
1971
|
+
{ id: "openrouter/anthropic/claude-sonnet-4-6", name: "Claude Sonnet 4.6 via OpenRouter (recommended)" },
|
|
1972
|
+
{ id: "openrouter/openai/gpt-5.4", name: "GPT-5.4 via OpenRouter" },
|
|
1973
|
+
{ id: "openrouter/google/gemini-2.5-flash", name: "Gemini 2.5 Flash via OpenRouter" },
|
|
1974
|
+
],
|
|
1976
1975
|
},
|
|
1977
1976
|
{
|
|
1978
1977
|
id: "groq",
|
|
1979
|
-
models: [
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
models: [{ id: "openrouter/anthropic/claude-sonnet-4-6", name: "Claude Sonnet 4.6 (via OpenRouter)" }],
|
|
1978
|
+
models: [
|
|
1979
|
+
{ id: "groq/llama-4-scout-17b-16e-instruct", name: "Llama 4 Scout (recommended)" },
|
|
1980
|
+
{ id: "groq/llama-4-maverick-17b-128e-instruct", name: "Llama 4 Maverick" },
|
|
1981
|
+
],
|
|
1984
1982
|
},
|
|
1985
1983
|
{
|
|
1986
1984
|
id: "mistral",
|
|
1987
|
-
models: [
|
|
1985
|
+
models: [
|
|
1986
|
+
{ id: "mistral/mistral-large-latest", name: "Mistral Large (recommended)" },
|
|
1987
|
+
{ id: "mistral/mistral-medium-latest", name: "Mistral Medium" },
|
|
1988
|
+
],
|
|
1988
1989
|
},
|
|
1989
1990
|
{
|
|
1990
1991
|
id: "perplexity",
|
|
@@ -2002,174 +2003,13 @@ async function loadWizardLlmCatalogAsync() {
|
|
|
2002
2003
|
id: "qwen",
|
|
2003
2004
|
models: [{ id: "qwen/qwen3-235b-a22b", name: "Qwen3 235B A22B" }],
|
|
2004
2005
|
},
|
|
2006
|
+
{
|
|
2007
|
+
id: "moonshot",
|
|
2008
|
+
models: [{ id: "moonshot/kimi-k2", name: "Kimi K2" }],
|
|
2009
|
+
},
|
|
2005
2010
|
],
|
|
2011
|
+
generatedAt: new Date().toISOString(),
|
|
2006
2012
|
};
|
|
2007
|
-
|
|
2008
|
-
if (!commandExists("openclaw")) {
|
|
2009
|
-
return { ...fallback, warning: "openclaw_not_found" };
|
|
2010
|
-
}
|
|
2011
|
-
|
|
2012
|
-
const providerIds = [...supportedProviders].sort(compareWizardProviderPriority);
|
|
2013
|
-
const priorityProviderIds = providerIds.filter((id) => WIZARD_PRIORITY_PROVIDERS.includes(id));
|
|
2014
|
-
|
|
2015
|
-
async function fetchModelsForProvider(provider) {
|
|
2016
|
-
try {
|
|
2017
|
-
const { stdout } = await execFileAsync(
|
|
2018
|
-
"openclaw",
|
|
2019
|
-
["models", "list", "--all", "--provider", provider, "--json"],
|
|
2020
|
-
{
|
|
2021
|
-
encoding: "utf-8",
|
|
2022
|
-
maxBuffer: 25 * 1024 * 1024,
|
|
2023
|
-
timeout: OPENCLAW_MODELS_PER_PROVIDER_TIMEOUT_MS,
|
|
2024
|
-
env: NO_COLOR_ENV,
|
|
2025
|
-
},
|
|
2026
|
-
);
|
|
2027
|
-
return { provider, stdout };
|
|
2028
|
-
} catch (err) {
|
|
2029
|
-
return { provider, error: err };
|
|
2030
|
-
}
|
|
2031
|
-
}
|
|
2032
|
-
|
|
2033
|
-
function seedFallbackProviderMap() {
|
|
2034
|
-
return new Map(
|
|
2035
|
-
fallback.providers.map((entry) => [
|
|
2036
|
-
entry.id,
|
|
2037
|
-
entry.models.map((model) => ({ ...model })),
|
|
2038
|
-
]),
|
|
2039
|
-
);
|
|
2040
|
-
}
|
|
2041
|
-
|
|
2042
|
-
function mergeCatalogModelsIntoMap(providerMap, models, expectedProvider = "") {
|
|
2043
|
-
let added = 0;
|
|
2044
|
-
for (const entry of models) {
|
|
2045
|
-
if (!entry || typeof entry.key !== "string") continue;
|
|
2046
|
-
const modelId = String(entry.key);
|
|
2047
|
-
const slash = modelId.indexOf("/");
|
|
2048
|
-
if (slash <= 0 || slash === modelId.length - 1) continue;
|
|
2049
|
-
const provider = modelId.slice(0, slash);
|
|
2050
|
-
if (!supportedProviders.has(provider)) continue;
|
|
2051
|
-
if (expectedProvider && provider !== expectedProvider) continue;
|
|
2052
|
-
const existing = providerMap.get(provider) || [];
|
|
2053
|
-
existing.push({
|
|
2054
|
-
id: modelId,
|
|
2055
|
-
name: typeof entry.name === "string" && entry.name.trim() ? entry.name : modelId,
|
|
2056
|
-
});
|
|
2057
|
-
providerMap.set(provider, existing);
|
|
2058
|
-
added += 1;
|
|
2059
|
-
}
|
|
2060
|
-
return added;
|
|
2061
|
-
}
|
|
2062
|
-
|
|
2063
|
-
function buildProvidersFromMap(providerMap) {
|
|
2064
|
-
return providerIds
|
|
2065
|
-
.map((id) => {
|
|
2066
|
-
const rawModels = providerMap.get(id) || [];
|
|
2067
|
-
const sortedIds = sortModelsByPreference(
|
|
2068
|
-
id,
|
|
2069
|
-
rawModels.map((m) => m.id),
|
|
2070
|
-
);
|
|
2071
|
-
const byId = new Map(rawModels.map((m) => [m.id, m]));
|
|
2072
|
-
const limitedIds = sortedIds.slice(0, MAX_MODELS_PER_PROVIDER_SORT);
|
|
2073
|
-
const models = limitedIds.map((mid) => byId.get(mid)).filter(Boolean);
|
|
2074
|
-
return { id, models };
|
|
2075
|
-
})
|
|
2076
|
-
.filter((entry) => supportedProviders.has(entry.id))
|
|
2077
|
-
.filter((entry) => entry.models.length > 0);
|
|
2078
|
-
}
|
|
2079
|
-
|
|
2080
|
-
/** When `openclaw models list --all --json` returns models; used if per-provider calls yield nothing. */
|
|
2081
|
-
function mergeFlatCatalogIntoMap(providerMap) {
|
|
2082
|
-
const raw = execSync("openclaw models list --all --json", {
|
|
2083
|
-
encoding: "utf-8",
|
|
2084
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
2085
|
-
maxBuffer: 50 * 1024 * 1024,
|
|
2086
|
-
timeout: OPENCLAW_MODELS_FLAT_TIMEOUT_MS,
|
|
2087
|
-
env: NO_COLOR_ENV,
|
|
2088
|
-
});
|
|
2089
|
-
const parsed = extractJson(raw);
|
|
2090
|
-
if (!parsed) return 0;
|
|
2091
|
-
const models = Array.isArray(parsed?.models) ? parsed.models : [];
|
|
2092
|
-
return mergeCatalogModelsIntoMap(providerMap, models);
|
|
2093
|
-
}
|
|
2094
|
-
|
|
2095
|
-
try {
|
|
2096
|
-
const t0 = Date.now();
|
|
2097
|
-
const liveProviderMap = new Map();
|
|
2098
|
-
let catalogStrategy = "flat_all";
|
|
2099
|
-
let flatError = "";
|
|
2100
|
-
let liveAdded = 0;
|
|
2101
|
-
try {
|
|
2102
|
-
liveAdded = mergeFlatCatalogIntoMap(liveProviderMap);
|
|
2103
|
-
} catch (err) {
|
|
2104
|
-
flatError = err instanceof Error ? err.message : String(err);
|
|
2105
|
-
}
|
|
2106
|
-
|
|
2107
|
-
let batches = [];
|
|
2108
|
-
if (liveAdded === 0) {
|
|
2109
|
-
catalogStrategy = "priority_parallel";
|
|
2110
|
-
batches = await Promise.all(priorityProviderIds.map((p) => fetchModelsForProvider(p)));
|
|
2111
|
-
for (const batch of batches) {
|
|
2112
|
-
if (batch.error || !batch.stdout) continue;
|
|
2113
|
-
const parsed = extractJson(batch.stdout);
|
|
2114
|
-
if (!parsed) continue;
|
|
2115
|
-
const models = Array.isArray(parsed?.models) ? parsed.models : [];
|
|
2116
|
-
liveAdded += mergeCatalogModelsIntoMap(liveProviderMap, models, batch.provider);
|
|
2117
|
-
}
|
|
2118
|
-
}
|
|
2119
|
-
|
|
2120
|
-
let providers = buildProvidersFromMap(liveProviderMap);
|
|
2121
|
-
if (providers.length === 0) {
|
|
2122
|
-
const failedParallel = batches.filter((b) => b.error).length;
|
|
2123
|
-
const details = [];
|
|
2124
|
-
if (flatError) details.push(`flat list failed: ${flatError.slice(0, 160)}`);
|
|
2125
|
-
if (failedParallel > 0) {
|
|
2126
|
-
details.push(
|
|
2127
|
-
`${failedParallel}/${priorityProviderIds.length} priority provider lookups failed`,
|
|
2128
|
-
);
|
|
2129
|
-
}
|
|
2130
|
-
return {
|
|
2131
|
-
...fallback,
|
|
2132
|
-
warning: `openclaw_model_catalog_unavailable${details.length ? ` (${details.join("; ")})` : ""}`,
|
|
2133
|
-
};
|
|
2134
|
-
}
|
|
2135
|
-
|
|
2136
|
-
const mergedProviderMap = new Map(liveProviderMap);
|
|
2137
|
-
for (const [provider, models] of seedFallbackProviderMap()) {
|
|
2138
|
-
if (!mergedProviderMap.has(provider) || (mergedProviderMap.get(provider) || []).length === 0) {
|
|
2139
|
-
mergedProviderMap.set(provider, models);
|
|
2140
|
-
}
|
|
2141
|
-
}
|
|
2142
|
-
providers = buildProvidersFromMap(mergedProviderMap);
|
|
2143
|
-
|
|
2144
|
-
const elapsedMs = Date.now() - t0;
|
|
2145
|
-
const source =
|
|
2146
|
-
providers.length > buildProvidersFromMap(liveProviderMap).length ? "hybrid" : "openclaw";
|
|
2147
|
-
const warning =
|
|
2148
|
-
source === "hybrid" && flatError
|
|
2149
|
-
? `loaded priority providers; kept curated defaults for the rest (${flatError.slice(0, 160)})`
|
|
2150
|
-
: source === "hybrid"
|
|
2151
|
-
? "loaded priority providers; kept curated defaults for the rest"
|
|
2152
|
-
: "";
|
|
2153
|
-
return {
|
|
2154
|
-
source,
|
|
2155
|
-
providers,
|
|
2156
|
-
generatedAt: new Date().toISOString(),
|
|
2157
|
-
catalogFetchMs: elapsedMs,
|
|
2158
|
-
catalogStrategy,
|
|
2159
|
-
...(warning ? { warning } : {}),
|
|
2160
|
-
};
|
|
2161
|
-
} catch (err) {
|
|
2162
|
-
const detail = err?.message || String(err);
|
|
2163
|
-
const isBufferErr = detail.includes("maxBuffer") || detail.includes("ENOBUFS");
|
|
2164
|
-
const hint = isBufferErr
|
|
2165
|
-
? " (stdout exceeded buffer — OpenClaw model catalog may have grown; this version raises the limit)"
|
|
2166
|
-
: "";
|
|
2167
|
-
console.error(`[traderclaw] loadWizardLlmCatalog failed${hint}: ${detail.slice(0, 500)}`);
|
|
2168
|
-
return {
|
|
2169
|
-
...fallback,
|
|
2170
|
-
warning: `openclaw_models_list_failed: ${detail}`,
|
|
2171
|
-
};
|
|
2172
|
-
}
|
|
2173
2013
|
}
|
|
2174
2014
|
|
|
2175
2015
|
function wizardHtml(defaults) {
|
|
@@ -2468,11 +2308,11 @@ function wizardHtml(defaults) {
|
|
|
2468
2308
|
startBtn.textContent = "Loading providers...";
|
|
2469
2309
|
const updateHint = () => {
|
|
2470
2310
|
const elapsedSeconds = Math.max(1, Math.floor((Date.now() - llmLoadStartedAt) / 1000));
|
|
2471
|
-
if (elapsedSeconds >=
|
|
2472
|
-
llmLoadingHintTextEl.textContent = "Still loading
|
|
2311
|
+
if (elapsedSeconds >= 5) {
|
|
2312
|
+
llmLoadingHintTextEl.textContent = "Still loading (" + elapsedSeconds + "s). Check network or reload.";
|
|
2473
2313
|
return;
|
|
2474
2314
|
}
|
|
2475
|
-
llmLoadingHintTextEl.textContent = "
|
|
2315
|
+
llmLoadingHintTextEl.textContent = "Loading provider list (" + elapsedSeconds + "s)...";
|
|
2476
2316
|
};
|
|
2477
2317
|
updateHint();
|
|
2478
2318
|
stopLlmLoadTicker();
|
|
@@ -2523,7 +2363,7 @@ function wizardHtml(defaults) {
|
|
|
2523
2363
|
setLlmCatalogLoading(true);
|
|
2524
2364
|
setSelectOptions(llmProviderEl, [{ value: "", label: "Loading providers..." }], "");
|
|
2525
2365
|
setSelectOptions(llmModelEl, [{ value: "", label: "Loading models..." }], "");
|
|
2526
|
-
setLlmCatalogReady(false, "Loading
|
|
2366
|
+
setLlmCatalogReady(false, "Loading provider list...");
|
|
2527
2367
|
try {
|
|
2528
2368
|
const res = await fetch("/api/llm/options");
|
|
2529
2369
|
const data = await res.json();
|
|
@@ -2532,21 +2372,15 @@ function wizardHtml(defaults) {
|
|
|
2532
2372
|
if (providers.length === 0) {
|
|
2533
2373
|
setSelectOptions(llmProviderEl, [{ value: "", label: "No providers available" }], "");
|
|
2534
2374
|
refreshModelOptions("");
|
|
2535
|
-
setLlmCatalogReady(false, "No LLM providers
|
|
2375
|
+
setLlmCatalogReady(false, "No LLM providers found. Reload the page to try again.", true);
|
|
2536
2376
|
return;
|
|
2537
2377
|
}
|
|
2538
2378
|
setSelectOptions(llmProviderEl, providers, "${defaults.llmProvider}");
|
|
2539
2379
|
refreshModelOptions("${defaults.llmModel}");
|
|
2540
|
-
const
|
|
2541
|
-
|
|
2542
|
-
const catalogMsg = isFallback
|
|
2543
|
-
? "Showing curated safe defaults only (could not load live OpenClaw catalog" + (llmCatalog.warning ? ": " + llmCatalog.warning : "") + "). Anthropic and OpenAI stay ready first, with several other providers still available."
|
|
2544
|
-
: isHybrid
|
|
2545
|
-
? "Loaded priority providers first and filled the rest with curated defaults" + (llmCatalog.warning ? " (" + llmCatalog.warning + ")" : "") + "."
|
|
2546
|
-
: "LLM providers loaded. Select provider and paste credential to continue. Model selection is optional.";
|
|
2547
|
-
setLlmCatalogReady(true, catalogMsg, isFallback || isHybrid);
|
|
2380
|
+
const catalogMsg = "Select your provider, paste your API key, and start installation. After setup, run \`openclaw models list\` to explore your live catalog.";
|
|
2381
|
+
setLlmCatalogReady(true, catalogMsg, false);
|
|
2548
2382
|
} catch (err) {
|
|
2549
|
-
setLlmCatalogReady(false, "Failed to load LLM providers.
|
|
2383
|
+
setLlmCatalogReady(false, "Failed to load LLM providers. Reload the page and try again.", true);
|
|
2550
2384
|
manualEl.textContent = "Failed to load LLM provider catalog: " + (err && err.message ? err.message : String(err));
|
|
2551
2385
|
} finally {
|
|
2552
2386
|
setLlmCatalogLoading(false);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "traderclaw-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.66",
|
|
4
4
|
"description": "Global TraderClaw CLI (install --wizard, setup, precheck). Installs solana-traderclaw as a dependency for OpenClaw plugin files.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"node": ">=22"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"solana-traderclaw": "^1.0.
|
|
20
|
+
"solana-traderclaw": "^1.0.66"
|
|
21
21
|
},
|
|
22
22
|
"keywords": [
|
|
23
23
|
"traderclaw",
|