Skip to content

Commit

Permalink
Add new API handler and bulk source handler
Browse files Browse the repository at this point in the history
  • Loading branch information
n4ze3m committed Mar 19, 2024
1 parent 6dfa718 commit 1b7e96c
Show file tree
Hide file tree
Showing 7 changed files with 455 additions and 5 deletions.
208 changes: 208 additions & 0 deletions server/src/handlers/api/v1/bot/bot/api.handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
import { FastifyReply, FastifyRequest } from "fastify";
import {
HELPFUL_ASSISTANT_WITH_CONTEXT_PROMPT, QUESTION_GENERATOR_PROMPT,
} from "../../../../../utils/prompts";
import { AddNewSourceBulkById, CreateBotAPIRequest } from "./types";
import { getSettings } from "../../../../../utils/common";
import { apiKeyValidaton, apiKeyValidatonMessage } from "../../../../../utils/validate";
import { adjectives, animals, colors, uniqueNamesGenerator } from "unique-names-generator";
import { validateDataSource } from "../../../../../utils/datasource-validation";

export const createBotAPIHandler = async (
request: FastifyRequest<CreateBotAPIRequest>,
reply: FastifyReply
) => {
const {
name: nameFromRequest,
embedding,
model,
question_generator_prompt,
system_prompt,
temperature
} = request.body;

const prisma = request.server.prisma;

// only non-admin users are affected by this settings
const settings = await getSettings(prisma);
const user = request.user;
const isBotCreatingAllowed = settings?.allowUserToCreateBots;
if (!user.is_admin && !isBotCreatingAllowed) {
return reply.status(400).send({
message: "Bot creation is disabled by admin",
});
}

const totalBotsUserCreated = await prisma.bot.count({
where: {
user_id: request.user.user_id,
},
});

const maxBotsAllowed = settings?.noOfBotsPerUser || 10;

if (!user.is_admin && totalBotsUserCreated >= maxBotsAllowed) {
return reply.status(400).send({
message: `Reach maximum limit of ${maxBotsAllowed} bots per user`,
});
}
const modelInfo = await prisma.dialoqbaseModels.findFirst({
where: {
hide: false,
deleted: false,
OR: [
{
model_id: model
},
{
model_id: `${model}-dbase`
}
]
},
});

if (!modelInfo) {
return reply.status(400).send({
message: "Chat Model not found",
});
}

const embeddingInfo = await prisma.dialoqbaseModels.findFirst({
where: {
OR: [
{
model_id: embedding,
},
{
model_id: `dialoqbase_eb_${embedding}`
}
],
hide: false,
deleted: false,
},
});

if (!embeddingInfo) {
return reply.status(400).send({
message: "Embedding Model not found",
});
}

const isEmbeddingsValid = apiKeyValidaton(
`${embeddingInfo.model_provider}`.toLowerCase()
);

if (!isEmbeddingsValid) {
return reply.status(400).send({
message: apiKeyValidatonMessage(embedding),
});
}

const isAPIKeyAddedForProvider = apiKeyValidaton(
`${modelInfo.model_provider}`.toLowerCase()
);

if (!isAPIKeyAddedForProvider) {
return reply.status(400).send({
message: apiKeyValidatonMessage(modelInfo.model_provider || ""),
});
}

const shortName = uniqueNamesGenerator({
dictionaries: [adjectives, animals, colors],
length: 2,
});

const name = nameFromRequest || shortName;

const isStreamingAvilable = modelInfo.stream_available;

const bot = await prisma.bot.create({
data: {
name,
embedding: embeddingInfo.model_id,
model: modelInfo.model_id,
provider: modelInfo.model_provider || "",
streaming: isStreamingAvilable,
user_id: request.user.user_id,
temperature: temperature || 0.7,
qaPrompt: system_prompt || HELPFUL_ASSISTANT_WITH_CONTEXT_PROMPT,
questionGeneratorPrompt: question_generator_prompt || QUESTION_GENERATOR_PROMPT,
},
});

return {
id: bot.id,
};
};


export const addNewSourceByIdBulkHandler = async (
request: FastifyRequest<AddNewSourceBulkById>,
reply: FastifyReply
) => {
try {
const prisma = request.server.prisma;
const id = request.params.id;

const bot = await prisma.bot.findFirst({
where: {
id,
user_id: request.user.user_id,
},
include: {
source: true,
},
});

if (!bot) {
return reply.status(404).send({
message: "Bot not found",
});
}

const data = request.body;

const queueSource: any[] = [];

const isOk = validateDataSource(data);

if (isOk.length > 0) {
return reply.status(400).send({
message: isOk,
});
}

for (const source of data) {

const { content, type } = source;

const botSource = await prisma.botSource.create({
data: {
content,
type,
botId: bot.id,
options: source.options,
},
});

queueSource.push({
...botSource,
embedding: bot.embedding,
maxDepth: source.maxDepth,
maxLinks: source.maxLinks,
options: source.options,
});
}
await request.server.queue.add(queueSource);

return {
id: bot.id,
};
} catch (error) {
console.log(error);
return reply.status(500).send({
message: "Internal Server Error",
});
}
};
3 changes: 2 additions & 1 deletion server/src/handlers/api/v1/bot/bot/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export * from "./get.handler";
export * from "./upload.handler";
export * from "./delete.handler";
export * from "./put.handler";
export * from "./copy.handler";
export * from "./copy.handler";
export * from "./api.handler"
27 changes: 26 additions & 1 deletion server/src/handlers/api/v1/bot/bot/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,19 @@ export interface AddNewSourceById {
};
}

export interface AddNewSourceBulkById {
Params: {
id: string;
};
Body: {
type: string;
content: string;
maxDepth?: number;
maxLinks?: number;
options?: any;
}[];
}

export interface AddNewPDFById {
Params: {
id: string;
Expand Down Expand Up @@ -75,4 +88,16 @@ export interface GetBotById {
Params: {
bot_id: string;
};
}
}


export interface CreateBotAPIRequest {
Body: {
name?: string;
embedding: string;
model: string;
system_prompt?: string;
question_generator_prompt?: string;
temperature?: number;
};
}
28 changes: 26 additions & 2 deletions server/src/routes/api/v1/bot/root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@ import {
updateBotByIdHandler,
getCreateBotConfigHandler,
getBotByIdSettingsHandler,
createCopyHandler
createCopyHandler,
createBotAPIHandler,
addNewSourceByIdBulkHandler
} from "../../../../handlers/api/v1/bot/bot";
import {
addNewSourceByIdSchema,
createBotSchema,
getBotByIdSchema,
updateBotByIdSchema,
createCopyBotSchema
createCopyBotSchema,
createBotAPISchema,
addNewSourceByBulkIdSchema
} from "../../../../schema/api/v1/bot/bot";

const root: FastifyPluginAsync = async (fastify, _): Promise<void> => {
Expand Down Expand Up @@ -207,6 +211,26 @@ const root: FastifyPluginAsync = async (fastify, _): Promise<void> => {
},
createCopyHandler
);

// for sdk
fastify.post(
"/api",
{
schema: createBotAPISchema,
onRequest: [fastify.authenticate],
},
createBotAPIHandler
);

// add new source by bulk id
fastify.post(
"/:id/source/bulk",
{
schema: addNewSourceByBulkIdSchema,
onRequest: [fastify.authenticate],
},
addNewSourceByIdBulkHandler
);
};

export default root;
82 changes: 81 additions & 1 deletion server/src/schema/api/v1/bot/bot/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,84 @@ export const createCopyBotSchema: FastifySchema = {
},
},
},
};
};


export const createBotAPISchema: FastifySchema = {
tags: ["Bot"],
headers: {
type: "object",
properties: {
Authorization: { type: "string" },
},
required: ["Authorization"],
},
body: {
type: "object",
properties: {
name: {
type: "string",
},
embedding: {
type: "string",
},
model: {
type: "string",
},
question_generator_prompt: {
type: "string",
},
system_prompt: {
type: "string",
},
temperature: {
type: "number",
},
},
},
};

export const addNewSourceByBulkIdSchema: FastifySchema = {
tags: ["Bot"],
headers: {
type: "object",
properties: {
Authorization: { type: "string" },
},
required: ["Authorization"],
},
params: {
type: "object",
required: ["id"],
properties: {
id: {
type: "string",
},
},
},
body: {
type: "array",
items: {
type: "object",
properties: {
content: {
type: "string",
},
type: {
type: "string",
enum: SUPPORTED_SOURCE_TYPES,
},
maxDepth: {
type: "number",
},
maxLinks: {
type: "number",
},

options: {
type: "object",
},
},
},
},
};
Loading

0 comments on commit 1b7e96c

Please sign in to comment.