notionalpha-clarity 0.3.1
Python SDK for NotionAlpha Clarity - AI Value Realization Platform
License: MIT
Requires Python: >=3.8
Keywords: notionalpha, clarity, ai, llm, finops, value-realization, roi, openai, anthropic, azure

# notionalpha-clarity

**Python SDK for NotionAlpha Clarity - AI Value Realization Platform**

## Features

- **Cost Tracking** - Track LLM costs across providers (OpenAI, Anthropic, Azure OpenAI)
- **Outcome Tracking** - Link business outcomes to LLM calls
- **ROI Calculation** - Calculate return on investment for AI features
- **Forecasting** - Predict future costs, value, and ROI with ML-powered insights
- **Recommendations** - Get AI-generated optimization suggestions
- **Signal Enrichment** - Automatic agent-aware signal capture and analysis

## Installation

```bash
pip install notionalpha-clarity openai anthropic
```

## Quick Start

### 1. Get Your Configuration

1. Sign up at [notionalpha.com](https://notionalpha.com)
2. Create a provider (OpenAI, Anthropic, or Azure OpenAI)
3. Create a team for cost attribution
4. Copy your `org_id`, `team_id`, and `provider_id`

### 2. Initialize the Client

```python
from notionalpha import NotionAlphaClient
import os

clarity = NotionAlphaClient(
    org_id=os.getenv('NOTIONALPHA_ORG_ID'),
    team_id=os.getenv('NOTIONALPHA_TEAM_ID'),
    environment='production',
    provider={
        'type': 'openai',
        'provider_id': os.getenv('NOTIONALPHA_PROVIDER_ID')
    }
)
```

### 3. Make LLM Calls

```python
# OpenAI
response, transaction_id = clarity.chat.completions.create(
    model='gpt-4o-mini',
    messages=[{'role': 'user', 'content': 'Help me resolve this ticket'}]
)

print(response.choices[0].message.content)
# Cost and security are tracked automatically
```

### 4. Track Outcomes

```python
# Link business outcome to LLM call
clarity.track_outcome(
    transaction_id=transaction_id,
    type='customer_support',
    metadata={
        'ticket_id': 'TICKET-456',
        'resolution_time_seconds': 120,
        'customer_satisfaction': 5,
        'time_saved_minutes': 15
    }
)
```

### Optional: Enable Automatic Signal Enrichment

Configure the SDK to analyze every LLM call and send structured signals to the NotionAlpha agent pipeline (context classification, intent, complexity, value estimates). This is the first step toward the signals-first refactor described in `/specs/002-agent-architecture-implementation`.

```python
from notionalpha import NotionAlphaClient

clarity = NotionAlphaClient(
    org_id=os.getenv('NOTIONALPHA_ORG_ID'),
    team_id=os.getenv('NOTIONALPHA_TEAM_ID'),
    provider={
        'type': 'openai',
        'provider_id': os.getenv('NOTIONALPHA_PROVIDER_ID')
    },
    signal_enrichment={
        'enabled': True,
        'openai_api_key': os.getenv('OPENAI_API_KEY'),
    },
    # Optional: override where enriched signals are delivered
    signal_capture_url='https://api.notionalpha.com/api/v1/signals'
)
```

With enrichment enabled, each provider wrapper schedules best-effort signal capture in the background, so synchronous code keeps working even when no event loop is available.

### 5. View Value Realization

```python
# Get ROI summary
value = clarity.get_value_realization()

print(f"""
  Total Cost: ${value['total_cost']}
  Total Value: ${value['total_value']}
  ROI: {value['roi']}x
""")
```

## Complete Example: Customer Support Bot

```python
from notionalpha import NotionAlphaClient
import os

clarity = NotionAlphaClient(
    org_id=os.getenv('NOTIONALPHA_ORG_ID'),
    team_id=os.getenv('NOTIONALPHA_TEAM_ID'),
    environment='production',
    feature_id='customer-support-bot',
    provider={
        'type': 'openai',
        'provider_id': os.getenv('NOTIONALPHA_PROVIDER_ID')
    }
)

async def resolve_ticket(ticket_id: str, question: str):
    # Step 1: Make LLM call
    response, transaction_id = clarity.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': question}]
    )

    # Step 2: Track outcome
    clarity.track_outcome(
        transaction_id=transaction_id,
        type='customer_support',
        metadata={
            'ticket_id': ticket_id,
            'time_saved_minutes': 15,
            'customer_satisfaction': 5
        }
    )

    return response.choices[0].message.content

# Use it
await resolve_ticket('TICKET-123', 'How do I reset my password?')

# Later: View ROI
value = clarity.get_value_realization()
print(f"ROI: {value['roi']}x")  # e.g., "ROI: 25x"
```

## Supported Providers

### OpenAI

```python
clarity = NotionAlphaClient(
    org_id='org_xxx',
    team_id='team-uuid',
    provider={'type': 'openai', 'provider_id': 'provider-uuid'}
)

response, transaction_id = clarity.chat.completions.create(
    model='gpt-4o-mini',
    messages=[{'role': 'user', 'content': 'Hello!'}]
)
```

### Anthropic

```python
clarity = NotionAlphaClient(
    org_id='org_xxx',
    team_id='team-uuid',
    provider={'type': 'anthropic', 'provider_id': 'provider-uuid'}
)

response, transaction_id = clarity.messages.create(
    model='claude-3-5-sonnet-20241022',
    max_tokens=1024,
    messages=[{'role': 'user', 'content': 'Hello!'}]
)
```

### Azure OpenAI

```python
clarity = NotionAlphaClient(
    org_id='org_xxx',
    team_id='team-uuid',
    provider={
        'type': 'azure-openai',
        'provider_id': 'provider-uuid',
        'deployment_name': 'gpt-4o-mini'
    }
)

response, transaction_id = clarity.chat.completions.create(
    model='gpt-4o-mini',
    messages=[{'role': 'user', 'content': 'Hello!'}]
)
```

## API Reference

### NotionAlphaClient

Main client for interacting with NotionAlpha Clarity.

**Parameters:**
- `org_id` (str): Organization ID from NotionAlpha dashboard
- `team_id` (str): Team ID for cost attribution
- `environment` (str, optional): Environment name (default: 'production')
- `feature_id` (str, optional): Feature ID for granular tracking
- `provider` (dict): Provider configuration
- `api_base_url` (str, optional): Base URL for NotionAlpha API
- `proxy_base_url` (str, optional): Base URL for NotionAlpha proxy

### Methods

#### `chat.completions.create(**kwargs)`

Create a chat completion (OpenAI/Azure OpenAI).

**Returns:** `(response, transaction_id)`

#### `messages.create(**kwargs)`

Create a message (Anthropic).

**Returns:** `(response, transaction_id)`

#### `track_outcome(transaction_id, type, metadata, timestamp=None)`

> ⚠️ **Deprecated**: This method is deprecated and will be removed in v1.0.0. The Clarity SDK now captures signals automatically when you make LLM calls. See [migration guide](https://docs.notionalpha.com/signals-migration).

Track a business outcome.

**Parameters:**
- `transaction_id` (str): Transaction ID from LLM response
- `type` (str): Outcome type (e.g., 'customer_support_ticket_resolved', 'code_generated')
- `metadata` (dict): Outcome-specific metadata
- `timestamp` (datetime, optional): Outcome timestamp (default: now)

#### `get_value_realization()`

Get value realization summary.

**Returns:** `dict` with `total_cost`, `total_value`, `roi`, etc.

#### `get_forecast(horizon=30, method='hybrid')`

Get value forecast with predictions and insights.

**Parameters:**
- `horizon` (int): Forecast horizon in days (7, 14, or 30)
- `method` (str): Forecasting method ('statistical', 'hybrid', or 'llm')

**Returns:** `ForecastData` with predictions for cost, value, and ROI

```python
forecast = clarity.get_forecast(horizon=30, method='hybrid')
print(f"Predictions: {forecast['predictions']}")
print(f"Insights: {forecast['insights']}")
```

#### `get_recommendations()`

Get AI-generated optimization recommendations.

**Returns:** `List[Recommendation]` with actionable insights

```python
recommendations = clarity.get_recommendations()
for rec in recommendations:
    print(f"{rec['title']}: {rec['description']}")
    print(f"  Estimated savings: ${rec['estimated_savings']}")
```

#### `update_recommendation(recommendation_id, status)`

Update recommendation status.

**Parameters:**
- `recommendation_id` (str): The ID of the recommendation
- `status` (str): New status ('in_progress', 'completed', or 'rejected')

```python
clarity.update_recommendation('rec-123', 'completed')
```

## License

MIT