jishushell 0.4.17 → 0.4.24
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/Dockerfile.hermes-slim +193 -0
- package/apps/hermes-container.yaml +35 -0
- package/apps/ollama-binary.yaml +200 -0
- package/apps/ollama-cpu-container.yaml +37 -0
- package/apps/ollama-with-hollama-binary.yaml +195 -0
- package/apps/openclaw-binary.yaml +69 -0
- package/apps/openclaw-container.yaml +37 -0
- package/apps/openclaw-with-ollama-container.yaml +42 -0
- package/apps/openclaw-with-searxng-container.yaml +136 -0
- package/apps/openwebui-container.yaml +53 -0
- package/apps/playwright-container.yaml +120 -0
- package/apps/searxng-container.yaml +115 -0
- package/dist/auth.d.ts +1 -0
- package/dist/auth.js +15 -14
- package/dist/auth.js.map +1 -1
- package/dist/cli/app.d.ts +1 -0
- package/dist/cli/app.js +710 -52
- package/dist/cli/app.js.map +1 -1
- package/dist/cli/backup.d.ts +3 -0
- package/dist/cli/backup.js +434 -0
- package/dist/cli/backup.js.map +1 -0
- package/dist/cli/doctor.d.ts +1 -0
- package/dist/cli/doctor.js +61 -35
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/job.d.ts +1 -0
- package/dist/cli/job.js +37 -99
- package/dist/cli/job.js.map +1 -1
- package/dist/cli/llm.d.ts +1 -0
- package/dist/cli/llm.js +20 -14
- package/dist/cli/llm.js.map +1 -1
- package/dist/cli/managed-list.d.ts +30 -0
- package/dist/cli/managed-list.js +129 -0
- package/dist/cli/managed-list.js.map +1 -0
- package/dist/cli/panel.d.ts +4 -3
- package/dist/cli/panel.js +94 -24
- package/dist/cli/panel.js.map +1 -1
- package/dist/cli/version.d.ts +1 -0
- package/dist/cli/version.js +12 -0
- package/dist/cli/version.js.map +1 -0
- package/dist/cli.js +47 -516
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +68 -0
- package/dist/config.js +266 -12
- package/dist/config.js.map +1 -1
- package/dist/control.d.ts +10 -6
- package/dist/control.js +87 -6
- package/dist/control.js.map +1 -1
- package/dist/install.d.ts +16 -0
- package/dist/install.js +75 -26
- package/dist/install.js.map +1 -1
- package/dist/routes/agent-apps.d.ts +15 -0
- package/dist/routes/agent-apps.js +78 -0
- package/dist/routes/agent-apps.js.map +1 -0
- package/dist/routes/apps.js +186 -7
- package/dist/routes/apps.js.map +1 -1
- package/dist/routes/backup.js +3 -3
- package/dist/routes/backup.js.map +1 -1
- package/dist/routes/instances.d.ts +6 -0
- package/dist/routes/instances.js +862 -879
- package/dist/routes/instances.js.map +1 -1
- package/dist/routes/llm.js +9 -8
- package/dist/routes/llm.js.map +1 -1
- package/dist/routes/runtime.d.ts +15 -0
- package/dist/routes/runtime.js +69 -0
- package/dist/routes/runtime.js.map +1 -0
- package/dist/routes/setup.js +103 -8
- package/dist/routes/setup.js.map +1 -1
- package/dist/routes/system.js +25 -3
- package/dist/routes/system.js.map +1 -1
- package/dist/server.js +71 -7
- package/dist/server.js.map +1 -1
- package/dist/services/agent-apps/catalog.d.ts +30 -0
- package/dist/services/agent-apps/catalog.js +60 -0
- package/dist/services/agent-apps/catalog.js.map +1 -0
- package/dist/services/agent-apps/index.d.ts +36 -0
- package/dist/services/agent-apps/index.js +171 -0
- package/dist/services/agent-apps/index.js.map +1 -0
- package/dist/services/agent-apps/installers/adapter-probes.d.ts +49 -0
- package/dist/services/agent-apps/installers/adapter-probes.js +223 -0
- package/dist/services/agent-apps/installers/adapter-probes.js.map +1 -0
- package/dist/services/agent-apps/installers/adapter.d.ts +30 -0
- package/dist/services/agent-apps/installers/adapter.js +171 -0
- package/dist/services/agent-apps/installers/adapter.js.map +1 -0
- package/dist/services/agent-apps/installers/registry-probe.d.ts +38 -0
- package/dist/services/agent-apps/installers/registry-probe.js +183 -0
- package/dist/services/agent-apps/installers/registry-probe.js.map +1 -0
- package/dist/services/agent-apps/installers/shell-script.d.ts +47 -0
- package/dist/services/agent-apps/installers/shell-script.js +471 -0
- package/dist/services/agent-apps/installers/shell-script.js.map +1 -0
- package/dist/services/agent-apps/types.d.ts +125 -0
- package/dist/services/agent-apps/types.js +17 -0
- package/dist/services/agent-apps/types.js.map +1 -0
- package/dist/services/{app-compiler.d.ts → app/app-compiler.d.ts} +3 -3
- package/dist/services/{app-compiler.js → app/app-compiler.js} +10 -7
- package/dist/services/app/app-compiler.js.map +1 -0
- package/dist/services/app/app-manager.d.ts +142 -0
- package/dist/services/app/app-manager.js +1988 -0
- package/dist/services/app/app-manager.js.map +1 -0
- package/dist/services/app/custom-manager.d.ts +27 -0
- package/dist/services/app/custom-manager.js +285 -0
- package/dist/services/app/custom-manager.js.map +1 -0
- package/dist/services/app/hermes-agent-manager.d.ts +20 -0
- package/dist/services/app/hermes-agent-manager.js +289 -0
- package/dist/services/app/hermes-agent-manager.js.map +1 -0
- package/dist/services/app/id-normalizer.d.ts +27 -0
- package/dist/services/app/id-normalizer.js +77 -0
- package/dist/services/app/id-normalizer.js.map +1 -0
- package/dist/services/app/ollama-manager.d.ts +18 -0
- package/dist/services/app/ollama-manager.js +207 -0
- package/dist/services/app/ollama-manager.js.map +1 -0
- package/dist/services/app/openclaw-manager.d.ts +63 -0
- package/dist/services/app/openclaw-manager.js +1178 -0
- package/dist/services/app/openclaw-manager.js.map +1 -0
- package/dist/services/app/paths.d.ts +47 -0
- package/dist/services/app/paths.js +68 -0
- package/dist/services/app/paths.js.map +1 -0
- package/dist/services/app/registry.d.ts +17 -0
- package/dist/services/app/registry.js +31 -0
- package/dist/services/app/registry.js.map +1 -0
- package/dist/services/app/remote-spec.d.ts +14 -0
- package/dist/services/app/remote-spec.js +58 -0
- package/dist/services/app/remote-spec.js.map +1 -0
- package/dist/services/app/terminal-session-manager.d.ts +27 -0
- package/dist/services/app/terminal-session-manager.js +157 -0
- package/dist/services/app/terminal-session-manager.js.map +1 -0
- package/dist/services/app/types.d.ts +72 -0
- package/dist/services/app/types.js +16 -0
- package/dist/services/app/types.js.map +1 -0
- package/dist/services/backup-manager.js +60 -22
- package/dist/services/backup-manager.js.map +1 -1
- package/dist/services/instance-manager.d.ts +82 -39
- package/dist/services/instance-manager.js +575 -1142
- package/dist/services/instance-manager.js.map +1 -1
- package/dist/services/llm-proxy/circuit-breaker.js +10 -2
- package/dist/services/llm-proxy/circuit-breaker.js.map +1 -1
- package/dist/services/llm-proxy/index.d.ts +14 -1
- package/dist/services/llm-proxy/index.js +51 -6
- package/dist/services/llm-proxy/index.js.map +1 -1
- package/dist/services/nomad-manager.d.ts +260 -3
- package/dist/services/nomad-manager.js +2866 -449
- package/dist/services/nomad-manager.js.map +1 -1
- package/dist/services/panel-manager.d.ts +10 -0
- package/dist/services/panel-manager.js +97 -0
- package/dist/services/panel-manager.js.map +1 -1
- package/dist/services/plugin-installer.js +28 -2
- package/dist/services/plugin-installer.js.map +1 -1
- package/dist/services/process-manager.js +22 -0
- package/dist/services/process-manager.js.map +1 -1
- package/dist/services/runtime/adapters/custom.d.ts +20 -0
- package/dist/services/runtime/adapters/custom.js +90 -0
- package/dist/services/runtime/adapters/custom.js.map +1 -0
- package/dist/services/runtime/adapters/hermes.d.ts +174 -0
- package/dist/services/runtime/adapters/hermes.js +1316 -0
- package/dist/services/runtime/adapters/hermes.js.map +1 -0
- package/dist/services/runtime/adapters/openclaw-routes.d.ts +17 -0
- package/dist/services/runtime/adapters/openclaw-routes.js +946 -0
- package/dist/services/runtime/adapters/openclaw-routes.js.map +1 -0
- package/dist/services/runtime/adapters/openclaw.d.ts +188 -0
- package/dist/services/runtime/adapters/openclaw.js +2195 -0
- package/dist/services/runtime/adapters/openclaw.js.map +1 -0
- package/dist/services/runtime/errors.d.ts +28 -0
- package/dist/services/runtime/errors.js +31 -0
- package/dist/services/runtime/errors.js.map +1 -0
- package/dist/services/runtime/index.d.ts +34 -0
- package/dist/services/runtime/index.js +51 -0
- package/dist/services/runtime/index.js.map +1 -0
- package/dist/services/runtime/instance.d.ts +24 -0
- package/dist/services/runtime/instance.js +143 -0
- package/dist/services/runtime/instance.js.map +1 -0
- package/dist/services/runtime/migrations.d.ts +15 -0
- package/dist/services/runtime/migrations.js +25 -0
- package/dist/services/runtime/migrations.js.map +1 -0
- package/dist/services/runtime/registry.d.ts +13 -0
- package/dist/services/runtime/registry.js +32 -0
- package/dist/services/runtime/registry.js.map +1 -0
- package/dist/services/runtime/types.d.ts +545 -0
- package/dist/services/runtime/types.js +14 -0
- package/dist/services/runtime/types.js.map +1 -0
- package/dist/services/setup-manager.d.ts +70 -29
- package/dist/services/setup-manager.js +278 -597
- package/dist/services/setup-manager.js.map +1 -1
- package/dist/services/task-registry.d.ts +44 -0
- package/dist/services/task-registry.js +74 -0
- package/dist/services/task-registry.js.map +1 -0
- package/dist/services/telemetry/heartbeat.d.ts +6 -6
- package/dist/services/telemetry/heartbeat.js +29 -30
- package/dist/services/telemetry/heartbeat.js.map +1 -1
- package/dist/types.d.ts +162 -2
- package/dist/utils/docker-host.d.ts +15 -0
- package/dist/utils/docker-host.js +64 -0
- package/dist/utils/docker-host.js.map +1 -0
- package/install/jishu-install.sh +25 -1
- package/package.json +14 -4
- package/public/assets/Dashboard-B-JoOjBQ.js +1 -0
- package/public/assets/HermesChatPanel-mFSureyc.js +1 -0
- package/public/assets/HermesConfigForm-DvR05LK1.js +4 -0
- package/public/assets/InitPassword-CVA8wQA6.js +1 -0
- package/public/assets/InstanceDetail-DcZW2QGO.js +91 -0
- package/public/assets/{Login-D1Bt-Lyk.js → Login-BWsZH2mu.js} +1 -1
- package/public/assets/NewInstance-BCIrAd86.js +1 -0
- package/public/assets/Settings-xkDcduFz.js +1 -0
- package/public/assets/Setup-Cfuwj4gV.js +1 -0
- package/public/assets/WeixinLoginPanel-CnjR8xMu.js +9 -0
- package/public/assets/index-CPhVFEsx.css +1 -0
- package/public/assets/index-DQsM6Joa.js +19 -0
- package/public/assets/input-paste-CrNVAyOy.js +1 -0
- package/public/assets/registry-B4UFJdpA.js +2 -0
- package/public/assets/{usePolling-CK0DfI4h.js → usePolling-Do5Erqm_.js} +1 -1
- package/public/assets/vendor-i18n-ucpM0OR0.js +9 -0
- package/public/assets/{vendor-react-B1-3Yrt-.js → vendor-react-Bk1hRGiY.js} +1 -1
- package/public/favicon.png +0 -0
- package/public/index.html +9 -4
- package/public/logos/hermes.png +0 -0
- package/public/logos/ollama.png +0 -0
- package/public/logos/openclaw.svg +60 -0
- package/scripts/build-hermes-image.sh +21 -0
- package/scripts/build-local.sh +54 -0
- package/scripts/check-adapter-isolation.ts +293 -0
- package/scripts/fixtures/instances/hermes-sample/instance.json +37 -0
- package/scripts/fixtures/instances/legacy-openclaw-sample/instance.json +7 -0
- package/scripts/smoke/hermes-bootstrap.sh +195 -0
- package/templates/hermes-entrypoint.sh +154 -0
- package/dist/cli/openclaw.d.ts +0 -12
- package/dist/cli/openclaw.js +0 -156
- package/dist/cli/openclaw.js.map +0 -1
- package/dist/services/app-compiler.js.map +0 -1
- package/dist/services/app-manager.d.ts +0 -17
- package/dist/services/app-manager.js +0 -168
- package/dist/services/app-manager.js.map +0 -1
- package/dist/services/job-manager.d.ts +0 -22
- package/dist/services/job-manager.js +0 -102
- package/dist/services/job-manager.js.map +0 -1
- package/public/assets/Dashboard-CQsp1Mr9.js +0 -1
- package/public/assets/InitPassword-BEC8SE4A.js +0 -1
- package/public/assets/InstanceDetail-B5wTgNEg.js +0 -17
- package/public/assets/NewInstance-GQzm3K9D.js +0 -1
- package/public/assets/Settings-ByjGlqhP.js +0 -1
- package/public/assets/Setup-cMF21Y-8.js +0 -1
- package/public/assets/index-B6qQP4mH.css +0 -1
- package/public/assets/index-BuTQtuNy.js +0 -16
- package/public/assets/vendor-i18n-CfW0RvgE.js +0 -9
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent apps module — unified catalog + install dispatcher for user-
|
|
3
|
+
* installable software around the agent ecosystem (agent runtimes, agent
|
|
4
|
+
* support services, agent-related CLI tools).
|
|
5
|
+
*
|
|
6
|
+
* Public surface:
|
|
7
|
+
* - `listAgentApps()` — card-shaped view backing `GET /api/agent-apps`
|
|
8
|
+
* - `getAgentApp(id)` — single entry lookup
|
|
9
|
+
* - `startAgentAppInstall(id)` — kicks off install/update, returns task id
|
|
10
|
+
*/
|
|
11
|
+
import type { AgentAppCardView, InstallStartResult } from "./types.js";
|
|
12
|
+
export type { AgentAppCardView, AgentAppStatus, InstallStartResult } from "./types.js";
|
|
13
|
+
export declare function listAgentApps(): Promise<AgentAppCardView[]>;
|
|
14
|
+
export declare function getAgentApp(id: string): Promise<AgentAppCardView | null>;
|
|
15
|
+
export declare function startAgentAppInstall(id: string, options?: Record<string, any>): Promise<InstallStartResult>;
|
|
16
|
+
/**
|
|
17
|
+
* Backs `POST /api/agent-apps/check-updates`. Runs the update probe for
|
|
18
|
+
* every app across all installer kinds in parallel. Slow networks can take
|
|
19
|
+
* tens of seconds — the endpoint holds the connection until all probes
|
|
20
|
+
* complete or time out individually.
|
|
21
|
+
*
|
|
22
|
+
* - adapter kind: registry HTTPS digest comparison (cached)
|
|
23
|
+
* - shell-script kind: GitHub Releases API tag vs installed version (direct,
|
|
24
|
+
* no cache yet; light-weight call so acceptable)
|
|
25
|
+
*/
|
|
26
|
+
export declare function checkAllAgentAppUpdates(): Promise<{
|
|
27
|
+
checkedAt: number;
|
|
28
|
+
results: Record<string, boolean | null>;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* Newest "last checked" timestamp across all installer kinds. The UI
|
|
32
|
+
* ("上次检查更新:2 分钟前") reads this — it doesn't care which installer
|
|
33
|
+
* owned the probe, only when *any* probe last finished.
|
|
34
|
+
*/
|
|
35
|
+
export declare function getAgentAppUpdatesLastCheckedAt(): number | null;
|
|
36
|
+
export declare function startAgentAppUninstall(id: string): Promise<InstallStartResult>;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent apps module — unified catalog + install dispatcher for user-
|
|
3
|
+
* installable software around the agent ecosystem (agent runtimes, agent
|
|
4
|
+
* support services, agent-related CLI tools).
|
|
5
|
+
*
|
|
6
|
+
* Public surface:
|
|
7
|
+
* - `listAgentApps()` — card-shaped view backing `GET /api/agent-apps`
|
|
8
|
+
* - `getAgentApp(id)` — single entry lookup
|
|
9
|
+
* - `startAgentAppInstall(id)` — kicks off install/update, returns task id
|
|
10
|
+
*/
|
|
11
|
+
import { AGENT_APP_CATALOG, getCatalogEntry } from "./catalog.js";
|
|
12
|
+
import { countInstancesUsingAgentType, findRunningAdapterTask, forceRefreshAllAdapterUpdates, getUpdateCacheLastCheckedAt, probeAdapterImageSizeMB, probeAdapterStatus, probeAdapterUpdateAvailable, startAdapterInstall, startAdapterUninstall, } from "./installers/adapter.js";
|
|
13
|
+
import { findRunningShellScriptTask, getShellScriptUpdateCacheLastCheckedAt, probeShellScriptSizeMB, probeShellScriptStatus, readShellScriptUpdateAvailable, refreshShellScriptUpdateCache, startShellScriptInstall, startShellScriptUninstall, } from "./installers/shell-script.js";
|
|
14
|
+
async function buildCardView(entry) {
|
|
15
|
+
const status = { installed: false };
|
|
16
|
+
let diskSpaceMB = null;
|
|
17
|
+
if (entry.source.kind === "adapter") {
|
|
18
|
+
// Probe status + size + update-availability in parallel. Each docker
|
|
19
|
+
// shell call has its own short timeout so a slow daemon degrades to
|
|
20
|
+
// "unknown" fields rather than hanging the whole catalog response.
|
|
21
|
+
const [probe, sizeMB, updateAvailable] = await Promise.all([
|
|
22
|
+
probeAdapterStatus(entry.source.agentType),
|
|
23
|
+
probeAdapterImageSizeMB(entry.source.agentType),
|
|
24
|
+
probeAdapterUpdateAvailable(entry.source.agentType),
|
|
25
|
+
]);
|
|
26
|
+
if (probe) {
|
|
27
|
+
status.installed = probe.installed;
|
|
28
|
+
status.imageReady = probe.imageReady;
|
|
29
|
+
status.version = probe.version;
|
|
30
|
+
status.digest = probe.digest;
|
|
31
|
+
}
|
|
32
|
+
const running = findRunningAdapterTask(entry.source.agentType);
|
|
33
|
+
status.currentTaskId = running?.id;
|
|
34
|
+
status.currentTaskKind = running?.kind;
|
|
35
|
+
status.updateAvailable = status.installed ? updateAvailable : null;
|
|
36
|
+
diskSpaceMB = sizeMB;
|
|
37
|
+
}
|
|
38
|
+
else if (entry.source.kind === "shell-script") {
|
|
39
|
+
// Hot-path probes only. Update availability is a cached read (written
|
|
40
|
+
// by `checkAllAgentAppUpdates`) — this branch never makes an outbound
|
|
41
|
+
// HTTP call to GitHub so the 5 s catalog poll can't trip rate limits
|
|
42
|
+
// or stall on slow WAN.
|
|
43
|
+
const [probe, sizeMB] = await Promise.all([
|
|
44
|
+
probeShellScriptStatus(entry.source),
|
|
45
|
+
probeShellScriptSizeMB(entry.source),
|
|
46
|
+
]);
|
|
47
|
+
if (probe) {
|
|
48
|
+
status.installed = probe.installed;
|
|
49
|
+
status.imageReady = probe.installed; // shell tools are binary-or-not; treat installed == imageReady
|
|
50
|
+
status.version = probe.version;
|
|
51
|
+
}
|
|
52
|
+
const running = findRunningShellScriptTask(entry.id);
|
|
53
|
+
status.currentTaskId = running?.id;
|
|
54
|
+
status.currentTaskKind = running?.kind;
|
|
55
|
+
status.updateAvailable = status.installed ? readShellScriptUpdateAvailable(entry.id) : null;
|
|
56
|
+
diskSpaceMB = sizeMB;
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
id: entry.id,
|
|
60
|
+
name: entry.name,
|
|
61
|
+
category: entry.category,
|
|
62
|
+
description: entry.description,
|
|
63
|
+
icon: entry.icon,
|
|
64
|
+
diskSpaceMB,
|
|
65
|
+
source: entry.source,
|
|
66
|
+
status,
|
|
67
|
+
actions: entry.actions,
|
|
68
|
+
required: entry.required,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export async function listAgentApps() {
|
|
72
|
+
return Promise.all(AGENT_APP_CATALOG.map(buildCardView));
|
|
73
|
+
}
|
|
74
|
+
export async function getAgentApp(id) {
|
|
75
|
+
const entry = getCatalogEntry(id);
|
|
76
|
+
if (!entry)
|
|
77
|
+
return null;
|
|
78
|
+
return buildCardView(entry);
|
|
79
|
+
}
|
|
80
|
+
export async function startAgentAppInstall(id, options = {}) {
|
|
81
|
+
const entry = getCatalogEntry(id);
|
|
82
|
+
if (!entry) {
|
|
83
|
+
return { ok: false, error: `Unknown agent app "${id}"` };
|
|
84
|
+
}
|
|
85
|
+
if (!entry.actions.install && !entry.actions.update) {
|
|
86
|
+
return { ok: false, error: `Agent app "${id}" does not support install/update` };
|
|
87
|
+
}
|
|
88
|
+
if (entry.source.kind === "adapter") {
|
|
89
|
+
return startAdapterInstall(entry.source.agentType, options);
|
|
90
|
+
}
|
|
91
|
+
if (entry.source.kind === "shell-script") {
|
|
92
|
+
return startShellScriptInstall(entry.id, entry.source);
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
ok: false,
|
|
96
|
+
error: `Installer for source kind "${entry.source.kind}" is not implemented yet`,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Backs `POST /api/agent-apps/check-updates`. Runs the update probe for
|
|
101
|
+
* every app across all installer kinds in parallel. Slow networks can take
|
|
102
|
+
* tens of seconds — the endpoint holds the connection until all probes
|
|
103
|
+
* complete or time out individually.
|
|
104
|
+
*
|
|
105
|
+
* - adapter kind: registry HTTPS digest comparison (cached)
|
|
106
|
+
* - shell-script kind: GitHub Releases API tag vs installed version (direct,
|
|
107
|
+
* no cache yet; light-weight call so acceptable)
|
|
108
|
+
*/
|
|
109
|
+
export async function checkAllAgentAppUpdates() {
|
|
110
|
+
const adapterAgents = [];
|
|
111
|
+
const shellScriptEntries = [];
|
|
112
|
+
for (const entry of AGENT_APP_CATALOG) {
|
|
113
|
+
if (entry.source.kind === "adapter")
|
|
114
|
+
adapterAgents.push(entry.source.agentType);
|
|
115
|
+
else if (entry.source.kind === "shell-script") {
|
|
116
|
+
shellScriptEntries.push({ id: entry.id, source: entry.source });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const [adapterResults, shellScriptResults] = await Promise.all([
|
|
120
|
+
forceRefreshAllAdapterUpdates(adapterAgents),
|
|
121
|
+
Promise.all(shellScriptEntries.map(async ({ id, source }) => {
|
|
122
|
+
const value = await refreshShellScriptUpdateCache(id, source);
|
|
123
|
+
return [id, value];
|
|
124
|
+
})),
|
|
125
|
+
]);
|
|
126
|
+
const results = { ...adapterResults };
|
|
127
|
+
for (const [id, value] of shellScriptResults)
|
|
128
|
+
results[id] = value;
|
|
129
|
+
return { checkedAt: Date.now(), results };
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Newest "last checked" timestamp across all installer kinds. The UI
|
|
133
|
+
* ("上次检查更新:2 分钟前") reads this — it doesn't care which installer
|
|
134
|
+
* owned the probe, only when *any* probe last finished.
|
|
135
|
+
*/
|
|
136
|
+
export function getAgentAppUpdatesLastCheckedAt() {
|
|
137
|
+
const adapterAt = getUpdateCacheLastCheckedAt();
|
|
138
|
+
const shellScriptAt = getShellScriptUpdateCacheLastCheckedAt();
|
|
139
|
+
if (adapterAt == null)
|
|
140
|
+
return shellScriptAt;
|
|
141
|
+
if (shellScriptAt == null)
|
|
142
|
+
return adapterAt;
|
|
143
|
+
return Math.max(adapterAt, shellScriptAt);
|
|
144
|
+
}
|
|
145
|
+
export async function startAgentAppUninstall(id) {
|
|
146
|
+
const entry = getCatalogEntry(id);
|
|
147
|
+
if (!entry) {
|
|
148
|
+
return { ok: false, error: `Unknown agent app "${id}"` };
|
|
149
|
+
}
|
|
150
|
+
if (!entry.actions.uninstall) {
|
|
151
|
+
return { ok: false, error: `${entry.name} 不支持卸载` };
|
|
152
|
+
}
|
|
153
|
+
if (entry.source.kind === "adapter") {
|
|
154
|
+
const depCount = countInstancesUsingAgentType(entry.source.agentType);
|
|
155
|
+
if (depCount > 0) {
|
|
156
|
+
return {
|
|
157
|
+
ok: false,
|
|
158
|
+
error: `还有 ${depCount} 个实例使用 ${entry.name},请先删除这些实例再卸载`,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
return startAdapterUninstall(entry.source.agentType);
|
|
162
|
+
}
|
|
163
|
+
if (entry.source.kind === "shell-script") {
|
|
164
|
+
return startShellScriptUninstall(entry.id, entry.source);
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
ok: false,
|
|
168
|
+
error: `Uninstaller for source kind "${entry.source.kind}" is not implemented yet`,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/agent-apps/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Probe functions used by `buildCardView` to populate an adapter-backed
|
|
3
|
+
* `AgentAppCardView` — install status, disk size, and update availability.
|
|
4
|
+
*
|
|
5
|
+
* The update probe is the expensive one (needs to reach the upstream
|
|
6
|
+
* registry) so it runs behind a stale-while-revalidate cache: callers see
|
|
7
|
+
* whatever is cached immediately, and a background refresh kicks off when
|
|
8
|
+
* the cache is stale. `forceRefreshAllAdapterUpdates` is the explicit
|
|
9
|
+
* "check updates now" path used by the UI button; it awaits in-flight
|
|
10
|
+
* refreshes instead of skipping them so the button's result reflects the
|
|
11
|
+
* newest state, not the value that was cached at click time.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Resolve the docker image an adapter's instances currently run on. Prefers
|
|
15
|
+
* the installed record in panel.json.runtime_catalog; falls back to the
|
|
16
|
+
* adapter's declared default so update checks still work even when the app
|
|
17
|
+
* has been uninstalled (or was never installed through the new flow).
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveAdapterImage(agentType: string): string | null;
|
|
20
|
+
export declare function probeAdapterStatus(agentType: string): Promise<{
|
|
21
|
+
installed: boolean;
|
|
22
|
+
imageReady: boolean;
|
|
23
|
+
version?: string;
|
|
24
|
+
digest?: string;
|
|
25
|
+
} | null>;
|
|
26
|
+
/**
|
|
27
|
+
* Read the disk size (MB, decimal) of the adapter's current docker image.
|
|
28
|
+
* Uses `docker image ls --format {{.Size}}` (same cumulative-layer total
|
|
29
|
+
* admins see in `docker images`) instead of `docker image inspect .Size`
|
|
30
|
+
* which reports dedup'd unique bytes and doesn't match operator
|
|
31
|
+
* expectation.
|
|
32
|
+
*/
|
|
33
|
+
export declare function probeAdapterImageSizeMB(agentType: string): Promise<number | null>;
|
|
34
|
+
/**
|
|
35
|
+
* Lazy background probe: returns whatever is currently cached, and kicks
|
|
36
|
+
* off a refresh in the background if the cache is stale. First cold call
|
|
37
|
+
* returns `null`; the next catalog poll after the refresh lands will flip
|
|
38
|
+
* to the real value.
|
|
39
|
+
*/
|
|
40
|
+
export declare function probeAdapterUpdateAvailable(agentType: string): Promise<boolean | null>;
|
|
41
|
+
/** Timestamp (ms since epoch) when the freshest cached probe completed. */
|
|
42
|
+
export declare function getUpdateCacheLastCheckedAt(): number | null;
|
|
43
|
+
/**
|
|
44
|
+
* Explicit "check updates now" path — backs `POST /api/agent-apps/check-
|
|
45
|
+
* updates`. Bypasses the TTL entirely: if a refresh is already running it
|
|
46
|
+
* awaits it instead of skipping (so the response carries the newest value,
|
|
47
|
+
* not a stale cached null). Runs all targets in parallel.
|
|
48
|
+
*/
|
|
49
|
+
export declare function forceRefreshAllAdapterUpdates(agentTypes: string[]): Promise<Record<string, boolean | null>>;
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Probe functions used by `buildCardView` to populate an adapter-backed
|
|
3
|
+
* `AgentAppCardView` — install status, disk size, and update availability.
|
|
4
|
+
*
|
|
5
|
+
* The update probe is the expensive one (needs to reach the upstream
|
|
6
|
+
* registry) so it runs behind a stale-while-revalidate cache: callers see
|
|
7
|
+
* whatever is cached immediately, and a background refresh kicks off when
|
|
8
|
+
* the cache is stale. `forceRefreshAllAdapterUpdates` is the explicit
|
|
9
|
+
* "check updates now" path used by the UI button; it awaits in-flight
|
|
10
|
+
* refreshes instead of skipping them so the button's result reflects the
|
|
11
|
+
* newest state, not the value that was cached at click time.
|
|
12
|
+
*/
|
|
13
|
+
import { execFile } from "child_process";
|
|
14
|
+
import { promisify } from "util";
|
|
15
|
+
import { HERMES_DEFAULT_IMAGE, getOpenclawDockerImage, getRuntimeCatalogEntry, } from "../../../config.js";
|
|
16
|
+
import { getAdapter, hasAdapter } from "../../runtime/index.js";
|
|
17
|
+
import { fetchRemoteDigest, parseImageRef } from "./registry-probe.js";
|
|
18
|
+
const execFileAsync = promisify(execFile);
|
|
19
|
+
// ── Image resolution ────────────────────────────────────────────────────
|
|
20
|
+
/**
|
|
21
|
+
* Resolve the docker image an adapter's instances currently run on. Prefers
|
|
22
|
+
* the installed record in panel.json.runtime_catalog; falls back to the
|
|
23
|
+
* adapter's declared default so update checks still work even when the app
|
|
24
|
+
* has been uninstalled (or was never installed through the new flow).
|
|
25
|
+
*/
|
|
26
|
+
export function resolveAdapterImage(agentType) {
|
|
27
|
+
if (agentType === "openclaw")
|
|
28
|
+
return getOpenclawDockerImage();
|
|
29
|
+
const entry = getRuntimeCatalogEntry(agentType);
|
|
30
|
+
const fromCatalog = entry?.defaultImage;
|
|
31
|
+
if (typeof fromCatalog === "string" && fromCatalog.trim())
|
|
32
|
+
return fromCatalog;
|
|
33
|
+
// Fallback: hardcoded defaults per adapter. Adapters that want to
|
|
34
|
+
// participate in update checks without a runtime_catalog entry (yet)
|
|
35
|
+
// advertise their default here.
|
|
36
|
+
if (agentType === "hermes")
|
|
37
|
+
return HERMES_DEFAULT_IMAGE;
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
// ── Status probe ────────────────────────────────────────────────────────
|
|
41
|
+
export async function probeAdapterStatus(agentType) {
|
|
42
|
+
if (!hasAdapter(agentType))
|
|
43
|
+
return null;
|
|
44
|
+
const adapter = getAdapter(agentType);
|
|
45
|
+
if (!adapter.getInstallStatus)
|
|
46
|
+
return null;
|
|
47
|
+
try {
|
|
48
|
+
return (await Promise.race([
|
|
49
|
+
Promise.resolve(adapter.getInstallStatus()),
|
|
50
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("install-status probe timed out")), 2500)),
|
|
51
|
+
]));
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// ── Image size probe ────────────────────────────────────────────────────
|
|
58
|
+
/**
|
|
59
|
+
* Read the disk size (MB, decimal) of the adapter's current docker image.
|
|
60
|
+
* Uses `docker image ls --format {{.Size}}` (same cumulative-layer total
|
|
61
|
+
* admins see in `docker images`) instead of `docker image inspect .Size`
|
|
62
|
+
* which reports dedup'd unique bytes and doesn't match operator
|
|
63
|
+
* expectation.
|
|
64
|
+
*/
|
|
65
|
+
export async function probeAdapterImageSizeMB(agentType) {
|
|
66
|
+
const image = resolveAdapterImage(agentType);
|
|
67
|
+
if (!image)
|
|
68
|
+
return null;
|
|
69
|
+
try {
|
|
70
|
+
const { stdout } = await execFileAsync("docker", ["image", "ls", "--format", "{{.Size}}", image], { timeout: 2500, encoding: "utf-8" });
|
|
71
|
+
const firstLine = stdout.split("\n")[0]?.trim();
|
|
72
|
+
if (!firstLine)
|
|
73
|
+
return null;
|
|
74
|
+
return parseDockerSizeToMB(firstLine);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Parse docker's human-readable size strings ("2.26GB", "593MB", "12.5kB")
|
|
82
|
+
* into megabytes. Docker uses decimal (SI) units for these displays.
|
|
83
|
+
*/
|
|
84
|
+
function parseDockerSizeToMB(raw) {
|
|
85
|
+
const m = raw.trim().match(/^(\d+(?:\.\d+)?)\s*(B|kB|MB|GB|TB)$/i);
|
|
86
|
+
if (!m)
|
|
87
|
+
return null;
|
|
88
|
+
const value = parseFloat(m[1]);
|
|
89
|
+
if (!Number.isFinite(value))
|
|
90
|
+
return null;
|
|
91
|
+
const unit = m[2].toLowerCase();
|
|
92
|
+
const mb = unit === "b" ? value / 1_000_000 :
|
|
93
|
+
unit === "kb" ? value / 1_000 :
|
|
94
|
+
unit === "mb" ? value :
|
|
95
|
+
unit === "gb" ? value * 1_000 :
|
|
96
|
+
unit === "tb" ? value * 1_000_000 : NaN;
|
|
97
|
+
return Number.isFinite(mb) ? Math.round(mb) : null;
|
|
98
|
+
}
|
|
99
|
+
const updateCache = new Map();
|
|
100
|
+
const UPDATE_CACHE_TTL_OK_MS = 10 * 60 * 1000;
|
|
101
|
+
const UPDATE_CACHE_TTL_NULL_MS = 60 * 1000;
|
|
102
|
+
/**
|
|
103
|
+
* Read the local RepoDigest sha for the given image — this is what docker
|
|
104
|
+
* recorded when it pulled the tag (the manifest-list's digest for
|
|
105
|
+
* multi-arch images), so it lines up with what the registry HEAD returns.
|
|
106
|
+
*/
|
|
107
|
+
async function readLocalDigest(image) {
|
|
108
|
+
try {
|
|
109
|
+
const { stdout } = await execFileAsync("docker", ["image", "inspect", "--format", "{{range .RepoDigests}}{{.}}{{println}}{{end}}", image], { timeout: 5_000, encoding: "utf-8" });
|
|
110
|
+
const line = stdout.split("\n").find((l) => l.includes("@sha256:"));
|
|
111
|
+
const m = line?.match(/@sha256:([a-f0-9]{64})/);
|
|
112
|
+
return m ? m[1] : null;
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async function readRemoteDigest(image) {
|
|
119
|
+
const ref = parseImageRef(image);
|
|
120
|
+
if (!ref)
|
|
121
|
+
return null;
|
|
122
|
+
return fetchRemoteDigest(ref);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Refresh the update-cache entry for one agentType. Safe to call while a
|
|
126
|
+
* refresh is already in flight — the second caller awaits the same
|
|
127
|
+
* promise instead of starting a duplicate probe.
|
|
128
|
+
*/
|
|
129
|
+
function refreshUpdateCache(agentType, image) {
|
|
130
|
+
const cached = updateCache.get(agentType);
|
|
131
|
+
if (cached?.inflight)
|
|
132
|
+
return cached.inflight;
|
|
133
|
+
const t0 = Date.now();
|
|
134
|
+
console.log(`[agent-apps] ${agentType}: probing digest for ${image}`);
|
|
135
|
+
const inflight = (async () => {
|
|
136
|
+
try {
|
|
137
|
+
const [local, remote] = await Promise.all([
|
|
138
|
+
readLocalDigest(image),
|
|
139
|
+
readRemoteDigest(image),
|
|
140
|
+
]);
|
|
141
|
+
const value = !local || !remote ? null : local !== remote;
|
|
142
|
+
console.log(`[agent-apps] ${agentType}: local=${local?.slice(0, 12) ?? "null"} ` +
|
|
143
|
+
`remote=${remote?.slice(0, 12) ?? "null"} result=${value} (+${Date.now() - t0}ms)`);
|
|
144
|
+
updateCache.set(agentType, { value, at: Date.now() });
|
|
145
|
+
}
|
|
146
|
+
catch (e) {
|
|
147
|
+
console.log(`[agent-apps] ${agentType}: probe error ${e?.message || e} (+${Date.now() - t0}ms)`);
|
|
148
|
+
updateCache.set(agentType, { value: null, at: Date.now() });
|
|
149
|
+
}
|
|
150
|
+
})();
|
|
151
|
+
updateCache.set(agentType, {
|
|
152
|
+
value: cached?.value ?? null,
|
|
153
|
+
at: cached?.at ?? 0,
|
|
154
|
+
inflight,
|
|
155
|
+
});
|
|
156
|
+
// When the async IIFE above writes the final value, the new entry will
|
|
157
|
+
// not carry `inflight`, so subsequent calls will see the fresh state.
|
|
158
|
+
inflight.finally(() => {
|
|
159
|
+
const final = updateCache.get(agentType);
|
|
160
|
+
if (final?.inflight === inflight) {
|
|
161
|
+
updateCache.set(agentType, { value: final.value, at: final.at });
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
return inflight;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Lazy background probe: returns whatever is currently cached, and kicks
|
|
168
|
+
* off a refresh in the background if the cache is stale. First cold call
|
|
169
|
+
* returns `null`; the next catalog poll after the refresh lands will flip
|
|
170
|
+
* to the real value.
|
|
171
|
+
*/
|
|
172
|
+
export async function probeAdapterUpdateAvailable(agentType) {
|
|
173
|
+
const image = resolveAdapterImage(agentType);
|
|
174
|
+
if (!image)
|
|
175
|
+
return null;
|
|
176
|
+
const cached = updateCache.get(agentType);
|
|
177
|
+
const now = Date.now();
|
|
178
|
+
const ttl = cached?.value == null ? UPDATE_CACHE_TTL_NULL_MS : UPDATE_CACHE_TTL_OK_MS;
|
|
179
|
+
const stale = !cached || now - cached.at > ttl;
|
|
180
|
+
if (stale && !cached?.inflight) {
|
|
181
|
+
refreshUpdateCache(agentType, image).catch(() => {
|
|
182
|
+
// swallowed — refreshUpdateCache writes a null entry on its own
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
return cached?.value ?? null;
|
|
186
|
+
}
|
|
187
|
+
/** Timestamp (ms since epoch) when the freshest cached probe completed. */
|
|
188
|
+
export function getUpdateCacheLastCheckedAt() {
|
|
189
|
+
let latest = 0;
|
|
190
|
+
for (const entry of updateCache.values()) {
|
|
191
|
+
if (entry.at > latest)
|
|
192
|
+
latest = entry.at;
|
|
193
|
+
}
|
|
194
|
+
return latest > 0 ? latest : null;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Explicit "check updates now" path — backs `POST /api/agent-apps/check-
|
|
198
|
+
* updates`. Bypasses the TTL entirely: if a refresh is already running it
|
|
199
|
+
* awaits it instead of skipping (so the response carries the newest value,
|
|
200
|
+
* not a stale cached null). Runs all targets in parallel.
|
|
201
|
+
*/
|
|
202
|
+
export async function forceRefreshAllAdapterUpdates(agentTypes) {
|
|
203
|
+
const targets = [];
|
|
204
|
+
for (const agentType of agentTypes) {
|
|
205
|
+
const image = resolveAdapterImage(agentType);
|
|
206
|
+
if (image)
|
|
207
|
+
targets.push({ agentType, image });
|
|
208
|
+
}
|
|
209
|
+
await Promise.all(targets.map(({ agentType, image }) => {
|
|
210
|
+
const cached = updateCache.get(agentType);
|
|
211
|
+
// Already refreshing → wait for it. Otherwise start a fresh probe
|
|
212
|
+
// even if the TTL hasn't expired (user explicitly asked for a check).
|
|
213
|
+
if (cached?.inflight)
|
|
214
|
+
return cached.inflight;
|
|
215
|
+
return refreshUpdateCache(agentType, image);
|
|
216
|
+
}));
|
|
217
|
+
const out = {};
|
|
218
|
+
for (const { agentType } of targets) {
|
|
219
|
+
out[agentType] = updateCache.get(agentType)?.value ?? null;
|
|
220
|
+
}
|
|
221
|
+
return out;
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=adapter-probes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-probes.js","sourceRoot":"","sources":["../../../../src/services/agent-apps/installers/adapter-probes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEvE,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C,2EAA2E;AAE3E;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,SAAiB;IACnD,IAAI,SAAS,KAAK,UAAU;QAAE,OAAO,sBAAsB,EAAE,CAAC;IAE9D,MAAM,KAAK,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,KAAK,EAAE,YAAY,CAAC;IACxC,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,CAAC,IAAI,EAAE;QAAE,OAAO,WAAW,CAAC;IAE9E,kEAAkE;IAClE,qEAAqE;IACrE,gCAAgC;IAChC,IAAI,SAAS,KAAK,QAAQ;QAAE,OAAO,oBAAoB,CAAC;IAExD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,2EAA2E;AAE3E,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAAiB;IAEjB,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IACtC,IAAI,CAAC,OAAO,CAAC,gBAAgB;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC;YACzB,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC;YAC3C,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAC9B,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC,EAAE,IAAI,CAAC,CAC5E;SACF,CAAC,CAEM,CAAC;IACX,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,2EAA2E;AAE3E;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,SAAiB;IAC7D,MAAM,KAAK,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CACpC,QAAQ,EACR,CAAC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,CAAC,EAC/C,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CACrC,CAAC;QACF,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QAChD,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAC5B,OAAO,mBAAmB,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAAC,GAAW;IACtC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACnE,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAChC,MAAM,EAAE,GACN,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;QAClC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;YAC/B,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACvB,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;oBAC/B,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC;IAC1C,OAAO,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACrD,CAAC;AAWD,MAAM,WAAW,GAAG,IAAI,GAAG,EAA4B,CAAC;AACxD,MAAM,sBAAsB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAC9C,MAAM,wBAAwB,GAAG,EAAE,GAAG,IAAI,CAAC;AAE3C;;;;GAIG;AACH,KAAK,UAAU,eAAe,CAAC,KAAa;IAC1C,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CACpC,QAAQ,EACR,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,+CAA+C,EAAE,KAAK,CAAC,EACxF,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,CACtC,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;QACpE,MAAM,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAChD,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,KAAa;IAC3C,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,OAAO,iBAAiB,CAAC,GAAG,CAAC,CAAC;AAChC,CAAC;AAED;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,SAAiB,EAAE,KAAa;IAC1D,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC1C,IAAI,MAAM,EAAE,QAAQ;QAAE,OAAO,MAAM,CAAC,QAAQ,CAAC;IAE7C,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACtB,OAAO,CAAC,GAAG,CAAC,gBAAgB,SAAS,wBAAwB,KAAK,EAAE,CAAC,CAAC;IACtE,MAAM,QAAQ,GAAG,CAAC,KAAK,IAAI,EAAE;QAC3B,IAAI,CAAC;YACH,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBACxC,eAAe,CAAC,KAAK,CAAC;gBACtB,gBAAgB,CAAC,KAAK,CAAC;aACxB,CAAC,CAAC;YACH,MAAM,KAAK,GACT,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC;YAC9C,OAAO,CAAC,GAAG,CACT,gBAAgB,SAAS,WAAW,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,GAAG;gBACpE,UAAU,MAAM,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,WAAW,KAAK,MAAM,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CACnF,CAAC;YACF,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACxD,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,gBAAgB,SAAS,iBAAiB,CAAC,EAAE,OAAO,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;YACjG,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IAEL,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE;QACzB,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,IAAI;QAC5B,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC;QACnB,QAAQ;KACT,CAAC,CAAC;IACH,uEAAuE;IACvE,sEAAsE;IACtE,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE;QACpB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,KAAK,EAAE,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QACnE,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,SAAiB;IAEjB,MAAM,KAAK,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,GAAG,GAAG,MAAM,EAAE,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,sBAAsB,CAAC;IACtF,MAAM,KAAK,GAAG,CAAC,MAAM,IAAI,GAAG,GAAG,MAAM,CAAC,EAAE,GAAG,GAAG,CAAC;IAE/C,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC;QAC/B,kBAAkB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YAC9C,gEAAgE;QAClE,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,EAAE,KAAK,IAAI,IAAI,CAAC;AAC/B,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,2BAA2B;IACzC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;QACzC,IAAI,KAAK,CAAC,EAAE,GAAG,MAAM;YAAE,MAAM,GAAG,KAAK,CAAC,EAAE,CAAC;IAC3C,CAAC;IACD,OAAO,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,UAAoB;IAEpB,MAAM,OAAO,GAAgD,EAAE,CAAC;IAChE,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,KAAK;YAAE,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,OAAO,CAAC,GAAG,CACf,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE;QACnC,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC1C,kEAAkE;QAClE,sEAAsE;QACtE,IAAI,MAAM,EAAE,QAAQ;YAAE,OAAO,MAAM,CAAC,QAAQ,CAAC;QAC7C,OAAO,kBAAkB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,GAAG,GAAmC,EAAE,CAAC;IAC/C,KAAK,MAAM,EAAE,SAAS,EAAE,IAAI,OAAO,EAAE,CAAC;QACpC,GAAG,CAAC,SAAS,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC;IAC7D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Installer strategy for adapter-backed agent apps (hermes, openclaw).
|
|
3
|
+
*
|
|
4
|
+
* Delegates install to `adapter.startBuildRuntimeImage` (preferred when
|
|
5
|
+
* present — openclaw builds its image locally) or
|
|
6
|
+
* `adapter.startInstallRuntime` (hermes pulls from GHCR). Uninstall runs
|
|
7
|
+
* locally here (docker image rm + clear runtime_catalog + drop shim).
|
|
8
|
+
*
|
|
9
|
+
* Probe + cache logic lives in `adapter-probes.ts`; this file re-exports
|
|
10
|
+
* the probes so callers import one entry point.
|
|
11
|
+
*/
|
|
12
|
+
import type { InstallStartResult } from "../types.js";
|
|
13
|
+
export { forceRefreshAllAdapterUpdates, getUpdateCacheLastCheckedAt, probeAdapterImageSizeMB, probeAdapterStatus, probeAdapterUpdateAvailable, resolveAdapterImage, } from "./adapter-probes.js";
|
|
14
|
+
export declare function startAdapterInstall(agentType: string, options?: Record<string, any>): Promise<InstallStartResult>;
|
|
15
|
+
export declare function startAdapterUninstall(agentType: string): InstallStartResult;
|
|
16
|
+
/**
|
|
17
|
+
* Current running task for this agentType. Returns both the id and the
|
|
18
|
+
* kind so the UI can render "安装中" vs "卸载中" from one field instead
|
|
19
|
+
* of having to guess from task name shape.
|
|
20
|
+
*
|
|
21
|
+
* Install tasks match by prefix (`openclaw`, `openclaw-docker-pull`,
|
|
22
|
+
* `hermes`). Uninstall tasks use the disjoint `uninstall-${agentType}`
|
|
23
|
+
* name so no prefix collision is possible.
|
|
24
|
+
*/
|
|
25
|
+
export declare function findRunningAdapterTask(agentType: string): {
|
|
26
|
+
id: string;
|
|
27
|
+
kind: "install" | "uninstall";
|
|
28
|
+
} | undefined;
|
|
29
|
+
/** Count live instances bound to this agentType — used to block uninstall. */
|
|
30
|
+
export declare function countInstancesUsingAgentType(agentType: string): number;
|