Agent and Mission GraphQL CRUD operations

This commit is contained in:
Eng. Elias
2024-02-20 17:06:45 +04:00
parent e6f08d85fc
commit 619f199abe
13 changed files with 1744 additions and 59 deletions

View File

@@ -0,0 +1,167 @@
import { Process } from "@/data/consts";
import { Agent } from "@/types/agent";
import { CreateMissionInput, Mission } from "@/types/mission";
import { Task } from "@/types/task";
import prisma from "@/utils/prisma";
import { GraphQLResolveInfo } from "graphql";
import { NextRequest, NextResponse } from "next/server";
const resolvers = {
Query: {
agents: () => {
return prisma.agent.findMany();
},
agent: (id: number) => {
return prisma.agent.findFirst({
where: {
id: id,
},
});
},
missions: async () => {
const missions = await prisma.mission.findMany({
include: {
crew: true,
},
});
return missions;
},
mission: (id: number) => {
return prisma.mission.findFirst({
where: {
id: id,
},
});
},
},
Mutation: {
createAgent: async (
parent: any,
body: Agent,
context: { req: NextRequest; res: NextResponse; datasource: any },
info: GraphQLResolveInfo
) => {
const agent = await prisma.agent.create({ data: body });
return agent;
},
updateAgent: async (
parent: any,
body: Agent,
context: { req: NextRequest; res: NextResponse; datasource: any },
info: GraphQLResolveInfo
) => {
const updatedAgent = await prisma.agent.update({
where: { id: body.id },
data: body,
});
return updatedAgent;
},
deleteAgent: async (
parent: any,
body: { id: number },
context: { req: NextRequest; res: NextResponse; datasource: any },
info: GraphQLResolveInfo
) => {
await prisma.agent.delete({ where: { id: body.id } });
return { deleted: true };
},
createMission: async (
parent: any,
body: CreateMissionInput,
context: { req: NextRequest; res: NextResponse; datasource: any },
info: GraphQLResolveInfo
) => {
const { name, verbose, process } = body;
const crew = await prisma.agent.findMany({
where: {
id: {
in: body.crew,
},
},
});
const tasks: Array<Task> = [];
for (let task of body.tasks) {
const agent = await prisma.agent.findFirst({
where: { id: task.agent },
});
tasks.push({
...task,
agent,
});
}
const mission = await prisma.mission.create({
data: {
name,
verbose: !!verbose,
process: process ?? Process.SEQUENTIAL,
crew: { create: crew },
tasks,
result: "",
},
});
mission.id;
return mission;
},
updateMission: async (
parent: any,
body: CreateMissionInput,
context: { req: NextRequest; res: NextResponse; datasource: any },
info: GraphQLResolveInfo
) => {
const { id, name, verbose, process } = body;
const crew = await prisma.agent.findMany({
where: {
id: {
in: body.crew,
},
},
});
const tasks: Array<Task> = [];
if (body.tasks) {
for (let task of body.tasks) {
const agent = await prisma.agent.findFirst({
where: { id: task.agent },
});
tasks.push({
...task,
agent,
});
}
}
const mission = await prisma.mission.update({
where: {
id,
},
include: {
crew: true,
},
data: {
name,
verbose: verbose,
process: process,
crew: { set: crew.map((agent) => ({ id: agent.id })) },
tasks,
result: "",
},
});
return mission;
},
deleteMission: async (
parent: any,
body: { id: number },
context: { req: NextRequest; res: NextResponse; datasource: any },
info: GraphQLResolveInfo
) => {
await prisma.mission.delete({ where: { id: body.id } });
return { deleted: true };
},
runMission: async (
parent: any,
body: { id: number },
context: { req: NextRequest; res: NextResponse; datasource: any },
info: GraphQLResolveInfo
) => {},
},
};
export default resolvers;

View File

@@ -0,0 +1,24 @@
import { startServerAndCreateNextHandler } from "@as-integrations/next";
import { ApolloServer } from "@apollo/server";
import { NextRequest, NextResponse } from "next/server";
import typeDefs from "./schema";
import resolvers from "./resolvers";
const server = new ApolloServer<object>({
resolvers,
typeDefs,
});
const handler = startServerAndCreateNextHandler<NextRequest>(server, {
context: async (req, res) => ({
req,
res,
dataSources: {},
}),
});
export async function GET(request: NextRequest) {
return handler(request);
}
export async function POST(request: NextRequest) {
return handler(request);
}

View File

@@ -0,0 +1,113 @@
const typeDefs = `#graphql
enum AgentTool {
DUCK_DUCK_GO_SEARCH
PUBMED
PYTHON_REPL
SEMANTIC_SCHOLER
STACK_EXCHANGE
WIKIDATA
WIKIPEDIA
YAHOO_FINANCE
YUOUTUBE_SEARCH
}
type Agent {
id: ID!
role: String!
goal: String!
backstory: String
tools: [AgentTool!]!
allowDelegation: Boolean!
verbose: Boolean!
image: String
missions: [Mission!]
}
input AgentInput {
id: ID!
}
type DeleteOutput {
deleted: Boolean!
}
type Task {
name: String!
description: String!
agent: Agent!
}
input TaskInput {
name: String!
description: String!
agent: Int
}
type Mission {
id: ID!
name: String!
crew: [Agent!]
tasks: [Task]
verbose: Boolean
process: MissionProcess
result: String
}
enum MissionProcess {
SEQUENTIAL
HIERARCHICAL
}
type Query {
agents(filter: String): [Agent!]!
agent(id: Int!): Agent
missions(filter: String): [Mission!]!
mission(id: Int!): Mission
}
type Mutation {
createAgent(
role: String!
goal: String!
backstory: String
tools: [AgentTool!] = []
allowDelegation: Boolean = false
verbose: Boolean = false
): Agent!
updateAgent(
id: Int!
role: String
goal: String
backstory: String
tools: [AgentTool!]
allowDelegation: Boolean
verbose: Boolean
): Agent!
deleteAgent(id: Int!): DeleteOutput
createMission(
name: String!
crew: [Int!] = []
tasks: [TaskInput!] = []
verbose: Boolean = false
process: MissionProcess = "SEQUENTIAL"
): Mission!
updateMission(
id: Int!
name: String
crew: [Int!]
tasks: [TaskInput!]
verbose: Boolean
process: MissionProcess
): Mission
deleteMission(id: Int!): DeleteOutput
runMission(id: Int!): Mission
}
`;
export default typeDefs;