@chrysb/alphaclaw 0.8.5 → 0.8.7-beta.0
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/alphaclaw.js +56 -20
- package/lib/public/css/explorer.css +48 -0
- package/lib/public/css/shell.css +149 -0
- package/lib/public/css/tailwind.generated.css +1 -1
- package/lib/public/css/theme.css +265 -0
- package/lib/public/dist/app.bundle.js +2441 -2352
- package/lib/public/js/app.js +7 -0
- package/lib/public/js/components/gateway.js +6 -3
- package/lib/public/js/components/general/index.js +2 -0
- package/lib/public/js/components/icons.js +38 -0
- package/lib/public/js/components/models-tab/provider-auth-card.js +60 -49
- package/lib/public/js/components/models-tab/use-models.js +74 -9
- package/lib/public/js/components/models.js +52 -37
- package/lib/public/js/components/onboarding/use-welcome-codex.js +34 -24
- package/lib/public/js/components/onboarding/welcome-config.js +76 -10
- package/lib/public/js/components/onboarding/welcome-form-step.js +31 -11
- package/lib/public/js/components/onboarding/welcome-header.js +12 -14
- package/lib/public/js/components/onboarding/welcome-setup-step.js +3 -3
- package/lib/public/js/components/providers.js +53 -42
- package/lib/public/js/components/routes/general-route.js +2 -0
- package/lib/public/js/components/routes/watchdog-route.js +2 -0
- package/lib/public/js/components/sidebar.js +29 -8
- package/lib/public/js/components/theme-toggle.js +113 -0
- package/lib/public/js/components/update-modal-helpers.js +12 -0
- package/lib/public/js/components/update-modal.js +2 -1
- package/lib/public/js/components/watchdog-tab/index.js +2 -0
- package/lib/public/js/components/welcome/index.js +1 -2
- package/lib/public/js/components/welcome/use-welcome.js +153 -38
- package/lib/public/js/hooks/use-app-shell-controller.js +33 -9
- package/lib/public/js/lib/api.js +35 -0
- package/lib/public/js/lib/codex-oauth-window.js +22 -0
- package/lib/public/js/lib/model-catalog.js +20 -0
- package/lib/public/js/lib/storage-keys.js +1 -1
- package/lib/public/login.html +8 -4
- package/lib/public/setup.html +9 -0
- package/lib/server/alphaclaw-version.js +30 -127
- package/lib/server/db/webhooks/index.js +48 -8
- package/lib/server/model-catalog-cache.js +251 -0
- package/lib/server/openclaw-version.js +59 -130
- package/lib/server/pending-alphaclaw-update.js +71 -0
- package/lib/server/pending-openclaw-update.js +71 -0
- package/lib/server/routes/models.js +14 -23
- package/lib/server/routes/system.js +6 -1
- package/lib/server/routes/webhooks.js +12 -1
- package/package.json +1 -1
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const { execSync } = require("child_process");
|
|
2
2
|
const fs = require("fs");
|
|
3
|
-
const os = require("os");
|
|
4
3
|
const path = require("path");
|
|
5
4
|
const {
|
|
6
5
|
kVersionCacheTtlMs,
|
|
7
6
|
kLatestVersionCacheTtlMs,
|
|
8
|
-
|
|
9
|
-
kOpenclawUpdateCopyTimeoutMs,
|
|
7
|
+
kRootDir,
|
|
10
8
|
} = require("./constants");
|
|
11
9
|
const { normalizeOpenclawVersion } = require("./helpers");
|
|
12
10
|
const { parseJsonObjectFromNoisyOutput } = require("./utils/json");
|
|
@@ -24,6 +22,9 @@ const createOpenclawVersionService = ({
|
|
|
24
22
|
};
|
|
25
23
|
let kOpenclawUpdateInProgress = false;
|
|
26
24
|
|
|
25
|
+
const buildOpenclawInstallSpec = (version = "latest") =>
|
|
26
|
+
`openclaw@${String(version || "").trim() || "latest"}`;
|
|
27
|
+
|
|
27
28
|
const readOpenclawVersion = () => {
|
|
28
29
|
const now = Date.now();
|
|
29
30
|
if (
|
|
@@ -87,118 +88,6 @@ const createOpenclawVersionService = ({
|
|
|
87
88
|
}
|
|
88
89
|
};
|
|
89
90
|
|
|
90
|
-
const findInstallDir = () => {
|
|
91
|
-
// Resolve the consumer app root (for example /app in Docker), not this package directory.
|
|
92
|
-
let dir = kNpmPackageRoot;
|
|
93
|
-
while (dir !== path.dirname(dir)) {
|
|
94
|
-
const parent = path.dirname(dir);
|
|
95
|
-
if (
|
|
96
|
-
path.basename(parent) === "node_modules" ||
|
|
97
|
-
parent.includes(`${path.sep}node_modules${path.sep}`)
|
|
98
|
-
) {
|
|
99
|
-
dir = parent;
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
const pkgPath = path.join(parent, "package.json");
|
|
103
|
-
if (fs.existsSync(pkgPath)) {
|
|
104
|
-
try {
|
|
105
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
106
|
-
if (
|
|
107
|
-
pkg.dependencies?.["@chrysb/alphaclaw"] ||
|
|
108
|
-
pkg.devDependencies?.["@chrysb/alphaclaw"] ||
|
|
109
|
-
pkg.optionalDependencies?.["@chrysb/alphaclaw"]
|
|
110
|
-
) {
|
|
111
|
-
return parent;
|
|
112
|
-
}
|
|
113
|
-
} catch {}
|
|
114
|
-
}
|
|
115
|
-
dir = parent;
|
|
116
|
-
}
|
|
117
|
-
return kNpmPackageRoot;
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
// Install to a temp directory, then copy into the real node_modules.
|
|
121
|
-
// Running `npm install` directly in the app dir causes EBUSY on Docker
|
|
122
|
-
// because npm tries to rename directories that the running process holds open.
|
|
123
|
-
// Copying individual files (cp -af) avoids the rename syscall entirely.
|
|
124
|
-
const installLatestOpenclaw = () =>
|
|
125
|
-
new Promise((resolve, reject) => {
|
|
126
|
-
const installDir = findInstallDir();
|
|
127
|
-
const tmpDir = fs.mkdtempSync(
|
|
128
|
-
path.join(os.tmpdir(), "openclaw-update-"),
|
|
129
|
-
);
|
|
130
|
-
const cleanup = () => {
|
|
131
|
-
try {
|
|
132
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
133
|
-
} catch {}
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
fs.writeFileSync(
|
|
137
|
-
path.join(tmpDir, "package.json"),
|
|
138
|
-
JSON.stringify({
|
|
139
|
-
private: true,
|
|
140
|
-
dependencies: { openclaw: "latest" },
|
|
141
|
-
}),
|
|
142
|
-
);
|
|
143
|
-
|
|
144
|
-
const npmEnv = {
|
|
145
|
-
...process.env,
|
|
146
|
-
npm_config_update_notifier: "false",
|
|
147
|
-
npm_config_fund: "false",
|
|
148
|
-
npm_config_audit: "false",
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
console.log(
|
|
152
|
-
`[alphaclaw] Running: npm install openclaw@latest in temp dir (target: ${installDir})`,
|
|
153
|
-
);
|
|
154
|
-
exec(
|
|
155
|
-
"npm install --omit=dev --prefer-online --package-lock=false",
|
|
156
|
-
{ cwd: tmpDir, env: npmEnv, timeout: 180000 },
|
|
157
|
-
(installErr, stdout, stderr) => {
|
|
158
|
-
if (installErr) {
|
|
159
|
-
const message = String(stderr || installErr.message || "").trim();
|
|
160
|
-
console.log(
|
|
161
|
-
`[alphaclaw] openclaw install error: ${message.slice(0, 200)}`,
|
|
162
|
-
);
|
|
163
|
-
cleanup();
|
|
164
|
-
return reject(
|
|
165
|
-
new Error(message || "Failed to install openclaw@latest"),
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
if (stdout?.trim()) {
|
|
169
|
-
console.log(
|
|
170
|
-
`[alphaclaw] openclaw install stdout: ${stdout.trim().slice(0, 300)}`,
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const src = path.join(tmpDir, "node_modules");
|
|
175
|
-
const dest = path.join(installDir, "node_modules");
|
|
176
|
-
exec(
|
|
177
|
-
`cp -af "${src}/." "${dest}/"`,
|
|
178
|
-
{ timeout: kOpenclawUpdateCopyTimeoutMs },
|
|
179
|
-
(cpErr) => {
|
|
180
|
-
cleanup();
|
|
181
|
-
if (cpErr) {
|
|
182
|
-
console.log(
|
|
183
|
-
`[alphaclaw] openclaw copy error: ${(cpErr.message || "").slice(0, 200)}`,
|
|
184
|
-
);
|
|
185
|
-
return reject(
|
|
186
|
-
new Error(
|
|
187
|
-
`Failed to copy updated openclaw files: ${cpErr.message}`,
|
|
188
|
-
),
|
|
189
|
-
);
|
|
190
|
-
}
|
|
191
|
-
console.log("[alphaclaw] openclaw install completed");
|
|
192
|
-
resolve({
|
|
193
|
-
stdout: stdout?.trim() || "",
|
|
194
|
-
stderr: stderr?.trim() || "",
|
|
195
|
-
});
|
|
196
|
-
},
|
|
197
|
-
);
|
|
198
|
-
},
|
|
199
|
-
);
|
|
200
|
-
});
|
|
201
|
-
|
|
202
91
|
const getVersionStatus = async (refresh) => {
|
|
203
92
|
const currentVersion = readOpenclawVersion();
|
|
204
93
|
try {
|
|
@@ -228,27 +117,67 @@ const createOpenclawVersionService = ({
|
|
|
228
117
|
kOpenclawUpdateInProgress = true;
|
|
229
118
|
const previousVersion = readOpenclawVersion();
|
|
230
119
|
try {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
120
|
+
let latestVersion = null;
|
|
121
|
+
let hasUpdate = false;
|
|
122
|
+
try {
|
|
123
|
+
const updateStatus = readOpenclawUpdateStatus({ refresh: true });
|
|
124
|
+
latestVersion = updateStatus.latestVersion || null;
|
|
125
|
+
hasUpdate = !!updateStatus.hasUpdate;
|
|
126
|
+
} catch (error) {
|
|
127
|
+
console.log(
|
|
128
|
+
`[alphaclaw] Could not resolve exact OpenClaw version before restart: ${error.message || "unknown error"}`,
|
|
129
|
+
);
|
|
241
130
|
}
|
|
131
|
+
|
|
132
|
+
if (!hasUpdate && latestVersion && latestVersion === previousVersion) {
|
|
133
|
+
return {
|
|
134
|
+
status: 200,
|
|
135
|
+
body: {
|
|
136
|
+
ok: true,
|
|
137
|
+
previousVersion,
|
|
138
|
+
currentVersion: previousVersion,
|
|
139
|
+
latestVersion,
|
|
140
|
+
hasUpdate: false,
|
|
141
|
+
restarted: false,
|
|
142
|
+
restarting: false,
|
|
143
|
+
updated: false,
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const targetVersion = latestVersion || "latest";
|
|
149
|
+
const spec = buildOpenclawInstallSpec(targetVersion);
|
|
150
|
+
const markerPath = path.join(kRootDir, ".openclaw-update-pending");
|
|
151
|
+
fs.writeFileSync(
|
|
152
|
+
markerPath,
|
|
153
|
+
JSON.stringify({
|
|
154
|
+
from: previousVersion,
|
|
155
|
+
to: targetVersion,
|
|
156
|
+
spec,
|
|
157
|
+
ts: Date.now(),
|
|
158
|
+
}),
|
|
159
|
+
);
|
|
160
|
+
console.log(
|
|
161
|
+
`[alphaclaw] OpenClaw update marker written to ${markerPath} for ${spec}`,
|
|
162
|
+
);
|
|
163
|
+
kOpenclawVersionCache = { value: previousVersion, fetchedAt: 0 };
|
|
164
|
+
kOpenclawUpdateStatusCache = {
|
|
165
|
+
latestVersion,
|
|
166
|
+
hasUpdate,
|
|
167
|
+
fetchedAt: 0,
|
|
168
|
+
};
|
|
242
169
|
return {
|
|
243
170
|
status: 200,
|
|
244
171
|
body: {
|
|
245
172
|
ok: true,
|
|
246
173
|
previousVersion,
|
|
247
|
-
currentVersion,
|
|
174
|
+
currentVersion: previousVersion,
|
|
175
|
+
targetVersion: targetVersion === "latest" ? null : targetVersion,
|
|
248
176
|
latestVersion,
|
|
249
|
-
hasUpdate,
|
|
250
|
-
restarted,
|
|
251
|
-
|
|
177
|
+
hasUpdate: true,
|
|
178
|
+
restarted: false,
|
|
179
|
+
restarting: true,
|
|
180
|
+
updated: previousVersion !== targetVersion,
|
|
252
181
|
},
|
|
253
182
|
};
|
|
254
183
|
} catch (err) {
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const buildPendingAlphaclawInstallSpec = (marker = {}) => {
|
|
2
|
+
const explicitSpec = String(marker?.spec || "").trim();
|
|
3
|
+
if (explicitSpec) {
|
|
4
|
+
return explicitSpec;
|
|
5
|
+
}
|
|
6
|
+
const targetVersion = String(marker?.to || "").trim() || "latest";
|
|
7
|
+
return `@chrysb/alphaclaw@${targetVersion}`;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const shellQuote = (value) =>
|
|
11
|
+
`'${String(value || "").replace(/'/g, `'\"'\"'`)}'`;
|
|
12
|
+
|
|
13
|
+
const applyPendingAlphaclawUpdate = ({
|
|
14
|
+
execSyncImpl,
|
|
15
|
+
fsModule,
|
|
16
|
+
installDir,
|
|
17
|
+
logger = console,
|
|
18
|
+
markerPath,
|
|
19
|
+
}) => {
|
|
20
|
+
if (!fsModule.existsSync(markerPath)) {
|
|
21
|
+
return {
|
|
22
|
+
attempted: false,
|
|
23
|
+
installed: false,
|
|
24
|
+
spec: "",
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let marker = {};
|
|
29
|
+
try {
|
|
30
|
+
marker = JSON.parse(fsModule.readFileSync(markerPath, "utf8"));
|
|
31
|
+
} catch {
|
|
32
|
+
marker = {};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const spec = buildPendingAlphaclawInstallSpec(marker);
|
|
36
|
+
logger.log(`[alphaclaw] Pending update detected, installing ${spec}...`);
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
execSyncImpl(
|
|
40
|
+
`npm install ${shellQuote(spec)} --omit=dev --no-save --save=false --package-lock=false --prefer-online`,
|
|
41
|
+
{
|
|
42
|
+
cwd: installDir,
|
|
43
|
+
stdio: "inherit",
|
|
44
|
+
timeout: 180000,
|
|
45
|
+
},
|
|
46
|
+
);
|
|
47
|
+
fsModule.unlinkSync(markerPath);
|
|
48
|
+
logger.log("[alphaclaw] Update applied successfully");
|
|
49
|
+
return {
|
|
50
|
+
attempted: true,
|
|
51
|
+
installed: true,
|
|
52
|
+
spec,
|
|
53
|
+
};
|
|
54
|
+
} catch (error) {
|
|
55
|
+
logger.log(`[alphaclaw] Update install failed: ${error.message}`);
|
|
56
|
+
try {
|
|
57
|
+
fsModule.unlinkSync(markerPath);
|
|
58
|
+
} catch {}
|
|
59
|
+
return {
|
|
60
|
+
attempted: true,
|
|
61
|
+
installed: false,
|
|
62
|
+
spec,
|
|
63
|
+
error,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
module.exports = {
|
|
69
|
+
applyPendingAlphaclawUpdate,
|
|
70
|
+
buildPendingAlphaclawInstallSpec,
|
|
71
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const buildPendingOpenclawInstallSpec = (marker = {}) => {
|
|
2
|
+
const explicitSpec = String(marker?.spec || "").trim();
|
|
3
|
+
if (explicitSpec) {
|
|
4
|
+
return explicitSpec;
|
|
5
|
+
}
|
|
6
|
+
const targetVersion = String(marker?.to || "").trim() || "latest";
|
|
7
|
+
return `openclaw@${targetVersion}`;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const shellQuote = (value) =>
|
|
11
|
+
`'${String(value || "").replace(/'/g, `'\"'\"'`)}'`;
|
|
12
|
+
|
|
13
|
+
const applyPendingOpenclawUpdate = ({
|
|
14
|
+
execSyncImpl,
|
|
15
|
+
fsModule,
|
|
16
|
+
installDir,
|
|
17
|
+
logger = console,
|
|
18
|
+
markerPath,
|
|
19
|
+
}) => {
|
|
20
|
+
if (!fsModule.existsSync(markerPath)) {
|
|
21
|
+
return {
|
|
22
|
+
attempted: false,
|
|
23
|
+
installed: false,
|
|
24
|
+
spec: "",
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let marker = {};
|
|
29
|
+
try {
|
|
30
|
+
marker = JSON.parse(fsModule.readFileSync(markerPath, "utf8"));
|
|
31
|
+
} catch {
|
|
32
|
+
marker = {};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const spec = buildPendingOpenclawInstallSpec(marker);
|
|
36
|
+
logger.log(`[alphaclaw] Pending OpenClaw update detected, installing ${spec}...`);
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
execSyncImpl(
|
|
40
|
+
`npm install ${shellQuote(spec)} --omit=dev --no-save --save=false --package-lock=false --prefer-online`,
|
|
41
|
+
{
|
|
42
|
+
cwd: installDir,
|
|
43
|
+
stdio: "inherit",
|
|
44
|
+
timeout: 180000,
|
|
45
|
+
},
|
|
46
|
+
);
|
|
47
|
+
fsModule.unlinkSync(markerPath);
|
|
48
|
+
logger.log("[alphaclaw] OpenClaw update applied successfully");
|
|
49
|
+
return {
|
|
50
|
+
attempted: true,
|
|
51
|
+
installed: true,
|
|
52
|
+
spec,
|
|
53
|
+
};
|
|
54
|
+
} catch (error) {
|
|
55
|
+
logger.log(`[alphaclaw] OpenClaw update install failed: ${error.message}`);
|
|
56
|
+
try {
|
|
57
|
+
fsModule.unlinkSync(markerPath);
|
|
58
|
+
} catch {}
|
|
59
|
+
return {
|
|
60
|
+
attempted: true,
|
|
61
|
+
installed: false,
|
|
62
|
+
spec,
|
|
63
|
+
error,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
module.exports = {
|
|
69
|
+
applyPendingOpenclawUpdate,
|
|
70
|
+
buildPendingOpenclawInstallSpec,
|
|
71
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const { kFallbackOnboardingModels } = require("../constants");
|
|
2
|
+
const { createModelCatalogCache } = require("../model-catalog-cache");
|
|
2
3
|
|
|
3
4
|
const runModelsGitSync = async (shellCmd) => {
|
|
4
5
|
if (typeof shellCmd !== "function") return null;
|
|
@@ -22,6 +23,13 @@ const registerModelRoutes = ({
|
|
|
22
23
|
readEnvFile,
|
|
23
24
|
writeEnvFile,
|
|
24
25
|
reloadEnv,
|
|
26
|
+
modelCatalogCache = createModelCatalogCache({
|
|
27
|
+
shellCmd,
|
|
28
|
+
gatewayEnv,
|
|
29
|
+
parseJsonFromNoisyOutput,
|
|
30
|
+
normalizeOnboardingModels,
|
|
31
|
+
fallbackModels: kFallbackOnboardingModels,
|
|
32
|
+
}),
|
|
25
33
|
}) => {
|
|
26
34
|
const upsertEnvVar = (items, key, value) => {
|
|
27
35
|
const next = Array.isArray(items) ? [...items] : [];
|
|
@@ -154,29 +162,8 @@ const registerModelRoutes = ({
|
|
|
154
162
|
// ── Existing CLI-backed catalog/status routes ──
|
|
155
163
|
|
|
156
164
|
app.get("/api/models", async (req, res) => {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
env: gatewayEnv(),
|
|
160
|
-
timeout: 20000,
|
|
161
|
-
});
|
|
162
|
-
const parsed = parseJsonFromNoisyOutput(output);
|
|
163
|
-
const models = normalizeOnboardingModels(parsed?.models || []);
|
|
164
|
-
if (models.length > 0) {
|
|
165
|
-
return res.json({ ok: true, source: "openclaw", models });
|
|
166
|
-
}
|
|
167
|
-
return res.json({
|
|
168
|
-
ok: true,
|
|
169
|
-
source: "fallback",
|
|
170
|
-
models: kFallbackOnboardingModels,
|
|
171
|
-
});
|
|
172
|
-
} catch (err) {
|
|
173
|
-
console.error("[models] Failed to load dynamic models:", err.message);
|
|
174
|
-
return res.json({
|
|
175
|
-
ok: true,
|
|
176
|
-
source: "fallback",
|
|
177
|
-
models: kFallbackOnboardingModels,
|
|
178
|
-
});
|
|
179
|
-
}
|
|
165
|
+
const response = await modelCatalogCache.getCatalogResponse();
|
|
166
|
+
return res.json(response);
|
|
180
167
|
});
|
|
181
168
|
|
|
182
169
|
app.get("/api/models/status", async (req, res) => {
|
|
@@ -210,6 +197,7 @@ const registerModelRoutes = ({
|
|
|
210
197
|
env: gatewayEnv(),
|
|
211
198
|
timeout: 30000,
|
|
212
199
|
});
|
|
200
|
+
modelCatalogCache.markStale();
|
|
213
201
|
res.json({ ok: true });
|
|
214
202
|
} catch (err) {
|
|
215
203
|
res
|
|
@@ -286,6 +274,7 @@ const registerModelRoutes = ({
|
|
|
286
274
|
authProfiles.syncConfigAuthReferencesForAgent(agentId);
|
|
287
275
|
|
|
288
276
|
const syncWarning = await runModelsGitSync(shellCmd);
|
|
277
|
+
modelCatalogCache.markStale();
|
|
289
278
|
res.json({
|
|
290
279
|
ok: true,
|
|
291
280
|
...(syncWarning ? { syncWarning } : {}),
|
|
@@ -338,6 +327,7 @@ const registerModelRoutes = ({
|
|
|
338
327
|
const agentId = req.query.agentId || undefined;
|
|
339
328
|
authProfiles.upsertProfile(profileId, credential, agentId);
|
|
340
329
|
syncEnvVarsForProfiles([{ id: profileId, ...credential }]);
|
|
330
|
+
modelCatalogCache.markStale();
|
|
341
331
|
res.json({ ok: true });
|
|
342
332
|
} catch (err) {
|
|
343
333
|
res
|
|
@@ -359,6 +349,7 @@ const registerModelRoutes = ({
|
|
|
359
349
|
try {
|
|
360
350
|
const agentId = req.query.agentId || undefined;
|
|
361
351
|
const removed = authProfiles.removeProfile(profileId, agentId);
|
|
352
|
+
modelCatalogCache.markStale();
|
|
362
353
|
res.json({ ok: true, removed });
|
|
363
354
|
} catch (err) {
|
|
364
355
|
res
|
|
@@ -588,7 +588,12 @@ const registerSystemRoutes = ({
|
|
|
588
588
|
console.log(
|
|
589
589
|
`[alphaclaw] /api/openclaw/update result: status=${result.status} ok=${result.body?.ok === true}`,
|
|
590
590
|
);
|
|
591
|
-
|
|
591
|
+
if (result.status === 200 && result.body?.ok && result.body?.restarting) {
|
|
592
|
+
res.json(result.body);
|
|
593
|
+
setTimeout(() => alphaclawVersionService.restartProcess(), 1000);
|
|
594
|
+
} else {
|
|
595
|
+
res.status(result.status).json(result.body);
|
|
596
|
+
}
|
|
592
597
|
});
|
|
593
598
|
|
|
594
599
|
app.get("/api/alphaclaw/version", async (req, res) => {
|
|
@@ -29,13 +29,24 @@ const mergeWebhookAndSummary = ({ webhook, summary }) => {
|
|
|
29
29
|
const totalCount = Number(summary?.totalCount || 0);
|
|
30
30
|
const errorCount = Number(summary?.errorCount || 0);
|
|
31
31
|
const successCount = Number(summary?.successCount || 0);
|
|
32
|
+
const recentTotalCount = Number(summary?.recentTotalCount || 0);
|
|
33
|
+
const recentErrorCount = Number(summary?.recentErrorCount || 0);
|
|
34
|
+
const recentSuccessCount = Number(summary?.recentSuccessCount || 0);
|
|
35
|
+
const healthWindowSize = Number(summary?.healthWindowSize || 0);
|
|
32
36
|
return {
|
|
33
37
|
...webhook,
|
|
34
38
|
lastReceived: summary?.lastReceived || null,
|
|
35
39
|
totalCount,
|
|
36
40
|
successCount,
|
|
37
41
|
errorCount,
|
|
38
|
-
|
|
42
|
+
recentTotalCount,
|
|
43
|
+
recentSuccessCount,
|
|
44
|
+
recentErrorCount,
|
|
45
|
+
healthWindowSize,
|
|
46
|
+
health: buildHealth({
|
|
47
|
+
totalCount: recentTotalCount || totalCount,
|
|
48
|
+
errorCount: recentTotalCount > 0 ? recentErrorCount : errorCount,
|
|
49
|
+
}),
|
|
39
50
|
};
|
|
40
51
|
};
|
|
41
52
|
|