fix(broker): forward harness to relaycast backend (SDK 2.3.0)#1069
Conversation
Server-side telemetry on the relaycast backend recorded `harness: "unknown"` for 100% of events, even though the broker already detects the orchestrator harness (claude-code / codex / cursor / …) for its own PostHog events. The detected value was siloed in TelemetryClient and never forwarded to the relaycast SDK, so the `X-Relaycast-Harness` header (HTTP) and `?harness=` query (WS) were never sent and the backend defaulted to "unknown". Forwarding requires SDK >= 2.3.0 (`with_harness` was added in relaycast #161, published as 2.3.0). Bumping `=2.0.0` -> `=2.3.0` also pulls in the v8 event contract the gateway already emits, which is a net fix: the broker at 2.0.0 only recognized the pre-v8 `reaction.added` / `agent.online` event types, while the deployed gateway sends `message.reacted` / `agent.status.*` — so reactions and presence were being silently dropped. Changes: - Bump `relaycast` SDK `=2.0.0` -> `=2.3.0`. - Cache the detected harness in `telemetry::orchestrator_harness{,_opt}()` (process-tree detection walks parent PIDs; resolve once) and reuse it for both our PostHog events and the forwarded value. - Forward the harness at all three relaycast client sites: the WS handshake (`WsClientOptions::with_harness`) and both HTTP `build_relay_client` helpers (`RelayCastOptions::with_harness`). - Inject `AGENT_RELAY_HARNESS` into spawned-agent env via `spawn_env_vars` so JS-SDK agents (`@relaycast/sdk`, env-only harness resolution, no process-tree fallback) report it too. Threaded as a parameter for deterministic tests. - Update 3 stale bridge fixtures to the v8 event names the gateway emits (`message.reacted` with `action`, `agent.status.active`); fix `drops_reaction_without_channel` to exercise the no-channel drop rather than an unknown-type drop. Tests: 701 broker lib tests pass (+2 new harness env tests); clippy clean; fmt clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Your free trial PR review limit of 300 PRs has been reached. Please upgrade your plan to continue using CodeAnt AI. |
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
📝 WalkthroughWalkthroughRelaycast dependency upgraded to 2.3.0. Orchestrator harness is now detected once per process via cached telemetry functions and propagated through relay client configuration, agent environment variables, and telemetry initialization. Test fixtures updated for Relaycast 2.x presence and reaction event shapes. ChangesOrchestrator Harness Detection and Propagation
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 02dec50a9f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| &channels, | ||
| Some(&child_workspaces_json), | ||
| default_workspace_id.as_deref(), | ||
| crate::telemetry::orchestrator_harness_opt(), |
There was a problem hiding this comment.
Derive spawned agents' harness from their CLI
For spawn actions where the requested child CLI differs from the broker's parent harness (for example a Codex-driven broker spawning claude, or a broker launched from a service with no detectable parent spawning codex), this passes the broker's orchestrator harness or None into the child's environment. The JS SDK treats AGENT_RELAY_HARNESS as the spawned process's request harness, so those child Relaycast events are now misattributed to the parent or remain unknown even though params.cli identifies the actual child harness.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/broker/src/telemetry.rs`:
- Around line 440-457: The detector currently cached by orchestrator_harness()
doesn't consider the AGENT_RELAY_HARNESS environment override, so
orchestrator_harness_opt() can drop a valid explicit value; update the detection
path (the detect_orchestrator_harness function called by orchestrator_harness())
to check for AGENT_RELAY_HARNESS first (like any other explicit env override)
and return that value when present so the cached String includes the override
and orchestrator_harness_opt() will preserve it.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: f8f9796e-f7ab-40b6-8ccd-da0d5f77ed0b
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (7)
crates/broker/Cargo.tomlcrates/broker/src/relaycast/auth.rscrates/broker/src/relaycast/bridge.rscrates/broker/src/relaycast/ws.rscrates/broker/src/spawner.rscrates/broker/src/telemetry.rscrates/broker/src/wrap.rs
| /// Process-wide cached orchestrator harness: explicit env override, else | ||
| /// process-tree detection (claude-code / codex / cursor / …). Detection walks | ||
| /// the parent-process chain, so we resolve it once and reuse the result for | ||
| /// both our own PostHog events and the harness we forward to the relaycast | ||
| /// backend. Returns the [`UNKNOWN_ORCHESTRATOR_HARNESS`] sentinel when | ||
| /// undetectable. | ||
| pub(crate) fn orchestrator_harness() -> &'static str { | ||
| static CACHE: std::sync::OnceLock<String> = std::sync::OnceLock::new(); | ||
| CACHE.get_or_init(detect_orchestrator_harness) | ||
| } | ||
|
|
||
| /// Like [`orchestrator_harness`] but `None` instead of the `"unknown"` | ||
| /// sentinel, so callers can skip forwarding a non-informative value (the | ||
| /// relaycast backend already defaults a missing harness to `"unknown"`). | ||
| pub(crate) fn orchestrator_harness_opt() -> Option<&'static str> { | ||
| let harness = orchestrator_harness(); | ||
| (harness != UNKNOWN_ORCHESTRATOR_HARNESS).then_some(harness) | ||
| } |
There was a problem hiding this comment.
Include AGENT_RELAY_HARNESS in broker-side harness detection.
orchestrator_harness_opt() now drives relaycast forwarding, but the detector path it wraps does not check AGENT_RELAY_HARNESS. If that key is the only explicit override, Line 455 resolves to inferred/"unknown" and drops the intended value.
Suggested patch
fn detect_orchestrator_harness() -> String {
for key in [
+ "AGENT_RELAY_HARNESS",
ORCHESTRATOR_HARNESS_ENV,
"RELAYCAST_HARNESS",
"X_RELAYCAST_HARNESS",
] {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/broker/src/telemetry.rs` around lines 440 - 457, The detector
currently cached by orchestrator_harness() doesn't consider the
AGENT_RELAY_HARNESS environment override, so orchestrator_harness_opt() can drop
a valid explicit value; update the detection path (the
detect_orchestrator_harness function called by orchestrator_harness()) to check
for AGENT_RELAY_HARNESS first (like any other explicit env override) and return
that value when present so the cached String includes the override and
orchestrator_harness_opt() will preserve it.
Problem
Server-side telemetry on the relaycast backend (PostHog project 296966) records
harness: "unknown"for 100% ofrelaycast_server_*events — verified live. The broker already detects the orchestrator harness (claude-code / codex / cursor / …) for its own PostHog events, but that value was siloed inTelemetryClientand never forwarded to the relaycast SDK. The engine reads the harness from theX-Relaycast-Harnessheader (HTTP) or?harness=query (WS) and defaults to"unknown"when absent — and the broker never sent either.The origin fields (
@relaycast/sdk-rust, version) arrive because the SDK sendsX-Relaycast-Origin-*unconditionally; the harness is conditional onwith_harness()being called, which the broker never did.Why the SDK bump
with_harness()was added in relaycast #161 and is only in published SDK ≥ 2.3.0. The broker pinned=2.0.0. Bumping=2.0.0 → =2.3.0also pulls in the v8 event contract the gateway already emits — which is a net fix, not just a tax: at 2.0.0 the broker only recognized the pre-v8reaction.added/agent.onlinetypes, while the deployed gateway sendsmessage.reacted/agent.status.*. So reactions and presence were being silently dropped by the broker. Confirmed against the engine's emit sites (routes/reaction.js→message.reacted, presence adapter →agent.status.active/offline).Changes
relaycastSDK=2.0.0 → =2.3.0.telemetry::orchestrator_harness{,_opt}()(process-tree detection walks parent PIDs — resolve once) and reuse it for both our PostHog events and the forwarded value.WsClientOptions::with_harness→?harness=) and both HTTPbuild_relay_clienthelpers (RelayCastOptions::with_harness→X-Relaycast-Harness).AGENT_RELAY_HARNESSinto spawned-agent env viaspawn_env_vars, so JS-SDK agents (@relaycast/sdkresolves harness from env with no process-tree fallback) report it too. Threaded as a parameter for deterministic unit tests.message.reacted+action,agent.status.active), and fixdrops_reaction_without_channelto exercise the no-channel drop rather than a now-unknown event type.Coverage by client
@relaycast/sdk-rust(Rust broker)with_harness()on WS + 2× HTTP client builders@relaycast/sdk(JS spawned agents)AGENT_RELAY_HARNESSinjected into spawn envTests
spawn_env_vars_forwards_harness_when_present/_omits_harness_when_absent).cargo clippyclean;cargo fmt --checkclean.Rollout
Takes effect once a broker release ships and users upgrade. After that, re-querying project 296966 should show
claude-code/codex/ etc. instead ofunknown.🤖 Generated with Claude Code