anurag008w commited on
Commit
d80a211
Β·
1 Parent(s): 0e6fb59

Add files via upload

Browse files
Files changed (1) hide show
  1. env-builder.js +2295 -0
env-builder.js ADDED
@@ -0,0 +1,2295 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const MODEL_CATALOGS = {
2
+ "LLM_MODEL": {
3
+ "Anthropic": [
4
+ "claude-opus-4-7",
5
+ "claude-opus-4-6",
6
+ "claude-opus-4-5",
7
+ "claude-opus-4-1",
8
+ "claude-sonnet-4-7",
9
+ "claude-sonnet-4-6",
10
+ "claude-sonnet-4-5",
11
+ "claude-haiku-4-5",
12
+ "claude-haiku-4-5-20251001",
13
+ "claude-haiku-3-5"
14
+ ],
15
+ "OpenAI": [
16
+ "gpt-5.4-pro",
17
+ "gpt-5.4",
18
+ "gpt-5.4-mini",
19
+ "gpt-5.4-nano",
20
+ "gpt-5.1",
21
+ "gpt-5",
22
+ "gpt-4.1",
23
+ "gpt-4.1-mini",
24
+ "gpt-4o",
25
+ "gpt-4o-mini",
26
+ "o3",
27
+ "o4-mini"
28
+ ],
29
+ "Gemini": [
30
+ "gemini-3.1-pro-preview",
31
+ "gemini-3.1-flash-preview",
32
+ "gemini-3-flash-preview",
33
+ "gemini-2.5-pro",
34
+ "gemini-2.5-flash",
35
+ "gemini-2.0-flash",
36
+ "gemini-flash-latest",
37
+ "gemini-pro-latest"
38
+ ],
39
+ "DeepSeek": [
40
+ "deepseek-v4-pro",
41
+ "deepseek-v4-flash",
42
+ "deepseek-v3.2",
43
+ "deepseek-chat",
44
+ "deepseek-reasoner",
45
+ "deepseek-r1",
46
+ "deepseek-r1-0528"
47
+ ],
48
+ "xAI": [
49
+ "grok-4.3",
50
+ "grok-4.1",
51
+ "grok-4",
52
+ "grok-3"
53
+ ],
54
+ "Groq": [
55
+ "groq/compound",
56
+ "groq/compound-mini",
57
+ "llama-3.1-8b-instant",
58
+ "llama-3.1-70b-versatile",
59
+ "llama-3.3-70b-versatile",
60
+ "meta-llama/llama-4-scout-17b-16e-instruct",
61
+ "openai/gpt-oss-20b",
62
+ "openai/gpt-oss-120b",
63
+ "qwen/qwen3-32b",
64
+ "mixtral-8x7b-32768"
65
+ ],
66
+ "Mistral": [
67
+ "mistral-large-latest",
68
+ "mistral-large-2",
69
+ "mistral-medium-3.5",
70
+ "mistral-small-latest",
71
+ "mistral-small-3.2",
72
+ "devstral-2",
73
+ "ocr-3-premier",
74
+ "voxtral-mini-transcribe-realtime",
75
+ "codestral-latest"
76
+ ],
77
+ "Cohere": [
78
+ "command-a",
79
+ "command-a-03-2025",
80
+ "command-a-translate-08-2025",
81
+ "command-a-reasoning-08-2025",
82
+ "command-a-vision-07-2025",
83
+ "command-r7b-12-2024",
84
+ "command-r-08-2024",
85
+ "command-r-plus-08-2024"
86
+ ],
87
+ "OpenRouter": [
88
+ "openrouter/free",
89
+ "openrouter/auto",
90
+ "anthropic/claude-opus-4-7",
91
+ "anthropic/claude-sonnet-4-6",
92
+ "anthropic/claude-haiku-4-5",
93
+ "openai/gpt-5.4",
94
+ "openai/gpt-4.1",
95
+ "openai/gpt-4o",
96
+ "openai/gpt-5.1",
97
+ "google/gemini-3.1-pro-preview",
98
+ "google/gemini-2.5-pro",
99
+ "deepseek/deepseek-v3.2",
100
+ "deepseek/deepseek-r1",
101
+ "moonshotai/kimi-k2.5",
102
+ "qwen/qwen3-32b",
103
+ "meta-llama/llama-3.3-70b-instruct"
104
+ ],
105
+ "Together": [
106
+ "moonshotai/Kimi-K2.5",
107
+ "deepseek-ai/DeepSeek-R1",
108
+ "Qwen/Qwen3-235B-A22B-Instruct-2507-tput",
109
+ "zai-org/GLM-5.1",
110
+ "google/gemma-4-31B-it",
111
+ "MiniMaxAI/MiniMax-M2.7",
112
+ "meta-llama/Llama-3.3-70B-Instruct-Turbo",
113
+ "openai/gpt-oss-20b",
114
+ "openai/gpt-oss-120b",
115
+ "mistralai/Mistral-Small-3.2-24B-Instruct-2506",
116
+ "moonshotai/Kimi-K2.5-Instruct"
117
+ ],
118
+ "OpenCode": [
119
+ "opencode/claude-opus-4-6",
120
+ "opencode/gpt-5.4",
121
+ "opencode-go/kimi-k2.5",
122
+ "opencode-go/qwen3-32b"
123
+ ],
124
+ "Cerebras": [
125
+ "cerebras/zai-glm-4.7",
126
+ "cerebras/deepseek-r1",
127
+ "cerebras/llama-4-scout-17b-16e-instruct",
128
+ "cerebras/qwen3-32b"
129
+ ],
130
+ "NVIDIA": [
131
+ "nvidia/nemotron-3-super-120b-a12b",
132
+ "nvidia/nemotron-4-340b-instruct",
133
+ "nvidia/llama-3.1-nemotron-70b-instruct"
134
+ ],
135
+ "KiloCode": [
136
+ "kilocode/anthropic/claude-opus-4.6",
137
+ "kilocode/anthropic/claude-sonnet-4.6",
138
+ "kilocode/openai/gpt-5.4",
139
+ "kilocode/google/gemini-2.5-pro"
140
+ ],
141
+ "Z.AI": [
142
+ "zai-org/GLM-5.1",
143
+ "zai-org/GLM-4.7",
144
+ "zai-org/GLM-4.5"
145
+ ],
146
+ "Moonshot": [
147
+ "moonshot/kimi-k2.5",
148
+ "moonshot/kimi-k2.5-thinking",
149
+ "moonshot/kimi-k2.5-coder"
150
+ ],
151
+ "MiniMax": [
152
+ "minimax/minimax-m2.7",
153
+ "minimax/minimax-m1.5",
154
+ "minimax/abab6.5s-chat"
155
+ ],
156
+ "Xiaomi": [
157
+ "xiaomi/mimo-v1",
158
+ "xiaomi/mimo-v2",
159
+ "xiaomi/mi-mo"
160
+ ],
161
+ "Volcano Engine": [
162
+ "volcengine/doubao-seed-1.6",
163
+ "volcengine/doubao-1.5-pro",
164
+ "volcengine/doubao-1.5-lite"
165
+ ],
166
+ "BytePlus": [
167
+ "byteplus/seed-1.6",
168
+ "byteplus/deepseek-v3.2",
169
+ "byteplus/doubao-seed-1.6"
170
+ ],
171
+ "Qianfan": [
172
+ "qianfan/ernie-4.5",
173
+ "qianfan/ernie-4.5-8k",
174
+ "qianfan/deepseek-v3.2",
175
+ "qianfan/ernie-x1"
176
+ ],
177
+ "ModelStudio": [
178
+ "modelstudio/qwen3-max",
179
+ "modelstudio/qwen3-coder",
180
+ "modelstudio/qwen3-32b"
181
+ ],
182
+ "Hugging Face": [
183
+ "meta-llama/Llama-3.3-70B-Instruct",
184
+ "Qwen/Qwen3-32B",
185
+ "google/gemma-4-31B-it",
186
+ "deepseek-ai/DeepSeek-V3.2",
187
+ "moonshotai/Kimi-K2.5"
188
+ ],
189
+ "Venice": [
190
+ "venice/gpt-5",
191
+ "venice/llama-3.3-70b",
192
+ "venice/deepseek-r1"
193
+ ],
194
+ "Synthetic": [
195
+ "synthetic/gpt-5",
196
+ "synthetic/claude-sonnet-4-6"
197
+ ],
198
+ "AI Gateway": [
199
+ "openai/gpt-5.4",
200
+ "anthropic/claude-sonnet-4-6",
201
+ "google/gemini-2.5-pro"
202
+ ],
203
+ "GitHub Copilot": [
204
+ "github-copilot/gpt-5",
205
+ "github-copilot/gpt-4.1",
206
+ "github-copilot/gpt-4o"
207
+ ],
208
+ "ZAI": [
209
+ "zai/glm-5",
210
+ "zai/glm-5-turbo",
211
+ "zai/glm-4.7",
212
+ "zai/glm-4.7-flash"
213
+ ],
214
+ "Kimi": [
215
+ "moonshot/kimi-k2.5",
216
+ "moonshot/kimi-k2.5-thinking"
217
+ ],
218
+ "HuggingFace": [
219
+ "huggingface/deepseek-ai/DeepSeek-R1",
220
+ "huggingface/meta-llama/Llama-3.3-70B-Instruct",
221
+ "huggingface/Qwen/Qwen3-32B"
222
+ ]
223
+ },
224
+ "OPENAI_MODELS": [
225
+ "gpt-5.4-pro",
226
+ "gpt-5.4",
227
+ "gpt-5.4-mini",
228
+ "gpt-5.4-nano",
229
+ "gpt-5.1",
230
+ "gpt-5",
231
+ "gpt-4.1",
232
+ "gpt-4.1-mini",
233
+ "gpt-4o",
234
+ "gpt-4o-mini",
235
+ "o3",
236
+ "o4-mini"
237
+ ],
238
+ "ANTHROPIC_MODELS": [
239
+ "anthropic/claude-opus-4-7",
240
+ "anthropic/claude-opus-4-6",
241
+ "anthropic/claude-opus-4-5",
242
+ "anthropic/claude-sonnet-4-6",
243
+ "anthropic/claude-sonnet-4-5",
244
+ "anthropic/claude-haiku-4-5"
245
+ ],
246
+ "GEMINI_MODELS": [
247
+ "google/gemini-3.1-pro-preview",
248
+ "google/gemini-3.1-flash-preview",
249
+ "google/gemini-3-flash-preview",
250
+ "google/gemini-2.5-pro",
251
+ "google/gemini-2.5-flash",
252
+ "google/gemini-2.0-flash"
253
+ ],
254
+ "DEEPSEEK_MODELS": [
255
+ "deepseek/deepseek-v4-pro",
256
+ "deepseek/deepseek-v4-flash",
257
+ "deepseek/deepseek-v3.2",
258
+ "deepseek/deepseek-chat",
259
+ "deepseek/deepseek-reasoner",
260
+ "deepseek/deepseek-r1",
261
+ "deepseek/deepseek-r1-0528"
262
+ ],
263
+ "OPENROUTER_MODELS": [
264
+ "openrouter/free",
265
+ "openrouter/auto",
266
+ "openrouter/anthropic/claude-sonnet-4-6",
267
+ "openrouter/anthropic/claude-opus-4-7",
268
+ "openrouter/anthropic/claude-haiku-4-5",
269
+ "openrouter/openai/gpt-5.4",
270
+ "openrouter/openai/gpt-4.1",
271
+ "openrouter/openai/gpt-4o",
272
+ "openrouter/openai/gpt-5.1",
273
+ "openrouter/google/gemini-3.1-pro-preview",
274
+ "openrouter/google/gemini-2.5-pro",
275
+ "openrouter/deepseek/deepseek-v3.2",
276
+ "openrouter/deepseek/deepseek-r1",
277
+ "openrouter/moonshotai/kimi-k2.5",
278
+ "openrouter/qwen/qwen3-32b"
279
+ ],
280
+ "GROQ_MODELS": [
281
+ "groq/compound",
282
+ "groq/compound-mini",
283
+ "llama-3.1-8b-instant",
284
+ "llama-3.1-70b-versatile",
285
+ "llama-3.3-70b-versatile",
286
+ "openai/gpt-oss-20b",
287
+ "openai/gpt-oss-120b",
288
+ "meta-llama/llama-4-scout-17b-16e-instruct",
289
+ "qwen/qwen3-32b",
290
+ "mixtral-8x7b-32768"
291
+ ],
292
+ "MISTRAL_MODELS": [
293
+ "mistral-large-latest",
294
+ "mistral-large-2",
295
+ "mistral-medium-3.5",
296
+ "mistral-small-latest",
297
+ "mistral-small-3.2",
298
+ "devstral-2",
299
+ "ocr-3-premier",
300
+ "voxtral-mini-transcribe-realtime",
301
+ "codestral-latest"
302
+ ],
303
+ "XAI_MODELS": [
304
+ "grok-4.3",
305
+ "grok-4.1",
306
+ "grok-4",
307
+ "grok-3"
308
+ ],
309
+ "COHERE_MODELS": [
310
+ "command-a",
311
+ "command-a-03-2025",
312
+ "command-a-translate-08-2025",
313
+ "command-a-reasoning-08-2025",
314
+ "command-a-vision-07-2025",
315
+ "command-r7b-12-2024",
316
+ "command-r-08-2024",
317
+ "command-r-plus-08-2024"
318
+ ],
319
+ "TOGETHER_MODELS": [
320
+ "moonshotai/Kimi-K2.5",
321
+ "deepseek-ai/DeepSeek-R1",
322
+ "Qwen/Qwen3-235B-A22B-Instruct-2507-tput",
323
+ "zai-org/GLM-5.1",
324
+ "google/gemma-4-31B-it",
325
+ "MiniMaxAI/MiniMax-M2.7",
326
+ "meta-llama/Llama-3.3-70B-Instruct-Turbo",
327
+ "openai/gpt-oss-20b",
328
+ "openai/gpt-oss-120b",
329
+ "mistralai/Mistral-Small-3.2-24B-Instruct-2506",
330
+ "moonshotai/Kimi-K2.5-Instruct"
331
+ ],
332
+ "CEREBRAS_MODELS": [
333
+ "cerebras/zai-glm-4.7",
334
+ "cerebras/deepseek-r1",
335
+ "cerebras/llama-4-scout-17b-16e-instruct",
336
+ "cerebras/qwen3-32b"
337
+ ],
338
+ "NVIDIA_MODELS": [
339
+ "nvidia/nemotron-3-super-120b-a12b",
340
+ "nvidia/nemotron-4-340b-instruct",
341
+ "nvidia/llama-3.1-nemotron-70b-instruct"
342
+ ],
343
+ "KILOCODE_MODELS": [
344
+ "kilocode/anthropic/claude-opus-4.6",
345
+ "kilocode/anthropic/claude-sonnet-4.6",
346
+ "kilocode/openai/gpt-5.4",
347
+ "kilocode/google/gemini-2.5-pro"
348
+ ],
349
+ "OPENCODE_MODELS": [
350
+ "opencode/claude-opus-4-6",
351
+ "opencode/gpt-5.4",
352
+ "opencode-go/kimi-k2.5",
353
+ "opencode-go/qwen3-32b"
354
+ ],
355
+ "ZAI_MODELS": [
356
+ "zai/glm-5",
357
+ "zai/glm-5-turbo",
358
+ "zai/glm-4.7",
359
+ "zai/glm-4.7-flash"
360
+ ],
361
+ "MOONSHOT_MODELS": [
362
+ "moonshot/kimi-k2.5",
363
+ "moonshot/kimi-k2.5-thinking",
364
+ "moonshot/kimi-k2.5-coder"
365
+ ],
366
+ "MINIMAX_MODELS": [
367
+ "minimax/minimax-m2.7",
368
+ "minimax/minimax-m1.5",
369
+ "minimax/abab6.5s-chat"
370
+ ],
371
+ "XIAOMI_MODELS": [
372
+ "xiaomi/mimo-v1",
373
+ "xiaomi/mimo-v2",
374
+ "xiaomi/mi-mo"
375
+ ],
376
+ "VOLCANO_ENGINE_MODELS": [
377
+ "volcengine/doubao-seed-1.6",
378
+ "volcengine/doubao-1.5-pro",
379
+ "volcengine/doubao-1.5-lite"
380
+ ],
381
+ "BYTEPLUS_MODELS": [
382
+ "byteplus/seed-1.6",
383
+ "byteplus/deepseek-v3.2",
384
+ "byteplus/doubao-seed-1.6"
385
+ ],
386
+ "QIANFAN_MODELS": [
387
+ "qianfan/ernie-4.5",
388
+ "qianfan/ernie-4.5-8k",
389
+ "qianfan/deepseek-v3.2",
390
+ "qianfan/ernie-x1"
391
+ ],
392
+ "MODELSTUDIO_MODELS": [
393
+ "modelstudio/qwen3-max",
394
+ "modelstudio/qwen3-coder",
395
+ "modelstudio/qwen3-32b"
396
+ ],
397
+ "KIMI_MODELS": [
398
+ "moonshot/kimi-k2.5",
399
+ "moonshot/kimi-k2.5-thinking",
400
+ "moonshot/kimi-k2.5-coder"
401
+ ],
402
+ "HUGGINGFACE_MODELS": [
403
+ "huggingface/deepseek-ai/DeepSeek-R1",
404
+ "huggingface/meta-llama/Llama-3.3-70B-Instruct",
405
+ "huggingface/Qwen/Qwen3-32B",
406
+ "huggingface/mistralai/Mistral-Small-3.2-24B-Instruct-2506"
407
+ ],
408
+ "GITHUB_COPILOT_MODELS": [
409
+ "github-copilot/gpt-5",
410
+ "github-copilot/gpt-4.1",
411
+ "github-copilot/gpt-4o"
412
+ ],
413
+ "AI_GATEWAY_MODELS": [],
414
+ "VENICE_MODELS": [],
415
+ "SYNTHETIC_MODELS": []
416
+ };
417
+
418
+ const FIELDS = [
419
+ {
420
+ "g": "Core",
421
+ "icon": "⚑",
422
+ "k": "LLM_MODEL",
423
+ "lbl": "Default model ID",
424
+ "type": "model",
425
+ "options_key": "LLM_MODEL",
426
+ "ph": "choose a provider model",
427
+ "common": 1
428
+ },
429
+ {
430
+ "g": "Core",
431
+ "icon": "⚑",
432
+ "k": "LLM_API_KEY",
433
+ "lbl": "Primary provider API key",
434
+ "type": "password",
435
+ "secret": 1,
436
+ "ph": "sk-...",
437
+ "common": 1
438
+ },
439
+ {
440
+ "g": "Core",
441
+ "icon": "⚑",
442
+ "k": "GATEWAY_TOKEN",
443
+ "lbl": "Control UI gateway token",
444
+ "type": "password",
445
+ "secret": 1,
446
+ "common": 1
447
+ },
448
+ {
449
+ "g": "Core",
450
+ "icon": "⚑",
451
+ "k": "OPENCLAW_PASSWORD",
452
+ "lbl": "Optional password auth",
453
+ "type": "password",
454
+ "secret": 1
455
+ },
456
+ {
457
+ "g": "Core",
458
+ "icon": "⚑",
459
+ "k": "OPENCLAW_VERSION",
460
+ "lbl": "Pin OpenClaw version",
461
+ "type": "text",
462
+ "ph": "latest"
463
+ },
464
+ {
465
+ "g": "Core",
466
+ "icon": "⚑",
467
+ "k": "LLM_API_KEY_FALLBACK_ENABLED",
468
+ "lbl": "Allow global LLM_API_KEY fallback",
469
+ "type": "toggle",
470
+ "ph": "true"
471
+ },
472
+ {
473
+ "g": "Core",
474
+ "icon": "⚑",
475
+ "k": "DEV_MODE",
476
+ "lbl": "Enable dev mode",
477
+ "type": "toggle",
478
+ "ph": "false",
479
+ "common": 1
480
+ },
481
+ {
482
+ "g": "Core",
483
+ "icon": "⚑",
484
+ "k": "HUGGINGCLAW_JUPYTER_ENABLED",
485
+ "lbl": "Enable Jupyter terminal",
486
+ "type": "toggle",
487
+ "ph": "false",
488
+ "common": 1
489
+ },
490
+ {
491
+ "g": "Core",
492
+ "icon": "⚑",
493
+ "k": "DEVDATA",
494
+ "lbl": "DevData switch",
495
+ "type": "toggle",
496
+ "ph": "on",
497
+ "common": 1
498
+ },
499
+ {
500
+ "g": "Core",
501
+ "icon": "⚑",
502
+ "k": "DEVDATA_DATASET_NAME",
503
+ "lbl": "DevData dataset name",
504
+ "type": "text",
505
+ "ph": "huggingclaw-devdata",
506
+ "common": 1
507
+ },
508
+ {
509
+ "g": "Core",
510
+ "icon": "⚑",
511
+ "k": "DEVDATA_SYNC_INTERVAL",
512
+ "lbl": "DevData sync interval (seconds)",
513
+ "type": "number",
514
+ "ph": "180"
515
+ },
516
+ {
517
+ "g": "Core",
518
+ "icon": "⚑",
519
+ "k": "WHATSAPP_ENABLED",
520
+ "lbl": "Enable WhatsApp pairing",
521
+ "type": "toggle",
522
+ "ph": "false",
523
+ "common": 1
524
+ },
525
+ {
526
+ "g": "Core",
527
+ "icon": "⚑",
528
+ "k": "HUGGINGCLAW_CAPTURE_DISABLE",
529
+ "lbl": "Disable capture wrapper",
530
+ "type": "toggle",
531
+ "ph": "false"
532
+ },
533
+ {
534
+ "g": "Core",
535
+ "icon": "⚑",
536
+ "k": "HUGGINGCLAW_STARTUP_STRICT",
537
+ "lbl": "Stop on startup failure",
538
+ "type": "toggle",
539
+ "ph": "false"
540
+ },
541
+ {
542
+ "g": "Core",
543
+ "icon": "⚑",
544
+ "k": "HUGGINGCLAW_RUN",
545
+ "lbl": "Startup command (one-liner)",
546
+ "type": "textarea"
547
+ },
548
+ {
549
+ "g": "Core",
550
+ "icon": "⚑",
551
+ "k": "HUGGINGCLAW_STARTUP_COMMANDS",
552
+ "lbl": "Multiline startup commands",
553
+ "type": "textarea"
554
+ },
555
+ {
556
+ "g": "Core",
557
+ "icon": "⚑",
558
+ "k": "HUGGINGCLAW_STARTUP_SCRIPT",
559
+ "lbl": "Startup shell script",
560
+ "type": "textarea"
561
+ },
562
+ {
563
+ "g": "Core",
564
+ "icon": "⚑",
565
+ "k": "HUGGINGCLAW_STARTUP_SCRIPT_B64",
566
+ "lbl": "Startup script (base64)",
567
+ "type": "textarea"
568
+ },
569
+ {
570
+ "g": "Core",
571
+ "icon": "⚑",
572
+ "k": "HUGGINGCLAW_APT_PACKAGES",
573
+ "lbl": "APT packages to install",
574
+ "type": "textarea"
575
+ },
576
+ {
577
+ "g": "Core",
578
+ "icon": "⚑",
579
+ "k": "HUGGINGCLAW_PIP_PACKAGES",
580
+ "lbl": "Pip packages to install",
581
+ "type": "textarea"
582
+ },
583
+ {
584
+ "g": "Core",
585
+ "icon": "⚑",
586
+ "k": "HUGGINGCLAW_NPM_PACKAGES",
587
+ "lbl": "NPM packages to install",
588
+ "type": "textarea"
589
+ },
590
+ {
591
+ "g": "Core",
592
+ "icon": "⚑",
593
+ "k": "HUGGINGCLAW_OPENCLAW_PLUGINS",
594
+ "lbl": "OpenClaw plugins to load",
595
+ "type": "textarea"
596
+ },
597
+ {
598
+ "g": "Core",
599
+ "icon": "⚑",
600
+ "k": "ALLOWED_ORIGINS",
601
+ "lbl": "Allowed CORS origins",
602
+ "type": "textarea"
603
+ },
604
+ {
605
+ "g": "Core",
606
+ "icon": "⚑",
607
+ "k": "TRUSTED_PROXIES",
608
+ "lbl": "Trusted proxy CIDRs",
609
+ "type": "textarea"
610
+ },
611
+ {
612
+ "g": "Core",
613
+ "icon": "⚑",
614
+ "k": "WEBHOOK_URL",
615
+ "lbl": "Webhook URL",
616
+ "type": "text",
617
+ "ph": "https://..."
618
+ },
619
+ {
620
+ "g": "Core",
621
+ "icon": "⚑",
622
+ "k": "WS_MIN_PROTOCOL",
623
+ "lbl": "Min WebSocket protocol",
624
+ "type": "number",
625
+ "ph": "1"
626
+ },
627
+ {
628
+ "g": "Core",
629
+ "icon": "⚑",
630
+ "k": "WS_MAX_PROTOCOL",
631
+ "lbl": "Max WebSocket protocol",
632
+ "type": "number",
633
+ "ph": "5"
634
+ },
635
+ {
636
+ "g": "Core",
637
+ "icon": "⚑",
638
+ "k": "GATEWAY_MAX_RESTARTS",
639
+ "lbl": "Gateway max restarts",
640
+ "type": "number",
641
+ "ph": "10"
642
+ },
643
+ {
644
+ "g": "Core",
645
+ "icon": "⚑",
646
+ "k": "GATEWAY_READY_TIMEOUT",
647
+ "lbl": "Gateway ready timeout",
648
+ "type": "number",
649
+ "ph": "90"
650
+ },
651
+ {
652
+ "g": "Core",
653
+ "icon": "⚑",
654
+ "k": "GATEWAY_RESTART_DELAY",
655
+ "lbl": "Gateway restart delay",
656
+ "type": "number",
657
+ "ph": "5"
658
+ },
659
+ {
660
+ "g": "Core",
661
+ "icon": "⚑",
662
+ "k": "GATEWAY_VERBOSE",
663
+ "lbl": "Verbose gateway logs",
664
+ "type": "toggle",
665
+ "ph": "false"
666
+ },
667
+ {
668
+ "g": "Core",
669
+ "icon": "⚑",
670
+ "k": "OPENCLAW_CONSOLE_LOG_LEVEL",
671
+ "lbl": "Console log level",
672
+ "type": "select",
673
+ "options": [
674
+ "debug",
675
+ "info",
676
+ "warn",
677
+ "error"
678
+ ],
679
+ "ph": "info"
680
+ },
681
+ {
682
+ "g": "Core",
683
+ "icon": "⚑",
684
+ "k": "OPENCLAW_FILE_LOG_LEVEL",
685
+ "lbl": "File log level",
686
+ "type": "select",
687
+ "options": [
688
+ "debug",
689
+ "info",
690
+ "warn",
691
+ "error"
692
+ ],
693
+ "ph": "info"
694
+ },
695
+ {
696
+ "g": "Core",
697
+ "icon": "⚑",
698
+ "k": "OPENCLAW_CONSOLE_LOG_STYLE",
699
+ "lbl": "Console log style",
700
+ "type": "select",
701
+ "options": [
702
+ "pretty",
703
+ "json",
704
+ "compact"
705
+ ],
706
+ "ph": "pretty"
707
+ },
708
+ {
709
+ "g": "Core",
710
+ "icon": "⚑",
711
+ "k": "BROWSER_PLUGIN_MODE",
712
+ "lbl": "Browser plugin mode",
713
+ "type": "select",
714
+ "options": [
715
+ "auto",
716
+ "enabled",
717
+ "disabled"
718
+ ],
719
+ "ph": "auto"
720
+ },
721
+ {
722
+ "g": "Core",
723
+ "icon": "⚑",
724
+ "k": "ACP_PLUGIN_MODE",
725
+ "lbl": "ACP plugin mode",
726
+ "type": "select",
727
+ "options": [
728
+ "auto",
729
+ "enabled",
730
+ "disabled"
731
+ ],
732
+ "ph": "auto"
733
+ },
734
+ {
735
+ "g": "Core",
736
+ "icon": "⚑",
737
+ "k": "CLOUDFLARE_PROXY_DEBUG",
738
+ "lbl": "Cloudflare proxy debug",
739
+ "type": "toggle",
740
+ "ph": "false"
741
+ },
742
+ {
743
+ "g": "Core",
744
+ "icon": "⚑",
745
+ "k": "CLOUDFLARE_KEEPALIVE_ENABLED",
746
+ "lbl": "Enable keep-awake worker",
747
+ "type": "toggle",
748
+ "ph": "true"
749
+ },
750
+ {
751
+ "g": "Core",
752
+ "icon": "⚑",
753
+ "k": "CLOUDFLARE_PROXY_URL",
754
+ "lbl": "Proxy worker URL",
755
+ "type": "text",
756
+ "ph": "https://your-proxy.workers.dev",
757
+ "common": 1
758
+ },
759
+ {
760
+ "g": "Core",
761
+ "icon": "⚑",
762
+ "k": "CLOUDFLARE_PROXY_SECRET",
763
+ "lbl": "Proxy shared secret",
764
+ "type": "password",
765
+ "secret": 1
766
+ },
767
+ {
768
+ "g": "Core",
769
+ "icon": "⚑",
770
+ "k": "CLOUDFLARE_PROXY_DOMAINS",
771
+ "lbl": "Extra domains to proxy",
772
+ "type": "textarea",
773
+ "ph": "api.sendgrid.com,slack.com"
774
+ },
775
+ {
776
+ "g": "Core",
777
+ "icon": "⚑",
778
+ "k": "CLOUDFLARE_WORKERS_TOKEN",
779
+ "lbl": "Workers API token",
780
+ "type": "password",
781
+ "secret": 1,
782
+ "common": 1
783
+ },
784
+ {
785
+ "g": "Core",
786
+ "icon": "⚑",
787
+ "k": "HF_USERNAME",
788
+ "lbl": "Hugging Face username",
789
+ "type": "text",
790
+ "common": 1
791
+ },
792
+ {
793
+ "g": "Core",
794
+ "icon": "⚑",
795
+ "k": "HF_TOKEN",
796
+ "lbl": "HF write token",
797
+ "type": "password",
798
+ "secret": 1,
799
+ "common": 1
800
+ },
801
+ {
802
+ "g": "Core",
803
+ "icon": "⚑",
804
+ "k": "BACKUP_DATASET_NAME",
805
+ "lbl": "Backup dataset name",
806
+ "type": "text",
807
+ "ph": "huggingclaw-backup",
808
+ "common": 1
809
+ },
810
+ {
811
+ "g": "Core",
812
+ "icon": "⚑",
813
+ "k": "SYNC_INTERVAL",
814
+ "lbl": "Sync interval (seconds)",
815
+ "type": "number",
816
+ "ph": "180",
817
+ "common": 1
818
+ },
819
+ {
820
+ "g": "Core",
821
+ "icon": "⚑",
822
+ "k": "JUPYTER_TOKEN",
823
+ "lbl": "Jupyter access token",
824
+ "type": "password",
825
+ "secret": 1,
826
+ "ph": "huggingface",
827
+ "common": 1
828
+ },
829
+ {
830
+ "g": "Core",
831
+ "icon": "⚑",
832
+ "k": "KEEP_ALIVE_INTERVAL",
833
+ "lbl": "Keep-alive ping interval (seconds)",
834
+ "type": "number",
835
+ "ph": "300",
836
+ "common": 1
837
+ },
838
+ {
839
+ "g": "Core",
840
+ "icon": "⚑",
841
+ "k": "OPENCLAW_DISABLE_BONJOUR",
842
+ "lbl": "Disable Bonjour/mDNS discovery",
843
+ "type": "toggle",
844
+ "ph": "false"
845
+ },
846
+ {
847
+ "g": "Core",
848
+ "icon": "⚑",
849
+ "k": "OPENCLAW_RUNTIME_VERSION",
850
+ "lbl": "Pin runtime version",
851
+ "type": "text",
852
+ "ph": "latest"
853
+ },
854
+ {
855
+ "g": "Core",
856
+ "icon": "⚑",
857
+ "k": "OPENCLAW_DISPLAY_VERSION",
858
+ "lbl": "Display version label",
859
+ "type": "text",
860
+ "ph": ""
861
+ },
862
+ {
863
+ "g": "Integrations",
864
+ "icon": "πŸ”Œ",
865
+ "k": "CLOUDFLARE_ACCOUNT_ID",
866
+ "lbl": "Cloudflare account ID",
867
+ "type": "text",
868
+ "ph": "account-id"
869
+ },
870
+ {
871
+ "g": "Integrations",
872
+ "icon": "πŸ”Œ",
873
+ "k": "CLOUDFLARE_WORKER_NAME",
874
+ "lbl": "Outbound proxy worker name",
875
+ "type": "text",
876
+ "ph": "huggingclaw-proxy"
877
+ },
878
+ {
879
+ "g": "Integrations",
880
+ "icon": "πŸ”Œ",
881
+ "k": "CLOUDFLARE_KEEPALIVE_URL",
882
+ "lbl": "Keepalive worker URL",
883
+ "type": "text",
884
+ "ph": "https://your-worker.workers.dev"
885
+ },
886
+ {
887
+ "g": "Integrations",
888
+ "icon": "πŸ”Œ",
889
+ "k": "CLOUDFLARE_KEEPALIVE_WORKER_NAME",
890
+ "lbl": "Keepalive worker name",
891
+ "type": "text",
892
+ "ph": "huggingclaw-keepalive"
893
+ },
894
+ {
895
+ "g": "Integrations",
896
+ "icon": "πŸ”Œ",
897
+ "k": "CLOUDFLARE_KEEPALIVE_CRON",
898
+ "lbl": "Keepalive cron schedule",
899
+ "type": "text",
900
+ "ph": "*/5 * * * *"
901
+ },
902
+ {
903
+ "g": "Integrations",
904
+ "icon": "πŸ”Œ",
905
+ "k": "TELEGRAM_API_ROOT",
906
+ "lbl": "Telegram API root override",
907
+ "type": "text",
908
+ "ph": "https://api.telegram.org"
909
+ },
910
+ {
911
+ "g": "Runtime",
912
+ "icon": "βš™οΈ",
913
+ "k": "OPENCLAW_CONFIG_WATCH_INTERVAL",
914
+ "lbl": "Config watch interval (seconds)",
915
+ "type": "number",
916
+ "ph": "1"
917
+ },
918
+ {
919
+ "g": "Runtime",
920
+ "icon": "βš™οΈ",
921
+ "k": "OPENCLAW_CONFIG_SETTLE_SECONDS",
922
+ "lbl": "Config settle window (seconds)",
923
+ "type": "number",
924
+ "ph": "3"
925
+ },
926
+ {
927
+ "g": "Runtime",
928
+ "icon": "βš™οΈ",
929
+ "k": "JUPYTER_ROOT_DIR",
930
+ "lbl": "Jupyter root directory",
931
+ "type": "text",
932
+ "ph": "/home/node"
933
+ },
934
+ {
935
+ "g": "Backup",
936
+ "icon": "πŸ’Ύ",
937
+ "k": "WORKSPACE_GIT_USER",
938
+ "lbl": "Workspace git author email",
939
+ "type": "text",
940
+ "ph": "openclaw@example.com"
941
+ },
942
+ {
943
+ "g": "Backup",
944
+ "icon": "πŸ’Ύ",
945
+ "k": "WORKSPACE_GIT_NAME",
946
+ "lbl": "Workspace git author name",
947
+ "type": "text",
948
+ "ph": "OpenClaw Bot"
949
+ },
950
+ {
951
+ "g": "Provider Keys",
952
+ "icon": "πŸ”‘",
953
+ "k": "ANTHROPIC_API_KEY",
954
+ "lbl": "Anthropic (Claude)",
955
+ "type": "password",
956
+ "secret": 1,
957
+ "common": 0
958
+ },
959
+ {
960
+ "g": "Provider Keys",
961
+ "icon": "πŸ”‘",
962
+ "k": "OPENAI_API_KEY",
963
+ "lbl": "OpenAI (GPT)",
964
+ "type": "password",
965
+ "secret": 1,
966
+ "common": 0
967
+ },
968
+ {
969
+ "g": "Provider Keys",
970
+ "icon": "πŸ”‘",
971
+ "k": "GOOGLE_API_KEY",
972
+ "lbl": "Google AI Studio",
973
+ "type": "password",
974
+ "secret": 1,
975
+ "common": 0
976
+ },
977
+ {
978
+ "g": "Provider Keys",
979
+ "icon": "πŸ”‘",
980
+ "k": "GEMINI_API_KEY",
981
+ "lbl": "Google Gemini",
982
+ "type": "password",
983
+ "secret": 1,
984
+ "common": 0
985
+ },
986
+ {
987
+ "g": "Provider Keys",
988
+ "icon": "πŸ”‘",
989
+ "k": "DEEPSEEK_API_KEY",
990
+ "lbl": "DeepSeek",
991
+ "type": "password",
992
+ "secret": 1,
993
+ "common": 0
994
+ },
995
+ {
996
+ "g": "Provider Keys",
997
+ "icon": "πŸ”‘",
998
+ "k": "OPENROUTER_API_KEY",
999
+ "lbl": "OpenRouter",
1000
+ "type": "password",
1001
+ "secret": 1,
1002
+ "common": 1
1003
+ },
1004
+ {
1005
+ "g": "Provider Keys",
1006
+ "icon": "πŸ”‘",
1007
+ "k": "OPENCODE_API_KEY",
1008
+ "lbl": "OpenCode",
1009
+ "type": "password",
1010
+ "secret": 1,
1011
+ "common": 0
1012
+ },
1013
+ {
1014
+ "g": "Provider Keys",
1015
+ "icon": "πŸ”‘",
1016
+ "k": "KILOCODE_API_KEY",
1017
+ "lbl": "KiloCode",
1018
+ "type": "password",
1019
+ "secret": 1,
1020
+ "common": 0
1021
+ },
1022
+ {
1023
+ "g": "Provider Keys",
1024
+ "icon": "πŸ”‘",
1025
+ "k": "ZAI_API_KEY",
1026
+ "lbl": "Z.ai / GLM",
1027
+ "type": "password",
1028
+ "secret": 1,
1029
+ "common": 0
1030
+ },
1031
+ {
1032
+ "g": "Provider Keys",
1033
+ "icon": "πŸ”‘",
1034
+ "k": "MOONSHOT_API_KEY",
1035
+ "lbl": "Moonshot / Kimi",
1036
+ "type": "password",
1037
+ "secret": 1,
1038
+ "common": 0
1039
+ },
1040
+ {
1041
+ "g": "Provider Keys",
1042
+ "icon": "πŸ”‘",
1043
+ "k": "MINIMAX_API_KEY",
1044
+ "lbl": "MiniMax",
1045
+ "type": "password",
1046
+ "secret": 1,
1047
+ "common": 0
1048
+ },
1049
+ {
1050
+ "g": "Provider Keys",
1051
+ "icon": "πŸ”‘",
1052
+ "k": "XIAOMI_API_KEY",
1053
+ "lbl": "Xiaomi / MiMo",
1054
+ "type": "password",
1055
+ "secret": 1,
1056
+ "common": 0
1057
+ },
1058
+ {
1059
+ "g": "Provider Keys",
1060
+ "icon": "πŸ”‘",
1061
+ "k": "VOLCANO_ENGINE_API_KEY",
1062
+ "lbl": "Volcengine / Doubao",
1063
+ "type": "password",
1064
+ "secret": 1,
1065
+ "common": 0
1066
+ },
1067
+ {
1068
+ "g": "Provider Keys",
1069
+ "icon": "πŸ”‘",
1070
+ "k": "BYTEPLUS_API_KEY",
1071
+ "lbl": "BytePlus",
1072
+ "type": "password",
1073
+ "secret": 1,
1074
+ "common": 0
1075
+ },
1076
+ {
1077
+ "g": "Provider Keys",
1078
+ "icon": "πŸ”‘",
1079
+ "k": "MISTRAL_API_KEY",
1080
+ "lbl": "Mistral",
1081
+ "type": "password",
1082
+ "secret": 1,
1083
+ "common": 0
1084
+ },
1085
+ {
1086
+ "g": "Provider Keys",
1087
+ "icon": "πŸ”‘",
1088
+ "k": "XAI_API_KEY",
1089
+ "lbl": "xAI (Grok)",
1090
+ "type": "password",
1091
+ "secret": 1,
1092
+ "common": 0
1093
+ },
1094
+ {
1095
+ "g": "Provider Keys",
1096
+ "icon": "πŸ”‘",
1097
+ "k": "NVIDIA_API_KEY",
1098
+ "lbl": "NVIDIA",
1099
+ "type": "password",
1100
+ "secret": 1,
1101
+ "common": 0
1102
+ },
1103
+ {
1104
+ "g": "Provider Keys",
1105
+ "icon": "πŸ”‘",
1106
+ "k": "GROQ_API_KEY",
1107
+ "lbl": "Groq",
1108
+ "type": "password",
1109
+ "secret": 1,
1110
+ "common": 0
1111
+ },
1112
+ {
1113
+ "g": "Provider Keys",
1114
+ "icon": "πŸ”‘",
1115
+ "k": "COHERE_API_KEY",
1116
+ "lbl": "Cohere",
1117
+ "type": "password",
1118
+ "secret": 1,
1119
+ "common": 0
1120
+ },
1121
+ {
1122
+ "g": "Provider Keys",
1123
+ "icon": "πŸ”‘",
1124
+ "k": "TOGETHER_API_KEY",
1125
+ "lbl": "Together AI",
1126
+ "type": "password",
1127
+ "secret": 1,
1128
+ "common": 0
1129
+ },
1130
+ {
1131
+ "g": "Provider Keys",
1132
+ "icon": "πŸ”‘",
1133
+ "k": "CEREBRAS_API_KEY",
1134
+ "lbl": "Cerebras",
1135
+ "type": "password",
1136
+ "secret": 1,
1137
+ "common": 0
1138
+ },
1139
+ {
1140
+ "g": "Provider Keys",
1141
+ "icon": "πŸ”‘",
1142
+ "k": "QIANFAN_API_KEY",
1143
+ "lbl": "Qianfan",
1144
+ "type": "password",
1145
+ "secret": 1,
1146
+ "common": 0
1147
+ },
1148
+ {
1149
+ "g": "Provider Keys",
1150
+ "icon": "πŸ”‘",
1151
+ "k": "MODELSTUDIO_API_KEY",
1152
+ "lbl": "ModelStudio",
1153
+ "type": "password",
1154
+ "secret": 1,
1155
+ "common": 0
1156
+ },
1157
+ {
1158
+ "g": "Provider Keys",
1159
+ "icon": "πŸ”‘",
1160
+ "k": "KIMI_API_KEY",
1161
+ "lbl": "Kimi",
1162
+ "type": "password",
1163
+ "secret": 1,
1164
+ "common": 0
1165
+ },
1166
+ {
1167
+ "g": "Provider Keys",
1168
+ "icon": "πŸ”‘",
1169
+ "k": "HUGGINGFACE_HUB_TOKEN",
1170
+ "lbl": "Hugging Face token",
1171
+ "type": "password",
1172
+ "secret": 1,
1173
+ "common": 0
1174
+ },
1175
+ {
1176
+ "g": "Provider Keys",
1177
+ "icon": "πŸ”‘",
1178
+ "k": "COPILOT_GITHUB_TOKEN",
1179
+ "lbl": "GitHub Copilot",
1180
+ "type": "password",
1181
+ "secret": 1,
1182
+ "common": 0
1183
+ },
1184
+ {
1185
+ "g": "Provider Keys",
1186
+ "icon": "πŸ”‘",
1187
+ "k": "VENICE_API_KEY",
1188
+ "lbl": "Venice",
1189
+ "type": "password",
1190
+ "secret": 1,
1191
+ "common": 0
1192
+ },
1193
+ {
1194
+ "g": "Provider Keys",
1195
+ "icon": "πŸ”‘",
1196
+ "k": "SYNTHETIC_API_KEY",
1197
+ "lbl": "Synthetic",
1198
+ "type": "password",
1199
+ "secret": 1,
1200
+ "common": 0
1201
+ },
1202
+ {
1203
+ "g": "Provider Keys",
1204
+ "icon": "πŸ”‘",
1205
+ "k": "AI_GATEWAY_API_KEY",
1206
+ "lbl": "AI Gateway",
1207
+ "type": "password",
1208
+ "secret": 1,
1209
+ "common": 0
1210
+ },
1211
+ {
1212
+ "g": "Provider Keys",
1213
+ "icon": "πŸ”‘",
1214
+ "k": "CLOUDFLARE_API_TOKEN",
1215
+ "lbl": "Cloudflare API token",
1216
+ "type": "password",
1217
+ "secret": 1,
1218
+ "common": 0
1219
+ },
1220
+ {
1221
+ "g": "Rotation Pools",
1222
+ "icon": "πŸ”„",
1223
+ "k": "ANTHROPIC_API_KEYS",
1224
+ "lbl": "Anthropic pool (comma-sep)",
1225
+ "type": "text"
1226
+ },
1227
+ {
1228
+ "g": "Rotation Pools",
1229
+ "icon": "πŸ”„",
1230
+ "k": "OPENAI_API_KEYS",
1231
+ "lbl": "OpenAI pool",
1232
+ "type": "text"
1233
+ },
1234
+ {
1235
+ "g": "Rotation Pools",
1236
+ "icon": "πŸ”„",
1237
+ "k": "GEMINI_API_KEYS",
1238
+ "lbl": "Gemini pool",
1239
+ "type": "text"
1240
+ },
1241
+ {
1242
+ "g": "Rotation Pools",
1243
+ "icon": "πŸ”„",
1244
+ "k": "GOOGLE_API_KEYS",
1245
+ "lbl": "Google pool",
1246
+ "type": "text"
1247
+ },
1248
+ {
1249
+ "g": "Rotation Pools",
1250
+ "icon": "πŸ”„",
1251
+ "k": "DEEPSEEK_API_KEYS",
1252
+ "lbl": "DeepSeek pool",
1253
+ "type": "text"
1254
+ },
1255
+ {
1256
+ "g": "Rotation Pools",
1257
+ "icon": "πŸ”„",
1258
+ "k": "OPENROUTER_API_KEYS",
1259
+ "lbl": "OpenRouter pool",
1260
+ "type": "text"
1261
+ },
1262
+ {
1263
+ "g": "Rotation Pools",
1264
+ "icon": "πŸ”„",
1265
+ "k": "OPENCODE_API_KEYS",
1266
+ "lbl": "OpenCode pool",
1267
+ "type": "text"
1268
+ },
1269
+ {
1270
+ "g": "Rotation Pools",
1271
+ "icon": "πŸ”„",
1272
+ "k": "KILOCODE_API_KEYS",
1273
+ "lbl": "KiloCode pool",
1274
+ "type": "text"
1275
+ },
1276
+ {
1277
+ "g": "Rotation Pools",
1278
+ "icon": "πŸ”„",
1279
+ "k": "ZAI_API_KEYS",
1280
+ "lbl": "Z.ai / GLM pool",
1281
+ "type": "text"
1282
+ },
1283
+ {
1284
+ "g": "Rotation Pools",
1285
+ "icon": "πŸ”„",
1286
+ "k": "MOONSHOT_API_KEYS",
1287
+ "lbl": "Moonshot / Kimi pool",
1288
+ "type": "text"
1289
+ },
1290
+ {
1291
+ "g": "Rotation Pools",
1292
+ "icon": "πŸ”„",
1293
+ "k": "MINIMAX_API_KEYS",
1294
+ "lbl": "MiniMax pool",
1295
+ "type": "text"
1296
+ },
1297
+ {
1298
+ "g": "Rotation Pools",
1299
+ "icon": "πŸ”„",
1300
+ "k": "XIAOMI_API_KEYS",
1301
+ "lbl": "Xiaomi pool",
1302
+ "type": "text"
1303
+ },
1304
+ {
1305
+ "g": "Rotation Pools",
1306
+ "icon": "πŸ”„",
1307
+ "k": "VOLCANO_ENGINE_API_KEYS",
1308
+ "lbl": "Volcano Engine pool",
1309
+ "type": "text"
1310
+ },
1311
+ {
1312
+ "g": "Rotation Pools",
1313
+ "icon": "πŸ”„",
1314
+ "k": "BYTEPLUS_API_KEYS",
1315
+ "lbl": "BytePlus pool",
1316
+ "type": "text"
1317
+ },
1318
+ {
1319
+ "g": "Rotation Pools",
1320
+ "icon": "πŸ”„",
1321
+ "k": "MISTRAL_API_KEYS",
1322
+ "lbl": "Mistral pool",
1323
+ "type": "text"
1324
+ },
1325
+ {
1326
+ "g": "Rotation Pools",
1327
+ "icon": "πŸ”„",
1328
+ "k": "XAI_API_KEYS",
1329
+ "lbl": "xAI pool",
1330
+ "type": "text"
1331
+ },
1332
+ {
1333
+ "g": "Rotation Pools",
1334
+ "icon": "πŸ”„",
1335
+ "k": "NVIDIA_API_KEYS",
1336
+ "lbl": "NVIDIA pool",
1337
+ "type": "text"
1338
+ },
1339
+ {
1340
+ "g": "Rotation Pools",
1341
+ "icon": "πŸ”„",
1342
+ "k": "GROQ_API_KEYS",
1343
+ "lbl": "Groq pool",
1344
+ "type": "text"
1345
+ },
1346
+ {
1347
+ "g": "Rotation Pools",
1348
+ "icon": "πŸ”„",
1349
+ "k": "COHERE_API_KEYS",
1350
+ "lbl": "Cohere pool",
1351
+ "type": "text"
1352
+ },
1353
+ {
1354
+ "g": "Rotation Pools",
1355
+ "icon": "πŸ”„",
1356
+ "k": "TOGETHER_API_KEYS",
1357
+ "lbl": "Together pool",
1358
+ "type": "text"
1359
+ },
1360
+ {
1361
+ "g": "Rotation Pools",
1362
+ "icon": "πŸ”„",
1363
+ "k": "CEREBRAS_API_KEYS",
1364
+ "lbl": "Cerebras pool",
1365
+ "type": "text"
1366
+ },
1367
+ {
1368
+ "g": "Rotation Pools",
1369
+ "icon": "πŸ”„",
1370
+ "k": "HUGGINGFACE_HUB_TOKENS",
1371
+ "lbl": "HF token pool",
1372
+ "type": "text"
1373
+ },
1374
+ {
1375
+ "g": "Model Lists",
1376
+ "icon": "πŸ“‹",
1377
+ "k": "OPENAI_MODELS",
1378
+ "lbl": "Visible OpenAI models",
1379
+ "type": "model_list",
1380
+ "options_key": "OPENAI_MODELS",
1381
+ "ph": "Select models to build a comma list"
1382
+ },
1383
+ {
1384
+ "g": "Model Lists",
1385
+ "icon": "πŸ“‹",
1386
+ "k": "ANTHROPIC_MODELS",
1387
+ "lbl": "Visible Anthropic models",
1388
+ "type": "model_list",
1389
+ "options_key": "ANTHROPIC_MODELS",
1390
+ "ph": "Select models to build a comma list"
1391
+ },
1392
+ {
1393
+ "g": "Model Lists",
1394
+ "icon": "πŸ“‹",
1395
+ "k": "GEMINI_MODELS",
1396
+ "lbl": "Visible Gemini models",
1397
+ "type": "model_list",
1398
+ "options_key": "GEMINI_MODELS",
1399
+ "ph": "Select models to build a comma list"
1400
+ },
1401
+ {
1402
+ "g": "Model Lists",
1403
+ "icon": "πŸ“‹",
1404
+ "k": "DEEPSEEK_MODELS",
1405
+ "lbl": "Visible DeepSeek models",
1406
+ "type": "model_list",
1407
+ "options_key": "DEEPSEEK_MODELS",
1408
+ "ph": "Select models to build a comma list"
1409
+ },
1410
+ {
1411
+ "g": "Model Lists",
1412
+ "icon": "πŸ“‹",
1413
+ "k": "OPENROUTER_MODELS",
1414
+ "lbl": "Visible OpenRouter models",
1415
+ "type": "model_list",
1416
+ "options_key": "OPENROUTER_MODELS",
1417
+ "ph": "Select models to build a comma list"
1418
+ },
1419
+ {
1420
+ "g": "Model Lists",
1421
+ "icon": "πŸ“‹",
1422
+ "k": "GROQ_MODELS",
1423
+ "lbl": "Visible Groq models",
1424
+ "type": "model_list",
1425
+ "options_key": "GROQ_MODELS",
1426
+ "ph": "Select models to build a comma list"
1427
+ },
1428
+ {
1429
+ "g": "Model Lists",
1430
+ "icon": "πŸ“‹",
1431
+ "k": "MISTRAL_MODELS",
1432
+ "lbl": "Visible Mistral models",
1433
+ "type": "model_list",
1434
+ "options_key": "MISTRAL_MODELS",
1435
+ "ph": "Select models to build a comma list"
1436
+ },
1437
+ {
1438
+ "g": "Model Lists",
1439
+ "icon": "πŸ“‹",
1440
+ "k": "XAI_MODELS",
1441
+ "lbl": "Visible xAI models",
1442
+ "type": "model_list",
1443
+ "options_key": "XAI_MODELS",
1444
+ "ph": "Select models to build a comma list"
1445
+ },
1446
+ {
1447
+ "g": "Model Lists",
1448
+ "icon": "πŸ“‹",
1449
+ "k": "COHERE_MODELS",
1450
+ "lbl": "Visible Cohere models",
1451
+ "type": "model_list",
1452
+ "options_key": "COHERE_MODELS",
1453
+ "ph": "Select models to build a comma list"
1454
+ },
1455
+ {
1456
+ "g": "Model Lists",
1457
+ "icon": "πŸ“‹",
1458
+ "k": "TOGETHER_MODELS",
1459
+ "lbl": "Visible Together models",
1460
+ "type": "model_list",
1461
+ "options_key": "TOGETHER_MODELS",
1462
+ "ph": "Select models to build a comma list"
1463
+ },
1464
+ {
1465
+ "g": "Model Lists",
1466
+ "icon": "πŸ“‹",
1467
+ "k": "CEREBRAS_MODELS",
1468
+ "lbl": "Visible Cerebras models",
1469
+ "type": "model_list",
1470
+ "options_key": "CEREBRAS_MODELS",
1471
+ "ph": "Select models to build a comma list"
1472
+ },
1473
+ {
1474
+ "g": "Model Lists",
1475
+ "icon": "πŸ“‹",
1476
+ "k": "NVIDIA_MODELS",
1477
+ "lbl": "Visible NVIDIA models",
1478
+ "type": "model_list",
1479
+ "options_key": "NVIDIA_MODELS",
1480
+ "ph": "Select models to build a comma list"
1481
+ },
1482
+ {
1483
+ "g": "Model Lists",
1484
+ "icon": "πŸ“‹",
1485
+ "k": "KILOCODE_MODELS",
1486
+ "lbl": "Visible KiloCode models",
1487
+ "type": "model_list",
1488
+ "options_key": "KILOCODE_MODELS",
1489
+ "ph": "Select models to build a comma list"
1490
+ },
1491
+ {
1492
+ "g": "Model Lists",
1493
+ "icon": "πŸ“‹",
1494
+ "k": "OPENCODE_MODELS",
1495
+ "lbl": "Visible OpenCode models",
1496
+ "type": "model_list",
1497
+ "options_key": "OPENCODE_MODELS",
1498
+ "ph": "Select models to build a comma list"
1499
+ },
1500
+ {
1501
+ "g": "Model Lists",
1502
+ "icon": "πŸ“‹",
1503
+ "k": "ZAI_MODELS",
1504
+ "lbl": "Visible Z.ai / GLM models",
1505
+ "type": "model_list",
1506
+ "options_key": "ZAI_MODELS",
1507
+ "ph": "Select models to build a comma list"
1508
+ },
1509
+ {
1510
+ "g": "Model Lists",
1511
+ "icon": "πŸ“‹",
1512
+ "k": "MOONSHOT_MODELS",
1513
+ "lbl": "Visible Moonshot / Kimi models",
1514
+ "type": "model_list",
1515
+ "options_key": "MOONSHOT_MODELS",
1516
+ "ph": "Select models to build a comma list"
1517
+ },
1518
+ {
1519
+ "g": "Model Lists",
1520
+ "icon": "πŸ“‹",
1521
+ "k": "MINIMAX_MODELS",
1522
+ "lbl": "Visible MiniMax models",
1523
+ "type": "model_list",
1524
+ "options_key": "MINIMAX_MODELS",
1525
+ "ph": "Select models to build a comma list"
1526
+ },
1527
+ {
1528
+ "g": "Model Lists",
1529
+ "icon": "πŸ“‹",
1530
+ "k": "XIAOMI_MODELS",
1531
+ "lbl": "Visible Xiaomi models",
1532
+ "type": "model_list",
1533
+ "options_key": "XIAOMI_MODELS",
1534
+ "ph": "Select models to build a comma list"
1535
+ },
1536
+ {
1537
+ "g": "Model Lists",
1538
+ "icon": "πŸ“‹",
1539
+ "k": "VOLCANO_ENGINE_MODELS",
1540
+ "lbl": "Visible Volcano Engine models",
1541
+ "type": "model_list",
1542
+ "options_key": "VOLCANO_ENGINE_MODELS",
1543
+ "ph": "Select models to build a comma list"
1544
+ },
1545
+ {
1546
+ "g": "Model Lists",
1547
+ "icon": "πŸ“‹",
1548
+ "k": "BYTEPLUS_MODELS",
1549
+ "lbl": "Visible BytePlus models",
1550
+ "type": "model_list",
1551
+ "options_key": "BYTEPLUS_MODELS",
1552
+ "ph": "Select models to build a comma list"
1553
+ },
1554
+ {
1555
+ "g": "Model Lists",
1556
+ "icon": "πŸ“‹",
1557
+ "k": "QIANFAN_MODELS",
1558
+ "lbl": "Visible Qianfan models",
1559
+ "type": "model_list",
1560
+ "options_key": "QIANFAN_MODELS",
1561
+ "ph": "Select models to build a comma list"
1562
+ },
1563
+ {
1564
+ "g": "Model Lists",
1565
+ "icon": "πŸ“‹",
1566
+ "k": "MODELSTUDIO_MODELS",
1567
+ "lbl": "Visible ModelStudio models",
1568
+ "type": "model_list",
1569
+ "options_key": "MODELSTUDIO_MODELS",
1570
+ "ph": "Select models to build a comma list"
1571
+ },
1572
+ {
1573
+ "g": "Model Lists",
1574
+ "icon": "πŸ“‹",
1575
+ "k": "KIMI_MODELS",
1576
+ "lbl": "Visible Kimi models",
1577
+ "type": "model_list",
1578
+ "options_key": "KIMI_MODELS",
1579
+ "ph": "Select models to build a comma list"
1580
+ },
1581
+ {
1582
+ "g": "Model Lists",
1583
+ "icon": "πŸ“‹",
1584
+ "k": "HUGGINGFACE_MODELS",
1585
+ "lbl": "Visible Hugging Face models",
1586
+ "type": "model_list",
1587
+ "options_key": "HUGGINGFACE_MODELS",
1588
+ "ph": "Select models to build a comma list"
1589
+ },
1590
+ {
1591
+ "g": "Model Lists",
1592
+ "icon": "πŸ“‹",
1593
+ "k": "GITHUB_COPILOT_MODELS",
1594
+ "lbl": "Visible GitHub Copilot models",
1595
+ "type": "model_list",
1596
+ "options_key": "GITHUB_COPILOT_MODELS",
1597
+ "ph": "Select models to build a comma list"
1598
+ },
1599
+ {
1600
+ "g": "Custom Provider",
1601
+ "icon": "πŸ”Œ",
1602
+ "k": "CUSTOM_PROVIDER_NAME",
1603
+ "lbl": "Provider display name",
1604
+ "type": "text"
1605
+ },
1606
+ {
1607
+ "g": "Custom Provider",
1608
+ "icon": "πŸ”Œ",
1609
+ "k": "CUSTOM_BASE_URL",
1610
+ "lbl": "OpenAI-compatible base URL",
1611
+ "type": "text"
1612
+ },
1613
+ {
1614
+ "g": "Custom Provider",
1615
+ "icon": "πŸ”Œ",
1616
+ "k": "CUSTOM_MODEL_ID",
1617
+ "lbl": "Model ID",
1618
+ "type": "model",
1619
+ "options_key": "LLM_MODEL",
1620
+ "ph": "custom model id"
1621
+ },
1622
+ {
1623
+ "g": "Custom Provider",
1624
+ "icon": "πŸ”Œ",
1625
+ "k": "CUSTOM_MODEL_NAME",
1626
+ "lbl": "Friendly model name",
1627
+ "type": "text"
1628
+ },
1629
+ {
1630
+ "g": "Custom Provider",
1631
+ "icon": "πŸ”Œ",
1632
+ "k": "CUSTOM_API_KEY",
1633
+ "lbl": "Provider API key",
1634
+ "type": "password",
1635
+ "secret": 1
1636
+ },
1637
+ {
1638
+ "g": "Custom Provider",
1639
+ "icon": "πŸ”Œ",
1640
+ "k": "CUSTOM_API_TYPE",
1641
+ "lbl": "API type",
1642
+ "type": "select",
1643
+ "options": [
1644
+ "openai-completions",
1645
+ "openai-chat-completions",
1646
+ "anthropic",
1647
+ "gemini",
1648
+ "openrouter"
1649
+ ],
1650
+ "ph": "openai-completions"
1651
+ },
1652
+ {
1653
+ "g": "Custom Provider",
1654
+ "icon": "πŸ”Œ",
1655
+ "k": "CUSTOM_CONTEXT_WINDOW",
1656
+ "lbl": "Context window",
1657
+ "type": "number",
1658
+ "ph": "128000"
1659
+ },
1660
+ {
1661
+ "g": "Custom Provider",
1662
+ "icon": "πŸ”Œ",
1663
+ "k": "CUSTOM_MAX_TOKENS",
1664
+ "lbl": "Max output tokens",
1665
+ "type": "number",
1666
+ "ph": "500"
1667
+ },
1668
+ {
1669
+ "g": "Telegram",
1670
+ "icon": "✈️",
1671
+ "k": "TELEGRAM_BOT_TOKEN",
1672
+ "lbl": "Bot token from BotFather",
1673
+ "type": "password",
1674
+ "secret": 1,
1675
+ "common": 1
1676
+ },
1677
+ {
1678
+ "g": "Telegram",
1679
+ "icon": "✈️",
1680
+ "k": "TELEGRAM_ALLOWED_USERS",
1681
+ "lbl": "Allowed user IDs (comma)",
1682
+ "type": "text",
1683
+ "ph": "123456789,987654321",
1684
+ "common": 1
1685
+ },
1686
+ {
1687
+ "g": "Telegram",
1688
+ "icon": "✈️",
1689
+ "k": "TELEGRAM_USER_ID",
1690
+ "lbl": "Single Telegram user ID",
1691
+ "type": "text"
1692
+ },
1693
+ {
1694
+ "g": "Telegram",
1695
+ "icon": "✈️",
1696
+ "k": "TELEGRAM_USER_IDS",
1697
+ "lbl": "Telegram user IDs (comma)",
1698
+ "type": "text"
1699
+ },
1700
+ {
1701
+ "g": "Deployment",
1702
+ "icon": "🧭",
1703
+ "k": "APP_BASE",
1704
+ "lbl": "Public app base path",
1705
+ "type": "text",
1706
+ "ph": "/app"
1707
+ },
1708
+ {
1709
+ "g": "Deployment",
1710
+ "icon": "🧭",
1711
+ "k": "BACKUP_DATASET",
1712
+ "lbl": "Backup dataset alias",
1713
+ "type": "text",
1714
+ "ph": "huggingclaw-backup"
1715
+ },
1716
+ {
1717
+ "g": "Deployment",
1718
+ "icon": "🧭",
1719
+ "k": "SPACE_AUTHOR_NAME",
1720
+ "lbl": "HF Space author name",
1721
+ "type": "text"
1722
+ },
1723
+ {
1724
+ "g": "Deployment",
1725
+ "icon": "🧭",
1726
+ "k": "SPACE_HOST",
1727
+ "lbl": "HF Space host domain",
1728
+ "type": "text"
1729
+ },
1730
+ {
1731
+ "g": "Deployment",
1732
+ "icon": "🧭",
1733
+ "k": "PORT",
1734
+ "lbl": "Public dashboard port",
1735
+ "type": "number",
1736
+ "ph": "7861"
1737
+ },
1738
+ {
1739
+ "g": "Deployment",
1740
+ "icon": "🧭",
1741
+ "k": "GATEWAY_PORT",
1742
+ "lbl": "OpenClaw internal port",
1743
+ "type": "number",
1744
+ "ph": "7860"
1745
+ },
1746
+ {
1747
+ "g": "Deployment",
1748
+ "icon": "🧭",
1749
+ "k": "JUPYTER_PORT",
1750
+ "lbl": "Jupyter internal port",
1751
+ "type": "number",
1752
+ "ph": "8888"
1753
+ },
1754
+ {
1755
+ "g": "Deployment",
1756
+ "icon": "🧭",
1757
+ "k": "JUPYTER_BASE",
1758
+ "lbl": "Jupyter public base path",
1759
+ "type": "text",
1760
+ "ph": "/terminal"
1761
+ }
1762
+ ];
1763
+
1764
+ const ICONS = {
1765
+ All:'🏠', Core:'⚑', Deployment:'🧭', 'Provider Keys':'πŸ”‘', 'Rotation Pools':'πŸ”„',
1766
+ 'Model Lists':'πŸ“‹', 'Custom Provider':'πŸ”Œ', Telegram:'✈️', WhatsApp:'πŸ’¬',
1767
+ Cloudflare:'☁️', Backup:'πŸ’Ύ', DevData:'πŸ§ͺ', Runtime:'βš™οΈ', 'Custom Env':'πŸ”§'
1768
+ };
1769
+
1770
+ const $ = id => document.getElementById(id);
1771
+ const esc = s => String(s ?? '').replace(/[&<>"']/g, c => ({
1772
+ '&': '&amp;',
1773
+ '<': '&lt;',
1774
+ '>': '&gt;',
1775
+ '"': '&quot;',
1776
+ "'": '&#39;'
1777
+ }[c]));
1778
+ const safeKey = k => /^[A-Z_][A-Z0-9_]*$/.test(k) && !['HUGGINGCLAW_ENV_BUNDLE', 'ENV_BUNDLE'].includes(k);
1779
+
1780
+ function encodeBundle(obj) {
1781
+ const j = JSON.stringify(obj);
1782
+ let b = '';
1783
+ for (const x of new TextEncoder().encode(j)) b += String.fromCharCode(x);
1784
+ return btoa(b).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, '');
1785
+ }
1786
+
1787
+ function decodeBundle(raw) {
1788
+ try {
1789
+ raw = String(raw || '').trim();
1790
+ if (!raw) return {};
1791
+
1792
+ if (raw.includes('HUGGINGCLAW_ENV_BUNDLE=')) {
1793
+ raw = raw.split('HUGGINGCLAW_ENV_BUNDLE=').pop().trim();
1794
+ }
1795
+
1796
+ if (
1797
+ (raw.startsWith('"') && raw.endsWith('"')) ||
1798
+ (raw.startsWith("'") && raw.endsWith("'"))
1799
+ ) {
1800
+ raw = raw.slice(1, -1);
1801
+ }
1802
+
1803
+ if (raw.startsWith('{')) return JSON.parse(raw);
1804
+
1805
+ const p = raw + '='.repeat((4 - raw.length % 4) % 4);
1806
+ const b = atob(p.replace(/-/g, '+').replace(/_/g, '/'));
1807
+ const bytes = Uint8Array.from(b, c => c.charCodeAt(0));
1808
+ return JSON.parse(new TextDecoder().decode(bytes));
1809
+ } catch {
1810
+ return {};
1811
+ }
1812
+ }
1813
+
1814
+ function parseEnv(text) {
1815
+ text = String(text || '').trim();
1816
+ if (!text) return {};
1817
+
1818
+ if (
1819
+ text.startsWith('{') ||
1820
+ /^[A-Za-z0-9_-]{20,}$/.test(text) ||
1821
+ text.includes('HUGGINGCLAW_ENV_BUNDLE=')
1822
+ ) {
1823
+ return decodeBundle(text);
1824
+ }
1825
+
1826
+ const out = {};
1827
+ for (let line of text.split(/\r?\n/)) {
1828
+ line = line.trim();
1829
+ if (!line || line.startsWith('#')) continue;
1830
+ if (line.startsWith('export ')) line = line.slice(7).trim();
1831
+ const i = line.indexOf('=');
1832
+ if (i < 1) continue;
1833
+
1834
+ const key = line.slice(0, i).trim();
1835
+ let val = line.slice(i + 1).trim();
1836
+
1837
+ if (
1838
+ (val.startsWith('"') && val.endsWith('"')) ||
1839
+ (val.startsWith("'") && val.endsWith("'"))
1840
+ ) {
1841
+ val = val.slice(1, -1);
1842
+ }
1843
+
1844
+ if (safeKey(key)) out[key] = val;
1845
+ }
1846
+ return out;
1847
+ }
1848
+
1849
+ function showToast(msg = 'Copied!') {
1850
+ const t = $('toast');
1851
+ t.textContent = msg;
1852
+ t.classList.add('show');
1853
+ setTimeout(() => t.classList.remove('show'), 1500);
1854
+ }
1855
+
1856
+ let activeGroup = 'All';
1857
+ let customCount = 0;
1858
+ const GROUPS = ['All', ...[...new Set(FIELDS.map(f => f.g))], 'Custom Env'];
1859
+
1860
+ function renderSidebar() {
1861
+ const sb = $('sidebar');
1862
+ sb.innerHTML = '<div class="sb-label">Groups</div>';
1863
+ GROUPS.forEach(g => {
1864
+ const btn = document.createElement('button');
1865
+ btn.className = 'nav-btn' + (activeGroup === g ? ' active' : '');
1866
+ btn.dataset.group = g;
1867
+ const id = 'nc_' + g.replace(/\W/g, '_');
1868
+ btn.innerHTML = `<span class="nav-icon">${ICONS[g] || 'πŸ“'}</span><span class="nav-label">${esc(g)}</span><span class="nav-count" id="${id}">0</span>`;
1869
+ btn.onclick = () => {
1870
+ activeGroup = g;
1871
+ renderSidebar();
1872
+ filter();
1873
+ };
1874
+ sb.appendChild(btn);
1875
+ });
1876
+ }
1877
+
1878
+ function renderOptionsHTML(field) {
1879
+ const src = field.options || MODEL_CATALOGS[field.options_key] || [];
1880
+
1881
+ if (field.options_key === 'LLM_MODEL') {
1882
+ const groups = MODEL_CATALOGS.LLM_MODEL || {};
1883
+ return Object.entries(groups).map(([group, items]) => {
1884
+ const options = items.map(v => `<option value="${esc(v)}">${esc(v)}</option>`).join('');
1885
+ return `<optgroup label="${esc(group)}">${options}</optgroup>`;
1886
+ }).join('');
1887
+ }
1888
+
1889
+ if (Array.isArray(src)) {
1890
+ return src.map(v => `<option value="${esc(v)}">${esc(v)}</option>`).join('');
1891
+ }
1892
+
1893
+ return '';
1894
+ }
1895
+
1896
+ function defaultValueFor(field) {
1897
+ if (field.type === 'toggle') {
1898
+ const on = String(field.ph ?? '').toLowerCase();
1899
+ return ['1', 'true', 'yes', 'on', 'enabled'].includes(on) ? 'true' : 'false';
1900
+ }
1901
+ if (field.type === 'select') return String(field.ph ?? '');
1902
+ return '';
1903
+ }
1904
+
1905
+ function valueControlHTML(field) {
1906
+ const key = esc(field.k);
1907
+ const placeholder = esc(field.ph || field.lbl || '');
1908
+ const isSecret = !!field.secret;
1909
+ const isTextarea = field.type === 'textarea' || field.type === 'model_list';
1910
+ const hasPicker = !!field.options_key || Array.isArray(field.options);
1911
+ const inputType = isSecret ? 'password' : (field.type === 'number' ? 'number' : 'text');
1912
+
1913
+ let control = '';
1914
+ if (field.type === 'toggle') {
1915
+ const initial = defaultValueFor(field);
1916
+ control = `
1917
+ <div class="toggle-shell" data-toggle-row="1" data-field="${key}">
1918
+ <input type="hidden" data-key="${key}" value="${initial}">
1919
+ <button type="button" class="tog ${initial === 'true' ? 'on' : ''}" data-toggle="${key}">${initial === 'true' ? 'On' : 'Off'}</button>
1920
+ </div>`;
1921
+ } else if (isTextarea) {
1922
+ control = `<textarea data-key="${key}" placeholder="${placeholder}" spellcheck="false"></textarea>`;
1923
+ } else {
1924
+ control = `<input type="${inputType}" data-key="${key}" placeholder="${placeholder}" spellcheck="false"/>`;
1925
+ }
1926
+
1927
+ if (!hasPicker) return control;
1928
+
1929
+ const pickerMode = field.type === 'model_list' ? 'multi' : 'single';
1930
+ const pickerLabel = field.type === 'model_list' ? 'Add model…' : 'Choose preset…';
1931
+ return `
1932
+ <div class="picker-shell" data-picker-shell="${key}" data-picker-mode="${pickerMode}">
1933
+ <div class="picker-row">
1934
+ <select class="picker-select" data-pick-for="${key}" aria-label="${esc(field.lbl || field.k)} presets">
1935
+ <option value="">${esc(pickerLabel)}</option>
1936
+ ${renderOptionsHTML(field)}
1937
+ <option value="__custom__">Custom…</option>
1938
+ </select>
1939
+ <button type="button" class="mini-btn" data-custom-for="${key}">+ Custom</button>
1940
+ <button type="button" class="mini-btn" data-clear-for="${key}">Clear</button>
1941
+ </div>
1942
+ ${control}
1943
+ </div>`;
1944
+
1945
+ return control;
1946
+ }
1947
+
1948
+ function cardHTML(f) {
1949
+ const badge = f.secret
1950
+ ? '<span class="badge badge-s">secret</span>'
1951
+ : '<span class="badge badge-f">safe</span>';
1952
+
1953
+ return `<div class="env-card" data-row data-group="${esc(f.g)}" data-search="${esc((f.g + ' ' + f.k + ' ' + (f.lbl || '')).toLowerCase())}">
1954
+ <div class="card-top">
1955
+ <input type="checkbox" class="card-check" data-check="${esc(f.k)}" ${f.common ? 'data-common="1"' : ''}>
1956
+ <div class="card-info">
1957
+ <div class="card-key">${esc(f.k)}</div>
1958
+ <div class="card-lbl">${esc(f.lbl || '')}</div>
1959
+ </div>
1960
+ ${badge}
1961
+ </div>
1962
+ <div class="card-input">${valueControlHTML(f)}</div>
1963
+ </div>`;
1964
+ }
1965
+
1966
+ function addCustomRow(key = '', val = '', enabled = false) {
1967
+ const id = customCount++;
1968
+ const row = document.createElement('div');
1969
+ row.className = 'custom-row';
1970
+ row.dataset.customRow = id;
1971
+ row.dataset.enabled = enabled ? '1' : '0';
1972
+
1973
+ row.innerHTML = `
1974
+ <input data-ck="${id}" placeholder="CUSTOM_ENV_NAME" value="${esc(key)}">
1975
+ <input data-cv="${id}" placeholder="value" value="${esc(val)}">
1976
+ <button class="tog${enabled ? ' on' : ''}">${enabled ? 'On' : 'Off'}</button>
1977
+ `;
1978
+
1979
+ $('customRows').appendChild(row);
1980
+
1981
+ row.querySelectorAll('input').forEach(el => el.addEventListener('input', refresh));
1982
+ row.querySelector('button').onclick = () => {
1983
+ const on = row.dataset.enabled !== '1';
1984
+ row.dataset.enabled = on ? '1' : '0';
1985
+ row.querySelector('button').textContent = on ? 'On' : 'Off';
1986
+ row.querySelector('button').classList.toggle('on', on);
1987
+ refresh();
1988
+ };
1989
+ }
1990
+
1991
+ function getFieldValueInput(key) {
1992
+ return document.querySelector(`[data-key="${CSS.escape(key)}"]`);
1993
+ }
1994
+
1995
+ function setFieldValue(key, value) {
1996
+ const el = getFieldValueInput(key);
1997
+ if (!el) return;
1998
+ el.value = value ?? '';
1999
+ }
2000
+
2001
+ function appendCsvValue(existing, next) {
2002
+ const parts = String(existing || '').split(',').map(s => s.trim()).filter(Boolean);
2003
+ const val = String(next || '').trim();
2004
+ if (!val) return parts.join(', ');
2005
+ if (!parts.includes(val)) parts.push(val);
2006
+ return parts.join(', ');
2007
+ }
2008
+
2009
+ function collect() {
2010
+ const obj = {};
2011
+ document.querySelectorAll('[data-key]').forEach(el => {
2012
+ const key = el.dataset.key;
2013
+ if (!key || !safeKey(key)) return;
2014
+ const val = String(el.value ?? '').trim();
2015
+ if (val) obj[key] = val;
2016
+ });
2017
+
2018
+ document.querySelectorAll('[data-custom-row]').forEach(row => {
2019
+ const id = row.dataset.customRow;
2020
+ const key = (row.querySelector(`[data-ck="${id}"]`)?.value || '').trim();
2021
+ const val = (row.querySelector(`[data-cv="${id}"]`)?.value || '').trim();
2022
+ if (row.dataset.enabled === '1' && safeKey(key) && val) obj[key] = val;
2023
+ });
2024
+
2025
+ return obj;
2026
+ }
2027
+
2028
+ function refresh() {
2029
+ const obj = collect();
2030
+ const keys = Object.keys(obj).sort();
2031
+ const bundle = keys.length ? encodeBundle(Object.fromEntries(keys.map(k => [k, obj[k]]))) : '';
2032
+
2033
+ $('bundleOut').value = bundle;
2034
+ $('envLineOut').value = bundle ? `HUGGINGCLAW_ENV_BUNDLE=${bundle}` : '';
2035
+
2036
+ const s = $('summary');
2037
+ if (keys.length) {
2038
+ s.innerHTML = `<strong>${keys.length}</strong> variable${keys.length > 1 ? 's' : ''} selected<div class="sum-keys">${keys.map(k => `<span class="sum-key">${esc(k)}</span>`).join('')}</div>`;
2039
+ } else {
2040
+ s.innerHTML = 'No variables selected yet.';
2041
+ }
2042
+ updateCounts();
2043
+ }
2044
+
2045
+ function markSelected() {
2046
+ document.querySelectorAll('[data-row]').forEach(r => r.classList.toggle('selected', !!r.querySelector('[data-check]')?.checked));
2047
+ }
2048
+
2049
+ function updateCounts() {
2050
+ document.querySelectorAll('[id^="nc_"]').forEach(el => el.textContent = '0');
2051
+ const byGrp = {};
2052
+ document.querySelectorAll('[data-check]:checked').forEach(ch => {
2053
+ const g = ch.closest('[data-row]')?.dataset.group;
2054
+ if (g) byGrp[g] = (byGrp[g] || 0) + 1;
2055
+ });
2056
+ const custOn = document.querySelectorAll('[data-custom-row][data-enabled="1"]').length;
2057
+ const total = Object.values(byGrp).reduce((a, b) => a + b, 0) + custOn;
2058
+ const allEl = document.getElementById('nc_All'); if (allEl) allEl.textContent = total;
2059
+ Object.entries(byGrp).forEach(([g, c]) => {
2060
+ const el = document.getElementById('nc_' + g.replace(/\W/g, '_'));
2061
+ if (el) el.textContent = c;
2062
+ });
2063
+ const custEl = document.getElementById('nc_Custom_Env'); if (custEl) custEl.textContent = custOn;
2064
+ }
2065
+
2066
+ function filter() {
2067
+ const q = $('search').value.trim().toLowerCase();
2068
+ document.querySelectorAll('.sec[data-section]').forEach(sec => {
2069
+ const grp = sec.dataset.section;
2070
+ const gMatch = activeGroup === 'All' || activeGroup === grp;
2071
+ if (!gMatch) { sec.classList.add('sec-hidden'); return; }
2072
+ let any = false;
2073
+ sec.querySelectorAll('[data-row]').forEach(card => {
2074
+ const m = !q || card.dataset.search.includes(q);
2075
+ card.classList.toggle('hidden', !m);
2076
+ if (m) any = true;
2077
+ });
2078
+ sec.classList.toggle('sec-hidden', !any);
2079
+ });
2080
+ const cs = $('customSec');
2081
+ if (cs) cs.style.display = (activeGroup === 'All' || activeGroup === 'Custom Env') ? '' : 'none';
2082
+ document.querySelectorAll('.nav-btn').forEach(b => b.classList.toggle('active', b.dataset.group === activeGroup));
2083
+ }
2084
+
2085
+ function clearForm() {
2086
+ document.querySelectorAll('[data-check]').forEach(c => c.checked = false);
2087
+ document.querySelectorAll('[data-key]').forEach(el => {
2088
+ if (el.closest('[data-toggle-row]')) {
2089
+ el.value = 'false';
2090
+ const btn = el.closest('.toggle-shell')?.querySelector('[data-toggle]');
2091
+ if (btn) {
2092
+ btn.textContent = 'Off';
2093
+ btn.classList.remove('on');
2094
+ }
2095
+ return;
2096
+ }
2097
+ el.value = '';
2098
+ });
2099
+ $('customRows').innerHTML = '';
2100
+ customCount = 0;
2101
+ addCustomRow();
2102
+ }
2103
+
2104
+ function applyObj(obj, replace = false) {
2105
+ if (replace) clearForm();
2106
+ for (const [key, val] of Object.entries(obj || {})) {
2107
+ if (!safeKey(key)) continue;
2108
+ const inp = getFieldValueInput(key);
2109
+ const chk = document.querySelector(`[data-check="${CSS.escape(key)}"]`);
2110
+ if (inp && chk) {
2111
+ inp.value = val;
2112
+ chk.checked = true;
2113
+ const btn = inp.closest('[data-toggle-row]')?.querySelector('[data-toggle]');
2114
+ if (btn) {
2115
+ const on = String(val).trim().toLowerCase() === 'true';
2116
+ btn.textContent = on ? 'On' : 'Off';
2117
+ btn.classList.toggle('on', on);
2118
+ inp.value = on ? 'true' : 'false';
2119
+ }
2120
+ } else {
2121
+ addCustomRow(key, val, true);
2122
+ }
2123
+ }
2124
+ markSelected(); filter(); refresh();
2125
+ }
2126
+
2127
+ function handlePickerChange(sel) {
2128
+ const key = sel.dataset.pickFor;
2129
+ const mode = sel.closest('[data-picker-shell]')?.dataset.pickerMode || 'single';
2130
+ const value = sel.value;
2131
+ if (!key || !value) return;
2132
+ if (value === '__custom__') {
2133
+ sel.value = '';
2134
+ return;
2135
+ }
2136
+ const inp = getFieldValueInput(key);
2137
+ if (!inp) return;
2138
+
2139
+ if (mode === 'multi') {
2140
+ inp.value = appendCsvValue(inp.value, value);
2141
+ } else {
2142
+ inp.value = value;
2143
+ }
2144
+ sel.value = '';
2145
+ refresh();
2146
+ }
2147
+
2148
+ function promptCustomModel(btn) {
2149
+ const key = btn.dataset.customFor;
2150
+ const mode = btn.closest('[data-picker-shell]')?.dataset.pickerMode || 'single';
2151
+ const inp = getFieldValueInput(key);
2152
+ if (!inp) return;
2153
+ const message = mode === 'multi'
2154
+ ? 'Enter one or more custom model IDs separated by commas'
2155
+ : 'Enter a custom model ID';
2156
+ const initial = '';
2157
+ const text = prompt(message, initial);
2158
+ if (text === null) return;
2159
+ const val = String(text).trim();
2160
+ if (!val) return;
2161
+ if (mode === 'multi') {
2162
+ const vals = val.split(',').map(s => s.trim()).filter(Boolean);
2163
+ let out = inp.value || '';
2164
+ for (const v of vals) out = appendCsvValue(out, v);
2165
+ inp.value = out;
2166
+ } else {
2167
+ inp.value = val;
2168
+ }
2169
+ refresh();
2170
+ }
2171
+
2172
+ function resetPickerField(btn) {
2173
+ const key = btn.dataset.clearFor;
2174
+ const inp = getFieldValueInput(key);
2175
+ if (!inp) return;
2176
+ if (inp.closest('[data-toggle-row]')) {
2177
+ inp.value = 'false';
2178
+ const toggleBtn = inp.closest('.toggle-shell')?.querySelector('[data-toggle]');
2179
+ if (toggleBtn) {
2180
+ toggleBtn.textContent = 'Off';
2181
+ toggleBtn.classList.remove('on');
2182
+ }
2183
+ } else {
2184
+ inp.value = '';
2185
+ }
2186
+ refresh();
2187
+ }
2188
+
2189
+ function toggleField(key) {
2190
+ const inp = getFieldValueInput(key);
2191
+ if (!inp) return;
2192
+ const on = String(inp.value || '').trim().toLowerCase() !== 'true';
2193
+ inp.value = on ? 'true' : 'false';
2194
+ const btn = inp.closest('.toggle-shell')?.querySelector('[data-toggle]');
2195
+ if (btn) {
2196
+ btn.textContent = on ? 'On' : 'Off';
2197
+ btn.classList.toggle('on', on);
2198
+ }
2199
+ refresh();
2200
+ }
2201
+
2202
+ function bindFieldEvents() {
2203
+ document.querySelectorAll('[data-check]').forEach(el => el.addEventListener('change', () => { markSelected(); refresh(); }));
2204
+ document.querySelectorAll('[data-key]').forEach(el => el.addEventListener('input', refresh));
2205
+ document.querySelectorAll('[data-toggle]').forEach(btn => btn.addEventListener('click', () => toggleField(btn.dataset.toggle)));
2206
+ document.querySelectorAll('[data-pick-for]').forEach(sel => sel.addEventListener('change', () => handlePickerChange(sel)));
2207
+ document.querySelectorAll('[data-custom-for]').forEach(btn => btn.addEventListener('click', () => promptCustomModel(btn)));
2208
+ document.querySelectorAll('[data-clear-for]').forEach(btn => btn.addEventListener('click', () => resetPickerField(btn)));
2209
+ }
2210
+
2211
+ function renderSections() {
2212
+ const grouped = {};
2213
+ FIELDS.forEach(f => { (grouped[f.g] ||= []).push(f); });
2214
+
2215
+ const wrap = $('sections');
2216
+ wrap.innerHTML = '';
2217
+ Object.entries(grouped).forEach(([grp, items]) => {
2218
+ const sec = document.createElement('div');
2219
+ sec.className = 'sec';
2220
+ sec.dataset.section = grp;
2221
+ sec.innerHTML = `
2222
+ <div class="sec-header">
2223
+ <span class="sec-icon">${ICONS[grp] || 'πŸ“'}</span>
2224
+ <span class="sec-title">${esc(grp)}</span>
2225
+ <div class="sec-line"></div>
2226
+ </div>
2227
+ <div class="cards">${items.map(cardHTML).join('')}</div>`;
2228
+ wrap.appendChild(sec);
2229
+ });
2230
+ bindFieldEvents();
2231
+ }
2232
+
2233
+ function copyText(text) {
2234
+ return navigator.clipboard.writeText(text).then(
2235
+ () => showToast('Copied βœ“'),
2236
+ () => {
2237
+ const ta = document.createElement('textarea');
2238
+ ta.value = text;
2239
+ ta.style.position = 'fixed';
2240
+ ta.style.left = '-9999px';
2241
+ document.body.appendChild(ta);
2242
+ ta.select();
2243
+ document.execCommand('copy');
2244
+ ta.remove();
2245
+ showToast('Copied βœ“');
2246
+ }
2247
+ );
2248
+ }
2249
+
2250
+ // ── Init ──
2251
+ renderSidebar();
2252
+ renderSections();
2253
+ addCustomRow();
2254
+ filter();
2255
+ refresh();
2256
+
2257
+ // ── Events ──
2258
+ $('search').oninput = filter;
2259
+ $('selectCommon').onclick = () => {
2260
+ document.querySelectorAll('[data-common="1"]').forEach(c => c.checked = true);
2261
+ markSelected();
2262
+ refresh();
2263
+ };
2264
+ $('selectVisible').onclick = () => {
2265
+ document.querySelectorAll('.sec:not(.sec-hidden) [data-row]:not(.hidden) [data-check]').forEach(c => c.checked = true);
2266
+ markSelected();
2267
+ refresh();
2268
+ };
2269
+ $('clearAll').onclick = () => {
2270
+ clearForm();
2271
+ markSelected();
2272
+ filter();
2273
+ refresh();
2274
+ };
2275
+ $('applyImport').onclick = () => {
2276
+ try {
2277
+ applyObj(parseEnv($('importText').value), true);
2278
+ showToast('Imported βœ“');
2279
+ } catch (e) {
2280
+ showToast('Import failed');
2281
+ alert(e.message);
2282
+ }
2283
+ };
2284
+ $('addCustom').onclick = () => addCustomRow();
2285
+ $('applyBundle').onclick = () => {
2286
+ try {
2287
+ applyObj(decodeBundle($('bundleOut').value), true);
2288
+ showToast('Bundle applied βœ“');
2289
+ } catch (e) {
2290
+ showToast('Invalid bundle');
2291
+ }
2292
+ };
2293
+ $('copyBundle').onclick = () => copyText($('bundleOut').value);
2294
+ $('copyEnvLine').onclick = () => copyText($('envLineOut').value);
2295
+ $('copyJson').onclick = () => copyText(JSON.stringify(collect(), null, 2));