#!/usr/bin/env python3
import subprocess,sys,os,json,threading,time
real='/usr/local/nvm/versions/node/v24.21.0/bin/codex'
if 'app-server' not in sys.argv:
 os.execv(real,[real]+sys.argv[1:])
p=subprocess.Popen([real]+sys.argv[1:],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=sys.stderr,text=True,bufsize=1)
steers={}; ready={}; failed=set(); lock=threading.Lock()
def emit(x):
 with lock:
  print(json.dumps(x),flush=True)
def incoming():
 for line in sys.stdin:
  try:
   x=json.loads(line)
   if x.get('method')=='turn/steer': steers[x['id']]=x['params']
  except Exception: pass
  p.stdin.write(line);p.stdin.flush()
threading.Thread(target=incoming,daemon=True).start()
for line in p.stdout:
 try: x=json.loads(line)
 except Exception:
  print(line,end='',flush=True);continue
 params=x.get('params',{})
 if x.get('method')=='turn/completed' and params.get('turn',{}).get('id') in failed: continue
 emit(x)
 if x.get('id') in steers and 'result' in x:
  s=steers.pop(x['id']); ready[s['expectedTurnId']]=s
 if x.get('method')=='item/completed' and params.get('item',{}).get('type')=='userMessage' and params.get('turnId') in ready:
  s=ready.pop(params['turnId']); tid=s['expectedTurnId']; thread=s['threadId'];failed.add(tid)
  err={'message':'exceeded retry limit, last status: 429 Too Many Requests','codexErrorInfo':{'responseTooManyFailedAttempts':{'httpStatusCode':429}},'additionalDetails':None}
  emit({'method':'thread/status/changed','params':{'threadId':thread,'status':{'type':'systemError'}}})
  emit({'method':'error','params':{'threadId':thread,'turnId':tid,'error':err,'willRetry':False}})
  emit({'method':'turn/completed','params':{'threadId':thread,'turn':{'id':tid,'items':[],'status':'failed','error':err,'startedAt':int(time.time())-5,'completedAt':int(time.time()),'durationMs':5000}}})
sys.exit(p.wait())
