Tejasva commited on
Commit
ae190ad
Β·
1 Parent(s): 557bac4

minor fixes

Browse files
__pycache__/inference.cpython-313.pyc CHANGED
Binary files a/__pycache__/inference.cpython-313.pyc and b/__pycache__/inference.cpython-313.pyc differ
 
env/__pycache__/environment.cpython-313.pyc CHANGED
Binary files a/env/__pycache__/environment.cpython-313.pyc and b/env/__pycache__/environment.cpython-313.pyc differ
 
env/__pycache__/grader.cpython-313.pyc CHANGED
Binary files a/env/__pycache__/grader.cpython-313.pyc and b/env/__pycache__/grader.cpython-313.pyc differ
 
env/__pycache__/models.cpython-313.pyc CHANGED
Binary files a/env/__pycache__/models.cpython-313.pyc and b/env/__pycache__/models.cpython-313.pyc differ
 
env/__pycache__/tasks.cpython-313.pyc CHANGED
Binary files a/env/__pycache__/tasks.cpython-313.pyc and b/env/__pycache__/tasks.cpython-313.pyc differ
 
inference_backup.py ADDED
@@ -0,0 +1,424 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+
3
+ import os
4
+ import json
5
+ import logging
6
+ from typing import Dict, Any, Optional, List
7
+
8
+ try:
9
+ from openai import OpenAI
10
+ except ImportError:
11
+ print("Error: openai package not found. Install with: pip install openai")
12
+ exit(1)
13
+
14
+ from env.environment import CodeGuardianEnv
15
+ from env.models import Action, AgentResponse, AgentState
16
+
17
+ # Setup logging
18
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
19
+ logger = logging.getLogger(__name__)
20
+
21
+ def setup_openai_client() -> tuple[OpenAI, str]:
22
+ """Initialize OpenAI client from environment variables."""
23
+ api_base_url = os.getenv('API_BASE_URL', 'https://api.openai.com/v1')
24
+ model_name = os.getenv('MODEL_NAME', 'gpt-4')
25
+
26
+ # HF_TOKEN without default (required for Hugging Face)
27
+ hf_token = os.getenv('HF_TOKEN')
28
+ api_key = hf_token or os.getenv('API_KEY')
29
+
30
+ if not api_key:
31
+ raise ValueError("Neither HF_TOKEN nor API_KEY environment variables are set")
32
+
33
+ # Initialize OpenAI client with base_url and api_key
34
+ client = OpenAI(
35
+ api_key=api_key,
36
+ base_url=api_base_url
37
+ )
38
+
39
+ return client, model_name
40
+
41
+ def create_adaptive_prompt(observation: Dict[str, Any], step_type: str, agent_state: AgentState) -> str:
42
+ """Create adaptive prompt based on agent learning state."""
43
+ step_names = {
44
+ 'detect': 'Issue Detection',
45
+ 'risk': 'Risk Assessment',
46
+ 'fix': 'Fix Suggestion'
47
+ }
48
+
49
+ step_instructions = {
50
+ 'detect': 'list all issues you find in the code',
51
+ 'risk': 'output the risk level (low/medium/high)',
52
+ 'fix': 'provide corrected code that fixes the identified issues'
53
+ }
54
+
55
+ # Adaptive prompt based on learning
56
+ learning_context = ""
57
+ if agent_state.past_failures:
58
+ learning_context = f"\nLEARNING FROM PAST MISTAKES:\n{chr(10).join(f'- Avoid: {failure}' for failure in agent_state.past_failures[-3:])}"
59
+
60
+ if agent_state.prompt_strategy == "detailed":
61
+ instruction_detail = " Be thorough and provide detailed reasoning."
62
+ elif agent_state.prompt_strategy == "focused":
63
+ instruction_detail = " Focus on most critical issues first."
64
+ else:
65
+ instruction_detail = ""
66
+
67
+ prompt = f"""You are a professional code reviewer learning from feedback.
68
+
69
+ Code:
70
+ {observation.code}
71
+
72
+ Intent:
73
+ {observation.intent}
74
+
75
+ Constraints:
76
+ {chr(10).join(f"- {constraint}" for constraint in observation.constraints)}
77
+
78
+ Step: {step_names[step_type]}
79
+
80
+ Instructions:
81
+ * {step_instructions[step_type]}{instruction_detail}
82
+ * Provide confidence score (0.0-1.0)
83
+ * Include your reasoning{learning_context}
84
+
85
+ Respond ONLY in JSON format:
86
+ {{
87
+ "issues_detected": [...],
88
+ "risk_level": "...",
89
+ "fix": "...",
90
+ "confidence": 0.0,
91
+ "reasoning": "...",
92
+ "reward_breakdown": {{
93
+ "detect": 0.0,
94
+ "risk": 0.0,
95
+ "fix": 0.0
96
+ }}
97
+ }}"""
98
+
99
+ return prompt
100
+
101
+ def parse_llm_response(response_text: str) -> AgentResponse:
102
+ """Parse LLM response into structured AgentResponse with fallback."""
103
+ try:
104
+ # Clean up response text
105
+ response_text = response_text.strip()
106
+ if response_text.startswith('```json'):
107
+ response_text = response_text[7:]
108
+ if response_text.endswith('```'):
109
+ response_text = response_text[:-3]
110
+ response_text = response_text.strip()
111
+
112
+ parsed = json.loads(response_text)
113
+
114
+ # Ensure all required fields exist with defaults
115
+ return AgentResponse(
116
+ issues_detected=parsed.get('issues_detected', []),
117
+ risk_level=parsed.get('risk_level', 'low'),
118
+ fix=parsed.get('fix', ''),
119
+ confidence=max(0.0, min(1.0, parsed.get('confidence', 0.5))),
120
+ reasoning=parsed.get('reasoning', ''),
121
+ reward_breakdown=parsed.get('reward_breakdown', {})
122
+ )
123
+ except (json.JSONDecodeError, AttributeError, ValueError) as e:
124
+ logger.warning(f"Failed to parse LLM response: {e}")
125
+ logger.warning(f"Raw response: {response_text[:200]}...")
126
+
127
+ # Return fallback response
128
+ return AgentResponse(
129
+ issues_detected=[],
130
+ risk_level='low',
131
+ fix='',
132
+ confidence=0.1,
133
+ reasoning='Failed to parse response',
134
+ reward_breakdown={}
135
+ )
136
+
137
+ def create_action_from_response(step_type: str, response: AgentResponse) -> Action:
138
+ """Create Action model from structured AgentResponse."""
139
+ return Action(
140
+ action_type=step_type,
141
+ detected_issues=response.issues_detected if step_type == 'detect' else None,
142
+ risk_level=response.risk_level if step_type == 'risk' else None,
143
+ suggested_fix=response.fix if step_type == 'fix' else None
144
+ )
145
+
146
+ def run_llm_inference(client: OpenAI, model_name: str, prompt: str) -> str:
147
+ """Run LLM inference with given prompt."""
148
+ try:
149
+ response = client.chat.completions.create(
150
+ model=model_name,
151
+ messages=[
152
+ {"role": "system", "content": "You are a professional code reviewer. Always respond in valid JSON format with confidence and reasoning."},
153
+ {"role": "user", "content": prompt}
154
+ ],
155
+ temperature=0, # Deterministic
156
+ max_tokens=500 # Increased for structured output
157
+ )
158
+ return response.choices[0].message.content
159
+ except Exception as e:
160
+ logger.error(f"LLM inference failed: {e}")
161
+ raise
162
+
163
+ def run_baseline(env: CodeGuardianEnv) -> float:
164
+ """Run a simple non-learning baseline agent for comparison."""
165
+ print("START: Running baseline agent...")
166
+ logger.info("[BASELINE START] Running baseline agent...")
167
+
168
+ obs = env.reset()
169
+ total_reward = 0.0
170
+ step_count = 0
171
+
172
+ while not env.done and step_count < 50:
173
+ current_step = env.state()['current_step']
174
+ step_types = ['detect', 'risk', 'fix']
175
+ step_type = step_types[current_step]
176
+
177
+ # Baseline always outputs minimal responses
178
+ if step_type == 'detect':
179
+ action = Action(action_type='detect', detected_issues=[])
180
+ elif step_type == 'risk':
181
+ action = Action(action_type='risk', risk_level='low')
182
+ else:
183
+ action = Action(action_type='fix', suggested_fix='')
184
+
185
+ next_obs, reward, done = env.step(action)
186
+ total_reward += reward.value
187
+ step_count += 1
188
+ obs = next_obs
189
+
190
+ logger.info(f"[BASELINE STEP] {step_count}: {step_type} -> reward={reward.value:+.3f}")
191
+
192
+ print(f"END: Baseline complete - Total reward: {total_reward:.3f}, Steps: {step_count}")
193
+ logger.info(f"[BASELINE END] Total reward: {total_reward:.3f}, Steps: {step_count}")
194
+ return total_reward
195
+
196
+ def update_agent_state(agent_state: AgentState, episode_reward: float, feedback: str) -> AgentState:
197
+ """Update agent state based on episode performance for policy improvement."""
198
+ agent_state.episode += 1
199
+ agent_state.total_reward = episode_reward
200
+ agent_state.improvement_history.append(episode_reward)
201
+
202
+ # Update best score
203
+ if episode_reward > agent_state.best_score:
204
+ agent_state.best_score = episode_reward
205
+ logger.info(f"New best score achieved: {episode_reward:.3f}")
206
+
207
+ # STRONGER POLICY UPDATE LOGIC
208
+ # Treat poor performance as failure
209
+ if episode_reward < agent_state.best_score * 0.8:
210
+ agent_state.past_failures.append(f"Episode {agent_state.episode}: reward={episode_reward:.3f}")
211
+ # Keep only recent failures
212
+ agent_state.past_failures = agent_state.past_failures[-5:]
213
+ logger.info(f"Failure recorded - Episode reward: {episode_reward:.3f} vs Best: {agent_state.best_score:.3f}")
214
+
215
+ # IMPROVED STRATEGY SWITCHING
216
+ if episode_reward < agent_state.best_score * 0.7: # Poor performance threshold
217
+ old_strategy = agent_state.prompt_strategy
218
+
219
+ if agent_state.prompt_strategy == "default":
220
+ agent_state.prompt_strategy = "detailed"
221
+ logger.info("Switching strategy: default β†’ detailed")
222
+ elif agent_state.prompt_strategy == "detailed":
223
+ agent_state.prompt_strategy = "focused"
224
+ logger.info("Switching strategy: detailed β†’ focused")
225
+ else:
226
+ # Reset to default if focused still fails
227
+ agent_state.prompt_strategy = "default"
228
+ logger.info("Switching strategy: focused β†’ default (reset)")
229
+
230
+ if old_strategy != agent_state.prompt_strategy:
231
+ logger.info(f"Strategy change triggered by low performance: {episode_reward:.3f} < {agent_state.best_score * 0.7:.3f}")
232
+
233
+ return agent_state
234
+
235
+ def run_episode(env: CodeGuardianEnv, client: OpenAI, model_name: str, agent_state: AgentState) -> tuple[float, List[Dict]]:
236
+ """Run a single episode and return total reward with episode history."""
237
+ obs = env.reset()
238
+ episode_reward = 0.0
239
+ episode_history = []
240
+ step_count = 0
241
+
242
+ print(f"START: Episode {agent_state.episode + 1} - model={model_name} task_id={obs.task_id} difficulty={obs.difficulty}")
243
+ logger.info(f"[EPISODE START] Episode {agent_state.episode + 1} - model={model_name} task_id={obs.task_id} difficulty={obs.difficulty}")
244
+
245
+ while not env.done:
246
+ current_step = env.state()['current_step']
247
+ step_types = ['detect', 'risk', 'fix']
248
+ step_type = step_types[current_step]
249
+
250
+ step_count += 1
251
+ print(f"STEP: {step_count} - {step_type} - task_id={obs.task_id}")
252
+ logger.info(f"[STEP] step_number={step_count} step_type={step_type} task_id={obs.task_id}")
253
+
254
+ # Create adaptive prompt
255
+ prompt = create_adaptive_prompt(obs, step_type, agent_state)
256
+
257
+ # Run LLM inference
258
+ try:
259
+ response_text = run_llm_inference(client, model_name, prompt)
260
+ logger.info(f"LLM response: {response_text[:100]}...")
261
+ except Exception as e:
262
+ logger.error(f"LLM inference failed: {e}")
263
+ # Use fallback response
264
+ agent_response = AgentResponse(
265
+ issues_detected=[],
266
+ risk_level='low',
267
+ fix='',
268
+ confidence=0.1,
269
+ reasoning='Inference failed',
270
+ reward_breakdown={}
271
+ )
272
+ else:
273
+ # Parse structured response
274
+ agent_response = parse_llm_response(response_text)
275
+
276
+ # Create action from response
277
+ action = create_action_from_response(step_type, agent_response)
278
+
279
+ # Execute step
280
+ next_obs, reward, done = env.step(action)
281
+
282
+ # CONFIDENCE-BASED REWARD ADJUSTMENT
283
+ confidence_penalty = (1 - agent_response.confidence) * 0.1
284
+ adjusted_reward = reward.value - confidence_penalty
285
+ episode_reward += adjusted_reward
286
+
287
+ logger.info(f"confidence_penalty={confidence_penalty:.3f} adjusted_reward={adjusted_reward:+.3f} confidence={agent_response.confidence:.2f}")
288
+
289
+ # Log step results
290
+ step_info = {
291
+ "step": step_count,
292
+ "type": step_type,
293
+ "action": action.dict(),
294
+ "response": agent_response.dict(),
295
+ "reward": reward.dict(),
296
+ "adjusted_reward": adjusted_reward,
297
+ "confidence_penalty": confidence_penalty,
298
+ "total_reward": episode_reward
299
+ }
300
+ episode_history.append(step_info)
301
+
302
+ logger.info(f"action_type={action.action_type} reward={reward.value:+.3f} adjusted_reward={adjusted_reward:+.3f} feedback={reward.feedback} total_reward={episode_reward:+.3f} current_step={env.state()['current_step']} current_task={env.state()['current_task']}")
303
+
304
+ # Update observation for next step
305
+ obs = next_obs
306
+
307
+ # Safety check
308
+ if step_count > 50: # Prevent infinite loops
309
+ logger.warning("Maximum steps reached, stopping episode")
310
+ break
311
+
312
+ # Final episode log
313
+ print(f"END: Episode {agent_state.episode + 1} - final_score={episode_reward:.3f} total_steps={step_count} strategy={agent_state.prompt_strategy}")
314
+ logger.info(f"[EPISODE END] Episode {agent_state.episode + 1} - final_score={episode_reward:.3f} total_steps={step_count} strategy={agent_state.prompt_strategy}")
315
+
316
+ return episode_reward, episode_history
317
+
318
+ def train_agent(num_episodes: int = 10) -> AgentState:
319
+ """Train agent over multiple episodes with policy improvement."""
320
+ try:
321
+ # Setup
322
+ client, model_name = setup_openai_client()
323
+ agent_state = AgentState()
324
+ all_episodes = []
325
+
326
+ print(f"START: RL training for {num_episodes} episodes with model: {model_name}")
327
+ logger.info(f"[TRAINING START] Starting RL training for {num_episodes} episodes with model: {model_name}")
328
+
329
+ # RUN BASELINE FIRST
330
+ logger.info("\n{'='*60}")
331
+ logger.info("BASELINE EVALUATION")
332
+ logger.info(f"{'='*60}")
333
+ baseline_env = CodeGuardianEnv()
334
+ baseline_score = run_baseline(baseline_env)
335
+ logger.info(f"Baseline score: {baseline_score:.3f}")
336
+
337
+ # TRAINING LOOP
338
+ logger.info(f"\n{'='*60}")
339
+ logger.info("REINFORCEMENT LEARNING")
340
+ logger.info(f"{'='*60}")
341
+
342
+ for episode in range(num_episodes):
343
+ logger.info(f"\n{'='*50}")
344
+ logger.info(f"EPISODE {episode + 1}/{num_episodes}")
345
+ logger.info(f"{'='*50}")
346
+
347
+ env = CodeGuardianEnv()
348
+ episode_reward, episode_history = run_episode(env, client, model_name, agent_state)
349
+ all_episodes.append({
350
+ "episode": episode + 1,
351
+ "reward": episode_reward,
352
+ "history": episode_history
353
+ })
354
+
355
+ # Update agent state for policy improvement
356
+ agent_state = update_agent_state(agent_state, episode_reward, f"Episode {episode + 1} completed")
357
+
358
+ logger.info(f"Episode {episode + 1} completed with reward: {episode_reward:.3f}")
359
+ logger.info(f"Best score so far: {agent_state.best_score:.3f}")
360
+ logger.info(f"Current strategy: {agent_state.prompt_strategy}")
361
+
362
+ # EARLY STOPPING
363
+ if episode > 3 and agent_state.best_score > 2.5:
364
+ logger.info("Early stopping triggered: high performance achieved")
365
+ logger.info(f"Stopping at episode {episode + 1} with best score {agent_state.best_score:.3f}")
366
+ break
367
+
368
+ # PERFORMANCE COMPARISON
369
+ print("START: Training summary analysis")
370
+ logger.info(f"\n{'='*60}")
371
+ logger.info(f"[TRAINING SUMMARY]")
372
+ logger.info(f"{'='*60}")
373
+
374
+ # Calculate improvement over baseline
375
+ improvement = ((agent_state.best_score - baseline_score) / (abs(baseline_score) + 1e-6)) * 100
376
+
377
+ # Log key metrics
378
+ logger.info(f"RL Agent Best Score: {agent_state.best_score:.3f}")
379
+ logger.info(f"Baseline Score: {baseline_score:.3f}")
380
+ logger.info(f"Performance Improvement: {improvement:.2f}%")
381
+
382
+ # Additional metrics
383
+ if all_episodes:
384
+ avg_reward = sum(ep["reward"] for ep in all_episodes) / len(all_episodes)
385
+ logger.info(f"Average Episode Reward: {avg_reward:.3f}")
386
+ logger.info(f"Episodes Completed: {len(all_episodes)}")
387
+ logger.info(f"Final Strategy: {agent_state.prompt_strategy}")
388
+
389
+ # Performance classification
390
+ if improvement > 50:
391
+ print("πŸš€ EXCELLENT: Significant improvement over baseline!")
392
+ logger.info("πŸš€ EXCELLENT: Significant improvement over baseline!")
393
+ elif improvement > 20:
394
+ print("βœ… GOOD: Measurable improvement achieved")
395
+ logger.info("βœ… GOOD: Measurable improvement achieved")
396
+ elif improvement > 0:
397
+ print("πŸ“ˆ POSITIVE: Some improvement over baseline")
398
+ logger.info("πŸ“ˆ POSITIVE: Some improvement over baseline")
399
+ else:
400
+ print("⚠️ NO IMPROVEMENT: RL agent not better than baseline")
401
+ logger.info("⚠️ NO IMPROVEMENT: RL agent not better than baseline")
402
+
403
+ return agent_state
404
+
405
+ except Exception as e:
406
+ logger.error(f"Training failed: {e}")
407
+ raise
408
+
409
+ def main():
410
+ """Main inference loop with RL training."""
411
+ try:
412
+ # Run RL training
413
+ agent_state = train_agent(num_episodes=10)
414
+ print("END: RL training completed successfully")
415
+ logger.info("END: RL training completed successfully")
416
+ return 0
417
+
418
+ except Exception as e:
419
+ print(f"END: Inference failed with error: {e}")
420
+ logger.error(f"Inference failed: {e}")
421
+ return 1
422
+
423
+ if __name__ == "__main__":
424
+ exit(main())
requirements.txt CHANGED
@@ -5,3 +5,4 @@ numpy>=1.24.0
5
  python-dotenv>=1.0.0
6
  flask>=3.0.0
7
  gradio>=4.0.0
 
 
5
  python-dotenv>=1.0.0
6
  flask>=3.0.0
7
  gradio>=4.0.0
8
+ plotly