Metadata-Version: 2.4
Name: ai37-agent-sdk
Version: 0.1.0a2
Summary: AI37 agent SDK (Python): JWKS auth + billing + A2A forward for ecosystem agents
License: Apache-2.0
License-File: LICENSE
Author: AI37
Requires-Python: >=3.11,<4.0
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Dist: httpx (>=0.27,<0.29)
Requires-Dist: pyjwt[crypto] (>=2.9.0,<3.0.0)
Description-Content-Type: text/markdown

# ai37-agent-sdk (Python)

SDK агентов экосистемы **AI37** (Python). Зеркало TS-пакета `@ai37/agent-sdk` (имена snake_case,
**синхронный** API). Модули: **auth** (JWKS-верификация user-JWT), **billing** (runtime state +
metered usage), **a2a** (forward user-JWT), **AgentContext** (sugar) и **testing kit**.

> Контракт (источник истины) — `../../contract/`. Спецификация — `docs/projects/ai37-agent-sdk/`.
> Host-слой (Express/FastAPI) в Python **не реализован** (пока не нужен).

## Быстрый старт

```python
from ai37_agent_sdk import AgentContext, AgentContextSettings, AuthSettings, BillingSettings

ctx = AgentContext.from_request(
    request_headers,
    AgentContextSettings(
        auth=AuthSettings(
            issuer="https://<issuer>/",
            audience="<client-id>",
            jwks_url="https://<issuer>/jwks/",
            required=True,
        ),
        billing=BillingSettings(base_url="http://billing:8000"),
    ),
)
state = ctx.assert_execution_allowed(feature=..., privilege=...)  # preflight
# LLM-агент:    api_key = ctx.llm_key
# metered-агент: ctx.report_usage(transaction_id=task_id, code="lift_calculation", properties={...})
```

## Тестирование агентов без внешних сервисов

```python
from ai37_agent_sdk.testing import make_test_context, InMemoryBillingClient, fixtures

ctx = make_test_context(
    claims={"sub": "u1", "org_id": "u1", "billing_org_id": "org1", "app_id": "product-a"},
    billing=InMemoryBillingClient(runtime_state=fixtures.runtime_state.no_resources()),
)
# ctx.assert_execution_allowed(...) -> BillingExecutionDeniedError по фикстуре
```

## Разработка

```bash
poetry install --with dev
poetry run pytest
poetry run ruff check .
poetry run mypy src
```

Не реализовано (follow-up): CLI dev-серверы (`dev-jwks`/`dev-billing`), режимы
`AI37_AUTH_MODE=insecure-dev` / `BILLING_MODE=fake`. Основной testing kit (фейки/фикстуры/тест-токены)
— есть.

