initial
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .dockerignore +14 -1
- .eslintignore +13 -0
- .eslintrc.cjs +44 -0
- .gitignore +17 -0
- .prettierignore +14 -0
- .prettierrc +7 -0
- chart/Chart.yaml +5 -0
- chart/env/prod.yaml +724 -0
- chart/templates/_helpers.tpl +22 -0
- chart/templates/config.yaml +10 -0
- chart/templates/deployment.yaml +81 -0
- chart/templates/hpa.yaml +45 -0
- chart/templates/infisical.yaml +24 -0
- chart/templates/ingress-internal.yaml +32 -0
- chart/templates/ingress.yaml +32 -0
- chart/templates/network-policy.yaml +36 -0
- chart/templates/service-account.yaml +13 -0
- chart/templates/service-monitor.yaml +15 -0
- chart/templates/service.yaml +21 -0
- chart/values.yaml +74 -0
- package-lock.json +0 -0
- package.json +128 -11
- postcss.config.js +6 -0
- scripts/config.ts +64 -0
- scripts/populate.ts +391 -0
- scripts/samples.txt +194 -0
- scripts/setups/vitest-setup-client.ts +0 -0
- scripts/setups/vitest-setup-server.ts +49 -0
- scripts/updateLocalEnv.ts +48 -0
- static/chatui/apple-touch-icon.png +3 -0
- static/chatui/favicon.ico +0 -0
- static/chatui/favicon.svg +3 -0
- static/chatui/icon-128x128.png +3 -0
- static/chatui/icon-256x256.png +3 -0
- static/chatui/icon-512x512.png +3 -0
- static/chatui/icon.svg +3 -0
- static/chatui/logo.svg +6 -0
- static/chatui/manifest.json +24 -0
- static/huggingchat/apple-touch-icon.png +3 -0
- static/huggingchat/assistants-thumbnail.png +3 -0
- static/huggingchat/favicon.ico +0 -0
- static/huggingchat/favicon.svg +7 -0
- static/huggingchat/icon-128x128.png +3 -0
- static/huggingchat/icon-144x144.png +3 -0
- static/huggingchat/icon-192x192.png +3 -0
- static/huggingchat/icon-256x256.png +3 -0
- static/huggingchat/icon-36x36.png +3 -0
- static/huggingchat/icon-48x48.png +3 -0
- static/huggingchat/icon-512x512.png +3 -0
- static/huggingchat/icon-72x72.png +3 -0
.dockerignore
CHANGED
|
@@ -1,2 +1,15 @@
|
|
| 1 |
node_modules
|
| 2 |
-
.git
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
node_modules
|
| 2 |
+
.git
|
| 3 |
+
Dockerfile
|
| 4 |
+
.vscode/
|
| 5 |
+
.idea
|
| 6 |
+
.gitignore
|
| 7 |
+
LICENSE
|
| 8 |
+
README.md
|
| 9 |
+
node_modules/
|
| 10 |
+
.svelte-kit/
|
| 11 |
+
.env*
|
| 12 |
+
!.env
|
| 13 |
+
.env.local
|
| 14 |
+
db
|
| 15 |
+
models/**
|
.eslintignore
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.DS_Store
|
| 2 |
+
node_modules
|
| 3 |
+
/build
|
| 4 |
+
/.svelte-kit
|
| 5 |
+
/package
|
| 6 |
+
.env
|
| 7 |
+
.env.*
|
| 8 |
+
!.env.example
|
| 9 |
+
|
| 10 |
+
# Ignore files for PNPM, NPM and YARN
|
| 11 |
+
pnpm-lock.yaml
|
| 12 |
+
package-lock.json
|
| 13 |
+
yarn.lock
|
.eslintrc.cjs
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
module.exports = {
|
| 2 |
+
root: true,
|
| 3 |
+
parser: "@typescript-eslint/parser",
|
| 4 |
+
extends: [
|
| 5 |
+
"eslint:recommended",
|
| 6 |
+
"plugin:@typescript-eslint/recommended",
|
| 7 |
+
"plugin:svelte/recommended",
|
| 8 |
+
"prettier",
|
| 9 |
+
],
|
| 10 |
+
plugins: ["@typescript-eslint"],
|
| 11 |
+
ignorePatterns: ["*.cjs"],
|
| 12 |
+
overrides: [
|
| 13 |
+
{
|
| 14 |
+
files: ["*.svelte"],
|
| 15 |
+
parser: "svelte-eslint-parser",
|
| 16 |
+
parserOptions: {
|
| 17 |
+
parser: "@typescript-eslint/parser",
|
| 18 |
+
},
|
| 19 |
+
},
|
| 20 |
+
],
|
| 21 |
+
parserOptions: {
|
| 22 |
+
sourceType: "module",
|
| 23 |
+
ecmaVersion: 2020,
|
| 24 |
+
extraFileExtensions: [".svelte"],
|
| 25 |
+
},
|
| 26 |
+
rules: {
|
| 27 |
+
"require-yield": "off",
|
| 28 |
+
"@typescript-eslint/no-explicit-any": "error",
|
| 29 |
+
"@typescript-eslint/no-non-null-assertion": "error",
|
| 30 |
+
"@typescript-eslint/no-unused-vars": [
|
| 31 |
+
// prevent variables with a _ prefix from being marked as unused
|
| 32 |
+
"error",
|
| 33 |
+
{
|
| 34 |
+
argsIgnorePattern: "^_",
|
| 35 |
+
},
|
| 36 |
+
],
|
| 37 |
+
"object-shorthand": ["error", "always"],
|
| 38 |
+
},
|
| 39 |
+
env: {
|
| 40 |
+
browser: true,
|
| 41 |
+
es2017: true,
|
| 42 |
+
node: true,
|
| 43 |
+
},
|
| 44 |
+
};
|
.gitignore
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
node_modules
|
| 2 |
|
| 3 |
# Output
|
|
|
|
| 1 |
+
.DS_Store
|
| 2 |
+
node_modules
|
| 3 |
+
/build
|
| 4 |
+
/.svelte-kit
|
| 5 |
+
/package
|
| 6 |
+
.env
|
| 7 |
+
.env.*
|
| 8 |
+
vite.config.js.timestamp-*
|
| 9 |
+
vite.config.ts.timestamp-*
|
| 10 |
+
SECRET_CONFIG
|
| 11 |
+
.idea
|
| 12 |
+
!.env.ci
|
| 13 |
+
!.env
|
| 14 |
+
gcp-*.json
|
| 15 |
+
db
|
| 16 |
+
models/*
|
| 17 |
+
!models/add-your-models-here.txt
|
| 18 |
node_modules
|
| 19 |
|
| 20 |
# Output
|
.prettierignore
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.DS_Store
|
| 2 |
+
node_modules
|
| 3 |
+
/build
|
| 4 |
+
/.svelte-kit
|
| 5 |
+
/package
|
| 6 |
+
/chart
|
| 7 |
+
.env
|
| 8 |
+
.env.*
|
| 9 |
+
!.env.example
|
| 10 |
+
|
| 11 |
+
# Ignore files for PNPM, NPM and YARN
|
| 12 |
+
pnpm-lock.yaml
|
| 13 |
+
package-lock.json
|
| 14 |
+
yarn.lock
|
.prettierrc
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"useTabs": true,
|
| 3 |
+
"trailingComma": "es5",
|
| 4 |
+
"printWidth": 100,
|
| 5 |
+
"plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
|
| 6 |
+
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
| 7 |
+
}
|
chart/Chart.yaml
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
apiVersion: v2
|
| 2 |
+
name: chat-ui
|
| 3 |
+
version: 0.0.1-latest
|
| 4 |
+
type: application
|
| 5 |
+
icon: https://huggingface.co/front/assets/huggingface_logo-noborder.svg
|
chart/env/prod.yaml
ADDED
|
@@ -0,0 +1,724 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
image:
|
| 2 |
+
repository: huggingface
|
| 3 |
+
name: chat-ui
|
| 4 |
+
|
| 5 |
+
nodeSelector:
|
| 6 |
+
role-huggingchat: "true"
|
| 7 |
+
|
| 8 |
+
tolerations:
|
| 9 |
+
- key: "huggingface.co/huggingchat"
|
| 10 |
+
operator: "Equal"
|
| 11 |
+
value: "true"
|
| 12 |
+
effect: "NoSchedule"
|
| 13 |
+
|
| 14 |
+
serviceAccount:
|
| 15 |
+
enabled: true
|
| 16 |
+
create: true
|
| 17 |
+
name: huggingchat-prod
|
| 18 |
+
|
| 19 |
+
ingress:
|
| 20 |
+
path: "/chat"
|
| 21 |
+
annotations:
|
| 22 |
+
alb.ingress.kubernetes.io/healthcheck-path: "/healthcheck"
|
| 23 |
+
alb.ingress.kubernetes.io/listen-ports: "[{\"HTTP\": 80}, {\"HTTPS\": 443}]"
|
| 24 |
+
alb.ingress.kubernetes.io/group.name: "hub-prod"
|
| 25 |
+
alb.ingress.kubernetes.io/scheme: "internet-facing"
|
| 26 |
+
alb.ingress.kubernetes.io/ssl-redirect: "443"
|
| 27 |
+
alb.ingress.kubernetes.io/tags: "Env=prod,Project=hub,Terraform=true"
|
| 28 |
+
alb.ingress.kubernetes.io/target-node-labels: "role-hub-utils=true"
|
| 29 |
+
kubernetes.io/ingress.class: "alb"
|
| 30 |
+
|
| 31 |
+
ingressInternal:
|
| 32 |
+
enabled: true
|
| 33 |
+
path: "/chat"
|
| 34 |
+
annotations:
|
| 35 |
+
alb.ingress.kubernetes.io/group.name: hub-prod-internal-public
|
| 36 |
+
alb.ingress.kubernetes.io/healthcheck-path: "/healthcheck"
|
| 37 |
+
alb.ingress.kubernetes.io/listen-ports: "[{\"HTTP\": 80}, {\"HTTPS\": 443}]"
|
| 38 |
+
alb.ingress.kubernetes.io/load-balancer-name: hub-prod-internal-public
|
| 39 |
+
alb.ingress.kubernetes.io/target-group-attributes: deregistration_delay.timeout_seconds=30
|
| 40 |
+
alb.ingress.kubernetes.io/target-node-labels: role-hub-lb=true
|
| 41 |
+
alb.ingress.kubernetes.io/target-type: ip
|
| 42 |
+
kubernetes.io/ingress.class: "alb"
|
| 43 |
+
|
| 44 |
+
envVars:
|
| 45 |
+
ADDRESS_HEADER: 'X-Forwarded-For'
|
| 46 |
+
ADMIN_CLI_LOGIN: "false"
|
| 47 |
+
ALTERNATIVE_REDIRECT_URLS: '["huggingchat://login/callback"]'
|
| 48 |
+
APP_BASE: "/chat"
|
| 49 |
+
ALLOW_IFRAME: "false"
|
| 50 |
+
COMMUNITY_TOOLS: "true"
|
| 51 |
+
COOKIE_SAMESITE: "lax"
|
| 52 |
+
COOKIE_SECURE: "true"
|
| 53 |
+
ENABLE_ASSISTANTS: "true"
|
| 54 |
+
ENABLE_ASSISTANTS_RAG: "true"
|
| 55 |
+
ENABLE_CONFIG_MANAGER: "false"
|
| 56 |
+
METRICS_PORT: 5565
|
| 57 |
+
LOG_LEVEL: "debug"
|
| 58 |
+
METRICS_ENABLED: "true"
|
| 59 |
+
MODELS: >
|
| 60 |
+
[
|
| 61 |
+
{
|
| 62 |
+
"name": "meta-llama/Llama-3.3-70B-Instruct",
|
| 63 |
+
"id": "meta-llama/Llama-3.3-70B-Instruct",
|
| 64 |
+
"description": "Ideal for everyday use. A fast and extremely capable model matching closed source models' capabilities. Now with the latest Llama 3.3 weights!",
|
| 65 |
+
"modelUrl": "https://huggingface.co/meta-llama/Llama-3.3-70B-Instruct",
|
| 66 |
+
"websiteUrl": "https://llama.meta.com/",
|
| 67 |
+
"logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/meta-logo.png",
|
| 68 |
+
"tools": true,
|
| 69 |
+
"preprompt": "",
|
| 70 |
+
"parameters": {
|
| 71 |
+
"stop": ["<|endoftext|>", "<|eot_id|>"],
|
| 72 |
+
"temperature": 0.6,
|
| 73 |
+
"max_new_tokens": 1024,
|
| 74 |
+
"truncate": 7167
|
| 75 |
+
},
|
| 76 |
+
"endpoints": [{"type" : "inference-client"}],
|
| 77 |
+
"promptExamples": [
|
| 78 |
+
{
|
| 79 |
+
"title": "Write an email",
|
| 80 |
+
"prompt": "As a restaurant owner, write a professional email to the supplier to get these products every week: \n\n- Wine (x10)\n- Eggs (x24)\n- Bread (x12)"
|
| 81 |
+
},
|
| 82 |
+
{
|
| 83 |
+
"title": "Code a game",
|
| 84 |
+
"prompt": "Code a basic snake game in python, give explanations for each step."
|
| 85 |
+
},
|
| 86 |
+
{
|
| 87 |
+
"title": "Recipe help",
|
| 88 |
+
"prompt": "How do I make a delicious lemon cheesecake?"
|
| 89 |
+
}
|
| 90 |
+
]
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"name": "Qwen/Qwen3-235B-A22B",
|
| 94 |
+
"description": "Qwen's flagship model featuring optional reasoning. Exceptional performance with benchmarks rivaling R1 and o1.",
|
| 95 |
+
"modelUrl": "https://huggingface.co/Qwen/Qwen3-235B-A22B",
|
| 96 |
+
"websiteUrl": "https://qwenlm.github.io/blog/qwen3/",
|
| 97 |
+
"logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/qwen-logo.png",
|
| 98 |
+
"preprompt": "You are Qwen, created by Alibaba Cloud. You are a helpful assistant.",
|
| 99 |
+
"reasoning": {
|
| 100 |
+
"type": "tokens",
|
| 101 |
+
"beginToken": "<think>",
|
| 102 |
+
"endToken": "</think>"
|
| 103 |
+
},
|
| 104 |
+
"parameters": {
|
| 105 |
+
"stop": ["<|endoftext|>", "<|im_end|>"],
|
| 106 |
+
"temperature": 0.6,
|
| 107 |
+
},
|
| 108 |
+
"tools": true,
|
| 109 |
+
"promptExamples": [
|
| 110 |
+
{
|
| 111 |
+
"title": "Write an email",
|
| 112 |
+
"prompt": "As a restaurant owner, write a professional email to the supplier to get these products every week: \n\n- Wine (x10)\n- Eggs (x24)\n- Bread (x12) /nothink"
|
| 113 |
+
},
|
| 114 |
+
{
|
| 115 |
+
"title": "Build a website",
|
| 116 |
+
"prompt": "Generate a snazzy static landing page for a local coffee shop using HTML and CSS. You can use tailwind using <script src='https://cdn.tailwindcss.com'></script>."
|
| 117 |
+
},
|
| 118 |
+
{
|
| 119 |
+
"title": "Larger number",
|
| 120 |
+
"prompt": "9.11 or 9.9 which number is larger?"
|
| 121 |
+
},
|
| 122 |
+
],
|
| 123 |
+
"endpoints": [
|
| 124 |
+
{
|
| 125 |
+
"type": "inference-client",
|
| 126 |
+
"baseURL": "https://api-inference.endpoints.huggingface.tech/models/Qwen/Qwen3-235B-A22B/v1"
|
| 127 |
+
}
|
| 128 |
+
]
|
| 129 |
+
},
|
| 130 |
+
{
|
| 131 |
+
"name": "Qwen/Qwen2.5-72B-Instruct",
|
| 132 |
+
"description": "The latest Qwen open model with improved role-playing, long text generation and structured data understanding.",
|
| 133 |
+
"modelUrl": "https://huggingface.co/Qwen/Qwen2.5-72B-Instruct",
|
| 134 |
+
"websiteUrl": "https://qwenlm.github.io/blog/qwen2.5/",
|
| 135 |
+
"logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/qwen-logo.png",
|
| 136 |
+
"preprompt": "You are Qwen, created by Alibaba Cloud. You are a helpful assistant.",
|
| 137 |
+
"parameters": {
|
| 138 |
+
"stop": ["<|endoftext|>", "<|im_end|>"],
|
| 139 |
+
"temperature": 0.6,
|
| 140 |
+
"truncate": 28672,
|
| 141 |
+
"max_new_tokens": 3072
|
| 142 |
+
},
|
| 143 |
+
"tools": true,
|
| 144 |
+
"endpoints": [{"type" : "inference-client"}],
|
| 145 |
+
"promptExamples": [
|
| 146 |
+
{
|
| 147 |
+
"title": "Write an email",
|
| 148 |
+
"prompt": "As a restaurant owner, write a professional email to the supplier to get these products every week: \n\n- Wine (x10)\n- Eggs (x24)\n- Bread (x12)"
|
| 149 |
+
},
|
| 150 |
+
{
|
| 151 |
+
"title": "Code a game",
|
| 152 |
+
"prompt": "Code a basic snake game in python, give explanations for each step."
|
| 153 |
+
},
|
| 154 |
+
{
|
| 155 |
+
"title": "Recipe help",
|
| 156 |
+
"prompt": "How do I make a delicious lemon cheesecake?"
|
| 157 |
+
}
|
| 158 |
+
]
|
| 159 |
+
},
|
| 160 |
+
{
|
| 161 |
+
"name": "CohereLabs/c4ai-command-r-plus-08-2024",
|
| 162 |
+
"description": "Cohere's largest language model, optimized for conversational interaction and tool use. Now with the 2024 update!",
|
| 163 |
+
"modelUrl": "https://huggingface.co/CohereLabs/c4ai-command-r-plus-08-2024",
|
| 164 |
+
"websiteUrl": "https://docs.cohere.com/docs/command-r-plus",
|
| 165 |
+
"logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/cohere-logo.png",
|
| 166 |
+
"tools": true,
|
| 167 |
+
"systemRoleSupported": false,
|
| 168 |
+
"parameters": {
|
| 169 |
+
"stop": ["<|END_OF_TURN_TOKEN|>", "<|im_end|>"],
|
| 170 |
+
"truncate": 28672,
|
| 171 |
+
"max_new_tokens": 2048,
|
| 172 |
+
"temperature": 0.3
|
| 173 |
+
},
|
| 174 |
+
"endpoints": [{"type" : "inference-client"}],
|
| 175 |
+
"promptExamples": [
|
| 176 |
+
{
|
| 177 |
+
"title": "Generate image",
|
| 178 |
+
"prompt": "Generate the portrait of a scientific mouse in its laboratory."
|
| 179 |
+
},
|
| 180 |
+
{
|
| 181 |
+
"title": "Review code",
|
| 182 |
+
"prompt": "Review this pull request: https://github.com/huggingface/chat-ui/pull/1131/files"
|
| 183 |
+
},
|
| 184 |
+
{
|
| 185 |
+
"title": "Code a game",
|
| 186 |
+
"prompt": "Code a basic snake game in python, give explanations for each step."
|
| 187 |
+
}
|
| 188 |
+
]
|
| 189 |
+
},
|
| 190 |
+
{
|
| 191 |
+
"name": "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B",
|
| 192 |
+
"modelUrl": "https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Qwen-32B",
|
| 193 |
+
"websiteUrl": "https://deepseek.com/",
|
| 194 |
+
"logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/deepseek-logo.png",
|
| 195 |
+
"description": "The first reasoning model from DeepSeek, distilled into a 32B dense model. Outperforms o1-mini on multiple benchmarks.",
|
| 196 |
+
"reasoning": {
|
| 197 |
+
"type": "tokens",
|
| 198 |
+
"beginToken": "",
|
| 199 |
+
"endToken": "</think>"
|
| 200 |
+
},
|
| 201 |
+
"tools": true,
|
| 202 |
+
"promptExamples": [
|
| 203 |
+
{
|
| 204 |
+
"title": "Rs in strawberry",
|
| 205 |
+
"prompt": "how many R in strawberry?"
|
| 206 |
+
},
|
| 207 |
+
{
|
| 208 |
+
"title": "Larger number",
|
| 209 |
+
"prompt": "9.11 or 9.9 which number is larger?"
|
| 210 |
+
},
|
| 211 |
+
{
|
| 212 |
+
"title": "Measuring 6 liters",
|
| 213 |
+
"prompt": "I have a 6- and a 12-liter jug. I want to measure exactly 6 liters."
|
| 214 |
+
}
|
| 215 |
+
],
|
| 216 |
+
"endpoints": [
|
| 217 |
+
{
|
| 218 |
+
"type": "inference-client",
|
| 219 |
+
"baseURL": "https://b8xf586h164t4vk7.us-east-1.aws.endpoints.huggingface.cloud/v1"
|
| 220 |
+
}
|
| 221 |
+
]
|
| 222 |
+
},
|
| 223 |
+
{
|
| 224 |
+
"name": "nvidia/Llama-3.1-Nemotron-70B-Instruct-HF",
|
| 225 |
+
"modelUrl": "https://huggingface.co/nvidia/Llama-3.1-Nemotron-70B-Instruct-HF",
|
| 226 |
+
"websiteUrl": "https://www.nvidia.com/",
|
| 227 |
+
"logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/nvidia-logo.png",
|
| 228 |
+
"description": "Nvidia's latest Llama fine-tune, topping alignment benchmarks and optimized for instruction following.",
|
| 229 |
+
"parameters": {
|
| 230 |
+
"stop": ["<|eot_id|>", "<|im_end|>"],
|
| 231 |
+
"temperature": 0.5,
|
| 232 |
+
"truncate": 28672,
|
| 233 |
+
"max_new_tokens": 2048
|
| 234 |
+
},
|
| 235 |
+
"promptExamples": [
|
| 236 |
+
{
|
| 237 |
+
"title": "Rs in strawberry",
|
| 238 |
+
"prompt": "how many R in strawberry?"
|
| 239 |
+
},
|
| 240 |
+
{
|
| 241 |
+
"title": "Larger number",
|
| 242 |
+
"prompt": "9.11 or 9.9 which number is larger?"
|
| 243 |
+
},
|
| 244 |
+
{
|
| 245 |
+
"title": "Measuring 6 liters",
|
| 246 |
+
"prompt": "I have a 6- and a 12-liter jug. I want to measure exactly 6 liters."
|
| 247 |
+
}
|
| 248 |
+
],
|
| 249 |
+
"endpoints": [
|
| 250 |
+
{
|
| 251 |
+
"type": "inference-client",
|
| 252 |
+
"baseURL": "https://api-inference.endpoints.huggingface.tech/models/nvidia/Llama-3.1-Nemotron-70B-Instruct-HF/v1"
|
| 253 |
+
}
|
| 254 |
+
]
|
| 255 |
+
},
|
| 256 |
+
{
|
| 257 |
+
"name": "Qwen/QwQ-32B",
|
| 258 |
+
"tools": true,
|
| 259 |
+
"preprompt": "You are a helpful and harmless assistant. You are Qwen developed by Alibaba. You should think step-by-step.",
|
| 260 |
+
"modelUrl": "https://huggingface.co/Qwen/QwQ-32B",
|
| 261 |
+
"websiteUrl": "https://qwenlm.github.io/blog/qwq-32b/",
|
| 262 |
+
"logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/qwen-logo.png",
|
| 263 |
+
"description": "QwQ is the latest reasoning model released by the Qwen team, approaching the capabilities of R1 in benchmarks.",
|
| 264 |
+
"reasoning": {
|
| 265 |
+
"type": "tokens",
|
| 266 |
+
"beginToken": "",
|
| 267 |
+
"endToken": "</think>"
|
| 268 |
+
},
|
| 269 |
+
"promptExamples": [
|
| 270 |
+
{
|
| 271 |
+
"title": "Rs in strawberry",
|
| 272 |
+
"prompt": "how many R in strawberry?"
|
| 273 |
+
},
|
| 274 |
+
{
|
| 275 |
+
"title": "Larger number",
|
| 276 |
+
"prompt": "9.11 or 9.9 which number is larger?"
|
| 277 |
+
},
|
| 278 |
+
{
|
| 279 |
+
"title": "Measuring 6 liters",
|
| 280 |
+
"prompt": "I have a 6- and a 12-liter jug. I want to measure exactly 6 liters."
|
| 281 |
+
}
|
| 282 |
+
],
|
| 283 |
+
"endpoints": [
|
| 284 |
+
{
|
| 285 |
+
"type": "inference-client",
|
| 286 |
+
}
|
| 287 |
+
]
|
| 288 |
+
},
|
| 289 |
+
{
|
| 290 |
+
"name": "google/gemma-3-27b-it",
|
| 291 |
+
"logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/google-logo.png",
|
| 292 |
+
"multimodal": true,
|
| 293 |
+
"tools": true,
|
| 294 |
+
"systemRoleSupported" : false,
|
| 295 |
+
"description": "Google's latest open model with great multilingual performance, supports image inputs natively.",
|
| 296 |
+
"websiteUrl": "https://blog.google/technology/developers/gemma-3/",
|
| 297 |
+
"promptExamples": [
|
| 298 |
+
{
|
| 299 |
+
"title": "Write an email",
|
| 300 |
+
"prompt": "As a restaurant owner, write a professional email to the supplier to get these products every week: \n\n- Wine (x10)\n- Eggs (x24)\n- Bread (x12)"
|
| 301 |
+
},
|
| 302 |
+
{
|
| 303 |
+
"title": "Code a game",
|
| 304 |
+
"prompt": "Code a basic snake game in python, give explanations for each step."
|
| 305 |
+
},
|
| 306 |
+
{
|
| 307 |
+
"title": "Recipe help",
|
| 308 |
+
"prompt": "How do I make a delicious lemon cheesecake?"
|
| 309 |
+
}
|
| 310 |
+
],
|
| 311 |
+
"endpoints": [
|
| 312 |
+
{
|
| 313 |
+
"type": "inference-client",
|
| 314 |
+
"baseURL": "https://wp0d3hn6s3k8jk22.us-east-1.aws.endpoints.huggingface.cloud/v1",
|
| 315 |
+
"multimodal": {
|
| 316 |
+
"image": {
|
| 317 |
+
"maxSizeInMB": 10,
|
| 318 |
+
"maxWidth": 560,
|
| 319 |
+
"maxHeight": 560,
|
| 320 |
+
"supportedMimeTypes": ["image/jpeg", "image/png", "image/webp"],
|
| 321 |
+
"preferredMimeType": "image/webp"
|
| 322 |
+
}
|
| 323 |
+
}
|
| 324 |
+
}
|
| 325 |
+
]
|
| 326 |
+
},
|
| 327 |
+
{
|
| 328 |
+
"name": "mistralai/Mistral-Small-3.1-24B-Instruct-2503",
|
| 329 |
+
"tools": true,
|
| 330 |
+
"displayName": "mistralai/Mistral-Small-3.1-24B-Instruct-2503",
|
| 331 |
+
"description": "A small model with good capabilities in language understanding and commonsense reasoning.",
|
| 332 |
+
"logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/mistral-logo.png",
|
| 333 |
+
"websiteUrl": "https://mistral.ai/news/mistral-nemo/",
|
| 334 |
+
"modelUrl": "https://huggingface.co/mistralai/Mistral-Small-3.1-24B-Instruct-2503",
|
| 335 |
+
"preprompt": "",
|
| 336 |
+
"promptExamples": [
|
| 337 |
+
{
|
| 338 |
+
"title": "Write an email",
|
| 339 |
+
"prompt": "As a restaurant owner, write a professional email to the supplier to get these products every week: \n\n- Wine (x10)\n- Eggs (x24)\n- Bread (x12)"
|
| 340 |
+
},
|
| 341 |
+
{
|
| 342 |
+
"title": "Code a game",
|
| 343 |
+
"prompt": "Code a basic snake game in python, give explanations for each step."
|
| 344 |
+
},
|
| 345 |
+
{
|
| 346 |
+
"title": "Recipe help",
|
| 347 |
+
"prompt": "How do I make a delicious lemon cheesecake?"
|
| 348 |
+
}
|
| 349 |
+
],
|
| 350 |
+
|
| 351 |
+
"endpoints": [
|
| 352 |
+
{
|
| 353 |
+
"type": "inference-client",
|
| 354 |
+
"baseURL": "https://hkjfqcryevvq9cie.us-east-1.aws.endpoints.huggingface.cloud/v1"
|
| 355 |
+
}
|
| 356 |
+
]
|
| 357 |
+
},
|
| 358 |
+
{
|
| 359 |
+
"name": "Qwen/Qwen2.5-VL-32B-Instruct",
|
| 360 |
+
"logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/qwen-logo.png",
|
| 361 |
+
"description": "The latest multimodal model from Qwen! Supports image inputs natively.",
|
| 362 |
+
"websiteUrl": "https://qwenlm.github.io/blog/qwen2.5-vl/",
|
| 363 |
+
"modelUrl": "https://huggingface.co/Qwen/Qwen2.5-VL-32B-Instruct",
|
| 364 |
+
"multimodal": true,
|
| 365 |
+
"promptExamples": [
|
| 366 |
+
{
|
| 367 |
+
"title": "Write an email",
|
| 368 |
+
"prompt": "As a restaurant owner, write a professional email to the supplier to get these products every week: \n\n- Wine (x10)\n- Eggs (x24)\n- Bread (x12)"
|
| 369 |
+
},
|
| 370 |
+
{
|
| 371 |
+
"title": "Code a game",
|
| 372 |
+
"prompt": "Code a basic snake game in python, give explanations for each step."
|
| 373 |
+
},
|
| 374 |
+
{
|
| 375 |
+
"title": "Recipe help",
|
| 376 |
+
"prompt": "How do I make a delicious lemon cheesecake?"
|
| 377 |
+
}
|
| 378 |
+
],
|
| 379 |
+
"endpoints": [
|
| 380 |
+
{
|
| 381 |
+
"type": "inference-client",
|
| 382 |
+
"multimodal": {
|
| 383 |
+
"image": {
|
| 384 |
+
"maxSizeInMB": 10,
|
| 385 |
+
"maxWidth": 1024,
|
| 386 |
+
"maxHeight": 1024,
|
| 387 |
+
"supportedMimeTypes": ["image/png", "image/jpeg", "image/webp"],
|
| 388 |
+
"preferredMimeType": "image/webp"
|
| 389 |
+
}
|
| 390 |
+
}
|
| 391 |
+
}
|
| 392 |
+
]
|
| 393 |
+
},
|
| 394 |
+
{
|
| 395 |
+
"name": "microsoft/Phi-4",
|
| 396 |
+
"tools": true,
|
| 397 |
+
"systemRoleSupported": false,
|
| 398 |
+
"description": "One of the best small models, super fast for simple tasks.",
|
| 399 |
+
"logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/microsoft-logo.png",
|
| 400 |
+
"modelUrl": "https://huggingface.co/microsoft/Phi-4",
|
| 401 |
+
"websiteUrl": "https://techcommunity.microsoft.com/blog/aiplatformblog/introducing-phi-4-microsoft%E2%80%99s-newest-small-language-model-specializing-in-comple/4357090",
|
| 402 |
+
"preprompt": "",
|
| 403 |
+
"parameters": {
|
| 404 |
+
"stop": ["<|end|>", "<|endoftext|>", "<|assistant|>"],
|
| 405 |
+
"temperature": 0.6,
|
| 406 |
+
"truncate": 28672,
|
| 407 |
+
"max_new_tokens": 3072
|
| 408 |
+
},
|
| 409 |
+
"promptExamples": [
|
| 410 |
+
{
|
| 411 |
+
"title": "Write an email",
|
| 412 |
+
"prompt": "As a restaurant owner, write a professional email to the supplier to get these products every week: \n\n- Wine (x10)\n- Eggs (x24)\n- Bread (x12)"
|
| 413 |
+
},
|
| 414 |
+
{
|
| 415 |
+
"title": "Code a game",
|
| 416 |
+
"prompt": "Code a basic snake game in python, give explanations for each step."
|
| 417 |
+
},
|
| 418 |
+
{
|
| 419 |
+
"title": "Recipe help",
|
| 420 |
+
"prompt": "How do I make a delicious lemon cheesecake?"
|
| 421 |
+
}
|
| 422 |
+
],
|
| 423 |
+
"endpoints": [
|
| 424 |
+
{
|
| 425 |
+
"type": "inference-client",
|
| 426 |
+
"baseURL": "https://up5ijetg6a2e9zlb.us-east-1.aws.endpoints.huggingface.cloud/v1"
|
| 427 |
+
}
|
| 428 |
+
]
|
| 429 |
+
},
|
| 430 |
+
{
|
| 431 |
+
"name": "NousResearch/Hermes-3-Llama-3.1-8B",
|
| 432 |
+
"description": "Nous Research's latest Hermes 3 release in 8B size. Follows instruction closely.",
|
| 433 |
+
"tools": true,
|
| 434 |
+
"logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/nous-logo.png",
|
| 435 |
+
"websiteUrl": "https://nousresearch.com/",
|
| 436 |
+
"modelUrl": "https://huggingface.co/NousResearch/Hermes-3-Llama-3.1-8B",
|
| 437 |
+
"promptExamples": [
|
| 438 |
+
{
|
| 439 |
+
"title": "Write an email",
|
| 440 |
+
"prompt": "As a restaurant owner, write a professional email to the supplier to get these products every week: \n\n- Wine (x10)\n- Eggs (x24)\n- Bread (x12)"
|
| 441 |
+
},
|
| 442 |
+
{
|
| 443 |
+
"title": "Code a game",
|
| 444 |
+
"prompt": "Code a basic snake game in python, give explanations for each step."
|
| 445 |
+
},
|
| 446 |
+
{
|
| 447 |
+
"title": "Recipe help",
|
| 448 |
+
"prompt": "How do I make a delicious lemon cheesecake?"
|
| 449 |
+
}
|
| 450 |
+
],
|
| 451 |
+
"parameters": {
|
| 452 |
+
"stop": ["<|im_end|>"],
|
| 453 |
+
"temperature": 0.6,
|
| 454 |
+
"truncate": 14336,
|
| 455 |
+
"max_new_tokens": 1536
|
| 456 |
+
},
|
| 457 |
+
"endpoints": [{"type" : "inference-client"}]
|
| 458 |
+
}
|
| 459 |
+
]
|
| 460 |
+
|
| 461 |
+
NODE_ENV: "prod"
|
| 462 |
+
NODE_LOG_STRUCTURED_DATA: true
|
| 463 |
+
OLD_MODELS: >
|
| 464 |
+
[
|
| 465 |
+
{ "name": "bigcode/starcoder" },
|
| 466 |
+
{ "name": "OpenAssistant/oasst-sft-6-llama-30b-xor" },
|
| 467 |
+
{ "name": "HuggingFaceH4/zephyr-7b-alpha" },
|
| 468 |
+
{ "name": "openchat/openchat_3.5" },
|
| 469 |
+
{ "name": "openchat/openchat-3.5-1210" },
|
| 470 |
+
{ "name": "tiiuae/falcon-180B-chat" },
|
| 471 |
+
{ "name": "codellama/CodeLlama-34b-Instruct-hf" },
|
| 472 |
+
{ "name": "google/gemma-7b-it" },
|
| 473 |
+
{ "name": "meta-llama/Llama-2-70b-chat-hf" },
|
| 474 |
+
{ "name": "codellama/CodeLlama-70b-Instruct-hf" },
|
| 475 |
+
{ "name": "openchat/openchat-3.5-0106" },
|
| 476 |
+
{ "name": "meta-llama/Meta-Llama-3-70B-Instruct" },
|
| 477 |
+
{ "name": "meta-llama/Meta-Llama-3.1-405B-Instruct-FP8" },
|
| 478 |
+
{
|
| 479 |
+
"name": "CohereForAI/c4ai-command-r-plus-08-2024",
|
| 480 |
+
"transferTo": "CohereLabs/c4ai-command-r-plus-08-2024"
|
| 481 |
+
},
|
| 482 |
+
{
|
| 483 |
+
"name": "CohereForAI/c4ai-command-r-plus",
|
| 484 |
+
"transferTo": "CohereLabs/c4ai-command-r-plus-08-2024"
|
| 485 |
+
},
|
| 486 |
+
{
|
| 487 |
+
"name": "01-ai/Yi-1.5-34B-Chat",
|
| 488 |
+
"transferTo": "CohereLabs/c4ai-command-r-plus-08-2024"
|
| 489 |
+
},
|
| 490 |
+
{
|
| 491 |
+
"name": "mistralai/Mixtral-8x7B-Instruct-v0.1",
|
| 492 |
+
"transferTo": "mistralai/Mistral-Small-3.1-24B-Instruct-2503"
|
| 493 |
+
},
|
| 494 |
+
{
|
| 495 |
+
"name": "NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO",
|
| 496 |
+
"transferTo": "NousResearch/Hermes-3-Llama-3.1-8B"
|
| 497 |
+
},
|
| 498 |
+
{
|
| 499 |
+
"name": "mistralai/Mistral-7B-Instruct-v0.3",
|
| 500 |
+
"transferTo": "mistralai/Mistral-Small-3.1-24B-Instruct-2503"
|
| 501 |
+
},
|
| 502 |
+
{
|
| 503 |
+
"name": "microsoft/Phi-3-mini-4k-instruct",
|
| 504 |
+
"transferTo": "microsoft/Phi-4"
|
| 505 |
+
},
|
| 506 |
+
{
|
| 507 |
+
"name": "meta-llama/Meta-Llama-3.1-70B-Instruct",
|
| 508 |
+
"transferTo": "meta-llama/Llama-3.3-70B-Instruct"
|
| 509 |
+
},
|
| 510 |
+
{
|
| 511 |
+
"name": "Qwen/QwQ-32B-Preview",
|
| 512 |
+
"transferTo": "Qwen/QwQ-32B"
|
| 513 |
+
},
|
| 514 |
+
{
|
| 515 |
+
"name": "mistralai/Mistral-Nemo-Instruct-2407",
|
| 516 |
+
"transferTo": "mistralai/Mistral-Small-3.1-24B-Instruct-2503"
|
| 517 |
+
},
|
| 518 |
+
{
|
| 519 |
+
"name": "microsoft/Phi-3.5-mini-instruct",
|
| 520 |
+
"transferTo": "microsoft/Phi-4"
|
| 521 |
+
},
|
| 522 |
+
{
|
| 523 |
+
"name": "Qwen/Qwen2.5-Coder-32B-Instruct",
|
| 524 |
+
"transferTo": "Qwen/QwQ-32B"
|
| 525 |
+
},
|
| 526 |
+
{
|
| 527 |
+
"name": "meta-llama/Llama-3.2-11B-Vision-Instruct",
|
| 528 |
+
"transferTo" : "Qwen/Qwen2.5-VL-32B-Instruct"
|
| 529 |
+
}
|
| 530 |
+
]
|
| 531 |
+
PUBLIC_ORIGIN: "https://huggingface.co"
|
| 532 |
+
PUBLIC_SHARE_PREFIX: "https://hf.co/chat"
|
| 533 |
+
PUBLIC_ANNOUNCEMENT_BANNERS: >
|
| 534 |
+
[
|
| 535 |
+
{
|
| 536 |
+
"title": "Qwen 3 235B is available!",
|
| 537 |
+
"linkTitle": "Try it out!",
|
| 538 |
+
"linkHref": "https://huggingface.co/chat/models/Qwen/Qwen3-235B-A22B"
|
| 539 |
+
}
|
| 540 |
+
]
|
| 541 |
+
PUBLIC_APP_NAME: "HuggingChat"
|
| 542 |
+
PUBLIC_APP_ASSETS: "huggingchat"
|
| 543 |
+
PUBLIC_APP_COLOR: "yellow"
|
| 544 |
+
PUBLIC_APP_DESCRIPTION: "Making the community's best AI chat models available to everyone."
|
| 545 |
+
PUBLIC_APP_DISCLAIMER_MESSAGE: "Disclaimer: AI is an area of active research with known problems such as biased generation and misinformation. Do not use this application for high-stakes decisions or advice."
|
| 546 |
+
PUBLIC_APP_GUEST_MESSAGE: "Sign in with a free Hugging Face account to continue using HuggingChat."
|
| 547 |
+
PUBLIC_APP_DATA_SHARING: 0
|
| 548 |
+
PUBLIC_APP_DISCLAIMER: 1
|
| 549 |
+
PUBLIC_PLAUSIBLE_SCRIPT_URL: "/js/script.js"
|
| 550 |
+
REQUIRE_FEATURED_ASSISTANTS: "true"
|
| 551 |
+
TASK_MODEL: >
|
| 552 |
+
{
|
| 553 |
+
"name": "NousResearch/Hermes-3-Llama-3.1-8B",
|
| 554 |
+
"unlisted": true,
|
| 555 |
+
"endpoints": [{"type" : "inference-client"}],
|
| 556 |
+
"parameters": {
|
| 557 |
+
"temperature": 0.1,
|
| 558 |
+
"max_new_tokens": 256
|
| 559 |
+
}
|
| 560 |
+
}
|
| 561 |
+
|
| 562 |
+
|
| 563 |
+
TEXT_EMBEDDING_MODELS: >
|
| 564 |
+
[{
|
| 565 |
+
"name": "bge-base-en-v1-5-sxa",
|
| 566 |
+
"displayName": "bge-base-en-v1-5-sxa",
|
| 567 |
+
"chunkCharLength": 512,
|
| 568 |
+
"endpoints": [{
|
| 569 |
+
"type": "tei",
|
| 570 |
+
"url": "https://huggingchat-tei.hf.space/"
|
| 571 |
+
}]
|
| 572 |
+
}]
|
| 573 |
+
WEBSEARCH_BLOCKLIST: '["youtube.com", "twitter.com"]'
|
| 574 |
+
XFF_DEPTH: '2'
|
| 575 |
+
TOOLS: >
|
| 576 |
+
[
|
| 577 |
+
{
|
| 578 |
+
"_id": "000000000000000000000001",
|
| 579 |
+
"displayName": "Image Generation",
|
| 580 |
+
"description": "Use this tool to generate images based on a prompt.",
|
| 581 |
+
"color": "yellow",
|
| 582 |
+
"icon": "camera",
|
| 583 |
+
"baseUrl": "black-forest-labs/FLUX.1-schnell",
|
| 584 |
+
"name": "image_generation",
|
| 585 |
+
"endpoint": "/infer",
|
| 586 |
+
"inputs": [
|
| 587 |
+
{
|
| 588 |
+
"name": "prompt",
|
| 589 |
+
"description": "A prompt to generate an image from",
|
| 590 |
+
"paramType": "required",
|
| 591 |
+
"type": "str"
|
| 592 |
+
},
|
| 593 |
+
{ "name": "seed", "paramType": "fixed", "value": "0", "type": "float" },
|
| 594 |
+
{
|
| 595 |
+
"name": "randomize_seed",
|
| 596 |
+
"paramType": "fixed",
|
| 597 |
+
"value": "true",
|
| 598 |
+
"type": "bool"
|
| 599 |
+
},
|
| 600 |
+
{
|
| 601 |
+
"name": "width",
|
| 602 |
+
"description": "numeric value between 256 and 2048",
|
| 603 |
+
"paramType": "optional",
|
| 604 |
+
"default": 1024,
|
| 605 |
+
"type": "float"
|
| 606 |
+
},
|
| 607 |
+
{
|
| 608 |
+
"name": "height",
|
| 609 |
+
"description": "numeric value between 256 and 2048",
|
| 610 |
+
"paramType": "optional",
|
| 611 |
+
"default": 1024,
|
| 612 |
+
"type": "float"
|
| 613 |
+
},
|
| 614 |
+
{
|
| 615 |
+
"name": "num_inference_steps",
|
| 616 |
+
"paramType": "fixed",
|
| 617 |
+
"value": "4",
|
| 618 |
+
"type": "float"
|
| 619 |
+
}
|
| 620 |
+
],
|
| 621 |
+
"outputComponent": "image",
|
| 622 |
+
"outputComponentIdx": 0,
|
| 623 |
+
"showOutput": true
|
| 624 |
+
},
|
| 625 |
+
{
|
| 626 |
+
"_id": "000000000000000000000002",
|
| 627 |
+
"displayName": "Document Parser",
|
| 628 |
+
"description": "Use this tool to parse any document and get its content in markdown format.",
|
| 629 |
+
"color": "yellow",
|
| 630 |
+
"icon": "cloud",
|
| 631 |
+
"baseUrl": "huggingchat/document-parser",
|
| 632 |
+
"name": "document_parser",
|
| 633 |
+
"endpoint": "/predict",
|
| 634 |
+
"inputs": [
|
| 635 |
+
{
|
| 636 |
+
"name": "document",
|
| 637 |
+
"description": "Filename of the document to parse",
|
| 638 |
+
"paramType": "required",
|
| 639 |
+
"type": "file",
|
| 640 |
+
"mimeTypes": 'application/*'
|
| 641 |
+
},
|
| 642 |
+
{
|
| 643 |
+
"name": "filename",
|
| 644 |
+
"paramType": "fixed",
|
| 645 |
+
"value": "document.pdf",
|
| 646 |
+
"type": "str"
|
| 647 |
+
}
|
| 648 |
+
],
|
| 649 |
+
"outputComponent": "textbox",
|
| 650 |
+
"outputComponentIdx": 0,
|
| 651 |
+
"showOutput": false,
|
| 652 |
+
"isHidden": true
|
| 653 |
+
},
|
| 654 |
+
{
|
| 655 |
+
"_id": "000000000000000000000003",
|
| 656 |
+
"name": "edit_image",
|
| 657 |
+
"baseUrl": "multimodalart/cosxl",
|
| 658 |
+
"endpoint": "/run_edit",
|
| 659 |
+
"inputs": [
|
| 660 |
+
{
|
| 661 |
+
"name": "image",
|
| 662 |
+
"description": "The image path to be edited",
|
| 663 |
+
"paramType": "required",
|
| 664 |
+
"type": "file",
|
| 665 |
+
"mimeTypes": 'image/*'
|
| 666 |
+
},
|
| 667 |
+
{
|
| 668 |
+
"name": "prompt",
|
| 669 |
+
"description": "The prompt with which to edit the image",
|
| 670 |
+
"paramType": "required",
|
| 671 |
+
"type": "str"
|
| 672 |
+
},
|
| 673 |
+
{
|
| 674 |
+
"name": "negative_prompt",
|
| 675 |
+
"paramType": "fixed",
|
| 676 |
+
"value": "",
|
| 677 |
+
"type": "str"
|
| 678 |
+
},
|
| 679 |
+
{
|
| 680 |
+
"name": "guidance_scale",
|
| 681 |
+
"paramType": "fixed",
|
| 682 |
+
"value": 6.5,
|
| 683 |
+
"type": "float"
|
| 684 |
+
},
|
| 685 |
+
{
|
| 686 |
+
"name": "steps",
|
| 687 |
+
"paramType": "fixed",
|
| 688 |
+
"value": 30,
|
| 689 |
+
"type": "float"
|
| 690 |
+
}
|
| 691 |
+
],
|
| 692 |
+
"outputComponent": "image",
|
| 693 |
+
"showOutput": true,
|
| 694 |
+
"displayName": "Image Editor",
|
| 695 |
+
"color": "green",
|
| 696 |
+
"icon": "camera",
|
| 697 |
+
"description": "This tool lets you edit images",
|
| 698 |
+
"outputComponentIdx": 0
|
| 699 |
+
}
|
| 700 |
+
]
|
| 701 |
+
HF_ORG_ADMIN: '644171cfbd0c97265298aa99'
|
| 702 |
+
HF_ORG_EARLY_ACCESS: '5e67bd5b1009063689407478'
|
| 703 |
+
HF_API_ROOT: 'https://api-inference.endpoints.huggingface.tech/models'
|
| 704 |
+
infisical:
|
| 705 |
+
enabled: true
|
| 706 |
+
env: "prod-us-east-1"
|
| 707 |
+
|
| 708 |
+
autoscaling:
|
| 709 |
+
enabled: true
|
| 710 |
+
minReplicas: 12
|
| 711 |
+
maxReplicas: 30
|
| 712 |
+
targetMemoryUtilizationPercentage: "50"
|
| 713 |
+
targetCPUUtilizationPercentage: "50"
|
| 714 |
+
|
| 715 |
+
resources:
|
| 716 |
+
requests:
|
| 717 |
+
cpu: 2
|
| 718 |
+
memory: 4Gi
|
| 719 |
+
limits:
|
| 720 |
+
cpu: 4
|
| 721 |
+
memory: 8Gi
|
| 722 |
+
|
| 723 |
+
monitoring:
|
| 724 |
+
enabled: true
|
chart/templates/_helpers.tpl
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{{- define "name" -}}
|
| 2 |
+
{{- default $.Release.Name | trunc 63 | trimSuffix "-" -}}
|
| 3 |
+
{{- end -}}
|
| 4 |
+
|
| 5 |
+
{{- define "app.name" -}}
|
| 6 |
+
chat-ui
|
| 7 |
+
{{- end -}}
|
| 8 |
+
|
| 9 |
+
{{- define "labels.standard" -}}
|
| 10 |
+
release: {{ $.Release.Name | quote }}
|
| 11 |
+
heritage: {{ $.Release.Service | quote }}
|
| 12 |
+
chart: "{{ include "name" . }}"
|
| 13 |
+
app: "{{ include "app.name" . }}"
|
| 14 |
+
{{- end -}}
|
| 15 |
+
|
| 16 |
+
{{- define "labels.resolver" -}}
|
| 17 |
+
release: {{ $.Release.Name | quote }}
|
| 18 |
+
heritage: {{ $.Release.Service | quote }}
|
| 19 |
+
chart: "{{ include "name" . }}"
|
| 20 |
+
app: "{{ include "app.name" . }}-resolver"
|
| 21 |
+
{{- end -}}
|
| 22 |
+
|
chart/templates/config.yaml
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
apiVersion: v1
|
| 2 |
+
kind: ConfigMap
|
| 3 |
+
metadata:
|
| 4 |
+
labels: {{ include "labels.standard" . | nindent 4 }}
|
| 5 |
+
name: {{ include "name" . }}
|
| 6 |
+
namespace: {{ .Release.Namespace }}
|
| 7 |
+
data:
|
| 8 |
+
{{- range $key, $value := $.Values.envVars }}
|
| 9 |
+
{{ $key }}: {{ $value | quote }}
|
| 10 |
+
{{- end }}
|
chart/templates/deployment.yaml
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
apiVersion: apps/v1
|
| 2 |
+
kind: Deployment
|
| 3 |
+
metadata:
|
| 4 |
+
labels: {{ include "labels.standard" . | nindent 4 }}
|
| 5 |
+
name: {{ include "name" . }}
|
| 6 |
+
namespace: {{ .Release.Namespace }}
|
| 7 |
+
{{- if .Values.infisical.enabled }}
|
| 8 |
+
annotations:
|
| 9 |
+
secrets.infisical.com/auto-reload: "true"
|
| 10 |
+
{{- end }}
|
| 11 |
+
spec:
|
| 12 |
+
progressDeadlineSeconds: 600
|
| 13 |
+
{{- if not $.Values.autoscaling.enabled }}
|
| 14 |
+
replicas: {{ .Values.replicas }}
|
| 15 |
+
{{- end }}
|
| 16 |
+
revisionHistoryLimit: 10
|
| 17 |
+
selector:
|
| 18 |
+
matchLabels: {{ include "labels.standard" . | nindent 6 }}
|
| 19 |
+
strategy:
|
| 20 |
+
rollingUpdate:
|
| 21 |
+
maxSurge: 25%
|
| 22 |
+
maxUnavailable: 25%
|
| 23 |
+
type: RollingUpdate
|
| 24 |
+
template:
|
| 25 |
+
metadata:
|
| 26 |
+
labels: {{ include "labels.standard" . | nindent 8 }}
|
| 27 |
+
annotations:
|
| 28 |
+
checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }}
|
| 29 |
+
{{- if $.Values.envVars.NODE_LOG_STRUCTURED_DATA }}
|
| 30 |
+
co.elastic.logs/json.expand_keys: "true"
|
| 31 |
+
{{- end }}
|
| 32 |
+
spec:
|
| 33 |
+
{{- if .Values.serviceAccount.enabled }}
|
| 34 |
+
serviceAccountName: "{{ .Values.serviceAccount.name | default (include "name" .) }}"
|
| 35 |
+
{{- end }}
|
| 36 |
+
containers:
|
| 37 |
+
- name: chat-ui
|
| 38 |
+
image: "{{ .Values.image.repository }}/{{ .Values.image.name }}:{{ .Values.image.tag }}"
|
| 39 |
+
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
| 40 |
+
readinessProbe:
|
| 41 |
+
failureThreshold: 30
|
| 42 |
+
periodSeconds: 10
|
| 43 |
+
httpGet:
|
| 44 |
+
path: {{ $.Values.envVars.APP_BASE | default "" }}/healthcheck
|
| 45 |
+
port: {{ $.Values.envVars.APP_PORT | default 3000 | int }}
|
| 46 |
+
livenessProbe:
|
| 47 |
+
failureThreshold: 30
|
| 48 |
+
periodSeconds: 10
|
| 49 |
+
httpGet:
|
| 50 |
+
path: {{ $.Values.envVars.APP_BASE | default "" }}/healthcheck
|
| 51 |
+
port: {{ $.Values.envVars.APP_PORT | default 3000 | int }}
|
| 52 |
+
ports:
|
| 53 |
+
- containerPort: {{ $.Values.envVars.APP_PORT | default 3000 | int }}
|
| 54 |
+
name: http
|
| 55 |
+
protocol: TCP
|
| 56 |
+
{{- if $.Values.monitoring.enabled }}
|
| 57 |
+
- containerPort: {{ $.Values.envVars.METRICS_PORT | default 5565 | int }}
|
| 58 |
+
name: metrics
|
| 59 |
+
protocol: TCP
|
| 60 |
+
{{- end }}
|
| 61 |
+
resources: {{ toYaml .Values.resources | nindent 12 }}
|
| 62 |
+
{{- with $.Values.extraEnv }}
|
| 63 |
+
env:
|
| 64 |
+
{{- toYaml . | nindent 14 }}
|
| 65 |
+
{{- end }}
|
| 66 |
+
envFrom:
|
| 67 |
+
- configMapRef:
|
| 68 |
+
name: {{ include "name" . }}
|
| 69 |
+
{{- if $.Values.infisical.enabled }}
|
| 70 |
+
- secretRef:
|
| 71 |
+
name: {{ include "name" $ }}-secs
|
| 72 |
+
{{- end }}
|
| 73 |
+
{{- with $.Values.extraEnvFrom }}
|
| 74 |
+
{{- toYaml . | nindent 14 }}
|
| 75 |
+
{{- end }}
|
| 76 |
+
nodeSelector: {{ toYaml .Values.nodeSelector | nindent 8 }}
|
| 77 |
+
tolerations: {{ toYaml .Values.tolerations | nindent 8 }}
|
| 78 |
+
volumes:
|
| 79 |
+
- name: config
|
| 80 |
+
configMap:
|
| 81 |
+
name: {{ include "name" . }}
|
chart/templates/hpa.yaml
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{{- if $.Values.autoscaling.enabled }}
|
| 2 |
+
apiVersion: autoscaling/v2
|
| 3 |
+
kind: HorizontalPodAutoscaler
|
| 4 |
+
metadata:
|
| 5 |
+
labels: {{ include "labels.standard" . | nindent 4 }}
|
| 6 |
+
name: {{ include "name" . }}
|
| 7 |
+
namespace: {{ .Release.Namespace }}
|
| 8 |
+
spec:
|
| 9 |
+
scaleTargetRef:
|
| 10 |
+
apiVersion: apps/v1
|
| 11 |
+
kind: Deployment
|
| 12 |
+
name: {{ include "name" . }}
|
| 13 |
+
minReplicas: {{ $.Values.autoscaling.minReplicas }}
|
| 14 |
+
maxReplicas: {{ $.Values.autoscaling.maxReplicas }}
|
| 15 |
+
metrics:
|
| 16 |
+
{{- if ne "" $.Values.autoscaling.targetMemoryUtilizationPercentage }}
|
| 17 |
+
- type: Resource
|
| 18 |
+
resource:
|
| 19 |
+
name: memory
|
| 20 |
+
target:
|
| 21 |
+
type: Utilization
|
| 22 |
+
averageUtilization: {{ $.Values.autoscaling.targetMemoryUtilizationPercentage | int }}
|
| 23 |
+
{{- end }}
|
| 24 |
+
{{- if ne "" $.Values.autoscaling.targetCPUUtilizationPercentage }}
|
| 25 |
+
- type: Resource
|
| 26 |
+
resource:
|
| 27 |
+
name: cpu
|
| 28 |
+
target:
|
| 29 |
+
type: Utilization
|
| 30 |
+
averageUtilization: {{ $.Values.autoscaling.targetCPUUtilizationPercentage | int }}
|
| 31 |
+
{{- end }}
|
| 32 |
+
behavior:
|
| 33 |
+
scaleDown:
|
| 34 |
+
stabilizationWindowSeconds: 600
|
| 35 |
+
policies:
|
| 36 |
+
- type: Percent
|
| 37 |
+
value: 10
|
| 38 |
+
periodSeconds: 60
|
| 39 |
+
scaleUp:
|
| 40 |
+
stabilizationWindowSeconds: 0
|
| 41 |
+
policies:
|
| 42 |
+
- type: Pods
|
| 43 |
+
value: 1
|
| 44 |
+
periodSeconds: 30
|
| 45 |
+
{{- end }}
|
chart/templates/infisical.yaml
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{{- if .Values.infisical.enabled }}
|
| 2 |
+
apiVersion: secrets.infisical.com/v1alpha1
|
| 3 |
+
kind: InfisicalSecret
|
| 4 |
+
metadata:
|
| 5 |
+
name: {{ include "name" $ }}-infisical-secret
|
| 6 |
+
namespace: {{ $.Release.Namespace }}
|
| 7 |
+
spec:
|
| 8 |
+
authentication:
|
| 9 |
+
universalAuth:
|
| 10 |
+
credentialsRef:
|
| 11 |
+
secretName: {{ .Values.infisical.operatorSecretName | quote }}
|
| 12 |
+
secretNamespace: {{ .Values.infisical.operatorSecretNamespace | quote }}
|
| 13 |
+
secretsScope:
|
| 14 |
+
envSlug: {{ .Values.infisical.env | quote }}
|
| 15 |
+
projectSlug: {{ .Values.infisical.project | quote }}
|
| 16 |
+
secretsPath: /
|
| 17 |
+
hostAPI: {{ .Values.infisical.url | quote }}
|
| 18 |
+
managedSecretReference:
|
| 19 |
+
creationPolicy: Owner
|
| 20 |
+
secretName: {{ include "name" $ }}-secs
|
| 21 |
+
secretNamespace: {{ .Release.Namespace | quote }}
|
| 22 |
+
secretType: Opaque
|
| 23 |
+
resyncInterval: {{ .Values.infisical.resyncInterval }}
|
| 24 |
+
{{- end }}
|
chart/templates/ingress-internal.yaml
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{{- if $.Values.ingressInternal.enabled }}
|
| 2 |
+
apiVersion: networking.k8s.io/v1
|
| 3 |
+
kind: Ingress
|
| 4 |
+
metadata:
|
| 5 |
+
annotations: {{ toYaml .Values.ingressInternal.annotations | nindent 4 }}
|
| 6 |
+
labels: {{ include "labels.standard" . | nindent 4 }}
|
| 7 |
+
name: {{ include "name" . }}-internal
|
| 8 |
+
namespace: {{ .Release.Namespace }}
|
| 9 |
+
spec:
|
| 10 |
+
{{ if $.Values.ingressInternal.className }}
|
| 11 |
+
ingressClassName: {{ .Values.ingressInternal.className }}
|
| 12 |
+
{{ end }}
|
| 13 |
+
{{- with .Values.ingressInternal.tls }}
|
| 14 |
+
tls:
|
| 15 |
+
- hosts:
|
| 16 |
+
- {{ $.Values.domain | quote }}
|
| 17 |
+
{{- with .secretName }}
|
| 18 |
+
secretName: {{ . }}
|
| 19 |
+
{{- end }}
|
| 20 |
+
{{- end }}
|
| 21 |
+
rules:
|
| 22 |
+
- host: {{ .Values.domain }}
|
| 23 |
+
http:
|
| 24 |
+
paths:
|
| 25 |
+
- backend:
|
| 26 |
+
service:
|
| 27 |
+
name: {{ include "name" . }}
|
| 28 |
+
port:
|
| 29 |
+
name: http
|
| 30 |
+
path: {{ $.Values.ingressInternal.path | default "/" }}
|
| 31 |
+
pathType: Prefix
|
| 32 |
+
{{- end }}
|
chart/templates/ingress.yaml
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{{- if $.Values.ingress.enabled }}
|
| 2 |
+
apiVersion: networking.k8s.io/v1
|
| 3 |
+
kind: Ingress
|
| 4 |
+
metadata:
|
| 5 |
+
annotations: {{ toYaml .Values.ingress.annotations | nindent 4 }}
|
| 6 |
+
labels: {{ include "labels.standard" . | nindent 4 }}
|
| 7 |
+
name: {{ include "name" . }}
|
| 8 |
+
namespace: {{ .Release.Namespace }}
|
| 9 |
+
spec:
|
| 10 |
+
{{ if $.Values.ingress.className }}
|
| 11 |
+
ingressClassName: {{ .Values.ingress.className }}
|
| 12 |
+
{{ end }}
|
| 13 |
+
{{- with .Values.ingress.tls }}
|
| 14 |
+
tls:
|
| 15 |
+
- hosts:
|
| 16 |
+
- {{ $.Values.domain | quote }}
|
| 17 |
+
{{- with .secretName }}
|
| 18 |
+
secretName: {{ . }}
|
| 19 |
+
{{- end }}
|
| 20 |
+
{{- end }}
|
| 21 |
+
rules:
|
| 22 |
+
- host: {{ .Values.domain }}
|
| 23 |
+
http:
|
| 24 |
+
paths:
|
| 25 |
+
- backend:
|
| 26 |
+
service:
|
| 27 |
+
name: {{ include "name" . }}
|
| 28 |
+
port:
|
| 29 |
+
name: http
|
| 30 |
+
path: {{ $.Values.ingress.path | default "/" }}
|
| 31 |
+
pathType: Prefix
|
| 32 |
+
{{- end }}
|
chart/templates/network-policy.yaml
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{{- if $.Values.networkPolicy.enabled }}
|
| 2 |
+
apiVersion: networking.k8s.io/v1
|
| 3 |
+
kind: NetworkPolicy
|
| 4 |
+
metadata:
|
| 5 |
+
name: {{ include "name" . }}
|
| 6 |
+
namespace: {{ .Release.Namespace }}
|
| 7 |
+
spec:
|
| 8 |
+
egress:
|
| 9 |
+
- ports:
|
| 10 |
+
- port: 53
|
| 11 |
+
protocol: UDP
|
| 12 |
+
to:
|
| 13 |
+
- namespaceSelector:
|
| 14 |
+
matchLabels:
|
| 15 |
+
kubernetes.io/metadata.name: kube-system
|
| 16 |
+
podSelector:
|
| 17 |
+
matchLabels:
|
| 18 |
+
k8s-app: kube-dns
|
| 19 |
+
- to:
|
| 20 |
+
{{- range $ip := .Values.networkPolicy.allowedBlocks }}
|
| 21 |
+
- ipBlock:
|
| 22 |
+
cidr: {{ $ip | quote }}
|
| 23 |
+
{{- end }}
|
| 24 |
+
- to:
|
| 25 |
+
- ipBlock:
|
| 26 |
+
cidr: 0.0.0.0/0
|
| 27 |
+
except:
|
| 28 |
+
- 10.0.0.0/8
|
| 29 |
+
- 172.16.0.0/12
|
| 30 |
+
- 192.168.0.0/16
|
| 31 |
+
- 169.254.169.254/32
|
| 32 |
+
podSelector:
|
| 33 |
+
matchLabels: {{ include "labels.standard" . | nindent 6 }}
|
| 34 |
+
policyTypes:
|
| 35 |
+
- Egress
|
| 36 |
+
{{- end }}
|
chart/templates/service-account.yaml
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{{- if and .Values.serviceAccount.enabled .Values.serviceAccount.create }}
|
| 2 |
+
apiVersion: v1
|
| 3 |
+
kind: ServiceAccount
|
| 4 |
+
automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
|
| 5 |
+
metadata:
|
| 6 |
+
name: "{{ .Values.serviceAccount.name | default (include "name" .) }}"
|
| 7 |
+
namespace: {{ .Release.Namespace }}
|
| 8 |
+
labels: {{ include "labels.standard" . | nindent 4 }}
|
| 9 |
+
{{- with .Values.serviceAccount.annotations }}
|
| 10 |
+
annotations:
|
| 11 |
+
{{- toYaml . | nindent 4 }}
|
| 12 |
+
{{- end }}
|
| 13 |
+
{{- end }}
|
chart/templates/service-monitor.yaml
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{{- if $.Values.monitoring.enabled }}
|
| 2 |
+
apiVersion: monitoring.coreos.com/v1
|
| 3 |
+
kind: ServiceMonitor
|
| 4 |
+
metadata:
|
| 5 |
+
labels: {{ include "labels.standard" . | nindent 4 }}
|
| 6 |
+
name: {{ include "name" . }}
|
| 7 |
+
namespace: {{ .Release.Namespace }}
|
| 8 |
+
spec:
|
| 9 |
+
selector:
|
| 10 |
+
matchLabels: {{ include "labels.standard" . | nindent 6 }}
|
| 11 |
+
endpoints:
|
| 12 |
+
- port: metrics
|
| 13 |
+
path: /metrics
|
| 14 |
+
interval: 15s
|
| 15 |
+
{{- end }}
|
chart/templates/service.yaml
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
apiVersion: v1
|
| 2 |
+
kind: Service
|
| 3 |
+
metadata:
|
| 4 |
+
name: "{{ include "name" . }}"
|
| 5 |
+
annotations: {{ toYaml .Values.service.annotations | nindent 4 }}
|
| 6 |
+
namespace: {{ .Release.Namespace }}
|
| 7 |
+
labels: {{ include "labels.standard" . | nindent 4 }}
|
| 8 |
+
spec:
|
| 9 |
+
ports:
|
| 10 |
+
- name: http
|
| 11 |
+
port: 80
|
| 12 |
+
protocol: TCP
|
| 13 |
+
targetPort: http
|
| 14 |
+
{{- if $.Values.monitoring.enabled }}
|
| 15 |
+
- name: metrics
|
| 16 |
+
port: 5565
|
| 17 |
+
protocol: TCP
|
| 18 |
+
targetPort: metrics
|
| 19 |
+
{{- end }}
|
| 20 |
+
selector: {{ include "labels.standard" . | nindent 4 }}
|
| 21 |
+
type: {{.Values.service.type}}
|
chart/values.yaml
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
image:
|
| 2 |
+
repository: ghcr.io/huggingface
|
| 3 |
+
name: chat-ui
|
| 4 |
+
tag: 0.0.0-latest
|
| 5 |
+
pullPolicy: IfNotPresent
|
| 6 |
+
|
| 7 |
+
replicas: 3
|
| 8 |
+
|
| 9 |
+
domain: huggingface.co
|
| 10 |
+
|
| 11 |
+
networkPolicy:
|
| 12 |
+
enabled: false
|
| 13 |
+
allowedBlocks: []
|
| 14 |
+
|
| 15 |
+
service:
|
| 16 |
+
type: NodePort
|
| 17 |
+
annotations: { }
|
| 18 |
+
|
| 19 |
+
serviceAccount:
|
| 20 |
+
enabled: false
|
| 21 |
+
create: false
|
| 22 |
+
name: ""
|
| 23 |
+
automountServiceAccountToken: true
|
| 24 |
+
annotations: { }
|
| 25 |
+
|
| 26 |
+
ingress:
|
| 27 |
+
enabled: true
|
| 28 |
+
path: "/"
|
| 29 |
+
annotations: { }
|
| 30 |
+
# className: "nginx"
|
| 31 |
+
tls: { }
|
| 32 |
+
# secretName: XXX
|
| 33 |
+
|
| 34 |
+
ingressInternal:
|
| 35 |
+
enabled: false
|
| 36 |
+
path: "/"
|
| 37 |
+
annotations: { }
|
| 38 |
+
# className: "nginx"
|
| 39 |
+
tls: { }
|
| 40 |
+
|
| 41 |
+
resources:
|
| 42 |
+
requests:
|
| 43 |
+
cpu: 2
|
| 44 |
+
memory: 4Gi
|
| 45 |
+
limits:
|
| 46 |
+
cpu: 2
|
| 47 |
+
memory: 4Gi
|
| 48 |
+
nodeSelector: {}
|
| 49 |
+
tolerations: []
|
| 50 |
+
|
| 51 |
+
envVars: { }
|
| 52 |
+
|
| 53 |
+
infisical:
|
| 54 |
+
enabled: false
|
| 55 |
+
env: ""
|
| 56 |
+
project: "huggingchat-v2-a1"
|
| 57 |
+
url: ""
|
| 58 |
+
resyncInterval: 60
|
| 59 |
+
operatorSecretName: "huggingchat-operator-secrets"
|
| 60 |
+
operatorSecretNamespace: "hub-utils"
|
| 61 |
+
|
| 62 |
+
# Allow to environment injections on top or instead of infisical
|
| 63 |
+
extraEnvFrom: []
|
| 64 |
+
extraEnv: []
|
| 65 |
+
|
| 66 |
+
autoscaling:
|
| 67 |
+
enabled: false
|
| 68 |
+
minReplicas: 1
|
| 69 |
+
maxReplicas: 2
|
| 70 |
+
targetMemoryUtilizationPercentage: ""
|
| 71 |
+
targetCPUUtilizationPercentage: ""
|
| 72 |
+
|
| 73 |
+
monitoring:
|
| 74 |
+
enabled: false
|
package-lock.json
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
package.json
CHANGED
|
@@ -9,21 +9,138 @@
|
|
| 9 |
"preview": "vite preview",
|
| 10 |
"prepare": "svelte-kit sync || echo ''",
|
| 11 |
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
| 12 |
-
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
},
|
| 14 |
"devDependencies": {
|
| 15 |
-
"@
|
| 16 |
-
"@
|
| 17 |
-
"@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
"@sveltejs/adapter-node": "^5.2.12",
|
| 19 |
-
"@sveltejs/kit": "^2.
|
| 20 |
-
"@sveltejs/vite-plugin-svelte": "^
|
| 21 |
-
"
|
| 22 |
-
"
|
| 23 |
-
"
|
| 24 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
},
|
| 26 |
"optionalDependencies": {
|
| 27 |
-
"@rollup/rollup-linux-x64-musl": "4.44.*"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
}
|
| 29 |
}
|
|
|
|
| 9 |
"preview": "vite preview",
|
| 10 |
"prepare": "svelte-kit sync || echo ''",
|
| 11 |
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
| 12 |
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
| 13 |
+
"format": "prettier --write .",
|
| 14 |
+
"test": "vitest",
|
| 15 |
+
"updateLocalEnv": "vite-node --options.transformMode.ssr='/.*/' scripts/updateLocalEnv.ts",
|
| 16 |
+
"populate": "vite-node --options.transformMode.ssr='/.*/' scripts/populate.ts",
|
| 17 |
+
"config": "vite-node --options.transformMode.ssr='/.*/' scripts/config.ts"
|
| 18 |
},
|
| 19 |
"devDependencies": {
|
| 20 |
+
"@elysiajs/cors": "^1.3.3",
|
| 21 |
+
"@elysiajs/eden": "^1.3.2",
|
| 22 |
+
"@elysiajs/node": "^1.3.0",
|
| 23 |
+
"@faker-js/faker": "^9.8.0",
|
| 24 |
+
"@fontsource/fira-mono": "^5.2.6",
|
| 25 |
+
"@iconify-json/carbon": "^1.2.10",
|
| 26 |
+
"@iconify-json/eos-icons": "^1.2.2",
|
| 27 |
+
"@neoconfetti/svelte": "^2.2.2",
|
| 28 |
+
"@sveltejs/adapter-auto": "^6.0.1",
|
| 29 |
"@sveltejs/adapter-node": "^5.2.12",
|
| 30 |
+
"@sveltejs/kit": "^2.22.2",
|
| 31 |
+
"@sveltejs/vite-plugin-svelte": "^6.0.0-next.1",
|
| 32 |
+
"@tailwindcss/typography": "^0.5.16",
|
| 33 |
+
"@types/express": "^5.0.3",
|
| 34 |
+
"@types/fs-extra": "^11.0.4",
|
| 35 |
+
"@types/js-yaml": "^4.0.9",
|
| 36 |
+
"@types/jsdom": "^21.1.7",
|
| 37 |
+
"@types/jsonpath": "^0.2.4",
|
| 38 |
+
"@types/katex": "^0.16.7",
|
| 39 |
+
"@types/mime-types": "^3.0.1",
|
| 40 |
+
"@types/minimist": "^1.2.5",
|
| 41 |
+
"@types/node": "^22.15.33",
|
| 42 |
+
"@types/parquetjs": "^0.10.6",
|
| 43 |
+
"@types/sbd": "^1.0.5",
|
| 44 |
+
"@types/uuid": "^10.0.0",
|
| 45 |
+
"@typescript-eslint/eslint-plugin": "^8.35.0",
|
| 46 |
+
"@typescript-eslint/parser": "^8.35.0",
|
| 47 |
+
"bson-objectid": "^2.0.4",
|
| 48 |
+
"dompurify": "^3.2.6",
|
| 49 |
+
"elysia": "^1.3.5",
|
| 50 |
+
"eslint": "^9.29.0",
|
| 51 |
+
"eslint-config-prettier": "^10.1.5",
|
| 52 |
+
"eslint-plugin-svelte": "^3.10.1",
|
| 53 |
+
"fs-extra": "^11.3.0",
|
| 54 |
+
"husky": "^9.1.7",
|
| 55 |
+
"isomorphic-dompurify": "^2.25.0",
|
| 56 |
+
"js-yaml": "^4.1.0",
|
| 57 |
+
"jsonrepair": "^3.12.0",
|
| 58 |
+
"minimist": "^1.2.8",
|
| 59 |
+
"mongodb-memory-server": "^10.1.4",
|
| 60 |
+
"node-llama-cpp": "^3.10.0",
|
| 61 |
+
"prettier": "^3.6.1",
|
| 62 |
+
"prettier-plugin-svelte": "^3.4.0",
|
| 63 |
+
"prettier-plugin-tailwindcss": "^0.6.13",
|
| 64 |
+
"prom-client": "^15.1.3",
|
| 65 |
+
"sade": "^1.8.1",
|
| 66 |
+
"superjson": "^2.2.2",
|
| 67 |
+
|
| 68 |
+
"svelte": "^5.34.8",
|
| 69 |
+
"svelte-check": "^4.2.2",
|
| 70 |
+
"svelte-gestures": "^5.1.4",
|
| 71 |
+
"ts-node": "^10.9.2",
|
| 72 |
+
"tslib": "^2.8.1",
|
| 73 |
+
"typescript": "^5.8.3",
|
| 74 |
+
"unplugin-icons": "^22.1.0",
|
| 75 |
+
"vite": "^7.0.0",
|
| 76 |
+
"vite-node": "^3.2.4",
|
| 77 |
+
"vitest": "^3.2.4"
|
| 78 |
+
},
|
| 79 |
+
"dependencies": {
|
| 80 |
+
"@aws-sdk/credential-providers": "^3.835.0",
|
| 81 |
+
"@elysiajs/swagger": "^1.3.0",
|
| 82 |
+
"@ghostery/adblocker-playwright": "^2.8.0",
|
| 83 |
+
"@gradio/client": "^1.15.3",
|
| 84 |
+
"@huggingface/hub": "^2.2.0",
|
| 85 |
+
"@huggingface/inference": "^4.0.6",
|
| 86 |
+
"@huggingface/mcp-client": "^0.2.0",
|
| 87 |
+
"@huggingface/tasks": "^0.19.19",
|
| 88 |
+
"@huggingface/transformers": "^3.6.0",
|
| 89 |
+
"@iconify-json/bi": "^1.2.4",
|
| 90 |
+
"@playwright/browser-chromium": "^1.53.1",
|
| 91 |
+
"@resvg/resvg-js": "^2.6.2",
|
| 92 |
+
"autoprefixer": "^10.4.21",
|
| 93 |
+
"aws-sigv4-fetch": "^4.4.1",
|
| 94 |
+
"aws4": "^1.13.2",
|
| 95 |
+
"date-fns": "^4.1.0",
|
| 96 |
+
"dotenv": "^16.6.0",
|
| 97 |
+
"express": "^5.1.0",
|
| 98 |
+
"file-type": "^21.0.0",
|
| 99 |
+
"google-auth-library": "^10.1.0",
|
| 100 |
+
"handlebars": "^4.7.8",
|
| 101 |
+
"highlight.js": "^11.11.1",
|
| 102 |
+
"image-size": "^2.0.2",
|
| 103 |
+
"ip-address": "^10.0.1",
|
| 104 |
+
"jose": "^6.0.11",
|
| 105 |
+
"jsdom": "^26.1.0",
|
| 106 |
+
"json5": "^2.2.3",
|
| 107 |
+
"jsonpath": "^1.1.1",
|
| 108 |
+
"katex": "^0.16.22",
|
| 109 |
+
"lint-staged": "^16.1.2",
|
| 110 |
+
"marked": "^15.0.12",
|
| 111 |
+
"mongodb": "^6.17.0",
|
| 112 |
+
"nanoid": "^5.1.5",
|
| 113 |
+
"natural": "^8.1.0",
|
| 114 |
+
"openid-client": "^6.6.1",
|
| 115 |
+
"parquetjs": "^0.11.2",
|
| 116 |
+
"pino": "^9.7.0",
|
| 117 |
+
"pino-pretty": "^13.0.0",
|
| 118 |
+
"playwright": "^1.53.1",
|
| 119 |
+
"postcss": "^8.5.6",
|
| 120 |
+
"saslprep": "^1.0.3",
|
| 121 |
+
"satori": "^0.15.2",
|
| 122 |
+
"satori-html": "^0.3.2",
|
| 123 |
+
"sbd": "^1.0.19",
|
| 124 |
+
"serpapi": "^2.1.0",
|
| 125 |
+
"sharp": "^0.34.2",
|
| 126 |
+
"tailwind-scrollbar": "^4.0.2",
|
| 127 |
+
"tailwindcss": "^4.1.11",
|
| 128 |
+
"uuid": "^11.1.0",
|
| 129 |
+
"vitest-browser-svelte": "^1.0.0",
|
| 130 |
+
"zod": "^3.25.67"
|
| 131 |
},
|
| 132 |
"optionalDependencies": {
|
| 133 |
+
"@rollup/rollup-linux-x64-musl": "4.44.*",
|
| 134 |
+
"@anthropic-ai/sdk": "^0.32.1",
|
| 135 |
+
"@anthropic-ai/vertex-sdk": "^0.4.1",
|
| 136 |
+
"@aws-sdk/client-bedrock-runtime": "^3.631.0",
|
| 137 |
+
"@google-cloud/vertexai": "^1.1.0",
|
| 138 |
+
"@google/generative-ai": "^0.24.0",
|
| 139 |
+
"aws4fetch": "^1.0.17",
|
| 140 |
+
"cohere-ai": "^7.9.0",
|
| 141 |
+
"openai": "^4.44.0"
|
| 142 |
+
},
|
| 143 |
+
"overrides": {
|
| 144 |
+
"@reflink/reflink": "file:stub/@reflink/reflink"
|
| 145 |
}
|
| 146 |
}
|
postcss.config.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export default {
|
| 2 |
+
plugins: {
|
| 3 |
+
tailwindcss: {},
|
| 4 |
+
autoprefixer: {},
|
| 5 |
+
},
|
| 6 |
+
};
|
scripts/config.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sade from "sade";
|
| 2 |
+
|
| 3 |
+
// @ts-expect-error: vite-node makes the var available but the typescript compiler doesn't see them
|
| 4 |
+
import { config, ready } from "$lib/server/config";
|
| 5 |
+
|
| 6 |
+
const prog = sade("config");
|
| 7 |
+
await ready;
|
| 8 |
+
prog
|
| 9 |
+
.command("clear")
|
| 10 |
+
.describe("Clear all config keys")
|
| 11 |
+
.action(async () => {
|
| 12 |
+
console.log("Clearing config...");
|
| 13 |
+
await clear();
|
| 14 |
+
});
|
| 15 |
+
|
| 16 |
+
prog
|
| 17 |
+
.command("add <key> <value>")
|
| 18 |
+
.describe("Add a new config key")
|
| 19 |
+
.action(async (key: string, value: string) => {
|
| 20 |
+
await add(key, value);
|
| 21 |
+
});
|
| 22 |
+
|
| 23 |
+
prog
|
| 24 |
+
.command("remove <key>")
|
| 25 |
+
.describe("Remove a config key")
|
| 26 |
+
.action(async (key: string) => {
|
| 27 |
+
console.log(`Removing ${key}`);
|
| 28 |
+
await remove(key);
|
| 29 |
+
process.exit(0);
|
| 30 |
+
});
|
| 31 |
+
|
| 32 |
+
prog
|
| 33 |
+
.command("help")
|
| 34 |
+
.describe("Show help information")
|
| 35 |
+
.action(() => {
|
| 36 |
+
prog.help();
|
| 37 |
+
process.exit(0);
|
| 38 |
+
});
|
| 39 |
+
|
| 40 |
+
async function clear() {
|
| 41 |
+
await config.clear();
|
| 42 |
+
process.exit(0);
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
async function add(key: string, value: string) {
|
| 46 |
+
if (!key || !value) {
|
| 47 |
+
console.error("Key and value are required");
|
| 48 |
+
process.exit(1);
|
| 49 |
+
}
|
| 50 |
+
await config.set(key as keyof typeof config.keysFromEnv, value);
|
| 51 |
+
process.exit(0);
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
async function remove(key: string) {
|
| 55 |
+
if (!key) {
|
| 56 |
+
console.error("Key is required");
|
| 57 |
+
process.exit(1);
|
| 58 |
+
}
|
| 59 |
+
await config.delete(key as keyof typeof config.keysFromEnv);
|
| 60 |
+
process.exit(0);
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
// Parse arguments and handle help automatically
|
| 64 |
+
prog.parse(process.argv);
|
scripts/populate.ts
ADDED
|
@@ -0,0 +1,391 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import readline from "readline";
|
| 2 |
+
import minimist from "minimist";
|
| 3 |
+
|
| 4 |
+
// @ts-expect-error: vite-node makes the var available but the typescript compiler doesn't see them
|
| 5 |
+
import { env } from "$env/dynamic/private";
|
| 6 |
+
|
| 7 |
+
import { faker } from "@faker-js/faker";
|
| 8 |
+
import { ObjectId } from "mongodb";
|
| 9 |
+
|
| 10 |
+
// @ts-expect-error: vite-node makes the var available but the typescript compiler doesn't see them
|
| 11 |
+
import { ready } from "$lib/server/config";
|
| 12 |
+
import { collections } from "$lib/server/database.ts";
|
| 13 |
+
import { models } from "../src/lib/server/models.ts";
|
| 14 |
+
import type { User } from "../src/lib/types/User";
|
| 15 |
+
import type { Assistant } from "../src/lib/types/Assistant";
|
| 16 |
+
import type { Conversation } from "../src/lib/types/Conversation";
|
| 17 |
+
import type { Settings } from "../src/lib/types/Settings";
|
| 18 |
+
import type { CommunityToolDB, ToolLogoColor, ToolLogoIcon } from "../src/lib/types/Tool";
|
| 19 |
+
import { defaultEmbeddingModel } from "../src/lib/server/embeddingModels.ts";
|
| 20 |
+
import { Message } from "../src/lib/types/Message.ts";
|
| 21 |
+
|
| 22 |
+
import { addChildren } from "../src/lib/utils/tree/addChildren.ts";
|
| 23 |
+
import { generateSearchTokens } from "../src/lib/utils/searchTokens.ts";
|
| 24 |
+
import { ReviewStatus } from "../src/lib/types/Review.ts";
|
| 25 |
+
import fs from "fs";
|
| 26 |
+
import path from "path";
|
| 27 |
+
import { MessageUpdateType } from "../src/lib/types/MessageUpdate.ts";
|
| 28 |
+
import { MessageReasoningUpdateType } from "../src/lib/types/MessageUpdate.ts";
|
| 29 |
+
|
| 30 |
+
const rl = readline.createInterface({
|
| 31 |
+
input: process.stdin,
|
| 32 |
+
output: process.stdout,
|
| 33 |
+
});
|
| 34 |
+
|
| 35 |
+
await ready;
|
| 36 |
+
|
| 37 |
+
rl.on("close", function () {
|
| 38 |
+
process.exit(0);
|
| 39 |
+
});
|
| 40 |
+
|
| 41 |
+
const samples = fs.readFileSync(path.join(__dirname, "samples.txt"), "utf8").split("\n---\n");
|
| 42 |
+
|
| 43 |
+
const possibleFlags = ["reset", "all", "users", "settings", "assistants", "conversations", "tools"];
|
| 44 |
+
const argv = minimist(process.argv.slice(2));
|
| 45 |
+
const flags = argv["_"].filter((flag) => possibleFlags.includes(flag));
|
| 46 |
+
|
| 47 |
+
async function generateMessages(preprompt?: string): Promise<Message[]> {
|
| 48 |
+
const isLinear = faker.datatype.boolean(0.5);
|
| 49 |
+
const isInterrupted = faker.datatype.boolean(0.05);
|
| 50 |
+
|
| 51 |
+
const messages: Message[] = [];
|
| 52 |
+
|
| 53 |
+
messages.push({
|
| 54 |
+
id: crypto.randomUUID(),
|
| 55 |
+
from: "system",
|
| 56 |
+
content: preprompt ?? "",
|
| 57 |
+
createdAt: faker.date.recent({ days: 30 }),
|
| 58 |
+
updatedAt: faker.date.recent({ days: 30 }),
|
| 59 |
+
});
|
| 60 |
+
|
| 61 |
+
let isUser = true;
|
| 62 |
+
let lastId = messages[0].id;
|
| 63 |
+
if (isLinear) {
|
| 64 |
+
const convLength = faker.number.int({ min: 1, max: 25 }) * 2; // must always be even
|
| 65 |
+
|
| 66 |
+
for (let i = 0; i < convLength; i++) {
|
| 67 |
+
const hasReasoning = Math.random() < 0.2;
|
| 68 |
+
lastId = addChildren(
|
| 69 |
+
{
|
| 70 |
+
messages,
|
| 71 |
+
rootMessageId: messages[0].id,
|
| 72 |
+
},
|
| 73 |
+
{
|
| 74 |
+
from: isUser ? "user" : "assistant",
|
| 75 |
+
content:
|
| 76 |
+
faker.lorem.sentence({
|
| 77 |
+
min: 10,
|
| 78 |
+
max: isUser ? 50 : 200,
|
| 79 |
+
}) +
|
| 80 |
+
(!isUser && Math.random() < 0.1
|
| 81 |
+
? "\n```\n" + faker.helpers.arrayElement(samples) + "\n```\n"
|
| 82 |
+
: ""),
|
| 83 |
+
createdAt: faker.date.recent({ days: 30 }),
|
| 84 |
+
updatedAt: faker.date.recent({ days: 30 }),
|
| 85 |
+
reasoning: hasReasoning ? faker.lorem.paragraphs(2) : undefined,
|
| 86 |
+
updates: hasReasoning
|
| 87 |
+
? [
|
| 88 |
+
{
|
| 89 |
+
type: MessageUpdateType.Reasoning,
|
| 90 |
+
subtype: MessageReasoningUpdateType.Status,
|
| 91 |
+
uuid: crypto.randomUUID(),
|
| 92 |
+
status: "thinking",
|
| 93 |
+
},
|
| 94 |
+
]
|
| 95 |
+
: [],
|
| 96 |
+
interrupted: !isUser && i === convLength - 1 && isInterrupted,
|
| 97 |
+
},
|
| 98 |
+
lastId
|
| 99 |
+
);
|
| 100 |
+
isUser = !isUser;
|
| 101 |
+
}
|
| 102 |
+
} else {
|
| 103 |
+
const convLength = faker.number.int({ min: 2, max: 200 });
|
| 104 |
+
|
| 105 |
+
for (let i = 0; i < convLength; i++) {
|
| 106 |
+
const hasReasoning = Math.random() < 0.2;
|
| 107 |
+
addChildren(
|
| 108 |
+
{
|
| 109 |
+
messages,
|
| 110 |
+
rootMessageId: messages[0].id,
|
| 111 |
+
},
|
| 112 |
+
{
|
| 113 |
+
from: isUser ? "user" : "assistant",
|
| 114 |
+
content:
|
| 115 |
+
faker.lorem.sentence({
|
| 116 |
+
min: 10,
|
| 117 |
+
max: isUser ? 50 : 200,
|
| 118 |
+
}) +
|
| 119 |
+
(!isUser && Math.random() < 0.1
|
| 120 |
+
? "\n```\n" + faker.helpers.arrayElement(samples) + "\n```\n"
|
| 121 |
+
: ""),
|
| 122 |
+
reasoning: hasReasoning ? faker.lorem.paragraphs(2) : undefined,
|
| 123 |
+
updates: hasReasoning
|
| 124 |
+
? [
|
| 125 |
+
{
|
| 126 |
+
type: MessageUpdateType.Reasoning,
|
| 127 |
+
subtype: MessageReasoningUpdateType.Status,
|
| 128 |
+
uuid: crypto.randomUUID(),
|
| 129 |
+
status: "thinking",
|
| 130 |
+
},
|
| 131 |
+
]
|
| 132 |
+
: [],
|
| 133 |
+
createdAt: faker.date.recent({ days: 30 }),
|
| 134 |
+
updatedAt: faker.date.recent({ days: 30 }),
|
| 135 |
+
interrupted: !isUser && i === convLength - 1 && isInterrupted,
|
| 136 |
+
},
|
| 137 |
+
faker.helpers.arrayElement([
|
| 138 |
+
messages[0].id,
|
| 139 |
+
...messages.filter((m) => m.from === (isUser ? "assistant" : "user")).map((m) => m.id),
|
| 140 |
+
])
|
| 141 |
+
);
|
| 142 |
+
|
| 143 |
+
isUser = !isUser;
|
| 144 |
+
}
|
| 145 |
+
}
|
| 146 |
+
return messages;
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
async function seed() {
|
| 150 |
+
console.log("Seeding...");
|
| 151 |
+
const modelIds = models.map((model) => model.id);
|
| 152 |
+
|
| 153 |
+
if (flags.includes("reset")) {
|
| 154 |
+
console.log("Starting reset of DB");
|
| 155 |
+
await collections.users.deleteMany({});
|
| 156 |
+
await collections.settings.deleteMany({});
|
| 157 |
+
await collections.assistants.deleteMany({});
|
| 158 |
+
await collections.conversations.deleteMany({});
|
| 159 |
+
await collections.tools.deleteMany({});
|
| 160 |
+
await collections.migrationResults.deleteMany({});
|
| 161 |
+
await collections.semaphores.deleteMany({});
|
| 162 |
+
console.log("Reset done");
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
if (flags.includes("users") || flags.includes("all")) {
|
| 166 |
+
console.log("Creating 100 new users");
|
| 167 |
+
const newUsers: User[] = Array.from({ length: 100 }, () => ({
|
| 168 |
+
_id: new ObjectId(),
|
| 169 |
+
createdAt: faker.date.recent({ days: 30 }),
|
| 170 |
+
updatedAt: faker.date.recent({ days: 30 }),
|
| 171 |
+
username: faker.internet.userName(),
|
| 172 |
+
name: faker.person.fullName(),
|
| 173 |
+
hfUserId: faker.string.alphanumeric(24),
|
| 174 |
+
avatarUrl: faker.image.avatar(),
|
| 175 |
+
}));
|
| 176 |
+
|
| 177 |
+
await collections.users.insertMany(newUsers);
|
| 178 |
+
console.log("Done creating users.");
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
+
const users = await collections.users.find().toArray();
|
| 182 |
+
if (flags.includes("settings") || flags.includes("all")) {
|
| 183 |
+
console.log("Updating settings for all users");
|
| 184 |
+
users.forEach(async (user) => {
|
| 185 |
+
const settings: Settings = {
|
| 186 |
+
userId: user._id,
|
| 187 |
+
shareConversationsWithModelAuthors: faker.datatype.boolean(0.25),
|
| 188 |
+
hideEmojiOnSidebar: faker.datatype.boolean(0.25),
|
| 189 |
+
ethicsModalAcceptedAt: faker.date.recent({ days: 30 }),
|
| 190 |
+
activeModel: faker.helpers.arrayElement(modelIds),
|
| 191 |
+
createdAt: faker.date.recent({ days: 30 }),
|
| 192 |
+
updatedAt: faker.date.recent({ days: 30 }),
|
| 193 |
+
disableStream: faker.datatype.boolean(0.25),
|
| 194 |
+
directPaste: faker.datatype.boolean(0.25),
|
| 195 |
+
customPrompts: {},
|
| 196 |
+
assistants: [],
|
| 197 |
+
};
|
| 198 |
+
await collections.settings.updateOne(
|
| 199 |
+
{ userId: user._id },
|
| 200 |
+
{ $set: { ...settings } },
|
| 201 |
+
{ upsert: true }
|
| 202 |
+
);
|
| 203 |
+
});
|
| 204 |
+
console.log("Done updating settings.");
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
if (flags.includes("assistants") || flags.includes("all")) {
|
| 208 |
+
console.log("Creating assistants for all users");
|
| 209 |
+
await Promise.all(
|
| 210 |
+
users.map(async (user) => {
|
| 211 |
+
const name = faker.animal.insect();
|
| 212 |
+
const assistants = faker.helpers.multiple<Assistant>(
|
| 213 |
+
() => ({
|
| 214 |
+
_id: new ObjectId(),
|
| 215 |
+
name,
|
| 216 |
+
createdById: user._id,
|
| 217 |
+
createdByName: user.username,
|
| 218 |
+
createdAt: faker.date.recent({ days: 30 }),
|
| 219 |
+
updatedAt: faker.date.recent({ days: 30 }),
|
| 220 |
+
userCount: faker.number.int({ min: 1, max: 100000 }),
|
| 221 |
+
review: faker.helpers.enumValue(ReviewStatus),
|
| 222 |
+
modelId: faker.helpers.arrayElement(modelIds),
|
| 223 |
+
description: faker.lorem.sentence(),
|
| 224 |
+
preprompt: faker.hacker.phrase(),
|
| 225 |
+
exampleInputs: faker.helpers.multiple(() => faker.lorem.sentence(), {
|
| 226 |
+
count: faker.number.int({ min: 0, max: 4 }),
|
| 227 |
+
}),
|
| 228 |
+
searchTokens: generateSearchTokens(name),
|
| 229 |
+
last24HoursCount: faker.number.int({ min: 0, max: 1000 }),
|
| 230 |
+
}),
|
| 231 |
+
{ count: faker.number.int({ min: 3, max: 10 }) }
|
| 232 |
+
);
|
| 233 |
+
await collections.assistants.insertMany(assistants);
|
| 234 |
+
await collections.settings.updateOne(
|
| 235 |
+
{ userId: user._id },
|
| 236 |
+
{ $set: { assistants: assistants.map((a) => a._id.toString()) } },
|
| 237 |
+
{ upsert: true }
|
| 238 |
+
);
|
| 239 |
+
})
|
| 240 |
+
);
|
| 241 |
+
console.log("Done creating assistants.");
|
| 242 |
+
}
|
| 243 |
+
|
| 244 |
+
if (flags.includes("conversations") || flags.includes("all")) {
|
| 245 |
+
console.log("Creating conversations for all users");
|
| 246 |
+
await Promise.all(
|
| 247 |
+
users.map(async (user) => {
|
| 248 |
+
const conversations = faker.helpers.multiple(
|
| 249 |
+
async () => {
|
| 250 |
+
const settings = await collections.settings.findOne<Settings>({ userId: user._id });
|
| 251 |
+
|
| 252 |
+
const assistantId =
|
| 253 |
+
settings?.assistants && settings.assistants.length > 0 && faker.datatype.boolean(0.1)
|
| 254 |
+
? faker.helpers.arrayElement<ObjectId>(settings.assistants)
|
| 255 |
+
: undefined;
|
| 256 |
+
|
| 257 |
+
const preprompt =
|
| 258 |
+
(assistantId
|
| 259 |
+
? await collections.assistants
|
| 260 |
+
.findOne({ _id: assistantId })
|
| 261 |
+
.then((assistant: Assistant) => assistant?.preprompt ?? "")
|
| 262 |
+
: faker.helpers.maybe(() => faker.hacker.phrase(), { probability: 0.5 })) ?? "";
|
| 263 |
+
|
| 264 |
+
const messages = await generateMessages(preprompt);
|
| 265 |
+
|
| 266 |
+
const conv = {
|
| 267 |
+
_id: new ObjectId(),
|
| 268 |
+
userId: user._id,
|
| 269 |
+
assistantId,
|
| 270 |
+
preprompt,
|
| 271 |
+
createdAt: faker.date.recent({ days: 145 }),
|
| 272 |
+
updatedAt: faker.date.recent({ days: 145 }),
|
| 273 |
+
model: faker.helpers.arrayElement(modelIds),
|
| 274 |
+
title: faker.internet.emoji() + " " + faker.hacker.phrase(),
|
| 275 |
+
embeddingModel: defaultEmbeddingModel.id,
|
| 276 |
+
messages,
|
| 277 |
+
rootMessageId: messages[0].id,
|
| 278 |
+
} satisfies Conversation;
|
| 279 |
+
|
| 280 |
+
return conv;
|
| 281 |
+
},
|
| 282 |
+
{ count: faker.number.int({ min: 10, max: 200 }) }
|
| 283 |
+
);
|
| 284 |
+
|
| 285 |
+
await collections.conversations.insertMany(await Promise.all(conversations));
|
| 286 |
+
})
|
| 287 |
+
);
|
| 288 |
+
console.log("Done creating conversations.");
|
| 289 |
+
}
|
| 290 |
+
|
| 291 |
+
// generate Community Tools
|
| 292 |
+
if (flags.includes("tools") || flags.includes("all")) {
|
| 293 |
+
const tools = await Promise.all(
|
| 294 |
+
faker.helpers.multiple(
|
| 295 |
+
() => {
|
| 296 |
+
const _id = new ObjectId();
|
| 297 |
+
const displayName = faker.company.catchPhrase();
|
| 298 |
+
const description = faker.company.catchPhrase();
|
| 299 |
+
const color = faker.helpers.arrayElement([
|
| 300 |
+
"purple",
|
| 301 |
+
"blue",
|
| 302 |
+
"green",
|
| 303 |
+
"yellow",
|
| 304 |
+
"red",
|
| 305 |
+
]) satisfies ToolLogoColor;
|
| 306 |
+
const icon = faker.helpers.arrayElement([
|
| 307 |
+
"wikis",
|
| 308 |
+
"tools",
|
| 309 |
+
"camera",
|
| 310 |
+
"code",
|
| 311 |
+
"email",
|
| 312 |
+
"cloud",
|
| 313 |
+
"terminal",
|
| 314 |
+
"game",
|
| 315 |
+
"chat",
|
| 316 |
+
"speaker",
|
| 317 |
+
"video",
|
| 318 |
+
]) satisfies ToolLogoIcon;
|
| 319 |
+
const baseUrl = faker.helpers.arrayElement([
|
| 320 |
+
"stabilityai/stable-diffusion-3-medium",
|
| 321 |
+
"multimodalart/cosxl",
|
| 322 |
+
"gokaygokay/SD3-Long-Captioner",
|
| 323 |
+
"xichenhku/MimicBrush",
|
| 324 |
+
]);
|
| 325 |
+
|
| 326 |
+
// keep empty for populate for now
|
| 327 |
+
|
| 328 |
+
const user: User = faker.helpers.arrayElement(users);
|
| 329 |
+
const createdById = user._id;
|
| 330 |
+
const createdByName = user.username ?? user.name;
|
| 331 |
+
|
| 332 |
+
return {
|
| 333 |
+
type: "community" as const,
|
| 334 |
+
_id,
|
| 335 |
+
createdById,
|
| 336 |
+
createdByName,
|
| 337 |
+
displayName,
|
| 338 |
+
name: displayName.toLowerCase().replace(" ", "_"),
|
| 339 |
+
endpoint: "/test",
|
| 340 |
+
description,
|
| 341 |
+
color,
|
| 342 |
+
icon,
|
| 343 |
+
baseUrl,
|
| 344 |
+
inputs: [],
|
| 345 |
+
outputPath: null,
|
| 346 |
+
outputType: "str" as const,
|
| 347 |
+
showOutput: false,
|
| 348 |
+
useCount: faker.number.int({ min: 0, max: 100000 }),
|
| 349 |
+
last24HoursUseCount: faker.number.int({ min: 0, max: 1000 }),
|
| 350 |
+
createdAt: faker.date.recent({ days: 30 }),
|
| 351 |
+
updatedAt: faker.date.recent({ days: 30 }),
|
| 352 |
+
searchTokens: generateSearchTokens(displayName),
|
| 353 |
+
review: faker.helpers.enumValue(ReviewStatus),
|
| 354 |
+
outputComponent: null,
|
| 355 |
+
outputComponentIdx: null,
|
| 356 |
+
};
|
| 357 |
+
},
|
| 358 |
+
{ count: faker.number.int({ min: 10, max: 200 }) }
|
| 359 |
+
)
|
| 360 |
+
);
|
| 361 |
+
|
| 362 |
+
await collections.tools.insertMany(tools satisfies CommunityToolDB[]);
|
| 363 |
+
}
|
| 364 |
+
}
|
| 365 |
+
|
| 366 |
+
// run seed
|
| 367 |
+
(async () => {
|
| 368 |
+
try {
|
| 369 |
+
rl.question(
|
| 370 |
+
"You're about to run a seeding script on the following MONGODB_URL: \x1b[31m" +
|
| 371 |
+
env.MONGODB_URL +
|
| 372 |
+
"\x1b[0m\n\n With the following flags: \x1b[31m" +
|
| 373 |
+
flags.join("\x1b[0m , \x1b[31m") +
|
| 374 |
+
"\x1b[0m\n \n\n Are you sure you want to continue? (yes/no): ",
|
| 375 |
+
async (confirm) => {
|
| 376 |
+
if (confirm !== "yes") {
|
| 377 |
+
console.log("Not 'yes', exiting.");
|
| 378 |
+
rl.close();
|
| 379 |
+
process.exit(0);
|
| 380 |
+
}
|
| 381 |
+
console.log("Starting seeding...");
|
| 382 |
+
await seed();
|
| 383 |
+
console.log("Seeding done.");
|
| 384 |
+
rl.close();
|
| 385 |
+
}
|
| 386 |
+
);
|
| 387 |
+
} catch (e) {
|
| 388 |
+
console.error(e);
|
| 389 |
+
process.exit(1);
|
| 390 |
+
}
|
| 391 |
+
})();
|
scripts/samples.txt
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Observable, of, from, interval, throwError } from 'rxjs';
|
| 2 |
+
import { map, filter, catchError, switchMap, take, tap } from 'rxjs/operators';
|
| 3 |
+
|
| 4 |
+
// Mock function to fetch stock prices (simulates API call)
|
| 5 |
+
const fetchStockPrice = (ticker: string): Observable<number> => {
|
| 6 |
+
return new Observable<number>((observer) => {
|
| 7 |
+
const intervalId = setInterval(() => {
|
| 8 |
+
if (Math.random() < 0.1) { // Simulating an error 10% of the time
|
| 9 |
+
observer.error(`Error fetching stock price for ${ticker}`);
|
| 10 |
+
} else {
|
| 11 |
+
const price = parseFloat((Math.random() * 1000).toFixed(2));
|
| 12 |
+
observer.next(price);
|
| 13 |
+
}
|
| 14 |
+
}, 1000);
|
| 15 |
+
|
| 16 |
+
return () => {
|
| 17 |
+
clearInterval(intervalId);
|
| 18 |
+
console.log(`Stopped fetching prices for ${ticker}`);
|
| 19 |
+
};
|
| 20 |
+
});
|
| 21 |
+
};
|
| 22 |
+
|
| 23 |
+
// Example usage: Tracking stock price updates
|
| 24 |
+
const stockTicker = 'AAPL';
|
| 25 |
+
const stockPrice$ = fetchStockPrice(stockTicker).pipe(
|
| 26 |
+
map(price => ({ ticker: stockTicker, price })), // Transform data
|
| 27 |
+
filter(data => data.price > 500), // Only keep prices above 500
|
| 28 |
+
tap(data => console.log(`Price update:`, data)), // Side effect: Logging
|
| 29 |
+
catchError(err => {
|
| 30 |
+
console.error(err);
|
| 31 |
+
return of({ ticker: stockTicker, price: null }); // Fallback observable
|
| 32 |
+
})
|
| 33 |
+
);
|
| 34 |
+
|
| 35 |
+
// Subscribe to the stock price updates
|
| 36 |
+
const subscription = stockPrice$.subscribe({
|
| 37 |
+
next: data => console.log(`Subscriber received:`, data),
|
| 38 |
+
error: err => console.error(`Subscription error:`, err),
|
| 39 |
+
complete: () => console.log('Stream complete'),
|
| 40 |
+
});
|
| 41 |
+
|
| 42 |
+
// Automatically unsubscribe after 10 seconds
|
| 43 |
+
setTimeout(() => {
|
| 44 |
+
subscription.unsubscribe();
|
| 45 |
+
console.log('Unsubscribed from stock price updates.');
|
| 46 |
+
}, 10000);
|
| 47 |
+
---
|
| 48 |
+
class EnforceAttrsMeta(type):
|
| 49 |
+
"""
|
| 50 |
+
Metaclass that enforces the presence of specific attributes in a class
|
| 51 |
+
and automatically decorates methods with a logging wrapper.
|
| 52 |
+
"""
|
| 53 |
+
|
| 54 |
+
required_attributes = ['name', 'version']
|
| 55 |
+
|
| 56 |
+
def __new__(cls, name, bases, class_dict):
|
| 57 |
+
"""
|
| 58 |
+
Create a new class with enforced attributes and method logging.
|
| 59 |
+
|
| 60 |
+
:param name: Name of the class being created.
|
| 61 |
+
:param bases: Tuple of base classes.
|
| 62 |
+
:param class_dict: Dictionary of attributes and methods of the class.
|
| 63 |
+
:return: Newly created class object.
|
| 64 |
+
"""
|
| 65 |
+
# Ensure required attributes exist
|
| 66 |
+
for attr in cls.required_attributes:
|
| 67 |
+
if attr not in class_dict:
|
| 68 |
+
raise TypeError(f"Class '{name}' is missing required attribute '{attr}'")
|
| 69 |
+
|
| 70 |
+
# Wrap all methods in a logging decorator
|
| 71 |
+
for key, value in class_dict.items():
|
| 72 |
+
if callable(value): # Check if it's a method
|
| 73 |
+
class_dict[key] = cls.log_calls(value)
|
| 74 |
+
|
| 75 |
+
return super().__new__(cls, name, bases, class_dict)
|
| 76 |
+
|
| 77 |
+
@staticmethod
|
| 78 |
+
def log_calls(func):
|
| 79 |
+
"""
|
| 80 |
+
Decorator that logs method calls and arguments.
|
| 81 |
+
|
| 82 |
+
:param func: Function to be wrapped.
|
| 83 |
+
:return: Wrapped function with logging.
|
| 84 |
+
"""
|
| 85 |
+
def wrapper(*args, **kwargs):
|
| 86 |
+
print(f"Calling {func.__name__} with args={args} kwargs={kwargs}")
|
| 87 |
+
result = func(*args, **kwargs)
|
| 88 |
+
print(f"{func.__name__} returned {result}")
|
| 89 |
+
return result
|
| 90 |
+
return wrapper
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
class PluginBase(metaclass=EnforceAttrsMeta):
|
| 94 |
+
"""
|
| 95 |
+
Base class for plugins that enforces required attributes and logging.
|
| 96 |
+
"""
|
| 97 |
+
name = "BasePlugin"
|
| 98 |
+
version = "1.0"
|
| 99 |
+
|
| 100 |
+
def run(self, data):
|
| 101 |
+
"""
|
| 102 |
+
Process the input data.
|
| 103 |
+
|
| 104 |
+
:param data: The data to be processed.
|
| 105 |
+
:return: Processed result.
|
| 106 |
+
"""
|
| 107 |
+
return f"Processed {data}"
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
class CustomPlugin(PluginBase):
|
| 111 |
+
"""
|
| 112 |
+
Custom plugin that extends PluginBase and adheres to enforced rules.
|
| 113 |
+
"""
|
| 114 |
+
name = "CustomPlugin"
|
| 115 |
+
version = "2.0"
|
| 116 |
+
|
| 117 |
+
def run(self, data):
|
| 118 |
+
"""
|
| 119 |
+
Custom processing logic.
|
| 120 |
+
|
| 121 |
+
:param data: The data to process.
|
| 122 |
+
:return: Modified data.
|
| 123 |
+
"""
|
| 124 |
+
return f"Custom processing of {data}"
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
# Uncommenting the following class definition will raise a TypeError
|
| 128 |
+
# because 'version' attribute is missing.
|
| 129 |
+
# class InvalidPlugin(PluginBase):
|
| 130 |
+
# name = "InvalidPlugin"
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
if __name__ == "__main__":
|
| 134 |
+
# Instantiate and use the plugin
|
| 135 |
+
plugin = CustomPlugin()
|
| 136 |
+
print(plugin.run("example data"))
|
| 137 |
+
---
|
| 138 |
+
<!DOCTYPE html>
|
| 139 |
+
<html lang="en">
|
| 140 |
+
<head>
|
| 141 |
+
<meta charset="UTF-8">
|
| 142 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 143 |
+
<title>Click the Box Game</title>
|
| 144 |
+
<style>
|
| 145 |
+
body {
|
| 146 |
+
text-align: center;
|
| 147 |
+
font-family: Arial, sans-serif;
|
| 148 |
+
}
|
| 149 |
+
#game-container {
|
| 150 |
+
position: relative;
|
| 151 |
+
width: 300px;
|
| 152 |
+
height: 300px;
|
| 153 |
+
margin: 20px auto;
|
| 154 |
+
border: 2px solid black;
|
| 155 |
+
overflow: hidden;
|
| 156 |
+
}
|
| 157 |
+
#target {
|
| 158 |
+
width: 50px;
|
| 159 |
+
height: 50px;
|
| 160 |
+
background-color: red;
|
| 161 |
+
position: absolute;
|
| 162 |
+
cursor: pointer;
|
| 163 |
+
}
|
| 164 |
+
</style>
|
| 165 |
+
</head>
|
| 166 |
+
<body>
|
| 167 |
+
<h1>Click the Box!</h1>
|
| 168 |
+
<p>Score: <span id="score">0</span></p>
|
| 169 |
+
<div id="game-container">
|
| 170 |
+
<div id="target"></div>
|
| 171 |
+
</div>
|
| 172 |
+
<script>
|
| 173 |
+
let score = 0;
|
| 174 |
+
const target = document.getElementById("target");
|
| 175 |
+
const scoreDisplay = document.getElementById("score");
|
| 176 |
+
const container = document.getElementById("game-container");
|
| 177 |
+
|
| 178 |
+
function moveTarget() {
|
| 179 |
+
const maxX = container.clientWidth - target.clientWidth;
|
| 180 |
+
const maxY = container.clientHeight - target.clientHeight;
|
| 181 |
+
target.style.left = Math.random() * maxX + "px";
|
| 182 |
+
target.style.top = Math.random() * maxY + "px";
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
target.addEventListener("click", function() {
|
| 186 |
+
score++;
|
| 187 |
+
scoreDisplay.textContent = score;
|
| 188 |
+
moveTarget();
|
| 189 |
+
});
|
| 190 |
+
|
| 191 |
+
moveTarget();
|
| 192 |
+
</script>
|
| 193 |
+
</body>
|
| 194 |
+
</html>
|
scripts/setups/vitest-setup-client.ts
ADDED
|
File without changes
|
scripts/setups/vitest-setup-server.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { vi, afterAll } from "vitest";
|
| 2 |
+
import dotenv from "dotenv";
|
| 3 |
+
import { resolve } from "path";
|
| 4 |
+
import fs from "fs";
|
| 5 |
+
import { MongoMemoryServer } from "mongodb-memory-server";
|
| 6 |
+
|
| 7 |
+
let mongoServer: MongoMemoryServer;
|
| 8 |
+
// Load the .env file
|
| 9 |
+
const envPath = resolve(__dirname, "../../.env");
|
| 10 |
+
dotenv.config({ path: envPath });
|
| 11 |
+
|
| 12 |
+
// Read the .env file content
|
| 13 |
+
const envContent = fs.readFileSync(envPath, "utf-8");
|
| 14 |
+
|
| 15 |
+
// Parse the .env content
|
| 16 |
+
const envVars = dotenv.parse(envContent);
|
| 17 |
+
|
| 18 |
+
// Separate public and private variables
|
| 19 |
+
const publicEnv = {};
|
| 20 |
+
const privateEnv = {};
|
| 21 |
+
|
| 22 |
+
for (const [key, value] of Object.entries(envVars)) {
|
| 23 |
+
if (key.startsWith("PUBLIC_")) {
|
| 24 |
+
publicEnv[key] = value;
|
| 25 |
+
} else {
|
| 26 |
+
privateEnv[key] = value;
|
| 27 |
+
}
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
vi.mock("$env/dynamic/public", () => ({
|
| 31 |
+
env: publicEnv,
|
| 32 |
+
}));
|
| 33 |
+
|
| 34 |
+
vi.mock("$env/dynamic/private", async () => {
|
| 35 |
+
mongoServer = await MongoMemoryServer.create();
|
| 36 |
+
|
| 37 |
+
return {
|
| 38 |
+
env: {
|
| 39 |
+
...privateEnv,
|
| 40 |
+
MONGODB_URL: mongoServer.getUri(),
|
| 41 |
+
},
|
| 42 |
+
};
|
| 43 |
+
});
|
| 44 |
+
|
| 45 |
+
afterAll(async () => {
|
| 46 |
+
if (mongoServer) {
|
| 47 |
+
await mongoServer.stop();
|
| 48 |
+
}
|
| 49 |
+
});
|
scripts/updateLocalEnv.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import fs from "fs";
|
| 2 |
+
import yaml from "js-yaml";
|
| 3 |
+
|
| 4 |
+
const file = fs.readFileSync("chart/env/prod.yaml", "utf8");
|
| 5 |
+
|
| 6 |
+
// have to do a weird stringify/parse because of some node error
|
| 7 |
+
const prod = JSON.parse(JSON.stringify(yaml.load(file)));
|
| 8 |
+
const vars = prod.envVars as Record<string, string>;
|
| 9 |
+
|
| 10 |
+
let PUBLIC_CONFIG = "";
|
| 11 |
+
|
| 12 |
+
Object.entries(vars)
|
| 13 |
+
// filter keys used in prod with the proxy
|
| 14 |
+
.filter(
|
| 15 |
+
([key]) =>
|
| 16 |
+
![
|
| 17 |
+
"XFF_DEPTH",
|
| 18 |
+
"ADDRESS_HEADER",
|
| 19 |
+
"APP_BASE",
|
| 20 |
+
"PUBLIC_ORIGIN",
|
| 21 |
+
"PUBLIC_SHARE_PREFIX",
|
| 22 |
+
"ADMIN_CLI_LOGIN",
|
| 23 |
+
].includes(key)
|
| 24 |
+
)
|
| 25 |
+
.forEach(([key, value]) => {
|
| 26 |
+
PUBLIC_CONFIG += `${key}=\`${value}\`\n`;
|
| 27 |
+
});
|
| 28 |
+
|
| 29 |
+
const SECRET_CONFIG =
|
| 30 |
+
(fs.existsSync(".env.SECRET_CONFIG")
|
| 31 |
+
? fs.readFileSync(".env.SECRET_CONFIG", "utf8")
|
| 32 |
+
: process.env.SECRET_CONFIG) ?? "";
|
| 33 |
+
|
| 34 |
+
// Prepend the content of the env variable SECRET_CONFIG
|
| 35 |
+
let full_config = `${PUBLIC_CONFIG}\n${SECRET_CONFIG}`;
|
| 36 |
+
|
| 37 |
+
// replace the internal proxy url with the public endpoint
|
| 38 |
+
full_config = full_config.replaceAll(
|
| 39 |
+
"https://internal.api-inference.huggingface.co",
|
| 40 |
+
"https://router.huggingface.co/hf-inference"
|
| 41 |
+
);
|
| 42 |
+
|
| 43 |
+
full_config = full_config.replaceAll("COOKIE_SECURE=`true`", "COOKIE_SECURE=`false`");
|
| 44 |
+
full_config = full_config.replaceAll("LOG_LEVEL=`debug`", "LOG_LEVEL=`info`");
|
| 45 |
+
full_config = full_config.replaceAll("NODE_ENV=`prod`", "NODE_ENV=`development`");
|
| 46 |
+
|
| 47 |
+
// Write full_config to .env.local
|
| 48 |
+
fs.writeFileSync(".env.local", full_config);
|
static/chatui/apple-touch-icon.png
ADDED
|
|
Git LFS Details
|
static/chatui/favicon.ico
ADDED
|
|
static/chatui/favicon.svg
ADDED
|
|
static/chatui/icon-128x128.png
ADDED
|
|
Git LFS Details
|
static/chatui/icon-256x256.png
ADDED
|
|
Git LFS Details
|
static/chatui/icon-512x512.png
ADDED
|
|
Git LFS Details
|
static/chatui/icon.svg
ADDED
|
|
static/chatui/logo.svg
ADDED
|
|
static/chatui/manifest.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"background_color": "#ffffff",
|
| 3 |
+
"name": "Chat UI",
|
| 4 |
+
"short_name": "Chat UI",
|
| 5 |
+
"display": "standalone",
|
| 6 |
+
"start_url": "/",
|
| 7 |
+
"icons": [
|
| 8 |
+
{
|
| 9 |
+
"src": "/chatui/icon-128x128.png",
|
| 10 |
+
"sizes": "128x128",
|
| 11 |
+
"type": "image/png"
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"src": "/chatui/icon-256x256.png",
|
| 15 |
+
"sizes": "256x256",
|
| 16 |
+
"type": "image/png"
|
| 17 |
+
},
|
| 18 |
+
{
|
| 19 |
+
"src": "/chatui/icon-512x512.png",
|
| 20 |
+
"sizes": "512x512",
|
| 21 |
+
"type": "image/png"
|
| 22 |
+
}
|
| 23 |
+
]
|
| 24 |
+
}
|
static/huggingchat/apple-touch-icon.png
ADDED
|
|
Git LFS Details
|
static/huggingchat/assistants-thumbnail.png
ADDED
|
|
Git LFS Details
|
static/huggingchat/favicon.ico
ADDED
|
|
static/huggingchat/favicon.svg
ADDED
|
|
static/huggingchat/icon-128x128.png
ADDED
|
|
Git LFS Details
|
static/huggingchat/icon-144x144.png
ADDED
|
|
Git LFS Details
|
static/huggingchat/icon-192x192.png
ADDED
|
|
Git LFS Details
|
static/huggingchat/icon-256x256.png
ADDED
|
|
Git LFS Details
|
static/huggingchat/icon-36x36.png
ADDED
|
|
Git LFS Details
|
static/huggingchat/icon-48x48.png
ADDED
|
|
Git LFS Details
|
static/huggingchat/icon-512x512.png
ADDED
|
|
Git LFS Details
|
static/huggingchat/icon-72x72.png
ADDED
|
|
Git LFS Details
|