Metadata-Version: 2.4
Name: thx02
Version: 1.0.0
Summary: THX-02: an open decision model that thinks. Typed questions in, calibrated probabilities out. API client, CLI (Termux too) and local runtime.
Author: HAL-X
License: Apache-2.0
Project-URL: Homepage, https://huggingface.co/HAL-X-AI/THX-02
Project-URL: API docs, https://api.hal-x.ai/docs/thx-02/
Project-URL: Status, https://api.hal-x.ai/status/thx
Project-URL: ModelScope, https://modelscope.ai/models/HAL-X/THX-02
Keywords: decision model,classification,llm,calibration,thinking,routing,termux,hal-x,thx
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Operating System :: Android
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Provides-Extra: local
Requires-Dist: torch>=2.6; extra == "local"
Requires-Dist: transformers>=5.17; extra == "local"
Requires-Dist: safetensors; extra == "local"
Requires-Dist: pillow; extra == "local"
Requires-Dist: torchvision; extra == "local"
Requires-Dist: huggingface_hub; extra == "local"
Provides-Extra: server
Requires-Dist: thx02[local]; extra == "server"
Requires-Dist: aiohttp; extra == "server"
Requires-Dist: httpx; extra == "server"
Provides-Extra: fast
Requires-Dist: thx02[local]; extra == "fast"
Requires-Dist: flash-linear-attention==0.5.2; extra == "fast"
Provides-Extra: thinker
Requires-Dist: thx02[local]; extra == "thinker"
Requires-Dist: peft; extra == "thinker"
Requires-Dist: vllm>=0.11; extra == "thinker"
Dynamic: license-file

# thx02

**THX-02** is an open decision model by [HAL-X](https://api.hal-x.ai/docs/thx-02/). You give it a state (a message,
a document, a JSON record or up to four images) and typed questions; it returns a calibrated probability for every
option. When a question needs a calculation or a chain of logic, it can write a short thought first and decide with it.

- **65.06** on Decision Index 0.3 with thinking, **63.83** without: above Jev (57.96) and 27B decision models
- 4.5 B parameters, Apache-2.0, multilingual (Azerbaijani, Russian, English, Turkish, Kazakh, Uzbek, Chinese and more)
- 50 to 150 ms per decision on one GPU; thinking only when it changes the answer

This package gives you three things:

| Install | What you get |
|---|---|
| `pip install thx02` | API client and the `thx02` command. No dependencies: works on servers, laptops and Android (Termux) |
| `pip install "thx02[local]"` | Also run THX-02 on your own GPU or CPU |
| `pip install "thx02[server]"` | Also run your own THX-02 HTTP server (`thx02 serve`) |

Links: [weights on Hugging Face](https://huggingface.co/HAL-X-AI/THX-02) ·
[API reference](https://api.hal-x.ai/docs/thx-02/) · [status](https://api.hal-x.ai/status/thx) ·
[ModelScope](https://modelscope.ai/models/HAL-X/THX-02)

---

## 1. Quickstart (API)

```bash
pip install thx02
export HALX_API_KEY=sk-...          # your HAL-X API key (optional on the free tier, which is limited per IP)
thx02 "Salam, kartımdan iki dəfə pul çıxılıb, geri qaytarın" \
  --choice "team=billing:charges and refunds,support:technical problems,sales:buying a product" \
  -i "Which team should handle this?" --yesno "Does the customer ask for a refund?"
```

```
team
  › billing                  ███████████████████████   96.0%
    support                  █                          3.5%
    sales                                               0.4%

Does the customer ask for a refund
  › yes                      ███████████████████████   95.8%
    no                       █                          4.2%

THX-02 · 126 ms
```

The same from Python:

```python
from thx02 import Client, choice, noul, score

thx = Client()                       # reads HALX_API_KEY
out = thx.decide(
    "Salam, kartımdan iki dəfə pul çıxılıb, geri qaytarın zəhmət olmasa.",
    {
        "team":   choice("Which team should handle this?", billing="Charges and refunds",
                         support="Technical problems", sales="Buying a product"),
        "refund": noul("Does the customer ask for a refund?"),
        "anger":  score("How frustrated is the customer?", ["calm", "annoyed", "angry"]),
    },
)
print(out["answers"]["team"]["choice"])           # billing
print(out["answers"]["refund"]["noul"])           # 0.957
```

## 2. Question types

| Type | Builder | Answer |
|---|---|---|
| `choice` | `choice("Which team?", billing="Charges and refunds", support="Technical problems")` or `choice("Which team?", ["billing", "support"])` | `choice`, `probabilities`, `confidence` |
| `noul` | `noul("Does the customer ask for a refund?")` | `noul`: probability of yes |
| `score` | `score("How urgent?", ["low", "medium", "high"])` | `probabilities` per level, `score` (expected level), `legend` |

Descriptions are what the model reads, so write them as short definitions. Up to 64 questions per state and 255
options per question. Ask everything about one state in one call: the questions share one read.

`Client.top(answer)` returns the winning `(label, probability)` of any answer.

## 3. Thinking

```python
out = thx.decide(
    "Applicant income $4,200/month; rent $1,500; car loan $450; cards $250; new loan payment $600. "
    "Policy: total debt payments (including rent) must not exceed 50% of income.",
    {"policy": choice("Does the application pass the bank policy?", passes="Within the limit", fails="Over the limit")},
    think=True, return_thoughts=True,
)
a = out["answers"]["policy"]
print(a["choice"], a["thought"])
# fails  Total monthly debt payments = $1,500 + $450 + $250 + $600 = $2,800. 50% of income = $2,100. $2,800 > $2,100 ...
```

| `think` | Behaviour | Latency |
|---|---|---|
| `False` (default) | Direct answer | 50 to 150 ms |
| `"auto"` | Thinks only on questions that are unsure and need reasoning | median ~80 ms |
| `True` | Thinks on almost every question | 0.5 to 2 s |

`out["usage"]` reports `input_tokens`, `output_tokens` (thought tokens) and `thoughts`.

## 4. Images

```python
from thx02 import Client, noul, choice

thx = Client()
out = thx.decide("", {"legible": noul("Is the receipt fully legible?"),
                      "total": choice("What is the total?", ["8.85", "8.56", "6.56"])},
                 images=["receipt.jpg"])         # paths, bytes or data URIs; up to 4
```

## 5. Batch

```python
results = thx.batch([
    ("My package never arrived", {"team": choice("Which team?", billing="Charges", shipping="Deliveries")}),
    ("I was charged twice",      {"team": choice("Which team?", billing="Charges", shipping="Deliveries")}),
], think="auto")
print([r["answers"]["team"]["choice"] for r in results])     # ['shipping', 'billing']
```

Up to 1,024 states per call; results come back in order; a failed item is `{"error": ...}` in its place.

## 6. The `thx02` command

```bash
thx02 "text" --choice team=billing,support,sales          # pick one (descriptions make it sharper: below)
thx02 "text" --choice "team=billing:charges and refunds,support:technical problems"   # with descriptions
thx02 "text" --yesno "Is this phishing?" --yesno "Is it urgent?"
thx02 "text" --score urgency=low,medium,high
thx02 "Income 4200, debts 2800, limit 50%. Pass?" --choice verdict=pass,fail --think on --thoughts
thx02 --image photo.jpg --yesno "Is the egg cracked?"
thx02 --batch tickets.txt --choice team=billing,shipping > answers.jsonl   # one state per line
echo "I want my money back" | thx02 --yesno "Refund request?"              # stdin
thx02                                                                       # interactive mode
thx02 models                                                                # models your key can use
thx02 "text" --json                                                         # raw JSON
```

Options: `--model thx-01` uses THX-01, `--server URL` uses your own server, `--key` overrides `$HALX_API_KEY`,
`--tta 4` averages choice options over four orders.

## 7. Android: Termux (and tmux)

THX-02 works from a phone. Install [Termux](https://termux.dev) from F-Droid or GitHub, then:

```bash
pkg update -y && pkg install -y python
pip install thx02
echo 'export HALX_API_KEY=sk-...' >> ~/.bashrc && source ~/.bashrc
thx02 "Kargom gelmedi, param ne zaman iade edilir?" --choice team=billing,shipping,support
```

Keep a decision session open across app switches with tmux:

```bash
pkg install -y tmux
tmux new -s thx                                  # start a session
thx02 --choice intent=question,complaint,order   # interactive: type messages, get decisions
# detach: Ctrl-b then d       re-attach later: tmux attach -t thx
```

A script that classifies every SMS you paste, in a tmux pane, is one line:
`while read -r s; do thx02 "$s" --yesno "Is this a scam?" ; done`.

Running the model itself on a phone is experimental: it needs an aarch64 phone with 12 GB+ RAM and about 9 GB of free
storage, inside an Ubuntu userland:

```bash
pkg install -y proot-distro && proot-distro install ubuntu
proot-distro login ubuntu -- bash -c '
  apt-get update && apt-get install -y python3 python3-venv
  python3 -m venv /opt/thx02 && . /opt/thx02/bin/activate
  pip install torch --index-url https://download.pytorch.org/whl/cpu && pip install "thx02[local]"
  THX02_DEVICE=cpu thx02 --local HAL-X-AI/THX-02 "I was charged twice" --choice team=billing,shipping'
```

## 8. Run THX-02 locally

```bash
pip install "thx02[local]"                     # add [fast] on NVIDIA GPUs for the compiled kernels
```

```python
from thx02 import THX02
m = THX02.load("HAL-X-AI/THX-02")              # downloads the weights once (about 9 GB); or a local folder
m.decide("I was charged twice", {"refund": {"type": "noul", "instructions": "Refund request?"}})
```

One RTX 4090 (24 GB) is enough. `device="cpu"` works on CPU (slower). Thinking needs the think adapter served by vLLM
(`pip install "thx02[thinker]"`, see the model card).

## 9. Run your own server

```bash
pip install "thx02[server]"
thx02 serve --model HAL-X-AI/THX-02 --port 8200 --gpus 0          # add --thinker-url to enable thinking
thx02 --server http://localhost:8200 "I was charged twice" --yesno "Refund request?"
```

The server speaks the same API as api.hal-x.ai (`/v1/decide`, `/v1/decide/batch`, `/v1/systemone`, `/health`).

## 10. Errors

The client raises `thx02.APIError` with `status`, `code`, `message` and `request_id`. It retries 429, 502, 503 and 504
with back-off. Common cases: `401` no or invalid key, `403` the key does not grant `thx-02`, `400` a malformed question
(the message says what to fix). Full reference: <https://api.hal-x.ai/docs/thx-02/>.

## License

Apache-2.0. See `LICENSE` and `NOTICE`.
