# 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.