Spaces:
Sleeping
Sleeping
Download inference.py from ProthamD/api-debug-env: direct link, hf CLI and curl.
- Browser
- Download file 3.99 kB
-
https://huggingface.co/spaces/ProthamD/api-debug-env/resolve/06ca7e4ceb1507d3a1d4d1eb7f104caef29ce7e7/inference.py
- Command line
-
hf download hf://spaces/ProthamD/api-debug-env@06ca7e4ceb1507d3a1d4d1eb7f104caef29ce7e7/inference.py
-
curl -L -o inference.py https://huggingface.co/spaces/ProthamD/api-debug-env/resolve/06ca7e4ceb1507d3a1d4d1eb7f104caef29ce7e7/inference.py
3.99 kB
| import os | |
| import json | |
| import asyncio | |
| from openai import OpenAI | |
| from client import APIDebugEnv | |
| from models import APIAction | |
| API_BASE_URL = os.environ["API_BASE_URL"] | |
| MODEL_NAME = os.environ["MODEL_NAME"] | |
| HF_TOKEN = os.environ["HF_TOKEN"] | |
| ENV_URL = os.environ.get("ENV_URL", "http://localhost:8000") | |
| llm = OpenAI(base_url=API_BASE_URL, api_key=HF_TOKEN) | |
| SYSTEM_PROMPT = """You are an HTTP API debugger. You receive a broken request and must fix it to get HTTP 200. | |
| Respond ONLY in valid JSON with exactly these fields: | |
| { | |
| "method": "GET", | |
| "url": "/mock_api/...", | |
| "headers": {}, | |
| "body": null, | |
| "query_params": {} | |
| } | |
| Rules: | |
| - method must be uppercase | |
| - url must start with /mock_api/ | |
| - body must be null for GET requests | |
| - always include Content-Type: application/json when body is not null | |
| - do not add any text outside the JSON""" | |
| def call_llm(task_description, broken_request, last_status, last_body, feedback): | |
| user_msg = ( | |
| f"Task: {task_description}\n\n" | |
| f"Broken request:\n{json.dumps(broken_request, indent=2)}\n\n" | |
| f"Last response status: {last_status}\n" | |
| f"Last response body: {last_body[:300]}\n\n" | |
| f"Feedback: {feedback}\n\n" | |
| f"Return the fixed request as JSON:" | |
| ) | |
| resp = llm.chat.completions.create( | |
| model=MODEL_NAME, | |
| messages=[ | |
| {"role": "system", "content": SYSTEM_PROMPT}, | |
| {"role": "user", "content": user_msg}, | |
| ], | |
| max_tokens=300, | |
| temperature=0.1, | |
| ) | |
| raw = resp.choices[0].message.content.strip() | |
| raw = raw.replace("```json", "").replace("```", "").strip() | |
| try: | |
| return json.loads(raw) | |
| except json.JSONDecodeError: | |
| return broken_request | |
| async def run_task(env, task_id): | |
| obs = await env.reset(task_id=task_id) | |
| state = await env.state() | |
| print(json.dumps({ | |
| "type": "[START]", | |
| "task_id": task_id, | |
| "episode_id": state.episode_id, | |
| "task_description": obs.task_description, | |
| "broken_request": obs.broken_request, | |
| })) | |
| final_reward = 0.0 | |
| step_num = 0 | |
| for step_num in range(state.max_steps): | |
| fixed = call_llm( | |
| obs.task_description, | |
| obs.broken_request, | |
| obs.last_status_code, | |
| obs.last_response_body, | |
| obs.step_feedback, | |
| ) | |
| action = APIAction( | |
| method=str(fixed.get("method", "GET")), | |
| url=str(fixed.get("url", obs.broken_request.get("url", "/mock_api/users"))), | |
| headers=dict(fixed.get("headers") or {}), | |
| body=fixed.get("body") or {}, | |
| query_params=dict(fixed.get("query_params") or {}), | |
| ) | |
| result = await env.step(action) | |
| final_reward = result.reward | |
| obs = result.observation | |
| print(json.dumps({ | |
| "type": "[STEP]", | |
| "task_id": task_id, | |
| "step": step_num + 1, | |
| "action": { | |
| "method": action.method, | |
| "url": action.url, | |
| "headers": action.headers, | |
| "body": action.body, | |
| "query_params": action.query_params, | |
| }, | |
| "status_code": obs.last_status_code, | |
| "reward": result.reward, | |
| "done": result.done, | |
| "feedback": obs.step_feedback, | |
| })) | |
| if result.done: | |
| break | |
| print(json.dumps({ | |
| "type": "[END]", | |
| "task_id": task_id, | |
| "final_reward": final_reward, | |
| "steps_taken": step_num + 1, | |
| })) | |
| return final_reward | |
| async def main(): | |
| async with APIDebugEnv(base_url=ENV_URL) as env: | |
| scores = {} | |
| for task_id in ["easy", "medium", "hard"]: | |
| scores[task_id] = await run_task(env, task_id) | |
| print(json.dumps({ | |
| "type": "[SUMMARY]", | |
| "scores": scores, | |
| "average": round(sum(scores.values()) / len(scores), 4), | |
| })) | |
| if __name__ == "__main__": | |
| asyncio.run(main()) | |