Project Info
Inspiration
I cofounded Appacella, an AI mobile app developer. While building that, I manually read hundreds of AI coding traces to find issues and improve the agent. Now I work on RL environments and hit the same wall: I need to read hundreds of transcripts of the model attempting a task. I can't trust the model to read the whole thing itself so I wanted an LLM to help me read transcripts quickly, plus a tool to group and keep track of model runs. That's how the idea for this project started.
What it does
RLX-ray is a dashboard for agent run observability. You ingest RL runs from Hugging Face datasets or by triggering SWE-agent on Modal. SWE-agent is the standard harness for SWE-bench. Then each run gets analyzed by an LLM agent that segments the trajectory into sections (good / warning / failure) and summarizes what went wrong. You can search over massive transcripts with Elasticsearch, compare runs within a task with embedding-backed similarity, and see runs with similar failure modes so you don't have to read hundreds of traces by hand. The goal is to better understand how the agent interacts with the environment (where it gets stuck, what it tries, where it goes wrong) without reading every transcript yourself. How I built it Frontend: Next.js. It's a dashboard for displaying runs and sections; server-side rendering works well for that. Storage & search: Elasticsearch. I needed to store runs and search over massive transcripts; Elasticsearch made that tractable. Comparing runs: I wanted embeddings to compare runs within a task. I use Jina (via Elastic) for embeddings and keep everything in Elastic, so I went with Elastic Agent Builder for the trajectory-analyzer agent. It integrates cleanly with the same DB and lets the agent query via Elasticsearch instead of stuffing the whole transcript into context (transcripts can be near the context limit or larger with autocompaction). User-supplied runs: I ingest runs from Hugging Face, but the product only really works if users can run their own. So I use Modal's sandbox to run the SWE-agent harness on a SWE-bench task: the app triggers a Modal endpoint that runs SWE-agent and writes results back to Elasticsearch. Analysis design: I didn't want to dump the entire transcript into the model. I use Elasticsearch so the agent can query the run (e.g. by event type or step) and do sectioning without blowing context limits. Challenges I ran into Section splits: Getting the LLM to produce good section boundaries instead of splitting arbitrarily on errors was hard. I had to tune prompts and tooling so sections reflect meaningful phases (e.g. "got stuck here," "repeated attempt") rather than every failure. Grouping similar runs: With embeddings, runs that feel similar (e.g. "error + loop") should cluster together. But if the error text differs, embeddings put them in different buckets. I needed a pseudo re-ranking approach (not classic search re-ranking) to surface runs that are behaviorally similar even when the surface text differs. Modal + SWE-agent: SWE-agent was rough to wire up for a few reasons. It isn't a simple pip-and-run library: it expects a full repo layout (config/, tools/, trajectories/), so I had to build a Modal image that clones the repo and does an editable install, then runs the CLI. SWE-agent also uses Modal internally for code execution (via swe-rex), so I ended up with Modal-in-Modal: my orchestrator runs on Modal and the CLI spawns its own Modal sandboxes for each run. I hit API compatibility issues too: SWE-agent uses litellm, and some models (e.g. GPT-5, Claude) error on unsupported params like top_p, so I added a custom entrypoint that sets litellm.drop_params=True before invoking the real runner. On top of that, I had to discover and parse the trajectory output (.traj files), normalize "history" vs "trajectory" (schema varies by version), and write events plus run status back to Elasticsearch. Getting the whole chain reliable took a lot of iteration. Accomplishments that I'm proud of End-to-end pipeline: From raw runs (Hugging Face or live Modal) to searchable, sectioned trajectories and "similar runs" in one dashboard. LLM that queries instead of ingesting: The trajectory-analyzer agent uses Elasticsearch as its source of truth and queries by step/event type instead of stuffing full transcripts into context, so I can handle long runs without blowing context limits. Sectioning that surfaces mild failures: Sections don't just split on hard errors; they highlight "got stuck," "repeated attempt," and partial failures so you see where a run went off the rails, not just pass/fail. Custom similar-run grouping: I built a pseudo re-ranking approach so runs that are behaviorally similar (e.g. same failure mode) cluster together even when the literal error text differs, beyond off-the-shelf embedding similarity. Modal + SWE-agent integration: Getting the app → Modal → swe-rex sandbox chain working so users can launch and track SWE-agent runs from the UI. What I learned Formats: LLM trajectories are stored in many formats; normalizing and ingesting them is a real integration challenge. Elasticsearch: I learned Elasticsearch properly: indices, k-NN, and wiring an agent to query it instead of relying on raw context. Beyond re-ranking: I built a custom approach to group "similar" runs when standard embedding similarity wasn't enough (different error text, same failure mode). Product: Focus on value. The core value is analyzing trajectories: sections, similar runs, "where did it go wrong." The Modal "run SWE-agent from the UI" flow is cool but secondary; the dashboard and analysis are what actually help when reading hundreds of runs.
What's next
Environment versioning: Track versions of environments so you can compare runs across env changes and know exactly what code/config a run used. Custom RL environments: Let people upload their own RL environments (e.g. via Docker plus a standardized interface) and run tasks against them, instead of being limited to the tasks already in the system. More trajectory formats: Support additional agent/RL run formats so more teams can ingest their runs. Smarter similar-run logic: Improve the pseudo re-ranking so "same failure mode, different text" clusters even better. Built with TypeScript, React, Next.js, Python, Elasticsearch, Kibana, Elastic Agent Builder, Jina, Hugging Face, Modal, Vercel, SWE-agent, swe-rex, Tailwind CSS, uv Languages & frameworks TypeScript, React 19, Next.js 16 Python (workers, scripts) Infrastructure & data Elasticsearch (Elastic Cloud): store runs, events, sections; full-text and k-NN search Kibana / Elastic Agent Builder: trajectory-analyzer agent (converse API, tools, query over ES) Jina: section and run-summary embeddings (768-dim), similarity for "find similar runs/sections" Hugging Face: dataset ingestion for runs Modal: run SWE-agent in sandboxes (swe-rex); app triggers Modal endpoint, worker writes to Elasticsearch Vercel: host the Next.js app APIs & tooling Elasticsearch API, Kibana Agent Builder Converse API Jina Embeddings API SWE-agent / swe-rex (execution harness) Other Tailwind CSS, react-markdown uv (Python envs and scripts)
This is a Next.js project bootstrapped with create-next-app.
Environment (.env.local)
| Variable | Purpose |
|---|---|
ELASTICSEARCH_URL | Elasticsearch cluster for index/search (runs, events, sections). Example: https://….es.us-west1.gcp.elastic.cloud:443 |
ELASTICSEARCH_API_KEY | API key for Elasticsearch (and for Kibana Agent Builder API). |
KIBANA_URL | Kibana instance only used for the Agent Builder REST API (converse, tools, agents). Not used for dashboards or inference. Example: https://….kb.us-west1.gcp.elastic.cloud:443 |
ELASTIC_AGENT_CONNECTOR_ID | Optional. Connector ID for the LLM used by the trajectory-analyzer agent (converse API). If unset, Kibana uses its default connector (often set in Stack Management → Connectors or Agent Builder / GenAI settings). Set this to pin the run analyzer to a specific model. |
JINA_API_KEY | Required for run analysis. Section embeddings use Jina AI’s API (https://api.jina.ai/v1/embeddings). If missing, analysis fails with a clear error. Get a key at jina.ai. |
To list Kibana connectors (for ELASTIC_AGENT_CONNECTOR_ID): npx tsx scripts/list-connectors.ts
Getting Started
First, run the development server:
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
Open http://localhost:3000 with your browser to see the result.
You can start editing the page by modifying app/page.tsx. The page auto-updates as you edit the file.
This project uses next/font to automatically optimize and load Geist, a new font family for Vercel.
Learn More
To learn more about Next.js, take a look at the following resources:
- Next.js Documentation - learn about Next.js features and API.
- Learn Next.js - an interactive Next.js tutorial.
You can check out the Next.js GitHub repository - your feedback and contributions are welcome!
Deploy on Vercel
The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.
Check out our Next.js deployment documentation for more details.
Analysis
View
Metric
- 13
- 12
Figures cover GitHub contributors during the hackathon window. A co-authored commit counts in full for each author, so per-member totals add up to more than the whole-team figures.
Technology
- CSSIn code
- Next.jsIn code
- PythonIn code
- ReactIn code
- Tailwind CSSIn code
- TypeScriptIn code
- Hugging FaceClaimed
- VercelClaimed
6 of 8 appear in the indexed code. 2 claimed on Devpost could not be matched to code, which may simply mean the tool leaves no trace in the repository.
AI coding agents
- CursorConfig · Commits
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
201 KB
Source files
50
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
MittelmanDaniel/agent-observability
65 files · 888 KB · @ 5f4d081
Structure
Interface
9 files · 14%Screens, components and styles rendered to the user.
API & routing
7 files · 11%Request entry points: routes, handlers and controllers.
Application logic
7 files · 11%Domain rules, services and shared utilities.
Background jobs
6 files · 9%Work run outside a request: tasks, workers and schedules.
Supporting
Layers are inferred from where files sit in the tree, not from reading the code. A project that names its directories unconventionally will read oddly here — open the file browser to check anything the diagram implies.
Languages
- TypeScript73%
- Python15%
- Markdown12%
- CSS0%
Share of indexed source by file size. Binary and vendored files are excluded.
Dependencies
package.json
npm · 16- @elastic/elasticsearch
- @tailwindcss/typography
- dotenv
- next
- react
- react-dom
- react-markdown
- tsx
- +8 more
scripts/requirements.txt
pypi · 3- datasets
- huggingface_hub
- requests
Declared in the repository’s manifests at the indexed commit. A declared package is not proof it is used, and runtime dependencies are listed first.
This project’s features have not been analysed yet.
Export this project's context (description, README, evidence, key source files) to chat with an AI agent elsewhere.