129 lines
3.2 KiB
Markdown
129 lines
3.2 KiB
Markdown
# VAPORA Validation Schemas
|
|
|
|
Nickel schemas for runtime validation of MCP tools and agent tasks.
|
|
|
|
## Directory Structure
|
|
|
|
```
|
|
schemas/
|
|
├── tools/ # MCP tool parameter validation
|
|
│ ├── kanban_create_task.ncl
|
|
│ ├── kanban_update_task.ncl
|
|
│ ├── assign_task_to_agent.ncl
|
|
│ ├── get_project_summary.ncl
|
|
│ └── get_agent_capabilities.ncl
|
|
│
|
|
└── agents/ # Agent task assignment validation
|
|
└── task_assignment.ncl
|
|
```
|
|
|
|
## Schema Format
|
|
|
|
Nickel schemas define:
|
|
|
|
- **Field types** (String, Number, Bool, Array, Object)
|
|
- **Required/optional fields** (via `default` values)
|
|
- **Validation contracts** (NonEmpty, Email, UUID, Range, Pattern, etc.)
|
|
- **Documentation** (via `doc` annotations)
|
|
|
|
### Example
|
|
|
|
```nickel
|
|
{
|
|
tool_name = "example_tool",
|
|
|
|
parameters = {
|
|
# Required field with contracts
|
|
user_id
|
|
| String
|
|
| doc "User UUID"
|
|
| std.string.NonEmpty
|
|
| std.string.match "^[0-9a-f]{8}-[0-9a-f]{4}-...$",
|
|
|
|
# Optional field with default
|
|
priority
|
|
| Number
|
|
| doc "Priority score (0-100)"
|
|
| std.number.between 0 100
|
|
| default = 50,
|
|
},
|
|
}
|
|
```
|
|
|
|
## Supported Contracts
|
|
|
|
| Contract | Description | Example |
|
|
|----------|-------------|---------|
|
|
| `std.string.NonEmpty` | String cannot be empty | Required text fields |
|
|
| `std.string.length.min N` | Minimum length | `min 3` for titles |
|
|
| `std.string.length.max N` | Maximum length | `max 200` for titles |
|
|
| `std.string.match PATTERN` | Regex validation | UUID format |
|
|
| `std.number.between A B` | Numeric range | `between 0 100` |
|
|
| `std.number.greater_than N` | Minimum value (exclusive) | `> -1` |
|
|
| `std.number.less_than N` | Maximum value (exclusive) | `< 1000` |
|
|
| `std.string.Email` | Email format | user@example.com |
|
|
| `std.string.Url` | URL format | https://... |
|
|
| `std.string.Uuid` | UUID format | xxxxxxxx-xxxx-... |
|
|
| `std.enum.TaggedUnion` | Enum validation | `[| 'low, 'high |]` |
|
|
|
|
## Usage
|
|
|
|
Schemas are loaded by `ValidationPipeline` at runtime:
|
|
|
|
```rust
|
|
use vapora_shared::validation::{SchemaRegistry, ValidationPipeline};
|
|
|
|
let registry = Arc::new(SchemaRegistry::new(PathBuf::from("schemas")));
|
|
let pipeline = ValidationPipeline::new(registry);
|
|
|
|
// Validate MCP tool input
|
|
let result = pipeline.validate("tools/kanban_create_task", &input).await?;
|
|
|
|
if !result.valid {
|
|
return (StatusCode::BAD_REQUEST, Json(result.errors));
|
|
}
|
|
```
|
|
|
|
## Testing Schemas
|
|
|
|
Validate schema syntax:
|
|
|
|
```bash
|
|
nickel typecheck schemas/tools/kanban_create_task.ncl
|
|
```
|
|
|
|
Export schema as JSON:
|
|
|
|
```bash
|
|
nickel export schemas/tools/kanban_create_task.ncl
|
|
```
|
|
|
|
Query specific field:
|
|
|
|
```bash
|
|
nickel query --field parameters.title schemas/tools/kanban_create_task.ncl
|
|
```
|
|
|
|
## Adding New Schemas
|
|
|
|
1. Create `.ncl` file in appropriate directory
|
|
2. Define `tool_name` or `schema_name`
|
|
3. Define `parameters` or `fields` with types and contracts
|
|
4. Add `doc` annotations for documentation
|
|
5. Test with `nickel typecheck`
|
|
6. Restart services to reload schemas (or use hot-reload)
|
|
|
|
## Hot Reload
|
|
|
|
Invalidate cached schema without restart:
|
|
|
|
```rust
|
|
registry.invalidate("tools/kanban_create_task").await;
|
|
```
|
|
|
|
Invalidate all schemas:
|
|
|
|
```rust
|
|
registry.invalidate_all().await;
|
|
```
|