feat(router): add aiChat tRPC sub-router
CRUD for chat sessions and messages, used by both home and contextual channels. No UI consumer yet — added ahead of refactor.
This commit is contained in:
105
src/main/router/ai-chat.ts
Normal file
105
src/main/router/ai-chat.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
// adiuvAI/src/main/router/ai-chat.ts
|
||||
import { initTRPC } from '@trpc/server';
|
||||
import { z } from 'zod';
|
||||
import { eq, desc, asc } from 'drizzle-orm';
|
||||
import { getDb } from '../db';
|
||||
import { aiChatSessions, aiChatMessages } from '../db/schema';
|
||||
import type { TRPCContext } from '../ipc';
|
||||
|
||||
const t = initTRPC.context<TRPCContext>().create();
|
||||
const router = t.router;
|
||||
const publicProcedure = t.procedure;
|
||||
|
||||
const ChannelSchema = z.enum(['home', 'contextual']);
|
||||
const RoleSchema = z.enum(['user', 'assistant', 'system']);
|
||||
|
||||
export const aiChatRouter = router({
|
||||
listSessions: publicProcedure
|
||||
.input(z.object({ channel: ChannelSchema }))
|
||||
.query(({ input }) => {
|
||||
return getDb()
|
||||
.select()
|
||||
.from(aiChatSessions)
|
||||
.where(eq(aiChatSessions.channel, input.channel))
|
||||
.orderBy(desc(aiChatSessions.updatedAt))
|
||||
.all();
|
||||
}),
|
||||
|
||||
getSession: publicProcedure
|
||||
.input(z.object({ id: z.string() }))
|
||||
.query(({ input }) => {
|
||||
const db = getDb();
|
||||
const session = db
|
||||
.select()
|
||||
.from(aiChatSessions)
|
||||
.where(eq(aiChatSessions.id, input.id))
|
||||
.get();
|
||||
if (!session) return null;
|
||||
const messages = db
|
||||
.select()
|
||||
.from(aiChatMessages)
|
||||
.where(eq(aiChatMessages.sessionId, input.id))
|
||||
.orderBy(asc(aiChatMessages.createdAt))
|
||||
.all();
|
||||
return { session, messages };
|
||||
}),
|
||||
|
||||
createSession: publicProcedure
|
||||
.input(z.object({
|
||||
channel: ChannelSchema,
|
||||
initialScope: z.string().optional(),
|
||||
}))
|
||||
.mutation(({ input }) => {
|
||||
const db = getDb();
|
||||
const id = crypto.randomUUID();
|
||||
const now = Date.now();
|
||||
db.insert(aiChatSessions).values({
|
||||
id,
|
||||
channel: input.channel,
|
||||
title: null,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
lastScope: input.initialScope ?? null,
|
||||
}).run();
|
||||
return { id };
|
||||
}),
|
||||
|
||||
appendMessage: publicProcedure
|
||||
.input(z.object({
|
||||
sessionId: z.string(),
|
||||
role: RoleSchema,
|
||||
content: z.string(),
|
||||
toolCalls: z.string().optional(),
|
||||
toolResults: z.string().optional(),
|
||||
scope: z.string().optional(),
|
||||
}))
|
||||
.mutation(({ input }) => {
|
||||
const db = getDb();
|
||||
const id = crypto.randomUUID();
|
||||
const now = Date.now();
|
||||
db.insert(aiChatMessages).values({
|
||||
id,
|
||||
sessionId: input.sessionId,
|
||||
role: input.role,
|
||||
content: input.content,
|
||||
toolCalls: input.toolCalls ?? null,
|
||||
toolResults: input.toolResults ?? null,
|
||||
scope: input.scope ?? null,
|
||||
createdAt: now,
|
||||
}).run();
|
||||
db.update(aiChatSessions)
|
||||
.set({ updatedAt: now, lastScope: input.scope ?? null })
|
||||
.where(eq(aiChatSessions.id, input.sessionId))
|
||||
.run();
|
||||
return { id };
|
||||
}),
|
||||
|
||||
deleteSession: publicProcedure
|
||||
.input(z.object({ id: z.string() }))
|
||||
.mutation(({ input }) => {
|
||||
const db = getDb();
|
||||
db.delete(aiChatMessages).where(eq(aiChatMessages.sessionId, input.id)).run();
|
||||
db.delete(aiChatSessions).where(eq(aiChatSessions.id, input.id)).run();
|
||||
return { ok: true };
|
||||
}),
|
||||
});
|
||||
@@ -18,6 +18,7 @@ import { getAuthManager, AuthError } from '../auth/auth-manager';
|
||||
import { detectFormatPrefs, detectLanguage } from '../auth/locale-defaults';
|
||||
import type { TRPCContext } from '../ipc';
|
||||
import { projectFoldersRouter } from './projectFolders';
|
||||
import { aiChatRouter } from './ai-chat';
|
||||
|
||||
const t = initTRPC.context<TRPCContext>().create();
|
||||
|
||||
@@ -1856,6 +1857,7 @@ export const appRouter = router({
|
||||
agent: agentRouter,
|
||||
memory: memoryRouter,
|
||||
projectFolders: projectFoldersRouter,
|
||||
aiChat: aiChatRouter,
|
||||
});
|
||||
|
||||
export type AppRouter = typeof appRouter;
|
||||
|
||||
Reference in New Issue
Block a user