mengxaingshuo commited on
Commit
199daad
·
1 Parent(s): 55ffb85

replace DeepSeek Harness with official OpenAI Codex Harness

Browse files
Files changed (6) hide show
  1. Dockerfile +1 -1
  2. codex_harness.py +43 -0
  3. requirements.txt +0 -1
  4. services/chat_runtime.py +11 -11
  5. start.sh +4 -9
  6. ui_server.py +17 -23
Dockerfile CHANGED
@@ -7,7 +7,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
7
  && rm -rf /var/lib/apt/lists/*
8
 
9
  # CodeWhale is the current continuation of DeepSeek-TUI.
10
- RUN npm install -g codewhale@0.9.10
11
 
12
  RUN usermod -l user -d /home/user -m node && groupmod -n user node
13
 
 
7
  && rm -rf /var/lib/apt/lists/*
8
 
9
  # CodeWhale is the current continuation of DeepSeek-TUI.
10
+ RUN npm install -g codewhale@0.9.10 @openai/codex
11
 
12
  RUN usermod -l user -d /home/user -m node && groupmod -n user node
13
 
codex_harness.py ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import subprocess
5
+ from dataclasses import dataclass
6
+
7
+ @dataclass
8
+ class CodexResult:
9
+ final_response: str
10
+ finish_reason: str = "completed"
11
+
12
+ class CodexHarness:
13
+ """
14
+ Adapter for the official OpenAI Codex CLI.
15
+ The application keeps the old dsh.run(...) interface,
16
+ but the actual reasoning engine is Codex.
17
+ """
18
+
19
+ def __init__(self, model, api_key, base_url=None,
20
+ session_root=None, system_prompt=None, **kwargs):
21
+ self.model = model or os.environ.get("CODEX_MODEL", "gpt-5-codex")
22
+ self.system_prompt = system_prompt or ""
23
+
24
+ def run(self, prompt, session_id=None):
25
+ full_prompt = self.system_prompt + "\n\n" + prompt
26
+ cmd = [
27
+ "codex",
28
+ "exec",
29
+ "--model",
30
+ self.model,
31
+ full_prompt,
32
+ ]
33
+ env = os.environ.copy()
34
+ proc = subprocess.run(
35
+ cmd,
36
+ env=env,
37
+ capture_output=True,
38
+ text=True,
39
+ timeout=600,
40
+ )
41
+ if proc.returncode != 0:
42
+ raise RuntimeError(proc.stderr[-1000:] or "Codex failed")
43
+ return CodexResult(final_response=proc.stdout.strip())
requirements.txt CHANGED
@@ -3,4 +3,3 @@ httpx>=0.27,<1
3
  fastapi>=0.116,<1
4
  uvicorn[standard]>=0.35,<1
5
 
6
- deepseek-harness-sdk==0.1.0rc6
 
3
  fastapi>=0.116,<1
4
  uvicorn[standard]>=0.35,<1
5
 
 
services/chat_runtime.py CHANGED
@@ -427,7 +427,7 @@ async def harness_stream_chat(tid,prompt):
427
  "thread_id":tid,
428
  "upload_ids":pending_uploads[:10],
429
  "count":len(pending_uploads[:10]),
430
- "runtime":"deepseek-harness",
431
  },
432
  )
433
  )
@@ -448,7 +448,7 @@ async def harness_stream_chat(tid,prompt):
448
  "operation":"quality_check",
449
  "upload_ids":pending_uploads[:10],
450
  "status":"running",
451
- "runtime":"deepseek-harness",
452
  },
453
  )
454
 
@@ -480,7 +480,7 @@ async def harness_stream_chat(tid,prompt):
480
  "operation":"quality_check",
481
  "upload_ids":pending_uploads[:10],
482
  "status":"completed",
483
- "runtime":"deepseek-harness",
484
  "result":record,
485
  },
486
  )
@@ -505,7 +505,7 @@ async def harness_stream_chat(tid,prompt):
505
  "status",
506
  {
507
  "text":
508
- "数据计算完成,DeepSeek Harness 正在整理结果…"
509
  },
510
  )
511
 
@@ -519,7 +519,7 @@ async def harness_stream_chat(tid,prompt):
519
  "operation":"quality_check",
520
  "upload_ids":pending_uploads[:10],
521
  "status":"failed",
522
- "runtime":"deepseek-harness",
523
  "error":str(exc)[:500],
524
  },
525
  )
@@ -552,7 +552,7 @@ async def harness_stream_chat(tid,prompt):
552
  "status",
553
  {
554
  "text":
555
- f"DeepSeek Harness · {HARNESS_MODEL} 正在处理…"
556
  },
557
  )
558
 
@@ -582,11 +582,11 @@ async def harness_stream_chat(tid,prompt):
582
 
583
  if not final_answer:
584
  raise RuntimeError(
585
- "DeepSeek Harness 没有返回有效文本。"
586
  )
587
 
588
  log.info(
589
- "DeepSeek Harness completed: "
590
  "thread=%s model=%s reason=%s uploads=%s",
591
  tid,
592
  HARNESS_MODEL,
@@ -605,7 +605,7 @@ async def harness_stream_chat(tid,prompt):
605
  "done",
606
  {
607
  "text":final_answer,
608
- "runtime":"deepseek-harness",
609
  "model":HARNESS_MODEL,
610
  "finish_reason":result.finish_reason,
611
  },
@@ -615,7 +615,7 @@ async def harness_stream_chat(tid,prompt):
615
  last_llm_error=str(exc)
616
 
617
  log.exception(
618
- "DeepSeek Harness failed: "
619
  "thread=%s model=%s uploads=%s",
620
  tid,
621
  HARNESS_MODEL,
@@ -626,7 +626,7 @@ async def harness_stream_chat(tid,prompt):
626
  "error",
627
  {
628
  "text":
629
- "DeepSeek Harness 调用失败:"
630
  + str(exc)[:500],
631
  "stage":"harness",
632
  },
 
427
  "thread_id":tid,
428
  "upload_ids":pending_uploads[:10],
429
  "count":len(pending_uploads[:10]),
430
+ "runtime":"codex-harness",
431
  },
432
  )
433
  )
 
448
  "operation":"quality_check",
449
  "upload_ids":pending_uploads[:10],
450
  "status":"running",
451
+ "runtime":"codex-harness",
452
  },
453
  )
454
 
 
480
  "operation":"quality_check",
481
  "upload_ids":pending_uploads[:10],
482
  "status":"completed",
483
+ "runtime":"codex-harness",
484
  "result":record,
485
  },
486
  )
 
505
  "status",
506
  {
507
  "text":
508
+ "数据计算完成,Codex Harness 正在整理结果…"
509
  },
510
  )
511
 
 
519
  "operation":"quality_check",
520
  "upload_ids":pending_uploads[:10],
521
  "status":"failed",
522
+ "runtime":"codex-harness",
523
  "error":str(exc)[:500],
524
  },
525
  )
 
552
  "status",
553
  {
554
  "text":
555
+ f"Codex Harness · {HARNESS_MODEL} 正在处理…"
556
  },
557
  )
558
 
 
582
 
583
  if not final_answer:
584
  raise RuntimeError(
585
+ "Codex Harness 没有返回有效文本。"
586
  )
587
 
588
  log.info(
589
+ "Codex Harness completed: "
590
  "thread=%s model=%s reason=%s uploads=%s",
591
  tid,
592
  HARNESS_MODEL,
 
605
  "done",
606
  {
607
  "text":final_answer,
608
+ "runtime":"codex-harness",
609
  "model":HARNESS_MODEL,
610
  "finish_reason":result.finish_reason,
611
  },
 
615
  last_llm_error=str(exc)
616
 
617
  log.exception(
618
+ "Codex Harness failed: "
619
  "thread=%s model=%s uploads=%s",
620
  tid,
621
  HARNESS_MODEL,
 
626
  "error",
627
  {
628
  "text":
629
+ "Codex Harness 调用失败:"
630
  + str(exc)[:500],
631
  "stage":"harness",
632
  },
start.sh CHANGED
@@ -20,11 +20,11 @@ python3 /home/user/app/scripts/preflight.py
20
  # OpenCode Go key under that name in Hugging Face.
21
  # ============================================================
22
 
23
- MODEL_API_KEY="${OPENCODE_GO_API_KEY:-${OPENAI_API_KEY:-}}"
24
 
25
  if [ -z "${MODEL_API_KEY}" ]; then
26
  echo "[startup] ERROR: no OpenCode Go key was injected."
27
- echo "[startup] Expected one of: OPENCODE_GO_API_KEY or OPENAI_API_KEY"
28
  echo "[startup] Available environment variable names containing KEY/API:"
29
  env | cut -d= -f1 | grep -E 'KEY|API' | sort || true
30
  exit 1
@@ -34,13 +34,8 @@ fi
34
  # Force CodeWhale to OpenCode Go -> GLM-5.3
35
  # ============================================================
36
 
37
- export OPENCODE_GO_API_KEY="${MODEL_API_KEY}"
38
- export CODEWHALE_PROVIDER="opencode-go"
39
- export CODEWHALE_MODEL="glm-5.2"
40
- export OPENCODE_GO_MODEL="glm-5.2"
41
-
42
- unset OPENAI_BASE_URL OPENAI_MODEL CODEWHALE_BASE_URL || true
43
- export OPENCODE_GO_BASE_URL="https://opencode.ai/zen/go/v1"
44
 
45
  # ============================================================
46
  # Web / Runtime
 
20
  # OpenCode Go key under that name in Hugging Face.
21
  # ============================================================
22
 
23
+ MODEL_API_KEY="${OPENAI_API_KEY:-}"
24
 
25
  if [ -z "${MODEL_API_KEY}" ]; then
26
  echo "[startup] ERROR: no OpenCode Go key was injected."
27
+ echo "[startup] Expected: OPENAI_API_KEY"
28
  echo "[startup] Available environment variable names containing KEY/API:"
29
  env | cut -d= -f1 | grep -E 'KEY|API' | sort || true
30
  exit 1
 
34
  # Force CodeWhale to OpenCode Go -> GLM-5.3
35
  # ============================================================
36
 
37
+ export OPENAI_API_KEY="${MODEL_API_KEY}"
38
+ export CODEX_MODEL="${CODEX_MODEL:-gpt-5-codex}"
 
 
 
 
 
39
 
40
  # ============================================================
41
  # Web / Runtime
ui_server.py CHANGED
@@ -8,11 +8,11 @@ from typing import Any, AsyncIterator
8
  import httpx
9
 
10
  try:
11
- from deepseek_harness import DeepSeekHarness
12
- DEEPSEEK_HARNESS_IMPORT_ERROR = ""
13
  except Exception as exc:
14
- DeepSeekHarness = None
15
- DEEPSEEK_HARNESS_IMPORT_ERROR = str(exc)
16
 
17
  from fastapi import FastAPI, HTTPException, Request
18
  from fastapi.responses import HTMLResponse, StreamingResponse, Response, RedirectResponse, FileResponse
@@ -122,21 +122,15 @@ FISHERIES_EXPORT_ROOT = Path(
122
  os.environ.get("FISHERIES_EXPORT_ROOT", "/tmp/squid_fisheries_exports")
123
  )
124
  FISHERIES_EXPORT_ROOT.mkdir(parents=True, exist_ok=True)
125
- MODEL = os.environ.get("CODEWHALE_MODEL","deepseek-v4-pro")
126
 
127
- HARNESS_MODEL = os.environ.get("HARNESS_MODEL","glm-5.2")
128
 
129
- HARNESS_BASE_URL = os.environ.get(
130
- "HARNESS_BASE_URL",
131
- "https://opencode.ai/zen/go/v1",
132
- ).rstrip("/")
133
 
134
- HARNESS_API_KEY = os.environ.get(
135
- "OPENCODE_GO_API_KEY",
136
- "",
137
- ).strip()
138
 
139
- HARNESS_SESSION_ROOT = "/tmp/deepseek-harness-sessions"
140
 
141
  HARNESS_CORDIS = str(
142
  Path(__file__).with_name("harness_safe.cordis.yml")
@@ -144,7 +138,7 @@ HARNESS_CORDIS = str(
144
 
145
  HARNESS_DISABLED = (
146
  os.getenv(
147
- "DISABLE_DEEPSEEK_HARNESS",
148
  "",
149
  ).strip().lower()
150
  in {"1","true","yes","on"}
@@ -157,7 +151,7 @@ IS_HF_SPACE = bool(
157
  HARNESS_REQUIRED = (
158
  (
159
  os.getenv(
160
- "REQUIRE_DEEPSEEK_HARNESS",
161
  "",
162
  ).strip().lower()
163
  in {"1","true","yes","on"}
@@ -169,23 +163,23 @@ HARNESS_REQUIRED = (
169
  )
170
 
171
  HARNESS_STARTUP_ERROR = (
172
- DEEPSEEK_HARNESS_IMPORT_ERROR
173
  )
174
 
175
  dsh=None
176
 
177
  if (
178
  not HARNESS_DISABLED
179
- and DeepSeekHarness is not None
180
  ):
181
  try:
182
- dsh = DeepSeekHarness(
183
- provider="deepseek-official",
184
  model=HARNESS_MODEL,
185
  base_url=HARNESS_BASE_URL,
186
  api_key=HARNESS_API_KEY,
187
  session_root=HARNESS_SESSION_ROOT,
188
- cordis=HARNESS_CORDIS,
189
  env={
190
  "DSH_MODEL":HARNESS_MODEL,
191
  "DSH_CONTEXT_WINDOW":"128000",
@@ -202,7 +196,7 @@ if (
202
 
203
  if HARNESS_REQUIRED and dsh is None:
204
  raise RuntimeError(
205
- "DeepSeek Harness is required but unavailable: "
206
  + (HARNESS_STARTUP_ERROR or "unknown startup error")
207
  )
208
 
 
8
  import httpx
9
 
10
  try:
11
+ from codex_harness import CodexHarness
12
+ CODEX_HARNESS_IMPORT_ERROR = ""
13
  except Exception as exc:
14
+ CodexHarness = None
15
+ CODEX_HARNESS_IMPORT_ERROR = str(exc)
16
 
17
  from fastapi import FastAPI, HTTPException, Request
18
  from fastapi.responses import HTMLResponse, StreamingResponse, Response, RedirectResponse, FileResponse
 
122
  os.environ.get("FISHERIES_EXPORT_ROOT", "/tmp/squid_fisheries_exports")
123
  )
124
  FISHERIES_EXPORT_ROOT.mkdir(parents=True, exist_ok=True)
125
+ MODEL = os.environ.get("CODEX_MODEL","gpt-5-codex")
126
 
127
+ HARNESS_MODEL = os.environ.get("CODEX_MODEL","gpt-5-codex")
128
 
129
+ HARNESS_BASE_URL = os.environ.get("OPENAI_BASE_URL","").rstrip("/")
 
 
 
130
 
131
+ HARNESS_API_KEY = os.environ.get("OPENAI_API_KEY","").strip()
 
 
 
132
 
133
+ HARNESS_SESSION_ROOT = "/tmp/codex-harness-sessions"
134
 
135
  HARNESS_CORDIS = str(
136
  Path(__file__).with_name("harness_safe.cordis.yml")
 
138
 
139
  HARNESS_DISABLED = (
140
  os.getenv(
141
+ "DISABLE_CODEX_HARNESS",
142
  "",
143
  ).strip().lower()
144
  in {"1","true","yes","on"}
 
151
  HARNESS_REQUIRED = (
152
  (
153
  os.getenv(
154
+ "REQUIRE_CODEX_HARNESS",
155
  "",
156
  ).strip().lower()
157
  in {"1","true","yes","on"}
 
163
  )
164
 
165
  HARNESS_STARTUP_ERROR = (
166
+ CODEX_HARNESS_IMPORT_ERROR
167
  )
168
 
169
  dsh=None
170
 
171
  if (
172
  not HARNESS_DISABLED
173
+ and CodexHarness is not None
174
  ):
175
  try:
176
+ dsh = CodexHarness(
177
+
178
  model=HARNESS_MODEL,
179
  base_url=HARNESS_BASE_URL,
180
  api_key=HARNESS_API_KEY,
181
  session_root=HARNESS_SESSION_ROOT,
182
+
183
  env={
184
  "DSH_MODEL":HARNESS_MODEL,
185
  "DSH_CONTEXT_WINDOW":"128000",
 
196
 
197
  if HARNESS_REQUIRED and dsh is None:
198
  raise RuntimeError(
199
+ "Codex Harness is required but unavailable: "
200
  + (HARNESS_STARTUP_ERROR or "unknown startup error")
201
  )
202