Fraser commited on
Commit
836962d
·
1 Parent(s): 80733a2

working qwen demo

Browse files
Files changed (1) hide show
  1. qwen.html +298 -0
qwen.html ADDED
@@ -0,0 +1,298 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Qwen3 Demo</title>
7
+ <style>
8
+ body {
9
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
10
+ max-width: 800px;
11
+ margin: 0 auto;
12
+ padding: 20px;
13
+ background: #f5f5f5;
14
+ }
15
+
16
+ .container {
17
+ background: white;
18
+ border-radius: 12px;
19
+ padding: 30px;
20
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
21
+ }
22
+
23
+ h1 {
24
+ color: #333;
25
+ text-align: center;
26
+ margin-bottom: 30px;
27
+ }
28
+
29
+ .form-group {
30
+ margin-bottom: 20px;
31
+ }
32
+
33
+ label {
34
+ display: block;
35
+ margin-bottom: 8px;
36
+ font-weight: 600;
37
+ color: #555;
38
+ }
39
+
40
+ textarea {
41
+ width: 100%;
42
+ min-height: 120px;
43
+ padding: 12px;
44
+ border: 2px solid #e1e5e9;
45
+ border-radius: 8px;
46
+ font-size: 14px;
47
+ resize: vertical;
48
+ box-sizing: border-box;
49
+ }
50
+
51
+ textarea:focus {
52
+ outline: none;
53
+ border-color: #007aff;
54
+ }
55
+
56
+ button {
57
+ background: #007aff;
58
+ color: white;
59
+ border: none;
60
+ padding: 12px 24px;
61
+ border-radius: 8px;
62
+ font-size: 16px;
63
+ cursor: pointer;
64
+ transition: background 0.2s;
65
+ }
66
+
67
+ button:hover:not(:disabled) {
68
+ background: #0056b3;
69
+ }
70
+
71
+ button:disabled {
72
+ background: #ccc;
73
+ cursor: not-allowed;
74
+ }
75
+
76
+ .status {
77
+ margin: 20px 0;
78
+ padding: 12px;
79
+ border-radius: 6px;
80
+ font-weight: 500;
81
+ }
82
+
83
+ .status.connecting {
84
+ background: #fff3cd;
85
+ color: #856404;
86
+ border: 1px solid #ffeaa7;
87
+ }
88
+
89
+ .status.connected {
90
+ background: #d4edda;
91
+ color: #155724;
92
+ border: 1px solid #c3e6cb;
93
+ }
94
+
95
+ .status.error {
96
+ background: #f8d7da;
97
+ color: #721c24;
98
+ border: 1px solid #f5c6cb;
99
+ }
100
+
101
+ .response {
102
+ margin-top: 20px;
103
+ padding: 20px;
104
+ background: #f8f9fa;
105
+ border-radius: 8px;
106
+ border-left: 4px solid #007aff;
107
+ white-space: pre-wrap;
108
+ font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
109
+ font-size: 14px;
110
+ line-height: 1.5;
111
+ }
112
+
113
+ .hidden {
114
+ display: none;
115
+ }
116
+ </style>
117
+ </head>
118
+ <body>
119
+ <div class="container">
120
+ <h1>Qwen3 Demo</h1>
121
+
122
+ <div id="status" class="status connecting">
123
+ Connecting to Qwen/Qwen3-Demo...
124
+ </div>
125
+
126
+ <div class="form-group">
127
+ <label for="prompt">Enter your prompt:</label>
128
+ <textarea
129
+ id="prompt"
130
+ placeholder="Ask Qwen3 anything... For example: 'Explain quantum computing in simple terms' or 'Write a short story about a robot learning to paint'"
131
+ ></textarea>
132
+ </div>
133
+
134
+ <button id="submitBtn" onclick="generateResponse()" disabled>
135
+ Generate Response
136
+ </button>
137
+
138
+ <div id="response" class="response hidden"></div>
139
+ </div>
140
+
141
+ <script type="module">
142
+ // Import Gradio client using the same CDN pattern as your project
143
+ import { Client } from "https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js";
144
+
145
+ let qwenClient = null;
146
+ const statusEl = document.getElementById('status');
147
+ const submitBtn = document.getElementById('submitBtn');
148
+ const promptEl = document.getElementById('prompt');
149
+ const responseEl = document.getElementById('response');
150
+
151
+ // Initialize connection to Qwen/Qwen3-Demo
152
+ async function initializeClient() {
153
+ try {
154
+ qwenClient = await Client.connect("Qwen/Qwen3-Demo");
155
+
156
+ statusEl.textContent = "✅ Connected to Qwen/Qwen3-Demo";
157
+ statusEl.className = "status connected";
158
+ submitBtn.disabled = false;
159
+
160
+ console.log("Successfully connected to Qwen/Qwen3-Demo");
161
+ console.log("API Map:", qwenClient.api_map);
162
+ } catch (error) {
163
+ console.error("Failed to connect:", error);
164
+ statusEl.textContent = `❌ Failed to connect: ${error.message}`;
165
+ statusEl.className = "status error";
166
+ }
167
+ }
168
+
169
+ // Generate response using Qwen3
170
+ window.generateResponse = async function() {
171
+ if (!qwenClient) {
172
+ alert("Not connected to Qwen service");
173
+ return;
174
+ }
175
+
176
+ const prompt = promptEl.value.trim();
177
+ if (!prompt) {
178
+ alert("Please enter a prompt");
179
+ return;
180
+ }
181
+
182
+ submitBtn.disabled = true;
183
+ submitBtn.textContent = "Generating...";
184
+ responseEl.className = "response hidden";
185
+
186
+ try {
187
+ // Based on the source code analysis:
188
+ // add_message: 13 is the correct function
189
+ // It expects [input, settings_form, thinking_btn_state, state] parameters
190
+
191
+ console.log("Using add_message function (fn_index 13) from API map");
192
+
193
+ // Create the required state structure based on app.py
194
+ const defaultState = {
195
+ "conversation_contexts": {},
196
+ "conversations": [],
197
+ "conversation_id": "",
198
+ };
199
+
200
+ // Create default settings based on config.py
201
+ const defaultSettings = {
202
+ "model": "qwen3-235b-a22b", // DEFAULT_MODEL from config.py
203
+ "sys_prompt": "You are a helpful and harmless assistant.", // DEFAULT_SYS_PROMPT
204
+ "thinking_budget": 38 // DEFAULT_THINKING_BUDGET
205
+ };
206
+
207
+ // Create thinking button state
208
+ const thinkingBtnState = {
209
+ "enable_thinking": true
210
+ };
211
+
212
+ console.log("Calling add_message with parameters:", {
213
+ input: prompt,
214
+ settings: defaultSettings,
215
+ thinking: thinkingBtnState,
216
+ state: defaultState
217
+ });
218
+
219
+ // Call the add_message function (fn_index 13)
220
+ const output = await qwenClient.predict(13, [
221
+ prompt, // input_value
222
+ defaultSettings, // settings_form_value
223
+ thinkingBtnState, // thinking_btn_state_value
224
+ defaultState // state_value
225
+ ]);
226
+
227
+ console.log("add_message response:", output);
228
+ console.log("Chatbot data (index 5):", output.data[5]);
229
+ if (output.data[5] && output.data[5].value) {
230
+ console.log("Chat history:", output.data[5].value);
231
+ }
232
+
233
+ // Extract the chatbot response from the output
234
+ let responseText = "";
235
+ if (output && output.data && Array.isArray(output.data)) {
236
+ // The add_message function returns multiple updates
237
+ // The chatbot response is at index 5 in the outputs array
238
+ const chatbotUpdate = output.data[5]; // chatbot is at index 5 in the outputs array
239
+
240
+ if (chatbotUpdate && chatbotUpdate.value && Array.isArray(chatbotUpdate.value)) {
241
+ // The value array contains the chat history
242
+ const chatHistory = chatbotUpdate.value;
243
+
244
+ if (chatHistory.length > 0) {
245
+ // Get the last message (assistant's response)
246
+ const lastMessage = chatHistory[chatHistory.length - 1];
247
+
248
+ if (lastMessage && lastMessage.content && Array.isArray(lastMessage.content)) {
249
+ // Extract text content from the message
250
+ const textContents = lastMessage.content
251
+ .filter(item => item.type === "text")
252
+ .map(item => item.content)
253
+ .join("\n");
254
+ responseText = textContents || "Response received but no text content found";
255
+ } else if (lastMessage && lastMessage.role === "assistant") {
256
+ // Fallback - if content structure is different
257
+ responseText = JSON.stringify(lastMessage, null, 2);
258
+ } else {
259
+ responseText = "Last message structure unexpected: " + JSON.stringify(lastMessage, null, 2);
260
+ }
261
+ } else {
262
+ responseText = "No messages in chat history";
263
+ }
264
+ } else {
265
+ responseText = "No chatbot value found in response: " + JSON.stringify(chatbotUpdate, null, 2);
266
+ }
267
+ } else {
268
+ responseText = "Unexpected response format: " + JSON.stringify(output, null, 2);
269
+ }
270
+
271
+ responseEl.textContent = responseText;
272
+ responseEl.className = "response";
273
+
274
+ } catch (error) {
275
+ console.error("Generation error:", error);
276
+ responseEl.textContent = `Error: ${error.message}`;
277
+ responseEl.className = "response";
278
+ } finally {
279
+ submitBtn.disabled = false;
280
+ submitBtn.textContent = "Generate Response";
281
+ }
282
+ };
283
+
284
+ // Handle Enter key in textarea (Shift+Enter for new line, Enter to submit)
285
+ promptEl.addEventListener('keydown', function(e) {
286
+ if (e.key === 'Enter' && !e.shiftKey) {
287
+ e.preventDefault();
288
+ if (!submitBtn.disabled) {
289
+ generateResponse();
290
+ }
291
+ }
292
+ });
293
+
294
+ // Initialize the client when the page loads
295
+ initializeClient();
296
+ </script>
297
+ </body>
298
+ </html>