Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions microtensor_subnet/cli/epoch.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import logging
import os
import random
import sys
import time
from pathlib import Path
from typing import Any
Expand Down Expand Up @@ -229,10 +230,26 @@ def _relay_token(args: argparse.Namespace) -> int:
return 0


def _show_logs() -> None:
package = logging.getLogger("microtensor_subnet")
if not any(getattr(h, "_mt_visible", False) for h in package.handlers):
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(name)s %(message)s"))
handler._mt_visible = True # type: ignore[attr-defined]
package.addHandler(handler)
package.setLevel(logging.INFO)
package.propagate = False
package.disabled = False
for name, found in list(logging.Logger.manager.loggerDict.items()):
if isinstance(found, logging.Logger) and name.startswith("microtensor_subnet"):
found.disabled = False


def _run(args: argparse.Namespace) -> int:
config = chain_config(args)
wallet = open_wallet(config)
client = open_client(config, wallet)
_show_logs()
server = ServerClient(args.server, hotkey_address(wallet), wallet)
try:
block = client.block()
Expand Down Expand Up @@ -558,6 +575,7 @@ def _loop(args: argparse.Namespace) -> int:
config = chain_config(args)
wallet = open_wallet(config)
client = open_client(config, wallet)
_show_logs()
server = ServerClient(args.server, hotkey_address(wallet), wallet)
state = Path(args.home) / "state"
state.mkdir(parents=True, exist_ok=True)
Expand Down
2 changes: 1 addition & 1 deletion microtensor_subnet/validator/epoch.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def load_context(
files = items.open_bundle(manifest, bundle, hotkey, private)
work_dir = config.work_dir / str(epoch_index)
epoch_items, trees = items.unpack(files, seed=seed, work_dir=work_dir, limit=config.item_limit)
ref = items.reference_components(trees, definition, config.cache_dir)
ref = items.reference_components(trees, definition, config.cache_dir, config.chain.network)
snapshot = client.ledger_snapshot(config.arena_id, epoch_index)
roster_doc = client.roster(config.arena_id, epoch_index)
charged = dict(dict(dict(roster_doc or {}).get("body") or {}).get("fee") or {})
Expand Down
41 changes: 40 additions & 1 deletion microtensor_subnet/validator/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import hashlib
import json
import logging
import shutil
import subprocess
from pathlib import Path
from typing import Any

Expand Down Expand Up @@ -133,8 +135,43 @@ def unpack(
), trees


TESTNET = "test"
TEMPLATE_REPO = "https://github.com/microtensor-io/microtensor-miner-template"
TEMPLATE_FILES = ("main.py", "config.json", "requirements.txt")
TEMPLATE_DIRS = ("harness", "escalation")


def template_harness(task: str, cache_dir: Path) -> Path:
clone = cache_dir / "reference-template"
if not (clone / "main.py").is_file():
shutil.rmtree(clone, ignore_errors=True)
try:
subprocess.run( # noqa: S603
["git", "clone", "--quiet", "--depth", "1", TEMPLATE_REPO, str(clone)], # noqa: S607
check=True,
capture_output=True,
timeout=300,
)
except (OSError, subprocess.SubprocessError) as exc:
reason = f"the reference harness could not be built from the template: {exc}"
raise ReleaseError(reason) from exc
into = cache_dir / f"reference-harness-{task or 'generic'}"
shutil.rmtree(into, ignore_errors=True)
into.mkdir(parents=True)
for name in TEMPLATE_FILES:
shutil.copy2(clone / name, into / name)
for name in TEMPLATE_DIRS:
shutil.copytree(clone / name, into / name, ignore=shutil.ignore_patterns("__pycache__"))
if task and (into / "harness" / "prompts" / task).is_dir():
config = json.loads((into / "config.json").read_text(encoding="utf-8"))
config["adapter"] = task
(into / "config.json").write_text(json.dumps(config, indent=2) + chr(10), encoding="utf-8")
log.warning("testnet: the bundle has no reference harness; built one from the miner template")
return into


def reference_components(
trees: dict[str, Path], definition: dict[str, Any], cache_dir: Path
trees: dict[str, Path], definition: dict[str, Any], cache_dir: Path, network: str = ""
) -> Reference:
references = dict(definition.get("references") or {})
slm_repo = str(references.get("slm", ""))
Expand All @@ -147,6 +184,8 @@ def reference_components(
except ParameterError as exc:
raise ReleaseError(f"the reference slm has no readable weights: {exc}") from exc
harness = trees.get("harness")
if harness is None and network == TESTNET:
harness = template_harness(str(definition.get("task") or ""), cache_dir)
if harness is None:
raise ReleaseError("the bundle carries no reference harness")
variants = tuple(path for name, path in sorted(trees.items()) if name.startswith("variant-"))
Expand Down
Loading