Metadata-Version: 2.4
Name: chatrepl
Version: 0.3.0a2
Summary: A Python 2.7+ REPL for interacting with LLMs with an OpenAI Chat Completions-compatible API.
Author-email: Jifeng Wu <jifengwu2k@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/jifengwu2k/chatrepl
Project-URL: Bug Tracker, https://github.com/jifengwu2k/chatrepl/issues
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=2
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: ctypes-unicode-proclaunch
Requires-Dist: escape-nt-command-line-argument
Requires-Dist: get-unicode-multiline-input-with-editor
Requires-Dist: get-unicode-shell
Requires-Dist: live-tee-and-capture
Requires-Dist: posix-or-nt
Requires-Dist: textcompat
Requires-Dist: typing; python_version < "3.5"
Dynamic: license-file

# chatrepl

A minimal single-file coding agent and chat REPL for OpenAI-compatible Chat Completions APIs.

`chatrepl.py` is no longer just a plain chat interface. It now exposes a small tool-enabled agent loop with four built-in tools:

- `read`
- `write`
- `edit`
- `bash`

The model can call these tools automatically, receive their results, and continue for multiple steps until it finishes.

## Features

- Minimal coding agent with automatic tool calling
- Four local tools: `read`, `write`, `edit`, `bash`
- Streaming assistant responses
- Interactive Python-powered REPL
- Non-interactive CLI mode for piped input or one-shot prompts
- Conversation save/load as JSON
- Markdown export
- Editable multiline input through your editor
- Optional discovery of `AGENTS.md` and `CLAUDE.md` from the working directory up to `/`
- Works with OpenAI-compatible `/chat/completions` endpoints
- Python 2.7+ and Python 3 compatible

## Tool model

The agent is intentionally small and constrained.

### `read`
Reads a text file with optional `offset` and `limit` arguments.

- Truncates output to 2000 lines or 50 KB
- Detects binary files and refuses to display them
- Resolves paths relative to the current tool working directory

### `write`
Writes full file contents.

- Creates parent directories automatically
- Rewrites the destination file completely

### `edit`
Applies exact text replacements to an existing file.

Rules:
- each `oldText` must match exactly once
- edits must not overlap
- all edits are matched against the original file

Returns a unified diff after a successful edit.

### `bash`
Runs a shell command in the current working directory.

- live output is streamed to the terminal
- output returned to the model is truncated to the last 2000 lines or 50 KB
- default timeout is 30 seconds
- long outputs are saved to a temporary log file

## Installation

### From source

```bash
git clone <repo-url>
cd chatrepl
pip install -r requirements.txt
```

Or run the script directly if its dependencies are already available.

## Usage

### Interactive REPL

```bash
python chatrepl.py \
  --api-key "your-api-key" \
  --base-url "https://api.openai.com/v1" \
  --model "gpt-4o"
```

You enter a Python interactive console with helper functions preloaded.

Available commands:

| Function | Description |
|---|---|
| `send(text='')` | Send a message and let the agent complete tool calls |
| `append(text)` | Append a user message without sending |
| `multiline()` | Append multiline input from your editor |
| `txt(path)` | Append a UTF-8 text file as a user message |
| `load(path)` | Load a conversation from JSON |
| `save(path)` | Save the current conversation to JSON |
| `export(path)` | Export the conversation to Markdown |
| `correct()` | Edit the last assistant response |
| `show()` | Print all conversation messages |
| `reset()` | Reset to only the system prompt |
| `cwd(path=None)` | Show or change the tool working directory |
| `model(name=None)` | Show or change the model ID |
| `base_url(url=None)` | Show or change the API base URL |
| `stream(enabled=None)` | Show or change streaming mode |
| `context_files(enabled=None)` | Enable or disable `AGENTS.md` / `CLAUDE.md` discovery |
| `context_paths()` | Show discovered context file paths |

Exit with `exit()` or EOF.

### One-shot prompt

```bash
python chatrepl.py \
  --api-key "your-api-key" \
  --base-url "https://api.openai.com/v1" \
  --model "gpt-4o" \
  "Inspect this repository and summarize the build system"
```

### Piped input

```bash
cat prompt.txt | python chatrepl.py \
  --api-key "your-api-key" \
  --base-url "https://api.openai.com/v1" \
  --model "gpt-4o"
```

## CLI options

```text
-k, --api-key           API key for the OpenAI-compatible endpoint
-u, --base-url          Base URL, e.g. http://localhost:11434/v1
-m, --model             Model ID
-l, --load              Load a conversation JSON file
--no-stream             Disable streaming
--no-context-files      Disable AGENTS.md and CLAUDE.md discovery
```

## Agent behavior

The core agent loop is implemented in `AgentConversation.send()`.

For each turn it:
1. sends the current messages and tool schemas to the model
2. receives assistant content and optional tool calls
3. executes tool calls locally
4. appends tool results as `tool` messages
5. asks the model again
6. repeats until there are no more tool calls or `MAX_AGENT_STEPS` is reached

Current limit:
- `MAX_AGENT_STEPS = 32`

## Context files

When enabled, the script searches from the current working directory up to the filesystem root for:

- `AGENTS.md`
- `CLAUDE.md`

Their contents are appended to the base system prompt.

This lets you keep project-local instructions outside the script itself.

## Notes and limitations

- This is a minimal agent, not a full task planner framework.
- Tool execution is local and unsandboxed.
- `bash` can modify the current machine and repository.
- Tool support depends on your model and server correctly implementing OpenAI-compatible tool calling.
- `write` overwrites full files; use `edit` for precise changes.
- Output truncation is intentional to keep context bounded.

## Example session

```text
$ python chatrepl.py --api-key ... --base-url http://localhost:11434/v1 --model your-model
Welcome to pi-single-chatrepl. Use one of the following commands to interact with your-model:

>>> send('Inspect chatrepl.py and tell me whether it is agentic now.')
The script now has agentic behavior.

[tool read]
#!/usr/bin/env python
...

It defines tools, sends them to the model, executes tool calls, and loops until completion.
[tokens in=... out=... total_in=... total_out=...]
```

## License

This project is licensed under the [MIT License](LICENSE).
