feat(routing): auto-detect dario at startup, drop the manual env-var dance#26
Merged
Conversation
This was referenced Apr 29, 2026
…dance When ANTHROPIC_BASE_URL isn't already set, probe localhost:3456/health at the start of `hands run`. If dario responds within 2s, set ANTHROPIC_BASE_URL so the Anthropic SDK routes through dario for OAuth subscription billing. Operator override always wins: ANTHROPIC_BASE_URL set in env or via shell skips the probe; --no-dario flag opts out explicitly even when dario is reachable. Why: today's E2E verification proved hands SDK mode + dario gives subscription billing instead of per-token API key cost (Discussion #172 + dario PR #174). Friction was the only remaining barrier — users had to remember `export ANTHROPIC_BASE_URL=http://localhost:3456` before every run. This makes the subscription path automatic when dario is up, falls through silently to api.anthropic.com when it's not. Probe details: - Default target: http://localhost:3456 (dario's canonical port). - HANDS_DARIO_URL env var overrides the target for non-default ports. - Hits dario's /health endpoint (already used by hands doctor — same shape, decoupled by route from any auth-bearing path). - 2s timeout — dario's first /health on a cold proxy was observed at ~840ms (account pool + template state checks); subsequent hits are much faster, but each `hands run` invocation runs the probe once so we budget for the cold path. Hands startup already takes a few seconds for screenshot + config, so 2s here is not the dominant latency. - Network errors / non-OK responses fall through silently — the common "no dario running" case is normal, no warn/error noise. Test coverage: test/dario-detect.test.mjs — 7 unit tests covering operator-override (env var pre-set), explicit disable (--no-dario), successful probe, non-OK response, network error fall-through, HANDS_DARIO_URL override, trailing-slash trimming. Live verified end-to-end against a running dario instance: info line "auto-detected dario at http://localhost:3456 — routing through it for subscription billing" prints, request reaches dario, billing routes to five_hour.
7db3532 to
4046633
Compare
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When `ANTHROPIC_BASE_URL` isn't already set, probe `localhost:3456/health` at the start of `hands run`. If dario responds, set `ANTHROPIC_BASE_URL` so the Anthropic SDK routes through it for OAuth subscription billing. Operator override always wins: env-pre-set or `--no-dario` skip the probe.
Why
Today's E2E verification (dario #172 + dario #174) proved hands SDK mode + dario gives OAuth subscription billing instead of per-token API key cost. Friction was the only barrier left — users had to remember `export ANTHROPIC_BASE_URL=http://localhost:3456\` before every `hands run`. This makes the subscription path automatic when dario is up; silent fall-through to `api.anthropic.com` when it isn't.
Behavior
Probe target: dario's `/health` endpoint (already used by `hands doctor` — same shape, decoupled by route from any auth-bearing path). 2s timeout — dario's first `/health` on a cold proxy was observed at ~840ms (account pool + template state checks); subsequent hits much faster, but each `hands run` invocation runs the probe once so we budget for cold-path.
Test plan
Notes