swebot-client
Python client for the swebot autonomous coding agent.
Pure Python — zero dependencies beyond the standard library.
Install
# pip
pip install swebot-client
# uv
uv add swebot-client
Quick start
from swebot_client import SwebotClient
client = SwebotClient("http://localhost:8080")
session = client.create_session()
# Stream tokens
for token in session.stream("explain goroutines"):
print(token, end="", flush=True)
# Or get the full reply at once
reply = session.send("what is 2+2?")
print(reply)
Features
- Streaming — real-time token-by-token output via SSE
- Tool callbacks — observe tool invocations and results
- Session management — create, resume, list, delete sessions
- Mode / model control — switch modes, models, thinking, reasoning
- Todos & checkpoints — read, create, update, delete todos; list/restore checkpoints
- MCP management — configure MCP servers programmatically
- Plugin management — install, remove, enable, disable plugins
- AgentSpeak — multi-agent collaboration (join, leave, send messages)
- Context control — compact or clear session context
- Skills — list built-in skill agents
Examples
from swebot_client import SwebotClient, ToolCall
client = SwebotClient("http://localhost:8080")
client.wait_until_ready(timeout=10)
# Set mode to autonomous so the agent executes (not plans)
client.set_mode("autonomous")
# Enable extended thinking
client.set_thinking("high")
# Switch model
client.set_model("claude-opus-4-5")
# Create a session and send a message
session = client.create_session(agent="developer")
def on_tool(tc: ToolCall):
print(f" ⚙ {tc.name}")
reply = session.send_with_events(
"create a hello.py file",
on_tool_start=on_tool,
)
# Read todos
for todo in session.get_todos():
print(f"[{todo.status}] {todo.title}")
# Token usage
usage = session.token_usage()
print(f"Tokens: {usage['tokens_in']:,} in / {usage['tokens_out']:,} out ({usage['usage_pct']}%)")
Pipeline example
from swebot_client import SwebotClient
client = SwebotClient()
client.wait_until_ready()
client.set_mode("autonomous")
# Stage 1: generate
s1 = client.create_session()
code = s1.send("Write a Python prime sieve for 0-1000000")
# Stage 2: review
s2 = client.create_session("code_auditor")
review = s2.send(f"Review this code:\n{code}")
print(review)
API reference
SwebotClient(addr="http://localhost:8080")
No token needed for local use. If the backend was started with --token,
set SWEBOT_TOKEN in your environment — the SDK reads it automatically.
Sessions
| Method |
Description |
create_session(agent) |
Create a new session → Session |
get_session(id) |
Resume an existing session → Session |
list_sessions() |
List all sessions |
delete_session(id) |
Delete a session |
Agents / Providers / Models
| Method |
Description |
list_agents() |
List available agents |
get_agent(name) |
Get agent details (name, system_prompt, tools) |
list_providers() |
List LLM providers |
list_models(provider) |
List models for a provider → {provider, active, models} |
set_model(model, provider) |
Switch model (and optionally provider) |
Mode / Thinking / Reasoning
| Method |
Description |
get_mode() |
Current mode (plan, agent, autonomous) |
set_mode(mode) |
Set mode: "plan", "agent", "autonomous" |
get_thinking() |
Current thinking level |
set_thinking(level) |
Set thinking: "", "low", "medium", "high" |
get_reasoning() |
Current reasoning depth |
set_reasoning(level) |
Set reasoning: "low", "medium", "high" |
MCP Servers
| Method |
Description |
list_mcp() |
List MCP servers with connection state |
add_mcp(name, ...) |
Add a new MCP server |
update_mcp(name, ...) |
Update an existing server |
delete_mcp(name) |
Remove a server |
enable_mcp(name) |
Enable a disabled server |
disable_mcp(name) |
Disable without removing |
reload_mcp() |
Reconnect all enabled servers |
Plugins
| Method |
Description |
list_plugins() |
List installed plugins |
install_plugin(url) |
Install from GitHub (owner/repo) |
remove_plugin(name) |
Uninstall a plugin |
enable_plugin(name) |
Re-enable a disabled plugin |
disable_plugin(name) |
Disable without removing |
AgentSpeak (Multi-Agent)
| Method |
Description |
agentspeak_status() |
Connection status → {connected, project, role, url} |
agentspeak_projects() |
List visible projects |
agentspeak_who() |
List agents in current project |
agentspeak_messages(since) |
Fetch recent messages |
agentspeak_join(url, project, role) |
Connect and join a project |
agentspeak_leave() |
Disconnect from project |
agentspeak_send(message, to) |
Send message (broadcast or targeted) |
Backend Management
| Method |
Description |
health() |
Check if backend is reachable |
wait_until_ready(timeout) |
Block until backend responds |
stats() |
Backend stats (model, tokens, uptime) |
version() |
Version info (version, commit, latest) |
skills() |
List built-in skill agents |
panic() |
Emergency stop — cancel all, reset to plan mode |
shutdown() |
Gracefully stop the backend |
Session
Messaging
| Method |
Description |
stream(message) |
Stream tokens → Iterator[str] |
send(message) |
Send and get full reply → str |
send_with_events(msg, on_token, on_tool_start, on_tool_result) |
Send with callbacks → str |
Todos
| Method |
Description |
get_todos() |
List todo items → list[TodoItem] |
create_todo(title) |
Create a new todo |
update_todo(id, status) |
Update status: pending, in_progress, done |
delete_todo(id) |
Delete a todo |
Checkpoints
| Method |
Description |
list_checkpoints() |
List file checkpoints → list[dict] |
restore_checkpoint(id) |
Restore a file to a previous checkpoint |
Context
| Method |
Description |
compact() |
Trigger context compaction |
clear() |
Clear all session context |
token_usage() |
Token usage stats → {tokens_in, tokens_out, context_window, usage_pct} |
Info
| Method |
Description |
refresh() |
Reload session data from backend |
message_count |
Number of messages (property) |
Publishing to PyPI
cd sdk/python
python3 -m build
UV_PUBLISH_TOKEN=pypi-YOUR-TOKEN uv publish dist/*
Requirements
- Python 3.9+
- A running swebot backend (
swebot --serve)
License
MIT
Code review
Review what a session changed, then choose what to fix. Findings are verified
by an adversarial second pass — only confirmed ones can be applied.
from swebot_client import SwebotClient
session = SwebotClient().create_session()
session.send("Add a ParseInt helper to util/parse.go")
rev = session.review(mode="informative") # or "autonomous"
if rev.running:
rev = session.wait_for_review(rev.id)
for f in rev.findings:
print(f.id, f.severity, f.file, f.claim, "confirmed" if f.confirmed else "refuted")
keep = [f.id for f in rev.confirmed if f.blocking]
drop = [f.id for f in rev.confirmed if not f.blocking]
if keep:
session.apply_review(rev.id, keep)
if drop:
session.dismiss_findings(rev.id, drop, reason="not now")
A session that changed no files returns scope="out_of_scope" (or
"nothing_to_review") without calling a model at all.