Skip to main content

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 APICustom AgentsPer-Agent ModelsEvent HooksPyPI 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:


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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

llama2a-0.1.1.tar.gz (26.6 kB view details)

Uploaded Source

Built Distribution

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

llama2a-0.1.1-py3-none-any.whl (33.5 kB view details)

Uploaded Python 3

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

Hashes for llama2a-0.1.1.tar.gz
Algorithm Hash digest
SHA256 71e0341cda01eaf51735ead4659ff49651562dadaf9417ad2ffc202de6db0432
MD5 bfb64e271e51358813acf10121ea1c92
BLAKE2b-256 8cae948afd3505b13db075b1cb3e4035327d7cdc8b0622d16b21cc4b8058d9fa

See more details on using hashes here.

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

Hashes for llama2a-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6bba42f9468ab4a8e839881638aab6c1e23ea411fa0db277ed995872a3753aa0
MD5 a507bc02f105c4b5b0cb2dec5573eed6
BLAKE2b-256 d300a5c5ce94b38eef21c376864fc5f3778bc9be9d562ed6a75bdafee269c961

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