mlclaw 0.3.4 → 0.3.6
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 +2 -19
- package/README.md +10 -9
- package/dist/mlclaw-space-runtime.js +8 -5
- package/dist/mlclaw.mjs +12 -14
- package/package.json +1 -1
package/Dockerfile
CHANGED
|
@@ -2,7 +2,7 @@ ARG OPENCLAW_VERSION=2026.7.1
|
|
|
2
2
|
ARG OPENCLAW_BASE_IMAGE=ghcr.io/openclaw/openclaw:${OPENCLAW_VERSION}
|
|
3
3
|
ARG BROKERKIT_PLUGIN_VERSION=0.2.1
|
|
4
4
|
ARG BROKERKIT_VERSION=hf-broker/v0.1.0
|
|
5
|
-
ARG MLCLAW_RUNTIME_IMAGE=ghcr.io/osolmaz/mlclaw:0.3.
|
|
5
|
+
ARG MLCLAW_RUNTIME_IMAGE=ghcr.io/osolmaz/mlclaw:0.3.6-openclaw-2026.7.1
|
|
6
6
|
|
|
7
7
|
FROM golang:1.26.5-bookworm AS hf-broker-build
|
|
8
8
|
ARG BROKERKIT_VERSION
|
|
@@ -23,21 +23,6 @@ RUN git init /src \
|
|
|
23
23
|
--scope /out/hf-broker.scope.json \
|
|
24
24
|
--manifest /out/hf-broker.policy-manifest.json
|
|
25
25
|
|
|
26
|
-
FROM node:24-bookworm-slim AS brokerkit-plugin-build
|
|
27
|
-
ARG BROKERKIT_VERSION
|
|
28
|
-
RUN apt-get update \
|
|
29
|
-
&& apt-get install -y --no-install-recommends ca-certificates git \
|
|
30
|
-
&& rm -rf /var/lib/apt/lists/* \
|
|
31
|
-
&& git init /src \
|
|
32
|
-
&& git -C /src fetch --depth=1 https://github.com/osolmaz/brokerkit.git "refs/tags/$BROKERKIT_VERSION:refs/tags/$BROKERKIT_VERSION" \
|
|
33
|
-
&& git -C /src checkout --detach "$BROKERKIT_VERSION" \
|
|
34
|
-
&& test "$(git -C /src rev-parse "refs/tags/$BROKERKIT_VERSION^{commit}")" = "$(git -C /src rev-parse HEAD)"
|
|
35
|
-
WORKDIR /src
|
|
36
|
-
RUN corepack enable \
|
|
37
|
-
&& pnpm install --frozen-lockfile \
|
|
38
|
-
&& pnpm --filter openclaw-brokerkit build \
|
|
39
|
-
&& pnpm --filter openclaw-brokerkit pack --pack-destination /out
|
|
40
|
-
|
|
41
26
|
# Stage 1: build the state-sync bundle so the runtime image needs no dev deps.
|
|
42
27
|
FROM node:24-bookworm-slim AS sync-build
|
|
43
28
|
WORKDIR /build
|
|
@@ -69,10 +54,8 @@ RUN python3 -m pip install --break-system-packages --no-cache-dir \
|
|
|
69
54
|
"uv==0.11.28" \
|
|
70
55
|
"hf-discover==1.3.7"
|
|
71
56
|
ARG BROKERKIT_PLUGIN_VERSION
|
|
72
|
-
COPY --from=brokerkit-plugin-build /out/openclaw-brokerkit-${BROKERKIT_PLUGIN_VERSION}.tgz /tmp/openclaw-brokerkit.tgz
|
|
73
57
|
RUN npm install --omit=dev --omit=peer --no-audit --no-fund --prefix /opt/openclaw-plugins \
|
|
74
|
-
|
|
75
|
-
&& rm /tmp/openclaw-brokerkit.tgz \
|
|
58
|
+
"openclaw-brokerkit@${BROKERKIT_PLUGIN_VERSION}" \
|
|
76
59
|
&& test -f /opt/openclaw-plugins/node_modules/openclaw-brokerkit/openclaw.plugin.json
|
|
77
60
|
|
|
78
61
|
COPY --from=sync-build /build/dist/hf-state-sync.js /app/hf-state-sync.js
|
package/README.md
CHANGED
|
@@ -86,12 +86,13 @@ Choose a Hugging Face Router model with `--model`:
|
|
|
86
86
|
```bash
|
|
87
87
|
npx mlclaw@latest bootstrap \
|
|
88
88
|
--name mlclaw \
|
|
89
|
-
--model huggingface/
|
|
89
|
+
--model huggingface/zai-org/GLM-5.2:fireworks-ai
|
|
90
90
|
```
|
|
91
91
|
|
|
92
92
|
Recommended router-compatible options:
|
|
93
93
|
|
|
94
|
-
- `huggingface/
|
|
94
|
+
- `huggingface/zai-org/GLM-5.2:fireworks-ai`: default long-context model with tool support.
|
|
95
|
+
- `huggingface/google/gemma-4-26B-A4B-it:deepinfra`: lower-cost Gemma option with tool and structured-output support.
|
|
95
96
|
- `huggingface/Qwen/Qwen3.6-35B-A3B:deepinfra`: strong Qwen 3.6 option with tool and structured-output support.
|
|
96
97
|
- `huggingface/Qwen/Qwen3.6-27B:deepinfra`: live Qwen 3.6 option with tool and structured-output support.
|
|
97
98
|
- `huggingface/zai-org/GLM-5.2:deepinfra`: long-context GLM option with tool and structured-output support.
|
|
@@ -102,10 +103,10 @@ Recommended router-compatible options:
|
|
|
102
103
|
- `huggingface/deepseek-ai/DeepSeek-V4-Pro:deepinfra`: higher-quality long-context DeepSeek V4 option.
|
|
103
104
|
- `huggingface/MiniMaxAI/MiniMax-M3:together`: long-context MiniMax option with tool and structured-output support.
|
|
104
105
|
|
|
105
|
-
Fireworks
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
Fireworks options are also included for Kimi K2.7 Code, GPT-OSS 120B and 20B,
|
|
107
|
+
DeepSeek V4 Flash and Pro, and MiniMax M3. Use the provider suffix
|
|
108
|
+
`:fireworks-ai`. The current Router catalog does not expose the Gemma 4 or Qwen
|
|
109
|
+
3.6 presets through Fireworks.
|
|
109
110
|
|
|
110
111
|
## Optional Telegram
|
|
111
112
|
|
|
@@ -210,9 +211,9 @@ merges every BrokerKit-compatible backend configured in
|
|
|
210
211
|
cancel, or revoke requests. The plugin registers the Gateway tab, while ML Claw
|
|
211
212
|
serves the immutable packaged UI from its trusted HTTP boundary and gives it a
|
|
212
213
|
small popover inside the Gateway. Administrators decide requests directly in
|
|
213
|
-
the sandboxed popover
|
|
214
|
-
|
|
215
|
-
|
|
214
|
+
the sandboxed popover by default. Set
|
|
215
|
+
`MLCLAW_BROKERKIT_POPOVER_DECISIONS=false` only to make the popover read-only.
|
|
216
|
+
The popover uses a renewable, short-lived, admin-bound browser token.
|
|
216
217
|
Broker operator tokens remain in backend-only files and are never sent to the
|
|
217
218
|
browser or OpenClaw. See
|
|
218
219
|
[Operator Broker Configuration](docs/operator-brokers-config.md).
|
|
@@ -129,16 +129,19 @@ function normalizeAssetRef(value, fallback) {
|
|
|
129
129
|
return normalized;
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
+
// src/mlclaw-space-runtime/model-default.ts
|
|
133
|
+
var DEFAULT_MODEL_ID = "zai-org/GLM-5.2";
|
|
134
|
+
var DEFAULT_MODEL_PROVIDER = "fireworks-ai";
|
|
135
|
+
var DEFAULT_MODEL = `huggingface/${DEFAULT_MODEL_ID}:${DEFAULT_MODEL_PROVIDER}`;
|
|
136
|
+
|
|
132
137
|
// src/mlclaw-space-runtime/model-choices.ts
|
|
133
138
|
var DEFAULT_ROUTER_PROVIDER = "deepinfra";
|
|
134
|
-
var DEFAULT_ROUTER_MODEL_ID = "google/gemma-4-26B-A4B-it";
|
|
135
|
-
var DEFAULT_MODEL = formatOpenClawModelRef(DEFAULT_ROUTER_MODEL_ID, DEFAULT_ROUTER_PROVIDER);
|
|
136
139
|
var PRESET_MODEL_CHOICES = [
|
|
137
140
|
freezeChoice({
|
|
138
141
|
modelId: "google/gemma-4-26B-A4B-it",
|
|
139
142
|
provider: "deepinfra",
|
|
140
143
|
label: "Gemma 4 26B A4B",
|
|
141
|
-
note: "
|
|
144
|
+
note: "Low-cost Gemma preset on DeepInfra",
|
|
142
145
|
contextLength: 262144,
|
|
143
146
|
pricing: { input: 0.07, output: 0.34 },
|
|
144
147
|
supportsTools: true,
|
|
@@ -298,7 +301,7 @@ var PRESET_MODEL_CHOICES = [
|
|
|
298
301
|
modelId: "zai-org/GLM-5.2",
|
|
299
302
|
provider: "fireworks-ai",
|
|
300
303
|
label: "GLM 5.2",
|
|
301
|
-
note: "
|
|
304
|
+
note: "Default long-context GLM preset on Fireworks",
|
|
302
305
|
contextLength: 1048576,
|
|
303
306
|
pricing: { input: 1.4, output: 4.4 },
|
|
304
307
|
supportsTools: true,
|
|
@@ -5106,7 +5109,7 @@ function loadConfig(env = process.env) {
|
|
|
5106
5109
|
brokerAgentSecret: readOptionalSecret(trim(env.MLCLAW_HF_BROKER_AGENT_SECRET_FILE)),
|
|
5107
5110
|
brokerAgentSecretFile: trim(env.MLCLAW_HF_BROKER_AGENT_SECRET_FILE),
|
|
5108
5111
|
operatorBrokers: loadOperatorBrokers(trim(env.MLCLAW_OPERATOR_BROKERS_FILE)),
|
|
5109
|
-
brokerKitPopoverDecisions: env.MLCLAW_BROKERKIT_POPOVER_DECISIONS
|
|
5112
|
+
brokerKitPopoverDecisions: env.MLCLAW_BROKERKIT_POPOVER_DECISIONS !== "0" && env.MLCLAW_BROKERKIT_POPOVER_DECISIONS !== "false",
|
|
5110
5113
|
hubUrl: trim(env.HF_ENDPOINT) ?? "https://huggingface.co",
|
|
5111
5114
|
openaiCredentialFile: trim(env.MLCLAW_OPENAI_CREDENTIAL_FILE) ?? "/tmp/mlclaw-secrets/openai.env",
|
|
5112
5115
|
openaiCredentialStoreFile,
|
package/dist/mlclaw.mjs
CHANGED
|
@@ -14997,12 +14997,6 @@ RUN git init /src \\
|
|
|
14997
14997
|
--scope /out/hf-broker.scope.json \\
|
|
14998
14998
|
--manifest /out/hf-broker.policy-manifest.json
|
|
14999
14999
|
|
|
15000
|
-
FROM node:24-bookworm-slim AS brokerkit-plugin-build
|
|
15001
|
-
ARG BROKERKIT_VERSION
|
|
15002
|
-
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates git && rm -rf /var/lib/apt/lists/* && git init /src && git -C /src fetch --depth=1 https://github.com/osolmaz/brokerkit.git "refs/tags/$BROKERKIT_VERSION:refs/tags/$BROKERKIT_VERSION" && git -C /src checkout --detach "$BROKERKIT_VERSION" && test "$(git -C /src rev-parse "refs/tags/$BROKERKIT_VERSION^{commit}")" = "$(git -C /src rev-parse HEAD)"
|
|
15003
|
-
WORKDIR /src
|
|
15004
|
-
RUN corepack enable && pnpm install --frozen-lockfile && pnpm --filter openclaw-brokerkit build && pnpm --filter openclaw-brokerkit pack --pack-destination /out
|
|
15005
|
-
|
|
15006
15000
|
FROM ${OPENCLAW_BASE_IMAGE}
|
|
15007
15001
|
|
|
15008
15002
|
LABEL org.opencontainers.image.source="https://github.com/osolmaz/mlclaw"
|
|
@@ -15026,8 +15020,7 @@ RUN python3 -m pip install --break-system-packages --no-cache-dir \\
|
|
|
15026
15020
|
"uv==0.11.28" \\
|
|
15027
15021
|
"hf-discover==1.3.7"
|
|
15028
15022
|
ARG BROKERKIT_PLUGIN_VERSION
|
|
15029
|
-
|
|
15030
|
-
RUN npm install --omit=dev --omit=peer --no-audit --no-fund --prefix /opt/openclaw-plugins /tmp/openclaw-brokerkit.tgz && rm /tmp/openclaw-brokerkit.tgz && test -f /opt/openclaw-plugins/node_modules/openclaw-brokerkit/openclaw.plugin.json
|
|
15023
|
+
RUN npm install --omit=dev --omit=peer --no-audit --no-fund --prefix /opt/openclaw-plugins "openclaw-brokerkit@\${BROKERKIT_PLUGIN_VERSION}" && test -f /opt/openclaw-plugins/node_modules/openclaw-brokerkit/openclaw.plugin.json
|
|
15031
15024
|
|
|
15032
15025
|
COPY --chown=node:node runtime/hf-state-sync.js /app/hf-state-sync.js
|
|
15033
15026
|
COPY --chown=node:node runtime/hf-tooling-seed.js /app/hf-tooling-seed.js
|
|
@@ -15187,6 +15180,11 @@ async function assertNoLiveForeignLease(params) {
|
|
|
15187
15180
|
);
|
|
15188
15181
|
}
|
|
15189
15182
|
|
|
15183
|
+
// src/mlclaw-space-runtime/model-default.ts
|
|
15184
|
+
var DEFAULT_MODEL_ID = "zai-org/GLM-5.2";
|
|
15185
|
+
var DEFAULT_MODEL_PROVIDER = "fireworks-ai";
|
|
15186
|
+
var DEFAULT_MODEL = `huggingface/${DEFAULT_MODEL_ID}:${DEFAULT_MODEL_PROVIDER}`;
|
|
15187
|
+
|
|
15190
15188
|
// src/mlclaw/local-config.ts
|
|
15191
15189
|
import fs13 from "node:fs/promises";
|
|
15192
15190
|
import os5 from "node:os";
|
|
@@ -15326,7 +15324,7 @@ function delay(ms) {
|
|
|
15326
15324
|
}
|
|
15327
15325
|
|
|
15328
15326
|
// src/mlclaw/cli.ts
|
|
15329
|
-
var
|
|
15327
|
+
var DEFAULT_MODEL2 = DEFAULT_MODEL;
|
|
15330
15328
|
var DEFAULT_HARDWARE = "cpu-basic";
|
|
15331
15329
|
var TELEGRAM_HARDWARE = "cpu-upgrade";
|
|
15332
15330
|
var TELEGRAM_SLEEP_TIME = -1;
|
|
@@ -15374,7 +15372,7 @@ function createProgram(runtimeOverrides = {}) {
|
|
|
15374
15372
|
program2.name("mlclaw").description("Deploy OpenClaw to a Hugging Face Space and private bucket").showHelpAfterError().exitOverride((err) => {
|
|
15375
15373
|
throw err;
|
|
15376
15374
|
});
|
|
15377
|
-
program2.command("bootstrap", { isDefault: true }).description("Create or update a Hugging Face OpenClaw deployment").option("--owner <owner>", "Hugging Face user or organization").option("--name <name>", "Agent and runtime resource base name").option("--bucket <owner/bucket>", "State bucket to create or adopt").option("--gateway <local|space>", "Where the live gateway runs").option("--telegram-token <token>", "Optional Telegram bot token").option("--telegram-token-file <path>", "File containing TELEGRAM_BOT_TOKEN=... or a raw token").option("--telegram-user-id <id>", "Allowed Telegram user ID").option("--telegram-api-root <url>", "Telegram API root override").option("--telegram-proxy <url>", "Telegram proxy URL override").option("--hardware <flavor>", "Hugging Face Space hardware flavor").option("--sleep-time <seconds>", "Space sleep timeout in seconds; -1 means never sleep", parseInteger).option("--model <model>", "OpenClaw model identifier",
|
|
15375
|
+
program2.command("bootstrap", { isDefault: true }).description("Create or update a Hugging Face OpenClaw deployment").option("--owner <owner>", "Hugging Face user or organization").option("--name <name>", "Agent and runtime resource base name").option("--bucket <owner/bucket>", "State bucket to create or adopt").option("--gateway <local|space>", "Where the live gateway runs").option("--telegram-token <token>", "Optional Telegram bot token").option("--telegram-token-file <path>", "File containing TELEGRAM_BOT_TOKEN=... or a raw token").option("--telegram-user-id <id>", "Allowed Telegram user ID").option("--telegram-api-root <url>", "Telegram API root override").option("--telegram-proxy <url>", "Telegram proxy URL override").option("--hardware <flavor>", "Hugging Face Space hardware flavor").option("--sleep-time <seconds>", "Space sleep timeout in seconds; -1 means never sleep", parseInteger).option("--model <model>", "OpenClaw model identifier", DEFAULT_MODEL2).option("--runtime-image <image>", "ML Claw runtime image").option("--bundled-runtime", "Generate a bundled Space runtime instead of using the prebuilt ML Claw image", false).option("--public-space", "Create the Hugging Face Space as public instead of private", false).addOption(new Option("--gateway-token <token>").hideHelp()).option("--router-token <token>", "Hugging Face Router inference token for Space gateway model calls").option("--router-token-file <path>", "File containing MLCLAW_ROUTER_TOKEN=..., HF_ROUTER_TOKEN=..., or a raw token").option("--docker-context <name>", "Docker context for local gateway mode").option("--no-pull", "Do not docker pull before starting a local gateway").option("--takeover", "Start even if a stale runtime lease is present", false).option("--yes", "Confirm paid hardware prompts for automation", false).action(async (opts) => {
|
|
15378
15376
|
await bootstrap(opts, runtime);
|
|
15379
15377
|
});
|
|
15380
15378
|
program2.command("update").description("Regenerate and upload current ML Claw Space files").argument("<owner/space>", "Hugging Face Space repo ID").option("--runtime-image <image>", "Runtime image to write into the generated Space Dockerfile").option("--bundled-runtime", "Generate a bundled Space runtime instead of using the prebuilt ML Claw image", false).option("--router-token <token>", "Dedicated Hugging Face Router inference token").option("--router-token-file <path>", "File containing MLCLAW_ROUTER_TOKEN=..., HF_ROUTER_TOKEN=..., or a raw token").option("--force", "Update even if the Space does not look like ML Claw", false).action(async (repoId, opts) => {
|
|
@@ -15445,7 +15443,7 @@ async function bootstrap(opts, runtime) {
|
|
|
15445
15443
|
const bot = telegramToken ? await runtime.getTelegramBot(telegramToken, opts.telegramApiRoot) : void 0;
|
|
15446
15444
|
let agentName = slugifyAgentName(opts.name ?? bot?.username ?? await promptAgentName(runtime));
|
|
15447
15445
|
const telegramUserId = telegramToken ? opts.telegramUserId ?? runtime.env.TELEGRAM_ALLOWED_USERS ?? await promptRequired("Telegram allowed user ID", runtime) : void 0;
|
|
15448
|
-
const model = opts.model ??
|
|
15446
|
+
const model = opts.model ?? DEFAULT_MODEL2;
|
|
15449
15447
|
const runtimeImage = resolveRuntimeImage(opts.runtimeImage, runtime.env);
|
|
15450
15448
|
const templateRuntimeImage = resolveSpaceRuntimeImage(opts, runtime.env);
|
|
15451
15449
|
let plan;
|
|
@@ -16534,7 +16532,7 @@ async function update(repoId, opts, hub, hfToken, runtime) {
|
|
|
16534
16532
|
await ensureUpdateRouterToken({
|
|
16535
16533
|
repoId,
|
|
16536
16534
|
agentName,
|
|
16537
|
-
model: variables.get("OPENCLAW_MODEL")?.value ??
|
|
16535
|
+
model: variables.get("OPENCLAW_MODEL")?.value ?? DEFAULT_MODEL2,
|
|
16538
16536
|
opts,
|
|
16539
16537
|
hub,
|
|
16540
16538
|
runtime
|
|
@@ -16706,7 +16704,7 @@ async function doctor(repoId, opts, hub, runtime) {
|
|
|
16706
16704
|
}
|
|
16707
16705
|
const staleTokenSecrets = ["HF_TOKEN", "HUGGINGFACE_HUB_TOKEN"].filter((key) => secrets.has(key));
|
|
16708
16706
|
if (staleTokenSecrets.length > 0) {
|
|
16709
|
-
const model = variables.get("OPENCLAW_MODEL")?.value ??
|
|
16707
|
+
const model = variables.get("OPENCLAW_MODEL")?.value ?? DEFAULT_MODEL2;
|
|
16710
16708
|
const canDelete = canDeleteBroadTokenSecrets({
|
|
16711
16709
|
model,
|
|
16712
16710
|
routerTokenPresent: hasBrokerOrRouterTokenSecretMap(secrets)
|
|
@@ -17112,7 +17110,7 @@ export {
|
|
|
17112
17110
|
DEFAULT_GATEWAY_LOCATION,
|
|
17113
17111
|
DEFAULT_HARDWARE,
|
|
17114
17112
|
DEFAULT_LOCAL_PORT,
|
|
17115
|
-
DEFAULT_MODEL,
|
|
17113
|
+
DEFAULT_MODEL2 as DEFAULT_MODEL,
|
|
17116
17114
|
DEFAULT_SPACE_OPENCLAW_PORT,
|
|
17117
17115
|
LOCAL_LIVE_DIR,
|
|
17118
17116
|
LOCAL_VOLUME_MOUNT_PATH,
|