atlas-iac/services/hermes/switchyard-configmap.yaml

600 lines
26 KiB
YAML

# services/hermes/switchyard-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: hermes-switchyard
namespace: hermes
labels:
app: hermes-switchyard
data:
routes.toml: |
schema_version = 1
[llm_clients.classifier]
format = "openai_chat"
base_url = "http://ollama.ai.svc.cluster.local:11434/v1"
max_retries = 1
[llm_clients.local_low]
format = "openai_chat"
base_url = "http://hermes-model-gate.hermes.svc.cluster.local:11434/v1"
max_retries = 1
[llm_clients.local_medium]
format = "openai_chat"
base_url = "http://hermes-model-gate.hermes.svc.cluster.local:11434/v1"
max_retries = 1
[llm_clients.codex_low]
format = "openai_responses"
base_url = "http://hermes-codex-broker.hermes.svc.cluster.local:9003/v1"
api_key_env = "ATLAS_BROKER_KEY"
max_retries = 1
[llm_clients.codex_medium]
format = "openai_responses"
base_url = "http://hermes-codex-broker.hermes.svc.cluster.local:9003/v1"
api_key_env = "ATLAS_BROKER_KEY"
max_retries = 1
[llm_clients.codex_high]
format = "openai_responses"
base_url = "http://hermes-codex-broker.hermes.svc.cluster.local:9003/v1"
api_key_env = "ATLAS_BROKER_KEY"
max_retries = 1
[llm_clients.codex_xhigh]
format = "openai_responses"
base_url = "http://hermes-codex-broker.hermes.svc.cluster.local:9003/v1"
api_key_env = "ATLAS_BROKER_KEY"
max_retries = 1
[llm_clients.claude_low]
format = "anthropic_messages"
base_url = "http://127.0.0.1:9006/v1"
api_key_env = "ATLAS_BROKER_KEY"
max_retries = 1
[llm_clients.claude_medium]
format = "anthropic_messages"
base_url = "http://127.0.0.1:9006/v1"
api_key_env = "ATLAS_BROKER_KEY"
max_retries = 1
[llm_clients.claude_high]
format = "anthropic_messages"
base_url = "http://127.0.0.1:9006/v1"
api_key_env = "ATLAS_BROKER_KEY"
max_retries = 1
[llm_clients.claude_xhigh]
format = "anthropic_messages"
base_url = "http://127.0.0.1:9006/v1"
api_key_env = "ATLAS_BROKER_KEY"
max_retries = 1
[llm_clients.worker_decision]
format = "openai_chat"
base_url = "http://127.0.0.1:9007/v1"
max_retries = 0
[targets.classifier]
id = "qwen2.5:14b-instruct-q4_0"
llm_client = "classifier"
[targets.local_qwen_low]
id = "route/local/qwen2.5-14b/low"
llm_client = "local_low"
[targets.local_qwen_medium]
id = "route/local/qwen2.5-14b/medium"
llm_client = "local_medium"
[targets.codex_luna_low]
id = "route/codex/luna/low"
llm_client = "codex_low"
extra_body = { reasoning = { effort = "low" } }
[targets.codex_terra_low]
id = "route/codex/terra/low"
llm_client = "codex_low"
extra_body = { reasoning = { effort = "low" } }
[targets.codex_terra_medium]
id = "route/codex/terra/medium"
llm_client = "codex_medium"
extra_body = { reasoning = { effort = "medium" } }
[targets.codex_terra_high]
id = "route/codex/terra/high"
llm_client = "codex_high"
extra_body = { reasoning = { effort = "high" } }
[targets.codex_sol_medium]
id = "route/codex/sol/medium"
llm_client = "codex_medium"
extra_body = { reasoning = { effort = "medium" } }
[targets.codex_sol_high]
id = "route/codex/sol/high"
llm_client = "codex_high"
extra_body = { reasoning = { effort = "high" } }
[targets.codex_sol_xhigh]
id = "route/codex/sol/xhigh"
llm_client = "codex_xhigh"
extra_body = { reasoning = { effort = "xhigh" } }
[targets.claude_haiku_low]
id = "route/claude/haiku/low"
llm_client = "claude_low"
[targets.claude_sonnet_medium]
id = "route/claude/sonnet/medium"
llm_client = "claude_medium"
extra_body = { thinking = { type = "adaptive" }, output_config = { effort = "medium" } }
[targets.claude_sonnet_high]
id = "route/claude/sonnet/high"
llm_client = "claude_high"
extra_body = { thinking = { type = "adaptive" }, output_config = { effort = "high" } }
[targets.claude_opus_high]
id = "route/claude/opus/high"
llm_client = "claude_high"
extra_body = { thinking = { type = "adaptive" }, output_config = { effort = "high" } }
[targets.claude_opus_xhigh]
id = "route/claude/opus/xhigh"
llm_client = "claude_xhigh"
extra_body = { thinking = { type = "adaptive" }, output_config = { effort = "xhigh" } }
[targets.worker_codex_luna_low]
id = "worker/codex/luna/low"
llm_client = "worker_decision"
[targets.worker_codex_terra_medium]
id = "worker/codex/terra/medium"
llm_client = "worker_decision"
[targets.worker_codex_sol_high]
id = "worker/codex/sol/high"
llm_client = "worker_decision"
[targets.worker_codex_sol_xhigh]
id = "worker/codex/sol/xhigh"
llm_client = "worker_decision"
[targets.worker_claude_haiku_low]
id = "worker/claude/haiku/low"
llm_client = "worker_decision"
[targets.worker_claude_sonnet_medium]
id = "worker/claude/sonnet/medium"
llm_client = "worker_decision"
[targets.worker_claude_sonnet_high]
id = "worker/claude/sonnet/high"
llm_client = "worker_decision"
[targets.worker_claude_opus_xhigh]
id = "worker/claude/opus/xhigh"
llm_client = "worker_decision"
[routes.auto_fast]
id = "atlas/auto/fast"
type = "llm_classifier"
mode = "custom"
classifier_target = "classifier"
# Switchyard falls through this list after a request-local target failure.
# Keep both xhigh providers first so recovery can escalate, never downgrade.
targets = ["codex_sol_xhigh", "claude_opus_xhigh", "codex_sol_high", "claude_sonnet_high", "claude_opus_high", "codex_terra_high", "codex_sol_medium", "claude_sonnet_medium", "codex_terra_medium", "local_qwen_medium", "codex_terra_low", "codex_luna_low", "claude_haiku_low", "local_qwen_low"]
default_target = "codex_terra_medium"
max_output_tokens = 96
session_affinity = false
recent_turn_window = 8
context_window = 272000
tool_calling = true
reasoning = true
prompt = """
You are the deterministic routing authority for one private family-assistant
model-call boundary. Mildly favor speed, but apply these rules in order.
1. Set a mandatory minimum effort floor from the whole current objective and
recent context: xhigh for critical security work, risky production
migrations, destructive or data-loss risk, or consequential independent
final/release review; high for difficult debugging, consequential
implementation, adversarial review, major architectural tradeoffs, or
uncertain production work; medium for ordinary implementation, tool use,
analysis, or bounded architecture; low only for simple conversation,
formatting, lookup, or mechanical reversible work. Never choose below the
floor and never exceed xhigh.
2. Treat "think hard", "deeply", "carefully", and equivalent intent as a
request to raise capability by at least one tier when the safety floor is
lower. Treat "answer quickly" and equivalent intent as permission to choose
the fastest target at the safety floor, never below it. An explicit
available provider or model wins at the safety floor.
3. Use local Qwen only at low or medium for low-risk conversation,
formatting, lookup, and continuity. Prefer Codex for implementation,
debugging, tests, commands, and repository work. Prefer Claude for
architecture, ambiguity, synthesis, risk analysis, adversarial analysis,
and independent review. Anthropic means Claude; OpenAI means Codex. Never
select a provider stated to be unavailable, failed, exhausted, rate-limited,
or out of capacity; use the other provider at the same floor.
4. Map exactly: Codex low=codex_luna_low, medium=codex_terra_medium,
high=codex_sol_high, xhigh=codex_sol_xhigh; Claude low=claude_haiku_low,
medium=claude_sonnet_medium, high=claude_sonnet_high,
xhigh=claude_opus_xhigh; local low=local_qwen_low and local
medium=local_qwen_medium. Re-evaluate every boundary and resolve "continue"
or "do it" from recent context.
"""
response_schema = '''
{"type":"object","properties":{"decision":{"type":"object","properties":{"target":{"type":"string","enum":["codex_terra_medium","claude_sonnet_medium","codex_luna_low","claude_haiku_low","local_qwen_low","local_qwen_medium","codex_terra_low","codex_terra_high","codex_sol_medium","codex_sol_high","codex_sol_xhigh","claude_sonnet_high","claude_opus_high","claude_opus_xhigh"]}},"required":["target"],"additionalProperties":false}},"required":["decision"],"additionalProperties":false}
'''
[routes.auto_fast.policy]
type = "target_selector"
selector = "/decision/target"
[routes.auto_balanced]
id = "atlas/auto/balanced"
type = "llm_classifier"
mode = "custom"
classifier_target = "classifier"
# Switchyard falls through this list after a request-local target failure.
# Keep both xhigh providers first so recovery can escalate, never downgrade.
targets = ["codex_sol_xhigh", "claude_opus_xhigh", "codex_sol_high", "claude_sonnet_high", "claude_opus_high", "codex_terra_high", "codex_sol_medium", "claude_sonnet_medium", "codex_terra_medium", "local_qwen_medium", "codex_terra_low", "codex_luna_low", "claude_haiku_low", "local_qwen_low"]
default_target = "codex_terra_medium"
max_output_tokens = 96
session_affinity = false
recent_turn_window = 8
context_window = 272000
tool_calling = true
reasoning = true
prompt = """
You are the deterministic routing authority for one private general-assistant
model-call boundary. Balance speed and intelligence, then apply these rules
in order.
1. Set a mandatory minimum effort floor from the whole current objective and
recent context: xhigh for critical security work, risky production
migrations, destructive or data-loss risk, or consequential independent
final/release review; high for difficult debugging, consequential
implementation, adversarial review, major architectural tradeoffs, or
uncertain production work; medium for ordinary implementation, tool use,
analysis, or bounded architecture; low only for simple conversation,
formatting, lookup, or mechanical reversible work. Never choose below the
floor and never exceed xhigh.
2. Treat "think hard", "deeply", "carefully", and equivalent intent as a
request to raise capability by at least one tier when the safety floor is
lower. Treat "answer quickly" and equivalent intent as permission to choose
the fastest target at the safety floor, never below it. An explicit
available provider or model wins at the safety floor.
3. Use local Qwen only at low or medium for low-risk conversation,
formatting, lookup, and continuity. Prefer Codex for implementation,
debugging, tests, commands, and repository work. Prefer Claude for
architecture, ambiguity, synthesis, risk analysis, adversarial analysis,
and independent review. Anthropic means Claude; OpenAI means Codex. Never
select a provider stated to be unavailable, failed, exhausted, rate-limited,
or out of capacity; use the other provider at the same floor.
4. Map exactly: Codex low=codex_luna_low, medium=codex_terra_medium,
high=codex_sol_high, xhigh=codex_sol_xhigh; Claude low=claude_haiku_low,
medium=claude_sonnet_medium, high=claude_sonnet_high,
xhigh=claude_opus_xhigh; local low=local_qwen_low and local
medium=local_qwen_medium. Re-evaluate every boundary and resolve "continue"
or "do it" from recent context.
"""
response_schema = '''
{"type":"object","properties":{"decision":{"type":"object","properties":{"target":{"type":"string","enum":["codex_terra_medium","claude_sonnet_medium","codex_luna_low","claude_haiku_low","local_qwen_low","local_qwen_medium","codex_terra_low","codex_terra_high","codex_sol_medium","codex_sol_high","codex_sol_xhigh","claude_sonnet_high","claude_opus_high","claude_opus_xhigh"]}},"required":["target"],"additionalProperties":false}},"required":["decision"],"additionalProperties":false}
'''
[routes.auto_balanced.policy]
type = "target_selector"
selector = "/decision/target"
[routes.auto_deep]
id = "atlas/auto/deep"
type = "llm_classifier"
mode = "custom"
classifier_target = "classifier"
# Switchyard falls through this list after a request-local target failure.
# Keep both xhigh providers first so recovery can escalate, never downgrade.
targets = ["claude_opus_xhigh", "codex_sol_xhigh", "claude_sonnet_high", "codex_sol_high", "claude_opus_high", "codex_terra_high", "claude_sonnet_medium", "codex_sol_medium", "codex_terra_medium", "local_qwen_medium", "claude_haiku_low", "codex_luna_low", "codex_terra_low", "local_qwen_low"]
default_target = "claude_sonnet_high"
max_output_tokens = 96
session_affinity = false
recent_turn_window = 12
context_window = 272000
tool_calling = true
reasoning = true
prompt = """
You are the deterministic routing authority for one operations-triage
model-call boundary. Favor evidence and intelligence, then apply these rules
in order.
1. Set a mandatory minimum effort floor from the whole current objective,
recent context, and tool evidence: xhigh for critical security incidents,
risky production migrations, destructive or data-loss risk, or
consequential independent final/release review; high for difficult
diagnosis or debugging, consequential implementation, adversarial review,
major architectural tradeoffs, or uncertain production work; medium for
ordinary diagnosis, implementation, tool use, analysis, or bounded
architecture; low only for simple notification summaries, lookup, or
mechanical reversible work. Never choose below the floor or above xhigh.
2. Treat "think hard", "deeply", "carefully", and equivalent intent as a
request to raise capability by at least one tier when the safety floor is
lower. Treat "answer quickly" and equivalent intent as permission to choose
the fastest target at the safety floor, never below it. An explicit
available provider or model wins at the safety floor.
3. Use local Qwen only at low or medium for low-risk summaries, formatting,
lookup, and continuity. Prefer Codex for implementation, debugging, tests,
commands, and repository work. Prefer Claude for diagnosis, architecture,
ambiguity, synthesis, risk analysis, adversarial analysis, and independent
review. Anthropic means Claude; OpenAI means Codex. Never select a provider
stated to be unavailable, failed, exhausted, rate-limited, or out of
capacity; use the other provider at the same floor.
4. Map exactly: Codex low=codex_luna_low, medium=codex_terra_medium,
high=codex_sol_high, xhigh=codex_sol_xhigh; Claude low=claude_haiku_low,
medium=claude_sonnet_medium, high=claude_sonnet_high,
xhigh=claude_opus_xhigh; local low=local_qwen_low and local
medium=local_qwen_medium. Re-evaluate every boundary and resolve "continue"
or "do it" from recent context.
"""
response_schema = '''
{"type":"object","properties":{"decision":{"type":"object","properties":{"target":{"type":"string","enum":["claude_sonnet_high","codex_sol_high","codex_terra_medium","claude_sonnet_medium","codex_terra_high","codex_sol_medium","claude_opus_high","codex_sol_xhigh","claude_opus_xhigh","codex_luna_low","claude_haiku_low","local_qwen_medium","local_qwen_low","codex_terra_low"]}},"required":["target"],"additionalProperties":false}},"required":["decision"],"additionalProperties":false}
'''
[routes.auto_deep.policy]
type = "target_selector"
selector = "/decision/target"
[routes.auto_maximum]
id = "atlas/auto/maximum"
type = "llm_classifier"
mode = "custom"
classifier_target = "classifier"
# Switchyard falls through this list after a request-local target failure.
# Keep both xhigh providers first so recovery can escalate, never downgrade.
targets = ["codex_sol_xhigh", "claude_opus_xhigh", "codex_sol_high", "claude_opus_high", "claude_sonnet_high", "codex_terra_high", "codex_sol_medium", "claude_sonnet_medium", "codex_terra_medium", "local_qwen_medium", "codex_luna_low", "claude_haiku_low", "codex_terra_low", "local_qwen_low"]
default_target = "codex_sol_high"
max_output_tokens = 96
session_affinity = false
recent_turn_window = 16
context_window = 272000
tool_calling = true
reasoning = true
prompt = """
You are the deterministic routing authority for one owner-only engineering
model-call boundary. Strongly favor intelligence, verification, and task
completion, then apply these rules in order.
1. Set a mandatory minimum effort floor from the whole current objective,
recent context, and tool evidence: xhigh for critical security work, risky
production migrations, destructive or data-loss risk, or consequential
independent final/release review; high for difficult debugging,
consequential implementation, adversarial review, major architectural
tradeoffs, or uncertain production work; medium for ordinary
implementation, tests, tool use, analysis, or bounded architecture; low
only for lookup or truly mechanical reversible work. Never choose below the
floor or above xhigh.
2. Treat "think hard", "deeply", "carefully", and equivalent intent as a
request to raise capability by at least one tier when the safety floor is
lower. Treat "answer quickly" and equivalent intent as permission to choose
the fastest target at the safety floor, never below it. An explicit
available provider or model wins at the safety floor.
3. Use local Qwen only at low or medium for low-risk lookup, formatting, and
continuity. Prefer Codex for implementation, debugging, tests, commands,
and repository changes. Prefer Claude for architecture, ambiguity,
synthesis, risk analysis, adversarial analysis, and independent review.
Anthropic means Claude; OpenAI means Codex. Never select a provider stated
to be unavailable, failed, exhausted, rate-limited, or out of capacity; use
the other provider at the same floor.
4. Map exactly: Codex low=codex_luna_low, medium=codex_terra_medium,
high=codex_sol_high, xhigh=codex_sol_xhigh; Claude low=claude_haiku_low,
medium=claude_sonnet_medium, high=claude_sonnet_high,
xhigh=claude_opus_xhigh; local low=local_qwen_low and local
medium=local_qwen_medium. Re-evaluate every boundary and resolve "continue"
or "do it" from recent context.
"""
response_schema = '''
{"type":"object","properties":{"decision":{"type":"object","properties":{"target":{"type":"string","enum":["codex_sol_high","claude_opus_high","claude_sonnet_high","codex_terra_high","codex_sol_xhigh","claude_opus_xhigh","codex_terra_medium","claude_sonnet_medium","codex_sol_medium","codex_luna_low","claude_haiku_low","local_qwen_medium","local_qwen_low","codex_terra_low"]}},"required":["target"],"additionalProperties":false}},"required":["decision"],"additionalProperties":false}
'''
[routes.auto_maximum.policy]
type = "target_selector"
selector = "/decision/target"
[routes.worker_auto_maximum]
id = "atlas/worker/auto/maximum"
type = "llm_classifier"
mode = "custom"
classifier_target = "classifier"
targets = ["worker_codex_sol_high", "worker_claude_sonnet_high", "worker_codex_sol_xhigh", "worker_claude_opus_xhigh", "worker_codex_terra_medium", "worker_claude_sonnet_medium", "worker_codex_luna_low", "worker_claude_haiku_low"]
default_target = "worker_codex_sol_high"
max_output_tokens = 96
session_affinity = false
recent_turn_window = 16
context_window = 272000
tool_calling = false
reasoning = true
prompt = """
You are the deterministic routing authority for one durable engineering
worker launch. Choose exactly one configured target. Apply these steps in
order.
1. Set a mandatory minimum effort floor from the whole objective:
- xhigh: critical security work; a risky production migration; destructive
or data-loss risk; or an independent final/release review of consequential
changes.
- high: difficult debugging, consequential implementation, adversarial
review, architecture with major tradeoffs, or uncertain production work.
- medium: ordinary implementation, tests, analysis, or bounded architecture
work.
- low: only mechanical, reversible, tightly bounded work such as a typo,
formatting, or a simple lookup.
Never choose below the floor and never exceed xhigh.
2. Determine provider availability before provider preference:
- Anthropic and Claude name the same provider. If either is failed,
unavailable, exhausted, rate-limited, or out of capacity, Claude is
unavailable.
- OpenAI and Codex name the same provider. If either is failed, unavailable,
exhausted, rate-limited, or out of capacity, Codex is unavailable.
- Never select an unavailable provider. Use the available provider at the
same effort floor.
3. Choose the provider for the dominant action when both are available:
- Codex: implementation, debugging, tests, commands, and repository changes.
- Claude: architecture, ambiguity, synthesis, risk analysis, adversarial
analysis, and independent review.
A final independent review is Claude; implementing review findings is Codex.
4. Map provider and effort exactly:
Codex low=worker_codex_luna_low;
Codex medium=worker_codex_terra_medium;
Codex high=worker_codex_sol_high;
Codex xhigh=worker_codex_sol_xhigh.
Claude low=worker_claude_haiku_low;
Claude medium=worker_claude_sonnet_medium;
Claude high=worker_claude_sonnet_high;
Claude xhigh=worker_claude_opus_xhigh.
Examples:
Critical security migration final review -> worker_claude_opus_xhigh.
Implement critical security review fixes -> worker_codex_sol_xhigh.
Difficult intermittent production failure -> worker_codex_sol_high.
Ordinary component design -> worker_claude_sonnet_medium.
One spelling correction -> worker_codex_luna_low.
Anthropic exhausted + critical independent final review ->
worker_codex_sol_xhigh.
OpenAI exhausted + difficult repository implementation ->
worker_claude_sonnet_high.
Before responding, verify the provider is available and effort is not below
the floor. Return only the required decision object.
"""
response_schema = '''
{"type":"object","properties":{"decision":{"type":"object","properties":{"target":{"type":"string","enum":["worker_codex_sol_high","worker_claude_sonnet_high","worker_codex_sol_xhigh","worker_claude_opus_xhigh","worker_codex_terra_medium","worker_claude_sonnet_medium","worker_codex_luna_low","worker_claude_haiku_low"]}},"required":["target"],"additionalProperties":false}},"required":["decision"],"additionalProperties":false}
'''
[routes.worker_auto_maximum.policy]
type = "target_selector"
selector = "/decision/target"
[routes.worker_manual_codex_low]
id = "atlas/worker/manual/codex/low"
type = "random"
targets = ["worker_codex_luna_low"]
[routes.worker_manual_codex_medium]
id = "atlas/worker/manual/codex/medium"
type = "random"
targets = ["worker_codex_terra_medium"]
[routes.worker_manual_codex_high]
id = "atlas/worker/manual/codex/high"
type = "random"
targets = ["worker_codex_sol_high"]
[routes.worker_manual_codex_xhigh]
id = "atlas/worker/manual/codex/xhigh"
type = "random"
targets = ["worker_codex_sol_xhigh"]
[routes.worker_manual_claude_low]
id = "atlas/worker/manual/claude/low"
type = "random"
targets = ["worker_claude_haiku_low"]
[routes.worker_manual_claude_medium]
id = "atlas/worker/manual/claude/medium"
type = "random"
targets = ["worker_claude_sonnet_medium"]
[routes.worker_manual_claude_high]
id = "atlas/worker/manual/claude/high"
type = "random"
targets = ["worker_claude_sonnet_high"]
[routes.worker_manual_claude_xhigh]
id = "atlas/worker/manual/claude/xhigh"
type = "random"
targets = ["worker_claude_opus_xhigh"]
# A zero-weight target is not selected initially. Switchyard still walks
# this ordered list after 403/408/429/5xx, timeout, or transport failure.
[routes.manual_codex_luna]
id = "atlas/manual/codex/luna"
type = "random"
targets = ["codex_luna_low", "claude_haiku_low", "codex_terra_medium", "claude_sonnet_medium", "local_qwen_low"]
weights = [1, 0, 0, 0, 0]
context_window = 272000
tool_calling = true
reasoning = true
[routes.manual_codex_terra]
id = "atlas/manual/codex/terra"
type = "random"
targets = ["codex_terra_medium", "claude_sonnet_medium", "codex_sol_high", "claude_sonnet_high", "local_qwen_medium"]
weights = [1, 0, 0, 0, 0]
context_window = 272000
tool_calling = true
reasoning = true
[routes.manual_codex_sol]
id = "atlas/manual/codex/sol"
type = "random"
targets = ["codex_sol_high", "claude_opus_high", "claude_sonnet_high", "codex_terra_high", "local_qwen_medium"]
weights = [1, 0, 0, 0, 0]
context_window = 272000
tool_calling = true
reasoning = true
[routes.manual_claude_haiku]
id = "atlas/manual/claude/haiku"
type = "random"
targets = ["claude_haiku_low", "codex_luna_low", "claude_sonnet_medium", "codex_terra_medium", "local_qwen_low"]
weights = [1, 0, 0, 0, 0]
context_window = 272000
tool_calling = true
reasoning = true
[routes.manual_claude_sonnet]
id = "atlas/manual/claude/sonnet"
type = "random"
targets = ["claude_sonnet_high", "codex_sol_high", "claude_opus_high", "codex_terra_high", "local_qwen_medium"]
weights = [1, 0, 0, 0, 0]
context_window = 272000
tool_calling = true
reasoning = true
[routes.manual_claude_opus]
id = "atlas/manual/claude/opus"
type = "random"
targets = ["claude_opus_high", "codex_sol_high", "claude_sonnet_high", "codex_terra_high", "local_qwen_medium"]
weights = [1, 0, 0, 0, 0]
context_window = 272000
tool_calling = true
reasoning = true
[routes.manual_local_qwen]
id = "atlas/manual/local/qwen-14b"
type = "random"
targets = ["local_qwen_medium", "codex_terra_medium", "claude_sonnet_medium", "codex_luna_low", "claude_haiku_low"]
weights = [1, 0, 0, 0, 0]
context_window = 131072
tool_calling = true
reasoning = false