Skip to content

Commit c37cad8

Browse files
eugenioclaude
andcommitted
feat: switch to Bedrock Mantle endpoint, new model lineup, fix tool-use bugs
- Switch from native Bedrock SDK to Mantle (OpenAI-compatible endpoint) which gives all models uniform tool-use support including GLM 5 - New 3-tier lineup: MiniMax M2.1 (budget), GLM 4.7 (mid), GLM 5 (premium) - Fix NadirClaw bug: empty string content on assistant tool_call messages became None, rejected by Bedrock (sed patch in Dockerfile) - Disable NADIRCLAW_OPTIMIZE — the optimizer strips tool_calls and tool_call_id from messages, breaking all tool-use conversations - Load Mantle API key from ~/.nadirclaw/mantle.env via docker-compose Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent dd2afe6 commit c37cad8

4 files changed

Lines changed: 32 additions & 28 deletions

File tree

Dockerfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ WORKDIR /app
55
# Install nadirclaw with dashboard extra
66
RUN pip install --no-cache-dir "nadirclaw[dashboard]>=0.13" boto3>=1.35
77

8+
# Fix NadirClaw bug: empty string content on assistant tool_call messages
9+
# becomes None, which Bedrock/Mantle rejects. Preserve empty string instead.
10+
RUN sed -i 's/content = text if text else message.content/content = text if text is not None else message.content/g' \
11+
/usr/local/lib/python3.11/site-packages/nadirclaw/server.py
12+
813
# Pre-download the sentence-transformers model so first startup is fast
914
RUN python -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('all-MiniLM-L6-v2')"
1015

config/nadirclaw.env

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,47 @@
1-
# NadirClaw configuration for AWS Bedrock (eu-west-2 London)
2-
# eu-west-2 has the most coding models of any EU region
1+
# NadirClaw configuration for AWS Bedrock Mantle (eu-west-2 London)
2+
# Uses Bedrock Mantle (OpenAI-compatible endpoint) for all models
33
# Copy to ~/.nadirclaw/.env or set as environment variables
44

5-
# AWS Bedrock credentials (use AWS_PROFILE or explicit keys)
6-
AWS_PROFILE=default
7-
AWS_DEFAULT_REGION=eu-west-2
8-
# AWS_ACCESS_KEY_ID=
9-
# AWS_SECRET_ACCESS_KEY=
5+
# Bedrock Mantle endpoint (OpenAI-compatible, all models support tool-use)
6+
NADIRCLAW_API_BASE=https://bedrock-mantle.eu-west-2.api.aws/v1
7+
# API key loaded from ~/.nadirclaw/mantle.env at container startup
8+
# OPENAI_API_KEY is set via docker-compose env_file
109

11-
# Three-tier routing with Bedrock models (verified available in eu-west-2)
12-
# Budget: Qwen3 Coder 30B - fast, cheap, good for simple tasks
13-
# Mid: Qwen3 Coder 480B - code-specialized, strong benchmarks
14-
# Premium: Kimi K2.5 - top coding scores (SWE 76.8%, HE 99%, LCB 85%)
15-
NADIRCLAW_SIMPLE_MODEL=bedrock/qwen.qwen3-coder-30b-a3b-v1:0
16-
NADIRCLAW_MID_MODEL=bedrock/qwen.qwen3-coder-480b-a35b-v1:0
17-
NADIRCLAW_COMPLEX_MODEL=bedrock/moonshotai.kimi-k2.5
10+
# Three-tier routing with Bedrock models (all available in eu-west-2)
11+
# Budget: MiniMax M2.1 - 10B active params, fast, cheap, good tool calling
12+
# Mid: GLM 4.7 - best tool-call reliability, 200K context, strong SWE
13+
# Premium: GLM 5 - top-tier coding, 200K context, 128K output, best consistency
14+
NADIRCLAW_SIMPLE_MODEL=openai/minimax.minimax-m2.1
15+
NADIRCLAW_MID_MODEL=openai/zai.glm-4.7
16+
NADIRCLAW_COMPLEX_MODEL=openai/zai.glm-5
1817

1918
# Tier thresholds (score 0-1: <= simple_max -> budget, >= complex_min -> premium)
2019
NADIRCLAW_TIER_THRESHOLDS=0.35,0.65
2120

2221
# Fallback chain (try next model on failure)
23-
# Qwen3 30B is the final fallback — it handles large system prompts that 480B/Kimi reject
24-
NADIRCLAW_FALLBACK_CHAIN=bedrock/moonshotai.kimi-k2.5,bedrock/qwen.qwen3-coder-480b-a35b-v1:0,bedrock/qwen.qwen3-coder-30b-a3b-v1:0
25-
NADIRCLAW_SIMPLE_FALLBACK=bedrock/qwen.qwen3-coder-480b-a35b-v1:0
26-
NADIRCLAW_MID_FALLBACK=bedrock/moonshotai.kimi-k2.5,bedrock/qwen.qwen3-coder-30b-a3b-v1:0
27-
NADIRCLAW_COMPLEX_FALLBACK=bedrock/qwen.qwen3-coder-480b-a35b-v1:0,bedrock/qwen.qwen3-coder-30b-a3b-v1:0
22+
# All models support tool-use via Mantle endpoint
23+
NADIRCLAW_FALLBACK_CHAIN=openai/zai.glm-5,openai/deepseek.v3.2,openai/zai.glm-4.7,openai/minimax.minimax-m2.1
24+
NADIRCLAW_SIMPLE_FALLBACK=openai/zai.glm-4.7-flash,openai/zai.glm-4.7
25+
NADIRCLAW_MID_FALLBACK=openai/zai.glm-5,openai/deepseek.v3.2
26+
NADIRCLAW_COMPLEX_FALLBACK=openai/deepseek.v3.2,openai/zai.glm-4.7,openai/minimax.minimax-m2.1
2827

2928
# Budget controls (USD)
3029
NADIRCLAW_DAILY_BUDGET=5.00
3130
NADIRCLAW_MONTHLY_BUDGET=80.00
3231
NADIRCLAW_BUDGET_WARN_THRESHOLD=0.8
3332
NADIRCLAW_BUDGET_STDOUT_ALERTS=true
3433

35-
# Context optimization (reduces token usage on long conversations)
36-
NADIRCLAW_OPTIMIZE=safe
37-
NADIRCLAW_OPTIMIZE_MAX_TURNS=40
34+
# Context optimization DISABLED — the optimizer strips tool_calls and
35+
# tool_call_id from messages, breaking tool-use conversations.
36+
# See: optimize_messages() converts messages to {"role","content"} only.
37+
NADIRCLAW_OPTIMIZE=off
3838

3939
# LiteLLM: merge consecutive user/tool blocks for Bedrock compatibility
40-
# Without this, OpenCode tool-use messages cause BadRequestError on Bedrock models
4140
LITELLM_MODIFY_PARAMS=true
4241

4342
# Server (localhost only)
4443
NADIRCLAW_PORT=4000
4544

4645
# Logging
4746
NADIRCLAW_LOG_DIR=~/.nadirclaw/logs
48-
NADIRCLAW_LOG_RAW=true
49-
LITELLM_LOG=DEBUG
47+
NADIRCLAW_LOG_RAW=false

docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ services:
88
- "127.0.0.1:4000:4000"
99
env_file:
1010
- config/nadirclaw.env
11+
- "${HOME}/.nadirclaw/mantle.env"
1112
volumes:
1213
# Mount AWS credentials (read-only)
1314
- "${HOME}/.aws:/root/.aws:ro"

opencode.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010
},
1111
"models": {
1212
"auto": {
13-
"name": "Auto (3-tier routing: Qwen3 30B / Mistral Large 3 / Kimi K2)"
13+
"name": "Auto (3-tier: MiniMax M2.1 / GLM 4.7 / GLM 5)"
1414
},
1515
"eco": {
16-
"name": "Budget (Qwen3 Coder 30B)"
16+
"name": "Budget (MiniMax M2.1)"
1717
},
1818
"premium": {
19-
"name": "Premium (Kimi K2 Thinking)"
19+
"name": "Premium (GLM 5)"
2020
}
2121
}
2222
}

0 commit comments

Comments
 (0)