Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .agents/plugins/marketplace.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "codex-observability-plugin",
"name": "donadio-codex-observability",
"interface": {
"displayName": "Langfuse"
"displayName": "Langfuse realtime tracing"
},
"plugins": [
{
"name": "tracing",
"source": {
"source": "npm",
"package": "@langfuse/codex-observability-plugin"
"source": "local",
"path": "./plugins/tracing"
},
"policy": {
"installation": "AVAILABLE",
Expand Down
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
plugins/tracing/dist/index.mjs linguist-generated=true
5 changes: 5 additions & 0 deletions .github/codeql/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: Plugin source analysis
# The standalone artifact embeds unchanged npm dependencies. CI rebuilds it
# byte-for-byte from the scanned TypeScript and the integrity-pinned lockfile.
paths-ignore:
- plugins/tracing/dist
13 changes: 8 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,25 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

- name: Install pnpm
uses: pnpm/action-setup@v5
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5

- name: Setup Node.js
uses: actions/setup-node@v7
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7
with:
node-version: 22.x
node-version: 22.22.2
cache: "pnpm"

- name: Install dependencies
run: pnpm install --frozen-lockfile
run: pnpm install --frozen-lockfile --ignore-scripts --network-concurrency=4 --child-concurrency=1

- name: Lint
run: pnpm run lint

- name: Test
run: pnpm test

- name: Verify shipped bundle matches source
run: git diff --exit-code -- plugins/tracing/dist/index.mjs
32 changes: 32 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: CodeQL source

on:
push:
branches: [main]
pull_request:
workflow_dispatch:

concurrency:
group: codeql-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
analyze:
name: Analyze plugin source
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
security-events: write
actions: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: github/codeql-action/init@24c54180a607b1449ed407dd24f251e4e9147c8d # v4
with:
languages: javascript-typescript
config-file: ./.github/codeql/config.yml
- uses: github/codeql-action/analyze@24c54180a607b1449ed407dd24f251e4e9147c8d # v4
with:
category: /language:javascript-typescript
10 changes: 5 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- name: Validate release version
Expand All @@ -38,15 +38,15 @@ jobs:
exit 1
fi
- name: Setup pnpm
uses: pnpm/action-setup@v5
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5
- name: Setup Node.js
uses: actions/setup-node@v7
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7
with:
node-version: 22.x
node-version: 22.22.2
registry-url: https://registry.npmjs.org
package-manager-cache: false
- name: Install dependencies
run: pnpm install --frozen-lockfile
run: pnpm install --frozen-lockfile --ignore-scripts --network-concurrency=4 --child-concurrency=1
- name: Lint
run: pnpm run lint
- name: Test
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ node_modules/

# Codex writes a per-rollout dedup sidecar next to each transcript at runtime.
*.jsonl.langfuse
*.jsonl.langfuse-*

# Local debugging
debug.log

# Build output
plugins/tracing/dist/
plugins/tracing/dist/*
!plugins/tracing/dist/index.mjs

# Claude Code scratch space; globbed so a later `!` negation works.
.claude/*
54 changes: 47 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
# Langfuse Codex Plugin
# Langfuse Codex Plugin — Donadio fork

Codex plugin that sends OpenAI Codex session telemetry to Langfuse. It traces agent turns, model generations, reasoning summaries, system prompts, tool calls, images, subagent threads, skills, and token usage.

Langfuse also documents this integration on the [Codex integration page](https://langfuse.com/integrations/developer-tools/codex).
This fork uploads activity incrementally across all 12 supported Codex hooks.
The upstream project is [langfuse/codex-observability-plugin](https://github.com/langfuse/codex-observability-plugin).

Langfuse also documents the upstream integration on the [Codex integration page](https://langfuse.com/integrations/developer-tools/codex).

## Quick Start

Add the plugin marketplace:

```bash
codex plugin marketplace add langfuse/codex-observability-plugin
codex plugin marketplace add donadiosolutions/codex-observability-plugin --ref <commit-sha>
codex plugin add tracing@donadio-codex-observability --json
```

Then enable hooks and the plugin in `~/.codex/config.toml`, or only for one project in `<project>/.codex/config.toml`:
Expand All @@ -18,19 +22,47 @@ Then enable hooks and the plugin in `~/.codex/config.toml`, or only for one proj
[features]
hooks = true

[plugins."tracing@codex-observability-plugin"]
[plugins."tracing@donadio-codex-observability"]
enabled = true
```

Restart Codex after changing the config. When **Hooks need review** appears, review the Langfuse `Stop` hook in `/hooks` and trust it. An installed and enabled plugin is not yet a trusted hook, and no traces are uploaded before you trust it. Codex records trust against the current hook hash, so a plugin update can require another review.
Restart Codex after changing the config. When **Hooks need review** appears, review the tracing hooks in `/hooks` and trust them. An installed and enabled plugin is not yet a trusted hook, and no traces are uploaded before you trust it. Codex records trust against the current hook hash, so a plugin update can require another review.

## Supported Versions

- Codex `0.143` and newer
- A Codex build supporting all hooks below and `async: true` command hooks
(the local `0.162.1` hook contract was inspected during validation)
- Node.js `22` and newer
- The `npm` CLI on your `PATH`, which Codex uses to fetch the plugin from the npm registry
- Linux with the supplied `flock` command for exclusive uploader ownership
- Git access to this fork; the marketplace uses the shipped standalone bundle
- Langfuse Cloud, or self-hosted Langfuse `3.95.0` and newer

## Delivery

Every invocation records a hook event and uploads changed observations. Active
turns keep stable observation IDs as their input, output, usage, and completion
state change. Hook payloads cover transcript-flush races; child uploads resolve
their parent trace so a child can finish after its parent turn.

Live activity hooks run asynchronously. `Stop`, `SubagentStop`, `Interrupt`,
and `SessionEnd` flush synchronously because Codex cancels outstanding async
hooks before invoking its session-end handlers. Codex limits `SessionEnd`
and `Interrupt` to three seconds; pending payloads are saved before transcript
discovery and remain retryable if that deadline interrupts delivery. The supported events
are `PreToolUse`, `PermissionRequest`, `PostToolUse`, `PreCompact`, `PostCompact`,
`SessionStart`, `SessionEnd`, `UserPromptSubmit`, `SubagentStart`, `SubagentStop`,
`Stop`, and `Interrupt`.

Exports flush at 16 observations, an 8 MiB encoded request budget, or one second,
whichever comes first. A larger individual observation uses a single request
up to 256 MiB without truncation. Requests run sequentially. Failed or partially
acknowledged uploads remain retryable. Pending hook payloads and acknowledged
observation fingerprints are stored privately beside the root transcript;
concurrent invocations serialize delivery with a bounded lock.

Delivery follows hook events; Codex currently has no hook for each streamed
model token. Langfuse visibility also includes its ingestion processing time.

## Langfuse Credentials

Create `~/.codex/langfuse.json` (global) or `<project>/.codex/langfuse.json` (per-project) with your Langfuse credentials.
Expand Down Expand Up @@ -70,6 +102,14 @@ The remaining options are settable both ways, as a `langfuse.json` key or as the

Everything the plugin traces is uploaded to Langfuse, including prompts and tool inputs and outputs, so do not enable it for sessions containing data you do not want stored there.

## Build and review

The Git marketplace ships `dist/index.mjs`. CI rebuilds it and requires byte
identity with the committed artifact. CodeQL analyzes the TypeScript source
and tests; the generated dependency bundle is excluded from duplicate source
analysis. Dependency integrity remains pinned in `pnpm-lock.yaml` and checked
by Socket.

## Contributing

See the [contributing guide](./CONTRIBUTING.md).
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@
"tracing",
"opentelemetry"
],
"homepage": "https://github.com/langfuse/codex-observability-plugin#readme",
"homepage": "https://github.com/donadiosolutions/codex-observability-plugin#readme",
"bugs": {
"url": "https://github.com/langfuse/codex-observability-plugin/issues"
"url": "https://github.com/donadiosolutions/codex-observability-plugin/issues"
},
"license": "MIT",
"author": "Langfuse",
"repository": {
"type": "git",
"url": "https://github.com/langfuse/codex-observability-plugin.git"
"url": "https://github.com/donadiosolutions/codex-observability-plugin.git"
},
"type": "module",
"scripts": {
"build": "tsdown --config plugins/tracing/tsdown.config.ts",
"test": "pnpm run build && vitest run",
"test": "pnpm run build && vitest run --maxWorkers=1 --no-file-parallelism",
"test:watch": "pnpm run build && vitest",
"format": "prettier --write .",
"format:check": "prettier --check .",
Expand All @@ -36,6 +36,7 @@
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/core": "^2.11.0",
"@opentelemetry/exporter-trace-otlp-http": "^0.222.0",
"@opentelemetry/otlp-transformer": "0.222.0",
"@opentelemetry/resources": "^2.11.0",
"@opentelemetry/sdk-trace-base": "^2.11.0",
"@opentelemetry/sdk-trace-node": "^2.11.0",
Expand Down
8 changes: 4 additions & 4 deletions plugins/tracing/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
{
"name": "tracing",
"version": "0.4.2",
"version": "0.5.0-donadio.2",
"description": "Trace OpenAI Codex sessions to Langfuse.",
"author": {
"name": "Langfuse",
"email": "support@langfuse.com",
"url": "https://langfuse.com"
},
"homepage": "https://github.com/langfuse/codex-observability-plugin#readme",
"repository": "https://github.com/langfuse/codex-observability-plugin",
"homepage": "https://github.com/donadiosolutions/codex-observability-plugin#readme",
"repository": "https://github.com/donadiosolutions/codex-observability-plugin",
"license": "MIT",
"keywords": ["codex", "hooks", "langfuse", "observability", "tracing"],
"hooks": "./hooks/hooks.json",
"interface": {
"displayName": "Tracing",
"shortDescription": "Trace Codex sessions to Langfuse",
"longDescription": "Uploads completed OpenAI Codex rollout transcripts to Langfuse so teams can inspect Codex sessions as traces: agent turns, model calls, tool executions, token usage, and subagent threads.",
"longDescription": "Uploads Codex activity incrementally across all supported hooks, with asynchronous delivery and acknowledged observation checkpoints.",
"developerName": "Langfuse",
"category": "Coding",
"capabilities": ["Read"],
Expand Down
Loading
Loading