Skip to content
Open
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
7 changes: 7 additions & 0 deletions engines/mock_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ def has_fail_directive(spec: str) -> bool:
return any(line.strip() == "MOCK_FAIL" for line in spec.splitlines())


def has_engine_down_directive(spec: str) -> bool:
return any(line.strip() == "MOCK_ENGINE_DOWN" for line in spec.splitlines())


def parse_blocks(spec: str) -> list[tuple[str, str]]:
lines = spec.splitlines()
blocks: list[tuple[str, str]] = []
Expand Down Expand Up @@ -73,6 +77,9 @@ def main(argv: list[str]) -> int:
return 2

spec = argv[-1]
if has_engine_down_directive(spec):
print("mock-worker: 402 Payment Required: usage balance exhausted", file=sys.stderr)
return 1
if has_fail_directive(spec):
print("mock-worker: simulated failure")
return 1
Expand Down
30 changes: 28 additions & 2 deletions engines/opencode-sandboxed.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
# flag (required for headless runs) disables ALL of its interactive approval
# prompts. This wrapper supplies the real containment: full network and reads,
# writes confined to the task dir, a per-run scratch/cache dir, and OpenCode's
# own state dirs.
# own state dirs. The scratch root also carries a private per-run XDG_DATA_HOME,
# which is what keeps concurrent workers off one shared session database (see the
# comment on that export below — it is a correctness fix for parallel runs).
#
# Usage (as a ringer engine bin):
# opencode-sandboxed.sh <taskdir> [--no-sandbox] <opencode args...>
Expand All @@ -28,6 +30,9 @@ if ! OPENCODE_BIN="$(command -v opencode)" || [ -z "$OPENCODE_BIN" ]; then
fi

if [ "$SANDBOX" = "0" ]; then
# Full-access mode keeps OpenCode's real ~/.local/share/opencode, so it also
# keeps the shared-session-DB contention documented below. Fine for a lone
# full-access task; do not fan out several at once.
exec "$OPENCODE_BIN" "$@" < /dev/null
fi

Expand Down Expand Up @@ -59,7 +64,8 @@ cat > "$PROFILE" <<'SBEOF'
(subpath (param "SCRATCH"))
(subpath (param "OC_SHARE"))
(subpath (param "OC_STATE"))
(subpath (param "OC_CONFIG")))
(subpath (param "OC_CONFIG"))
(subpath (param "OC_BASE")))
; /dev is needed for /dev/null, /dev/urandom, etc.; writes there can't create
; persistent files without root, so a few literals are allowed rather than via param.
(allow file-write-data
Expand All @@ -72,6 +78,25 @@ export TMPDIR="$SCRATCH"
export XDG_CACHE_HOME="$SCRATCH/cache"
mkdir -p "$XDG_CACHE_HOME"

# Per-run DATA root — this is a concurrency fix, not just containment. OpenCode
# keeps its session store at $XDG_DATA_HOME/opencode/opencode.db, defaulting to
# ~/.local/share/opencode: one file, shared by every worker, opened for write,
# growing without bound. On 2026-07-27 it stood at 1.78 GB and two of three
# workers launched simultaneously died before their first tool call with
# "Error: Unexpected error / database is locked" — recorded as model failures
# though no model had run. Since every non-Codex model routes through this
# engine, shared-DB contention penalises exactly the cheap tier, and worsens as
# parallelism rises. A private store per worker removes the contention entirely.
# Credentials live beside the DB, so seed the fresh root with auth.json — copy,
# never symlink: the profile denies writes outside SCRATCH, and a symlink would
# resolve straight back to the shared file this exists to avoid.
export XDG_DATA_HOME="$SCRATCH/share"
mkdir -p "$XDG_DATA_HOME/opencode"
if [ -f "$HOME/.local/share/opencode/auth.json" ]; then
cp "$HOME/.local/share/opencode/auth.json" "$XDG_DATA_HOME/opencode/auth.json"
chmod 600 "$XDG_DATA_HOME/opencode/auth.json"
fi

# Run as a child (not exec) so the EXIT trap fires and cleans up the profile +
# scratch dir even on the success path; propagate the child's exit status.
set +e
Expand All @@ -81,6 +106,7 @@ set +e
-D "OC_SHARE=$HOME/.local/share/opencode" \
-D "OC_STATE=$HOME/.local/state/opencode" \
-D "OC_CONFIG=$HOME/.config/opencode" \
-D "OC_BASE=$HOME/.opencode" \
-f "$PROFILE" "$OPENCODE_BIN" "$@" < /dev/null
status=$?
set -e
Expand Down
126 changes: 126 additions & 0 deletions registry/model-identity.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,16 @@ confidence = "verified" # Cursor (Anysphere) model, served through xAI's Gro
source = "https://cursor.com/blog/composer-2-5"
last_verified = 2026-07-10

[engines.grok.models."grok-4.5"]
# Task-manifest "model" field for grok-engine tasks logs "grok-4.5" directly
# (not the "grok-build" default_model_key above) — this is the actual slug
# ringer observes on grok-engine attempts. Same artifact as grok-build.
display = "Grok 4.5"
lab = "xAI"
confidence = "verified"
source = "https://docs.x.ai/developers/release-notes"
last_verified = 2026-08-01

[engines.opencode]
harness = "OpenCode"
access = "OpenRouter API"
Expand Down Expand Up @@ -98,3 +108,119 @@ lab = "Meta"
confidence = "verified"
source = "manifest model field; OpenRouter slug meta-llama/llama-3.3-70b-instruct:free"
last_verified = 2026-07-10

[engines.opencode.models."openrouter/anthropic/claude-sonnet-5"]
display = "Claude Sonnet 5"
lab = "Anthropic"
confidence = "verified"
source = "manifest model field; OpenRouter slug anthropic/claude-sonnet-5"
last_verified = 2026-08-01

[engines.opencode.models."openrouter/cohere/north-mini-code:free"]
display = "North Mini Code (free)"
lab = "Cohere"
confidence = "verified"
source = "manifest model field; OpenRouter slug cohere/north-mini-code:free"
last_verified = 2026-08-01

[engines.opencode.models."openrouter/deepseek/deepseek-v4-flash"]
display = "DeepSeek V4 Flash"
lab = "DeepSeek"
confidence = "verified"
source = "manifest model field; OpenRouter slug deepseek/deepseek-v4-flash"
last_verified = 2026-08-01

[engines.opencode.models."openrouter/deepseek/deepseek-v4-pro"]
display = "DeepSeek V4 Pro"
lab = "DeepSeek"
confidence = "verified"
source = "manifest model field; OpenRouter slug deepseek/deepseek-v4-pro"
last_verified = 2026-08-01

[engines.opencode.models."openrouter/inclusionai/ling-2.6-flash"]
# InclusionAI is Ant Group's AGI/open-source publishing org (home of the Ant
# Ling team) — see https://huggingface.co/inclusionAI.
display = "Ling 2.6 Flash"
lab = "InclusionAI (Ant Group)"
confidence = "verified"
source = "https://huggingface.co/inclusionAI"
last_verified = 2026-08-01

[engines.opencode.models."openrouter/inclusionai/ling-3.0-flash:free"]
display = "Ling 3.0 Flash (free)"
lab = "InclusionAI (Ant Group)"
confidence = "verified"
source = "https://huggingface.co/inclusionAI"
last_verified = 2026-08-01

[engines.opencode.models."openrouter/moonshotai/kimi-k2.5"]
display = "Kimi K2.5"
lab = "Moonshot AI"
confidence = "verified"
source = "manifest model field; OpenRouter slug moonshotai/kimi-k2.5"
last_verified = 2026-08-01

[engines.opencode.models."openrouter/moonshotai/kimi-k2.6"]
display = "Kimi K2.6"
lab = "Moonshot AI"
confidence = "verified"
source = "https://openrouter.ai/moonshotai/kimi-k2.6"
last_verified = 2026-08-01

[engines.opencode.models."openrouter/nvidia/nemotron-3-nano-30b-a3b:free"]
display = "Nemotron 3 Nano 30B A3B (free)"
lab = "NVIDIA"
confidence = "verified"
source = "manifest model field; OpenRouter slug nvidia/nemotron-3-nano-30b-a3b:free"
last_verified = 2026-08-01

[engines.opencode.models."openrouter/nvidia/nemotron-3-super-120b-a12b"]
display = "Nemotron 3 Super 120B A12B"
lab = "NVIDIA"
confidence = "verified"
source = "manifest model field; OpenRouter slug nvidia/nemotron-3-super-120b-a12b"
last_verified = 2026-08-01

[engines.opencode.models."openrouter/nvidia/nemotron-3-ultra-550b-a55b:free"]
display = "Nemotron 3 Ultra 550B A55B (free)"
lab = "NVIDIA"
confidence = "verified"
source = "manifest model field; OpenRouter slug nvidia/nemotron-3-ultra-550b-a55b:free"
last_verified = 2026-08-01

[engines.opencode.models."openrouter/qwen/qwen3-coder"]
display = "Qwen3 Coder 480B A35B"
lab = "Alibaba (Qwen)"
confidence = "verified"
source = "manifest model field; OpenRouter slug qwen/qwen3-coder"
last_verified = 2026-08-01

[engines.opencode.models."openrouter/thinkingmachines/inkling"]
display = "Inkling"
lab = "Thinking Machines Lab"
confidence = "verified"
source = "https://openrouter.ai/thinkingmachines/inkling"
last_verified = 2026-08-01

[engines.opencode.models."openrouter/poolside/laguna-m.1:free"]
# Not a typo — OpenRouter carried this slug from 2026-07-09 until it was
# delisted 2026-08-01T23:13:22Z (same day as this entry, hours before this
# registry check ran). Confirmed via ~/.ringer/openrouter-catalog.changes.jsonl
# added/removed events, catalog name "Poolside: Laguna M.1 (free)". Historical
# attempts against this slug should still resolve to Poolside identity even
# though the model is no longer orderable.
display = "Laguna M.1 (free)"
lab = "Poolside"
confidence = "verified"
source = "OpenRouter catalog history (~/.ringer/openrouter-catalog.changes.jsonl): added 2026-07-09, delisted 2026-08-01"
last_verified = 2026-08-01

[engines.opencode.models."openrouter/nousresearch/hermes-3-llama-3.1-405b:free"]
# Not a typo — OpenRouter carried the free tier of this model from 2026-07-09
# until it was delisted 2026-07-19; the paid nousresearch/hermes-3-llama-3.1-405b
# slug remains live. Catalog name "Nous: Hermes 3 405B Instruct (free)".
display = "Hermes 3 405B Instruct (free)"
lab = "Nous Research"
confidence = "verified"
source = "OpenRouter catalog history (~/.ringer/openrouter-catalog.changes.jsonl): added 2026-07-09, delisted 2026-07-19"
last_verified = 2026-08-01
Loading