Metadata-Version: 2.4
Name: ai-lib-python
Version: 1.0.1
Summary: Official Python Runtime for AI-Protocol - The canonical Pythonic implementation for unified AI model interaction
Project-URL: Homepage, https://github.com/ailib-official/ai-lib-python
Project-URL: Documentation, https://github.com/ailib-official/ai-lib-python#readme
Project-URL: Repository, https://github.com/ailib-official/ai-lib-python
Project-URL: Issues, https://github.com/ailib-official/ai-lib-python/issues
Author: AI-Protocol Team
License-Expression: MIT OR Apache-2.0
License-File: LICENSE-APACHE
License-File: LICENSE-MIT
Keywords: ai,anthropic,claude,gpt,llm,openai,protocol,streaming
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: fastjsonschema>=2.19
Requires-Dist: httpx>=0.25.0
Requires-Dist: jsonpath-ng>=1.6
Requires-Dist: pydantic-settings>=2.0
Requires-Dist: pydantic>=2.0
Requires-Dist: pyyaml>=6.0
Provides-Extra: agentic
Provides-Extra: audio
Requires-Dist: soundfile>=0.12; extra == 'audio'
Provides-Extra: batch
Provides-Extra: contact
Provides-Extra: dev
Requires-Dist: mypy>=1.8; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest-httpx>=0.30; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.2; extra == 'dev'
Requires-Dist: types-pyyaml>=6.0; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.0; extra == 'docs'
Requires-Dist: mkdocs>=1.5; extra == 'docs'
Requires-Dist: mkdocstrings[python]>=0.24; extra == 'docs'
Provides-Extra: embeddings
Provides-Extra: full
Requires-Dist: keyring>=24.0; extra == 'full'
Requires-Dist: opentelemetry-api>=1.20; extra == 'full'
Requires-Dist: opentelemetry-exporter-otlp>=1.20; extra == 'full'
Requires-Dist: opentelemetry-sdk>=1.20; extra == 'full'
Requires-Dist: pillow>=10.0; extra == 'full'
Requires-Dist: soundfile>=0.12; extra == 'full'
Requires-Dist: tiktoken>=0.5; extra == 'full'
Requires-Dist: watchdog>=3.0; extra == 'full'
Provides-Extra: jupyter
Requires-Dist: ipywidgets>=8.0; extra == 'jupyter'
Provides-Extra: reranking
Provides-Extra: structured
Provides-Extra: stt
Provides-Extra: telemetry
Requires-Dist: opentelemetry-api>=1.20; extra == 'telemetry'
Requires-Dist: opentelemetry-exporter-otlp>=1.20; extra == 'telemetry'
Requires-Dist: opentelemetry-sdk>=1.20; extra == 'telemetry'
Provides-Extra: tokenizer
Requires-Dist: tiktoken>=0.5; extra == 'tokenizer'
Provides-Extra: tts
Provides-Extra: vision
Requires-Dist: pillow>=10.0; extra == 'vision'
Description-Content-Type: text/markdown

# ai-lib-python

**Protocol runtime for [AI-Protocol](https://github.com/ailib-official/ai-protocol)** — async Python reference implementation (v**1.0.0**).

`ai-lib-python` is a single package with **execution / policy module separation** (E/P at the module level). Most apps import from the root:

```python
from ai_lib_python import AiClient, Message, StreamingEvent
```

## How it works

**Default chat path:** `AiClient` loads a provider manifest → builds a **`Pipeline`** from manifest operators → sends HTTP via **`HttpTransport`** (httpx). Streaming frames are normalized to **`StreamingEvent`**.

This is protocol-driven for chat, but not “zero provider code”: the repo also ships provider-specific decoders/mappers, optional **`ProviderDriver`** implementations (advanced / tests), and standalone HTTP clients for embeddings, STT, TTS, and rerank.

| Layer | Packages / modules | Responsibility |
|-------|-------------------|----------------|
| Execution (E) | `client`, `protocol`, `pipeline`, `transport`, `types`, `structured`, optional capability modules | Deterministic execution, manifest loading, HTTP |
| Policy (P) | `resilience`, `cache`, `routing`, `plugins`, `guardrails`, `batch`, `telemetry`, `tokens` | Retry, rate limits, routing, telemetry — opt-in beside the client |
| Facade | `ai_lib_python` (root) | Stable imports + examples + compliance tests |

Published on [PyPI](https://pypi.org/project/ai-lib-python/): **`ai-lib-python` 1.0.0**. Python **3.10+**.

## Quick start

```bash
pip install ai-lib-python
export DEEPSEEK_API_KEY="your-key"
```

```python
import asyncio
from ai_lib_python import AiClient, Message

async def main() -> None:
    client = await AiClient.create("deepseek/deepseek-chat")

    response = await (
        client.chat()
        .messages([
            Message.system("You are a helpful assistant."),
            Message.user("Hello!"),
        ])
        .temperature(0.7)
        .max_tokens(500)
        .execute()
    )

    print(response.content)
    await client.close()

asyncio.run(main())
```

Same example: `python examples/basic_chat.py` (requires `OPENAI_API_KEY` or change the model).

The fluent builder also supports `.system()` / `.user()` shorthands on `client.chat()`.

### Streaming

```python
import asyncio
from ai_lib_python import AiClient

async def main() -> None:
    client = await AiClient.create("deepseek/deepseek-chat")

    async for event in (
        client.chat()
        .user("Write a haiku about Python.")
        .stream()
    ):
        if event.is_content_delta:
            print(event.as_content_delta.content, end="", flush=True)
        elif event.is_stream_end:
            break

    await client.close()

asyncio.run(main())
```

Same example: `python examples/streaming.py`.

### Call statistics

`ChatResponse` does not embed stats. Use `execute_with_stats()` or `stream_with_stats()`:

```python
response, stats = await client.chat().user("Hello!").execute_with_stats()
print(stats.latency_ms, stats.input_tokens, stats.output_tokens)
```

### Production resilience (opt-in)

```python
client = await (
    AiClient.builder()
    .model("deepseek/deepseek-chat")
    .production_ready()  # ResilientConfig.production() defaults
    .build()
)
```

`production_ready()` wires the policy-layer `resilience` module. It is **not** enabled by `AiClient.create()` alone.

## Public API (package root)

Always exported from `ai_lib_python`:

- **Client:** `AiClient`, `AiClientBuilder`, `ChatResponse`, `CallStats`
- **Types:** `Message`, `MessageRole`, `MessageContent`, `ContentBlock`, `StreamingEvent`, `ToolCall`, `ToolDefinition`
- **Errors:** `AiLibError`, `ProtocolError`, `TransportError`
- **Feature probes:** `HAS_VISION`, `HAS_AUDIO`, `HAS_TELEMETRY`, `HAS_TOKENIZER`, `HAS_WATCHDOG`, `HAS_KEYRING`, `require_extra`

Subpackages (import explicitly when needed):

- **Execution:** `ai_lib_python.pipeline`, `protocol`, `transport`, `structured`, `embeddings`, `stt`, `tts`, `rerank`, `multimodal`, `mcp`, `computer_use`
- **Policy:** `ai_lib_python.resilience`, `cache`, `routing`, `plugins`, `guardrails`, `batch`, `telemetry`, `tokens`, `registry`
- **Advanced:** `ai_lib_python.drivers` — `ProviderDriver`, `create_driver` (not used by default `AiClient` chat path)

### What extras actually do

| Extra | What you get | Notes |
|-------|--------------|-------|
| `vision` | Pillow-backed image blocks | Marked via `HAS_VISION` |
| `audio` | Audio helpers | `HAS_AUDIO` |
| `embeddings` | `EmbeddingClient` | Standalone HTTP client |
| `structured` | Structured / JSON mode helpers | |
| `stt` / `tts` / `reranking` | `SttClient`, `TtsClient`, `RerankerClient` | Standalone service clients |
| `batch` | Batch collector / executor | Policy layer |
| `telemetry` | OpenTelemetry sinks, `report_feedback` | `FeedbackEvent` types in subpackage |
| `tokenizer` | Token counting (tiktoken) | `HAS_TOKENIZER` |
| `full` | All extras above | |
| `dev` | pytest, mypy, ruff | Development only |

```bash
pip install ai-lib-python[full]
```

### Honest capability boundaries

| Area | In the package | Not included |
|------|----------------|--------------|
| **MCP** (`mcp` module) | `McpToolBridge` format conversion | MCP server transport wired into `AiClient` |
| **Computer Use** (`computer_use`) | `ComputerAction`, `SafetyPolicy` validation | Screenshot / input execution environment |
| **Hot reload** | `AiClientBuilder.hot_reload()` flag + in-memory cache | File watching (needs `watchdog`; `HAS_WATCHDOG`) — no automatic reload today |
| **`ProviderDriver`** | Public `drivers` module | Default `AiClient` chat path |
| **Rate limit env** | Configure via `AiClientBuilder` / `resilience` | `AI_LIB_RPS` / `AI_LIB_RPM` are **not** read by the runtime |

## Advanced: `ProviderDriver`

`ai_lib_python.drivers` exposes `ProviderDriver`, `create_driver`, and OpenAI / Anthropic / Gemini drivers. **`AiClient` does not use this path** for chat; it uses `Pipeline` from manifests. Drivers are for compliance tests and custom integrations.

## Resilience

- **Built into `AiClient`:** optional `max_inflight` backpressure via builder.
- **Opt-in policy layer:** `ai_lib_python.resilience` (retry, rate limiter, circuit breaker) — use `production_ready()` or explicit `ResilientConfig`.
- **Not auto-enabled** on `AiClient.create()`.

## Protocol manifests

Resolution order:

1. `AiClientBuilder.protocol_path(...)` / `ProtocolLoader(base_path=...)`
2. `AI_PROTOCOL_DIR` / `AI_PROTOCOL_PATH`
3. Dev paths: `ai-protocol/`, `../ai-protocol/`, …
4. Fallback: GitHub raw `ailib-official/ai-protocol` (`main`)

Per base path: `dist/v2/providers/<id>.json` → `v2/providers/<id>.yaml` → V1 equivalents.

## API keys (BYOK chain)

1. Explicit override on builder / `AiClient.create(..., api_key=...)`
2. Manifest-declared env from `endpoint.auth`
3. `<PROVIDER_ID>_API_KEY` (recommended for CI/containers)
4. OS keyring when `keyring` is installed (`HAS_KEYRING`)

## Environment variables

| Variable | Purpose |
|----------|---------|
| `AI_PROTOCOL_DIR` / `AI_PROTOCOL_PATH` | Local manifest directory or GitHub raw base URL |
| `AI_PROXY_URL` | Explicit proxy when `AI_HTTP_TRUST_ENV=1` |
| `HTTP_PROXY` / `HTTPS_PROXY` | Standard proxy vars (with `AI_HTTP_TRUST_ENV=1`) |
| `NO_PROXY` / `AI_PROXY_NO_PROXY` | Hosts that bypass proxy |
| `AI_HTTP_TIMEOUT_SECS` | HTTP timeout |
| `AI_LIB_MAX_INFLIGHT` | Concurrency backpressure (also via builder) |

Cross-runtime proxy semantics: [CROSS_RUNTIME.md](https://github.com/ailib-official/ai-protocol/blob/main/docs/CROSS_RUNTIME.md).

## Standard error codes (V2)

| Code | Name | Retryable | Fallbackable |
|------|------|-----------|--------------|
| E1001 | `invalid_request` | No | No |
| E1002 | `authentication` | No | Yes |
| E1003 | `permission_denied` | No | No |
| E1004 | `not_found` | No | No |
| E1005 | `request_too_large` | No | No |
| E2001 | `rate_limited` | Yes | Yes |
| E2002 | `quota_exhausted` | No | Yes |
| E3001 | `server_error` | Yes | Yes |
| E3002 | `overloaded` | Yes | Yes |
| E3003 | `timeout` | Yes | Yes |
| E4001 | `conflict` | Yes | No |
| E4002 | `cancelled` | No | No |
| E9999 | `unknown` | No | No |

## Testing

```bash
pip install -e ".[dev]"
pytest tests/unit/ -v
```

Compliance (cross-runtime YAML):

```bash
# POSIX
COMPLIANCE_DIR=../ai-protocol/tests/compliance pytest tests/compliance/ -v

# Windows PowerShell
$env:COMPLIANCE_DIR = "D:\ai-protocol\tests\compliance"
pytest tests/compliance/ -v
```

Mock server integration (requires [ai-protocol-mock](https://github.com/ailib-official/ai-protocol-mock)):

```bash
MOCK_HTTP_URL=http://localhost:4010 pytest tests/integration/ -v
```

## Examples

| Example | Topic |
|---------|-------|
| `basic_chat.py` | Quick start, `execute_with_stats` |
| `streaming.py` | `is_content_delta`, `stream_with_stats` |
| `resilience.py` | Policy layer |
| `multimodal.py` | Vision extra |
| `tool_calling.py` | Tools |
| `multi_provider_production.py` | Routing / fallbacks |
| `guardrails_production.py` | Guardrails |
| `concurrent_production.py` | Concurrency |
| `providers.py` | Provider switching |

## Related

- [AI-Protocol](https://github.com/ailib-official/ai-protocol) — specification & manifests
- [ai-lib-rust](https://github.com/ailib-official/ai-lib-rust) — Rust runtime
- [ai-lib-ts](https://github.com/ailib-official/ai-lib-ts) — TypeScript runtime
- [ai-lib-go](https://github.com/ailib-official/ai-lib-go) — Go runtime

## License

Dual-licensed under [Apache-2.0](LICENSE-APACHE) or [MIT](LICENSE-MIT).
