Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: installer populates vector store #76

Merged
merged 11 commits into from Mar 14, 2024
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

95 changes: 64 additions & 31 deletions src/client/pages/[locale]/installer/02.tsx
Expand Up @@ -56,7 +56,6 @@ function useInstallProgress() {
buildKey([ID.INSTALL], { suffix: ":completed" }),
() => {
setStatus(DownloadState.DONE);
window.ipc.send(buildKey([ID.APP], { suffix: ":ready" }), true);
}
);
const unsubscribeUnpacking = window.ipc.on(
Expand Down Expand Up @@ -179,6 +178,28 @@ export function InstallScreen({ percent, status }: { percent: number; status: Do
);
}

case DownloadState.DONE: {
return (
<InstallStep
heading={t("labels:installtionSuccess")}
illustration="/illustrations/minimalistic/discovery.svg"
>
<Box
sx={{
flex: 1,
position: "relative",
display: "flex",
alignItems: "center",
}}
>
<Typography level="body-lg" sx={{ my: 2, textAlign: "center" }}>
{t("texts:unpackingSuccess")}
</Typography>
</Box>
</InstallStep>
);
}

default: {
return null;
}
Expand All @@ -200,36 +221,48 @@ export default function Page(_properties: InferGetStaticPropsType<typeof getStat
{t("common:previous")}
</Button>
</I18nLink>
<Button
disabled={status !== DownloadState.IDLE}
data-testid="installer-02-start"
onClick={() => {
reset();

window.ipc.send(buildKey([ID.INSTALL], { suffix: ":start" }), [
{
url: "https://blibla-captain-assets.s3.eu-central-1.amazonaws.com/python-embedded-win.7z",
destination: "python-embedded",
size: "2.1 GB",
unzip: true,
},
{
url: "https://blibla-captain-assets.s3.eu-central-1.amazonaws.com/portable-git-win.7z",
destination: "portable-git",
size: "86.9 MB",
unzip: true,
},
{
url: "https://blibla-captain-assets.s3.eu-central-1.amazonaws.com/qdrant-win.7z",
destination: "qdrant",
size: "13.9 MB",
unzip: true,
},
]);
}}
>
{t("installer:install")}
</Button>
{status === DownloadState.DONE ? (
<I18nLink href="/installer/03">
<Button component="a">{t("common:next")}</Button>
</I18nLink>
) : (
<Button
disabled={status !== DownloadState.IDLE}
data-testid="installer-02-start"
onClick={() => {
reset();

window.ipc.send(buildKey([ID.INSTALL], { suffix: ":start" }), [
{
url: "https://blibla-captain-assets.s3.eu-central-1.amazonaws.com/python-embedded-win.7z",
destination: "python-embedded",
size: "2.1 GB",
unzip: true,
},
{
url: "https://blibla-captain-assets.s3.eu-central-1.amazonaws.com/portable-git-win.7z",
destination: "portable-git",
size: "86.9 MB",
unzip: true,
},
{
url: "https://blibla-captain-assets.s3.eu-central-1.amazonaws.com/all-MiniLM-L6-v2.7z",
destination: "downloads/llm/embeddings/Xenova",
size: "15.3 MB",
unzip: true,
},
{
url: "https://blibla-captain-assets.s3.eu-central-1.amazonaws.com/qdrant-win.7z",
destination: "qdrant",
size: "13.9 MB",
unzip: true,
},
]);
}}
>
{t("installer:install")}
</Button>
)}
</Box>
</Box>
</Box>
Expand Down
165 changes: 165 additions & 0 deletions src/client/pages/[locale]/installer/03.tsx
@@ -0,0 +1,165 @@
import { AppFrame } from "@captn/joy/app-frame";
import { TitleBar } from "@captn/joy/title-bar";
import Alert from "@mui/joy/Alert";
import Box from "@mui/joy/Box";
import Button from "@mui/joy/Button";
import CircularProgress from "@mui/joy/CircularProgress";
import Input from "@mui/joy/Input";
import Typography from "@mui/joy/Typography";
import type { InferGetStaticPropsType } from "next";
import { useTranslation } from "next-i18next";
import { useEffect, useState } from "react";

import { buildKey } from "#/build-key";
import { ID } from "#/enums";
import { Captain } from "@/atoms/logo/captain";
import { makeStaticProperties } from "@/ions/i18n/get-static";

function DummyPrompt() {
const { t } = useTranslation(["labels", "texts"]);
return (
<Box
sx={{
position: "relative",
fontSize: 24,
my: "1em",
mx: 1,
overflow: "hidden",
boxShadow: "md",
}}
>
<Input
readOnly
placeholder={t("labels:placeholder.prompt")}
endDecorator={
<Box
sx={{
flex: 1,
display: "flex",
alignItems: "center",
justifyContent: "center",
height: 44,
width: 44,
}}
>
<Captain sx={{ height: "100%" }} />
</Box>
}
sx={{
fontSize: "inherit",
lineHeight: 1.25,
p: 2,
flexDirection: "row",
}}
/>
</Box>
);
}

export default function Page(_properties: InferGetStaticPropsType<typeof getStaticProps>) {
const { t } = useTranslation(["labels", "texts"]);
const [loading, setLoading] = useState(true);
const [starting, setStarting] = useState(false);
const [error, setError] = useState(null);

let buttonText;

useEffect(() => {
const unsubscribeInitialized = window.ipc.on(
buildKey([ID.INSTALL], { suffix: ":initialized" }),
() => {
setLoading(false);
setError(null);
}
);

const unsubscribeError = window.ipc.on(
buildKey([ID.INSTALL], { suffix: ":error" }),
error => {
setLoading(false);
setError(error);
}
);

window.ipc.send(buildKey([ID.INSTALL], { suffix: ":initialize" }));

return () => {
unsubscribeInitialized();
unsubscribeError();
};
}, []);

if (loading) {
buttonText = t("labels:preparation");
} else if (starting) {
buttonText = t("labels:starting");
} else {
buttonText = t("labels:start");
}

return (
<AppFrame titleBar={<TitleBar disableMaximize />}>
<Box sx={{ minHeight: "100%", display: "flex", flexDirection: "column" }}>
<Box sx={{ height: 200, alignContent: "center", px: 2 }}>
<DummyPrompt />
</Box>

<Typography level="h1" sx={{ my: 2, textAlign: "center" }}>
{t("labels:finishing")}
</Typography>

<Box
sx={{
flex: 1,
display: "flex",
flexDirection: "column",
justifyContent: "center",
mx: 8,
}}
>
<Box
sx={{
display: "flex",
p: 2,
backgroundColor: "background.default",
borderRadius: "8px",
flexDirection: "column",
}}
>
<Typography level="body-lg" sx={{ my: 2, textAlign: "center" }}>
{t("texts:howToUseCaptain")}
</Typography>

{error ? (
<Alert color="danger">{error}</Alert>
) : (
<Typography level="body-lg" sx={{ my: 2, textAlign: "center" }}>
{loading ? t("texts:preparation") : t("texts:preparationDone")}
</Typography>
)}
</Box>
</Box>

<Box sx={{ display: "flex", justifyContent: "flex-end", m: 1 }}>
<Box sx={{ display: "flex", gap: 1 }}>
<Button
endDecorator={
loading || starting ? <CircularProgress size="sm" /> : null
}
onClick={() => {
setStarting(true);
window.ipc.send(buildKey([ID.APP], { suffix: ":ready" }), true);
}}
>
{buttonText}
</Button>
</Box>
</Box>
</Box>
</AppFrame>
);
}

export const getStaticProps = makeStaticProperties(["common", "installer", "texts", "labels"]);

export { getStaticPaths } from "@/ions/i18n/get-static";
9 changes: 7 additions & 2 deletions src/client/public/locales/de/labels.json
Expand Up @@ -12,6 +12,7 @@
"delete": "Löschen",
"deleted": "Gelöscht",
"downloading": "Herunterladen",
"finishing": "Abschluss",
"formLabel": {
"characters": "Charaktere",
"customStyle": "Eigener Stil",
Expand All @@ -29,6 +30,7 @@
"manga": "Manga",
"realism": "Realismus"
},
"installtionSuccess": "Installation fertig",
"length": {
"long": "Lang",
"medium": "Mittel",
Expand All @@ -47,8 +49,10 @@
"overlay": "Überlagerung",
"placeholder": {
"characters": "Der Name des Jungen ist Erin und sein Hund heißt Ruffy",
"customStyle": "Die Geschichte sollte skurril und sehr lustig sein, ein Mysterium ohne Abschluss beinhalten"
"customStyle": "Die Geschichte sollte skurril und sehr lustig sein, ein Mysterium ohne Abschluss beinhalten",
"prompt": "Ich möchte ein Bild malen"
},
"preparation": "Captain wird vorbereitet",
"privacy": "Datenschutz",
"prompt": "Prompt",
"promptInfo": "Der Prompt sollte in Englisch geschrieben werden.",
Expand All @@ -61,7 +65,8 @@
"security": "Sicherheit",
"sideBySide": "Nebeneinander",
"start": "Start",
"stop": "Stop",
"starting": "Captain wird gestartet",
"stop": "Stopp",
"style": {
"adventure": "Abenteuer",
"custom": "Eigener",
Expand Down
6 changes: 5 additions & 1 deletion src/client/public/locales/de/texts.json
@@ -1,10 +1,14 @@
{
"analyzingImages": "Bleib dran! Wir analysieren gerade die von dir bereitgestellten Bilder, um die perfekte Geschichte darum zu weben. Dieser Prozess nutzt fortschrittliche KI-Algorithmen, um den Kontext und die Elemente in deinen Bildern zu verstehen und eine Erzählung zu gewährleisten, die wirklich mit den Bildern harmoniert. Abhängig von der Komplexität und Anzahl der Bilder kann dies einige Minuten dauern. Wir schätzen deine Geduld. Mach dich bereit, von den Geschichten, die unsere KI speziell für dich kreieren kann, erstaunt zu werden.",
"downloadSuccessUnpacking": "Download erfolgreich! Jetzt packen wir diesen Schatz der Technologie aus.",
"howToUseCaptain": "Captain kannst du ganz einfach über den Prompt steuern, welchen du mit der Tastenkombination Strg + Alt + Leertaste jederzeit öffnen kannst. Schreibe dann einfach, was du machen möchtest und wir erledigen den Rest.",
"preparation": "Damit der Prompt funktioniert, bereiten wir noch kurz alles vor.",
"preparationDone": "Alle Vorbereitungen sind abgeschlossen! Viel Spaß mit Captain.",
"quote1": "Wie Menschen träumen KIs auch von elektrischen Schafen. Zzz...",
"quote2": "Ich lerne neue Dinge! Wusstest du, dass ich keinen Kaffee genießen kann? Aber ich kann helfen, einen zu brauen!",
"quote3": "Wenn du denkst, eine Minute vergeht wirklich schnell, warst du noch nie in den 'letzten Sekunden' eines Downloads.",
"quote4": "Mit KI zu arbeiten ist wie einen Freund zu haben, der fast alles weiß, aber immer noch nicht seine Schuhe binden kann.",
"quote5": "Ich bat eine KI um einen Witz. Sie sagte: 'Ich könnte dir einen UDP-Witz erzählen, aber du verstehst ihn vielleicht nicht.'",
"storyFormIntroduction": "Willkommen zu unserem Tool zur Geschichtsanpassung! Nachdem du deine Visionen mit unserem KI-gestützten Malwerkzeug zum Leben erweckt hast, ist es nun an der Zeit, Geschichten um deine Kreationen zu weben. Wähle unten deine Präferenzen, um die Geschichte zu formen, die am besten zu deinem Meisterwerk passt. Ob du eine kurze und süße Erzählung wünschst, eine mittellange Reise ins Fantastische oder einen tiefen Tauchgang in die Reiche des Unbekannten, wir sind hier, um deine Geschichte zum Leben zu erwecken. Wähle deinen Erzählstil, setze den emotionalen Ton und lass uns gemeinsam eine magische Geschichte erschaffen."
"storyFormIntroduction": "Willkommen zu unserem Tool zur Geschichtsanpassung! Nachdem du deine Visionen mit unserem KI-gestützten Malwerkzeug zum Leben erweckt hast, ist es nun an der Zeit, Geschichten um deine Kreationen zu weben. Wähle unten deine Präferenzen, um die Geschichte zu formen, die am besten zu deinem Meisterwerk passt. Ob du eine kurze und süße Erzählung wünschst, eine mittellange Reise ins Fantastische oder einen tiefen Tauchgang in die Reiche des Unbekannten, wir sind hier, um deine Geschichte zum Leben zu erwecken. Wähle deinen Erzählstil, setze den emotionalen Ton und lass uns gemeinsam eine magische Geschichte erschaffen.",
"unpackingSuccess": "Super, alles wurde installiert. Du hast es fast geschafft."
}
9 changes: 7 additions & 2 deletions src/client/public/locales/en/labels.json
Expand Up @@ -12,6 +12,7 @@
"delete": "Delete",
"deleted": "Deleted",
"downloading": "Downloading",
"finishing": "Finishing",
"formLabel": {
"characters": "Characters",
"customStyle": "Custom Style",
Expand All @@ -29,6 +30,7 @@
"manga": "Manga",
"realism": "Realism"
},
"installationSuccess": "Installation complete",
"length": {
"long": "Long",
"medium": "Medium",
Expand All @@ -46,9 +48,11 @@
},
"overlay": "Overlay",
"placeholder": {
"characters": "The boy's name is Erin and his dog's name is Ruffy",
"customStyle": "The story should be quirky and very funny, include a mystery without closure"
"characters": "The boys's name is Erin and his dog's name is Ruffy",
"customStyle": "The story should be quirky and very funny, include a mystery without closure",
"prompt": "I want to paint a picture"
},
"preparation": "Captain is being prepared",
"privacy": "Privacy",
"prompt": "Prompt",
"promptInfo": "The prompt should be written in English.",
Expand All @@ -61,6 +65,7 @@
"security": "Security",
"sideBySide": "Side by Side",
"start": "Start",
"starting": "Captain is starting",
"stop": "Stop",
"style": {
"adventure": "Adventure",
Expand Down