abbasyk60 commited on
Commit
0b6cad1
·
1 Parent(s): 68cd3b2

Switch to static Space with HTML chat UI

Browse files
Files changed (6) hide show
  1. .gitignore +2 -3
  2. Dockerfile +0 -43
  3. README.md +3 -24
  4. entrypoint.sh +0 -75
  5. index.html +241 -0
  6. opencode.json +0 -73
.gitignore CHANGED
@@ -1,5 +1,4 @@
1
- node_modules/
2
- data/
3
  .env
4
- *.log
5
  .DS_Store
 
1
+ __pycache__/
2
+ *.pyc
3
  .env
 
4
  .DS_Store
Dockerfile DELETED
@@ -1,43 +0,0 @@
1
- FROM node:20-slim
2
-
3
- # Install system dependencies
4
- RUN apt-get update && apt-get install -y \
5
- git \
6
- curl \
7
- procps \
8
- lsof \
9
- python3 \
10
- && rm -rf /var/lib/apt/lists/*
11
-
12
- # Install OpenCode
13
- RUN npm install -g opencode-ai
14
-
15
- # Create app directory
16
- WORKDIR /app
17
-
18
- # Copy package.json and install dependencies
19
- COPY package.json ./
20
- RUN npm install --production
21
-
22
- # Copy OpenCode config
23
- COPY opencode.json /root/.config/opencode/opencode.json
24
-
25
- # Copy bot code
26
- COPY bot.js ./
27
-
28
- # Create entrypoint script
29
- COPY entrypoint.sh /entrypoint.sh
30
- RUN chmod +x /entrypoint.sh
31
-
32
- # Create data directories
33
- RUN mkdir -p /app/data /root/.local/share/opencode
34
-
35
- # Expose port 7860 for HF Spaces
36
- EXPOSE 7860
37
-
38
- # Health check
39
- HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
40
- CMD curl -f http://localhost:7860/ || exit 1
41
-
42
- # Run entrypoint
43
- ENTRYPOINT ["/entrypoint.sh"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
README.md CHANGED
@@ -3,31 +3,10 @@ title: OpenCode AI Agent
3
  emoji: 🤖
4
  colorFrom: blue
5
  colorTo: purple
6
- sdk: docker
7
- app_port: 7860
8
  pinned: true
9
  ---
10
 
11
- # OpenCode AI Agent on HuggingFace Spaces
12
 
13
- AI coding agent with Web UI and Telegram integration powered by OpenCode Zen.
14
-
15
- ## Features
16
-
17
- - **Web UI**: Access OpenCode directly in your browser
18
- - **Telegram Bot**: Chat with OpenCode via Telegram
19
- - **Multiple Models**: GPT-5, Claude, Gemini, DeepSeek and more
20
- - **Free Models Available**: DeepSeek V4 Flash Free, MiMo-V2.5 Free
21
-
22
- ## Access
23
-
24
- - **Web UI**: [https://abbasyk60-opencode.hf.space](https://abbasyk60-opencode.hf.space)
25
- - **Telegram**: Send messages to your bot in the configured supergroup
26
-
27
- ## Configuration
28
-
29
- Environment variables (set in HF Space secrets):
30
-
31
- - `OPENCODE_ZEN_KEY` - OpenCode Zen API key
32
- - `TELEGRAM_BOT_TOKEN` - Telegram bot token
33
- - `TELEGRAM_CHAT_ID` - Telegram supergroup chat ID
 
3
  emoji: 🤖
4
  colorFrom: blue
5
  colorTo: purple
6
+ sdk: static
 
7
  pinned: true
8
  ---
9
 
10
+ # OpenCode AI Agent
11
 
12
+ AI coding agent with Web UI powered by OpenCode Zen.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
entrypoint.sh DELETED
@@ -1,75 +0,0 @@
1
- #!/bin/bash
2
- set -e
3
-
4
- echo "========================================="
5
- echo " OpenCode AI Agent - Starting"
6
- echo "========================================="
7
-
8
- # Create OpenCode config directory
9
- mkdir -p /root/.config/opencode
10
-
11
- # Write OpenCode config if OPENCODE_ZEN_KEY is provided
12
- if [ -n "$OPENCODE_ZEN_KEY" ]; then
13
- cat > /root/.config/opencode/opencode.json <<EOF
14
- {
15
- "\$schema": "https://opencode.ai/config.json",
16
- "model": "opencode/gpt-5.4",
17
- "small_model": "opencode/gpt-5-nano",
18
- "provider": {
19
- "opencode": {
20
- "npm": "@ai-sdk/openai-compatible",
21
- "name": "OpenCode Zen",
22
- "options": {
23
- "baseURL": "https://opencode.ai/zen/v1",
24
- "apiKey": "$OPENCODE_ZEN_KEY"
25
- }
26
- }
27
- },
28
- "server": {
29
- "port": 7860,
30
- "hostname": "0.0.0.0"
31
- }
32
- }
33
- EOF
34
- echo "[OK] OpenCode config written"
35
- else
36
- echo "[WARN] OPENCODE_ZEN_KEY not set - using bundled config"
37
- cp /app/opencode.json /root/.config/opencode/opencode.json 2>/dev/null || true
38
- fi
39
-
40
- # Create data directories
41
- mkdir -p /root/.local/share/opencode
42
- mkdir -p /app/data
43
-
44
- # Start OpenCode web server in background
45
- echo "[OK] Starting OpenCode web server on port 7860..."
46
- opencode web --port 7860 --hostname 0.0.0.0 &
47
- OPENCODE_PID=$!
48
-
49
- # Wait for OpenCode to be ready
50
- echo "[OK] Waiting for OpenCode to start..."
51
- for i in $(seq 1 30); do
52
- if curl -s http://localhost:7860 > /dev/null 2>&1; then
53
- echo "[OK] OpenCode is ready!"
54
- break
55
- fi
56
- sleep 2
57
- done
58
-
59
- # Start Telegram bot if token is provided
60
- if [ -n "$TELEGRAM_BOT_TOKEN" ]; then
61
- echo "[OK] Starting Telegram bot..."
62
- node /app/bot.js &
63
- TELEGRAM_PID=$!
64
- echo "[OK] Telegram bot started!"
65
- else
66
- echo "[WARN] TELEGRAM_BOT_TOKEN not set - Telegram bot disabled"
67
- fi
68
-
69
- echo "========================================="
70
- echo " All services started!"
71
- echo " Web UI: http://localhost:7860"
72
- echo "========================================="
73
-
74
- # Keep the container running
75
- wait -n $OPENCODE_PID ${TELEGRAM_PID:-}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
index.html ADDED
@@ -0,0 +1,241 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>OpenCode AI Agent</title>
7
+ <style>
8
+ * { margin: 0; padding: 0; box-sizing: border-box; }
9
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #1a1a2e; color: #fff; height: 100vh; display: flex; flex-direction: column; }
10
+ .header { background: #16213e; padding: 15px 20px; border-bottom: 1px solid #0f3460; }
11
+ .header h1 { font-size: 1.4em; color: #e94560; }
12
+ .header p { font-size: 0.85em; color: #888; margin-top: 4px; }
13
+ .model-select { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
14
+ .model-select label { font-size: 0.9em; color: #aaa; }
15
+ .model-select select { background: #0f3460; color: #fff; border: 1px solid #e94560; padding: 6px 12px; border-radius: 6px; font-size: 0.9em; }
16
+ .chat-container { flex: 1; overflow-y: auto; padding: 20px; display: flex; flex-direction: column; gap: 12px; }
17
+ .message { max-width: 80%; padding: 12px 16px; border-radius: 12px; line-height: 1.5; font-size: 0.95em; white-space: pre-wrap; word-wrap: break-word; }
18
+ .message.user { align-self: flex-end; background: #e94560; color: #fff; border-bottom-right-radius: 4px; }
19
+ .message.bot { align-self: flex-start; background: #16213e; color: #ddd; border-bottom-left-radius: 4px; border: 1px solid #0f3460; }
20
+ .message.error { align-self: flex-start; background: #5c1a1a; color: #ff6b6b; }
21
+ .input-area { padding: 15px 20px; background: #16213e; border-top: 1px solid #0f3460; display: flex; gap: 10px; }
22
+ .input-area textarea { flex: 1; background: #0f3460; color: #fff; border: 1px solid #333; border-radius: 8px; padding: 12px; font-size: 0.95em; resize: none; font-family: inherit; }
23
+ .input-area textarea:focus { outline: none; border-color: #e94560; }
24
+ .input-area button { background: #e94560; color: #fff; border: none; border-radius: 8px; padding: 12px 24px; font-size: 0.95em; cursor: pointer; font-weight: 600; }
25
+ .input-area button:hover { background: #c73650; }
26
+ .input-area button:disabled { background: #555; cursor: not-allowed; }
27
+ .api-key-area { padding: 10px 20px; background: #0d1117; border-top: 1px solid #333; }
28
+ .api-key-area input { width: 100%; background: #161b22; color: #c9d1d9; border: 1px solid #30363d; border-radius: 6px; padding: 8px 12px; font-size: 0.85em; font-family: monospace; }
29
+ .api-key-area input::placeholder { color: #484f58; }
30
+ .loading { display: inline-block; }
31
+ .loading::after { content: ''; animation: dots 1.5s infinite; }
32
+ @keyframes dots { 0%, 20% { content: '.'; } 40% { content: '..'; } 60%, 100% { content: '...'; } }
33
+ .free-tag { background: #2ea043; color: #fff; font-size: 0.7em; padding: 2px 6px; border-radius: 4px; margin-left: 6px; }
34
+ </style>
35
+ </head>
36
+ <body>
37
+ <div class="header">
38
+ <h1>🤖 OpenCode AI Agent</h1>
39
+ <p>Chat with AI models powered by OpenCode Zen</p>
40
+ <div class="model-select">
41
+ <label>Model:</label>
42
+ <select id="model-select">
43
+ <optgroup label="GPT Models">
44
+ <option value="gpt-5.6-sol">GPT 5.6 Sol</option>
45
+ <option value="gpt-5.6-terra">GPT 5.6 Terra</option>
46
+ <option value="gpt-5.6-luna">GPT 5.6 Luna</option>
47
+ <option value="gpt-5.5" selected>GPT 5.5</option>
48
+ <option value="gpt-5.5-pro">GPT 5.5 Pro</option>
49
+ <option value="gpt-5.4">GPT 5.4</option>
50
+ <option value="gpt-5.4-pro">GPT 5.4 Pro</option>
51
+ <option value="gpt-5.4-mini">GPT 5.4 Mini</option>
52
+ <option value="gpt-5.4-nano">GPT 5.4 Nano</option>
53
+ <option value="gpt-5.3-codex">GPT 5.3 Codex</option>
54
+ <option value="gpt-5.3-codex-spark">GPT 5.3 Codex Spark</option>
55
+ <option value="gpt-5.2">GPT 5.2</option>
56
+ <option value="gpt-5.1">GPT 5.1</option>
57
+ <option value="gpt-5">GPT 5</option>
58
+ <option value="gpt-5-nano">GPT 5 Nano</option>
59
+ </optgroup>
60
+ <optgroup label="Claude Models">
61
+ <option value="claude-fable-5">Claude Fable 5</option>
62
+ <option value="claude-opus-5">Claude Opus 5</option>
63
+ <option value="claude-opus-4-8">Claude Opus 4.8</option>
64
+ <option value="claude-opus-4-7">Claude Opus 4.7</option>
65
+ <option value="claude-opus-4-5">Claude Opus 4.5</option>
66
+ <option value="claude-sonnet-5">Claude Sonnet 5</option>
67
+ <option value="claude-sonnet-4-6">Claude Sonnet 4.6</option>
68
+ <option value="claude-sonnet-4-5">Claude Sonnet 4.5</option>
69
+ <option value="claude-haiku-4-5">Claude Haiku 4.5</option>
70
+ </optgroup>
71
+ <optgroup label="Gemini Models">
72
+ <option value="gemini-3.6-flash">Gemini 3.6 Flash</option>
73
+ <option value="gemini-3.5-flash">Gemini 3.5 Flash</option>
74
+ <option value="gemini-3.5-flash-lite">Gemini 3.5 Flash Lite</option>
75
+ <option value="gemini-3.1-pro">Gemini 3.1 Pro</option>
76
+ <option value="gemini-3-flash">Gemini 3 Flash</option>
77
+ </optgroup>
78
+ <optgroup label="Other Models">
79
+ <option value="grok-4.5">Grok 4.5</option>
80
+ <option value="qwen3.7-max">Qwen3.7 Max</option>
81
+ <option value="qwen3.7-plus">Qwen3.7 Plus</option>
82
+ <option value="deepseek-v4-pro">DeepSeek V4 Pro</option>
83
+ <option value="deepseek-v4-flash">DeepSeek V4 Flash</option>
84
+ <option value="kimi-k2.7-code">Kimi K2.7 Code</option>
85
+ <option value="minimax-m3">MiniMax M3</option>
86
+ <option value="glm-5.2">GLM 5.2</option>
87
+ </optgroup>
88
+ <optgroup label="Free Models">
89
+ <option value="deepseek-v4-flash-free">DeepSeek V4 Flash Free <span class="free-tag">FREE</span></option>
90
+ <option value="mimo-v2.5-free">MiMo-V2.5 Free <span class="free-tag">FREE</span></option>
91
+ <option value="big-pickle">Big Pickle Free <span class="free-tag">FREE</span></option>
92
+ <option value="laguna-s-2.1-free">Laguna S 2.1 Free <span class="free-tag">FREE</span></option>
93
+ <option value="ling-3.0-flash-free">Ling-3.0 Flash Free <span class="free-tag">FREE</span></option>
94
+ <option value="north-mini-code-free">North Mini Code Free <span class="free-tag">FREE</span></option>
95
+ <option value="nemotron-3-ultra-free">Nemotron 3 Ultra Free <span class="free-tag">FREE</span></option>
96
+ </optgroup>
97
+ </select>
98
+ </div>
99
+ </div>
100
+ <div class="chat-container" id="chat"></div>
101
+ <div class="api-key-area">
102
+ <input type="password" id="api-key" placeholder="Enter your OpenCode Zen API key (sk-...)" />
103
+ </div>
104
+ <div class="input-area">
105
+ <textarea id="user-input" placeholder="Type your message..." rows="2"></textarea>
106
+ <button id="send-btn" onclick="sendMessage()">Send</button>
107
+ </div>
108
+
109
+ <script>
110
+ const chatEl = document.getElementById('chat');
111
+ const inputEl = document.getElementById('user-input');
112
+ const sendBtn = document.getElementById('send-btn');
113
+ const apiKeyEl = document.getElementById('api-key');
114
+ const modelSelect = document.getElementById('model-select');
115
+ let history = [];
116
+
117
+ // Load saved API key
118
+ const savedKey = localStorage.getItem('opencode_zen_key');
119
+ if (savedKey) apiKeyEl.value = savedKey;
120
+
121
+ inputEl.addEventListener('keydown', (e) => {
122
+ if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); }
123
+ });
124
+
125
+ function addMessage(role, content, isError = false) {
126
+ const div = document.createElement('div');
127
+ div.className = `message ${role}${isError ? ' error' : ''}`;
128
+ div.textContent = content;
129
+ chatEl.appendChild(div);
130
+ chatEl.scrollTop = chatEl.scrollHeight;
131
+ }
132
+
133
+ function addLoading() {
134
+ const div = document.createElement('div');
135
+ div.className = 'message bot';
136
+ div.id = 'loading';
137
+ div.innerHTML = '<span class="loading">Thinking</span>';
138
+ chatEl.appendChild(div);
139
+ chatEl.scrollTop = chatEl.scrollHeight;
140
+ }
141
+
142
+ function removeLoading() {
143
+ const el = document.getElementById('loading');
144
+ if (el) el.remove();
145
+ }
146
+
147
+ function getEndpoint(modelId) {
148
+ const openaiPrefixes = ['gpt-', 'deepseek-', 'grok-', 'minimax-', 'glm-', 'kimi-', 'big-pickle', 'mimo-', 'laguna-', 'ling-', 'north-', 'nemotron-'];
149
+ if (openaiPrefixes.some(p => modelId.startsWith(p) || modelId.includes(p))) {
150
+ return 'https://opencode.ai/zen/v1/chat/completions';
151
+ }
152
+ if (modelId.startsWith('claude-') || modelId.startsWith('qwen3')) {
153
+ return 'https://opencode.ai/zen/v1/messages';
154
+ }
155
+ if (modelId.startsWith('gemini-')) {
156
+ return 'https://opencode.ai/zen/v1/models/' + modelId;
157
+ }
158
+ return 'https://opencode.ai/zen/v1/chat/completions';
159
+ }
160
+
161
+ async function sendMessage() {
162
+ const message = inputEl.value.trim();
163
+ const apiKey = apiKeyEl.value.trim();
164
+
165
+ if (!apiKey) { addMessage('error', 'Please enter your OpenCode Zen API key first.'); return; }
166
+ if (!message) return;
167
+
168
+ localStorage.setItem('opencode_zen_key', apiKey);
169
+
170
+ addMessage('user', message);
171
+ inputEl.value = '';
172
+ sendBtn.disabled = true;
173
+ addLoading();
174
+
175
+ const modelId = modelSelect.value;
176
+ const endpoint = getEndpoint(modelId);
177
+ const messages = [...history, { role: 'user', content: message }];
178
+
179
+ try {
180
+ let response, data;
181
+
182
+ if (endpoint.includes('/messages')) {
183
+ response = await fetch(endpoint, {
184
+ method: 'POST',
185
+ headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json', 'anthropic-version': '2023-06-01' },
186
+ body: JSON.stringify({ model: modelId, messages: messages, max_tokens: 4096 })
187
+ });
188
+ } else if (endpoint.includes('/models/')) {
189
+ response = await fetch(endpoint, {
190
+ method: 'POST',
191
+ headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
192
+ body: JSON.stringify({ contents: [{ parts: [{ text: message }] }] })
193
+ });
194
+ } else {
195
+ response = await fetch(endpoint, {
196
+ method: 'POST',
197
+ headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
198
+ body: JSON.stringify({ model: modelId, messages: messages, max_tokens: 4096 })
199
+ });
200
+ }
201
+
202
+ removeLoading();
203
+
204
+ if (!response.ok) {
205
+ const errText = await response.text();
206
+ addMessage('error', `API Error ${response.status}: ${errText.substring(0, 500)}`);
207
+ sendBtn.disabled = false;
208
+ return;
209
+ }
210
+
211
+ data = await response.json();
212
+ let botMessage = '';
213
+
214
+ if (endpoint.includes('/messages') && data.content) {
215
+ botMessage = data.content.map(c => c.text || '').join('');
216
+ } else if (data.choices && data.choices[0]) {
217
+ botMessage = data.choices[0].message.content;
218
+ } else if (data.candidates && data.candidates[0]) {
219
+ botMessage = data.candidates[0].content.parts.map(p => p.text).join('');
220
+ } else {
221
+ botMessage = JSON.stringify(data, null, 2).substring(0, 2000);
222
+ }
223
+
224
+ addMessage('bot', botMessage);
225
+ history.push({ role: 'user', content: message });
226
+ history.push({ role: 'assistant', content: botMessage });
227
+
228
+ // Keep history manageable
229
+ if (history.length > 20) history = history.slice(-20);
230
+
231
+ } catch (err) {
232
+ removeLoading();
233
+ addMessage('error', `Error: ${err.message}`);
234
+ }
235
+
236
+ sendBtn.disabled = false;
237
+ inputEl.focus();
238
+ }
239
+ </script>
240
+ </body>
241
+ </html>
opencode.json DELETED
@@ -1,73 +0,0 @@
1
- {
2
- "$schema": "https://opencode.ai/config.json",
3
- "model": "opencode/gpt-5.4",
4
- "small_model": "opencode/gpt-5-nano",
5
- "provider": {
6
- "opencode": {
7
- "npm": "@ai-sdk/openai-compatible",
8
- "name": "OpenCode Zen",
9
- "options": {
10
- "baseURL": "https://opencode.ai/zen/v1",
11
- "apiKey": "{env:OPENCODE_ZEN_KEY}"
12
- },
13
- "models": {
14
- "gpt-5.4": { "name": "GPT 5.4" },
15
- "gpt-5.4-pro": { "name": "GPT 5.4 Pro" },
16
- "gpt-5.4-mini": { "name": "GPT 5.4 Mini" },
17
- "gpt-5.4-nano": { "name": "GPT 5.4 Nano" },
18
- "gpt-5.5": { "name": "GPT 5.5" },
19
- "gpt-5.5-pro": { "name": "GPT 5.5 Pro" },
20
- "gpt-5.3-codex": { "name": "GPT 5.3 Codex" },
21
- "gpt-5.3-codex-spark": { "name": "GPT 5.3 Codex Spark" },
22
- "gpt-5.2": { "name": "GPT 5.2" },
23
- "gpt-5.1": { "name": "GPT 5.1" },
24
- "gpt-5": { "name": "GPT 5" },
25
- "gpt-5-nano": { "name": "GPT 5 Nano" },
26
- "gpt-5.6-sol": { "name": "GPT 5.6 Sol" },
27
- "gpt-5.6-terra": { "name": "GPT 5.6 Terra" },
28
- "gpt-5.6-luna": { "name": "GPT 5.6 Luna" },
29
- "claude-sonnet-5": { "name": "Claude Sonnet 5" },
30
- "claude-opus-5": { "name": "Claude Opus 5" },
31
- "claude-opus-4-8": { "name": "Claude Opus 4.8" },
32
- "claude-opus-4-7": { "name": "Claude Opus 4.7" },
33
- "claude-opus-4-5": { "name": "Claude Opus 4.5" },
34
- "claude-sonnet-4-6": { "name": "Claude Sonnet 4.6" },
35
- "claude-sonnet-4-5": { "name": "Claude Sonnet 4.5" },
36
- "claude-haiku-4-5": { "name": "Claude Haiku 4.5" },
37
- "claude-fable-5": { "name": "Claude Fable 5" },
38
- "gemini-3.6-flash": { "name": "Gemini 3.6 Flash" },
39
- "gemini-3.5-flash": { "name": "Gemini 3.5 Flash" },
40
- "gemini-3.5-flash-lite": { "name": "Gemini 3.5 Flash Lite" },
41
- "gemini-3.1-pro": { "name": "Gemini 3.1 Pro" },
42
- "gemini-3-flash": { "name": "Gemini 3 Flash" },
43
- "grok-4.5": { "name": "Grok 4.5" },
44
- "grok-build-0.1": { "name": "Grok Build 0.1" },
45
- "qwen3.7-max": { "name": "Qwen3.7 Max" },
46
- "qwen3.7-plus": { "name": "Qwen3.7 Plus" },
47
- "qwen3.6-plus": { "name": "Qwen3.6 Plus" },
48
- "qwen3.5-plus": { "name": "Qwen3.5 Plus" },
49
- "deepseek-v4-pro": { "name": "DeepSeek V4 Pro" },
50
- "deepseek-v4-flash": { "name": "DeepSeek V4 Flash" },
51
- "deepseek-v4-flash-free": { "name": "DeepSeek V4 Flash Free" },
52
- "minimax-m3": { "name": "MiniMax M3" },
53
- "minimax-m2.7": { "name": "MiniMax M2.7" },
54
- "glm-5.2": { "name": "GLM 5.2" },
55
- "glm-5.1": { "name": "GLM 5.1" },
56
- "kimi-k2.5": { "name": "Kimi K2.5" },
57
- "kimi-k2.6": { "name": "Kimi K2.6" },
58
- "kimi-k2.7-code": { "name": "Kimi K2.7 Code" },
59
- "big-pickle": { "name": "Big Pickle" },
60
- "mimo-v2.5-free": { "name": "MiMo-V2.5 Free" },
61
- "laguna-s-2.1-free": { "name": "Laguna S 2.1 Free" },
62
- "ling-3.0-flash-free": { "name": "Ling-3.0 Flash Free" },
63
- "north-mini-code-free": { "name": "North Mini Code Free" },
64
- "nemotron-3-ultra-free": { "name": "Nemotron 3 Ultra Free" }
65
- }
66
- }
67
- },
68
- "server": {
69
- "port": 7860,
70
- "hostname": "0.0.0.0",
71
- "cors": ["*"]
72
- }
73
- }