A Python 2.7+ REPL for interacting with LLMs with an OpenAI Chat Completions-compatible API.
Project description
chatrepl
A minimal agent for OpenAI-compatible Chat Completions APIs with four built-in tools:
readwriteeditshell
Features
- Interactive Python-powered REPL
- Python 2.7+ and Python 3 compatible
- Works with OpenAI-compatible
/chat/completionsendpoints - Discovery of
AGENTS.mdandCLAUDE.mdunder the current working directory - Streaming assistant responses
- Editable multiline input through your editor
- Non-interactive CLI mode for piped input or one-shot prompts
Installation
pip install chatrepl
Usage
CLI options
-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
--no-stream Disable streaming
--no-context-files Disable AGENTS.md and CLAUDE.md discovery
Interactive REPL
chatrepl \
--api-key "your-api-key" \
--base-url "https://api.openai.com/v1" \
--model "gpt-5.4"
You enter a Python interactive console with helper functions preloaded.
Available commands:
| Function | Description |
|---|---|
send(text='', image_path=None, stream=True) |
Send a message and let the agent complete tool calls, optionally with a local image path used as-is and streaming control |
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 using the provided path as-is |
img(path) |
Append a local image as a user message; files are embedded as data URLs using the provided path as-is |
reset() |
Reset to only the system prompt |
Exit with exit() or EOF.
One-shot prompt
chatrepl \
--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
cat prompt.txt | chatrepl \
--api-key "your-api-key" \
--base-url "https://api.openai.com/v1" \
--model "gpt-4o"
Tool model
The agent is intentionally small and constrained.
read
Reads a text file with optional offset and limit arguments.
- Uses the provided path as-is
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
oldTextmust match exactly once - edits must not overlap
- all edits are matched against the original file
Returns a unified diff after a successful edit.
shell
Runs a shell command in the current working directory.
- live output is streamed to the terminal
- full output is returned to the model
Example session
Turn 1: appended user message, then send with no new text
This is useful because it exercises the path where send() is called with no pending user message.
>>> append("Reply with exactly APPENDED-OK.")
>>> send(stream=False)
Assistant response:
APPENDED-OK
Turn 2: streamed text + streamed tool-call deltas + follow-up tool result
>>> send("Read hello.txt and quote its contents back to me.", stream=True)
Mock streamed assistant output:
I’ll inspect the file.
[assistant is preparing tool call(s)]
[tool_call 0]
id: call_read_1
type: function
name += re
name += ad
arguments += {"path":"he
arguments += llo.txt"}
Then tool execution:
[assistant is using 1 tool(s)]
[tool read]
Hello!
Then assistant follow-up response:
The file contains `Hello!`.
Turn 3: multiple tool calls in one assistant message
This exercises:
- multiple tool calls
writeeditread- diff generation
- tool index tracking in streaming
>>> send("Create tmp/demo.txt with alpha and beta on separate lines, change beta to gamma, then read it back.", stream=True)
Mock streamed assistant output:
I’ll create the file, patch it, and verify the result.
[assistant is preparing tool call(s)]
[tool_call 0]
id: call_write_1
type: function
name += wr
name += ite
arguments += {"path":"tmp/demo.txt","content":"alpha\nbeta\n"}
[tool_call 1]
id: call_edit_1
type: function
name += ed
name += it
arguments += {"path":"tmp/demo.txt","edits":[{"oldText":"beta","newText":"gamma"}]}
[tool_call 2]
id: call_read_2
type: function
name += read
arguments += {"path":"tmp/demo.txt"}
Then tool execution:
[assistant is using 3 tool(s)]
[tool write]
Successfully wrote 11 characters to <repo>/tmp/demo.txt
[tool edit]
Applied 1 edit(s) to <repo>/tmp/demo.txt
--- <repo>/tmp/demo.txt
+++ <repo>/tmp/demo.txt
@@
-alpha
-beta
+alpha
+gamma
[tool read]
alpha
gamma
Then assistant follow-up:
Done. `tmp/demo.txt` now contains:
- alpha
- gamma
Turn 4: shell tool, stdout + stderr, non-streaming
>>> send("Run a shell command that prints one line to stdout and one to stderr.", stream=False)
Assistant response with tool call:
I’ll run a small shell command.
Then tool execution:
[assistant is using 1 tool(s)]
[tool shell]
$ printf 'stdout-line\n'; printf 'stderr-line\n' >&2
Exit code: 0
stdout-line
stderr-line
Then assistant follow-up:
The shell command succeeded and produced both stdout and stderr output.
License
This project is licensed under the MIT License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file chatrepl-0.3.0a8.tar.gz.
File metadata
- Download URL: chatrepl-0.3.0a8.tar.gz
- Upload date:
- Size: 10.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
69b3e3b5e9e8a522c693792770d166c347262663124934ddf51e1ed46dc7262a
|
|
| MD5 |
115f2d4e2c75a9a50f3150b0cdb03169
|
|
| BLAKE2b-256 |
b4887a155498ef9a56e53267e66720969d21bc07406085ea9d98d60664ca3b77
|
File details
Details for the file chatrepl-0.3.0a8-py2.py3-none-any.whl.
File metadata
- Download URL: chatrepl-0.3.0a8-py2.py3-none-any.whl
- Upload date:
- Size: 10.7 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1d171a08838f9417eccb2f47d0377cb173fdf4a15e4a0932df71c1a293def09
|
|
| MD5 |
64e936198b8f5387f9ab2b6956ff0124
|
|
| BLAKE2b-256 |
9d3ade38a4fc832fadf021707caee110e3789ba0e87fcb514c5994341e711b7e
|