File size: 5,217 Bytes
eee14a2 8f6b7b7 cd0a5b6 eee14a2 8f6b7b7 cd0a5b6 eee14a2 8f6b7b7 cd0a5b6 eee14a2 8f6b7b7 eee14a2 cd0a5b6 eee14a2 cd0a5b6 eee14a2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | """OpenCode configuration for remote, keyless Minecraft supervision."""
from __future__ import annotations
import json
import os
from pathlib import Path
from typing import Any
OPENCODE_VERSION = "1.18.34"
MINE_BASE = "https://erinaldordso-mine.hf.space/v1"
MAIN_MODEL = "qwen3-coder-30b-a3b-instruct"
AUX_MODEL = "granite-4.0-h-tiny"
# Coach-only model: high-level supervision runs SOLELY on the free OpenCode
# Muse model. No Mine provider is configured here; other bots/Spaces that use
# the Mine Space keep their own wiring and are unaffected.
MUSE_MODEL_ID = "muse-spark-1.3-contributor-free"
MUSE_MODEL = "opencode/" + MUSE_MODEL_ID
COACH_PROMPT = """You supervise the upstream AltoClef Minecraft survival speedrun bot.
AltoClef performs real movement, gear progression, stronghold search, portal
activation and dragon combat on difficulty Normal. You are a text decider, not
a file/shell executor: use no tools, run no commands, edit nothing. Observe
only the supplied telemetry and reply ONLY with one compact JSON object:
{"action":"continue","reason":"brief factual explanation"}.
Allowed actions: start, continue, resume. Start/resume runs AltoClef @gamer only
when its task is inactive. Prefer continue while a task is active. Never invent
world observations or success. Naldo plays Survival with a retained pre-existing
inventory (assisted run). Credits observed after entering the End are required
to claim completion. Keep reason under 25 words.
"""
def configuration() -> dict[str, Any]:
# Supported Zen free-tier shape (probed 2026-10-03, opencode 1.18.33,
# keyless isolated HOME, empty stdin): NO custom agent at all. Upstream
# request.ts uses `agent.prompt OR SystemPrompt.provider(model)`, and Zen
# rejects the tested override shapes with
# `FreeTierError: ... can only be used from within OpenCode` (403):
# prompt override, tools lockdown, blanket permission deny, and even a
# read-only permission shape (*-deny + read/glob/grep-allow +
# external_directory-deny) each reproduce it. Bare description+mode and the
# built-ins (build, plan) succeed. The built-in `plan` agent is used:
# official Muse system prompt intact, read-only by design
# ("Plan mode. Disallows all edit tools"). All coach instructions live at
# user level (COACH_PROMPT + telemetry in the run message). There is
# intentionally no Mine provider either, so nothing falls back to Mine.
return {
"$schema": "https://opencode.ai/config.json",
"enabled_providers": ["opencode"],
"model": MUSE_MODEL,
"small_model": MUSE_MODEL,
"share": "disabled",
"autoupdate": False,
"default_agent": "plan",
}
def coach_user_message(telemetry: dict[str, Any]) -> str:
"""Build the user-level run message: instructions + real telemetry."""
compact = {key: telemetry.get(key) for key in [
"connected", "dimension", "position", "creative", "task_active",
"tasks", "entered_end", "credits_observed", "error"]}
return COACH_PROMPT + "\nReal telemetry: " + json.dumps(compact)
def child_environment(root: Path) -> dict[str, str]:
# Independent configuration/data prevents inheriting other CLI credentials
# or reading the Xbox relay directory. Models are reached without a key.
env = dict(os.environ)
for name in list(env):
if name.endswith("API_KEY") or name.startswith("GEMINI_BOT_KEY_") or name in {
"HF_TOKEN", "HUGGING_FACE_HUB_TOKEN", "VOYAGER_API_KEY", "GITHUB_TOKEN", "GH_TOKEN"
}:
env.pop(name, None)
env.update({
"XDG_CONFIG_HOME": str(root / "config"),
"XDG_DATA_HOME": str(root / "data"),
"XDG_CACHE_HOME": str(root / "cache"),
"OPENCODE_CONFIG": str(root / "opencode.json"),
"OPENCODE_DISABLE_AUTOUPDATE": "true",
"OPENCODE_DISABLE_DEFAULT_PLUGINS": "true",
"OPENCODE_DISABLE_SHARE": "true",
})
return env
def parse_decision(output: str) -> dict[str, str]:
texts: list[str] = []
for line in output.splitlines():
try:
event = json.loads(line)
except (ValueError, TypeError):
continue
if event.get("type") == "error":
raise RuntimeError(str(event.get("error") or event)[:300])
part = event.get("part") or {}
if event.get("type") == "text" and part.get("text"):
texts.append(part["text"])
raw = "\n".join(texts).strip()
if raw.startswith("```"):
raw = "\n".join(raw.splitlines()[1:-1]).strip()
try:
decision = json.loads(raw)
except ValueError as exc:
raise RuntimeError("OpenCode did not return a valid decision: " + raw[:200]) from exc
if not isinstance(decision, dict) or decision.get("action") not in {"start", "continue", "resume"}:
raise RuntimeError("Unsupported OpenCode decision")
return {"action": decision["action"], "reason": str(decision.get("reason") or "")[:240]}
def goal_completed(observation: dict[str, Any]) -> bool:
# A disappearing/unloaded dragon or an inactive task never means victory.
return bool(observation.get("entered_end") and observation.get("credits_observed"))
|