diff --git a/.env.dev.example b/.env.dev.example
new file mode 100644
index 00000000000..98c548324c9
--- /dev/null
+++ b/.env.dev.example
@@ -0,0 +1,11 @@
+# .env for docker-compose.dev.yaml
+
+# False = no login screen, the developer is automatically logged in upon opening the root
+WEBUI_AUTH=False
+# Set this to an arbitrary random string if WEBUI_AUTH=True
+WEBUI_SECRET_KEY="< generate some random string >"
+
+# DO NOT TRACK
+SCARF_NO_ANALYTICS=true
+DO_NOT_TRACK=true
+ANONYMIZED_TELEMETRY=false
diff --git a/.gitignore b/.gitignore
index 32271f8087e..8901e1dc42e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@ node_modules
.env
.env.*
!.env.example
+!.env.dev.example
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
# Byte-compiled / optimized / DLL files
diff --git a/Dockerfile b/Dockerfile
index 274e23dbfc7..c61ddd4b020 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -31,6 +31,10 @@ RUN npm ci
COPY . .
ENV APP_BUILD_HASH=${BUILD_HASH}
+# Necessary on some systems, maybe only for Podman otherwise the build fails with
+# FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
+ENV NODE_OPTIONS=--max-old-space-size=3100
+RUN echo "PUBLIC_FEEDBACK_BASE_URL=" > .env
RUN npm run build
######## WebUI backend ########
diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py
index a5adbb0f170..41aae2ffbe4 100644
--- a/backend/open_webui/config.py
+++ b/backend/open_webui/config.py
@@ -827,6 +827,8 @@ def load_oauth_providers():
"WEBHOOK_URL", "webhook_url", os.environ.get("WEBHOOK_URL", "")
)
+ENABLE_MODEL_INFOS = os.environ.get("ENABLE_MODEL_INFOS", "True").lower() == "true"
+
ENABLE_ADMIN_EXPORT = os.environ.get("ENABLE_ADMIN_EXPORT", "True").lower() == "true"
ENABLE_ADMIN_CHAT_ACCESS = (
diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py
index c145ca1b82a..8925ec10fc7 100644
--- a/backend/open_webui/main.py
+++ b/backend/open_webui/main.py
@@ -72,6 +72,7 @@
DEFAULT_LOCALE,
ENABLE_ADMIN_CHAT_ACCESS,
ENABLE_ADMIN_EXPORT,
+ ENABLE_MODEL_INFOS,
ENABLE_OLLAMA_API,
ENABLE_OPENAI_API,
ENABLE_TAGS_GENERATION,
@@ -2439,6 +2440,7 @@ async def get_app_config(request: Request):
"enable_message_rating": webui_app.state.config.ENABLE_MESSAGE_RATING,
"enable_admin_export": ENABLE_ADMIN_EXPORT,
"enable_admin_chat_access": ENABLE_ADMIN_CHAT_ACCESS,
+ "enable_model_infos": ENABLE_MODEL_INFOS,
}
if user is not None
else {}
diff --git a/backend/open_webui/static/favicon.png b/backend/open_webui/static/favicon.png
index 2b207478084..169948c2859 100644
Binary files a/backend/open_webui/static/favicon.png and b/backend/open_webui/static/favicon.png differ
diff --git a/docker-compose.dev.yaml b/docker-compose.dev.yaml
new file mode 100644
index 00000000000..42e0e6f6f79
--- /dev/null
+++ b/docker-compose.dev.yaml
@@ -0,0 +1,42 @@
+name: open-webui-dev
+
+services:
+ frontend:
+ build:
+ context: .
+ target: build
+ command: ["sh", "/app/src/frontend-dev.sh"]
+ env_file: ".env"
+ depends_on:
+ - backend
+ ports:
+ - "3000:5173"
+ extra_hosts:
+ - host.docker.internal:127.0.0.1
+ volumes:
+ - ./src:/app/src
+ - ./package.json:/app/package.json
+ - ./package-lock.json:/app/package-lock.json
+ - ./vite.config.ts:/app/vite.config.ts
+ - ./svelte.config.js:/app/svelte.config.js
+ - ./tsconfig.json:/app/tsconfig.json
+ - ./tailwind.config.js:/app/tailwind.config.js
+
+ backend:
+ build:
+ context: .
+ target: base
+ command: ["bash", "dev.sh"]
+ env_file: ".env"
+ environment:
+ - ENV=dev
+ ports:
+ - "8080:8080"
+ extra_hosts:
+ - host.docker.internal:127.0.0.1
+ volumes:
+ - ./backend:/app/backend
+ - data:/app/backend/data
+
+volumes:
+ data: {}
diff --git a/src/app.css b/src/app.css
index 9d073d05ded..d3a73992990 100644
--- a/src/app.css
+++ b/src/app.css
@@ -61,7 +61,7 @@ math {
}
.font-primary {
- font-family: 'Archivo', sans-serif;
+ font-family: var(--default-font-regular, 'OpenSansSemibold', arial, sans-serif);
}
iframe {
@@ -215,3 +215,7 @@ input[type='number'] {
@apply absolute inset-0 z-0 text-gray-500;
}
+
+body {
+ background-color: var(--primary-background-color);
+}
diff --git a/src/app.html b/src/app.html
index f6e46c9cfbe..c35eebb6715 100644
--- a/src/app.html
+++ b/src/app.html
@@ -28,6 +28,9 @@
+
+
+
+
+
+ {#if !feedbackSent}
+
+ {$i18n.t('Feedback', { ns: 'ionos' })}
+
+
+ {$i18n.t('Pass on your impressions, suggestions etc. to us...', { ns: 'ionos' })}
+
+
+
+
+ {#if noRating}
+
+
{$i18n.t('General evaluation', { ns: 'ionos' })}
+ {#each Array(5) as _, index}
+
(rating = index + 1)}
+ on:mouseover={() => (hoveredRating = index + 1)}
+ on:mouseout={() => (hoveredRating = undefined)}
+ on:focus={() => (hoveredRating = index + 1)}
+ on:blur={() => (hoveredRating = undefined)}
+ class:filled={index < (hoveredRating ?? rating ?? 0)}
+ >
+
+
+ {/each}
+
+ {/if}
+
+
+
+ {/if}
+
+ {#if feedbackSent}
+ {#await postFeedback(feedbackText, rating)}
+
+ {:then}
+
+ {$i18n.t('Thanks!', { ns: 'ionos' })}
+
+
+
+
+
+ {$i18n.t('We have received your feedback', { ns: 'ionos' })}
+
+
+
+
+ {:catch}
+
+
+ {$i18n.t('Something went wrong', { ns: 'ionos' })}
+
+
+
+
+
+ {$i18n.t('Feedback could not be sent', { ns: 'ionos' })}
+
+
+
+
+ {/await}
+ {/if}
+
+
+
+
diff --git a/src/lib/IONOS/components/IonosFooter.svelte b/src/lib/IONOS/components/IonosFooter.svelte
new file mode 100644
index 00000000000..3c3bf176828
--- /dev/null
+++ b/src/lib/IONOS/components/IonosFooter.svelte
@@ -0,0 +1,106 @@
+
+
+
+
+
diff --git a/src/lib/IONOS/components/IonosHeader.svelte b/src/lib/IONOS/components/IonosHeader.svelte
new file mode 100644
index 00000000000..b29fe24b7d1
--- /dev/null
+++ b/src/lib/IONOS/components/IonosHeader.svelte
@@ -0,0 +1,95 @@
+
+
+
+
+
diff --git a/src/lib/IONOS/components/IonosHelp.svelte b/src/lib/IONOS/components/IonosHelp.svelte
new file mode 100644
index 00000000000..e52b40cf3dd
--- /dev/null
+++ b/src/lib/IONOS/components/IonosHelp.svelte
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+ {$i18n.t('Further information', { ns: 'ionos' })}
+
+
+
diff --git a/src/lib/IONOS/components/IonosRegister.svelte b/src/lib/IONOS/components/IonosRegister.svelte
new file mode 100644
index 00000000000..0526bcc5d50
--- /dev/null
+++ b/src/lib/IONOS/components/IonosRegister.svelte
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+ {#if !registrationSent}
+
+ {$i18n.t('Stay informed', { ns: 'ionos' })}
+
+
+
+ {$i18n.t(
+ 'We are still working on it and will keep you up to date when there is news. Just give us your email address',
+ { ns: 'ionos' }
+ )}
+
+
+
+ Email
+
+
+
+
+
+
+ {:else}
+ {#await postRegistration(mailInput)}
+
+ {:then}
+
+ {$i18n.t('Vielen Dank!', { ns: 'ionos' })}
+
+
+
+
+ {$i18n.t('The e-mail address has been saved', { ns: 'ionos' })}
+
+
+
+
+ {:catch}
+
+
+ {$i18n.t('Something went wrong', { ns: 'ionos' })}
+
+
+
+
+
+ {$i18n.t('Your e-mail address could not be saved', { ns: 'ionos' })}
+
+
+
+
+ {/await}
+ {/if}
+
+
diff --git a/src/lib/IONOS/components/ModelIcons.svelte b/src/lib/IONOS/components/ModelIcons.svelte
new file mode 100644
index 00000000000..170bea6f212
--- /dev/null
+++ b/src/lib/IONOS/components/ModelIcons.svelte
@@ -0,0 +1,150 @@
+
+
+{#if selectedModel === Models.CHAT}
+
+
+
+
+
+
+
+
+
+
+
+
+
+{:else if selectedModel === Models.CODE}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{:else if selectedModel === Models.IMAGE}
+
+
+
+
+
+
+
+
+
+
+
+
+{:else if selectedModel === Models.TEXT}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{/if}
diff --git a/src/lib/IONOS/components/ModelSelector.svelte b/src/lib/IONOS/components/ModelSelector.svelte
new file mode 100644
index 00000000000..225c992d182
--- /dev/null
+++ b/src/lib/IONOS/components/ModelSelector.svelte
@@ -0,0 +1,45 @@
+
+
+
+
+
diff --git a/src/lib/IONOS/components/SendMessageButton.svelte b/src/lib/IONOS/components/SendMessageButton.svelte
new file mode 100644
index 00000000000..741ed6e20d9
--- /dev/null
+++ b/src/lib/IONOS/components/SendMessageButton.svelte
@@ -0,0 +1,45 @@
+
+
+
+
+
diff --git a/src/lib/IONOS/components/Suggestions.svelte b/src/lib/IONOS/components/Suggestions.svelte
new file mode 100644
index 00000000000..e1cd56e0447
--- /dev/null
+++ b/src/lib/IONOS/components/Suggestions.svelte
@@ -0,0 +1,63 @@
+
+
+
+ {#each promptSelection as prompt, promptIdx}
+
(hoveredId = promptIdx)}
+ on:mouseleave={() => (hoveredId = null)}
+ >
+
{
+ dispatch('select', { prompt: prompt.content, model: prompt.model, modelName: prompt.modelName });
+ }}
+ >
+
+ {prompt.description}
+ {prompt.detail}
+
+
+
+ {/each}
+
+
+
diff --git a/src/lib/IONOS/components/Trailer.svelte b/src/lib/IONOS/components/Trailer.svelte
new file mode 100644
index 00000000000..d32cfdb9895
--- /dev/null
+++ b/src/lib/IONOS/components/Trailer.svelte
@@ -0,0 +1,8 @@
+
+
+
+
{$i18n.t("By sending messages to IONOS GPT, you agree to our terms and conditions and confirm that you have read our privacy policy.", { ns: "ionos" })}
+
diff --git a/src/lib/IONOS/components/ionos-variables.css b/src/lib/IONOS/components/ionos-variables.css
new file mode 100644
index 00000000000..931c9a2ce23
--- /dev/null
+++ b/src/lib/IONOS/components/ionos-variables.css
@@ -0,0 +1,365 @@
+:root,
+[data-exos-theme='ionos'] {
+ --default-font-regular: "OpenSansRegular",arial,arial narrow,sans-serif;
+ --default-font-bold: "OpenSansSemibold",arial,sans-serif;
+ --corporate-font-regular: "OverpassRegular",arial,arial narrow,sans-serif;
+ --corporate-font-bold: "OverpassSemibold",arial,sans-serif;
+ --default-text-size: 14px;
+ --default-text-line-height: 20px;
+ --large-text-size: 16px;
+ --large-text-line-height: 22px;
+ --small-text-size: 12px;
+ --small-text-line-height: 18px;
+ --default-border-radius: 16px;
+ --small-border-radius: 8px;
+ --xsmall-border-radius: 4px;
+ --xxsmall-border-radius: 2px;
+ --default-border-width: 1px;
+ --thick-border-width: 2px;
+ --button-font-size: var(--default-text-size);
+ --button-border-width: 2px;
+ --button-border-radius: 24px;
+ --button-padding: 4px 20px;
+ --palette-black: #000;
+ --palette-white: #fff;
+ --palette-corporate-1: #dbedf8;
+ --palette-corporate-2: #95caeb;
+ --palette-corporate-3: #3196d6;
+ --palette-corporate-4: #1474c4;
+ --palette-corporate-5: #095bb1;
+ --palette-corporate-6: #003d8f;
+ --palette-corporate-7: #0b2a63;
+ --palette-corporate-8: #001b41;
+ --palette-corporate-9: #02102b;
+ --palette-success-1: #c7fae2;
+ --palette-success-2: #46efa0;
+ --palette-success-3: #12cf76;
+ --palette-success-4: #0fa954;
+ --palette-success-5: #0c8a44;
+ --palette-success-6: #096b35;
+ --palette-success-7: #074d26;
+ --palette-warning-1: #ffedca;
+ --palette-warning-2: #ffd176;
+ --palette-warning-3: #fa0;
+ --palette-warning-4: #ef8300;
+ --palette-warning-5: #c36b00;
+ --palette-warning-6: #8e4e00;
+ --palette-warning-7: #603500;
+ --palette-critical-1: #ffe4e2;
+ --palette-critical-2: #ffa8a3;
+ --palette-critical-3: #ff6159;
+ --palette-critical-4: #f50c00;
+ --palette-critical-5: #c80a00;
+ --palette-critical-6: #9c0800;
+ --palette-critical-7: #6e0500;
+ --palette-neutral-1: #f4f7fa;
+ --palette-neutral-2: #dbe2e8;
+ --palette-neutral-3: #bcc8d4;
+ --palette-neutral-4: #97a3b4;
+ --palette-neutral-5: #718095;
+ --palette-neutral-6: #465a75;
+ --palette-neutral-7: #2e4360;
+ --palette-neutral-8: #1d2d42;
+ --palette-neutral-9: #0a121c;
+ --palette-activating-1: #d2f6fc;
+ --palette-activating-2: #7fe4f6;
+ --palette-activating-3: #11c7e6;
+ --palette-activating-4: #08a5c5;
+ --palette-activating-5: #007e9c;
+ --palette-activating-6: #005b72;
+ --palette-activating-7: #003d4b;
+ --palette-promoting-1: #fae7fe;
+ --palette-promoting-2: #f0b7fb;
+ --palette-promoting-3: #e480f8;
+ --palette-promoting-4: #d746f5;
+ --palette-promoting-5: #b410e7;
+ --palette-promoting-6: #8212c2;
+ --palette-promoting-7: #560e8a;
+ --black: var(--palette-black);
+ --white: var(--palette-white);
+ --primary-text-color: var(--palette-corporate-9);
+ --default-text-color: var(--palette-corporate-8);
+ --secondary-text-color: var(--palette-neutral-6);
+ --tertiary-text-color: var(--palette-neutral-5);
+ --primary-text-color-inverted: var(--palette-neutral-1);
+ --default-text-color-inverted: var(--palette-neutral-2);
+ --secondary-text-color-inverted: var(--palette-neutral-3);
+ --primary-shape-color: var(--palette-neutral-7);
+ --default-shape-color: var(--palette-neutral-6);
+ --secondary-shape-color: var(--palette-neutral-5);
+ --tertiary-shape-color: var(--palette-neutral-3);
+ --primary-background-color: var(--palette-white);
+ --default-background-color: var(--palette-neutral-1);
+ --secondary-background-color: var(--palette-white);
+ --tertiary-background-color: var(--palette-neutral-3);
+ --quaternary-background-color: var(--palette-neutral-4);
+ --primary-background-color-inverted: var(--palette-corporate-8);
+ --default-background-color-inverted: var(--palette-corporate-7);
+ --secondary-background-color-inverted: var(--palette-neutral-6);
+ --tertiary-background-color-inverted: var(--palette-neutral-5);
+ --success-text-color: var(--palette-success-6);
+ --success-shape-color: var(--palette-success-4);
+ --caution-text-color: var(--palette-warning-4);
+ --caution-shape-color: var(--palette-warning-2);
+ --warning-text-color: var(--palette-warning-5);
+ --warning-shape-color: var(--palette-warning-3);
+ --critical-text-color: var(--palette-critical-5);
+ --critical-shape-color: var(--palette-critical-4);
+ --neutral-text-color: var(--palette-neutral-6);
+ --neutral-shape-color: var(--palette-neutral-5);
+ --activating-text-color: var(--palette-activating-5);
+ --activating-shape-color: var(--palette-activating-3);
+ --promoting-text-color: var(--palette-promoting-7);
+ --promoting-shape-color: var(--palette-promoting-5);
+ --corporate-text-color: var(--palette-corporate-7);
+ --corporate-shape-color: var(--palette-corporate-8);
+ --inactive-success-text-color: var(--palette-success-3);
+ --inactive-success-shape-color: var(--palette-success-3);
+ --inactive-warning-text-color: var(--palette-warning-2);
+ --inactive-warning-shape-color: var(--palette-warning-2);
+ --inactive-critical-text-color: var(--palette-critical-2);
+ --inactive-critical-shape-color: var(--palette-critical-2);
+ --inactive-neutral-text-color: var(--palette-neutral-3);
+ --inactive-neutral-shape-color: var(--palette-neutral-3);
+ --inactive-activating-text-color: var(--palette-activating-2);
+ --inactive-activating-shape-color: var(--palette-activating-2);
+ --inactive-promoting-text-color: var(--palette-promoting-2);
+ --inactive-promoting-shape-color: var(--palette-promoting-2);
+ --inactive-corporate-text-color: var(--palette-corporate-2);
+ --inactive-corporate-shape-color: var(--palette-corporate-2);
+ --solid-success-background-color: var(--palette-success-3);
+ --solid-caution-background-color: var(--palette-warning-2);
+ --solid-warning-background-color: var(--palette-warning-3);
+ --solid-critical-background-color: var(--palette-critical-3);
+ --solid-neutral-background-color: var(--palette-neutral-6);
+ --solid-activating-background-color: var(--palette-activating-3);
+ --solid-promoting-background-color: var(--palette-promoting-3);
+ --solid-corporate-background-color: var(--palette-corporate-7);
+ --solid-bright-background-color: var(--palette-white);
+ --success-background-color: var(--palette-white);
+ --hovered-success-background-color: var(--palette-success-1);
+ --warning-background-color: var(--palette-white);
+ --hovered-warning-background-color: var(--palette-warning-1);
+ --critical-background-color: var(--palette-white);
+ --hovered-critical-background-color: var(--palette-critical-1);
+ --neutral-background-color: var(--palette-white);
+ --hovered-neutral-background-color: var(--palette-neutral-1);
+ --activating-background-color: var(--palette-white);
+ --hovered-activating-background-color: var(--palette-activating-1);
+ --promoting-background-color: var(--palette-white);
+ --hovered-promoting-background-color: var(--palette-promoting-1);
+ --corporate-background-color: var(--palette-white);
+ --hovered-corporate-background-color: var(--palette-corporate-1);
+ --advertising-background-gradient-start: var(--palette-corporate-6);
+ --advertising-background-gradient-end: var(--palette-corporate-4);
+ --hovered-advertising-background-gradient-start: var(--palette-corporate-8);
+ --hovered-advertising-background-gradient-end: var(--palette-corporate-6);
+ --interactive-text-color: var(--palette-corporate-4);
+ --interactive-shape-color: var(--palette-corporate-4);
+ --hovered-interactive-text-color: var(--palette-corporate-5);
+ --default-shadow-color: #71809580;
+ --default-shadow: 0 1px 2px 0 var(--default-shadow-color);
+ --primary-shadow: 0 2px 8px 0 var(--default-shadow-color);
+ --secondary-shadow: 0 1px 0 0 var(--default-shadow-color);
+ --semantic-container-border-width: 0;
+ --semantic-section-border-width: var(--thick-border-width);
+ --semantic-section-border-overlapping-margin: -1px 0 0 0;
+ --primary-button-background-color: var(--palette-corporate-7);
+ --primary-button-border-color: var(--palette-corporate-7);
+ --primary-button-text-color: var(--palette-white);
+ --hovered-primary-button-background-color: var(--palette-corporate-4);
+ --hovered-primary-button-border-color: var(--palette-corporate-4);
+ --hovered-primary-button-text-color: var(--palette-white);
+ --bright-primary-button-background-color: var(--palette-white);
+ --bright-primary-button-border-color: var(--palette-white);
+ --bright-primary-button-text-color: var(--palette-corporate-7);
+ --hovered-bright-primary-button-background-color: var(--palette-corporate-2);
+ --hovered-bright-primary-button-border-color: var(--palette-corporate-2);
+ --hovered-bright-primary-button-text-color: var(--palette-corporate-7);
+ --activating-primary-button-background-color: var(--palette-activating-3);
+ --activating-primary-button-border-color: var(--palette-activating-3);
+ --activating-primary-button-text-color: var(--palette-corporate-7);
+ --hovered-activating-primary-button-background-color: var(--palette-activating-2);
+ --hovered-activating-primary-button-border-color: var(--palette-activating-2);
+ --hovered-activating-primary-button-text-color: var(--palette-corporate-7);
+ --promoting-primary-button-background-color: var(--palette-promoting-3);
+ --promoting-primary-button-border-color: var(--palette-promoting-3);
+ --promoting-primary-button-text-color: var(--palette-white);
+ --hovered-promoting-primary-button-background-color: var(--palette-promoting-2);
+ --hovered-promoting-primary-button-border-color: var(--palette-promoting-2);
+ --hovered-promoting-primary-button-text-color: var(--palette-white);
+ --disabled-primary-button-background-color: var(--palette-neutral-4);
+ --disabled-primary-button-border-color: var(--palette-neutral-4);
+ --disabled-primary-button-text-color: var(--palette-white);
+ --secondary-button-background-color: #0000;
+ --secondary-button-border-color: var(--palette-corporate-7);
+ --secondary-button-text-color: var(--palette-corporate-7);
+ --hovered-secondary-button-background-color: var(--palette-corporate-7);
+ --hovered-secondary-button-border-color: var(--palette-corporate-7);
+ --hovered-secondary-button-text-color: var(--palette-white);
+ --bright-secondary-button-background-color: #0000;
+ --bright-secondary-button-border-color: var(--palette-white);
+ --bright-secondary-button-text-color: var(--palette-white);
+ --hovered-bright-secondary-button-background-color: var(--palette-white);
+ --hovered-bright-secondary-button-border-color: var(--palette-white);
+ --hovered-bright-secondary-button-text-color: var(--palette-corporate-7);
+ --activating-secondary-button-background-color: #0000;
+ --activating-secondary-button-border-color: var(--palette-activating-3);
+ --activating-secondary-button-text-color: var(--palette-activating-3);
+ --hovered-activating-secondary-button-background-color: var(--palette-activating-3);
+ --hovered-activating-secondary-button-border-color: var(--palette-activating-3);
+ --hovered-activating-secondary-button-text-color: var(--palette-corporate-7);
+ --promoting-secondary-button-background-color: #0000;
+ --promoting-secondary-button-border-color: var(--palette-promoting-3);
+ --promoting-secondary-button-text-color: var(--palette-promoting-3);
+ --hovered-promoting-secondary-button-background-color: var(--palette-promoting-2);
+ --hovered-promoting-secondary-button-border-color: var(--palette-promoting-2);
+ --hovered-promoting-secondary-button-text-color: var(--palette-white);
+ --disabled-secondary-button-background-color: #0000;
+ --disabled-secondary-button-border-color: var(--palette-neutral-4);
+ --disabled-secondary-button-text-color: var(--palette-neutral-4);
+ --ghost-button-background-color: #0000;
+ --ghost-button-text-color: var(--palette-corporate-4);
+ --hovered-ghost-button-background-color: var(--palette-corporate-1);
+ --hovered-ghost-button-text-color: var(--palette-corporate-5);
+ --bright-ghost-button-background-color: #0000;
+ --bright-ghost-button-text-color: var(--palette-corporate-2);
+ --hovered-bright-ghost-button-background-color: var(--palette-corporate-6);
+ --hovered-bright-ghost-button-text-color: var(--palette-corporate-2);
+ --activating-ghost-button-background-color: #0000;
+ --activating-ghost-button-text-color: var(--palette-corporate-2);
+ --hovered-activating-ghost-button-background-color: var(--palette-corporate-6);
+ --hovered-activating-ghost-button-text-color: var(--palette-corporate-2);
+ --promoting-ghost-button-background-color: #0000;
+ --promoting-ghost-button-text-color: var(--palette-corporate-2);
+ --hovered-promoting-ghost-button-background-color: var(--palette-corporate-6);
+ --hovered-promoting-ghost-button-text-color: var(--palette-corporate-2);
+ --disabled-ghost-button-background-color: #0000;
+ --disabled-ghost-button-text-color: var(--palette-neutral-4);
+ --table-background-color: var(--white);
+ --table-border: 0 none #0000;
+ --table-border-radius: var(--default-border-radius);
+ --table-shadow: none;
+ --table-row-shadow: inset 0 -1px 0 0 var(--tertiary-shape-color);
+ --table-header-background-color: #0000;
+ --table-footer-background-color: var(--white);
+ --hovered-table-row-background-color: var(--palette-corporate-1);
+ --highlighted-table-cell-background-color: #dbedf840;
+ --table-search-background-color: var(--white);
+ --secondary-table-search-background-color: var(--white);
+ --table-search-border: var(--table-border);
+ --table-search-shadow: var(--table-shadow);
+ --table-search-separator: 0 none #0000;
+ --table-toolbar-background-color: var(--white);
+ --table-toolbar-border: var(--table-border);
+ --table-toolbar-border-bottom: 1px solid var(--tertiary-shape-color);
+ --table-toolbar-shadow: var(--table-shadow);
+ --table-toolbar-padding: 24px 16px;
+ --table-toolbar-bottom-spacing: 0;
+ --price-badge-background-color: var(--solid-warning-background-color);
+ --price-badge-text-color: var(--corporate-text-color);
+ --promoting-badge-text-color: var(--corporate-text-color);
+ --card-background-color: var(--white);
+ --card-border: 0 none #0000;
+ --card-shadow: none;
+ --distinct-card-background-color: var(--default-background-color);
+ --distinct-card-footer-background-color: var(--secondary-background-color);
+ --hovered-card-background-color: var(--hovered-corporate-background-color);
+ --hovered-card-border: 0 none #0000;
+ --hovered-card-shadow: none;
+ --hovered-card-visual-filter: invert(0.125) contrast(1.5);
+ --sheet-background-color: var(--white);
+ --sheet-border: 0 none #0000;
+ --sheet-shadow: none;
+ --distinct-sheet-background-color: var(--secondary-background-color);
+ --sheet-header-background-color: var(--secondary-background-color);
+ --page-message-background-color: var(--white);
+ --page-message-border: var(--default-border-width) solid var(--neutral-shape-color);
+ --page-message-border-width: var(--default-border-width);
+ --accordion-border: 0 none #0000;
+ --accordion-item-background-color: var(--white);
+ --accordion-item-border: 1px solid var(--tertiary-shape-color);
+ --hovered-accordion-shadow: none;
+ --panel-background-color: var(--white);
+ --panel-border: 0 none #0000;
+ --panel-shadow: none;
+ --hovered-panel-border: 0 none #0000;
+ --hovered-panel-shadow: 0 0 0 0 #0000;
+ --hovered-panel-headline-color: var(--interactive-text-color);
+ --tile-background-color: #0000;
+ --tile-border: 0 none #0000;
+ --tile-shadow: none;
+ --hovered-tile-background-color: var(--palette-corporate-1);
+ --hovered-tile-border: 0 none #0000;
+ --hovered-tile-shadow: none;
+ --filled-tile-background-color: var(--white);
+ --filled-tile-border: 0 none #0000;
+ --filled-tile-shadow: none;
+ --hovered-filled-tile-background-color: var(--palette-corporate-1);
+ --hovered-filled-tile-border: 0 none #0000;
+ --hovered-filled-tile-shadow: none;
+ --outlined-tile-background-color: #0000;
+ --outlined-tile-border: 1px solid var(--corporate-text-color);
+ --outlined-tile-shadow: none;
+ --hovered-outlined-tile-background-color: var(--palette-corporate-1);
+ --hovered-outlined-tile-border: 1px solid var(--corporate-text-color);
+ --hovered-outlined-tile-shadow: none;
+ --bright-tile-background-color: var(--white);
+ --bright-tile-border: 0 none #0000;
+ --bright-tile-shadow: none;
+ --hovered-bright-tile-background-color: var(--palette-corporate-1);
+ --hovered-bright-tile-border: 0 none #0000;
+ --hovered-bright-tile-shadow: none;
+ --checkbox-border-width: var(--default-border-width);
+ --checkbox-square-size: 16px;
+ --input-select-border-width: var(--default-border-width);
+ --input-select-height: 36px;
+ --input-text-border-width: var(--default-border-width);
+ --input-text-group-height: 34px;
+ --input-text-group-line-height: 44px;
+ --input-text-height: 36px;
+ --secondary-textarea-background-color: var(--palette-neutral-2);
+ --hovered-textarea-background-color: var(--palette-corporate-1);
+ --check-list-icon-background-color: var(--palette-corporate-2);
+ --check-list-icon-color: var(--palette-corporate-6);
+ --inverted-check-list-icon-background-color: #fff3;
+ --inverted-check-list-icon-color: var(--white);
+ --context-menu-border: 2px solid var(--palette-corporate-4);
+ --context-menu-separator: 1px solid var(--tertiary-shape-color);
+ --page-tabbar-bottom-border: 0 none #0000;
+ --page-footer-border: 1px solid var(--tertiary-shape-color);
+ --global-navigation-background-color: var(--palette-corporate-6);
+ --global-navigation-border1: #095bb1;
+ --global-navigation-border2: #0b2a63;
+}
+
+@media (prefers-color-scheme: dark) {
+ :root {
+ /* disable dark mode values for now */
+ /*--ion-background-color: #0d0d0d;*/
+ /*--ion-brand-color: #f4f7fa;*/
+ /*--secondary-button-border-color: #f4f7fa;*/
+ /*--secondary-button-background-color: #fff;*/
+ /*--ion-text-color: var(--primary-text-color-inverted);*/
+ /*--powered-by-text-color: var(--primary-text-color-inverted);*/
+ }
+}
+
+@media (prefers-color-scheme: light) {
+ :root {
+ --ion-background-color: #f9f9f9;
+ --ion-brand-color: var(--palette-corporate-6);
+ --ion-text-color: var(--primary-text-color);
+ --powered-by-text-color: var(--primary-text-color);
+ }
+}
+
+/**
+ * override prefers-color-scheme dependent values for now
+ */
+:root {
+ --ion-background-color: #f9f9f9;
+ --ion-brand-color: var(--palette-corporate-6);
+ --ion-text-color: var(--primary-text-color);
+ --powered-by-text-color: var(--palette-corporate-6);
+}
diff --git a/src/lib/IONOS/configs/ionosPromptSuggestions.json b/src/lib/IONOS/configs/ionosPromptSuggestions.json
new file mode 100644
index 00000000000..042b035fb13
--- /dev/null
+++ b/src/lib/IONOS/configs/ionosPromptSuggestions.json
@@ -0,0 +1,107 @@
+[
+ {
+ "description": "Text zusammenfassen",
+ "detail": "Geben Sie der AI längere Texte und lassen Sie sich diese schnell zusammenfassen.",
+ "modelName": "IONOS Chat-Assistent",
+ "model": "ionos-chat-assistent",
+ "content": "Fasse mir einen Text zusammen."
+ },
+ {
+ "description": "Texte überarbeiten",
+ "detail": "Lassen Sie von Ihnen geschriebene Texte automatisiert verbessern.",
+ "modelName": "IONOS Chat-Assistent",
+ "model": "ionos-chat-assistent",
+ "content": "Verbessere meinen Text, um ihn professioneller klingen zu lassen."
+ },
+ {
+ "description": "in neue Themen eintauchen",
+ "detail": "Bekommen Sie einen Überblick über neue Themen und lassen Sie sich diese erklären.",
+ "modelName": "IONOS Chat-Assistent",
+ "model": "ionos-chat-assistent",
+ "content": "Helfe mir ein Thema besser zu verstehen."
+ },
+ {
+ "description": "Ideen sammeln",
+ "detail": "Erzeugen Sie vielseitige Ideen zu einem Thema Ihrer Wahl.",
+ "modelName": "IONOS Chat-Assistent",
+ "model": "ionos-chat-assistent",
+ "content": "Helfe mir dabei Ideen zu sammeln."
+ },
+ {
+ "description": "Programmieren",
+ "detail": "Lassen Sie Funktionen oder ganze Skripte in der Programmiersprache Ihrer Wahl generieren.",
+ "modelName": "Codegenerierung",
+ "model": "codegenerierung",
+ "content": "Schreibe eine Python-Funktion für mich. Frage mich zunächst nach meinen Anforderungen daran."
+ },
+ {
+ "description": "Code Überarbeiten",
+ "detail": "Lassen Sie Ihren Code automatisiert überarbeiten.",
+ "modelName": "Codegenerierung",
+ "model": "codegenerierung",
+ "content": "Hilf mir meinen Code effizienter und kompakter zu machen. Frage mich zunächst, meinen Code einzugeben."
+ },
+ {
+ "description": "Tests erstellen",
+ "detail": "Erstellen Sie passende Tests für Ihren Code.",
+ "modelName": "Codegenerierung",
+ "model": "codegenerierung",
+ "content": "Erstelle mir passende Tests für meine Funktionen. Frage mich zunächst, die entsprechende Funktion einzugeben."
+ },
+ {
+ "description": "einen Plan erstellen",
+ "detail": "Lassen Sie sich einen Plan für Ihren nächsten Workshop, Ihre nächste Reise oder Ihr nächstes Training erstellen.",
+ "modelName": "IONOS Chat-Assistent",
+ "model": "ionos-chat-assistent",
+ "content": "Erstelle mir einen Plan. "
+ },
+ {
+ "description": "einen Firmentext schreiben",
+ "detail": "Erstellen Sie passende Texte für Ihre Firmenkanäle.",
+ "modelName": "KI Texter",
+ "model": "copywriter",
+ "content": "Hilf mir einen Firmentext zu verfassen."
+ },
+ {
+ "description": "etwas in seinem Style schreiben lassen",
+ "detail": "Stellen Sie Beispieltexte zur Verfügung, um Inhalte in Ihrem spezifischen Firmenstil erstellen zu lassen.",
+ "modelName": "KI Texter",
+ "model": "copywriter",
+ "content": "Schreibe einen Text und orientiere dich dabei am Schreibstil meines Beispieltextes."
+ },
+ {
+ "description": "einen Blogartikel schreiben",
+ "detail": "Erstellen Sie Blogartikel für Ihre Firmenplattform.",
+ "modelName": "KI Texter",
+ "model": "copywriter",
+ "content": "Schreibe einen Blogartikel für meine Firmenwebseite."
+ },
+ {
+ "description": "einen Social Media Post schreiben",
+ "detail": "Erstellen Sie Social Media Posts für Ihren Firmenaccount.",
+ "modelName": "KI Texter",
+ "model": "copywriter",
+ "content": "Schreibe einen Social Media Post für mein LinkedIn Profil."
+ },
+ {
+ "description": "ein Bild erstellen",
+ "detail": "Generieren Sie visuelle Inhalte für Ihre Webseite, einen Blog oder Ihre nächste Präsentation.",
+ "modelName": "Bildgenerierung",
+ "model": "ionos-image-pipeline",
+ "content": "Stilisiertes Bild, verschiedene Blautöne, abstrakt, runde formen, flächig"
+ },
+ {
+ "description": "ein Bild erstellen",
+ "detail": "Generieren Sie visuelle Inhalte für Ihre Webseite, einen Blog oder Ihre nächste Präsentation.",
+ "modelName": "Bildgenerierung",
+ "model": "ionos-image-pipeline",
+ "content": "Fotorealistisches Bild eines Waldes am Tag, Tau, high quality"
+ },
+ {
+ "description": "ein Bild erstellen",
+ "detail": "Generieren Sie visuelle Inhalte für Ihre Webseite, einen Blog oder Ihre nächste Präsentation.",
+ "modelName": "Bildgenerierung",
+ "model": "ionos-image-pipeline",
+ "content": "Stilisiertes Bild, künstlicher Intelligenz, futuristisch."
+ }
+]
diff --git a/src/lib/IONOS/utils/getModels.ts b/src/lib/IONOS/utils/getModels.ts
new file mode 100644
index 00000000000..1e6d30edd78
--- /dev/null
+++ b/src/lib/IONOS/utils/getModels.ts
@@ -0,0 +1,17 @@
+import prompts from '$lib/IONOS/configs/ionosPromptSuggestions.json';
+
+/**
+ * Select the models from the array.
+ *
+ * @param {Array} array of something
+ * @param {Number} maxPicks max number of picks
+ */
+export default (): Array => {
+ const models = new Map();
+
+ for (const { model, modelName } of prompts ) {
+ models.set(model, modelName);
+ }
+
+ return [...models.entries().map(([model, modelName]) => ([model, modelName]))];
+}
diff --git a/src/lib/IONOS/utils/randomSelection.ts b/src/lib/IONOS/utils/randomSelection.ts
new file mode 100644
index 00000000000..246e0704c8a
--- /dev/null
+++ b/src/lib/IONOS/utils/randomSelection.ts
@@ -0,0 +1,25 @@
+/** Select max picks from the array.
+ *
+ * @param {Array} array of someting
+ * @param {Number} maxPicks max number of picks
+ */
+export default (array: Array, maxPicks: number): Array => {
+ let pickedIndexes = { };
+ let result = [];
+
+ for (let index = 0, counter = 0; counter < Math.min(array.length, maxPicks);) {
+ index = Math.floor(Math.random() * array.length);
+
+ if (index in pickedIndexes) {
+ continue;
+ }
+
+ counter++
+
+ pickedIndexes[index] = true;
+
+ result.push(array[index]);
+ }
+
+ return result;
+}
diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte
index 8a1ef2d9162..2dfc3899047 100644
--- a/src/lib/components/chat/Chat.svelte
+++ b/src/lib/components/chat/Chat.svelte
@@ -508,7 +508,8 @@
await showArtifacts.set(false);
if ($page.url.pathname.includes('/c/')) {
- window.history.replaceState(history.state, '', `/`);
+ goto('/start');
+ return;
}
autoScroll = true;
@@ -552,8 +553,9 @@
showControls.set(true);
}
- if ($page.url.searchParams.get('q')) {
- prompt = $page.url.searchParams.get('q') ?? '';
+ if (sessionStorage.ionosGptDemoPrompt) {
+ prompt = sessionStorage.ionosGptDemoPrompt ?? '';
+ sessionStorage.removeItem('ionosGptDemoPrompt');
if (prompt) {
await tick();
@@ -2190,7 +2192,7 @@
{#if !chatIdProp || (loaded && chatIdProp)}