Spaces:
Sleeping
Sleeping
File size: 5,932 Bytes
3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 88b7c69 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 7769e75 3b33bb3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | import asyncio
import os
import textwrap
from typing import List, Optional
from openai import OpenAI
# from .UnitTestCaseGenerator_environment import (
# UnittestcasegeneratorEnvironment,
# UnittestcasegeneratorAction,
# )
from client import UnittestcasegeneratorEnv, UnittestcasegeneratorAction
# ββ CONFIG βββββββββββββββββββββββββββββββββββββββββββββ
API_KEY = os.getenv("HF_TOKEN") or os.getenv("API_KEY")
API_BASE_URL = os.getenv("API_BASE_URL") or "https://router.huggingface.co/v1"
MODEL_NAME = os.getenv("MODEL_NAME") or "Qwen/Qwen2.5-72B-Instruct"
BENCHMARK = "unit_test_env"
MAX_STEPS = 1
SUCCESS_SCORE_THRESHOLD = 0.5
DIFFICULTIES = ["easy", "medium", "hard"]
# ββ PROMPT βββββββββββββββββββββββββββββββββββββββββββββ
SYSTEM_PROMPT = textwrap.dedent(
"""
You are an expert Java developer. You write JUnit 5 unit tests.
Rules:
- ALWAYS read the source code carefully before writing tests
- ALWAYS use the exact class name specified in the task hint
- NEVER write tests for a different class than what is given
- Use @Test annotation on every test method
- Always import: import org.junit.jupiter.api.Test;
- Always import: import static org.junit.jupiter.api.Assertions.*;
- Use assertEquals, assertTrue, assertFalse, assertThrows
- Reply with ONLY Java code, no explanation
"""
).strip()
# ββ LOGGING (STRICT FORMAT) βββββββββββββββββββββββββββββ
def log_start(task: str, env: str, model: str):
print(f"[START] task={task} env={env} model={model}", flush=True)
def log_step(step: int, action: str, reward: float, done: bool, error: Optional[str]):
error_val = error if error else "null"
done_str = "true" if done else "false"
print(
f"[STEP] step={step} action={action[:100]} reward={reward} done={done_str} error={error_val}",
flush=True,
)
def log_end(success: bool, steps: int, score: float, rewards: List[float]):
# Update 0.0 and 1.0 to be 0 and 1 without decimal places
for i, r in enumerate(rewards, 1):
if abs(r - 0.0) < 1e-6:
rewards[i - 1] = 0
elif abs(r - 1.0) < 1e-6:
rewards[i - 1] = 1
rewards_str = ",".join(f"{r}" for r in rewards)
success_str = "true" if success else "false"
print(
f"[END] success={success_str} steps={steps} score={score} rewards={rewards_str}",
flush=True,
)
# ββ MODEL CALL βββββββββββββββββββββββββββββββββββββββββββββ
def get_tests_from_model(
client: OpenAI,
source_code: str,
task_hint: str,
feedback: Optional[str],
) -> str:
prompt = f"""
{task_hint}
Source code:
{source_code}
Feedback: {feedback or "None"}
Write JUnit 5 tests:
"""
try:
completion = client.chat.completions.create(
model=MODEL_NAME,
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": prompt},
],
temperature=0.3,
max_tokens=800,
)
text = (completion.choices[0].message.content or "").strip()
return text.replace("```java", "").replace("```", "").strip()
except Exception:
return "public class PlaceholderTest {}"
# ββ MAIN βββββββββββββββββββββββββββββββββββββββββββββ
async def main():
client = OpenAI(base_url=API_BASE_URL, api_key=API_KEY)
from client import UnittestcasegeneratorEnv
all_rewards = []
success = False
score = 0
for difficulty in DIFFICULTIES:
# env = UnittestcasegeneratorEnv(base_url="http://localhost:8000")
with UnittestcasegeneratorEnv(base_url="http://localhost:8000").sync() as env:
rewards: List[float] = []
steps_taken = 0
feedback = None
log_start(task=difficulty, env=BENCHMARK, model=MODEL_NAME)
try:
result = env.reset(difficulty=difficulty)
source_code = result.observation.source_code
task_hint = result.observation.task_hint
for step in range(1, MAX_STEPS + 1):
if result.observation.done:
break
action = get_tests_from_model(client, source_code, task_hint, feedback)
result = env.step(UnittestcasegeneratorAction(test_code=action))
reward = result.observation.reward or 0.0
done = result.observation.done
error = getattr(result, "error", None)
feedback = f"Passed {result.observation.passed}/{result.observation.total}"
rewards.append(reward)
steps_taken = step
log_step(step, action, reward, done, error)
if done:
break
score = max(rewards) if rewards else 0.0
_EPS = 0.001
score = min(max(score, _EPS), 1.0 - _EPS)
success = score >= SUCCESS_SCORE_THRESHOLD
finally:
try:
if hasattr(env, "close"):
env.close()
except Exception:
pass
log_end(success, steps_taken, score, rewards)
all_rewards.append(score)
# ββ RUN βββββββββββββββββββββββββββββββββββββββββββββ
if __name__ == "__main__":
asyncio.run(main())
|