mirror of
https://github.com/aljazceru/dev-gpt.git
synced 2025-12-21 07:34:20 +01:00
feat: support for gpt
This commit is contained in:
23
frontend/.gitignore
vendored
23
frontend/.gitignore
vendored
@@ -1,23 +0,0 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
@@ -1,70 +0,0 @@
|
||||
# Getting Started with Create React App
|
||||
|
||||
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
||||
|
||||
## Available Scripts
|
||||
|
||||
In the project directory, you can run:
|
||||
|
||||
### `npm start`
|
||||
|
||||
Runs the app in the development mode.\
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
|
||||
|
||||
The page will reload when you make changes.\
|
||||
You may also see any lint errors in the console.
|
||||
|
||||
### `npm test`
|
||||
|
||||
Launches the test runner in the interactive watch mode.\
|
||||
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
|
||||
|
||||
### `npm run build`
|
||||
|
||||
Builds the app for production to the `build` folder.\
|
||||
It correctly bundles React in production mode and optimizes the build for the best performance.
|
||||
|
||||
The build is minified and the filenames include the hashes.\
|
||||
Your app is ready to be deployed!
|
||||
|
||||
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
||||
|
||||
### `npm run eject`
|
||||
|
||||
**Note: this is a one-way operation. Once you `eject`, you can't go back!**
|
||||
|
||||
If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
|
||||
|
||||
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
|
||||
|
||||
You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
|
||||
|
||||
## Learn More
|
||||
|
||||
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
|
||||
|
||||
To learn React, check out the [React documentation](https://reactjs.org/).
|
||||
|
||||
### Code Splitting
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
|
||||
|
||||
### Analyzing the Bundle Size
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
|
||||
|
||||
### Making a Progressive Web App
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
|
||||
|
||||
### Deployment
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
|
||||
|
||||
### `npm run build` fails to minify
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
|
||||
17228
frontend/package-lock.json
generated
17228
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,46 +0,0 @@
|
||||
{
|
||||
"name": "microchain-frontend",
|
||||
"version": "0.1.1",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.10.6",
|
||||
"@emotion/styled": "^11.10.6",
|
||||
"@material-ui/core": "^4.12.4",
|
||||
"@material-ui/icons": "^4.11.3",
|
||||
"@mui/material": "^5.11.13",
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"axios": "^1.3.4",
|
||||
"clipboard-copy": "^4.0.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"uuid": "^9.0.0",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.8 KiB |
@@ -1,43 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 9.4 KiB |
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
||||
@@ -1,38 +0,0 @@
|
||||
.App {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
height: 40vmin;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.App-logo {
|
||||
animation: App-logo-spin infinite 20s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.App-header {
|
||||
background-color: #282c34;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.App-link {
|
||||
color: #61dafb;
|
||||
}
|
||||
|
||||
@keyframes App-logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@@ -1,196 +0,0 @@
|
||||
import React, {useState} from 'react';
|
||||
import axios from 'axios';
|
||||
import {Box, Container, FormControl, InputLabel, MenuItem, Select, TextField, Typography,} from '@mui/material';
|
||||
import copy from 'clipboard-copy';
|
||||
import Button from '@mui/material/Button';
|
||||
|
||||
function App() {
|
||||
const [executorName, setExecutorName] = useState('MyCoolOcrExecutor');
|
||||
const [executorDescription, setExecutorDescription] = useState('OCR detector');
|
||||
const [inputModality, setInputModality] = useState('image');
|
||||
const [inputDocField, setInputDocField] = useState('uri');
|
||||
const [outputModality, setOutputModality] = useState('text');
|
||||
const [outputDocField, setOutputDocField] = useState('text');
|
||||
const [testIn, settestIn] = useState('https://miro.medium.com/v2/resize:fit:1024/0*4ty0Adbdg4dsVBo3.png');
|
||||
const [testOut, settestOut] = useState('> Hello, world!_');
|
||||
const [responseText, setResponseText] = useState(null);
|
||||
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const requestBody = {
|
||||
executor_name: executorName,
|
||||
executor_description: executorDescription,
|
||||
input_modality: inputModality,
|
||||
input_doc_field: inputDocField,
|
||||
output_modality: outputModality,
|
||||
output_doc_field: outputDocField,
|
||||
test_in: testIn,
|
||||
test_out: testOut,
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await axios.post('http://0.0.0.0:8000/create', requestBody);
|
||||
console.log(response.data)
|
||||
setResponseText(response.data);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
setResponseText('An error occurred while processing the request.');
|
||||
}
|
||||
};
|
||||
|
||||
const handleCopy = (fileContent) => {
|
||||
copy(fileContent);
|
||||
};
|
||||
|
||||
return (
|
||||
<Container maxWidth="md">
|
||||
<Box sx={{my: 4}}>
|
||||
<Typography variant="h4" component="h1" gutterBottom>
|
||||
MicroChain
|
||||
</Typography>
|
||||
<Typography variant="body1" component="p" gutterBottom>
|
||||
✨ Magically create your microservice just by describing it.
|
||||
</Typography>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Box sx={{my: 2}}>
|
||||
<TextField
|
||||
label="Executor Name"
|
||||
value={executorName}
|
||||
onChange={(e) => setExecutorName(e.target.value)}
|
||||
fullWidth
|
||||
/>
|
||||
</Box>
|
||||
<Box sx={{my: 2}}>
|
||||
<TextField
|
||||
label="Executor Description"
|
||||
value={executorDescription}
|
||||
onChange={(e) => setExecutorDescription(e.target.value)}
|
||||
fullWidth
|
||||
/>
|
||||
</Box>
|
||||
<Box sx={{my: 2}}>
|
||||
<Typography variant="h6" component="h2" gutterBottom>
|
||||
Input Interface
|
||||
</Typography>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel id="input-modality-label">Input Modality</InputLabel>
|
||||
<Select
|
||||
labelId="input-modality-label"
|
||||
value={inputModality}
|
||||
onChange={(e) => setInputModality(e.target.value)}
|
||||
>
|
||||
<MenuItem value="text">Text</MenuItem>
|
||||
<MenuItem value="image">Image</MenuItem>
|
||||
<MenuItem value="3d">3D</MenuItem>
|
||||
<MenuItem value="audio">Audio</MenuItem>
|
||||
<MenuItem value="video">Video</MenuItem>
|
||||
<MenuItem value="pdf">PDF</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Box>
|
||||
<Box sx={{my: 2}}>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel id="input-doc-field-label">Input Doc Field</InputLabel>
|
||||
<Select
|
||||
labelId="input-doc-field-label"
|
||||
value={inputDocField}
|
||||
onChange={(e) => setInputDocField(e.target.value)}
|
||||
>
|
||||
<MenuItem value="text">Text</MenuItem>
|
||||
<MenuItem value="blob">Blob</MenuItem>
|
||||
<MenuItem value="tensor">Tensor</MenuItem>
|
||||
<MenuItem value="uri">URL</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Box>
|
||||
<Box sx={{my: 2}}>
|
||||
<Typography variant="h6" component="h2" gutterBottom>
|
||||
Output Interface
|
||||
</Typography>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel id="output-modality-label">Output Modality</InputLabel>
|
||||
<Select
|
||||
labelId="output-modality-label"
|
||||
value={outputModality}
|
||||
onChange={(e) => setOutputModality(e.target.value)}
|
||||
>
|
||||
<MenuItem value="text">Text</MenuItem>
|
||||
<MenuItem value="image">Image</MenuItem>
|
||||
<MenuItem value="3d">3D</MenuItem>
|
||||
<MenuItem value="audio">Audio</MenuItem>
|
||||
<MenuItem value="video">Video</MenuItem>
|
||||
<MenuItem value="pdf">PDF</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Box>
|
||||
<Box sx={{my: 2}}>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel id="output-doc-field-label">Output Doc Field</InputLabel>
|
||||
<Select
|
||||
labelId="output-doc-field-label"
|
||||
value={outputDocField}
|
||||
onChange={(e) => setOutputDocField(e.target.value)}
|
||||
>
|
||||
<MenuItem value="text">Text</MenuItem>
|
||||
<MenuItem value="blob">Blob</MenuItem>
|
||||
<MenuItem value="tensor">Tensor</MenuItem>
|
||||
<MenuItem value="uri">URL</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Box>
|
||||
<Box sx={{my: 2}}>
|
||||
<Typography variant="h6" component="h2" gutterBottom>
|
||||
Test Parameters
|
||||
</Typography>
|
||||
<TextField
|
||||
label="Input Test In"
|
||||
value={testIn}
|
||||
onChange={(e) => settestIn(e.target.value)}
|
||||
fullWidth
|
||||
/>
|
||||
</Box>
|
||||
<Box sx={{my: 2}}>
|
||||
<TextField
|
||||
label="Input Test Out"
|
||||
value={testOut}
|
||||
onChange={(e) => settestOut(e.target.value)}
|
||||
fullWidth
|
||||
/>
|
||||
</Box>
|
||||
<Box sx={{my: 2}}>
|
||||
<Button type="submit" variant="contained" color="primary">
|
||||
Submit
|
||||
</Button>
|
||||
</Box>
|
||||
</form>
|
||||
{responseText && (
|
||||
<Box sx={{my: 4}}>
|
||||
<Typography variant="h6" component="h2" gutterBottom>
|
||||
Response
|
||||
</Typography>
|
||||
{Object.entries(responseText.result).map(([fileName, fileContent]) => (
|
||||
<Box key={fileName} sx={{my: 2, p: 2, border: '1px solid #ddd', borderRadius: '4px'}}>
|
||||
<Typography variant="subtitle1" gutterBottom>
|
||||
{fileName}
|
||||
</Typography>
|
||||
<pre>{fileContent}</pre>
|
||||
<Button
|
||||
onClick={() => handleCopy(fileContent)}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
size="small"
|
||||
>
|
||||
Copy Code
|
||||
</Button>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
@@ -1,8 +0,0 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import App from './App';
|
||||
|
||||
test('renders learn react link', () => {
|
||||
render(<App />);
|
||||
const linkElement = screen.getByText(/learn react/i);
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
});
|
||||
@@ -1,111 +0,0 @@
|
||||
import React, { useState } from 'react';
|
||||
|
||||
function CreateExecutorForm({ onCreateExecutor }) {
|
||||
const [formData, setFormData] = useState({
|
||||
executor_name: '',
|
||||
executor_description: '',
|
||||
input_modality: '',
|
||||
input_doc_field: '',
|
||||
output_modality: '',
|
||||
output_doc_field: '',
|
||||
test_in: '',
|
||||
test_out: '',
|
||||
});
|
||||
|
||||
const handleChange = (e) => {
|
||||
setFormData({ ...formData, [e.target.name]: e.target.value });
|
||||
};
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
onCreateExecutor(formData);
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<label>
|
||||
Executor Name:
|
||||
<input
|
||||
type="text"
|
||||
name="executor_name"
|
||||
value={formData.executor_name}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
Input Executor Description:
|
||||
<input
|
||||
type="text"
|
||||
name="executor_description"
|
||||
value={formData.executor_description}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
Input Modality:
|
||||
<input
|
||||
type="text"
|
||||
name="input_modality"
|
||||
value={formData.input_modality}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
Input Doc Field:
|
||||
<input
|
||||
type="text"
|
||||
name="input_doc_field"
|
||||
value={formData.input_doc_field}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
Output Modality:
|
||||
<input
|
||||
type="text"
|
||||
name="output_modality"
|
||||
value={formData.output_modality}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
Output Doc Field:
|
||||
<input
|
||||
type="text"
|
||||
name="output_doc_field"
|
||||
value={formData.output_doc_field}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
Input Test URL:
|
||||
<input
|
||||
type="url"
|
||||
name="test_in"
|
||||
value={formData.test_in}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
Input Test Output:
|
||||
<input
|
||||
type="text"
|
||||
name="test_out"
|
||||
value={formData.test_out}
|
||||
onChange={handleChange}
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<button type="submit">Create Executor</button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
export default CreateExecutorForm
|
||||
@@ -1,30 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
function ExecutorOutput({ response }) {
|
||||
const { result, success, message } = response;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Generated Executor Files</h2>
|
||||
{success ? (
|
||||
<div>
|
||||
{Object.entries(result).map(([filename, content]) => (
|
||||
<div key={filename}>
|
||||
<h3>{filename}</h3>
|
||||
<pre>
|
||||
<code>{content}</code>
|
||||
</pre>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<h3>Error</h3>
|
||||
<p>{message}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ExecutorOutput;
|
||||
@@ -1,13 +0,0 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
);
|
||||
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.6 KiB |
@@ -1,5 +0,0 @@
|
||||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom';
|
||||
9759
frontend/yarn.lock
9759
frontend/yarn.lock
File diff suppressed because it is too large
Load Diff
@@ -8,8 +8,9 @@ from langchain import PromptTemplate
|
||||
from langchain.callbacks import CallbackManager
|
||||
from langchain.chat_models import ChatOpenAI
|
||||
from openai.error import RateLimitError
|
||||
from langchain.schema import AIMessage, HumanMessage, SystemMessage, BaseMessage
|
||||
from langchain.schema import HumanMessage, SystemMessage, BaseMessage
|
||||
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
|
||||
from requests.exceptions import ConnectionError
|
||||
|
||||
from src.options.generate.templates_system import template_system_message_base, executor_example, docarray_example, client_example
|
||||
from src.utils.string_tools import print_colored
|
||||
@@ -83,7 +84,16 @@ class _GPTConversation:
|
||||
if os.environ['VERBOSE'].lower() == 'true':
|
||||
print_colored('user', prompt, 'blue')
|
||||
print_colored('assistant', '', 'green', end='')
|
||||
for i in range(10):
|
||||
try:
|
||||
response = self._chat([self.system_message] + self.messages)
|
||||
break
|
||||
except ConnectionError as e:
|
||||
print('There was a connection error. Retrying...')
|
||||
if i == 9:
|
||||
raise e
|
||||
sleep(10)
|
||||
|
||||
if os.environ['VERBOSE'].lower() == 'true':
|
||||
print()
|
||||
self.messages.append(response)
|
||||
|
||||
@@ -73,6 +73,7 @@ def push_executor(dir_path):
|
||||
'public': 'True',
|
||||
'private': 'False',
|
||||
'verbose': 'True',
|
||||
'buildEnv': f'{{"OPENAI_API_KEY": "{os.environ["OPENAI_API_KEY"]}"}}',
|
||||
'md5sum': md5_digest,
|
||||
}
|
||||
with suppress_stdout():
|
||||
@@ -207,6 +208,7 @@ jtype: Flow
|
||||
with:
|
||||
name: nowapi
|
||||
port: 8080
|
||||
protocol: http
|
||||
jcloud:
|
||||
version: 3.14.2.dev18
|
||||
labels:
|
||||
@@ -217,6 +219,8 @@ executors:
|
||||
- name: {executor_name.lower()}
|
||||
uses: {prefix}://{get_user_name(DEMO_TOKEN)}/{executor_name}:latest
|
||||
{"" if use_docker else "install-requirements: True"}
|
||||
env:
|
||||
OPENAI_API_KEY: {os.environ['OPENAI_API_KEY']}
|
||||
jcloud:
|
||||
resources:
|
||||
instance: C2
|
||||
@@ -290,3 +294,5 @@ def process_error_message(error_message):
|
||||
if not response and last_line.startswith('error: '):
|
||||
return last_line
|
||||
return response
|
||||
|
||||
push_executor('/Users/florianhonicke/jina/gptdeploy/microservice/NewsArticleSummaryExecutor7754860')
|
||||
@@ -4,7 +4,9 @@ REQUIREMENTS_FILE_NAME = 'requirements.txt'
|
||||
DOCKER_FILE_NAME = 'Dockerfile'
|
||||
CLIENT_FILE_NAME = 'client.py'
|
||||
STREAMLIT_FILE_NAME = 'streamlit.py'
|
||||
GPT_3_5_TURBO_API_FILE_NAME = 'gpt_3_5_turbo_api.py'
|
||||
|
||||
GPT_3_5_TURBO_API_FILE_TAG = 'python'
|
||||
EXECUTOR_FILE_TAG = 'python'
|
||||
TEST_EXECUTOR_FILE_TAG = 'python'
|
||||
REQUIREMENTS_FILE_TAG = ''
|
||||
@@ -12,7 +14,9 @@ DOCKER_FILE_TAG = 'dockerfile'
|
||||
CLIENT_FILE_TAG = 'python'
|
||||
STREAMLIT_FILE_TAG = 'python'
|
||||
|
||||
|
||||
FILE_AND_TAG_PAIRS = [
|
||||
(GPT_3_5_TURBO_API_FILE_NAME, GPT_3_5_TURBO_API_FILE_NAME),
|
||||
(EXECUTOR_FILE_NAME, EXECUTOR_FILE_TAG),
|
||||
(TEST_EXECUTOR_FILE_NAME, TEST_EXECUTOR_FILE_TAG),
|
||||
(REQUIREMENTS_FILE_NAME, REQUIREMENTS_FILE_TAG),
|
||||
@@ -33,3 +37,5 @@ PROBLEMATIC_PACKAGES = [
|
||||
# 'Pyrender', 'Trimesh',
|
||||
'ModernGL', 'PyOpenGL', 'Pyglet', 'pythreejs', 'panda3d' # because they need a screen
|
||||
]
|
||||
|
||||
GPT_3_5_TURBO_API_FILE_NAME = 'gpt_3_5_turbo_api.py'
|
||||
@@ -6,7 +6,7 @@ from src.apis import gpt
|
||||
from src.apis.jina_cloud import process_error_message, push_executor
|
||||
from src.constants import FILE_AND_TAG_PAIRS, NUM_IMPLEMENTATION_STRATEGIES, MAX_DEBUGGING_ITERATIONS, \
|
||||
PROBLEMATIC_PACKAGES, EXECUTOR_FILE_NAME, EXECUTOR_FILE_TAG, TEST_EXECUTOR_FILE_NAME, TEST_EXECUTOR_FILE_TAG, \
|
||||
REQUIREMENTS_FILE_NAME, REQUIREMENTS_FILE_TAG, DOCKER_FILE_NAME, DOCKER_FILE_TAG
|
||||
REQUIREMENTS_FILE_NAME, REQUIREMENTS_FILE_TAG, DOCKER_FILE_NAME, DOCKER_FILE_TAG, GPT_3_5_TURBO_API_FILE_NAME
|
||||
from src.options.generate.templates_user import template_generate_microservice_name, template_generate_possible_packages, \
|
||||
template_solve_code_issue, \
|
||||
template_solve_dependency_issue, template_is_dependency_issue, template_generate_playground, \
|
||||
@@ -70,7 +70,7 @@ metas:
|
||||
content_raw, file_name, match_single_block=True
|
||||
)
|
||||
persist_file(content, os.path.join(destination_folder, file_name))
|
||||
return content_raw
|
||||
return content
|
||||
|
||||
def generate_microservice(
|
||||
self,
|
||||
@@ -82,10 +82,13 @@ metas:
|
||||
MICROSERVICE_FOLDER_v1 = get_microservice_path(path, microservice_name, packages, num_approach, 1)
|
||||
os.makedirs(MICROSERVICE_FOLDER_v1)
|
||||
|
||||
gpt_3_5_turbo_api_content = self.write_gpt_api_file(MICROSERVICE_FOLDER_v1)
|
||||
|
||||
microservice_content = self.generate_and_persist_file(
|
||||
'Microservice',
|
||||
template_generate_executor,
|
||||
MICROSERVICE_FOLDER_v1,
|
||||
code_files_wrapped=self.files_to_string({'gpt_3_5_turbo_api.py': gpt_3_5_turbo_api_content}),
|
||||
microservice_name=microservice_name,
|
||||
microservice_description=self.task_description,
|
||||
test_description=self.test_description,
|
||||
@@ -99,7 +102,7 @@ metas:
|
||||
'Test Microservice',
|
||||
template_generate_test,
|
||||
MICROSERVICE_FOLDER_v1,
|
||||
code_files_wrapped=self.files_to_string({'microservice.py': microservice_content}),
|
||||
code_files_wrapped=self.files_to_string({'microservice.py': microservice_content, 'gpt_3_5_turbo_api.py': gpt_3_5_turbo_api_content,}),
|
||||
microservice_name=microservice_name,
|
||||
microservice_description=self.task_description,
|
||||
test_description=self.test_description,
|
||||
@@ -114,7 +117,8 @@ metas:
|
||||
MICROSERVICE_FOLDER_v1,
|
||||
code_files_wrapped=self.files_to_string({
|
||||
'microservice.py': microservice_content,
|
||||
'test_microservice.py': test_microservice_content
|
||||
'test_microservice.py': test_microservice_content,
|
||||
'gpt_3_5_turbo_api.py': gpt_3_5_turbo_api_content,
|
||||
}),
|
||||
file_name_purpose=REQUIREMENTS_FILE_NAME,
|
||||
file_name=REQUIREMENTS_FILE_NAME,
|
||||
@@ -128,7 +132,8 @@ metas:
|
||||
code_files_wrapped=self.files_to_string({
|
||||
'microservice.py': microservice_content,
|
||||
'test_microservice.py': test_microservice_content,
|
||||
'requirements.txt': requirements_content
|
||||
'requirements.txt': requirements_content,
|
||||
'gpt_3_5_turbo_api.py': gpt_3_5_turbo_api_content,
|
||||
}),
|
||||
file_name_purpose=DOCKER_FILE_NAME,
|
||||
file_name=DOCKER_FILE_NAME,
|
||||
@@ -136,6 +141,7 @@ metas:
|
||||
)
|
||||
|
||||
self.write_config_yml(microservice_name, MICROSERVICE_FOLDER_v1)
|
||||
|
||||
print('\nFirst version of the microservice generated. Start iterating on it to make the tests pass...')
|
||||
|
||||
def generate_playground(self, microservice_name, microservice_path):
|
||||
@@ -271,3 +277,11 @@ gptdeploy deploy --path {microservice_path}
|
||||
conversation = self.gpt_session.get_conversation([])
|
||||
error_summary = conversation.chat(template_summarize_error.format(error=error))
|
||||
return error_summary
|
||||
|
||||
def write_gpt_api_file(self, MICROSERVICE_FOLDER_v1):
|
||||
cur_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
with open(os.path.join(cur_dir, GPT_3_5_TURBO_API_FILE_NAME), 'r', encoding='utf-8') as file:
|
||||
GPT_3_5_Turbo_API_content = file.read()
|
||||
with open(os.path.join(MICROSERVICE_FOLDER_v1, GPT_3_5_TURBO_API_FILE_NAME), 'w', encoding='utf-8') as file:
|
||||
file.write(GPT_3_5_Turbo_API_content)
|
||||
return GPT_3_5_Turbo_API_content
|
||||
|
||||
24
src/options/generate/gpt_3_5_turbo_api.py
Normal file
24
src/options/generate/gpt_3_5_turbo_api.py
Normal file
@@ -0,0 +1,24 @@
|
||||
import os
|
||||
import openai
|
||||
openai.api_key = os.getenv("OPENAI_API_KEY")
|
||||
|
||||
class GPT_3_5_Turbo_API:
|
||||
def __init__(self, system: str = ''):
|
||||
self.system = system
|
||||
|
||||
def __call__(self, prompt: str) -> str:
|
||||
response = openai.ChatCompletion.create(
|
||||
model="gpt-3.5-turbo",
|
||||
messages=[{
|
||||
"role": 'system',
|
||||
"content": self.system
|
||||
}, {
|
||||
"role": 'user',
|
||||
"content": prompt
|
||||
}]
|
||||
)
|
||||
return response.choices[0].text
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,27 @@
|
||||
from src.constants import FLOW_URL_PLACEHOLDER
|
||||
from src.options.generate.templates_user import not_allowed_docker_string, not_allowed_executor_string
|
||||
|
||||
gpt_example = '''
|
||||
# gpt_3_5_turbo is a language model that can be used to generate text.
|
||||
you can use it to generate text given a system definition and a user prompt.
|
||||
The system definition defines the agent the user is talking to.
|
||||
The user prompt is precise question and the expected answer format.
|
||||
Example:
|
||||
# in the executor init:
|
||||
from gpt_3_5_turbo_api import GPT_3_5_Turbo_API
|
||||
gpt = GPT_3_5_Turbo_API(
|
||||
system=\'\'\'
|
||||
You are a tv-reporter who is specialized in C-list celebrities.
|
||||
When you get asked something like 'Who was having a date with <X>?', then you answer with a json like '{"dates": ["<Y>", "<Z>"]}'.
|
||||
You must not answer something else - only the json.
|
||||
\'\'\')
|
||||
|
||||
# in the executor endpoint function:
|
||||
response_string = gpt(prompt)
|
||||
response = json.loads(response_string) # response is a string
|
||||
|
||||
'''
|
||||
|
||||
executor_example = '''Using the Jina framework, users can define executors.
|
||||
Here is an example of how an executor can be defined. It always starts with a comment:
|
||||
|
||||
|
||||
@@ -25,7 +25,9 @@ The executor and the test must not use a pre-trained model unless it is explicit
|
||||
The executor and the test must not train a model.
|
||||
The executor and the test must not use any attribute of Document accept Document.text.
|
||||
The executor and the test must not contain prototype or placeholder implementations.
|
||||
The executor and the test must run in a docker container based on debian.'''
|
||||
The executor and the test must run in a docker container based on debian.
|
||||
The executor and the test must use gpt_3_5_turbo_api if the task requires a language model. Other language models are not allowed.'''
|
||||
|
||||
|
||||
|
||||
template_generate_microservice_name = PromptTemplate.from_template(
|
||||
@@ -88,6 +90,8 @@ You must provide the complete file with the exact same syntax to wrap the code.'
|
||||
template_generate_executor = PromptTemplate.from_template(
|
||||
general_guidelines_string + '''
|
||||
|
||||
{code_files_wrapped}
|
||||
|
||||
Write the executor called '{microservice_name}'. The name is very important to keep.
|
||||
It matches the following description: '{microservice_description}'.
|
||||
It will be tested with the following scenario: '{test_description}'.
|
||||
@@ -99,7 +103,7 @@ Have in mind that d.uri is never a path to a local file. It is always a url.
|
||||
|
||||
Your approach:
|
||||
1. Identify the core challenge when implementing the executor.
|
||||
2. Think about solutions for these challenges.
|
||||
2. Think about solutions for these challenges including the usage of gpt via "from gpt_3_5_turbo_api import GPT_3_5_Turbo_API"
|
||||
3. Decide for one of the solutions.
|
||||
4. Write the code for the executor. Don't write code for the test.
|
||||
''' + '\n' + template_code_wrapping_string
|
||||
@@ -132,7 +136,13 @@ template_generate_requirements = PromptTemplate.from_template(
|
||||
|
||||
{code_files_wrapped}
|
||||
|
||||
Write the content of the requirements.txt file. Make sure to include pytest. Make sure that jina==3.14.1. Make sure that docarray==0.21.0.
|
||||
Write the content of the requirements.txt file.
|
||||
Make sure to include pytest.
|
||||
Make sure to include openai>=0.26.0.
|
||||
Make sure that jina==3.14.1.
|
||||
Make sure that docarray==0.21.0.
|
||||
You must not add gpt_3_5_turbo_api to the requirements.txt file.
|
||||
|
||||
All versions are fixed using ~=, ==, <, >, <=, >=. The package versions must not have conflicts.
|
||||
''' + '\n' + template_code_wrapping_string
|
||||
)
|
||||
@@ -148,7 +158,8 @@ It is important to make sure that all libs are installed that are required by th
|
||||
Usually libraries are installed with apt-get.
|
||||
Be aware that the machine the docker container is running on does not have a GPU - only CPU.
|
||||
Add the config.yml file to the Dockerfile.
|
||||
Note that the Dockerfile only has access to the files: microservice.py, requirements.txt, config.yml, test_microservice.py.
|
||||
Add the gpt_3_5_turbo_api.py file to the Dockerfile.
|
||||
Note that the Dockerfile only has access to the files: microservice.py, requirements.txt, config.yml, test_microservice.py and gpt_3_5_turbo_api.py.
|
||||
The base image of the Dockerfile is FROM jinaai/jina:3.14.1-py39-standard.
|
||||
The entrypoint is ENTRYPOINT ["jina", "executor", "--uses", "config.yml"].
|
||||
Make sure the all files are in the /workdir.
|
||||
|
||||
Reference in New Issue
Block a user