465 lines
19 KiB
YAML
465 lines
19 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:3b-instruct-q4_0"
|
|
llm_client = "classifier"
|
|
|
|
[targets.local_qwen_low]
|
|
id = "route/local/qwen2.5-14b/low"
|
|
llm_client = "local_low"
|
|
extra_body = { reasoning_effort = "low" }
|
|
|
|
[targets.local_qwen_medium]
|
|
id = "route/local/qwen2.5-14b/medium"
|
|
llm_client = "local_medium"
|
|
extra_body = { reasoning_effort = "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"
|
|
extra_body = { thinking = { type = "adaptive" }, output_config = { effort = "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"
|
|
targets = ["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"]
|
|
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 routing authority for a private family assistant. Choose exactly
|
|
one configured target for this model-call boundary. Mildly favor fast and
|
|
economical answers, but never trade away correctness for difficult,
|
|
ambiguous, safety-sensitive, tool-heavy, or consequential work. Use local
|
|
Qwen only for simple low-risk conversation, formatting, or continuity.
|
|
Prefer Codex for implementation, debugging, tests, and direct repository
|
|
work. Prefer Claude for architecture, ambiguity, long-context synthesis,
|
|
risk analysis, and independent review. Interpret requests such as "answer
|
|
quickly", "think hard", or "use Claude" semantically. An explicit user
|
|
provider, model, or depth instruction wins unless it would undercut a clear
|
|
safety floor. Every request is a fresh boundary; classify the actual current
|
|
objective and recent context, including referential instructions like
|
|
"continue" or "do it". Never select effort above xhigh.
|
|
"""
|
|
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"
|
|
targets = ["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"]
|
|
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 routing authority for a private general assistant. Choose
|
|
exactly one configured target for this model-call boundary. Balance latency,
|
|
cost, and intelligence while giving difficult, uncertain, tool-heavy, or
|
|
consequential work enough capability. Use local Qwen only for simple
|
|
low-risk conversation, formatting, or continuity. Prefer Codex for
|
|
implementation, debugging, tests, and direct repository work. Prefer Claude
|
|
for architecture, ambiguity, long-context synthesis, risk analysis, and
|
|
independent review. Interpret speed/depth and provider requests
|
|
semantically; explicit user intent wins unless it undercuts a clear safety
|
|
floor. Classify the actual current objective and recent context, including
|
|
referential instructions such as "continue" or "do it". Never select effort
|
|
above xhigh.
|
|
"""
|
|
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"
|
|
targets = ["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"]
|
|
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 routing authority for operations triage. Choose exactly one
|
|
configured target for this model-call boundary. Favor evidence, diagnosis,
|
|
uncertainty handling, and correctness over marginal latency savings. Cheap
|
|
routes are appropriate only for genuinely mechanical low-risk steps. Prefer
|
|
Codex for implementation, debugging, tests, and repository work; prefer
|
|
Claude for diagnosis, architecture, ambiguity, synthesis, risk analysis,
|
|
and independent review. Interpret requests for speed, depth, or a provider
|
|
semantically. Explicit user intent wins unless it violates a safety floor.
|
|
Re-evaluate every current boundary using recent tool evidence and resolve
|
|
referential instructions such as "continue" or "do it" from that context.
|
|
Never select effort above xhigh.
|
|
"""
|
|
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"
|
|
targets = ["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"]
|
|
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 routing authority for an owner-only engineering agent. Choose
|
|
exactly one configured target for this model-call boundary. Strongly favor
|
|
correctness, verification, and task completion; do not waste premium
|
|
capacity on truly mechanical steps. Prefer Codex for implementation,
|
|
debugging, tests, and direct repository changes. Prefer Claude for
|
|
architecture, difficult ambiguity, long-context synthesis, risk analysis,
|
|
and independent review. Production changes, security, migrations, data-loss
|
|
risk, destructive work, and critical final review require high or xhigh.
|
|
Interpret user requests for speed, deeper thought, or a specific provider
|
|
semantically. Explicit user intent wins unless it undercuts the safety
|
|
floor. Re-evaluate every current boundary from the objective and recent tool
|
|
evidence, including referential instructions such as "continue" or "do
|
|
it". Never select effort above xhigh.
|
|
"""
|
|
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 sole routing authority for one durable engineering-worker
|
|
launch. Choose exactly one configured worker target from the current
|
|
objective, acceptance criteria, risk, and any prior-provider failure in the
|
|
request. Prefer Codex for implementation, debugging, tests, and repository
|
|
changes. Prefer Claude for architecture, ambiguity, synthesis, adversarial
|
|
analysis, and independent review. Use low only for mechanical bounded work,
|
|
medium for ordinary work, high for difficult or consequential work, and
|
|
xhigh for critical security, migration, destructive-risk, or independent
|
|
final review. Never exceed xhigh. If the request says a provider has failed
|
|
or exhausted capacity, do not select that provider.
|
|
"""
|
|
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
|