Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
c17a756
fix(proxy): keep discovery disabled path compatible
Brisbanehuang Jul 20, 2026
856a44e
feat(settings): configure bounded streaming discovery
Brisbanehuang Jul 20, 2026
722900e
fix(proxy): close discovery coordinator lifecycle gaps
Brisbanehuang Jul 20, 2026
3edd52b
fix(proxy): guard optional discovery request message
Brisbanehuang Jul 20, 2026
fcaf248
fix(proxy): handle replacement launch failures
Brisbanehuang Jul 20, 2026
00de8ab
fix(discovery): close coordinator and configuration lifecycle gaps
Brisbanehuang Jul 20, 2026
420802a
docs(discovery): document Redis cluster capability fallback
Brisbanehuang Jul 20, 2026
96cbae6
fix(discovery): synchronize Sticky fallback promotion
Brisbanehuang Jul 20, 2026
e453b8e
fix(discovery): probe binding capability before eligibility
Brisbanehuang Jul 20, 2026
4c9690d
fix(discovery): reject stale attempt boundary events
Brisbanehuang Jul 20, 2026
8cbf3be
fix(discovery): honor configured sticky SLA and validation
Brisbanehuang Jul 20, 2026
e95f0d0
test(discovery): cover complete ready stream
Brisbanehuang Jul 20, 2026
309d6ca
test(settings): cover discovery window boundary
Brisbanehuang Jul 20, 2026
0de55d7
fix(discovery): recognize Anthropic tool deltas
Brisbanehuang Jul 20, 2026
059de38
fix(discovery): preserve binding safety and tool prefixes
Brisbanehuang Jul 20, 2026
f98a558
fix(discovery): preserve rectifier and sticky binding semantics
Brisbanehuang Jul 20, 2026
24a39cc
style(discovery): organize response handler imports
Brisbanehuang Jul 20, 2026
bb86b49
merge: synchronize discovery and binding fixes
Brisbanehuang Jul 20, 2026
e3cb570
fix(settings): tighten discovery configuration
Brisbanehuang Jul 20, 2026
3e9fcd9
merge: synchronize discovery safety fixes
Brisbanehuang Jul 20, 2026
e852b6d
merge: synchronize latest discovery and binding fixes
Brisbanehuang Jul 20, 2026
ddd156b
merge: synchronize final binding and discovery safety fixes
Brisbanehuang Jul 21, 2026
3d314e3
fix(discovery): preserve long-stream binding safety
Brisbanehuang Jul 21, 2026
825f4ff
fix(discovery): fail closed on binding conflicts
Brisbanehuang Jul 21, 2026
811192a
fix(discovery): reject failed response terminal markers
Brisbanehuang Jul 21, 2026
754c1a9
merge: synchronize final discovery lifecycle fixes
Brisbanehuang Jul 21, 2026
3c1105b
merge: synchronize tenant isolation and discovery fences
Brisbanehuang Jul 21, 2026
0880619
fix(discovery): unwrap Gemini response candidates
Brisbanehuang Jul 21, 2026
51cbc69
Merge branch 'codex/discovery-pr2' into codex/discovery-pr3
Brisbanehuang Jul 21, 2026
bde3d9f
fix(discovery): localize validation and completion checks
Brisbanehuang Jul 21, 2026
acda2e3
merge: synchronize discovery authority fixes
Brisbanehuang Jul 21, 2026
9643f10
fix(discovery): preserve peers after retry setup failure
Brisbanehuang Jul 21, 2026
43fa079
fix(discovery): parse SSE events by complete data frames
Brisbanehuang Jul 21, 2026
d98f641
fix(discovery): reserve slots during rectifier retry setup
Brisbanehuang Jul 21, 2026
75382b9
fix(discovery): close setup reservation races
Brisbanehuang Jul 21, 2026
70f3c44
fix(discovery): gate queued fallback promotion
Brisbanehuang Jul 21, 2026
1ae6bfb
fix(discovery): await queued wave handoff
Brisbanehuang Jul 21, 2026
e7b33e7
fix(discovery): refill failed fallback during setup
Brisbanehuang Jul 21, 2026
290e4c2
fix(config): stabilize Discovery window error code
Brisbanehuang Jul 21, 2026
06bbc1b
Merge remote-tracking branch 'origin/integration/discovery-stack-2026…
ding113 Jul 23, 2026
d585290
fix(discovery): align fallback error handling
ding113 Jul 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions docs/streaming-discovery.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Bounded Streaming Discovery

Bounded Discovery is an optional cold-start routing mode for streaming
requests. It exists to reduce duplicate upstream spend while preserving a
working request when the first provider is slow.

## Defaults

| Setting | Default | Meaning |
| --- | ---: | --- |
| `discoveryEnabled` | `false` | Keep the existing Hedge path until explicitly enabled. |
| `discoveryConcurrency` | `2` | Number of normal providers in the first batch. |
| `maxDiscoveryRounds` | `2` | Maximum Discovery rounds. |
| `discoverySlaMs` | `10000` | First-byte budget for a Discovery round. |
| `stickySlaMs` | `20000` | First-byte budget for an existing Sticky provider. |
| `racingTotalTimeoutMs` | `60000` | Total pre-winner deadline; it is cleared after a winner is committed. |
| `stickyTimeoutCooldownMs` | `300000` | Session/provider cooldown after a Sticky timeout. |

The total deadline must be at least `stickySlaMs + maxDiscoveryRounds *
discoverySlaMs`. The UI and API reject configurations that do not satisfy
this relationship.

## Request lifecycle

- A healthy Sticky provider is probed alone. If it times out, it becomes the
single fallback for this request and receives a cooldown; a later request
may select it again after the cooldown.
- A cold start launches the configured initial normal candidates. The highest
priority ready candidate wins; a lower-priority candidate remains held while
a higher-priority candidate is still inside its SLA window.
- At a round boundary, at most one pending normal attempt is promoted to the
fallback. The next round uses the remaining slots for new normal candidates,
so `discoveryConcurrency=2` means `one fallback + one new candidate`.
- A fallback that has produced a valid prefix is held until the current normal
window closes, all normal candidates fail, or no candidates remain. A normal
winner always has precedence during the window.
- Discovery losers are cancelled and their readers/agents/provider-session
references are released. They do not enter legacy `bill_hedge_losers`
draining.
- Sticky binding is written only after a natural, successful stream completion
with the protocol completion marker and a generation-aware CAS. Fake-200,
incomplete, and client-aborted streams do not create or renew Sticky.

Discovery is eligible only for supported streaming protocol families and when
the versioned Redis binding capability is available. If Redis capability is
unknown/unavailable, the existing provider selection and Hedge behavior remain
active.

The versioned binding scripts require the canonical binding, legacy provider,
legacy owner, lease, and cooldown keys to be evaluated atomically. On Redis
Cluster layouts where those keys do not share a slot and Redis returns
`CROSSSLOT` (or when Lua capability probing fails), the capability state is
`unavailable`; the service records that state and uses the tenant-checked
legacy wrapper. Discovery stays disabled until a later connection-lifecycle
probe succeeds.

## Rollout

1. Apply the system-settings migration.
2. Confirm the Redis versioned-binding capability probe is `available`.
3. Leave `discoveryEnabled=false` while validating the existing Hedge and
versioned binding checks.
4. Enable Discovery for a controlled group, observe provider-chain outcomes,
first-token latency, fallback promotions, cancellations, CAS conflicts, and
final 503s.
5. Disable the setting to return immediately to the legacy Hedge path.

This feature does not change the final client failure contract: an exhausted
request continues to return the existing `503` mapping.
7 changes: 7 additions & 0 deletions drizzle/0110_daffy_rawhide_kid.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ALTER TABLE "system_settings" ADD COLUMN "discovery_enabled" boolean DEFAULT false NOT NULL;--> statement-breakpoint
ALTER TABLE "system_settings" ADD COLUMN "discovery_concurrency" integer DEFAULT 2 NOT NULL;--> statement-breakpoint
ALTER TABLE "system_settings" ADD COLUMN "max_discovery_rounds" integer DEFAULT 2 NOT NULL;--> statement-breakpoint
ALTER TABLE "system_settings" ADD COLUMN "discovery_sla_ms" integer DEFAULT 10000 NOT NULL;--> statement-breakpoint
ALTER TABLE "system_settings" ADD COLUMN "sticky_sla_ms" integer DEFAULT 20000 NOT NULL;--> statement-breakpoint
ALTER TABLE "system_settings" ADD COLUMN "racing_total_timeout_ms" integer DEFAULT 60000 NOT NULL;--> statement-breakpoint
ALTER TABLE "system_settings" ADD COLUMN "sticky_timeout_cooldown_ms" integer DEFAULT 300000 NOT NULL;
Loading