mlclaw 0.3.2 → 0.3.5
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 +8 -25
- package/dist/hf-tooling-seed.js +12 -6
- package/dist/mlclaw-space-runtime.js +83 -27
- package/dist/mlclaw.mjs +7 -14
- package/entrypoint.sh +2 -4
- package/package.json +6 -6
package/Dockerfile
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
ARG OPENCLAW_VERSION=2026.7.1
|
|
1
|
+
ARG OPENCLAW_VERSION=2026.7.1
|
|
2
2
|
ARG OPENCLAW_BASE_IMAGE=ghcr.io/openclaw/openclaw:${OPENCLAW_VERSION}
|
|
3
|
-
ARG BROKERKIT_PLUGIN_VERSION=0.1
|
|
4
|
-
ARG BROKERKIT_VERSION=
|
|
5
|
-
ARG MLCLAW_RUNTIME_IMAGE=ghcr.io/osolmaz/mlclaw:0.3.
|
|
3
|
+
ARG BROKERKIT_PLUGIN_VERSION=0.2.1
|
|
4
|
+
ARG BROKERKIT_VERSION=hf-broker/v0.1.0
|
|
5
|
+
ARG MLCLAW_RUNTIME_IMAGE=ghcr.io/osolmaz/mlclaw:0.3.5-openclaw-2026.7.1
|
|
6
6
|
|
|
7
7
|
FROM golang:1.26.5-bookworm AS hf-broker-build
|
|
8
8
|
ARG BROKERKIT_VERSION
|
|
9
9
|
RUN git init /src \
|
|
10
|
-
&& git -C /src fetch --depth=1 https://github.com/osolmaz/brokerkit.git "
|
|
11
|
-
&& git -C /src checkout --detach
|
|
12
|
-
&& test "$(git -C /src rev-parse
|
|
10
|
+
&& git -C /src fetch --depth=1 https://github.com/osolmaz/brokerkit.git "refs/tags/$BROKERKIT_VERSION:refs/tags/$BROKERKIT_VERSION" \
|
|
11
|
+
&& git -C /src checkout --detach "$BROKERKIT_VERSION" \
|
|
12
|
+
&& test "$(git -C /src rev-parse "refs/tags/$BROKERKIT_VERSION^{commit}")" = "$(git -C /src rev-parse HEAD)" \
|
|
13
13
|
&& cd /src \
|
|
14
14
|
&& GOWORK=off go build -trimpath -o /out/hf-broker ./brokers/huggingface/cmd/hf-broker \
|
|
15
15
|
&& /out/hf-broker policy render \
|
|
@@ -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 "$BROKERKIT_VERSION" \
|
|
33
|
-
&& git -C /src checkout --detach FETCH_HEAD \
|
|
34
|
-
&& test "$(git -C /src rev-parse HEAD)" = "$BROKERKIT_VERSION"
|
|
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/dist/hf-tooling-seed.js
CHANGED
|
@@ -127,12 +127,18 @@ This workspace has Hugging Face tooling preinstalled. Use the Hugging Face CLI
|
|
|
127
127
|
work.
|
|
128
128
|
|
|
129
129
|
Protected Hugging Face mutations use the preconfigured HF Broker. Never ask
|
|
130
|
-
the user for a Hugging Face token and never run \`hf auth login\`.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
\`
|
|
130
|
+
the user for a Hugging Face token and never run \`hf auth login\`. Choose the
|
|
131
|
+
matching \`hf_*\` MCP tool for the operation. Omit \`request_id\` for a new
|
|
132
|
+
operation unless you deliberately need an exact retry identity. Record the
|
|
133
|
+
returned operation \`id\`, then use \`hf_operation_wait\` or
|
|
134
|
+
\`hf_operation_get\` to observe completion. Use the bounded
|
|
135
|
+
\`hf_operation_list\` tool, optionally filtered by \`request_id\`, to recover
|
|
136
|
+
an operation after an ambiguous transport timeout.
|
|
137
|
+
|
|
138
|
+
Never reuse a request ID for a different target or argument set. A request-ID
|
|
139
|
+
conflict is durable: inspect the existing operation instead of restarting the
|
|
140
|
+
broker. Protected actions appear in the ML Claw BrokerKit control and may also
|
|
141
|
+
be sent through configured OpenClaw channels.
|
|
136
142
|
|
|
137
143
|
After repository creation, use the brokered Git transport for repository
|
|
138
144
|
contents. The limited broker credential is not a Hugging Face Hub token; do
|
|
@@ -4698,7 +4698,7 @@ var approvalSchema = external_exports.object({
|
|
|
4698
4698
|
pending_expires_at: external_exports.string().datetime({ offset: true }).optional(),
|
|
4699
4699
|
active_expires_at: external_exports.string().datetime({ offset: true }).optional(),
|
|
4700
4700
|
requested_duration_seconds: external_exports.number().int().positive().safe(),
|
|
4701
|
-
requested_max_uses: external_exports.number().int().positive().safe(),
|
|
4701
|
+
requested_max_uses: external_exports.number().int().positive().safe().nullable(),
|
|
4702
4702
|
granted_max_uses: external_exports.number().int().positive().safe().nullable(),
|
|
4703
4703
|
used_count: external_exports.number().int().nonnegative().safe(),
|
|
4704
4704
|
request_reason: external_exports.string().max(2e3).optional(),
|
|
@@ -4712,10 +4712,10 @@ var approvalSchema = external_exports.object({
|
|
|
4712
4712
|
facts: external_exports.array(displayFieldSchema).max(20).optional()
|
|
4713
4713
|
}).strict(),
|
|
4714
4714
|
presentation_unavailable: external_exports.boolean().optional(),
|
|
4715
|
-
allowed_actions: external_exports.array(external_exports.enum(["approve", "deny", "
|
|
4715
|
+
allowed_actions: external_exports.array(external_exports.enum(["approve", "deny", "revoke"])).max(3),
|
|
4716
4716
|
approval_bounds: external_exports.object({
|
|
4717
4717
|
max_duration_seconds: external_exports.number().int().positive().safe(),
|
|
4718
|
-
max_uses: external_exports.number().int().positive().safe()
|
|
4718
|
+
max_uses: external_exports.number().int().positive().safe().nullable()
|
|
4719
4719
|
}).strict().optional()
|
|
4720
4720
|
}).strict();
|
|
4721
4721
|
var approvalPageSchema = external_exports.object({
|
|
@@ -4808,10 +4808,10 @@ var BrokerOperatorClient = class {
|
|
|
4808
4808
|
expected_revision: decision.expectedRevision,
|
|
4809
4809
|
idempotency_key: decision.idempotencyKey,
|
|
4810
4810
|
on_behalf_of: decision.onBehalfOf,
|
|
4811
|
-
...decision.durationSeconds || decision.maxUses ? {
|
|
4811
|
+
...decision.durationSeconds !== void 0 || decision.maxUses !== void 0 ? {
|
|
4812
4812
|
constraints: {
|
|
4813
|
-
...decision.durationSeconds ? { duration_seconds: decision.durationSeconds } : {},
|
|
4814
|
-
...decision.maxUses ? { max_uses: decision.maxUses } : {}
|
|
4813
|
+
...decision.durationSeconds !== void 0 ? { duration_seconds: decision.durationSeconds } : {},
|
|
4814
|
+
...decision.maxUses !== void 0 ? { max_uses: decision.maxUses } : {}
|
|
4815
4815
|
}
|
|
4816
4816
|
} : {}
|
|
4817
4817
|
})
|
|
@@ -7475,11 +7475,11 @@ var DelegatedBrokerKit = class {
|
|
|
7475
7475
|
renewal_transport: "direct"
|
|
7476
7476
|
};
|
|
7477
7477
|
}
|
|
7478
|
-
authorize(
|
|
7479
|
-
return this.authorizeSession(
|
|
7478
|
+
authorize(token) {
|
|
7479
|
+
return this.authorizeSession(token)?.actor;
|
|
7480
7480
|
}
|
|
7481
|
-
authorizeSession(
|
|
7482
|
-
const encoded = authenticatedTokenPayload(
|
|
7481
|
+
authorizeSession(token) {
|
|
7482
|
+
const encoded = authenticatedTokenPayload(token, (value) => this.sign(value));
|
|
7483
7483
|
if (!encoded) return void 0;
|
|
7484
7484
|
const payload = parseTokenPayload(encoded);
|
|
7485
7485
|
return payload && tokenIsCurrent(payload, this.now()) ? { actor: payload.subject, sessionId: payload.nonce, access: payload.access } : void 0;
|
|
@@ -7750,16 +7750,21 @@ function decisionOptions(record, action, expectedRevision, actor, options) {
|
|
|
7750
7750
|
idempotencyKey: decisionKey(record, action, actor),
|
|
7751
7751
|
onBehalfOf: `mlclaw:${actor}`,
|
|
7752
7752
|
...options.durationSeconds ? { durationSeconds: options.durationSeconds } : {},
|
|
7753
|
-
...options.maxUses ? { maxUses: options.maxUses } : {}
|
|
7753
|
+
...options.maxUses !== void 0 ? { maxUses: options.maxUses } : {}
|
|
7754
7754
|
};
|
|
7755
7755
|
}
|
|
7756
7756
|
function decisionWithinBounds(action, request, options) {
|
|
7757
7757
|
if (options.durationSeconds === void 0 && options.maxUses === void 0) return true;
|
|
7758
7758
|
const bounds = request.approval_bounds;
|
|
7759
7759
|
return Boolean(
|
|
7760
|
-
action === "approve" && bounds && options.durationSeconds !== void 0 && options.durationSeconds <= bounds.max_duration_seconds && options.maxUses
|
|
7760
|
+
action === "approve" && bounds && options.durationSeconds !== void 0 && options.durationSeconds <= bounds.max_duration_seconds && useLimitWithinBounds(options.maxUses, bounds.max_uses)
|
|
7761
7761
|
);
|
|
7762
7762
|
}
|
|
7763
|
+
function useLimitWithinBounds(requested, maximum) {
|
|
7764
|
+
if (requested === void 0) return false;
|
|
7765
|
+
if (requested === null) return maximum === null;
|
|
7766
|
+
return maximum === null || requested <= maximum;
|
|
7767
|
+
}
|
|
7763
7768
|
function assertDecisionAllowed(request, record, action, expectedRevision, options) {
|
|
7764
7769
|
if (request.revision !== record.revision || request.revision !== expectedRevision) {
|
|
7765
7770
|
throw delegatedError("revision_stale");
|
|
@@ -7768,10 +7773,8 @@ function assertDecisionAllowed(request, record, action, expectedRevision, option
|
|
|
7768
7773
|
throw delegatedError("action_not_allowed");
|
|
7769
7774
|
}
|
|
7770
7775
|
}
|
|
7771
|
-
function authenticatedTokenPayload(
|
|
7772
|
-
if (!
|
|
7773
|
-
const token = header.slice("Bearer ".length);
|
|
7774
|
-
if (token.length > 4096) return void 0;
|
|
7776
|
+
function authenticatedTokenPayload(token, sign3) {
|
|
7777
|
+
if (!token || token.length > 4096 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/u.test(token)) return void 0;
|
|
7775
7778
|
const [encoded, signature, extra] = token.split(".");
|
|
7776
7779
|
return encoded && signature && extra === void 0 && safeEqual(signature, sign3(encoded)) ? encoded : void 0;
|
|
7777
7780
|
}
|
|
@@ -8520,6 +8523,8 @@ function remainingUpstreamTimeout(deadline) {
|
|
|
8520
8523
|
}
|
|
8521
8524
|
|
|
8522
8525
|
// src/mlclaw-space-runtime/openclaw-config.ts
|
|
8526
|
+
var BROKER_MCP_CONNECTION_TIMEOUT_MS = 1e4;
|
|
8527
|
+
var BROKER_MCP_REQUEST_TIMEOUT_MS = 45e3;
|
|
8523
8528
|
async function configureOpenClawGateway(config2) {
|
|
8524
8529
|
const raw2 = await fs.readFile(config2.openclawConfigPath, "utf8");
|
|
8525
8530
|
const openclawConfig = JSON.parse(raw2);
|
|
@@ -8562,16 +8567,52 @@ function configureBrokerMcpServer(openclawConfig, config2) {
|
|
|
8562
8567
|
}
|
|
8563
8568
|
const existing = objectValue2(servers["huggingface-broker"]);
|
|
8564
8569
|
servers["huggingface-broker"] = {
|
|
8565
|
-
...existing,
|
|
8570
|
+
...preservedBrokerMcpFields(existing),
|
|
8566
8571
|
command: "/usr/local/bin/hf-broker",
|
|
8567
8572
|
args: ["mcp"],
|
|
8573
|
+
connectionTimeoutMs: BROKER_MCP_CONNECTION_TIMEOUT_MS,
|
|
8574
|
+
requestTimeoutMs: BROKER_MCP_REQUEST_TIMEOUT_MS,
|
|
8568
8575
|
env: {
|
|
8569
|
-
|
|
8570
|
-
|
|
8576
|
+
HF_BROKER_AGENT_ENDPOINT: brokerAgentEndpoint(config2.brokerAgentUrl),
|
|
8577
|
+
HF_BROKER_SHARED_SECRET_FILE: config2.brokerAgentSecretFile
|
|
8571
8578
|
},
|
|
8572
8579
|
...existing?.enabled === false ? { enabled: false } : { enabled: true }
|
|
8573
8580
|
};
|
|
8574
8581
|
}
|
|
8582
|
+
function brokerAgentEndpoint(agentUrl) {
|
|
8583
|
+
const parsed = new URL(agentUrl);
|
|
8584
|
+
if (parsed.protocol !== "http:" || !parsed.port || parsed.username || parsed.password) {
|
|
8585
|
+
throw new Error("HF Broker agent URL must be an unauthenticated HTTP URL with an explicit port");
|
|
8586
|
+
}
|
|
8587
|
+
return `tcp://${parsed.host}`;
|
|
8588
|
+
}
|
|
8589
|
+
function preservedBrokerMcpFields(existing) {
|
|
8590
|
+
const codex = preservedBrokerCodexConfig(objectValue2(existing?.codex));
|
|
8591
|
+
return {
|
|
8592
|
+
...existing?.toolFilter && typeof existing.toolFilter === "object" ? { toolFilter: existing.toolFilter } : {},
|
|
8593
|
+
...typeof existing?.supportsParallelToolCalls === "boolean" ? { supportsParallelToolCalls: existing.supportsParallelToolCalls } : {},
|
|
8594
|
+
...codex ? { codex } : {}
|
|
8595
|
+
};
|
|
8596
|
+
}
|
|
8597
|
+
function preservedBrokerCodexConfig(existing) {
|
|
8598
|
+
const agents = brokerAgentScope(existing?.agents);
|
|
8599
|
+
const defaultToolsApprovalMode = brokerApprovalMode(existing?.defaultToolsApprovalMode);
|
|
8600
|
+
const nativeApprovalMode = brokerApprovalMode(existing?.default_tools_approval_mode);
|
|
8601
|
+
const preserved = {
|
|
8602
|
+
...agents ? { agents } : {},
|
|
8603
|
+
...defaultToolsApprovalMode ? { defaultToolsApprovalMode } : {},
|
|
8604
|
+
...nativeApprovalMode ? { default_tools_approval_mode: nativeApprovalMode } : {}
|
|
8605
|
+
};
|
|
8606
|
+
return Object.keys(preserved).length > 0 ? preserved : void 0;
|
|
8607
|
+
}
|
|
8608
|
+
function brokerAgentScope(value) {
|
|
8609
|
+
if (!Array.isArray(value)) return void 0;
|
|
8610
|
+
const agents = value.filter((agent) => typeof agent === "string" && /^[a-z0-9][a-z0-9_-]{0,63}$/iu.test(agent.trim())).map((agent) => agent.trim());
|
|
8611
|
+
return agents.length > 0 ? agents : void 0;
|
|
8612
|
+
}
|
|
8613
|
+
function brokerApprovalMode(value) {
|
|
8614
|
+
return value === "auto" || value === "prompt" || value === "approve" ? value : void 0;
|
|
8615
|
+
}
|
|
8575
8616
|
function configureBrokerKitPlugin(openclawConfig, config2) {
|
|
8576
8617
|
const plugins = object(openclawConfig, "plugins");
|
|
8577
8618
|
const load = object(plugins, "load");
|
|
@@ -9510,6 +9551,7 @@ function escapeHtml2(value) {
|
|
|
9510
9551
|
}
|
|
9511
9552
|
|
|
9512
9553
|
// src/mlclaw-space-runtime/app.ts
|
|
9554
|
+
var BROKERKIT_SESSION_HEADER = "brokerkit-session";
|
|
9513
9555
|
function createSpaceRuntimeApp(config2, controls) {
|
|
9514
9556
|
const app = new Hono2();
|
|
9515
9557
|
const operatorBrokers = new OperatorBrokerRegistry(config2.operatorBrokers);
|
|
@@ -9649,7 +9691,7 @@ function createSpaceRuntimeApp(config2, controls) {
|
|
|
9649
9691
|
return delegatedFailure(c, error);
|
|
9650
9692
|
}
|
|
9651
9693
|
});
|
|
9652
|
-
for (const action of ["approve", "deny", "
|
|
9694
|
+
for (const action of ["approve", "deny", "revoke"]) {
|
|
9653
9695
|
app.post(`/mlclaw/api/brokerkit/requests/:handle/${action}`, async (c) => {
|
|
9654
9696
|
const identity = delegatedIdentity(c, delegatedBrokerKit);
|
|
9655
9697
|
if (!identity || identity.access !== "decide") return delegatedErrorResponse(c, "not_authorized", 401);
|
|
@@ -9660,7 +9702,7 @@ function createSpaceRuntimeApp(config2, controls) {
|
|
|
9660
9702
|
const constraints = recordValue(body.constraints);
|
|
9661
9703
|
const expectedRevision = positiveJsonInteger(body.expectedRevision);
|
|
9662
9704
|
const durationSeconds = optionalPositiveJsonInteger(constraints?.durationSeconds);
|
|
9663
|
-
const maxUses =
|
|
9705
|
+
const maxUses = optionalUseLimitJsonInteger(constraints?.maxUses);
|
|
9664
9706
|
if (!expectedRevision || body.constraints !== void 0 && (!constraints || Object.keys(constraints).some((key) => !["durationSeconds", "maxUses"].includes(key)) || durationSeconds === void 0 || maxUses === void 0) || durationSeconds === "invalid" || maxUses === "invalid" || action !== "approve" && (durationSeconds !== void 0 || maxUses !== void 0)) {
|
|
9665
9707
|
return delegatedErrorResponse(c, "invalid_input", 400);
|
|
9666
9708
|
}
|
|
@@ -9669,7 +9711,7 @@ function createSpaceRuntimeApp(config2, controls) {
|
|
|
9669
9711
|
c,
|
|
9670
9712
|
await delegatedBrokerKit.decide(c.req.param("handle"), action, expectedRevision, identity.actor, {
|
|
9671
9713
|
...typeof durationSeconds === "number" ? { durationSeconds } : {},
|
|
9672
|
-
...typeof maxUses === "number" ? { maxUses } : {}
|
|
9714
|
+
...typeof maxUses === "number" || maxUses === null ? { maxUses } : {}
|
|
9673
9715
|
})
|
|
9674
9716
|
);
|
|
9675
9717
|
} catch (error) {
|
|
@@ -9677,6 +9719,7 @@ function createSpaceRuntimeApp(config2, controls) {
|
|
|
9677
9719
|
}
|
|
9678
9720
|
});
|
|
9679
9721
|
}
|
|
9722
|
+
app.all("/mlclaw/api/brokerkit/*", (c) => delegatedErrorResponse(c, "not_found", 404));
|
|
9680
9723
|
app.post("/mlclaw/api/integrations/huggingface/disconnect", async (c) => {
|
|
9681
9724
|
const auth = requireAdmin(c, config2);
|
|
9682
9725
|
if (auth instanceof Response) {
|
|
@@ -10052,12 +10095,12 @@ function delegatedEventQuery(urlValue) {
|
|
|
10052
10095
|
}
|
|
10053
10096
|
function delegatedIdentity(c, delegated) {
|
|
10054
10097
|
if (!delegatedOriginAllowed(c)) return void 0;
|
|
10055
|
-
return delegated.authorizeSession(c.req.header(
|
|
10098
|
+
return delegated.authorizeSession(c.req.header(BROKERKIT_SESSION_HEADER));
|
|
10056
10099
|
}
|
|
10057
10100
|
function delegatedPreflight(c) {
|
|
10058
10101
|
if (!delegatedOriginAllowed(c)) return delegatedErrorResponse(c, "not_authorized", 403);
|
|
10059
10102
|
delegatedHeaders(c);
|
|
10060
|
-
c.header("access-control-allow-headers",
|
|
10103
|
+
c.header("access-control-allow-headers", `${BROKERKIT_SESSION_HEADER}, content-type`);
|
|
10061
10104
|
c.header("access-control-allow-methods", "GET, POST, OPTIONS");
|
|
10062
10105
|
c.header("access-control-max-age", "300");
|
|
10063
10106
|
return c.body(null, 204);
|
|
@@ -10080,13 +10123,22 @@ function delegatedFailure(c, error) {
|
|
|
10080
10123
|
const status = error.status === 404 ? 404 : error.status === 409 ? 409 : 502;
|
|
10081
10124
|
return delegatedErrorResponse(c, code, status);
|
|
10082
10125
|
}
|
|
10083
|
-
process.stderr.write(
|
|
10084
|
-
`)
|
|
10126
|
+
process.stderr.write(
|
|
10127
|
+
`[mlclaw] delegated BrokerKit request failed: route=${delegatedRouteLabel(c)} status=502 class=${safeErrorClass(error)}
|
|
10128
|
+
`
|
|
10129
|
+
);
|
|
10085
10130
|
return delegatedErrorResponse(c, "source_unavailable", 502);
|
|
10086
10131
|
}
|
|
10132
|
+
function delegatedRouteLabel(c) {
|
|
10133
|
+
const pathLabel = c.req.path.replace(/\/requests\/[^/]+/u, "/requests/:handle");
|
|
10134
|
+
return `${c.req.method}:${pathLabel}`;
|
|
10135
|
+
}
|
|
10136
|
+
function safeErrorClass(error) {
|
|
10137
|
+
const name = error instanceof Error ? error.name : typeof error;
|
|
10138
|
+
return /^[A-Za-z][A-Za-z0-9]{0,79}$/u.test(name) ? name : "unknown";
|
|
10139
|
+
}
|
|
10087
10140
|
function delegatedHeaders(c) {
|
|
10088
10141
|
c.header("access-control-allow-origin", "null");
|
|
10089
|
-
c.header("access-control-allow-credentials", "true");
|
|
10090
10142
|
c.header("cache-control", "no-store");
|
|
10091
10143
|
c.header("vary", "origin");
|
|
10092
10144
|
c.header("x-content-type-options", "nosniff");
|
|
@@ -10263,6 +10315,10 @@ function optionalPositiveJsonInteger(value) {
|
|
|
10263
10315
|
if (value === void 0) return void 0;
|
|
10264
10316
|
return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : "invalid";
|
|
10265
10317
|
}
|
|
10318
|
+
function optionalUseLimitJsonInteger(value) {
|
|
10319
|
+
if (value === null) return null;
|
|
10320
|
+
return optionalPositiveJsonInteger(value);
|
|
10321
|
+
}
|
|
10266
10322
|
function fixedWindowRateLimit(limit, windowMs) {
|
|
10267
10323
|
const windows = /* @__PURE__ */ new Map();
|
|
10268
10324
|
return (key) => {
|
package/dist/mlclaw.mjs
CHANGED
|
@@ -14836,9 +14836,9 @@ function sseDataToText(raw) {
|
|
|
14836
14836
|
import fs11 from "node:fs";
|
|
14837
14837
|
import path12 from "node:path";
|
|
14838
14838
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
14839
|
-
var DEFAULT_OPENCLAW_VERSION = "2026.7.1
|
|
14840
|
-
var DEFAULT_BROKERKIT_PLUGIN_VERSION = "0.1
|
|
14841
|
-
var DEFAULT_BROKERKIT_VERSION = "
|
|
14839
|
+
var DEFAULT_OPENCLAW_VERSION = "2026.7.1";
|
|
14840
|
+
var DEFAULT_BROKERKIT_PLUGIN_VERSION = "0.2.1";
|
|
14841
|
+
var DEFAULT_BROKERKIT_VERSION = "hf-broker/v0.1.0";
|
|
14842
14842
|
var DEFAULT_RUNTIME_IMAGE_REPOSITORY = "ghcr.io/osolmaz/mlclaw";
|
|
14843
14843
|
var PACKAGE_METADATA = readPackageMetadata();
|
|
14844
14844
|
var PACKAGE_VERSION = packageString("version", "unknown");
|
|
@@ -14981,9 +14981,9 @@ ARG BROKERKIT_VERSION=${BROKERKIT_VERSION}
|
|
|
14981
14981
|
FROM golang:1.26.5-bookworm AS hf-broker-build
|
|
14982
14982
|
ARG BROKERKIT_VERSION
|
|
14983
14983
|
RUN git init /src \\
|
|
14984
|
-
&& git -C /src fetch --depth=1 https://github.com/osolmaz/brokerkit.git "
|
|
14985
|
-
&& git -C /src checkout --detach
|
|
14986
|
-
&& test "$(git -C /src rev-parse
|
|
14984
|
+
&& git -C /src fetch --depth=1 https://github.com/osolmaz/brokerkit.git "refs/tags/$BROKERKIT_VERSION:refs/tags/$BROKERKIT_VERSION" \\
|
|
14985
|
+
&& git -C /src checkout --detach "$BROKERKIT_VERSION" \\
|
|
14986
|
+
&& test "$(git -C /src rev-parse "refs/tags/$BROKERKIT_VERSION^{commit}")" = "$(git -C /src rev-parse HEAD)" \\
|
|
14987
14987
|
&& cd /src \\
|
|
14988
14988
|
&& GOWORK=off go build -trimpath -o /out/hf-broker ./brokers/huggingface/cmd/hf-broker \\
|
|
14989
14989
|
&& /out/hf-broker policy render \\
|
|
@@ -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 "$BROKERKIT_VERSION" && git -C /src checkout --detach FETCH_HEAD && test "$(git -C /src rev-parse HEAD)" = "$BROKERKIT_VERSION"
|
|
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
|
package/entrypoint.sh
CHANGED
|
@@ -93,10 +93,8 @@ start_hf_broker() {
|
|
|
93
93
|
HF_BROKER_HF_TOKEN_FILE="$HF_BROKER_RUN_DIR/hf-token" \
|
|
94
94
|
HF_BROKER_SECRETS_FILE="$HF_BROKER_RUN_DIR/agent-secrets.conf" \
|
|
95
95
|
HF_BROKER_OPERATOR_SECRETS_FILE="$HF_BROKER_RUN_DIR/operator-secrets.conf" \
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
HF_BROKER_OPERATOR_BIND_ADDR=127.0.0.1 \
|
|
99
|
-
HF_BROKER_OPERATOR_PORT=7864 \
|
|
96
|
+
HF_BROKER_AGENT_ENDPOINT=tcp://127.0.0.1:7863 \
|
|
97
|
+
HF_BROKER_OPERATOR_ENDPOINT=tcp://127.0.0.1:7864 \
|
|
100
98
|
HF_BROKER_SCOPE_FILE=/app/hf-broker.scope.json \
|
|
101
99
|
HF_BROKER_STATE_DIR="$HF_BROKER_STATE_DIR" \
|
|
102
100
|
gosu hf-broker:hf-broker /usr/local/bin/hf-broker &
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mlclaw",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"config": {
|
|
6
|
-
"openclawVersion": "2026.7.1
|
|
7
|
-
"brokerkitVersion": "
|
|
8
|
-
"brokerkitPluginVersion": "0.1
|
|
6
|
+
"openclawVersion": "2026.7.1",
|
|
7
|
+
"brokerkitVersion": "hf-broker/v0.1.0",
|
|
8
|
+
"brokerkitPluginVersion": "0.2.1",
|
|
9
9
|
"runtimeImageRepository": "ghcr.io/osolmaz/mlclaw"
|
|
10
10
|
},
|
|
11
11
|
"repository": {
|
|
@@ -55,8 +55,8 @@
|
|
|
55
55
|
"pack:check": "node scripts/check-package.mjs",
|
|
56
56
|
"prepack": "npm run build",
|
|
57
57
|
"check:secrets": "node scripts/check-secrets.mjs",
|
|
58
|
-
"format": "prettier --check eslint.config.mjs vitest.config.ts vitest.stryker.config.ts package.json README.md src/hf-state-sync/archive.ts src/hf-state-sync/cli.ts src/hf-state-sync/paths.ts src/hf-state-sync/prepare.ts src/hf-state-sync/stage-worker.ts src/hf-state-sync/supervise.ts src/mlclaw-space-runtime/delegated-brokerkit.ts src/mlclaw-space-runtime/delegated-revisions.ts src/mlclaw-space-runtime/operator-brokers.ts src/mlclaw-space-runtime/openclaw-config.ts src/mlclaw-space-runtime/app.ts src/mlclaw-space-runtime/config.ts src/mlclaw-space-runtime/openai-credentials.ts src/mlclaw-space-runtime/server.ts src/mlclaw-space-runtime/shell.ts src/mlclaw-control-ui/src/main.tsx src/mlclaw-control-ui/src/styles.css src/mlclaw-control-ui/src/components/ui/utils.ts src/mlclaw/git.ts test/hf-state-sync.archive.test.ts test/hf-state-sync.roundtrip.test.ts test/hf-state-sync.supervise.test.ts test/mlclaw.bundle.test.ts test/mlclaw.delegated-brokerkit.test.ts test/mlclaw.generate-space.test.ts test/mlclaw.operator-brokers.test.ts test/mlclaw.runtime-image.test.ts test/mlclaw.space-runtime.test.ts docs/operator-brokers-config.md",
|
|
59
|
-
"format:write": "prettier --write eslint.config.mjs vitest.config.ts vitest.stryker.config.ts package.json README.md src/hf-state-sync/archive.ts src/hf-state-sync/cli.ts src/hf-state-sync/paths.ts src/hf-state-sync/prepare.ts src/hf-state-sync/stage-worker.ts src/hf-state-sync/supervise.ts src/mlclaw-space-runtime/delegated-brokerkit.ts src/mlclaw-space-runtime/delegated-revisions.ts src/mlclaw-space-runtime/operator-brokers.ts src/mlclaw-space-runtime/openclaw-config.ts src/mlclaw-space-runtime/app.ts src/mlclaw-space-runtime/config.ts src/mlclaw-space-runtime/openai-credentials.ts src/mlclaw-space-runtime/server.ts src/mlclaw-space-runtime/shell.ts src/mlclaw-control-ui/src/main.tsx src/mlclaw-control-ui/src/styles.css src/mlclaw-control-ui/src/components/ui/utils.ts src/mlclaw/git.ts test/hf-state-sync.archive.test.ts test/hf-state-sync.roundtrip.test.ts test/hf-state-sync.supervise.test.ts test/mlclaw.bundle.test.ts test/mlclaw.delegated-brokerkit.test.ts test/mlclaw.generate-space.test.ts test/mlclaw.operator-brokers.test.ts test/mlclaw.runtime-image.test.ts test/mlclaw.space-runtime.test.ts docs/operator-brokers-config.md",
|
|
58
|
+
"format": "prettier --check eslint.config.mjs vitest.config.ts vitest.stryker.config.ts package.json README.md src/hf-state-sync/archive.ts src/hf-state-sync/cli.ts src/hf-state-sync/paths.ts src/hf-state-sync/prepare.ts src/hf-state-sync/stage-worker.ts src/hf-state-sync/supervise.ts src/mlclaw-space-runtime/delegated-brokerkit.ts src/mlclaw-space-runtime/delegated-revisions.ts src/mlclaw-space-runtime/operator-brokers.ts src/mlclaw-space-runtime/openclaw-config.ts src/mlclaw-space-runtime/app.ts src/mlclaw-space-runtime/config.ts src/mlclaw-space-runtime/openai-credentials.ts src/mlclaw-space-runtime/server.ts src/mlclaw-space-runtime/shell.ts src/mlclaw-control-ui/src/main.tsx src/mlclaw-control-ui/src/styles.css src/mlclaw-control-ui/src/components/ui/utils.ts src/mlclaw/git.ts test/hf-state-sync.archive.test.ts test/hf-state-sync.roundtrip.test.ts test/hf-state-sync.supervise.test.ts test/mlclaw.brokerkit-agent-tools.test.ts test/mlclaw.bundle.test.ts test/mlclaw.delegated-brokerkit.test.ts test/mlclaw.generate-space.test.ts test/mlclaw.operator-brokers.test.ts test/mlclaw.runtime-image.test.ts test/mlclaw.space-runtime.test.ts docs/operator-brokers-config.md",
|
|
59
|
+
"format:write": "prettier --write eslint.config.mjs vitest.config.ts vitest.stryker.config.ts package.json README.md src/hf-state-sync/archive.ts src/hf-state-sync/cli.ts src/hf-state-sync/paths.ts src/hf-state-sync/prepare.ts src/hf-state-sync/stage-worker.ts src/hf-state-sync/supervise.ts src/mlclaw-space-runtime/delegated-brokerkit.ts src/mlclaw-space-runtime/delegated-revisions.ts src/mlclaw-space-runtime/operator-brokers.ts src/mlclaw-space-runtime/openclaw-config.ts src/mlclaw-space-runtime/app.ts src/mlclaw-space-runtime/config.ts src/mlclaw-space-runtime/openai-credentials.ts src/mlclaw-space-runtime/server.ts src/mlclaw-space-runtime/shell.ts src/mlclaw-control-ui/src/main.tsx src/mlclaw-control-ui/src/styles.css src/mlclaw-control-ui/src/components/ui/utils.ts src/mlclaw/git.ts test/hf-state-sync.archive.test.ts test/hf-state-sync.roundtrip.test.ts test/hf-state-sync.supervise.test.ts test/mlclaw.brokerkit-agent-tools.test.ts test/mlclaw.bundle.test.ts test/mlclaw.delegated-brokerkit.test.ts test/mlclaw.generate-space.test.ts test/mlclaw.operator-brokers.test.ts test/mlclaw.runtime-image.test.ts test/mlclaw.space-runtime.test.ts docs/operator-brokers-config.md",
|
|
60
60
|
"lint": "eslint --max-warnings 0 src/mlclaw-space-runtime/delegated-brokerkit.ts src/mlclaw-space-runtime/delegated-revisions.ts src/mlclaw-space-runtime/operator-brokers.ts src/mlclaw-space-runtime/openclaw-config.ts",
|
|
61
61
|
"coverage": "vitest run --coverage",
|
|
62
62
|
"dry": "slophammer-ts dry .",
|