Metadata-Version: 2.5
Name: tacet
Version: 0.1.0
Summary: Official Python client for the Tacet API
Project-URL: Homepage, https://tacet.codepawl.com
Project-URL: Documentation, https://tacet.codepawl.com/docs
Author-email: CodePawl <hello@codepawl.com>
License-Expression: MIT
License-File: LICENSE
Keywords: api client,classification,llm,tacet,typed decisions
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx>=0.23
Description-Content-Type: text/markdown

# tacet

Official Python client for the [Tacet API](https://tacet.codepawl.com/docs).

## Install

```bash
pip install tacet
# or
uv add tacet
```

## Quickstart

```python
from tacet import Tacet, choice, score, noul

client = Tacet(api_key="tacet_sk_...")  # or set TACET_API_KEY

result = client.decide(
    state="Customer says their export has been stuck at 'processing' for two days.",
    questions={
        "routing_team": choice(
            "Which team should own this ticket?",
            {"billing": "Payment or invoicing issues", "support": "Product or account issues"},
        ),
        "urgency": score(
            "How urgent is this ticket?",
            ["low", "medium", "high", "critical"],
        ),
        "needs_human": noul("Does this ticket need a human to step in?"),
    },
)

print(result.answers["routing_team"].choice)
print(result.answers["urgency"].score)
print(result.answers["needs_human"].noul)
print(result.usage.input_tokens)
```

An `AsyncTacet` client with the same methods, `await`ed, is available for
async code.

## Question types

- **choice**: pick one option out of a named set. `criteria` maps option
  names to descriptions. The answer carries `choice`, `probabilities` (one
  per option), and `confidence`.
- **score**: an expected level over an ordered list of levels. `criteria`
  is that list. The answer carries `score`, `probabilities` (one per level
  index), and `confidence`.
- **noul**: yes or no. `noul` is the probability of yes, from 0 to 1, and
  an optional `criteria` object says what "true" and "false" mean. The answer
  carries `noul` and `confidence`, no probabilities.

The `choice`, `score`, and `noul` helpers build the question dict for you;
you can also pass the dict shape directly.

## Errors and retries

Every non-2xx response raises a subclass of `TacetError`, which carries
`status`, `code`, `error_type`, `param`, `request_id`, and `message`:

- `AuthenticationError`: 401 (missing, invalid, or revoked API key)
- `InsufficientCreditError`: 402 (out of credit)
- `RateLimitError`: 429, also carries `retry_after` seconds
- `InvalidRequestError`: 400/404/413 (bad request, unknown model, state too large, etc.)
- `APIError`: 5xx
- `APIConnectionError`: the request failed before a response came back

The client retries 429s (honoring the `Retry-After` header) and 500/502/503/504
responses and connection failures, with exponential backoff and jitter, up to
`max_retries` times (default 2). Other 4xx errors fail immediately and are
never retried.

## Idle starts

If the API hasn't been called in a while, the first request after that idle
period can take tens of seconds while it starts back up. The default timeout
(90 seconds) accounts for this; don't lower it unless you know your traffic
is steady.

## Pricing

$0.042 per 1M input tokens, and output is free. Details are in the
[API docs](https://tacet.codepawl.com/docs).
