333 lines
24 KiB
Markdown
333 lines
24 KiB
Markdown
# Bantam: tiny, powerful, DIY AI agent
|
|
|
|
## About
|
|
|
|
Bantam is a minimalist, dependency-free AI agent specification with reference implementations in **Go** (`main.go` + `term_*.go`, module `code.luxferre.top/luxferre/bantam`) and **Perl 5** as **MicroBantam** (`mb`, under 100 SLOC). It provides an agentic loop capable of autonomous tool execution, direct shell interaction, file writing/editing, real-time response streaming, markdown terminal rendering with box-drawing tables, Fibonacci backoff network resilience, context window auto-discovery, token usage tracking with prompt cache breakdowns, and conversation compaction using any OpenAI-compatible completions API.
|
|
|
|
The entire philosophy of Bantam is built upon two principles:
|
|
|
|
1. The structure must be as simple as possible for anyone to be able to reimplement the agent from a plain algorithm description.
|
|
2. The agent only needs to provide two tools: a tool to call shell commands (`shell_exec`) and a tool to write/edit files (`write_file`). In theory, this should be sufficient to give LLMs the ability to handle tasks of any complexity.
|
|
|
|
Because of the second principle, Bantam itself was named after Victorinox Bantam Alox, a small and lightweight Swiss army knife with only two tools.
|
|
|
|
## Usage
|
|
|
|
### Prerequisites
|
|
- **Go 1.21+** or **Perl 5.14+** (standard library / core modules only)
|
|
- 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 four platform files (`term_linux.go`, `term_bsd.go`, `term_windows.go`, `term_other.go`) for the built-in raw-terminal line editor — zero external dependencies.
|
|
|
|
### Running Bantam
|
|
|
|
All implementations read `model.cfg` (or `.bantam.cfg`, which takes priority if present) from the current working directory.
|
|
|
|
1. Configure `model.cfg` (or `.bantam.cfg`, which takes priority) with your API settings:
|
|
```ini
|
|
endpoint=https://api.kilo.ai/api/openrouter
|
|
model=kilo-auto/free
|
|
temperature=0.7
|
|
api_key=your_api_key_here
|
|
stream=true
|
|
context_window=200000
|
|
```
|
|
|
|
2. Interactive mode:
|
|
```bash
|
|
bantam # Go (or: go run .)
|
|
./mb # MicroBantam (Perl 5)
|
|
```
|
|
|
|
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 clears line / interrupts in-flight run, Ctrl+D exits), working everywhere without third-party dependencies.
|
|
|
|
After every interaction, Bantam displays token usage (prompt tokens, cached/uncached breakdown when supported by the provider, completion tokens, and context window utilization):
|
|
```text
|
|
[tokens: 1420 prompt (1000 cached, 420 uncached) + 85 completion | context: 1420/200000 (0.7%)]
|
|
```
|
|
|
|
Sessions are saved under `~/.bantam/sessions/` and can be managed with these commands:
|
|
- `/save [name]` — save the entire conversation to a session file (named `name`, or defaulting to the MD5 hash of the current project directory) and generate its summary
|
|
- `/continue` (alias `/cont`) — continue/autoload the session corresponding to the current project directory
|
|
- `/list` — list saved sessions (newest first) with their ids, timestamps, message counts and summaries (marking the current project's session)
|
|
- `/load <id>` — load a saved session (exact id or unique prefix) and continue from there
|
|
- `/compact` — compact context down to the system message and a concise summary using the LLM; the compaction prompt is appended to the conversation to derive the summary, then the conversation is reset to `[system, summary-user-message]` (a fresh prefix, so downstream prompt-cache hits depend on the provider and are not guaranteed)
|
|
- `/cfg <param> [val]` — inspect or update a configuration parameter live (writes to `.bantam.cfg`)
|
|
- `/models` — query the `/models` path on the current inference endpoint and print a plain list of supported model IDs, marking the currently configured model with a leading `* ` (Go port)
|
|
- `!<cmd>` — execute a shell command directly through `shell_exec` without adding the result to the conversation context (Go port)
|
|
- `/help` — show all supported commands
|
|
- `/clear` — reset the conversation to just the system prompt
|
|
- `/quit` — exit
|
|
|
|
When context window usage reaches **60% or higher**, Bantam automatically offers to compact the conversation:
|
|
```text
|
|
Context usage is at 62.4% (124800 / 200000 tokens). Compact conversation? [Y/n]:
|
|
```
|
|
|
|
Pressing **Ctrl+C** during an active inference run or long-running shell execution cleanly interrupts the turn without appending partial or malformed responses to the conversation context.
|
|
|
|
The current conversation is also **auto-saved** to `~/.bantam/sessions/<project-md5>.json` after every turn, on `/clear`, `/load`, `/compact`, `/continue`, and on exit — so you can always run `/continue` (or `/cont`) to resume where you left off.
|
|
|
|
3. File input mode:
|
|
```bash
|
|
bantam prompt.txt # Go
|
|
./mb prompt.txt # MicroBantam (Perl 5)
|
|
```
|
|
|
|
## Rules of Bantam (The Algorithm)
|
|
|
|
Using these rules, everyone can build their own copy of Bantam from scratch in little time in any language that supports file access, shell and HTTP(S) calls.
|
|
|
|
### High-Level Overview
|
|
|
|
1. **Initialization**: Read the config file (`.bantam.cfg` if present, else `model.cfg`). Discover context window size from the `/models` endpoint (or fallback to `context_window` from `model.cfg` or 200,000 tokens). Prepare an array of messages starting with the built-in system prompt `{"role": "system", "content": system_prompt}`.
|
|
2. **Input Processing**: Take user prompt (via command-line file parameter or interactive stdin). If prefixed with `!`, execute the command directly via `shell_exec` without appending to conversation context. Otherwise, append `{"role": "user", "content": prompt}`, and invoke `AL(cfg, messages)`.
|
|
3. **Agentic Loop (`AL`)**:
|
|
- Send `messages` and tool definitions (`shell_exec`, `write_file`) to the OpenAI-compatible `/chat/completions` API endpoint with custom `User-Agent` headers and `stream_options: {"include_usage": true}`.
|
|
- Support context cancellation (e.g. on `SIGINT` / Ctrl+C) to cleanly abort in-flight requests without appending incomplete messages.
|
|
- On network or HTTP failure, retry using Fibonacci backoff delays (`1s, 1s, 2s, 3s, 5s, 8s, 13s, 21s, 34s`).
|
|
- If `stream=true`, parse SSE data chunks (`data: {...}`) in real-time to stream reasoning content (`reasoning_content`) and response text directly to stdout, bracketing the reasoning block with `--- reasoning start ---` / `--- reasoning end ---` markers, rendering Markdown and tables constrained to terminal width.
|
|
- Reconstruct the assistant message and track usage tokens (`prompt_tokens`, `completion_tokens`, cached tokens). If `tool_calls` exist, trace the call (`[tool call: name(args)]`), validate JSON arguments, execute the requested tool (`shell_exec` or `write_file`), trace the result (`[tool result: name]`), append the tool response `{"role": "tool", "tool_call_id": id, "content": result}`, and repeat the loop.
|
|
- If no tool calls remain or `max_al_iterations` is reached, return the updated messages list and turn usage stats.
|
|
4. **Post-Turn Reporting & Compaction**:
|
|
- Display token usage and context window percentage.
|
|
- If context usage is >= 60%, prompt user to compact.
|
|
- Compaction appends `"You are now acting as a compaction engine. Summarize the preceding conversation concisely but completely..."` as a user message to the conversation, invokes the LLM, and then resets the conversation to the system prompt plus a `user` message carrying the resulting summary. (The compaction prompt is not retained; the post-compaction conversation is a new prefix, so prompt-cache hits are provider-dependent.)
|
|
|
|
### Main program
|
|
|
|
1. Initialize system prompt from built-in default.
|
|
2. Read model parameters from the config file (`.bantam.cfg` if present, else `model.cfg`) in `key=value` format and discover context window size.
|
|
3. Prepare a new message list with the system prompt (`role: "system"`).
|
|
4. Read the first command-line parameter. If non-empty, read user prompt from the specified file. If prefixed with `!`, execute the shell command directly via `shell_exec` and exit. Otherwise, append to `messages` (`role: "user"`), run `AL(cfg, messages)`, display token usage, and exit.
|
|
5. Read user prompt from standard input (with `readline` line editing and history in `~/.bantam_history`; **Ctrl+J** inserts a real newline into the line being edited). If equal to `/quit` or EOF, exit. If equal to `/clear`, reset `messages` to step 3 and return to step 5. If starting with `/save`, write the whole `messages` array to `~/.bantam/sessions/<name>.json` (or `<project-md5>.json` if no name is given) and return to step 5. If equal to `/continue` or `/cont`, load the session corresponding to the current project's MD5 hash and return to step 5. If equal to `/list`, print saved sessions and their summaries (marking current project session) and return to step 5. If starting with `/load`, replace `messages` with the saved session's messages (by exact id or unique prefix) and return to step 5. If equal to `/compact`, ask the LLM to summarize the conversation by appending the compaction prompt to derive the summary, replace `messages` with `[system, summary-user-message]`, and return to step 5. If starting with `/cfg`, display the current value (`/cfg <param>`) or update the config live by writing to `.bantam.cfg` (`/cfg <param> <val>`) and return to step 5. If equal to `/models`, query the `/models` path on the current inference endpoint and print a plain list of supported model IDs (the currently configured model marked with a leading `* `), then return to step 5. If starting with `!`, execute the command directly via `shell_exec` without adding the result to `messages` and return to step 5. If equal to `/help`, print the command list and return to step 5. After every user turn and on exit, auto-save `messages` to `~/.bantam/sessions/<project-md5>.json`.
|
|
6. Append user prompt to `messages` (`role: "user"`), run `AL(cfg, messages)`, display token usage, check 60% context threshold for auto-compaction, and go to step 5.
|
|
|
|
### Agentic loop (`AL(cfg, messages)`) function
|
|
|
|
1. Call OpenAI-compatible Completions API (`POST {endpoint}/chat/completions`) forwarding relevant parameters from `cfg` (`model`, `temperature`, `stream`, `reasoning_effort`, etc., excluding internal agent configs like `endpoint`, `api_key`, `timeout`, `shell_timeout`, `max_al_iterations`, `color`, `context_window`) and optional `api_key` bearer header.
|
|
- Set custom `User-Agent` header (`Mozilla/5.0 (compatible; Bantam/1.0)`) to avoid gateway 403 blocks.
|
|
- Retry network/HTTP errors with Fibonacci backoff delays (`1s, 1s, 2s, 3s, 5s, 8s, 13s, 21s, 34s`).
|
|
- If `stream=true`, parse SSE stream (`data: {...}`) for real-time reasoning and text output, bracketing reasoning with `--- reasoning start ---` / `--- reasoning end ---` markers.
|
|
2. Append the assistant's response message object to `messages`. If non-streaming and response has reasoning tokens (`reasoning_content` or `reasoning`), output them wrapped in `--- reasoning start ---` / `--- reasoning end ---` markers.
|
|
3. If there are pending `tool_calls` in the assistant response:
|
|
- For each tool call, output a trace log (`[tool call: name(args)]`).
|
|
- Sanitize tool arguments to filter out non-printable and space-like Unicode characters (protecting against indirect prompt injection), and validate JSON arguments. If invalid, format a tool-error response so the LLM can self-correct.
|
|
- Execute tool action (`shell_exec` or `write_file`).
|
|
- Sanitize the tool result output to strip any non-printable and space-like Unicode characters (leaving only ASCII space, tab, newline, and printable Unicode characters).
|
|
- Output a trace log of the result (`[tool result: name]`).
|
|
- Append tool result message (`role: "tool"`, `tool_call_id`, `content`: result string) to `messages`.
|
|
- Loop back to step 1.
|
|
4. If no pending tool calls (or if `max_al_iterations` is reached), stop and return `messages` and accumulated usage.
|
|
|
|
If the API rejects the request with an `Invalid assistant message: content or tool_calls must be set` error (usually caused by a previously cut-off stream that left an empty assistant message in the session), all implementations strip the last `assistant`-role message from the session and retry the call.
|
|
|
|
### Model configuration parameters
|
|
|
|
(shared by all implementations; the config file — `.bantam.cfg` takes priority over `model.cfg` when both exist — is plain `key=value` with `#` comments)
|
|
|
|
- `endpoint` (base OpenAI-compatible API URL, default `https://api.kilo.ai/api/openrouter`)
|
|
- `model` (model name, default `kilo-auto/free`)
|
|
- `temperature` (model temperature, default 0.7)
|
|
- `api_key` (API key / Bearer token, optional; fall back to `OPENAI_API_KEY` env var)
|
|
- `stream` (stream response tokens in real-time, default `true`)
|
|
- `color` (ANSI coloring: `auto` (TTY-detected, default), `always`, or `never`; also disabled by `NO_COLOR`/`BANTAM_NO_COLOR` env vars)
|
|
- `timeout` (HTTP timeout in seconds for LLM API calls, default 300; in the Go port it bounds connection setup and time-to-first-byte, so long streaming responses are not cut off mid-stream)
|
|
- `shell_timeout` (timeout in seconds for `shell_exec` commands, default 120)
|
|
- `max_al_iterations` (max tool-call loop iterations per `AL()` invocation, default 1000)
|
|
- `context_window` (context window size in tokens, auto-discovered from `/models` API if available, fallback to this setting, default 200000)
|
|
|
|
- `bantam_tools_dir` (optional path to a directory of extra shell tools; the Go port appends `"Extra shell tools can be found at <dir>"` to the system prompt at startup when set. The `BANTAM_TOOLS_DIR` environment variable overrides this and is checked first; if neither is set, nothing is appended. Note: this is an agent-internal hint, not forwarded to the API.)
|
|
|
|
The Go port also supports SOCKS5 proxying via the `SOCKS_PROXY` (or `socks_proxy`) environment variable (e.g. `SOCKS_PROXY=socks5://127.0.0.1:1080` or `SOCKS_PROXY=127.0.0.1:1080`), falling back to standard `HTTP_PROXY` / `HTTPS_PROXY` environment variables.
|
|
|
|
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.
|
|
|
|
### Tool call definitions
|
|
|
|
#### `write_file` tool
|
|
|
|
- Parameters:
|
|
- `path` (string, required): JSON-escaped file path to write to (must be created unless existing).
|
|
- `offset` (integer, optional, default 0): byte offset to start writing from.
|
|
- `del_bytes` (integer, optional, default 0): bytes to delete starting from the `offset` prior to writing.
|
|
- `content` (string, required, may be empty): JSON-escaped content to write to the file.
|
|
- Return value: string
|
|
- Action: write `content` into the file at `path` starting at `offset` after deleting `del_bytes` bytes (creating the file and any necessary parent directories).
|
|
|
|
#### `shell_exec` tool
|
|
|
|
- Parameters: `command` (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.
|
|
|
|
## MicroBantam
|
|
|
|
MicroBantam (`mb`) is a compressed Perl 5 reference implementation of the same agent in **under 100 SLOC**, written to stay readable while keeping the full agentic core. It reads the config file (`.bantam.cfg` if present, else `model.cfg`) from the current working directory.
|
|
|
|
### Features
|
|
|
|
- Full agentic loop: LLM calls, `shell_exec` / `write_file` tool execution with JSON argument validation (invalid args are fed back so the model can self-correct)
|
|
- Indirect prompt injection defense: sanitizes tool parameters and tool outputs by filtering non-printable and space-like Unicode characters, preserving standard space, tab, newline, and printable Unicode characters
|
|
- A `...requesting...` in-flight indicator: in-place on a TTY (`\r` overwrite, erased on completion), a plain line when output is piped
|
|
- Session management: `/save`, `/list`, `/load <id>` (exact id only, no prefix matching), `/cfg <param> [val]`, and auto-save to `~/.bantam/sessions/autosave.json` after every turn and on exit; session ids get `-1`, `-2`, ... suffixes on same-second collisions
|
|
- Interactive mode (`/quit`, `/clear`, `/save`, `/list`, `/load <id>`, `/cfg`, `/help`) and file input mode
|
|
- Same built-in default system prompt and `OPENAI_API_KEY` fallback as the Go implementation
|
|
- Automatic recovery from `Invalid assistant message: content or tool_calls must be set` API errors: strips the last assistant message and retries (matches the Go port; note that a 4xx response other than this specific error aborts the run with an `API error` message, unlike the Go port which retries only on 5xx/408/429)
|
|
|
|
### What it drops
|
|
|
|
- Streaming (requests are non-streaming; `stream` is ignored)
|
|
- ANSI coloring/styling (`color` is ignored)
|
|
- Line editing, Ctrl+J multi-line prompts and history (plain single-line prompts)
|
|
- Fibonacci backoff network retries (a failed request aborts with an `API error` message)
|
|
- `/compact` context summarization
|
|
|
|
### Running MicroBantam
|
|
|
|
```bash
|
|
./mb # interactive (or: perl mb)
|
|
./mb prompt.txt # file input mode
|
|
```
|
|
|
|
## Repository layout
|
|
|
|
- `main.go`, `term_linux.go`, `term_bsd.go`, `term_windows.go`, `term_other.go` — Go implementation (stdlib only, module `code.luxferre.top/luxferre/bantam`)
|
|
- `mb` — MicroBantam, compressed Perl 5 implementation (core modules only, under 100 SLOC)
|
|
- `model.cfg` (or `.bantam.cfg`, which takes priority) — configuration file
|
|
- `README.md` — this document
|
|
|
|
## Extra tools
|
|
|
|
The `extras/` directory contains small, dependency-light shell scripts that extend Bantam without changing its core. Because Bantam's built-in tools are `shell_exec` and `write_file`, these helpers can be invoked directly by the agent through `shell_exec` to give it real-world capabilities (web search, live weather) that the base model alone does not have. They are plain `/bin/sh` scripts depending only on `curl` (and `jq` where noted), so the agent can discover and run them just like any other command.
|
|
|
|
If you keep your own collection of helper scripts, point Bantam at them with the `BANTAM_TOOLS_DIR` environment variable or the `bantam_tools_dir` key in the config file (`.bantam.cfg` if present, else `model.cfg`). When either is defined (environment variable taking precedence over the config key), the Go port appends the line `Extra shell tools can be found at <dir>` to the system prompt at startup, so the agent is aware of where to look for them. The `extras/` scripts shipped here are just examples of what such a directory can contain.
|
|
|
|
### `extras/websearch`
|
|
|
|
|
|
A simple web search tool for Bantam built on [Exa's MCP server](https://mcp.exa.ai/mcp)
|
|
(Streamable HTTP). It speaks the JSON-RPC MCP protocol (`initialize` ->
|
|
`notifications/initialized` -> `tools/call` with `web_search_exa`) and prints
|
|
the formatted result text. Usage:
|
|
|
|
```sh
|
|
extras/websearch "your query" # default 5 results
|
|
extras/websearch "your query" 10 # custom number of results
|
|
```
|
|
|
|
Environment:
|
|
|
|
- `EXA_MCP_ENDPOINT` — endpoint URL (default `https://mcp.exa.ai/mcp`).
|
|
- `EXA_API_KEY` — optional; when set, it is passed as an `?api_key=` query
|
|
parameter so no extra HTTP headers are added beyond `Content-Type`.
|
|
|
|
Dependencies: `curl`, `jq`.
|
|
|
|
### `extras/weather`
|
|
|
|
A wrapper around the [wttr.in](https://github.com/chubin/wttr.in) weather API
|
|
that queries current conditions and forecasts for any location. It supports the
|
|
graphical ANSI terminal view (default), one-line presets (`1`-`4`), custom
|
|
`%`-notation formats, and the rich JSON document (`?format=j1`). Usage:
|
|
|
|
```sh
|
|
extras/weather # auto-detect location from request IP
|
|
extras/weather London # graphical report
|
|
extras/weather -f 3 "New York" # one-line preset
|
|
extras/weather -f "%l: %c %t" Paris # custom one-line format
|
|
extras/weather -u u -L de Berlin # USCS units, German output
|
|
extras/weather -j Tokyo # raw JSON (pretty-printed via jq)
|
|
```
|
|
|
|
Options include `-l/--location`, `-u/--units` (`m`/`u`/`M`), `-L/--lang`,
|
|
`-f/--format`, `-j/--json`, `-0`/`-1`/`-2` (view depth), `-q`/`--quiet`,
|
|
`-A` (force ANSI) and `-h/--help`. Environment overrides: `WTTRAPI` (default
|
|
`https://wttr.in`) and `WEATHER_TIMEOUT` (default `20`s).
|
|
|
|
Dependencies: `curl`, `jq` (only required for the JSON format).
|
|
|
|
### `extras/context7`
|
|
|
|
A documentation lookup tool for Bantam backed by the
|
|
[Context7 public MCP server](https://mcp.context7.com/mcp). It speaks the same
|
|
JSON-RPC MCP protocol as `websearch` (`initialize` ->
|
|
`notifications/initialized` -> `tools/call`) and prints the returned text.
|
|
Context7 keeps up-to-date docs and code examples for thousands of libraries and
|
|
exposes two tools, both wrapped here:
|
|
|
|
- `resolve-library-id` — maps a library name to a Context7 ID
|
|
(`/org/project`).
|
|
- `query-docs` — fetches documentation and code examples for a resolved ID.
|
|
|
|
Usage:
|
|
|
|
```sh
|
|
extras/context7 resolve "React" "hooks" # list candidate library IDs
|
|
extras/context7 query "/reactjs/react.dev" "useEffect cleanup" # fetch docs
|
|
extras/context7 docs "Express" "middleware error handling" # resolve + query
|
|
extras/context7 --help
|
|
```
|
|
|
|
The `docs` subcommand is a convenience that resolves the library, auto-selects
|
|
the top-ranked match, and immediately queries it (the chosen ID is printed to
|
|
stderr so stdout stays clean for piping). Environment overrides:
|
|
`CONTEXT7_MCP_ENDPOINT` (default `https://mcp.context7.com/mcp`) and
|
|
`CONTEXT7_API_KEY` (optional; sent as the `X-Context7-API-Key` header for
|
|
higher rate limits / private docs).
|
|
|
|
Dependencies: `curl`, `jq`.
|
|
|
|
|
|
## FAQ
|
|
|
|
### Does Bantam support `AGENTS.md`?
|
|
|
|
The default system prompt instructs the agent to respect `AGENTS.md` contents in the project.
|
|
|
|
### How do I tell Bantam about extra shell tools?
|
|
|
|
Set the `BANTAM_TOOLS_DIR` environment variable (or the `bantam_tools_dir` key in the config file — `.bantam.cfg` if present, else `model.cfg`) to a directory containing your helper scripts. When defined, the Go port appends `Extra shell tools can be found at <dir>` to the system prompt at startup, making the agent aware of them. The environment variable takes precedence over the config key; if neither is set, nothing is appended.
|
|
|
|
### Is there any common config place for Bantam?
|
|
|
|
No, loading the config file (`.bantam.cfg` if present, else `model.cfg`) is deliberately only supported from the current working directory. This allows natural separation of configs per project. In case there's no config file inside the project, Bantam will use the `kilo/auto-free` model from Kilo Code with the temperature 0.7.
|
|
|
|
### Why no MCP support?
|
|
|
|
If you need MCP server tools, there's nothing a simple shell wrapper cannot solve in this case.
|
|
|
|
### Why no sandboxing?
|
|
|
|
Same philosophy as the Pi agent: there's nothing a simple chroot environment cannot solve in case sandboxing is really necessary.
|
|
|
|
### Any advanced authentication schemes or header injection?
|
|
|
|
You can pair Bantam with the [Dynagate](https://code.luxferre.top/luxferre/dynagate) LLM gateway to achieve all that.
|
|
|
|
### How to run on mobiles?
|
|
|
|
On Android, Bantam (Go) and MicroBantam (`mb`) are easily runnable within the Termux environment. The Go implementation is preferred for performance reasons.
|
|
|
|
On iOS/iPadOS, the easiest way to use Bantam is to run MicroBantam (`mb`) inside iSH. Some terminal features may not be available (run with `rlwrap` to bring them back), but the agent itself is fully functional.
|
|
|
|
## Credits
|
|
|
|
Created by Luxferre in 2026, released into the public domain with no warranties.
|