165 lines
6.2 KiB
JavaScript
165 lines
6.2 KiB
JavaScript
/**
|
||
* ═══════════════════════════════════════════════════════════
|
||
* 成员Agent路由 · /api/zhiku/agent
|
||
* ═══════════════════════════════════════════════════════════
|
||
*
|
||
* 智库节点 Phase 3 · ZY-SVR-006
|
||
* 守护: 铸渊 · ICE-GL-ZY001
|
||
* 版权: 国作登字-2026-A-00037559
|
||
*
|
||
* 端点:
|
||
* GET / — 列出所有Agent
|
||
* GET /:memberId — 获取Agent详情
|
||
* POST /:memberId — 注册/获取Agent
|
||
* POST /:memberId/chat — 对话
|
||
* GET /:memberId/chat — 获取对话历史
|
||
* GET /:memberId/memories — 获取记忆
|
||
* POST /:memberId/memories — 添加记忆
|
||
* GET /:memberId/notes — 获取笔记
|
||
* POST /:memberId/notes — 添加笔记
|
||
* GET /stats — Agent统计
|
||
*
|
||
* ═══════════════════════════════════════════════════════════
|
||
*/
|
||
|
||
'use strict';
|
||
|
||
const express = require('express');
|
||
const router = express.Router();
|
||
const engine = require('../services/member-agent-engine');
|
||
|
||
/* ─── GET /stats — 统计 (放在 /:memberId 前面) ─── */
|
||
router.get('/stats', (req, res) => {
|
||
res.json({ error: false, data: engine.getStats() });
|
||
});
|
||
|
||
/* ─── GET / — 列出所有Agent ─── */
|
||
router.get('/', (req, res) => {
|
||
const agents = engine.listAgents();
|
||
res.json({ error: false, data: agents, total: agents.length });
|
||
});
|
||
|
||
/* ─── GET /:memberId — 获取Agent详情 ─── */
|
||
router.get('/:memberId', (req, res) => {
|
||
const agent = engine.getAgent(req.params.memberId);
|
||
if (!agent) return res.status(404).json({ error: true, code: 'NOT_FOUND', message: 'Agent不存在' });
|
||
// 返回摘要(不暴露全部记忆)
|
||
res.json({
|
||
error: false,
|
||
data: {
|
||
member_id: agent.member_id,
|
||
nickname: agent.nickname,
|
||
role: agent.role,
|
||
memory_count: agent.memory ? agent.memory.length : 0,
|
||
note_count: agent.notes ? agent.notes.length : 0,
|
||
chat_count: agent.chat_history ? agent.chat_history.length : 0,
|
||
preferences: agent.preferences,
|
||
last_active: agent.last_active,
|
||
created_at: agent.created_at
|
||
}
|
||
});
|
||
});
|
||
|
||
/* ─── POST /:memberId — 注册/获取Agent ─── */
|
||
router.post('/:memberId', (req, res) => {
|
||
try {
|
||
const { nickname, role } = req.body;
|
||
const agent = engine.getOrCreateAgent(req.params.memberId, { nickname, role });
|
||
res.json({
|
||
error: false,
|
||
data: {
|
||
member_id: agent.member_id,
|
||
nickname: agent.nickname,
|
||
role: agent.role,
|
||
last_active: agent.last_active,
|
||
created_at: agent.created_at
|
||
}
|
||
});
|
||
} catch (err) {
|
||
res.status(400).json({ error: true, code: 'CREATE_FAILED', message: err.message });
|
||
}
|
||
});
|
||
|
||
/* ─── POST /:memberId/chat — 对话 ─── */
|
||
router.post('/:memberId/chat', async (req, res) => {
|
||
try {
|
||
const { message, use_ai } = req.body;
|
||
if (!message || !message.trim()) {
|
||
return res.status(400).json({ error: true, code: 'EMPTY_MESSAGE', message: '消息不能为空' });
|
||
}
|
||
|
||
// 默认使用AI,use_ai=false 时使用本地快速回复
|
||
let result;
|
||
if (use_ai === false) {
|
||
result = engine.chat(req.params.memberId, message);
|
||
} else {
|
||
// 优先尝试异步AI对话
|
||
try {
|
||
result = await engine.chatAsync(req.params.memberId, message);
|
||
} catch {
|
||
// AI失败时降级为本地回复
|
||
result = engine.chat(req.params.memberId, message);
|
||
}
|
||
}
|
||
|
||
res.json({ error: false, data: result });
|
||
} catch (err) {
|
||
res.status(400).json({ error: true, code: 'CHAT_FAILED', message: err.message });
|
||
}
|
||
});
|
||
|
||
/* ─── GET /:memberId/chat — 对话历史 ─── */
|
||
router.get('/:memberId/chat', (req, res) => {
|
||
const limit = req.query.limit ? parseInt(req.query.limit) : undefined;
|
||
const history = engine.getChatHistory(req.params.memberId, limit);
|
||
res.json({ error: false, data: history, total: history.length });
|
||
});
|
||
|
||
/* ─── GET /:memberId/memories — 记忆列表 ─── */
|
||
router.get('/:memberId/memories', (req, res) => {
|
||
const { type, limit } = req.query;
|
||
const memories = engine.getMemories(req.params.memberId, {
|
||
type, limit: limit ? parseInt(limit) : undefined
|
||
});
|
||
res.json({ error: false, data: memories, total: memories.length });
|
||
});
|
||
|
||
/* ─── POST /:memberId/memories — 添加记忆 ─── */
|
||
router.post('/:memberId/memories', (req, res) => {
|
||
try {
|
||
const { type, content, source, tags } = req.body;
|
||
if (!content || !content.trim()) {
|
||
return res.status(400).json({ error: true, code: 'EMPTY_CONTENT', message: 'content 不能为空' });
|
||
}
|
||
const result = engine.addMemory(req.params.memberId, { type, content, source, tags });
|
||
res.json({ error: false, data: result });
|
||
} catch (err) {
|
||
res.status(400).json({ error: true, code: 'ADD_MEMORY_FAILED', message: err.message });
|
||
}
|
||
});
|
||
|
||
/* ─── GET /:memberId/notes — 笔记列表 ─── */
|
||
router.get('/:memberId/notes', (req, res) => {
|
||
const { book_id, limit } = req.query;
|
||
const notes = engine.getNotes(req.params.memberId, {
|
||
book_id, limit: limit ? parseInt(limit) : undefined
|
||
});
|
||
res.json({ error: false, data: notes, total: notes.length });
|
||
});
|
||
|
||
/* ─── POST /:memberId/notes — 添加笔记 ─── */
|
||
router.post('/:memberId/notes', (req, res) => {
|
||
try {
|
||
const { title, content, book_id } = req.body;
|
||
if (!content || !content.trim()) {
|
||
return res.status(400).json({ error: true, code: 'EMPTY_CONTENT', message: 'content 不能为空' });
|
||
}
|
||
const result = engine.addNote(req.params.memberId, { title, content, book_id });
|
||
res.json({ error: false, data: result });
|
||
} catch (err) {
|
||
res.status(400).json({ error: true, code: 'ADD_NOTE_FAILED', message: err.message });
|
||
}
|
||
});
|
||
|
||
module.exports = router;
|