Metadata-Version: 2.4
Name: logitly
Version: 0.2.0
Summary: CUDA LLM decisions from restricted next-token logits across inference runtimes
License-Expression: MIT
License-File: LICENSE
Requires-Python: <3.14,>=3.11
Provides-Extra: benchmark
Requires-Dist: datasets==4.4.2; extra == 'benchmark'
Requires-Dist: huggingface-hub==1.20.1; extra == 'benchmark'
Requires-Dist: matplotlib==3.10.8; extra == 'benchmark'
Requires-Dist: numpy==2.3.5; extra == 'benchmark'
Requires-Dist: psutil==7.2.2; extra == 'benchmark'
Provides-Extra: browser
Requires-Dist: browser-harness==0.1.13; extra == 'browser'
Provides-Extra: llama-cpp
Requires-Dist: llama-cpp-python==0.3.16; extra == 'llama-cpp'
Provides-Extra: quantized
Requires-Dist: compressed-tensors==0.18.0; extra == 'quantized'
Provides-Extra: test
Requires-Dist: pytest-cov==7.0.0; extra == 'test'
Requires-Dist: pytest==9.0.2; extra == 'test'
Provides-Extra: transformers
Requires-Dist: accelerate==1.14.0; extra == 'transformers'
Requires-Dist: huggingface-hub==1.20.1; extra == 'transformers'
Requires-Dist: safetensors==0.6.2; extra == 'transformers'
Requires-Dist: torch==2.10.0; extra == 'transformers'
Requires-Dist: transformers==5.12.1; extra == 'transformers'
Provides-Extra: vllm
Requires-Dist: transformers==5.12.1; extra == 'vllm'
Requires-Dist: vllm==0.26.0; extra == 'vllm'
Description-Content-Type: text/markdown

# Logitly

Logitly turns a compatible LLM into a decision model. Give it a state, a question, and named choices; it returns a probability distribution using one forward pass and the model's existing LM-head logits. The model weights stay unchanged, and no answer tokens are generated.

## Install

Python 3.11–3.13 and an NVIDIA CUDA GPU are required for inference.

```bash
python -m pip install "logitly[transformers]"
```

For supported quantized checkpoints, also install `logitly[quantized]`. The `vllm` and `llama-cpp` extras are available for their respective GPU runtimes; use separate environments when their dependency versions differ.

## Example

```python
from logitly import DecisionModel

with DecisionModel.from_pretrained("lfm") as model:
    result = model.choice(
        state={"amount": 9700, "device": "unknown"},
        question="What action should we take?",
        choices={
            "close": "Close as benign",
            "review": "Request analyst review",
            "block": "Block immediately",
        },
    )

print(result.choice)
print(result.probabilities)
```

The `lfm`, `glm`, and `qwen` aliases select pinned checkpoints. Compatible Hugging Face model IDs and local checkpoints are also accepted. `model.noul(state, question)` returns yes/no probabilities; `model.score(state, question, levels)` returns an ordered distribution and expected score; `model.decide_many(requests, batch_size=...)` processes batches.

Logitly selects single-token label logits after the assistant answer boundary and normalizes only those logits. It does not use `generate()`, change model weights, or add a new prediction head. Returned confidence is the maximum choice probability and is not a calibrated correctness guarantee.

The CLI provides `logitly validate`, `logitly playground`, and `logitly benchmark`.
