| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Qwen3 Demo</title> |
| <style> |
| body { |
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; |
| max-width: 800px; |
| margin: 0 auto; |
| padding: 20px; |
| background: #f5f5f5; |
| } |
| |
| .container { |
| background: white; |
| border-radius: 12px; |
| padding: 30px; |
| box-shadow: 0 2px 10px rgba(0,0,0,0.1); |
| } |
| |
| h1 { |
| color: #333; |
| text-align: center; |
| margin-bottom: 30px; |
| } |
| |
| .form-group { |
| margin-bottom: 20px; |
| } |
| |
| label { |
| display: block; |
| margin-bottom: 8px; |
| font-weight: 600; |
| color: #555; |
| } |
| |
| textarea { |
| width: 100%; |
| min-height: 120px; |
| padding: 12px; |
| border: 2px solid #e1e5e9; |
| border-radius: 8px; |
| font-size: 14px; |
| resize: vertical; |
| box-sizing: border-box; |
| } |
| |
| textarea:focus { |
| outline: none; |
| border-color: #007aff; |
| } |
| |
| button { |
| background: #007aff; |
| color: white; |
| border: none; |
| padding: 12px 24px; |
| border-radius: 8px; |
| font-size: 16px; |
| cursor: pointer; |
| transition: background 0.2s; |
| } |
| |
| button:hover:not(:disabled) { |
| background: #0056b3; |
| } |
| |
| button:disabled { |
| background: #ccc; |
| cursor: not-allowed; |
| } |
| |
| .status { |
| margin: 20px 0; |
| padding: 12px; |
| border-radius: 6px; |
| font-weight: 500; |
| } |
| |
| .status.connecting { |
| background: #fff3cd; |
| color: #856404; |
| border: 1px solid #ffeaa7; |
| } |
| |
| .status.connected { |
| background: #d4edda; |
| color: #155724; |
| border: 1px solid #c3e6cb; |
| } |
| |
| .status.error { |
| background: #f8d7da; |
| color: #721c24; |
| border: 1px solid #f5c6cb; |
| } |
| |
| .response { |
| margin-top: 20px; |
| padding: 20px; |
| background: #f8f9fa; |
| border-radius: 8px; |
| border-left: 4px solid #007aff; |
| white-space: pre-wrap; |
| font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace; |
| font-size: 14px; |
| line-height: 1.5; |
| } |
| |
| .hidden { |
| display: none; |
| } |
| </style> |
| </head> |
| <body> |
| <div class="container"> |
| <h1>Qwen3 Demo</h1> |
| |
| <div id="status" class="status connecting"> |
| Connecting to Qwen/Qwen3-Demo... |
| </div> |
| |
| <div class="form-group"> |
| <label for="prompt">Enter your prompt:</label> |
| <textarea |
| id="prompt" |
| placeholder="Ask Qwen3 anything... For example: 'Explain quantum computing in simple terms' or 'Write a short story about a robot learning to paint'" |
| ></textarea> |
| </div> |
| |
| <button id="submitBtn" onclick="generateResponse()" disabled> |
| Generate Response |
| </button> |
| |
| <div id="response" class="response hidden"></div> |
| </div> |
|
|
| <script type="module"> |
| |
| import { Client } from "https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js"; |
| |
| let qwenClient = null; |
| const statusEl = document.getElementById('status'); |
| const submitBtn = document.getElementById('submitBtn'); |
| const promptEl = document.getElementById('prompt'); |
| const responseEl = document.getElementById('response'); |
| |
| |
| async function initializeClient() { |
| try { |
| qwenClient = await Client.connect("Qwen/Qwen3-Demo"); |
| |
| statusEl.textContent = "✅ Connected to Qwen/Qwen3-Demo"; |
| statusEl.className = "status connected"; |
| submitBtn.disabled = false; |
| |
| console.log("Successfully connected to Qwen/Qwen3-Demo"); |
| console.log("API Map:", qwenClient.api_map); |
| } catch (error) { |
| console.error("Failed to connect:", error); |
| statusEl.textContent = `❌ Failed to connect: ${error.message}`; |
| statusEl.className = "status error"; |
| } |
| } |
| |
| |
| window.generateResponse = async function() { |
| if (!qwenClient) { |
| alert("Not connected to Qwen service"); |
| return; |
| } |
| |
| const prompt = promptEl.value.trim(); |
| if (!prompt) { |
| alert("Please enter a prompt"); |
| return; |
| } |
| |
| submitBtn.disabled = true; |
| submitBtn.textContent = "Generating..."; |
| responseEl.className = "response hidden"; |
| |
| try { |
| |
| |
| |
| |
| console.log("Using add_message function (fn_index 13) from API map"); |
| |
| |
| const defaultState = { |
| "conversation_contexts": {}, |
| "conversations": [], |
| "conversation_id": "", |
| }; |
| |
| |
| const defaultSettings = { |
| "model": "qwen3-235b-a22b", |
| "sys_prompt": "You are a helpful and harmless assistant.", |
| "thinking_budget": 38 |
| }; |
| |
| |
| const thinkingBtnState = { |
| "enable_thinking": true |
| }; |
| |
| console.log("Calling add_message with parameters:", { |
| input: prompt, |
| settings: defaultSettings, |
| thinking: thinkingBtnState, |
| state: defaultState |
| }); |
| |
| |
| const output = await qwenClient.predict(13, [ |
| prompt, |
| defaultSettings, |
| thinkingBtnState, |
| defaultState |
| ]); |
| |
| console.log("add_message response:", output); |
| console.log("Chatbot data (index 5):", output.data[5]); |
| if (output.data[5] && output.data[5].value) { |
| console.log("Chat history:", output.data[5].value); |
| } |
| |
| |
| let responseText = ""; |
| if (output && output.data && Array.isArray(output.data)) { |
| |
| |
| const chatbotUpdate = output.data[5]; |
| |
| if (chatbotUpdate && chatbotUpdate.value && Array.isArray(chatbotUpdate.value)) { |
| |
| const chatHistory = chatbotUpdate.value; |
| |
| if (chatHistory.length > 0) { |
| |
| const lastMessage = chatHistory[chatHistory.length - 1]; |
| |
| if (lastMessage && lastMessage.content && Array.isArray(lastMessage.content)) { |
| |
| const textContents = lastMessage.content |
| .filter(item => item.type === "text") |
| .map(item => item.content) |
| .join("\n"); |
| responseText = textContents || "Response received but no text content found"; |
| } else if (lastMessage && lastMessage.role === "assistant") { |
| |
| responseText = JSON.stringify(lastMessage, null, 2); |
| } else { |
| responseText = "Last message structure unexpected: " + JSON.stringify(lastMessage, null, 2); |
| } |
| } else { |
| responseText = "No messages in chat history"; |
| } |
| } else { |
| responseText = "No chatbot value found in response: " + JSON.stringify(chatbotUpdate, null, 2); |
| } |
| } else { |
| responseText = "Unexpected response format: " + JSON.stringify(output, null, 2); |
| } |
| |
| responseEl.textContent = responseText; |
| responseEl.className = "response"; |
| |
| } catch (error) { |
| console.error("Generation error:", error); |
| responseEl.textContent = `Error: ${error.message}`; |
| responseEl.className = "response"; |
| } finally { |
| submitBtn.disabled = false; |
| submitBtn.textContent = "Generate Response"; |
| } |
| }; |
| |
| |
| promptEl.addEventListener('keydown', function(e) { |
| if (e.key === 'Enter' && !e.shiftKey) { |
| e.preventDefault(); |
| if (!submitBtn.disabled) { |
| generateResponse(); |
| } |
| } |
| }); |
| |
| |
| initializeClient(); |
| </script> |
| </body> |
| </html> |