Metadata-Version: 2.4
Name: system-one-adapter
Version: 0.0.1a0
Summary: Drop-in TypeSafeClient replacement backed by LLM APIs
Author: TypeSafe AI
Author-email: TypeSafe AI <support@typesafe.ai>
License-Expression: MIT
License-File: LICENSE
Requires-Dist: msgspec>=0.19.0
Requires-Dist: tenacity>=8.0.0
Requires-Dist: typesafe-sdk>=0.6.0
Requires-Dist: typing-extensions>=4.0.0
Requires-Dist: anthropic>=0.121.0 ; extra == 'anthropic'
Requires-Dist: openai>=2.53.0 ; extra == 'openai'
Maintainer: Erik Gafni, Daniel Gafni
Maintainer-email: Erik Gafni <erik@typesafe.ai>, Daniel Gafni <daniel@typesafe.ai>
Requires-Python: >=3.10
Project-URL: Repository, https://github.com/typesafe-ai/system-one-adapter-python
Provides-Extra: anthropic
Provides-Extra: openai
Description-Content-Type: text/markdown

# System One Adapter

A drop-in replacement for `typesafe_sdk`'s `system_one` evaluation API, backed by LLM
APIs instead of TypeSafe. 

Useful for comparing TypeSafe against an LLM on
cost/speed/intelligence.

## Install

The provider SDKs are optional extras — install the one(s) you use:

```bash
pip install 'system-one-adapter[openai]'      # OpenAI-compatible providers
pip install 'system-one-adapter[anthropic]'   # native Anthropic
```

## Usage

Unlike `TypeSafeClient`, the client is configured with how the LLM should answer, and
each call names a `provider` alongside the `model`:

```python
from system_one_adapter import SystemOneAdapterClient, Noul, Score, Choice

client = SystemOneAdapterClient(
    structured_outputs=True,  # use the provider's native structured-output mode
    llm_answer_mode="probabilities",  # or "discrete"
    normalize_probabilities=True,
)

response = client.system_one(
    state="This book was a delight to read.",
    questions={"positive": Noul(instructions="The book review is positive.")},
    provider="openai",  # "openai" or "anthropic"
    model="gpt-4o-mini",
)
```

`provider` and `model` may also be set on the constructor as defaults. `provider`
is required unless `model` is a `Provider` instance (e.g. a custom OpenAI-compatible
endpoint):

```python
from system_one_adapter.providers import OpenAIProvider

client.system_one(state, questions, model=OpenAIProvider("grok-4", base_url="https://api.x.ai/v1"))
```

### Response

The response is a `typesafe_sdk.SystemOneResponse` subclass — same `answers` and typed
views — with two additions:

- `response.usage` adds `input_tokens_total` / `output_tokens_total` (across retries),
  `n_retries`, `n_retries_malformed_structure`, and `latency`.
- `response.debug` holds `retry_reasons` and probability-normalization diagnostics.

It is a `msgspec.Struct` like every SDK response, so serialize it the same way (there is
no `model_dump`):

```python
import msgspec

print(msgspec.json.encode(response).decode())
```

### Async

`AsyncSystemOneAdapterClient` mirrors the sync client with `await client.system_one(...)`
and `async with`.

## Options

| Option | Meaning |
| --- | --- |
| `structured_outputs` | Use the provider's native structured output, else prompt for JSON and validate client-side (works with any chat model). |
| `llm_answer_mode` | `"probabilities"` (per-label distribution) or `"discrete"` (one value per question). |
| `normalize_probabilities` | Rescale invalid LLM probability distributions to sum to 1. |
| `n_retry_malformed_structure` | Corrective retries when the model's output fails schema validation. |
| `retry` | `typesafe_sdk.RetryPolicy` for transient provider failures. |
