MCPcopy Create free account
hub / github.com/MaxBittker/runebench / OpenCodeAdapter

Class OpenCodeAdapter

agents/opencode_adapter.py:89–336  ·  view source on GitHub ↗

Base class for agents that run via OpenCode CLI.

Source from the content-addressed store, hash-verified

87 # Meta Model API (api.meta.ai) — custom provider declared in
88 # muse_adapter; the key is referenced as {env:META_MODEL_API_KEY} in opencode.json.
89 "meta": "META_MODEL_API_KEY",
90 # z.ai GLM Coding Plan (api.z.ai/api/coding/paas/v4) — native models.dev
91 # provider used by glm53_adapter.
92 "zai-coding-plan": "ZHIPU_API_KEY",
93}
94
95
96class OpenCodeAdapter(BaseInstalledAgent):
97 """
98 Base class for agents that run via OpenCode CLI.
99 """
100
101 _default_model: str = ""
102 _log_prefix: str = "opencode"
103 _log_file: str = "opencode.txt"
104 _model_options: dict = {} # extra options merged into the model config
105
106 def __init__(self, run_timeout_sec: int | None = None, *args, **kwargs):
107 super().__init__(*args, **kwargs)
108 self._run_timeout_sec = int(run_timeout_sec) if run_timeout_sec is not None else None
109
110 @property
111 def _install_agent_template_path(self) -> Path:
112 return Path(__file__).parent / "install-opencode.sh.j2"
113
114 @staticmethod
115 def name() -> str:
116 return "opencode-adapter"
117
118 async def install(self, environment: BaseEnvironment) -> None:
119 # OpenCode is pre-installed in the Docker image via NVM.
120 # Verify it's accessible; if not, install it.
121 result = await environment.exec(
122 command='export NVM_DIR="$HOME/.nvm"; [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"; command -v opencode',
123 )
124 if result.return_code != 0:
125 await self.exec_as_agent(
126 environment,
127 command=(
128 "curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.2/install.sh | bash && "
129 'export NVM_DIR="$HOME/.nvm" && '
130 '. "$NVM_DIR/nvm.sh" && '
131 "nvm install 22 && npm i -g opencode-ai@latest && "
132 "opencode --version"
133 ),
134 )
135
136 def populate_context_post_run(self, context: AgentContext) -> None:
137 """Parse OpenCode JSONL log → ATIF trajectory.json + token counts."""
138 log_path = self.logs_dir / self._log_file
139 if not log_path.exists():
140 logger.warning("OpenCode log not found: %s", log_path)
141 return
142
143 try:
144 trajectory = _parse_opencode_log(
145 log_path,
146 model_name=self.model_name or self._default_model,

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected