Metadata-Version: 2.4
Name: oxygenai
Version: 0.1.0
Summary: OxygenAI - locally-powered terminal AI coding assistant (Ollama + Qwen2.5-coder)
License: MIT
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: rich>=13.7
Requires-Dist: httpx>=0.28
Requires-Dist: markdown-it-py>=3
Requires-Dist: pygments>=2.17
Provides-Extra: ui
Requires-Dist: prompt_toolkit>=3.0.50; extra == "ui"
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: pytest-mock; extra == "dev"
Dynamic: license-file

# OxygenAI

A **locally-powered terminal AI coding assistant** for Windows. The brain is
[Ollama](https://ollama.com) running the `qwen2.5-coder` model; the agent is
our own tool-calling loop — it can read/write files in your project, list
directories, run shell commands (with confirmation), and run your test suite.

## Quickstart

### 1. Install Ollama + pull the model
```bat
scripts\install_ollama.bat
```
This installs Ollama (winget first, direct download fallback), waits for the
server on `127.0.0.1:11434`, then pulls `qwen2.5-coder:3b` (~2 GB).

> Want a smarter (but larger) model? After setup run:
> `oxygenai /model qwen2.5-coder:7b` — needs ~5 GB RAM.

### 2. Launch OxygenAI
Double-click `run_oxygenai.bat`, or from a terminal:
```bat
cmd /c run_oxygenai.bat
```
First run creates a `.venv`, installs dependencies, then starts the REPL.

### 3. Chat
```
oxygenai> write fib.py that prints the first 20 numbers
```
The agent streams its answer, then calls `write_file`, runs commands after
you approve, runs tests with the detected runner, and saves every session.

Check health any time:
```bat
oxygenai doctor
```

## Slash commands

| Command | What it does |
|---|---|
| `/new` | Start a fresh session |
| `/model <name>` | Switch model (e.g. `/model qwen2.5-coder:7b`) |
| `/cwd <dir>` | Change working directory |
| `/sessions` | List past sessions |
| `/paste` | Multi-line input (finish with a line `END`) |
| `/clear` | Clear screen |
| `/auto on\|off` | Toggle auto-confirm for shell commands |
| `/exit` | Quit (also Ctrl-D) |

CLI subcommands: `oxygenai doctor`, `oxygenai sessions list|show|rm <id>`,
`oxygenai config`.

## How it works

- **Model**: local via Ollama's native `/api/chat` (SSE streaming). We use raw
  `httpx`, not the `ollama` SDK, so we own the stream parsing.
- **Agent loop**: model → tool call → execute → result fed back → repeat, capped
  at `max_tool_iterations` (8). Denied commands aren't errors — the model sees
  `status: denied` and adapts.
- **Safety**: file tools are sandboxed to the working directory (`resolve_within`
  rejects `..` and symlink/junction escapes); shell commands pass a denylist →
  allowlist → interactive `y/N/a` gate.
- **Sessions**: JSONL under `%USERPROFILE%\.oxygenai\sessions`; resumed verbatim.
- **UI**: `rich` live panel with throttled incremental markdown, code-fence
  tracking, tool banners, usage footer.

## Project-type detection

OxygenAI inspects the working directory each turn:
- `pyproject.toml` / `requirements*.txt` / `.py` files → **Python**
  (tests: `python -m pytest -v`)
- `package.json` / `.js/.ts/.jsx` → **Node**
  (tests: the `scripts.test` value, else `npm test`)
- Both / neither → **mixed** / **generic**

## Troubleshooting

**`oxygenai doctor` shows "server not reachable"**
Start Ollama (tray icon) or run `ollama serve`, then re-run.

**Model not pulled**
`ollama pull qwen2.5-coder:3b`.

**Mojibake / `?` box glyphs**
We set `PYTHONUTF8=1` in the launcher. Use Windows Terminal (not legacy cmd
with raster fonts) for best look.

**Slow first response**
Cold model load takes 30–60 s on CPU. The UI shows a spinner.

**Health after failure**
`oxygenai doctor` prints ✓/✗ for the four checks.

## Auto device detection

OxygenAI auto-detects the machine on startup and picks the best model +
settings for it — pure-stdlib, so it works on Windows, Linux, macOS, and
mobile **Android (Termux) / iOS** (the `.bat`/`.exe` are Windows-only
shortcuts; the core `python -m oxygenai` runs anywhere Python runs).

| Detected tier | RAM | model | num_ctx |
|---|---|---|---|
| **lite** | < 5.5 GB | `qwen2.5-coder:1.5b` | 2048 |
| **mid** | 5.5–11 GB | `qwen2.5-coder:3b` | 3072 |
| **high** | > 11 GB (+GPU) | `qwen2.5-coder:7b` | 8192 |

Check what it chose:
```bat
oxygenai device
```

Your own `config.json` / `OXYGENAI_*` env overrides still win over the
auto-detection (it only fills what you haven't explicitly set).

## Low-RAM defaults

OxygenAI ships tuned for modest hardware (8 GB RAM, CPU-only):

| Setting | Default | Why |
|---|---|---|
| `model` | `qwen2.5-coder:3b` | fits ~2 GB in RAM; 1.5b is faster but weaker code |
| `num_ctx` | `3072` | fast prompt processing; enough for agent turns |
| `keep_alive` | `15m` | keeps the model hot so the next prompt is fast; `/unload` frees it |
| `num_threads` | 4 (physical cores) | avoids OMP oversubscription that stalls the UI |
| options | `num_batch: 128` | snappier first token on a 4-core CPU |
| `max_history_messages` | `40` | bounded chat window sent to Ollama each turn |
| `max_redraw_interval_ms` | `500` | less CPU churn in the renderer |

You can override per-run via env:
```bat
set OXYGENAI_NUM_CTX=2048
set OXYGENAI_KEEP_ALIVE=0
set OXYGENAI_NUM_THREADS=4
oxygenai repl
```
Or persistently in `%USERPROFILE%\.oxygenai\config.json`. `/unload` in the
REPL frees the model from RAM immediately (useful before leaving your PC).

## Development

```bat
.venv\Scripts\python.exe -m pytest -q
```
Unit tests mock Ollama (no network, no model needed).

### Roadmap
- Multi-model routing (claude-api provider mixing)
- Diff preview before `write_file`
- `.oxygenai` per-project config
