agentleFS
0gfoundation0gfoundation/0g-agent-skills/skills/private-computer/0g-pc-switch-model/SKILL.md

0g-pc-switch-model

Skill15 starsChanged 57 days agoMITView on GitHub

- Category: private-computer - SDK: Not applicable. This skill configures Claude Code to reach the 0G router; it uses no 0G SDK, no wallet and no .env. - Activation Triggers: "换模型", "换个模型", "切到 glm-5.3", "换成别的 0G 模型", "switch 0G model", "change the 0G model" - Supported Host: Claude Code only. It configures a project's .claude/ directory, which Cursor and GitHub Copilot do not read. - Source: skills/0g-pc-switch-model/SKILL.md in the 0gfoundation/0g-pc-skills repository, where it is tested and released. Changes are made…

  • Pipes a download into a shell
  • Reads credentials

The file

We split this skill into the rules it gives an agent

8 rules. About 0 are common, 5 are distinctive, and 3 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈5

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  • could be automatic: a setting could enforce it
  1. Very specific:

    SDK: Not applicable. This skill configures Claude Code to reach the 0G router.

    line 18
  2. Distinctive:

    Use AskUserQuestion and let it block.

    line 50
  3. Very specific:

    Never offer a model that is not in this output.

    line 113
  4. Distinctive:

    Read the three TEE tiers out loud and do not merge them.

    line 118
  5. Distinctive:

    Put the models from step 1 to the user with AskUserQuestion, carrying the context length, the TEE tier and the image column into what they …

    line 135
  6. Distinctive:

    Write nothing until the answer comes back: Not the config, not a draft, not "I'll assume glm-5.3 for now".

    line 138
  7. Very specific:

    If the user names a model the router serves in openai format only — kimi-k3 and glm-5.2 are the ones people ask for — say plainly that a …

    line 143
  8. Distinctive:

    Put the id the user chose on the command line.

    line 151

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Switch the 0G model for this project

Metadata

  • Category: private-computer
  • SDK: Not applicable. This skill configures Claude Code to reach the 0G router; it uses no 0G SDK, no wallet and no .env.
  • Activation Triggers: "换模型", "换个模型", "切到 glm-5.3", "换成别的 0G 模型", "switch 0G model", "change the 0G model"
  • Supported Host: Claude Code only. It configures a project's .claude/ directory, which Cursor and GitHub Copilot do not read.
  • Source: skills/0g-pc-switch-model/SKILL.md in the 0gfoundation/0g-pc-skills repository, where it is tested and released. Changes are made there first.

This skill does one thing: change which model <project>/.claude/settings.local.json points at.

It does not install, and it does not uninstall. If the user wants either, say so and stop — /0g-pc-setup (skills/private-computer/0g-pc-setup/SKILL.md here) and /0g-pc-uninstall (skills/private-computer/0g-pc-uninstall/SKILL.md here) are the ones, and doing their job from here produces a half-configured project that looks finished.

Hard rules

  1. Never write ~/.claude/settings.json. The user's global file holds their hooks, plugins, status line and /model choice. Read it if you need to; write only <project>/.claude/settings.local.json.
  2. Do not touch the permission gate. modelOverrides["claude-sonnet-5"] must stay on 0gm-1.0-35b-a3b. In auto mode the safety classifier resolves through the Sonnet tier, not Haiku; point it at a reasoning model and every Bash, git and network call times out with "temporarily unavailable" while chat keeps working — which reads as "model fine, tools broken" and sends people looking in the wrong place. ANTHROPIC_DEFAULT_HAIKU_MODEL and fallbackModel are likewise left alone; both are deliberately pinned to the fast model.
  3. Nothing takes effect until the next launch. Finish by telling the user to restart. Never say the running session is now on the new model — it is not, and /model cannot get it there.
  4. Every place the user has to decide is a tool call, not a sentence. This file is loaded into whatever model is driving the session, which in a project on 0G is a 0G model rather than Claude. A written instruction like "let the user choose" is read as narration and walked straight past. Use AskUserQuestion and let it block. That tool is Claude Code's; in a host without an equivalent blocking prompt, stop and hand the choice back to the user rather than deciding for them. This is the defect that made the skill this one was split out of non-interactive.

0 — The one precondition

Run this from the host project root — the directory you want on 0G. These paths resolve against the working directory, so running it inside .0g-skills/ or any other checkout of this repository would configure the wrong project.

python3 - <<'PY'
import json, pathlib

# "在不在 0G 上"看的是**生效配置里的接入点**,不是某个文件在不在。
# 文件可能因为别的原因存在(团队自己的 settings.json),也可能因为新布局而不存在;
# 两种情况下"文件在不在"都答错。Claude Code 后加载 local,所以 local 压过 project。
ROUTER_URL = "https://router-api.0g.ai"

def load(p):
    try:
        d = json.loads(pathlib.Path(p).read_text())
        return d if isinstance(d, dict) else {}
    except Exception:
        return {}

proj = load(".claude/settings.json")
local = load(".claude/settings.local.json")
env = {**(proj.get("env") or {}), **(local.get("env") or {})}

if env.get("ANTHROPIC_BASE_URL") != ROUTER_URL:
    print("absent")
elif (local.get("env") or {}).get("ANTHROPIC_BASE_URL") == ROUTER_URL:
    print("present")
else:
    print("present-old-layout")
PY

absent means this project is not on 0G at all, so there is no model to switch. Say that, point at /0g-pc-setup (skills/private-computer/0g-pc-setup/SKILL.md here), and stop. Do not install anything from here.

This is a precondition, not a mode decision: the skill's job never changes based on what it finds on disk. It either does that job or refuses to start.

1 — Ask the router what it serves

curl -s https://router-api.0g.ai/v1/models | python3 -c "
import json,sys
rows=[m for m in json.load(sys.stdin)['data']
      if 'anthropic' in (m.get('supported_formats') or [])
      and m.get('type') == 'chatbot' and m.get('context_length')]
if not rows: sys.exit('router returned no anthropic-format chat model - stop and report')
for m in sorted(rows, key=lambda x:-(x.get('context_length') or 0)):
    v=m.get('verifiability') if m.get('tee_attested') else None
    tee={'TeeML':'TEE, model in enclave','TeeTLS':'TEE, proxied upstream'}.get(v,'NO TEE')
    a=m.get('architecture') or {}
    img='text+image' if 'image' in (a.get('input_modalities') or []) else 'text only'
    print(f\"{m['id']:22} ctx={m.get('context_length'):>8}  {tee:22} {img}\")"

Never offer a model that is not in this output. A model the router serves in openai format only cannot be reached by this config at all — it is a direct connection, with nothing in between to translate. If the endpoint is unreachable, stop and report; do not fall back to a list written down somewhere, which is how a model that was retired last month ends up recommended today.

Read the three TEE tiers out loud and do not merge them. They are different promises:

ColumnWhat it means
TEE, model in enclaveThe model runs inside the enclave and signs its responses. The strongest guarantee on offer.
TEE, proxied upstreamThe enclave terminates TLS and forwards to an upstream provider. The connection is attested; the model's own execution is not.
NO TEEOrdinary hosted inference.

Someone may be choosing a model precisely because of that column. Flattening it to "TEE ✓" tells them something false about where their prompt gets processed.

Mention the text only / text+image column too. A text-only main model cannot take an image at all — fallbackModel does not rescue that, because it fires on the router being overloaded, not on the request being the wrong shape.

2 — Let the user pick, and wait

Put the models from step 1 to the user with AskUserQuestion, carrying the context length, the TEE tier and the image column into what they see. Then stop.

Write nothing until the answer comes back. Not the config, not a draft, not "I'll assume glm-5.3 for now". When installed as a slash command, an argument may carry the answer: if one was passed (/0g-pc-switch-model glm-5.3 (skills/private-computer/0g-pc-switch-model/SKILL.md here)), that is the answer and this step is already done — go to step 3 without asking.

If the user names a model the router serves in openai format only — kimi-k3 and glm-5.2 are the ones people ask for — say plainly that a direct config cannot reach it, point at the reference, and stop there. Do not start building a local translation layer inside this conversation. That path exists and is documented; it is not this skill.

3 — Rewrite the four fields together

Put the id the user chose on the command line. It has no default: this file is loaded into whatever model is driving the session, and a placeholder that happens to be a working model name is a placeholder that gets left in place. With nothing to fall back on, forgetting it is a hard stop instead of a confident report about a model nobody picked.

Run this from the host project root — the directory you want on 0G. These paths resolve against the working directory, so running it inside .0g-skills/ or any other checkout of this repository would configure the wrong project.

MODEL=          # ← the id from step 1, e.g. MODEL=glm-5.3
python3 - "$MODEL" <<'PY'
import json, pathlib, sys, urllib.request

TARGET = (sys.argv[1] if len(sys.argv) > 1 else "").strip()
if not TARGET:
    sys.exit("no model given - put the id the user chose in MODEL= and run it again. "
             "Nothing has been changed.")

with urllib.request.urlopen("https://router-api.0g.ai/v1/models", timeout=15) as r:
    live = {m["id"]: m for m in json.load(r)["data"]}
m = live.get(TARGET)
if m is None:
    sys.exit(f"{TARGET} is not on the router right now - check the list again")
if "anthropic" not in (m.get("supported_formats") or []):
    sys.exit(f"{TARGET} speaks {'+'.join(m.get('supported_formats') or ['no'])} only; "
             "a direct config cannot reach it. Pick one from the step 1 list.")

p = pathlib.Path(".claude/settings.local.json")
cfg = json.loads(p.read_text())          # fails loudly rather than clobbering
env = cfg["env"]
for k in ("ANTHROPIC_MODEL", "ANTHROPIC_DEFAULT_FABLE_MODEL", "ANTHROPIC_DEFAULT_OPUS_MODEL"):
    env[k] = TARGET
ceiling = m["context_length"] * 15 // 16
env["CLAUDE_CODE_MAX_CONTEXT_TOKENS"] = str(ceiling)

text = json.dumps(cfg, indent=2) + "\n"
json.loads(text)                          # validate before touching disk
p.write_text(text)
print(f"{TARGET}  context {m['context_length']}  ceiling {ceiling}")
PY

Four fields, one write. Three of them name the model; the fourth is the context ceiling, and it has to move with it. Leave it at a larger model's value and nothing fails until the session grows long — an error hours later, with nothing visibly connecting it to this switch.

The model name and the ceiling both come from the router in the same call that validates the choice. Neither is typed into this file: a model name written down here would outlive its presence on the router and turn every switch into a confident report about a model that is gone.

4 — Confirm, then hand off

curl -fsSL https://raw.githubusercontent.com/0gfoundation/0g-pc-skills/main/check-0g.sh | sh

Silence is the pass. It reads the effective model, the permission gate and the context ceiling, and says nothing when all three agree.

Then tell the user to restart Claude Code, and to run /status afterwards to see the Model line. The running session keeps the old model: /model switches tiers inside a session, but it cannot reach a 0G model name — the client rejects the name before any request leaves the machine — so a restart is the only way through.

When it goes wrong

SymptomCause → fix
Auto mode: "… is temporarily unavailable, cannot determine the safety of …"Read the model named in the message. If it is 0gm-1.0-35b-a3b, the gate was changed — put modelOverrides["claude-sonnet-5"] back (hard rule 2). If it is the model just switched to, the Sonnet tier resolved to nothing and the classifier fell back to the main model.
That message names a model ending in [1m]Not the cause. Measured on 2.1.273 on both the settings-file and the in-session path: the tag does not reach the derived classifier. Diagnose the gate itself.
The user picked Sonnet in /model and got a different modelExpected. That entry advertises Anthropic's Sonnet 5 and its price, and resolves to modelOverrides["claude-sonnet-5"] — 0gm-1.0-35b-a3b on the shipped config. ANTHROPIC_DEFAULT_* values rename their menu entries; modelOverrides does not.
A /model switch is gone after restartExpected. ANTHROPIC_MODEL is always set by the shipped config, and a new session uses it. Change the config, not /model, for a lasting switch.
Long sessions fail hours after a switchThe ceiling did not move with the model. Re-run step 3 rather than editing the number by hand.
The switch appears to do nothingThe old session is still running, or claude was launched from a different directory — project config is scoped to the folder holding .claude/. If step 0 said present-old-layout, the 0G config is in settings.json and this skill does not write there: those fields have to be moved into settings.local.json first.
402 from the routerThe key is valid and the account is empty. Nothing in the config needs changing — top up at https://pc.0g.ai/dashboard/overview

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.