Metadata-Version: 2.4
Name: ploop
Version: 0.1.1
Summary: Ploop (Proactive Loop), a lightweight local proactive agent with pluggable model backends.
Project-URL: Homepage, https://github.com/ferdinandobons/ploop
Project-URL: Repository, https://github.com/ferdinandobons/ploop
Project-URL: Changelog, https://github.com/ferdinandobons/ploop/blob/main/CHANGELOG.md
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Provides-Extra: mlx
Requires-Dist: mlx-lm==0.31.3; extra == "mlx"
Requires-Dist: transformers==5.0.0; extra == "mlx"

# Ploop

**Ploop** stands for **Proactive Loop**. It is a **local, proactive, autonomous** AI agent
with a tiny pluggable model layer. By default it talks to a local OpenAI-compatible server
(Ollama, LM Studio, llama.cpp server, LocalAI, vLLM, etc.); on Apple Silicon it can also use
MLX as an optional backend. The agent decides on its own what to do on every cycle, and
everything is controllable from the `ploop` CLI.

The project rule is to stay **proactive, lightweight, and small**: prefer a few explicit
standard-library functions over agent frameworks, broad abstractions, or extra dependencies.
New code should earn its lines by directly improving the proactive loop, safety, or local
runtime behavior.

Ploop ships everything needed for the agent itself: CLI, state, tools, backend adapters, and
docs. It does **not** bundle model weights or start a model server for you. That is
intentional: model runtimes are large, platform-specific, and often already installed. Ploop
connects to an existing local runtime such as Ollama, LM Studio, llama.cpp server, LocalAI,
or vLLM.

On every "cycle" the agent reads its own open goals and recent history, asks the model —
without a specific prompt from the user — "what do you do now?", and the model picks a tool
to run (write a note, read/write a file, close a goal that's been reached, or just wait). In
`loop` mode this repeats at regular intervals, indefinitely: this is the autonomous mode,
meant to run in the background without supervision.

By default the agent operates in the directory where you launch it. Use `-C /path/to/project`
to point it at another directory; its state and notes live in that directory's hidden
`.ploop/` folder.

## Requirements

- Python 3.10+
- A model runtime:
  - Default/cross-OS: a local OpenAI-compatible server at `http://localhost:11434/v1`
    (Ollama's OpenAI endpoint works well).
  - Optional Apple Silicon path: MLX via `pip install "ploop[mlx]"`.

## Installation

Install from PyPI:

```bash
python3 -m pip install ploop
```

This installs the `ploop` CLI command with no mandatory model-runtime dependency.

For local development from this source checkout:

```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
```

The repo-local `./bin/ploop` wrapper also works for development.

## Quick start

If you already have a local OpenAI-compatible runtime serving `qwen3:4b` at
`http://localhost:11434/v1`, you can skip straight to `ploop run`.

With Ollama, pull the default model once and make sure the local server is running:

```bash
ollama pull qwen3:4b
ollama serve
```

Then, from the folder Ploop should work in:

```bash
ploop run "Inspect this folder and write a short note with the next useful step."
ploop status        # shows what it did
```

To run one cycle against another folder:

```bash
ploop -C /path/to/project run "Inspect this project and write the next useful step."
```

To let it run continuously in the background:

```bash
ploop loop "Monitor this folder and write useful notes when there is something worth doing next." --interval 60
```

For already saved goals, omit the goal text:

```bash
ploop run              # one cycle on saved open goals
ploop loop --interval 60  # continuous cycles on saved open goals
```

Generation can be tuned per run with `--max-tokens` (default `2048`, range `256`-`8192`)
and `--temperature` (default `0.0`, range `0.0`-`2.0`).

### Replacing a running loop

Only one continuous loop should be active per target directory. If you start another
`ploop loop` in the same directory, the new loop supersedes the old one:

```bash
ploop loop "New goal for this folder" --interval 30
```

The previous process notices the replacement through `.ploop/loop.json` and exits before its
next cycle, usually within one second while sleeping; if it had just received a model
response, it exits before executing that stale action. Previous open goals are marked
`superseded`, so the new loop starts from the new goal instead of mixing old and new work.
This keeps repeated launches simple: rerun `ploop loop ...` when you want to replace the
current loop goal.

For goals that create longer files, ask for short tool calls or incremental writes. Ploop
will report `invalid_tool_call` if the model emits truncated JSON, then feed that error into
the next cycle so the model can retry with a smaller `write_file` or `append_file` call.

## Model

The default backend is `openai`, pointing at `http://localhost:11434/v1` with model
`qwen3:4b`. This means Ploop sends OpenAI-compatible HTTP requests to a local runtime that
is already running on your machine. The Python package stays small and cross-OS because model
download, loading, GPU/CPU acceleration, and caching are handled by that runtime.

Ploop does not call a cloud service by default. It only uses a remote service if you
explicitly configure `--base-url` / `PLOOP_BASE_URL` to point at one.

```bash
ploop model show
ploop model set qwen3:4b --backend openai --base-url http://localhost:11434/v1
ploop run "Inspect this folder"
```

For MLX on Apple Silicon:

```bash
python3 -m pip install "ploop[mlx]"
ploop model set mlx-community/Qwen3-4B-Instruct-2507-4bit --backend mlx
ploop model show
```

Runtime priority is: CLI flags, saved project settings, environment variables, then defaults.
The relevant environment variables are `PLOOP_BACKEND`, `PLOOP_MODEL`, `PLOOP_BASE_URL`, and
`PLOOP_API_KEY`.

## Documentation

The full reference (CLI commands, tools available to the model, architecture, security,
testing, troubleshooting) lives in the [`docs/`](docs/README.md) folder:

| Document | Content |
|---|---|
| [docs/architecture.md](docs/architecture.md) | How the project is built and how the proactive cycle works |
| [docs/cli.md](docs/cli.md) | Full reference of every CLI command |
| [docs/agent-tools.md](docs/agent-tools.md) | The tools the model can invoke |
| [docs/security.md](docs/security.md) | Sandboxing and what to know before running it unsupervised |
| [docs/test.md](docs/test.md) | How to run the tests |
| [docs/troubleshooting.md](docs/troubleshooting.md) | Known issues and fixes |
| [CHANGELOG.md](CHANGELOG.md) | Release history |

## Project structure

```
ploop/          — agent code (llm.py, tools.py, state.py, core.py, cli.py)
bin/ploop       — CLI wrapper (uses `.venv` if present, then runs `python -m ploop`)
bin/agent       — compatibility wrapper that delegates to `bin/ploop`
pyproject.toml — local editable install and `ploop` CLI entry point
tests/          — unit tests + end-to-end smoke test
docs/           — full documentation
```
