prompt fix

This commit is contained in:
Luxferre
2026-08-08 20:28:58 +03:00
parent bec49bad94
commit e64fa242fd
3 changed files with 49 additions and 6 deletions
+36 -5
View File
@@ -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?
+5 -1
View File
@@ -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
+8
View File
@@ -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.