| 1 | import { runSSH, b64 } from './ssh'; |
| 2 | import type { DelegateParams, DelegateResult } from './types'; |
| 3 | |
| 4 | const HOST = process.env.ZPM_CODEX_HOST || 'REDACTED-IP'; |
| 5 | const USER = process.env.ZPM_CODEX_USER || 'zion'; |
| 6 | |
| 7 | export async function codexAdapter(p: DelegateParams): Promise<DelegateResult> { |
| 8 | const start = Date.now(); |
| 9 | const cwd = p.cwd || '/tmp'; |
| 10 | const prompt = p.context ? `${p.context}\n\n---\n\n${p.task}` : p.task; |
| 11 | const cmd = |
| 12 | `export PATH="$HOME/.local/bin:/usr/local/bin:$PATH"; cd ${JSON.stringify(cwd)} 2>/dev/null; ` + |
| 13 | `f=$(mktemp); printf %s ${b64(prompt)} | base64 -d > "$f"; ` + |
| 14 | `codex exec --skip-git-repo-check "$(cat "$f")" 2>&1; rc=$?; rm -f "$f"; exit $rc`; |
| 15 | try { |
| 16 | const r = await runSSH(HOST, USER, cmd, p.timeoutMs ?? 240_000); |
| 17 | return { ok: r.code === 0, output: extractCodexReply(r.stdout) || r.stderr.trim(), artifacts: [], error: r.code === 0 ? undefined : `exit ${r.code}`, durationMs: Date.now() - start }; |
| 18 | } catch (e) { |
| 19 | return { ok: false, output: '', artifacts: [], error: (e as Error).message, durationMs: Date.now() - start }; |
| 20 | } |
| 21 | } |
| 22 | |
| 23 | function extractCodexReply(raw: string): string { |
| 24 | const s = raw.trim(); |
| 25 | const i = s.lastIndexOf('\ncodex\n'); |
| 26 | let body = i >= 0 ? s.slice(i + 7) : s; |
| 27 | body = body.replace(/\ntokens used[\s\S]*$/i, '').trim(); |
| 28 | return body || s; |
| 29 | } |