Metadata-Version: 2.4
Name: logicgaze
Version: 1.1.0
Summary: AI-native observability SDK for tracing, evaluating, and optimizing production LLM applications
Project-URL: Homepage, https://github.com/VikneeshVG/logicgaze
Project-URL: Repository, https://github.com/VikneeshVG/logicgaze
Project-URL: Issues, https://github.com/VikneeshVG/logicgaze/issues
Author-email: Vikneesh VG <vikneeshwaran.k@ventragate.com>
License: MIT
License-File: LICENSE
Keywords: ai,anthropic,evaluation,langchain,llm,logicgaze,observability,openai,tracing
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.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Requires-Dist: httpx>=0.26.0
Provides-Extra: dev
Requires-Dist: build>=1.0.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: twine>=4.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# llm-tracking

Python SDK for [LogicGaze](https://github.com/yourusername/tracker) — an AI-native observability platform.
All LLM calls are routed through the LogicGaze gateway, which records traces, spans, token usage, and cost automatically.

## Installation

```bash
pip install llm-tracking
```

## Quick Start

### 1. Initialize once at startup

```python
import llm_tracking

llm_tracking.init(
    api_key="lgz_...",          # LogicGaze API key (or set LLM_TRACKING_API_KEY)
    base_url="http://localhost:8000",   # your LogicGaze backend URL
)
```

### 2. Wrap your AI client

**OpenAI**
```python
from openai import OpenAI
import llm_tracking

llm_tracking.init(api_key="lgz_...")
client = llm_tracking.wrap_openai(OpenAI())

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)
```

**Anthropic**
```python
from anthropic import Anthropic
import llm_tracking

llm_tracking.init(api_key="lgz_...")
client = llm_tracking.wrap_anthropic(Anthropic())

response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello!"}],
)
print(response.content[0].text)
```

> **Note:** The wrapped client routes calls through the LogicGaze gateway.
> The AI provider credentials must be configured in your LogicGaze backend, not in the client app.

### 3. Group calls with `TraceContext`

```python
from llm_tracking import TraceContext, wrap_openai
from openai import OpenAI

client = wrap_openai(OpenAI())

with TraceContext(session_id="sess-abc", user_id="user-42", service_name="chat-api"):
    # Both calls share the same session in the trace viewer
    client.chat.completions.create(model="gpt-4o", messages=[...])
    client.chat.completions.create(model="gpt-4o", messages=[...])
```

### 4. Use `@traceable` on functions

```python
from llm_tracking import traceable, wrap_openai
from openai import OpenAI

client = wrap_openai(OpenAI())

@traceable(session_id="sess-1", service_name="recommendation-engine")
def recommend(user_query: str):
    return client.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": user_query}],
    )

# Async functions are supported too
@traceable(service_name="summarizer")
async def summarize(text: str):
    return await client.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": f"Summarize: {text}"}],
    )
```

### 5. Query traces programmatically

```python
from llm_tracking import get_client

lg = get_client()

# List recent traces
traces = lg.list_traces(service_name="chat-api", page_size=20)

# Get a specific trace with all spans
trace = lg.get_trace("trace-uuid-here", include_spans=True)

# Dashboard overview (last 24 h)
overview = lg.get_dashboard(window_hours=24)
print(overview["total_requests"], overview["total_cost_usd"])

# Estimate cost before a call
estimate = lg.estimate_cost("openai", "gpt-4o", prompt_tokens=500, completion_tokens=200)
```

## Configuration

| Parameter | Environment variable | Default |
|-----------|---------------------|---------|
| `api_key` | `LLM_TRACKING_API_KEY` | — |
| `base_url` | — | `http://localhost:8000` |
| `timeout` | — | `30.0` s |

## API Reference

### `llm_tracking.init(api_key, base_url, timeout)`
Initialize the global client. Call once at startup.

### `wrap_openai(client, *, service_name=None)`
Patches `client.chat.completions.create` (sync & async). Returns the same client object.

### `wrap_anthropic(client, *, service_name=None)`
Patches `client.messages.create` (sync & async). Returns the same client object.

### `TraceContext(*, project, trace_id, session_id, user_id, service_name, tags)`
Context manager (sync & async). Sets metadata injected into every gateway call made within the block.

### `@traceable(*, name, project, session_id, user_id, service_name, tags, run_type)`
Decorator. Wraps the function body in a `TraceContext`. Works with both sync and async functions. Can be used with or without arguments.

### `LogicGazeClient` methods

| Method | Backend endpoint |
|--------|-----------------|
| `chat_completion(provider, model, messages, **kwargs)` | `POST /gateway/chat/completions` |
| `achat_completion(...)` | async version of above |
| `list_traces(**filters)` | `GET /traces` |
| `get_trace(trace_id, include_spans)` | `GET /traces/{id}` |
| `get_spans(trace_id)` | `GET /traces/{id}/spans` |
| `get_agent_graph(trace_id)` | `GET /traces/{id}/agent-graph` |
| `get_dashboard(window_hours)` | `GET /dashboard/overview` |
| `get_model_distribution(window_hours)` | `GET /dashboard/model-distribution` |
| `get_provider_breakdown(window_hours)` | `GET /dashboard/provider-breakdown` |
| `estimate_cost(provider, model, prompt_tokens, completion_tokens)` | `POST /costs/estimate` |
| `list_model_costs(provider)` | `GET /costs/models` |
| `get_guardrails_summary(window_hours)` | `GET /guardrails/summary` |

## Requirements

- Python 3.9+
- `httpx >= 0.26.0`

## License

MIT
