agnost 0.1.13
Python SDK for tracking AI conversations and events
License: MIT
Requires Python: >=3.7

# Agnost Conversation SDK

[![PyPI version](https://badge.fury.io/py/agnost-conversation.svg)](https://badge.fury.io/py/agnost-conversation)
[![Python](https://img.shields.io/pypi/pyversions/agnost-conversation.svg)](https://pypi.org/project/agnost-conversation/)

Python SDK for tracking AI conversations and events. Monitor your AI agent interactions, track user conversations, and gain insights into how your AI applications are performing.

## Installation

```bash
pip install agnost
```

## Basic Usage

```python
import agnost

# Initialize with your organization ID
agnost.init("your-org-id")

# Track an AI interaction
agnost.track(
    user_id="user_123",
    input="What is the weather?",
    output="The weather is sunny.",
    agent_name="weather-agent"
)
```

## API Reference

### `init(write_key, **config)`

Initialize the SDK with your organization ID.

```python
agnost.init("your-org-id")

# With custom configuration
agnost.init(
    "your-org-id",
    endpoint="https://api.agnost.ai",
    debug=True
)
```

### `track(user_id, ...)`

Record an AI interaction event.

```python
event_id = agnost.track(
    user_id="user_123",         # Optional: User identifier
    input="What is the weather?",
    output="The weather is sunny.",
    agent_name="weather-agent",  # Defaults to "default" if not provided
    conversation_id="conv_abc",  # Group related events
    properties={"temperature": "0.7"},
    latency=1500                 # Execution time in ms
)
```

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `user_id` | `str` | No | User identifier (default: "") |
| `input` | `str` | No | Input text/prompt |
| `output` | `str` | No | Output/response text. **When `success=False`, this is the error message** |
| `agent_name` | `str` | No | Agent name (default: "default") |
| `conversation_id` | `str` | No | Conversation ID for grouping |
| `properties` | `dict` | No | Additional event properties |
| `timestamp` | `datetime` | No | Event timestamp (defaults to now) |
| `success` | `bool` | No | Whether successful (default: `True`). Set to `False` for errors |
| `latency` | `int` | No | Execution time in milliseconds |

**Important**: When tracking errors (`success=False`), put the error message in the `output` parameter.

### `identify(user_id, traits)`

Associate user characteristics with a user ID.

```python
agnost.identify("user_123", {
    "name": "John Doe",
    "email": "john@example.com",
    "age": 30,
    "plan": "paid"
})
```

### `begin(user_id, ...)`

Begin a partial interaction for deferred completion. Use this when the output is not immediately available.

**✨ NEW: Automatic latency tracking** - Latency is now automatically calculated from `begin()` to `end()`!

```python
# Pass input directly (recommended)
interaction = agnost.begin(
    user_id="user_123",
    agent_name="weather-agent",
    input="What is the weather?"
)

interaction.set_property("temperature", "0.7")

# ... do async work ...

interaction.end(output="The weather is sunny.")
# ✅ Latency automatically calculated! (~duration from begin to end)
```

**Alternative: Set input later:**
```python
interaction = agnost.begin(
    user_id="user_123",
    agent_name="weather-agent"
)
interaction.set_input("What is the weather?")
interaction.end(output="The weather is sunny.")
```

**Manual latency override (optional):**
```python
interaction.end(
    output="The weather is sunny.",
    latency=1500  # Override auto-calculation if needed
)
```

**Interaction Methods:**

| Method | Description |
|--------|-------------|
| `set_input(text)` | Set the input text (optional if passed to `begin()`) |
| `set_properties(dict)` | Set multiple properties |
| `set_property(key, value)` | Set a single property |
| `end(output, success, latency)` | Complete the interaction. **When `success=False`, `output` is the error message.** Latency is auto-calculated if not provided |

### `flush()`

Manually flush all queued events.

```python
agnost.flush()
```

### `shutdown()`

Shutdown the SDK and flush remaining events.

```python
agnost.shutdown()
```

### `set_debug_logs(enabled)`

Enable or disable debug logging.

```python
agnost.set_debug_logs(True)  # See queued events
```

## Configuration

You can customize the SDK behavior using the configuration object:

```python
import agnost_conversation as agnost
from agnost_conversation import ConversationConfig

# Create a custom configuration
config = ConversationConfig(
    endpoint="https://api.agnost.ai",
    debug=False
)

# Apply the configuration
agnost.init("your-org-id", config=config)
```

### Configuration Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `endpoint` | `str` | `"https://api.agnost.ai"` | API endpoint URL |
| `debug` | `bool` | `False` | Enable debug logging |

## Advanced Usage

### Conversation Tracking

Group related events using `conversation_id`:

```python
conversation_id = "conv_" + str(uuid.uuid4())

# First message
agnost.track(
    user_id="user_123",
    input="Hello!",
    output="Hi there! How can I help?",
    agent_name="support-bot",
    conversation_id=conversation_id
)

# Follow-up message
agnost.track(
    user_id="user_123",
    input="What's the weather?",
    output="The weather is sunny.",
    agent_name="support-bot",
    conversation_id=conversation_id
)
```

### Direct Client Instantiation

For multiple clients or advanced use cases:

```python
from agnost_conversation import ConversationClient

client = ConversationClient()
client.init("your-org-id")

client.track(
    user_id="user_123",
    output="Hello!",
    agent_name="greeting-bot"
)

client.shutdown()
```

### Error Handling

When tracking errors, set `success=False` and pass the error message as the `output`:

```python
# Track failed interactions
agnost.track(
    user_id="user_123",
    input="Generate an image",
    output="Rate limit exceeded",  # Error message as output
    success=False,
    agent_name="image-agent"
)

# With begin() and end()
interaction = agnost.begin(
    user_id="user_123",
    agent_name="image-agent",
    input="Generate an image"
)

try:
    result = generate_image()
    interaction.end(output=result)
except Exception as e:
    # Error message goes in output when success=False
    interaction.end(output=str(e), success=False)
```

## Contact

For support or questions, contact the founders: [founders@agnost.ai](mailto:founders@agnost.ai)