LLM primitives for Python. You own the loop.
Project description
barebone
LLM primitives for Python. You own the loop.
from barebone import complete, user
response = complete("claude-sonnet-4", [user("What is 2+2?")])
print(response.content)
Install
pip install barebone
Philosophy
barebone provides LLM primitives — you write the orchestration in Python.
complete()— single LLM callexecute()— run a toolTool— define toolsMessage,Response,ToolCall— types
No hidden loops. No magic. Just primitives.
Basic Usage
from barebone import complete, user
messages = [user("Explain quantum computing in one sentence")]
response = complete("claude-sonnet-4", messages)
print(response.content)
Tools
Define tools as classes:
from barebone import Tool, Param
class GetWeather(Tool):
"""Get weather for a city."""
city: str = Param(description="City name")
def execute(self) -> str:
return f"72°F and sunny in {self.city}"
Agent Loop
You own the loop:
from barebone import complete, execute, user, tool_result
tools = [GetWeather]
messages = [user("What's the weather in Paris?")]
while True:
response = complete("claude-sonnet-4", messages, tools=tools)
if not response.tool_calls:
print(response.content)
break
for tool_call in response.tool_calls:
result = execute(tool_call, tools)
messages.append(tool_result(tool_call, result))
Async
import asyncio
from barebone import acomplete, aexecute, user, tool_result
async def main():
tools = [GetWeather]
messages = [user("What's the weather in Tokyo?")]
while True:
response = await acomplete("claude-sonnet-4", messages, tools=tools)
if not response.tool_calls:
print(response.content)
break
for tool_call in response.tool_calls:
result = await aexecute(tool_call, tools)
messages.append(tool_result(tool_call, result))
asyncio.run(main())
Built-in Tools
from barebone import Read, Write, Edit, Bash, Glob, Grep
from barebone import WebFetch, WebSearch, HttpRequest
from barebone import Python
| Tool | Description |
|---|---|
Read |
Read files |
Write |
Write files |
Edit |
Find and replace |
Bash |
Run commands |
Glob |
Find files by pattern |
Grep |
Search file contents |
WebFetch |
Fetch web pages |
WebSearch |
Search the web |
HttpRequest |
HTTP requests |
Python |
Execute Python |
Hooks
Add lifecycle hooks to tool execution:
from barebone import Hooks, Deny, tool_result
hooks = Hooks()
@hooks.before
def validate(tool_call):
if tool_call.name == "Bash":
raise Deny("Bash not allowed")
@hooks.after
def log(tool_call, result):
print(f"{tool_call.name}: {result[:50]}")
# Use hooks.run() instead of execute()
for tool_call in response.tool_calls:
result = hooks.run(tool_call, tools)
messages.append(tool_result(tool_call, result))
System Prompt
response = complete(
"claude-sonnet-4",
messages,
system="You are a helpful assistant.",
)
Memory
Log conversations:
from barebone import Memory
memory = Memory("./chat.db") # SQLite
memory.log("user", "Hello")
memory.log("assistant", "Hi there!")
# Retrieve
messages = memory.get_messages()
Authentication
Set environment variables:
export ANTHROPIC_API_KEY=sk-ant-...
# or
export OPENROUTER_API_KEY=sk-or-...
Or pass explicitly:
response = complete("claude-sonnet-4", messages, api_key="sk-ant-...")
API Reference
complete(model, messages, **kwargs) -> Response
Make a single LLM call.
| Param | Type | Description |
|---|---|---|
model |
str |
Model name |
messages |
list[Message] |
Conversation |
system |
str |
System prompt |
tools |
list[Tool] |
Available tools |
api_key |
str |
API key |
max_tokens |
int |
Max response tokens |
temperature |
float |
Sampling temperature |
execute(tool_call, tools) -> str
Execute a tool call.
user(content) -> Message
Create a user message.
assistant(content) -> Message
Create an assistant message.
tool_result(tool_call, result) -> Message
Create a tool result message.
Hooks
Composable hooks for tool execution lifecycle.
| Method | Description |
|---|---|
@hooks.before |
Register a before hook. Raise Deny to reject. |
@hooks.after |
Register an after hook. Return value replaces result. |
hooks.run(tool_call, tools) |
Execute with hooks: before → execute → after |
hooks.arun(tool_call, tools) |
Async version of run |
License
MIT
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 barebone-0.1.0.tar.gz.
File metadata
- Download URL: barebone-0.1.0.tar.gz
- Upload date:
- Size: 26.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1263fd4be35a528fb4d4b6fa030d974ab76c65313171138c74e8e660317baa11
|
|
| MD5 |
ea0956474a5224aa41871a52ef30abbf
|
|
| BLAKE2b-256 |
4a39bdaac134da84fef61e35cb13b32598082ad002f3248dee38f62f98218489
|
File details
Details for the file barebone-0.1.0-py3-none-any.whl.
File metadata
- Download URL: barebone-0.1.0-py3-none-any.whl
- Upload date:
- Size: 27.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d8b61c3a60a86d8b33c64ed786ebf03a01d01ad8d70554a7b661b274ab367ac2
|
|
| MD5 |
6e61c66b8e0e28d8c98459677995ce7c
|
|
| BLAKE2b-256 |
4615167ba8cdc3f5aed2331c655722f272fa3564c0d1f03d44a575eb8b517226
|