Vapora/schemas/README.md
2026-01-14 21:12:49 +00:00

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;
```