From 33a73d30064fed27ce48d61fe894869deddbe35d Mon Sep 17 00:00:00 2001 From: "kolbeyang@gmail.com" Date: Tue, 14 Jul 2026 22:11:00 +0000 Subject: [PATCH 1/3] LAM-1968: add Claude Code and Codex plugin integration pages New coding-agent integration pages for the Laminar Claude Code and Codex plugins, installable with one command via the new `lmnr-cli plugin add ` installer (lmnr-ts #279, shipped in lmnr-cli 0.3.2). Each page covers the CLI install flow, manual marketplace install, the ~/.config/lmnr/-plugin.json config contract, a dedicated self-hosting note (--frontend-url / --base-url, port-carrying baseUrl), and troubleshooting. Also: list both pages first under Coding agents in docs.json and the integrations overview, add a July 2026 changelog entry, and record the plugin-docs invariants in CLAUDE.md (lmnr@lmnr ref, per-agent activation, stale README ref caveat). Co-Authored-By: Claude Fable 5 --- CLAUDE.md | 8 ++ changelog.mdx | 1 + docs.json | 2 + tracing/integrations/claude-code.mdx | 142 +++++++++++++++++++++++++++ tracing/integrations/codex.mdx | 140 ++++++++++++++++++++++++++ tracing/integrations/overview.mdx | 6 ++ 6 files changed, 299 insertions(+) create mode 100644 tracing/integrations/claude-code.mdx create mode 100644 tracing/integrations/codex.mdx diff --git a/CLAUDE.md b/CLAUDE.md index f9954e7..450ff1b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -162,6 +162,14 @@ This is a Mintlify site. Pages are `.mdx`, navigation lives in `docs.json`, reus - **Signal/alert enable-disable** (LAM-1858, docs LAM-1927): the `disabled` flag lives in the JSONB `metadata` column of `signals` / `alerts` (absent = enabled, only persisted when true; migration 0102 moved `sample_rate` into `signals.metadata` — staging Postgres lagged this one, apply the committed SQL if `s.metadata` errors). UI surface is in the OSS repo, so screenshots come from the local `lmnr` prod stack. Docs vocabulary: the UI switch label is **Active**/**Inactive**, the signals-list badge and section header say **Disabled** — use "pause"/"paused" for the verb in prose, and never invent an "Enabled" badge. Disabled signals reject backfills (403) and skip trigger evaluation but keep events/clusters; disabled alerts only silence notifications. - Alert trigger labels in the UI come from `ALERT_TYPE_LABELS` in `frontend/lib/actions/alerts/types.ts`: `SIGNAL_EVENT` → **New event**, `NEW_CLUSTER` → **New cluster**. Docs should use these user-facing labels, not the raw enum names, when describing the trigger picker or alert rows. +## Claude Code and Codex plugin integrations + +- Pages: `tracing/integrations/claude-code.mdx` and `tracing/integrations/codex.mdx` (LAM-1968), listed FIRST in the Coding agents section of `docs.json` and `tracing/integrations/overview.mdx`, before Claude Agent SDK / OpenCode. Source repos: `github.com/lmnr-ai/lmnr-claude-code-plugin` and `lmnr-ai/lmnr-codex-plugin` (not under `/repos`; clone to inspect). CLI installer lives in `lmnr-ts/packages/lmnr-cli/src/commands/plugin/index.ts` (`AGENTS` registry is the source of truth for marketplace refs, install verbs, and config filenames). +- Canonical install is `npx lmnr-cli@latest plugin add claude-code|codex` (shipped in `lmnr-cli` 0.3.2). It is GLOBAL and directory-independent: never touches `.lmnr/project.json` or `.env`; the minted key goes to `~/.config/lmnr/-plugin.json` (0600) as `{ projectApiKey, baseUrl }`, which is the plugin's primary config source. `LMNR_PROJECT_API_KEY` / `LMNR_BASE_URL` env override the file. Don't document `--config` flags or the old Codex curl-bundle/launcher/config.toml flow — both were replaced by native marketplace installs. +- **The manual-install plugin ref is `lmnr@lmnr` for BOTH agents** (`claude plugin install lmnr@lmnr --scope user`; `codex plugin add lmnr@lmnr`). The Claude plugin repo's README still says `laminar@laminar` — that's stale; the `.claude-plugin/marketplace.json` manifest (marketplace `lmnr`, plugin `lmnr`) and the published CLI both use `lmnr@lmnr`. +- Activation differs per agent and must stay distinct in docs: Claude Code has `/reload-plugins` (or restart in a NEW terminal window — relaunching in the same terminal can reuse the previous session and skip the plugin); Codex has no in-session reload, so restart. +- Self-hoster wiring: `plugin add` takes `--frontend-url` (auth issuer, mints the key via `POST /api/cli/api-key`) and `--base-url` (written to the config file verbatim; the plugin POSTs OTLP/JSON to `/v1/traces`, so the URL must carry the API port, e.g. `http://localhost:8000`). Unlike the SDK's `base_url` + `http_port` split, the plugin config's `baseUrl` INCLUDES the port. + ## Claude Agent SDK integration - Public TS API is `Laminar.wrapClaudeAgentQuery(originalQuery)` (alias: module-level `instrumentClaudeAgentQuery`). Document the static-method form; it's the one in the TSDoc example. diff --git a/changelog.mdx b/changelog.mdx index 8dce7d4..18e1246 100644 --- a/changelog.mdx +++ b/changelog.mdx @@ -6,6 +6,7 @@ New releases and improvements. ## July 2026 +- **Claude Code and Codex plugins** - Trace [Claude Code](/tracing/integrations/claude-code) and [OpenAI Codex CLI](/tracing/integrations/codex) sessions in Laminar with a one-command install: `npx lmnr-cli@latest plugin add claude-code` (or `codex`) logs you in, picks a project, mints a key, and installs the plugin. Each turn becomes a trace with LLM calls, tool executions, and (for Claude Code) subagents, grouped into one session per conversation. - **Generate render templates in the editor** - The [render template](/platform/render-templates#generate-a-template) editor now generates the JSX for you: name the template, describe the view you want, click **Generate**, and iterate with **Request changes**. For trace templates, generation also writes the span filter from an outline of the trace's real spans and refreshes the sample data against it. No more copying a prompt to an external AI tool, though the **Copy prompt** fallback remains in the Code tab. - **Enable or disable Signals and alerts** - [Pause a Signal](/signals/quickstart#pause-and-resume-a-signal) with the **Active** switch in its settings: new traces stop being evaluated while existing events and clusters are kept, and paused Signals are grouped under a **Disabled** section on the Signals list. [Alerts](/signals/alerts#enable-or-disable-an-alert) get the same treatment, with an on/off switch directly on each alert card to silence notifications without losing the alert's configuration. - **Evaluations UI refresh** - The [evaluations page](/evaluations/comparing-runs) now has a groups sidebar with run counts, a combined progression chart with one line per score dimension (legend toggles, per-run eye icons to exclude runs), and an aggregation picker (Average, Sum, Min, Max, Median, p90/p95/p99). The run detail page is a split view with the datapoint table next to an always-open trace panel, and side-by-side comparison shows `old → new` deltas on the score card and on every row. diff --git a/docs.json b/docs.json index 95d0204..7a8eb2d 100644 --- a/docs.json +++ b/docs.json @@ -31,6 +31,8 @@ "tracing/integrations/anthropic", "tracing/integrations/openai", "tracing/integrations/gemini", + "tracing/integrations/claude-code", + "tracing/integrations/codex", "tracing/integrations/claude-agent-sdk", "tracing/integrations/openai-agents-sdk", "tracing/integrations/opencode", diff --git a/tracing/integrations/claude-code.mdx b/tracing/integrations/claude-code.mdx new file mode 100644 index 0000000..57605ad --- /dev/null +++ b/tracing/integrations/claude-code.mdx @@ -0,0 +1,142 @@ +--- +title: Claude Code Observability, Trace Sessions in Laminar +sidebarTitle: Claude Code +--- + +## Overview + +Laminar is an open-source, OpenTelemetry-native observability platform for AI agents. Trace, debug, and monitor every [Claude Code](https://claude.com/claude-code) session: each conversational turn lands in Laminar as a full trace with LLM calls, tool executions, and subagents. Self-host via Helm or use managed cloud. + +The integration is a Claude Code plugin. It hooks into the end of each assistant response, reads the session transcript, and exports spans to Laminar. It fails open: if Laminar is unreachable, Claude Code is never blocked. + +What Laminar captures: + +- One trace per conversational turn, with your prompt and the final assistant response on the root span. +- Every LLM call with input and output messages, model name, and token usage (including cache reads and writes). +- Tool calls (`Read`, `Write`, `Edit`, `Bash`, MCP tools, and the rest) with arguments and results. +- Subagents as nested spans under the tool call that spawned them, including agents that finish in the background. +- Session grouping: all turns of one Claude Code session show up under one [session](/tracing/structure/sessions) in Laminar. +- Context on every trace: working directory, git branch, and Claude Code version as queryable metadata. + +## Install + + + + +```bash +npx lmnr-cli@latest plugin add claude-code +``` + +The CLI logs you in (browser device flow), lets you pick the Laminar project that should receive your Claude Code traces, mints a project API key named after the plugin and your machine, writes it to `~/.config/lmnr/claude-code-plugin.json`, and installs the plugin through Claude Code's own plugin marketplace. No `npm install` is needed inside the plugin. + + +Pick a dedicated project for coding-agent traces so they don't mix with your application's traces. The setup is global and directory-independent: it never touches `.lmnr/project.json` or your `.env`. + + + + + +Run `/reload-plugins` in an open Claude Code session, or quit Claude Code and start it in a new terminal window. + + + + +Every turn becomes a trace in the project you picked. Open the Laminar dashboard to watch them land in realtime. + + + + + +**Self-hosting Laminar?** The same command works against your instance: pass your frontend URL (the auth issuer) and your API URL, including the API port: + +```bash +npx lmnr-cli@latest plugin add claude-code \ + --frontend-url https://laminar.example.com \ + --base-url https://api.laminar.example.com +``` + +For a local [Docker Compose](/self-hosting/docker-compose) deployment, that's `--frontend-url http://localhost:5667 --base-url http://localhost:8000`. The `--base-url` value is written to the plugin's config file verbatim and the plugin sends traces to `/v1/traces`, so include the port when your API doesn't listen on 443. Already installed and pointing at the wrong place? Edit `baseUrl` in `~/.config/lmnr/claude-code-plugin.json`. + + +### Manual install + +If you'd rather not use `lmnr-cli`, install the plugin with Claude Code's plugin commands and create the config file yourself: + +```bash +claude plugin marketplace add lmnr-ai/lmnr-claude-code-plugin +claude plugin install lmnr@lmnr --scope user +``` + +Then create `~/.config/lmnr/claude-code-plugin.json` with a project API key. Get one from the Laminar dashboard under **Settings → Project API Keys** (create a dedicated key so it's clear it belongs to the plugin): + +```bash +mkdir -p ~/.config/lmnr +cat > ~/.config/lmnr/claude-code-plugin.json <<'EOF' +{ "projectApiKey": "your-project-api-key", "baseUrl": "https://api.lmnr.ai" } +EOF +chmod 600 ~/.config/lmnr/claude-code-plugin.json +``` + +`projectApiKey` is required. `baseUrl` is optional and defaults to `https://api.lmnr.ai`; self-hosters set it to their instance's API URL (for example `http://localhost:8000`). + +## Configuration + +The plugin reads its config from `~/.config/lmnr/claude-code-plugin.json`, written by `lmnr-cli plugin add claude-code`: + +```json +{ "projectApiKey": "...", "baseUrl": "https://api.lmnr.ai" } +``` + +The environment variables `LMNR_PROJECT_API_KEY` and `LMNR_BASE_URL` override the file when set, which is handy for CI or a shell you already have configured. Traces are attributed to the identity from `lmnr-cli login` when present; set `LMNR_USER_ID` to override the user id attached to traces. + +## See what happened in a trace + +Open any turn in [Viewing traces](/platform/viewing-traces). Laminar extracts your prompt, the LLM outputs, tool calls, and subagent runs into a transcript view, so you read the conversation instead of a span tree. Subagents render as collapsible cards showing their input and final output. + +## Track outcomes with Signals + +Traces answer *what happened on this turn*. **[Signals](/signals/introduction) answer the cross-trace question**: *how often does Claude Code edit a file it wasn't asked to touch, when does a Bash call fail three times in a row, which sessions burn tokens without producing a diff*. A Signal pairs a plain-language prompt with a JSON output schema. Laminar runs it live on new traces (Triggers) or backfills it across history (Jobs) and records a structured event every time it matches. From there you [query](/platform/sql-editor), [cluster](/signals/clusters), and [alert](/signals/alerts) on events across every trace. + + +Every new project ships with a **Failure Detector** Signal that categorizes issues on any trace over 1000 tokens. Open it from the Signals sidebar to see events as soon as your Claude Code traces arrive. + + +## Query across traces + +- **[SQL editor](/platform/sql-editor)** for ad-hoc queries across traces, spans, signals, and evals. +- **SQL API** for programmatic access from scripts and pipelines. +- **[CLI](/platform/cli)** (`lmnr-cli sql query`) for terminal-driven queries and piping JSON into shell tools or coding agents. +- **[MCP server](/platform/mcp)** to query Laminar directly from Claude Code itself, Cursor, or Codex. + +## Troubleshooting + + + + - Confirm `~/.config/lmnr/claude-code-plugin.json` exists and contains a valid `projectApiKey`. Without a key the plugin exits silently. + - Make sure the plugin is active: restart Claude Code in a new terminal window, or run `/reload-plugins`. + - Check that you're looking at the project you picked during `plugin add`. The key is named `Claude Code plugin @ ` in **Settings → Project API Keys**, which tells you which project it belongs to. + + + `lmnr-cli plugin add` runs the install through the `claude` CLI. When `claude` isn't on your PATH or is too old to have plugin support, the CLI prints the `claude plugin ...` commands for you to run by hand after updating. Your API key is already minted and written to the config file at that point, so running the two printed commands finishes the setup. + + + Re-run the installer with `--frontend-url` and `--base-url` pointing at your instance (see the note in [Install](#install)), or edit `baseUrl` in `~/.config/lmnr/claude-code-plugin.json` directly. The plugin exports traces to `/v1/traces`, so the URL must include your API's HTTP port when it isn't 443. + + + +## What's next + + + + Read the transcript view, filter, and search across traces. + + + Detect behaviors and failures across every Claude Code turn, then query, cluster, and alert on them. + + + Also using OpenAI Codex CLI? Install its Laminar plugin the same way. + + + Calling the Claude Code agent from your own code? Trace it with the SDK integration. + + diff --git a/tracing/integrations/codex.mdx b/tracing/integrations/codex.mdx new file mode 100644 index 0000000..eff97c1 --- /dev/null +++ b/tracing/integrations/codex.mdx @@ -0,0 +1,140 @@ +--- +title: OpenAI Codex CLI Observability, Trace Sessions in Laminar +sidebarTitle: Codex +--- + +## Overview + +Laminar is an open-source, OpenTelemetry-native observability platform for AI agents. Trace, debug, and monitor every [OpenAI Codex CLI](https://github.com/openai/codex) session: each conversational turn lands in Laminar as a full trace with LLM calls and tool executions. Self-host via Helm or use managed cloud. + +The integration is a native Codex plugin. It hooks into the end of each turn, reads the Codex rollout, and exports spans to Laminar. It fails open: if Laminar is unreachable, Codex is never blocked. + +What Laminar captures: + +- One trace per conversational turn, with your prompt and the final assistant answer on the root span. +- Every model step with model name, input and output messages, and token usage. +- Tool calls (shell commands, MCP tools, web search, custom tools) with arguments and results. +- Session grouping: all turns of one Codex thread show up under one [session](/tracing/structure/sessions) in Laminar. + +## Install + + + + +```bash +npx lmnr-cli@latest plugin add codex +``` + +The CLI logs you in (browser device flow), lets you pick the Laminar project that should receive your Codex traces, mints a project API key named after the plugin and your machine, writes it to `~/.config/lmnr/codex-plugin.json`, and installs the plugin through Codex's native plugin marketplace. + + +Pick a dedicated project for coding-agent traces so they don't mix with your application's traces. The setup is global and directory-independent: it never touches `.lmnr/project.json` or your `.env`. + + + + + +Codex loads plugins at startup, so restart it to activate the plugin. + + + + +Every turn becomes a trace in the project you picked. Open the Laminar dashboard to watch them land in realtime. + + + + + +**Self-hosting Laminar?** The same command works against your instance: pass your frontend URL (the auth issuer) and your API URL, including the API port: + +```bash +npx lmnr-cli@latest plugin add codex \ + --frontend-url https://laminar.example.com \ + --base-url https://api.laminar.example.com +``` + +For a local [Docker Compose](/self-hosting/docker-compose) deployment, that's `--frontend-url http://localhost:5667 --base-url http://localhost:8000`. The `--base-url` value is written to the plugin's config file verbatim and the plugin sends traces to `/v1/traces`, so include the port when your API doesn't listen on 443. Already installed and pointing at the wrong place? Edit `baseUrl` in `~/.config/lmnr/codex-plugin.json`. + + +### Manual install + +If you'd rather not use `lmnr-cli`, install the plugin with Codex's plugin commands and create the config file yourself: + +```bash +codex plugin marketplace add lmnr-ai/lmnr-codex-plugin +codex plugin add lmnr@lmnr +``` + +Then create `~/.config/lmnr/codex-plugin.json` with a project API key. Get one from the Laminar dashboard under **Settings → Project API Keys** (create a dedicated key so it's clear it belongs to the plugin): + +```bash +mkdir -p ~/.config/lmnr +cat > ~/.config/lmnr/codex-plugin.json <<'EOF' +{ "projectApiKey": "your-project-api-key", "baseUrl": "https://api.lmnr.ai" } +EOF +chmod 600 ~/.config/lmnr/codex-plugin.json +``` + +`projectApiKey` is required. `baseUrl` is optional and defaults to `https://api.lmnr.ai`; self-hosters set it to their instance's API URL (for example `http://localhost:8000`). + +## Configuration + +The plugin reads its config from `~/.config/lmnr/codex-plugin.json`, written by `lmnr-cli plugin add codex`: + +```json +{ "projectApiKey": "...", "baseUrl": "https://api.lmnr.ai" } +``` + +The environment variables `LMNR_PROJECT_API_KEY` and `LMNR_BASE_URL` override the file when set, which is handy for CI or a shell you already have configured. Traces are attributed to the identity from `lmnr-cli login` when present; set `LMNR_USER_ID` to override the user id attached to traces. + +## See what happened in a trace + +Open any turn in [Viewing traces](/platform/viewing-traces). Laminar extracts your prompt, the model outputs, and tool calls into a transcript view, so you read the conversation instead of a span tree. + +## Track outcomes with Signals + +Traces answer *what happened on this turn*. **[Signals](/signals/introduction) answer the cross-trace question**: *how often does Codex run a destructive shell command, when does a turn fail after repeated tool errors, which sessions burn tokens without producing a diff*. A Signal pairs a plain-language prompt with a JSON output schema. Laminar runs it live on new traces (Triggers) or backfills it across history (Jobs) and records a structured event every time it matches. From there you [query](/platform/sql-editor), [cluster](/signals/clusters), and [alert](/signals/alerts) on events across every trace. + + +Every new project ships with a **Failure Detector** Signal that categorizes issues on any trace over 1000 tokens. Open it from the Signals sidebar to see events as soon as your Codex traces arrive. + + +## Query across traces + +- **[SQL editor](/platform/sql-editor)** for ad-hoc queries across traces, spans, signals, and evals. +- **SQL API** for programmatic access from scripts and pipelines. +- **[CLI](/platform/cli)** (`lmnr-cli sql query`) for terminal-driven queries and piping JSON into shell tools or coding agents. +- **[MCP server](/platform/mcp)** to query Laminar directly from Codex itself, Claude Code, or Cursor. + +## Troubleshooting + + + + - Confirm `~/.config/lmnr/codex-plugin.json` exists and contains a valid `projectApiKey`. Without a key the plugin exits silently. + - Make sure you restarted Codex after installing; plugins load at startup. + - Check that you're looking at the project you picked during `plugin add`. The key is named `Codex plugin @ ` in **Settings → Project API Keys**, which tells you which project it belongs to. + + + `lmnr-cli plugin add` runs the install through the `codex` CLI. When `codex` isn't on your PATH or is too old to have plugin support, the CLI prints the `codex plugin ...` commands for you to run by hand after updating. Your API key is already minted and written to the config file at that point, so running the two printed commands finishes the setup. + + + Re-run the installer with `--frontend-url` and `--base-url` pointing at your instance (see the note in [Install](#install)), or edit `baseUrl` in `~/.config/lmnr/codex-plugin.json` directly. The plugin exports traces to `/v1/traces`, so the URL must include your API's HTTP port when it isn't 443. + + + +## What's next + + + + Read the transcript view, filter, and search across traces. + + + Detect behaviors and failures across every Codex turn, then query, cluster, and alert on them. + + + Also using Claude Code? Install its Laminar plugin the same way. + + + Building agents with the OpenAI Agents SDK? Trace them with the SDK integration. + + diff --git a/tracing/integrations/overview.mdx b/tracing/integrations/overview.mdx index b302828..f74ccee 100644 --- a/tracing/integrations/overview.mdx +++ b/tracing/integrations/overview.mdx @@ -69,6 +69,12 @@ Multi-step agents, tool calls, and subagents render as a transcript instead of a ## Coding agents + + Trace Claude Code sessions with a one-command plugin install. + + + Trace OpenAI Codex CLI sessions with a one-command plugin install. + Trace Claude Agent SDK runs and subagents. From b4d2da50ce9a7ff94945e61f1152293f15da820d Mon Sep 17 00:00:00 2001 From: kolbeyang Date: Tue, 14 Jul 2026 15:32:43 -0700 Subject: [PATCH 2/3] docs: trim Claude Code and Codex plugin pages to lean install references Co-Authored-By: Claude Opus 4.8 (1M context) --- tracing/integrations/claude-code.mdx | 77 ++-------------------------- tracing/integrations/codex.mdx | 73 ++------------------------ 2 files changed, 7 insertions(+), 143 deletions(-) diff --git a/tracing/integrations/claude-code.mdx b/tracing/integrations/claude-code.mdx index 57605ad..bd5854e 100644 --- a/tracing/integrations/claude-code.mdx +++ b/tracing/integrations/claude-code.mdx @@ -1,22 +1,11 @@ --- -title: Claude Code Observability, Trace Sessions in Laminar +title: Claude Code Plugin sidebarTitle: Claude Code --- ## Overview -Laminar is an open-source, OpenTelemetry-native observability platform for AI agents. Trace, debug, and monitor every [Claude Code](https://claude.com/claude-code) session: each conversational turn lands in Laminar as a full trace with LLM calls, tool executions, and subagents. Self-host via Helm or use managed cloud. - -The integration is a Claude Code plugin. It hooks into the end of each assistant response, reads the session transcript, and exports spans to Laminar. It fails open: if Laminar is unreachable, Claude Code is never blocked. - -What Laminar captures: - -- One trace per conversational turn, with your prompt and the final assistant response on the root span. -- Every LLM call with input and output messages, model name, and token usage (including cache reads and writes). -- Tool calls (`Read`, `Write`, `Edit`, `Bash`, MCP tools, and the rest) with arguments and results. -- Subagents as nested spans under the tool call that spawned them, including agents that finish in the background. -- Session grouping: all turns of one Claude Code session show up under one [session](/tracing/structure/sessions) in Laminar. -- Context on every trace: working directory, git branch, and Claude Code version as queryable metadata. +The Claude Code plugin traces every local [Claude Code](https://claude.com/claude-code) session: each turn becomes a full trace with its LLM calls, tool executions, and subagents, sent to Laminar Cloud or your self-hosted Helm deployment. ## Install @@ -27,7 +16,7 @@ What Laminar captures: npx lmnr-cli@latest plugin add claude-code ``` -The CLI logs you in (browser device flow), lets you pick the Laminar project that should receive your Claude Code traces, mints a project API key named after the plugin and your machine, writes it to `~/.config/lmnr/claude-code-plugin.json`, and installs the plugin through Claude Code's own plugin marketplace. No `npm install` is needed inside the plugin. +The CLI logs you in (browser device flow), lets you pick the Laminar project that should receive your Claude Code traces, mints a project API key named after the plugin and your machine, writes it to `~/.config/lmnr/claude-code-plugin.json`, and installs the plugin through Claude Code's own plugin marketplace. Pick a dedicated project for coding-agent traces so they don't mix with your application's traces. The setup is global and directory-independent: it never touches `.lmnr/project.json` or your `.env`. @@ -54,8 +43,6 @@ npx lmnr-cli@latest plugin add claude-code \ --frontend-url https://laminar.example.com \ --base-url https://api.laminar.example.com ``` - -For a local [Docker Compose](/self-hosting/docker-compose) deployment, that's `--frontend-url http://localhost:5667 --base-url http://localhost:8000`. The `--base-url` value is written to the plugin's config file verbatim and the plugin sends traces to `/v1/traces`, so include the port when your API doesn't listen on 443. Already installed and pointing at the wrong place? Edit `baseUrl` in `~/.config/lmnr/claude-code-plugin.json`. ### Manual install @@ -69,12 +56,8 @@ claude plugin install lmnr@lmnr --scope user Then create `~/.config/lmnr/claude-code-plugin.json` with a project API key. Get one from the Laminar dashboard under **Settings → Project API Keys** (create a dedicated key so it's clear it belongs to the plugin): -```bash -mkdir -p ~/.config/lmnr -cat > ~/.config/lmnr/claude-code-plugin.json <<'EOF' +```json ~/.config/lmnr/claude-code-plugin.json { "projectApiKey": "your-project-api-key", "baseUrl": "https://api.lmnr.ai" } -EOF -chmod 600 ~/.config/lmnr/claude-code-plugin.json ``` `projectApiKey` is required. `baseUrl` is optional and defaults to `https://api.lmnr.ai`; self-hosters set it to their instance's API URL (for example `http://localhost:8000`). @@ -88,55 +71,3 @@ The plugin reads its config from `~/.config/lmnr/claude-code-plugin.json`, writt ``` The environment variables `LMNR_PROJECT_API_KEY` and `LMNR_BASE_URL` override the file when set, which is handy for CI or a shell you already have configured. Traces are attributed to the identity from `lmnr-cli login` when present; set `LMNR_USER_ID` to override the user id attached to traces. - -## See what happened in a trace - -Open any turn in [Viewing traces](/platform/viewing-traces). Laminar extracts your prompt, the LLM outputs, tool calls, and subagent runs into a transcript view, so you read the conversation instead of a span tree. Subagents render as collapsible cards showing their input and final output. - -## Track outcomes with Signals - -Traces answer *what happened on this turn*. **[Signals](/signals/introduction) answer the cross-trace question**: *how often does Claude Code edit a file it wasn't asked to touch, when does a Bash call fail three times in a row, which sessions burn tokens without producing a diff*. A Signal pairs a plain-language prompt with a JSON output schema. Laminar runs it live on new traces (Triggers) or backfills it across history (Jobs) and records a structured event every time it matches. From there you [query](/platform/sql-editor), [cluster](/signals/clusters), and [alert](/signals/alerts) on events across every trace. - - -Every new project ships with a **Failure Detector** Signal that categorizes issues on any trace over 1000 tokens. Open it from the Signals sidebar to see events as soon as your Claude Code traces arrive. - - -## Query across traces - -- **[SQL editor](/platform/sql-editor)** for ad-hoc queries across traces, spans, signals, and evals. -- **SQL API** for programmatic access from scripts and pipelines. -- **[CLI](/platform/cli)** (`lmnr-cli sql query`) for terminal-driven queries and piping JSON into shell tools or coding agents. -- **[MCP server](/platform/mcp)** to query Laminar directly from Claude Code itself, Cursor, or Codex. - -## Troubleshooting - - - - - Confirm `~/.config/lmnr/claude-code-plugin.json` exists and contains a valid `projectApiKey`. Without a key the plugin exits silently. - - Make sure the plugin is active: restart Claude Code in a new terminal window, or run `/reload-plugins`. - - Check that you're looking at the project you picked during `plugin add`. The key is named `Claude Code plugin @ ` in **Settings → Project API Keys**, which tells you which project it belongs to. - - - `lmnr-cli plugin add` runs the install through the `claude` CLI. When `claude` isn't on your PATH or is too old to have plugin support, the CLI prints the `claude plugin ...` commands for you to run by hand after updating. Your API key is already minted and written to the config file at that point, so running the two printed commands finishes the setup. - - - Re-run the installer with `--frontend-url` and `--base-url` pointing at your instance (see the note in [Install](#install)), or edit `baseUrl` in `~/.config/lmnr/claude-code-plugin.json` directly. The plugin exports traces to `/v1/traces`, so the URL must include your API's HTTP port when it isn't 443. - - - -## What's next - - - - Read the transcript view, filter, and search across traces. - - - Detect behaviors and failures across every Claude Code turn, then query, cluster, and alert on them. - - - Also using OpenAI Codex CLI? Install its Laminar plugin the same way. - - - Calling the Claude Code agent from your own code? Trace it with the SDK integration. - - diff --git a/tracing/integrations/codex.mdx b/tracing/integrations/codex.mdx index eff97c1..9086044 100644 --- a/tracing/integrations/codex.mdx +++ b/tracing/integrations/codex.mdx @@ -1,20 +1,11 @@ --- -title: OpenAI Codex CLI Observability, Trace Sessions in Laminar +title: Codex Plugin sidebarTitle: Codex --- ## Overview -Laminar is an open-source, OpenTelemetry-native observability platform for AI agents. Trace, debug, and monitor every [OpenAI Codex CLI](https://github.com/openai/codex) session: each conversational turn lands in Laminar as a full trace with LLM calls and tool executions. Self-host via Helm or use managed cloud. - -The integration is a native Codex plugin. It hooks into the end of each turn, reads the Codex rollout, and exports spans to Laminar. It fails open: if Laminar is unreachable, Codex is never blocked. - -What Laminar captures: - -- One trace per conversational turn, with your prompt and the final assistant answer on the root span. -- Every model step with model name, input and output messages, and token usage. -- Tool calls (shell commands, MCP tools, web search, custom tools) with arguments and results. -- Session grouping: all turns of one Codex thread show up under one [session](/tracing/structure/sessions) in Laminar. +The Codex plugin traces every local [OpenAI Codex CLI](https://github.com/openai/codex) session: each turn becomes a full trace with its LLM calls and tool executions, sent to Laminar Cloud or your self-hosted Helm deployment. ## Install @@ -52,8 +43,6 @@ npx lmnr-cli@latest plugin add codex \ --frontend-url https://laminar.example.com \ --base-url https://api.laminar.example.com ``` - -For a local [Docker Compose](/self-hosting/docker-compose) deployment, that's `--frontend-url http://localhost:5667 --base-url http://localhost:8000`. The `--base-url` value is written to the plugin's config file verbatim and the plugin sends traces to `/v1/traces`, so include the port when your API doesn't listen on 443. Already installed and pointing at the wrong place? Edit `baseUrl` in `~/.config/lmnr/codex-plugin.json`. ### Manual install @@ -67,12 +56,8 @@ codex plugin add lmnr@lmnr Then create `~/.config/lmnr/codex-plugin.json` with a project API key. Get one from the Laminar dashboard under **Settings → Project API Keys** (create a dedicated key so it's clear it belongs to the plugin): -```bash -mkdir -p ~/.config/lmnr -cat > ~/.config/lmnr/codex-plugin.json <<'EOF' +```json ~/.config/lmnr/codex-plugin.json { "projectApiKey": "your-project-api-key", "baseUrl": "https://api.lmnr.ai" } -EOF -chmod 600 ~/.config/lmnr/codex-plugin.json ``` `projectApiKey` is required. `baseUrl` is optional and defaults to `https://api.lmnr.ai`; self-hosters set it to their instance's API URL (for example `http://localhost:8000`). @@ -86,55 +71,3 @@ The plugin reads its config from `~/.config/lmnr/codex-plugin.json`, written by ``` The environment variables `LMNR_PROJECT_API_KEY` and `LMNR_BASE_URL` override the file when set, which is handy for CI or a shell you already have configured. Traces are attributed to the identity from `lmnr-cli login` when present; set `LMNR_USER_ID` to override the user id attached to traces. - -## See what happened in a trace - -Open any turn in [Viewing traces](/platform/viewing-traces). Laminar extracts your prompt, the model outputs, and tool calls into a transcript view, so you read the conversation instead of a span tree. - -## Track outcomes with Signals - -Traces answer *what happened on this turn*. **[Signals](/signals/introduction) answer the cross-trace question**: *how often does Codex run a destructive shell command, when does a turn fail after repeated tool errors, which sessions burn tokens without producing a diff*. A Signal pairs a plain-language prompt with a JSON output schema. Laminar runs it live on new traces (Triggers) or backfills it across history (Jobs) and records a structured event every time it matches. From there you [query](/platform/sql-editor), [cluster](/signals/clusters), and [alert](/signals/alerts) on events across every trace. - - -Every new project ships with a **Failure Detector** Signal that categorizes issues on any trace over 1000 tokens. Open it from the Signals sidebar to see events as soon as your Codex traces arrive. - - -## Query across traces - -- **[SQL editor](/platform/sql-editor)** for ad-hoc queries across traces, spans, signals, and evals. -- **SQL API** for programmatic access from scripts and pipelines. -- **[CLI](/platform/cli)** (`lmnr-cli sql query`) for terminal-driven queries and piping JSON into shell tools or coding agents. -- **[MCP server](/platform/mcp)** to query Laminar directly from Codex itself, Claude Code, or Cursor. - -## Troubleshooting - - - - - Confirm `~/.config/lmnr/codex-plugin.json` exists and contains a valid `projectApiKey`. Without a key the plugin exits silently. - - Make sure you restarted Codex after installing; plugins load at startup. - - Check that you're looking at the project you picked during `plugin add`. The key is named `Codex plugin @ ` in **Settings → Project API Keys**, which tells you which project it belongs to. - - - `lmnr-cli plugin add` runs the install through the `codex` CLI. When `codex` isn't on your PATH or is too old to have plugin support, the CLI prints the `codex plugin ...` commands for you to run by hand after updating. Your API key is already minted and written to the config file at that point, so running the two printed commands finishes the setup. - - - Re-run the installer with `--frontend-url` and `--base-url` pointing at your instance (see the note in [Install](#install)), or edit `baseUrl` in `~/.config/lmnr/codex-plugin.json` directly. The plugin exports traces to `/v1/traces`, so the URL must include your API's HTTP port when it isn't 443. - - - -## What's next - - - - Read the transcript view, filter, and search across traces. - - - Detect behaviors and failures across every Codex turn, then query, cluster, and alert on them. - - - Also using Claude Code? Install its Laminar plugin the same way. - - - Building agents with the OpenAI Agents SDK? Trace them with the SDK integration. - - From 988c4c20c3a92a59b767ee4267ab30d7ecd7ff0b Mon Sep 17 00:00:00 2001 From: kolbeyang Date: Tue, 14 Jul 2026 15:33:30 -0700 Subject: [PATCH 3/3] docs: shorten plugin overview to "sent to Laminar" Co-Authored-By: Claude Opus 4.8 (1M context) --- tracing/integrations/claude-code.mdx | 2 +- tracing/integrations/codex.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tracing/integrations/claude-code.mdx b/tracing/integrations/claude-code.mdx index bd5854e..271b7be 100644 --- a/tracing/integrations/claude-code.mdx +++ b/tracing/integrations/claude-code.mdx @@ -5,7 +5,7 @@ sidebarTitle: Claude Code ## Overview -The Claude Code plugin traces every local [Claude Code](https://claude.com/claude-code) session: each turn becomes a full trace with its LLM calls, tool executions, and subagents, sent to Laminar Cloud or your self-hosted Helm deployment. +The Claude Code plugin traces every local [Claude Code](https://claude.com/claude-code) session: each turn becomes a full trace with its LLM calls, tool executions, and subagents, sent to Laminar. ## Install diff --git a/tracing/integrations/codex.mdx b/tracing/integrations/codex.mdx index 9086044..fac4b88 100644 --- a/tracing/integrations/codex.mdx +++ b/tracing/integrations/codex.mdx @@ -5,7 +5,7 @@ sidebarTitle: Codex ## Overview -The Codex plugin traces every local [OpenAI Codex CLI](https://github.com/openai/codex) session: each turn becomes a full trace with its LLM calls and tool executions, sent to Laminar Cloud or your self-hosted Helm deployment. +The Codex plugin traces every local [OpenAI Codex CLI](https://github.com/openai/codex) session: each turn becomes a full trace with its LLM calls and tool executions, sent to Laminar. ## Install