# Introduction
Source: https://docs.trynexus.io/api-reference/introduction
Python API surface for Nexus instrumentation
Nexus exposes a Python-first API for trace logging.
## Core modules
* `NexusClient` and `Span` for manual instrumentation.
* `LangHandler` for LangChain callback instrumentation.
* `config` helpers for DB and trigger URLs.
## Data model written to storage
Both manual spans and LangChain callbacks map to rows with these key fields:
* `run_id`
* `user_id`
* `trace_id`
* `parent_run_id`
* `event_type`
* `name`
* `input`
* `output`
* `error`
## Reference pages
Constructor behavior, span lifecycle, flush, and tree helpers.
Callback hooks, event mapping, and root-chain trigger behavior.
# LangHandler
Source: https://docs.trynexus.io/api-reference/langchain-handler
Nexus reference for LangChain callback tracing
## `LangHandler(nexus_client, dev_mode=False, session_id=None, db_url=None)`
Callback handler for LangChain event instrumentation.
* `nexus_client`: required `NexusClient` source for `user_id`
* `dev_mode`: disables root-chain trigger calls when true
* `session_id`: optional metadata value
* `db_url`: optional DB override
## Callback hooks implemented
### LLM and chat model
* `on_llm_start`, `on_llm_end`, `on_llm_error`
* `on_chat_model_start`
* `on_llm_new_token` (present but not persisted by default)
### Chains
* `on_chain_start`, `on_chain_end`, `on_chain_error`
* root `on_chain_end` and root `on_chain_error` may trigger `/catch_route_manual`
### Tools
* `on_tool_start`, `on_tool_end`, `on_tool_error`
### Agents
* `on_agent_action`, `on_agent_finish`
### Retrieval and misc
* `on_retriever_start`, `on_retriever_end`, `on_retriever_error`
* `on_text`
* `on_retry`
## Event normalization
Incoming callback names are normalized into category-style values before persistence:
* `llm_start` -> `llm`
* `tool_error` -> `tool`
* `retriever_end` -> `retriever`
## Persistence behavior
Each callback writes to `agent_logs` with:
* run identifiers and parent linkage
* normalized event category
* serialized JSON for `input` and `output`
* nullable `error` text
# NexusClient and Span
Source: https://docs.trynexus.io/api-reference/python-client
Nexus reference for manual tracing primitives
## `NexusClient(api_key: str, db_url: Optional[str] = None)`
Creates a client for manual instrumentation.
* `api_key`: parsed as UUID and stored as `user_id`
* `trace_id`: generated once during client creation
* `db_url`: optional override; otherwise uses config helper lookup
In your app code, `api_key` is your Nexus platform `nexus_api_key`.
## `client.span(name: str, event_type: str, input_data=None) -> Span`
Creates a nested span context manager.
* tracks parent/child relationships automatically
* buffers events in memory until `flush()`
## `Span.set_output(output)`
Stores output payload for the span before it closes.
## `Span.set_error(error)`
Sets explicit error metadata and marks span status as error.
## `client.flush()`
Persists buffered events to PostgreSQL `agent_logs`.
* writes one event row per span
* clears in-memory event buffer after successful loop
## `client.get_all_events(trace_id: Optional[str] = None) -> list[dict]`
Reads stored events for the current `user_id` and selected trace.
## `client.print_tree_structure(trace_id: Optional[str] = None)`
Prints an event tree in terminal.
## `client.build_tree_data_from_events(trace_id: Optional[str] = None) -> dict`
Builds tree-shaped data keyed by `run_id`.
## `client.get_trace_tree_string(trace_id: Optional[str] = None) -> str`
Returns an LLM-friendly string representation of trace structure.
# Configuration
Source: https://docs.trynexus.io/guides/configuration
Configure Nexus DB connections and trigger behavior
Nexus writes events to PostgreSQL and optionally triggers a follow-up endpoint after root-chain completion.
## Database URL
You can set the DB URL in two common ways:
* pass `db_url` directly to `NexusClient` / `LangHandler`
* rely on library config helpers (`get_db_url()` / `set_db_url()`)
```python theme={null}
from nexus_library.nexus_core import NexusClient
client = NexusClient(
api_key="00000000-0000-0000-0000-000000000000",
db_url="postgresql://user:pass@host/db",
)
```
## Trigger URL
LangChain tracing can call a trigger endpoint after root chain completion or failure:
* `POST {trigger_url}/catch_route_manual`
The URL is read through `get_trigger_url()`.
## Storage contract
The library expects an `agent_logs` table with at least:
* UUIDs for `run_id`, `user_id`, and optional `parent_run_id`
* text for `trace_id`, `event_type`, and `name`
* JSONB fields for `input` and `output`
* nullable text for `error`
## Security guidance
Do not rely on hardcoded credentials in source code for production usage. Prefer environment-driven secrets and managed secret stores.
* rotate credentials regularly
* use least-privilege DB roles
* separate dev and prod storage backends
# LangChain integration
Source: https://docs.trynexus.io/guides/langchain
Trace LangChain chains, tools, agents, and retrievers with Nexus
Use `LangHandler` to capture LangChain callback events without manually instrumenting every call site.
## Install
```bash theme={null}
pip install nexus-library[langchain]
```
## Set up the handler
```python theme={null}
from nexus_library.nexus_core import NexusClient
from nexus_library.langchain import LangHandler
nexus_key = "your_nexus_api_key"
nexus_client = NexusClient(api_key=nexus_key)
callback_handler = LangHandler(nexus_client)
```
Attach `callback_handler` to your runnable or agent callback configuration.
## What gets logged
The handler listens to standard callback hooks, including:
* LLM and chat model lifecycle (`start`, `end`, `error`)
* chain lifecycle (`start`, `end`, `error`)
* tool lifecycle (`start`, `end`, `error`)
* agent actions and finish events
* retriever lifecycle (`start`, `end`, `error`)
* text and retry events
Each event is persisted with parent linkage so you can reconstruct execution trees.
## Event category mapping
The handler normalizes callback names into category-style `event_type` values.\
Example: `llm_start` and `llm_end` are stored as `llm`.
## Root-chain trigger behavior
When a root chain ends (or errors), the handler can trigger:
* `POST {trigger_url}/catch_route_manual`
* query params: `user_id` and `trace_id`
Set `dev_mode=True` to disable this external trigger while testing locally.
Get your `nexus_api_key` from the Nexus platform: [Nexus platform](https://app.trynexus.io).
## Best practices
* Reuse one `NexusClient` for one logical run.
* Keep `dev_mode=True` in local and CI environments.
* Treat trigger endpoints as production infrastructure and monitor failures.
# Manual tracing
Source: https://docs.trynexus.io/guides/manual-tracing
Instrument custom Python code with Nexus NexusClient and spans
Use manual tracing when you need explicit control over what gets logged and when.
## How it works
* Create one `NexusClient` per request or workflow.
* Create nested spans with `client.span(...)`.
* Set outputs or errors on spans.
* Call `client.flush()` to persist buffered events.
## Minimal example
```python theme={null}
from uuid import uuid4
from nexus_library.nexus_core import NexusClient
client = NexusClient(api_key=str(uuid4()), db_url="postgresql://user:pass@host/db")
with client.span("orchestrator", event_type="chain", input_data={"task": "summarize"}) as root:
with client.span("retrieve-docs", event_type="retriever", input_data={"k": 5}) as retrieve_span:
retrieve_span.set_output({"hits": 5})
with client.span("generate-answer", event_type="llm", input_data={"model": "gpt-4.1"}) as llm_span:
llm_span.set_output({"text": "Final answer"})
root.set_output({"status": "ok"})
client.flush()
```
## Span behavior
* A span gets a generated `run_id`.
* The active parent span becomes `parent_run_id` for children.
* Exceptions inside `with client.span(...)` mark the span as errored.
* Exceptions are re-raised after logging because span context managers do not suppress them.
## Choosing `event_type`
Use categories that map to your architecture:
* `chain`
* `llm`
* `chat_model`
* `tool`
* `agent`
* `retriever`
* `text`
* `retry`
## Common pitfalls
`NexusClient(api_key=...)` converts strings into `uuid.UUID`. If your API key is not UUID-formatted, initialization fails.
* Forgetting to call `flush()` means events stay in memory.
* Passing non-JSON-serializable objects is allowed, but they are converted to strings.
# OpenAI Agents SDK integration
Source: https://docs.trynexus.io/guides/openai
Trace OpenAI agents with Nexus using NexusOpenAITracingProcessor
Use `NexusOpenAITracingProcessor` to capture every span emitted by the OpenAI Agents SDK and send it to Nexus automatically.
## Install
```bash theme={null}
pip install nexus-library[openai]
```
## Set up the processor
```python theme={null}
import asyncio
import os
from agents import Agent, Runner, set_trace_processors
from nexus_library.nexus_core import NexusClient
from nexus_library.openai import NexusOpenAITracingProcessor
nexus_client = NexusClient(api_key=os.environ["NEXUS_API_KEY"])
dev_mode = os.getenv("NEXUS_DEV_MODE", "false").lower() == "true"
tracing_processor = NexusOpenAITracingProcessor(nexus_client, dev_mode=dev_mode)
set_trace_processors([tracing_processor])
```
Register the processor once at startup before any agents run. All subsequent `Runner.run` calls in the process are captured automatically.
## Environment variables
| Variable | Values | Behavior |
| ---------------- | ----------------- | ------------------------------------------------------ |
| `NEXUS_API_KEY` | your API key | Authenticates the Nexus client |
| `NEXUS_DEV_MODE` | `true` | Disables external trigger POST — use locally and in CI |
| `NEXUS_DEV_MODE` | `false` (default) | Fires the trigger endpoint — use in production |
## Full example
```python theme={null}
import asyncio
import os
from agents import Agent, Runner, set_trace_processors, function_tool
from dotenv import load_dotenv
from nexus_library.nexus_core import NexusClient
from nexus_library.openai import NexusOpenAITracingProcessor
load_dotenv()
nexus_client = NexusClient(api_key=os.environ["NEXUS_API_KEY"])
dev_mode = os.getenv("NEXUS_DEV_MODE", "false").lower() == "true"
tracing_processor = NexusOpenAITracingProcessor(nexus_client, dev_mode=dev_mode)
set_trace_processors([tracing_processor])
@function_tool
def hello_world():
"""Prints 'Hello, world!' to the console."""
print("Hello, world!")
async def main():
agent = Agent(
name="my-agent",
tools=[hello_world],
instructions="You are a helpful assistant.",
)
result = await Runner.run(agent, "Say hello.")
print(result.final_output)
asyncio.run(main())
```
## Dev vs production
* **Development** — set `NEXUS_DEV_MODE=true` in your `.env` file. The processor records traces locally without firing the external trigger endpoint.
* **Production** — set `NEXUS_DEV_MODE=false` (or leave it unset). The processor fires `POST {trigger_url}/catch_route_manual` with `user_id` and `trace_id` after each root span completes.
## Best practices
* Store `NEXUS_API_KEY` in environment variables — never hardcode it.
* Reuse one `NexusClient` for the lifetime of the process.
* Call `set_trace_processors` once at startup, before any `Runner.run` calls.
Get your `nexus_api_key` from the Nexus platform: [Nexus platform](https://app.trynexus.io).
# Production checklist — Nexus
Source: https://docs.trynexus.io/guides/production-checklist
Harden Nexus tracing before shipping
Use this checklist before enabling tracing in production systems.
## Runtime safety
* ensure `api_key` values are valid UUID strings
* keep payload size bounded before logging `input` and `output`
* avoid logging raw secrets, tokens, or PII
* apply timeout and retry strategy to any external trigger endpoint
## Data layer
* provision `agent_logs` with indexes for `user_id`, `trace_id`, and `parent_run_id`
* configure DB connection limits for your request volume
* monitor write failures from psycopg connection attempts
* set retention policies for trace data
## LangChain behavior
* keep `dev_mode=True` outside production if trigger calls are not desired
* document callback attachment points in your app architecture
* verify root chain events are consistently produced in your chains
## Observability
* alert on sustained insert failures
* sample event volumes per trace
* track average and p95 trace depth
* define dashboards for error-heavy event categories
# Tree inspection
Source: https://docs.trynexus.io/guides/tree-inspection
Inspect Nexus stored traces as parent-child execution trees
Nexus includes helper methods to inspect stored events after they are persisted.
## Fetch events
```python theme={null}
events = client.get_all_events()
```
You can pass a specific `trace_id`:
```python theme={null}
events = client.get_all_events(trace_id="your-trace-id")
```
## Print a visual tree
```python theme={null}
client.print_tree_structure()
```
This prints a terminal tree grouped by `parent_run_id` relationships and colorized by event category.
## Build tree data programmatically
```python theme={null}
tree_data = client.build_tree_data_from_events()
```
Use this when you want custom rendering or downstream processing.
## Get an LLM-friendly tree string
```python theme={null}
tree_str = client.get_trace_tree_string()
```
This returns a structured text representation designed for agent or LLM consumption.
## Notes
* Tree methods rely on persisted rows in `agent_logs`.
* Call `flush()` before tree inspection when using manual spans.
# Nexus
Source: https://docs.trynexus.io/index
AI monitoring for custom silent failure modes in production
**Nexus** helps you trace AI execution in three ways:
* **Automatic tracing** via a LangChain callback handler.
* **OpenAI Agents SDK tracing** via `NexusOpenAITracingProcessor`.
* **Manual tracing** via `NexusClient` spans in your own code.
You can log runs, connect parent and child operations, and inspect tree structures from stored traces.
## Start here
Install the package and send your first trace.
Attach `LangHandler` to chains, tools, and agents.
Trace OpenAI agents with `NexusOpenAITracingProcessor`.
Configure DB and trigger behavior for your environment.
## What Nexus captures
* `run_id`, `trace_id`, `parent_run_id`, and `user_id`
* event category (`chain`, `llm`, `tool`, `agent`, `retriever`, and more)
* name metadata (for model, chain, tool, and agent nodes)
* JSON payloads for `input`, `output`, and `error`
This structure lets you reconstruct execution trees after a run and debug both failed and successful paths.
## Choose your tracing path
Plug in a callback and collect traces with minimal code changes.
Register a trace processor and capture every agent span automatically.
Add spans exactly where your app does meaningful work.
Your Nexus API key (`nexus_api_key`) is available on the [Nexus platform](https://app.trynexus.io).
# Quickstart
Source: https://docs.trynexus.io/quickstart
Install Nexus and emit your first trace
## Install
**LangChain integration**
```bash theme={null}
pip install nexus-library[langchain]
```
**OpenAI Agents SDK integration**
```bash theme={null}
pip install nexus-library[openai]
```
## Get your Nexus API key
Create or sign in to the Nexus platform and copy your `nexus_api_key`:
* [Nexus platform](https://app.trynexus.io)
In examples below, `nexus_key` means your `nexus_api_key`.
## Run your first manual trace
The source tree exports `NexusClient` from `nexus_library.nexus_core`.
```python theme={null}
from nexus_library.nexus_core import NexusClient
nexus_key = "your_nexus_api_key"
client = NexusClient(api_key=nexus_key)
with client.span("root-workflow", event_type="chain", input_data={"question": "What is Nexus?"}) as root:
with client.span("lookup-tool", event_type="tool", input_data={"query": "nexus-library"}) as tool_span:
tool_span.set_output({"result": "Tracing library for AI systems"})
root.set_output({"status": "ok"})
client.flush()
```
## Add LangChain callback tracing
```python theme={null}
from nexus_library.nexus_core import NexusClient
from nexus_library.langchain import LangHandler
nexus_key = "your_nexus_api_key"
nexus_client = NexusClient(api_key=nexus_key)
callback_handler = LangHandler(nexus_client)
# Attach `callback_handler` to your LangChain runnable / agent callbacks
```
## Add OpenAI Agents SDK tracing
```python theme={null}
import asyncio
import os
from agents import Agent, Runner, set_trace_processors
from nexus_library.nexus_core import NexusClient
from nexus_library.openai import NexusOpenAITracingProcessor
nexus_client = NexusClient(api_key=os.environ["NEXUS_API_KEY"])
dev_mode = os.getenv("NEXUS_DEV_MODE", "false").lower() == "true"
tracing_processor = NexusOpenAITracingProcessor(nexus_client, dev_mode=dev_mode)
set_trace_processors([tracing_processor])
async def main():
agent = Agent(name="my-agent", instructions="You are a helpful assistant.")
result = await Runner.run(agent, "Hello!")
print(result.final_output)
asyncio.run(main())
```
Set `NEXUS_DEV_MODE=true` locally to disable external triggers. Set it to `false` (or omit it) in production.
## Verify the trace exists
After your run finishes:
* use `client.get_all_events()` to fetch stored rows
* use `client.print_tree_structure()` to inspect hierarchy in terminal
* use `client.get_trace_tree_string()` to get an LLM-readable tree dump
## Next steps
Deep dive into span nesting and flush semantics.
Understand callback lifecycle and event categories.
Trace OpenAI agents with NexusOpenAITracingProcessor.
Set DB URLs and trigger endpoints safely.
Review method-level behavior for `NexusClient`.
`nexus_key` should be your Nexus platform `nexus_api_key`. Keep it secret and load it from environment variables in production.