Metadata-Version: 2.4
Name: kayak
Version: 0.4.0
Summary: Typed decisions from Contrastive Language Models, locally or over HTTP
License-Expression: Apache-2.0
Project-URL: Documentation, https://github.com/teilomillet/kayak/blob/main/docs/README.md
Project-URL: Source, https://github.com/teilomillet/kayak/tree/main
Project-URL: Issues, https://github.com/teilomillet/kayak/issues
Project-URL: Changelog, https://github.com/teilomillet/kayak/blob/main/CHANGELOG.md
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: httpx<1,>=0.28
Requires-Dist: pydantic<3,>=2.10
Provides-Extra: local
Requires-Dist: torch<3,>=2.6; extra == "local"
Requires-Dist: transformers<5,>=4.51; extra == "local"
Requires-Dist: huggingface-hub<1,>=0.30; extra == "local"
Provides-Extra: serve
Requires-Dist: kayak[local]; extra == "serve"
Requires-Dist: fastapi<1,>=0.115; extra == "serve"
Requires-Dist: uvicorn<1,>=0.30; extra == "serve"
Provides-Extra: test
Requires-Dist: pytest<10,>=8; extra == "test"
Requires-Dist: hypothesis<7,>=6.130; extra == "test"
Requires-Dist: ruff>=0.11; extra == "test"
Requires-Dist: mypy<3,>=2.3; extra == "test"
Requires-Dist: fastapi<1,>=0.115; extra == "test"
Requires-Dist: uvicorn<1,>=0.30; extra == "test"
Requires-Dist: build; extra == "test"
Requires-Dist: twine; extra == "test"
Provides-Extra: bench
Requires-Dist: pyperf<3,>=2.9; extra == "bench"
Requires-Dist: fastapi<1,>=0.115; extra == "bench"
Dynamic: license-file

# Kayak

**Typed AI decisions for Python.** Classify text, route requests, rank candidates,
and ask structured questions using a local model or a service you operate.

[Quickstart](#quickstart) · [Documentation](docs/README.md) · [Examples](examples/README.md) · [Contributing](CONTRIBUTING.md)

[![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-3776AB)](pyproject.toml)
[![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-16a085)](LICENSE)

Give Kayak text state, named questions, and candidate descriptions. It returns
validated answers, the underlying distributions, and model identity. Your
application decides how to use the result.

| Operation | Result |
| --- | --- |
| `decide` with `Choice` | A supplied candidate ID, scores, and relative shares |
| `judge` with `Choice`, `Noul`, or `Score` | Named typed answers, including binary shares and rubric averages |
| `rank` | Supplied candidates in score order, with stable ties |

The same operations are available on a local `Model`, `Client`, and `AsyncClient`.
Optional [Laya and Jev adapters](docs/provider-adapters.md) use the same named
questions while preserving each provider's result semantics.

## Quickstart

**Kayak 0.4.0** requires Python 3.11+. Install it in your project with
[uv](https://docs.astral.sh/uv/):

```sh
uv add 'kayak==0.4.0'
```

The base package provides typed values, HTTP clients, and evaluation. Add the
`local` extra for local inference or `serve` for the HTTP service. See
[release validation](docs/release.md) for the tested scope and remaining model
and hardware checks.

For the runnable examples below, download and extract the
[source distribution](https://pypi.org/project/kayak/0.4.0/#files). It includes
the documentation, examples, tests, and validation tools:

```sh
cd kayak-0.4.0
uv sync
```

Check the client integration without a model, service, or accelerator:

```sh
uv run -m examples.mock_integration
```

This command uses a simulated HTTP response. To run actual inference, use a
local model or connect to an existing Kayak service as shown below.

### Make a local decision

The default model is [CLM-v0.1-8B](https://huggingface.co/Contrastive-LM/CLM-v0.1-8B).
The first load downloads approximately 16 GB of encoder weights and 76 MB of
projection heads. Runtime memory exceeds the weight size; check the
[hardware guide](docs/validation.md) before loading.

Save this as `decide.py` in the checkout:

```python
import kayak
from kayak import Choice

questions = {
    "department": Choice(
        instructions="Which team should handle this request?",
        criteria={
            "billing": "Charges, invoices, and refunds",
            "technical": "Bugs and service outages",
        },
    )
}

with kayak.load(device="auto") as model:
    result = model.decide(
        state="I was charged twice for my subscription.",
        questions=questions,
    )

answer = result.answers["department"]
print(answer.choice)
print(answer.probabilities)
print(result.model.fingerprint)
```

```sh
uv run --extra local decide.py
```

Keep the model context open to reuse the loaded weights. `device="auto"` selects
available CUDA, then MPS, then CPU. Explicit device, precision, cache, and batch
settings are described in the [API reference](docs/api.md).

## Serve once, call from your application

Start a service on a machine with sufficient memory:

```sh
uv run --extra serve kayak serve --device auto
```

After loading and a readiness inference, it listens on `http://127.0.0.1:8000`.
In the quickstart program, replace the model context with a client context:

```python
with kayak.Client(base_url="http://127.0.0.1:8000") as client:
    result = client.decide(
        state="I was charged twice for my subscription.",
        questions=questions,
    )
```

The base client requires no inference libraries. In another Python project,
install it with `uv add 'kayak==0.4.0'`. Async applications use
`async with kayak.AsyncClient(...)` and await the same operations.

The service admits one inference request at a time and returns 503 when busy.
Clients make one attempt per call. Configure authentication, TLS at your network
boundary, and timeouts using the [serving guide](docs/serving.md).

## Use retrieved evidence

Pass your query and retrieved passages as text `state`, then ask named questions
with `judge`. The [RAG decision example](examples/rag_decisions.py) shows
Choice, Noul, and Score together. Your application owns retrieval and any text
generation. [RAG evaluation](docs/rag-evaluation.md) checks recorded retrieval,
reranking, context, and answers; the [experiment guide](docs/rag-experiments.md)
covers configuration, repeated runs, and quality gates.

## Evaluate the result

CLM scores are scaled cosine similarities. Probabilities are relative shares
among the supplied candidates, not calibrated confidence. A candidate is selected
even when every option is unsuitable; application thresholds and fallback rules
need evaluation against reviewed labels.

Use the [evaluation API](docs/evaluation-python.md) for your data and the
[use-case evaluation map](examples/evaluations/README.md) for starter datasets
and application checks. Hardware validation, numerical conformance, and task
quality are separate evidence; their current scope is recorded in the
[release checklist](docs/release.md).

## Documentation

The [documentation index](docs/README.md) organizes guides by integration,
operation, evaluation, and contribution.

| Need | Reference |
| --- | --- |
| Types, inputs, results, and errors | [Python API](docs/api.md) · [Typed judgments](docs/typed-judgments.md) |
| Files, pipes, and JSON requests | [CLI](docs/cli.md) |
| Service operation and upgrades | [Serving](docs/serving.md) · [Diagnostics](docs/diagnostics.md) · [Compatibility](docs/compatibility.md) |
| Provider integration | [Laya and Jev](docs/provider-adapters.md) · [Migration](docs/migrating.md) |
| Implementation and model behavior | [Architecture](docs/architecture.md) · [Model contract](docs/model-contract.md) |
| Runnable integrations | [Examples](examples/README.md) |
| Coding assistant context | [Assistant guide](docs/using-with-agents.md) · [llms.txt](llms.txt) |

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, checks, bug reports,
and pull requests. Code changes follow the [engineering conventions](docs/engineering.md).

## License

Kayak is licensed under [Apache 2.0](LICENSE). It builds on
[Contrastive Language Models](https://github.com/Contrastive-LM/CLM) and the
Qwen3 encoder. See [NOTICE](NOTICE) for attribution. Model weights are downloaded
separately under their upstream licenses.
