monet.py
A simple DSPy based coding agent with a Textual TUI.
Install
pip install monet-code
Or for development:
git clone https://github.com/wallyqs/monet.py.git
cd monet.py
uv sync
Run
# Set API keys in .env (loaded automatically)
echo 'export ANTHROPIC_API_KEY=sk-...' >> .env
uv run monet
Features
ReAct-based chat
Chat uses ReAct for multi-step reasoning with tool calling:
class ChatSignature(dspy.Signature): # type: ignore[misc,valid-type]
"""Respond to the user. Use tools when helpful. Maintain context from history.
...
Use Rich markup in log.write(): [bold], [dim], [#F4A300]amber[/], etc.
"""
history: dspy.History = dspy.InputField(
desc="Prior turns of the conversation."
)
message: str = dspy.InputField(desc="The user's current message.")
response: str = dspy.OutputField(desc="Assistant reply.")
self._react = dspy.ReAct(ChatSignature, tools=self._tools)
return self._react
The agent thinks, calls tools, observes results, and iterates until it
has an answer. The trajectory (thinking, tool calls, results) is
displayed in the content pane. By pressing ctrl-o you can toggle
on/off thinking.
Multi-provider model switching
Switch models at runtime with /model or /model <name>. The current
model is shown in the bottom-right corner of the status bar.
| Provider | Models |
|---|---|
| Anthropic | claude-haiku-4-5, claude-sonnet-4, claude-opus-4 |
| OpenAI | gpt-4o, gpt-4o-mini, o3, o4-mini |
| NVIDIA NIM | gpt-oss-20b, gpt-oss-120b, qwen3-coder-480b, kimi-k2.5 |
Built-in coding tools
The agent has access to these tools:
| Tool | Description |
|---|---|
read |
Read files with line numbers, offset, and limit |
write |
Write/create files (creates directories as needed) |
edit |
Exact string replacement with unified diff output |
bash |
Shell command execution with timeout |
grep |
Regex search across files and directories |
list_dir |
List directory contents |
register_command |
Hot-load a slash command plugin from a Python file |
Self-extending
The agent can add new slash commands to itself at runtime via the
register_command. Ask it to "add a /greet monet command" and it
will:
- Create a plugin file at
.monet/commands/greet.py - Call
register_command()to activate it immediately - The command persists across restarts
Plugin files follow a simple convention:
NAME = "/greet"
DESCRIPTION = "Greet someone"
def handler(app, args: str) -> None:
log = app.query_one("#content")
log.write(f"Hi {args.strip() or 'world'}!")
Commands can call app.predict(signature, **kwargs) to query the LLM using DSPy Predict:
def handler(app, args: str) -> None:
log = app.query_one("#content")
result = app.predict("topic -> summary", topic=args.strip())
log.write(result.get("summary", result.get("error", "")))
Commands also have full access to the
Textual framework via the app
object. For example, you can ask the agent: "add a /screenshot monet
command which uses app.save_screenshot()" and it will generate:
NAME = "/screenshot"
DESCRIPTION = "Take a screenshot of the current application"
def handler(app, args: str) -> None:
log = app.query_one("#content")
try:
app.save_screenshot()
log.write("Screenshot saved successfully.")
except Exception as e:
log.write(f"Error saving screenshot: {e}")
Slash command completion
Type / to see available commands. Tab autocompletes from the
filtered list. ctrl+n / ctrl+p navigate the picker.
Input history
ctrl+p / ctrl+n navigate through previously submitted chat
messages (when the command picker is not visible). Slash commands are
not added to history. In-progress text is stashed and restored.
Keyboard shortcuts
| Key | Action |
|---|---|
? |
Show shortcuts help |
/ |
Show available commands |
Tab |
Autocomplete command name |
ctrl+p |
History previous / picker up |
ctrl+n |
History next / picker down |
ctrl+o |
Toggle thinking block visibility |
esc |
Cancel in-flight request |
ctrl+z |
Suspend process |
ctrl+b |
Cursor back one character |
ctrl+f |
Cursor forward one character |
ctrl+k |
Kill to end of line |
ctrl+y |
Yank (paste) killed text |
Response rendering
- Markdown with syntax-highlighted code blocks
- ReAct trajectory display (thinking, tool calls, tool results)
- Unified diffs with syntax highlighting after edits
- Animated spinner during LLM calls
- Text selection and auto-copy to clipboard
- Command output is kept in chat context for follow-up conversation
UI behavior
- Banner auto-hides when content overflows
- Typing anywhere auto-focuses the input
ctrl+oretroactively shows/hides all thinking blocks- Current model shown in status bar
Testing
uv run pytest
Metadata
Release files for monet-code 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| monet_code-0.1.1.tar.gz | 186.1 kB | Without provenance | Details for monet_code-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| monet_code-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for monet_code-0.1.1-py3-none-any.whl |
Total release size: 214.1 kB
Release files / monet_code-0.1.1.tar.gz
| Download URL | monet_code-0.1.1.tar.gz |
|---|---|
| Size | 186.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4f2710db8d2a150a20acc0b8690ea1d79ee94c71c2a5c09c34e1077163b93497
|
|
BLAKE2b-256 checksum How to use checksums |
65608ca443f9bf7638968eeb97399a5334293aa9bd2b5709fa47b5aec5eb4565
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.7.6
|
Release files / monet_code-0.1.1-py3-none-any.whl
| Download URL | monet_code-0.1.1-py3-none-any.whl |
|---|---|
| Size | 28.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1dcf75eb5e5c7730e99a7c2a31a2fcab92636cb0582a93ec5c9336e2454363e9
|
|
BLAKE2b-256 checksum How to use checksums |
c805c36edf7ad6100a5ec962ffc5bf530b2a3ca3121bcbc27594ad4db4551eba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.7.6
|
Security for monet-code 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.