Merge pull request #21 from jina-ai/feat_going_meta

Feat going meta
This commit is contained in:
Florian Hönicke
2023-04-20 10:17:07 +02:00
committed by GitHub
28 changed files with 98 additions and 27626 deletions

View File

@@ -26,6 +26,9 @@ Your imagination is the limit!
<a href="https://github.com/tiangolo/gptdeploy/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://img.shields.io/badge/platform-mac%20%7C%20linux%20%7C%20windows-blue" alt="Supported platforms">
</a>
<a href="https://pypi.org/project/gptdeploy" target="_blank">
<img src="https://img.shields.io/pypi/dm/gptdeploy?color=%2334D058&label=pypi%20downloads" alt="Downloads">
</a>
<a href="https://discord.gg/ESn8ED6Fyn" target="_blank">
<img src="https://img.shields.io/badge/chat_on-Discord-7289DA?logo=discord&logoColor=white" alt="Discord Chat">
</a>
@@ -99,6 +102,16 @@ jc delete <microservice id>
## Examples
In this section you can get a feeling for the kind of microservices that can be generated with GPT Deploy.
### Extract and summarize news articles given a URL
```bash
gptdeploy generate \
--description "Extract text from a news article URL using Newspaper3k library and generate a summary using gpt." \
--test "input: 'http://fox13now.com/2013/12/30/new-year-new-laws-obamacare-pot-guns-and-drones/' output: assert a summarized version of the article exists" \
--model gpt-4 \
--path microservice
```
<img src="res/news_article_example.png" alt="News Article Example" width="400" />
### Chemical Formula Visualization
```bash
gptdeploy generate \
@@ -122,10 +135,10 @@ gptdeploy generate \
### Product Recommendation
```bash
gptdeploy generate \
--description "Generate personalized product recommendations based on user product browsing history and the product categories fashion, electronics and sport" --test "Test that a user how visited p1(electronics),p2(fashion),p3(fashion) is more likely to buy p4(fashion) than p5(sports)" \
--description "Generate personalized product recommendations based on user product browsing history and the product categories fashion, electronics and sport" \
--test "Test that a user how visited p1(electronics),p2(fashion),p3(fashion) is more likely to buy p4(fashion) than p5(sports)" \
--model gpt-4 \
--path microservice \
--verbose
--path microservice
```
<img src="res/recommendation_example.png" alt="Product Recommendation" width="400" />
@@ -512,7 +525,6 @@ In the following, you can find a list of things that need to be done.
next steps:
- [ ] check if windows and linux support works
- [ ] support gpt3.5-turbo
- [ ] add video to README.md
- [ ] bug: it can happen that the code generation is hanging forever - in this case aboard and redo the generation
- [ ] new user has free credits but should be told to verify account
@@ -524,7 +536,6 @@ Nice to have:
- [ ] don't show this message:
🔐 You are logged in to Jina AI as florian.hoenicke (username:auth0-unified-448f11965ce142b6).
To log out, use jina auth logout.
- [ ] rest endpoint instead of grpc since it is more popular
- [ ] put the playground into the custom gateway (without rebuilding the custom gateway)
- [ ] hide prompts in normal mode and show them in verbose mode
- [ ] tests

23
frontend/.gitignore vendored
View File

@@ -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*

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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

View File

@@ -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"
}

View File

@@ -1,3 +0,0 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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();
});

View File

@@ -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

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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>
);

View File

@@ -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

View File

@@ -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';

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

View File

@@ -10,10 +10,12 @@ from langchain.chat_models import ChatOpenAI
from openai.error import RateLimitError
from langchain.schema import HumanMessage, SystemMessage, BaseMessage
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
from requests.exceptions import ConnectionError
from src.constants import PRICING_GPT4_PROMPT, PRICING_GPT4_GENERATION, PRICING_GPT3_5_TURBO_PROMPT, \
PRICING_GPT3_5_TURBO_GENERATION, CHARS_PER_TOKEN
from src.options.generate.templates_system import template_system_message_base, executor_example, docarray_example, client_example
from src.options.generate.templates_system import template_system_message_base, executor_example, docarray_example, \
client_example, gpt_example
from src.utils.string_tools import print_colored
@@ -35,7 +37,7 @@ class GPTSession:
self.chars_prompt_so_far = 0
self.chars_generation_so_far = 0
def get_conversation(self, system_definition_examples: List[str] = ['executor', 'docarray', 'client']):
def get_conversation(self, system_definition_examples: List[str] = ['gpt', 'executor', 'docarray', 'client']):
return _GPTConversation(
self.model_name, self.cost_callback, self.task_description, self.test_description, system_definition_examples
)
@@ -111,7 +113,16 @@ class _GPTConversation:
if os.environ['VERBOSE'].lower() == 'true':
print_colored('user', prompt, 'blue')
print_colored('assistant', '', 'green', end='')
response = self._chat([self.system_message] + self.messages)
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.cost_callback(sum([len(m.content) for m in self.messages]), len(response.content))
@@ -124,6 +135,8 @@ class _GPTConversation:
task_description=task_description,
test_description=test_description,
)
if 'gpt' in system_definition_examples:
system_message += f'\n{gpt_example}'
if 'executor' in system_definition_examples:
system_message += f'\n{executor_example}'
if 'docarray' in system_definition_examples:

View File

@@ -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():
@@ -218,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

View File

@@ -12,6 +12,7 @@ DOCKER_FILE_TAG = 'dockerfile'
CLIENT_FILE_TAG = 'python'
STREAMLIT_FILE_TAG = 'python'
FILE_AND_TAG_PAIRS = [
(EXECUTOR_FILE_NAME, EXECUTOR_FILE_TAG),
(TEST_EXECUTOR_FILE_NAME, TEST_EXECUTOR_FILE_TAG),
@@ -38,4 +39,4 @@ DEMO_TOKEN = '45372338e04f5a41af949024db929d46'
PROBLEMATIC_PACKAGES = [
# 'Pyrender', 'Trimesh',
'ModernGL', 'PyOpenGL', 'Pyglet', 'pythreejs', 'panda3d' # because they need a screen
]
]

View File

@@ -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,
@@ -114,7 +114,7 @@ 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,
}),
file_name_purpose=REQUIREMENTS_FILE_NAME,
file_name=REQUIREMENTS_FILE_NAME,
@@ -128,7 +128,7 @@ 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,
}),
file_name_purpose=DOCKER_FILE_NAME,
file_name=DOCKER_FILE_NAME,
@@ -136,6 +136,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):
@@ -272,3 +273,4 @@ gptdeploy deploy --path {microservice_path}
conversation = self.gpt_session.get_conversation([])
error_summary = conversation.chat(template_summarize_error.format(error=error))
return error_summary

View File

@@ -1,6 +1,26 @@
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:
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:

View File

@@ -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(
@@ -99,9 +101,32 @@ 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 "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.
If you decided to use gpt, then the executor must include the following code:
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]['message']['content']
''' + '\n' + template_code_wrapping_string
)
@@ -132,7 +157,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 +179,7 @@ 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.
Note that the Dockerfile only has access to the files: microservice.py, requirements.txt, config.yml and test_microservice.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.
@@ -264,7 +295,7 @@ template_generate_playground = PromptTemplate.from_template(
Create a playground for the executor {microservice_name} using streamlit.
The playground must look like it was made by a professional designer.
All the ui elements are well thought out to make them visually appealing and easy to use.
The playground contains emojis that fit the theme of the playground.
The playground contains many emojis that fit the theme of the playground and has an emoji as favicon.
This is an example how you can connect to the executor assuming the document (d) is already defined:
```
from jina import Client, Document, DocumentArray