A modular multi-agent framework for building AI development workflows with Ollama
Project description
llama2a 🔗
A minimal, zero-dependency Python library for building multi-agent workflows.
Fluent API • Custom Agents • Per-Agent Models • Event Hooks • PyPI Ready
Installation
pip install llama2a
Or install from source:
git clone https://github.com/yourusername/llama2a
cd llama2a
pip install -e .
Quick Start
from llama2a import llama2a
llama2a() \
.requirements("Build a calculator app with add, subtract, multiply, divide") \
.model("deepseek-coder-v2:16b") \
.output("./calculator") \
.run()
That's it. llama2a coordinates multiple AI agents to plan and implement your project.
Core Concepts
The Default Workflow
llama2a ships with 3 agents that form a complete development pipeline:
| Agent | Role | Responsibility |
|---|---|---|
| Contractor | Orchestrator | Coordinates the workflow, handles retries, verifies completion |
| Planner | Planning | Breaks requirements into concrete, ordered tasks |
| Coder | Implementation | Writes code to files based on task specifications |
Fluent API
Configure everything with method chaining:
llama2a()
.requirements("Your project description") # What to build
.model("llama3:8b") # Default model for all agents
.configure("planner", model="llama3:70b") # Planner gets a bigger model
.configure("coder", model="deepseek-coder-v2:16b") # Coder is specialized
.output("./my_project") # Where to write files
.run()
Configuration
Per-Agent Models
Use the right model for each task:
llama2a()
.requirements("Build a REST API")
.configure("planner", model="llama3:70b") # Planning: bigger model
.configure("coder", model="deepseek-coder-v2:16b") # Coding: code-focused model
.output("./api")
.run()
Agent Parameters
Pass custom parameters to specific agents:
llama2a()
.requirements("Build a game")
.configure("planner",
model="llama3:70b",
max_tasks=20, # Custom parameter
include_tests=True # Custom parameter
)
.configure("coder",
model="deepseek-coder-v2:16b",
style="verbose", # Custom parameter
language="python" # Custom parameter
)
.output("./game")
.run()
LLM Configuration
Configure the LLM endpoint:
from llama2a import ChainConfig
config = ChainConfig(
llm_base_url="http://localhost:11434", # Ollama default
default_model="llama3:8b",
)
llama2a(config)
.requirements("Build something")
.output("./output")
.run()
Custom Agents
Function-Based Agents
The simplest way to add an agent:
from llama2a import llama2a, agent, AgentContext, AgentResult
@agent(name="reviewer", role="Code Reviewer")
def review_code(context: AgentContext, llm) -> AgentResult:
code = context.get("code", "")
response = llm.generate(
"Review this code for issues:\n\n" + code,
model="llama3:8b"
)
return AgentResult.ok({"review": response})
# Use it
llama2a()
.requirements("Build a CLI tool")
.register("reviewer", review_code) # Add to this chain
.output("./cli")
.run()
Class-Based Agents
For more complex agents with state:
from llama2a import Agent, agent, AgentContext, AgentResult
@agent(name="tester", role="Test Writer")
class TesterAgent(Agent):
def execute(self, context: AgentContext) -> AgentResult:
code_files = context.get("files", [])
for file in code_files:
test_code = self._llm.generate(
f"Write tests for:\n{file['content']}",
model=self._config.get("model", "llama3:8b")
)
# Write test file...
return AgentResult.ok({"tests_created": len(code_files)})
Custom Orchestrator
Replace the entire workflow:
from llama2a import Orchestrator, orchestrator, AgentContext, AgentResult
@orchestrator(name="my_workflow", role="Custom Pipeline")
class MyOrchestrator(Orchestrator):
def execute(self, context: AgentContext) -> AgentResult:
# Phase 1: Your planning logic
plan_result = self.invoke_agent("planner", context)
# Phase 2: Your implementation logic
for task in plan_result.data.get("tasks", []):
self.invoke_agent("coder", AgentContext(
task=task["description"],
inputs=task
))
# Phase 3: Your custom phase
if self.get_agent("tester"):
self.invoke_agent("tester", context)
return AgentResult.ok({"status": "complete"})
# Use it
llama2a()
.requirements("Build something")
.orchestrator(MyOrchestrator)
.output("./output")
.run()
Events & Callbacks
Monitor progress with event hooks:
from llama2a import llama2a, Event
def on_progress(event_type, data):
print(f"[{event_type}] {data.get('message', '')}")
def on_task_complete(event_type, data):
task = data.get("task", {})
print(f"✓ Completed: {task.get('name')}")
llama2a()
.requirements("Build an app")
.on(Event.PROGRESS, on_progress)
.on(Event.TASK_COMPLETE, on_task_complete)
.on(Event.AGENT_ERROR, lambda e, d: print(f"Error: {d}"))
.output("./app")
.run()
Available Events
| Event | Trigger |
|---|---|
Event.CHAIN_START |
Chain execution begins |
Event.CHAIN_COMPLETE |
Chain execution finishes |
Event.AGENT_START |
An agent starts executing |
Event.AGENT_COMPLETE |
An agent finishes |
Event.AGENT_ERROR |
An agent encounters an error |
Event.TASK_START |
A task begins |
Event.TASK_COMPLETE |
A task completes |
Event.TASK_FAILED |
A task fails |
Event.PROGRESS |
General progress update |
CLI Usage
llama2a includes a command-line interface:
# Basic usage
llama2a "Build a todo app with Flask" --output ./todo-app
# With specific model
llama2a "Build a calculator" --model deepseek-coder-v2:16b --output ./calc
# Verbose output
llama2a "Build a game" --output ./game --verbose
API Reference
llama2a
The main entry point for building chains.
class llama2a:
def requirements(self, text: str) -> llama2a
def model(self, name: str) -> llama2a
def configure(self, agent_name: str, **kwargs) -> llama2a
def output(self, directory: str) -> llama2a
def orchestrator(self, cls: Type[Orchestrator]) -> llama2a
def register(self, name: str, agent: Agent | Callable) -> llama2a
def on(self, event: Event, handler: Callable) -> llama2a
def run(self) -> AgentResult
AgentContext
Data passed to agents:
class AgentContext:
task: str # Current task description
inputs: dict # Input data from previous agents
workspace: str # Output directory path
def get(self, key: str, default=None) -> Any
AgentResult
Return value from agents:
class AgentResult:
success: bool # Whether execution succeeded
data: dict # Output data
error: str | None # Error message if failed
@classmethod
def ok(cls, data: dict) -> AgentResult
@classmethod
def fail(cls, error: str) -> AgentResult
Requirements
- Python: 3.9+
- LLM Backend: Ollama running at
localhost:11434(configurable) - Dependencies: None (stdlib only!)
Examples
See the examples/ directory:
- minimal.py - Basic usage
- multi_model.py - Different models per agent
- custom_agent.py - Creating custom agents
- custom_orchestrator.py - Custom workflow
License
MIT License - see LICENSE
Contributing
Contributions welcome! Please read our contributing guidelines first.
# Development install
pip install -e ".[dev]"
# Run tests
pytest
# Format code
black src/
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 llama2a-0.1.1.tar.gz.
File metadata
- Download URL: llama2a-0.1.1.tar.gz
- Upload date:
- Size: 26.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
71e0341cda01eaf51735ead4659ff49651562dadaf9417ad2ffc202de6db0432
|
|
| MD5 |
bfb64e271e51358813acf10121ea1c92
|
|
| BLAKE2b-256 |
8cae948afd3505b13db075b1cb3e4035327d7cdc8b0622d16b21cc4b8058d9fa
|
File details
Details for the file llama2a-0.1.1-py3-none-any.whl.
File metadata
- Download URL: llama2a-0.1.1-py3-none-any.whl
- Upload date:
- Size: 33.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6bba42f9468ab4a8e839881638aab6c1e23ea411fa0db277ed995872a3753aa0
|
|
| MD5 |
a507bc02f105c4b5b0cb2dec5573eed6
|
|
| BLAKE2b-256 |
d300a5c5ce94b38eef21c376864fc5f3778bc9be9d562ed6a75bdafee269c961
|