ferrywuai commited on
Commit
2f921c8
·
1 Parent(s): 5a2eb52

Support user-provided HF token instead of env variable

Browse files

modified: README.md
modified: src/components/ChatInterface.jsx
new file: src/components/TokenInput.jsx
deleted: src/utils/hfClient.js

README.md CHANGED
@@ -17,24 +17,12 @@ This project was bootstrapped with [Create React App](https://github.com/faceboo
17
 
18
  ## Features
19
 
20
- - Get Hugging Face Access Token from environment variable.
21
  - Support UI to send user input and get response of the chatbot.
22
  - Keep user input and response in chat history.
23
 
24
  ## Usage
25
 
26
- ### Prerequisite
27
-
28
- - Create a test token on Hugging Face with read access only.
29
- - Export it in your shell:\
30
- `export REACT_APP_HF_TOKEN=your_test_token`
31
-
32
- ### Security note
33
-
34
- - The token is bundled into client-side JS and visible in browser DevTools.
35
- - For testing, create a temporary token with read-only permission.
36
- - After testing, revoke or delete the token to prevent exposure.
37
-
38
  ### Development mode
39
 
40
  - `npm start`
 
17
 
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
 
24
  ## Usage
25
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  ### Development mode
27
 
28
  - `npm start`
src/components/ChatInterface.jsx CHANGED
@@ -1,13 +1,19 @@
1
  import { useState } from "react";
2
- import { hf } from "../utils/hfClient";
3
  import MessageInput from "./MessageInput";
4
  import MessagePair from "./MessagePair";
 
5
 
6
  export default function ChatInterface() {
 
7
  const [chatHistory, setChatHistory] = useState([]);
8
 
9
  const handleMessageSend = async (message) => {
10
- const result = await hf.chatCompletion({
 
 
 
 
 
11
  model: "openai/gpt-oss-20b",
12
  messages: [{ role: "user", content: message }],
13
  });
@@ -17,6 +23,10 @@ export default function ChatInterface() {
17
  setChatHistory([newPair, ...chatHistory]);
18
  };
19
 
 
 
 
 
20
  return (
21
  <div
22
  style={{
@@ -28,6 +38,11 @@ export default function ChatInterface() {
28
  gap: "24px",
29
  }}
30
  >
 
 
 
 
 
31
  {/* Input area */}
32
  <div>
33
  <MessageInput onSend={handleMessageSend} />
 
1
  import { useState } from "react";
 
2
  import MessageInput from "./MessageInput";
3
  import MessagePair from "./MessagePair";
4
+ import TokenInput from "./TokenInput";
5
 
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
  });
 
23
  setChatHistory([newPair, ...chatHistory]);
24
  };
25
 
26
+ const handleHFClientReady = (client) => {
27
+ setHFClient(client);
28
+ };
29
+
30
  return (
31
  <div
32
  style={{
 
38
  gap: "24px",
39
  }}
40
  >
41
+ {/* Token input */}
42
+ <div>
43
+ <TokenInput onHFClientReady={handleHFClientReady} />
44
+ </div>
45
+
46
  {/* Input area */}
47
  <div>
48
  <MessageInput onSend={handleMessageSend} />
src/components/TokenInput.jsx ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { InferenceClient } from "@huggingface/inference";
2
+ import { useState } from "react";
3
+
4
+ export default function TokenInput({ onHFClientReady }) {
5
+ const [token, setToken] = useState("");
6
+
7
+ const handleConfirm = async () => {
8
+ if (!token.trim()) return;
9
+ const client = new InferenceClient(token);
10
+ onHFClientReady(client);
11
+ };
12
+
13
+ return (
14
+ <div style={{ display: "flex", gap: "10px" }}>
15
+ <input
16
+ type="password"
17
+ value={token}
18
+ onChange={(e) => setToken(e.target.value)}
19
+ placeholder="Enter Hugging Face token"
20
+ style={{ flex: 1, padding: "10px", fontSize: "16px" }}
21
+ />
22
+ <button onClick={handleConfirm} style={{ padding: "10px 20px" }}>
23
+ Confirm
24
+ </button>
25
+ </div>
26
+ );
27
+ }
src/utils/hfClient.js DELETED
@@ -1,5 +0,0 @@
1
- import { InferenceClient } from "@huggingface/inference";
2
-
3
- const HF_TOKEN = process.env.REACT_APP_HF_TOKEN;
4
-
5
- export const hf = new InferenceClient(HF_TOKEN);