Metadata-Version: 2.4
Name: ioa-observe-sdk
Version: 1.0.0
Summary: IOA Observability SDK
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE.md
Requires-Dist: aiohappyeyeballs==2.4.8
Requires-Dist: aiohttp==3.11.18
Requires-Dist: aiosignal==1.3.2
Requires-Dist: annotated-types==0.7.0
Requires-Dist: anyio==4.8.0
Requires-Dist: async-timeout==4.0.3
Requires-Dist: attrs==25.1.0
Requires-Dist: backoff==2.2.1
Requires-Dist: certifi==2025.1.31
Requires-Dist: charset-normalizer==3.4.1
Requires-Dist: colorama==0.4.6
Requires-Dist: Deprecated==1.2.18
Requires-Dist: distro==1.9.0
Requires-Dist: exceptiongroup==1.2.2
Requires-Dist: frozenlist==1.5.0
Requires-Dist: googleapis-common-protos==1.69.0
Requires-Dist: grpcio==1.70.0
Requires-Dist: h11==0.16.0
Requires-Dist: httpcore==1.0.9
Requires-Dist: httpx==0.28.1
Requires-Dist: idna==3.10
Requires-Dist: importlib_metadata==8.5.0
Requires-Dist: Jinja2==3.1.6
Requires-Dist: jiter==0.8.2
Requires-Dist: MarkupSafe==3.0.2
Requires-Dist: monotonic==1.6
Requires-Dist: multidict==6.1.0
Requires-Dist: openai==1.75.0
Requires-Dist: opentelemetry-api==1.33.1
Requires-Dist: opentelemetry-distro
Requires-Dist: opentelemetry-exporter-otlp==1.33.1
Requires-Dist: opentelemetry-exporter-otlp-proto-common==1.33.1
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc==1.33.1
Requires-Dist: opentelemetry-exporter-otlp-proto-http==1.33.1
Requires-Dist: opentelemetry-instrumentation
Requires-Dist: opentelemetry-instrumentation-logging==0.54b1
Requires-Dist: opentelemetry-instrumentation-openai==0.40.2
Requires-Dist: opentelemetry-instrumentation-llamaindex==0.40.2
Requires-Dist: opentelemetry-instrumentation-ollama==0.40.2
Requires-Dist: opentelemetry-instrumentation-langchain==0.40.2
Requires-Dist: opentelemetry-instrumentation-threading==00.54b1
Requires-Dist: opentelemetry-instrumentation-urllib3==0.54b1
Requires-Dist: opentelemetry-proto==1.33.1
Requires-Dist: opentelemetry-sdk==1.33.1
Requires-Dist: opentelemetry-semantic-conventions==0.54b1
Requires-Dist: opentelemetry-semantic-conventions-ai==0.4.5
Requires-Dist: opentelemetry-util-http==0.54b1
Requires-Dist: packaging==24.2
Requires-Dist: propcache==0.3.0
Requires-Dist: protobuf==5.29.3
Requires-Dist: pydantic==2.10.6
Requires-Dist: pydantic_core==2.27.2
Requires-Dist: python-dateutil==2.9.0.post0
Requires-Dist: regex==2024.11.6
Requires-Dist: requests==2.32.3
Requires-Dist: six==1.17.0
Requires-Dist: sniffio==1.3.1
Requires-Dist: tenacity==9.0.0
Requires-Dist: tiktoken==0.9.0
Requires-Dist: tqdm==4.67.1
Requires-Dist: typing_extensions==4.12.2
Requires-Dist: urllib3==2.3.0
Requires-Dist: wrapt==1.17.2
Requires-Dist: yarl==1.18.3
Requires-Dist: zipp==3.21.0
Requires-Dist: langgraph==0.4.1
Requires-Dist: langchain==0.3.25
Requires-Dist: langchain-openai==0.3.21
Requires-Dist: opentelemetry-instrumentation-requests
Requires-Dist: opentelemetry-instrumentation-transformers>=0.40.2
Requires-Dist: opentelemetry-instrumentation-crewai>=0.40.2
Requires-Dist: llama-index-utils-workflow>=0.3.1
Requires-Dist: pytest
Requires-Dist: pytest-vcr
Dynamic: license-file

# Observe-SDK

IOA observability SDK for your multi-agentic application.

## Table of Contents

- [Installation](#installation)
- [Usage](#usage)
- [Features](#features)
- [Contributing](#contributing)
- [License](#license)

## Installation

To install the package via PyPI, simply run:

```bash
pip install ioa_observe_sdk
```

Alternatively, to download the SDK from git, you could also use the following command. Ensure you have `uv` installed in your environment.

```bash
uv add "git+https://github.com/agntcy/observe"
```

## Dev

To get started with development, start a Clickhouse DB and an OTel collector container locally using docker-compose like so:

```
cd deploy/
docker compose up -d
```

Ensure the contents of `otel-collector.yaml` is correct.

Check the logs of the collector to ensure it is running correctly:

```
docker logs -f otel-collector
```

Create a `.env` file with the following content:

```bash
OTLP_HTTP_ENDPOINT=http://localhost:4318
```

Install the dependencies and activate the virtual environment:

```bash
set -a
source .env
set +a

python3 -m venv .venv
source .venv/bin/activate
uv sync
```

## Testing

To run the unit tests, ensure you have the `OPENAI_API_KEY` set in your environment. You can run the tests using the following command:

```bash
OPENAI_API_KEY=<KEY> make test
```

## Getting Started

For getting started with the SDK, please refer to the [GETTING-STARTED.md](GETTING-STARTED.md) file. It contains detailed instructions on how to set up and use the SDK effectively.

## SLIM-Based Multi-Agentic Systems

For distributed agent systems using SLIM protocol, additional instrumentation is available:


### Initializing the SLIM Connector with your agent

```python
from ioa_observe.sdk.connectors.slim import SLIMConnector, process_slim_msg
from ioa_observe.sdk.instrumentations.slim import SLIMInstrumentor

# Initialize SLIM connector
slim_connector = SLIMConnector(
    remote_org="cisco",
    remote_namespace="default",
    shared_space="chat",
)

# Register agents with the connector
slim_connector.register("remote_client_agent")

# Instrument SLIM communications
SLIMInstrumentor().instrument()
```

### Receiving Messages with a Callback

Add the decorator `process_slim_msg` to the callback function to process incoming messages. This function will be called whenever a message is received in the shared space.

```python

# Define a callback to process incoming messages
from ioa_observe.sdk.connectors.slim import SLIMConnector, process_slim_msg
import json
from typing import Dict, Any

@process_slim_msg("remote_client_agent")
async def send_and_recv(msg) -> Dict[str, Any]:
    """Send message to remote endpoint and wait for reply."""
    gateway = GatewayHolder.gateway
    session_info = GatewayHolder.session_info

    if gateway is not None:
        await gateway.publish(session_info, msg.encode(), "cisco", "default", "server")
        async with gateway:
            _, recv = await gateway.receive(session=session_info.id)
    else:
        raise RuntimeError("Gateway is not initialized yet!")

    response_data = json.loads(recv.decode("utf8"))
    return {"messages": response_data.get("messages", [])}
```

### Starting the Message Receiver

```python
# Start receiving messages from the SLIM shared space
await slim.receive(callback=on_message_received)
```

### Publishing Messages

```python
# Publish a message to the SLIM shared space
message = {"type": "ChatMessage", "author": "moderator", "message": "Hello, world!"}
await slim.publish(msg=json.dumps(message).encode("utf-8"))
```

We will observe various events and metrics being sent to the Otel collector as we interact with other agents in the shared space via SLIM.

## Contributing

Contributions are welcome! Please follow these steps to contribute:

1. Fork the repository.
2. Create a new branch (`git checkout -b feature-branch`).
3. Commit your changes (`git commit -am 'Add new feature'`).
4. Push to the branch (`git push origin feature-branch`).
5. Create a new Pull Request.
