fix: 修复构建失败并补齐聊天存储模块
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
type ChatLocale = 'zh' | 'en'
|
||||
type ChatRole = 'USER' | 'ASSISTANT' | 'SYSTEM'
|
||||
type ChatStatus = 'ACTIVE'
|
||||
|
||||
interface ChatMessage {
|
||||
id: string
|
||||
sessionId: string
|
||||
role: ChatRole
|
||||
contentText: string
|
||||
mode: string | null
|
||||
createdAt: string
|
||||
}
|
||||
|
||||
interface ChatSession {
|
||||
id: string
|
||||
clientId: string
|
||||
locale: ChatLocale
|
||||
title: string
|
||||
status: ChatStatus
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
lastMessageAt: string
|
||||
}
|
||||
|
||||
interface ChatStoreState {
|
||||
sessions: Map<string, ChatSession>
|
||||
messages: Map<string, ChatMessage[]>
|
||||
}
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line no-var
|
||||
var __agentParkChatStore: ChatStoreState | undefined
|
||||
}
|
||||
|
||||
function getStore(): ChatStoreState {
|
||||
if (!globalThis.__agentParkChatStore) {
|
||||
globalThis.__agentParkChatStore = {
|
||||
sessions: new Map<string, ChatSession>(),
|
||||
messages: new Map<string, ChatMessage[]>(),
|
||||
}
|
||||
}
|
||||
|
||||
return globalThis.__agentParkChatStore
|
||||
}
|
||||
|
||||
function nowIso(): string {
|
||||
return new Date().toISOString()
|
||||
}
|
||||
|
||||
export async function createChatSession(input: {
|
||||
clientId: string
|
||||
locale: ChatLocale
|
||||
title?: string
|
||||
}): Promise<ChatSession> {
|
||||
const store = getStore()
|
||||
const now = nowIso()
|
||||
|
||||
const session: ChatSession = {
|
||||
id: crypto.randomUUID(),
|
||||
clientId: input.clientId,
|
||||
locale: input.locale,
|
||||
title: input.title?.trim() || 'New Chat',
|
||||
status: 'ACTIVE',
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
lastMessageAt: now,
|
||||
}
|
||||
|
||||
store.sessions.set(session.id, session)
|
||||
store.messages.set(session.id, [])
|
||||
|
||||
return session
|
||||
}
|
||||
|
||||
export async function listChatSessions(input: {
|
||||
clientId: string
|
||||
locale?: ChatLocale
|
||||
limit: number
|
||||
cursor?: string
|
||||
}): Promise<Array<ChatSession & { messages: ChatMessage[] }>> {
|
||||
const store = getStore()
|
||||
|
||||
const ordered = Array.from(store.sessions.values())
|
||||
.filter((session) =>
|
||||
input.locale
|
||||
? session.clientId === input.clientId && session.locale === input.locale
|
||||
: session.clientId === input.clientId
|
||||
)
|
||||
.sort((a, b) => b.lastMessageAt.localeCompare(a.lastMessageAt))
|
||||
|
||||
const cursorIndex = input.cursor ? ordered.findIndex((session) => session.id === input.cursor) : -1
|
||||
const page = cursorIndex >= 0 ? ordered.slice(cursorIndex + 1, cursorIndex + 1 + input.limit) : ordered.slice(0, input.limit)
|
||||
|
||||
return page.map((session) => {
|
||||
const messageList = store.messages.get(session.id) || []
|
||||
const latest = messageList.length > 0 ? [messageList[messageList.length - 1] as ChatMessage] : []
|
||||
return {
|
||||
...session,
|
||||
messages: latest,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function assertSessionOwnership(input: {
|
||||
sessionId: string
|
||||
clientId: string
|
||||
}): Promise<void> {
|
||||
const store = getStore()
|
||||
const session = store.sessions.get(input.sessionId)
|
||||
|
||||
if (!session) {
|
||||
throw new Error('CHAT_SESSION_NOT_FOUND')
|
||||
}
|
||||
|
||||
if (session.clientId !== input.clientId) {
|
||||
throw new Error('CHAT_SESSION_FORBIDDEN')
|
||||
}
|
||||
}
|
||||
|
||||
export async function listChatMessages(input: {
|
||||
sessionId: string
|
||||
limit: number
|
||||
}): Promise<ChatMessage[]> {
|
||||
const store = getStore()
|
||||
const messages = store.messages.get(input.sessionId) || []
|
||||
const normalizedLimit = Math.max(1, input.limit)
|
||||
|
||||
return messages.slice(-normalizedLimit)
|
||||
}
|
||||
@@ -232,13 +232,6 @@ export async function GET(request: NextRequest) {
|
||||
? [{ isHot: 'desc' }, { hotScore: 'desc' }, { engagement: 'desc' }, { publishedAt: 'desc' }, { id: 'desc' }]
|
||||
: [{ publishedAt: 'desc' }, { id: 'desc' }]
|
||||
|
||||
const cursorArgs = parsed.cursor
|
||||
? {
|
||||
cursor: { id: parsed.cursor },
|
||||
skip: 1 as const,
|
||||
}
|
||||
: {}
|
||||
|
||||
let rows: Array<{
|
||||
id: string
|
||||
source: string
|
||||
@@ -262,7 +255,8 @@ export async function GET(request: NextRequest) {
|
||||
where,
|
||||
orderBy,
|
||||
take: parsed.limit + 1,
|
||||
...cursorArgs,
|
||||
cursor: parsed.cursor ? { id: parsed.cursor } : undefined,
|
||||
skip: parsed.cursor ? 1 : undefined,
|
||||
select: {
|
||||
id: true,
|
||||
source: true,
|
||||
@@ -293,7 +287,8 @@ export async function GET(request: NextRequest) {
|
||||
where,
|
||||
orderBy: fallbackOrderBy,
|
||||
take: parsed.limit + 1,
|
||||
...cursorArgs,
|
||||
cursor: parsed.cursor ? { id: parsed.cursor } : undefined,
|
||||
skip: parsed.cursor ? 1 : undefined,
|
||||
select: {
|
||||
id: true,
|
||||
source: true,
|
||||
|
||||
Reference in New Issue
Block a user