Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 10 additions & 56 deletions apps/server/src/controllers/agent/index.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import { AgentType } from '@prisma/client';
import z from 'zod';

import { HTTPSTATUS } from '../../configs/http';
import { asyncHandler } from '../../middleware/async';
import {
createAgent,
deleteAgentById,
getAllAgents,
updateAgentById,
} from '../../services/agent';
import { AgentService } from '../../services/agent';
import AppResponse from '../../utils/appResponse';
import {
agentIdSchema,
createNewAgentValidator,
updateAgentSchema,
} from '../../validator/agent';

const createNewAgent = asyncHandler(async (req, res) => {
const data = createNewAgentValidator.parse(req.body);

await createAgent(data);
await AgentService.createAgent(data);

new AppResponse({
res,
Expand All @@ -25,7 +22,7 @@ const createNewAgent = asyncHandler(async (req, res) => {
});

const agentLists = asyncHandler(async (_, res) => {
const agents = await getAllAgents();
const agents = await AgentService.getAllAgents();

new AppResponse({
res,
Expand All @@ -39,7 +36,7 @@ const agentLists = asyncHandler(async (_, res) => {
const updateAgent = asyncHandler(async (req, res) => {
const params = agentIdSchema.parse(req.params);
const data = updateAgentSchema.parse(req.body);
await updateAgentById(params.agentId, data);
await AgentService.updateAgentById(params.agentId, data);

new AppResponse({
res,
Expand All @@ -51,7 +48,7 @@ const updateAgent = asyncHandler(async (req, res) => {

const deleteAgent = asyncHandler(async (req, res) => {
const data = agentIdSchema.parse(req.params);
await deleteAgentById(data.agentId);
await AgentService.deleteAgentById(data.agentId);

new AppResponse({
res,
Expand All @@ -61,49 +58,6 @@ const deleteAgent = asyncHandler(async (req, res) => {
});
});

const createNewAgentValidator = z.object({
datasourceIds: z.array(z.string().min(1)).optional(),
name: z.string().min(1),
description: z.string().optional(),
type: z.enum([AgentType.AI, AgentType.HUMAN]),
model: z.string().min(1),
system_prompt: z
.string({
message: 'System prompt is required',
})
.optional(),
user_prompt: z
.string({
message: 'System prompt is required',
})
.optional(),
prompt_variables: z.record(z.string()).optional(),
});

const updateAgentSchema = z.object({
datasourceIds: z.array(z.string().min(1)).optional(),
name: z.string().min(1),
description: z.string().optional(),
type: z.enum([AgentType.AI, AgentType.HUMAN]),
model: z.string().min(1),
system_prompt: z
.string({
message: 'System prompt is required',
})
.optional(),
user_prompt: z
.string({
message: 'System prompt is required',
})
.optional(),
prompt_variables: z.record(z.string()).optional(),
lastActive: z.string().optional(),
});

const agentIdSchema = z.object({
agentId: z.string().min(1),
});

export const agentController = {
createNewAgent,
agentLists,
Expand Down
40 changes: 15 additions & 25 deletions apps/server/src/controllers/chat/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,27 @@ import z from 'zod';
import type { CreateMessage } from '../../types/interface/message';
import type { Agent, Prisma } from '@prisma/client';
import { asyncHandler } from '../../middleware/async';
import { getAgentById, updateAgentById } from '../../services/agent';
import {
createConversation,
getConversationByChatId,
getConversationById,
updateConversationById,
} from '../../services/conversation';
import { createMessage } from '../../services/messages';
import { AgentService } from '../../services/agent';
import { ConversationService } from '../../services/conversation';
import { messageService } from '../../services/messages';
import { UpdateAgent } from '../../types/interface/agent';
import { AppError } from '../../utils/appError';
import { graph } from '../../utils/mygraph/cs_graph';
import {
QUERY_SYSTEM_PROMPT_TEMPLATE,
RESPONSE_SYSTEM_PROMPT_TEMPLATE,
} from '../../utils/mygraph/cs_graph/prompt';
import { createNewMessageValidator } from '../../validator/chat';

type MessageEvent = {
eventData: Record<string, any>;
eventType: 'messages' | 'values';
res: Response;
};

const createNewMessageValidator = z.object({
messages: z.array(
z.object({ role: z.enum(['human', 'ai']), content: z.string().min(1) })
),
userId: z.string().min(1),
agentId: z.string().min(1),
chatId: z.number().min(1).optional().describe('Telegram chat id'),
conversationId: z.string().min(1).optional(),
});

const createNewMessage = asyncHandler(async (req, res) => {
const data = createNewMessageValidator.parse(req.body);
const agent = await getAgentById(data.agentId);
const agent = await AgentService.getAgentById(data.agentId);
if (!agent) {
throw AppError.notFound('Agent not found');
}
Expand Down Expand Up @@ -166,7 +152,7 @@ function createMessagesToStore(

async function storeMessages(messages: CreateMessage[]) {
for (const message of messages) {
await createMessage(message);
await messageService.createMessage(message);
}
}

Expand All @@ -175,14 +161,18 @@ const getOrCreateConversation = async (
agent: Agent
) => {
if (data.conversationId) {
const conversation = await getConversationById(data.conversationId);
const conversation = await ConversationService.getConversationById(
data.conversationId
);
if (conversation) return conversation;
} else if (data.chatId) {
const conversation = await getConversationByChatId(data.chatId);
const conversation = await ConversationService.getConversationByChatId(
data.chatId
);
if (conversation) return conversation;
}

return await createConversation({
return await ConversationService.createConversation({
agentId: agent.id,
userId: data.userId,
chatId: data.chatId,
Expand All @@ -196,13 +186,13 @@ const updateConversation = async (
conversationId: string,
filteredData: Record<string, string>
) => {
return await updateConversationById(conversationId, {
return await ConversationService.updateConversationById(conversationId, {
priority: filteredData.priority as 'low' | 'medium' | 'high',
});
};

const updateAgent: UpdateAgent = async (agentId, data) => {
return await updateAgentById(agentId, data);
return await AgentService.updateAgentById(agentId, data);
};

function handleMessageEvent({
Expand Down
18 changes: 6 additions & 12 deletions apps/server/src/controllers/conversation/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import z from 'zod';

import { HTTPSTATUS } from '../../configs/http';
import { asyncHandler } from '../../middleware/async';
import {
deleteConversationById,
getAllConversations,
getConversationById,
} from '../../services/conversation';
import { ConversationService } from '../../services/conversation';
import { AppError } from '../../utils/appError';
import AppResponse from '../../utils/appResponse';
import { conversationIdSchema } from '../../validator/chat';

const getConversationId = asyncHandler(async (req, res) => {
const { conversationId } = conversationIdSchema.parse(req.params);
const conversation = await getConversationById(conversationId);
const conversation =
await ConversationService.getConversationById(conversationId);

if (!conversation) {
throw AppError.notFound('Conversation not found');
Expand All @@ -28,7 +24,7 @@ const getConversationId = asyncHandler(async (req, res) => {
});

const conversationLists = asyncHandler(async (_req, res) => {
const conversations = await getAllConversations();
const conversations = await ConversationService.getAllConversations();

new AppResponse({
res,
Expand All @@ -42,7 +38,7 @@ const conversationLists = asyncHandler(async (_req, res) => {
const deleteConversation = asyncHandler(async (req, res) => {
const { conversationId } = conversationIdSchema.parse(req.params);

await deleteConversationById(conversationId);
await ConversationService.deleteConversationById(conversationId);

new AppResponse({
res,
Expand All @@ -52,8 +48,6 @@ const deleteConversation = asyncHandler(async (req, res) => {
});
});

const conversationIdSchema = z.object({ conversationId: z.string().min(1) });

export const conversationController = {
getConversationId,
conversationLists,
Expand Down
90 changes: 13 additions & 77 deletions apps/server/src/controllers/datasource/index.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import { $Enums, Datasource } from '@prisma/client';
import z from 'zod';
import { Datasource } from '@prisma/client';

import { HTTPSTATUS } from '../../configs/http';
import { asyncHandler } from '../../middleware/async';
import {
createDatasource,
deleteDatasourceById,
getAllDatasource,
updateDatasourceById,
} from '../../services/datasource';
import { DatasourceService } from '../../services/datasource';
import { storeDocument } from '../../services/document';
import { AppError } from '../../utils/appError';
import AppResponse from '../../utils/appResponse';
import {
createNewDatasouceSchema,
datasourceIdSchema,
updateDatasouceSchema,
} from '../../validator/datasource';

const createNewDatasource = asyncHandler(async (req, res) => {
const data = createNewDatasouceSchema.parse(req.body);
let datasource: Datasource = {} as Datasource;

if (data.type === 'DOCUMENT' && data.fileUrl) {
datasource = await createDatasource(data);
datasource = await DatasourceService.createDatasource(data);

await storeDocument({
fileUrl: data.fileUrl,
Expand All @@ -27,7 +26,7 @@ const createNewDatasource = asyncHandler(async (req, res) => {
}

if (data.type === 'TEXT' && data.content) {
datasource = await createDatasource(data);
datasource = await DatasourceService.createDatasource(data);

await storeDocument({
content: data.content,
Expand All @@ -36,7 +35,7 @@ const createNewDatasource = asyncHandler(async (req, res) => {
}

if (data.type === 'WEB' && data.url) {
datasource = await createDatasource(data);
datasource = await DatasourceService.createDatasource(data);

await storeDocument({
url: data.url,
Expand All @@ -61,7 +60,7 @@ const updateDatasource = asyncHandler(async (req, res) => {
const { datasourceId } = datasourceIdSchema.parse(req.params);
const data = updateDatasouceSchema.parse(req.body);

await updateDatasourceById(datasourceId, data);
await DatasourceService.updateDatasourceById(datasourceId, data);

new AppResponse({
res,
Expand All @@ -72,7 +71,7 @@ const updateDatasource = asyncHandler(async (req, res) => {
});

const datasourceLists = asyncHandler(async (_, res) => {
const datasources = await getAllDatasource();
const datasources = await DatasourceService.getAllDatasource();

new AppResponse({
res,
Expand All @@ -86,7 +85,7 @@ const datasourceLists = asyncHandler(async (_, res) => {
const deteleDatasource = asyncHandler(async (req, res) => {
const { datasourceId } = datasourceIdSchema.parse(req.params);

await deleteDatasourceById(datasourceId);
await DatasourceService.deleteDatasourceById(datasourceId);

new AppResponse({
res,
Expand All @@ -96,69 +95,6 @@ const deteleDatasource = asyncHandler(async (req, res) => {
});
});

const createNewDatasouceSchema = z
.object({
name: z.string().min(1),
description: z.string().optional(),
agentIds: z.array(z.string().min(1)).optional(),
fileUrl: z.string().url().optional(),
type: z.nativeEnum($Enums.DatasourceType),
category: z.string().optional(),
content: z.string().optional(),
url: z.string().optional(),
size: z.number().optional(),
})
.refine(
(data) =>
data.type !== 'DOCUMENT' || (data.type === 'DOCUMENT' && data.fileUrl),
{ message: 'fileUrl is required when type is DOCUMENT', path: ['fileUrl'] }
)
.refine(
(data) => data.type !== 'TEXT' || (data.type === 'TEXT' && data.content),
{ message: 'content is required when type is TEXT', path: ['content'] }
)
.refine((data) => data.type !== 'WEB' || (data.type === 'WEB' && data.url), {
message: 'url is required when type is WEBSITE',
path: ['url'],
});
// .refine(
// (data) =>
// data.type !== 'DATABASE' || (data.type === 'DATABASE' && data.size),
// { message: 'size is required when type is DATABASE', path: ['size'] }
// );

const datasourceIdSchema = z.object({
datasourceId: z.string().min(1),
});

const updateDatasouceSchema = z
.object({
name: z.string().min(1, {
message: 'Source name cannot be empty',
}),
description: z.string().optional(),
agentIds: z.array(z.string().min(1)).optional(),
fileUrl: z.string().url().optional(),
type: z.enum(['DOCUMENT', 'TEXT', 'WEB', 'DATABASE']),
category: z.string().optional(),
content: z.string().optional(),
url: z.string().optional(),
size: z.number().optional(),
})
.refine(
(data) =>
data.type !== 'DOCUMENT' || (data.type === 'DOCUMENT' && data.fileUrl),
{ message: 'fileUrl is required when type is DOCUMENT', path: ['fileUrl'] }
)
.refine(
(data) => data.type !== 'TEXT' || (data.type === 'TEXT' && data.content),
{ message: 'content is required when type is TEXT', path: ['content'] }
)
.refine((data) => data.type !== 'WEB' || (data.type === 'WEB' && data.url), {
message: 'url is required when type is WEBSITE',
path: ['url'],
});

export const dataSourceController = {
createNewDatasource,
updateDatasource,
Expand Down
Loading
Loading