openzoo 0.39.0 → 0.39.2
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/lib/boxes.js +24 -11
- package/lib/proxy.js +9 -1
- package/package.json +1 -1
package/lib/boxes.js
CHANGED
|
@@ -32,29 +32,40 @@ function podAgentB64() {
|
|
|
32
32
|
const REST = 'https://rest.runpod.io/v1';
|
|
33
33
|
export const BOX_PREFIX = 'openzoo-box-';
|
|
34
34
|
const CPU_FLAVORS = ['cpu3c', 'cpu3g', 'cpu5c'];
|
|
35
|
-
|
|
35
|
+
// GLIBC, NOT ALPINE. `npx openzoo` pulls native deps (ed25519 / ws helpers);
|
|
36
|
+
// on musl they fail to build because the entrypoint has no toolchain, which is
|
|
37
|
+
// why alpine boxes sat at 404 forever. Debian-slim runs the shim as published,
|
|
38
|
+
// and its apt has a real sshd.
|
|
39
|
+
const BOX_IMAGE = process.env.OPENZOO_BOX_IMAGE || 'node:22-slim';
|
|
36
40
|
const BOX_PORTS = ['8402/http', '1337/http', '6080/http', '1340/http', '6081/http', '22/tcp'];
|
|
37
41
|
const TTL_MAX_HOURS = 90 * 24;
|
|
38
42
|
|
|
39
43
|
/**
|
|
40
|
-
* Boot: write the wallet, start the x402 proxy
|
|
44
|
+
* Boot: write the wallet, START SSHD, start the x402 proxy + capture agent.
|
|
41
45
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
46
|
+
* SSHD IS NOT OPTIONAL and was the second bug: our dockerStartCmd replaces the
|
|
47
|
+
* image's own init, so nothing starts sshd and every `execInBox` got
|
|
48
|
+
* "connection refused" — the agent had no hands. RunPod injects the account
|
|
49
|
+
* key at $PUBLIC_KEY / $SSH_PUBLIC_KEY; we write it to authorized_keys, generate
|
|
50
|
+
* host keys, and run sshd in the foreground of the background. Passwordless
|
|
51
|
+
* root login is NOT enabled — key-only.
|
|
52
|
+
*
|
|
53
|
+
* `npx --yes openzoo` is still fetched at boot so a box always runs the
|
|
54
|
+
* published shim; readyBox() polls /v1/models rather than assuming a timing.
|
|
47
55
|
*/
|
|
48
56
|
const ENTRYPOINT = [
|
|
49
|
-
'
|
|
50
|
-
'set
|
|
57
|
+
'bash', '-lc',
|
|
58
|
+
'set +e; mkdir -p /workspace /root/.openzoo /var/log/openzoo /run/sshd /root/.ssh; '
|
|
51
59
|
+ 'if [ -n "$OPENZOO_WALLET_JSON" ]; then printf %s "$OPENZOO_WALLET_JSON" > /root/.openzoo/wallet.json; chmod 600 /root/.openzoo/wallet.json; fi; '
|
|
52
|
-
+ '
|
|
60
|
+
+ 'export DEBIAN_FRONTEND=noninteractive; apt-get update >/dev/null 2>&1; apt-get install -y --no-install-recommends openssh-server git ca-certificates >/dev/null 2>&1; '
|
|
61
|
+
// RunPod hands the operator pubkey in one of these — accept whichever is set
|
|
62
|
+
+ 'for K in "$PUBLIC_KEY" "$SSH_PUBLIC_KEY"; do [ -n "$K" ] && echo "$K" >> /root/.ssh/authorized_keys; done; chmod 600 /root/.ssh/authorized_keys 2>/dev/null; '
|
|
63
|
+
+ 'ssh-keygen -A >/dev/null 2>&1; sed -i "s/^#\\?PermitRootLogin.*/PermitRootLogin prohibit-password/" /etc/ssh/sshd_config 2>/dev/null; /usr/sbin/sshd -e >/var/log/openzoo/sshd.log 2>&1 & '
|
|
53
64
|
+ 'npx --yes openzoo > /var/log/openzoo/proxy.log 2>&1 & '
|
|
54
65
|
// the capture agent answers the ports Grok Bot expects a Cursor sandbox on,
|
|
55
66
|
// logging the protocol we do not yet speak (see lib/podagent.mjs)
|
|
56
67
|
+ 'if [ -n "$OZ_PODAGENT_B64" ]; then printf %s "$OZ_PODAGENT_B64" | base64 -d > /opt/podagent.mjs; node /opt/podagent.mjs > /var/log/openzoo/agent.log 2>&1 & fi; '
|
|
57
|
-
+ '
|
|
68
|
+
+ 'sleep infinity',
|
|
58
69
|
];
|
|
59
70
|
|
|
60
71
|
function key() {
|
|
@@ -185,6 +196,8 @@ export async function spawnBox({ name = 'bot', days = 1, vcpu = 2, walletJson, p
|
|
|
185
196
|
OPENZOO_BOX: '1',
|
|
186
197
|
OPENZOO_EXPIRES_UNIX: String(unix),
|
|
187
198
|
OPENZOO_NO_TUNNEL: '1', // the runpod proxy already fronts it
|
|
199
|
+
OPENZOO_BIND: '0.0.0.0', // else the runpod proxy can't reach :8402
|
|
200
|
+
OPENZOO_TUNNEL_TOKEN: `oz-${Math.random().toString(36).slice(2)}${Math.random().toString(36).slice(2)}`,
|
|
188
201
|
...(walletJson ? { OPENZOO_WALLET_JSON: walletJson } : {}),
|
|
189
202
|
...(pubkey ? { OPENZOO_WALLET_PUBKEY: pubkey } : {}),
|
|
190
203
|
OZ_PODAGENT_B64: podAgentB64(),
|
package/lib/proxy.js
CHANGED
|
@@ -715,9 +715,17 @@ export async function startProxy({ silent = false, requireToken = null, sessionM
|
|
|
715
715
|
}
|
|
716
716
|
});
|
|
717
717
|
|
|
718
|
+
// BIND HOST. Default 127.0.0.1 — the keyless localhost path must never be
|
|
719
|
+
// world-reachable on an ordinary machine. A RunPod box is the exception: its
|
|
720
|
+
// HTTP proxy reaches the container over the pod network, so a localhost bind
|
|
721
|
+
// shows "Initializing…" forever (MEASURED: podagent's 0.0.0.0 ports went
|
|
722
|
+
// Ready, the 127.0.0.1 proxy never did). The box sets OPENZOO_BIND=0.0.0.0
|
|
723
|
+
// AND a tunnel token, so the RunPod-fronted port stays gated exactly like the
|
|
724
|
+
// public tunnel path.
|
|
725
|
+
const bindHost = process.env.OPENZOO_BIND || '127.0.0.1';
|
|
718
726
|
await new Promise((resolve, reject) => {
|
|
719
727
|
server.on('error', reject);
|
|
720
|
-
server.listen(config.port,
|
|
728
|
+
server.listen(config.port, bindHost, resolve);
|
|
721
729
|
});
|
|
722
730
|
|
|
723
731
|
if (!silent) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openzoo",
|
|
3
|
-
"version": "0.39.
|
|
3
|
+
"version": "0.39.2",
|
|
4
4
|
"description": "Local x402-paying proxy + MCP server for openzoo.fun — point any OpenAI-compatible harness (Cursor, Claude Code, aider, SDKs) at localhost and it pays per call from a local burner wallet. Solana and Base rails live; Robinhood experimental.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|