Skip to content

Commit 4d8d850

Browse files
author
root
committed
events working, prompt appearing on shell
1 parent 0b6163b commit 4d8d850

File tree

21 files changed

+57
-124
lines changed

21 files changed

+57
-124
lines changed

gpt_engineer/applications/w3s/server.py

+15-13
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,18 @@
33
# * @zdanl here modiyfing @atheorell work from websockets to socket.io
44

55
from aiohttp import web
6-
import aiohttp_cors
76
import socketio
87
import tempfile
98
import json
9+
import os
1010

1111
from gpt_engineer.core.default.lean_agent import LeanAgent
12-
from gpt_engineer.core.preprompt_holder import PrepromptHolder
1312

14-
sio = socketio.AsyncServer(cors_allowed_origins="*")
13+
# from gpt_engineer.core.preprompt_holder import PrepromptHolder
14+
15+
sio = socketio.AsyncServer(async_mode="aiohttp", cors_allowed_origins="*")
16+
# sio.set('transports', ['websocket']);
17+
1518
app = web.Application()
1619
sio.attach(app)
1720

@@ -20,22 +23,21 @@
2023

2124

2225
class GPTEngineerNamespace(socketio.AsyncNamespace):
23-
def on_connect(self, sid, environ):
26+
async def on_connect(self, sid, environ):
2427
print("Real-time socket to browser established.")
28+
await self.emit("openai_api_key", os.environ["OPENAI_API_KEY"])
2529

2630
def on_disconnect(self, sid):
2731
print("Browser disconnected.")
2832

29-
def on_my_event(self, sid, data):
30-
self.emit("my_response", data)
31-
32-
def on_gp4_apikey(self, sid, data):
33+
async def on_openai_api_key(self, sid, data):
34+
print(f"Received new OpenAI API Key: {data}")
3335
code = agent.seed(data)
3436

35-
async def on_init(event, sid, data):
36-
print(f"{event}: {data}")
37-
code = agent.init(event["prompt"])
38-
await socketio.emit("prompt", {"payload": json.dumps(code)})
37+
async def on_init(self, sid, prompt):
38+
print(f"Initializing: {prompt}")
39+
code = agent.init(prompt)
40+
await self.emit("init", {"payload": json.dumps(code)})
3941

4042
async def on_improve(event, sid, data):
4143
print(f"{event}: {data}")
@@ -52,7 +54,7 @@ async def on_execute(event, sid, data):
5254
await socketio.emit("execute", {"payload": payload})
5355

5456

55-
sio.register_namespace(GPTEngineerNamespace("/gptengineer"))
57+
sio.register_namespace(GPTEngineerNamespace("/gpt-engineer"))
5658

5759

5860
async def main():

gpt_engineer/core/default/lean_agent.py

+4
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ def init(self, prompt: str) -> Code:
5858
self.execution_env.execute_program(code)
5959
return code
6060

61+
def seed(self, api_key: str) -> bool:
62+
# Overwrite API Key
63+
return True
64+
6165
def improve(
6266
self, code: Code, prompt: str, execution_command: str = ENTRYPOINT_FILE
6367
) -> Code:

webapp/pages/_app.tsx

+10-1
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,22 @@ function App({ Component, pageProps }: AppProps<{}>) {
5151
setGPTEvents((previous) => [...previous, value]);
5252
}
5353

54+
function onAPIKey(key: string) {
55+
console.log(`API Key received ${key}`);
56+
localStorage.setItem("apiKey", key);
57+
setApiKey(key);
58+
}
59+
5460
socket.on("connect", onConnect);
5561
socket.on("disconnect", onDisconnect);
5662
socket.on("event", onGPTEvent);
63+
socket.on("openai_api_key", onAPIKey);
5764

5865
return () => {
5966
socket.off("connect", onConnect);
6067
socket.off("disconnect", onDisconnect);
6168
socket.off("event", onGPTEvent);
69+
socket.off("openai_api_key", onAPIKey);
6270
};
6371
}, [apiKey]);
6472

@@ -69,7 +77,7 @@ function App({ Component, pageProps }: AppProps<{}>) {
6977
<ConnectionManager />
7078
<ChakraProvider theme={theme}>
7179
<Box>
72-
<Sidebar setApiKey={setApiKey} routes={routes} />
80+
<Sidebar apiKey={apiKey} setApiKey={setApiKey} routes={routes} />
7381
<Box
7482
pt={{ base: "60px", md: "100px" }}
7583
float="right"
@@ -89,6 +97,7 @@ function App({ Component, pageProps }: AppProps<{}>) {
8997
<Box>
9098
<Navbar
9199
setApiKey={setApiKey}
100+
apiKey={apiKey}
92101
onOpen={onOpen}
93102
logoText={"GPT-Engineer"}
94103
brandText={getActiveRoute(routes, pathname)}

webapp/pages/index.tsx

+5-52
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import Link from '@/components/link/Link';
55
import MessageBoxChat from '@/components/MessageBox';
66
import { ChatBody, OpenAIModel } from '@/types/types';
7+
import { socket } from "@/socket";
78
import {
89
Accordion,
910
AccordionButton,
@@ -27,6 +28,9 @@ import Bg from '../public/img/chat/bg-image.png';
2728
export default function Chat(props: { apiKeyApp: string }) {
2829
// *** If you use .env.local variable for your API key, method which we recommend, use the apiKey variable commented below
2930
const { apiKeyApp } = props;
31+
32+
socket.on("init", (value: string) => { setOutputCode(value) });
33+
3034
// Input States
3135
const [inputOnSubmit, setInputOnSubmit] = useState<string>('');
3236
const [inputCode, setInputCode] = useState<string>('');
@@ -75,61 +79,10 @@ export default function Chat(props: { apiKeyApp: string }) {
7579
return;
7680
}
7781

78-
if (inputCode.length > maxCodeLength) {
79-
alert(
80-
`Please enter code less than ${maxCodeLength} characters. You are currently at ${inputCode.length} characters.`,
81-
);
82-
return;
83-
}
8482
setOutputCode(' ');
8583
setLoading(true);
8684
const controller = new AbortController();
87-
const body: ChatBody = {
88-
inputCode,
89-
model,
90-
apiKey,
91-
};
92-
93-
// -------------- Fetch --------------
94-
const response = await fetch('/api/chatAPI', {
95-
method: 'POST',
96-
headers: {
97-
'Content-Type': 'application/json',
98-
},
99-
signal: controller.signal,
100-
body: JSON.stringify(body),
101-
});
102-
103-
if (!response.ok) {
104-
setLoading(false);
105-
if (response) {
106-
alert(
107-
'Something went wrong went fetching from the API. Make sure to use a valid API key.',
108-
);
109-
}
110-
return;
111-
}
112-
113-
const data = response.body;
114-
115-
if (!data) {
116-
setLoading(false);
117-
alert('Something went wrong');
118-
return;
119-
}
120-
121-
const reader = data.getReader();
122-
const decoder = new TextDecoder();
123-
let done = false;
124-
125-
while (!done) {
126-
setLoading(true);
127-
const { value, done: doneReading } = await reader.read();
128-
done = doneReading;
129-
const chunkValue = decoder.decode(value);
130-
setOutputCode((prevCode) => prevCode + chunkValue);
131-
}
132-
85+
socket.emit('init', inputCode);
13386
setLoading(false);
13487
};
13588
// -------------- Copy Response --------------

webapp/public/img/avatars/avatar1.png

-66.1 KB
Binary file not shown.
-72.5 KB
Binary file not shown.

webapp/public/img/avatars/avatar2.png

-81.6 KB
Binary file not shown.

webapp/public/img/avatars/avatar3.png

-68.7 KB
Binary file not shown.

webapp/public/img/avatars/avatar4.png

-51.6 KB
Binary file not shown.

webapp/public/img/avatars/avatar5.png

-62.1 KB
Binary file not shown.

webapp/public/img/avatars/avatar6.png

-66.5 KB
Binary file not shown.

webapp/public/img/avatars/avatar7.png

-73.4 KB
Binary file not shown.

webapp/public/img/avatars/avatar8.png

-56.9 KB
Binary file not shown.

webapp/public/img/avatars/avatar9.png

-77.5 KB
Binary file not shown.
-13.4 KB
Binary file not shown.

webapp/src/components/apiModal/index.tsx

+11-8
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ import {
2727
} from '@chakra-ui/react';
2828
import { useState } from 'react';
2929
import { MdLock } from 'react-icons/md';
30+
import { socket } from "@/socket";
3031

31-
function APIModal(props: { setApiKey: any; sidebar?: boolean }) {
32-
const { setApiKey, sidebar } = props;
32+
function APIModal(props: { apiKey: string; setApiKey: any; sidebar?: boolean }) {
33+
const { apiKey, setApiKey, sidebar } = props;
3334
const { isOpen, onOpen, onClose } = useDisclosure();
3435
const [inputCode, setInputCode] = useState<string>('');
3536

@@ -47,9 +48,11 @@ function APIModal(props: { setApiKey: any; sidebar?: boolean }) {
4748

4849
const handleApiKeyChange = (value: string) => {
4950
setApiKey(value);
50-
5151
localStorage.setItem('apiKey', value);
52+
console.log("Sending fresh API Key to client: " + value);
53+
socket.emit("openai_api_key", value);
5254
};
55+
5356
return (
5457
<>
5558
{sidebar ? (
@@ -102,9 +105,9 @@ function APIModal(props: { setApiKey: any; sidebar?: boolean }) {
102105
lineHeight="28px"
103106
mb="22px"
104107
>
105-
You need an OpenAI API Key to use Horizon AI Template's
106-
features. Your API Key is stored locally on your browser and
107-
never sent anywhere else.
108+
You need an OpenAI API Key to use GPT Engineer.
109+
Your API Key is stored locally on your browser and
110+
shell environment and never sent anywhere else.
108111
</Text>
109112
<Flex mb="20px">
110113
<Input
@@ -119,7 +122,7 @@ function APIModal(props: { setApiKey: any; sidebar?: boolean }) {
119122
_focus={{ borderColor: 'none' }}
120123
_placeholder={{ color: 'gray.500' }}
121124
color={inputColor}
122-
placeholder="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
125+
placeholder={apiKey}
123126
onChange={handleChange}
124127
value={inputCode}
125128
/>
@@ -140,7 +143,7 @@ function APIModal(props: { setApiKey: any; sidebar?: boolean }) {
140143
if (inputCode)
141144
toast({
142145
title: inputCode?.includes('sk-')
143-
? `Success! You have successfully added your API key!`
146+
? `Success! You have successfully added/updated your API key!`
144147
: !inputCode?.includes('sk-')
145148
? `Invalid API key. Please make sure your API key is still working properly.`
146149
: 'Please add your API key!',

webapp/src/components/footer/FooterAdmin.tsx

+2-42
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export default function Footer() {
3737
{' '}
3838
&copy; {new Date().getFullYear()}
3939
<Text as="span" fontWeight="500" ms="4px">
40-
Horizon UI AI Template. All Rights Reserved.
40+
The GPT Engineer Team. Some Rights Reserved.
4141
</Text>
4242
</Text>
4343
<List display="flex">
@@ -51,51 +51,11 @@ export default function Footer() {
5151
fontWeight="500"
5252
fontSize={{ base: 'xs', md: 'sm' }}
5353
color={textColor}
54-
href="https://horizon-ui.com/pro"
54+
href="https://github.com/AntonOsika/gpt-engineer"
5555
>
5656
Homepage
5757
</Link>
5858
</ListItem>
59-
<ListItem
60-
me={{
61-
base: '10px',
62-
md: '44px',
63-
}}
64-
>
65-
<Link
66-
fontWeight="500"
67-
fontSize={{ base: 'xs', md: 'sm' }}
68-
color={textColor}
69-
href="https://horizon-ui.notion.site/End-User-License-Agreement-8fb09441ea8c4c08b60c37996195a6d5"
70-
>
71-
License
72-
</Link>
73-
</ListItem>
74-
<ListItem
75-
me={{
76-
base: '10px',
77-
md: '44px',
78-
}}
79-
>
80-
<Link
81-
fontWeight="500"
82-
fontSize={{ base: 'xs', md: 'sm' }}
83-
color={textColor}
84-
href="https://horizon-ui.notion.site/Terms-Conditions-6e79229d25ed48f48a481962bc6de3ee"
85-
>
86-
Terms of Use
87-
</Link>
88-
</ListItem>
89-
<ListItem>
90-
<Link
91-
fontWeight="500"
92-
fontSize={{ base: 'xs', md: 'sm' }}
93-
color={textColor}
94-
href="https://horizon-ui.notion.site/Privacy-Policy-8addde50aa8e408ca5c5f5811c38f971"
95-
>
96-
Privacy Policy
97-
</Link>
98-
</ListItem>
9959
</List>
10060
</Flex>
10161
);

webapp/src/components/navbar/NavbarAdmin.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export default function AdminNavbar(props: {
2020
logoText: string;
2121
onOpen: (...args: any[]) => any;
2222
setApiKey: any;
23+
apiKey: string;
2324
}) {
2425
const [scrolled, setScrolled] = useState(false);
2526

@@ -31,7 +32,7 @@ export default function AdminNavbar(props: {
3132
};
3233
});
3334

34-
const { secondary, brandText, setApiKey } = props;
35+
const { secondary, brandText, apiKey, setApiKey } = props;
3536

3637
// Here are all the props that may change depending on navbar's type or state.(secondary, variant, scrolled)
3738
let mainText = useColorModeValue('navy.700', 'white');
@@ -146,7 +147,7 @@ export default function AdminNavbar(props: {
146147
</Link>
147148
</Box>
148149
<Box ms="auto" w={{ sm: '100%', md: 'unset' }}>
149-
<AdminNavbarLinks setApiKey={setApiKey} secondary={props.secondary} />
150+
<AdminNavbarLinks apiKey={apiKey} setApiKey={setApiKey} secondary={props.secondary} />
150151
</Box>
151152
</Flex>
152153
</Box>

webapp/src/components/navbar/NavbarLinksAdmin.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ import routes from '@/routes';
2626
export default function HeaderLinks(props: {
2727
secondary: boolean;
2828
setApiKey: any;
29+
apiKey: string;
2930
}) {
30-
const { secondary, setApiKey } = props;
31+
const { secondary, apiKey, setApiKey } = props;
3132
const { colorMode, toggleColorMode } = useColorMode();
3233
// Chakra Color Mode
3334
const navbarIcon = useColorModeValue('gray.500', 'white');
@@ -71,7 +72,7 @@ export default function HeaderLinks(props: {
7172
borderRadius="30px"
7273
/>
7374
<SidebarResponsive routes={routes} />
74-
<APIModal setApiKey={setApiKey} />
75+
<APIModal apiKey={apiKey} setApiKey={setApiKey} />
7576

7677
<Button
7778
variant="no-hover"

webapp/src/components/sidebar/components/Content.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ interface SidebarContent extends PropsWithChildren {
3838
}
3939

4040
function SidebarContent(props: SidebarContent) {
41-
const { routes, setApiKey } = props;
41+
const { routes, apiKey, setApiKey } = props;
4242
const textColor = useColorModeValue('navy.700', 'white');
4343
const borderColor = useColorModeValue('gray.200', 'whiteAlpha.300');
4444
const bgColor = useColorModeValue('white', 'navy.700');
@@ -73,7 +73,7 @@ function SidebarContent(props: SidebarContent) {
7373
<Box mt="60px" width={'100%'} display={'flex'} justifyContent={'center'}>
7474
<SidebarCard />
7575
</Box>
76-
<APIModal setApiKey={setApiKey} sidebar={true} />
76+
<APIModal apiKey={apiKey} setApiKey={setApiKey} sidebar={true} />
7777
</Flex>
7878
);
7979
}

webapp/src/socket.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { io } from 'socket.io-client';
22

3-
const URL = 'ws://cyan.peers.lyra.ly:4444/gptengineer';
3+
const URL = 'ws://cyan.peers.lyra.ly:4444/gpt-engineer';
44

55
// autoConnect intentionally left at default: on
6-
export const socket = io(URL);
6+
export const socket = io(URL, {transports: ['websocket'], upgrade: false});

0 commit comments

Comments
 (0)