Mishig julien-c HF staff victor HF staff commited on
Commit
ebac87f
1 Parent(s): 0953d85

[Websearch] update (#427)

Browse files

* Fix reuqest body

* update webSearchQueryPromptTemplate

* update generate google query parser

* Add today's date to google search query creator

* crawl top stories if exts; remove answer_box & knowledgeGraph

* Create paragraph chunks from top articles

* flattened paragprah chunks

* update status texts

* add gradio client

* call gradio app for RAG

* Web scrape only "p, li, span" els

* add MAX_N_CHUNKS

* gradio result typing

* parse only <p> elements

* rm dev change

* update typing WebSearch

* buld RAG prompt

* Rm dev change

* change websearch context msg from user to assisntat type

* use hosted gradio app

* fix lint

* prompt engineering

* more prompt engineering

* MAX_N_PAGES_SCRAPE = 10

* better error msg

* more prompt engineering

* revert websearch prompt to previous

* rm `top_stories` from websearch as the results are not good

* Stop using gradio client, use regular fetch

* chore

* Rm websearchsummary references as it is no longer used

* update readme

* Apply suggestions from code review

Co-authored-by: Julien Chaumond <[email protected]>

* Use tfjs to do embeddings in server node

* fix websearch component disapperar after finishing generation

* Show sources of closest embeddings used in RAG

* fix prompting and also add current date

* add comment

* comment for search query

* sources

* hide www

* using hostname direclty

* Show successful web pages instead of failed ones

* rm noisy messages

* google query generation using previous messaages as context

* handle falcon generation

* bring back Browsing webpage msg

---------

Co-authored-by: Julien Chaumond <[email protected]>
Co-authored-by: Victor Mustar <[email protected]>

README.md CHANGED
@@ -155,7 +155,7 @@ You can change things like the parameters, or customize the preprompt to better
155
 
156
  By default the prompt is constructed using `userMessageToken`, `assistantMessageToken`, `userMessageEndToken`, `assistantMessageEndToken`, `preprompt` parameters and a series of default templates.
157
 
158
- However, these templates can be modified by setting the `chatPromptTemplate`, `webSearchSummaryPromptTemplate`, and `webSearchQueryPromptTemplate` parameters. Note that if WebSearch is not enabled, only `chatPromptTemplate` needs to be set. The template language is https://handlebarsjs.com. The templates have access to the model's prompt parameters (`preprompt`, etc.). However, if the templates are specified it is recommended to inline the prompt parameters, as using the references (`{{preprompt}}`) is deprecated.
159
 
160
  For example:
161
 
@@ -187,33 +187,14 @@ The following is the default `chatPromptTemplate`, although newlines and indenti
187
 
188
  When performing a websearch, the search query is constructed using the `webSearchQueryPromptTemplate` template. It is recommended that that the prompt instructs the chat model to only return a few keywords.
189
 
190
- The following is the default `webSearchQueryPromptTemplate`. Note that not all models supports consecutive user-messages which this template uses.
191
 
192
  ```
193
  {{userMessageToken}}
194
- The following messages were written by a user, trying to answer a question.
 
195
  {{userMessageEndToken}}
196
- {{#each messages}}
197
- {{#ifUser}}{{@root.userMessageToken}}{{content}}{{@root.userMessageEndToken}}{{/ifUser}}
198
- {{/each}}
199
- {{userMessageToken}}
200
- What plain-text english sentence would you input into Google to answer the last question? Answer with a short (10 words max) simple sentence.
201
- {{userMessageEndToken}}
202
- {{assistantMessageToken}}Query:
203
- ```
204
-
205
- **webSearchSummaryPromptTemplate**
206
-
207
- The search-engine response (`answer`) is summarized using the following prompt template. However, when `HF_ACCESS_TOKEN` is provided, a dedicated summary model is used instead. Additionally, the model's `query` response to `webSearchQueryPromptTemplate` is also available to this template.
208
-
209
- The following is the default `webSearchSummaryPromptTemplate`. Note that not all models supports consecutive user-messages which this template uses.
210
-
211
- ```
212
- {{userMessageToken}}{{answer}}{{userMessageEndToken}}
213
- {{userMessageToken}}
214
- The text above should be summarized to best answer the query: {{query}}.
215
- {{userMessageEndToken}}
216
- {{assistantMessageToken}}Summary:
217
  ```
218
 
219
  #### Running your own models using a custom endpoint
 
155
 
156
  By default the prompt is constructed using `userMessageToken`, `assistantMessageToken`, `userMessageEndToken`, `assistantMessageEndToken`, `preprompt` parameters and a series of default templates.
157
 
158
+ However, these templates can be modified by setting the `chatPromptTemplate` and `webSearchQueryPromptTemplate` parameters. Note that if WebSearch is not enabled, only `chatPromptTemplate` needs to be set. The template language is https://handlebarsjs.com. The templates have access to the model's prompt parameters (`preprompt`, etc.). However, if the templates are specified it is recommended to inline the prompt parameters, as using the references (`{{preprompt}}`) is deprecated.
159
 
160
  For example:
161
 
 
187
 
188
  When performing a websearch, the search query is constructed using the `webSearchQueryPromptTemplate` template. It is recommended that that the prompt instructs the chat model to only return a few keywords.
189
 
190
+ The following is the default `webSearchQueryPromptTemplate`.
191
 
192
  ```
193
  {{userMessageToken}}
194
+ My question is: {{message.content}}.
195
+ Based on the conversation history (my previous questions are: {{previousMessages}}), give me an appropriate query to answer my question for google search. You should not say more than query. You should not say any words except the query. For the context, today is {{currentDate}}
196
  {{userMessageEndToken}}
197
+ {{assistantMessageToken}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
  ```
199
 
200
  #### Running your own models using a custom endpoint
package-lock.json CHANGED
@@ -10,6 +10,7 @@
10
  "dependencies": {
11
  "@huggingface/hub": "^0.5.1",
12
  "@huggingface/inference": "^2.2.0",
 
13
  "autoprefixer": "^10.4.14",
14
  "aws4fetch": "^1.0.17",
15
  "date-fns": "^2.29.3",
@@ -655,6 +656,60 @@
655
  "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==",
656
  "dev": true
657
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
658
  "node_modules/@rollup/plugin-commonjs": {
659
  "version": "24.0.1",
660
  "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.0.1.tgz",
@@ -947,6 +1002,11 @@
947
  "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
948
  "dev": true
949
  },
 
 
 
 
 
950
  "node_modules/@types/marked": {
951
  "version": "4.0.8",
952
  "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.8.tgz",
@@ -1298,6 +1358,18 @@
1298
  "url": "https://opencollective.com/vitest"
1299
  }
1300
  },
 
 
 
 
 
 
 
 
 
 
 
 
1301
  "node_modules/abab": {
1302
  "version": "2.0.6",
1303
  "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
@@ -1472,6 +1544,11 @@
1472
  "resolved": "https://registry.npmjs.org/aws4fetch/-/aws4fetch-1.0.17.tgz",
1473
  "integrity": "sha512-4IbOvsxqxeOSxI4oA+8xEO8SzBMVlzbSTgGy/EF83rHnQ/aKtP6Sc6YV/k0oiW0mqrcxuThlbDosnvetGOuO+g=="
1474
  },
 
 
 
 
 
1475
  "node_modules/balanced-match": {
1476
  "version": "1.0.2",
1477
  "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -1510,6 +1587,16 @@
1510
  "integrity": "sha512-u4cBQNepWxYA55FunZSM7wMi55yQaN0otnhhilNoWHq0MfOfJeQx0v0mRRpolGOExPjZcl6FtB0BB8Xkb88F0g==",
1511
  "optional": true
1512
  },
 
 
 
 
 
 
 
 
 
 
1513
  "node_modules/blueimp-md5": {
1514
  "version": "2.19.0",
1515
  "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz",
@@ -1579,6 +1666,29 @@
1579
  "node": ">=14.20.1"
1580
  }
1581
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1582
  "node_modules/buffer-crc32": {
1583
  "version": "0.2.13",
1584
  "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
@@ -1588,6 +1698,20 @@
1588
  "node": "*"
1589
  }
1590
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1591
  "node_modules/builtin-modules": {
1592
  "version": "3.3.0",
1593
  "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
@@ -1736,11 +1860,27 @@
1736
  "node": ">= 6"
1737
  }
1738
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1739
  "node_modules/color-convert": {
1740
  "version": "2.0.1",
1741
  "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
1742
  "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
1743
- "dev": true,
1744
  "dependencies": {
1745
  "color-name": "~1.1.4"
1746
  },
@@ -1753,6 +1893,15 @@
1753
  "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
1754
  "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
1755
  },
 
 
 
 
 
 
 
 
 
1756
  "node_modules/combined-stream": {
1757
  "version": "1.0.8",
1758
  "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -1928,6 +2077,20 @@
1928
  "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
1929
  "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA=="
1930
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1931
  "node_modules/deep-eql": {
1932
  "version": "4.1.3",
1933
  "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz",
@@ -1940,6 +2103,14 @@
1940
  "node": ">=6"
1941
  }
1942
  },
 
 
 
 
 
 
 
 
1943
  "node_modules/deep-is": {
1944
  "version": "0.1.4",
1945
  "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@@ -1972,6 +2143,14 @@
1972
  "node": ">=8"
1973
  }
1974
  },
 
 
 
 
 
 
 
 
1975
  "node_modules/devalue": {
1976
  "version": "4.3.0",
1977
  "resolved": "https://registry.npmjs.org/devalue/-/devalue-4.3.0.tgz",
@@ -2036,6 +2215,14 @@
2036
  "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.359.tgz",
2037
  "integrity": "sha512-OoVcngKCIuNXtZnsYoqlCvr0Cf3NIPzDIgwUfI9bdTFjXCrr79lI0kwQstLPZ7WhCezLlGksZk/BFAzoXC7GDw=="
2038
  },
 
 
 
 
 
 
 
 
2039
  "node_modules/entities": {
2040
  "version": "4.5.0",
2041
  "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
@@ -2397,6 +2584,14 @@
2397
  "url": "https://github.com/sindresorhus/execa?sponsor=1"
2398
  }
2399
  },
 
 
 
 
 
 
 
 
2400
  "node_modules/fast-deep-equal": {
2401
  "version": "3.1.3",
2402
  "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -2409,6 +2604,11 @@
2409
  "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
2410
  "dev": true
2411
  },
 
 
 
 
 
2412
  "node_modules/fast-glob": {
2413
  "version": "3.2.12",
2414
  "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
@@ -2507,6 +2707,11 @@
2507
  "node": "^10.12.0 || >=12.0.0"
2508
  }
2509
  },
 
 
 
 
 
2510
  "node_modules/flatted": {
2511
  "version": "3.2.7",
2512
  "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
@@ -2538,6 +2743,11 @@
2538
  "url": "https://www.patreon.com/infusion"
2539
  }
2540
  },
 
 
 
 
 
2541
  "node_modules/fs.realpath": {
2542
  "version": "1.0.0",
2543
  "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -2582,6 +2792,11 @@
2582
  "url": "https://github.com/sponsors/sindresorhus"
2583
  }
2584
  },
 
 
 
 
 
2585
  "node_modules/glob": {
2586
  "version": "7.2.3",
2587
  "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@@ -2672,6 +2887,11 @@
2672
  "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
2673
  "dev": true
2674
  },
 
 
 
 
 
2675
  "node_modules/handlebars": {
2676
  "version": "4.7.8",
2677
  "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
@@ -2781,6 +3001,25 @@
2781
  "node": ">=0.10.0"
2782
  }
2783
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2784
  "node_modules/ignore": {
2785
  "version": "5.2.4",
2786
  "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
@@ -2829,6 +3068,11 @@
2829
  "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
2830
  "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
2831
  },
 
 
 
 
 
2832
  "node_modules/int53": {
2833
  "version": "0.2.4",
2834
  "resolved": "https://registry.npmjs.org/int53/-/int53-0.2.4.tgz",
@@ -2839,6 +3083,11 @@
2839
  "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
2840
  "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ=="
2841
  },
 
 
 
 
 
2842
  "node_modules/is-binary-path": {
2843
  "version": "2.1.0",
2844
  "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -3177,6 +3426,11 @@
3177
  "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
3178
  "dev": true
3179
  },
 
 
 
 
 
3180
  "node_modules/loupe": {
3181
  "version": "2.3.6",
3182
  "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz",
@@ -3314,6 +3568,17 @@
3314
  "node": ">=6"
3315
  }
3316
  },
 
 
 
 
 
 
 
 
 
 
 
3317
  "node_modules/min-indent": {
3318
  "version": "1.0.1",
3319
  "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
@@ -3354,6 +3619,11 @@
3354
  "mkdirp": "bin/cmd.js"
3355
  }
3356
  },
 
 
 
 
 
3357
  "node_modules/mlly": {
3358
  "version": "1.2.1",
3359
  "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.2.1.tgz",
@@ -3457,6 +3727,11 @@
3457
  "node": "^14 || ^16 || >=18"
3458
  }
3459
  },
 
 
 
 
 
3460
  "node_modules/natural-compare": {
3461
  "version": "1.4.0",
3462
  "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
@@ -3474,6 +3749,34 @@
3474
  "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
3475
  "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
3476
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3477
  "node_modules/node-int64": {
3478
  "version": "0.4.0",
3479
  "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
@@ -3572,6 +3875,46 @@
3572
  "url": "https://github.com/sponsors/sindresorhus"
3573
  }
3574
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3575
  "node_modules/openid-client": {
3576
  "version": "5.4.2",
3577
  "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.4.2.tgz",
@@ -3790,6 +4133,11 @@
3790
  "pathe": "^1.1.0"
3791
  }
3792
  },
 
 
 
 
 
3793
  "node_modules/postcss": {
3794
  "version": "8.4.23",
3795
  "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz",
@@ -3947,6 +4295,57 @@
3947
  "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
3948
  }
3949
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3950
  "node_modules/prelude-ls": {
3951
  "version": "1.2.1",
3952
  "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -4081,11 +4480,45 @@
4081
  "url": "https://github.com/chalk/ansi-styles?sponsor=1"
4082
  }
4083
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4084
  "node_modules/psl": {
4085
  "version": "1.9.0",
4086
  "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
4087
  "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag=="
4088
  },
 
 
 
 
 
 
 
 
 
4089
  "node_modules/punycode": {
4090
  "version": "2.3.0",
4091
  "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
@@ -4127,6 +4560,11 @@
4127
  }
4128
  ]
4129
  },
 
 
 
 
 
4130
  "node_modules/quick-lru": {
4131
  "version": "5.1.1",
4132
  "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
@@ -4138,6 +4576,28 @@
4138
  "url": "https://github.com/sponsors/sindresorhus"
4139
  }
4140
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4141
  "node_modules/react-is": {
4142
  "version": "17.0.2",
4143
  "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
@@ -4152,6 +4612,19 @@
4152
  "pify": "^2.3.0"
4153
  }
4154
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
4155
  "node_modules/readdirp": {
4156
  "version": "3.6.0",
4157
  "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -4284,6 +4757,25 @@
4284
  "node": ">=6"
4285
  }
4286
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4287
  "node_modules/safer-buffer": {
4288
  "version": "2.1.2",
4289
  "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
@@ -4337,10 +4829,9 @@
4337
  }
4338
  },
4339
  "node_modules/semver": {
4340
- "version": "7.3.8",
4341
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
4342
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
4343
- "dev": true,
4344
  "dependencies": {
4345
  "lru-cache": "^6.0.0"
4346
  },
@@ -4365,6 +4856,28 @@
4365
  "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==",
4366
  "dev": true
4367
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4368
  "node_modules/shebang-command": {
4369
  "version": "2.0.0",
4370
  "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -4398,6 +4911,57 @@
4398
  "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
4399
  "dev": true
4400
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4401
  "node_modules/sirv": {
4402
  "version": "2.0.2",
4403
  "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.2.tgz",
@@ -4508,6 +5072,23 @@
4508
  "node": ">=10.0.0"
4509
  }
4510
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4511
  "node_modules/strip-ansi": {
4512
  "version": "6.0.1",
4513
  "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -4865,6 +5446,26 @@
4865
  "postcss": "^8.0.9"
4866
  }
4867
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4868
  "node_modules/text-table": {
4869
  "version": "0.2.0",
4870
  "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -5023,6 +5624,17 @@
5023
  "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
5024
  "dev": true
5025
  },
 
 
 
 
 
 
 
 
 
 
 
5026
  "node_modules/type-check": {
5027
  "version": "0.4.0",
5028
  "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
 
10
  "dependencies": {
11
  "@huggingface/hub": "^0.5.1",
12
  "@huggingface/inference": "^2.2.0",
13
+ "@xenova/transformers": "^2.6.0",
14
  "autoprefixer": "^10.4.14",
15
  "aws4fetch": "^1.0.17",
16
  "date-fns": "^2.29.3",
 
656
  "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==",
657
  "dev": true
658
  },
659
+ "node_modules/@protobufjs/aspromise": {
660
+ "version": "1.1.2",
661
+ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
662
+ "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
663
+ },
664
+ "node_modules/@protobufjs/base64": {
665
+ "version": "1.1.2",
666
+ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
667
+ "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
668
+ },
669
+ "node_modules/@protobufjs/codegen": {
670
+ "version": "2.0.4",
671
+ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
672
+ "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
673
+ },
674
+ "node_modules/@protobufjs/eventemitter": {
675
+ "version": "1.1.0",
676
+ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
677
+ "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
678
+ },
679
+ "node_modules/@protobufjs/fetch": {
680
+ "version": "1.1.0",
681
+ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
682
+ "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
683
+ "dependencies": {
684
+ "@protobufjs/aspromise": "^1.1.1",
685
+ "@protobufjs/inquire": "^1.1.0"
686
+ }
687
+ },
688
+ "node_modules/@protobufjs/float": {
689
+ "version": "1.0.2",
690
+ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
691
+ "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
692
+ },
693
+ "node_modules/@protobufjs/inquire": {
694
+ "version": "1.1.0",
695
+ "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
696
+ "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
697
+ },
698
+ "node_modules/@protobufjs/path": {
699
+ "version": "1.1.2",
700
+ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
701
+ "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
702
+ },
703
+ "node_modules/@protobufjs/pool": {
704
+ "version": "1.1.0",
705
+ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
706
+ "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
707
+ },
708
+ "node_modules/@protobufjs/utf8": {
709
+ "version": "1.1.0",
710
+ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
711
+ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
712
+ },
713
  "node_modules/@rollup/plugin-commonjs": {
714
  "version": "24.0.1",
715
  "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.0.1.tgz",
 
1002
  "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
1003
  "dev": true
1004
  },
1005
+ "node_modules/@types/long": {
1006
+ "version": "4.0.2",
1007
+ "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
1008
+ "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA=="
1009
+ },
1010
  "node_modules/@types/marked": {
1011
  "version": "4.0.8",
1012
  "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.8.tgz",
 
1358
  "url": "https://opencollective.com/vitest"
1359
  }
1360
  },
1361
+ "node_modules/@xenova/transformers": {
1362
+ "version": "2.6.0",
1363
+ "resolved": "https://registry.npmjs.org/@xenova/transformers/-/transformers-2.6.0.tgz",
1364
+ "integrity": "sha512-k9bs+reiwhn+kx0d4FYnlBTWtl8D5Q4fIzoKYxKbTTSVyS33KXbQESRpdIxiU9gtlMKML2Sw0Oep4FYK9dQCsQ==",
1365
+ "dependencies": {
1366
+ "onnxruntime-web": "1.14.0",
1367
+ "sharp": "^0.32.0"
1368
+ },
1369
+ "optionalDependencies": {
1370
+ "onnxruntime-node": "1.14.0"
1371
+ }
1372
+ },
1373
  "node_modules/abab": {
1374
  "version": "2.0.6",
1375
  "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
 
1544
  "resolved": "https://registry.npmjs.org/aws4fetch/-/aws4fetch-1.0.17.tgz",
1545
  "integrity": "sha512-4IbOvsxqxeOSxI4oA+8xEO8SzBMVlzbSTgGy/EF83rHnQ/aKtP6Sc6YV/k0oiW0mqrcxuThlbDosnvetGOuO+g=="
1546
  },
1547
+ "node_modules/b4a": {
1548
+ "version": "1.6.4",
1549
+ "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz",
1550
+ "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw=="
1551
+ },
1552
  "node_modules/balanced-match": {
1553
  "version": "1.0.2",
1554
  "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
 
1587
  "integrity": "sha512-u4cBQNepWxYA55FunZSM7wMi55yQaN0otnhhilNoWHq0MfOfJeQx0v0mRRpolGOExPjZcl6FtB0BB8Xkb88F0g==",
1588
  "optional": true
1589
  },
1590
+ "node_modules/bl": {
1591
+ "version": "4.1.0",
1592
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
1593
+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
1594
+ "dependencies": {
1595
+ "buffer": "^5.5.0",
1596
+ "inherits": "^2.0.4",
1597
+ "readable-stream": "^3.4.0"
1598
+ }
1599
+ },
1600
  "node_modules/blueimp-md5": {
1601
  "version": "2.19.0",
1602
  "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz",
 
1666
  "node": ">=14.20.1"
1667
  }
1668
  },
1669
+ "node_modules/buffer": {
1670
+ "version": "5.7.1",
1671
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
1672
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
1673
+ "funding": [
1674
+ {
1675
+ "type": "github",
1676
+ "url": "https://github.com/sponsors/feross"
1677
+ },
1678
+ {
1679
+ "type": "patreon",
1680
+ "url": "https://www.patreon.com/feross"
1681
+ },
1682
+ {
1683
+ "type": "consulting",
1684
+ "url": "https://feross.org/support"
1685
+ }
1686
+ ],
1687
+ "dependencies": {
1688
+ "base64-js": "^1.3.1",
1689
+ "ieee754": "^1.1.13"
1690
+ }
1691
+ },
1692
  "node_modules/buffer-crc32": {
1693
  "version": "0.2.13",
1694
  "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
 
1698
  "node": "*"
1699
  }
1700
  },
1701
+ "node_modules/bufferutil": {
1702
+ "version": "4.0.7",
1703
+ "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.7.tgz",
1704
+ "integrity": "sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==",
1705
+ "hasInstallScript": true,
1706
+ "optional": true,
1707
+ "peer": true,
1708
+ "dependencies": {
1709
+ "node-gyp-build": "^4.3.0"
1710
+ },
1711
+ "engines": {
1712
+ "node": ">=6.14.2"
1713
+ }
1714
+ },
1715
  "node_modules/builtin-modules": {
1716
  "version": "3.3.0",
1717
  "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
 
1860
  "node": ">= 6"
1861
  }
1862
  },
1863
+ "node_modules/chownr": {
1864
+ "version": "1.1.4",
1865
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
1866
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
1867
+ },
1868
+ "node_modules/color": {
1869
+ "version": "4.2.3",
1870
+ "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
1871
+ "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
1872
+ "dependencies": {
1873
+ "color-convert": "^2.0.1",
1874
+ "color-string": "^1.9.0"
1875
+ },
1876
+ "engines": {
1877
+ "node": ">=12.5.0"
1878
+ }
1879
+ },
1880
  "node_modules/color-convert": {
1881
  "version": "2.0.1",
1882
  "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
1883
  "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
 
1884
  "dependencies": {
1885
  "color-name": "~1.1.4"
1886
  },
 
1893
  "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
1894
  "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
1895
  },
1896
+ "node_modules/color-string": {
1897
+ "version": "1.9.1",
1898
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
1899
+ "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
1900
+ "dependencies": {
1901
+ "color-name": "^1.0.0",
1902
+ "simple-swizzle": "^0.2.2"
1903
+ }
1904
+ },
1905
  "node_modules/combined-stream": {
1906
  "version": "1.0.8",
1907
  "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
 
2077
  "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
2078
  "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA=="
2079
  },
2080
+ "node_modules/decompress-response": {
2081
+ "version": "6.0.0",
2082
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
2083
+ "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
2084
+ "dependencies": {
2085
+ "mimic-response": "^3.1.0"
2086
+ },
2087
+ "engines": {
2088
+ "node": ">=10"
2089
+ },
2090
+ "funding": {
2091
+ "url": "https://github.com/sponsors/sindresorhus"
2092
+ }
2093
+ },
2094
  "node_modules/deep-eql": {
2095
  "version": "4.1.3",
2096
  "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz",
 
2103
  "node": ">=6"
2104
  }
2105
  },
2106
+ "node_modules/deep-extend": {
2107
+ "version": "0.6.0",
2108
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
2109
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
2110
+ "engines": {
2111
+ "node": ">=4.0.0"
2112
+ }
2113
+ },
2114
  "node_modules/deep-is": {
2115
  "version": "0.1.4",
2116
  "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
 
2143
  "node": ">=8"
2144
  }
2145
  },
2146
+ "node_modules/detect-libc": {
2147
+ "version": "2.0.2",
2148
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
2149
+ "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==",
2150
+ "engines": {
2151
+ "node": ">=8"
2152
+ }
2153
+ },
2154
  "node_modules/devalue": {
2155
  "version": "4.3.0",
2156
  "resolved": "https://registry.npmjs.org/devalue/-/devalue-4.3.0.tgz",
 
2215
  "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.359.tgz",
2216
  "integrity": "sha512-OoVcngKCIuNXtZnsYoqlCvr0Cf3NIPzDIgwUfI9bdTFjXCrr79lI0kwQstLPZ7WhCezLlGksZk/BFAzoXC7GDw=="
2217
  },
2218
+ "node_modules/end-of-stream": {
2219
+ "version": "1.4.4",
2220
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
2221
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
2222
+ "dependencies": {
2223
+ "once": "^1.4.0"
2224
+ }
2225
+ },
2226
  "node_modules/entities": {
2227
  "version": "4.5.0",
2228
  "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
 
2584
  "url": "https://github.com/sindresorhus/execa?sponsor=1"
2585
  }
2586
  },
2587
+ "node_modules/expand-template": {
2588
+ "version": "2.0.3",
2589
+ "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
2590
+ "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
2591
+ "engines": {
2592
+ "node": ">=6"
2593
+ }
2594
+ },
2595
  "node_modules/fast-deep-equal": {
2596
  "version": "3.1.3",
2597
  "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
 
2604
  "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
2605
  "dev": true
2606
  },
2607
+ "node_modules/fast-fifo": {
2608
+ "version": "1.3.2",
2609
+ "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
2610
+ "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="
2611
+ },
2612
  "node_modules/fast-glob": {
2613
  "version": "3.2.12",
2614
  "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
 
2707
  "node": "^10.12.0 || >=12.0.0"
2708
  }
2709
  },
2710
+ "node_modules/flatbuffers": {
2711
+ "version": "1.12.0",
2712
+ "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz",
2713
+ "integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ=="
2714
+ },
2715
  "node_modules/flatted": {
2716
  "version": "3.2.7",
2717
  "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
 
2743
  "url": "https://www.patreon.com/infusion"
2744
  }
2745
  },
2746
+ "node_modules/fs-constants": {
2747
+ "version": "1.0.0",
2748
+ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
2749
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
2750
+ },
2751
  "node_modules/fs.realpath": {
2752
  "version": "1.0.0",
2753
  "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
 
2792
  "url": "https://github.com/sponsors/sindresorhus"
2793
  }
2794
  },
2795
+ "node_modules/github-from-package": {
2796
+ "version": "0.0.0",
2797
+ "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
2798
+ "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="
2799
+ },
2800
  "node_modules/glob": {
2801
  "version": "7.2.3",
2802
  "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
 
2887
  "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
2888
  "dev": true
2889
  },
2890
+ "node_modules/guid-typescript": {
2891
+ "version": "1.0.9",
2892
+ "resolved": "https://registry.npmjs.org/guid-typescript/-/guid-typescript-1.0.9.tgz",
2893
+ "integrity": "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ=="
2894
+ },
2895
  "node_modules/handlebars": {
2896
  "version": "4.7.8",
2897
  "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
 
3001
  "node": ">=0.10.0"
3002
  }
3003
  },
3004
+ "node_modules/ieee754": {
3005
+ "version": "1.2.1",
3006
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
3007
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
3008
+ "funding": [
3009
+ {
3010
+ "type": "github",
3011
+ "url": "https://github.com/sponsors/feross"
3012
+ },
3013
+ {
3014
+ "type": "patreon",
3015
+ "url": "https://www.patreon.com/feross"
3016
+ },
3017
+ {
3018
+ "type": "consulting",
3019
+ "url": "https://feross.org/support"
3020
+ }
3021
+ ]
3022
+ },
3023
  "node_modules/ignore": {
3024
  "version": "5.2.4",
3025
  "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
 
3068
  "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
3069
  "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
3070
  },
3071
+ "node_modules/ini": {
3072
+ "version": "1.3.8",
3073
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
3074
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
3075
+ },
3076
  "node_modules/int53": {
3077
  "version": "0.2.4",
3078
  "resolved": "https://registry.npmjs.org/int53/-/int53-0.2.4.tgz",
 
3083
  "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
3084
  "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ=="
3085
  },
3086
+ "node_modules/is-arrayish": {
3087
+ "version": "0.3.2",
3088
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
3089
+ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
3090
+ },
3091
  "node_modules/is-binary-path": {
3092
  "version": "2.1.0",
3093
  "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
 
3426
  "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
3427
  "dev": true
3428
  },
3429
+ "node_modules/long": {
3430
+ "version": "4.0.0",
3431
+ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
3432
+ "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
3433
+ },
3434
  "node_modules/loupe": {
3435
  "version": "2.3.6",
3436
  "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz",
 
3568
  "node": ">=6"
3569
  }
3570
  },
3571
+ "node_modules/mimic-response": {
3572
+ "version": "3.1.0",
3573
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
3574
+ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
3575
+ "engines": {
3576
+ "node": ">=10"
3577
+ },
3578
+ "funding": {
3579
+ "url": "https://github.com/sponsors/sindresorhus"
3580
+ }
3581
+ },
3582
  "node_modules/min-indent": {
3583
  "version": "1.0.1",
3584
  "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
 
3619
  "mkdirp": "bin/cmd.js"
3620
  }
3621
  },
3622
+ "node_modules/mkdirp-classic": {
3623
+ "version": "0.5.3",
3624
+ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
3625
+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
3626
+ },
3627
  "node_modules/mlly": {
3628
  "version": "1.2.1",
3629
  "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.2.1.tgz",
 
3727
  "node": "^14 || ^16 || >=18"
3728
  }
3729
  },
3730
+ "node_modules/napi-build-utils": {
3731
+ "version": "1.0.2",
3732
+ "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
3733
+ "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
3734
+ },
3735
  "node_modules/natural-compare": {
3736
  "version": "1.4.0",
3737
  "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
 
3749
  "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
3750
  "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
3751
  },
3752
+ "node_modules/node-abi": {
3753
+ "version": "3.47.0",
3754
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.47.0.tgz",
3755
+ "integrity": "sha512-2s6B2CWZM//kPgwnuI0KrYwNjfdByE25zvAaEpq9IH4zcNsarH8Ihu/UuX6XMPEogDAxkuUFeZn60pXNHAqn3A==",
3756
+ "dependencies": {
3757
+ "semver": "^7.3.5"
3758
+ },
3759
+ "engines": {
3760
+ "node": ">=10"
3761
+ }
3762
+ },
3763
+ "node_modules/node-addon-api": {
3764
+ "version": "6.1.0",
3765
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz",
3766
+ "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA=="
3767
+ },
3768
+ "node_modules/node-gyp-build": {
3769
+ "version": "4.6.1",
3770
+ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.1.tgz",
3771
+ "integrity": "sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==",
3772
+ "optional": true,
3773
+ "peer": true,
3774
+ "bin": {
3775
+ "node-gyp-build": "bin.js",
3776
+ "node-gyp-build-optional": "optional.js",
3777
+ "node-gyp-build-test": "build-test.js"
3778
+ }
3779
+ },
3780
  "node_modules/node-int64": {
3781
  "version": "0.4.0",
3782
  "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
 
3875
  "url": "https://github.com/sponsors/sindresorhus"
3876
  }
3877
  },
3878
+ "node_modules/onnx-proto": {
3879
+ "version": "4.0.4",
3880
+ "resolved": "https://registry.npmjs.org/onnx-proto/-/onnx-proto-4.0.4.tgz",
3881
+ "integrity": "sha512-aldMOB3HRoo6q/phyB6QRQxSt895HNNw82BNyZ2CMh4bjeKv7g/c+VpAFtJuEMVfYLMbRx61hbuqnKceLeDcDA==",
3882
+ "dependencies": {
3883
+ "protobufjs": "^6.8.8"
3884
+ }
3885
+ },
3886
+ "node_modules/onnxruntime-common": {
3887
+ "version": "1.14.0",
3888
+ "resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.14.0.tgz",
3889
+ "integrity": "sha512-3LJpegM2iMNRX2wUmtYfeX/ytfOzNwAWKSq1HbRrKc9+uqG/FsEA0bbKZl1btQeZaXhC26l44NWpNUeXPII7Ew=="
3890
+ },
3891
+ "node_modules/onnxruntime-node": {
3892
+ "version": "1.14.0",
3893
+ "resolved": "https://registry.npmjs.org/onnxruntime-node/-/onnxruntime-node-1.14.0.tgz",
3894
+ "integrity": "sha512-5ba7TWomIV/9b6NH/1x/8QEeowsb+jBEvFzU6z0T4mNsFwdPqXeFUM7uxC6QeSRkEbWu3qEB0VMjrvzN/0S9+w==",
3895
+ "optional": true,
3896
+ "os": [
3897
+ "win32",
3898
+ "darwin",
3899
+ "linux"
3900
+ ],
3901
+ "dependencies": {
3902
+ "onnxruntime-common": "~1.14.0"
3903
+ }
3904
+ },
3905
+ "node_modules/onnxruntime-web": {
3906
+ "version": "1.14.0",
3907
+ "resolved": "https://registry.npmjs.org/onnxruntime-web/-/onnxruntime-web-1.14.0.tgz",
3908
+ "integrity": "sha512-Kcqf43UMfW8mCydVGcX9OMXI2VN17c0p6XvR7IPSZzBf/6lteBzXHvcEVWDPmCKuGombl997HgLqj91F11DzXw==",
3909
+ "dependencies": {
3910
+ "flatbuffers": "^1.12.0",
3911
+ "guid-typescript": "^1.0.9",
3912
+ "long": "^4.0.0",
3913
+ "onnx-proto": "^4.0.4",
3914
+ "onnxruntime-common": "~1.14.0",
3915
+ "platform": "^1.3.6"
3916
+ }
3917
+ },
3918
  "node_modules/openid-client": {
3919
  "version": "5.4.2",
3920
  "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.4.2.tgz",
 
4133
  "pathe": "^1.1.0"
4134
  }
4135
  },
4136
+ "node_modules/platform": {
4137
+ "version": "1.3.6",
4138
+ "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz",
4139
+ "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg=="
4140
+ },
4141
  "node_modules/postcss": {
4142
  "version": "8.4.23",
4143
  "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz",
 
4295
  "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
4296
  }
4297
  },
4298
+ "node_modules/prebuild-install": {
4299
+ "version": "7.1.1",
4300
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
4301
+ "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==",
4302
+ "dependencies": {
4303
+ "detect-libc": "^2.0.0",
4304
+ "expand-template": "^2.0.3",
4305
+ "github-from-package": "0.0.0",
4306
+ "minimist": "^1.2.3",
4307
+ "mkdirp-classic": "^0.5.3",
4308
+ "napi-build-utils": "^1.0.1",
4309
+ "node-abi": "^3.3.0",
4310
+ "pump": "^3.0.0",
4311
+ "rc": "^1.2.7",
4312
+ "simple-get": "^4.0.0",
4313
+ "tar-fs": "^2.0.0",
4314
+ "tunnel-agent": "^0.6.0"
4315
+ },
4316
+ "bin": {
4317
+ "prebuild-install": "bin.js"
4318
+ },
4319
+ "engines": {
4320
+ "node": ">=10"
4321
+ }
4322
+ },
4323
+ "node_modules/prebuild-install/node_modules/tar-fs": {
4324
+ "version": "2.1.1",
4325
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
4326
+ "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
4327
+ "dependencies": {
4328
+ "chownr": "^1.1.1",
4329
+ "mkdirp-classic": "^0.5.2",
4330
+ "pump": "^3.0.0",
4331
+ "tar-stream": "^2.1.4"
4332
+ }
4333
+ },
4334
+ "node_modules/prebuild-install/node_modules/tar-stream": {
4335
+ "version": "2.2.0",
4336
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
4337
+ "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
4338
+ "dependencies": {
4339
+ "bl": "^4.0.3",
4340
+ "end-of-stream": "^1.4.1",
4341
+ "fs-constants": "^1.0.0",
4342
+ "inherits": "^2.0.3",
4343
+ "readable-stream": "^3.1.1"
4344
+ },
4345
+ "engines": {
4346
+ "node": ">=6"
4347
+ }
4348
+ },
4349
  "node_modules/prelude-ls": {
4350
  "version": "1.2.1",
4351
  "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
 
4480
  "url": "https://github.com/chalk/ansi-styles?sponsor=1"
4481
  }
4482
  },
4483
+ "node_modules/protobufjs": {
4484
+ "version": "6.11.4",
4485
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz",
4486
+ "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==",
4487
+ "hasInstallScript": true,
4488
+ "dependencies": {
4489
+ "@protobufjs/aspromise": "^1.1.2",
4490
+ "@protobufjs/base64": "^1.1.2",
4491
+ "@protobufjs/codegen": "^2.0.4",
4492
+ "@protobufjs/eventemitter": "^1.1.0",
4493
+ "@protobufjs/fetch": "^1.1.0",
4494
+ "@protobufjs/float": "^1.0.2",
4495
+ "@protobufjs/inquire": "^1.1.0",
4496
+ "@protobufjs/path": "^1.1.2",
4497
+ "@protobufjs/pool": "^1.1.0",
4498
+ "@protobufjs/utf8": "^1.1.0",
4499
+ "@types/long": "^4.0.1",
4500
+ "@types/node": ">=13.7.0",
4501
+ "long": "^4.0.0"
4502
+ },
4503
+ "bin": {
4504
+ "pbjs": "bin/pbjs",
4505
+ "pbts": "bin/pbts"
4506
+ }
4507
+ },
4508
  "node_modules/psl": {
4509
  "version": "1.9.0",
4510
  "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
4511
  "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag=="
4512
  },
4513
+ "node_modules/pump": {
4514
+ "version": "3.0.0",
4515
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
4516
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
4517
+ "dependencies": {
4518
+ "end-of-stream": "^1.1.0",
4519
+ "once": "^1.3.1"
4520
+ }
4521
+ },
4522
  "node_modules/punycode": {
4523
  "version": "2.3.0",
4524
  "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
 
4560
  }
4561
  ]
4562
  },
4563
+ "node_modules/queue-tick": {
4564
+ "version": "1.0.1",
4565
+ "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
4566
+ "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag=="
4567
+ },
4568
  "node_modules/quick-lru": {
4569
  "version": "5.1.1",
4570
  "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
 
4576
  "url": "https://github.com/sponsors/sindresorhus"
4577
  }
4578
  },
4579
+ "node_modules/rc": {
4580
+ "version": "1.2.8",
4581
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
4582
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
4583
+ "dependencies": {
4584
+ "deep-extend": "^0.6.0",
4585
+ "ini": "~1.3.0",
4586
+ "minimist": "^1.2.0",
4587
+ "strip-json-comments": "~2.0.1"
4588
+ },
4589
+ "bin": {
4590
+ "rc": "cli.js"
4591
+ }
4592
+ },
4593
+ "node_modules/rc/node_modules/strip-json-comments": {
4594
+ "version": "2.0.1",
4595
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
4596
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
4597
+ "engines": {
4598
+ "node": ">=0.10.0"
4599
+ }
4600
+ },
4601
  "node_modules/react-is": {
4602
  "version": "17.0.2",
4603
  "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
 
4612
  "pify": "^2.3.0"
4613
  }
4614
  },
4615
+ "node_modules/readable-stream": {
4616
+ "version": "3.6.2",
4617
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
4618
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
4619
+ "dependencies": {
4620
+ "inherits": "^2.0.3",
4621
+ "string_decoder": "^1.1.1",
4622
+ "util-deprecate": "^1.0.1"
4623
+ },
4624
+ "engines": {
4625
+ "node": ">= 6"
4626
+ }
4627
+ },
4628
  "node_modules/readdirp": {
4629
  "version": "3.6.0",
4630
  "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
 
4757
  "node": ">=6"
4758
  }
4759
  },
4760
+ "node_modules/safe-buffer": {
4761
+ "version": "5.2.1",
4762
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
4763
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
4764
+ "funding": [
4765
+ {
4766
+ "type": "github",
4767
+ "url": "https://github.com/sponsors/feross"
4768
+ },
4769
+ {
4770
+ "type": "patreon",
4771
+ "url": "https://www.patreon.com/feross"
4772
+ },
4773
+ {
4774
+ "type": "consulting",
4775
+ "url": "https://feross.org/support"
4776
+ }
4777
+ ]
4778
+ },
4779
  "node_modules/safer-buffer": {
4780
  "version": "2.1.2",
4781
  "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
 
4829
  }
4830
  },
4831
  "node_modules/semver": {
4832
+ "version": "7.5.4",
4833
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
4834
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
 
4835
  "dependencies": {
4836
  "lru-cache": "^6.0.0"
4837
  },
 
4856
  "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==",
4857
  "dev": true
4858
  },
4859
+ "node_modules/sharp": {
4860
+ "version": "0.32.5",
4861
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.5.tgz",
4862
+ "integrity": "sha512-0dap3iysgDkNaPOaOL4X/0akdu0ma62GcdC2NBQ+93eqpePdDdr2/LM0sFdDSMmN7yS+odyZtPsb7tx/cYBKnQ==",
4863
+ "hasInstallScript": true,
4864
+ "dependencies": {
4865
+ "color": "^4.2.3",
4866
+ "detect-libc": "^2.0.2",
4867
+ "node-addon-api": "^6.1.0",
4868
+ "prebuild-install": "^7.1.1",
4869
+ "semver": "^7.5.4",
4870
+ "simple-get": "^4.0.1",
4871
+ "tar-fs": "^3.0.4",
4872
+ "tunnel-agent": "^0.6.0"
4873
+ },
4874
+ "engines": {
4875
+ "node": ">=14.15.0"
4876
+ },
4877
+ "funding": {
4878
+ "url": "https://opencollective.com/libvips"
4879
+ }
4880
+ },
4881
  "node_modules/shebang-command": {
4882
  "version": "2.0.0",
4883
  "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
 
4911
  "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
4912
  "dev": true
4913
  },
4914
+ "node_modules/simple-concat": {
4915
+ "version": "1.0.1",
4916
+ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
4917
+ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
4918
+ "funding": [
4919
+ {
4920
+ "type": "github",
4921
+ "url": "https://github.com/sponsors/feross"
4922
+ },
4923
+ {
4924
+ "type": "patreon",
4925
+ "url": "https://www.patreon.com/feross"
4926
+ },
4927
+ {
4928
+ "type": "consulting",
4929
+ "url": "https://feross.org/support"
4930
+ }
4931
+ ]
4932
+ },
4933
+ "node_modules/simple-get": {
4934
+ "version": "4.0.1",
4935
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
4936
+ "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
4937
+ "funding": [
4938
+ {
4939
+ "type": "github",
4940
+ "url": "https://github.com/sponsors/feross"
4941
+ },
4942
+ {
4943
+ "type": "patreon",
4944
+ "url": "https://www.patreon.com/feross"
4945
+ },
4946
+ {
4947
+ "type": "consulting",
4948
+ "url": "https://feross.org/support"
4949
+ }
4950
+ ],
4951
+ "dependencies": {
4952
+ "decompress-response": "^6.0.0",
4953
+ "once": "^1.3.1",
4954
+ "simple-concat": "^1.0.0"
4955
+ }
4956
+ },
4957
+ "node_modules/simple-swizzle": {
4958
+ "version": "0.2.2",
4959
+ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
4960
+ "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
4961
+ "dependencies": {
4962
+ "is-arrayish": "^0.3.1"
4963
+ }
4964
+ },
4965
  "node_modules/sirv": {
4966
  "version": "2.0.2",
4967
  "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.2.tgz",
 
5072
  "node": ">=10.0.0"
5073
  }
5074
  },
5075
+ "node_modules/streamx": {
5076
+ "version": "2.15.1",
5077
+ "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.1.tgz",
5078
+ "integrity": "sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==",
5079
+ "dependencies": {
5080
+ "fast-fifo": "^1.1.0",
5081
+ "queue-tick": "^1.0.1"
5082
+ }
5083
+ },
5084
+ "node_modules/string_decoder": {
5085
+ "version": "1.3.0",
5086
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
5087
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
5088
+ "dependencies": {
5089
+ "safe-buffer": "~5.2.0"
5090
+ }
5091
+ },
5092
  "node_modules/strip-ansi": {
5093
  "version": "6.0.1",
5094
  "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
 
5446
  "postcss": "^8.0.9"
5447
  }
5448
  },
5449
+ "node_modules/tar-fs": {
5450
+ "version": "3.0.4",
5451
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz",
5452
+ "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==",
5453
+ "dependencies": {
5454
+ "mkdirp-classic": "^0.5.2",
5455
+ "pump": "^3.0.0",
5456
+ "tar-stream": "^3.1.5"
5457
+ }
5458
+ },
5459
+ "node_modules/tar-stream": {
5460
+ "version": "3.1.6",
5461
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz",
5462
+ "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==",
5463
+ "dependencies": {
5464
+ "b4a": "^1.6.4",
5465
+ "fast-fifo": "^1.2.0",
5466
+ "streamx": "^2.15.0"
5467
+ }
5468
+ },
5469
  "node_modules/text-table": {
5470
  "version": "0.2.0",
5471
  "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
 
5624
  "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
5625
  "dev": true
5626
  },
5627
+ "node_modules/tunnel-agent": {
5628
+ "version": "0.6.0",
5629
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
5630
+ "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
5631
+ "dependencies": {
5632
+ "safe-buffer": "^5.0.1"
5633
+ },
5634
+ "engines": {
5635
+ "node": "*"
5636
+ }
5637
+ },
5638
  "node_modules/type-check": {
5639
  "version": "0.4.0",
5640
  "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
package.json CHANGED
@@ -42,6 +42,7 @@
42
  "dependencies": {
43
  "@huggingface/hub": "^0.5.1",
44
  "@huggingface/inference": "^2.2.0",
 
45
  "autoprefixer": "^10.4.14",
46
  "aws4fetch": "^1.0.17",
47
  "date-fns": "^2.29.3",
 
42
  "dependencies": {
43
  "@huggingface/hub": "^0.5.1",
44
  "@huggingface/inference": "^2.2.0",
45
+ "@xenova/transformers": "^2.6.0",
46
  "autoprefixer": "^10.4.14",
47
  "aws4fetch": "^1.0.17",
48
  "date-fns": "^2.29.3",
src/lib/buildPrompt.ts CHANGED
@@ -3,6 +3,7 @@ import type { Message } from "./types/Message";
3
  import { collections } from "$lib/server/database";
4
  import { ObjectId } from "mongodb";
5
  import { authCondition } from "./server/auth";
 
6
  /**
7
  * Convert [{user: "assistant", content: "hi"}, {user: "user", content: "hello"}] to:
8
  *
@@ -39,13 +40,16 @@ export async function buildPrompt({
39
 
40
  if (!conversation) throw new Error("Conversation not found");
41
 
42
- if (webSearch.summary) {
 
 
 
43
  messages = [
 
44
  {
45
- from: "assistant",
46
- content: `The following context was found while searching the internet: ${webSearch.summary}`,
47
  },
48
- ...messages,
49
  ];
50
  }
51
  }
 
3
  import { collections } from "$lib/server/database";
4
  import { ObjectId } from "mongodb";
5
  import { authCondition } from "./server/auth";
6
+ import { format } from "date-fns";
7
  /**
8
  * Convert [{user: "assistant", content: "hi"}, {user: "user", content: "hello"}] to:
9
  *
 
40
 
41
  if (!conversation) throw new Error("Conversation not found");
42
 
43
+ if (webSearch.context) {
44
+ const messagesWithoutLastUsrMsg = messages.slice(0, -1);
45
+ const lastUserMsg = messages.slice(-1)[0];
46
+ const currentDate = format(new Date(), "MMMM d, yyyy");
47
  messages = [
48
+ ...messagesWithoutLastUsrMsg,
49
  {
50
+ from: "user",
51
+ content: `Please answer my question "${lastUserMsg.content}" using the supplied context below (paragrpahs from various websites). For the context, today is ${currentDate}: \n=====================\n${webSearch.context}\n=====================\nSo my question is "${lastUserMsg.content}"`,
52
  },
 
53
  ];
54
  }
55
  }
src/lib/components/chat/ChatMessage.svelte CHANGED
@@ -13,7 +13,7 @@
13
  import CarbonThumbsDown from "~icons/carbon/thumbs-down";
14
  import { PUBLIC_SEP_TOKEN } from "$lib/constants/publicSepToken";
15
  import type { Model } from "$lib/types/Model";
16
- import type { WebSearchMessage } from "$lib/types/WebSearch";
17
 
18
  import OpenWebSearchResults from "../OpenWebSearchResults.svelte";
19
 
@@ -100,6 +100,10 @@
100
  $: webSearchIsDone =
101
  webSearchMessages.length > 0 &&
102
  webSearchMessages[webSearchMessages.length - 1].type === "result";
 
 
 
 
103
  </script>
104
 
105
  {#if message.from === "assistant"}
@@ -140,6 +144,26 @@
140
  {/if}
141
  {/each}
142
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  </div>
144
  {#if isAuthor && !loading && message.content}
145
  <div
 
13
  import CarbonThumbsDown from "~icons/carbon/thumbs-down";
14
  import { PUBLIC_SEP_TOKEN } from "$lib/constants/publicSepToken";
15
  import type { Model } from "$lib/types/Model";
16
+ import type { WebSearchMessage, WebSearchMessageSources } from "$lib/types/WebSearch";
17
 
18
  import OpenWebSearchResults from "../OpenWebSearchResults.svelte";
19
 
 
100
  $: webSearchIsDone =
101
  webSearchMessages.length > 0 &&
102
  webSearchMessages[webSearchMessages.length - 1].type === "result";
103
+
104
+ $: webSearchSources = (
105
+ webSearchMessages.filter(({ type }) => type === "sources")?.[0] as WebSearchMessageSources
106
+ )?.sources;
107
  </script>
108
 
109
  {#if message.from === "assistant"}
 
144
  {/if}
145
  {/each}
146
  </div>
147
+ <!-- Web Search sources -->
148
+ {#if webSearchSources?.length}
149
+ <div class="mt-4 flex flex-wrap items-center gap-x-2 gap-y-1.5 text-sm">
150
+ <div class="text-gray-400">Sources:</div>
151
+ {#each webSearchSources as { link, title, hostname }}
152
+ <a
153
+ class="flex items-center gap-2 whitespace-nowrap rounded-lg border bg-white px-2 py-1.5 leading-none hover:border-gray-300 dark:border-gray-800 dark:bg-gray-900 dark:hover:border-gray-700"
154
+ href={link}
155
+ target="_blank"
156
+ >
157
+ <img
158
+ class="h-3.5 w-3.5 rounded"
159
+ src="https://www.google.com/s2/favicons?sz=64&domain_url={hostname}"
160
+ alt="{title} favicon"
161
+ />
162
+ <div>{hostname.replace(/^www\./, "")}</div>
163
+ </a>
164
+ {/each}
165
+ </div>
166
+ {/if}
167
  </div>
168
  {#if isAuthor && !loading && message.content}
169
  <div
src/lib/server/generateFromDefaultEndpoint.ts CHANGED
@@ -29,7 +29,7 @@ export async function generateFromDefaultEndpoint(
29
 
30
  if (randomEndpoint.host === "sagemaker") {
31
  const requestParams = JSON.stringify({
32
- ...newParameters,
33
  inputs: prompt,
34
  });
35
 
@@ -56,7 +56,7 @@ export async function generateFromDefaultEndpoint(
56
  },
57
  method: "POST",
58
  body: JSON.stringify({
59
- ...newParameters,
60
  inputs: prompt,
61
  }),
62
  signal: abortController.signal,
 
29
 
30
  if (randomEndpoint.host === "sagemaker") {
31
  const requestParams = JSON.stringify({
32
+ parameters: newParameters,
33
  inputs: prompt,
34
  });
35
 
 
56
  },
57
  method: "POST",
58
  body: JSON.stringify({
59
+ parameters: newParameters,
60
  inputs: prompt,
61
  }),
62
  signal: abortController.signal,
src/lib/server/models.ts CHANGED
@@ -1,9 +1,5 @@
1
  import { HF_ACCESS_TOKEN, MODELS, OLD_MODELS } from "$env/static/private";
2
- import type {
3
- ChatTemplateInput,
4
- WebSearchQueryTemplateInput,
5
- WebSearchSummaryTemplateInput,
6
- } from "$lib/types/Template";
7
  import { compileTemplate } from "$lib/utils/template";
8
  import { z } from "zod";
9
 
@@ -71,28 +67,14 @@ const modelsRaw = z
71
  "{{/each}}" +
72
  "{{assistantMessageToken}}"
73
  ),
74
- webSearchSummaryPromptTemplate: z
75
- .string()
76
- .default(
77
- "{{userMessageToken}}{{answer}}{{userMessageEndToken}}" +
78
- "{{userMessageToken}}" +
79
- "The text above should be summarized to best answer the query: {{query}}." +
80
- "{{userMessageEndToken}}" +
81
- "{{assistantMessageToken}}Summary: "
82
- ),
83
  webSearchQueryPromptTemplate: z
84
  .string()
85
  .default(
86
  "{{userMessageToken}}" +
87
- "The following messages were written by a user, trying to answer a question." +
 
88
  "{{userMessageEndToken}}" +
89
- "{{#each messages}}" +
90
- "{{#ifUser}}{{@root.userMessageToken}}{{content}}{{@root.userMessageEndToken}}{{/ifUser}}" +
91
- "{{/each}}" +
92
- "{{userMessageToken}}" +
93
- "What plain-text english sentence would you input into Google to answer the last question? Answer with a short (10 words max) simple sentence." +
94
- "{{userMessageEndToken}}" +
95
- "{{assistantMessageToken}}Query: "
96
  ),
97
  promptExamples: z
98
  .array(
@@ -122,10 +104,6 @@ export const models = await Promise.all(
122
  userMessageEndToken: m?.userMessageEndToken || m?.messageEndToken,
123
  assistantMessageEndToken: m?.assistantMessageEndToken || m?.messageEndToken,
124
  chatPromptRender: compileTemplate<ChatTemplateInput>(m.chatPromptTemplate, m),
125
- webSearchSummaryPromptRender: compileTemplate<WebSearchSummaryTemplateInput>(
126
- m.webSearchSummaryPromptTemplate,
127
- m
128
- ),
129
  webSearchQueryPromptRender: compileTemplate<WebSearchQueryTemplateInput>(
130
  m.webSearchQueryPromptTemplate,
131
  m
 
1
  import { HF_ACCESS_TOKEN, MODELS, OLD_MODELS } from "$env/static/private";
2
+ import type { ChatTemplateInput, WebSearchQueryTemplateInput } from "$lib/types/Template";
 
 
 
 
3
  import { compileTemplate } from "$lib/utils/template";
4
  import { z } from "zod";
5
 
 
67
  "{{/each}}" +
68
  "{{assistantMessageToken}}"
69
  ),
 
 
 
 
 
 
 
 
 
70
  webSearchQueryPromptTemplate: z
71
  .string()
72
  .default(
73
  "{{userMessageToken}}" +
74
+ 'My question is: "{{message.content}}". ' +
75
+ "Based on the conversation history (my previous questions are: {{previousMessages}}), give me an appropriate query to answer my question for google search. You should not say more than query. You should not say any words except the query. For the context, today is {{currentDate}}" +
76
  "{{userMessageEndToken}}" +
77
+ "{{assistantMessageToken}}"
 
 
 
 
 
 
78
  ),
79
  promptExamples: z
80
  .array(
 
104
  userMessageEndToken: m?.userMessageEndToken || m?.messageEndToken,
105
  assistantMessageEndToken: m?.assistantMessageEndToken || m?.messageEndToken,
106
  chatPromptRender: compileTemplate<ChatTemplateInput>(m.chatPromptTemplate, m),
 
 
 
 
107
  webSearchQueryPromptRender: compileTemplate<WebSearchQueryTemplateInput>(
108
  m.webSearchQueryPromptTemplate,
109
  m
src/lib/server/websearch/generateQuery.ts CHANGED
@@ -1,12 +1,45 @@
1
  import type { Message } from "$lib/types/Message";
 
2
  import { generateFromDefaultEndpoint } from "../generateFromDefaultEndpoint";
3
  import { defaultModel } from "../models";
4
 
5
  export async function generateQuery(messages: Message[]) {
6
- const promptSearchQuery = defaultModel.webSearchQueryPromptRender({ messages });
 
 
 
 
 
 
 
 
7
  const searchQuery = await generateFromDefaultEndpoint(promptSearchQuery).then((query) => {
8
- const arr = query.split(/\r?\n/);
9
- return arr[0].length > 0 ? arr[0] : arr[1];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  });
11
 
12
  return searchQuery;
 
1
  import type { Message } from "$lib/types/Message";
2
+ import { format } from "date-fns";
3
  import { generateFromDefaultEndpoint } from "../generateFromDefaultEndpoint";
4
  import { defaultModel } from "../models";
5
 
6
  export async function generateQuery(messages: Message[]) {
7
+ const currentDate = format(new Date(), "MMMM d, yyyy");
8
+ const userMessages = messages.filter(({ from }) => from === "user");
9
+ const previousUserMessages = userMessages.slice(0, -1);
10
+ const lastMessage = userMessages.slice(-1)[0];
11
+ const promptSearchQuery = defaultModel.webSearchQueryPromptRender({
12
+ message: lastMessage,
13
+ previousMessages: previousUserMessages.map(({ content }) => content).join(" "),
14
+ currentDate,
15
+ });
16
  const searchQuery = await generateFromDefaultEndpoint(promptSearchQuery).then((query) => {
17
+ // example of generating google query:
18
+ // case 1
19
+ // user: tell me what happened yesterday
20
+ // LLM: google query is "news september 12, 2023"
21
+ // the regex below will try to capture the last "phrase" (i.e. words between quotes or double quotes or ticks)
22
+ // in this case, it is "news september 12, 2023"
23
+ // if there is no "phrase", we will just use the user query, which was "tell me what happened yesterday"
24
+ const regexLastPhrase = /("|'|`)((?:(?!\1).)+)\1$/;
25
+ let match = query.match(regexLastPhrase);
26
+ if (match) {
27
+ return match[2];
28
+ }
29
+
30
+ // case 2
31
+ // user: tell me what happened yesterday
32
+ // LLM: Here is a query: news september 12, 2023
33
+ // the regex below will try to capture the last sentences starting from :
34
+ // in this case, it is "news september 12, 2023"
35
+ // if there is no math, we will just use the user query, which was "tell me what happened yesterday"
36
+ const regexColon = /:\s(.*)$/;
37
+ match = query.match(regexColon);
38
+ if (match) {
39
+ return match[1];
40
+ }
41
+
42
+ return lastMessage.content;
43
  });
44
 
45
  return searchQuery;
src/lib/server/websearch/parseWeb.ts CHANGED
@@ -1,32 +1,5 @@
1
  import { JSDOM, VirtualConsole } from "jsdom";
2
 
3
- function removeTags(node: Node) {
4
- if (node.hasChildNodes()) {
5
- node.childNodes.forEach((childNode) => {
6
- if (node.nodeName === "SCRIPT" || node.nodeName === "STYLE") {
7
- node.removeChild(childNode);
8
- } else {
9
- removeTags(childNode);
10
- }
11
- });
12
- }
13
- }
14
- function naiveInnerText(node: Node): string {
15
- const Node = node; // We need Node(DOM's Node) for the constants, but Node doesn't exist in the nodejs global space, and any Node instance references the constants through the prototype chain
16
- return [...node.childNodes]
17
- .map((childNode) => {
18
- switch (childNode.nodeType) {
19
- case Node.TEXT_NODE:
20
- return node.textContent;
21
- case Node.ELEMENT_NODE:
22
- return naiveInnerText(childNode);
23
- default:
24
- return "";
25
- }
26
- })
27
- .join("\n");
28
- }
29
-
30
  export async function parseWeb(url: string) {
31
  const abortController = new AbortController();
32
  setTimeout(() => abortController.abort(), 10000);
@@ -44,13 +17,16 @@ export async function parseWeb(url: string) {
44
  virtualConsole,
45
  });
46
 
47
- const body = dom.window.document.querySelector("body");
48
- if (!body) throw new Error("body of the webpage is null");
49
-
50
- removeTags(body);
 
 
 
51
 
52
- // recursively extract text content from the body and then remove newlines and multiple spaces
53
- const text = (naiveInnerText(body) ?? "").replace(/ {2}|\r\n|\n|\r/gm, "");
54
 
55
  return text;
56
  }
 
1
  import { JSDOM, VirtualConsole } from "jsdom";
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  export async function parseWeb(url: string) {
4
  const abortController = new AbortController();
5
  setTimeout(() => abortController.abort(), 10000);
 
17
  virtualConsole,
18
  });
19
 
20
+ const { document } = dom.window;
21
+ const textElTags = "p";
22
+ const paragraphs = document.querySelectorAll(textElTags);
23
+ if (!paragraphs.length) {
24
+ throw new Error(`webpage doesn't have any "${textElTags}" element`);
25
+ }
26
+ const paragraphTexts = Array.from(paragraphs).map((p) => p.textContent);
27
 
28
+ // combine text contents from paragraphs and then remove newlines and multiple spaces
29
+ const text = paragraphTexts.join(" ").replace(/ {2}|\r\n|\n|\r/gm, "");
30
 
31
  return text;
32
  }
src/lib/server/websearch/searchWeb.ts CHANGED
@@ -42,8 +42,6 @@ export async function searchWebSerper(query: string) {
42
 
43
  return {
44
  organic_results: data["organic"] ?? [],
45
- knowledge_graph: data["knowledgeGraph"] ?? null,
46
- answer_box: data["answerBox"] ?? null,
47
  };
48
  }
49
 
 
42
 
43
  return {
44
  organic_results: data["organic"] ?? [],
 
 
45
  };
46
  }
47
 
src/lib/server/websearch/sentenceSimilarity.ts ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import type { Tensor } from "@xenova/transformers";
2
+ import { pipeline, dot } from "@xenova/transformers";
3
+
4
+ // see here: https://github.com/nmslib/hnswlib/blob/359b2ba87358224963986f709e593d799064ace6/README.md?plain=1#L34
5
+ function innerProduct(tensor1: Tensor, tensor2: Tensor) {
6
+ return 1.0 - dot(tensor1.data, tensor2.data);
7
+ }
8
+
9
+ const extractor = await pipeline("feature-extraction", "Xenova/e5-small-v2");
10
+
11
+ export async function findSimilarSentences(
12
+ query: string,
13
+ sentences: string[],
14
+ { topK = 5 }: { topK: number }
15
+ ) {
16
+ // this preprocessing step is suggested for e5-small-v2 model
17
+ // see more: https://huggingface.co/intfloat/e5-small-v2/blob/main/README.md?code=true#L2631
18
+ const input = [`query: ${query}`, ...sentences.map((s) => `passage: ${s}`)];
19
+ const output: Tensor = await extractor(input, { pooling: "mean", normalize: true });
20
+
21
+ const queryTensor: Tensor = output[0];
22
+ const sentencesTensor: Tensor = output.slice([1, input.length - 1]);
23
+
24
+ const distancesFromQuery: { distance: number; index: number }[] = [...sentencesTensor].map(
25
+ (sentenceTensor: Tensor, index: number) => {
26
+ return {
27
+ distance: innerProduct(queryTensor, sentenceTensor),
28
+ index: index,
29
+ };
30
+ }
31
+ );
32
+
33
+ distancesFromQuery.sort((a, b) => {
34
+ return a.distance - b.distance;
35
+ });
36
+
37
+ // Return the indexes of the closest topK sentences
38
+ return distancesFromQuery.slice(0, topK).map((item) => item.index);
39
+ }
src/lib/server/websearch/summarizeWeb.ts DELETED
@@ -1,39 +0,0 @@
1
- import { HF_ACCESS_TOKEN } from "$env/static/private";
2
- import { HfInference } from "@huggingface/inference";
3
- import { defaultModel } from "$lib/server/models";
4
- import type { BackendModel } from "../models";
5
- import { generateFromDefaultEndpoint } from "../generateFromDefaultEndpoint";
6
-
7
- export async function summarizeWeb(content: string, query: string, model: BackendModel) {
8
- // if HF_ACCESS_TOKEN is set, we use a HF dedicated endpoint for summarization
9
- try {
10
- if (HF_ACCESS_TOKEN) {
11
- const summary = (
12
- await new HfInference(HF_ACCESS_TOKEN).summarization({
13
- model: "facebook/bart-large-cnn",
14
- inputs: content,
15
- parameters: {
16
- max_length: 512,
17
- },
18
- })
19
- ).summary_text;
20
- return summary;
21
- }
22
- } catch (e) {
23
- console.log(e);
24
- }
25
-
26
- // else we use the LLM to generate a summary
27
- const summaryPrompt = defaultModel.webSearchSummaryPromptRender({
28
- answer: content
29
- .split(" ")
30
- .slice(0, model.parameters?.truncate ?? 0)
31
- .join(" "),
32
- query: query,
33
- });
34
- const summary = await generateFromDefaultEndpoint(summaryPrompt).then((txt: string) =>
35
- txt.trim()
36
- );
37
-
38
- return summary;
39
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/types/Template.ts CHANGED
@@ -13,11 +13,8 @@ export type ChatTemplateInput = {
13
  preprompt?: string;
14
  };
15
 
16
- export type WebSearchSummaryTemplateInput = {
17
- answer: string;
18
- query: string;
19
- };
20
-
21
  export type WebSearchQueryTemplateInput = {
22
- messages: Pick<Message, "from" | "content">[];
 
 
23
  };
 
13
  preprompt?: string;
14
  };
15
 
 
 
 
 
 
16
  export type WebSearchQueryTemplateInput = {
17
+ message: Pick<Message, "from" | "content">;
18
+ previousMessages: string;
19
+ currentDate: string;
20
  };
src/lib/types/WebSearch.ts CHANGED
@@ -2,6 +2,12 @@ import type { ObjectId } from "mongodb";
2
  import type { Conversation } from "./Conversation";
3
  import type { Timestamps } from "./Timestamps";
4
 
 
 
 
 
 
 
5
  export interface WebSearch extends Timestamps {
6
  _id: ObjectId;
7
 
@@ -10,10 +16,9 @@ export interface WebSearch extends Timestamps {
10
  prompt: string;
11
 
12
  searchQuery: string;
13
- results: string[];
14
- knowledgeGraph: string;
15
- answerBox: string;
16
- summary: string;
17
 
18
  messages: WebSearchMessage[];
19
  }
@@ -35,7 +40,13 @@ export type WebSearchMessageResult = {
35
  id: string;
36
  };
37
 
 
 
 
 
 
38
  export type WebSearchMessage =
39
  | WebSearchMessageUpdate
40
  | WebSearchMessageResult
41
- | WebSearchMessageError;
 
 
2
  import type { Conversation } from "./Conversation";
3
  import type { Timestamps } from "./Timestamps";
4
 
5
+ export interface WebSearchSource {
6
+ title: string;
7
+ link: string;
8
+ hostname: string;
9
+ }
10
+
11
  export interface WebSearch extends Timestamps {
12
  _id: ObjectId;
13
 
 
16
  prompt: string;
17
 
18
  searchQuery: string;
19
+ results: WebSearchSource[];
20
+ context: string;
21
+ contextSources: WebSearchSource[];
 
22
 
23
  messages: WebSearchMessage[];
24
  }
 
40
  id: string;
41
  };
42
 
43
+ export type WebSearchMessageSources = {
44
+ type: "sources";
45
+ sources: WebSearchSource[];
46
+ };
47
+
48
  export type WebSearchMessage =
49
  | WebSearchMessageUpdate
50
  | WebSearchMessageResult
51
+ | WebSearchMessageError
52
+ | WebSearchMessageSources;
src/lib/utils/chunk.ts ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Chunk array into arrays of length at most `chunkSize`
3
+ *
4
+ * @param chunkSize must be greater than or equal to 1
5
+ */
6
+ export function chunk<T extends unknown[] | string>(arr: T, chunkSize: number): T[] {
7
+ if (isNaN(chunkSize) || chunkSize < 1) {
8
+ throw new RangeError("Invalid chunk size: " + chunkSize);
9
+ }
10
+
11
+ if (!arr.length) {
12
+ return [];
13
+ }
14
+
15
+ /// Small optimization to not chunk buffers unless needed
16
+ if (arr.length <= chunkSize) {
17
+ return [arr];
18
+ }
19
+
20
+ return range(Math.ceil(arr.length / chunkSize)).map((i) => {
21
+ return arr.slice(i * chunkSize, (i + 1) * chunkSize);
22
+ }) as T[];
23
+ }
24
+
25
+ function range(n: number, b?: number): number[] {
26
+ return b
27
+ ? Array(b - n)
28
+ .fill(0)
29
+ .map((_, i) => n + i)
30
+ : Array(n)
31
+ .fill(0)
32
+ .map((_, i) => i);
33
+ }
src/routes/conversation/[id]/+page.server.ts CHANGED
@@ -2,7 +2,7 @@ import { collections } from "$lib/server/database";
2
  import { ObjectId } from "mongodb";
3
  import { error } from "@sveltejs/kit";
4
  import { authCondition } from "$lib/server/auth";
5
- import type { WebSearchMessageResult } from "$lib/types/WebSearch";
6
  import { UrlDependency } from "$lib/types/UrlDependency";
7
 
8
  export const load = async ({ params, depends, locals }) => {
@@ -39,7 +39,11 @@ export const load = async ({ params, depends, locals }) => {
39
  const searches = Object.fromEntries(
40
  results.map((x) => [
41
  x._id.toString(),
42
- [...x.messages, { type: "result", id: x._id.toString() } satisfies WebSearchMessageResult],
 
 
 
 
43
  ])
44
  );
45
 
 
2
  import { ObjectId } from "mongodb";
3
  import { error } from "@sveltejs/kit";
4
  import { authCondition } from "$lib/server/auth";
5
+ import type { WebSearchMessageResult, WebSearchMessageSources } from "$lib/types/WebSearch";
6
  import { UrlDependency } from "$lib/types/UrlDependency";
7
 
8
  export const load = async ({ params, depends, locals }) => {
 
39
  const searches = Object.fromEntries(
40
  results.map((x) => [
41
  x._id.toString(),
42
+ [
43
+ ...x.messages,
44
+ { type: "sources", sources: x.contextSources ?? [] } satisfies WebSearchMessageSources,
45
+ { type: "result", id: x._id.toString() } satisfies WebSearchMessageResult,
46
+ ],
47
  ])
48
  );
49
 
src/routes/conversation/[id]/+page.svelte CHANGED
@@ -184,6 +184,7 @@
184
  if (lastSearchMessage.type === "result") {
185
  searchResponseId = lastSearchMessage.id;
186
  reader.cancel();
 
187
  return;
188
  }
189
  })
 
184
  if (lastSearchMessage.type === "result") {
185
  searchResponseId = lastSearchMessage.id;
186
  reader.cancel();
187
+ data.searches[searchResponseId] = [...webSearchMessages];
188
  return;
189
  }
190
  })
src/routes/conversation/[id]/web-search/+server.ts CHANGED
@@ -1,31 +1,22 @@
1
  import { authCondition } from "$lib/server/auth";
2
  import { collections } from "$lib/server/database";
3
- import { defaultModel } from "$lib/server/models";
4
  import { searchWeb } from "$lib/server/websearch/searchWeb";
5
  import type { Message } from "$lib/types/Message";
6
  import { error } from "@sveltejs/kit";
7
  import { ObjectId } from "mongodb";
8
  import { z } from "zod";
9
- import type { WebSearch } from "$lib/types/WebSearch";
10
  import { generateQuery } from "$lib/server/websearch/generateQuery";
11
  import { parseWeb } from "$lib/server/websearch/parseWeb";
12
- import { summarizeWeb } from "$lib/server/websearch/summarizeWeb";
 
13
  import { RATE_LIMIT } from "$env/static/private";
14
  import { ERROR_MESSAGES } from "$lib/stores/errors.js";
15
 
16
- interface GenericObject {
17
- [key: string]: GenericObject | unknown;
18
- }
19
 
20
- function removeLinks(obj: GenericObject) {
21
- for (const prop in obj) {
22
- if (prop.endsWith("link")) delete obj[prop];
23
- else if (typeof obj[prop] === "object") removeLinks(obj[prop] as GenericObject);
24
- }
25
- return obj;
26
- }
27
  export async function GET({ params, locals, url, getClientAddress }) {
28
- const model = defaultModel;
29
  const convId = new ObjectId(params.id);
30
  const searchId = new ObjectId();
31
 
@@ -68,10 +59,9 @@ export async function GET({ params, locals, url, getClientAddress }) {
68
  convId: convId,
69
  prompt: prompt,
70
  searchQuery: "",
71
- knowledgeGraph: "",
72
- answerBox: "",
73
  results: [],
74
- summary: "",
 
75
  messages: [],
76
  createdAt: new Date(),
77
  updatedAt: new Date(),
@@ -92,45 +82,62 @@ export async function GET({ params, locals, url, getClientAddress }) {
92
 
93
  appendUpdate("Searching Google", [webSearch.searchQuery]);
94
  const results = await searchWeb(webSearch.searchQuery);
95
-
96
- let text = "";
97
  webSearch.results =
98
  (results.organic_results &&
99
- results.organic_results.map((el: { link: string }) => el.link)) ??
 
 
 
 
100
  [];
101
-
102
- if (results.answer_box) {
103
- // if google returns an answer box, we use it
104
- webSearch.answerBox = JSON.stringify(removeLinks(results.answer_box));
105
- text = webSearch.answerBox;
106
- appendUpdate("Found a Google answer box");
107
- } else if (results.knowledge_graph) {
108
- // if google returns a knowledge graph, we use it
109
- webSearch.knowledgeGraph = JSON.stringify(removeLinks(results.knowledge_graph));
110
- text = webSearch.knowledgeGraph;
111
- appendUpdate("Found a Google knowledge page");
112
- } else if (webSearch.results.length > 0) {
113
- let tries = 0;
114
-
115
- while (!text && tries < 3) {
116
- const searchUrl = webSearch.results[tries];
117
- appendUpdate("Browsing result", [JSON.stringify(searchUrl)]);
118
  try {
119
- text = await parseWeb(searchUrl);
120
- if (!text) throw new Error("text of the webpage is null");
121
  } catch (e) {
122
- appendUpdate("Error parsing webpage", [], "error");
123
- tries++;
124
  }
 
 
 
 
 
 
 
 
 
125
  }
126
- if (!text) throw new Error("No text found on the first 3 results");
127
  } else {
128
  throw new Error("No results found for this search query");
129
  }
130
 
131
- appendUpdate("Creating summary");
132
- webSearch.summary = await summarizeWeb(text, webSearch.searchQuery, model);
133
- appendUpdate("Injecting summary", [JSON.stringify(webSearch.summary)]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  } catch (searchError) {
135
  if (searchError instanceof Error) {
136
  webSearch.messages.push({
@@ -142,6 +149,10 @@ export async function GET({ params, locals, url, getClientAddress }) {
142
  }
143
 
144
  const res = await collections.webSearches.insertOne(webSearch);
 
 
 
 
145
  webSearch.messages.push({
146
  type: "result",
147
  id: res.insertedId.toString(),
 
1
  import { authCondition } from "$lib/server/auth";
2
  import { collections } from "$lib/server/database";
 
3
  import { searchWeb } from "$lib/server/websearch/searchWeb";
4
  import type { Message } from "$lib/types/Message";
5
  import { error } from "@sveltejs/kit";
6
  import { ObjectId } from "mongodb";
7
  import { z } from "zod";
8
+ import type { WebSearch, WebSearchSource } from "$lib/types/WebSearch";
9
  import { generateQuery } from "$lib/server/websearch/generateQuery";
10
  import { parseWeb } from "$lib/server/websearch/parseWeb";
11
+ import { chunk } from "$lib/utils/chunk";
12
+ import { findSimilarSentences } from "$lib/server/websearch/sentenceSimilarity";
13
  import { RATE_LIMIT } from "$env/static/private";
14
  import { ERROR_MESSAGES } from "$lib/stores/errors.js";
15
 
16
+ const MAX_N_PAGES_SCRAPE = 10 as const;
17
+ const MAX_N_PAGES_EMBED = 5 as const;
 
18
 
 
 
 
 
 
 
 
19
  export async function GET({ params, locals, url, getClientAddress }) {
 
20
  const convId = new ObjectId(params.id);
21
  const searchId = new ObjectId();
22
 
 
59
  convId: convId,
60
  prompt: prompt,
61
  searchQuery: "",
 
 
62
  results: [],
63
+ context: "",
64
+ contextSources: [],
65
  messages: [],
66
  createdAt: new Date(),
67
  updatedAt: new Date(),
 
82
 
83
  appendUpdate("Searching Google", [webSearch.searchQuery]);
84
  const results = await searchWeb(webSearch.searchQuery);
 
 
85
  webSearch.results =
86
  (results.organic_results &&
87
+ results.organic_results.map((el: { title: string; link: string }) => {
88
+ const { title, link } = el;
89
+ const { hostname } = new URL(link);
90
+ return { title, link, hostname };
91
+ })) ??
92
  [];
93
+ webSearch.results = webSearch.results
94
+ .filter(({ link }) => !link.includes("youtube.com")) // filter out youtube links
95
+ .slice(0, MAX_N_PAGES_SCRAPE); // limit to first 10 links only
96
+
97
+ let paragraphChunks: { source: WebSearchSource; text: string }[] = [];
98
+ if (webSearch.results.length > 0) {
99
+ appendUpdate("Browsing results");
100
+ const promises = webSearch.results.map(async (result) => {
101
+ const { link } = result;
102
+ let text = "";
 
 
 
 
 
 
 
103
  try {
104
+ text = await parseWeb(link);
105
+ appendUpdate("Browsing webpage", [link]);
106
  } catch (e) {
107
+ console.error(`Error parsing webpage "${link}"`, e);
 
108
  }
109
+ const CHUNK_CAR_LEN = 512;
110
+ const MAX_N_CHUNKS = 100;
111
+ const texts = chunk(text, CHUNK_CAR_LEN).slice(0, MAX_N_CHUNKS);
112
+ return texts.map((t) => ({ source: result, text: t }));
113
+ });
114
+ const nestedParagraphChunks = (await Promise.all(promises)).slice(0, MAX_N_PAGES_EMBED);
115
+ paragraphChunks = nestedParagraphChunks.flat();
116
+ if (!paragraphChunks.length) {
117
+ throw new Error("No text found on the first 5 results");
118
  }
 
119
  } else {
120
  throw new Error("No results found for this search query");
121
  }
122
 
123
+ appendUpdate("Extracting relevant information");
124
+ const topKClosestParagraphs = 8;
125
+ const texts = paragraphChunks.map(({ text }) => text);
126
+ const indices = await findSimilarSentences(prompt, texts, {
127
+ topK: topKClosestParagraphs,
128
+ });
129
+ webSearch.context = indices.map((idx) => texts[idx]).join("");
130
+
131
+ const usedSources = new Set<string>();
132
+ for (const idx of indices) {
133
+ const { source } = paragraphChunks[idx];
134
+ if (!usedSources.has(source.link)) {
135
+ usedSources.add(source.link);
136
+ webSearch.contextSources.push(source);
137
+ }
138
+ }
139
+
140
+ appendUpdate("Injecting relevant information");
141
  } catch (searchError) {
142
  if (searchError instanceof Error) {
143
  webSearch.messages.push({
 
149
  }
150
 
151
  const res = await collections.webSearches.insertOne(webSearch);
152
+ webSearch.messages.push({
153
+ type: "sources",
154
+ sources: webSearch.contextSources,
155
+ });
156
  webSearch.messages.push({
157
  type: "result",
158
  id: res.insertedId.toString(),
src/routes/r/[id]/+page.server.ts CHANGED
@@ -2,7 +2,7 @@ import type { PageServerLoad } from "./$types";
2
  import { collections } from "$lib/server/database";
3
  import { error } from "@sveltejs/kit";
4
  import { ObjectId } from "mongodb";
5
- import type { WebSearchMessageResult } from "$lib/types/WebSearch";
6
 
7
  export const load: PageServerLoad = async ({ params }) => {
8
  const conversation = await collections.sharedConversations.findOne({
@@ -22,7 +22,11 @@ export const load: PageServerLoad = async ({ params }) => {
22
  const searches = Object.fromEntries(
23
  results.map((x) => [
24
  x._id.toString(),
25
- [...x.messages, { type: "result", id: x._id.toString() } satisfies WebSearchMessageResult],
 
 
 
 
26
  ])
27
  );
28
 
 
2
  import { collections } from "$lib/server/database";
3
  import { error } from "@sveltejs/kit";
4
  import { ObjectId } from "mongodb";
5
+ import type { WebSearchMessageResult, WebSearchMessageSources } from "$lib/types/WebSearch";
6
 
7
  export const load: PageServerLoad = async ({ params }) => {
8
  const conversation = await collections.sharedConversations.findOne({
 
22
  const searches = Object.fromEntries(
23
  results.map((x) => [
24
  x._id.toString(),
25
+ [
26
+ ...x.messages,
27
+ { type: "sources", sources: x.contextSources ?? [] } satisfies WebSearchMessageSources,
28
+ { type: "result", id: x._id.toString() } satisfies WebSearchMessageResult,
29
+ ],
30
  ])
31
  );
32