Metadata-Version: 2.4
Name: raindrop-strands
Version: 0.0.3
Summary: Raindrop integration for Strands Agents
Project-URL: Homepage, https://raindrop.ai
Project-URL: Repository, https://github.com/invisible-tools/dawn/tree/main/packages/strands-python
Author-email: Raindrop AI <sdk@raindrop.ai>
License-Expression: MIT
License-File: LICENSE
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: raindrop-ai>=0.0.42
Requires-Dist: strands-agents>=1.0.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: requests>=2.20; extra == 'dev'
Description-Content-Type: text/markdown

# raindrop-strands

Raindrop integration for [Strands Agents](https://strandsagents.com) (Python). Automatically captures agent invocations, model calls, tool usage, and token metrics via the Strands hook system.

## Installation

```bash
pip install raindrop-strands strands-agents
```

`strands-agents` is a required dependency.

## Quick Start

```python
import os
from strands import Agent
from raindrop_strands import RaindropStrands

raindrop = RaindropStrands(
    api_key=os.environ.get("RAINDROP_API_KEY"),
    user_id="user_123",
    convo_id="session_456",
)

agent = Agent(
    model="us.amazon.nova-lite-v1:0",
    system_prompt="You are a helpful assistant.",
)

raindrop.handler.register_hooks(agent)

result = agent("What is the capital of France?")
print(result)

raindrop.flush()
```

Omitting `api_key` disables telemetry shipping (a warning is emitted) but does not crash your application.

## Debug Mode

Enable verbose logging to troubleshoot telemetry issues:

```python
raindrop = RaindropStrands(
    api_key=os.environ.get("RAINDROP_API_KEY"),
    debug=True,
)
```

## Configuration

```python
raindrop = RaindropStrands(
    api_key="rk_...",              # Optional: Raindrop API key
    user_id="user_123",            # Optional: associate events with a user
    convo_id="session_456",        # Optional: conversation/session ID
    tracing_enabled=True,          # Optional: enable OTEL-based tracing (default: True)
    bypass_otel_for_tools=True,    # Optional: bypass OTEL for tool spans (default: True)
    debug=False,                   # Optional: enable debug logging (default: False)
)
```

## Factory Function

A `create_raindrop_strands()` factory function is also available for convenience:

```python
from raindrop_strands import create_raindrop_strands

raindrop = create_raindrop_strands(api_key="rk_...")
agent = Agent(model="us.amazon.nova-lite-v1:0")
raindrop.handler.register_hooks(agent)
result = agent("Hello!")
raindrop.flush()
```

## Identifying Users

```python
raindrop.identify(
    user_id="user_123",
    traits={"plan": "pro", "email": "user@example.com"},
)
```

## Tracking Signals

Track user feedback or other signals on AI responses:

```python
raindrop.track_signal(
    event_id="evt_...",
    name="thumbs_up",
    signal_type="feedback",
    sentiment="POSITIVE",
)
```

## Flush & Shutdown

Always flush before your process exits to ensure all data is sent:

```python
raindrop.flush()       # flush pending data
raindrop.shutdown()    # flush + release resources
```

## What Gets Captured

- **Agent invocations**: input prompt, output text, model name
- **Token usage**: prompt tokens, completion tokens, and cached tokens (from Bedrock/Anthropic `cacheReadInputTokens` / `cacheCreationInputTokens`)
- **Tool call spans**: individual tool spans tracked via `interaction.track_tool()` with name, input, output, duration, and error
- **Finish reason**: `stop_reason` or `finish_reason` from model responses (e.g., `end_turn`, `tool_use`)
- **Errors**: error type and message captured in event properties
- **Async support**: preserved via Strands' hook system

## API

### `RaindropStrands(api_key, user_id, convo_id, tracing_enabled, bypass_otel_for_tools, disable_auto_instrument, debug)`

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `api_key` | `str \| None` | `None` | Raindrop API key (`rk_...`). Omit to disable telemetry |
| `user_id` | `str \| None` | `None` | Associate all events with a user |
| `convo_id` | `str \| None` | `None` | Group events into a conversation |
| `tracing_enabled` | `bool` | `True` | Enable OTEL-based tracing |
| `bypass_otel_for_tools` | `bool` | `True` | Bypass OTEL for tool spans |
| `disable_auto_instrument` | `bool` | `True` | Library auto-instrumentation is opt-in (see below) |
| `debug` | `bool` | `False` | Enable debug logging |

### Library auto-instrumentation is opt-in

As of `0.0.3`, `disable_auto_instrument` defaults to `True`: the
integration no longer lets Traceloop monkey-patch every LLM client library
it recognizes in your process (including the botocore machinery Strands' default Bedrock provider drives). The
hook handler captures input/output, token usage, model name, and tool calls
directly from Strands hook events, so no library patching is needed for full
dashboards.

If you specifically want LLM-call-level spans from library instrumentation
and have verified compatibility in your environment, opt back in with
`disable_auto_instrument=False`.

**Properties:**

- `handler` — `RaindropEventHandler` instance to register on agents

**Methods:**

- `flush()` — flush pending telemetry
- `shutdown()` — flush and release resources
- `identify(user_id, traits)` — identify a user with optional traits
- `track_signal(event_id, name, ...)` — track a signal event

## Testing

```bash
cd packages/strands-python
pip install -e '.[dev]'
python -m pytest tests/ -v
```

## Full Documentation

See the [Raindrop Strands integration docs](https://docs.raindrop.ai/integrations/strands) for full details.

## License

MIT
