Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions evaluators/builtin/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ dependencies = [
]

[project.optional-dependencies]
galileo = ["agent-control-evaluator-galileo>=3.0.0"]
cisco = ["agent-control-evaluator-cisco>=0.1.0"]
galileo = ["agent-control-evaluator-galileo>=7.5.0"]
budget = ["agent-control-evaluator-budget>=7.5.0"]
cisco = ["agent-control-evaluator-cisco>=7.5.0"]
dev = ["pytest>=8.0.0", "pytest-asyncio>=0.23.0"]

[project.entry-points."agent_control.evaluators"]
Expand All @@ -35,6 +36,7 @@ packages = ["src/agent_control_evaluators"]

[tool.uv.sources]
agent-control-models = { workspace = true }
# For local dev: use local galileo package instead of PyPI
# For local dev: use local contrib packages instead of PyPI
agent-control-evaluator-galileo = { path = "../contrib/galileo", editable = true }
agent-control-evaluator-budget = { path = "../contrib/budget", editable = true }
agent-control-evaluator-cisco = { path = "../contrib/cisco", editable = true }
28 changes: 28 additions & 0 deletions evaluators/contrib/budget/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
.PHONY: help test lint lint-fix typecheck check build

help:
@echo "Agent Control Evaluator - Budget - Makefile commands"
@echo ""
@echo " make test - run pytest"
@echo " make lint - run ruff check"
@echo " make lint-fix - run ruff check --fix"
@echo " make typecheck - run mypy"
@echo " make check - run lint, typecheck, and test"
@echo " make build - build package"

test:
uv run --with pytest --with pytest-asyncio --with pytest-cov pytest tests --cov=src --cov-report=xml:../../../coverage-evaluators-budget.xml -q

lint:
uv run --with ruff ruff check --config ../../../pyproject.toml src/

lint-fix:
uv run --with ruff ruff check --config ../../../pyproject.toml --fix src/

typecheck:
uv run --with mypy mypy --config-file ../../../pyproject.toml src/

check: lint typecheck test

build:
uv build
12 changes: 12 additions & 0 deletions evaluators/contrib/budget/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,22 @@ Budget evaluator for agent-control that tracks cumulative LLM token and cost usa

## Install

```bash
pip install "agent-control-evaluators[budget]"
```

Fallback direct wheel install:

```bash
pip install agent-control-evaluator-budget
```

For local development:

```bash
uv pip install -e evaluators/contrib/budget
```

## Quickstart

```python
Expand Down
6 changes: 3 additions & 3 deletions evaluators/contrib/budget/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[project]
name = "agent-control-evaluator-budget"
version = "0.1.0"
version = "7.5.0"
description = "Budget evaluator for agent-control -- cumulative LLM cost and token tracking"
readme = "README.md"
requires-python = ">=3.12"
license = { text = "Apache-2.0" }
authors = [{ name = "Agent Control Team" }]
dependencies = [
"agent-control-evaluators>=3.0.0",
"agent-control-models>=3.0.0",
"agent-control-evaluators>=7.5.0",
"agent-control-models>=7.5.0",
]

[project.optional-dependencies]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class BudgetEvaluatorConfig(EvaluatorConfig):
metadata_paths: dict[str, str] = Field(default_factory=dict)

@model_validator(mode="after")
def require_pricing_for_cost_rules(self) -> "BudgetEvaluatorConfig":
def require_pricing_for_cost_rules(self) -> BudgetEvaluatorConfig:
has_cost_rule = any(rule.limit_unit == "usd_cents" for rule in self.limits)
if has_cost_rule and self.pricing is None:
raise ValueError('pricing is required when any rule uses limit_unit="usd_cents"')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import logging
import math
import threading
from importlib.metadata import PackageNotFoundError, version
from typing import Any

from agent_control_evaluators._base import Evaluator, EvaluatorMetadata
Expand All @@ -27,6 +28,11 @@

logger = logging.getLogger(__name__)

try:
_PACKAGE_VERSION = version("agent-control-evaluator-budget")
except PackageNotFoundError:
_PACKAGE_VERSION = "0.0.0.dev"

# ---------------------------------------------------------------------------
# Module-level store registry
#
Expand Down Expand Up @@ -173,7 +179,7 @@ class BudgetEvaluator(Evaluator[BudgetEvaluatorConfig]):

metadata = EvaluatorMetadata(
name="budget",
version="3.0.0",
version=_PACKAGE_VERSION,
description="Cumulative LLM token and cost budget tracking",
)
config_model = BudgetEvaluatorConfig
Expand Down
5 changes: 5 additions & 0 deletions evaluators/contrib/budget/tests/budget/test_budget.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from __future__ import annotations

from importlib.metadata import version
import threading
from typing import Any

Expand Down Expand Up @@ -39,6 +40,10 @@ def _clean_store_registry() -> None:
clear_budget_stores()


def test_metadata_version_matches_distribution_version() -> None:
assert BudgetEvaluator.metadata.version == version("agent-control-evaluator-budget")


# ---------------------------------------------------------------------------
# InMemoryBudgetStore
# ---------------------------------------------------------------------------
Expand Down
12 changes: 6 additions & 6 deletions evaluators/contrib/cisco/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@ External evaluator that calls Cisco AI Defense Chat Inspection via REST and maps

## Installation

Install from PyPI (if available):
Canonical install path:

```bash
pip install agent-control-evaluator-cisco
pip install "agent-control-evaluators[cisco]"
```

Or install from the workspace for local development:
Fallback direct wheel install:

```bash
uv pip install -e evaluators/contrib/cisco
pip install agent-control-evaluator-cisco
```

Alternatively, install via the builtin evaluators package extra (one-liner):
For local development:

```bash
pip install agent-control-evaluators[cisco]
uv pip install -e evaluators/contrib/cisco
```

- Build wheel from the repo root (contrib package only):
Expand Down
6 changes: 3 additions & 3 deletions evaluators/contrib/cisco/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[project]
name = "agent-control-evaluator-cisco"
version = "0.1.0"
version = "7.5.0"
description = "Cisco AI Defense evaluator for agent-control"
readme = "README.md"
requires-python = ">=3.12"
license = { text = "Apache-2.0" }
authors = [{ name = "Cisco AI Defense Team" }]
dependencies = [
"agent-control-evaluators>=3.0.0",
"agent-control-models>=3.0.0",
"agent-control-evaluators>=7.5.0",
"agent-control-models>=7.5.0",
"httpx>=0.24.0",
]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import json
import os
from importlib.metadata import PackageNotFoundError, version
from typing import Any

from agent_control_evaluators import (
Expand All @@ -14,6 +15,11 @@
from .client import AI_DEFENSE_HTTPX_AVAILABLE, REGION_BASE_URLS, AIDefenseClient, build_endpoint
from .config import CiscoAIDefenseConfig

try:
_PACKAGE_VERSION = version("agent-control-evaluator-cisco")
except PackageNotFoundError:
_PACKAGE_VERSION = "0.0.0.dev"


def _load_api_key(env_name: str) -> str:
key = os.getenv(env_name)
Expand Down Expand Up @@ -99,7 +105,7 @@ class CiscoAIDefenseEvaluator(Evaluator[CiscoAIDefenseConfig]):

metadata = EvaluatorMetadata(
name="cisco.ai_defense",
version="0.1.0",
version=_PACKAGE_VERSION,
description="Cisco AI Defense Chat Inspection integration",
requires_api_key=True,
timeout_ms=15000,
Expand Down
6 changes: 6 additions & 0 deletions evaluators/contrib/cisco/tests/test_evaluator.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from importlib.metadata import version

import pytest
from pydantic import ValidationError

Expand All @@ -13,6 +15,10 @@ def _env_api_key(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv("AI_DEFENSE_API_KEY", "test-key")


def test_metadata_version_matches_distribution_version() -> None:
assert CiscoAIDefenseEvaluator.metadata.version == version("agent-control-evaluator-cisco")


@pytest.mark.asyncio
async def test_none_input_returns_no_data() -> None:
cfg = CiscoAIDefenseConfig()
Expand Down
21 changes: 21 additions & 0 deletions evaluators/contrib/galileo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,27 @@

Integration package for Galileo Luna-2 evaluator.

## Install

Canonical install path:

```bash
pip install "agent-control-evaluators[galileo]"
```

Grandfathered convenience aliases remain available:

```bash
pip install "agent-control-sdk[galileo]"
pip install "agent-control-server[galileo]"
```

Fallback direct wheel install:

```bash
pip install agent-control-evaluator-galileo
```

See full documentation in: https://docs.agentcontrol.dev/concepts/evaluators/contributing-evaluator

Example with usage: https://docs.agentcontrol.dev/examples/galileo-luna2
4 changes: 2 additions & 2 deletions evaluators/contrib/galileo/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ requires-python = ">=3.12"
license = { text = "Apache-2.0" }
authors = [{ name = "Agent Control Team" }]
dependencies = [
"agent-control-evaluators>=3.0.0",
"agent-control-models>=3.0.0",
"agent-control-evaluators>=7.5.0",
"agent-control-models>=7.5.0",
"httpx>=0.24.0",
"pydantic>=2.12.4",
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import logging
import os
from importlib.metadata import PackageNotFoundError, version
from typing import Any

from agent_control_evaluators import Evaluator, EvaluatorMetadata, register_evaluator
Expand All @@ -15,6 +16,11 @@

logger = logging.getLogger(__name__)

try:
_PACKAGE_VERSION = version("agent-control-evaluator-galileo")
except PackageNotFoundError:
_PACKAGE_VERSION = "0.0.0.dev"

# Check if httpx is available
try:
import httpx
Expand Down Expand Up @@ -84,7 +90,7 @@ class Luna2Evaluator(Evaluator[Luna2EvaluatorConfig]):

metadata = EvaluatorMetadata(
name="galileo.luna2",
version="3.0.0",
version=_PACKAGE_VERSION,
description="Galileo Luna-2 enterprise runtime protection (direct API)",
requires_api_key=True,
timeout_ms=10000,
Expand Down
3 changes: 2 additions & 1 deletion evaluators/contrib/galileo/tests/test_luna2_evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
The evaluator uses direct HTTP API calls instead of the galileo SDK.
"""

from importlib.metadata import version
import os
from unittest.mock import AsyncMock, MagicMock, patch

Expand Down Expand Up @@ -282,7 +283,7 @@ def test_luna2_evaluator_import_success(self):

assert Luna2Evaluator is not None
assert Luna2Evaluator.metadata.name == "galileo.luna2"
assert Luna2Evaluator.metadata.version == "3.0.0"
assert Luna2Evaluator.metadata.version == version("agent-control-evaluator-galileo")

@patch("agent_control_evaluator_galileo.luna2.evaluator.LUNA2_AVAILABLE", False)
def test_luna2_evaluator_is_available_false_without_httpx(self):
Expand Down
4 changes: 2 additions & 2 deletions sdks/python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ dependencies = [
"docstring-parser>=0.15", # For @tool decorator schema inference
"google-re2>=1.1", # For engine (bundled)
"jsonschema>=4.0.0", # For models/engine (bundled)
"agent-control-evaluators>=3.0.0", # NOT vendored - avoid conflict with galileo
"agent-control-evaluators>=7.5.0", # NOT vendored - avoid conflict with galileo
]
authors = [
{name = "Agent Control Team"}
Expand All @@ -38,7 +38,7 @@ Repository = "https://github.com/yourusername/agent-control"
[project.optional-dependencies]
strands-agents = ["strands-agents>=1.26.0"]
google-adk = ["google-adk>=1.0.0"]
galileo = ["agent-control-evaluator-galileo>=3.0.0"]
galileo = ["agent-control-evaluator-galileo>=7.5.0"]

[dependency-groups]
dev = [
Expand Down
4 changes: 2 additions & 2 deletions server/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ dependencies = [
"jsonschema-rs>=0.22.0",
"PyJWT>=2.8.0",
"google-re2>=1.1", # For engine (bundled)
"agent-control-evaluators>=3.0.0", # NOT vendored - avoid conflict with galileo
"agent-control-evaluators>=7.5.0", # NOT vendored - avoid conflict with galileo
]
authors = [
{name = "Agent Control Team"}
Expand All @@ -31,7 +31,7 @@ readme = "README.md"
license = {text = "Apache-2.0"}

[project.optional-dependencies]
galileo = ["agent-control-evaluator-galileo>=3.0.0"]
galileo = ["agent-control-evaluator-galileo>=7.5.0"]

[dependency-groups]
dev = [
Expand Down
Loading