Lightweight single-file agent framework
Project description
BOS AI
Lightweight, extensible infrastructure for building agentic systems in Python.
bos-ai is an actor-based framework for running LLM-driven agents with explicit
message routing, configurable runtime boundaries, and a small core. It is meant
to be shaped into different kinds of agentic systems rather than forcing one
opinionated product workflow.
What It Is
- Fully configurable: agents, tools, skills, memories, channels, runtime, and storage are configured in TOML and wired through extension points.
- Actor-based: agents communicate through a
MailRouteplus boundMailBoxcapabilities instead of direct in-process coupling. - Built for composition: the same core can back a local TUI, an HTTP/WebSocket endpoint, or a Telegram bot. Server-side chat cursors let one client resume threads created from another client.
- Small core, explicit boundaries: contracts, defaults, harness lifecycle, runtime orchestration, and extensions are kept separate.
Privacy
BOS AI does not ship with built-in telemetry, analytics, or hosted data collection. Your privacy boundary is defined by the models, tools, channels, and storage backends you configure.
If you use your own local or self-hosted model and keep your channels and storage local, BOS AI itself does not require sending your data to any BOS-owned service.
Quickstart
Install the package:
pip install bos-ai
Initialize a workspace:
mkdir my-agent
cd my-agent
bos init
Start the agent runtime:
bos start
Connect the built-in TUI:
bos tui
Useful lifecycle commands:
bos status
bos restart
bos stop
Workspace Model
Each workspace gets a .bos/config.toml. BOS AI searches upward from the
current directory for .bos/config.toml. If no workspace-local .bos exists,
set BOS_DIR explicitly. If both an ancestor .bos and BOS_DIR are present
but point to different locations, BOS AI fails with an ambiguity error instead
of silently choosing one.
Agent definitions may stay inline in .bos/config.toml or be placed in external
directories. By default, .bos/agents/ is auto-scanned. To customize the scan
locations:
[platform]
agent_dirs = ["agents", "../shared-agents", "~/.bos/agents", "/opt/agents"]
Relative paths are resolved against .bos/; absolute paths and ~ are
supported. External agents are <dir>/<name>.toml files or <dir>/<name>.md
files. For Markdown agents, optional YAML-style frontmatter supplies settings
such as name, description, tools, and exclude_tools; the Markdown body is
the system_prompt. If name is provided in the file it is used as-is; if
omitted, the name is derived from the filename stem. Inline agents load first,
external agents load second (alphabetically within each directory, directories
processed in list order), exact-name duplicates are last-wins, and case-only
collisions are errors. Workspace.config stays as the raw manifest, and
runtime-facing agent config is produced through a resolved platform view.
For the full rule set and resolver behavior, see
docs/architecture/config-workspace.md.
By default, the primary actor is addressed as agent@main. The selected main
agent implementation is configured separately under [main].agent.
Example channel configuration:
[main]
agent = "main"
[[main.channels]]
name = "HttpChannel"
bind_address = "channel@http"
target_address = "agent@main"
host = "127.0.0.1"
port = 5920
#[[main.channels]]
#name = "TelegramChannel"
#bind_address = "channel@telegram"
#target_address = "agent@main"
#token = "123456:telegram-bot-token"
#poll_timeout = 30
#allowed_chat_ids = [123456789]
This keeps routing explicit:
- channels target
agent@maindirectly - client cursors are stored server-side by
client_id - aliases can point to durable
chat_idvalues for cross-client resume
Named Actors
Named Actors let one runtime host multiple long-lived, addressable actors. The
actor key under [main.actors] is the route name, mailbox identity, and memory
scope. The agent field is the reusable agent kind, so multiple actors can
instantiate the same agent definition with different runtime identities.
[main.actors.main]
agent = "assistant"
display_name = "Main"
[main.actors.bob]
agent = "architect"
display_name = "Bob"
[main.actors.investment]
agent = "assistant"
display_name = "Investment"
Channels that support mention routing can route a message such as @bob review this design to agent@bob. Channels can also bind directly to a specific actor
with target_address = "agent@investment".
Named Actors is a routing feature, not autonomous swarm orchestration. Planning, delegation lifecycle, actor-to-actor relay, and result synthesis belong in a separate orchestration layer.
Runtime
The agent can run in-process or in Docker.
Docker runtime example:
[main.runtime]
kind = "docker"
image = "bos-ai:local"
workspace_dir = "/workspace"
Build and run:
docker build -t bos-ai:local .
bos start
bos tui
When Docker is enabled, HttpChannel host binding is normalized for container
access, and BOS AI publishes configured HTTP channel ports automatically.
Named agents are capability-deny by default. Omitted tools, skills,
memories, and subagents settings are treated as empty allow-lists. Configure
each agent with explicit allow-lists, or use "*" to allow all names in that
capability group:
[[platform.agents]]
name = "main"
tools = ["ReadFile", "SearchFiles"]
skills = "*"
memories = ["user", "memory"]
subagents = ["researcher"]
exclude_tools, exclude_skills, exclude_memories, and exclude_subagents
can still be used to subtract names from an allow-list, including from "*".
Scratch agents created directly through harness.create_agent() without a named
agent config also start with no tools, skills, memories, or subagents.
Skills
Skills are discovered from configured skill directories. A skill is a directory
containing SKILL.md; the directory name is the skill name. Configure workspace
skill roots with:
[harness.skills_loader]
skill_dirs = ["skills"]
Agents see allowed skills in the system prompt with each skill's SKILL.md
location and summary. LoadSkill reads and returns the full SKILL.md
instructions as a tool result; it does not permanently mutate the agent's
system prompt.
Subagent Orchestration
BOS already supports a lightweight form of subagent orchestration inside one active harness. The pattern is:
- register multiple named agent profiles under
platform.agents - allow the parent agent to use the local
AskSubagenttool - scope which specialists it may call with
subagents = [...] - customize specialist behavior under
[[harness.subagents]]
This is delegated orchestration, not a second long-running actor process. The
parent agent stays at agent@main, while specialist agents are invoked on
demand as additional agent.ask(...) calls with their own chat IDs.
Minimal use case: a manager agent handles the user-facing chat and
delegates focused document analysis to a researcher subagent.
[platform.agent_defaults]
tools = []
subagents = []
[[platform.agents]]
name = "main"
description = "User-facing manager."
tools = ["AskSubagent"]
subagents = ["researcher"]
system_prompt = """
Handle the user-facing workflow. Delegate focused repo analysis when needed.
"""
[[platform.agents]]
name = "researcher"
description = "Focused repo analyst."
tools = []
system_prompt = """
You only perform focused research tasks delegated by the main agent.
Return concise findings.
"""
[[harness.subagents]]
name = "researcher"
task_template = """
You are the {agent_name} specialist.
Use this dedicated thread for delegated analysis work.
Task:
{task}
"""
AskSubagent always runs the specialist in a fresh child thread. The runtime
derives that child chat_id from the current parent thread plus a
short agent tag and random suffix, for example
parent-chat~researcher1a2b3c4d.
Extension Points
The framework is designed to be reconfigured and extended, not forked.
Harness Consolidator
Chat history compaction is handled by a harness-level consolidator service. The
agent owns the dynamic history budget (max_tokens) and decides when compaction
is needed; the consolidator owns the model and instruction used to summarize.
Configure the default LLM-backed consolidator with:
[harness.consolidator]
model = "gemini/gemini-2.5-flash"
instruction = """
Summarize the conversation history for future turns.
Preserve user intent, decisions, unresolved tasks, tool results, and important constraints.
"""
The consolidator model is resolved from harness.consolidator.model, then
BOS_CONSOLIDATOR_MODEL, then BOS_MODEL. It does not fall back to
platform.agent_defaults.model.
Core extension points include:
@ep_providerfor model backends@ep_toolfor tool calls@ep_memory_storefor long-term memory backends@ep_message_storefor chat history@ep_mail_routefor message transport@ep_turn_interceptorfor turn loop interception@ep_channelfor external interfaces like HTTP, Telegram, or grouped channels
Minimal example:
from bos.core import ep_tool
@ep_tool(
name="echo_upper",
description="Return an uppercase version of the input.",
parameters={
"type": "object",
"properties": {"text": {"type": "string"}},
"required": ["text"],
},
)
async def echo_upper(text: str) -> str:
return text.upper()
Load extensions by adding their modules to platform.extensions in
.bos/config.toml.
CLI
The built-in CLI currently exposes:
bos initbos authbos startbos stopbos statusbos restartbos tui
Global workspace selection:
bos -w /path/to/workspace start
What BOS AI Is Good For
- local-first agent runtimes
- custom tool-using assistants
- multi-agent or actor-based orchestration experiments
- private deployments with self-hosted models
- channel-driven agents exposed over HTTP or Telegram
If you want a fixed hosted product, this repo is probably too low-level. If you want infrastructure for shaping your own agent runtime, this is the right layer.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bos_ai-1.1.0.tar.gz.
File metadata
- Download URL: bos_ai-1.1.0.tar.gz
- Upload date:
- Size: 252.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f268bf0bc41b90341c6bc2e9cfcd6b6b318a85aea103c0993867ea7028a0ab0a
|
|
| MD5 |
f9b78cb0caec1c663708c87e092a42cb
|
|
| BLAKE2b-256 |
2d115353f579c90c2b8d1a9a7f93fa32c4987a14adef01f3448fcea3e9f64ba9
|
Provenance
The following attestation bundles were made for bos_ai-1.1.0.tar.gz:
Publisher:
release.yml on bos-agent/bos-ai
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bos_ai-1.1.0.tar.gz -
Subject digest:
f268bf0bc41b90341c6bc2e9cfcd6b6b318a85aea103c0993867ea7028a0ab0a - Sigstore transparency entry: 1439118467
- Sigstore integration time:
-
Permalink:
bos-agent/bos-ai@96dfc0096f5e084bf328b36974d91091168260a7 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/bos-agent
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@96dfc0096f5e084bf328b36974d91091168260a7 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file bos_ai-1.1.0-py3-none-any.whl.
File metadata
- Download URL: bos_ai-1.1.0-py3-none-any.whl
- Upload date:
- Size: 123.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
908c0f2359585ace8b6086ef3450ee991b0c016190c171b20bd0042a7360966d
|
|
| MD5 |
9f4358cba5a0a42a7f8ad54b01ecffed
|
|
| BLAKE2b-256 |
6022492defc659d6282dcbf690d0d2b5067da5661e93986b67dde4449f20e0c2
|
Provenance
The following attestation bundles were made for bos_ai-1.1.0-py3-none-any.whl:
Publisher:
release.yml on bos-agent/bos-ai
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bos_ai-1.1.0-py3-none-any.whl -
Subject digest:
908c0f2359585ace8b6086ef3450ee991b0c016190c171b20bd0042a7360966d - Sigstore transparency entry: 1439118468
- Sigstore integration time:
-
Permalink:
bos-agent/bos-ai@96dfc0096f5e084bf328b36974d91091168260a7 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/bos-agent
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@96dfc0096f5e084bf328b36974d91091168260a7 -
Trigger Event:
workflow_dispatch
-
Statement type: