File size: 7,136 Bytes
ea9cb24
 
 
 
 
 
 
 
 
 
 
7043cc6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58bb04b
7043cc6
58bb04b
 
 
 
52e6772
58bb04b
 
52e6772
58bb04b
 
7043cc6
 
 
0983a18
 
 
 
 
 
 
 
 
 
 
 
7043cc6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7ff548f
2ae1f78
 
 
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
---
title: AdaptiveWorld Env
emoji: 🌐
colorFrom: indigo
colorTo: purple
sdk: docker
app_file: server/app.py
app_port: 7860
pinned: false
---

# AdaptiveWorld Env

**Theme 3.1** (World Modeling / Professional Tasks) + **Theme 5** (Wild Card)  
**Sub-theme:** Patronus AI β€” Consumer Workflows with Schema Drift  
**Built on:** [ProthamD/api-debug-env](https://huggingface.co/spaces/ProthamD/api-debug-env) (Round 1)

---

## What This Is

An OpenEnv environment where an AI agent completes multi-step professional tasks
(booking, ordering, filing claims) while the world **mutates mid-episode without announcement**.

API schemas change, field names shift, policies flip, and sometimes the API returns
`200 OK` but the meaning of the response has silently changed.

### Five novel contributions (stacked)

1. **Non-stationary world** β€” environment mutates mid-episode (drift mechanic)
2. **Dual metrics** β€” `task_reward` + `belief_accuracy` tracked separately
3. **Adaptive difficulty** β€” environment auto-escalates when agent masters easy drift types
4. **Drift provenance hidden** β€” agent must infer drift from evidence, not from being told
5. **Cross-episode persistence** β€” agent's world model carries across episodes

No existing OpenEnv environment has any of these five properties simultaneously.

---

## Quick Start

```bash
# Install
pip install -e .

# Run server
uvicorn server.app:app --host 0.0.0.0 --port 7860

# Health check
curl http://localhost:7860/health

# Run inference
python inference.py --difficulty easy --episodes 3
```

---

## Project Structure

```
adaptive-world-env/
β”œβ”€β”€ server/
β”‚   β”œβ”€β”€ app.py                        ← FastAPI entry point
β”‚   β”œβ”€β”€ adaptive_world_environment.py ← Core environment logic
β”‚   β”œβ”€β”€ mock_api.py                   ← Dynamic mock API (4 domains)
β”‚   β”œβ”€β”€ drift_injector.py             ← World state mutation manager
β”‚   └── difficulty_controller.py     ← Adaptive difficulty escalation
β”œβ”€β”€ scenarios/
β”‚   β”œβ”€β”€ easy.py    (E1: field rename, E2: endpoint version, E3: auth scheme)
β”‚   β”œβ”€β”€ medium.py  (M1: double drift, M2: policy flip, M3: rate limit)
β”‚   β”œβ”€β”€ hard.py    (H1: silent status, H2: response structure, H3: cascading)
β”‚   └── expert.py  (EX1: transient vs real, EX2: cross-service, EX3: red herring)
β”œβ”€β”€ graders/grader.py                 ← grade_task + grade_belief + infer_belief
β”œβ”€β”€ models.py                         ← AdaptiveAction, AdaptiveObservation, AdaptiveState
β”œβ”€β”€ inference.py                      ← LLM inference loop (OpenAI-compatible)
β”œβ”€β”€ training_notebook.ipynb          ← Colab GRPO training notebook
└── openenv.yaml                      ← OpenEnv spec
```

---

## Action Space

| `action_type` | What it does |
|---|---|
| `call_api` | Standard HTTP request to mock API |
| `probe_schema` | GET current API schema β€” reveals post-drift contract |
| `query_history` | Review last N step logs β€” compare pre vs post drift responses |
| `declare_belief` | Agent states its current world model (scored later) |
| `submit_result` | End episode, agent declares final `belief_state` |

---

## Observation Space

All fields the agent sees. **Note:** `drift_occurred` and `drift_type` are intentionally absent.
The agent must infer drift from evidence.

| Field | Type | Description |
|---|---|---|
| `task_description` | str | What to accomplish |
| `domain` | str | e-commerce / hotel / flight / insurance |
| `prior_world_model` | dict | Agent's beliefs from previous episodes |
| `current_step` | int | Step number |
| `max_steps` | int | Episode step limit |
| `last_status_code` | int | HTTP status of last call |
| `last_response_body` | str | Response body |
| `step_feedback` | str | Contextual hint |
| `episode_history` | list | Returned by `query_history` |
| `task_reward` | float | Task completion score (on done) |
| `belief_accuracy` | float | Belief accuracy score (on done) |
| `difficulty_level` | int | Current escalation level (0-3) |
| `reward` | float | Combined: 0.7Γ—task + 0.3Γ—belief |

---

## Drift Types

| Type | Error Signal | Example |
|---|---|---|
| `field_rename` | 422 | `qty` β†’ `quantity` |
| `endpoint_version` | 404 | `/book` β†’ `/v2/book` |
| `policy_change` | 403 or 429 | Discount requires gold membership |
| `silent_semantic` | None (200 OK) | `"confirmed"` β†’ `"approved"` |

---

## Training Results

| Metric | Early window (dashboard) | Late window (dashboard) |
|---|---|---|
| Task reward (avg) | 0.35 | 0.49 |
| Belief accuracy (avg) | 0.16 | 0.23 |
| Combined reward (avg) | 0.30 | 0.41 |
| Correlation r (task vs belief) | 0.957 | **0.977** |

These aggregates come from the same 200-step GRPO run (Qwen2.5-3B 4-bit, 4 completions/step)
after SFT (30 steps) and before/with DPO (~50 steps), matching the Training Runs dashboard export.

The correlation chart is the headline: early-window correlation is already high (~0.957) on smoothed traces;
late-window correlation reaches ~**0.977** β€” task success and belief understanding stay aligned as difficulty ramps.

---

## Combating Reward Hacking

During development, we discovered that highly capable models (like Llama-3.3-70B) would exhibit **reward hacking**. The models were so efficient they would complete the task within 2 stepsβ€”before the environment's original `drift_trigger_step` even had a chance to mutate the API!

Furthermore, when the API returned a `200 OK` (even with a silent semantic drift inside the body), the environment was auto-terminating the episode. This short-circuited the agent, preventing it from investigating the response and resulting in a `0.0` belief accuracy score despite a high task reward.

**How we solved it:**
1. **Immediate Drift:** We lowered `drift_trigger_step = 1` for most scenarios. The world mutates immediately on the very first API call, forcing the agent to confront the non-stationary world.
2. **Preventing Auto-Termination:** We removed the environment's premature auto-termination on task completion. Instead of ending the episode immediately upon a `200 OK`, the environment returns a feedback hint: *"Task completed successfully. Please review the response for any silent changes, and use 'submit_result' to end the episode."* This forces the agent to explicitly declare its understanding of the new API contract before scoring occurs.

---

## HF Space Deployment

```bash
# Create new HF Space (Docker)
huggingface-cli repo create prothamd-adaptive-world-env --type space --space-sdk docker

# Push
git remote add hf https://huggingface.co/spaces/ProthamD/prothamd-adaptive-world-env
git push hf main
```

Space URL: `https://huggingface.co/spaces/ProthamD/prothamd-adaptive-world-env`  
API URL: `https://prothamd-adaptive-world-env.hf.space`

---

## Run Tests

```bash
pytest tests/ -v
```

---

*Built on: `ProthamD/api-debug-env` (Round 1 submission)*  
*Version: 2.3 β€” Adaptive Difficulty + Drift Provenance Hidden + Cross-Episode Persistence*


Licensed under CC BY-NC 4.0 β€” https://creativecommons.org/licenses/by-nc/4.0/