Tutorial: Connect Litefuse
Send session-derived traces from Orca Agent Engine to Litefuse through OTLP HTTP/JSON.
Litefuse accepts traces through a Langfuse-compatible OTLP interface. Configure an export binding in the registry, then create a session to pin that binding. You do not install a Langfuse SDK in your agent or supply Litefuse credentials to the harness.
This walkthrough uses a dedicated Workspace custom binding and metadata-only capture. It does not create a Litefuse project or change deployment-wide capture policy.
Before you begin
- Run an exporter with Kafka Transcript access and Registry internal authentication. For a self-hosted deployment, follow deploy the exporter.
- Prepare a dedicated Litefuse project with an externally reachable public HTTPS endpoint.
- Select a test Workspace without an existing custom binding. Have an organization admin key with
observability:readandobservability:write, ororg:admin. - Have a runnable agent and environment in that same Workspace.
- Install
curl,jq, anduuidgen; examples use Bash.
Export these variables from your credential manager or shell setup. Do not put real keys in source control or enable shell tracing while running the commands.
| Variable | Value |
|---|---|
ORCA_ADMIN_URL | Admin listener origin, without a path suffix |
ORCA_ORG_ADMIN_KEY | Organization admin API key |
WORKSPACE_ID | ID of the test Workspace belonging to that organization |
LITEFUSE_BASE_URL | Litefuse public HTTPS origin, without a trailing slash or path |
LITEFUSE_PROJECT_ID | Identity of the dedicated project |
LITEFUSE_PUBLIC_KEY, LITEFUSE_SECRET_KEY | Keys for that same project |
ORCA_REGISTRY_URL | Public registry origin for that Workspace |
ORCA_API_KEY | Public Workspace API key, sent as x-api-key |
AGENT_ID, ENVIRONMENT_ID | Existing runnable agent and environment IDs in that Workspace |
Admin endpoint
These operations use the registry admin listener, not the public Workspace API. Set
ORCA_ADMIN_URL to its origin without a path suffix. Organization operations use
ORCA_ORG_ADMIN_KEY; platform policy operations use a separate ORCA_PLATFORM_KEY. Both examples
send x-api-key. Never use a Workspace key or an exporter workload token here. See
observability administration for OIDC and scopes.
Read the current Workspace state
Keep the opaque ETag exactly as returned, including quotes. Workspace PUT always requires it.
headers=$(mktemp)
state=$(curl -fsS -D "$headers" \
"$ORCA_ADMIN_URL/v1/organizations/workspaces/$WORKSPACE_ID/agent_observability" \
-H "x-api-key: $ORCA_ORG_ADMIN_KEY")
WORKSPACE_ETAG=$(awk 'tolower($1) == "etag:" { sub(/\r$/, "", $2); print $2 }' "$headers")
rm -f "$headers"
jq '{configured, effective}' <<< "$state"If configured.mode is already custom, use a different test Workspace or follow the
replacement rules. The next
example is a new binding creation; a same-active-target replacement must omit credentials.
Create the Litefuse binding
Use semantic_profile: langfuse for Litefuse. Credentials bind ingestion to a project; setting
external_project_id is not a substitute for matching project keys.
IDEMPOTENCY_KEY=$(uuidgen)
binding=$(jq -n '{
mode: "custom",
capture_ceiling: "metadata_only",
target: {
adapter_type: "otlp_http",
endpoint_kind: "traces_endpoint",
endpoint_class: "public",
endpoint_url: (env.LITEFUSE_BASE_URL + "/api/public/otel/v1/traces"),
external_project_id: env.LITEFUSE_PROJECT_ID
},
config: {
semantic_profile: "langfuse",
protocol: "http/json",
compression: "none",
timeout_ms: 10000,
sample_rate: 1,
capture_mode: "metadata_only",
environment: "test",
release: "litefuse-check"
},
credentials: {
type: "basic",
username: env.LITEFUSE_PUBLIC_KEY,
password: env.LITEFUSE_SECRET_KEY
}
}' | curl -fsS -X PUT \
"$ORCA_ADMIN_URL/v1/organizations/workspaces/$WORKSPACE_ID/agent_observability" \
-H "x-api-key: $ORCA_ORG_ADMIN_KEY" \
-H "Content-Type: application/json" \
-H "If-Match: $WORKSPACE_ETAG" \
-H "Idempotency-Key: $IDEMPOTENCY_KEY" --data-binary @-)
BINDING_ID=$(jq -r '.configured.binding.id' <<< "$binding")
jq '{scope, configured, effective}' <<< "$binding"A newly created custom binding returns 201. Confirm effective.source is workspace_custom,
effective.status is enabled, and effective.capture_mode is metadata_only. The response
contains no key material. A successful PUT does not contact Litefuse or prove delivery.
For a retry of this request, retain the original body, ETag, and idempotency key. For a new mutation, read a fresh ETag and create a new key.
Run a new session
Switch to the public registry endpoint and Workspace credential. Session creation pins the current export selection; do not reuse a session created before the binding.
session=$(jq -n --arg agent "$AGENT_ID" --arg environment "$ENVIRONMENT_ID" '{
agent: $agent, environment_id: $environment, title: "Litefuse export check"
}' | curl -fsS "$ORCA_REGISTRY_URL/v1/sessions" \
-H "x-api-key: $ORCA_API_KEY" \
-H "Content-Type: application/json" --data-binary @-)
SESSION_ID=$(jq -r '.id' <<< "$session")
curl -fsS "$ORCA_REGISTRY_URL/v1/sessions/$SESSION_ID/events" \
-H "x-api-key: $ORCA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"events":[{"type":"user.message","content":[{"type":"text","text":"Reply with the word ready."}]}]}'Use the event stream or event list to confirm the message was processed and the turn completed. Allow time for asynchronous delivery and backend indexing, then open the dedicated Litefuse project.
Verify:
- The session grouping is
$WORKSPACE_ID:$SESSION_ID; the trace has anagentroot. - Metadata identifies the Workspace/session and, for newly attributed contexts, the binding
$BINDING_ID, agent revision,testenvironment, andlitefuse-checkrelease. - Tool/evaluator observations appear only if the run produced corresponding events.
- Input/output are absent: that is expected in metadata-only mode. Model summaries are
spanobservations, not synthetic provider generations.
To include content, follow enable raw capture explicitly. After all applicable ceilings and the binding permit raw capture, run another new session with synthetic data. Check root/tool I/O and omission markers rather than assuming a complete transcript.
Troubleshoot missing traces
| Symptom | Check |
|---|---|
| PUT succeeds, but no trace appears | Exporter is running; effective state is enabled; the exact supported target/profile/protocol combination is selected. |
| Newly configured project stays empty | Create a new session. Existing pins, including terminal suppression, do not adopt the new selection. Check that the keys belong to this project. |
| Session exists, but no turn trace | A message must be accepted and a turn must complete. Check public events and sampling; sample_rate: 0 exports nothing. |
| Exporter is Ready, but ingestion fails | Readiness checks Kafka/runtime availability, not binding validity or remote ingest. Inspect safe delivery diagnostics and backend availability. |
| Endpoint rejected | Public HTTPS and the exact traces path are required. Check DNS: a public hostname resolving to a private/fake-IP range is rejected. Do not bypass egress validation. |
401 or 403 from ingestion | Check project keys; use the credential-rotation API. The exporter refreshes credentials once before treating repeated rejection as terminal. |
| Trace has no input/output | Confirm every capture ceiling, a new raw-authorized session, and Kafka state mode. Legacy Postgres is metadata-only. Check size/omission markers. |
| A trace is delivered again | At-least-once HTTP delivery can resend deterministic trace IDs after failure; it is not a new session. |
Stop the test export
Read a fresh Workspace ETag, then PUT {"mode":"disabled","capture_ceiling":"metadata_only"}
with a new idempotency key. See disable a Workspace.
Disabling the organization default does not stop a Workspace custom binding. Export disable does not
delete already stored content or Litefuse traces.