44 lines
2.5 KiB
TypeScript
44 lines
2.5 KiB
TypeScript
import type { Router } from "express";
|
|
import { z } from "zod";
|
|
import { getLocalAgentContext } from "../context/localContext.js";
|
|
import { readPurpose, type SessionMetadataStore } from "../sessions/metadataStore.js";
|
|
|
|
const nameSchema = z.object({ name: z.string().trim().min(1).max(80) }).strict();
|
|
const membershipSchema = z.object({ topic_id: z.string().uuid().nullable() }).strict();
|
|
|
|
export function registerChatTopicRoutes(router: Router, sessions: SessionMetadataStore) {
|
|
router.get("/topics", async (req, res) => {
|
|
res.json({ topics: await sessions.topics.list(getLocalAgentContext(req)) });
|
|
});
|
|
router.post("/topics", async (req, res) => {
|
|
const parsed = nameSchema.safeParse(req.body);
|
|
if (!parsed.success) { res.status(400).json({ message: "主题名称须为 1 至 80 个字符" }); return; }
|
|
res.status(201).json(await sessions.topics.create(getLocalAgentContext(req), parsed.data.name));
|
|
});
|
|
router.patch("/topics/:topic_id", async (req, res) => {
|
|
const parsed = nameSchema.safeParse(req.body);
|
|
if (!parsed.success) { res.status(400).json({ message: "主题名称须为 1 至 80 个字符" }); return; }
|
|
const topic = await sessions.topics.rename(getLocalAgentContext(req), req.params.topic_id, parsed.data.name);
|
|
if (!topic) { res.status(404).json({ message: "主题不存在" }); return; }
|
|
res.json(topic);
|
|
});
|
|
router.delete("/topics/:topic_id", async (req, res) => {
|
|
// Removing a grouping never deletes conversations. Old IDs resolve as unclassified.
|
|
const removed = await sessions.topics.remove(getLocalAgentContext(req), req.params.topic_id);
|
|
if (!removed) { res.status(404).json({ message: "主题不存在" }); return; }
|
|
res.status(204).end();
|
|
});
|
|
router.patch("/session/:session_id/topic", async (req, res) => {
|
|
const parsed = membershipSchema.safeParse(req.body);
|
|
if (!parsed.success) { res.status(400).json({ message: "invalid topic membership" }); return; }
|
|
const context = getLocalAgentContext(req);
|
|
const record = await sessions.get(context, req.params.session_id);
|
|
if (!record || readPurpose(record) === "task_execution") { res.status(404).json({ message: "session not found" }); return; }
|
|
if (parsed.data.topic_id && !await sessions.topics.get(context, parsed.data.topic_id)) {
|
|
res.status(404).json({ message: "主题不存在" }); return;
|
|
}
|
|
await sessions.touch(record, { topicId: parsed.data.topic_id });
|
|
res.json({ session_id: record.sessionId, topic_id: parsed.data.topic_id });
|
|
});
|
|
}
|