1# SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
2#
3# SPDX-License-Identifier: Unlicense
4
5# Claude Code agent definition for synu
6# Provides model configuration for routing through Synthetic API
7
8# Source cache functions
9source (status dirname)/../_synu_cache.fish
10
11# Fallback defaults (used when no cache entry exists)
12set -g _synu_claude_fallback_opus "hf:moonshotai/Kimi-K2-Thinking"
13set -g _synu_claude_fallback_sonnet "hf:MiniMaxAI/MiniMax-M2"
14set -g _synu_claude_fallback_haiku "hf:deepseek-ai/DeepSeek-V3.1-Terminus"
15set -g _synu_claude_fallback_agent "hf:MiniMaxAI/MiniMax-M2"
16
17function _synu_claude_default --description "Get default model: _synu_claude_default slot"
18 set -l slot $argv[1]
19 set -l cached (_synu_cache_get claude $slot)
20 if test $status -eq 0
21 echo $cached
22 else
23 set -l var_name _synu_claude_fallback_$slot
24 echo $$var_name
25 end
26end
27
28function _synu_agent_claude_flags --description "Return argparse-compatible flag specification"
29 echo "L/large="
30 echo "l/light="
31 echo "o/opus="
32 echo "s/sonnet="
33 echo "H/haiku="
34 echo "a/agent="
35end
36
37function _synu_agent_claude_configure --description "Configure Claude Code environment variables"
38 # Parse flags passed from main synu
39 argparse 'L/large=' 'l/light=' 'o/opus=' 's/sonnet=' 'H/haiku=' 'a/agent=' -- $argv
40 or return 1
41
42 # Start with defaults (from cache or fallback)
43 set -l opus_model (_synu_claude_default opus)
44 set -l sonnet_model (_synu_claude_default sonnet)
45 set -l haiku_model (_synu_claude_default haiku)
46 set -l subagent_model (_synu_claude_default agent)
47
48 # Apply group overrides
49 if set -q _flag_large
50 set opus_model $_flag_large
51 set sonnet_model $_flag_large
52 set subagent_model $_flag_large
53 end
54
55 if set -q _flag_light
56 set haiku_model $_flag_light
57 end
58
59 # Apply specific overrides (take precedence over groups)
60 if set -q _flag_opus
61 set opus_model $_flag_opus
62 end
63 if set -q _flag_sonnet
64 set sonnet_model $_flag_sonnet
65 end
66 if set -q _flag_haiku
67 set haiku_model $_flag_haiku
68 end
69 if set -q _flag_agent
70 set subagent_model $_flag_agent
71 end
72
73 # Export environment variables for Claude Code
74 set -gx ANTHROPIC_BASE_URL "https://api.synthetic.new/anthropic"
75 set -gx ANTHROPIC_AUTH_TOKEN $SYNTHETIC_API_KEY
76 set -gx ANTHROPIC_DEFAULT_OPUS_MODEL $opus_model
77 set -gx ANTHROPIC_DEFAULT_SONNET_MODEL $sonnet_model
78 set -gx ANTHROPIC_DEFAULT_HAIKU_MODEL $haiku_model
79 set -gx CLAUDE_CODE_SUBAGENT_MODEL $subagent_model
80 set -gx CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC 1
81end
82
83function _synu_agent_claude_interactive --description "Interactive model selection using gum"
84 # Check for gum
85 if not command -q gum
86 echo "Error: gum is required for interactive mode. Install: https://github.com/charmbracelet/gum" >&2
87 return 1
88 end
89
90 # Fetch available models
91 set -l models_json (gum spin --spinner dot --title "Fetching models..." -- \
92 curl -s -H "Authorization: Bearer $SYNTHETIC_API_KEY" \
93 "https://api.synthetic.new/openai/v1/models")
94 or return 1
95
96 set -l model_names (echo $models_json | jq -r '.data[].name')
97 or return 1
98
99 # Prompt for groups vs individual
100 set -l mode (gum choose --limit 1 --header "How do you want to select models?" \
101 "Groups" "Individual models")
102 or return 1
103
104 # Build flags array
105 set -l flags
106
107 if test "$mode" = "Groups"
108 # Select which groups to override
109 set -l groups (gum choose --no-limit \
110 --header "Which group(s) do you want to override?" \
111 "Large (Opus, Sonnet, Sub-agent)" "Light (Haiku)")
112 or return 1
113
114 for group in $groups
115 if test "$group" = "Large (Opus, Sonnet, Sub-agent)"
116 set -l model_name (printf "%s\n" $model_names | \
117 gum filter --limit 1 --header "Select model for Large group" \
118 --placeholder "Filter models...")
119 or return 1
120 set -l model_id (echo $models_json | \
121 jq -r --arg name "$model_name" '.data[] | select(.name == $name) | .id')
122 if test -n "$model_id"
123 set flags $flags --large=$model_id
124 end
125 else if test "$group" = "Light (Haiku)"
126 set -l model_name (printf "%s\n" $model_names | \
127 gum filter --limit 1 --header "Select model for Light group" \
128 --placeholder "Filter models...")
129 or return 1
130 set -l model_id (echo $models_json | \
131 jq -r --arg name "$model_name" '.data[] | select(.name == $name) | .id')
132 if test -n "$model_id"
133 set flags $flags --light=$model_id
134 end
135 end
136 end
137 else
138 # Select which individual models to override
139 set -l models (gum choose --no-limit \
140 --header "Which model(s) do you want to override?" \
141 "Opus" "Sonnet" "Haiku" "Sub-agent")
142 or return 1
143
144 for model_type in $models
145 switch $model_type
146 case "Opus"
147 set -l model_name (printf "%s\n" $model_names | \
148 gum filter --limit 1 --header "Select Opus model" \
149 --placeholder "Filter models...")
150 or return 1
151 set -l model_id (echo $models_json | \
152 jq -r --arg name "$model_name" '.data[] | select(.name == $name) | .id')
153 if test -n "$model_id"
154 set flags $flags --opus=$model_id
155 end
156 case "Sonnet"
157 set -l model_name (printf "%s\n" $model_names | \
158 gum filter --limit 1 --header "Select Sonnet model" \
159 --placeholder "Filter models...")
160 or return 1
161 set -l model_id (echo $models_json | \
162 jq -r --arg name "$model_name" '.data[] | select(.name == $name) | .id')
163 if test -n "$model_id"
164 set flags $flags --sonnet=$model_id
165 end
166 case "Haiku"
167 set -l model_name (printf "%s\n" $model_names | \
168 gum filter --limit 1 --header "Select Haiku model" \
169 --placeholder "Filter models...")
170 or return 1
171 set -l model_id (echo $models_json | \
172 jq -r --arg name "$model_name" '.data[] | select(.name == $name) | .id')
173 if test -n "$model_id"
174 set flags $flags --haiku=$model_id
175 end
176 case "Sub-agent"
177 set -l model_name (printf "%s\n" $model_names | \
178 gum filter --limit 1 --header "Select Sub-agent model" \
179 --placeholder "Filter models...")
180 or return 1
181 set -l model_id (echo $models_json | \
182 jq -r --arg name "$model_name" '.data[] | select(.name == $name) | .id')
183 if test -n "$model_id"
184 set flags $flags --agent=$model_id
185 end
186 end
187 end
188 end
189
190 # Offer to save as defaults
191 if test (count $flags) -gt 0
192 if gum confirm "Save as default for 'claude'?"
193 for flag in $flags
194 # Parse --key=value format
195 set -l parts (string match -r '^--([^=]+)=(.+)$' $flag)
196 if test -n "$parts[2]"
197 set -l key $parts[2]
198 set -l value $parts[3]
199 # Expand group flags to individual slots
200 switch $key
201 case large
202 _synu_cache_set claude opus $value
203 _synu_cache_set claude sonnet $value
204 _synu_cache_set claude agent $value
205 case light
206 _synu_cache_set claude haiku $value
207 case '*'
208 _synu_cache_set claude $key $value
209 end
210 end
211 end
212 end
213 end
214
215 # Output flags for caller to use
216 echo $flags
217end