Metadata-Version: 2.4
Name: agent-factory-core
Version: 0.3.4
Summary: Core library for building AI agents with pluggable models and channels
Project-URL: Homepage, https://github.com/dinocloud/dinocloud-agent-factory
Project-URL: Repository, https://github.com/dinocloud/dinocloud-agent-factory
Project-URL: Documentation, https://github.com/dinocloud/dinocloud-agent-factory#readme
Author-email: DinoCloud <dev@dinocloud.co>
License-Expression: MIT
Keywords: agents,ai,anthropic,bedrock,slack,teams
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Requires-Dist: httpx>=0.25.0
Requires-Dist: pydantic-settings>=2.0
Requires-Dist: pydantic>=2.0
Requires-Dist: tenacity>=8.0
Provides-Extra: all
Requires-Dist: anthropic>=0.40.0; extra == 'all'
Requires-Dist: aws-lambda-powertools>=3.0.0; extra == 'all'
Requires-Dist: aws-lambda-powertools[metrics,tracer]>=3.0.0; extra == 'all'
Requires-Dist: bedrock-agentcore>=0.1.0; extra == 'all'
Requires-Dist: botbuilder-core>=4.14.0; extra == 'all'
Requires-Dist: boto3>=1.35.0; extra == 'all'
Requires-Dist: botocore>=1.35.0; extra == 'all'
Requires-Dist: opentelemetry-api>=1.20.0; extra == 'all'
Requires-Dist: opentelemetry-sdk>=1.20.0; extra == 'all'
Requires-Dist: requests>=2.31.0; extra == 'all'
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.40.0; extra == 'anthropic'
Provides-Extra: aws
Requires-Dist: aws-lambda-powertools>=3.0.0; extra == 'aws'
Requires-Dist: boto3>=1.35.0; extra == 'aws'
Requires-Dist: botocore>=1.35.0; extra == 'aws'
Provides-Extra: bedrock
Requires-Dist: bedrock-agentcore>=0.1.0; extra == 'bedrock'
Requires-Dist: boto3>=1.35.0; extra == 'bedrock'
Requires-Dist: botocore>=1.35.0; extra == 'bedrock'
Provides-Extra: dev
Requires-Dist: mypy>=1.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Provides-Extra: observability
Requires-Dist: aws-lambda-powertools[metrics,tracer]>=3.0.0; extra == 'observability'
Requires-Dist: opentelemetry-api>=1.20.0; extra == 'observability'
Requires-Dist: opentelemetry-sdk>=1.20.0; extra == 'observability'
Provides-Extra: slack
Requires-Dist: requests>=2.31.0; extra == 'slack'
Provides-Extra: teams
Requires-Dist: botbuilder-core>=4.14.0; extra == 'teams'
Requires-Dist: requests>=2.31.0; extra == 'teams'
Description-Content-Type: text/markdown

# Agent Factory Core

Core library for building AI agents with pluggable models and channels.

## Installation

```bash
# Basic installation
pip install agent-factory-core

# With Bedrock support
pip install agent-factory-core[bedrock]

# With Anthropic API support
pip install agent-factory-core[anthropic]

# With Slack channel support
pip install agent-factory-core[slack]

# With Teams channel support
pip install agent-factory-core[teams]

# All providers
pip install agent-factory-core[all]
```

## Quick Start

### Basic Agent

```python
from agent_factory import AgentOrchestrator
from agent_factory.models import BedrockModel
from agent_factory.tools import tool

# Define a tool
@tool
def get_weather(city: str) -> str:
    """Get current weather for a city."""
    return f"Weather in {city}: 72°F, Sunny"

# Create orchestrator with Bedrock
orchestrator = AgentOrchestrator(
    model=BedrockModel(model_id="anthropic.claude-3-5-sonnet-20241022-v2:0"),
    system_prompt="You are a helpful weather assistant.",
    tools=[get_weather],
)

# Invoke
response = orchestrator.invoke(
    prompt="What's the weather in Miami?",
    session_id="user-123",
)
print(response["content"])
```

### Using Anthropic API

```python
from agent_factory import AgentOrchestrator
from agent_factory.models import AnthropicModel

orchestrator = AgentOrchestrator(
    model=AnthropicModel(
        model_id="claude-3-5-sonnet-20241022",
        api_key="sk-ant-...",  # Or use ANTHROPIC_API_KEY env var
    ),
    system_prompt="You are a helpful assistant.",
)
```

### Slack Channel Integration

```python
from agent_factory.channels import SlackChannel

# Create Slack channel
slack = SlackChannel(
    bot_token="xoxb-...",
    signing_secret="...",
)

# Handle incoming event
response = slack.handle_event(event_body)

# Send message
slack.send_message(
    channel="#general",
    text="Hello from the agent!",
)
```

### Teams Channel Integration

```python
from agent_factory.channels import TeamsChannel

# Create Teams channel
teams = TeamsChannel(
    app_id="your-app-id",        # Or use TEAMS_APP_ID env var
    app_password="your-secret",   # Or use TEAMS_APP_PASSWORD env var
)

# Handle incoming activity
message = teams.handle_event(activity)

# Send response
teams.send_message(
    conversation_id=message.channel_id,
    text="Hello from the bot!",
    service_url=message.metadata["service_url"],
)

# Send Adaptive Card
teams.send_adaptive_card(
    conversation_id=message.channel_id,
    card={"type": "AdaptiveCard", "body": [...]},
    service_url=message.metadata["service_url"],
)
```

### Lambda Handler

```python
from agent_factory import AgentOrchestrator
from agent_factory.models import BedrockModel
from agent_factory.handlers import LambdaHandler

orchestrator = AgentOrchestrator(
    model=BedrockModel(),
    system_prompt="You are a helpful assistant.",
)
handler = LambdaHandler(orchestrator)

def lambda_handler(event, context):
    return handler.handle(event)
```

## Architecture

### Models

The library provides a pluggable model interface:

- `BedrockModel` - AWS Bedrock (Claude, Llama, etc.)
- `AnthropicModel` - Direct Anthropic API

Create custom models by extending `BaseModel`:

```python
from agent_factory.models import BaseModel, ModelResponse

class CustomModel(BaseModel):
    def converse(self, messages, system_prompt, tools=None, **kwargs):
        # Your implementation
        return ModelResponse(content="...", stop_reason=StopReason.END_TURN)
```

### Channels

Supported channels:

- `SlackChannel` - Slack integration
- `TeamsChannel` - Microsoft Teams integration
- API - Use `LambdaHandler` with API Gateway

#### Channel Allowlist

Restrict which Slack channels can interact with your agent:

```python
from agent_factory.channels import SlackChannel

# Only allow specific channels
slack = SlackChannel(
    allowed_channels=["C0123456789", "C9876543210"],
)

# Or use environment variable (comma-separated)
# SLACK_ALLOWED_CHANNELS=C0123456789,C9876543210
slack = SlackChannel()  # Will read from env var
```

Messages from unauthorized channels will raise `ChannelAccessDeniedError`.

### Tools

Define tools with the `@tool` decorator:

```python
from agent_factory.tools import tool

@tool
def search_database(query: str, limit: int = 10) -> list:
    """Search the database for records.

    Args:
        query: Search query string
        limit: Maximum results to return
    """
    return [{"id": 1, "name": "Result"}]
```

## Configuration

| Environment Variable | Description |
|---------------------|-------------|
| `ANTHROPIC_API_KEY` | Anthropic API key |
| `AWS_REGION` | AWS region for Bedrock |
| `SLACK_BOT_TOKEN` | Slack bot token |
| `SLACK_SIGNING_SECRET` | Slack signing secret |
| `TEAMS_APP_ID` | Microsoft Teams App ID |
| `TEAMS_APP_PASSWORD` | Microsoft Teams App Password |
| `TEAMS_TENANT_ID` | Azure AD Tenant ID (optional) |

## License

MIT
