solana-traderclaw 1.0.31 → 1.0.32
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.
|
@@ -203,6 +203,29 @@ function gatewayModeUnsetRemediation() {
|
|
|
203
203
|
].join("\n");
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
+
function gatewayConfigValidationRemediation() {
|
|
207
|
+
return [
|
|
208
|
+
"OpenClaw could not load or validate ~/.openclaw/openclaw.json after plugins are enabled (often an Ajv/schema compile error in the OpenClaw CLI, not invalid JSON syntax).",
|
|
209
|
+
"The first `openclaw config validate` in this installer runs before plugins install; validation must be re-run once plugin schemas are registered — that is why this can appear only at gateway.",
|
|
210
|
+
"On the VPS, try in order:",
|
|
211
|
+
"1) openclaw --version",
|
|
212
|
+
"2) npm install -g openclaw@latest",
|
|
213
|
+
"3) openclaw config validate",
|
|
214
|
+
"4) openclaw plugins doctor",
|
|
215
|
+
"5) cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.bak.$(date +%s) || true",
|
|
216
|
+
"If it still fails, report the OpenClaw version plus output of steps 3–4 to OpenClaw/TraderClaw support (redact secrets).",
|
|
217
|
+
].join("\n");
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function isOpenClawConfigSchemaFailure(text) {
|
|
221
|
+
const t = String(text || "").toLowerCase();
|
|
222
|
+
return (
|
|
223
|
+
t.includes("ajv implementation")
|
|
224
|
+
|| t.includes("validatejsonschemavalue")
|
|
225
|
+
|| (t.includes("failed to read config") && t.includes("ajv"))
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
|
|
206
229
|
function runCommandWithEvents(cmd, args = [], opts = {}) {
|
|
207
230
|
return new Promise((resolve, reject) => {
|
|
208
231
|
const { onEvent, ...spawnOpts } = opts;
|
|
@@ -1114,9 +1137,10 @@ function resolveLlmModelSelection(provider, requestedModel) {
|
|
|
1114
1137
|
}
|
|
1115
1138
|
|
|
1116
1139
|
/**
|
|
1117
|
-
* OpenClaw 2026+
|
|
1118
|
-
* `heartbeat`
|
|
1119
|
-
*
|
|
1140
|
+
* OpenClaw 2026+ expects `agents.defaults.heartbeat` as an object when `defaults` exists; plugin merges
|
|
1141
|
+
* sometimes drop it. We only add `heartbeat: {}` here — do NOT add `model: {}` when `model` is absent:
|
|
1142
|
+
* many schemas require `model.primary` whenever `model` is present; an empty model object caused Ajv
|
|
1143
|
+
* failures after hardening (regression for installs where the plugin stripped `model` but left defaults).
|
|
1120
1144
|
*/
|
|
1121
1145
|
function ensureAgentsDefaultsSchemaCompat(config) {
|
|
1122
1146
|
if (!config || typeof config !== "object") return;
|
|
@@ -1125,8 +1149,9 @@ function ensureAgentsDefaultsSchemaCompat(config) {
|
|
|
1125
1149
|
if (!config.agents.defaults.heartbeat || typeof config.agents.defaults.heartbeat !== "object") {
|
|
1126
1150
|
config.agents.defaults.heartbeat = {};
|
|
1127
1151
|
}
|
|
1128
|
-
|
|
1129
|
-
|
|
1152
|
+
const m = config.agents.defaults.model;
|
|
1153
|
+
if (m !== undefined && m !== null && (typeof m !== "object" || Array.isArray(m))) {
|
|
1154
|
+
delete config.agents.defaults.model;
|
|
1130
1155
|
}
|
|
1131
1156
|
}
|
|
1132
1157
|
|
|
@@ -1189,6 +1214,9 @@ function configureOpenClawLlmProvider({ provider, model, credential }, configPat
|
|
|
1189
1214
|
if (!config.agents) config.agents = {};
|
|
1190
1215
|
if (!config.agents.defaults) config.agents.defaults = {};
|
|
1191
1216
|
ensureAgentsDefaultsSchemaCompat(config);
|
|
1217
|
+
if (!config.agents.defaults.model || typeof config.agents.defaults.model !== "object") {
|
|
1218
|
+
config.agents.defaults.model = {};
|
|
1219
|
+
}
|
|
1192
1220
|
config.agents.defaults.model.primary = model;
|
|
1193
1221
|
|
|
1194
1222
|
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
@@ -1643,6 +1671,19 @@ export class InstallerStepEngine {
|
|
|
1643
1671
|
await this.runStep("tailscale_up", "Connecting Tailscale", async () => this.runTailscaleUp());
|
|
1644
1672
|
}
|
|
1645
1673
|
if (!this.options.skipGatewayBootstrap) {
|
|
1674
|
+
await this.runStep("openclaw_config_validate", "Validating OpenClaw config (with plugins)", async () => {
|
|
1675
|
+
normalizeOpenClawConfigFileShape(CONFIG_FILE);
|
|
1676
|
+
try {
|
|
1677
|
+
await this.runWithPrivilegeGuidance("openclaw_config_validate", "openclaw", ["config", "validate"]);
|
|
1678
|
+
} catch (err) {
|
|
1679
|
+
const blob = `${err?.message || ""}\n${err?.stderr || ""}\n${err?.stdout || ""}`;
|
|
1680
|
+
if (isOpenClawConfigSchemaFailure(blob)) {
|
|
1681
|
+
throw new Error(gatewayConfigValidationRemediation());
|
|
1682
|
+
}
|
|
1683
|
+
throw err;
|
|
1684
|
+
}
|
|
1685
|
+
return { ok: true };
|
|
1686
|
+
});
|
|
1646
1687
|
await this.runStep("gateway_bootstrap", "Starting OpenClaw gateway and Funnel", async () => {
|
|
1647
1688
|
try {
|
|
1648
1689
|
normalizeOpenClawConfigFileShape(CONFIG_FILE);
|
|
@@ -1667,6 +1708,9 @@ export class InstallerStepEngine {
|
|
|
1667
1708
|
}
|
|
1668
1709
|
throw new Error(gatewayTimeoutRemediation());
|
|
1669
1710
|
}
|
|
1711
|
+
if (isOpenClawConfigSchemaFailure(text)) {
|
|
1712
|
+
throw new Error(gatewayConfigValidationRemediation());
|
|
1713
|
+
}
|
|
1670
1714
|
throw err;
|
|
1671
1715
|
}
|
|
1672
1716
|
});
|
package/package.json
CHANGED