This view is limited to 50 files because it contains too many changes.  See the raw diff here.
Files changed (50) hide show
  1. .dockerignore +1 -1
  2. .env +0 -4
  3. .env.template +54 -99
  4. .github/release.yml +0 -16
  5. .github/workflows/build-image.yml +3 -3
  6. .gitignore +1 -2
  7. Dockerfile +8 -64
  8. Dockerfile.local +28 -0
  9. README.md +21 -50
  10. entrypoint.sh +15 -5
  11. package-lock.json +21 -916
  12. package.json +2 -7
  13. scripts/populate.ts +4 -9
  14. src/app.d.ts +0 -5
  15. src/hooks.server.ts +27 -63
  16. src/lib/assistantStats/refresh-assistants-counts.ts +37 -43
  17. src/lib/components/AnnouncementBanner.svelte +1 -1
  18. src/lib/components/CopyToClipBoardBtn.svelte +1 -1
  19. src/lib/components/DisclaimerModal.svelte +10 -6
  20. src/lib/components/LoginModal.svelte +5 -5
  21. src/lib/components/ModelCardMetadata.svelte +2 -8
  22. src/lib/components/NavMenu.svelte +4 -7
  23. src/lib/components/chat/AssistantIntroduction.svelte +2 -3
  24. src/lib/components/chat/ChatIntroduction.svelte +8 -6
  25. src/lib/components/chat/ChatMessage.svelte +1 -2
  26. src/lib/components/chat/ChatWindow.svelte +1 -1
  27. src/lib/components/icons/Logo.svelte +4 -4
  28. src/lib/migrations/migrations.ts +30 -38
  29. src/lib/migrations/routines/01-update-search-assistants.ts +5 -5
  30. src/lib/migrations/routines/02-update-assistants-models.ts +3 -3
  31. src/lib/migrations/routines/index.ts +3 -4
  32. src/lib/server/abortedGenerations.ts +14 -27
  33. src/lib/server/auth.ts +24 -15
  34. src/lib/server/database.ts +141 -189
  35. src/lib/server/embeddingEndpoints/embeddingEndpoints.ts +0 -3
  36. src/lib/server/embeddingEndpoints/hfApi/embeddingHfApi.ts +0 -53
  37. src/lib/server/embeddingEndpoints/openai/embeddingEndpoints.ts +2 -2
  38. src/lib/server/embeddingEndpoints/tei/embeddingEndpoints.ts +3 -13
  39. src/lib/server/embeddingEndpoints/transformersjs/embeddingEndpoints.ts +2 -3
  40. src/lib/server/embeddingModels.ts +2 -6
  41. src/lib/server/endpoints/anthropic/endpointAnthropic.ts +2 -2
  42. src/lib/server/endpoints/cloudflare/endpointCloudflare.ts +5 -6
  43. src/lib/server/endpoints/cohere/endpointCohere.ts +2 -2
  44. src/lib/server/endpoints/google/endpointVertex.ts +43 -108
  45. src/lib/server/endpoints/langserve/endpointLangserve.ts +2 -3
  46. src/lib/server/endpoints/llamacpp/endpointLlamacpp.ts +4 -5
  47. src/lib/server/endpoints/openai/endpointOai.ts +2 -2
  48. src/lib/server/endpoints/tgi/endpointTgi.ts +2 -2
  49. src/lib/server/files/downloadFile.ts +1 -1
  50. src/lib/server/files/uploadFile.ts +1 -1
.dockerignore CHANGED
@@ -8,4 +8,4 @@ node_modules/
8
  .svelte-kit/
9
  .env*
10
  !.env
11
- .env.local
 
8
  .svelte-kit/
9
  .env*
10
  !.env
11
+ !.env.local
.env CHANGED
@@ -145,7 +145,6 @@ EXPOSE_API=true
145
 
146
  ENABLE_ASSISTANTS=false #set to true to enable assistants feature
147
  ENABLE_ASSISTANTS_RAG=false # /!\ This will let users specify arbitrary URLs that the server will then request. Make sure you have the proper firewall rules in place.
148
- REQUIRE_FEATURED_ASSISTANTS=false
149
  ENABLE_LOCAL_FETCH=false #set to true to disable the blocklist for local fetches. Only enable this if you have the proper firewall rules to prevent SSRF attacks and understand the implications.
150
  ALTERNATIVE_REDIRECT_URLS=`[]` #valide alternative redirect URL for OAuth
151
  WEBHOOK_URL_REPORT_ASSISTANT=#provide webhook url to get notified when an assistant gets reported
@@ -153,6 +152,3 @@ WEBHOOK_URL_REPORT_ASSISTANT=#provide webhook url to get notified when an assist
153
  ALLOWED_USER_EMAILS=`[]` # if it's defined, only these emails will be allowed to use the app
154
 
155
  USAGE_LIMITS=`{}`
156
- ALLOW_INSECURE_COOKIES=false # recommended to keep this to false but set to true if you need to run over http without tls
157
- METRICS_PORT=
158
- LOG_LEVEL=info
 
145
 
146
  ENABLE_ASSISTANTS=false #set to true to enable assistants feature
147
  ENABLE_ASSISTANTS_RAG=false # /!\ This will let users specify arbitrary URLs that the server will then request. Make sure you have the proper firewall rules in place.
 
148
  ENABLE_LOCAL_FETCH=false #set to true to disable the blocklist for local fetches. Only enable this if you have the proper firewall rules to prevent SSRF attacks and understand the implications.
149
  ALTERNATIVE_REDIRECT_URLS=`[]` #valide alternative redirect URL for OAuth
150
  WEBHOOK_URL_REPORT_ASSISTANT=#provide webhook url to get notified when an assistant gets reported
 
152
  ALLOWED_USER_EMAILS=`[]` # if it's defined, only these emails will be allowed to use the app
153
 
154
  USAGE_LIMITS=`{}`
 
 
 
.env.template CHANGED
@@ -10,8 +10,8 @@ MODELS=`[
10
  "logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/cohere-logo.png",
11
  "parameters": {
12
  "stop": ["<|END_OF_TURN_TOKEN|>"],
13
- "truncate" : 28672,
14
- "max_new_tokens" : 4096,
15
  "temperature" : 0.3
16
  },
17
  "promptExamples" : [
@@ -27,31 +27,6 @@ MODELS=`[
27
  }
28
  ]
29
  },
30
- {
31
- "name" : "meta-llama/Meta-Llama-3-70B-Instruct",
32
- "description": "Generation over generation, Meta Llama 3 demonstrates state-of-the-art performance on a wide range of industry benchmarks and offers new capabilities, including improved reasoning.",
33
- "logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/meta-logo.png",
34
- "modelUrl": "https://huggingface.co/meta-llama/Meta-Llama-3-70B-Instruct",
35
- "websiteUrl": "https://llama.meta.com/llama3/",
36
- "tokenizer" : "philschmid/meta-llama-3-tokenizer",
37
- "promptExamples" : [
38
- {
39
- "title": "Write an email from bullet list",
40
- "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)"
41
- }, {
42
- "title": "Code a snake game",
43
- "prompt": "Code a basic snake game in python, give explanations for each step."
44
- }, {
45
- "title": "Assist in a task",
46
- "prompt": "How do I make a delicious lemon cheesecake?"
47
- }
48
- ],
49
- "parameters": {
50
- "stop": ["<|eot_id|>"],
51
- "truncate": 6144,
52
- "max_new_tokens": 2047
53
- }
54
- },
55
  {
56
  "name" : "HuggingFaceH4/zephyr-orpo-141b-A35b-v0.1",
57
  "tokenizer": "HuggingFaceH4/zephyr-orpo-141b-A35b-v0.1",
@@ -76,7 +51,7 @@ MODELS=`[
76
  "prompt": "How do I make a delicious lemon cheesecake?"
77
  }
78
  ]
79
- },
80
  {
81
  "name" : "mistralai/Mixtral-8x7B-Instruct-v0.1",
82
  "description" : "The latest MoE model from Mistral AI! 8x7B and outperforms Llama 2 70B in most benchmarks.",
@@ -108,6 +83,33 @@ MODELS=`[
108
  }
109
  ]
110
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  {
112
  "name" : "NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO",
113
  "description" : "Nous Hermes 2 Mixtral 8x7B DPO is the new flagship Nous Research model trained over the Mixtral 8x7B MoE LLM.",
@@ -138,46 +140,18 @@ MODELS=`[
138
  "stop": ["<|im_end|>"]
139
  }
140
  },
141
- {
142
- "name" : "google/gemma-1.1-7b-it",
143
- "description": "Gemma 7B 1.1 is the latest release in the Gemma family of lightweight models built by Google, trained using a novel RLHF method.",
144
- "websiteUrl" : "https://blog.google/technology/developers/gemma-open-models/",
145
- "logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/google-logo.png",
146
- "modelUrl": "https://huggingface.co/google/gemma-1.1-7b-it",
147
- "preprompt": "",
148
- "chatPromptTemplate" : "{{#each messages}}{{#ifUser}}<start_of_turn>user\n{{#if @first}}{{#if @root.preprompt}}{{@root.preprompt}}\n{{/if}}{{/if}}{{content}}<end_of_turn>\n<start_of_turn>model\n{{/ifUser}}{{#ifAssistant}}{{content}}<end_of_turn>\n{{/ifAssistant}}{{/each}}",
149
- "promptExamples": [
150
- {
151
- "title": "Write an email from bullet list",
152
- "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)"
153
- }, {
154
- "title": "Code a snake game",
155
- "prompt": "Code a basic snake game in python, give explanations for each step."
156
- }, {
157
- "title": "Assist in a task",
158
- "prompt": "How do I make a delicious lemon cheesecake?"
159
- }
160
- ],
161
- "parameters": {
162
- "do_sample": true,
163
- "truncate": 7168,
164
- "max_new_tokens": 1024,
165
- "stop" : ["<end_of_turn>"]
166
- }
167
- },
168
-
169
- {
170
- "name": "mistralai/Mistral-7B-Instruct-v0.2",
171
- "displayName": "mistralai/Mistral-7B-Instruct-v0.2",
172
  "description": "Mistral 7B is a new Apache 2.0 model, released by Mistral AI that outperforms Llama2 13B in benchmarks.",
173
  "logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/mistral-logo.png",
174
  "websiteUrl": "https://mistral.ai/news/announcing-mistral-7b/",
175
- "modelUrl": "https://huggingface.co/mistralai/Mistral-7B-Instruct-v0.2",
176
- "tokenizer": "mistralai/Mistral-7B-Instruct-v0.2",
177
  "preprompt": "",
178
  "chatPromptTemplate" : "<s>{{#each messages}}{{#ifUser}}[INST] {{#if @first}}{{#if @root.preprompt}}{{@root.preprompt}}\n{{/if}}{{/if}}{{content}} [/INST]{{/ifUser}}{{#ifAssistant}}{{content}}</s>{{/ifAssistant}}{{/each}}",
179
  "parameters": {
180
- "temperature": 0.3,
181
  "top_p": 0.95,
182
  "repetition_penalty": 1.2,
183
  "top_k": 50,
@@ -196,21 +170,27 @@ MODELS=`[
196
  "title": "Assist in a task",
197
  "prompt": "How do I make a delicious lemon cheesecake?"
198
  }
199
- ]
 
200
  },
201
- {
202
- "name": "microsoft/Phi-3-mini-4k-instruct",
203
- "tokenizer": "microsoft/Phi-3-mini-4k-instruct",
204
- "description" : "Phi-3 Mini-4K-Instruct is a 3.8B parameters, lightweight, state-of-the-art open model built upon datasets used for Phi-2.",
205
- "logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/microsoft-logo.png",
206
- "modelUrl": "https://huggingface.co/microsoft/Phi-3-mini-4k-instruct",
207
- "websiteUrl": "https://azure.microsoft.com/en-us/blog/introducing-phi-3-redefining-whats-possible-with-slms/",
 
208
  "preprompt": "",
209
- "chatPromptTemplate": "<s>{{preprompt}}{{#each messages}}{{#ifUser}}<|user|>\n{{content}}<|end|>\n<|assistant|>\n{{/ifUser}}{{#ifAssistant}}{{content}}<|end|>\n{{/ifAssistant}}{{/each}}",
210
  "parameters": {
211
- "stop": ["<|end|>", "<|endoftext|>", "<|assistant|>"],
 
 
 
 
212
  "max_new_tokens": 1024,
213
- "truncate": 3071
214
  },
215
  "promptExamples": [
216
  {
@@ -224,16 +204,6 @@ MODELS=`[
224
  "prompt": "How do I make a delicious lemon cheesecake?"
225
  }
226
  ]
227
- },
228
- {
229
- "name": "meta-llama/Meta-Llama-3-8B-Instruct",
230
- "tokenizer" : "philschmid/meta-llama-3-tokenizer",
231
- "parameters": {
232
- "temperature": 0.1,
233
- "stop": ["<|eot_id|>"],
234
- "truncate": 1024,
235
- },
236
- "unlisted": true
237
  }
238
  ]`
239
 
@@ -251,21 +221,7 @@ OLD_MODELS=`[
251
  {"name": "openchat/openchat-3.5-0106"}
252
  ]`
253
 
254
- TASK_MODEL='meta-llama/Meta-Llama-3-8B-Instruct'
255
-
256
- TEXT_EMBEDDING_MODELS = `[
257
- {
258
- "name": "bge-base-en-v1-5-sxa",
259
- "displayName": "bge-base-en-v1-5-sxa",
260
- "chunkCharLength": 512,
261
- "endpoints": [
262
- { "type": "tei",
263
- "url" : "https://huggingchat-tei.hf.space/"
264
- }
265
- ]
266
- }
267
- ]`
268
-
269
 
270
  APP_BASE="/chat"
271
  PUBLIC_ORIGIN=https://huggingface.co
@@ -288,7 +244,6 @@ PUBLIC_APPLE_APP_ID=6476778843
288
 
289
  ENABLE_ASSISTANTS=true
290
  ENABLE_ASSISTANTS_RAG=true
291
- REQUIRE_FEATURED_ASSISTANTS=true
292
  EXPOSE_API=true
293
 
294
  ALTERNATIVE_REDIRECT_URLS=`[
 
10
  "logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/cohere-logo.png",
11
  "parameters": {
12
  "stop": ["<|END_OF_TURN_TOKEN|>"],
13
+ "truncate" : 24576,
14
+ "max_new_tokens" : 8192,
15
  "temperature" : 0.3
16
  },
17
  "promptExamples" : [
 
27
  }
28
  ]
29
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  {
31
  "name" : "HuggingFaceH4/zephyr-orpo-141b-A35b-v0.1",
32
  "tokenizer": "HuggingFaceH4/zephyr-orpo-141b-A35b-v0.1",
 
51
  "prompt": "How do I make a delicious lemon cheesecake?"
52
  }
53
  ]
54
+ },
55
  {
56
  "name" : "mistralai/Mixtral-8x7B-Instruct-v0.1",
57
  "description" : "The latest MoE model from Mistral AI! 8x7B and outperforms Llama 2 70B in most benchmarks.",
 
83
  }
84
  ]
85
  },
86
+ {
87
+ "name" : "google/gemma-1.1-7b-it",
88
+ "description": "Gemma 7B 1.1 is the latest release in the Gemma family of lightweight models built by Google, trained using a novel RLHF method.",
89
+ "websiteUrl" : "https://blog.google/technology/developers/gemma-open-models/",
90
+ "logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/google-logo.png",
91
+ "modelUrl": "https://huggingface.co/google/gemma-1.1-7b-it",
92
+ "preprompt": "",
93
+ "chatPromptTemplate" : "{{#each messages}}{{#ifUser}}<start_of_turn>user\n{{#if @first}}{{#if @root.preprompt}}{{@root.preprompt}}\n{{/if}}{{/if}}{{content}}<end_of_turn>\n<start_of_turn>model\n{{/ifUser}}{{#ifAssistant}}{{content}}<end_of_turn>\n{{/ifAssistant}}{{/each}}",
94
+ "promptExamples": [
95
+ {
96
+ "title": "Write an email from bullet list",
97
+ "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)"
98
+ }, {
99
+ "title": "Code a snake game",
100
+ "prompt": "Code a basic snake game in python, give explanations for each step."
101
+ }, {
102
+ "title": "Assist in a task",
103
+ "prompt": "How do I make a delicious lemon cheesecake?"
104
+ }
105
+ ],
106
+ "parameters": {
107
+ "do_sample": true,
108
+ "truncate": 7168,
109
+ "max_new_tokens": 1024,
110
+ "stop" : ["<end_of_turn>"]
111
+ }
112
+ },
113
  {
114
  "name" : "NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO",
115
  "description" : "Nous Hermes 2 Mixtral 8x7B DPO is the new flagship Nous Research model trained over the Mixtral 8x7B MoE LLM.",
 
140
  "stop": ["<|im_end|>"]
141
  }
142
  },
143
+ {
144
+ "name": "mistralai/Mistral-7B-Instruct-v0.1",
145
+ "displayName": "mistralai/Mistral-7B-Instruct-v0.1",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  "description": "Mistral 7B is a new Apache 2.0 model, released by Mistral AI that outperforms Llama2 13B in benchmarks.",
147
  "logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/mistral-logo.png",
148
  "websiteUrl": "https://mistral.ai/news/announcing-mistral-7b/",
149
+ "modelUrl": "https://huggingface.co/mistralai/Mistral-7B-Instruct-v0.1",
150
+ "tokenizer": "mistralai/Mistral-7B-Instruct-v0.1",
151
  "preprompt": "",
152
  "chatPromptTemplate" : "<s>{{#each messages}}{{#ifUser}}[INST] {{#if @first}}{{#if @root.preprompt}}{{@root.preprompt}}\n{{/if}}{{/if}}{{content}} [/INST]{{/ifUser}}{{#ifAssistant}}{{content}}</s>{{/ifAssistant}}{{/each}}",
153
  "parameters": {
154
+ "temperature": 0.1,
155
  "top_p": 0.95,
156
  "repetition_penalty": 1.2,
157
  "top_k": 50,
 
170
  "title": "Assist in a task",
171
  "prompt": "How do I make a delicious lemon cheesecake?"
172
  }
173
+ ],
174
+ "unlisted": true
175
  },
176
+ {
177
+ "name": "mistralai/Mistral-7B-Instruct-v0.2",
178
+ "displayName": "mistralai/Mistral-7B-Instruct-v0.2",
179
+ "description": "Mistral 7B is a new Apache 2.0 model, released by Mistral AI that outperforms Llama2 13B in benchmarks.",
180
+ "logoUrl": "https://huggingface.co/datasets/huggingchat/models-logo/resolve/main/mistral-logo.png",
181
+ "websiteUrl": "https://mistral.ai/news/announcing-mistral-7b/",
182
+ "modelUrl": "https://huggingface.co/mistralai/Mistral-7B-Instruct-v0.2",
183
+ "tokenizer": "mistralai/Mistral-7B-Instruct-v0.2",
184
  "preprompt": "",
185
+ "chatPromptTemplate" : "<s>{{#each messages}}{{#ifUser}}[INST] {{#if @first}}{{#if @root.preprompt}}{{@root.preprompt}}\n{{/if}}{{/if}}{{content}} [/INST]{{/ifUser}}{{#ifAssistant}}{{content}}</s>{{/ifAssistant}}{{/each}}",
186
  "parameters": {
187
+ "temperature": 0.3,
188
+ "top_p": 0.95,
189
+ "repetition_penalty": 1.2,
190
+ "top_k": 50,
191
+ "truncate": 3072,
192
  "max_new_tokens": 1024,
193
+ "stop": ["</s>"]
194
  },
195
  "promptExamples": [
196
  {
 
204
  "prompt": "How do I make a delicious lemon cheesecake?"
205
  }
206
  ]
 
 
 
 
 
 
 
 
 
 
207
  }
208
  ]`
209
 
 
221
  {"name": "openchat/openchat-3.5-0106"}
222
  ]`
223
 
224
+ TASK_MODEL='mistralai/Mistral-7B-Instruct-v0.1'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
 
226
  APP_BASE="/chat"
227
  PUBLIC_ORIGIN=https://huggingface.co
 
244
 
245
  ENABLE_ASSISTANTS=true
246
  ENABLE_ASSISTANTS_RAG=true
 
247
  EXPOSE_API=true
248
 
249
  ALTERNATIVE_REDIRECT_URLS=`[
.github/release.yml DELETED
@@ -1,16 +0,0 @@
1
- changelog:
2
- exclude:
3
- labels:
4
- - huggingchat
5
- - CI/CD
6
- - documentation
7
- categories:
8
- - title: Features
9
- labels:
10
- - enhancement
11
- - title: Bugfixes
12
- labels:
13
- - bug
14
- - title: Other changes
15
- labels:
16
- - "*"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.github/workflows/build-image.yml CHANGED
@@ -8,7 +8,7 @@ on:
8
  branches:
9
  - "*"
10
  paths:
11
- - "Dockerfile"
12
  - "entrypoint.sh"
13
  workflow_dispatch:
14
  release:
@@ -62,7 +62,7 @@ jobs:
62
  uses: docker/build-push-action@v5
63
  with:
64
  context: .
65
- file: Dockerfile
66
  push: ${{ github.event_name != 'pull_request' }}
67
  tags: ${{ steps.meta.outputs.tags }}
68
  labels: ${{ steps.meta.outputs.labels }}
@@ -116,7 +116,7 @@ jobs:
116
  uses: docker/build-push-action@v5
117
  with:
118
  context: .
119
- file: Dockerfile
120
  push: ${{ github.event_name != 'pull_request' }}
121
  tags: ${{ steps.meta.outputs.tags }}
122
  labels: ${{ steps.meta.outputs.labels }}
 
8
  branches:
9
  - "*"
10
  paths:
11
+ - "Dockerfile.local"
12
  - "entrypoint.sh"
13
  workflow_dispatch:
14
  release:
 
62
  uses: docker/build-push-action@v5
63
  with:
64
  context: .
65
+ file: Dockerfile.local
66
  push: ${{ github.event_name != 'pull_request' }}
67
  tags: ${{ steps.meta.outputs.tags }}
68
  labels: ${{ steps.meta.outputs.labels }}
 
116
  uses: docker/build-push-action@v5
117
  with:
118
  context: .
119
+ file: Dockerfile.local
120
  push: ${{ github.event_name != 'pull_request' }}
121
  tags: ${{ steps.meta.outputs.tags }}
122
  labels: ${{ steps.meta.outputs.labels }}
.gitignore CHANGED
@@ -11,5 +11,4 @@ SECRET_CONFIG
11
  .idea
12
  !.env.ci
13
  !.env
14
- !.env.template
15
- gcp-*.json
 
11
  .idea
12
  !.env.ci
13
  !.env
14
+ !.env.template
 
Dockerfile CHANGED
@@ -1,9 +1,6 @@
1
  # syntax=docker/dockerfile:1
2
  # read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
3
  # you will also find guides on how best to write your Dockerfile
4
- ARG INCLUDE_DB=false
5
-
6
- # stage that install the dependencies
7
  FROM node:20 as builder-production
8
 
9
  WORKDIR /app
@@ -15,74 +12,21 @@ RUN --mount=type=cache,target=/app/.npm \
15
 
16
  FROM builder-production as builder
17
 
18
- ARG APP_BASE=
19
- ARG PUBLIC_APP_COLOR=blue
20
-
21
  RUN --mount=type=cache,target=/app/.npm \
22
  npm set cache /app/.npm && \
23
  npm ci
24
 
25
  COPY --link --chown=1000 . .
26
 
27
- RUN npm run build
28
-
29
- # mongo image
30
- FROM mongo:latest as mongo
31
-
32
- # image to be used if INCLUDE_DB is false
33
- FROM node:20-slim as local_db_false
34
-
35
- # image to be used if INCLUDE_DB is true
36
- FROM node:20-slim as local_db_true
37
-
38
- RUN apt-get update
39
- RUN apt-get install gnupg curl -y
40
- # copy mongo from the other stage
41
- COPY --from=mongo /usr/bin/mongo* /usr/bin/
42
-
43
- ENV MONGODB_URL=mongodb://localhost:27017
44
- RUN mkdir -p /data/db
45
- RUN chown -R 1000:1000 /data/db
46
-
47
- # final image
48
- FROM local_db_${INCLUDE_DB} as final
49
-
50
- # build arg to determine if the database should be included
51
- ARG INCLUDE_DB=false
52
- ENV INCLUDE_DB=${INCLUDE_DB}
53
-
54
- # svelte requires APP_BASE at build time so it must be passed as a build arg
55
- ARG APP_BASE=
56
- # tailwind requires the primary theme to be known at build time so it must be passed as a build arg
57
- ARG PUBLIC_APP_COLOR=blue
58
-
59
-
60
- # install dotenv-cli
61
- RUN npm install -g dotenv-cli
62
-
63
- # switch to a user that works for spaces
64
- RUN userdel -r node
65
- RUN useradd -m -u 1000 user
66
- USER user
67
-
68
- ENV HOME=/home/user \
69
- PATH=/home/user/.local/bin:$PATH
70
-
71
- WORKDIR /app
72
-
73
- # add a .env.local if the user doesn't bind a volume to it
74
- RUN touch /app/.env.local
75
 
76
- # get the default config, the entrypoint script and the server script
77
- COPY --chown=1000 package.json /app/package.json
78
- COPY --chown=1000 .env /app/.env
79
- COPY --chown=1000 entrypoint.sh /app/entrypoint.sh
80
- COPY --chown=1000 gcp-*.json /app/
81
 
82
- #import the build & dependencies
83
- COPY --from=builder --chown=1000 /app/build /app/build
84
- COPY --from=builder --chown=1000 /app/node_modules /app/node_modules
85
 
86
- RUN chmod +x /app/entrypoint.sh
 
 
87
 
88
- CMD ["/bin/bash", "-c", "/app/entrypoint.sh"]
 
1
  # syntax=docker/dockerfile:1
2
  # read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
3
  # you will also find guides on how best to write your Dockerfile
 
 
 
4
  FROM node:20 as builder-production
5
 
6
  WORKDIR /app
 
12
 
13
  FROM builder-production as builder
14
 
 
 
 
15
  RUN --mount=type=cache,target=/app/.npm \
16
  npm set cache /app/.npm && \
17
  npm ci
18
 
19
  COPY --link --chown=1000 . .
20
 
21
+ RUN --mount=type=secret,id=DOTENV_LOCAL,dst=.env.local \
22
+ npm run build
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
+ FROM node:20-slim
 
 
 
 
25
 
26
+ RUN npm install -g pm2
 
 
27
 
28
+ COPY --from=builder-production /app/node_modules /app/node_modules
29
+ COPY --link --chown=1000 package.json /app/package.json
30
+ COPY --from=builder /app/build /app/build
31
 
32
+ CMD pm2 start /app/build/index.js -i $CPU_CORES --no-daemon
Dockerfile.local ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ARG INCLUDE_DB=false
2
+ FROM mongo:latest as mongo
3
+
4
+ FROM node:20-slim as local_db_false
5
+
6
+ FROM node:20-slim as local_db_true
7
+
8
+ RUN apt-get update
9
+ RUN apt-get install gnupg curl -y
10
+
11
+ COPY --from=mongo /usr/bin/mongo* /usr/bin/
12
+
13
+ FROM local_db_${INCLUDE_DB} as final
14
+ ARG INCLUDE_DB=false
15
+ ENV INCLUDE_DB=${INCLUDE_DB}
16
+
17
+ WORKDIR /app
18
+
19
+ COPY --link --chown=1000 package-lock.json package.json ./
20
+ RUN --mount=type=cache,target=/app/.npm \
21
+ npm set cache /app/.npm && \
22
+ npm ci
23
+
24
+ # copy the rest of the files, run regardless of
25
+ COPY --chown=1000 --link . .
26
+ RUN chmod +x /app/entrypoint.sh
27
+
28
+ CMD ["/bin/bash", "-c", "/app/entrypoint.sh"]
README.md CHANGED
@@ -9,7 +9,6 @@ license: apache-2.0
9
  base_path: /chat
10
  app_port: 3000
11
  failure_strategy: rollback
12
- load_balancing_strategy: random
13
  ---
14
 
15
  # Chat UI
@@ -24,9 +23,8 @@ A chat interface using open source models, eg OpenAssistant or Llama. It is a Sv
24
  3. [Web Search](#web-search)
25
  4. [Text Embedding Models](#text-embedding-models)
26
  5. [Extra parameters](#extra-parameters)
27
- 6. [Common issues](#common-issues)
28
- 7. [Deploying to a HF Space](#deploying-to-a-hf-space)
29
- 8. [Building](#building)
30
 
31
  ## No Setup Deploy
32
 
@@ -590,11 +588,11 @@ Chat UI can connect to the google Vertex API endpoints ([List of supported model
590
 
591
  To enable:
592
 
593
- 1. [Select](https://console.cloud.google.com/project) or [create](https://cloud.google.com/resource-manager/docs/creating-managing-projects#creating_a_project) a Google Cloud project.
594
- 1. [Enable billing for your project](https://cloud.google.com/billing/docs/how-to/modify-project).
595
- 1. [Enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com).
596
- 1. [Set up authentication with a service account](https://cloud.google.com/docs/authentication/getting-started)
597
- so you can access the API from your local workstation.
598
 
599
  The service account credentials file can be imported as an environmental variable:
600
 
@@ -602,24 +600,18 @@ The service account credentials file can be imported as an environmental variabl
602
  GOOGLE_APPLICATION_CREDENTIALS = clientid.json
603
  ```
604
 
605
- Make sure your docker container has access to the file and the variable is correctly set.
606
- Afterwards Google Vertex endpoints can be configured as following:
607
 
608
  ```
609
  MODELS=`[
610
  //...
611
  {
612
- "name": "gemini-1.5-pro",
613
- "displayName": "Vertex Gemini Pro 1.5",
 
 
614
  "endpoints" : [{
615
- "type": "vertex",
616
- "project": "abc-xyz",
617
- "location": "europe-west3",
618
- "model": "gemini-1.5-pro-preview-0409", // model-name
619
-
620
- // Optional
621
- "safetyThreshold": "BLOCK_MEDIUM_AND_ABOVE",
622
- "apiEndpoint": "", // alternative api endpoint url
623
  }]
624
  },
625
  ]`
@@ -736,14 +728,6 @@ MODELS=`[
736
  ]`
737
  ```
738
 
739
- ## Common issues
740
-
741
- ### 403:You don't have access to this conversation
742
-
743
- Most likely you are running chat-ui over HTTP. The recommended option is to setup something like NGINX to handle HTTPS and proxy the requests to chat-ui. If you really need to run over HTTP you can add `ALLOW_INSECURE_COOKIES=true` to your `.env.local`.
744
-
745
- Make sure to set your `PUBLIC_ORIGIN` in your `.env.local` to the correct URL as well.
746
-
747
  ## Deploying to a HF Space
748
 
749
  Create a `DOTENV_LOCAL` secret to your HF space with the content of your .env.local, and they will be picked up automatically when you run.
@@ -765,7 +749,7 @@ You can preview the production build with `npm run preview`.
765
  The config file for HuggingChat is stored in the `.env.template` file at the root of the repository. It is the single source of truth that is used to generate the actual `.env.local` file using our CI/CD pipeline. See [updateProdEnv](https://github.com/huggingface/chat-ui/blob/cdb33a9583f5339ade724db615347393ef48f5cd/scripts/updateProdEnv.ts) for more details.
766
 
767
  > [!TIP]
768
- > If you want to make changes to the model config used in production for HuggingChat, you should do so against `.env.template`.
769
 
770
  We currently use the following secrets for deploying HuggingChat in addition to the `.env.template` above:
771
 
@@ -774,34 +758,21 @@ We currently use the following secrets for deploying HuggingChat in addition to
774
  - `OPENID_CONFIG`
775
  - `SERPER_API_KEY`
776
 
777
- ### Running a copy of HuggingChat locally
778
-
779
- If you want to run an exact copy of HuggingChat locally, you will need to do the following first:
780
 
781
- 1. Create an [OAuth App on the hub](https://huggingface.co/settings/applications/new) with `openid profile email` permissions. Make sure to set the callback URL to something like `http://localhost:5173/chat/login/callback` which matches the right path for your local instance.
782
- 2. Create a [HF Token](https://huggingface.co/settings/tokens) with your Hugging Face account. You will need a Pro account to be able to access some of the larger models available through HuggingChat.
783
- 3. Create a free account with [serper.dev](https://serper.dev/) (you will get 2500 free search queries)
784
- 4. Run an instance of mongoDB, however you want. (Local or remote)
785
 
786
- You can then create a new `.env.SECRET_CONFIG` file with the following content
787
 
788
- ```env
789
- MONGODB_URL=<link to your mongo DB from step 4>
790
- HF_TOKEN=<your HF token from step 2>
791
- OPENID_CONFIG=`{
792
- PROVIDER_URL: "https://huggingface.co",
793
- CLIENT_ID: "<your client ID from step 1>",
794
- CLIENT_SECRET: "<your client secret from step 1>",
795
- }`
796
- SERPER_API_KEY=<your serper API key from step 3>
797
- MESSAGES_BEFORE_LOGIN=<can be any numerical value, or set to 0 to require login>
798
  ```
799
 
800
- You can then run `npm run updateLocalEnv` in the root of chat-ui. This will create a `.env.local` file which combines the `.env.template` and the `.env.SECRET_CONFIG` file. You can then run `npm run dev` to start your local instance of HuggingChat.
801
 
802
  ### Populate database
803
 
804
- > [!WARNING]
805
  > The `MONGODB_URL` used for this script will be fetched from `.env.local`. Make sure it's correct! The command runs directly on the database.
806
 
807
  You can populate the database using faker data using the `populate` script:
 
9
  base_path: /chat
10
  app_port: 3000
11
  failure_strategy: rollback
 
12
  ---
13
 
14
  # Chat UI
 
23
  3. [Web Search](#web-search)
24
  4. [Text Embedding Models](#text-embedding-models)
25
  5. [Extra parameters](#extra-parameters)
26
+ 6. [Deploying to a HF Space](#deploying-to-a-hf-space)
27
+ 7. [Building](#building)
 
28
 
29
  ## No Setup Deploy
30
 
 
588
 
589
  To enable:
590
 
591
+ 1. [Select](https://console.cloud.google.com/project) or [create](https://cloud.google.com/resource-manager/docs/creating-managing-projects#creating_a_project) a Google Cloud project.
592
+ 1. [Enable billing for your project](https://cloud.google.com/billing/docs/how-to/modify-project).
593
+ 1. [Enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com).
594
+ 1. [Set up authentication with a service account](https://cloud.google.com/docs/authentication/getting-started)
595
+ so you can access the API from your local workstation.
596
 
597
  The service account credentials file can be imported as an environmental variable:
598
 
 
600
  GOOGLE_APPLICATION_CREDENTIALS = clientid.json
601
  ```
602
 
603
+ Make sure docker has access to the file. Afterwards Google Vertex endpoints can be configured as following:
 
604
 
605
  ```
606
  MODELS=`[
607
  //...
608
  {
609
+ "name": "gemini-1.0-pro", //model-name
610
+ "displayName": "Vertex Gemini Pro 1.0",
611
+ "location": "europe-west3",
612
+ "apiEndpoint": "", //alternative api endpoint url
613
  "endpoints" : [{
614
+ "type": "vertex"
 
 
 
 
 
 
 
615
  }]
616
  },
617
  ]`
 
728
  ]`
729
  ```
730
 
 
 
 
 
 
 
 
 
731
  ## Deploying to a HF Space
732
 
733
  Create a `DOTENV_LOCAL` secret to your HF space with the content of your .env.local, and they will be picked up automatically when you run.
 
749
  The config file for HuggingChat is stored in the `.env.template` file at the root of the repository. It is the single source of truth that is used to generate the actual `.env.local` file using our CI/CD pipeline. See [updateProdEnv](https://github.com/huggingface/chat-ui/blob/cdb33a9583f5339ade724db615347393ef48f5cd/scripts/updateProdEnv.ts) for more details.
750
 
751
  > [!TIP]
752
+ > If you want to make changes to model config for HuggingChat, you should do so against `.env.template`.
753
 
754
  We currently use the following secrets for deploying HuggingChat in addition to the `.env.template` above:
755
 
 
758
  - `OPENID_CONFIG`
759
  - `SERPER_API_KEY`
760
 
761
+ They are defined as secrets in the repository.
 
 
762
 
763
+ ### Testing config changes locally
 
 
 
764
 
765
+ You can test the config changes locally by first creating an `.env.SECRET_CONFIG` file with the secrets defined above. Then you can run the following command to generate the `.env.local` file:
766
 
767
+ ```bash
768
+ npm run updateLocalEnv
 
 
 
 
 
 
 
 
769
  ```
770
 
771
+ This will replace your `.env.local` file with the one that will be used in prod (simply taking `.env.template + .env.SECRET_CONFIG`).
772
 
773
  ### Populate database
774
 
775
+ > [!WARNING]
776
  > The `MONGODB_URL` used for this script will be fetched from `.env.local`. Make sure it's correct! The command runs directly on the database.
777
 
778
  You can populate the database using faker data using the `populate` script:
entrypoint.sh CHANGED
@@ -2,7 +2,7 @@ ENV_LOCAL_PATH=/app/.env.local
2
 
3
  if test -z "${DOTENV_LOCAL}" ; then
4
  if ! test -f "${ENV_LOCAL_PATH}" ; then
5
- echo "DOTENV_LOCAL was not found in the ENV variables and .env.local is not set using a bind volume. Make sure to set environment variables properly. "
6
  fi;
7
  else
8
  echo "DOTENV_LOCAL was found in the ENV variables. Creating .env.local file."
@@ -10,10 +10,20 @@ else
10
  fi;
11
 
12
  if [ "$INCLUDE_DB" = "true" ] ; then
 
 
 
 
 
 
 
 
 
 
 
13
  echo "Starting local MongoDB instance"
14
- nohup mongod &
15
- fi;
16
 
17
- export PUBLIC_VERSION=$(node -p "require('./package.json').version")
18
 
19
- dotenv -e /app/.env -c -- node /app/build/index.js -- --host 0.0.0.0 --port 3000
 
 
2
 
3
  if test -z "${DOTENV_LOCAL}" ; then
4
  if ! test -f "${ENV_LOCAL_PATH}" ; then
5
+ echo "DOTENV_LOCAL was not found in the ENV variables and .env.local is not set using a bind volume. We are using the default .env config."
6
  fi;
7
  else
8
  echo "DOTENV_LOCAL was found in the ENV variables. Creating .env.local file."
 
10
  fi;
11
 
12
  if [ "$INCLUDE_DB" = "true" ] ; then
13
+ echo "INCLUDE_DB is set to true."
14
+
15
+ MONGODB_CONFIG="MONGODB_URL=mongodb://localhost:27017"
16
+ if ! grep -q "^${MONGODB_CONFIG}$" ${ENV_LOCAL_PATH}; then
17
+ echo "Appending MONGODB_URL"
18
+ touch /app/.env.local
19
+ echo -e "\n${MONGODB_CONFIG}" >> ${ENV_LOCAL_PATH}
20
+ fi
21
+
22
+ mkdir -p /data/db
23
+ mongod &
24
  echo "Starting local MongoDB instance"
 
 
25
 
26
+ fi;
27
 
28
+ npm run build
29
+ npm run preview -- --host 0.0.0.0 --port 3000
package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
  {
2
  "name": "chat-ui",
3
- "version": "0.8.3",
4
  "lockfileVersion": 3,
5
  "requires": true,
6
  "packages": {
7
  "": {
8
  "name": "chat-ui",
9
- "version": "0.8.3",
10
  "dependencies": {
11
  "@huggingface/hub": "^0.5.1",
12
  "@huggingface/inference": "^2.6.3",
@@ -17,7 +17,6 @@
17
  "browser-image-resizer": "^2.4.1",
18
  "date-fns": "^2.29.3",
19
  "dotenv": "^16.0.3",
20
- "express": "^4.19.2",
21
  "handlebars": "^4.7.8",
22
  "highlight.js": "^11.7.0",
23
  "image-size": "^1.0.2",
@@ -30,8 +29,6 @@
30
  "nanoid": "^4.0.2",
31
  "openid-client": "^5.4.2",
32
  "parquetjs": "^0.11.2",
33
- "pino": "^9.0.0",
34
- "pino-pretty": "^11.0.0",
35
  "postcss": "^8.4.31",
36
  "saslprep": "^1.0.3",
37
  "satori": "^0.10.11",
@@ -50,7 +47,6 @@
50
  "@sveltejs/adapter-node": "^1.3.1",
51
  "@sveltejs/kit": "^1.30.4",
52
  "@tailwindcss/typography": "^0.5.9",
53
- "@types/express": "^4.17.21",
54
  "@types/jsdom": "^21.1.1",
55
  "@types/minimist": "^1.2.5",
56
  "@types/parquetjs": "^0.10.3",
@@ -64,7 +60,6 @@
64
  "prettier": "^2.8.0",
65
  "prettier-plugin-svelte": "^2.10.1",
66
  "prettier-plugin-tailwindcss": "^0.2.7",
67
- "prom-client": "^15.1.2",
68
  "svelte": "^4.2.8",
69
  "svelte-check": "^3.6.2",
70
  "ts-node": "^10.9.1",
@@ -77,7 +72,7 @@
77
  },
78
  "optionalDependencies": {
79
  "@anthropic-ai/sdk": "^0.17.1",
80
- "@google-cloud/vertexai": "^1.1.0",
81
  "aws4fetch": "^1.0.17",
82
  "cohere-ai": "^7.9.0",
83
  "openai": "^4.14.2"
@@ -635,9 +630,9 @@
635
  }
636
  },
637
  "node_modules/@google-cloud/vertexai": {
638
- "version": "1.1.0",
639
- "resolved": "https://registry.npmjs.org/@google-cloud/vertexai/-/vertexai-1.1.0.tgz",
640
- "integrity": "sha512-hfwfdlVpJ+kM6o2b5UFfPnweBcz8tgHAFRswnqUKYqLJsvKU0DDD0Z2/YKoHyAUoPJAv20qg6KlC3msNeUKUiw==",
641
  "optional": true,
642
  "dependencies": {
643
  "google-auth-library": "^9.1.0"
@@ -1266,15 +1261,6 @@
1266
  "node": ">= 8"
1267
  }
1268
  },
1269
- "node_modules/@opentelemetry/api": {
1270
- "version": "1.8.0",
1271
- "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz",
1272
- "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==",
1273
- "dev": true,
1274
- "engines": {
1275
- "node": ">=8.0.0"
1276
- }
1277
- },
1278
  "node_modules/@polka/url": {
1279
  "version": "1.0.0-next.21",
1280
  "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz",
@@ -1999,16 +1985,6 @@
1999
  "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
2000
  "devOptional": true
2001
  },
2002
- "node_modules/@types/body-parser": {
2003
- "version": "1.19.5",
2004
- "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
2005
- "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==",
2006
- "dev": true,
2007
- "dependencies": {
2008
- "@types/connect": "*",
2009
- "@types/node": "*"
2010
- }
2011
- },
2012
  "node_modules/@types/chai": {
2013
  "version": "4.3.5",
2014
  "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz",
@@ -2024,15 +2000,6 @@
2024
  "@types/chai": "*"
2025
  }
2026
  },
2027
- "node_modules/@types/connect": {
2028
- "version": "3.4.38",
2029
- "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
2030
- "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
2031
- "dev": true,
2032
- "dependencies": {
2033
- "@types/node": "*"
2034
- }
2035
- },
2036
  "node_modules/@types/cookie": {
2037
  "version": "0.5.1",
2038
  "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.5.1.tgz",
@@ -2045,36 +2012,6 @@
2045
  "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
2046
  "dev": true
2047
  },
2048
- "node_modules/@types/express": {
2049
- "version": "4.17.21",
2050
- "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
2051
- "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
2052
- "dev": true,
2053
- "dependencies": {
2054
- "@types/body-parser": "*",
2055
- "@types/express-serve-static-core": "^4.17.33",
2056
- "@types/qs": "*",
2057
- "@types/serve-static": "*"
2058
- }
2059
- },
2060
- "node_modules/@types/express-serve-static-core": {
2061
- "version": "4.19.0",
2062
- "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz",
2063
- "integrity": "sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==",
2064
- "dev": true,
2065
- "dependencies": {
2066
- "@types/node": "*",
2067
- "@types/qs": "*",
2068
- "@types/range-parser": "*",
2069
- "@types/send": "*"
2070
- }
2071
- },
2072
- "node_modules/@types/http-errors": {
2073
- "version": "2.0.4",
2074
- "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
2075
- "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
2076
- "dev": true
2077
- },
2078
  "node_modules/@types/jsdom": {
2079
  "version": "21.1.1",
2080
  "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.1.tgz",
@@ -2102,12 +2039,6 @@
2102
  "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
2103
  "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA=="
2104
  },
2105
- "node_modules/@types/mime": {
2106
- "version": "1.3.5",
2107
- "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
2108
- "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
2109
- "dev": true
2110
- },
2111
  "node_modules/@types/minimist": {
2112
  "version": "1.2.5",
2113
  "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz",
@@ -2153,18 +2084,6 @@
2153
  "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==",
2154
  "dev": true
2155
  },
2156
- "node_modules/@types/qs": {
2157
- "version": "6.9.15",
2158
- "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz",
2159
- "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==",
2160
- "dev": true
2161
- },
2162
- "node_modules/@types/range-parser": {
2163
- "version": "1.2.7",
2164
- "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
2165
- "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
2166
- "dev": true
2167
- },
2168
  "node_modules/@types/resolve": {
2169
  "version": "1.20.2",
2170
  "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
@@ -2177,27 +2096,6 @@
2177
  "integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==",
2178
  "dev": true
2179
  },
2180
- "node_modules/@types/send": {
2181
- "version": "0.17.4",
2182
- "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
2183
- "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
2184
- "dev": true,
2185
- "dependencies": {
2186
- "@types/mime": "^1",
2187
- "@types/node": "*"
2188
- }
2189
- },
2190
- "node_modules/@types/serve-static": {
2191
- "version": "1.15.7",
2192
- "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz",
2193
- "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==",
2194
- "dev": true,
2195
- "dependencies": {
2196
- "@types/http-errors": "*",
2197
- "@types/node": "*",
2198
- "@types/send": "*"
2199
- }
2200
- },
2201
  "node_modules/@types/tough-cookie": {
2202
  "version": "4.0.2",
2203
  "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz",
@@ -2553,6 +2451,7 @@
2553
  "version": "3.0.0",
2554
  "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
2555
  "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
 
2556
  "dependencies": {
2557
  "event-target-shim": "^5.0.0"
2558
  },
@@ -2560,18 +2459,6 @@
2560
  "node": ">=6.5"
2561
  }
2562
  },
2563
- "node_modules/accepts": {
2564
- "version": "1.3.8",
2565
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
2566
- "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
2567
- "dependencies": {
2568
- "mime-types": "~2.1.34",
2569
- "negotiator": "0.6.3"
2570
- },
2571
- "engines": {
2572
- "node": ">= 0.6"
2573
- }
2574
- },
2575
  "node_modules/acorn": {
2576
  "version": "8.11.3",
2577
  "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
@@ -2702,11 +2589,6 @@
2702
  "dequal": "^2.0.3"
2703
  }
2704
  },
2705
- "node_modules/array-flatten": {
2706
- "version": "1.1.1",
2707
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
2708
- "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
2709
- },
2710
  "node_modules/array-union": {
2711
  "version": "2.1.0",
2712
  "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
@@ -2730,14 +2612,6 @@
2730
  "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
2731
  "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
2732
  },
2733
- "node_modules/atomic-sleep": {
2734
- "version": "1.0.0",
2735
- "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz",
2736
- "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==",
2737
- "engines": {
2738
- "node": ">=8.0.0"
2739
- }
2740
- },
2741
  "node_modules/autoprefixer": {
2742
  "version": "10.4.14",
2743
  "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz",
@@ -2843,12 +2717,6 @@
2843
  "integrity": "sha512-u4cBQNepWxYA55FunZSM7wMi55yQaN0otnhhilNoWHq0MfOfJeQx0v0mRRpolGOExPjZcl6FtB0BB8Xkb88F0g==",
2844
  "optional": true
2845
  },
2846
- "node_modules/bintrees": {
2847
- "version": "1.0.2",
2848
- "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz",
2849
- "integrity": "sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==",
2850
- "dev": true
2851
- },
2852
  "node_modules/bl": {
2853
  "version": "4.1.0",
2854
  "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
@@ -2865,67 +2733,6 @@
2865
  "integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==",
2866
  "dev": true
2867
  },
2868
- "node_modules/body-parser": {
2869
- "version": "1.20.2",
2870
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
2871
- "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
2872
- "dependencies": {
2873
- "bytes": "3.1.2",
2874
- "content-type": "~1.0.5",
2875
- "debug": "2.6.9",
2876
- "depd": "2.0.0",
2877
- "destroy": "1.2.0",
2878
- "http-errors": "2.0.0",
2879
- "iconv-lite": "0.4.24",
2880
- "on-finished": "2.4.1",
2881
- "qs": "6.11.0",
2882
- "raw-body": "2.5.2",
2883
- "type-is": "~1.6.18",
2884
- "unpipe": "1.0.0"
2885
- },
2886
- "engines": {
2887
- "node": ">= 0.8",
2888
- "npm": "1.2.8000 || >= 1.4.16"
2889
- }
2890
- },
2891
- "node_modules/body-parser/node_modules/debug": {
2892
- "version": "2.6.9",
2893
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
2894
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
2895
- "dependencies": {
2896
- "ms": "2.0.0"
2897
- }
2898
- },
2899
- "node_modules/body-parser/node_modules/iconv-lite": {
2900
- "version": "0.4.24",
2901
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
2902
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
2903
- "dependencies": {
2904
- "safer-buffer": ">= 2.1.2 < 3"
2905
- },
2906
- "engines": {
2907
- "node": ">=0.10.0"
2908
- }
2909
- },
2910
- "node_modules/body-parser/node_modules/ms": {
2911
- "version": "2.0.0",
2912
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
2913
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
2914
- },
2915
- "node_modules/body-parser/node_modules/qs": {
2916
- "version": "6.11.0",
2917
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
2918
- "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
2919
- "dependencies": {
2920
- "side-channel": "^1.0.4"
2921
- },
2922
- "engines": {
2923
- "node": ">=0.6"
2924
- },
2925
- "funding": {
2926
- "url": "https://github.com/sponsors/ljharb"
2927
- }
2928
- },
2929
  "node_modules/brace-expansion": {
2930
  "version": "1.1.11",
2931
  "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -3058,14 +2865,6 @@
3058
  "url": "https://github.com/sponsors/sindresorhus"
3059
  }
3060
  },
3061
- "node_modules/bytes": {
3062
- "version": "3.1.2",
3063
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
3064
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
3065
- "engines": {
3066
- "node": ">= 0.8"
3067
- }
3068
- },
3069
  "node_modules/cac": {
3070
  "version": "6.7.14",
3071
  "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
@@ -3079,6 +2878,7 @@
3079
  "version": "1.0.7",
3080
  "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
3081
  "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
 
3082
  "dependencies": {
3083
  "es-define-property": "^1.0.0",
3084
  "es-errors": "^1.3.0",
@@ -3303,11 +3103,6 @@
3303
  "simple-swizzle": "^0.2.2"
3304
  }
3305
  },
3306
- "node_modules/colorette": {
3307
- "version": "2.0.20",
3308
- "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
3309
- "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w=="
3310
- },
3311
  "node_modules/combined-stream": {
3312
  "version": "1.0.8",
3313
  "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -3357,25 +3152,6 @@
3357
  "node": ">=10.18.0 <11 || >=12.14.0 <13 || >=14"
3358
  }
3359
  },
3360
- "node_modules/content-disposition": {
3361
- "version": "0.5.4",
3362
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
3363
- "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
3364
- "dependencies": {
3365
- "safe-buffer": "5.2.1"
3366
- },
3367
- "engines": {
3368
- "node": ">= 0.6"
3369
- }
3370
- },
3371
- "node_modules/content-type": {
3372
- "version": "1.0.5",
3373
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
3374
- "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
3375
- "engines": {
3376
- "node": ">= 0.6"
3377
- }
3378
- },
3379
  "node_modules/cookie": {
3380
  "version": "0.5.0",
3381
  "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
@@ -3385,11 +3161,6 @@
3385
  "node": ">= 0.6"
3386
  }
3387
  },
3388
- "node_modules/cookie-signature": {
3389
- "version": "1.0.6",
3390
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
3391
- "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
3392
- },
3393
  "node_modules/create-require": {
3394
  "version": "1.1.1",
3395
  "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
@@ -3542,14 +3313,6 @@
3542
  "node": ">=6"
3543
  }
3544
  },
3545
- "node_modules/dateformat": {
3546
- "version": "4.6.3",
3547
- "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz",
3548
- "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==",
3549
- "engines": {
3550
- "node": "*"
3551
- }
3552
- },
3553
  "node_modules/debug": {
3554
  "version": "4.3.4",
3555
  "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -3624,6 +3387,7 @@
3624
  "version": "1.1.4",
3625
  "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
3626
  "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
 
3627
  "dependencies": {
3628
  "es-define-property": "^1.0.0",
3629
  "es-errors": "^1.3.0",
@@ -3644,14 +3408,6 @@
3644
  "node": ">=0.4.0"
3645
  }
3646
  },
3647
- "node_modules/depd": {
3648
- "version": "2.0.0",
3649
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
3650
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
3651
- "engines": {
3652
- "node": ">= 0.8"
3653
- }
3654
- },
3655
  "node_modules/dequal": {
3656
  "version": "2.0.3",
3657
  "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
@@ -3661,15 +3417,6 @@
3661
  "node": ">=6"
3662
  }
3663
  },
3664
- "node_modules/destroy": {
3665
- "version": "1.2.0",
3666
- "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
3667
- "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
3668
- "engines": {
3669
- "node": ">= 0.8",
3670
- "npm": "1.2.8000 || >= 1.4.16"
3671
- }
3672
- },
3673
  "node_modules/detect-indent": {
3674
  "version": "6.1.0",
3675
  "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz",
@@ -3774,11 +3521,6 @@
3774
  "safe-buffer": "^5.0.1"
3775
  }
3776
  },
3777
- "node_modules/ee-first": {
3778
- "version": "1.1.1",
3779
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
3780
- "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
3781
- },
3782
  "node_modules/electron-to-chromium": {
3783
  "version": "1.4.359",
3784
  "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.359.tgz",
@@ -3789,14 +3531,6 @@
3789
  "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz",
3790
  "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw=="
3791
  },
3792
- "node_modules/encodeurl": {
3793
- "version": "1.0.2",
3794
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
3795
- "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
3796
- "engines": {
3797
- "node": ">= 0.8"
3798
- }
3799
- },
3800
  "node_modules/end-of-stream": {
3801
  "version": "1.4.4",
3802
  "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@@ -3820,6 +3554,7 @@
3820
  "version": "1.0.0",
3821
  "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
3822
  "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
 
3823
  "dependencies": {
3824
  "get-intrinsic": "^1.2.4"
3825
  },
@@ -3831,6 +3566,7 @@
3831
  "version": "1.3.0",
3832
  "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
3833
  "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
 
3834
  "engines": {
3835
  "node": ">= 0.4"
3836
  }
@@ -4120,30 +3856,15 @@
4120
  "node": ">=0.10.0"
4121
  }
4122
  },
4123
- "node_modules/etag": {
4124
- "version": "1.8.1",
4125
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
4126
- "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
4127
- "engines": {
4128
- "node": ">= 0.6"
4129
- }
4130
- },
4131
  "node_modules/event-target-shim": {
4132
  "version": "5.0.1",
4133
  "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
4134
  "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
 
4135
  "engines": {
4136
  "node": ">=6"
4137
  }
4138
  },
4139
- "node_modules/events": {
4140
- "version": "3.3.0",
4141
- "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
4142
- "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
4143
- "engines": {
4144
- "node": ">=0.8.x"
4145
- }
4146
- },
4147
  "node_modules/execa": {
4148
  "version": "5.1.1",
4149
  "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
@@ -4175,93 +3896,12 @@
4175
  "node": ">=6"
4176
  }
4177
  },
4178
- "node_modules/express": {
4179
- "version": "4.19.2",
4180
- "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
4181
- "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
4182
- "dependencies": {
4183
- "accepts": "~1.3.8",
4184
- "array-flatten": "1.1.1",
4185
- "body-parser": "1.20.2",
4186
- "content-disposition": "0.5.4",
4187
- "content-type": "~1.0.4",
4188
- "cookie": "0.6.0",
4189
- "cookie-signature": "1.0.6",
4190
- "debug": "2.6.9",
4191
- "depd": "2.0.0",
4192
- "encodeurl": "~1.0.2",
4193
- "escape-html": "~1.0.3",
4194
- "etag": "~1.8.1",
4195
- "finalhandler": "1.2.0",
4196
- "fresh": "0.5.2",
4197
- "http-errors": "2.0.0",
4198
- "merge-descriptors": "1.0.1",
4199
- "methods": "~1.1.2",
4200
- "on-finished": "2.4.1",
4201
- "parseurl": "~1.3.3",
4202
- "path-to-regexp": "0.1.7",
4203
- "proxy-addr": "~2.0.7",
4204
- "qs": "6.11.0",
4205
- "range-parser": "~1.2.1",
4206
- "safe-buffer": "5.2.1",
4207
- "send": "0.18.0",
4208
- "serve-static": "1.15.0",
4209
- "setprototypeof": "1.2.0",
4210
- "statuses": "2.0.1",
4211
- "type-is": "~1.6.18",
4212
- "utils-merge": "1.0.1",
4213
- "vary": "~1.1.2"
4214
- },
4215
- "engines": {
4216
- "node": ">= 0.10.0"
4217
- }
4218
- },
4219
- "node_modules/express/node_modules/cookie": {
4220
- "version": "0.6.0",
4221
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
4222
- "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
4223
- "engines": {
4224
- "node": ">= 0.6"
4225
- }
4226
- },
4227
- "node_modules/express/node_modules/debug": {
4228
- "version": "2.6.9",
4229
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
4230
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
4231
- "dependencies": {
4232
- "ms": "2.0.0"
4233
- }
4234
- },
4235
- "node_modules/express/node_modules/ms": {
4236
- "version": "2.0.0",
4237
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
4238
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
4239
- },
4240
- "node_modules/express/node_modules/qs": {
4241
- "version": "6.11.0",
4242
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
4243
- "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
4244
- "dependencies": {
4245
- "side-channel": "^1.0.4"
4246
- },
4247
- "engines": {
4248
- "node": ">=0.6"
4249
- },
4250
- "funding": {
4251
- "url": "https://github.com/sponsors/ljharb"
4252
- }
4253
- },
4254
  "node_modules/extend": {
4255
  "version": "3.0.2",
4256
  "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
4257
  "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
4258
  "optional": true
4259
  },
4260
- "node_modules/fast-copy": {
4261
- "version": "3.0.2",
4262
- "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.2.tgz",
4263
- "integrity": "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ=="
4264
- },
4265
  "node_modules/fast-deep-equal": {
4266
  "version": "3.1.3",
4267
  "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -4317,19 +3957,6 @@
4317
  "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
4318
  "dev": true
4319
  },
4320
- "node_modules/fast-redact": {
4321
- "version": "3.5.0",
4322
- "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz",
4323
- "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==",
4324
- "engines": {
4325
- "node": ">=6"
4326
- }
4327
- },
4328
- "node_modules/fast-safe-stringify": {
4329
- "version": "2.1.1",
4330
- "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
4331
- "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="
4332
- },
4333
  "node_modules/fastq": {
4334
  "version": "1.15.0",
4335
  "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
@@ -4366,36 +3993,6 @@
4366
  "node": ">=8"
4367
  }
4368
  },
4369
- "node_modules/finalhandler": {
4370
- "version": "1.2.0",
4371
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
4372
- "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
4373
- "dependencies": {
4374
- "debug": "2.6.9",
4375
- "encodeurl": "~1.0.2",
4376
- "escape-html": "~1.0.3",
4377
- "on-finished": "2.4.1",
4378
- "parseurl": "~1.3.3",
4379
- "statuses": "2.0.1",
4380
- "unpipe": "~1.0.0"
4381
- },
4382
- "engines": {
4383
- "node": ">= 0.8"
4384
- }
4385
- },
4386
- "node_modules/finalhandler/node_modules/debug": {
4387
- "version": "2.6.9",
4388
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
4389
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
4390
- "dependencies": {
4391
- "ms": "2.0.0"
4392
- }
4393
- },
4394
- "node_modules/finalhandler/node_modules/ms": {
4395
- "version": "2.0.0",
4396
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
4397
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
4398
- },
4399
  "node_modules/find-up": {
4400
  "version": "5.0.0",
4401
  "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@@ -4468,14 +4065,6 @@
4468
  "node": ">= 12.20"
4469
  }
4470
  },
4471
- "node_modules/forwarded": {
4472
- "version": "0.2.0",
4473
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
4474
- "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
4475
- "engines": {
4476
- "node": ">= 0.6"
4477
- }
4478
- },
4479
  "node_modules/fraction.js": {
4480
  "version": "4.2.0",
4481
  "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
@@ -4488,14 +4077,6 @@
4488
  "url": "https://www.patreon.com/infusion"
4489
  }
4490
  },
4491
- "node_modules/fresh": {
4492
- "version": "0.5.2",
4493
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
4494
- "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
4495
- "engines": {
4496
- "node": ">= 0.6"
4497
- }
4498
- },
4499
  "node_modules/fs-constants": {
4500
  "version": "1.0.0",
4501
  "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
@@ -4593,6 +4174,7 @@
4593
  "version": "1.2.4",
4594
  "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
4595
  "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
 
4596
  "dependencies": {
4597
  "es-errors": "^1.3.0",
4598
  "function-bind": "^1.1.2",
@@ -4723,6 +4305,7 @@
4723
  "version": "1.0.1",
4724
  "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
4725
  "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
 
4726
  "dependencies": {
4727
  "get-intrinsic": "^1.1.3"
4728
  },
@@ -4799,6 +4382,7 @@
4799
  "version": "1.0.2",
4800
  "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
4801
  "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
 
4802
  "dependencies": {
4803
  "es-define-property": "^1.0.0"
4804
  },
@@ -4810,6 +4394,7 @@
4810
  "version": "1.0.3",
4811
  "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
4812
  "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
 
4813
  "engines": {
4814
  "node": ">= 0.4"
4815
  },
@@ -4821,6 +4406,7 @@
4821
  "version": "1.0.3",
4822
  "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
4823
  "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
 
4824
  "engines": {
4825
  "node": ">= 0.4"
4826
  },
@@ -4844,11 +4430,6 @@
4844
  "node": ">= 0.4"
4845
  }
4846
  },
4847
- "node_modules/help-me": {
4848
- "version": "5.0.0",
4849
- "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz",
4850
- "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg=="
4851
- },
4852
  "node_modules/hex-rgb": {
4853
  "version": "4.3.0",
4854
  "resolved": "https://registry.npmjs.org/hex-rgb/-/hex-rgb-4.3.0.tgz",
@@ -4879,21 +4460,6 @@
4879
  "node": ">=12"
4880
  }
4881
  },
4882
- "node_modules/http-errors": {
4883
- "version": "2.0.0",
4884
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
4885
- "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
4886
- "dependencies": {
4887
- "depd": "2.0.0",
4888
- "inherits": "2.0.4",
4889
- "setprototypeof": "1.2.0",
4890
- "statuses": "2.0.1",
4891
- "toidentifier": "1.0.1"
4892
- },
4893
- "engines": {
4894
- "node": ">= 0.8"
4895
- }
4896
- },
4897
  "node_modules/http-proxy-agent": {
4898
  "version": "5.0.0",
4899
  "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
@@ -5051,14 +4617,6 @@
5051
  "node": ">= 12"
5052
  }
5053
  },
5054
- "node_modules/ipaddr.js": {
5055
- "version": "1.9.1",
5056
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
5057
- "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
5058
- "engines": {
5059
- "node": ">= 0.10"
5060
- }
5061
- },
5062
  "node_modules/is-arrayish": {
5063
  "version": "0.3.2",
5064
  "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
@@ -5197,14 +4755,6 @@
5197
  "url": "https://github.com/sponsors/panva"
5198
  }
5199
  },
5200
- "node_modules/joycon": {
5201
- "version": "3.1.1",
5202
- "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz",
5203
- "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==",
5204
- "engines": {
5205
- "node": ">=10"
5206
- }
5207
- },
5208
  "node_modules/js-base64": {
5209
  "version": "3.7.2",
5210
  "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz",
@@ -5621,24 +5171,11 @@
5621
  "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
5622
  "dev": true
5623
  },
5624
- "node_modules/media-typer": {
5625
- "version": "0.3.0",
5626
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
5627
- "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
5628
- "engines": {
5629
- "node": ">= 0.6"
5630
- }
5631
- },
5632
  "node_modules/memory-pager": {
5633
  "version": "1.5.0",
5634
  "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
5635
  "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg=="
5636
  },
5637
- "node_modules/merge-descriptors": {
5638
- "version": "1.0.1",
5639
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
5640
- "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
5641
- },
5642
  "node_modules/merge-stream": {
5643
  "version": "2.0.0",
5644
  "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -5653,14 +5190,6 @@
5653
  "node": ">= 8"
5654
  }
5655
  },
5656
- "node_modules/methods": {
5657
- "version": "1.1.2",
5658
- "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
5659
- "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
5660
- "engines": {
5661
- "node": ">= 0.6"
5662
- }
5663
- },
5664
  "node_modules/micromatch": {
5665
  "version": "4.0.5",
5666
  "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
@@ -5673,17 +5202,6 @@
5673
  "node": ">=8.6"
5674
  }
5675
  },
5676
- "node_modules/mime": {
5677
- "version": "1.6.0",
5678
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
5679
- "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
5680
- "bin": {
5681
- "mime": "cli.js"
5682
- },
5683
- "engines": {
5684
- "node": ">=4"
5685
- }
5686
- },
5687
  "node_modules/mime-db": {
5688
  "version": "1.52.0",
5689
  "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@@ -5890,14 +5408,6 @@
5890
  "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
5891
  "dev": true
5892
  },
5893
- "node_modules/negotiator": {
5894
- "version": "0.6.3",
5895
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
5896
- "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
5897
- "engines": {
5898
- "node": ">= 0.6"
5899
- }
5900
- },
5901
  "node_modules/neo-async": {
5902
  "version": "2.6.2",
5903
  "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
@@ -6055,6 +5565,7 @@
6055
  "version": "1.13.1",
6056
  "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
6057
  "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==",
 
6058
  "funding": {
6059
  "url": "https://github.com/sponsors/ljharb"
6060
  }
@@ -6075,25 +5586,6 @@
6075
  "node": "^10.13.0 || >=12.0.0"
6076
  }
6077
  },
6078
- "node_modules/on-exit-leak-free": {
6079
- "version": "2.1.2",
6080
- "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz",
6081
- "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==",
6082
- "engines": {
6083
- "node": ">=14.0.0"
6084
- }
6085
- },
6086
- "node_modules/on-finished": {
6087
- "version": "2.4.1",
6088
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
6089
- "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
6090
- "dependencies": {
6091
- "ee-first": "1.1.1"
6092
- },
6093
- "engines": {
6094
- "node": ">= 0.8"
6095
- }
6096
- },
6097
  "node_modules/once": {
6098
  "version": "1.4.0",
6099
  "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -6320,14 +5812,6 @@
6320
  "url": "https://github.com/inikulin/parse5?sponsor=1"
6321
  }
6322
  },
6323
- "node_modules/parseurl": {
6324
- "version": "1.3.3",
6325
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
6326
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
6327
- "engines": {
6328
- "node": ">= 0.8"
6329
- }
6330
- },
6331
  "node_modules/path-exists": {
6332
  "version": "4.0.0",
6333
  "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -6359,11 +5843,6 @@
6359
  "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
6360
  "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
6361
  },
6362
- "node_modules/path-to-regexp": {
6363
- "version": "0.1.7",
6364
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
6365
- "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
6366
- },
6367
  "node_modules/path-type": {
6368
  "version": "4.0.0",
6369
  "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
@@ -6441,141 +5920,6 @@
6441
  "node": ">=0.10.0"
6442
  }
6443
  },
6444
- "node_modules/pino": {
6445
- "version": "9.0.0",
6446
- "resolved": "https://registry.npmjs.org/pino/-/pino-9.0.0.tgz",
6447
- "integrity": "sha512-uI1ThkzTShNSwvsUM6b4ND8ANzWURk9zTELMztFkmnCQeR/4wkomJ+echHee5GMWGovoSfjwdeu80DsFIt7mbA==",
6448
- "dependencies": {
6449
- "atomic-sleep": "^1.0.0",
6450
- "fast-redact": "^3.1.1",
6451
- "on-exit-leak-free": "^2.1.0",
6452
- "pino-abstract-transport": "^1.2.0",
6453
- "pino-std-serializers": "^6.0.0",
6454
- "process-warning": "^3.0.0",
6455
- "quick-format-unescaped": "^4.0.3",
6456
- "real-require": "^0.2.0",
6457
- "safe-stable-stringify": "^2.3.1",
6458
- "sonic-boom": "^3.7.0",
6459
- "thread-stream": "^2.6.0"
6460
- },
6461
- "bin": {
6462
- "pino": "bin.js"
6463
- }
6464
- },
6465
- "node_modules/pino-abstract-transport": {
6466
- "version": "1.2.0",
6467
- "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz",
6468
- "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==",
6469
- "dependencies": {
6470
- "readable-stream": "^4.0.0",
6471
- "split2": "^4.0.0"
6472
- }
6473
- },
6474
- "node_modules/pino-abstract-transport/node_modules/buffer": {
6475
- "version": "6.0.3",
6476
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
6477
- "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
6478
- "funding": [
6479
- {
6480
- "type": "github",
6481
- "url": "https://github.com/sponsors/feross"
6482
- },
6483
- {
6484
- "type": "patreon",
6485
- "url": "https://www.patreon.com/feross"
6486
- },
6487
- {
6488
- "type": "consulting",
6489
- "url": "https://feross.org/support"
6490
- }
6491
- ],
6492
- "dependencies": {
6493
- "base64-js": "^1.3.1",
6494
- "ieee754": "^1.2.1"
6495
- }
6496
- },
6497
- "node_modules/pino-abstract-transport/node_modules/readable-stream": {
6498
- "version": "4.5.2",
6499
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz",
6500
- "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==",
6501
- "dependencies": {
6502
- "abort-controller": "^3.0.0",
6503
- "buffer": "^6.0.3",
6504
- "events": "^3.3.0",
6505
- "process": "^0.11.10",
6506
- "string_decoder": "^1.3.0"
6507
- },
6508
- "engines": {
6509
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
6510
- }
6511
- },
6512
- "node_modules/pino-pretty": {
6513
- "version": "11.0.0",
6514
- "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-11.0.0.tgz",
6515
- "integrity": "sha512-YFJZqw59mHIY72wBnBs7XhLGG6qpJMa4pEQTRgEPEbjIYbng2LXEZZF1DoyDg9CfejEy8uZCyzpcBXXG0oOCwQ==",
6516
- "dependencies": {
6517
- "colorette": "^2.0.7",
6518
- "dateformat": "^4.6.3",
6519
- "fast-copy": "^3.0.0",
6520
- "fast-safe-stringify": "^2.1.1",
6521
- "help-me": "^5.0.0",
6522
- "joycon": "^3.1.1",
6523
- "minimist": "^1.2.6",
6524
- "on-exit-leak-free": "^2.1.0",
6525
- "pino-abstract-transport": "^1.0.0",
6526
- "pump": "^3.0.0",
6527
- "readable-stream": "^4.0.0",
6528
- "secure-json-parse": "^2.4.0",
6529
- "sonic-boom": "^3.0.0",
6530
- "strip-json-comments": "^3.1.1"
6531
- },
6532
- "bin": {
6533
- "pino-pretty": "bin.js"
6534
- }
6535
- },
6536
- "node_modules/pino-pretty/node_modules/buffer": {
6537
- "version": "6.0.3",
6538
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
6539
- "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
6540
- "funding": [
6541
- {
6542
- "type": "github",
6543
- "url": "https://github.com/sponsors/feross"
6544
- },
6545
- {
6546
- "type": "patreon",
6547
- "url": "https://www.patreon.com/feross"
6548
- },
6549
- {
6550
- "type": "consulting",
6551
- "url": "https://feross.org/support"
6552
- }
6553
- ],
6554
- "dependencies": {
6555
- "base64-js": "^1.3.1",
6556
- "ieee754": "^1.2.1"
6557
- }
6558
- },
6559
- "node_modules/pino-pretty/node_modules/readable-stream": {
6560
- "version": "4.5.2",
6561
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz",
6562
- "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==",
6563
- "dependencies": {
6564
- "abort-controller": "^3.0.0",
6565
- "buffer": "^6.0.3",
6566
- "events": "^3.3.0",
6567
- "process": "^0.11.10",
6568
- "string_decoder": "^1.3.0"
6569
- },
6570
- "engines": {
6571
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
6572
- }
6573
- },
6574
- "node_modules/pino-std-serializers": {
6575
- "version": "6.2.2",
6576
- "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz",
6577
- "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA=="
6578
- },
6579
  "node_modules/pirates": {
6580
  "version": "4.0.5",
6581
  "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
@@ -6969,32 +6313,6 @@
6969
  "url": "https://github.com/chalk/ansi-styles?sponsor=1"
6970
  }
6971
  },
6972
- "node_modules/process": {
6973
- "version": "0.11.10",
6974
- "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
6975
- "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
6976
- "engines": {
6977
- "node": ">= 0.6.0"
6978
- }
6979
- },
6980
- "node_modules/process-warning": {
6981
- "version": "3.0.0",
6982
- "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz",
6983
- "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ=="
6984
- },
6985
- "node_modules/prom-client": {
6986
- "version": "15.1.2",
6987
- "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-15.1.2.tgz",
6988
- "integrity": "sha512-on3h1iXb04QFLLThrmVYg1SChBQ9N1c+nKAjebBjokBqipddH3uxmOUcEkTnzmJ8Jh/5TSUnUqS40i2QB2dJHQ==",
6989
- "dev": true,
6990
- "dependencies": {
6991
- "@opentelemetry/api": "^1.4.0",
6992
- "tdigest": "^0.1.1"
6993
- },
6994
- "engines": {
6995
- "node": "^16 || ^18 || >=20"
6996
- }
6997
- },
6998
  "node_modules/protobufjs": {
6999
  "version": "6.11.4",
7000
  "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz",
@@ -7020,18 +6338,6 @@
7020
  "pbts": "bin/pbts"
7021
  }
7022
  },
7023
- "node_modules/proxy-addr": {
7024
- "version": "2.0.7",
7025
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
7026
- "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
7027
- "dependencies": {
7028
- "forwarded": "0.2.0",
7029
- "ipaddr.js": "1.9.1"
7030
- },
7031
- "engines": {
7032
- "node": ">= 0.10"
7033
- }
7034
- },
7035
  "node_modules/psl": {
7036
  "version": "1.9.0",
7037
  "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
@@ -7115,44 +6421,6 @@
7115
  "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
7116
  "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag=="
7117
  },
7118
- "node_modules/quick-format-unescaped": {
7119
- "version": "4.0.4",
7120
- "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz",
7121
- "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="
7122
- },
7123
- "node_modules/range-parser": {
7124
- "version": "1.2.1",
7125
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
7126
- "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
7127
- "engines": {
7128
- "node": ">= 0.6"
7129
- }
7130
- },
7131
- "node_modules/raw-body": {
7132
- "version": "2.5.2",
7133
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
7134
- "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
7135
- "dependencies": {
7136
- "bytes": "3.1.2",
7137
- "http-errors": "2.0.0",
7138
- "iconv-lite": "0.4.24",
7139
- "unpipe": "1.0.0"
7140
- },
7141
- "engines": {
7142
- "node": ">= 0.8"
7143
- }
7144
- },
7145
- "node_modules/raw-body/node_modules/iconv-lite": {
7146
- "version": "0.4.24",
7147
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
7148
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
7149
- "dependencies": {
7150
- "safer-buffer": ">= 2.1.2 < 3"
7151
- },
7152
- "engines": {
7153
- "node": ">=0.10.0"
7154
- }
7155
- },
7156
  "node_modules/rc": {
7157
  "version": "1.2.8",
7158
  "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
@@ -7213,14 +6481,6 @@
7213
  "node": ">=8.10.0"
7214
  }
7215
  },
7216
- "node_modules/real-require": {
7217
- "version": "0.2.0",
7218
- "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz",
7219
- "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==",
7220
- "engines": {
7221
- "node": ">= 12.13.0"
7222
- }
7223
- },
7224
  "node_modules/requires-port": {
7225
  "version": "1.0.0",
7226
  "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
@@ -7349,14 +6609,6 @@
7349
  }
7350
  ]
7351
  },
7352
- "node_modules/safe-stable-stringify": {
7353
- "version": "2.4.3",
7354
- "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz",
7355
- "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==",
7356
- "engines": {
7357
- "node": ">=10"
7358
- }
7359
- },
7360
  "node_modules/safer-buffer": {
7361
  "version": "2.1.2",
7362
  "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
@@ -7436,11 +6688,6 @@
7436
  "node": ">=v12.22.7"
7437
  }
7438
  },
7439
- "node_modules/secure-json-parse": {
7440
- "version": "2.7.0",
7441
- "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz",
7442
- "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw=="
7443
- },
7444
  "node_modules/semver": {
7445
  "version": "7.5.4",
7446
  "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
@@ -7455,47 +6702,6 @@
7455
  "node": ">=10"
7456
  }
7457
  },
7458
- "node_modules/send": {
7459
- "version": "0.18.0",
7460
- "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
7461
- "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
7462
- "dependencies": {
7463
- "debug": "2.6.9",
7464
- "depd": "2.0.0",
7465
- "destroy": "1.2.0",
7466
- "encodeurl": "~1.0.2",
7467
- "escape-html": "~1.0.3",
7468
- "etag": "~1.8.1",
7469
- "fresh": "0.5.2",
7470
- "http-errors": "2.0.0",
7471
- "mime": "1.6.0",
7472
- "ms": "2.1.3",
7473
- "on-finished": "2.4.1",
7474
- "range-parser": "~1.2.1",
7475
- "statuses": "2.0.1"
7476
- },
7477
- "engines": {
7478
- "node": ">= 0.8.0"
7479
- }
7480
- },
7481
- "node_modules/send/node_modules/debug": {
7482
- "version": "2.6.9",
7483
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
7484
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
7485
- "dependencies": {
7486
- "ms": "2.0.0"
7487
- }
7488
- },
7489
- "node_modules/send/node_modules/debug/node_modules/ms": {
7490
- "version": "2.0.0",
7491
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
7492
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
7493
- },
7494
- "node_modules/send/node_modules/ms": {
7495
- "version": "2.1.3",
7496
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
7497
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
7498
- },
7499
  "node_modules/serpapi": {
7500
  "version": "1.1.1",
7501
  "resolved": "https://registry.npmjs.org/serpapi/-/serpapi-1.1.1.tgz",
@@ -7504,20 +6710,6 @@
7504
  "undici": "^5.12.0"
7505
  }
7506
  },
7507
- "node_modules/serve-static": {
7508
- "version": "1.15.0",
7509
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
7510
- "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
7511
- "dependencies": {
7512
- "encodeurl": "~1.0.2",
7513
- "escape-html": "~1.0.3",
7514
- "parseurl": "~1.3.3",
7515
- "send": "0.18.0"
7516
- },
7517
- "engines": {
7518
- "node": ">= 0.8.0"
7519
- }
7520
- },
7521
  "node_modules/set-cookie-parser": {
7522
  "version": "2.6.0",
7523
  "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz",
@@ -7528,6 +6720,7 @@
7528
  "version": "1.2.2",
7529
  "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
7530
  "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
 
7531
  "dependencies": {
7532
  "define-data-property": "^1.1.4",
7533
  "es-errors": "^1.3.0",
@@ -7540,11 +6733,6 @@
7540
  "node": ">= 0.4"
7541
  }
7542
  },
7543
- "node_modules/setprototypeof": {
7544
- "version": "1.2.0",
7545
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
7546
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
7547
- },
7548
  "node_modules/sharp": {
7549
  "version": "0.33.2",
7550
  "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.2.tgz",
@@ -7609,6 +6797,7 @@
7609
  "version": "1.0.6",
7610
  "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
7611
  "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
 
7612
  "dependencies": {
7613
  "call-bind": "^1.0.7",
7614
  "es-errors": "^1.3.0",
@@ -7735,14 +6924,6 @@
7735
  "npm": ">= 3.0.0"
7736
  }
7737
  },
7738
- "node_modules/sonic-boom": {
7739
- "version": "3.8.1",
7740
- "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.8.1.tgz",
7741
- "integrity": "sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==",
7742
- "dependencies": {
7743
- "atomic-sleep": "^1.0.0"
7744
- }
7745
- },
7746
  "node_modules/sorcery": {
7747
  "version": "0.11.0",
7748
  "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.0.tgz",
@@ -7782,14 +6963,6 @@
7782
  "memory-pager": "^1.0.2"
7783
  }
7784
  },
7785
- "node_modules/split2": {
7786
- "version": "4.2.0",
7787
- "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
7788
- "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
7789
- "engines": {
7790
- "node": ">= 10.x"
7791
- }
7792
- },
7793
  "node_modules/sprintf-js": {
7794
  "version": "1.1.3",
7795
  "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
@@ -7801,14 +6974,6 @@
7801
  "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
7802
  "dev": true
7803
  },
7804
- "node_modules/statuses": {
7805
- "version": "2.0.1",
7806
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
7807
- "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
7808
- "engines": {
7809
- "node": ">= 0.8"
7810
- }
7811
- },
7812
  "node_modules/std-env": {
7813
  "version": "3.3.3",
7814
  "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.3.3.tgz",
@@ -7874,6 +7039,7 @@
7874
  "version": "3.1.1",
7875
  "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
7876
  "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
 
7877
  "engines": {
7878
  "node": ">=8"
7879
  },
@@ -8280,15 +7446,6 @@
8280
  "streamx": "^2.15.0"
8281
  }
8282
  },
8283
- "node_modules/tdigest": {
8284
- "version": "0.1.2",
8285
- "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.2.tgz",
8286
- "integrity": "sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==",
8287
- "dev": true,
8288
- "dependencies": {
8289
- "bintrees": "1.0.2"
8290
- }
8291
- },
8292
  "node_modules/text-table": {
8293
  "version": "0.2.0",
8294
  "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -8314,14 +7471,6 @@
8314
  "node": ">=0.8"
8315
  }
8316
  },
8317
- "node_modules/thread-stream": {
8318
- "version": "2.7.0",
8319
- "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.7.0.tgz",
8320
- "integrity": "sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==",
8321
- "dependencies": {
8322
- "real-require": "^0.2.0"
8323
- }
8324
- },
8325
  "node_modules/thrift": {
8326
  "version": "0.11.0",
8327
  "resolved": "https://registry.npmjs.org/thrift/-/thrift-0.11.0.tgz",
@@ -8394,14 +7543,6 @@
8394
  "node": ">=8.0"
8395
  }
8396
  },
8397
- "node_modules/toidentifier": {
8398
- "version": "1.0.1",
8399
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
8400
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
8401
- "engines": {
8402
- "node": ">=0.6"
8403
- }
8404
- },
8405
  "node_modules/totalist": {
8406
  "version": "3.0.0",
8407
  "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.0.tgz",
@@ -8552,18 +7693,6 @@
8552
  "url": "https://github.com/sponsors/sindresorhus"
8553
  }
8554
  },
8555
- "node_modules/type-is": {
8556
- "version": "1.6.18",
8557
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
8558
- "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
8559
- "dependencies": {
8560
- "media-typer": "0.3.0",
8561
- "mime-types": "~2.1.24"
8562
- },
8563
- "engines": {
8564
- "node": ">= 0.6"
8565
- }
8566
- },
8567
  "node_modules/typescript": {
8568
  "version": "5.2.2",
8569
  "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
@@ -8628,14 +7757,6 @@
8628
  "node": ">= 4.0.0"
8629
  }
8630
  },
8631
- "node_modules/unpipe": {
8632
- "version": "1.0.0",
8633
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
8634
- "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
8635
- "engines": {
8636
- "node": ">= 0.8"
8637
- }
8638
- },
8639
  "node_modules/unplugin": {
8640
  "version": "1.3.1",
8641
  "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.3.1.tgz",
@@ -8740,14 +7861,6 @@
8740
  "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
8741
  "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
8742
  },
8743
- "node_modules/utils-merge": {
8744
- "version": "1.0.1",
8745
- "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
8746
- "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
8747
- "engines": {
8748
- "node": ">= 0.4.0"
8749
- }
8750
- },
8751
  "node_modules/uuid": {
8752
  "version": "9.0.1",
8753
  "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
@@ -8771,14 +7884,6 @@
8771
  "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz",
8772
  "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow=="
8773
  },
8774
- "node_modules/vary": {
8775
- "version": "1.1.2",
8776
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
8777
- "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
8778
- "engines": {
8779
- "node": ">= 0.8"
8780
- }
8781
- },
8782
  "node_modules/vite": {
8783
  "version": "4.5.3",
8784
  "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz",
 
1
  {
2
  "name": "chat-ui",
3
+ "version": "0.8.2",
4
  "lockfileVersion": 3,
5
  "requires": true,
6
  "packages": {
7
  "": {
8
  "name": "chat-ui",
9
+ "version": "0.8.2",
10
  "dependencies": {
11
  "@huggingface/hub": "^0.5.1",
12
  "@huggingface/inference": "^2.6.3",
 
17
  "browser-image-resizer": "^2.4.1",
18
  "date-fns": "^2.29.3",
19
  "dotenv": "^16.0.3",
 
20
  "handlebars": "^4.7.8",
21
  "highlight.js": "^11.7.0",
22
  "image-size": "^1.0.2",
 
29
  "nanoid": "^4.0.2",
30
  "openid-client": "^5.4.2",
31
  "parquetjs": "^0.11.2",
 
 
32
  "postcss": "^8.4.31",
33
  "saslprep": "^1.0.3",
34
  "satori": "^0.10.11",
 
47
  "@sveltejs/adapter-node": "^1.3.1",
48
  "@sveltejs/kit": "^1.30.4",
49
  "@tailwindcss/typography": "^0.5.9",
 
50
  "@types/jsdom": "^21.1.1",
51
  "@types/minimist": "^1.2.5",
52
  "@types/parquetjs": "^0.10.3",
 
60
  "prettier": "^2.8.0",
61
  "prettier-plugin-svelte": "^2.10.1",
62
  "prettier-plugin-tailwindcss": "^0.2.7",
 
63
  "svelte": "^4.2.8",
64
  "svelte-check": "^3.6.2",
65
  "ts-node": "^10.9.1",
 
72
  },
73
  "optionalDependencies": {
74
  "@anthropic-ai/sdk": "^0.17.1",
75
+ "@google-cloud/vertexai": "^0.5.0",
76
  "aws4fetch": "^1.0.17",
77
  "cohere-ai": "^7.9.0",
78
  "openai": "^4.14.2"
 
630
  }
631
  },
632
  "node_modules/@google-cloud/vertexai": {
633
+ "version": "0.5.0",
634
+ "resolved": "https://registry.npmjs.org/@google-cloud/vertexai/-/vertexai-0.5.0.tgz",
635
+ "integrity": "sha512-qIFHYTXA5UCLdm9JG+Xf1suomCXxRqa1PKdYjqXuhZsCm8mn37Rb0Tf8djlhDzuRVWyWoQTmsWpsk28ZTmbqJg==",
636
  "optional": true,
637
  "dependencies": {
638
  "google-auth-library": "^9.1.0"
 
1261
  "node": ">= 8"
1262
  }
1263
  },
 
 
 
 
 
 
 
 
 
1264
  "node_modules/@polka/url": {
1265
  "version": "1.0.0-next.21",
1266
  "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz",
 
1985
  "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
1986
  "devOptional": true
1987
  },
 
 
 
 
 
 
 
 
 
 
1988
  "node_modules/@types/chai": {
1989
  "version": "4.3.5",
1990
  "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz",
 
2000
  "@types/chai": "*"
2001
  }
2002
  },
 
 
 
 
 
 
 
 
 
2003
  "node_modules/@types/cookie": {
2004
  "version": "0.5.1",
2005
  "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.5.1.tgz",
 
2012
  "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
2013
  "dev": true
2014
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2015
  "node_modules/@types/jsdom": {
2016
  "version": "21.1.1",
2017
  "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.1.tgz",
 
2039
  "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
2040
  "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA=="
2041
  },
 
 
 
 
 
 
2042
  "node_modules/@types/minimist": {
2043
  "version": "1.2.5",
2044
  "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz",
 
2084
  "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==",
2085
  "dev": true
2086
  },
 
 
 
 
 
 
 
 
 
 
 
 
2087
  "node_modules/@types/resolve": {
2088
  "version": "1.20.2",
2089
  "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
 
2096
  "integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==",
2097
  "dev": true
2098
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2099
  "node_modules/@types/tough-cookie": {
2100
  "version": "4.0.2",
2101
  "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz",
 
2451
  "version": "3.0.0",
2452
  "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
2453
  "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
2454
+ "optional": true,
2455
  "dependencies": {
2456
  "event-target-shim": "^5.0.0"
2457
  },
 
2459
  "node": ">=6.5"
2460
  }
2461
  },
 
 
 
 
 
 
 
 
 
 
 
 
2462
  "node_modules/acorn": {
2463
  "version": "8.11.3",
2464
  "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
 
2589
  "dequal": "^2.0.3"
2590
  }
2591
  },
 
 
 
 
 
2592
  "node_modules/array-union": {
2593
  "version": "2.1.0",
2594
  "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
 
2612
  "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
2613
  "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
2614
  },
 
 
 
 
 
 
 
 
2615
  "node_modules/autoprefixer": {
2616
  "version": "10.4.14",
2617
  "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz",
 
2717
  "integrity": "sha512-u4cBQNepWxYA55FunZSM7wMi55yQaN0otnhhilNoWHq0MfOfJeQx0v0mRRpolGOExPjZcl6FtB0BB8Xkb88F0g==",
2718
  "optional": true
2719
  },
 
 
 
 
 
 
2720
  "node_modules/bl": {
2721
  "version": "4.1.0",
2722
  "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
 
2733
  "integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==",
2734
  "dev": true
2735
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2736
  "node_modules/brace-expansion": {
2737
  "version": "1.1.11",
2738
  "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
 
2865
  "url": "https://github.com/sponsors/sindresorhus"
2866
  }
2867
  },
 
 
 
 
 
 
 
 
2868
  "node_modules/cac": {
2869
  "version": "6.7.14",
2870
  "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
 
2878
  "version": "1.0.7",
2879
  "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
2880
  "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
2881
+ "optional": true,
2882
  "dependencies": {
2883
  "es-define-property": "^1.0.0",
2884
  "es-errors": "^1.3.0",
 
3103
  "simple-swizzle": "^0.2.2"
3104
  }
3105
  },
 
 
 
 
 
3106
  "node_modules/combined-stream": {
3107
  "version": "1.0.8",
3108
  "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
 
3152
  "node": ">=10.18.0 <11 || >=12.14.0 <13 || >=14"
3153
  }
3154
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3155
  "node_modules/cookie": {
3156
  "version": "0.5.0",
3157
  "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
 
3161
  "node": ">= 0.6"
3162
  }
3163
  },
 
 
 
 
 
3164
  "node_modules/create-require": {
3165
  "version": "1.1.1",
3166
  "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
 
3313
  "node": ">=6"
3314
  }
3315
  },
 
 
 
 
 
 
 
 
3316
  "node_modules/debug": {
3317
  "version": "4.3.4",
3318
  "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
 
3387
  "version": "1.1.4",
3388
  "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
3389
  "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
3390
+ "optional": true,
3391
  "dependencies": {
3392
  "es-define-property": "^1.0.0",
3393
  "es-errors": "^1.3.0",
 
3408
  "node": ">=0.4.0"
3409
  }
3410
  },
 
 
 
 
 
 
 
 
3411
  "node_modules/dequal": {
3412
  "version": "2.0.3",
3413
  "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
 
3417
  "node": ">=6"
3418
  }
3419
  },
 
 
 
 
 
 
 
 
 
3420
  "node_modules/detect-indent": {
3421
  "version": "6.1.0",
3422
  "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz",
 
3521
  "safe-buffer": "^5.0.1"
3522
  }
3523
  },
 
 
 
 
 
3524
  "node_modules/electron-to-chromium": {
3525
  "version": "1.4.359",
3526
  "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.359.tgz",
 
3531
  "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz",
3532
  "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw=="
3533
  },
 
 
 
 
 
 
 
 
3534
  "node_modules/end-of-stream": {
3535
  "version": "1.4.4",
3536
  "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
 
3554
  "version": "1.0.0",
3555
  "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
3556
  "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
3557
+ "optional": true,
3558
  "dependencies": {
3559
  "get-intrinsic": "^1.2.4"
3560
  },
 
3566
  "version": "1.3.0",
3567
  "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
3568
  "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
3569
+ "optional": true,
3570
  "engines": {
3571
  "node": ">= 0.4"
3572
  }
 
3856
  "node": ">=0.10.0"
3857
  }
3858
  },
 
 
 
 
 
 
 
 
3859
  "node_modules/event-target-shim": {
3860
  "version": "5.0.1",
3861
  "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
3862
  "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
3863
+ "optional": true,
3864
  "engines": {
3865
  "node": ">=6"
3866
  }
3867
  },
 
 
 
 
 
 
 
 
3868
  "node_modules/execa": {
3869
  "version": "5.1.1",
3870
  "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
 
3896
  "node": ">=6"
3897
  }
3898
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3899
  "node_modules/extend": {
3900
  "version": "3.0.2",
3901
  "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
3902
  "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
3903
  "optional": true
3904
  },
 
 
 
 
 
3905
  "node_modules/fast-deep-equal": {
3906
  "version": "3.1.3",
3907
  "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
 
3957
  "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
3958
  "dev": true
3959
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
3960
  "node_modules/fastq": {
3961
  "version": "1.15.0",
3962
  "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
 
3993
  "node": ">=8"
3994
  }
3995
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3996
  "node_modules/find-up": {
3997
  "version": "5.0.0",
3998
  "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
 
4065
  "node": ">= 12.20"
4066
  }
4067
  },
 
 
 
 
 
 
 
 
4068
  "node_modules/fraction.js": {
4069
  "version": "4.2.0",
4070
  "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
 
4077
  "url": "https://www.patreon.com/infusion"
4078
  }
4079
  },
 
 
 
 
 
 
 
 
4080
  "node_modules/fs-constants": {
4081
  "version": "1.0.0",
4082
  "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
 
4174
  "version": "1.2.4",
4175
  "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
4176
  "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
4177
+ "optional": true,
4178
  "dependencies": {
4179
  "es-errors": "^1.3.0",
4180
  "function-bind": "^1.1.2",
 
4305
  "version": "1.0.1",
4306
  "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
4307
  "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
4308
+ "optional": true,
4309
  "dependencies": {
4310
  "get-intrinsic": "^1.1.3"
4311
  },
 
4382
  "version": "1.0.2",
4383
  "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
4384
  "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
4385
+ "optional": true,
4386
  "dependencies": {
4387
  "es-define-property": "^1.0.0"
4388
  },
 
4394
  "version": "1.0.3",
4395
  "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
4396
  "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
4397
+ "optional": true,
4398
  "engines": {
4399
  "node": ">= 0.4"
4400
  },
 
4406
  "version": "1.0.3",
4407
  "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
4408
  "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
4409
+ "optional": true,
4410
  "engines": {
4411
  "node": ">= 0.4"
4412
  },
 
4430
  "node": ">= 0.4"
4431
  }
4432
  },
 
 
 
 
 
4433
  "node_modules/hex-rgb": {
4434
  "version": "4.3.0",
4435
  "resolved": "https://registry.npmjs.org/hex-rgb/-/hex-rgb-4.3.0.tgz",
 
4460
  "node": ">=12"
4461
  }
4462
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4463
  "node_modules/http-proxy-agent": {
4464
  "version": "5.0.0",
4465
  "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
 
4617
  "node": ">= 12"
4618
  }
4619
  },
 
 
 
 
 
 
 
 
4620
  "node_modules/is-arrayish": {
4621
  "version": "0.3.2",
4622
  "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
 
4755
  "url": "https://github.com/sponsors/panva"
4756
  }
4757
  },
 
 
 
 
 
 
 
 
4758
  "node_modules/js-base64": {
4759
  "version": "3.7.2",
4760
  "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz",
 
5171
  "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
5172
  "dev": true
5173
  },
 
 
 
 
 
 
 
 
5174
  "node_modules/memory-pager": {
5175
  "version": "1.5.0",
5176
  "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
5177
  "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg=="
5178
  },
 
 
 
 
 
5179
  "node_modules/merge-stream": {
5180
  "version": "2.0.0",
5181
  "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
 
5190
  "node": ">= 8"
5191
  }
5192
  },
 
 
 
 
 
 
 
 
5193
  "node_modules/micromatch": {
5194
  "version": "4.0.5",
5195
  "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
 
5202
  "node": ">=8.6"
5203
  }
5204
  },
 
 
 
 
 
 
 
 
 
 
 
5205
  "node_modules/mime-db": {
5206
  "version": "1.52.0",
5207
  "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
 
5408
  "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
5409
  "dev": true
5410
  },
 
 
 
 
 
 
 
 
5411
  "node_modules/neo-async": {
5412
  "version": "2.6.2",
5413
  "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
 
5565
  "version": "1.13.1",
5566
  "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
5567
  "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==",
5568
+ "optional": true,
5569
  "funding": {
5570
  "url": "https://github.com/sponsors/ljharb"
5571
  }
 
5586
  "node": "^10.13.0 || >=12.0.0"
5587
  }
5588
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5589
  "node_modules/once": {
5590
  "version": "1.4.0",
5591
  "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
 
5812
  "url": "https://github.com/inikulin/parse5?sponsor=1"
5813
  }
5814
  },
 
 
 
 
 
 
 
 
5815
  "node_modules/path-exists": {
5816
  "version": "4.0.0",
5817
  "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
 
5843
  "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
5844
  "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
5845
  },
 
 
 
 
 
5846
  "node_modules/path-type": {
5847
  "version": "4.0.0",
5848
  "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
 
5920
  "node": ">=0.10.0"
5921
  }
5922
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5923
  "node_modules/pirates": {
5924
  "version": "4.0.5",
5925
  "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
 
6313
  "url": "https://github.com/chalk/ansi-styles?sponsor=1"
6314
  }
6315
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6316
  "node_modules/protobufjs": {
6317
  "version": "6.11.4",
6318
  "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz",
 
6338
  "pbts": "bin/pbts"
6339
  }
6340
  },
 
 
 
 
 
 
 
 
 
 
 
 
6341
  "node_modules/psl": {
6342
  "version": "1.9.0",
6343
  "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
 
6421
  "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
6422
  "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag=="
6423
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6424
  "node_modules/rc": {
6425
  "version": "1.2.8",
6426
  "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
 
6481
  "node": ">=8.10.0"
6482
  }
6483
  },
 
 
 
 
 
 
 
 
6484
  "node_modules/requires-port": {
6485
  "version": "1.0.0",
6486
  "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
 
6609
  }
6610
  ]
6611
  },
 
 
 
 
 
 
 
 
6612
  "node_modules/safer-buffer": {
6613
  "version": "2.1.2",
6614
  "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
 
6688
  "node": ">=v12.22.7"
6689
  }
6690
  },
 
 
 
 
 
6691
  "node_modules/semver": {
6692
  "version": "7.5.4",
6693
  "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
 
6702
  "node": ">=10"
6703
  }
6704
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6705
  "node_modules/serpapi": {
6706
  "version": "1.1.1",
6707
  "resolved": "https://registry.npmjs.org/serpapi/-/serpapi-1.1.1.tgz",
 
6710
  "undici": "^5.12.0"
6711
  }
6712
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6713
  "node_modules/set-cookie-parser": {
6714
  "version": "2.6.0",
6715
  "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz",
 
6720
  "version": "1.2.2",
6721
  "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
6722
  "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
6723
+ "optional": true,
6724
  "dependencies": {
6725
  "define-data-property": "^1.1.4",
6726
  "es-errors": "^1.3.0",
 
6733
  "node": ">= 0.4"
6734
  }
6735
  },
 
 
 
 
 
6736
  "node_modules/sharp": {
6737
  "version": "0.33.2",
6738
  "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.2.tgz",
 
6797
  "version": "1.0.6",
6798
  "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
6799
  "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
6800
+ "optional": true,
6801
  "dependencies": {
6802
  "call-bind": "^1.0.7",
6803
  "es-errors": "^1.3.0",
 
6924
  "npm": ">= 3.0.0"
6925
  }
6926
  },
 
 
 
 
 
 
 
 
6927
  "node_modules/sorcery": {
6928
  "version": "0.11.0",
6929
  "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.0.tgz",
 
6963
  "memory-pager": "^1.0.2"
6964
  }
6965
  },
 
 
 
 
 
 
 
 
6966
  "node_modules/sprintf-js": {
6967
  "version": "1.1.3",
6968
  "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
 
6974
  "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
6975
  "dev": true
6976
  },
 
 
 
 
 
 
 
 
6977
  "node_modules/std-env": {
6978
  "version": "3.3.3",
6979
  "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.3.3.tgz",
 
7039
  "version": "3.1.1",
7040
  "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
7041
  "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
7042
+ "dev": true,
7043
  "engines": {
7044
  "node": ">=8"
7045
  },
 
7446
  "streamx": "^2.15.0"
7447
  }
7448
  },
 
 
 
 
 
 
 
 
 
7449
  "node_modules/text-table": {
7450
  "version": "0.2.0",
7451
  "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
 
7471
  "node": ">=0.8"
7472
  }
7473
  },
 
 
 
 
 
 
 
 
7474
  "node_modules/thrift": {
7475
  "version": "0.11.0",
7476
  "resolved": "https://registry.npmjs.org/thrift/-/thrift-0.11.0.tgz",
 
7543
  "node": ">=8.0"
7544
  }
7545
  },
 
 
 
 
 
 
 
 
7546
  "node_modules/totalist": {
7547
  "version": "3.0.0",
7548
  "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.0.tgz",
 
7693
  "url": "https://github.com/sponsors/sindresorhus"
7694
  }
7695
  },
 
 
 
 
 
 
 
 
 
 
 
 
7696
  "node_modules/typescript": {
7697
  "version": "5.2.2",
7698
  "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
 
7757
  "node": ">= 4.0.0"
7758
  }
7759
  },
 
 
 
 
 
 
 
 
7760
  "node_modules/unplugin": {
7761
  "version": "1.3.1",
7762
  "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.3.1.tgz",
 
7861
  "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
7862
  "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
7863
  },
 
 
 
 
 
 
 
 
7864
  "node_modules/uuid": {
7865
  "version": "9.0.1",
7866
  "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
 
7884
  "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz",
7885
  "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow=="
7886
  },
 
 
 
 
 
 
 
 
7887
  "node_modules/vite": {
7888
  "version": "4.5.3",
7889
  "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz",
package.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "chat-ui",
3
- "version": "0.8.3",
4
  "private": true,
5
  "packageManager": "npm@9.5.0",
6
  "scripts": {
@@ -23,7 +23,6 @@
23
  "@sveltejs/adapter-node": "^1.3.1",
24
  "@sveltejs/kit": "^1.30.4",
25
  "@tailwindcss/typography": "^0.5.9",
26
- "@types/express": "^4.17.21",
27
  "@types/jsdom": "^21.1.1",
28
  "@types/minimist": "^1.2.5",
29
  "@types/parquetjs": "^0.10.3",
@@ -37,7 +36,6 @@
37
  "prettier": "^2.8.0",
38
  "prettier-plugin-svelte": "^2.10.1",
39
  "prettier-plugin-tailwindcss": "^0.2.7",
40
- "prom-client": "^15.1.2",
41
  "svelte": "^4.2.8",
42
  "svelte-check": "^3.6.2",
43
  "ts-node": "^10.9.1",
@@ -59,7 +57,6 @@
59
  "browser-image-resizer": "^2.4.1",
60
  "date-fns": "^2.29.3",
61
  "dotenv": "^16.0.3",
62
- "express": "^4.19.2",
63
  "handlebars": "^4.7.8",
64
  "highlight.js": "^11.7.0",
65
  "image-size": "^1.0.2",
@@ -72,8 +69,6 @@
72
  "nanoid": "^4.0.2",
73
  "openid-client": "^5.4.2",
74
  "parquetjs": "^0.11.2",
75
- "pino": "^9.0.0",
76
- "pino-pretty": "^11.0.0",
77
  "postcss": "^8.4.31",
78
  "saslprep": "^1.0.3",
79
  "satori": "^0.10.11",
@@ -87,7 +82,7 @@
87
  },
88
  "optionalDependencies": {
89
  "@anthropic-ai/sdk": "^0.17.1",
90
- "@google-cloud/vertexai": "^1.1.0",
91
  "aws4fetch": "^1.0.17",
92
  "cohere-ai": "^7.9.0",
93
  "openai": "^4.14.2"
 
1
  {
2
  "name": "chat-ui",
3
+ "version": "0.8.2",
4
  "private": true,
5
  "packageManager": "npm@9.5.0",
6
  "scripts": {
 
23
  "@sveltejs/adapter-node": "^1.3.1",
24
  "@sveltejs/kit": "^1.30.4",
25
  "@tailwindcss/typography": "^0.5.9",
 
26
  "@types/jsdom": "^21.1.1",
27
  "@types/minimist": "^1.2.5",
28
  "@types/parquetjs": "^0.10.3",
 
36
  "prettier": "^2.8.0",
37
  "prettier-plugin-svelte": "^2.10.1",
38
  "prettier-plugin-tailwindcss": "^0.2.7",
 
39
  "svelte": "^4.2.8",
40
  "svelte-check": "^3.6.2",
41
  "ts-node": "^10.9.1",
 
57
  "browser-image-resizer": "^2.4.1",
58
  "date-fns": "^2.29.3",
59
  "dotenv": "^16.0.3",
 
60
  "handlebars": "^4.7.8",
61
  "highlight.js": "^11.7.0",
62
  "image-size": "^1.0.2",
 
69
  "nanoid": "^4.0.2",
70
  "openid-client": "^5.4.2",
71
  "parquetjs": "^0.11.2",
 
 
72
  "postcss": "^8.4.31",
73
  "saslprep": "^1.0.3",
74
  "satori": "^0.10.11",
 
82
  },
83
  "optionalDependencies": {
84
  "@anthropic-ai/sdk": "^0.17.1",
85
+ "@google-cloud/vertexai": "^0.5.0",
86
  "aws4fetch": "^1.0.17",
87
  "cohere-ai": "^7.9.0",
88
  "openai": "^4.14.2"
scripts/populate.ts CHANGED
@@ -2,13 +2,12 @@ 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 { collections } from "$lib/server/database";
12
  import { models } from "../src/lib/server/models.ts";
13
  import type { User } from "../src/lib/types/User";
14
  import type { Assistant } from "../src/lib/types/Assistant";
@@ -18,7 +17,6 @@ import { defaultEmbeddingModel } from "../src/lib/server/embeddingModels.ts";
18
  import { Message } from "../src/lib/types/Message.ts";
19
 
20
  import { addChildren } from "../src/lib/utils/tree/addChildren.ts";
21
- import { generateSearchTokens } from "../src/lib/utils/searchTokens.ts";
22
 
23
  const rl = readline.createInterface({
24
  input: process.stdin,
@@ -160,11 +158,10 @@ async function seed() {
160
  console.log("Creating assistants for all users");
161
  await Promise.all(
162
  users.map(async (user) => {
163
- const name = faker.animal.insect();
164
  const assistants = faker.helpers.multiple<Assistant>(
165
  () => ({
166
  _id: new ObjectId(),
167
- name,
168
  createdById: user._id,
169
  createdByName: user.username,
170
  createdAt: faker.date.recent({ days: 30 }),
@@ -177,8 +174,6 @@ async function seed() {
177
  exampleInputs: faker.helpers.multiple(() => faker.lorem.sentence(), {
178
  count: faker.number.int({ min: 0, max: 4 }),
179
  }),
180
- searchTokens: generateSearchTokens(name),
181
- last24HoursCount: faker.number.int({ min: 0, max: 1000 }),
182
  }),
183
  { count: faker.number.int({ min: 3, max: 10 }) }
184
  );
@@ -246,7 +241,7 @@ async function seed() {
246
  try {
247
  rl.question(
248
  "You're about to run a seeding script on the following MONGODB_URL: \x1b[31m" +
249
- env.MONGODB_URL +
250
  "\x1b[0m\n\n With the following flags: \x1b[31m" +
251
  flags.join("\x1b[0m , \x1b[31m") +
252
  "\x1b[0m\n \n\n Are you sure you want to continue? (yes/no): ",
 
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 { MONGODB_URL } from "$env/static/private";
6
 
7
  import { faker } from "@faker-js/faker";
8
  import { ObjectId } from "mongodb";
9
 
10
+ import { collections } from "../src/lib/server/database.ts";
 
11
  import { models } from "../src/lib/server/models.ts";
12
  import type { User } from "../src/lib/types/User";
13
  import type { Assistant } from "../src/lib/types/Assistant";
 
17
  import { Message } from "../src/lib/types/Message.ts";
18
 
19
  import { addChildren } from "../src/lib/utils/tree/addChildren.ts";
 
20
 
21
  const rl = readline.createInterface({
22
  input: process.stdin,
 
158
  console.log("Creating assistants for all users");
159
  await Promise.all(
160
  users.map(async (user) => {
 
161
  const assistants = faker.helpers.multiple<Assistant>(
162
  () => ({
163
  _id: new ObjectId(),
164
+ name: faker.animal.insect(),
165
  createdById: user._id,
166
  createdByName: user.username,
167
  createdAt: faker.date.recent({ days: 30 }),
 
174
  exampleInputs: faker.helpers.multiple(() => faker.lorem.sentence(), {
175
  count: faker.number.int({ min: 0, max: 4 }),
176
  }),
 
 
177
  }),
178
  { count: faker.number.int({ min: 3, max: 10 }) }
179
  );
 
241
  try {
242
  rl.question(
243
  "You're about to run a seeding script on the following MONGODB_URL: \x1b[31m" +
244
+ MONGODB_URL +
245
  "\x1b[0m\n\n With the following flags: \x1b[31m" +
246
  flags.join("\x1b[0m , \x1b[31m") +
247
  "\x1b[0m\n \n\n Are you sure you want to continue? (yes/no): ",
src/app.d.ts CHANGED
@@ -12,11 +12,6 @@ declare global {
12
  sessionId: string;
13
  user?: User;
14
  }
15
-
16
- interface Error {
17
- message: string;
18
- errorId?: ReturnType<typeof crypto.randomUUID>;
19
- }
20
  // interface PageData {}
21
  // interface Platform {}
22
  }
 
12
  sessionId: string;
13
  user?: User;
14
  }
 
 
 
 
 
15
  // interface PageData {}
16
  // interface Platform {}
17
  }
src/hooks.server.ts CHANGED
@@ -1,6 +1,17 @@
1
- import { env } from "$env/dynamic/private";
2
- import { env as envPublic } from "$env/dynamic/public";
3
- import type { Handle, HandleServerError } from "@sveltejs/kit";
 
 
 
 
 
 
 
 
 
 
 
4
  import { collections } from "$lib/server/database";
5
  import { base } from "$app/paths";
6
  import { findUser, refreshSessionCookie, requiresUser } from "$lib/server/auth";
@@ -10,63 +21,16 @@ import { addWeeks } from "date-fns";
10
  import { checkAndRunMigrations } from "$lib/migrations/migrations";
11
  import { building } from "$app/environment";
12
  import { refreshAssistantsCounts } from "$lib/assistantStats/refresh-assistants-counts";
13
- import { logger } from "$lib/server/logger";
14
- import { AbortedGenerations } from "$lib/server/abortedGenerations";
15
- import { MetricsServer } from "$lib/server/metrics";
16
 
17
- // TODO: move this code on a started server hook, instead of using a "building" flag
18
  if (!building) {
19
  await checkAndRunMigrations();
20
- if (env.ENABLE_ASSISTANTS) {
21
  refreshAssistantsCounts();
22
  }
23
-
24
- // Init metrics server
25
- MetricsServer.getInstance();
26
-
27
- // Init AbortedGenerations refresh process
28
- AbortedGenerations.getInstance();
29
  }
30
 
31
- export const handleError: HandleServerError = async ({ error, event }) => {
32
- // handle 404
33
-
34
- if (building) {
35
- throw error;
36
- }
37
-
38
- if (event.route.id === null) {
39
- return {
40
- message: `Page ${event.url.pathname} not found`,
41
- };
42
- }
43
-
44
- const errorId = crypto.randomUUID();
45
-
46
- logger.error({
47
- locals: event.locals,
48
- url: event.request.url,
49
- params: event.params,
50
- request: event.request,
51
- error,
52
- errorId,
53
- });
54
-
55
- return {
56
- message: "An error occurred",
57
- errorId,
58
- };
59
- };
60
-
61
  export const handle: Handle = async ({ event, resolve }) => {
62
- logger.debug({
63
- locals: event.locals,
64
- url: event.url.pathname,
65
- params: event.params,
66
- request: event.request,
67
- });
68
-
69
- if (event.url.pathname.startsWith(`${base}/api/`) && env.EXPOSE_API !== "true") {
70
  return new Response("API is disabled", { status: 403 });
71
  }
72
 
@@ -83,7 +47,7 @@ export const handle: Handle = async ({ event, resolve }) => {
83
  }
84
 
85
  if (event.url.pathname.startsWith(`${base}/admin/`) || event.url.pathname === `${base}/admin`) {
86
- const ADMIN_SECRET = env.ADMIN_API_SECRET || env.PARQUET_EXPORT_SECRET;
87
 
88
  if (!ADMIN_SECRET) {
89
  return errorResponse(500, "Admin API is not configured");
@@ -94,7 +58,7 @@ export const handle: Handle = async ({ event, resolve }) => {
94
  }
95
  }
96
 
97
- const token = event.cookies.get(env.COOKIE_NAME);
98
 
99
  let secretSessionId: string;
100
  let sessionId: string;
@@ -133,18 +97,18 @@ export const handle: Handle = async ({ event, resolve }) => {
133
  refreshSessionCookie(event.cookies, event.locals.sessionId);
134
 
135
  if (nativeFormContentTypes.includes(requestContentType)) {
136
- const origin = event.request.headers.get("origin");
137
 
138
- if (!origin) {
139
- return errorResponse(403, "Non-JSON form requests need to have an origin");
140
  }
141
 
142
  const validOrigins = [
143
- new URL(event.request.url).host,
144
- ...(envPublic.PUBLIC_ORIGIN ? [new URL(envPublic.PUBLIC_ORIGIN).host] : []),
145
  ];
146
 
147
- if (!validOrigins.includes(new URL(origin).host)) {
148
  return errorResponse(403, "Invalid referer for POST request");
149
  }
150
  }
@@ -168,7 +132,7 @@ export const handle: Handle = async ({ event, resolve }) => {
168
  if (
169
  !event.locals.user &&
170
  requiresUser &&
171
- !((env.MESSAGES_BEFORE_LOGIN ? parseInt(env.MESSAGES_BEFORE_LOGIN) : 0) > 0)
172
  ) {
173
  return errorResponse(401, ERROR_MESSAGES.authOnly);
174
  }
@@ -179,7 +143,7 @@ export const handle: Handle = async ({ event, resolve }) => {
179
  if (
180
  !requiresUser &&
181
  !event.url.pathname.startsWith(`${base}/settings`) &&
182
- !!envPublic.PUBLIC_APP_DISCLAIMER
183
  ) {
184
  const hasAcceptedEthicsModal = await collections.settings.countDocuments({
185
  sessionId: event.locals.sessionId,
@@ -202,7 +166,7 @@ export const handle: Handle = async ({ event, resolve }) => {
202
  }
203
  replaced = true;
204
 
205
- return chunk.html.replace("%gaId%", envPublic.PUBLIC_GOOGLE_ANALYTICS_ID);
206
  },
207
  });
208
 
 
1
+ import {
2
+ ADMIN_API_SECRET,
3
+ COOKIE_NAME,
4
+ ENABLE_ASSISTANTS,
5
+ EXPOSE_API,
6
+ MESSAGES_BEFORE_LOGIN,
7
+ PARQUET_EXPORT_SECRET,
8
+ } from "$env/static/private";
9
+ import type { Handle } from "@sveltejs/kit";
10
+ import {
11
+ PUBLIC_GOOGLE_ANALYTICS_ID,
12
+ PUBLIC_ORIGIN,
13
+ PUBLIC_APP_DISCLAIMER,
14
+ } from "$env/static/public";
15
  import { collections } from "$lib/server/database";
16
  import { base } from "$app/paths";
17
  import { findUser, refreshSessionCookie, requiresUser } from "$lib/server/auth";
 
21
  import { checkAndRunMigrations } from "$lib/migrations/migrations";
22
  import { building } from "$app/environment";
23
  import { refreshAssistantsCounts } from "$lib/assistantStats/refresh-assistants-counts";
 
 
 
24
 
 
25
  if (!building) {
26
  await checkAndRunMigrations();
27
+ if (ENABLE_ASSISTANTS) {
28
  refreshAssistantsCounts();
29
  }
 
 
 
 
 
 
30
  }
31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  export const handle: Handle = async ({ event, resolve }) => {
33
+ if (event.url.pathname.startsWith(`${base}/api/`) && EXPOSE_API !== "true") {
 
 
 
 
 
 
 
34
  return new Response("API is disabled", { status: 403 });
35
  }
36
 
 
47
  }
48
 
49
  if (event.url.pathname.startsWith(`${base}/admin/`) || event.url.pathname === `${base}/admin`) {
50
+ const ADMIN_SECRET = ADMIN_API_SECRET || PARQUET_EXPORT_SECRET;
51
 
52
  if (!ADMIN_SECRET) {
53
  return errorResponse(500, "Admin API is not configured");
 
58
  }
59
  }
60
 
61
+ const token = event.cookies.get(COOKIE_NAME);
62
 
63
  let secretSessionId: string;
64
  let sessionId: string;
 
97
  refreshSessionCookie(event.cookies, event.locals.sessionId);
98
 
99
  if (nativeFormContentTypes.includes(requestContentType)) {
100
+ const referer = event.request.headers.get("referer");
101
 
102
+ if (!referer) {
103
+ return errorResponse(403, "Non-JSON form requests need to have a referer");
104
  }
105
 
106
  const validOrigins = [
107
+ new URL(event.request.url).origin,
108
+ ...(PUBLIC_ORIGIN ? [new URL(PUBLIC_ORIGIN).origin] : []),
109
  ];
110
 
111
+ if (!validOrigins.includes(new URL(referer).origin)) {
112
  return errorResponse(403, "Invalid referer for POST request");
113
  }
114
  }
 
132
  if (
133
  !event.locals.user &&
134
  requiresUser &&
135
+ !((MESSAGES_BEFORE_LOGIN ? parseInt(MESSAGES_BEFORE_LOGIN) : 0) > 0)
136
  ) {
137
  return errorResponse(401, ERROR_MESSAGES.authOnly);
138
  }
 
143
  if (
144
  !requiresUser &&
145
  !event.url.pathname.startsWith(`${base}/settings`) &&
146
+ !!PUBLIC_APP_DISCLAIMER
147
  ) {
148
  const hasAcceptedEthicsModal = await collections.settings.countDocuments({
149
  sessionId: event.locals.sessionId,
 
166
  }
167
  replaced = true;
168
 
169
+ return chunk.html.replace("%gaId%", PUBLIC_GOOGLE_ANALYTICS_ID);
170
  },
171
  });
172
 
src/lib/assistantStats/refresh-assistants-counts.ts CHANGED
@@ -1,8 +1,7 @@
1
- import { Database } from "$lib/server/database";
2
  import { acquireLock, refreshLock } from "$lib/migrations/lock";
3
  import type { ObjectId } from "mongodb";
4
  import { subDays } from "date-fns";
5
- import { logger } from "$lib/server/logger";
6
 
7
  const LOCK_KEY = "assistants.count";
8
 
@@ -15,52 +14,47 @@ async function refreshAssistantsCountsHelper() {
15
  }
16
 
17
  try {
18
- await Database.getInstance()
19
- .getClient()
20
- .withSession((session) =>
21
- session.withTransaction(async () => {
22
- await Database.getInstance()
23
- .getCollections()
24
- .assistants.aggregate([
25
- { $project: { _id: 1 } },
26
- { $set: { last24HoursCount: 0 } },
27
- {
28
- $unionWith: {
29
- coll: "assistants.stats",
30
- pipeline: [
31
- {
32
- $match: { "date.at": { $gte: subDays(new Date(), 1) }, "date.span": "hour" },
33
  },
34
- {
35
- $group: {
36
- _id: "$assistantId",
37
- last24HoursCount: { $sum: "$count" },
38
- },
39
- },
40
- ],
41
- },
42
  },
43
- {
44
- $group: {
45
- _id: "$_id",
46
- last24HoursCount: { $sum: "$last24HoursCount" },
47
- },
48
  },
49
- {
50
- $merge: {
51
- into: "assistants",
52
- on: "_id",
53
- whenMatched: "merge",
54
- whenNotMatched: "discard",
55
- },
56
  },
57
- ])
58
- .next();
59
- })
60
- );
 
61
  } catch (e) {
62
- logger.error("Refresh assistants counter failed!");
63
- logger.error(e);
64
  }
65
  }
66
 
 
1
+ import { client, collections } from "$lib/server/database";
2
  import { acquireLock, refreshLock } from "$lib/migrations/lock";
3
  import type { ObjectId } from "mongodb";
4
  import { subDays } from "date-fns";
 
5
 
6
  const LOCK_KEY = "assistants.count";
7
 
 
14
  }
15
 
16
  try {
17
+ await client.withSession((session) =>
18
+ session.withTransaction(async () => {
19
+ await collections.assistants
20
+ .aggregate([
21
+ { $project: { _id: 1 } },
22
+ { $set: { last24HoursCount: 0 } },
23
+ {
24
+ $unionWith: {
25
+ coll: "assistants.stats",
26
+ pipeline: [
27
+ { $match: { "date.at": { $gte: subDays(new Date(), 1) }, "date.span": "hour" } },
28
+ {
29
+ $group: {
30
+ _id: "$assistantId",
31
+ last24HoursCount: { $sum: "$count" },
32
  },
33
+ },
34
+ ],
 
 
 
 
 
 
35
  },
36
+ },
37
+ {
38
+ $group: {
39
+ _id: "$_id",
40
+ last24HoursCount: { $sum: "$last24HoursCount" },
41
  },
42
+ },
43
+ {
44
+ $merge: {
45
+ into: "assistants",
46
+ on: "_id",
47
+ whenMatched: "merge",
48
+ whenNotMatched: "discard",
49
  },
50
+ },
51
+ ])
52
+ .next();
53
+ })
54
+ );
55
  } catch (e) {
56
+ console.log("Refresh assistants counter failed!");
57
+ console.error(e);
58
  }
59
  }
60
 
src/lib/components/AnnouncementBanner.svelte CHANGED
@@ -5,7 +5,7 @@
5
 
6
  <div class="flex items-center rounded-xl bg-gray-100 p-1 text-sm dark:bg-gray-800 {classNames}">
7
  <span
8
- class="from-primary-300 text-primary-700 dark:from-primary-900 dark:text-primary-400 mr-2 inline-flex items-center rounded-lg bg-gradient-to-br px-2 py-1 text-xxs font-medium uppercase leading-3"
9
  >New</span
10
  >
11
  {title}
 
5
 
6
  <div class="flex items-center rounded-xl bg-gray-100 p-1 text-sm dark:bg-gray-800 {classNames}">
7
  <span
8
+ class="mr-2 inline-flex items-center rounded-lg bg-gradient-to-br from-primary-300 px-2 py-1 text-xxs font-medium uppercase leading-3 text-primary-700 dark:from-primary-900 dark:text-primary-400"
9
  >New</span
10
  >
11
  {title}
src/lib/components/CopyToClipBoardBtn.svelte CHANGED
@@ -43,7 +43,7 @@
43
  >
44
  <div class="relative">
45
  <slot>
46
- <IconCopy classNames="dark:text-gray-700 text-gray-200" />
47
  </slot>
48
 
49
  <Tooltip classNames={isSuccess ? "opacity-100" : "opacity-0"} />
 
43
  >
44
  <div class="relative">
45
  <slot>
46
+ <IconCopy />
47
  </slot>
48
 
49
  <Tooltip classNames={isSuccess ? "opacity-100" : "opacity-0"} />
src/lib/components/DisclaimerModal.svelte CHANGED
@@ -1,7 +1,11 @@
1
  <script lang="ts">
2
  import { base } from "$app/paths";
3
  import { page } from "$app/stores";
4
- import { env as envPublic } from "$env/dynamic/public";
 
 
 
 
5
  import LogoHuggingFaceBorderless from "$lib/components/icons/LogoHuggingFaceBorderless.svelte";
6
  import Modal from "$lib/components/Modal.svelte";
7
  import { useSettingsStore } from "$lib/stores/settings";
@@ -13,19 +17,19 @@
13
 
14
  <Modal>
15
  <div
16
- class="from-primary-500/40 via-primary-500/10 to-primary-500/0 flex w-full flex-col items-center gap-6 bg-gradient-to-b px-5 pb-8 pt-9 text-center sm:px-6"
17
  >
18
  <h2 class="flex items-center text-2xl font-semibold text-gray-800">
19
  <Logo classNames="mr-1" />
20
- {envPublic.PUBLIC_APP_NAME}
21
  </h2>
22
 
23
  <p class="text-lg font-semibold leading-snug text-gray-800" style="text-wrap: balance;">
24
- {envPublic.PUBLIC_APP_DESCRIPTION}
25
  </p>
26
 
27
  <p class="text-sm text-gray-500">
28
- {envPublic.PUBLIC_APP_DISCLAIMER_MESSAGE}
29
  </p>
30
 
31
  <div class="flex w-full flex-col items-center gap-2">
@@ -57,7 +61,7 @@
57
  class="flex w-full items-center justify-center whitespace-nowrap rounded-full border-2 border-black bg-black px-5 py-2 text-lg font-semibold text-gray-100 transition-colors hover:bg-gray-900"
58
  >
59
  Sign in
60
- {#if envPublic.PUBLIC_APP_NAME === "HuggingChat"}
61
  with <LogoHuggingFaceBorderless classNames="text-xl mr-1 ml-1.5 flex-none" /> Hugging Face
62
  {/if}
63
  </button>
 
1
  <script lang="ts">
2
  import { base } from "$app/paths";
3
  import { page } from "$app/stores";
4
+ import {
5
+ PUBLIC_APP_DESCRIPTION,
6
+ PUBLIC_APP_NAME,
7
+ PUBLIC_APP_DISCLAIMER_MESSAGE,
8
+ } from "$env/static/public";
9
  import LogoHuggingFaceBorderless from "$lib/components/icons/LogoHuggingFaceBorderless.svelte";
10
  import Modal from "$lib/components/Modal.svelte";
11
  import { useSettingsStore } from "$lib/stores/settings";
 
17
 
18
  <Modal>
19
  <div
20
+ class="flex w-full flex-col items-center gap-6 bg-gradient-to-b from-primary-500/40 via-primary-500/10 to-primary-500/0 px-5 pb-8 pt-9 text-center sm:px-6"
21
  >
22
  <h2 class="flex items-center text-2xl font-semibold text-gray-800">
23
  <Logo classNames="mr-1" />
24
+ {PUBLIC_APP_NAME}
25
  </h2>
26
 
27
  <p class="text-lg font-semibold leading-snug text-gray-800" style="text-wrap: balance;">
28
+ {PUBLIC_APP_DESCRIPTION}
29
  </p>
30
 
31
  <p class="text-sm text-gray-500">
32
+ {PUBLIC_APP_DISCLAIMER_MESSAGE}
33
  </p>
34
 
35
  <div class="flex w-full flex-col items-center gap-2">
 
61
  class="flex w-full items-center justify-center whitespace-nowrap rounded-full border-2 border-black bg-black px-5 py-2 text-lg font-semibold text-gray-100 transition-colors hover:bg-gray-900"
62
  >
63
  Sign in
64
+ {#if PUBLIC_APP_NAME === "HuggingChat"}
65
  with <LogoHuggingFaceBorderless classNames="text-xl mr-1 ml-1.5 flex-none" /> Hugging Face
66
  {/if}
67
  </button>
src/lib/components/LoginModal.svelte CHANGED
@@ -1,7 +1,7 @@
1
  <script lang="ts">
2
  import { base } from "$app/paths";
3
  import { page } from "$app/stores";
4
- import { env as envPublic } from "$env/dynamic/public";
5
  import LogoHuggingFaceBorderless from "$lib/components/icons/LogoHuggingFaceBorderless.svelte";
6
  import Modal from "$lib/components/Modal.svelte";
7
  import { useSettingsStore } from "$lib/stores/settings";
@@ -13,14 +13,14 @@
13
 
14
  <Modal on:close>
15
  <div
16
- class="from-primary-500/40 via-primary-500/10 to-primary-500/0 flex w-full flex-col items-center gap-6 bg-gradient-to-b px-5 pb-8 pt-9 text-center"
17
  >
18
  <h2 class="flex items-center text-2xl font-semibold text-gray-800">
19
  <Logo classNames="mr-1" />
20
- {envPublic.PUBLIC_APP_NAME}
21
  </h2>
22
  <p class="text-balance text-lg font-semibold leading-snug text-gray-800">
23
- {envPublic.PUBLIC_APP_DESCRIPTION}
24
  </p>
25
  <p class="text-balance rounded-xl border bg-white/80 p-2 text-base text-gray-800">
26
  You have reached the guest message limit, <strong class="font-semibold"
@@ -40,7 +40,7 @@
40
  class="flex w-full items-center justify-center whitespace-nowrap rounded-full bg-black px-5 py-2 text-center text-lg font-semibold text-gray-100 transition-colors hover:bg-gray-900"
41
  >
42
  Sign in
43
- {#if envPublic.PUBLIC_APP_NAME === "HuggingChat"}
44
  with <LogoHuggingFaceBorderless classNames="text-xl mr-1 ml-1.5" /> Hugging Face
45
  {/if}
46
  </button>
 
1
  <script lang="ts">
2
  import { base } from "$app/paths";
3
  import { page } from "$app/stores";
4
+ import { PUBLIC_APP_DESCRIPTION, PUBLIC_APP_NAME } from "$env/static/public";
5
  import LogoHuggingFaceBorderless from "$lib/components/icons/LogoHuggingFaceBorderless.svelte";
6
  import Modal from "$lib/components/Modal.svelte";
7
  import { useSettingsStore } from "$lib/stores/settings";
 
13
 
14
  <Modal on:close>
15
  <div
16
+ class="flex w-full flex-col items-center gap-6 bg-gradient-to-b from-primary-500/40 via-primary-500/10 to-primary-500/0 px-5 pb-8 pt-9 text-center"
17
  >
18
  <h2 class="flex items-center text-2xl font-semibold text-gray-800">
19
  <Logo classNames="mr-1" />
20
+ {PUBLIC_APP_NAME}
21
  </h2>
22
  <p class="text-balance text-lg font-semibold leading-snug text-gray-800">
23
+ {PUBLIC_APP_DESCRIPTION}
24
  </p>
25
  <p class="text-balance rounded-xl border bg-white/80 p-2 text-base text-gray-800">
26
  You have reached the guest message limit, <strong class="font-semibold"
 
40
  class="flex w-full items-center justify-center whitespace-nowrap rounded-full bg-black px-5 py-2 text-center text-lg font-semibold text-gray-100 transition-colors hover:bg-gray-900"
41
  >
42
  Sign in
43
+ {#if PUBLIC_APP_NAME === "HuggingChat"}
44
  with <LogoHuggingFaceBorderless classNames="text-xl mr-1 ml-1.5" /> Hugging Face
45
  {/if}
46
  </button>
src/lib/components/ModelCardMetadata.svelte CHANGED
@@ -1,7 +1,6 @@
1
  <script lang="ts">
2
  import CarbonEarth from "~icons/carbon/earth";
3
  import CarbonArrowUpRight from "~icons/carbon/arrow-up-right";
4
- import BIMeta from "~icons/bi/meta";
5
  import type { Model } from "$lib/types/Model";
6
 
7
  export let model: Pick<Model, "name" | "datasetName" | "websiteUrl" | "modelUrl" | "datasetUrl">;
@@ -42,13 +41,8 @@
42
  class="ml-auto flex items-center hover:underline"
43
  rel="noreferrer"
44
  >
45
- {#if model.name === "meta-llama/Meta-Llama-3-70B-Instruct"}
46
- <BIMeta class="mr-1.5 shrink-0 text-xs text-gray-400" />
47
- Built with Meta Llama 3
48
- {:else}
49
- <CarbonEarth class="mr-1.5 shrink-0 text-xs text-gray-400" />
50
- Website
51
- {/if}
52
  </a>
53
  {/if}
54
  </div>
 
1
  <script lang="ts">
2
  import CarbonEarth from "~icons/carbon/earth";
3
  import CarbonArrowUpRight from "~icons/carbon/arrow-up-right";
 
4
  import type { Model } from "$lib/types/Model";
5
 
6
  export let model: Pick<Model, "name" | "datasetName" | "websiteUrl" | "modelUrl" | "datasetUrl">;
 
41
  class="ml-auto flex items-center hover:underline"
42
  rel="noreferrer"
43
  >
44
+ <CarbonEarth class="mr-1.5 shrink-0 text-xs text-gray-400" />
45
+ Website
 
 
 
 
 
46
  </a>
47
  {/if}
48
  </div>
src/lib/components/NavMenu.svelte CHANGED
@@ -4,7 +4,7 @@
4
  import Logo from "$lib/components/icons/Logo.svelte";
5
  import { switchTheme } from "$lib/switchTheme";
6
  import { isAborted } from "$lib/stores/isAborted";
7
- import { env as envPublic } from "$env/dynamic/public";
8
  import NavConversationItem from "./NavConversationItem.svelte";
9
  import type { LayoutData } from "../../routes/$types";
10
  import type { ConvSidebar } from "$lib/types/ConvSidebar";
@@ -47,12 +47,9 @@
47
  </script>
48
 
49
  <div class="sticky top-0 flex flex-none items-center justify-between px-3 py-3.5 max-sm:pt-0">
50
- <a
51
- class="flex items-center rounded-xl text-lg font-semibold"
52
- href="{envPublic.PUBLIC_ORIGIN}{base}/"
53
- >
54
  <Logo classNames="mr-1" />
55
- {envPublic.PUBLIC_APP_NAME}
56
  </a>
57
  <a
58
  href={`${base}/`}
@@ -145,7 +142,7 @@
145
  >
146
  Settings
147
  </a>
148
- {#if envPublic.PUBLIC_APP_NAME === "HuggingChat"}
149
  <a
150
  href="{base}/privacy"
151
  class="flex h-9 flex-none items-center gap-1.5 rounded-lg pl-2.5 pr-2 text-gray-500 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700"
 
4
  import Logo from "$lib/components/icons/Logo.svelte";
5
  import { switchTheme } from "$lib/switchTheme";
6
  import { isAborted } from "$lib/stores/isAborted";
7
+ import { PUBLIC_APP_NAME, PUBLIC_ORIGIN } from "$env/static/public";
8
  import NavConversationItem from "./NavConversationItem.svelte";
9
  import type { LayoutData } from "../../routes/$types";
10
  import type { ConvSidebar } from "$lib/types/ConvSidebar";
 
47
  </script>
48
 
49
  <div class="sticky top-0 flex flex-none items-center justify-between px-3 py-3.5 max-sm:pt-0">
50
+ <a class="flex items-center rounded-xl text-lg font-semibold" href="{PUBLIC_ORIGIN}{base}/">
 
 
 
51
  <Logo classNames="mr-1" />
52
+ {PUBLIC_APP_NAME}
53
  </a>
54
  <a
55
  href={`${base}/`}
 
142
  >
143
  Settings
144
  </a>
145
+ {#if PUBLIC_APP_NAME === "HuggingChat"}
146
  <a
147
  href="{base}/privacy"
148
  class="flex h-9 flex-none items-center gap-1.5 rounded-lg pl-2.5 pr-2 text-gray-500 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700"
src/lib/components/chat/AssistantIntroduction.svelte CHANGED
@@ -10,7 +10,7 @@
10
  import CarbonUserMultiple from "~icons/carbon/user-multiple";
11
 
12
  import { share } from "$lib/utils/share";
13
- import { env as envPublic } from "$env/dynamic/public";
14
  import { page } from "$app/stores";
15
 
16
  export let assistant: Pick<
@@ -35,8 +35,7 @@
35
  (assistant?.rag?.allowedLinks?.length ?? 0) > 0 ||
36
  assistant?.dynamicPrompt;
37
 
38
- const prefix =
39
- envPublic.PUBLIC_SHARE_PREFIX || `${envPublic.PUBLIC_ORIGIN || $page.url.origin}${base}`;
40
 
41
  $: shareUrl = `${prefix}/assistant/${assistant?._id}`;
42
 
 
10
  import CarbonUserMultiple from "~icons/carbon/user-multiple";
11
 
12
  import { share } from "$lib/utils/share";
13
+ import { PUBLIC_ORIGIN, PUBLIC_SHARE_PREFIX } from "$env/static/public";
14
  import { page } from "$app/stores";
15
 
16
  export let assistant: Pick<
 
35
  (assistant?.rag?.allowedLinks?.length ?? 0) > 0 ||
36
  assistant?.dynamicPrompt;
37
 
38
+ const prefix = PUBLIC_SHARE_PREFIX || `${PUBLIC_ORIGIN || $page.url.origin}${base}`;
 
39
 
40
  $: shareUrl = `${prefix}/assistant/${assistant?._id}`;
41
 
src/lib/components/chat/ChatIntroduction.svelte CHANGED
@@ -1,5 +1,7 @@
1
  <script lang="ts">
2
- import { env as envPublic } from "$env/dynamic/public";
 
 
3
  import Logo from "$lib/components/icons/Logo.svelte";
4
  import { createEventDispatcher } from "svelte";
5
  import IconGear from "~icons/bi/gear-fill";
@@ -18,8 +20,8 @@
18
 
19
  $: currentModelMetadata = findCurrentModel(models, $settings.activeModel);
20
 
21
- const announcementBanners = envPublic.PUBLIC_ANNOUNCEMENT_BANNERS
22
- ? JSON5.parse(envPublic.PUBLIC_ANNOUNCEMENT_BANNERS)
23
  : [];
24
 
25
  const dispatch = createEventDispatcher<{ message: string }>();
@@ -30,15 +32,15 @@
30
  <div>
31
  <div class="mb-3 flex items-center text-2xl font-semibold">
32
  <Logo classNames="mr-1 flex-none" />
33
- {envPublic.PUBLIC_APP_NAME}
34
  <div
35
  class="ml-3 flex h-6 items-center rounded-lg border border-gray-100 bg-gray-50 px-2 text-base text-gray-400 dark:border-gray-700/60 dark:bg-gray-800"
36
  >
37
- v{envPublic.PUBLIC_VERSION}
38
  </div>
39
  </div>
40
  <p class="text-base text-gray-600 dark:text-gray-400">
41
- {envPublic.PUBLIC_APP_DESCRIPTION ||
42
  "Making the community's best AI chat models available to everyone."}
43
  </p>
44
  </div>
 
1
  <script lang="ts">
2
+ import { PUBLIC_APP_NAME, PUBLIC_VERSION } from "$env/static/public";
3
+ import { PUBLIC_ANNOUNCEMENT_BANNERS } from "$env/static/public";
4
+ import { PUBLIC_APP_DESCRIPTION } from "$env/static/public";
5
  import Logo from "$lib/components/icons/Logo.svelte";
6
  import { createEventDispatcher } from "svelte";
7
  import IconGear from "~icons/bi/gear-fill";
 
20
 
21
  $: currentModelMetadata = findCurrentModel(models, $settings.activeModel);
22
 
23
+ const announcementBanners = PUBLIC_ANNOUNCEMENT_BANNERS
24
+ ? JSON5.parse(PUBLIC_ANNOUNCEMENT_BANNERS)
25
  : [];
26
 
27
  const dispatch = createEventDispatcher<{ message: string }>();
 
32
  <div>
33
  <div class="mb-3 flex items-center text-2xl font-semibold">
34
  <Logo classNames="mr-1 flex-none" />
35
+ {PUBLIC_APP_NAME}
36
  <div
37
  class="ml-3 flex h-6 items-center rounded-lg border border-gray-100 bg-gray-50 px-2 text-base text-gray-400 dark:border-gray-700/60 dark:bg-gray-800"
38
  >
39
+ v{PUBLIC_VERSION}
40
  </div>
41
  </div>
42
  <p class="text-base text-gray-600 dark:text-gray-400">
43
+ {PUBLIC_APP_DESCRIPTION ||
44
  "Making the community's best AI chat models available to everyone."}
45
  </p>
46
  </div>
src/lib/components/chat/ChatMessage.svelte CHANGED
@@ -344,8 +344,7 @@
344
  }}
345
  >
346
  <textarea
347
- class="w-full whitespace-break-spaces break-words rounded-xl bg-gray-100 px-5 py-3.5 text-gray-500 *:h-max dark:bg-gray-800 dark:text-gray-400"
348
- rows="5"
349
  bind:this={editContentEl}
350
  value={message.content.trim()}
351
  on:keydown={handleKeyDown}
 
344
  }}
345
  >
346
  <textarea
347
+ class="w-full whitespace-break-spaces break-words rounded-lg bg-gray-100 px-5 py-3.5 text-gray-500 *:h-max dark:bg-gray-800 dark:text-gray-400"
 
348
  bind:this={editContentEl}
349
  value={message.content.trim()}
350
  on:keydown={handleKeyDown}
src/lib/components/chat/ChatWindow.svelte CHANGED
@@ -395,7 +395,7 @@
395
  <CarbonCheckmark class="text-[.6rem] sm:mr-1.5 sm:text-green-600" />
396
  <div class="text-green-600 max-sm:hidden">Link copied to clipboard</div>
397
  {:else}
398
- <CarbonExport class="sm:text-primary-500 text-[.6rem] sm:mr-1.5" />
399
  <div class="max-sm:hidden">Share this conversation</div>
400
  {/if}
401
  </button>
 
395
  <CarbonCheckmark class="text-[.6rem] sm:mr-1.5 sm:text-green-600" />
396
  <div class="text-green-600 max-sm:hidden">Link copied to clipboard</div>
397
  {:else}
398
+ <CarbonExport class="text-[.6rem] sm:mr-1.5 sm:text-primary-500" />
399
  <div class="max-sm:hidden">Share this conversation</div>
400
  {/if}
401
  </button>
src/lib/components/icons/Logo.svelte CHANGED
@@ -1,12 +1,12 @@
1
  <script lang="ts">
2
  import { page } from "$app/stores";
3
- import { env as envPublic } from "$env/dynamic/public";
4
  import { base } from "$app/paths";
5
 
6
  export let classNames = "";
7
  </script>
8
 
9
- {#if envPublic.PUBLIC_APP_ASSETS === "chatui"}
10
  <svg
11
  height="30"
12
  width="30"
@@ -22,7 +22,7 @@
22
  {:else}
23
  <img
24
  class={classNames}
25
- alt="{envPublic.PUBLIC_APP_NAME} logo"
26
- src="{envPublic.PUBLIC_ORIGIN || $page.url.origin}{base}/{envPublic.PUBLIC_APP_ASSETS}/logo.svg"
27
  />
28
  {/if}
 
1
  <script lang="ts">
2
  import { page } from "$app/stores";
3
+ import { PUBLIC_APP_ASSETS, PUBLIC_APP_NAME, PUBLIC_ORIGIN } from "$env/static/public";
4
  import { base } from "$app/paths";
5
 
6
  export let classNames = "";
7
  </script>
8
 
9
+ {#if PUBLIC_APP_ASSETS === "chatui"}
10
  <svg
11
  height="30"
12
  width="30"
 
22
  {:else}
23
  <img
24
  class={classNames}
25
+ alt="{PUBLIC_APP_NAME} logo"
26
+ src="{PUBLIC_ORIGIN || $page.url.origin}{base}/{PUBLIC_APP_ASSETS}/logo.svg"
27
  />
28
  {/if}
src/lib/migrations/migrations.ts CHANGED
@@ -1,8 +1,7 @@
1
- import { Database } from "$lib/server/database";
2
  import { migrations } from "./routines";
3
  import { acquireLock, releaseLock, isDBLocked, refreshLock } from "./lock";
4
  import { isHuggingChat } from "$lib/utils/isHuggingChat";
5
- import { logger } from "$lib/server/logger";
6
 
7
  const LOCK_KEY = "migrations";
8
 
@@ -13,21 +12,18 @@ export async function checkAndRunMigrations() {
13
  }
14
 
15
  // check if all migrations have already been run
16
- const migrationResults = await Database.getInstance()
17
- .getCollections()
18
- .migrationResults.find()
19
- .toArray();
20
 
21
- logger.info("[MIGRATIONS] Begin check...");
22
 
23
  // connect to the database
24
- const connectedClient = await Database.getInstance().getClient().connect();
25
 
26
  const lockId = await acquireLock(LOCK_KEY);
27
 
28
  if (!lockId) {
29
  // another instance already has the lock, so we exit early
30
- logger.info(
31
  "[MIGRATIONS] Another instance already has the lock. Waiting for DB to be unlocked."
32
  );
33
 
@@ -54,69 +50,65 @@ export async function checkAndRunMigrations() {
54
 
55
  // check if the migration has already been applied
56
  if (!shouldRun) {
57
- logger.info(`[MIGRATIONS] "${migration.name}" already applied. Skipping...`);
58
  } else {
59
  // check the modifiers to see if some cases match
60
  if (
61
  (migration.runForHuggingChat === "only" && !isHuggingChat) ||
62
  (migration.runForHuggingChat === "never" && isHuggingChat)
63
  ) {
64
- logger.info(
65
  `[MIGRATIONS] "${migration.name}" should not be applied for this run. Skipping...`
66
  );
67
  continue;
68
  }
69
 
70
  // otherwise all is good and we can run the migration
71
- logger.info(
72
  `[MIGRATIONS] "${migration.name}" ${
73
  migration.runEveryTime ? "should run every time" : "not applied yet"
74
  }. Applying...`
75
  );
76
 
77
- await Database.getInstance()
78
- .getCollections()
79
- .migrationResults.updateOne(
80
- { _id: migration._id },
81
- {
82
- $set: {
83
- name: migration.name,
84
- status: "ongoing",
85
- },
86
  },
87
- { upsert: true }
88
- );
 
89
 
90
  const session = connectedClient.startSession();
91
  let result = false;
92
 
93
  try {
94
  await session.withTransaction(async () => {
95
- result = await migration.up(Database.getInstance());
96
  });
97
  } catch (e) {
98
- logger.info(`[MIGRATIONS] "${migration.name}" failed!`);
99
- logger.error(e);
100
  } finally {
101
  await session.endSession();
102
  }
103
 
104
- await Database.getInstance()
105
- .getCollections()
106
- .migrationResults.updateOne(
107
- { _id: migration._id },
108
- {
109
- $set: {
110
- name: migration.name,
111
- status: result ? "success" : "failure",
112
- },
113
  },
114
- { upsert: true }
115
- );
 
116
  }
117
  }
118
 
119
- logger.info("[MIGRATIONS] All migrations applied. Releasing lock");
120
 
121
  clearInterval(refreshInterval);
122
  await releaseLock(LOCK_KEY, lockId);
 
1
+ import { client, collections } from "$lib/server/database";
2
  import { migrations } from "./routines";
3
  import { acquireLock, releaseLock, isDBLocked, refreshLock } from "./lock";
4
  import { isHuggingChat } from "$lib/utils/isHuggingChat";
 
5
 
6
  const LOCK_KEY = "migrations";
7
 
 
12
  }
13
 
14
  // check if all migrations have already been run
15
+ const migrationResults = await collections.migrationResults.find().toArray();
 
 
 
16
 
17
+ console.log("[MIGRATIONS] Begin check...");
18
 
19
  // connect to the database
20
+ const connectedClient = await client.connect();
21
 
22
  const lockId = await acquireLock(LOCK_KEY);
23
 
24
  if (!lockId) {
25
  // another instance already has the lock, so we exit early
26
+ console.log(
27
  "[MIGRATIONS] Another instance already has the lock. Waiting for DB to be unlocked."
28
  );
29
 
 
50
 
51
  // check if the migration has already been applied
52
  if (!shouldRun) {
53
+ console.log(`[MIGRATIONS] "${migration.name}" already applied. Skipping...`);
54
  } else {
55
  // check the modifiers to see if some cases match
56
  if (
57
  (migration.runForHuggingChat === "only" && !isHuggingChat) ||
58
  (migration.runForHuggingChat === "never" && isHuggingChat)
59
  ) {
60
+ console.log(
61
  `[MIGRATIONS] "${migration.name}" should not be applied for this run. Skipping...`
62
  );
63
  continue;
64
  }
65
 
66
  // otherwise all is good and we can run the migration
67
+ console.log(
68
  `[MIGRATIONS] "${migration.name}" ${
69
  migration.runEveryTime ? "should run every time" : "not applied yet"
70
  }. Applying...`
71
  );
72
 
73
+ await collections.migrationResults.updateOne(
74
+ { _id: migration._id },
75
+ {
76
+ $set: {
77
+ name: migration.name,
78
+ status: "ongoing",
 
 
 
79
  },
80
+ },
81
+ { upsert: true }
82
+ );
83
 
84
  const session = connectedClient.startSession();
85
  let result = false;
86
 
87
  try {
88
  await session.withTransaction(async () => {
89
+ result = await migration.up(connectedClient);
90
  });
91
  } catch (e) {
92
+ console.log(`[MIGRATION[] "${migration.name}" failed!`);
93
+ console.error(e);
94
  } finally {
95
  await session.endSession();
96
  }
97
 
98
+ await collections.migrationResults.updateOne(
99
+ { _id: migration._id },
100
+ {
101
+ $set: {
102
+ name: migration.name,
103
+ status: result ? "success" : "failure",
 
 
 
104
  },
105
+ },
106
+ { upsert: true }
107
+ );
108
  }
109
  }
110
 
111
+ console.log("[MIGRATIONS] All migrations applied. Releasing lock");
112
 
113
  clearInterval(refreshInterval);
114
  await releaseLock(LOCK_KEY, lockId);
src/lib/migrations/routines/01-update-search-assistants.ts CHANGED
@@ -1,5 +1,5 @@
1
  import type { Migration } from ".";
2
- import { collections } from "$lib/server/database";
3
  import { ObjectId, type AnyBulkWriteOperation } from "mongodb";
4
  import type { Assistant } from "$lib/types/Assistant";
5
  import { generateSearchTokens } from "$lib/utils/searchTokens";
@@ -7,8 +7,8 @@ import { generateSearchTokens } from "$lib/utils/searchTokens";
7
  const migration: Migration = {
8
  _id: new ObjectId("5f9f3e3e3e3e3e3e3e3e3e3e"),
9
  name: "Update search assistants",
10
- up: async () => {
11
- const { assistants } = collections;
12
  let ops: AnyBulkWriteOperation<Assistant>[] = [];
13
 
14
  for await (const assistant of assistants
@@ -40,8 +40,8 @@ const migration: Migration = {
40
 
41
  return true;
42
  },
43
- down: async () => {
44
- const { assistants } = collections;
45
  await assistants.updateMany({}, { $unset: { searchTokens: "" } });
46
  return true;
47
  },
 
1
  import type { Migration } from ".";
2
+ import { getCollections } from "$lib/server/database";
3
  import { ObjectId, type AnyBulkWriteOperation } from "mongodb";
4
  import type { Assistant } from "$lib/types/Assistant";
5
  import { generateSearchTokens } from "$lib/utils/searchTokens";
 
7
  const migration: Migration = {
8
  _id: new ObjectId("5f9f3e3e3e3e3e3e3e3e3e3e"),
9
  name: "Update search assistants",
10
+ up: async (client) => {
11
+ const { assistants } = getCollections(client);
12
  let ops: AnyBulkWriteOperation<Assistant>[] = [];
13
 
14
  for await (const assistant of assistants
 
40
 
41
  return true;
42
  },
43
+ down: async (client) => {
44
+ const { assistants } = getCollections(client);
45
  await assistants.updateMany({}, { $unset: { searchTokens: "" } });
46
  return true;
47
  },
src/lib/migrations/routines/02-update-assistants-models.ts CHANGED
@@ -1,14 +1,14 @@
1
  import type { Migration } from ".";
2
- import { collections } from "$lib/server/database";
3
  import { ObjectId } from "mongodb";
4
 
5
  const updateAssistantsModels: Migration = {
6
  _id: new ObjectId("5f9f3f3f3f3f3f3f3f3f3f3f"),
7
  name: "Update deprecated models in assistants with the default model",
8
- up: async () => {
9
  const models = (await import("$lib/server/models")).models;
10
 
11
- const { assistants } = collections;
12
 
13
  const modelIds = models.map((el) => el.id); // string[]
14
  const defaultModelId = models[0].id;
 
1
  import type { Migration } from ".";
2
+ import { getCollections } from "$lib/server/database";
3
  import { ObjectId } from "mongodb";
4
 
5
  const updateAssistantsModels: Migration = {
6
  _id: new ObjectId("5f9f3f3f3f3f3f3f3f3f3f3f"),
7
  name: "Update deprecated models in assistants with the default model",
8
+ up: async (client) => {
9
  const models = (await import("$lib/server/models")).models;
10
 
11
+ const { assistants } = getCollections(client);
12
 
13
  const modelIds = models.map((el) => el.id); // string[]
14
  const defaultModelId = models[0].id;
src/lib/migrations/routines/index.ts CHANGED
@@ -1,14 +1,13 @@
1
- import type { ObjectId } from "mongodb";
2
 
3
  import updateSearchAssistant from "./01-update-search-assistants";
4
  import updateAssistantsModels from "./02-update-assistants-models";
5
- import type { Database } from "$lib/server/database";
6
 
7
  export interface Migration {
8
  _id: ObjectId;
9
  name: string;
10
- up: (client: Database) => Promise<boolean>;
11
- down?: (client: Database) => Promise<boolean>;
12
  runForFreshInstall?: "only" | "never"; // leave unspecified to run for both
13
  runForHuggingChat?: "only" | "never"; // leave unspecified to run for both
14
  runEveryTime?: boolean;
 
1
+ import type { MongoClient, ObjectId } from "mongodb";
2
 
3
  import updateSearchAssistant from "./01-update-search-assistants";
4
  import updateAssistantsModels from "./02-update-assistants-models";
 
5
 
6
  export interface Migration {
7
  _id: ObjectId;
8
  name: string;
9
+ up: (client: MongoClient) => Promise<boolean>;
10
+ down?: (client: MongoClient) => Promise<boolean>;
11
  runForFreshInstall?: "only" | "never"; // leave unspecified to run for both
12
  runForHuggingChat?: "only" | "never"; // leave unspecified to run for both
13
  runEveryTime?: boolean;
src/lib/server/abortedGenerations.ts CHANGED
@@ -1,42 +1,29 @@
1
  // Shouldn't be needed if we dove into sveltekit internals, see https://github.com/huggingface/chat-ui/pull/88#issuecomment-1523173850
2
 
3
- import { logger } from "$lib/server/logger";
4
- import { collections } from "$lib/server/database";
5
 
6
- export class AbortedGenerations {
7
- private static instance: AbortedGenerations;
 
 
8
 
9
- private abortedGenerations: Map<string, Date> = new Map();
10
 
11
- private constructor() {
12
- const interval = setInterval(this.updateList, 1000);
 
13
 
14
- process.on("SIGINT", () => {
15
- clearInterval(interval);
16
- });
17
- }
18
-
19
- public static getInstance(): AbortedGenerations {
20
- if (!AbortedGenerations.instance) {
21
- AbortedGenerations.instance = new AbortedGenerations();
22
- }
23
-
24
- return AbortedGenerations.instance;
25
- }
26
-
27
- public getList(): Map<string, Date> {
28
- return this.abortedGenerations;
29
- }
30
-
31
- private async updateList() {
32
  try {
33
  const aborts = await collections.abortedGenerations.find({}).sort({ createdAt: 1 }).toArray();
34
 
35
- this.abortedGenerations = new Map(
36
  aborts.map(({ conversationId, createdAt }) => [conversationId.toString(), createdAt])
37
  );
38
  } catch (err) {
39
- logger.error(err);
40
  }
41
  }
42
  }
 
 
 
1
  // Shouldn't be needed if we dove into sveltekit internals, see https://github.com/huggingface/chat-ui/pull/88#issuecomment-1523173850
2
 
3
+ import { setTimeout } from "node:timers/promises";
4
+ import { collections } from "./database";
5
 
6
+ let closed = false;
7
+ process.on("SIGINT", () => {
8
+ closed = true;
9
+ });
10
 
11
+ export let abortedGenerations: Map<string, Date> = new Map();
12
 
13
+ async function maintainAbortedGenerations() {
14
+ while (!closed) {
15
+ await setTimeout(1000);
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  try {
18
  const aborts = await collections.abortedGenerations.find({}).sort({ createdAt: 1 }).toArray();
19
 
20
+ abortedGenerations = new Map(
21
  aborts.map(({ conversationId, createdAt }) => [conversationId.toString(), createdAt])
22
  );
23
  } catch (err) {
24
+ console.error(err);
25
  }
26
  }
27
  }
28
+
29
+ maintainAbortedGenerations();
src/lib/server/auth.ts CHANGED
@@ -1,13 +1,22 @@
1
  import { Issuer, BaseClient, type UserinfoResponse, TokenSet, custom } from "openid-client";
2
  import { addHours, addWeeks } from "date-fns";
3
- import { env } from "$env/dynamic/private";
 
 
 
 
 
 
 
 
 
 
4
  import { sha256 } from "$lib/utils/sha256";
5
  import { z } from "zod";
6
  import { dev } from "$app/environment";
7
  import type { Cookies } from "@sveltejs/kit";
8
- import { collections } from "$lib/server/database";
9
  import JSON5 from "json5";
10
- import { logger } from "$lib/server/logger";
11
 
12
  export interface OIDCSettings {
13
  redirectURI: string;
@@ -26,27 +35,27 @@ const stringWithDefault = (value: string) =>
26
 
27
  export const OIDConfig = z
28
  .object({
29
- CLIENT_ID: stringWithDefault(env.OPENID_CLIENT_ID),
30
- CLIENT_SECRET: stringWithDefault(env.OPENID_CLIENT_SECRET),
31
- PROVIDER_URL: stringWithDefault(env.OPENID_PROVIDER_URL),
32
- SCOPES: stringWithDefault(env.OPENID_SCOPES),
33
- NAME_CLAIM: stringWithDefault(env.OPENID_NAME_CLAIM).refine(
34
  (el) => !["preferred_username", "email", "picture", "sub"].includes(el),
35
  { message: "nameClaim cannot be one of the restricted keys." }
36
  ),
37
- TOLERANCE: stringWithDefault(env.OPENID_TOLERANCE),
38
- RESOURCE: stringWithDefault(env.OPENID_RESOURCE),
39
  })
40
- .parse(JSON5.parse(env.OPENID_CONFIG));
41
 
42
  export const requiresUser = !!OIDConfig.CLIENT_ID && !!OIDConfig.CLIENT_SECRET;
43
 
44
  export function refreshSessionCookie(cookies: Cookies, sessionId: string) {
45
- cookies.set(env.COOKIE_NAME, sessionId, {
46
  path: "/",
47
  // So that it works inside the space's iframe
48
- sameSite: dev || env.ALLOW_INSECURE_COOKIES === "true" ? "lax" : "none",
49
- secure: !dev && !(env.ALLOW_INSECURE_COOKIES === "true"),
50
  httpOnly: true,
51
  expires: addWeeks(new Date(), 2),
52
  });
@@ -141,7 +150,7 @@ export async function validateAndParseCsrfToken(
141
  return { redirectUrl: data.redirectUrl };
142
  }
143
  } catch (e) {
144
- logger.error(e);
145
  }
146
  return null;
147
  }
 
1
  import { Issuer, BaseClient, type UserinfoResponse, TokenSet, custom } from "openid-client";
2
  import { addHours, addWeeks } from "date-fns";
3
+ import {
4
+ COOKIE_NAME,
5
+ OPENID_CLIENT_ID,
6
+ OPENID_CLIENT_SECRET,
7
+ OPENID_PROVIDER_URL,
8
+ OPENID_SCOPES,
9
+ OPENID_NAME_CLAIM,
10
+ OPENID_TOLERANCE,
11
+ OPENID_RESOURCE,
12
+ OPENID_CONFIG,
13
+ } from "$env/static/private";
14
  import { sha256 } from "$lib/utils/sha256";
15
  import { z } from "zod";
16
  import { dev } from "$app/environment";
17
  import type { Cookies } from "@sveltejs/kit";
18
+ import { collections } from "./database";
19
  import JSON5 from "json5";
 
20
 
21
  export interface OIDCSettings {
22
  redirectURI: string;
 
35
 
36
  export const OIDConfig = z
37
  .object({
38
+ CLIENT_ID: stringWithDefault(OPENID_CLIENT_ID),
39
+ CLIENT_SECRET: stringWithDefault(OPENID_CLIENT_SECRET),
40
+ PROVIDER_URL: stringWithDefault(OPENID_PROVIDER_URL),
41
+ SCOPES: stringWithDefault(OPENID_SCOPES),
42
+ NAME_CLAIM: stringWithDefault(OPENID_NAME_CLAIM).refine(
43
  (el) => !["preferred_username", "email", "picture", "sub"].includes(el),
44
  { message: "nameClaim cannot be one of the restricted keys." }
45
  ),
46
+ TOLERANCE: stringWithDefault(OPENID_TOLERANCE),
47
+ RESOURCE: stringWithDefault(OPENID_RESOURCE),
48
  })
49
+ .parse(JSON5.parse(OPENID_CONFIG));
50
 
51
  export const requiresUser = !!OIDConfig.CLIENT_ID && !!OIDConfig.CLIENT_SECRET;
52
 
53
  export function refreshSessionCookie(cookies: Cookies, sessionId: string) {
54
+ cookies.set(COOKIE_NAME, sessionId, {
55
  path: "/",
56
  // So that it works inside the space's iframe
57
+ sameSite: dev ? "lax" : "none",
58
+ secure: !dev,
59
  httpOnly: true,
60
  expires: addWeeks(new Date(), 2),
61
  });
 
150
  return { redirectUrl: data.redirectUrl };
151
  }
152
  } catch (e) {
153
+ console.error(e);
154
  }
155
  return null;
156
  }
src/lib/server/database.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { env } from "$env/dynamic/private";
2
  import { GridFSBucket, MongoClient } from "mongodb";
3
  import type { Conversation } from "$lib/types/Conversation";
4
  import type { SharedConversation } from "$lib/types/SharedConversation";
@@ -13,197 +13,149 @@ import type { ConversationStats } from "$lib/types/ConversationStats";
13
  import type { MigrationResult } from "$lib/types/MigrationResult";
14
  import type { Semaphore } from "$lib/types/Semaphore";
15
  import type { AssistantStats } from "$lib/types/AssistantStats";
16
- import { logger } from "$lib/server/logger";
17
- import { building } from "$app/environment";
18
 
 
 
 
 
 
19
  export const CONVERSATION_STATS_COLLECTION = "conversations.stats";
20
 
21
- export class Database {
22
- private client: MongoClient;
23
-
24
- private static instance: Database;
25
-
26
- private constructor() {
27
- if (!env.MONGODB_URL) {
28
- throw new Error(
29
- "Please specify the MONGODB_URL environment variable inside .env.local. Set it to mongodb://localhost:27017 if you are running MongoDB locally, or to a MongoDB Atlas free instance for example."
30
- );
31
- }
32
-
33
- this.client = new MongoClient(env.MONGODB_URL, {
34
- directConnection: env.MONGODB_DIRECT_CONNECTION === "true",
35
- });
36
-
37
- this.client.connect().catch((err) => {
38
- logger.error("Connection error", err);
39
- process.exit(1);
40
- });
41
- this.client.db(env.MONGODB_DB_NAME + (import.meta.env.MODE === "test" ? "-test" : ""));
42
- this.client.on("open", () => this.initDatabase());
43
-
44
- // Disconnect DB on process kill
45
- process.on("SIGINT", async () => {
46
- await this.client.close(true);
47
-
48
- // https://github.com/sveltejs/kit/issues/9540
49
- setTimeout(() => {
50
- process.exit(0);
51
- }, 100);
52
- });
53
- }
54
-
55
- public static getInstance(): Database {
56
- if (!Database.instance) {
57
- Database.instance = new Database();
58
- }
59
-
60
- return Database.instance;
61
- }
62
-
63
- /**
64
- * Return mongoClient
65
- */
66
- public getClient(): MongoClient {
67
- return this.client;
68
- }
69
-
70
- /**
71
- * Return map of database's collections
72
- */
73
- public getCollections() {
74
- const db = this.client.db(
75
- env.MONGODB_DB_NAME + (import.meta.env.MODE === "test" ? "-test" : "")
76
- );
77
-
78
- const conversations = db.collection<Conversation>("conversations");
79
- const conversationStats = db.collection<ConversationStats>(CONVERSATION_STATS_COLLECTION);
80
- const assistants = db.collection<Assistant>("assistants");
81
- const assistantStats = db.collection<AssistantStats>("assistants.stats");
82
- const reports = db.collection<Report>("reports");
83
- const sharedConversations = db.collection<SharedConversation>("sharedConversations");
84
- const abortedGenerations = db.collection<AbortedGeneration>("abortedGenerations");
85
- const settings = db.collection<Settings>("settings");
86
- const users = db.collection<User>("users");
87
- const sessions = db.collection<Session>("sessions");
88
- const messageEvents = db.collection<MessageEvent>("messageEvents");
89
- const bucket = new GridFSBucket(db, { bucketName: "files" });
90
- const migrationResults = db.collection<MigrationResult>("migrationResults");
91
- const semaphores = db.collection<Semaphore>("semaphores");
92
-
93
- return {
94
- conversations,
95
- conversationStats,
96
- assistants,
97
- assistantStats,
98
- reports,
99
- sharedConversations,
100
- abortedGenerations,
101
- settings,
102
- users,
103
- sessions,
104
- messageEvents,
105
- bucket,
106
- migrationResults,
107
- semaphores,
108
- };
109
- }
110
-
111
- /**
112
- * Init database once connected: Index creation
113
- * @private
114
- */
115
- private initDatabase() {
116
- const {
117
- conversations,
118
- conversationStats,
119
- assistants,
120
- assistantStats,
121
- reports,
122
- sharedConversations,
123
- abortedGenerations,
124
- settings,
125
- users,
126
- sessions,
127
- messageEvents,
128
- semaphores,
129
- } = this.getCollections();
130
-
131
- conversations
132
- .createIndex(
133
- { sessionId: 1, updatedAt: -1 },
134
- { partialFilterExpression: { sessionId: { $exists: true } } }
135
- )
136
- .catch(logger.error);
137
- conversations
138
- .createIndex(
139
- { userId: 1, updatedAt: -1 },
140
- { partialFilterExpression: { userId: { $exists: true } } }
141
- )
142
- .catch(logger.error);
143
- conversations
144
- .createIndex(
145
- { "message.id": 1, "message.ancestors": 1 },
146
- { partialFilterExpression: { userId: { $exists: true } } }
147
- )
148
- .catch(logger.error);
149
- // Not strictly necessary, could use _id, but more convenient. Also for stats
150
- // To do stats on conversation messages
151
- conversations.createIndex({ "messages.createdAt": 1 }, { sparse: true }).catch(logger.error);
152
- // Unique index for stats
153
- conversationStats
154
- .createIndex(
155
- {
156
- type: 1,
157
- "date.field": 1,
158
- "date.span": 1,
159
- "date.at": 1,
160
- distinct: 1,
161
- },
162
- { unique: true }
163
- )
164
- .catch(logger.error);
165
- // Allow easy check of last computed stat for given type/dateField
166
- conversationStats
167
- .createIndex({
168
  type: 1,
169
  "date.field": 1,
 
170
  "date.at": 1,
171
- })
172
- .catch(logger.error);
173
- abortedGenerations
174
- .createIndex({ updatedAt: 1 }, { expireAfterSeconds: 30 })
175
- .catch(logger.error);
176
- abortedGenerations.createIndex({ conversationId: 1 }, { unique: true }).catch(logger.error);
177
- sharedConversations.createIndex({ hash: 1 }, { unique: true }).catch(logger.error);
178
- settings.createIndex({ sessionId: 1 }, { unique: true, sparse: true }).catch(logger.error);
179
- settings.createIndex({ userId: 1 }, { unique: true, sparse: true }).catch(logger.error);
180
- settings.createIndex({ assistants: 1 }).catch(logger.error);
181
- users.createIndex({ hfUserId: 1 }, { unique: true }).catch(logger.error);
182
- users.createIndex({ sessionId: 1 }, { unique: true, sparse: true }).catch(logger.error);
183
- // No unicity because due to renames & outdated info from oauth provider, there may be the same username on different users
184
- users.createIndex({ username: 1 }).catch(logger.error);
185
- messageEvents.createIndex({ createdAt: 1 }, { expireAfterSeconds: 60 }).catch(logger.error);
186
- sessions.createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 }).catch(logger.error);
187
- sessions.createIndex({ sessionId: 1 }, { unique: true }).catch(logger.error);
188
- assistants.createIndex({ createdById: 1, userCount: -1 }).catch(logger.error);
189
- assistants.createIndex({ userCount: 1 }).catch(logger.error);
190
- assistants.createIndex({ featured: 1, userCount: -1 }).catch(logger.error);
191
- assistants.createIndex({ modelId: 1, userCount: -1 }).catch(logger.error);
192
- assistants.createIndex({ searchTokens: 1 }).catch(logger.error);
193
- assistants.createIndex({ last24HoursCount: 1 }).catch(logger.error);
194
- assistantStats
195
- // Order of keys is important for the queries
196
- .createIndex({ "date.span": 1, "date.at": 1, assistantId: 1 }, { unique: true })
197
- .catch(logger.error);
198
- reports.createIndex({ assistantId: 1 }).catch(logger.error);
199
- reports.createIndex({ createdBy: 1, assistantId: 1 }).catch(logger.error);
200
-
201
- // Unique index for semaphore and migration results
202
- semaphores.createIndex({ key: 1 }, { unique: true }).catch(logger.error);
203
- semaphores.createIndex({ createdAt: 1 }, { expireAfterSeconds: 60 }).catch(logger.error);
204
- }
205
- }
206
-
207
- export const collections = building
208
- ? ({} as unknown as ReturnType<typeof Database.prototype.getCollections>)
209
- : Database.getInstance().getCollections();
 
 
 
 
 
1
+ import { MONGODB_URL, MONGODB_DB_NAME, MONGODB_DIRECT_CONNECTION } from "$env/static/private";
2
  import { GridFSBucket, MongoClient } from "mongodb";
3
  import type { Conversation } from "$lib/types/Conversation";
4
  import type { SharedConversation } from "$lib/types/SharedConversation";
 
13
  import type { MigrationResult } from "$lib/types/MigrationResult";
14
  import type { Semaphore } from "$lib/types/Semaphore";
15
  import type { AssistantStats } from "$lib/types/AssistantStats";
 
 
16
 
17
+ if (!MONGODB_URL) {
18
+ throw new Error(
19
+ "Please specify the MONGODB_URL environment variable inside .env.local. Set it to mongodb://localhost:27017 if you are running MongoDB locally, or to a MongoDB Atlas free instance for example."
20
+ );
21
+ }
22
  export const CONVERSATION_STATS_COLLECTION = "conversations.stats";
23
 
24
+ const client = new MongoClient(MONGODB_URL, {
25
+ directConnection: MONGODB_DIRECT_CONNECTION === "true",
26
+ });
27
+
28
+ export const connectPromise = client.connect().catch(console.error);
29
+
30
+ export function getCollections(mongoClient: MongoClient) {
31
+ const db = mongoClient.db(MONGODB_DB_NAME + (import.meta.env.MODE === "test" ? "-test" : ""));
32
+
33
+ const conversations = db.collection<Conversation>("conversations");
34
+ const conversationStats = db.collection<ConversationStats>(CONVERSATION_STATS_COLLECTION);
35
+ const assistants = db.collection<Assistant>("assistants");
36
+ const assistantStats = db.collection<AssistantStats>("assistants.stats");
37
+ const reports = db.collection<Report>("reports");
38
+ const sharedConversations = db.collection<SharedConversation>("sharedConversations");
39
+ const abortedGenerations = db.collection<AbortedGeneration>("abortedGenerations");
40
+ const settings = db.collection<Settings>("settings");
41
+ const users = db.collection<User>("users");
42
+ const sessions = db.collection<Session>("sessions");
43
+ const messageEvents = db.collection<MessageEvent>("messageEvents");
44
+ const bucket = new GridFSBucket(db, { bucketName: "files" });
45
+ const migrationResults = db.collection<MigrationResult>("migrationResults");
46
+ const semaphores = db.collection<Semaphore>("semaphores");
47
+
48
+ return {
49
+ conversations,
50
+ conversationStats,
51
+ assistants,
52
+ assistantStats,
53
+ reports,
54
+ sharedConversations,
55
+ abortedGenerations,
56
+ settings,
57
+ users,
58
+ sessions,
59
+ messageEvents,
60
+ bucket,
61
+ migrationResults,
62
+ semaphores,
63
+ };
64
+ }
65
+ const db = client.db(MONGODB_DB_NAME + (import.meta.env.MODE === "test" ? "-test" : ""));
66
+
67
+ const collections = getCollections(client);
68
+
69
+ const {
70
+ conversations,
71
+ conversationStats,
72
+ assistants,
73
+ assistantStats,
74
+ reports,
75
+ sharedConversations,
76
+ abortedGenerations,
77
+ settings,
78
+ users,
79
+ sessions,
80
+ messageEvents,
81
+ semaphores,
82
+ } = collections;
83
+
84
+ export { client, db, collections };
85
+
86
+ client.on("open", () => {
87
+ conversations
88
+ .createIndex(
89
+ { sessionId: 1, updatedAt: -1 },
90
+ { partialFilterExpression: { sessionId: { $exists: true } } }
91
+ )
92
+ .catch(console.error);
93
+ conversations
94
+ .createIndex(
95
+ { userId: 1, updatedAt: -1 },
96
+ { partialFilterExpression: { userId: { $exists: true } } }
97
+ )
98
+ .catch(console.error);
99
+ conversations
100
+ .createIndex(
101
+ { "message.id": 1, "message.ancestors": 1 },
102
+ { partialFilterExpression: { userId: { $exists: true } } }
103
+ )
104
+ .catch(console.error);
105
+ // To do stats on conversations
106
+ conversations.createIndex({ updatedAt: 1 }).catch(console.error);
107
+ // Not strictly necessary, could use _id, but more convenient. Also for stats
108
+ conversations.createIndex({ createdAt: 1 }).catch(console.error);
109
+ // To do stats on conversation messages
110
+ conversations.createIndex({ "messages.createdAt": 1 }, { sparse: true }).catch(console.error);
111
+ // Unique index for stats
112
+ conversationStats
113
+ .createIndex(
114
+ {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  type: 1,
116
  "date.field": 1,
117
+ "date.span": 1,
118
  "date.at": 1,
119
+ distinct: 1,
120
+ },
121
+ { unique: true }
122
+ )
123
+ .catch(console.error);
124
+ // Allow easy check of last computed stat for given type/dateField
125
+ conversationStats
126
+ .createIndex({
127
+ type: 1,
128
+ "date.field": 1,
129
+ "date.at": 1,
130
+ })
131
+ .catch(console.error);
132
+ abortedGenerations.createIndex({ updatedAt: 1 }, { expireAfterSeconds: 30 }).catch(console.error);
133
+ abortedGenerations.createIndex({ conversationId: 1 }, { unique: true }).catch(console.error);
134
+ sharedConversations.createIndex({ hash: 1 }, { unique: true }).catch(console.error);
135
+ settings.createIndex({ sessionId: 1 }, { unique: true, sparse: true }).catch(console.error);
136
+ settings.createIndex({ userId: 1 }, { unique: true, sparse: true }).catch(console.error);
137
+ settings.createIndex({ assistants: 1 }).catch(console.error);
138
+ users.createIndex({ hfUserId: 1 }, { unique: true }).catch(console.error);
139
+ users.createIndex({ sessionId: 1 }, { unique: true, sparse: true }).catch(console.error);
140
+ // No unicity because due to renames & outdated info from oauth provider, there may be the same username on different users
141
+ users.createIndex({ username: 1 }).catch(console.error);
142
+ messageEvents.createIndex({ createdAt: 1 }, { expireAfterSeconds: 60 }).catch(console.error);
143
+ sessions.createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 }).catch(console.error);
144
+ sessions.createIndex({ sessionId: 1 }, { unique: true }).catch(console.error);
145
+ assistants.createIndex({ createdById: 1, userCount: -1 }).catch(console.error);
146
+ assistants.createIndex({ userCount: 1 }).catch(console.error);
147
+ assistants.createIndex({ featured: 1, userCount: -1 }).catch(console.error);
148
+ assistants.createIndex({ modelId: 1, userCount: -1 }).catch(console.error);
149
+ assistants.createIndex({ searchTokens: 1 }).catch(console.error);
150
+ assistants.createIndex({ last24HoursCount: 1 }).catch(console.error);
151
+ assistantStats
152
+ // Order of keys is important for the queries
153
+ .createIndex({ "date.span": 1, "date.at": 1, assistantId: 1 }, { unique: true })
154
+ .catch(console.error);
155
+ reports.createIndex({ assistantId: 1 }).catch(console.error);
156
+ reports.createIndex({ createdBy: 1, assistantId: 1 }).catch(console.error);
157
+
158
+ // Unique index for semaphore and migration results
159
+ semaphores.createIndex({ key: 1 }, { unique: true }).catch(console.error);
160
+ semaphores.createIndex({ createdAt: 1 }, { expireAfterSeconds: 60 }).catch(console.error);
161
+ });
src/lib/server/embeddingEndpoints/embeddingEndpoints.ts CHANGED
@@ -11,7 +11,6 @@ import {
11
  embeddingEndpointOpenAI,
12
  embeddingEndpointOpenAIParametersSchema,
13
  } from "./openai/embeddingEndpoints";
14
- import { embeddingEndpointHfApi, embeddingEndpointHfApiSchema } from "./hfApi/embeddingHfApi";
15
 
16
  // parameters passed when generating text
17
  interface EmbeddingEndpointParameters {
@@ -27,7 +26,6 @@ export const embeddingEndpointSchema = z.discriminatedUnion("type", [
27
  embeddingEndpointTeiParametersSchema,
28
  embeddingEndpointTransformersJSParametersSchema,
29
  embeddingEndpointOpenAIParametersSchema,
30
- embeddingEndpointHfApiSchema,
31
  ]);
32
 
33
  type EmbeddingEndpointTypeOptions = z.infer<typeof embeddingEndpointSchema>["type"];
@@ -44,7 +42,6 @@ export const embeddingEndpoints: {
44
  tei: embeddingEndpointTei,
45
  transformersjs: embeddingEndpointTransformersJS,
46
  openai: embeddingEndpointOpenAI,
47
- hfapi: embeddingEndpointHfApi,
48
  };
49
 
50
  export default embeddingEndpoints;
 
11
  embeddingEndpointOpenAI,
12
  embeddingEndpointOpenAIParametersSchema,
13
  } from "./openai/embeddingEndpoints";
 
14
 
15
  // parameters passed when generating text
16
  interface EmbeddingEndpointParameters {
 
26
  embeddingEndpointTeiParametersSchema,
27
  embeddingEndpointTransformersJSParametersSchema,
28
  embeddingEndpointOpenAIParametersSchema,
 
29
  ]);
30
 
31
  type EmbeddingEndpointTypeOptions = z.infer<typeof embeddingEndpointSchema>["type"];
 
42
  tei: embeddingEndpointTei,
43
  transformersjs: embeddingEndpointTransformersJS,
44
  openai: embeddingEndpointOpenAI,
 
45
  };
46
 
47
  export default embeddingEndpoints;
src/lib/server/embeddingEndpoints/hfApi/embeddingHfApi.ts DELETED
@@ -1,53 +0,0 @@
1
- import { z } from "zod";
2
- import type { EmbeddingEndpoint, Embedding } from "../embeddingEndpoints";
3
- import { chunk } from "$lib/utils/chunk";
4
- import { env } from "$env/dynamic/private";
5
- import { logger } from "$lib/server/logger";
6
-
7
- export const embeddingEndpointHfApiSchema = z.object({
8
- weight: z.number().int().positive().default(1),
9
- model: z.any(),
10
- type: z.literal("hfapi"),
11
- authorization: z
12
- .string()
13
- .optional()
14
- .transform((v) => (!v && env.HF_TOKEN ? "Bearer " + env.HF_TOKEN : v)), // if the header is not set but HF_TOKEN is, use it as the authorization header
15
- });
16
-
17
- export async function embeddingEndpointHfApi(
18
- input: z.input<typeof embeddingEndpointHfApiSchema>
19
- ): Promise<EmbeddingEndpoint> {
20
- const { model, authorization } = embeddingEndpointHfApiSchema.parse(input);
21
- const url = "https://api-inference.huggingface.co/models/" + model.id;
22
-
23
- return async ({ inputs }) => {
24
- const batchesInputs = chunk(inputs, 128);
25
-
26
- const batchesResults = await Promise.all(
27
- batchesInputs.map(async (batchInputs) => {
28
- const response = await fetch(`${url}`, {
29
- method: "POST",
30
- headers: {
31
- Accept: "application/json",
32
- "Content-Type": "application/json",
33
- ...(authorization ? { Authorization: authorization } : {}),
34
- },
35
- body: JSON.stringify({ inputs: batchInputs }),
36
- });
37
-
38
- if (!response.ok) {
39
- logger.error(await response.text());
40
- logger.error("Failed to get embeddings from Hugging Face API", response);
41
- return [];
42
- }
43
-
44
- const embeddings: Embedding[] = await response.json();
45
- return embeddings;
46
- })
47
- );
48
-
49
- const flatAllEmbeddings = batchesResults.flat();
50
-
51
- return flatAllEmbeddings;
52
- };
53
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/server/embeddingEndpoints/openai/embeddingEndpoints.ts CHANGED
@@ -1,14 +1,14 @@
1
  import { z } from "zod";
2
  import type { EmbeddingEndpoint, Embedding } from "../embeddingEndpoints";
3
  import { chunk } from "$lib/utils/chunk";
4
- import { env } from "$env/dynamic/private";
5
 
6
  export const embeddingEndpointOpenAIParametersSchema = z.object({
7
  weight: z.number().int().positive().default(1),
8
  model: z.any(),
9
  type: z.literal("openai"),
10
  url: z.string().url().default("https://api.openai.com/v1/embeddings"),
11
- apiKey: z.string().default(env.OPENAI_API_KEY),
12
  });
13
 
14
  export async function embeddingEndpointOpenAI(
 
1
  import { z } from "zod";
2
  import type { EmbeddingEndpoint, Embedding } from "../embeddingEndpoints";
3
  import { chunk } from "$lib/utils/chunk";
4
+ import { OPENAI_API_KEY } from "$env/static/private";
5
 
6
  export const embeddingEndpointOpenAIParametersSchema = z.object({
7
  weight: z.number().int().positive().default(1),
8
  model: z.any(),
9
  type: z.literal("openai"),
10
  url: z.string().url().default("https://api.openai.com/v1/embeddings"),
11
+ apiKey: z.string().default(OPENAI_API_KEY),
12
  });
13
 
14
  export async function embeddingEndpointOpenAI(
src/lib/server/embeddingEndpoints/tei/embeddingEndpoints.ts CHANGED
@@ -1,18 +1,13 @@
1
  import { z } from "zod";
2
  import type { EmbeddingEndpoint, Embedding } from "../embeddingEndpoints";
3
  import { chunk } from "$lib/utils/chunk";
4
- import { env } from "$env/dynamic/private";
5
- import { logger } from "$lib/server/logger";
6
 
7
  export const embeddingEndpointTeiParametersSchema = z.object({
8
  weight: z.number().int().positive().default(1),
9
  model: z.any(),
10
  type: z.literal("tei"),
11
  url: z.string().url(),
12
- authorization: z
13
- .string()
14
- .optional()
15
- .transform((v) => (!v && env.HF_TOKEN ? "Bearer " + env.HF_TOKEN : v)), // if the header is not set but HF_TOKEN is, use it as the authorization header
16
  });
17
 
18
  const getModelInfoByUrl = async (url: string, authorization?: string) => {
@@ -26,13 +21,8 @@ const getModelInfoByUrl = async (url: string, authorization?: string) => {
26
  },
27
  });
28
 
29
- try {
30
- const json = await response.json();
31
- return { max_client_batch_size: 32, max_batch_tokens: 16384, ...json };
32
- } catch {
33
- logger.debug("Could not get info from TEI embedding endpoint. Using defaults.");
34
- return { max_client_batch_size: 32, max_batch_tokens: 16384 };
35
- }
36
  };
37
 
38
  export async function embeddingEndpointTei(
 
1
  import { z } from "zod";
2
  import type { EmbeddingEndpoint, Embedding } from "../embeddingEndpoints";
3
  import { chunk } from "$lib/utils/chunk";
 
 
4
 
5
  export const embeddingEndpointTeiParametersSchema = z.object({
6
  weight: z.number().int().positive().default(1),
7
  model: z.any(),
8
  type: z.literal("tei"),
9
  url: z.string().url(),
10
+ authorization: z.string().optional(),
 
 
 
11
  });
12
 
13
  const getModelInfoByUrl = async (url: string, authorization?: string) => {
 
21
  },
22
  });
23
 
24
+ const json = await response.json();
25
+ return json;
 
 
 
 
 
26
  };
27
 
28
  export async function embeddingEndpointTei(
src/lib/server/embeddingEndpoints/transformersjs/embeddingEndpoints.ts CHANGED
@@ -18,10 +18,9 @@ class TransformersJSModelsSingleton {
18
 
19
  if (modelPipelineInstance) {
20
  const [, modelPipeline] = modelPipelineInstance;
21
- // dispose of the previous pipeline to clear memory
22
- await (await modelPipeline).dispose();
23
- this.instances = this.instances.filter(([name]) => name !== modelName);
24
  }
 
25
  const newModelPipeline = pipeline("feature-extraction", modelName);
26
  this.instances.push([modelName, newModelPipeline]);
27
 
 
18
 
19
  if (modelPipelineInstance) {
20
  const [, modelPipeline] = modelPipelineInstance;
21
+ return modelPipeline;
 
 
22
  }
23
+
24
  const newModelPipeline = pipeline("feature-extraction", modelName);
25
  this.instances.push([modelName, newModelPipeline]);
26
 
src/lib/server/embeddingModels.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { env } from "$env/dynamic/private";
2
 
3
  import { z } from "zod";
4
  import { sum } from "$lib/utils/sum";
@@ -29,7 +29,7 @@ const modelConfig = z.object({
29
 
30
  // Default embedding model for backward compatibility
31
  const rawEmbeddingModelJSON =
32
- env.TEXT_EMBEDDING_MODELS ||
33
  `[
34
  {
35
  "name": "Xenova/gte-small",
@@ -73,10 +73,6 @@ const addEndpoint = (m: Awaited<ReturnType<typeof processEmbeddingModel>>) => ({
73
  return embeddingEndpoints.transformersjs(args);
74
  case "openai":
75
  return embeddingEndpoints.openai(args);
76
- case "hfapi":
77
- return embeddingEndpoints.hfapi(args);
78
- default:
79
- throw new Error(`Unknown endpoint type: ${args}`);
80
  }
81
  }
82
 
 
1
+ import { TEXT_EMBEDDING_MODELS } from "$env/static/private";
2
 
3
  import { z } from "zod";
4
  import { sum } from "$lib/utils/sum";
 
29
 
30
  // Default embedding model for backward compatibility
31
  const rawEmbeddingModelJSON =
32
+ TEXT_EMBEDDING_MODELS ||
33
  `[
34
  {
35
  "name": "Xenova/gte-small",
 
73
  return embeddingEndpoints.transformersjs(args);
74
  case "openai":
75
  return embeddingEndpoints.openai(args);
 
 
 
 
76
  }
77
  }
78
 
src/lib/server/endpoints/anthropic/endpointAnthropic.ts CHANGED
@@ -1,5 +1,5 @@
1
  import { z } from "zod";
2
- import { env } from "$env/dynamic/private";
3
  import type { Endpoint } from "../endpoints";
4
  import type { TextGenerationStreamOutput } from "@huggingface/inference";
5
 
@@ -8,7 +8,7 @@ export const endpointAnthropicParametersSchema = z.object({
8
  model: z.any(),
9
  type: z.literal("anthropic"),
10
  baseURL: z.string().url().default("https://api.anthropic.com"),
11
- apiKey: z.string().default(env.ANTHROPIC_API_KEY ?? "sk-"),
12
  defaultHeaders: z.record(z.string()).optional(),
13
  defaultQuery: z.record(z.string()).optional(),
14
  });
 
1
  import { z } from "zod";
2
+ import { ANTHROPIC_API_KEY } from "$env/static/private";
3
  import type { Endpoint } from "../endpoints";
4
  import type { TextGenerationStreamOutput } from "@huggingface/inference";
5
 
 
8
  model: z.any(),
9
  type: z.literal("anthropic"),
10
  baseURL: z.string().url().default("https://api.anthropic.com"),
11
+ apiKey: z.string().default(ANTHROPIC_API_KEY ?? "sk-"),
12
  defaultHeaders: z.record(z.string()).optional(),
13
  defaultQuery: z.record(z.string()).optional(),
14
  });
src/lib/server/endpoints/cloudflare/endpointCloudflare.ts CHANGED
@@ -1,15 +1,14 @@
1
  import { z } from "zod";
2
  import type { Endpoint } from "../endpoints";
3
  import type { TextGenerationStreamOutput } from "@huggingface/inference";
4
- import { env } from "$env/dynamic/private";
5
- import { logger } from "$lib/server/logger";
6
 
7
  export const endpointCloudflareParametersSchema = z.object({
8
  weight: z.number().int().positive().default(1),
9
  model: z.any(),
10
  type: z.literal("cloudflare"),
11
- accountId: z.string().default(env.CLOUDFLARE_ACCOUNT_ID),
12
- apiToken: z.string().default(env.CLOUDFLARE_API_TOKEN),
13
  });
14
 
15
  export async function endpointCloudflare(
@@ -105,8 +104,8 @@ export async function endpointCloudflare(
105
  try {
106
  data = JSON.parse(jsonString);
107
  } catch (e) {
108
- logger.error("Failed to parse JSON", e);
109
- logger.error("Problematic JSON string:", jsonString);
110
  continue; // Skip this iteration and try the next chunk
111
  }
112
 
 
1
  import { z } from "zod";
2
  import type { Endpoint } from "../endpoints";
3
  import type { TextGenerationStreamOutput } from "@huggingface/inference";
4
+ import { CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_TOKEN } from "$env/static/private";
 
5
 
6
  export const endpointCloudflareParametersSchema = z.object({
7
  weight: z.number().int().positive().default(1),
8
  model: z.any(),
9
  type: z.literal("cloudflare"),
10
+ accountId: z.string().default(CLOUDFLARE_ACCOUNT_ID),
11
+ apiToken: z.string().default(CLOUDFLARE_API_TOKEN),
12
  });
13
 
14
  export async function endpointCloudflare(
 
104
  try {
105
  data = JSON.parse(jsonString);
106
  } catch (e) {
107
+ console.error("Failed to parse JSON", e);
108
+ console.error("Problematic JSON string:", jsonString);
109
  continue; // Skip this iteration and try the next chunk
110
  }
111
 
src/lib/server/endpoints/cohere/endpointCohere.ts CHANGED
@@ -1,5 +1,5 @@
1
  import { z } from "zod";
2
- import { env } from "$env/dynamic/private";
3
  import type { Endpoint } from "../endpoints";
4
  import type { TextGenerationStreamOutput } from "@huggingface/inference";
5
  import type { Cohere, CohereClient } from "cohere-ai";
@@ -9,7 +9,7 @@ export const endpointCohereParametersSchema = z.object({
9
  weight: z.number().int().positive().default(1),
10
  model: z.any(),
11
  type: z.literal("cohere"),
12
- apiKey: z.string().default(env.COHERE_API_TOKEN),
13
  raw: z.boolean().default(false),
14
  });
15
 
 
1
  import { z } from "zod";
2
+ import { COHERE_API_TOKEN } from "$env/static/private";
3
  import type { Endpoint } from "../endpoints";
4
  import type { TextGenerationStreamOutput } from "@huggingface/inference";
5
  import type { Cohere, CohereClient } from "cohere-ai";
 
9
  weight: z.number().int().positive().default(1),
10
  model: z.any(),
11
  type: z.literal("cohere"),
12
+ apiKey: z.string().default(COHERE_API_TOKEN),
13
  raw: z.boolean().default(false),
14
  });
15
 
src/lib/server/endpoints/google/endpointVertex.ts CHANGED
@@ -1,14 +1,8 @@
1
- import {
2
- VertexAI,
3
- HarmCategory,
4
- HarmBlockThreshold,
5
- type Content,
6
- type TextPart,
7
- } from "@google-cloud/vertexai";
8
  import type { Endpoint } from "../endpoints";
9
  import { z } from "zod";
10
- import type { Message } from "$lib/types/Message";
11
- import type { TextGenerationStreamOutput } from "@huggingface/inference";
12
 
13
  export const endpointVertexParametersSchema = z.object({
14
  weight: z.number().int().positive().default(1),
@@ -17,20 +11,10 @@ export const endpointVertexParametersSchema = z.object({
17
  location: z.string().default("europe-west1"),
18
  project: z.string(),
19
  apiEndpoint: z.string().optional(),
20
- safetyThreshold: z
21
- .enum([
22
- HarmBlockThreshold.HARM_BLOCK_THRESHOLD_UNSPECIFIED,
23
- HarmBlockThreshold.BLOCK_LOW_AND_ABOVE,
24
- HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
25
- HarmBlockThreshold.BLOCK_NONE,
26
- HarmBlockThreshold.BLOCK_ONLY_HIGH,
27
- ])
28
- .optional(),
29
  });
30
 
31
  export function endpointVertex(input: z.input<typeof endpointVertexParametersSchema>): Endpoint {
32
- const { project, location, model, apiEndpoint, safetyThreshold } =
33
- endpointVertexParametersSchema.parse(input);
34
 
35
  const vertex_ai = new VertexAI({
36
  project,
@@ -38,104 +22,55 @@ export function endpointVertex(input: z.input<typeof endpointVertexParametersSch
38
  apiEndpoint,
39
  });
40
 
41
- return async ({ messages, preprompt, generateSettings }) => {
42
- const generativeModel = vertex_ai.getGenerativeModel({
43
- model: model.id ?? model.name,
44
- safetySettings: safetyThreshold
45
- ? [
46
- {
47
- category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
48
- threshold: safetyThreshold,
49
- },
50
- {
51
- category: HarmCategory.HARM_CATEGORY_HARASSMENT,
52
- threshold: safetyThreshold,
53
- },
54
- {
55
- category: HarmCategory.HARM_CATEGORY_HATE_SPEECH,
56
- threshold: safetyThreshold,
57
- },
58
- {
59
- category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT,
60
- threshold: safetyThreshold,
61
- },
62
- {
63
- category: HarmCategory.HARM_CATEGORY_UNSPECIFIED,
64
- threshold: safetyThreshold,
65
- },
66
- ]
67
- : undefined,
68
- generationConfig: {
69
- maxOutputTokens: generateSettings?.max_new_tokens ?? 4096,
70
- stopSequences: generateSettings?.stop,
71
- temperature: generateSettings?.temperature ?? 1,
72
  },
73
- });
74
-
75
- // Preprompt is the same as the first system message.
76
- let systemMessage = preprompt;
77
- if (messages[0].from === "system") {
78
- systemMessage = messages[0].content;
79
- messages.shift();
80
- }
81
-
82
- const vertexMessages = messages.map(({ from, content }: Omit<Message, "id">): Content => {
83
- return {
84
- role: from === "user" ? "user" : "model",
85
- parts: [
86
- {
87
- text: content,
88
- },
89
- ],
90
- };
91
- });
92
 
93
- const result = await generativeModel.generateContentStream({
94
- contents: vertexMessages,
95
- systemInstruction: systemMessage
96
- ? {
97
- role: "system",
98
- parts: [
99
- {
100
- text: systemMessage,
101
- },
102
- ],
103
- }
104
- : undefined,
105
  });
106
 
 
 
107
  let tokenId = 0;
 
108
  return (async function* () {
109
  let generatedText = "";
110
 
111
  for await (const data of result.stream) {
112
- if (!data?.candidates?.length) break; // Handle case where no candidates are present
113
-
114
- const candidate = data.candidates[0];
115
- if (!candidate.content?.parts?.length) continue; // Skip if no parts are present
116
-
117
- const firstPart = candidate.content.parts.find((part) => "text" in part) as
118
- | TextPart
119
- | undefined;
120
- if (!firstPart) continue; // Skip if no text part is found
121
-
122
- const isLastChunk = !!candidate.finishReason;
123
-
124
- const content = firstPart.text;
125
- generatedText += content;
126
- const output: TextGenerationStreamOutput = {
127
- token: {
128
- id: tokenId++,
129
- text: content,
130
- logprob: 0,
131
- special: isLastChunk,
132
- },
133
- generated_text: isLastChunk ? generatedText : null,
134
- details: null,
135
- };
136
- yield output;
137
 
138
- if (isLastChunk) break;
 
 
 
139
  }
140
  })();
141
  };
 
1
+ import { VertexAI, HarmCategory, HarmBlockThreshold } from "@google-cloud/vertexai";
2
+ import { buildPrompt } from "$lib/buildPrompt";
3
+ import type { TextGenerationStreamOutput } from "@huggingface/inference";
 
 
 
 
4
  import type { Endpoint } from "../endpoints";
5
  import { z } from "zod";
 
 
6
 
7
  export const endpointVertexParametersSchema = z.object({
8
  weight: z.number().int().positive().default(1),
 
11
  location: z.string().default("europe-west1"),
12
  project: z.string(),
13
  apiEndpoint: z.string().optional(),
 
 
 
 
 
 
 
 
 
14
  });
15
 
16
  export function endpointVertex(input: z.input<typeof endpointVertexParametersSchema>): Endpoint {
17
+ const { project, location, model, apiEndpoint } = endpointVertexParametersSchema.parse(input);
 
18
 
19
  const vertex_ai = new VertexAI({
20
  project,
 
22
  apiEndpoint,
23
  });
24
 
25
+ const generativeModel = vertex_ai.getGenerativeModel({
26
+ model: model.id ?? model.name,
27
+ safety_settings: [
28
+ {
29
+ category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
30
+ threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  },
32
+ ],
33
+ generation_config: {},
34
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
+ return async ({ messages, preprompt, continueMessage }) => {
37
+ const prompt = await buildPrompt({
38
+ messages,
39
+ continueMessage,
40
+ preprompt,
41
+ model,
 
 
 
 
 
 
42
  });
43
 
44
+ const chat = generativeModel.startChat();
45
+ const result = await chat.sendMessageStream(prompt);
46
  let tokenId = 0;
47
+
48
  return (async function* () {
49
  let generatedText = "";
50
 
51
  for await (const data of result.stream) {
52
+ if (Array.isArray(data?.candidates) && data.candidates.length > 0) {
53
+ const firstPart = data.candidates[0].content.parts[0];
54
+ if ("text" in firstPart) {
55
+ const content = firstPart.text;
56
+ generatedText += content;
57
+ const output: TextGenerationStreamOutput = {
58
+ token: {
59
+ id: tokenId++,
60
+ text: content ?? "",
61
+ logprob: 0,
62
+ special: false,
63
+ },
64
+ generated_text: generatedText,
65
+ details: null,
66
+ };
67
+ yield output;
68
+ }
 
 
 
 
 
 
 
 
69
 
70
+ if (!data.candidates.slice(-1)[0].finishReason) break;
71
+ } else {
72
+ break;
73
+ }
74
  }
75
  })();
76
  };
src/lib/server/endpoints/langserve/endpointLangserve.ts CHANGED
@@ -2,7 +2,6 @@ import { buildPrompt } from "$lib/buildPrompt";
2
  import { z } from "zod";
3
  import type { Endpoint } from "../endpoints";
4
  import type { TextGenerationStreamOutput } from "@huggingface/inference";
5
- import { logger } from "$lib/server/logger";
6
 
7
  export const endpointLangserveParametersSchema = z.object({
8
  weight: z.number().int().positive().default(1),
@@ -100,8 +99,8 @@ export function endpointLangserve(
100
  try {
101
  data = JSON.parse(jsonString);
102
  } catch (e) {
103
- logger.error("Failed to parse JSON", e);
104
- logger.error("Problematic JSON string:", jsonString);
105
  continue; // Skip this iteration and try the next chunk
106
  }
107
  // Assuming content within data is a plain string
 
2
  import { z } from "zod";
3
  import type { Endpoint } from "../endpoints";
4
  import type { TextGenerationStreamOutput } from "@huggingface/inference";
 
5
 
6
  export const endpointLangserveParametersSchema = z.object({
7
  weight: z.number().int().positive().default(1),
 
99
  try {
100
  data = JSON.parse(jsonString);
101
  } catch (e) {
102
+ console.error("Failed to parse JSON", e);
103
+ console.error("Problematic JSON string:", jsonString);
104
  continue; // Skip this iteration and try the next chunk
105
  }
106
  // Assuming content within data is a plain string
src/lib/server/endpoints/llamacpp/endpointLlamacpp.ts CHANGED
@@ -1,9 +1,8 @@
1
- import { env } from "$env/dynamic/private";
2
  import { buildPrompt } from "$lib/buildPrompt";
3
  import type { TextGenerationStreamOutput } from "@huggingface/inference";
4
  import type { Endpoint } from "../endpoints";
5
  import { z } from "zod";
6
- import { logger } from "$lib/server/logger";
7
 
8
  export const endpointLlamacppParametersSchema = z.object({
9
  weight: z.number().int().positive().default(1),
@@ -13,7 +12,7 @@ export const endpointLlamacppParametersSchema = z.object({
13
  accessToken: z
14
  .string()
15
  .min(1)
16
- .default(env.HF_TOKEN ?? env.HF_ACCESS_TOKEN),
17
  });
18
 
19
  export function endpointLlamacpp(
@@ -94,8 +93,8 @@ export function endpointLlamacpp(
94
  try {
95
  data = JSON.parse(jsonString);
96
  } catch (e) {
97
- logger.error("Failed to parse JSON", e);
98
- logger.error("Problematic JSON string:", jsonString);
99
  continue; // Skip this iteration and try the next chunk
100
  }
101
 
 
1
+ import { HF_ACCESS_TOKEN, HF_TOKEN } from "$env/static/private";
2
  import { buildPrompt } from "$lib/buildPrompt";
3
  import type { TextGenerationStreamOutput } from "@huggingface/inference";
4
  import type { Endpoint } from "../endpoints";
5
  import { z } from "zod";
 
6
 
7
  export const endpointLlamacppParametersSchema = z.object({
8
  weight: z.number().int().positive().default(1),
 
12
  accessToken: z
13
  .string()
14
  .min(1)
15
+ .default(HF_TOKEN ?? HF_ACCESS_TOKEN),
16
  });
17
 
18
  export function endpointLlamacpp(
 
93
  try {
94
  data = JSON.parse(jsonString);
95
  } catch (e) {
96
+ console.error("Failed to parse JSON", e);
97
+ console.error("Problematic JSON string:", jsonString);
98
  continue; // Skip this iteration and try the next chunk
99
  }
100
 
src/lib/server/endpoints/openai/endpointOai.ts CHANGED
@@ -2,7 +2,7 @@ import { z } from "zod";
2
  import { openAICompletionToTextGenerationStream } from "./openAICompletionToTextGenerationStream";
3
  import { openAIChatToTextGenerationStream } from "./openAIChatToTextGenerationStream";
4
  import { buildPrompt } from "$lib/buildPrompt";
5
- import { env } from "$env/dynamic/private";
6
  import type { Endpoint } from "../endpoints";
7
 
8
  export const endpointOAIParametersSchema = z.object({
@@ -10,7 +10,7 @@ export const endpointOAIParametersSchema = z.object({
10
  model: z.any(),
11
  type: z.literal("openai"),
12
  baseURL: z.string().url().default("https://api.openai.com/v1"),
13
- apiKey: z.string().default(env.OPENAI_API_KEY ?? "sk-"),
14
  completion: z
15
  .union([z.literal("completions"), z.literal("chat_completions")])
16
  .default("chat_completions"),
 
2
  import { openAICompletionToTextGenerationStream } from "./openAICompletionToTextGenerationStream";
3
  import { openAIChatToTextGenerationStream } from "./openAIChatToTextGenerationStream";
4
  import { buildPrompt } from "$lib/buildPrompt";
5
+ import { OPENAI_API_KEY } from "$env/static/private";
6
  import type { Endpoint } from "../endpoints";
7
 
8
  export const endpointOAIParametersSchema = z.object({
 
10
  model: z.any(),
11
  type: z.literal("openai"),
12
  baseURL: z.string().url().default("https://api.openai.com/v1"),
13
+ apiKey: z.string().default(OPENAI_API_KEY ?? "sk-"),
14
  completion: z
15
  .union([z.literal("completions"), z.literal("chat_completions")])
16
  .default("chat_completions"),
src/lib/server/endpoints/tgi/endpointTgi.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { env } from "$env/dynamic/private";
2
  import { buildPrompt } from "$lib/buildPrompt";
3
  import { textGenerationStream } from "@huggingface/inference";
4
  import type { Endpoint } from "../endpoints";
@@ -9,7 +9,7 @@ export const endpointTgiParametersSchema = z.object({
9
  model: z.any(),
10
  type: z.literal("tgi"),
11
  url: z.string().url(),
12
- accessToken: z.string().default(env.HF_TOKEN ?? env.HF_ACCESS_TOKEN),
13
  authorization: z.string().optional(),
14
  });
15
 
 
1
+ import { HF_ACCESS_TOKEN, HF_TOKEN } from "$env/static/private";
2
  import { buildPrompt } from "$lib/buildPrompt";
3
  import { textGenerationStream } from "@huggingface/inference";
4
  import type { Endpoint } from "../endpoints";
 
9
  model: z.any(),
10
  type: z.literal("tgi"),
11
  url: z.string().url(),
12
+ accessToken: z.string().default(HF_TOKEN ?? HF_ACCESS_TOKEN),
13
  authorization: z.string().optional(),
14
  });
15
 
src/lib/server/files/downloadFile.ts CHANGED
@@ -1,5 +1,5 @@
1
  import { error } from "@sveltejs/kit";
2
- import { collections } from "$lib/server/database";
3
  import type { Conversation } from "$lib/types/Conversation";
4
  import type { SharedConversation } from "$lib/types/SharedConversation";
5
 
 
1
  import { error } from "@sveltejs/kit";
2
+ import { collections } from "../database";
3
  import type { Conversation } from "$lib/types/Conversation";
4
  import type { SharedConversation } from "$lib/types/SharedConversation";
5
 
src/lib/server/files/uploadFile.ts CHANGED
@@ -1,6 +1,6 @@
1
  import type { Conversation } from "$lib/types/Conversation";
2
  import { sha256 } from "$lib/utils/sha256";
3
- import { collections } from "$lib/server/database";
4
 
5
  export async function uploadFile(file: Blob, conv: Conversation): Promise<string> {
6
  const sha = await sha256(await file.text());
 
1
  import type { Conversation } from "$lib/types/Conversation";
2
  import { sha256 } from "$lib/utils/sha256";
3
+ import { collections } from "../database";
4
 
5
  export async function uploadFile(file: Blob, conv: Conversation): Promise<string> {
6
  const sha = await sha256(await file.text());