Metadata-Version: 2.4
Name: fixpi
Version: 1.1.1
Summary: LLM-Powered Remote OS Repair Agent — SSH + LLM diagnostic tool for any Linux device
Author-email: Tom Sapletta <tom@sapletta.com>
Maintainer-email: Tom Sapletta <tom@sapletta.com>
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/zlecenia/c2004/tree/main/fixPI
Project-URL: Repository, https://github.com/zlecenia/c2004/tree/main/fixPI
Project-URL: Documentation, https://github.com/zlecenia/c2004/tree/main/fixPI#readme
Project-URL: Bug Tracker, https://github.com/zlecenia/c2004/issues
Project-URL: Changelog, https://github.com/zlecenia/c2004/tree/main/fixPI/CHANGELOG.md
Keywords: raspberry-pi,ssh,llm,diagnostics,repair,display,devops,automation,rest-api
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: System Administrators
Classifier: Intended Audience :: Developers
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: System :: Systems Administration
Classifier: Topic :: System :: Hardware
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: paramiko>=3.4.0
Requires-Dist: litellm>=1.40.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: click>=8.0
Requires-Dist: rich>=13.7.0
Provides-Extra: clickmd
Requires-Dist: clickmd>=1.0.0; extra == "clickmd"
Provides-Extra: server
Requires-Dist: fastapi>=0.115.0; extra == "server"
Requires-Dist: uvicorn[standard]>=0.32.0; extra == "server"
Requires-Dist: websockets>=12.0; extra == "server"
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
Requires-Dist: black>=23.0.0; extra == "dev"
Requires-Dist: isort>=5.12.0; extra == "dev"
Requires-Dist: flake8>=6.0.0; extra == "dev"
Requires-Dist: mypy>=1.5.0; extra == "dev"
Requires-Dist: pre-commit>=3.0.0; extra == "dev"
Provides-Extra: test
Requires-Dist: pytest>=7.0.0; extra == "test"
Requires-Dist: pytest-cov>=4.0.0; extra == "test"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "test"
Requires-Dist: pytest-mock>=3.11.0; extra == "test"
Provides-Extra: docs
Requires-Dist: mkdocs>=1.5.0; extra == "docs"
Requires-Dist: mkdocs-material>=9.0.0; extra == "docs"
Requires-Dist: mkdocstrings[python]>=0.23.0; extra == "docs"
Dynamic: license-file

# fixpi — Remote OS Repair Agent

SSH into any Linux device, describe the problem, let the LLM diagnose and fix it.

```bash
fixpi -p "Docker won't start, cgroup error"           # one-liner
fixpi run -f /var/log/syslog -p "service crashing"    # attach log
fixpi run -d rpi3 -l groq -p "display not working"    # device + LLM profile
fixpi serve                                            # REST/WS API on :7771
```

## Quick Start

```bash
cd fixPI
cp .env.example .env
# Set: RPI_HOST, RPI_USER, RPI_PASSWORD, LLM_MODEL, GROQ_API_KEY

pip install -e ".[clickmd]"
fixpi                        # interactive menu
```

```bash
# .env minimum:
RPI_HOST=raspberrypi.local
RPI_USER=tom
RPI_PASSWORD=secret
LLM_MODEL=groq/llama-3.3-70b-versatile
GROQ_API_KEY=gsk_...
```

## CLI Reference

```text
fixpi [OPTIONS] COMMAND [ARGS]

Global options:
  -p, --prompt TEXT   Problem to fix (runs immediately without menu)
  -f, --file PATH     Log/error file to attach as context

Commands:
  run          Diagnose & fix via LLM agent
  diagnose     Diagnose only — no changes applied
  serve        Start REST/WebSocket API server
  config       Configure LLM provider & SSH wizard
  test         Test LLM connection
  list-models  Show all supported LLM providers & models
  list-devices Show configured device profiles

run / diagnose options:
  -p, --prompt TEXT    Problem description
  -f, --file PATH      Log file to include as LLM context
  -d, --device NAME    Device profile (~/.fixpi/devices/NAME.env)
  -l, --llm NAME       LLM profile (~/.fixpi/llm/NAME.env)

serve options:
  --host TEXT          Bind host [default: 0.0.0.0]
  --port INT           Bind port [default: 7771]
  --reload             Dev mode
```

### Examples

```bash
# Fix any problem:
fixpi -p "pydantic-core fails to install on Python 3.13"
fixpi run -p "Docker not starting" -f /var/log/syslog

# Diagnose without changes:
fixpi diagnose -p "why is systemd service crashing?"

# Multi-device:
fixpi run -d rpi3 -p "display black after reboot"
fixpi run -d rpi4-prod -l gemini -p "OOM killer active"

# Pipe log from stdin:
journalctl -u docker --since '1h ago' | fixpi run -f /dev/stdin

# REST API:
fixpi serve &
curl -X POST http://localhost:7771/run \
     -d '{"prompt": "fix display", "device": "rpi3"}' \
     -H 'Content-Type: application/json'
```

## Device & LLM Profiles

```bash
# Create device profiles in ~/.fixpi/devices/NAME.env
mkdir -p ~/.fixpi/devices ~/.fixpi/llm

cat > ~/.fixpi/devices/rpi3.env << 'EOF'
RPI_HOST=192.168.1.100
RPI_USER=tom
RPI_PASSWORD=secret
EOF

cat > ~/.fixpi/llm/groq.env << 'EOF'
LLM_MODEL=groq/llama-3.3-70b-versatile
GROQ_API_KEY=gsk_...
EOF

# Use:
fixpi run -d rpi3 -l groq -p "fix problem"
fixpi list-devices
```

## REST / WebSocket API

```bash
pip install 'fixpi[server]'   # fastapi + uvicorn
fixpi serve                   # http://localhost:7771
```

| Method | Endpoint | Description |
| ------ | -------- | ----------- |
| `POST` | `/run` | Start repair job → returns `job_id` |
| `POST` | `/diagnose` | Diagnose only |
| `GET` | `/status/{id}` | Job status + result |
| `GET` | `/jobs` | List all jobs |
| `GET` | `/devices` | List device profiles |
| `GET` | `/models` | List LLM providers/models |
| `WS` | `/ws/run` | Streaming via WebSocket |

## LLM Providers

Any [litellm](https://docs.litellm.ai/docs/providers)-compatible provider:

| Provider | Model example | Env key |
| -------- | ------------ | ------- |
| **Groq** | `groq/llama-3.3-70b-versatile` | `GROQ_API_KEY` |
| **OpenRouter** | `openrouter/google/gemma-3-27b-it:free` | `OPENROUTER_API_KEY` |
| **Anthropic** | `anthropic/claude-3-5-sonnet-20241022` | `ANTHROPIC_API_KEY` |
| **OpenAI** | `gpt-4o-mini` | `OPENAI_API_KEY` |
| **Gemini** | `gemini/gemini-2.0-flash-exp` | `GEMINI_API_KEY` |
| **Ollama** | `ollama/llama3.2` | *(none — local)* |

> **Note**: `groq/groq/llama-...` is automatically normalized to `groq/llama-...`

## What it fixes

Any Linux system problem accessible via SSH. Verified examples:

| Problem | Command |
| ------- | ------- |
| pydantic-core build fail (Python 3.13) | `fixpi run -p "pip install fails" -f /tmp/pip.log` |
| Docker cgroups error | `fixpi run -p "docker not starting"` |
| WaveShare DSI not detected | `fixpi run` (display mode) |
| Frontend build fail (npm/tsc) | `fixpi run -p "npm build fails" -f /tmp/build.log` |
| Systemd service crash | `fixpi run -p "service failing" -f /tmp/journal.log` |
| OOM killer active | `fixpi run -p "OOM killer killing app"` |

31 documented RPi examples: [examples/](examples/)

### Verified: RPi3 + WaveShare 7.9" DSI (kernel 6.12.x)

```ini
# /boot/firmware/config.txt — working config
dtoverlay=vc4-kms-v3d
# display_auto_detect=1   ← must be disabled
dtoverlay=vc4-kms-dsi-waveshare-panel,7_9_inch
hdmi_force_hotplug=1
```

*fixpi discovered this fix automatically by analysing kernel logs and dmesg.*

## Architecture

```text
fixPI/
├── pyproject.toml
├── Makefile
├── .env.example
├── examples/             ← 31 documented RPi problems + integration guide
│   └── integration/      ← bash/Python/REST/WS/CI examples
├── tests/
│   ├── test_agent.py
│   ├── test_cli.py
│   ├── test_diagnostics.py
│   ├── test_llm_agent.py
│   └── e2e/              ← Docker-based SSH e2e tests
└── fixpi/
    ├── __main__.py       ← CLI entry point (clickmd)
    ├── cli.py            ← interactive menu + _load_profiles()
    ├── agent.py          ← LLM decision loop (generic + display mode)
    ├── server.py         ← FastAPI REST/WS server (fixpi serve)
    ├── llm_agent.py      ← multi-provider LLM via litellm
    ├── ssh_client.py     ← paramiko SSH + reboot/reconnect
    └── diagnostics.py    ← system state collector
```

## Agent Modes

| Mode | How | Behaviour |
| ---- | --- | --------- |
| **Display** | `fixpi run` | Decision tree → LLM, targets display config |
| **Generic** | `fixpi run -p "..."` | Skips display tree, LLM gets your problem |
| **Log** | `fixpi run -f file` | Log content injected into LLM context |
| **Diagnose** | `fixpi diagnose` | Analysis only, no changes applied |

## Integration

See [examples/integration/README.md](examples/integration/README.md) for:

- Bash pipe / one-liners
- Python SDK
- REST API via curl
- WebSocket streaming (Node.js + Python)
- c2004 installation fallback
- Multi-device management
- CI/CD pipeline example

## License

Apache License 2.0 - see [LICENSE](LICENSE) for details.

## Author

Created by **Tom Sapletta** - [tom@sapletta.com](mailto:tom@sapletta.com)
