Merge pull request #4 from Eng-Elias/V0.2

V0.2

### Version 0.2

- Features:
  - Update crewai package and add more fields to agents and tasks.
  - Add more tools:
    - ARXIV to search in scientific articles of many domains.
    - PubMed to answer questions about medicine, health, and biomedical topic.
- Improvement:
  - Update python and npm packages.
  - Some UI enhancements.
  - Add .bat and .sh files to setup and start the project easily for normal users.
  - Enhance README.md.
This commit is contained in:
Eng. Elias
2024-03-24 20:58:06 +04:00
committed by GitHub
28 changed files with 1818 additions and 1102 deletions

View File

@@ -1,3 +1,4 @@
{ {
"extends": "next/core-web-vitals" "extends": "next/core-web-vitals",
"ignorePatterns": ["venv/**/*.*"]
} }

View File

@@ -15,7 +15,15 @@ This application provides a simplified user interface for leveraging the power o
## Getting Started ## Getting Started
To get started with the CrewAI Simplified App, follow these simple steps: To get started with the CrewAI Simplified App, install [PostgreSQL](https://www.postgresql.org/download/), setup PostgreSQL user and password and follow these simple steps:
For non-developers:
1. **Setup the project**: clone or download the project then run `setup_win.bat` for Windows users or `setup_linux_mac.sh` for Linux or MacOS users.
2. **Start the project**: run `start_win.bat` for Windows users or `start_linux_mac.sh` for Linux or MacOS users. ✔Finish!
For developers:
1. **Installation**: Clone the repository and install dependencies using npm or yarn: 1. **Installation**: Clone the repository and install dependencies using npm or yarn:
@@ -56,7 +64,7 @@ To get started with the CrewAI Simplified App, follow these simple steps:
Just rename .env.template to .env and set your values: Just rename .env.template to .env and set your values:
```plaintext ```plaintext
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/ crew_ai_visualizer?schema=public" DATABASE_URL="postgresql://<user>:<password>@localhost:5432/crew_ai_visualizer?schema=public"
GEMINI_API_KEY="" GEMINI_API_KEY=""
@@ -65,23 +73,37 @@ To get started with the CrewAI Simplified App, follow these simple steps:
CREW_AI_PY_FILE="<the path of my crew_ai.py file in on your system. you can find it in src/app/api/graphql/crew_ai.py>" CREW_AI_PY_FILE="<the path of my crew_ai.py file in on your system. you can find it in src/app/api/graphql/crew_ai.py>"
``` ```
4. **Start the Development Server**: Run the following command to start the development server: 4. **DB Migrations**: Run the following commands to apply database migrations:
```bash
npx prisma generate
npx prisma migrate deploy
```
5. **Start the Development Server**: Run the following command to start the development server:
```bash ```bash
npm run dev npm run dev
``` ```
5. **Access the App**: Once the development server is running, access the app in your browser at `http://localhost:3000`. OR build the project and run the production server:
```bash
npm run build
npm start
```
6. **Access the App**: Once the development server is running, access the app in your browser at `http://localhost:3000`.
## Usage ## Usage
1. **Create a New Crew**: By adding agents. 1. **Create a New Crew**: By adding agents.
2. **Customize Agents**: Fill in the information for each agent, including role, goal, backstory, tools, allow_deligation, and verbose. 2. **Customize Agents**: Fill in the information for each agent, including role, goal, backstory, tools, allow_deligation, verbose and memory.
3. **Define Missions**: Fill mission information including name, crew, verbose, process and add tasks with their details (name, description, agent). 3. **Define Missions**: Fill mission information including name, crew, verbose, process and add tasks with their details (name, description, agent, expected_output).
4. **Execute Mission**: Once your mission is set up, execute it to start the execution process. 4. **Execute Mission**: Once your mission is set up, run it to start the execution process.
5. **View Results**: View the output of completed missions within the app. 5. **View Results**: View the output of completed missions within the app.
@@ -98,15 +120,36 @@ We welcome contributions to the CrewAI Simplified App. If you'd like to contribu
This app is built using TypeScript, Prisma, GraphQL, Next.js, and node-calls-python to execute Python code from Node.js and get the result in addition to use Gemini as LLM. This app is built using TypeScript, Prisma, GraphQL, Next.js, and node-calls-python to execute Python code from Node.js and get the result in addition to use Gemini as LLM.
## License ## Updates
This application is open-source and is released under the MIT License. See the [LICENSE](LICENSE) file for details. ### Version 0.1
- Initial version.
### Version 0.2
- Features:
- Update crewai package and add more fields to agents and tasks.
- Add more tools:
- ARXIV to search in scientific articles of many domains.
- PubMed to answer questions about medicine, health, and biomedical topic.
- Improvement:
- Update python and npm packages.
- Some UI enhancements.
- Add .bat and .sh files to setup and start the project easily for normal users.
- Enhance README.md.
## To Do ## To Do
- [ ] Build simpler version to simplify installing and using CrewAI Visualizer by normal users.
- [ ] Integrate [crewai[tools]](https://docs.crewai.com/core-concepts/Tools/) by adding tools settings to allow configuring API keys and uploading files.
- [ ] Add more tools for agents either from LangChain community or create new useful tools. - [ ] Add more tools for agents either from LangChain community or create new useful tools.
- [ ] Add more LLM options like ChatGPT and local LLMs. - [ ] Add more LLM options like ChatGPT and local LLMs.
## License
This application is open-source and is released under the MIT License. See the [LICENSE](LICENSE) file for details.
## Credits ## Credits
Special thanks to [João Moura](https://github.com/joaomdmoura) the creator of [CrewAI](https://github.com/joaomdmoura/crewAI) for providing the underlying framework for AI crew orchestration. Special thanks to [João Moura](https://github.com/joaomdmoura) the creator of [CrewAI](https://github.com/joaomdmoura/crewAI) for providing the underlying framework for AI crew orchestration.

2174
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -10,41 +10,41 @@
"lint": "next lint" "lint": "next lint"
}, },
"dependencies": { "dependencies": {
"@apollo/client": "^3.9.5", "@apollo/client": "^3.9.9",
"@apollo/experimental-nextjs-app-support": "^0.8.0", "@apollo/experimental-nextjs-app-support": "^0.8.0",
"@apollo/server": "^4.10.0", "@apollo/server": "^4.10.2",
"@as-integrations/next": "^3.0.0", "@as-integrations/next": "^3.0.0",
"@material-tailwind/react": "^2.1.9", "@material-tailwind/react": "^2.1.9",
"@prisma/client": "^5.9.1", "@prisma/client": "^5.11.0",
"framer-motion": "^11.0.8", "framer-motion": "^11.0.20",
"graphql": "^16.8.1", "graphql": "^16.8.1",
"next": "14.1.0", "next": "14.1.0",
"node-calls-python": "^1.8.2", "node-calls-python": "^1.8.2",
"react": "^18", "react": "^18",
"react-dom": "^18", "react-dom": "^18",
"sharp": "^0.33.2", "sharp": "^0.33.3",
"sweetalert2": "^11.10.5", "sweetalert2": "^11.10.7",
"sweetalert2-react-content": "^5.0.7", "sweetalert2-react-content": "^5.0.7",
"tw-elements": "^1.1.0", "tw-elements": "^1.1.0",
"tw-elements-react": "^1.0.0-alpha2", "tw-elements-react": "^1.0.0-alpha2",
"uuid": "^9.0.1" "uuid": "^9.0.1"
}, },
"devDependencies": { "devDependencies": {
"@ianvs/prettier-plugin-sort-imports": "^4.1.0", "@ianvs/prettier-plugin-sort-imports": "^4.2.1",
"@iconify/react": "^4.1.1", "@iconify/react": "^4.1.1",
"@types/node": "^20.11.19", "@types/node": "^20.11.30",
"@types/react": "^18", "@types/react": "^18.2.69",
"@types/react-dom": "^18", "@types/react-dom": "^18.2.22",
"@types/uuid": "^9.0.8", "@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^6.7.3", "@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.7.3", "@typescript-eslint/parser": "^6.21.0",
"autoprefixer": "^10.0.1", "autoprefixer": "^10.4.19",
"eslint": "^8", "eslint": "^8.57.0",
"eslint-config-next": "14.1.0", "eslint-config-next": "14.1.0",
"postcss": "^8", "postcss": "^8.4.38",
"prisma": "^5.9.1", "prisma": "^5.11.0",
"tailwindcss": "^3.3.0", "tailwindcss": "^3.4.1",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "^5.3.3" "typescript": "^5.4.3"
} }
} }

View File

@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Agent" ADD COLUMN "memory" BOOLEAN NOT NULL DEFAULT false;

View File

@@ -0,0 +1,10 @@
-- AlterEnum
-- This migration adds more than one value to an enum.
-- With PostgreSQL versions 11 and earlier, this is not possible
-- in a single migration. This can be worked around by creating
-- multiple migrations, each migration adding only one value to
-- the enum.
ALTER TYPE "AgentTool" ADD VALUE 'ARXIV';
ALTER TYPE "AgentTool" ADD VALUE 'PUBMED';

View File

@@ -17,6 +17,8 @@ enum AgentTool {
WIKIPEDIA WIKIPEDIA
YAHOO_FINANCE YAHOO_FINANCE
YUOUTUBE_SEARCH YUOUTUBE_SEARCH
ARXIV
PUBMED
} }
model Agent { model Agent {
@@ -27,6 +29,7 @@ model Agent {
tools AgentTool[] @default([]) tools AgentTool[] @default([])
allowDelegation Boolean @default(false) allowDelegation Boolean @default(false)
verbose Boolean @default(false) verbose Boolean @default(false)
memory Boolean @default(false)
image String? image String?
createdAt DateTime @default(now()) createdAt DateTime @default(now())

View File

@@ -1,106 +1,203 @@
aiohttp==3.9.3 aiohttp==3.9.3
aiosignal==1.3.1 aiosignal==1.3.1
alembic==1.13.1
annotated-types==0.6.0 annotated-types==0.6.0
anyio==4.3.0 anyio==4.3.0
appdirs==1.4.4 appdirs==1.4.4
arxiv==2.1.0
asgiref==3.7.2
attrs==23.2.0 attrs==23.2.0
backoff==2.2.1 backoff==2.2.1
bcrypt==4.1.2
beautifulsoup4==4.12.3 beautifulsoup4==4.12.3
Brotli==1.1.0
build==1.1.1
cachetools==5.3.2 cachetools==5.3.2
certifi==2024.2.2 certifi==2024.2.2
cffi==1.16.0 cffi==1.16.0
charset-normalizer==3.3.2 charset-normalizer==3.3.2
chroma-hnswlib==0.7.3
chromadb==0.4.24
click==8.1.7 click==8.1.7
colorama==0.4.6 colorama==0.4.6
crewai==0.11.2 coloredlogs==15.0.1
contextlib2==21.6.0
crewai==0.22.5
crewai-tools==0.0.15
cryptography==42.0.5
curl_cffi==0.6.0b9 curl_cffi==0.6.0b9
dataclasses-json==0.6.4 dataclasses-json==0.6.4
decorator==5.1.1
Deprecated==1.2.14 Deprecated==1.2.14
deprecation==2.1.0
distro==1.9.0 distro==1.9.0
docstring-parser==0.15 docstring-parser==0.15
duckduckgo_search==4.4.3 duckduckgo_search==4.4.3
embedchain==0.1.97
fastapi==0.110.0
feedparser==6.0.10
filelock==3.13.1
flatbuffers==24.3.7
frozendict==2.4.0 frozendict==2.4.0
frozenlist==1.4.1 frozenlist==1.4.1
fsspec==2024.3.0
gitdb==4.0.11
GitPython==3.1.42
google-ai-generativelanguage==0.4.0 google-ai-generativelanguage==0.4.0
google-api-core==2.17.1 google-api-core==2.17.1
google-auth==2.28.0 google-auth==2.28.0
google-generativeai==0.3.2 google-cloud-aiplatform==1.44.0
google-cloud-bigquery==3.19.0
google-cloud-core==2.4.1
google-cloud-resource-manager==1.12.3
google-cloud-storage==2.15.0
google-crc32c==1.5.0
google-generativeai==0.4.1
google-resumable-media==2.7.0
googleapis-common-protos==1.62.0 googleapis-common-protos==1.62.0
gptcache==0.1.43
greenlet==3.0.3 greenlet==3.0.3
grpc-google-iam-v1==0.13.0
grpcio==1.60.1 grpcio==1.60.1
grpcio-status==1.60.1 grpcio-status==1.60.1
h11==0.14.0 h11==0.14.0
html5lib==1.1 html5lib==1.1
httpcore==1.0.3 httpcore==1.0.3
httptools==0.6.1
httpx==0.26.0 httpx==0.26.0
huggingface-hub==0.21.4
humanfriendly==10.0
idna==3.6 idna==3.6
importlib-metadata==6.11.0 importlib-metadata==6.11.0
importlib_resources==6.3.1
iniconfig==2.0.0
instructor==0.5.2 instructor==0.5.2
jsonpatch==1.33 jsonpatch==1.33
jsonpointer==2.4 jsonpointer==2.4
langchain==0.1.8 kubernetes==29.0.0
langchain-community==0.0.21 lancedb==0.5.7
langchain-core==0.1.24 langchain==0.1.13
langchain-experimental==0.0.52 langchain-community==0.0.29
langchain-google-genai==0.0.9 langchain-core==0.1.33
langchain-experimental==0.0.55
langchain-google-genai==0.0.11
langchain-openai==0.0.5 langchain-openai==0.0.5
langsmith==0.1.3 langchain-text-splitters==0.0.1
langsmith==0.1.31
lxml==5.1.0 lxml==5.1.0
Mako==1.3.2
markdown-it-py==3.0.0 markdown-it-py==3.0.0
MarkupSafe==2.1.5
marshmallow==3.20.2 marshmallow==3.20.2
mdurl==0.1.2 mdurl==0.1.2
mediawikiapi==1.2 mediawikiapi==1.2
mmh3==4.1.0
monotonic==1.6
mpmath==1.3.0
multidict==6.0.5 multidict==6.0.5
multitasking==0.0.11 multitasking==0.0.11
mutagen==1.47.0
mypy-extensions==1.0.0 mypy-extensions==1.0.0
nest-asyncio==1.6.0 nest-asyncio==1.6.0
nodeenv==1.8.0
numpy==1.26.4 numpy==1.26.4
openai==1.12.0 oauthlib==3.2.2
onnxruntime==1.17.1
openai==1.14.1
opentelemetry-api==1.22.0 opentelemetry-api==1.22.0
opentelemetry-exporter-otlp-proto-common==1.22.0 opentelemetry-exporter-otlp-proto-common==1.22.0
opentelemetry-exporter-otlp-proto-grpc==1.22.0
opentelemetry-exporter-otlp-proto-http==1.22.0 opentelemetry-exporter-otlp-proto-http==1.22.0
opentelemetry-instrumentation==0.43b0
opentelemetry-instrumentation-asgi==0.43b0
opentelemetry-instrumentation-fastapi==0.43b0
opentelemetry-proto==1.22.0 opentelemetry-proto==1.22.0
opentelemetry-sdk==1.22.0 opentelemetry-sdk==1.22.0
opentelemetry-semantic-conventions==0.43b0 opentelemetry-semantic-conventions==0.43b0
opentelemetry-util-http==0.43b0
orjson==3.9.15
outcome==1.3.0.post0
overrides==7.7.0
packaging==23.2 packaging==23.2
pandas==2.2.0 pandas==2.2.0
peewee==3.17.1 peewee==3.17.1
pluggy==1.4.0
posthog==3.5.0
proto-plus==1.23.0 proto-plus==1.23.0
protobuf==4.25.3 protobuf==4.25.3
pulsar-client==3.4.0
py==1.11.0
pyarrow==15.0.1
pyasn1==0.5.1 pyasn1==0.5.1
pyasn1-modules==0.3.0 pyasn1-modules==0.3.0
pycparser==2.21 pycparser==2.21
pycryptodomex==3.20.0
pydantic==2.6.1 pydantic==2.6.1
pydantic_core==2.16.2 pydantic_core==2.16.2
PyGithub==1.59.1
Pygments==2.17.2 Pygments==2.17.2
PyJWT==2.8.0
pylance==0.9.18
PyNaCl==1.5.0
pypdf==3.17.4
PyPika==0.48.9
pyproject_hooks==1.0.0
pyreadline3==3.4.1
pyright==1.1.354
pysbd==0.3.4
PySocks==1.7.1
pytest==8.1.1
python-dateutil==2.8.2 python-dateutil==2.8.2
python-dotenv==1.0.1 python-dotenv==1.0.0
pytube==15.0.0
pytz==2024.1 pytz==2024.1
PyYAML==6.0.1 PyYAML==6.0.1
ratelimiter==1.2.0.post0
regex==2023.12.25 regex==2023.12.25
requests==2.31.0 requests==2.31.0
requests-oauthlib==1.4.0
retry==0.9.2
rich==13.7.0 rich==13.7.0
rsa==4.9 rsa==4.9
schema==0.7.5
selenium==4.18.1
semanticscholar==0.7.0 semanticscholar==0.7.0
semver==3.0.2
sgmllib3k==1.0.0
shapely==2.0.3
six==1.16.0 six==1.16.0
smmap==5.0.1
sniffio==1.3.0 sniffio==1.3.0
sortedcontainers==2.4.0
soupsieve==2.5 soupsieve==2.5
SQLAlchemy==2.0.27 SQLAlchemy==2.0.27
StackAPI==0.3.0 StackAPI==0.3.0
starlette==0.36.3
sympy==1.12
tenacity==8.2.3 tenacity==8.2.3
tiktoken==0.5.2 tiktoken==0.5.2
tokenizers==0.15.2
tqdm==4.66.2 tqdm==4.66.2
trio==0.24.0
trio-websocket==0.11.1
typer==0.9.0 typer==0.9.0
typing-inspect==0.9.0 typing-inspect==0.9.0
typing_extensions==4.9.0 typing_extensions==4.9.0
tzdata==2024.1 tzdata==2024.1
urllib3==2.2.1 urllib3==2.2.1
uvicorn==0.28.0
watchfiles==0.21.0
webencodings==0.5.1 webencodings==0.5.1
websocket-client==1.7.0
websockets==12.0
wikibase-rest-api-client==0.1.3 wikibase-rest-api-client==0.1.3
wikipedia==1.4.0 wikipedia==1.4.0
wrapt==1.16.0 wrapt==1.16.0
wsproto==1.2.0
xmltodict==0.13.0 xmltodict==0.13.0
yarl==1.9.4 yarl==1.9.4
yfinance==0.2.36 yfinance==0.2.36
youtube-search==2.1.2 youtube-search==2.1.2
youtube-transcript-api==0.6.2
yt-dlp==2023.12.30
zipp==3.17.0 zipp==3.17.0

26
setup_linux_mac.sh Normal file
View File

@@ -0,0 +1,26 @@
#!/bin/bash
# Install npm packages
echo "Installing npm packages..."
npm i
# Create Python virtual environment
echo "Creating Python virtual environment..."
python3 -m venv venv
# Install Python packages using pip
echo "Installing Python dependencies..."
./venv/bin/python ./venv/bin/pip install -r requirements.txt
# Prisma Migrations
echo "Applying Prisma Migrations..."
npx prisma generate
npx prisma migrate deploy
# Building the project
echo "Building the project..."
npm run build
# Building is finished
echo "Building is finished"
pause

25
setup_win.bat Normal file
View File

@@ -0,0 +1,25 @@
@echo off
REM Install npm packages
echo Installing npm packages...
call npm i
echo Creating Python virtual environment...
call python -m venv venv
REM Install Python packages using pip
echo Installing Python dependencies...
call "./venv/scripts/python.exe" "./venv/scripts/pip.exe" install -r requirements.txt
REM Prisma Migrations
echo Applying Prisma Migrations...
call npx prisma generate
call npx prisma migrate deploy
REM Building the project
echo Building the project
call npm run build
REM Building is finished
echo Building is finished
pause

View File

@@ -7,6 +7,7 @@ import { GET_AGENTS } from "@/utils/graphql_queries";
import { useQuery } from "@apollo/client"; import { useQuery } from "@apollo/client";
import { Icon } from "@iconify/react"; import { Icon } from "@iconify/react";
import { Alert, Button, IconButton } from "@material-tailwind/react"; import { Alert, Button, IconButton } from "@material-tailwind/react";
import Image from "next/image";
import { useState } from "react"; import { useState } from "react";
const AgentsPage = () => { const AgentsPage = () => {
@@ -24,6 +25,8 @@ const AgentsPage = () => {
loading={true} loading={true}
placeholder={"Loading"} placeholder={"Loading"}
className="text-white" className="text-white"
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Loading Loading
</Button> </Button>
@@ -40,6 +43,8 @@ const AgentsPage = () => {
onClick={() => { onClick={() => {
setShowNewAgentModal(true); setShowNewAgentModal(true);
}} }}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
<Icon icon="mdi:add-bold" width="30" height="30" /> <Icon icon="mdi:add-bold" width="30" height="30" />
</IconButton> </IconButton>
@@ -65,6 +70,19 @@ const AgentsPage = () => {
</Alert> </Alert>
</div> </div>
)} )}
{data?.agents.length === 0 && (
<div className="w-full">
<Alert
color="cyan"
icon={
<Icon icon="material-symbols:warning-outline" fontSize={26} />
}
className="w-fit"
>
No Agents, Try to add one.
</Alert>
</div>
)}
{data?.agents.map((agent: Agent, i: number) => ( {data?.agents.map((agent: Agent, i: number) => (
<div key={i} className="w-full lg:w-1/2 p-3 relative"> <div key={i} className="w-full lg:w-1/2 p-3 relative">
<div <div
@@ -72,8 +90,8 @@ const AgentsPage = () => {
i % 2 == 0 ? "lg:flex-row" : "lg:flex-row-reverse" i % 2 == 0 ? "lg:flex-row" : "lg:flex-row-reverse"
} rounded overflow-hidden h-auto min-h-52 border`} } rounded overflow-hidden h-auto min-h-52 border`}
> >
<img <Image
className="block max-w-72 w-full lg:w-48 flex-none bg-cover" className="block max-w-72 w-full lg:w-48 flex-none bg-cover mx-auto"
src={agent.image ?? "/agents_images/sailor.png"} src={agent.image ?? "/agents_images/sailor.png"}
alt="Agent" alt="Agent"
/> />

View File

@@ -3,13 +3,15 @@ import os
from textwrap import dedent from textwrap import dedent
from crewai import Agent, Task, Crew, Process from crewai import Agent, Task, Crew, Process
from langchain_google_genai import ChatGoogleGenerativeAI from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_community.tools import DuckDuckGoSearchRun from langchain_community.tools.ddg_search import DuckDuckGoSearchRun
from langchain_community.tools.semanticscholar.tool import SemanticScholarQueryRun from langchain_community.tools.semanticscholar.tool import SemanticScholarQueryRun
from langchain_community.tools.wikidata.tool import WikidataAPIWrapper, WikidataQueryRun from langchain_community.tools.wikidata.tool import WikidataAPIWrapper, WikidataQueryRun
from langchain_community.tools import WikipediaQueryRun from langchain_community.tools.wikipedia.tool import WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper from langchain_community.utilities.wikipedia import WikipediaAPIWrapper
from langchain_community.tools.yahoo_finance_news import YahooFinanceNewsTool from langchain_community.tools.yahoo_finance_news import YahooFinanceNewsTool
from langchain_community.tools import YouTubeSearchTool from langchain_community.tools.youtube.search import YouTubeSearchTool
from langchain_community.tools.arxiv.tool import ArxivQueryRun
from langchain_community.tools.pubmed.tool import PubmedQueryRun
from dotenv import load_dotenv from dotenv import load_dotenv
load_dotenv() load_dotenv()
@@ -26,6 +28,8 @@ tool_dict = {
"WIKIPEDIA": WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper()), "WIKIPEDIA": WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper()),
"YAHOO_FINANCE": YahooFinanceNewsTool(), "YAHOO_FINANCE": YahooFinanceNewsTool(),
"YUOUTUBE_SEARCH": YouTubeSearchTool(), "YUOUTUBE_SEARCH": YouTubeSearchTool(),
"ARXIV": ArxivQueryRun(),
"PUBMED": PubmedQueryRun(),
} }
@@ -47,6 +51,8 @@ def run_mission(mission):
verbose=agent["verbose"], verbose=agent["verbose"],
tools=[tool_dict[tool] for tool in agent["tools"]], tools=[tool_dict[tool] for tool in agent["tools"]],
llm=llm, llm=llm,
max_rpm=60 / len(mission["crew"]),
memory=agent.get("memory", False),
) )
for agent in mission["crew"] for agent in mission["crew"]
] ]
@@ -61,6 +67,7 @@ def run_mission(mission):
if task["agent"] if task["agent"]
else None else None
), ),
expected_output=task["expected_output"],
) )
for task in mission["tasks"] for task in mission["tasks"]
] ]

View File

@@ -58,24 +58,13 @@ const resolvers = {
id: true, id: true,
}, },
}); });
const tasks = [];
for (let task of body.tasks) {
let agent = null;
if (task.agent) {
agent = crew.find((a) => a.id === task.agent) ?? null;
}
tasks.push({
...task,
agent,
});
}
const mission = await prisma.mission.create({ const mission = await prisma.mission.create({
data: { data: {
name, name,
verbose: !!verbose, verbose: !!verbose,
process: process ?? Process.SEQUENTIAL, process: process ?? Process.SEQUENTIAL,
crew: { connect: crew }, crew: { connect: crew },
tasks, tasks: [],
result: "", result: "",
}, },
}); });

View File

@@ -6,6 +6,8 @@ const typeDefs = `#graphql
WIKIPEDIA WIKIPEDIA
YAHOO_FINANCE YAHOO_FINANCE
YUOUTUBE_SEARCH YUOUTUBE_SEARCH
ARXIV
PUBMED
} }
type Agent { type Agent {
@@ -16,6 +18,7 @@ const typeDefs = `#graphql
tools: [AgentTool!]! tools: [AgentTool!]!
allowDelegation: Boolean! allowDelegation: Boolean!
verbose: Boolean! verbose: Boolean!
memory: Boolean
image: String image: String
missions: [Mission!] missions: [Mission!]
} }
@@ -31,12 +34,14 @@ const typeDefs = `#graphql
type Task { type Task {
name: String! name: String!
description: String! description: String!
expected_output: String!
agent: Agent agent: Agent
} }
input TaskInput { input TaskInput {
name: String! name: String!
description: String! description: String!
expected_output: String!
agent: Int agent: Int
} }
@@ -74,8 +79,9 @@ const typeDefs = `#graphql
goal: String! goal: String!
backstory: String backstory: String
tools: [AgentTool!] = [] tools: [AgentTool!] = []
allowDelegation: Boolean = false allowDelegation: Boolean
verbose: Boolean = false verbose: Boolean
memory: Boolean
): Agent! ): Agent!
updateAgent( updateAgent(
@@ -86,6 +92,7 @@ const typeDefs = `#graphql
tools: [AgentTool!] tools: [AgentTool!]
allowDelegation: Boolean allowDelegation: Boolean
verbose: Boolean verbose: Boolean
memory: Boolean
): Agent! ): Agent!
deleteAgent(id: Int!): DeleteOutput deleteAgent(id: Int!): DeleteOutput
@@ -93,8 +100,7 @@ const typeDefs = `#graphql
createMission( createMission(
name: String! name: String!
crew: [Int!] = [] crew: [Int!] = []
tasks: [TaskInput!] = [] verbose: Boolean
verbose: Boolean = false
process: MissionProcess = "SEQUENTIAL" process: MissionProcess = "SEQUENTIAL"
): Mission! ): Mission!

View File

@@ -24,6 +24,8 @@ const MissionsPage = () => {
loading={true} loading={true}
placeholder={"Loading"} placeholder={"Loading"}
className="text-white" className="text-white"
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Loading Loading
</Button> </Button>
@@ -54,6 +56,8 @@ const MissionsPage = () => {
onClick={() => { onClick={() => {
setShowNewMissionModal(true); setShowNewMissionModal(true);
}} }}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
<Icon icon="mdi:add-bold" width="30" height="30" /> <Icon icon="mdi:add-bold" width="30" height="30" />
</IconButton> </IconButton>
@@ -65,6 +69,19 @@ const MissionsPage = () => {
}} }}
/> />
</div> </div>
{data?.missions.length === 0 && (
<div className="w-full">
<Alert
color="cyan"
icon={
<Icon icon="material-symbols:warning-outline" fontSize={26} />
}
className="w-fit"
>
No missions, Try to add one.
</Alert>
</div>
)}
<div className="container m-auto flex flex-wrap flex-col md:flex-row items-center justify-start p-2"> <div className="container m-auto flex flex-wrap flex-col md:flex-row items-center justify-start p-2">
{data?.missions.map((mission: Mission, i: number) => ( {data?.missions.map((mission: Mission, i: number) => (
<div key={i} className=" w-full lg:w-1/2 p-3"> <div key={i} className=" w-full lg:w-1/2 p-3">

View File

@@ -4,7 +4,7 @@ import { selectTheme } from "@/data/consts";
import { Agent } from "@/types/agent"; import { Agent } from "@/types/agent";
import { Mission } from "@/types/mission"; import { Mission } from "@/types/mission";
import { Task } from "@/types/task"; import { Task } from "@/types/task";
import { Button } from "@material-tailwind/react"; import { Button, Input, Textarea } from "@material-tailwind/react";
import React, { useState } from "react"; import React, { useState } from "react";
import { TESelect } from "tw-elements-react"; import { TESelect } from "tw-elements-react";
@@ -20,13 +20,15 @@ const MissionTaskEditor: React.FC<MissionTaskEditorProps> = ({
onMissionChange, onMissionChange,
}) => { }) => {
const [newTaskName, setNewTaskName] = useState(""); const [newTaskName, setNewTaskName] = useState("");
const [newTaskAgent, setNewTaskAgent] = useState<Agent | null>(null);
const [newTaskDescription, setNewTaskDescription] = useState(""); const [newTaskDescription, setNewTaskDescription] = useState("");
const [newTaskExpectedOutput, setNewTaskExpectedOutput] = useState("");
const [newTaskAgent, setNewTaskAgent] = useState<Agent | null>(null);
const handleAddTask = () => { const handleAddTask = () => {
const newTask: Task = { const newTask: Task = {
name: newTaskName, name: newTaskName,
description: newTaskDescription, description: newTaskDescription,
expected_output: newTaskExpectedOutput,
agent: newTaskAgent, agent: newTaskAgent,
}; };
const updatedTasks = [...(mission?.tasks ?? []), newTask]; const updatedTasks = [...(mission?.tasks ?? []), newTask];
@@ -54,6 +56,8 @@ const MissionTaskEditor: React.FC<MissionTaskEditorProps> = ({
onClick={() => handleRemoveTask(index)} onClick={() => handleRemoveTask(index)}
className="text-red-500" className="text-red-500"
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Remove Remove
</Button> </Button>
@@ -73,23 +77,36 @@ const MissionTaskEditor: React.FC<MissionTaskEditorProps> = ({
</div> </div>
<div className="border border-t-0 border-success-400 rounded-b bg-success-100 px-4 py-3 text-success-700"> <div className="border border-t-0 border-success-400 rounded-b bg-success-100 px-4 py-3 text-success-700">
<div> <div>
<label>Task Name: </label> <Input
<input label="Task Name"
type="text" color="green"
placeholder="Task Name"
value={newTaskName} value={newTaskName}
onChange={(e) => setNewTaskName(e.target.value)} onChange={(e) => setNewTaskName(e.target.value)}
className="border border-gray-300 text-black rounded px-3 py-1" crossOrigin={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/>
</div>
<div className="my-2">
<Textarea
label="Task Description"
color="green"
resize={true}
value={newTaskDescription}
onChange={(e) => setNewTaskDescription(e.target.value)}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/> />
</div> </div>
<div> <div>
<label>Task Description: </label> <Textarea
<br /> label="Expected Output"
<textarea color="green"
placeholder="Task Description" resize={true}
value={newTaskDescription} value={newTaskExpectedOutput}
onChange={(e) => setNewTaskDescription(e.target.value)} onChange={(e) => setNewTaskExpectedOutput(e.target.value)}
className="w-full border border-gray-300 text-black rounded px-3 py-1 ml-2" onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/> />
</div> </div>
<div className="m-2"> <div className="m-2">
@@ -118,6 +135,8 @@ const MissionTaskEditor: React.FC<MissionTaskEditorProps> = ({
disabled={!newTaskName || !newTaskDescription} disabled={!newTaskName || !newTaskDescription}
onClick={handleAddTask} onClick={handleAddTask}
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Add Task Add Task
</Button> </Button>

View File

@@ -12,17 +12,16 @@ import {
TEModalHeader, TEModalHeader,
TEModalBody, TEModalBody,
TEModalFooter, TEModalFooter,
TEInput,
TETextarea,
TESelect, TESelect,
} from "tw-elements-react"; } from "tw-elements-react";
import TWFileInput from "../inputs/file"; import TWFileInput from "../inputs/file";
import { selectTheme } from "@/data/consts"; import { selectTheme } from "@/data/consts";
import { Button, Switch } from "@material-tailwind/react"; import { Button, Input, Switch, Textarea } from "@material-tailwind/react";
import Swal from "sweetalert2"; import Swal from "sweetalert2";
import withReactContent from "sweetalert2-react-content"; import withReactContent from "sweetalert2-react-content";
import { DELETE_AGENT, UPDATE_AGENT } from "@/utils/graphql_queries"; import { DELETE_AGENT, UPDATE_AGENT } from "@/utils/graphql_queries";
import { useMutation } from "@apollo/client"; import { useMutation } from "@apollo/client";
import Image from "next/image";
export default function AgentModal(props: { export default function AgentModal(props: {
agent: Agent; agent: Agent;
@@ -164,6 +163,8 @@ export default function AgentModal(props: {
<Button <Button
onClick={() => setShowModal(false)} onClick={() => setShowModal(false)}
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
<Icon icon="ep:close-bold" width={20} height={20} /> <Icon icon="ep:close-bold" width={20} height={20} />
</Button> </Button>
@@ -174,9 +175,10 @@ export default function AgentModal(props: {
{isEdit && ( {isEdit && (
<div className="mb-4"> <div className="mb-4">
<label className="font-bold text-lg">Role:</label> <label className="font-bold text-lg">Role:</label>
<TEInput <Input
type="text" label="Role"
className="mt-2" color="blue"
className="text-white"
value={tempAgent?.role} value={tempAgent?.role}
onChange={(event) => { onChange={(event) => {
setTempAgent((prevState) => ({ setTempAgent((prevState) => ({
@@ -184,15 +186,19 @@ export default function AgentModal(props: {
role: event.target.value, role: event.target.value,
})); }));
}} }}
crossOrigin={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/> />
</div> </div>
)} )}
<div className="mb-4"> <div className="mb-4">
<label className="font-bold text-lg">Goal:</label> <label className="font-bold text-lg">Goal:</label>
{isEdit ? ( {isEdit ? (
<TEInput <Input
type="text" label="Goal"
className="mt-2" color="blue"
className="text-white"
value={tempAgent?.goal} value={tempAgent?.goal}
onChange={(event) => { onChange={(event) => {
setTempAgent((prevState) => ({ setTempAgent((prevState) => ({
@@ -200,6 +206,9 @@ export default function AgentModal(props: {
goal: event.target.value, goal: event.target.value,
})); }));
}} }}
crossOrigin={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/> />
) : ( ) : (
<div>{agent?.goal}</div> <div>{agent?.goal}</div>
@@ -208,8 +217,11 @@ export default function AgentModal(props: {
<div className="mb-4"> <div className="mb-4">
<label className="font-bold text-lg">Backstory:</label> <label className="font-bold text-lg">Backstory:</label>
{isEdit ? ( {isEdit ? (
<TETextarea <Textarea
rows={4} label="Backstory"
color="blue"
className="text-white"
resize={true}
value={tempAgent?.backstory || ""} value={tempAgent?.backstory || ""}
onChange={(event) => { onChange={(event) => {
setTempAgent((prevState) => ({ setTempAgent((prevState) => ({
@@ -217,6 +229,8 @@ export default function AgentModal(props: {
backstory: event.target.value, backstory: event.target.value,
})); }));
}} }}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/> />
) : ( ) : (
<div>{agent?.backstory}</div> <div>{agent?.backstory}</div>
@@ -263,13 +277,17 @@ export default function AgentModal(props: {
allowDelegation: !!event.target.value, allowDelegation: !!event.target.value,
})); }));
}} }}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/> />
) : ( ) : (
<Switch <Switch
crossOrigin={undefined} crossOrigin={undefined}
color="blue" color="blue"
defaultChecked={tempAgent?.allowDelegation} checked={agent?.allowDelegation}
disabled={true} disabled={true}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/> />
)} )}
</div> </div>
@@ -286,13 +304,44 @@ export default function AgentModal(props: {
verbose: !!event.target.value, verbose: !!event.target.value,
})); }));
}} }}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/> />
) : ( ) : (
<Switch <Switch
crossOrigin={undefined} crossOrigin={undefined}
color="blue" color="blue"
defaultChecked={tempAgent?.verbose} checked={agent?.verbose}
disabled={true} disabled={true}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/>
)}
</div>
<div className="flex items-center mb-4">
<label className="font-bold mx-2">Memory: </label>
{isEdit ? (
<Switch
crossOrigin={undefined}
color="blue"
defaultChecked={tempAgent?.memory}
onChange={(event) => {
setTempAgent((prevState) => ({
...prevState!,
memory: !!event.target.value,
}));
}}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/>
) : (
<Switch
crossOrigin={undefined}
color="blue"
checked={agent?.memory}
disabled={true}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/> />
)} )}
</div> </div>
@@ -316,12 +365,14 @@ export default function AgentModal(props: {
color="blue" color="blue"
className="mx-auto" className="mx-auto"
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Upload Upload
</Button> </Button>
</div> </div>
{selectedImage && ( {selectedImage && (
<img <Image
// @ts-ignore // @ts-ignore
src={selectedImage} src={selectedImage}
alt="Agent Image" alt="Agent Image"
@@ -330,7 +381,7 @@ export default function AgentModal(props: {
)} )}
</> </>
) : ( ) : (
<img <Image
src={tempAgent?.image ?? "/agents_images/sailor.png"} src={tempAgent?.image ?? "/agents_images/sailor.png"}
alt="Agent Image" alt="Agent Image"
className="w-7/12 mx-auto rounded-lg" className="w-7/12 mx-auto rounded-lg"
@@ -374,6 +425,8 @@ export default function AgentModal(props: {
}); });
}} }}
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Delete Delete
</Button> </Button>
@@ -383,6 +436,8 @@ export default function AgentModal(props: {
color="green" color="green"
onClick={() => setEdit(true)} onClick={() => setEdit(true)}
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Edit Edit
</Button> </Button>
@@ -396,6 +451,8 @@ export default function AgentModal(props: {
color="white" color="white"
onClick={() => setEdit(false)} onClick={() => setEdit(false)}
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Cancel Cancel
</Button> </Button>
@@ -411,6 +468,7 @@ export default function AgentModal(props: {
handleUpdateAgent(tempAgent) handleUpdateAgent(tempAgent)
.then(() => { .then(() => {
setShowModal(false); setShowModal(false);
setEdit(false);
ReactSwal.fire({ ReactSwal.fire({
title: "Updated", title: "Updated",
text: "Agent updated successfully", text: "Agent updated successfully",
@@ -428,6 +486,8 @@ export default function AgentModal(props: {
}} }}
className="mx-1" className="mx-1"
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Save Changes Save Changes
</Button> </Button>

View File

@@ -10,14 +10,13 @@ import {
TEModalHeader, TEModalHeader,
TEModalBody, TEModalBody,
TEModalFooter, TEModalFooter,
TEInput,
TESelect, TESelect,
} from "tw-elements-react"; } from "tw-elements-react";
import { Mission } from "@/types/mission"; import { Mission } from "@/types/mission";
import MissionTaskEditor from "../inputs/mission_tasks_editor"; import MissionTaskEditor from "../inputs/mission_tasks_editor";
import { TasksAccordion } from "../ui/tasks_accordions"; import { TasksAccordion } from "../ui/tasks_accordions";
import { Process, selectTheme } from "@/data/consts"; import { Process, selectTheme } from "@/data/consts";
import { Alert, Button, Switch } from "@material-tailwind/react"; import { Alert, Button, Input, Switch } from "@material-tailwind/react";
import { useMutation, useQuery } from "@apollo/client"; import { useMutation, useQuery } from "@apollo/client";
import { import {
DELETE_MISSION, DELETE_MISSION,
@@ -80,6 +79,7 @@ export default function MissionModal(props: {
tasks: missionData.tasks.map((task) => ({ tasks: missionData.tasks.map((task) => ({
name: task.name, name: task.name,
description: task.description, description: task.description,
expected_output: task.expected_output,
agent: Number.parseInt(task.agent?.id as string), agent: Number.parseInt(task.agent?.id as string),
})), })),
}, },
@@ -130,6 +130,8 @@ export default function MissionModal(props: {
<Button <Button
onClick={() => setShowModal(false)} onClick={() => setShowModal(false)}
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
<Icon icon="ep:close-bold" width={20} height={20} /> <Icon icon="ep:close-bold" width={20} height={20} />
</Button> </Button>
@@ -139,9 +141,10 @@ export default function MissionModal(props: {
{isEdit && ( {isEdit && (
<div className="mb-4"> <div className="mb-4">
<label className="font-bold text-lg">Name:</label> <label className="font-bold text-lg">Name:</label>
<TEInput <Input
type="text" label="Name"
className="mt-2" color="blue"
className="text-white"
value={tempMission?.name} value={tempMission?.name}
onChange={(event) => { onChange={(event) => {
setTempMission((prevState) => ({ setTempMission((prevState) => ({
@@ -149,6 +152,9 @@ export default function MissionModal(props: {
name: event.target.value, name: event.target.value,
})); }));
}} }}
crossOrigin={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/> />
</div> </div>
)} )}
@@ -180,6 +186,8 @@ export default function MissionModal(props: {
loading={true} loading={true}
placeholder={"Loading"} placeholder={"Loading"}
className="text-white" className="text-white"
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Loading Loading
</Button> </Button>
@@ -241,6 +249,8 @@ export default function MissionModal(props: {
verbose: !!event.target.value, verbose: !!event.target.value,
})); }));
}} }}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/> />
) : ( ) : (
<Switch <Switch
@@ -248,6 +258,8 @@ export default function MissionModal(props: {
color="blue" color="blue"
checked={mission?.verbose} checked={mission?.verbose}
disabled={true} disabled={true}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/> />
)} )}
</div> </div>
@@ -342,6 +354,8 @@ export default function MissionModal(props: {
}); });
}} }}
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
{mission?.result ? "Re-Run" : "Run"} {mission?.result ? "Re-Run" : "Run"}
</Button> </Button>
@@ -351,6 +365,8 @@ export default function MissionModal(props: {
loading={true} loading={true}
placeholder={"Running"} placeholder={"Running"}
className="text-white" className="text-white"
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Running Running
</Button> </Button>
@@ -358,14 +374,12 @@ export default function MissionModal(props: {
</div> </div>
<div> <div>
<label className="font-bold text-lg">Result:</label> <label className="font-bold text-lg">Result:</label>
{mission?.result && ( <div
<div className="border-2 rounded p-2"
className="border-2 rounded p-2" style={{ whiteSpace: "pre-line" }}
style={{ whiteSpace: "pre-line" }} >
> {missionResult}
{missionResult} </div>
</div>
)}
</div> </div>
</> </>
)} )}
@@ -407,6 +421,8 @@ export default function MissionModal(props: {
}); });
}} }}
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Delete Delete
</Button> </Button>
@@ -416,6 +432,8 @@ export default function MissionModal(props: {
color="green" color="green"
onClick={() => setEdit(true)} onClick={() => setEdit(true)}
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Edit Edit
</Button> </Button>
@@ -429,6 +447,8 @@ export default function MissionModal(props: {
color="white" color="white"
onClick={() => setEdit(false)} onClick={() => setEdit(false)}
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Cancel Cancel
</Button> </Button>
@@ -460,6 +480,8 @@ export default function MissionModal(props: {
}} }}
className="mx-1" className="mx-1"
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Save Changes Save Changes
</Button> </Button>

View File

@@ -4,7 +4,6 @@ import { Agent } from "@/types/agent";
import { Icon } from "@iconify/react/dist/iconify.js"; import { Icon } from "@iconify/react/dist/iconify.js";
import React, { useState } from "react"; import React, { useState } from "react";
import { import {
TEInput,
TEModal, TEModal,
TEModalBody, TEModalBody,
TEModalContent, TEModalContent,
@@ -13,9 +12,8 @@ import {
TEModalHeader, TEModalHeader,
TERipple, TERipple,
TESelect, TESelect,
TETextarea,
} from "tw-elements-react"; } from "tw-elements-react";
import { Button, Switch } from "@material-tailwind/react"; import { Button, Input, Switch, Textarea } from "@material-tailwind/react";
import { useMutation } from "@apollo/client"; import { useMutation } from "@apollo/client";
import { CREATE_AGENT } from "@/utils/graphql_queries"; import { CREATE_AGENT } from "@/utils/graphql_queries";
import withReactContent from "sweetalert2-react-content"; import withReactContent from "sweetalert2-react-content";
@@ -41,23 +39,6 @@ function NewAgentModal(props: {
verbose: false, verbose: false,
}); });
const [selectedImage, setSelectedImage] = useState<
string | ArrayBuffer | null
>(null);
const handleImageChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event?.target?.files?.[0];
const reader = new FileReader();
reader.onloadend = () => {
setSelectedImage(reader.result);
};
if (file) {
reader.readAsDataURL(file);
}
};
const [createAgent] = useMutation(CREATE_AGENT); const [createAgent] = useMutation(CREATE_AGENT);
const [createAgentLoading, setCreateAgentLoading] = useState(false); const [createAgentLoading, setCreateAgentLoading] = useState(false);
@@ -86,6 +67,8 @@ function NewAgentModal(props: {
<Button <Button
onClick={() => setShowModal(false)} onClick={() => setShowModal(false)}
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
<Icon icon="ep:close-bold" width={20} height={20} /> <Icon icon="ep:close-bold" width={20} height={20} />
</Button> </Button>
@@ -95,9 +78,10 @@ function NewAgentModal(props: {
<div className="sm:w-1/2 mx-auto"> <div className="sm:w-1/2 mx-auto">
<div className="mb-4"> <div className="mb-4">
<label className="font-bold text-lg">Role:</label> <label className="font-bold text-lg">Role:</label>
<TEInput <Input
type="text" label="Role"
className="mt-2" color="blue"
className="text-white"
value={tempAgent?.role} value={tempAgent?.role}
onChange={(event) => { onChange={(event) => {
setTempAgent((prevState) => ({ setTempAgent((prevState) => ({
@@ -105,13 +89,17 @@ function NewAgentModal(props: {
role: event.target.value, role: event.target.value,
})); }));
}} }}
crossOrigin={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/> />
</div> </div>
<div className="mb-4"> <div className="mb-4">
<label className="font-bold text-lg">Goal:</label> <label className="font-bold text-lg">Goal:</label>
<TEInput <Input
type="text" label="Goal"
className="mt-2" color="blue"
className="text-white"
value={tempAgent?.goal} value={tempAgent?.goal}
onChange={(event) => { onChange={(event) => {
setTempAgent((prevState) => ({ setTempAgent((prevState) => ({
@@ -119,12 +107,18 @@ function NewAgentModal(props: {
goal: event.target.value, goal: event.target.value,
})); }));
}} }}
crossOrigin={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/> />
</div> </div>
<div className="mb-4"> <div className="mb-4">
<label className="font-bold text-lg">Backstory:</label> <label className="font-bold text-lg">Backstory:</label>
<TETextarea <Textarea
rows={4} label="Backstory"
color="blue"
className="text-white"
resize={true}
value={tempAgent?.backstory || ""} value={tempAgent?.backstory || ""}
onChange={(event) => { onChange={(event) => {
setTempAgent((prevState) => ({ setTempAgent((prevState) => ({
@@ -132,6 +126,8 @@ function NewAgentModal(props: {
backstory: event.target.value, backstory: event.target.value,
})); }));
}} }}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/> />
</div> </div>
<div className="flex flex-wrap mb-4"> <div className="flex flex-wrap mb-4">
@@ -163,6 +159,8 @@ function NewAgentModal(props: {
allowDelegation: !!event.target.value, allowDelegation: !!event.target.value,
})); }));
}} }}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/> />
</div> </div>
<div className="flex items-center mb-4"> <div className="flex items-center mb-4">
@@ -177,6 +175,24 @@ function NewAgentModal(props: {
verbose: !!event.target.value, verbose: !!event.target.value,
})); }));
}} }}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/>
</div>
<div className="flex items-center mb-4">
<label className="font-bold mx-2">Memory: </label>
<Switch
crossOrigin={undefined}
color="blue"
defaultChecked={tempAgent?.verbose}
onChange={(event) => {
setTempAgent((prevState) => ({
...prevState!,
memory: !!event.target.value,
}));
}}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/> />
</div> </div>
</div> </div>
@@ -189,6 +205,8 @@ function NewAgentModal(props: {
color="white" color="white"
onClick={() => setShowModal(false)} onClick={() => setShowModal(false)}
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Close Close
</Button> </Button>
@@ -221,6 +239,8 @@ function NewAgentModal(props: {
}} }}
className="mx-1" className="mx-1"
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Add Add
</Button> </Button>

View File

@@ -1,10 +1,9 @@
import { Process, selectTheme } from "@/data/consts"; import { Process, selectTheme } from "@/data/consts";
import { Mission } from "@/types/mission"; import { Mission } from "@/types/mission";
import { Icon } from "@iconify/react/dist/iconify.js"; import { Icon } from "@iconify/react/dist/iconify.js";
import { Alert, Button, Switch } from "@material-tailwind/react"; import { Alert, Button, Input, Switch } from "@material-tailwind/react";
import React, { useState } from "react"; import React, { useState } from "react";
import { import {
TEInput,
TEModal, TEModal,
TEModalBody, TEModalBody,
TEModalContent, TEModalContent,
@@ -14,7 +13,6 @@ import {
TERipple, TERipple,
TESelect, TESelect,
} from "tw-elements-react"; } from "tw-elements-react";
import MissionTaskEditor from "../inputs/mission_tasks_editor";
import { useMutation, useQuery } from "@apollo/client"; import { useMutation, useQuery } from "@apollo/client";
import { CREATE_MISSION, GET_AGENTS } from "@/utils/graphql_queries"; import { CREATE_MISSION, GET_AGENTS } from "@/utils/graphql_queries";
import { Agent } from "@/types/agent"; import { Agent } from "@/types/agent";
@@ -79,6 +77,8 @@ function NewMissionModal(props: {
<Button <Button
onClick={() => setShowModal(false)} onClick={() => setShowModal(false)}
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
<Icon icon="ep:close-bold" width={20} height={20} /> <Icon icon="ep:close-bold" width={20} height={20} />
</Button> </Button>
@@ -87,9 +87,10 @@ function NewMissionModal(props: {
<div> <div>
<div className="mb-4"> <div className="mb-4">
<label className="font-bold text-lg">Name:</label> <label className="font-bold text-lg">Name:</label>
<TEInput <Input
type="text" label="Name"
className="mt-2" color="blue"
className="text-white"
value={tempMission?.name} value={tempMission?.name}
onChange={(event) => { onChange={(event) => {
setTempMission((prevState) => ({ setTempMission((prevState) => ({
@@ -97,6 +98,9 @@ function NewMissionModal(props: {
name: event.target.value, name: event.target.value,
})); }));
}} }}
crossOrigin={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/> />
</div> </div>
<div className="mb-4"> <div className="mb-4">
@@ -126,6 +130,8 @@ function NewMissionModal(props: {
loading={true} loading={true}
placeholder={"Loading"} placeholder={"Loading"}
className="text-white" className="text-white"
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Loading Loading
</Button> </Button>
@@ -173,6 +179,8 @@ function NewMissionModal(props: {
verbose: !!event.target.value, verbose: !!event.target.value,
})); }));
}} }}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/> />
</div> </div>
<div className="mb-4"> <div className="mb-4">
@@ -205,6 +213,8 @@ function NewMissionModal(props: {
color="white" color="white"
onClick={() => setShowModal(false)} onClick={() => setShowModal(false)}
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Close Close
</Button> </Button>
@@ -235,6 +245,8 @@ function NewMissionModal(props: {
}} }}
className="mx-1" className="mx-1"
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
Add Add
</Button> </Button>

View File

@@ -3,6 +3,7 @@ import {
Accordion, Accordion,
AccordionHeader, AccordionHeader,
AccordionBody, AccordionBody,
Typography,
} from "@material-tailwind/react"; } from "@material-tailwind/react";
import { Task } from "@/types/task"; import { Task } from "@/types/task";
@@ -19,11 +20,15 @@ export function TasksAccordion({ tasks }: { tasks: Array<Task> }) {
open={open === i} open={open === i}
className="mb-2 rounded-lg border border-blue-gray-100 px-4" className="mb-2 rounded-lg border border-blue-gray-100 px-4"
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
<AccordionHeader <AccordionHeader
onClick={() => handleOpen(i)} onClick={() => handleOpen(i)}
className={`border-b-0 transition-colors ${open === i ? "text-blue-500 hover:!text-blue-700" : "text-gray-400 hover:!text-gray-300"}`} className={`border-b-0 transition-colors ${open === i ? "text-blue-500 hover:!text-blue-700" : "text-gray-400 hover:!text-gray-300"}`}
placeholder={undefined} placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
> >
{task.name} {task.name}
</AccordionHeader> </AccordionHeader>
@@ -33,7 +38,34 @@ export function TasksAccordion({ tasks }: { tasks: Array<Task> }) {
{task.agent?.role ?? "No Agent"} {task.agent?.role ?? "No Agent"}
</span> </span>
</div> </div>
<div>{task.description}</div> <div>
<Typography
variant="lead"
placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
>
{task.description}
</Typography>
</div>
<div>
<Typography
variant="h3"
placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
>
Expected Output
</Typography>
<Typography
variant="paragraph"
placeholder={undefined}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
>
{task.expected_output}
</Typography>
</div>
</AccordionBody> </AccordionBody>
</Accordion> </Accordion>
))} ))}

View File

@@ -53,6 +53,8 @@ export const tools = [
{ text: "WIKIPEDIA", value: "WIKIPEDIA" }, { text: "WIKIPEDIA", value: "WIKIPEDIA" },
{ text: "YAHOO_FINANCE", value: "YAHOO_FINANCE" }, { text: "YAHOO_FINANCE", value: "YAHOO_FINANCE" },
{ text: "YUOUTUBE_SEARCH", value: "YUOUTUBE_SEARCH" }, { text: "YUOUTUBE_SEARCH", value: "YUOUTUBE_SEARCH" },
{ text: "ARXIV", value: "ARXIV" },
{ text: "PUBMED", value: "PUBMED" },
]; ];
const game = ` const game = `
@@ -74,9 +76,9 @@ export const missions: Array<Mission> = [
Instructions Instructions
------------ ------------
${game} ${game}
Your Final answer must be the full python code, only the python code and nothing else.
`, `,
expected_output:
"Your Final answer must be the full python code, only the python code and nothing else.",
agent: agents[0], agent: agents[0],
}, },
{ {
@@ -91,9 +93,9 @@ export const missions: Array<Mission> = [
Using the code you got, check for errors. Check for logic errors, Using the code you got, check for errors. Check for logic errors,
syntax errors, missing imports, variable declarations, mismatched brackets, syntax errors, missing imports, variable declarations, mismatched brackets,
and security vulnerabilities. and security vulnerabilities.
Your Final answer must be the full python code, only the python code and nothing else.
`, `,
expected_output:
"Your Final answer must be the full python code, only the python code and nothing else.",
agent: agents[1], agent: agents[1],
}, },
{ {
@@ -107,9 +109,9 @@ export const missions: Array<Mission> = [
You will look over the code to insure that it is complete and You will look over the code to insure that it is complete and
does the job that it is supposed to do. does the job that it is supposed to do.
Your Final answer must be the full python code, only the python code and nothing else.
`, `,
expected_output:
"Your Final answer must be the full python code, only the python code and nothing else.",
agent: agents[2], agent: agents[2],
}, },
], ],
@@ -124,11 +126,13 @@ export const missions: Array<Mission> = [
{ {
name: "Task1", name: "Task1",
description: "description description description description", description: "description description description description",
expected_output: "Expected Output",
agent: agents[0], agent: agents[0],
}, },
{ {
name: "Task2", name: "Task2",
description: "description description description description", description: "description description description description",
expected_output: "Expected Output",
}, },
], ],
verbose: true, verbose: true,
@@ -142,11 +146,13 @@ export const missions: Array<Mission> = [
{ {
name: "Task1", name: "Task1",
description: "description description description description", description: "description description description description",
expected_output: "Expected Output",
agent: agents[0], agent: agents[0],
}, },
{ {
name: "Task2", name: "Task2",
description: "description description description description", description: "description description description description",
expected_output: "Expected Output",
}, },
], ],
verbose: true, verbose: true,

View File

@@ -4,7 +4,9 @@ type Tool =
| "WIKIDATA" | "WIKIDATA"
| "WIKIPEDIA" | "WIKIPEDIA"
| "YAHOO_FINANCE" | "YAHOO_FINANCE"
| "YUOUTUBE_SEARCH"; | "YUOUTUBE_SEARCH"
| "ARXIV"
| "PUBMED";
export type Agent = { export type Agent = {
id?: number | string; id?: number | string;
@@ -14,5 +16,6 @@ export type Agent = {
tools: Array<Tool>; tools: Array<Tool>;
allowDelegation: boolean; allowDelegation: boolean;
verbose: boolean; verbose: boolean;
memory?: boolean;
image?: string | null; image?: string | null;
}; };

View File

@@ -9,5 +9,6 @@ export type TaskInput = {
export type Task = { export type Task = {
name: string; name: string;
description: string; description: string;
expected_output: string;
agent?: Agent | null; agent?: Agent | null;
}; };

View File

@@ -10,6 +10,7 @@ export const GET_AGENTS = gql`
tools tools
allowDelegation allowDelegation
verbose verbose
memory
image image
} }
} }
@@ -25,6 +26,7 @@ export const GET_AGENT_BY_ID = gql`
tools tools
allowDelegation allowDelegation
verbose verbose
memory
image image
missions { missions {
id id
@@ -42,6 +44,7 @@ export const CREATE_AGENT = gql`
$tools: [AgentTool!] $tools: [AgentTool!]
$allowDelegation: Boolean! $allowDelegation: Boolean!
$verbose: Boolean! $verbose: Boolean!
$memory: Boolean
) { ) {
createAgent( createAgent(
role: $role role: $role
@@ -50,6 +53,7 @@ export const CREATE_AGENT = gql`
tools: $tools tools: $tools
allowDelegation: $allowDelegation allowDelegation: $allowDelegation
verbose: $verbose verbose: $verbose
memory: $memory
) { ) {
id id
role role
@@ -58,6 +62,7 @@ export const CREATE_AGENT = gql`
tools tools
allowDelegation allowDelegation
verbose verbose
memory
image image
} }
} }
@@ -72,6 +77,7 @@ export const UPDATE_AGENT = gql`
$tools: [AgentTool!] $tools: [AgentTool!]
$allowDelegation: Boolean $allowDelegation: Boolean
$verbose: Boolean $verbose: Boolean
$memory: Boolean
) { ) {
updateAgent( updateAgent(
id: $id id: $id
@@ -81,6 +87,7 @@ export const UPDATE_AGENT = gql`
tools: $tools tools: $tools
allowDelegation: $allowDelegation allowDelegation: $allowDelegation
verbose: $verbose verbose: $verbose
memory: $memory
) { ) {
id id
role role
@@ -89,6 +96,7 @@ export const UPDATE_AGENT = gql`
tools tools
allowDelegation allowDelegation
verbose verbose
memory
image image
} }
} }
@@ -115,11 +123,13 @@ export const GET_MISSIONS = gql`
tools tools
allowDelegation allowDelegation
verbose verbose
memory
image image
} }
tasks { tasks {
name name
description description
expected_output
agent { agent {
id id
role role
@@ -145,11 +155,13 @@ export const GET_MISSION_BY_ID = gql`
tools tools
allowDelegation allowDelegation
verbose verbose
memory
image image
} }
tasks { tasks {
name name
description description
expected_output
agent { agent {
id id
role role
@@ -166,14 +178,12 @@ export const CREATE_MISSION = gql`
mutation CreateMission( mutation CreateMission(
$name: String! $name: String!
$crew: [Int!] $crew: [Int!]
$tasks: [TaskInput!]
$verbose: Boolean $verbose: Boolean
$process: MissionProcess $process: MissionProcess
) { ) {
createMission( createMission(
name: $name name: $name
crew: $crew crew: $crew
tasks: $tasks
verbose: $verbose verbose: $verbose
process: $process process: $process
) { ) {
@@ -187,11 +197,13 @@ export const CREATE_MISSION = gql`
tools tools
allowDelegation allowDelegation
verbose verbose
memory
image image
} }
tasks { tasks {
name name
description description
expected_output
agent { agent {
id id
role role
@@ -231,11 +243,13 @@ export const UPDATE_MISSION = gql`
tools tools
allowDelegation allowDelegation
verbose verbose
memory
image image
} }
tasks { tasks {
name name
description description
expected_output
agent { agent {
id id
role role

9
start_linux_mac.sh Normal file
View File

@@ -0,0 +1,9 @@
#!/bin/bash
# Open browser
echo "Opening browser..."
open http://localhost:3000
# Run the project
echo "Starting development server..."
npm start

10
start_win.bat Normal file
View File

@@ -0,0 +1,10 @@
REM Run the project
echo Starting development server...
start call npm start
REM Wait for a few seconds to ensure the server is up and running
timeout /t 2
REM Open browser
echo Opening browser...
start http://localhost:3000

View File

@@ -22,5 +22,5 @@
} }
}, },
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "**/*.js", "postcss.config.cjs"], "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "**/*.js", "postcss.config.cjs"],
"exclude": ["node_modules"] "exclude": ["node_modules", "venv"]
} }