Compare commits

..

169 Commits

Author SHA1 Message Date
Timothy Jaeryang Baek 506dc0149c Merge pull request #8246 from open-webui/dev
Create and publish Docker images with specific build args / build-main-image (linux/amd64) (push) Waiting to run
Create and publish Docker images with specific build args / build-main-image (linux/arm64) (push) Waiting to run
Create and publish Docker images with specific build args / build-cuda-image (linux/amd64) (push) Waiting to run
Create and publish Docker images with specific build args / build-cuda-image (linux/arm64) (push) Waiting to run
Create and publish Docker images with specific build args / build-ollama-image (linux/amd64) (push) Waiting to run
Create and publish Docker images with specific build args / build-ollama-image (linux/arm64) (push) Waiting to run
Create and publish Docker images with specific build args / merge-main-images (push) Blocked by required conditions
Create and publish Docker images with specific build args / merge-cuda-images (push) Blocked by required conditions
Create and publish Docker images with specific build args / merge-ollama-images (push) Blocked by required conditions
0.5.4
2025-01-05 01:38:42 -08:00
Timothy Jaeryang Baek d651cdb1e4 doc: changelog 2025-01-05 01:38:34 -08:00
Timothy Jaeryang Baek 0c40319371 doc: readme 2025-01-05 01:36:27 -08:00
Timothy Jaeryang Baek c74083ace7 doc: wording 2025-01-05 01:34:31 -08:00
Timothy Jaeryang Baek a3ca39f377 refac 2025-01-05 01:33:12 -08:00
Timothy Jaeryang Baek d11e6e40b1 doc: changelog 2025-01-05 01:32:26 -08:00
Timothy Jaeryang Baek 71bbdf25c6 refac 2025-01-05 01:18:30 -08:00
Timothy Jaeryang Baek f4a595db11 chore: format 2025-01-05 01:12:19 -08:00
Timothy Jaeryang Baek c8be0ee1e0 fix: temp chat json export 2025-01-05 01:10:45 -08:00
Timothy Jaeryang Baek 6ed8c3cb70 Update pyproject.toml 2025-01-05 00:56:32 -08:00
Timothy Jaeryang Baek c434aff1a2 refac: styling 2025-01-05 00:48:41 -08:00
Timothy Jaeryang Baek 3886c82ed0 Merge pull request #8286 from srajangarg/sg
feat: functionality to clone shared chats
2025-01-05 00:45:55 -08:00
Timothy Jaeryang Baek fe59b7f39c refac 2025-01-05 00:44:38 -08:00
Timothy Jaeryang Baek a4132322d9 refac 2025-01-05 00:28:36 -08:00
Timothy Jaeryang Baek d477f73c7e enh: torch mps support 2025-01-05 00:27:44 -08:00
Timothy Jaeryang Baek 614379a427 fix: chat drag and drop 2025-01-04 02:42:26 -08:00
Timothy Jaeryang Baek b4d91b5cb4 refac 2025-01-04 02:34:12 -08:00
Timothy Jaeryang Baek f31e2af349 refac: play sound only in last active tab 2025-01-04 02:30:51 -08:00
Timothy Jaeryang Baek afcbf2cafb enh: native notifications 2025-01-04 02:15:57 -08:00
Timothy Jaeryang Baek c0b93791dc refac 2025-01-04 02:05:42 -08:00
Timothy Jaeryang Baek f3a4d61f81 fix: actions 2025-01-03 21:31:24 -08:00
Timothy Jaeryang Baek 99c3194181 fix: API_KEY_ALLOWED_ENDPOINTS 2025-01-03 13:08:21 -08:00
Timothy Jaeryang Baek 0e805e7dc4 Merge pull request #8298 from jk-f5/feat/pg_vector_size
feat: Allow setting the initial vector length on pgvector document_chunk table
2025-01-03 13:03:53 -08:00
Timothy Jaeryang Baek 226408ffe3 Merge pull request #8309 from yarikoptic/enh-codespell
ci: add codespell support (config, workflow to detect/not fix) and make it fix few typos
2025-01-03 13:02:32 -08:00
Yaroslav Halchenko 8f1953e667 [DATALAD RUNCMD] run codespell throughout fixing few left typos automagically
=== Do not change lines below ===
{
 "chain": [],
 "cmd": "codespell -w",
 "exit": 0,
 "extra_inputs": [],
 "inputs": [],
 "outputs": [],
 "pwd": "."
}
^^^ Do not change lines above ^^^
2025-01-03 15:07:21 -05:00
Yaroslav Halchenko 1a928bc6a4 Add rudimentary codespell config 2025-01-03 15:07:21 -05:00
Yaroslav Halchenko 2e5fbba961 Add github action to codespell main on push and PRs 2025-01-03 15:07:21 -05:00
Jason Kidd 70b74b5217 feat: Allow setting the initial vector length on pgvector document_chunk table 2025-01-03 09:18:59 -08:00
Timothy Jaeryang Baek 996ade9090 refac: notification sound behaviour 2025-01-02 21:39:40 -08:00
Srajan Garg 2444327a47 add functionality to clone shared chats 2025-01-03 00:08:49 -05:00
Timothy Jaeryang Baek 6b3be4bb5b refac: sidebar styling 2025-01-02 20:53:30 -08:00
Timothy Jaeryang Baek b2b56d14cb fix: channel thread 2025-01-02 20:48:50 -08:00
Timothy Jaeryang Baek 3e9c92729d refac: styling 2025-01-02 20:28:01 -08:00
Timothy Jaeryang Baek 0c49553f79 refac: styling 2025-01-02 20:23:07 -08:00
Timothy Jaeryang Baek 66b8166397 refac: styling 2025-01-02 20:19:52 -08:00
Timothy Jaeryang Baek 87ba39df57 fix: moa 2025-01-02 14:32:25 -08:00
Timothy Jaeryang Baek 43964de675 refac: audio input 2025-01-02 02:32:51 -08:00
Timothy Jaeryang Baek fab82b51de fix: generate_queries 2025-01-01 20:13:28 -08:00
Timothy Jaeryang Baek 44716a4cb2 refac: disable ENABLE_REALTIME_CHAT_SAVE by default 2025-01-01 20:12:42 -08:00
Timothy Jaeryang Baek d9fb971196 Merge pull request #8249 from albinvar/main
fix: raise exceptions properly in process_chat_payload
2025-01-01 18:44:42 -08:00
Timothy Jaeryang Baek 51d875a14e Merge pull request #8251 from TiancongLx/dev
i18n: update zh-TW
2025-01-01 18:44:16 -08:00
Tiancong Li 45cc0e6209 i18n: update zh-TW
待翻譯:「Add Reaction」
2025-01-01 21:20:11 +08:00
Albin Varghese c561eb7bbd fix: raise exceptions properly in process_chat_payload 2025-01-01 17:15:06 +05:30
Timothy Jaeryang Baek 00a089b596 doc: readme 2024-12-31 20:37:54 -08:00
Timothy Jaeryang Baek 541fa37c5c Merge pull request #8245 from open-webui/dependabot/pip/backend/dev/peewee-3.17.8
build(deps): bump peewee from 3.17.6 to 3.17.8 in /backend
2024-12-31 20:00:01 -08:00
Timothy Jaeryang Baek 06301aa90d Merge pull request #8243 from open-webui/dependabot/pip/backend/dev/validators-0.34.0
build(deps): bump validators from 0.33.0 to 0.34.0 in /backend
2024-12-31 19:59:45 -08:00
Timothy Jaeryang Baek 55fbc60ad3 Merge pull request #8244 from open-webui/dependabot/pip/backend/dev/flask-3.1.0
build(deps): bump flask from 3.0.3 to 3.1.0 in /backend
2024-12-31 19:59:36 -08:00
Timothy Jaeryang Baek b69941caf4 Merge pull request #8242 from open-webui/dependabot/pip/backend/dev/fpdf2-2.8.2
build(deps): bump fpdf2 from 2.7.9 to 2.8.2 in /backend
2024-12-31 19:59:13 -08:00
Timothy Jaeryang Baek 80600dbe63 Merge pull request #8241 from open-webui/dependabot/pip/backend/dev/pyjwt-crypto--2.10.1
build(deps): bump pyjwt[crypto] from 2.9.0 to 2.10.1 in /backend
2024-12-31 19:58:59 -08:00
Timothy Jaeryang Baek 085f48366b refac 2024-12-31 19:54:11 -08:00
Timothy Jaeryang Baek 60fc24cd39 refac: channel message input 2024-12-31 19:42:49 -08:00
dependabot[bot] 7fb87ddf99 build(deps): bump peewee from 3.17.6 to 3.17.8 in /backend
Bumps [peewee](https://github.com/coleifer/peewee) from 3.17.6 to 3.17.8.
- [Release notes](https://github.com/coleifer/peewee/releases)
- [Changelog](https://github.com/coleifer/peewee/blob/master/CHANGELOG.md)
- [Commits](https://github.com/coleifer/peewee/compare/3.17.6...3.17.8)

---
updated-dependencies:
- dependency-name: peewee
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-01 02:15:02 +00:00
dependabot[bot] b41c1128c6 build(deps): bump flask from 3.0.3 to 3.1.0 in /backend
Bumps [flask](https://github.com/pallets/flask) from 3.0.3 to 3.1.0.
- [Release notes](https://github.com/pallets/flask/releases)
- [Changelog](https://github.com/pallets/flask/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/flask/compare/3.0.3...3.1.0)

---
updated-dependencies:
- dependency-name: flask
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-01 02:14:54 +00:00
dependabot[bot] 5bb308a098 build(deps): bump validators from 0.33.0 to 0.34.0 in /backend
Bumps [validators](https://github.com/python-validators/validators) from 0.33.0 to 0.34.0.
- [Release notes](https://github.com/python-validators/validators/releases)
- [Changelog](https://github.com/python-validators/validators/blob/master/CHANGES.md)
- [Commits](https://github.com/python-validators/validators/compare/0.33.0...0.34.0)

---
updated-dependencies:
- dependency-name: validators
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-01 02:14:51 +00:00
dependabot[bot] 236410cd95 build(deps): bump fpdf2 from 2.7.9 to 2.8.2 in /backend
Bumps [fpdf2](https://github.com/py-pdf/fpdf2) from 2.7.9 to 2.8.2.
- [Release notes](https://github.com/py-pdf/fpdf2/releases)
- [Changelog](https://github.com/py-pdf/fpdf2/blob/master/CHANGELOG.md)
- [Commits](https://github.com/py-pdf/fpdf2/compare/2.7.9...2.8.2)

---
updated-dependencies:
- dependency-name: fpdf2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-01 02:14:48 +00:00
dependabot[bot] f1800e2853 build(deps): bump pyjwt[crypto] from 2.9.0 to 2.10.1 in /backend
Bumps [pyjwt[crypto]](https://github.com/jpadilla/pyjwt) from 2.9.0 to 2.10.1.
- [Release notes](https://github.com/jpadilla/pyjwt/releases)
- [Changelog](https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/jpadilla/pyjwt/compare/2.9.0...2.10.1)

---
updated-dependencies:
- dependency-name: pyjwt[crypto]
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-01 02:14:45 +00:00
Timothy Jaeryang Baek 4bc9904b3c Merge pull request #8159 from open-webui/dev
Create and publish Docker images with specific build args / build-main-image (linux/amd64) (push) Waiting to run
Create and publish Docker images with specific build args / build-main-image (linux/arm64) (push) Waiting to run
Create and publish Docker images with specific build args / build-cuda-image (linux/amd64) (push) Waiting to run
Create and publish Docker images with specific build args / build-cuda-image (linux/arm64) (push) Waiting to run
Create and publish Docker images with specific build args / build-ollama-image (linux/amd64) (push) Waiting to run
Create and publish Docker images with specific build args / build-ollama-image (linux/arm64) (push) Waiting to run
Create and publish Docker images with specific build args / merge-main-images (push) Blocked by required conditions
Create and publish Docker images with specific build args / merge-cuda-images (push) Blocked by required conditions
Create and publish Docker images with specific build args / merge-ollama-images (push) Blocked by required conditions
0.5.3
2024-12-31 13:41:03 -08:00
Timothy Jaeryang Baek 995f80002f doc: changelog 2024-12-31 13:40:49 -08:00
Timothy Jaeryang Baek ffdb45cc4b refac 2024-12-31 13:39:03 -08:00
Timothy Jaeryang Baek f5ee5deec8 chore: format 2024-12-31 13:30:59 -08:00
Timothy Jaeryang Baek 02777ffc54 doc: changelog 2024-12-31 13:23:05 -08:00
Timothy Jaeryang Baek a5627d4226 refac 2024-12-31 13:09:17 -08:00
Timothy Jaeryang Baek 435a174316 Merge pull request #8232 from okamototk/improve-jp-trans
i18n - Updated Japanese Translation
2024-12-31 13:04:58 -08:00
Timothy Jaeryang Baek d905202afb refac 2024-12-31 13:04:27 -08:00
Takashi Okamoto 221cc19ac6 i18n - Updated Japanese Translation 2024-12-31 11:58:43 +00:00
Timothy Jaeryang Baek 3d69eaf34f refac: styling 2024-12-31 03:57:43 -08:00
Timothy Jaeryang Baek e7c501677c refac 2024-12-31 03:54:43 -08:00
Timothy Jaeryang Baek 96b1c2024b refac 2024-12-31 03:45:54 -08:00
Timothy Jaeryang Baek f7ecfafe1a refac: styling 2024-12-31 03:25:25 -08:00
Timothy Jaeryang Baek 6ecee8b920 refac: emoji picker optimisation 2024-12-31 03:24:05 -08:00
Timothy Jaeryang Baek cce8f37ada refac 2024-12-31 02:58:15 -08:00
Timothy Jaeryang Baek 60247fe18d refac 2024-12-31 02:51:52 -08:00
Timothy Jaeryang Baek de4e086bd5 refac 2024-12-31 02:48:43 -08:00
Timothy Jaeryang Baek 3da7ff1721 refac 2024-12-31 02:42:46 -08:00
Timothy Jaeryang Baek c8cdc6377b refac 2024-12-31 02:30:03 -08:00
Timothy Jaeryang Baek 85038cef69 refac: styling 2024-12-31 02:27:49 -08:00
Timothy Jaeryang Baek 016b91adda chore: format 2024-12-31 02:26:30 -08:00
Timothy Jaeryang Baek 0846a08795 Merge pull request #8230 from moblangeois/dev
i18n: update fr-FR
2024-12-31 02:24:42 -08:00
Timothy Jaeryang Baek 277eef62c2 Merge pull request #8210 from open-webui/channels
enh: channel threads & reactions
2024-12-31 02:24:10 -08:00
Timothy Jaeryang Baek 9f19933e64 refac: styling 2024-12-31 02:23:26 -08:00
Timothy Jaeryang Baek 904ddcec13 refac: styling 2024-12-31 02:19:22 -08:00
Timothy Jaeryang Baek 77da0a6cc1 refac: styling 2024-12-31 02:17:39 -08:00
Timothy Jaeryang Baek a754a4388a feat: channel threads 2024-12-31 02:16:07 -08:00
Morgan Blangeois 93f262c6a2 i18n: update fr-FR 2024-12-31 11:09:31 +01:00
Timothy Jaeryang Baek 16a48ef4eb fix 2024-12-31 02:06:55 -08:00
Timothy Jaeryang Baek 841f74894e refac 2024-12-31 02:06:19 -08:00
Timothy Jaeryang Baek 9c337552e6 enh: reply count 2024-12-31 02:05:11 -08:00
Timothy Jaeryang Baek 584e9e6da5 refac: threads 2024-12-31 00:51:43 -08:00
Timothy Jaeryang Baek a3dfa90668 refac: optimisation 2024-12-31 00:11:46 -08:00
Timothy Jaeryang Baek 00e8849445 refac 2024-12-30 23:55:19 -08:00
Timothy Jaeryang Baek 2840ff405b refac 2024-12-30 23:48:55 -08:00
Timothy Jaeryang Baek 9d39404e6c refac: styling 2024-12-30 23:16:50 -08:00
Timothy Jaeryang Baek 371201d820 refac 2024-12-30 23:12:50 -08:00
Timothy Jaeryang Baek f93c2e4a8d feat: reactions 2024-12-30 23:06:34 -08:00
Timothy Jaeryang Baek 4b0fa112bb Merge pull request #8222 from open-webui/dev
dev
2024-12-30 17:55:13 -08:00
Timothy Jaeryang Baek fd0170c179 revert 2024-12-30 16:55:29 -08:00
Timothy Jaeryang Baek 9b56b64cfa Merge pull request #8212 from ashm-dev/main
feat: Small optimization
2024-12-30 16:00:18 -08:00
Timothy Jaeryang Baek 887627fa34 Merge pull request #8217 from gabriel-ecegi/batch_fix
fix: Add missing request parameter to knowledge and retrieval routes
2024-12-30 15:58:10 -08:00
Timothy Jaeryang Baek 46bcf98ef2 fix: usage stats 2024-12-30 15:52:07 -08:00
Timothy Jaeryang Baek 947f5600d6 refac 2024-12-30 15:39:35 -08:00
Timothy Jaeryang Baek 79ce6e0a3f refac 2024-12-30 11:29:18 -08:00
Gabriel Ecegi 46e57706c1 refac: formatting 2024-12-30 17:45:43 +01:00
Gabriel Ecegi ba2964cb01 fix: missing parameter 2024-12-30 17:36:34 +01:00
shamil a0aee4ff28 feat: Small optimization 2024-12-30 13:45:20 +03:00
Timothy Jaeryang Baek 45289b0fa8 refac 2024-12-30 02:21:45 -08:00
Timothy Jaeryang Baek eece28ccc6 feat: emoji picker 2024-12-30 02:20:09 -08:00
Timothy Jaeryang Baek c216d89520 enh: threads & reactions 2024-12-29 23:16:18 -08:00
Timothy Jaeryang Baek d94134ad2d refac 2024-12-29 22:11:20 -08:00
Timothy Jaeryang Baek 952822ad5d refac 2024-12-29 21:02:11 -08:00
Timothy Jaeryang Baek 79d7e67e51 fix: ollama options 2024-12-29 16:30:36 -08:00
Timothy Jaeryang Baek 6de1923151 Merge pull request #8192 from TiancongLx/dev
i18n: update zh-TW
2024-12-29 15:36:19 -08:00
Tiancong Li abdbd6a67e i18n: update zh-TW 2024-12-30 03:13:20 +08:00
Timothy Jaeryang Baek a14dee87e8 Merge pull request #8184 from vishwamartur/fix-offline-docker
Fix offline docker container startup issue
2024-12-28 22:26:38 -08:00
Vishwanath Martur 00e6ffe83c Fix offline docker container startup issue
Related to #7207

Modify the code to allow the docker container to start in an offline environment for versions >= 0.4.0.

* **backend/open_webui/retrieval/utils.py**
  - Import `OFFLINE_MODE` from `open_webui.env`.
  - Set `local_files_only` to `True` when `OFFLINE_MODE` is enabled in `snapshot_kwargs`.

* **backend/open_webui/env.py**
  - Add logic to set `HF_HUB_OFFLINE` environment variable to `1` when `OFFLINE_MODE` is enabled.

* **README.md**
  - Document setting `HF_HUB_OFFLINE` environment variable to `1` for offline environments.
2024-12-29 11:53:09 +05:30
Timothy Jaeryang Baek 36d927e1ba refac 2024-12-28 19:31:03 -08:00
Timothy Jaeryang Baek 091e9e2f40 refac 2024-12-28 18:08:30 -08:00
Timothy Jaeryang Baek 54daf3b765 fix: outlet filter hook 2024-12-28 18:05:07 -08:00
Timothy Jaeryang Baek 76decdba2a fix: delete file 2024-12-28 17:40:00 -08:00
Timothy Jaeryang Baek e6e8978f78 refac 2024-12-28 16:42:43 -08:00
Timothy Jaeryang Baek fcaeb2f539 Merge pull request #8179 from cvaz1306/add_reset_button_mermaidjs_renderer
i18n: Add reset panzoom button to SVGPanZoom and cleanup
2024-12-28 16:27:44 -08:00
cvaz1306 f7d1833f41 Fixing formatting 2024-12-28 15:50:23 -08:00
cvaz1306 95598e5435 Merge branch 'dev' into add_reset_button_mermaidjs_renderer 2024-12-28 15:46:23 -08:00
cvaz1306 8a7e8b57a8 Add reset panzoom button to SVGPanZoom and cleanup 2024-12-28 15:27:47 -08:00
Timothy Jaeryang Baek 5a720a4a31 refac 2024-12-27 22:46:50 -08:00
Timothy Jaeryang Baek d55884b50e enh: ENABLE_REALTIME_CHAT_SAVE 2024-12-27 22:36:14 -08:00
Timothy Jaeryang Baek c8fb11db59 Merge pull request #8158 from cvaz1306/add_reset_button_mermaidjs_renderer
feat: Add reset button mermaidjs renderer
2024-12-27 17:55:00 -08:00
cvaz1306 7b3a86475d Add reset panzoom button to SVGPanZoom and cleanup 2024-12-27 17:06:15 -08:00
Timothy Jaeryang Baek 59ed53ec1e Merge pull request #8145 from bernadinm/fix/modified_update_ollama_models.sh
fix: Add execute permissions to update_ollama_models.sh
2024-12-27 16:24:32 -08:00
Timothy Jaeryang Baek 7f8b6ebbd5 refac: styling 2024-12-27 12:24:58 -08:00
Miguel Bernadin 3f0dd80898 fix: chmod +x update_ollama_models.sh 2024-12-27 08:29:54 -08:00
Timothy Jaeryang Baek 2299f48430 Merge pull request #8131 from open-webui/dev
fix: api key restrictions
2024-12-27 00:32:37 -08:00
Timothy Jaeryang Baek 99386bf680 fix: api key restrictions 2024-12-27 00:32:25 -08:00
Timothy Jaeryang Baek 4e4e2792b1 Merge pull request #8130 from open-webui/dev
refac
2024-12-27 00:06:41 -08:00
Timothy Jaeryang Baek d99e3d49e1 refac 2024-12-27 00:05:32 -08:00
Timothy Jaeryang Baek e42cbf07f5 Merge pull request #8122 from open-webui/dev
Create and publish Docker images with specific build args / build-main-image (linux/amd64) (push) Waiting to run
Create and publish Docker images with specific build args / build-main-image (linux/arm64) (push) Waiting to run
Create and publish Docker images with specific build args / build-cuda-image (linux/amd64) (push) Waiting to run
Create and publish Docker images with specific build args / build-cuda-image (linux/arm64) (push) Waiting to run
Create and publish Docker images with specific build args / build-ollama-image (linux/amd64) (push) Waiting to run
Create and publish Docker images with specific build args / build-ollama-image (linux/arm64) (push) Waiting to run
Create and publish Docker images with specific build args / merge-main-images (push) Blocked by required conditions
Create and publish Docker images with specific build args / merge-cuda-images (push) Blocked by required conditions
Create and publish Docker images with specific build args / merge-ollama-images (push) Blocked by required conditions
0.5.2
2024-12-26 23:51:49 -08:00
Timothy Jaeryang Baek 016862a6b8 doc: changelog 2024-12-26 23:51:40 -08:00
Timothy Jaeryang Baek cd9dae0f3a refac 2024-12-26 23:51:30 -08:00
Timothy Jaeryang Baek b7baf4ddef doc: changelog 2024-12-26 23:46:07 -08:00
Timothy Jaeryang Baek 1584015d3b chore: format 2024-12-26 23:35:56 -08:00
Timothy Jaeryang Baek e4b4a78e52 refac 2024-12-26 23:35:01 -08:00
Timothy Jaeryang Baek 50534a0dcf enh: user status indicator 2024-12-26 23:29:33 -08:00
Timothy Jaeryang Baek c53ace3c98 refac 2024-12-26 22:03:39 -08:00
Timothy Jaeryang Baek 7fa60dd63e refac 2024-12-26 21:55:21 -08:00
Timothy Jaeryang Baek 6ff6d57507 enh: typing indicator 2024-12-26 21:51:09 -08:00
Timothy Jaeryang Baek 4f93ecf519 refac 2024-12-26 20:58:46 -08:00
Timothy Jaeryang Baek 1e974439d9 enh: configurable api key endpoint restrictions 2024-12-26 20:57:51 -08:00
Timothy Jaeryang Baek 611955bc91 refac 2024-12-26 20:38:27 -08:00
Timothy Jaeryang Baek e3937ada38 fix: ollama usage 2024-12-26 20:35:14 -08:00
Timothy Jaeryang Baek c5b8466c0e fix: playground 2024-12-26 19:12:08 -08:00
Timothy Jaeryang Baek e25b082162 fix: pipelines outlet 2024-12-26 19:10:28 -08:00
Timothy Jaeryang Baek 247d7896fc Merge pull request #8093 from aleixdorca/dev
i18n: Updated Catalan translation.json
2024-12-26 13:34:30 -08:00
Timothy Jaeryang Baek a0ad681c77 Merge pull request #8101 from panda44312/dev
i18n - Updated Simplified Chinese Translation
2024-12-26 13:34:21 -08:00
Timothy Jaeryang Baek 1b7ee5dd2b Merge pull request #8115 from taylorwilsdon/fix_drive_integration
Fix drive integration
2024-12-26 13:34:09 -08:00
Timothy Jaeryang Baek 8b6d03e430 fix: elevenlabs audio 2024-12-26 12:54:31 -08:00
Taylor Wilsdon efc4ad9f65 Update Documents.svelte 2024-12-26 14:48:38 -05:00
Taylor Wilsdon 3cfb6507c5 Update .gitignore 2024-12-26 14:47:41 -05:00
Taylor Wilsdon 24a314876b formatting 2024-12-26 14:46:41 -05:00
Taylor Wilsdon 190911206b Remove logging 2024-12-26 14:46:06 -05:00
Taylor Wilsdon ea11521961 Remove unnecessary logging 2024-12-26 14:44:36 -05:00
Taylor Wilsdon 909c94e983 Fix Google Drive integration 2024-12-26 14:41:58 -05:00
Taylor Wilsdon (aider) 1c7ff7b1dc fix: Initialize enableGoogleDriveIntegration with default value 2024-12-26 12:22:58 -05:00
Taylor Wilsdon (aider) c7cec2131c debug: Add detailed logging for Google Drive Integration state changes 2024-12-26 12:21:38 -05:00
Taylor Wilsdon (aider) 6f3e7ed0e9 debug: Add console logs for Google Drive Integration state changes 2024-12-26 12:19:53 -05:00
Panda d4ccd25760 Update translation.json 2024-12-26 11:51:44 +01:00
Timothy Jaeryang Baek dd933e406f Merge pull request #8095 from open-webui/dev
fix: automatic1111 image generation
2024-12-25 23:35:10 -08:00
Timothy Jaeryang Baek 3c74ce3653 fix: automatic1111 image generation 2024-12-25 23:34:54 -08:00
Timothy Jaeryang Baek de2bda3e2e Merge pull request #8094 from open-webui/dev
refac: title generation logic
2024-12-25 23:52:21 -07:00
Timothy Jaeryang Baek 4b3e1bb747 refac: title generation logic 2024-12-25 22:51:08 -08:00
Aleix Dorca bb30a83520 Update catalan translation.json 2024-12-26 07:49:49 +01:00
3964 changed files with 14165 additions and 728 deletions
+25
View File
@@ -0,0 +1,25 @@
# Codespell configuration is within pyproject.toml
---
name: Codespell
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
jobs:
codespell:
name: Check for spelling errors
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Annotate locations with typos
uses: codespell-project/codespell-problem-matcher@v1
- name: Codespell
uses: codespell-project/actions-codespell@v2
+64
View File
@@ -5,6 +5,70 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.5.4] - 2024-01-05
### Added
- **🔄 Clone Shared Chats**: Effortlessly clone shared chats to save time and streamline collaboration, perfect for reusing insightful discussions or custom setups.
- **📣 Native Notifications for Channel Messages**: Stay informed with integrated desktop notifications for channel messages, ensuring you never miss important updates while multitasking.
- **🔥 Torch MPS Support**: MPS support for Mac users when Open WebUI is installed directly, offering better performance and compatibility for AI workloads.
- **🌍 Enhanced Translations**: Small improvements to various translations, ensuring a smoother global user experience.
### Fixed
- **🖼️ Image-Only Messages in Channels**: You can now send images without accompanying text or content in channels.
- **❌ Proper Exception Handling**: Enhanced error feedback by ensuring exceptions are raised clearly, reducing confusion and promoting smoother debugging.
- **🔍 RAG Query Generation Restored**: Fixed query generation issues for Retrieval-Augmented Generation, improving retrieval accuracy and ensuring seamless functionality.
- **📩 MOA Response Functionality Fixed**: Addressed an error with the MOA response generation feature.
- **💬 Channel Thread Loading with 50+ Messages**: Resolved an issue where channel threads stalled when exceeding 50 messages, ensuring smooth navigation in active discussions.
- **🔑 API Endpoint Restrictions Resolution**: Fixed a critical bug where the 'API_KEY_ALLOWED_ENDPOINTS' setting was not functioning as intended, ensuring API access is limited to specified endpoints for enhanced security.
- **🛠️ Action Functions Restored**: Corrected an issue preventing action functions from working, restoring their utility for customized automations and workflows.
- **📂 Temporary Chat JSON Export Fix**: Resolved a bug blocking temporary chats from being exported in JSON format, ensuring seamless data portability.
### Changed
- **🎛️ Sidebar UI Tweaks**: Chat folders, including pinned folders, now display below the Chats section for better organization; the "New Folder" button has been relocated to the Chats section for a more intuitive workflow.
- **🏗️ Real-Time Save Disabled by Default**: The 'ENABLE_REALTIME_CHAT_SAVE' setting is now off by default, boosting response speed for users who prioritize performance in high-paced workflows or less critical scenarios.
- **🎤 Audio Input Echo Cancellation**: Audio input now features echo cancellation enabled by default, reducing audio feedback for improved clarity during conversations or voice-based interactions.
- **🔧 General Reliability Improvements**: Numerous under-the-hood enhancements have been made to improve platform stability, boost overall performance, and ensure a more seamless, dependable experience across workflows.
## [0.5.3] - 2024-12-31
### Added
- **💬 Channel Reactions with Built-In Emoji Picker**: Easily express yourself in channel threads and messages with reactions, featuring an intuitive built-in emoji picker for seamless selection.
- **🧵 Threads for Channels**: Organize discussions within channels by creating threads, improving clarity and fostering focused conversations.
- **🔄 Reset Button for SVG Pan/Zoom**: Added a handy reset button to SVG Pan/Zoom, allowing users to quickly return diagrams or visuals to their default state without hassle.
- **⚡ Realtime Chat Save Environment Variable**: Introduced the ENABLE_REALTIME_CHAT_SAVE environment variable. Choose between faster responses by disabling realtime chat saving or ensuring chunk-by-chunk data persistency for critical operations.
- **🌍 Translation Enhancements**: Updated and refined translations across multiple languages, providing a smoother experience for international users.
- **📚 Improved Documentation**: Expanded documentation on functions, including clearer guidance on function plugins and detailed instructions for migrating to v0.5. This ensures users can adapt and harness new updates more effectively. (https://docs.openwebui.com/features/plugin/)
### Fixed
- **🛠️ Ollama Parameters Respected**: Resolved an issue where input parameters for Ollama were being ignored, ensuring precise and consistent model behavior.
- **🔧 Function Plugin Outlet Hook Reliability**: Fixed a bug causing issues with 'event_emitter' and outlet hooks in filter function plugins, guaranteeing smoother operation within custom extensions.
- **🖋️ Weird Custom Status Descriptions**: Adjusted the formatting and functionality for custom user statuses, ensuring they display correctly and intuitively.
- **🔗 Restored API Functionality**: Fixed a critical issue where APIs were not operational for certain configurations, ensuring uninterrupted access.
- **⏳ Custom Pipe Function Completion**: Resolved an issue where chats using specific custom pipe function plugins werent finishing properly, restoring consistent chat workflows.
- **✅ General Stability Enhancements**: Implemented various under-the-hood improvements to boost overall reliability, ensuring smoother and more consistent performance across the WebUI.
## [0.5.2] - 2024-12-26
### Added
- **🖊️ Typing Indicators in Channels**: Know exactly whos typing in real-time within your channels, enhancing collaboration and keeping everyone engaged.
- **👤 User Status Indicators**: Quickly view a users status by clicking their profile image in channels for better coordination and availability insights.
- **🔒 Configurable API Key Authentication Restrictions**: Flexibly configure endpoint restrictions for API key authentication, now off by default for a smoother setup in trusted environments.
### Fixed
- **🔧 Playground Functionality Restored**: Resolved a critical issue where the playground wasnt working, ensuring seamless experimentation and troubleshooting workflows.
- **📊 Corrected Ollama Usage Statistics**: Fixed a calculation error in Ollamas usage statistics, providing more accurate tracking and insights for better resource management.
- **🔗 Pipelines Outlet Hook Registration**: Addressed an issue where outlet hooks for pipelines werent registered, restoring functionality and consistency in pipeline workflows.
- **🎨 Image Generation Error**: Resolved a persistent issue causing errors with 'get_automatic1111_api_auth()' to ensure smooth image generation workflows.
- **🎙️ Text-to-Speech Error**: Fixed the missing argument in Eleven Labs 'get_available_voices()', restoring full text-to-speech capabilities for uninterrupted voice interactions.
- **🖋️ Title Generation Issue**: Fixed a bug where title generation was not working in certain cases, ensuring consistent and reliable chat organization.
## [0.5.1] - 2024-12-25
### Added
+1 -1
View File
@@ -2,7 +2,7 @@
## Our Pledge
As members, contributors, and leaders of this community, we pledge to make participation in our open-source project a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
As members, contributors, and leaders of this community, we pledge to make participation in our open-source project a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socioeconomic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
We are committed to creating and maintaining an open, respectful, and professional environment where positive contributions and meaningful discussions can flourish. By participating in this project, you agree to uphold these values and align your behavior to the standards outlined in this Code of Conduct.
+11 -1
View File
@@ -11,7 +11,9 @@
[![Discord](https://img.shields.io/badge/Discord-Open_WebUI-blue?logo=discord&logoColor=white)](https://discord.gg/5rJgQTnV4s)
[![](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86)](https://github.com/sponsors/tjbck)
Open WebUI is an [extensible](https://github.com/open-webui/pipelines), feature-rich, and user-friendly self-hosted WebUI designed to operate entirely offline. It supports various LLM runners, including Ollama and OpenAI-compatible APIs. For more information, be sure to check out our [Open WebUI Documentation](https://docs.openwebui.com/).
**Open WebUI is an [extensible](https://docs.openwebui.com/features/plugin/), feature-rich, and user-friendly self-hosted AI platform designed to operate entirely offline.** It supports various LLM runners like **Ollama** and **OpenAI-compatible APIs**, with **built-in inference engine** for RAG, making it a **powerful AI deployment solution**.
For more information, be sure to check out our [Open WebUI Documentation](https://docs.openwebui.com/).
![Open WebUI Demo](./demo.gif)
@@ -185,6 +187,14 @@ If you want to try out the latest bleeding-edge features and are okay with occas
docker run -d -p 3000:8080 -v open-webui:/app/backend/data --name open-webui --add-host=host.docker.internal:host-gateway --restart always ghcr.io/open-webui/open-webui:dev
```
### Offline Mode
If you are running Open WebUI in an offline environment, you can set the `HF_HUB_OFFLINE` environment variable to `1` to prevent attempts to download models from the internet.
```bash
export HF_HUB_OFFLINE=1
```
## What's Next? 🌟
Discover upcoming features on our roadmap in the [Open WebUI Documentation](https://docs.openwebui.com/roadmap/).
+26 -11
View File
@@ -272,6 +272,18 @@ ENABLE_API_KEY = PersistentConfig(
os.environ.get("ENABLE_API_KEY", "True").lower() == "true",
)
ENABLE_API_KEY_ENDPOINT_RESTRICTIONS = PersistentConfig(
"ENABLE_API_KEY_ENDPOINT_RESTRICTIONS",
"auth.api_key.endpoint_restrictions",
os.environ.get("ENABLE_API_KEY_ENDPOINT_RESTRICTIONS", "False").lower() == "true",
)
API_KEY_ALLOWED_ENDPOINTS = PersistentConfig(
"API_KEY_ALLOWED_ENDPOINTS",
"auth.api_key.allowed_endpoints",
os.environ.get("API_KEY_ALLOWED_ENDPOINTS", ""),
)
JWT_EXPIRES_IN = PersistentConfig(
"JWT_EXPIRES_IN", "auth.jwt_expiry", os.environ.get("JWT_EXPIRES_IN", "-1")
@@ -307,17 +319,6 @@ GOOGLE_CLIENT_SECRET = PersistentConfig(
os.environ.get("GOOGLE_CLIENT_SECRET", ""),
)
GOOGLE_DRIVE_CLIENT_ID = PersistentConfig(
"GOOGLE_DRIVE_CLIENT_ID",
"google_drive.client_id",
os.environ.get("GOOGLE_DRIVE_CLIENT_ID", ""),
)
GOOGLE_DRIVE_API_KEY = PersistentConfig(
"GOOGLE_DRIVE_API_KEY",
"google_drive.api_key",
os.environ.get("GOOGLE_DRIVE_API_KEY", ""),
)
GOOGLE_OAUTH_SCOPE = PersistentConfig(
"GOOGLE_OAUTH_SCOPE",
@@ -1210,6 +1211,9 @@ if VECTOR_DB == "pgvector" and not PGVECTOR_DB_URL.startswith("postgres"):
raise ValueError(
"Pgvector requires setting PGVECTOR_DB_URL or using Postgres with vector extension as the primary database."
)
PGVECTOR_INITIALIZE_MAX_VECTOR_LENGTH = int(
os.environ.get("PGVECTOR_INITIALIZE_MAX_VECTOR_LENGTH", "1536")
)
####################################
# Information Retrieval (RAG)
@@ -1223,6 +1227,17 @@ ENABLE_GOOGLE_DRIVE_INTEGRATION = PersistentConfig(
os.getenv("ENABLE_GOOGLE_DRIVE_INTEGRATION", "False").lower() == "true",
)
GOOGLE_DRIVE_CLIENT_ID = PersistentConfig(
"GOOGLE_DRIVE_CLIENT_ID",
"google_drive.client_id",
os.environ.get("GOOGLE_DRIVE_CLIENT_ID", ""),
)
GOOGLE_DRIVE_API_KEY = PersistentConfig(
"GOOGLE_DRIVE_API_KEY",
"google_drive.api_key",
os.environ.get("GOOGLE_DRIVE_API_KEY", ""),
)
# RAG Content Extraction
CONTENT_EXTRACTION_ENGINE = PersistentConfig(
+13
View File
@@ -53,6 +53,11 @@ if USE_CUDA.lower() == "true":
else:
DEVICE_TYPE = "cpu"
try:
if torch.backends.mps.is_available() and torch.backends.mps.is_built():
DEVICE_TYPE = "mps"
except Exception:
pass
####################################
# LOGGING
@@ -311,6 +316,11 @@ RESET_CONFIG_ON_START = (
os.environ.get("RESET_CONFIG_ON_START", "False").lower() == "true"
)
ENABLE_REALTIME_CHAT_SAVE = (
os.environ.get("ENABLE_REALTIME_CHAT_SAVE", "False").lower() == "true"
)
####################################
# REDIS
####################################
@@ -392,3 +402,6 @@ else:
####################################
OFFLINE_MODE = os.environ.get("OFFLINE_MODE", "false").lower() == "true"
if OFFLINE_MODE:
os.environ["HF_HUB_OFFLINE"] = "1"
+7
View File
@@ -199,6 +199,8 @@ from open_webui.config import (
ENABLE_SIGNUP,
ENABLE_LOGIN_FORM,
ENABLE_API_KEY,
ENABLE_API_KEY_ENDPOINT_RESTRICTIONS,
API_KEY_ALLOWED_ENDPOINTS,
ENABLE_CHANNELS,
ENABLE_COMMUNITY_SHARING,
ENABLE_MESSAGE_RATING,
@@ -392,7 +394,12 @@ app.state.OPENAI_MODELS = {}
app.state.config.WEBUI_URL = WEBUI_URL
app.state.config.ENABLE_SIGNUP = ENABLE_SIGNUP
app.state.config.ENABLE_LOGIN_FORM = ENABLE_LOGIN_FORM
app.state.config.ENABLE_API_KEY = ENABLE_API_KEY
app.state.config.ENABLE_API_KEY_ENDPOINT_RESTRICTIONS = (
ENABLE_API_KEY_ENDPOINT_RESTRICTIONS
)
app.state.config.API_KEY_ALLOWED_ENDPOINTS = API_KEY_ALLOWED_ENDPOINTS
app.state.config.JWT_EXPIRES_IN = JWT_EXPIRES_IN
@@ -0,0 +1,70 @@
"""Update message & channel tables
Revision ID: 3781e22d8b01
Revises: 7826ab40b532
Create Date: 2024-12-30 03:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
revision = "3781e22d8b01"
down_revision = "7826ab40b532"
branch_labels = None
depends_on = None
def upgrade():
# Add 'type' column to the 'channel' table
op.add_column(
"channel",
sa.Column(
"type",
sa.Text(),
nullable=True,
),
)
# Add 'parent_id' column to the 'message' table for threads
op.add_column(
"message",
sa.Column("parent_id", sa.Text(), nullable=True),
)
op.create_table(
"message_reaction",
sa.Column(
"id", sa.Text(), nullable=False, primary_key=True, unique=True
), # Unique reaction ID
sa.Column("user_id", sa.Text(), nullable=False), # User who reacted
sa.Column(
"message_id", sa.Text(), nullable=False
), # Message that was reacted to
sa.Column(
"name", sa.Text(), nullable=False
), # Reaction name (e.g. "thumbs_up")
sa.Column(
"created_at", sa.BigInteger(), nullable=True
), # Timestamp of when the reaction was added
)
op.create_table(
"channel_member",
sa.Column(
"id", sa.Text(), nullable=False, primary_key=True, unique=True
), # Record ID for the membership row
sa.Column("channel_id", sa.Text(), nullable=False), # Associated channel
sa.Column("user_id", sa.Text(), nullable=False), # Associated user
sa.Column(
"created_at", sa.BigInteger(), nullable=True
), # Timestamp of when the user joined the channel
)
def downgrade():
# Revert 'type' column addition to the 'channel' table
op.drop_column("channel", "type")
op.drop_column("message", "parent_id")
op.drop_table("message_reaction")
op.drop_table("channel_member")
+6 -2
View File
@@ -21,6 +21,7 @@ class Channel(Base):
id = Column(Text, primary_key=True)
user_id = Column(Text)
type = Column(Text, nullable=True)
name = Column(Text)
description = Column(Text, nullable=True)
@@ -38,9 +39,11 @@ class ChannelModel(BaseModel):
id: str
user_id: str
description: Optional[str] = None
type: Optional[str] = None
name: str
description: Optional[str] = None
data: Optional[dict] = None
meta: Optional[dict] = None
access_control: Optional[dict] = None
@@ -64,12 +67,13 @@ class ChannelForm(BaseModel):
class ChannelTable:
def insert_new_channel(
self, form_data: ChannelForm, user_id: str
self, type: Optional[str], form_data: ChannelForm, user_id: str
) -> Optional[ChannelModel]:
with get_db() as db:
channel = ChannelModel(
**{
**form_data.model_dump(),
"type": type,
"name": form_data.name.lower(),
"id": str(uuid.uuid4()),
"user_id": user_id,
+11
View File
@@ -212,6 +212,15 @@ class ChatTable:
return chat.chat.get("history", {}).get("messages", {}) or {}
def get_message_by_id_and_message_id(
self, id: str, message_id: str
) -> Optional[dict]:
chat = self.get_chat_by_id(id)
if chat is None:
return None
return chat.chat.get("history", {}).get("messages", {}).get(message_id, {})
def upsert_message_to_chat_by_id_and_message_id(
self, id: str, message_id: str, message: dict
) -> Optional[ChatModel]:
@@ -460,6 +469,8 @@ class ChatTable:
def get_chat_by_share_id(self, id: str) -> Optional[ChatModel]:
try:
with get_db() as db:
# it is possible that the shared link was deleted. hence,
# we check if the chat is still shared by checkng if a chat with the share_id exists
chat = db.query(Chat).filter_by(share_id=id).first()
if chat:
+144 -6
View File
@@ -17,6 +17,25 @@ from sqlalchemy.sql import exists
####################
class MessageReaction(Base):
__tablename__ = "message_reaction"
id = Column(Text, primary_key=True)
user_id = Column(Text)
message_id = Column(Text)
name = Column(Text)
created_at = Column(BigInteger)
class MessageReactionModel(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: str
user_id: str
message_id: str
name: str
created_at: int # timestamp in epoch
class Message(Base):
__tablename__ = "message"
id = Column(Text, primary_key=True)
@@ -24,6 +43,8 @@ class Message(Base):
user_id = Column(Text)
channel_id = Column(Text, nullable=True)
parent_id = Column(Text, nullable=True)
content = Column(Text)
data = Column(JSON, nullable=True)
meta = Column(JSON, nullable=True)
@@ -39,6 +60,8 @@ class MessageModel(BaseModel):
user_id: str
channel_id: Optional[str] = None
parent_id: Optional[str] = None
content: str
data: Optional[dict] = None
meta: Optional[dict] = None
@@ -54,10 +77,23 @@ class MessageModel(BaseModel):
class MessageForm(BaseModel):
content: str
parent_id: Optional[str] = None
data: Optional[dict] = None
meta: Optional[dict] = None
class Reactions(BaseModel):
name: str
user_ids: list[str]
count: int
class MessageResponse(MessageModel):
latest_reply_at: Optional[int]
reply_count: int
reactions: list[Reactions]
class MessageTable:
def insert_new_message(
self, form_data: MessageForm, channel_id: str, user_id: str
@@ -71,6 +107,7 @@ class MessageTable:
"id": id,
"user_id": user_id,
"channel_id": channel_id,
"parent_id": form_data.parent_id,
"content": form_data.content,
"data": form_data.data,
"meta": form_data.meta,
@@ -85,10 +122,40 @@ class MessageTable:
db.refresh(result)
return MessageModel.model_validate(result) if result else None
def get_message_by_id(self, id: str) -> Optional[MessageModel]:
def get_message_by_id(self, id: str) -> Optional[MessageResponse]:
with get_db() as db:
message = db.get(Message, id)
return MessageModel.model_validate(message) if message else None
if not message:
return None
reactions = self.get_reactions_by_message_id(id)
replies = self.get_replies_by_message_id(id)
return MessageResponse(
**{
**MessageModel.model_validate(message).model_dump(),
"latest_reply_at": replies[0].created_at if replies else None,
"reply_count": len(replies),
"reactions": reactions,
}
)
def get_replies_by_message_id(self, id: str) -> list[MessageModel]:
with get_db() as db:
all_messages = (
db.query(Message)
.filter_by(parent_id=id)
.order_by(Message.created_at.desc())
.all()
)
return [MessageModel.model_validate(message) for message in all_messages]
def get_reply_user_ids_by_message_id(self, id: str) -> list[str]:
with get_db() as db:
return [
message.user_id
for message in db.query(Message).filter_by(parent_id=id).all()
]
def get_messages_by_channel_id(
self, channel_id: str, skip: int = 0, limit: int = 50
@@ -96,7 +163,7 @@ class MessageTable:
with get_db() as db:
all_messages = (
db.query(Message)
.filter_by(channel_id=channel_id)
.filter_by(channel_id=channel_id, parent_id=None)
.order_by(Message.created_at.desc())
.offset(skip)
.limit(limit)
@@ -104,18 +171,28 @@ class MessageTable:
)
return [MessageModel.model_validate(message) for message in all_messages]
def get_messages_by_user_id(
self, user_id: str, skip: int = 0, limit: int = 50
def get_messages_by_parent_id(
self, channel_id: str, parent_id: str, skip: int = 0, limit: int = 50
) -> list[MessageModel]:
with get_db() as db:
message = db.get(Message, parent_id)
if not message:
return []
all_messages = (
db.query(Message)
.filter_by(user_id=user_id)
.filter_by(channel_id=channel_id, parent_id=parent_id)
.order_by(Message.created_at.desc())
.offset(skip)
.limit(limit)
.all()
)
# If length of all_messages is less than limit, then add the parent message
if len(all_messages) < limit:
all_messages.append(message)
return [MessageModel.model_validate(message) for message in all_messages]
def update_message_by_id(
@@ -131,9 +208,70 @@ class MessageTable:
db.refresh(message)
return MessageModel.model_validate(message) if message else None
def add_reaction_to_message(
self, id: str, user_id: str, name: str
) -> Optional[MessageReactionModel]:
with get_db() as db:
reaction_id = str(uuid.uuid4())
reaction = MessageReactionModel(
id=reaction_id,
user_id=user_id,
message_id=id,
name=name,
created_at=int(time.time_ns()),
)
result = MessageReaction(**reaction.model_dump())
db.add(result)
db.commit()
db.refresh(result)
return MessageReactionModel.model_validate(result) if result else None
def get_reactions_by_message_id(self, id: str) -> list[Reactions]:
with get_db() as db:
all_reactions = db.query(MessageReaction).filter_by(message_id=id).all()
reactions = {}
for reaction in all_reactions:
if reaction.name not in reactions:
reactions[reaction.name] = {
"name": reaction.name,
"user_ids": [],
"count": 0,
}
reactions[reaction.name]["user_ids"].append(reaction.user_id)
reactions[reaction.name]["count"] += 1
return [Reactions(**reaction) for reaction in reactions.values()]
def remove_reaction_by_id_and_user_id_and_name(
self, id: str, user_id: str, name: str
) -> bool:
with get_db() as db:
db.query(MessageReaction).filter_by(
message_id=id, user_id=user_id, name=name
).delete()
db.commit()
return True
def delete_reactions_by_id(self, id: str) -> bool:
with get_db() as db:
db.query(MessageReaction).filter_by(message_id=id).delete()
db.commit()
return True
def delete_replies_by_id(self, id: str) -> bool:
with get_db() as db:
db.query(Message).filter_by(parent_id=id).delete()
db.commit()
return True
def delete_message_by_id(self, id: str) -> bool:
with get_db() as db:
db.query(Message).filter_by(id=id).delete()
# Delete all reactions to this message
db.query(MessageReaction).filter_by(message_id=id).delete()
db.commit()
return True
+4 -1
View File
@@ -14,7 +14,7 @@ from langchain_core.documents import Document
from open_webui.retrieval.vector.connector import VECTOR_DB_CLIENT
from open_webui.utils.misc import get_last_user_message
from open_webui.env import SRC_LOG_LEVELS
from open_webui.env import SRC_LOG_LEVELS, OFFLINE_MODE
log = logging.getLogger(__name__)
log.setLevel(SRC_LOG_LEVELS["RAG"])
@@ -375,6 +375,9 @@ def get_model_path(model: str, update_model: bool = False):
local_files_only = not update_model
if OFFLINE_MODE:
local_files_only = True
snapshot_kwargs = {
"cache_dir": cache_dir,
"local_files_only": local_files_only,
@@ -5,6 +5,7 @@ from sqlalchemy import (
create_engine,
Column,
Integer,
MetaData,
select,
text,
Text,
@@ -19,9 +20,9 @@ from pgvector.sqlalchemy import Vector
from sqlalchemy.ext.mutable import MutableDict
from open_webui.retrieval.vector.main import VectorItem, SearchResult, GetResult
from open_webui.config import PGVECTOR_DB_URL
from open_webui.config import PGVECTOR_DB_URL, PGVECTOR_INITIALIZE_MAX_VECTOR_LENGTH
VECTOR_LENGTH = 1536
VECTOR_LENGTH = PGVECTOR_INITIALIZE_MAX_VECTOR_LENGTH
Base = declarative_base()
@@ -56,6 +57,9 @@ class PgvectorClient:
# Ensure the pgvector extension is available
self.session.execute(text("CREATE EXTENSION IF NOT EXISTS vector;"))
# Check vector length consistency
self.check_vector_length()
# Create the tables if they do not exist
# Base.metadata.create_all requires a bind (engine or connection)
# Get the connection from the session
@@ -82,6 +86,38 @@ class PgvectorClient:
print(f"Error during initialization: {e}")
raise
def check_vector_length(self) -> None:
"""
Check if the VECTOR_LENGTH matches the existing vector column dimension in the database.
Raises an exception if there is a mismatch.
"""
metadata = MetaData()
metadata.reflect(bind=self.session.bind, only=["document_chunk"])
if "document_chunk" in metadata.tables:
document_chunk_table = metadata.tables["document_chunk"]
if "vector" in document_chunk_table.columns:
vector_column = document_chunk_table.columns["vector"]
vector_type = vector_column.type
if isinstance(vector_type, Vector):
db_vector_length = vector_type.dim
if db_vector_length != VECTOR_LENGTH:
raise Exception(
f"VECTOR_LENGTH {VECTOR_LENGTH} does not match existing vector column dimension {db_vector_length}. "
"Cannot change vector size after initialization without migrating the data."
)
else:
raise Exception(
"The 'vector' column exists but is not of type 'Vector'."
)
else:
raise Exception(
"The 'vector' column does not exist in the 'document_chunk' table."
)
else:
# Table does not exist yet; no action needed
pass
def adjust_vector_length(self, vector: List[float]) -> List[float]:
# Adjust vector to have length VECTOR_LENGTH
current_length = len(vector)
+1 -1
View File
@@ -683,7 +683,7 @@
"age": "October 29, 2022",
"extra_snippets": [
"You can pass many options to the configure script; run ./configure --help to find out more. On macOS case-insensitive file systems and on Cygwin, the executable is called python.exe; elsewhere it's just python.",
"Building a complete Python installation requires the use of various additional third-party libraries, depending on your build platform and configure options. Not all standard library modules are buildable or useable on all platforms. Refer to the Install dependencies section of the Developer Guide for current detailed information on dependencies for various Linux distributions and macOS.",
"Building a complete Python installation requires the use of various additional third-party libraries, depending on your build platform and configure options. Not all standard library modules are buildable or usable on all platforms. Refer to the Install dependencies section of the Developer Guide for current detailed information on dependencies for various Linux distributions and macOS.",
"To get an optimized build of Python, configure --enable-optimizations before you run make. This sets the default make targets up to enable Profile Guided Optimization (PGO) and may be used to auto-enable Link Time Optimization (LTO) on some platforms. For more details, see the sections below.",
"Copyright © 2001-2024 Python Software Foundation. All rights reserved."
]
+1 -1
View File
@@ -311,7 +311,7 @@ async def speech(request: Request, user=Depends(get_verified_user)):
elif request.app.state.config.TTS_ENGINE == "elevenlabs":
voice_id = payload.get("voice", "")
if voice_id not in get_available_voices():
if voice_id not in get_available_voices(request):
raise HTTPException(
status_code=400,
detail="Invalid voice id",
+14
View File
@@ -616,6 +616,8 @@ async def get_admin_config(request: Request, user=Depends(get_admin_user)):
"WEBUI_URL": request.app.state.config.WEBUI_URL,
"ENABLE_SIGNUP": request.app.state.config.ENABLE_SIGNUP,
"ENABLE_API_KEY": request.app.state.config.ENABLE_API_KEY,
"ENABLE_API_KEY_ENDPOINT_RESTRICTIONS": request.app.state.config.ENABLE_API_KEY_ENDPOINT_RESTRICTIONS,
"API_KEY_ALLOWED_ENDPOINTS": request.app.state.config.API_KEY_ALLOWED_ENDPOINTS,
"ENABLE_CHANNELS": request.app.state.config.ENABLE_CHANNELS,
"DEFAULT_USER_ROLE": request.app.state.config.DEFAULT_USER_ROLE,
"JWT_EXPIRES_IN": request.app.state.config.JWT_EXPIRES_IN,
@@ -629,6 +631,8 @@ class AdminConfig(BaseModel):
WEBUI_URL: str
ENABLE_SIGNUP: bool
ENABLE_API_KEY: bool
ENABLE_API_KEY_ENDPOINT_RESTRICTIONS: bool
API_KEY_ALLOWED_ENDPOINTS: str
ENABLE_CHANNELS: bool
DEFAULT_USER_ROLE: str
JWT_EXPIRES_IN: str
@@ -643,7 +647,15 @@ async def update_admin_config(
request.app.state.config.SHOW_ADMIN_DETAILS = form_data.SHOW_ADMIN_DETAILS
request.app.state.config.WEBUI_URL = form_data.WEBUI_URL
request.app.state.config.ENABLE_SIGNUP = form_data.ENABLE_SIGNUP
request.app.state.config.ENABLE_API_KEY = form_data.ENABLE_API_KEY
request.app.state.config.ENABLE_API_KEY_ENDPOINT_RESTRICTIONS = (
form_data.ENABLE_API_KEY_ENDPOINT_RESTRICTIONS
)
request.app.state.config.API_KEY_ALLOWED_ENDPOINTS = (
form_data.API_KEY_ALLOWED_ENDPOINTS
)
request.app.state.config.ENABLE_CHANNELS = form_data.ENABLE_CHANNELS
if form_data.DEFAULT_USER_ROLE in ["pending", "user", "admin"]:
@@ -665,6 +677,8 @@ async def update_admin_config(
"WEBUI_URL": request.app.state.config.WEBUI_URL,
"ENABLE_SIGNUP": request.app.state.config.ENABLE_SIGNUP,
"ENABLE_API_KEY": request.app.state.config.ENABLE_API_KEY,
"ENABLE_API_KEY_ENDPOINT_RESTRICTIONS": request.app.state.config.ENABLE_API_KEY_ENDPOINT_RESTRICTIONS,
"API_KEY_ALLOWED_ENDPOINTS": request.app.state.config.API_KEY_ALLOWED_ENDPOINTS,
"ENABLE_CHANNELS": request.app.state.config.ENABLE_CHANNELS,
"DEFAULT_USER_ROLE": request.app.state.config.DEFAULT_USER_ROLE,
"JWT_EXPIRES_IN": request.app.state.config.JWT_EXPIRES_IN,
+329 -13
View File
@@ -11,7 +11,12 @@ from open_webui.socket.main import sio, get_user_ids_from_room
from open_webui.models.users import Users, UserNameResponse
from open_webui.models.channels import Channels, ChannelModel, ChannelForm
from open_webui.models.messages import Messages, MessageModel, MessageForm
from open_webui.models.messages import (
Messages,
MessageModel,
MessageResponse,
MessageForm,
)
from open_webui.config import ENABLE_ADMIN_CHAT_ACCESS, ENABLE_ADMIN_EXPORT
@@ -49,7 +54,7 @@ async def get_channels(user=Depends(get_verified_user)):
@router.post("/create", response_model=Optional[ChannelModel])
async def create_new_channel(form_data: ChannelForm, user=Depends(get_admin_user)):
try:
channel = Channels.insert_new_channel(form_data, user.id)
channel = Channels.insert_new_channel(None, form_data, user.id)
return ChannelModel(**channel.model_dump())
except Exception as e:
log.exception(e)
@@ -134,11 +139,11 @@ async def delete_channel_by_id(id: str, user=Depends(get_admin_user)):
############################
class MessageUserModel(MessageModel):
class MessageUserResponse(MessageResponse):
user: UserNameResponse
@router.get("/{id}/messages", response_model=list[MessageUserModel])
@router.get("/{id}/messages", response_model=list[MessageUserResponse])
async def get_channel_messages(
id: str, skip: int = 0, limit: int = 50, user=Depends(get_verified_user)
):
@@ -164,10 +169,16 @@ async def get_channel_messages(
user = Users.get_user_by_id(message.user_id)
users[message.user_id] = user
replies = Messages.get_replies_by_message_id(message.id)
latest_reply_at = replies[0].created_at if replies else None
messages.append(
MessageUserModel(
MessageUserResponse(
**{
**message.model_dump(),
"reply_count": len(replies),
"latest_reply_at": latest_reply_at,
"reactions": Messages.get_reactions_by_message_id(message.id),
"user": UserNameResponse(**users[message.user_id].model_dump()),
}
)
@@ -236,10 +247,17 @@ async def post_new_message(
"message_id": message.id,
"data": {
"type": "message",
"data": {
**message.model_dump(),
"user": UserNameResponse(**user.model_dump()).model_dump(),
},
"data": MessageUserResponse(
**{
**message.model_dump(),
"reply_count": 0,
"latest_reply_at": None,
"reactions": Messages.get_reactions_by_message_id(
message.id
),
"user": UserNameResponse(**user.model_dump()),
}
).model_dump(),
},
"user": UserNameResponse(**user.model_dump()).model_dump(),
"channel": channel.model_dump(),
@@ -251,6 +269,35 @@ async def post_new_message(
to=f"channel:{channel.id}",
)
if message.parent_id:
# If this message is a reply, emit to the parent message as well
parent_message = Messages.get_message_by_id(message.parent_id)
if parent_message:
await sio.emit(
"channel-events",
{
"channel_id": channel.id,
"message_id": parent_message.id,
"data": {
"type": "message:reply",
"data": MessageUserResponse(
**{
**parent_message.model_dump(),
"user": UserNameResponse(
**Users.get_user_by_id(
parent_message.user_id
).model_dump()
),
}
).model_dump(),
},
"user": UserNameResponse(**user.model_dump()).model_dump(),
"channel": channel.model_dump(),
},
to=f"channel:{channel.id}",
)
active_user_ids = get_user_ids_from_room(f"channel:{channel.id}")
background_tasks.add_task(
@@ -269,6 +316,101 @@ async def post_new_message(
)
############################
# GetChannelMessage
############################
@router.get("/{id}/messages/{message_id}", response_model=Optional[MessageUserResponse])
async def get_channel_message(
id: str, message_id: str, user=Depends(get_verified_user)
):
channel = Channels.get_channel_by_id(id)
if not channel:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND
)
if user.role != "admin" and not has_access(
user.id, type="read", access_control=channel.access_control
):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT()
)
message = Messages.get_message_by_id(message_id)
if not message:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND
)
if message.channel_id != id:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT()
)
return MessageUserResponse(
**{
**message.model_dump(),
"user": UserNameResponse(
**Users.get_user_by_id(message.user_id).model_dump()
),
}
)
############################
# GetChannelThreadMessages
############################
@router.get(
"/{id}/messages/{message_id}/thread", response_model=list[MessageUserResponse]
)
async def get_channel_thread_messages(
id: str,
message_id: str,
skip: int = 0,
limit: int = 50,
user=Depends(get_verified_user),
):
channel = Channels.get_channel_by_id(id)
if not channel:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND
)
if user.role != "admin" and not has_access(
user.id, type="read", access_control=channel.access_control
):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT()
)
message_list = Messages.get_messages_by_parent_id(id, message_id, skip, limit)
users = {}
messages = []
for message in message_list:
if message.user_id not in users:
user = Users.get_user_by_id(message.user_id)
users[message.user_id] = user
messages.append(
MessageUserResponse(
**{
**message.model_dump(),
"reply_count": 0,
"latest_reply_at": None,
"reactions": Messages.get_reactions_by_message_id(message.id),
"user": UserNameResponse(**users[message.user_id].model_dump()),
}
)
)
return messages
############################
# UpdateMessageById
############################
@@ -306,6 +448,8 @@ async def update_message_by_id(
try:
message = Messages.update_message_by_id(message_id, form_data)
message = Messages.get_message_by_id(message_id)
if message:
await sio.emit(
"channel-events",
@@ -314,10 +458,14 @@ async def update_message_by_id(
"message_id": message.id,
"data": {
"type": "message:update",
"data": {
**message.model_dump(),
"user": UserNameResponse(**user.model_dump()).model_dump(),
},
"data": MessageUserResponse(
**{
**message.model_dump(),
"user": UserNameResponse(
**user.model_dump()
).model_dump(),
}
).model_dump(),
},
"user": UserNameResponse(**user.model_dump()).model_dump(),
"channel": channel.model_dump(),
@@ -333,6 +481,145 @@ async def update_message_by_id(
)
############################
# AddReactionToMessage
############################
class ReactionForm(BaseModel):
name: str
@router.post("/{id}/messages/{message_id}/reactions/add", response_model=bool)
async def add_reaction_to_message(
id: str, message_id: str, form_data: ReactionForm, user=Depends(get_verified_user)
):
channel = Channels.get_channel_by_id(id)
if not channel:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND
)
if user.role != "admin" and not has_access(
user.id, type="read", access_control=channel.access_control
):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT()
)
message = Messages.get_message_by_id(message_id)
if not message:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND
)
if message.channel_id != id:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT()
)
try:
Messages.add_reaction_to_message(message_id, user.id, form_data.name)
message = Messages.get_message_by_id(message_id)
await sio.emit(
"channel-events",
{
"channel_id": channel.id,
"message_id": message.id,
"data": {
"type": "message:reaction:add",
"data": {
**message.model_dump(),
"user": UserNameResponse(
**Users.get_user_by_id(message.user_id).model_dump()
).model_dump(),
"name": form_data.name,
},
},
"user": UserNameResponse(**user.model_dump()).model_dump(),
"channel": channel.model_dump(),
},
to=f"channel:{channel.id}",
)
return True
except Exception as e:
log.exception(e)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT()
)
############################
# RemoveReactionById
############################
@router.post("/{id}/messages/{message_id}/reactions/remove", response_model=bool)
async def remove_reaction_by_id_and_user_id_and_name(
id: str, message_id: str, form_data: ReactionForm, user=Depends(get_verified_user)
):
channel = Channels.get_channel_by_id(id)
if not channel:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND
)
if user.role != "admin" and not has_access(
user.id, type="read", access_control=channel.access_control
):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT()
)
message = Messages.get_message_by_id(message_id)
if not message:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail=ERROR_MESSAGES.NOT_FOUND
)
if message.channel_id != id:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT()
)
try:
Messages.remove_reaction_by_id_and_user_id_and_name(
message_id, user.id, form_data.name
)
message = Messages.get_message_by_id(message_id)
await sio.emit(
"channel-events",
{
"channel_id": channel.id,
"message_id": message.id,
"data": {
"type": "message:reaction:remove",
"data": {
**message.model_dump(),
"user": UserNameResponse(
**Users.get_user_by_id(message.user_id).model_dump()
).model_dump(),
"name": form_data.name,
},
},
"user": UserNameResponse(**user.model_dump()).model_dump(),
"channel": channel.model_dump(),
},
to=f"channel:{channel.id}",
)
return True
except Exception as e:
log.exception(e)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT()
)
############################
# DeleteMessageById
############################
@@ -386,6 +673,35 @@ async def delete_message_by_id(
to=f"channel:{channel.id}",
)
if message.parent_id:
# If this message is a reply, emit to the parent message as well
parent_message = Messages.get_message_by_id(message.parent_id)
if parent_message:
await sio.emit(
"channel-events",
{
"channel_id": channel.id,
"message_id": parent_message.id,
"data": {
"type": "message:reply",
"data": MessageUserResponse(
**{
**parent_message.model_dump(),
"user": UserNameResponse(
**Users.get_user_by_id(
parent_message.user_id
).model_dump()
),
}
).model_dump(),
},
"user": UserNameResponse(**user.model_dump()).model_dump(),
"channel": channel.model_dump(),
},
to=f"channel:{channel.id}",
)
return True
except Exception as e:
log.exception(e)
+24
View File
@@ -463,6 +463,30 @@ async def clone_chat_by_id(id: str, user=Depends(get_verified_user)):
)
############################
# CloneSharedChatById
############################
@router.post("/{id}/clone/shared", response_model=Optional[ChatResponse])
async def clone_shared_chat_by_id(id: str, user=Depends(get_verified_user)):
chat = Chats.get_chat_by_share_id(id)
if chat:
updated_chat = {
**chat.chat,
"originalChatId": chat.id,
"branchPointMessageId": chat.chat["history"]["currentId"],
"title": f"Clone of {chat.title}",
}
chat = Chats.insert_new_chat(user.id, ChatForm(**{"chat": updated_chat}))
return ChatResponse(**chat.model_dump())
else:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.DEFAULT()
)
############################
# ArchiveChat
############################
+1 -1
View File
@@ -348,7 +348,7 @@ async def delete_file_by_id(id: str, user=Depends(get_verified_user)):
result = Files.delete_file_by_id(id)
if result:
try:
Storage.delete_file(file.filename)
Storage.delete_file(file.path)
except Exception as e:
log.exception(e)
log.error(f"Error deleting files")
+3 -3
View File
@@ -236,7 +236,7 @@ def get_image_model(request):
try:
r = requests.get(
url=f"{request.app.state.config.AUTOMATIC1111_BASE_URL}/sdapi/v1/options",
headers={"authorization": get_automatic1111_api_auth()},
headers={"authorization": get_automatic1111_api_auth(request)},
)
options = r.json()
return options["sd_model_checkpoint"]
@@ -354,7 +354,7 @@ def get_models(request: Request, user=Depends(get_verified_user)):
):
r = requests.get(
url=f"{request.app.state.config.AUTOMATIC1111_BASE_URL}/sdapi/v1/sd-models",
headers={"authorization": get_automatic1111_api_auth()},
headers={"authorization": get_automatic1111_api_auth(request)},
)
models = r.json()
return list(
@@ -578,7 +578,7 @@ async def image_generations(
requests.post,
url=f"{request.app.state.config.AUTOMATIC1111_BASE_URL}/sdapi/v1/txt2img",
json=data,
headers={"authorization": get_automatic1111_api_auth()},
headers={"authorization": get_automatic1111_api_auth(request)},
)
res = r.json()
+4 -8
View File
@@ -419,13 +419,6 @@ def remove_file_from_knowledge_by_id(
collection_name=knowledge.id, filter={"file_id": form_data.file_id}
)
result = VECTOR_DB_CLIENT.query(
collection_name=knowledge.id,
filter={"file_id": form_data.file_id},
)
Files.delete_file_by_id(form_data.file_id)
if knowledge:
data = knowledge.data or {}
file_ids = data.get("file_ids", [])
@@ -527,6 +520,7 @@ async def reset_knowledge_by_id(id: str, user=Depends(get_verified_user)):
@router.post("/{id}/files/batch/add", response_model=Optional[KnowledgeFilesResponse])
def add_files_to_knowledge_batch(
request: Request,
id: str,
form_data: list[KnowledgeFileIdForm],
user=Depends(get_verified_user),
@@ -562,7 +556,9 @@ def add_files_to_knowledge_batch(
# Process files
try:
result = process_files_batch(
BatchProcessFilesForm(files=files, collection_name=id)
request=request,
form_data=BatchProcessFilesForm(files=files, collection_name=id),
user=user,
)
except Exception as e:
log.error(
+3 -7
View File
@@ -124,18 +124,14 @@ def process_pipeline_outlet_filter(request, payload, user, models):
f"{url}/{filter['id']}/filter/outlet",
headers={"Authorization": f"Bearer {key}"},
json={
"user": {
"id": user.id,
"name": user.name,
"email": user.email,
"role": user.role,
},
"body": data,
"user": user,
"body": payload,
},
)
r.raise_for_status()
data = r.json()
payload = data
except Exception as e:
# Handle connection error here
print(f"Connection error: {e}")
+6 -2
View File
@@ -347,7 +347,7 @@ async def get_rag_config(request: Request, user=Depends(get_admin_user)):
return {
"status": True,
"pdf_extract_images": request.app.state.config.PDF_EXTRACT_IMAGES,
"ENABLE_GOOGLE_DRIVE_INTEGRATION": request.app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION,
"enable_google_drive_integration": request.app.state.config.ENABLE_GOOGLE_DRIVE_INTEGRATION,
"content_extraction": {
"engine": request.app.state.config.CONTENT_EXTRACTION_ENGINE,
"tika_server_url": request.app.state.config.TIKA_SERVER_URL,
@@ -1458,6 +1458,7 @@ class BatchProcessFilesResponse(BaseModel):
@router.post("/process/files/batch")
def process_files_batch(
request: Request,
form_data: BatchProcessFilesForm,
user=Depends(get_verified_user),
) -> BatchProcessFilesResponse:
@@ -1504,7 +1505,10 @@ def process_files_batch(
if all_docs:
try:
save_docs_to_vector_db(
docs=all_docs, collection_name=collection_name, add=True
request=request,
docs=all_docs,
collection_name=collection_name,
add=True,
)
# Update all files with collection name
+1 -1
View File
@@ -499,8 +499,8 @@ async def generate_moa_response(
"model": task_model_id,
"messages": [{"role": "user", "content": content}],
"stream": form_data.get("stream", False),
"chat_id": form_data.get("chat_id", None),
"metadata": {
"chat_id": form_data.get("chat_id", None),
"task": str(TASKS.MOA_RESPONSE_GENERATION),
"task_body": form_data,
},
+11 -1
View File
@@ -10,6 +10,9 @@ from open_webui.models.users import (
UserSettings,
UserUpdateForm,
)
from open_webui.socket.main import get_active_status_by_user_id
from open_webui.constants import ERROR_MESSAGES
from open_webui.env import SRC_LOG_LEVELS
from fastapi import APIRouter, Depends, HTTPException, Request, status
@@ -196,6 +199,7 @@ async def update_user_info_by_session_user(
class UserResponse(BaseModel):
name: str
profile_image_url: str
active: Optional[bool] = None
@router.get("/{user_id}", response_model=UserResponse)
@@ -216,7 +220,13 @@ async def get_user_by_id(user_id: str, user=Depends(get_verified_user)):
user = Users.get_user_by_id(user_id)
if user:
return UserResponse(name=user.name, profile_image_url=user.profile_image_url)
return UserResponse(
**{
"name": user.name,
"profile_image_url": user.profile_image_url,
"active": get_active_status_by_user_id(user_id),
}
)
else:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
+78 -15
View File
@@ -4,7 +4,7 @@ import logging
import sys
import time
from open_webui.models.users import Users
from open_webui.models.users import Users, UserNameResponse
from open_webui.models.channels import Channels
from open_webui.models.chats import Chats
@@ -152,14 +152,14 @@ async def connect(sid, environ, auth):
user = Users.get_user_by_id(data["id"])
if user:
SESSION_POOL[sid] = user.id
SESSION_POOL[sid] = user.model_dump()
if user.id in USER_POOL:
USER_POOL[user.id] = USER_POOL[user.id] + [sid]
else:
USER_POOL[user.id] = [sid]
# print(f"user {user.name}({user.id}) connected with session ID {sid}")
await sio.emit("user-count", {"count": len(USER_POOL.items())})
await sio.emit("user-list", {"user_ids": list(USER_POOL.keys())})
await sio.emit("usage", {"models": get_models_in_use()})
@@ -178,7 +178,7 @@ async def user_join(sid, data):
if not user:
return
SESSION_POOL[sid] = user.id
SESSION_POOL[sid] = user.model_dump()
if user.id in USER_POOL:
USER_POOL[user.id] = USER_POOL[user.id] + [sid]
else:
@@ -192,7 +192,7 @@ async def user_join(sid, data):
# print(f"user {user.name}({user.id}) connected with session ID {sid}")
await sio.emit("user-count", {"count": len(USER_POOL.items())})
await sio.emit("user-list", {"user_ids": list(USER_POOL.keys())})
return {"id": user.id, "name": user.name}
@@ -217,28 +217,52 @@ async def join_channel(sid, data):
await sio.enter_room(sid, f"channel:{channel.id}")
@sio.on("user-count")
async def user_count(sid):
await sio.emit("user-count", {"count": len(USER_POOL.items())})
@sio.on("channel-events")
async def channel_events(sid, data):
room = f"channel:{data['channel_id']}"
participants = sio.manager.get_participants(
namespace="/",
room=room,
)
sids = [sid for sid, _ in participants]
if sid not in sids:
return
event_data = data["data"]
event_type = event_data["type"]
if event_type == "typing":
await sio.emit(
"channel-events",
{
"channel_id": data["channel_id"],
"message_id": data.get("message_id", None),
"data": event_data,
"user": UserNameResponse(**SESSION_POOL[sid]).model_dump(),
},
room=room,
)
@sio.on("chat")
async def chat(sid, data):
print("chat", sid, SESSION_POOL[sid], data)
@sio.on("user-list")
async def user_list(sid):
await sio.emit("user-list", {"user_ids": list(USER_POOL.keys())})
@sio.event
async def disconnect(sid):
if sid in SESSION_POOL:
user_id = SESSION_POOL[sid]
user = SESSION_POOL[sid]
del SESSION_POOL[sid]
user_id = user["id"]
USER_POOL[user_id] = [_sid for _sid in USER_POOL[user_id] if _sid != sid]
if len(USER_POOL[user_id]) == 0:
del USER_POOL[user_id]
await sio.emit("user-count", {"count": len(USER_POOL)})
await sio.emit("user-list", {"user_ids": list(USER_POOL.keys())})
else:
pass
# print(f"Unknown session ID {sid} disconnected")
@@ -269,6 +293,34 @@ def get_event_emitter(request_info):
event_data.get("data", {}),
)
if "type" in event_data and event_data["type"] == "message":
message = Chats.get_message_by_id_and_message_id(
request_info["chat_id"],
request_info["message_id"],
)
content = message.get("content", "")
content += event_data.get("data", {}).get("content", "")
Chats.upsert_message_to_chat_by_id_and_message_id(
request_info["chat_id"],
request_info["message_id"],
{
"content": content,
},
)
if "type" in event_data and event_data["type"] == "replace":
content = event_data.get("data", {}).get("content", "")
Chats.upsert_message_to_chat_by_id_and_message_id(
request_info["chat_id"],
request_info["message_id"],
{
"content": content,
},
)
return __event_emitter__
@@ -289,7 +341,10 @@ def get_event_call(request_info):
def get_user_id_from_session_pool(sid):
return SESSION_POOL.get(sid)
user = SESSION_POOL.get(sid)
if user:
return user["id"]
return None
def get_user_ids_from_room(room):
@@ -299,6 +354,14 @@ def get_user_ids_from_room(room):
)
active_user_ids = list(
set([SESSION_POOL.get(session_id[0]) for session_id in active_session_ids])
set(
[SESSION_POOL.get(session_id[0])["id"] for session_id in active_session_ids]
)
)
return active_user_ids
def get_active_status_by_user_id(user_id):
if user_id in USER_POOL:
return True
return False
+3 -1
View File
@@ -147,8 +147,10 @@ class StorageProvider:
return self._get_file_from_s3(file_path)
return self._get_file_from_local(file_path)
def delete_file(self, filename: str) -> None:
def delete_file(self, file_path: str) -> None:
"""Deletes a file either from S3 or the local file system."""
filename = file_path.split("/")[-1]
if self.storage_provider == "s3":
self._delete_from_s3(filename)
+12 -5
View File
@@ -96,11 +96,18 @@ def get_current_user(
status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.API_KEY_NOT_ALLOWED
)
allowed_paths = ["/api/models", "/api/chat/completions"]
if request.url.path not in allowed_paths:
raise HTTPException(
status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.API_KEY_NOT_ALLOWED
)
if request.app.state.config.ENABLE_API_KEY_ENDPOINT_RESTRICTIONS:
allowed_paths = [
path.strip()
for path in str(
request.app.state.config.API_KEY_ALLOWED_ENDPOINTS
).split(",")
]
if request.url.path not in allowed_paths:
raise HTTPException(
status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.API_KEY_NOT_ALLOWED
)
return get_current_user_by_api_key(token)
+7
View File
@@ -157,6 +157,9 @@ async def generate_chat_completion(
)
chat_completion = generate_chat_completion
async def chat_completed(request: Request, form_data: dict, user: Any):
if not request.app.state.MODELS:
await get_all_models(request)
@@ -179,6 +182,7 @@ async def chat_completed(request: Request, form_data: dict, user: Any):
"chat_id": data["chat_id"],
"message_id": data["id"],
"session_id": data["session_id"],
"user_id": user.id,
}
)
@@ -187,6 +191,7 @@ async def chat_completed(request: Request, form_data: dict, user: Any):
"chat_id": data["chat_id"],
"message_id": data["id"],
"session_id": data["session_id"],
"user_id": user.id,
}
)
@@ -310,6 +315,7 @@ async def chat_action(request: Request, action_id: str, form_data: dict, user: A
"chat_id": data["chat_id"],
"message_id": data["id"],
"session_id": data["session_id"],
"user_id": user.id,
}
)
__event_call__ = get_event_call(
@@ -317,6 +323,7 @@ async def chat_action(request: Request, action_id: str, form_data: dict, user: A
"chat_id": data["chat_id"],
"message_id": data["id"],
"session_id": data["session_id"],
"user_id": user.id,
}
)
+78 -42
View File
@@ -23,7 +23,7 @@ from open_webui.models.users import Users
from open_webui.socket.main import (
get_event_call,
get_event_emitter,
get_user_id_from_session_pool,
get_active_status_by_user_id,
)
from open_webui.routers.tasks import (
generate_queries,
@@ -65,6 +65,7 @@ from open_webui.env import (
SRC_LOG_LEVELS,
GLOBAL_LOG_LEVEL,
BYPASS_MODEL_ACCESS_CONTROL,
ENABLE_REALTIME_CHAT_SAVE,
)
from open_webui.constants import TASKS
@@ -493,6 +494,7 @@ async def chat_completion_files_handler(
if files := body.get("metadata", {}).get("files", None):
try:
queries_response = await generate_queries(
request,
{
"model": body["model"],
"messages": body["messages"],
@@ -560,7 +562,6 @@ def apply_params_to_form_data(form_data, model):
if "frequency_penalty" in params:
form_data["frequency_penalty"] = params["frequency_penalty"]
return form_data
@@ -644,7 +645,7 @@ async def process_chat_payload(request, form_data, metadata, user, model):
request, form_data, model, extra_params
)
except Exception as e:
return Exception(f"Error: {e}")
raise Exception(f"Error: {e}")
tool_ids = form_data.pop("tool_ids", None)
files = form_data.pop("files", None)
@@ -750,7 +751,7 @@ async def process_chat_response(
):
async def background_tasks_handler():
message_map = Chats.get_messages_by_chat_id(metadata["chat_id"])
message = message_map.get(metadata["message_id"])
message = message_map.get(metadata["message_id"]) if message_map else None
if message:
messages = get_message_list(message_map, message.get("id"))
@@ -776,7 +777,10 @@ async def process_chat_response(
"content",
message.get("content", "New Chat"),
)
)
).strip()
if not title:
title = messages[0].get("content", "New Chat")
Chats.update_chat_title_by_id(metadata["chat_id"], title)
@@ -893,7 +897,7 @@ async def process_chat_response(
)
# Send a webhook notification if the user is not active
if get_user_id_from_session_pool(metadata["session_id"]) is None:
if get_active_status_by_user_id(user.id) is None:
webhook_url = Users.get_user_webhook_url_by_id(user.id)
if webhook_url:
post_webhook(
@@ -925,6 +929,11 @@ async def process_chat_response(
# Handle as a background task
async def post_response_handler(response, events):
message = Chats.get_message_by_id_and_message_id(
metadata["chat_id"], metadata["message_id"]
)
content = message.get("content", "") if message else ""
try:
for event in events:
await event_emitter(
@@ -943,9 +952,6 @@ async def process_chat_response(
},
)
assistant_message = get_last_assistant_message(form_data["messages"])
content = assistant_message if assistant_message else ""
async for line in response.body_iterator:
line = line.decode("utf-8") if isinstance(line, bytes) else line
data = line
@@ -974,7 +980,6 @@ async def process_chat_response(
)
else:
value = (
data.get("choices", [])[0]
.get("delta", {})
@@ -984,55 +989,85 @@ async def process_chat_response(
if value:
content = f"{content}{value}"
# Save message in the database
Chats.upsert_message_to_chat_by_id_and_message_id(
metadata["chat_id"],
metadata["message_id"],
{
if ENABLE_REALTIME_CHAT_SAVE:
# Save message in the database
Chats.upsert_message_to_chat_by_id_and_message_id(
metadata["chat_id"],
metadata["message_id"],
{
"content": content,
},
)
else:
data = {
"content": content,
},
)
}
await event_emitter(
{
"type": "chat:completion",
"data": data,
}
)
except Exception as e:
done = "data: [DONE]" in line
title = Chats.get_chat_title_by_id(metadata["chat_id"])
if done:
data = {"done": True, "content": content, "title": title}
# Send a webhook notification if the user is not active
if (
get_user_id_from_session_pool(metadata["session_id"])
is None
):
webhook_url = Users.get_user_webhook_url_by_id(user.id)
if webhook_url:
post_webhook(
webhook_url,
f"{title} - {request.app.state.config.WEBUI_URL}/c/{metadata['chat_id']}\n\n{content}",
{
"action": "chat",
"message": content,
"title": title,
"url": f"{request.app.state.config.WEBUI_URL}/c/{metadata['chat_id']}",
},
)
pass
else:
continue
await event_emitter(
title = Chats.get_chat_title_by_id(metadata["chat_id"])
data = {"done": True, "content": content, "title": title}
if not ENABLE_REALTIME_CHAT_SAVE:
# Save message in the database
Chats.upsert_message_to_chat_by_id_and_message_id(
metadata["chat_id"],
metadata["message_id"],
{
"type": "chat:completion",
"data": data,
}
"content": content,
},
)
# Send a webhook notification if the user is not active
if get_active_status_by_user_id(user.id) is None:
webhook_url = Users.get_user_webhook_url_by_id(user.id)
if webhook_url:
post_webhook(
webhook_url,
f"{title} - {request.app.state.config.WEBUI_URL}/c/{metadata['chat_id']}\n\n{content}",
{
"action": "chat",
"message": content,
"title": title,
"url": f"{request.app.state.config.WEBUI_URL}/c/{metadata['chat_id']}",
},
)
await event_emitter(
{
"type": "chat:completion",
"data": data,
}
)
await background_tasks_handler()
except asyncio.CancelledError:
print("Task was cancelled!")
await event_emitter({"type": "task-cancelled"})
if not ENABLE_REALTIME_CHAT_SAVE:
# Save message in the database
Chats.upsert_message_to_chat_by_id_and_message_id(
metadata["chat_id"],
metadata["message_id"],
{
"content": content,
},
)
if response.background is not None:
await response.background()
@@ -1056,4 +1091,5 @@ async def process_chat_response(
return StreamingResponse(
stream_wrapper(response.body_iterator, events),
headers=dict(response.headers),
background=response.background,
)
+4
View File
@@ -160,6 +160,10 @@ def convert_payload_openai_to_ollama(openai_payload: dict) -> dict:
# If there are advanced parameters in the payload, format them in Ollama's options field
ollama_options = {}
if openai_payload.get("options"):
ollama_payload["options"] = openai_payload["options"]
ollama_options = openai_payload["options"]
# Handle parameters which map directly
for param in ["temperature", "top_p", "seed"]:
if param in openai_payload:
+6 -19
View File
@@ -29,7 +29,7 @@ async def convert_streaming_response_ollama_to_openai(ollama_streaming_response)
(
(
data.get("eval_count", 0)
/ ((data.get("eval_duration", 0) / 1_000_000_000))
/ ((data.get("eval_duration", 0) / 10_000_000))
)
* 100
),
@@ -43,12 +43,7 @@ async def convert_streaming_response_ollama_to_openai(ollama_streaming_response)
(
(
data.get("prompt_eval_count", 0)
/ (
(
data.get("prompt_eval_duration", 0)
/ 1_000_000_000
)
)
/ ((data.get("prompt_eval_duration", 0) / 10_000_000))
)
* 100
),
@@ -57,20 +52,12 @@ async def convert_streaming_response_ollama_to_openai(ollama_streaming_response)
if data.get("prompt_eval_duration", 0) > 0
else "N/A"
),
"total_duration": round(
((data.get("total_duration", 0) / 1_000_000) * 100), 2
),
"load_duration": round(
((data.get("load_duration", 0) / 1_000_000) * 100), 2
),
"total_duration": data.get("total_duration", 0),
"load_duration": data.get("load_duration", 0),
"prompt_eval_count": data.get("prompt_eval_count", 0),
"prompt_eval_duration": round(
((data.get("prompt_eval_duration", 0) / 1_000_000) * 100), 2
),
"prompt_eval_duration": data.get("prompt_eval_duration", 0),
"eval_count": data.get("eval_count", 0),
"eval_duration": round(
((data.get("eval_duration", 0) / 1_000_000) * 100), 2
),
"eval_duration": data.get("eval_duration", 0),
"approximate_total": (
lambda s: f"{s // 3600}h{(s % 3600) // 60}m{s % 60}s"
)((data.get("total_duration", 0) or 0) // 1_000_000_000),
+5 -5
View File
@@ -3,7 +3,7 @@ uvicorn[standard]==0.30.6
pydantic==2.9.2
python-multipart==0.0.18
Flask==3.0.3
Flask==3.1.0
Flask-Cors==5.0.0
python-socketio==5.11.3
@@ -18,7 +18,7 @@ aiofiles
sqlalchemy==2.0.32
alembic==1.14.0
peewee==3.17.6
peewee==3.17.8
peewee-migrate==1.12.2
psycopg2-binary==2.9.9
pgvector==0.3.5
@@ -55,7 +55,7 @@ einops==0.8.0
ftfy==6.2.3
pypdf==4.3.1
fpdf2==2.7.9
fpdf2==2.8.2
pymdown-extensions==10.11.2
docx2txt==0.8
python-pptx==1.0.0
@@ -67,7 +67,7 @@ pandas==2.2.3
openpyxl==3.1.5
pyxlsb==1.0.10
xlrd==2.0.1
validators==0.33.0
validators==0.34.0
psutil
sentencepiece
soundfile==0.12.1
@@ -78,7 +78,7 @@ rank-bm25==0.2.2
faster-whisper==1.0.3
PyJWT[crypto]==2.9.0
PyJWT[crypto]==2.10.1
authlib==1.3.2
black==24.8.0
+9 -2
View File
@@ -1,12 +1,12 @@
{
"name": "open-webui",
"version": "0.5.1",
"version": "0.5.4",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "open-webui",
"version": "0.5.1",
"version": "0.5.4",
"dependencies": {
"@codemirror/lang-javascript": "^6.2.2",
"@codemirror/lang-python": "^6.1.6",
@@ -16,6 +16,7 @@
"@mediapipe/tasks-vision": "^0.10.17",
"@pyscript/core": "^0.4.32",
"@sveltejs/adapter-node": "^2.0.0",
"@sveltejs/svelte-virtual-list": "^3.0.1",
"@tiptap/core": "^2.10.0",
"@tiptap/extension-code-block-lowlight": "^2.10.0",
"@tiptap/extension-highlight": "^2.10.0",
@@ -2291,6 +2292,12 @@
"vite": "^5.0.3 || ^6.0.0"
}
},
"node_modules/@sveltejs/svelte-virtual-list": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@sveltejs/svelte-virtual-list/-/svelte-virtual-list-3.0.1.tgz",
"integrity": "sha512-aF9TptS7NKKS7/TqpsxQBSDJ9Q0XBYzBehCeIC5DzdMEgrJZpIYao9LRLnyyo6SVodpapm2B7FE/Lj+FSA5/SQ==",
"license": "LIL"
},
"node_modules/@sveltejs/vite-plugin-svelte": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.1.tgz",
+3 -2
View File
@@ -1,6 +1,6 @@
{
"name": "open-webui",
"version": "0.5.1",
"version": "0.5.4",
"private": true,
"scripts": {
"dev": "npm run pyodide:fetch && vite dev --host",
@@ -50,7 +50,6 @@
"type": "module",
"dependencies": {
"@codemirror/lang-javascript": "^6.2.2",
"codemirror-lang-hcl": "^0.0.0-beta.2",
"@codemirror/lang-python": "^6.1.6",
"@codemirror/language-data": "^6.5.1",
"@codemirror/theme-one-dark": "^6.1.2",
@@ -58,6 +57,7 @@
"@mediapipe/tasks-vision": "^0.10.17",
"@pyscript/core": "^0.4.32",
"@sveltejs/adapter-node": "^2.0.0",
"@sveltejs/svelte-virtual-list": "^3.0.1",
"@tiptap/core": "^2.10.0",
"@tiptap/extension-code-block-lowlight": "^2.10.0",
"@tiptap/extension-highlight": "^2.10.0",
@@ -69,6 +69,7 @@
"async": "^3.2.5",
"bits-ui": "^0.19.7",
"codemirror": "^6.0.1",
"codemirror-lang-hcl": "^0.0.0-beta.2",
"crc-32": "^1.2.2",
"dayjs": "^1.11.10",
"dompurify": "^3.1.6",
+12 -5
View File
@@ -11,7 +11,7 @@ dependencies = [
"pydantic==2.9.2",
"python-multipart==0.0.18",
"Flask==3.0.3",
"Flask==3.1.0",
"Flask-Cors==5.0.0",
"python-socketio==5.11.3",
@@ -26,7 +26,7 @@ dependencies = [
"sqlalchemy==2.0.32",
"alembic==1.14.0",
"peewee==3.17.6",
"peewee==3.17.8",
"peewee-migrate==1.12.2",
"psycopg2-binary==2.9.9",
"pgvector==0.3.5",
@@ -61,7 +61,7 @@ dependencies = [
"ftfy==6.2.3",
"pypdf==4.3.1",
"fpdf2==2.7.9",
"fpdf2==2.8.2",
"pymdown-extensions==10.11.2",
"docx2txt==0.8",
"python-pptx==1.0.0",
@@ -73,7 +73,7 @@ dependencies = [
"openpyxl==3.1.5",
"pyxlsb==1.0.10",
"xlrd==2.0.1",
"validators==0.33.0",
"validators==0.34.0",
"psutil",
"sentencepiece",
"soundfile==0.12.1",
@@ -84,7 +84,7 @@ dependencies = [
"faster-whisper==1.0.3",
"PyJWT[crypto]==2.9.0",
"PyJWT[crypto]==2.10.1",
"authlib==1.3.2",
"black==24.8.0",
@@ -151,3 +151,10 @@ exclude = [
"chroma.sqlite3",
]
force-include = { "CHANGELOG.md" = "open_webui/CHANGELOG.md", build = "open_webui/frontend" }
[tool.codespell]
# Ref: https://github.com/codespell-project/codespell#using-a-config-file
skip = '.git*,*.svg,package-lock.json,i18n,*.lock,*.css,*-bundle.js,locales,example-doc.txt,emoji-shortcodes.json'
check-hidden = true
# ignore-regex = ''
ignore-words-list = 'ans'
+122
View File
@@ -1,4 +1,5 @@
import { WEBUI_API_BASE_URL } from '$lib/constants';
import { t } from 'i18next';
type ChannelForm = {
name: string;
@@ -207,7 +208,48 @@ export const getChannelMessages = async (
return res;
};
export const getChannelThreadMessages = async (
token: string = '',
channel_id: string,
message_id: string,
skip: number = 0,
limit: number = 50
) => {
let error = null;
const res = await fetch(
`${WEBUI_API_BASE_URL}/channels/${channel_id}/messages/${message_id}/thread?skip=${skip}&limit=${limit}`,
{
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
authorization: `Bearer ${token}`
}
}
)
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.then((json) => {
return json;
})
.catch((err) => {
error = err.detail;
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};
type MessageForm = {
parent_id?: string;
content: string;
data?: object;
meta?: object;
@@ -285,6 +327,86 @@ export const updateMessage = async (
return res;
};
export const addReaction = async (
token: string = '',
channel_id: string,
message_id: string,
name: string
) => {
let error = null;
const res = await fetch(
`${WEBUI_API_BASE_URL}/channels/${channel_id}/messages/${message_id}/reactions/add`,
{
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
authorization: `Bearer ${token}`
},
body: JSON.stringify({ name })
}
)
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.then((json) => {
return json;
})
.catch((err) => {
error = err.detail;
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};
export const removeReaction = async (
token: string = '',
channel_id: string,
message_id: string,
name: string
) => {
let error = null;
const res = await fetch(
`${WEBUI_API_BASE_URL}/channels/${channel_id}/messages/${message_id}/reactions/remove`,
{
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
authorization: `Bearer ${token}`
},
body: JSON.stringify({ name })
}
)
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.then((json) => {
return json;
})
.catch((err) => {
error = err.detail;
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};
export const deleteMessage = async (token: string = '', channel_id: string, message_id: string) => {
let error = null;
+38
View File
@@ -618,6 +618,44 @@ export const cloneChatById = async (token: string, id: string) => {
return res;
};
export const cloneSharedChatById = async (token: string, id: string) => {
let error = null;
const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/clone/shared`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
...(token && { authorization: `Bearer ${token}` })
}
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.then((json) => {
return json;
})
.catch((err) => {
error = err;
if ('detail' in err) {
error = err.detail;
} else {
error = err;
}
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};
export const shareChatById = async (token: string, id: string) => {
let error = null;
+14 -3
View File
@@ -1,5 +1,5 @@
<script lang="ts">
import { settings } from '$lib/stores';
import { settings, playingNotificationSound, isLastActiveTab } from '$lib/stores';
import DOMPurify from 'dompurify';
import { marked } from 'marked';
@@ -12,9 +12,20 @@
export let content: string;
onMount(() => {
if (!navigator.userActivation.hasBeenActive) {
return;
}
if ($settings?.notificationSound ?? true) {
const audio = new Audio(`/audio/notification.mp3`);
audio.play();
if (!$playingNotificationSound && $isLastActiveTab) {
playingNotificationSound.set(true);
const audio = new Audio(`/audio/notification.mp3`);
audio.play().finally(() => {
// Ensure the global state is reset after the sound finishes
playingNotificationSound.set(false);
});
}
}
});
</script>
@@ -112,12 +112,48 @@
</div>
</div>
<div class=" flex w-full justify-between pr-2">
<div class=" self-center text-xs font-medium">{$i18n.t('Enable API Key Auth')}</div>
<div class=" flex w-full justify-between pr-2 my-3">
<div class=" self-center text-xs font-medium">{$i18n.t('Enable API Key')}</div>
<Switch bind:state={adminConfig.ENABLE_API_KEY} />
</div>
{#if adminConfig?.ENABLE_API_KEY}
<div class=" flex w-full justify-between pr-2 my-3">
<div class=" self-center text-xs font-medium">
{$i18n.t('API Key Endpoint Restrictions')}
</div>
<Switch bind:state={adminConfig.ENABLE_API_KEY_ENDPOINT_RESTRICTIONS} />
</div>
{#if adminConfig?.ENABLE_API_KEY_ENDPOINT_RESTRICTIONS}
<div class=" flex w-full flex-col pr-2">
<div class=" text-xs font-medium">
{$i18n.t('Allowed Endpoints')}
</div>
<input
class="w-full mt-1 rounded-lg text-sm dark:text-gray-300 bg-transparent outline-none"
type="text"
placeholder={`e.g.) /api/v1/messages, /api/v1/channels`}
bind:value={adminConfig.API_KEY_ALLOWED_ENDPOINTS}
/>
<div class="mt-2 text-xs text-gray-400 dark:text-gray-500">
<!-- https://docs.openwebui.com/getting-started/advanced-topics/api-endpoints -->
<a
href="https://docs.openwebui.com/getting-started/advanced-topics/api-endpoints"
target="_blank"
class=" text-gray-300 font-medium underline"
>
{$i18n.t('To learn more about available endpoints, visit our documentation.')}
</a>
</div>
</div>
{/if}
{/if}
<hr class=" border-gray-50 dark:border-gray-850 my-2" />
<div class="my-3 flex w-full items-center justify-between pr-2">
@@ -128,7 +128,7 @@
await toggleModelById(localStorage.token, model.id);
}
await init();
// await init();
_models.set(await getModels(localStorage.token));
};
+193 -46
View File
@@ -1,14 +1,19 @@
<script lang="ts">
import { toast } from 'svelte-sonner';
import { onDestroy, onMount, tick } from 'svelte';
import { Pane, PaneGroup, PaneResizer } from 'paneforge';
import { chatId, showSidebar, socket } from '$lib/stores';
import { onDestroy, onMount, tick } from 'svelte';
import { goto } from '$app/navigation';
import { chatId, showSidebar, socket, user } from '$lib/stores';
import { getChannelById, getChannelMessages, sendMessage } from '$lib/apis/channels';
import Messages from './Messages.svelte';
import MessageInput from './MessageInput.svelte';
import { goto } from '$app/navigation';
import Navbar from './Navbar.svelte';
import Drawer from '../common/Drawer.svelte';
import EllipsisVertical from '../icons/EllipsisVertical.svelte';
import Thread from './Thread.svelte';
export let id = '';
@@ -20,18 +25,29 @@
let channel = null;
let messages = null;
let threadId = null;
let typingUsers = [];
let typingUsersTimeout = {};
$: if (id) {
initHandler();
}
const scrollToBottom = () => {
messagesContainerElement.scrollTop = messagesContainerElement.scrollHeight;
if (messagesContainerElement) {
messagesContainerElement.scrollTop = messagesContainerElement.scrollHeight;
}
};
const initHandler = async () => {
top = false;
messages = null;
channel = null;
threadId = null;
typingUsers = [];
typingUsersTimeout = {};
channel = await getChannelById(localStorage.token, id).catch((error) => {
return null;
@@ -41,7 +57,7 @@
messages = await getChannelMessages(localStorage.token, id, 0);
if (messages) {
messagesContainerElement.scrollTop = messagesContainerElement.scrollHeight;
scrollToBottom();
if (messages.length < 50) {
top = true;
@@ -53,35 +69,74 @@
};
const channelEventHandler = async (event) => {
console.log(event);
if (event.channel_id === id) {
const type = event?.data?.type ?? null;
const data = event?.data?.data ?? null;
if (type === 'message') {
console.log('message', data);
messages = [data, ...messages];
await tick();
if (scrollEnd) {
messagesContainerElement.scrollTop = messagesContainerElement.scrollHeight;
if ((data?.parent_id ?? null) === null) {
messages = [data, ...messages];
if (typingUsers.find((user) => user.id === event.user.id)) {
typingUsers = typingUsers.filter((user) => user.id !== event.user.id);
}
await tick();
if (scrollEnd) {
scrollToBottom();
}
}
} else if (type === 'message:update') {
console.log('message:update', data);
const idx = messages.findIndex((message) => message.id === data.id);
if (idx !== -1) {
messages[idx] = data;
}
} else if (type === 'message:delete') {
console.log('message:delete', data);
messages = messages.filter((message) => message.id !== data.id);
} else if (type === 'message:reply') {
const idx = messages.findIndex((message) => message.id === data.id);
if (idx !== -1) {
messages[idx] = data;
}
} else if (type.includes('message:reaction')) {
const idx = messages.findIndex((message) => message.id === data.id);
if (idx !== -1) {
messages[idx] = data;
}
} else if (type === 'typing' && event.message_id === null) {
if (event.user.id === $user.id) {
return;
}
typingUsers = data.typing
? [
...typingUsers,
...(typingUsers.find((user) => user.id === event.user.id)
? []
: [
{
id: event.user.id,
name: event.user.name
}
])
]
: typingUsers.filter((user) => user.id !== event.user.id);
if (typingUsersTimeout[event.user.id]) {
clearTimeout(typingUsersTimeout[event.user.id]);
}
typingUsersTimeout[event.user.id] = setTimeout(() => {
typingUsers = typingUsers.filter((user) => user.id !== event.user.id);
}, 5000);
}
}
};
const submitHandler = async ({ content, data }) => {
if (!content) {
if (!content && (data?.files ?? []).length === 0) {
return;
}
@@ -97,59 +152,151 @@
}
};
const onChange = async () => {
$socket?.emit('channel-events', {
channel_id: id,
message_id: null,
data: {
type: 'typing',
data: {
typing: true
}
}
});
};
let mediaQuery;
let largeScreen = false;
onMount(() => {
if ($chatId) {
chatId.set('');
}
$socket?.on('channel-events', channelEventHandler);
mediaQuery = window.matchMedia('(min-width: 1024px)');
const handleMediaQuery = async (e) => {
if (e.matches) {
largeScreen = true;
} else {
largeScreen = false;
}
};
mediaQuery.addEventListener('change', handleMediaQuery);
handleMediaQuery(mediaQuery);
});
onDestroy(() => {
// $socket?.off('channel-events', channelEventHandler);
$socket?.off('channel-events', channelEventHandler);
});
</script>
<svelte:head>
<title>#{channel?.name ?? 'Channel'} | Open WebUI</title>
</svelte:head>
<div
class="h-screen max-h-[100dvh] {$showSidebar
? 'md:max-w-[calc(100%-260px)]'
: ''} w-full max-w-full flex flex-col"
id="channel-container"
>
<Navbar {channel} />
<PaneGroup direction="horizontal" class="w-full h-full">
<Pane defaultSize={50} minSize={50} class="h-full flex flex-col w-full relative">
<Navbar {channel} />
<div class="flex-1 overflow-y-auto">
{#if channel}
<div
class=" pb-2.5 max-w-full z-10 scrollbar-hidden w-full h-full pt-6 flex-1 flex flex-col-reverse overflow-auto"
id="messages-container"
bind:this={messagesContainerElement}
on:scroll={(e) => {
scrollEnd = Math.abs(messagesContainerElement.scrollTop) <= 50;
}}
<div class="flex-1 overflow-y-auto">
{#if channel}
<div
class=" pb-2.5 max-w-full z-10 scrollbar-hidden w-full h-full pt-6 flex-1 flex flex-col-reverse overflow-auto"
id="messages-container"
bind:this={messagesContainerElement}
on:scroll={(e) => {
scrollEnd = Math.abs(messagesContainerElement.scrollTop) <= 50;
}}
>
{#key id}
<Messages
{channel}
{messages}
{top}
onThread={(id) => {
threadId = id;
}}
onLoad={async () => {
const newMessages = await getChannelMessages(
localStorage.token,
id,
messages.length
);
messages = [...messages, ...newMessages];
if (newMessages.length < 50) {
top = true;
return;
}
}}
/>
{/key}
</div>
{/if}
</div>
<div class=" pb-[1rem]">
<MessageInput
id="root"
{typingUsers}
{onChange}
onSubmit={submitHandler}
{scrollToBottom}
{scrollEnd}
/>
</div>
</Pane>
{#if !largeScreen}
{#if threadId !== null}
<Drawer
show={threadId !== null}
on:close={() => {
threadId = null;
}}
>
<div class=" {threadId !== null ? ' h-screen w-screen' : 'px-6 py-4'} h-full">
<Thread
{threadId}
{channel}
onClose={() => {
threadId = null;
}}
/>
</div>
</Drawer>
{/if}
{:else if threadId !== null}
<PaneResizer
class="relative flex w-[3px] items-center justify-center bg-background group bg-gray-50 dark:bg-gray-850"
>
{#key id}
<Messages
<div class="z-10 flex h-7 w-5 items-center justify-center rounded-sm">
<EllipsisVertical className="size-4 invisible group-hover:visible" />
</div>
</PaneResizer>
<Pane defaultSize={50} minSize={30} class="h-full w-full">
<div class="h-full w-full shadow-xl">
<Thread
{threadId}
{channel}
{messages}
{top}
onLoad={async () => {
const newMessages = await getChannelMessages(localStorage.token, id, messages.length);
messages = [...messages, ...newMessages];
if (newMessages.length < 50) {
top = true;
return;
}
onClose={() => {
threadId = null;
}}
/>
{/key}
</div>
</div>
</Pane>
{/if}
</div>
<div class=" pb-[1rem]">
<MessageInput onSubmit={submitHandler} {scrollToBottom} {scrollEnd} />
</div>
</PaneGroup>
</div>
+85 -106
View File
@@ -6,7 +6,7 @@
const i18n = getContext('i18n');
import { config, mobile, settings } from '$lib/stores';
import { config, mobile, settings, socket } from '$lib/stores';
import { blobToFile, compressImage } from '$lib/utils';
import Tooltip from '../common/Tooltip.svelte';
@@ -23,6 +23,8 @@
export let placeholder = $i18n.t('Send a Message');
export let transparentBackground = false;
export let id = null;
let draggedOver = false;
let recording = false;
@@ -32,9 +34,12 @@
let filesInputElement;
let inputFiles;
export let typingUsers = [];
export let onSubmit: Function;
export let onChange: Function;
export let scrollEnd = true;
export let scrollToBottom: Function;
export let scrollToBottom: Function = () => {};
const screenCaptureHandler = async () => {
try {
@@ -238,7 +243,7 @@
};
const submitHandler = async () => {
if (content === '') {
if (content === '' && files.length === 0) {
return;
}
@@ -254,13 +259,17 @@
await tick();
const chatInputElement = document.getElementById('chat-input');
const chatInputElement = document.getElementById(`chat-input-${id}`);
chatInputElement?.focus();
};
$: if (content) {
onChange();
}
onMount(async () => {
window.setTimeout(() => {
const chatInput = document.getElementById('chat-input');
const chatInput = document.getElementById(`chat-input-${id}`);
chatInput?.focus();
}, 0);
@@ -290,37 +299,6 @@
<FilesOverlay show={draggedOver} />
<div class=" mx-auto inset-x-0 bg-transparent flex justify-center">
<div class="flex flex-col px-3 max-w-6xl w-full">
<div class="relative">
{#if scrollEnd === false}
<div class=" absolute -top-12 left-0 right-0 flex justify-center z-30 pointer-events-none">
<button
class=" bg-white border border-gray-100 dark:border-none dark:bg-white/20 p-1.5 rounded-full pointer-events-auto"
on:click={() => {
scrollEnd = true;
scrollToBottom();
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="w-5 h-5"
>
<path
fill-rule="evenodd"
d="M10 3a.75.75 0 01.75.75v10.638l3.96-4.158a.75.75 0 111.08 1.04l-5.25 5.5a.75.75 0 01-1.08 0l-5.25-5.5a.75.75 0 111.08-1.04l3.96 4.158V3.75A.75.75 0 0110 3z"
clip-rule="evenodd"
/>
</svg>
</button>
</div>
{/if}
</div>
</div>
</div>
<input
bind:this={filesInputElement}
bind:files={inputFiles}
@@ -337,12 +315,58 @@
filesInputElement.value = '';
}}
/>
<div class="{transparentBackground ? 'bg-transparent' : 'bg-white dark:bg-gray-900'} ">
<div class="bg-transparent">
<div
class="{($settings?.widescreenMode ?? null)
? 'max-w-full'
: 'max-w-6xl'} px-2.5 mx-auto inset-x-0"
: 'max-w-6xl'} px-2.5 mx-auto inset-x-0 relative"
>
<div class="absolute top-0 left-0 right-0 mx-auto inset-x-0 bg-transparent flex justify-center">
<div class="flex flex-col px-3 w-full">
<div class="relative">
{#if scrollEnd === false}
<div
class=" absolute -top-12 left-0 right-0 flex justify-center z-30 pointer-events-none"
>
<button
class=" bg-white border border-gray-100 dark:border-none dark:bg-white/20 p-1.5 rounded-full pointer-events-auto"
on:click={() => {
scrollEnd = true;
scrollToBottom();
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="w-5 h-5"
>
<path
fill-rule="evenodd"
d="M10 3a.75.75 0 01.75.75v10.638l3.96-4.158a.75.75 0 111.08 1.04l-5.25 5.5a.75.75 0 01-1.08 0l-5.25-5.5a.75.75 0 111.08-1.04l3.96 4.158V3.75A.75.75 0 0110 3z"
clip-rule="evenodd"
/>
</svg>
</button>
</div>
{/if}
</div>
<div class="relative">
<div class=" -mt-5">
{#if typingUsers.length > 0}
<div class=" text-xs px-4 mb-1">
<span class=" font-normal text-black dark:text-white">
{typingUsers.map((user) => user.name).join(', ')}
</span>
{$i18n.t('is typing...')}
</div>
{/if}
</div>
</div>
</div>
</div>
<div class="">
{#if recording}
<VoiceRecording
@@ -351,7 +375,7 @@
recording = false;
await tick();
document.getElementById('chat-input')?.focus();
document.getElementById(`chat-input-${id}`)?.focus();
}}
on:confirm={async (e) => {
const { text, filename } = e.detail;
@@ -359,7 +383,7 @@
recording = false;
await tick();
document.getElementById('chat-input')?.focus();
document.getElementById(`chat-input-${id}`)?.focus();
}}
/>
{:else}
@@ -370,7 +394,7 @@
}}
>
<div
class="flex-1 flex flex-col relative w-full rounded-3xl px-1 bg-gray-50 dark:bg-gray-400/5 dark:text-gray-100"
class="flex-1 flex flex-col relative w-full rounded-3xl px-1 bg-gray-600/5 dark:bg-gray-400/5 dark:text-gray-100"
dir={$settings?.chatDirection ?? 'LTR'}
>
{#if files.length > 0}
@@ -456,61 +480,21 @@
</InputMenu>
</div>
{#if $settings?.richTextInput ?? true}
<div
class="scrollbar-hidden text-left bg-transparent dark:text-gray-100 outline-none w-full py-2.5 px-1 rounded-xl resize-none h-fit max-h-80 overflow-auto"
>
<RichTextInput
bind:value={content}
id="chat-input"
messageInput={true}
shiftEnter={!$mobile ||
!(
'ontouchstart' in window ||
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0
)}
{placeholder}
largeTextAsFile={$settings?.largeTextAsFile ?? false}
on:keydown={async (e) => {
e = e.detail.event;
const isCtrlPressed = e.ctrlKey || e.metaKey; // metaKey is for Cmd key on Mac
if (
!$mobile ||
!(
'ontouchstart' in window ||
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0
)
) {
// Prevent Enter key from creating a new line
// Uses keyCode '13' for Enter key for chinese/japanese keyboards
if (e.keyCode === 13 && !e.shiftKey) {
e.preventDefault();
}
// Submit the content when Enter key is pressed
if (content !== '' && e.keyCode === 13 && !e.shiftKey) {
submitHandler();
}
}
if (e.key === 'Escape') {
console.log('Escape');
}
}}
on:paste={async (e) => {
e = e.detail.event;
console.log(e);
}}
/>
</div>
{:else}
<textarea
id="chat-input"
class="scrollbar-hidden bg-transparent dark:text-gray-100 outline-none w-full py-3 px-1 rounded-xl resize-none h-[48px]"
{placeholder}
<div
class="scrollbar-hidden text-left bg-transparent dark:text-gray-100 outline-none w-full py-2.5 px-1 rounded-xl resize-none h-fit max-h-80 overflow-auto"
>
<RichTextInput
bind:value={content}
id={`chat-input-${id}`}
messageInput={true}
shiftEnter={!$mobile ||
!(
'ontouchstart' in window ||
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0
)}
{placeholder}
largeTextAsFile={$settings?.largeTextAsFile ?? false}
on:keydown={async (e) => {
e = e.detail.event;
const isCtrlPressed = e.ctrlKey || e.metaKey; // metaKey is for Cmd key on Mac
@@ -538,17 +522,12 @@
console.log('Escape');
}
}}
rows="1"
on:input={async (e) => {
e.target.style.height = '';
e.target.style.height = Math.min(e.target.scrollHeight, 320) + 'px';
}}
on:focus={async (e) => {
e.target.style.height = '';
e.target.style.height = Math.min(e.target.scrollHeight, 320) + 'px';
on:paste={async (e) => {
e = e.detail.event;
console.log(e);
}}
/>
{/if}
</div>
<div class="self-end mb-1.5 flex space-x-1 mr-1">
{#if content === ''}
@@ -602,11 +581,11 @@
<Tooltip content={$i18n.t('Send message')}>
<button
id="send-message-button"
class="{content !== ''
class="{content !== '' || files.length !== 0
? 'bg-black text-white hover:bg-gray-900 dark:bg-white dark:text-black dark:hover:bg-gray-100 '
: 'text-white bg-gray-200 dark:text-gray-900 dark:bg-gray-700 disabled'} transition rounded-full p-1.5 self-center"
type="submit"
disabled={content === ''}
disabled={content === '' && files.length === 0}
>
<svg
xmlns="http://www.w3.org/2000/svg"
+82 -5
View File
@@ -11,20 +11,23 @@
dayjs.extend(isYesterday);
import { tick, getContext, onMount, createEventDispatcher } from 'svelte';
import { settings } from '$lib/stores';
import { settings, user } from '$lib/stores';
import Message from './Messages/Message.svelte';
import Loader from '../common/Loader.svelte';
import Spinner from '../common/Spinner.svelte';
import { deleteMessage, updateMessage } from '$lib/apis/channels';
import { addReaction, deleteMessage, removeReaction, updateMessage } from '$lib/apis/channels';
const i18n = getContext('i18n');
export let id = null;
export let channel = null;
export let messages = [];
export let top = false;
export let thread = false;
export let onLoad: Function = () => {};
export let onThread: Function = () => {};
let messagesLoading = false;
@@ -59,14 +62,14 @@
<div class=" ">Loading...</div>
</div>
</Loader>
{:else}
{:else if !thread}
<div
class="px-5
{($settings?.widescreenMode ?? null) ? 'max-w-full' : 'max-w-5xl'} mx-auto"
>
{#if channel}
<div class="flex flex-col gap-1.5 py-5">
<div class="flex flex-col gap-1.5 pb-5 pt-10">
<div class="text-2xl font-medium capitalize">{channel.name}</div>
<div class=" text-gray-500">
@@ -88,12 +91,15 @@
</div>
{/if}
{#each messageList as message, messageIdx (message.id)}
{#each messageList as message, messageIdx (id ? `${id}-${message.id}` : message.id)}
<Message
{message}
{thread}
showUserProfile={messageIdx === 0 ||
messageList.at(messageIdx - 1)?.user_id !== message.user_id}
onDelete={() => {
messages = messages.filter((m) => m.id !== message.id);
const res = deleteMessage(localStorage.token, message.channel_id, message.id).catch(
(error) => {
toast.error(error);
@@ -102,6 +108,13 @@
);
}}
onEdit={(content) => {
messages = messages.map((m) => {
if (m.id === message.id) {
m.content = content;
}
return m;
});
const res = updateMessage(localStorage.token, message.channel_id, message.id, {
content: content
}).catch((error) => {
@@ -109,6 +122,70 @@
return null;
});
}}
onThread={(id) => {
onThread(id);
}}
onReaction={(name) => {
if (
(message?.reactions ?? [])
.find((reaction) => reaction.name === name)
?.user_ids?.includes($user.id) ??
false
) {
messages = messages.map((m) => {
if (m.id === message.id) {
const reaction = m.reactions.find((reaction) => reaction.name === name);
if (reaction) {
reaction.user_ids = reaction.user_ids.filter((id) => id !== $user.id);
reaction.count = reaction.user_ids.length;
if (reaction.count === 0) {
m.reactions = m.reactions.filter((r) => r.name !== name);
}
}
}
return m;
});
const res = removeReaction(
localStorage.token,
message.channel_id,
message.id,
name
).catch((error) => {
toast.error(error);
return null;
});
} else {
messages = messages.map((m) => {
if (m.id === message.id) {
if (m.reactions) {
const reaction = m.reactions.find((reaction) => reaction.name === name);
if (reaction) {
reaction.user_ids.push($user.id);
reaction.count = reaction.user_ids.length;
} else {
m.reactions.push({
name: name,
user_ids: [$user.id],
count: 1
});
}
}
}
return m;
});
const res = addReaction(localStorage.token, message.channel_id, message.id, name).catch(
(error) => {
toast.error(error);
return null;
}
);
}
}}
/>
{/each}
@@ -8,10 +8,10 @@
dayjs.extend(isToday);
dayjs.extend(isYesterday);
import { getContext } from 'svelte';
import { getContext, onMount } from 'svelte';
const i18n = getContext<Writable<i18nType>>('i18n');
import { settings, user } from '$lib/stores';
import { settings, user, shortCodesToEmojis } from '$lib/stores';
import { WEBUI_BASE_URL } from '$lib/constants';
@@ -25,12 +25,22 @@
import Textarea from '$lib/components/common/Textarea.svelte';
import Image from '$lib/components/common/Image.svelte';
import FileItem from '$lib/components/common/FileItem.svelte';
import ProfilePreview from './Message/ProfilePreview.svelte';
import ChatBubbleOvalEllipsis from '$lib/components/icons/ChatBubbleOvalEllipsis.svelte';
import FaceSmile from '$lib/components/icons/FaceSmile.svelte';
import ReactionPicker from './Message/ReactionPicker.svelte';
import ChevronRight from '$lib/components/icons/ChevronRight.svelte';
export let message;
export let showUserProfile = true;
export let thread = false;
export let onDelete: Function = () => {};
export let onEdit: Function = () => {};
export let onThread: Function = () => {};
export let onReaction: Function = () => {};
let showButtons = false;
let edit = false;
let editedContent = null;
@@ -65,29 +75,69 @@
? 'pt-1.5 pb-0.5'
: ''} w-full {($settings?.widescreenMode ?? null)
? 'max-w-full'
: 'max-w-5xl'} mx-auto group hover:bg-gray-500/5 transition relative"
: 'max-w-5xl'} mx-auto group hover:bg-gray-300/5 dark:hover:bg-gray-700/5 transition relative"
>
{#if (message.user_id === $user.id || $user.role === 'admin') && !edit}
<div class=" absolute invisible group-hover:visible right-1 -top-2 z-30">
{#if !edit}
<div
class=" absolute {showButtons ? '' : 'invisible group-hover:visible'} right-1 -top-2 z-10"
>
<div
class="flex gap-1 rounded-lg bg-white dark:bg-gray-850 shadow-md p-0.5 border border-gray-100 dark:border-gray-800"
>
<button
class="hover:bg-gray-100 dark:hover:bg-gray-800 transition rounded-lg p-1"
on:click={() => {
edit = true;
editedContent = message.content;
<ReactionPicker
onClose={() => (showButtons = false)}
onSubmit={(name) => {
showButtons = false;
onReaction(name);
}}
>
<Pencil />
</button>
<Tooltip content={$i18n.t('Add Reaction')}>
<button
class="hover:bg-gray-100 dark:hover:bg-gray-800 transition rounded-lg p-1"
on:click={() => {
showButtons = true;
}}
>
<FaceSmile />
</button>
</Tooltip>
</ReactionPicker>
<button
class="hover:bg-gray-100 dark:hover:bg-gray-800 transition rounded-lg p-1"
on:click={() => (showDeleteConfirmDialog = true)}
>
<GarbageBin />
</button>
{#if !thread}
<Tooltip content={$i18n.t('Reply in Thread')}>
<button
class="hover:bg-gray-100 dark:hover:bg-gray-800 transition rounded-lg p-1"
on:click={() => {
onThread(message.id);
}}
>
<ChatBubbleOvalEllipsis />
</button>
</Tooltip>
{/if}
{#if message.user_id === $user.id || $user.role === 'admin'}
<Tooltip content={$i18n.t('Edit')}>
<button
class="hover:bg-gray-100 dark:hover:bg-gray-800 transition rounded-lg p-1"
on:click={() => {
edit = true;
editedContent = message.content;
}}
>
<Pencil />
</button>
</Tooltip>
<Tooltip content={$i18n.t('Delete')}>
<button
class="hover:bg-gray-100 dark:hover:bg-gray-800 transition rounded-lg p-1"
on:click={() => (showDeleteConfirmDialog = true)}
>
<GarbageBin />
</button>
</Tooltip>
{/if}
</div>
</div>
{/if}
@@ -101,11 +151,13 @@
class={`flex-shrink-0 ${($settings?.chatDirection ?? 'LTR') === 'LTR' ? 'mr-3' : 'ml-3'} w-9`}
>
{#if showUserProfile}
<ProfileImage
src={message.user?.profile_image_url ??
($i18n.language === 'dg-DG' ? `/doge.png` : `${WEBUI_BASE_URL}/static/favicon.png`)}
className={'size-8 translate-y-1 ml-0.5'}
/>
<ProfilePreview user={message.user}>
<ProfileImage
src={message.user?.profile_image_url ??
($i18n.language === 'dg-DG' ? `/doge.png` : `${WEBUI_BASE_URL}/static/favicon.png`)}
className={'size-8 translate-y-1 ml-0.5'}
/>
</ProfilePreview>
{:else}
<!-- <div class="w-7 h-7 rounded-full bg-transparent" /> -->
@@ -126,7 +178,7 @@
<div class="flex-auto w-0 pl-1">
{#if showUserProfile}
<Name>
<div class=" self-end text-base font-medium">
<div class=" self-end text-base shrink-0 font-medium truncate">
{message?.user?.name}
</div>
@@ -137,7 +189,7 @@
<Tooltip
content={dayjs(message.created_at / 1000000).format('dddd, DD MMMM YYYY HH:mm')}
>
{formatDate(message.created_at / 1000000)}
<span class="line-clamp-1">{formatDate(message.created_at / 1000000)}</span>
</Tooltip>
</div>
{/if}
@@ -219,6 +271,85 @@
>(edited)</span
>{/if}
</div>
{#if (message?.reactions ?? []).length > 0}
<div>
<div class="flex items-center flex-wrap gap-y-1.5 gap-1 mt-1 mb-2">
{#each message.reactions as reaction}
<Tooltip content={`:${reaction.name}:`}>
<button
class="flex items-center gap-1.5 transition rounded-xl px-2 py-1 cursor-pointer {reaction.user_ids.includes(
$user.id
)
? ' bg-blue-300/10 outline outline-blue-500/50 outline-1'
: 'bg-gray-300/10 dark:bg-gray-500/10 hover:outline hover:outline-gray-700/30 dark:hover:outline-gray-300/30 hover:outline-1'}"
on:click={() => {
onReaction(reaction.name);
}}
>
{#if $shortCodesToEmojis[reaction.name]}
<img
src="/assets/emojis/{$shortCodesToEmojis[
reaction.name
].toLowerCase()}.svg"
alt={reaction.name}
class=" size-4"
loading="lazy"
/>
{:else}
<div>
{reaction.name}
</div>
{/if}
{#if reaction.user_ids.length > 0}
<div class="text-xs font-medium text-gray-500 dark:text-gray-400">
{reaction.user_ids?.length}
</div>
{/if}
</button>
</Tooltip>
{/each}
<ReactionPicker
onSubmit={(name) => {
onReaction(name);
}}
>
<Tooltip content={$i18n.t('Add Reaction')}>
<div
class="flex items-center gap-1.5 bg-gray-500/10 hover:outline hover:outline-gray-700/30 dark:hover:outline-gray-300/30 hover:outline-1 transition rounded-xl px-1 py-1 cursor-pointer text-gray-500 dark:text-gray-400"
>
<FaceSmile />
</div>
</Tooltip>
</ReactionPicker>
</div>
</div>
{/if}
{#if !thread && message.reply_count > 0}
<div class="flex items-center gap-1.5 -mt-0.5 mb-1.5">
<button
class="flex items-center text-xs py-1 text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 transition"
on:click={() => {
onThread(message.id);
}}
>
<span class="font-medium mr-1">
{$i18n.t('{{COUNT}} Replies', { COUNT: message.reply_count })}</span
><span>
{' - '}{$i18n.t('Last reply')}
{dayjs.unix(message.latest_reply_at / 1000000000).fromNow()}</span
>
<span class="ml-1">
<ChevronRight className="size-2.5" strokeWidth="3" />
</span>
<!-- {$i18n.t('View Replies')} -->
</button>
</div>
{/if}
{/if}
</div>
</div>
@@ -0,0 +1,85 @@
<script lang="ts">
import { DropdownMenu } from 'bits-ui';
import { createEventDispatcher } from 'svelte';
import { flyAndScale } from '$lib/utils/transitions';
import { WEBUI_BASE_URL } from '$lib/constants';
import { activeUserIds } from '$lib/stores';
export let side = 'right';
export let align = 'top';
export let user = null;
let show = false;
const dispatch = createEventDispatcher();
</script>
<DropdownMenu.Root
bind:open={show}
closeFocus={false}
onOpenChange={(state) => {
dispatch('change', state);
}}
typeahead={false}
>
<DropdownMenu.Trigger>
<slot />
</DropdownMenu.Trigger>
<slot name="content">
<DropdownMenu.Content
class="max-w-full w-[240px] rounded-lg z-[9999] bg-white dark:bg-black dark:text-white shadow-lg"
sideOffset={8}
{side}
{align}
transition={flyAndScale}
>
{#if user}
<div class=" flex flex-col gap-2 w-full rounded-lg">
<div class="py-8 relative bg-gray-900 rounded-t-lg">
<img
crossorigin="anonymous"
src={user?.profile_image_url ?? `${WEBUI_BASE_URL}/static/favicon.png`}
class=" absolute -bottom-5 left-3 size-12 ml-0.5 object-cover rounded-full -translate-y-[1px]"
alt="profile"
/>
</div>
<div class=" flex flex-col pt-4 pb-2.5 px-4">
<div class=" -mb-1">
<span class="font-medium text-sm line-clamp-1"> {user.name} </span>
</div>
<div class=" flex items-center gap-2">
{#if $activeUserIds.includes(user.id)}
<div>
<span class="relative flex size-2">
<span
class="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"
/>
<span class="relative inline-flex rounded-full size-2 bg-green-500" />
</span>
</div>
<div class=" -translate-y-[1px]">
<span class="text-xs"> Active </span>
</div>
{:else}
<div>
<span class="relative flex size-2">
<span class="relative inline-flex rounded-full size-2 bg-gray-500" />
</span>
</div>
<div class=" -translate-y-[1px]">
<span class="text-xs"> Away </span>
</div>
{/if}
</div>
</div>
</div>
{/if}
</DropdownMenu.Content>
</slot>
</DropdownMenu.Root>
@@ -0,0 +1,166 @@
<script lang="ts">
import { DropdownMenu } from 'bits-ui';
import { flyAndScale } from '$lib/utils/transitions';
import emojiGroups from '$lib/emoji-groups.json';
import emojiShortCodes from '$lib/emoji-shortcodes.json';
import Tooltip from '$lib/components/common/Tooltip.svelte';
import VirtualList from '@sveltejs/svelte-virtual-list';
export let onClose = () => {};
export let onSubmit = (name) => {};
export let side = 'top';
export let align = 'start';
export let user = null;
let show = false;
let emojis = emojiShortCodes;
let search = '';
let flattenedEmojis = [];
let emojiRows = [];
// Reactive statement to filter the emojis based on search query
$: {
if (search) {
emojis = Object.keys(emojiShortCodes).reduce((acc, key) => {
if (key.includes(search)) {
acc[key] = emojiShortCodes[key];
} else {
if (Array.isArray(emojiShortCodes[key])) {
const filtered = emojiShortCodes[key].filter((emoji) => emoji.includes(search));
if (filtered.length) {
acc[key] = filtered;
}
} else {
if (emojiShortCodes[key].includes(search)) {
acc[key] = emojiShortCodes[key];
}
}
}
return acc;
}, {});
} else {
emojis = emojiShortCodes;
}
}
// Flatten emoji groups and group them into rows of 8 for virtual scrolling
$: {
flattenedEmojis = [];
Object.keys(emojiGroups).forEach((group) => {
const groupEmojis = emojiGroups[group].filter((emoji) => emojis[emoji]);
if (groupEmojis.length > 0) {
flattenedEmojis.push({ type: 'group', label: group });
flattenedEmojis.push(
...groupEmojis.map((emoji) => ({
type: 'emoji',
name: emoji,
shortCodes:
typeof emojiShortCodes[emoji] === 'string'
? [emojiShortCodes[emoji]]
: emojiShortCodes[emoji]
}))
);
}
});
// Group emojis into rows of 8
emojiRows = [];
let currentRow = [];
flattenedEmojis.forEach((item) => {
if (item.type === 'emoji') {
currentRow.push(item);
if (currentRow.length === 8) {
emojiRows.push(currentRow);
currentRow = [];
}
} else if (item.type === 'group') {
if (currentRow.length > 0) {
emojiRows.push(currentRow); // Push the remaining row
currentRow = [];
}
emojiRows.push([item]); // Add the group label as a separate row
}
});
if (currentRow.length > 0) {
emojiRows.push(currentRow); // Push the final row
}
}
const ROW_HEIGHT = 48; // Approximate height for a row with multiple emojis
// Handle emoji selection
function selectEmoji(emoji) {
const selectedCode = emoji.shortCodes[0];
onSubmit(selectedCode);
show = false;
}
</script>
<DropdownMenu.Root
bind:open={show}
closeFocus={false}
onOpenChange={(state) => {
if (!state) {
search = '';
onClose();
}
}}
typeahead={false}
>
<DropdownMenu.Trigger>
<slot />
</DropdownMenu.Trigger>
<DropdownMenu.Content
class="max-w-full w-80 bg-gray-50 dark:bg-gray-850 rounded-lg z-[9999] shadow-lg dark:text-white"
sideOffset={8}
{side}
{align}
transition={flyAndScale}
>
<div class="mb-1 px-3 pt-2 pb-2">
<input
type="text"
class="w-full text-sm bg-transparent outline-none"
placeholder="Search all emojis"
bind:value={search}
/>
</div>
<!-- Virtualized Emoji List -->
<div class="w-full flex justify-start h-96 overflow-y-auto px-3 pb-3 text-sm">
{#if emojiRows.length === 0}
<div class="text-center text-xs text-gray-500 dark:text-gray-400">No results</div>
{:else}
<div class="w-full flex ml-0.5">
<VirtualList rowHeight={ROW_HEIGHT} items={emojiRows} height={384} let:item>
<div class="w-full">
{#if item.length === 1 && item[0].type === 'group'}
<!-- Render group header -->
<div class="text-xs font-medium mb-2 text-gray-500 dark:text-gray-400">
{item[0].label}
</div>
{:else}
<!-- Render emojis in a row -->
<div class="flex items-center gap-1.5 w-full">
{#each item as emojiItem}
<Tooltip
content={emojiItem.shortCodes.map((code) => `:${code}:`).join(', ')}
placement="top"
>
<button
class="p-1.5 rounded-lg cursor-pointer hover:bg-gray-200 dark:hover:bg-gray-700 transition"
on:click={() => selectEmoji(emojiItem)}
>
<img
src="/assets/emojis/{emojiItem.name.toLowerCase()}.svg"
alt={emojiItem.name}
class="size-5"
loading="lazy"
/>
</button>
</Tooltip>
{/each}
</div>
{/if}
</div>
</VirtualList>
</div>
{/if}
</div>
</DropdownMenu.Content>
</DropdownMenu.Root>
+204
View File
@@ -0,0 +1,204 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { socket, user } from '$lib/stores';
import { getChannelThreadMessages, sendMessage } from '$lib/apis/channels';
import XMark from '$lib/components/icons/XMark.svelte';
import MessageInput from './MessageInput.svelte';
import Messages from './Messages.svelte';
import { onDestroy, onMount, tick } from 'svelte';
import { toast } from 'svelte-sonner';
export let threadId = null;
export let channel = null;
export let onClose = () => {};
let messages = null;
let top = false;
let typingUsers = [];
let typingUsersTimeout = {};
let messagesContainerElement = null;
$: if (threadId) {
initHandler();
}
const scrollToBottom = () => {
messagesContainerElement.scrollTop = messagesContainerElement.scrollHeight;
};
const initHandler = async () => {
messages = null;
top = false;
typingUsers = [];
typingUsersTimeout = {};
if (channel) {
messages = await getChannelThreadMessages(localStorage.token, channel.id, threadId);
if (messages.length < 50) {
top = true;
}
await tick();
scrollToBottom();
} else {
goto('/');
}
};
const channelEventHandler = async (event) => {
console.log(event);
if (event.channel_id === channel.id) {
const type = event?.data?.type ?? null;
const data = event?.data?.data ?? null;
if (type === 'message') {
if ((data?.parent_id ?? null) === threadId) {
if (messages) {
messages = [data, ...messages];
if (typingUsers.find((user) => user.id === event.user.id)) {
typingUsers = typingUsers.filter((user) => user.id !== event.user.id);
}
}
}
} else if (type === 'message:update') {
if (messages) {
const idx = messages.findIndex((message) => message.id === data.id);
if (idx !== -1) {
messages[idx] = data;
}
}
} else if (type === 'message:delete') {
if (messages) {
messages = messages.filter((message) => message.id !== data.id);
}
} else if (type.includes('message:reaction')) {
if (messages) {
const idx = messages.findIndex((message) => message.id === data.id);
if (idx !== -1) {
messages[idx] = data;
}
}
} else if (type === 'typing' && event.message_id === threadId) {
if (event.user.id === $user.id) {
return;
}
typingUsers = data.typing
? [
...typingUsers,
...(typingUsers.find((user) => user.id === event.user.id)
? []
: [
{
id: event.user.id,
name: event.user.name
}
])
]
: typingUsers.filter((user) => user.id !== event.user.id);
if (typingUsersTimeout[event.user.id]) {
clearTimeout(typingUsersTimeout[event.user.id]);
}
typingUsersTimeout[event.user.id] = setTimeout(() => {
typingUsers = typingUsers.filter((user) => user.id !== event.user.id);
}, 5000);
}
}
};
const submitHandler = async ({ content, data }) => {
if (!content) {
return;
}
const res = await sendMessage(localStorage.token, channel.id, {
parent_id: threadId,
content: content,
data: data
}).catch((error) => {
toast.error(error);
return null;
});
};
const onChange = async () => {
$socket?.emit('channel-events', {
channel_id: channel.id,
message_id: threadId,
data: {
type: 'typing',
data: {
typing: true
}
}
});
};
onMount(() => {
$socket?.on('channel-events', channelEventHandler);
});
onDestroy(() => {
$socket?.off('channel-events', channelEventHandler);
});
</script>
{#if channel}
<div class="flex flex-col w-full h-full bg-gray-50 dark:bg-gray-850">
<div class="flex items-center justify-between px-3.5 pt-3">
<div class=" font-medium text-lg">Thread</div>
<div>
<button
class="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300 p-2"
on:click={() => {
onClose();
}}
>
<XMark />
</button>
</div>
</div>
<div class=" max-h-full w-full overflow-y-auto pt-3" bind:this={messagesContainerElement}>
<Messages
id={threadId}
{channel}
{messages}
{top}
thread={true}
onLoad={async () => {
const newMessages = await getChannelThreadMessages(
localStorage.token,
channel.id,
threadId,
messages.length
);
messages = [...messages, ...newMessages];
if (newMessages.length < 50) {
top = true;
return;
}
}}
/>
<div class=" pb-[1rem]">
<MessageInput id={threadId} {typingUsers} {onChange} onSubmit={submitHandler} />
</div>
</div>
</div>
{/if}
+44 -14
View File
@@ -427,7 +427,7 @@
onDestroy(() => {
chatIdUnsubscriber?.();
window.removeEventListener('message', onMessageHandler);
// $socket?.off('chat-events');
$socket?.off('chat-events', chatEventHandler);
});
// File upload functions
@@ -836,7 +836,7 @@
return null;
});
if (res !== null) {
if (res !== null && res.messages) {
// Update chat history with the new messages
for (const message of res.messages) {
history.messages[message.id] = {
@@ -890,7 +890,7 @@
return null;
});
if (res !== null) {
if (res !== null && res.messages) {
// Update chat history with the new messages
for (const message of res.messages) {
history.messages[message.id] = {
@@ -1053,7 +1053,7 @@
};
const chatCompletionEventHandler = async (data, message, chatId) => {
const { id, done, choices, sources, selected_model_id, error, usage } = data;
const { id, done, choices, content, sources, selected_model_id, error, usage } = data;
if (error) {
await handleOpenAIError(error, message);
@@ -1105,6 +1105,38 @@
}
}
if (content) {
// REALTIME_CHAT_SAVE is disabled
message.content = content;
if (navigator.vibrate && ($settings?.hapticFeedback ?? false)) {
navigator.vibrate(5);
}
// Emit chat event for TTS
const messageContentParts = getMessageContentParts(
message.content,
$config?.audio?.tts?.split_on ?? 'punctuation'
);
messageContentParts.pop();
// dispatch only last sentence and make sure it hasn't been dispatched before
if (
messageContentParts.length > 0 &&
messageContentParts[messageContentParts.length - 1] !== message.lastSentence
) {
message.lastSentence = messageContentParts[messageContentParts.length - 1];
eventTarget.dispatchEvent(
new CustomEvent('chat', {
detail: {
id: message.id,
content: messageContentParts[messageContentParts.length - 1]
}
})
);
}
}
if (selected_model_id) {
message.selectedModelId = selected_model_id;
message.arena = true;
@@ -1114,16 +1146,11 @@
message.usage = usage;
}
history.messages[message.id] = message;
if (done) {
message.done = true;
if ($settings.notificationEnabled && !document.hasFocus()) {
new Notification(`${message.model}`, {
body: message.content,
icon: `${WEBUI_BASE_URL}/static/favicon.png`
});
}
if ($settings.responseAutoCopy) {
copyToClipboard(message.content);
}
@@ -1158,8 +1185,6 @@
await chatCompletedHandler(chatId, message.model, message.id, createMessagesList(message.id));
}
history.messages[message.id] = message;
console.log(data);
if (autoScroll) {
scrollToBottom();
@@ -1511,7 +1536,12 @@
chat_id: $chatId,
id: responseMessageId,
...(!$temporaryChatEnabled && messages.length == 1 && selectedModels[0] === model.id
...(!$temporaryChatEnabled &&
(messages.length == 1 ||
(messages.length == 2 &&
messages.at(0)?.role === 'system' &&
messages.at(1)?.role === 'user')) &&
selectedModels[0] === model.id
? {
background_tasks: {
title_generation: $settings?.title?.auto ?? true,
+1 -1
View File
@@ -544,7 +544,7 @@
}}
>
<div
class="flex-1 flex flex-col relative w-full rounded-3xl px-1 bg-gray-50 dark:bg-gray-400/5 dark:text-gray-100"
class="flex-1 flex flex-col relative w-full rounded-3xl px-1 bg-gray-600/5 dark:bg-gray-400/5 dark:text-gray-100"
dir={$settings?.chatDirection ?? 'LTR'}
>
{#if files.length > 0}
@@ -217,7 +217,13 @@
const startRecording = async () => {
if ($showCallOverlay) {
if (!audioStream) {
audioStream = await navigator.mediaDevices.getUserMedia({ audio: true });
audioStream = await navigator.mediaDevices.getUserMedia({
audio: {
echoCancellation: true,
noiseSuppression: true,
autoGainControl: true
}
});
}
mediaRecorder = new MediaRecorder(audioStream);
@@ -161,7 +161,13 @@
const startRecording = async () => {
startDurationCounter();
stream = await navigator.mediaDevices.getUserMedia({ audio: true });
stream = await navigator.mediaDevices.getUserMedia({
audio: {
echoCancellation: true,
noiseSuppression: true,
autoGainControl: true
}
});
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.onstart = () => {
console.log('Recording started');
+3 -1
View File
@@ -16,6 +16,8 @@
const i18n = getContext('i18n');
export let className = 'h-full flex pt-8';
export let chatId = '';
export let user = $_user;
@@ -333,7 +335,7 @@
};
</script>
<div class="h-full flex pt-8">
<div class={className}>
{#if Object.keys(history?.messages ?? {}).length == 0}
<ChatPlaceholder
modelIds={selectedModels}
@@ -52,12 +52,21 @@
}
const init = () => {
selectedReason = message?.annotation?.reason ?? '';
comment = message?.annotation?.comment ?? '';
if (!selectedReason) {
selectedReason = message?.annotation?.reason ?? '';
}
if (!comment) {
comment = message?.annotation?.comment ?? '';
}
tags = (message?.annotation?.tags ?? []).map((tag) => ({
name: tag
}));
detailedRating = message?.annotation?.details?.rating ?? null;
if (!detailedRating) {
detailedRating = message?.annotation?.details?.rating ?? null;
}
};
onMount(() => {
@@ -489,11 +489,15 @@
<div class="flex-auto w-0 pl-1">
<Name>
{model?.name ?? message.model}
<Tooltip content={model?.name ?? message.model} placement="top-start">
<span class="line-clamp-1">
{model?.name ?? message.model}
</span>
</Tooltip>
{#if message.timestamp}
<span
class=" self-center invisible group-hover:visible text-gray-400 text-xs font-medium uppercase ml-0.5 -mt-0.5"
class=" self-center shrink-0 translate-y-0.5 invisible group-hover:visible text-gray-400 text-xs font-medium uppercase ml-0.5 -mt-0.5"
>
{dayjs(message.timestamp * 1000).format($i18n.t('h:mm a'))}
</span>
@@ -543,8 +547,12 @@
{$i18n.t(status?.description, {
count: status?.urls.length
})}
{:else if status?.description === 'No search query generated'}
{$i18n.t('No search query generated')}
{:else if status?.description === 'Generating search query'}
{$i18n.t('Generating search query')}
{:else}
{$i18n.t(status?.description)}
{status?.description}
{/if}
</div>
</div>
@@ -573,8 +581,12 @@
{$i18n.t(status?.description, {
searchQuery: status?.query
})}
{:else if status?.description === 'No search query generated'}
{$i18n.t('No search query generated')}
{:else if status?.description === 'Generating search query'}
{$i18n.t('Generating search query')}
{:else}
{$i18n.t(status?.description)}
{status?.description}
{/if}
</div>
</div>
@@ -106,6 +106,12 @@
<hr class=" dark:border-gray-850" />
<div class="mt-2 text-xs text-gray-400 dark:text-gray-500">
Emoji graphics provided by
<a href="https://github.com/jdecked/twemoji" target="_blank">Twemoji</a>, licensed under
<a href="https://creativecommons.org/licenses/by/4.0/" target="_blank">CC-BY 4.0</a>.
</div>
<div class="flex space-x-1">
<a href="https://discord.gg/5rJgQTnV4s" target="_blank">
<img
@@ -132,11 +132,11 @@
</div>
<div class="flex justify-end">
<div class="flex flex-col items-end space-x-1 mt-1.5">
<div class="flex flex-col items-end space-x-1 mt-3">
<div class="flex gap-1">
{#if $config?.features.enable_community_sharing}
<button
class=" self-center px-3.5 py-2 rounded-xl text-sm font-medium bg-gray-100 hover:bg-gray-200 text-gray-800 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-white"
class="self-center flex items-center gap-1 px-3.5 py-2 text-sm font-medium bg-gray-100 hover:bg-gray-200 text-gray-800 dark:bg-gray-850 dark:text-white dark:hover:bg-gray-800 transition rounded-full"
type="button"
on:click={() => {
shareChat();
@@ -148,7 +148,7 @@
{/if}
<button
class=" self-center flex items-center gap-1 px-3.5 py-2 rounded-xl text-sm font-medium bg-emerald-600 hover:bg-emerald-500 text-white"
class="self-center flex items-center gap-1 px-3.5 py-2 text-sm font-medium bg-black hover:bg-gray-900 text-white dark:bg-white dark:text-black dark:hover:bg-gray-100 transition rounded-full"
type="button"
id="copy-and-share-chat-button"
on:click={async () => {
+1 -1
View File
@@ -57,7 +57,7 @@
<div
bind:this={modalElement}
class="modal fixed right-0 left-0 bottom-0 bg-black/60 w-full h-screen max-h-[100dvh] flex justify-center z-[9999] overflow-hidden overscroll-contain"
class="modal fixed right-0 left-0 bottom-0 bg-black/60 w-full h-screen max-h-[100dvh] flex justify-center z-[999] overflow-hidden overscroll-contain"
in:fly={{ y: 100, duration: 100 }}
on:mousedown={() => {
show = false;
+4 -2
View File
@@ -5,6 +5,8 @@
import { flyAndScale } from '$lib/utils/transitions';
export let show = false;
export let side = 'bottom';
export let align = 'start';
const dispatch = createEventDispatcher();
</script>
@@ -24,8 +26,8 @@
<DropdownMenu.Content
class="w-full max-w-[130px] rounded-lg px-1 py-1.5 border border-gray-900 z-50 bg-gray-850 text-white"
sideOffset={8}
side="bottom"
align="start"
{side}
{align}
transition={flyAndScale}
>
<DropdownMenu.Item class="flex items-center px-3 py-2 text-sm font-medium">
+22 -2
View File
@@ -2,7 +2,7 @@
import { onMount, getContext } from 'svelte';
const i18n = getContext('i18n');
import panzoom from 'panzoom';
import panzoom, { type PanZoom } from 'panzoom';
import DOMPurify from 'dompurify';
import DocumentDuplicate from '../icons/DocumentDuplicate.svelte';
@@ -10,12 +10,13 @@
import { toast } from 'svelte-sonner';
import Tooltip from './Tooltip.svelte';
import Clipboard from '../icons/Clipboard.svelte';
import Reset from '../icons/Reset.svelte';
export let className = '';
export let svg = '';
export let content = '';
let instance;
let instance: PanZoom;
let sceneParentElement: HTMLElement;
let sceneElement: HTMLElement;
@@ -28,6 +29,12 @@
zoomSpeed: 0.065
});
}
function resetPanZoomViewport() {
console.log('Reset View');
instance.moveTo(0, 0);
instance.zoomAbs(0, 0, 1);
console.log(instance.getTransform());
}
</script>
<div bind:this={sceneParentElement} class="relative {className}">
@@ -49,5 +56,18 @@
</button>
</Tooltip>
</div>
<div class=" absolute top-1 right-10">
<Tooltip content={$i18n.t('Reset view')}>
<button
class="p-1.5 rounded-lg border border-gray-100 dark:border-none dark:bg-gray-850 hover:bg-gray-50 dark:hover:bg-gray-800 transition"
on:click={() => {
resetPanZoomViewport();
toast.success($i18n.t('Reset view'));
}}
>
<Reset className=" size-4" />
</button>
</Tooltip>
</div>
{/if}
</div>
+1 -1
View File
@@ -56,7 +56,7 @@
<style>
.placeholder::before {
/* abolute */
/* absolute */
position: absolute;
content: attr(data-placeholder);
color: #adb5bd;
@@ -0,0 +1,19 @@
<script lang="ts">
export let className = 'size-4';
export let strokeWidth = '1.5';
</script>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width={strokeWidth}
stroke="currentColor"
class={className}
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M8.625 12a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0H8.25m4.125 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0H12m4.125 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0h-.375M21 12c0 4.556-4.03 8.25-9 8.25a9.764 9.764 0 0 1-2.555-.337A5.972 5.972 0 0 1 5.41 20.97a5.969 5.969 0 0 1-.474-.065 4.48 4.48 0 0 0 .978-2.025c.09-.457-.133-.901-.467-1.226C3.93 16.178 3 14.189 3 12c0-4.556 4.03-8.25 9-8.25s9 3.694 9 8.25Z"
/>
</svg>
+19
View File
@@ -0,0 +1,19 @@
<script lang="ts">
export let className = 'size-4';
export let strokeWidth = '1.5';
</script>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width={strokeWidth}
stroke="currentColor"
class={className}
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.182 15.182a4.5 4.5 0 0 1-6.364 0M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0ZM9.75 9.75c0 .414-.168.75-.375.75S9 10.164 9 9.75 9.168 9 9.375 9s.375.336.375.75Zm-.375 0h.008v.015h-.008V9.75Zm5.625 0c0 .414-.168.75-.375.75s-.375-.336-.375-.75.168-.75.375-.75.375.336.375.75Zm-.375 0h.008v.015h-.008V9.75Z"
/>
</svg>
+9
View File
@@ -0,0 +1,9 @@
<script lang="ts">
export let className = 'size-4';
</script>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor" class={className}>
<path
d="M463.5 224l8.5 0c13.3 0 24-10.7 24-24l0-128c0-9.7-5.8-18.5-14.8-22.2s-19.3-1.7-26.2 5.2L413.4 96.6c-87.6-86.5-228.7-86.2-315.8 1c-87.5 87.5-87.5 229.3 0 316.8s229.3 87.5 316.8 0c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0c-62.5 62.5-163.8 62.5-226.3 0s-62.5-163.8 0-226.3c62.2-62.2 162.7-62.5 225.3-1L327 183c-6.9 6.9-8.9 17.2-5.2 26.2s12.5 14.8 22.2 14.8l119.5 0z"
/>
</svg>
+12 -5
View File
@@ -83,12 +83,19 @@
const downloadJSONExport = async () => {
if (chat.id) {
chat = await getChatById(localStorage.token, chat.id);
let chatObj = null;
if (chat.id === 'local' || $temporaryChatEnabled) {
chatObj = chat;
} else {
chatObj = await getChatById(localStorage.token, chat.id);
}
let blob = new Blob([JSON.stringify([chatObj])], {
type: 'application/json'
});
saveAs(blob, `chat-export-${Date.now()}.json`);
}
let blob = new Blob([JSON.stringify([chat])], {
type: 'application/json'
});
saveAs(blob, `chat-export-${Date.now()}.json`);
};
</script>
+97 -106
View File
@@ -558,19 +558,6 @@
on:input={searchDebounceHandler}
placeholder={$i18n.t('Search')}
/>
<div class="absolute z-40 right-3.5 top-1">
<Tooltip content={$i18n.t('New folder')}>
<button
class="p-1 rounded-lg bg-gray-50 hover:bg-gray-100 dark:bg-gray-950 dark:hover:bg-gray-900 text-gray-500 dark:text-gray-500 transition"
on:click={() => {
createFolder();
}}
>
<Plus className=" size-3" strokeWidth="2.5" />
</button>
</Tooltip>
</div>
</div>
<div
@@ -578,82 +565,6 @@
? 'opacity-20'
: ''}"
>
{#if !search && $pinnedChats.length > 0}
<div class="flex flex-col space-y-1 rounded-xl">
<Folder
className="px-2"
bind:open={showPinnedChat}
on:change={(e) => {
localStorage.setItem('showPinnedChat', e.detail);
console.log(e.detail);
}}
on:import={(e) => {
importChatHandler(e.detail, true);
}}
on:drop={async (e) => {
const { type, id, item } = e.detail;
if (type === 'chat') {
let chat = await getChatById(localStorage.token, id).catch((error) => {
return null;
});
if (!chat && item) {
chat = await importChat(localStorage.token, item.chat, item?.meta ?? {});
}
if (chat) {
console.log(chat);
if (chat.folder_id) {
const res = await updateChatFolderIdById(
localStorage.token,
chat.id,
null
).catch((error) => {
toast.error(error);
return null;
});
}
if (!chat.pinned) {
const res = await toggleChatPinnedStatusById(localStorage.token, chat.id);
}
initChatList();
}
}
}}
name={$i18n.t('Pinned')}
>
<div
class="ml-3 pl-1 mt-[1px] flex flex-col overflow-y-auto scrollbar-hidden border-s border-gray-100 dark:border-gray-900"
>
{#each $pinnedChats as chat, idx}
<ChatItem
className=""
id={chat.id}
title={chat.title}
{shiftKey}
selected={selectedChatId === chat.id}
on:select={() => {
selectedChatId = chat.id;
}}
on:unselect={() => {
selectedChatId = null;
}}
on:change={async () => {
initChatList();
}}
on:tag={(e) => {
const { type, name } = e.detail;
tagEventHandler(type, name, chat.id);
}}
/>
{/each}
</div>
</Folder>
</div>
{/if}
{#if $config?.features?.enable_channels && ($user.role === 'admin' || $channels.length > 0) && !search}
<Folder
className="px-2 mt-0.5"
@@ -677,26 +588,14 @@
</Folder>
{/if}
{#if !search && folders}
<Folders
{folders}
on:import={(e) => {
const { folderId, items } = e.detail;
importChatHandler(items, false, folderId);
}}
on:update={async (e) => {
initChatList();
}}
on:change={async () => {
initChatList();
}}
/>
{/if}
<Folder
collapsible={!search}
className="px-2 mt-0.5"
name={$i18n.t('Chats')}
onAdd={() => {
createFolder();
}}
onAddLabel={$i18n.t('New Folder')}
on:import={(e) => {
importChatHandler(e.detail);
}}
@@ -723,7 +622,7 @@
}
if (chat.pinned) {
const res = await toggleChatPinnedStatusById(localStorage.token, chat, id);
const res = await toggleChatPinnedStatusById(localStorage.token, chat.id);
}
initChatList();
@@ -750,6 +649,98 @@
<div class="absolute z-40 w-full h-full flex justify-center"></div>
{/if}
{#if !search && $pinnedChats.length > 0}
<div class="flex flex-col space-y-1 rounded-xl">
<Folder
className=""
bind:open={showPinnedChat}
on:change={(e) => {
localStorage.setItem('showPinnedChat', e.detail);
console.log(e.detail);
}}
on:import={(e) => {
importChatHandler(e.detail, true);
}}
on:drop={async (e) => {
const { type, id, item } = e.detail;
if (type === 'chat') {
let chat = await getChatById(localStorage.token, id).catch((error) => {
return null;
});
if (!chat && item) {
chat = await importChat(localStorage.token, item.chat, item?.meta ?? {});
}
if (chat) {
console.log(chat);
if (chat.folder_id) {
const res = await updateChatFolderIdById(
localStorage.token,
chat.id,
null
).catch((error) => {
toast.error(error);
return null;
});
}
if (!chat.pinned) {
const res = await toggleChatPinnedStatusById(localStorage.token, chat.id);
}
initChatList();
}
}
}}
name={$i18n.t('Pinned')}
>
<div
class="ml-3 pl-1 mt-[1px] flex flex-col overflow-y-auto scrollbar-hidden border-s border-gray-100 dark:border-gray-900"
>
{#each $pinnedChats as chat, idx}
<ChatItem
className=""
id={chat.id}
title={chat.title}
{shiftKey}
selected={selectedChatId === chat.id}
on:select={() => {
selectedChatId = chat.id;
}}
on:unselect={() => {
selectedChatId = null;
}}
on:change={async () => {
initChatList();
}}
on:tag={(e) => {
const { type, name } = e.detail;
tagEventHandler(type, name, chat.id);
}}
/>
{/each}
</div>
</Folder>
</div>
{/if}
{#if !search && folders}
<Folders
{folders}
on:import={(e) => {
const { folderId, items } = e.detail;
importChatHandler(items, false, folderId);
}}
on:update={async (e) => {
initChatList();
}}
on:change={async () => {
initChatList();
}}
/>
{/if}
<div class=" flex-1 flex flex-col overflow-y-auto scrollbar-hidden">
<div class="pt-1.5">
{#if $chats}
@@ -81,9 +81,8 @@
{#if $user?.role === 'admin'}
<button
class="absolute z-10 right-2 invisible group-hover:visible self-center flex items-center dark:text-gray-300"
on:pointerup={(e) => {
on:click={(e) => {
e.stopPropagation();
showEditChannelModal = true;
}}
>
@@ -19,7 +19,7 @@
{#each folderList as folderId (folderId)}
<RecursiveFolder
className="px-2"
className=""
{folders}
{folderId}
on:import={(e) => {
@@ -5,7 +5,7 @@
import { flyAndScale } from '$lib/utils/transitions';
import { goto } from '$app/navigation';
import ArchiveBox from '$lib/components/icons/ArchiveBox.svelte';
import { showSettings, activeUserCount, USAGE_POOL, mobile, showSidebar } from '$lib/stores';
import { showSettings, activeUserIds, USAGE_POOL, mobile, showSidebar } from '$lib/stores';
import { fade, slide } from 'svelte/transition';
import Tooltip from '$lib/components/common/Tooltip.svelte';
import { userSignOut } from '$lib/apis/auths';
@@ -184,7 +184,7 @@
<div class=" self-center truncate">{$i18n.t('Sign Out')}</div>
</button>
{#if $activeUserCount}
{#if $activeUserIds?.length > 0}
<hr class=" border-gray-50 dark:border-gray-850 my-1 p-0" />
<Tooltip
@@ -207,7 +207,7 @@
{$i18n.t('Active Users')}:
</span>
<span class=" font-semibold">
{$activeUserCount}
{$activeUserIds?.length}
</span>
</div>
</div>
+2 -2
View File
@@ -12,7 +12,7 @@
} from '$lib/constants';
import { WEBUI_NAME, config, user, models, settings } from '$lib/stores';
import { generateOpenAIChatCompletion } from '$lib/apis/openai';
import { chatCompletion, generateOpenAIChatCompletion } from '$lib/apis/openai';
import { splitStream } from '$lib/utils';
import Collapsible from '../common/Collapsible.svelte';
@@ -61,7 +61,7 @@
const chatCompletionHandler = async () => {
const model = $models.find((model) => model.id === selectedModelId);
const [res, controller] = await generateOpenAIChatCompletion(
const [res, controller] = await chatCompletion(
localStorage.token,
{
model: model.id,
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "( `sh webui.sh --api`مثال)",
"(latest)": "(الأخير)",
"{{ models }}": "{{ نماذج }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "دردشات {{user}}",
"{{webUIName}} Backend Required": "{{webUIName}} مطلوب",
"*Prompt node ID(s) are required for image generation": "",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "إضافة ذكرايات",
"Add Model": "اضافة موديل",
"Add Reaction": "",
"Add Tag": "",
"Add Tags": "اضافة تاق",
"Add text content": "",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "",
"Allow User Location": "",
"Allow Voice Interruption in Call": "",
"Allowed Endpoints": "",
"Already have an account?": "هل تملك حساب ؟",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "API الرابط الرئيسي",
"API Key": "API مفتاح",
"API Key created.": "API تم أنشاء المفتاح",
"API Key Endpoint Restrictions": "",
"API keys": "مفاتيح واجهة برمجة التطبيقات",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "أضغط على أسم الصلاحيات لتغيرها للمستخدم",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "",
"Clone": "استنساخ",
"Clone Chat": "",
"Close": "أغلق",
"Code execution": "",
"Code formatted successfully": "",
@@ -310,7 +315,7 @@
"Embedding Model": "نموذج التضمين",
"Embedding Model Engine": "تضمين محرك النموذج",
"Embedding model set to \"{{embedding_model}}\"": "تم تعيين نموذج التضمين على \"{{embedding_model}}\"",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "تمكين مشاركة المجتمع",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "واجهه المستخدم",
"Invalid file format.": "",
"Invalid Tag": "تاق غير صالحة",
"is typing...": "",
"January": "يناير",
"Jina API Key": "",
"join our Discord for help.": "انضم إلى Discord للحصول على المساعدة.",
@@ -531,6 +537,7 @@
"Language": "اللغة",
"Last Active": "آخر نشاط",
"Last Modified": "",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "",
@@ -605,7 +612,7 @@
"Name": "الأسم",
"Name your knowledge base": "",
"New Chat": "دردشة جديدة",
"New folder": "",
"New Folder": "",
"New Password": "كلمة المرور الجديدة",
"new-channel": "",
"No content found": "",
@@ -736,6 +743,7 @@
"Rename": "إعادة تسمية",
"Reorder Models": "",
"Repeat Last N": "N كرر آخر",
"Reply in Thread": "",
"Request Mode": "وضع الطلب",
"Reranking Model": "إعادة تقييم النموذج",
"Reranking model disabled": "تم تعطيل نموذج إعادة الترتيب",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "",
"Reset Vector Storage/Knowledge": "",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
"Response splitting": "",
"Result": "",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "للوصول إلى الموديلات GGUF المتاحة للتنزيل،",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "",
"To select actions here, add them to the \"Functions\" workspace first.": "",
"To select filters here, add them to the \"Functions\" workspace first.": "",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "متغير لاستبدالها بمحتوى الحافظة.",
"Version": "إصدار",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"View Replies": "",
"Visibility": "",
"Voice": "",
"Voice Input": "",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(например `sh webui.sh --api`)",
"(latest)": "(последна)",
"{{ models }}": "{{ модели }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "{{user}}'s чатове",
"{{webUIName}} Backend Required": "{{webUIName}} Изисква се Бекенд",
"*Prompt node ID(s) are required for image generation": "",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "Добавяне на Памет",
"Add Model": "Добавяне на Модел",
"Add Reaction": "",
"Add Tag": "",
"Add Tags": "добавяне на тагове",
"Add text content": "",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "",
"Allow User Location": "",
"Allow Voice Interruption in Call": "",
"Allowed Endpoints": "",
"Already have an account?": "Вече имате акаунт? ",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "API Базов URL",
"API Key": "API Ключ",
"API Key created.": "API Ключ създаден.",
"API Key Endpoint Restrictions": "",
"API keys": "API Ключове",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "Натиснете върху бутона за промяна на ролята на потребителя.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "",
"Clone": "Клонинг",
"Clone Chat": "",
"Close": "Затвори",
"Code execution": "",
"Code formatted successfully": "",
@@ -310,7 +315,7 @@
"Embedding Model": "Модел за вграждане",
"Embedding Model Engine": "Модел за вграждане",
"Embedding model set to \"{{embedding_model}}\"": "Модел за вграждане е настроен на \"{{embedding_model}}\"",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "Разрешаване на споделяне в общност",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "Интерфейс",
"Invalid file format.": "",
"Invalid Tag": "Невалиден тег",
"is typing...": "",
"January": "Януари",
"Jina API Key": "",
"join our Discord for help.": "свържете се с нашия Discord за помощ.",
@@ -531,6 +537,7 @@
"Language": "Език",
"Last Active": "Последни активни",
"Last Modified": "",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "",
@@ -605,7 +612,7 @@
"Name": "Име",
"Name your knowledge base": "",
"New Chat": "Нов чат",
"New folder": "",
"New Folder": "",
"New Password": "Нова парола",
"new-channel": "",
"No content found": "",
@@ -736,6 +743,7 @@
"Rename": "Преименуване",
"Reorder Models": "",
"Repeat Last N": "Repeat Last N",
"Reply in Thread": "",
"Request Mode": "Request Mode",
"Reranking Model": "Reranking Model",
"Reranking model disabled": "Reranking model disabled",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "",
"Reset Vector Storage/Knowledge": "",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
"Response splitting": "",
"Result": "",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "За да получите достъп до GGUF моделите, налични за изтегляне,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "",
"To select actions here, add them to the \"Functions\" workspace first.": "",
"To select filters here, add them to the \"Functions\" workspace first.": "",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "променливи да се заменят съдържанието от клипборд.",
"Version": "Версия",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"View Replies": "",
"Visibility": "",
"Voice": "",
"Voice Input": "",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(যেমন `sh webui.sh --api`)",
"(latest)": "(সর্বশেষ)",
"{{ models }}": "{{ মডেল}}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "{{user}}র চ্যাটস",
"{{webUIName}} Backend Required": "{{webUIName}} ব্যাকএন্ড আবশ্যক",
"*Prompt node ID(s) are required for image generation": "",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "মেমোরি যোগ করুন",
"Add Model": "মডেল যোগ করুন",
"Add Reaction": "",
"Add Tag": "",
"Add Tags": "ট্যাগ যোগ করুন",
"Add text content": "",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "",
"Allow User Location": "",
"Allow Voice Interruption in Call": "",
"Allowed Endpoints": "",
"Already have an account?": "আগে থেকেই একাউন্ট আছে?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "এপিআই বেজ ইউআরএল",
"API Key": "এপিআই কোড",
"API Key created.": "একটি এপিআই কোড তৈরি করা হয়েছে.",
"API Key Endpoint Restrictions": "",
"API keys": "এপিআই কোডস",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "ইউজারের পদবি পরিবর্তন করার জন্য ইউজারের পদবি বাটনে ক্লিক করুন",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "",
"Clone": "ক্লোন",
"Clone Chat": "",
"Close": "বন্ধ",
"Code execution": "",
"Code formatted successfully": "",
@@ -310,7 +315,7 @@
"Embedding Model": "ইমেজ ইমেবডিং মডেল",
"Embedding Model Engine": "ইমেজ ইমেবডিং মডেল ইঞ্জিন",
"Embedding model set to \"{{embedding_model}}\"": "ইমেজ ইমেবডিং মডেল সেট করা হয়েছে - \"{{embedding_model}}\"",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "সম্প্রদায় শেয়ারকরণ সক্ষম করুন",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "ইন্টারফেস",
"Invalid file format.": "",
"Invalid Tag": "অবৈধ ট্যাগ",
"is typing...": "",
"January": "জানুয়ারী",
"Jina API Key": "",
"join our Discord for help.": "সাহায্যের জন্য আমাদের Discord-এ যুক্ত হোন",
@@ -531,6 +537,7 @@
"Language": "ভাষা",
"Last Active": "সর্বশেষ সক্রিয়",
"Last Modified": "",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "",
@@ -605,7 +612,7 @@
"Name": "নাম",
"Name your knowledge base": "",
"New Chat": "নতুন চ্যাট",
"New folder": "",
"New Folder": "",
"New Password": "নতুন পাসওয়ার্ড",
"new-channel": "",
"No content found": "",
@@ -736,6 +743,7 @@
"Rename": "রেনেম",
"Reorder Models": "",
"Repeat Last N": "রিপিট Last N",
"Reply in Thread": "",
"Request Mode": "রিকোয়েস্ট মোড",
"Reranking Model": "রির্যাক্টিং মডেল",
"Reranking model disabled": "রির্যাক্টিং মডেল নিষ্ক্রিয় করা",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "",
"Reset Vector Storage/Knowledge": "",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
"Response splitting": "",
"Result": "",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "ডাউলোডের জন্য এভেইলএবল GGUF মডেলগুলো এক্সেস করতে,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "",
"To select actions here, add them to the \"Functions\" workspace first.": "",
"To select filters here, add them to the \"Functions\" workspace first.": "",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "ক্লিপবোর্ডের কন্টেন্ট দিয়ে যেই ভেরিয়েবল রিপ্লেস করা যাবে।",
"Version": "ভার্সন",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"View Replies": "",
"Visibility": "",
"Voice": "",
"Voice Input": "",
+33 -22
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(p. ex. `sh webui.sh --api`)",
"(latest)": "(últim)",
"{{ models }}": "{{ models }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "Els xats de {{user}}",
"{{webUIName}} Backend Required": "El Backend de {{webUIName}} és necessari",
"*Prompt node ID(s) are required for image generation": "*Els identificadors de nodes d'indicacions són necessaris per a la generació d'imatges",
@@ -34,6 +35,7 @@
"Add Group": "Afegir grup",
"Add Memory": "Afegir memòria",
"Add Model": "Afegir un model",
"Add Reaction": "",
"Add Tag": "Afegir etiqueta",
"Add Tags": "Afegir etiquetes",
"Add text content": "Afegir contingut de text",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "Permetre el xat temporal",
"Allow User Location": "Permetre la ubicació de l'usuari",
"Allow Voice Interruption in Call": "Permetre la interrupció de la veu en una trucada",
"Allowed Endpoints": "",
"Already have an account?": "Ja tens un compte?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "Alternativa al top_p, i pretén garantir un equilibri de qualitat i varietat. El paràmetre p representa la probabilitat mínima que es consideri un token, en relació amb la probabilitat del token més probable. Per exemple, amb p=0,05 i el token més probable amb una probabilitat de 0,9, es filtren els logits amb un valor inferior a 0,045. (Per defecte: 0.0)",
"Amazing": "Al·lucinant",
@@ -67,6 +70,7 @@
"API Base URL": "URL Base de l'API",
"API Key": "clau API",
"API Key created.": "clau API creada.",
"API Key Endpoint Restrictions": "",
"API keys": "Claus de l'API",
"Application DN": "DN d'aplicació",
"Application DN Password": "Contrasenya del DN d'aplicació",
@@ -76,8 +80,8 @@
"Archive All Chats": "Arxiva tots els xats",
"Archived Chats": "Xats arxivats",
"archived-chat-export": "archived-chat-export",
"Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "",
"Are you sure you want to delete this channel?": "Estàs segur que vols eliminar aquest canal?",
"Are you sure you want to delete this message?": "Estàs segur que vols eliminar aquest missatge?",
"Are you sure you want to unarchive all archived chats?": "Estàs segur que vols desarxivar tots els xats arxivats?",
"Are you sure?": "Estàs segur?",
"Arena Models": "Models de l'Arena",
@@ -110,7 +114,7 @@
"Batch Size (num_batch)": "Mida del lot (num_batch)",
"before": "abans",
"Being lazy": "Essent mandrós",
"Beta": "",
"Beta": "Beta",
"Bing Search V7 Endpoint": "Punt de connexió a Bing Search V7",
"Bing Search V7 Subscription Key": "Clau de subscripció a Bing Search V7",
"Brave Search API Key": "Clau API de Brave Search",
@@ -124,8 +128,8 @@
"Capture": "Captura",
"Certificate Path": "Camí del certificat",
"Change Password": "Canviar la contrasenya",
"Channel Name": "",
"Channels": "",
"Channel Name": "Nom del canal",
"Channels": "Canals",
"Character": "Personatge",
"Character limit for autocomplete generation input": "Límit de caràcters per a l'entrada de generació automàtica",
"Chart new frontiers": "Traça noves fronteres",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "Clica sobre el botó de rol d'usuari per canviar el rol d'un usuari.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Permís d'escriptura al porta-retalls denegat. Comprova els ajustos de navegador per donar l'accés necessari.",
"Clone": "Clonar",
"Clone Chat": "",
"Close": "Tancar",
"Code execution": "Execució de codi",
"Code formatted successfully": "Codi formatat correctament",
@@ -181,7 +186,7 @@
"Confirm": "Confirmar",
"Confirm Password": "Confirmar la contrasenya",
"Confirm your action": "Confirma la teva acció",
"Confirm your new password": "",
"Confirm your new password": "Confirma la teva nova contrasenya",
"Connections": "Connexions",
"Contact Admin for WebUI Access": "Posat en contacte amb l'administrador per accedir a WebUI",
"Content": "Contingut",
@@ -208,7 +213,7 @@
"Create a model": "Crear un model",
"Create Account": "Crear un compte",
"Create Admin Account": "Crear un compte d'Administrador",
"Create Channel": "",
"Create Channel": "Crear un canal",
"Create Group": "Crear grup",
"Create Knowledge": "Crear Coneixement",
"Create new key": "Crear una nova clau",
@@ -244,7 +249,7 @@
"Delete chat?": "Eliminar el xat?",
"Delete folder?": "Eliminar la carpeta?",
"Delete function?": "Eliminar funció?",
"Delete Message": "",
"Delete Message": "Eleiminar el missatge",
"Delete prompt?": "Eliminar indicació?",
"delete this link": "Eliminar aquest enllaç",
"Delete tool?": "Eliminar eina?",
@@ -297,7 +302,7 @@
"e.g. Tools for performing various operations": "p. ex. Eines per dur a terme operacions",
"Edit": "Editar",
"Edit Arena Model": "Editar model de l'Arena",
"Edit Channel": "",
"Edit Channel": "Editar el canal",
"Edit Connection": "Editar la connexió",
"Edit Default Permissions": "Editar el permisos per defecte",
"Edit Memory": "Editar la memòria",
@@ -310,7 +315,7 @@
"Embedding Model": "Model d'incrustació",
"Embedding Model Engine": "Motor de model d'incrustació",
"Embedding model set to \"{{embedding_model}}\"": "Model d'incrustació configurat a \"{{embedding_model}}\"",
"Enable API Key Auth": "Activar l'autenticació amb clau API",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "Activar la generació automàtica per als missatges del xat",
"Enable Community Sharing": "Activar l'ús compartit amb la comunitat",
"Enable Google Drive": "Activar Google Drive",
@@ -364,20 +369,20 @@
"Enter stop sequence": "Introdueix la seqüència de parada",
"Enter system prompt": "Introdueix la indicació de sistema",
"Enter Tavily API Key": "Introdueix la clau API de Tavily",
"Enter the public URL of your WebUI. This URL will be used to generate links in the notifications.": "",
"Enter the public URL of your WebUI. This URL will be used to generate links in the notifications.": "Entra la URL pública de WebUI. Aquesta URL s'utilitzarà per generar els enllaços en les notificacions.",
"Enter Tika Server URL": "Introdueix l'URL del servidor Tika",
"Enter Top K": "Introdueix Top K",
"Enter URL (e.g. http://127.0.0.1:7860/)": "Introdueix l'URL (p. ex. http://127.0.0.1:7860/)",
"Enter URL (e.g. http://localhost:11434)": "Introdueix l'URL (p. ex. http://localhost:11434)",
"Enter your current password": "",
"Enter your current password": "Introdueix la teva contrasenya actual",
"Enter Your Email": "Introdueix el teu correu electrònic",
"Enter Your Full Name": "Introdueix el teu nom complet",
"Enter your message": "Introdueix el teu missatge",
"Enter your new password": "",
"Enter your new password": "Introdueix la teva nova contrasenya",
"Enter Your Password": "Introdueix la teva contrasenya",
"Enter Your Role": "Introdueix el teu rol",
"Enter Your Username": "Introdueix el teu nom d'usuari",
"Enter your webhook URL": "",
"Enter your webhook URL": "Entra la URL del webhook",
"Error": "Error",
"ERROR": "ERROR",
"Error accessing Google Drive: {{error}}": "Error en accedir a Google Drive: {{error}}",
@@ -483,10 +488,10 @@
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "Afirmo que he llegit i entenc les implicacions de la meva acció. Soc conscient dels riscos associats a l'execució de codi arbitrari i he verificat la fiabilitat de la font.",
"ID": "ID",
"Ignite curiosity": "Despertar la curiositat",
"Image Compression": "",
"Image Compression": "Compressió d'imatges",
"Image Generation (Experimental)": "Generació d'imatges (Experimental)",
"Image Generation Engine": "Motor de generació d'imatges",
"Image Max Compression Size": "",
"Image Max Compression Size": "Mida màxima de la compressió d'imatges",
"Image Settings": "Preferències d'imatges",
"Images": "Imatges",
"Import Chats": "Importar xats",
@@ -507,6 +512,7 @@
"Interface": "Interfície",
"Invalid file format.": "Format d'arxiu no vàlid.",
"Invalid Tag": "Etiqueta no vàlida",
"is typing...": "",
"January": "Gener",
"Jina API Key": "Clau API de Jina",
"join our Discord for help.": "uneix-te al nostre Discord per obtenir ajuda.",
@@ -531,6 +537,7 @@
"Language": "Idioma",
"Last Active": "Activitat recent",
"Last Modified": "Modificació",
"Last reply": "",
"LDAP": "LDAP",
"LDAP server updated": "Servidor LDAP actualitzat",
"Leaderboard": "Tauler de classificació",
@@ -605,9 +612,9 @@
"Name": "Nom",
"Name your knowledge base": "Anomena la teva base de coneixement",
"New Chat": "Nou xat",
"New folder": "",
"New Folder": "",
"New Password": "Nova contrasenya",
"new-channel": "",
"new-channel": "nou-canal",
"No content found": "No s'ha trobat contingut",
"No content to speak": "No hi ha contingut per parlar",
"No distance available": "No hi ha distància disponible",
@@ -630,8 +637,8 @@
"Not helpful": "No ajuda",
"Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "Nota: Si s'estableix una puntuació mínima, la cerca només retornarà documents amb una puntuació major o igual a la puntuació mínima.",
"Notes": "Notes",
"Notification Sound": "",
"Notification Webhook": "",
"Notification Sound": "So de la notificació",
"Notification Webhook": "Webhook de la notificació",
"Notifications": "Notificacions",
"November": "Novembre",
"num_gpu (Ollama)": "num_gpu (Ollama)",
@@ -736,6 +743,7 @@
"Rename": "Canviar el nom",
"Reorder Models": "Reordenar els models",
"Repeat Last N": "Repeteix els darrers N",
"Reply in Thread": "",
"Request Mode": "Mode de sol·licitud",
"Reranking Model": "Model de reavaluació",
"Reranking model disabled": "Model de reavaluació desactivat",
@@ -744,6 +752,7 @@
"Reset All Models": "Restablir tots els models",
"Reset Upload Directory": "Restableix el directori de pujades",
"Reset Vector Storage/Knowledge": "Restableix el Repositori de vectors/Coneixement",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Les notifications de resposta no es poden activar perquè els permisos del lloc web han estat rebutjats. Comprova les preferències del navegador per donar l'accés necessari.",
"Response splitting": "Divisió de la resposta",
"Result": "Resultat",
@@ -781,7 +790,7 @@
"Search Tools": "Cercar eines",
"SearchApi API Key": "Clau API de SearchApi",
"SearchApi Engine": "Motor de SearchApi",
"Searched {{count}} sites": "",
"Searched {{count}} sites": "S'han cercat {{count}} pàgines",
"Searching \"{{searchQuery}}\"": "Cercant \"{{searchQuery}}\"",
"Searching Knowledge for \"{{searchQuery}}\"": "Cercant \"{{searchQuery}}\" al coneixement",
"Searxng Query URL": "URL de consulta de Searxng",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "Per accedir als models GGUF disponibles per descarregar,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Per accedir a la WebUI, poseu-vos en contacte amb l'administrador. Els administradors poden gestionar els estats dels usuaris des del tauler d'administració.",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "Per adjuntar la base de coneixement aquí, afegiu-la primer a l'espai de treball \"Coneixement\".",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "Per protegir la privadesa, només es comparteixen puntuacions, identificadors de models, etiquetes i metadades dels comentaris; els registres de xat romanen privats i no s'inclouen.",
"To select actions here, add them to the \"Functions\" workspace first.": "Per seleccionar accions aquí, afegeix-les primer a l'espai de treball \"Funcions\".",
"To select filters here, add them to the \"Functions\" workspace first.": "Per seleccionar filtres aquí, afegeix-los primer a l'espai de treball \"Funcions\".",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "variable per tenir-les reemplaçades amb el contingut del porta-retalls.",
"Version": "Versió",
"Version {{selectedVersion}} of {{totalVersions}}": "Versió {{selectedVersion}} de {{totalVersions}}",
"View Replies": "",
"Visibility": "Visibilitat",
"Voice": "Veu",
"Voice Input": "Entrada de veu",
@@ -1015,7 +1026,7 @@
"Web Search Query Generation": "Generació de consultes per a la cerca de la web",
"Webhook URL": "URL del webhook",
"WebUI Settings": "Preferències de WebUI",
"WebUI URL": "",
"WebUI URL": "URL de WebUI",
"WebUI will make requests to \"{{url}}/api/chat\"": "WebUI farà peticions a \"{{url}}/api/chat\"",
"WebUI will make requests to \"{{url}}/chat/completions\"": "WebUI farà peticions a \"{{url}}/chat/completions\"",
"What are you trying to achieve?": "Què intentes aconseguir?",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(pananglitan `sh webui.sh --api`)",
"(latest)": "",
"{{ models }}": "",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "",
"{{webUIName}} Backend Required": "Backend {{webUIName}} gikinahanglan",
"*Prompt node ID(s) are required for image generation": "",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "",
"Add Model": "",
"Add Reaction": "",
"Add Tag": "",
"Add Tags": "idugang ang mga tag",
"Add text content": "",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "",
"Allow User Location": "",
"Allow Voice Interruption in Call": "",
"Allowed Endpoints": "",
"Already have an account?": "Naa na kay account ?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "API Base URL",
"API Key": "yawe sa API",
"API Key created.": "",
"API Key Endpoint Restrictions": "",
"API keys": "",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "I-klik ang User Role button aron usbon ang role sa user.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "",
"Clone": "",
"Clone Chat": "",
"Close": "Suod nga",
"Code execution": "",
"Code formatted successfully": "",
@@ -310,7 +315,7 @@
"Embedding Model": "",
"Embedding Model Engine": "",
"Embedding model set to \"{{embedding_model}}\"": "",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "Interface",
"Invalid file format.": "",
"Invalid Tag": "",
"is typing...": "",
"January": "",
"Jina API Key": "",
"join our Discord for help.": "Apil sa among Discord alang sa tabang.",
@@ -531,6 +537,7 @@
"Language": "Pinulongan",
"Last Active": "",
"Last Modified": "",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "",
@@ -605,7 +612,7 @@
"Name": "Ngalan",
"Name your knowledge base": "",
"New Chat": "Bag-ong diskusyon",
"New folder": "",
"New Folder": "",
"New Password": "Bag-ong Password",
"new-channel": "",
"No content found": "",
@@ -736,6 +743,7 @@
"Rename": "",
"Reorder Models": "",
"Repeat Last N": "Balika ang katapusang N",
"Reply in Thread": "",
"Request Mode": "Query mode",
"Reranking Model": "",
"Reranking model disabled": "",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "",
"Reset Vector Storage/Knowledge": "",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
"Response splitting": "",
"Result": "",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "Aron ma-access ang mga modelo sa GGUF nga magamit alang sa pag-download,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "",
"To select actions here, add them to the \"Functions\" workspace first.": "",
"To select filters here, add them to the \"Functions\" workspace first.": "",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "variable aron pulihan kini sa mga sulud sa clipboard.",
"Version": "Bersyon",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"View Replies": "",
"Visibility": "",
"Voice": "",
"Voice Input": "",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(např. `sh webui.sh --api`)",
"(latest)": "Nejnovější",
"{{ models }}": "{{ models }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "{{user}}'s konverzace",
"{{webUIName}} Backend Required": "Požadován {{webUIName}} Backend",
"*Prompt node ID(s) are required for image generation": "*Jsou vyžadovány IDs pro prompt node pro generování obrázků",
@@ -34,6 +35,7 @@
"Add Group": "Přidat skupinu",
"Add Memory": "Přidat paměť",
"Add Model": "Přidat model",
"Add Reaction": "",
"Add Tag": "Přidat štítek",
"Add Tags": "Přidat štítky",
"Add text content": "Přidejte textový obsah",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "Povolit dočasný chat",
"Allow User Location": "Povolit uživatelskou polohu",
"Allow Voice Interruption in Call": "Povolit přerušení hlasu při hovoru",
"Allowed Endpoints": "",
"Already have an account?": "Už máte účet?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "Základní URL adresa API",
"API Key": "Klíč API",
"API Key created.": "API klíč byl vytvořen.",
"API Key Endpoint Restrictions": "",
"API keys": "API klíče",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "Klikněte na tlačítko role uživatele, abyste změnili roli uživatele.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Přístup k zápisu do schránky byl zamítnut. Prosím, zkontrolujte nastavení svého prohlížeče a udělte potřebný přístup.",
"Clone": "Klonovat",
"Clone Chat": "",
"Close": "Zavřít",
"Code execution": "Provádění kódu",
"Code formatted successfully": "Kód byl úspěšně naformátován.",
@@ -310,7 +315,7 @@
"Embedding Model": "Vkládací model (Embedding Model)",
"Embedding Model Engine": "",
"Embedding model set to \"{{embedding_model}}\"": "Model vkládání nastaven na \"{{embedding_model}}\"",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "Povolit sdílení komunity",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "Rozhraní",
"Invalid file format.": "Neplatný formát souboru.",
"Invalid Tag": "Neplatný tag",
"is typing...": "",
"January": "Leden",
"Jina API Key": "",
"join our Discord for help.": "připojte se k našemu Discordu pro pomoc.",
@@ -531,6 +537,7 @@
"Language": "Jazyk",
"Last Active": "Naposledy aktivní",
"Last Modified": "Poslední změna",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "Žebříček",
@@ -605,7 +612,7 @@
"Name": "Jméno",
"Name your knowledge base": "",
"New Chat": "Nový chat",
"New folder": "",
"New Folder": "",
"New Password": "Nové heslo",
"new-channel": "",
"No content found": "Nebyly nalezeny žádné obsahové informace.",
@@ -736,6 +743,7 @@
"Rename": "Přejmenovat",
"Reorder Models": "",
"Repeat Last N": "Opakovat posledních N",
"Reply in Thread": "",
"Request Mode": "Režim žádosti",
"Reranking Model": "Model pro přehodnocení pořadí",
"Reranking model disabled": "Přeřazovací model je deaktivován",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "Resetovat adresář nahrávání",
"Reset Vector Storage/Knowledge": "Resetování úložiště vektorů/znalostí",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Oznámení o odpovědích nelze aktivovat, protože oprávnění webu byla zamítnuta. Navštivte nastavení svého prohlížeče a udělte potřebný přístup.",
"Response splitting": "Rozdělení odpovědi",
"Result": "Výsledek",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "Pro přístup k modelům GGUF dostupným pro stažení,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Pro přístup k WebUI se prosím obraťte na administrátora. Administrátoři mohou spravovat stavy uživatelů z Admin Panelu.",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "Chcete-li zde připojit znalostní databázi, nejprve ji přidejte do workspace \"Knowledge\".",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "Aby byla chráněna vaše soukromí, z vaší zpětné vazby jsou sdílena pouze hodnocení, ID modelů, značky a metadata vaše chatové záznamy zůstávají soukromé a nejsou zahrnuty.",
"To select actions here, add them to the \"Functions\" workspace first.": "Chcete-li zde vybrat akce, nejprve je přidejte do pracovní plochy \"Functions\".",
"To select filters here, add them to the \"Functions\" workspace first.": "Chcete-li zde vybrat filtry, nejprve je přidejte do workspace „Functions“.",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "proměnnou, aby byl jejich obsah nahrazen obsahem schránky.",
"Version": "Verze",
"Version {{selectedVersion}} of {{totalVersions}}": "Verze {{selectedVersion}} z {{totalVersions}}",
"View Replies": "",
"Visibility": "Viditelnost",
"Voice": "Hlas",
"Voice Input": "Hlasový vstup",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(f.eks. `sh webui.sh --api`)",
"(latest)": "(seneste)",
"{{ models }}": "{{ modeller }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "{{user}}s chats",
"{{webUIName}} Backend Required": "{{webUIName}} Backend kræves",
"*Prompt node ID(s) are required for image generation": "*Prompt node ID(s) er påkrævet for at kunne generere billeder",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "Tilføj hukommelse",
"Add Model": "Tilføj model",
"Add Reaction": "",
"Add Tag": "Tilføj tag",
"Add Tags": "Tilføj tags",
"Add text content": "Tilføj tekst",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "Tillad midlertidig chat",
"Allow User Location": "Tillad bruger-lokation",
"Allow Voice Interruption in Call": "Tillad afbrydelser i stemme i opkald",
"Allowed Endpoints": "",
"Already have an account?": "Har du allerede en profil?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "API Base URL",
"API Key": "API nøgle",
"API Key created.": "API nøgle lavet",
"API Key Endpoint Restrictions": "",
"API keys": "API nøgler",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "Klik på bruger ikonet for at ændre brugerens rolle.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Skriveadgang til udklipsholderen ikke tilladt. Tjek venligst indstillingerne i din browser for at give adgang.",
"Clone": "Klon",
"Clone Chat": "",
"Close": "Luk",
"Code execution": "",
"Code formatted successfully": "Kode formateret korrekt",
@@ -310,7 +315,7 @@
"Embedding Model": "Embedding Model",
"Embedding Model Engine": "Embedding Model engine",
"Embedding model set to \"{{embedding_model}}\"": "Embedding model sat til \"{{embedding_model}}\"",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "Aktiver deling til Community",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "Grænseflade",
"Invalid file format.": "",
"Invalid Tag": "Ugyldigt tag",
"is typing...": "",
"January": "Januar",
"Jina API Key": "",
"join our Discord for help.": "tilslut dig vores Discord for at få hjælp.",
@@ -531,6 +537,7 @@
"Language": "Sprog",
"Last Active": "Sidst aktiv",
"Last Modified": "Sidst ændret",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "",
@@ -605,7 +612,7 @@
"Name": "Navn",
"Name your knowledge base": "",
"New Chat": "Ny chat",
"New folder": "",
"New Folder": "",
"New Password": "Ny adgangskode",
"new-channel": "",
"No content found": "",
@@ -736,6 +743,7 @@
"Rename": "Omdøb",
"Reorder Models": "",
"Repeat Last N": "Gentag sidste N",
"Reply in Thread": "",
"Request Mode": "Forespørgselstilstand",
"Reranking Model": "Omarrangeringsmodel",
"Reranking model disabled": "Omarrangeringsmodel deaktiveret",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "Nulstil uploadmappe",
"Reset Vector Storage/Knowledge": "",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Svarnotifikationer kan ikke aktiveres, da webstedets tilladelser er blevet nægtet. Besøg dine browserindstillinger for at give den nødvendige adgang.",
"Response splitting": "Svaropdeling",
"Result": "",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "For at få adgang til de GGUF-modeller, der er tilgængelige til download,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "For at få adgang til WebUI skal du kontakte administratoren. Administratorer kan administrere brugerstatus fra administrationspanelet.",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "For at vedhæfte vidensbase her skal du først tilføje dem til \"Viden\"-arbejdsområdet.",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "",
"To select actions here, add them to the \"Functions\" workspace first.": "For at vælge handlinger her skal du først tilføje dem til \"Funktioner\"-arbejdsområdet.",
"To select filters here, add them to the \"Functions\" workspace first.": "For at vælge filtre her skal du først tilføje dem til \"Funktioner\"-arbejdsområdet.",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "variabel for at få dem erstattet med indholdet af udklipsholderen.",
"Version": "Version",
"Version {{selectedVersion}} of {{totalVersions}}": "Version {{selectedVersion}} af {{totalVersions}}",
"View Replies": "",
"Visibility": "",
"Voice": "Stemme",
"Voice Input": "",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(z. B. `sh webui.sh --api`)",
"(latest)": "(neueste)",
"{{ models }}": "{{ Modelle }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "{{user}}s Unterhaltungen",
"{{webUIName}} Backend Required": "{{webUIName}}-Backend erforderlich",
"*Prompt node ID(s) are required for image generation": "*Prompt-Node-ID(s) sind für die Bildgenerierung erforderlich",
@@ -34,6 +35,7 @@
"Add Group": "Gruppe hinzufügen",
"Add Memory": "Erinnerung hinzufügen",
"Add Model": "Modell hinzufügen",
"Add Reaction": "",
"Add Tag": "Tag hinzufügen",
"Add Tags": "Tags hinzufügen",
"Add text content": "Textinhalt hinzufügen",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "Temporäre Unterhaltungen erlauben",
"Allow User Location": "Standort freigeben",
"Allow Voice Interruption in Call": "Unterbrechung durch Stimme im Anruf zulassen",
"Allowed Endpoints": "",
"Already have an account?": "Haben Sie bereits einen Account?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "Alternative zu top_p und zielt darauf ab, ein Gleichgewicht zwischen Qualität und Vielfalt zu gewährleisten. Der Parameter p repräsentiert die Mindestwahrscheinlichkeit für ein Token, um berücksichtigt zu werden, relativ zur Wahrscheinlichkeit des wahrscheinlichsten Tokens. Zum Beispiel, bei p=0.05 und das wahrscheinlichste Token hat eine Wahrscheinlichkeit von 0.9, werden Logits mit einem Wert von weniger als 0.045 herausgefiltert. (Standard: 0.0)",
"Amazing": "Fantastisch",
@@ -67,6 +70,7 @@
"API Base URL": "API-Basis-URL",
"API Key": "API-Schlüssel",
"API Key created.": "API-Schlüssel erstellt.",
"API Key Endpoint Restrictions": "",
"API keys": "API-Schlüssel",
"Application DN": "Anwendungs-DN",
"Application DN Password": "Anwendungs-DN-Passwort",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "Klicken Sie auf die Benutzerrolle, um sie zu ändern.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Schreibberechtigung für die Zwischenablage verweigert. Bitte überprüfen Sie Ihre Browsereinstellungen, um den erforderlichen Zugriff zu erlauben.",
"Clone": "Klonen",
"Clone Chat": "",
"Close": "Schließen",
"Code execution": "Codeausführung",
"Code formatted successfully": "Code erfolgreich formatiert",
@@ -310,7 +315,7 @@
"Embedding Model": "Embedding-Modell",
"Embedding Model Engine": "Embedding-Modell-Engine",
"Embedding model set to \"{{embedding_model}}\"": "Embedding-Modell auf \"{{embedding_model}}\" gesetzt",
"Enable API Key Auth": "API-Schlüssel-Authentifizierung aktivieren",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "Community-Freigabe aktivieren",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "Benutzeroberfläche",
"Invalid file format.": "Ungültiges Dateiformat.",
"Invalid Tag": "Ungültiger Tag",
"is typing...": "",
"January": "Januar",
"Jina API Key": "Jina-API-Schlüssel",
"join our Discord for help.": "Treten Sie unserem Discord bei, um Hilfe zu erhalten.",
@@ -531,6 +537,7 @@
"Language": "Sprache",
"Last Active": "Zuletzt aktiv",
"Last Modified": "Zuletzt bearbeitet",
"Last reply": "",
"LDAP": "LDAP",
"LDAP server updated": "LDAP-Server aktualisiert",
"Leaderboard": "Bestenliste",
@@ -605,7 +612,7 @@
"Name": "Name",
"Name your knowledge base": "Benennen Sie Ihren Wissensspeicher",
"New Chat": "Neue Unterhaltung",
"New folder": "",
"New Folder": "",
"New Password": "Neues Passwort",
"new-channel": "",
"No content found": "Kein Inhalt gefunden",
@@ -736,6 +743,7 @@
"Rename": "Umbenennen",
"Reorder Models": "",
"Repeat Last N": "Wiederhole die letzten N",
"Reply in Thread": "",
"Request Mode": "Anforderungsmodus",
"Reranking Model": "Reranking-Modell",
"Reranking model disabled": "Reranking-Modell deaktiviert",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "Upload-Verzeichnis zurücksetzen",
"Reset Vector Storage/Knowledge": "Vektorspeicher/Wissen zurücksetzen",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Benachrichtigungen können nicht aktiviert werden, da die Website-Berechtigungen abgelehnt wurden. Bitte besuchen Sie Ihre Browser-Einstellungen, um den erforderlichen Zugriff zu gewähren.",
"Response splitting": "Antwortaufteilung",
"Result": "Ergebnis",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "Um auf die verfügbaren GGUF-Modelle zuzugreifen,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Um auf das WebUI zugreifen zu können, wenden Sie sich bitte an einen Administrator. Administratoren können den Benutzerstatus über das Admin-Panel verwalten.",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "Um Wissensdatenbanken hier anzuhängen, fügen Sie sie zunächst dem Arbeitsbereich \"Wissen\" hinzu.",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "Um Ihre Privatsphäre zu schützen, werden nur Bewertungen, Modell-IDs, Tags und Metadaten aus Ihrem Feedback geteilt Ihre Unterhaltungen bleiben privat und werden nicht einbezogen.",
"To select actions here, add them to the \"Functions\" workspace first.": "Um Aktionen auszuwählen, fügen Sie diese zunächst dem Arbeitsbereich „Funktionen“ hinzu.",
"To select filters here, add them to the \"Functions\" workspace first.": "Um Filter auszuwählen, fügen Sie diese zunächst dem Arbeitsbereich „Funktionen“ hinzu.",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "Variable, um den Inhalt der Zwischenablage beim Nutzen des Prompts zu ersetzen.",
"Version": "Version",
"Version {{selectedVersion}} of {{totalVersions}}": "Version {{selectedVersion}} von {{totalVersions}}",
"View Replies": "",
"Visibility": "Sichtbarkeit",
"Voice": "Stimme",
"Voice Input": "Spracheingabe",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(such e.g. `sh webui.sh --api`)",
"(latest)": "(much latest)",
"{{ models }}": "",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "",
"{{webUIName}} Backend Required": "{{webUIName}} Backend Much Required",
"*Prompt node ID(s) are required for image generation": "",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "",
"Add Model": "",
"Add Reaction": "",
"Add Tag": "",
"Add Tags": "",
"Add text content": "",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "",
"Allow User Location": "",
"Allow Voice Interruption in Call": "",
"Allowed Endpoints": "",
"Already have an account?": "Such account exists?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "API Base URL",
"API Key": "API Key",
"API Key created.": "",
"API Key Endpoint Restrictions": "",
"API keys": "",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "Click user role button to change role.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "",
"Clone": "",
"Clone Chat": "",
"Close": "Close",
"Code execution": "",
"Code formatted successfully": "",
@@ -310,7 +315,7 @@
"Embedding Model": "",
"Embedding Model Engine": "",
"Embedding model set to \"{{embedding_model}}\"": "",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "Interface",
"Invalid file format.": "",
"Invalid Tag": "",
"is typing...": "",
"January": "",
"Jina API Key": "",
"join our Discord for help.": "join our Discord for help.",
@@ -531,6 +537,7 @@
"Language": "Doge Speak",
"Last Active": "",
"Last Modified": "",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "",
@@ -605,7 +612,7 @@
"Name": "Name",
"Name your knowledge base": "",
"New Chat": "New Bark",
"New folder": "",
"New Folder": "",
"New Password": "New Barkword",
"new-channel": "",
"No content found": "",
@@ -736,6 +743,7 @@
"Rename": "",
"Reorder Models": "",
"Repeat Last N": "Repeat Last N",
"Reply in Thread": "",
"Request Mode": "Request Bark",
"Reranking Model": "",
"Reranking model disabled": "",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "",
"Reset Vector Storage/Knowledge": "",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
"Response splitting": "",
"Result": "",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "To access the GGUF models available for downloading, much access",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "",
"To select actions here, add them to the \"Functions\" workspace first.": "",
"To select filters here, add them to the \"Functions\" workspace first.": "",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "variable to have them replaced with clipboard content. Very replace.",
"Version": "Version much version",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"View Replies": "",
"Visibility": "",
"Voice": "",
"Voice Input": "",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(π.χ. `sh webui.sh --api`)",
"(latest)": "(τελευταίο)",
"{{ models }}": "{{ models }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "Συνομιλίες του {{user}}",
"{{webUIName}} Backend Required": "{{webUIName}} Απαιτείται Backend",
"*Prompt node ID(s) are required for image generation": "*Τα αναγνωριστικά κόμβου Prompt απαιτούνται για τη δημιουργία εικόνων",
@@ -34,6 +35,7 @@
"Add Group": "Προσθήκη Ομάδας",
"Add Memory": "Προσθήκη Μνήμης",
"Add Model": "Προσθήκη Μοντέλου",
"Add Reaction": "",
"Add Tag": "Προσθήκη Ετικέτας",
"Add Tags": "Προσθήκη Ετικετών",
"Add text content": "Προσθήκη κειμένου",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "Επιτρέπεται η Προσωρινή Συνομιλία",
"Allow User Location": "Επιτρέπεται η Τοποθεσία Χρήστη",
"Allow Voice Interruption in Call": "Επιτρέπεται η Παύση Φωνής στην Κλήση",
"Allowed Endpoints": "",
"Already have an account?": "Έχετε ήδη λογαριασμό;",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "Εναλλακτικό στο top_p, και στοχεύει στη διασφάλιση μιας ισορροπίας μεταξύ ποιότητας και ποικιλίας. Η παράμετρος p αντιπροσωπεύει την ελάχιστη πιθανότητα για ένα token να θεωρηθεί, σε σχέση με την πιθανότητα του πιο πιθανού token. Για παράδειγμα, με p=0.05 και το πιο πιθανό token να έχει πιθανότητα 0.9, τα logits με τιμή μικρότερη από 0.045 φιλτράρονται. (Προεπιλογή: 0.0)",
"Amazing": "Καταπληκτικό",
@@ -67,6 +70,7 @@
"API Base URL": "API Βασικό URL",
"API Key": "Κλειδί API",
"API Key created.": "Το κλειδί API δημιουργήθηκε.",
"API Key Endpoint Restrictions": "",
"API keys": "κλειδιά API",
"Application DN": "DN Εφαρμογής",
"Application DN Password": "Κωδικός DN Εφαρμογής",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "Κάντε κλικ στο κουμπί ρόλου χρήστη για να αλλάξετε το ρόλο ενός χρήστη.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Άρνηση δικαιώματος εγγραφής στο πρόχειρο. Παρακαλώ ελέγξτε τις ρυθμίσεις του περιηγητή σας για να δώσετε την απαραίτητη πρόσβαση.",
"Clone": "Κλώνος",
"Clone Chat": "",
"Close": "Κλείσιμο",
"Code execution": "Εκτέλεση κώδικα",
"Code formatted successfully": "Ο κώδικας μορφοποιήθηκε επιτυχώς",
@@ -310,7 +315,7 @@
"Embedding Model": "Μοντέλο Ενσωμάτωσης",
"Embedding Model Engine": "Μηχανή Μοντέλου Ενσωμάτωσης",
"Embedding model set to \"{{embedding_model}}\"": "Το μοντέλο ενσωμάτωσης έχει οριστεί σε \"{{embedding_model}}\"",
"Enable API Key Auth": "Ενεργοποίηση Επαλήθευσης Κλειδιού API",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "Ενεργοποίηση Κοινοτικής Κοινής Χρήσης",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "Διεπαφή",
"Invalid file format.": "Μη έγκυρη μορφή αρχείου.",
"Invalid Tag": "Μη έγκυρη Ετικέτα",
"is typing...": "",
"January": "Ιανουάριος",
"Jina API Key": "Κλειδί API Jina",
"join our Discord for help.": "συμμετέχετε στο Discord μας για βοήθεια.",
@@ -531,6 +537,7 @@
"Language": "Γλώσσα",
"Last Active": "Τελευταία Ενεργή",
"Last Modified": "Τελευταία Τροποποίηση",
"Last reply": "",
"LDAP": "LDAP",
"LDAP server updated": "Ο διακομιστής LDAP ενημερώθηκε",
"Leaderboard": "Κατάταξη",
@@ -605,7 +612,7 @@
"Name": "Όνομα",
"Name your knowledge base": "Ονομάστε τη βάση γνώσης σας",
"New Chat": "Νέα Συνομιλία",
"New folder": "",
"New Folder": "",
"New Password": "Νέος Κωδικός",
"new-channel": "",
"No content found": "Δεν βρέθηκε περιεχόμενο",
@@ -736,6 +743,7 @@
"Rename": "Μετονομασία",
"Reorder Models": "Επαναταξινόμηση Μοντέλων",
"Repeat Last N": "Επανάληψη Τελευταίων N",
"Reply in Thread": "",
"Request Mode": "Λειτουργία Αιτήματος",
"Reranking Model": "Μοντέλο Επαναταξινόμησης",
"Reranking model disabled": "Το μοντέλο επαναταξινόμησης απενεργοποιήθηκε",
@@ -744,6 +752,7 @@
"Reset All Models": "Επαναφορά Όλων των Μοντέλων",
"Reset Upload Directory": "Επαναφορά Καταλόγου Ανεβάσματος",
"Reset Vector Storage/Knowledge": "Επαναφορά Αποθήκευσης Διανυσμάτων/Γνώσης",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Οι ειδοποιήσεις απάντησης δεν μπορούν να ενεργοποιηθούν καθώς οι άδειες του ιστότοπου έχουν αρνηθεί. Παρακαλώ επισκεφτείτε τις ρυθμίσεις του περιηγητή σας για να δώσετε την απαραίτητη πρόσβαση.",
"Response splitting": "Διαχωρισμός απάντησης",
"Result": "Αποτέλεσμα",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "Για να αποκτήσετε πρόσβαση στα μοντέλα GGUF διαθέσιμα για λήψη,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Για να αποκτήσετε πρόσβαση στο WebUI, παρακαλώ επικοινωνήστε με τον διαχειριστή. Οι διαχειριστές μπορούν να διαχειριστούν τις καταστάσεις των χρηστών από τον Πίνακα Διαχειριστή.",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "Για να επισυνάψετε τη βάση γνώσης εδώ, προσθέστε τα πρώτα στο χώρο εργασίας \"Knowledge\".",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "Για να προστατεύσετε την ιδιωτικότητά σας, μόνο οι βαθμολογίες, τα IDs μοντέλων, οι ετικέτες και τα μεταδεδομένα μοιράζονται από την ανατροφοδότησή σας—τα αρχεία συνομιλιών σας παραμένουν ιδιωτικά και δεν περιλαμβάνονται.",
"To select actions here, add them to the \"Functions\" workspace first.": "Για να επιλέξετε ενέργειες εδώ, προσθέστε τις πρώτα στο χώρο εργασίας \"Functions\".",
"To select filters here, add them to the \"Functions\" workspace first.": "Για να επιλέξετε φίλτρα εδώ, προσθέστε τα πρώτα στο χώρο εργασίας \"Functions\".",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "μεταβλητή να αντικατασταθούν με το περιεχόμενο του πρόχειρου.",
"Version": "Έκδοση",
"Version {{selectedVersion}} of {{totalVersions}}": "Έκδοση {{selectedVersion}} από {{totalVersions}}",
"View Replies": "",
"Visibility": "Ορατότητα",
"Voice": "Φωνή",
"Voice Input": "Εισαγωγή Φωνής",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "",
"(latest)": "",
"{{ models }}": "",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "",
"{{webUIName}} Backend Required": "",
"*Prompt node ID(s) are required for image generation": "",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "",
"Add Model": "",
"Add Reaction": "",
"Add Tag": "",
"Add Tags": "",
"Add text content": "",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "",
"Allow User Location": "",
"Allow Voice Interruption in Call": "",
"Allowed Endpoints": "",
"Already have an account?": "",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "",
"API Key": "",
"API Key created.": "",
"API Key Endpoint Restrictions": "",
"API keys": "",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "",
"Clone": "",
"Clone Chat": "",
"Close": "",
"Code execution": "",
"Code formatted successfully": "",
@@ -310,7 +315,7 @@
"Embedding Model": "",
"Embedding Model Engine": "",
"Embedding model set to \"{{embedding_model}}\"": "",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "",
"Invalid file format.": "",
"Invalid Tag": "",
"is typing...": "",
"January": "",
"Jina API Key": "",
"join our Discord for help.": "",
@@ -531,6 +537,7 @@
"Language": "",
"Last Active": "",
"Last Modified": "",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "",
@@ -605,7 +612,7 @@
"Name": "",
"Name your knowledge base": "",
"New Chat": "",
"New folder": "",
"New Folder": "",
"New Password": "",
"new-channel": "",
"No content found": "",
@@ -736,6 +743,7 @@
"Rename": "",
"Reorder Models": "",
"Repeat Last N": "",
"Reply in Thread": "",
"Request Mode": "",
"Reranking Model": "",
"Reranking model disabled": "",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "",
"Reset Vector Storage/Knowledge": "",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
"Response splitting": "",
"Result": "",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "",
"To select actions here, add them to the \"Functions\" workspace first.": "",
"To select filters here, add them to the \"Functions\" workspace first.": "",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "",
"Version": "",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"View Replies": "",
"Visibility": "",
"Voice": "",
"Voice Input": "",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "",
"(latest)": "",
"{{ models }}": "",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "",
"{{webUIName}} Backend Required": "",
"*Prompt node ID(s) are required for image generation": "",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "",
"Add Model": "",
"Add Reaction": "",
"Add Tag": "",
"Add Tags": "",
"Add text content": "",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "",
"Allow User Location": "",
"Allow Voice Interruption in Call": "",
"Allowed Endpoints": "",
"Already have an account?": "",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "",
"API Key": "",
"API Key created.": "",
"API Key Endpoint Restrictions": "",
"API keys": "",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "",
"Clone": "",
"Clone Chat": "",
"Close": "",
"Code execution": "",
"Code formatted successfully": "",
@@ -310,7 +315,7 @@
"Embedding Model": "",
"Embedding Model Engine": "",
"Embedding model set to \"{{embedding_model}}\"": "",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "",
"Invalid file format.": "",
"Invalid Tag": "",
"is typing...": "",
"January": "",
"Jina API Key": "",
"join our Discord for help.": "",
@@ -531,6 +537,7 @@
"Language": "",
"Last Active": "",
"Last Modified": "",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "",
@@ -605,7 +612,7 @@
"Name": "",
"Name your knowledge base": "",
"New Chat": "",
"New folder": "",
"New Folder": "",
"New Password": "",
"new-channel": "",
"No content found": "",
@@ -736,6 +743,7 @@
"Rename": "",
"Reorder Models": "",
"Repeat Last N": "",
"Reply in Thread": "",
"Request Mode": "",
"Reranking Model": "",
"Reranking model disabled": "",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "",
"Reset Vector Storage/Knowledge": "",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
"Response splitting": "",
"Result": "",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "",
"To select actions here, add them to the \"Functions\" workspace first.": "",
"To select filters here, add them to the \"Functions\" workspace first.": "",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "",
"Version": "",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"View Replies": "",
"Visibility": "",
"Voice": "",
"Voice Input": "",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(p.ej. `sh webui.sh --api`)",
"(latest)": "(latest)",
"{{ models }}": "{{ models }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "Chats de {{user}}",
"{{webUIName}} Backend Required": "{{webUIName}} Servidor Requerido",
"*Prompt node ID(s) are required for image generation": "Los ID de nodo son requeridos para la generación de imágenes",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "Agregar Memoria",
"Add Model": "Agregar Modelo",
"Add Reaction": "",
"Add Tag": "Agregar etiqueta",
"Add Tags": "agregar etiquetas",
"Add text content": "Añade contenido de texto",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "Permitir Chat Temporal",
"Allow User Location": "Permitir Ubicación del Usuario",
"Allow Voice Interruption in Call": "Permitir interrupción de voz en llamada",
"Allowed Endpoints": "",
"Already have an account?": "¿Ya tienes una cuenta?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "Dirección URL de la API",
"API Key": "Clave de la API ",
"API Key created.": "Clave de la API creada.",
"API Key Endpoint Restrictions": "",
"API keys": "Claves de la API",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "Presiona en el botón de roles del usuario para cambiar su rol.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Permisos de escritura del portapapeles denegados. Por favor, comprueba las configuraciones de tu navegador para otorgar el acceso necesario.",
"Clone": "Clonar",
"Clone Chat": "",
"Close": "Cerrar",
"Code execution": "",
"Code formatted successfully": "Se ha formateado correctamente el código.",
@@ -310,7 +315,7 @@
"Embedding Model": "Modelo de Embedding",
"Embedding Model Engine": "Motor de Modelo de Embedding",
"Embedding model set to \"{{embedding_model}}\"": "Modelo de Embedding configurado a \"{{embedding_model}}\"",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "Habilitar el uso compartido de la comunidad",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "Interfaz",
"Invalid file format.": "",
"Invalid Tag": "Etiqueta Inválida",
"is typing...": "",
"January": "Enero",
"Jina API Key": "",
"join our Discord for help.": "Únase a nuestro Discord para obtener ayuda.",
@@ -531,6 +537,7 @@
"Language": "Lenguaje",
"Last Active": "Última Actividad",
"Last Modified": "Modificado por última vez",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "",
@@ -605,7 +612,7 @@
"Name": "Nombre",
"Name your knowledge base": "",
"New Chat": "Nuevo Chat",
"New folder": "",
"New Folder": "",
"New Password": "Nueva Contraseña",
"new-channel": "",
"No content found": "",
@@ -736,6 +743,7 @@
"Rename": "Renombrar",
"Reorder Models": "",
"Repeat Last N": "Repetir las últimas N",
"Reply in Thread": "",
"Request Mode": "Modo de petición",
"Reranking Model": "Modelo de reranking",
"Reranking model disabled": "Modelo de reranking deshabilitado",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "Reiniciar Directorio de carga",
"Reset Vector Storage/Knowledge": "",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Las notificaciones de respuesta no pueden activarse debido a que los permisos del sitio web han sido denegados. Por favor, visite las configuraciones de su navegador para otorgar el acceso necesario.",
"Response splitting": "División de respuestas",
"Result": "",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "Para acceder a los modelos GGUF disponibles para descargar,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Para acceder al interfaz de usuario web, por favor contacte al administrador. Los administradores pueden administrar los estados de los usuarios desde el panel de administración.",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "Para adjuntar la base de conocimientos aquí, agreguelas al área de trabajo \"Conocimiento\" primero.",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "",
"To select actions here, add them to the \"Functions\" workspace first.": "Para seleccionar acciones aquí, agreguelas al área de trabajo \"Funciones\" primero.",
"To select filters here, add them to the \"Functions\" workspace first.": "Para seleccionar filtros aquí, agreguelos al área de trabajo \"Funciones\" primero.",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "variable para reemplazarlos con el contenido del portapapeles.",
"Version": "Versión",
"Version {{selectedVersion}} of {{totalVersions}}": "Versión {{selectedVersion}} de {{totalVersions}}",
"View Replies": "",
"Visibility": "",
"Voice": "Voz",
"Voice Input": "",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(adib. `sh webui.sh --api`)",
"(latest)": "(azkena)",
"{{ models }}": "{{ models }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "{{user}}-ren Txatak",
"{{webUIName}} Backend Required": "{{webUIName}} Backend-a Beharrezkoa",
"*Prompt node ID(s) are required for image generation": "Prompt nodoaren IDa(k) beharrezkoak dira irudiak sortzeko",
@@ -34,6 +35,7 @@
"Add Group": "Gehitu Taldea",
"Add Memory": "Gehitu Memoria",
"Add Model": "Gehitu Eredua",
"Add Reaction": "",
"Add Tag": "Gehitu Etiketa",
"Add Tags": "Gehitu Etiketak",
"Add text content": "Gehitu testu edukia",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "Baimendu Behin-behineko Txata",
"Allow User Location": "Baimendu Erabiltzailearen Kokapena",
"Allow Voice Interruption in Call": "Baimendu Ahots Etena Deietan",
"Allowed Endpoints": "",
"Already have an account?": "Baduzu kontu bat?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "top_p-ren alternatiba, kalitate eta aniztasunaren arteko oreka bermatzea du helburu. p parametroak token bat kontuan hartzeko gutxieneko probabilitatea adierazten du, token probableenaren probabilitatearen arabera. Adibidez, p=0.05 balioarekin eta token probableenaren probabilitatea 0.9 denean, 0.045 baino balio txikiagoko logit-ak baztertzen dira. (Lehenetsia: 0.0)",
"Amazing": "Harrigarria",
@@ -67,6 +70,7 @@
"API Base URL": "API Oinarri URLa",
"API Key": "API Gakoa",
"API Key created.": "API Gakoa sortu da.",
"API Key Endpoint Restrictions": "",
"API keys": "API gakoak",
"Application DN": "Aplikazioaren DN",
"Application DN Password": "Aplikazioaren DN Pasahitza",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "Klikatu erabiltzaile rolaren botoian erabiltzaile baten rola aldatzeko.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Arbelerako idazteko baimena ukatua. Mesedez, egiaztatu zure nabigatzailearen ezarpenak beharrezko sarbidea emateko.",
"Clone": "Klonatu",
"Clone Chat": "",
"Close": "Itxi",
"Code execution": "Kodearen exekuzioa",
"Code formatted successfully": "Kodea ongi formateatu da",
@@ -310,7 +315,7 @@
"Embedding Model": "Embedding Eredua",
"Embedding Model Engine": "Embedding Eredu Motorea",
"Embedding model set to \"{{embedding_model}}\"": "Embedding eredua \"{{embedding_model}}\"-ra ezarri da",
"Enable API Key Auth": "Gaitu API Gako Autentikazioa",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "Gaitu Komunitatearen Partekatzea",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "Interfazea",
"Invalid file format.": "Fitxategi formatu baliogabea.",
"Invalid Tag": "Etiketa Baliogabea",
"is typing...": "",
"January": "Urtarrila",
"Jina API Key": "Jina API Gakoa",
"join our Discord for help.": "batu gure Discord-era laguntzarako.",
@@ -531,6 +537,7 @@
"Language": "Hizkuntza",
"Last Active": "Azken Aktibitatea",
"Last Modified": "Azken Aldaketa",
"Last reply": "",
"LDAP": "LDAP",
"LDAP server updated": "LDAP zerbitzaria eguneratu da",
"Leaderboard": "Sailkapena",
@@ -605,7 +612,7 @@
"Name": "Izena",
"Name your knowledge base": "Izendatu zure ezagutza-basea",
"New Chat": "Txat berria",
"New folder": "",
"New Folder": "",
"New Password": "Pasahitz berria",
"new-channel": "",
"No content found": "Ez da edukirik aurkitu",
@@ -736,6 +743,7 @@
"Rename": "Berrizendatu",
"Reorder Models": "Berrantolatu modeloak",
"Repeat Last N": "Errepikatu azken N",
"Reply in Thread": "",
"Request Mode": "Eskaera modua",
"Reranking Model": "Berrantolatze modeloa",
"Reranking model disabled": "Berrantolatze modeloa desgaituta",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "Berrezarri karga direktorioa",
"Reset Vector Storage/Knowledge": "Berrezarri bektore biltegia/ezagutza",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Erantzunen jakinarazpenak ezin dira aktibatu webgunearen baimenak ukatu direlako. Mesedez, bisitatu zure nabigatzailearen ezarpenak beharrezko sarbidea emateko.",
"Response splitting": "Erantzun banaketa",
"Result": "Emaitza",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "Deskargatzeko eskuragarri dauden GGUF modeloak atzitzeko,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "WebUI-a atzitzeko, mesedez jarri harremanetan administratzailearekin. Administratzaileek erabiltzaileen egoerak kudeatu ditzakete Admin Paneletik.",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "Ezagutza-basea hemen eransteko, gehitu ezazu lehenik \"Ezagutza\" lan-eremura.",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "Zure pribatutasuna babesteko, zure feedbacketik bakarrik partekatzen dira balorazioak, modelo IDak, etiketak eta metadatuak—zure txat erregistroak pribatuak dira eta ez dira sartzen.",
"To select actions here, add them to the \"Functions\" workspace first.": "Ekintzak hemen hautatzeko, gehitu itzazu lehenik \"Funtzioak\" lan-eremura.",
"To select filters here, add them to the \"Functions\" workspace first.": "Iragazkiak hemen hautatzeko, gehitu itzazu lehenik \"Funtzioak\" lan-eremura.",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "aldagaia arbeleko edukiarekin ordezkatzeko.",
"Version": "Bertsioa",
"Version {{selectedVersion}} of {{totalVersions}}": "{{totalVersions}}-tik {{selectedVersion}}. bertsioa",
"View Replies": "",
"Visibility": "Ikusgarritasuna",
"Voice": "Ahotsa",
"Voice Input": "Ahots sarrera",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(e.g. `sh webui.sh --api`)",
"(latest)": "(آخرین)",
"{{ models }}": "{{ models }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "{{user}} گفتگوهای",
"{{webUIName}} Backend Required": "بکند {{webUIName}} نیاز است.",
"*Prompt node ID(s) are required for image generation": "",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "افزودن حافظه",
"Add Model": "افزودن مدل",
"Add Reaction": "",
"Add Tag": "افزودن برچسب",
"Add Tags": "افزودن برچسب\u200cها",
"Add text content": "افزودن محتوای متنی",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "اجازهٔ گفتگوی موقتی",
"Allow User Location": "اجازهٔ موقعیت مکانی کاربر",
"Allow Voice Interruption in Call": "",
"Allowed Endpoints": "",
"Already have an account?": "از قبل حساب کاربری دارید؟",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "نشانی پایهٔ API",
"API Key": "کلید API",
"API Key created.": "کلید API ساخته شد.",
"API Key Endpoint Restrictions": "",
"API keys": "کلیدهای API",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "برای تغییر نقش کاربر، روی دکمه نقش کاربر کلیک کنید.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "",
"Clone": "کلون",
"Clone Chat": "",
"Close": "بسته",
"Code execution": "",
"Code formatted successfully": "",
@@ -310,7 +315,7 @@
"Embedding Model": "مدل پیدائش",
"Embedding Model Engine": "محرک مدل پیدائش",
"Embedding model set to \"{{embedding_model}}\"": "مدل پیدائش را به \"{{embedding_model}}\" تنظیم کنید",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "فعالسازی اشتراک انجمن",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "رابط",
"Invalid file format.": "",
"Invalid Tag": "تگ نامعتبر",
"is typing...": "",
"January": "ژانویه",
"Jina API Key": "",
"join our Discord for help.": "برای کمک به دیسکورد ما بپیوندید.",
@@ -531,6 +537,7 @@
"Language": "زبان",
"Last Active": "آخرین فعال",
"Last Modified": "",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "",
@@ -605,7 +612,7 @@
"Name": "نام",
"Name your knowledge base": "",
"New Chat": "گپ جدید",
"New folder": "",
"New Folder": "",
"New Password": "رمز عبور جدید",
"new-channel": "",
"No content found": "",
@@ -736,6 +743,7 @@
"Rename": "تغییر نام",
"Reorder Models": "",
"Repeat Last N": "Repeat Last N",
"Reply in Thread": "",
"Request Mode": "حالت درخواست",
"Reranking Model": "مدل ری\u200cشناسی مجدد غیرفعال است",
"Reranking model disabled": "مدل ری\u200cشناسی مجدد غیرفعال است",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "",
"Reset Vector Storage/Knowledge": "",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
"Response splitting": "",
"Result": "نتیجه",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "برای دسترسی به مدل\u200cهای GGUF موجود برای دانلود،",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "",
"To select actions here, add them to the \"Functions\" workspace first.": "",
"To select filters here, add them to the \"Functions\" workspace first.": "",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "متغیر برای جایگزینی آنها با محتوای بریده\u200cدان.",
"Version": "نسخه",
"Version {{selectedVersion}} of {{totalVersions}}": "نسخهٔ {{selectedVersion}} از {{totalVersions}}",
"View Replies": "",
"Visibility": "",
"Voice": "صوت",
"Voice Input": "ورودی صوتی",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(esim. `sh webui.sh --api`)",
"(latest)": "(uusin)",
"{{ models }}": "{{ mallit }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "{{user}}:n keskustelut",
"{{webUIName}} Backend Required": "{{webUIName}}-backend vaaditaan",
"*Prompt node ID(s) are required for image generation": "Kuvan luomiseen vaaditaan kehote-solmun ID(t)",
@@ -34,6 +35,7 @@
"Add Group": "Lisää ryhmä",
"Add Memory": "Lisää muistia",
"Add Model": "Lisää malli",
"Add Reaction": "",
"Add Tag": "Lisää tagi",
"Add Tags": "Lisää tageja",
"Add text content": "Lisää tekstisisältöä",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "Salli väliaikaiset keskustelut",
"Allow User Location": "Salli käyttäjän sijainti",
"Allow Voice Interruption in Call": "Salli äänen keskeytys puhelussa",
"Allowed Endpoints": "",
"Already have an account?": "Onko sinulla jo tili?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "Vaihtoehto top_p:lle, jolla pyritään varmistamaan laadun ja monipuolisuuden tasapaino. Parametri p edustaa pienintä todennäköisyyttä, jolla token otetaan huomioon suhteessa todennäköisimpään tokeniin. Esimerkiksi p=0.05 ja todennäköisin token todennäköisyydellä 0.9, arvoltaan alle 0.045 olevat logit suodatetaan pois. (Oletus: 0.0)",
"Amazing": "Hämmästyttävä",
@@ -67,6 +70,7 @@
"API Base URL": "APIn perus-URL",
"API Key": "API-avain",
"API Key created.": "API-avain luotu.",
"API Key Endpoint Restrictions": "",
"API keys": "API-avaimet",
"Application DN": "Sovelluksen DN",
"Application DN Password": "Sovelluksen DN-salasana",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "Klikkaa käyttäjän roolipainiketta vaihtaaksesi käyttäjän roolia.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Leikepöydälle kirjoitusoikeus evätty. Tarkista selaimesi asetukset ja myönnä tarvittavat käyttöoikeudet.",
"Clone": "Kloonaa",
"Clone Chat": "",
"Close": "Sulje",
"Code execution": "Koodin suorittaminen",
"Code formatted successfully": "Koodin muotoilu onnistui",
@@ -310,7 +315,7 @@
"Embedding Model": "Upotusmalli",
"Embedding Model Engine": "Upotusmallin moottori",
"Embedding model set to \"{{embedding_model}}\"": "\"{{embedding_model}}\" valittu upotusmalliksi",
"Enable API Key Auth": "Ota API-avaimen todentaminen käyttöön",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "Ota automaattinen täydennys käyttöön keskusteluviesteissä",
"Enable Community Sharing": "Ota yhteisön jakaminen käyttöön",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "Käyttöliittymä",
"Invalid file format.": "Virheellinen tiedostomuoto.",
"Invalid Tag": "Virheellinen tagi",
"is typing...": "",
"January": "tammikuu",
"Jina API Key": "Jina API -avain",
"join our Discord for help.": "liity Discordiimme saadaksesi apua.",
@@ -531,6 +537,7 @@
"Language": "Kieli",
"Last Active": "Viimeksi aktiivinen",
"Last Modified": "Viimeksi muokattu",
"Last reply": "",
"LDAP": "LDAP",
"LDAP server updated": "LDAP-palvelin päivitetty",
"Leaderboard": "Tulosluettelo",
@@ -605,7 +612,7 @@
"Name": "Nimi",
"Name your knowledge base": "Anna tietokannalle nimi",
"New Chat": "Uusi keskustelu",
"New folder": "",
"New Folder": "",
"New Password": "Uusi salasana",
"new-channel": "",
"No content found": "Sisältöä ei löytynyt",
@@ -736,6 +743,7 @@
"Rename": "Nimeä uudelleen",
"Reorder Models": "Uudelleenjärjestä malleja",
"Repeat Last N": "Toista viimeiset N",
"Reply in Thread": "",
"Request Mode": "Pyyntötila",
"Reranking Model": "Uudelleenpisteytymismalli",
"Reranking model disabled": "Uudelleenpisteytymismalli poistettu käytöstä",
@@ -744,6 +752,7 @@
"Reset All Models": "Palauta kaikki mallit",
"Reset Upload Directory": "Palauta latauspolku",
"Reset Vector Storage/Knowledge": "Tyhjennä vektoritallennukset/tietämys",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Vastausilmoituksia ei voida ottaa käyttöön, koska verkkosivuston käyttöoikeudet on evätty. Myönnä tarvittavat käyttöoikeudet selaimesi asetuksista.",
"Response splitting": "Vastauksen jakaminen",
"Result": "Tulos",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "Päästäksesi käsiksi ladattavissa oleviin GGUF-malleihin,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Päästäksesi käyttämään WebUI:ta, ota yhteyttä ylläpitäjään. Ylläpitäjät voivat hallita käyttäjien tiloja Ylläpitopaneelista.",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "Liittääksesi tietokantasi tähän, lisää ne ensin \"Tietämys\"-työtilaan.",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "Yksityisyydensuojasi vuoksi palautteestasi jaetaan vain arvostelut, mallitunnukset, tagit ja metadata - keskustelulokisi pysyvät yksityisinä eikä niitä sisällytetä.",
"To select actions here, add them to the \"Functions\" workspace first.": "Valitaksesi toimintoja tässä, lisää ne ensin \"Toiminnot\"-työtilaan.",
"To select filters here, add them to the \"Functions\" workspace first.": "Valitaksesi suodattimia tässä, lisää ne ensin \"Toiminnot\"-työtilaan.",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "muuttuja korvataan leikepöydän sisällöllä.",
"Version": "Versio",
"Version {{selectedVersion}} of {{totalVersions}}": "Versio {{selectedVersion}} / {{totalVersions}}",
"View Replies": "",
"Visibility": "Näkyvyys",
"Voice": "Ääni",
"Voice Input": "Äänitulolaitteen käyttö",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(par exemple `sh webui.sh --api`)",
"(latest)": "(dernier)",
"{{ models }}": "{{ modèles }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "Discussions de {{user}}",
"{{webUIName}} Backend Required": "Backend {{webUIName}} requis",
"*Prompt node ID(s) are required for image generation": "",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "Ajouter de la mémoire",
"Add Model": "Ajouter un modèle",
"Add Reaction": "",
"Add Tag": "",
"Add Tags": "Ajouter des balises",
"Add text content": "",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "",
"Allow User Location": "Autoriser l'emplacement de l'utilisateur",
"Allow Voice Interruption in Call": "Autoriser l'interruption vocale pendant un appel",
"Allowed Endpoints": "",
"Already have an account?": "Avez-vous déjà un compte ?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "URL de base de l'API",
"API Key": "Clé d'API",
"API Key created.": "Clé d'API générée.",
"API Key Endpoint Restrictions": "",
"API keys": "Clés d'API",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "Cliquez sur le bouton de rôle d'utilisateur pour modifier le rôle d'un utilisateur.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "L'autorisation d'écriture du presse-papier a été refusée. Veuillez vérifier les paramètres de votre navigateur pour accorder l'accès nécessaire.",
"Clone": "Copie conforme",
"Clone Chat": "",
"Close": "Fermer",
"Code execution": "",
"Code formatted successfully": "Le code a été formaté avec succès",
@@ -310,7 +315,7 @@
"Embedding Model": "Modèle d'embedding",
"Embedding Model Engine": "Moteur de modèle d'encodage",
"Embedding model set to \"{{embedding_model}}\"": "Modèle d'encodage défini sur « {{embedding_model}} »",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "Activer le partage communautaire",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "Interface utilisateur",
"Invalid file format.": "",
"Invalid Tag": "Étiquette non valide",
"is typing...": "",
"January": "Janvier",
"Jina API Key": "",
"join our Discord for help.": "Rejoignez notre Discord pour obtenir de l'aide.",
@@ -531,6 +537,7 @@
"Language": "Langue",
"Last Active": "Dernière activité",
"Last Modified": "Dernière modification",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "",
@@ -605,7 +612,7 @@
"Name": "Nom",
"Name your knowledge base": "",
"New Chat": "Nouvelle conversation",
"New folder": "",
"New Folder": "",
"New Password": "Nouveau mot de passe",
"new-channel": "",
"No content found": "",
@@ -736,6 +743,7 @@
"Rename": "Renommer",
"Reorder Models": "",
"Repeat Last N": "Répéter les N derniers",
"Reply in Thread": "",
"Request Mode": "Mode de Requête",
"Reranking Model": "Modèle de ré-ranking",
"Reranking model disabled": "Modèle de ré-ranking désactivé",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "Répertoire de téléchargement réinitialisé",
"Reset Vector Storage/Knowledge": "",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Les notifications de réponse ne peuvent pas être activées car les autorisations du site web ont été refusées. Veuillez visiter les paramètres de votre navigateur pour accorder l'accès nécessaire.",
"Response splitting": "Fractionnement de la réponse",
"Result": "",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "Pour accéder aux modèles GGUF disponibles en téléchargement,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Pour accéder à l'interface Web, veuillez contacter l'administrateur. Les administrateurs peuvent gérer les statuts des utilisateurs depuis le panneau d'administration.",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "",
"To select actions here, add them to the \"Functions\" workspace first.": "",
"To select filters here, add them to the \"Functions\" workspace first.": "Pour sélectionner des filtres ici, ajoutez-les d'abord à l'espace de travail « Fonctions ». ",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "variable pour qu'elles soient remplacées par le contenu du presse-papiers.",
"Version": "Version améliorée",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"View Replies": "",
"Visibility": "",
"Voice": "Voix",
"Voice Input": "",
+55 -44
View File
@@ -1,10 +1,11 @@
{
"-1 for no limit, or a positive integer for a specific limit": "",
"-1 for no limit, or a positive integer for a specific limit": "-1 pour aucune limite, ou un entier positif pour une limite spécifique",
"'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": " 's', 'm', 'h', 'd', 'w' ou '-1' pour une durée illimitée.",
"(e.g. `sh webui.sh --api --api-auth username_password`)": "(par ex. `sh webui.sh --api --api-auth username_password`)",
"(e.g. `sh webui.sh --api`)": "(par exemple `sh webui.sh --api`)",
"(latest)": "(dernière version)",
"{{ models }}": "{{ models }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "Conversations de {{user}}",
"{{webUIName}} Backend Required": "Backend {{webUIName}} requis",
"*Prompt node ID(s) are required for image generation": "*Les ID de noeud du prompt sont nécessaires pour la génération dimages",
@@ -34,6 +35,7 @@
"Add Group": "Ajouter un groupe",
"Add Memory": "Ajouter de la mémoire",
"Add Model": "Ajouter un modèle",
"Add Reaction": "",
"Add Tag": "Ajouter un tag",
"Add Tags": "Ajouter des tags",
"Add text content": "Ajouter du contenu textuel",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "Autoriser le chat éphémère",
"Allow User Location": "Autoriser l'emplacement de l'utilisateur",
"Allow Voice Interruption in Call": "Autoriser l'interruption vocale pendant un appel",
"Allowed Endpoints": "Points de terminaison autorisés",
"Already have an account?": "Avez-vous déjà un compte ?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "Alternative au top_p, visant à assurer un équilibre entre qualité et variété. Le paramètre p représente la probabilité minimale pour qu'un token soit pris en compte, par rapport à la probabilité du token le plus probable. Par exemple, avec p=0.05 et le token le plus probable ayant une probabilité de 0.9, les logits ayant une valeur inférieure à 0.045 sont filtrés. (Par défaut : 0.0)",
"Amazing": "Incroyable",
@@ -67,6 +70,7 @@
"API Base URL": "URL de base de l'API",
"API Key": "Clé d'API",
"API Key created.": "Clé d'API générée.",
"API Key Endpoint Restrictions": "Restrictions des points de terminaison de la clé API",
"API keys": "Clés d'API",
"Application DN": "DN de l'application",
"Application DN Password": "Mot de passe DN de l'application",
@@ -76,8 +80,8 @@
"Archive All Chats": "Archiver toutes les conversations",
"Archived Chats": "Conversations archivées",
"archived-chat-export": "exportation de conversation archivée",
"Are you sure you want to delete this channel?": "",
"Are you sure you want to delete this message?": "",
"Are you sure you want to delete this channel?": "Êtes-vous sûr de vouloir supprimer ce canal ?",
"Are you sure you want to delete this message?": "Êtes-vous sûr de vouloir supprimer ce message ?",
"Are you sure you want to unarchive all archived chats?": "Êtes-vous sûr de vouloir désarchiver toutes les conversations archivées?",
"Are you sure?": "Êtes-vous certain ?",
"Arena Models": "Modèles d'arène",
@@ -92,8 +96,8 @@
"Authenticate": "Authentifier",
"Auto-Copy Response to Clipboard": "Copie automatique de la réponse vers le presse-papiers",
"Auto-playback response": "Lire automatiquement la réponse",
"Autocomplete Generation": "",
"Autocomplete Generation Input Max Length": "",
"Autocomplete Generation": "Génération des suggestions",
"Autocomplete Generation Input Max Length": "Longueur maximale pour la génération des suggestions",
"Automatic1111": "Automatic1111",
"AUTOMATIC1111 Api Auth String": "AUTOMATIC1111 Chaîne d'authentification de l'API",
"AUTOMATIC1111 Base URL": "URL de base AUTOMATIC1111",
@@ -110,7 +114,7 @@
"Batch Size (num_batch)": "Batch Size (num_batch)",
"before": "avant",
"Being lazy": "Être fainéant",
"Beta": "",
"Beta": "Bêta",
"Bing Search V7 Endpoint": "Point de terminaison Bing Search V7",
"Bing Search V7 Subscription Key": "Clé d'abonnement Bing Search V7",
"Brave Search API Key": "Clé API Brave Search",
@@ -121,13 +125,13 @@
"Camera": "Appareil photo",
"Cancel": "Annuler",
"Capabilities": "Capacités",
"Capture": "",
"Capture": "Prise de vue",
"Certificate Path": "Chemin du certificat",
"Change Password": "Changer le mot de passe",
"Channel Name": "",
"Channels": "",
"Channel Name": "Nom du canal",
"Channels": "Canaux",
"Character": "Caractère",
"Character limit for autocomplete generation input": "",
"Character limit for autocomplete generation input": "Limite de caractères pour la génération des suggestions",
"Chart new frontiers": "Tracer de nouvelles frontières",
"Chat": "Chat",
"Chat Background Image": "Image d'arrière-plan de la fenêtre de chat",
@@ -162,13 +166,14 @@
"Click on the user role button to change a user's role.": "Cliquez sur le bouton de rôle d'utilisateur pour modifier son rôle.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "L'autorisation d'écriture du presse-papier a été refusée. Veuillez vérifier les paramètres de votre navigateur pour accorder l'accès nécessaire.",
"Clone": "Cloner",
"Clone Chat": "",
"Close": "Fermer",
"Code execution": "Exécution de code",
"Code formatted successfully": "Le code a été formaté avec succès",
"Collection": "Collection",
"Color": "Couleur",
"ComfyUI": "ComfyUI",
"ComfyUI API Key": "",
"ComfyUI API Key": "Clé API ComfyUI",
"ComfyUI Base URL": "URL de base ComfyUI",
"ComfyUI Base URL is required.": "L'URL de base ComfyUI est requise.",
"ComfyUI Workflow": "Flux de travaux de ComfyUI",
@@ -181,7 +186,7 @@
"Confirm": "Confirmer",
"Confirm Password": "Confirmer le mot de passe",
"Confirm your action": "Confirmer votre action",
"Confirm your new password": "",
"Confirm your new password": "Confirmer votre nouveau mot de passe",
"Connections": "Connexions",
"Contact Admin for WebUI Access": "Contacter l'administrateur pour obtenir l'accès à WebUI",
"Content": "Contenu",
@@ -208,7 +213,7 @@
"Create a model": "Créer un modèle",
"Create Account": "Créer un compte",
"Create Admin Account": "Créer un compte administrateur",
"Create Channel": "",
"Create Channel": "Créer un canal",
"Create Group": "Créer un groupe",
"Create Knowledge": "Créer une connaissance",
"Create new key": "Créer une nouvelle clé",
@@ -244,7 +249,7 @@
"Delete chat?": "Supprimer la conversation ?",
"Delete folder?": "Supprimer le dossier ?",
"Delete function?": "Supprimer la fonction ?",
"Delete Message": "",
"Delete Message": "Supprimer le message",
"Delete prompt?": "Supprimer le prompt ?",
"delete this link": "supprimer ce lien",
"Delete tool?": "Effacer l'outil ?",
@@ -297,7 +302,7 @@
"e.g. Tools for performing various operations": "par ex. Outils pour effectuer diverses opérations",
"Edit": "Modifier",
"Edit Arena Model": "Modifier le modèle d'arène",
"Edit Channel": "",
"Edit Channel": "Modifier le canal",
"Edit Connection": "Modifier la connexion",
"Edit Default Permissions": "Modifier les autorisations par défaut",
"Edit Memory": "Modifier la mémoire",
@@ -310,10 +315,10 @@
"Embedding Model": "Modèle d'embedding",
"Embedding Model Engine": "Moteur de modèle d'embedding",
"Embedding model set to \"{{embedding_model}}\"": "Modèle d'embedding défini sur « {{embedding_model}} »",
"Enable API Key Auth": "Activer l'authentification par clé API",
"Enable autocomplete generation for chat messages": "",
"Enable API Key": "Activer la clé API",
"Enable autocomplete generation for chat messages": "Activer la génération des suggestions pour les messages",
"Enable Community Sharing": "Activer le partage communautaire",
"Enable Google Drive": "",
"Enable Google Drive": "Activer Google Drive",
"Enable Memory Locking (mlock) to prevent model data from being swapped out of RAM. This option locks the model's working set of pages into RAM, ensuring that they will not be swapped out to disk. This can help maintain performance by avoiding page faults and ensuring fast data access.": "Activer le verrouillage de la mémoire (mlock) pour empêcher les données du modèle d'être échangées de la RAM. Cette option verrouille l'ensemble de pages de travail du modèle en RAM, garantissant qu'elles ne seront pas échangées vers le disque. Cela peut aider à maintenir les performances en évitant les défauts de page et en assurant un accès rapide aux données.",
"Enable Memory Mapping (mmap) to load model data. This option allows the system to use disk storage as an extension of RAM by treating disk files as if they were in RAM. This can improve model performance by allowing for faster data access. However, it may not work correctly with all systems and can consume a significant amount of disk space.": "Activer le mappage de la mémoire (mmap) pour charger les données du modèle. Cette option permet au système d'utiliser le stockage disque comme une extension de la RAM en traitant les fichiers disque comme s'ils étaient en RAM. Cela peut améliorer les performances du modèle en permettant un accès plus rapide aux données. Cependant, cela peut ne pas fonctionner correctement avec tous les systèmes et peut consommer une quantité significative d'espace disque.",
"Enable Message Rating": "Activer l'évaluation des messages",
@@ -341,13 +346,13 @@
"Enter Google PSE Engine Id": "Entrez l'identifiant du moteur Google PSE",
"Enter Image Size (e.g. 512x512)": "Entrez la taille de l'image (par ex. 512x512)",
"Enter Jina API Key": "Entrez la clé API Jina",
"Enter Kagi Search API Key": "",
"Enter Kagi Search API Key": "Entrez la clé API Kagi Search",
"Enter language codes": "Entrez les codes de langue",
"Enter Model ID": "Entrez l'ID du modèle",
"Enter model tag (e.g. {{modelTag}})": "Entrez le tag du modèle (par ex. {{modelTag}})",
"Enter Mojeek Search API Key": "Entrez la clé API Mojeek",
"Enter Number of Steps (e.g. 50)": "Entrez le nombre d'étapes (par ex. 50)",
"Enter proxy URL (e.g. https://user:password@host:port)": "",
"Enter proxy URL (e.g. https://user:password@host:port)": "Entrez l'URL du proxy (par ex. https://use:password@host:port)",
"Enter Sampler (e.g. Euler a)": "Entrez le sampler (par ex. Euler a)",
"Enter Scheduler (e.g. Karras)": "Entrez le planificateur (par ex. Karras)",
"Enter Score": "Entrez votre score",
@@ -364,24 +369,24 @@
"Enter stop sequence": "Entrez la séquence d'arrêt",
"Enter system prompt": "Entrez le prompt système",
"Enter Tavily API Key": "Entrez la clé API Tavily",
"Enter the public URL of your WebUI. This URL will be used to generate links in the notifications.": "",
"Enter the public URL of your WebUI. This URL will be used to generate links in the notifications.": "Entrez l'URL publique de votre WebUI. Cette URL sera utilisée pour générer des liens dans les notifications.",
"Enter Tika Server URL": "Entrez l'URL du serveur Tika",
"Enter Top K": "Entrez les Top K",
"Enter URL (e.g. http://127.0.0.1:7860/)": "Entrez l'URL (par ex. {http://127.0.0.1:7860/})",
"Enter URL (e.g. http://localhost:11434)": "Entrez l'URL (par ex. http://localhost:11434)",
"Enter your current password": "",
"Enter your current password": "Entrez votre mot de passe actuel",
"Enter Your Email": "Entrez votre adresse e-mail",
"Enter Your Full Name": "Entrez votre nom complet",
"Enter your message": "Entrez votre message",
"Enter your new password": "",
"Enter your new password": "Entrez votre nouveau mot de passe",
"Enter Your Password": "Entrez votre mot de passe",
"Enter Your Role": "Entrez votre rôle",
"Enter Your Username": "Entrez votre nom d'utilisateur",
"Enter your webhook URL": "",
"Enter your webhook URL": "Entrez l'URL de votre webhook",
"Error": "Erreur",
"ERROR": "ERREUR",
"Error accessing Google Drive: {{error}}": "",
"Error uploading file: {{error}}": "",
"Error accessing Google Drive: {{error}}": "Erreur d'accès à Google Drive : {{error}}",
"Error uploading file: {{error}}": "Erreur de téléversement du fichier : {{error}}",
"Evaluations": "Évaluations",
"Example: (&(objectClass=inetOrgPerson)(uid=%s))": "Exemple: (&(objectClass=inetOrgPerson)(uid=%s))",
"Example: ALL": "Exemple: TOUS",
@@ -420,7 +425,7 @@
"File not found.": "Fichier introuvable.",
"File removed successfully.": "Fichier supprimé avec succès.",
"File size should not exceed {{maxSize}} MB.": "La taille du fichier ne doit pas dépasser {{maxSize}} Mo.",
"File uploaded successfully": "",
"File uploaded successfully": "Fichier téléversé avec succès",
"Files": "Fichiers",
"Filter is now globally disabled": "Le filtre est maintenant désactivé globalement",
"Filter is now globally enabled": "Le filtre est désormais activé globalement",
@@ -458,7 +463,7 @@
"Get started with {{WEBUI_NAME}}": "Commencez avec {{WEBUI_NAME}}",
"Global": "Mondial",
"Good Response": "Bonne réponse",
"Google Drive": "",
"Google Drive": "Google Drive",
"Google PSE API Key": "Clé API Google PSE",
"Google PSE Engine Id": "ID du moteur de recherche PSE de Google",
"Group created successfully": "Groupe créé avec succès",
@@ -483,10 +488,10 @@
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "Je reconnais avoir lu et compris les implications de mes actions. Je suis conscient des risques associés à l'exécution d'un code arbitraire et j'ai vérifié la fiabilité de la source.",
"ID": "ID",
"Ignite curiosity": "Éveiller la curiosité",
"Image Compression": "",
"Image Compression": "Compression d'image",
"Image Generation (Experimental)": "Génération d'images (expérimental)",
"Image Generation Engine": "Moteur de génération d'images",
"Image Max Compression Size": "",
"Image Max Compression Size": "Taille maximale de compression d'image",
"Image Settings": "Paramètres de génération d'images",
"Images": "Images",
"Import Chats": "Importer les conversations",
@@ -507,6 +512,7 @@
"Interface": "Interface utilisateur",
"Invalid file format.": "Format de fichier non valide.",
"Invalid Tag": "Tag non valide",
"is typing...": "est en train d'écrire...",
"January": "Janvier",
"Jina API Key": "Clé API Jina",
"join our Discord for help.": "Rejoignez notre Discord pour obtenir de l'aide.",
@@ -516,7 +522,7 @@
"June": "Juin",
"JWT Expiration": "Expiration du token JWT",
"JWT Token": "Token JWT",
"Kagi Search API Key": "",
"Kagi Search API Key": "Clé API Kagi Search",
"Keep Alive": "Temps de maintien connecté",
"Key": "Clé",
"Keyboard shortcuts": "Raccourcis clavier",
@@ -531,6 +537,7 @@
"Language": "Langue",
"Last Active": "Dernière activité",
"Last Modified": "Dernière modification",
"Last reply": "",
"LDAP": "LDAP",
"LDAP server updated": "Serveur LDAP mis à jour",
"Leaderboard": "Classement",
@@ -605,9 +612,9 @@
"Name": "Nom d'utilisateur",
"Name your knowledge base": "Nommez votre base de connaissances",
"New Chat": "Nouvelle conversation",
"New folder": "",
"New Folder": "",
"New Password": "Nouveau mot de passe",
"new-channel": "",
"new-channel": "nouveau-canal",
"No content found": "Aucun contenu trouvé",
"No content to speak": "Rien à signaler",
"No distance available": "Aucune distance disponible",
@@ -630,8 +637,8 @@
"Not helpful": "Pas utile",
"Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "Note : Si vous définissez un score minimum, seuls les documents ayant un score supérieur ou égal à ce score minimum seront retournés par la recherche.",
"Notes": "Notes",
"Notification Sound": "",
"Notification Webhook": "",
"Notification Sound": "Son de notification",
"Notification Webhook": "Webhook de notification",
"Notifications": "Notifications",
"November": "Novembre",
"num_gpu (Ollama)": "num_gpu (Ollama)",
@@ -697,7 +704,7 @@
"Please carefully review the following warnings:": "Veuillez lire attentivement les avertissements suivants :",
"Please enter a prompt": "Veuillez saisir un prompt",
"Please fill in all fields.": "Veuillez remplir tous les champs.",
"Please select a model first.": "",
"Please select a model first.": "Veuillez d'abord sélectionner un modèle.",
"Please select a reason": "Veuillez sélectionner une raison",
"Port": "Port",
"Positive attitude": "Attitude positive",
@@ -713,7 +720,7 @@
"Prompt updated successfully": "Prompt mis à jour avec succès",
"Prompts": "Prompts",
"Prompts Access": "Accès aux prompts",
"Proxy URL": "",
"Proxy URL": "URL du proxy",
"Pull \"{{searchValue}}\" from Ollama.com": "Récupérer « {{searchValue}} » depuis Ollama.com",
"Pull a model from Ollama.com": "Télécharger un modèle depuis Ollama.com",
"Query Generation Prompt": "Prompt de génération de requête",
@@ -736,6 +743,7 @@
"Rename": "Renommer",
"Reorder Models": "Réorganiser les modèles",
"Repeat Last N": "Répéter les N derniers",
"Reply in Thread": "",
"Request Mode": "Mode de requête",
"Reranking Model": "Modèle de ré-ranking",
"Reranking model disabled": "Modèle de ré-ranking désactivé",
@@ -744,10 +752,11 @@
"Reset All Models": "Réinitialiser tous les modèles",
"Reset Upload Directory": "Réinitialiser le répertoire de téléchargement",
"Reset Vector Storage/Knowledge": "Réinitialiser le stockage vectoriel/connaissances",
"Reset view": "Réinitialiser la vue",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Les notifications de réponse ne peuvent pas être activées car les autorisations du site web ont été refusées. Veuillez vérifier les paramètres de votre navigateur pour accorder l'accès nécessaire.",
"Response splitting": "Fractionnement de la réponse",
"Result": "Résultat",
"Retrieval Query Generation": "",
"Retrieval Query Generation": "Génération de requête de RAG",
"Rich Text Input for Chat": "Saisie de texte enrichi pour le chat",
"RK": "Rang",
"Role": "Rôle",
@@ -781,7 +790,7 @@
"Search Tools": "Rechercher des outils",
"SearchApi API Key": "Clé API SearchApi",
"SearchApi Engine": "Moteur de recherche SearchApi",
"Searched {{count}} sites": "",
"Searched {{count}} sites": "{{count}} sites recherchés",
"Searching \"{{searchQuery}}\"": "Recherche de « {{searchQuery}} »",
"Searching Knowledge for \"{{searchQuery}}\"": "Recherche des connaissances pour « {{searchQuery}} »",
"Searxng Query URL": "URL de recherche Searxng",
@@ -849,7 +858,7 @@
"Sign up": "Inscrivez-vous",
"Sign up to {{WEBUI_NAME}}": "Inscrivez-vous à {{WEBUI_NAME}}",
"Signing in to {{WEBUI_NAME}}": "Connexion à {{WEBUI_NAME}}",
"sk-1234": "",
"sk-1234": "sk-1234",
"Source": "Source",
"Speech Playback Speed": "Vitesse de lecture de la parole",
"Speech recognition error: {{error}}": "Erreur de reconnaissance vocale\u00a0: {{error}}",
@@ -869,7 +878,7 @@
"System": "Système",
"System Instructions": "Instructions système",
"System Prompt": "Prompt système",
"Tags Generation": "",
"Tags Generation": "Génération de tags",
"Tags Generation Prompt": "Prompt de génération de tags",
"Tail free sampling is used to reduce the impact of less probable tokens from the output. A higher value (e.g., 2.0) will reduce the impact more, while a value of 1.0 disables this setting. (default: 1)": "L'échantillonnage sans queue est utilisé pour réduire l'impact des tokens moins probables dans la sortie. Une valeur plus élevée (par exemple 2.0) réduira davantage l'impact, tandis qu'une valeur de 1.0 désactive ce paramètre. (par défaut : 1)",
"Tap to interrupt": "Appuyez pour interrompre",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "Pour accéder aux modèles GGUF disponibles,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Pour accéder à l'interface Web, veuillez contacter l'administrateur. Les administrateurs peuvent gérer les statuts des utilisateurs depuis le panneau d'administration.",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "Pour attacher une base de connaissances ici, ajoutez-les d'abord à l'espace de travail « Connaissances ».",
"To learn more about available endpoints, visit our documentation.": "Pour en savoir plus sur les points de terminaison disponibles, consultez notre documentation.",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "Pour protéger votre confidentialité, seules les notes, les identifiants de modèle, les tags et les métadonnées de vos commentaires sont partagés. Vos journaux de discussion restent privés et ne sont pas inclus.",
"To select actions here, add them to the \"Functions\" workspace first.": "Pour sélectionner des actions ici, ajoutez-les d'abord à l'espace de travail « Fonctions ».",
"To select filters here, add them to the \"Functions\" workspace first.": "Pour sélectionner des filtres ici, ajoutez-les d'abord à l'espace de travail « Fonctions ». ",
@@ -954,7 +964,7 @@
"TTS Voice": "Voix de Text-to-Speech",
"Type": "Type",
"Type Hugging Face Resolve (Download) URL": "Entrez l'URL de Téléchargement Hugging Face Resolve",
"Uh-oh! There was an issue with the response.": "",
"Uh-oh! There was an issue with the response.": "Oh! Un problème est survenu avec la réponse.",
"UI": "UI",
"Unarchive All": "Désarchiver tout",
"Unarchive All Archived Chats": "Désarchiver toutes les conversations archivées",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "variable pour qu'elles soient remplacées par le contenu du presse-papiers.",
"Version": "version:",
"Version {{selectedVersion}} of {{totalVersions}}": "Version {{selectedVersion}} de {{totalVersions}}",
"View Replies": "",
"Visibility": "Visibilité",
"Voice": "Voix",
"Voice Input": "Saisie vocale",
@@ -1012,10 +1023,10 @@
"Web Loader Settings": "Paramètres du Web Loader",
"Web Search": "Recherche Web",
"Web Search Engine": "Moteur de recherche Web",
"Web Search Query Generation": "",
"Web Search Query Generation": "Génération de requête de recherche Web",
"Webhook URL": "URL du webhook",
"WebUI Settings": "Paramètres de WebUI",
"WebUI URL": "",
"WebUI URL": "URL de WebUI",
"WebUI will make requests to \"{{url}}/api/chat\"": "WebUI fera des requêtes à \"{{url}}/api/chat\"",
"WebUI will make requests to \"{{url}}/chat/completions\"": "WebUI fera des requêtes à \"{{url}}/chat/completions\"",
"What are you trying to achieve?": "Que cherchez-vous à accomplir ?",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(למשל `sh webui.sh --api`)",
"(latest)": "(האחרון)",
"{{ models }}": "{{ דגמים }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "צ'אטים של {{user}}",
"{{webUIName}} Backend Required": "נדרש Backend של {{webUIName}}",
"*Prompt node ID(s) are required for image generation": "",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "הוסף זיכרון",
"Add Model": "הוסף מודל",
"Add Reaction": "",
"Add Tag": "",
"Add Tags": "הוסף תגים",
"Add text content": "",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "",
"Allow User Location": "",
"Allow Voice Interruption in Call": "",
"Allowed Endpoints": "",
"Already have an account?": "כבר יש לך חשבון?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "כתובת URL בסיסית ל-API",
"API Key": "מפתח API",
"API Key created.": "מפתח API נוצר.",
"API Key Endpoint Restrictions": "",
"API keys": "מפתחות API",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "לחץ על כפתור תפקיד המשתמש כדי לשנות את תפקיד המשתמש.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "",
"Clone": "שיבוט",
"Clone Chat": "",
"Close": "סגור",
"Code execution": "",
"Code formatted successfully": "",
@@ -310,7 +315,7 @@
"Embedding Model": "מודל הטמעה",
"Embedding Model Engine": "מנוע מודל הטמעה",
"Embedding model set to \"{{embedding_model}}\"": "מודל ההטמעה הוגדר ל-\"{{embedding_model}}\"",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "הפיכת שיתוף קהילה לזמין",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "ממשק",
"Invalid file format.": "",
"Invalid Tag": "תג לא חוקי",
"is typing...": "",
"January": "ינואר",
"Jina API Key": "",
"join our Discord for help.": "הצטרף ל-Discord שלנו לעזרה.",
@@ -531,6 +537,7 @@
"Language": "שפה",
"Last Active": "פעיל לאחרונה",
"Last Modified": "",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "",
@@ -605,7 +612,7 @@
"Name": "שם",
"Name your knowledge base": "",
"New Chat": "צ'אט חדש",
"New folder": "",
"New Folder": "",
"New Password": "סיסמה חדשה",
"new-channel": "",
"No content found": "",
@@ -736,6 +743,7 @@
"Rename": "שנה שם",
"Reorder Models": "",
"Repeat Last N": "חזור על ה-N האחרונים",
"Reply in Thread": "",
"Request Mode": "מצב בקשה",
"Reranking Model": "מודל דירוג מחדש",
"Reranking model disabled": "מודל דירוג מחדש מושבת",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "",
"Reset Vector Storage/Knowledge": "",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
"Response splitting": "",
"Result": "",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "כדי לגשת לדגמי GGUF הזמינים להורדה,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "",
"To select actions here, add them to the \"Functions\" workspace first.": "",
"To select filters here, add them to the \"Functions\" workspace first.": "",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "משתנה להחליפו ב- clipboard תוכן.",
"Version": "גרסה",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"View Replies": "",
"Visibility": "",
"Voice": "",
"Voice Input": "",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(e.g. `sh webui.sh --api`)",
"(latest)": "(latest)",
"{{ models }}": "{{ मॉडल }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "{{user}} की चैट",
"{{webUIName}} Backend Required": "{{webUIName}} बैकएंड आवश्यक",
"*Prompt node ID(s) are required for image generation": "",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "मेमोरी जोड़ें",
"Add Model": "मॉडल जोड़ें",
"Add Reaction": "",
"Add Tag": "",
"Add Tags": "टैगों को जोड़ें",
"Add text content": "",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "",
"Allow User Location": "",
"Allow Voice Interruption in Call": "",
"Allowed Endpoints": "",
"Already have an account?": "क्या आपके पास पहले से एक खाता मौजूद है?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "एपीआई बेस यूआरएल",
"API Key": "एपीआई कुंजी",
"API Key created.": "एपीआई कुंजी बनाई गई",
"API Key Endpoint Restrictions": "",
"API keys": "एपीआई कुंजियाँ",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "उपयोगकर्ता की भूमिका बदलने के लिए उपयोगकर्ता भूमिका बटन पर क्लिक करें।",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "",
"Clone": "क्लोन",
"Clone Chat": "",
"Close": "बंद करना",
"Code execution": "",
"Code formatted successfully": "",
@@ -310,7 +315,7 @@
"Embedding Model": "मॉडेल अनुकूलन",
"Embedding Model Engine": "एंबेडिंग मॉडल इंजन",
"Embedding model set to \"{{embedding_model}}\"": "एम्बेडिंग मॉडल को \"{{embedding_model}}\" पर सेट किया गया",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "समुदाय साझाकरण सक्षम करें",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "इंटरफेस",
"Invalid file format.": "",
"Invalid Tag": "अवैध टैग",
"is typing...": "",
"January": "जनवरी",
"Jina API Key": "",
"join our Discord for help.": "मदद के लिए हमारे डिस्कोर्ड में शामिल हों।",
@@ -531,6 +537,7 @@
"Language": "भाषा",
"Last Active": "पिछली बार सक्रिय",
"Last Modified": "",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "",
@@ -605,7 +612,7 @@
"Name": "नाम",
"Name your knowledge base": "",
"New Chat": "नई चैट",
"New folder": "",
"New Folder": "",
"New Password": "नया पासवर्ड",
"new-channel": "",
"No content found": "",
@@ -736,6 +743,7 @@
"Rename": "नाम बदलें",
"Reorder Models": "",
"Repeat Last N": "अंतिम N दोहराएँ",
"Reply in Thread": "",
"Request Mode": "अनुरोध मोड",
"Reranking Model": "रीरैकिंग मोड",
"Reranking model disabled": "पुनर्रैंकिंग मॉडल अक्षम किया गया",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "",
"Reset Vector Storage/Knowledge": "",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
"Response splitting": "",
"Result": "",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "डाउनलोडिंग के लिए उपलब्ध GGUF मॉडल तक पहुँचने के लिए,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "",
"To select actions here, add them to the \"Functions\" workspace first.": "",
"To select filters here, add them to the \"Functions\" workspace first.": "",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "उन्हें क्लिपबोर्ड सामग्री से बदलने के लिए वेरिएबल।",
"Version": "संस्करण",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"View Replies": "",
"Visibility": "",
"Voice": "",
"Voice Input": "",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(npr. `sh webui.sh --api`)",
"(latest)": "(najnovije)",
"{{ models }}": "{{ modeli }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "Razgovori korisnika {{user}}",
"{{webUIName}} Backend Required": "{{webUIName}} Backend je potreban",
"*Prompt node ID(s) are required for image generation": "",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "Dodaj memoriju",
"Add Model": "Dodaj model",
"Add Reaction": "",
"Add Tag": "",
"Add Tags": "Dodaj oznake",
"Add text content": "",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "",
"Allow User Location": "",
"Allow Voice Interruption in Call": "",
"Allowed Endpoints": "",
"Already have an account?": "Već imate račun?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "Osnovni URL API-ja",
"API Key": "API ključ",
"API Key created.": "API ključ je stvoren.",
"API Key Endpoint Restrictions": "",
"API keys": "API ključevi",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "Kliknite na gumb uloge korisnika za promjenu uloge korisnika.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "",
"Clone": "Kloniraj",
"Clone Chat": "",
"Close": "Zatvori",
"Code execution": "",
"Code formatted successfully": "",
@@ -310,7 +315,7 @@
"Embedding Model": "Embedding model",
"Embedding Model Engine": "Embedding model pogon",
"Embedding model set to \"{{embedding_model}}\"": "Embedding model postavljen na \"{{embedding_model}}\"",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "Omogući zajedničko korištenje zajednice",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "Sučelje",
"Invalid file format.": "",
"Invalid Tag": "Nevažeća oznaka",
"is typing...": "",
"January": "Siječanj",
"Jina API Key": "",
"join our Discord for help.": "pridružite se našem Discordu za pomoć.",
@@ -531,6 +537,7 @@
"Language": "Jezik",
"Last Active": "Zadnja aktivnost",
"Last Modified": "",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "",
@@ -605,7 +612,7 @@
"Name": "Ime",
"Name your knowledge base": "",
"New Chat": "Novi razgovor",
"New folder": "",
"New Folder": "",
"New Password": "Nova lozinka",
"new-channel": "",
"No content found": "",
@@ -736,6 +743,7 @@
"Rename": "Preimenuj",
"Reorder Models": "",
"Repeat Last N": "Ponovi zadnjih N",
"Reply in Thread": "",
"Request Mode": "Način zahtjeva",
"Reranking Model": "Model za ponovno rangiranje",
"Reranking model disabled": "Model za ponovno rangiranje onemogućen",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "Poništi upload direktorij",
"Reset Vector Storage/Knowledge": "",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
"Response splitting": "",
"Result": "",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "Za pristup GGUF modelima dostupnim za preuzimanje,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Za pristup WebUI-u obratite se administratoru. Administratori mogu upravljati statusima korisnika s Admin panela.",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "",
"To select actions here, add them to the \"Functions\" workspace first.": "",
"To select filters here, add them to the \"Functions\" workspace first.": "",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "varijabla za zamjenu sadržajem međuspremnika.",
"Version": "Verzija",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"View Replies": "",
"Visibility": "",
"Voice": "",
"Voice Input": "",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(pl. `sh webui.sh --api`)",
"(latest)": "(legújabb)",
"{{ models }}": "{{ modellek }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "{{user}} beszélgetései",
"{{webUIName}} Backend Required": "{{webUIName}} Backend szükséges",
"*Prompt node ID(s) are required for image generation": "*Prompt node ID(k) szükségesek a képgeneráláshoz",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "Memória hozzáadása",
"Add Model": "Modell hozzáadása",
"Add Reaction": "",
"Add Tag": "Címke hozzáadása",
"Add Tags": "Címkék hozzáadása",
"Add text content": "Szöveges tartalom hozzáadása",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "Ideiglenes beszélgetés engedélyezése",
"Allow User Location": "Felhasználói helyzet engedélyezése",
"Allow Voice Interruption in Call": "Hang megszakítás engedélyezése hívás közben",
"Allowed Endpoints": "",
"Already have an account?": "Már van fiókod?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "API alap URL",
"API Key": "API kulcs",
"API Key created.": "API kulcs létrehozva.",
"API Key Endpoint Restrictions": "",
"API keys": "API kulcsok",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "Kattints a felhasználói szerep gombra a felhasználó szerepének módosításához.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Vágólap írási engedély megtagadva. Kérjük, ellenőrizd a böngésző beállításait a szükséges hozzáférés megadásához.",
"Clone": "Klónozás",
"Clone Chat": "",
"Close": "Bezárás",
"Code execution": "Kód végrehajtás",
"Code formatted successfully": "Kód sikeresen formázva",
@@ -310,7 +315,7 @@
"Embedding Model": "Beágyazási modell",
"Embedding Model Engine": "Beágyazási modell motor",
"Embedding model set to \"{{embedding_model}}\"": "Beágyazási modell beállítva: \"{{embedding_model}}\"",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "Közösségi megosztás engedélyezése",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "Felület",
"Invalid file format.": "Érvénytelen fájlformátum.",
"Invalid Tag": "Érvénytelen címke",
"is typing...": "",
"January": "Január",
"Jina API Key": "",
"join our Discord for help.": "Csatlakozz a Discord szerverünkhöz segítségért.",
@@ -531,6 +537,7 @@
"Language": "Nyelv",
"Last Active": "Utoljára aktív",
"Last Modified": "Utoljára módosítva",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "Ranglista",
@@ -605,7 +612,7 @@
"Name": "Név",
"Name your knowledge base": "",
"New Chat": "Új beszélgetés",
"New folder": "",
"New Folder": "",
"New Password": "Új jelszó",
"new-channel": "",
"No content found": "Nem található tartalom",
@@ -736,6 +743,7 @@
"Rename": "Átnevezés",
"Reorder Models": "",
"Repeat Last N": "Utolsó N ismétlése",
"Reply in Thread": "",
"Request Mode": "Kérési mód",
"Reranking Model": "Újrarangsoroló modell",
"Reranking model disabled": "Újrarangsoroló modell letiltva",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "Feltöltési könyvtár visszaállítása",
"Reset Vector Storage/Knowledge": "Vektor tárhely/tudásbázis visszaállítása",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "A válasz értesítések nem aktiválhatók, mert a weboldal engedélyei meg lettek tagadva. Kérjük, látogasson el a böngésző beállításaihoz a szükséges hozzáférés megadásához.",
"Response splitting": "Válasz felosztás",
"Result": "Eredmény",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "A letölthető GGUF modellek eléréséhez,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "A WebUI eléréséhez kérjük, forduljon az adminisztrátorhoz. Az adminisztrátorok az Admin Panelen keresztül kezelhetik a felhasználói státuszokat.",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "A tudásbázis csatolásához először adja hozzá őket a \"Knowledge\" munkaterülethez.",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "Adatai védelme érdekében a visszajelzésből csak az értékelések, modell azonosítók, címkék és metaadatok kerülnek megosztásra - a chat előzményei privátak maradnak és nem kerülnek megosztásra.",
"To select actions here, add them to the \"Functions\" workspace first.": "A műveletek kiválasztásához először adja hozzá őket a \"Functions\" munkaterülethez.",
"To select filters here, add them to the \"Functions\" workspace first.": "A szűrők kiválasztásához először adja hozzá őket a \"Functions\" munkaterülethez.",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "változó, hogy a vágólap tartalmával helyettesítse őket.",
"Version": "Verzió",
"Version {{selectedVersion}} of {{totalVersions}}": "{{selectedVersion}}. verzió a {{totalVersions}}-ból",
"View Replies": "",
"Visibility": "",
"Voice": "Hang",
"Voice Input": "Hangbevitel",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(contoh: `sh webui.sh --api`)",
"(latest)": "(terbaru)",
"{{ models }}": "{{ models }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "Obrolan {{user}}",
"{{webUIName}} Backend Required": "{{webUIName}} Diperlukan Backend",
"*Prompt node ID(s) are required for image generation": "",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "Menambahkan Memori",
"Add Model": "Tambahkan Model",
"Add Reaction": "",
"Add Tag": "",
"Add Tags": "Tambahkan Tag",
"Add text content": "",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "",
"Allow User Location": "Izinkan Lokasi Pengguna",
"Allow Voice Interruption in Call": "Izinkan Gangguan Suara dalam Panggilan",
"Allowed Endpoints": "",
"Already have an account?": "Sudah memiliki akun?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "URL Dasar API",
"API Key": "Kunci API",
"API Key created.": "Kunci API dibuat.",
"API Key Endpoint Restrictions": "",
"API keys": "Kunci API",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "Klik tombol peran pengguna untuk mengubah peran pengguna.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Izin menulis papan klip ditolak. Periksa pengaturan peramban Anda untuk memberikan akses yang diperlukan.",
"Clone": "Kloning",
"Clone Chat": "",
"Close": "Tutup",
"Code execution": "",
"Code formatted successfully": "Kode berhasil diformat",
@@ -310,7 +315,7 @@
"Embedding Model": "Model Penyematan",
"Embedding Model Engine": "Mesin Model Penyematan",
"Embedding model set to \"{{embedding_model}}\"": "Model penyematan diatur ke \"{{embedding_model}}\"",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "Aktifkan Berbagi Komunitas",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "Antarmuka",
"Invalid file format.": "",
"Invalid Tag": "Tag tidak valid",
"is typing...": "",
"January": "Januari",
"Jina API Key": "",
"join our Discord for help.": "bergabunglah dengan Discord kami untuk mendapatkan bantuan.",
@@ -531,6 +537,7 @@
"Language": "Bahasa",
"Last Active": "Terakhir Aktif",
"Last Modified": "Terakhir Dimodifikasi",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "",
@@ -605,7 +612,7 @@
"Name": "Nama",
"Name your knowledge base": "",
"New Chat": "Obrolan Baru",
"New folder": "",
"New Folder": "",
"New Password": "Kata Sandi Baru",
"new-channel": "",
"No content found": "",
@@ -736,6 +743,7 @@
"Rename": "Ganti nama",
"Reorder Models": "",
"Repeat Last N": "Ulangi N Terakhir",
"Reply in Thread": "",
"Request Mode": "Mode Permintaan",
"Reranking Model": "Model Pemeringkatan Ulang",
"Reranking model disabled": "Model pemeringkatan ulang dinonaktifkan",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "Setel Ulang Direktori Unggahan",
"Reset Vector Storage/Knowledge": "",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Notifikasi respons tidak dapat diaktifkan karena izin situs web telah ditolak. Silakan kunjungi pengaturan browser Anda untuk memberikan akses yang diperlukan.",
"Response splitting": "",
"Result": "",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "Untuk mengakses model GGUF yang tersedia untuk diunduh,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Untuk mengakses WebUI, hubungi administrator. Admin dapat mengelola status pengguna dari Panel Admin.",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "",
"To select actions here, add them to the \"Functions\" workspace first.": "",
"To select filters here, add them to the \"Functions\" workspace first.": "Untuk memilih filter di sini, tambahkan filter ke ruang kerja \"Fungsi\" terlebih dahulu.",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "variabel untuk diganti dengan konten papan klip.",
"Version": "Versi",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"View Replies": "",
"Visibility": "",
"Voice": "Suara",
"Voice Input": "",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(m.sh. `sh webui.sh --api`)",
"(latest)": "(is déanaí)",
"{{ models }}": "{{models}}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "Comhráite {{user}}",
"{{webUIName}} Backend Required": "{{webUIName}} Ceoldeireadh Riachtanach",
"*Prompt node ID(s) are required for image generation": "* Tá ID nód pras ag teastáil chun íomhá a ghiniúint",
@@ -34,6 +35,7 @@
"Add Group": "Cuir Grúpa leis",
"Add Memory": "Cuir Cuimhne",
"Add Model": "Cuir múnla leis",
"Add Reaction": "",
"Add Tag": "Cuir Clib leis",
"Add Tags": "Cuir Clibeanna leis",
"Add text content": "Cuir ábhar téacs leis",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "Cead Comhrá Sealadach",
"Allow User Location": "Ceadaigh Suíomh Úsáideora",
"Allow Voice Interruption in Call": "Ceadaigh Briseadh Guth i nGlao",
"Allowed Endpoints": "",
"Already have an account?": "Tá cuntas agat cheana féin?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "Rogha eile seachas an top_p, agus tá sé mar aidhm aige cothromaíocht cáilíochta agus éagsúlachta a chinntiú. Léiríonn an paraiméadar p an dóchúlacht íosta go mbreithneofar comhartha, i gcoibhneas le dóchúlacht an chomhartha is dóichí. Mar shampla, le p=0.05 agus dóchúlacht 0.9 ag an comhartha is dóichí, déantar logits le luach níos lú ná 0.045 a scagadh amach. (Réamhshocrú: 0.0)",
"Amazing": "Iontach",
@@ -67,6 +70,7 @@
"API Base URL": "URL Bonn API",
"API Key": "Eochair API",
"API Key created.": "Cruthaíodh Eochair API.",
"API Key Endpoint Restrictions": "",
"API keys": "Eochracha API",
"Application DN": "Feidhmchlár DN",
"Application DN Password": "Feidhmchlár DN Pasfhocal",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "Cliceáil ar an gcnaipe ról úsáideora chun ról úsáideora a athrú.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Diúltaíodh cead scríofa an ghearrthaisce. Seiceáil socruithe do bhrabhsálaí chun an rochtain riachtanach a dheonú.",
"Clone": "Clón",
"Clone Chat": "",
"Close": "Dún",
"Code execution": "Cód a fhorghníomhú",
"Code formatted successfully": "Cód formáidithe go rathúil",
@@ -310,7 +315,7 @@
"Embedding Model": "Múnla Leabháilte",
"Embedding Model Engine": "Inneall Múnla Ionchorprú",
"Embedding model set to \"{{embedding_model}}\"": "Samhail leabaithe atá socraithe go \"{{embedding_model}}\"",
"Enable API Key Auth": "Cumasaigh Fíordheimhniú Eochracha API",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "Cumasaigh Comhroinnt Pobail",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "Comhéadan",
"Invalid file format.": "Formáid comhaid neamhbhailí.",
"Invalid Tag": "Clib neamhbhailí",
"is typing...": "",
"January": "Eanáir",
"Jina API Key": "Jina API Eochair",
"join our Discord for help.": "bí inár Discord chun cabhair a fháil.",
@@ -531,6 +537,7 @@
"Language": "Teanga",
"Last Active": "Gníomhach Deiridh",
"Last Modified": "Athraithe Deiridh",
"Last reply": "",
"LDAP": "LDAP",
"LDAP server updated": "Nuashonraíodh freastalaí LDAP",
"Leaderboard": "An Clár Ceannairí",
@@ -605,7 +612,7 @@
"Name": "Ainm",
"Name your knowledge base": "Cuir ainm ar do bhunachar eolais",
"New Chat": "Comhrá Nua",
"New folder": "",
"New Folder": "",
"New Password": "Pasfhocal Nua",
"new-channel": "",
"No content found": "Níor aimsíodh aon ábhar",
@@ -736,6 +743,7 @@
"Rename": "Athainmnigh",
"Reorder Models": "",
"Repeat Last N": "Déan an N deireanach arís",
"Reply in Thread": "",
"Request Mode": "Mód Iarratais",
"Reranking Model": "Múnla Athrangú",
"Reranking model disabled": "Samhail athrangú faoi mhíchumas",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "Athshocraigh Eolaire Uas",
"Reset Vector Storage/Knowledge": "Athshocraigh Stóráil/Eolas Veicteoir",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Ní féidir fógraí freagartha a ghníomhachtú toisc gur diúltaíodh ceadanna an tsuímh Ghréasáin. Tabhair cuairt ar do shocruithe brabhsálaí chun an rochtain riachtanach a dheonú.",
"Response splitting": "Scoilt freagartha",
"Result": "Toradh",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "Chun rochtain a fháil ar na múnlaí GGUF atá ar fáil le híoslódáil,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Chun rochtain a fháil ar an WebUI, déan teagmháil leis an riarthóir le do thoil. Is féidir le riarthóirí stádas úsáideora a bhainistiú ón bPainéal Riaracháin.",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "Chun an bonn eolais a cheangal anseo, cuir leis an spás oibre \"Eolas\" iad ar dtús.",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "Chun do phríobháideachas a chosaint, ní roinntear ach rátálacha, aitheantais mhúnla, clibeanna agus meiteashonraí ó daiseolas - fanann do logaí comhrá príobháideach agus níl siad san áireamh.",
"To select actions here, add them to the \"Functions\" workspace first.": "Chun gníomhartha a roghnú anseo, cuir iad leis an spás oibre \"Feidhmeanna\" ar dtús.",
"To select filters here, add them to the \"Functions\" workspace first.": "Chun scagairí a roghnú anseo, cuir iad leis an spás oibre \"Feidhmeanna\" ar dtús.",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "athróg chun ábhar gearrthaisce a chur in ionad iad.",
"Version": "Leagan",
"Version {{selectedVersion}} of {{totalVersions}}": "Leagan {{selectedVersion}} de {{totalVersions}}",
"View Replies": "",
"Visibility": "Infheictheacht",
"Voice": "Guth",
"Voice Input": "Ionchur Gutha",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(p.e. `sh webui.sh --api`)",
"(latest)": "(ultima)",
"{{ models }}": "{{ modelli }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "{{user}} Chat",
"{{webUIName}} Backend Required": "{{webUIName}} Backend richiesto",
"*Prompt node ID(s) are required for image generation": "",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "Aggiungi memoria",
"Add Model": "Aggiungi modello",
"Add Reaction": "",
"Add Tag": "",
"Add Tags": "Aggiungi tag",
"Add text content": "",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "",
"Allow User Location": "",
"Allow Voice Interruption in Call": "",
"Allowed Endpoints": "",
"Already have an account?": "Hai già un account?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "URL base API",
"API Key": "Chiave API",
"API Key created.": "Chiave API creata.",
"API Key Endpoint Restrictions": "",
"API keys": "Chiavi API",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "Clicca sul pulsante del ruolo utente per modificare il ruolo di un utente.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "",
"Clone": "Clone",
"Clone Chat": "",
"Close": "Chiudi",
"Code execution": "",
"Code formatted successfully": "",
@@ -310,7 +315,7 @@
"Embedding Model": "Modello di embedding",
"Embedding Model Engine": "Motore del modello di embedding",
"Embedding model set to \"{{embedding_model}}\"": "Modello di embedding impostato su \"{{embedding_model}}\"",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "Abilita la condivisione della community",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "Interfaccia",
"Invalid file format.": "",
"Invalid Tag": "Tag non valido",
"is typing...": "",
"January": "Gennaio",
"Jina API Key": "",
"join our Discord for help.": "unisciti al nostro Discord per ricevere aiuto.",
@@ -531,6 +537,7 @@
"Language": "Lingua",
"Last Active": "Ultima attività",
"Last Modified": "",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "",
@@ -605,7 +612,7 @@
"Name": "Nome",
"Name your knowledge base": "",
"New Chat": "Nuova chat",
"New folder": "",
"New Folder": "",
"New Password": "Nuova password",
"new-channel": "",
"No content found": "",
@@ -736,6 +743,7 @@
"Rename": "Rinomina",
"Reorder Models": "",
"Repeat Last N": "Ripeti ultimi N",
"Reply in Thread": "",
"Request Mode": "Modalità richiesta",
"Reranking Model": "Modello di riclassificazione",
"Reranking model disabled": "Modello di riclassificazione disabilitato",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "",
"Reset Vector Storage/Knowledge": "",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
"Response splitting": "",
"Result": "",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "Per accedere ai modelli GGUF disponibili per il download,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "",
"To select actions here, add them to the \"Functions\" workspace first.": "",
"To select filters here, add them to the \"Functions\" workspace first.": "",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "variabile per farli sostituire con il contenuto degli appunti.",
"Version": "Versione",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"View Replies": "",
"Visibility": "",
"Voice": "",
"Voice Input": "",
+30 -19
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(例: `sh webui.sh --api`)",
"(latest)": "(最新)",
"{{ models }}": "{{ モデル }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "{{user}} のチャット",
"{{webUIName}} Backend Required": "{{webUIName}} バックエンドが必要です",
"*Prompt node ID(s) are required for image generation": "",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "メモリを追加",
"Add Model": "モデルを追加",
"Add Reaction": "",
"Add Tag": "タグを追加",
"Add Tags": "タグを追加",
"Add text content": "コンテンツを追加",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "一時的なチャットを許可",
"Allow User Location": "ユーザーロケーションの許可",
"Allow Voice Interruption in Call": "通話中に音声の割り込みを許可",
"Allowed Endpoints": "",
"Already have an account?": "すでにアカウントをお持ちですか?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "API ベース URL",
"API Key": "API キー",
"API Key created.": "API キーが作成されました。",
"API Key Endpoint Restrictions": "",
"API keys": "API キー",
"Application DN": "",
"Application DN Password": "",
@@ -136,7 +140,7 @@
"Chat direction": "チャットの方向",
"Chat Overview": "チャット概要",
"Chat Permissions": "",
"Chat Tags Auto-Generation": "",
"Chat Tags Auto-Generation": "チャットタグの自動生成",
"Chats": "チャット",
"Check Again": "再確認",
"Check for updates": "アップデートを確認",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "ユーザーの役割を変更するには、ユーザー役割ボタンをクリックしてください。",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "クリップボードへの書き込み許可がありません。ブラウザ設定を確認し許可してください。",
"Clone": "クローン",
"Clone Chat": "",
"Close": "閉じる",
"Code execution": "",
"Code formatted successfully": "コードフォーマットに成功しました",
@@ -179,7 +184,7 @@
"Configure": "",
"Configure Models": "",
"Confirm": "確認",
"Confirm Password": "パスワード確認",
"Confirm Password": "パスワード確認",
"Confirm your action": "あなたのアクションの確認",
"Confirm your new password": "",
"Connections": "接続",
@@ -210,7 +215,7 @@
"Create Admin Account": "",
"Create Channel": "",
"Create Group": "",
"Create Knowledge": "知識データ作成",
"Create Knowledge": "ナレッジベース作成",
"Create new key": "新しいキーを作成",
"Create new secret key": "新しいシークレットキーを作成",
"Created at": "作成日時",
@@ -310,10 +315,10 @@
"Embedding Model": "埋め込みモデル",
"Embedding Model Engine": "埋め込みモデルエンジン",
"Embedding model set to \"{{embedding_model}}\"": "埋め込みモデルを\"{{embedding_model}}\"に設定しました",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "コミュニティ共有を有効にする",
"Enable Google Drive": "",
"Enable Google Drive": "Google Driveの有効化",
"Enable Memory Locking (mlock) to prevent model data from being swapped out of RAM. This option locks the model's working set of pages into RAM, ensuring that they will not be swapped out to disk. This can help maintain performance by avoiding page faults and ensuring fast data access.": "",
"Enable Memory Mapping (mmap) to load model data. This option allows the system to use disk storage as an extension of RAM by treating disk files as if they were in RAM. This can improve model performance by allowing for faster data access. However, it may not work correctly with all systems and can consume a significant amount of disk space.": "",
"Enable Message Rating": "メッセージ評価を有効にする",
@@ -507,6 +512,7 @@
"Interface": "インターフェース",
"Invalid file format.": "",
"Invalid Tag": "無効なタグ",
"is typing...": "",
"January": "1月",
"Jina API Key": "",
"join our Discord for help.": "ヘルプについては、Discord に参加してください。",
@@ -520,17 +526,18 @@
"Keep Alive": "キープアライブ",
"Key": "",
"Keyboard shortcuts": "キーボードショートカット",
"Knowledge": "知識",
"Knowledge": "ナレッジベース",
"Knowledge Access": "",
"Knowledge created successfully.": "知識の作成に成功しました",
"Knowledge deleted successfully.": "知識の削除に成功しました",
"Knowledge reset successfully.": "知識のリセットに成功しました",
"Knowledge updated successfully": "知識のアップデートに成功しました",
"Knowledge created successfully.": "ナレッジベースの作成に成功しました",
"Knowledge deleted successfully.": "ナレッジベースの削除に成功しました",
"Knowledge reset successfully.": "ナレッジベースのリセットに成功しました",
"Knowledge updated successfully": "ナレッジベースのアップデートに成功しました",
"Label": "",
"Landing Page Mode": "ランディングページモード",
"Language": "言語",
"Last Active": "最終アクティブ",
"Last Modified": "",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "",
@@ -605,7 +612,7 @@
"Name": "名前",
"Name your knowledge base": "",
"New Chat": "新しいチャット",
"New folder": "",
"New Folder": "",
"New Password": "新しいパスワード",
"new-channel": "",
"No content found": "",
@@ -616,7 +623,7 @@
"No files found.": "",
"No groups with access, add a group to grant access": "",
"No HTML, CSS, or JavaScript content found.": "",
"No knowledge found": "知識が見つかりません",
"No knowledge found": "ナレッジベースが見つかりません",
"No model IDs": "",
"No models found": "",
"No models selected": "",
@@ -630,7 +637,7 @@
"Not helpful": "",
"Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "注意:最小スコアを設定した場合、検索は最小スコア以上のスコアを持つドキュメントのみを返します。",
"Notes": "",
"Notification Sound": "",
"Notification Sound": "通知音",
"Notification Webhook": "",
"Notifications": "デスクトップ通知",
"November": "11月",
@@ -736,6 +743,7 @@
"Rename": "名前を変更",
"Reorder Models": "",
"Repeat Last N": "最後の N を繰り返す",
"Reply in Thread": "",
"Request Mode": "リクエストモード",
"Reranking Model": "モデルの再ランキング",
"Reranking model disabled": "再ランキングモデルが無効です",
@@ -743,7 +751,8 @@
"Reset": "",
"Reset All Models": "",
"Reset Upload Directory": "アップロードディレクトリをリセット",
"Reset Vector Storage/Knowledge": "",
"Reset Vector Storage/Knowledge": "ベクターストレージとナレッジべーうをリセット",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
"Response splitting": "応答の分割",
"Result": "",
@@ -772,7 +781,7 @@
"Search Filters": "",
"search for tags": "",
"Search Functions": "Functionの検索",
"Search Knowledge": "知識の検索",
"Search Knowledge": "ナレッジベースの検索",
"Search Models": "モデル検索",
"Search options": "",
"Search Prompts": "プロンプトを検索",
@@ -797,7 +806,7 @@
"Select a pipeline url": "パイプラインの URL を選択する",
"Select a tool": "ツールの選択",
"Select Engine": "エンジンの選択",
"Select Knowledge": "知識の選択",
"Select Knowledge": "ナレッジベースの選択",
"Select model": "モデルを選択",
"Select only one model to call": "",
"Selected model(s) do not support image inputs": "一部のモデルは画像入力をサポートしていません",
@@ -851,7 +860,7 @@
"Signing in to {{WEBUI_NAME}}": "",
"sk-1234": "",
"Source": "ソース",
"Speech Playback Speed": "",
"Speech Playback Speed": "音声の再生速度",
"Speech recognition error: {{error}}": "音声認識エラー: {{error}}",
"Speech-to-Text Engine": "音声テキスト変換エンジン",
"Stop": "",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "ダウンロード可能な GGUF モデルにアクセスするには、",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "",
"To select actions here, add them to the \"Functions\" workspace first.": "",
"To select filters here, add them to the \"Functions\" workspace first.": "",
@@ -940,7 +950,7 @@
"Tool imported successfully": "",
"Tool Name": "",
"Tool updated successfully": "",
"Tools": "",
"Tools": "ツール",
"Tools Access": "",
"Tools are a function calling system with arbitrary code execution": "",
"Tools have a function calling system that allows arbitrary code execution": "",
@@ -979,7 +989,7 @@
"Upload Progress": "アップロードの進行状況",
"URL": "",
"URL Mode": "URL モード",
"Use '#' in the prompt input to load and include your knowledge.": "#を入力すると知識データを参照することが出来ます。",
"Use '#' in the prompt input to load and include your knowledge.": "#を入力するとナレッジベースを参照することが出来ます。",
"Use Gravatar": "Gravatar を使用する",
"Use groups to group your users and assign permissions.": "",
"Use Initials": "初期値を使用する",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "クリップボードの内容に置き換える変数。",
"Version": "バージョン",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"View Replies": "",
"Visibility": "",
"Voice": "ボイス",
"Voice Input": "",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(მაგ. `sh webui.sh --api`)",
"(latest)": "(უახლესი)",
"{{ models }}": "{{ models }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "{{user}}-ის ჩათები",
"{{webUIName}} Backend Required": "{{webUIName}} საჭიროა ბექენდი",
"*Prompt node ID(s) are required for image generation": "",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "მემორიის დამატება",
"Add Model": "მოდელის დამატება",
"Add Reaction": "",
"Add Tag": "",
"Add Tags": "ტეგების დამატება",
"Add text content": "",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "",
"Allow User Location": "",
"Allow Voice Interruption in Call": "",
"Allowed Endpoints": "",
"Already have an account?": "უკვე გაქვს ანგარიში?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "API საბაზისო URL",
"API Key": "API გასაღები",
"API Key created.": "API გასაღები შექმნილია.",
"API Key Endpoint Restrictions": "",
"API keys": "API გასაღები",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "დააკლიკეთ მომხმარებლის როლის ღილაკს რომ შეცვალოთ მომხმარების როლი",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "",
"Clone": "კლონი",
"Clone Chat": "",
"Close": "დახურვა",
"Code execution": "",
"Code formatted successfully": "",
@@ -310,7 +315,7 @@
"Embedding Model": "ჩასმის ძირითადი პროგრამა",
"Embedding Model Engine": "ჩასმის ძირითადი პროგრამა",
"Embedding model set to \"{{embedding_model}}\"": "ჩასმის ძირითადი პროგრამა ჩართულია \"{{embedding_model}}\"",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "საზოგადოების გაზიარების ჩართვა",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "ინტერფეისი",
"Invalid file format.": "",
"Invalid Tag": "არასწორი ტეგი",
"is typing...": "",
"January": "იანვარი",
"Jina API Key": "",
"join our Discord for help.": "შეუერთდით ჩვენს Discord-ს დახმარებისთვის",
@@ -531,6 +537,7 @@
"Language": "ენა",
"Last Active": "ბოლო აქტიური",
"Last Modified": "",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "",
@@ -605,7 +612,7 @@
"Name": "სახელი",
"Name your knowledge base": "",
"New Chat": "ახალი მიმოწერა",
"New folder": "",
"New Folder": "",
"New Password": "ახალი პაროლი",
"new-channel": "",
"No content found": "",
@@ -736,6 +743,7 @@
"Rename": "პოპულარობის რაოდენობა",
"Reorder Models": "",
"Repeat Last N": "გაიმეორეთ ბოლო N",
"Reply in Thread": "",
"Request Mode": "მოთხოვნის რეჟიმი",
"Reranking Model": "რექვექტირება",
"Reranking model disabled": "რექვექტირება არაა ჩართული",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "",
"Reset Vector Storage/Knowledge": "",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "",
"Response splitting": "",
"Result": "",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "ჩასატვირთად ხელმისაწვდომი GGUF მოდელებზე წვდომისთვის",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "",
"To select actions here, add them to the \"Functions\" workspace first.": "",
"To select filters here, add them to the \"Functions\" workspace first.": "",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "ცვლადი, რომ შეცვალოს ისინი ბუფერში შიგთავსით.",
"Version": "ვერსია",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"View Replies": "",
"Visibility": "",
"Voice": "",
"Voice Input": "",
+13 -2
View File
@@ -5,6 +5,7 @@
"(e.g. `sh webui.sh --api`)": "(예: `sh webui.sh --api`)",
"(latest)": "(최근)",
"{{ models }}": "{{ models }}",
"{{COUNT}} Replies": "",
"{{user}}'s Chats": "{{user}}의 채팅",
"{{webUIName}} Backend Required": "{{webUIName}} 백엔드가 필요합니다.",
"*Prompt node ID(s) are required for image generation": "사진 생성을 위해 프롬포트 노드 ID가 필요합니다",
@@ -34,6 +35,7 @@
"Add Group": "",
"Add Memory": "메모리 추가",
"Add Model": "모델 추가",
"Add Reaction": "",
"Add Tag": "태그 추가",
"Add Tags": "태그 추가",
"Add text content": "글 추가",
@@ -57,6 +59,7 @@
"Allow Temporary Chat": "임시 채팅 허용",
"Allow User Location": "사용자 위치 활용 허용",
"Allow Voice Interruption in Call": "음성 기능에서 음성 방해 허용",
"Allowed Endpoints": "",
"Already have an account?": "이미 계정이 있으신가요?",
"Alternative to the top_p, and aims to ensure a balance of quality and variety. The parameter p represents the minimum probability for a token to be considered, relative to the probability of the most likely token. For example, with p=0.05 and the most likely token having a probability of 0.9, logits with a value less than 0.045 are filtered out. (Default: 0.0)": "",
"Amazing": "",
@@ -67,6 +70,7 @@
"API Base URL": "API 기본 URL",
"API Key": "API 키",
"API Key created.": "API 키가 생성되었습니다.",
"API Key Endpoint Restrictions": "",
"API keys": "API 키",
"Application DN": "",
"Application DN Password": "",
@@ -162,6 +166,7 @@
"Click on the user role button to change a user's role.": "사용자 역할 버튼을 클릭하여 사용자의 역할을 변경하세요.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "클립보드 사용 권한이 거절되었습니다. 필요한 접근을 사용하기 위해 브라우져 설정을 확인 부탁드립니다.",
"Clone": "복제",
"Clone Chat": "",
"Close": "닫기",
"Code execution": "코드 실행",
"Code formatted successfully": "성공적으로 코드가 생성되었습니다",
@@ -310,7 +315,7 @@
"Embedding Model": "임베딩 모델",
"Embedding Model Engine": "임베딩 모델 엔진",
"Embedding model set to \"{{embedding_model}}\"": "임베딩 모델을 \"{{embedding_model}}\"로 설정함",
"Enable API Key Auth": "",
"Enable API Key": "",
"Enable autocomplete generation for chat messages": "",
"Enable Community Sharing": "커뮤니티 공유 활성화",
"Enable Google Drive": "",
@@ -507,6 +512,7 @@
"Interface": "인터페이스",
"Invalid file format.": "잘못된 파일 형식",
"Invalid Tag": "잘못된 태그",
"is typing...": "",
"January": "1월",
"Jina API Key": "",
"join our Discord for help.": "도움말을 보려면 Discord에 가입하세요.",
@@ -531,6 +537,7 @@
"Language": "언어",
"Last Active": "최근 활동",
"Last Modified": "마지막 수정",
"Last reply": "",
"LDAP": "",
"LDAP server updated": "",
"Leaderboard": "리더보드",
@@ -605,7 +612,7 @@
"Name": "이름",
"Name your knowledge base": "",
"New Chat": "새 채팅",
"New folder": "",
"New Folder": "",
"New Password": "새 비밀번호",
"new-channel": "",
"No content found": "내용을 찾을 수 없음",
@@ -736,6 +743,7 @@
"Rename": "이름 변경",
"Reorder Models": "",
"Repeat Last N": "마지막 N 반복",
"Reply in Thread": "",
"Request Mode": "요청 모드",
"Reranking Model": "Reranking 모델",
"Reranking model disabled": "Reranking 모델 비활성화",
@@ -744,6 +752,7 @@
"Reset All Models": "",
"Reset Upload Directory": "업로드 디렉토리 초기화",
"Reset Vector Storage/Knowledge": "벡터 저장 공간/지식 기반 초기화",
"Reset view": "",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "웹사이트 권환과 같이 응답 알림이 활성화될 수 없습니다. 필요한 접근을 사용하기 위해 브라우져 설정을 확인 부탁드립니다.",
"Response splitting": "응답 나누기",
"Result": "결과",
@@ -922,6 +931,7 @@
"To access the GGUF models available for downloading,": "다운로드 가능한 GGUF 모델을 확인하려면,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "WebUI에 접속하려면 관리자에게 문의하십시오. 관리자는 관리자 패널에서 사용자 상태를 관리할 수 있습니다.",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "지식 기반을 여기에 첨부하려면. \"지식 기반\" 워크스페이스에 먼저 추가하세요",
"To learn more about available endpoints, visit our documentation.": "",
"To protect your privacy, only ratings, model IDs, tags, and metadata are shared from your feedback—your chat logs remain private and are not included.": "개인정보를 보호하기 위해, 당신의 채팅 로그는 비공개로 유지되고, 오직 당신의 피드백에서 평가, 모델 ID, 태그, 그리고 메타데이타만 공유됩니다",
"To select actions here, add them to the \"Functions\" workspace first.": "여기서 행동을 선택하려면, \"함수\" 워크스페이스에 먼저 추가하세요",
"To select filters here, add them to the \"Functions\" workspace first.": "여기서 필터를 선택하려면, \"함수\" 워크스페이스에 먼저 추가하세요",
@@ -1000,6 +1010,7 @@
"variable to have them replaced with clipboard content.": "변수를 사용하여 클립보드 내용으로 바꾸세요.",
"Version": "버전",
"Version {{selectedVersion}} of {{totalVersions}}": "버전 {{totalVersions}}의 {{selectedVersion}}",
"View Replies": "",
"Visibility": "",
"Voice": "음성",
"Voice Input": "음성 입력",

Some files were not shown because too many files have changed in this diff Show More