ferrywuai commited on
Commit
41c0d09
·
1 Parent(s): 2f921c8

Add ChatSettings component with slider-based parameter control

Browse files

modified: README.md
modified: src/components/ChatInterface.jsx
new file: src/components/ChatSettings.jsx
new file: src/hooks/useChatSettings.js

README.md CHANGED
@@ -18,6 +18,7 @@ This project was bootstrapped with [Create React App](https://github.com/faceboo
18
  ## Features
19
 
20
  - Support user input of Hugging Face Access Token.
 
21
  - Support UI to send user input and get response of the chatbot.
22
  - Keep user input and response in chat history.
23
 
 
18
  ## Features
19
 
20
  - Support user input of Hugging Face Access Token.
21
+ - Support tuning system prompt and parameters: temperature, top_p, max_tokens.
22
  - Support UI to send user input and get response of the chatbot.
23
  - Keep user input and response in chat history.
24
 
src/components/ChatInterface.jsx CHANGED
@@ -1,4 +1,5 @@
1
  import { useState } from "react";
 
2
  import MessageInput from "./MessageInput";
3
  import MessagePair from "./MessagePair";
4
  import TokenInput from "./TokenInput";
@@ -6,16 +7,24 @@ import TokenInput from "./TokenInput";
6
  export default function ChatInterface() {
7
  const [hfClient, setHFClient] = useState(null);
8
  const [chatHistory, setChatHistory] = useState([]);
 
9
 
10
  const handleMessageSend = async (message) => {
11
  if (!hfClient) {
12
  alert("Please enter a valid Hugging Face token first.");
13
  return;
14
  }
 
15
 
16
  const result = await hfClient.chatCompletion({
17
  model: "openai/gpt-oss-20b",
18
- messages: [{ role: "user", content: message }],
 
 
 
 
 
 
19
  });
20
 
21
  const assistantReply = result.choices[0].message.content;
@@ -43,6 +52,11 @@ export default function ChatInterface() {
43
  <TokenInput onHFClientReady={handleHFClientReady} />
44
  </div>
45
 
 
 
 
 
 
46
  {/* Input area */}
47
  <div>
48
  <MessageInput onSend={handleMessageSend} />
 
1
  import { useState } from "react";
2
+ import ChatSettings from "./ChatSettings";
3
  import MessageInput from "./MessageInput";
4
  import MessagePair from "./MessagePair";
5
  import TokenInput from "./TokenInput";
 
7
  export default function ChatInterface() {
8
  const [hfClient, setHFClient] = useState(null);
9
  const [chatHistory, setChatHistory] = useState([]);
10
+ const [chatSettings, setChatSettings] = useState();
11
 
12
  const handleMessageSend = async (message) => {
13
  if (!hfClient) {
14
  alert("Please enter a valid Hugging Face token first.");
15
  return;
16
  }
17
+ if (!chatSettings) return;
18
 
19
  const result = await hfClient.chatCompletion({
20
  model: "openai/gpt-oss-20b",
21
+ messages: [
22
+ { role: "system", content: chatSettings.system },
23
+ { role: "user", content: message },
24
+ ],
25
+ temperature: chatSettings.temperature,
26
+ top_p: chatSettings.top_p,
27
+ max_tokens: chatSettings.max_tokens,
28
  });
29
 
30
  const assistantReply = result.choices[0].message.content;
 
52
  <TokenInput onHFClientReady={handleHFClientReady} />
53
  </div>
54
 
55
+ {/* Chat settings */}
56
+ <div>
57
+ <ChatSettings onChange={(s) => setChatSettings(s)} />
58
+ </div>
59
+
60
  {/* Input area */}
61
  <div>
62
  <MessageInput onSend={handleMessageSend} />
src/components/ChatSettings.jsx ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useChatSettings } from "../hooks/useChatSettings";
2
+
3
+ export default function ChatSettings({ onChange }) {
4
+ const [settings, setSettings] = useChatSettings(onChange);
5
+
6
+ return (
7
+ <div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
8
+ <input
9
+ type="text"
10
+ value={settings.system}
11
+ onChange={(e) => setSettings({ ...settings, system: e.target.value })}
12
+ placeholder="System prompt (e.g. You are a helpful assistant)"
13
+ style={{ padding: "10px", fontSize: "16px" }}
14
+ />
15
+
16
+ <label>
17
+ Temperature: {settings.temperature}
18
+ <input
19
+ type="range"
20
+ min="0"
21
+ max="2"
22
+ step="0.1"
23
+ value={settings.temperature}
24
+ onChange={(e) =>
25
+ setSettings({
26
+ ...settings,
27
+ temperature: parseFloat(e.target.value),
28
+ })
29
+ }
30
+ />
31
+ </label>
32
+
33
+ <label>
34
+ Top-p: {settings.top_p}
35
+ <input
36
+ type="range"
37
+ min="0"
38
+ max="1"
39
+ step="0.05"
40
+ value={settings.top_p}
41
+ onChange={(e) =>
42
+ setSettings({ ...settings, top_p: parseFloat(e.target.value) })
43
+ }
44
+ />
45
+ </label>
46
+
47
+ <label>
48
+ Max tokens: {settings.max_tokens}
49
+ <input
50
+ type="range"
51
+ min="50"
52
+ max="1024"
53
+ step="50"
54
+ value={settings.max_tokens}
55
+ onChange={(e) =>
56
+ setSettings({ ...settings, max_tokens: parseInt(e.target.value) })
57
+ }
58
+ />
59
+ </label>
60
+ </div>
61
+ );
62
+ }
src/hooks/useChatSettings.js ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useEffect, useRef, useState } from "react";
2
+
3
+ // Manage chat settings and trigger onChange when settings change
4
+ export function useChatSettings(onChange) {
5
+ const [settings, setSettings] = useState({
6
+ system: "You are a helpful assistant.",
7
+ temperature: 0.7,
8
+ top_p: 1,
9
+ max_tokens: 512,
10
+ });
11
+
12
+ // Always use the latest onChange without triggering effect
13
+ const stableOnChange = useRef(onChange);
14
+ useEffect(() => {
15
+ stableOnChange.current = onChange;
16
+ }, [onChange]);
17
+
18
+ // Trigger onChange only when settings change
19
+ useEffect(() => {
20
+ stableOnChange.current(settings);
21
+ }, [settings]);
22
+
23
+ return [settings, setSettings];
24
+ }