From 4442799f6cdf4cc35cb53aed71282afde1c2135b Mon Sep 17 00:00:00 2001 From: Julien Goux Date: Wed, 20 Nov 2024 18:14:49 +0100 Subject: [PATCH 01/24] wip --- apps/postgres-new/sw.ts | 9 +++++++++ apps/postgres-new/tsconfig.json | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 apps/postgres-new/sw.ts diff --git a/apps/postgres-new/sw.ts b/apps/postgres-new/sw.ts new file mode 100644 index 00000000..f4b2313e --- /dev/null +++ b/apps/postgres-new/sw.ts @@ -0,0 +1,9 @@ +export type {} +declare const self: ServiceWorkerGlobalScope + +self.addEventListener('fetch', (event) => { + if (event.request.url.includes('/api/chat')) { + } + + event.respondWith(fetch(event.request)) +}) diff --git a/apps/postgres-new/tsconfig.json b/apps/postgres-new/tsconfig.json index d506c8ec..5cb519b6 100644 --- a/apps/postgres-new/tsconfig.json +++ b/apps/postgres-new/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "lib": ["dom", "dom.iterable", "esnext"], + "lib": ["dom", "dom.iterable", "esnext", "webworker"], "allowJs": true, "skipLibCheck": true, "strict": true, From ce4070bd1538bc9369c63574fd91906cf87be910 Mon Sep 17 00:00:00 2001 From: Julien Goux Date: Thu, 21 Nov 2024 15:31:09 +0100 Subject: [PATCH 02/24] wip --- .../components/model/set-model-dialog.tsx | 130 +++++++++++++ apps/postgres-new/components/sidebar.tsx | 34 ++++ apps/postgres-new/components/ui/form.tsx | 178 ++++++++++++++++++ apps/postgres-new/lib/tools.ts | 2 +- apps/postgres-new/package.json | 3 + apps/postgres-new/sw.ts | 86 ++++++++- package-lock.json | 34 ++++ 7 files changed, 464 insertions(+), 3 deletions(-) create mode 100644 apps/postgres-new/components/model/set-model-dialog.tsx create mode 100644 apps/postgres-new/components/ui/form.tsx diff --git a/apps/postgres-new/components/model/set-model-dialog.tsx b/apps/postgres-new/components/model/set-model-dialog.tsx new file mode 100644 index 00000000..55a86909 --- /dev/null +++ b/apps/postgres-new/components/model/set-model-dialog.tsx @@ -0,0 +1,130 @@ +'use client' + +import * as kv from 'idb-keyval' +import { useState } from 'react' +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from '~/components/ui/dialog' +import { Input } from '~/components/ui/input' +import { Button } from '../ui/button' +import { zodResolver } from '@hookform/resolvers/zod' +import { z } from 'zod' +import { useForm } from 'react-hook-form' +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '../ui/form' +import { Brain } from 'lucide-react' + +const formSchema = z.object({ + apiKey: z.string().min(1).optional(), + baseUrl: z.string().min(1), + model: z.string().min(1), +}) + +type FormSchema = z.infer + +function SetModelForm(props: { id: string; onSubmit: (values: FormSchema) => void }) { + const form = useForm({ + resolver: zodResolver(formSchema), + defaultValues: async () => { + const model = await kv.get('model') + return model + }, + }) + + async function onSubmit(values: z.infer) { + await kv.set('model', values) + props.onSubmit(values) + } + + return ( +
+ + ( + + Base URL + + + + + + )} + /> + ( + + API Key (optional) + + + + + + )} + /> + ( + + Model + + + + + + )} + /> + + + ) +} + +export type SetModelDialogProps = { + open: boolean + onOpenChange: (open: boolean) => void + onConfirm?: () => void +} + +export function SetModelDialog(props: SetModelDialogProps) { + return ( + + + + + Set an external model + + + You can set your own external model compatible with the OpenAI API. Your model + informations will be saved in your browser. + + +
+ { + props.onOpenChange(false) + }} + /> + + + + + +
+ ) +} diff --git a/apps/postgres-new/components/sidebar.tsx b/apps/postgres-new/components/sidebar.tsx index fd1fec09..b6c41ea7 100644 --- a/apps/postgres-new/components/sidebar.tsx +++ b/apps/postgres-new/components/sidebar.tsx @@ -5,6 +5,7 @@ import { AnimatePresence, m } from 'framer-motion' import { ArrowLeftToLine, ArrowRightToLine, + Brain, Database as DbIcon, Download, Loader, @@ -55,6 +56,7 @@ import { DropdownMenuSubTrigger, DropdownMenuTrigger, } from './ui/dropdown-menu' +import { SetModelDialog } from './model/set-model-dialog' export default function Sidebar() { const { @@ -70,6 +72,7 @@ export default function Sidebar() { let { id: currentDatabaseId } = useParams<{ id: string }>() const router = useRouter() const [showSidebar, setShowSidebar] = useState(true) + const [isSetModelDialogOpen, setIsSetModelDialogOpen] = useState(false) const { data: databases, isLoading: isLoadingDatabases } = useMergedDatabases() @@ -106,6 +109,7 @@ export default function Sidebar() { + {showSidebar && ( )} + + + @@ -267,6 +283,24 @@ export default function Sidebar() {
+ + + + + + + +

Set external model

+
+
diff --git a/apps/postgres-new/components/ui/form.tsx b/apps/postgres-new/components/ui/form.tsx new file mode 100644 index 00000000..37930795 --- /dev/null +++ b/apps/postgres-new/components/ui/form.tsx @@ -0,0 +1,178 @@ +"use client" + +import * as React from "react" +import * as LabelPrimitive from "@radix-ui/react-label" +import { Slot } from "@radix-ui/react-slot" +import { + Controller, + ControllerProps, + FieldPath, + FieldValues, + FormProvider, + useFormContext, +} from "react-hook-form" + +import { cn } from "~/lib/utils" +import { Label } from "~/components/ui/label" + +const Form = FormProvider + +type FormFieldContextValue< + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath +> = { + name: TName +} + +const FormFieldContext = React.createContext( + {} as FormFieldContextValue +) + +const FormField = < + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath +>({ + ...props +}: ControllerProps) => { + return ( + + + + ) +} + +const useFormField = () => { + const fieldContext = React.useContext(FormFieldContext) + const itemContext = React.useContext(FormItemContext) + const { getFieldState, formState } = useFormContext() + + const fieldState = getFieldState(fieldContext.name, formState) + + if (!fieldContext) { + throw new Error("useFormField should be used within ") + } + + const { id } = itemContext + + return { + id, + name: fieldContext.name, + formItemId: `${id}-form-item`, + formDescriptionId: `${id}-form-item-description`, + formMessageId: `${id}-form-item-message`, + ...fieldState, + } +} + +type FormItemContextValue = { + id: string +} + +const FormItemContext = React.createContext( + {} as FormItemContextValue +) + +const FormItem = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + const id = React.useId() + + return ( + +
+ + ) +}) +FormItem.displayName = "FormItem" + +const FormLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => { + const { error, formItemId } = useFormField() + + return ( +
- {showSidebar && ( )} - - - + @@ -283,24 +268,7 @@ export default function Sidebar() {
- - - - - - - -

Set external model

-
-
+ diff --git a/apps/postgres-new/sw.ts b/apps/postgres-new/sw.ts index b3eb703a..304425a8 100644 --- a/apps/postgres-new/sw.ts +++ b/apps/postgres-new/sw.ts @@ -3,19 +3,18 @@ import * as kv from 'idb-keyval' import { convertToCoreMessages, streamText, ToolInvocation } from 'ai' import { codeBlock } from 'common-tags' import { convertToCoreTools, maxMessageContext, maxRowLimit, tools } from './lib/tools' +import type { ModelProvider } from './components/model/use-model-provider' type Message = { role: 'user' | 'assistant' content: string toolInvocations?: (ToolInvocation & { result: any })[] } -export type {} + declare const self: ServiceWorkerGlobalScope async function handleRequest(event: FetchEvent) { - const externalModel = (await kv.get('model')) as - | { apiKey?: string; model: string; baseUrl: string } - | undefined + const externalModel = (await kv.get('modelProvider')) as ModelProvider | undefined const url = new URL(event.request.url) const isChatRoute = url.pathname === '/api/chat' && event.request.method === 'POST' From fb386c6bbb803a803873216d5192449ec4559a0c Mon Sep 17 00:00:00 2001 From: Julien Goux Date: Fri, 22 Nov 2024 11:05:33 +0100 Subject: [PATCH 07/24] renaming --- apps/postgres-new/components/app-provider.tsx | 2 +- .../set-model-provider-dialog.tsx} | 18 +++--- .../use-model-provider.ts | 0 .../set-external-model-provider-button.tsx | 17 ++++-- apps/postgres-new/components/ui/switch.tsx | 29 +++++++++ apps/postgres-new/package.json | 1 + apps/postgres-new/sw.ts | 2 +- package-lock.json | 60 +++++++++++++++++++ 8 files changed, 113 insertions(+), 16 deletions(-) rename apps/postgres-new/components/{model/set-model-dialog.tsx => model-provider/set-model-provider-dialog.tsx} (84%) rename apps/postgres-new/components/{model => model-provider}/use-model-provider.ts (100%) create mode 100644 apps/postgres-new/components/ui/switch.tsx diff --git a/apps/postgres-new/components/app-provider.tsx b/apps/postgres-new/components/app-provider.tsx index fbaeb58a..1198d746 100644 --- a/apps/postgres-new/components/app-provider.tsx +++ b/apps/postgres-new/components/app-provider.tsx @@ -32,7 +32,7 @@ import { import { legacyDomainHostname } from '~/lib/util' import { parse, serialize } from '~/lib/websocket-protocol' import { createClient } from '~/utils/supabase/client' -import { useModelProvider } from './model/use-model-provider' +import { useModelProvider } from './model-provider/use-model-provider' export type AppProps = PropsWithChildren diff --git a/apps/postgres-new/components/model/set-model-dialog.tsx b/apps/postgres-new/components/model-provider/set-model-provider-dialog.tsx similarity index 84% rename from apps/postgres-new/components/model/set-model-dialog.tsx rename to apps/postgres-new/components/model-provider/set-model-provider-dialog.tsx index 38ac2b91..a3bec0fe 100644 --- a/apps/postgres-new/components/model/set-model-dialog.tsx +++ b/apps/postgres-new/components/model-provider/set-model-provider-dialog.tsx @@ -25,7 +25,7 @@ const formSchema = z.object({ type FormSchema = z.infer -function SetModelForm(props: { id: string; onSubmit: (values: FormSchema) => void }) { +function SetModelProviderForm(props: { id: string; onSubmit: (values: FormSchema) => void }) { const { modelProvider } = useApp() const form = useForm({ @@ -85,28 +85,28 @@ function SetModelForm(props: { id: string; onSubmit: (values: FormSchema) => voi ) } -export type SetModelDialogProps = { +export type SetModelProviderDialogProps = { open: boolean onOpenChange: (open: boolean) => void onConfirm?: () => void } -export function SetModelDialog(props: SetModelDialogProps) { +export function SetModelProviderDialog(props: SetModelProviderDialogProps) { return ( - Set an external model + Set an external model provider - You can set your own external model compatible with the OpenAI API. Your model - informations will be saved in your browser. + You can set your own external model provider compatible with the OpenAI API. Your model + provider informations will be saved in your browser.
- { props.onOpenChange(false) }} @@ -120,7 +120,7 @@ export function SetModelDialog(props: SetModelDialogProps) { > Cancel - +
diff --git a/apps/postgres-new/components/model/use-model-provider.ts b/apps/postgres-new/components/model-provider/use-model-provider.ts similarity index 100% rename from apps/postgres-new/components/model/use-model-provider.ts rename to apps/postgres-new/components/model-provider/use-model-provider.ts diff --git a/apps/postgres-new/components/sidebar/set-external-model-provider-button.tsx b/apps/postgres-new/components/sidebar/set-external-model-provider-button.tsx index 15f3e43e..4f26fb88 100644 --- a/apps/postgres-new/components/sidebar/set-external-model-provider-button.tsx +++ b/apps/postgres-new/components/sidebar/set-external-model-provider-button.tsx @@ -3,7 +3,7 @@ import { Button } from '../ui/button' import { Brain } from 'lucide-react' import { useApp } from '../app-provider' import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip' -import { SetModelDialog } from '../model/set-model-dialog' +import { SetModelProviderDialog } from '../model-provider/set-model-provider-dialog' import { useState } from 'react' type SetExternalModelProviderButtonProps = { @@ -12,7 +12,7 @@ type SetExternalModelProviderButtonProps = { export function SetExternalModelProviderButton(props: SetExternalModelProviderButtonProps) { const { modelProvider } = useApp() - const [isSetModelDialogOpen, setIsSetModelDialogOpen] = useState(false) + const [isSetModelProviderDialogOpen, setIsSetModelProviderDialogOpen] = useState(false) const modelName = modelProvider.state?.model.split('/').at(-1) const text = modelName ?? 'Set external model' @@ -20,7 +20,11 @@ export function SetExternalModelProviderButton(props: SetExternalModelProviderBu - @@ -34,7 +38,7 @@ export function SetExternalModelProviderButton(props: SetExternalModelProviderBu
) : (
- {user ? ( + {!isAuthRequired ? ( <>
- {!user && !isLoadingUser && isConversationStarted && ( + {isAuthRequired && !isLoadingUser && isConversationStarted && ( { e.preventDefault() - if (!user) { + if (isAuthRequired) { return } diff --git a/apps/postgres-new/components/model-provider/set-model-provider-dialog.tsx b/apps/postgres-new/components/model-provider/set-model-provider-dialog.tsx index a3bec0fe..a42e2e22 100644 --- a/apps/postgres-new/components/model-provider/set-model-provider-dialog.tsx +++ b/apps/postgres-new/components/model-provider/set-model-provider-dialog.tsx @@ -16,11 +16,13 @@ import { useForm } from 'react-hook-form' import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '../ui/form' import { Brain } from 'lucide-react' import { useApp } from '../app-provider' +import { Switch } from '../ui/switch' const formSchema = z.object({ apiKey: z.string().min(1).optional(), baseUrl: z.string().min(1), model: z.string().min(1), + enabled: z.boolean().default(true), }) type FormSchema = z.infer @@ -41,6 +43,21 @@ function SetModelProviderForm(props: { id: string; onSubmit: (values: FormSchema return (
+ ( + +
+ + + + Enable +
+ +
+ )} + /> Date: Fri, 22 Nov 2024 11:35:59 +0100 Subject: [PATCH 09/24] build the sw before build next --- apps/postgres-new/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/postgres-new/package.json b/apps/postgres-new/package.json index 6f98ecc7..a1efd343 100644 --- a/apps/postgres-new/package.json +++ b/apps/postgres-new/package.json @@ -4,7 +4,7 @@ "private": true, "scripts": { "dev": "next dev", - "build": "next build", + "build": "npm run build:sw && next build", "build:sw": "vite build", "start": "next start", "lint": "next lint", From 39b91fdb90a9f6498df19340c2a38a8b14116637 Mon Sep 17 00:00:00 2001 From: Julien Goux Date: Fri, 22 Nov 2024 12:23:27 +0100 Subject: [PATCH 10/24] upgrade sdk --- apps/postgres-new/app/api/chat/route.ts | 2 +- .../components/sidebar/sidebar.tsx | 6 +- apps/postgres-new/components/workspace.tsx | 1 - apps/postgres-new/package.json | 4 +- apps/postgres-new/sw.ts | 10 +- package-lock.json | 633 ++---------------- 6 files changed, 79 insertions(+), 577 deletions(-) diff --git a/apps/postgres-new/app/api/chat/route.ts b/apps/postgres-new/app/api/chat/route.ts index 4a7a0b62..11d84e29 100644 --- a/apps/postgres-new/app/api/chat/route.ts +++ b/apps/postgres-new/app/api/chat/route.ts @@ -158,7 +158,7 @@ export async function POST(req: Request) { }, }) - return result.toAIStreamResponse() + return result.toDataStreamResponse() } function getEventToolResult(toolResult: ToolResultPart): ChatInferenceEventToolResult | undefined { diff --git a/apps/postgres-new/components/sidebar/sidebar.tsx b/apps/postgres-new/components/sidebar/sidebar.tsx index d42e1bc1..4f02ae13 100644 --- a/apps/postgres-new/components/sidebar/sidebar.tsx +++ b/apps/postgres-new/components/sidebar/sidebar.tsx @@ -67,11 +67,13 @@ export default function Sidebar() { setIsRenameDialogOpen, isLegacyDomain, liveShare, + modelProvider, } = useApp() let { id: currentDatabaseId } = useParams<{ id: string }>() const router = useRouter() const [showSidebar, setShowSidebar] = useState(true) const { data: databases, isLoading: isLoadingDatabases } = useMergedDatabases() + const isAuthRequired = user === undefined && modelProvider.state?.enabled !== true return ( <> @@ -141,7 +143,7 @@ export default function Sidebar() {