agent-validator


Nameagent-validator JSON
Version 1.0.0 PyPI version JSON
download
home_pageNone
SummaryA library for validating agent outputs against schemas
upload_time2025-08-31 02:40:18
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseMIT
keywords validation schema agent ai
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # πŸš€ Agent Validator

> **A simple drop-in tool to validate LLM/agent outputs against schemas with automatic retries, logging, and optional cloud monitoring.**

[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

---

## ✨ Features

- πŸ” **Schema Validation**: Validate JSON outputs against Python dict schemas
- πŸ”„ **Automatic Retries**: Retry failed validations with exponential backoff
- πŸ”§ **Type Coercion**: Optional safe type coercion (e.g., `"42"` β†’ `42`)
- πŸ“ **Local Logging**: JSON Lines logging with automatic redaction
- ☁️ **Cloud Monitoring**: Optional cloud logging with secure authentication
- πŸ› οΈ **CLI Tools**: Command-line interface for testing and log management
- πŸ›‘οΈ **Size Limits**: Configurable limits to prevent abuse

---

## πŸš€ Quick Start

### πŸ“¦ Installation

```bash
pip install agent-validator
```

### πŸ’» Basic Usage

```python
from agent_validator import validate, Schema, ValidationMode

# Define your schema
schema = Schema({
    "name": str,
    "age": int,
    "email": str,
    "tags": [str]
})

# Validate agent output
try:
    result = validate(
        agent_output,  # Your agent's output (string or dict)
        schema,
        retry_fn=call_agent,  # Function to retry if validation fails
        retries=2,
        mode=ValidationMode.COERCE,  # Allow type coercion
        context={"correlation_id": "abc123"}  # Optional correlation ID for tracking
    )
    print("βœ… Validation successful!")
    print(result)
except ValidationError as e:
    print(f"❌ Validation failed: {e}")
    print(f"Correlation ID: {e.correlation_id}")  # For debugging
```

### πŸ–₯️ CLI Usage

```bash
# Test validation with files
agent-validator test schema.json input.json --mode COERCE

# View recent logs
agent-validator logs -n 20

# View cloud logs
agent-validator cloud-logs -n 20

# Open web dashboard (secure proxy)
agent-validator dashboard

# Generate correlation ID
agent-validator id

# Configure cloud logging
agent-validator config --set-license-key YOUR_LICENSE_KEY
agent-validator config --set-log-to-cloud true
```

---

## πŸ“‹ Schema Definition

Schemas are defined using Python dictionaries with type annotations:

```python
schema = Schema({
    "name": str,           # Required string field
    "age": int,            # Required integer field
    "email": str,          # Required string field
    "is_active": bool,     # Required boolean field
    "score": float,        # Required float field
    "tags": [str],         # List of strings
    "metadata": None,      # Optional field (can be omitted)
    "address": {           # Nested object
        "street": str,
        "city": str,
        "zip": str
    },
    "scores": [int]        # List of integers
})
```

### 🎯 Supported Types

- **Primitives**: `str`, `int`, `float`, `bool`
- **Lists**: `[type]` for lists of that type
- **Objects**: `dict` for nested objects
- **Optional**: `None` for optional fields

### πŸ“„ Schema File Formats

When using the CLI with JSON files, you can use either format:

#### **Direct Schema Format** (Recommended)

```json
{
  "name": "string",
  "age": "integer",
  "email": "string",
  "is_active": "boolean",
  "tags": ["string"],
  "metadata": {
    "source": "string",
    "version": "string"
  }
}
```

#### **Wrapped Schema Format**

```json
{
  "schema": {
    "name": "string",
    "age": "integer",
    "email": "string",
    "is_active": "boolean"
  }
}
```

**Supported string types**: `string`, `integer`, `int`, `float`, `number`, `boolean`, `bool`, `list`, `array`, `dict`, `object`

---

## πŸ”„ Validation Modes

### 🚫 Strict Mode (Default)

No type coercion allowed. Input must match schema exactly.

```python
schema = Schema({"age": int})
data = {"age": "30"}  # String instead of int

# This will fail
validate(data, schema, mode=ValidationMode.STRICT)
```

### πŸ”§ Coerce Mode

Safe type coercion is performed:

```python
schema = Schema({"age": int, "is_active": bool})
data = {"age": "30", "is_active": "true"}

# This will succeed and coerce types
result = validate(data, schema, mode=ValidationMode.COERCE)
# result = {"age": 30, "is_active": True}
```

#### πŸ”„ Coercion Rules

| Input Type | Target Type | Coercion |
| ---------- | ----------- | -------- |
| `"42"`     | `int`       | `42`     |
| `"42.5"`   | `float`     | `42.5`   |
| `"true"`   | `bool`      | `True`   |
| `"false"`  | `bool`      | `False`  |
| `"1"`      | `bool`      | `True`   |
| `"0"`      | `bool`      | `False`  |
| `"yes"`    | `bool`      | `True`   |
| `"no"`     | `bool`      | `False`  |
| `"on"`     | `bool`      | `True`   |
| `"off"`    | `bool`      | `False`  |

---

## πŸ”„ Retry Logic

When validation fails and a `retry_fn` is provided, the system will automatically retry:

```python
def call_agent(prompt: str, context: dict) -> str:
    """Your agent function that returns JSON string."""
    # Call your LLM/agent here
    return json.dumps({"name": "John", "age": 30})

result = validate(
    malformed_output,
    schema,
    retry_fn=call_agent,
    retries=2,  # Retry up to 2 times
    timeout_s=20  # 20 second timeout per attempt
)
```

### ⚑ Retry Behavior

- **Exponential Backoff**: Delays increase with each retry (0.5s, 1s, 2s)
- **Jitter**: Random variation to prevent thundering herd
- **Timeout**: Per-attempt timeout to prevent hanging
- **Context Preservation**: Original context is passed to retry function

---

## πŸ“ Logging

### πŸ’Ύ Local Logging

All validation attempts are logged to `~/.agent_validator/logs/YYYY-MM-DD.jsonl`:

```json
{
  "ts": "2023-12-01T10:30:00Z",
  "correlation_id": "abc123-def456",
  "valid": true,
  "errors": [],
  "attempts": 1,
  "duration_ms": 150,
  "mode": "coerce",
  "limits": {
    "max_output_bytes": 131072,
    "max_str_len": 8192,
    "max_list_len": 2048,
    "max_dict_keys": 512
  },
  "context": { "correlation_id": "abc123" },
  "output_sample": "{\"name\": \"John\", \"age\": 30}"
}
```

**Correlation IDs** are automatically generated for each validation attempt and help you:

- πŸ” **Track specific validations** across logs and error messages
- πŸ› **Debug issues** by correlating errors with specific validation attempts
- πŸ“Š **Monitor performance** by tracking validation duration and retry attempts
- πŸ”— **Link related operations** when using retry functions

When viewing logs with `agent-validator logs`, logs are displayed in a clear table format:

```bash
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Timestamp                           β”‚ Status β”‚ Correlation β”‚ Mode    β”‚ Attempts β”‚ Duration    β”‚ Errors  β”‚ Size    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 2025-08-30 18:40:00                 β”‚      βœ— β”‚        none β”‚  strict β”‚        1 β”‚         0ms β”‚       2 β”‚    45B  β”‚
β”‚ 2025-08-30 18:40:00                 β”‚      βœ“ β”‚        none β”‚  coerce β”‚        1 β”‚         0ms β”‚       0 β”‚    45B  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

Correlation IDs are truncated for readability and show `[none]` when not set.

### ☁️ Cloud Logging

Enable cloud logging for monitoring and recovery:

```python
from agent_validator import Config

config = Config(
    log_to_cloud=True,
    license_key="your-license-key",
    cloud_endpoint="https://api.agentvalidator.dev"
)

result = validate(
    agent_output,
    schema,
    log_to_cloud=True,
    config=config
)
```

### πŸ” Webhook Secret Management

For enhanced security, generate a webhook secret for HMAC signature validation:

```bash
# Generate a new webhook secret
agent-validator webhook --generate

# Check webhook status
agent-validator webhook --status

# Show current webhook secret
agent-validator webhook --show

# Revoke webhook secret
agent-validator webhook --revoke
```

**Security Features:**

- βœ… **One-time display**: Webhook secrets are only shown once when generated
- βœ… **Secure storage**: Secrets are stored encrypted in the database
- βœ… **User isolation**: Each license key has its own webhook secret
- βœ… **Revocation**: Users can revoke and regenerate secrets as needed

#### Using HMAC Signatures

Once you have a webhook secret, requests can include an HMAC signature:

```python
import hmac
import hashlib

# Create signature
signature = hmac.new(
    webhook_secret.encode(),
    payload.encode(),
    hashlib.sha256
).hexdigest()

# Include in request headers
headers = {
    "license-key": "your-license-key",
    "x-signature": signature
}
```

#### Security Notes

- **One-time display**: Webhook secrets are only shown once when generated
- **Secure storage**: Secrets are stored encrypted in the database
- **User isolation**: Each license key has its own webhook secret
- **Revocation**: Users can revoke and regenerate secrets as needed

### 🌐 Web Dashboard

Access your validation logs through a secure web dashboard:

```bash
# Configure your license key
agent-validator config --set-license-key your-license-key

# Open dashboard with secure local proxy
agent-validator dashboard
```

This opens a local proxy server at `http://localhost:8080` that securely forwards requests to the cloud API with proper authentication headers. The dashboard shows:

- Recent validation attempts
- Success/failure rates
- Performance metrics
- Error details
- Correlation IDs for debugging

**Security Features:**

- βœ… No credentials in URLs
- βœ… Secure header authentication
- βœ… User data isolation
- βœ… Local proxy prevents credential exposure

---

## βš™οΈ Configuration

### 🌍 Environment Variables

```bash
export AGENT_VALIDATOR_LICENSE_KEY="your-license-key"
export AGENT_VALIDATOR_WEBHOOK_SECRET="your-webhook-secret"
export AGENT_VALIDATOR_LOG_TO_CLOUD="1"
export AGENT_VALIDATOR_ENDPOINT="https://api.agentvalidator.dev"
export AGENT_VALIDATOR_MAX_OUTPUT_BYTES="131072"
export AGENT_VALIDATOR_MAX_STR_LEN="8192"
export AGENT_VALIDATOR_MAX_LIST_LEN="2048"
export AGENT_VALIDATOR_MAX_DICT_KEYS="512"
export AGENT_VALIDATOR_TIMEOUT_S="20"
export AGENT_VALIDATOR_RETRIES="2"
```

### πŸ“„ Configuration File

Configuration is stored in `~/.agent_validator/config.toml`:

```toml
max_output_bytes = 131072
max_str_len = 8192
max_list_len = 2048
max_dict_keys = 512
log_to_cloud = false
cloud_endpoint = "https://api.agentvalidator.dev"
timeout_s = 20
retries = 2
license_key = "your-license-key"
webhook_secret = "your-webhook-secret"
```

### πŸ”„ Configuration Precedence

Configuration values are loaded in the following order (highest to lowest priority):

1. **CLI Arguments** (highest priority)

   ```bash
   agent-validator test schema.json input.json --mode COERCE --timeout-s 30
   ```

2. **Environment Variables**

   ```bash
   export AGENT_VALIDATOR_MODE="COERCE"
   export AGENT_VALIDATOR_TIMEOUT_S="30"
   ```

3. **Configuration File** (lowest priority)
   ```toml
   # ~/.agent_validator/config.toml
   mode = "STRICT"
   timeout_s = 20
   ```

**Example**: If you have `timeout_s = 20` in your config file, but set `export AGENT_VALIDATOR_TIMEOUT_S="30"`, the environment variable (30 seconds) will take precedence.

**Note**: CLI arguments always override environment variables and config file settings.

---

## πŸ”’ Security & Privacy

### 🚫 Redaction

Sensitive data is automatically redacted before logging:

- **API Keys**: `sk-1234567890abcdef` β†’ `[REDACTED]`
- **JWT Tokens**: `Bearer eyJ...` β†’ `[REDACTED]`
- **Emails**: `john@example.com` β†’ `j***n@example.com`
- **Phone Numbers**: `+1-555-123-4567` β†’ `***-***-4567`
- **SSNs**: `123-45-6789` β†’ `***-**-6789`
- **Credit Cards**: `1234-5678-9012-3456` β†’ `************3456`
- **Passwords**: `secret123` β†’ `[REDACTED]`

### πŸ”§ Custom Redaction Patterns

```python
from agent_validator.redact import add_redaction_pattern

# Add custom pattern
add_redaction_pattern("custom_token", r"custom-[a-zA-Z0-9]{20,}")
```

---

## πŸ“ Size Limits

Default limits to prevent abuse:

| Limit              | Default | Description              |
| ------------------ | ------- | ------------------------ |
| `max_output_bytes` | 131,072 | Total JSON size in bytes |
| `max_str_len`      | 8,192   | Maximum string length    |
| `max_list_len`     | 2,048   | Maximum list length      |
| `max_dict_keys`    | 512     | Maximum dictionary keys  |

---

## ⚠️ Error Handling

### 🚨 ValidationError

Raised when validation fails after all retries:

```python
from agent_validator import ValidationError

try:
    result = validate(data, schema)
except ValidationError as e:
    print(f"Path: {e.path}")
    print(f"Reason: {e.reason}")
    print(f"Attempt: {e.attempt}")
    print(f"Correlation ID: {e.correlation_id}")
```

### πŸ“‹ SchemaError

Raised when schema definition is invalid:

```python
from agent_validator import SchemaError

try:
    schema = Schema({"name": bytes})  # Unsupported type
except SchemaError as e:
    print(f"Schema error: {e}")
```

### ☁️ CloudLogError

Raised when cloud logging fails (non-fatal):

```python
from agent_validator import CloudLogError

try:
    result = validate(data, schema, log_to_cloud=True)
except CloudLogError as e:
    print(f"Cloud logging failed: {e}")
    # Validation still succeeds
```

---

## πŸ’‘ Examples

### 🎯 Basic Example

```python
from agent_validator import validate, Schema, ValidationMode

def call_agent(prompt: str, context: dict) -> str:
    """Mock agent function."""
    import random
    if random.random() < 0.3:
        return "This is not valid JSON"
    return '{"name": "John", "age": 30, "email": "john@example.com"}'

schema = Schema({
    "name": str,
    "age": int,
    "email": str
})

result = validate(
    call_agent("", {}),
    schema,
    retry_fn=call_agent,
    retries=2,
    mode=ValidationMode.COERCE
)
```

### ☁️ With Cloud Logging

```python
from agent_validator import validate, Schema, Config

config = Config(
    log_to_cloud=True,
    license_key=os.getenv("AGENT_VALIDATOR_LICENSE_KEY")
)

schema = Schema({
    "user": {
        "name": str,
        "age": int,
        "preferences": {
            "theme": str,
            "notifications": bool
        }
    }
})

result = validate(
    agent_output,
    schema,
    log_to_cloud=True,
    config=config,
    context={"user_id": "123", "environment": "production"}
)
```

---

## πŸ–₯️ CLI Reference

### πŸ› οΈ Commands

```bash
# Test validation
agent-validator test <schema.json> <input.json> [--mode STRICT|COERCE]

# View local logs
agent-validator logs [-n <number>] [--clear]

# View cloud logs
agent-validator cloud-logs [-n <number>]

# Open web dashboard
agent-validator dashboard [--port <port>] [--url] [--open]

# Generate correlation ID
agent-validator id

# Manage configuration
agent-validator config [--show] [--show-secrets] [--set-license-key <key>] [--set-endpoint <url>] [--set-webhook-secret <secret>] [--set-log-to-cloud <true|false>]

# Manage webhook secrets
agent-validator webhook [--generate] [--status] [--show] [--revoke] [--force]
```

### πŸ“Š Exit Codes

- `0`: Success
- `1`: General error
- `2`: Validation failed

### πŸ”’ Security Notes

- **Configuration Display**: By default, sensitive values (license key, webhook secret) are masked as `***` when showing configuration
- **Show Secrets**: Use `--show-secrets` flag to display actual values for debugging/verification
- **Example**:

  ```bash
  # Default (masked)
  agent-validator config --show
  # Output: license_key: ***

  # With secrets visible
  agent-validator config --show --show-secrets
  # Output: license_key: my-actual-key
  ```

---

## πŸ› οΈ Development

### πŸ“¦ Installation

```bash
git clone https://github.com/agent-validator/agent-validator.git
cd agent-validator
pip install -e ".[dev]"
```

**Note**: The `[dev]` extras include build tools (`build`, `twine`) needed for creating releases.

### πŸ§ͺ Running Tests

```bash
# Run all tests
python -m pytest tests/ -v

# Run with coverage
pytest --cov=agent_validator

# Run property-based tests
python -m pytest tests/property/ -v

# Run type checking
mypy agent_validator cli

# Run linting
ruff check .
black --check .
isort --check-only .

# Run smoke tests (isolated environment)
python smoke_tests/smoke_tests.py
```

### πŸ”§ Pre-commit Hooks

```bash
pre-commit install
pre-commit run --all-files
```

### πŸš€ Smoke Tests

Smoke tests verify the complete user experience in an isolated environment:

```bash
# Run comprehensive smoke tests
python smoke_tests/smoke_tests.py

# With backend URL for cloud testing
python smoke_tests/smoke_tests.py --backend-url http://localhost:9090
```

**What gets tested:**

- βœ… Package installation in isolated environment
- βœ… CLI command availability and functionality
- βœ… Library imports and basic operations
- βœ… Configuration management
- βœ… Log generation and retrieval
- βœ… Schema validation (strict and coerce modes)
- βœ… Error handling and edge cases

**Benefits:**

- πŸ›‘οΈ No pollution to your development environment
- πŸ”„ Clean testing environment every time
- πŸ§ͺ Tests real installation and usage scenarios
- πŸš€ Perfect for CI/CD integration

### πŸ“¦ Releasing New Versions

The project uses automated CI/CD for releases. When you push a version tag, the CI automatically builds and publishes to PyPI.

#### 1. **Update Version**

Update the version in `agent_validator/version.py`:

```python
__version__ = "1.0.1"  # Increment version number
```

#### 2. **Update CHANGELOG**

Add a new entry to `CHANGELOG.md` following the [Keep a Changelog](https://keepachangelog.com/) format:

```markdown
## [1.0.1] - 2025-01-01

### Added

- New feature description

### Changed

- Breaking change description

### Fixed

- Bug fix description
```

#### 3. **Run Pre-release Checks**

```bash
# Install build dependencies (if not already installed)
pip install -e ".[dev]"

# Run all tests
python -m pytest tests/ -v

# Run smoke tests
python smoke_tests/smoke_tests.py

# Check code quality (matches CI)
ruff check .
mypy agent_validator cli

# Verify package builds
python -m build
```

#### 4. **Commit and Push Changes**

```bash
# Commit version and changelog updates
git add agent_validator/version.py CHANGELOG.md
git commit -m "Release v1.0.1"
git push origin master
```

#### 5. **Create and Push Git Tag**

```bash
# Create version tag
git tag v1.0.1

# Push tag to trigger automated release
git push origin v1.0.1
```

**That's it!** πŸš€ The CI/CD pipeline will automatically:

- βœ… Run tests across Python 3.9, 3.10, 3.11, and 3.12
- βœ… Run linting and type checking
- βœ… Build the package
- βœ… Publish to PyPI (if tag starts with `v`)

#### 6. **Verify Release**

After the CI completes (usually 2-3 minutes):

```bash
# Test installation from PyPI
pip install agent-validator==1.0.1 --force-reinstall

# Verify functionality
agent-validator --help
python -c "import agent_validator; print(agent_validator.__version__)"
```

#### 7. **Create GitHub Release**

- Go to [GitHub Releases](https://github.com/agent-validator/agent-validator/releases)
- Click "Create a new release"
- Select the tag you just pushed
- Copy the changelog content
- Publish the release

**Release Checklist:**

- [ ] Version updated in `agent_validator/version.py`
- [ ] CHANGELOG.md updated
- [ ] All tests pass locally
- [ ] Smoke tests pass
- [ ] Code quality checks pass
- [ ] Package builds successfully
- [ ] Changes committed and pushed to master
- [ ] Git tag created and pushed
- [ ] CI/CD pipeline completes successfully
- [ ] Installation from PyPI verified
- [ ] GitHub release created with changelog

**CI/CD Pipeline Details:**

The `.github/workflows/ci.yml` workflow automatically:

- **Tests**: Runs on Python 3.9, 3.10, 3.11, 3.12
- **Quality**: Runs `ruff check` and `mypy`
- **Coverage**: Generates and uploads coverage reports
- **Publishing**: Automatically publishes to PyPI when a tag starting with `v` is pushed
- **Security**: Uses GitHub secrets for PyPI authentication

---

## 🀝 Contributing

1. 🍴 Fork the repository
2. 🌿 Create a feature branch
3. ✏️ Make your changes
4. πŸ§ͺ Add tests
5. βœ… Run the test suite
6. πŸ“€ Submit a pull request

---

## πŸ“„ License

MIT License - see [LICENSE](LICENSE) file for details.

---

## ❓ FAQ

**Q: Can I use this with any LLM/agent?**  
A: Yes! The library is framework-agnostic. Just pass your agent's output to the `validate` function.

**Q: What happens if my agent returns malformed JSON?**  
A: In strict mode, it will fail immediately. In coerce mode, it will try to parse as JSON first, then fall back to treating it as a plain string.

**Q: How do I handle sensitive data in logs?**  
A: Sensitive data is automatically redacted before logging. You can also add custom redaction patterns.

**Q: Can I use this in production?**  
A: Yes! The library is designed for production use with proper error handling, logging, and monitoring capabilities.

**Q: How do I access the web dashboard securely?**  
A: Use `agent-validator dashboard` which creates a secure local proxy server. Never put your license key in URLs - the CLI handles authentication securely via headers.

**Q: How do I verify my license key is set correctly?**  
A: Use `agent-validator config --show --show-secrets` to display the actual license key value. By default, sensitive values are masked as `***` for security.

**Q: What's the performance impact?**  
A: Minimal. Validation is fast, and logging is asynchronous. The main overhead comes from retry attempts when validation fails.

**Q: Can I use my own schema format?**  
A: Currently only Python dict schemas are supported. JSONSchema support is planned for v0.1.

---

## πŸ—ΊοΈ Roadmap

- [ ] JSONSchema import/export
- [ ] Pydantic model support
- [ ] Custom validators per field
- [ ] Schema composition and inheritance
- [x] Web dashboard for monitoring
- [ ] Alerting and notifications
- [ ] Schema versioning
- [ ] Performance metrics

---

<div align="center">

**Made with ❀️ by the Agent Validator community**

[![GitHub stars](https://img.shields.io/github/stars/agent-validator/agent-validator?style=social)](https://github.com/agent-validator/agent-validator)
[![GitHub forks](https://img.shields.io/github/forks/agent-validator/agent-validator?style=social)](https://github.com/agent-validator/agent-validator)

</div>

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "agent-validator",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "validation, schema, agent, ai",
    "author": null,
    "author_email": "Neil Okikiolu <neil@agentvalidator.dev>",
    "download_url": "https://files.pythonhosted.org/packages/ee/03/ea266c20d611b7994ddb82ebe3fe9fcb8dec1d5c3527ddd40354c11c2789/agent_validator-1.0.0.tar.gz",
    "platform": null,
    "description": "# \ud83d\ude80 Agent Validator\n\n> **A simple drop-in tool to validate LLM/agent outputs against schemas with automatic retries, logging, and optional cloud monitoring.**\n\n[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n\n---\n\n## \u2728 Features\n\n- \ud83d\udd0d **Schema Validation**: Validate JSON outputs against Python dict schemas\n- \ud83d\udd04 **Automatic Retries**: Retry failed validations with exponential backoff\n- \ud83d\udd27 **Type Coercion**: Optional safe type coercion (e.g., `\"42\"` \u2192 `42`)\n- \ud83d\udcdd **Local Logging**: JSON Lines logging with automatic redaction\n- \u2601\ufe0f **Cloud Monitoring**: Optional cloud logging with secure authentication\n- \ud83d\udee0\ufe0f **CLI Tools**: Command-line interface for testing and log management\n- \ud83d\udee1\ufe0f **Size Limits**: Configurable limits to prevent abuse\n\n---\n\n## \ud83d\ude80 Quick Start\n\n### \ud83d\udce6 Installation\n\n```bash\npip install agent-validator\n```\n\n### \ud83d\udcbb Basic Usage\n\n```python\nfrom agent_validator import validate, Schema, ValidationMode\n\n# Define your schema\nschema = Schema({\n    \"name\": str,\n    \"age\": int,\n    \"email\": str,\n    \"tags\": [str]\n})\n\n# Validate agent output\ntry:\n    result = validate(\n        agent_output,  # Your agent's output (string or dict)\n        schema,\n        retry_fn=call_agent,  # Function to retry if validation fails\n        retries=2,\n        mode=ValidationMode.COERCE,  # Allow type coercion\n        context={\"correlation_id\": \"abc123\"}  # Optional correlation ID for tracking\n    )\n    print(\"\u2705 Validation successful!\")\n    print(result)\nexcept ValidationError as e:\n    print(f\"\u274c Validation failed: {e}\")\n    print(f\"Correlation ID: {e.correlation_id}\")  # For debugging\n```\n\n### \ud83d\udda5\ufe0f CLI Usage\n\n```bash\n# Test validation with files\nagent-validator test schema.json input.json --mode COERCE\n\n# View recent logs\nagent-validator logs -n 20\n\n# View cloud logs\nagent-validator cloud-logs -n 20\n\n# Open web dashboard (secure proxy)\nagent-validator dashboard\n\n# Generate correlation ID\nagent-validator id\n\n# Configure cloud logging\nagent-validator config --set-license-key YOUR_LICENSE_KEY\nagent-validator config --set-log-to-cloud true\n```\n\n---\n\n## \ud83d\udccb Schema Definition\n\nSchemas are defined using Python dictionaries with type annotations:\n\n```python\nschema = Schema({\n    \"name\": str,           # Required string field\n    \"age\": int,            # Required integer field\n    \"email\": str,          # Required string field\n    \"is_active\": bool,     # Required boolean field\n    \"score\": float,        # Required float field\n    \"tags\": [str],         # List of strings\n    \"metadata\": None,      # Optional field (can be omitted)\n    \"address\": {           # Nested object\n        \"street\": str,\n        \"city\": str,\n        \"zip\": str\n    },\n    \"scores\": [int]        # List of integers\n})\n```\n\n### \ud83c\udfaf Supported Types\n\n- **Primitives**: `str`, `int`, `float`, `bool`\n- **Lists**: `[type]` for lists of that type\n- **Objects**: `dict` for nested objects\n- **Optional**: `None` for optional fields\n\n### \ud83d\udcc4 Schema File Formats\n\nWhen using the CLI with JSON files, you can use either format:\n\n#### **Direct Schema Format** (Recommended)\n\n```json\n{\n  \"name\": \"string\",\n  \"age\": \"integer\",\n  \"email\": \"string\",\n  \"is_active\": \"boolean\",\n  \"tags\": [\"string\"],\n  \"metadata\": {\n    \"source\": \"string\",\n    \"version\": \"string\"\n  }\n}\n```\n\n#### **Wrapped Schema Format**\n\n```json\n{\n  \"schema\": {\n    \"name\": \"string\",\n    \"age\": \"integer\",\n    \"email\": \"string\",\n    \"is_active\": \"boolean\"\n  }\n}\n```\n\n**Supported string types**: `string`, `integer`, `int`, `float`, `number`, `boolean`, `bool`, `list`, `array`, `dict`, `object`\n\n---\n\n## \ud83d\udd04 Validation Modes\n\n### \ud83d\udeab Strict Mode (Default)\n\nNo type coercion allowed. Input must match schema exactly.\n\n```python\nschema = Schema({\"age\": int})\ndata = {\"age\": \"30\"}  # String instead of int\n\n# This will fail\nvalidate(data, schema, mode=ValidationMode.STRICT)\n```\n\n### \ud83d\udd27 Coerce Mode\n\nSafe type coercion is performed:\n\n```python\nschema = Schema({\"age\": int, \"is_active\": bool})\ndata = {\"age\": \"30\", \"is_active\": \"true\"}\n\n# This will succeed and coerce types\nresult = validate(data, schema, mode=ValidationMode.COERCE)\n# result = {\"age\": 30, \"is_active\": True}\n```\n\n#### \ud83d\udd04 Coercion Rules\n\n| Input Type | Target Type | Coercion |\n| ---------- | ----------- | -------- |\n| `\"42\"`     | `int`       | `42`     |\n| `\"42.5\"`   | `float`     | `42.5`   |\n| `\"true\"`   | `bool`      | `True`   |\n| `\"false\"`  | `bool`      | `False`  |\n| `\"1\"`      | `bool`      | `True`   |\n| `\"0\"`      | `bool`      | `False`  |\n| `\"yes\"`    | `bool`      | `True`   |\n| `\"no\"`     | `bool`      | `False`  |\n| `\"on\"`     | `bool`      | `True`   |\n| `\"off\"`    | `bool`      | `False`  |\n\n---\n\n## \ud83d\udd04 Retry Logic\n\nWhen validation fails and a `retry_fn` is provided, the system will automatically retry:\n\n```python\ndef call_agent(prompt: str, context: dict) -> str:\n    \"\"\"Your agent function that returns JSON string.\"\"\"\n    # Call your LLM/agent here\n    return json.dumps({\"name\": \"John\", \"age\": 30})\n\nresult = validate(\n    malformed_output,\n    schema,\n    retry_fn=call_agent,\n    retries=2,  # Retry up to 2 times\n    timeout_s=20  # 20 second timeout per attempt\n)\n```\n\n### \u26a1 Retry Behavior\n\n- **Exponential Backoff**: Delays increase with each retry (0.5s, 1s, 2s)\n- **Jitter**: Random variation to prevent thundering herd\n- **Timeout**: Per-attempt timeout to prevent hanging\n- **Context Preservation**: Original context is passed to retry function\n\n---\n\n## \ud83d\udcdd Logging\n\n### \ud83d\udcbe Local Logging\n\nAll validation attempts are logged to `~/.agent_validator/logs/YYYY-MM-DD.jsonl`:\n\n```json\n{\n  \"ts\": \"2023-12-01T10:30:00Z\",\n  \"correlation_id\": \"abc123-def456\",\n  \"valid\": true,\n  \"errors\": [],\n  \"attempts\": 1,\n  \"duration_ms\": 150,\n  \"mode\": \"coerce\",\n  \"limits\": {\n    \"max_output_bytes\": 131072,\n    \"max_str_len\": 8192,\n    \"max_list_len\": 2048,\n    \"max_dict_keys\": 512\n  },\n  \"context\": { \"correlation_id\": \"abc123\" },\n  \"output_sample\": \"{\\\"name\\\": \\\"John\\\", \\\"age\\\": 30}\"\n}\n```\n\n**Correlation IDs** are automatically generated for each validation attempt and help you:\n\n- \ud83d\udd0d **Track specific validations** across logs and error messages\n- \ud83d\udc1b **Debug issues** by correlating errors with specific validation attempts\n- \ud83d\udcca **Monitor performance** by tracking validation duration and retry attempts\n- \ud83d\udd17 **Link related operations** when using retry functions\n\nWhen viewing logs with `agent-validator logs`, logs are displayed in a clear table format:\n\n```bash\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 Timestamp                           \u2502 Status \u2502 Correlation \u2502 Mode    \u2502 Attempts \u2502 Duration    \u2502 Errors  \u2502 Size    \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 2025-08-30 18:40:00                 \u2502      \u2717 \u2502        none \u2502  strict \u2502        1 \u2502         0ms \u2502       2 \u2502    45B  \u2502\n\u2502 2025-08-30 18:40:00                 \u2502      \u2713 \u2502        none \u2502  coerce \u2502        1 \u2502         0ms \u2502       0 \u2502    45B  \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\nCorrelation IDs are truncated for readability and show `[none]` when not set.\n\n### \u2601\ufe0f Cloud Logging\n\nEnable cloud logging for monitoring and recovery:\n\n```python\nfrom agent_validator import Config\n\nconfig = Config(\n    log_to_cloud=True,\n    license_key=\"your-license-key\",\n    cloud_endpoint=\"https://api.agentvalidator.dev\"\n)\n\nresult = validate(\n    agent_output,\n    schema,\n    log_to_cloud=True,\n    config=config\n)\n```\n\n### \ud83d\udd10 Webhook Secret Management\n\nFor enhanced security, generate a webhook secret for HMAC signature validation:\n\n```bash\n# Generate a new webhook secret\nagent-validator webhook --generate\n\n# Check webhook status\nagent-validator webhook --status\n\n# Show current webhook secret\nagent-validator webhook --show\n\n# Revoke webhook secret\nagent-validator webhook --revoke\n```\n\n**Security Features:**\n\n- \u2705 **One-time display**: Webhook secrets are only shown once when generated\n- \u2705 **Secure storage**: Secrets are stored encrypted in the database\n- \u2705 **User isolation**: Each license key has its own webhook secret\n- \u2705 **Revocation**: Users can revoke and regenerate secrets as needed\n\n#### Using HMAC Signatures\n\nOnce you have a webhook secret, requests can include an HMAC signature:\n\n```python\nimport hmac\nimport hashlib\n\n# Create signature\nsignature = hmac.new(\n    webhook_secret.encode(),\n    payload.encode(),\n    hashlib.sha256\n).hexdigest()\n\n# Include in request headers\nheaders = {\n    \"license-key\": \"your-license-key\",\n    \"x-signature\": signature\n}\n```\n\n#### Security Notes\n\n- **One-time display**: Webhook secrets are only shown once when generated\n- **Secure storage**: Secrets are stored encrypted in the database\n- **User isolation**: Each license key has its own webhook secret\n- **Revocation**: Users can revoke and regenerate secrets as needed\n\n### \ud83c\udf10 Web Dashboard\n\nAccess your validation logs through a secure web dashboard:\n\n```bash\n# Configure your license key\nagent-validator config --set-license-key your-license-key\n\n# Open dashboard with secure local proxy\nagent-validator dashboard\n```\n\nThis opens a local proxy server at `http://localhost:8080` that securely forwards requests to the cloud API with proper authentication headers. The dashboard shows:\n\n- Recent validation attempts\n- Success/failure rates\n- Performance metrics\n- Error details\n- Correlation IDs for debugging\n\n**Security Features:**\n\n- \u2705 No credentials in URLs\n- \u2705 Secure header authentication\n- \u2705 User data isolation\n- \u2705 Local proxy prevents credential exposure\n\n---\n\n## \u2699\ufe0f Configuration\n\n### \ud83c\udf0d Environment Variables\n\n```bash\nexport AGENT_VALIDATOR_LICENSE_KEY=\"your-license-key\"\nexport AGENT_VALIDATOR_WEBHOOK_SECRET=\"your-webhook-secret\"\nexport AGENT_VALIDATOR_LOG_TO_CLOUD=\"1\"\nexport AGENT_VALIDATOR_ENDPOINT=\"https://api.agentvalidator.dev\"\nexport AGENT_VALIDATOR_MAX_OUTPUT_BYTES=\"131072\"\nexport AGENT_VALIDATOR_MAX_STR_LEN=\"8192\"\nexport AGENT_VALIDATOR_MAX_LIST_LEN=\"2048\"\nexport AGENT_VALIDATOR_MAX_DICT_KEYS=\"512\"\nexport AGENT_VALIDATOR_TIMEOUT_S=\"20\"\nexport AGENT_VALIDATOR_RETRIES=\"2\"\n```\n\n### \ud83d\udcc4 Configuration File\n\nConfiguration is stored in `~/.agent_validator/config.toml`:\n\n```toml\nmax_output_bytes = 131072\nmax_str_len = 8192\nmax_list_len = 2048\nmax_dict_keys = 512\nlog_to_cloud = false\ncloud_endpoint = \"https://api.agentvalidator.dev\"\ntimeout_s = 20\nretries = 2\nlicense_key = \"your-license-key\"\nwebhook_secret = \"your-webhook-secret\"\n```\n\n### \ud83d\udd04 Configuration Precedence\n\nConfiguration values are loaded in the following order (highest to lowest priority):\n\n1. **CLI Arguments** (highest priority)\n\n   ```bash\n   agent-validator test schema.json input.json --mode COERCE --timeout-s 30\n   ```\n\n2. **Environment Variables**\n\n   ```bash\n   export AGENT_VALIDATOR_MODE=\"COERCE\"\n   export AGENT_VALIDATOR_TIMEOUT_S=\"30\"\n   ```\n\n3. **Configuration File** (lowest priority)\n   ```toml\n   # ~/.agent_validator/config.toml\n   mode = \"STRICT\"\n   timeout_s = 20\n   ```\n\n**Example**: If you have `timeout_s = 20` in your config file, but set `export AGENT_VALIDATOR_TIMEOUT_S=\"30\"`, the environment variable (30 seconds) will take precedence.\n\n**Note**: CLI arguments always override environment variables and config file settings.\n\n---\n\n## \ud83d\udd12 Security & Privacy\n\n### \ud83d\udeab Redaction\n\nSensitive data is automatically redacted before logging:\n\n- **API Keys**: `sk-1234567890abcdef` \u2192 `[REDACTED]`\n- **JWT Tokens**: `Bearer eyJ...` \u2192 `[REDACTED]`\n- **Emails**: `john@example.com` \u2192 `j***n@example.com`\n- **Phone Numbers**: `+1-555-123-4567` \u2192 `***-***-4567`\n- **SSNs**: `123-45-6789` \u2192 `***-**-6789`\n- **Credit Cards**: `1234-5678-9012-3456` \u2192 `************3456`\n- **Passwords**: `secret123` \u2192 `[REDACTED]`\n\n### \ud83d\udd27 Custom Redaction Patterns\n\n```python\nfrom agent_validator.redact import add_redaction_pattern\n\n# Add custom pattern\nadd_redaction_pattern(\"custom_token\", r\"custom-[a-zA-Z0-9]{20,}\")\n```\n\n---\n\n## \ud83d\udccf Size Limits\n\nDefault limits to prevent abuse:\n\n| Limit              | Default | Description              |\n| ------------------ | ------- | ------------------------ |\n| `max_output_bytes` | 131,072 | Total JSON size in bytes |\n| `max_str_len`      | 8,192   | Maximum string length    |\n| `max_list_len`     | 2,048   | Maximum list length      |\n| `max_dict_keys`    | 512     | Maximum dictionary keys  |\n\n---\n\n## \u26a0\ufe0f Error Handling\n\n### \ud83d\udea8 ValidationError\n\nRaised when validation fails after all retries:\n\n```python\nfrom agent_validator import ValidationError\n\ntry:\n    result = validate(data, schema)\nexcept ValidationError as e:\n    print(f\"Path: {e.path}\")\n    print(f\"Reason: {e.reason}\")\n    print(f\"Attempt: {e.attempt}\")\n    print(f\"Correlation ID: {e.correlation_id}\")\n```\n\n### \ud83d\udccb SchemaError\n\nRaised when schema definition is invalid:\n\n```python\nfrom agent_validator import SchemaError\n\ntry:\n    schema = Schema({\"name\": bytes})  # Unsupported type\nexcept SchemaError as e:\n    print(f\"Schema error: {e}\")\n```\n\n### \u2601\ufe0f CloudLogError\n\nRaised when cloud logging fails (non-fatal):\n\n```python\nfrom agent_validator import CloudLogError\n\ntry:\n    result = validate(data, schema, log_to_cloud=True)\nexcept CloudLogError as e:\n    print(f\"Cloud logging failed: {e}\")\n    # Validation still succeeds\n```\n\n---\n\n## \ud83d\udca1 Examples\n\n### \ud83c\udfaf Basic Example\n\n```python\nfrom agent_validator import validate, Schema, ValidationMode\n\ndef call_agent(prompt: str, context: dict) -> str:\n    \"\"\"Mock agent function.\"\"\"\n    import random\n    if random.random() < 0.3:\n        return \"This is not valid JSON\"\n    return '{\"name\": \"John\", \"age\": 30, \"email\": \"john@example.com\"}'\n\nschema = Schema({\n    \"name\": str,\n    \"age\": int,\n    \"email\": str\n})\n\nresult = validate(\n    call_agent(\"\", {}),\n    schema,\n    retry_fn=call_agent,\n    retries=2,\n    mode=ValidationMode.COERCE\n)\n```\n\n### \u2601\ufe0f With Cloud Logging\n\n```python\nfrom agent_validator import validate, Schema, Config\n\nconfig = Config(\n    log_to_cloud=True,\n    license_key=os.getenv(\"AGENT_VALIDATOR_LICENSE_KEY\")\n)\n\nschema = Schema({\n    \"user\": {\n        \"name\": str,\n        \"age\": int,\n        \"preferences\": {\n            \"theme\": str,\n            \"notifications\": bool\n        }\n    }\n})\n\nresult = validate(\n    agent_output,\n    schema,\n    log_to_cloud=True,\n    config=config,\n    context={\"user_id\": \"123\", \"environment\": \"production\"}\n)\n```\n\n---\n\n## \ud83d\udda5\ufe0f CLI Reference\n\n### \ud83d\udee0\ufe0f Commands\n\n```bash\n# Test validation\nagent-validator test <schema.json> <input.json> [--mode STRICT|COERCE]\n\n# View local logs\nagent-validator logs [-n <number>] [--clear]\n\n# View cloud logs\nagent-validator cloud-logs [-n <number>]\n\n# Open web dashboard\nagent-validator dashboard [--port <port>] [--url] [--open]\n\n# Generate correlation ID\nagent-validator id\n\n# Manage configuration\nagent-validator config [--show] [--show-secrets] [--set-license-key <key>] [--set-endpoint <url>] [--set-webhook-secret <secret>] [--set-log-to-cloud <true|false>]\n\n# Manage webhook secrets\nagent-validator webhook [--generate] [--status] [--show] [--revoke] [--force]\n```\n\n### \ud83d\udcca Exit Codes\n\n- `0`: Success\n- `1`: General error\n- `2`: Validation failed\n\n### \ud83d\udd12 Security Notes\n\n- **Configuration Display**: By default, sensitive values (license key, webhook secret) are masked as `***` when showing configuration\n- **Show Secrets**: Use `--show-secrets` flag to display actual values for debugging/verification\n- **Example**:\n\n  ```bash\n  # Default (masked)\n  agent-validator config --show\n  # Output: license_key: ***\n\n  # With secrets visible\n  agent-validator config --show --show-secrets\n  # Output: license_key: my-actual-key\n  ```\n\n---\n\n## \ud83d\udee0\ufe0f Development\n\n### \ud83d\udce6 Installation\n\n```bash\ngit clone https://github.com/agent-validator/agent-validator.git\ncd agent-validator\npip install -e \".[dev]\"\n```\n\n**Note**: The `[dev]` extras include build tools (`build`, `twine`) needed for creating releases.\n\n### \ud83e\uddea Running Tests\n\n```bash\n# Run all tests\npython -m pytest tests/ -v\n\n# Run with coverage\npytest --cov=agent_validator\n\n# Run property-based tests\npython -m pytest tests/property/ -v\n\n# Run type checking\nmypy agent_validator cli\n\n# Run linting\nruff check .\nblack --check .\nisort --check-only .\n\n# Run smoke tests (isolated environment)\npython smoke_tests/smoke_tests.py\n```\n\n### \ud83d\udd27 Pre-commit Hooks\n\n```bash\npre-commit install\npre-commit run --all-files\n```\n\n### \ud83d\ude80 Smoke Tests\n\nSmoke tests verify the complete user experience in an isolated environment:\n\n```bash\n# Run comprehensive smoke tests\npython smoke_tests/smoke_tests.py\n\n# With backend URL for cloud testing\npython smoke_tests/smoke_tests.py --backend-url http://localhost:9090\n```\n\n**What gets tested:**\n\n- \u2705 Package installation in isolated environment\n- \u2705 CLI command availability and functionality\n- \u2705 Library imports and basic operations\n- \u2705 Configuration management\n- \u2705 Log generation and retrieval\n- \u2705 Schema validation (strict and coerce modes)\n- \u2705 Error handling and edge cases\n\n**Benefits:**\n\n- \ud83d\udee1\ufe0f No pollution to your development environment\n- \ud83d\udd04 Clean testing environment every time\n- \ud83e\uddea Tests real installation and usage scenarios\n- \ud83d\ude80 Perfect for CI/CD integration\n\n### \ud83d\udce6 Releasing New Versions\n\nThe project uses automated CI/CD for releases. When you push a version tag, the CI automatically builds and publishes to PyPI.\n\n#### 1. **Update Version**\n\nUpdate the version in `agent_validator/version.py`:\n\n```python\n__version__ = \"1.0.1\"  # Increment version number\n```\n\n#### 2. **Update CHANGELOG**\n\nAdd a new entry to `CHANGELOG.md` following the [Keep a Changelog](https://keepachangelog.com/) format:\n\n```markdown\n## [1.0.1] - 2025-01-01\n\n### Added\n\n- New feature description\n\n### Changed\n\n- Breaking change description\n\n### Fixed\n\n- Bug fix description\n```\n\n#### 3. **Run Pre-release Checks**\n\n```bash\n# Install build dependencies (if not already installed)\npip install -e \".[dev]\"\n\n# Run all tests\npython -m pytest tests/ -v\n\n# Run smoke tests\npython smoke_tests/smoke_tests.py\n\n# Check code quality (matches CI)\nruff check .\nmypy agent_validator cli\n\n# Verify package builds\npython -m build\n```\n\n#### 4. **Commit and Push Changes**\n\n```bash\n# Commit version and changelog updates\ngit add agent_validator/version.py CHANGELOG.md\ngit commit -m \"Release v1.0.1\"\ngit push origin master\n```\n\n#### 5. **Create and Push Git Tag**\n\n```bash\n# Create version tag\ngit tag v1.0.1\n\n# Push tag to trigger automated release\ngit push origin v1.0.1\n```\n\n**That's it!** \ud83d\ude80 The CI/CD pipeline will automatically:\n\n- \u2705 Run tests across Python 3.9, 3.10, 3.11, and 3.12\n- \u2705 Run linting and type checking\n- \u2705 Build the package\n- \u2705 Publish to PyPI (if tag starts with `v`)\n\n#### 6. **Verify Release**\n\nAfter the CI completes (usually 2-3 minutes):\n\n```bash\n# Test installation from PyPI\npip install agent-validator==1.0.1 --force-reinstall\n\n# Verify functionality\nagent-validator --help\npython -c \"import agent_validator; print(agent_validator.__version__)\"\n```\n\n#### 7. **Create GitHub Release**\n\n- Go to [GitHub Releases](https://github.com/agent-validator/agent-validator/releases)\n- Click \"Create a new release\"\n- Select the tag you just pushed\n- Copy the changelog content\n- Publish the release\n\n**Release Checklist:**\n\n- [ ] Version updated in `agent_validator/version.py`\n- [ ] CHANGELOG.md updated\n- [ ] All tests pass locally\n- [ ] Smoke tests pass\n- [ ] Code quality checks pass\n- [ ] Package builds successfully\n- [ ] Changes committed and pushed to master\n- [ ] Git tag created and pushed\n- [ ] CI/CD pipeline completes successfully\n- [ ] Installation from PyPI verified\n- [ ] GitHub release created with changelog\n\n**CI/CD Pipeline Details:**\n\nThe `.github/workflows/ci.yml` workflow automatically:\n\n- **Tests**: Runs on Python 3.9, 3.10, 3.11, 3.12\n- **Quality**: Runs `ruff check` and `mypy`\n- **Coverage**: Generates and uploads coverage reports\n- **Publishing**: Automatically publishes to PyPI when a tag starting with `v` is pushed\n- **Security**: Uses GitHub secrets for PyPI authentication\n\n---\n\n## \ud83e\udd1d Contributing\n\n1. \ud83c\udf74 Fork the repository\n2. \ud83c\udf3f Create a feature branch\n3. \u270f\ufe0f Make your changes\n4. \ud83e\uddea Add tests\n5. \u2705 Run the test suite\n6. \ud83d\udce4 Submit a pull request\n\n---\n\n## \ud83d\udcc4 License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n---\n\n## \u2753 FAQ\n\n**Q: Can I use this with any LLM/agent?**  \nA: Yes! The library is framework-agnostic. Just pass your agent's output to the `validate` function.\n\n**Q: What happens if my agent returns malformed JSON?**  \nA: In strict mode, it will fail immediately. In coerce mode, it will try to parse as JSON first, then fall back to treating it as a plain string.\n\n**Q: How do I handle sensitive data in logs?**  \nA: Sensitive data is automatically redacted before logging. You can also add custom redaction patterns.\n\n**Q: Can I use this in production?**  \nA: Yes! The library is designed for production use with proper error handling, logging, and monitoring capabilities.\n\n**Q: How do I access the web dashboard securely?**  \nA: Use `agent-validator dashboard` which creates a secure local proxy server. Never put your license key in URLs - the CLI handles authentication securely via headers.\n\n**Q: How do I verify my license key is set correctly?**  \nA: Use `agent-validator config --show --show-secrets` to display the actual license key value. By default, sensitive values are masked as `***` for security.\n\n**Q: What's the performance impact?**  \nA: Minimal. Validation is fast, and logging is asynchronous. The main overhead comes from retry attempts when validation fails.\n\n**Q: Can I use my own schema format?**  \nA: Currently only Python dict schemas are supported. JSONSchema support is planned for v0.1.\n\n---\n\n## \ud83d\uddfa\ufe0f Roadmap\n\n- [ ] JSONSchema import/export\n- [ ] Pydantic model support\n- [ ] Custom validators per field\n- [ ] Schema composition and inheritance\n- [x] Web dashboard for monitoring\n- [ ] Alerting and notifications\n- [ ] Schema versioning\n- [ ] Performance metrics\n\n---\n\n<div align=\"center\">\n\n**Made with \u2764\ufe0f by the Agent Validator community**\n\n[![GitHub stars](https://img.shields.io/github/stars/agent-validator/agent-validator?style=social)](https://github.com/agent-validator/agent-validator)\n[![GitHub forks](https://img.shields.io/github/forks/agent-validator/agent-validator?style=social)](https://github.com/agent-validator/agent-validator)\n\n</div>\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A library for validating agent outputs against schemas",
    "version": "1.0.0",
    "project_urls": {
        "Bug Tracker": "https://github.com/agent-validator/agent-validator/issues",
        "Documentation": "https://agent-validator.readthedocs.io/",
        "Homepage": "https://github.com/agent-validator/agent-validator",
        "Repository": "https://github.com/agent-validator/agent-validator"
    },
    "split_keywords": [
        "validation",
        " schema",
        " agent",
        " ai"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "12da80be98ee20855f87aeadda095cb98ff25747566f050c1b15332e438369c0",
                "md5": "916e058612de6dd3ec3ab97250a6533b",
                "sha256": "acf1085c636a5652ab0d945997a1e581f2d9e83be3ea762444fc9762d14df83d"
            },
            "downloads": -1,
            "filename": "agent_validator-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "916e058612de6dd3ec3ab97250a6533b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 29721,
            "upload_time": "2025-08-31T02:40:16",
            "upload_time_iso_8601": "2025-08-31T02:40:16.742079Z",
            "url": "https://files.pythonhosted.org/packages/12/da/80be98ee20855f87aeadda095cb98ff25747566f050c1b15332e438369c0/agent_validator-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "ee03ea266c20d611b7994ddb82ebe3fe9fcb8dec1d5c3527ddd40354c11c2789",
                "md5": "95a403e44e7ed347c6be0119b04ea942",
                "sha256": "44b5b049bec31378077ddc4b1dffc72266aab1e9a86ba75d052aed969064d33b"
            },
            "downloads": -1,
            "filename": "agent_validator-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "95a403e44e7ed347c6be0119b04ea942",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 40348,
            "upload_time": "2025-08-31T02:40:18",
            "upload_time_iso_8601": "2025-08-31T02:40:18.114542Z",
            "url": "https://files.pythonhosted.org/packages/ee/03/ea266c20d611b7994ddb82ebe3fe9fcb8dec1d5c3527ddd40354c11c2789/agent_validator-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-31 02:40:18",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "agent-validator",
    "github_project": "agent-validator",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "agent-validator"
}
        
Elapsed time: 0.67064s