lenzcom commited on
Commit
2396865
·
verified ·
1 Parent(s): 6e55e67

Upload folder using huggingface_hub

Browse files
Files changed (4) hide show
  1. CHANGELOG.md +16 -0
  2. PROJECT_ANALYSIS.md +45 -0
  3. backup/server.js +254 -0
  4. server.js +5 -4
CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Changelog
2
+
3
+ ## [Unreleased] - 2026-02-12
4
+ ### Added
5
+ - Created \PROJECT_ANALYSIS.md\ to document system architecture.
6
+ - Created \CHANGELOG.md\.
7
+
8
+ ### Changed
9
+ - **server.js**:
10
+ - Updated reference from \MssterPrompt_Talk2People.txt\ to \MasterPrompt_Talk2People.txt\.
11
+ - Updated UI loading state to show '�ang suy nghi...'.
12
+ - Updated initial chat greeting to the new 'dahanhstd-1.0' persona.
13
+ - **MasterPrompt_Talk2People.txt**:
14
+ - Renamed from \MssterPrompt_Talk2People.txt\ to fix typo.
15
+ - Updated system prompt content to match the 'dahanhstd-1.0' persona (removing Video Director prompt).
16
+
PROJECT_ANALYSIS.md ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Project Analysis: AI Agents from Scratch (Lenzcom Email/Chat)
2
+
3
+ ## Overview
4
+ This project is a Node.js-based AI Chat Application hosted on Hugging Face Spaces. It serves a single-page web interface where users can interact with an AI model (dahanhstd-1.0) powered by
5
+ ode-llama-cpp. The application is designed to be self-contained, with the HTML frontend embedded directly in the server code.
6
+
7
+ ## Directory Structure
8
+ - **Root**: H:\BuilddingProject\ai-agents-from-scratch
9
+ - **Source Code**:
10
+ - server.js: The main entry point. Handles HTTP requests, serves the embedded HTML, and manages the LLM inference.
11
+ - src/index.js (implied): Contains the AI logic wrapper classes (SystemMessage, HumanMessage, etc.).
12
+ - **Configuration**:
13
+ - MssterPrompt_Talk2People.txt (to be renamed): Contains the system prompt for the 'talk2people' role.
14
+ - secrets.local.md: Stores local secrets (not to be pushed).
15
+ - **Deployment**:
16
+ - hf_deploy.py: Python script for deploying to Hugging Face Spaces.
17
+
18
+ ## Key Components
19
+ 1. **Server (server.js)**:
20
+ - Uses express for the web server.
21
+ - Dynamically imports AI modules from ./src/index.js.
22
+ - Loads the LLM model from ./models/Qwen3-1.7B-Q8_0.gguf.
23
+ - Defines prompts for different roles ('talk2people', 'coder', 'default').
24
+ - Embeds the frontend HTML/CSS/JS in the HTML_PAGE constant.
25
+
26
+ 2. **Frontend (Embedded in server.js)**:
27
+ - Simple HTML/CSS/JS interface.
28
+ - Communicates with the backend via /chat (POST) and /info (GET) endpoints.
29
+ - Handles chat history and role switching.
30
+
31
+ ## Logic Flow
32
+ 1. **Initialization**: Server starts, loads the LLM model (initModel()).
33
+ 2. **User Request**: User sends a message via the web UI.
34
+ 3. **Processing**:
35
+ - Frontend sends JSON to /chat.
36
+ - Backend constructs a message chain (System + History + User Message).
37
+ - LLM generates a response.
38
+ 4. **Response**: Backend returns JSON { reply, model, ... } to the frontend.
39
+
40
+ ## Current Issues & TODOs
41
+ - **File Naming**: MssterPrompt_Talk2People.txt has a typo.
42
+ - **Role/Prompt Mismatch**: The text in the prompt file does not match the 'Talk2People' persona.
43
+ - **UI Feedback**: 'Thinking' state is just '...', needs to be more descriptive.
44
+ - **Greeting**: Initial greeting is hardcoded and outdated.
45
+
backup/server.js ADDED
@@ -0,0 +1,254 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ console.log("--> SERVER STARTING...");
2
+ import express from 'express';
3
+ // --- DYNAMIC IMPORT ---
4
+ let SystemMessage, HumanMessage, AIMessage, LlamaCppLLM;
5
+ try {
6
+ const module = await import('./src/index.js');
7
+ SystemMessage = module.SystemMessage;
8
+ HumanMessage = module.HumanMessage;
9
+ AIMessage = module.AIMessage;
10
+ LlamaCppLLM = module.LlamaCppLLM;
11
+ console.log("--> Modules loaded successfully");
12
+ } catch (e) {
13
+ console.error("--> FATAL IMPORT ERROR:", e);
14
+ }
15
+
16
+ import bodyParser from 'body-parser';
17
+ import fs from 'fs';
18
+ import path from 'path';
19
+
20
+ // --- CONFIGURATION ---
21
+ const PORT = 7860;
22
+ const MODEL_PATH = './models/Qwen3-1.7B-Q8_0.gguf';
23
+ const MODEL_NAME = "dahanhstd-1.0"; // Tên model tùy chỉnh
24
+
25
+ // --- LOAD PROMPTS ---
26
+ const PROMPTS = {
27
+ "default": "You are a helpful AI assistant. Answer concisely.",
28
+ "talk2people": fs.existsSync('MssterPrompt_Talk2People.txt')
29
+ ? fs.readFileSync('MssterPrompt_Talk2People.txt', 'utf-8')
30
+ : "You are a creative Video Director specializing in realistic Vietnamese scenes.",
31
+ "coder": "You are an expert programmer."
32
+ };
33
+
34
+ // --- HTML TEMPLATE (GIAO DIỆN CHAT) ---
35
+ const HTML_PAGE = `
36
+ <!DOCTYPE html>
37
+ <html lang="vi">
38
+ <head>
39
+ <meta charset="UTF-8">
40
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
41
+ <title>Dạ Hành AI Studio</title>
42
+ <style>
43
+ :root { --primary:#00ff88; --bg:#121212; --chat-bg:#1e1e1e; --user-bg:#2a2a2a; --ai-bg:#0a3a2a; }
44
+ body { font-family:'Segoe UI',sans-serif; background:var(--bg); color:white; margin:0; display:flex; height:100vh; overflow:hidden; }
45
+ .sidebar { width:260px; background:#000; padding:20px; border-right:1px solid #333; display:flex; flex-direction:column; }
46
+ .main { flex:1; display:flex; flex-direction:column; padding:20px; position:relative; }
47
+ h1 { font-size:1.2rem; color:var(--primary); margin-bottom:20px; text-transform:uppercase; letter-spacing:1px; }
48
+ select { width:100%; padding:12px; background:#333; color:white; border:1px solid #555; border-radius:8px; margin-bottom:20px; outline:none; }
49
+ #chat-box { flex:1; overflow-y:auto; background:var(--chat-bg); border-radius:12px; padding:20px; margin-bottom:20px; display:flex; flex-direction:column; gap:15px; scroll-behavior:smooth; }
50
+ .message { max-width:80%; padding:12px 18px; border-radius:18px; line-height:1.5; font-size:0.95rem; animation:fadeIn 0.3s ease; }
51
+ .message.ai { align-self:flex-start; background:var(--ai-bg); border-bottom-left-radius:4px; }
52
+ .message.user { align-self:flex-end; background:var(--user-bg); border-bottom-right-radius:4px; color:#ddd; }
53
+ .input-area { display:flex; gap:10px; }
54
+ input { flex:1; padding:15px 20px; border-radius:30px; border:1px solid #444; background:#222; color:white; outline:none; font-size:1rem; }
55
+ input:focus { border-color:var(--primary); }
56
+ button { padding:10px 30px; border-radius:30px; border:none; background:var(--primary); color:black; font-weight:bold; cursor:pointer; transition:0.2s; }
57
+ button:hover { transform:scale(1.05); box-shadow:0 0 10px var(--primary); }
58
+ .status { margin-top:auto; font-size:0.8rem; color:#666; border-top:1px solid #333; padding-top:15px; }
59
+ @keyframes fadeIn { from { opacity:0; transform:translateY(10px); } to { opacity:1; transform:translateY(0); } }
60
+ /* Scrollbar */
61
+ ::-webkit-scrollbar { width:8px; }
62
+ ::-webkit-scrollbar-track { background:#1e1e1e; }
63
+ ::-webkit-scrollbar-thumb { background:#444; border-radius:4px; }
64
+ </style>
65
+ </head>
66
+ <body>
67
+ <div class="sidebar">
68
+ <h1>DẠ HÀNH STUDIO</h1>
69
+ <label style="font-size:0.9rem; color:#aaa; margin-bottom:5px">Chọn Role:</label>
70
+ <select id="role-select">
71
+ <option value="talk2people">🎬 Đạo diễn (Talk2People)</option>
72
+ <option value="coder">💻 Coder Expert</option>
73
+ <option value="default">🤖 Trợ lý ảo</option>
74
+ </select>
75
+ <div class="status">
76
+ Model: <b>${MODEL_NAME}</b><br>
77
+ Privacy: <b>Local Safe</b><br>
78
+ Status: <span id="status-text" style="color:yellow">Connecting...</span>
79
+ </div>
80
+ </div>
81
+ <div class="main">
82
+ <div id="chat-box"></div>
83
+ <div class="input-area">
84
+ <input type="text" id="user-input" placeholder="Nhập tin nhắn..." autocomplete="off">
85
+ <button onclick="sendMessage()">GỬI</button>
86
+ </div>
87
+ </div>
88
+ <script>
89
+ const chatBox = document.getElementById('chat-box');
90
+ const userInput = document.getElementById('user-input');
91
+ const roleSelect = document.getElementById('role-select');
92
+ const statusText = document.getElementById('status-text');
93
+ let chatHistory = [];
94
+
95
+ function addMessage(role, text) {
96
+ const div = document.createElement('div');
97
+ div.className = 'message ' + role;
98
+ div.innerText = text;
99
+ chatBox.appendChild(div);
100
+ chatBox.scrollTop = chatBox.scrollHeight;
101
+ }
102
+
103
+ async function checkHealth() {
104
+ try {
105
+ const res = await fetch('/info');
106
+ const data = await res.json();
107
+ statusText.innerText = "Online";
108
+ statusText.style.color = "#00ff88";
109
+ addMessage('ai', "Xin chào đây là hệ thống bot AI hoạt động riêng tư được đào tạo bởi Dạ Hành Studio, Không phụ thuộc vào Google");
110
+ } catch (e) {
111
+ statusText.innerText = "Offline";
112
+ statusText.style.color = "red";
113
+ }
114
+ }
115
+
116
+ async function sendMessage() {
117
+ const text = userInput.value.trim();
118
+ if (!text) return;
119
+
120
+ addMessage('user', text);
121
+ userInput.value = '';
122
+ chatHistory.push({ role: 'user', content: text });
123
+
124
+ // Loading effect
125
+ const loadingId = 'loading-' + Date.now();
126
+ const loadingDiv = document.createElement('div');
127
+ loadingDiv.className = 'message ai';
128
+ loadingDiv.id = loadingId;
129
+ loadingDiv.innerText = '...';
130
+ chatBox.appendChild(loadingDiv);
131
+ chatBox.scrollTop = chatBox.scrollHeight;
132
+
133
+ try {
134
+ const response = await fetch('/chat', {
135
+ method: 'POST',
136
+ headers: { 'Content-Type': 'application/json' },
137
+ body: JSON.stringify({
138
+ message: text,
139
+ history: chatHistory.slice(-10),
140
+ role: roleSelect.value
141
+ })
142
+ });
143
+ const data = await response.json();
144
+
145
+ document.getElementById(loadingId).remove();
146
+
147
+ if(data.error) {
148
+ addMessage('ai', 'Lỗi: ' + data.error);
149
+ } else {
150
+ addMessage('ai', data.reply);
151
+ chatHistory.push({ role: 'ai', content: data.reply });
152
+ }
153
+ } catch (error) {
154
+ document.getElementById(loadingId).remove();
155
+ addMessage('ai', 'Lỗi kết nối: ' + error.message);
156
+ }
157
+ }
158
+
159
+ userInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') sendMessage(); });
160
+ roleSelect.addEventListener('change', () => {
161
+ chatHistory = [];
162
+ chatBox.innerHTML = '';
163
+ addMessage('ai', "Đã chuyển sang chế độ: " + roleSelect.options[roleSelect.selectedIndex].text);
164
+ });
165
+
166
+ checkHealth();
167
+ </script>
168
+ </body>
169
+ </html>
170
+ `;
171
+
172
+ // --- AI ENGINE ---
173
+ let llm = null;
174
+
175
+ async function initModel() {
176
+ if (!LlamaCppLLM) return;
177
+ try {
178
+ console.log('--> Loading model...');
179
+ if (!fs.existsSync(MODEL_PATH)) {
180
+ console.error(`--> Model not found at ${MODEL_PATH}`);
181
+ // Fallback: check if we are in /app
182
+ return;
183
+ }
184
+ llm = new LlamaCppLLM({
185
+ modelPath: MODEL_PATH,
186
+ temperature: 0.7,
187
+ maxTokens: 1024
188
+ });
189
+ await llm.invoke("Hello");
190
+ console.log('--> Model loaded successfully.');
191
+ } catch (err) {
192
+ console.error('--> FATAL MODEL ERROR:', err.message);
193
+ }
194
+ }
195
+
196
+ // --- SERVER SETUP ---
197
+ const app = express();
198
+ app.use(bodyParser.json());
199
+
200
+ // 1. API: CHAT (Public API for other apps)
201
+ app.post('/chat', async (req, res) => {
202
+ // API Response Format
203
+ const apiResponse = {
204
+ model: MODEL_NAME,
205
+ created: Date.now(),
206
+ reply: "",
207
+ error: null
208
+ };
209
+
210
+ if (!llm) {
211
+ apiResponse.error = "System initializing or Model missing";
212
+ return res.status(503).json(apiResponse);
213
+ }
214
+
215
+ try {
216
+ const { message, history = [], role = 'default' } = req.body;
217
+ const systemInstruction = PROMPTS[role] || PROMPTS['default'];
218
+
219
+ const messages = [new SystemMessage(systemInstruction)];
220
+ history.forEach(msg => {
221
+ if (msg.role === 'user') messages.push(new HumanMessage(msg.content));
222
+ if (msg.role === 'ai') messages.push(new AIMessage(msg.content));
223
+ });
224
+ messages.push(new HumanMessage(message));
225
+
226
+ const response = await llm.invoke(messages);
227
+
228
+ apiResponse.reply = response.content;
229
+ res.json(apiResponse);
230
+
231
+ } catch (error) {
232
+ apiResponse.error = error.message;
233
+ res.status(500).json(apiResponse);
234
+ }
235
+ });
236
+
237
+ // 2. API: INFO
238
+ app.get('/info', (req, res) => {
239
+ res.json({
240
+ model: MODEL_NAME,
241
+ status: llm ? "ready" : "loading",
242
+ roles: Object.keys(PROMPTS)
243
+ });
244
+ });
245
+
246
+ // 3. UI: HOME PAGE (Direct HTML Render)
247
+ app.get('/', (req, res) => {
248
+ res.send(HTML_PAGE);
249
+ });
250
+
251
+ app.listen(PORT, '0.0.0.0', () => {
252
+ console.log(`--> Server listening on ${PORT}`);
253
+ initModel();
254
+ });
server.js CHANGED
@@ -1,4 +1,4 @@
1
- console.log("--> SERVER STARTING...");
2
  import express from 'express';
3
  // --- DYNAMIC IMPORT ---
4
  let SystemMessage, HumanMessage, AIMessage, LlamaCppLLM;
@@ -25,8 +25,8 @@ const MODEL_NAME = "dahanhstd-1.0"; // Tên model tùy chỉnh
25
  // --- LOAD PROMPTS ---
26
  const PROMPTS = {
27
  "default": "You are a helpful AI assistant. Answer concisely.",
28
- "talk2people": fs.existsSync('MssterPrompt_Talk2People.txt')
29
- ? fs.readFileSync('MssterPrompt_Talk2People.txt', 'utf-8')
30
  : "You are a creative Video Director specializing in realistic Vietnamese scenes.",
31
  "coder": "You are an expert programmer."
32
  };
@@ -126,7 +126,7 @@ const HTML_PAGE = `
126
  const loadingDiv = document.createElement('div');
127
  loadingDiv.className = 'message ai';
128
  loadingDiv.id = loadingId;
129
- loadingDiv.innerText = '...';
130
  chatBox.appendChild(loadingDiv);
131
  chatBox.scrollTop = chatBox.scrollHeight;
132
 
@@ -252,3 +252,4 @@ app.listen(PORT, '0.0.0.0', () => {
252
  console.log(`--> Server listening on ${PORT}`);
253
  initModel();
254
  });
 
 
1
+ console.log("--> SERVER STARTING...");
2
  import express from 'express';
3
  // --- DYNAMIC IMPORT ---
4
  let SystemMessage, HumanMessage, AIMessage, LlamaCppLLM;
 
25
  // --- LOAD PROMPTS ---
26
  const PROMPTS = {
27
  "default": "You are a helpful AI assistant. Answer concisely.",
28
+ "talk2people": fs.existsSync('MasterPrompt_Talk2People.txt')
29
+ ? fs.readFileSync('MasterPrompt_Talk2People.txt', 'utf-8')
30
  : "You are a creative Video Director specializing in realistic Vietnamese scenes.",
31
  "coder": "You are an expert programmer."
32
  };
 
126
  const loadingDiv = document.createElement('div');
127
  loadingDiv.className = 'message ai';
128
  loadingDiv.id = loadingId;
129
+ loadingDiv.innerText = 'Đang suy nghĩ...';
130
  chatBox.appendChild(loadingDiv);
131
  chatBox.scrollTop = chatBox.scrollHeight;
132
 
 
252
  console.log(`--> Server listening on ${PORT}`);
253
  initModel();
254
  });
255
+