|
<!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> |