Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
vincent0426 committed Aug 13, 2023
2 parents 523eee0 + 1ad39ac commit 686f405
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 21 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Supatest

## Documentation

### Natural Language Processing

Our initial strategy involves generating an entire column within the target table using the language model (in our case, ChatGPT), and we can furnish the schema of the table through a prompt. However, as we intend to execute the same prompt multiple times to obtain various sets of synthetic data, we desire a degree of randomness in our language model's outputs. Yet, incrementing the temperature setting to achieve this randomness leads to unstable outputs from the language model. Consequently, we have adopted an alternative approach.

#### First Step: Column Classification

Given the inherent instability in generating substantial amounts of data from the language model (LLM), our approach aims to enhance stability. We begin by dissecting the intended purpose of the column, categorizing it into recognized types such as usernames or locations using zero-shot classification with the `transformer` library. Those columns with clearly defined purposes can then be efficiently created using the `faker.js` library. However, for more intricate columns like paragraph content, we leverage the capabilities of a more-powerful prompt-based LLM to generate such data.

#### Second Step: Complex Data Generation

Beginning with the initial step, our approach involves providing the schema of the table along with the contents of the incomplete column to our prompt-based language model (LLM). This enables the model to discern the context and generate appropriate content accordingly. To illustrate, in a trial run, we utilize the `faker.js` library to generate the values for columns such as `sender_name` (Jorge) and `receiver_name` (Marie), while the column message_content is crafted by ChatGPT, yielding the desired result: *Hey Marie, how have you been?* This process effectively fulfills our intended objective.

## Roadmap

1. Fetch schema data from supabase sql.
Expand Down
4 changes: 2 additions & 2 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { Inter } from 'next/font/google';
const inter = Inter({ subsets: ['latin'] });

export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
title: 'Supatest',
description: 'Generate fake data for your Supabase tables',
};

export default function RootLayout({
Expand Down
62 changes: 43 additions & 19 deletions components/ConnectionButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,53 @@ import {
AlertDialogTrigger,
} from '@/components/ui/alert-dialog';
import { Button } from '@/components/ui/button';

import { Eye } from 'lucide-react';
import { useConnectionAtom, useOpenAIAtom, useSchemaAtom } from '@/atoms';
import React, { useState } from 'react';
import { Input } from '@/components/ui/input';
import { Label } from '../ui/label';
import { toast } from 'sonner';

function ConnectionForm() {
const { url, anon, setUrl, setAnon } = useConnectionAtom();
const [hidden, setHidden] = useState(true);
return (
<div className="flex flex-col gap-4 text-white">
<Input type="text" value={url} onChange={(e) => setUrl(e.target.value)} placeholder="URL" />
<Input type="text" value={anon} onChange={(e) => setAnon(e.target.value)} placeholder="API Key" />
<div className="flex flex-col gap-4 text-muted-foreground">
<div>
<Label htmlFor="url" className="text-sm">
Supabase URL
</Label>
<Input id="url" type="text" value={url} onChange={(e) => setUrl(e.target.value)} className='w-[430px]'/>
</div>
<div>
<Label htmlFor="anon" className="text-sm">
Supabase API Key
</Label>
<div className="flex items-center"> {/* Wrapping in a flex container */}
<Input id="anon" type={`${hidden ? 'password' : 'text'}`} value={anon} onChange={(e) => setAnon(e.target.value)} />
<button onClick={() => setHidden(!hidden)} className="ml-2"> {/* Toggle button */}
<Eye />
</button>
</div>
</div>
</div>
);
};



export function ConnectionButton() {
const [open, setOpen] = useState(false);

const [openAPIHidden, setOpenAPIHidden] = useState(true);
// Set this to your Supabase Credentials if you want to test it out
const { url, anon } = useConnectionAtom();
const { openAIAPIToken, setOpenAIAPIToken } = useOpenAIAtom();

const [error, setError] = useState('');

const {schema, setSchema} = useSchemaAtom();

const handleConnect = () => {
setError('');

if (!url || !anon) {
setError('URL and API key are required.');
toast.error('Please enter a Supabase URL and API key.');
return;
}

Expand All @@ -59,19 +74,23 @@ export function ConnectionButton() {
},
});
if (!response.ok) {
throw new Error('Error with fetching data');
console.log(response);
toast.error('Invalid content type. Please check your URL and API key.');
return;
}

const contentType = response.headers.get('content-type');
if (!contentType || contentType.indexOf('application/openapi+json') === -1) {
throw new Error('Invalid link');
toast.error('Invalid content type. Please check your URL and API key.');
return;
}

const data = await response.json();
setSchema(data);
return data;
toast.success('Connected to Supabase!');
} catch (error: any) {
setError(error.message || 'An error occurred.');
console.log(error);
toast.error('Something went wrong. Please check your URL and API key.');
}
};

Expand All @@ -85,16 +104,21 @@ export function ConnectionButton() {
<AlertDialogTitle>Please Enter Your Connection Details</AlertDialogTitle>
<AlertDialogDescription className='text-sm text-red-500'>
This will not be saved anywhere.
<ConnectionForm />
</AlertDialogDescription>
<ConnectionForm />
<AlertDialogDescription className='text-sm pt-2'>
Your Open AI API Token
<Input type="text" value={openAIAPIToken} onChange={(e) => setOpenAIAPIToken(e.target.value)} />
Open AI API Token
<div className="flex items-center"> {/* Wrapping in a flex container */}
<Input type={`${openAPIHidden ? 'password' : 'text'}`} value={openAIAPIToken} onChange={(e) => setOpenAIAPIToken(e.target.value)} />
<button onClick={() => setOpenAPIHidden(!openAPIHidden)} className="ml-2"> {/* Toggle button */}
<Eye />
</button>
</div>
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogFooter className='mr-8'>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction onClick={handleConnect}>Confirm</AlertDialogAction>
<AlertDialogAction onClick={handleConnect}>Connect</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
Expand Down

0 comments on commit 686f405

Please sign in to comment.