Deterministic Routing Strategies
Deterministic routing strategies
์น์ ์ ๋ชฉ: โDeterministic routing strategiesโOmniRouteโs self-hosted gateway entry (/v1/chat/completions, RIC-738) routes to a
single provider by default. When you configure a strategy: block, the route decision
becomes a deterministic, explainable policy โ the OmniRoute differentiator vs
NotDiamond/Martian โpredictโ black-box routing.
Every decision is:
- Deterministic โ the same config + same runtime state yields the same provider.
- Config-expressed โ one rule per line; no โไธไฝๅๆบ่ฝไฝโ, no learned model.
- Explainable โ every response carries
x-omniroute-route-decision, a one-line answer to โwhy this model?โ (and โwhy NOT that oneโ).
This is M2 of the RIC-697 differentiation (D3 ๅฏๅฎก่ฎก่ทฏ็ฑ). There is no predictive / ML dependency โ the strategies are pure rules over observable signals (consecutive failures, declared cost, measured latency).
Add a strategy: block to the same YAML document as providers:, or point
OMNIROUTE_SELF_HOSTED_STRATEGY (inline YAML) / OMNIROUTE_SELF_HOSTED_STRATEGY_FILE
(a file) at a standalone strategy: document. An explicit env strategy merges over
the inline block per-key.
providers: - id: cheap kind: openai baseUrl: http://127.0.0.1:11434/v1 model: llama3 costPer1MInput: 0.2 # USD per 1M input tokens โ used by cost-priority - id: fast kind: openai baseUrl: http://127.0.0.1:8080/v1 model: gpt-4o-mini costPer1MInput: 0.6 - id: premium kind: anthropic baseUrl: http://127.0.0.1:8081 model: claude-sonnet costPer1MInput: 3.0
strategy: blacklist: [] # provider ids never used whitelist: [cheap, fast, premium] # when non-empty, ONLY these are used costPriority: true # cheapest eligible candidate first latencyAware: enabled: true # fastest recent-average candidate first cooldown: consecutiveFailures: 2 # breaker trips after this many in a row cooldownMs: 30000 # โฆand the provider stays excluded this long fallbackChain: [cheap, fast, premium] # explicit fallback orderThe five strategies
์น์ ์ ๋ชฉ: โThe five strategiesโ| Strategy | Config | Effect |
|---|---|---|
| Blacklist | blacklist: [id, ...] |
Listed providers are never candidates. |
| Whitelist | whitelist: [id, ...] |
Non-empty โ only listed providers are candidates. |
| Cooldown/breaker | cooldown: {consecutiveFailures, cooldownMs} |
After N consecutive failures a provider is excluded for the window. A success resets the counter. |
| Cost-priority | costPriority: true |
Eligible candidates sorted by costPer1MInput ascending (declared, never fabricated). |
| Latency-aware | latencyAware.enabled: true |
Eligible candidates sorted by recent average request latency ascending. Unsampled providers sort last. |
| Fallback chain | fallbackChain: [id, ...] |
Explicit primaryโbackup order. Wins over cost/latency ordering. |
Filters (blacklist / whitelist / cooldown) run first and remove candidates. Then the
ordering stage sorts the survivors: explicit fallbackChain wins; otherwise
costPriority then latencyAware apply in that order.
Pinned providers
์น์ ์ ๋ชฉ: โPinned providersโThe x-omniroute-provider header and the provider/model model-prefix are explicit
pins, not preferences. If a pinned provider is excluded by a hard filter (blacklist /
whitelist / active cooldown), the request fails with 400 and the pin reason โ the
gateway never silently re-routes a client who asked for a specific provider. If the pin
survives the filters it is the first candidate, and the remaining candidates serve as
its fallback chain.
Fallback on failure
์น์ ์ ๋ชฉ: โFallback on failureโThe ordered candidate list is the fallback chain. When the first provider fails
(network unreachable, connection refused, DNS/TLS, or any non-2xx), the gateway walks
the next candidate, and so on. Each failure is recorded into the cooldown breaker and
each attempt is latency-sampled โ so a broken primary also cools down for subsequent
requests. When every candidate fails, the last normalized error (OpenAI shape) is
returned. When no candidate is eligible at all, a 503 with the full explainable
decision is returned.
Explainability
์น์ ์ ๋ชฉ: โExplainabilityโEvery response routed through the strategy engine carries:
x-omniroute-route-decision: cheap(cost-priority: cheap #1) -> fast(cost-priority: fast #2); premium excluded: blacklist: premium forbiddenThe value is the ordered candidate list plus every exclusion reason โ the audit trail for โwhy this model, why not that oneโ.
Failure contract (unchanged from RIC-738)
์น์ ์ ๋ชฉ: โFailure contract (unchanged from RIC-738)โ- Upstream non-2xx body is normalized through
parseUpstreamError+buildErrorBodyinto the standard OpenAIerrorshape (Hard Rule #12). - Network-level failures return a normalized
502; after the whole chain is exhausted, the last normalized error is surfaced. - Credential / session headers echoed upstream are stripped from every response.
- Provider config with a malformed
strategy:block returns500โ a misconfigured policy never silently becomes a no-op.
tests/unit/routing-strategies.test.tsโ 25 unit tests over the pure strategy engine: parse, blacklist/whitelist, cooldown breaker, cost-priority, latency-aware, fallback chain, combined pipeline, explainability.tests/unit/self-hosted-entry.test.tsโ fault injection over real HTTP: primary down โ fallback succeeds; all-down โ last error; pinned-blacklisted โ 400; cooldown excludes a failing provider on the next request; no-eligible โ 503 with explainable decision.
HagiCode
HagiCode๋ ์์ด์ ํธ ์ฝ๋ฉ ์์ ๊ณต๊ฐ์ ๋๋ค. ํ๋ถํ๊ณ ํธ๋ฆฌํ UI ์ํธ์์ฉ์ผ๋ก ๊ณํ ์๋ฆฝ, ์์ด์ ํธ ์คํ, ํ๋ก์ ํธ ์์ ์ ์ฝ๊ฒ ์์ํ๊ณ ๋ฐ๋ผ๊ฐ๋ฉฐ ๊ฐ๋ฐ์ ๋ ํฅ๋ฏธ๋ก์ด ๊ฒฝํ์ผ๋ก ๋ง๋ญ๋๋ค.
ํ๋ถํ๊ณ ํธ๋ฆฌํ UI ์ํธ์์ฉ์ผ๋ก ๊ณํ๋ถํฐ ํ๋ก์ ํธ ์์ ๊น์ง ์ฝ๊ฒ ๋ฐ๋ผ๊ฐ ์ ์์ต๋๋ค.
- ์ค๋งํธOpenSpec ์ํฌํ๋ก๋ ์๋๋ฅผ ์ ์, ์ค๊ณ, ์์ ์ ๊ฑฐ์ณ ๋ฐฐํฌ๊น์ง ์ด์ด์ง๋ ์คํ ๊ฐ๋ฅํ ๊ฒฝ๋ก๋ก ๋ฐ๊ฟ๋๋ค.
- ํจ์จ์ ๋ค์ค ์์ด์ ํธ ์คํ์ผ๋ก ์กฐ์ฌ, ๊ตฌํ, ๊ฒํ ๋ฅผ ๋ณ๋ ฌ๋ก ์งํํ๋ฉฐ ์ฌ๋ฌ ์ ์ฅ์์ ์ต์ํ Agent CLI๋ฅผ ์ง์ํฉ๋๋ค.
- ํฅ๋ฏธ๋ก์ดํ๋ถํ๊ณ ํธ๋ฆฌํ UI ์ํธ์์ฉ์ผ๋ก ๊ณํ ์๋ฆฝ, ์์ด์ ํธ ์คํ, ํ๋ก์ ํธ ์์ ์ ์ฝ๊ฒ ์์ํ๊ณ ๋ฐ๋ผ๊ฐ ์ ์์ต๋๋ค.
Windows์ฉ ๋ค์ด๋ก๋
HagiCode ๊ณต์
์์ด๋์ด๋ฅผ ์ค์ ๋ก ๋ฐฐํฌ๋๋ ์ํํธ์จ์ด๋ก.
HagiCode๋ ์์ด์ ํธ ์ฝ๋ฉ ์์ ๊ณต๊ฐ์ ๋๋ค. OpenSpec ์ํฌํ๋ก๋ก ๋ณ๊ฒฝ์ ๊ณํํ๊ณ , ๋ค์ค ์์ด์ ํธ ์คํ์ผ๋ก ์งํํ๋ฉฐ, Hero Scenario๋ก ๊ธด ์์ ์ ์งํ ์ํฉ์ ํ๋์ ๋ณด์ฌ ์์ด๋์ด๋ฅผ ์ค์ ๋ก ๋ฐฐํฌ๋๋ ์ํํธ์จ์ด๋ก ๋ง๋ญ๋๋ค.
- ์ค๋งํธ
- OpenSpec ์ํฌํ๋ก๋ ์๋๋ฅผ ์ ์๋ถํฐ ๋ฐฐํฌ๊น์ง ์ด์ด์ง๋ ์คํ ๊ฐ๋ฅํ ๊ฒฝ๋ก๋ก ๋ฐ๊ฟ๋๋ค.
- ํจ์จ์
- ๋ค์ค ์์ด์ ํธ ์คํ์ผ๋ก ์กฐ์ฌ, ๊ตฌํ, ๊ฒํ ๋ฅผ ๋ณ๋ ฌ๋ก ์งํํฉ๋๋ค.
- ์ฆ๊ฑฐ์ด
- ํธ๋ฆฌํ UI ์ํธ์์ฉ์ผ๋ก ๊ณํ, ์์ด์ ํธ ์คํ, ํ๋ก์ ํธ ์์ ์ ์ฝ๊ฒ ๋ฐ๋ผ๊ฐ ์ ์์ต๋๋ค.
ยฉ 2026 HagiCode | Powered By hagilight-starlight@0.21.0 | Branch: main | Commit: de60bcd | Built:

