traderclaw-cli 1.0.59 → 1.0.61
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 +5 -5
- package/bin/openclaw-trader.mjs +162 -66
- package/package.json +2 -2
|
@@ -768,7 +768,7 @@ function traderCronPrescriptiveJobs(agentId) {
|
|
|
768
768
|
schedule: "30 */2 * * *",
|
|
769
769
|
agentId,
|
|
770
770
|
message:
|
|
771
|
-
"CRON_JOB: portfolio_risk_audit —
|
|
771
|
+
"CRON_JOB: portfolio_risk_audit\n\nStep 1: Call solana_capital_status to get wallet balance and portfolio value.\n\nStep 2: Call solana_positions to get all open positions with entry prices and sizes.\n\nStep 3: For each open position, call solana_token_snapshot to get current price, 24h volume, and market cap.\n\nStep 4: Run concentration check — flag WARNING if any single position exceeds 30 percent of total portfolio value, CRITICAL if above 50 percent.\n\nStep 5: Run exposure check — flag WARNING if total exposure exceeds 50 percent of wallet balance, CRITICAL if above 75 percent.\n\nStep 6: Run drawdown check — CRITICAL if portfolio drawdown exceeds 25 percent from peak capital.\n\nStep 7: Calculate portfolio heat (sum of all position risk scores). Flag WARNING above 50 percent, CRITICAL above 75 percent.\n\nStep 8: Run liquidity check — WARNING if any position exceeds 2 percent of its pool depth.\n\nStep 9: Check solana_killswitch_status.\n\nStep 10: Write risk report via solana_memory_write with tag 'risk_audit'.\n\nFORMATTING RULES:\n- Every token reference MUST use SYMBOL (full_CA) format.\n- Do not execute trades. Do not ask questions.",
|
|
772
772
|
enabled: true,
|
|
773
773
|
},
|
|
774
774
|
{
|
|
@@ -776,15 +776,15 @@ function traderCronPrescriptiveJobs(agentId) {
|
|
|
776
776
|
schedule: "0 */3 * * *",
|
|
777
777
|
agentId,
|
|
778
778
|
message:
|
|
779
|
-
"CRON_JOB: source_reputation_recalc
|
|
779
|
+
"CRON_JOB: source_reputation_recalc\n\nStep 1: Call solana_alpha_sources to get per-source performance stats (signal count, conversion rate, avg score).\n\nStep 2: Call solana_alpha_history to get recent signal history with scores and source identifiers.\n\nStep 3: Call solana_trades to get recent trade outcomes. Cross-reference each trade back to its originating signal source.\n\nStep 4: For each source, calculate: win rate (trades that hit TP vs SL), average PnL per trade, signal-to-trade conversion rate.\n\nStep 5: Assign tier rankings:\n- TIER-1 (LOCK): Win rate above 60% AND 5+ trades AND positive avg PnL\n- TIER-2 (CONDITIONAL): Win rate 30-60% OR fewer than 5 trades\n- TIER-3 (BLACKLIST): Win rate below 30% with 5+ trades\n\nStep 6: Write scorecard to memory using solana_memory_write with tag 'source_reputation'.\n\nFORMATTING RULES:\n- Every token reference MUST use SYMBOL (full_CA) format.\n- Do not execute trades. Do not ask questions.",
|
|
780
780
|
enabled: true,
|
|
781
781
|
},
|
|
782
782
|
{
|
|
783
|
-
id: "meta-rotation
|
|
783
|
+
id: "meta-rotation",
|
|
784
784
|
schedule: "30 */3 * * *",
|
|
785
785
|
agentId,
|
|
786
786
|
message:
|
|
787
|
-
"CRON_JOB: meta_rotation_analysis
|
|
787
|
+
"CRON_JOB: meta_rotation_analysis\n\nStep 0: Call x_search_tweets with queries: 'solana memecoin', 'pump fun gem', 'sol alpha'. Note which token names and narratives appear most frequently in the last 3 hours. Use this social signal to validate or challenge the on-chain data in the following steps.\n\nStep 1: Call solana_scan_launches to get recent token launches (last 3-6 hours).\n\nStep 2: Categorize each token by narrative cluster: AI/Agents, Animal Memes, Political, Celebrity/IP, DeFi, Gaming, Culture/Humor, Other.\n\nStep 3: For each cluster, aggregate: token count, total volume, average market cap.\n\nStep 4: Call solana_memory_search for 'meta_rotation' to compare with prior scan.\n\nStep 5: Classify each narrative: GAINING, SATURATED, COOLING, DORMANT.\n\nStep 6: Write rotation report via solana_memory_write with tag 'meta_rotation'.\n\nFORMATTING RULES:\n- Every token reference MUST use SYMBOL (full_CA) format.\n- Do not execute trades. Do not ask questions.",
|
|
788
788
|
enabled: true,
|
|
789
789
|
},
|
|
790
790
|
{
|
|
@@ -800,7 +800,7 @@ function traderCronPrescriptiveJobs(agentId) {
|
|
|
800
800
|
schedule: "15 * * * *",
|
|
801
801
|
agentId,
|
|
802
802
|
message:
|
|
803
|
-
"CRON_JOB: subscription_cleanup
|
|
803
|
+
"CRON_JOB: subscription_cleanup\n\nStep 1: Call solana_positions to get all open positions and extract their contract addresses.\n\nStep 2: Call solana_bitquery_subscriptions to list all active Bitquery subscriptions. If this call returns an AUTH_SCOPE_MISSING error, log the error to memory and stop gracefully — do not retry or error out.\n\nStep 3: For each active subscription, check if the associated token CA still has an open position. Build two lists: 'matched' (has position) and 'orphaned' (no position).\n\nStep 4: Unsubscribe orphans via solana_bitquery_unsubscribe.\n\nStep 5: Reopen subscriptions nearing 24h expiry via solana_bitquery_subscription_reopen.\n\nStep 6: Write summary via solana_memory_write with tag 'subscription_cleanup'.\n\nFORMATTING RULES:\n- Every token reference MUST use SYMBOL (full_CA) format.\n- Do not execute trades. Do not ask questions.",
|
|
804
804
|
enabled: true,
|
|
805
805
|
},
|
|
806
806
|
{
|
package/bin/openclaw-trader.mjs
CHANGED
|
@@ -14,8 +14,42 @@ import { resolvePluginPackageRoot } from "./resolve-plugin-root.mjs";
|
|
|
14
14
|
|
|
15
15
|
const execFileAsync = promisify(execFile);
|
|
16
16
|
|
|
17
|
-
/**
|
|
18
|
-
const
|
|
17
|
+
/** Fast wizard catalog lookup: prefer one full list, then only probe key providers. */
|
|
18
|
+
const OPENCLAW_MODELS_FLAT_TIMEOUT_MS = 7_500;
|
|
19
|
+
const OPENCLAW_MODELS_PER_PROVIDER_TIMEOUT_MS = 4_500;
|
|
20
|
+
const WIZARD_PRIORITY_PROVIDERS = [
|
|
21
|
+
"anthropic",
|
|
22
|
+
"openai",
|
|
23
|
+
"openrouter",
|
|
24
|
+
"google",
|
|
25
|
+
"xai",
|
|
26
|
+
"deepseek",
|
|
27
|
+
"groq",
|
|
28
|
+
"mistral",
|
|
29
|
+
];
|
|
30
|
+
const WIZARD_PROVIDER_PRIORITY = [
|
|
31
|
+
...WIZARD_PRIORITY_PROVIDERS,
|
|
32
|
+
"perplexity",
|
|
33
|
+
"together",
|
|
34
|
+
"openai-codex",
|
|
35
|
+
"google-vertex",
|
|
36
|
+
"amazon-bedrock",
|
|
37
|
+
"vercel-ai-gateway",
|
|
38
|
+
"nvidia",
|
|
39
|
+
"moonshot",
|
|
40
|
+
"qwen",
|
|
41
|
+
"cerebras",
|
|
42
|
+
"minimax",
|
|
43
|
+
];
|
|
44
|
+
let wizardLlmCatalogPromise = null;
|
|
45
|
+
|
|
46
|
+
function compareWizardProviderPriority(a, b) {
|
|
47
|
+
const ai = WIZARD_PROVIDER_PRIORITY.indexOf(a);
|
|
48
|
+
const bi = WIZARD_PROVIDER_PRIORITY.indexOf(b);
|
|
49
|
+
const aRank = ai >= 0 ? ai : Number.MAX_SAFE_INTEGER;
|
|
50
|
+
const bRank = bi >= 0 ? bi : Number.MAX_SAFE_INTEGER;
|
|
51
|
+
return aRank - bRank || a.localeCompare(b);
|
|
52
|
+
}
|
|
19
53
|
|
|
20
54
|
const PLUGIN_ROOT = resolvePluginPackageRoot(import.meta.url);
|
|
21
55
|
const PLUGIN_PACKAGE_JSON = JSON.parse(readFileSync(join(PLUGIN_ROOT, "package.json"), "utf-8"));
|
|
@@ -1871,11 +1905,23 @@ async function loadWizardLlmCatalogAsync() {
|
|
|
1871
1905
|
providers: [
|
|
1872
1906
|
{
|
|
1873
1907
|
id: "anthropic",
|
|
1874
|
-
models: [
|
|
1908
|
+
models: [
|
|
1909
|
+
{ id: "anthropic/claude-sonnet-4-6", name: "Claude Sonnet 4.6 (recommended default)" },
|
|
1910
|
+
{ id: "anthropic/claude-opus-4-6", name: "Claude Opus 4.6" },
|
|
1911
|
+
{ id: "anthropic/claude-haiku-4-5", name: "Claude Haiku 4.5" },
|
|
1912
|
+
],
|
|
1875
1913
|
},
|
|
1876
1914
|
{
|
|
1877
1915
|
id: "openai",
|
|
1878
|
-
models: [
|
|
1916
|
+
models: [
|
|
1917
|
+
{ id: "openai/gpt-5.4", name: "GPT-5.4 (recommended default)" },
|
|
1918
|
+
{ id: "openai/gpt-5.4-mini", name: "GPT-5.4 mini" },
|
|
1919
|
+
{ id: "openai/gpt-5.4-nano", name: "GPT-5.4 nano" },
|
|
1920
|
+
],
|
|
1921
|
+
},
|
|
1922
|
+
{
|
|
1923
|
+
id: "openai-codex",
|
|
1924
|
+
models: [{ id: "openai-codex/gpt-5-codex", name: "GPT-5 Codex" }],
|
|
1879
1925
|
},
|
|
1880
1926
|
{
|
|
1881
1927
|
id: "xai",
|
|
@@ -1901,6 +1947,22 @@ async function loadWizardLlmCatalogAsync() {
|
|
|
1901
1947
|
id: "mistral",
|
|
1902
1948
|
models: [{ id: "mistral/mistral-large-latest", name: "Mistral Large" }],
|
|
1903
1949
|
},
|
|
1950
|
+
{
|
|
1951
|
+
id: "perplexity",
|
|
1952
|
+
models: [{ id: "perplexity/sonar-pro", name: "Sonar Pro" }],
|
|
1953
|
+
},
|
|
1954
|
+
{
|
|
1955
|
+
id: "together",
|
|
1956
|
+
models: [{ id: "together/moonshotai/Kimi-K2.5", name: "Kimi K2.5" }],
|
|
1957
|
+
},
|
|
1958
|
+
{
|
|
1959
|
+
id: "nvidia",
|
|
1960
|
+
models: [{ id: "nvidia/llama-3.3-70b-instruct", name: "Llama 3.3 70B Instruct" }],
|
|
1961
|
+
},
|
|
1962
|
+
{
|
|
1963
|
+
id: "qwen",
|
|
1964
|
+
models: [{ id: "qwen/qwen3-235b-a22b", name: "Qwen3 235B A22B" }],
|
|
1965
|
+
},
|
|
1904
1966
|
],
|
|
1905
1967
|
};
|
|
1906
1968
|
|
|
@@ -1908,7 +1970,8 @@ async function loadWizardLlmCatalogAsync() {
|
|
|
1908
1970
|
return { ...fallback, warning: "openclaw_not_found" };
|
|
1909
1971
|
}
|
|
1910
1972
|
|
|
1911
|
-
const providerIds = [...supportedProviders].sort(
|
|
1973
|
+
const providerIds = [...supportedProviders].sort(compareWizardProviderPriority);
|
|
1974
|
+
const priorityProviderIds = providerIds.filter((id) => WIZARD_PRIORITY_PROVIDERS.includes(id));
|
|
1912
1975
|
|
|
1913
1976
|
async function fetchModelsForProvider(provider) {
|
|
1914
1977
|
try {
|
|
@@ -1928,6 +1991,36 @@ async function loadWizardLlmCatalogAsync() {
|
|
|
1928
1991
|
}
|
|
1929
1992
|
}
|
|
1930
1993
|
|
|
1994
|
+
function seedFallbackProviderMap() {
|
|
1995
|
+
return new Map(
|
|
1996
|
+
fallback.providers.map((entry) => [
|
|
1997
|
+
entry.id,
|
|
1998
|
+
entry.models.map((model) => ({ ...model })),
|
|
1999
|
+
]),
|
|
2000
|
+
);
|
|
2001
|
+
}
|
|
2002
|
+
|
|
2003
|
+
function mergeCatalogModelsIntoMap(providerMap, models, expectedProvider = "") {
|
|
2004
|
+
let added = 0;
|
|
2005
|
+
for (const entry of models) {
|
|
2006
|
+
if (!entry || typeof entry.key !== "string") continue;
|
|
2007
|
+
const modelId = String(entry.key);
|
|
2008
|
+
const slash = modelId.indexOf("/");
|
|
2009
|
+
if (slash <= 0 || slash === modelId.length - 1) continue;
|
|
2010
|
+
const provider = modelId.slice(0, slash);
|
|
2011
|
+
if (!supportedProviders.has(provider)) continue;
|
|
2012
|
+
if (expectedProvider && provider !== expectedProvider) continue;
|
|
2013
|
+
const existing = providerMap.get(provider) || [];
|
|
2014
|
+
existing.push({
|
|
2015
|
+
id: modelId,
|
|
2016
|
+
name: typeof entry.name === "string" && entry.name.trim() ? entry.name : modelId,
|
|
2017
|
+
});
|
|
2018
|
+
providerMap.set(provider, existing);
|
|
2019
|
+
added += 1;
|
|
2020
|
+
}
|
|
2021
|
+
return added;
|
|
2022
|
+
}
|
|
2023
|
+
|
|
1931
2024
|
function buildProvidersFromMap(providerMap) {
|
|
1932
2025
|
return providerIds
|
|
1933
2026
|
.map((id) => {
|
|
@@ -1951,86 +2044,80 @@ async function loadWizardLlmCatalogAsync() {
|
|
|
1951
2044
|
encoding: "utf-8",
|
|
1952
2045
|
stdio: ["ignore", "pipe", "pipe"],
|
|
1953
2046
|
maxBuffer: 50 * 1024 * 1024,
|
|
1954
|
-
timeout:
|
|
2047
|
+
timeout: OPENCLAW_MODELS_FLAT_TIMEOUT_MS,
|
|
1955
2048
|
env: NO_COLOR_ENV,
|
|
1956
2049
|
});
|
|
1957
2050
|
const parsed = extractJson(raw);
|
|
1958
|
-
if (!parsed) return;
|
|
2051
|
+
if (!parsed) return 0;
|
|
1959
2052
|
const models = Array.isArray(parsed?.models) ? parsed.models : [];
|
|
1960
|
-
|
|
1961
|
-
if (!entry || typeof entry.key !== "string") continue;
|
|
1962
|
-
const modelId = String(entry.key);
|
|
1963
|
-
const slash = modelId.indexOf("/");
|
|
1964
|
-
if (slash <= 0 || slash === modelId.length - 1) continue;
|
|
1965
|
-
const provider = modelId.slice(0, slash);
|
|
1966
|
-
if (!supportedProviders.has(provider)) continue;
|
|
1967
|
-
const existing = providerMap.get(provider) || [];
|
|
1968
|
-
existing.push({
|
|
1969
|
-
id: modelId,
|
|
1970
|
-
name: typeof entry.name === "string" && entry.name.trim() ? entry.name : modelId,
|
|
1971
|
-
});
|
|
1972
|
-
providerMap.set(provider, existing);
|
|
1973
|
-
}
|
|
2053
|
+
return mergeCatalogModelsIntoMap(providerMap, models);
|
|
1974
2054
|
}
|
|
1975
2055
|
|
|
1976
2056
|
try {
|
|
1977
2057
|
const t0 = Date.now();
|
|
1978
|
-
const
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
if (
|
|
1994
|
-
const
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
});
|
|
1999
|
-
providerMap.set(provider, existing);
|
|
2058
|
+
const liveProviderMap = new Map();
|
|
2059
|
+
let catalogStrategy = "flat_all";
|
|
2060
|
+
let flatError = "";
|
|
2061
|
+
let liveAdded = 0;
|
|
2062
|
+
try {
|
|
2063
|
+
liveAdded = mergeFlatCatalogIntoMap(liveProviderMap);
|
|
2064
|
+
} catch (err) {
|
|
2065
|
+
flatError = err instanceof Error ? err.message : String(err);
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2068
|
+
let batches = [];
|
|
2069
|
+
if (liveAdded === 0) {
|
|
2070
|
+
catalogStrategy = "priority_parallel";
|
|
2071
|
+
batches = await Promise.all(priorityProviderIds.map((p) => fetchModelsForProvider(p)));
|
|
2072
|
+
for (const batch of batches) {
|
|
2073
|
+
if (batch.error || !batch.stdout) continue;
|
|
2074
|
+
const parsed = extractJson(batch.stdout);
|
|
2075
|
+
if (!parsed) continue;
|
|
2076
|
+
const models = Array.isArray(parsed?.models) ? parsed.models : [];
|
|
2077
|
+
liveAdded += mergeCatalogModelsIntoMap(liveProviderMap, models, batch.provider);
|
|
2000
2078
|
}
|
|
2001
2079
|
}
|
|
2002
2080
|
|
|
2003
|
-
let providers = buildProvidersFromMap(
|
|
2004
|
-
let catalogStrategy = "parallel";
|
|
2005
|
-
|
|
2081
|
+
let providers = buildProvidersFromMap(liveProviderMap);
|
|
2006
2082
|
if (providers.length === 0) {
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
`[traderclaw] loadWizardLlmCatalog legacy fallback failed: ${legacyErr instanceof Error ? legacyErr.message : String(legacyErr)}`,
|
|
2083
|
+
const failedParallel = batches.filter((b) => b.error).length;
|
|
2084
|
+
const details = [];
|
|
2085
|
+
if (flatError) details.push(`flat list failed: ${flatError.slice(0, 160)}`);
|
|
2086
|
+
if (failedParallel > 0) {
|
|
2087
|
+
details.push(
|
|
2088
|
+
`${failedParallel}/${priorityProviderIds.length} priority provider lookups failed`,
|
|
2014
2089
|
);
|
|
2015
2090
|
}
|
|
2091
|
+
return {
|
|
2092
|
+
...fallback,
|
|
2093
|
+
warning: `openclaw_model_catalog_unavailable${details.length ? ` (${details.join("; ")})` : ""}`,
|
|
2094
|
+
};
|
|
2016
2095
|
}
|
|
2017
2096
|
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
: "";
|
|
2024
|
-
return { ...fallback, warning: `openclaw_model_catalog_empty${hint}` };
|
|
2097
|
+
const mergedProviderMap = new Map(liveProviderMap);
|
|
2098
|
+
for (const [provider, models] of seedFallbackProviderMap()) {
|
|
2099
|
+
if (!mergedProviderMap.has(provider) || (mergedProviderMap.get(provider) || []).length === 0) {
|
|
2100
|
+
mergedProviderMap.set(provider, models);
|
|
2101
|
+
}
|
|
2025
2102
|
}
|
|
2103
|
+
providers = buildProvidersFromMap(mergedProviderMap);
|
|
2026
2104
|
|
|
2027
2105
|
const elapsedMs = Date.now() - t0;
|
|
2106
|
+
const source =
|
|
2107
|
+
providers.length > buildProvidersFromMap(liveProviderMap).length ? "hybrid" : "openclaw";
|
|
2108
|
+
const warning =
|
|
2109
|
+
source === "hybrid" && flatError
|
|
2110
|
+
? `loaded priority providers; kept curated defaults for the rest (${flatError.slice(0, 160)})`
|
|
2111
|
+
: source === "hybrid"
|
|
2112
|
+
? "loaded priority providers; kept curated defaults for the rest"
|
|
2113
|
+
: "";
|
|
2028
2114
|
return {
|
|
2029
|
-
source
|
|
2115
|
+
source,
|
|
2030
2116
|
providers,
|
|
2031
2117
|
generatedAt: new Date().toISOString(),
|
|
2032
2118
|
catalogFetchMs: elapsedMs,
|
|
2033
2119
|
catalogStrategy,
|
|
2120
|
+
...(warning ? { warning } : {}),
|
|
2034
2121
|
};
|
|
2035
2122
|
} catch (err) {
|
|
2036
2123
|
const detail = err?.message || String(err);
|
|
@@ -2334,7 +2421,7 @@ function wizardHtml(defaults) {
|
|
|
2334
2421
|
const updateHint = () => {
|
|
2335
2422
|
const elapsedSeconds = Math.max(1, Math.floor((Date.now() - llmLoadStartedAt) / 1000));
|
|
2336
2423
|
if (elapsedSeconds >= 8) {
|
|
2337
|
-
llmLoadingHintTextEl.textContent = "Still loading provider catalog (" + elapsedSeconds + "s).
|
|
2424
|
+
llmLoadingHintTextEl.textContent = "Still loading provider catalog (" + elapsedSeconds + "s). This should usually finish in under ~10s.";
|
|
2338
2425
|
return;
|
|
2339
2426
|
}
|
|
2340
2427
|
llmLoadingHintTextEl.textContent = "Fetching provider list (" + elapsedSeconds + "s)...";
|
|
@@ -2403,10 +2490,13 @@ function wizardHtml(defaults) {
|
|
|
2403
2490
|
setSelectOptions(llmProviderEl, providers, "${defaults.llmProvider}");
|
|
2404
2491
|
refreshModelOptions("${defaults.llmModel}");
|
|
2405
2492
|
const isFallback = llmCatalog.source === "fallback";
|
|
2493
|
+
const isHybrid = llmCatalog.source === "hybrid";
|
|
2406
2494
|
const catalogMsg = isFallback
|
|
2407
|
-
? "Showing safe defaults only (could not load
|
|
2408
|
-
:
|
|
2409
|
-
|
|
2495
|
+
? "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."
|
|
2496
|
+
: isHybrid
|
|
2497
|
+
? "Loaded priority providers first and filled the rest with curated defaults" + (llmCatalog.warning ? " (" + llmCatalog.warning + ")" : "") + "."
|
|
2498
|
+
: "LLM providers loaded. Select provider and paste credential to continue. Model selection is optional.";
|
|
2499
|
+
setLlmCatalogReady(true, catalogMsg, isFallback || isHybrid);
|
|
2410
2500
|
} catch (err) {
|
|
2411
2501
|
setLlmCatalogReady(false, "Failed to load LLM providers. Check OpenClaw and reload this page.", true);
|
|
2412
2502
|
manualEl.textContent = "Failed to load LLM provider catalog: " + (err && err.message ? err.message : String(err));
|
|
@@ -2782,7 +2872,13 @@ async function cmdInstall(args) {
|
|
|
2782
2872
|
|
|
2783
2873
|
if (req.method === "GET" && req.url === "/api/llm/options") {
|
|
2784
2874
|
try {
|
|
2785
|
-
|
|
2875
|
+
if (!wizardLlmCatalogPromise) {
|
|
2876
|
+
wizardLlmCatalogPromise = loadWizardLlmCatalogAsync().catch((err) => {
|
|
2877
|
+
wizardLlmCatalogPromise = null;
|
|
2878
|
+
throw err;
|
|
2879
|
+
});
|
|
2880
|
+
}
|
|
2881
|
+
const payload = await wizardLlmCatalogPromise;
|
|
2786
2882
|
respondJson(200, payload);
|
|
2787
2883
|
} catch (err) {
|
|
2788
2884
|
respondJson(500, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "traderclaw-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.61",
|
|
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.61"
|
|
21
21
|
},
|
|
22
22
|
"keywords": [
|
|
23
23
|
"traderclaw",
|