thisisgini commited on
Commit
13b2248
·
verified ·
1 Parent(s): 0b580ad

Update inference.py

Browse files
Files changed (1) hide show
  1. inference.py +102 -55
inference.py CHANGED
@@ -1,66 +1,113 @@
 
1
  import os
2
- import sys
3
  import json
 
4
  from openai import OpenAI
5
 
6
- # 1. MANDATORY START TAG
7
- # Updated to match the model we are actually calling
8
- print("[START] task=ecommerce_lifecycle_v1 env=ecommerce_bot model=Qwen2.5-72B-Instruct", flush=True)
 
 
 
 
9
 
10
- def run_inference(data):
11
- # 2. CONFIGURATION FROM YOUR SCREENSHOT (image_42204f.png)
12
- # This ensures we hit the exact proxy the validator expects
13
- api_base = os.getenv("API_BASE_URL") or "https://router.huggingface.co/v1"
14
-
15
- # In HF Spaces, the 'API_KEY' for the router is usually your HF_TOKEN secret
16
- api_key = os.getenv("HF_TOKEN") or os.getenv("API_KEY")
17
- model_name = os.getenv("MODEL_NAME") or "Qwen/Qwen2.5-72B-Instruct"
18
-
19
- # Initialize OpenAI client pointed at the Hugging Face Router
20
- client = OpenAI(
21
- base_url=api_base,
22
- api_key=api_key
23
- )
24
-
25
- query = data.get("query", "")
26
- order_id = data.get("order_id", "Unknown")
27
-
28
- # 3. LOG THE STEP - Include model name to prove we are using the correct router
29
- print(f"[STEP] step=1 action=hf_router_call model={model_name} reward=0.5 done=False", flush=True)
30
 
 
 
 
 
 
 
31
  try:
32
- # 4. THE ACTUAL PROXY CALL
33
- # Note: We use the parameters (temp, max_tokens) observed in your screenshot
34
  completion = client.chat.completions.create(
35
- model=model_name,
36
  messages=[
37
- {"role": "system", "content": "You are a professional e-commerce agent. Respond ONLY in valid JSON with fields: 'reply', 'action', and 'status'. Actions: issue_refund, update_address, escalate_to_hitl."},
38
- {"role": "user", "content": f"User Query: {query} | Order ID: {order_id}"}
39
  ],
40
- temperature=0.7,
41
- max_tokens=150
42
  )
43
-
44
- # 5. PARSE & CLEAN
45
- raw_content = completion.choices[0].message.content
46
- # Remove any markdown backticks if the model includes them
47
- clean_content = raw_content.replace("```json", "").replace("```", "").strip()
48
- llm_json = json.loads(clean_content)
49
-
50
- # 6. LOG FINAL SUCCESS
51
- print(f"[STEP] step=2 action={llm_json.get('action', 'complete')} reward=1.0 done=True", flush=True)
52
- print(f"[END] task=ecommerce_lifecycle_v1 score=1.0 steps=2", flush=True)
53
-
54
- return llm_json
55
-
56
- except Exception as e:
57
- # Detailed error logging for your HF Container tab
58
- print(f"HF ROUTER FAILURE: {str(e)}", flush=True)
59
- print(f"[STEP] step=1 action=error reward=0.0 done=True", flush=True)
60
- print(f"[END] task=ecommerce_lifecycle_v1 score=0.0 steps=1", flush=True)
61
-
62
- return {
63
- "reply": "The fulfillment system is temporarily unreachable via the HF Router.",
64
- "action": "error",
65
- "status": "failed"
66
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
  import os
3
+ import textwrap
4
  import json
5
+ from typing import List, Optional
6
  from openai import OpenAI
7
 
8
+ # Import the environment classes - ensure these files are in your root!
9
+ # Based on your previous screenshots, you might need to adjust the import name
10
+ try:
11
+ from my_env_v4 import MyEnvV4Action, MyEnvV4Env
12
+ except ImportError:
13
+ # Fallback if the naming in your project is different
14
+ from env import MyEnvV4Action, MyEnvV4Env
15
 
16
+ # 1. CONFIGURATION (Environment Variables)
17
+ IMAGE_NAME = os.getenv("IMAGE_NAME")
18
+ API_KEY = os.getenv("HF_TOKEN") or os.getenv("API_KEY")
19
+ API_BASE_URL = os.getenv("API_BASE_URL") or "https://router.huggingface.co/v1"
20
+ MODEL_NAME = os.getenv("MODEL_NAME") or "Qwen/Qwen2.5-72B-Instruct"
21
+
22
+ TASK_NAME = "ecommerce_lifecycle_v1"
23
+ BENCHMARK = "scaler_ecommerce_bot"
24
+ MAX_STEPS = 5 # Adjusted based on your previous logic
25
+ TEMPERATURE = 0.7
26
+ MAX_TOKENS = 150
27
+
28
+ # 2. LOGGING HELPERS (Mandatory for Scaler Stdout Parsing)
29
+ def log_start(task: str, env: str, model: str) -> None:
30
+ print(f"[START] task={task} env={env} model={model}", flush=True)
31
+
32
+ def log_step(step: int, action: str, reward: float, done: bool, error: Optional[str]) -> None:
33
+ error_val = error if error else "null"
34
+ done_val = str(done).lower()
35
+ print(f"[STEP] step={step} action={action} reward={reward:.2f} done={done_val} error={error_val}", flush=True)
36
 
37
+ def log_end(success: bool, steps: int, score: float, rewards: List[float]) -> None:
38
+ rewards_str = ",".join(f"{r:.2f}" for r in rewards)
39
+ print(f"[END] success={str(success).lower()} steps={steps} score={score:.2f} rewards={rewards_str}", flush=True)
40
+
41
+ # 3. LLM INFERENCE LOGIC
42
+ def get_model_decision(client: OpenAI, query: str, history: List[str]) -> dict:
43
  try:
 
 
44
  completion = client.chat.completions.create(
45
+ model=MODEL_NAME,
46
  messages=[
47
+ {"role": "system", "content": "You are an e-commerce agent. Respond ONLY in JSON with 'reply', 'action' (issue_refund, update_address, escalate_to_hitl), and 'status'."},
48
+ {"role": "user", "content": f"Query: {query}\nHistory: {history}"}
49
  ],
50
+ temperature=TEMPERATURE,
51
+ max_tokens=MAX_TOKENS,
52
  )
53
+ content = completion.choices[0].message.content.strip()
54
+ # Clean potential markdown
55
+ clean_content = content.replace("```json", "").replace("```", "").strip()
56
+ return json.loads(clean_content)
57
+ except Exception as exc:
58
+ print(f"[DEBUG] Proxy call failed: {exc}", flush=True)
59
+ return {"reply": "Error", "action": "escalate_to_hitl", "status": "error"}
60
+
61
+ # 4. MAIN AGENT LOOP
62
+ async def main() -> None:
63
+ client = OpenAI(base_url=API_BASE_URL, api_key=API_KEY)
64
+
65
+ # Initialize the containerized environment
66
+ env = await MyEnvV4Env.from_docker_image(IMAGE_NAME)
67
+
68
+ rewards: List[float] = []
69
+ steps_taken = 0
70
+ score = 0.0
71
+ success = False
72
+ history = []
73
+
74
+ log_start(task=TASK_NAME, env=BENCHMARK, model=MODEL_NAME)
75
+
76
+ try:
77
+ # Reset environment and get initial observation
78
+ result = await env.reset()
79
+ current_query = result.observation.get("query", "No query provided")
80
+
81
+ for step in range(1, MAX_STEPS + 1):
82
+ if result.done:
83
+ break
84
+
85
+ # Get decision from LLM via Proxy
86
+ decision = get_model_decision(client, current_query, history)
87
+ action_str = decision.get("action", "none")
88
+
89
+ # Execute step in environment
90
+ result = await env.step(MyEnvV4Action(action=action_str, metadata=decision))
91
+
92
+ reward = result.reward or 0.0
93
+ done = result.done
94
+
95
+ rewards.append(reward)
96
+ steps_taken = step
97
+ log_step(step=step, action=action_str, reward=reward, done=done, error=None)
98
+
99
+ history.append(f"Step {step}: {action_str} -> reward {reward}")
100
+
101
+ if done:
102
+ break
103
+
104
+ # Calculate final score (normalized to 1.0)
105
+ score = sum(rewards) / len(rewards) if rewards else 0.0
106
+ success = score > 0.5
107
+
108
+ finally:
109
+ await env.close()
110
+ log_end(success=success, steps=steps_taken, score=score, rewards=rewards)
111
+
112
+ if __name__ == "__main__":
113
+ asyncio.run(main())