File size: 4,140 Bytes
1f213fe
 
 
 
 
 
 
 
 
 
 
 
 
89d9242
 
1f213fe
 
89d9242
 
1f213fe
 
 
 
 
 
89d9242
1f213fe
 
 
 
6c48c5d
 
1f213fe
89d9242
1f213fe
 
 
6c48c5d
1f213fe
 
 
 
89d9242
 
 
1f213fe
 
 
 
 
89d9242
 
 
 
 
 
 
 
1f213fe
 
 
 
89d9242
 
 
1f213fe
89d9242
1f213fe
 
 
 
 
 
 
 
89d9242
1f213fe
 
89d9242
 
 
 
 
1f213fe
 
 
 
 
 
 
 
 
 
 
 
 
89d9242
1f213fe
 
 
 
 
89d9242
 
 
 
1f213fe
 
89d9242
 
 
 
1f213fe
 
 
 
 
 
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
"""Baseline inference script for PM-Ops environment."""
import json
import os

API_BASE_URL = os.getenv("API_BASE_URL", "https://adityaguntur-pm-ops.hf.space")
MODEL_NAME = os.getenv("MODEL_NAME", "claude-opus-4-5")
HF_TOKEN = os.getenv("HF_TOKEN")
LOCAL_IMAGE_NAME = os.getenv("LOCAL_IMAGE_NAME")

MAX_STEPS = 40
TASK_IDS = ["triage", "incident_routing", "release_notes", "dep_update"]


def baseline_agent(obs: dict, org_config: dict) -> tuple[str, dict]:
    """Heuristic baseline: read runbook -> create ticket -> assign -> notify -> finish."""
    step = obs.get("step", 0)
    task_brief = obs.get("task_brief", "")
    last = obs.get("last_action_result", {})
    data = last.get("data", {})

    if step == 0:
        return "meta.read_runbook", {}

    if step == 1 and isinstance(data, dict) and "org_config" in data:
        org = data["org_config"]
        org_config.update(org)
        label_taxonomy = org.get("label_taxonomy", {})
        priority_levels = org.get("priority_levels", ["P1"])
        label = list(label_taxonomy.values())[0] if label_taxonomy else "bug"
        priority = priority_levels[1] if len(priority_levels) > 1 else priority_levels[0]
        teams = list(org_config.get("team_map", {}).values())
        assignee = teams[0] if teams else "backend"
        return "ticketing.create_ticket", {
            "summary": f"Issue: {task_brief[:80]}",
            "description": task_brief,
            "label": label,
            "priority": priority,
            "assignee": assignee,
        }

    if step == 2 and isinstance(data, dict) and "id" in data:
        ticket_id = data["id"]
        teams = list(org_config.get("team_map", {}).values())
        team = teams[0] if teams else "backend"
        return "ticketing.assign_ticket", {"ticket_id": ticket_id, "team": team}

    if step == 3:
        return "chat.list_channels", {}

    if step == 4:
        oncall = org_config.get("oncall_channels", {})
        oncall_names = list(oncall.values())
        channels = data if isinstance(data, list) else []
        channel = oncall_names[0] if oncall_names else (channels[0] if channels else "general")
        return "chat.post_message", {
            "channel": channel,
            "text": f"Incident notification: {task_brief[:150]}. Please review and respond.",
        }

    return "meta.finish", {}


def run_episode(task_id: str, env) -> float:
    result = env.reset()
    obs = result.observation if hasattr(result, "observation") else result

    org_config: dict = {}
    rewards = []
    n = 0
    done = False
    score = 0.0

    print(f"[START] task={task_id} env=pm_ops model={MODEL_NAME}", flush=True)

    while not done and n < MAX_STEPS:
        action_type, args = baseline_agent(obs, org_config)

        try:
            result = env.step({"action_type": action_type, "args": args})
            obs = result.observation if hasattr(result, "observation") else result
            r = float(result.reward if hasattr(result, "reward") else obs.get("reward", 0.0))
            done = bool(result.done if hasattr(result, "done") else obs.get("done", False))
            err = obs.get("last_action_result", {}).get("error", "none") if isinstance(obs, dict) else "none"
        except Exception as e:
            r = 0.0
            done = True
            err = str(e)

        rewards.append(r)
        n += 1
        print(f"[STEP] step={n} action={action_type} reward={r:.2f} done={done} error={err}", flush=True)

        if done:
            score = r

    rewards_str = ",".join(f"{x:.2f}" for x in rewards)
    success = score > 0.5
    print(f"[END] success={success} steps={n} score={score:.2f} rewards={rewards_str}", flush=True)
    return score


def main():
    from openenv.core import GenericEnvClient

    async_client = GenericEnvClient(base_url=API_BASE_URL)
    env = async_client.sync()

    total_score = 0.0
    with env:
        for task_id in TASK_IDS:
            score = run_episode(task_id, env)
            total_score += score

    print(f"[SUMMARY] avg_score={total_score / len(TASK_IDS):.3f}", flush=True)


if __name__ == "__main__":
    main()