An exploration of making an agent sdk as lean as possible while being effective.
Project description
minimal-harness
A lightweight Python agent harness for building LLM-powered agents with tool-calling support. An exploration of making an agent SDK as lean as possible while being effective.
Features
- Simple
Agentclass for building LLM-powered agents - Tool-calling support with concurrent execution
- Streaming response support via chunk callbacks
- Conversation history management with
Memoryinterface - Built-in tools:
glob(file pattern matching) andgrep(content search) - Multiple LLM backends: OpenAI-compatible and LiteLLM
- Extensible LLM provider interface
Installation
pip install -e . # Basic install
pip install -e ".[test]" # With test dependencies
pip install -e ".[demo]" # With demo dependencies
pip install -e ".[dev]" # All dev dependencies
Quick Start
import asyncio
from minimal_harness import Agent, Tool, OpenAILLMProvider
from openai import AsyncOpenAI
async def get_weather(city: str) -> dict:
return {"city": city, "temperature": "22°C", "condition": "Sunny"}
tools = [
Tool(
name="get_weather",
description="Get weather for a specified city",
parameters={
"type": "object",
"properties": {"city": {"type": "string", "description": "City name"}},
"required": ["city"],
},
fn=get_weather,
),
]
client = AsyncOpenAI(api_key="your-api-key", base_url="https://aihubmix.com/v1")
async def on_chunk(chunk, is_done):
if is_done:
print()
return
delta = chunk.choices[0].delta if chunk.choices else None
if delta and delta.content:
print(delta.content, end="", flush=True)
llm_provider = OpenAILLMProvider(client=client, model="qwen3.5-27b", on_chunk=on_chunk)
agent = Agent(llm_provider=llm_provider, tools=tools)
result = await agent.run("What's the weather in Beijing?")
print(result)
Demo
Run an interactive TUI demo:
python demo/cli.py
Agent
The Agent class manages conversation context and tool execution.
Constructor
Agent(
llm_provider: LLMProvider,
tools: list[Tool] | None = None,
max_iterations: int = 10,
memory: Memory | None = None,
tool_executor: ToolExecutor | None = None,
)
Methods
run(user_input: str, on_chunk: ChunkCallback | None = None) -> str- Run the agent with user input
LLMProvider
The LLMProvider is a protocol that defines the interface for LLM backends.
OpenAILLMProvider
OpenAILLMProvider(client: AsyncOpenAI, model: str = "qwen3.5-27b")
LiteLLMProvider
LiteLLMProvider(model: str = "qwen3.5-27b", **kwargs)
Memory
Memory classes manage conversation history.
ConversationMemory
ConversationMemory(system_prompt: str = "You are a helpful assistant.")
Tool
Define tools that the agent can call.
Tool(
name: str,
description: str,
parameters: dict, # OpenAI function parameters schema
fn: Callable[..., Awaitable[Any]], # Async function implementation
)
ToolExecutor
Executes tool calls concurrently and returns results as messages.
Built-in Tools
glob
File pattern matching tool.
from minimal_harness.tool import glob
tool = glob()
grep
Content search tool.
from minimal_harness.tool import grep
tool = grep()
Testing
pip install -e ".[test]"
pytest
Project details
Release history Release notifications | RSS feed
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 minimal_harness-0.2.0.tar.gz.
File metadata
- Download URL: minimal_harness-0.2.0.tar.gz
- Upload date:
- Size: 21.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c444b6bd71bb38f7e1eedbd131859fbb15e34abcddaaca928d58ab738b660736
|
|
| MD5 |
4ec59a74b5fcc2c774e6f6cad03145b3
|
|
| BLAKE2b-256 |
a48018a00f73766a01aa90f727af561e0bf2719e6f00c4e77b7294ee98103379
|
File details
Details for the file minimal_harness-0.2.0-py3-none-any.whl.
File metadata
- Download URL: minimal_harness-0.2.0-py3-none-any.whl
- Upload date:
- Size: 37.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e5e1fc04b1d7004f31fecdcea3ac8b2b3cf901a67f547dac2c3f31efcde1d2a7
|
|
| MD5 |
15a20894b5102fc44286032392774974
|
|
| BLAKE2b-256 |
4fc33f8e70e55421e57f6c1cd4b34d4d7dc0a45413b6a9fa63b765ba767541e9
|