Skip to main content

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 call
  • execute() — run a tool
  • Tool — define tools
  • Message, 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

barebone-0.1.0.tar.gz (26.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

barebone-0.1.0-py3-none-any.whl (27.3 kB view details)

Uploaded Python 3

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

Hashes for barebone-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1263fd4be35a528fb4d4b6fa030d974ab76c65313171138c74e8e660317baa11
MD5 ea0956474a5224aa41871a52ef30abbf
BLAKE2b-256 4a39bdaac134da84fef61e35cb13b32598082ad002f3248dee38f62f98218489

See more details on using hashes here.

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

Hashes for barebone-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d8b61c3a60a86d8b33c64ed786ebf03a01d01ad8d70554a7b661b274ab367ac2
MD5 6e61c66b8e0e28d8c98459677995ce7c
BLAKE2b-256 4615167ba8cdc3f5aed2331c655722f272fa3564c0d1f03d44a575eb8b517226

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page