Spaces:
Sleeping
Sleeping
Upload folder using huggingface_hub
Browse files- README.md +58 -46
- server/rewards.py +13 -11
- server/spec_generator.py +12 -5
README.md
CHANGED
|
@@ -13,17 +13,24 @@ base_path: /web
|
|
| 13 |
|
| 14 |
# API Contract Validator β OpenEnv Environment
|
| 15 |
|
| 16 |
-
An OpenEnv RL environment where AI agents learn to validate API request/response
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
## Why This Environment?
|
| 19 |
|
| 20 |
-
API contract violations are one of the **top causes of production incidents** in
|
|
|
|
|
|
|
|
|
|
| 21 |
|
| 22 |
**Real-world applications:**
|
| 23 |
- CI/CD pipeline contract testing
|
| 24 |
-
- API gateway validation
|
| 25 |
-
- SDK compatibility checking
|
| 26 |
-
-
|
|
|
|
| 27 |
|
| 28 |
## How It Works
|
| 29 |
|
|
@@ -31,31 +38,36 @@ Each episode presents the agent with:
|
|
| 31 |
1. An **OpenAPI specification** defining expected types, required fields, and constraints
|
| 32 |
2. A **payload** containing planted violations
|
| 33 |
|
| 34 |
-
The agent inspects both and reports violations **one per step**. The environment
|
|
|
|
| 35 |
|
| 36 |
```
|
| 37 |
-
reset()
|
| 38 |
-
step(violation_report)
|
| 39 |
-
step(
|
|
|
|
| 40 |
```
|
| 41 |
|
| 42 |
-
## Tasks (
|
| 43 |
|
| 44 |
| Task | Difficulty | Violations | Max Steps | What the Agent Must Find |
|
| 45 |
|------|-----------|------------|-----------|--------------------------|
|
| 46 |
-
| `find_type_mismatches` | Easy | 4 | 10 | Type mismatches, missing required fields, invalid enums at the top level |
|
| 47 |
-
| `validate_nested_objects` | Medium | 7 | 15 | Violations inside nested objects and arrays β requires traversing deep structures |
|
| 48 |
-
| `detect_breaking_changes` | Hard | 9 | 20 | Breaking changes between two API spec versions β type changes, removed fields, narrowed enums, new
|
| 49 |
-
| `validate_response_schema` | Expert | 10 | 25 | Subtle format errors in an API response: invalid date formats, pattern mismatches, out-of-range numerics,
|
| 50 |
-
| `validate_cross_field_constraints` | Expert | 7 | 18 | Cross-field arithmetic and date ordering
|
|
|
|
| 51 |
|
| 52 |
### Randomised Episode Generation
|
| 53 |
|
| 54 |
-
All tasks support seed-based randomisation, making the environment suitable for
|
|
|
|
| 55 |
|
| 56 |
-
- `find_type_mismatches` β samples 4
|
| 57 |
-
- `validate_nested_objects` β
|
| 58 |
-
- `validate_response_schema` β
|
|
|
|
| 59 |
- Pass `seed` in the `reset()` call to select a deterministic episode
|
| 60 |
|
| 61 |
## Action Space
|
|
@@ -64,8 +76,8 @@ Each step the agent submits a `ValidatorAction`:
|
|
| 64 |
|
| 65 |
| Field | Type | Description |
|
| 66 |
|-------|------|-------------|
|
| 67 |
-
| `field_path` | `str` | Dot-notation path to the violated field (e.g.
|
| 68 |
-
| `violation_type` | `str` | One of: `type_mismatch`, `missing_required`, `invalid_enum`, `format_error`, `extra_field`, `breaking_change` |
|
| 69 |
| `description` | `str` | Human-readable explanation of the violation |
|
| 70 |
| `suggested_fix` | `str` | Optional suggested correction |
|
| 71 |
|
|
@@ -76,28 +88,30 @@ After each step the agent receives a `ValidatorObservation`:
|
|
| 76 |
| Field | Type | Description |
|
| 77 |
|-------|------|-------------|
|
| 78 |
| `task_name` | `str` | Current task identifier |
|
| 79 |
-
| `task_description` | `str` | Natural-language instructions |
|
| 80 |
| `api_spec` | `dict` | The OpenAPI specification (or version diff for hard task) |
|
| 81 |
-
| `payload` | `dict` | The payload to validate |
|
| 82 |
| `violations_found` | `list[dict]` | Violations correctly identified so far |
|
| 83 |
-
| `violations_remaining` | `int` |
|
| 84 |
| `feedback` | `str` | Result of the last submitted report |
|
| 85 |
-
| `max_steps` | `int` | Step budget for
|
| 86 |
| `done` | `bool` | Whether the episode has ended |
|
| 87 |
| `reward` | `float` | Reward for the last action |
|
| 88 |
|
| 89 |
## Reward Function
|
| 90 |
|
| 91 |
-
|
| 92 |
|
| 93 |
| Event | Reward | Rationale |
|
| 94 |
|-------|--------|-----------|
|
| 95 |
-
| Correct violation
|
| 96 |
-
|
|
| 97 |
-
|
|
| 98 |
-
|
|
|
|
|
|
|
|
| 99 |
|
| 100 |
-
**Final score** = `correct_violations / total_violations`
|
| 101 |
|
| 102 |
## Setup
|
| 103 |
|
|
@@ -138,9 +152,6 @@ python inference.py
|
|
| 138 |
|
| 139 |
```bash
|
| 140 |
openenv validate
|
| 141 |
-
|
| 142 |
-
# Full pre-submission check
|
| 143 |
-
./validate-submission.sh https://your-space.hf.space
|
| 144 |
```
|
| 145 |
|
| 146 |
## Baseline Scores
|
|
@@ -152,6 +163,7 @@ openenv validate
|
|
| 152 |
| `detect_breaking_changes` | Qwen2.5-72B-Instruct | ~0.44 | 12β18 |
|
| 153 |
| `validate_response_schema` | Qwen2.5-72B-Instruct | ~0.40 | 15β22 |
|
| 154 |
| `validate_cross_field_constraints` | Qwen2.5-72B-Instruct | ~0.43 | 10β16 |
|
|
|
|
| 155 |
|
| 156 |
*Scores are approximate and may vary with temperature/sampling.*
|
| 157 |
|
|
@@ -160,20 +172,20 @@ openenv validate
|
|
| 160 |
```
|
| 161 |
api_contract_validator/
|
| 162 |
βββ openenv.yaml # OpenEnv manifest
|
| 163 |
-
βββ pyproject.toml
|
| 164 |
-
βββ Dockerfile
|
| 165 |
-
βββ inference.py
|
| 166 |
-
βββ README.md
|
| 167 |
-
βββ models.py
|
| 168 |
-
βββ client.py
|
| 169 |
-
βββ __init__.py
|
| 170 |
βββ server/
|
| 171 |
βββ __init__.py
|
| 172 |
-
βββ app.py
|
| 173 |
-
βββ environment.py
|
| 174 |
-
βββ spec_generator.py
|
| 175 |
-
βββ rewards.py
|
| 176 |
-
βββ requirements.txt
|
| 177 |
```
|
| 178 |
|
| 179 |
## License
|
|
|
|
| 13 |
|
| 14 |
# API Contract Validator β OpenEnv Environment
|
| 15 |
|
| 16 |
+
An OpenEnv RL environment where AI agents learn to validate API request/response
|
| 17 |
+
payloads against OpenAPI specifications. Agents identify type mismatches, missing
|
| 18 |
+
required fields, invalid enum values, format constraint violations, breaking API
|
| 19 |
+
changes, cross-field arithmetic errors, and authentication schema violations.
|
| 20 |
|
| 21 |
## Why This Environment?
|
| 22 |
|
| 23 |
+
API contract violations are one of the **top causes of production incidents** in
|
| 24 |
+
microservice architectures. Every API integration requires validating payloads
|
| 25 |
+
against specs β a tedious, error-prone task that developers perform daily. This
|
| 26 |
+
environment trains agents to automate this critical workflow.
|
| 27 |
|
| 28 |
**Real-world applications:**
|
| 29 |
- CI/CD pipeline contract testing
|
| 30 |
+
- API gateway request/response validation
|
| 31 |
+
- SDK compatibility checking between API versions
|
| 32 |
+
- OAuth2 and auth schema enforcement
|
| 33 |
+
- Migration safety audits
|
| 34 |
|
| 35 |
## How It Works
|
| 36 |
|
|
|
|
| 38 |
1. An **OpenAPI specification** defining expected types, required fields, and constraints
|
| 39 |
2. A **payload** containing planted violations
|
| 40 |
|
| 41 |
+
The agent inspects both and reports violations **one per step**. The environment
|
| 42 |
+
grades each report against ground-truth violations and provides immediate reward feedback.
|
| 43 |
|
| 44 |
```
|
| 45 |
+
reset() β Agent sees spec + payload with N hidden violations
|
| 46 |
+
step(violation_report) β Correct? +1.0 | Wrong path, right type? +0.3 | False positive? -0.3 | Duplicate? -0.1
|
| 47 |
+
step(HINT) β Receive a location clue at -0.5 cost
|
| 48 |
+
step(DONE) β Episode ends with completeness bonus +0.5 Γ (found/total)
|
| 49 |
```
|
| 50 |
|
| 51 |
+
## Tasks (6 difficulty levels)
|
| 52 |
|
| 53 |
| Task | Difficulty | Violations | Max Steps | What the Agent Must Find |
|
| 54 |
|------|-----------|------------|-----------|--------------------------|
|
| 55 |
+
| `find_type_mismatches` | Easy | 4 | 10 | Type mismatches, missing required fields, invalid enums at the top level. Sampled from a pool of 12 β 495 unique episode combinations |
|
| 56 |
+
| `validate_nested_objects` | Medium | 7 | 15 | Violations inside nested objects and arrays β requires traversing deep structures. 2 variants: Order Service / Event Booking |
|
| 57 |
+
| `detect_breaking_changes` | Hard | 9 | 20 | Breaking changes between two API spec versions β type changes, removed fields, narrowed enums, new required fields |
|
| 58 |
+
| `validate_response_schema` | Expert | 10 | 25 | Subtle format errors in an API response: invalid date formats, pattern mismatches, out-of-range numerics, bad enum values. 2 variants |
|
| 59 |
+
| `validate_cross_field_constraints` | Expert | 7 | 18 | Cross-field arithmetic and date ordering on Invoice API β line totals, subtotal sum, tax calculation, discount rules for trial accounts |
|
| 60 |
+
| `validate_auth_request` | Expert | 6 | 14 | OAuth2 token and API key management violations β invalid grant types, bad scopes, MFA token patterns, IP format, rate limits. 2 variants |
|
| 61 |
|
| 62 |
### Randomised Episode Generation
|
| 63 |
|
| 64 |
+
All tasks support seed-based randomisation, making the environment suitable for
|
| 65 |
+
**training** (varied seeds) as well as **evaluation** (fixed seeds):
|
| 66 |
|
| 67 |
+
- `find_type_mismatches` β samples 4 from a pool of 12 violations (495 unique combinations)
|
| 68 |
+
- `validate_nested_objects` β 2 complete scenario variants (Order Service / Event Booking)
|
| 69 |
+
- `validate_response_schema` β 2 complete scenario variants with different violation sets
|
| 70 |
+
- `validate_auth_request` β 2 complete scenario variants (OAuth2 / API key management)
|
| 71 |
- Pass `seed` in the `reset()` call to select a deterministic episode
|
| 72 |
|
| 73 |
## Action Space
|
|
|
|
| 76 |
|
| 77 |
| Field | Type | Description |
|
| 78 |
|-------|------|-------------|
|
| 79 |
+
| `field_path` | `str` | Dot-notation path to the violated field (e.g. `customer.email`, `items[1].quantity`). Special values: `DONE` to end episode, `HINT` for a location clue |
|
| 80 |
+
| `violation_type` | `str` | One of: `type_mismatch`, `missing_required`, `invalid_enum`, `format_error`, `extra_field`, `breaking_change`, `cross_field_constraint` |
|
| 81 |
| `description` | `str` | Human-readable explanation of the violation |
|
| 82 |
| `suggested_fix` | `str` | Optional suggested correction |
|
| 83 |
|
|
|
|
| 88 |
| Field | Type | Description |
|
| 89 |
|-------|------|-------------|
|
| 90 |
| `task_name` | `str` | Current task identifier |
|
| 91 |
+
| `task_description` | `str` | Natural-language instructions for the agent |
|
| 92 |
| `api_spec` | `dict` | The OpenAPI specification (or version diff for hard task) |
|
| 93 |
+
| `payload` | `dict` | The API payload to validate |
|
| 94 |
| `violations_found` | `list[dict]` | Violations correctly identified so far |
|
| 95 |
+
| `violations_remaining` | `int` | Number of planted violations still undetected |
|
| 96 |
| `feedback` | `str` | Result of the last submitted report |
|
| 97 |
+
| `max_steps` | `int` | Step budget for this episode |
|
| 98 |
| `done` | `bool` | Whether the episode has ended |
|
| 99 |
| `reward` | `float` | Reward for the last action |
|
| 100 |
|
| 101 |
## Reward Function
|
| 102 |
|
| 103 |
+
Partial progress signals β not binary end-of-episode scoring:
|
| 104 |
|
| 105 |
| Event | Reward | Rationale |
|
| 106 |
|-------|--------|-----------|
|
| 107 |
+
| Correct violation (path + type match) | **+1.0** | Primary incentive |
|
| 108 |
+
| Proximity match (right path, wrong type) | **+0.3** | Encourages finding the right field first |
|
| 109 |
+
| HINT requested | **β0.5** | Informative but expensive |
|
| 110 |
+
| Duplicate report | **β0.1** | Light penalty β track what you already found |
|
| 111 |
+
| False positive | **β0.3** | Penalises guessing |
|
| 112 |
+
| DONE signal | **+0.5 Γ (found/total)** | Completeness bonus |
|
| 113 |
|
| 114 |
+
**Final score** = `correct_violations / total_violations` clamped to `(0.01, 0.99)`
|
| 115 |
|
| 116 |
## Setup
|
| 117 |
|
|
|
|
| 152 |
|
| 153 |
```bash
|
| 154 |
openenv validate
|
|
|
|
|
|
|
|
|
|
| 155 |
```
|
| 156 |
|
| 157 |
## Baseline Scores
|
|
|
|
| 163 |
| `detect_breaking_changes` | Qwen2.5-72B-Instruct | ~0.44 | 12β18 |
|
| 164 |
| `validate_response_schema` | Qwen2.5-72B-Instruct | ~0.40 | 15β22 |
|
| 165 |
| `validate_cross_field_constraints` | Qwen2.5-72B-Instruct | ~0.43 | 10β16 |
|
| 166 |
+
| `validate_auth_request` | Qwen2.5-72B-Instruct | ~0.60 | 8β12 |
|
| 167 |
|
| 168 |
*Scores are approximate and may vary with temperature/sampling.*
|
| 169 |
|
|
|
|
| 172 |
```
|
| 173 |
api_contract_validator/
|
| 174 |
βββ openenv.yaml # OpenEnv manifest
|
| 175 |
+
βββ pyproject.toml # Python project metadata
|
| 176 |
+
βββ Dockerfile # Container definition
|
| 177 |
+
βββ inference.py # Baseline inference script
|
| 178 |
+
βββ README.md # This file
|
| 179 |
+
βββ models.py # Pydantic models (Action, Observation, State)
|
| 180 |
+
βββ client.py # WebSocket client (EnvClient subclass)
|
| 181 |
+
βββ __init__.py # Package exports
|
| 182 |
βββ server/
|
| 183 |
βββ __init__.py
|
| 184 |
+
βββ app.py # FastAPI wiring (create_app)
|
| 185 |
+
βββ environment.py # Core environment logic (reset/step/state)
|
| 186 |
+
βββ spec_generator.py # Task scenarios with planted violations
|
| 187 |
+
βββ rewards.py # Reward computation
|
| 188 |
+
βββ requirements.txt # Server dependencies
|
| 189 |
```
|
| 190 |
|
| 191 |
## License
|
server/rewards.py
CHANGED
|
@@ -2,17 +2,19 @@
|
|
| 2 |
Reward computation for the API Contract Validator Environment.
|
| 3 |
|
| 4 |
Provides partial-progress reward signals rather than binary end-of-episode
|
| 5 |
-
scoring
|
| 6 |
-
|
| 7 |
-
- Correct violation found
|
| 8 |
-
- Path-only match (wrong type)
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
-
|
| 12 |
-
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
|
|
|
|
|
|
| 16 |
"""
|
| 17 |
|
| 18 |
from dataclasses import dataclass
|
|
|
|
| 2 |
Reward computation for the API Contract Validator Environment.
|
| 3 |
|
| 4 |
Provides partial-progress reward signals rather than binary end-of-episode
|
| 5 |
+
scoring, creating a richer gradient for RL training:
|
| 6 |
+
|
| 7 |
+
- Correct violation found β +1.0 primary incentive, one reward per unique violation
|
| 8 |
+
- Path-only match (wrong type) β +0.3 proximity signal β agent found the right field,
|
| 9 |
+
now needs to classify it correctly; each path
|
| 10 |
+
earns proximity reward at most once
|
| 11 |
+
- HINT requested β -0.5 informative but expensive; use sparingly
|
| 12 |
+
- Duplicate report β -0.1 light penalty β agent should track findings
|
| 13 |
+
- False positive β -0.3 penalises random guessing
|
| 14 |
+
- DONE signal β +0.5 Γ (found/total) completeness bonus on exit
|
| 15 |
+
|
| 16 |
+
Final episode score = correct / total, clamped to (0.01, 0.99) so it is
|
| 17 |
+
always strictly between 0 and 1 as required by the OpenEnv eval pipeline.
|
| 18 |
"""
|
| 19 |
|
| 20 |
from dataclasses import dataclass
|
server/spec_generator.py
CHANGED
|
@@ -2,15 +2,22 @@
|
|
| 2 |
Spec generator for the API Contract Validator Environment.
|
| 3 |
|
| 4 |
Generates OpenAPI specifications, payloads with planted violations,
|
| 5 |
-
and ground-truth violation records for
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
|
| 7 |
Each generator accepts an optional *seed* for deterministic randomisation:
|
| 8 |
-
|
| 9 |
-
|
| 10 |
|
| 11 |
This makes the environment suitable for both evaluation (fixed seed) and
|
| 12 |
-
training (varied seeds)
|
| 13 |
-
|
| 14 |
"""
|
| 15 |
|
| 16 |
import random
|
|
|
|
| 2 |
Spec generator for the API Contract Validator Environment.
|
| 3 |
|
| 4 |
Generates OpenAPI specifications, payloads with planted violations,
|
| 5 |
+
and ground-truth violation records for six difficulty levels:
|
| 6 |
+
|
| 7 |
+
find_type_mismatches Easy β 4 violations from pool of 12 (495 combos)
|
| 8 |
+
validate_nested_objects Medium β 7 violations, 2 scenario variants
|
| 9 |
+
detect_breaking_changes Hard β 9 breaking changes between v1 and v2
|
| 10 |
+
validate_response_schema Expert β 10 format/constraint violations, 2 variants
|
| 11 |
+
validate_cross_field_constraints Expert β 7 arithmetic + date cross-field errors
|
| 12 |
+
validate_auth_request Expert β 6 auth/security violations, 2 variants
|
| 13 |
|
| 14 |
Each generator accepts an optional *seed* for deterministic randomisation:
|
| 15 |
+
seed=None β fixed canonical scenario (backward-compatible defaults)
|
| 16 |
+
seed=int β reproducible randomised variant (use for RL training)
|
| 17 |
|
| 18 |
This makes the environment suitable for both evaluation (fixed seed) and
|
| 19 |
+
training (varied seeds) β the key distinction between a one-shot evaluator
|
| 20 |
+
and a genuine RL training environment.
|
| 21 |
"""
|
| 22 |
|
| 23 |
import random
|