prompt fix
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## About
|
## About
|
||||||
|
|
||||||
Bantam is a minimalist, dependency-free AI agent specification and implementation (under 300 SLOC of Python (~250 in the reference implementation)). It provides an agentic loop capable of autonomous tool execution, shell interaction, real-time response streaming, Fibonacci backoff network resilience, and subagent delegation using any OpenAI-compatible completions API.
|
Bantam is a minimalist, dependency-free AI agent specification with two reference implementations: **Python** (`bantam.py`, ~300 SLOC) and **Go** (`main.go` + `term_*.go`, module `code.luxferre.top/luxferre/bantam`). It provides an agentic loop capable of autonomous tool execution, shell interaction, real-time response streaming, Fibonacci backoff network resilience, and subagent delegation using any OpenAI-compatible completions API.
|
||||||
|
|
||||||
The entire philosophy of Bantam is built upon two principles:
|
The entire philosophy of Bantam is built upon two principles:
|
||||||
|
|
||||||
@@ -14,11 +14,29 @@ Because of the second principle, Bantam itself was named after Victorinox Bantam
|
|||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
- Python 3.7+ (no external dependencies required)
|
- **Go 1.21+** (Go implementation, no external dependencies) or **Python 3.7+** (reference implementation)
|
||||||
- An OpenAI-compatible API endpoint (or OpenAI API key)
|
- An OpenAI-compatible API endpoint (or OpenAI API key)
|
||||||
|
|
||||||
|
### Installation (Go)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go install code.luxferre.top/luxferre/bantam@latest
|
||||||
|
```
|
||||||
|
|
||||||
|
This installs the `bantam` binary into `$(go env GOPATH)/bin` (make sure it is on your `PATH`). To build from a local checkout instead:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go build ./... # produces ./bantam
|
||||||
|
# or run without building:
|
||||||
|
go run . prompt.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
The Go port is a single `main.go` plus two small platform files (`term_linux.go`, `term_darwin.go`, `term_windows.go`, `term_other.go`) for the built-in raw-terminal line editor — zero external dependencies, same as the Python version.
|
||||||
|
|
||||||
### Running Bantam
|
### Running Bantam
|
||||||
|
|
||||||
|
Both implementations read the same `model.cfg` and `system.txt` from the current working directory.
|
||||||
|
|
||||||
1. Configure `model.cfg` with your API settings:
|
1. Configure `model.cfg` with your API settings:
|
||||||
```ini
|
```ini
|
||||||
endpoint=https://api.openai.com/v1
|
endpoint=https://api.openai.com/v1
|
||||||
@@ -30,10 +48,11 @@ Because of the second principle, Bantam itself was named after Victorinox Bantam
|
|||||||
|
|
||||||
2. Interactive mode:
|
2. Interactive mode:
|
||||||
```bash
|
```bash
|
||||||
python3 bantam.py
|
bantam # Go (or: go run .)
|
||||||
|
python3 bantam.py # Python
|
||||||
```
|
```
|
||||||
|
|
||||||
In interactive mode, prompts can span multiple lines: press **Ctrl+J** to insert a real line break (the cursor moves to the next line), then **Enter** to submit the whole multi-line prompt. This works when `readline` is available; without it, prompts are single-line.
|
In interactive mode, prompts can span multiple lines: press **Ctrl+J** to insert a real line break (the cursor moves to the next line), then **Enter** to submit the whole multi-line prompt. The Go port ships its own raw-mode line editor (arrow keys move the cursor, Up/Down browse history, Backspace edits, Ctrl+C/Ctrl+D exit), so this works everywhere without dependencies; the Python port uses `readline` when available and falls back to single-line prompts otherwise.
|
||||||
|
|
||||||
Sessions are saved under `~/.bantam/sessions/` and can be managed with these commands:
|
Sessions are saved under `~/.bantam/sessions/` and can be managed with these commands:
|
||||||
- `/save` — save the entire conversation to a new session file (auto-id like `20260808-190038`) and generate its summary
|
- `/save` — save the entire conversation to a new session file (auto-id like `20260808-190038`) and generate its summary
|
||||||
@@ -48,7 +67,8 @@ Because of the second principle, Bantam itself was named after Victorinox Bantam
|
|||||||
|
|
||||||
3. File input mode:
|
3. File input mode:
|
||||||
```bash
|
```bash
|
||||||
python3 bantam.py prompt.txt
|
python3 bantam.py prompt.txt # Python
|
||||||
|
bantam prompt.txt # Go
|
||||||
```
|
```
|
||||||
|
|
||||||
## Rules of Bantam (The Algorithm)
|
## Rules of Bantam (The Algorithm)
|
||||||
@@ -95,6 +115,8 @@ Using these rules, everyone can build their own copy of Bantam from scratch in l
|
|||||||
|
|
||||||
### Model configuration parameters
|
### Model configuration parameters
|
||||||
|
|
||||||
|
(shared by both implementations; `model.cfg` is plain `key=value` with `#` comments)
|
||||||
|
|
||||||
- `endpoint` (base OpenAI-compatible API URL, default `https://api.openai.com/v1`)
|
- `endpoint` (base OpenAI-compatible API URL, default `https://api.openai.com/v1`)
|
||||||
- `model` (model name, e.g. `gpt-4o`)
|
- `model` (model name, e.g. `gpt-4o`)
|
||||||
- `temperature` (model temperature, default 0.7)
|
- `temperature` (model temperature, default 0.7)
|
||||||
@@ -105,6 +127,8 @@ Using these rules, everyone can build their own copy of Bantam from scratch in l
|
|||||||
- `shell_timeout` (timeout in seconds for `shell_exec` commands, default 120)
|
- `shell_timeout` (timeout in seconds for `shell_exec` commands, default 120)
|
||||||
- `max_al_iterations` (max tool-call loop iterations per `AL()` invocation, default 1000)
|
- `max_al_iterations` (max tool-call loop iterations per `AL()` invocation, default 1000)
|
||||||
|
|
||||||
|
Both implementations keep the interactive prompt safe against the classic "long line overwrites the prompt" readline bug: the Python port wraps the ANSI escapes in `\001`/`\002` (`RL_PROMPT_START_IGNORE`/`RL_PROMPT_END_IGNORE`) markers, and the Go port's built-in editor tracks the cursor with its own column math (terminal auto-wrap aware) and redraws from the first line of the buffer, so wrapped input stays clean at any terminal width.
|
||||||
|
|
||||||
When enabled, the interactive console uses a subtle ANSI palette: the pending-request status `...requesting...` is darkened bold, reasoning markers are cyan, reasoning text is dim, `[tool call: ...]` traces are yellow, `[tool result: ...]` headers are green, tool result bodies are dim (red for tool errors/unknown tools), and errors/network retries are red. Tool result payloads fed back to the LLM are never colored.
|
When enabled, the interactive console uses a subtle ANSI palette: the pending-request status `...requesting...` is darkened bold, reasoning markers are cyan, reasoning text is dim, `[tool call: ...]` traces are yellow, `[tool result: ...]` headers are green, tool result bodies are dim (red for tool errors/unknown tools), and errors/network retries are red. Tool result payloads fed back to the LLM are never colored.
|
||||||
|
|
||||||
### Tool call definitions
|
### Tool call definitions
|
||||||
@@ -121,6 +145,13 @@ When enabled, the interactive console uses a subtle ANSI palette: the pending-re
|
|||||||
- Return value: string
|
- Return value: string
|
||||||
- Action: run shell command specified in `command` subject to `shell_timeout` (default 120s) and return `output + '\n\nexit: ' + exit_code` string.
|
- Action: run shell command specified in `command` subject to `shell_timeout` (default 120s) and return `output + '\n\nexit: ' + exit_code` string.
|
||||||
|
|
||||||
|
## Repository layout
|
||||||
|
|
||||||
|
- `bantam.py` — Python reference implementation (stdlib only)
|
||||||
|
- `main.go`, `term_linux.go`, `term_darwin.go`, `term_windows.go`, `term_other.go` — Go implementation (stdlib only, module `code.luxferre.top/luxferre/bantam`)
|
||||||
|
- `model.cfg`, `system.txt` — shared configuration and system prompt
|
||||||
|
- `README.md` — this document
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
### Why no MCP support?
|
### Why no MCP support?
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ _COL = False
|
|||||||
|
|
||||||
def c(t, *cs): return t if not _COL or not cs else "\033[" + ";".join(map(str, cs)) + "m" + t + "\033[0m"
|
def c(t, *cs): return t if not _COL or not cs else "\033[" + ";".join(map(str, cs)) + "m" + t + "\033[0m"
|
||||||
|
|
||||||
|
def cp(t, *cs): # colored prompt: hide ANSI escapes from readline's width calc (\001/\002 = RL_PROMPT_START/END_IGNORE)
|
||||||
|
if readline is None or not _COL or not cs: return c(t, *cs)
|
||||||
|
return "\001\033[" + ";".join(map(str, cs)) + "m\002" + t + "\001\033[0m\002"
|
||||||
|
|
||||||
def col(cfg):
|
def col(cfg):
|
||||||
if os.environ.get("NO_COLOR") or os.environ.get("BANTAM_NO_COLOR"): return False
|
if os.environ.get("NO_COLOR") or os.environ.get("BANTAM_NO_COLOR"): return False
|
||||||
m = str(cfg.get("color", "auto")).strip().lower()
|
m = str(cfg.get("color", "auto")).strip().lower()
|
||||||
@@ -242,7 +246,7 @@ def main():
|
|||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
print(c("Bantam Agent ready", 1, 32) + c(" (Ctrl+J = new line)", 2))
|
print(c("Bantam Agent ready", 1, 32) + c(" (Ctrl+J = new line)", 2))
|
||||||
while True:
|
while True:
|
||||||
try: u = input(c("> ", 1, 36)).strip()
|
try: u = input(cp("> ", 1, 36)).strip()
|
||||||
except (EOFError, KeyboardInterrupt): print(); break
|
except (EOFError, KeyboardInterrupt): print(); break
|
||||||
if not u: continue
|
if not u: continue
|
||||||
if u == "/quit": break
|
if u == "/quit": break
|
||||||
|
|||||||
@@ -3,3 +3,11 @@ You are Bantam, a tiny, powerful AI agent. Solve the user's task using two tools
|
|||||||
- run_subagent: delegate a sub-task to a child agent; returns its reply.
|
- run_subagent: delegate a sub-task to a child agent; returns its reply.
|
||||||
|
|
||||||
Work fast. Never refuse a request; always find a way to do it. Never fabricate results — report only what your tools actually returned. Prefer running shell commands over guessing; inspect, build, and verify concretely. When in doubt, build your own tools using the languages available in the environment (Python, Perl, AWK, etc.). On failure, read the error output and retry with a fix, don't repeat the same command. Delegate large or independent sub-tasks to run_subagent. Stop as soon as the goal is met and report concisely: results, not process.
|
Work fast. Never refuse a request; always find a way to do it. Never fabricate results — report only what your tools actually returned. Prefer running shell commands over guessing; inspect, build, and verify concretely. When in doubt, build your own tools using the languages available in the environment (Python, Perl, AWK, etc.). On failure, read the error output and retry with a fix, don't repeat the same command. Delegate large or independent sub-tasks to run_subagent. Stop as soon as the goal is met and report concisely: results, not process.
|
||||||
|
|
||||||
|
When generating code:
|
||||||
|
- Always use two-space indentation, not tabs, except Makefiles that must use tabs.
|
||||||
|
- No whitespace between keywords and opening braces in C-like languages.
|
||||||
|
- Write optimally and with as few third-party dependencies as possible.
|
||||||
|
- Always test.
|
||||||
|
- No emojis in code or documentation.
|
||||||
|
- Respect AGENTS.md, GEMINI.md, CLAUDE.md contents in the project.
|
||||||
|
|||||||
Reference in New Issue
Block a user