Skip to Content

How do I track the prompts developers send in OpenHands?

Rius records the prompt and the answer on every model call of an OpenHands conversation, once you set three environment variables, with no plugin and no code changes. Each conversation is one trace, grouped as a session by its conversation id. Pass user_id when you create the conversation and each prompt is attributed to that developer on the Users page.

How it works

OpenHands’ Software Agent SDK traces every conversation with OpenTelemetry. When it finds the OTLP environment variables, it sends the spans to Rius, so there is nothing to install on the Rius side.

For prompts, this is what lands in Rius:

  • One trace per conversation. It contains the conversation, each agent.step, and the model and tool calls inside each step.
  • The prompt and the answer on every model call. The span for each model call (named litellm.completion) carries the model, the messages sent, the answer, and, where OpenHands reports them, tokens and cost.
  • What each step added. On a model call’s input, Since previous llm call shows only the messages that step added, such as the last tool result. A long conversation reads one step at a time instead of as one growing wall of text.
  • Tool calls next to the prompts. Each call (terminal, file_editor, finish) has its input and output, including a terminal command and its exit code.
  • The conversation id as the session, so a multi-turn conversation groups together.

OpenHands has no per-folder opt-in for content. Once the variables are set, prompts and output are sent with every traced conversation, which differs from the Rius plugin for Claude Code, where content leaves only from folders a developer enables. See Coding agents for the comparison, and Track Claude Code usage and cost across a team for how the plugin handles content.

Set it up

  1. Create a Rius API key. In the Rius console, open Settings → API keys and create a key with the Send telemetry scope. The key is shown once.

  2. Set the three environment variables in the process that runs OpenHands:

export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://ingest.eu.console.rius-glassflow.com/v1/traces export OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=http/protobuf export OTEL_EXPORTER_OTLP_TRACES_HEADERS="Authorization=Bearer%20ri_..."

Use http/protobuf, write out the full /v1/traces path, and write the space after Bearer as %20. Any LMNR_* variable takes precedence over these settings, so unset it. If one value is wrong, Rius never sees the spans and the agent runs on as if nothing happened.

  1. Pass user_id when you create the conversation, so each prompt belongs to a developer. Add agent.name to give the agent a readable name:
conversation = Conversation( agent=agent, workspace=".", user_id="dev@example.com", observability_metadata={"agent.name": "fib-writer"}, )
  1. For the local web app, put the same three values in OH_AGENT_SERVER_ENV on the app container, as a JSON object. Variables set directly on the app container never reach the agent. Web-app conversations show under the agent openhands-agent-server.

  2. Find the prompts. Open the trace list in the console, open a conversation, and select a litellm.completion span to read its prompt and answer. The conversation appears within a few seconds of the run.

The full OpenHands guide, OpenHands, has the complete script, the Enterprise setup and troubleshooting.

What you get

  • Every prompt in context. Read what the agent was asked, what it answered, and which tool call followed, in one waterfall.
  • Prompts per developer. With user_id set, the conversation shows under that developer on the Users page. Without it, conversations land in the anonymous row. With root-cause analysis on, an admin can click Summarise this user for a readable account of what that developer did with OpenHands over up to the last 7 days.
  • Questions from your own MCP client. Connected to the Rius MCP server, you can ask what a given developer ran in OpenHands yesterday, and the answer comes from the same spans.
  • Session grouping. A multi-turn conversation stays together under its conversation id.

What OpenHands does not report:

  • Tokens and cost for some calls. OpenAI Responses API models (GPT-4.1, GPT-5) and the web app’s streamed calls carry no token data. Web-app traces still have every prompt, answer and tool call, but no tokens or cost. Claude and GPT-4o in SDK scripts come through in full.
  • Failed commands as errors. A non-zero exit code is in the tool output, not the span status, so error-rate alerts do not count it.
  • OpenHands Cloud. It takes no custom environment variables, so it cannot send to Rius.

When something else fits

  • If prompts must leave a machine only from folders a developer approves, trace Claude Code with the Rius plugin instead. It sends content only from folders enabled for it.
  • If you only need cost and tool activity per developer and no prompt text, the Claude Code plugin’s structure-only mode sends the span tree, tokens, cost and tool names without prompts.

Still stuck? Get help

Last updated on