Compare commits

...

57 Commits

Author SHA1 Message Date
Aarushi
f2849b4b5b Update rnd/autogpt_builder/src/components/CustomNode.tsx
Co-authored-by: Reinier van der Leer <pwuts@agpt.co>
2024-07-17 10:05:26 +01:00
Nicholas Tindle
1ffa261518 fix(server): setup remove replacement 2024-07-17 02:08:02 -05:00
Nicholas Tindle
189eccb523 Update app.py 2024-07-17 01:52:51 -05:00
Nicholas Tindle
cbb81a359b fix(server): file name 2024-07-17 01:33:33 -05:00
Nicholas Tindle
4565635646 feat(server): try this instead 2024-07-17 01:00:43 -05:00
Nicholas Tindle
7479d18705 fix(server): remove debugpy 2024-07-17 00:39:26 -05:00
Nicholas Tindle
bfb3a45722 feat(server): try replace paths 2024-07-17 00:21:27 -05:00
Nicholas Tindle
68f46c00cd feat(builder, server): code review changes 2024-07-16 22:23:32 -05:00
Nicholas Tindle
72c633241c fix(builder): spacing 2024-07-16 22:20:04 -05:00
Nicholas Tindle
e676124527 fix: spacing 2024-07-16 22:19:27 -05:00
Nicholas Tindle
03df00c4a8 feat(builder): merge continues 2024-07-16 22:16:54 -05:00
Nicholas Tindle
2359a7d109 Merge branch 'master' into aarushikansal/open-1370-serve-frontend-on-server 2024-07-16 22:16:41 -05:00
Nicholas Tindle
a15ad5cf89 feat(server): breakpoints and cx_freeze update 2024-07-16 22:12:26 -05:00
Nicholas Tindle
e7c569668f Update rnd/autogpt_server/setup.py
Co-authored-by: Reinier van der Leer <pwuts@agpt.co>
2024-07-16 10:02:17 -05:00
Nicholas Tindle
dc3a9b402b Merge branch 'aarushikansal/open-1370-serve-frontend-on-server' of https://github.com/Significant-Gravitas/AutoGPT into aarushikansal/open-1370-serve-frontend-on-server 2024-07-16 03:35:53 -05:00
Nicholas Tindle
6b89941e9c Update app.py 2024-07-16 03:35:51 -05:00
Nicholas Tindle
95ccc058d7 Merge branch 'master' into aarushikansal/open-1370-serve-frontend-on-server 2024-07-16 03:33:09 -05:00
Nicholas Tindle
e46cfb1161 Merge branch 'master' into aarushikansal/open-1370-serve-frontend-on-server 2024-07-16 03:30:02 -05:00
Nicholas Tindle
c25f32e389 Merge branch 'aarushikansal/open-1370-serve-frontend-on-server' of https://github.com/Significant-Gravitas/AutoGPT into aarushikansal/open-1370-serve-frontend-on-server 2024-07-16 03:28:47 -05:00
Nicholas Tindle
94e2d0e2d3 Update autogpt-server-ci.yml 2024-07-16 03:28:45 -05:00
Nicholas Tindle
a30b3f7d76 Merge branch 'master' into aarushikansal/open-1370-serve-frontend-on-server 2024-07-16 03:06:37 -05:00
Nicholas Tindle
5617a64598 Update autogpt-server-ci.yml 2024-07-16 03:05:56 -05:00
Nicholas Tindle
20152cf5e0 Update autogpt-server-ci.yml 2024-07-16 03:00:48 -05:00
Nicholas Tindle
01e6fdd925 ci(server): try more envars 2024-07-16 02:40:29 -05:00
Nicholas Tindle
f673f8ae23 fix(server): comment 2024-07-16 02:11:57 -05:00
Nicholas Tindle
5243c9d7fd Update setup.py 2024-07-16 02:11:28 -05:00
Nicholas Tindle
be14969ec7 fix(server): move the prisma fetch to build 2024-07-16 01:59:08 -05:00
Nicholas Tindle
db14af2833 ci(server): make the folder 2024-07-16 01:58:20 -05:00
Nicholas Tindle
8c212e565a ci(server): try and force prisma location 2024-07-16 01:54:35 -05:00
Nicholas Tindle
0716b5967f ci(server): try this instead 2024-07-15 22:46:07 -05:00
Nicholas Tindle
75a5ee8207 ci(server): prisma py fetch suggested after installing from windows 2024-07-15 22:23:16 -05:00
Nicholas Tindle
66384c1795 fix(server): only mount the static files if the _next directory exists 2024-07-15 22:09:51 -05:00
Nicholas Tindle
9be9dbed08 Merge branch 'master' into aarushikansal/open-1370-serve-frontend-on-server 2024-07-15 21:42:23 -05:00
Nicholas Tindle
2a434625ef Merge branch 'master' into aarushikansal/open-1370-serve-frontend-on-server 2024-07-15 17:29:45 -05:00
Nicholas Tindle
483cd07c9e Merge branch 'master' into aarushikansal/open-1370-serve-frontend-on-server 2024-07-15 15:40:28 -05:00
Nicholas Tindle
ab830b5e4c feat(server): more path protections and a warning 2024-07-15 14:16:11 -05:00
Nicholas Tindle
2e6d0944ae Merge branch 'master' into aarushikansal/open-1370-serve-frontend-on-server 2024-07-15 14:01:19 -05:00
Nicholas Tindle
97581a709c fix(builder): typescript linting errors 2024-07-15 14:00:01 -05:00
Nicholas Tindle
9fe1efac68 fix(server): try a different way to specify working directory in a more windows friendly way 2024-07-15 07:24:38 -05:00
Nicholas Tindle
2e3e8ac11e ci(server): correctly specify the npm install location 2024-07-15 07:18:39 -05:00
Nicholas Tindle
2c56b8519f ci(server): correctly build the server when builder changes 2024-07-15 07:12:50 -05:00
Nicholas Tindle
d3c8cf0a57 Merge branch 'master' into aarushikansal/open-1370-serve-frontend-on-server 2024-07-15 06:57:26 -05:00
Aarushi
fad8e30d6e Merge branch 'master' into aarushikansal/open-1370-serve-frontend-on-server 2024-07-14 14:06:04 +01:00
Nicholas Tindle
d06d8a2f2c feat: update gitignore 2024-07-12 13:55:57 -05:00
Nicholas Tindle
42ee23d243 fix: delete all the files in the frontend folder 2024-07-12 13:54:03 -05:00
Nicholas Tindle
a57d27a811 feat(dx): keep the frontend folder 2024-07-12 13:53:13 -05:00
Nicholas Tindle
01cc25bfd2 fix: import order 2024-07-12 13:51:04 -05:00
Nicholas Tindle
50d92d164a fix: move files to frontend 2024-07-12 13:42:58 -05:00
Nicholas Tindle
aedb8d8823 fix: render all assets correctly 2024-07-12 12:23:59 -05:00
Nicholas Tindle
bded7916c2 feat: partial loading of routes and ui files 2024-07-12 00:01:36 -05:00
Nicholas Tindle
b376e84556 feat: partial serving files on built version 2024-07-11 23:25:24 -05:00
Aarushi
2f4fe3311e add static files 2024-07-11 19:15:28 +01:00
Aarushi
741e4db8b1 number issue 2024-07-11 18:45:08 +01:00
Aarushi
5969d4444d fix more issues 2024-07-11 18:40:13 +01:00
Aarushi
76cfeef789 fixed input issue 2024-07-11 17:12:31 +01:00
Aarushi
7337e2fd0d most errors gone, i think 2024-07-11 15:21:09 +01:00
Aarushi
48740d9a3c wip 2024-07-11 12:57:25 +01:00
21 changed files with 953 additions and 737 deletions

View File

@@ -6,11 +6,13 @@ on:
paths:
- ".github/workflows/autogpt-server-ci.yml"
- "rnd/autogpt_server/**"
- "rnd/autogpt_builder/**"
pull_request:
branches: [master, development, release-*]
paths:
- ".github/workflows/autogpt-server-ci.yml"
- "rnd/autogpt_server/**"
- "rnd/autogpt_builder/**"
concurrency:
group: ${{ format('autogpt-server-ci-{0}', github.head_ref && format('{0}-{1}', github.event_name, github.event.pull_request.number) || github.sha) }}
@@ -144,6 +146,17 @@ jobs:
fetch-depth: 0
submodules: true
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '21'
- name: Install dependencies for autogpt_builder
working-directory: rnd/autogpt_builder
run: |
yarn install
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
@@ -183,11 +196,25 @@ jobs:
- name: Install Python dependencies
run: poetry install
- name: Install Prisma Dependencies
run: |
mkdir prisma
poetry run prisma py fetch --force
env:
PRISMA_BINARY_CACHE_DIR: "./prisma"
PRISMA_HOME_DIR: "./prisma"
- name: Generate Prisma Client
run: poetry run prisma generate
env:
PRISMA_BINARY_CACHE_DIR: "./prisma"
PRISMA_HOME_DIR: "./prisma"
- name: Run Database Migrations
run: poetry run prisma migrate dev --name updates
env:
PRISMA_BINARY_CACHE_DIR: "./prisma"
PRISMA_HOME_DIR: "./prisma"
- name: install rpm
if: matrix.platform-os == 'ubuntu'

1
rnd/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
frontend/

View File

@@ -1,3 +1,10 @@
{
"extends": "next/core-web-vitals"
"extends": [
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended"
],
"rules": {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/ban-ts-comment": "off"
}
}

View File

@@ -5,6 +5,7 @@ dotenv.config();
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
env: {
AGPT_SERVER_URL: process.env.AGPT_SERVER_URL,
},
@@ -17,6 +18,12 @@ const nextConfig = {
},
];
},
eslint: {
ignoreDuringBuilds: true,
},
typescript: {
ignoreBuildErrors: true,
},
};
export default nextConfig;

View File

@@ -17,9 +17,9 @@
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"date-fns": "^3.6.0",
"moment": "^2.30.1",
"dotenv": "^16.4.5",
"lucide-react": "^0.407.0",
"moment": "^2.30.1",
"next": "14.2.4",
"next-themes": "^0.3.0",
"react": "^18",
@@ -36,7 +36,9 @@
"@types/react": "^18",
"@types/react-dom": "^18",
"@types/react-modal": "^3.16.3",
"eslint": "^8",
"@typescript-eslint/eslint-plugin": "^7.16.0",
"@typescript-eslint/parser": "^7.16.0",
"eslint": "^8.57.0",
"eslint-config-next": "14.2.4",
"postcss": "^8",
"tailwindcss": "^3.4.1",

View File

@@ -1,43 +1,54 @@
"use client";
import React, { Suspense } from "react";
import Image from "next/image";
import { useSearchParams } from "next/navigation";
import FlowEditor from '@/components/Flow';
export default function Home() {
return (
<div className="flex flex-col items-center px-12">
<div className="z-10 w-full items-center justify-between font-mono text-sm lg:flex">
<p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-600 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-900 dark:bg-zinc-900 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30">
Get started by adding a&nbsp;
<code className="font-mono font-bold">node</code>
</p>
<div
className="fixed bottom-0 left-0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:size-auto lg:bg-none"
>
<a
className="pointer-events-none flex place-items-center gap-2 p-8 lg:pointer-events-auto lg:p-0"
href="https://news.agpt.co/"
target="_blank"
rel="noopener noreferrer"
>
By{" "}
<Image
src="/AUTOgpt_Logo_dark.png"
alt="AutoGPT Logo"
width={100}
height={24}
priority
/>
</a>
</div>
</div>
function FlowEditorWrapper() {
const searchParams = useSearchParams();
const flowID = searchParams.get("flowID") ?? undefined;
<div className="w-full flex justify-center mt-10">
<FlowEditor
className="flow-container w-full min-h-[75vh] border border-gray-300 dark:border-gray-700 rounded-lg"
flowID={useSearchParams().get("flowID") ?? undefined}
/>
</div>
</div>
return (
<FlowEditor
className="flow-container w-full min-h-[75vh] border border-gray-300 dark:border-gray-700 rounded-lg"
flowID={flowID}
/>
);
}
export default function Home() {
return (
<div className="flex flex-col items-center px-12">
<div className="z-10 w-full items-center justify-between font-mono text-sm lg:flex">
<p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-600 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-900 dark:bg-zinc-900 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30">
Get started by adding a&nbsp;
<code className="font-mono font-bold">node</code>
</p>
<div
className="fixed bottom-0 left-0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:size-auto lg:bg-none"
>
<a
className="pointer-events-none flex place-items-center gap-2 p-8 lg:pointer-events-auto lg:p-0"
href="https://news.agpt.co/"
target="_blank"
rel="noopener noreferrer"
>
By{" "}
<Image
src="/AUTOgpt_Logo_dark.png"
alt="AutoGPT Logo"
width={100}
height={24}
priority
/>
</a>
</div>
</div>
<div className="w-full flex justify-center mt-10">
<Suspense fallback={<div>Loading...</div>}>
<FlowEditorWrapper />
</Suspense>
</div>
</div>
);
}

View File

@@ -4,7 +4,7 @@ import { ThemeProvider as NextThemeProvider } from "next-themes";
import { type ThemeProviderProps } from "next-themes/dist/types";
import { Inter } from "next/font/google";
import Link from "next/link";
import { CubeIcon, Pencil1Icon, ReaderIcon, TimerIcon } from "@radix-ui/react-icons";
import { Pencil1Icon, TimerIcon } from "@radix-ui/react-icons";
import "./globals.css";

View File

@@ -266,6 +266,7 @@ const AgentFlowList = (
</Card>
);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const FlowStatusBadge = ({ status }: { status: "active" | "disabled" | "failing" }) => (
<Badge
variant="default"
@@ -538,7 +539,7 @@ const FlowRunsTimeline = (
tickFormatter={s => s > 90 ? `${Math.round(s / 60)}m` : `${s}s`}
/>
<Tooltip
content={({ payload, label }) => {
content={({ payload }) => {
if (payload && payload.length) {
const data: FlowRun & { time: number, _duration: number } = payload[0].payload;
const flow = flows.find(f => f.id === data.flowID);

View File

@@ -116,6 +116,16 @@ const CustomNode: FC<NodeProps<CustomNodeData>> = ({ data, id }) => {
setErrors((prevErrors) => ({ ...prevErrors, [key]: null }));
};
const getSelectValue = (value: any): string => {
if (typeof value === 'string') return value;
if (typeof value === 'number') return value.toString();
if (Array.isArray(value)) return value.join(',');
if (typeof value === 'object' && value !== null) {
return JSON.stringify(value);
}
return '';
};
const getValue = (key: string) => {
const keys = key.split('.');
return keys.reduce((acc, k) => (acc && acc[k] !== undefined) ? acc[k] : '', data.hardcodedValues);
@@ -124,7 +134,7 @@ const CustomNode: FC<NodeProps<CustomNodeData>> = ({ data, id }) => {
const isHandleConnected = (key: string) => {
return data.connections && data.connections.some((conn: any) => {
if (typeof conn === 'string') {
const [source, target] = conn.split(' -> ');
const [ target ] = conn.split(' -> ');
return target.includes(key) && target.includes(data.title);
}
return conn.target === id && conn.targetHandle === key;
@@ -300,7 +310,7 @@ const CustomNode: FC<NodeProps<CustomNodeData>> = ({ data, id }) => {
return schema.enum ? (
<div key={fullKey} className="input-container">
<select
value={value || ''}
value={getSelectValue(value)}
onChange={(e) => handleInputChange(fullKey, e.target.value)}
className="select-input"
>
@@ -340,7 +350,7 @@ const CustomNode: FC<NodeProps<CustomNodeData>> = ({ data, id }) => {
<div key={fullKey} className="input-container">
<input
type="number"
value={value || ''}
value={["number", "string"].includes(typeof value) ? value : ''}
onChange={(e) => handleInputChange(fullKey, parseFloat(e.target.value))}
className="number-input"
/>
@@ -349,7 +359,7 @@ const CustomNode: FC<NodeProps<CustomNodeData>> = ({ data, id }) => {
);
case 'array':
if (schema.items && schema.items.type === 'string') {
const arrayValues = value || [];
const arrayValues = Array.isArray(value) ? value : [];
return (
<div key={fullKey} className="input-container">
{arrayValues.map((item: string, index: number) => (
@@ -360,7 +370,11 @@ const CustomNode: FC<NodeProps<CustomNodeData>> = ({ data, id }) => {
onChange={(e) => handleInputChange(`${fullKey}.${index}`, e.target.value)}
className="array-item-input"
/>
<Button onClick={() => handleInputChange(`${fullKey}.${index}`, '')} className="array-item-remove">
<Button onClick={() => {
const newArray = [...arrayValues];
newArray.splice(index, 1);
handleInputChange(fullKey, newArray);
}} className="array-item-remove">
&times;
</Button>
</div>
@@ -372,7 +386,7 @@ const CustomNode: FC<NodeProps<CustomNodeData>> = ({ data, id }) => {
</div>
);
}
return null;
return <div key={fullKey}></div>;
default:
return (
<div key={fullKey} className="input-container">
@@ -383,28 +397,6 @@ const CustomNode: FC<NodeProps<CustomNodeData>> = ({ data, id }) => {
}
};
const validateInputs = () => {
const newErrors: { [key: string]: string | null } = {};
const validateRecursive = (schema: any, parentKey: string = '') => {
Object.entries(schema.properties).forEach(([key, propSchema]: [string, any]) => {
const fullKey = parentKey ? `${parentKey}.${key}` : key;
const value = getValue(fullKey);
if (propSchema.type === 'object' && propSchema.properties) {
validateRecursive(propSchema, fullKey);
} else {
if (propSchema.required && !value) {
newErrors[fullKey] = `${fullKey} is required`;
}
}
});
};
validateRecursive(data.inputSchema);
setErrors(newErrors);
return Object.values(newErrors).every((error) => error === null);
};
return (
<div className={`custom-node dark-theme ${data.status === 'RUNNING' ? 'running' : data.status === 'COMPLETED' ? 'completed' : data.status === 'FAILED' ? 'failed' :''}`}>
<div className="node-header">

View File

@@ -1,3 +1,4 @@
// @ts-nocheck
"use client";
import React, { useState, useCallback, useEffect, useMemo } from 'react';
import ReactFlow, {
@@ -129,6 +130,7 @@ const FlowEditor: React.FC<{ flowID?: string; className?: string }> = ({
const onConnect: OnConnect = useCallback(
(connection: Connection) => {
setEdges((eds) => addEdge(connection, eds));
setNodes((nds) =>
nds.map((node) => {
if (node.id === connection.target) {
@@ -253,6 +255,7 @@ const FlowEditor: React.FC<{ flowID?: string; className?: string }> = ({
})));
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const prepareNodeInputData = (node: Node<CustomNodeData>, allNodes: Node<CustomNodeData>[], allEdges: Edge[]) => {
console.log("Preparing input data for node:", node.id, node.data.blockType);
@@ -285,7 +288,7 @@ const FlowEditor: React.FC<{ flowID?: string; className?: string }> = ({
return inputData;
};
let inputData = getNestedData(blockSchema, node.data.hardcodedValues);
const inputData = getNestedData(blockSchema, node.data.hardcodedValues);
console.log(`Final prepared input for ${node.data.blockType} (${node.id}):`, inputData);
return inputData;

View File

@@ -60,8 +60,8 @@ function Calendar({
...classNames,
}}
components={{
IconLeft: ({ ...props }) => <ChevronLeftIcon className="h-4 w-4" />,
IconRight: ({ ...props }) => <ChevronRightIcon className="h-4 w-4" />,
IconLeft: () => <ChevronLeftIcon className="h-4 w-4" />,
IconRight: () => <ChevronRightIcon className="h-4 w-4" />,
}}
{...props}
/>

View File

@@ -1,13 +1,19 @@
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"target": "esnext",
"module": "esnext",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
@@ -21,6 +27,13 @@
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,11 @@
from multiprocessing import freeze_support, set_start_method
import pathlib
import shutil
import sys
from autogpt_server.executor import ExecutionManager, ExecutionScheduler
from autogpt_server.server import AgentServer
from autogpt_server.util.data import get_prisma_exe_path
from autogpt_server.util.process import AppProcess
from autogpt_server.util.service import PyroNameServer
@@ -31,6 +36,17 @@ def main(**kwargs):
set_start_method("spawn", force=True)
freeze_support()
# if frozen on windows
# if getattr(sys, "frozen", False) and sys.platform == "win32":
# # The application is frozen
# # copy the prisma exe from get_prisma_exe to user directory
# query_file_location = get_prisma_exe_path()
# # copy the prisma exe to the windows user directory
# query_file_location_user = (
# pathlib.Path.home() / "prisma-query-engine-windows.exe"
# )
# shutil.copyfile(query_file_location, query_file_location_user)
run_processes(
[
PyroNameServer(),

View File

@@ -1,8 +1,12 @@
import asyncio
import mimetypes
import os
import uuid
from contextlib import asynccontextmanager
from typing import Annotated, Any, Dict
from typing import Annotated, Any, Dict, MutableMapping
from starlette.responses import Response
from starlette.exceptions import HTTPException as StarletteHTTPException
import uvicorn
from fastapi import (
APIRouter,
@@ -13,7 +17,7 @@ from fastapi import (
WebSocketDisconnect,
)
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from fastapi.responses import FileResponse, HTMLResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
import autogpt_server.server.ws_api
@@ -178,20 +182,63 @@ class AgentServer(AppService):
methods=["POST"],
)
app.add_exception_handler(500, self.handle_internal_error) # type: ignore
app.add_exception_handler(500, self.handle_internal_error)
app.mount(
path="/frontend",
app=StaticFiles(directory=get_frontend_path(), html=True),
name="example_files",
)
class SPAStaticFiles(StaticFiles):
async def get_response(
self, path: str, scope: MutableMapping[str, Any]
) -> Response:
try:
return await super().get_response(path, scope)
except (HTTPException, StarletteHTTPException) as ex:
if ex.status_code == 404:
return await super().get_response("build.html", scope)
else:
raise ex
app.include_router(router)
#! WARNING: THE ORDER OF THE REST OF THESE FUNCTIONS IS IMPORTANT
#! DO NOT CHANGE THE ORDER OF THESE FUNCTIONS
#! DO NOT ADD ANY FUNCTIONS BETWEEN THESE FUNCTIONS
#! DO NOT REMOVE ANY OF THESE FUNCTIONS
#! YOU WILL BREAK THE FRONTEND PACKAGED WITH THE SERVER
if os.path.exists(get_frontend_path() / "_next"):
app.mount(
path="/_next",
app=SPAStaticFiles(directory=get_frontend_path() / "_next", html=True),
name="frontend",
)
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket): # type: ignore
await self.websocket_router(websocket)
@app.get("/{extras_file:str}", response_class=HTMLResponse)
async def catch_others(extras_file: str):
# Do not allow directory traversal
if ".." in extras_file:
raise HTTPException(status_code=400, detail="Invalid file path")
if extras_file.count(".") > 1:
raise HTTPException(status_code=400, detail="Invalid file path")
# check if the file is directly in the frontend path folder to further prevent directory traversal against the allowed files
files = os.listdir(get_frontend_path())
# detect the file type and return the appropriate response
if extras_file in files:
mime = mimetypes.guess_type(extras_file)[0]
if mime is not None and mime.startswith("image"):
return FileResponse(get_frontend_path() / extras_file)
else:
with open(get_frontend_path() / extras_file) as file:
return str(file.read())
raise HTTPException(status_code=400, detail="Invalid file path")
@app.get("/", response_class=HTMLResponse)
async def catch_root():
with open(get_frontend_path() / "build.html") as file:
return str(file.read())
uvicorn.run(app, host="0.0.0.0", port=8000)
@property

View File

@@ -14,15 +14,30 @@ def get_config_path() -> pathlib.Path:
def get_frontend_path() -> pathlib.Path:
if getattr(sys, "frozen", False):
# The application is frozen
datadir = pathlib.Path(os.path.dirname(sys.executable)) / "example_files"
datadir = pathlib.Path(os.path.dirname(sys.executable)) / "frontend"
else:
# The application is not frozen
# Change this bit to match where you store your data files:
filedir = os.path.dirname(__file__)
datadir = pathlib.Path(filedir).parent.parent.parent / "example_files"
datadir = pathlib.Path(filedir).parent.parent.parent / "frontend"
return pathlib.Path(datadir)
def get_prisma_path() -> pathlib.Path:
return get_data_path() / "prisma"
def get_prisma_exe_path() -> pathlib.Path:
if sys.platform == "win32":
return (
get_prisma_path() / "node_modules" / "prisma" / "query-engine-windows.exe"
)
else:
raise NotImplementedError(
"Freezing AutoGPT Server is only supported on Windows at the moment."
)
def get_data_path() -> pathlib.Path:
if getattr(sys, "frozen", False):
# The application is frozen

View File

@@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
[[package]]
name = "agpt"
@@ -25,7 +25,7 @@ requests = "*"
sentry-sdk = "^1.40.4"
[package.extras]
benchmark = ["agbenchmark @ file:///Users/majdyz/Code/AutoGPT/benchmark"]
benchmark = ["agbenchmark"]
[package.source]
type = "directory"
@@ -329,7 +329,7 @@ watchdog = "4.0.0"
webdriver-manager = "^4.0.1"
[package.extras]
benchmark = ["agbenchmark @ file:///Users/majdyz/Code/AutoGPT/benchmark"]
benchmark = ["agbenchmark"]
[package.source]
type = "directory"
@@ -883,33 +883,69 @@ python-dateutil = "*"
pytz = ">2021.1"
[[package]]
name = "cx_Freeze"
version = "7.1.1"
name = "cx-freeze"
version = "7.2.0"
description = "Create standalone executables from Python scripts"
optional = false
python-versions = ">=3.8"
files = []
develop = true
files = [
{file = "cx_Freeze-7.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f843263c0faab92f71a5650f9676806378b0d2cfe5902cb2cefb3dce20a275ac"},
{file = "cx_Freeze-7.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37df5c5184bde8a7512e08bb0c6ee72b7d26b7a72fdb71454d63530ea440ab84"},
{file = "cx_Freeze-7.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa95b50e3746cb534a53023e3b7393b6b39ab039885302dcaeab4245066656b5"},
{file = "cx_Freeze-7.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3fcb9fb7016b28a969952761ed2ed730a8001941e29757379cc386f080bbe055"},
{file = "cx_Freeze-7.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1c9d67de843ba748f2e52a5cf44f9f943e15ad8ec3bb590f767613b20ac24882"},
{file = "cx_Freeze-7.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:11b86b7e5f307e67a76a8f164b9b8b0a3745418b495e6f59abd0fdfeaab206f7"},
{file = "cx_Freeze-7.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9fbd82cdd0739daf9009c5ba0110f758f586391a00a624db94f81f3531178ea5"},
{file = "cx_Freeze-7.2.0-cp310-cp310-win32.whl", hash = "sha256:ecea5246805c063a1d782e446c811a3c517918770fa04678637dc0f356449489"},
{file = "cx_Freeze-7.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:ac48fe678f69b965b10c5f880609e0ec738777c109d45d77e139c76385ac4404"},
{file = "cx_Freeze-7.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0d518c75880a517b04a82258d935b9408874d7b27f6d8d20dc4d8818395d02e"},
{file = "cx_Freeze-7.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8437c18a129b0cf875f68697a56cd86c69698e6790a5d2c61f8b970bc512128b"},
{file = "cx_Freeze-7.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dbd24c7f0f402c62bed9cfbf6e7dd7d65ef2a011d2576404d9cf2d2c113c1e48"},
{file = "cx_Freeze-7.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e04a06dc36bfd38088879f5faab7de15c99f3daada524b8a816addb203ec9464"},
{file = "cx_Freeze-7.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:620635e86ef46872763be8b65b7c06f5f24943151e80013e3a37f312fe070895"},
{file = "cx_Freeze-7.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e84fb083182bcaab226b7a75d2069cefcf3e3181142b09b514d99a5ae4860c8"},
{file = "cx_Freeze-7.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dd175db3069991b60a792ee17a2e2e4853bfbcfc0b1be976ebee04ed1098c101"},
{file = "cx_Freeze-7.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4030de54f227b5852155d86fc00f86a19e87d0470aa650ec4ddd06b06f270ceb"},
{file = "cx_Freeze-7.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:60eba74abdb2211b38263797342e95732ec96621a781b02e5ff909cdc9cf5be5"},
{file = "cx_Freeze-7.2.0-cp311-cp311-win32.whl", hash = "sha256:d727df584a9b1548dbc478f036382b8cde94471e106d38fb9c45b238bf8af4d1"},
{file = "cx_Freeze-7.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:bb6d91342f7379ba76d8a07c263d1fba380f0044b13d3e4629e50cc8dd19b681"},
{file = "cx_Freeze-7.2.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f7cf98f63c85fc2f947a7f68548136d60dfd7927a464d1cd38239a75b730f7f7"},
{file = "cx_Freeze-7.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:7f988be0ad19be0df357102fae21553f36cc4f83b4e881888e3512d1a2bcb8ba"},
{file = "cx_Freeze-7.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:98491338f6dcf52f8ee4d872d08aeae0c91466a47383ad19d1332a565f7c4df8"},
{file = "cx_Freeze-7.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51a2f286ff58e04510b6af87c055b6fca36045a0fb785cd966f38aa70f86c3ce"},
{file = "cx_Freeze-7.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43e6c1ccaf9be9010a0e8a8c33edc7671dd0a6f8c49ab2bcd9f49ce0960089e0"},
{file = "cx_Freeze-7.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64c3f734cff3620d5ecc474d59a753cae52ba96b52e0a9ade803a70699be1bc1"},
{file = "cx_Freeze-7.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d68f2ec4c0c456c6f1ca5e623f240f27fb63ae65970a16e04689863b03a16c7e"},
{file = "cx_Freeze-7.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:77e2362f075b242a99e041afb9a49693a60c102b9b1df67f6387c87fde02e34f"},
{file = "cx_Freeze-7.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a51b97024401d5cfaa392caef8b150bf91e62c0fdcb6a68372959c6ff28349d3"},
{file = "cx_Freeze-7.2.0-cp312-cp312-win32.whl", hash = "sha256:19fb97c8481266931c5fd5cc380b12fb09053258413ebaf6760d5063e5ffde41"},
{file = "cx_Freeze-7.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:e61692176a8803e0853ca115cede397942c1cee9e20c8eb5798613d0b92dd75d"},
{file = "cx_Freeze-7.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5ed93d21a7962cc2886fb6e9e7d53fec67d6da02ff8088c9007a03835adc0240"},
{file = "cx_Freeze-7.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b00302fc33f279f7dbca764bdb60247d609e3b424ff31198512c6eeb8cdda17b"},
{file = "cx_Freeze-7.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:e97745e663450871736f06321fc732b440628cff397f8ddbef05ffbc355b2f5d"},
{file = "cx_Freeze-7.2.0-cp38-cp38-win32.whl", hash = "sha256:b7a0c2cced3fa9cf3b0cb4b67064b3ed2db1edec3186d75270ee0c01ed31cf54"},
{file = "cx_Freeze-7.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:96046d864e03d4241e869fa5e3ae186be1fbdc170d77125fe36185c7a0108f6f"},
{file = "cx_Freeze-7.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:36285f3367f4d220632c572f37140bdacb2020bdf7b166ee707e3e2351338955"},
{file = "cx_Freeze-7.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:717915dfa25730b57166b25d392c83d41e3f655c8996d473ba0368aec2a9d262"},
{file = "cx_Freeze-7.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:afc91a24eccfe14f1853c93e78656772710ed754f7cc5ecb9761b6250a540848"},
{file = "cx_Freeze-7.2.0-cp39-cp39-win32.whl", hash = "sha256:166b93473e86b926db7ab26e7d83504e8330df07af44cc090ebcad40e3158417"},
{file = "cx_Freeze-7.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:4a91284a925df800e0dbb324c51ab4fd7bd0ea708f280d94a2a10cf564c28cbe"},
{file = "cx_freeze-7.2.0.tar.gz", hash = "sha256:c57f7101b4d35132464b1ec88cb8948c3b7c5b4ece4bb354c16091589cb33583"},
]
[package.dependencies]
cx_Logging = {version = ">=3.1", markers = "sys_platform == \"win32\""}
cx-Logging = {version = ">=3.1", markers = "sys_platform == \"win32\""}
dmgbuild = {version = ">=1.6.1", markers = "sys_platform == \"darwin\""}
filelock = {version = ">=3.12.3", markers = "sys_platform == \"linux\""}
lief = {version = ">=0.12.0,<0.15.0", markers = "sys_platform == \"win32\""}
patchelf = {version = ">=0.14", markers = "sys_platform == \"linux\" and (platform_machine == \"x86_64\" or platform_machine == \"i686\" or platform_machine == \"aarch64\" or platform_machine == \"armv7l\" or platform_machine == \"ppc64le\" or platform_machine == \"s390x\")"}
patchelf = {version = ">=0.14", markers = "sys_platform == \"linux\" and (platform_machine == \"aarch64\" or platform_machine == \"armv7l\" or platform_machine == \"i686\" or platform_machine == \"ppc64le\" or platform_machine == \"s390x\" or platform_machine == \"x86_64\")"}
setuptools = ">=65.6.3,<71"
wheel = ">=0.42.0,<=0.43.0"
[package.extras]
dev = ["bump-my-version (==0.24.0)", "cibuildwheel (==2.19.1)", "pre-commit (==3.5.0)", "pre-commit (==3.7.1)"]
doc = ["furo (==2024.5.6)", "myst-parser (==3.0.1)", "sphinx (==7.3.7)", "sphinx-new-tab-link (==0.4.0)", "sphinx-tabs (==3.4.5)"]
test = ["coverage (==7.5.4)", "pluggy (==1.5.0)", "pytest (==8.2.2)", "pytest-cov (==5.0.0)", "pytest-datafiles (==3.0.0)", "pytest-mock (==3.14.0)", "pytest-timeout (==2.3.1)", "pytest-xdist[psutil] (==3.6.1)"]
[package.source]
type = "git"
url = "https://github.com/ntindle/cx_Freeze.git"
reference = "main"
resolved_reference = "876fe77c97db749b7b0aed93c12142a7226ee7e4"
dev = ["bump-my-version (==0.24.2)", "cibuildwheel (==2.19.2)", "pre-commit (==3.5.0)", "pre-commit (==3.7.1)"]
doc = ["furo (==2024.5.6)", "myst-parser (==3.0.1)", "sphinx (==7.3.7)", "sphinx-new-tab-link (==0.5.0)", "sphinx-tabs (==3.4.5)"]
test = ["coverage (==7.6.0)", "pluggy (==1.5.0)", "pytest (==8.2.2)", "pytest-cov (==5.0.0)", "pytest-datafiles (==3.0.0)", "pytest-mock (==3.14.0)", "pytest-timeout (==2.3.1)", "pytest-xdist[psutil] (==3.6.1)"]
[[package]]
name = "cx-logging"
@@ -6218,4 +6254,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools",
[metadata]
lock-version = "2.0"
python-versions = "^3.10"
content-hash = "ac40cb89830fcc95bec5c0dfb0646503dd9bd3abc26b7258ed69403fd546bed5"
content-hash = "d229f380acc15c3685140f45b47c7c94e77efa86394fe8d9d04be0d30f89cdb2"

View File

@@ -37,11 +37,11 @@ anthropic = "^0.25.1"
[tool.poetry.group.dev.dependencies]
cx-freeze = { git = "https://github.com/ntindle/cx_Freeze.git", rev = "main", develop = true }
poethepoet = "^0.26.1"
httpx = "^0.27.0"
pytest-watcher = "^0.4.2"
requests = "^2.32.3"
cx-freeze = "^7.2.0"
[build-system]
requires = ["poetry-core"]

View File

@@ -2,9 +2,13 @@ import platform
from pathlib import Path
from pkgutil import iter_modules
from typing import Union
import shutil
import os
from cx_Freeze import Executable, setup # type: ignore
GUID = "{323a1ee5-317d-4423-8490-effd8f5bedff}"
packages = [
m.name
for m in iter_modules()
@@ -57,6 +61,22 @@ def txt_to_rtf(input_file: Union[str, Path], output_file: Union[str, Path]) -> N
license_file = "LICENSE.rtf"
txt_to_rtf("../../LICENSE", license_file)
# call npm run build in ../autogpt_builder
os.system("npm run build --prefix ../autogpt_builder")
# copy the ../autogpt_builder/out to frontend
shutil.rmtree("../frontend", ignore_errors=True)
shutil.copytree("../autogpt_builder/out", "../frontend")
include_files = [ # source, destination in the bundle
("../frontend", "frontend"),
("./secrets", "secrets"),
]
# add the prisma directory if it exists
if os.path.exists("./prisma"):
include_files.append(("./prisma", "prisma"))
setup(
name="AutoGPT Server",
url="https://agpt.co",
@@ -85,11 +105,13 @@ setup(
],
# Exclude the two module from readability.compat as it causes issues
"excludes": ["readability.compat.two"],
"include_files": [
# source, destination in the bundle
# (../frontend, example_files) would also work but you'd need to load the frontend differently in the data.py to correctly get the path when frozen
("../example_files", "example_files"),
],
"include_files": include_files,
# "replace_paths": [
# (
# "D:\a\\AutoGPT\\AutoGPT\rnd\autogpt_server\\",
# "%AppData%\\..\\Local\\Programs\\AutoGPTServer\\",
# ),
# ],
},
# Mac .app specific options
"bdist_mac": {
@@ -101,7 +123,6 @@ setup(
"applications_shortcut": True,
"volume_label": "AutoGPTServer",
"background": "builtin-arrow",
"license": {
"default-language": "en_US",
"licenses": {"en_US": license_file},
@@ -123,6 +144,7 @@ setup(
"add_to_path": True,
"install_icon": "../../assets/gpt_dark_RGB.ico",
"license_file": license_file,
"upgrade_code": GUID,
},
# Linux .appimage specific options
"bdist_appimage": {},

View File

@@ -1,19 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Example Files</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1>Example Files</h1>
<ul>
<li><a href="example1.txt">Example 1</a></li>
<li><a href="example2.txt">Example 2</a></li>
<li><a href="example3.txt">Example 3</a></li>
</ul>
</body>
</html>

1
rnd/frontend/.gitkeep Normal file
View File

@@ -0,0 +1 @@
# Copy your frontend builds here manually if you'd like to test the serving capabilities of the fast api server\