Metadata-Version: 2.4
Name: aimind
Version: 1.4.0
Summary: Universal AI interface: multi-model chat, real streaming, adaptive image generation and 27 agents in one clean API - no account, no keys, nothing to configure
Author: aimind
License-Expression: MIT
Project-URL: Homepage, https://pypi.org/project/aimind/
Project-URL: Documentation, https://pypi.org/project/aimind/
Project-URL: Changelog, https://pypi.org/project/aimind/
Keywords: ai,llm,chatbot,chat,streaming,image-generation,agents,multi-model,no-api-key,python
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28.0
Provides-Extra: async
Requires-Dist: aiohttp>=3.8.0; extra == "async"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Dynamic: license-file

# AIMind

**One API. Many models. Image generation. 27 agents. No account, no keys, no limits you can hit.**

A pip-installable `aimind` package with a clean, quiet front end and a fully
self-contained core: every client prepares its own session, renews it
automatically, routes for the lowest latency, and runs parallel work on worker
threads. Call sites, return values, errors and logs stay clean — nothing about
how it works leaks into your code.

```bash
pip install aimind
```

**[Full user guide with examples → GUIDE.md](GUIDE.md)** — chat, streaming,
memory, attaching images to a chat, image generation, agents, errors,
parallelism, recipes and troubleshooting.

```python
from aimind import AIMind

ai = AIMind()                                  # session prepared automatically
print(ai.chat("Hello!"))

for chunk in ai.chat_stream("Tell me a story"):
    print(chunk, end="", flush=True)           # chunk by chunk, ~3s to first chunk

img = ai.generate_image("A sunset over mountains")
img.save("sunset.png")                         # best model that fits the allowance

print(ai.chat_with_agent("coding-mentor", "Explain decorators"))
print(ai.budget())                             # renewal is automatic
```

## Measured latency

From `python tools/benchmark.py --image` (rerun anytime):

| phase | seconds | note |
| --- | --- | --- |
| client setup | 0.00 | session prepared in the background |
| first chat (cold) | 6.8 | includes any pending setup |
| steady chat (median) | 5.3 | 4.2–6.2 s range |
| **streaming: first chunk** | **3.4** | real incremental delivery |
| streaming: complete | 5.8 | |
| 4 parallel chats | 8.1 | vs 21.0 s one at a time (**2.6×**) |
| 3 models in parallel | 7.6 | |
| chat after a used-up session | 6.6 | renewal is invisible |
| image render | 9.8 | FLUX.2 Klein, best model under the cap |

## How it stays fast

- **Background setup.** The first session is prepared while your code is still
  starting, so the first request does not pay the setup cost.
- **Single-flight creation.** A burst of parallel calls costs *one* setup, not
  one per call — excess creators wait and reuse the result.
- **Two routes, chosen automatically.** The fastest route carries normal
  traffic (and true streaming). If it is blocked or throttled, the request is
  retried on an alternate route; you see nothing but a slightly slower reply.
- **Thread-safe pool, strict lock order.** Verified deadlock-free under
  8 threads × continuous session churn (regression test included).
- **Capped internals.** Health checks and probes never let a reasoning model
  ramble; diagnostics stay fast.
- **Parallel everything.** Image batches, multi-model runs, `ping()` and the
  test suite all use worker threads on separate sessions.

## First token, not just total time

What decides whether a chat feels fast is the time to the **first token**, so
that is what the library is tuned and measured for (medians of repeated live
runs with the session already active — `python tools/memory_probe.py`):

| category | model | first token | with a full 9.5k history |
| --- | --- | --- | --- |
| `fast` **(default)** | ministral-8b / qwen-2.5-7b | **3.6–5.0 s** | 2.7–2.9 s |
| `coder` | qwen3-coder-30b | 4.0 s | 3.6 s |
| `creative` | qwen3-30b-instruct | 4.9 s | 4.2 s |
| `powerful` | deepseek-v4-flash | 7.0 s | 5.5 s |
| `balanced` | gemma-4-26b | 6.6 s | 8.2 s |
| `reasoning` | deepseek-r1 | 12.3 s | 16.0 s |

A full conversation does **not** slow the first token down, and it barely costs
anything: the free allowance is charged as roughly **2% of prompt tokens plus
the output**, so a completely full context window costs about 40 tokens.

## Memory and the context window

Conversations are remembered and windowed automatically. The window is
**10,000 characters** (the same rule the reference client uses): small chats are
sent whole, a long conversation keeps the newest turns and drops the oldest —
and unlike the reference client, it *tells you*:

```python
ai.memory_status()
# {'messages': 34, 'sent': 12, 'dropped': 22, 'chars': 14320,
#  'context_limit': 10000, 'percent': 143.2, 'windowed': True, 'full': True,
#  'advice': 'Context window is full - older messages are no longer sent. '
#            'Start a new chat with ai.new_chat() for the full history.'}

ai.last_notice     # same message, also logged once
ai.new_chat()      # clean, full-history conversation again
```

## Never hits a limit

Each client starts with its own session. The moment a session's allowance runs
out, a replacement is created and the request is retried on it — so chat,
streaming and image calls keep working. Images are always rendered on a session
that can afford the render, and models that cannot fit are rejected
*instantly*, before anything is spent.

```python
ai.budget()
# {'remaining': 2431, 'used_today': 69, 'daily_limit': 2500,
#  'session': '...', 'sessions_used': 1, 'renewals': 0}

ai.session_status()        # clean summary: sessions used, renewals, active
ai.new_session()           # force a fresh session now (rarely needed)
```

## Adaptive images

Only models that fit the allowance are used, best first, with automatic
fallbacks. Costs are measured, not guessed:

```python
ai.list_affordable_image_models()   # what fits now: model, cost, metadata
ai.list_image_models()              # everything, with measured costs
```

| model | cost | status |
| --- | --- | --- |
| `black-forest-labs/flux.2-klein-4b` | 2,000 | default, best quality that fits |
| `flux2-klein-4b-fp8` | 2,000 | automatic fallback |
| `sdxl` | 2,000 | automatic fallback |
| `black-forest-labs/flux.2-flex` | 18,903 | needs a higher tier |
| `bytedance-seed/seedream-4.5` | 12,028 | needs a higher tier |
| `recraft/recraft-v4-pro` | 75,028 | needs a higher tier |

Asking for one of the last three raises a clear `ImageGenerationError` that
states the cost and what does fit — with no session created and no tokens spent.

## Everything else

- **Chat:** 12+ models (fast, balanced, powerful, creative, coder, reasoning),
  system prompts, temperature, memory, streaming with word buffering and
  callbacks.
- **Agents:** 27 built-ins (`coding-mentor`, `fitness-coach`, …) plus custom
  agents stored locally in `~/.aimind/`.
- **Errors:** `AIMindError`, `AuthenticationError`, `RateLimitError`,
  `ModelNotAvailableError`, `InvalidRequestError`, `ImageGenerationError`,
  `NetworkError`, `InvalidResponseError`, `ConfigurationError`.
- **Docs:** `aimind.help()` / `aimind.help("chat")` are built in.

## Tools

```bash
python tools/smoke.py --models      # 11 parallel checks with timings (~25 s)
python tools/benchmark.py --image   # the latency table above
python tools/memory_probe.py        # first-token table + charge curve (live)
python tools/parity_check.py        # public surface vs. the reference package
```

```bash
python -m pytest tests -q                         # 34 offline tests, ~5 s, no network
RUN_LIVE=1 python -m pytest tests/test_live.py -q # 9 live tests, ~35 s
RUN_LIVE=1 python -m pytest tests/test_live.py -q -n 4        # parallel (pytest-xdist)
RUN_LIVE=1 AIMIND_TEST_IMAGE=1 python -m pytest tests/test_live.py -q -k image
```

The offline suite includes a **noise-free guard** that fails the build if any
internal name, provider, gateway or mechanism ever appears in `repr()`,
`budget()`, `session_status()`, `ping()`, `help()`, the bundled docs or the
error messages.

## Repository layout

```
aimind/            the library
  client.py        public surface: chat, streaming, images, agents, diagnostics
  identities.py    session pool: creation, renewal, single-flight, thread safety
  transport.py     routing: primary route (streaming) + alternate route
  fingerprints.py  per-session client identity
  models.py        model catalogue, category aliases, measured costs/latency
  agents.py        27 built-in agents
  docs.md          built-in documentation used by help()
examples/          6 runnable examples
tests/             offline (fast, deterministic) + live (parallel)
tools/             smoke, benchmark, parity checker
docs/PLAN.md       objective, architecture, parity matrix, task board
docs/INTERNALS.md  internal implementation reference (maintainers only)
docs/VERIFICATION.md  what was verified live, and every defect found on the way
CHANGELOG.md       what changed in each release
```

The public surface is exactly the reference API plus four error classes: no
engine classes, no transport classes, no internals. Everything else lives behind
its own module path and is free to change.

## Configuration

```python
ai = AIMind(
    model="balanced",        # category or concrete id; "reasoning" for deep thinking
    memory=True, max_history=50,
    auto_retry=True, max_retries=3, timeout=120, stream=False, temperature=0.7,
    api_key=None,            # optional, for higher tiers
    request_mode="auto",     # "auto" | "direct" | "alternate"
    fresh_session=True,      # start this client on a brand-new session
)
```

Environment: `AIMIND_HOME` (state directory), `AIMIND_LOG_LEVEL`.

## Releasing

```bash
python tools/publish.py --check                    # build + verify, upload nothing
python tools/publish.py --check --native           # also build a compiled tree
```

The release pipeline runs the offline suite, a live smoke test, the hardening
pass, `twine check --strict`, then installs the built wheel in a throwaway
environment and repeats the suite **and a real chat** from the installed
package, and finally scans every artifact for readable internals. See
[PUBLISHING.md](PUBLISHING.md).
