PROTHAM commited on
Commit
9ec21a6
·
1 Parent(s): 8fc7d70

chore: update Dockerfile and inference.py based on local edits

Browse files
Files changed (2) hide show
  1. Dockerfile +6 -5
  2. inference.py +65 -38
Dockerfile CHANGED
@@ -1,12 +1,13 @@
1
- FROM python:3.11-slim-bookworm
2
 
3
  RUN useradd -m -u 1000 envuser
4
  WORKDIR /app
5
 
6
- RUN apt-get update && apt-get install -y gcc curl && rm -rf /var/lib/apt/lists/*
7
 
8
- COPY requirements.txt .
9
- RUN pip install --no-cache-dir -r requirements.txt
 
10
 
11
  COPY . .
12
  RUN pip install --no-cache-dir -e .
@@ -19,4 +20,4 @@ EXPOSE 7860
19
  HEALTHCHECK --interval=20s --timeout=8s --start-period=40s --retries=3 \
20
  CMD curl -f http://localhost:7860/health || exit 1
21
 
22
- CMD ["uvicorn", "server.app:app", "--host", "0.0.0.0", "--port", "7860", "--workers", "1"]
 
1
+ FROM python:3.11-slim
2
 
3
  RUN useradd -m -u 1000 envuser
4
  WORKDIR /app
5
 
6
+ RUN apt-get update && apt-get install -y --no-install-recommends gcc curl && rm -rf /var/lib/apt/lists/*
7
 
8
+ COPY server/requirements.txt .
9
+ RUN pip install --no-cache-dir --upgrade pip && \
10
+ pip install --no-cache-dir -r requirements.txt
11
 
12
  COPY . .
13
  RUN pip install --no-cache-dir -e .
 
20
  HEALTHCHECK --interval=20s --timeout=8s --start-period=40s --retries=3 \
21
  CMD curl -f http://localhost:7860/health || exit 1
22
 
23
+ CMD ["uvicorn", "server.app:app", "--host", "0.0.0.0", "--port", "7860", "--workers", "1"]
inference.py CHANGED
@@ -1,20 +1,19 @@
1
  import os
2
  import json
3
  import asyncio
 
4
  from typing import List, Optional
5
  from openai import OpenAI
6
- from client import APIDebugEnv
7
- from models import APIAction
8
 
9
- API_BASE_URL = os.getenv("API_BASE_URL", "https://router.huggingface.co/v1")
10
- MODEL_NAME = os.getenv("MODEL_NAME", "mistralai/Mistral-7B-Instruct-v0.3")
11
- HF_TOKEN = os.getenv("HF_TOKEN")
12
- ENV_URL = os.getenv("ENV_URL", "http://localhost:7860")
13
  BENCHMARK = "api_debug_env"
14
- MAX_STEPS = 10
15
  SUCCESS_SCORE_THRESHOLD = 0.8
16
 
17
- llm = OpenAI(base_url=API_BASE_URL, api_key=HF_TOKEN or "dummy-token")
18
 
19
  SYSTEM_PROMPT = """You are an HTTP API debugger. You receive a broken request and must fix it to get HTTP 200.
20
  Respond ONLY in valid JSON with exactly these fields:
@@ -56,7 +55,7 @@ def call_llm(task_description, broken_request, last_status, last_body, feedback)
56
  f"Task: {task_description}\n\n"
57
  f"Broken request:\n{json.dumps(broken_request, indent=2)}\n\n"
58
  f"Last response status: {last_status}\n"
59
- f"Last response body: {last_body[:300]}\n\n"
60
  f"Feedback: {feedback}\n\n"
61
  f"Return the fixed request as JSON:"
62
  )
@@ -73,12 +72,29 @@ def call_llm(task_description, broken_request, last_status, last_body, feedback)
73
  raw = resp.choices[0].message.content.strip()
74
  raw = raw.replace("```json", "").replace("```", "").strip()
75
  return json.loads(raw)
76
- except Exception as e:
77
- print(f"[WARN] LLM Call failed: {e}", flush=True)
78
  return broken_request
79
 
80
 
81
- async def run_task(env, task_id):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  rewards: List[float] = []
83
  steps_taken = 0
84
  score = 0.0
@@ -87,35 +103,37 @@ async def run_task(env, task_id):
87
  log_start(task=task_id, env=BENCHMARK, model=MODEL_NAME)
88
 
89
  try:
90
- result = await env.reset(task_id=task_id)
91
- obs = result.observation
92
- state = await env.state()
 
93
 
94
- for step in range(1, state.max_steps + 1):
95
- if result.done:
96
  break
97
 
98
  fixed = call_llm(
99
- obs.task_description,
100
- obs.broken_request,
101
- obs.last_status_code,
102
- obs.last_response_body,
103
- obs.step_feedback,
104
  )
105
 
106
- action = APIAction(
107
- method=str(fixed.get("method", "GET")),
108
- url=str(fixed.get("url", obs.broken_request.get("url", "/mock_api/users"))),
109
- headers=dict(fixed.get("headers") or {}),
110
- body=fixed.get("body") or {},
111
- query_params=dict(fixed.get("query_params") or {}),
112
- )
113
 
114
- action_str = f"{action.method}:{action.url}"
115
- result = await env.step(action)
116
- reward = result.reward or 0.0
117
- done = result.done
118
- obs = result.observation
 
119
 
120
  rewards.append(reward)
121
  steps_taken = step
@@ -130,6 +148,7 @@ async def run_task(env, task_id):
130
 
131
  except Exception as e:
132
  print(f"[DEBUG] Task {task_id} error: {e}", flush=True)
 
133
 
134
  finally:
135
  log_end(success=success, steps=steps_taken, score=score, rewards=rewards)
@@ -138,10 +157,18 @@ async def run_task(env, task_id):
138
 
139
 
140
  async def main():
141
- async with APIDebugEnv(base_url=ENV_URL) as env:
142
- for task_id in ["easy", "medium", "hard", "expert"]:
143
- await run_task(env, task_id)
 
 
 
 
 
 
 
 
144
 
145
 
146
  if __name__ == "__main__":
147
- asyncio.run(main())
 
1
  import os
2
  import json
3
  import asyncio
4
+ import httpx
5
  from typing import List, Optional
6
  from openai import OpenAI
 
 
7
 
8
+ API_BASE_URL = os.getenv("API_BASE_URL") or "https://router.huggingface.co/v1"
9
+ MODEL_NAME = os.getenv("MODEL_NAME") or "mistralai/Mistral-7B-Instruct-v0.3"
10
+ API_KEY = os.getenv("HF_TOKEN") or os.getenv("API_KEY") or "dummy"
11
+ ENV_URL = os.getenv("ENV_URL", "http://localhost:7860").rstrip("/")
12
  BENCHMARK = "api_debug_env"
13
+ MAX_STEPS = 5
14
  SUCCESS_SCORE_THRESHOLD = 0.8
15
 
16
+ llm = OpenAI(base_url=API_BASE_URL, api_key=API_KEY)
17
 
18
  SYSTEM_PROMPT = """You are an HTTP API debugger. You receive a broken request and must fix it to get HTTP 200.
19
  Respond ONLY in valid JSON with exactly these fields:
 
55
  f"Task: {task_description}\n\n"
56
  f"Broken request:\n{json.dumps(broken_request, indent=2)}\n\n"
57
  f"Last response status: {last_status}\n"
58
+ f"Last response body: {str(last_body)[:300]}\n\n"
59
  f"Feedback: {feedback}\n\n"
60
  f"Return the fixed request as JSON:"
61
  )
 
72
  raw = resp.choices[0].message.content.strip()
73
  raw = raw.replace("```json", "").replace("```", "").strip()
74
  return json.loads(raw)
75
+ except Exception:
 
76
  return broken_request
77
 
78
 
79
+ async def env_reset(client: httpx.AsyncClient, task_id: str) -> dict:
80
+ resp = await client.post("/reset", json={"task_id": task_id}, timeout=30)
81
+ resp.raise_for_status()
82
+ return resp.json()
83
+
84
+
85
+ async def env_step(client: httpx.AsyncClient, action: dict) -> dict:
86
+ resp = await client.post("/step", json={"action": action}, timeout=30)
87
+ resp.raise_for_status()
88
+ return resp.json()
89
+
90
+
91
+ async def env_state(client: httpx.AsyncClient) -> dict:
92
+ resp = await client.get("/state", timeout=10)
93
+ resp.raise_for_status()
94
+ return resp.json()
95
+
96
+
97
+ async def run_task(client: httpx.AsyncClient, task_id: str) -> float:
98
  rewards: List[float] = []
99
  steps_taken = 0
100
  score = 0.0
 
103
  log_start(task=task_id, env=BENCHMARK, model=MODEL_NAME)
104
 
105
  try:
106
+ obs = await env_reset(client, task_id)
107
+ state = await env_state(client)
108
+ max_steps = state.get("max_steps", MAX_STEPS)
109
+ done = obs.get("done", False)
110
 
111
+ for step in range(1, max_steps + 1):
112
+ if done:
113
  break
114
 
115
  fixed = call_llm(
116
+ obs.get("task_description", ""),
117
+ obs.get("broken_request", {}),
118
+ obs.get("last_status_code", 0),
119
+ obs.get("last_response_body", ""),
120
+ obs.get("step_feedback", ""),
121
  )
122
 
123
+ action = {
124
+ "method": str(fixed.get("method", "GET")),
125
+ "url": str(fixed.get("url", "/mock_api/users")),
126
+ "headers": dict(fixed.get("headers") or {}),
127
+ "body": fixed.get("body") or None,
128
+ "query_params": dict(fixed.get("query_params") or {}),
129
+ }
130
 
131
+ action_str = f"{action['method']}:{action['url']}"
132
+ result = await env_step(client, action)
133
+
134
+ reward = float(result.get("reward", 0.0))
135
+ done = bool(result.get("done", False))
136
+ obs = result.get("observation", result)
137
 
138
  rewards.append(reward)
139
  steps_taken = step
 
148
 
149
  except Exception as e:
150
  print(f"[DEBUG] Task {task_id} error: {e}", flush=True)
151
+ log_step(step=steps_taken, action="error", reward=0.0, done=True, error=str(e))
152
 
153
  finally:
154
  log_end(success=success, steps=steps_taken, score=score, rewards=rewards)
 
157
 
158
 
159
  async def main():
160
+ async with httpx.AsyncClient(base_url=ENV_URL, timeout=30.0) as client:
161
+ # Verify environment is reachable
162
+ try:
163
+ health = await client.get("/health")
164
+ health.raise_for_status()
165
+ except Exception as e:
166
+ print(f"[DEBUG] Environment not reachable at {ENV_URL}: {e}", flush=True)
167
+ raise
168
+
169
+ for task_id in ["easy", "medium", "hard"]:
170
+ await run_task(client, task_id)
171
 
172
 
173
  if __name__ == "__main__":
174
+ asyncio.run(main())