"""Owner-requested model-only adapter; ordinary Runner CLI and gates unchanged.""" import os import json import sys from pathlib import Path control = Path(os.environ['OWNER_RUNNER_CONTROL']).resolve() sys.path.insert(0, str(control)) from runner.core import Runner ALLOWED_CODEX_MODELS = ('gpt-6.1-sol', 'gpt-6-astra') original_llm = Runner.llm def owner_model_llm(self, task_id, role, service, prompt, cwd, schema): if service == 'claude' and role == 'commander': schema = json.loads(json.dumps(schema)) schema['required'] += ['codex_model', 'codex_model_reason'] schema['properties']['codex_model'] = {'type': 'string', 'enum': list(ALLOWED_CODEX_MODELS)} schema['properties']['codex_model_reason'] = {'type': 'string', 'minLength': 1} prompt = ('Owner-authorized model policy: You, Claude Opus 5.5, select the Codex worker model for this task. ' 'Default gpt-6.1-sol. Select gpt-6-astra only when task difficulty warrants it; ' 'state concrete reasons and consider quality, time and usage. Return codex_model and codex_model_reason ' 'with the ordinary decision. Model choice does not authorize a run, repair, cap change or acceptance waiver.\n' + prompt) if service == 'codex': row = self.db.execute( "SELECT data FROM events WHERE task_id=? AND event='commander_proposal' ORDER BY id DESC LIMIT 1", (task_id,)).fetchone() if not row: raise ValueError('Codex model selection requires recorded Claude commander decision') decision = json.loads(row[0])['decision'] chosen = decision.get('codex_model') if decision.get('task_id') != task_id or decision.get('action') != 'run' or chosen not in ALLOWED_CODEX_MODELS or not str(decision.get('codex_model_reason', '')).strip(): raise ValueError('A recorded Claude run decision with explicit model and reason is required') self._owner_codex_model = chosen try: return original_llm(self, task_id, role, service, prompt, cwd, schema) finally: del self._owner_codex_model return original_llm(self, task_id, role, service, prompt, cwd, schema) Runner.llm = owner_model_llm original = Runner.provider_argv def owner_model_argv(self, service, role, runtime, schema): argv = original(self, service, role, runtime, schema) if service in ('claude', 'codex'): if '--model' in argv: position = argv.index('--model') del argv[position:position + 2] argv += ['--model', 'claude-opus-5-5' if service == 'claude' else getattr(self, '_owner_codex_model', 'gpt-6.1-sol')] return argv Runner.provider_argv = owner_model_argv original_packet = Runner.packet def packet_with_actual_evidence(self, task_id, role, sha=None): packet = original_packet(self, task_id, role, sha) extra = os.environ.get('OWNER_REVIEW_SUPPLEMENT') if role == 'reviewer' and extra: prefix, data = packet.split('\nDATA:\n', 1) body = json.loads(data) body['coordinator_actual_runtime_evidence'] = json.loads(Path(extra).read_text()) assert len(json.dumps(body).encode()) < 500000, 'unchanged complete packet size guard' packet = prefix + '\nDATA:\n' + json.dumps(body, ensure_ascii=False) return packet Runner.packet = packet_with_actual_evidence from runner.cli import main main()