78 lines
3.7 KiB
JavaScript
78 lines
3.7 KiB
JavaScript
const express = require('express');
|
||
const axios = require('axios');
|
||
const { execSync } = require('child_process');
|
||
const fs = require('fs');
|
||
const Database = require('better-sqlite3');
|
||
const { v4: uuidv4 } = require('uuid');
|
||
const DEEPSEEK_KEY = 'sk-5bf0ac6628ff406eb37d5043b7c9220b';
|
||
|
||
const db = new Database('/opt/zhuyuan/agent/conversations3.db');
|
||
db.exec('CREATE TABLE IF NOT EXISTS convs (id TEXT PRIMARY KEY, title TEXT, ctime TEXT, utime TEXT)');
|
||
db.exec('CREATE TABLE IF NOT EXISTS msgs (id INTEGER PRIMARY KEY AUTOINCREMENT, cid TEXT, role TEXT, content TEXT, ctime TEXT)');
|
||
|
||
const app = express();
|
||
app.use(express.json());
|
||
app.use(express.static('/opt/zhuyuan/agent/public'));
|
||
|
||
function raw(cmd){ try{ return execSync(cmd,{timeout:5000}).toString().trim() }catch(e){ return '?' } }
|
||
|
||
function reality(){
|
||
return {
|
||
host: raw('hostname'),
|
||
cpu: raw('top -bn1 | head -5 | head -c 200'),
|
||
mem: raw('free -h'),
|
||
disk: raw('df -h /'),
|
||
pm2: raw('pm2 jlist 2>/dev/null | head -c 500')
|
||
};
|
||
}
|
||
|
||
app.get('/api/convs',(req,res)=>{
|
||
res.json(db.prepare('SELECT * FROM convs ORDER BY utime DESC').all());
|
||
});
|
||
app.post('/api/convs',(req,res)=>{
|
||
const id=uuidv4();
|
||
db.prepare("INSERT INTO convs VALUES(?,?,datetime('now'),datetime('now'))").run(id,'新对话');
|
||
res.json({id});
|
||
});
|
||
app.get('/api/convs/:id',(req,res)=>{
|
||
const c=db.prepare('SELECT * FROM convs WHERE id=?').get(req.params.id);
|
||
if(!c)return res.status(404).json({e:'not found'});
|
||
c.messages=db.prepare('SELECT role,content FROM msgs WHERE cid=? ORDER BY id ASC').all(req.params.id);
|
||
res.json(c);
|
||
});
|
||
app.delete('/api/convs/:id',(req,res)=>{
|
||
db.prepare('DELETE FROM msgs WHERE cid=?').run(req.params.id);
|
||
db.prepare('DELETE FROM convs WHERE id=?').run(req.params.id);
|
||
res.json({ok:1});
|
||
});
|
||
app.post('/api/chat',async(req,res)=>{
|
||
const{conversation_id,message}=req.body;
|
||
if(!message)return res.status(400).json({e:'no msg'});
|
||
let cid=conversation_id||uuidv4();
|
||
if(!conversation_id)db.prepare("INSERT INTO convs VALUES(?,?,datetime('now'),datetime('now'))").run(cid,'新对话');
|
||
db.prepare("INSERT INTO msgs(cid,role,content,ctime) VALUES(?,'user',?,datetime('now'))").run(cid,message);
|
||
const hist=db.prepare('SELECT role,content FROM msgs WHERE cid=? ORDER BY id DESC LIMIT 30').all(cid).reverse();
|
||
const t=db.prepare('SELECT title FROM convs WHERE id=?').get(cid);
|
||
if(t&&t.title==='新对话')db.prepare('UPDATE convs SET title=? WHERE id=?').run(message.slice(0,25),cid);
|
||
|
||
const r=reality();
|
||
const ctx='[Server Reality - '+r.host+']'+'\nCPU:\n'+r.cpu+'\nMemory:\n'+r.mem+'\nDisk:\n'+r.disk+'\nPM2:\n'+r.pm2;
|
||
|
||
const sys='你是光湖团队技术助手,由铸渊ICE-GL-ZY001部署。技术主控Awen的AI助手。服务器: 冰朔6台+团队2台。广州是中枢(43.139.217.141)。每次回答时用户消息末尾会附带当前服务器真实采集数据,请基于真实数据回答,不要编造。';
|
||
|
||
try{
|
||
const resp=await axios.post('https://api.deepseek.com/v1/chat/completions',{
|
||
model:'deepseek-chat',
|
||
messages:[{role:'system',content:sys},...hist.slice(0,-1),{role:'user',content:message+'\n\n'+ctx}],
|
||
temperature:0.5,max_tokens:2000
|
||
},{headers:{'Authorization':'Bearer '+DEEPSEEK_KEY,'Content-Type':'application/json'}});
|
||
const reply=resp.data.choices[0].message.content;
|
||
db.prepare("INSERT INTO msgs(cid,role,content,ctime) VALUES(?,'assistant',?,datetime('now'))").run(cid,reply);
|
||
db.prepare("UPDATE convs SET utime=datetime('now') WHERE id=?").run(cid);
|
||
res.json({conversation_id:cid,reply,reality:r});
|
||
}catch(e){res.status(500).json({e:'API:'+e.message})}
|
||
});
|
||
app.get('/api/reality',(req,res)=>res.json(reality()));
|
||
app.get('/api/health',(req,res)=>res.json({ok:1}));
|
||
app.listen(3940,'127.0.0.1',()=>console.log('Agent OK'));
|