Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd246b769d | ||
|
|
4013ffbe2f | ||
|
|
5d745abcd0 | ||
|
|
f7af9ac7ae | ||
|
|
a2fcd07924 | ||
|
|
ecc1138f8f | ||
|
|
f1cf96c5a4 | ||
|
|
24fab13a30 | ||
|
|
f3ff09bb4e | ||
|
|
a654f454b8 | ||
|
|
202483f47e |
@@ -1,3 +1,4 @@
|
||||
{
|
||||
"extends": "next/core-web-vitals"
|
||||
"extends": "next/core-web-vitals",
|
||||
"ignorePatterns": ["venv/**/*.*"]
|
||||
}
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -42,3 +42,6 @@ __pycache__/
|
||||
|
||||
# PyCharm
|
||||
.idea/
|
||||
|
||||
# Images
|
||||
agents_images/
|
||||
|
||||
60
README.md
60
README.md
@@ -2,8 +2,14 @@
|
||||
|
||||
This application provides a simplified user interface for leveraging the power of CrewAI, a cutting-edge framework for orchestrating role-playing autonomous AI agents. With this app, users can streamline the process of creating and managing AI crews without the need for coding.
|
||||
|
||||
<h3>V0.1</h3>
|
||||
|
||||
[](https://www.youtube.com/watch?v=ZVZucnzccpk)
|
||||
|
||||
<h3>V0.2</h3>
|
||||
|
||||
[](https://www.youtube.com/watch?v=IpGmL_EM_bY)
|
||||
|
||||
## Features
|
||||
|
||||
- **Intuitive UI**: The app offers a user-friendly interface, allowing users to easily create and manage AI crews.
|
||||
@@ -15,7 +21,15 @@ This application provides a simplified user interface for leveraging the power o
|
||||
|
||||
## 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:
|
||||
|
||||
@@ -56,7 +70,7 @@ To get started with the CrewAI Simplified App, follow these simple steps:
|
||||
Just rename .env.template to .env and set your values:
|
||||
|
||||
```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=""
|
||||
|
||||
@@ -65,23 +79,30 @@ 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>"
|
||||
```
|
||||
|
||||
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
|
||||
npm run dev
|
||||
```
|
||||
|
||||
5. **Access the App**: Once the development server is running, access the app in your browser at `http://localhost:3000`.
|
||||
6. **Access the App**: Once the development server is running, access the app in your browser at `http://localhost:3000`.
|
||||
|
||||
## Usage
|
||||
|
||||
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.
|
||||
|
||||
@@ -98,15 +119,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.
|
||||
|
||||
## 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
|
||||
|
||||
- [ ] 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 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
|
||||
|
||||
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
2174
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
36
package.json
36
package.json
@@ -10,41 +10,41 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.9.5",
|
||||
"@apollo/client": "^3.9.9",
|
||||
"@apollo/experimental-nextjs-app-support": "^0.8.0",
|
||||
"@apollo/server": "^4.10.0",
|
||||
"@apollo/server": "^4.10.2",
|
||||
"@as-integrations/next": "^3.0.0",
|
||||
"@material-tailwind/react": "^2.1.9",
|
||||
"@prisma/client": "^5.9.1",
|
||||
"framer-motion": "^11.0.8",
|
||||
"@prisma/client": "^5.11.0",
|
||||
"framer-motion": "^11.0.20",
|
||||
"graphql": "^16.8.1",
|
||||
"next": "14.1.0",
|
||||
"node-calls-python": "^1.8.2",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"sharp": "^0.33.2",
|
||||
"sweetalert2": "^11.10.5",
|
||||
"sharp": "^0.33.3",
|
||||
"sweetalert2": "^11.10.7",
|
||||
"sweetalert2-react-content": "^5.0.7",
|
||||
"tw-elements": "^1.1.0",
|
||||
"tw-elements-react": "^1.0.0-alpha2",
|
||||
"uuid": "^9.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ianvs/prettier-plugin-sort-imports": "^4.1.0",
|
||||
"@ianvs/prettier-plugin-sort-imports": "^4.2.1",
|
||||
"@iconify/react": "^4.1.1",
|
||||
"@types/node": "^20.11.19",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"@types/node": "^20.11.30",
|
||||
"@types/react": "^18.2.69",
|
||||
"@types/react-dom": "^18.2.22",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.3",
|
||||
"@typescript-eslint/parser": "^6.7.3",
|
||||
"autoprefixer": "^10.0.1",
|
||||
"eslint": "^8",
|
||||
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
||||
"@typescript-eslint/parser": "^6.21.0",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-next": "14.1.0",
|
||||
"postcss": "^8",
|
||||
"prisma": "^5.9.1",
|
||||
"tailwindcss": "^3.3.0",
|
||||
"postcss": "^8.4.38",
|
||||
"prisma": "^5.11.0",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.3.3"
|
||||
"typescript": "^5.4.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Agent" ADD COLUMN "memory" BOOLEAN NOT NULL DEFAULT false;
|
||||
@@ -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';
|
||||
@@ -17,6 +17,8 @@ enum AgentTool {
|
||||
WIKIPEDIA
|
||||
YAHOO_FINANCE
|
||||
YUOUTUBE_SEARCH
|
||||
ARXIV
|
||||
PUBMED
|
||||
}
|
||||
|
||||
model Agent {
|
||||
@@ -27,6 +29,7 @@ model Agent {
|
||||
tools AgentTool[] @default([])
|
||||
allowDelegation Boolean @default(false)
|
||||
verbose Boolean @default(false)
|
||||
memory Boolean @default(false)
|
||||
image String?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
117
requirements.txt
117
requirements.txt
@@ -1,106 +1,203 @@
|
||||
aiohttp==3.9.3
|
||||
aiosignal==1.3.1
|
||||
alembic==1.13.1
|
||||
annotated-types==0.6.0
|
||||
anyio==4.3.0
|
||||
appdirs==1.4.4
|
||||
arxiv==2.1.0
|
||||
asgiref==3.7.2
|
||||
attrs==23.2.0
|
||||
backoff==2.2.1
|
||||
bcrypt==4.1.2
|
||||
beautifulsoup4==4.12.3
|
||||
Brotli==1.1.0
|
||||
build==1.1.1
|
||||
cachetools==5.3.2
|
||||
certifi==2024.2.2
|
||||
cffi==1.16.0
|
||||
charset-normalizer==3.3.2
|
||||
chroma-hnswlib==0.7.3
|
||||
chromadb==0.4.24
|
||||
click==8.1.7
|
||||
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
|
||||
dataclasses-json==0.6.4
|
||||
decorator==5.1.1
|
||||
Deprecated==1.2.14
|
||||
deprecation==2.1.0
|
||||
distro==1.9.0
|
||||
docstring-parser==0.15
|
||||
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
|
||||
frozenlist==1.4.1
|
||||
fsspec==2024.3.0
|
||||
gitdb==4.0.11
|
||||
GitPython==3.1.42
|
||||
google-ai-generativelanguage==0.4.0
|
||||
google-api-core==2.17.1
|
||||
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
|
||||
gptcache==0.1.43
|
||||
greenlet==3.0.3
|
||||
grpc-google-iam-v1==0.13.0
|
||||
grpcio==1.60.1
|
||||
grpcio-status==1.60.1
|
||||
h11==0.14.0
|
||||
html5lib==1.1
|
||||
httpcore==1.0.3
|
||||
httptools==0.6.1
|
||||
httpx==0.26.0
|
||||
huggingface-hub==0.21.4
|
||||
humanfriendly==10.0
|
||||
idna==3.6
|
||||
importlib-metadata==6.11.0
|
||||
importlib_resources==6.3.1
|
||||
iniconfig==2.0.0
|
||||
instructor==0.5.2
|
||||
jsonpatch==1.33
|
||||
jsonpointer==2.4
|
||||
langchain==0.1.8
|
||||
langchain-community==0.0.21
|
||||
langchain-core==0.1.24
|
||||
langchain-experimental==0.0.52
|
||||
langchain-google-genai==0.0.9
|
||||
kubernetes==29.0.0
|
||||
lancedb==0.5.7
|
||||
langchain==0.1.13
|
||||
langchain-community==0.0.29
|
||||
langchain-core==0.1.33
|
||||
langchain-experimental==0.0.55
|
||||
langchain-google-genai==0.0.11
|
||||
langchain-openai==0.0.5
|
||||
langsmith==0.1.3
|
||||
langchain-text-splitters==0.0.1
|
||||
langsmith==0.1.31
|
||||
lxml==5.1.0
|
||||
Mako==1.3.2
|
||||
markdown-it-py==3.0.0
|
||||
MarkupSafe==2.1.5
|
||||
marshmallow==3.20.2
|
||||
mdurl==0.1.2
|
||||
mediawikiapi==1.2
|
||||
mmh3==4.1.0
|
||||
monotonic==1.6
|
||||
mpmath==1.3.0
|
||||
multidict==6.0.5
|
||||
multitasking==0.0.11
|
||||
mutagen==1.47.0
|
||||
mypy-extensions==1.0.0
|
||||
nest-asyncio==1.6.0
|
||||
nodeenv==1.8.0
|
||||
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-exporter-otlp-proto-common==1.22.0
|
||||
opentelemetry-exporter-otlp-proto-grpc==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-sdk==1.22.0
|
||||
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
|
||||
pandas==2.2.0
|
||||
peewee==3.17.1
|
||||
pluggy==1.4.0
|
||||
posthog==3.5.0
|
||||
proto-plus==1.23.0
|
||||
protobuf==4.25.3
|
||||
pulsar-client==3.4.0
|
||||
py==1.11.0
|
||||
pyarrow==15.0.1
|
||||
pyasn1==0.5.1
|
||||
pyasn1-modules==0.3.0
|
||||
pycparser==2.21
|
||||
pycryptodomex==3.20.0
|
||||
pydantic==2.6.1
|
||||
pydantic_core==2.16.2
|
||||
PyGithub==1.59.1
|
||||
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-dotenv==1.0.1
|
||||
python-dotenv==1.0.0
|
||||
pytube==15.0.0
|
||||
pytz==2024.1
|
||||
PyYAML==6.0.1
|
||||
ratelimiter==1.2.0.post0
|
||||
regex==2023.12.25
|
||||
requests==2.31.0
|
||||
requests-oauthlib==1.4.0
|
||||
retry==0.9.2
|
||||
rich==13.7.0
|
||||
rsa==4.9
|
||||
schema==0.7.5
|
||||
selenium==4.18.1
|
||||
semanticscholar==0.7.0
|
||||
semver==3.0.2
|
||||
sgmllib3k==1.0.0
|
||||
shapely==2.0.3
|
||||
six==1.16.0
|
||||
smmap==5.0.1
|
||||
sniffio==1.3.0
|
||||
sortedcontainers==2.4.0
|
||||
soupsieve==2.5
|
||||
SQLAlchemy==2.0.27
|
||||
StackAPI==0.3.0
|
||||
starlette==0.36.3
|
||||
sympy==1.12
|
||||
tenacity==8.2.3
|
||||
tiktoken==0.5.2
|
||||
tokenizers==0.15.2
|
||||
tqdm==4.66.2
|
||||
trio==0.24.0
|
||||
trio-websocket==0.11.1
|
||||
typer==0.9.0
|
||||
typing-inspect==0.9.0
|
||||
typing_extensions==4.9.0
|
||||
tzdata==2024.1
|
||||
urllib3==2.2.1
|
||||
uvicorn==0.28.0
|
||||
watchfiles==0.21.0
|
||||
webencodings==0.5.1
|
||||
websocket-client==1.7.0
|
||||
websockets==12.0
|
||||
wikibase-rest-api-client==0.1.3
|
||||
wikipedia==1.4.0
|
||||
wrapt==1.16.0
|
||||
wsproto==1.2.0
|
||||
xmltodict==0.13.0
|
||||
yarl==1.9.4
|
||||
yfinance==0.2.36
|
||||
youtube-search==2.1.2
|
||||
youtube-transcript-api==0.6.2
|
||||
yt-dlp==2023.12.30
|
||||
zipp==3.17.0
|
||||
|
||||
26
setup_linux_mac.sh
Normal file
26
setup_linux_mac.sh
Normal 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
25
setup_win.bat
Normal 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
|
||||
@@ -7,6 +7,7 @@ import { GET_AGENTS } from "@/utils/graphql_queries";
|
||||
import { useQuery } from "@apollo/client";
|
||||
import { Icon } from "@iconify/react";
|
||||
import { Alert, Button, IconButton } from "@material-tailwind/react";
|
||||
import Image from "next/image";
|
||||
import { useState } from "react";
|
||||
|
||||
const AgentsPage = () => {
|
||||
@@ -24,6 +25,8 @@ const AgentsPage = () => {
|
||||
loading={true}
|
||||
placeholder={"Loading"}
|
||||
className="text-white"
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Loading
|
||||
</Button>
|
||||
@@ -40,6 +43,8 @@ const AgentsPage = () => {
|
||||
onClick={() => {
|
||||
setShowNewAgentModal(true);
|
||||
}}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
<Icon icon="mdi:add-bold" width="30" height="30" />
|
||||
</IconButton>
|
||||
@@ -65,6 +70,19 @@ const AgentsPage = () => {
|
||||
</Alert>
|
||||
</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) => (
|
||||
<div key={i} className="w-full lg:w-1/2 p-3 relative">
|
||||
<div
|
||||
@@ -73,7 +91,7 @@ const AgentsPage = () => {
|
||||
} rounded overflow-hidden h-auto min-h-52 border`}
|
||||
>
|
||||
<img
|
||||
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"}
|
||||
alt="Agent"
|
||||
/>
|
||||
|
||||
@@ -3,13 +3,15 @@ import os
|
||||
from textwrap import dedent
|
||||
from crewai import Agent, Task, Crew, Process
|
||||
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.wikidata.tool import WikidataAPIWrapper, WikidataQueryRun
|
||||
from langchain_community.tools import WikipediaQueryRun
|
||||
from langchain_community.utilities import WikipediaAPIWrapper
|
||||
from langchain_community.tools.wikipedia.tool import WikipediaQueryRun
|
||||
from langchain_community.utilities.wikipedia import WikipediaAPIWrapper
|
||||
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
|
||||
|
||||
load_dotenv()
|
||||
@@ -26,6 +28,8 @@ tool_dict = {
|
||||
"WIKIPEDIA": WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper()),
|
||||
"YAHOO_FINANCE": YahooFinanceNewsTool(),
|
||||
"YUOUTUBE_SEARCH": YouTubeSearchTool(),
|
||||
"ARXIV": ArxivQueryRun(),
|
||||
"PUBMED": PubmedQueryRun(),
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +51,8 @@ def run_mission(mission):
|
||||
verbose=agent["verbose"],
|
||||
tools=[tool_dict[tool] for tool in agent["tools"]],
|
||||
llm=llm,
|
||||
max_rpm=60 / len(mission["crew"]),
|
||||
memory=agent.get("memory", False),
|
||||
)
|
||||
for agent in mission["crew"]
|
||||
]
|
||||
@@ -61,6 +67,7 @@ def run_mission(mission):
|
||||
if task["agent"]
|
||||
else None
|
||||
),
|
||||
expected_output=task["expected_output"],
|
||||
)
|
||||
for task in mission["tasks"]
|
||||
]
|
||||
|
||||
@@ -58,24 +58,13 @@ const resolvers = {
|
||||
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({
|
||||
data: {
|
||||
name,
|
||||
verbose: !!verbose,
|
||||
process: process ?? Process.SEQUENTIAL,
|
||||
crew: { connect: crew },
|
||||
tasks,
|
||||
tasks: [],
|
||||
result: "",
|
||||
},
|
||||
});
|
||||
|
||||
@@ -6,6 +6,8 @@ const typeDefs = `#graphql
|
||||
WIKIPEDIA
|
||||
YAHOO_FINANCE
|
||||
YUOUTUBE_SEARCH
|
||||
ARXIV
|
||||
PUBMED
|
||||
}
|
||||
|
||||
type Agent {
|
||||
@@ -16,6 +18,7 @@ const typeDefs = `#graphql
|
||||
tools: [AgentTool!]!
|
||||
allowDelegation: Boolean!
|
||||
verbose: Boolean!
|
||||
memory: Boolean
|
||||
image: String
|
||||
missions: [Mission!]
|
||||
}
|
||||
@@ -31,12 +34,14 @@ const typeDefs = `#graphql
|
||||
type Task {
|
||||
name: String!
|
||||
description: String!
|
||||
expected_output: String!
|
||||
agent: Agent
|
||||
}
|
||||
|
||||
input TaskInput {
|
||||
name: String!
|
||||
description: String!
|
||||
expected_output: String!
|
||||
agent: Int
|
||||
}
|
||||
|
||||
@@ -74,8 +79,9 @@ const typeDefs = `#graphql
|
||||
goal: String!
|
||||
backstory: String
|
||||
tools: [AgentTool!] = []
|
||||
allowDelegation: Boolean = false
|
||||
verbose: Boolean = false
|
||||
allowDelegation: Boolean
|
||||
verbose: Boolean
|
||||
memory: Boolean
|
||||
): Agent!
|
||||
|
||||
updateAgent(
|
||||
@@ -86,6 +92,7 @@ const typeDefs = `#graphql
|
||||
tools: [AgentTool!]
|
||||
allowDelegation: Boolean
|
||||
verbose: Boolean
|
||||
memory: Boolean
|
||||
): Agent!
|
||||
|
||||
deleteAgent(id: Int!): DeleteOutput
|
||||
@@ -93,8 +100,7 @@ const typeDefs = `#graphql
|
||||
createMission(
|
||||
name: String!
|
||||
crew: [Int!] = []
|
||||
tasks: [TaskInput!] = []
|
||||
verbose: Boolean = false
|
||||
verbose: Boolean
|
||||
process: MissionProcess = "SEQUENTIAL"
|
||||
): Mission!
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ const MissionsPage = () => {
|
||||
loading={true}
|
||||
placeholder={"Loading"}
|
||||
className="text-white"
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Loading
|
||||
</Button>
|
||||
@@ -54,6 +56,8 @@ const MissionsPage = () => {
|
||||
onClick={() => {
|
||||
setShowNewMissionModal(true);
|
||||
}}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
<Icon icon="mdi:add-bold" width="30" height="30" />
|
||||
</IconButton>
|
||||
@@ -65,6 +69,19 @@ const MissionsPage = () => {
|
||||
}}
|
||||
/>
|
||||
</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">
|
||||
{data?.missions.map((mission: Mission, i: number) => (
|
||||
<div key={i} className=" w-full lg:w-1/2 p-3">
|
||||
|
||||
@@ -4,7 +4,7 @@ import { selectTheme } from "@/data/consts";
|
||||
import { Agent } from "@/types/agent";
|
||||
import { Mission } from "@/types/mission";
|
||||
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 { TESelect } from "tw-elements-react";
|
||||
|
||||
@@ -20,13 +20,15 @@ const MissionTaskEditor: React.FC<MissionTaskEditorProps> = ({
|
||||
onMissionChange,
|
||||
}) => {
|
||||
const [newTaskName, setNewTaskName] = useState("");
|
||||
const [newTaskAgent, setNewTaskAgent] = useState<Agent | null>(null);
|
||||
const [newTaskDescription, setNewTaskDescription] = useState("");
|
||||
const [newTaskExpectedOutput, setNewTaskExpectedOutput] = useState("");
|
||||
const [newTaskAgent, setNewTaskAgent] = useState<Agent | null>(null);
|
||||
|
||||
const handleAddTask = () => {
|
||||
const newTask: Task = {
|
||||
name: newTaskName,
|
||||
description: newTaskDescription,
|
||||
expected_output: newTaskExpectedOutput,
|
||||
agent: newTaskAgent,
|
||||
};
|
||||
const updatedTasks = [...(mission?.tasks ?? []), newTask];
|
||||
@@ -34,6 +36,8 @@ const MissionTaskEditor: React.FC<MissionTaskEditorProps> = ({
|
||||
onMissionChange(updatedMission);
|
||||
setNewTaskName("");
|
||||
setNewTaskDescription("");
|
||||
setNewTaskExpectedOutput("");
|
||||
setNewTaskAgent(null);
|
||||
};
|
||||
|
||||
const handleRemoveTask = (index: number) => {
|
||||
@@ -54,6 +58,8 @@ const MissionTaskEditor: React.FC<MissionTaskEditorProps> = ({
|
||||
onClick={() => handleRemoveTask(index)}
|
||||
className="text-red-500"
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Remove
|
||||
</Button>
|
||||
@@ -73,23 +79,36 @@ const MissionTaskEditor: React.FC<MissionTaskEditorProps> = ({
|
||||
</div>
|
||||
<div className="border border-t-0 border-success-400 rounded-b bg-success-100 px-4 py-3 text-success-700">
|
||||
<div>
|
||||
<label>Task Name: </label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Task Name"
|
||||
<Input
|
||||
label="Task Name"
|
||||
color="green"
|
||||
value={newTaskName}
|
||||
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>
|
||||
<label>Task Description: </label>
|
||||
<br />
|
||||
<textarea
|
||||
placeholder="Task Description"
|
||||
value={newTaskDescription}
|
||||
onChange={(e) => setNewTaskDescription(e.target.value)}
|
||||
className="w-full border border-gray-300 text-black rounded px-3 py-1 ml-2"
|
||||
<Textarea
|
||||
label="Expected Output"
|
||||
color="green"
|
||||
resize={true}
|
||||
value={newTaskExpectedOutput}
|
||||
onChange={(e) => setNewTaskExpectedOutput(e.target.value)}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
/>
|
||||
</div>
|
||||
<div className="m-2">
|
||||
@@ -118,6 +137,8 @@ const MissionTaskEditor: React.FC<MissionTaskEditorProps> = ({
|
||||
disabled={!newTaskName || !newTaskDescription}
|
||||
onClick={handleAddTask}
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Add Task
|
||||
</Button>
|
||||
|
||||
@@ -12,17 +12,16 @@ import {
|
||||
TEModalHeader,
|
||||
TEModalBody,
|
||||
TEModalFooter,
|
||||
TEInput,
|
||||
TETextarea,
|
||||
TESelect,
|
||||
} from "tw-elements-react";
|
||||
import TWFileInput from "../inputs/file";
|
||||
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 withReactContent from "sweetalert2-react-content";
|
||||
import { DELETE_AGENT, UPDATE_AGENT } from "@/utils/graphql_queries";
|
||||
import { useMutation } from "@apollo/client";
|
||||
import Image from "next/image";
|
||||
|
||||
export default function AgentModal(props: {
|
||||
agent: Agent;
|
||||
@@ -164,6 +163,8 @@ export default function AgentModal(props: {
|
||||
<Button
|
||||
onClick={() => setShowModal(false)}
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
<Icon icon="ep:close-bold" width={20} height={20} />
|
||||
</Button>
|
||||
@@ -174,9 +175,10 @@ export default function AgentModal(props: {
|
||||
{isEdit && (
|
||||
<div className="mb-4">
|
||||
<label className="font-bold text-lg">Role:</label>
|
||||
<TEInput
|
||||
type="text"
|
||||
className="mt-2"
|
||||
<Input
|
||||
label="Role"
|
||||
color="blue"
|
||||
className="text-white"
|
||||
value={tempAgent?.role}
|
||||
onChange={(event) => {
|
||||
setTempAgent((prevState) => ({
|
||||
@@ -184,15 +186,19 @@ export default function AgentModal(props: {
|
||||
role: event.target.value,
|
||||
}));
|
||||
}}
|
||||
crossOrigin={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="mb-4">
|
||||
<label className="font-bold text-lg">Goal:</label>
|
||||
{isEdit ? (
|
||||
<TEInput
|
||||
type="text"
|
||||
className="mt-2"
|
||||
<Input
|
||||
label="Goal"
|
||||
color="blue"
|
||||
className="text-white"
|
||||
value={tempAgent?.goal}
|
||||
onChange={(event) => {
|
||||
setTempAgent((prevState) => ({
|
||||
@@ -200,6 +206,9 @@ export default function AgentModal(props: {
|
||||
goal: event.target.value,
|
||||
}));
|
||||
}}
|
||||
crossOrigin={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
/>
|
||||
) : (
|
||||
<div>{agent?.goal}</div>
|
||||
@@ -208,8 +217,11 @@ export default function AgentModal(props: {
|
||||
<div className="mb-4">
|
||||
<label className="font-bold text-lg">Backstory:</label>
|
||||
{isEdit ? (
|
||||
<TETextarea
|
||||
rows={4}
|
||||
<Textarea
|
||||
label="Backstory"
|
||||
color="blue"
|
||||
className="text-white"
|
||||
resize={true}
|
||||
value={tempAgent?.backstory || ""}
|
||||
onChange={(event) => {
|
||||
setTempAgent((prevState) => ({
|
||||
@@ -217,6 +229,8 @@ export default function AgentModal(props: {
|
||||
backstory: event.target.value,
|
||||
}));
|
||||
}}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
/>
|
||||
) : (
|
||||
<div>{agent?.backstory}</div>
|
||||
@@ -263,13 +277,17 @@ export default function AgentModal(props: {
|
||||
allowDelegation: !!event.target.value,
|
||||
}));
|
||||
}}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
/>
|
||||
) : (
|
||||
<Switch
|
||||
crossOrigin={undefined}
|
||||
color="blue"
|
||||
defaultChecked={tempAgent?.allowDelegation}
|
||||
checked={agent?.allowDelegation}
|
||||
disabled={true}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -286,13 +304,44 @@ export default function AgentModal(props: {
|
||||
verbose: !!event.target.value,
|
||||
}));
|
||||
}}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
/>
|
||||
) : (
|
||||
<Switch
|
||||
crossOrigin={undefined}
|
||||
color="blue"
|
||||
defaultChecked={tempAgent?.verbose}
|
||||
checked={agent?.verbose}
|
||||
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>
|
||||
@@ -316,6 +365,8 @@ export default function AgentModal(props: {
|
||||
color="blue"
|
||||
className="mx-auto"
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Upload
|
||||
</Button>
|
||||
@@ -374,6 +425,8 @@ export default function AgentModal(props: {
|
||||
});
|
||||
}}
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
@@ -383,6 +436,8 @@ export default function AgentModal(props: {
|
||||
color="green"
|
||||
onClick={() => setEdit(true)}
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
@@ -396,6 +451,8 @@ export default function AgentModal(props: {
|
||||
color="white"
|
||||
onClick={() => setEdit(false)}
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
@@ -411,6 +468,7 @@ export default function AgentModal(props: {
|
||||
handleUpdateAgent(tempAgent)
|
||||
.then(() => {
|
||||
setShowModal(false);
|
||||
setEdit(false);
|
||||
ReactSwal.fire({
|
||||
title: "Updated",
|
||||
text: "Agent updated successfully",
|
||||
@@ -428,6 +486,8 @@ export default function AgentModal(props: {
|
||||
}}
|
||||
className="mx-1"
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Save Changes
|
||||
</Button>
|
||||
|
||||
@@ -10,14 +10,13 @@ import {
|
||||
TEModalHeader,
|
||||
TEModalBody,
|
||||
TEModalFooter,
|
||||
TEInput,
|
||||
TESelect,
|
||||
} from "tw-elements-react";
|
||||
import { Mission } from "@/types/mission";
|
||||
import MissionTaskEditor from "../inputs/mission_tasks_editor";
|
||||
import { TasksAccordion } from "../ui/tasks_accordions";
|
||||
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 {
|
||||
DELETE_MISSION,
|
||||
@@ -80,6 +79,7 @@ export default function MissionModal(props: {
|
||||
tasks: missionData.tasks.map((task) => ({
|
||||
name: task.name,
|
||||
description: task.description,
|
||||
expected_output: task.expected_output,
|
||||
agent: Number.parseInt(task.agent?.id as string),
|
||||
})),
|
||||
},
|
||||
@@ -130,6 +130,8 @@ export default function MissionModal(props: {
|
||||
<Button
|
||||
onClick={() => setShowModal(false)}
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
<Icon icon="ep:close-bold" width={20} height={20} />
|
||||
</Button>
|
||||
@@ -139,9 +141,10 @@ export default function MissionModal(props: {
|
||||
{isEdit && (
|
||||
<div className="mb-4">
|
||||
<label className="font-bold text-lg">Name:</label>
|
||||
<TEInput
|
||||
type="text"
|
||||
className="mt-2"
|
||||
<Input
|
||||
label="Name"
|
||||
color="blue"
|
||||
className="text-white"
|
||||
value={tempMission?.name}
|
||||
onChange={(event) => {
|
||||
setTempMission((prevState) => ({
|
||||
@@ -149,6 +152,9 @@ export default function MissionModal(props: {
|
||||
name: event.target.value,
|
||||
}));
|
||||
}}
|
||||
crossOrigin={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
@@ -180,6 +186,8 @@ export default function MissionModal(props: {
|
||||
loading={true}
|
||||
placeholder={"Loading"}
|
||||
className="text-white"
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Loading
|
||||
</Button>
|
||||
@@ -241,6 +249,8 @@ export default function MissionModal(props: {
|
||||
verbose: !!event.target.value,
|
||||
}));
|
||||
}}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
/>
|
||||
) : (
|
||||
<Switch
|
||||
@@ -248,6 +258,8 @@ export default function MissionModal(props: {
|
||||
color="blue"
|
||||
checked={mission?.verbose}
|
||||
disabled={true}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -342,6 +354,8 @@ export default function MissionModal(props: {
|
||||
});
|
||||
}}
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
{mission?.result ? "Re-Run" : "Run"}
|
||||
</Button>
|
||||
@@ -351,6 +365,8 @@ export default function MissionModal(props: {
|
||||
loading={true}
|
||||
placeholder={"Running"}
|
||||
className="text-white"
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Running
|
||||
</Button>
|
||||
@@ -358,14 +374,12 @@ export default function MissionModal(props: {
|
||||
</div>
|
||||
<div>
|
||||
<label className="font-bold text-lg">Result:</label>
|
||||
{mission?.result && (
|
||||
<div
|
||||
className="border-2 rounded p-2"
|
||||
style={{ whiteSpace: "pre-line" }}
|
||||
>
|
||||
{missionResult}
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className="border-2 rounded p-2"
|
||||
style={{ whiteSpace: "pre-line" }}
|
||||
>
|
||||
{missionResult}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
@@ -407,6 +421,8 @@ export default function MissionModal(props: {
|
||||
});
|
||||
}}
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
@@ -416,6 +432,8 @@ export default function MissionModal(props: {
|
||||
color="green"
|
||||
onClick={() => setEdit(true)}
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
@@ -429,6 +447,8 @@ export default function MissionModal(props: {
|
||||
color="white"
|
||||
onClick={() => setEdit(false)}
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
@@ -460,6 +480,8 @@ export default function MissionModal(props: {
|
||||
}}
|
||||
className="mx-1"
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Save Changes
|
||||
</Button>
|
||||
|
||||
@@ -4,7 +4,6 @@ import { Agent } from "@/types/agent";
|
||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
TEInput,
|
||||
TEModal,
|
||||
TEModalBody,
|
||||
TEModalContent,
|
||||
@@ -13,9 +12,8 @@ import {
|
||||
TEModalHeader,
|
||||
TERipple,
|
||||
TESelect,
|
||||
TETextarea,
|
||||
} 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 { CREATE_AGENT } from "@/utils/graphql_queries";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
@@ -41,23 +39,6 @@ function NewAgentModal(props: {
|
||||
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 [createAgentLoading, setCreateAgentLoading] = useState(false);
|
||||
|
||||
@@ -86,6 +67,8 @@ function NewAgentModal(props: {
|
||||
<Button
|
||||
onClick={() => setShowModal(false)}
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
<Icon icon="ep:close-bold" width={20} height={20} />
|
||||
</Button>
|
||||
@@ -95,9 +78,10 @@ function NewAgentModal(props: {
|
||||
<div className="sm:w-1/2 mx-auto">
|
||||
<div className="mb-4">
|
||||
<label className="font-bold text-lg">Role:</label>
|
||||
<TEInput
|
||||
type="text"
|
||||
className="mt-2"
|
||||
<Input
|
||||
label="Role"
|
||||
color="blue"
|
||||
className="text-white"
|
||||
value={tempAgent?.role}
|
||||
onChange={(event) => {
|
||||
setTempAgent((prevState) => ({
|
||||
@@ -105,13 +89,17 @@ function NewAgentModal(props: {
|
||||
role: event.target.value,
|
||||
}));
|
||||
}}
|
||||
crossOrigin={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<label className="font-bold text-lg">Goal:</label>
|
||||
<TEInput
|
||||
type="text"
|
||||
className="mt-2"
|
||||
<Input
|
||||
label="Goal"
|
||||
color="blue"
|
||||
className="text-white"
|
||||
value={tempAgent?.goal}
|
||||
onChange={(event) => {
|
||||
setTempAgent((prevState) => ({
|
||||
@@ -119,12 +107,18 @@ function NewAgentModal(props: {
|
||||
goal: event.target.value,
|
||||
}));
|
||||
}}
|
||||
crossOrigin={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<label className="font-bold text-lg">Backstory:</label>
|
||||
<TETextarea
|
||||
rows={4}
|
||||
<Textarea
|
||||
label="Backstory"
|
||||
color="blue"
|
||||
className="text-white"
|
||||
resize={true}
|
||||
value={tempAgent?.backstory || ""}
|
||||
onChange={(event) => {
|
||||
setTempAgent((prevState) => ({
|
||||
@@ -132,6 +126,8 @@ function NewAgentModal(props: {
|
||||
backstory: event.target.value,
|
||||
}));
|
||||
}}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-wrap mb-4">
|
||||
@@ -163,6 +159,8 @@ function NewAgentModal(props: {
|
||||
allowDelegation: !!event.target.value,
|
||||
}));
|
||||
}}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center mb-4">
|
||||
@@ -177,6 +175,24 @@ function NewAgentModal(props: {
|
||||
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>
|
||||
@@ -189,6 +205,8 @@ function NewAgentModal(props: {
|
||||
color="white"
|
||||
onClick={() => setShowModal(false)}
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
@@ -221,6 +239,8 @@ function NewAgentModal(props: {
|
||||
}}
|
||||
className="mx-1"
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Add
|
||||
</Button>
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { Process, selectTheme } from "@/data/consts";
|
||||
import { Mission } from "@/types/mission";
|
||||
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 {
|
||||
TEInput,
|
||||
TEModal,
|
||||
TEModalBody,
|
||||
TEModalContent,
|
||||
@@ -14,7 +13,6 @@ import {
|
||||
TERipple,
|
||||
TESelect,
|
||||
} from "tw-elements-react";
|
||||
import MissionTaskEditor from "../inputs/mission_tasks_editor";
|
||||
import { useMutation, useQuery } from "@apollo/client";
|
||||
import { CREATE_MISSION, GET_AGENTS } from "@/utils/graphql_queries";
|
||||
import { Agent } from "@/types/agent";
|
||||
@@ -79,6 +77,8 @@ function NewMissionModal(props: {
|
||||
<Button
|
||||
onClick={() => setShowModal(false)}
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
<Icon icon="ep:close-bold" width={20} height={20} />
|
||||
</Button>
|
||||
@@ -87,9 +87,10 @@ function NewMissionModal(props: {
|
||||
<div>
|
||||
<div className="mb-4">
|
||||
<label className="font-bold text-lg">Name:</label>
|
||||
<TEInput
|
||||
type="text"
|
||||
className="mt-2"
|
||||
<Input
|
||||
label="Name"
|
||||
color="blue"
|
||||
className="text-white"
|
||||
value={tempMission?.name}
|
||||
onChange={(event) => {
|
||||
setTempMission((prevState) => ({
|
||||
@@ -97,6 +98,9 @@ function NewMissionModal(props: {
|
||||
name: event.target.value,
|
||||
}));
|
||||
}}
|
||||
crossOrigin={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
@@ -126,6 +130,8 @@ function NewMissionModal(props: {
|
||||
loading={true}
|
||||
placeholder={"Loading"}
|
||||
className="text-white"
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Loading
|
||||
</Button>
|
||||
@@ -173,6 +179,8 @@ function NewMissionModal(props: {
|
||||
verbose: !!event.target.value,
|
||||
}));
|
||||
}}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
@@ -205,6 +213,8 @@ function NewMissionModal(props: {
|
||||
color="white"
|
||||
onClick={() => setShowModal(false)}
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
@@ -235,6 +245,8 @@ function NewMissionModal(props: {
|
||||
}}
|
||||
className="mx-1"
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
Add
|
||||
</Button>
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
Accordion,
|
||||
AccordionHeader,
|
||||
AccordionBody,
|
||||
Typography,
|
||||
} from "@material-tailwind/react";
|
||||
import { Task } from "@/types/task";
|
||||
|
||||
@@ -19,11 +20,15 @@ export function TasksAccordion({ tasks }: { tasks: Array<Task> }) {
|
||||
open={open === i}
|
||||
className="mb-2 rounded-lg border border-blue-gray-100 px-4"
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
<AccordionHeader
|
||||
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"}`}
|
||||
placeholder={undefined}
|
||||
onPointerEnterCapture={undefined}
|
||||
onPointerLeaveCapture={undefined}
|
||||
>
|
||||
{task.name}
|
||||
</AccordionHeader>
|
||||
@@ -33,7 +38,34 @@ export function TasksAccordion({ tasks }: { tasks: Array<Task> }) {
|
||||
{task.agent?.role ?? "No Agent"}
|
||||
</span>
|
||||
</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>
|
||||
</Accordion>
|
||||
))}
|
||||
|
||||
@@ -53,6 +53,8 @@ export const tools = [
|
||||
{ text: "WIKIPEDIA", value: "WIKIPEDIA" },
|
||||
{ text: "YAHOO_FINANCE", value: "YAHOO_FINANCE" },
|
||||
{ text: "YUOUTUBE_SEARCH", value: "YUOUTUBE_SEARCH" },
|
||||
{ text: "ARXIV", value: "ARXIV" },
|
||||
{ text: "PUBMED", value: "PUBMED" },
|
||||
];
|
||||
|
||||
const game = `
|
||||
@@ -74,9 +76,9 @@ export const missions: Array<Mission> = [
|
||||
Instructions
|
||||
------------
|
||||
${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],
|
||||
},
|
||||
{
|
||||
@@ -91,9 +93,9 @@ export const missions: Array<Mission> = [
|
||||
Using the code you got, check for errors. Check for logic errors,
|
||||
syntax errors, missing imports, variable declarations, mismatched brackets,
|
||||
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],
|
||||
},
|
||||
{
|
||||
@@ -107,9 +109,9 @@ export const missions: Array<Mission> = [
|
||||
|
||||
You will look over the code to insure that it is complete and
|
||||
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],
|
||||
},
|
||||
],
|
||||
@@ -124,11 +126,13 @@ export const missions: Array<Mission> = [
|
||||
{
|
||||
name: "Task1",
|
||||
description: "description description description description",
|
||||
expected_output: "Expected Output",
|
||||
agent: agents[0],
|
||||
},
|
||||
{
|
||||
name: "Task2",
|
||||
description: "description description description description",
|
||||
expected_output: "Expected Output",
|
||||
},
|
||||
],
|
||||
verbose: true,
|
||||
@@ -142,11 +146,13 @@ export const missions: Array<Mission> = [
|
||||
{
|
||||
name: "Task1",
|
||||
description: "description description description description",
|
||||
expected_output: "Expected Output",
|
||||
agent: agents[0],
|
||||
},
|
||||
{
|
||||
name: "Task2",
|
||||
description: "description description description description",
|
||||
expected_output: "Expected Output",
|
||||
},
|
||||
],
|
||||
verbose: true,
|
||||
|
||||
@@ -4,7 +4,9 @@ type Tool =
|
||||
| "WIKIDATA"
|
||||
| "WIKIPEDIA"
|
||||
| "YAHOO_FINANCE"
|
||||
| "YUOUTUBE_SEARCH";
|
||||
| "YUOUTUBE_SEARCH"
|
||||
| "ARXIV"
|
||||
| "PUBMED";
|
||||
|
||||
export type Agent = {
|
||||
id?: number | string;
|
||||
@@ -14,5 +16,6 @@ export type Agent = {
|
||||
tools: Array<Tool>;
|
||||
allowDelegation: boolean;
|
||||
verbose: boolean;
|
||||
memory?: boolean;
|
||||
image?: string | null;
|
||||
};
|
||||
|
||||
@@ -9,5 +9,6 @@ export type TaskInput = {
|
||||
export type Task = {
|
||||
name: string;
|
||||
description: string;
|
||||
expected_output: string;
|
||||
agent?: Agent | null;
|
||||
};
|
||||
|
||||
@@ -10,6 +10,7 @@ export const GET_AGENTS = gql`
|
||||
tools
|
||||
allowDelegation
|
||||
verbose
|
||||
memory
|
||||
image
|
||||
}
|
||||
}
|
||||
@@ -25,6 +26,7 @@ export const GET_AGENT_BY_ID = gql`
|
||||
tools
|
||||
allowDelegation
|
||||
verbose
|
||||
memory
|
||||
image
|
||||
missions {
|
||||
id
|
||||
@@ -42,6 +44,7 @@ export const CREATE_AGENT = gql`
|
||||
$tools: [AgentTool!]
|
||||
$allowDelegation: Boolean!
|
||||
$verbose: Boolean!
|
||||
$memory: Boolean
|
||||
) {
|
||||
createAgent(
|
||||
role: $role
|
||||
@@ -50,6 +53,7 @@ export const CREATE_AGENT = gql`
|
||||
tools: $tools
|
||||
allowDelegation: $allowDelegation
|
||||
verbose: $verbose
|
||||
memory: $memory
|
||||
) {
|
||||
id
|
||||
role
|
||||
@@ -58,6 +62,7 @@ export const CREATE_AGENT = gql`
|
||||
tools
|
||||
allowDelegation
|
||||
verbose
|
||||
memory
|
||||
image
|
||||
}
|
||||
}
|
||||
@@ -72,6 +77,7 @@ export const UPDATE_AGENT = gql`
|
||||
$tools: [AgentTool!]
|
||||
$allowDelegation: Boolean
|
||||
$verbose: Boolean
|
||||
$memory: Boolean
|
||||
) {
|
||||
updateAgent(
|
||||
id: $id
|
||||
@@ -81,6 +87,7 @@ export const UPDATE_AGENT = gql`
|
||||
tools: $tools
|
||||
allowDelegation: $allowDelegation
|
||||
verbose: $verbose
|
||||
memory: $memory
|
||||
) {
|
||||
id
|
||||
role
|
||||
@@ -89,6 +96,7 @@ export const UPDATE_AGENT = gql`
|
||||
tools
|
||||
allowDelegation
|
||||
verbose
|
||||
memory
|
||||
image
|
||||
}
|
||||
}
|
||||
@@ -115,11 +123,13 @@ export const GET_MISSIONS = gql`
|
||||
tools
|
||||
allowDelegation
|
||||
verbose
|
||||
memory
|
||||
image
|
||||
}
|
||||
tasks {
|
||||
name
|
||||
description
|
||||
expected_output
|
||||
agent {
|
||||
id
|
||||
role
|
||||
@@ -145,11 +155,13 @@ export const GET_MISSION_BY_ID = gql`
|
||||
tools
|
||||
allowDelegation
|
||||
verbose
|
||||
memory
|
||||
image
|
||||
}
|
||||
tasks {
|
||||
name
|
||||
description
|
||||
expected_output
|
||||
agent {
|
||||
id
|
||||
role
|
||||
@@ -166,14 +178,12 @@ export const CREATE_MISSION = gql`
|
||||
mutation CreateMission(
|
||||
$name: String!
|
||||
$crew: [Int!]
|
||||
$tasks: [TaskInput!]
|
||||
$verbose: Boolean
|
||||
$process: MissionProcess
|
||||
) {
|
||||
createMission(
|
||||
name: $name
|
||||
crew: $crew
|
||||
tasks: $tasks
|
||||
verbose: $verbose
|
||||
process: $process
|
||||
) {
|
||||
@@ -187,11 +197,13 @@ export const CREATE_MISSION = gql`
|
||||
tools
|
||||
allowDelegation
|
||||
verbose
|
||||
memory
|
||||
image
|
||||
}
|
||||
tasks {
|
||||
name
|
||||
description
|
||||
expected_output
|
||||
agent {
|
||||
id
|
||||
role
|
||||
@@ -231,11 +243,13 @@ export const UPDATE_MISSION = gql`
|
||||
tools
|
||||
allowDelegation
|
||||
verbose
|
||||
memory
|
||||
image
|
||||
}
|
||||
tasks {
|
||||
name
|
||||
description
|
||||
expected_output
|
||||
agent {
|
||||
id
|
||||
role
|
||||
|
||||
9
start_linux_mac.sh
Normal file
9
start_linux_mac.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Open browser
|
||||
echo "Opening browser..."
|
||||
open http://localhost:3000
|
||||
|
||||
# Run the project
|
||||
echo "Starting development server..."
|
||||
npm run dev
|
||||
10
start_win.bat
Normal file
10
start_win.bat
Normal file
@@ -0,0 +1,10 @@
|
||||
REM Run the project
|
||||
echo Starting development server...
|
||||
start call npm run dev
|
||||
|
||||
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
|
||||
@@ -22,5 +22,5 @@
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "**/*.js", "postcss.config.cjs"],
|
||||
"exclude": ["node_modules"]
|
||||
"exclude": ["node_modules", "venv"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user