Agent Observability
How to see what the app and the agent did: E2E artifacts, the inference capture proxy, and Langfuse traces.
This page covers three ways to see what OpenHuman did. E2E artifacts let a coding agent (Codex, Claude Code, Cursor) inspect the desktop app through the WDIO harness (see E2E testing). The capture proxy shows what the core sent to inference. Langfuse traces cover real agent runs.
The E2E layer is narrow on purpose. It covers one onboarding and privacy flow and saves screenshots, page-source dumps and mock backend request logs to disk.
Quick start
bash app/scripts/e2e-agent-review.shArtifacts land under:
app/test/e2e/artifacts/<ISO-timestamp>-agent-review/
01-welcome.png
01-welcome.source.xml
02-post-welcome.png
02-post-welcome.source.xml
03-post-onboarding.png
03-post-onboarding.source.xml
04-privacy-panel.png
04-privacy-panel.source.xml
mock-requests-after-welcome.json
mock-requests-after-onboarding.json
mock-requests-after-privacy.json
failure-<test>.png # only on failure
failure-<test>.source.xml # only on failure
meta.json # run metadata + checkpoint indexThe script prints the resolved artifact directory at the end.
Pieces
Helper
app/test/e2e/helpers/artifacts.ts
Run dir, captureCheckpoint, captureFailureArtifacts, saveMockRequestLog
WDIO hook
app/test/wdio.conf.ts (afterTest)
Always dumps screenshot + source on any failing test
Canonical spec
app/test/e2e/specs/agent-review.spec.ts
Welcome, onboarding, then the privacy panel, with named checkpoints
Wrapper script
app/scripts/e2e-agent-review.sh
Build + run + print artifact dir
Stable selectors
data-testid on OnboardingNextButton, Onboarding overlay + skip button, WelcomeStep, PrivacyPanel
Agent-reliable navigation anchors
Environment overrides
E2E_ARTIFACT_DIR
Force a specific run dir (skips auto-timestamped name)
E2E_ARTIFACT_ROOT
Parent dir for auto-generated run dirs (default: app/test/e2e/artifacts)
E2E_ARTIFACT_LABEL
Label used in the auto-generated run dir name (default: run; wrapper sets agent-review)
Using the helper from new specs
captureCheckpoint numbers captures so the run dir reads chronologically. captureFailureArtifacts is wired into wdio.conf.ts and fires automatically on any failing test. Specs should not call it directly.
Inference on the wire: the capture proxy
Logs tell you a turn was slow. They do not tell you what the harness sent or which endpoint answered. scripts/debug/capture-first-inference.mjs (pnpm debug capture) is a loopback proxy between the core and its inference backend that records both sides:
Every inference request body is written, numbered, under target/debug-logs/inference-sequence/ (the exact system prompt, tool schemas and prompt_cache_key the harness assembled), and every response yields one summary line and one JSONL record in target/debug-logs/inference-capture.jsonl:
CAPTURE_UPSTREAM=https://openrouter.ai captures a direct BYOK OpenRouter route instead of the hosted backend. Non-2xx response bodies are saved next to the request dumps so an HTML 503 from an ingress is not lost behind a generic "model error".
Across the turns of one thread, check three things. cache_key must stay identical, because it is the harness's stable-prefix fingerprint and OpenRouter's sticky-routing key. served_by should not change. cached should approach prompt from the second call on. A drift in any of them has been a real bug.
The proxy binds loopback only. It refuses a plaintext non-loopback upstream unless you override that, because it forwards the bearer token verbatim. --help lists every CAPTURE_* option.
Production agent traces
Everything above is about local artifacts. For a real agent run, the core can export trace spans to Langfuse instead: when observability.share_usage_data is on (the default), a completed run's spans go to the OpenHuman backend's Langfuse ingestion proxy over the same session bearer every other backend call uses, and the backend forwards them to Langfuse with the project keys injected server-side. Clients never hold Langfuse credentials directly. Prompt and reply text ride along only while observability.agent_tracing.capture_content is also on; turning it off keeps metadata (names, timings, token and cost figures) but drops content. See crates/openhuman-core/src/agent/progress_tracing/langfuse.rs and crates/openhuman-core/src/config/schema/observability.rs.
Out of scope for the E2E layer
Visual baselines and image diffs across every component state.
Screenshot capture on every click (too noisy).
Live integrations (Gmail, Notion, Telegram); mock server only.
A new test framework or reporter.
Add more flows only after this loop proves itself.
Last updated