Update README and guide for model configuration and Supabase integration; enhance setup script for fallback models
Browse files- README.md +15 -23
- guide.md +90 -225
- setup-hf-config.mjs +8 -1
README.md
CHANGED
|
@@ -23,32 +23,34 @@ This Space runs the [OpenClaw](https://github.com/openclaw/openclaw) gateway so
|
|
| 23 |
- **`OPENCLAW_GATEWAY_TOKEN`** — long random string (e.g. `openssl rand -hex 24`). Paste this in the Control UI to log in. **Recommended.** (Alternative: use `OPENCLAW_GATEWAY_PASSWORD` for password auth; if both are set, token is used.)
|
| 24 |
- **`OPENCLAW_GATEWAY_PASSWORD`** — (optional) Gateway password; startup script sets `gateway.auth.mode: "password"`. Use when you prefer password over token.
|
| 25 |
- **`HF_TOKEN`** — your [Hugging Face token](https://huggingface.co/settings/tokens) with **Make calls to Inference Providers**. Needed only when you want to use the Hugging Face provider; without it, choose another provider such as Gemini or OpenCode.
|
| 26 |
-
- **`GEMINI_API_KEY`** — (optional
|
| 27 |
- **`OPENCODE_API_KEY`** — (optional) OpenCode Zen API key. OpenClaw reads this directly from the gateway environment for the `opencode` provider.
|
| 28 |
- **`SUPABASE_URL`** — (recommended) Supabase project URL for external state backup.
|
| 29 |
- **`SUPABASE_KEY`** — (recommended) Supabase service key or project API key with insert/update access to your sync table.
|
| 30 |
-
- **`OPENCLAW_DEFAULT_MODEL`** — (optional)
|
|
|
|
| 31 |
- **`OPENCLAW_HF_DEFAULT_MODEL`** — (optional, legacy alias) Backwards-compatible alias for `OPENCLAW_DEFAULT_MODEL`. If both are set, `OPENCLAW_DEFAULT_MODEL` wins.
|
| 32 |
- **`OPENCLAW_GATEWAY_TRUSTED_PROXIES`** — (optional) Comma-separated proxy IPs (e.g. `10.20.31.87,10.20.26.157`). The startup script writes this into `gateway.trustedProxies`; set if you see “Proxy headers detected from untrusted address” or pairing/unauthorized. Use **Variables** if you prefer (IPs need not be secret).
|
| 33 |
- **`OPENCLAW_CONTROL_UI_ALLOWED_ORIGINS`** — (optional) Comma-separated origins (e.g. `https://your-space.hf.space`). Written to `gateway.controlUi.allowedOrigins` so only those origins can open the Control UI; useful to lock down to your Space URL.
|
| 34 |
- **`TELEGRAM_BOT_TOKEN`** — (optional) Telegram BotFather token. This is the only Telegram setting you need for a minimal setup.
|
| 35 |
- **`OPENCLAW_TELEGRAM_DM_POLICY`** / **`OPENCLAW_TELEGRAM_ALLOW_FROM`** / **`OPENCLAW_TELEGRAM_GROUP_POLICY`** / **`OPENCLAW_TELEGRAM_GROUP_ALLOW_FROM`** / **`OPENCLAW_TELEGRAM_REQUIRE_MENTION`** — (optional) Advanced Telegram access-control settings.
|
| 36 |
-
4. **Build and run** — push to the Space repo; the Space will build and start the gateway. Startup writes config so the default model is `gpt-codex`, the Control UI accepts token-only connections (no device pairing), and Supabase sync starts automatically when `SUPABASE_URL` + `SUPABASE_KEY` are present.
|
| 37 |
|
| 38 |
When the logs show `listening on ws://0.0.0.0:7860`, open your Space’s URL (e.g. `https://your-username-openclaw-gateway.hf.space`) and paste the gateway token in **Settings → token** (or use `https://your-space.hf.space#token=YOUR_TOKEN`).
|
| 39 |
|
| 40 |
-
##
|
| 41 |
|
| 42 |
-
- **Default behavior in this repo** is now
|
| 43 |
-
-
|
| 44 |
-
-
|
| 45 |
-
- **
|
|
|
|
| 46 |
- **OpenCode Zen** also works well in Hugging Face Spaces. Set `OPENCODE_API_KEY` and use a default model such as `opencode/claude-opus-4-6`.
|
| 47 |
-
- **Codex
|
| 48 |
- **Telegram minimal setup** only needs `TELEGRAM_BOT_TOKEN`.
|
| 49 |
- **Telegram advanced settings** are optional and only needed when you want allowlists, group restrictions, or mention-only behavior.
|
| 50 |
|
| 51 |
-
Minimal example for `
|
| 52 |
|
| 53 |
```text
|
| 54 |
Secrets
|
|
@@ -58,24 +60,13 @@ SUPABASE_KEY=<your supabase service key>
|
|
| 58 |
TELEGRAM_BOT_TOKEN=<botfather token>
|
| 59 |
|
| 60 |
Variables
|
| 61 |
-
OPENCLAW_DEFAULT_MODEL=
|
|
|
|
| 62 |
OPENCLAW_CONTROL_UI_ALLOWED_ORIGINS=https://your-space.hf.space
|
| 63 |
OPENCLAW_SUPABASE_TABLE=openclaw_state
|
| 64 |
OPENCLAW_SYNC_INTERVAL_MS=300000
|
| 65 |
```
|
| 66 |
|
| 67 |
-
If you want Telegram access controls later, add the optional `OPENCLAW_TELEGRAM_*` variables.
|
| 68 |
-
|
| 69 |
-
If you want to switch the primary model to Gemini fallback mode:
|
| 70 |
-
|
| 71 |
-
```text
|
| 72 |
-
Secrets
|
| 73 |
-
GEMINI_API_KEY=<your google ai studio key>
|
| 74 |
-
|
| 75 |
-
Variables
|
| 76 |
-
OPENCLAW_DEFAULT_MODEL=google/gemini-3.1-pro-preview
|
| 77 |
-
```
|
| 78 |
-
|
| 79 |
## Keep it running 24/7
|
| 80 |
|
| 81 |
- **Free hardware:** The Space will **sleep after ~48 hours** of inactivity. Anyone opening the URL will wake it.
|
|
@@ -153,6 +144,7 @@ The startup script `setup-hf-config.mjs` reads the following from **Secrets** or
|
|
| 153 |
| Env variable | Config path | Format |
|
| 154 |
|--------------|------------|--------|
|
| 155 |
| `OPENCLAW_DEFAULT_MODEL` | `agents.defaults.model.primary` | Generic model ref string |
|
|
|
|
| 156 |
| `OPENCLAW_HF_DEFAULT_MODEL` | `agents.defaults.model.primary` | Legacy alias for `OPENCLAW_DEFAULT_MODEL` |
|
| 157 |
| `OPENCLAW_GATEWAY_TOKEN` | `gateway.auth.mode` + `gateway.auth.token` | Any string |
|
| 158 |
| `OPENCLAW_GATEWAY_PASSWORD` | `gateway.auth.mode` + `gateway.auth.password` | Any string (token wins if both set) |
|
|
|
|
| 23 |
- **`OPENCLAW_GATEWAY_TOKEN`** — long random string (e.g. `openssl rand -hex 24`). Paste this in the Control UI to log in. **Recommended.** (Alternative: use `OPENCLAW_GATEWAY_PASSWORD` for password auth; if both are set, token is used.)
|
| 24 |
- **`OPENCLAW_GATEWAY_PASSWORD`** — (optional) Gateway password; startup script sets `gateway.auth.mode: "password"`. Use when you prefer password over token.
|
| 25 |
- **`HF_TOKEN`** — your [Hugging Face token](https://huggingface.co/settings/tokens) with **Make calls to Inference Providers**. Needed only when you want to use the Hugging Face provider; without it, choose another provider such as Gemini or OpenCode.
|
| 26 |
+
- **`GEMINI_API_KEY`** — (optional) Google Gemini API key. Not needed for the default DeepSeek -> Qwen -> Codex chain.
|
| 27 |
- **`OPENCODE_API_KEY`** — (optional) OpenCode Zen API key. OpenClaw reads this directly from the gateway environment for the `opencode` provider.
|
| 28 |
- **`SUPABASE_URL`** — (recommended) Supabase project URL for external state backup.
|
| 29 |
- **`SUPABASE_KEY`** — (recommended) Supabase service key or project API key with insert/update access to your sync table.
|
| 30 |
+
- **`OPENCLAW_DEFAULT_MODEL`** — (optional) Primary model ref. This repo now defaults to `huggingface/Qwen/Qwen3-8B`.
|
| 31 |
+
- **`OPENCLAW_FALLBACK_MODELS`** — (optional) Comma-separated fallback model refs. This repo now defaults to `huggingface/deepseek-ai/DeepSeek-R1,gpt-codex`.
|
| 32 |
- **`OPENCLAW_HF_DEFAULT_MODEL`** — (optional, legacy alias) Backwards-compatible alias for `OPENCLAW_DEFAULT_MODEL`. If both are set, `OPENCLAW_DEFAULT_MODEL` wins.
|
| 33 |
- **`OPENCLAW_GATEWAY_TRUSTED_PROXIES`** — (optional) Comma-separated proxy IPs (e.g. `10.20.31.87,10.20.26.157`). The startup script writes this into `gateway.trustedProxies`; set if you see “Proxy headers detected from untrusted address” or pairing/unauthorized. Use **Variables** if you prefer (IPs need not be secret).
|
| 34 |
- **`OPENCLAW_CONTROL_UI_ALLOWED_ORIGINS`** — (optional) Comma-separated origins (e.g. `https://your-space.hf.space`). Written to `gateway.controlUi.allowedOrigins` so only those origins can open the Control UI; useful to lock down to your Space URL.
|
| 35 |
- **`TELEGRAM_BOT_TOKEN`** — (optional) Telegram BotFather token. This is the only Telegram setting you need for a minimal setup.
|
| 36 |
- **`OPENCLAW_TELEGRAM_DM_POLICY`** / **`OPENCLAW_TELEGRAM_ALLOW_FROM`** / **`OPENCLAW_TELEGRAM_GROUP_POLICY`** / **`OPENCLAW_TELEGRAM_GROUP_ALLOW_FROM`** / **`OPENCLAW_TELEGRAM_REQUIRE_MENTION`** — (optional) Advanced Telegram access-control settings.
|
| 37 |
+
4. **Build and run** — push to the Space repo; the Space will build and start the gateway. Startup writes config so the default model chain is `Qwen3-8B -> DeepSeek-R1 -> gpt-codex`, the Control UI accepts token-only connections (no device pairing), and Supabase sync starts automatically when `SUPABASE_URL` + `SUPABASE_KEY` are present.
|
| 38 |
|
| 39 |
When the logs show `listening on ws://0.0.0.0:7860`, open your Space’s URL (e.g. `https://your-username-openclaw-gateway.hf.space`) and paste the gateway token in **Settings → token** (or use `https://your-space.hf.space#token=YOUR_TOKEN`).
|
| 40 |
|
| 41 |
+
## DeepSeek Primary, Qwen and Codex Fallback, and Telegram
|
| 42 |
|
| 43 |
+
- **Default behavior in this repo** is now:
|
| 44 |
+
- primary: `huggingface/Qwen/Qwen3-8B`
|
| 45 |
+
- fallbacks: `huggingface/deepseek-ai/DeepSeek-R1`, `gpt-codex`
|
| 46 |
+
- **The startup script now writes both `primary` and `fallbacks`.**
|
| 47 |
+
- **Codex fallback only works if Codex itself is already authenticated and usable.** If `gpt-codex` still lacks auth, fallback will still fail when traffic reaches it.
|
| 48 |
- **OpenCode Zen** also works well in Hugging Face Spaces. Set `OPENCODE_API_KEY` and use a default model such as `opencode/claude-opus-4-6`.
|
| 49 |
+
- **Codex auth remains the special case**: if your `gpt-codex` path depends on OAuth-backed credentials, use a separate environment that can complete the login flow first, or expect the Codex fallback to fail.
|
| 50 |
- **Telegram minimal setup** only needs `TELEGRAM_BOT_TOKEN`.
|
| 51 |
- **Telegram advanced settings** are optional and only needed when you want allowlists, group restrictions, or mention-only behavior.
|
| 52 |
|
| 53 |
+
Minimal example for `Qwen -> DeepSeek -> Codex` + Supabase + Telegram:
|
| 54 |
|
| 55 |
```text
|
| 56 |
Secrets
|
|
|
|
| 60 |
TELEGRAM_BOT_TOKEN=<botfather token>
|
| 61 |
|
| 62 |
Variables
|
| 63 |
+
OPENCLAW_DEFAULT_MODEL=huggingface/Qwen/Qwen3-8B
|
| 64 |
+
OPENCLAW_FALLBACK_MODELS=huggingface/deepseek-ai/DeepSeek-R1,gpt-codex
|
| 65 |
OPENCLAW_CONTROL_UI_ALLOWED_ORIGINS=https://your-space.hf.space
|
| 66 |
OPENCLAW_SUPABASE_TABLE=openclaw_state
|
| 67 |
OPENCLAW_SYNC_INTERVAL_MS=300000
|
| 68 |
```
|
| 69 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
## Keep it running 24/7
|
| 71 |
|
| 72 |
- **Free hardware:** The Space will **sleep after ~48 hours** of inactivity. Anyone opening the URL will wake it.
|
|
|
|
| 144 |
| Env variable | Config path | Format |
|
| 145 |
|--------------|------------|--------|
|
| 146 |
| `OPENCLAW_DEFAULT_MODEL` | `agents.defaults.model.primary` | Generic model ref string |
|
| 147 |
+
| `OPENCLAW_FALLBACK_MODELS` | `agents.defaults.model.fallbacks` | Comma-separated model refs |
|
| 148 |
| `OPENCLAW_HF_DEFAULT_MODEL` | `agents.defaults.model.primary` | Legacy alias for `OPENCLAW_DEFAULT_MODEL` |
|
| 149 |
| `OPENCLAW_GATEWAY_TOKEN` | `gateway.auth.mode` + `gateway.auth.token` | Any string |
|
| 150 |
| `OPENCLAW_GATEWAY_PASSWORD` | `gateway.auth.mode` + `gateway.auth.password` | Any string (token wins if both set) |
|
guide.md
CHANGED
|
@@ -1,68 +1,25 @@
|
|
| 1 |
-
# OpenClaw HF Space
|
| 2 |
|
| 3 |
-
這份
|
| 4 |
|
| 5 |
-
##
|
| 6 |
|
| 7 |
-
|
| 8 |
-
- 主路徑是 Codex
|
| 9 |
-
- `gemini-3.1-pro-preview` 是備援切換方案
|
| 10 |
-
- 如果有設定 `SUPABASE_URL` 和 `SUPABASE_KEY`,會自動啟動背景同步,把 `.openclaw` 內的文字狀態檔同步到 Supabase
|
| 11 |
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
- 所以這裡的 fallback 不是自動 failover
|
| 16 |
-
- 如果 `gpt-codex` 出問題,你要手動把 `OPENCLAW_DEFAULT_MODEL` 改成 `google/gemini-3.1-pro-preview`
|
| 17 |
-
|
| 18 |
-
## 2. 最穩定的建議架構
|
| 19 |
-
|
| 20 |
-
- Hugging Face Space:跑 OpenClaw gateway
|
| 21 |
-
- HF Persistent Storage:保存 OAuth refresh token 與本地狀態
|
| 22 |
-
- Supabase:做外部備份,保存 config、session、memory、logs
|
| 23 |
-
- Uptime Robot:每 30 分鐘 ping 一次 Space,降低休眠機率
|
| 24 |
-
|
| 25 |
-
這樣即使 Space 重啟,主要狀態仍有兩層保護:
|
| 26 |
-
|
| 27 |
-
- 本地 persistent storage
|
| 28 |
-
- 外部 Supabase 備份
|
| 29 |
-
|
| 30 |
-
## 3. 部署前要準備的東西
|
| 31 |
-
|
| 32 |
-
你需要先準備:
|
| 33 |
-
|
| 34 |
-
- 一個 Hugging Face Space,SDK 選 `Docker`
|
| 35 |
-
- 一個 Supabase 專案
|
| 36 |
-
- 一組你要給 `gpt-codex` 使用的憑證或 OAuth 能力
|
| 37 |
-
- 一個 Google Gemini API key,作為 fallback
|
| 38 |
-
- 一個 Uptime Robot 帳號
|
| 39 |
-
|
| 40 |
-
## 4. Supabase 先建立資料表
|
| 41 |
-
|
| 42 |
-
到 Supabase SQL Editor 執行:
|
| 43 |
-
|
| 44 |
-
```sql
|
| 45 |
-
create table if not exists openclaw_state (
|
| 46 |
-
path text primary key,
|
| 47 |
-
kind text not null,
|
| 48 |
-
content text not null,
|
| 49 |
-
sha256 text not null,
|
| 50 |
-
size_bytes bigint not null,
|
| 51 |
-
updated_at timestamptz not null,
|
| 52 |
-
synced_at timestamptz not null
|
| 53 |
-
);
|
| 54 |
-
```
|
| 55 |
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
- `SUPABASE_URL`
|
| 59 |
-
- `SUPABASE_KEY`
|
| 60 |
|
| 61 |
-
|
|
|
|
|
|
|
|
|
|
| 62 |
|
| 63 |
-
##
|
| 64 |
|
| 65 |
-
|
| 66 |
|
| 67 |
- `Dockerfile`
|
| 68 |
- `README.md`
|
|
@@ -70,231 +27,139 @@ create table if not exists openclaw_state (
|
|
| 70 |
- `sync-external-storage.mjs`
|
| 71 |
- `guide.md`
|
| 72 |
|
| 73 |
-
##
|
| 74 |
|
| 75 |
### Secrets
|
| 76 |
|
| 77 |
-
|
| 78 |
|
| 79 |
```text
|
| 80 |
-
OPENCLAW_GATEWAY_TOKEN=<
|
| 81 |
-
|
| 82 |
-
|
|
|
|
| 83 |
```
|
| 84 |
|
| 85 |
-
|
| 86 |
|
| 87 |
```text
|
| 88 |
-
|
| 89 |
-
TELEGRAM_BOT_TOKEN=<如果要接 Telegram,只要這個就能先用>
|
| 90 |
-
HF_TOKEN=<只有你要用 Hugging Face provider 才需要>
|
| 91 |
-
OPENCODE_API_KEY=<只有你要用 OpenCode provider 才需要>
|
| 92 |
```
|
| 93 |
|
| 94 |
### Variables
|
| 95 |
|
| 96 |
-
|
| 97 |
|
| 98 |
```text
|
| 99 |
-
OPENCLAW_DEFAULT_MODEL=
|
|
|
|
|
|
|
| 100 |
OPENCLAW_SUPABASE_TABLE=openclaw_state
|
| 101 |
OPENCLAW_SYNC_INTERVAL_MS=300000
|
| 102 |
-
OPENCLAW_SYNC_MAX_FILE_BYTES=5242880
|
| 103 |
-
OPENCLAW_SYNC_INCLUDE_EXTENSIONS=.json,.jsonl,.md,.txt
|
| 104 |
-
OPENCLAW_CONTROL_UI_ALLOWED_ORIGINS=https://your-space-name.hf.space
|
| 105 |
```
|
| 106 |
|
| 107 |
-
|
| 108 |
|
| 109 |
-
|
| 110 |
|
| 111 |
-
```
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
```
|
| 118 |
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
這一步很重要,尤其是你把主路徑放在 `gpt-codex` 時。
|
| 122 |
-
|
| 123 |
-
到 HF Space 的 `Settings -> Storage`:
|
| 124 |
|
| 125 |
-
-
|
| 126 |
-
|
| 127 |
-
原因:
|
| 128 |
|
| 129 |
-
|
| 130 |
-
- OpenClaw 本地狀態會寫到 `/data/.openclaw`
|
| 131 |
-
- 沒有 persistent storage,Space 重建後 OAuth 很容易失效
|
| 132 |
|
| 133 |
-
|
|
|
|
| 134 |
|
| 135 |
-
##
|
| 136 |
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
如果你的 `gpt-codex` 依賴互動式 OAuth,第一次通常要在有 shell 的環境完成。
|
| 140 |
-
|
| 141 |
-
穩定做法:
|
| 142 |
-
|
| 143 |
-
1. 先讓 Space build 完成
|
| 144 |
-
2. 開啟 HF Space Dev Mode 或其他可進 shell 的方式
|
| 145 |
-
3. 在容器內完成 `gpt-codex` 對應的登入流程
|
| 146 |
-
4. 確認 OAuth 或 auth profile 憑證落在 persistent storage
|
| 147 |
-
5. 重新啟動 Space
|
| 148 |
-
|
| 149 |
-
原則上你要確保登入後產生的憑證不是只留在臨時層,而是能跟著 `/data` 保留。
|
| 150 |
-
|
| 151 |
-
如果你發現每次重啟都要重登,通常就是:
|
| 152 |
-
|
| 153 |
-
- 沒開 persistent storage
|
| 154 |
-
- 或 auth profile / OAuth 憑證沒有寫到持久化路徑
|
| 155 |
-
|
| 156 |
-
## 9. Gemini fallback 要怎麼設
|
| 157 |
-
|
| 158 |
-
你現在的策略應該是:
|
| 159 |
-
|
| 160 |
-
- 主模型:`gpt-codex`
|
| 161 |
-
- fallback:`google/gemini-3.1-pro-preview`
|
| 162 |
-
|
| 163 |
-
如果你暫時要切到 Gemini,只要改 primary model 即可。
|
| 164 |
-
|
| 165 |
-
Secrets:
|
| 166 |
-
|
| 167 |
-
```text
|
| 168 |
-
GEMINI_API_KEY=<your-google-ai-studio-key>
|
| 169 |
-
```
|
| 170 |
-
|
| 171 |
-
Variables:
|
| 172 |
|
| 173 |
```text
|
| 174 |
-
|
| 175 |
```
|
| 176 |
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
背景腳本會定期掃描 `.openclaw` 下面符合副檔名條件的文字檔,例如:
|
| 180 |
-
|
| 181 |
-
- `openclaw.json`
|
| 182 |
-
- sessions
|
| 183 |
-
- memory
|
| 184 |
-
- logs
|
| 185 |
-
|
| 186 |
-
然後把內容 upsert 到 Supabase 的 `openclaw_state`。
|
| 187 |
-
|
| 188 |
-
目前這個同步層的定位是:
|
| 189 |
-
|
| 190 |
-
- 外部備份
|
| 191 |
-
- 快速還原依據
|
| 192 |
-
- 避免 Space 重啟後資料完全消失
|
| 193 |
|
| 194 |
-
|
| 195 |
|
| 196 |
-
|
| 197 |
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
- Monitor Type: `HTTP(s)`
|
| 201 |
-
- URL: `https://your-space-name.hf.space`
|
| 202 |
-
- Monitoring Interval: `30 minutes`
|
| 203 |
-
|
| 204 |
-
作用:
|
| 205 |
-
|
| 206 |
-
- 定期送 GET
|
| 207 |
-
- 降低因為長時間無人訪問而進入 sleep 的機率
|
| 208 |
-
|
| 209 |
-
注意:
|
| 210 |
-
|
| 211 |
-
- HF 免費層仍可能受平台政策影響,不保證絕不休眠
|
| 212 |
-
- 真正要長時間穩定在線,還是建議付費硬體或其他常駐環境
|
| 213 |
-
|
| 214 |
-
## 12. 部署完成後怎麼驗證
|
| 215 |
-
|
| 216 |
-
先看 Space logs,確認幾件事:
|
| 217 |
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
3. `auth=token` 或符合你設定的 auth 模式
|
| 221 |
-
4. `supabase=1`
|
| 222 |
-
5. gateway 正常 listen 在 `0.0.0.0:7860`
|
| 223 |
|
| 224 |
-
|
| 225 |
|
| 226 |
-
|
| 227 |
-
2. 能用 `OPENCLAW_GATEWAY_TOKEN` 登入
|
| 228 |
-
3. Supabase table 有開始出現同步資料
|
| 229 |
|
| 230 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 231 |
|
| 232 |
-
|
| 233 |
|
| 234 |
-
|
|
|
|
|
|
|
| 235 |
|
| 236 |
-
|
| 237 |
-
- OAuth 或 auth profile 憑證是否真的寫到持久化路徑
|
| 238 |
-
- 是否在 rebuild 後把憑證留在 ephemeral layer
|
| 239 |
|
| 240 |
-
|
| 241 |
|
| 242 |
-
|
| 243 |
|
| 244 |
-
-
|
| 245 |
-
-
|
| 246 |
-
-
|
| 247 |
-
- key 是否有 insert / update 權限
|
| 248 |
|
| 249 |
-
|
| 250 |
|
| 251 |
-
|
|
|
|
| 252 |
|
| 253 |
-
|
| 254 |
-
- `OPENCLAW_CONTROL_UI_ALLOWED_ORIGINS` 是否有填對 Space URL
|
| 255 |
-
- `OPENCLAW_GATEWAY_TRUSTED_PROXIES` 是否需要手動補 IP
|
| 256 |
|
| 257 |
-
|
|
|
|
| 258 |
|
| 259 |
-
|
| 260 |
|
| 261 |
-
|
| 262 |
|
| 263 |
```text
|
| 264 |
-
|
|
|
|
|
|
|
|
|
|
| 265 |
```
|
| 266 |
|
| 267 |
-
|
| 268 |
|
| 269 |
```text
|
| 270 |
-
|
|
|
|
| 271 |
```
|
| 272 |
|
| 273 |
-
|
| 274 |
-
|
| 275 |
-
## 14. 我建議你實際操作順序
|
| 276 |
|
| 277 |
-
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
4. 先設定 Secrets 和 Variables
|
| 283 |
-
5. 開 persistent storage
|
| 284 |
-
6. 等第一次 build 完成
|
| 285 |
-
7. 進 Dev Mode 完成 `gpt-codex` 所需登入
|
| 286 |
-
8. 重啟 Space
|
| 287 |
-
9. 檢查 logs 和 Supabase
|
| 288 |
-
10. 最後再接 Uptime Robot
|
| 289 |
-
|
| 290 |
-
## 15. 最後建議
|
| 291 |
-
|
| 292 |
-
如果你的目標是「長期穩定運行」,優先順序應該是:
|
| 293 |
-
|
| 294 |
-
1. persistent storage
|
| 295 |
-
2. gateway token auth
|
| 296 |
-
3. Supabase 外部備份
|
| 297 |
-
4. Uptime Robot
|
| 298 |
-
5. `gpt-codex` 的 auth 持久化
|
| 299 |
-
|
| 300 |
-
也就是說,OAuth 不是最先要保證的,資料持久化和可恢復性才是。
|
|
|
|
| 1 |
+
# OpenClaw HF Space 設定指引
|
| 2 |
|
| 3 |
+
這份是目前專案的實際配置指引。
|
| 4 |
|
| 5 |
+
## 模型順序
|
| 6 |
|
| 7 |
+
目前預設模型鏈是:
|
|
|
|
|
|
|
|
|
|
| 8 |
|
| 9 |
+
1. `huggingface/Qwen/Qwen3-8B`
|
| 10 |
+
2. `huggingface/deepseek-ai/DeepSeek-R1`
|
| 11 |
+
3. `gpt-codex`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
|
| 13 |
+
注意:
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
+
- `Qwen` 是 primary
|
| 16 |
+
- `DeepSeek` 是第一個 fallback
|
| 17 |
+
- `gpt-codex` 是第二個 fallback
|
| 18 |
+
- `gpt-codex` 只有在它本身已經可用時,fallback 才會成功
|
| 19 |
|
| 20 |
+
## 你在 HF Space 要放的檔案
|
| 21 |
|
| 22 |
+
至少要有:
|
| 23 |
|
| 24 |
- `Dockerfile`
|
| 25 |
- `README.md`
|
|
|
|
| 27 |
- `sync-external-storage.mjs`
|
| 28 |
- `guide.md`
|
| 29 |
|
| 30 |
+
## HF Space Settings
|
| 31 |
|
| 32 |
### Secrets
|
| 33 |
|
| 34 |
+
請加入:
|
| 35 |
|
| 36 |
```text
|
| 37 |
+
OPENCLAW_GATEWAY_TOKEN=<你的 gateway token>
|
| 38 |
+
HF_TOKEN=<你的 Hugging Face token>
|
| 39 |
+
SUPABASE_URL=https://cpflxjkupogczhyodoov.supabase.co
|
| 40 |
+
SUPABASE_KEY=<你的 supabase service_role key>
|
| 41 |
```
|
| 42 |
|
| 43 |
+
如果你要 Telegram,再加:
|
| 44 |
|
| 45 |
```text
|
| 46 |
+
TELEGRAM_BOT_TOKEN=<你的 telegram bot token>
|
|
|
|
|
|
|
|
|
|
| 47 |
```
|
| 48 |
|
| 49 |
### Variables
|
| 50 |
|
| 51 |
+
請加入:
|
| 52 |
|
| 53 |
```text
|
| 54 |
+
OPENCLAW_DEFAULT_MODEL=huggingface/Qwen/Qwen3-8B
|
| 55 |
+
OPENCLAW_FALLBACK_MODELS=huggingface/deepseek-ai/DeepSeek-R1,gpt-codex
|
| 56 |
+
OPENCLAW_CONTROL_UI_ALLOWED_ORIGINS=https://你的-space-url.hf.space
|
| 57 |
OPENCLAW_SUPABASE_TABLE=openclaw_state
|
| 58 |
OPENCLAW_SYNC_INTERVAL_MS=300000
|
|
|
|
|
|
|
|
|
|
| 59 |
```
|
| 60 |
|
| 61 |
+
## Supabase
|
| 62 |
|
| 63 |
+
先在 Supabase SQL Editor 建這個 table:
|
| 64 |
|
| 65 |
+
```sql
|
| 66 |
+
create table if not exists openclaw_state (
|
| 67 |
+
path text primary key,
|
| 68 |
+
kind text not null,
|
| 69 |
+
content text not null,
|
| 70 |
+
sha256 text not null,
|
| 71 |
+
size_bytes bigint not null,
|
| 72 |
+
updated_at timestamptz not null,
|
| 73 |
+
synced_at timestamptz not null
|
| 74 |
+
);
|
| 75 |
```
|
| 76 |
|
| 77 |
+
`SUPABASE_KEY` 要用:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
|
| 79 |
+
- `service_role key`
|
|
|
|
|
|
|
| 80 |
|
| 81 |
+
不要用:
|
|
|
|
|
|
|
| 82 |
|
| 83 |
+
- `Publishable Key`
|
| 84 |
+
- `Anon Key`
|
| 85 |
|
| 86 |
+
## Telegram 最小可用設定
|
| 87 |
|
| 88 |
+
如果你只是要 bot 先能用,只要:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 89 |
|
| 90 |
```text
|
| 91 |
+
TELEGRAM_BOT_TOKEN=<你的 bot token>
|
| 92 |
```
|
| 93 |
|
| 94 |
+
其他 `OPENCLAW_TELEGRAM_*` 都不是必填。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
|
| 96 |
+
## Persistent Storage
|
| 97 |
|
| 98 |
+
建議開啟 HF Space 的 persistent storage。
|
| 99 |
|
| 100 |
+
原因:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
|
| 102 |
+
- OpenClaw 狀態會存在 `/data/.openclaw`
|
| 103 |
+
- 如果之後 `gpt-codex` 要用到持久化 auth,沒有 persistent storage 會不穩
|
|
|
|
|
|
|
|
|
|
| 104 |
|
| 105 |
+
## 部署後怎麼檢查
|
| 106 |
|
| 107 |
+
看 Space logs,至少確認:
|
|
|
|
|
|
|
| 108 |
|
| 109 |
+
1. `setup-hf-config.mjs` 有執行
|
| 110 |
+
2. 出現 `model=huggingface/Qwen/Qwen3-8B`
|
| 111 |
+
3. 出現 `fallbacks=2`
|
| 112 |
+
4. 出現 `supabase=1`
|
| 113 |
+
5. gateway listen 在 `0.0.0.0:7860`
|
| 114 |
|
| 115 |
+
再確認:
|
| 116 |
|
| 117 |
+
1. Control UI 能打開
|
| 118 |
+
2. 可以用 `OPENCLAW_GATEWAY_TOKEN` 登入
|
| 119 |
+
3. Supabase 的 `openclaw_state` 有同步資料
|
| 120 |
|
| 121 |
+
## 關於 `gpt-codex`
|
|
|
|
|
|
|
| 122 |
|
| 123 |
+
目前 `gpt-codex` 是 fallback,不是 primary。
|
| 124 |
|
| 125 |
+
這樣做的好處是:
|
| 126 |
|
| 127 |
+
- 主要流量先走 Qwen
|
| 128 |
+
- Qwen 不行再走 DeepSeek
|
| 129 |
+
- Codex 放最後
|
|
|
|
| 130 |
|
| 131 |
+
但要注意:
|
| 132 |
|
| 133 |
+
- 如果 `gpt-codex` 還沒完成它需要的登入或授權
|
| 134 |
+
- 真正切到第三個 fallback 時,仍然可能失敗
|
| 135 |
|
| 136 |
+
所以目前最穩的理解方式是:
|
|
|
|
|
|
|
| 137 |
|
| 138 |
+
- `Qwen + DeepSeek` 保證主流程
|
| 139 |
+
- `Codex` 先保留在 fallback 鏈
|
| 140 |
|
| 141 |
+
## 最後的最小清單
|
| 142 |
|
| 143 |
+
### 必填 Secrets
|
| 144 |
|
| 145 |
```text
|
| 146 |
+
OPENCLAW_GATEWAY_TOKEN
|
| 147 |
+
HF_TOKEN
|
| 148 |
+
SUPABASE_URL
|
| 149 |
+
SUPABASE_KEY
|
| 150 |
```
|
| 151 |
|
| 152 |
+
### 必填 Variables
|
| 153 |
|
| 154 |
```text
|
| 155 |
+
OPENCLAW_DEFAULT_MODEL=huggingface/Qwen/Qwen3-8B
|
| 156 |
+
OPENCLAW_FALLBACK_MODELS=huggingface/deepseek-ai/DeepSeek-R1,gpt-codex
|
| 157 |
```
|
| 158 |
|
| 159 |
+
### 建議 Variables
|
|
|
|
|
|
|
| 160 |
|
| 161 |
+
```text
|
| 162 |
+
OPENCLAW_CONTROL_UI_ALLOWED_ORIGINS=https://你的-space-url.hf.space
|
| 163 |
+
OPENCLAW_SUPABASE_TABLE=openclaw_state
|
| 164 |
+
OPENCLAW_SYNC_INTERVAL_MS=300000
|
| 165 |
+
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setup-hf-config.mjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
| 3 |
* One-time setup for OpenClaw on Hugging Face Spaces.
|
| 4 |
* Runs at container startup; writes or merges openclaw.json from env (Secrets/Variables):
|
| 5 |
* - agents.defaults.model.primary from OPENCLAW_DEFAULT_MODEL / OPENCLAW_HF_DEFAULT_MODEL.
|
|
|
|
| 6 |
* - gateway.auth: OPENCLAW_GATEWAY_TOKEN (token) or OPENCLAW_GATEWAY_PASSWORD (password); token wins if both set.
|
| 7 |
* - gateway.controlUi.dangerouslyDisableDeviceAuth when auth is set (no device pairing in Spaces).
|
| 8 |
* - gateway.trustedProxies from OPENCLAW_GATEWAY_TRUSTED_PROXIES, or default HF proxy IPs so the UI works without extra config.
|
|
@@ -48,7 +49,11 @@ function parseBoolean(raw) {
|
|
| 48 |
const defaultModel =
|
| 49 |
process.env.OPENCLAW_DEFAULT_MODEL?.trim() ||
|
| 50 |
process.env.OPENCLAW_HF_DEFAULT_MODEL?.trim() ||
|
| 51 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
const gatewayToken = readGatewayToken();
|
| 53 |
const gatewayPassword = process.env.OPENCLAW_GATEWAY_PASSWORD?.trim();
|
| 54 |
const telegramBotToken = process.env.TELEGRAM_BOT_TOKEN?.trim();
|
|
@@ -94,6 +99,7 @@ if (!config.agents) config.agents = {};
|
|
| 94 |
if (!config.agents.defaults) config.agents.defaults = {};
|
| 95 |
if (!config.agents.defaults.model) config.agents.defaults.model = {};
|
| 96 |
config.agents.defaults.model.primary = defaultModel;
|
|
|
|
| 97 |
|
| 98 |
// Auth: token wins if both set; otherwise password
|
| 99 |
const useTokenAuth = Boolean(gatewayToken);
|
|
@@ -163,6 +169,7 @@ fs.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
| 163 |
const authKind = useTokenAuth ? "token" : usePasswordAuth ? "password" : "none";
|
| 164 |
const parts = [
|
| 165 |
`model=${defaultModel}`,
|
|
|
|
| 166 |
`token_present=${useTokenAuth ? "1" : "0"}`,
|
| 167 |
`password_present=${usePasswordAuth ? "1" : "0"}`,
|
| 168 |
`auth=${authKind}`,
|
|
|
|
| 3 |
* One-time setup for OpenClaw on Hugging Face Spaces.
|
| 4 |
* Runs at container startup; writes or merges openclaw.json from env (Secrets/Variables):
|
| 5 |
* - agents.defaults.model.primary from OPENCLAW_DEFAULT_MODEL / OPENCLAW_HF_DEFAULT_MODEL.
|
| 6 |
+
* - agents.defaults.model.fallbacks from OPENCLAW_FALLBACK_MODELS.
|
| 7 |
* - gateway.auth: OPENCLAW_GATEWAY_TOKEN (token) or OPENCLAW_GATEWAY_PASSWORD (password); token wins if both set.
|
| 8 |
* - gateway.controlUi.dangerouslyDisableDeviceAuth when auth is set (no device pairing in Spaces).
|
| 9 |
* - gateway.trustedProxies from OPENCLAW_GATEWAY_TRUSTED_PROXIES, or default HF proxy IPs so the UI works without extra config.
|
|
|
|
| 49 |
const defaultModel =
|
| 50 |
process.env.OPENCLAW_DEFAULT_MODEL?.trim() ||
|
| 51 |
process.env.OPENCLAW_HF_DEFAULT_MODEL?.trim() ||
|
| 52 |
+
"huggingface/Qwen/Qwen3-8B";
|
| 53 |
+
const fallbackModels = parseCsv(
|
| 54 |
+
process.env.OPENCLAW_FALLBACK_MODELS?.trim() ||
|
| 55 |
+
"huggingface/deepseek-ai/DeepSeek-R1,gpt-codex",
|
| 56 |
+
);
|
| 57 |
const gatewayToken = readGatewayToken();
|
| 58 |
const gatewayPassword = process.env.OPENCLAW_GATEWAY_PASSWORD?.trim();
|
| 59 |
const telegramBotToken = process.env.TELEGRAM_BOT_TOKEN?.trim();
|
|
|
|
| 99 |
if (!config.agents.defaults) config.agents.defaults = {};
|
| 100 |
if (!config.agents.defaults.model) config.agents.defaults.model = {};
|
| 101 |
config.agents.defaults.model.primary = defaultModel;
|
| 102 |
+
config.agents.defaults.model.fallbacks = fallbackModels;
|
| 103 |
|
| 104 |
// Auth: token wins if both set; otherwise password
|
| 105 |
const useTokenAuth = Boolean(gatewayToken);
|
|
|
|
| 169 |
const authKind = useTokenAuth ? "token" : usePasswordAuth ? "password" : "none";
|
| 170 |
const parts = [
|
| 171 |
`model=${defaultModel}`,
|
| 172 |
+
`fallbacks=${fallbackModels.length}`,
|
| 173 |
`token_present=${useTokenAuth ? "1" : "0"}`,
|
| 174 |
`password_present=${usePasswordAuth ? "1" : "0"}`,
|
| 175 |
`auth=${authKind}`,
|