Spaces:
Sleeping
Sleeping
Commit ·
8778707
1
Parent(s): 842e560
corrected
Browse files- sdea-trained/eval_results.json +38 -0
- test_environment.py +80 -0
- tests/test_environment.py +3 -4
sdea-trained/eval_results.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"random": [
|
| 3 |
+
0.0,
|
| 4 |
+
0.0,
|
| 5 |
+
0.0,
|
| 6 |
+
0.0,
|
| 7 |
+
0.0,
|
| 8 |
+
0.0,
|
| 9 |
+
0.0,
|
| 10 |
+
0.0,
|
| 11 |
+
0.0,
|
| 12 |
+
0.0,
|
| 13 |
+
0.0,
|
| 14 |
+
0.0,
|
| 15 |
+
0.0,
|
| 16 |
+
0.0,
|
| 17 |
+
0.0
|
| 18 |
+
],
|
| 19 |
+
"strategic": [
|
| 20 |
+
11.200000000000003,
|
| 21 |
+
28.53,
|
| 22 |
+
10.079999999999998,
|
| 23 |
+
12.219999999999999,
|
| 24 |
+
17.930000000000007,
|
| 25 |
+
47.68000000000001,
|
| 26 |
+
29.810000000000002,
|
| 27 |
+
58.03,
|
| 28 |
+
39.53,
|
| 29 |
+
51.3,
|
| 30 |
+
44.38,
|
| 31 |
+
51.809999999999995,
|
| 32 |
+
57.7,
|
| 33 |
+
47.52,
|
| 34 |
+
42.98
|
| 35 |
+
],
|
| 36 |
+
"avg_r": 0.0,
|
| 37 |
+
"avg_s": 36.71333333333334
|
| 38 |
+
}
|
test_environment.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from env.environment import SQLDebuggerEnvironment
|
| 2 |
+
from env.models import Action, ActionType
|
| 3 |
+
|
| 4 |
+
env = SQLDebuggerEnvironment()
|
| 5 |
+
|
| 6 |
+
# Test 1: state() before reset — must not crash
|
| 7 |
+
s = env.state()
|
| 8 |
+
print(f"State before reset: initialized={s.initialized}")
|
| 9 |
+
|
| 10 |
+
# Test 2: reset()
|
| 11 |
+
obs = env.reset(difficulty="easy")
|
| 12 |
+
print(f"Reset OK: task_id={obs.task_id}, difficulty={obs.difficulty}")
|
| 13 |
+
print(f"Context keys: {list(obs.current_context.keys())}")
|
| 14 |
+
print(f"Ground truth NOT in context: {'fixed_query' not in obs.current_context}")
|
| 15 |
+
|
| 16 |
+
# Test 3: step() identify_error
|
| 17 |
+
action1 = Action(
|
| 18 |
+
action_type=ActionType.IDENTIFY_ERROR,
|
| 19 |
+
payload={"error_location": "SELECT clause", "error_type": "syntax", "explanation": "Missing commas"}
|
| 20 |
+
)
|
| 21 |
+
resp1 = env.step(action1)
|
| 22 |
+
print(f"Step 1: reward={resp1.reward.score}, done={resp1.done}, step={resp1.observation.step_count}")
|
| 23 |
+
|
| 24 |
+
# Test 4: step() request_hint
|
| 25 |
+
action2 = Action(action_type=ActionType.REQUEST_HINT, payload={"hint_type": "location"})
|
| 26 |
+
resp2 = env.step(action2)
|
| 27 |
+
print(f"Step 2 hint: reward={resp2.reward.score}, hints_used={resp2.observation.hints_used}")
|
| 28 |
+
print(f"Hint in context: {'last_hint' in resp2.observation.current_context}")
|
| 29 |
+
|
| 30 |
+
# Test 5: step() submit_answer
|
| 31 |
+
obs = env.reset(difficulty="easy", task_id="easy_001")
|
| 32 |
+
action3 = Action(
|
| 33 |
+
action_type=ActionType.SUBMIT_ANSWER,
|
| 34 |
+
payload={
|
| 35 |
+
"fixed_query": "SELECT id, name, email FROM users WHERE active = 1",
|
| 36 |
+
"explanation": "Added missing commas between column names in SELECT clause",
|
| 37 |
+
"error_type": "syntax",
|
| 38 |
+
"error_location": "SELECT clause",
|
| 39 |
+
"confidence": 0.95
|
| 40 |
+
}
|
| 41 |
+
)
|
| 42 |
+
resp3 = env.step(action3)
|
| 43 |
+
print(f"Submit answer: reward={resp3.reward.score}, done={resp3.done}")
|
| 44 |
+
|
| 45 |
+
# Test 6: step after done — must not crash
|
| 46 |
+
resp4 = env.step(action3)
|
| 47 |
+
print(f"Step after done: done={resp4.done}, feedback='{resp4.reward.feedback}'")
|
| 48 |
+
|
| 49 |
+
# Test 7: null action
|
| 50 |
+
obs = env.reset(difficulty="easy")
|
| 51 |
+
resp5 = env.step(None)
|
| 52 |
+
print(f"Null action: reward={resp5.reward.score}, done={resp5.done}")
|
| 53 |
+
|
| 54 |
+
# Test 8: reset mid-episode clears state
|
| 55 |
+
obs = env.reset(difficulty="medium")
|
| 56 |
+
print(f"Mid-episode reset: new task={obs.task_id}, step_count={obs.step_count}")
|
| 57 |
+
|
| 58 |
+
# Test 9: full episode 10 steps
|
| 59 |
+
obs = env.reset(difficulty="hard")
|
| 60 |
+
print(f"Hard episode started: {obs.task_id}")
|
| 61 |
+
actions = [
|
| 62 |
+
Action(action_type=ActionType.IDENTIFY_ERROR, payload={"error_location": "SELECT clause", "error_type": "performance"}),
|
| 63 |
+
Action(action_type=ActionType.EXPLAIN_ISSUE, payload={"explanation": "N+1 correlated subqueries cause multiple DB hits per row", "impact": "O(n) queries", "root_cause": "Subquery per user"}),
|
| 64 |
+
Action(action_type=ActionType.OPTIMIZE_QUERY, payload={
|
| 65 |
+
"optimized_query": "SELECT u.id, u.name, COUNT(o.id) as order_count, COALESCE(SUM(o.total), 0) as total_spent FROM users u LEFT JOIN orders o ON u.id = o.user_id GROUP BY u.id, u.name",
|
| 66 |
+
"optimization_type": "Replace N+1 correlated subqueries with LEFT JOIN aggregation",
|
| 67 |
+
"explanation": "Single query replaces N+1 pattern",
|
| 68 |
+
"root_cause": "Correlated subqueries in SELECT",
|
| 69 |
+
"expected_improvement": "99% reduction in DB round trips",
|
| 70 |
+
"confidence": 0.9
|
| 71 |
+
}),
|
| 72 |
+
]
|
| 73 |
+
total = 0.0
|
| 74 |
+
for i, a in enumerate(actions):
|
| 75 |
+
r = env.step(a)
|
| 76 |
+
total += r.reward.score
|
| 77 |
+
print(f" Hard step {i+1}: reward={r.reward.score}, done={r.done}")
|
| 78 |
+
print(f"Hard episode total reward: {round(total,4)}")
|
| 79 |
+
|
| 80 |
+
print("environment.py OK")
|
tests/test_environment.py
CHANGED
|
@@ -50,15 +50,14 @@ def test_reset_clears_state(env):
|
|
| 50 |
|
| 51 |
|
| 52 |
def test_step_identify_error(env):
|
| 53 |
-
|
|
|
|
| 54 |
action = Action(action_type=ActionType.IDENTIFY_ERROR,
|
| 55 |
payload={"error_location": "SELECT clause", "error_type": "syntax",
|
| 56 |
"explanation": "Missing commas"})
|
| 57 |
resp = env.step(action)
|
| 58 |
assert resp.reward.score > 0
|
| 59 |
-
assert resp.done == False
|
| 60 |
-
assert resp.observation.step_count == 1
|
| 61 |
-
|
| 62 |
|
| 63 |
def test_step_null_action(env):
|
| 64 |
"""Null action must return -0.1, never crash."""
|
|
|
|
| 50 |
|
| 51 |
|
| 52 |
def test_step_identify_error(env):
|
| 53 |
+
# Use Round 1 task which has no DB simulator target to hit
|
| 54 |
+
env.reset(difficulty="easy", task_id="easy_001")
|
| 55 |
action = Action(action_type=ActionType.IDENTIFY_ERROR,
|
| 56 |
payload={"error_location": "SELECT clause", "error_type": "syntax",
|
| 57 |
"explanation": "Missing commas"})
|
| 58 |
resp = env.step(action)
|
| 59 |
assert resp.reward.score > 0
|
| 60 |
+
assert resp.done == False # identify_error is not terminal
|
|
|
|
|
|
|
| 61 |
|
| 62 |
def test_step_null_action(env):
|
| 63 |
"""Null action must return -0.1, never crash."""
|