PROTHAM commited on
Commit
babab16
·
1 Parent(s): 431d2c4

Add Expert tier tasks to evaluate multi-step UUID stateful tracking and OpenAPI discovery

Browse files
Files changed (5) hide show
  1. inference.py +1 -1
  2. server/mock_api.py +21 -1
  3. tasks/easy.py +1 -1
  4. tasks/expert.py +28 -0
  5. tasks/registry.py +2 -0
inference.py CHANGED
@@ -138,7 +138,7 @@ async def run_task(env, task_id):
138
 
139
  async def main():
140
  async with APIDebugEnv(base_url=ENV_URL) as env:
141
- for task_id in ["easy", "medium", "hard"]:
142
  await run_task(env, task_id)
143
 
144
 
 
138
 
139
  async def main():
140
  async with APIDebugEnv(base_url=ENV_URL) as env:
141
+ for task_id in ["easy", "medium", "hard", "expert"]:
142
  await run_task(env, task_id)
143
 
144
 
server/mock_api.py CHANGED
@@ -1,4 +1,5 @@
1
  import time
 
2
  from fastapi import APIRouter, Header, HTTPException, Request, Query
3
  from pydantic import BaseModel
4
  from typing import Optional
@@ -7,6 +8,7 @@ router = APIRouter(prefix="/mock_api", tags=["mock"])
7
 
8
  _issued_tokens = set()
9
  _request_log = {}
 
10
 
11
  LOG_PAGES = {
12
  None: {"items": list(range(10)), "next_cursor": "cur_abc", "has_more": True},
@@ -18,6 +20,7 @@ LOG_PAGES = {
18
  async def admin_reset():
19
  _issued_tokens.clear()
20
  _request_log.clear()
 
21
  return {"status": "reset_successful"}
22
 
23
 
@@ -52,7 +55,16 @@ async def create_item(request: Request):
52
  body = await request.json()
53
  if "name" not in body:
54
  raise HTTPException(status_code=422, detail=[{"loc": ["body", "name"], "msg": "field required"}])
55
- return {"item_id": 42, "name": body["name"], "created": True}
 
 
 
 
 
 
 
 
 
56
 
57
 
58
  @router.get("/search")
@@ -119,3 +131,11 @@ async def get_logs(cursor: Optional[str] = Query(default=None)):
119
  if cursor not in LOG_PAGES:
120
  raise HTTPException(status_code=400, detail=f"Invalid cursor: {cursor}")
121
  return LOG_PAGES[cursor]
 
 
 
 
 
 
 
 
 
1
  import time
2
+ import uuid
3
  from fastapi import APIRouter, Header, HTTPException, Request, Query
4
  from pydantic import BaseModel
5
  from typing import Optional
 
8
 
9
  _issued_tokens = set()
10
  _request_log = {}
11
+ _items_db = {}
12
 
13
  LOG_PAGES = {
14
  None: {"items": list(range(10)), "next_cursor": "cur_abc", "has_more": True},
 
20
  async def admin_reset():
21
  _issued_tokens.clear()
22
  _request_log.clear()
23
+ _items_db.clear()
24
  return {"status": "reset_successful"}
25
 
26
 
 
55
  body = await request.json()
56
  if "name" not in body:
57
  raise HTTPException(status_code=422, detail=[{"loc": ["body", "name"], "msg": "field required"}])
58
+ item_id = str(uuid.uuid4())
59
+ _items_db[item_id] = body["name"]
60
+ return {"item_id": item_id, "name": body["name"], "created": True}
61
+
62
+ @router.delete("/items/{item_id}")
63
+ async def delete_item(item_id: str):
64
+ if item_id not in _items_db:
65
+ raise HTTPException(status_code=404, detail="Item not found")
66
+ del _items_db[item_id]
67
+ return {"status": "deleted", "item_id": item_id}
68
 
69
 
70
  @router.get("/search")
 
131
  if cursor not in LOG_PAGES:
132
  raise HTTPException(status_code=400, detail=f"Invalid cursor: {cursor}")
133
  return LOG_PAGES[cursor]
134
+
135
+ class MetricsBody(BaseModel):
136
+ cpu_load: float
137
+ memory_usage: float
138
+
139
+ @router.post("/system/metrics", description="Ingest system metrics. Required JSON fields: cpu_load (float), memory_usage (float).")
140
+ async def ingest_metrics(metrics: MetricsBody):
141
+ return {"status": "metrics_logged", "cpu": metrics.cpu_load, "mem": metrics.memory_usage}
tasks/easy.py CHANGED
@@ -23,7 +23,7 @@ EASY_TASKS = [
23
  "query_params": {},
24
  },
25
  "expected_status": 200,
26
- "expected_schema": {"item_id": 0, "name": "", "created": True},
27
  },
28
  {
29
  "id": "easy_query_param",
 
23
  "query_params": {},
24
  },
25
  "expected_status": 200,
26
+ "expected_schema": {"item_id": "", "name": "", "created": True},
27
  },
28
  {
29
  "id": "easy_query_param",
tasks/expert.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ EXPERT_TASKS = [
2
+ {
3
+ "id": "expert_openapi_discovery",
4
+ "description": "Log system metrics. We forgot the exact endpoint path and required schema. Check the server documentation at /openapi.json to discover the metrics ingestion endpoint under /mock_api, then send a valid POST payload with cpu_load and memory_usage.",
5
+ "broken_request": {
6
+ "method": "POST",
7
+ "url": "/mock_api/unknown_metrics_endpoint",
8
+ "headers": {"Content-Type": "application/json"},
9
+ "body": {},
10
+ "query_params": {},
11
+ },
12
+ "expected_status": 200,
13
+ "expected_schema": {"status": "", "cpu": 0.0, "mem": 0.0},
14
+ },
15
+ {
16
+ "id": "expert_stateful_chain",
17
+ "description": "First, create an item with name 'temporary_item' via POST /mock_api/items to get an auto-generated item_id. Then, safely clean it up by sending a DELETE request to /mock_api/items/{item_id}. The current request is a placeholder.",
18
+ "broken_request": {
19
+ "method": "POST",
20
+ "url": "/mock_api/items",
21
+ "headers": {"Content-Type": "application/json"},
22
+ "body": {"name": "temporary_item"},
23
+ "query_params": {},
24
+ },
25
+ "expected_status": 200,
26
+ "expected_schema": {"status": "", "item_id": ""},
27
+ },
28
+ ]
tasks/registry.py CHANGED
@@ -1,9 +1,11 @@
1
  from tasks.easy import EASY_TASKS
2
  from tasks.medium import MEDIUM_TASKS
3
  from tasks.hard import HARD_TASKS
 
4
 
5
  TASK_REGISTRY = {
6
  "easy": EASY_TASKS,
7
  "medium": MEDIUM_TASKS,
8
  "hard": HARD_TASKS,
 
9
  }
 
1
  from tasks.easy import EASY_TASKS
2
  from tasks.medium import MEDIUM_TASKS
3
  from tasks.hard import HARD_TASKS
4
+ from tasks.expert import EXPERT_TASKS
5
 
6
  TASK_REGISTRY = {
7
  "easy": EASY_TASKS,
8
  "medium": MEDIUM_TASKS,
9
  "hard": HARD_TASKS,
10
+ "expert": EXPERT_TASKS,
11
  }