Skip to main content
The Try HALO with a Demo Repo guide runs this same loop against the hosted Catalyst dashboard. This one does the whole thing on your machine with the free, open-source HALO desktop app. Traces live in a local SQLite database, HALO runs against a model provider you configure, and nothing leaves your laptop. No Inference account required. You will install the app, load a bundled demo dataset of about 1,000 real agent runs with one click, explore the traces in the local viewer, run HALO over them, and open the resulting report directly in a coding agent to apply the fixes. The traces come from a search agent with deliberate, documented flaws, so HALO has something real to find.
Desktop or hosted? The desktop app is the best way to try HALO end to end for free and keep your traces fully local. For continuous production observability across a team (always-on ingest, multiple users, scheduled HALO runs, Signals, and alerts), the hosted version is the better fit. You can start local and move to hosted later without changing your instrumentation; it is the same Catalyst tracing under the hood. See Self-hosting and production.

Before you start

You need:
  • The HALO desktop app (installed in Step 1). HALO v1 ships for Apple Silicon Macs and Ubuntu/Debian Linux (x64). Intel Macs, other Linux distributions, and Windows are not supported yet.
  • A model provider key for running HALO. The desktop app supports OpenAI-compatible and Anthropic-compatible endpoints (OpenAI, Anthropic, OpenRouter, Inference, or your own endpoint), and you bring your own key. The app stores it locally and it never leaves your machine.
  • A coding agent for the last step: Claude Code, Cursor, or Codex. The report opens in any of them with one click, and there is a copy-paste path for everything else.
What “no account” means. The desktop app, the local trace timeline, and the HALO engine all run with no Inference account and no sign-in. The one thing that always needs a key is a model provider, because HALO calls an LLM to do the analysis. That key can be any provider you already have.

Step 1: Install the desktop app

Install with the one-line installer:
curl -fsSL https://inference.net/halo/install.sh | sh
The installer detects your platform and downloads the matching release: a signed, notarized DMG on Apple Silicon macOS, or a -Setup.tar.gz on Ubuntu/Debian x64. You can also grab a build directly from the releases page.
HALO v1 supports Apple Silicon Macs and Ubuntu/Debian Linux (x64) only. The installer stops with a clear message on Intel Macs, other Linux distributions, and Windows. On a clean Ubuntu/Debian box you may also need a few system libraries first: sudo apt-get install -y libgtk-3-0 libwebkit2gtk-4.1-0 libayatana-appindicator3-1.

Step 2: Load the demo traces

Launch the app. After a short welcome, onboarding lands on the Import Demo Traces screen. This is the front door for getting data into HALO: import history from Langfuse or Phoenix, upload a JSONL trace export, connect a local agent, or load a demo dataset.
The Import Agent Traces onboarding screen with cards for Import from Langfuse, Import from Phoenix, Import JSONL File, Connect Local Agent, Load Demo Traces, and Read Documentation
For this guide, click Load Demo Traces. The dialog explains exactly what it does: HALO downloads an allowlisted JSONL export from the public inference-net/SearchAgentDemoTraces dataset on Hugging Face, caches it beside your local app data, and queues the normal JSONL importer. No arbitrary remote URLs are accepted.
The Load Demo Traces dialog showing the SearchAgentDemoTraces Hugging Face dataset, with Source, Cache, and Import cards and a Load Traces button
Click Load Traces. The dataset is about 1,000 real runs of a pre-instrumented web-search agent (more on it in Step 5), and the import usually finishes in under a minute. You can watch it complete on the Imports page, which tracks everything you have ever brought into HALO:
The Imports page showing a completed file import of 1,005 traces and 16,174 observations
You can come back to this screen anytime. The Import Data button in the top right of the Data and Imports pages reopens the same import options, and Settings → Replay onboarding restarts the whole flow.

Step 3: Add a model provider

HALO analysis runs against a model you choose, with your own key. Open Settings and click Add Provider under Model providers.
The Settings page showing the Model providers section with an Add Provider button, Data Management with database details, and the HALO Configuration section with the engine installed
Pick a provider type, which prefills the base URL, then paste your API key:
  • OpenAI sets https://api.openai.com/v1.
  • Anthropic sets https://api.anthropic.com/v1.
  • Custom OpenAI-compatible lets you point at OpenRouter, Inference (https://api.inference.net/v1), or any other compatible endpoint.
The Add provider dialog with a provider type selector, name, base URL, and API key fields
The key is stored locally in SQLite, masked in the UI, and never leaves the machine. While you are in Settings, check the HALO Configuration section at the bottom. HALO runs as a local Python engine; this section shows its install status and runtime checks (git, uv, Python 3.12).

Step 4: Find your way around

The app has four main pages, all in the left sidebar:
  • Data is the trace timeline: every trace and session in your local workspace, with search, filters, and summary stats.
  • Analysis is where HALO runs live: start new runs, watch them stream, and revisit every completed report.
  • Imports tracks trace history brought in from other tools, with per-import status and counts.
  • Settings holds model providers, the local database details, and the HALO engine install.
Open Data. The stats bar across the top summarizes the workspace (traces, spans, LLM spans, errors, tokens, cost), and each row is one run with its input, output, and duration. Failed runs are tinted red, so problems jump out while scrolling. The left rail filters by time window, status, source, service, agent, and model, and the Traces / Sessions toggle switches between individual runs and grouped sessions.
The Data page showing about 1,000 imported traces with filters on the left, summary stats across the top, and failed runs highlighted in red
Imported traces keep their original timestamps, not the time you imported them. Set the time window to All time so the demo dataset shows up, and do the same when you configure the HALO run in Step 6.

Step 5: Open a trace

The demo traces all come from one agent, Traceable Search Agent: a compact web-search agent that plans in a scratchpad, searches the web through Tavily, extracts pages, scores sources, and writes a final answer. It ships with deliberate, documented flaws (a heuristic source-quality score, an unstructured scratchpad, no enforced answer schema), which is exactly what makes this dataset a good HALO sandbox. The code lives in context-labs/SearchAgentDemo (Python) and context-labs/SearchAgentDemoTS (TypeScript); you will clone one in Step 7. Click any row on the Data page to open the trace viewer. The Timeline view is a waterfall of every span in the run: the agent loop at the top, then each LLM call, tool call, and retriever call laid out against the clock. It makes the shape of a run obvious at a glance, including what ran serially that could have been parallel, and where the time actually went. Use the Cost heatmap toggle to shade spans by spend, and zoom with the controls or by double-clicking a span.
The Timeline view of a single trace, showing a waterfall of OpenAI Chat Completions calls, web search tool calls, and nested tavily.search retriever spans across an 8 second run
Switch to the Conversation view to read the same run as a thread: the user’s question, the agent’s answer, and an expandable list of every span in between. Click any span to inspect it in the side panel, with the full input and output, model, duration, and cost. Open the first LLM span and you can read the agent’s entire system prompt, including its operating loop and its known rough edges.
The Conversation view of a trace with the span list expanded and a side panel showing an LLM span's system prompt, model, and timing details
Skim a handful of runs, especially the red ones. You will spot failed searches and retry loops by eye. That is the point of the next step: HALO reads all 1,000 runs and finds the patterns for you.

Step 6: Run HALO

Click Run Analysis in the top right of the Data page (or start from the Analysis page). The dialog is where you scope the run:
  • Session group or Trace group picks the unit of analysis.
  • The filters (search, window, status, source, service, agent, observed model, scope) narrow which telemetry HALO reads. For the demo dataset, set the window to All time and leave the rest open. The live counts at the bottom confirm what the run will cover, about 1,000 traces here.
  • Provider and model select the provider you saved in Step 3 and which of its models does the analysis.
  • Title and prompt name the run and tell HALO what to look for.
The Run Analysis dialog with Session group and Trace group tabs, telemetry filters, live counts showing 1,000 traces, and provider and model selectors
A specific prompt gives sharper results. This run used:
Analyze these traces. Identify the most important failures, latency bottlenecks,
confusing tool behavior, and concrete improvements for the developer.
Click Start run. The run moves through Queued → Export → Analysis → Done, and you can watch every agent step stream in as the engine digs through the traces. The right rail tracks the run details: target, provider, model, and the trace, session, and span counts as they are exported.
A HALO run just after starting, showing the analysis prompt, the Queued, Export, Analysis, Done status pipeline, and run details in the right rail
Expect several minutes for a dataset this size; this run covered 1,000 traces and 16,000+ spans in about nine minutes. When it finishes, the report renders in place: ranked findings with citations back to the exact traces each one came from. Click a citation chip to drop into that trace and confirm the finding before you act on it.
A completed HALO report showing ranked findings with trace citations, section chips for failures and latency bottlenecks, and an Act on this report panel in the right rail
On this dataset, HALO’s top findings included:
  • A deterministic tool-argument failure. The model passes topic="health" or topic="sports" to the Tavily search tool, which only accepts general, news, or finance, so those searches fail every single time. The fix is to encode the constraint as an enum in the tool schema.
  • Error-prone search and extraction that triggers rework loops. Failed searches and extractions send the agent back through extra LLM deliberation and retries, burning latency and tokens.
  • Latency dominated by sequential LLM calls. The slowest runs stack around six back-to-back chat completions plus serial searches that could run concurrently.
  • Confusing telemetry. The tool wrapper span and the underlying provider span both report ERROR for the same root cause, and the wrapper span is missing its real inputs, which makes debugging and error counts misleading.
The report closes with a prioritized action plan, ordered by return on effort:
The developer-focused action plan from the HALO report, listing five fixes ranked by ROI, from Tavily topic correctness through cleaning up tracing semantics
The chat box under the report asks follow-up questions by re-running HALO over the same traces with full context. Use it to drill into a finding (“show me more traces with the topic failure”) without configuring a new run.

Step 7: Hand the report to a coding agent

The report is a ranked, cited to-do list for the agent’s codebase, and the desktop app hands it off directly. The Act on this report panel next to every completed run has one-click buttons for Open in Cursor, Open in Claude Code, and Open in Codex, plus Copy prompt for any other tool. No MCP server, no wiring.
The Act on this report panel with Open in Cursor, Open in Claude Code, and Open in Codex buttons and a Copy prompt option
The demo traces came from the search agent repo, so that is where the fixes belong. Clone it first, in whichever language you prefer (the two flavors have the same tools, the same deliberate flaws, and produce the same findings):
git clone https://github.com/context-labs/SearchAgentDemo.git
cd SearchAgentDemo
git clone https://github.com/context-labs/SearchAgentDemoTS.git
cd SearchAgentDemoTS
Then click the button for your coding agent and run it from the cloned repo. Every run saves its full report to disk (the paths are listed under Artifacts in the run details), and the handoff prompt points the coding agent at that file with instructions along the lines of:
Read the HALO trace-analysis report at
~/Library/Application Support/net.inference.halo/halo-runs/<run-id>/report.md
and act on its findings in this codebase: fix the identified failures and
implement the recommended improvements.
For this dataset, the fixes land in the tool schemas (tools.py / tools.ts), the agent loop (agent.py / agent.ts), and the tracing setup. The report’s citations mean the coding agent is not guessing: every recommendation traces back to specific runs you can open in the viewer.

Step 8: Close the loop

A fix is not done until new traces from the changed code confirm it. This is where the desktop app’s live mode comes in: the same agent repo can stream traces straight into your local timeline while it runs, with nothing crossing the network beyond the agent’s own model calls.
  1. In the app, open Import Data → Connect Local Agent. It shows the local ingest endpoint. Copy the repo’s env file and point the agent at it:
    cp .env.example .env
    
    # .env
    INFERENCE_API_KEY=sk-...                                # powers the agent's model calls
    CATALYST_OTLP_ENDPOINT=http://127.0.0.1:8799/v1/traces  # send traces to the desktop app, not the cloud
    
    INFERENCE_API_KEY is what the agent uses to call its model; point it at any provider by also setting INFERENCE_BASE_URL (it defaults to Inference’s OpenAI-compatible endpoint). The CATALYST_OTLP_ENDPOINT override is the whole trick: instead of shipping spans to the cloud, the agent posts them to the desktop app listening on 127.0.0.1:8799.
  2. Run a batch from the repo’s bundled query dataset against your patched code. The query set is fixed, so the only variable between before and after is your fix:
    uv run search-agent-batch --limit 5
    
    bun run search-agent-batch --limit 5
    
    Watch the traces land in the Data page as each run finishes.
  3. Run HALO again, scoped to the new traces (a recent time window or the new session IDs), and compare the two reports. The findings you fixed should be gone or diminished; pick up the next one.
That is the whole HALO loop, start to finish, running entirely on your machine. Once it clicks here, point the same loop at your own agent.

Bring your own traces

You do not have to use the demo dataset. The same Import Agent Traces options from Step 2 work on your real data, which makes the desktop app a low-commitment way to try HALO on the agent you actually run:
  • Import from Langfuse. Paste a Langfuse project’s API URL and key pair (public and secret). HALO pulls your trace history over the Langfuse public API and stores it locally. If you would rather keep your existing pipeline and try HALO without importing, you can instead point the Langfuse SDK at Catalyst with an env-var switch.
  • Import from Phoenix. Bring historical traces from an Arize Phoenix project into the local timeline the same way.
  • Import JSONL. Any JSONL trace export with one span per line works, including OpenTelemetry and Catalyst exports.
  • Connect Local Agent. Stream traces live from any Catalyst- or OpenTelemetry-instrumented agent by pointing its OTLP endpoint at http://127.0.0.1:8799/v1/traces, as in Step 8.
HALO groups and analyzes traces by agent identity. For the sharpest reports from imported data, make sure your top-level spans carry a stable agent.name (and ideally agent.id). For Langfuse specifically, see Group by agent.

Self-hosting and production

A common question: can you run this in production? Two answers, depending on what you mean.
  • The desktop app is a single-user, local-first tool. It is ideal for exploring, debugging, and iterating on an agent on your own machine. It is not designed to be a shared, always-on production service.
  • The HALO engine is open source and MIT licensed (context-labs/halo, halo-engine on PyPI). You can self-host it: install the CLI, point it at exported traces, and run it anywhere, including in CI against a fresh trace export on every deploy. That is the self-hosted production path for the analysis step itself.
For continuous, team-scale observability (always-on trace ingest, multiple users, scheduled HALO runs, Signals, and alerting), the hosted Catalyst platform is the path we recommend. The instrumentation is identical, so anything you build locally moves over by changing where traces are sent.

Where to go next

Try the hosted version

The same loop on the hosted Catalyst dashboard, with scheduled runs, Signals, and the MCP server.

Do this on your own agent

Run the trace, analyze, fix loop against your real app from instrumentation onward.

Bring your Langfuse traces

Point the Langfuse SDK at Catalyst with an env-var switch, no code changes.

HALO on GitHub

The open-source HALO desktop app, engine, and methodology. MIT licensed.