refinire 0.3.2
Refined simplicity for AI agents - Build intelligent workflows with automatic quality assurance and multi-provider LLM support
License: MIT
Requires Python: >=3.10
Keywords: agents, ai, llm, orchestration, workflow

# Refinire ✨ - Refined Simplicity for Agentic AI

[![PyPI Downloads](https://static.pepy.tech/badge/refinire)](https://pepy.tech/projects/refinire)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![OpenAI Agents 0.0.17](https://img.shields.io/badge/OpenAI-Agents_0.0.17-green.svg)](https://github.com/openai/openai-agents-python)
[![Coverage](https://img.shields.io/badge/coverage-85%25-brightgreen.svg)]

**Transform ideas into working AI agents—intuitive agent framework**

---

## Why Refinire?

- **Simple installation** — Just `pip install refinire`
- **Simplify LLM-specific configuration** — No complex setup required
- **Unified API across providers** — OpenAI / Anthropic / Google / Ollama  
- **Built-in evaluation & regeneration loops** — Quality assurance out of the box
- **One-line parallel processing** — Complex async operations with just `{"parallel": [...]}`
- **Comprehensive observability** — Automatic tracing with OpenTelemetry integration

## 30-Second Quick Start

```bash
pip install refinire
```

**Optional**: Set up environment variables easily with the interactive CLI:

```bash
pip install "refinire[cli]"
refinire-setup
```

```python
from refinire import RefinireAgent

# Simple AI agent
agent = RefinireAgent(
    name="assistant",
    generation_instructions="You are a helpful assistant.",
    model="gpt-4o-mini"
)

result = agent.run("Hello!")
print(result.content)
```

## The Core Components

Refinire provides key components to support AI agent development.

## RefinireAgent - Integrated Generation and Evaluation

```python
from refinire import RefinireAgent

# Agent with automatic evaluation
agent = RefinireAgent(
    name="quality_writer",
    generation_instructions="Generate high-quality, informative content with clear structure and engaging writing style",
    evaluation_instructions="""Evaluate the content quality on a scale of 0-100 based on:
    - Clarity and readability (0-25 points)
    - Accuracy and factual correctness (0-25 points)  
    - Structure and organization (0-25 points)
    - Engagement and writing style (0-25 points)
    
    Provide your evaluation as:
    Score: [0-100]
    Comments:
    - [Specific feedback on strengths]
    - [Areas for improvement]
    - [Suggestions for enhancement]""",
    threshold=85.0,  # Automatically regenerate if score < 85
    max_retries=3,
    model="gpt-4o-mini"
)

result = agent.run("Write an article about AI")
print(f"Quality Score: {result.evaluation_score}")
print(f"Content: {result.content}")
```

## Orchestration Mode - Multi-Agent Coordination

**The Challenge**: Building complex multi-agent systems requires standardized communication protocols between agents. Different output formats make agent coordination difficult and error-prone.

**The Solution**: RefinireAgent's orchestration mode provides structured JSON output with standardized status, result, reasoning, and next-step hints. This enables seamless integration in multi-agent workflows where agents need to communicate their status and recommend next actions.

**Key Benefits**:
- **Standardized Communication**: Unified JSON protocol for agent-to-agent interaction
- **Smart Coordination**: Agents provide hints about recommended next steps
- **Error Handling**: Clear status reporting (completed/failed) for robust workflows
- **Type Safety**: Structured output with optional Pydantic model integration

### Basic Orchestration Mode

```python
from refinire import RefinireAgent

# Agent configured for orchestration
orchestrator_agent = RefinireAgent(
    name="analysis_worker",
    generation_instructions="Analyze the provided data and provide insights",
    orchestration_mode=True,  # Enable structured output
    model="gpt-4o-mini"
)

# Returns structured JSON instead of Context
result = orchestrator_agent.run("Analyze user engagement trends")

# Standard orchestration response format
print(f"Status: {result['status']}")           # "completed" or "failed"
print(f"Result: {result['result']}")           # Analysis output
print(f"Reasoning: {result['reasoning']}")     # Why this result was generated
print(f"Next Task: {result['next_hint']['task']}")        # Recommended next step
print(f"Confidence: {result['next_hint']['confidence']}")  # Confidence level (0-1)
```

### Orchestration with Structured Output

```python
from pydantic import BaseModel
from refinire import RefinireAgent

class AnalysisReport(BaseModel):
    findings: list[str]
    recommendations: list[str]
    confidence_score: float

# Orchestration mode with typed result
agent = RefinireAgent(
    name="structured_analyst",
    generation_instructions="Generate detailed analysis report",
    orchestration_mode=True,
    output_model=AnalysisReport,  # Result will be typed
    model="gpt-4o-mini"
)

result = agent.run("Analyze customer feedback data")

# result['result'] is now a typed AnalysisReport object
report = result['result']
print(f"Findings: {report.findings}")
print(f"Recommendations: {report.recommendations}")
print(f"Confidence: {report.confidence_score}")
```

### Multi-Agent Workflow Coordination

```python
from refinire import RefinireAgent, Flow, FunctionStep

# Orchestration-enabled agents
data_collector = RefinireAgent(
    name="data_collector",
    generation_instructions="Collect and prepare data for analysis",
    orchestration_mode=True,
    model="gpt-4o-mini"
)

analyzer = RefinireAgent(
    name="analyzer", 
    generation_instructions="Perform deep analysis on collected data",
    orchestration_mode=True,
    model="gpt-4o-mini"
)

reporter = RefinireAgent(
    name="reporter",
    generation_instructions="Generate final report with recommendations",
    orchestration_mode=True,
    model="gpt-4o-mini"
)

def orchestration_router(ctx):
    """Route based on agent recommendations"""
    if hasattr(ctx, 'result') and isinstance(ctx.result, dict):
        next_task = ctx.result.get('next_hint', {}).get('task', 'unknown')
        if next_task == 'analysis':
            return 'analyzer'
        elif next_task == 'reporting':
            return 'reporter'
    return 'end'

# Workflow with orchestration-based routing
flow = Flow({
    "collect": data_collector,
    "route": ConditionStep("route", orchestration_router, "analyzer", "end"),
    "analyzer": analyzer,
    "report": reporter
})

result = await flow.run("Process customer survey data")
```

**Key Orchestration Features**:
- **Status Tracking**: Clear completion/failure status for workflow control
- **Result Typing**: Optional Pydantic model integration for type safety
- **Next-Step Hints**: Agents recommend optimal next actions with confidence levels
- **Reasoning Transparency**: Agents explain their decision-making process
- **Error Handling**: Structured error reporting for robust multi-agent systems
- **Backward Compatibility**: Normal mode continues to work unchanged (orchestration_mode=False)

## Streaming Output - Real-time Response Display

**Stream responses in real-time** for improved user experience and immediate feedback. Both RefinireAgent and Flow support streaming output, perfect for chat interfaces, live dashboards, and interactive applications.

### Basic RefinireAgent Streaming

```python
from refinire import RefinireAgent

agent = RefinireAgent(
    name="streaming_assistant",
    generation_instructions="Provide detailed, helpful responses",
    model="gpt-4o-mini"
)

# Stream response chunks as they arrive
async for chunk in agent.run_streamed("Explain quantum computing"):
    print(chunk, end="", flush=True)  # Real-time display
```

### Streaming with Callback Processing

```python
# Custom processing for each chunk
chunks_received = []
def process_chunk(chunk: str):
    chunks_received.append(chunk)
    # Send to websocket, update UI, save to file, etc.

async for chunk in agent.run_streamed(
    "Write a Python tutorial", 
    callback=process_chunk
):
    print(chunk, end="", flush=True)

print(f"\nReceived {len(chunks_received)} chunks")
```

### Context-Aware Streaming

```python
from refinire import Context

# Maintain conversation context across streaming responses
ctx = Context()

# First message
async for chunk in agent.run_streamed("Hello, I'm learning Python", ctx=ctx):
    print(chunk, end="", flush=True)

# Context-aware follow-up
ctx.add_user_message("What about async programming?")
async for chunk in agent.run_streamed("What about async programming?", ctx=ctx):
    print(chunk, end="", flush=True)
```

### Flow Streaming

**Flows also support streaming** for complex multi-step workflows:

```python
from refinire import Flow, FunctionStep

flow = Flow({
    "analyze": FunctionStep("analyze", analyze_input),
    "generate": RefinireAgent(
        name="writer", 
        generation_instructions="Write detailed content"
    )
})

# Stream entire flow output
async for chunk in flow.run_streamed("Create a technical article"):
    print(chunk, end="", flush=True)
```

### Structured Output Streaming

**Important**: When using structured output (Pydantic models) with streaming, the response is streamed as **JSON chunks**, not parsed objects:

```python
from pydantic import BaseModel

class Article(BaseModel):
    title: str
    content: str
    tags: list[str]

agent = RefinireAgent(
    name="structured_writer",
    generation_instructions="Generate an article",
    output_model=Article  # Structured output
)

# Streams JSON chunks: {"title": "...", "content": "...", "tags": [...]}
async for json_chunk in agent.run_streamed("Write about AI"):
    print(json_chunk, end="", flush=True)
    
# For parsed objects, use regular run() method:
result = await agent.run_async("Write about AI")
article = result.content  # Returns Article object
```

**Key Streaming Features**:
- **Real-time Output**: Immediate response as content is generated
- **Callback Support**: Custom processing for each chunk  
- **Context Continuity**: Streaming works with conversation context
- **Flow Integration**: Stream complex multi-step workflows
- **JSON Streaming**: Structured output streams as JSON chunks
- **Error Handling**: Graceful handling of streaming interruptions


## Flow Architecture: Orchestrate Complex Workflows

**The Challenge**: Building complex AI workflows requires managing multiple agents, conditional logic, parallel processing, and error handling. Traditional approaches lead to rigid, hard-to-maintain code.

**The Solution**: Refinire's Flow Architecture lets you compose workflows from reusable steps. Each step can be a function, condition, parallel execution, or AI agent. Flows handle routing, error recovery, and state management automatically.

**Key Benefits**:
- **Composable Design**: Build complex workflows from simple, reusable components
- **Visual Logic**: Workflow structure is immediately clear from the code
- **Automatic Orchestration**: Flow engine handles execution order and data passing
- **Built-in Parallelization**: Dramatic performance improvements with simple syntax

### Simple Yet Powerful

```python
from refinire import Flow, FunctionStep, ConditionStep

# Define your workflow as a composable flow
flow = Flow({
    "start": FunctionStep("analyze", analyze_request),
    "route": ConditionStep("route", route_by_complexity, "simple", "complex"),
    "simple": RefinireAgent(name="simple", generation_instructions="Quick response"),
    "complex": {
        "parallel": [
            RefinireAgent(name="expert1", generation_instructions="Deep analysis"),
            RefinireAgent(name="expert2", generation_instructions="Alternative perspective")
        ],
        "next_step": "aggregate"
    },
    "aggregate": FunctionStep("combine", combine_results)
})

result = await flow.run("Complex user request")
```

**🎯 Complete Flow Guide**: For comprehensive workflow construction learning, explore our detailed step-by-step guides:

**📖 English**: [Complete Flow Guide](docs/tutorials/flow_complete_guide_en.md) - From basics to advanced parallel processing  
**📖 日本語**: [Flow完全ガイド](docs/tutorials/flow_complete_guide_ja.md) - 包括的なワークフロー構築ガイド

### Flow Design Patterns

**Simple Routing**:
```python
# Automatic routing based on user language
def detect_language(ctx):
    return "japanese" if any(char in ctx.user_input for char in "あいうえお") else "english"

flow = Flow({
    "detect": ConditionStep("detect", detect_language, "jp_agent", "en_agent"),
    "jp_agent": RefinireAgent(name="jp", generation_instructions="日本語で丁寧に回答"),
    "en_agent": RefinireAgent(name="en", generation_instructions="Respond in English professionally")
})
```

**High-Performance Parallel Analysis**:
```python
# Execute multiple analyses simultaneously
flow = Flow(start="preprocess", steps={
    "preprocess": FunctionStep("preprocess", clean_data),
    "analysis": {
        "parallel": [
            RefinireAgent(name="sentiment", generation_instructions="Perform sentiment analysis"),
            RefinireAgent(name="keywords", generation_instructions="Extract keywords"),
            RefinireAgent(name="summary", generation_instructions="Create summary"),
            RefinireAgent(name="classification", generation_instructions="Classify content")
        ],
        "next_step": "report",
        "max_workers": 4
    },
    "report": FunctionStep("report", generate_final_report)
})
```

**Compose steps like building blocks. Each step can be a function, condition, parallel execution, or LLM pipeline.**

---

## 1. Unified LLM Interface

**The Challenge**: Switching between AI providers requires different SDKs, APIs, and authentication methods. Managing multiple provider integrations creates vendor lock-in and complexity.

**The Solution**: RefinireAgent provides a single, consistent interface across all major LLM providers. Provider selection happens automatically based on your environment configuration, eliminating the need to manage multiple SDKs or rewrite code when switching providers.

**Key Benefits**:
- **Provider Freedom**: Switch between OpenAI, Anthropic, Google, and Ollama without code changes
- **Zero Vendor Lock-in**: Your agent logic remains independent of provider specifics
- **Automatic Resolution**: Environment variables determine the optimal provider automatically
- **Consistent API**: Same method calls work across all providers

```python
from refinire import RefinireAgent

# Just specify the model name—provider is resolved automatically
agent = RefinireAgent(
    name="assistant",
    generation_instructions="You are a helpful assistant.",
    model="gpt-4o-mini"  # OpenAI
)

# Anthropic, Google, and Ollama are also supported in the same way
agent2 = RefinireAgent(
    name="anthropic_assistant",
    generation_instructions="For Anthropic model",
    model="claude-3-sonnet"  # Anthropic
)

agent3 = RefinireAgent(
    name="google_assistant",
    generation_instructions="For Google Gemini",
    model="gemini-pro"  # Google
)

agent4 = RefinireAgent(
    name="ollama_assistant",
    generation_instructions="For Ollama model",
    model="llama3.1:8b"  # Ollama
)
```

This makes switching between providers and managing API keys extremely simple, greatly increasing development flexibility.

**📖 Tutorial:** [Quickstart Guide](docs/tutorials/quickstart.md) | **Details:** [Unified LLM Interface](docs/unified-llm-interface.md)

## 2. Autonomous Quality Assurance

**The Challenge**: AI outputs can be inconsistent, requiring manual review and regeneration. Quality control becomes a bottleneck in production systems.

**The Solution**: RefinireAgent includes built-in evaluation that automatically assesses output quality and regenerates content when it falls below your standards. This creates a self-improving system that maintains consistent quality without manual intervention.

**Key Benefits**:
- **Automatic Quality Control**: Set thresholds and let the system maintain standards
- **Self-Improving**: Failed outputs trigger regeneration with improved prompts
- **Production Ready**: Consistent quality without manual oversight
- **Configurable Standards**: Define your own evaluation criteria and thresholds

```python
from refinire import RefinireAgent

# Agent with evaluation loop
agent = RefinireAgent(
    name="quality_assistant",
    generation_instructions="Generate helpful responses",
    evaluation_instructions="Rate accuracy and usefulness from 0-100",
    threshold=85.0,
    max_retries=3,
    model="gpt-4o-mini"
)

result = agent.run("Explain quantum computing")
print(f"Evaluation Score: {result.evaluation_score}")
print(f"Content: {result.content}")

# With Context for workflow integration
from refinire import Context
ctx = Context()
result_ctx = agent.run("Explain quantum computing", ctx)
print(f"Evaluation Result: {result_ctx.evaluation_result}")
print(f"Score: {result_ctx.evaluation_result['score']}")
print(f"Passed: {result_ctx.evaluation_result['passed']}")
print(f"Feedback: {result_ctx.evaluation_result['feedback']}")
```

If evaluation falls below threshold, content is automatically regenerated for consistent high quality.

**📖 Tutorial:** [Advanced Features](docs/tutorials/advanced.md) | **Details:** [Autonomous Quality Assurance](docs/autonomous-quality-assurance.md)

## Intelligent Routing System

**The Challenge**: Complex AI workflows need to dynamically determine the next step based on generated content. Manual conditional branching is complex and hard to maintain.

**The Solution**: RefinireAgent's new routing functionality automatically analyzes generated content and determines the next step based on quality, complexity, or completion status. This enables dynamic workflow control within flows.

**Key Benefits**:
- **Automatic Flow Control**: Dynamic step routing based on content quality
- **Flexible Analysis Modes**: Accuracy-focused or performance-focused execution modes
- **Type-Safe Output**: Structured routing results using Pydantic models
- **Seamless Integration**: Complete integration with existing Flow architecture

### Basic Routing Functionality

```python
from refinire import RefinireAgent

# Agent with routing functionality
agent = RefinireAgent(
    name="smart_processor",
    generation_instructions="Generate appropriate responses to user requests",
    routing_instruction="Evaluate content quality and determine next processing: high quality → 'complete', needs improvement → 'enhance', insufficient → 'regenerate'",
    routing_mode="accurate_routing",  # Accuracy-focused analysis
    model="gpt-4o-mini"
)

result = agent.run("Explain machine learning")

# Access routing results
print(f"Generated Content: {result.content}")
print(f"Next Route: {result.next_route}")
print(f"Confidence: {result.confidence}")
print(f"Reasoning: {result.reasoning}")
```

### Combining with Structured Output

```python
from pydantic import BaseModel, Field

class ArticleOutput(BaseModel):
    title: str = Field(description="Article title")
    content: str = Field(description="Article content")
    keywords: list[str] = Field(description="Keywords list")

# Combine structured output with routing
agent = RefinireAgent(
    name="article_generator", 
    generation_instructions="Create detailed articles on specified topics",
    output_model=ArticleOutput,
    routing_instruction="Evaluate article quality and determine next processing: excellent → 'publish', good → 'review', needs improvement → 'revise'",
    routing_mode="accurate_routing",  # Accuracy-focused analysis
    model="gpt-4o-mini"
)

result = agent.run("Write an article about quantum computing")

# Access both structured content and routing information
article = result.content  # ArticleOutput object
print(f"Title: {article.title}")
print(f"Keywords: {article.keywords}")
print(f"Next Action: {result.next_route}")
```

### Flow Workflow Routing Integration

```python
from refinire import Flow, FunctionStep, Context

# Function that utilizes routing results
def route_based_processor(ctx: Context):
    routing_result = ctx.routing_result
    if routing_result:
        quality = routing_result['confidence']
        next_route = routing_result['next_route']
        
        # Branch processing based on routing results
        if next_route == "complete":
            ctx.goto("finalize")
        elif next_route == "enhance":
            ctx.goto("improvement")
        else:
            ctx.goto("regenerate")
    else:
        ctx.goto("default_process")

# Routing integrated flow
flow = Flow({
    "analyze": RefinireAgent(
        name="content_analyzer",
        generation_instructions="Analyze content and determine quality",
        routing_instruction="Determine next processing based on quality level: high quality → 'complete', medium quality → 'enhance', low quality → 'regenerate'",
        routing_mode="accurate_routing"
    ),
    "router": FunctionStep("router", route_based_processor),
    "complete": FunctionStep("complete", finalize_content),
    "enhance": FunctionStep("enhance", improve_content),
    "regenerate": FunctionStep("regenerate", regenerate_content),
    "finalize": FunctionStep("finalize", publish_content)
})

result = await flow.run("Process technical article content")
```

### Routing Mode Selection

```python
# Accuracy-focused mode - detailed analysis and high-quality routing decisions
accurate_agent = RefinireAgent(
    name="quality_analyzer",
    generation_instructions="Generate high-quality content",
    routing_instruction="Rigorously evaluate content and determine appropriate next step",
    routing_mode="accurate_routing",  # Separate agent for detailed analysis
    model="gpt-4o-mini"
)

# Note: Only accurate_routing mode is supported
# Routing decisions are made by separate agents for highest accuracy
```

**Key Routing Features**:
- **Dynamic Content Analysis**: Automatic quality assessment of generated content
- **Flexible Routing Instructions**: Define custom routing logic
- **Accurate Routing**: Routing decisions made by separate agents for highest quality
- **Structured Output Support**: Complete integration with custom data types
- **Flow Integration**: Automatic routing decisions within workflows
- **Context Preservation**: Share routing results across workflow stages

**📖 Detailed Guide**: [New Flow Control Concept](docs/new_flow_control_concept.md) - Complete routing system explanation

## 3. Tool Integration - Automated Function Calling

**The Challenge**: AI agents often need to interact with external systems, APIs, or perform calculations. Manual tool integration is complex and error-prone.

**The Solution**: RefinireAgent automatically detects when to use tools and executes them seamlessly. Simply provide decorated functions, and the agent handles tool selection, parameter extraction, and execution automatically.

**Key Benefits**:
- **Zero Configuration**: Decorated functions are automatically available as tools
- **Intelligent Selection**: Agent chooses appropriate tools based on user requests
- **Error Handling**: Built-in retry and error recovery for tool execution
- **Extensible**: Easy to add custom tools for your specific use cases

```python
from refinire import RefinireAgent, tool

@tool
def calculate(expression: str) -> float:
    """Calculate mathematical expressions"""
    return eval(expression)

@tool
def get_weather(city: str) -> str:
    """Get weather for a city"""
    return f"Weather in {city}: Sunny, 22°C"

# Agent with tools
agent = RefinireAgent(
    name="tool_assistant",
    generation_instructions="Answer questions using tools",
    tools=[calculate, get_weather],
    model="gpt-4o-mini"
)

result = agent.run("What's the weather in Tokyo? Also, what's 15 * 23?")
print(result.content)  # Automatically answers both questions
```

### MCP Server Integration - Model Context Protocol

RefinireAgent natively supports **MCP (Model Context Protocol) servers**, providing standardized access to external data sources and tools:

```python
from refinire import RefinireAgent

# MCP server integrated agent
agent = RefinireAgent(
    name="mcp_agent",
    generation_instructions="Use MCP server tools to accomplish tasks",
    mcp_servers=[
        "stdio://filesystem-server",  # Local filesystem access
        "http://localhost:8000/mcp",  # Remote API server
        "stdio://database-server --config db.json"  # Database access
    ],
    model="gpt-4o-mini"
)

# MCP tools become automatically available
result = agent.run("Analyze project files and include database information in your report")
```

**MCP Server Types:**
- **stdio servers**: Run as local subprocess
- **HTTP servers**: Remote HTTP endpoints  
- **WebSocket servers**: Real-time communication support

**Automatic Features:**
- Tool auto-discovery from MCP servers
- Dynamic tool registration and execution
- Error handling and retry logic
- Parallel management of multiple servers

**📖 Tutorial:** [Advanced Features](docs/tutorials/advanced.md) | **Details:** [Composable Flow Architecture](docs/composable-flow-architecture.md)

## 4. Automatic Parallel Processing: Dramatic Performance Boost

**The Challenge**: Sequential processing of independent tasks creates unnecessary bottlenecks. Manual async implementation is complex and error-prone.

**The Solution**: Refinire's parallel processing automatically identifies independent operations and executes them simultaneously. Simply wrap operations in a `parallel` block, and the system handles all async coordination.

**Key Benefits**:
- **Automatic Optimization**: System identifies parallelizable operations
- **Dramatic Speedup**: 4x+ performance improvements are common
- **Zero Complexity**: No async/await or thread management required
- **Scalable**: Configurable worker pools adapt to your workload

Dramatically improve performance with parallel execution:

```python
from refinire import Flow, FunctionStep
import asyncio

# Define parallel processing with DAG structure
flow = Flow(start="preprocess", steps={
    "preprocess": FunctionStep("preprocess", preprocess_text),
    "parallel_analysis": {
        "parallel": [
            FunctionStep("sentiment", analyze_sentiment),
            FunctionStep("keywords", extract_keywords), 
            FunctionStep("topic", classify_topic),
            FunctionStep("readability", calculate_readability)
        ],
        "next_step": "aggregate",
        "max_workers": 4
    },
    "aggregate": FunctionStep("aggregate", combine_results)
})

# Sequential execution → Parallel execution (significant speedup)
result = await flow.run("Analyze this comprehensive text...")
```

Run complex analysis tasks simultaneously without manual async implementation.

**📖 Tutorial:** [Advanced Features](docs/tutorials/advanced.md) | **Details:** [Composable Flow Architecture](docs/composable-flow-architecture.md)

### Conditional Intelligence

```python
# AI that makes decisions
def route_by_complexity(ctx):
    return "simple" if len(ctx.user_input) < 50 else "complex"

flow = Flow({
    "router": ConditionStep("router", route_by_complexity, "simple", "complex"),
    "simple": SimpleAgent(),
    "complex": ExpertAgent()
})
```

### Parallel Processing: Dramatic Performance Boost

```python
from refinire import Flow, FunctionStep

# Process multiple analysis tasks simultaneously
flow = Flow(start="preprocess", steps={
    "preprocess": FunctionStep("preprocess", preprocess_text),
    "parallel_analysis": {
        "parallel": [
            FunctionStep("sentiment", analyze_sentiment),
            FunctionStep("keywords", extract_keywords),
            FunctionStep("topic", classify_topic),
            FunctionStep("readability", calculate_readability)
        ],
        "next_step": "aggregate",
        "max_workers": 4
    },
    "aggregate": FunctionStep("aggregate", combine_results)
})

# Sequential execution → Parallel execution (significant speedup)
result = await flow.run("Analyze this comprehensive text...")
```

**Intelligence flows naturally through your logic, now with lightning speed.**

---

## Interactive Conversations

```python
from refinire import create_simple_interactive_pipeline

def completion_check(result):
    return "finished" in str(result).lower()

# Multi-turn conversation agent
pipeline = create_simple_interactive_pipeline(
    name="conversation_agent",
    instructions="Have a natural conversation with the user.",
    completion_check=completion_check,
    max_turns=10,
    model="gpt-4o-mini"
)

# Natural conversation flow
result = pipeline.run_interactive("Hello, I need help with my project")
while not result.is_complete:
    user_input = input(f"Turn {result.turn}: ")
    result = pipeline.continue_interaction(user_input)

print("Conversation complete:", result.content)
```

**Conversations that remember, understand, and evolve.**

---

## Monitoring and Insights

### Real-time Agent Analytics

```python
# Search and analyze your AI agents
registry = get_global_registry()

# Find specific patterns
customer_flows = registry.search_by_agent_name("customer_support")
performance_data = registry.complex_search(
    flow_name_pattern="support",
    status="completed",
    min_duration=100
)

# Understand performance patterns
for flow in performance_data:
    print(f"Flow: {flow.flow_name}")
    print(f"Average response time: {flow.avg_duration}ms")
    print(f"Success rate: {flow.success_rate}%")
```

### Quality Monitoring

```python
# Automatic quality tracking
quality_flows = registry.search_by_quality_threshold(min_score=80.0)
improvement_candidates = registry.search_by_quality_threshold(max_score=70.0)

# Continuous improvement insights
print(f"High-quality flows: {len(quality_flows)}")
print(f"Improvement opportunities: {len(improvement_candidates)}")
```

**Your AI's performance becomes visible, measurable, improvable.**

---

## Installation & Quick Start

### Install

```bash
pip install refinire
```

### Environment Setup (Recommended)

Set up your environment variables interactively:

```bash
# Install with CLI support
pip install "refinire[cli]"

# Run interactive setup wizard
refinire-setup
```

The CLI will guide you through:
- **Provider Selection**: Choose from OpenAI, Anthropic, Google, OpenRouter, Groq, Ollama, or LM Studio
- **Feature Configuration**: Enable tracing, agent settings, or development features
- **Template Generation**: Create a customized `.env` file

**Manual Setup**: Alternatively, set environment variables manually:

```bash
export OPENAI_API_KEY="your-api-key-here"
export REFINIRE_DEFAULT_LLM_MODEL="gpt-4o-mini"
```

📖 **Complete Guide**: [Environment Variables](docs/environment_variables.md) | [CLI Tool](docs/cli.md)

### Your First Agent (30 seconds)

```python
from refinire import RefinireAgent

# Create
agent = RefinireAgent(
    name="hello_world",
    generation_instructions="You are a friendly assistant.",
    model="gpt-4o-mini"
)

# Run
result = agent.run("Hello!")
print(result.content)
```

### Provider Flexibility

```python
from refinire import get_llm

# Test multiple providers
providers = [
    ("openai", "gpt-4o-mini"),
    ("anthropic", "claude-3-haiku-20240307"),
    ("google", "gemini-1.5-flash"),
    ("ollama", "llama3.1:8b")
]

for provider, model in providers:
    try:
        llm = get_llm(provider=provider, model=model)
        print(f"✓ {provider}: {model} - Ready")
    except Exception as e:
        print(f"✗ {provider}: {model} - {str(e)}")
```

## Environment Management with oneenv Namespaces

**The Challenge**: Managing environment variables across different environments (development, testing, production) can be complex and error-prone. Traditional approaches require multiple `.env` files or manual environment switching.

**The Solution**: Refinire supports oneenv 0.4.0+ namespace functionality, allowing you to organize environment variables by namespace and switch between different configurations seamlessly.

**Key Benefits**:
- **Environment Separation**: Clear separation between development, testing, and production configurations
- **Namespace Organization**: Group related environment variables by purpose or environment
- **Simplified Configuration**: Single source of truth for all environment variables
- **Backward Compatibility**: Works with existing `os.getenv()` patterns

### Basic Namespace Usage

```python
from refinire import RefinireAgent

# Development environment
dev_agent = RefinireAgent(
    name="dev_assistant",
    generation_instructions="You are a helpful assistant.",
    model="gpt-4o-mini",
    namespace="development"  # Uses development environment variables
)

# Production environment
prod_agent = RefinireAgent(
    name="prod_assistant", 
    generation_instructions="You are a helpful assistant.",
    model="gpt-4o-mini",
    namespace="production"  # Uses production environment variables
)
```

### Environment Configuration Management

Set up different environments with oneenv:

```bash
# Install oneenv if not already installed
pip install oneenv

# Initialize environment configuration
oneenv init

# Set development environment variables
oneenv set OPENAI_API_KEY "dev-key-here" --namespace development
oneenv set ANTHROPIC_API_KEY "dev-claude-key" --namespace development
oneenv set REFINIRE_DEFAULT_LLM_MODEL "gpt-4o-mini" --namespace development

# Set production environment variables  
oneenv set OPENAI_API_KEY "prod-key-here" --namespace production
oneenv set ANTHROPIC_API_KEY "prod-claude-key" --namespace production
oneenv set REFINIRE_DEFAULT_LLM_MODEL "gpt-4o" --namespace production

# Set testing environment variables
oneenv set OPENAI_API_KEY "test-key-here" --namespace testing
oneenv set ANTHROPIC_API_KEY "test-claude-key" --namespace testing
oneenv set REFINIRE_DEFAULT_LLM_MODEL "gpt-4o-mini" --namespace testing
```

### Provider-Specific Namespace Support

All major providers support namespace-based configuration:

```python
from refinire import get_llm

# OpenAI with namespace
openai_llm = get_llm(
    provider="openai",
    model="gpt-4o-mini",
    namespace="development"
)

# Anthropic with namespace
anthropic_llm = get_llm(
    provider="anthropic", 
    model="claude-3-haiku-20240307",
    namespace="development"
)

# Google with namespace
google_llm = get_llm(
    provider="google",
    model="gemini-1.5-flash", 
    namespace="development"
)

# Ollama with namespace
ollama_llm = get_llm(
    provider="ollama",
    model="llama3.1:8b",
    namespace="development"
)
```

### Workflow Integration with Namespaces

```python
from refinire import RefinireAgent, Flow, FunctionStep

# Create environment-aware agents
dev_analyzer = RefinireAgent(
    name="dev_analyzer",
    generation_instructions="Analyze the input data",
    model="gpt-4o-mini",
    namespace="development"
)

prod_analyzer = RefinireAgent(
    name="prod_analyzer", 
    generation_instructions="Analyze the input data",
    model="gpt-4o",
    namespace="production"
)

# Environment-specific workflow
def create_analysis_flow(environment="development"):
    return Flow({
        "analyze": RefinireAgent(
            name="analyzer",
            generation_instructions="Perform analysis",
            model="gpt-4o-mini",
            namespace=environment
        ),
        "summarize": RefinireAgent(
            name="summarizer",
            generation_instructions="Create summary",
            model="gpt-4o-mini", 
            namespace=environment
        )
    })

# Use different environments
dev_flow = create_analysis_flow("development")
prod_flow = create_analysis_flow("production")
```

### Environment Variable Mapping

Refinire automatically maps environment variables based on namespace:

| Variable | Development | Production | Testing |
|----------|-------------|------------|---------|
| `OPENAI_API_KEY` | `dev-key-here` | `prod-key-here` | `test-key-here` |
| `ANTHROPIC_API_KEY` | `dev-claude-key` | `prod-claude-key` | `test-claude-key` |
| `REFINIRE_DEFAULT_LLM_MODEL` | `gpt-4o-mini` | `gpt-4o` | `gpt-4o-mini` |

### Backward Compatibility

If oneenv is not installed or namespace is not specified, Refinire falls back to standard environment variables:

```python
# Works with or without oneenv
agent = RefinireAgent(
    name="compatible_agent",
    generation_instructions="You are helpful",
    model="gpt-4o-mini"
    # No namespace specified - uses standard environment variables
)
```

**📖 Complete Environment Setup Guide**: [Environment Variables](docs/environment_variables.md) | [oneenv Documentation](https://github.com/kitadai31/oneenv)

---

## Advanced Features

### Structured Output

```python
from pydantic import BaseModel
from refinire import RefinireAgent

class WeatherReport(BaseModel):
    location: str
    temperature: float
    condition: str

agent = RefinireAgent(
    name="weather_reporter",
    generation_instructions="Generate weather reports",
    output_model=WeatherReport,
    model="gpt-4o-mini"
)

result = agent.run("Weather in Tokyo")
weather = result.content  # Typed WeatherReport object
```

### Guardrails and Safety

```python
from refinire import RefinireAgent

def content_filter(content: str) -> bool:
    """Filter inappropriate content"""
    return "inappropriate" not in content.lower()

agent = RefinireAgent(
    name="safe_assistant",
    generation_instructions="Be helpful and appropriate",
    output_guardrails=[content_filter],
    model="gpt-4o-mini"
)
```

### Custom Tool Integration

```python
from refinire import RefinireAgent, tool

@tool
def web_search(query: str) -> str:
    """Search the web for information"""
    # Your search implementation
    return f"Search results for: {query}"

agent = RefinireAgent(
    name="research_assistant",
    generation_instructions="Help with research using web search",
    tools=[web_search],
    model="gpt-4o-mini"
)
```

### Context Management - Intelligent Memory

**The Challenge**: AI agents lose context between conversations and lack awareness of relevant files or code. This leads to repetitive questions and less helpful responses.

**The Solution**: RefinireAgent's context management automatically maintains conversation history, analyzes relevant files, and searches your codebase for pertinent information. The agent builds a comprehensive understanding of your project and maintains it across conversations.

**Key Benefits**:
- **Persistent Memory**: Conversations build upon previous interactions
- **Code Awareness**: Automatic analysis of relevant source files
- **Dynamic Context**: Context adapts based on current conversation topics
- **Intelligent Filtering**: Only relevant information is included to avoid token limits

RefinireAgent provides sophisticated context management for enhanced conversations:

```python
from refinire import RefinireAgent

# Agent with conversation history and file context
agent = RefinireAgent(
    name="code_assistant",
    generation_instructions="Help with code analysis and improvements",
    context_providers_config=[
        {
            "type": "conversation_history",
            "max_items": 10
        },
        {
            "type": "fixed_file",
            "file_path": "src/main.py",
            "description": "Main application file"
        },
        {
            "type": "source_code",
            "base_path": "src/",
            "file_patterns": ["*.py"],
            "max_files": 5
        }
    ],
    model="gpt-4o-mini"
)

# Context is automatically managed across conversations
result = agent.run("What's the main function doing?")
print(result.content)

# Context persists and evolves
result = agent.run("How can I improve the error handling?")
print(result.content)
```

**📖 Tutorial:** [Context Management](docs/tutorials/context_management.md) | **Details:** [Context Management Design](docs/context_management.md)

### Dynamic Prompt Generation - Variable Embedding

R