Compare commits

...

328 Commits

Author SHA1 Message Date
arvinxx 5fb46399d2 fix RCE 2026-01-04 10:23:46 +08:00
LobeHub Bot fdadef2f98 🤖 style: update i18n (#11145)
💄 style: update i18n

Co-authored-by: canisminor1990 <17870709+canisminor1990@users.noreply.github.com>
2026-01-04 10:22:24 +08:00
lobehubbot 234c6a10b7 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-03 16:35:52 +00:00
semantic-release-bot d498d06031 🔖 chore(release): v2.0.0-next.202 [skip ci]
## [Version&nbsp;2.0.0-next.202](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.201...v2.0.0-next.202)
<sup>Released on **2026-01-03**</sup>

#### ♻ Code Refactoring

- **misc**: Refactor and fix model runtime initialize.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### Code refactoring

* **misc**: Refactor and fix model runtime initialize, closes [#11134](https://github.com/lobehub/lobe-chat/issues/11134) ([8078cb9](https://github.com/lobehub/lobe-chat/commit/8078cb9))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-03 16:34:26 +00:00
Arvin Xu 8078cb9778 ♻️ refactor: refactor and fix model runtime initialize (#11134)
* ♻️ refactor: refactor and fix model runtime initialize

* fix test for model runtime

* improve loading style

* fix tests

* fix error mode

* fix error display issue

* improve style

* try to fix issue

* improve style

* improve task Inspector style

* update i18n

* fix task error state

* update i18n

* fix error result

* fix error
2026-01-04 00:16:43 +08:00
lobehubbot cc96d5a47a 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-03 15:42:12 +00:00
semantic-release-bot 2bcee32064 🔖 chore(release): v2.0.0-next.201 [skip ci]
## [Version&nbsp;2.0.0-next.201](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.200...v2.0.0-next.201)
<sup>Released on **2026-01-03**</sup>

#### 🐛 Bug Fixes

- **misc**: Restore window resizable before hard reload in desktop onboarding.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **misc**: Restore window resizable before hard reload in desktop onboarding, closes [#11144](https://github.com/lobehub/lobe-chat/issues/11144) ([2516874](https://github.com/lobehub/lobe-chat/commit/2516874))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-03 15:40:42 +00:00
Innei 25168745c9 🐛 fix: restore window resizable before hard reload in desktop onboarding (#11144)
在桌面 onboarding 完成后的硬重载之前,先恢复窗口的可调整大小状态,
确保应用重新启动时窗口可以正常调整大小。

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-01-03 23:18:59 +08:00
sxjeru 9c43353dcd 🔨 chore: Update build:vercel script to include postbuild (#11140)
Update build:vercel script to include postbuild
2026-01-03 22:07:31 +08:00
lobehubbot 8e3eb15a38 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-03 08:49:05 +00:00
semantic-release-bot 44065cdb54 🔖 chore(release): v2.0.0-next.200 [skip ci]
## [Version&nbsp;2.0.0-next.200](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.199...v2.0.0-next.200)
<sup>Released on **2026-01-03**</sup>

####  Features

- **misc**: Add work path for local system.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's improved

* **misc**: Add work path for local system, closes [#11128](https://github.com/lobehub/lobe-chat/issues/11128) ([d8deadd](https://github.com/lobehub/lobe-chat/commit/d8deadd))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-03 08:47:38 +00:00
LobeHub Bot dd6dd8cac4 test: add unit tests for genOG utilities (#11005)
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-03 16:29:26 +08:00
Arvin Xu d8deaddedd feat: add work path for local system (#11128)
*  feat: support to show working dir

* fix style

* update docs

* update topic

* refactor to use chat config

* inject working Directory

* update i18n

* fix tests
2026-01-03 16:22:22 +08:00
lobehubbot 7f3226d625 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-03 08:18:46 +00:00
semantic-release-bot 66fa060fb3 🔖 chore(release): v2.0.0-next.199 [skip ci]
## [Version&nbsp;2.0.0-next.199](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.198...v2.0.0-next.199)
<sup>Released on **2026-01-03**</sup>

#### 🐛 Bug Fixes

- **misc**: Filter empty assistant messages for Anthropic API.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **misc**: Filter empty assistant messages for Anthropic API, closes [#11129](https://github.com/lobehub/lobe-chat/issues/11129) ([7af750b](https://github.com/lobehub/lobe-chat/commit/7af750b))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-03 08:17:14 +00:00
Arvin Xu 7af750beeb 🐛 fix: filter empty assistant messages for Anthropic API (#11129)
fix anthropic empty error
2026-01-03 15:59:05 +08:00
lobehubbot 371e6449e1 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-03 07:14:01 +00:00
semantic-release-bot bbe51763b7 🔖 chore(release): v2.0.0-next.198 [skip ci]
## [Version&nbsp;2.0.0-next.198](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.197...v2.0.0-next.198)
<sup>Released on **2026-01-03**</sup>

#### 🐛 Bug Fixes

- **misc**: Support thoughtSignature for openrouter.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **misc**: Support thoughtSignature for openrouter, closes [#11117](https://github.com/lobehub/lobe-chat/issues/11117) ([bf5d41e](https://github.com/lobehub/lobe-chat/commit/bf5d41e))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-03 07:12:31 +00:00
wangxiaolei bf5d41e1a7 🐛 fix: support thoughtSignature for openrouter (#11117)
feat: support thoughtSignature for openrouter
2026-01-03 14:53:50 +08:00
lobehubbot 8e0e5020db 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-03 06:21:36 +00:00
semantic-release-bot c0c834e22a 🔖 chore(release): v2.0.0-next.197 [skip ci]
## [Version&nbsp;2.0.0-next.197](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.196...v2.0.0-next.197)
<sup>Released on **2026-01-03**</sup>

#### ♻ Code Refactoring

- **misc**: Remove client db and refactor test.

#### 🐛 Bug Fixes

- **misc**: Fix file upload issue.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### Code refactoring

* **misc**: Remove client db and refactor test, closes [#11123](https://github.com/lobehub/lobe-chat/issues/11123) ([bb2799d](https://github.com/lobehub/lobe-chat/commit/bb2799d))

#### What's fixed

* **misc**: Fix file upload issue, closes [#11122](https://github.com/lobehub/lobe-chat/issues/11122) ([1ae327a](https://github.com/lobehub/lobe-chat/commit/1ae327a))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-03 06:20:01 +00:00
Arvin Xu bb2799dc75 ♻️ refactor: remove client db and refactor test (#11123)
* ♻️ refactor: refactor to remove client db

* remove tableViewer

*  tests: remove tests
2026-01-03 13:59:45 +08:00
bbbugg bc44cba10a 🐛fix: add support for built-in model search in TokenTag component (#11114)
* fix: add support for built-in model search in TokenTag component

* fix: improve layout handling in List component for better overflow management
2026-01-03 13:56:17 +08:00
Arvin Xu 1ae327ab53 🐛 fix: fix file upload issue (#11122)
* fix upload

*  tests: fix upload
2026-01-03 13:55:19 +08:00
lobehubbot f737afacc7 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-03 04:45:55 +00:00
semantic-release-bot c8710d7585 🔖 chore(release): v2.0.0-next.196 [skip ci]
## [Version&nbsp;2.0.0-next.196](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.195...v2.0.0-next.196)
<sup>Released on **2026-01-03**</sup>

#### ♻ Code Refactoring

- **misc**: Refactor to remove access code.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### Code refactoring

* **misc**: Refactor to remove access code, closes [#11120](https://github.com/lobehub/lobe-chat/issues/11120) ([0e9f98c](https://github.com/lobehub/lobe-chat/commit/0e9f98c))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-03 04:44:30 +00:00
Arvin Xu 0e9f98cacb ♻️ refactor: refactor to remove access code (#11120) 2026-01-03 12:26:02 +08:00
lobehubbot d5cde9fbbf 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-03 04:13:53 +00:00
semantic-release-bot ff0c3c4364 🔖 chore(release): v2.0.0-next.195 [skip ci]
## [Version&nbsp;2.0.0-next.195](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.194...v2.0.0-next.195)
<sup>Released on **2026-01-03**</sup>

#### 🐛 Bug Fixes

- **misc**: Fix tool call message content missing.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **misc**: Fix tool call message content missing, closes [#11116](https://github.com/lobehub/lobe-chat/issues/11116) ([885964e](https://github.com/lobehub/lobe-chat/commit/885964e))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-03 04:12:25 +00:00
Arvin Xu 885964e1bc 🐛 fix: fix tool call message content missing (#11116)
* implement telemetry middleware

* refactor mcp http call tool telemetry

* refactor cloud call tool telemetry

* 🐛 fix: fix call tool telemetry

* 🐛 fix: fix call tool issue

*  tests: add tests

*  tests: add tests

*  tests: improve tests

* 🔥 chore: remove files

* fix tests

* fix tests
2026-01-03 11:54:29 +08:00
LobeHub Bot 553a369673 🌐 chore: translate non-English comments to English in zhipu provider (#11119)
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-03 10:56:19 +08:00
lobehubbot 821a14c712 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-03 02:18:05 +00:00
semantic-release-bot c552327d70 🔖 chore(release): v2.0.0-next.194 [skip ci]
## [Version&nbsp;2.0.0-next.194](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.193...v2.0.0-next.194)
<sup>Released on **2026-01-03**</sup>

#### 💄 Styles

- **misc**: Update i18n.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### Styles

* **misc**: Update i18n, closes [#11115](https://github.com/lobehub/lobe-chat/issues/11115) ([072e0dd](https://github.com/lobehub/lobe-chat/commit/072e0dd))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-03 02:16:45 +00:00
LobeHub Bot 072e0ddd88 🤖 style: update i18n (#11115)
💄 style: update i18n

Co-authored-by: canisminor1990 <17870709+canisminor1990@users.noreply.github.com>
2026-01-03 09:57:40 +08:00
lobehubbot e2ad5a683c 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-02 13:22:29 +00:00
semantic-release-bot eeda4f90af 🔖 chore(release): v2.0.0-next.193 [skip ci]
## [Version&nbsp;2.0.0-next.193](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.192...v2.0.0-next.193)
<sup>Released on **2026-01-02**</sup>

#### 🐛 Bug Fixes

- **database**: Add userId authorization check in removeFilesFromKnowledgeBase.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **database**: Add userId authorization check in removeFilesFromKnowledgeBase, closes [#11108](https://github.com/lobehub/lobe-chat/issues/11108) ([2c1762b](https://github.com/lobehub/lobe-chat/commit/2c1762b))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-02 13:21:07 +00:00
Arvin Xu 2c1762b85a 🐛 fix(database): add userId authorization check in removeFilesFromKnowledgeBase (#11108)
* fix kb issue

* 🔒 fix(file): validate file size from S3 instead of trusting client input

Security fix for GHSA-wrrr-8jcv-wjf5: The file upload feature did not
validate the integrity of upload requests, allowing users to manipulate
the size parameter to bypass quota limits.

Changes:
- Add getFileMetadata method to S3 module using HeadObjectCommand
- Add getFileMetadata to FileServiceImpl interface and implementations
- Update createFile router to fetch actual file size from S3
- Add comprehensive tests for the new functionality
- Fix duplicate import in knowledgeBase.test.ts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* 🐛 fix(ci): use allowed_tools instead of claude_args for claude-translator

Fix shell parsing issue where special characters in claude_args were
incorrectly split. The parentheses and asterisks in tool patterns like
`Bash(gh issue view *)` were being parsed by shell, causing:
- "Bash(gh issue view *)" to become ["Bash", "gh", "issue", "view", "*"]

Changes:
- Replace `claude_args: "--allowed-tools ..."` with `allowed_tools: '...'`
- Use colon separator format consistent with other workflows
- Simplify tool patterns while maintaining security restrictions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-02 21:03:05 +08:00
lobehubbot a2947c91c7 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-02 12:42:29 +00:00
semantic-release-bot 0abe565347 🔖 chore(release): v2.0.0-next.192 [skip ci]
## [Version&nbsp;2.0.0-next.192](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.191...v2.0.0-next.192)
<sup>Released on **2026-01-02**</sup>

#### 🐛 Bug Fixes

- **misc**: Fix model edit icon missing.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **misc**: Fix model edit icon missing, closes [#11105](https://github.com/lobehub/lobe-chat/issues/11105) ([0f88995](https://github.com/lobehub/lobe-chat/commit/0f88995))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-02 12:41:06 +00:00
Arvin Xu 0f889952dd 🐛 fix: fix model edit icon missing (#11105)
* 🐛 fix: fix model edit icon missing

* fix stats welcome

* refactor pglite db case

* fix e2e tests

* update docs
2026-01-02 20:12:19 +08:00
lobehubbot 3db9947b14 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-02 12:03:43 +00:00
semantic-release-bot 521908008e 🔖 chore(release): v2.0.0-next.191 [skip ci]
## [Version&nbsp;2.0.0-next.191](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.190...v2.0.0-next.191)
<sup>Released on **2026-01-02**</sup>

#### ♻ Code Refactoring

- **misc**: Refactor to remove meta in message.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### Code refactoring

* **misc**: Refactor to remove meta in message, closes [#11103](https://github.com/lobehub/lobe-chat/issues/11103) ([527c1cd](https://github.com/lobehub/lobe-chat/commit/527c1cd))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-02 12:02:07 +00:00
LobeHub Bot 5b214b6642 🌐 chore: translate non-English comments to English in agent executors (#11023)
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-02 19:21:36 +08:00
LobeHub Bot 472b664a13 test: add unit tests for packages/const/src/utils/merge (#10987)
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-02 19:18:51 +08:00
Arvin Xu 527c1cd670 ♻️ refactor: refactor to remove meta in message (#11103)
* ♻️ refactor: refactor to remove meta in message

*  test: update test fixtures to remove deprecated meta field

- Update 8 snapshots in prompts package for groupChat tests
- Remove meta field from 36 JSON fixtures in conversation-flow package
  - Updated both inputs and outputs fixtures
  - Covers: linear-conversation, tasks, branch, compare, agentCouncil,
    agentGroup, assistantGroup scenarios

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-02 19:15:38 +08:00
LobeHub Bot 88552540fb test: add unit tests for modelParamsResolver (#11104)
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-02 14:08:16 +08:00
LobeHub Bot 0cf6275ed4 🌐 chore: translate non-English comments to English in src/server/services (#11102)
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-02 14:07:54 +08:00
lobehubbot e3727e1a6f 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-02 02:39:22 +00:00
semantic-release-bot c786c028c6 🔖 chore(release): v2.0.0-next.190 [skip ci]
## [Version&nbsp;2.0.0-next.190](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.189...v2.0.0-next.190)
<sup>Released on **2026-01-02**</sup>

#### 💄 Styles

- **misc**: Update i18n.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### Styles

* **misc**: Update i18n, closes [#11100](https://github.com/lobehub/lobe-chat/issues/11100) ([bb4571b](https://github.com/lobehub/lobe-chat/commit/bb4571b))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-02 02:38:02 +00:00
LobeHub Bot bb4571b0d5 🤖 style: update i18n (#11100)
💄 style: update i18n

Co-authored-by: canisminor1990 <17870709+canisminor1990@users.noreply.github.com>
2026-01-02 10:20:04 +08:00
lobehubbot b43404c892 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-01 17:34:23 +00:00
semantic-release-bot 73c042352b 🔖 chore(release): v2.0.0-next.189 [skip ci]
## [Version&nbsp;2.0.0-next.189](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.188...v2.0.0-next.189)
<sup>Released on **2026-01-01**</sup>

#### ♻ Code Refactoring

- **misc**: Migrate to new DropdownMenuV2 and showContextMenu API.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### Code refactoring

* **misc**: Migrate to new DropdownMenuV2 and showContextMenu API, closes [#11079](https://github.com/lobehub/lobe-chat/issues/11079) ([04cfc0e](https://github.com/lobehub/lobe-chat/commit/04cfc0e))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-01 17:32:56 +00:00
Innei 04cfc0e9e0 ♻️ refactor: migrate to new DropdownMenuV2 and showContextMenu API (#11079)
* ♻️ refactor: migrate to new DropdownMenuV2 and showContextMenu API

- Replace Dropdown with DropdownMenuV2 for action menus
- Use showContextMenu for context menu handling instead of Dropdown wrapper
- Update @lobehub/ui to preview version with new context menu API
- Add styles for popup-open state in NavItem component

* ♻️ refactor: migrate to new DropdownMenuV2 and showContextMenu API

* chore: Update @lobehub/ui dependency to version ^4.6.3.

Signed-off-by: Innei <tukon479@gmail.com>

* ♻️ refactor: migrate to new DropdownMenuV2 and showContextMenu API

- Remove deprecated ContextMenu component
- Migrate all context menu usages to DropdownMenuV2 and showContextMenu API
- Update multiple Action components across Conversation features
- Update ResourceManager toolbar components
- Clean up related styles

🤖 Generated with [Claude Code](https://claude.com/claude-code)

* feat: Update `@lobehub/ui` dependency, simplify `ActionIconGroup` menu prop, and ensure action group visibility when popups are open.

Signed-off-by: Innei <tukon479@gmail.com>

* fix: Add null check for context menu items, include debug log, and update `@lobehub/ui` dependency.

Signed-off-by: Innei <tukon479@gmail.com>

* ♻️ refactor: migrate TopicSelector to new DropdownMenuV2 API

Migrate from antd/Dropdown to @lobehub/ui DropdownMenu component
with checkbox items pattern.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: Innei <tukon479@gmail.com>
2026-01-02 01:14:30 +08:00
Arvin Xu e3f0f46436 test: add more user journey (#11072)
*  test(e2e): add Agent conversation E2E test with LLM mock

- Add LLM mock framework to intercept /webapi/chat/openai requests
- Create Agent conversation journey test (AGENT-CHAT-001)
- Add data-testid="chat-input" to Desktop ChatInput for E2E testing
- Mock returns SSE streaming responses matching LobeChat's actual format

Test scenario: Enter Lobe AI → Send "hello" → Verify AI response

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* 📝 docs(e2e): add experience-driven E2E testing strategy

Add comprehensive testing strategy from LOBE-2417:
- Core philosophy: user experience baseline for refactoring safety
- Product architecture coverage with priority levels
- Tag system (@journey, @P0/@P1/@P2, module tags)
- Execution strategies for CI, Nightly, and Release
- Updated directory structure with full journey coverage plan

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

📝 docs(e2e): add E2E testing guide for Claude

Document key learnings from implementing Agent conversation test:
- LLM Mock SSE format and usage
- Desktop/Mobile dual component handling with boundingBox
- contenteditable input handling
- Debugging tips and common issues

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* 📝 docs(e2e): add experience-driven E2E testing strategy

Add comprehensive testing strategy from LOBE-2417:
- Core philosophy: user experience baseline for refactoring safety
- Product architecture coverage with priority levels
- Tag system (@journey, @P0/@P1/@P2, module tags)
- Execution strategies for CI, Nightly, and Release
- Updated directory structure with full journey coverage plan

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

📝 docs(e2e): add E2E testing guide for Claude

Document key learnings from implementing Agent conversation test:
- LLM Mock SSE format and usage
- Desktop/Mobile dual component handling with boundingBox
- contenteditable input handling
- Debugging tips and common issues

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* update sop

* update sop

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 23:53:25 +08:00
lobehubbot 2bc3b16671 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-01 15:44:04 +00:00
semantic-release-bot ae759f29aa 🔖 chore(release): v2.0.0-next.188 [skip ci]
## [Version&nbsp;2.0.0-next.188](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.187...v2.0.0-next.188)
<sup>Released on **2026-01-01**</sup>

#### 💄 Styles

- **misc**: Improve tools UI and fix Google schema compatibility.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### Styles

* **misc**: Improve tools UI and fix Google schema compatibility, closes [#11096](https://github.com/lobehub/lobe-chat/issues/11096) ([70a9cff](https://github.com/lobehub/lobe-chat/commit/70a9cff))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-01 15:42:42 +00:00
Arvin Xu 70a9cffc52 💄 style: improve tools UI and fix Google schema compatibility (#11096)
* ♻️ refactor: refactor tool implement

* 🐛 fix: fix google tool schema issue

* ♻️ refactor: refactor tool implement

*  feat: improve kb inspector

* 💄 style: improve local system inspector

* 💄 style: improve local system inspector

* 💄 style: improve web and kb inspector
2026-01-01 23:23:31 +08:00
lobehubbot b937a815ca 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-01 15:08:36 +00:00
semantic-release-bot 4d01659ded 🔖 chore(release): v2.0.0-next.187 [skip ci]
## [Version&nbsp;2.0.0-next.187](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.186...v2.0.0-next.187)
<sup>Released on **2026-01-01**</sup>

#### 💄 Styles

- **misc**: Add Gemini 3 Flash & Doubao Seed 1.8 models.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### Styles

* **misc**: Add Gemini 3 Flash & Doubao Seed 1.8 models, closes [#10832](https://github.com/lobehub/lobe-chat/issues/10832) ([cb35935](https://github.com/lobehub/lobe-chat/commit/cb35935))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-01 15:07:05 +00:00
LobeHub Bot d502924665 test: add unit tests for fetch-sse request module (#11014)
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-01 22:47:18 +08:00
sxjeru cb3593585b 💄 style: Add Gemini 3 Flash & Doubao Seed 1.8 models (#10832)
*  feat: 添加 Gemini 3 Flash 模型及其参数配置

*  feat: 添加 Doubao Seed 1.8 和 DeepSeek V3.2 模型,更新模型参数配置;修改处理负载以支持 reasoning_effort

*  feat: 启用 DeepSeek V3.2 模型

*  feat: 移除 doubaoChatModels 中的 enableReasoning 参数

*  feat: 添加混元图生文模型,更新智谱模型配置,优化模型解析逻辑

*  feat: 添加 MiniMax M2.1 和 MiniMax M2.1 Lightning 模型,更新模型参数配置;调整 OllamaCloud 模型的上下文窗口大小

*  feat: 添加 MiniMax M2.1 和 GLM-4.7 模型,更新模型描述和参数配置

*  feat: 添加 GLM-4.7 模型,更新模型描述和定价策略;优化 Zhipu 模型的工具处理逻辑

*  feat: add thinkingLevel2 parameter and update related components

* Update volcengine.ts

*  feat: 添加 gpt5_2ReasoningEffort 和 gpt5_2ProReasoningEffort 参数,并更新相关组件

---------

Co-authored-by: Arvin Xu <arvinx@foxmail.com>
2026-01-01 22:42:25 +08:00
lobehubbot 2e260a8146 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-01 14:07:08 +00:00
semantic-release-bot ffbb4fd6a0 🔖 chore(release): v2.0.0-next.186 [skip ci]
## [Version&nbsp;2.0.0-next.186](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.185...v2.0.0-next.186)
<sup>Released on **2026-01-01**</sup>

#### ♻ Code Refactoring

- **misc**: Refactor oidc env to auth env.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### Code refactoring

* **misc**: Refactor oidc env to auth env, closes [#11095](https://github.com/lobehub/lobe-chat/issues/11095) ([6e8d4ff](https://github.com/lobehub/lobe-chat/commit/6e8d4ff))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-01 14:05:35 +00:00
Arvin Xu 6e8d4ffbc7 ♻️ refactor: refactor oidc env to auth env (#11095)
♻️ refactor: refactor oidc to auth
2026-01-01 21:45:42 +08:00
LobeHub Bot a71d9c70d2 🌐 chore: translate non-English comments to English in packages/types (#11086)
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-01 20:54:29 +08:00
sxjeru 479556b39a 🔨 chore: fix Vercel build process (#11092)
* Update package.json

* Update next.config.ts

* improve webpack handling

* 调整构建命令以增加内存限制并更新 Vercel 构建命令
2026-01-01 19:18:38 +08:00
lobehubbot 789c302e2e 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-01 09:57:09 +00:00
semantic-release-bot b883d833d4 🔖 chore(release): v2.0.0-next.185 [skip ci]
## [Version&nbsp;2.0.0-next.185](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.184...v2.0.0-next.185)
<sup>Released on **2026-01-01**</sup>

#### 💄 Styles

- **misc**: Update i18n.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### Styles

* **misc**: Update i18n, closes [#11085](https://github.com/lobehub/lobe-chat/issues/11085) ([0941a52](https://github.com/lobehub/lobe-chat/commit/0941a52))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-01 09:55:46 +00:00
LobeHub Bot bfd07ca266 test: add unit tests for size utils (#11090) 2026-01-01 17:37:28 +08:00
LobeHub Bot 0941a52b9e 🤖 style: update i18n (#11085)
💄 style: update i18n

Co-authored-by: canisminor1990 <17870709+canisminor1990@users.noreply.github.com>
2026-01-01 14:02:50 +08:00
lobehubbot 21bb985bec 📝 docs(bot): Auto sync agents & plugin to readme 2026-01-01 05:44:34 +00:00
semantic-release-bot 3b870e41da 🔖 chore(release): v2.0.0-next.184 [skip ci]
## [Version&nbsp;2.0.0-next.184](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.183...v2.0.0-next.184)
<sup>Released on **2026-01-01**</sup>

#### 💄 Styles

- **misc**: Improve loading and local-system render.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### Styles

* **misc**: Improve loading and local-system render, closes [#11087](https://github.com/lobehub/lobe-chat/issues/11087) ([44630bc](https://github.com/lobehub/lobe-chat/commit/44630bc))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2026-01-01 05:43:09 +00:00
Arvin Xu 44630bcfe4 💄 style: improve loading and local-system render (#11087)
* 💄 style: improve loading

* ♻️ refactor: move local-system to builtin-tool-local-system package

* update

* remove focusThrottleInterval
2026-01-01 13:24:17 +08:00
lobehubbot ee48742f7b 📝 docs(bot): Auto sync agents & plugin to readme 2025-12-31 18:19:27 +00:00
semantic-release-bot 4306ec5cb1 🔖 chore(release): v2.0.0-next.183 [skip ci]
## [Version&nbsp;2.0.0-next.183](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.182...v2.0.0-next.183)
<sup>Released on **2025-12-31**</sup>

#### 🐛 Bug Fixes

- **store**: Clear new key data when switchTopic to new state.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **store**: Clear new key data when switchTopic to new state, closes [#11078](https://github.com/lobehub/lobe-chat/issues/11078) ([180ea14](https://github.com/lobehub/lobe-chat/commit/180ea14))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2025-12-31 18:18:08 +00:00
Arvin Xu 180ea14b18 🐛 fix(store): clear new key data when switchTopic to new state (#11078)
When switching to a new topic state (topicId = null), the previous
messages in the `_new` key might remain as stale data. This causes
old messages to appear when users click "New Topic".

Changes:
- Add `SwitchTopicOptions` interface with `scope` and `skipRefreshMessage`
- Modify `switchTopic` to support both boolean and options object (backward compatible)
- Clear the corresponding scope's `_new` key when switching to new state
- Add 6 new test cases for the new functionality

Closes: LOBE-2456

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 02:00:33 +08:00
lobehubbot 5b98b08353 📝 docs(bot): Auto sync agents & plugin to readme 2025-12-31 15:06:57 +00:00
semantic-release-bot bdde01d9cf 🔖 chore(release): v2.0.0-next.182 [skip ci]
## [Version&nbsp;2.0.0-next.182](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.181...v2.0.0-next.182)
<sup>Released on **2025-12-31**</sup>

####  Features

- **misc**: Brand new 2.0 ui for next.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's improved

* **misc**: Brand new 2.0 ui for next ([e5d6d3d](https://github.com/lobehub/lobe-chat/commit/e5d6d3d))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2025-12-31 15:05:36 +00:00
arvinxx e5d6d3d0d3 feat: brand new 2.0 ui for next 2025-12-31 22:44:43 +08:00
lobehubbot b7488b85e6 📝 docs(bot): Auto sync agents & plugin to readme 2025-12-31 14:36:24 +00:00
semantic-release-bot 8934282c2c 🔖 chore(release): v2.0.0-next.181 [skip ci]
## [Version&nbsp;2.0.0-next.181](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.180...v2.0.0-next.181)
<sup>Released on **2025-12-31**</sup>

#### ♻ Code Refactoring

- **userMemories**: Added `benchmark_locomo` as source unify use the of source type.
- **misc**: Add builtin tools, clean code, clean desktop relative code, clean page editor, flatten i18n keys and extract hardcoded strings in desktop, i18n formatting optimization, improve modal handling with createRawModal, move code-interpreter to single packages, refactor builtin-tool implement, refactor hooks, refactor implement, refactor implement for desktop, refactor local-system, refactor service, refactor static style, refactor to use better underline style, refactor to use better underline style, refactor tool prompt injection, refactor ui and layout, refactor with editor runtime, refactor with electron, refactor with es-toolkit, remove desktop-specific upload logic, rename browser identifier from 'chat' to 'app', tools ui, use /f/:fid as file mode, use supervisor role for agent group supervisor.

####  Features

- **auth**: Add confirm password field and integrate business signup logic, add useBusinessSignup hook for business signup functionality, enhance BetterAuthSignUpForm with businessElement and update useSignUp hook for improved signup process, integrate business sign-in features and update social sign-in logic, update useBusinessSignin to include getAdditionalData function for enhanced sign-in process.
- **desktop**: MacOS About menu should navigate to Settings About tab.
- **layout**: Integrate BusinessGlobalProvider for conditional rendering based on business features.
- **memory-user-memory**: Added LoCoMo dataset loader & converter & exporter, support to extract memories from LoCoMo dataset, support to load in memory, and extract from in-memory memory sources.
- **model**: Improve model list UI and add disabled models management.
- **referral**: Add backfill referral code i18n keys.
- **userMemories**: Apply userMemories.enable from settings for injecting, use capturedAt for time of memory entries, use honorific title for identity memory.
- **misc**: Add a white waitlist in edge config env, add always show tools render in createPlan & createDoc tools, add batch tasks ui, add Bundle Analyzer workflow for detailed bundle size analysis, add business features support with new components and hooks, add business settings features with dynamic loading for Plans, Funds, Usage, Billing, and Referral tabs, add db and schema feature, add home page create group builder button, Add i18n UI locales and improve tool types, add like action in community detail, add memory implement, add subscription settings group with dynamic loading for Plans, Funds, Usage, Billing, and Referral tabs, add the market auth auto generate way, Add turbopack configuration support to CustomNextConfig, add user memory, agent builder, agent builder, agent builder and group builder, app ui page, brand new 2.0 ui for next, buildin some tools should save into docs, code-interpreter tool, code-interpreter tool, code-interpreter tool, desktop feature, enhance desktop onboarding with sign out and localization, enhance macOS desktop permissions and onboarding, enhance onboarding process by removing mode selection step and adding export functionality in advanced settings, file search feature, gtd create plan support streaming render, implement agent builder, implement builtin agents packages, implement memories package, implement Redis caching for presigned URLs in file proxy service, implement server data feature, include Subscription settings group in the Accordion component, Integrate bcryptjs for password verification in BetterAuth, integrate BrandingProviderCard and update Provider components for branding support, onboarding ui, page and knowledge base, rebranding total UI of app, refactor authentication handler to support dynamic loading of better-auth and next-auth, refactor desktop implement with brand new 2.0, rename codeinterpreter into lobe sandbox, server implement, support CMD K, support exec async sub agent task, support export and import topic JSON, support files upload in chat input, support notebook tool, support swr local cache, topic message swr cache, translate AI model descriptions to English, update agent builder ui, update create group chat use builder, update gtd tools( use editor & update metadata ), update user memory embedding model selection based on business features, user memory, user memory, user onboarding, when use usesend to create agent/group, the model should override by lobeAi, wrap ConversationArea and ModelSwitchPanel in TooltipGroup for enhanced UI.

#### 🐛 Bug Fixes

- **ci**: Skip backend routes in bundle analyzer build.
- **desktop**:  prevent window resize when onboarding, add safe top edge for message container.
- **i18n**: Translate plugin.ts locale to English.
- **image-generation**: Update chargeBeforeGenerate to return ChargeResult and include configForDatabase in parameters.
- **memory-user-memory**: Should pre-process date & time.
- **observability-otel**: Typo in package name.
- **prebuild**: Correct syntax in partialBuildPages array.
- **translation**: Add fallback for all English locale variants.
- **userMemories**: 404/405 issue due to incorrectly used workflow name and mounted catch-all route, missing base memory as part of context, must assign workflow id, should use `context.invoke` for workflow instead of `context.run`, skip to handle WorkflowAbort, use date & time for building context, workflow id build issue.
- **misc**: Agent profiles update, agent tools config set, editor placeholder, bump charts 3.0.4 to fix import es path, fix anthropic thinking budget, fix async task and improve tool style, fix default waitlist bug, fix delete agent group bug, Fix desktop test cases and refactor translations, Fix desktop test cases and refactor translations, fix gemini 3 model thinking issue, fix gemini 3 pro parallel tool use, fix gemini 3 thinking params, fix identity memory not working, fix supervisor flag, fix thread not working issue, fix when use branch topic,the branch index error problem, fixed the welcome card the create button not work, handle session invalidation on 401 error by logging out signed-in users, improve test infrastructure and mock configurations, locale resolve bug with ESM module loading, page agent editor, prevent redundant login redirect when already on auth pages, redis read json object, remove openapi pkg patch file, slove input editor on pause emit, slove swr mutate not work in Cache Provider, slove the group add member checkbox not work, slove the model select null problem, slove the mutate not work problem, slove when click agentbuilder should clean topic, slove when first call thread, not show ai chat message, support retry error message and fix continueGenerationMessage, update contextMenu in group tools message, update OFFICIAL_URL to app.lobehub.com, update PlanTag link paths for subscription settings, update test snapshots for model description changes, when use agentbuilder the topic id should use new & clear topic….

#### 💄 Styles

- **misc**: Improve ExecTask and task message UI, improve gtd tool inspector and todo list, improve page document tool inspector UI, improve RunCommand Inspector, rebranding chat ui, refactor UI in features, rerun i18n, setting style, support streaming and display ui for group mode, support tool streaming and title custom render, update i18n, Update i18n microcopy, update ui.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### Code refactoring

* **userMemories**: Added `benchmark_locomo` as source unify use the of source type, closes [#10922](https://github.com/lobehub/lobe-chat/issues/10922) ([03342a7](https://github.com/lobehub/lobe-chat/commit/03342a7))
* **misc**: Add builtin tools ([26e73cc](https://github.com/lobehub/lobe-chat/commit/26e73cc))
* **misc**: Clean code ([4ddb491](https://github.com/lobehub/lobe-chat/commit/4ddb491))
* **misc**: Clean desktop relative code ([ffd7d23](https://github.com/lobehub/lobe-chat/commit/ffd7d23))
* **misc**: Clean page editor, closes [#10966](https://github.com/lobehub/lobe-chat/issues/10966) ([15410d1](https://github.com/lobehub/lobe-chat/commit/15410d1))
* **misc**: Flatten i18n keys and extract hardcoded strings in desktop, closes [#10939](https://github.com/lobehub/lobe-chat/issues/10939) ([e5f3a58](https://github.com/lobehub/lobe-chat/commit/e5f3a58))
* **misc**: I18n formatting optimization, closes [#10929](https://github.com/lobehub/lobe-chat/issues/10929) [#10933](https://github.com/lobehub/lobe-chat/issues/10933) ([d692a37](https://github.com/lobehub/lobe-chat/commit/d692a37))
* **misc**: Improve modal handling with createRawModal, closes [#11071](https://github.com/lobehub/lobe-chat/issues/11071) ([f5314c5](https://github.com/lobehub/lobe-chat/commit/f5314c5))
* **misc**: Move code-interpreter to single packages ([1fa4357](https://github.com/lobehub/lobe-chat/commit/1fa4357))
* **misc**: Refactor builtin-tool implement ([9ede8e7](https://github.com/lobehub/lobe-chat/commit/9ede8e7))
* **misc**: Refactor hooks ([e3fa62e](https://github.com/lobehub/lobe-chat/commit/e3fa62e))
* **misc**: Refactor implement ([34d059f](https://github.com/lobehub/lobe-chat/commit/34d059f))
* **misc**: Refactor implement for desktop ([27f101f](https://github.com/lobehub/lobe-chat/commit/27f101f))
* **misc**: Refactor local-system ([a69221f](https://github.com/lobehub/lobe-chat/commit/a69221f))
* **misc**: Refactor service ([91bbbf5](https://github.com/lobehub/lobe-chat/commit/91bbbf5))
* **misc**: Refactor static style, closes [#11010](https://github.com/lobehub/lobe-chat/issues/11010) ([d865e27](https://github.com/lobehub/lobe-chat/commit/d865e27))
* **misc**: Refactor to use better underline style ([784bb58](https://github.com/lobehub/lobe-chat/commit/784bb58))
* **misc**: Refactor to use better underline style ([5e10ac8](https://github.com/lobehub/lobe-chat/commit/5e10ac8))
* **misc**: Refactor tool prompt injection ([6099ac3](https://github.com/lobehub/lobe-chat/commit/6099ac3))
* **misc**: Refactor ui and layout ([436d9e5](https://github.com/lobehub/lobe-chat/commit/436d9e5))
* **misc**: Refactor with editor runtime ([be2b41c](https://github.com/lobehub/lobe-chat/commit/be2b41c))
* **misc**: Refactor with electron ([849ee3d](https://github.com/lobehub/lobe-chat/commit/849ee3d))
* **misc**: Refactor with es-toolkit ([1848d27](https://github.com/lobehub/lobe-chat/commit/1848d27))
* **misc**: Remove desktop-specific upload logic, closes [#11070](https://github.com/lobehub/lobe-chat/issues/11070) ([475065e](https://github.com/lobehub/lobe-chat/commit/475065e))
* **misc**: Rename browser identifier from 'chat' to 'app', closes [#10940](https://github.com/lobehub/lobe-chat/issues/10940) ([dc870c7](https://github.com/lobehub/lobe-chat/commit/dc870c7))
* **misc**: Tools ui ([6bf4546](https://github.com/lobehub/lobe-chat/commit/6bf4546))
* **misc**: Use /f/:fid as file mode ([3b01174](https://github.com/lobehub/lobe-chat/commit/3b01174))
* **misc**: Use supervisor role for agent group supervisor ([0ca823f](https://github.com/lobehub/lobe-chat/commit/0ca823f))

#### What's improved

* **auth**: Add confirm password field and integrate business signup logic ([2ccd5c7](https://github.com/lobehub/lobe-chat/commit/2ccd5c7))
* **auth**: Add useBusinessSignup hook for business signup functionality ([3efb6cc](https://github.com/lobehub/lobe-chat/commit/3efb6cc))
* **auth**: Enhance BetterAuthSignUpForm with businessElement and update useSignUp hook for improved signup process ([991d8c1](https://github.com/lobehub/lobe-chat/commit/991d8c1))
* **auth**: Integrate business sign-in features and update social sign-in logic ([6dc7916](https://github.com/lobehub/lobe-chat/commit/6dc7916))
* **auth**: Update useBusinessSignin to include getAdditionalData function for enhanced sign-in process ([c8e3bc9](https://github.com/lobehub/lobe-chat/commit/c8e3bc9))
* **desktop**: MacOS About menu should navigate to Settings About tab, closes [#10942](https://github.com/lobehub/lobe-chat/issues/10942) ([1a4f456](https://github.com/lobehub/lobe-chat/commit/1a4f456))
* **layout**: Integrate BusinessGlobalProvider for conditional rendering based on business features ([52c7a49](https://github.com/lobehub/lobe-chat/commit/52c7a49))
* **memory-user-memory**: Added LoCoMo dataset loader & converter & exporter, closes [#10923](https://github.com/lobehub/lobe-chat/issues/10923) ([a5dd785](https://github.com/lobehub/lobe-chat/commit/a5dd785))
* **memory-user-memory**: Support to extract memories from LoCoMo dataset, closes [#10925](https://github.com/lobehub/lobe-chat/issues/10925) ([c7c7d6f](https://github.com/lobehub/lobe-chat/commit/c7c7d6f))
* **memory-user-memory**: Support to load in memory, and extract from in-memory memory sources, closes [#10924](https://github.com/lobehub/lobe-chat/issues/10924) ([9ac3ce7](https://github.com/lobehub/lobe-chat/commit/9ac3ce7))
* **model**: Improve model list UI and add disabled models management, closes [#11036](https://github.com/lobehub/lobe-chat/issues/11036) ([4faa65c](https://github.com/lobehub/lobe-chat/commit/4faa65c))
* **referral**: Add backfill referral code i18n keys ([bbf62ce](https://github.com/lobehub/lobe-chat/commit/bbf62ce))
* **userMemories**: Apply userMemories.enable from settings for injecting, closes [#11038](https://github.com/lobehub/lobe-chat/issues/11038) ([1cc0e8c](https://github.com/lobehub/lobe-chat/commit/1cc0e8c))
* **userMemories**: Use capturedAt for time of memory entries, closes [#11037](https://github.com/lobehub/lobe-chat/issues/11037) ([5615d20](https://github.com/lobehub/lobe-chat/commit/5615d20))
* **userMemories**: Use honorific title for identity memory, closes [#11039](https://github.com/lobehub/lobe-chat/issues/11039) ([ab61c69](https://github.com/lobehub/lobe-chat/commit/ab61c69))
* **misc**: Add a white waitlist in edge config env, closes [#11009](https://github.com/lobehub/lobe-chat/issues/11009) ([88f22f4](https://github.com/lobehub/lobe-chat/commit/88f22f4))
* **misc**: Add always show tools render in createPlan & createDoc tools, closes [#10937](https://github.com/lobehub/lobe-chat/issues/10937) ([c224951](https://github.com/lobehub/lobe-chat/commit/c224951))
* **misc**: Add batch tasks ui ([80587ae](https://github.com/lobehub/lobe-chat/commit/80587ae))
* **misc**: Add Bundle Analyzer workflow for detailed bundle size analysis ([596e489](https://github.com/lobehub/lobe-chat/commit/596e489))
* **misc**: Add business features support with new components and hooks ([1dccc04](https://github.com/lobehub/lobe-chat/commit/1dccc04))
* **misc**: Add business settings features with dynamic loading for Plans, Funds, Usage, Billing, and Referral tabs ([35c6ad9](https://github.com/lobehub/lobe-chat/commit/35c6ad9))
* **misc**: Add db and schema feature ([9e47c33](https://github.com/lobehub/lobe-chat/commit/9e47c33))
* **misc**: Add home page create group builder button, closes [#10904](https://github.com/lobehub/lobe-chat/issues/10904) ([3183189](https://github.com/lobehub/lobe-chat/commit/3183189))
* **misc**: Add i18n UI locales and improve tool types, closes [#10964](https://github.com/lobehub/lobe-chat/issues/10964) ([0e89ce5](https://github.com/lobehub/lobe-chat/commit/0e89ce5))
* **misc**: Add like action in community detail, closes [#10971](https://github.com/lobehub/lobe-chat/issues/10971) ([c11d802](https://github.com/lobehub/lobe-chat/commit/c11d802))
* **misc**: Add memory implement ([fdae83c](https://github.com/lobehub/lobe-chat/commit/fdae83c))
* **misc**: Add subscription settings group with dynamic loading for Plans, Funds, Usage, Billing, and Referral tabs ([2ddc876](https://github.com/lobehub/lobe-chat/commit/2ddc876))
* **misc**: Add the market auth auto generate way, closes [#10993](https://github.com/lobehub/lobe-chat/issues/10993) ([849ac73](https://github.com/lobehub/lobe-chat/commit/849ac73))
* **misc**: Add turbopack configuration support to CustomNextConfig ([2e7076a](https://github.com/lobehub/lobe-chat/commit/2e7076a))
* **misc**: Add user memory ([c305889](https://github.com/lobehub/lobe-chat/commit/c305889))
* **misc**: Agent builder ([ede0ed6](https://github.com/lobehub/lobe-chat/commit/ede0ed6))
* **misc**: Agent builder ([e3c9454](https://github.com/lobehub/lobe-chat/commit/e3c9454))
* **misc**: Agent builder and group builder ([d735e2c](https://github.com/lobehub/lobe-chat/commit/d735e2c))
* **misc**: App ui page ([78d07c0](https://github.com/lobehub/lobe-chat/commit/78d07c0))
* **misc**: Brand new 2.0 ui for next ([f7d724f](https://github.com/lobehub/lobe-chat/commit/f7d724f))
* **misc**: Buildin some tools should save into docs, closes [#10935](https://github.com/lobehub/lobe-chat/issues/10935) ([be4c17d](https://github.com/lobehub/lobe-chat/commit/be4c17d))
* **misc**: Code-interpreter tool ([1940914](https://github.com/lobehub/lobe-chat/commit/1940914))
* **misc**: Code-interpreter tool ([c931909](https://github.com/lobehub/lobe-chat/commit/c931909))
* **misc**: Code-interpreter tool ([baa29c8](https://github.com/lobehub/lobe-chat/commit/baa29c8))
* **misc**: Desktop feature ([ac93637](https://github.com/lobehub/lobe-chat/commit/ac93637))
* **misc**: Enhance desktop onboarding with sign out and localization, closes [#11033](https://github.com/lobehub/lobe-chat/issues/11033) ([34a6312](https://github.com/lobehub/lobe-chat/commit/34a6312))
* **misc**: Enhance macOS desktop permissions and onboarding, closes [#11016](https://github.com/lobehub/lobe-chat/issues/11016) ([9db8da8](https://github.com/lobehub/lobe-chat/commit/9db8da8))
* **misc**: Enhance onboarding process by removing mode selection step and adding export functionality in advanced settings ([8b6c30e](https://github.com/lobehub/lobe-chat/commit/8b6c30e))
* **misc**: File search feature ([9786d64](https://github.com/lobehub/lobe-chat/commit/9786d64))
* **misc**: Gtd create plan support streaming render, closes [#11034](https://github.com/lobehub/lobe-chat/issues/11034) ([74d3555](https://github.com/lobehub/lobe-chat/commit/74d3555))
* **misc**: Implement agent builder ([f638b97](https://github.com/lobehub/lobe-chat/commit/f638b97))
* **misc**: Implement builtin agents packages ([2255a7c](https://github.com/lobehub/lobe-chat/commit/2255a7c))
* **misc**: Implement memories package ([7f94ef1](https://github.com/lobehub/lobe-chat/commit/7f94ef1))
* **misc**: Implement Redis caching for presigned URLs in file proxy service ([15722f1](https://github.com/lobehub/lobe-chat/commit/15722f1))
* **misc**: Implement server data feature ([9c46c6e](https://github.com/lobehub/lobe-chat/commit/9c46c6e))
* **misc**: Include Subscription settings group in the Accordion component ([8f2d57d](https://github.com/lobehub/lobe-chat/commit/8f2d57d))
* **misc**: Integrate bcryptjs for password verification in BetterAuth ([180ebfd](https://github.com/lobehub/lobe-chat/commit/180ebfd))
* **misc**: Integrate BrandingProviderCard and update Provider components for branding support ([6b5ce79](https://github.com/lobehub/lobe-chat/commit/6b5ce79))
* **misc**: Onboarding ui ([81d33a6](https://github.com/lobehub/lobe-chat/commit/81d33a6))
* **misc**: Page and knowledge base ([492d3cc](https://github.com/lobehub/lobe-chat/commit/492d3cc))
* **misc**: Rebranding total UI of app ([13ca81b](https://github.com/lobehub/lobe-chat/commit/13ca81b))
* **misc**: Refactor authentication handler to support dynamic loading of better-auth and next-auth ([d6419e4](https://github.com/lobehub/lobe-chat/commit/d6419e4))
* **misc**: Refactor desktop implement with brand new 2.0 ([10e048c](https://github.com/lobehub/lobe-chat/commit/10e048c))
* **misc**: Rename codeinterpreter into lobe sandbox, closes [#11076](https://github.com/lobehub/lobe-chat/issues/11076) ([2a631b4](https://github.com/lobehub/lobe-chat/commit/2a631b4))
* **misc**: Server implement ([685a6cd](https://github.com/lobehub/lobe-chat/commit/685a6cd))
* **misc**: Support CMD K ([d2bd8a6](https://github.com/lobehub/lobe-chat/commit/d2bd8a6))
* **misc**: Support exec async sub agent task ([dba1acf](https://github.com/lobehub/lobe-chat/commit/dba1acf))
* **misc**: Support export and import topic JSON, closes [#10885](https://github.com/lobehub/lobe-chat/issues/10885) ([0c5a41f](https://github.com/lobehub/lobe-chat/commit/0c5a41f))
* **misc**: Support files upload in chat input, closes [#10967](https://github.com/lobehub/lobe-chat/issues/10967) ([60eba45](https://github.com/lobehub/lobe-chat/commit/60eba45))
* **misc**: Support notebook tool, closes [#10902](https://github.com/lobehub/lobe-chat/issues/10902) ([e05375f](https://github.com/lobehub/lobe-chat/commit/e05375f))
* **misc**: Support swr local cache, closes [#10884](https://github.com/lobehub/lobe-chat/issues/10884) ([bc3f3e2](https://github.com/lobehub/lobe-chat/commit/bc3f3e2))
* **misc**: Topic message swr cache, closes [#10886](https://github.com/lobehub/lobe-chat/issues/10886) ([613a404](https://github.com/lobehub/lobe-chat/commit/613a404))
* **misc**: Translate AI model descriptions to English, closes [#10989](https://github.com/lobehub/lobe-chat/issues/10989) ([36ea258](https://github.com/lobehub/lobe-chat/commit/36ea258))
* **misc**: Update agent builder ui, closes [#10996](https://github.com/lobehub/lobe-chat/issues/10996) ([704ef7f](https://github.com/lobehub/lobe-chat/commit/704ef7f))
* **misc**: Update create group chat use builder, closes [#11030](https://github.com/lobehub/lobe-chat/issues/11030) ([7ae24c2](https://github.com/lobehub/lobe-chat/commit/7ae24c2))
* **misc**: Update gtd tools( use editor & update metadata ), closes [#11029](https://github.com/lobehub/lobe-chat/issues/11029) ([4a47ea0](https://github.com/lobehub/lobe-chat/commit/4a47ea0))
* **misc**: Update user memory embedding model selection based on business features ([c026117](https://github.com/lobehub/lobe-chat/commit/c026117))
* **misc**: User memory ([d5ce144](https://github.com/lobehub/lobe-chat/commit/d5ce144))
* **misc**: User memory ([49ffcb5](https://github.com/lobehub/lobe-chat/commit/49ffcb5))
* **misc**: User onboarding ([5e59388](https://github.com/lobehub/lobe-chat/commit/5e59388))
* **misc**: When use usesend to create agent/group, the model should override by lobeAi, closes [#11048](https://github.com/lobehub/lobe-chat/issues/11048) ([754ffe1](https://github.com/lobehub/lobe-chat/commit/754ffe1))
* **misc**: Wrap ConversationArea and ModelSwitchPanel in TooltipGroup for enhanced UI ([672bcf7](https://github.com/lobehub/lobe-chat/commit/672bcf7))

#### What's fixed

* **ci**: Skip backend routes in bundle analyzer build, closes [#10944](https://github.com/lobehub/lobe-chat/issues/10944) ([2fc3b42](https://github.com/lobehub/lobe-chat/commit/2fc3b42))
* **desktop**:  prevent window resize when onboarding, closes [#10887](https://github.com/lobehub/lobe-chat/issues/10887) ([c29c02b](https://github.com/lobehub/lobe-chat/commit/c29c02b))
* **desktop**: Add safe top edge for message container, closes [#10908](https://github.com/lobehub/lobe-chat/issues/10908) ([2558b47](https://github.com/lobehub/lobe-chat/commit/2558b47))
* **i18n**: Translate plugin.ts locale to English, closes [#10972](https://github.com/lobehub/lobe-chat/issues/10972) ([89f89c7](https://github.com/lobehub/lobe-chat/commit/89f89c7))
* **image-generation**: Update chargeBeforeGenerate to return ChargeResult and include configForDatabase in parameters ([4f2a683](https://github.com/lobehub/lobe-chat/commit/4f2a683))
* **memory-user-memory**: Should pre-process date & time, closes [#10979](https://github.com/lobehub/lobe-chat/issues/10979) ([c2bcf73](https://github.com/lobehub/lobe-chat/commit/c2bcf73))
* **observability-otel**: Typo in package name, closes [#11025](https://github.com/lobehub/lobe-chat/issues/11025) ([63224dd](https://github.com/lobehub/lobe-chat/commit/63224dd))
* **prebuild**: Correct syntax in partialBuildPages array ([9580672](https://github.com/lobehub/lobe-chat/commit/9580672))
* **translation**: Add fallback for all English locale variants, closes [#10984](https://github.com/lobehub/lobe-chat/issues/10984) ([ce46996](https://github.com/lobehub/lobe-chat/commit/ce46996))
* **userMemories**: 404/405 issue due to incorrectly used workflow name and mounted catch-all route, closes [#10995](https://github.com/lobehub/lobe-chat/issues/10995) ([45996c6](https://github.com/lobehub/lobe-chat/commit/45996c6))
* **userMemories**: Missing base memory as part of context, closes [#11040](https://github.com/lobehub/lobe-chat/issues/11040) ([3c9bafe](https://github.com/lobehub/lobe-chat/commit/3c9bafe))
* **userMemories**: Must assign workflow id, closes [#11021](https://github.com/lobehub/lobe-chat/issues/11021) ([78b0c7b](https://github.com/lobehub/lobe-chat/commit/78b0c7b))
* **userMemories**: Should use `context.invoke` for workflow instead of `context.run`, closes [#10994](https://github.com/lobehub/lobe-chat/issues/10994) ([6592d10](https://github.com/lobehub/lobe-chat/commit/6592d10))
* **userMemories**: Skip to handle WorkflowAbort, closes [#11031](https://github.com/lobehub/lobe-chat/issues/11031) ([17124a8](https://github.com/lobehub/lobe-chat/commit/17124a8))
* **userMemories**: Use date & time for building context, closes [#10978](https://github.com/lobehub/lobe-chat/issues/10978) ([15bc6bc](https://github.com/lobehub/lobe-chat/commit/15bc6bc))
* **userMemories**: Workflow id build issue, closes [#10998](https://github.com/lobehub/lobe-chat/issues/10998) ([0b110b6](https://github.com/lobehub/lobe-chat/commit/0b110b6))
* **misc**: Agent profiles update, agent tools config set, editor placeholder, closes [#11074](https://github.com/lobehub/lobe-chat/issues/11074) ([f7cbfe4](https://github.com/lobehub/lobe-chat/commit/f7cbfe4))
* **misc**: Bump charts 3.0.4 to fix import es path, closes [#10898](https://github.com/lobehub/lobe-chat/issues/10898) ([6d7dce7](https://github.com/lobehub/lobe-chat/commit/6d7dce7))
* **misc**: Fix anthropic thinking budget ([6e19bd3](https://github.com/lobehub/lobe-chat/commit/6e19bd3))
* **misc**: Fix async task and improve tool style ([1aa1c04](https://github.com/lobehub/lobe-chat/commit/1aa1c04))
* **misc**: Fix default waitlist bug ([de62035](https://github.com/lobehub/lobe-chat/commit/de62035))
* **misc**: Fix delete agent group bug ([0fe0d6f](https://github.com/lobehub/lobe-chat/commit/0fe0d6f))
* **misc**: Fix desktop test cases and refactor translations, closes [#10956](https://github.com/lobehub/lobe-chat/issues/10956) ([568235c](https://github.com/lobehub/lobe-chat/commit/568235c))
* **misc**: Fix desktop test cases and refactor translations, closes [#10955](https://github.com/lobehub/lobe-chat/issues/10955) ([b3520a2](https://github.com/lobehub/lobe-chat/commit/b3520a2))
* **misc**: Fix gemini 3 model thinking issue ([69f4cf3](https://github.com/lobehub/lobe-chat/commit/69f4cf3))
* **misc**: Fix gemini 3 pro parallel tool use ([a0cc9c3](https://github.com/lobehub/lobe-chat/commit/a0cc9c3))
* **misc**: Fix gemini 3 thinking params ([89363b2](https://github.com/lobehub/lobe-chat/commit/89363b2))
* **misc**: Fix identity memory not working, closes [#10916](https://github.com/lobehub/lobe-chat/issues/10916) ([fbd0b66](https://github.com/lobehub/lobe-chat/commit/fbd0b66))
* **misc**: Fix supervisor flag ([fc20dbc](https://github.com/lobehub/lobe-chat/commit/fc20dbc))
* **misc**: Fix thread not working issue ([7dd30eb](https://github.com/lobehub/lobe-chat/commit/7dd30eb))
* **misc**: Fix when use branch topic,the branch index error problem, closes [#11049](https://github.com/lobehub/lobe-chat/issues/11049) ([34b5a32](https://github.com/lobehub/lobe-chat/commit/34b5a32))
* **misc**: Fixed the welcome card the create button not work, closes [#11055](https://github.com/lobehub/lobe-chat/issues/11055) ([00e81f1](https://github.com/lobehub/lobe-chat/commit/00e81f1))
* **misc**: Handle session invalidation on 401 error by logging out signed-in users ([499bd4a](https://github.com/lobehub/lobe-chat/commit/499bd4a))
* **misc**: Improve test infrastructure and mock configurations, closes [#11028](https://github.com/lobehub/lobe-chat/issues/11028) ([da4eb9c](https://github.com/lobehub/lobe-chat/commit/da4eb9c))
* **misc**: Locale resolve bug with ESM module loading, closes [#11018](https://github.com/lobehub/lobe-chat/issues/11018) ([770c872](https://github.com/lobehub/lobe-chat/commit/770c872))
* **misc**: Page agent editor, closes [#10953](https://github.com/lobehub/lobe-chat/issues/10953) ([61b3031](https://github.com/lobehub/lobe-chat/commit/61b3031))
* **misc**: Prevent redundant login redirect when already on auth pages ([1a5049c](https://github.com/lobehub/lobe-chat/commit/1a5049c))
* **misc**: Redis read json object ([1718fa3](https://github.com/lobehub/lobe-chat/commit/1718fa3))
* **misc**: Remove openapi pkg patch file, closes [#10910](https://github.com/lobehub/lobe-chat/issues/10910) ([a34c111](https://github.com/lobehub/lobe-chat/commit/a34c111))
* **misc**: Slove input editor on pause emit, closes [#11051](https://github.com/lobehub/lobe-chat/issues/11051) ([d102d47](https://github.com/lobehub/lobe-chat/commit/d102d47))
* **misc**: Slove swr mutate not work in Cache Provider, closes [#10895](https://github.com/lobehub/lobe-chat/issues/10895) ([b3fbffe](https://github.com/lobehub/lobe-chat/commit/b3fbffe))
* **misc**: Slove the group add member checkbox not work, closes [#11045](https://github.com/lobehub/lobe-chat/issues/11045) [#11042](https://github.com/lobehub/lobe-chat/issues/11042) ([91d3f74](https://github.com/lobehub/lobe-chat/commit/91d3f74))
* **misc**: Slove the model select null problem, closes [#10988](https://github.com/lobehub/lobe-chat/issues/10988) ([50aa304](https://github.com/lobehub/lobe-chat/commit/50aa304))
* **misc**: Slove the mutate not work problem, closes [#10947](https://github.com/lobehub/lobe-chat/issues/10947) ([78ca5eb](https://github.com/lobehub/lobe-chat/commit/78ca5eb))
* **misc**: Slove when click agentbuilder should clean topic, closes [#11068](https://github.com/lobehub/lobe-chat/issues/11068) ([048bd66](https://github.com/lobehub/lobe-chat/commit/048bd66))
* **misc**: Slove when first call thread, not show ai chat message, closes [#10878](https://github.com/lobehub/lobe-chat/issues/10878) ([5a79cb9](https://github.com/lobehub/lobe-chat/commit/5a79cb9))
* **misc**: Support retry error message and fix continueGenerationMessage ([8bf85fb](https://github.com/lobehub/lobe-chat/commit/8bf85fb))
* **misc**: Update contextMenu in group tools message, closes [#11056](https://github.com/lobehub/lobe-chat/issues/11056) ([8b49414](https://github.com/lobehub/lobe-chat/commit/8b49414))
* **misc**: Update OFFICIAL_URL to app.lobehub.com, closes [#11015](https://github.com/lobehub/lobe-chat/issues/11015) ([f9e11d0](https://github.com/lobehub/lobe-chat/commit/f9e11d0))
* **misc**: Update PlanTag link paths for subscription settings ([ada71d3](https://github.com/lobehub/lobe-chat/commit/ada71d3))
* **misc**: Update test snapshots for model description changes, closes [#11008](https://github.com/lobehub/lobe-chat/issues/11008) ([626e808](https://github.com/lobehub/lobe-chat/commit/626e808))
* **misc**: When use agentbuilder the topic id should use new & clear topic…, closes [#10983](https://github.com/lobehub/lobe-chat/issues/10983) ([0b2b096](https://github.com/lobehub/lobe-chat/commit/0b2b096))

#### Styles

* **misc**: Improve ExecTask and task message UI ([977a700](https://github.com/lobehub/lobe-chat/commit/977a700))
* **misc**: Improve gtd tool inspector and todo list ([0664563](https://github.com/lobehub/lobe-chat/commit/0664563))
* **misc**: Improve page document tool inspector UI, closes [#10977](https://github.com/lobehub/lobe-chat/issues/10977) ([7f69cb1](https://github.com/lobehub/lobe-chat/commit/7f69cb1))
* **misc**: Improve RunCommand Inspector ([0751fa4](https://github.com/lobehub/lobe-chat/commit/0751fa4))
* **misc**: Rebranding chat ui ([ad14222](https://github.com/lobehub/lobe-chat/commit/ad14222))
* **misc**: Refactor UI in features ([83e689f](https://github.com/lobehub/lobe-chat/commit/83e689f))
* **misc**: Rerun i18n ([80f511c](https://github.com/lobehub/lobe-chat/commit/80f511c))
* **misc**: Setting style ([e8c755f](https://github.com/lobehub/lobe-chat/commit/e8c755f))
* **misc**: Support streaming and display ui for group mode ([f708cdb](https://github.com/lobehub/lobe-chat/commit/f708cdb))
* **misc**: Support tool streaming and title custom render, closes [#10976](https://github.com/lobehub/lobe-chat/issues/10976) ([576ccd6](https://github.com/lobehub/lobe-chat/commit/576ccd6))
* **misc**: Update i18n ([2e6fd07](https://github.com/lobehub/lobe-chat/commit/2e6fd07))
* **misc**: Update i18n microcopy, closes [#10905](https://github.com/lobehub/lobe-chat/issues/10905) ([024aeb2](https://github.com/lobehub/lobe-chat/commit/024aeb2))
* **misc**: Update ui ([1693fc5](https://github.com/lobehub/lobe-chat/commit/1693fc5))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2025-12-31 14:28:13 +00:00
arvinxx 876a1d40ef Revert " test: add unit tests for EdgeConfig module (#11069)"
This reverts commit 377b5388c3.
2025-12-31 22:09:01 +08:00
LobeHub Bot 377b5388c3 test: add unit tests for EdgeConfig module (#11069)
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:00:41 +08:00
Arvin Xu f7d724fb87 feat: brand new 2.0 ui for next 2025-12-31 21:55:39 +08:00
YuTengjing b96363d8c0 🔧 chore: update business interface and test fixes (#11077) 2025-12-31 21:30:07 +08:00
arvinxx 8fe36548d6 ♻️ refactor rename code-interpreter to cloud-sandbox 2025-12-31 20:30:11 +08:00
arvinxx 9ea3df62b3 ♻️ refactor rename code-interpreter to cloud-sandbox 2025-12-31 20:27:37 +08:00
YuTengjing e48aac72b2 🔧 chore: limit max image num to 8 when business features enabled 2025-12-31 20:22:45 +08:00
Shinji-Li 2a631b476f feat: rename codeinterpreter into lobe sandbox (#11076)
* feat: rename codeinterpreter into lobe sandbox

* fix: fixed the market publish agent too much
2025-12-31 20:02:18 +08:00
YuTengjing 954789dc4e feat: add createImageBusinessMiddleware to enhance image creation process
- Introduced createImageBusinessMiddleware for additional processing in the createImage mutation.
- Updated imageRouter to utilize the new middleware, improving the structure and maintainability of the image generation logic.
2025-12-31 20:02:18 +08:00
YuTengjing 39aa01b444 refactor: move async jwt auth to async auth middleware 2025-12-31 20:02:18 +08:00
canisminor1990 e8c755f532 💄 style: setting style 2025-12-31 20:02:18 +08:00
arvinxx 8bf85fb251 🐛 fix: support retry error message and fix continueGenerationMessage 2025-12-31 18:23:59 +08:00
YuTengjing 7a532eee92 🔒 security: replace KEY_VAULTS_SECRET with JWT signing for async router auth
- Add JWKS_KEY env variable with fallback to OIDC_JWKS_KEY
- Add signInternalJWT() and validateInternalJWT() in internalJwt.ts
- Use short-lived JWT (3s) with purpose claim to authenticate lambda → async calls
- Remove KEY_VAULTS_SECRET from Authorization header transmission
- Update OIDC provider to use JWKS_KEY from authEnv
- Update documentation for JWKS_KEY and desktop sync
2025-12-31 18:06:02 +08:00
Rene Wang 0f0eb40b41 refac: Use SDK to submit feedback 2025-12-31 17:57:59 +08:00
Rene Wang 99c18702d2 fix: Highlight style 2025-12-31 17:37:56 +08:00
arvinxx 0751fa48c6 💄 style: improve RunCommand Inspector 2025-12-31 17:13:44 +08:00
arvinxx 89363b277e 🐛 fix: fix gemini 3 thinking params 2025-12-31 17:13:44 +08:00
YuTengjing bbf62ce97c feat(referral): add backfill referral code i18n keys
Add translations for backfill referral code feature:
- errors.alreadyBound, errors.backfillExpired, errors.invalidCode, errors.selfReferral
- rules.backfill.* (title, description, placeholder, submit, success, etc.)
- rules.missedCode with link component
2025-12-31 17:00:32 +08:00
Shinji-Li f7cbfe4497 🐛 fix: agent profiles update, agent tools config set, editor placeholder (#11074)
* feat: open the gtd & document tools in normal agent

* feat: add getAllbuildintools in agent profles tools settings

* fix: slove the tools modal segment not work

* feat: support editor placeholder
2025-12-31 16:45:20 +08:00
Innei f26bbc56de chore: change lobehub/ui exported const
Signed-off-by: Innei <tukon479@gmail.com>
2025-12-31 16:32:16 +08:00
YuTengjing 1718fa378a 🔧 fix: redis read json object 2025-12-31 16:30:24 +08:00
Rene Wang 1c47de378d feat: Create folder in the modal 2025-12-31 16:28:50 +08:00
YuTengjing 15722f1e27 feat: implement Redis caching for presigned URLs in file proxy service
- Added Redis integration to cache presigned URLs, reducing S3 API calls.
- Implemented cache hit/miss logic to improve performance.
- Set cache expiration time to 4 minutes.
2025-12-31 16:18:41 +08:00
YuTengjing 5a93639cbd chore: remove @lobehub/ui from devDependencies in package.json 2025-12-31 16:02:16 +08:00
canisminor1990 08b2444b1c style: update cloud style 2025-12-31 15:43:12 +08:00
canisminor1990 ddb4c2ac7c style: update cloud style 2025-12-31 15:43:11 +08:00
arvinxx 1c2723c5db 🔧 chore: unpin lobehub and antd-style 2025-12-31 15:34:14 +08:00
arvinxx a0cc9c3354 🐛 fix: fix gemini 3 pro parallel tool use 2025-12-31 15:20:11 +08:00
arvinxx 80f511cd6e 🌐 style: rerun i18n 2025-12-31 15:20:11 +08:00
arvinxx 5cfb4a5e0e 🔒 chore: remove error stack 2025-12-31 15:19:16 +08:00
YuTengjing ada71d386d 🔗 fix: update PlanTag link paths for subscription settings
- Change the link paths in PlanTag component to direct users to '/settings/plans' and '/settings/usage' based on the isFree flag, improving navigation consistency.
2025-12-31 15:06:22 +08:00
Innei f5314c5c32 ♻️ refactor: improve modal handling with createRawModal (#11071)
* feat: integrate TooltipGroup into SideBarLayout for enhanced UI interactions

Signed-off-by: Innei <tukon479@gmail.com>

* feat: refactor components to utilize createRawModal for improved modal handling and enhance UI interactions with TooltipGroup

Signed-off-by: Innei <tukon479@gmail.com>

* chore: update @lobehub/ui dependency to version 4.5.0 in package.json

Signed-off-by: Innei <tukon479@gmail.com>

---------

Signed-off-by: Innei <tukon479@gmail.com>
2025-12-31 15:03:24 +08:00
Innei f9d991b26c Merge branch 'next' into dev 2025-12-31 14:58:42 +08:00
YuTengjing 98f75cff6a 🔧 chore: update prebuild script to echo environment variables
- Modify the prebuild script in package.json to include echo statements for NEXT_PUBLIC_AUTH_URL, NEXTAUTH_URL, APP_URL, and VERCEL_URL, enhancing visibility of environment variables during the build process.
2025-12-31 14:54:06 +08:00
YuTengjing c026117d1a feat: update user memory embedding model selection based on business features
- Import BRANDING_PROVIDER and ENABLE_BUSINESS_FEATURES constants.
- Modify getEmbeddingRuntime to select the model provider based on the ENABLE_BUSINESS_FEATURES flag, enhancing flexibility in model usage.
2025-12-31 14:38:54 +08:00
canisminor1990 e62d6cc1a1 style: update style 2025-12-31 14:23:38 +08:00
Innei 475065e081 ♻️ refactor: remove desktop-specific upload logic (#11070)
- Remove isDesktop check for upload flow
- Remove uploadToDesktopS3 method
- Clean up related mocks in tests
- Simplify upload service to use server-side logic only

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-31 14:16:10 +08:00
Rene Wang e3dd7ff16c feat: Open feedback with CMDK 2025-12-31 13:28:32 +08:00
Shinji-Li 048bd66ce0 🐛 fix: slove when click agentbuilder should clean topic (#11068)
fix: slove when click agentbuilder should clean topic
2025-12-31 12:14:10 +08:00
Rene Wang 8b1c0a4a13 feat: Submit feedback to Linear 2025-12-31 11:47:24 +08:00
Rene Wang ab683abf18 feat: Submit feedback to Linear 2025-12-31 11:45:48 +08:00
Rene Wang a155693acf feat: Submit feedback to Linear 2025-12-31 11:39:45 +08:00
Arvin Xu 8560a6bf29 test: agent e2e case for user journey (#11063)
*  test(e2e): add Agent conversation E2E test with LLM mock

- Add LLM mock framework to intercept /webapi/chat/openai requests
- Create Agent conversation journey test (AGENT-CHAT-001)
- Add data-testid="chat-input" to Desktop ChatInput for E2E testing
- Mock returns SSE streaming responses matching LobeChat's actual format

Test scenario: Enter Lobe AI → Send "hello" → Verify AI response

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* 📝 docs(e2e): add E2E testing guide for Claude

Document key learnings from implementing Agent conversation test:
- LLM Mock SSE format and usage
- Desktop/Mobile dual component handling with boundingBox
- contenteditable input handling
- Debugging tips and common issues

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* 📝 docs(e2e): add experience-driven E2E testing strategy

Add comprehensive testing strategy from LOBE-2417:
- Core philosophy: user experience baseline for refactoring safety
- Product architecture coverage with priority levels
- Tag system (@journey, @P0/@P1/@P2, module tags)
- Execution strategies for CI, Nightly, and Release
- Updated directory structure with full journey coverage plan

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* add conversation case

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 10:10:40 +08:00
arvinxx b5d33e6564 tests: add more tests case 2025-12-31 09:28:56 +08:00
Arvin Xu a9a93c15ae test: fix e2e tests for new product flow (#11060)
* add e2e tests

* fix workflow

* update workflow

* 🐛 fix(e2e): fix smoke tests i18n and timeout issues

- Unify default port to 3006 across hooks.ts and world.ts
- Reduce step timeout from 30s to 10s for faster feedback
- Fix i18n matching for featured sections (support zh-CN/en-US)
- Add mock framework foundation for future API mocking

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* 🐛 fix(e2e): save failure screenshots to file for CI artifacts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* 🐛 fix(e2e): move PORT to global env for consistent access

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* 🐛 fix(e2e): set onboarding as completed for test user

Skip onboarding flow by setting finishedAt in test user seed
2025-12-31 02:13:32 +08:00
arvinxx 6e19bd3d4c 🐛 fix: fix anthropic thinking budget 2025-12-31 01:49:42 +08:00
arvinxx 69f4cf3dd9 🐛 fix: fix gemini 3 model thinking issue 2025-12-31 01:15:50 +08:00
arvinxx 7d65b51e0c tests: fix tests 2025-12-31 00:08:49 +08:00
arvinxx fc20dbca36 🐛 fix: fix supervisor flag 2025-12-30 23:39:46 +08:00
Zhijie He 5034fd02d4 👷 build: fix docker image build error, missing patches folder (#11059)
fix: fix docker image build error, missing `patches` folder
2025-12-30 23:39:46 +08:00
YuTengjing 8f2d57d968 feat: include Subscription settings group in the Accordion component 2025-12-30 23:39:46 +08:00
YuTengjing 2ddc876a4c feat: add subscription settings group with dynamic loading for Plans, Funds, Usage, Billing, and Referral tabs 2025-12-30 23:39:46 +08:00
YuTengjing ea11a2b506 🔧 chore: update ESLint rules to be commented out, enhance manifest for development mode, and adjust Welcome component username prop 2025-12-30 23:39:46 +08:00
canisminor1990 dd5b28b4ad style: task style 2025-12-30 23:39:46 +08:00
YuTengjing 35c6ad909b feat: add business settings features with dynamic loading for Plans, Funds, Usage, Billing, and Referral tabs 2025-12-30 20:43:41 +08:00
Rene Wang 0f94fa9968 feat: Add error boundary 2025-12-30 20:27:36 +08:00
canisminor1990 88abd1bbd1 style: update supervisor 2025-12-30 20:11:43 +08:00
YuTengjing d6419e4903 feat: refactor authentication handler to support dynamic loading of better-auth and next-auth 2025-12-30 19:40:28 +08:00
YuTengjing 0b1c7812ba 🔧 chore: downgrade better-auth package versions to 1.4.6 2025-12-30 18:59:49 +08:00
canisminor1990 f4d420076b style: fix some style 2025-12-30 18:54:23 +08:00
Shinji-Li eb97bf696b 🔨 chore: update editor version (#11057)
chore: update editor version
2025-12-30 18:38:37 +08:00
Shinji-Li 8b494142ea 🐛 fix: update contextMenu in group tools message (#11056)
feat: update contextMenu in group tools message
2025-12-30 18:29:06 +08:00
canisminor1990 7367093191 style: update actions bar 2025-12-30 18:21:10 +08:00
YuTengjing 499bd4a722 🐛 fix: handle session invalidation on 401 error by logging out signed-in users 2025-12-30 18:16:49 +08:00
Shinji-Li 00e81f1abd 🐛 fix: fixed the welcome card the create button not work (#11055)
fix: slove the welcome card create agent button problem
2025-12-30 18:15:26 +08:00
canisminor1990 e056a69a94 style: update typing speed 2025-12-30 18:03:41 +08:00
canisminor1990 ed694f202f style: update desktop onboarding 2025-12-30 18:01:47 +08:00
canisminor1990 0bb6b44fcd style: update desktop onboarding 2025-12-30 17:48:13 +08:00
YuTengjing cdd7a9239d 🔧 chore: update better-auth version to a fixed release 2025-12-30 17:43:57 +08:00
Shinji-Li d102d47577 🐛 fix: slove input editor on pause emit (#11051)
fix: slove input editor on pause emit
2025-12-30 17:30:25 +08:00
YuTengjing 1a5049c5b0 🐛 fix: prevent redundant login redirect when already on auth pages 2025-12-30 17:05:49 +08:00
arvinxx 1fa4357963 ♻️ refactor: move code-interpreter to single packages 2025-12-30 17:04:43 +08:00
arvinxx 784bb5806a ♻️ refactor: refactor to use better underline style 2025-12-30 17:04:42 +08:00
Innei efe18bf762 ♻️ chore: move desktop onboarding route file path 2025-12-30 16:57:31 +08:00
Rene Wang 43d506cfa4 lint: Use createStyles instead of CSS-in-JS 2025-12-30 16:55:54 +08:00
Innei 4faa65c6af feat(model): improve model list UI and add disabled models management (#11036)
*  feat(model): improve model list UI and add disabled models management

- Enhanced DisabledModels component with better UI/UX
- Updated ModelList layout and interactions
- Added repository methods for disabled model management
- Improved AI model service and router functionality
- Added tests for new functionality

*  feat(DisabledModels): enhance loading and rendering logic for disabled models

- Implemented pagination and dynamic loading for disabled models
- Improved state management for visible models and loading conditions
- Ensured unique model entries in the displayed list
- Updated component to handle provider changes effectively

Signed-off-by: Innei <tukon479@gmail.com>

* fix(DisabledModels): handle edge case for last page in pagination logic

- Added a check to ensure lastPage is defined before evaluating pagination end conditions
- Improved robustness of loading state management in DisabledModels component

Signed-off-by: Innei <tukon479@gmail.com>

* lint

* lint

* lint

---------

Signed-off-by: Innei <tukon479@gmail.com>
2025-12-30 16:49:12 +08:00
YuTengjing 381cf51ec0 refactor: simplify prebuild script by removing environment variable echoes 2025-12-30 16:33:22 +08:00
YuTengjing 6b5ce79e56 feat: integrate BrandingProviderCard and update Provider components for branding support 2025-12-30 16:33:21 +08:00
Rene Wang adcc987faf lint: Clean up code 2025-12-30 16:30:38 +08:00
Shinji-Li 34b5a32aa1 🐛 fix: fix when use branch topic,the branch index error problem (#11049)
fix: fix when use branch topic,the branch index error problem
2025-12-30 16:25:01 +08:00
arvinxx 5e10ac8d88 ♻️ refactor: refactor to use better underline style 2025-12-30 16:21:41 +08:00
canisminor1990 73b773260b style: update ChatInput 2025-12-30 16:16:54 +08:00
Innei 9db8da82f6 feat: enhance macOS desktop permissions and onboarding (#11016)
* feat: enhance macOS desktop permissions and onboarding

- Improve screen recording access request with dual-method approach
  (Electron API + getDisplayMedia trigger for TCC registration)
- Add auto-add functionality for Full Disk Access using AppleScript
- Make onboarding flow platform-aware (skip Screen3 on non-macOS)
- Add NSAppleEventsUsageDescription and NSScreenCaptureUsageDescription
- Add comprehensive unit tests for permission flows

* feat: implement full disk access automation and enhance onboarding messages

* feat: enhance Screen5 with context menu support and update theme background color
2025-12-30 16:06:44 +08:00
canisminor1990 98df0d144f style: add chat appearance 2025-12-30 15:58:14 +08:00
Rene Wang 5d8a0acc73 lint: Rename varibles 2025-12-30 15:57:24 +08:00
canisminor1990 752f4e51ff style: update stats 2025-12-30 15:46:14 +08:00
YuTengjing 8b6c30ebef feat: enhance onboarding process by removing mode selection step and adding export functionality in advanced settings 2025-12-30 15:31:04 +08:00
YuTengjing 1dccc04a29 feat: add business features support with new components and hooks 2025-12-30 14:57:00 +08:00
Rene Wang d3012ce677 fix: Upload file 2025-12-30 14:45:51 +08:00
Shinji-Li 754ffe1de2 feat: when use usesend to create agent/group, the model should override by lobeAi (#11048)
feat: when use usesend to create agent/group, the model should override by LobeAI
2025-12-30 14:39:41 +08:00
arvinxx 80587aeb7e feat: add batch tasks ui 2025-12-30 14:38:02 +08:00
arvinxx d780fa82ab 📸 tests: add test fixtures 2025-12-30 14:38:02 +08:00
Rene Wang 2cc5c6611f lint: Remove ocnosle.log 2025-12-30 14:04:56 +08:00
Rene Wang 84467157ac fix: Button hover 2025-12-30 14:00:47 +08:00
arvinxx a2582f285e tests: fix tests 2025-12-30 13:04:14 +08:00
arvinxx 0fe0d6f86f 🐛 fix: fix delete agent group bug 2025-12-30 12:33:53 +08:00
Shinji-Li 91d3f746c7 🐛 fix: slove the group add member checkbox not work (#11045)
* fix: slove wait list always jupm wait problem

* 🐛 fix: slove wait list always jump wait problem (#11042)

fix: slove wait list always jupm wait problem

* fix: roll back state.isInWaitList judge problem

* fix: slove the group add member checkbox notwork
2025-12-30 12:07:24 +08:00
Rene Wang 41f1005dfa fix: Border radius of dock 2025-12-30 12:02:47 +08:00
Rene Wang f9595f0dfa fix: Drag stuck 2025-12-30 11:52:03 +08:00
Shinji-Li 977a700615 💄 style: improve ExecTask and task message UI 2025-12-30 11:40:50 +08:00
arvinxx de62035979 🐛 fix: fix default waitlist bug 2025-12-30 09:54:59 +08:00
Neko 3c9bafee6f 🐛 fix(userMemories): missing base memory as part of context (#11040) 2025-12-30 03:52:00 +08:00
Neko ab61c69fef feat(userMemories): use honorific title for identity memory (#11039) 2025-12-30 03:50:23 +08:00
Neko 1cc0e8c375 feat(userMemories): apply userMemories.enable from settings for injecting (#11038) 2025-12-30 03:44:33 +08:00
Neko 5615d20d45 feat(userMemories): use capturedAt for time of memory entries (#11037) 2025-12-30 03:43:44 +08:00
arvinxx a3fc406b7d 🚨 chore: fix lint 2025-12-30 01:25:41 +08:00
arvinxx cd78e5f196 tests: fix tests 2025-12-30 01:19:26 +08:00
arvinxx f708cdb901 💄 style: support streaming and display ui for group mode 2025-12-30 01:11:24 +08:00
arvinxx 30cb4dfb93 move web-browsing 2025-12-30 01:11:24 +08:00
arvinxx 3b01174d4f ♻️ refactor: use /f/:fid as file mode 2025-12-30 00:41:00 +08:00
arvinxx 0ca823fc56 ♻️ refactor: use supervisor role for agent group supervisor 2025-12-29 23:59:11 +08:00
Innei 98bc8567a1 chore: update @lobehub/ui dependency to version 4.4.0 in package.json
Signed-off-by: Innei <tukon479@gmail.com>
2025-12-29 22:27:05 +08:00
YuTengjing 52c7a4928a feat(layout): integrate BusinessGlobalProvider for conditional rendering based on business features 2025-12-29 22:05:24 +08:00
YuTengjing 991d8c1874 feat(auth): enhance BetterAuthSignUpForm with businessElement and update useSignUp hook for improved signup process 2025-12-29 21:52:44 +08:00
YuTengjing 3efb6cc3f1 feat(auth): add useBusinessSignup hook for business signup functionality 2025-12-29 21:44:14 +08:00
Rene Wang bb1a6d65fa opti: Better performance 2025-12-29 21:41:22 +08:00
YuTengjing c8e3bc90b3 feat(auth): update useBusinessSignin to include getAdditionalData function for enhanced sign-in process 2025-12-29 21:40:52 +08:00
canisminor1990 149315c427 fix: fix style issues 2025-12-29 21:33:17 +08:00
canisminor1990 f4ef1f7d96 fix: fix style issues 2025-12-29 21:22:34 +08:00
YuTengjing 2ccd5c78f5 feat(auth): add confirm password field and integrate business signup logic 2025-12-29 21:10:39 +08:00
YuTengjing 6dc79162f0 feat(auth): integrate business sign-in features and update social sign-in logic 2025-12-29 21:10:38 +08:00
Shinji-Li 74d35554f2 feat: gtd create plan support streaming render (#11034)
feat: add the gtd stream render
2025-12-29 21:05:24 +08:00
Innei 34a6312668 feat: enhance desktop onboarding with sign out and localization (#11033)
*  feat(onboarding): add English and Chinese localization for desktop onboarding screens

*  feat(onboarding): implement sign out functionality and enhance onboarding experience

*  feat(remote-server): implement broadcast for remote server configuration updates

* update
2025-12-29 21:03:08 +08:00
arvinxx 1aa1c04a8d 🐛 fix: fix async task and improve tool style 2025-12-29 21:01:11 +08:00
Rene Wang 7fce85ea88 refac: Better resource manager 2025-12-29 20:52:56 +08:00
canisminor1990 e3df7f6e24 style: fix style issues 2025-12-29 20:49:47 +08:00
YuTengjing 821d57e56e chore: remove JSON validation from ESLint settings in VSCode configuration 2025-12-29 20:26:15 +08:00
Shinji-Li 4a47ea0d2f feat: update gtd tools( use editor & update metadata ) (#11029)
* feat: use lobehub editor to modify gtd plan

* merge origin/dev

* feat: show todo in doc portal

* feat: use the todoProcess in docs portal

* feat: add gtd context engine inject
2025-12-29 20:20:11 +08:00
Neko Ayaka 8786628016 fix: duplicated alias of vitest config 2025-12-29 18:52:41 +08:00
Neko 17124a8e73 🐛 fix(userMemories): skip to handle WorkflowAbort (#11031) 2025-12-29 18:48:07 +08:00
YuTengjing 85df0bc8ca chore: add JSON validation to ESLint settings in VSCode configuration 2025-12-29 17:58:03 +08:00
Shinji-Li 7ae24c2163 feat: update create group chat use builder (#11030)
feat: change the create group button to direction group/profile
2025-12-29 17:57:02 +08:00
arvinxx dba1acf2b4 feat: support exec async sub agent task 2025-12-29 17:50:38 +08:00
arvinxx 6099ac380a ♻️ refactor: refactor tool prompt injection 2025-12-29 17:49:08 +08:00
arvinxx be2b41c792 ♻️ refactor: refactor with editor runtime 2025-12-29 17:43:10 +08:00
YuTengjing 37e33b8b73 docs: update CLAUDE.md to reflect repository name change and clarify git workflow 2025-12-29 16:59:44 +08:00
canisminor1990 8d947ceefc feat: codemirror 2025-12-29 16:59:23 +08:00
huangkairan 812ed7db15 fix: updater not work on Windows (#11027) 2025-12-29 16:55:51 +08:00
Innei da4eb9c1b1 🧪 fix: improve test infrastructure and mock configurations (#11028)
* 🧪 fix: improve test infrastructure and mock configurations

- Add vitest plugin to fix @lobehub/fluent-emoji style import issue
- Update antd-style mocks to preserve actual exports while mocking specific functions
- Switch from useClientDataSWR to useClientDataSWRWithSync in tests
- Add @/utils/identifier alias in vitest config
- Fix duplicate @lobehub/ui mock in ComfyUIForm test

* 🐛 fix: use recommended-legacy for ESLint 8 compatibility

The @next/eslint-plugin-next v16 changed to flat config format which is
incompatible with ESLint 8. Using recommended-legacy to maintain compatibility.
2025-12-29 16:54:06 +08:00
YuTengjing 8b67718158 docs: update subscription locale json 2025-12-29 16:48:39 +08:00
YuTengjing db5e02bac8 feat: expose useBusinessTTSProvider hook 2025-12-29 16:42:34 +08:00
YuTengjing d257a06887 feat: expose markUserValidAction business interface 2025-12-29 16:38:29 +08:00
YuTengjing bbe7a050b7 docs: expose cloud locales 2025-12-29 16:22:22 +08:00
Rene Wang 3942de130e style: Hide save label while loading 2025-12-29 15:37:51 +08:00
Rene Wang 61119dee74 opti: Use useSWR to cache request 2025-12-29 15:37:51 +08:00
Innei 95806721ba 🐛 fix(prebuild): correct syntax in partialBuildPages array
- Fixed the syntax of the partialBuildPages array in prebuild.mts by replacing a trailing comma with a closing brace.
- Ensured proper structure for the array to avoid potential runtime errors.

Signed-off-by: Innei <tukon479@gmail.com>
2025-12-29 14:38:43 +08:00
Innei 5380f76ed1 🔧 chore: increase NODE_OPTIONS memory limit to 8GB across configurations
- Updated NODE_OPTIONS from 6144MB to 8192MB in Dockerfile, package.json scripts, GitHub workflows, and environment configurations.
- Ensured consistent memory allocation for builds and tests to improve performance.

Signed-off-by: Innei <tukon479@gmail.com>
2025-12-29 14:35:04 +08:00
Innei 2fc3b4238a 🐛 fix(ci): skip backend routes in bundle analyzer build (#10944)
- Add isBundleAnalyzer check in prebuild script to skip backend routes when ANALYZE=true && CI=true
- Update bundle analyzer workflow to use fallback KEY_VAULTS_SECRET from generate-secret step
- Increase NODE_OPTIONS memory limit to 8GB
- Remove unnecessary S3_PUBLIC_DOMAIN and APP_URL env vars

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-29 13:51:03 +08:00
Innei 04de37b0ec 🔧 chore(deps): upgrade Next.js from 16.1.0 to 16.1.1 (#10949)
Upgrade Next.js and related packages to 16.1.1:
- next: 16.1.0 → 16.1.1
- @next/third-parties: 16.1.0 → 16.1.1
- @next/bundle-analyzer: 16.1.0 → 16.1.1
- @next/eslint-plugin-next: 15.5.9 → 16.1.1

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-29 13:32:52 +08:00
Innei 596e489d74 feat: add Bundle Analyzer workflow for detailed bundle size analysis
Signed-off-by: Innei <tukon479@gmail.com>
2025-12-29 13:29:40 +08:00
Innei f9e11d03df 🐛 fix: update OFFICIAL_URL to app.lobehub.com (#11015)
fix: update OFFICIAL_URL to app.lobehub.com

Update OFFICIAL_URL from https://lobechat.com to https://app.lobehub.com

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-29 13:24:10 +08:00
Innei 770c87256b 🐛 fix: locale resolve bug with ESM module loading (#11018)
* 🐛 fix: simplify translation key access and add fallback logic

- Remove special handling for 'models' and 'providers' namespaces in create.ts
- Use flat key structure (direct object access) instead of nested get()
- Add fallback to default module when locale JSON is missing
- Add tests for missing key fallback behavior

* 🐛 fix: locale resolve bug with ESM module loading

Fix locale resolution in desktop and server environments by properly handling ESM module loading and adding fallback logic for translation namespaces.

Also move lexical from devDependencies to dependencies in builtin-tool-page-agent to fix type-check issues.
2025-12-29 13:19:51 +08:00
Neko 63224dd1a4 🐛 fix(observability-otel): typo in package name (#11025) 2025-12-29 11:40:29 +08:00
Neko 6f0574ddfd feat(observability-otel,userMemories): implemented upstash workflow tracing (#11024) 2025-12-29 11:38:06 +08:00
Rene Wang 61fe7849d7 impr: Quit guard 2025-12-29 11:10:52 +08:00
Rene Wang dcd54f50f1 feat: Limit title length 2025-12-29 11:02:18 +08:00
Neko Ayaka 6ad7cd518c fix(userMemories): completely removed serveMany 2025-12-29 05:25:40 +08:00
Neko c4a5055081 🔨 chore(userMemories): debug with more console (#11022) 2025-12-29 04:06:06 +08:00
Neko 78b0c7be9b 🐛 fix(userMemories): must assign workflow id (#11021) 2025-12-29 03:31:01 +08:00
Neko 02a3cc796f 🔨 chore(userMemories): debug memory workflow keep stucking (#11020) 2025-12-29 02:58:51 +08:00
arvinxx 0f57b8aacc refactor for execSubAgentTask 2025-12-29 00:34:53 +08:00
arvinxx 0664563da7 💄 style: improve gtd tool inspector and todo list 2025-12-29 00:34:53 +08:00
Innei e935ddcbe4 test: update test snapshots for i18n model description changes
Updated model descriptions in test snapshots from Chinese to English to align with model-bank package updates.

Changes:
- Fixed descriptions in parseModels.test.ts for gpt-4o, gpt-4o-mini, and o1-mini
- Fixed descriptions in openaiCompatibleFactory/index.test.ts for claude-3-haiku-20240307 with correct smart quote (U+2019)
- Updated related snapshot files for responsesStream, novita, openai, and ppio providers

All tests passing:
- parseModels.test.ts: 49 tests ✓
- openaiCompatibleFactory/index.test.ts: 65 tests ✓
2025-12-28 22:25:27 +08:00
arvinxx 9ede8e7ffd ♻️ refactor: refactor builtin-tool implement 2025-12-28 13:07:43 +08:00
canisminor1990 bfd88a1df2 style: fix style issues 2025-12-28 12:42:36 +08:00
YuTengjing 2f2264da49 fix: update EnableSwitch logic to conditionally render based on ENABLE_BUSINESS_FEATURES 2025-12-28 01:26:07 +08:00
canisminor1990 0659d4f88d style: fix menu border 2025-12-28 01:19:49 +08:00
YuTengjing e83885670d fix: update ENABLED_LOBEHUB logic and enhance server global config with business features 2025-12-28 01:15:08 +08:00
YuTengjing 333355d77a fix: update waitlist redirection logic to check pathname 2025-12-28 00:38:42 +08:00
YuTengjing 15fd41342a chore: remove unneed business logic 2025-12-28 00:00:44 +08:00
YuTengjing 38016e73cb style: optimize waitList ux 2025-12-28 00:00:44 +08:00
CanisMinor d865e27d58 ♻️ refactor: refactor static style (#11010)
* refactor: refactor static style

* refactor: refactor static style

* refactor: refactor static style

* refactor: refactor static style

* refactor: refactor static style

* refactor: refactor static style

* refactor: refactor static style

* refactor: refactor static style

* refactor: refactor static style

* refactor: refactor static style

* refactor: refactor static style

* refactor: refactor static style

* refactor: refactor static style

* refactor: refactor static style

* refactor: refactor static style

* refactor: refactor static style
2025-12-27 23:51:21 +08:00
YuTengjing ba4834ff84 feat: add businessErrorsLocales and businessLocales to error handling 2025-12-27 20:38:38 +08:00
YuTengjing b8e5715766 feat: add businessLocales to default resources 2025-12-27 20:33:10 +08:00
YuTengjing c963a47474 refactor: BusinessGlobalService file rename 2025-12-27 20:11:26 +08:00
YuTengjing 0e35629529 Revert "chore: rename filename BusinessGlobalService"
This reverts commit b3e77ffae6.
2025-12-27 20:10:25 +08:00
YuTengjing b3e77ffae6 chore: rename filename BusinessGlobalService 2025-12-27 20:09:09 +08:00
YuTengjing 5d4c0694a9 feat: introduce BusinessGlobalService and extend GlobalService 2025-12-27 20:00:34 +08:00
YuTengjing c2acb551f6 refactor: change access modifiers for getValue and getValues methods in EdgeConfig class 2025-12-27 19:56:11 +08:00
YuTengjing c923e0a716 feat: add business configuration endpoints to lambda router 2025-12-27 19:51:41 +08:00
YuTengjing 6b2154d165 feat: ready for cloud client 2025-12-27 19:21:01 +08:00
arvinxx 7a3d25be7f Revert " feat: add a white waitlist in edge config env (#11009)"
This reverts commit 88f22f4f2d.
2025-12-27 19:07:28 +08:00
Shinji-Li 88f22f4f2d feat: add a white waitlist in edge config env (#11009)
feat: add a white waitlist in edge config
2025-12-27 17:40:36 +08:00
Innei 626e808a1c 🐛 fix: update test snapshots for model description changes (#11008)
fix: update test snapshots for model description changes

Update test snapshots to reflect English model descriptions replacing Chinese ones.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-27 16:57:58 +08:00
Innei a763f12fd3 build: add assertions to electron workflow modifiers (#11003)
- Add post-condition assertions to all file modification operations
- Add verify-desktop-patch.yml workflow for CI validation
- Add invariant, updateFile, writeFileEnsuring, removePathEnsuring utilities
- Improve error messages and validation in workflow scripts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-27 02:04:53 +08:00
lobehubbot e96c014426 📝 docs(bot): Auto sync agents & plugin to readme 2025-12-26 16:34:51 +00:00
semantic-release-bot 527bcf3fdc 🔖 chore(release): v2.0.0-next.180 [skip ci]
## [Version&nbsp;2.0.0-next.180](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.179...v2.0.0-next.180)
<sup>Released on **2025-12-26**</sup>

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2025-12-26 16:33:28 +00:00
Innei e409ec8725 👷 build: add manual desktop build workflow (#11002)
👷 feat: add manual desktop build workflow

Add GitHub Actions workflow for manually triggering desktop builds across all platforms (macOS, Windows, Linux) with configurable release channels (nightly, beta, stable) and optional version override.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-27 00:18:51 +08:00
YuTengjing 841f3e4db5 fix: make models property optional in RouterInstance interface 2025-12-27 00:09:51 +08:00
YuTengjing 87dac5f426 chore: export edge config types 2025-12-26 23:53:54 +08:00
YuTengjing 548f41ddfb refactor: move edge-config to npm package 2025-12-26 23:49:40 +08:00
YuTengjing d2a14620a2 chore: remove outdated @auth/core dependency from package.json 2025-12-26 23:19:28 +08:00
YuTengjing 5e521d2fb5 chore: update package dependencies in database and utils 2025-12-26 22:54:06 +08:00
Arvin Xu 563927b55c 👷 build: fix deps not correct set in packages (#11001)
fix deps
2025-12-26 22:38:16 +08:00
Neko 2c86cfd877 🔨 chore(@upstash/qstash): debug 400 error not shown issue (#11000) 2025-12-26 22:22:30 +08:00
LobeHub Bot 6da2a8d4df test: add unit tests for keyboard module (#10861)
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 22:06:14 +08:00
Shinji-Li 134788961d 🐛 fix slove when have market scerat key should direct publish agnet (#10999)
fix: slove when have market scerat key  should direct publish agnet
2025-12-26 21:31:26 +08:00
Innei 704ef7f2cf feat: update agent builder ui (#10996)
* refactor: remove memoization from InputArea component and adjust Flexbox padding in Checker component

* style: enhance layout and spacing in ProviderMenu and ModelList components

* fix: update FloatPanel to conditionally render FloatButton based on isDesktop

* feat: add NewModelBadge component and refactor ModelInfoTags to use FeatureTagItem for improved rendering

* remove

* style: enhance UpdatePrompt component with new styles and improve layout for better readability
2025-12-26 20:48:45 +08:00
YuTengjing c401b55ff6 chore: remove outdate @types/bcryptjs 2025-12-26 20:46:17 +08:00
YuTengjing 28f0dab520 fix: circle deps 2025-12-26 20:41:27 +08:00
Neko 0b110b6012 🐛 fix(userMemories): workflow id build issue (#10998) 2025-12-26 20:26:27 +08:00
Shinji-Li 849ac733c7 feat: add the market auth auto generate way (#10993)
* feat: add the market auth auto generate way

* feat: use market trusted client to have auto auth way

* chore: update deps
2025-12-26 20:23:33 +08:00
Neko 45996c6f23 🐛 fix(userMemories): 404/405 issue due to incorrectly used workflow name and mounted catch-all route (#10995) 2025-12-26 19:21:19 +08:00
Neko 6592d10b1d 🐛 fix(userMemories): should use context.invoke for workflow instead of context.run (#10994) 2025-12-26 18:51:51 +08:00
Rene Wang 1a82a12cac feat: Swtich agent 2025-12-26 18:50:48 +08:00
YuTengjing fce68b0f58 feat: conditionally render ReferralProvider based on business feature flag 2025-12-26 18:31:59 +08:00
YuTengjing 9933ab109d fix: export RootLayoutProps interface for better accessibility in layout component 2025-12-26 18:14:43 +08:00
YuTengjing 53b4aa76d3 feat: add export for lobehub model provider in package.json 2025-12-26 17:44:16 +08:00
Rene Wang 3efe8dbfed fix: Agent swtich UI 2025-12-26 17:26:50 +08:00
YuTengjing 79e90eccce fix: add missing @lobehub/ui deps to builtin-tool-gtd 2025-12-26 16:24:41 +08:00
YuTengjing 1737b7fe30 fix: update getSubscriptionPlan to return default plan 2025-12-26 16:08:04 +08:00
YuTengjing c92f3cf4ac chore: export some business router interface 2025-12-26 15:39:56 +08:00
Innei 36ea258fec feat: translate AI model descriptions to English (#10989)
Translate all AI model and model provider descriptions from Chinese to English for better international accessibility and consistency.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-26 15:21:59 +08:00
canisminor1990 8d2eb1ca2e style: replace all checkbox 2025-12-26 15:20:12 +08:00
Shinji-Li 50aa304317 🐛 fix: slove the model select null problem (#10988)
fix: slove the model select null problem
2025-12-26 14:46:12 +08:00
canisminor1990 fddff0e962 style: update Group Avatar 2025-12-26 14:31:57 +08:00
Innei 50bca49e7d refactor(i18n): move UI locale files from TypeScript to JSON format (#10985)
* refactor(i18n): move UI locale files from TypeScript to JSON format

- Move UI locale translations from src/locales/ui/*.ts to locales/{locale}/ui.json
- Add src/locales/default/ui.ts for default (en-US) translations
- Update getUILocaleAndResources.ts to load from JSON files
- Add ui.json for all 18 supported locales (ar, bg-BG, de-DE, en-US, es-ES, fa-IR, fr-FR, it-IT, ja-JP, ko-KR, nl-NL, pl-PL, pt-BR, ru-RU, tr-TR, vi-VN, zh-CN, zh-TW)

This change unifies the locale file format, using JSON for all translations
instead of mixing TS and JSON formats.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: throw error when UI locale resources and fallback both fail

Instead of returning an empty object which could cause silent failures
in string lookups, throw an error when both the primary locale and
en-US fallback fail to load.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(i18n): remove component-level texts props and unused locale keys

- Remove texts props from all @lobehub/ui components (EmojiPicker, Form.SubmitFooter, Hotkey, ColorSwatches)
- Remove unused 'custom' and 'presets' keys from color.json files (only used for ColorSwatches texts prop)
- Components now use @lobehub/ui's built-in translations via ConfigProvider resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(i18n): remove unused locale keys from default locale files

- Remove EmojiPicker.* keys from components.ts (only used for texts prop)
- Remove submitFooter.* keys from setting.ts (only used for texts prop)
- Remove custom and presets keys from color.ts (only used for ColorSwatches texts prop)
- Update getUILocaleAndResources tests to reflect new behavior

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(i18n): enhance getUILocaleAndResources with fallback logic

* style: format code and remove unused imports

- Remove unused useTranslation import from EmojiPicker
- Format code with prettier

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-26 14:13:46 +08:00
Innei ce469967de 🐛 fix(translation): add fallback for all English locale variants (#10984)
When using English locale variants (e.g., en-GB, en-AU), the translation system should fall back to the default English namespace instead of trying to load non-existent locale files.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-26 12:37:50 +08:00
Rene Wang 972809deed lint: Warp id conversion logic 2025-12-26 12:29:10 +08:00
YuTengjing 5acd5c0a2f chore: revert type only lint 2025-12-26 12:01:32 +08:00
YuTengjing 4f2a6833b2 🐛 fix(image-generation): update chargeBeforeGenerate to return ChargeResult and include configForDatabase in parameters 2025-12-26 12:01:32 +08:00
Rene Wang a784b73685 feat: Export to markdown 2025-12-26 11:55:04 +08:00
Rene Wang 1b61f0c978 feat: Update translation 2025-12-26 11:37:58 +08:00
Shinji-Li 0b2b0963d4 🐛 fix: when use agentbuilder the topic id should use new & clear topic… (#10983)
* feat: when use agentbuilder the topic id should use new & clear topicid in unmount

* feat: when click chat button,should clear topicid first
2025-12-26 11:34:31 +08:00
Arvin Xu 7f69cb1e54 💄 style: improve page document tool inspector UI (#10977) 2025-12-26 08:51:08 +08:00
Neko 15bc6bcfbb 🐛 fix(userMemories): use date & time for building context (#10978) 2025-12-26 03:40:17 +08:00
Neko 196cfce115 tests(memory-user-memory): add tests (#10980) 2025-12-26 03:40:08 +08:00
Neko c2bcf73f9d 🐛 fix(memory-user-memory): should pre-process date & time (#10979) 2025-12-26 03:39:59 +08:00
canisminor1990 4f592ce100 style: update i18n 2025-12-26 00:09:41 +08:00
canisminor1990 4f71117bac style: update todo list style 2025-12-26 00:09:41 +08:00
Rene Wang 41e59f733b opti: Better strings 2025-12-25 23:58:30 +08:00
Arvin Xu 576ccd678c 💄 style: support tool streaming and title custom render (#10976)
* support custom inspector

* support local-system inspector

* add streaming feature

* merge
2025-12-25 23:52:57 +08:00
Rene Wang 84350b3ffc feat: Import from PDF 2025-12-25 23:23:47 +08:00
Innei e87bee6dd5 chore: update lint to use type imports (#10970)
* chore: update lint to use type imports

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* revert

* chore: add workspaces and overrides to package.json

* refactor: clean up imports in lobe-web-browsing executor

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-25 22:28:19 +08:00
Rene Wang 7f6bca71e7 fix: Page title missing 2025-12-25 22:22:10 +08:00
Rene Wang 13349406d5 fix: Cannot load more 2025-12-25 22:12:20 +08:00
YuTengjing 51ddc7cb18 refactor: replace logging library with console.error in tRPC tools handler 2025-12-25 22:00:50 +08:00
lobehubbot c00dbebc2c 📝 docs(bot): Auto sync agents & plugin to readme 2025-12-25 07:14:20 +00:00
semantic-release-bot 350c36a762 🔖 chore(release): v2.0.0-next.179 [skip ci]
## [Version&nbsp;2.0.0-next.179](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.178...v2.0.0-next.179)
<sup>Released on **2025-12-25**</sup>

#### 🐛 Bug Fixes

- **scripts**: Fix syntax error in prebuild.mts.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **scripts**: Fix syntax error in prebuild.mts, closes [#10952](https://github.com/lobehub/lobe-chat/issues/10952) ([3d46c13](https://github.com/lobehub/lobe-chat/commit/3d46c13))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2025-12-25 07:13:06 +00:00
IpiggyI 3d46c13c08 🐛 fix(scripts): fix syntax error in prebuild.mts (#10952) 2025-12-25 14:58:17 +08:00
lobehubbot 7a8373926d 📝 docs(bot): Auto sync agents & plugin to readme 2025-12-24 14:37:32 +00:00
semantic-release-bot 825e6ebd39 🔖 chore(release): v2.0.0-next.178 [skip ci]
## [Version&nbsp;2.0.0-next.178](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.177...v2.0.0-next.178)
<sup>Released on **2025-12-24**</sup>

#### 🐛 Bug Fixes

- **ci**: Always continue build to upload bundle analyzer report, skip backend routes in bundle analyzer build.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

* **ci**: Always continue build to upload bundle analyzer report, closes [#10946](https://github.com/lobehub/lobe-chat/issues/10946) ([8d37811](https://github.com/lobehub/lobe-chat/commit/8d37811))
* **ci**: Skip backend routes in bundle analyzer build, closes [#10944](https://github.com/lobehub/lobe-chat/issues/10944) ([0276b87](https://github.com/lobehub/lobe-chat/commit/0276b87))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2025-12-24 14:36:23 +00:00
Innei 8d37811b79 🐛 fix(ci): always continue build to upload bundle analyzer report (#10946)
Use `|| true` to ensure the build step always succeeds and continues
to the report upload step, even if the actual build fails.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-24 22:21:21 +08:00
Innei 0276b8713f 🐛 fix(ci): skip backend routes in bundle analyzer build (#10944)
- Add isBundleAnalyzer check in prebuild script to skip backend routes when ANALYZE=true && CI=true
- Update bundle analyzer workflow to use fallback KEY_VAULTS_SECRET from generate-secret step
- Increase NODE_OPTIONS memory limit to 8GB
- Remove unnecessary S3_PUBLIC_DOMAIN and APP_URL env vars

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-24 22:01:01 +08:00
lobehubbot 0da2b3652f 📝 docs(bot): Auto sync agents & plugin to readme 2025-12-24 11:31:33 +00:00
semantic-release-bot 804a6197a9 🔖 chore(release): v2.0.0-next.177 [skip ci]
## [Version&nbsp;2.0.0-next.177](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.176...v2.0.0-next.177)
<sup>Released on **2025-12-24**</sup>

####  Features

- **ci**: Add bundle analyzer workflow.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's improved

* **ci**: Add bundle analyzer workflow, closes [#10932](https://github.com/lobehub/lobe-chat/issues/10932) ([c470cfb](https://github.com/lobehub/lobe-chat/commit/c470cfb))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>
2025-12-24 11:30:20 +00:00
Innei c470cfb1e8 feat(ci): add bundle analyzer workflow (#10932)
*  feat(ci): add bundle analyzer workflow

- Add GitHub Actions workflow for bundle size analysis
- Generate pnpm lockfile for reproducible builds
- Include analyzer reports and lockfile in artifacts
- Use pnpm for dependency installation
- Run build:analyze script directly for bundle generation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(ci): add required env vars for bundle analyzer build

- Add KEY_VAULTS_SECRET generation step
- Add S3_PUBLIC_DOMAIN and APP_URL env vars
- Fixes build error when running build:analyze

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-24 19:15:17 +08:00
3426 changed files with 129886 additions and 101712 deletions
@@ -0,0 +1,959 @@
# createStaticStyles 迁移指南
## 📖 概述
`createStaticStyles``antd-style` 提供的静态样式创建函数,相比 `createStyles`(hook 方案)具有零运行时开销的优势。样式在模块加载时计算一次,而不是每次组件渲染时计算。
## 🎯 适用场景
### ✅ 可以优化的场景
1. **纯静态样式**:不依赖运行时动态值
2. **使用标准 token**:所有 token 都在 `cssVar.json` 中有对应项
3. **简单的条件逻辑**:可以通过静态样式拆分处理
### ❌ 无法优化的场景
1. **JS 计算函数**`readableColor()`, `chroma()`, `mix()`, `calc()` 中使用 token 数值
2. **复杂的动态 props**:需要运行时计算的复杂逻辑
3. **动态 prefixCls**:需要运行时传入的类名前缀(但可以硬编码为 `'ant'`
## 🔄 基本转换步骤
### 1. 样式文件转换
**之前(createStyles):**
```typescript
import { createStyles } from 'antd-style';
export const useStyles = createStyles(({ css, token }) => {
return {
root: css`
color: ${token.colorText};
font-size: ${token.fontSize}px;
`,
};
});
```
**之后(createStaticStyles):**
```typescript
import { createStaticStyles } from 'antd-style';
export const styles = createStaticStyles(({ css, cssVar }) => {
return {
root: css`
color: ${cssVar.colorText};
font-size: ${cssVar.fontSize};
`,
};
});
```
### 2. 组件文件转换
**之前:**
```typescript
import { useStyles } from './style';
const Component = () => {
const { styles, cx } = useStyles();
return <div className={cx(styles.root, className)} />;
};
```
**之后:**
```typescript
import { cx } from 'antd-style';
import { styles } from './style';
const Component = () => {
return <div className={cx(styles.root, className)} />;
};
```
## 🛠️ 常见场景处理
### 场景 1: Token 转换
**规则:**
- `token.xxx``cssVar.xxx`
- 注意:`cssVar.fontSize` 已经包含 `px` 单位,不需要再加 `px`
**示例:**
```typescript
// ❌ 错误
font-size: ${cssVar.fontSize}px; // cssVar.fontSize 已经是 "14px"
// ✅ 正确
font-size: ${cssVar.fontSize}; // 直接使用
```
**特殊情况 - calc ()**
```typescript
// ❌ 错误
calc(${token.fontSize}px * 2.5)
// ✅ 正确
calc(${cssVar.fontSize} * 2.5) // cssVar.fontSize 已经包含单位
```
### 场景 2: 动态 Props → CSS 变量
**适用:** 数值、字符串类型的 props
**步骤:**
1. 在样式文件中使用 CSS 变量(带默认值)
2. 在组件中通过 `style` prop 设置 CSS 变量
**示例:**
**样式文件:**
```typescript
export const styles = createStaticStyles(({ css }) => {
return {
root: css`
width: var(--component-size, 24px);
height: var(--component-size, 24px);
`,
};
});
```
**组件文件:**
```typescript
import { useMemo } from 'react';
const Component = ({ size = 24, style, ...rest }) => {
const cssVariables = useMemo<Record<string, string>>(
() => ({
'--component-size': `${size}px`,
}),
[size],
);
return (
<div
className={styles.root}
style={{
...cssVariables,
...style,
}}
{...rest}
/>
);
};
```
**已优化示例:**
- `Video`: `maxHeight`, `maxWidth`, `minHeight`, `minWidth`
- `ScrollShadow`: `size`
- `MaskShadow`: `size`
- `ColorSwatches`: `size`
- `Grid`: `rows`, `maxItemWidth`, `gap`
- `Layout`: `headerHeight`
- `Footer`: `contentMaxWidth`
### 场景 3: 布尔值 Props → 静态样式拆分
**适用:** 简单的布尔值 props(2-3 个)
**步骤:**
1. 创建所有可能的组合样式
2. 运行时使用 `cx` 组合
**示例:**
**样式文件:**
```typescript
export const styles = createStaticStyles(({ css }) => {
return {
root: css`
/* base styles */
`,
root_closable_true: css`
/* closable styles */
`,
root_closable_false: css`
/* no closable styles */
`,
root_hasTitle_true: css`
/* has title styles */
`,
root_hasTitle_false: css`
/* no title styles */
`,
};
});
```
**组件文件:**
```typescript
const Component = ({ closable, hasTitle }) => {
const className = cx(
styles.root,
styles[`root_closable_${!!closable}`],
styles[`root_hasTitle_${!!hasTitle}`],
);
return <div className={className} />;
};
```
**已优化示例:**
- `Alert`: `closable`, `hasTitle`, `showIcon` → 8 个组合(2×2×2
- `Image`: `alwaysShowActions` → 2 个样式
- `StoryBook`: `noPadding` → 2 个样式
### 场景 4: isDarkMode → 静态样式拆分
**适用:** 依赖 `isDarkMode` 的条件样式
**有两种处理方式:**
#### 方式 A: 直接条件选择(简单场景)
**步骤:**
1. 创建 `Dark``Light` 两个静态样式
2. 运行时根据 `theme.isDarkMode` 选择
**示例:**
**样式文件:**
```typescript
export const styles = createStaticStyles(({ css, cssVar }) => {
return {
rootDark: css`
background: ${cssVar.colorFillTertiary};
color: ${cssVar.colorTextLightSolid};
`,
rootLight: css`
background: ${cssVar.colorFillQuaternary};
color: ${cssVar.colorText};
`,
};
});
```
**组件文件:**
```typescript
import { useThemeMode } from 'antd-style';
const Component = () => {
const { isDarkMode } = useThemeMode();
return (
<div
className={cx(
isDarkMode ? styles.rootDark : styles.rootLight
)}
/>
);
};
```
#### 方式 B: 使用 cva 将 isDarkMode 作为 variant(推荐,适用于复杂场景)
**步骤:**
1. 创建 `Dark``Light` 两个静态样式
2.`cva` 中将 `isDarkMode` 作为 variant prop
3. 运行时直接传入 `isDarkMode`
**示例:**
**样式文件:**
```typescript
import { createStaticStyles } from 'antd-style';
import { cva } from 'class-variance-authority';
export const styles = createStaticStyles(({ css, cssVar }) => {
return {
filledDark: css`
background: ${cssVar.colorFillTertiary};
color: ${cssVar.colorTextLightSolid};
`,
filledLight: css`
background: ${cssVar.colorFillQuaternary};
color: ${cssVar.colorText};
`,
outlined: css`
border: 1px solid ${cssVar.colorBorder};
`,
root: css`
/* base styles */
`,
};
});
export const variants = cva(styles.root, {
defaultVariants: {
isDarkMode: false,
variant: 'filled',
},
variants: {
isDarkMode: {
false: null,
true: null, // isDarkMode 本身不添加样式,通过 compoundVariants 组合
},
variant: {
filled: null, // variant 本身不添加样式,通过 compoundVariants 组合
outlined: styles.outlined,
},
},
compoundVariants: [
{
class: styles.filledDark,
isDarkMode: true,
variant: 'filled',
},
{
class: styles.filledLight,
isDarkMode: false,
variant: 'filled',
},
],
});
```
**组件文件:**
```typescript
import { useThemeMode } from 'antd-style';
import { variants } from './style';
const Component = ({ variant = 'filled' }) => {
const { isDarkMode } = useThemeMode();
return (
<div
className={variants({ isDarkMode, variant })}
/>
);
};
```
**优势:**
- ✅ 不需要 `useMemo` 动态创建 variants
- ✅ 更符合 `cva` 的设计理念
- ✅ 代码更简洁,性能更好
- ✅ 类型安全,IDE 自动补全
**已优化示例:**
- `TypewriterEffect`: `textDark` / `textLight`(方式 A
- `Collapse`: `filledDark` / `filledLight`(可优化为方式 B
- `Hotkey`: `inverseThemeDark` / `inverseThemeLight`(可优化为方式 B
- `GuideCard`: `filledDark` / `filledLight`(可优化为方式 B
- `GradientButton`: `buttonDark` / `buttonLight`(方式 A
### 场景 5: responsive → 静态 responsive
**适用:** 使用响应式断点
**步骤:**
1. 导入静态 `responsive` from `antd-style`
2. 使用 `responsive.sm` 替代 `responsive.mobile`
3.`createStyles` 参数中移除 `responsive`
**示例:**
**之前:**
```typescript
import { createStyles } from 'antd-style';
export const useStyles = createStyles(({ css, responsive }) => ({
root: css`
${responsive.mobile} {
padding: 12px;
}
`,
}));
```
**之后:**
```typescript
import { createStaticStyles } from 'antd-style';
import { responsive } from 'antd-style';
export const styles = createStaticStyles(({ css }) => ({
root: css`
${responsive.sm} {
padding: 12px;
}
`,
}));
```
**注意:**
- `responsive.mobile``responsive.sm`
- 静态 `responsive` 提供:`xs`, `sm`, `md`, `lg`, `xl`, `xxl`
**已优化示例:**
- `Header`: `responsive.mobile``responsive.sm`
- `FormModal`: `responsive.mobile``responsive.sm`
- `Hero`: `responsive.mobile``responsive.sm`
### 场景 6: stylish → lobeStaticStylish
**适用:** 使用自定义 `stylish` 工具
**步骤:**
1. 导入 `lobeStaticStylish` from `@/styles`
2. 替换 `stylish.xxx``lobeStaticStylish.xxx`
**示例:**
**之前:**
```typescript
import { createStyles } from 'antd-style';
export const useStyles = createStyles(({ css, stylish }) => ({
root: css`
${stylish.blur};
${stylish.variantFilled};
`,
}));
```
**之后:**
```typescript
import { createStaticStyles } from 'antd-style';
import { lobeStaticStylish } from '@/styles';
export const styles = createStaticStyles(({ css }) => ({
root: css`
${lobeStaticStylish.blur};
${lobeStaticStylish.variantFilled};
`,
}));
```
**已优化示例:**
- `Button`: `stylish.blur``lobeStaticStylish.blur`
- `Hero`: `stylish.gradientAnimation``lobeStaticStylish.gradientAnimation`
### 场景 7: prefixCls → 硬编码
**适用:** 使用动态 `prefixCls` 参数
**步骤:**
1. 在文件顶部硬编码 `const prefixCls = 'ant'`
2.`createStyles` 参数中移除 `prefixCls`
**示例:**
**之前:**
```typescript
export const useStyles = createStyles(({ css }, prefixCls: string) => ({
root: css`
.${prefixCls}-button {
/* styles */
}
`,
}));
```
**之后:**
```typescript
const prefixCls = 'ant';
export const styles = createStaticStyles(({ css }) => ({
root: css`
.${prefixCls}-button {
/* styles */
}
`,
}));
```
**已优化示例:**
- `Alert`, `Collapse`, `FormModal`, `Image`, `Burger`, `DraggablePanel`, `DraggableSideNav`, `Toc`, `ColorSwatches`, `EmojiPicker`, `Form`, `awesome/Features`
### 场景 8: readableColor () → Token 替换
**适用:** 使用 `readableColor()` 计算对比色
**规则:**
- `readableColor(token.colorPrimary)``cssVar.colorTextLightSolid`(主色背景用白色文字)
- `readableColor(token.colorTextQuaternary)``cssVar.colorText`(浅色背景用深色文字)
**示例:**
**之前:**
```typescript
import { readableColor } from 'polished';
export const useStyles = createStyles(({ css, token }) => ({
checked: css`
background-color: ${token.colorPrimary};
color: ${readableColor(token.colorPrimary)};
`,
}));
```
**之后:**
```typescript
export const styles = createStaticStyles(({ css, cssVar }) => ({
checked: css`
background-color: ${cssVar.colorPrimary};
color: ${cssVar.colorTextLightSolid};
`,
}));
```
**已优化示例:**
- `Checkbox`: `readableColor(token.colorPrimary)``cssVar.colorTextLightSolid`
### 场景 9: rgba () → color-mix ()
**适用:** 使用 `rgba()` 设置透明度
**步骤:**
1. 使用 CSS 原生的 `color-mix()` 函数
2. 格式:`color-mix(in srgb, ${cssVar.xxx} alpha%, transparent)`
**示例:**
**之前:**
```typescript
import { rgba } from 'polished';
export const useStyles = createStyles(({ css, token }) => ({
root: css`
background-color: ${rgba(token.colorBgLayout, 0.4)};
`,
}));
```
**之后:**
```typescript
export const styles = createStaticStyles(({ css, cssVar }) => ({
root: css`
background-color: color-mix(in srgb, ${cssVar.colorBgLayout} 40%, transparent);
`,
}));
```
**已优化示例:**
- `Header`: `rgba(cssVar.colorBgLayout, 0.4)``color-mix(...)`
- `FormModal`: `rgba(cssVar.colorBgContainer, 0)``color-mix(...)`
### 场景 10: keyframes → css
**适用:** 使用 `keyframes` 创建动画
**步骤:**
1.`createStaticStyles` 外部定义 `keyframes`
2. 在样式内部使用
**示例:**
**之前:**
```typescript
export const useStyles = createStyles(({ css, keyframes }) => {
const spin = keyframes`
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
`;
return {
icon: css`
animation: ${spin} 1s linear infinite;
`,
};
});
```
**之后:**
```typescript
import { keyframes } from 'antd-style';
const spin = keyframes`
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
`;
export const styles = createStaticStyles(({ css }) => ({
icon: css`
animation: ${spin} 1s linear infinite;
`,
}));
```
**已优化示例:**
- `Icon`: `keyframes` 动画
- `Skeleton`: `keyframes` shimmer 动画
## ⚠️ 反模式:避免使用 createVariants (isDarkMode)
**不推荐的做法:**
```typescript
// ❌ 不推荐:在组件中动态创建 variants
export const createVariants = (isDarkMode: boolean) =>
cva(styles.root, {
variants: {
variant: {
filled: isDarkMode ? styles.filledDark : styles.filledLight,
},
},
});
// 组件中
const variants = useMemo(() => createVariants(isDarkMode), [isDarkMode]);
```
**推荐的做法:**
`isDarkMode` 作为 `cva` 的 variant prop(见场景 4 方式 B),这样:
- ✅ 不需要 `useMemo` 动态创建
- ✅ 更符合 `cva` 的设计理念
- ✅ 代码更简洁,性能更好
- ✅ 类型安全,IDE 自动补全
```typescript
// ✅ 推荐:将 isDarkMode 作为 variant prop
export const variants = cva(styles.root, {
variants: {
isDarkMode: {
false: null,
true: null,
},
variant: {
filled: null,
},
},
compoundVariants: [
{
class: styles.filledDark,
isDarkMode: true,
variant: 'filled',
},
{
class: styles.filledLight,
isDarkMode: false,
variant: 'filled',
},
],
});
// 组件中
const { isDarkMode } = useThemeMode();
const className = variants({ isDarkMode, variant: 'filled' });
```
## ⚠️ 无法优化的场景
### 1. JS 计算函数
**无法优化:**
- `chroma()` - 颜色计算库
- `readableColor()` - 需要运行时计算(但可以用 token 替代)
- `mix()` - 颜色混合计算
- `calc()` 中使用 token 数值进行复杂计算
**示例:**
```typescript
// ❌ 无法优化
const scale = chroma.bezier([token.colorText, backgroundColor]).scale().colors(6);
```
### 2. 复杂的动态 Props
**无法优化:**
- 需要复杂计算的 props
- 对象 / 数组类型的 props
- 函数类型的 props
### 3. useTheme Hook
**无法优化:**
- 直接使用 `useTheme()` hook 获取运行时值
- 例如:`awesome/Giscus/style.ts` 使用 `useTheme()` 获取主题值
## 📋 迁移检查清单
### 样式文件检查
- [ ] `createStyles``createStaticStyles`
- [ ] `token.xxx``cssVar.xxx`
- [ ] 移除 `px` 后缀(`cssVar` 已包含单位)
- [ ] `responsive.mobile``responsive.sm`(如果使用)
- [ ] `stylish.xxx``lobeStaticStylish.xxx`(如果使用)
- [ ] `rgba()``color-mix()`(如果使用)
- [ ] `readableColor()` → token 替换(如果使用)
- [ ] `prefixCls` 参数 → 硬编码 `const prefixCls = 'ant'`(如果使用)
- [ ] `isDarkMode` → 静态样式拆分(如果使用)
- [ ] 动态 props → CSS 变量(如果使用)
### 组件文件检查
- [ ] `useStyles()``import { styles } from './style'`
- [ ] `import { cx } from 'antd-style'`(如果需要)
- [ ] `import { useTheme } from 'antd-style'`(如果需要 `theme.isDarkMode`
- [ ] 动态 props → CSS 变量设置(如果使用)
- [ ] `isDarkMode` 条件 → `theme.isDarkMode` 判断(如果使用)
## 🎯 优化优先级
### 高优先级(简单优化)
1. ✅ 纯静态样式(无动态 props)
2.`isDarkMode` 拆分
3.`responsive.mobile``responsive.sm`
4.`stylish``lobeStaticStylish`
5.`readableColor()` → token 替换
### 中优先级(需要转换)
6. ✅ 简单的动态 props → CSS 变量(1-2 个)
7. ✅ 布尔值 props → 静态样式拆分(2-3 个)
### 低优先级(复杂优化)
8. ⚠️ 多个动态 props → CSS 变量(3+ 个)
9. ⚠️ 复杂的条件逻辑拆分
## 📚 参考示例
### 完整示例 1: 简单组件
**样式文件:**
```typescript
import { createStaticStyles } from 'antd-style';
export const styles = createStaticStyles(({ css, cssVar }) => ({
root: css`
padding: ${cssVar.padding};
color: ${cssVar.colorText};
border-radius: ${cssVar.borderRadius};
`,
}));
```
**组件文件:**
```typescript
import { cx } from 'antd-style';
import { styles } from './style';
const Component = ({ className }) => {
return <div className={cx(styles.root, className)} />;
};
```
### 完整示例 2: 带动态 Props
**样式文件:**
```typescript
import { createStaticStyles } from 'antd-style';
export const styles = createStaticStyles(({ css, cssVar }) => ({
root: css`
width: var(--component-size, 24px);
height: var(--component-size, 24px);
background: ${cssVar.colorBgContainer};
`,
}));
```
**组件文件:**
```typescript
import { cx } from 'antd-style';
import { useMemo } from 'react';
import { styles } from './style';
const Component = ({ size = 24, className, style, ...rest }) => {
const cssVariables = useMemo<Record<string, string>>(
() => ({
'--component-size': `${size}px`,
}),
[size],
);
return (
<div
className={cx(styles.root, className)}
style={{
...cssVariables,
...style,
}}
{...rest}
/>
);
};
```
### 完整示例 3: 带 isDarkMode
**样式文件:**
```typescript
import { createStaticStyles } from 'antd-style';
export const styles = createStaticStyles(({ css, cssVar }) => ({
rootDark: css`
background: ${cssVar.colorFillTertiary};
color: ${cssVar.colorTextLightSolid};
`,
rootLight: css`
background: ${cssVar.colorFillQuaternary};
color: ${cssVar.colorText};
`,
}));
```
**组件文件:**
```typescript
import { cx, useTheme } from 'antd-style';
import { styles } from './style';
const Component = ({ className }) => {
const { theme } = useTheme();
return (
<div
className={cx(
theme.isDarkMode ? styles.rootDark : styles.rootLight,
className
)}
/>
);
};
```
## 🔍 验证步骤
1. **类型检查:** `pnpm run type-check`
2. **运行时测试:** 确保视觉效果一致
3. **性能验证:** 检查样式计算是否在模块加载时完成
## 📊 优化效果
-**零运行时开销**:样式在模块加载时计算一次
-**减少重新渲染**:组件不再依赖样式 hook
-**更好的性能**:减少每次渲染的计算开销
-**代码更简洁**:直接导入样式对象
## 🔧 场景 11: useTheme () → useThemeMode () /cssVar
**适用:** 组件中只使用 `theme.isDarkMode` 或其他 token 值
**规则:**
- 如果只使用 `theme.isDarkMode`,使用 `const { isDarkMode } = useThemeMode()` 替代
- 如果使用其他 token(如 `theme.colorText`, `theme.borderRadius` 等),使用 `cssVar` 替代
- `useThemeMode()``useTheme()` 更轻量,只返回 `isDarkMode`
**示例:**
**之前:**
```typescript
import { useTheme } from 'antd-style';
const Component = () => {
const theme = useTheme();
return (
<div className={theme.isDarkMode ? styles.dark : styles.light}>
{theme.colorText}
</div>
);
};
```
**之后:**
```typescript
import { cssVar, useThemeMode } from 'antd-style';
const Component = () => {
const { isDarkMode } = useThemeMode();
return (
<div className={isDarkMode ? styles.dark : styles.light}>
{cssVar.colorText}
</div>
);
};
```
**已优化示例:**
- `AuroraBackground`, `Select`, `Input`, `Button`, `DatePicker`, `AutoComplete`, `InputNumber`, `InputPassword`, `InputOPT`, `TextArea`, `SpotlightCardItem`, `Spotlight`, `HotkeyInput` - 只使用 `isDarkMode``useThemeMode()`
- `Image`, `GradientButton`, `Empty`, `FileTypeIcon`, `FormSubmitFooter`, `CodeEditor`, `LobeChat`, `Drawer`, `Modal`, `Avatar`, `AvatarGroup`, `SkeletonAvatar`, `SkeletonButton`, `SkeletonTags`, `Callout`, `LobeHub`, `GridBackground`, `FolderIcon`, `FileIcon`, `TokenTag`, `ChatSendButton`, `AvatarUploader` - 使用 token → `cssVar`
**无法优化的文件(需要保留 `useTheme()`):**
- `useMermaid`, `useStreamMermaid`, `useHighlight`, `useStreamHighlight` - 需要完整的 theme 对象传给第三方库
- `Alert`, `Tag`, `Menu`, `EmojiPicker` - 需要实际颜色值传给颜色计算函数
- `SkeletonTitle`, `SkeletonTags` - 需要数值进行数学运算
- `GridShowcase`, `GridBackground/demos` - 需要实际颜色值传给 `rgba()` 函数
- `CustomFonts` - 需要实际字符串值进行字符串拼接
- `Giscus/style.ts` - 需要实际颜色值传给 `readableColor()``rgba()` 函数(其他 token 已优化为 `cssVar`
**注意事项:**
- `useThemeMode()` 只返回 `{ isDarkMode }`,不返回完整的 theme 对象
- `cssVar` 的值是字符串(如 `"14px"`, `"#ffffff"`),可以直接在 JSX 中使用
- 如果 token 需要用于数值计算(如 `Math.round(theme.fontSize * 1.5)`),需要保留 `useTheme()`
## 🎉 总结
`createStaticStyles` 迁移是一个渐进式的优化过程。对于简单的静态样式,可以直接转换;对于复杂的动态场景,需要根据具体情况选择合适的优化策略。关键是要理解每种场景的处理方式,并灵活运用 CSS 变量、静态样式拆分等技术。
### useTheme () 优化总结
-**使用 `useThemeMode()`**:当组件只使用 `theme.isDarkMode`
-**使用 `cssVar`**:当组件使用其他 token 值(颜色、尺寸等)时
- ⚠️ **保留 `useTheme()`**:当 token 需要用于数值计算或传给第三方库时
+1 -1
View File
@@ -1,7 +1,7 @@
const config = require('@lobehub/lint').eslint;
config.root = true;
config.extends.push('plugin:@next/next/recommended');
config.extends.push('plugin:@next/next/recommended-legacy');
config.rules['unicorn/no-negated-condition'] = 0;
config.rules['unicorn/prefer-type-error'] = 0;
+115
View File
@@ -0,0 +1,115 @@
name: Bundle Analyzer
on:
workflow_dispatch:
permissions:
contents: read
actions: write
env:
NODE_VERSION: 24.11.1
BUN_VERSION: 1.2.23
jobs:
bundle-analyzer:
name: Analyze Bundle Size
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: ${{ env.BUN_VERSION }}
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Install dependencies
run: pnpm i
- name: Ensure lockfile exists
run: |
# Temporarily override .npmrc lockfile=false setting
# to generate pnpm-lock.yaml for reproducible builds
if [ ! -f "pnpm-lock.yaml" ]; then
echo "Generating pnpm-lock.yaml..."
# Create temporary .npmrc override
mv .npmrc .npmrc.bak
echo "lockfile=true" > .npmrc
cat .npmrc.bak >> .npmrc
pnpm i
mv .npmrc.bak .npmrc
fi
- name: Generate build secrets
id: generate-secret
run: echo "secret=$(openssl rand -base64 32)" >> $GITHUB_OUTPUT
- name: Build with bundle analyzer
run: bun run build:analyze || true
env:
NODE_OPTIONS: --max-old-space-size=8192
KEY_VAULTS_SECRET: ${{ secrets.KEY_VAULTS_SECRET || steps.generate-secret.outputs.secret }}
- name: Prepare analyzer reports
run: |
mkdir -p bundle-report
# Copy analyzer HTML reports if they exist
if [ -d ".next/analyze" ]; then
cp -r .next/analyze/* bundle-report/ || true
fi
# Also check if reports are in .vercel/output
if [ -d ".vercel/output/.next/analyze" ]; then
cp -r .vercel/output/.next/analyze/* bundle-report/ || true
fi
# Include pnpm lockfile for reproducible builds
if [ -f "pnpm-lock.yaml" ]; then
cp pnpm-lock.yaml bundle-report/pnpm-lock.yaml
echo "Copied pnpm-lock.yaml to bundle-report"
else
echo "Warning: pnpm-lock.yaml not found"
fi
# Create a summary with build metadata
echo "# Bundle Analysis Report" > bundle-report/README.md
echo "" >> bundle-report/README.md
echo "**Build Date:** $(date -u +"%Y-%m-%d %H:%M:%S UTC")" >> bundle-report/README.md
echo "**Commit:** ${{ github.sha }}" >> bundle-report/README.md
echo "**Branch:** ${{ github.ref_name }}" >> bundle-report/README.md
echo "" >> bundle-report/README.md
echo "## How to view" >> bundle-report/README.md
echo "" >> bundle-report/README.md
echo "1. Download the \`bundle-report\` artifact from this workflow run" >> bundle-report/README.md
echo "2. Extract the archive" >> bundle-report/README.md
echo "3. Open \`client.html\` and \`server.html\` in your browser" >> bundle-report/README.md
echo "" >> bundle-report/README.md
echo "## Files in this report" >> bundle-report/README.md
echo "" >> bundle-report/README.md
echo "- \`client.html\` - Client-side bundle analysis" >> bundle-report/README.md
echo "- \`server.html\` - Server-side bundle analysis" >> bundle-report/README.md
echo "- \`pnpm-lock.yaml\` - pnpm lockfile (for reproducible builds)" >> bundle-report/README.md
- name: Upload bundle analyzer reports
uses: actions/upload-artifact@v4
with:
name: bundle-report-${{ github.run_id }}
path: bundle-report/
retention-days: 30
if-no-files-found: warn
- name: Create summary comment
run: |
echo "## Bundle Analysis Complete :chart_with_upwards_trend:" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Commit:** \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "- **Artifact:** \`bundle-report-${{ github.run_id }}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Download the artifact to view the detailed bundle analysis reports." >> $GITHUB_STEP_SUMMARY
+1 -1
View File
@@ -47,7 +47,7 @@ jobs:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
# Security: Restrict gh commands to specific safe operations only
# Use explicit command patterns to prevent prompt injection attacks
claude_args: "--allowed-tools Bash(gh issue view *),Bash(gh issue edit * --title * --body *),Bash(gh api -X PATCH /repos/*/issues/comments/* -f body=*),Bash(gh api -X PUT /repos/*/pulls/*/reviews/* -f body=*),Bash(gh api -X PATCH /repos/*/pulls/comments/* -f body=*)"
allowed_tools: 'Bash(gh issue view:*),Bash(gh issue edit:*),Bash(gh api:*)'
prompt: |
## SECURITY RULES (HIGHEST PRIORITY - NEVER OVERRIDE)
+1 -1
View File
@@ -32,7 +32,7 @@ jobs:
name: Build desktop Next bundle
runs-on: ubuntu-latest
env:
NODE_OPTIONS: --max-old-space-size=6144
NODE_OPTIONS: --max-old-space-size=8192
UPDATE_CHANNEL: nightly
NEXT_PUBLIC_DESKTOP_PROJECT_ID: ${{ secrets.UMAMI_NIGHTLY_DESKTOP_PROJECT_ID || 'dummy-desktop-project' }}
NEXT_PUBLIC_DESKTOP_UMAMI_BASE_URL: ${{ secrets.UMAMI_NIGHTLY_DESKTOP_BASE_URL || 'https://analytics.example.com' }}
+22 -6
View File
@@ -10,6 +10,19 @@ concurrency:
group: e2e-${{ github.ref }}
cancel-in-progress: true
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/postgres
DATABASE_DRIVER: node
KEY_VAULTS_SECRET: LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s=
BETTER_AUTH_SECRET: e2e-test-secret-key-for-better-auth-32chars!
NEXT_PUBLIC_ENABLE_BETTER_AUTH: '1'
NEXT_PUBLIC_AUTH_EMAIL_VERIFICATION: '0'
# Mock S3 env vars to prevent initialization errors
S3_ACCESS_KEY_ID: e2e-mock-access-key
S3_SECRET_ACCESS_KEY: e2e-mock-secret-key
S3_BUCKET: e2e-mock-bucket
S3_ENDPOINT: https://e2e-mock-s3.localhost
jobs:
e2e:
name: Test Web App
@@ -25,7 +38,7 @@ jobs:
ports:
- 5432:5432
timeout-minutes: 25
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v5
@@ -41,12 +54,15 @@ jobs:
- name: Install Playwright browsers (with system deps)
run: bunx playwright install --with-deps chromium
- name: Run E2E tests
- name: Run database migrations
run: bun run db:migrate
- name: Build application
run: bun run build
env:
PORT: 3010
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/postgres
DATABASE_DRIVER: node
KEY_VAULTS_SECRET: LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s=
SKIP_LINT: '1'
- name: Run E2E tests
run: bun run e2e
- name: Upload Cucumber HTML report (on failure)
@@ -62,13 +62,9 @@ jobs:
- name: Install deps
run: bun i
env:
NODE_OPTIONS: --max-old-space-size=6144
- name: Lint
run: bun run lint
env:
NODE_OPTIONS: --max-old-space-size=6144
version:
name: Determine version
+3 -3
View File
@@ -39,12 +39,12 @@ jobs:
- name: Install deps
run: bun i
env:
NODE_OPTIONS: --max-old-space-size=6144
NODE_OPTIONS: --max-old-space-size=8192
- name: Lint
run: bun run lint
env:
NODE_OPTIONS: --max-old-space-size=6144
NODE_OPTIONS: --max-old-space-size=8192
version:
name: Determine version
@@ -80,7 +80,7 @@ jobs:
echo "📦 Release Version: ${version} (based on base version ${base_version})"
env:
NODE_OPTIONS: --max-old-space-size=6144
NODE_OPTIONS: --max-old-space-size=8192
# 输出版本信息总结,方便在 GitHub Actions 界面查看
- name: Version Summary
+2 -1
View File
@@ -143,7 +143,7 @@ jobs:
run: pnpm install
working-directory: apps/desktop
env:
NODE_OPTIONS: --max-old-space-size=6144
NODE_OPTIONS: --max-old-space-size=8192
- name: Typecheck Desktop
run: pnpm type-check
@@ -173,6 +173,7 @@ jobs:
options: >-
--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
ports:
- 5432:5432
@@ -0,0 +1,55 @@
name: Verify Desktop Patch
on:
push:
branches:
- main
- next
- dev
paths:
- 'scripts/electronWorkflow/**'
- 'src/libs/next/config/**'
- 'src/app/**'
- 'src/layout/**'
- 'src/components/mdx/**'
- 'src/features/DevPanel/**'
- 'src/server/translation.ts'
pull_request:
paths:
- 'scripts/electronWorkflow/**'
- 'src/libs/next/config/**'
- 'src/app/**'
- 'src/layout/**'
- 'src/components/mdx/**'
- 'src/features/DevPanel/**'
- 'src/server/translation.ts'
workflow_dispatch:
permissions:
contents: read
env:
NODE_VERSION: 24.11.1
BUN_VERSION: 1.2.23
jobs:
verify:
name: Desktop patch smoke test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Setup Node & Bun
uses: ./.github/actions/setup-node-bun
with:
node-version: ${{ env.NODE_VERSION }}
bun-version: ${{ env.BUN_VERSION }}
- name: Install deps
run: bun i
- name: Verify desktop patch
run: bun scripts/electronWorkflow/modifiers/index.mts
+3 -3
View File
@@ -1,14 +1,14 @@
const { defineConfig } = require('@lobehub/i18n-cli');
module.exports = defineConfig({
entry: 'locales/zh-CN',
entryLocale: 'zh-CN',
entry: 'locales/en-US',
entryLocale: 'en-US',
output: 'locales',
outputLocales: [
'ar',
'bg-BG',
'zh-CN',
'zh-TW',
'en-US',
'ru-RU',
'ja-JP',
'ko-KR',
+8 -6
View File
@@ -7,14 +7,16 @@
"editor.formatOnSave": true,
// don't show errors, but fix when save and git pre commit
"eslint.rules.customizations": [
{ "rule": "import/order", "severity": "off" },
{ "rule": "prettier/prettier", "severity": "off" },
{ "rule": "react/jsx-sort-props", "severity": "off" },
{ "rule": "sort-keys-fix/sort-keys-fix", "severity": "off" },
{ "rule": "simple-import-sort/exports", "severity": "off" },
{ "rule": "typescript-sort-keys/interface", "severity": "off" }
// { "rule": "import/order", "severity": "off" },
// { "rule": "prettier/prettier", "severity": "off" },
// { "rule": "react/jsx-sort-props", "severity": "off" },
// { "rule": "sort-keys-fix/sort-keys-fix", "severity": "off" },
// { "rule": "simple-import-sort/exports", "severity": "off" },
// { "rule": "typescript-sort-keys/interface", "severity": "off" }
],
"eslint.validate": [
// vscode eslint not 插件兼容性有问题
// "json",
"javascript",
"javascriptreact",
"typescript",
+858
View File
@@ -2,6 +2,864 @@
# Changelog
## [Version 2.0.0-next.202](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.201...v2.0.0-next.202)
<sup>Released on **2026-01-03**</sup>
#### ♻ Code Refactoring
- **misc**: Refactor and fix model runtime initialize.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Code refactoring
- **misc**: Refactor and fix model runtime initialize, closes [#11134](https://github.com/lobehub/lobe-chat/issues/11134) ([8078cb9](https://github.com/lobehub/lobe-chat/commit/8078cb9))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.201](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.200...v2.0.0-next.201)
<sup>Released on **2026-01-03**</sup>
#### 🐛 Bug Fixes
- **misc**: Restore window resizable before hard reload in desktop onboarding.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **misc**: Restore window resizable before hard reload in desktop onboarding, closes [#11144](https://github.com/lobehub/lobe-chat/issues/11144) ([2516874](https://github.com/lobehub/lobe-chat/commit/2516874))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.200](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.199...v2.0.0-next.200)
<sup>Released on **2026-01-03**</sup>
#### ✨ Features
- **misc**: Add work path for local system.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's improved
- **misc**: Add work path for local system, closes [#11128](https://github.com/lobehub/lobe-chat/issues/11128) ([d8deadd](https://github.com/lobehub/lobe-chat/commit/d8deadd))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.199](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.198...v2.0.0-next.199)
<sup>Released on **2026-01-03**</sup>
#### 🐛 Bug Fixes
- **misc**: Filter empty assistant messages for Anthropic API.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **misc**: Filter empty assistant messages for Anthropic API, closes [#11129](https://github.com/lobehub/lobe-chat/issues/11129) ([7af750b](https://github.com/lobehub/lobe-chat/commit/7af750b))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.198](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.197...v2.0.0-next.198)
<sup>Released on **2026-01-03**</sup>
#### 🐛 Bug Fixes
- **misc**: Support thoughtSignature for openrouter.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **misc**: Support thoughtSignature for openrouter, closes [#11117](https://github.com/lobehub/lobe-chat/issues/11117) ([bf5d41e](https://github.com/lobehub/lobe-chat/commit/bf5d41e))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.197](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.196...v2.0.0-next.197)
<sup>Released on **2026-01-03**</sup>
#### ♻ Code Refactoring
- **misc**: Remove client db and refactor test.
#### 🐛 Bug Fixes
- **misc**: Fix file upload issue.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Code refactoring
- **misc**: Remove client db and refactor test, closes [#11123](https://github.com/lobehub/lobe-chat/issues/11123) ([bb2799d](https://github.com/lobehub/lobe-chat/commit/bb2799d))
#### What's fixed
- **misc**: Fix file upload issue, closes [#11122](https://github.com/lobehub/lobe-chat/issues/11122) ([1ae327a](https://github.com/lobehub/lobe-chat/commit/1ae327a))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.196](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.195...v2.0.0-next.196)
<sup>Released on **2026-01-03**</sup>
#### ♻ Code Refactoring
- **misc**: Refactor to remove access code.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Code refactoring
- **misc**: Refactor to remove access code, closes [#11120](https://github.com/lobehub/lobe-chat/issues/11120) ([0e9f98c](https://github.com/lobehub/lobe-chat/commit/0e9f98c))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.195](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.194...v2.0.0-next.195)
<sup>Released on **2026-01-03**</sup>
#### 🐛 Bug Fixes
- **misc**: Fix tool call message content missing.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **misc**: Fix tool call message content missing, closes [#11116](https://github.com/lobehub/lobe-chat/issues/11116) ([885964e](https://github.com/lobehub/lobe-chat/commit/885964e))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.194](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.193...v2.0.0-next.194)
<sup>Released on **2026-01-03**</sup>
#### 💄 Styles
- **misc**: Update i18n.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Styles
- **misc**: Update i18n, closes [#11115](https://github.com/lobehub/lobe-chat/issues/11115) ([072e0dd](https://github.com/lobehub/lobe-chat/commit/072e0dd))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.193](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.192...v2.0.0-next.193)
<sup>Released on **2026-01-02**</sup>
#### 🐛 Bug Fixes
- **database**: Add userId authorization check in removeFilesFromKnowledgeBase.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **database**: Add userId authorization check in removeFilesFromKnowledgeBase, closes [#11108](https://github.com/lobehub/lobe-chat/issues/11108) ([2c1762b](https://github.com/lobehub/lobe-chat/commit/2c1762b))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.192](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.191...v2.0.0-next.192)
<sup>Released on **2026-01-02**</sup>
#### 🐛 Bug Fixes
- **misc**: Fix model edit icon missing.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **misc**: Fix model edit icon missing, closes [#11105](https://github.com/lobehub/lobe-chat/issues/11105) ([0f88995](https://github.com/lobehub/lobe-chat/commit/0f88995))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.191](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.190...v2.0.0-next.191)
<sup>Released on **2026-01-02**</sup>
#### ♻ Code Refactoring
- **misc**: Refactor to remove meta in message.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Code refactoring
- **misc**: Refactor to remove meta in message, closes [#11103](https://github.com/lobehub/lobe-chat/issues/11103) ([527c1cd](https://github.com/lobehub/lobe-chat/commit/527c1cd))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.190](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.189...v2.0.0-next.190)
<sup>Released on **2026-01-02**</sup>
#### 💄 Styles
- **misc**: Update i18n.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Styles
- **misc**: Update i18n, closes [#11100](https://github.com/lobehub/lobe-chat/issues/11100) ([bb4571b](https://github.com/lobehub/lobe-chat/commit/bb4571b))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.189](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.188...v2.0.0-next.189)
<sup>Released on **2026-01-01**</sup>
#### ♻ Code Refactoring
- **misc**: Migrate to new DropdownMenuV2 and showContextMenu API.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Code refactoring
- **misc**: Migrate to new DropdownMenuV2 and showContextMenu API, closes [#11079](https://github.com/lobehub/lobe-chat/issues/11079) ([04cfc0e](https://github.com/lobehub/lobe-chat/commit/04cfc0e))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.188](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.187...v2.0.0-next.188)
<sup>Released on **2026-01-01**</sup>
#### 💄 Styles
- **misc**: Improve tools UI and fix Google schema compatibility.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Styles
- **misc**: Improve tools UI and fix Google schema compatibility, closes [#11096](https://github.com/lobehub/lobe-chat/issues/11096) ([70a9cff](https://github.com/lobehub/lobe-chat/commit/70a9cff))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.187](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.186...v2.0.0-next.187)
<sup>Released on **2026-01-01**</sup>
#### 💄 Styles
- **misc**: Add Gemini 3 Flash & Doubao Seed 1.8 models.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Styles
- **misc**: Add Gemini 3 Flash & Doubao Seed 1.8 models, closes [#10832](https://github.com/lobehub/lobe-chat/issues/10832) ([cb35935](https://github.com/lobehub/lobe-chat/commit/cb35935))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.186](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.185...v2.0.0-next.186)
<sup>Released on **2026-01-01**</sup>
#### ♻ Code Refactoring
- **misc**: Refactor oidc env to auth env.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Code refactoring
- **misc**: Refactor oidc env to auth env, closes [#11095](https://github.com/lobehub/lobe-chat/issues/11095) ([6e8d4ff](https://github.com/lobehub/lobe-chat/commit/6e8d4ff))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.185](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.184...v2.0.0-next.185)
<sup>Released on **2026-01-01**</sup>
#### 💄 Styles
- **misc**: Update i18n.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Styles
- **misc**: Update i18n, closes [#11085](https://github.com/lobehub/lobe-chat/issues/11085) ([0941a52](https://github.com/lobehub/lobe-chat/commit/0941a52))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.184](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.183...v2.0.0-next.184)
<sup>Released on **2026-01-01**</sup>
#### 💄 Styles
- **misc**: Improve loading and local-system render.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Styles
- **misc**: Improve loading and local-system render, closes [#11087](https://github.com/lobehub/lobe-chat/issues/11087) ([44630bc](https://github.com/lobehub/lobe-chat/commit/44630bc))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.183](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.182...v2.0.0-next.183)
<sup>Released on **2025-12-31**</sup>
#### 🐛 Bug Fixes
- **store**: Clear new key data when switchTopic to new state.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **store**: Clear new key data when switchTopic to new state, closes [#11078](https://github.com/lobehub/lobe-chat/issues/11078) ([180ea14](https://github.com/lobehub/lobe-chat/commit/180ea14))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.182](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.181...v2.0.0-next.182)
<sup>Released on **2025-12-31**</sup>
#### ✨ Features
- **misc**: Brand new 2.0 ui for next.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's improved
- **misc**: Brand new 2.0 ui for next ([e5d6d3d](https://github.com/lobehub/lobe-chat/commit/e5d6d3d))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.181](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.180...v2.0.0-next.181)
<sup>Released on **2025-12-31**</sup>
#### ♻ Code Refactoring
- **userMemories**: Added `benchmark_locomo` as source unify use the of source type.
- **misc**: Add builtin tools, clean code, clean desktop relative code, clean page editor, flatten i18n keys and extract hardcoded strings in desktop, i18n formatting optimization, improve modal handling with createRawModal, move code-interpreter to single packages, refactor builtin-tool implement, refactor hooks, refactor implement, refactor implement for desktop, refactor local-system, refactor service, refactor static style, refactor to use better underline style, refactor to use better underline style, refactor tool prompt injection, refactor ui and layout, refactor with editor runtime, refactor with electron, refactor with es-toolkit, remove desktop-specific upload logic, rename browser identifier from 'chat' to 'app', tools ui, use /f/:fid as file mode, use supervisor role for agent group supervisor.
#### ✨ Features
- **auth**: Add confirm password field and integrate business signup logic, add useBusinessSignup hook for business signup functionality, enhance BetterAuthSignUpForm with businessElement and update useSignUp hook for improved signup process, integrate business sign-in features and update social sign-in logic, update useBusinessSignin to include getAdditionalData function for enhanced sign-in process.
- **desktop**: MacOS About menu should navigate to Settings About tab.
- **layout**: Integrate BusinessGlobalProvider for conditional rendering based on business features.
- **memory-user-memory**: Added LoCoMo dataset loader & converter & exporter, support to extract memories from LoCoMo dataset, support to load in memory, and extract from in-memory memory sources.
- **model**: Improve model list UI and add disabled models management.
- **referral**: Add backfill referral code i18n keys.
- **userMemories**: Apply userMemories.enable from settings for injecting, use capturedAt for time of memory entries, use honorific title for identity memory.
- **misc**: Add a white waitlist in edge config env, add always show tools render in createPlan & createDoc tools, add batch tasks ui, add Bundle Analyzer workflow for detailed bundle size analysis, add business features support with new components and hooks, add business settings features with dynamic loading for Plans, Funds, Usage, Billing, and Referral tabs, add db and schema feature, add home page create group builder button, Add i18n UI locales and improve tool types, add like action in community detail, add memory implement, add subscription settings group with dynamic loading for Plans, Funds, Usage, Billing, and Referral tabs, add the market auth auto generate way, Add turbopack configuration support to CustomNextConfig, add user memory, agent builder, agent builder, agent builder and group builder, app ui page, brand new 2.0 ui for next, buildin some tools should save into docs, code-interpreter tool, code-interpreter tool, code-interpreter tool, desktop feature, enhance desktop onboarding with sign out and localization, enhance macOS desktop permissions and onboarding, enhance onboarding process by removing mode selection step and adding export functionality in advanced settings, file search feature, gtd create plan support streaming render, implement agent builder, implement builtin agents packages, implement memories package, implement Redis caching for presigned URLs in file proxy service, implement server data feature, include Subscription settings group in the Accordion component, Integrate bcryptjs for password verification in BetterAuth, integrate BrandingProviderCard and update Provider components for branding support, onboarding ui, page and knowledge base, rebranding total UI of app, refactor authentication handler to support dynamic loading of better-auth and next-auth, refactor desktop implement with brand new 2.0, rename codeinterpreter into lobe sandbox, server implement, support CMD K, support exec async sub agent task, support export and import topic JSON, support files upload in chat input, support notebook tool, support swr local cache, topic message swr cache, translate AI model descriptions to English, update agent builder ui, update create group chat use builder, update gtd tools( use editor & update metadata ), update user memory embedding model selection based on business features, user memory, user memory, user onboarding, when use usesend to create agent/group, the model should override by lobeAi, wrap ConversationArea and ModelSwitchPanel in TooltipGroup for enhanced UI.
#### 🐛 Bug Fixes
- **ci**: Skip backend routes in bundle analyzer build.
- **desktop**: prevent window resize when onboarding, add safe top edge for message container.
- **i18n**: Translate plugin.ts locale to English.
- **image-generation**: Update chargeBeforeGenerate to return ChargeResult and include configForDatabase in parameters.
- **memory-user-memory**: Should pre-process date & time.
- **observability-otel**: Typo in package name.
- **prebuild**: Correct syntax in partialBuildPages array.
- **translation**: Add fallback for all English locale variants.
- **userMemories**: 404/405 issue due to incorrectly used workflow name and mounted catch-all route, missing base memory as part of context, must assign workflow id, should use `context.invoke` for workflow instead of `context.run`, skip to handle WorkflowAbort, use date & time for building context, workflow id build issue.
- **misc**: Agent profiles update, agent tools config set, editor placeholder, bump charts 3.0.4 to fix import es path, fix anthropic thinking budget, fix async task and improve tool style, fix default waitlist bug, fix delete agent group bug, Fix desktop test cases and refactor translations, Fix desktop test cases and refactor translations, fix gemini 3 model thinking issue, fix gemini 3 pro parallel tool use, fix gemini 3 thinking params, fix identity memory not working, fix supervisor flag, fix thread not working issue, fix when use branch topic,the branch index error problem, fixed the welcome card the create button not work, handle session invalidation on 401 error by logging out signed-in users, improve test infrastructure and mock configurations, locale resolve bug with ESM module loading, page agent editor, prevent redundant login redirect when already on auth pages, redis read json object, remove openapi pkg patch file, slove input editor on pause emit, slove swr mutate not work in Cache Provider, slove the group add member checkbox not work, slove the model select null problem, slove the mutate not work problem, slove when click agentbuilder should clean topic, slove when first call thread, not show ai chat message, support retry error message and fix continueGenerationMessage, update contextMenu in group tools message, update OFFICIAL_URL to app.lobehub.com, update PlanTag link paths for subscription settings, update test snapshots for model description changes, when use agentbuilder the topic id should use new & clear topic….
#### 💄 Styles
- **misc**: Improve ExecTask and task message UI, improve gtd tool inspector and todo list, improve page document tool inspector UI, improve RunCommand Inspector, rebranding chat ui, refactor UI in features, rerun i18n, setting style, support streaming and display ui for group mode, support tool streaming and title custom render, update i18n, Update i18n microcopy, update ui.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Code refactoring
- **userMemories**: Added `benchmark_locomo` as source unify use the of source type, closes [#10922](https://github.com/lobehub/lobe-chat/issues/10922) ([03342a7](https://github.com/lobehub/lobe-chat/commit/03342a7))
- **misc**: Add builtin tools ([26e73cc](https://github.com/lobehub/lobe-chat/commit/26e73cc))
- **misc**: Clean code ([4ddb491](https://github.com/lobehub/lobe-chat/commit/4ddb491))
- **misc**: Clean desktop relative code ([ffd7d23](https://github.com/lobehub/lobe-chat/commit/ffd7d23))
- **misc**: Clean page editor, closes [#10966](https://github.com/lobehub/lobe-chat/issues/10966) ([15410d1](https://github.com/lobehub/lobe-chat/commit/15410d1))
- **misc**: Flatten i18n keys and extract hardcoded strings in desktop, closes [#10939](https://github.com/lobehub/lobe-chat/issues/10939) ([e5f3a58](https://github.com/lobehub/lobe-chat/commit/e5f3a58))
- **misc**: I18n formatting optimization, closes [#10929](https://github.com/lobehub/lobe-chat/issues/10929) [#10933](https://github.com/lobehub/lobe-chat/issues/10933) ([d692a37](https://github.com/lobehub/lobe-chat/commit/d692a37))
- **misc**: Improve modal handling with createRawModal, closes [#11071](https://github.com/lobehub/lobe-chat/issues/11071) ([f5314c5](https://github.com/lobehub/lobe-chat/commit/f5314c5))
- **misc**: Move code-interpreter to single packages ([1fa4357](https://github.com/lobehub/lobe-chat/commit/1fa4357))
- **misc**: Refactor builtin-tool implement ([9ede8e7](https://github.com/lobehub/lobe-chat/commit/9ede8e7))
- **misc**: Refactor hooks ([e3fa62e](https://github.com/lobehub/lobe-chat/commit/e3fa62e))
- **misc**: Refactor implement ([34d059f](https://github.com/lobehub/lobe-chat/commit/34d059f))
- **misc**: Refactor implement for desktop ([27f101f](https://github.com/lobehub/lobe-chat/commit/27f101f))
- **misc**: Refactor local-system ([a69221f](https://github.com/lobehub/lobe-chat/commit/a69221f))
- **misc**: Refactor service ([91bbbf5](https://github.com/lobehub/lobe-chat/commit/91bbbf5))
- **misc**: Refactor static style, closes [#11010](https://github.com/lobehub/lobe-chat/issues/11010) ([d865e27](https://github.com/lobehub/lobe-chat/commit/d865e27))
- **misc**: Refactor to use better underline style ([784bb58](https://github.com/lobehub/lobe-chat/commit/784bb58))
- **misc**: Refactor to use better underline style ([5e10ac8](https://github.com/lobehub/lobe-chat/commit/5e10ac8))
- **misc**: Refactor tool prompt injection ([6099ac3](https://github.com/lobehub/lobe-chat/commit/6099ac3))
- **misc**: Refactor ui and layout ([436d9e5](https://github.com/lobehub/lobe-chat/commit/436d9e5))
- **misc**: Refactor with editor runtime ([be2b41c](https://github.com/lobehub/lobe-chat/commit/be2b41c))
- **misc**: Refactor with electron ([849ee3d](https://github.com/lobehub/lobe-chat/commit/849ee3d))
- **misc**: Refactor with es-toolkit ([1848d27](https://github.com/lobehub/lobe-chat/commit/1848d27))
- **misc**: Remove desktop-specific upload logic, closes [#11070](https://github.com/lobehub/lobe-chat/issues/11070) ([475065e](https://github.com/lobehub/lobe-chat/commit/475065e))
- **misc**: Rename browser identifier from 'chat' to 'app', closes [#10940](https://github.com/lobehub/lobe-chat/issues/10940) ([dc870c7](https://github.com/lobehub/lobe-chat/commit/dc870c7))
- **misc**: Tools ui ([6bf4546](https://github.com/lobehub/lobe-chat/commit/6bf4546))
- **misc**: Use /f/:fid as file mode ([3b01174](https://github.com/lobehub/lobe-chat/commit/3b01174))
- **misc**: Use supervisor role for agent group supervisor ([0ca823f](https://github.com/lobehub/lobe-chat/commit/0ca823f))
#### What's improved
- **auth**: Add confirm password field and integrate business signup logic ([2ccd5c7](https://github.com/lobehub/lobe-chat/commit/2ccd5c7))
- **auth**: Add useBusinessSignup hook for business signup functionality ([3efb6cc](https://github.com/lobehub/lobe-chat/commit/3efb6cc))
- **auth**: Enhance BetterAuthSignUpForm with businessElement and update useSignUp hook for improved signup process ([991d8c1](https://github.com/lobehub/lobe-chat/commit/991d8c1))
- **auth**: Integrate business sign-in features and update social sign-in logic ([6dc7916](https://github.com/lobehub/lobe-chat/commit/6dc7916))
- **auth**: Update useBusinessSignin to include getAdditionalData function for enhanced sign-in process ([c8e3bc9](https://github.com/lobehub/lobe-chat/commit/c8e3bc9))
- **desktop**: MacOS About menu should navigate to Settings About tab, closes [#10942](https://github.com/lobehub/lobe-chat/issues/10942) ([1a4f456](https://github.com/lobehub/lobe-chat/commit/1a4f456))
- **layout**: Integrate BusinessGlobalProvider for conditional rendering based on business features ([52c7a49](https://github.com/lobehub/lobe-chat/commit/52c7a49))
- **memory-user-memory**: Added LoCoMo dataset loader & converter & exporter, closes [#10923](https://github.com/lobehub/lobe-chat/issues/10923) ([a5dd785](https://github.com/lobehub/lobe-chat/commit/a5dd785))
- **memory-user-memory**: Support to extract memories from LoCoMo dataset, closes [#10925](https://github.com/lobehub/lobe-chat/issues/10925) ([c7c7d6f](https://github.com/lobehub/lobe-chat/commit/c7c7d6f))
- **memory-user-memory**: Support to load in memory, and extract from in-memory memory sources, closes [#10924](https://github.com/lobehub/lobe-chat/issues/10924) ([9ac3ce7](https://github.com/lobehub/lobe-chat/commit/9ac3ce7))
- **model**: Improve model list UI and add disabled models management, closes [#11036](https://github.com/lobehub/lobe-chat/issues/11036) ([4faa65c](https://github.com/lobehub/lobe-chat/commit/4faa65c))
- **referral**: Add backfill referral code i18n keys ([bbf62ce](https://github.com/lobehub/lobe-chat/commit/bbf62ce))
- **userMemories**: Apply userMemories.enable from settings for injecting, closes [#11038](https://github.com/lobehub/lobe-chat/issues/11038) ([1cc0e8c](https://github.com/lobehub/lobe-chat/commit/1cc0e8c))
- **userMemories**: Use capturedAt for time of memory entries, closes [#11037](https://github.com/lobehub/lobe-chat/issues/11037) ([5615d20](https://github.com/lobehub/lobe-chat/commit/5615d20))
- **userMemories**: Use honorific title for identity memory, closes [#11039](https://github.com/lobehub/lobe-chat/issues/11039) ([ab61c69](https://github.com/lobehub/lobe-chat/commit/ab61c69))
- **misc**: Add a white waitlist in edge config env, closes [#11009](https://github.com/lobehub/lobe-chat/issues/11009) ([88f22f4](https://github.com/lobehub/lobe-chat/commit/88f22f4))
- **misc**: Add always show tools render in createPlan & createDoc tools, closes [#10937](https://github.com/lobehub/lobe-chat/issues/10937) ([c224951](https://github.com/lobehub/lobe-chat/commit/c224951))
- **misc**: Add batch tasks ui ([80587ae](https://github.com/lobehub/lobe-chat/commit/80587ae))
- **misc**: Add Bundle Analyzer workflow for detailed bundle size analysis ([596e489](https://github.com/lobehub/lobe-chat/commit/596e489))
- **misc**: Add business features support with new components and hooks ([1dccc04](https://github.com/lobehub/lobe-chat/commit/1dccc04))
- **misc**: Add business settings features with dynamic loading for Plans, Funds, Usage, Billing, and Referral tabs ([35c6ad9](https://github.com/lobehub/lobe-chat/commit/35c6ad9))
- **misc**: Add db and schema feature ([9e47c33](https://github.com/lobehub/lobe-chat/commit/9e47c33))
- **misc**: Add home page create group builder button, closes [#10904](https://github.com/lobehub/lobe-chat/issues/10904) ([3183189](https://github.com/lobehub/lobe-chat/commit/3183189))
- **misc**: Add i18n UI locales and improve tool types, closes [#10964](https://github.com/lobehub/lobe-chat/issues/10964) ([0e89ce5](https://github.com/lobehub/lobe-chat/commit/0e89ce5))
- **misc**: Add like action in community detail, closes [#10971](https://github.com/lobehub/lobe-chat/issues/10971) ([c11d802](https://github.com/lobehub/lobe-chat/commit/c11d802))
- **misc**: Add memory implement ([fdae83c](https://github.com/lobehub/lobe-chat/commit/fdae83c))
- **misc**: Add subscription settings group with dynamic loading for Plans, Funds, Usage, Billing, and Referral tabs ([2ddc876](https://github.com/lobehub/lobe-chat/commit/2ddc876))
- **misc**: Add the market auth auto generate way, closes [#10993](https://github.com/lobehub/lobe-chat/issues/10993) ([849ac73](https://github.com/lobehub/lobe-chat/commit/849ac73))
- **misc**: Add turbopack configuration support to CustomNextConfig ([2e7076a](https://github.com/lobehub/lobe-chat/commit/2e7076a))
- **misc**: Add user memory ([c305889](https://github.com/lobehub/lobe-chat/commit/c305889))
- **misc**: Agent builder ([ede0ed6](https://github.com/lobehub/lobe-chat/commit/ede0ed6))
- **misc**: Agent builder ([e3c9454](https://github.com/lobehub/lobe-chat/commit/e3c9454))
- **misc**: Agent builder and group builder ([d735e2c](https://github.com/lobehub/lobe-chat/commit/d735e2c))
- **misc**: App ui page ([78d07c0](https://github.com/lobehub/lobe-chat/commit/78d07c0))
- **misc**: Brand new 2.0 ui for next ([f7d724f](https://github.com/lobehub/lobe-chat/commit/f7d724f))
- **misc**: Buildin some tools should save into docs, closes [#10935](https://github.com/lobehub/lobe-chat/issues/10935) ([be4c17d](https://github.com/lobehub/lobe-chat/commit/be4c17d))
- **misc**: Code-interpreter tool ([1940914](https://github.com/lobehub/lobe-chat/commit/1940914))
- **misc**: Code-interpreter tool ([c931909](https://github.com/lobehub/lobe-chat/commit/c931909))
- **misc**: Code-interpreter tool ([baa29c8](https://github.com/lobehub/lobe-chat/commit/baa29c8))
- **misc**: Desktop feature ([ac93637](https://github.com/lobehub/lobe-chat/commit/ac93637))
- **misc**: Enhance desktop onboarding with sign out and localization, closes [#11033](https://github.com/lobehub/lobe-chat/issues/11033) ([34a6312](https://github.com/lobehub/lobe-chat/commit/34a6312))
- **misc**: Enhance macOS desktop permissions and onboarding, closes [#11016](https://github.com/lobehub/lobe-chat/issues/11016) ([9db8da8](https://github.com/lobehub/lobe-chat/commit/9db8da8))
- **misc**: Enhance onboarding process by removing mode selection step and adding export functionality in advanced settings ([8b6c30e](https://github.com/lobehub/lobe-chat/commit/8b6c30e))
- **misc**: File search feature ([9786d64](https://github.com/lobehub/lobe-chat/commit/9786d64))
- **misc**: Gtd create plan support streaming render, closes [#11034](https://github.com/lobehub/lobe-chat/issues/11034) ([74d3555](https://github.com/lobehub/lobe-chat/commit/74d3555))
- **misc**: Implement agent builder ([f638b97](https://github.com/lobehub/lobe-chat/commit/f638b97))
- **misc**: Implement builtin agents packages ([2255a7c](https://github.com/lobehub/lobe-chat/commit/2255a7c))
- **misc**: Implement memories package ([7f94ef1](https://github.com/lobehub/lobe-chat/commit/7f94ef1))
- **misc**: Implement Redis caching for presigned URLs in file proxy service ([15722f1](https://github.com/lobehub/lobe-chat/commit/15722f1))
- **misc**: Implement server data feature ([9c46c6e](https://github.com/lobehub/lobe-chat/commit/9c46c6e))
- **misc**: Include Subscription settings group in the Accordion component ([8f2d57d](https://github.com/lobehub/lobe-chat/commit/8f2d57d))
- **misc**: Integrate bcryptjs for password verification in BetterAuth ([180ebfd](https://github.com/lobehub/lobe-chat/commit/180ebfd))
- **misc**: Integrate BrandingProviderCard and update Provider components for branding support ([6b5ce79](https://github.com/lobehub/lobe-chat/commit/6b5ce79))
- **misc**: Onboarding ui ([81d33a6](https://github.com/lobehub/lobe-chat/commit/81d33a6))
- **misc**: Page and knowledge base ([492d3cc](https://github.com/lobehub/lobe-chat/commit/492d3cc))
- **misc**: Rebranding total UI of app ([13ca81b](https://github.com/lobehub/lobe-chat/commit/13ca81b))
- **misc**: Refactor authentication handler to support dynamic loading of better-auth and next-auth ([d6419e4](https://github.com/lobehub/lobe-chat/commit/d6419e4))
- **misc**: Refactor desktop implement with brand new 2.0 ([10e048c](https://github.com/lobehub/lobe-chat/commit/10e048c))
- **misc**: Rename codeinterpreter into lobe sandbox, closes [#11076](https://github.com/lobehub/lobe-chat/issues/11076) ([2a631b4](https://github.com/lobehub/lobe-chat/commit/2a631b4))
- **misc**: Server implement ([685a6cd](https://github.com/lobehub/lobe-chat/commit/685a6cd))
- **misc**: Support CMD K ([d2bd8a6](https://github.com/lobehub/lobe-chat/commit/d2bd8a6))
- **misc**: Support exec async sub agent task ([dba1acf](https://github.com/lobehub/lobe-chat/commit/dba1acf))
- **misc**: Support export and import topic JSON, closes [#10885](https://github.com/lobehub/lobe-chat/issues/10885) ([0c5a41f](https://github.com/lobehub/lobe-chat/commit/0c5a41f))
- **misc**: Support files upload in chat input, closes [#10967](https://github.com/lobehub/lobe-chat/issues/10967) ([60eba45](https://github.com/lobehub/lobe-chat/commit/60eba45))
- **misc**: Support notebook tool, closes [#10902](https://github.com/lobehub/lobe-chat/issues/10902) ([e05375f](https://github.com/lobehub/lobe-chat/commit/e05375f))
- **misc**: Support swr local cache, closes [#10884](https://github.com/lobehub/lobe-chat/issues/10884) ([bc3f3e2](https://github.com/lobehub/lobe-chat/commit/bc3f3e2))
- **misc**: Topic message swr cache, closes [#10886](https://github.com/lobehub/lobe-chat/issues/10886) ([613a404](https://github.com/lobehub/lobe-chat/commit/613a404))
- **misc**: Translate AI model descriptions to English, closes [#10989](https://github.com/lobehub/lobe-chat/issues/10989) ([36ea258](https://github.com/lobehub/lobe-chat/commit/36ea258))
- **misc**: Update agent builder ui, closes [#10996](https://github.com/lobehub/lobe-chat/issues/10996) ([704ef7f](https://github.com/lobehub/lobe-chat/commit/704ef7f))
- **misc**: Update create group chat use builder, closes [#11030](https://github.com/lobehub/lobe-chat/issues/11030) ([7ae24c2](https://github.com/lobehub/lobe-chat/commit/7ae24c2))
- **misc**: Update gtd tools( use editor & update metadata ), closes [#11029](https://github.com/lobehub/lobe-chat/issues/11029) ([4a47ea0](https://github.com/lobehub/lobe-chat/commit/4a47ea0))
- **misc**: Update user memory embedding model selection based on business features ([c026117](https://github.com/lobehub/lobe-chat/commit/c026117))
- **misc**: User memory ([d5ce144](https://github.com/lobehub/lobe-chat/commit/d5ce144))
- **misc**: User memory ([49ffcb5](https://github.com/lobehub/lobe-chat/commit/49ffcb5))
- **misc**: User onboarding ([5e59388](https://github.com/lobehub/lobe-chat/commit/5e59388))
- **misc**: When use usesend to create agent/group, the model should override by lobeAi, closes [#11048](https://github.com/lobehub/lobe-chat/issues/11048) ([754ffe1](https://github.com/lobehub/lobe-chat/commit/754ffe1))
- **misc**: Wrap ConversationArea and ModelSwitchPanel in TooltipGroup for enhanced UI ([672bcf7](https://github.com/lobehub/lobe-chat/commit/672bcf7))
#### What's fixed
- **ci**: Skip backend routes in bundle analyzer build, closes [#10944](https://github.com/lobehub/lobe-chat/issues/10944) ([2fc3b42](https://github.com/lobehub/lobe-chat/commit/2fc3b42))
- **desktop**: prevent window resize when onboarding, closes [#10887](https://github.com/lobehub/lobe-chat/issues/10887) ([c29c02b](https://github.com/lobehub/lobe-chat/commit/c29c02b))
- **desktop**: Add safe top edge for message container, closes [#10908](https://github.com/lobehub/lobe-chat/issues/10908) ([2558b47](https://github.com/lobehub/lobe-chat/commit/2558b47))
- **i18n**: Translate plugin.ts locale to English, closes [#10972](https://github.com/lobehub/lobe-chat/issues/10972) ([89f89c7](https://github.com/lobehub/lobe-chat/commit/89f89c7))
- **image-generation**: Update chargeBeforeGenerate to return ChargeResult and include configForDatabase in parameters ([4f2a683](https://github.com/lobehub/lobe-chat/commit/4f2a683))
- **memory-user-memory**: Should pre-process date & time, closes [#10979](https://github.com/lobehub/lobe-chat/issues/10979) ([c2bcf73](https://github.com/lobehub/lobe-chat/commit/c2bcf73))
- **observability-otel**: Typo in package name, closes [#11025](https://github.com/lobehub/lobe-chat/issues/11025) ([63224dd](https://github.com/lobehub/lobe-chat/commit/63224dd))
- **prebuild**: Correct syntax in partialBuildPages array ([9580672](https://github.com/lobehub/lobe-chat/commit/9580672))
- **translation**: Add fallback for all English locale variants, closes [#10984](https://github.com/lobehub/lobe-chat/issues/10984) ([ce46996](https://github.com/lobehub/lobe-chat/commit/ce46996))
- **userMemories**: 404/405 issue due to incorrectly used workflow name and mounted catch-all route, closes [#10995](https://github.com/lobehub/lobe-chat/issues/10995) ([45996c6](https://github.com/lobehub/lobe-chat/commit/45996c6))
- **userMemories**: Missing base memory as part of context, closes [#11040](https://github.com/lobehub/lobe-chat/issues/11040) ([3c9bafe](https://github.com/lobehub/lobe-chat/commit/3c9bafe))
- **userMemories**: Must assign workflow id, closes [#11021](https://github.com/lobehub/lobe-chat/issues/11021) ([78b0c7b](https://github.com/lobehub/lobe-chat/commit/78b0c7b))
- **userMemories**: Should use `context.invoke` for workflow instead of `context.run`, closes [#10994](https://github.com/lobehub/lobe-chat/issues/10994) ([6592d10](https://github.com/lobehub/lobe-chat/commit/6592d10))
- **userMemories**: Skip to handle WorkflowAbort, closes [#11031](https://github.com/lobehub/lobe-chat/issues/11031) ([17124a8](https://github.com/lobehub/lobe-chat/commit/17124a8))
- **userMemories**: Use date & time for building context, closes [#10978](https://github.com/lobehub/lobe-chat/issues/10978) ([15bc6bc](https://github.com/lobehub/lobe-chat/commit/15bc6bc))
- **userMemories**: Workflow id build issue, closes [#10998](https://github.com/lobehub/lobe-chat/issues/10998) ([0b110b6](https://github.com/lobehub/lobe-chat/commit/0b110b6))
- **misc**: Agent profiles update, agent tools config set, editor placeholder, closes [#11074](https://github.com/lobehub/lobe-chat/issues/11074) ([f7cbfe4](https://github.com/lobehub/lobe-chat/commit/f7cbfe4))
- **misc**: Bump charts 3.0.4 to fix import es path, closes [#10898](https://github.com/lobehub/lobe-chat/issues/10898) ([6d7dce7](https://github.com/lobehub/lobe-chat/commit/6d7dce7))
- **misc**: Fix anthropic thinking budget ([6e19bd3](https://github.com/lobehub/lobe-chat/commit/6e19bd3))
- **misc**: Fix async task and improve tool style ([1aa1c04](https://github.com/lobehub/lobe-chat/commit/1aa1c04))
- **misc**: Fix default waitlist bug ([de62035](https://github.com/lobehub/lobe-chat/commit/de62035))
- **misc**: Fix delete agent group bug ([0fe0d6f](https://github.com/lobehub/lobe-chat/commit/0fe0d6f))
- **misc**: Fix desktop test cases and refactor translations, closes [#10956](https://github.com/lobehub/lobe-chat/issues/10956) ([568235c](https://github.com/lobehub/lobe-chat/commit/568235c))
- **misc**: Fix desktop test cases and refactor translations, closes [#10955](https://github.com/lobehub/lobe-chat/issues/10955) ([b3520a2](https://github.com/lobehub/lobe-chat/commit/b3520a2))
- **misc**: Fix gemini 3 model thinking issue ([69f4cf3](https://github.com/lobehub/lobe-chat/commit/69f4cf3))
- **misc**: Fix gemini 3 pro parallel tool use ([a0cc9c3](https://github.com/lobehub/lobe-chat/commit/a0cc9c3))
- **misc**: Fix gemini 3 thinking params ([89363b2](https://github.com/lobehub/lobe-chat/commit/89363b2))
- **misc**: Fix identity memory not working, closes [#10916](https://github.com/lobehub/lobe-chat/issues/10916) ([fbd0b66](https://github.com/lobehub/lobe-chat/commit/fbd0b66))
- **misc**: Fix supervisor flag ([fc20dbc](https://github.com/lobehub/lobe-chat/commit/fc20dbc))
- **misc**: Fix thread not working issue ([7dd30eb](https://github.com/lobehub/lobe-chat/commit/7dd30eb))
- **misc**: Fix when use branch topic,the branch index error problem, closes [#11049](https://github.com/lobehub/lobe-chat/issues/11049) ([34b5a32](https://github.com/lobehub/lobe-chat/commit/34b5a32))
- **misc**: Fixed the welcome card the create button not work, closes [#11055](https://github.com/lobehub/lobe-chat/issues/11055) ([00e81f1](https://github.com/lobehub/lobe-chat/commit/00e81f1))
- **misc**: Handle session invalidation on 401 error by logging out signed-in users ([499bd4a](https://github.com/lobehub/lobe-chat/commit/499bd4a))
- **misc**: Improve test infrastructure and mock configurations, closes [#11028](https://github.com/lobehub/lobe-chat/issues/11028) ([da4eb9c](https://github.com/lobehub/lobe-chat/commit/da4eb9c))
- **misc**: Locale resolve bug with ESM module loading, closes [#11018](https://github.com/lobehub/lobe-chat/issues/11018) ([770c872](https://github.com/lobehub/lobe-chat/commit/770c872))
- **misc**: Page agent editor, closes [#10953](https://github.com/lobehub/lobe-chat/issues/10953) ([61b3031](https://github.com/lobehub/lobe-chat/commit/61b3031))
- **misc**: Prevent redundant login redirect when already on auth pages ([1a5049c](https://github.com/lobehub/lobe-chat/commit/1a5049c))
- **misc**: Redis read json object ([1718fa3](https://github.com/lobehub/lobe-chat/commit/1718fa3))
- **misc**: Remove openapi pkg patch file, closes [#10910](https://github.com/lobehub/lobe-chat/issues/10910) ([a34c111](https://github.com/lobehub/lobe-chat/commit/a34c111))
- **misc**: Slove input editor on pause emit, closes [#11051](https://github.com/lobehub/lobe-chat/issues/11051) ([d102d47](https://github.com/lobehub/lobe-chat/commit/d102d47))
- **misc**: Slove swr mutate not work in Cache Provider, closes [#10895](https://github.com/lobehub/lobe-chat/issues/10895) ([b3fbffe](https://github.com/lobehub/lobe-chat/commit/b3fbffe))
- **misc**: Slove the group add member checkbox not work, closes [#11045](https://github.com/lobehub/lobe-chat/issues/11045) [#11042](https://github.com/lobehub/lobe-chat/issues/11042) ([91d3f74](https://github.com/lobehub/lobe-chat/commit/91d3f74))
- **misc**: Slove the model select null problem, closes [#10988](https://github.com/lobehub/lobe-chat/issues/10988) ([50aa304](https://github.com/lobehub/lobe-chat/commit/50aa304))
- **misc**: Slove the mutate not work problem, closes [#10947](https://github.com/lobehub/lobe-chat/issues/10947) ([78ca5eb](https://github.com/lobehub/lobe-chat/commit/78ca5eb))
- **misc**: Slove when click agentbuilder should clean topic, closes [#11068](https://github.com/lobehub/lobe-chat/issues/11068) ([048bd66](https://github.com/lobehub/lobe-chat/commit/048bd66))
- **misc**: Slove when first call thread, not show ai chat message, closes [#10878](https://github.com/lobehub/lobe-chat/issues/10878) ([5a79cb9](https://github.com/lobehub/lobe-chat/commit/5a79cb9))
- **misc**: Support retry error message and fix continueGenerationMessage ([8bf85fb](https://github.com/lobehub/lobe-chat/commit/8bf85fb))
- **misc**: Update contextMenu in group tools message, closes [#11056](https://github.com/lobehub/lobe-chat/issues/11056) ([8b49414](https://github.com/lobehub/lobe-chat/commit/8b49414))
- **misc**: Update OFFICIAL_URL to app.lobehub.com, closes [#11015](https://github.com/lobehub/lobe-chat/issues/11015) ([f9e11d0](https://github.com/lobehub/lobe-chat/commit/f9e11d0))
- **misc**: Update PlanTag link paths for subscription settings ([ada71d3](https://github.com/lobehub/lobe-chat/commit/ada71d3))
- **misc**: Update test snapshots for model description changes, closes [#11008](https://github.com/lobehub/lobe-chat/issues/11008) ([626e808](https://github.com/lobehub/lobe-chat/commit/626e808))
- **misc**: When use agentbuilder the topic id should use new & clear topic…, closes [#10983](https://github.com/lobehub/lobe-chat/issues/10983) ([0b2b096](https://github.com/lobehub/lobe-chat/commit/0b2b096))
#### Styles
- **misc**: Improve ExecTask and task message UI ([977a700](https://github.com/lobehub/lobe-chat/commit/977a700))
- **misc**: Improve gtd tool inspector and todo list ([0664563](https://github.com/lobehub/lobe-chat/commit/0664563))
- **misc**: Improve page document tool inspector UI, closes [#10977](https://github.com/lobehub/lobe-chat/issues/10977) ([7f69cb1](https://github.com/lobehub/lobe-chat/commit/7f69cb1))
- **misc**: Improve RunCommand Inspector ([0751fa4](https://github.com/lobehub/lobe-chat/commit/0751fa4))
- **misc**: Rebranding chat ui ([ad14222](https://github.com/lobehub/lobe-chat/commit/ad14222))
- **misc**: Refactor UI in features ([83e689f](https://github.com/lobehub/lobe-chat/commit/83e689f))
- **misc**: Rerun i18n ([80f511c](https://github.com/lobehub/lobe-chat/commit/80f511c))
- **misc**: Setting style ([e8c755f](https://github.com/lobehub/lobe-chat/commit/e8c755f))
- **misc**: Support streaming and display ui for group mode ([f708cdb](https://github.com/lobehub/lobe-chat/commit/f708cdb))
- **misc**: Support tool streaming and title custom render, closes [#10976](https://github.com/lobehub/lobe-chat/issues/10976) ([576ccd6](https://github.com/lobehub/lobe-chat/commit/576ccd6))
- **misc**: Update i18n ([2e6fd07](https://github.com/lobehub/lobe-chat/commit/2e6fd07))
- **misc**: Update i18n microcopy, closes [#10905](https://github.com/lobehub/lobe-chat/issues/10905) ([024aeb2](https://github.com/lobehub/lobe-chat/commit/024aeb2))
- **misc**: Update ui ([1693fc5](https://github.com/lobehub/lobe-chat/commit/1693fc5))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.180](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.179...v2.0.0-next.180)
<sup>Released on **2025-12-26**</sup>
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.179](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.178...v2.0.0-next.179)
<sup>Released on **2025-12-25**</sup>
#### 🐛 Bug Fixes
- **scripts**: Fix syntax error in prebuild.mts.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **scripts**: Fix syntax error in prebuild.mts, closes [#10952](https://github.com/lobehub/lobe-chat/issues/10952) ([3d46c13](https://github.com/lobehub/lobe-chat/commit/3d46c13))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.178](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.177...v2.0.0-next.178)
<sup>Released on **2025-12-24**</sup>
#### 🐛 Bug Fixes
- **ci**: Always continue build to upload bundle analyzer report, skip backend routes in bundle analyzer build.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **ci**: Always continue build to upload bundle analyzer report, closes [#10946](https://github.com/lobehub/lobe-chat/issues/10946) ([8d37811](https://github.com/lobehub/lobe-chat/commit/8d37811))
- **ci**: Skip backend routes in bundle analyzer build, closes [#10944](https://github.com/lobehub/lobe-chat/issues/10944) ([0276b87](https://github.com/lobehub/lobe-chat/commit/0276b87))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.177](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.176...v2.0.0-next.177)
<sup>Released on **2025-12-24**</sup>
#### ✨ Features
- **ci**: Add bundle analyzer workflow.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's improved
- **ci**: Add bundle analyzer workflow, closes [#10932](https://github.com/lobehub/lobe-chat/issues/10932) ([c470cfb](https://github.com/lobehub/lobe-chat/commit/c470cfb))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.176](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.175...v2.0.0-next.176)
<sup>Released on **2025-12-23**</sup>
+1 -2
View File
@@ -1,6 +1,6 @@
# CLAUDE.md
This document serves as a shared guideline for all team members when using Claude Code in this repository.
This document serves as a shared guideline for all team members when using Claude Code in this opensource lobe-chat(also known as lobehub) repository.
## Tech Stack
@@ -14,7 +14,6 @@ read @.cursor/rules/project-structure.mdc
### Git Workflow
- The current release branch is `next` instead of `main` until v2.0.0 is officially released
- use rebase for git pull
- git commit message should prefix with gitmoji
- git branch name format template: <type>/<feature-name>
+2 -1
View File
@@ -74,13 +74,14 @@ ENV NEXT_PUBLIC_ANALYTICS_UMAMI="${NEXT_PUBLIC_ANALYTICS_UMAMI}" \
NEXT_PUBLIC_UMAMI_WEBSITE_ID="${NEXT_PUBLIC_UMAMI_WEBSITE_ID}"
# Node
ENV NODE_OPTIONS="--max-old-space-size=6144"
ENV NODE_OPTIONS="--max-old-space-size=8192"
WORKDIR /app
COPY package.json pnpm-workspace.yaml ./
COPY .npmrc ./
COPY packages ./packages
COPY patches ./patches
# bring in desktop workspace manifest so pnpm can resolve it
COPY apps/desktop/src/main/package.json ./apps/desktop/src/main/package.json
+4
View File
@@ -165,12 +165,16 @@ const config = {
CFBundleURLSchemes: [protocolScheme],
},
],
NSAppleEventsUsageDescription:
'Application needs to control System Settings to help you grant Full Disk Access automatically.',
NSCameraUsageDescription: "Application requests access to the device's camera.",
NSDocumentsFolderUsageDescription:
"Application requests access to the user's Documents folder.",
NSDownloadsFolderUsageDescription:
"Application requests access to the user's Downloads folder.",
NSMicrophoneUsageDescription: "Application requests access to the device's microphone.",
NSScreenCaptureUsageDescription:
'Application requests access to record and analyze screen content for AI assistance.',
},
gatekeeperAssess: false,
hardenedRuntime: hasAppleCertificate,
@@ -96,6 +96,8 @@ export default class RemoteServerConfigCtr extends ControllerModule {
const merged = this.normalizeConfig({ ...prev, ...config });
storeManager.set('dataSyncConfig', merged);
this.broadcastRemoteServerConfigUpdated();
return true;
}
@@ -113,9 +115,16 @@ export default class RemoteServerConfigCtr extends ControllerModule {
// Clear tokens (if any)
await this.clearTokens();
this.broadcastRemoteServerConfigUpdated();
return true;
}
private broadcastRemoteServerConfigUpdated() {
logger.debug('Broadcasting remoteServerConfigUpdated event to all windows');
this.app.browserManager.broadcastToAllWindows('remoteServerConfigUpdated', undefined);
}
/**
* Encrypted tokens
* Stored in memory for quick access, loaded from persistent storage on init.
+129 -6
View File
@@ -1,11 +1,14 @@
import { ElectronAppState, ThemeMode } from '@lobechat/electron-client-ipc';
import { app, nativeTheme, shell, systemPreferences } from 'electron';
import { app, dialog, nativeTheme, shell, systemPreferences } from 'electron';
import { macOS } from 'electron-is';
import { spawn } from 'node:child_process';
import path from 'node:path';
import process from 'node:process';
import { createLogger } from '@/utils/logger';
import { ControllerModule, IpcMethod } from './index';
import fullDiskAccessAutoAddScript from './scripts/full-disk-access.applescript?raw';
const logger = createLogger('controllers:SystemCtr');
@@ -76,17 +79,114 @@ export default class SystemController extends ControllerModule {
}
@IpcMethod()
async requestScreenAccess(): Promise<void> {
if (!macOS()) return;
shell.openExternal(
async requestScreenAccess(): Promise<boolean> {
if (!macOS()) return true;
// IMPORTANT:
// On macOS, the app may NOT appear in "Screen Recording" list until it actually
// requests the permission once (TCC needs to register this app).
// So we try to proactively request it first, then open System Settings for manual toggle.
// 1) Best-effort: try Electron runtime API if available (not typed in Electron 38).
try {
const status = systemPreferences.getMediaAccessStatus('screen');
if (status !== 'granted') {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
await (systemPreferences as any).askForMediaAccess?.('screen');
}
} catch (error) {
logger.warn('Failed to request screen recording access via systemPreferences', error);
}
// 2) Reliable trigger: run a one-shot getDisplayMedia in renderer to register TCC entry.
// This will show the OS capture picker; once the user selects/cancels, we stop tracks immediately.
try {
const status = systemPreferences.getMediaAccessStatus('screen');
if (status !== 'granted') {
const mainWindow = this.app.browserManager.getMainWindow()?.browserWindow;
if (mainWindow && !mainWindow.isDestroyed()) {
const script = `
(() => {
const stop = (stream) => {
try { stream.getTracks().forEach((t) => t.stop()); } catch {}
};
return navigator.mediaDevices.getDisplayMedia({ video: true, audio: false })
.then((stream) => { stop(stream); return true; })
.catch(() => false);
})()
`.trim();
await mainWindow.webContents.executeJavaScript(script, true);
}
}
} catch (error) {
logger.warn('Failed to request screen recording access via getDisplayMedia', error);
}
await shell.openExternal(
'x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture',
);
return systemPreferences.getMediaAccessStatus('screen') === 'granted';
}
@IpcMethod()
openFullDiskAccessSettings() {
openFullDiskAccessSettings(payload?: { autoAdd?: boolean }) {
if (!macOS()) return;
shell.openExternal('x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles');
const { autoAdd = false } = payload || {};
// NOTE:
// - Full Disk Access cannot be requested programmatically like microphone/screen.
// - On macOS 13+ (Ventura), System Preferences is replaced by System Settings,
// and deep links may differ. We try multiple known schemes for compatibility.
const candidates = [
// macOS 13+ (System Settings)
'com.apple.settings:Privacy&path=FullDiskAccess',
// Older macOS (System Preferences)
'x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles',
];
if (autoAdd) this.tryAutoAddFullDiskAccess();
(async () => {
for (const url of candidates) {
try {
await shell.openExternal(url);
return;
} catch (error) {
logger.warn(`Failed to open Full Disk Access settings via ${url}`, error);
}
}
})();
}
/**
* Best-effort UI automation to add this app into Full Disk Access list.
*
* Limitations:
* - This uses AppleScript UI scripting (System Events) and may require the user to grant
* additional "Automation" permission (to control System Settings).
* - UI structure differs across macOS versions/languages; we fall back silently.
*/
private tryAutoAddFullDiskAccess() {
if (!macOS()) return;
const exePath = app.getPath('exe');
// /Applications/App.app/Contents/MacOS/App -> /Applications/App.app
const appBundlePath = path.resolve(path.dirname(exePath), '..', '..');
// Keep the script minimal and resilient; failure should not break onboarding flow.
const script = fullDiskAccessAutoAddScript.trim();
try {
const child = spawn('osascript', ['-e', script, appBundlePath], { env: process.env });
child.on('error', (error) => {
logger.warn('Full Disk Access auto-add (osascript) failed to start', error);
});
child.on('exit', (code) => {
logger.debug('Full Disk Access auto-add (osascript) exited', { code });
});
} catch (error) {
logger.warn('Full Disk Access auto-add failed', error);
}
}
@IpcMethod()
@@ -94,6 +194,29 @@ export default class SystemController extends ControllerModule {
return shell.openExternal(url);
}
/**
* Open native folder picker dialog
*/
@IpcMethod()
async selectFolder(payload?: {
defaultPath?: string;
title?: string;
}): Promise<string | undefined> {
const mainWindow = this.app.browserManager.getMainWindow()?.browserWindow;
const result = await dialog.showOpenDialog(mainWindow!, {
defaultPath: payload?.defaultPath,
properties: ['openDirectory', 'createDirectory'],
title: payload?.title || 'Select Folder',
});
if (result.canceled || result.filePaths.length === 0) {
return undefined;
}
return result.filePaths[0];
}
/**
* 更新应用语言设置
*/
@@ -43,7 +43,12 @@ const mockStoreManager = {
set: vi.fn(),
};
const mockBrowserManager = {
broadcastToAllWindows: vi.fn(),
};
const mockApp = {
browserManager: mockBrowserManager,
storeManager: mockStoreManager,
} as unknown as App;
@@ -44,6 +44,22 @@ vi.mock('@/utils/logger', () => ({
}),
}));
const { spawnMock } = vi.hoisted(() => ({
spawnMock: vi.fn(() => {
const handlers = new Map<string, (...args: any[]) => void>();
return {
on: vi.fn((event: string, cb: (...args: any[]) => void) => {
handlers.set(event, cb);
return undefined;
}),
} as any;
}),
}));
vi.mock('node:child_process', () => ({
spawn: (...args: any[]) => spawnMock.call(null, ...args),
}));
// Mock electron
vi.mock('electron', () => ({
app: {
@@ -61,6 +77,8 @@ vi.mock('electron', () => ({
openExternal: vi.fn().mockResolvedValue(undefined),
},
systemPreferences: {
askForMediaAccess: vi.fn(async () => true),
getMediaAccessStatus: vi.fn(() => 'not-determined'),
isTrustedAccessibilityClient: vi.fn(() => true),
},
}));
@@ -73,6 +91,14 @@ vi.mock('electron-is', () => ({
// Mock browserManager
const mockBrowserManager = {
broadcastToAllWindows: vi.fn(),
getMainWindow: vi.fn(() => ({
browserWindow: {
isDestroyed: vi.fn(() => false),
webContents: {
executeJavaScript: vi.fn(async () => true),
},
},
})),
handleAppThemeChange: vi.fn(),
};
@@ -163,6 +189,68 @@ describe('SystemController', () => {
});
});
describe('screen recording', () => {
it('should request screen recording access and open System Settings on macOS', async () => {
const { shell, systemPreferences } = await import('electron');
const result = await invokeIpc('system.requestScreenAccess');
expect(systemPreferences.getMediaAccessStatus).toHaveBeenCalledWith('screen');
expect(systemPreferences.askForMediaAccess).toHaveBeenCalledWith('screen');
expect(mockBrowserManager.getMainWindow).toHaveBeenCalled();
expect(shell.openExternal).toHaveBeenCalledWith(
'x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture',
);
expect(typeof result).toBe('boolean');
});
it('should return true on non-macOS and not open settings', async () => {
const { macOS } = await import('electron-is');
const { shell, systemPreferences } = await import('electron');
vi.mocked(macOS).mockReturnValue(false);
const result = await invokeIpc('system.requestScreenAccess');
expect(result).toBe(true);
expect(systemPreferences.askForMediaAccess).not.toHaveBeenCalled();
expect(shell.openExternal).not.toHaveBeenCalled();
// Reset
vi.mocked(macOS).mockReturnValue(true);
});
});
describe('full disk access', () => {
it('should try to open Full Disk Access settings with fallbacks', async () => {
const { shell } = await import('electron');
vi.mocked(shell.openExternal)
.mockRejectedValueOnce(new Error('fail first'))
.mockResolvedValueOnce(undefined);
await invokeIpc('system.openFullDiskAccessSettings');
expect(shell.openExternal).toHaveBeenCalledWith(
'com.apple.settings:Privacy&path=FullDiskAccess',
);
expect(shell.openExternal).toHaveBeenCalledWith(
'x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles',
);
});
it('should spawn osascript when autoAdd is enabled', async () => {
const { shell } = await import('electron');
vi.mocked(shell.openExternal).mockResolvedValueOnce(undefined);
await invokeIpc('system.openFullDiskAccessSettings', { autoAdd: true });
expect(spawnMock).toHaveBeenCalledWith(
'osascript',
expect.arrayContaining(['-e', expect.any(String), expect.any(String)]),
expect.objectContaining({ env: expect.any(Object) }),
);
});
});
describe('openExternalLink', () => {
it('should open external link', async () => {
const { shell } = await import('electron');
@@ -0,0 +1,85 @@
on run argv
set appBundlePath to item 1 of argv
set settingsBundleIds to {"com.apple.SystemSettings", "com.apple.systempreferences"}
-- Bring System Settings/Preferences to front (Ventura+ / older). If it doesn't exist, ignore.
repeat with bundleId in settingsBundleIds
try
tell application id bundleId to activate
exit repeat
end try
end repeat
tell application "System Events"
set settingsProcess to missing value
repeat 30 times
repeat with bundleId in settingsBundleIds
try
if exists (first process whose bundle identifier is bundleId) then
set settingsProcess to first process whose bundle identifier is bundleId
exit repeat
end if
end try
end repeat
if settingsProcess is not missing value then exit repeat
delay 0.2
end repeat
if settingsProcess is missing value then return "no-settings-process"
tell settingsProcess
set frontmost to true
repeat 30 times
if exists window 1 then exit repeat
delay 0.2
end repeat
if not (exists window 1) then return "no-window"
-- Best-effort: find an "add" button in the front window and click it.
set clickedAdd to false
repeat 30 times
try
repeat with b in (buttons of window 1)
set bDesc to ""
set bName to ""
set bTitle to ""
try set bDesc to description of b end try
try set bName to name of b end try
try set bTitle to title of b end try
if (bDesc is "Add") or (bTitle is "Add") or (bName is "+") or (bTitle is "+") then
click b
set clickedAdd to true
exit repeat
end if
end repeat
end try
if clickedAdd is true then exit repeat
delay 0.2
end repeat
if clickedAdd is false then return "no-add-button"
-- Wait for open panel / sheet
repeat 30 times
if exists sheet 1 of window 1 then exit repeat
delay 0.2
end repeat
if not (exists sheet 1 of window 1) then return "no-sheet"
-- Open "Go to the folder" and input the app bundle path, then confirm.
keystroke "G" using {command down, shift down}
delay 0.3
keystroke appBundlePath
key code 36
delay 0.6
-- Confirm "Open" in the panel (Enter usually triggers default)
key code 36
return "ok"
end tell
end tell
end run
@@ -1,5 +1,6 @@
import type { Session } from 'electron';
import { BrowserWindow, type Session } from 'electron';
import { isDev } from '@/const/env';
import { createLogger } from '@/utils/logger';
interface BackendProxyProtocolManagerOptions {
@@ -30,6 +31,15 @@ export class BackendProxyProtocolManager {
private readonly handledSessions = new WeakSet<Session>();
private readonly logger = createLogger('core:BackendProxyProtocolManager');
private notifyAuthorizationRequired() {
const allWindows = BrowserWindow.getAllWindows();
for (const win of allWindows) {
if (!win.isDestroyed()) {
win.webContents.send('authorizationRequired');
}
}
}
registerWithRemoteBaseUrl(
session: Session,
options: BackendProxyProtocolManagerRemoteBaseOptions,
@@ -85,7 +95,9 @@ export class BackendProxyProtocolManager {
const headers = new Headers(request.headers);
const token = await options.getAccessToken();
if (token) headers.set('Oidc-Auth', token);
if (token) {
headers.set('Oidc-Auth', token);
}
// eslint-disable-next-line no-undef
const requestInit: RequestInit & { duplex?: 'half' } = {
@@ -126,10 +138,18 @@ export class BackendProxyProtocolManager {
responseHeaders.set('Access-Control-Allow-Credentials', 'true');
}
if (isDev) {
responseHeaders.set('x-dev-oidc-auth', token);
}
responseHeaders.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
responseHeaders.set('Access-Control-Allow-Headers', '*');
responseHeaders.set('X-Src-Url', rewrittenUrl);
if (!token && upstreamResponse.status === 401) {
this.notifyAuthorizationRequired();
}
return new Response(upstreamResponse.body, {
headers: responseHeaders,
status: upstreamResponse.status,
@@ -175,6 +175,7 @@ export class I18nManager {
try {
logger.debug(`Loading namespace: ${lng}/${ns}`);
const resources = await loadResources(lng, ns);
this.i18n.addResourceBundle(lng, ns, resources, true, true);
return true;
} catch (error) {
@@ -1,7 +1,7 @@
import log from 'electron-log';
import { autoUpdater } from 'electron-updater';
import { isDev } from '@/const/env';
import { isDev, isWindows } from '@/const/env';
import { UPDATE_CHANNEL as channel, updaterConfig } from '@/modules/updater/configs';
import { createLogger } from '@/utils/logger';
@@ -144,12 +144,16 @@ export class UpdaterManager {
// Close all windows first to ensure clean exit
logger.info('Closing all windows before update installation...');
const { BrowserWindow, app } = require('electron');
const allWindows = BrowserWindow.getAllWindows();
allWindows.forEach((window) => {
if (!window.isDestroyed()) {
window.close();
}
});
// do not close windows and quit first
// on Windows, window-all-closed -> app.quit()` can terminate the process before the timer fires
if (!isWindows) {
const allWindows = BrowserWindow.getAllWindows();
allWindows.forEach((window) => {
if (!window.isDestroyed()) {
window.close();
}
});
}
// Release single instance lock before quitting
// This ensures the new instance can acquire the lock
@@ -21,6 +21,13 @@ const { mockProtocol, protocolHandlerRef } = vi.hoisted(() => {
};
});
vi.mock('electron-is', () => ({
dev: vi.fn(() => false),
macOS: vi.fn(() => false),
windows: vi.fn(() => false),
linux: vi.fn(() => true),
}));
vi.mock('@/utils/logger', () => ({
createLogger: () => ({
debug: vi.fn(),
+1 -1
View File
@@ -76,7 +76,7 @@ export const getDesktopEnv = memoize(() =>
MCP_TOOL_TIMEOUT: envNumber(60_000),
// cloud server url (can be overridden for selfhost/dev)
OFFICIAL_CLOUD_SERVER: z.string().optional().default('https://lobechat.com'),
OFFICIAL_CLOUD_SERVER: z.string().optional().default('https://app.lobehub.com'),
},
clientPrefix: 'PUBLIC_',
client: {},
+3 -1
View File
@@ -22,7 +22,9 @@ export const loadResources = async (lng: string, ns: string) => {
}
try {
return await import(`@/../../resources/locales/${lng}/${ns}.json`);
const { default: content } = await import(`@/../../resources/locales/${lng}/${ns}.json`);
return content;
} catch (error) {
console.error(`无法加载翻译文件: ${lng} - ${ns}`, error);
return {};
+179
View File
@@ -1,4 +1,183 @@
[
{
"children": {
"improvements": ["Refactor and fix model runtime initialize."]
},
"date": "2026-01-03",
"version": "2.0.0-next.202"
},
{
"children": {
"fixes": ["Restore window resizable before hard reload in desktop onboarding."]
},
"date": "2026-01-03",
"version": "2.0.0-next.201"
},
{
"children": {
"features": ["Add work path for local system."]
},
"date": "2026-01-03",
"version": "2.0.0-next.200"
},
{
"children": {
"fixes": ["Filter empty assistant messages for Anthropic API."]
},
"date": "2026-01-03",
"version": "2.0.0-next.199"
},
{
"children": {
"fixes": ["Support thoughtSignature for openrouter."]
},
"date": "2026-01-03",
"version": "2.0.0-next.198"
},
{
"children": {
"improvements": ["Remove client db and refactor test."],
"fixes": ["Fix file upload issue."]
},
"date": "2026-01-03",
"version": "2.0.0-next.197"
},
{
"children": {
"improvements": ["Refactor to remove access code."]
},
"date": "2026-01-03",
"version": "2.0.0-next.196"
},
{
"children": {
"fixes": ["Fix tool call message content missing."]
},
"date": "2026-01-03",
"version": "2.0.0-next.195"
},
{
"children": {
"improvements": ["Update i18n."]
},
"date": "2026-01-03",
"version": "2.0.0-next.194"
},
{
"children": {},
"date": "2026-01-02",
"version": "2.0.0-next.193"
},
{
"children": {
"fixes": ["Fix model edit icon missing."]
},
"date": "2026-01-02",
"version": "2.0.0-next.192"
},
{
"children": {
"improvements": ["Refactor to remove meta in message."]
},
"date": "2026-01-02",
"version": "2.0.0-next.191"
},
{
"children": {
"improvements": ["Update i18n."]
},
"date": "2026-01-02",
"version": "2.0.0-next.190"
},
{
"children": {
"improvements": ["Migrate to new DropdownMenuV2 and showContextMenu API."]
},
"date": "2026-01-01",
"version": "2.0.0-next.189"
},
{
"children": {
"improvements": ["Improve tools UI and fix Google schema compatibility."]
},
"date": "2026-01-01",
"version": "2.0.0-next.188"
},
{
"children": {
"improvements": ["Add Gemini 3 Flash & Doubao Seed 1.8 models."]
},
"date": "2026-01-01",
"version": "2.0.0-next.187"
},
{
"children": {
"improvements": ["Refactor oidc env to auth env."]
},
"date": "2026-01-01",
"version": "2.0.0-next.186"
},
{
"children": {
"improvements": ["Update i18n."]
},
"date": "2026-01-01",
"version": "2.0.0-next.185"
},
{
"children": {
"improvements": ["Improve loading and local-system render."]
},
"date": "2026-01-01",
"version": "2.0.0-next.184"
},
{
"children": {},
"date": "2025-12-31",
"version": "2.0.0-next.183"
},
{
"children": {
"features": ["Brand new 2.0 ui for next."]
},
"date": "2025-12-31",
"version": "2.0.0-next.182"
},
{
"children": {
"improvements": [
"Improve ExecTask and task message UI, improve gtd tool inspector and todo list, improve page document tool inspector UI, improve RunCommand Inspector, rebranding chat ui, refactor UI in features, rerun i18n, setting style, support streaming and display ui for group mode, support tool streaming and title custom render, update i18n, Update i18n microcopy, update ui."
],
"features": [
"Add a white waitlist in edge config env, add always show tools render in createPlan & createDoc tools, add batch tasks ui, add Bundle Analyzer workflow for detailed bundle size analysis, add business features support with new components and hooks, add business settings features with dynamic loading for Plans, Funds, Usage, Billing, and Referral tabs, add db and schema feature, add home page create group builder button, Add i18n UI locales and improve tool types, add like action in community detail, add memory implement, add subscription settings group with dynamic loading for Plans, Funds, Usage, Billing, and Referral tabs, add the market auth auto generate way, Add turbopack configuration support to CustomNextConfig, add user memory, agent builder, agent builder, agent builder and group builder, app ui page, brand new 2.0 ui for next, buildin some tools should save into docs, code-interpreter tool, code-interpreter tool, code-interpreter tool, desktop feature, enhance desktop onboarding with sign out and localization, enhance macOS desktop permissions and onboarding, enhance onboarding process by removing mode selection step and adding export functionality in advanced settings, file search feature, gtd create plan support streaming render, implement agent builder, implement builtin agents packages, implement memories package, implement Redis caching for presigned URLs in file proxy service, implement server data feature, include Subscription settings group in the Accordion component, Integrate bcryptjs for password verification in BetterAuth, integrate BrandingProviderCard and update Provider components for branding support, onboarding ui, page and knowledge base, rebranding total UI of app, refactor authentication handler to support dynamic loading of better-auth and next-auth, refactor desktop implement with brand new 2.0, rename codeinterpreter into lobe sandbox, server implement, support CMD K, support exec async sub agent task, support export and import topic JSON, support files upload in chat input, support notebook tool, support swr local cache, topic message swr cache, translate AI model descriptions to English, update agent builder ui, update create group chat use builder, update gtd tools( use editor & update metadata ), update user memory embedding model selection based on business features, user memory, user memory, user onboarding, when use usesend to create agent/group, the model should override by lobeAi, wrap ConversationArea and ModelSwitchPanel in TooltipGroup for enhanced UI."
],
"fixes": [
"Agent profiles update, agent tools config set, editor placeholder, bump charts 3.0.4 to fix import es path, fix anthropic thinking budget, fix async task and improve tool style, fix default waitlist bug, fix delete agent group bug, Fix desktop test cases and refactor translations, Fix desktop test cases and refactor translations, fix gemini 3 model thinking issue, fix gemini 3 pro parallel tool use, fix gemini 3 thinking params, fix identity memory not working, fix supervisor flag, fix thread not working issue, fix when use branch topic,the branch index error problem, fixed the welcome card the create button not work, handle session invalidation on 401 error by logging out signed-in users, improve test infrastructure and mock configurations, locale resolve bug with ESM module loading, page agent editor, prevent redundant login redirect when already on auth pages, redis read json object, remove openapi pkg patch file, slove input editor on pause emit, slove swr mutate not work in Cache Provider, slove the group add member checkbox not work, slove the model select null problem, slove the mutate not work problem, slove when click agentbuilder should clean topic, slove when first call thread, not show ai chat message, support retry error message and fix continueGenerationMessage, update contextMenu in group tools message, update OFFICIAL_URL to app.lobehub.com, update PlanTag link paths for subscription settings, update test snapshots for model description changes, when use agentbuilder the topic id should use new & clear topic…."
]
},
"date": "2025-12-31",
"version": "2.0.0-next.181"
},
{
"children": {},
"date": "2025-12-26",
"version": "2.0.0-next.180"
},
{
"children": {},
"date": "2025-12-25",
"version": "2.0.0-next.179"
},
{
"children": {},
"date": "2025-12-24",
"version": "2.0.0-next.178"
},
{
"children": {},
"date": "2025-12-24",
"version": "2.0.0-next.177"
},
{
"children": {
"features": ["Mobile native better auth support."]
+5 -3
View File
@@ -44,12 +44,14 @@ Before connecting the desktop to your self-hosted instance, ensure that your sel
#### OIDC Environment Variable Configuration
You need to add the following two environment variables, `ENABLE_OIDC` and `OIDC_JWKS_KEY`, to your self-hosted instance. You can click the button below to generate them with one click:
You need to add the following two environment variables, `ENABLE_OIDC` and `JWKS_KEY`, to your self-hosted instance. You can click the button below to generate them with one click:
<OIDCJWKs />
Add the generated JWK key to your environment variables.
<Callout>If you have already configured `OIDC_JWKS_KEY`, no changes are needed. The system will automatically fall back to `OIDC_JWKS_KEY` for backward compatibility.</Callout>
If you are deploying LobeChat using one-click deployment methods (such as Vercel, Railway, etc.), you need to:
1. Add the above environment variables to the environment variable configuration of your deployment platform.
@@ -71,8 +73,8 @@ If you are deploying LobeChat using one-click deployment methods (such as Vercel
**Solution:**
- Confirm that you have correctly set the `ENABLE_OIDC=1` and `OIDC_JWKS_KEY` environment variables.
- Ensure that `OIDC_JWKS_KEY` is in valid JSON format without extra single quotes.
- Confirm that you have correctly set the `ENABLE_OIDC=1` and `JWKS_KEY` environment variables.
- Ensure that `JWKS_KEY` is in valid JSON format without extra single quotes.
- Check your server logs for specific error messages.
If you are using Nginx as a reverse proxy, the issue may be due to oversized request headers. You can try adding the following settings to your Nginx configuration:
+5 -3
View File
@@ -42,12 +42,14 @@ LobeChat 桌面端可以与您自托管的 LobeChat 实例连接,以便您可
#### OIDC 环境变量配置
您需要在自托管实例中添加以下`ENABLE_OIDC` 和 `OIDC_JWKS_KEY` 这两个环境变量,你可以点击下方按钮一键生成:
您需要在自托管实例中添加以下`ENABLE_OIDC` 和 `JWKS_KEY` 这两个环境变量,你可以点击下方按钮一键生成:
<OIDCJWKs />
将生成的 JWK 密钥添加到您的环境变量中。
<Callout>如果您之前已配置 `OIDC_JWKS_KEY`,无需修改。系统会自动回退使用 `OIDC_JWKS_KEY`(向后兼容)。</Callout>
如果您使用一键部署方式(如 Vercel、Railway 等平台)部署 LobeChat,您需要:
1. 将上述环境变量添加到部署平台的环境变量配置中
@@ -69,8 +71,8 @@ LobeChat 桌面端可以与您自托管的 LobeChat 实例连接,以便您可
**解决方案:**
- 确认您已经正确设置了 `ENABLE_OIDC=1` 和 `OIDC_JWKS_KEY` 环境变量
- 确保 `OIDC_JWKS_KEY` 是有效的 JSON 格式,没有额外的单引号
- 确认您已经正确设置了 `ENABLE_OIDC=1` 和 `JWKS_KEY` 环境变量
- 确保 `JWKS_KEY` 是有效的 JSON 格式,没有额外的单引号
- 检查您的服务端日志,查看具体错误信息
如果您使用 Nginx 作为反向代理,可能是请求头太大导致的问题。可以尝试在 Nginx 配置中添加以下设置:
@@ -55,6 +55,14 @@ LobeChat provides a complete authentication service capability when deployed. Th
- Default: `-`
- Example: `google,github,microsoft,cognito`
#### `JWKS_KEY`
- Type: Required
- Description: Generic JWKS (JSON Web Key Set) key for signing and verifying JWTs. Used for internal service authentication and other cryptographic operations. Must be a JWKS JSON string containing an RS256 RSA key pair. Falls back to `OIDC_JWKS_KEY` if not set (for backward compatibility).
- Default: `-`
<OIDCJWKs />
### Email Service (SMTP)
These settings are required for email verification and password reset features.
@@ -53,6 +53,14 @@ LobeChat 在部署时提供了完善的身份验证服务能力,以下是相
- 默认值:`-`
- 示例:`google,github,microsoft,cognito`
#### `JWKS_KEY`
- 类型:必选
- 描述:用于签名和验证 JWT 的通用 JWKSJSON Web Key Set)密钥。用于内部服务认证和其他加密操作。必须是包含 RS256 RSA 密钥对的 JWKS JSON 字符串。如果未设置,将回退到 `OIDC_JWKS_KEY`(向后兼容)。
- 默认值:`-`
<OIDCJWKs />
### 邮件服务(SMTP
启用邮箱验证和密码重置功能需要配置以下设置。
+1 -9
View File
@@ -7,15 +7,7 @@ import type { Config } from 'drizzle-kit';
dotenv.config();
let connectionString = process.env.DATABASE_URL;
if (process.env.NODE_ENV === 'test') {
console.log('current ENV:', process.env.NODE_ENV);
connectionString = process.env.DATABASE_TEST_URL;
}
if (!connectionString)
throw new Error('`DATABASE_URL` or `DATABASE_TEST_URL` not found in environment');
let connectionString = process.env.DATABASE_URL!;
export default {
dbCredentials: {
+2
View File
@@ -0,0 +1,2 @@
reports
screenshots
+428
View File
@@ -0,0 +1,428 @@
# E2E Testing Guide for Claude
本文档记录了在 LobeHub E2E 测试开发中的经验和最佳实践。
Related: [LOBE-2417](https://linear.app/lobehub/issue/LOBE-2417/建立核心产品功能-e2e-测试体验基准线)
## 测试策略:体验驱动的 E2E 测试
### 核心理念
建立完整的**用户体验链路 E2E 测试**,作为未来变更和重构的**体验基准线**。
**目的**
- 确保核心用户体验在代码变更后不会退化
- 为重构提供安全网,敢于大胆改进代码
- 从用户视角验证功能完整性
### 产品架构覆盖
| 模块 | 子功能 | 优先级 | 状态 |
| ---------------- | -------------------- | ------ | ---- |
| **Agent** | Builder, 对话,Task | P0 | 🚧 |
| **Agent Group** | Builder, 群聊 | P1 | ⏳ |
| **Page(文稿)** | 创建,编辑,分享 | P1 | ⏳ |
| **知识库** | 创建,上传,RAG 对话 | P1 | ⏳ |
| **记忆** | 查看,编辑,关联 | P2 | ⏳ |
### 标签系统
```gherkin
@journey # 用户旅程测试(体验基准线)
@smoke # 冒烟测试(快速验证)
@regression # 回归测试
@P0 # 最高优先级(CI 必跑)
@P1 # 高优先级(Nightly
@P2 # 中优先级(发版前)
@agent # Agent 模块
@agent-group # Agent Group 模块
@page # Page 文稿模块
@knowledge # 知识库模块
@memory # 记忆模块
```
### 执行策略
```bash
# CI - P0 冒烟测试(每次 PR)
pnpm exec cucumber-js --config cucumber.config.js --tags "@smoke and @P0"
# Nightly - 所有用户旅程
pnpm exec cucumber-js --config cucumber.config.js --tags "@journey"
# 发版前 - 完整回归
pnpm exec cucumber-js --config cucumber.config.js --tags "@P0 or @P1"
# 完整测试
pnpm exec cucumber-js --config cucumber.config.js
```
### 测试设计原则
1. **按 CRUD + 核心交互覆盖**:每个模块覆盖创建、读取、更新、删除及核心交互流程
2. **LLM 响应必须 Mock**:保证测试稳定性和可重复性
3. **中文描述场景**:Feature 文件使用中文,贴近产品需求
4. **优先级分层**:合理分配 P0/P1/P2,控制 CI 执行时间
## 目录结构
```
e2e/
├── src/
│ ├── features/ # Cucumber feature 文件
│ │ ├── journeys/ # 用户旅程(体验基准线)
│ │ │ ├── agent/
│ │ │ │ ├── agent-builder.feature
│ │ │ │ ├── agent-conversation.feature ✅
│ │ │ │ └── agent-task.feature
│ │ │ ├── agent-group/
│ │ │ │ ├── group-builder.feature
│ │ │ │ └── group-chat.feature
│ │ │ ├── page/
│ │ │ │ └── page-crud.feature
│ │ │ ├── knowledge/
│ │ │ │ └── knowledge-rag.feature
│ │ │ └── memory/
│ │ │ └── memory-crud.feature
│ │ ├── smoke/ # 冒烟测试
│ │ │ └── discover/
│ │ └── regression/ # 回归测试
│ ├── steps/ # Step definitions
│ │ ├── agent/ # Agent 相关 steps
│ │ ├── common/ # 通用 steps (auth, navigation)
│ │ └── hooks.ts # Before/After hooks
│ ├── mocks/ # Mock 框架
│ │ └── llm/ # LLM Mock (拦截 AI 请求) ✅
│ └── support/ # 测试支持文件
│ └── world.ts # CustomWorld 定义
├── screenshots/ # 失败截图
├── reports/ # 测试报告
├── cucumber.config.js # Cucumber 配置
└── CLAUDE.md # 本文档
```
## 本地环境启动
> 详细流程参考 [e2e/docs/local-setup.md](./docs/local-setup.md)
### 快速启动流程
```bash
# Step 1: 清理环境
docker stop postgres-e2e 2> /dev/null; docker rm postgres-e2e 2> /dev/null
lsof -ti:3006 | xargs kill -9 2> /dev/null
lsof -ti:5433 | xargs kill -9 2> /dev/null
# Step 2: 启动数据库(使用 paradedb 镜像,支持 pgvector
docker run -d --name postgres-e2e \
-e POSTGRES_PASSWORD=postgres \
-p 5433:5432 \
paradedb/paradedb:latest
# 等待数据库就绪
until docker exec postgres-e2e pg_isready; do sleep 2; done
# Step 3: 运行数据库迁移(项目根目录)
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
DATABASE_DRIVER=node \
KEY_VAULTS_SECRET=LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s= \
bun run db:migrate
# Step 4: 构建应用(首次或代码变更后)
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
DATABASE_DRIVER=node \
KEY_VAULTS_SECRET=LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s= \
BETTER_AUTH_SECRET=e2e-test-secret-key-for-better-auth-32chars! \
NEXT_PUBLIC_ENABLE_BETTER_AUTH=1 \
SKIP_LINT=1 \
bun run build
# Step 5: 启动服务器(必须在项目根目录运行!)
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
DATABASE_DRIVER=node \
KEY_VAULTS_SECRET=LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s= \
BETTER_AUTH_SECRET=e2e-test-secret-key-for-better-auth-32chars! \
NEXT_PUBLIC_ENABLE_BETTER_AUTH=1 \
NEXT_PUBLIC_AUTH_EMAIL_VERIFICATION=0 \
S3_ACCESS_KEY_ID=e2e-mock-access-key \
S3_SECRET_ACCESS_KEY=e2e-mock-secret-key \
S3_BUCKET=e2e-mock-bucket \
S3_ENDPOINT=https://e2e-mock-s3.localhost \
bunx next start -p 3006
```
**重要提示**:
- 必须使用 `paradedb/paradedb:latest` 镜像(支持 pgvector 扩展)
- 服务器必须在**项目根目录**启动,不能在 e2e 目录
- S3 环境变量是**必需**的,即使不测试文件上传
## 运行测试
```bash
# 从 e2e 目录运行
cd e2e
# 运行特定标签的测试
BASE_URL=http://localhost:3006 \
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
pnpm exec cucumber-js --config cucumber.config.js --tags "@AGENT-CHAT-001"
# 调试模式(显示浏览器)
HEADLESS=false BASE_URL=http://localhost:3006 \
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
pnpm exec cucumber-js --config cucumber.config.js --tags "@conversation"
# 运行所有测试
BASE_URL=http://localhost:3006 \
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
pnpm exec cucumber-js --config cucumber.config.js
```
**重要**: 必须显式指定 `--config cucumber.config.js`,否则配置不会被正确加载。
## LLM Mock 实现
### 核心原理
LLM Mock 通过 Playwright 的 `page.route()` 拦截对 `/webapi/chat/openai` 的请求,返回预设的 SSE 流式响应。
### SSE 响应格式
LobeHub 使用特定的 SSE 格式,必须严格匹配:
```typescript
// 1. 初始 data 事件
id: msg_xxx
event: data
data: {"id":"msg_xxx","model":"gpt-4o-mini","role":"assistant","type":"message",...}
// 2. 文本内容分块(text 事件)
id: msg_xxx
event: text
data: "Hello"
id: msg_xxx
event: text
data: "! I am"
// 3. 停止事件
id: msg_xxx
event: stop
data: "end_turn"
// 4. 使用量统计
id: msg_xxx
event: usage
data: {"totalTokens":100,...}
// 5. 最终停止
id: msg_xxx
event: stop
data: "message_stop"
```
### 使用示例
```typescript
import { llmMockManager, presetResponses } from '../../mocks/llm';
// 在测试步骤中设置 mock
llmMockManager.setResponse('hello', presetResponses.greeting);
await llmMockManager.setup(this.page);
```
### 添加自定义响应
```typescript
// 为特定用户消息设置响应
llmMockManager.setResponse('你好', '你好!我是 Lobe AI,有什么可以帮助你的?');
// 清除所有自定义响应
llmMockManager.clearResponses();
```
## 页面元素定位技巧
### 富文本编辑器 (contenteditable) 输入
LobeHub 使用 `@lobehub/editor` 作为聊天输入框,是一个 contenteditable 的富文本编辑器。
**关键点**:
1. 不能直接用 `locator.fill()` - 对 contenteditable 不生效
2. 需要先 click 容器让编辑器获得焦点
3. 使用 `keyboard.type()` 输入文本
```typescript
// 正确的输入方式
await chatInputContainer.click();
await this.page.waitForTimeout(500); // 等待焦点
await this.page.keyboard.type(message, { delay: 30 });
await this.page.keyboard.press('Enter'); // 发送
```
### 添加 data-testid
为了更可靠的元素定位,可以在组件上添加 `data-testid`
```tsx
// src/features/ChatInput/Desktop/index.tsx
<ChatInput
data-testid="chat-input"
...
/>
```
## 调试技巧
### 添加步骤日志
在每个关键步骤添加 console.log,帮助定位问题:
```typescript
Given('用户进入页面', async function (this: CustomWorld) {
console.log(' 📍 Step: 导航到首页...');
await this.page.goto('/');
console.log(' 📍 Step: 查找元素...');
const element = this.page.locator('...');
console.log(' ✅ 步骤完成');
});
```
### 查看失败截图
测试失败时会自动保存截图到 `e2e/screenshots/` 目录。
### 非 headless 模式
设置 `HEADLESS=false` 可以看到浏览器操作:
```bash
HEADLESS=false pnpm exec cucumber-js --config cucumber.config.js --tags "@smoke"
```
## 环境变量
运行测试需要以下环境变量:
```bash
BASE_URL=http://localhost:3010 # 测试服务器地址
DATABASE_URL=postgresql://... # 数据库连接
DATABASE_DRIVER=node # 数据库驱动
KEY_VAULTS_SECRET=... # 密钥
BETTER_AUTH_SECRET=... # Auth 密钥
NEXT_PUBLIC_ENABLE_BETTER_AUTH=1 # 启用 Better Auth
# 可选:S3 相关(如果测试涉及文件上传)
S3_ACCESS_KEY_ID=e2e-mock-access-key
S3_SECRET_ACCESS_KEY=e2e-mock-secret-key
S3_BUCKET=e2e-mock-bucket
S3_ENDPOINT=https://e2e-mock-s3.localhost
```
## 清理环境
测试完成后或需要重置环境时,执行以下清理操作:
### 停止服务器
```bash
# 查找并停止占用端口的进程
lsof -ti:3006 | xargs kill -9 2> /dev/null
lsof -ti:3010 | xargs kill -9 2> /dev/null
```
### 停止 Docker 容器
```bash
# 停止并删除 PostgreSQL 容器
docker stop postgres-e2e 2> /dev/null
docker rm postgres-e2e 2> /dev/null
```
### 一键清理(推荐)
```bash
# 清理所有 E2E 相关进程和容器
docker stop postgres-e2e 2> /dev/null
docker rm postgres-e2e 2> /dev/null
lsof -ti:3006 | xargs kill -9 2> /dev/null
lsof -ti:3010 | xargs kill -9 2> /dev/null
lsof -ti:5433 | xargs kill -9 2> /dev/null
echo "Cleanup done"
```
### 清理端口占用
如果遇到端口被占用的错误,可以清理特定端口:
```bash
# 清理 Next.js 服务器端口
lsof -ti:3006 | xargs kill -9
# 清理 PostgreSQL 端口
lsof -ti:5433 | xargs kill -9
```
## 常见问题
### 1. 测试超时 (function timed out)
**原因**: 元素定位失败或等待时间不足
**解决**:
- 检查选择器是否正确
- 增加 timeout 参数
- 添加显式等待 `waitForTimeout()`
### 2. strict mode violation (多个元素匹配)
**原因**: 选择器匹配到多个元素(如 desktop/mobile 双组件)
**解决**:
- 使用 `.first()``.nth(n)`
- 使用 `boundingBox()` 过滤可见元素
### 3. LLM Mock 未生效
**原因**: 路由拦截设置在页面导航之后
**解决**: 确保在 `page.goto()` 之前调用 `llmMockManager.setup(page)`
### 4. 输入框内容为空
**原因**: contenteditable 编辑器的特殊性
**解决**:
- 先 click 容器确保焦点
- 使用 `keyboard.type()` 而非 `fill()`
- 添加适当的等待时间
## 编写新测试的流程
1. **创建 Feature 文件** (`src/features/xxx/xxx.feature`)
- 使用中文描述场景
- 添加适当的标签 (@journey, @P0, @smoke 等)
2. **创建 Step Definitions** (`src/steps/xxx/xxx.steps.ts`)
- 导入必要的 mock 和工具
- 每个步骤添加日志
- 处理元素定位的边界情况
3. **设置 Mock**(如需要)
-`src/mocks/` 下创建对应的 mock
- 在步骤中初始化 mock
4. **调试和验证**
- 先用 `HEADLESS=false` 运行观察
- 检查失败截图
- 确保稳定通过后再提交
+2 -2
View File
@@ -10,11 +10,11 @@ export default {
formatOptions: {
snippetInterface: 'async-await',
},
parallel: process.env.CI ? 1 : 4,
parallel: 1,
paths: ['src/features/**/*.feature'],
publishQuiet: true,
require: ['src/steps/**/*.ts', 'src/support/**/*.ts'],
requireModule: ['tsx/cjs'],
retry: 0,
timeout: 120_000,
timeout: 30_000,
};
+68
View File
@@ -0,0 +1,68 @@
# LLM Mock 实现
## 核心原理
LLM Mock 通过 Playwright 的 `page.route()` 拦截对 `/webapi/chat/openai` 的请求,返回预设的 SSE 流式响应。
## SSE 响应格式
LobeHub 使用特定的 SSE 格式,必须严格匹配:
```
// 1. 初始 data 事件
id: msg_xxx
event: data
data: {"id":"msg_xxx","model":"gpt-4o-mini","role":"assistant","type":"message",...}
// 2. 文本内容分块(text 事件)
id: msg_xxx
event: text
data: "Hello"
id: msg_xxx
event: text
data: "! I am"
// 3. 停止事件
id: msg_xxx
event: stop
data: "end_turn"
// 4. 使用量统计
id: msg_xxx
event: usage
data: {"totalTokens":100,...}
// 5. 最终停止
id: msg_xxx
event: stop
data: "message_stop"
```
## 使用示例
```typescript
import { llmMockManager, presetResponses } from '../../mocks/llm';
// 在测试步骤中设置 mock
llmMockManager.setResponse('hello', presetResponses.greeting);
await llmMockManager.setup(this.page);
```
## 添加自定义响应
```typescript
// 为特定用户消息设置响应
llmMockManager.setResponse('你好', '你好!我是 Lobe AI,有什么可以帮助你的?');
// 清除所有自定义响应
llmMockManager.clearResponses();
```
## 常见问题
### LLM Mock 未生效
**原因**: 路由拦截设置在页面导航之后
**解决**: 确保在 `page.goto()` 之前调用 `llmMockManager.setup(page)`
+354
View File
@@ -0,0 +1,354 @@
# 本地运行 E2E 测试
## 前置要求
- Docker Desktop 已安装并**正在运行**
- Node.js 18+
- pnpm 已安装
- 项目已 `pnpm install`
## 完整启动流程
### Step 0: 环境清理(重要!)
每次运行测试前,建议先清理环境,避免残留状态导致问题。
```bash
# 0.1 确保 Docker Desktop 正在运行
# 如果未运行,请先启动 Docker Desktop
# 0.2 清理旧的 PostgreSQL 容器
docker stop postgres-e2e 2> /dev/null
docker rm postgres-e2e 2> /dev/null
# 0.3 清理占用的端口
lsof -ti:3006 | xargs kill -9 2> /dev/null # Next.js 服务器端口
lsof -ti:5433 | xargs kill -9 2> /dev/null # PostgreSQL 端口
```
### Step 1: 启动数据库
```bash
# 启动 PostgreSQL (端口 5433)
docker run -d --name postgres-e2e \
-e POSTGRES_PASSWORD=postgres \
-p 5433:5432 \
paradedb/paradedb:latest
# 等待数据库就绪
until docker exec postgres-e2e pg_isready; do sleep 2; done
echo "PostgreSQL is ready!"
```
### Step 2: 运行数据库迁移
```bash
# 在项目根目录运行
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
DATABASE_DRIVER=node \
bun run db:migrate
```
### Step 3: 构建应用(首次或代码变更后)
```bash
# 在项目根目录运行
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
DATABASE_DRIVER=node \
KEY_VAULTS_SECRET=LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s= \
BETTER_AUTH_SECRET=e2e-test-secret-key-for-better-auth-32chars! \
NEXT_PUBLIC_ENABLE_BETTER_AUTH=1 \
SKIP_LINT=1 \
bun run build
```
### Step 4: 启动应用服务器
**重要**: 必须在**项目根目录**运行,不能在 e2e 目录运行!
```bash
# 在项目根目录运行(注意:不是 e2e 目录)
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
DATABASE_DRIVER=node \
KEY_VAULTS_SECRET=LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s= \
BETTER_AUTH_SECRET=e2e-test-secret-key-for-better-auth-32chars! \
NEXT_PUBLIC_ENABLE_BETTER_AUTH=1 \
NEXT_PUBLIC_AUTH_EMAIL_VERIFICATION=0 \
S3_ACCESS_KEY_ID=e2e-mock-access-key \
S3_SECRET_ACCESS_KEY=e2e-mock-secret-key \
S3_BUCKET=e2e-mock-bucket \
S3_ENDPOINT=https://e2e-mock-s3.localhost \
bunx next start -p 3006
```
### Step 5: 等待服务器就绪
```bash
# 在另一个终端运行,确认服务器已启动
until curl -s http://localhost:3006 > /dev/null; do
sleep 2
echo "Waiting..."
done
echo "Server is ready!"
```
### Step 6: 运行测试
```bash
# 在 e2e 目录运行测试
cd e2e
# 运行特定标签(默认无头模式)
BASE_URL=http://localhost:3006 \
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
pnpm exec cucumber-js --config cucumber.config.js --tags "@conversation"
# 运行所有测试
BASE_URL=http://localhost:3006 \
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
pnpm exec cucumber-js --config cucumber.config.js
# 调试模式(显示浏览器,观察执行过程)
HEADLESS=false \
BASE_URL=http://localhost:3006 \
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
pnpm exec cucumber-js --config cucumber.config.js --tags "@conversation"
```
## 一键启动脚本
### 完整初始化(首次运行或需要重建)
在项目根目录创建 `e2e-init.sh`
```bash
#!/bin/bash
set -e
echo "🧹 Step 0: Cleaning up..."
docker stop postgres-e2e 2> /dev/null || true
docker rm postgres-e2e 2> /dev/null || true
lsof -ti:3006 | xargs kill -9 2> /dev/null || true
lsof -ti:5433 | xargs kill -9 2> /dev/null || true
echo "🐘 Step 1: Starting PostgreSQL..."
docker run -d --name postgres-e2e \
-e POSTGRES_PASSWORD=postgres \
-p 5433:5432 \
paradedb/paradedb:latest
echo "⏳ Waiting for PostgreSQL..."
until docker exec postgres-e2e pg_isready 2> /dev/null; do sleep 2; done
echo "✅ PostgreSQL is ready!"
echo "🔄 Step 2: Running migrations..."
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
DATABASE_DRIVER=node \
bun run db:migrate
echo "🔨 Step 3: Building application..."
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
DATABASE_DRIVER=node \
KEY_VAULTS_SECRET=LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s= \
BETTER_AUTH_SECRET=e2e-test-secret-key-for-better-auth-32chars! \
NEXT_PUBLIC_ENABLE_BETTER_AUTH=1 \
SKIP_LINT=1 \
bun run build
echo "✅ Initialization complete! Now run e2e-start.sh to start the server."
```
### 快速启动服务器
在项目根目录创建 `e2e-start.sh`
```bash
#!/bin/bash
set -e
echo "🧹 Cleaning up ports..."
lsof -ti:3006 | xargs kill -9 2> /dev/null || true
echo "🚀 Starting Next.js server on port 3006..."
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
DATABASE_DRIVER=node \
KEY_VAULTS_SECRET=LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s= \
BETTER_AUTH_SECRET=e2e-test-secret-key-for-better-auth-32chars! \
NEXT_PUBLIC_ENABLE_BETTER_AUTH=1 \
NEXT_PUBLIC_AUTH_EMAIL_VERIFICATION=0 \
S3_ACCESS_KEY_ID=e2e-mock-access-key \
S3_SECRET_ACCESS_KEY=e2e-mock-secret-key \
S3_BUCKET=e2e-mock-bucket \
S3_ENDPOINT=https://e2e-mock-s3.localhost \
bunx next start -p 3006
```
### 运行测试
在 e2e 目录创建 `run-test.sh`
```bash
#!/bin/bash
# 默认参数
TAGS="${1:-@journey}"
HEADLESS="${HEADLESS:-true}" # 默认无头模式
echo "🧪 Running E2E tests with tags: $TAGS"
echo " Headless: $HEADLESS"
HEADLESS=$HEADLESS \
BASE_URL=http://localhost:3006 \
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
pnpm exec cucumber-js --config cucumber.config.js --tags "$TAGS"
```
使用方式:
```bash
# 运行特定标签(默认无头模式)
./run-test.sh "@conversation"
# 调试模式(显示浏览器)
HEADLESS=false ./run-test.sh "@conversation"
```
## 快速启动(假设数据库和构建已完成)
```bash
# Terminal 1: 启动服务器(项目根目录)
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
DATABASE_DRIVER=node \
KEY_VAULTS_SECRET=LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s= \
BETTER_AUTH_SECRET=e2e-test-secret-key-for-better-auth-32chars! \
NEXT_PUBLIC_ENABLE_BETTER_AUTH=1 \
NEXT_PUBLIC_AUTH_EMAIL_VERIFICATION=0 \
S3_ACCESS_KEY_ID=e2e-mock-access-key \
S3_SECRET_ACCESS_KEY=e2e-mock-secret-key \
S3_BUCKET=e2e-mock-bucket \
S3_ENDPOINT=https://e2e-mock-s3.localhost \
bunx next start -p 3006
# Terminal 2: 运行测试(e2e 目录,默认无头模式)
cd e2e
BASE_URL=http://localhost:3006 \
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
pnpm exec cucumber-js --config cucumber.config.js --tags "@conversation"
# 调试模式(显示浏览器)
HEADLESS=false BASE_URL=http://localhost:3006 \
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
pnpm exec cucumber-js --config cucumber.config.js --tags "@conversation"
```
## 环境变量参考
### 测试运行时环境变量
| 变量 | 值 | 说明 |
| -------------- | -------------------------------------------------------- | --------------------------------------------------- |
| `BASE_URL` | `http://localhost:3006` | 测试服务器地址 |
| `DATABASE_URL` | `postgresql://postgres:postgres@localhost:5433/postgres` | 数据库连接 |
| `HEADLESS` | `true`(默认)/`false` | 是否无头模式运行浏览器,设为 `false` 可观察执行过程 |
### 服务器启动环境变量(全部必需)
| 变量 | 值 | 说明 |
| ------------------------------------- | -------------------------------------------------------- | ---------------- |
| `DATABASE_URL` | `postgresql://postgres:postgres@localhost:5433/postgres` | 数据库连接 |
| `DATABASE_DRIVER` | `node` | 数据库驱动 |
| `KEY_VAULTS_SECRET` | `LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s=` | 密钥保险库密钥 |
| `BETTER_AUTH_SECRET` | `e2e-test-secret-key-for-better-auth-32chars!` | 认证密钥 |
| `NEXT_PUBLIC_ENABLE_BETTER_AUTH` | `1` | 启用 Better Auth |
| `NEXT_PUBLIC_AUTH_EMAIL_VERIFICATION` | `0` | 禁用邮箱验证 |
### S3 Mock 变量(必需!)
| 变量 | 值 |
| ---------------------- | ------------------------------- |
| `S3_ACCESS_KEY_ID` | `e2e-mock-access-key` |
| `S3_SECRET_ACCESS_KEY` | `e2e-mock-secret-key` |
| `S3_BUCKET` | `e2e-mock-bucket` |
| `S3_ENDPOINT` | `https://e2e-mock-s3.localhost` |
**注意**: S3 环境变量是**必需**的,即使不测试文件上传功能。缺少这些变量会导致发送消息时报错 "S3 environment variables are not set completely"。
## 常见问题排查
### Docker daemon is not running
**症状**: `Cannot connect to the Docker daemon`
**解决**: 启动 Docker Desktop 应用
### PostgreSQL 容器已存在
**症状**: `docker: Error response from daemon: Conflict. The container name "/postgres-e2e" is already in use`
**解决**:
```bash
docker stop postgres-e2e
docker rm postgres-e2e
```
### S3 environment variables are not set completely
**原因**: 服务器启动时缺少 S3 环境变量
**解决**: 启动服务器时必须设置所有 S3 mock 变量
### Cannot find module './src/libs/next/config/define-config'
**原因**: 在 e2e 目录下运行 `next start`
**解决**: 必须在**项目根目录**运行 `bunx next start`,不能在 e2e 目录运行
### EADDRINUSE: address already in use
**原因**: 端口被占用
**解决**:
```bash
# 查找并杀掉占用端口的进程
lsof -ti:3006 | xargs kill -9
lsof -ti:5433 | xargs kill -9
```
### BeforeAll hook errored: net::ERR_CONNECTION_REFUSED
**原因**: 服务器未启动或未就绪
**解决**:
1. 确认服务器已启动:`curl http://localhost:3006`
2. 确认 `BASE_URL` 环境变量设置正确
3. 等待服务器完全就绪后再运行测试
### 测试超时或不稳定
**可能原因**:
1. 网络延迟
2. 服务器响应慢
3. 元素定位问题
**解决**:
1. 使用 `HEADLESS=false` 观察测试执行过程
2. 检查 `screenshots/` 目录中的失败截图
3. 增加等待时间或使用更稳定的定位器
## 清理环境
测试完成后,清理环境:
```bash
# 停止服务器
lsof -ti:3006 | xargs kill -9
# 停止并删除 PostgreSQL 容器
docker stop postgres-e2e
docker rm postgres-e2e
```
+124
View File
@@ -0,0 +1,124 @@
# 测试技巧
## 页面元素定位
### 富文本编辑器 (contenteditable) 输入
LobeHub 使用 `@lobehub/editor` 作为聊天输入框,是一个 contenteditable 的富文本编辑器。
**关键点**:
1. 不能直接用 `locator.fill()` - 对 contenteditable 不生效
2. 需要先 click 容器让编辑器获得焦点
3. 使用 `keyboard.type()` 输入文本
```typescript
// 正确的输入方式
await chatInputContainer.click();
await this.page.waitForTimeout(500); // 等待焦点
await this.page.keyboard.type(message, { delay: 30 });
await this.page.keyboard.press('Enter'); // 发送
```
### 添加 data-testid
为了更可靠的元素定位,可以在组件上添加 `data-testid`
```tsx
// src/features/ChatInput/Desktop/index.tsx
<ChatInput
data-testid="chat-input"
...
/>
```
## 调试技巧
### 添加步骤日志
在每个关键步骤添加 console.log,帮助定位问题:
```typescript
Given('用户进入页面', async function (this: CustomWorld) {
console.log(' 📍 Step: 导航到首页...');
await this.page.goto('/');
console.log(' 📍 Step: 查找元素...');
const element = this.page.locator('...');
console.log(' ✅ 步骤完成');
});
```
### 查看失败截图
测试失败时会自动保存截图到 `e2e/screenshots/` 目录。
### 非 headless 模式
设置 `HEADLESS=false` 可以看到浏览器操作:
```bash
HEADLESS=false pnpm exec cucumber-js --config cucumber.config.js --tags "@smoke"
```
## 常见问题
### waitForLoadState ('networkidle') 超时
**原因**: `networkidle` 表示 500ms 内没有网络请求。在 CI 环境中,由于分析脚本、外部资源加载、轮询等持续网络活动,这个状态可能永远无法达到。
**错误示例**:
```
page.waitForLoadState: Timeout 10000ms exceeded.
=========================== logs ===========================
"load" event fired
============================================================
```
**解决**:
- **避免使用 `networkidle`** - 这是不可靠的等待策略
- **直接等待目标元素** - 使用 `expect(element).toBeVisible({ timeout: 30_000 })` 替代
- 如果必须等待页面加载完成,使用 `domcontentloaded``load` 事件
```typescript
// ❌ 不推荐 - networkidle 在 CI 中容易超时
await this.page.waitForLoadState('networkidle', { timeout: 10_000 });
const element = this.page.locator('[data-testid="my-element"]');
await expect(element).toBeVisible();
// ✅ 推荐 - 直接等待目标元素
const element = this.page.locator('[data-testid="my-element"]');
await expect(element).toBeVisible({ timeout: 30_000 });
```
### 测试超时 (function timed out)
**原因**: 元素定位失败或等待时间不足
**解决**:
- 检查选择器是否正确
- 增加 timeout 参数
- 添加显式等待 `waitForTimeout()`
### strict mode violation (多个元素匹配)
**原因**: 选择器匹配到多个元素(如 desktop/mobile 双组件)
**解决**:
- 使用 `.first()``.nth(n)`
- 使用 `boundingBox()` 过滤可见元素
### 输入框内容为空
**原因**: contenteditable 编辑器的特殊性
**解决**:
- 先 click 容器确保焦点
- 使用 `keyboard.type()` 而非 `fill()`
- 添加适当的等待时间
+4
View File
@@ -4,7 +4,9 @@
"private": true,
"description": "E2E tests for LobeChat using Cucumber and Playwright",
"scripts": {
"build": "cd .. && bun run build",
"test": "cucumber-js --config cucumber.config.js",
"test:ci": "bun run build && bun run test",
"test:discover": "cucumber-js --config cucumber.config.js src/features/discover/",
"test:headed": "HEADLESS=false cucumber-js --config cucumber.config.js",
"test:routes": "cucumber-js --config cucumber.config.js --tags '@routes'",
@@ -14,6 +16,8 @@
"dependencies": {
"@cucumber/cucumber": "^12.2.0",
"@playwright/test": "^1.57.0",
"bcryptjs": "^3.0.3",
"pg": "^8.16.0",
"playwright": "^1.57.0"
},
"devDependencies": {
@@ -11,7 +11,7 @@ Feature: Discover Detail Pages
@DISCOVER-DETAIL-001 @P1
Scenario: Load assistant detail page and verify content
Given I navigate to "/discover/assistant"
Given I navigate to "/community/assistant"
And I wait for the page to fully load
When I click on the first assistant card
Then I should be on an assistant detail page
@@ -22,7 +22,7 @@ Feature: Discover Detail Pages
@DISCOVER-DETAIL-002 @P1
Scenario: Navigate back from assistant detail page
Given I navigate to "/discover/assistant"
Given I navigate to "/community/assistant"
And I wait for the page to fully load
And I click on the first assistant card
When I click the back button
@@ -34,7 +34,7 @@ Feature: Discover Detail Pages
@DISCOVER-DETAIL-003 @P1
Scenario: Load model detail page and verify content
Given I navigate to "/discover/model"
Given I navigate to "/community/model"
And I wait for the page to fully load
When I click on the first model card
Then I should be on a model detail page
@@ -44,7 +44,7 @@ Feature: Discover Detail Pages
@DISCOVER-DETAIL-004 @P1
Scenario: Navigate back from model detail page
Given I navigate to "/discover/model"
Given I navigate to "/community/model"
And I wait for the page to fully load
And I click on the first model card
When I click the back button
@@ -56,7 +56,7 @@ Feature: Discover Detail Pages
@DISCOVER-DETAIL-005 @P1
Scenario: Load provider detail page and verify content
Given I navigate to "/discover/provider"
Given I navigate to "/community/provider"
And I wait for the page to fully load
When I click on the first provider card
Then I should be on a provider detail page
@@ -66,7 +66,7 @@ Feature: Discover Detail Pages
@DISCOVER-DETAIL-006 @P1
Scenario: Navigate back from provider detail page
Given I navigate to "/discover/provider"
Given I navigate to "/community/provider"
And I wait for the page to fully load
And I click on the first provider card
When I click the back button
@@ -78,7 +78,7 @@ Feature: Discover Detail Pages
@DISCOVER-DETAIL-007 @P1
Scenario: Load MCP detail page and verify content
Given I navigate to "/discover/mcp"
Given I navigate to "/community/mcp"
And I wait for the page to fully load
When I click on the first MCP card
Then I should be on an MCP detail page
@@ -88,7 +88,7 @@ Feature: Discover Detail Pages
@DISCOVER-DETAIL-008 @P1
Scenario: Navigate back from MCP detail page
Given I navigate to "/discover/mcp"
Given I navigate to "/community/mcp"
And I wait for the page to fully load
And I click on the first MCP card
When I click the back button
+14 -14
View File
@@ -11,14 +11,14 @@ Feature: Discover Interactions
@DISCOVER-INTERACT-001 @P1
Scenario: Search for assistants
Given I navigate to "/discover/assistant"
Given I navigate to "/community/assistant"
When I type "developer" in the search bar
And I wait for the search results to load
Then I should see filtered assistant cards
@DISCOVER-INTERACT-002 @P1
Scenario: Filter assistants by category
Given I navigate to "/discover/assistant"
Given I navigate to "/community/assistant"
When I click on a category in the category menu
And I wait for the filtered results to load
Then I should see assistant cards filtered by the selected category
@@ -26,7 +26,7 @@ Feature: Discover Interactions
@DISCOVER-INTERACT-003 @P1
Scenario: Navigate to next page of assistants
Given I navigate to "/discover/assistant"
Given I navigate to "/community/assistant"
When I click the next page button
And I wait for the next page to load
Then I should see different assistant cards
@@ -34,7 +34,7 @@ Feature: Discover Interactions
@DISCOVER-INTERACT-004 @P1
Scenario: Navigate to assistant detail page
Given I navigate to "/discover/assistant"
Given I navigate to "/community/assistant"
When I click on the first assistant card
Then I should be navigated to the assistant detail page
And I should see the assistant detail content
@@ -45,7 +45,7 @@ Feature: Discover Interactions
@DISCOVER-INTERACT-005 @P1
Scenario: Sort models
Given I navigate to "/discover/model"
Given I navigate to "/community/model"
When I click on the sort dropdown
And I select a sort option
And I wait for the sorted results to load
@@ -53,7 +53,7 @@ Feature: Discover Interactions
@DISCOVER-INTERACT-006 @P1
Scenario: Navigate to model detail page
Given I navigate to "/discover/model"
Given I navigate to "/community/model"
When I click on the first model card
Then I should be navigated to the model detail page
And I should see the model detail content
@@ -64,7 +64,7 @@ Feature: Discover Interactions
@DISCOVER-INTERACT-007 @P1
Scenario: Navigate to provider detail page
Given I navigate to "/discover/provider"
Given I navigate to "/community/provider"
When I click on the first provider card
Then I should be navigated to the provider detail page
And I should see the provider detail content
@@ -75,14 +75,14 @@ Feature: Discover Interactions
@DISCOVER-INTERACT-008 @P1
Scenario: Filter MCP tools by category
Given I navigate to "/discover/mcp"
Given I navigate to "/community/mcp"
When I click on a category in the category filter
And I wait for the filtered results to load
Then I should see MCP cards filtered by the selected category
@DISCOVER-INTERACT-009 @P1
Scenario: Navigate to MCP detail page
Given I navigate to "/discover/mcp"
Given I navigate to "/community/mcp"
When I click on the first MCP card
Then I should be navigated to the MCP detail page
And I should see the MCP detail content
@@ -93,21 +93,21 @@ Feature: Discover Interactions
@DISCOVER-INTERACT-010 @P1
Scenario: Navigate from home to assistant list
Given I navigate to "/discover"
Given I navigate to "/community"
When I click on the "more" link in the featured assistants section
Then I should be navigated to "/discover/assistant"
Then I should be navigated to "/community/assistant"
And I should see the page body
@DISCOVER-INTERACT-011 @P1
Scenario: Navigate from home to MCP list
Given I navigate to "/discover"
Given I navigate to "/community"
When I click on the "more" link in the featured MCP tools section
Then I should be navigated to "/discover/mcp"
Then I should be navigated to "/community/mcp"
And I should see the page body
@DISCOVER-INTERACT-012 @P1
Scenario: Click featured assistant from home
Given I navigate to "/discover"
Given I navigate to "/community"
When I click on the first featured assistant card
Then I should be navigated to the assistant detail page
And I should see the assistant detail content
+8 -8
View File
@@ -1,10 +1,10 @@
@discover @smoke
Feature: Discover Smoke Tests
Critical path tests to ensure the discover module is functional
Feature: Community Smoke Tests
Critical path tests to ensure the community/discover module is functional
@DISCOVER-SMOKE-001 @P0
Scenario: Load Discover Home Page
Given I navigate to "/discover"
Scenario: Load Community Home Page
Given I navigate to "/community"
Then the page should load without errors
And I should see the page body
And I should see the featured assistants section
@@ -12,7 +12,7 @@ Feature: Discover Smoke Tests
@DISCOVER-SMOKE-002 @P0
Scenario: Load Assistant List Page
Given I navigate to "/discover/assistant"
Given I navigate to "/community/assistant"
Then the page should load without errors
And I should see the page body
And I should see the search bar
@@ -22,7 +22,7 @@ Feature: Discover Smoke Tests
@DISCOVER-SMOKE-003 @P0
Scenario: Load Model List Page
Given I navigate to "/discover/model"
Given I navigate to "/community/model"
Then the page should load without errors
And I should see the page body
And I should see model cards
@@ -30,14 +30,14 @@ Feature: Discover Smoke Tests
@DISCOVER-SMOKE-004 @P0
Scenario: Load Provider List Page
Given I navigate to "/discover/provider"
Given I navigate to "/community/provider"
Then the page should load without errors
And I should see the page body
And I should see provider cards
@DISCOVER-SMOKE-005 @P0
Scenario: Load MCP List Page
Given I navigate to "/discover/mcp"
Given I navigate to "/community/mcp"
Then the page should load without errors
And I should see the page body
And I should see MCP cards
@@ -0,0 +1,45 @@
@journey @agent @conversation-mgmt
Feature: Agent 对话管理用户体验链路
Background:
Given
And Lobe AI
@AGENT-CONV-001 @P0
Scenario: 创建新对话
Given
When
Then
And
@AGENT-CONV-002 @P0
Scenario: 切换不同对话
Given
When
Then
And
@AGENT-CONV-003 @P0
Scenario: 重命名对话
Given
When
And
And ""
Then ""
@AGENT-CONV-004 @P0
Scenario: 删除对话
Given
When
And
And
Then
And
@AGENT-CONV-005 @P1
Scenario: 搜索历史对话
Given
When ""
Then ""
And
@@ -0,0 +1,13 @@
@journey @agent @conversation
Feature: Agent 对话用户体验链路
AI
Background:
Given
@AGENT-CHAT-001 @P0 @smoke
Scenario: 使用 Lobe AI 发送消息并获得回复
Given Lobe AI
When "hello"
Then
And
@@ -0,0 +1,36 @@
@journey @agent @message-ops
Feature: Agent 消息操作用户体验链路
Background:
Given
And Lobe AI
And "hello"
@AGENT-MSG-001 @P1
Scenario: 复制消息内容
When
Then
@AGENT-MSG-002 @P1
Scenario: 编辑助手消息
When
And ""
And
Then ""
@AGENT-MSG-003 @P1
Scenario: 删除单条消息
When
And
And
Then
@AGENT-MSG-004 @P1
Scenario: 折叠和展开消息
When
And
Then
When
And
Then
+212
View File
@@ -0,0 +1,212 @@
/**
* Mock data for Discover/Community module
*/
import type {
AssistantListResponse,
McpListResponse,
ModelListResponse,
ProviderListResponse,
} from './types';
// ============================================
// Assistant Mock Data
// ============================================
export const mockAssistantList: AssistantListResponse = {
items: [
{
author: 'LobeHub',
avatar: '🤖',
backgroundColor: '#1890ff',
category: 'general',
createdAt: '2024-01-01T00:00:00.000Z',
description: 'A versatile AI assistant for general tasks and conversations.',
identifier: 'general-assistant',
installCount: 1000,
knowledgeCount: 5,
pluginCount: 3,
title: 'General Assistant',
tokenUsage: 4096,
userName: 'lobehub',
},
{
author: 'LobeHub',
avatar: '💻',
backgroundColor: '#52c41a',
category: 'programming',
createdAt: '2024-01-02T00:00:00.000Z',
description: 'Expert coding assistant for software development.',
identifier: 'code-assistant',
installCount: 800,
knowledgeCount: 10,
pluginCount: 5,
title: 'Code Assistant',
tokenUsage: 8192,
userName: 'lobehub',
},
{
author: 'LobeHub',
avatar: '✍️',
backgroundColor: '#722ed1',
category: 'copywriting',
createdAt: '2024-01-03T00:00:00.000Z',
description: 'Professional writing assistant for content creation.',
identifier: 'writing-assistant',
installCount: 600,
knowledgeCount: 3,
pluginCount: 2,
title: 'Writing Assistant',
tokenUsage: 4096,
userName: 'lobehub',
},
],
pagination: {
page: 1,
pageSize: 12,
total: 3,
totalPages: 1,
},
};
export const mockAssistantCategories = [
{ id: 'general', name: 'General' },
{ id: 'programming', name: 'Programming' },
{ id: 'copywriting', name: 'Copywriting' },
{ id: 'education', name: 'Education' },
];
// ============================================
// Model Mock Data
// ============================================
export const mockModelList: ModelListResponse = {
items: [
{
abilities: { functionCall: true, reasoning: true, vision: true },
contextWindowTokens: 128_000,
createdAt: '2024-01-01T00:00:00.000Z',
description: 'Most capable model for complex tasks',
displayName: 'GPT-4o',
id: 'gpt-4o',
providerId: 'openai',
providerName: 'OpenAI',
type: 'chat',
},
{
abilities: { functionCall: true, reasoning: true, vision: false },
contextWindowTokens: 200_000,
createdAt: '2024-01-02T00:00:00.000Z',
description: 'Advanced AI assistant by Anthropic',
displayName: 'Claude 3.5 Sonnet',
id: 'claude-3-5-sonnet-20241022',
providerId: 'anthropic',
providerName: 'Anthropic',
type: 'chat',
},
{
abilities: { functionCall: false, reasoning: false, vision: false },
contextWindowTokens: 32_768,
createdAt: '2024-01-03T00:00:00.000Z',
description: 'Open source language model',
displayName: 'Llama 3.1 70B',
id: 'llama-3.1-70b',
providerId: 'meta',
providerName: 'Meta',
type: 'chat',
},
],
pagination: {
page: 1,
pageSize: 12,
total: 3,
totalPages: 1,
},
};
// ============================================
// Provider Mock Data
// ============================================
export const mockProviderList: ProviderListResponse = {
items: [
{
description: 'Leading AI research company',
id: 'openai',
logo: 'https://example.com/openai.png',
modelCount: 10,
name: 'OpenAI',
},
{
description: 'AI safety focused research company',
id: 'anthropic',
logo: 'https://example.com/anthropic.png',
modelCount: 5,
name: 'Anthropic',
},
{
description: 'Open source AI leader',
id: 'meta',
logo: 'https://example.com/meta.png',
modelCount: 8,
name: 'Meta',
},
],
pagination: {
page: 1,
pageSize: 12,
total: 3,
totalPages: 1,
},
};
// ============================================
// MCP Mock Data
// ============================================
export const mockMcpList: McpListResponse = {
items: [
{
author: 'LobeHub',
avatar: '🔍',
category: 'search',
createdAt: '2024-01-01T00:00:00.000Z',
description: 'Web search capabilities for AI assistants',
identifier: 'web-search',
installCount: 500,
title: 'Web Search',
},
{
author: 'LobeHub',
avatar: '📁',
category: 'file',
createdAt: '2024-01-02T00:00:00.000Z',
description: 'File system operations and management',
identifier: 'file-manager',
installCount: 300,
title: 'File Manager',
},
{
author: 'LobeHub',
avatar: '🗄️',
category: 'database',
createdAt: '2024-01-03T00:00:00.000Z',
description: 'Database query and management tools',
identifier: 'db-tools',
installCount: 200,
title: 'Database Tools',
},
],
pagination: {
page: 1,
pageSize: 12,
total: 3,
totalPages: 1,
},
};
export const mockMcpCategories = [
{ id: 'search', name: 'Search' },
{ id: 'file', name: 'File' },
{ id: 'database', name: 'Database' },
{ id: 'utility', name: 'Utility' },
];
+179
View File
@@ -0,0 +1,179 @@
/**
* Mock handlers for Discover/Community API endpoints
*/
import type { Route } from 'playwright';
import { type MockHandler, createTrpcResponse } from '../index';
import {
mockAssistantCategories,
mockAssistantList,
mockMcpCategories,
mockMcpList,
mockModelList,
mockProviderList,
} from './data';
// ============================================
// Helper to parse tRPC batch requests
// ============================================
function parseTrpcUrl(url: string): { input?: Record<string, unknown>; procedure: string } {
const urlObj = new URL(url);
const pathname = urlObj.pathname;
// Extract procedure name from path like /trpc/lambda.market.getAssistantList
const procedureMatch = pathname.match(/lambda\.market\.(\w+)/);
const procedure = procedureMatch ? procedureMatch[1] : '';
// Parse input from query string
let input: Record<string, unknown> | undefined;
const inputParam = urlObj.searchParams.get('input');
if (inputParam) {
try {
input = JSON.parse(inputParam);
} catch {
// Ignore parse errors
}
}
return { input, procedure };
}
// ============================================
// Mock Handlers
// ============================================
/**
* Handler for assistant list endpoint
*/
const assistantListHandler: MockHandler = {
handler: async (route: Route) => {
await route.fulfill({
body: createTrpcResponse(mockAssistantList),
contentType: 'application/json',
status: 200,
});
},
pattern: '**/trpc/lambda/market.getAssistantList**',
};
/**
* Handler for assistant categories endpoint
*/
const assistantCategoriesHandler: MockHandler = {
handler: async (route: Route) => {
await route.fulfill({
body: createTrpcResponse(mockAssistantCategories),
contentType: 'application/json',
status: 200,
});
},
pattern: '**/trpc/lambda/market.getAssistantCategories**',
};
/**
* Handler for model list endpoint
*/
const modelListHandler: MockHandler = {
handler: async (route: Route) => {
await route.fulfill({
body: createTrpcResponse(mockModelList),
contentType: 'application/json',
status: 200,
});
},
pattern: '**/trpc/lambda/market.getModelList**',
};
/**
* Handler for provider list endpoint
*/
const providerListHandler: MockHandler = {
handler: async (route: Route) => {
await route.fulfill({
body: createTrpcResponse(mockProviderList),
contentType: 'application/json',
status: 200,
});
},
pattern: '**/trpc/lambda/market.getProviderList**',
};
/**
* Handler for MCP list endpoint
*/
const mcpListHandler: MockHandler = {
handler: async (route: Route) => {
await route.fulfill({
body: createTrpcResponse(mockMcpList),
contentType: 'application/json',
status: 200,
});
},
pattern: '**/trpc/lambda/market.getMcpList**',
};
/**
* Handler for MCP categories endpoint
*/
const mcpCategoriesHandler: MockHandler = {
handler: async (route: Route) => {
await route.fulfill({
body: createTrpcResponse(mockMcpCategories),
contentType: 'application/json',
status: 200,
});
},
pattern: '**/trpc/lambda/market.getMcpCategories**',
};
/**
* Debug handler to log all trpc requests
*/
const trpcDebugHandler: MockHandler = {
handler: async (route: Route) => {
const url = route.request().url();
console.log(` 🔍 TRPC Request: ${url}`);
await route.continue();
},
pattern: '**/trpc/**',
};
/**
* Fallback handler for any unhandled market endpoints
* Returns empty data to prevent hanging requests
*/
const marketFallbackHandler: MockHandler = {
handler: async (route: Route) => {
const url = route.request().url();
const { procedure } = parseTrpcUrl(url);
console.log(` ⚠️ Unhandled market endpoint: ${procedure}`);
// Return empty response to prevent timeout
await route.fulfill({
body: createTrpcResponse({ items: [], pagination: { page: 1, pageSize: 12, total: 0 } }),
contentType: 'application/json',
status: 200,
});
},
pattern: '**/trpc/lambda/market.**',
};
// ============================================
// Export all handlers
// ============================================
export const discoverHandlers: MockHandler[] = [
// Debug handler first to log all requests
trpcDebugHandler,
// Specific handlers (order matters - more specific first)
assistantListHandler,
assistantCategoriesHandler,
modelListHandler,
providerListHandler,
mcpListHandler,
mcpCategoriesHandler,
// Fallback handler (should be last)
marketFallbackHandler,
];
+7
View File
@@ -0,0 +1,7 @@
/**
* Discover/Community module mocks
*/
export * from './data';
export { discoverHandlers as discoverMocks } from './handlers';
export * from './types';
+98
View File
@@ -0,0 +1,98 @@
/**
* Type definitions for Discover mock data
* These mirror the actual types from the application
*/
export interface PaginationInfo {
page: number;
pageSize: number;
total: number;
totalPages: number;
}
// ============================================
// Assistant Types
// ============================================
export interface DiscoverAssistantItem {
author: string;
avatar: string;
backgroundColor?: string;
category: string;
createdAt: string;
description: string;
identifier: string;
installCount?: number;
knowledgeCount?: number;
pluginCount?: number;
title: string;
tokenUsage?: number;
userName?: string;
}
export interface AssistantListResponse {
items: DiscoverAssistantItem[];
pagination: PaginationInfo;
}
// ============================================
// Model Types
// ============================================
export interface DiscoverModelItem {
abilities: {
functionCall?: boolean;
reasoning?: boolean;
vision?: boolean;
};
contextWindowTokens: number;
createdAt: string;
description: string;
displayName: string;
id: string;
providerId: string;
providerName: string;
type: string;
}
export interface ModelListResponse {
items: DiscoverModelItem[];
pagination: PaginationInfo;
}
// ============================================
// Provider Types
// ============================================
export interface DiscoverProviderItem {
description: string;
id: string;
logo?: string;
modelCount: number;
name: string;
}
export interface ProviderListResponse {
items: DiscoverProviderItem[];
pagination: PaginationInfo;
}
// ============================================
// MCP Types
// ============================================
export interface DiscoverMcpItem {
author: string;
avatar: string;
category: string;
createdAt: string;
description: string;
identifier: string;
installCount?: number;
title: string;
}
export interface McpListResponse {
items: DiscoverMcpItem[];
pagination: PaginationInfo;
}
+158
View File
@@ -0,0 +1,158 @@
/**
* E2E Mock Framework
*
* This module provides a centralized way to mock API responses in E2E tests.
* It uses Playwright's route interception to mock tRPC and REST API calls.
*/
import type { Page, Route } from 'playwright';
import { discoverMocks } from './discover';
// ============================================
// Types
// ============================================
export interface MockHandler {
/** Optional: only apply this mock when condition is true */
enabled?: boolean;
/** Handler function to process the request */
handler: (route: Route, request: Request) => Promise<void>;
/** URL pattern to match (supports wildcards) */
pattern: string | RegExp;
}
export interface MockConfig {
/** Enable/disable all mocks globally */
enabled: boolean;
/** Mock handlers grouped by domain */
handlers: Record<string, MockHandler[]>;
}
// ============================================
// Default Configuration
// ============================================
const defaultConfig: MockConfig = {
enabled: true,
handlers: {
discover: discoverMocks,
// Add more domains here as needed:
// user: userMocks,
// chat: chatMocks,
},
};
// ============================================
// Mock Manager
// ============================================
export class MockManager {
private config: MockConfig;
private page: Page | null = null;
constructor(config: Partial<MockConfig> = {}) {
this.config = { ...defaultConfig, ...config };
}
/**
* Setup all mock handlers for a page
*/
async setup(page: Page): Promise<void> {
this.page = page;
if (!this.config.enabled) {
console.log('🔇 Mocks disabled');
return;
}
console.log('🎭 Setting up API mocks...');
for (const [domain, handlers] of Object.entries(this.config.handlers)) {
for (const mock of handlers) {
if (mock.enabled === false) continue;
await page.route(mock.pattern, async (route) => {
try {
await mock.handler(route, route.request() as unknown as Request);
} catch (error) {
console.error(`Mock handler error for ${mock.pattern}:`, error);
await route.continue();
}
});
}
console.log(`${domain} mocks registered`);
}
}
/**
* Disable a specific mock domain
*/
disableDomain(domain: string): void {
if (this.config.handlers[domain]) {
for (const handler of this.config.handlers[domain]) {
handler.enabled = false;
}
}
}
/**
* Enable a specific mock domain
*/
enableDomain(domain: string): void {
if (this.config.handlers[domain]) {
for (const handler of this.config.handlers[domain]) {
handler.enabled = true;
}
}
}
/**
* Add custom mock handlers at runtime
*/
addHandlers(domain: string, handlers: MockHandler[]): void {
if (!this.config.handlers[domain]) {
this.config.handlers[domain] = [];
}
this.config.handlers[domain].push(...handlers);
}
}
// ============================================
// Helper Functions
// ============================================
/**
* Create a JSON response for tRPC endpoints
*/
export function createTrpcResponse<T>(data: T): string {
return JSON.stringify({
result: {
data,
},
});
}
/**
* Create an error response for tRPC endpoints
*/
export function createTrpcError(message: string, code = 'INTERNAL_SERVER_ERROR'): string {
return JSON.stringify({
error: {
code,
message,
},
});
}
/**
* Create a standard JSON response
*/
export function createJsonResponse<T>(data: T): string {
return JSON.stringify(data);
}
// ============================================
// Singleton Instance
// ============================================
export const mockManager = new MockManager();
+245
View File
@@ -0,0 +1,245 @@
/**
* LLM Mock Framework
*
* Intercepts /webapi/chat/[provider] requests and returns mock SSE responses.
* This allows E2E tests to run without real LLM API calls.
*/
import type { Page, Route } from 'playwright';
// ============================================
// Types
// ============================================
export interface LLMMockConfig {
/** Default response content when no specific mock is set */
defaultResponse: string;
/** Whether to enable LLM mocking */
enabled: boolean;
/** Response delay in ms (simulates network latency) */
responseDelay: number;
/** Chunk size for streaming (characters per chunk) */
streamChunkSize: number;
/** Delay between chunks in ms */
streamDelay: number;
}
export interface ChatMessage {
content: string;
role: 'user' | 'assistant' | 'system';
}
// ============================================
// Default Configuration
// ============================================
const defaultConfig: LLMMockConfig = {
defaultResponse: 'Hello! I am a mock AI assistant. How can I help you today?',
enabled: true,
responseDelay: 100,
streamChunkSize: 10,
streamDelay: 20,
};
// ============================================
// SSE Response Builder
// ============================================
/**
* Build SSE formatted response chunks
* Follows LobeChat's actual streaming format
*/
function buildSSEChunks(content: string, chunkSize: number): string[] {
const chunks: string[] = [];
const id = `msg_mock_${Date.now()}`;
// Initial message data
const initialData = {
content: [],
id,
model: 'gpt-4o-mini',
role: 'assistant',
stop_reason: null,
stop_sequence: null,
type: 'message',
usage: { input_tokens: 10, output_tokens: 0 },
};
chunks.push(`id: ${id}\nevent: data\ndata: ${JSON.stringify(initialData)}\n\n`);
// Split content into chunks and send as text events
for (let i = 0; i < content.length; i += chunkSize) {
const chunk = content.slice(i, i + chunkSize);
chunks.push(`id: ${id}\nevent: text\ndata: "${chunk.replaceAll('"', '\\"')}"\n\n`);
}
// Stop event
chunks.push(`id: ${id}\nevent: stop\ndata: "end_turn"\n\n`);
// Usage event
const usageData = {
cost: 0.0001,
inputCacheMissTokens: 10,
inputCachedTokens: 0,
totalInputTokens: 10,
totalOutputTokens: Math.ceil(content.length / 4),
totalTokens: 10 + Math.ceil(content.length / 4),
};
chunks.push(
`id: ${id}\nevent: usage\ndata: ${JSON.stringify(usageData)}\n\n`,
`id: ${id}\nevent: stop\ndata: "message_stop"\n\n`,
);
return chunks;
}
// ============================================
// LLM Mock Manager
// ============================================
export class LLMMockManager {
private config: LLMMockConfig;
private customResponses: Map<string, string> = new Map();
private page: Page | null = null;
constructor(config: Partial<LLMMockConfig> = {}) {
this.config = { ...defaultConfig, ...config };
}
/**
* Set a custom response for a specific user message
*/
setResponse(userMessage: string, response: string): void {
this.customResponses.set(userMessage.toLowerCase().trim(), response);
}
/**
* Clear all custom responses
*/
clearResponses(): void {
this.customResponses.clear();
}
/**
* Get response for a user message
*/
private getResponse(messages: ChatMessage[]): string {
// Find the last user message
const lastUserMessage = [...messages].reverse().find((m) => m.role === 'user');
if (lastUserMessage) {
const key = lastUserMessage.content.toLowerCase().trim();
if (this.customResponses.has(key)) {
return this.customResponses.get(key)!;
}
}
return this.config.defaultResponse;
}
/**
* Setup LLM mock handlers for a page
*/
async setup(page: Page): Promise<void> {
this.page = page;
if (!this.config.enabled) {
console.log(' 🔇 LLM mocks disabled');
return;
}
// Intercept OpenAI chat API requests
await page.route('**/webapi/chat/openai**', async (route) => {
await this.handleChatRequest(route);
});
console.log(' ✓ LLM mocks registered (openai)');
}
/**
* Handle intercepted chat request
*/
private async handleChatRequest(route: Route): Promise<void> {
const request = route.request();
try {
// Parse request body
const body = request.postDataJSON();
const messages: ChatMessage[] = body?.messages || [];
console.log(` 🤖 LLM Request intercepted (${messages.length} messages)`);
// Get response content
const responseContent = this.getResponse(messages);
// Build SSE chunks
const chunks = buildSSEChunks(responseContent, this.config.streamChunkSize);
// Simulate initial delay
await new Promise((resolve) => {
setTimeout(resolve, this.config.responseDelay);
});
// Create streaming response
const stream = chunks.join('');
await route.fulfill({
body: stream,
headers: {
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Content-Type': 'text/event-stream',
},
status: 200,
});
console.log(` ✅ LLM Response sent (${responseContent.length} chars)`);
} catch (error) {
console.error(' ❌ LLM Mock error:', error);
await route.fulfill({
body: JSON.stringify({ error: 'Mock error' }),
headers: { 'Content-Type': 'application/json' },
status: 500,
});
}
}
/**
* Disable LLM mocking
*/
disable(): void {
this.config.enabled = false;
}
/**
* Enable LLM mocking
*/
enable(): void {
this.config.enabled = true;
}
}
// ============================================
// Singleton Instance
// ============================================
export const llmMockManager = new LLMMockManager();
// ============================================
// Preset Responses
// ============================================
export const presetResponses = {
codeHelp: 'I can help you with coding! Please share the code you would like me to review.',
error: 'I apologize, but I encountered an error processing your request.',
greeting: 'Hello! I am Lobe AI, your AI assistant. How can I help you today?',
// Long response for stop generation test
longArticle:
'这是一篇很长的文章。第一段:人工智能是计算机科学的一个分支,它企图了解智能的实质,并生产出一种新的能以人类智能相似的方式做出反应的智能机器。第二段:人工智能研究的主要目标包括推理、知识、规划、学习、自然语言处理、感知和移动与操控物体的能力。第三段:目前,人工智能已经在许多领域取得了重大突破,包括图像识别、语音识别、自然语言处理等。',
// Multi-turn conversation responses
nameIntro: '好的,我记住了,你的名字是小明。很高兴认识你,小明!有什么我可以帮助你的吗?',
nameRecall: '你刚才说你的名字是小明。',
// Regenerate response
regenerated: '这是重新生成的回复内容。我是 Lobe AI,很高兴为你服务!',
};
@@ -0,0 +1,428 @@
/**
* Agent Conversation Management Steps
*
* Step definitions for Agent conversation management E2E tests
* - Create new conversation
* - Switch conversations
* - Rename conversation
* - Delete conversation
* - Search conversations
*/
import { Given, Then, When } from '@cucumber/cucumber';
import { expect } from '@playwright/test';
import { CustomWorld } from '../../support/world';
// ============================================
// Given Steps
// ============================================
Given('用户已有一个对话', async function (this: CustomWorld) {
console.log(' 📍 Step: 创建一个对话...');
// Send a message to create a conversation
const chatInputs = this.page.locator('[data-testid="chat-input"]');
const count = await chatInputs.count();
let chatInputContainer = chatInputs.first();
for (let i = 0; i < count; i++) {
const elem = chatInputs.nth(i);
const box = await elem.boundingBox();
if (box && box.width > 0 && box.height > 0) {
chatInputContainer = elem;
break;
}
}
await chatInputContainer.click();
await this.page.waitForTimeout(300);
await this.page.keyboard.type('hello', { delay: 30 });
await this.page.keyboard.press('Enter');
// Wait for response
await this.page.waitForTimeout(2000);
// Store the current conversation title for later reference
const topicItems = this.page.locator('.ant-menu-item, [class*="NavItem"]');
const topicCount = await topicItems.count();
console.log(` 📍 Found ${topicCount} topic items after creating conversation`);
console.log(' ✅ 已创建一个对话');
});
Given('用户有多个对话历史', async function (this: CustomWorld) {
console.log(' 📍 Step: 创建多个对话...');
// Create first conversation
const chatInputs = this.page.locator('[data-testid="chat-input"]');
let chatInputContainer = chatInputs.first();
const count = await chatInputs.count();
for (let i = 0; i < count; i++) {
const elem = chatInputs.nth(i);
const box = await elem.boundingBox();
if (box && box.width > 0 && box.height > 0) {
chatInputContainer = elem;
break;
}
}
// First conversation - use "测试" content for search test
await chatInputContainer.click();
await this.page.waitForTimeout(300);
await this.page.keyboard.type('测试对话内容', { delay: 30 });
await this.page.keyboard.press('Enter');
await this.page.waitForTimeout(2000);
// Store first conversation reference
this.testContext.firstConversation = 'first';
// Create new topic and second conversation
console.log(' 📍 Creating second conversation...');
const addTopicButton = this.page.locator('svg.lucide-message-square-plus').locator('..');
if ((await addTopicButton.count()) > 0) {
await addTopicButton.first().click();
await this.page.waitForTimeout(1000);
// Send message in second conversation - different content
await chatInputContainer.click();
await this.page.waitForTimeout(300);
await this.page.keyboard.type('hello world', { delay: 30 });
await this.page.keyboard.press('Enter');
await this.page.waitForTimeout(2000);
}
console.log(' ✅ 已创建多个对话');
});
// ============================================
// When Steps
// ============================================
When('用户点击新建对话按钮', async function (this: CustomWorld) {
console.log(' 📍 Step: 点击新建对话按钮...');
// The add topic button uses MessageSquarePlusIcon from lucide-react
const addTopicButton = this.page.locator('svg.lucide-message-square-plus').locator('..');
if ((await addTopicButton.count()) > 0) {
await addTopicButton.first().click();
console.log(' ✅ 已点击新建对话按钮');
} else {
// Fallback: look for button with "新建" or "add" in title
const addButton = this.page.locator('button[title*="新建"], button[title*="add"]');
if ((await addButton.count()) > 0) {
await addButton.first().click();
console.log(' ✅ 已点击新建对话按钮 (fallback)');
} else {
throw new Error('New topic button not found');
}
}
await this.page.waitForTimeout(500);
});
When('用户点击另一个对话', async function (this: CustomWorld) {
console.log(' 📍 Step: 点击另一个对话...');
// Find topic items in the sidebar
// Topics are displayed with star icons (lucide-star) in the left sidebar
// Each topic item has a star icon as part of it
const sidebarTopics = this.page.locator('svg.lucide-star').locator('..').locator('..');
let topicCount = await sidebarTopics.count();
console.log(` 📍 Found ${topicCount} topics with star icons`);
// If not found by star, try finding by topic list structure
if (topicCount < 2) {
// Topics might be in a list container - look for items in sidebar with specific text
const topicItems = this.page.locator('[class*="nav-item"], [class*="NavItem"]');
topicCount = await topicItems.count();
console.log(` 📍 Found ${topicCount} nav items`);
if (topicCount >= 2) {
await topicItems.nth(1).click();
console.log(' ✅ 已点击另一个对话');
await this.page.waitForTimeout(500);
return;
}
}
// Click the second topic (first one is current/active)
if (topicCount >= 2) {
await sidebarTopics.nth(1).click();
console.log(' ✅ 已点击另一个对话');
} else {
throw new Error('Not enough topics to switch');
}
await this.page.waitForTimeout(500);
});
When('用户右键点击对话', async function (this: CustomWorld) {
console.log(' 📍 Step: 右键点击对话...');
// Find topic items by their star icon - each saved topic has a star
const sidebarTopics = this.page.locator('svg.lucide-star').locator('..').locator('..');
let topicCount = await sidebarTopics.count();
console.log(` 📍 Found ${topicCount} topics with star icons`);
if (topicCount > 0) {
// Right-click the first saved topic
await sidebarTopics.first().click({ button: 'right' });
console.log(' ✅ 已右键点击对话');
} else {
throw new Error('No topics found to right-click');
}
await this.page.waitForTimeout(500);
});
When('用户右键点击一个对话', async function (this: CustomWorld) {
console.log(' 📍 Step: 右键点击一个对话...');
// Find topic items by their star icon
const sidebarTopics = this.page.locator('svg.lucide-star').locator('..').locator('..');
let topicCount = await sidebarTopics.count();
console.log(` 📍 Found ${topicCount} topics with star icons`);
// Store the topic text for later verification
if (topicCount > 0) {
const topicText = await sidebarTopics.first().textContent();
this.testContext.deletedTopicTitle = topicText?.slice(0, 30);
await sidebarTopics.first().click({ button: 'right' });
console.log(` ✅ 已右键点击对话: "${topicText?.slice(0, 30)}..."`);
} else {
throw new Error('No topics found to right-click');
}
await this.page.waitForTimeout(500);
});
When('用户选择重命名选项', async function (this: CustomWorld) {
console.log(' 📍 Step: 选择重命名选项...');
// The context menu should be visible with "rename" option
// Use exact match to avoid matching "智能重命名"
const renameOption = this.page.getByRole('menuitem', { exact: true, name: '重命名' });
await expect(renameOption).toBeVisible({ timeout: 5000 });
await renameOption.click();
console.log(' ✅ 已选择重命名选项');
await this.page.waitForTimeout(300);
});
When('用户输入新的对话名称 {string}', async function (this: CustomWorld, newName: string) {
console.log(` 📍 Step: 输入新名称 "${newName}"...`);
// The topic should now be in editing mode with an input field
this.page.locator('input[type="text"]').filter({
has: this.page.locator(':focus'),
});
// Wait for input to appear
await this.page.waitForTimeout(500);
// Find the visible input in the sidebar area
const sidebarInput = this.page.locator('[class*="NavItem"] input, .ant-input');
const inputCount = await sidebarInput.count();
console.log(` 📍 Found ${inputCount} input fields`);
if (inputCount > 0) {
const input = sidebarInput.first();
await input.clear();
await input.fill(newName);
await this.page.keyboard.press('Enter');
console.log(` ✅ 已输入新名称 "${newName}"`);
} else {
// Try finding by focused element
await this.page.keyboard.type(newName, { delay: 30 });
await this.page.keyboard.press('Enter');
console.log(` ✅ 已通过键盘输入新名称 "${newName}"`);
}
await this.page.waitForTimeout(500);
});
When('用户选择删除选项', async function (this: CustomWorld) {
console.log(' 📍 Step: 选择删除选项...');
// The context menu should be visible with "delete" option
const deleteOption = this.page.locator(
'.ant-dropdown-menu-item:has-text("删除"), .ant-dropdown-menu-item-danger',
);
await expect(deleteOption).toBeVisible({ timeout: 5000 });
await deleteOption.click();
console.log(' ✅ 已选择删除选项');
await this.page.waitForTimeout(300);
});
When('用户确认删除', async function (this: CustomWorld) {
console.log(' 📍 Step: 确认删除...');
// A confirmation modal should appear
const confirmButton = this.page.locator('.ant-modal-confirm-btns button.ant-btn-dangerous');
// Wait for modal to appear
await expect(confirmButton).toBeVisible({ timeout: 5000 });
await confirmButton.click();
console.log(' ✅ 已确认删除');
await this.page.waitForTimeout(500);
});
When('用户在搜索框中输入 {string}', async function (this: CustomWorld, searchText: string) {
console.log(` 📍 Step: 在搜索框中输入 "${searchText}"...`);
// Find the search input in the sidebar
const searchInput = this.page.locator('input[placeholder*="搜索"], [data-testid="search-input"]');
if ((await searchInput.count()) > 0) {
await searchInput.first().click();
await searchInput.first().fill(searchText);
} else {
// Fallback: click on search icon to reveal search input
const searchIcon = this.page.locator('svg.lucide-search').locator('..');
if ((await searchIcon.count()) > 0) {
await searchIcon.first().click();
await this.page.waitForTimeout(300);
// Now find the input
const input = this.page.locator('input[type="text"]').last();
await input.fill(searchText);
}
}
console.log(` ✅ 已输入搜索内容 "${searchText}"`);
await this.page.waitForTimeout(500);
});
// ============================================
// Then Steps
// ============================================
Then('应该创建一个新的空白对话', async function (this: CustomWorld) {
console.log(' 📍 Step: 验证新对话已创建...');
// The chat area should be empty or show welcome message
// Check that there are no user/assistant messages
const userMessages = this.page.locator('[data-role="user"]');
const assistantMessages = this.page.locator('[data-role="assistant"]');
const userCount = await userMessages.count();
const assistantCount = await assistantMessages.count();
console.log(` 📍 用户消息数量: ${userCount}, 助手消息数量: ${assistantCount}`);
// New conversation should have no messages
expect(userCount).toBe(0);
expect(assistantCount).toBe(0);
console.log(' ✅ 新对话已创建');
});
Then('应该切换到该对话', async function (this: CustomWorld) {
console.log(' 📍 Step: 验证已切换对话...');
// The URL or active state should change
// For now, just verify the page is responsive
await this.page.waitForTimeout(500);
console.log(' ✅ 已切换到该对话');
});
Then('显示该对话的历史消息', async function (this: CustomWorld) {
console.log(' 📍 Step: 验证显示历史消息...');
// There should be messages in the chat area
const messages = this.page.locator('[class*="message"], [data-role]');
const messageCount = await messages.count();
console.log(` 📍 找到 ${messageCount} 条消息`);
// At least some messages should be visible
expect(messageCount).toBeGreaterThan(0);
console.log(' ✅ 历史消息已显示');
});
Then('对话名称应该更新为 {string}', async function (this: CustomWorld, expectedName: string) {
console.log(` 📍 Step: 验证对话名称为 "${expectedName}"...`);
// Wait for the rename to take effect
await this.page.waitForTimeout(1000);
// Find the topic with the new name by text content
// Topics are in the sidebar, look for text directly
// Use .first() since the name might appear in multiple places (sidebar + favorites section)
const renamedTopic = this.page.getByText(expectedName, { exact: true }).first();
await expect(renamedTopic).toBeVisible({ timeout: 5000 });
console.log(` ✅ 对话名称已更新为 "${expectedName}"`);
});
Then('该对话应该被删除', async function (this: CustomWorld) {
console.log(' 📍 Step: 验证对话已删除...');
// Wait for deletion to take effect
await this.page.waitForTimeout(500);
console.log(' ✅ 对话已删除');
});
Then('对话列表中不再显示该对话', async function (this: CustomWorld) {
console.log(' 📍 Step: 验证对话列表中不再显示该对话...');
// Wait for UI to update
await this.page.waitForTimeout(500);
// The deleted topic should not be in the list
if (this.testContext.deletedTopicTitle) {
const deletedTopic = this.page.locator(
`[class*="NavItem"]:has-text("${this.testContext.deletedTopicTitle}")`,
);
const count = await deletedTopic.count();
expect(count).toBe(0);
console.log(` ✅ 对话 "${this.testContext.deletedTopicTitle}" 已从列表中移除`);
} else {
console.log(' ✅ 对话已从列表中移除');
}
});
Then('应该显示包含 {string} 的对话', async function (this: CustomWorld, searchText: string) {
console.log(` 📍 Step: 验证搜索结果包含 "${searchText}"...`);
// Wait for search results to load (search opens a modal dialog)
await this.page.waitForTimeout(2000);
// Search results appear in a modal/dialog, not in sidebar
// Look for the search modal and check for matching results
const searchModal = this.page.locator('.ant-modal, [role="dialog"]');
const hasModal = (await searchModal.count()) > 0;
console.log(` 📍 搜索模态框: ${hasModal}`);
// Find matching items in the search results (either in modal or in sidebar if filtered)
const matchingInModal = searchModal.getByText(searchText);
const matchingInPage = this.page.getByText(searchText);
const modalMatchCount = await matchingInModal.count();
const pageMatchCount = await matchingInPage.count();
console.log(` 📍 模态框中找到 ${modalMatchCount} 个匹配, 页面中找到 ${pageMatchCount} 个匹配`);
// At least one match should be found (either in search input or results)
expect(modalMatchCount + pageMatchCount).toBeGreaterThan(0);
console.log(` ✅ 搜索结果显示包含 "${searchText}" 的对话`);
});
Then('不相关的对话应该被过滤', async function (this: CustomWorld) {
console.log(' 📍 Step: 验证不相关对话已被过滤...');
// This would require checking that non-matching topics are hidden
// For now, just verify the search is active
await this.page.waitForTimeout(300);
console.log(' ✅ 不相关对话已被过滤');
});
+153
View File
@@ -0,0 +1,153 @@
/**
* Agent Conversation Steps
*
* Step definitions for Agent conversation E2E tests
*/
import { Given, Then, When } from '@cucumber/cucumber';
import { expect } from '@playwright/test';
import { llmMockManager, presetResponses } from '../../mocks/llm';
import { CustomWorld } from '../../support/world';
// ============================================
// Given Steps
// ============================================
Given('用户已登录系统', async function (this: CustomWorld) {
// Session cookies are already set by the Before hook
// Just verify we have cookies
const cookies = await this.browserContext.cookies();
expect(cookies.length).toBeGreaterThan(0);
});
Given('用户进入 Lobe AI 对话页面', async function (this: CustomWorld) {
console.log(' 📍 Step: 设置 LLM mock...');
// Setup LLM mock before navigation
llmMockManager.setResponse('hello', presetResponses.greeting);
await llmMockManager.setup(this.page);
console.log(' 📍 Step: 导航到首页...');
// Navigate to home page first
await this.page.goto('/');
await this.page.waitForLoadState('networkidle', { timeout: 10_000 });
console.log(' 📍 Step: 查找 Lobe AI...');
// Find and click on "Lobe AI" agent in the sidebar/home
const lobeAIAgent = this.page.locator('text=Lobe AI').first();
await expect(lobeAIAgent).toBeVisible({ timeout: 10_000 });
console.log(' 📍 Step: 点击 Lobe AI...');
await lobeAIAgent.click();
console.log(' 📍 Step: 等待聊天界面加载...');
// Wait for the chat interface to be ready
await this.page.waitForLoadState('networkidle', { timeout: 10_000 });
console.log(' 📍 Step: 查找输入框...');
// The input is a rich text editor with contenteditable
// There are 2 ChatInput components (desktop & mobile), find the visible one
// Wait for the page to be ready, then find visible chat input
await this.page.waitForTimeout(1000);
// Find all chat-input elements and get the visible one
const chatInputs = this.page.locator('[data-testid="chat-input"]');
const count = await chatInputs.count();
console.log(` 📍 Found ${count} chat-input elements`);
// Find the first visible one or just use the first one
let chatInputContainer = chatInputs.first();
for (let i = 0; i < count; i++) {
const elem = chatInputs.nth(i);
const box = await elem.boundingBox();
if (box && box.width > 0 && box.height > 0) {
chatInputContainer = elem;
console.log(` ✓ Using chat-input element ${i} (has bounding box)`);
break;
}
}
// Click the container to focus the editor
await chatInputContainer.click();
console.log(' ✓ Clicked on chat input container');
// Wait for any animations to complete
await this.page.waitForTimeout(300);
console.log(' ✅ 已进入 Lobe AI 对话页面');
});
// ============================================
// When Steps
// ============================================
When('用户发送消息 {string}', async function (this: CustomWorld, message: string) {
console.log(` 📍 Step: 查找输入框...`);
// Find visible chat input container first
const chatInputs = this.page.locator('[data-testid="chat-input"]');
const count = await chatInputs.count();
console.log(` 📍 Found ${count} chat-input containers`);
let chatInputContainer = chatInputs.first();
for (let i = 0; i < count; i++) {
const elem = chatInputs.nth(i);
const box = await elem.boundingBox();
if (box && box.width > 0 && box.height > 0) {
chatInputContainer = elem;
console.log(` 📍 Using container ${i}`);
break;
}
}
// Click the container to ensure focus is on the input area
console.log(` 📍 Step: 点击输入区域...`);
await chatInputContainer.click();
await this.page.waitForTimeout(500);
console.log(` 📍 Step: 输入消息 "${message}"...`);
// Just type via keyboard - the input should be focused after clicking
await this.page.keyboard.type(message, { delay: 30 });
await this.page.waitForTimeout(300);
console.log(` 📍 Step: 发送消息 (按 Enter)...`);
await this.page.keyboard.press('Enter');
// Wait for the message to be sent and processed
await this.page.waitForTimeout(1000);
console.log(` ✅ 消息已发送`);
this.testContext.lastMessage = message;
});
// ============================================
// Then Steps
// ============================================
Then('用户应该收到助手的回复', async function (this: CustomWorld) {
// Wait for the assistant response to appear
// The response should be in a message bubble with role="assistant" or similar
const assistantMessage = this.page
.locator('[data-role="assistant"], [class*="assistant"], [class*="message"]')
.last();
await expect(assistantMessage).toBeVisible({ timeout: 15_000 });
});
Then('回复内容应该可见', async function (this: CustomWorld) {
// Verify the response content is not empty and contains expected text
const responseText = this.page
.locator('[data-role="assistant"], [class*="assistant"], [class*="message"]')
.last()
.locator('p, span, div')
.first();
await expect(responseText).toBeVisible({ timeout: 5000 });
// Get the text content and verify it's not empty
const text = await responseText.textContent();
expect(text).toBeTruthy();
expect(text!.length).toBeGreaterThan(0);
console.log(` ✅ Assistant replied: "${text?.slice(0, 50)}..."`);
});
+415
View File
@@ -0,0 +1,415 @@
/**
* Agent Message Operations Steps
*
* Step definitions for Agent message operations E2E tests
* - Copy message
* - Edit message
* - Delete message
* - Collapse/Expand message
*/
import { Then, When } from '@cucumber/cucumber';
import { expect } from '@playwright/test';
import { CustomWorld } from '../../support/world';
// ============================================
// When Steps
// ============================================
// Helper function to find the assistant message wrapper
async function findAssistantMessage(page: CustomWorld['page']) {
const messageWrappers = page.locator('.message-wrapper');
const wrapperCount = await messageWrappers.count();
console.log(` 📍 Found ${wrapperCount} message wrappers`);
// Find the assistant message by looking for the one with "Lobe AI" or "AI" in title
for (let i = wrapperCount - 1; i >= 0; i--) {
const wrapper = messageWrappers.nth(i);
const titleText = await wrapper
.locator('.message-header')
.textContent()
.catch(() => '');
if (titleText?.includes('Lobe AI') || titleText?.includes('AI')) {
console.log(` 📍 Found assistant message at index ${i}`);
return wrapper;
}
}
// Fallback: return the last message wrapper that's aligned left (assistant messages)
return messageWrappers.last();
}
When('用户点击消息的复制按钮', async function (this: CustomWorld) {
console.log(' 📍 Step: 点击复制按钮...');
// Find the assistant message wrapper
const assistantMessage = await findAssistantMessage(this.page);
// Hover to reveal action buttons
await assistantMessage.hover();
await this.page.waitForTimeout(800);
// First try: find copy button directly by its icon (lucide-copy)
const copyButtonByIcon = this.page.locator('svg.lucide-copy').locator('..');
let copyButtonCount = await copyButtonByIcon.count();
console.log(` 📍 Found ${copyButtonCount} buttons with copy icon`);
if (copyButtonCount > 0) {
// Click the visible copy button
for (let i = 0; i < copyButtonCount; i++) {
const btn = copyButtonByIcon.nth(i);
const box = await btn.boundingBox();
if (box && box.width > 0 && box.height > 0) {
await btn.click();
console.log(' ✅ 已点击复制按钮');
await this.page.waitForTimeout(500);
return;
}
}
}
// Fallback: Look for action bar within message and open more menu
console.log(' 📍 Fallback: Looking for copy in more menu...');
const actionBar = assistantMessage.locator('[role="menubar"]');
if ((await actionBar.count()) > 0) {
const moreButton = actionBar.locator('button').last();
await moreButton.click();
await this.page.waitForTimeout(300);
const copyMenuItem = this.page.getByRole('menuitem', { name: /复制/ });
if ((await copyMenuItem.count()) > 0) {
await copyMenuItem.click();
console.log(' ✅ 已从菜单中点击复制');
await this.page.waitForTimeout(500);
return;
}
}
// Last fallback: find more button by icon and open menu
const moreButtonByIcon = this.page.locator('svg.lucide-more-horizontal').locator('..');
if ((await moreButtonByIcon.count()) > 0) {
await moreButtonByIcon.first().click();
await this.page.waitForTimeout(300);
const copyMenuItem = this.page.getByRole('menuitem', { name: /复制/ });
await copyMenuItem.click();
console.log(' ✅ 已从更多菜单中点击复制');
}
await this.page.waitForTimeout(500);
});
When('用户点击助手消息的编辑按钮', async function (this: CustomWorld) {
console.log(' 📍 Step: 点击编辑按钮...');
// Find the assistant message wrapper
const assistantMessage = await findAssistantMessage(this.page);
// Hover to reveal action buttons
await assistantMessage.hover();
await this.page.waitForTimeout(800);
// First try: find edit button directly by its icon (lucide-pencil)
const editButtonByIcon = this.page.locator('svg.lucide-pencil').locator('..');
let editButtonCount = await editButtonByIcon.count();
console.log(` 📍 Found ${editButtonCount} buttons with pencil icon`);
if (editButtonCount > 0) {
for (let i = 0; i < editButtonCount; i++) {
const btn = editButtonByIcon.nth(i);
const box = await btn.boundingBox();
if (box && box.width > 0 && box.height > 0) {
await btn.click();
console.log(' ✅ 已点击编辑按钮');
await this.page.waitForTimeout(500);
return;
}
}
}
// Fallback: Look for edit in more menu
console.log(' 📍 Fallback: Looking for edit in more menu...');
const moreButtonByIcon = this.page.locator('svg.lucide-more-horizontal').locator('..');
if ((await moreButtonByIcon.count()) > 0) {
await moreButtonByIcon.first().click();
await this.page.waitForTimeout(300);
const editMenuItem = this.page.getByRole('menuitem', { name: /编辑/ });
if ((await editMenuItem.count()) > 0) {
await editMenuItem.click();
console.log(' ✅ 已从菜单中点击编辑');
}
}
await this.page.waitForTimeout(500);
});
When('用户修改消息内容为 {string}', async function (this: CustomWorld, newContent: string) {
console.log(` 📍 Step: 修改消息内容为 "${newContent}"...`);
// Find the editing textarea or input
const editArea = this.page.locator('textarea, [contenteditable="true"]').last();
await expect(editArea).toBeVisible({ timeout: 5000 });
// Clear and enter new content
await editArea.click();
await this.page.keyboard.press('Meta+a'); // Select all
await this.page.keyboard.type(newContent, { delay: 30 });
// Store for later verification
this.testContext.editedContent = newContent;
console.log(` ✅ 已修改消息内容为 "${newContent}"`);
});
When('用户保存编辑', async function (this: CustomWorld) {
console.log(' 📍 Step: 保存编辑...');
// Find and click the save/confirm button
const saveButton = this.page.locator('button').filter({
has: this.page.locator('svg.lucide-check'),
});
if ((await saveButton.count()) > 0) {
await saveButton.first().click();
} else {
// Fallback: press Enter or find confirm button
await this.page.keyboard.press('Enter');
}
console.log(' ✅ 已保存编辑');
await this.page.waitForTimeout(500);
});
When('用户点击消息的更多操作按钮', async function (this: CustomWorld) {
console.log(' 📍 Step: 点击更多操作按钮...');
// Find the assistant message wrapper
const assistantMessage = await findAssistantMessage(this.page);
// Hover to reveal action buttons
await assistantMessage.hover();
await this.page.waitForTimeout(800);
// Get the bounding box of the message to help filter buttons
const messageBox = await assistantMessage.boundingBox();
console.log(` 📍 Message bounding box: y=${messageBox?.y}, height=${messageBox?.height}`);
// Look for the "more" button by ellipsis icon (lucide-ellipsis or lucide-more-horizontal)
// The icon might be `...` which is lucide-ellipsis
const ellipsisButtons = this.page
.locator('svg.lucide-ellipsis, svg.lucide-more-horizontal')
.locator('..');
let ellipsisCount = await ellipsisButtons.count();
console.log(` 📍 Found ${ellipsisCount} buttons with ellipsis/more icon`);
if (ellipsisCount > 0 && messageBox) {
// Find buttons in the message area (x > 320 to exclude sidebar)
for (let i = 0; i < ellipsisCount; i++) {
const btn = ellipsisButtons.nth(i);
const box = await btn.boundingBox();
if (box && box.width > 0 && box.height > 0) {
console.log(` 📍 Ellipsis button ${i}: x=${box.x}, y=${box.y}`);
// Check if button is within the message area
if (
box.x > 320 &&
box.y >= messageBox.y - 50 &&
box.y <= messageBox.y + messageBox.height + 50
) {
await btn.click();
console.log(` ✅ 已点击更多操作按钮 (ellipsis at x=${box.x}, y=${box.y})`);
await this.page.waitForTimeout(300);
return;
}
}
}
}
// Second approach: Find the action bar and click its last button
const actionBar = assistantMessage.locator('[role="menubar"]');
const actionBarCount = await actionBar.count();
console.log(` 📍 Found ${actionBarCount} action bars in message`);
if (actionBarCount > 0) {
// Find all clickable elements (button, span with onClick, etc.)
const clickables = actionBar.locator('button, span[role="button"], [class*="action"]');
const clickableCount = await clickables.count();
console.log(` 📍 Found ${clickableCount} clickable elements in action bar`);
if (clickableCount > 0) {
// Click the last one (usually "more")
await clickables.last().click();
console.log(' ✅ 已点击更多操作按钮 (last clickable)');
await this.page.waitForTimeout(300);
return;
}
}
// Third approach: Find buttons by looking for all SVG icons in the message area
const allSvgButtons = this.page.locator('.message-wrapper svg').locator('..');
const svgButtonCount = await allSvgButtons.count();
console.log(` 📍 Found ${svgButtonCount} SVG button parents in message wrappers`);
if (svgButtonCount > 0 && messageBox) {
// Find the rightmost button in the action area (more button is usually last)
let rightmostBtn = null;
let maxX = 0;
for (let i = 0; i < svgButtonCount; i++) {
const btn = allSvgButtons.nth(i);
const box = await btn.boundingBox();
if (box && box.width > 0 && box.height > 0 && box.width < 50 && // Only consider small buttons (action icons are small)
box.x > 320 &&
box.y >= messageBox.y &&
box.y <= messageBox.y + messageBox.height + 50
&& box.x > maxX) {
maxX = box.x;
rightmostBtn = btn;
}
}
if (rightmostBtn) {
await rightmostBtn.click();
console.log(` ✅ 已点击更多操作按钮 (rightmost at x=${maxX})`);
await this.page.waitForTimeout(300);
return;
}
}
throw new Error('Could not find more button in message action bar');
});
When('用户选择删除消息选项', async function (this: CustomWorld) {
console.log(' 📍 Step: 选择删除消息选项...');
// Find and click delete option (exact match to avoid "删除并重新生成")
const deleteOption = this.page.getByRole('menuitem', { exact: true, name: '删除' });
await expect(deleteOption).toBeVisible({ timeout: 5000 });
await deleteOption.click();
console.log(' ✅ 已选择删除消息选项');
await this.page.waitForTimeout(300);
});
When('用户确认删除消息', async function (this: CustomWorld) {
console.log(' 📍 Step: 确认删除消息...');
// A confirmation popconfirm might appear
const confirmButton = this.page.locator('.ant-popconfirm-buttons button.ant-btn-dangerous');
if ((await confirmButton.count()) > 0) {
await confirmButton.click();
console.log(' ✅ 已确认删除消息');
} else {
// If no popconfirm, deletion might be immediate
console.log(' ✅ 删除操作已执行(无需确认)');
}
await this.page.waitForTimeout(500);
});
When('用户选择折叠消息选项', async function (this: CustomWorld) {
console.log(' 📍 Step: 选择折叠消息选项...');
// The collapse option is "收起消息" in the menu
const collapseOption = this.page.getByRole('menuitem', { name: /收起消息/ });
await expect(collapseOption).toBeVisible({ timeout: 5000 });
await collapseOption.click();
console.log(' ✅ 已选择折叠消息选项');
await this.page.waitForTimeout(500);
});
When('用户选择展开消息选项', async function (this: CustomWorld) {
console.log(' 📍 Step: 选择展开消息选项...');
// The expand option is "展开消息" in the menu
const expandOption = this.page.getByRole('menuitem', { name: /展开消息/ });
await expect(expandOption).toBeVisible({ timeout: 5000 });
await expandOption.click();
console.log(' ✅ 已选择展开消息选项');
await this.page.waitForTimeout(500);
});
// ============================================
// Then Steps
// ============================================
Then('消息内容应该被复制到剪贴板', async function (this: CustomWorld) {
console.log(' 📍 Step: 验证消息已复制到剪贴板...');
// Check for success message/toast
const successMessage = this.page.locator('.ant-message-success, [class*="toast"]');
// Wait briefly for any success notification
await this.page.waitForTimeout(1000);
// Verify by checking if clipboard has content (or success message appeared)
const successCount = await successMessage.count();
if (successCount > 0) {
console.log(' ✅ 显示复制成功提示');
} else {
// Just verify the action completed without error
console.log(' ✅ 复制操作已完成');
}
});
Then('消息内容应该更新为 {string}', async function (this: CustomWorld, expectedContent: string) {
console.log(` 📍 Step: 验证消息内容为 "${expectedContent}"...`);
await this.page.waitForTimeout(1000);
// Find the updated message content
const messageContent = this.page.getByText(expectedContent);
await expect(messageContent).toBeVisible({ timeout: 5000 });
console.log(` ✅ 消息内容已更新为 "${expectedContent}"`);
});
Then('该消息应该从对话中移除', async function (this: CustomWorld) {
console.log(' 📍 Step: 验证消息已移除...');
await this.page.waitForTimeout(500);
// The assistant message count should be reduced
// Or verify the specific message content is gone
const assistantMessages = this.page.locator('[data-role="assistant"]');
const count = await assistantMessages.count();
console.log(` 📍 剩余助手消息数量: ${count}`);
console.log(' ✅ 消息已移除');
});
Then('消息内容应该被折叠', async function (this: CustomWorld) {
console.log(' 📍 Step: 验证消息已折叠...');
await this.page.waitForTimeout(500);
// Look for collapsed indicator or truncated content
const collapsedIndicator = this.page.locator(
'[class*="collapsed"], [class*="truncate"], svg.lucide-chevron-down',
);
const hasCollapsed = (await collapsedIndicator.count()) > 0;
if (hasCollapsed) {
console.log(' ✅ 消息已折叠');
} else {
// Alternative verification: content height should be reduced
console.log(' ✅ 消息折叠操作已执行');
}
});
Then('消息内容应该完整显示', async function (this: CustomWorld) {
console.log(' 📍 Step: 验证消息完整显示...');
await this.page.waitForTimeout(500);
// The message content should be fully visible
const assistantMessage = await findAssistantMessage(this.page);
await expect(assistantMessage).toBeVisible();
console.log(' ✅ 消息内容完整显示');
});
+100
View File
@@ -0,0 +1,100 @@
import { Given, When } from '@cucumber/cucumber';
import { expect } from '@playwright/test';
import { TEST_USER, createTestSession } from '../../support/seedTestUser';
import { CustomWorld } from '../../support/world';
/**
* Login via UI - fills in the login form and submits
*/
Given('I am logged in as the test user', async function (this: CustomWorld) {
// Navigate to signin page
await this.page.goto('/signin');
// Wait for the login form to be visible
await this.page.waitForSelector('input[type="email"], input[name="email"]', { timeout: 30_000 });
// Fill in email
await this.page.fill('input[type="email"], input[name="email"]', TEST_USER.email);
// Fill in password
await this.page.fill('input[type="password"], input[name="password"]', TEST_USER.password);
// Click submit button
await this.page.click('button[type="submit"]');
// Wait for navigation away from signin page
await this.page.waitForURL((url) => !url.pathname.includes('/signin'), { timeout: 30_000 });
console.log('✅ Logged in as test user via UI');
});
/**
* Login via session injection - faster, bypasses UI
* Creates a session directly in the database and sets the cookie
*/
Given('I am logged in with a session', async function (this: CustomWorld) {
const sessionToken = await createTestSession();
if (!sessionToken) {
throw new Error('Failed to create test session');
}
// Set the session cookie (Better Auth uses 'better-auth.session_token' by default)
await this.browserContext.addCookies([
{
domain: 'localhost',
httpOnly: true,
name: 'better-auth.session_token',
path: '/',
sameSite: 'Lax',
secure: false,
value: sessionToken,
},
]);
console.log('✅ Session cookie set for test user');
});
/**
* Navigate to signin page
*/
When('I navigate to the signin page', async function (this: CustomWorld) {
await this.page.goto('/signin');
await this.page.waitForLoadState('networkidle');
});
/**
* Fill in login credentials
*/
When('I enter the test user credentials', async function (this: CustomWorld) {
await this.page.fill('input[type="email"], input[name="email"]', TEST_USER.email);
await this.page.fill('input[type="password"], input[name="password"]', TEST_USER.password);
});
/**
* Submit the login form
*/
When('I submit the login form', async function (this: CustomWorld) {
await this.page.click('button[type="submit"]');
});
/**
* Verify login was successful
*/
Given('I should be logged in', async function (this: CustomWorld) {
// Check we're not on signin page anymore
await expect(this.page).not.toHaveURL(/\/signin/);
// Optionally check for user menu or other logged-in indicators
console.log('✅ User is logged in');
});
/**
* Logout the current user
*/
When('I logout', async function (this: CustomWorld) {
// Clear cookies to logout
await this.browserContext.clearCookies();
console.log('✅ User logged out (cookies cleared)');
});
+37 -36
View File
@@ -8,7 +8,7 @@ import { CustomWorld } from '../../support/world';
// ============================================
Given('I wait for the page to fully load', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
await this.page.waitForTimeout(1000);
});
@@ -17,7 +17,7 @@ Given('I wait for the page to fully load', async function (this: CustomWorld) {
// ============================================
When('I click the back button', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Try to find a back button
const backButton = this.page
@@ -34,7 +34,7 @@ When('I click the back button', async function (this: CustomWorld) {
await this.page.goBack();
}
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
});
// ============================================
@@ -43,7 +43,7 @@ When('I click the back button', async function (this: CustomWorld) {
// Assistant Detail Page Assertions
Then('I should be on an assistant detail page', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const currentUrl = this.page.url();
// Check if URL matches assistant detail page pattern
@@ -55,13 +55,13 @@ Then('I should be on an assistant detail page', async function (this: CustomWorl
});
Then('I should see the assistant title', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Look for title element (h1, h2, or prominent text)
const title = this.page
.locator('h1, h2, [data-testid="detail-title"], [data-testid="assistant-title"]')
.first();
await expect(title).toBeVisible({ timeout: 120_000 });
await expect(title).toBeVisible({ timeout: 30_000 });
// Verify title has content
const titleText = await title.textContent();
@@ -69,7 +69,7 @@ Then('I should see the assistant title', async function (this: CustomWorld) {
});
Then('I should see the assistant description', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Look for description element
const description = this.page
@@ -77,11 +77,11 @@ Then('I should see the assistant description', async function (this: CustomWorld
'p, [data-testid="detail-description"], [data-testid="assistant-description"], .description',
)
.first();
await expect(description).toBeVisible({ timeout: 120_000 });
await expect(description).toBeVisible({ timeout: 30_000 });
});
Then('I should see the assistant author information', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Look for author information
const author = this.page
@@ -95,7 +95,7 @@ Then('I should see the assistant author information', async function (this: Cust
});
Then('I should see the add to workspace button', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Look for add button (might be "Add", "Install", "Add to Workspace", etc.)
const addButton = this.page
@@ -110,18 +110,19 @@ Then('I should see the add to workspace button', async function (this: CustomWor
});
Then('I should be on the assistant list page', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const currentUrl = this.page.url();
// Check if URL is assistant list (not detail page)
const isListPage =
currentUrl.includes('/discover/assistant') && !/\/discover\/assistant\/[^#?]+/.test(currentUrl);
currentUrl.includes('/community/assistant') &&
!/\/discover\/assistant\/[^#?]+/.test(currentUrl);
expect(isListPage, `Expected URL to be assistant list page, but got: ${currentUrl}`).toBeTruthy();
});
// Model Detail Page Assertions
Then('I should be on a model detail page', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const currentUrl = this.page.url();
// Check if URL matches model detail page pattern
@@ -133,30 +134,30 @@ Then('I should be on a model detail page', async function (this: CustomWorld) {
});
Then('I should see the model title', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const title = this.page
.locator('h1, h2, [data-testid="detail-title"], [data-testid="model-title"]')
.first();
await expect(title).toBeVisible({ timeout: 120_000 });
await expect(title).toBeVisible({ timeout: 30_000 });
const titleText = await title.textContent();
expect(titleText?.trim().length).toBeGreaterThan(0);
});
Then('I should see the model description', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const description = this.page
.locator(
'p, [data-testid="detail-description"], [data-testid="model-description"], .description',
)
.first();
await expect(description).toBeVisible({ timeout: 120_000 });
await expect(description).toBeVisible({ timeout: 30_000 });
});
Then('I should see the model parameters information', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Look for parameters or specs section
const params = this.page
@@ -169,18 +170,18 @@ Then('I should see the model parameters information', async function (this: Cust
});
Then('I should be on the model list page', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const currentUrl = this.page.url();
// Check if URL is model list (not detail page)
const isListPage =
currentUrl.includes('/discover/model') && !/\/discover\/model\/[^#?]+/.test(currentUrl);
currentUrl.includes('/community/model') && !/\/discover\/model\/[^#?]+/.test(currentUrl);
expect(isListPage, `Expected URL to be model list page, but got: ${currentUrl}`).toBeTruthy();
});
// Provider Detail Page Assertions
Then('I should be on a provider detail page', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const currentUrl = this.page.url();
// Check if URL matches provider detail page pattern
@@ -192,30 +193,30 @@ Then('I should be on a provider detail page', async function (this: CustomWorld)
});
Then('I should see the provider title', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const title = this.page
.locator('h1, h2, [data-testid="detail-title"], [data-testid="provider-title"]')
.first();
await expect(title).toBeVisible({ timeout: 120_000 });
await expect(title).toBeVisible({ timeout: 30_000 });
const titleText = await title.textContent();
expect(titleText?.trim().length).toBeGreaterThan(0);
});
Then('I should see the provider description', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const description = this.page
.locator(
'p, [data-testid="detail-description"], [data-testid="provider-description"], .description',
)
.first();
await expect(description).toBeVisible({ timeout: 120_000 });
await expect(description).toBeVisible({ timeout: 30_000 });
});
Then('I should see the provider website link', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Look for website link
const websiteLink = this.page
@@ -228,18 +229,18 @@ Then('I should see the provider website link', async function (this: CustomWorld
});
Then('I should be on the provider list page', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const currentUrl = this.page.url();
// Check if URL is provider list (not detail page)
const isListPage =
currentUrl.includes('/discover/provider') && !/\/discover\/provider\/[^#?]+/.test(currentUrl);
currentUrl.includes('/community/provider') && !/\/discover\/provider\/[^#?]+/.test(currentUrl);
expect(isListPage, `Expected URL to be provider list page, but got: ${currentUrl}`).toBeTruthy();
});
// MCP Detail Page Assertions
Then('I should be on an MCP detail page', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const currentUrl = this.page.url();
// Check if URL matches MCP detail page pattern
@@ -251,28 +252,28 @@ Then('I should be on an MCP detail page', async function (this: CustomWorld) {
});
Then('I should see the MCP title', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const title = this.page
.locator('h1, h2, [data-testid="detail-title"], [data-testid="mcp-title"]')
.first();
await expect(title).toBeVisible({ timeout: 120_000 });
await expect(title).toBeVisible({ timeout: 30_000 });
const titleText = await title.textContent();
expect(titleText?.trim().length).toBeGreaterThan(0);
});
Then('I should see the MCP description', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const description = this.page
.locator('p, [data-testid="detail-description"], [data-testid="mcp-description"], .description')
.first();
await expect(description).toBeVisible({ timeout: 120_000 });
await expect(description).toBeVisible({ timeout: 30_000 });
});
Then('I should see the install button', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Look for install button
const installButton = this.page
@@ -285,11 +286,11 @@ Then('I should see the install button', async function (this: CustomWorld) {
});
Then('I should be on the MCP list page', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const currentUrl = this.page.url();
// Check if URL is MCP list (not detail page)
const isListPage =
currentUrl.includes('/discover/mcp') && !/\/discover\/mcp\/[^#?]+/.test(currentUrl);
currentUrl.includes('/community/mcp') && !/\/discover\/mcp\/[^#?]+/.test(currentUrl);
expect(isListPage, `Expected URL to be MCP list page, but got: ${currentUrl}`).toBeTruthy();
});
+57 -57
View File
@@ -8,10 +8,10 @@ import { CustomWorld } from '../../support/world';
// ============================================
When('I type {string} in the search bar', async function (this: CustomWorld, searchText: string) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const searchBar = this.page.locator('input[type="text"]').first();
await searchBar.waitFor({ state: 'visible', timeout: 120_000 });
await searchBar.waitFor({ state: 'visible', timeout: 30_000 });
await searchBar.fill(searchText);
// Store the search text for later assertions
@@ -20,13 +20,13 @@ When('I type {string} in the search bar', async function (this: CustomWorld, sea
When('I wait for the search results to load', async function (this: CustomWorld) {
// Wait for network to be idle after typing
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Add a small delay to ensure UI updates
await this.page.waitForTimeout(500);
});
When('I click on a category in the category menu', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Find the category menu and click the first non-active category
const categoryItems = this.page.locator(
@@ -34,7 +34,7 @@ When('I click on a category in the category menu', async function (this: CustomW
);
// Wait for categories to be visible
await categoryItems.first().waitFor({ state: 'visible', timeout: 120_000 });
await categoryItems.first().waitFor({ state: 'visible', timeout: 30_000 });
// Click the second category (skip "All" which is usually first)
const secondCategory = categoryItems.nth(1);
@@ -46,7 +46,7 @@ When('I click on a category in the category menu', async function (this: CustomW
});
When('I click on a category in the category filter', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Find the category filter and click a category
const categoryItems = this.page.locator(
@@ -54,7 +54,7 @@ When('I click on a category in the category filter', async function (this: Custo
);
// Wait for categories to be visible
await categoryItems.first().waitFor({ state: 'visible', timeout: 120_000 });
await categoryItems.first().waitFor({ state: 'visible', timeout: 30_000 });
// Click the second category (skip "All" which is usually first)
const secondCategory = categoryItems.nth(1);
@@ -67,35 +67,35 @@ When('I click on a category in the category filter', async function (this: Custo
When('I wait for the filtered results to load', async function (this: CustomWorld) {
// Wait for network to be idle after filtering
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Add a small delay to ensure UI updates
await this.page.waitForTimeout(500);
});
When('I click the next page button', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Find and click the next page button
const nextButton = this.page.locator(
'button:has-text("Next"), button[aria-label*="next" i], .pagination button:last-child',
);
await nextButton.waitFor({ state: 'visible', timeout: 120_000 });
await nextButton.waitFor({ state: 'visible', timeout: 30_000 });
await nextButton.click();
});
When('I wait for the next page to load', async function (this: CustomWorld) {
// Wait for network to be idle after page change
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Add a small delay to ensure UI updates
await this.page.waitForTimeout(500);
});
When('I click on the first assistant card', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const firstCard = this.page.locator('[data-testid="assistant-item"]').first();
await firstCard.waitFor({ state: 'visible', timeout: 120_000 });
await firstCard.waitFor({ state: 'visible', timeout: 30_000 });
// Store the current URL before clicking
this.testContext.previousUrl = this.page.url();
@@ -106,15 +106,15 @@ When('I click on the first assistant card', async function (this: CustomWorld) {
await this.page.waitForFunction(
(previousUrl) => window.location.href !== previousUrl,
this.testContext.previousUrl,
{ timeout: 120_000 },
{ timeout: 30_000 },
);
});
When('I click on the first model card', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const firstCard = this.page.locator('[data-testid="model-item"]').first();
await firstCard.waitFor({ state: 'visible', timeout: 120_000 });
await firstCard.waitFor({ state: 'visible', timeout: 30_000 });
// Store the current URL before clicking
this.testContext.previousUrl = this.page.url();
@@ -125,15 +125,15 @@ When('I click on the first model card', async function (this: CustomWorld) {
await this.page.waitForFunction(
(previousUrl) => window.location.href !== previousUrl,
this.testContext.previousUrl,
{ timeout: 120_000 },
{ timeout: 30_000 },
);
});
When('I click on the first provider card', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const firstCard = this.page.locator('[data-testid="provider-item"]').first();
await firstCard.waitFor({ state: 'visible', timeout: 120_000 });
await firstCard.waitFor({ state: 'visible', timeout: 30_000 });
// Store the current URL before clicking
this.testContext.previousUrl = this.page.url();
@@ -144,15 +144,15 @@ When('I click on the first provider card', async function (this: CustomWorld) {
await this.page.waitForFunction(
(previousUrl) => window.location.href !== previousUrl,
this.testContext.previousUrl,
{ timeout: 120_000 },
{ timeout: 30_000 },
);
});
When('I click on the first MCP card', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const firstCard = this.page.locator('[data-testid="mcp-item"]').first();
await firstCard.waitFor({ state: 'visible', timeout: 120_000 });
await firstCard.waitFor({ state: 'visible', timeout: 30_000 });
// Store the current URL before clicking
this.testContext.previousUrl = this.page.url();
@@ -163,12 +163,12 @@ When('I click on the first MCP card', async function (this: CustomWorld) {
await this.page.waitForFunction(
(previousUrl) => window.location.href !== previousUrl,
this.testContext.previousUrl,
{ timeout: 120_000 },
{ timeout: 30_000 },
);
});
When('I click on the sort dropdown', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const sortDropdown = this.page
.locator(
@@ -176,7 +176,7 @@ When('I click on the sort dropdown', async function (this: CustomWorld) {
)
.first();
await sortDropdown.waitFor({ state: 'visible', timeout: 120_000 });
await sortDropdown.waitFor({ state: 'visible', timeout: 30_000 });
await sortDropdown.click();
});
@@ -187,7 +187,7 @@ When('I select a sort option', async function (this: CustomWorld) {
const sortOptions = this.page.locator('[role="option"], [role="menuitem"]');
// Wait for options to appear
await sortOptions.first().waitFor({ state: 'visible', timeout: 120_000 });
await sortOptions.first().waitFor({ state: 'visible', timeout: 30_000 });
// Click the second option (skip the default/first one)
const secondOption = sortOptions.nth(1);
@@ -200,7 +200,7 @@ When('I select a sort option', async function (this: CustomWorld) {
When('I wait for the sorted results to load', async function (this: CustomWorld) {
// Wait for network to be idle after sorting
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Add a small delay to ensure UI updates
await this.page.waitForTimeout(500);
});
@@ -208,14 +208,14 @@ When('I wait for the sorted results to load', async function (this: CustomWorld)
When(
'I click on the {string} link in the featured assistants section',
async function (this: CustomWorld, linkText: string) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Find the featured assistants section and the "more" link
const moreLink = this.page
.locator(`a:has-text("${linkText}"), button:has-text("${linkText}")`)
.first();
await moreLink.waitFor({ state: 'visible', timeout: 120_000 });
await moreLink.waitFor({ state: 'visible', timeout: 30_000 });
await moreLink.click();
},
);
@@ -223,7 +223,7 @@ When(
When(
'I click on the {string} link in the featured MCP tools section',
async function (this: CustomWorld, linkText: string) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Find the MCP section and the "more" link
// Since there might be multiple "more" links, we'll click the second one (MCP is after assistants)
@@ -232,7 +232,7 @@ When(
);
// Wait for links to be visible
await moreLinks.first().waitFor({ state: 'visible', timeout: 120_000 });
await moreLinks.first().waitFor({ state: 'visible', timeout: 30_000 });
// Click the second "more" link (for MCP section)
await moreLinks.nth(1).click();
@@ -240,10 +240,10 @@ When(
);
When('I click on the first featured assistant card', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const firstCard = this.page.locator('[data-testid="assistant-item"]').first();
await firstCard.waitFor({ state: 'visible', timeout: 120_000 });
await firstCard.waitFor({ state: 'visible', timeout: 30_000 });
// Store the current URL before clicking
this.testContext.previousUrl = this.page.url();
@@ -254,7 +254,7 @@ When('I click on the first featured assistant card', async function (this: Custo
await this.page.waitForFunction(
(previousUrl) => window.location.href !== previousUrl,
this.testContext.previousUrl,
{ timeout: 120_000 },
{ timeout: 30_000 },
);
});
@@ -263,12 +263,12 @@ When('I click on the first featured assistant card', async function (this: Custo
// ============================================
Then('I should see filtered assistant cards', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const assistantItems = this.page.locator('[data-testid="assistant-item"]');
// Wait for at least one item to be visible
await expect(assistantItems.first()).toBeVisible({ timeout: 120_000 });
await expect(assistantItems.first()).toBeVisible({ timeout: 30_000 });
// Verify that at least one item exists
const count = await assistantItems.count();
@@ -278,12 +278,12 @@ Then('I should see filtered assistant cards', async function (this: CustomWorld)
Then(
'I should see assistant cards filtered by the selected category',
async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const assistantItems = this.page.locator('[data-testid="assistant-item"]');
// Wait for at least one item to be visible
await expect(assistantItems.first()).toBeVisible({ timeout: 120_000 });
await expect(assistantItems.first()).toBeVisible({ timeout: 30_000 });
// Verify that at least one item exists
const count = await assistantItems.count();
@@ -301,12 +301,12 @@ Then('the URL should contain the category parameter', async function (this: Cust
});
Then('I should see different assistant cards', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const assistantItems = this.page.locator('[data-testid="assistant-item"]');
// Wait for at least one item to be visible
await expect(assistantItems.first()).toBeVisible({ timeout: 120_000 });
await expect(assistantItems.first()).toBeVisible({ timeout: 30_000 });
// Verify that at least one item exists
const count = await assistantItems.count();
@@ -323,7 +323,7 @@ Then('the URL should contain the page parameter', async function (this: CustomWo
});
Then('I should be navigated to the assistant detail page', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const currentUrl = this.page.url();
// Verify that URL changed and contains /assistant/ followed by an identifier
@@ -337,20 +337,20 @@ Then('I should be navigated to the assistant detail page', async function (this:
});
Then('I should see the assistant detail content', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Look for detail page elements (e.g., title, description, etc.)
const detailContent = this.page.locator('[data-testid="detail-content"], main, article').first();
await expect(detailContent).toBeVisible({ timeout: 120_000 });
await expect(detailContent).toBeVisible({ timeout: 30_000 });
});
Then('I should see model cards in the sorted order', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const modelItems = this.page.locator('[data-testid="model-item"]');
// Wait for at least one item to be visible
await expect(modelItems.first()).toBeVisible({ timeout: 120_000 });
await expect(modelItems.first()).toBeVisible({ timeout: 30_000 });
// Verify that at least one item exists
const count = await modelItems.count();
@@ -358,7 +358,7 @@ Then('I should see model cards in the sorted order', async function (this: Custo
});
Then('I should be navigated to the model detail page', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const currentUrl = this.page.url();
// Verify that URL changed and contains /model/ followed by an identifier
@@ -372,15 +372,15 @@ Then('I should be navigated to the model detail page', async function (this: Cus
});
Then('I should see the model detail content', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Look for detail page elements
const detailContent = this.page.locator('[data-testid="detail-content"], main, article').first();
await expect(detailContent).toBeVisible({ timeout: 120_000 });
await expect(detailContent).toBeVisible({ timeout: 30_000 });
});
Then('I should be navigated to the provider detail page', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const currentUrl = this.page.url();
// Verify that URL changed and contains /provider/ followed by an identifier
@@ -394,22 +394,22 @@ Then('I should be navigated to the provider detail page', async function (this:
});
Then('I should see the provider detail content', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Look for detail page elements
const detailContent = this.page.locator('[data-testid="detail-content"], main, article').first();
await expect(detailContent).toBeVisible({ timeout: 120_000 });
await expect(detailContent).toBeVisible({ timeout: 30_000 });
});
Then(
'I should see MCP cards filtered by the selected category',
async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const mcpItems = this.page.locator('[data-testid="mcp-item"]');
// Wait for at least one item to be visible
await expect(mcpItems.first()).toBeVisible({ timeout: 120_000 });
await expect(mcpItems.first()).toBeVisible({ timeout: 30_000 });
// Verify that at least one item exists
const count = await mcpItems.count();
@@ -418,7 +418,7 @@ Then(
);
Then('I should be navigated to the MCP detail page', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const currentUrl = this.page.url();
// Verify that URL changed and contains /mcp/ followed by an identifier
@@ -432,15 +432,15 @@ Then('I should be navigated to the MCP detail page', async function (this: Custo
});
Then('I should see the MCP detail content', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
// Look for detail page elements
const detailContent = this.page.locator('[data-testid="detail-content"], main, article').first();
await expect(detailContent).toBeVisible({ timeout: 120_000 });
await expect(detailContent).toBeVisible({ timeout: 30_000 });
});
Then('I should be navigated to {string}', async function (this: CustomWorld, expectedPath: string) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
const currentUrl = this.page.url();
// Verify that URL contains the expected path
+28 -67
View File
@@ -9,55 +9,40 @@ import { CustomWorld } from '../../support/world';
// Home Page Steps
Then('I should see the featured assistants section', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
// Look for featured assistants section by data-testid or heading
// Look for "Featured Agents" heading text (i18n key: home.featuredAssistants)
// Supports: en-US "Featured Agents", zh-CN "推荐助理"
const featuredSection = this.page
.locator(
'[data-testid="featured-assistants"], h2:has-text("Featured"), h3:has-text("Featured")',
)
.getByRole('heading', { name: /featured agents|推荐助理/i })
.first();
await expect(featuredSection).toBeVisible({ timeout: 120_000 });
await expect(featuredSection).toBeVisible({ timeout: 30_000 });
});
Then('I should see the featured MCP tools section', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
// Look for featured MCP section by data-testid or heading
const mcpSection = this.page
.locator('[data-testid="featured-mcp"], h2:has-text("MCP"), h3:has-text("MCP")')
.first();
await expect(mcpSection).toBeVisible({ timeout: 120_000 });
// Look for "Featured Skills" heading text (i18n key: home.featuredTools)
// Supports: en-US "Featured Skills", zh-CN "推荐技能"
const mcpSection = this.page.getByRole('heading', { name: /featured skills|推荐技能/i }).first();
await expect(mcpSection).toBeVisible({ timeout: 30_000 });
});
// Assistant List Page Steps
Then('I should see the search bar', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
// The SearchBar component from @lobehub/ui may not pass through data-testid
// Try to find the input element within the search component
const searchBar = this.page.locator('input[type="text"]').first();
await expect(searchBar).toBeVisible({ timeout: 120_000 });
// SearchBar component has data-testid="search-bar"
const searchBar = this.page.locator('[data-testid="search-bar"]').first();
await expect(searchBar).toBeVisible({ timeout: 30_000 });
});
Then('I should see the category menu', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
// Look for category menu/filter by data-testid or role
const categoryMenu = this.page
.locator('[data-testid="category-menu"], [role="menu"], nav[aria-label*="categor" i]')
.first();
await expect(categoryMenu).toBeVisible({ timeout: 120_000 });
// CategoryMenu component has data-testid="category-menu"
const categoryMenu = this.page.locator('[data-testid="category-menu"]').first();
await expect(categoryMenu).toBeVisible({ timeout: 30_000 });
});
Then('I should see assistant cards', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
// Look for assistant items by data-testid
const assistantItems = this.page.locator('[data-testid="assistant-item"]');
// Wait for at least one item to be visible
await expect(assistantItems.first()).toBeVisible({ timeout: 120_000 });
await expect(assistantItems.first()).toBeVisible({ timeout: 30_000 });
// Check we have multiple items
const count = await assistantItems.count();
@@ -65,26 +50,18 @@ Then('I should see assistant cards', async function (this: CustomWorld) {
});
Then('I should see pagination controls', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
// Look for pagination controls by data-testid, role, or common pagination elements
const pagination = this.page
.locator(
'[data-testid="pagination"], nav[aria-label*="pagination" i], .pagination, button:has-text("Next"), button:has-text("Previous")',
)
.first();
await expect(pagination).toBeVisible({ timeout: 120_000 });
// Pagination component has data-testid="pagination"
const pagination = this.page.locator('[data-testid="pagination"]').first();
await expect(pagination).toBeVisible({ timeout: 30_000 });
});
// Model List Page Steps
Then('I should see model cards', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
// Look for model items by data-testid
// Model items have data-testid="model-item"
const modelItems = this.page.locator('[data-testid="model-item"]');
// Wait for at least one item to be visible
await expect(modelItems.first()).toBeVisible({ timeout: 120_000 });
await expect(modelItems.first()).toBeVisible({ timeout: 30_000 });
// Check we have multiple items
const count = await modelItems.count();
@@ -92,26 +69,18 @@ Then('I should see model cards', async function (this: CustomWorld) {
});
Then('I should see the sort dropdown', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
// Look for sort dropdown by data-testid, role, or select element
const sortDropdown = this.page
.locator(
'[data-testid="sort-dropdown"], select, button[aria-label*="sort" i], [role="combobox"]',
)
.first();
await expect(sortDropdown).toBeVisible({ timeout: 120_000 });
// SortButton has data-testid="sort-dropdown"
const sortDropdown = this.page.locator('[data-testid="sort-dropdown"]').first();
await expect(sortDropdown).toBeVisible({ timeout: 30_000 });
});
// Provider List Page Steps
Then('I should see provider cards', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
// Look for provider items by data-testid
const providerItems = this.page.locator('[data-testid="provider-item"]');
// Wait for at least one item to be visible
await expect(providerItems.first()).toBeVisible({ timeout: 120_000 });
await expect(providerItems.first()).toBeVisible({ timeout: 30_000 });
// Check we have multiple items
const count = await providerItems.count();
@@ -120,13 +89,11 @@ Then('I should see provider cards', async function (this: CustomWorld) {
// MCP List Page Steps
Then('I should see MCP cards', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
// Look for MCP items by data-testid
const mcpItems = this.page.locator('[data-testid="mcp-item"]');
// Wait for at least one item to be visible
await expect(mcpItems.first()).toBeVisible({ timeout: 120_000 });
await expect(mcpItems.first()).toBeVisible({ timeout: 30_000 });
// Check we have multiple items
const count = await mcpItems.count();
@@ -134,13 +101,7 @@ Then('I should see MCP cards', async function (this: CustomWorld) {
});
Then('I should see the category filter', async function (this: CustomWorld) {
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
// Look for category filter by data-testid or similar to category menu
const categoryFilter = this.page
.locator(
'[data-testid="category-filter"], [data-testid="category-menu"], [role="menu"], nav[aria-label*="categor" i]',
)
.first();
await expect(categoryFilter).toBeVisible({ timeout: 120_000 });
// CategoryMenu component has data-testid="category-menu" (shared across list pages)
const categoryFilter = this.page.locator('[data-testid="category-menu"]').first();
await expect(categoryFilter).toBeVisible({ timeout: 30_000 });
});
+68 -7
View File
@@ -1,28 +1,80 @@
import { After, AfterAll, Before, BeforeAll, Status, setDefaultTimeout } from '@cucumber/cucumber';
import { type Cookie, chromium } from 'playwright';
import { TEST_USER, seedTestUser } from '../support/seedTestUser';
import { startWebServer, stopWebServer } from '../support/webServer';
import { CustomWorld } from '../support/world';
process.env['E2E'] = '1';
// Set default timeout for all steps to 120 seconds
setDefaultTimeout(120_000);
// Set default timeout for all steps to 10 seconds
setDefaultTimeout(10_000);
BeforeAll({ timeout: 120_000 }, async function () {
// Store base URL and cached session cookies
let baseUrl: string;
let sessionCookies: Cookie[] = [];
BeforeAll({ timeout: 600_000 }, async function () {
console.log('🚀 Starting E2E test suite...');
const PORT = process.env.PORT ? Number(process.env.PORT) : 3010;
const BASE_URL = process.env.BASE_URL || `http://localhost:${PORT}`;
const PORT = process.env.PORT ? Number(process.env.PORT) : 3006;
baseUrl = process.env.BASE_URL || `http://localhost:${PORT}`;
console.log(`Base URL: ${BASE_URL}`);
console.log(`Base URL: ${baseUrl}`);
// Seed test user before starting web server
await seedTestUser();
// Start web server if not using external BASE_URL
if (!process.env.BASE_URL) {
await startWebServer({
command: 'npm run dev',
command: `bunx next start -p ${PORT}`,
port: PORT,
reuseExistingServer: !process.env.CI,
timeout: 60_000,
});
}
// Login once and cache the session cookies
console.log('🔐 Performing one-time login to cache session...');
const browser = await chromium.launch({ headless: process.env.HEADLESS !== 'false' });
const context = await browser.newContext();
const page = await context.newPage();
try {
// Navigate to signin page
await page.goto(`${baseUrl}/signin`, { waitUntil: 'networkidle' });
// Step 1: Enter email
console.log(' Step 1: Entering email...');
const emailInput = page.locator('input[id="email"]').first();
await emailInput.waitFor({ state: 'visible', timeout: 30_000 });
await emailInput.fill(TEST_USER.email);
// Click the next button
const nextButton = page.locator('form button').first();
await nextButton.click();
// Step 2: Wait for password step and enter password
console.log(' Step 2: Entering password...');
const passwordInput = page.locator('input[id="password"]').first();
await passwordInput.waitFor({ state: 'visible', timeout: 30_000 });
await passwordInput.fill(TEST_USER.password);
// Click submit button
const submitButton = page.locator('form button').first();
await submitButton.click();
// Wait for navigation away from signin page
await page.waitForURL((url) => !url.pathname.includes('/signin'), { timeout: 30_000 });
await page.waitForLoadState('networkidle');
// Cache the session cookies
sessionCookies = await context.cookies();
console.log(`✅ Login successful, cached ${sessionCookies.length} cookies`);
} finally {
await browser.close();
}
});
Before(async function (this: CustomWorld, { pickle }) {
@@ -30,6 +82,15 @@ Before(async function (this: CustomWorld, { pickle }) {
const testId = pickle.tags.find((tag) => tag.name.startsWith('@DISCOVER-'));
console.log(`\n📝 Running: ${pickle.name}${testId ? ` (${testId.name.replace('@', '')})` : ''}`);
// Setup API mocks before any page navigation
// await mockManager.setup(this.page);
// Set cached session cookies to skip login
if (sessionCookies.length > 0) {
await this.browserContext.addCookies(sessionCookies);
console.log('🍪 Session cookies restored');
}
});
After(async function (this: CustomWorld, { pickle, result }) {
+126
View File
@@ -0,0 +1,126 @@
import bcrypt from 'bcryptjs';
// Test user credentials - these are used for e2e testing only
export const TEST_USER = {
email: 'e2e-test@lobehub.com',
fullName: 'E2E Test User',
id: 'user_e2e_test_user_001',
password: 'TestPassword123!',
username: 'e2e_test_user',
};
/**
* Create a bcrypt password hash
* Better Auth supports bcrypt for passwords migrated from Clerk
*/
async function hashPassword(password: string): Promise<string> {
return bcrypt.hash(password, 10);
}
/**
* Seed test user into the database for e2e testing
* This function connects directly to PostgreSQL and creates the necessary records
*/
export async function seedTestUser(): Promise<void> {
const databaseUrl = process.env.DATABASE_URL;
if (!databaseUrl) {
console.log('⚠️ DATABASE_URL not set, skipping test user seeding');
return;
}
// Dynamic import pg to avoid bundling issues
const { default: pg } = await import('pg');
const client = new pg.Client({ connectionString: databaseUrl });
try {
await client.connect();
console.log('🔌 Connected to database for test user seeding');
const now = new Date().toISOString();
// Use fixed account ID to avoid conflicts when multiple workers run concurrently
const accountId = 'e2e_test_account_001';
// Use upsert to handle concurrent worker execution
// Insert user or do nothing if already exists (handles all unique constraints)
const passwordHash = await hashPassword(TEST_USER.password);
// Use ON CONFLICT DO NOTHING to handle all unique constraint conflicts
// This is safe because we're using fixed test user credentials
// Set onboarding as completed to skip onboarding flow in tests
const onboarding = JSON.stringify({ finishedAt: now, version: 1 });
await client.query(
`INSERT INTO users (id, email, normalized_email, username, full_name, email_verified, onboarding, created_at, updated_at, last_active_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $8, $8)
ON CONFLICT (id) DO UPDATE SET onboarding = $7, updated_at = $8`,
[
TEST_USER.id,
TEST_USER.email,
TEST_USER.email.toLowerCase(),
TEST_USER.username,
TEST_USER.fullName,
true, // email_verified
onboarding,
now,
],
);
// Create account record with password (for credential login)
await client.query(
`INSERT INTO accounts (id, user_id, account_id, provider_id, password, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6, $6)
ON CONFLICT DO NOTHING`,
[
accountId,
TEST_USER.id,
TEST_USER.email, // account_id is email for credential provider
'credential', // provider_id
passwordHash,
now,
],
);
console.log('✅ Test user seeded successfully');
console.log(` Email: ${TEST_USER.email}`);
console.log(` Password: ${TEST_USER.password}`);
} catch (error) {
console.error('❌ Failed to seed test user:', error);
throw error;
} finally {
await client.end();
}
}
/**
* Clean up test user data after tests
*/
export async function cleanupTestUser(): Promise<void> {
const databaseUrl = process.env.DATABASE_URL;
if (!databaseUrl) {
return;
}
const { default: pg } = await import('pg');
const client = new pg.Client({ connectionString: databaseUrl });
try {
await client.connect();
// Delete sessions first (foreign key)
await client.query('DELETE FROM auth_sessions WHERE user_id = $1', [TEST_USER.id]);
// Delete accounts (foreign key)
await client.query('DELETE FROM accounts WHERE user_id = $1', [TEST_USER.id]);
// Delete user
await client.query('DELETE FROM users WHERE id = $1', [TEST_USER.id]);
console.log('🧹 Test user cleaned up');
} catch (error) {
console.error('❌ Failed to cleanup test user:', error);
} finally {
await client.end();
}
}
+68 -5
View File
@@ -1,9 +1,13 @@
import { type ChildProcess, exec } from 'node:child_process';
import { existsSync, unlinkSync, writeFileSync } from 'node:fs';
import { resolve } from 'node:path';
let serverProcess: ChildProcess | null = null;
let serverStartPromise: Promise<void> | null = null;
// File-based lock to coordinate between parallel workers
const LOCK_FILE = resolve(__dirname, '../../.server-starting.lock');
interface WebServerOptions {
command: string;
env?: Record<string, string>;
@@ -24,7 +28,7 @@ async function isServerRunning(port: number): Promise<boolean> {
}
export async function startWebServer(options: WebServerOptions): Promise<void> {
const { command, port, timeout = 120_000, env = {}, reuseExistingServer = true } = options;
const { command, port, timeout = 30_000, env = {}, reuseExistingServer = true } = options;
// If server is already being started by another worker, wait for it
if (serverStartPromise) {
@@ -38,6 +42,51 @@ export async function startWebServer(options: WebServerOptions): Promise<void> {
return;
}
// Check if another worker is starting the server (file-based lock for cross-process coordination)
if (existsSync(LOCK_FILE)) {
console.log(`⏳ Another worker is starting the server, waiting...`);
const startTime = Date.now();
while (!(await isServerRunning(port))) {
if (Date.now() - startTime > timeout) {
// Lock file might be stale, try to clean up and proceed
try {
unlinkSync(LOCK_FILE);
} catch {
// Ignore
}
break;
}
await new Promise((resolve) => {
setTimeout(resolve, 1000);
});
}
if (await isServerRunning(port)) {
console.log(`✅ Server is now ready on port ${port}`);
return;
}
}
// Create lock file to signal other workers
try {
writeFileSync(LOCK_FILE, String(process.pid));
} catch {
// Another worker might have created it, check again
if (existsSync(LOCK_FILE)) {
console.log(`⏳ Lock file created by another worker, waiting...`);
const startTime = Date.now();
while (!(await isServerRunning(port))) {
if (Date.now() - startTime > timeout) {
throw new Error(`Server failed to start within ${timeout}ms`);
}
await new Promise((resolve) => {
setTimeout(resolve, 1000);
});
}
console.log(`✅ Server is now ready on port ${port}`);
return;
}
}
// Create a promise for the server startup and store it
serverStartPromise = (async () => {
console.log(`🚀 Starting web server: ${command}`);
@@ -50,12 +99,20 @@ export async function startWebServer(options: WebServerOptions): Promise<void> {
cwd: projectRoot,
env: {
...process.env,
ENABLE_AUTH_PROTECTION: '0',
ENABLE_OIDC: '0',
NEXT_PUBLIC_ENABLE_CLERK_AUTH: '0',
NEXT_PUBLIC_ENABLE_NEXT_AUTH: '0',
// E2E test secret keys
BETTER_AUTH_SECRET: 'e2e-test-secret-key-for-better-auth-32chars!',
KEY_VAULTS_SECRET: 'LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s=',
// Disable email verification for e2e
NEXT_PUBLIC_AUTH_EMAIL_VERIFICATION: '0',
// Enable Better Auth for e2e tests with real authentication
NEXT_PUBLIC_ENABLE_BETTER_AUTH: '1',
NODE_OPTIONS: '--max-old-space-size=6144',
PORT: String(port),
// Mock S3 env vars to prevent initialization errors
S3_ACCESS_KEY_ID: 'e2e-mock-access-key',
S3_BUCKET: 'e2e-mock-bucket',
S3_ENDPOINT: 'https://e2e-mock-s3.localhost',
S3_SECRET_ACCESS_KEY: 'e2e-mock-secret-key',
...env,
},
});
@@ -93,4 +150,10 @@ export async function stopWebServer(): Promise<void> {
serverProcess = null;
serverStartPromise = null;
}
// Clean up lock file
try {
unlinkSync(LOCK_FILE);
} catch {
// Ignore if file doesn't exist
}
}
+17 -5
View File
@@ -1,5 +1,7 @@
import { IWorldOptions, World, setWorldConstructor } from '@cucumber/cucumber';
import { Browser, BrowserContext, Page, Response, chromium } from '@playwright/test';
import * as fs from 'node:fs';
import * as path from 'node:path';
export interface TestContext {
[key: string]: any;
@@ -29,7 +31,7 @@ export class CustomWorld extends World {
}
async init() {
const PORT = process.env.PORT ? Number(process.env.PORT) : 3010;
const PORT = process.env.PORT ? Number(process.env.PORT) : 3006;
const BASE_URL = process.env.BASE_URL || `http://localhost:${PORT}`;
this.browser = await chromium.launch({
@@ -42,7 +44,7 @@ export class CustomWorld extends World {
});
// Set expect timeout for assertions (e.g., toBeVisible, toHaveText)
this.browserContext.setDefaultTimeout(120_000);
this.browserContext.setDefaultTimeout(30_000);
this.page = await this.browserContext.newPage();
@@ -58,7 +60,7 @@ export class CustomWorld extends World {
}
});
this.page.setDefaultTimeout(120_000);
this.page.setDefaultTimeout(30_000);
}
async cleanup() {
@@ -68,8 +70,18 @@ export class CustomWorld extends World {
}
async takeScreenshot(name: string): Promise<Buffer> {
console.log(name);
return await this.page.screenshot({ fullPage: true });
const screenshot = await this.page.screenshot({ fullPage: true });
// Save screenshot to file
const screenshotsDir = path.join(process.cwd(), 'screenshots');
if (!fs.existsSync(screenshotsDir)) {
fs.mkdirSync(screenshotsDir, { recursive: true });
}
const filepath = path.join(screenshotsDir, `${name}.png`);
fs.writeFileSync(filepath, screenshot);
console.log(`📸 Screenshot saved: ${filepath}`);
return screenshot;
}
}
+110 -99
View File
@@ -1,39 +1,39 @@
{
"apikey.display.autoGenerated": "تم الإنشاء تلقائيًا",
"apikey.display.autoGenerated": "تم إنشاؤه تلقائيًا",
"apikey.display.copy": "نسخ",
"apikey.display.copyError": "فشل النسخ",
"apikey.display.copySuccess": "تم نسخ مفتاح API إلى الحافظة",
"apikey.display.enterPlaceholder": "الرجاء الإدخال",
"apikey.display.enterPlaceholder": "يرجى الإدخال",
"apikey.display.hide": "إخفاء",
"apikey.display.neverExpires": "لا تنتهي صلاحيتها أبدًا",
"apikey.display.neverUsed": "لم يُستخدم أبدًا",
"apikey.display.show": "عرض",
"apikey.display.neverExpires": "لا تنتهي صلاحيته",
"apikey.display.neverUsed": "لم يُستخدم من قبل",
"apikey.display.show": "إظهار",
"apikey.form.fields.expiresAt.label": "تاريخ الانتهاء",
"apikey.form.fields.expiresAt.placeholder": "لا تنتهي صلاحيتها أبدًا",
"apikey.form.fields.expiresAt.placeholder": "لا تنتهي صلاحيته",
"apikey.form.fields.name.label": "الاسم",
"apikey.form.fields.name.placeholder": "الرجاء إدخال اسم مفتاح API",
"apikey.form.fields.name.placeholder": "يرجى إدخال اسم مفتاح API",
"apikey.form.submit": "إنشاء",
"apikey.form.title": "إنشاء مفتاح API",
"apikey.list.actions.create": "إنشاء مفتاح API",
"apikey.list.actions.delete": "حذف",
"apikey.list.actions.deleteConfirm.actions.cancel": "إلغاء",
"apikey.list.actions.deleteConfirm.actions.ok": "تأكيد",
"apikey.list.actions.deleteConfirm.content": "هل أنت متأكد من حذف هذا المفتاح؟",
"apikey.list.actions.deleteConfirm.title": "تأكيد العملية",
"apikey.list.actions.deleteConfirm.content": "هل أنت متأكد أنك تريد حذف مفتاح API هذا؟",
"apikey.list.actions.deleteConfirm.title": "تأكيد الإجراء",
"apikey.list.columns.actions": "الإجراءات",
"apikey.list.columns.expiresAt": "تاريخ الانتهاء",
"apikey.list.columns.key": "المفتاح",
"apikey.list.columns.lastUsedAt": "آخر استخدام",
"apikey.list.columns.name": "الاسم",
"apikey.list.columns.status": "حالة التفعيل",
"apikey.list.columns.status": "حالة التمكين",
"apikey.list.title": "قائمة مفاتيح API",
"apikey.validation.required": "لا يمكن أن يكون المحتوى فارغًا",
"apikey.validation.required": "لا يمكن ترك هذا الحقل فارغًا",
"betterAuth.errors.confirmPasswordRequired": "يرجى تأكيد كلمة المرور",
"betterAuth.errors.emailExists": "هذا البريد الإلكتروني مسجّل بالفعل، يرجى تسجيل الدخول مباشرة",
"betterAuth.errors.emailInvalid": "يرجى إدخال عنوان بريد إلكتروني صالح",
"betterAuth.errors.emailNotRegistered": "هذا البريد الإلكتروني غير مسجل",
"betterAuth.errors.emailNotVerified": "لم يتم التحقق من البريد الإلكتروني، يرجى التحقق أولاً",
"betterAuth.errors.emailRequired": "يرجى إدخال عنوان البريد الإلكتروني",
"betterAuth.errors.emailExists": "هذا البريد الإلكتروني مسجل بالفعل. يرجى تسجيل الدخول بدلاً من ذلك",
"betterAuth.errors.emailInvalid": "يرجى إدخال بريد إلكتروني أو اسم مستخدم صالح",
"betterAuth.errors.emailNotRegistered": "هذا البريد الإلكتروني أو اسم المستخدم غير مسجل",
"betterAuth.errors.emailNotVerified": "البريد الإلكتروني غير مفعل، يرجى تفعيله أولاً",
"betterAuth.errors.emailRequired": "يرجى إدخال بريدك الإلكتروني أو اسم المستخدم",
"betterAuth.errors.firstNameRequired": "يرجى إدخال الاسم الأول",
"betterAuth.errors.lastNameRequired": "يرجى إدخال اسم العائلة",
"betterAuth.errors.loginFailed": "فشل تسجيل الدخول، يرجى التحقق من البريد الإلكتروني وكلمة المرور",
@@ -44,77 +44,82 @@
"betterAuth.errors.passwordRequired": "يرجى إدخال كلمة المرور",
"betterAuth.errors.usernameNotRegistered": "اسم المستخدم هذا غير مسجل",
"betterAuth.errors.usernameRequired": "يرجى إدخال اسم المستخدم",
"betterAuth.resetPassword.backToSignIn": "العودة إلى تسجيل الدخول",
"betterAuth.resetPassword.backToSignIn": "العودة لتسجيل الدخول",
"betterAuth.resetPassword.confirmPasswordPlaceholder": "تأكيد كلمة المرور الجديدة",
"betterAuth.resetPassword.confirmPasswordRequired": "يرجى تأكيد كلمة المرور الجديدة",
"betterAuth.resetPassword.description": "يرجى إدخال كلمة المرور الجديدة",
"betterAuth.resetPassword.error": "فشل إعادة تعيين كلمة المرور، يرجى المحاولة مرة أخرى",
"betterAuth.resetPassword.error": "فشل في إعادة تعيين كلمة المرور، يرجى المحاولة مرة أخرى",
"betterAuth.resetPassword.invalidToken": "رابط إعادة التعيين غير صالح أو منتهي الصلاحية",
"betterAuth.resetPassword.newPasswordPlaceholder": "أدخل كلمة المرور الجديدة",
"betterAuth.resetPassword.passwordMismatch": "كلمتا المرور غير متطابقتين",
"betterAuth.resetPassword.submit": "إعادة تعيين كلمة المرور",
"betterAuth.resetPassword.success": "تمت إعادة تعيين كلمة المرور بنجاح، يرجى تسجيل الدخول باستخدام كلمة المرور الجديدة",
"betterAuth.resetPassword.success": "تمت إعادة تعيين كلمة المرور بنجاح، يرجى تسجيل الدخول بكلمة المرور الجديدة",
"betterAuth.resetPassword.title": "إعادة تعيين كلمة المرور",
"betterAuth.signin.backToEmail": "العودة لتعديل البريد الإلكتروني",
"betterAuth.signin.continueWithApple": "تسجيل الدخول باستخدام Apple",
"betterAuth.signin.backToEmail": "العودة لتغيير البريد الإلكتروني",
"betterAuth.signin.continueWithApple": "المتابعة باستخدام Apple",
"betterAuth.signin.continueWithAuth0": "تسجيل الدخول باستخدام Auth0",
"betterAuth.signin.continueWithAuthelia": "تسجيل الدخول باستخدام Authelia",
"betterAuth.signin.continueWithAuthentik": "تسجيل الدخول باستخدام Authentik",
"betterAuth.signin.continueWithCasdoor": "تسجيل الدخول باستخدام Casdoor",
"betterAuth.signin.continueWithCloudflareZeroTrust": "تسجيل الدخول باستخدام Cloudflare Zero Trust",
"betterAuth.signin.continueWithCognito": "تسجيل الدخول باستخدام AWS Cognito",
"betterAuth.signin.continueWithCognito": "المتابعة باستخدام AWS Cognito",
"betterAuth.signin.continueWithFeishu": "تسجيل الدخول باستخدام Feishu",
"betterAuth.signin.continueWithGithub": "تسجيل الدخول باستخدام GitHub",
"betterAuth.signin.continueWithGoogle": "تسجيل الدخول باستخدام Google",
"betterAuth.signin.continueWithGithub": "المتابعة باستخدام GitHub",
"betterAuth.signin.continueWithGoogle": "المتابعة باستخدام Google",
"betterAuth.signin.continueWithKeycloak": "تسجيل الدخول باستخدام Keycloak",
"betterAuth.signin.continueWithLogto": "تسجيل الدخول باستخدام Logto",
"betterAuth.signin.continueWithMicrosoft": "تسجيل الدخول باستخدام Microsoft",
"betterAuth.signin.continueWithMicrosoft": "المتابعة باستخدام Microsoft",
"betterAuth.signin.continueWithOIDC": "تسجيل الدخول باستخدام OIDC",
"betterAuth.signin.continueWithOkta": "تسجيل الدخول باستخدام Okta",
"betterAuth.signin.continueWithWechat": "تسجيل الدخول باستخدام WeChat",
"betterAuth.signin.continueWithZitadel": "تسجيل الدخول باستخدام Zitadel",
"betterAuth.signin.emailPlaceholder": "يرجى إدخال عنوان البريد الإلكتروني",
"betterAuth.signin.emailPlaceholder": "أدخل بريدك الإلكتروني أو اسم المستخدم",
"betterAuth.signin.emailStep.title": "تسجيل الدخول",
"betterAuth.signin.error": "فشل تسجيل الدخول، يرجى التحقق من البريد الإلكتروني وكلمة المرور",
"betterAuth.signin.forgotPassword": "هل نسيت كلمة المرور؟",
"betterAuth.signin.forgotPasswordError": "فشل إرسال رابط إعادة تعيين كلمة المرور",
"betterAuth.signin.forgotPasswordError": "فشل في إرسال رابط إعادة تعيين كلمة المرور",
"betterAuth.signin.forgotPasswordSent": "تم إرسال رابط إعادة تعيين كلمة المرور، يرجى التحقق من بريدك الإلكتروني",
"betterAuth.signin.invalidReferralCodeContent": "رمز الإحالة \"{{code}}\" الذي استخدمته غير صالح أو منتهي الصلاحية. هل ترغب في المتابعة؟",
"betterAuth.signin.invalidReferralCodeTitle": "رمز إحالة غير صالح",
"betterAuth.signin.magicLinkButton": "إرسال رابط تسجيل الدخول",
"betterAuth.signin.magicLinkError": "فشل إرسال رابط تسجيل الدخول، يرجى المحاولة لاحقًا",
"betterAuth.signin.magicLinkError": "فشل في إرسال رابط تسجيل الدخول، يرجى المحاولة لاحقًا",
"betterAuth.signin.magicLinkSent": "تم إرسال رابط تسجيل الدخول، يرجى التحقق من بريدك الإلكتروني",
"betterAuth.signin.nextStep": "الخطوة التالية",
"betterAuth.signin.nextStep": "التالي",
"betterAuth.signin.noAccount": "ليس لديك حساب؟",
"betterAuth.signin.orContinueWith": "أو المتابعة باستخدام",
"betterAuth.signin.passwordPlaceholder": "يرجى إدخال كلمة المرور",
"betterAuth.signin.passwordStep.subtitle": "يرجى إدخال كلمة المرور للمتابعة",
"betterAuth.signin.orContinueWith": "أو",
"betterAuth.signin.passwordPlaceholder": "أدخل كلمة المرور",
"betterAuth.signin.passwordStep.subtitle": "أدخل كلمة المرور للمتابعة",
"betterAuth.signin.signupLink": "سجّل الآن",
"betterAuth.signin.socialError": "فشل تسجيل الدخول عبر الشبكات الاجتماعية، يرجى المحاولة مرة أخرى",
"betterAuth.signin.socialOnlyHint": "تم تسجيل هذا البريد الإلكتروني باستخدام حساب اجتماعي، يرجى تسجيل الدخول باستخدامه",
"betterAuth.signin.socialError": "فشل تسجيل الدخول الاجتماعي، يرجى المحاولة مرة أخرى",
"betterAuth.signin.socialOnlyHint": "تم تسجيل هذا البريد الإلكتروني باستخدام حساب اجتماعي. يرجى تسجيل الدخول باستخدام مزود الخدمة المناسب.",
"betterAuth.signin.submit": "تسجيل الدخول",
"betterAuth.signup.confirmPasswordPlaceholder": "يرجى تأكيد كلمة المرور",
"betterAuth.signup.emailPlaceholder": "يرجى إدخال عنوان البريد الإلكتروني",
"betterAuth.signup.confirmPasswordPlaceholder": "تأكيد كلمة المرور",
"betterAuth.signup.emailPlaceholder": "أدخل عنوان بريدك الإلكتروني",
"betterAuth.signup.error": "فشل التسجيل، يرجى المحاولة مرة أخرى",
"betterAuth.signup.firstNamePlaceholder": "الاسم الأول",
"betterAuth.signup.hasAccount": "هل لديك حساب؟",
"betterAuth.signup.hasAccount": "هل لديك حساب بالفعل؟",
"betterAuth.signup.invalidReferralCodeContent": "رمز الإحالة \"{{code}}\" الذي أدخلته غير صالح أو منتهي الصلاحية. هل ترغب في المتابعة؟",
"betterAuth.signup.invalidReferralCodeTitle": "رمز إحالة غير صالح",
"betterAuth.signup.lastNamePlaceholder": "اسم العائلة",
"betterAuth.signup.passwordPlaceholder": "يرجى إدخال كلمة المرور",
"betterAuth.signup.signinLink": "تسجيل الدخول الآن",
"betterAuth.signup.submit": "تسجيل",
"betterAuth.signup.subtitle": "ابدأ مساحة التعاون الخاصة بـ Agents",
"betterAuth.signup.passwordPlaceholder": "أدخل كلمة المرور",
"betterAuth.signup.referralCodePlaceholder": "رمز الإحالة (اختياري)",
"betterAuth.signup.signinLink": "سجّل الدخول الآن",
"betterAuth.signup.submit": "إنشاء حساب",
"betterAuth.signup.subtitle": "ابدأ مساحة التعاون الخاصة بك مع Agents",
"betterAuth.signup.success": "تم التسجيل بنجاح! يرجى التحقق من بريدك الإلكتروني لتأكيد الحساب",
"betterAuth.signup.title": "إنشاء حساب",
"betterAuth.signup.usernamePlaceholder": "يرجى إدخال اسم المستخدم",
"betterAuth.verifyEmail.backToSignIn": "العودة إلى تسجيل الدخول",
"betterAuth.verifyEmail.checkSpam": "إذا لم تتلقَ البريد الإلكتروني، يرجى التحقق من مجلد الرسائل غير المرغوب فيها",
"betterAuth.signup.usernamePlaceholder": "أدخل اسم المستخدم",
"betterAuth.verifyEmail.backToSignIn": "العودة لتسجيل الدخول",
"betterAuth.verifyEmail.checkSpam": "إذا لم يصلك البريد الإلكتروني، يرجى التحقق من مجلد الرسائل غير المرغوب فيها",
"betterAuth.verifyEmail.description": "تم إرسال رسالة تحقق إلى {{email}}",
"betterAuth.verifyEmail.resend.button": "إعادة إرسال رسالة التحقق",
"betterAuth.verifyEmail.resend.error": "فشل الإرسال، يرجى المحاولة لاحقًا",
"betterAuth.verifyEmail.resend.error": "فشل الإرسال. يرجى المحاولة لاحقًا.",
"betterAuth.verifyEmail.resend.noEmail": "عنوان البريد الإلكتروني مفقود",
"betterAuth.verifyEmail.resend.success": "تمت إعادة إرسال رسالة التحقق، يرجى التحقق من بريدك الإلكتروني",
"betterAuth.verifyEmail.resend.success": "تمت إعادة إرسال رسالة التحقق. يرجى التحقق من بريدك الوارد.",
"betterAuth.verifyEmail.title": "تحقق من بريدك الإلكتروني",
"date.prevMonth": "الشهر الماضي",
"date.recent30Days": "آخر 30 يومًا",
"footer.agreement": "بالمتابعة، فإنك تؤكد أنك قد قرأت ووافقت على <terms>الشروط والأحكام</terms> و<privacy>سياسة الخصوصية</privacy>",
"footer.agreement": "بالمتابعة، فإنك تؤكد أنك قرأت ووافقت على <terms>الشروط والأحكام</terms> و<privacy>سياسة الخصوصية</privacy>",
"footer.privacy": "سياسة الخصوصية",
"footer.terms": "شروط الخدمة",
"header.desc": "إدارة معلومات حسابك.",
@@ -133,104 +138,110 @@
"heatmaps.months.nov": "نوفمبر",
"heatmaps.months.oct": "أكتوبر",
"heatmaps.months.sep": "سبتمبر",
"heatmaps.tooltip": "{{date}} أرسل {{count}} رسائل في ذلك اليوم",
"heatmaps.totalCount": "إجمالي {{count}} رسائل أرسلت في العام الماضي",
"heatmaps.tooltip": "{{date}} تم إرسال {{count}} رسالة في هذا اليوم",
"heatmaps.totalCount": "تم إرسال ما مجموعه {{count}} رسالة خلال العام الماضي",
"login": "تسجيل الدخول",
"loginOrSignup": "تسجيل الدخول / الاشتراك",
"profile.authorizations.actions.revoke": "إلغاء التفويض",
"profile.authorizations.revoke.description": "بعد إلغاء التفويض، لن يتمكن هذا التطبيق من الوصول إلى بياناتك. لإعادة استخدامه، ستحتاج إلى منحه التفويض مرة أخرى.",
"profile.authorizations.revoke.title": "هل أنت متأكد من إلغاء التفويض لـ {{name}}؟",
"loginGuide.f1": "احصل على استخدام مجاني",
"loginGuide.f2": "مزامنة الرسائل عبر الأجهزة",
"loginGuide.f3": "الوصول إلى مجموعة كبيرة من الوكلاء",
"loginGuide.f4": "استكشاف الإضافات القوية",
"loginGuide.title": "بعد تسجيل الدخول، يمكنك:",
"loginOrSignup": "تسجيل الدخول / إنشاء حساب",
"profile.account": "الحساب",
"profile.authorizations.actions.revoke": "إلغاء",
"profile.authorizations.revoke.description": "بعد الإلغاء، لن يتمكن الأداة من الوصول إلى بياناتك. ستحتاج إلى إعادة التفويض لاستخدامها مرة أخرى.",
"profile.authorizations.revoke.title": "هل تريد إلغاء تفويض {{name}}؟",
"profile.authorizations.title": "إدارة التفويضات",
"profile.avatar": "الصورة الشخصية",
"profile.avatar": "الصورة الرمزية",
"profile.cancel": "إلغاء",
"profile.changePassword": "إعادة تعيين كلمة المرور",
"profile.email": "عنوان البريد الإلكتروني",
"profile.fullName": "الاسم الكامل",
"profile.fullNameInputHint": "يرجى إدخال الاسم الكامل الجديد",
"profile.interests": "مجالات الاهتمام",
"profile.fullNameInputHint": "يرجى إدخال اسمك الكامل الجديد",
"profile.interests": "الاهتمامات",
"profile.interestsAdd": "إضافة",
"profile.interestsPlaceholder": "أدخل مجالات الاهتمام",
"profile.interestsPlaceholder": "أدخل اهتمامًا",
"profile.password": "كلمة المرور",
"profile.resetPasswordError": "فشل إرسال رابط إعادة تعيين كلمة المرور",
"profile.resetPasswordError": "فشل في إرسال رابط إعادة تعيين كلمة المرور",
"profile.resetPasswordSent": "تم إرسال رابط إعادة تعيين كلمة المرور، يرجى التحقق من بريدك الإلكتروني",
"profile.save": "حفظ",
"profile.setPassword": "تعيين كلمة المرور",
"profile.sso.link.button": "ربط الحساب",
"profile.sso.link.success": "تم ربط الحساب بنجاح",
"profile.sso.loading": "جارٍ تحميل الحسابات المرتبطة من طرف ثالث",
"profile.sso.providers": "الحسابات المتصلة",
"profile.sso.unlink.description": "بعد إلغاء الربط، لن تتمكن من تسجيل الدخول باستخدام حساب {{provider}} \"{{providerAccountId}}\". إذا كنت ترغب في ربط حساب {{provider}} بهذا الحساب مرة أخرى، يرجى التأكد من أن عنوان البريد الإلكتروني لحساب {{provider}} هو {{email}}، وسنقوم بربطه تلقائيًا عند تسجيل الدخول.",
"profile.sso.unlink.forbidden": "يجب أن تحتفظ بحساب طرف ثالث واحد على الأقل مرتبطًا.",
"profile.sso.unlink.title": "هل تريد فصل حساب الطرف الثالث {{provider}}؟",
"profile.title": "تفاصيل الملف الشخصي",
"profile.updateAvatar": "تحديث الصورة الشخصية",
"profile.sso.loading": "جاري تحميل الحسابات المرتبطة من جهات خارجية",
"profile.sso.providers": "الحسابات المرتبطة",
"profile.sso.unlink.description": "ستحتاج إلى إعادة التفويض أو الربط لتسجيل الدخول باستخدام {{provider}} مرة أخرى بعد إلغاء الربط.",
"profile.sso.unlink.forbidden": "يجب الاحتفاظ بطريقة تسجيل دخول واحدة على الأقل.",
"profile.sso.unlink.title": "هل تريد إلغاء ربط حساب {{provider}}؟",
"profile.title": "الملف الشخصي",
"profile.updateAvatar": "تحديث الصورة الرمزية",
"profile.updateFullName": "تحديث الاسم الكامل",
"profile.updateInterests": "تحديث مجالات الاهتمام",
"profile.updateInterests": "تحديث الاهتمامات",
"profile.updateUsername": "تحديث اسم المستخدم",
"profile.username": "اسم المستخدم",
"profile.usernameDuplicate": "اسم المستخدم مستخدم بالفعل",
"profile.usernameInputHint": "يرجى إدخال اسم مستخدم جديد",
"profile.usernamePlaceholder": "يرجى إدخال اسم مستخدم مكوّن من أحرف أو أرقام أو شرطة سفلية",
"profile.usernameRequired": "اسم المستخدم لا يمكن أن يكون فارغًا",
"profile.usernameRule": "اسم المستخدم يجب أن يحتوي فقط على أحرف أو أرقام أو شرطة سفلية",
"profile.usernameInputHint": "يرجى إدخال اسم المستخدم الجديد",
"profile.usernamePlaceholder": "أدخل اسم مستخدم يحتوي على أحرف أو أرقام أو شرطة سفلية",
"profile.usernameRequired": "لا يمكن أن يكون اسم المستخدم فارغًا",
"profile.usernameRule": "يمكن أن يحتوي اسم المستخدم على أحرف أو أرقام أو شرطة سفلية فقط",
"profile.usernameUpdateFailed": "فشل في تحديث اسم المستخدم، يرجى المحاولة لاحقًا",
"signin.subtitle": "سجّل أو قم بتسجيل الدخول إلى حسابك في {{appName}}",
"signin.title": "مساحة التعاون الخاصة بك في Agents",
"signin.subtitle": "سجّل أو قم بتسجيل الدخول إلى حساب {{appName}} الخاص بك",
"signin.title": "للتعاون مع الوكلاء",
"signout": "تسجيل الخروج",
"signup": "الاشتراك",
"signup": "إنشاء حساب",
"stats.aiheatmaps": "مؤشر النشاط",
"stats.assistants": "المساعدون",
"stats.assistantsRank.left": "المساعد",
"stats.assistants": "الوكلاء",
"stats.assistantsRank.left": "الوكيل",
"stats.assistantsRank.right": "المواضيع",
"stats.assistantsRank.title": "ترتيب استخدام المساعد",
"stats.assistantsRank.title": "ترتيب استخدام الوكلاء",
"stats.createdAt": "تاريخ التسجيل",
"stats.days": "أيام",
"stats.empty.desc": "يرجى تجميع المزيد من بيانات الدردشة للعرض",
"stats.empty.desc": "يرجى جمع المزيد من بيانات الدردشة لعرضها",
"stats.empty.title": "لا توجد بيانات",
"stats.lastYearActivity": "النشاط في العام الماضي",
"stats.lastYearActivity": "النشاط خلال العام الماضي",
"stats.loginGuide.f1": "احصل على استخدام مجاني",
"stats.loginGuide.f2": "مزامنة الرسائل عبر الأجهزة المتعددة",
"stats.loginGuide.f3": "تمتع بمساعدين متنوعين",
"stats.loginGuide.f4": "استكشف الإضافات القوية",
"stats.loginGuide.title": "بعد تسجيل الدخول يمكنك:",
"stats.messages": "رسائل",
"stats.loginGuide.f2": "مزامنة الرسائل عبر الأجهزة",
"stats.loginGuide.f3": "الوصول إلى مجموعة كبيرة من الوكلاء",
"stats.loginGuide.f4": "استكشاف المهارات القوية",
"stats.loginGuide.title": "بعد تسجيل الدخول، يمكنك:",
"stats.messages": "الرسائل",
"stats.modelsRank.left": "النموذج",
"stats.modelsRank.right": "الرسائل",
"stats.modelsRank.title": "ترتيب استخدام النموذج",
"stats.share.title": "مؤشر نشاط الذكاء الاصطناعي الخاص بي",
"stats.modelsRank.title": "ترتيب استخدام النماذج",
"stats.share.title": "مؤشر نشاطي مع الذكاء الاصطناعي",
"stats.topics": "المواضيع",
"stats.topicsRank.left": "الموضوع",
"stats.topicsRank.right": "الرسائل",
"stats.topicsRank.title": "ترتيب محتوى الموضوع",
"stats.updatedAt": اريخ التحديث",
"stats.welcome": "{{username}}، هذا هو يومك <span>{{days}}</span> مع {{appName}}",
"stats.words": "كلمات",
"stats.topicsRank.title": "ترتيب محتوى المواضيع",
"stats.updatedAt": م التحديث في",
"stats.welcome": "{{username}}، هذه هي يومك <span>{{days}}</span> مع {{appName}}",
"stats.words": "إجمالي الكلمات",
"tab.apikey": "إدارة مفاتيح API",
"tab.profile": "حسابي",
"tab.security": "الأمان",
"tab.stats": "الإحصائيات",
"tab.usage": "إحصاءات الاستخدام",
"tab.usage": "إحصائيات الاستخدام",
"usage.activeModels.modelTable": "قائمة النماذج",
"usage.activeModels.models": "النماذج النشطة",
"usage.activeModels.providerTable": "قائمة المزودين",
"usage.activeModels.providers": "المزودون النشطون",
"usage.activeModels.table.calls": "عدد الاستدعاءات",
"usage.activeModels.table.calls": "المكالمات",
"usage.activeModels.table.model": "النموذج",
"usage.activeModels.table.provider": "المزود",
"usage.activeModels.table.spend": "التكلفة",
"usage.cards.month.modelCalls": "استدعاءات النموذج",
"usage.cards.month.title": "إنفاق هذا الشهر",
"usage.activeModels.table.spend": "الإنفاق",
"usage.cards.month.modelCalls": "مكالمات النموذج",
"usage.cards.month.title": "الإنفاق هذا الشهر",
"usage.cards.today.title": "إنفاق اليوم",
"usage.cards.today.yesterday": "أمس",
"usage.table.actions": "إجراءات",
"usage.table.actions": "الإجراءات",
"usage.table.createdAt": "وقت الاستخدام",
"usage.table.inputTokens": "رموز الإدخال",
"usage.table.inputTokens": "الرموز المدخلة",
"usage.table.model": "النموذج",
"usage.table.outputTokens": "رموز الإخراج",
"usage.table.spend": "التكلفة",
"usage.table.outputTokens": "الرموز الناتجة",
"usage.table.spend": "الإنفاق",
"usage.table.tps": "TPS",
"usage.table.ttft": "TTFT",
"usage.table.type": "نوع الاستدعاء",
"usage.table.type": "نوع المكالمة",
"usage.trends.spend": "المبلغ",
"usage.trends.tokens": "الرموز",
"usage.welcome.model": "النموذج",
+13 -13
View File
@@ -1,36 +1,36 @@
{
"actions.discord": "اذهب إلى Discord لإرسال الملاحظات",
"actions.discord": "اذهب إلى Discord للحصول على الملاحظات",
"actions.home": "العودة إلى الصفحة الرئيسية",
"actions.retry": "تسجيل الدخول مرة أخرى",
"codes.ACCOUNT_ALREADY_LINKED_TO_DIFFERENT_USER": "تم ربط هذا الحساب بمستخدم آخر",
"codes.ACCOUNT_ALREADY_LINKED_TO_DIFFERENT_USER": "هذا الحساب مرتبط بالفعل بمستخدم آخر",
"codes.ACCOUNT_NOT_FOUND": "لم يتم العثور على الحساب",
"codes.CREDENTIAL_ACCOUNT_NOT_FOUND": "حساب بيانات الاعتماد غير موجود",
"codes.EMAIL_CAN_NOT_BE_UPDATED": "لا يمكن تعديل البريد الإلكتروني لهذا الحساب",
"codes.EMAIL_CAN_NOT_BE_UPDATED": "لا يمكن تحديث البريد الإلكتروني لهذا الحساب",
"codes.EMAIL_NOT_VERIFIED": "يرجى التحقق من بريدك الإلكتروني أولاً",
"codes.FAILED_TO_CREATE_SESSION": "فشل في إنشاء الجلسة",
"codes.FAILED_TO_CREATE_USER": "فشل في إنشاء المستخدم",
"codes.FAILED_TO_GET_SESSION": "فشل في الحصول على الجلسة",
"codes.FAILED_TO_GET_USER_INFO": "فشل في جلب معلومات المستخدم",
"codes.FAILED_TO_GET_SESSION": "فشل في استرجاع الجلسة",
"codes.FAILED_TO_GET_USER_INFO": "فشل في استرجاع معلومات المستخدم",
"codes.FAILED_TO_UNLINK_LAST_ACCOUNT": "لا يمكن إلغاء ربط آخر حساب مرتبط",
"codes.FAILED_TO_UPDATE_USER": "فشل في تحديث معلومات المستخدم",
"codes.ID_TOKEN_NOT_SUPPORTED": "رمز الهوية غير مدعوم",
"codes.INVALID_EMAIL": "تنسيق البريد الإلكتروني غير صحيح",
"codes.INVALID_EMAIL": "تنسيق البريد الإلكتروني غير صالح",
"codes.INVALID_EMAIL_OR_PASSWORD": "البريد الإلكتروني أو كلمة المرور غير صحيحة",
"codes.INVALID_PASSWORD": "تنسيق كلمة المرور غير صالح",
"codes.INVALID_TOKEN": "الرمز غير صالح أو منتهي الصلاحية",
"codes.PASSWORD_TOO_LONG": "كلمة المرور طويلة جداً",
"codes.PASSWORD_TOO_SHORT": "كلمة المرور قصيرة جداً",
"codes.PROVIDER_NOT_FOUND": "لم يتم العثور على مزود الهوية المناسب",
"codes.RATE_LIMIT_EXCEEDED": "عدد الطلبات كبير جداً، يرجى المحاولة لاحقاً",
"codes.SESSION_EXPIRED": "انتهت صلاحية الجلسة، يرجى تسجيل الدخول مجدداً",
"codes.SOCIAL_ACCOUNT_ALREADY_LINKED": "تم ربط هذا الحساب الاجتماعي بمستخدم آخر",
"codes.PROVIDER_NOT_FOUND": "لم يتم العثور على إعدادات موفر الهوية",
"codes.RATE_LIMIT_EXCEEDED": "عدد كبير جداً من الطلبات، يرجى المحاولة لاحقاً",
"codes.SESSION_EXPIRED": "انتهت صلاحية الجلسة، يرجى تسجيل الدخول مرة أخرى",
"codes.SOCIAL_ACCOUNT_ALREADY_LINKED": "هذا الحساب الاجتماعي مرتبط بالفعل بمستخدم آخر",
"codes.UNEXPECTED_ERROR": "حدث خطأ غير متوقع، يرجى المحاولة مرة أخرى",
"codes.UNKNOWN": "حدث خطأ غير معروف، يرجى المحاولة مرة أخرى أو التواصل مع الدعم",
"codes.USER_ALREADY_EXISTS": "المستخدم موجود بالفعل",
"codes.USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL": "تم استخدام هذا البريد الإلكتروني، يرجى تجربة بريد آخر",
"codes.USER_ALREADY_HAS_PASSWORD": "تم تعيين كلمة مرور لهذا الحساب مسبقاً",
"codes.USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL": "البريد الإلكتروني مستخدم بالفعل، يرجى تجربة بريد آخر",
"codes.USER_ALREADY_HAS_PASSWORD": "هذا الحساب يحتوي بالفعل على كلمة مرور",
"codes.USER_BANNED": "تم حظر هذا المستخدم",
"codes.USER_EMAIL_NOT_FOUND": "لم يتم العثور على البريد الإلكتروني",
"codes.USER_NOT_FOUND": "لم يتم العثور على المستخدم",
"title": "حدث خطأ في التحقق من الهوية"
"title": "خطأ في المصادقة"
}
+5 -5
View File
@@ -1,14 +1,14 @@
{
"actions.followOnX": "تابعنا على X",
"actions.subscribeToUpdates": "اشترك في التحديثات",
"actions.subscribeToUpdates": "اشترك للحصول على التحديثات",
"actions.versions": "تفاصيل الإصدار",
"addedWhileAway": "لقد أضفنا ميزات جديدة أثناء غيابك.",
"allChangelog": "عرض جميع سجلات التحديثات",
"description": "تابع الميزات الجديدة والتحسينات في {{appName}}",
"addedWhileAway": "قمنا بإضافة ميزات جديدة أثناء غيابك.",
"allChangelog": "عرض جميع سجلات التغييرات",
"description": "ابقَ على اطلاع بآخر الميزات والتحسينات في {{appName}}",
"pagination.next": "الصفحة التالية",
"pagination.older": "عرض التغييرات السابقة",
"readDetails": "اقرأ التفاصيل",
"title": "سجل التحديثات",
"title": "سجل التغييرات",
"versionDetails": "تفاصيل الإصدار",
"welcomeBack": "مرحبًا بعودتك!"
}
+243 -235
View File
@@ -1,365 +1,373 @@
{
"ModelSwitch.title": "النموذج",
"active": "نشط",
"agentBuilder.installPlugin.authRequired": "يتطلب مكون MCP السحابي تسجيل الدخول والمصادقة",
"agentBuilder.installPlugin.authRequired": "يتطلب Cloud MCP تسجيل الدخول للمتابعة",
"agentBuilder.installPlugin.cancel": "إلغاء",
"agentBuilder.installPlugin.clickApproveToConnect": "انقر على \"الموافقة\" للاتصال وتفويض هذا التكامل",
"agentBuilder.installPlugin.clickApproveToInstall": "انقر على \"الموافقة\" لتثبيت هذا المكون الإضافي",
"agentBuilder.installPlugin.connectedAndEnabled": "تم الاتصال والتفعيل",
"agentBuilder.installPlugin.connectionFailed": "فشل الاتصال",
"agentBuilder.installPlugin.installFailed": "فشل التثبيت",
"agentBuilder.installPlugin.installPlugin": "تثبيت المكون الإضافي",
"agentBuilder.installPlugin.installToEnable": "قم بتثبيت هذا المكون الإضافي لتمكين المساعد",
"agentBuilder.installPlugin.clickApproveToConnect": "انقر على \"موافقة\" للاتصال وتفويض هذا التكامل",
"agentBuilder.installPlugin.clickApproveToInstall": "انقر على \"موافقة\" لتثبيت هذه المهارة",
"agentBuilder.installPlugin.connectedAndEnabled": "متصل ومفعل",
"agentBuilder.installPlugin.connectionFailed": "فشل الاتصال. أعد المحاولة أو تحقق من التفويض وإعدادات الشبكة.",
"agentBuilder.installPlugin.installFailed": "فشل التثبيت. أعد المحاولة أو اعرض التفاصيل وحاول مرة أخرى.",
"agentBuilder.installPlugin.installPlugin": "تثبيت المهارة",
"agentBuilder.installPlugin.installToEnable": "قم بالتثبيت لتفعيل هذه المهارة للوكيل (يمكنك القيام بذلك لاحقًا)",
"agentBuilder.installPlugin.installedAndEnabled": "تم التثبيت والتفعيل",
"agentBuilder.installPlugin.requiresAuth": "يتطلب تفويضًا، انقر على \"الموافقة\" للاتصال",
"agentBuilder.installPlugin.requiresAuth": "يتطلب التفويض. انقر على \"موافقة\" للاتصال",
"agentBuilder.installPlugin.retry": "إعادة المحاولة",
"agentBuilder.title": "خبير إنشاء المساعدين",
"agentBuilder.welcome": "ما هو سيناريو احتياجك؟ شريكك المهني جاهز لخدمتك.\n\nسواء كنت تكتب، تبرمج، أو تحلل البيانات، يمكنني مساعدتك في إنشاء مساعدك الخاص!",
"agentDefaultMessage": "مرحبًا، أنا **{{name}}**، يمكنك بدء المحادثة معي على الفور، أو يمكنك الذهاب إلى [إعدادات المساعد]({{url}}) لإكمال معلوماتي.",
"agentDefaultMessageWithSystemRole": "مرحبًا، أنا **{{name}}**، كيف يمكنني مساعدتك؟",
"agentDefaultMessageWithoutEdit": "مرحبًا، أنا **{{name}}**، كيف يمكنني مساعدتك؟",
"agents": "مساعد",
"artifact.generating": "جاري الإنشاء",
"artifact.inThread": "لا يمكن عرض الموضوعات الفرعية، يرجى التبديل إلى منطقة المحادثة الرئيسية لفتحها",
"artifact.thinking": "جاري التفكير",
"agentBuilder.title": "منشئ الوكلاء",
"agentBuilder.welcome": "أخبرني بحالتك.\n\nكتابة، برمجة، أو تحليل بيانات — أي شيء يناسبك. أنت تملك الهدف والمعايير؛ سأقوم بتقسيمها إلى وكلاء تعاونيين قابلين للتنفيذ.",
"agentDefaultMessage": "مرحبًا، أنا **{{name}}**. جملة واحدة تكفي.\n\nهل ترغب في أن أتناسب مع سير عملك بشكل أفضل؟ انتقل إلى [إعدادات الوكيل]({{url}}) واملأ ملف تعريف الوكيل (يمكنك تعديله في أي وقت).",
"agentDefaultMessageWithSystemRole": "مرحبًا، أنا **{{name}}**. جملة واحدة تكفي — أنت المتحكم.",
"agentDefaultMessageWithoutEdit": "مرحبًا، أنا **{{name}}**. جملة واحدة تكفي — أنت المتحكم.",
"agents": "الوكلاء",
"artifact.generating": "يتم التوليد",
"artifact.inThread": "لا يمكن العرض في الموضوع الفرعي، يرجى التبديل إلى منطقة المحادثة الرئيسية للفتح",
"artifact.thinking": "يفكر",
"artifact.thought": "عملية التفكير",
"artifact.unknownTitle": "عمل غير مسمى",
"availableAgents": "المساعدون المتاحون",
"backToBottom": "العودة إلى الأسفل",
"beforeUnload.confirmLeave": ديك طلب جارٍ معالجته، هل أنت متأكد من رغبتك في المغادرة؟",
"artifact.unknownTitle": "عمل بدون عنوان",
"availableAgents": "الوكلاء المتاحون",
"backToBottom": "الانتقال إلى الأحدث",
"beforeUnload.confirmLeave": ا يزال هناك طلب قيد التشغيل. هل تريد المغادرة؟",
"builtinCopilot": "المساعد المدمج",
"chatList.expandMessage": رض الرسائل",
"chatList.expandMessage": "توسيع الرسالة",
"chatList.longMessageDetail": "عرض التفاصيل",
"clearCurrentMessages": "مسح رسائل الجلسة الحالية",
"confirmClearCurrentMessages": "سيتم مسح رسائل الجلسة الحالية قريبًا، وبمجرد المسح لن يمكن استعادتها، يرجى تأكيد الإجراء الخاص بك",
"confirmRemoveChatGroupItemAlert": "سيتم حذف هذه المجموعة، ولن يتأثر أعضاء الفريق. يرجى تأكيد الإجراء.",
"confirmRemoveGroupItemAlert": "سيتم حذف هذه المجموعة قريبًا. بعد الحذف، سيُنتقل المساعدون في هذه المجموعة إلى القائمة الافتراضية. يرجى تأكيد إجراء الحذف.",
"confirmClearCurrentMessages": "أنت على وشك مسح رسائل الجلسة الحالية. بمجرد المسح، لا يمكن استعادتها. يرجى تأكيد الإجراء.",
"confirmRemoveChatGroupItemAlert": "سيتم حذف هذه المجموعة. سيتم أيضًا حذف المساعدين الخاصين بالمجموعة، بينما لن يتأثر المساعدون الخارجيون.",
"confirmRemoveGroupItemAlert": "أنت على وشك حذف هذه المجموعة. بعد الحذف، سيتم نقل وكلائها إلى القائمة الافتراضية. يرجى تأكيد الإجراء.",
"confirmRemoveGroupSuccess": "تم حذف المجموعة بنجاح",
"confirmRemoveSessionItemAlert": "سيتم حذف هذا المساعد قريبًا، وبمجرد الحذف لن يمكن استعادته، يرجى تأكيد الإجراء الخاص بك",
"confirmRemoveSessionSuccess": "تم حذف المساعد بنجاح",
"defaultAgent": "المساعد الافتراضي",
"confirmRemoveSessionItemAlert": "أنت على وشك حذف هذا الوكيل. بمجرد الحذف، لا يمكن استعادته. يرجى تأكيد الإجراء.",
"confirmRemoveSessionSuccess": "تم حذف الوكيل بنجاح",
"defaultAgent": "الوكيل الافتراضي",
"defaultGroupChat": "مجموعة",
"defaultList": "القائمة الافتراضية",
"defaultSession": "المساعد الافتراضي",
"desktopNotification.aiReplyCompleted.body": "تم الانتهاء من توليد رد الذكاء الاصطناعي",
"desktopNotification.aiReplyCompleted.title": "اكتمل رد الذكاء الاصطناعي",
"defaultSession": "الوكيل الافتراضي",
"desktopNotification.aiReplyCompleted.body": "رد الوكيل جاهز",
"desktopNotification.aiReplyCompleted.title": "تم إكمال الرد",
"dm.placeholder": "ستظهر رسائلك الخاصة مع {{agentTitle}} هنا.",
"dm.tooltip": "أرسل رسالة خاصة",
"dm.tooltip": "إرسال رسالة خاصة",
"dm.visibleTo": "مرئي فقط لـ {{target}}",
"dm.you": "أنت",
"duplicateSession.loading": "جاري النسخ...",
"duplicateSession.loading": تم النسخ...",
"duplicateSession.success": "تم النسخ بنجاح",
"duplicateSession.title": "{{title}} نسخة",
"duplicateTitle": "{{title}} نسخة",
"emptyAgent": "لا يوجد مساعد",
"emptyAgentAction": "إنشاء مساعد",
"extendParams.disableContextCaching.desc": مكن تقليل تكلفة توليد محادثة واحدة بنسبة تصل إلى 90%، وزيادة سرعة الاستجابة بمقدار 4 مرات (<1>اعرف المزيد</1>). عند التفعيل، سيتم تعطيل حد عدد الرسائل التاريخية تلقائيًا",
"extendParams.disableContextCaching.title": "تفعيل تخزين السياق",
"extendParams.enableReasoning.desc": "استنادًا إلى آلية تفكير كلود (Claude Thinking) المحدودة (<1>اعرف المزيد</1>)، عند التفعيل، سيتم تعطيل حد عدد الرسائل التاريخية تلقائيًا",
"duplicateSession.title": "نسخة {{title}}",
"duplicateTitle": "نسخة {{title}}",
"emptyAgent": "لا يوجد وكلاء بعد. ابدأ بأول وكيل لك — وابنِ نظامك بمرور الوقت.",
"emptyAgentAction": "إنشاء وكيل",
"extendParams.disableContextCaching.desc": قلل ما يصل إلى 90٪ من تكلفة توليد محادثة واحدة ويوفر سرعة تصل إلى 4 أضعاف. تفعيل هذا سيقوم تلقائيًا بإلغاء الحد على عدد الرسائل التاريخية. <1>اعرف المزيد</1>",
"extendParams.disableContextCaching.title": "تفعيل تخزين السياق المؤقت",
"extendParams.enableReasoning.desc": "استنادًا إلى آلية التفكير في Claude، فإن تفعيل هذا سيقوم تلقائيًا بإلغاء الحد على عدد الرسائل التاريخية. <1>اعرف المزيد</1>",
"extendParams.enableReasoning.title": "تفعيل التفكير العميق",
"extendParams.imageAspectRatio.title": "نسبة العرض إلى الارتفاع للصورة",
"extendParams.imageAspectRatio.title": "نسبة أبعاد الصورة",
"extendParams.imageResolution.title": "دقة الصورة",
"extendParams.reasoningBudgetToken.title": "استهلاك توكن التفكير",
"extendParams.reasoningEffort.title": "شدة الاستدلال",
"extendParams.textVerbosity.title": "مستوى تفصيل المخرجات النصية",
"extendParams.reasoningBudgetToken.title": "رمز استهلاك التفكير",
"extendParams.reasoningEffort.title": "شدة التفكير",
"extendParams.textVerbosity.title": "مستوى تفصيل النص الناتج",
"extendParams.thinking.title": "مفتاح التفكير العميق",
"extendParams.thinkingLevel.title": "مستوى التفكير",
"extendParams.title": "وظائف توسيع النموذج",
"extendParams.urlContext.desc": "عند التفعيل، سيتم تحليل روابط الويب تلقائيًا للحصول على محتوى السياق الفعلي للصفحة",
"extendParams.title": "ميزات توسيع النموذج",
"extendParams.urlContext.desc": "عند التفعيل، سيتم تحليل الروابط تلقائيًا لاستخراج محتوى صفحة الويب الفعلي",
"extendParams.urlContext.title": "استخراج محتوى رابط الويب",
"group.desc": "التعاون مع عدة مساعدين للذكاء الاصطناعي في مساحة محادثة مشتركة.",
"group.memberTooltip": "هناك {{count}} عضوًا في المجموعة",
"group.orchestratorThinking": "المُنسق يفكر...",
"group.removeMember": "إزالة عضو",
"group.desc": "ادفع المهمة للأمام مع عدة وكلاء في مساحة مشتركة واحدة.",
"group.memberTooltip": "يوجد {{count}} عضو في المجموعة",
"group.orchestratorThinking": "المنسق يفكر...",
"group.removeMember": "إزالة العضو",
"group.title": "مجموعة",
"groupDescription": "وصف الفريق",
"groupSidebar.agentProfile.chat": "الدردشة",
"groupDescription": "وصف المجموعة",
"groupSidebar.agentProfile.chat": "محادثة",
"groupSidebar.agentProfile.model": "النموذج",
"groupSidebar.members.addMember": "إضافة عضو",
"groupSidebar.members.enableOrchestrator": "تفعيل المنسق",
"groupSidebar.members.memberSettings": "إعدادات العضو",
"groupSidebar.members.orchestrator": "المُنسق",
"groupSidebar.members.orchestratorThinking": "المُنسق يفكر...",
"groupSidebar.members.removeMember": "إزالة عضو",
"groupSidebar.members.stopOrchestrator": "إيقاف التفكير",
"groupSidebar.members.triggerOrchestrator": "بدء المحادثة الجماعية",
"groupSidebar.tabs.host": "المضيف",
"groupSidebar.members.memberSettings": "إعدادات الأعضاء",
"groupSidebar.members.orchestrator": "المنسق",
"groupSidebar.members.orchestratorThinking": "المنسق يفكر...",
"groupSidebar.members.removeMember": "إزالة العضو",
"groupSidebar.members.stopOrchestrator": "إيقاف",
"groupSidebar.members.triggerOrchestrator": "تشغيل",
"groupSidebar.tabs.host": "المنسق",
"groupSidebar.tabs.members": "الأعضاء",
"groupSidebar.tabs.role": "الإعداد",
"groupWizard.chooseMembers": "اختر المساعدين الحاليين...",
"groupWizard.createGroup": "إنشاء فريق",
"groupSidebar.tabs.role": "الملف الشخصي",
"groupWizard.chooseMembers": "اختر وكلاء موجودين...",
"groupWizard.createGroup": "إنشاء مجموعة",
"groupWizard.existingMembers": "الوكلاء الحاليون",
"groupWizard.groupMembers": "سيتم أيضًا إضافة هؤلاء المساعدين إلى قائمتك",
"groupWizard.host.description": "تمكين الفريق من العمل بشكل مستقل",
"groupWizard.host.title": "تفعيل المضيف",
"groupWizard.host.tooltip": "إذا قمت بتعطيل المضيف، فستحتاج إلى الإشارة إلى الأعضاء يدويًا باستخدام @ لكي يتمكنوا من الرد",
"groupWizard.groupMembers": "سيتم أيضًا إضافة هؤلاء الوكلاء إلى قائمتك",
"groupWizard.host.description": "دع المجموعة تتقدم تلقائيًا. يمكنك التدخل في أي وقت.",
"groupWizard.host.title": "تفعيل المنسق",
"groupWizard.host.tooltip": "عند الإيقاف، ستحتاج إلى الإشارة إلى الأعضاء للحصول على ردودهم.",
"groupWizard.memberCount": "{{count}} عضو",
"groupWizard.noMatchingTemplates": "لا توجد قوالب مطابقة",
"groupWizard.noSelectedTemplates": "لم يتم اختيار أي قالب",
"groupWizard.noSelectedTemplates": "لم يتم تحديد أي قوالب",
"groupWizard.noTemplateMembers": "لا يوجد أعضاء في القالب",
"groupWizard.noTemplates": "لا توجد قوالب متاحة",
"groupWizard.searchTemplates": "ابحث في القوالب...",
"groupWizard.searchTemplates": "البحث في القوالب...",
"groupWizard.title": "إنشاء مجموعة",
"groupWizard.useTemplate": "استخدام القالب",
"hideForYou": "تم إخفاء محتوى الرسائل الخاصة، يرجى تفعيل خيار 【عرض محتوى الرسائل الخاصة في الإعدادات للعرض",
"history.title": "سيتذكر المساعد آخر {{count}} رسالة فقط",
"historyRange": "نطاق التاريخ",
"historySummary": "ملخص الرسائل التاريخية",
"groupWizard.useTemplate": "استخدام قالب",
"hideForYou": "محتوى الرسائل الخاصة مخفي. يرجى تفعيل 'عرض محتوى الرسائل الخاصة' في الإعدادات لعرضه.",
"history.title": "سيحتفظ الوكيل فقط بآخر {{count}} رسالة.",
"historyRange": "نطاق السجل",
"historySummary": "ملخص الرسائل السابقة",
"inactive": "غير نشط",
"inbox.desc": "قم بتشغيل مجموعة الدماغ وأشعل شرارة التفكير. مساعدك الذكي، هنا حيث يمكنك التواصل بكل شيء",
"inbox.desc": "تعاون في مساحة عمل واحدة وحوّل الأفكار إلى نتائج.",
"inbox.title": "Lobe AI",
"input.addAi": "إضافة رسالة AI",
"input.addUser": "إضافة رسالة مستخدم",
"input.disclaimer": "قد يرتكب الذكاء الاصطناعي أخطاءً أيضًا، يرجى التحقق من المعلومات الهامة",
"input.errorMsg": "فشل إرسال الرسالة، يرجى التحقق من الشبكة والمحاولة مرة أخرى: {{errorMsg}}",
"input.addAi": "إضافة رسالة من الذكاء الاصطناعي",
"input.addUser": "إضافة رسالة من المستخدم",
"input.disclaimer": "قد يخطئ الوكلاء. استخدم حكمك الخاص للمعلومات الحساسة.",
"input.errorMsg": "فشل الإرسال: {{errorMsg}}. أعد المحاولة أو أرسل لاحقًا.",
"input.more": "المزيد",
"input.send": "إرسال",
"input.sendWithCmdEnter": "اضغط <key/> للإرسال",
"input.sendWithEnter": "اضغط <key/> للإرسال",
"input.stop": "توقف",
"input.warp": "تغيير السطر",
"input.warpWithKey": "اضغط على مفتاح <key/> للانتقال إلى السطر",
"intentUnderstanding.title": "جارٍ فهم وتحليل نواياك...",
"input.stop": "إيقاف",
"input.warp": "سطر جديد",
"input.warpWithKey": "اضغط <key/> لإدراج فاصل أسطر",
"intentUnderstanding.title": "جارٍ فهم نيتك...",
"inviteMembers": "دعوة الأعضاء",
"knowledgeBase.all": "جميع المحتويات",
"knowledgeBase.allFiles": "جميع الملفات",
"knowledgeBase.allLibraries": "جميع قواعد البيانات",
"knowledgeBase.disabled": "وضع النشر الحالي لا يدعم المحادثة مع قاعدة البيانات. لاستخدام هذه الميزة، يرجى التبديل إلى نشر قاعدة بيانات على الخادم أو استخدام خدمة {{cloud}}",
"knowledgeBase.all": "كل المحتوى",
"knowledgeBase.allFiles": "كل الملفات",
"knowledgeBase.allLibraries": "كل المكتبات",
"knowledgeBase.disabled": "دردشة المكتبة غير متاحة في هذا النشر. يرجى التبديل إلى قاعدة بيانات على الخادم أو استخدام {{cloud}}.",
"knowledgeBase.library.action.add": "إضافة",
"knowledgeBase.library.action.detail": "تفاصيل",
"knowledgeBase.library.action.remove": "إزالة",
"knowledgeBase.library.title": "الملفات / قاعدة البيانات",
"knowledgeBase.relativeFilesOrLibraries": "الملفات / قواعد البيانات المرتبطة",
"knowledgeBase.title": "قاعدة البيانات",
"knowledgeBase.uploadGuide": "يمكنك عرض الملفات التي تم تحميلها في قسم \"الموارد\"",
"knowledgeBase.library.title": "الملفات / المكتبات",
"knowledgeBase.relativeFilesOrLibraries": "الملفات/المكتبات ذات الصلة",
"knowledgeBase.title": "المكتبة",
"knowledgeBase.uploadGuide": "يمكن عرض الملفات المرفوعة في قسم 'الموارد'.",
"knowledgeBase.viewMore": "عرض المزيد",
"memberSelection.addMember": "إضافة عضو",
"memberSelection.allMembers": "جميع الأعضاء",
"memberSelection.createGroup": "إنشاء مجموعة",
"memberSelection.noAvailableAgents": "لا يوجد وكلاء متاحون للدعوة",
"memberSelection.noSelectedAgents": "لم يتم اختيار أي وكيل بعد",
"memberSelection.searchAgents": "ابحث عن وكيل...",
"memberSelection.selectedAgents": "تم الاختيار ({{count}})",
"memberSelection.setInitialMembers": "اختيار أعضاء الفريق",
"memberSelection.noSelectedAgents": "لم يتم تحديد أي وكلاء بعد",
"memberSelection.searchAgents": "البحث عن وكلاء...",
"memberSelection.selectedAgents": "المحددون ({{count}})",
"memberSelection.setInitialMembers": "تحديد أعضاء المجموعة",
"members": "الأعضاء",
"mention.title": "الإشارة إلى الأعضاء",
"messageAction.collapse": "إخفاء الرسائل",
"messageAction.collapse": "طي الرسالة",
"messageAction.continueGeneration": "متابعة التوليد",
"messageAction.delAndRegenerate": "حذف وإعادة الإنشاء",
"messageAction.deleteDisabledByThreads": "يوجد موضوعات فرعية، لا يمكن الحذف",
"messageAction.expand": رض الرسائل",
"messageAction.regenerate": "إعادة الإنشاء",
"messageAction.delAndRegenerate": "حذف وإعادة التوليد",
"messageAction.deleteDisabledByThreads": "لا يمكن حذف هذه الرسالة لأنها تحتوي على موضوع فرعي",
"messageAction.expand": "توسيع الرسالة",
"messageAction.regenerate": "إعادة التوليد",
"messages.dm.sentTo": "مرئي فقط لـ {{name}}",
"messages.dm.title": "الرسائل الخاصة",
"messages.modelCard.credit": "نقاط",
"messages.dm.title": "رسالة خاصة",
"messages.modelCard.credit": "الأرصدة",
"messages.modelCard.creditPricing": "التسعير",
"messages.modelCard.creditTooltip": تسهيل العد، نقوم بتحويل 1$ إلى 1M نقطة، على سبيل المثال، 3$/M رموز تعني 3 نقاط/رمز",
"messages.modelCard.pricing.inputCachedTokens": "مدخلات مخزنة {{amount}}/نقطة · ${{amount}}/M",
"messages.modelCard.pricing.inputCharts": "${{amount}}/M حرف",
"messages.modelCard.creditTooltip": أغراض العد، نعتبر 1 دولار = 1 مليون رصيد. مثال: 3 دولارات/مليون رموز → 3 أرصدة لكل رمز.",
"messages.modelCard.pricing.inputCachedTokens": "المدخلات المخزنة {{amount}} أرصدة · ${{amount}}/مليون",
"messages.modelCard.pricing.inputCharts": "${{amount}}/مليون حرف",
"messages.modelCard.pricing.inputMinutes": "${{amount}}/دقيقة",
"messages.modelCard.pricing.inputTokens": "مدخلات {{amount}}/نقطة · ${{amount}}/M",
"messages.modelCard.pricing.outputTokens": "مخرجات {{amount}}/نقطة · ${{amount}}/M",
"messages.modelCard.pricing.writeCacheInputTokens": "تخزين إدخال الكتابة {{amount}}/نقطة · ${{amount}}/ميغابايت",
"messages.tokenDetails.average": "متوسط السعر",
"messages.tokenDetails.input": "مدخلات",
"messages.tokenDetails.inputAudio": "مدخلات صوتية",
"messages.tokenDetails.inputCached": "مدخلات مخزنة",
"messages.tokenDetails.inputCitation": "اقتباس الإدخال",
"messages.tokenDetails.inputText": "مدخلات نصية",
"messages.tokenDetails.inputTitle": "تفاصيل المدخلات",
"messages.tokenDetails.inputUncached": "مدخلات غير مخزنة",
"messages.tokenDetails.inputWriteCached": "تخزين إدخال الكتابة",
"messages.tokenDetails.output": "مخرجات",
"messages.tokenDetails.outputAudio": "مخرجات صوتية",
"messages.tokenDetails.outputImage": "إخراج الصورة",
"messages.tokenDetails.outputText": "مخرجات نصية",
"messages.tokenDetails.outputTitle": "تفاصيل المخرجات",
"messages.modelCard.pricing.inputTokens": "المدخلات {{amount}} أرصدة · ${{amount}}/مليون",
"messages.modelCard.pricing.outputTokens": "المخرجات {{amount}} أرصدة · ${{amount}}/مليون",
"messages.modelCard.pricing.writeCacheInputTokens": "كتابة إلى التخزين المؤقت {{amount}} أرصدة · ${{amount}}/مليون",
"messages.tokenDetails.average": "متوسط السعر للوحدة",
"messages.tokenDetails.input": "المدخلات",
"messages.tokenDetails.inputAudio": "مدخل صوتي",
"messages.tokenDetails.inputCached": "مدخل مخزن مؤقتًا",
"messages.tokenDetails.inputCitation": "استشهاد المدخل",
"messages.tokenDetails.inputText": "مدخل نصي",
"messages.tokenDetails.inputTitle": "تفاصيل المدخل",
"messages.tokenDetails.inputUncached": "مدخل غير مخزن مؤقتًا",
"messages.tokenDetails.inputWriteCached": "كتابة إلى التخزين المؤقت للمدخل",
"messages.tokenDetails.output": "المخرجات",
"messages.tokenDetails.outputAudio": "مخرج صوتي",
"messages.tokenDetails.outputImage": "مخرج صورة",
"messages.tokenDetails.outputText": "مخرج نصي",
"messages.tokenDetails.outputTitle": "تفاصيل المخرج",
"messages.tokenDetails.reasoning": "تفكير عميق",
"messages.tokenDetails.speed.tps.title": "TPS",
"messages.tokenDetails.speed.tps.tooltip": "عدد الرموز في الثانية، TPS. يشير إلى متوسط سرعة توليد المحتوى بواسطة الذكاء الاصطناعي (رمز/ثانية)، ويبدأ الحساب عند استلام أول رمز.",
"messages.tokenDetails.speed.tps.tooltip": "الرموز في الثانية (TPS). يشير إلى متوسط سرعة المحتوى الذي يولده الذكاء الاصطناعي (رموز/ثانية)، محسوبًا من لحظة استلام أول رمز.",
"messages.tokenDetails.speed.ttft.title": "TTFT",
"messages.tokenDetails.speed.ttft.tooltip": "الوقت حتى أول رمز، TTFT. يشير إلى الفارق الزمني من لحظة إرسال الرسالة حتى استلام أول رمز في العميل.",
"messages.tokenDetails.speed.ttft.tooltip": "الوقت لأول رمز (TTFT). يشير إلى الفترة الزمنية من إرسال الرسالة إلى استلام أول رمز من العميل.",
"messages.tokenDetails.title": "تفاصيل التوليد",
"messages.tokenDetails.total": "الإجمالي المستهلك",
"minimap.jumpToMessage": "الانتقال إلى الرسالة رقم {{index}}",
"messages.tokenDetails.total": "الاستهلاك الكلي",
"minimap.jumpToMessage": "الانتقال إلى الرسالة {{index}}",
"minimap.nextMessage": "الرسالة التالية",
"minimap.previousMessage": "الرسالة السابقة",
"minimap.senderAssistant": "الوكيل",
"minimap.senderUser": "أنت",
"newAgent": "إنشاء مساعد",
"newAgent": "إنشاء وكيل",
"newGroupChat": "إنشاء مجموعة",
"newPage": "إنشاء مستند",
"noAgentsYet": "لا يوجد أعضاء في هذه المجموعة بعد. انقر على زر + لدعوة مساعد.",
"newPage": "إنشاء صفحة",
"noAgentsYet": "لا يوجد أعضاء في هذه المجموعة بعد. انقر على زر + لدعوة وكلاء.",
"noAvailableAgents": "لا يوجد أعضاء متاحون للدعوة",
"noMatchingAgents": ا يوجد أعضاء مطابقون",
"noMembersYet": "لا يوجد أعضاء في هذه المجموعة بعد. انقر على زر + لدعوة المساعدين.",
"noSelectedAgents": "لم يتم اختيار أي أعضاء بعد",
"openInNewWindow": "فتح في نافذة مستقلة",
"noMatchingAgents": م يتم العثور على أعضاء مطابقين",
"noMembersYet": "لا تحتوي هذه المجموعة على أي أعضاء بعد. انقر على زر + لدعوة وكلاء.",
"noSelectedAgents": "لم يتم تحديد أي أعضاء بعد",
"openInNewWindow": "فتح في نافذة جديدة",
"owner": "مالك المجموعة",
"pageCopilot.title": "مساعد النصوص",
"pageCopilot.welcome": "**لنجعل كل جملة أكثر دقة.**\n\nسواء كنت تكتب مسودة، تعيد الصياغة، أو تقوم بالتحرير، سأساعدك في جعل كلماتك أوضح، أكثر طبيعية، وأكثر إقناعًا.",
"pageCopilot.title": "وكيل الصفحة",
"pageCopilot.welcome": "**كتابة أوضح وأكثر دقة**\n\nاكتب مسودة أو أعد الصياغة أو حسّن—أخبرني بنيتك وسأتولى الباقي.",
"pin": "تثبيت",
"pinOff": "إلغاء التثبيت",
"prompts.summaryExpert": "بصفتك خبيرًا في التلخيص، يرجى استخدام الإرشادات أعلاه لتلخيص المحتوى التالي:",
"rag.referenceChunks": "مراجع",
"rag.userQuery.actions.delete": "حذف الاستعلام",
"prompts.summaryExpert": "بصفتك خبيرًا في التلخيص، يرجى تلخيص المحتوى التالي بناءً على التعليمات أعلاه:",
"rag.referenceChunks": صدر المرجع",
"rag.userQuery.actions.delete": "حذف إعادة صياغة الاستعلام",
"rag.userQuery.actions.regenerate": "إعادة توليد الاستعلام",
"regenerate": "إعادة الإنشاء",
"roleAndArchive": "الدور والأرشيف",
"regenerate": "إعادة التوليد",
"roleAndArchive": "ملف الوكيل وسجل المحادثات",
"search.grounding.searchQueries": "كلمات البحث",
"search.grounding.title": "تم العثور على {{count}} نتيجة",
"search.mode.auto.desc": "تحديد ما إذا كان من الضروري البحث بناءً على محتوى المحادثة",
"search.mode.auto.title": "الاتصال الذكي",
"search.mode.off.desc": "استخدام المعرفة الأساسية للنموذج فقط، دون إجراء بحث عبر الإنترنت",
"search.mode.off.title": "إيقاف الاتصال",
"search.mode.on.desc": "الاستمرار في البحث عبر الإنترنت للحصول على أحدث المعلومات",
"search.mode.on.title": "الاتصال دائمًا",
"search.mode.useModelBuiltin": "استخدام محرك البحث المدمج في النموذج",
"search.searchModel.desc": "النموذج الحالي لا يدعم استدعاء الدوال، لذا يجب استخدام نموذج يدعم استدعاء الدوال للبحث عبر الإنترنت",
"search.searchModel.title": "نموذج البحث المساعد",
"search.title": "بحث عبر الإنترنت",
"searchAgentPlaceholder": "مساعد البحث...",
"searchAgents": "مساعد البحث...",
"selectedAgents": "المساعدون المختارون",
"sendPlaceholder": "اطرح سؤالًا، أنشئ محتوى، أو ابدأ مهمة، <hotkey><hotkey/>",
"sessionGroup.config": "إدارة المجموعات",
"sessionGroup.confirmRemoveGroupAlert": "سيتم حذف هذه المجموعة قريبًا، وبعد الحذف، سيتم نقل مساعدي هذه المجموعة إلى القائمة الافتراضية، يرجى تأكيد إجراءك",
"sessionGroup.createAgentSuccess": "تم إنشاء المساعد بنجاح",
"search.mode.auto.desc": "البحث في الويب تلقائيًا عند الحاجة.",
"search.mode.auto.title": "تلقائي",
"search.mode.off.desc": "تعطيل الوصول إلى الإنترنت.",
"search.mode.off.title": "إيقاف",
"search.mode.on.desc": "البحث دائمًا في الويب للحصول على أحدث المعلومات.",
"search.mode.on.title": "دائمًا مفعّل",
"search.mode.useModelBuiltin": "استخدام البحث المدمج في النموذج",
"search.searchModel.desc": "النموذج الحالي لا يدعم استدعاء الوظائف، لذا يجب إقرانه بنموذج يدعم ذلك للبحث عبر الإنترنت.",
"search.searchModel.title": "نموذج مساعد للبحث",
"search.title": "بحث الويب",
"searchAgentPlaceholder": "البحث عن وكلاء...",
"searchAgents": "البحث عن وكلاء...",
"selectedAgents": "الوكلاء المحددون",
"sendPlaceholder": "اطرح سؤالًا، أنشئ، أو ابدأ مهمة، <hotkey><hotkey/>",
"sessionGroup.config": "إدارة المجموعة",
"sessionGroup.confirmRemoveGroupAlert": "سيتم حذف هذه المجموعة. بعد الحذف، سيتم نقل الوكلاء إلى القائمة الافتراضية. يرجى تأكيد العملية.",
"sessionGroup.createAgentSuccess": "تم إنشاء الوكيل بنجاح",
"sessionGroup.createGroup": "إضافة مجموعة جديدة",
"sessionGroup.createGroupFailed": "فشل إنشاء المحادثة الجماعية",
"sessionGroup.createGroupFailed": "فشل في إنشاء محادثة جماعية",
"sessionGroup.createGroupSuccess": "تم إنشاء المحادثة الجماعية بنجاح",
"sessionGroup.createSuccess": "تم الإنشاء بنجاح",
"sessionGroup.creatingAgent": "جاري إنشاء المساعد...",
"sessionGroup.creatingAgent": "جارٍ إنشاء الوكيل...",
"sessionGroup.groupName": "اسم المجموعة",
"sessionGroup.inputPlaceholder": "الرجاء إدخال اسم المجموعة...",
"sessionGroup.inputPlaceholder": "يرجى إدخال اسم المجموعة...",
"sessionGroup.moveGroup": "نقل إلى مجموعة",
"sessionGroup.newGroup": "مجموعة جديدة",
"sessionGroup.noAvailableAgents": "لا يوجد مساعدين متاحين حالياً",
"sessionGroup.noMatchingAgents": "لم يتم العثور على مساعدين مطابقين",
"sessionGroup.noSelectedAgents": "يرجى اختيار مساعدين",
"sessionGroup.noAvailableAgents": "لا يوجد وكلاء متاحون",
"sessionGroup.noMatchingAgents": "لم يتم العثور على وكلاء مطابقين",
"sessionGroup.noSelectedAgents": "يرجى تحديد وكلاء",
"sessionGroup.rename": "إعادة تسمية المجموعة",
"sessionGroup.renameSuccess": "تمت إعادة التسمية بنجاح",
"sessionGroup.searchAgents": "البحث عن مساعدين",
"sessionGroup.selectedAgents": "المساعدون المختارون ({{count}})",
"sessionGroup.sortSuccess": "تمت إعادة ترتيب بنجاح",
"sessionGroup.sorting": "جاري تحديث ترتيب المجموعة...",
"sessionGroup.tooLong": "يجب أن يكون طول اسم المجموعة بين 1 و 20",
"sessionGroup.searchAgents": "البحث عن وكلاء",
"sessionGroup.selectedAgents": "الوكلاء المحددون ({{count}})",
"sessionGroup.sortSuccess": "تم الترتيب بنجاح",
"sessionGroup.sorting": "جارٍ تحديث ترتيب المجموعات...",
"sessionGroup.tooLong": "يجب أن يتراوح طول اسم المجموعة بين 1 و20 حرفًا",
"shareModal.copy": "نسخ",
"shareModal.download": "تحميل اللقطة",
"shareModal.downloadError": "فشل التنزيل",
"shareModal.download": "تحميل لقطة شاشة",
"shareModal.downloadError": "فشل التحميل",
"shareModal.downloadFile": "تحميل الملف",
"shareModal.downloadPdf": نزيل PDF",
"shareModal.downloadSuccess": "تم التنزيل بنجاح",
"shareModal.downloadPdf": حميل PDF",
"shareModal.downloadSuccess": "تم التحميل بنجاح",
"shareModal.exportMode.full": "افتراضي",
"shareModal.exportMode.label": "وضع التصدير",
"shareModal.exportMode.simple": "متوافق مع OpenAI",
"shareModal.exportPdf": "تصدير إلى PDF",
"shareModal.exportPdf": "تصدير كـ PDF",
"shareModal.exportTitle": "العنوان الافتراضي",
"shareModal.generatePdf": "إنشاء ملف PDF",
"shareModal.generatePdf": "إنشاء PDF",
"shareModal.generatingPdf": "جارٍ إنشاء PDF...",
"shareModal.imageType": "نوع الصورة",
"shareModal.includeTool": "تضمين رسالة الأداة",
"shareModal.includeUser": "تضمين رسالة المستخدم",
"shareModal.loadingPdf": "جارٍ تحميل ملف PDF...",
"shareModal.noPdfData": "لا توجد بيانات PDF",
"shareModal.imageType": "تنسيق الصورة",
"shareModal.includeTool": "تضمين رسائل المهارة",
"shareModal.includeUser": "تضمين رسائل المستخدم",
"shareModal.loadingPdf": "جارٍ تحميل PDF...",
"shareModal.noPdfData": "لا توجد بيانات PDF متاحة",
"shareModal.pdf": "PDF",
"shareModal.pdfErrorDescription": "حدث خطأ أثناء إنشاء PDF، يرجى المحاولة مرة أخرى",
"shareModal.pdfGenerationError": "فشل إنشاء PDF",
"shareModal.pdfReady": "تم تجهيز PDF",
"shareModal.regeneratePdf": "إعادة إنشاء ملف PDF",
"shareModal.pdfReady": "PDF جاهز",
"shareModal.regeneratePdf": "إعادة إنشاء PDF",
"shareModal.screenshot": "لقطة شاشة",
"shareModal.settings": "إعدادات التصدير",
"shareModal.text": "نص",
"shareModal.widthMode.label": "وضع العرض",
"shareModal.widthMode.narrow": "وضع الشاشة الضيقة",
"shareModal.widthMode.wide": "وضع الشاشة الواسعة",
"shareModal.widthMode.narrow": "ضيق",
"shareModal.widthMode.wide": "عريض",
"shareModal.withBackground": "تضمين صورة الخلفية",
"shareModal.withFooter": "تضمين تذييل",
"shareModal.withPluginInfo": "تضمين معلومات البرنامج المساعد",
"shareModal.withRole": "تضمين رسالة الدور",
"shareModal.withSystemRole": "تضمين دور المساعد",
"shareModal.withFooter": "تضمين التذييل",
"shareModal.withPluginInfo": "تضمين معلومات المهارة",
"shareModal.withRole": "تضمين دور الرسالة",
"shareModal.withSystemRole": "تضمين ملف الوكيل",
"stt.action": "إدخال صوتي",
"stt.loading": "جارٍ التعرف...",
"stt.prettifying": "جارٍ التجميل...",
"supervisor.todoList.allComplete": "تم إنجاز جميع المهام",
"supervisor.todoList.title": "المهام المنجزة",
"supervisor.label": "المشرف",
"supervisor.todoList.allComplete": "تم إكمال جميع المهام",
"supervisor.todoList.title": "المهام المكتملة",
"tab.groupProfile": "ملف المجموعة",
"tab.profile": "ملف المساعد",
"tab.profile": "ملف الوكيل",
"tab.search": "بحث",
"task.activity.calling": "جارٍ استدعاء الأداة...",
"task.activity.calling": "جارٍ استدعاء المهارة...",
"task.activity.generating": "جارٍ توليد الرد...",
"task.activity.gotResult": "تم الحصول على نتيجة الأداة",
"task.activity.gotResult": "تم استلام نتيجة الأداة",
"task.activity.toolCalling": "جارٍ استدعاء {{toolName}}...",
"task.activity.toolResult": "تم الحصول على نتيجة {{toolName}}",
"task.metrics.stepsShort": "خطوة",
"task.metrics.toolCallsShort": "مرة استخدام الأداة",
"task.status.initializing": "جارٍ بدء المهمة...",
"task.activity.toolResult": "تم استلام نتيجة {{toolName}}",
"task.batchTasks": "{{count}} مهمة فرعية مجمعة",
"task.metrics.stepsShort": "خطوات",
"task.metrics.toolCallsShort": "استخدامات الأداة",
"task.status.cancelled": "تم إلغاء المهمة",
"task.status.failed": "فشلت المهمة",
"task.status.initializing": "جارٍ تهيئة المهمة...",
"task.subtask": "مهمة فرعية",
"thread.divider": "موضوع فرعي",
"thread.threadMessageCount": "{{messageCount}} رسالة",
"thread.title": "موضوع فرعي",
"todoProgress.allCompleted": "تم إكمال جميع المهام",
"todoProgress.title": "المهام",
"toggleWideScreen.off": "إيقاف وضع الشاشة العريضة",
"toggleWideScreen.on": "تشغيل وضع الشاشة العريضة",
"tokenDetails.chats": "رسائل المحادثة",
"tokenDetails.historySummary": "ملخص التاريخ",
"tokenDetails.chats": "رسائل الدردشة",
"tokenDetails.historySummary": "ملخص السجل",
"tokenDetails.rest": "المتبقي",
"tokenDetails.supervisor": ُنسق المجموعة",
"tokenDetails.systemRole": "تعيين الدور",
"tokenDetails.title": "تفاصيل الرمز",
"tokenDetails.tools": "تعيين الإضافات",
"tokenDetails.total": "الإجمالي",
"tokenDetails.used": "المستخدم",
"tokenDetails.supervisor": ضيف المجموعة",
"tokenDetails.systemRole": "إعدادات الدور",
"tokenDetails.title": "تفاصيل السياق",
"tokenDetails.tools": "إعدادات المهارة",
"tokenDetails.total": "الإجمالي المتاح",
"tokenDetails.used": "الإجمالي المستخدم",
"tokenTag.overload": "تجاوز الحد",
"tokenTag.remained": "متبقي",
"tokenTag.used": "مستخدم",
"tool.intervention.approve": "الموافقة",
"tool.intervention.approveAndRemember": "الموافقة والتذكر",
"tool.intervention.approveOnce": "الموافقة لمرة واحدة فقط",
"tokenTag.remained": "المتبقي",
"tokenTag.used": "المستخدم",
"tool.intervention.approve": "موافقة",
"tool.intervention.approveAndRemember": "موافقة وتذكر",
"tool.intervention.approveOnce": "الموافقة هذه المرة فقط",
"tool.intervention.mode.allowList": "قائمة السماح",
"tool.intervention.mode.allowListDesc": "تنفيذ الأدوات المعتمدة فقط تلقائيًا",
"tool.intervention.mode.autoRun": "الموافقة التلقائية",
"tool.intervention.mode.autoRunDesc": "الموافقة تلقائيًا على تنفيذ جميع الأدوات",
"tool.intervention.mode.autoRun": "موافقة تلقائية",
"tool.intervention.mode.autoRunDesc": "الموافقة تلقائيًا على جميع تنفيذات الأدوات",
"tool.intervention.mode.manual": "يدوي",
"tool.intervention.mode.manualDesc": "يتطلب الموافقة اليدوية في كل مرة يتم فيها الاستدعاء",
"tool.intervention.mode.manualDesc": "يتطلب الموافقة اليدوية لكل استدعاء",
"tool.intervention.reject": "رفض",
"tool.intervention.rejectAndContinue": "رفض ثم إعادة المحاولة",
"tool.intervention.rejectAndContinue": "رفض وإعادة المحاولة",
"tool.intervention.rejectOnly": "رفض",
"tool.intervention.rejectReasonPlaceholder": "إدخال سبب الرفض سيساعد الوكيل على الفهم وتحسين الإجراءات المستقبلية",
"tool.intervention.rejectTitle": "رفض استدعاء الأداة هذه المرة",
"tool.intervention.rejectedWithReason": "تم رفض استدعاء الأداة هذه المرة بشكل يدوي: {{reason}}",
"tool.intervention.toolAbort": "تم إلغاء استدعاء الأداة من قبل المستخدم",
"tool.intervention.toolRejected": "تم رفض استدعاء الأداة هذه المرة بشكل يدوي",
"tool.intervention.rejectReasonPlaceholder": "سيساعد السبب الوكيل على فهم حدودك وتحسين التصرفات المستقبلية",
"tool.intervention.rejectTitle": "رفض استدعاء المهارة",
"tool.intervention.rejectedWithReason": "تم رفض استدعاء المهارة: {{reason}}",
"tool.intervention.toolAbort": "لقد ألغيت استدعاء المهارة",
"tool.intervention.toolRejected": "تم رفض استدعاء المهارة",
"toolAuth.authorize": "تفويض",
"toolAuth.authorizing": "جارٍ التفويض...",
"toolAuth.hint": "إذا لم يتم التفويض أو التكوين، فقد لا تعمل هذه الأدوات بشكل صحيح، مما قد يؤدي إلى فقدان وظائف المساعد أو ظهور أخطاء.",
"toolAuth.hint": "بدون التفويض أو الإعداد، قد لا تعمل المهارات. قد يؤدي ذلك إلى تقييد الوكيل أو حدوث أخطاء.",
"toolAuth.signIn": "تسجيل الدخول",
"toolAuth.title": "يرجى إكمال تفويض الأدوات للمساعد",
"topic.checkOpenNewTopic": "هل ترغب في فتح موضوع جديد؟",
"topic.checkSaveCurrentMessages": "هل ترغب في حفظ الدردشة الحالية كموضوع؟",
"toolAuth.title": "تفويض المهارات لهذا الوكيل",
"topic.checkOpenNewTopic": "هل تريد بدء موضوع جديد؟",
"topic.checkSaveCurrentMessages": "هل تريد حفظ المحادثة الحالية كموضوع؟",
"topic.openNewTopic": "فتح موضوع جديد",
"topic.recent": "المواضيع الأخيرة",
"topic.saveCurrentMessages": "حفظ الجلسة الحالية كموضوع",
"translate.action": "ترجمة",
"translate.clear": "مسح الترجمة",
"tts.action": "قراءة صوتية",
"tts.action": "تحويل النص إلى كلام",
"tts.clear": "مسح الصوت",
"untitledAgent": "مساعد بدون اسم",
"untitledGroup": "مجموعة بدون عنوان",
"updateAgent": "تحديث معلومات المساعد",
"untitledAgent": "وكيل بدون اسم",
"untitledGroup": "مجموعة بدون اسم",
"updateAgent": "تحديث معلومات الوكيل",
"upload.action.fileUpload": "رفع ملف",
"upload.action.folderUpload": "رفع مجلد",
"upload.action.imageDisabled": "النموذج الحالي لا يدعم التعرف على الصور، يرجى تغيير النموذج لاستخدامه",
"upload.action.imageDisabled": "النموذج الحالي لا يدعم التعرف البصري. يرجى التبديل إلى نموذج آخر لاستخدام هذه الميزة.",
"upload.action.imageUpload": "رفع صورة",
"upload.action.tooltip": "رفع",
"upload.clientMode.actionFiletip": "رفع ملف",
"upload.clientMode.actionTooltip": "رفع",
"upload.clientMode.disabled": "النموذج الحالي لا يدعم التعرف على الصور وتحليل الملفات، يرجى تغيير النموذج لاستخدامه",
"upload.clientMode.fileNotSupported": "وضع المتصفح لا يدعم تحميل الملفات حاليًا، يدعم الصور فقط",
"upload.clientMode.visionNotSupported": "النموذج الحالي لا يدعم التعرف البصري، يرجى تبديل النموذج لاستخدام هذه الميزة",
"upload.preview.prepareTasks": "تحضير الأجزاء...",
"upload.preview.status.pending": "يتم التحضير للتحميل...",
"upload.preview.status.processing": "يتم معالجة الملف...",
"upload.validation.videoSizeExceeded": "لا يمكن أن يتجاوز حجم ملف الفيديو 20 ميغابايت، حجم الملف الحالي هو {{actualSize}}",
"viewMode.normal": "عادي",
"upload.clientMode.disabled": "النموذج الحالي لا يدعم التعرف البصري وتحليل الملفات. يرجى التبديل إلى نموذج آخر لاستخدام هذه الميزة.",
"upload.clientMode.fileNotSupported": "رفع الملفات غير مدعوم في وضع المتصفح؛ يُسمح فقط بالصور.",
"upload.clientMode.visionNotSupported": "النموذج الحالي لا يدعم التعرف البصري. يرجى التبديل إلى نموذج مختلف لاستخدام هذه الميزة.",
"upload.preview.prepareTasks": "جارٍ تجهيز الأجزاء...",
"upload.preview.status.pending": "جارٍ التحضير للرفع...",
"upload.preview.status.processing": "جارٍ معالجة الملف...",
"upload.validation.videoSizeExceeded": "يجب ألا يتجاوز حجم ملف الفيديو 20 ميغابايت. الحجم الحالي هو {{actualSize}}.",
"viewMode.fullWidth": "العرض الكامل",
"viewMode.normal": "قياسي",
"viewMode.wideScreen": "شاشة عريضة",
"you": "أنت",
"zenMode": "وضع التركيز"
+272 -272
View File
@@ -1,40 +1,40 @@
{
"backButton": "الرجوع",
"backButton": "رجوع",
"badge__default": "افتراضي",
"badge__otherImpersonatorDevice": "جهاز تمثيل آخر",
"badge__primary": "أساسي",
"badge__otherImpersonatorDevice": "جهاز انتحال آخر",
"badge__primary": "رئيسي",
"badge__requiresAction": "يتطلب إجراء",
"badge__thisDevice": "هذا الجهاز",
"badge__unverified": "غير موثق",
"badge__unverified": "غير مُحقق",
"badge__userDevice": "جهاز المستخدم",
"badge__you": "أنت",
"createOrganization.formButtonSubmit": "إنشاء منظمة",
"createOrganization.invitePage.formButtonReset": "تخطي",
"createOrganization.title": "إنشاء منظمة",
"dates.lastDay": "أمس في {{ date | timeString('en-US') }}",
"dates.next6Days": "{{ date | weekday('en-US','long') }} في {{ date | timeString('en-US') }}",
"dates.nextDay": "غدًا في {{ date | timeString('en-US') }}",
"dates.numeric": "{{ date | numeric('en-US') }}",
"dates.previous6Days": "الماضي {{ date | weekday('en-US','long') }} في {{ date | timeString('en-US') }}",
"dates.sameDay": "اليوم في {{ date | timeString('en-US') }}",
"dates.lastDay": "أمس في {{ date | timeString('ar') }}",
"dates.next6Days": "{{ date | weekday('ar','long') }} في {{ date | timeString('ar') }}",
"dates.nextDay": "غدًا في {{ date | timeString('ar') }}",
"dates.numeric": "{{ date | numeric('ar') }}",
"dates.previous6Days": "{{ date | weekday('ar','long') }} الماضي في {{ date | timeString('ar') }}",
"dates.sameDay": "اليوم في {{ date | timeString('ar') }}",
"dividerText": "أو",
"footerActionLink__useAnotherMethod": "استخدام طريقة أخرى",
"footerPageLink__help": "المساعدة",
"footerActionLink__useAnotherMethod": "استخدم طريقة أخرى",
"footerPageLink__help": "مساعدة",
"footerPageLink__privacy": "الخصوصية",
"footerPageLink__terms": "البنود",
"footerPageLink__terms": "الشروط",
"formButtonPrimary": "متابعة",
"formButtonPrimary__verify": "التحقق",
"formButtonPrimary__verify": "تحقق",
"formFieldAction__forgotPassword": "هل نسيت كلمة المرور؟",
"formFieldError__matchingPasswords": "تتطابق كلمات المرور.",
"formFieldError__matchingPasswords": "كلمات المرور متطابقة.",
"formFieldError__notMatchingPasswords": "كلمات المرور غير متطابقة.",
"formFieldError__verificationLinkExpired": "انتهت صلاحية رابط التحقق. يرجى طلب رابط جديد.",
"formFieldHintText__optional": "اختياري",
"formFieldHintText__slug": "الـ Slug هو معرف يمكن قراءته بواسطة الإنسان ويجب أن يكون فريدًا. غالبًا ما يُستخدم في عناوين URL.",
"formFieldHintText__slug": "المُعرف هو اسم قابل للقراءة يجب أن يكون فريدًا. غالبًا ما يُستخدم في عناوين الروابط.",
"formFieldInputPlaceholder__backupCode": "",
"formFieldInputPlaceholder__confirmDeletionUserAccount": "حذف الحساب",
"formFieldInputPlaceholder__emailAddress": "",
"formFieldInputPlaceholder__emailAddress_username": "",
"formFieldInputPlaceholder__emailAddresses": "example@email.com, example2@email.com",
"formFieldInputPlaceholder__emailAddresses": "example@email.com، example2@email.com",
"formFieldInputPlaceholder__firstName": "",
"formFieldInputPlaceholder__lastName": "",
"formFieldInputPlaceholder__organizationDomain": "",
@@ -45,373 +45,373 @@
"formFieldInputPlaceholder__phoneNumber": "",
"formFieldInputPlaceholder__username": "",
"formFieldLabel__automaticInvitations": "تمكين الدعوات التلقائية لهذا النطاق",
"formFieldLabel__backupCode": "رمز النسخ الاحتياطي",
"formFieldLabel__backupCode": "رمز احتياطي",
"formFieldLabel__confirmDeletion": "تأكيد",
"formFieldLabel__confirmPassword": "تأكيد كلمة المرور",
"formFieldLabel__currentPassword": "كلمة المرور الحالية",
"formFieldLabel__emailAddress": "عنوان البريد الإلكتروني",
"formFieldLabel__emailAddress_username": "عنوان البريد الإلكتروني أو اسم المستخدم",
"formFieldLabel__emailAddress_username": "البريد الإلكتروني أو اسم المستخدم",
"formFieldLabel__emailAddresses": "عناوين البريد الإلكتروني",
"formFieldLabel__firstName": "الاسم الأول",
"formFieldLabel__lastName": "الاسم الأخير",
"formFieldLabel__lastName": "اسم العائلة",
"formFieldLabel__newPassword": "كلمة مرور جديدة",
"formFieldLabel__organizationDomain": "نطاق",
"formFieldLabel__organizationDomain": "النطاق",
"formFieldLabel__organizationDomainDeletePending": "حذف الدعوات والاقتراحات المعلقة",
"formFieldLabel__organizationDomainEmailAddress": "عنوان البريد الإلكتروني للتحقق",
"formFieldLabel__organizationDomainEmailAddressDescription": "أدخل عنوان بريد إلكتروني تحت هذا النطاق لتلقي رمز والتحقق من هذا النطاق.",
"formFieldLabel__organizationDomainEmailAddressDescription": "أدخل عنوان بريد إلكتروني ضمن هذا النطاق لتلقي رمز والتحقق من النطاق.",
"formFieldLabel__organizationName": "الاسم",
"formFieldLabel__organizationSlug": "Slug",
"formFieldLabel__passkeyName": "اسم مفتاح الوصول",
"formFieldLabel__organizationSlug": "المُعرف",
"formFieldLabel__passkeyName": "اسم مفتاح المرور",
"formFieldLabel__password": "كلمة المرور",
"formFieldLabel__phoneNumber": "رقم الهاتف",
"formFieldLabel__role": "الدور",
"formFieldLabel__signOutOfOtherSessions": "تسجيل الخروج من جميع الأجهزة الأخرى",
"formFieldLabel__username": "اسم المستخدم",
"impersonationFab.action__signOut": "تسجيل الخروج",
"impersonationFab.title": "تم تسجيل الدخول بواسطة {{identifier}}",
"impersonationFab.title": "تم تسجيل الدخول كـ {{identifier}}",
"locale": "ar",
"maintenanceMode": حن حاليًا في وضع الصيانة، ولكن لا تقلق، لن يستغرق الأمر أكثر من بضع دقائق.",
"maintenanceMode": قوم حاليًا بأعمال صيانة، لا تقلق، لن تستغرق أكثر من بضع دقائق.",
"membershipRole__admin": "مسؤول",
"membershipRole__basicMember": "عضو",
"membershipRole__guestMember": "ضيف",
"membershipRole__guestMember": "زائر",
"organizationList.action__createOrganization": "إنشاء منظمة",
"organizationList.action__invitationAccept": "الانضمام",
"organizationList.action__invitationAccept": "انضمام",
"organizationList.action__suggestionsAccept": "طلب الانضمام",
"organizationList.createOrganization": "إنشاء منظمة",
"organizationList.invitationAcceptedLabel": "انضمام",
"organizationList.subtitle": "لمتابعة {{applicationName}}",
"organizationList.suggestionsAcceptedLabel": "في انتظار الموافقة",
"organizationList.invitationAcceptedLabel": "تم الانضمام",
"organizationList.subtitle": لمتابعة إلى {{applicationName}}",
"organizationList.suggestionsAcceptedLabel": "بانتظار الموافقة",
"organizationList.title": "اختر حسابًا",
"organizationList.titleWithoutPersonal": "اختر منظمة",
"organizationProfile.badge__automaticInvitation": "دعوات تلقائية",
"organizationProfile.badge__automaticSuggestion": "اقتراحات تلقائية",
"organizationProfile.badge__manualInvitation": "لا تسجيل تلقائي",
"organizationProfile.badge__unverified": "غير موثق",
"organizationProfile.createDomainPage.subtitle": "أضف النطاق للتحقق. يمكن للمستخدمين الذين لديهم عناوين بريد إلكتروني في هذا النطاق الانضمام إلى المنظمة تلقائيًا أو طلب الانضمام.",
"organizationProfile.createDomainPage.title": "إضافة النطاق",
"organizationProfile.invitePage.detailsTitle__inviteFailed": "تعذر إرسال الدعوات. هناك دعوات معلقة بالفعل لعناوين البريد الإلكتروني التالية: {{email_addresses}}.",
"organizationProfile.badge__manualInvitation": "لا يوجد تسجيل تلقائي",
"organizationProfile.badge__unverified": "غير مُحقق",
"organizationProfile.createDomainPage.subtitle": "أضف النطاق للتحقق. يمكن للمستخدمين الذين لديهم بريد إلكتروني ضمن هذا النطاق الانضمام تلقائيًا أو طلب الانضمام.",
"organizationProfile.createDomainPage.title": "إضافة نطاق",
"organizationProfile.invitePage.detailsTitle__inviteFailed": "تعذر إرسال الدعوات. هناك دعوات معلقة بالفعل لعناوين البريد التالية: {{email_addresses}}.",
"organizationProfile.invitePage.formButtonPrimary__continue": "إرسال الدعوات",
"organizationProfile.invitePage.selectDropdown__role": "اختر الدور",
"organizationProfile.invitePage.subtitle": "أدخل أو الصق عناوين بريد إلكتروني واحدة أو أكثر، مفصولة بمسافات أو فواصل.",
"organizationProfile.invitePage.subtitle": "أدخل أو الصق عنوانًا أو أكثر من عناوين البريد الإلكتروني، مفصولة بمسافات أو فواصل.",
"organizationProfile.invitePage.successMessage": "تم إرسال الدعوات بنجاح",
"organizationProfile.invitePage.title": "دعوة أعضاء جدد",
"organizationProfile.membersPage.action__invite": "دعوة",
"organizationProfile.membersPage.activeMembersTab.menuAction__remove": "إزالة العضو",
"organizationProfile.membersPage.activeMembersTab.tableHeader__actions": "",
"organizationProfile.membersPage.activeMembersTab.tableHeader__joined": "انضم",
"organizationProfile.membersPage.activeMembersTab.tableHeader__joined": "تاريخ الانضمام",
"organizationProfile.membersPage.activeMembersTab.tableHeader__role": "الدور",
"organizationProfile.membersPage.activeMembersTab.tableHeader__user": "المستخدم",
"organizationProfile.membersPage.detailsTitle__emptyRow": "لا يوجد أعضاء لعرضهم",
"organizationProfile.membersPage.invitationsTab.autoInvitations.headerSubtitle": "قم بدعوة المستخدمين عن طريق ربط نطاق البريد الإلكتروني بالمنظمة. سيتمكن أي شخص يسجل الدخول بنطاق بريد إلكتروني متطابق من الانضمام إلى المنظمة في أي وقت.",
"organizationProfile.membersPage.invitationsTab.autoInvitations.headerSubtitle": "ادعُ المستخدمين من خلال ربط نطاق بريد إلكتروني بمنظمتك. سيتمكن أي شخص يسجل بعنوان بريد مطابق من الانضمام في أي وقت.",
"organizationProfile.membersPage.invitationsTab.autoInvitations.headerTitle": "دعوات تلقائية",
"organizationProfile.membersPage.invitationsTab.autoInvitations.primaryButton": "إدارة النطاقات الموثقة",
"organizationProfile.membersPage.invitationsTab.autoInvitations.primaryButton": "إدارة النطاقات المُحققة",
"organizationProfile.membersPage.invitationsTab.table__emptyRow": "لا توجد دعوات لعرضها",
"organizationProfile.membersPage.invitedMembersTab.menuAction__revoke": "إلغاء الدعوة",
"organizationProfile.membersPage.invitedMembersTab.tableHeader__invited": مت الدعوة",
"organizationProfile.membersPage.requestsTab.autoSuggestions.headerSubtitle": "المستخدمون الذين يسجلون الدخول بنطاق بريد إلكتروني متطابق، سيتمكنون من رؤية اقتراح لطلب الانضمام إلى منظمتك.",
"organizationProfile.membersPage.invitedMembersTab.tableHeader__invited": اريخ الدعوة",
"organizationProfile.membersPage.requestsTab.autoSuggestions.headerSubtitle": "المستخدمون الذين يسجلون بعنوان بريد إلكتروني مطابق، سيتمكنون من رؤية اقتراح لطلب الانضمام إلى منظمتك.",
"organizationProfile.membersPage.requestsTab.autoSuggestions.headerTitle": "اقتراحات تلقائية",
"organizationProfile.membersPage.requestsTab.autoSuggestions.primaryButton": "إدارة النطاقات الموثقة",
"organizationProfile.membersPage.requestsTab.menuAction__approve": "الموافقة",
"organizationProfile.membersPage.requestsTab.autoSuggestions.primaryButton": "إدارة النطاقات المُحققة",
"organizationProfile.membersPage.requestsTab.menuAction__approve": "موافقة",
"organizationProfile.membersPage.requestsTab.menuAction__reject": "رفض",
"organizationProfile.membersPage.requestsTab.tableHeader__requested": "طلب الوصول",
"organizationProfile.membersPage.requestsTab.table__emptyRow": "لا توجد طلبات لعرضها",
"organizationProfile.membersPage.start.headerTitle__invitations": "دعوات",
"organizationProfile.membersPage.start.headerTitle__members": "أعضاء",
"organizationProfile.membersPage.start.headerTitle__requests": "طلبات",
"organizationProfile.membersPage.start.headerTitle__invitations": "الدعوات",
"organizationProfile.membersPage.start.headerTitle__members": "الأعضاء",
"organizationProfile.membersPage.start.headerTitle__requests": "الطلبات",
"organizationProfile.navbar.description": "إدارة منظمتك.",
"organizationProfile.navbar.general": "عام",
"organizationProfile.navbar.members": "أعضاء",
"organizationProfile.navbar.members": "الأعضاء",
"organizationProfile.navbar.title": "المنظمة",
"organizationProfile.profilePage.dangerSection.deleteOrganization.actionDescription": "اكتب \"{{organizationName}}\" أدناه للمتابعة.",
"organizationProfile.profilePage.dangerSection.deleteOrganization.messageLine1": "هل أنت متأكد أنك تريد حذف هذه المنظمة؟",
"organizationProfile.profilePage.dangerSection.deleteOrganization.messageLine1": "هل أنت متأكد أنك تريد حذف هذه المؤسسة؟",
"organizationProfile.profilePage.dangerSection.deleteOrganization.messageLine2": "هذا الإجراء دائم ولا يمكن التراجع عنه.",
"organizationProfile.profilePage.dangerSection.deleteOrganization.successMessage": "لقد حذفت المنظمة.",
"organizationProfile.profilePage.dangerSection.deleteOrganization.title": "حذف المنظمة",
"organizationProfile.profilePage.dangerSection.deleteOrganization.successMessage": "تم حذف المؤسسة.",
"organizationProfile.profilePage.dangerSection.deleteOrganization.title": "حذف المؤسسة",
"organizationProfile.profilePage.dangerSection.leaveOrganization.actionDescription": "اكتب \"{{organizationName}}\" أدناه للمتابعة.",
"organizationProfile.profilePage.dangerSection.leaveOrganization.messageLine1": "هل أنت متأكد أنك تريد مغادرة هذه المنظمة؟ ستفقد الوصول إلى هذه المنظمة وتطبيقاتها.",
"organizationProfile.profilePage.dangerSection.leaveOrganization.messageLine1": "هل أنت متأكد أنك تريد مغادرة هذه المؤسسة؟ ستفقد الوصول إلى هذه المؤسسة وتطبيقاتها.",
"organizationProfile.profilePage.dangerSection.leaveOrganization.messageLine2": "هذا الإجراء دائم ولا يمكن التراجع عنه.",
"organizationProfile.profilePage.dangerSection.leaveOrganization.successMessage": "لقد غادرت المنظمة.",
"organizationProfile.profilePage.dangerSection.leaveOrganization.title": "مغادرة المنظمة",
"organizationProfile.profilePage.dangerSection.leaveOrganization.successMessage": "لقد غادرت المؤسسة.",
"organizationProfile.profilePage.dangerSection.leaveOrganization.title": "مغادرة المؤسسة",
"organizationProfile.profilePage.dangerSection.title": "خطر",
"organizationProfile.profilePage.domainSection.menuAction__manage": "إدارة",
"organizationProfile.profilePage.domainSection.menuAction__remove": "حذف",
"organizationProfile.profilePage.domainSection.menuAction__verify": "التحقق",
"organizationProfile.profilePage.domainSection.primaryButton": "إضافة النطاق",
"organizationProfile.profilePage.domainSection.subtitle": "اسمح للمستخدمين بالانضمام إلى المنظمة تلقائيًا أو طلب الانضمام بناءً على نطاق بريد إلكتروني موثق.",
"organizationProfile.profilePage.domainSection.title": "النطاقات الموثقة",
"organizationProfile.profilePage.successMessage": "تم تحديث المنظمة.",
"organizationProfile.profilePage.domainSection.menuAction__verify": "تحقق",
"organizationProfile.profilePage.domainSection.primaryButton": "إضافة نطاق",
"organizationProfile.profilePage.domainSection.subtitle": "اسمح للمستخدمين بالانضمام تلقائيًا إلى المؤسسة أو طلب الانضمام بناءً على نطاق بريد إلكتروني تم التحقق منه.",
"organizationProfile.profilePage.domainSection.title": "النطاقات التي تم التحقق منها",
"organizationProfile.profilePage.successMessage": "تم تحديث المؤسسة.",
"organizationProfile.profilePage.title": "تحديث الملف الشخصي",
"organizationProfile.removeDomainPage.messageLine1": "سيتم إزالة نطاق البريد الإلكتروني {{domain}}.",
"organizationProfile.removeDomainPage.messageLine2": "لن يتمكن المستخدمون من الانضمام إلى المنظمة تلقائيًا بعد ذلك.",
"organizationProfile.removeDomainPage.messageLine2": "لن يتمكن المستخدمون من الانضمام تلقائيًا إلى المؤسسة بعد ذلك.",
"organizationProfile.removeDomainPage.successMessage": "تمت إزالة {{domain}}.",
"organizationProfile.removeDomainPage.title": "إزالة النطاق",
"organizationProfile.start.headerTitle__general": "عام",
"organizationProfile.start.headerTitle__members": "أعضاء",
"organizationProfile.start.headerTitle__members": "الأعضاء",
"organizationProfile.start.profileSection.primaryButton": "تحديث الملف الشخصي",
"organizationProfile.start.profileSection.title": "ملف المنظمة",
"organizationProfile.start.profileSection.uploadAction__title": "شعار",
"organizationProfile.verifiedDomainPage.dangerTab.calloutInfoLabel": "سيؤثر إزالة هذا النطاق على المستخدمين المدعوين.",
"organizationProfile.start.profileSection.title": "ملف المؤسسة",
"organizationProfile.start.profileSection.uploadAction__title": "الشعار",
"organizationProfile.verifiedDomainPage.dangerTab.calloutInfoLabel": "إزالة هذا النطاق سيؤثر على المستخدمين المدعوين.",
"organizationProfile.verifiedDomainPage.dangerTab.removeDomainActionLabel__remove": "إزالة النطاق",
"organizationProfile.verifiedDomainPage.dangerTab.removeDomainSubtitle": "قم بإزالة هذا النطاق من نطاقاتك الموثقة",
"organizationProfile.verifiedDomainPage.dangerTab.removeDomainSubtitle": "إزالة هذا النطاق من قائمة النطاقات التي تم التحقق منها",
"organizationProfile.verifiedDomainPage.dangerTab.removeDomainTitle": "إزالة النطاق",
"organizationProfile.verifiedDomainPage.enrollmentTab.automaticInvitationOption__description": "يتم دعوة المستخدمين تلقائيًا للانضمام إلى المنظمة عند تسجيلهم، ويمكنهم الانضمام في أي وقت.",
"organizationProfile.verifiedDomainPage.enrollmentTab.automaticInvitationOption__description": "يتم دعوة المستخدمين تلقائيًا للانضمام إلى المؤسسة عند التسجيل ويمكنهم الانضمام في أي وقت.",
"organizationProfile.verifiedDomainPage.enrollmentTab.automaticInvitationOption__label": "دعوات تلقائية",
"organizationProfile.verifiedDomainPage.enrollmentTab.automaticSuggestionOption__description": "يتلقى المستخدمون اقتراحًا لطلب الانضمام، ولكن يجب أن يتمتعوا بموافقة من مسؤول قبل الانضمام إلى المنظمة.",
"organizationProfile.verifiedDomainPage.enrollmentTab.automaticSuggestionOption__description": "يتلقى المستخدمون اقتراحًا بطلب الانضمام، ولكن يجب الموافقة عليهم من قبل مسؤول قبل الانضمام.",
"organizationProfile.verifiedDomainPage.enrollmentTab.automaticSuggestionOption__label": "اقتراحات تلقائية",
"organizationProfile.verifiedDomainPage.enrollmentTab.calloutInfoLabel": "تؤثر تغيير وضع التسجيل فقط على المستخدمين الجدد.",
"organizationProfile.verifiedDomainPage.enrollmentTab.calloutInvitationCountLabel": "الدعوات المعلقة المرسلة للمستخدمين: {{count}}",
"organizationProfile.verifiedDomainPage.enrollmentTab.calloutSuggestionCountLabel": "الاقتراحات المعلقة المرسلة للمستخدمين: {{count}}",
"organizationProfile.verifiedDomainPage.enrollmentTab.manualInvitationOption__description": "يمكن فقط دعوة المستخدمين يدويًا إلى المنظمة.",
"organizationProfile.verifiedDomainPage.enrollmentTab.manualInvitationOption__label": "لا تسجيل تلقائي",
"organizationProfile.verifiedDomainPage.enrollmentTab.subtitle": "اختر كيف يمكن للمستخدمين من هذا النطاق الانضمام إلى المنظمة.",
"organizationProfile.verifiedDomainPage.enrollmentTab.calloutInfoLabel": "سيؤثر تغيير وضع التسجيل على المستخدمين الجدد فقط.",
"organizationProfile.verifiedDomainPage.enrollmentTab.calloutInvitationCountLabel": "الدعوات المعلقة المرسلة إلى المستخدمين: {{count}}",
"organizationProfile.verifiedDomainPage.enrollmentTab.calloutSuggestionCountLabel": "الاقتراحات المعلقة المرسلة إلى المستخدمين: {{count}}",
"organizationProfile.verifiedDomainPage.enrollmentTab.manualInvitationOption__description": "يمكن دعوة المستخدمين يدويًا فقط للانضمام إلى المؤسسة.",
"organizationProfile.verifiedDomainPage.enrollmentTab.manualInvitationOption__label": "لا يوجد تسجيل تلقائي",
"organizationProfile.verifiedDomainPage.enrollmentTab.subtitle": "اختر كيفية انضمام المستخدمين من هذا النطاق إلى المؤسسة.",
"organizationProfile.verifiedDomainPage.start.headerTitle__danger": "خطر",
"organizationProfile.verifiedDomainPage.start.headerTitle__enrollment": "خيارات التسجيل",
"organizationProfile.verifiedDomainPage.subtitle": "تم التحقق الآن من النطاق {{domain}}. تابع باختيار وضع التسجيل.",
"organizationProfile.verifiedDomainPage.subtitle": "تم التحقق من النطاق {{domain}}. تابع باختيار وضع التسجيل.",
"organizationProfile.verifiedDomainPage.title": "تحديث {{domain}}",
"organizationProfile.verifyDomainPage.formSubtitle": "أدخل رمز التحقق المرسل إلى عنوان بريدك الإلكتروني",
"organizationProfile.verifyDomainPage.formTitle": "رمز التحقق",
"organizationProfile.verifyDomainPage.resendButton": "لم تتلقى الرمز؟ إعادة الإرسال",
"organizationProfile.verifyDomainPage.resendButton": "لم تستلم الرمز؟ أعد الإرسال",
"organizationProfile.verifyDomainPage.subtitle": "يجب التحقق من النطاق {{domainName}} عبر البريد الإلكتروني.",
"organizationProfile.verifyDomainPage.subtitleVerificationCodeScreen": "تم إرسال رمز التحقق إلى {{emailAddress}}. أدخل الرمز للمتابعة.",
"organizationProfile.verifyDomainPage.title": "التحقق من النطاق",
"organizationSwitcher.action__createOrganization": "إنشاء منظمة",
"organizationSwitcher.action__invitationAccept": "الانضمام",
"organizationSwitcher.action__createOrganization": "إنشاء مؤسسة",
"organizationSwitcher.action__invitationAccept": "انضمام",
"organizationSwitcher.action__manageOrganization": "إدارة",
"organizationSwitcher.action__suggestionsAccept": "طلب الانضمام",
"organizationSwitcher.notSelected": "لم يتم تحديد أي منظمة",
"organizationSwitcher.notSelected": "لم يتم اختيار مؤسسة",
"organizationSwitcher.personalWorkspace": "الحساب الشخصي",
"organizationSwitcher.suggestionsAcceptedLabel": "في انتظار الموافقة",
"organizationSwitcher.suggestionsAcceptedLabel": "بانتظار الموافقة",
"paginationButton__next": "التالي",
"paginationButton__previous": "السابق",
"paginationRowText__displaying": "عرض",
"paginationRowText__of": "من",
"signIn.accountSwitcher.action__addAccount": "إضافة حساب",
"signIn.accountSwitcher.action__signOutAll": "تسجيل الخروج من جميع الحسابات",
"signIn.accountSwitcher.subtitle": "اختر الحساب الذي ترغب في الاستمرار به.",
"signIn.accountSwitcher.subtitle": "اختر الحساب الذي ترغب في المتابعة به.",
"signIn.accountSwitcher.title": "اختر حسابًا",
"signIn.alternativeMethods.actionLink": "احصل على مساعدة",
"signIn.alternativeMethods.actionText": يس لديك أحد هذه؟",
"signIn.alternativeMethods.blockButton__backupCode": "استخدام رمز الاحتياطي",
"signIn.alternativeMethods.blockButton__emailCode": "إرسال رمز بريد إلكتروني إلى {{identifier}}",
"signIn.alternativeMethods.blockButton__emailLink": "إرسال رابط بريد إلكتروني إلى {{identifier}}",
"signIn.alternativeMethods.blockButton__passkey": "تسجيل الدخول برمز الدخول",
"signIn.alternativeMethods.blockButton__password": "تسجيل الدخول بكلمة المرور",
"signIn.alternativeMethods.blockButton__phoneCode": "إرسال رمز SMS إلى {{identifier}}",
"signIn.alternativeMethods.blockButton__totp": "استخدام تطبيق الموثق الخاص بك",
"signIn.alternativeMethods.actionLink": "الحصول على المساعدة",
"signIn.alternativeMethods.actionText": ا تملك أياً من هذه؟",
"signIn.alternativeMethods.blockButton__backupCode": "استخدم رمز النسخ الاحتياطي",
"signIn.alternativeMethods.blockButton__emailCode": "أرسل رمزًا إلى البريد الإلكتروني {{identifier}}",
"signIn.alternativeMethods.blockButton__emailLink": "أرسل رابطًا إلى البريد الإلكتروني {{identifier}}",
"signIn.alternativeMethods.blockButton__passkey": "تسجيل الدخول باستخدام مفتاح المرور",
"signIn.alternativeMethods.blockButton__password": "تسجيل الدخول باستخدام كلمة المرور",
"signIn.alternativeMethods.blockButton__phoneCode": "أرسل رمزًا عبر الرسائل القصيرة إلى {{identifier}}",
"signIn.alternativeMethods.blockButton__totp": "استخدم تطبيق المصادقة",
"signIn.alternativeMethods.getHelp.blockButton__emailSupport": "الدعم عبر البريد الإلكتروني",
"signIn.alternativeMethods.getHelp.content": "إذا كنت تواجه صعوبة في تسجيل الدخول إلى حسابك، ارسل لنا بريدًا إلكترونيًا وسنعمل معك لاستعادة الوصول في أقرب وقت ممكن.",
"signIn.alternativeMethods.getHelp.title": "احصل على مساعدة",
"signIn.alternativeMethods.subtitle": "هل تواجه مشاكل؟ يمكنك استخدام أي من هذه الطرق لتسجيل الدخول.",
"signIn.alternativeMethods.getHelp.content": "إذا كنت تواجه صعوبة في تسجيل الدخول إلى حسابك، راسلنا عبر البريد الإلكتروني وسنعمل على استعادة الوصول في أقرب وقت ممكن.",
"signIn.alternativeMethods.getHelp.title": "الحصول على المساعدة",
"signIn.alternativeMethods.subtitle": "هل تواجه مشكلة؟ يمكنك استخدام أي من الطرق التالية لتسجيل الدخول.",
"signIn.alternativeMethods.title": "استخدم طريقة أخرى",
"signIn.backupCodeMfa.subtitle": "رمز الاحتياطي هو الرمز الذي حصلت عليه عند إعداد المصادقة ثنائية العامل.",
"signIn.backupCodeMfa.title": "أدخل رمز الاحتياطي",
"signIn.backupCodeMfa.subtitle": "رمز النسخ الاحتياطي هو الرمز الذي حصلت عليه عند إعداد المصادقة الثنائية.",
"signIn.backupCodeMfa.title": "أدخل رمز النسخ الاحتياطي",
"signIn.emailCode.formTitle": "رمز التحقق",
"signIn.emailCode.resendButton": "لم تستلم الرمز؟ إعادة الإرسال",
"signIn.emailCode.resendButton": "لم تستلم الرمز؟ أعد الإرسال",
"signIn.emailCode.subtitle": "للمتابعة إلى {{applicationName}}",
"signIn.emailCode.title": "تحقق من بريدك الإلكتروني",
"signIn.emailLink.expired.subtitle": "الرجاء العودة إلى التبويب الأصلي للمتابعة.",
"signIn.emailLink.expired.title": "انتهت صلاحية رابط التحقق هذا",
"signIn.emailLink.failed.subtitle": "الرجاء العودة إلى التبويب الأصلي للمتابعة.",
"signIn.emailLink.failed.title": "رابط التحقق هذا غير صالح",
"signIn.emailLink.formSubtitle": "استخدم الرابط المرسل إلى بريدك الإلكتروني للتحقق",
"signIn.emailLink.expired.subtitle": "ارجع إلى التبويب الأصلي للمتابعة.",
"signIn.emailLink.expired.title": "انتهت صلاحية رابط التحقق",
"signIn.emailLink.failed.subtitle": "ارجع إلى التبويب الأصلي للمتابعة.",
"signIn.emailLink.failed.title": "رابط التحقق غير صالح",
"signIn.emailLink.formSubtitle": "استخدم رابط التحقق المرسل إلى بريدك الإلكتروني",
"signIn.emailLink.formTitle": "رابط التحقق",
"signIn.emailLink.loading.subtitle": "سيتم توجيهك قريبًا",
"signIn.emailLink.loading.title": "تسجيل الدخول...",
"signIn.emailLink.resendButton": "لم تستلم الرابط؟ إعادة الإرسال",
"signIn.emailLink.loading.subtitle": "سيتم تحويلك قريبًا",
"signIn.emailLink.loading.title": "جارٍ تسجيل الدخول...",
"signIn.emailLink.resendButton": "لم تستلم الرابط؟ أعد الإرسال",
"signIn.emailLink.subtitle": "للمتابعة إلى {{applicationName}}",
"signIn.emailLink.title": "تحقق من بريدك الإلكتروني",
"signIn.emailLink.unusedTab.title": "يمكنك إغلاق هذا التبويب",
"signIn.emailLink.verified.subtitle": "سيتم توجيهك قريبًا",
"signIn.emailLink.verified.subtitle": "سيتم تحويلك قريبًا",
"signIn.emailLink.verified.title": "تم تسجيل الدخول بنجاح",
"signIn.emailLink.verifiedSwitchTab.subtitle": "الرجوع إلى التبويب الأصلي للمتابعة",
"signIn.emailLink.verifiedSwitchTab.subtitleNewTab": "الرجوع إلى التبويب الجديد للمتابعة",
"signIn.emailLink.verifiedSwitchTab.titleNewTab": "تم تسجيل الدخول على تبويب آخر",
"signIn.emailLink.verifiedSwitchTab.subtitle": "ارجع إلى التبويب الأصلي للمتابعة",
"signIn.emailLink.verifiedSwitchTab.subtitleNewTab": "ارجع إلى التبويب الجديد للمتابعة",
"signIn.emailLink.verifiedSwitchTab.titleNewTab": "تم تسجيل الدخول في تبويب آخر",
"signIn.forgotPassword.formTitle": "رمز إعادة تعيين كلمة المرور",
"signIn.forgotPassword.resendButton": "لم تستلم الرمز؟ إعادة الإرسال",
"signIn.forgotPassword.subtitle": "لإعادة تعيين كلمة المرور",
"signIn.forgotPassword.subtitle_email": "أدخل أولًا الرمز المرسل إلى عنوان بريدك الإلكتروني",
"signIn.forgotPassword.subtitle_phone": "أدخل أولًا الرمز المرسل إلى هاتفك",
"signIn.forgotPassword.resendButton": "لم تستلم الرمز؟ أعد الإرسال",
"signIn.forgotPassword.subtitle": "لإعادة تعيين كلمة المرور الخاصة بك",
"signIn.forgotPassword.subtitle_email": "أدخل أولاً الرمز المرسل إلى بريدك الإلكتروني",
"signIn.forgotPassword.subtitle_phone": "أدخل أولاً الرمز المرسل إلى هاتفك",
"signIn.forgotPassword.title": "إعادة تعيين كلمة المرور",
"signIn.forgotPasswordAlternativeMethods.blockButton__resetPassword": "إعادة تعيين كلمة المرور",
"signIn.forgotPasswordAlternativeMethods.label__alternativeMethods": "أو، قم بتسجيل الدخول باستخدام طريقة أخرى",
"signIn.forgotPasswordAlternativeMethods.title": "نسيت كلمة المرور؟",
"signIn.noAvailableMethods.message": "لا يمكن المتابعة في عملية تسجيل الدخول. لا يوجد عامل مصادقة متاح.",
"signIn.forgotPasswordAlternativeMethods.label__alternativeMethods": "أو، سجل الدخول بطريقة أخرى",
"signIn.forgotPasswordAlternativeMethods.title": "هل نسيت كلمة المرور؟",
"signIn.noAvailableMethods.message": "لا يمكن المتابعة في تسجيل الدخول. لا توجد وسيلة تحقق متاحة.",
"signIn.noAvailableMethods.subtitle": "حدث خطأ",
"signIn.noAvailableMethods.title": "لا يمكن تسجيل الدخول",
"signIn.passkey.subtitle": "استخدام رمز الدخول يؤكد أنك أنت. قد يطلب جهازك بصمة الإصبع أو الوجه أو قفل الشاشة.",
"signIn.passkey.title": "استخدام رمز الدخول",
"signIn.password.actionLink": "استخدام طريقة أخرى",
"signIn.passkey.subtitle": "استخدام مفتاح المرور يؤكد هويتك. قد يطلب منك جهازك بصمة الإصبع أو الوجه أو قفل الشاشة.",
"signIn.passkey.title": "استخدم مفتاح المرور",
"signIn.password.actionLink": "استخدم طريقة أخرى",
"signIn.password.subtitle": "أدخل كلمة المرور المرتبطة بحسابك",
"signIn.password.title": "أدخل كلمة المرور",
"signIn.passwordPwned.title": "تم تسريب كلمة المرور",
"signIn.phoneCode.formTitle": "رمز التحقق",
"signIn.phoneCode.resendButton": "لم تستلم الرمز؟ إعادة الإرسال",
"signIn.phoneCode.resendButton": "لم تستلم الرمز؟ أعد الإرسال",
"signIn.phoneCode.subtitle": "للمتابعة إلى {{applicationName}}",
"signIn.phoneCode.title": "تحقق من هاتفك",
"signIn.phoneCodeMfa.formTitle": "رمز التحقق",
"signIn.phoneCodeMfa.resendButton": "لم تستلم الرمز؟ إعادة الإرسال",
"signIn.phoneCodeMfa.subtitle": "للمتابعة، يرجى إدخال رمز التحقق المرسل إلى هاتفك",
"signIn.phoneCodeMfa.resendButton": "لم تستلم الرمز؟ أعد الإرسال",
"signIn.phoneCodeMfa.subtitle": "للمتابعة، أدخل رمز التحقق المرسل إلى هاتفك",
"signIn.phoneCodeMfa.title": "تحقق من هاتفك",
"signIn.resetPassword.formButtonPrimary": "إعادة تعيين كلمة المرور",
"signIn.resetPassword.requiredMessage": "من الضروري إعادة تعيين كلمة المرور لأسباب أمنية.",
"signIn.resetPassword.successMessage": "تم تغيير كلمة المرور بنجاح. جارٍ تسجيل الدخول، يرجى الانتظار لحظة.",
"signIn.resetPassword.requiredMessage": "لأسباب أمنية، يجب إعادة تعيين كلمة المرور.",
"signIn.resetPassword.successMessage": "تم تغيير كلمة المرور بنجاح. جارٍ تسجيل الدخول، يرجى الانتظار.",
"signIn.resetPassword.title": "تعيين كلمة مرور جديدة",
"signIn.resetPasswordMfa.detailsLabel": "نحتاج إلى التحقق من هويتك قبل إعادة تعيين كلمة المرور.",
"signIn.start.actionLink": "التسجيل",
"signIn.start.actionLink__use_email": "استخدام البريد الإلكتروني",
"signIn.start.actionLink__use_email_username": "استخدام البريد الإلكتروني أو اسم المستخدم",
"signIn.start.actionLink__use_passkey": "استخدام رمز الدخول بدلاً",
"signIn.start.actionLink__use_phone": "استخدام الهاتف",
"signIn.start.actionLink__use_username": "استخدام اسم المستخدم",
"signIn.start.actionText": يس لديك حساب؟",
"signIn.start.subtitle": "مرحبًا! يرجى ملء التفاصيل للبدء.",
"signIn.start.title": "إنشاء حسابك",
"signIn.start.actionLink": "إنشاء حساب",
"signIn.start.actionLink__use_email": "استخدم البريد الإلكتروني",
"signIn.start.actionLink__use_email_username": "استخدم البريد الإلكتروني أو اسم المستخدم",
"signIn.start.actionLink__use_passkey": "استخدم مفتاح المرور بدلاً من ذلك",
"signIn.start.actionLink__use_phone": "استخدم الهاتف",
"signIn.start.actionLink__use_username": "استخدم اسم المستخدم",
"signIn.start.actionText": ا تملك حسابًا؟",
"signIn.start.subtitle": "مرحبًا بعودتك! يرجى تسجيل الدخول للمتابعة",
"signIn.start.title": "تسجيل الدخول إلى {{applicationName}}",
"signIn.totpMfa.formTitle": "رمز التحقق",
"signIn.totpMfa.subtitle": "للمتابعة، يرجى إدخال رمز التحقق الذي تم توليده بواسطة تطبيق الموثق الخاص بك",
"signIn.totpMfa.title": "التحقق الثنائي الخطوة",
"signIn.totpMfa.subtitle": "للمتابعة، أدخل رمز التحقق الذي تم إنشاؤه بواسطة تطبيق المصادقة",
"signIn.totpMfa.title": "التحقق بخطوتين",
"signInEnterPasswordTitle": "أدخل كلمة المرور الخاصة بك",
"signUp.continue.actionLink": "تسجيل الدخول",
"signUp.continue.actionText": "هل لديك حساب بالفعل؟",
"signUp.continue.subtitle": "يرجى ملء التفاصيل المتبقية للمتابعة.",
"signUp.continue.title": "املأ الحقول الناقصة",
"signUp.emailCode.formSubtitle": "أدخل رمز التحقق المرسل إلى عنوان بريدك الإلكتروني",
"signUp.continue.subtitle": "يرجى إكمال البيانات المتبقية للمتابعة.",
"signUp.continue.title": "أكمل الحقول الناقصة",
"signUp.emailCode.formSubtitle": "أدخل رمز التحقق المرسل إلى بريدك الإلكتروني",
"signUp.emailCode.formTitle": "رمز التحقق",
"signUp.emailCode.resendButton": "لم تستلم الرمز؟ إعادة الإرسال",
"signUp.emailCode.resendButton": "لم تستلم الرمز؟ أعد الإرسال",
"signUp.emailCode.subtitle": "أدخل رمز التحقق المرسل إلى بريدك الإلكتروني",
"signUp.emailCode.title": "تحقق من بريدك الإلكتروني",
"signUp.emailLink.formSubtitle": "استخدم الرابط المرسل إلى عنوان بريدك الإلكتروني للتحقق",
"signUp.emailLink.formSubtitle": "استخدم رابط التحقق المرسل إلى بريدك الإلكتروني",
"signUp.emailLink.formTitle": "رابط التحقق",
"signUp.emailLink.loading.title": "جارٍ التسجيل...",
"signUp.emailLink.resendButton": "لم تستلم الرابط؟ إعادة الإرسال",
"signUp.emailLink.loading.title": "جارٍ إنشاء الحساب...",
"signUp.emailLink.resendButton": "لم تستلم الرابط؟ أعد الإرسال",
"signUp.emailLink.subtitle": "للمتابعة إلى {{applicationName}}",
"signUp.emailLink.title": "تحقق من بريدك الإلكتروني",
"signUp.emailLink.verified.title": "تم التسجيل بنجاح",
"signUp.emailLink.verifiedSwitchTab.subtitle": "الرجوع إلى التبويب الجديد للمتابعة",
"signUp.emailLink.verifiedSwitchTab.subtitleNewTab": "الرجوع إلى التبويب السابق للمتابعة",
"signUp.emailLink.verifiedSwitchTab.title": "تم التحقق بنجاح من البريد الإلكتروني",
"signUp.emailLink.verified.title": "تم إنشاء الحساب بنجاح",
"signUp.emailLink.verifiedSwitchTab.subtitle": "ارجع إلى التبويب الجديد للمتابعة",
"signUp.emailLink.verifiedSwitchTab.subtitleNewTab": "ارجع إلى التبويب السابق للمتابعة",
"signUp.emailLink.verifiedSwitchTab.title": "تم التحقق من البريد الإلكتروني بنجاح",
"signUp.phoneCode.formSubtitle": "أدخل رمز التحقق المرسل إلى رقم هاتفك",
"signUp.phoneCode.formTitle": "رمز التحقق",
"signUp.phoneCode.resendButton": "لم تستلم الرمز؟ إعادة الإرسال",
"signUp.phoneCode.resendButton": "لم تستلم الرمز؟ أعد الإرسال",
"signUp.phoneCode.subtitle": "أدخل رمز التحقق المرسل إلى هاتفك",
"signUp.phoneCode.title": "تحقق من هاتفك",
"signUp.start.actionLink": "تسجيل الدخول",
"signUp.start.actionText": "هل لديك حساب بالفعل؟",
"signUp.start.subtitle": "مرحبًا! يرجى ملء التفاصيل للبدء.",
"signUp.start.title": "إنشاء حسابك",
"socialButtonsBlockButton": "المتابعة مع {{provider|titleize}}",
"unstable__errors.captcha_invalid": "فشل تسجيل الدخول بسبب فشل التحقق من الأمان. يرجى تحديث الصفحة للمحاولة مرة أخرى أو التواصل مع الدعم للمزيد من المساعدة.",
"unstable__errors.captcha_unavailable": "فشل تسجيل الدخول بسبب فشل التحقق من الروبوت. يرجى تحديث الصفحة للمحاولة مرة أخرى أو التواصل مع الدعم للمزيد من المساعدة.",
"signUp.start.subtitle": "مرحبًا بك! يرجى تعبئة البيانات للبدء.",
"signUp.start.title": "أنشئ حسابك",
"socialButtonsBlockButton": "المتابعة باستخدام {{provider|titleize}}",
"unstable__errors.captcha_invalid": "فشل التسجيل بسبب عدم اجتياز التحقق الأمني. يرجى تحديث الصفحة والمحاولة مرة أخرى أو التواصل مع الدعم للمزيد من المساعدة.",
"unstable__errors.captcha_unavailable": "فشل التسجيل بسبب عدم اجتياز التحقق من الروبوتات. يرجى تحديث الصفحة والمحاولة مرة أخرى أو التواصل مع الدعم للمزيد من المساعدة.",
"unstable__errors.form_code_incorrect": "",
"unstable__errors.form_identifier_exists": "",
"unstable__errors.form_identifier_exists__email_address": "هذا البريد الإلكتروني مستخدم. يرجى المحاولة بعنوان آخر.",
"unstable__errors.form_identifier_exists__phone_number": "هذا الرقم مستخدم. يرجى المحاولة برقم آخر.",
"unstable__errors.form_identifier_exists__username": "اسم المستخدم هذا مستخدم. يرجى المحاولة بآخر.",
"unstable__errors.form_identifier_exists__email_address": "عنوان البريد الإلكتروني هذا مستخدم بالفعل. يرجى تجربة عنوان آخر.",
"unstable__errors.form_identifier_exists__phone_number": "رقم الهاتف هذا مستخدم بالفعل. يرجى تجربة رقم آخر.",
"unstable__errors.form_identifier_exists__username": "اسم المستخدم هذا مستخدم بالفعل. يرجى تجربة اسم آخر.",
"unstable__errors.form_identifier_not_found": "",
"unstable__errors.form_param_format_invalid": "",
"unstable__errors.form_param_format_invalid__email_address": "يجب أن يكون عنوان البريد الإلكتروني صالحًا.",
"unstable__errors.form_param_format_invalid__phone_number": "يجب أن يكون رقم الهاتف بتنسيق دولي صالح.",
"unstable__errors.form_param_format_invalid__phone_number": "يجب أن يكون رقم الهاتف بصيغة دولية صحيحة.",
"unstable__errors.form_param_max_length_exceeded__first_name": "يجب ألا يتجاوز الاسم الأول 256 حرفًا.",
"unstable__errors.form_param_max_length_exceeded__last_name": "يجب ألا يتجاوز الاسم الأخير 256 حرفًا.",
"unstable__errors.form_param_max_length_exceeded__last_name": "يجب ألا يتجاوز اسم العائلة 256 حرفًا.",
"unstable__errors.form_param_max_length_exceeded__name": "يجب ألا يتجاوز الاسم 256 حرفًا.",
"unstable__errors.form_param_nil": "",
"unstable__errors.form_password_incorrect": "",
"unstable__errors.form_password_length_too_short": "",
"unstable__errors.form_password_not_strong_enough": "كلمة المرور الخاصة بك غير قوية بما فيه الكفاية.",
"unstable__errors.form_password_pwned": "تم العثور على هذه كلمة المرور كجزء من اختراق ولا يمكن استخدامها، يرجى تجربة كلمة مرور أخرى بدلاً منها.",
"unstable__errors.form_password_pwned__sign_in": "تم العثور على هذه كلمة المرور كجزء من اختراق ولا يمكن استخدامها، يرجى إعادة تعيين كلمة المرور الخاصة بك.",
"unstable__errors.form_password_size_in_bytes_exceeded": "لقد تجاوزت كلمة المرور الحد الأقصى المسموح به من البايتات، يرجى تقصيرها أو إزالة بعض الرموز الخاصة.",
"unstable__errors.form_password_pwned": "تم العثور على هذه الكلمة المرور ضمن تسريب بيانات ولا يمكن استخدامها. يرجى تجربة كلمة مرور أخرى.",
"unstable__errors.form_password_pwned__sign_in": "تم العثور على هذه الكلمة المرور ضمن تسريب بيانات ولا يمكن استخدامها. يرجى إعادة تعيين كلمة المرور.",
"unstable__errors.form_password_size_in_bytes_exceeded": "تجاوزت كلمة المرور الحد الأقصى المسموح به من البايتات. يرجى تقصيرها أو إزالة بعض الرموز الخاصة.",
"unstable__errors.form_password_validation_failed": "كلمة المرور غير صحيحة",
"unstable__errors.form_username_invalid_character": "",
"unstable__errors.form_username_invalid_length": "",
"unstable__errors.identification_deletion_failed": "لا يمكنك حذف هويتك الأخيرة.",
"unstable__errors.identification_deletion_failed": "لا يمكنك حذف آخر وسيلة تعريف.",
"unstable__errors.not_allowed_access": "",
"unstable__errors.passkey_already_exists": "تم تسجيل مفتاح الوصول مسبقًا بهذا الجهاز.",
"unstable__errors.passkey_not_supported": "مفاتيح الوصول غير مدعومة على هذا الجهاز.",
"unstable__errors.passkey_pa_not_supported": "التسجيل يتطلب مصادق النظام ولكن الجهاز لا يدعم ذلك.",
"unstable__errors.passkey_registration_cancelled": "تم إلغاء تسجيل مفتاح الوصول أو انتهت صلاحيته.",
"unstable__errors.passkey_retrieval_cancelled": "تم إلغاء استرداد مفتاح الوصول أو انتهت صلاحيته.",
"unstable__errors.passwordComplexity.maximumLength": "أقل من {{length}} حرف",
"unstable__errors.passwordComplexity.minimumLength": "{{length}} أو أكثر من الأحرف",
"unstable__errors.passkey_already_exists": "يوجد مفتاح مرور مسجل بالفعل على هذا الجهاز.",
"unstable__errors.passkey_not_supported": "مفاتيح المرور غير مدعومة على هذا الجهاز.",
"unstable__errors.passkey_pa_not_supported": "يتطلب التسجيل مصادق منصة، لكن الجهاز لا يدعمه.",
"unstable__errors.passkey_registration_cancelled": "تم إلغاء تسجيل مفتاح المرور أو انتهت المهلة.",
"unstable__errors.passkey_retrieval_cancelled": "تم إلغاء التحقق من مفتاح المرور أو انتهت المهلة.",
"unstable__errors.passwordComplexity.maximumLength": "أقل من {{length}} حرفًا",
"unstable__errors.passwordComplexity.minimumLength": "{{length}} حرفًا أو أكثر",
"unstable__errors.passwordComplexity.requireLowercase": "حرف صغير",
"unstable__errors.passwordComplexity.requireNumbers": "رقم",
"unstable__errors.passwordComplexity.requireSpecialCharacter": "رمز خاص",
"unstable__errors.passwordComplexity.requireUppercase": "حرف كبير",
"unstable__errors.passwordComplexity.sentencePrefix": "يجب أن تحتوي كلمة المرور الخاصة بك على",
"unstable__errors.phone_number_exists": "هذا الرقم مستخدم. يرجى المحاولة برقم آخر.",
"unstable__errors.zxcvbn.couldBeStronger": "كلمة المرور الخاصة بك تعمل، ولكن يمكن أن تكون أقوى. جرب إضافة المزيد من الأحرف.",
"unstable__errors.zxcvbn.goodPassword": "كلمة المرور الخاصة بك تلبي جميع المتطلبات اللازمة.",
"unstable__errors.zxcvbn.notEnough": "كلمة المرور الخاصة بك ليست قوية بما فيه الكفاية.",
"unstable__errors.zxcvbn.suggestions.allUppercase": "قم بتحويل بعض الحروف إلى أحرف كبيرة، ولكن ليس كلها.",
"unstable__errors.zxcvbn.suggestions.anotherWord": "أضف المزيد من الكلمات غير الشائعة.",
"unstable__errors.passwordComplexity.sentencePrefix": "يجب أن تحتوي كلمة المرور على",
"unstable__errors.phone_number_exists": "رقم الهاتف هذا مستخدم بالفعل. يرجى تجربة رقم آخر.",
"unstable__errors.zxcvbn.couldBeStronger": "كلمة المرور تعمل، لكنها يمكن أن تكون أقوى. جرب إضافة المزيد من الأحرف.",
"unstable__errors.zxcvbn.goodPassword": "كلمة المرور الخاصة بك تستوفي جميع المتطلبات اللازمة.",
"unstable__errors.zxcvbn.notEnough": "كلمة المرور الخاصة بك غير قوية بما فيه الكفاية.",
"unstable__errors.zxcvbn.suggestions.allUppercase": "استخدم بعض الأحرف الكبيرة، وليس جميعها.",
"unstable__errors.zxcvbn.suggestions.anotherWord": "أضف كلمات أكثر وأقل شيوعًا.",
"unstable__errors.zxcvbn.suggestions.associatedYears": "تجنب السنوات المرتبطة بك.",
"unstable__errors.zxcvbn.suggestions.capitalization": "استخدم الحروف الكبيرة أكثر من الحرف الأول فقط.",
"unstable__errors.zxcvbn.suggestions.capitalization": "استخدم أكثر من حرف كبير واحد.",
"unstable__errors.zxcvbn.suggestions.dates": "تجنب التواريخ والسنوات المرتبطة بك.",
"unstable__errors.zxcvbn.suggestions.l33t": "تجنب التبديلات التنبؤية للحروف مثل '@' بدلاً من 'a'.",
"unstable__errors.zxcvbn.suggestions.longerKeyboardPattern": "استخدم أنماط لوحة المفاتيح الطويلة وغير اتجاه الكتابة عدة مرات.",
"unstable__errors.zxcvbn.suggestions.noNeed": "يمكنك إنشاء كلمات مرور قوية دون استخدام رموز أو أرقام أو حروف كبيرة.",
"unstable__errors.zxcvbn.suggestions.pwned": "إذا استخدمت هذه كلمة المرور في مكان آخر، يجب عليك تغييرها.",
"unstable__errors.zxcvbn.suggestions.l33t": "تجنب الاستبدالات المتوقعة مثل '@' بدلاً من 'a'.",
"unstable__errors.zxcvbn.suggestions.longerKeyboardPattern": "استخدم أنماط لوحة مفاتيح أطول وغيّر اتجاه الكتابة عدة مرات.",
"unstable__errors.zxcvbn.suggestions.noNeed": "يمكنك إنشاء كلمات مرور قوية دون استخدام رموز أو أرقام أو أحرف كبيرة.",
"unstable__errors.zxcvbn.suggestions.pwned": "إذا كنت تستخدم هذه الكلمة في مكان آخر، يجب عليك تغييرها.",
"unstable__errors.zxcvbn.suggestions.recentYears": "تجنب السنوات الحديثة.",
"unstable__errors.zxcvbn.suggestions.repeated": "تجنب تكرار الكلمات والأحرف.",
"unstable__errors.zxcvbn.suggestions.reverseWords": "تجنب تهجئة الكلمات الشائعة بشكل معكوس.",
"unstable__errors.zxcvbn.suggestions.repeated": "تجنب تكرار الكلمات أو الأحرف.",
"unstable__errors.zxcvbn.suggestions.reverseWords": "تجنب كتابة الكلمات الشائعة بشكل معكوس.",
"unstable__errors.zxcvbn.suggestions.sequences": "تجنب تسلسلات الأحرف الشائعة.",
"unstable__errors.zxcvbn.suggestions.useWords": "استخدم كلمات متعددة، ولكن تجنب العبارات الشائعة.",
"unstable__errors.zxcvbn.suggestions.useWords": "استخدم عدة كلمات، لكن تجنب العبارات الشائعة.",
"unstable__errors.zxcvbn.warnings.common": "هذه كلمة مرور شائعة الاستخدام.",
"unstable__errors.zxcvbn.warnings.commonNames": "الأسماء الشائعة سهلة التخمين.",
"unstable__errors.zxcvbn.warnings.dates": "التواريخ سهلة التخمين.",
"unstable__errors.zxcvbn.warnings.extendedRepeat": "أنماط الحروف المتكررة مثل \"abcabcabc\" سهلة التخمين.",
"unstable__errors.zxcvbn.warnings.keyPattern": "أنماط لوحة المفاتيح القصيرة سهلة التخمين.",
"unstable__errors.zxcvbn.warnings.namesByThemselves": "الأسماء الفردية أو الأسماء العائلية سهلة التخمين.",
"unstable__errors.zxcvbn.warnings.pwned": "تمت تعريض كلمة المرور الخاصة بك في اختراق على الإنترنت.",
"unstable__errors.zxcvbn.warnings.recentYears": "السنوات الحديثة سهلة التخمين.",
"unstable__errors.zxcvbn.warnings.sequences": "تسلسلات الأحرف الشائعة مثل \"abc\" سهلة التخمين.",
"unstable__errors.zxcvbn.warnings.similarToCommon": "هذا مشابه لكلمة مرور شائعة الاستخدام.",
"unstable__errors.zxcvbn.warnings.simpleRepeat": "الحروف المتكررة مثل \"aaa\" سهلة التخمين.",
"unstable__errors.zxcvbn.warnings.straightRow": "صفوف الحروف المستقيمة على لوحة المفاتيح سهلة التخمين.",
"unstable__errors.zxcvbn.warnings.topHundred": "هذه كلمة مرور تستخدم بكثرة.",
"unstable__errors.zxcvbn.warnings.topTen": "هذه كلمة مرور تستخدم بشكل كبير.",
"unstable__errors.zxcvbn.warnings.userInputs": "يجب ألا يكون هناك أي بيانات شخصية أو ذات صلة بالصفحة.",
"unstable__errors.zxcvbn.warnings.wordByItself": "الكلمات الفردية سهلة التخمين.",
"unstable__errors.zxcvbn.warnings.commonNames": "الأسماء والألقاب الشائعة يسهل تخمينها.",
"unstable__errors.zxcvbn.warnings.dates": "التواريخ يسهل تخمينها.",
"unstable__errors.zxcvbn.warnings.extendedRepeat": "أنماط الأحرف المتكررة مثل \"abcabcabc\" يسهل تخمينها.",
"unstable__errors.zxcvbn.warnings.keyPattern": "أنماط لوحة المفاتيح القصيرة يسهل تخمينها.",
"unstable__errors.zxcvbn.warnings.namesByThemselves": "الأسماء أو الألقاب المفردة يسهل تخمينها.",
"unstable__errors.zxcvbn.warnings.pwned": "تم تسريب كلمة المرور الخاصة بك في خرق بيانات على الإنترنت.",
"unstable__errors.zxcvbn.warnings.recentYears": "السنوات الحديثة يسهل تخمينها.",
"unstable__errors.zxcvbn.warnings.sequences": "تسلسلات الأحرف الشائعة مثل \"abc\" يسهل تخمينها.",
"unstable__errors.zxcvbn.warnings.similarToCommon": "تشبه كلمة مرور شائعة الاستخدام.",
"unstable__errors.zxcvbn.warnings.simpleRepeat": "الأحرف المتكررة مثل \"aaa\" يسهل تخمينها.",
"unstable__errors.zxcvbn.warnings.straightRow": "صفوف مستقيمة من المفاتيح على لوحة المفاتيح يسهل تخمينها.",
"unstable__errors.zxcvbn.warnings.topHundred": "هذه كلمة مرور مستخدمة بشكل متكرر.",
"unstable__errors.zxcvbn.warnings.topTen": "هذه كلمة مرور مستخدمة بكثرة.",
"unstable__errors.zxcvbn.warnings.userInputs": "يجب ألا تحتوي على بيانات شخصية أو متعلقة بالصفحة.",
"unstable__errors.zxcvbn.warnings.wordByItself": "الكلمات المفردة يسهل تخمينها.",
"userButton.action__addAccount": "إضافة حساب",
"userButton.action__manageAccount": "إدارة الحساب",
"userButton.action__signOut": "تسجيل الخروج",
"userButton.action__signOutAll": "تسجيل الخروج من جميع الحسابات",
"userProfile.backupCodePage.actionLabel__copied": "تم النسخ!",
"userProfile.backupCodePage.actionLabel__copy": "نسخ الكل",
"userProfile.backupCodePage.actionLabel__download": حميل .txt",
"userProfile.backupCodePage.actionLabel__download": نزيل .txt",
"userProfile.backupCodePage.actionLabel__print": "طباعة",
"userProfile.backupCodePage.infoText1": "سيتم تمكين رموز النسخ الاحتياطي لهذا الحساب.",
"userProfile.backupCodePage.infoText2": "احتفظ برموز النسخ الاحتياطي بسرية وقم بتخزينها بشكل آمن. يمكنك إعادة إنشاء رموز النسخ الاحتياطي إذا كنت تشتبه في تعرضها للخطر.",
"userProfile.backupCodePage.subtitle__codelist": "قم بتخزينها بشكل آمن واحتفظ بها سرية.",
"userProfile.backupCodePage.successMessage": "تم تمكين رموز النسخ الاحتياطي الآن. يمكنك استخدام أحد هذه الرموز لتسجيل الدخول إلى حسابك، إذا فقدت الوصول إلى جهاز المصادقة الخاص بك. يمكن استخدام كل رمز مرة واحدة فقط.",
"userProfile.backupCodePage.successSubtitle": "يمكنك استخدام أحد هذه الرموز لتسجيل الدخول إلى حسابك، إذا فقدت الوصول إلى جهاز المصادقة الخاص بك.",
"userProfile.backupCodePage.title": "إضافة التحقق برمز النسخ الاحتياطي",
"userProfile.backupCodePage.infoText1": "سيتم تفعيل رموز النسخ الاحتياطي لهذا الحساب.",
"userProfile.backupCodePage.infoText2": "احتفظ برموز النسخ الاحتياطي في مكان آمن وسري. يمكنك إعادة توليد الرموز إذا كنت تشك في أنها قد تم اختراقها.",
"userProfile.backupCodePage.subtitle__codelist": "احتفظ بها في مكان آمن وسري.",
"userProfile.backupCodePage.successMessage": "تم تفعيل رموز النسخ الاحتياطي. يمكنك استخدام أحد هذه الرموز لتسجيل الدخول إلى حسابك إذا فقدت الوصول إلى جهاز المصادقة. يمكن استخدام كل رمز مرة واحدة فقط.",
"userProfile.backupCodePage.successSubtitle": "يمكنك استخدام أحد هذه الرموز لتسجيل الدخول إلى حسابك إذا فقدت الوصول إلى جهاز المصادقة.",
"userProfile.backupCodePage.title": "إضافة تحقق برمز احتياطي",
"userProfile.backupCodePage.title__codelist": "رموز النسخ الاحتياطي",
"userProfile.connectedAccountPage.formHint": "حدد مزودًا للاتصال بحسابك.",
"userProfile.connectedAccountPage.formHint__noAccounts": "لا توجد مزودي حساب خارجي متاحين.",
"userProfile.connectedAccountPage.removeResource.messageLine1": "سيتم إزالة {{identifier}} من هذا الحساب.",
"userProfile.connectedAccountPage.removeResource.messageLine2": "لن تتمكن بعد الآن من استخدام هذا الحساب المتصل ولن تعمل أي ميزات تعتمد عليه.",
"userProfile.connectedAccountPage.formHint": "اختر مزودًا لربط حسابك.",
"userProfile.connectedAccountPage.formHint__noAccounts": "لا توجد مزودات حسابات خارجية متاحة.",
"userProfile.connectedAccountPage.removeResource.messageLine1": "{{identifier}} سيتم إزالته من هذا الحساب.",
"userProfile.connectedAccountPage.removeResource.messageLine2": "لن تتمكن من استخدام هذا الحساب المرتبط بعد الآن، وقد تتوقف بعض الميزات المعتمدة عليه.",
"userProfile.connectedAccountPage.removeResource.successMessage": "تمت إزالة {{connectedAccount}} من حسابك.",
"userProfile.connectedAccountPage.removeResource.title": "إزالة الحساب المتصل",
"userProfile.connectedAccountPage.removeResource.title": "إزالة الحساب المرتبط",
"userProfile.connectedAccountPage.socialButtonsBlockButton": "{{provider|titleize}}",
"userProfile.connectedAccountPage.successMessage": "تمت إضافة المزود إلى حسابك",
"userProfile.connectedAccountPage.title": "إضافة حساب متصل",
"userProfile.connectedAccountPage.title": "إضافة حساب مرتبط",
"userProfile.deletePage.actionDescription": "اكتب \"حذف الحساب\" أدناه للمتابعة.",
"userProfile.deletePage.confirm": "حذف الحساب",
"userProfile.deletePage.messageLine1": "هل أنت متأكد أنك تريد حذف حسابك؟",
"userProfile.deletePage.messageLine2": "هذا الإجراء دائم ولا يمكن التراجع عنه.",
"userProfile.deletePage.title": "حذف الحساب",
"userProfile.emailAddressPage.emailCode.formHint": "سيتم إرسال بريد إلكتروني يحتوي على رمز التحقق إلى هذا العنوان الإلكتروني.",
"userProfile.emailAddressPage.emailCode.formHint": "سيتم إرسال رسالة بريد إلكتروني تحتوي على رمز تحقق إلى هذا العنوان.",
"userProfile.emailAddressPage.emailCode.formSubtitle": "أدخل رمز التحقق المرسل إلى {{identifier}}",
"userProfile.emailAddressPage.emailCode.formTitle": "رمز التحقق",
"userProfile.emailAddressPage.emailCode.resendButton": "لم تستلم الرمز؟ إعادة الإرسال",
"userProfile.emailAddressPage.emailCode.resendButton": "لم يصلك الرمز؟ أعد الإرسال",
"userProfile.emailAddressPage.emailCode.successMessage": "تمت إضافة البريد الإلكتروني {{identifier}} إلى حسابك.",
"userProfile.emailAddressPage.emailLink.formHint": "سيتم إرسال بريد إلكتروني يحتوي على رابط التحقق إلى هذا العنوان الإلكتروني.",
"userProfile.emailAddressPage.emailLink.formSubtitle": "انقر على الرابط في البريد الإلكتروني المرسل إلى {{identifier}}",
"userProfile.emailAddressPage.emailLink.formHint": "سيتم إرسال رسالة بريد إلكتروني تحتوي على رابط تحقق إلى هذا العنوان.",
"userProfile.emailAddressPage.emailLink.formSubtitle": "انقر على رابط التحقق في البريد الإلكتروني المرسل إلى {{identifier}}",
"userProfile.emailAddressPage.emailLink.formTitle": "رابط التحقق",
"userProfile.emailAddressPage.emailLink.resendButton": "لم تستلم الرابط؟ إعادة الإرسال",
"userProfile.emailAddressPage.emailLink.resendButton": "لم يصلك الرابط؟ أعد الإرسال",
"userProfile.emailAddressPage.emailLink.successMessage": "تمت إضافة البريد الإلكتروني {{identifier}} إلى حسابك.",
"userProfile.emailAddressPage.removeResource.messageLine1": "سيتم إزالة {{identifier}} من هذا الحساب.",
"userProfile.emailAddressPage.removeResource.messageLine2": "لن تتمكن بعد الآن من تسجيل الدخول باستخدام هذا العنوان الإلكتروني.",
"userProfile.emailAddressPage.removeResource.messageLine1": "{{identifier}} سيتم إزالته من هذا الحساب.",
"userProfile.emailAddressPage.removeResource.messageLine2": "لن تتمكن من تسجيل الدخول باستخدام هذا البريد الإلكتروني بعد الآن.",
"userProfile.emailAddressPage.removeResource.successMessage": "تمت إزالة {{emailAddress}} من حسابك.",
"userProfile.emailAddressPage.removeResource.title": "إزالة عنوان البريد الإلكتروني",
"userProfile.emailAddressPage.title": "إضافة عنوان بريد إلكتروني",
@@ -422,33 +422,33 @@
"userProfile.formButtonPrimary__remove": "إزالة",
"userProfile.formButtonPrimary__save": "حفظ",
"userProfile.formButtonReset": "إلغاء",
"userProfile.mfaPage.formHint": "حدد طريقة للإضافة.",
"userProfile.mfaPage.title": "إضافة التحقق بخطوتين",
"userProfile.mfaPhoneCodePage.backButton": "استخدام الرقم الحالي",
"userProfile.mfaPhoneCodePage.primaryButton__addPhoneNumber": "إضافة رقم الهاتف",
"userProfile.mfaPhoneCodePage.removeResource.messageLine1": "لن يتم استقبال رموز التحقق من هذا الرقم بعد الآن عند تسجيل الدخول.",
"userProfile.mfaPhoneCodePage.removeResource.messageLine2": "قد لا يكون حسابك آمنًا. هل أنت متأكد من رغبتك في المتابعة؟",
"userProfile.mfaPage.formHint": "اختر طريقة للإضافة.",
"userProfile.mfaPage.title": "إضافة تحقق بخطوتين",
"userProfile.mfaPhoneCodePage.backButton": "استخدام رقم موجود",
"userProfile.mfaPhoneCodePage.primaryButton__addPhoneNumber": "إضافة رقم هاتف",
"userProfile.mfaPhoneCodePage.removeResource.messageLine1": "{{identifier}} لن يتلقى رموز التحقق عند تسجيل الدخول.",
"userProfile.mfaPhoneCodePage.removeResource.messageLine2": "قد لا يكون حسابك آمناً كما كان. هل ترغب في المتابعة؟",
"userProfile.mfaPhoneCodePage.removeResource.successMessage": "تمت إزالة التحقق بخطوتين عبر رمز SMS لـ {{mfaPhoneCode}}",
"userProfile.mfaPhoneCodePage.removeResource.title": "إزالة التحقق بخطوتين",
"userProfile.mfaPhoneCodePage.subtitle__availablePhoneNumbers": "حدد رقم هاتف موجود للتسجيل في التحقق بخطوتين عبر رمز SMS أو أضف واحدًا جديدًا.",
"userProfile.mfaPhoneCodePage.subtitle__unavailablePhoneNumbers": "لا توجد أرقام هواتف متاحة للتسجيل في التحقق بخطوتين عبر رمز SMS، يرجى إضافة واحدة جديدة.",
"userProfile.mfaPhoneCodePage.successMessage1": "عند تسجيل الدخول، ستحتاج إلى إدخال رمز التحقق المرسل إلى هذا الرقم كخطوة إضافية.",
"userProfile.mfaPhoneCodePage.successMessage2": "احفظ هذه الرموز الاحتياطية وقم بتخزينها في مكان آمن. إذا فقدت الوصول إلى جهاز المصادقة الخاص بك، يمكنك استخدام رموز النسخ الاحتياطي لتسجيل الدخول.",
"userProfile.mfaPhoneCodePage.successTitle": "تم تمكين التحقق برمز SMS",
"userProfile.mfaPhoneCodePage.title": "إضافة التحقق برمز SMS",
"userProfile.mfaTOTPPage.authenticatorApp.buttonAbleToScan__nonPrimary": "مسح رمز الاستجابة السريعة بدلاً من ذلك",
"userProfile.mfaTOTPPage.authenticatorApp.buttonUnableToScan__nonPrimary": "لا يمكن مسح رمز الاستجابة السريعة؟",
"userProfile.mfaTOTPPage.authenticatorApp.infoText__ableToScan": "قم بإعداد طريقة تسجيل دخول جديدة في تطبيق المصادقة الخاص بك وامسح رمز الاستجابة السريعة التالي لربطه بحسابك.",
"userProfile.mfaTOTPPage.authenticatorApp.infoText__unableToScan": "قم بإعداد طريقة تسجيل دخول جديدة في تطبيق المصادقة الخاص بك وأدخل المفتاح المقدم أدناه.",
"userProfile.mfaTOTPPage.authenticatorApp.inputLabel__unableToScan1": "تأكد من تمكين كلمة المرور الزمنية أو كلمات المرور لمرة واحدة، ثم انهي ربط حسابك.",
"userProfile.mfaTOTPPage.authenticatorApp.inputLabel__unableToScan2": "بديلًا، إذا كان جهاز المصادقة الخاص بك يدعم TOTP URIs، يمكنك أيضًا نسخ الرابط الكامل.",
"userProfile.mfaTOTPPage.removeResource.messageLine1": "لن تكون هناك حاجة لرموز التحقق من هذا التطبيق بعد الآن عند تسجيل الدخول.",
"userProfile.mfaTOTPPage.removeResource.messageLine2": "قد لا يكون حسابك آمنًا. هل أنت متأكد من رغبتك في المتابعة؟",
"userProfile.mfaPhoneCodePage.subtitle__availablePhoneNumbers": "اختر رقم هاتف موجود لتسجيله في التحقق بخطوتين عبر رمز SMS أو أضف رقمًا جديدًا.",
"userProfile.mfaPhoneCodePage.subtitle__unavailablePhoneNumbers": "لا توجد أرقام هواتف متاحة للتسجيل في التحقق بخطوتين عبر رمز SMS، يرجى إضافة رقم جديد.",
"userProfile.mfaPhoneCodePage.successMessage1": "عند تسجيل الدخول، ستحتاج إلى إدخال رمز تحقق يُرسل إلى هذا الرقم كخطوة إضافية.",
"userProfile.mfaPhoneCodePage.successMessage2": "احفظ رموز النسخ الاحتياطي واحتفظ بها في مكان آمن. إذا فقدت الوصول إلى جهاز المصادقة، يمكنك استخدام الرموز لتسجيل الدخول.",
"userProfile.mfaPhoneCodePage.successTitle": "تم تفعيل التحقق برمز SMS",
"userProfile.mfaPhoneCodePage.title": "إضافة تحقق برمز SMS",
"userProfile.mfaTOTPPage.authenticatorApp.buttonAbleToScan__nonPrimary": "مسح رمز QR بدلاً من ذلك",
"userProfile.mfaTOTPPage.authenticatorApp.buttonUnableToScan__nonPrimary": "لا يمكنك مسح رمز QR؟",
"userProfile.mfaTOTPPage.authenticatorApp.infoText__ableToScan": "قم بإعداد طريقة تسجيل دخول جديدة في تطبيق المصادقة الخاص بك وامسح رمز QR التالي لربطه بحسابك.",
"userProfile.mfaTOTPPage.authenticatorApp.infoText__unableToScan": "قم بإعداد طريقة تسجيل دخول جديدة في تطبيق المصادقة وأدخل المفتاح الموضح أدناه.",
"userProfile.mfaTOTPPage.authenticatorApp.inputLabel__unableToScan1": "تأكد من تفعيل كلمات المرور المؤقتة أو المستندة إلى الوقت، ثم أكمل ربط الحساب.",
"userProfile.mfaTOTPPage.authenticatorApp.inputLabel__unableToScan2": "بدلاً من ذلك، إذا كان تطبيق المصادقة يدعم TOTP URIs، يمكنك نسخ الرابط الكامل.",
"userProfile.mfaTOTPPage.removeResource.messageLine1": "لن يُطلب منك إدخال رموز التحقق من هذا التطبيق عند تسجيل الدخول.",
"userProfile.mfaTOTPPage.removeResource.messageLine2": "قد لا يكون حسابك آمناً كما كان. هل ترغب في المتابعة؟",
"userProfile.mfaTOTPPage.removeResource.successMessage": "تمت إزالة التحقق بخطوتين عبر تطبيق المصادقة.",
"userProfile.mfaTOTPPage.removeResource.title": "إزالة التحقق بخطوتين",
"userProfile.mfaTOTPPage.successMessage": "تم تمكين التحقق بخطوتين الآن. عند تسجيل الدخول، ستحتاج إلى إدخال رمز التحقق من هذا التطبيق كخطوة إضافية.",
"userProfile.mfaTOTPPage.title": "إضافة تطبيق المصادقة",
"userProfile.mfaTOTPPage.verifySubtitle": "أدخل رمز التحقق الذي تم إنشاؤه بواسطة تطبيق المصادقة الخاص بك",
"userProfile.mfaTOTPPage.successMessage": "تم تفعيل التحقق بخطوتين. عند تسجيل الدخول، ستحتاج إلى إدخال رمز تحقق من تطبيق المصادقة كخطوة إضافية.",
"userProfile.mfaTOTPPage.title": "إضافة تطبيق مصادقة",
"userProfile.mfaTOTPPage.verifySubtitle": "أدخل رمز التحقق الذي أنشأه تطبيق المصادقة",
"userProfile.mfaTOTPPage.verifyTitle": "رمز التحقق",
"userProfile.mobileButton__menu": "القائمة",
"userProfile.navbar.account": "الملف الشخصي",
@@ -459,70 +459,70 @@
"userProfile.passkeyScreen.removeResource.title": "إزالة مفتاح المرور",
"userProfile.passkeyScreen.subtitle__rename": "يمكنك تغيير اسم مفتاح المرور لتسهيل العثور عليه.",
"userProfile.passkeyScreen.title__rename": "إعادة تسمية مفتاح المرور",
"userProfile.passwordPage.checkboxInfoText__signOutOfOtherSessions": "يُوصى بتسجيل الخروج من جميع الأجهزة الأخرى التي قد تكون استخدمت كلمة المرور القديمة الخاصة بك.",
"userProfile.passwordPage.readonly": "لا يمكن تحرير كلمة المرور الخاصة بك حاليًا لأنه يمكنك تسجيل الدخول فقط عبر الاتصال بالشركة.",
"userProfile.passwordPage.checkboxInfoText__signOutOfOtherSessions": "يُوصى بتسجيل الخروج من جميع الأجهزة الأخرى التي قد استخدمت كلمة المرور القديمة.",
"userProfile.passwordPage.readonly": "لا يمكن تعديل كلمة المرور حالياً لأنك تسجل الدخول فقط عبر الاتصال المؤسسي.",
"userProfile.passwordPage.successMessage__set": "تم تعيين كلمة المرور الخاصة بك.",
"userProfile.passwordPage.successMessage__signOutOfOtherSessions": "تم تسجيل الخروج من جميع الأجهزة الأخرى.",
"userProfile.passwordPage.successMessage__update": "تم تحديث كلمة المرور الخاصة بك.",
"userProfile.passwordPage.title__set": "تعيين كلمة المرور",
"userProfile.passwordPage.title__update": "تحديث كلمة المرور",
"userProfile.phoneNumberPage.infoText": "سيتم إرسال رسالة نصية تحتوي على رمز التحقق إلى هذا الرقم. قد تنطبق رسوم الرسائل والبيانات.",
"userProfile.phoneNumberPage.infoText": "سيتم إرسال رسالة نصية تحتوي على رمز تحقق إلى هذا الرقم. قد يتم تطبيق رسوم على الرسائل والبيانات.",
"userProfile.phoneNumberPage.removeResource.messageLine1": "{{identifier}} سيتم إزالته من هذا الحساب.",
"userProfile.phoneNumberPage.removeResource.messageLine2": "لن تتمكن بعد الآن من تسجيل الدخول باستخدام هذا الرقم.",
"userProfile.phoneNumberPage.removeResource.messageLine2": "لن تتمكن من تسجيل الدخول باستخدام هذا الرقم بعد الآن.",
"userProfile.phoneNumberPage.removeResource.successMessage": "تمت إزالة {{phoneNumber}} من حسابك.",
"userProfile.phoneNumberPage.removeResource.title": "إزالة رقم الهاتف",
"userProfile.phoneNumberPage.successMessage": "{{identifier}} تمت إضافته إلى حسابك.",
"userProfile.phoneNumberPage.title": "إضافة رقم الهاتف",
"userProfile.phoneNumberPage.successMessage": "تمت إضافة {{identifier}} إلى حسابك.",
"userProfile.phoneNumberPage.title": "إضافة رقم هاتف",
"userProfile.phoneNumberPage.verifySubtitle": "أدخل رمز التحقق المرسل إلى {{identifier}}",
"userProfile.phoneNumberPage.verifyTitle": "تحقق من رقم الهاتف",
"userProfile.profilePage.fileDropAreaHint": "الحجم الموصى به 1:1، حتى 10 ميغابايت.",
"userProfile.profilePage.fileDropAreaHint": "الحجم الموصى به 1:1، حتى 10 ميجابايت.",
"userProfile.profilePage.imageFormDestructiveActionSubtitle": "إزالة",
"userProfile.profilePage.imageFormSubtitle": "تحميل",
"userProfile.profilePage.imageFormTitle": "صورة الملف الشخصي",
"userProfile.profilePage.readonly": "تم توفير معلومات ملفك الشخصي من خلال الاتصال بالشركة ولا يمكن تحريرها.",
"userProfile.profilePage.readonly": "تم توفير معلومات ملفك الشخصي من خلال الاتصال المؤسسي ولا يمكن تعديلها.",
"userProfile.profilePage.successMessage": "تم تحديث ملفك الشخصي.",
"userProfile.profilePage.title": "تحديث الملف الشخصي",
"userProfile.start.activeDevicesSection.destructiveAction": "تسجيل الخروج من الجهاز",
"userProfile.start.activeDevicesSection.title": "الأجهزة النشطة",
"userProfile.start.connectedAccountsSection.actionLabel__connectionFailed": "حاول مرة أخرى",
"userProfile.start.connectedAccountsSection.actionLabel__reauthorize": "التفويض الآن",
"userProfile.start.connectedAccountsSection.actionLabel__reauthorize": "قم بالتفويض الآن",
"userProfile.start.connectedAccountsSection.destructiveActionTitle": "إزالة",
"userProfile.start.connectedAccountsSection.primaryButton": "ربط الحساب",
"userProfile.start.connectedAccountsSection.subtitle__reauthorize": "تم تحديث النطاقات المطلوبة، وقد تواجه قدرًا محدودًا من الوظائف. يرجى إعادة تفويض هذا التطبيق لتجنب أي مشاكل",
"userProfile.start.connectedAccountsSection.title": "الحسابات المتصلة",
"userProfile.start.connectedAccountsSection.subtitle__reauthorize": "تم تحديث الأذونات المطلوبة، وقد تواجه وظائف محدودة. يرجى إعادة تفويض هذا التطبيق لتجنب أي مشاكل",
"userProfile.start.connectedAccountsSection.title": "الحسابات المرتبطة",
"userProfile.start.dangerSection.deleteAccountButton": "حذف الحساب",
"userProfile.start.dangerSection.title": "حذف الحساب",
"userProfile.start.emailAddressesSection.destructiveAction": "إزالة البريد الإلكتروني",
"userProfile.start.emailAddressesSection.detailsAction__nonPrimary": "تعيين كأساسي",
"userProfile.start.emailAddressesSection.detailsAction__primary": "اكتمال التحقق",
"userProfile.start.emailAddressesSection.detailsAction__unverified": "التحقق",
"userProfile.start.emailAddressesSection.detailsAction__nonPrimary": "تعيين كافتراضي",
"userProfile.start.emailAddressesSection.detailsAction__primary": "إكمال التحقق",
"userProfile.start.emailAddressesSection.detailsAction__unverified": "تحقق",
"userProfile.start.emailAddressesSection.primaryButton": "إضافة عنوان بريد إلكتروني",
"userProfile.start.emailAddressesSection.title": "عناوين البريد الإلكتروني",
"userProfile.start.enterpriseAccountsSection.title": "حسابات المؤسسة",
"userProfile.start.enterpriseAccountsSection.title": "حسابات المؤسسات",
"userProfile.start.headerTitle__account": "تفاصيل الملف الشخصي",
"userProfile.start.headerTitle__security": "الأمان",
"userProfile.start.mfaSection.backupCodes.actionLabel__regenerate": "إعادة إنشاء",
"userProfile.start.mfaSection.backupCodes.actionLabel__regenerate": "إعادة التوليد",
"userProfile.start.mfaSection.backupCodes.headerTitle": "رموز النسخ الاحتياطي",
"userProfile.start.mfaSection.backupCodes.subtitle__regenerate": "احصل على مجموعة جديدة من رموز النسخ الاحتياطي الآمنة. سيتم حذف رموز النسخ الاحتياطي السابقة ولا يمكن استخدامها.",
"userProfile.start.mfaSection.backupCodes.title__regenerate": "إعادة إنشاء رموز النسخ الاحتياطي",
"userProfile.start.mfaSection.backupCodes.subtitle__regenerate": "احصل على مجموعة جديدة من رموز النسخ الاحتياطي الآمنة. سيتم حذف الرموز السابقة ولن تكون صالحة للاستخدام.",
"userProfile.start.mfaSection.backupCodes.title__regenerate": "إعادة توليد رموز النسخ الاحتياطي",
"userProfile.start.mfaSection.phoneCode.actionLabel__setDefault": "تعيين كافتراضي",
"userProfile.start.mfaSection.phoneCode.destructiveActionLabel": "إزالة",
"userProfile.start.mfaSection.primaryButton": "إضافة التحقق من خطوتين",
"userProfile.start.mfaSection.title": "التحقق من خطوتين",
"userProfile.start.mfaSection.primaryButton": "إضافة التحقق بخطوتين",
"userProfile.start.mfaSection.title": "التحقق بخطوتين",
"userProfile.start.mfaSection.totp.destructiveActionTitle": "إزالة",
"userProfile.start.mfaSection.totp.headerTitle": "تطبيق المصادقة",
"userProfile.start.passkeysSection.menuAction__destructive": "إزالة",
"userProfile.start.passkeysSection.menuAction__rename": "إعادة تسمية",
"userProfile.start.passkeysSection.menuAction__rename": "إعادة التسمية",
"userProfile.start.passkeysSection.title": "مفاتيح المرور",
"userProfile.start.passwordSection.primaryButton__setPassword": "تعيين كلمة مرور",
"userProfile.start.passwordSection.primaryButton__setPassword": "تعيين كلمة المرور",
"userProfile.start.passwordSection.primaryButton__updatePassword": "تحديث كلمة المرور",
"userProfile.start.passwordSection.title": "كلمة المرور",
"userProfile.start.phoneNumbersSection.destructiveAction": "إزالة رقم الهاتف",
"userProfile.start.phoneNumbersSection.detailsAction__nonPrimary": "تعيين كأساسي",
"userProfile.start.phoneNumbersSection.detailsAction__primary": "اكتمال التحقق",
"userProfile.start.phoneNumbersSection.detailsAction__unverified": "التحقق من رقم الهاتف",
"userProfile.start.phoneNumbersSection.primaryButton": "إضافة رقم الهاتف",
"userProfile.start.phoneNumbersSection.title": "أرقام الهواتف",
"userProfile.start.phoneNumbersSection.detailsAction__nonPrimary": "تعيين كافتراضي",
"userProfile.start.phoneNumbersSection.detailsAction__primary": "إكمال التحقق",
"userProfile.start.phoneNumbersSection.detailsAction__unverified": "تحقق من رقم الهاتف",
"userProfile.start.phoneNumbersSection.primaryButton": "إضافة رقم هاتف",
"userProfile.start.phoneNumbersSection.title": "أرقام الهاتف",
"userProfile.start.profileSection.primaryButton": "تحديث الملف الشخصي",
"userProfile.start.profileSection.title": "الملف الشخصي",
"userProfile.start.usernameSection.primaryButton__setUsername": "تعيين اسم المستخدم",
@@ -535,11 +535,11 @@
"userProfile.usernamePage.title__set": "تعيين اسم المستخدم",
"userProfile.usernamePage.title__update": "تحديث اسم المستخدم",
"userProfile.web3WalletPage.removeResource.messageLine1": "{{identifier}} سيتم إزالته من هذا الحساب.",
"userProfile.web3WalletPage.removeResource.messageLine2": "لن تتمكن بعد الآن من تسجيل الدخول باستخدام هذا المحفظة web3.",
"userProfile.web3WalletPage.removeResource.successMessage": "{{web3Wallet}} تمت إزالته من حسابك.",
"userProfile.web3WalletPage.removeResource.title": "إزالة محفظة web3",
"userProfile.web3WalletPage.subtitle__availableWallets": "حدد محفظة web3 للاتصال بحسابك.",
"userProfile.web3WalletPage.subtitle__unavailableWallets": "لا توجد محافظ web3 متاحة.",
"userProfile.web3WalletPage.removeResource.messageLine2": "لن تتمكن من تسجيل الدخول باستخدام هذه المحفظة Web3 بعد الآن.",
"userProfile.web3WalletPage.removeResource.successMessage": "{{web3Wallet}} تم إزالته من حسابك.",
"userProfile.web3WalletPage.removeResource.title": "إزالة محفظة Web3",
"userProfile.web3WalletPage.subtitle__availableWallets": "اختر محفظة Web3 لربطها بحسابك.",
"userProfile.web3WalletPage.subtitle__unavailableWallets": "لا توجد محافظ Web3 متاحة.",
"userProfile.web3WalletPage.successMessage": "تمت إضافة المحفظة إلى حسابك.",
"userProfile.web3WalletPage.title": "إضافة محفظة web3"
"userProfile.web3WalletPage.title": "إضافة محفظة Web3"
}
+12 -14
View File
@@ -1,22 +1,20 @@
{
"blue": "أزرق الفجر",
"custom": "مخصص",
"cyan": "سماوي",
"cyan": "سماوي ساطع",
"default": "افتراضي",
"geekblue": "أزرق المهووسين",
"gold": "ذهب",
"geekblue": "أزرق تقني",
"gold": "أصفر القطيفة",
"green": "أخضر الشفق",
"lime": "ليموني",
"magenta": "ماجنتا فرنسي",
"mauve": "بنفسجي فاتح",
"magenta": "أرجواني فرنسي",
"mauve": "أرجواني الوستارية",
"olive": "أخضر زيتوني",
"orange": "برتقالي الغروب",
"presets": "الإعدادات المسبقة",
"purple": "بنفسجي داكن",
"red": حمر الغسق",
"sage": "أخضر حكيم",
"sand": "رمل",
"slate": "رمادي لوحي",
"orange": "غروب",
"purple": "أرجواني باذنجاني",
"red": "أحمر الشفق",
"sage": خضر الميرمية",
"sand": "شاطئ",
"slate": "رمادي أردوازي",
"volcano": "بركاني",
"yellow": "أصفر الشروق"
"yellow": "شروق الشمس"
}
+211 -190
View File
@@ -1,149 +1,149 @@
{
"about": "حول",
"advanceSettings": "إعدادات متقدمة",
"alert.cloud.action": "تجربة مجانية",
"alert.cloud.desc": "نحن نقدم {{credit}} نقطة حساب مجانية لجميع المستخدمين المسجلين، بدون الحاجة إلى تكوين معقد، فقط قم بتشغيلها، تدعم تاريخ الدردشة غير المحدود ومزامنة السحابة العالمية، والمزيد من الميزات المتقدمة بانتظار استكشافها معًا.",
"alert.cloud.descOnMobile": "نحن نقدم {{credit}} نقطة حساب مجانية لجميع المستخدمين المسجلين، بدون الحاجة إلى إعدادات معقدة، فقط قم بالاستخدام.",
"alert.cloud.title": "مرحبًا بك في التجربة {{name}}",
"appLoading.appIdle": "جاهز للإطلاق",
"appLoading.appInitializing": "جارٍ تشغيل التطبيق...",
"appLoading.failed": "عذرًا، فشل تحميل التطبيق، يرجى مراجعة التفاصيل للتحقق من المشكلة",
"appLoading.finished": "تم الانتهاء من تهيئة قاعدة البيانات",
"appLoading.goToChat": "جارٍ تحميل صفحة الدردشة...",
"appLoading.initAuth": "جارٍ تهيئة خدمة المصادقة...",
"appLoading.initUser": "جارٍ تهيئة حالة المستخدم...",
"appLoading.initializing": "جارٍ تهيئة قاعدة بيانات PGlite...",
"appLoading.loadingDependencies": "جارٍ تهيئة الاعتمادات...",
"appLoading.loadingWasm": "جارٍ تحميل وحدة WASM...",
"appLoading.migrating": "جارٍ تنفيذ ترحيل الجداول...",
"advanceSettings": "الإعدادات المتقدمة",
"alert.cloud.action": "جرّب الآن",
"alert.cloud.desc": "جميع المستخدمين المسجلين يحصلون على {{credit}} من أرصدة الحوسبة المجانية شهريًا — دون الحاجة إلى إعداد. يشمل المزامنة السحابية العالمية والبحث المتقدم على الويب.",
"alert.cloud.descOnMobile": "جميع المستخدمين المسجلين يحصلون على {{credit}} من أرصدة الحوسبة المجانية شهريًا — دون الحاجة إلى إعداد.",
"alert.cloud.title": "النسخة التجريبية من {{name}} متاحة الآن",
"appLoading.appIdle": "جاهز للبدء",
"appLoading.appInitializing": "يتم تشغيل التطبيق...",
"appLoading.failed": "حدث خطأ أثناء بدء التشغيل. اعرض التفاصيل لاستكشاف الأخطاء، أو حاول مرة أخرى لاحقًا.",
"appLoading.finished": "اكتمل تهيئة قاعدة البيانات",
"appLoading.goToChat": "يتم تحميل صفحة الدردشة...",
"appLoading.initAuth": "يتم تهيئة خدمة المصادقة...",
"appLoading.initUser": "يتم تهيئة حالة المستخدم...",
"appLoading.initializing": "يتم تهيئة قاعدة بيانات PGlite...",
"appLoading.loadingDependencies": "يتم تهيئة التبعيات...",
"appLoading.loadingWasm": "يتم تحميل وحدة WASM...",
"appLoading.migrating": "يتم تنفيذ ترحيل قاعدة البيانات...",
"appLoading.ready": "قاعدة البيانات جاهزة",
"appLoading.showDetail": "عرض التفاصيل",
"autoGenerate": "توليد تلقائي",
"autoGenerateTooltip": "إكمال تلقائي بناءً على الكلمات المقترحة لوصف المساعد",
"autoGenerateTooltipDisabled": "الرجاء إدخال كلمة تلميح قبل تفعيل وظيفة الإكمال التلقائي",
"back": ودة",
"batchDelete": "حذف دفعة",
"blog": "مدونة المنتجات",
"autoGenerate": "إكمال تلقائي",
"autoGenerateTooltip": "إكمال الوصف تلقائيًا من ملف تعريف الوكيل",
"autoGenerateTooltipDisabled": "أضف ملف تعريف وكيل أولاً لاستخدام الإكمال التلقائي",
"back": "رجوع",
"batchDelete": "حذف جماعي",
"blog": "مدونة المنتج",
"branching": "إنشاء موضوع فرعي",
"branchingDisable": "ميزة \"الموضوعات الفرعية\" غير متاحة في الوضع الحالي. لاستخدام هذه الميزة، يُرجى التبديل إلى وضع قاعدة البيانات Postgres/Pglite أو استخدام LobeHub Cloud",
"branchingRequiresSavedTopic": "الموضوع الحالي غير محفوظ، يجب الحفظ قبل استخدام ميزة الموضوع الفرعي",
"branchingDisable": "ميزة \"الموضوع الفرعي\" غير متاحة في الوضع الحالي. لاستخدام هذه الميزة، يرجى التبديل إلى وضع قاعدة بيانات Postgres/Pglite أو استخدام LobeHub Cloud.",
"branchingRequiresSavedTopic": "الموضوع الحالي غير محفوظ، يرجى حفظه أولاً لاستخدام ميزة الموضوع الفرعي",
"cancel": "إلغاء",
"changelog": "سجل التغييرات",
"clientDB.autoInit.title": "تهيئة قاعدة بيانات PGlite",
"clientDB.error.desc": "نعتذر، حدث خطأ أثناء عملية تهيئة قاعدة بيانات Pglite. يرجى النقر على الزر لإعادة المحاولة. إذا استمرت المشكلة بعد عدة محاولات، يرجى <1>تقديم مشكلة</1>، وسنساعدك في حلها في أسرع وقت ممكن",
"clientDB.error.detail": "سبب الخطأ: [{{type}}] {{message}}، التفاصيل كالتالي:",
"clientDB.autoInit.title": "يتم تهيئة قاعدة بيانات PGlite",
"clientDB.error.desc": "فشل تهيئة PGlite. حاول مرة أخرى أولاً. إذا لم تنجح، افتح الإصلاحات الذاتية واتبع الخطوات. لا تزال تواجه مشكلة؟ استخدم خيار الإبلاغ عن المشكلة لإرسال تفاصيل الخطأ.",
"clientDB.error.detail": "سبب الخطأ: [{{type}}] {{message}}. التفاصيل كما يلي:",
"clientDB.error.detailTitle": "سبب الخطأ",
"clientDB.error.report": "الإبلاغ عن مشكلة",
"clientDB.error.retry": "إعادة المحاولة",
"clientDB.error.selfSolve": "حل ذاتي",
"clientDB.error.selfSolve": "إصلاحات ذاتية",
"clientDB.error.title": "فشل تهيئة قاعدة البيانات",
"clientDB.initing.error": "حدث خطأ، يرجى إعادة المحاولة",
"clientDB.initing.error": "حدث خطأ، يرجى المحاولة مرة أخرى",
"clientDB.initing.idle": "في انتظار التهيئة...",
"clientDB.initing.initializing": "جارٍ التهيئة...",
"clientDB.initing.loadingDependencies": "جارٍ تحميل الاعتماديات...",
"clientDB.initing.loadingWasmModule": "جارٍ تحميل وحدة WASM...",
"clientDB.initing.migrating": "جارٍ تنفيذ ترحيل البيانات...",
"clientDB.initing.initializing": "يتم التهيئة...",
"clientDB.initing.loadingDependencies": "يتم تحميل التبعيات...",
"clientDB.initing.loadingWasmModule": "يتم تحميل وحدة WASM...",
"clientDB.initing.migrating": "يتم تنفيذ ترحيل قاعدة البيانات...",
"clientDB.initing.ready": "قاعدة البيانات جاهزة",
"clientDB.modal.desc": "فعّل قاعدة بيانات العميل من الجيل التالي الآن. خزّن بيانات الدردشة بشكل دائم في متصفحك، واستفد من ميزات متقدمة مثل مكتبة الموارد.",
"clientDB.modal.enable": "تمكين الآن",
"clientDB.modal.features.knowledgeBase.desc": "أنشئ مكتبة مواردك الشخصية وابدأ محادثات مع مساعدك باستخدامها بسهولة (قريبًا).",
"clientDB.modal.features.knowledgeBase.title": عم محادثات مكتبة الموارد، لتفعيل العقل الثاني",
"clientDB.modal.features.localFirst.desc": ُخزن بيانات الدردشة بالكامل في المتصفح، بياناتك دائمًا تحت سيطرتك.",
"clientDB.modal.features.localFirst.title": "الأولوية محلية، الخصوصية أولاً",
"clientDB.modal.features.pglite.desc": "مبني على PGlite، يدعم بشكل أصلي ميزات AI Native المتقدمة (استرجاع المتجهات)",
"clientDB.modal.features.pglite.title": "بنية تخزين عميل من الجيل الجديد",
"clientDB.modal.init.desc": "جارٍ تهيئة قاعدة البيانات، قد يستغرق الأمر من 5 إلى 30 ثانية حسب اختلاف الشبكة",
"clientDB.modal.init.title": "جارٍ تهيئة قاعدة بيانات PGlite",
"clientDB.modal.title": "فتح قاعدة بيانات العميل",
"clientDB.modal.desc": "فعّل قاعدة البيانات العميلة من الجيل التالي. احفظ بيانات الدردشة في متصفحك وافتح ميزات متقدمة مثل المكتبة.",
"clientDB.modal.enable": "فعّل الآن",
"clientDB.modal.features.knowledgeBase.desc": "أنشئ مكتبتك الشخصية وتحدث مع الوكلاء باستخدامها (قريبًا).",
"clientDB.modal.features.knowledgeBase.title": ردشة المكتبة — عقلك الثاني",
"clientDB.modal.features.localFirst.desc": "يتم تخزين بيانات الدردشة بالكامل في المتصفح، مما يحافظ على خصوصيتك وتحكمك الكامل.",
"clientDB.modal.features.localFirst.title": "محلي أولاً، خصوصية أولاً",
"clientDB.modal.features.pglite.desc": "مبني على PGlite، مع دعم مدمج لميزات متقدمة مثل البحث الشعاعي",
"clientDB.modal.features.pglite.title": "بنية تخزين عميل من الجيل التالي",
"clientDB.modal.init.desc": "يتم تهيئة قاعدة البيانات. قد يستغرق ذلك من 5 إلى 30 ثانية حسب جهازك وشبكتك. يمكنك القيام بشيء آخر والعودة لاحقًا.",
"clientDB.modal.init.title": "يتم تهيئة قاعدة بيانات PGlite",
"clientDB.modal.title": "تفعيل قاعدة البيانات العميلة",
"clientDB.ready.button": "استخدم الآن",
"clientDB.ready.desc": "استخدم الآن",
"clientDB.ready.desc": "جاهز للاستخدام",
"clientDB.ready.title": "قاعدة بيانات PGlite جاهزة",
"clientDB.solve.backup.backup": "نسخ احتياطي",
"clientDB.solve.backup.backupSuccess": "تم النسخ الاحتياطي بنجاح",
"clientDB.solve.backup.desc": "تصدير البيانات الأساسية من قاعدة البيانات الحالية",
"clientDB.solve.backup.export": "تصدير جميع البيانات",
"clientDB.solve.backup.exportDesc": "سيتم حفظ البيانات المصدرة بتنسيق JSON، ويمكن استخدامها لاستعادة أو تحليل لاحق.",
"clientDB.solve.backup.export": "تصدير كل البيانات",
"clientDB.solve.backup.exportDesc": "سيتم حفظ البيانات المصدرة بصيغة JSON، ويمكن استخدامها للاستعادة أو التحليل لاحقًا.",
"clientDB.solve.backup.reset.alert": "تحذير",
"clientDB.solve.backup.reset.alertDesc": "قد تؤدي العمليات التالية إلى فقدان البيانات. يرجى التأكد من أنك قد قمت بعمل نسخة احتياطية من البيانات الهامة قبل المتابعة.",
"clientDB.solve.backup.reset.button": "إعادة تعيين قاعدة البيانات بالكامل (حذف جميع البيانات)",
"clientDB.solve.backup.reset.confirm.desc": تؤدي هذه العملية إلى حذف جميع البيانات ولا يمكن التراجع عنها، هل تؤكد المتابعة؟",
"clientDB.solve.backup.reset.alertDesc": "قد تؤدي الإجراءات التالية إلى حذف البيانات. قم بالنسخ الاحتياطي أولاً — القرار لك.",
"clientDB.solve.backup.reset.button": "إعادة تعيين قاعدة البيانات بالكامل (حذف كل البيانات)",
"clientDB.solve.backup.reset.confirm.desc": يؤدي هذا الإجراء إلى حذف جميع البيانات ولا يمكن التراجع عنه. هل تؤكد المتابعة؟",
"clientDB.solve.backup.reset.confirm.title": "تأكيد إعادة تعيين قاعدة البيانات",
"clientDB.solve.backup.reset.desc": "إعادة تعيين قاعدة البيانات في حالة عدم إمكانية الاستعادة",
"clientDB.solve.backup.reset.desc": "أعد تعيين قاعدة البيانات في حال حدوث ترحيل غير قابل للاسترداد",
"clientDB.solve.backup.reset.title": "إعادة تعيين قاعدة البيانات",
"clientDB.solve.backup.restore": "استعادة",
"clientDB.solve.backup.restoreSuccess": "تم الاستعادة بنجاح",
"clientDB.solve.backup.restoreSuccess": "تمت الاستعادة بنجاح",
"clientDB.solve.backup.title": "نسخ احتياطي للبيانات",
"clientDB.solve.diagnosis.createdAt": اريخ الإنشاء",
"clientDB.solve.diagnosis.migratedAt": اريخ اكتمال النقل",
"clientDB.solve.diagnosis.sql": "نقل SQL",
"clientDB.solve.diagnosis.title": "حالة النقل",
"clientDB.solve.repair.desc": "إدارة حالة النقل يدويًا",
"clientDB.solve.diagnosis.createdAt": "وقت الإنشاء",
"clientDB.solve.diagnosis.migratedAt": "وقت اكتمال الترحيل",
"clientDB.solve.diagnosis.sql": "SQL الترحيل",
"clientDB.solve.diagnosis.title": "حالة الترحيل",
"clientDB.solve.repair.desc": "إدارة حالة الترحيل يدويًا",
"clientDB.solve.repair.runSQL": "تنفيذ مخصص",
"clientDB.solve.repair.sql.clear": "مسح",
"clientDB.solve.repair.sql.desc": "تنفيذ عبارة SQL مخصصة لإصلاح مشاكل قاعدة البيانات",
"clientDB.solve.repair.sql.markFinished": "تحديد كمنتهية",
"clientDB.solve.repair.sql.placeholder": "أدخل عبارة SQL...",
"clientDB.solve.repair.sql.desc": "تنفيذ أوامر SQL مخصصة لإصلاح مشكلات قاعدة البيانات",
"clientDB.solve.repair.sql.markFinished": "وضع علامة كمكتمل",
"clientDB.solve.repair.sql.placeholder": "أدخل أمر SQL...",
"clientDB.solve.repair.sql.result": "نتيجة التنفيذ",
"clientDB.solve.repair.sql.run": "تنفيذ",
"clientDB.solve.repair.sql.title": "منفذ SQL",
"clientDB.solve.repair.title": "تحكم النقل",
"clientDB.solve.repair.title": "التحكم في الترحيل",
"clientDB.solve.tabs.backup": "نسخ احتياطي واستعادة",
"clientDB.solve.tabs.diagnosis": "تشخيص",
"clientDB.solve.tabs.repair": "إصلاح",
"close": "إغلاق",
"cmdk.about": "حول",
"cmdk.aiModeEmptyState": "أدخل سؤالك في الحقل أعلاه لبدء المحادثة مع الذكاء الاصطناعي",
"cmdk.aiModeHint": "اضغط Enter لطرح سؤال على Lobe AI",
"cmdk.aiModePlaceholder": "اطرح سؤالاً على الذكاء الاصطناعي...",
"cmdk.aiPainting": "الرسم بالذكاء الاصطناعي",
"cmdk.askAI": "اسأل الذكاء الاصطناعي",
"cmdk.askAIHeading": "استخدم الوظائف التالية لمعالجة {{query}}",
"cmdk.askAIHeadingEmpty": "اختر وظيفة ذكاء اصطناعي",
"cmdk.aiModeEmptyState": "اكتب سؤالك أعلاه لبدء الدردشة مع الذكاء الاصطناعي",
"cmdk.aiModeHint": "اضغط Enter للسؤال",
"cmdk.aiModePlaceholder": "اسأل الذكاء الاصطناعي عن أي شيء...",
"cmdk.aiPainting": "فن الذكاء الاصطناعي",
"cmdk.askAI": "اسأل الوكيل",
"cmdk.askAIHeading": "استخدم الميزات التالية لـ {{query}}",
"cmdk.askAIHeadingEmpty": "اختر ميزة ذكاء اصطناعي",
"cmdk.askLobeAI": "اسأل Lobe AI",
"cmdk.community": "المجتمع",
"cmdk.communitySupport": "دعم المجتمع",
"cmdk.contactViaEmail": "اتصل بنا عبر البريد الإلكتروني",
"cmdk.context.agent": "المساعد",
"cmdk.contactViaEmail": "اتصل بنا",
"cmdk.context.agent": "وكيل",
"cmdk.context.community": "المجتمع",
"cmdk.context.general": "عام",
"cmdk.context.group": "المجموعة",
"cmdk.context.group": "مجموعة",
"cmdk.context.memory": "الذاكرة",
"cmdk.context.page": "الوثيقة",
"cmdk.context.painting": "الرسم",
"cmdk.context.resource": "الموارد",
"cmdk.context.page": "صفحة",
"cmdk.context.painting": "رسم",
"cmdk.context.resource": "مورد",
"cmdk.context.settings": "الإعدادات",
"cmdk.discover": "استكشاف",
"cmdk.keyboard.ESC": "ESC",
"cmdk.keyboard.Tab": "Tab",
"cmdk.memory": "الذاكرة",
"cmdk.navigate": "التنقل",
"cmdk.newAgent": "إنشاء مساعد جديد",
"cmdk.newAgentTeam": "إنشاء فريق مساعد جديد",
"cmdk.newLibrary": "إنشاء مكتبة جديدة",
"cmdk.newPage": "إنشاء مستند جديد",
"cmdk.newTopic": "إنشاء موضوع جديد في المساعد الحالي",
"cmdk.navigate": "تنقل",
"cmdk.newAgent": "إنشاء وكيل جديد",
"cmdk.newAgentTeam": "إنشاء مجموعة جديدة",
"cmdk.newLibrary": "مكتبة جديدة",
"cmdk.newPage": "صفحة جديدة",
"cmdk.newTopic": "موضوع جديد في الوكيل الحالي",
"cmdk.noResults": "لم يتم العثور على نتائج",
"cmdk.openSettings": "فتح الإعدادات",
"cmdk.pages": "المستندات",
"cmdk.pages": "الصفحات",
"cmdk.painting": "الرسم",
"cmdk.resource": "الموارد",
"cmdk.search.agent": "مساعد",
"cmdk.search.agents": "مساعدون",
"cmdk.search.assistant": "مساعد الذكاء الاصطناعي",
"cmdk.search.assistants": "مساعدو الذكاء الاصطناعي",
"cmdk.search.communityAgent": "مساعد المجتمع",
"cmdk.search.agent": "وكيل",
"cmdk.search.agents": "وكلاء",
"cmdk.search.assistant": "وكيل",
"cmdk.search.assistants": "وكلاء",
"cmdk.search.communityAgent": "وكيل المجتمع",
"cmdk.search.file": "ملف",
"cmdk.search.files": "ملفات",
"cmdk.search.loading": "جارٍ البحث...",
"cmdk.search.loading": "يتم البحث...",
"cmdk.search.market": "المجتمع",
"cmdk.search.mcp": "خادم MCP",
"cmdk.search.mcps": "خوادم MCP",
"cmdk.search.message": "المحادثة",
"cmdk.search.messages": "المحادثات",
"cmdk.search.page": "المستند",
"cmdk.search.pages": "المستندات",
"cmdk.search.plugin": "الملحق",
"cmdk.search.plugins": "الملحقات",
"cmdk.search.message": "رسالة",
"cmdk.search.messages": "رسائل",
"cmdk.search.page": "صفحة",
"cmdk.search.pages": "صفحات",
"cmdk.search.plugin": "مهارة",
"cmdk.search.plugins": "مهارات",
"cmdk.search.searchMore": "البحث عن المزيد من {{type}}",
"cmdk.search.searching": "نتائج البحث",
"cmdk.search.topic": "موضوع",
@@ -153,95 +153,116 @@
"cmdk.starOnGitHub": "قيّمنا على GitHub",
"cmdk.submitIssue": "إرسال مشكلة",
"cmdk.theme": "السمة",
"cmdk.themeAuto": "اتباع النظام",
"cmdk.themeDark": "الوضع الداكن",
"cmdk.themeLight": "الوضع الفاتح",
"cmdk.themeAuto": "تلقائي",
"cmdk.themeDark": "داكن",
"cmdk.themeLight": "فاتح",
"cmdk.toOpen": "فتح",
"cmdk.toSelect": "تحديد",
"confirm": "تأكيد",
"contact": "اتصل بنا",
"copy": "نسخ",
"copyFail": "فشل في النسخ",
"copyFail": "فشل النسخ",
"copySuccess": "تم النسخ بنجاح",
"dataStatistics.messages": "رسائل",
"dataStatistics.sessions": "جلسات",
"dataStatistics.today": "اليوم",
"dataStatistics.topics": "مواضيع",
"defaultAgent": "مساعد افتراضي",
"defaultSession": "جلسة افتراضية",
"dataStatistics.messages": "الرسائل",
"dataStatistics.sessions": "الوكلاء",
"dataStatistics.today": "الجديد اليوم",
"dataStatistics.topics": "المواضيع",
"defaultAgent": "وكيل مخصص",
"defaultSession": "وكيل مخصص",
"delete": "حذف",
"document": "وثيقة الاستخدام",
"download": حميل",
"duplicate": "إنشاء نسخة",
"edit": حرير",
"document": "دليل المستخدم",
"download": نزيل",
"duplicate": "تكرار",
"edit": عديل",
"errors.invalidFileFormat": "تنسيق الملف غير صالح",
"errors.unimplementedType": "النوع غير مدعوم حالياً، يرجى التحقق من المُخفض",
"errors.unimplementedType": "نوع غير مدعوم. يرجى التحقق من المُخفض.",
"export": "تصدير الإعدادات",
"exportType.agent": "تصدير إعدادات المساعد",
"exportType.agentWithMessage": "تصدير المساعد والرسائل",
"exportType.all": "تصدير الإعدادات العامة وجميع بيانات المساعد",
"exportType.allAgent": "تصدير جميع إعدادات المساعد",
"exportType.allAgentWithMessage": "تصدير جميع المساعدين والرسائل",
"exportType.agent": "تصدير إعدادات الوكيل",
"exportType.agentWithMessage": "تصدير الوكيل والرسائل",
"exportType.all": "تصدير الإعدادات العامة وجميع بيانات الوكلاء",
"exportType.allAgent": "تصدير جميع إعدادات الوكلاء",
"exportType.allAgentWithMessage": "تصدير جميع الوكلاء والرسائل",
"exportType.globalSetting": "تصدير الإعدادات العامة",
"feedback": "تقديم ملاحظات",
"feedback": "ملاحظات",
"feedback.errors.fileTooLarge": "الملف يتجاوز الحجم المسموح به (5 ميغابايت)",
"feedback.errors.submitFailed": "فشل في الإرسال. حاول مرة أخرى.",
"feedback.errors.teamNotFound": "خطأ في التكوين",
"feedback.errors.uploadFailed": "فشل في التحميل",
"feedback.fields.message.label": "الرسالة",
"feedback.fields.message.maxLength": "يجب ألا تتجاوز الرسالة 5000 حرف",
"feedback.fields.message.placeholder": "أخبرنا بالمزيد...",
"feedback.fields.message.required": "يرجى إدخال رسالة",
"feedback.fields.screenshot.hint": "الحد الأقصى 5 ميغابايت. PNG، JPG، GIF",
"feedback.fields.screenshot.label": "لقطة شاشة (اختياري)",
"feedback.fields.screenshot.remove": "إزالة",
"feedback.fields.screenshot.upload": "تحميل لقطة شاشة",
"feedback.fields.screenshot.uploading": "جارٍ التحميل...",
"feedback.fields.title.label": "العنوان",
"feedback.fields.title.maxLength": "يجب ألا يتجاوز العنوان 200 حرف",
"feedback.fields.title.placeholder": "ملخص موجز لسؤالك أو ملاحظاتك",
"feedback.fields.title.required": "يرجى إدخال عنوان",
"feedback.screenshotUploaded": "تم تحميل لقطة الشاشة",
"feedback.submit": "إرسال الملاحظات",
"feedback.success": "شكرًا لك! تم إرسال ملاحظاتك.",
"feedback.title": "كيف يمكننا مساعدتك؟",
"follow": "تابعنا على {{name}}",
"footer.action.feedback": "مشاركة ملاحظاتك الثمينة",
"footer.action.star": م بإضافة نجمة على GitHub",
"footer.action.feedback": "مشاركة الملاحظات",
"footer.action.star": يّمنا على GitHub",
"footer.and": "و",
"footer.feedback.action": "مشاركة الملاحظات",
"footer.feedback.desc": "كل فكرة ومقترح لديك ثمين بالنسبة لنا، نحن نتطلع بشوق لمعرفة آرائك! نرحب بالتواصل معنا لتقديم ملاحظاتك حول ميزات المنتج وتجربة الاستخدام، لمساعدتنا في تحسين LobeChat بشكل أفضل.",
"footer.feedback.title": "مشاركة ملاحظاتك الثمينة على GitHub",
"footer.feedback.desc": "أفكارك تساعدنا على تحسين {{appName}}. شاركنا اقتراحاتك أو ملاحظاتك حول تجربة الاستخدام وسنتولى الأمر.",
"footer.feedback.title": "شارك ملاحظاتك على GitHub",
"footer.later": "لاحقًا",
"footer.star.action": م بإضاءة النجمة",
"footer.star.desc": "إذا كنت تحب منتجنا وترغب في دعمنا، هل يمكنك إضافة نجمة لنا على GitHub؟ هذا الإجراء الصغير له أهمية كبيرة بالنسبة لنا، حيث يمكن أن يلهمنا لتقديم تجربة ميزات مستمرة لك.",
"footer.star.title": "قم بإضاءة النجمة لنا على GitHub",
"footer.title": "هل تحب منتجنا؟",
"fullscreen": "وضع كامل الشاشة",
"footer.star.action": يّمنا",
"footer.star.desc": "إذا أعجبك {{appName}}، فإن تقييمك على GitHub يساعدنا كثيرًا. شكرًا لك.",
"footer.star.title": يّمنا على GitHub",
"footer.title": "هل أعجبك منتجنا؟",
"fullscreen": "وضع ملء الشاشة",
"geminiImageChineseWarning.content": "قد يفشل Nano Banana أحيانًا في إنشاء الصور عند استخدام اللغة الصينية. يُنصح باستخدام اللغة الإنجليزية للحصول على نتائج أفضل.",
"geminiImageChineseWarning.continueGenerate": "متابعة الإنشاء",
"geminiImageChineseWarning.continueGenerate": "متابعة التوليد",
"geminiImageChineseWarning.continueSend": "متابعة الإرسال",
"geminiImageChineseWarning.doNotShowAgain": "عدم الإظهار مرة أخرى",
"geminiImageChineseWarning.title": "تنبيه إدخال اللغة الصينية",
"historyRange": "نطاق التاريخ",
"geminiImageChineseWarning.title": "تنبيه إدخال باللغة الصينية",
"historyRange": "نطاق السجل",
"import": "استيراد",
"importData": "استيراد البيانات",
"importModal.error.desc": "عذرًا، حدث استثناء أثناء عملية استيراد البيانات. يرجى المحاولة مرة أخرى، أو <1>تقديم مشكلتك</1>، وسنقوم بمساعدتك على الفور في تحديد المشكلة.",
"importModal.error.desc": "عذرًا، حدث خطأ أثناء عملية استيراد البيانات. يرجى المحاولة مرة أخرى، أو <1>إرسال طلب</1> وسنساعدك في حل المشكلة في أقرب وقت ممكن.",
"importModal.error.title": "فشل استيراد البيانات",
"importModal.finish.onlySettings": "تم استيراد إعدادات النظام بنجاح",
"importModal.finish.start": "ابدأ الاستخدام",
"importModal.finish.subTitle": "تم استيراد البيانات بنجاح، وقت الاستيراد {{duration}} ثانية. تفاصيل الاستيراد كالتالي:",
"importModal.finish.title": "اكتمال عملية الاستيراد",
"importModal.loading": "جاري استيراد البيانات، يرجى الانتظار...",
"importModal.preparing": "جاري تجهيز وحدة استيراد البيانات...",
"importModal.result.added": "تمت الإضافة بنجاح",
"importModal.result.errors": "حدثت أخطاء أثناء الاستيراد",
"importModal.finish.subTitle": "تم استيراد البيانات بنجاح خلال {{duration}} ثانية. تفاصيل الاستيراد كالتالي:",
"importModal.finish.title": "اكتمل استيراد البيانات",
"importModal.loading": "جارٍ استيراد البيانات، يرجى الانتظار...",
"importModal.preparing": "جارٍ تحضير وحدة استيراد البيانات...",
"importModal.result.added": "تم الاستيراد بنجاح",
"importModal.result.errors": "أخطاء في الاستيراد",
"importModal.result.messages": "الرسائل",
"importModal.result.sessionGroups": "مجموعات الجلسة",
"importModal.result.sessions": "الجلسات",
"importModal.result.skips": "التخطيات",
"importModal.result.sessionGroups": "المجموعات",
"importModal.result.sessions": "الوكلاء",
"importModal.result.skips": "تم تجاوز التكرارات",
"importModal.result.topics": "المواضيع",
"importModal.result.type": "نوع البيانات",
"importModal.result.update": "تحديث السجل",
"importModal.result.update": م تحديث السجل",
"importModal.title": "استيراد البيانات",
"importModal.uploading.desc": "الملف الحالي كبير نسبيًا، يتم رفعه بجد...",
"importModal.uploading.desc": "الملف الحالي كبير ويتم رفعه...",
"importModal.uploading.restTime": "الوقت المتبقي",
"importModal.uploading.speed": "سرعة الرفع",
"importPreview.confirmImport": "تأكيد الاستيراد",
"importPreview.hashLabel": "الهاش",
"importPreview.tables.count": "عدد السجلات",
"importPreview.tables.name": "اسم الجدول",
"importPreview.title": "معاينة بيانات الاستيراد",
"importPreview.totalRecords": "إجمالي السجلات التي سيتم استيرادها {{count}}",
"importPreview.totalTables": "{{count}} جدول",
"information": "المجتمع والمعلومات",
"importPreview.title": "معاينة استيراد البيانات",
"importPreview.totalRecords": "سيتم استيراد ما مجموعه {{count}} سجل",
"importPreview.totalTables": "{{count}} جداول",
"information": "المجتمع والأخبار",
"installPWA": "تثبيت تطبيق المتصفح",
"labs": "المختبرات",
"lang.ar": "العربية",
"lang.auto": "اتبع إعدادات لغة النظام",
"lang.auto": "اتباع إعدادات لغة النظام",
"lang.bg-BG": "البلغارية",
"lang.bn": "البنغالية",
"lang.cs-CZ": "التشيكية",
"lang.da-DK": "الدنماركية",
"lang.da-DK": "الدانماركية",
"lang.de-DE": "الألمانية",
"lang.el-GR": "اليونانية",
"lang.en": "الإنجليزية",
@@ -259,7 +280,7 @@
"lang.nl-NL": "الهولندية",
"lang.no-NO": "النرويجية",
"lang.pl-PL": "البولندية",
"lang.pt-BR": "البرتغالية",
"lang.pt-BR": "البرتغالية (البرازيل)",
"lang.pt-PT": "البرتغالية",
"lang.ro-RO": "الرومانية",
"lang.ru-RU": "الروسية",
@@ -273,31 +294,31 @@
"lang.zh": "الصينية المبسطة",
"lang.zh-CN": "الصينية المبسطة",
"lang.zh-TW": "الصينية التقليدية",
"layoutInitializing": "جاري تحميل التخطيط...",
"legal": "بيان قانوني",
"loading": "جارِ التحميل...",
"mail.business": "شراكات تجارية",
"mail.support": "الدعم عبر البريد الإلكتروني",
"layoutInitializing": "جارٍ تحميل التخطيط...",
"legal": "إخلاء المسؤولية القانونية",
"loading": "جارٍ التحميل...",
"mail.business": "تعاون تجاري",
"mail.support": "دعم عبر البريد الإلكتروني",
"more": "المزيد",
"navPanel.agent": "المساعد",
"navPanel.displayItems": رض العناصر",
"navPanel.agent": "الوكيل",
"navPanel.displayItems": "عناصر العرض",
"navPanel.library": "المكتبة",
"navPanel.searchAgent": "بحث عن مساعد...",
"navPanel.searchResultEmpty": ا توجد نتائج بحث",
"navPanel.searchAgent": "بحث عن وكيل...",
"navPanel.searchResultEmpty": م يتم العثور على نتائج",
"new": "جديد",
"noContent": "لا يوجد محتوى حالياً",
"oauth": "تسجيل الدخول SSO",
"noContent": "لا يوجد محتوى",
"oauth": "تسجيل الدخول الموحد",
"officialSite": "الموقع الرسمي",
"ok": "موافق",
"or": "أو",
"pageSizeItem": "{{count}} عنصر",
"password": "كلمة المرور",
"pin": "تثبيت في الأعلى",
"pin": "تثبيت",
"pinOff": "إلغاء التثبيت",
"privacy": "سياسة الخصوصية",
"regenerate": "إعادة توليد",
"regenerate": "إعادة التوليد",
"releaseNotes": "تفاصيل الإصدار",
"rename": "إعادة تسمية",
"rename": "إعادة التسمية",
"reset": "إعادة تعيين",
"retry": "إعادة المحاولة",
"run": "تشغيل",
@@ -307,65 +328,65 @@
"share": "مشاركة",
"stop": "إيقاف",
"sync.actions.settings": "إعدادات المزامنة",
"sync.actions.sync": "مزامنة فورية",
"sync.actions.sync": "مزامنة الآن",
"sync.awareness.current": "الجهاز الحالي",
"sync.channel": "القناة",
"sync.disabled.actions.enable": "تمكين المزامنة السحابية",
"sync.disabled.actions.settings": "تكوين معلمات المزامنة",
"sync.disabled.desc": "بيانات الجلسة الحالية تُخزن فقط في هذا المتصفح. إذا كنت بحاجة إلى مزامنة البيانات بين عدة أجهزة، يرجى تكوين وتمكين المزامنة السحابية.",
"sync.disabled.title": "لم يتم تشغيل مزامنة البيانات",
"sync.disabled.actions.settings": "إعدادات المزامنة",
"sync.disabled.desc": "يتم تخزين بيانات الجلسة الحالية فقط في هذا المتصفح. إذا كنت بحاجة إلى مزامنة البيانات عبر أجهزة متعددة، يرجى تهيئة وتمكين المزامنة السحابية.",
"sync.disabled.title": "تم تعطيل مزامنة البيانات",
"sync.enabled.title": "مزامنة البيانات",
"sync.status.connecting": "جار الاتصال",
"sync.status.disabled": "مزامنة غير مفعلة",
"sync.status.connecting": "جارٍ الاتصال",
"sync.status.disabled": "المزامنة معطلة",
"sync.status.ready": "متصل",
"sync.status.synced": "تمت المزامنة",
"sync.status.syncing": "جار المزامنة",
"sync.status.syncing": "جارٍ المزامنة",
"sync.status.unconnected": "فشل الاتصال",
"sync.title": "حالة المزامنة",
"sync.unconnected.tip": "فشل اتصال خادم الإشارة، لن يتمكن من إنشاء قناة اتصال نقطية، يرجى التحقق من الشبكة وإعادة المحاولة",
"tab.aiImage": "رسم",
"sync.unconnected.tip": "فشل الاتصال بخادم الإشارة، ولا يمكن إنشاء قناة اتصال من نظير إلى نظير. يرجى التحقق من الشبكة والمحاولة مرة أخرى.",
"tab.aiImage": "الرسومات",
"tab.audio": "الصوت",
"tab.chat": "الدردشة",
"tab.community": "المجتمع",
"tab.discover": "اكتشاف",
"tab.files": "ملفات",
"tab.home": "الصفحة الرئيسية",
"tab.knowledgeBase": "مكتبة الموارد",
"tab.discover": "اكتشف",
"tab.files": "الملفات",
"tab.home": "الرئيسية",
"tab.knowledgeBase": "المكتبة",
"tab.me": "أنا",
"tab.memory": "الذاكرة",
"tab.pages": "المستندات",
"tab.pages": "الصفحات",
"tab.resource": "الموارد",
"tab.search": "البحث",
"tab.search": "بحث",
"tab.setting": "الإعدادات",
"tab.video": "الفيديو",
"telemetry.allow": "السماح",
"telemetry.deny": "رفض",
"telemetry.desc": حن نأمل في الحصول على معلومات استخدامك بشكل مجهول لمساعدتنا في تحسين LobeChat وتوفير تجربة منتج أفضل لك. يمكنك إيقاف ذلك في أي وقت من \"الإعدادات\" - \"حول\".",
"telemetry.learnMore": "معرفة المزيد",
"telemetry.title": "مساعدة LobeChat في التحسن",
"telemetry.desc": ود جمع معلومات الاستخدام بشكل مجهول لمساعدتنا في تحسين {{appName}} وتقديم تجربة أفضل لك. يمكنك تعطيل هذا في أي وقت من خلال الإعدادات - حول.",
"telemetry.learnMore": "اعرف المزيد",
"telemetry.title": "ساعدنا في تحسين {{appName}}",
"temp": "مؤقت",
"terms": "شروط الخدمة",
"unknownError": "خطأ غير معروف",
"update": "تحديث",
"updateAgent": "تحديث معلومات الوكيل",
"upgradeVersion.action": "ترقية",
"upgradeVersion.hasNew": "يوجد تحديث متاح",
"upgradeVersion.newVersion": "هناك إصدار جديد متاح: {{version}}",
"upgradeVersion.hasNew": "تحديث متوفر",
"upgradeVersion.newVersion": "تحديث متوفر: {{version}}",
"userPanel.anonymousNickName": "مستخدم مجهول",
"userPanel.billing": "إدارة الفواتير",
"userPanel.cloud": جربة {{name}}",
"userPanel.community": "نسخة المجتمع",
"userPanel.billing": "إدارة الفوترة",
"userPanel.cloud": شغيل {{name}}",
"userPanel.community": "المجتمع",
"userPanel.data": "تخزين البيانات",
"userPanel.defaultNickname": "مستخدم النسخة المجتمعية",
"userPanel.discord": "الدعم المجتمعي",
"userPanel.docs": "وثائق الاستخدام",
"userPanel.email": "الدعم عبر البريد الإلكتروني",
"userPanel.feedback": "تقديم ملاحظات واقتراحات",
"userPanel.defaultNickname": "مستخدم المجتمع",
"userPanel.discord": "دعم المجتمع",
"userPanel.docs": "الوثائق",
"userPanel.email": "دعم البريد الإلكتروني",
"userPanel.feedback": "اتصل بنا",
"userPanel.help": "مركز المساعدة",
"userPanel.moveGuide": "تم نقل زر الإعدادات إلى هنا",
"userPanel.plans": "خطط الاشتراك",
"userPanel.profile": "إدارة الحساب",
"userPanel.setting": "إعدادات التطبيق",
"userPanel.usages": "إحصاءات الاستخدام",
"userPanel.profile": "الحساب",
"userPanel.setting": "الإعدادات",
"userPanel.usages": "إحصائيات الاستخدام",
"version": "الإصدار"
}
+92 -97
View File
@@ -1,32 +1,26 @@
{
"ArgsInput.addArgument": "إضافة وسيط",
"ArgsInput.argumentPlaceholder": "الوسيط {{index}}",
"ArgsInput.enterFirstArgument": "أدخل الوسيط الأول...",
"DragUpload.dragDesc": "اسحب الملفات هنا، يدعم تحميل عدة صور.",
"DragUpload.dragFileDesc": "اسحب الصور والملفات هنا، يدعم تحميل عدة صور وملفات.",
"ArgsInput.addArgument": "إضافة وسيطة",
"ArgsInput.argumentPlaceholder": "وسيطة {{index}}",
"ArgsInput.enterFirstArgument": "أدخل الوسيطة الأولى...",
"DragUpload.dragDesc": "اسحب الملفات وأفلتها هنا لتحميل صور متعددة.",
"DragUpload.dragFileDesc": "اسحب الصور والملفات وأفلتها هنا لتحميل صور وملفات متعددة.",
"DragUpload.dragFileTitle": "تحميل الملفات",
"DragUpload.dragTitle": "تحميل الصور",
"EmojiPicker.delete": "حذف الصورة الرمزية",
"EmojiPicker.draggerDesc": "انقر أو اسحب الصورة إلى هذه المنطقة للتحميل",
"EmojiPicker.emoji": "رمز تعبيري",
"EmojiPicker.fileTypeError": "يرجى تحميل ملف صورة صالح",
"EmojiPicker.upload": "تحميل الصورة الرمزية",
"EmojiPicker.uploadBtn": "قص وتحميل",
"FileManager.actions.addToKnowledgeBase": "إضافة إلى قاعدة الموارد",
"FileManager.actions.addToOtherKnowledgeBase": "إضافة إلى قاعدة موارد أخرى",
"FileManager.actions.batchChunking": "تقسيم دفعي",
"FileManager.actions.chunking": "تقسيم",
"FileManager.actions.chunkingTooltip": "قم بتقسيم الملف إلى عدة كتل نصية وتحويلها إلى متجهات، يمكن استخدامها في البحث الدلالي والمحادثة حول الملفات",
"FileManager.actions.chunkingUnsupported": "هذا الملف لا يدعم تقسيم الأجزاء",
"FileManager.actions.confirmDelete": "سيتم حذف هذا الملف، ولن يمكن استعادته بعد الحذف، يرجى تأكيد العملية",
"FileManager.actions.confirmDeleteFolder": "سيتم حذف هذا المجلد وجميع محتوياته، ولن يكون بالإمكان استعادته بعد الحذف. يرجى تأكيد العملية.",
"FileManager.actions.confirmDeleteMultiFiles": "سيتم حذف {{count}} ملفًا محددًا، ولن يمكن استعادته بعد الحذف، يرجى تأكيد العملية",
"FileManager.actions.confirmRemoveFromKnowledgeBase": "سيتم إزالة {{count}} ملفًا محددًا من قاعدة الموارد. بعد الإزالة، ستظل الملفات مرئية في جميع الملفات. يرجى تأكيد الإجراء.",
"FileManager.actions.addToKnowledgeBase": "إضافة إلى المكتبة",
"FileManager.actions.addToOtherKnowledgeBase": "إضافة إلى مكتبة أخرى",
"FileManager.actions.batchChunking": "تجزئة جماعية",
"FileManager.actions.chunking": "تجزئة",
"FileManager.actions.chunkingTooltip": "تقسيم الملف إلى أجزاء نصية متعددة وتضمينها للبحث الدلالي والحوار مع الملف.",
"FileManager.actions.chunkingUnsupported": "هذا الملف لا يدعم التجزئة.",
"FileManager.actions.confirmDelete": "أنت على وشك حذف هذا الملف. لا يمكن استعادته بعد الحذف. يرجى تأكيد الإجراء.",
"FileManager.actions.confirmDeleteFolder": "أنت على وشك حذف هذا المجلد وجميع محتوياته. لا يمكن التراجع عن هذا الإجراء. يرجى تأكيد القرار.",
"FileManager.actions.confirmDeleteMultiFiles": "أنت على وشك حذف {{count}} ملفًا محددًا. لا يمكن استعادتها بعد الحذف. يرجى تأكيد الإجراء.",
"FileManager.actions.confirmRemoveFromKnowledgeBase": "أنت على وشك إزالة {{count}} ملف(ات) من المكتبة. ستظل متاحة في جميع الملفات. يرجى التأكيد للمتابعة.",
"FileManager.actions.copyUrl": "نسخ الرابط",
"FileManager.actions.copyUrlSuccess": "تم نسخ عنوان الملف بنجاح",
"FileManager.actions.copyUrlSuccess": "تم نسخ رابط الملف بنجاح.",
"FileManager.actions.createChunkingTask": "جارٍ التحضير...",
"FileManager.actions.deleteSuccess": "تم حذف الملف بنجاح",
"FileManager.actions.downloading": "جارٍ تحميل الملف...",
"FileManager.actions.deleteSuccess": "تم حذف الملف بنجاح.",
"FileManager.actions.downloading": "جارٍ تنزيل الملف...",
"FileManager.actions.goBack": "العودة إلى الصفحة السابقة",
"FileManager.actions.goForward": "الانتقال إلى الصفحة التالية",
"FileManager.actions.goToParent": "الانتقال إلى المجلد الرئيسي",
@@ -34,109 +28,110 @@
"FileManager.actions.moveHere": "نقل إلى هنا",
"FileManager.actions.moveSuccess": "تم نقل الملف بنجاح",
"FileManager.actions.moveToFolder": "نقل إلى...",
"FileManager.actions.moveToRoot": "نقل إلى الدليل الجذري",
"FileManager.actions.removeFromKnowledgeBase": "إزالة من قاعدة الموارد",
"FileManager.actions.removeFromKnowledgeBaseSuccess": "تمت إزالة الملف بنجاح",
"FileManager.actions.moveToRoot": "نقل إلى الدليل الرئيسي",
"FileManager.actions.moving": "جارٍ النقل...",
"FileManager.actions.removeFromKnowledgeBase": "إزالة من المكتبة",
"FileManager.actions.removeFromKnowledgeBaseSuccess": "تمت إزالة الملف بنجاح.",
"FileManager.actions.rename": "إعادة التسمية",
"FileManager.actions.renameError": "فشل في إعادة التسمية",
"FileManager.actions.renameSuccess": "تمت إعادة التسمية بنجاح",
"FileManager.bottom": "لقد وصلت إلى النهاية",
"FileManager.config.showFilesInKnowledgeBase": "عرض المحتوى في قاعدة الموارد",
"FileManager.emptyStatus.actions.file": "رفع ملف",
"FileManager.emptyStatus.actions.folder": "رفع مجلد",
"FileManager.emptyStatus.actions.knowledgeBase": "إنشاء قاعدة موارد جديدة",
"FileManager.bottom": "لقد وصلت إلى النهاية.",
"FileManager.config.showFilesInKnowledgeBase": "عرض المحتوى في المكتبة",
"FileManager.emptyStatus.actions.file": "تحميل ملف",
"FileManager.emptyStatus.actions.folder": "تحميل مجلد",
"FileManager.emptyStatus.actions.knowledgeBase": "إنشاء مكتبة",
"FileManager.emptyStatus.or": "أو",
"FileManager.emptyStatus.title": "قم بسحب الملف أو المجلد هنا",
"FileManager.noFolders": "لا توجد مجلدات حالياً",
"FileManager.emptyStatus.title": "اسحب الملفات أو المجلدات إلى هنا",
"FileManager.noFolders": "لا توجد مجلدات متاحة",
"FileManager.sort.dateAdded": "تاريخ الإضافة",
"FileManager.sort.name": "الاسم",
"FileManager.sort.size": "الحجم",
"FileManager.title.createdAt": "تاريخ الإنشاء",
"FileManager.title.size": "الحجم",
"FileManager.title.title": "ملف",
"FileManager.total.fileCount": "إجمالي {{count}} عنصر",
"FileManager.total.selectedCount": "تم تحديد {{count}} عنصر",
"FileManager.title.title": "الملف",
"FileManager.total.fileCount": "الإجمالي {{count}} عنصر",
"FileManager.total.selectedCount": "المحدد {{count}} عنصر",
"FileManager.view.list": "عرض القائمة",
"FileManager.view.masonry": "عرض الشبكة",
"FileParsingStatus.chunks.embeddingStatus.empty": "لم يتم تحويل كتل النص بالكامل إلى متجهات، مما سيؤدي إلى عدم توفر وظيفة البحث الدلالي، لتحسين جودة البحث، يرجى تحويل كتل النص إلى متجهات",
"FileParsingStatus.chunks.embeddingStatus.error": "فشل في تحويل البيانات إلى متجهات",
"FileParsingStatus.chunks.embeddingStatus.errorResult": "فشل في تحويل البيانات إلى متجهات، يرجى التحقق والمحاولة مرة أخرى. سبب الفشل:",
"FileParsingStatus.chunks.embeddingStatus.processing": "يتم تحويل كتل النص إلى متجهات، يرجى الانتظار",
"FileParsingStatus.chunks.embeddingStatus.success": "تم تحويل جميع كتل النص الحالية إلى متجهات",
"FileParsingStatus.chunks.embeddings": "تحويل إلى متجهات",
"FileParsingStatus.chunks.status.error": "فشل في التقسيم",
"FileParsingStatus.chunks.status.errorResult": "فشل في التقسيم، يرجى التحقق والمحاولة مرة أخرى. سبب الفشل:",
"FileParsingStatus.chunks.status.processing": "جارٍ التقسيم",
"FileParsingStatus.chunks.status.processingTip": "الخادم يقوم بتقسيم كتل النص، إغلاق الصفحة لا يؤثر على تقدم التقسيم",
"GoBack.back": ودة",
"FileParsingStatus.chunks.embeddingStatus.empty": "لم يتم تضمين جميع أجزاء النص، مما يجعل ميزة البحث الدلالي غير متاحة. لتحسين جودة البحث، يرجى تضمين أجزاء النص.",
"FileParsingStatus.chunks.embeddingStatus.error": "فشل في التضمين",
"FileParsingStatus.chunks.embeddingStatus.errorResult": "فشل في التوجيه الشعاعي، يرجى التحقق والمحاولة مرة أخرى. تفاصيل الخطأ:",
"FileParsingStatus.chunks.embeddingStatus.processing": "جارٍ تضمين أجزاء النص، يرجى الانتظار.",
"FileParsingStatus.chunks.embeddingStatus.success": "تم تضمين جميع أجزاء النص الحالية",
"FileParsingStatus.chunks.embeddings": "التضمين",
"FileParsingStatus.chunks.status.error": "فشل في التجزئة",
"FileParsingStatus.chunks.status.errorResult": "فشل في التجزئة، يرجى التحقق والمحاولة مرة أخرى. تفاصيل الخطأ:",
"FileParsingStatus.chunks.status.processing": "جارٍ التجزئة",
"FileParsingStatus.chunks.status.processingTip": "الخادم يقوم بتقسيم أجزاء النص؛ إغلاق الصفحة لن يؤثر على تقدم التجزئة.",
"GoBack.back": "رجوع",
"HtmlPreview.actions.download": "تنزيل",
"HtmlPreview.actions.preview": "معاينة",
"HtmlPreview.iframeTitle": "معاينة HTML",
"HtmlPreview.mode.code": "رمز",
"HtmlPreview.mode.code": "كود",
"HtmlPreview.mode.preview": "معاينة",
"HtmlPreview.title": "معاينة HTML",
"ImageUpload.actions.changeImage": "انقر لتغيير الصورة",
"ImageUpload.actions.dropMultipleFiles": "لا يدعم تحميل ملفات متعددة في آن واحد، سيتم استخدام الملف الأول فقط",
"ImageUpload.actions.dropMultipleFiles": "تحميل ملفات متعددة غير مدعوم؛ سيتم استخدام الملف الأول فقط",
"ImageUpload.placeholder.primary": "إضافة صورة",
"ImageUpload.placeholder.secondary": "انقر أو اسحب للإرفاق",
"KeyValueEditor.addButton": "إضافة صف جديد",
"ImageUpload.placeholder.secondary": "انقر أو اسحب للتحميل",
"KeyValueEditor.addButton": "إضافة صف",
"KeyValueEditor.deleteTooltip": "حذف",
"KeyValueEditor.duplicateKeyError": "يجب أن يكون اسم المفتاح فريدًا",
"KeyValueEditor.duplicateKeyError": "يجب أن يكون المفتاح فريدًا",
"KeyValueEditor.keyPlaceholder": "المفتاح",
"KeyValueEditor.valuePlaceholder": "القيمة",
"LocalFile.action.open": "فتح",
"LocalFile.action.showInFolder": "عرض في المجلد",
"MaxTokenSlider.unlimited": "غير محدود",
"ModelSelect.featureTag.custom": "نموذج مخصص، الإعداد الافتراضي يدعم الاستدعاء الوظيفي والتعرف البصري، يرجى التحقق من قدرة النموذج على القيام بذلك بناءً على الحالة الفعلية",
"ModelSelect.featureTag.file": "يدعم هذا النموذج قراءة وتعرف الملفات المرفوعة",
"ModelSelect.featureTag.functionCall": "يدعم هذا النموذج استدعاء الوظائف",
"ModelSelect.featureTag.imageOutput": "يدعم هذا النموذج إنشاء الصور",
"ModelSelect.featureTag.reasoning": "يدعم هذا النموذج التفكير العميق",
"ModelSelect.featureTag.search": "يدعم هذا النموذج البحث عبر الإنترنت",
"ModelSelect.featureTag.tokens": "يدعم هذا النموذج حتى {{tokens}} رمزًا في جلسة واحدة",
"ModelSelect.featureTag.video": "هذا النموذج يدعم التعرف على الفيديو",
"ModelSelect.featureTag.vision": "يدعم هذا النموذج التعرف البصري",
"ModelSelect.removed": "هذا النموذج لم يعد متوفر في القائمة، سيتم إزالته تلقائيًا إذا تم إلغاء تحديده",
"ModelSwitchPanel.emptyModel": "لا توجد نماذج ممكن تمكينها، يرجى الانتقال إلى الإعدادات لتمكينها",
"ModelSwitchPanel.emptyProvider": "لا توجد مزودات مفعلة، يرجى الذهاب إلى الإعدادات لتفعيلها",
"ModelSwitchPanel.goToSettings": "اذهب إلى الإعدادات",
"ModelSwitchPanel.provider": "مزود",
"ModelSwitchPanel.title": "نموذج",
"MultiImagesUpload.actions.uploadMore": "انقر أو اسحب لإضافة المزيد",
"MultiImagesUpload.modal.complete": "اكتمل",
"ModelSelect.featureTag.custom": "نموذج مخصص، يدعم افتراضيًا استدعاء الوظائف والتعرف البصري. يرجى التحقق من توفر هذه القدرات حسب الحالة الفعلية.",
"ModelSelect.featureTag.file": "يدعم هذا النموذج تحميل الملفات للقراءة والتعرف.",
"ModelSelect.featureTag.functionCall": "يدعم هذا النموذج استدعاء الوظائف.",
"ModelSelect.featureTag.imageOutput": "يدعم هذا النموذج توليد الصور.",
"ModelSelect.featureTag.reasoning": "يدعم هذا النموذج التفكير العميق.",
"ModelSelect.featureTag.search": "يدعم هذا النموذج البحث عبر الإنترنت.",
"ModelSelect.featureTag.tokens": "يدعم هذا النموذج حتى {{tokens}} رمزًا في جلسة واحدة.",
"ModelSelect.featureTag.video": "يدعم هذا النموذج التعرف على الفيديو",
"ModelSelect.featureTag.vision": "يدعم هذا النموذج التعرف البصري.",
"ModelSelect.removed": "النموذج غير موجود في القائمة. سيتم حذفه تلقائيًا إذا تم إلغاء تحديده.",
"ModelSwitchPanel.emptyModel": "لا يوجد نموذج مفعل. يرجى الذهاب إلى الإعدادات لتفعيله.",
"ModelSwitchPanel.emptyProvider": "لا يوجد مزود مفعل. يرجى الذهاب إلى الإعدادات لتفعيل أحدهم.",
"ModelSwitchPanel.goToSettings": "الذهاب إلى الإعدادات",
"ModelSwitchPanel.provider": "المزود",
"ModelSwitchPanel.title": "النموذج",
"MultiImagesUpload.actions.uploadMore": "انقر أو اسحب لتحميل المزيد",
"MultiImagesUpload.modal.complete": "تم",
"MultiImagesUpload.modal.newFileIndicator": "جديد",
"MultiImagesUpload.modal.selectImageToPreview": "يرجى اختيار صورة للمعاينة",
"MultiImagesUpload.modal.title": "إدارة الصور ({{count}})",
"MultiImagesUpload.modal.upload": "تحميل الصور",
"MultiImagesUpload.placeholder.primary": "انقر أو اسحب لتحميل الصور",
"MultiImagesUpload.placeholder.secondary": "يدعم اختيار عدة صور",
"MultiImagesUpload.progress.uploadingWithCount": "تم تحميل {{completed}} من أصل {{total}}",
"MultiImagesUpload.validation.fileSizeExceeded": "تجاوز حجم الملف الحد المسموح",
"MultiImagesUpload.validation.fileSizeExceededDetail": "{{fileName}} ({{actualSize}}) يتجاوز الحد الأقصى للحجم {{maxSize}}",
"MultiImagesUpload.validation.fileSizeExceededMultiple": "{{count}} ملفات تتجاوز الحد الأقصى للحجم {{maxSize}}: {{fileList}}",
"MultiImagesUpload.validation.imageCountExceeded": "تجاوز عدد الصور الحد المسموح",
"OllamaSetupGuide.action.close": "إغلاق الإشعار",
"MultiImagesUpload.placeholder.secondary": "يدعم اختيار صور متعددة",
"MultiImagesUpload.progress.uploadingWithCount": "{{completed}}/{{total}} تم تحميلها",
"MultiImagesUpload.validation.fileSizeExceeded": "يتجاوز حجم الملف الحد الأقصى المسموح به",
"MultiImagesUpload.validation.fileSizeExceededDetail": "{{fileName}} ({{actualSize}}) يتجاوز الحد الأقصى المسموح به وهو {{maxSize}}",
"MultiImagesUpload.validation.fileSizeExceededMultiple": "{{count}} ملف(ات) تتجاوز الحد الأقصى المسموح به وهو {{maxSize}}: {{fileList}}",
"MultiImagesUpload.validation.imageCountExceeded": م تجاوز الحد الأقصى لعدد الصور",
"OllamaSetupGuide.action.close": "إغلاق النافذة",
"OllamaSetupGuide.action.start": "تم التثبيت",
"OllamaSetupGuide.cors.description": "بسبب قيود أمان المتصفح، تحتاج إلى تكوين CORS لـ Ollama لاستخدامه بشكل صحيح.",
"OllamaSetupGuide.cors.linux.env": "أضف `Environment` تحت قسم [Service]، وأضف متغير البيئة OLLAMA_ORIGINS:",
"OllamaSetupGuide.cors.description": "بسبب قيود أمان المتصفح، تحتاج إلى تكوين إعدادات الوصول عبر النطاقات ليعمل Ollama بشكل صحيح.",
"OllamaSetupGuide.cors.linux.env": "أضف `Environment` ضمن قسم [Service]، وقم بتعيين متغير البيئة OLLAMA_ORIGINS:",
"OllamaSetupGuide.cors.linux.reboot": "أعد تحميل systemd وأعد تشغيل Ollama",
"OllamaSetupGuide.cors.linux.systemd": "استخدم systemd لتحرير خدمة ollama:",
"OllamaSetupGuide.cors.macos": "يرجى فتح تطبيق «الطرفية» ولصق الأوامر التالية ثم الضغط على Enter للتنفيذ",
"OllamaSetupGuide.cors.reboot": "يرجى إعادة تشغيل خدمة Ollama بعد الانتهاء من التنفيذ",
"OllamaSetupGuide.cors.title": "تكوين Ollama للسماح بالوصول عبر النطاقات المتعددة",
"OllamaSetupGuide.cors.windows": "على نظام Windows، انقر على «لوحة التحكم»، ثم انتقل إلى تحرير متغيرات البيئة للنظام. أنشئ متغير بيئة جديد باسم «OLLAMA_ORIGINS» لقائمة المستخدم الخاصة بك، وقيمته هي *، ثم انقر على «موافق/تطبيق» لحفظ التغييرات.",
"OllamaSetupGuide.install.description": "يرجى التأكد من أنك قد قمت بتشغيل Ollama، إذا لم تقم بتنزيل Ollama، يرجى زيارة الموقع الرسمي <1>للتنزيل</1>",
"OllamaSetupGuide.install.docker": "إذا كنت تفضل استخدام Docker، فإن Ollama يوفر أيضًا صورة Docker رسمية، يمكنك سحبها باستخدام الأمر التالي:",
"OllamaSetupGuide.install.linux.command": "قم بتثبيت باستخدام الأمر التالي:",
"OllamaSetupGuide.install.linux.manual": "أو يمكنك الرجوع إلى <1>دليل التثبيت اليدوي لنظام Linux</1> للتثبيت بنفسك.",
"OllamaSetupGuide.cors.linux.systemd": "قم بتحرير خدمة ollama باستخدام systemd:",
"OllamaSetupGuide.cors.macos": "يرجى فتح تطبيق 'Terminal'، ولصق الأمر التالي، ثم الضغط على Enter لتنفيذه.",
"OllamaSetupGuide.cors.reboot": "يرجى إعادة تشغيل خدمة Ollama بعد الانتهاء من التنفيذ.",
"OllamaSetupGuide.cors.title": "تكوين Ollama للوصول عبر النطاقات",
"OllamaSetupGuide.cors.windows": "في Windows، انقر على 'لوحة التحكم' واذهب إلى تحرير متغيرات بيئة النظام. أنشئ متغير بيئة جديد باسم 'OLLAMA_ORIGINS' لحساب المستخدم الخاص بك، واجعل القيمة *، ثم انقر على 'موافق/تطبيق' للحفظ.",
"OllamaSetupGuide.install.description": "يرجى التأكد من أنك قمت بتشغيل Ollama. إذا لم تقم بتنزيله بعد، يرجى زيارة الموقع الرسمي لـ<1>تحميله</1>.",
"OllamaSetupGuide.install.docker": "إذا كنت تفضل استخدام Docker، فإن Ollama يوفر أيضًا صورة Docker رسمية يمكنك سحبها باستخدام الأمر التالي:",
"OllamaSetupGuide.install.linux.command": "قم بالتثبيت باستخدام الأمر التالي:",
"OllamaSetupGuide.install.linux.manual": "بدلاً من ذلك، يمكنك الرجوع إلى <1>دليل التثبيت اليدوي لنظام Linux</1>.",
"OllamaSetupGuide.install.title": "تثبيت وتشغيل تطبيق Ollama محليًا",
"OllamaSetupGuide.install.windowsTab": "Windows (نسخة المعاينة)",
"Thinking.thinking": "في حالة تفكير عميق...",
"Thinking.thought": "لقد فكرت بعمق (استغرق الأمر {{duration}} ثانية)",
"Thinking.thoughtWithDuration": "لقد فكرت بعمق",
"devTools.cache.empty": "ذاكرة التخزين المؤقت فارغة",
"devTools.metadata.empty": "لا توجد بيانات وصفية حالياً",
"knowledgeBase.empty.description": "أنشئ قاعدة موارد لتنظيم وإدارة ملفاتك",
"knowledgeBase.empty.search": "لم يتم العثور على قاعدة موارد مطابقة",
"knowledgeBase.empty.title": "لا توجد قواعد موارد حالياً"
"OllamaSetupGuide.install.windowsTab": "Windows (معاينة)",
"Thinking.thinking": "تفكير عميق...",
"Thinking.thought": "تم التفكير بعمق (في {{duration}} ثانية)",
"Thinking.thoughtWithDuration": "تم التفكير بعمق",
"devTools.cache.empty": "الذاكرة المؤقتة فارغة",
"devTools.metadata.empty": "لا توجد بيانات وصفية متاحة",
"knowledgeBase.empty.description": "أنشئ مكتبة لتنظيم وإدارة مواردك",
"knowledgeBase.empty.search": "لم يتم العثور على مكتبة مطابقة",
"knowledgeBase.empty.title": "لا توجد مكتبة متاحة"
}
+80
View File
@@ -0,0 +1,80 @@
{
"authResult.failed.desc": "يرجى المحاولة مرة أخرى أو التبديل إلى طريقة تسجيل دخول مختلفة",
"authResult.failed.title": "فشل التفويض",
"authResult.success.desc": "يرجى النقر على زر البدء أدناه لمتابعة استخدام LobeHub Desktop",
"authResult.success.title": "تم التفويض بنجاح",
"back": "رجوع",
"navigation.next": "متابعة",
"next": "التالي",
"screen1.description": "منصة إنتاجية مدعومة بالذكاء الاصطناعي مع وكلاء ذكيين",
"screen1.navigation.next": "ابدأ الإعداد",
"screen1.slogan.line1": "مصمم من أجلك",
"screen1.slogan.line2": "الفرد الخارق",
"screen2.badge": "الميزات",
"screen2.description": "قدرات ذكاء اصطناعي متقدمة مصممة لتناسب سير عملك",
"screen2.features.1.subtitle": "توليد الصور",
"screen2.features.1.title": "أنشئ ما تشعر به",
"screen2.features.2.subtitle": "سوق MCP",
"screen2.features.2.title": "اكتشف، تواصل، ووسّع",
"screen2.features.3.subtitle": "بحث ذكي على الويب",
"screen2.features.3.title": "معرفة العالم جاهزة",
"screen2.features.4.subtitle": "مزامنة عبر الأنظمة",
"screen2.features.4.title": "مساحة عملك، في أي مكان",
"screen2.features.5.subtitle": "القطع الفنية",
"screen2.features.5.title": "الذكاء الاصطناعي يلتقي الإبداع البصري",
"screen2.features.6.subtitle": "مزودو ذكاء اصطناعي متعددون",
"screen2.features.6.title": "منصة واحدة، جميع النماذج",
"screen2.title": "كل ما تحتاجه",
"screen3.actions.grantAccess": "منح الإذن",
"screen3.actions.granted": "تم منح الإذن",
"screen3.actions.openSettings": "فتح الإعدادات",
"screen3.badge": "الأذونات",
"screen3.description": "امنح الأذونات لفتح الإمكانات الكاملة للوكلاء والمجموعات. يمكنك إدارة هذه الأذونات في أي وقت من الإعدادات.",
"screen3.permissions.1.description": "تلقي الإشعارات عند اكتمال المهام، أو استجابة الوكلاء، أو وصول التحديثات المهمة",
"screen3.permissions.1.title": "الإشعارات",
"screen3.permissions.2.description": "الوصول إلى الملفات والمجلدات لتمكين تحليل المستندات، وإنشاء قواعد المعرفة، وسير عمل معالجة الملفات",
"screen3.permissions.2.title": "الوصول إلى الملفات",
"screen3.permissions.3.description": "التقاط محتوى الشاشة والصوت للتفاعل الصوتي، وتحليل الشاشة، والمساعدة متعددة الوسائط",
"screen3.permissions.3.title": "الشاشة والصوت",
"screen3.permissions.4.description": "تمكين الأتمتة على مستوى النظام لتنفيذ سير العمل بسلاسة عبر التطبيقات",
"screen3.permissions.4.title": "إمكانية الوصول",
"screen3.title": "منح الأذونات",
"screen3.title2": "فعّل الوصول لفتح جميع الميزات",
"screen3.title3": "يمكنك إدارة هذه الأذونات في أي وقت من الإعدادات",
"screen4.badge": "الخصوصية",
"screen4.description": "اختر كيف تريد مشاركة البيانات. يساعدنا اختيارك على التحسين، ويمكنك تغيير ذلك في أي وقت من الإعدادات.",
"screen4.footerNote": "يمكنك تغيير ذلك في أي وقت من الإعدادات",
"screen4.navigation.next": "متابعة",
"screen4.privacy.description": "احتفظ بكل شيء محليًا. لا يتم جمع أو مشاركة أي بيانات — خصوصية كاملة لمحادثاتك وسير عملك.",
"screen4.privacy.items.1": "لا جمع للبيانات",
"screen4.privacy.items.2": "لا تحليلات استخدام",
"screen4.privacy.items.3": "جميع المعالجة تتم محليًا",
"screen4.privacy.title": "وضع الخصوصية",
"screen4.share.description": "شارك بيانات استخدام مجهولة المصدر لمساعدتنا في تحسين LobeHub. يساعدنا ذلك على فهم كيفية استخدام الوكلاء وتحسينهم.",
"screen4.share.items.1": "مقاييس الأداء",
"screen4.share.items.2": "أنماط استخدام النماذج",
"screen4.share.items.3": "تفاعلات الميزات",
"screen4.share.title": "ساعد في تحسين LobeHub",
"screen4.title": "كيف تود مشاركة البيانات؟",
"screen4.title2": "اختيارك يساعدنا على التحسين",
"screen4.title3": "يمكنك تغيير ذلك في أي وقت من الإعدادات",
"screen5.actions.connectToServer": "الاتصال بالخادم",
"screen5.actions.connecting": "جارٍ الاتصال...",
"screen5.actions.signInCloud": "تسجيل الدخول إلى LobeHub Cloud",
"screen5.actions.signOut": "تسجيل الخروج",
"screen5.actions.signingIn": "جارٍ تسجيل الدخول...",
"screen5.actions.signingOut": "جارٍ تسجيل الخروج...",
"screen5.actions.tryAgain": "حاول مرة أخرى",
"screen5.badge": "تسجيل الدخول",
"screen5.description": "سجّل الدخول لمزامنة الوكلاء والمجموعات والإعدادات والسياق عبر جميع الأجهزة.",
"screen5.errors.desktopOnlyOidc": "تفويض OIDC متاح فقط في تطبيق سطح المكتب.",
"screen5.methods.cloud.description": "سجّل الدخول باستخدام حساب LobeHub Cloud الخاص بك لمزامنة كل شيء بسلاسة",
"screen5.methods.cloud.name": "LobeHub Cloud",
"screen5.methods.selfhost.description": "اتصل بنسختك الخاصة من خادم LobeHub",
"screen5.methods.selfhost.name": "نسخة مستضافة ذاتيًا",
"screen5.navigation.next": "ابدأ الآن",
"screen5.selfhost.endpointPlaceholder": "أدخل عنوان خادمك (مثال: https://your-server.com)",
"screen5.title": "سجّل الدخول للمزامنة عبر الأجهزة",
"screen5.title2": "احتفظ ببياناتك متزامنة في كل مكان",
"screen5.title3": "بياناتك تحت سيطرتك دائمًا"
}
+296 -296
View File
@@ -1,214 +1,214 @@
{
"assistant.favorite": "إضافة إلى المفضلة",
"assistant.favoriteFailed": "فشل في الإضافة إلى المفضلة",
"assistant.favoriteSuccess": "تمت الإضافة إلى المفضلة",
"assistant.favorite": "حفظ",
"assistant.favoriteFailed": "فشل في الحفظ",
"assistant.favoriteSuccess": "تم الحفظ",
"assistant.like": "إعجاب",
"assistant.likeFailed": "فشل في الإعجاب",
"assistant.likeSuccess": "تم الإعجاب",
"assistant.unfavorite": زالة من المفضلة",
"assistant.unfavoriteFailed": "فشل في الإزالة من المفضلة",
"assistant.unfavoriteSuccess": "تمت الإزالة من المفضلة",
"assistant.unfavorite": لغاء الحفظ",
"assistant.unfavoriteFailed": "فشل في إلغاء الحفظ",
"assistant.unfavoriteSuccess": "تم إلغاء الحفظ",
"assistant.unlike": "إلغاء الإعجاب",
"assistant.unlikeSuccess": "تم إلغاء الإعجاب",
"assistants.addAgent": "إضافة مساعد",
"assistants.addAgentAndConverse": "إضافة مساعد والدردشة",
"assistants.addAgentSuccess": "تمت الإضافة بنجاح",
"assistants.conversation.l1": "مرحبًا، أنا **{{name}}**، يمكنك أن تسألني أي سؤال وسأبذل قصارى جهدي للإجابة ~",
"assistants.conversation.l2": "إليك مقدمة عن قدراتي: ",
"assistants.conversation.l3": "لنبدأ المحادثة!",
"assistants.description": "مقدمة المساعد",
"assistants.addAgent": "إضافة وكيل",
"assistants.addAgentAndConverse": "إضافة وكيل والدردشة",
"assistants.addAgentSuccess": "تمت الإضافة",
"assistants.conversation.l1": "مرحبًا، أنا **{{name}}**. شاركني هدفك أو السياق وسنتعاون من هنا.",
"assistants.conversation.l2": "إليك ما يمكنني فعله:",
"assistants.conversation.l3": "ابدأ المحادثة",
"assistants.description": "حول هذا الوكيل",
"assistants.detail": "تفاصيل",
"assistants.details.capabilities.knowledge.desc": حتوي المساعد على مكتبات معرفية مدمجة لمساعدتك في الإجابة على المزيد من الأسئلة.",
"assistants.details.capabilities.knowledge.title": "المكتبات المعرفية",
"assistants.details.capabilities.plugin.desc": "المساعد مزود بالإضافة التالية لمساعدتك في إتمام المزيد من المهام.",
"assistants.details.capabilities.plugin.title": "الإضافات المدمجة",
"assistants.details.capabilities.title": "قدرات المساعد",
"assistants.details.overview.example": "عرض المساعد",
"assistants.details.capabilities.knowledge.desc": تضمن هذا الوكيل المكتبات التالية للمساعدة في الإجابة على المزيد من الأسئلة.",
"assistants.details.capabilities.knowledge.title": "المكتبة",
"assistants.details.capabilities.plugin.desc": "يتضمن هذا الوكيل المهارات التالية لمساعدتك في إنجاز المزيد من المهام.",
"assistants.details.capabilities.plugin.title": "المهارات المدمجة",
"assistants.details.capabilities.title": "قدرات الوكيل",
"assistants.details.overview.example": "عرض توضيحي للوكيل",
"assistants.details.overview.title": "نظرة عامة",
"assistants.details.related.listTitle": "المساعدون المرتبطون",
"assistants.details.related.listTitle": "وكلاء ذوو صلة",
"assistants.details.related.more": "عرض المزيد",
"assistants.details.related.title": "اقتراحات ذات صلة",
"assistants.details.sidebar.toc": "المحتوى",
"assistants.details.summary.title": "ما الذي يمكنك فعله باستخدام هذا المساعد؟",
"assistants.details.systemRole.openingMessage": "رسالة الافتتاح",
"assistants.details.systemRole.openingQuestions": "أسئلة الافتتاح",
"assistants.details.systemRole.title": "إعدادات المساعد",
"assistants.details.version.empty": "لا توجد إصدارات سابقة",
"assistants.details.related.title": "وكلاء مشابهون",
"assistants.details.sidebar.toc": "جدول المحتويات",
"assistants.details.summary.title": "ما الذي يمكنك فعله باستخدام هذا الوكيل؟",
"assistants.details.systemRole.openingMessage": "رسالة الترحيب",
"assistants.details.systemRole.openingQuestions": "أسئلة البداية",
"assistants.details.systemRole.title": "ملف تعريف الوكيل",
"assistants.details.version.empty": "لا توجد إصدارات سابقة بعد",
"assistants.details.version.status.archived": "مؤرشف",
"assistants.details.version.status.deprecated": "مرفوض",
"assistants.details.version.status.unpublished": "قيد المراجعة",
"assistants.details.version.table.isLatest": "أحدث إصدار",
"assistants.details.version.table.isValidated": "تم التحقق منه",
"assistants.details.version.table.publishAt": "تاريخ النشر",
"assistants.details.version.table.version": "رقم الإصدار",
"assistants.details.version.table.version": "الإصدار",
"assistants.details.version.title": "سجل الإصدارات",
"assistants.downloads": "عدد التنزيلات",
"assistants.duplicateAdd.content": "لقد قمت بإضافة المساعد «{{title}}» مسبقًا، هل ترغب في إضافته مرة أخرى؟",
"assistants.duplicateAdd.ok": "تأكيد الإضافة",
"assistants.duplicateAdd.title": "تأكيد الإضافة المكررة",
"assistants.empty.description": "حاول تعديل معايير التصفية أو زيارة المجتمع لاكتشاف المزيد من المساعدين",
"assistants.empty.search": "لم يتم العثور على مساعدين مطابقين",
"assistants.empty.title": ا يوجد مساعدين حالياً",
"assistants.list": "قائمة المساعدين",
"assistants.downloads": "التنزيلات",
"assistants.duplicateAdd.content": "{{title}} موجود بالفعل في وكلائك. هل ترغب في إضافة نسخة أخرى؟",
"assistants.duplicateAdd.ok": "إضافة نسخة",
"assistants.duplicateAdd.title": "إضافة نسخة مكررة؟",
"assistants.empty.description": "حاول تعديل الفلاتر، أو استكشف المزيد من الوكلاء في المجتمع.",
"assistants.empty.search": "لم يتم العثور على وكلاء مطابقين",
"assistants.empty.title": م يتم العثور على وكلاء",
"assistants.list": "قائمة الوكلاء",
"assistants.marketSource.label": "تبديل مصدر المجتمع",
"assistants.marketSource.legacy": "المجتمع القديم",
"assistants.marketSource.new": "المجتمع الجديد",
"assistants.more": "المزيد",
"assistants.plugins": "دمج الإضافات",
"assistants.recentSubmits": "آخر التحديثات",
"assistants.sorts.createdAt": "تم النشر مؤخراً",
"assistants.sorts.identifier": "معرف المساعد",
"assistants.sorts.knowledgeCount": "عدد المكتبات المعرفية",
"assistants.sorts.myown": "عرض مساعدي",
"assistants.sorts.pluginCount": "عدد الإضافات",
"assistants.sorts.title": "اسم المساعد",
"assistants.sorts.tokenUsage": "استهلاك التوكن",
"assistants.status.archived.reasons.official": "تمت إزالة المساعد من قبل الإدارة لأسباب أمنية أو سياسية",
"assistants.status.archived.reasons.owner": "قام مالك المساعد بإزالته أو أرشفته طوعًا",
"assistants.status.archived.subtitle": "المساعد الذي تحاول الوصول إليه تم أرشفته للأسباب التالية المحتملة:",
"assistants.status.archived.title": "تم أرشفة المساعد",
"assistants.status.backToMarket": "العودة إلى مجتمع المساعد",
"assistants.status.deprecated.reasons.official": "تمت إزالة المساعد من قبل الإدارة لأسباب أمنية أو سياسية",
"assistants.status.deprecated.reasons.owner": "قام مالك المساعد بإزالته أو رفضه طوعًا",
"assistants.status.deprecated.subtitle": "المساعد الذي تحاول الوصول إليه تم رفضه للأسباب التالية المحتملة:",
"assistants.status.deprecated.title": "تم رفض المساعد",
"assistants.status.support": "لأي استفسارات، يرجى نسخ الرابط وإرساله إلى <email>support@lobehub.com</email>.",
"assistants.status.unpublished.subtitle": "المساعد الذي تحاول الوصول إليه يخضع حاليًا لمراجعة الإصدار. إذا كان لديك أي استفسار، يرجى نسخ الرابط وإرساله إلى <email>support@lobehub.com</email>.",
"assistants.status.unpublished.title": "المساعد قيد المراجعة",
"assistants.suggestions": "اقتراحات ذات صلة",
"assistants.systemRole": "إعدادات المساعد",
"assistants.tokenUsage": "استهلاك توكنات تعليمات المساعد",
"assistants.try": "جرب",
"assistants.withKnowledge": "هذا المساعد مزود بمكتبات معرفية",
"assistants.withPlugin": "هذا المساعد مزود بالإضافة",
"back": "عودة إلى الاكتشاف",
"assistants.plugins": "المهارات المدمجة",
"assistants.recentSubmits": "التحديثات الأخيرة",
"assistants.sorts.createdAt": "تم النشر مؤخرًا",
"assistants.sorts.identifier": "معرّف الوكيل",
"assistants.sorts.knowledgeCount": "عدد المكتبات",
"assistants.sorts.myown": "عرض وكلائي",
"assistants.sorts.pluginCount": "عدد المهارات",
"assistants.sorts.title": "اسم الوكيل",
"assistants.sorts.tokenUsage": "استخدام الرموز",
"assistants.status.archived.reasons.official": "قامت المنصة بإزالة هذا الوكيل لأسباب تتعلق بالأمان أو السياسات أو غيرها.",
"assistants.status.archived.reasons.owner": "قام المنشئ بأرشفة أو إزالة هذا الوكيل.",
"assistants.status.archived.subtitle": "تمت أرشفة هذا الوكيل. الأسباب المحتملة:",
"assistants.status.archived.title": "تمت أرشفة الوكيل",
"assistants.status.backToMarket": "العودة إلى مجتمع الوكلاء",
"assistants.status.deprecated.reasons.official": "قامت المنصة بإزالة هذا الوكيل لأسباب تتعلق بالأمان أو السياسات أو غيرها.",
"assistants.status.deprecated.reasons.owner": "قام المنشئ برفض أو إزالة هذا الوكيل.",
"assistants.status.deprecated.subtitle": "هذا الوكيل غير متاح حاليًا. الأسباب المحتملة:",
"assistants.status.deprecated.title": "الوكيل غير متاح",
"assistants.status.support": "لأي استفسارات، يرجى نسخ الرابط وإرساله إلى <email>support@lobehub.com</email> للحصول على المساعدة.",
"assistants.status.unpublished.subtitle": "هذا الوكيل قيد المراجعة. لتأكيد حالته، انسخ الرابط وأرسله إلى <email>support@lobehub.com</email>.",
"assistants.status.unpublished.title": "الوكيل قيد المراجعة",
"assistants.suggestions": "وكلاء مشابهون",
"assistants.systemRole": "ملف تعريف الوكيل",
"assistants.tokenUsage": "استخدام رموز الوكيل",
"assistants.try": "جرّب",
"assistants.withKnowledge": "يتضمن هذا الوكيل مكتبات",
"assistants.withPlugin": "يتضمن هذا الوكيل مهارات",
"back": "العودة إلى الاكتشاف",
"category.assistant.academic": "أكاديمي",
"category.assistant.all": "الكل",
"category.assistant.career": "مهنة",
"category.assistant.copywriting": "كتابة نصوص",
"category.assistant.career": "المسار المهني",
"category.assistant.copywriting": "كتابة المحتوى",
"category.assistant.design": "تصميم",
"category.assistant.education": "تعليم",
"category.assistant.emotions": "عواطف",
"category.assistant.emotions": "العواطف",
"category.assistant.entertainment": "ترفيه",
"category.assistant.games": "ألعاب",
"category.assistant.general": "عام",
"category.assistant.life": "حياة",
"category.assistant.life": "الحياة",
"category.assistant.marketing": "تسويق",
"category.assistant.office": "مكتب",
"category.assistant.programming": "برمجة",
"category.assistant.translation": "ترجمة",
"category.plugin.all": "الكل",
"category.plugin.gaming-entertainment": "ألعاب وترفيه",
"category.plugin.life-style": "أسلوب حياة",
"category.plugin.gaming-entertainment": "الألعاب والترفيه",
"category.plugin.life-style": "نمط الحياة",
"category.plugin.lifestyle": "نمط الحياة",
"category.plugin.media-generate": "توليد الوسائط",
"category.plugin.science-education": "علوم وتعليم",
"category.plugin.media-generate": "إنشاء الوسائط",
"category.plugin.science-education": "العلم والتعليم",
"category.plugin.social": "وسائل التواصل الاجتماعي",
"category.plugin.stocks-finance": "أسواق مالية",
"category.plugin.tools": "أدوات عملية",
"category.plugin.web-search": "بحث على الويب",
"cleanFilter": "مسح الفلتر",
"category.plugin.stocks-finance": "الأسهم والتمويل",
"category.plugin.tools": "أدوات مساعدة",
"category.plugin.web-search": "البحث على الويب",
"cleanFilter": "مسح الفلاتر",
"create": "إنشاء",
"createGuide.func1.desc1": "ادخل إلى صفحة إعداد المساعد الذي ترغب في تقديمه من خلال الإعدادات في الزاوية العليا اليمنى من نافذة المحادثة;",
"createGuide.func1.desc2": "انقر على زر الإرسال إلى مجتمع المساعد في الزاوية اليمنى العليا.",
"createGuide.func1.tag": "الطريقة الأولى",
"createGuide.func1.title": "تقديم عبر LobeChat",
"createGuide.func2.button": "اذهب إلى مستودع مساعدي Github",
"createGuide.func2.desc": "إذا كنت ترغب في إضافة مساعد إلى الفهرس، يرجى استخدام agent-template.json أو agent-template-full.json لإنشاء إدخال في دليل الإضافات، كتابة وصف قصير ووضع علامات مناسبة، ثم إنشاء طلب سحب.",
"createGuide.func2.tag": "الطريقة الثانية",
"createGuide.func2.title": "تقديم عبر Github",
"dislike": "لا يعجبني",
"createGuide.func1.desc1": "في المحادثة، افتح إعدادات الوكيل من القائمة في الزاوية العلوية اليمنى.",
"createGuide.func1.desc2": "ثم انقر على إرسال إلى مجتمع الوكلاء في الزاوية العلوية اليمنى.",
"createGuide.func1.tag": "الخيار 1",
"createGuide.func1.title": "الإرسال في LobeHub",
"createGuide.func2.button": "افتح مستودع وكيل GitHub",
"createGuide.func2.desc": "لإضافة وكيل إلى الفهرس، أنشئ إدخالًا في `plugins/` باستخدام `agent-template.json` أو `agent-template-full.json`، أضف وصفًا قصيرًا وعلامات، ثم افتح طلب سحب.",
"createGuide.func2.tag": "الخيار 2",
"createGuide.func2.title": "الإرسال على GitHub",
"dislike": "عدم الإعجاب",
"filter": "تصفية",
"filterBy.authorRange.everyone": "جميع المؤلفين",
"filterBy.authorRange.followed": "المؤلفون المتابعون",
"filterBy.authorRange.title": "نطاق المؤلفين",
"filterBy.contentLength": "أقل طول للسياق",
"filterBy.maxToken.title": عيين الحد الأقصى للطول (Token)",
"filterBy.authorRange.title": "نطاق المؤلف",
"filterBy.contentLength": "الحد الأدنى لطول السياق",
"filterBy.maxToken.title": حديد الحد الأقصى للطول (رموز)",
"filterBy.maxToken.unlimited": "غير محدود",
"filterBy.other.functionCall": "دعم استدعاء الوظائف",
"filterBy.other.functionCall": "يدعم استدعاء الوظائف",
"filterBy.other.title": "أخرى",
"filterBy.other.vision": "دعم التعرف البصري",
"filterBy.other.withKnowledge": "مزود بمكتبات معرفية",
"filterBy.other.withTool": "مع الإضافات",
"filterBy.pricing": "أسعار النموذج",
"filterBy.other.vision": "يدعم التعرف البصري",
"filterBy.other.withKnowledge": "يتضمن مكتبات",
"filterBy.other.withTool": "يتضمن مهارات",
"filterBy.pricing": "تسعير النموذج",
"filterBy.timePeriod.all": "كل الوقت",
"filterBy.timePeriod.day": "آخر 24 ساعة",
"filterBy.timePeriod.month": "آخر 30 يومًا",
"filterBy.timePeriod.title": "نطاق الوقت",
"filterBy.timePeriod.title": "النطاق الزمني",
"filterBy.timePeriod.week": "آخر 7 أيام",
"filterBy.timePeriod.year": "آخر سنة",
"footer.desc": "بكل سهولة، شارك مساعديك ومواردك على مجتمع LobeHub، وتعاون مع مستخدمي الذكاء الاصطناعي حول العالم في الاستخدام والتغذية الراجعة والتطوير.",
"footer.title": "انشر إبداعاتك الآن على مجتمع LobeHub",
"home.communityAgents": "مساعدو المجتمع",
"home.featuredAssistants": "مساعدون مميزون",
"filterBy.timePeriod.year": "العام الماضي",
"footer.desc": "تطوّر مع مستخدمي الذكاء الاصطناعي حول العالم. كن منشئًا وشارك وكلاءك ومهاراتك في مجتمع LobeHub.",
"footer.title": "شارك إبداعاتك في مجتمع LobeHub اليوم",
"home.communityAgents": "وكلاء المجتمع",
"home.featuredAssistants": "وكلاء مميزون",
"home.featuredModels": "نماذج مميزة",
"home.featuredPlugins": "الإضافات المميزة",
"home.featuredProviders": "مزودو نماذج مميزون",
"home.featuredTools": "إضافات مميزة",
"home.featuredPlugins": "مهارات مميزة",
"home.featuredProviders": "مزودون مميزون",
"home.featuredTools": "مهارات مميزة",
"home.more": "اكتشف المزيد",
"isClaimed": "تم المطالبة",
"isClaimed": "تم المطالبة به",
"isFeatured": "مميز",
"isOfficial": "معتمد رسميًا",
"like": "أحب",
"isOfficial": "تم التحقق منه رسميًا",
"like": "إعجاب",
"mcp.categories.all.description": "جميع خوادم MCP",
"mcp.categories.all.name": "الكل",
"mcp.categories.business.description": "الخدمات التجارية والمؤسساتية",
"mcp.categories.business.name": "الخدمات التجارية",
"mcp.categories.developer.description": "أدوات وخدمات متعلقة بالتطوير",
"mcp.categories.developer.name": "أدوات التطوير",
"mcp.categories.gaming-entertainment.description": "الألعاب، الترفيه والأنشطة الترفيهية",
"mcp.categories.business.description": "خدمات الأعمال والمؤسسات",
"mcp.categories.business.name": "خدمات الأعمال",
"mcp.categories.developer.description": "أدوات وخدمات للمطورين",
"mcp.categories.developer.name": "أدوات المطورين",
"mcp.categories.gaming-entertainment.description": "الألعاب، الترفيه، والأنشطة الترفيهية",
"mcp.categories.gaming-entertainment.name": "الألعاب والترفيه",
"mcp.categories.health-wellness.description": "الصحة، اللياقة والعناية بالجسم والعقل",
"mcp.categories.health-wellness.description": "الصحة، اللياقة، والعافية",
"mcp.categories.health-wellness.name": "الصحة والعافية",
"mcp.categories.lifestyle.description": "أسلوب الحياة الشخصية، العادات والأنشطة اليومية",
"mcp.categories.lifestyle.description": "نمط الحياة الشخصية، العادات، والأنشطة اليومية",
"mcp.categories.lifestyle.name": "نمط الحياة",
"mcp.categories.media-generate.description": "إنشاء، تحرير ومعالجة الوسائط",
"mcp.categories.media-generate.description": "إنشاء الوسائط، تحريرها، ومعالجتها",
"mcp.categories.media-generate.name": "إنشاء الوسائط",
"mcp.categories.news.description": "تجميع الأخبار، التقارير وخدمات المعلومات",
"mcp.categories.news.description": "تجميع الأخبار، التقارير، وخدمات المعلومات",
"mcp.categories.news.name": "الأخبار والمعلومات",
"mcp.categories.productivity.description": "إدارة المهام، الملاحظات وأدوات الكفاءة",
"mcp.categories.productivity.description": "إدارة المهام، الملاحظات، وأدوات الإنتاجية",
"mcp.categories.productivity.name": "أدوات الإنتاجية",
"mcp.categories.science-education.description": "البحث العلمي، التعلم وأدوات التعليم",
"mcp.categories.science-education.name": "العلوم والتعليم",
"mcp.categories.science-education.description": "البحث العلمي، التعلم، وأدوات التعليم",
"mcp.categories.science-education.name": "العلم والتعليم",
"mcp.categories.social.description": "الشبكات الاجتماعية والتواصل",
"mcp.categories.social.name": "وسائل التواصل الاجتماعي",
"mcp.categories.stocks-finance.description": "أسواق المال، التداول والاستثمار",
"mcp.categories.stocks-finance.name": "الأسهم والمالية",
"mcp.categories.tools.description": "أدوات وخدمات عامة وعملية",
"mcp.categories.tools.name": "أدوات عملية",
"mcp.categories.travel-transport.description": "تخطيط السفر والتنقل",
"mcp.categories.travel-transport.name": "السفر والنقل",
"mcp.categories.stocks-finance.description": "الأسواق المالية، التداول، والاستثمار",
"mcp.categories.stocks-finance.name": "الأسهم والتمويل",
"mcp.categories.tools.description": "أدوات وخدمات عملية متعددة الأغراض",
"mcp.categories.tools.name": "أدوات مساعدة",
"mcp.categories.travel-transport.description": "تخطيط السفر والمواصلات",
"mcp.categories.travel-transport.name": "السفر والمواصلات",
"mcp.categories.weather.description": "توقعات الطقس وخدمات الأرصاد الجوية",
"mcp.categories.weather.name": "الطقس والأرصاد",
"mcp.categories.weather.name": "الطقس",
"mcp.categories.web-search.description": "البحث على الويب واسترجاع المعلومات",
"mcp.categories.web-search.name": "استرجاع المعلومات",
"mcp.details.connectionType.hybrid.desc": "هذه الخدمة يمكن تشغيلها محلياً أو على السحابة حسب الإعداد أو سيناريو الاستخدام، وتتمتع بقدرة تشغيل مزدوجة.",
"mcp.details.connectionType.hybrid.desc": "يمكن تشغيل هذه الخدمة محليًا أو عبر السحابة حسب الإعداد أو سيناريو الاستخدام، مما يوفر إمكانية التشغيل المزدوج.",
"mcp.details.connectionType.hybrid.title": "خدمة هجينة",
"mcp.details.connectionType.local.desc": "هذا الخادم يعمل فقط على جهاز العميل المحلي، ويتطلب التثبيت والاعتماد على الموارد المحلية.",
"mcp.details.connectionType.local.desc": "يمكن تشغيل هذا الخادم فقط على جهاز المستخدم المحلي، ويتطلب التثبيت ويعتمد على الموارد المحلية.",
"mcp.details.connectionType.local.title": "خدمة محلية",
"mcp.details.connectionType.remote.desc": "هذا الخادم مستضاف ويعمل عن بُعد، لأنه يعتمد بشكل رئيسي على خدمات بعيدة ولا يعتمد على البيئة المحلية.",
"mcp.details.connectionType.remote.desc": "يتم استضافة هذا الخادم عن بُعد لأنه يعتمد بشكل أساسي على خدمات خارجية ولا يعتمد على البيئة المحلية.",
"mcp.details.connectionType.remote.title": "خدمة سحابية",
"mcp.details.deployment.args": "المعطيات",
"mcp.details.deployment.args": "المعلمات",
"mcp.details.deployment.checkCommand": "أمر التحقق",
"mcp.details.deployment.command": "الأمر",
"mcp.details.deployment.commandLine": "اعتمادات النظام",
"mcp.details.deployment.connection": "طريقة الاتصال",
"mcp.details.deployment.connectionType": "نوع الاتصال",
"mcp.details.deployment.description": "طريقة تثبيت ونشر الإضافة",
"mcp.details.deployment.description": "طريقة تثبيت ونشر المهارة",
"mcp.details.deployment.descriptionPlaceholder": "وصف اختياري",
"mcp.details.deployment.empty": "لا توجد خيارات نشر حالياً",
"mcp.details.deployment.empty": "لا توجد خيارات نشر متاحة",
"mcp.details.deployment.env": "متغيرات البيئة",
"mcp.details.deployment.guide": "تعليمات التثبيت",
"mcp.details.deployment.guide": "دليل التثبيت",
"mcp.details.deployment.installation": "التثبيت عبر {{method}}",
"mcp.details.deployment.installationMethod": "طريقة التثبيت",
"mcp.details.deployment.other": "إعدادات أخرى",
"mcp.details.deployment.packageName": "اسم الحزمة",
"mcp.details.deployment.platform.steps.claude": "- افتح تطبيق **Claude Desktop**\n- اذهب إلى **الإعدادات** ثم اختر **المطور**\n- اضغط على **تحرير الإعدادات**\n- افتح ملف **claude_desktop_config.json**\n- انسخ والصق إعدادات الخادم في الملف الحالي ثم احفظ",
"mcp.details.deployment.platform.steps.cline": "- افتح VS Code مع إضافة Cline المثبتة\n- اضغط على أيقونة Cline في الشريط الجانبي\n- اختر **MCP Servers** من القائمة المنسدلة\n- في تبويب **الخوادم البعيدة**، أدخل اسم الخادم ورابط MCP الخاص بك\n- اضغط **Add Server** للاتصال",
"mcp.details.deployment.platform.steps.cursor": "- انتقل إلى **الإعدادات** ثم إعدادات Cursor\n- اختر **MCP** من الجانب الأيسر\n- اضغط على **إضافة خادم MCP عالمي جديد** في الأعلى يمين\n- انسخ والصق إعدادات الخادم في الملف الحالي ثم احفظ",
"mcp.details.deployment.platform.steps.lobeChat": "- افتح تطبيق **LobeChat لسطح المكتب**\n- اذهب إلى **الإعدادات** - **المساعد الافتراضي**\n- اختر **إعدادات الإضافة** - **إضافة مخصصة**\n- اضغط على **استيراد سريع لإعدادات JSON**\n- انسخ والصق إعدادات الخادم في مربع النص ثم ثبت",
"mcp.details.deployment.platform.steps.openai": "- افتح تطبيق **OpenAI** أو بيئة التطوير الخاصة بك\n- قم بإعداد أدوات MCP في **Responses API**\n- أضف كتلة MCP إلى مصفوفة **tools** في طلب API\n- عيّن **server_url** إلى نقطة نهاية خادم MCP الخاص بك\n- أدرج رؤوس المصادقة المطلوبة (مفتاح API، رموز، إلخ)\n- استخدم معلمة `allowed_tools` لتقييد الأدوات المكشوفة\n- عيّن `require_approval` للتحكم في موافقة تنفيذ الأدوات",
"mcp.details.deployment.platform.steps.vscode": "- افتح VS Code\n- افتح لوحة الأوامر (`Ctrl+Shift+P` / `Cmd+Shift+P`)\n- اكتب **MCP: Add Server** واختره\n- اختر الإضافة إلى مساحة العمل أو إعدادات المستخدم\n- انسخ والصق إعدادات الخادم",
"mcp.details.deployment.platform.steps.claude": "- افتح تطبيق **Claude Desktop**\n- انتقل إلى **الإعدادات** ثم اختر **المطور**\n- انقر على **تحرير الإعدادات**\n- افتح ملف **claude_desktop_config.json**\n- انسخ والصق إعدادات الخادم في الملف الحالي ثم احفظ",
"mcp.details.deployment.platform.steps.cline": "- افتح VS Code مع تثبيت إضافة Cline\n- انقر على أيقونة Cline في الشريط الجانبي\n- اختر **MCP Servers** من القائمة المنسدلة\n- في تبويب **الخوادم البعيدة**، أدخل اسم الخادم ورابط MCP الخاص بك\n- انقر على **إضافة خادم** للاتصال",
"mcp.details.deployment.platform.steps.cursor": "- انتقل إلى **الإعدادات** ثم اختر إعدادات Cursor\n- اختر **MCP** من القائمة الجانبية\n- انقر على **إضافة خادم MCP عالمي جديد** في الأعلى\n- انسخ والصق إعدادات الخادم في الملف الحالي ثم احفظ",
"mcp.details.deployment.platform.steps.lobeChat": "- افتح تطبيق **LobeHub Desktop**\n- انتقل إلى **الإعدادات** - **الوكيل الافتراضي**\n- ثم اختر **إعدادات المهارة** - **مهارات مخصصة**\n- انقر على **استيراد سريع لإعدادات JSON**\n- انسخ والصق إعدادات الخادم في مربع النص ثم قم بالتثبيت",
"mcp.details.deployment.platform.steps.openai": "- افتح تطبيق **OpenAI** أو بيئة التطوير الخاصة بك\n- قم بإعداد أدوات MCP في **Responses API**\n- أضف كتل MCP إلى مصفوفة **tools** في طلبات API\n- عيّن **server_url** إلى نقطة نهاية خادم MCP الخاص بك\n- أدرج رؤوس المصادقة المطلوبة (مفتاح API، رمز، إلخ)\n- استخدم المعامل `allowed_tools` لتقييد الأدوات المتاحة\n- عيّن `require_approval` للتحكم في الموافقة على تنفيذ الأدوات",
"mcp.details.deployment.platform.steps.vscode": "- افتح VS Code\n- افتح لوحة الأوامر (`Ctrl+Shift+P` / `Cmd+Shift+P`)\n- اكتب **MCP: Add Server** واختره\n- اختر الإضافة إلى إعدادات مساحة العمل أو المستخدم\n- انسخ والصق إعدادات الخادم",
"mcp.details.deployment.platform.title": "التثبيت على {{platform}}",
"mcp.details.deployment.recommended": "موصى به",
"mcp.details.deployment.systemDependencies": "اعتمادات النظام",
@@ -217,267 +217,267 @@
"mcp.details.deployment.table.required": "مطلوب",
"mcp.details.deployment.table.type": "النوع",
"mcp.details.deployment.title": "طريقة التثبيت",
"mcp.details.githubBadge.desc": "يقوم LobeHub بمسح مستودعات الأكواد والوثائق بانتظام من أجل:\n\n- التأكد من أن خوادم MCP تعمل بشكل صحيح.\n- استخراج ميزات الخادم مثل الأدوات، الموارد، التعليمات والمعطيات المطلوبة.\n- تساعد شارة التقييم المستخدمين على تقييم أمان الخادم، ميزاته ودليل التثبيت بسرعة.\n\nيرجى نسخ الكود التالي إلى ملف `README.md` الخاص بك:",
"mcp.details.nav.needHelp": "هل تحتاج مساعدة؟",
"mcp.details.githubBadge.desc": "يقوم LobeHub بمسح مستودعات الشيفرة والمستندات بانتظام من أجل:\n- التحقق من حالة تشغيل خادم MCP.\n- استخراج ميزات الخادم مثل الأدوات، الموارد، التعليمات، والمعلمات المطلوبة.\n- تساعد شارة MCP المستخدمين على تقييم أمان الخادم وميزاته وتعليمات التثبيت بسرعة. يرجى نسخ الكود التالي إلى ملف `README.md` الخاص بك:",
"mcp.details.nav.needHelp": "هل تحتاج إلى مساعدة؟",
"mcp.details.nav.reportIssue": "الإبلاغ عن مشكلة",
"mcp.details.nav.viewSourceCode": "عرض الشيفرة المصدرية",
"mcp.details.overview.title": "نظرة عامة",
"mcp.details.related.listTitle": "خوادم MCP ذات الصلة",
"mcp.details.related.listTitle": "خوادم MCP ذات صلة",
"mcp.details.related.more": "عرض المزيد",
"mcp.details.related.title": "اقتراحات ذات صلة",
"mcp.details.related.title": "توصيات ذات صلة",
"mcp.details.schema.mode.docs": "الوثائق",
"mcp.details.schema.prompts.arguments": "إعدادات المعطيات",
"mcp.details.schema.prompts.desc": "قوالب تفاعلية يتم تفعيلها باختيار المستخدم",
"mcp.details.schema.prompts.empty": "لا توجد تعليمات حالياً",
"mcp.details.schema.prompts.instructions": "تعليمات",
"mcp.details.schema.prompts.arguments": "إعداد المعلمات",
"mcp.details.schema.prompts.desc": "قوالب تفاعلية يتم تفعيلها عند اختيار المستخدم",
"mcp.details.schema.prompts.empty": "لا توجد تعليمات متاحة",
"mcp.details.schema.prompts.instructions": "وصف التعليمات",
"mcp.details.schema.prompts.table.description": "الوصف",
"mcp.details.schema.prompts.table.name": "الاسم",
"mcp.details.schema.prompts.table.required": "مطلوب",
"mcp.details.schema.prompts.title": "قائمة التعليمات",
"mcp.details.schema.resources.desc": "بيانات سياقية مرفقة ومدارة من قبل العميل",
"mcp.details.schema.resources.empty": "لا توجد موارد",
"mcp.details.schema.resources.desc": "بيانات السياق المرفقة والمدارة من قبل العميل",
"mcp.details.schema.resources.empty": "لا توجد موارد متاحة",
"mcp.details.schema.resources.table.description": "الوصف",
"mcp.details.schema.resources.table.mineType": "نوع MIME",
"mcp.details.schema.resources.table.name": "الاسم",
"mcp.details.schema.resources.table.uri": "رابط URI",
"mcp.details.schema.resources.table.uri": "الرابط URI",
"mcp.details.schema.resources.title": "قائمة الموارد",
"mcp.details.schema.title": "وظائف الإضافة",
"mcp.details.schema.tools.desc": "واجهات وظائف مكشوفة لنموذج اللغة الكبير (LLM) لتنفيذ العمليات",
"mcp.details.schema.tools.empty": "لا توجد أدوات",
"mcp.details.schema.title": "ميزات المهارة",
"mcp.details.schema.tools.desc": "واجهات وظيفية مكشوفة لنماذج اللغة الكبيرة (LLM) لتنفيذ العمليات",
"mcp.details.schema.tools.empty": "لا توجد أدوات متاحة",
"mcp.details.schema.tools.inputSchema": "وصف الإدخال",
"mcp.details.schema.tools.instructions": "تعليمات",
"mcp.details.schema.tools.instructions": "وصف التعليمات",
"mcp.details.schema.tools.table.description": "الوصف",
"mcp.details.schema.tools.table.name": "الاسم",
"mcp.details.schema.tools.table.required": "مطلوب",
"mcp.details.schema.tools.table.type": "النوع",
"mcp.details.schema.tools.title": "قائمة الأدوات",
"mcp.details.score.claimed.desc": "تمت المطالبة بهذا الخادم من قبل المالك، مما يضمن ملكيته وإدارته.",
"mcp.details.score.claimed.title": "مطالب به من قبل المالك",
"mcp.details.score.deployMoreThanManual.desc": "يوفر هذا الخادم طرق تثبيت أكثر سهولة من الطريقة اليدوية، مما يسمح للمستخدمين بالنشر والاستخدام بسهولة.",
"mcp.details.score.claimed.desc": "تم تأكيد ملكية هذا الخادم MCP من قبل مالكه، مما يضمن إدارته.",
"mcp.details.score.claimed.title": "تمت المطالبة به من قبل المالك",
"mcp.details.score.deployMoreThanManual.desc": "يوفر هذا الخادم MCP طرق تثبيت أسهل من التثبيت اليدوي، مما يسهل على المستخدمين نشره واستخدامه.",
"mcp.details.score.deployMoreThanManual.title": "يوفر طرق تثبيت سهلة",
"mcp.details.score.deployment.desc": "يوفر هذا الخادم على الأقل طريقة تثبيت واحدة تسمح للمستخدمين بالنشر والاستخدام.",
"mcp.details.score.deployment.descWithCount": "يوفر هذا الخادم {{number}} طريقة تثبيت تسمح للمستخدمين بالنشر والاستخدام.",
"mcp.details.score.deployment.desc": "يوفر هذا الخادم MCP طريقة تثبيت واحدة على الأقل، مما يتيح للمستخدمين نشره واستخدامه.",
"mcp.details.score.deployment.descWithCount": "يوفر هذا الخادم MCP {{number}} طريقة تثبيت، مما يتيح للمستخدمين نشره واستخدامه.",
"mcp.details.score.deployment.title": "يوفر طريقة تثبيت واحدة على الأقل",
"mcp.details.score.license.desc": "يحتوي هذا المستودع على ملف LICENSE.",
"mcp.details.score.license.descWithlicense": "رخصة هذا المستودع هي {{license}}.",
"mcp.details.score.license.title": "يحتوي على رخصة",
"mcp.details.score.license.desc": "يحتوي هذا المستودع على ملف ترخيص LICENSE.",
"mcp.details.score.license.descWithlicense": "تم ترخيص هذا المستودع بموجب {{license}}.",
"mcp.details.score.license.title": "يحتوي على ترخيص",
"mcp.details.score.listTitle": "تفاصيل التقييم",
"mcp.details.score.notClaimed.desc": "إذا كنت مالك هذا الخادم، يمكنك المطالبة به بالطرق التالية.",
"mcp.details.score.notClaimed.title": "غير مطالب به من قبل المالك",
"mcp.details.score.prompts.desc": "يوفر هذا الخادم تعليمات تسمح للمستخدمين بالتفاعل مع الخدمة.",
"mcp.details.score.prompts.descWithCount": "يوفر هذا الخادم {{number}} تعليمات تسمح للمستخدمين بالتفاعل مع الخدمة.",
"mcp.details.score.prompts.title": حتوي على تعليمات",
"mcp.details.score.notClaimed.desc": "إذا كنت مالك هذا الخادم MCP، يمكنك المطالبة به عبر الطرق التالية.",
"mcp.details.score.notClaimed.title": "لم تتم المطالبة به من قبل المالك",
"mcp.details.score.prompts.desc": "يوفر هذا الخادم MCP تعليمات تتيح للمستخدمين التفاعل مع الخدمة.",
"mcp.details.score.prompts.descWithCount": "يوفر هذا الخادم MCP {{number}} تعليمات تتيح للمستخدمين التفاعل مع الخدمة.",
"mcp.details.score.prompts.title": تضمن تعليمات",
"mcp.details.score.readme.desc": "يحتوي هذا المستودع على ملف README.md.",
"mcp.details.score.readme.title": "يحتوي على README",
"mcp.details.score.resources.desc": "يوفر هذا الخادم موارد تسمح للمستخدمين بإرفاق وإدارة بيانات السياق.",
"mcp.details.score.resources.descWithCount": "يوفر هذا الخادم {{number}} موارد تسمح للمستخدمين بإرفاق وإدارة بيانات السياق.",
"mcp.details.score.resources.title": حتوي على موارد",
"mcp.details.score.resources.desc": "يوفر هذا الخادم MCP موارد تتيح للمستخدمين إرفاق بيانات السياق وإدارتها.",
"mcp.details.score.resources.descWithCount": "يوفر هذا الخادم MCP {{number}} من الموارد تتيح للمستخدمين إرفاق بيانات السياق وإدارتها.",
"mcp.details.score.resources.title": تضمن موارد",
"mcp.details.score.title": "التقييم",
"mcp.details.score.tools.desc": "يجب أن يوفر الخادم أداة واحدة على الأقل تسمح للمستخدمين بتنفيذ عمليات محددة.",
"mcp.details.score.tools.descWithCount": "يوفر هذا الخادم {{number}} أداة تسمح للمستخدمين بتنفيذ عمليات محددة.",
"mcp.details.score.tools.title": حتوي على أداة واحدة على الأقل",
"mcp.details.score.validated.desc": "تم التحقق من هذا الخادم لضمان جودته وموثوقيته.",
"mcp.details.score.tools.desc": "يجب أن يوفر هذا الخادم أداة واحدة على الأقل تتيح للمستخدمين تنفيذ عمليات محددة.",
"mcp.details.score.tools.descWithCount": "يوفر هذا الخادم MCP {{number}} من الأدوات التي تتيح للمستخدمين تنفيذ عمليات محددة.",
"mcp.details.score.tools.title": تضمن أداة واحدة على الأقل",
"mcp.details.score.validated.desc": "تم التحقق من هذا الخادم MCP لضمان جودته وموثوقيته.",
"mcp.details.score.validated.title": "تم التحقق منه",
"mcp.details.scoreLevel.a.desc": "تم التحقق من هذا الخادم بدقة، ويوفر وظائف شاملة وتجربة مستخدم عالية الجودة.",
"mcp.details.scoreLevel.a.fullTitle": "إضافة ممتازة",
"mcp.details.scoreLevel.a.title": "ممتاز",
"mcp.details.scoreLevel.b.desc": وفر هذا الخادم وظائف وتجربة مستخدم جيدة، لكنه قد يحتاج إلى تحسين في بعض الجوانب.",
"mcp.details.scoreLevel.a.desc": "تم التحقق من هذا الخادم MCP بدقة، ويقدم ميزات شاملة وتجربة مستخدم عالية الجودة.",
"mcp.details.scoreLevel.a.fullTitle": "مهارة ممتازة",
"mcp.details.scoreLevel.a.title": "مميز",
"mcp.details.scoreLevel.b.desc": قدم هذا الخادم MCP ميزات جيدة وتجربة مستخدم مقبولة، لكنه قد يحتاج إلى تحسينات في بعض الجوانب.",
"mcp.details.scoreLevel.b.fullTitle": "وظائف جيدة",
"mcp.details.scoreLevel.b.title": "جيد",
"mcp.details.scoreLevel.f.desc": "وظائف هذا الخادم غير مكتملة أو جودته منخفضة، ينصح المستخدمون بالحذر عند الاستخدام.",
"mcp.details.scoreLevel.f.desc": "هذا الخادم MCP غير مكتمل أو منخفض الجودة؛ يُنصح المستخدمون باستخدامه بحذر.",
"mcp.details.scoreLevel.f.fullTitle": "جودة ضعيفة",
"mcp.details.scoreLevel.f.title": "ضعيف",
"mcp.details.settings.capabilities.prompts": "التلميحات",
"mcp.details.settings.capabilities.prompts": "المحفزات",
"mcp.details.settings.capabilities.resources": "الموارد",
"mcp.details.settings.capabilities.title": "قدرات الإضافة",
"mcp.details.settings.capabilities.title": "قدرات المهارة",
"mcp.details.settings.capabilities.tools": "الأدوات",
"mcp.details.settings.configuration.title": "تكوين الإضافة",
"mcp.details.settings.connection.args": "معاملات التشغيل",
"mcp.details.settings.configuration.title": "إعدادات المهارة",
"mcp.details.settings.connection.args": "وسائط التشغيل",
"mcp.details.settings.connection.command": "أمر التشغيل",
"mcp.details.settings.connection.title": "معلومات الاتصال",
"mcp.details.settings.connection.type": "نوع الاتصال",
"mcp.details.settings.connection.url": "عنوان الخدمة",
"mcp.details.settings.connection.url": "رابط الخدمة",
"mcp.details.settings.saveSettings": "حفظ الإعدادات",
"mcp.details.settings.title": "إعدادات الإضافة",
"mcp.details.settings.title": "إعدادات المهارة",
"mcp.details.sidebar.install": "تثبيت خادم MCP",
"mcp.details.sidebar.meta.homepage": "الصفحة الرئيسية",
"mcp.details.sidebar.meta.homepage": "الصفحة الرسمية",
"mcp.details.sidebar.meta.installCount": "عدد التثبيتات",
"mcp.details.sidebar.meta.language": "لغة المصدر",
"mcp.details.sidebar.meta.license": "الرخصة",
"mcp.details.sidebar.meta.published": "تاريخ النشر",
"mcp.details.sidebar.meta.repo": "مستودع الشيفرة",
"mcp.details.sidebar.meta.stars": "عدد النجوم",
"mcp.details.sidebar.meta.title": "معلومات مفصلة",
"mcp.details.sidebar.meta.repo": "مستودع المصدر",
"mcp.details.sidebar.meta.stars": "التقييمات",
"mcp.details.sidebar.meta.title": "التفاصيل",
"mcp.details.sidebar.meta.updated": "آخر تحديث",
"mcp.details.sidebar.moreServerConfig": "عرض التفاصيل",
"mcp.details.sidebar.recommendServers": "خوادم MCP ذات صلة",
"mcp.details.sidebar.serverConfig": "إعدادات التثبيت",
"mcp.details.sidebar.toc": "المحتوى",
"mcp.details.summary.title": "ما الذي يمكنك فعله باستخدام خادم MCP هذا؟",
"mcp.details.totalScore.description": "الدرجة الإجمالية المحسوبة بناءً على مؤشرات متعددة",
"mcp.details.totalScore.legend.aGrade": "الدرجة أ ({{minPercent}}-100%)",
"mcp.details.totalScore.legend.bGrade": "الدرجة ب ({{minPercent}}-{{maxPercent}}%)",
"mcp.details.totalScore.legend.fGrade": "الدرجة ف (0-{{maxPercent}}%)",
"mcp.details.totalScore.pointsFormat": "{{score}}/{{total}} نقاط",
"mcp.details.totalScore.popover.completedOptional": "✅ تم إكمال الخيارات الاختيارية ({{count}} عناصر)",
"mcp.details.totalScore.popover.completedRequired": "✅ تم إكمال العناصر المطلوبة ({{count}} عناصر)",
"mcp.details.totalScore.popover.incompleteOptional": "⏸️ لم تكتمل الخيارات الاختيارية ({{count}} عناصر)",
"mcp.details.totalScore.popover.incompleteRequired": "❌ لم تكتمل العناصر المطلوبة ({{count}} عناصر)",
"mcp.details.sidebar.toc": "جدول المحتويات",
"mcp.details.summary.title": "ماذا يمكنك أن تفعل بهذا الخادم MCP؟",
"mcp.details.totalScore.description": "تم حساب الدرجة الإجمالية بناءً على مؤشرات متعددة",
"mcp.details.totalScore.legend.aGrade": "الدرجة A ({{minPercent}}-100%)",
"mcp.details.totalScore.legend.bGrade": "الدرجة B ({{minPercent}}-{{maxPercent}}%)",
"mcp.details.totalScore.legend.fGrade": "الدرجة F (0-{{maxPercent}}%)",
"mcp.details.totalScore.pointsFormat": "{{score}}/{{total}} نقطة",
"mcp.details.totalScore.popover.completedOptional": "✅ العناصر الاختيارية المكتملة ({{count}})",
"mcp.details.totalScore.popover.completedRequired": "✅ العناصر المطلوبة المكتملة ({{count}})",
"mcp.details.totalScore.popover.incompleteOptional": "⏸️ العناصر الاختيارية غير المكتملة ({{count}})",
"mcp.details.totalScore.popover.incompleteRequired": "❌ العناصر المطلوبة غير المكتملة ({{count}})",
"mcp.details.totalScore.popover.title": "تفاصيل التقييم",
"mcp.details.totalScore.ratingFormat": "التقييم: {{level}}",
"mcp.details.totalScore.scoreInfo.items": "عناصر",
"mcp.details.totalScore.scoreInfo.points": "نقاط",
"mcp.details.totalScore.scoreInfo.requiredItems": "عناصر مطلوبة",
"mcp.details.totalScore.scoreInfo.items": "العناصر",
"mcp.details.totalScore.scoreInfo.points": "النقاط",
"mcp.details.totalScore.scoreInfo.requiredItems": "العناصر المطلوبة",
"mcp.details.totalScore.title": "الدرجة الإجمالية",
"mcp.details.versions.table.isLatest": "أحدث إصدار",
"mcp.details.versions.table.isValidated": "تم التحقق",
"mcp.details.versions.table.isValidated": "تم التحقق منه",
"mcp.details.versions.table.publishAt": "تاريخ النشر",
"mcp.details.versions.table.version": "الإصدار",
"mcp.details.versions.title": "سجل الإصدارات",
"mcp.hero.desc": نصة MCP Servers مفتوحة المصدر وقابلة للنشر، تساعد أنظمة الذكاء الاصطناعي على الوصول بسهولة إلى أنظمة الملفات، قواعد البيانات، واجهات برمجة التطبيقات وغيرها من الموارد الحيوية، لتوسيع قدرات الذكاء الاصطناعي الخاصة بك بشكل شامل.",
"mcp.hero.subTitle": "مفتوح المصدر وجاهز للاستخدام",
"mcp.hero.desc": جتمع خوادم MCP مفتوح المصدر وقابل للنشر—يساعد أنظمة الذكاء الاصطناعي على الوصول إلى أنظمة الملفات وقواعد البيانات وواجهات البرمجة وغيرها من الموارد الأساسية.",
"mcp.hero.subTitle": "مفتوح المصدر وجاهز للتشغيل",
"mcp.hero.title": "مجتمع MCP مفتوح المصدر للذكاء الاصطناعي",
"mcp.sorts.createdAt": "أضيف مؤخراً",
"mcp.sorts.createdAt": ُضيف حديثًا",
"mcp.sorts.installCount": "عدد التثبيتات",
"mcp.sorts.isFeatured": "الإضافات المميزة",
"mcp.sorts.isValidated": "الإضافات التي تم التحقق منها",
"mcp.sorts.promptsCount": "عدد التعليمات",
"mcp.sorts.isFeatured": "المهارات المميزة",
"mcp.sorts.isValidated": "المهارات المُتحقق منها",
"mcp.sorts.promptsCount": "عدد المحفزات",
"mcp.sorts.ratingCount": "عدد التقييمات",
"mcp.sorts.resourcesCount": "عدد الموارد",
"mcp.sorts.toolsCount": "عدد الأدوات",
"mcp.sorts.updatedAt": "تم التحديث مؤخراً",
"mcp.sorts.updatedAt": "تم التحديث مؤخرًا",
"mcp.title": "مجتمع MCP",
"mcp.unvalidated.desc": "هذا الخادم MCP لم يتم التحقق منه بعد",
"mcp.unvalidated.title": "غير مُحقق",
"mcp.unvalidated.desc": "لم يتم التحقق من هذا الخادم MCP بعد",
"mcp.unvalidated.title": "غير مُتحقق",
"mcp.validated.desc": "تم التحقق من هذا الخادم MCP لضمان جودته وموثوقيته.",
"mcp.validated.descWithDate": "تم التحقق من هذا الخادم MCP بتاريخ {{date}} لضمان جودته وموثوقيته.",
"mcp.validated.title": "تم التحقق",
"mcpEmpty.description": "حاول تعديل معايير التصفية أو البحث باستخدام كلمات مفتاحية",
"mcp.validated.descWithDate": "تم التحقق من هذا الخادم MCP في {{date}} لضمان جودته وموثوقيته.",
"mcp.validated.title": "تم التحقق منه",
"mcpEmpty.description": "حاول تعديل الفلاتر أو البحث بكلمات مفتاحية مختلفة.",
"mcpEmpty.search": "لم يتم العثور على خوادم MCP مطابقة",
"mcpEmpty.title": "لا توجد خوادم MCP حالياً",
"mcpEmpty.title": "لا توجد خوادم MCP",
"models.abilities": "قدرات النموذج",
"models.chat": "بدء المحادثة",
"models.contentLength": "أقصى طول للسياق",
"models.chat": "بدء محادثة",
"models.contentLength": "الحد الأقصى لطول السياق",
"models.details.overview.title": "نظرة عامة",
"models.details.related.listTitle": "النماذج ذات الصلة",
"models.details.related.listTitle": "نماذج ذات صلة",
"models.details.related.more": "عرض المزيد",
"models.details.related.title": "اقتراحات ذات صلة",
"models.empty.description": "حاول تعديل معايير التصفية لرؤية المزيد من النماذج",
"models.details.related.title": "توصيات ذات صلة",
"models.empty.description": "حاول تعديل الفلاتر لرؤية المزيد من النماذج",
"models.empty.search": "لم يتم العثور على نماذج مطابقة",
"models.empty.title": "لا توجد نماذج حالياً",
"models.empty.title": "لا توجد نماذج متاحة",
"models.free": "مجاني",
"models.guide": "دليل الإعداد",
"models.list": "قائمة النماذج",
"models.more": "المزيد",
"models.parameterList.defaultValue": "القيمة الافتراضية",
"models.parameterList.docs": "عرض الوثائق",
"models.parameterList.frequency_penalty.desc": قوم هذه الإعدادات بتعديل تكرار استخدام النموذج لكلمات معينة ظهرت بالفعل في المدخلات. القيم الأعلى تقلل من احتمال تكرار هذه الكلمات، بينما القيم السلبية تعزز استخدامها. عقوبة الكلمات لا تزداد مع زيادة عدد مرات الظهور. القيم السلبية ستشجع على تكرار الكلمات.",
"models.parameterList.docs": "عرض التوثيق",
"models.parameterList.frequency_penalty.desc": تحكم هذه الإعدادات في تكرار استخدام المفردات التي ظهرت مسبقًا في الإدخال. القيم الأعلى تقلل من التكرار، بينما القيم السالبة تشجع على إعادة الاستخدام.",
"models.parameterList.frequency_penalty.title": "عقوبة التكرار",
"models.parameterList.max_tokens.desc": "تحدد هذه الإعدادات الحد الأقصى لطول النص الذي يمكن أن ينتجه النموذج في رد واحد. يسمح تعيين قيمة أعلى للنموذج بإنتاج ردود أطول، بينما تحدد القيمة المنخفضة طول الردود، مما يجعلها أكثر اختصارًا. يمكن أن يساعد ضبط هذه القيمة بشكل معقول وفقًا لمختلف سيناريوهات الاستخدام في تحقيق الطول والتفاصيل المتوقعة للرد.",
"models.parameterList.max_tokens.desc": "يحدد هذا الإعداد الحد الأقصى لطول الرد الذي يمكن أن يولده النموذج. القيم الأعلى تسمح بردود أطول، بينما القيم الأقل تجعل الردود أكثر إيجازًا.",
"models.parameterList.max_tokens.title": "حد الرد الواحد",
"models.parameterList.presence_penalty.desc": "تهدف هذه الإعدادات إلى التحكم في تكرار استخدام الكلمات بناءً على تكرار ظهورها في المدخلات. تحاول تقليل استخدام الكلمات التي ظهرت كثيرًا في المدخلات، حيث يتناسب تكرار استخدامها مع تكرار ظهورها. عقوبة الكلمات تزداد مع عدد مرات الظهور. القيم السلبية ستشجع على تكرار الكلمات.",
"models.parameterList.presence_penalty.title": "جدة الموضوع",
"models.parameterList.range": "نطاق",
"models.parameterList.reasoning_effort.desc": "تُستخدم هذه الإعدادات للتحكم في شدة التفكير التي يقوم بها النموذج قبل توليد الإجابات. الشدة المنخفضة تعطي الأولوية لسرعة الاستجابة وتوفر الرموز، بينما الشدة العالية توفر تفكيرًا أكثر اكتمالًا ولكنها تستهلك المزيد من الرموز وتقلل من سرعة الاستجابة. القيمة الافتراضية هي متوسطة، مما يوازن بين دقة التفكير وسرعة الاستجابة.",
"models.parameterList.reasoning_effort.title": "شدة التفكير",
"models.parameterList.temperature.desc": "تؤثر هذه الإعدادات على تنوع استجابة النموذج. القيم المنخفضة تؤدي إلى استجابات أكثر توقعًا ونمطية، بينما القيم الأعلى تشجع على استجابات أكثر تنوعًا وغير شائعة. عندما تكون القيمة 0، يعطي النموذج نفس الاستجابة دائمًا لنفس المدخل.",
"models.parameterList.temperature.title": "عشوائية",
"models.parameterList.presence_penalty.desc": "يتحكم هذا الإعداد في استخدام المفردات بناءً على تكرارها في الإدخال. القيم الأعلى تقلل من استخدام الكلمات المتكررة، بينما القيم السالبة تشجع على إعادة استخدامها.",
"models.parameterList.presence_penalty.title": "تجديد الموضوع",
"models.parameterList.range": "النطاق",
"models.parameterList.reasoning_effort.desc": "يتحكم هذا الإعداد في مستوى التفكير الذي يستخدمه النموذج قبل توليد الرد. القيم الأعلى توفر استدلالًا أعمق ولكنها أبطأ، بينما القيم الأقل أسرع ولكنها أقل دقة.",
"models.parameterList.reasoning_effort.title": "شدة الاستدلال",
"models.parameterList.temperature.desc": "يؤثر هذا الإعداد على تنوع الردود. القيم المنخفضة تؤدي إلى ردود أكثر توقعًا، بينما القيم الأعلى تنتج ردودًا أكثر تنوعًا.",
"models.parameterList.temperature.title": "العشوائية",
"models.parameterList.title": "معلمات النموذج",
"models.parameterList.top_p.desc": "تحدد هذه الإعدادات اختيار النموذج للكلمات ذات الاحتمالية الأعلى فقط: اختيار الكلمات التي تصل احتمالاتها التراكمية إلى P. القيم المنخفضة تجعل استجابات النموذج أكثر توقعًا، بينما الإعداد الافتراضي يسمح للنموذج بالاختيار من جميع نطاق الكلمات.",
"models.parameterList.top_p.title": "عينات النواة",
"models.parameterList.type": "نوع",
"models.providerInfo.apiTooltip": "يدعم LobeChat استخدام مفتاح API مخصص لهذا المزود.",
"models.parameterList.top_p.desc": "يحدد هذا الإعداد نسبة الكلمات الأكثر احتمالًا التي يمكن للنموذج اختيارها. القيم المنخفضة تجعل الردود أكثر قابلية للتنبؤ.",
"models.parameterList.top_p.title": "اختيار النواة",
"models.parameterList.type": "النوع",
"models.providerInfo.apiTooltip": "يدعم LobeHub استخدام مفتاح API مخصص لهذا المزود.",
"models.providerInfo.input": "سعر الإدخال",
"models.providerInfo.inputTooltip": "تكلفة لكل مليون Token",
"models.providerInfo.latency": "زمن الاستجابة",
"models.providerInfo.latencyTooltip": "متوسط زمن استجابة المزود لإرسال أول Token",
"models.providerInfo.maxOutput": "أقصى طول للإخراج",
"models.providerInfo.maxOutputTooltip": "عدد Tokens الأقصى الذي يمكن أن ينتجه هذا النقطة",
"models.providerInfo.officialTooltip": "خدمة رسمية من LobeHub",
"models.providerInfo.inputTooltip": "التكلفة لكل مليون رمز",
"models.providerInfo.latency": "الكمون",
"models.providerInfo.latencyTooltip": "متوسط وقت الاستجابة لإرسال أول رمز",
"models.providerInfo.maxOutput": "الحد الأقصى لطول الإخراج",
"models.providerInfo.maxOutputTooltip": "أقصى عدد من الرموز يمكن أن يولدها هذا الطرف",
"models.providerInfo.officialTooltip": "خدمة LobeHub الرسمية",
"models.providerInfo.output": "سعر الإخراج",
"models.providerInfo.outputTooltip": "تكلفة لكل مليون Token",
"models.providerInfo.streamCancellationTooltip": "يدعم هذا المزود ميزة إلغاء التدفق.",
"models.providerInfo.outputTooltip": "التكلفة لكل مليون رمز",
"models.providerInfo.streamCancellationTooltip": "يدعم هذا المزود إلغاء البث.",
"models.providerInfo.throughput": "معدل النقل",
"models.providerInfo.throughputTooltip": "متوسط عدد Tokens المنقولة في الطلبات المتدفقة في الثانية",
"models.providerInfo.throughputTooltip": "متوسط عدد الرموز المنقولة في الثانية لطلبات البث",
"models.sorts.contextWindowTokens": "طول السياق",
"models.sorts.identifier": "معرف النموذج",
"models.sorts.inputPrice": "سعر الإدخال",
"models.sorts.outputPrice": "سعر الإخراج",
"models.sorts.providerCount": "عدد المزودين",
"models.sorts.releasedAt": "تم النشر مؤخراً",
"models.sorts.releasedAt": "تم الإصدار مؤخرًا",
"models.suggestions": "نماذج ذات صلة",
"models.supportedProviders": "مزودو الخدمة المدعومون لهذا النموذج",
"plugins.builtinTag": "الملحقات المدمجة",
"plugins.community": "إضافات المجتمع",
"plugins.details.settings.title": "إعدادات الإضافة",
"plugins.details.summary.title": "ما الذي يمكنك فعله باستخدام هذه الإضافة؟",
"plugins.details.tools.title": "أدوات الإضافة",
"plugins.install": "تثبيت الإضافة",
"plugins.installed": "تم التثبيت",
"plugins.legacyTag": "الملحقات القديمة",
"plugins.list": "قائمة الإضافات",
"plugins.meta.description": "وصف",
"plugins.meta.parameter": "معامل",
"plugins.meta.title": "معامل الأداة",
"plugins.meta.type": "نوع",
"models.supportedProviders": "المزودون الداعمون لهذا النموذج",
"plugins.builtinTag": "مضمن",
"plugins.community": "مهارات المجتمع",
"plugins.details.settings.title": "إعدادات المهارة",
"plugins.details.summary.title": "ماذا يمكنك أن تفعل بهذه المهارة؟",
"plugins.details.tools.title": "أدوات المهارة",
"plugins.install": "تثبيت المهارة",
"plugins.installed": "مثبت",
"plugins.legacyTag": "قديم",
"plugins.list": "قائمة المهارات",
"plugins.meta.description": "الوصف",
"plugins.meta.parameter": "المعلمة",
"plugins.meta.title": "معلمات الأداة",
"plugins.meta.type": "النوع",
"plugins.more": "المزيد",
"plugins.official": "إضافات رسمية",
"plugins.recentSubmits": "آخر التحديثات",
"plugins.sorts.createdAt": "تم النشر مؤخراً",
"plugins.sorts.identifier": "معرف الإضافة",
"plugins.sorts.title": "اسم الإضافة",
"plugins.suggestions": "اقتراحات ذات صلة",
"providers.config": "تكوين مزود الخدمة",
"providers.details.guide.title": "دليل الاندماج",
"plugins.official": "مهارات رسمية",
"plugins.recentSubmits": "تم التحديث مؤخرًا",
"plugins.sorts.createdAt": "تم النشر مؤخرًا",
"plugins.sorts.identifier": "معرف المهارة",
"plugins.sorts.title": "اسم المهارة",
"plugins.suggestions": "توصيات ذات صلة",
"providers.config": "إعداد المزود",
"providers.details.guide.title": "دليل التكامل",
"providers.details.overview.title": "نظرة عامة",
"providers.details.related.listTitle": "مزودو الخدمة ذات الصلة",
"providers.details.related.listTitle": "مزودون ذوو صلة",
"providers.details.related.more": "عرض المزيد",
"providers.details.related.title": "اقتراحات ذات صلة",
"providers.empty.description": "حاول تعديل معايير التصفية لرؤية المزيد من المزودين",
"providers.details.related.title": "توصيات ذات صلة",
"providers.empty.description": "حاول تعديل الفلاتر لرؤية المزيد من المزودين.",
"providers.empty.search": "لم يتم العثور على مزودين مطابقين",
"providers.empty.title": "لا يوجد مزودون حالياً",
"providers.list": "قائمة مزودي النماذج",
"providers.empty.title": "لا يوجد مزودون",
"providers.list": "قائمة المزودين",
"providers.modelCount": "{{count}} نموذج",
"providers.modelName": "اسم النموذج",
"providers.modelSite": "وثائق النموذج",
"providers.modelSite": "توثيق النموذج",
"providers.more": "المزيد",
"providers.officialSite": "الموقع الرسمي",
"providers.showAllModels": "عرض جميع النماذج",
"providers.sorts.default": "الترتيب الافتراضي",
"providers.sorts.default": "الافتراضي",
"providers.sorts.identifier": "معرف المزود",
"providers.sorts.modelCount": "عدد النماذج",
"providers.suggestions": "مزودو الخدمة ذوو الصلة",
"providers.suggestions": "مزودون ذوو صلة",
"providers.supportedModels": "النماذج المدعومة",
"publishedTime": "نشر في",
"search.placeholder": "ابحث عن اسم أو كلمة مفتاحية...",
"search.result": "{{count}} نتيجة بحث حول <highlight>{{keyword}}</highlight>",
"publishedTime": "تاريخ النشر",
"search.placeholder": "ابحث بالاسم أو الوصف أو الكلمات المفتاحية...",
"search.result": "{{count}} نتيجة حول <highlight>{{keyword}}</highlight>",
"search.searching": "جارٍ البحث...",
"tab.assistant": "المساعد",
"tab.home": "الصفحة الرئيسية",
"tab.assistant": "الوكيل",
"tab.home": "الرئيسية",
"tab.model": "النموذج",
"tab.plugin": "الإضافة",
"tab.provider": "مزود النموذج",
"tab.plugin": "المهارة",
"tab.provider": "المزود",
"tab.user": "المستخدم",
"user.agents": "المساعدون",
"user.agents": "الوكلاء",
"user.downloads": "التنزيلات",
"user.editProfile": "تعديل الملف الشخصي",
"user.favoriteAgents": "المساعدون المفضلون",
"user.favoritePlugins": "الإضافات المفضلة",
"user.favoriteAgents": "الوكلاء المحفوظون",
"user.favoritePlugins": "المهارات المحفوظة",
"user.follow": "متابعة",
"user.followers": "المتابعون",
"user.following": "المتابَعون",
"user.following": "يتابع",
"user.login": "كن منشئًا",
"user.logout": "تسجيل الخروج",
"user.myProfile": "صفحتي الشخصية",
"user.noAgents": "لم يقم هذا المستخدم بنشر أي مساعدين بعد",
"user.noFavoriteAgents": "لا يوجد مساعدون مفضلون حاليًا",
"user.noFavoritePlugins": "لا توجد إضافات مفضلة حاليًا",
"user.publishedAgents": "المساعدون الذين أنشأتهم",
"user.myProfile": "ملفي الشخصي",
"user.noAgents": "لم ينشر هذا المستخدم أي وكلاء بعد",
"user.noFavoriteAgents": "لا يوجد وكلاء محفوظون بعد",
"user.noFavoritePlugins": "لا توجد مهارات محفوظة بعد",
"user.publishedAgents": "الوكلاء المنشؤون",
"user.tabs.favorites": "المفضلة",
"user.tabs.publishedAgents": "الإبداعات",
"user.unfavorite": زالة من المفضلة",
"user.unfavoriteFailed": "فشل في الإزالة من المفضلة",
"user.unfavoriteSuccess": "تمت الإزالة من المفضلة",
"user.tabs.publishedAgents": "تم الإنشاء",
"user.unfavorite": لغاء الحفظ",
"user.unfavoriteFailed": "فشل في إلغاء الحفظ",
"user.unfavoriteSuccess": "تم إلغاء الحفظ",
"user.unfollow": "إلغاء المتابعة",
"user.website": "الموقع الشخصي"
"user.website": "الموقع الإلكتروني"
}
+34 -26
View File
@@ -1,12 +1,20 @@
{
"actions.expand.off": "طي",
"actions.expand.on": "توسيع",
"actions.typobar.off": "إخفاء شريط أدوات التنسيق",
"actions.typobar.on": "إظهار شريط أدوات التنسيق",
"autoSave.latest": "تم تحميل أحدث إصدار",
"actions.typobar.off": "إخفاء شريط تنسيق النص",
"actions.typobar.on": "إظهار شريط تنسيق النص",
"autoSave.latest": "تم تحميل أحدث نسخة",
"autoSave.saved": "تم الحفظ",
"autoSave.saving": "يتم الحفظ تلقائيًا...",
"cancel": "إلغاء",
"codemirror.copyFailed": "فشل النسخ",
"codemirror.copySuccess": "تم نسخ الكود إلى الحافظة",
"codemirror.selectLanguage": "اختر اللغة",
"codemirror.selectTheme": "اختر السمة",
"codemirror.showLineNumbers": "إظهار أرقام الأسطر",
"codemirror.tabSize": "حجم التبويب",
"codemirror.theme": "السمة",
"codemirror.useTabs": "استخدام التبويبات",
"confirm": "تأكيد",
"file.error": "خطأ: {{message}}",
"file.uploading": "جاري رفع الملف...",
@@ -15,44 +23,44 @@
"link.editLinkTitle": "الرابط",
"link.editTextTitle": "العنوان",
"link.open": "فتح الرابط",
"link.placeholder": "أدخل عنوان URL للرابط",
"link.placeholder": "أدخل عنوان الرابط",
"link.unlink": "إزالة الرابط",
"markdown.cancel": "إلغاء",
"markdown.confirm": "تحويل",
"markdown.parseMessage": "سيتم تحويل المحتوى إلى تنسيق Markdown، وسيتم استبدال المحتوى الحالي. هل ترغب في المتابعة؟ (سيُغلق تلقائيًا بعد 5 ثوانٍ)",
"markdown.parseTitle": "تنسيق Markdown",
"math.placeholder": "يرجى إدخال معادلة TeX",
"modifier.accept": "احتفاظ",
"modifier.acceptAll": "قبول الكل",
"modifier.reject": "إلغاء",
"modifier.rejectAll": "إلغاء الكل",
"slash.h1": "عنوان رئيسي من المستوى الأول",
"slash.h2": "عنوان فرعي من المستوى الثاني",
"slash.h3": "عنوان فرعي من المستوى الثالث",
"slash.hr": "خط فاصل",
"markdown.parseMessage": "سيتم التحويل إلى تنسيق Markdown. سيتم استبدال المحتوى الحالي. هل أنت متأكد؟ (سيُغلق تلقائيًا خلال 5 ثوانٍ)",
"markdown.parseTitle": "تنسيق كـ Markdown",
"math.placeholder": "يرجى إدخال صيغة TeX",
"modifier.accept": "الاحتفاظ",
"modifier.acceptAll": "الاحتفاظ بالجميع",
"modifier.reject": "تراجع",
"modifier.rejectAll": "تراجع عن الكل",
"slash.h1": "عنوان 1",
"slash.h2": "عنوان 2",
"slash.h3": "عنوان 3",
"slash.hr": "فاصل",
"slash.table": "جدول",
"slash.tex": "معادلة TeX",
"slash.tex": "صيغة TeX",
"table.delete": "حذف الجدول",
"table.deleteColumn": "حذف العمود",
"table.deleteRow": "حذف الصف",
"table.insertColumnLeft": "إدراج {{count}} عمودًا إلى اليسار",
"table.insertColumnRight": "إدراج {{count}} عمودًا إلى اليمين",
"table.insertRowAbove": "إدراج {{count}} صفًا في الأعلى",
"table.insertRowBelow": "إدراج {{count}} صفًا في الأسفل",
"table.insertColumnLeft": "إدراج {{count}} عمود إلى اليسار",
"table.insertColumnRight": "إدراج {{count}} عمود إلى اليمين",
"table.insertRowAbove": "إدراج {{count}} صف أعلى",
"table.insertRowBelow": "إدراج {{count}} صف أسفل",
"typobar.blockquote": "اقتباس",
"typobar.bold": "غامق",
"typobar.bold": "عريض",
"typobar.bulletList": "قائمة نقطية",
"typobar.code": "كود مضمن",
"typobar.code": "كود مضمّن",
"typobar.codeblock": "كتلة كود",
"typobar.image": "صورة",
"typobar.italic": "مائل",
"typobar.link": "رابط",
"typobar.numberList": "قائمة مرقمة",
"typobar.redo": "إعادة",
"typobar.strikethrough": "شطب",
"typobar.strikethrough": "يتوسطه خط",
"typobar.table": "جدول",
"typobar.taskList": "قائمة المهام",
"typobar.tex": "معادلة TeX",
"typobar.underline": سطير",
"typobar.taskList": "قائمة مهام",
"typobar.tex": "صيغة TeX",
"typobar.underline": حته خط",
"typobar.undo": "تراجع"
}
+53 -53
View File
@@ -1,92 +1,92 @@
{
"notification.finishChatGeneration": "تم إنشاء رسالة الذكاء الاصطناعي بنجاح",
"notification.finishChatGeneration": "اكتمل توليد الرسالة بواسطة الذكاء الاصطناعي",
"proxy.auth": "يتطلب المصادقة",
"proxy.authDesc": "إذا كان خادم الوكيل يتطلب اسم مستخدم وكلمة مرور",
"proxy.authDesc": "إذا كان خادم البروكسي يتطلب اسم مستخدم وكلمة مرور",
"proxy.authSettings": "إعدادات المصادقة",
"proxy.basicSettings": "إعدادات الوكيل",
"proxy.basicSettingsDesc": "تكوين معلمات اتصال خادم الوكيل",
"proxy.bypass": "العناوين التي لا تستخدم الوكيل",
"proxy.basicSettings": "إعدادات البروكسي",
"proxy.basicSettingsDesc": "قم بتكوين معلمات الاتصال لخادم البروكسي",
"proxy.bypass": "العناوين التي لا تستخدم البروكسي",
"proxy.connectionTest": "اختبار الاتصال",
"proxy.enable": "تفعيل الوكيل",
"proxy.enableDesc": "عند التفعيل، سيتم الوصول إلى الشبكة عبر خادم الوكيل",
"proxy.enable": "تفعيل البروكسي",
"proxy.enableDesc": "عند التفعيل، سيتم توجيه الوصول إلى الشبكة عبر خادم البروكسي",
"proxy.password": "كلمة المرور",
"proxy.password_placeholder": "الرجاء إدخال كلمة المرور",
"proxy.password_placeholder": "يرجى إدخال كلمة المرور",
"proxy.port": "المنفذ",
"proxy.resetButton": "إعادة تعيين",
"proxy.saveButton": "حفظ",
"proxy.saveFailed": "فشل الحفظ: {{error}}",
"proxy.saveSuccess": "تم حفظ إعدادات الوكيل بنجاح",
"proxy.saveSuccess": "تم حفظ إعدادات البروكسي بنجاح",
"proxy.server": "عنوان الخادم",
"proxy.testButton": "اختبار الاتصال",
"proxy.testDescription": "اختبر الاتصال باستخدام إعدادات الوكيل الحالية للتحقق من صحة التكوين",
"proxy.testDescription": "اختبر الاتصال باستخدام إعدادات البروكسي الحالية للتحقق من عمله بشكل صحيح",
"proxy.testFailed": "فشل الاتصال",
"proxy.testSuccessWithTime": "تم اختبار الاتصال بنجاح، استغرق {{time}} مللي ثانية",
"proxy.testUrl": "عنوان الاختبار",
"proxy.testUrlPlaceholder": "الرجاء إدخال عنوان URL للاختبار",
"proxy.testSuccessWithTime": "نجح اختبار الاتصال، استغرق {{time}} مللي ثانية",
"proxy.testUrl": "رابط الاختبار",
"proxy.testUrlPlaceholder": "يرجى إدخال الرابط للاختبار",
"proxy.testing": "جارٍ اختبار الاتصال...",
"proxy.type": "نوع الوكيل",
"proxy.type": "نوع البروكسي",
"proxy.unsavedChanges": "لديك تغييرات غير محفوظة",
"proxy.username": "اسم المستخدم",
"proxy.username_placeholder": "الرجاء إدخال اسم المستخدم",
"proxy.username_placeholder": "يرجى إدخال اسم المستخدم",
"proxy.validation.passwordRequired": "كلمة المرور مطلوبة عند تفعيل المصادقة",
"proxy.validation.portInvalid": "يجب أن يكون المنفذ رقمًا بين 1 و 65535",
"proxy.validation.portRequired": "المنفذ مطلوب عند تفعيل الوكيل",
"proxy.validation.portInvalid": "يجب أن يكون المنفذ رقماً بين 1 و65535",
"proxy.validation.portRequired": "المنفذ مطلوب عند تفعيل البروكسي",
"proxy.validation.serverInvalid": "يرجى إدخال عنوان خادم صالح (IP أو اسم نطاق)",
"proxy.validation.serverRequired": "عنوان الخادم مطلوب عند تفعيل الوكيل",
"proxy.validation.typeRequired": "نوع الوكيل مطلوب عند تفعيل الوكيل",
"proxy.validation.serverRequired": "عنوان الخادم مطلوب عند تفعيل البروكسي",
"proxy.validation.typeRequired": "نوع البروكسي مطلوب عند تفعيل البروكسي",
"proxy.validation.usernameRequired": "اسم المستخدم مطلوب عند تفعيل المصادقة",
"remoteServer.authError": "فشل التفويض: {{error}}",
"remoteServer.authPending": "يرجى إكمال التفويض في المتصفح",
"remoteServer.configDesc": "الاتصال بخادم LobeChat البعيد، تمكين مزامنة البيانات",
"remoteServer.configDesc": "اتصل بخادم LobeHub البعيد لتمكين مزامنة البيانات",
"remoteServer.configError": "خطأ في التكوين",
"remoteServer.configTitle": "تكوين المزامنة السحابية",
"remoteServer.connect": "الاتصال والتفويض",
"remoteServer.connect": "اتصل وفعّل التفويض",
"remoteServer.connected": "متصل",
"remoteServer.disconnect": "قطع الاتصال",
"remoteServer.disconnectError": "فشل في قطع الاتصال",
"remoteServer.disconnected": "غير متصل",
"remoteServer.fetchError": "فشل في جلب التكوين",
"remoteServer.invalidUrl": "يرجى إدخال عنوان URL صالح",
"remoteServer.invalidUrl": "يرجى إدخال رابط صالح",
"remoteServer.serverUrl": "عنوان الخادم",
"remoteServer.statusConnected": "متصل",
"remoteServer.statusDisconnected": "غير متصل",
"remoteServer.urlRequired": "يرجى إدخال عنوان الخادم",
"sync.continue": "استمر",
"sync.inCloud": "تستخدم حاليًا المزامنة السحابية",
"sync.inLocalStorage": "تستخدم حاليًا التخزين المحلي",
"sync.continue": "متابعة",
"sync.inCloud": "يتم استخدام المزامنة السحابية حالياً",
"sync.inLocalStorage": "يتم استخدام التخزين المحلي حالياً",
"sync.isIniting": "جارٍ التهيئة...",
"sync.lobehubCloud.description": "الإصدار السحابي المقدم رسميًا",
"sync.lobehubCloud.title": "LobeHub Cloud",
"sync.local.description": "استخدام قاعدة بيانات محلية، متاحة بالكامل دون اتصال",
"sync.local.title": "قاعدة بيانات محلية",
"sync.lobehubCloud.description": "الإصدار السحابي الرسمي المقدم",
"sync.lobehubCloud.title": "سحابة LobeHub",
"sync.local.description": "يستخدم قاعدة بيانات محلية، متاح بالكامل دون اتصال",
"sync.local.title": "قاعدة البيانات المحلية",
"sync.mode.cloudSync": "مزامنة سحابية",
"sync.mode.localStorage": "تخزين محلي",
"sync.mode.title": "اختر وضع الاتصال الخاص بك",
"sync.mode.useSelfHosted": "استخدام نسخة مستضافة ذاتيًا؟",
"sync.selfHosted.description": "نسخة المجتمع التي تم نشرها ذاتيًا",
"sync.selfHosted.title": "نسخة مستضافة ذاتيًا",
"updater.checkingUpdate": "التحقق من وجود تحديثات",
"updater.checkingUpdateDesc": "جارٍ الحصول على معلومات الإصدار...",
"updater.downloadNewVersion": "تحميل إصدار جديد",
"updater.downloadingUpdate": "جارٍ تنزيل التحديث",
"updater.downloadingUpdateDesc": "يتم تنزيل التحديث، يرجى الانتظار...",
"updater.installLater": "تحديث عند بدء التشغيل التالي",
"updater.isLatestVersion": "الإصدار الحالي هو الأحدث",
"updater.isLatestVersionDesc": "رائع، الإصدار {{version}} الذي تستخدمه هو أحدث إصدار متاح.",
"updater.later": "لاحقًا",
"updater.newVersionAvailable": "يتوفر إصدار جديد",
"updater.newVersionAvailableDesc": "تم العثور على إصدار جديد {{version}}، هل ترغب في التنزيل الآن؟",
"updater.restartAndInstall": "تثبيت التحديث وإعادة التشغيل",
"sync.mode.title": "اختر وضع الاتصال",
"sync.mode.useSelfHosted": "هل تريد استخدام نسخة مستضافة ذاتياً؟",
"sync.selfHosted.description": "نسخة المجتمع التي يمكنك نشرها بنفسك",
"sync.selfHosted.title": "نسخة مستضافة ذاتياً",
"updater.checkingUpdate": "جارٍ التحقق من التحديثات",
"updater.checkingUpdateDesc": "جارٍ جلب معلومات الإصدار...",
"updater.downloadNewVersion": "تحميل الإصدار الجديد",
"updater.downloadingUpdate": "جارٍ تحميل التحديث",
"updater.downloadingUpdateDesc": "جارٍ تحميل التحديث، يرجى الانتظار...",
"updater.installLater": ثبيت التحديث عند التشغيل التالي",
"updater.isLatestVersion": "أنت تستخدم أحدث إصدار",
"updater.isLatestVersionDesc": "رائع! الإصدار {{version}} الذي تستخدمه هو الأحدث المتاح.",
"updater.later": "لاحقاً",
"updater.newVersionAvailable": "إصدار جديد متاح",
"updater.newVersionAvailableDesc": "تم العثور على إصدار جديد {{version}}، هل ترغب في تحميله الآن؟",
"updater.restartAndInstall": "تثبيت التحديثات وإعادة التشغيل",
"updater.updateError": "خطأ في التحديث",
"updater.updateReady": "يتوفر إصدار جديد",
"updater.updateReadyDesc": "تم تنزيل الإصدار الجديد {{version}}، يمكنك إكمال التثبيت بعد إعادة تشغيل التطبيق.",
"updater.updateReady": "إصدار جديد متاح",
"updater.updateReadyDesc": "تم تحميل الإصدار الجديد {{version}}. أعد تشغيل التطبيق لإكمال التثبيت.",
"updater.upgradeNow": "تحديث الآن",
"updater.willInstallLater": "سيتم تثبيت التحديث عند بدء التشغيل التالي",
"updater.willInstallLater": "سيتم تثبيت التحديث عند التشغيل التالي",
"waitingOAuth.cancel": "إلغاء",
"waitingOAuth.description": "تم فتح صفحة التفويض في المتصفح، يرجى إكمال التفويض في المتصفح",
"waitingOAuth.description": "تم فتح صفحة التفويض في المتصفح، يرجى إكمال التفويض هناك",
"waitingOAuth.error": "فشل التفويض: {{error}}",
"waitingOAuth.errorTitle": "فشل في الاتصال بالتفويض",
"waitingOAuth.helpText": "إذا لم يفتح المتصفح تلقائيًا، يرجى النقر على إلغاء ثم المحاولة مرة أخرى",
"waitingOAuth.retry": "أعد المحاولة",
"waitingOAuth.title": "انتظار الاتصال بالتفويض"
"waitingOAuth.errorTitle": "فشل الاتصال بالتفويض",
"waitingOAuth.helpText": "إذا لم يفتح المتصفح تلقائياً، يرجى النقر على إلغاء والمحاولة مرة أخرى",
"waitingOAuth.retry": "إعادة المحاولة",
"waitingOAuth.title": "في انتظار الاتصال بالتفويض"
}
+128 -127
View File
@@ -1,147 +1,148 @@
{
"clerkAuth.loginSuccess.action": "استمر في الجلسة",
"clerkAuth.loginSuccess.desc": "{{greeting}}، يسعدني أن أواصل خدمتك. دعنا نواصل الحديث عن الموضوع الذي تحدثنا عنه مؤخرًا",
"clerkAuth.loginSuccess.action": "متابعة الجلسة",
"clerkAuth.loginSuccess.desc": "{{greeting}}، يسعدنا الاستمرار في خدمتك. لنكمل من حيث توقفنا.",
"clerkAuth.loginSuccess.title": "مرحبًا بعودتك، {{nickName}}",
"error.backHome": "العودة إلى الصفحة الرئيسية",
"error.desc": "حاول مرة أخرى في وقت لاحق، أو عد إلى العالم المألوف",
"error.desc": "حاول مرة أخرى لاحقًا، أو عد إلى العالم المعروف.",
"error.retry": "إعادة التحميل",
"error.title": "واجهت الصفحة مشكلة ما..",
"error.title": "عذرًا، حدث خطأ ما..",
"fetchError.detail": "تفاصيل الخطأ",
"fetchError.title": "فشل الطلب",
"import.importConfigFile.description": "سبب الخطأ: {{reason}}",
"import.importConfigFile.title": "فشل الاستيراد",
"import.incompatible.description": "تم تصدير هذا الملف من إصدار أعلى، يرجى محاولة الترقية إلى أحدث إصدار ثم إعادة الاستيراد",
"import.incompatible.description": "تم تصدير هذا الملف من إصدار أحدث. يرجى الترقية إلى أحدث إصدار ثم إعادة الاستيراد.",
"import.incompatible.title": "التطبيق الحالي لا يدعم استيراد هذا الملف",
"loginRequired.desc": "سيتم التحويل تلقائيًا إلى صفحة تسجيل الدخول",
"loginRequired.desc": "سيتم تحويلك إلى صفحة تسجيل الدخول قريبًا",
"loginRequired.title": "يرجى تسجيل الدخول لاستخدام هذه الميزة",
"notFound.backHome": "العودة إلى الصفحة الرئيسية",
"notFound.check": "يرجى التحقق من صحة عنوان URL الخاص بك",
"notFound.desc": "لم نتمكن من العثور على الصفحة التي تبحث عنها",
"notFound.title": "هل دخلت إلى مجال غير معروف؟",
"pluginSettings.desc": "أكمل الإعدادات التالية لبدء استخدام هذا المكون الإضافي",
"pluginSettings.title": "تكوين مكون الإضافة {{name}}",
"response.400": "عذرًا، الخادم غير قادر على فهم طلبك، يرجى التحقق من صحة معلمات الطلب الخاصة بك",
"response.401": "عذرًا، رفض الخادم طلبك، قد يكون بسبب صلاحياتك غير الكافية أو عدم تقديم التحقق من الهوية الصالحة",
"response.403": "عذرًا، رفض الخادم طلبك، ليس لديك إذن للوصول إلى هذا المحتوى",
"response.404": "عذرًا، الخادم لا يمكنه العثور على الصفحة أو المورد المطلوب، يرجى التحقق من صحة عنوان URL الخاص بك",
"response.405": "عذرًا، الخادم لا يدعم طريقة الطلب المستخدمة، يرجى التحقق من صحة طريقة الطلب الخاصة بك",
"response.406": "عذرًا، الخادم غير قادر على استكمال الطلب وفقًا لخصائص المحتوى التي طلبتها",
"response.407": "عذرًا، تحتاج إلى مصادقة الوكيل لمتابعة هذا الطلب",
"response.408": "عذرًا، تجاوز الخادم الوقت المحدد في انتظار الطلب، يرجى التحقق من اتصالك بالشبكة والمحاولة مرة أخرى",
"response.409": "عذرًا، يوجد تضارب في الطلب الذي لا يمكن معالجته، قد يكون بسبب عدم توافق حالة المورد مع الطلب",
"response.410": "عذرًا، تمت إزالة المورد الذي طلبته بشكل دائم ولا يمكن العثور عليه",
"response.411": "عذرًا، الخادم غير قادر على معالجة الطلب الذي لا يحتوي على طول محتوى صالح",
"response.412": "عذرًا، لم يتم تلبية شروط الخادم الجانبية لطلبك ولا يمكن استكمال الطلب",
"response.413": "عذرًا، حجم بيانات طلبك كبير جدًا والخادم غير قادر على معالجته",
"response.414": "عذرًا، طول عنوان URI الخاص بطلبك كبير جدًا والخادم غير قادر على معالجته",
"response.415": "عذرًا، الخادم غير قادر على معالجة تنسيق الوسائط المرفقة بالطلب",
"response.416": "عذرًا، الخادم غير قادر على تلبية نطاق الطلب الذي قدمته",
"response.417": "عذرًا، الخادم غير قادر على تلبية قيم توقعاتك",
"response.422": "عذرًا، الطلب لديه تنسيق صحيح، ولكن بسبب وجود أخطاء دلالية، لا يمكن الاستجابة",
"response.423": "عذرًا، تم قفل المورد الذي طلبته",
"response.424": "عذرًا، بسبب فشل الطلب السابق، لا يمكن استكمال الطلب الحالي",
"response.426": "عذرًا، يتطلب الخادم ترقية عميلك إلى إصدار بروتوكول أعلى",
"response.428": "عذرًا، يتطلب الخادم شروطًا مسبقة، ويجب أن يحتوي طلبك على رؤوس الشروط الصحيحة",
"response.429": "عذرًا، طلبك كثير جدًا والخادم متعب قليلاً، يرجى المحاولة مرة أخرى لاحقًا",
"response.431": "عذرًا، حقول رأس الطلب الخاصة بك كبيرة جدًا والخادم غير قادر على معالجتها",
"response.451": "عذرًا، بسبب الأسباب القانونية، يرفض الخادم توفير هذا المورد",
"response.499": "نعتذر، تم قطع طلبك بشكل غير متوقع أثناء معالجته على الخادم، قد يكون ذلك بسبب إلغاء العملية من قبلك أو بسبب عدم استقرار الاتصال بالشبكة. يرجى التحقق من حالة الشبكة ثم إعادة المحاولة.",
"response.500": "عذرًا، يبدو أن الخادم واجه بعض الصعوبات ولا يمكنه حاليًا استكمال طلبك، يرجى المحاولة مرة أخرى لاحقًا",
"response.501": "عذرًا، لا يعرف الخادم كيفية معالجة هذا الطلب، يرجى التأكد من صحة العملية الخاصة بك",
"response.502": "عذرًا، يبدو أن الخادم قد ضل الطريق ولا يمكنه حاليًا تقديم الخدمة، يرجى المحاولة مرة أخرى لاحقًا",
"response.503": "عذرًا، الخادم غير قادر حاليًا على معالجة طلبك، قد يكون بسبب الحمل الزائد أو الصيانة الجارية، يرجى المحاولة مرة أخرى لاحقًا",
"response.504": "عذرًا، الخادم لم ينتظر ردًا من الخادم الأصلي، يرجى المحاولة مرة أخرى لاحقًا",
"response.505": "عذرًا، لا يدعم الخادم إصدار HTTP الذي تستخدمه، يرجى التحديث والمحاولة مرة أخرى",
"response.506": "عذرًا، هناك مشكلة في تكوين الخادم، يرجى الاتصال بالمسؤول لحلها",
"response.507": "عذرًا، لا يوجد مساحة تخزين كافية على الخادم لمعالجة طلبك، يرجى المحاولة مرة أخرى لاحقًا",
"response.509": "عذرًا، لقد استنفد الخادم النطاق الترددي، يرجى المحاولة مرة أخرى لاحقًا",
"response.510": "عذرًا، لا يدعم الخادم الوظائف الإضافية المطلوبة، يرجى الاتصال بالمسؤول",
"response.520": "نعتذر، واجه الخادم مشكلة غير متوقعة، مما أدى إلى عدم القدرة على إكمال طلبك. يرجى المحاولة لاحقًا، نحن نعمل على حل هذه المشكلة.",
"response.522": "نعتذر، انتهت مهلة الاتصال بالخادم، ولم يتمكن من الاستجابة لطلبك في الوقت المناسب. قد يكون ذلك بسبب عدم استقرار الشبكة أو أن الخادم غير متاح مؤقتًا. يرجى المحاولة لاحقًا، نحن نبذل جهدًا لاستعادة الخدمة.",
"response.524": "نعتذر، انتهت مهلة الخادم أثناء انتظار الرد، قد يكون ذلك بسبب بطء الاستجابة، يرجى المحاولة لاحقًا.",
"response.AgentRuntimeError": "حدث خطأ في تشغيل نموذج Lobe اللغوي، يرجى التحقق من المعلومات التالية أو إعادة المحاولة",
"response.ComfyUIBizError": "حدث خطأ أثناء طلب خدمة ComfyUI، يرجى التحقق من المعلومات التالية أو المحاولة مرة أخرى",
"response.ComfyUIEmptyResult": "لم يتم إنشاء أي صورة من قبل ComfyUI، يرجى التحقق من إعدادات النموذج أو المحاولة مرة أخرى",
"response.ComfyUIModelError": "فشل تحميل نموذج ComfyUI، يرجى التحقق من وجود ملف النموذج",
"response.ComfyUIServiceUnavailable": "فشل الاتصال بخدمة ComfyUI، يرجى التأكد من أن ComfyUI يعمل بشكل صحيح أو التحقق من صحة عنوان الخدمة",
"response.ComfyUIUploadFailed": "فشل تحميل الصورة إلى ComfyUI، يرجى التحقق من الاتصال بالخادم أو المحاولة مرة أخرى",
"response.ComfyUIWorkflowError": "فشل تنفيذ سير العمل في ComfyUI، يرجى التحقق من إعدادات سير العمل",
"response.ConnectionCheckFailed": "الاستجابة فارغة، يرجى التحقق من أن عنوان وكيل الـ API لا ينتهي بـ `/v1`",
"response.CreateMessageError": "عذرًا، لم يتم إرسال الرسالة بشكل صحيح، يرجى نسخ المحتوى وإعادة إرساله، بعد تحديث الصفحة لن يتم الاحتفاظ بهذه الرسالة",
"response.ExceededContextWindow": "المحتوى المطلوب الحالي يتجاوز الطول الذي يمكن للنموذج معالجته، يرجى تقليل كمية المحتوى ثم إعادة المحاولة",
"response.FreePlanLimit": "أنت حاليًا مستخدم مجاني، لا يمكنك استخدام هذه الوظيفة، يرجى الترقية إلى خطة مدفوعة للمتابعة",
"response.GoogleAIBlockReason.BLOCKLIST": "يحتوي المحتوى الذي أرسلته على كلمات محظورة. يرجى مراجعته وتعديل مدخلاتك ثم المحاولة مرة أخرى.",
"response.GoogleAIBlockReason.IMAGE_SAFETY": "تم حظر المحتوى الصوري الناتج لأسباب تتعلق بالأمان. يرجى محاولة تعديل طلب توليد الصورة.",
"response.GoogleAIBlockReason.LANGUAGE": "اللغة التي تستخدمها غير مدعومة مؤقتًا. يرجى المحاولة باللغة الإنجليزية أو بلغة أخرى مدعومة.",
"response.GoogleAIBlockReason.OTHER": "تم حظر المحتوى لسبب غير معروف. يرجى محاولة إعادة صياغة طلبك.",
"response.GoogleAIBlockReason.PROHIBITED_CONTENT": "قد يحتوي طلبك على محتوى محظور. يرجى تعديل طلبك لضمان توافقه مع سياسات الاستخدام.",
"response.GoogleAIBlockReason.RECITATION": "تم حظر محتواك لكونه قد ينتهك حقوق النشر. يرجى محاولة استخدام محتوى أصلي أو إعادة صياغة طلبك.",
"response.GoogleAIBlockReason.SAFETY": "تم حظر المحتوى بسبب سياسات السلامة. يرجى تعديل طلبك لتجنب أي محتوى ضار أو غير مناسب.",
"response.GoogleAIBlockReason.SPII": "قد يحتوي المحتوى على معلومات شخصية حساسة. لحماية الخصوصية، يرجى إزالة المعلومات الحساسة ثم المحاولة مرة أخرى.",
"response.GoogleAIBlockReason.default": "تم حظر المحتوى: {{blockReason}}. يرجى تعديل طلبك ثم المحاولة مرة أخرى.",
"response.InsufficientQuota": "عذرًا، لقد تم الوصول إلى الحد الأقصى لحصة المفتاح (quota). يرجى التحقق من رصيد الحساب أو زيادة حصة المفتاح ثم المحاولة مرة أخرى.",
"response.InvalidAccessCode": "كلمة المرور غير صحيحة أو فارغة، يرجى إدخال كلمة مرور الوصول الصحيحة أو إضافة مفتاح API مخصص",
"response.InvalidBedrockCredentials": "فشلت مصادقة Bedrock، يرجى التحقق من AccessKeyId/SecretAccessKey وإعادة المحاولة",
"response.InvalidClerkUser": "عذرًا، لم تقم بتسجيل الدخول بعد، يرجى تسجيل الدخول أو التسجيل للمتابعة",
"response.InvalidComfyUIArgs": "تكوين ComfyUI غير صحيح، يرجى التحقق من إعدادات ComfyUI ثم المحاولة مرة أخرى",
"response.InvalidGithubToken": "رمز وصول شخصية GitHub غير صحيح أو فارغ، يرجى التحقق من رمز وصول GitHub الشخصي والمحاولة مرة أخرى",
"response.InvalidOllamaArgs": "تكوين Ollama غير صحيح، يرجى التحقق من تكوين Ollama وإعادة المحاولة",
"response.InvalidProviderAPIKey": "{{provider}} مفتاح API غير صحيح أو فارغ، يرجى التحقق من مفتاح API {{provider}} الخاص بك وحاول مرة أخرى",
"response.InvalidVertexCredentials": "فشل التحقق من بيانات اعتماد Vertex، يرجى التحقق من بيانات الاعتماد وإعادة المحاولة",
"response.LocationNotSupportError": "عذرًا، لا يدعم موقعك الحالي خدمة هذا النموذج، قد يكون ذلك بسبب قيود المنطقة أو عدم توفر الخدمة. يرجى التحقق مما إذا كان الموقع الحالي يدعم استخدام هذه الخدمة، أو محاولة استخدام معلومات الموقع الأخرى.",
"response.ModelNotFound": "عذرًا، لا يمكن طلب النموذج المطلوب، قد يكون النموذج غير موجود أو أن الوصول غير مصرح به، يرجى تغيير مفتاح API أو تعديل أذونات الوصول ثم إعادة المحاولة",
"response.NoOpenAIAPIKey": "مفتاح API الخاص بـ OpenAI فارغ، يرجى إضافة مفتاح API الخاص بـ OpenAI",
"response.OllamaBizError": "خطأ في طلب خدمة Ollama، يرجى التحقق من المعلومات التالية أو إعادة المحاولة",
"response.OllamaServiceUnavailable": "خدمة Ollama غير متوفرة، يرجى التحقق من تشغيل Ollama بشكل صحيح أو إعدادات الـ Ollama للاتصال عبر النطاقات",
"response.PermissionDenied": "عذرًا، ليس لديك إذن للوصول إلى هذه الخدمة، يرجى التحقق مما إذا كانت مفاتيحك تمتلك إذن الوصول",
"response.PluginApiNotFound": "عذرًا، لا يوجد API للإضافة في وصف الإضافة، يرجى التحقق من تطابق طريقة الطلب الخاصة بك مع API الوصف",
"response.PluginApiParamsError": "عذرًا، فشلت التحقق من صحة معلمات الطلب للإضافة، يرجى التحقق من تطابق المعلمات مع معلومات الوصف",
"response.PluginFailToTransformArguments": "عذرًا، فشل تحويل معلمات استدعاء الإضافة، يرجى محاولة إعادة إنشاء رسالة المساعد أو تجربة نموذج AI ذو قدرات استدعاء أقوى",
"response.PluginGatewayError": "عذرًا، حدث خطأ في بوابة الإضافة، يرجى التحقق من تكوين بوابة الإضافة",
"response.PluginManifestInvalid": "عذرًا، فشلت التحقق من صحة وصف الإضافة، يرجى التحقق من تنسيق وصف الإضافة",
"response.PluginManifestNotFound": "عذرًا، لم يتم العثور على وصف الإضافة (manifest.json) في الخادم، يرجى التحقق من صحة عنوان ملف وصف الإضافة",
"response.PluginMarketIndexInvalid": "عذرًا، فشلت التحقق من صحة فهرس الإضافات، يرجى التحقق من تنسيق ملف الفهرس",
"response.PluginMarketIndexNotFound": "عذرًا، لم يتم العثور على فهرس الإضافات في الخادم، يرجى التحقق من صحة عنوان الفهرس",
"response.PluginMetaInvalid": "عذرًا، فشلت التحقق من صحة بيانات الإضافة، يرجى التحقق من تنسيق بيانات الإضافة",
"response.PluginMetaNotFound": "عذرًا، لم يتم العثور على معلومات تكوين الإضافة في الفهرس",
"response.PluginOpenApiInitError": "عذرًا، فشل تهيئة عميل OpenAPI، يرجى التحقق من معلومات تكوين OpenAPI",
"response.PluginServerError": "خطأ في استجابة الخادم لطلب الإضافة، يرجى التحقق من ملف وصف الإضافة وتكوين الإضافة وتنفيذ الخادم وفقًا لمعلومات الخطأ أدناه",
"response.PluginSettingsInvalid": حتاج هذه الإضافة إلى تكوين صحيح قبل الاستخدام، يرجى التحقق من صحة تكوينك",
"response.ProviderBizError": "طلب خدمة {{provider}} خاطئ، يرجى التحقق من المعلومات التالية أو إعادة المحاولة",
"response.QuotaLimitReached": "عذرًا، لقد تم الوصول إلى الحد الأقصى لاستخدام الرموز (Token) أو عدد الطلبات لهذا المفتاح. يرجى زيادة حصة المفتاح أو المحاولة لاحقًا.",
"response.ServerAgentRuntimeError": "عذرًا، خدمة الوكيل غير متاحة حاليًا. يرجى المحاولة لاحقًا أو التواصل معنا عبر البريد الإلكتروني للحصول على الدعم.",
"response.StreamChunkError": "خطأ في تحليل كتلة الرسالة لطلب التدفق، يرجى التحقق مما إذا كانت واجهة برمجة التطبيقات الحالية تتوافق مع المعايير، أو الاتصال بمزود واجهة برمجة التطبيقات الخاصة بك للاستفسار.",
"response.SubscriptionKeyMismatch": "نعتذر، بسبب عطل عرضي في النظام، فإن استخدام الاشتراك الحالي غير فعال مؤقتًا. يرجى النقر على الزر أدناه لاستعادة الاشتراك، أو مراسلتنا عبر البريد الإلكتروني للحصول على الدعم.",
"response.SubscriptionPlanLimit": "لقد استنفدت نقاط اشتراكك، ولا يمكنك استخدام هذه الميزة. يرجى الترقية إلى خطة أعلى، أو تكوين واجهة برمجة التطبيقات للنموذج المخصص للاستمرار في الاستخدام",
"response.SystemTimeNotMatchError": "عذرًا، وقت النظام لديك لا يتطابق مع الخادم، يرجى التحقق من وقت النظام لديك ثم إعادة المحاولة",
"response.UnknownChatFetchError": "عذرًا، حدث خطأ غير معروف في الطلب، يرجى التحقق من المعلومات التالية أو المحاولة مرة أخرى",
"stt.responseError": "فشل طلب الخدمة، يرجى التحقق من الإعدادات أو إعادة المحاولة",
"supervisor.decisionFailed": "تعذر على مشرف المجموعة العمل. يرجى التحقق من إعدادات المشرف الخاصة بك، والتأكد من تكوين النموذج الصحيح، ومفتاح API، وعنوان API.",
"notFound.check": "يرجى التحقق من صحة عنوان URL.",
"notFound.desc": "لم نتمكن من العثور على الصفحة التي تبحث عنها.",
"notFound.title": "هل دخلت منطقة غير معروفة؟",
"pluginSettings.desc": "أكمل الإعدادات التالية لبدء استخدام هذه المهارة",
"pluginSettings.title": "إعدادات مهارة {{name}}",
"response.400": "عذرًا، الخادم لا يفهم طلبك. يرجى التأكد من صحة معلمات الطلب.",
"response.401": "عذرًا، تم رفض طلبك من قبل الخادم، ربما بسبب عدم كفاية الصلاحيات أو فشل التوثيق.",
"response.403": "عذرًا، تم رفض طلبك. ليس لديك إذن للوصول إلى هذا المحتوى.",
"response.404": "عذرًا، لم يتم العثور على الصفحة أو المورد المطلوب. يرجى التأكد من صحة عنوان URL.",
"response.405": "عذرًا، لا يدعم الخادم طريقة الطلب المستخدمة. يرجى التأكد من صحة طريقة الطلب.",
"response.406": "عذرًا، لا يمكن للخادم إكمال الطلب بناءً على خصائص المحتوى المطلوب.",
"response.407": "عذرًا، تحتاج إلى توثيق الوكيل قبل متابعة هذا الطلب.",
"response.408": "عذرًا، انتهت مهلة الخادم أثناء انتظار الطلب. يرجى التحقق من اتصالك بالشبكة والمحاولة مرة أخرى.",
"response.409": "عذرًا، لا يمكن معالجة الطلب بسبب تعارض، ربما بسبب حالة المورد غير المتوافقة مع الطلب.",
"response.410": "عذرًا، تم حذف المورد المطلوب بشكل دائم ولا يمكن العثور عليه.",
"response.411": "عذرًا، لا يمكن للخادم معالجة الطلب بدون طول محتوى صالح.",
"response.412": "عذرًا، لا يستوفي طلبك شروط الخادم ولا يمكن إكماله.",
"response.413": "عذرًا، بيانات الطلب كبيرة جدًا ولا يمكن معالجتها من قبل الخادم.",
"response.414": "عذرًا، عنوان URI الخاص بطلبك طويل جدًا ولا يمكن معالجته.",
"response.415": "عذرًا، لا يمكن للخادم معالجة تنسيق الوسائط المرفق بالطلب.",
"response.416": "عذرًا، لا يمكن للخادم تلبية نطاق طلبك.",
"response.417": "عذرًا، لا يمكن للخادم تلبية توقعاتك.",
"response.422": "عذرًا، تنسيق الطلب صحيح، ولكن لا يمكن الرد عليه بسبب أخطاء دلالية.",
"response.423": "عذرًا، المورد المطلوب مقفل.",
"response.424": "عذرًا، لا يمكن إكمال الطلب الحالي بسبب فشل في طلب سابق.",
"response.426": "عذرًا، يتطلب الخادم ترقية إصدار البروتوكول المستخدم.",
"response.428": "عذرًا، يتطلب الخادم شرطًا مسبقًا، ويجب أن يحتوي طلبك على ترويسة شرطية صحيحة.",
"response.429": "عذرًا، طلباتك متكررة جدًا والخادم مرهق. يرجى المحاولة لاحقًا.",
"response.431": "عذرًا، حقول الترويسة في طلبك كبيرة جدًا ولا يمكن معالجتها.",
"response.451": "عذرًا، يرفض الخادم توفير هذا المورد لأسباب قانونية.",
"response.499": "نعتذر، تم قطع طلبك بشكل غير متوقع أثناء معالجته من قبل الخادم، ربما بسبب إلغاء العملية أو ضعف الاتصال. يرجى التحقق من الشبكة والمحاولة مجددًا.",
"response.500": "عذرًا، يبدو أن الخادم يواجه صعوبات مؤقتة ولا يمكنه إكمال طلبك. يرجى المحاولة لاحقًا.",
"response.501": "عذرًا، لا يعرف الخادم كيفية معالجة هذا الطلب بعد. يرجى التأكد من صحة العملية.",
"response.502": "عذرًا، يبدو أن الخادم غير متصل مؤقتًا ولا يمكنه تقديم الخدمة. يرجى المحاولة لاحقًا.",
"response.503": "عذرًا، لا يمكن للخادم حاليًا معالجة طلبك، ربما بسبب الحمل الزائد أو الصيانة. يرجى المحاولة لاحقًا.",
"response.504": "عذرًا، لم يتلق الخادم ردًا من الخادم العلوي. يرجى المحاولة لاحقًا.",
"response.505": "عذرًا، لا يدعم الخادم إصدار HTTP الذي تستخدمه. يرجى التحديث والمحاولة مجددًا.",
"response.506": "عذرًا، هناك مشكلة في إعدادات الخادم. يرجى التواصل مع المسؤول لحل المشكلة.",
"response.507": "عذرًا، لا توجد مساحة تخزين كافية على الخادم لمعالجة طلبك. يرجى المحاولة لاحقًا.",
"response.509": "عذرًا، تم استهلاك عرض النطاق الترددي للخادم. يرجى المحاولة لاحقًا.",
"response.510": "عذرًا، لا يدعم الخادم الامتداد المطلوب. يرجى التواصل مع المسؤول.",
"response.520": "نعتذر، واجه الخادم مشكلة غير متوقعة منعته من إكمال طلبك. يرجى المحاولة لاحقًا، نحن نعمل على حل المشكلة.",
"response.522": "نعتذر، انتهت مهلة الاتصال بالخادم ولم يتمكن من الرد في الوقت المناسب. قد يكون السبب ضعف الشبكة أو تعذر الوصول المؤقت. يرجى المحاولة لاحقًا.",
"response.524": "نعتذر، انتهت مهلة الخادم أثناء انتظار الرد، ربما بسبب بطء الاستجابة. يرجى المحاولة لاحقًا.",
"response.AgentRuntimeError": "حدث خطأ أثناء تنفيذ نموذج Lobe. يرجى التحقق أو إعادة المحاولة بناءً على المعلومات التالية.",
"response.ComfyUIBizError": "حدث خطأ أثناء طلب خدمة ComfyUI. يرجى التحقق من المعلومات أدناه أو إعادة المحاولة.",
"response.ComfyUIEmptyResult": "لم يتم إنشاء أي صورة بواسطة ComfyUI. يرجى التحقق من إعدادات النموذج أو إعادة المحاولة.",
"response.ComfyUIModelError": "فشل تحميل نموذج ComfyUI. يرجى التأكد من وجود ملف النموذج.",
"response.ComfyUIServiceUnavailable": "فشل الاتصال بخدمة ComfyUI. يرجى التأكد من أنها تعمل بشكل صحيح وأن عنوان الخدمة مضبوط بشكل صحيح.",
"response.ComfyUIUploadFailed": "فشل تحميل الصورة إلى ComfyUI. يرجى التحقق من الاتصال بالخادم أو إعادة المحاولة.",
"response.ComfyUIWorkflowError": "فشل تنفيذ سير عمل ComfyUI. يرجى التحقق من إعدادات سير العمل.",
"response.ConnectionCheckFailed": "الطلب أعاد نتيجة فارغة. يرجى التحقق من أن عنوان وكيل API لا ينتهي بـ `/v1`.",
"response.CreateMessageError": "عذرًا، لم يتم إرسال الرسالة بنجاح. يرجى نسخ المحتوى والمحاولة مرة أخرى. لن يتم الاحتفاظ بهذه الرسالة بعد تحديث الصفحة.",
"response.ExceededContextWindow": "يتجاوز محتوى الطلب الحالي الحد الأقصى الذي يمكن للنموذج معالجته. يرجى تقليل المحتوى والمحاولة مجددًا.",
"response.FreePlanLimit": "أنت تستخدم الخطة المجانية حاليًا ولا يمكنك استخدام هذه الميزة. يرجى الترقية إلى خطة مدفوعة للمتابعة.",
"response.GoogleAIBlockReason.BLOCKLIST": "يحتوي المحتوى الخاص بك على مصطلحات محظورة. يرجى مراجعة مدخلاتك وتعديلها ثم المحاولة مجددًا.",
"response.GoogleAIBlockReason.IMAGE_SAFETY": "تم حظر الصورة المُولدة لأسباب تتعلق بالسلامة. يرجى تعديل طلب الصورة.",
"response.GoogleAIBlockReason.LANGUAGE": "اللغة المستخدمة غير مدعومة. يرجى المحاولة باللغة الإنجليزية أو بلغة مدعومة أخرى.",
"response.GoogleAIBlockReason.OTHER": "تم حظر المحتوى لسبب غير معروف. يرجى إعادة صياغة الطلب والمحاولة مجددًا.",
"response.GoogleAIBlockReason.PROHIBITED_CONTENT": "قد يحتوي طلبك على محتوى محظور. يرجى تعديل الطلب ليتوافق مع إرشادات الاستخدام.",
"response.GoogleAIBlockReason.RECITATION": "تم حظر المحتوى بسبب مخاوف تتعلق بحقوق النشر. يرجى استخدام محتوى أصلي أو إعادة صياغة الطلب.",
"response.GoogleAIBlockReason.SAFETY": "تم حظر المحتوى لأسباب تتعلق بسياسة السلامة. يرجى تعديل الطلب لتجنب المحتوى الضار أو غير المناسب.",
"response.GoogleAIBlockReason.SPII": "قد يحتوي المحتوى الخاص بك على معلومات تعريف شخصية حساسة. لحماية الخصوصية، يرجى إزالة التفاصيل الحساسة والمحاولة مجددًا.",
"response.GoogleAIBlockReason.default": "تم حظر المحتوى: {{blockReason}}. يرجى تعديل الطلب والمحاولة مجددًا.",
"response.InsufficientQuota": "عذرًا، تم استهلاك الحصة المخصصة لهذا المفتاح. يرجى التحقق من رصيد حسابك أو زيادة الحصة والمحاولة مجددًا.",
"response.InvalidAccessCode": "رمز الوصول غير صالح أو فارغ. يرجى إدخال رمز الوصول الصحيح أو إضافة مفتاح API مخصص.",
"response.InvalidBedrockCredentials": "فشل التوثيق مع Bedrock. يرجى التحقق من AccessKeyId/SecretAccessKey والمحاولة مجددًا.",
"response.InvalidClerkUser": "عذرًا، لم تقم بتسجيل الدخول حاليًا. يرجى تسجيل الدخول أو إنشاء حساب للمتابعة.",
"response.InvalidComfyUIArgs": "إعدادات ComfyUI غير صالحة. يرجى التحقق من الإعدادات والمحاولة مجددًا.",
"response.InvalidGithubToken": "رمز GitHub الشخصي غير صحيح أو فارغ. يرجى التحقق من الرمز والمحاولة مجددًا.",
"response.InvalidOllamaArgs": "إعدادات Ollama غير صالحة، يرجى التحقق منها والمحاولة مجددًا.",
"response.InvalidProviderAPIKey": "مفتاح API الخاص بـ {{provider}} غير صحيح أو فارغ، يرجى التحقق منه والمحاولة مجددًا.",
"response.InvalidVertexCredentials": "فشل التوثيق مع Vertex. يرجى التحقق من بيانات الاعتماد والمحاولة مجددًا.",
"response.LocationNotSupportError": "نعتذر، لا يدعم موقعك الحالي هذه الخدمة. قد يكون ذلك بسبب قيود إقليمية أو عدم توفر الخدمة. يرجى التأكد من دعم الموقع الحالي أو المحاولة من موقع مختلف.",
"response.ModelNotFound": "عذرًا، لم يتم العثور على النموذج المطلوب. قد لا يكون موجودًا أو ليس لديك صلاحية الوصول. يرجى المحاولة بعد تغيير مفتاح API أو تعديل الصلاحيات.",
"response.NoOpenAIAPIKey": "مفتاح OpenAI API فارغ، يرجى إضافة مفتاح API مخصص.",
"response.OllamaBizError": "حدث خطأ أثناء طلب خدمة Ollama، يرجى التحقق أو إعادة المحاولة بناءً على المعلومات التالية.",
"response.OllamaServiceUnavailable": "خدمة Ollama غير متوفرة. يرجى التحقق من تشغيلها بشكل صحيح أو إعدادات التكوين.",
"response.PermissionDenied": "عذرًا، لا تملك صلاحية الوصول إلى هذه الخدمة. يرجى التحقق من صلاحيات المفتاح.",
"response.PluginApiNotFound": "عذرًا، لم يتم العثور على API في ملف تعريف المهارة. يرجى التحقق من تطابق طريقة الطلب مع API المعرفة.",
"response.PluginApiParamsError": "عذرًا، فشل التحقق من معلمات الطلب للمهارة. يرجى التحقق من تطابق المعلمات مع وصف API.",
"response.PluginFailToTransformArguments": "عذرًا، فشلت المهارة في تحليل المعلمات. يرجى إعادة إنشاء رسالة الوكيل أو استخدام نموذج AI أقوى يدعم استدعاء الأدوات.",
"response.PluginGatewayError": "عذرًا، حدث خطأ في بوابة المهارة. يرجى التحقق من إعدادات البوابة.",
"response.PluginManifestInvalid": "عذرًا، فشل التحقق من ملف تعريف المهارة. يرجى التحقق من صحة التنسيق.",
"response.PluginManifestNotFound": "عذرًا، لم يتم العثور على ملف تعريف المهارة (manifest.json). يرجى التحقق من العنوان.",
"response.PluginMarketIndexInvalid": "عذرًا، فشل التحقق من فهرس المهارة. يرجى التحقق من تنسيق الملف.",
"response.PluginMarketIndexNotFound": "عذرًا، لم يتم العثور على فهرس المهارة. يرجى التحقق من العنوان.",
"response.PluginMetaInvalid": "عذرًا، فشل التحقق من بيانات المهارة. يرجى التحقق من التنسيق.",
"response.PluginMetaNotFound": "عذرًا، لم يتم العثور على المهارة في الفهرس. يرجى التحقق من إعدادات المهارة.",
"response.PluginOpenApiInitError": "عذرًا، فشل تهيئة عميل OpenAPI. يرجى التحقق من إعدادات OpenAPI.",
"response.PluginServerError": "أعاد خادم المهارة خطأ. يرجى التحقق من ملف تعريف المهارة أو إعدادات الخادم.",
"response.PluginSettingsInvalid": تطلب هذه المهارة إعدادًا صحيحًا قبل الاستخدام. يرجى التحقق من الإعدادات.",
"response.ProviderBizError": "حدث خطأ أثناء طلب خدمة {{provider}}، يرجى التحقق أو إعادة المحاولة.",
"response.QuotaLimitReached": "عذرًا، تم الوصول إلى الحد الأقصى لاستخدام الرموز أو عدد الطلبات لهذا المفتاح. يرجى زيادة الحصة أو المحاولة لاحقًا.",
"response.ServerAgentRuntimeError": "عذرًا، خدمة الوكيل غير متوفرة حاليًا. يرجى المحاولة لاحقًا أو التواصل معنا عبر البريد الإلكتروني.",
"response.StreamChunkError": "حدث خطأ أثناء تحليل جزء الرسالة من الطلب المتدفق. يرجى التحقق من توافق واجهة API أو التواصل مع مزود الخدمة.",
"response.SubscriptionKeyMismatch": "نعتذر عن الإزعاج. بسبب خلل مؤقت في النظام، اشتراكك غير نشط حاليًا. يرجى النقر على الزر أدناه لاستعادته أو التواصل معنا عبر البريد الإلكتروني.",
"response.SubscriptionPlanLimit": "تم استنفاد نقاط اشتراكك، ولا يمكنك استخدام هذه الميزة. يرجى الترقية إلى خطة أعلى أو إعداد API مخصص.",
"response.SubscriptionPlanLimitUltimate": "تم استنفاد نقاط اشتراكك، ولا يمكنك استخدام هذه الميزة. يرجى شحن الرصيد أو إعداد API مخصص.",
"response.SystemTimeNotMatchError": "عذرًا، لا يتطابق وقت نظامك مع الخادم. يرجى التحقق من الوقت والمحاولة مجددًا.",
"response.UnknownChatFetchError": "عذرًا، حدث خطأ غير معروف في الطلب. يرجى التحقق من المعلومات أدناه أو إعادة المحاولة.",
"stt.responseError": "فشل طلب الخدمة، يرجى التحقق من الإعدادات أو إعادة المحاولة.",
"supervisor.decisionFailed": "المضيف الجماعي غير قادر على العمل. يرجى التحقق من إعدادات المضيف والتأكد من صحة النموذج ومفتاح API ونقطة النهاية.",
"testConnectionFailed": "فشل اختبار الاتصال: {{error}}",
"tts.responseError": "فشل طلب الخدمة، يرجى التحقق من الإعدادات أو إعادة المحاولة",
"tts.responseError": "فشل طلب الخدمة، يرجى التحقق من الإعدادات أو إعادة المحاولة.",
"unlock.addProxyUrl": "إضافة عنوان وكيل OpenAI (اختياري)",
"unlock.apiKey.description": "يمكنك بدء الجلسة عن طريق إدخال مفتاح API {{name}} الخاص بك",
"unlock.apiKey.imageGenerationDescription": "أدخل مفتاح API الخاص بـ {{name}} للبدء في التوليد",
"unlock.apiKey.title": "استخدام مفتاح API {{name}} المخصص",
"unlock.apiKey.description": "أدخل مفتاح API الخاص بـ {{name}} لبدء الجلسة",
"unlock.apiKey.imageGenerationDescription": "أدخل مفتاح API الخاص بـ {{name}} لبدء التوليد",
"unlock.apiKey.title": "استخدام مفتاح API مخصص لـ {{name}}",
"unlock.closeMessage": "إغلاق الرسالة",
"unlock.comfyui.description": "يرجى إدخال معلومات المصادقة الصحيحة لـ {{name}} للبدء في إنشاء الصور",
"unlock.comfyui.modifyBaseUrl": "تعديل عنوان خدمة Comfy UI",
"unlock.comfyui.title": أكيد معلومات المصادقة الخاصة بـ {{name}}",
"unlock.comfyui.description": "أدخل بيانات اعتماد {{name}} الصالحة لبدء توليد الصور.",
"unlock.comfyui.modifyBaseUrl": "تعديل عنوان خدمة ComfyUI",
"unlock.comfyui.title": حقق من بيانات اعتماد {{name}}",
"unlock.confirm": "تأكيد وإعادة المحاولة",
"unlock.goToSettings": "الانتقال إلى الإعدادات",
"unlock.oauth.description": "فتح المسؤول توثيق تسجيل الدخول الموحد، انقر فوق الزر أدناه لتسجيل الدخول وفتح التطبيق",
"unlock.goToSettings": "الذهاب إلى الإعدادات",
"unlock.oauth.description": "قام المسؤول بتمكين تسجيل الدخول الموحد. انقر على الزر أدناه لتسجيل الدخول وفتح التطبيق.",
"unlock.oauth.success": "تم تسجيل الدخول بنجاح",
"unlock.oauth.title": "تسجيل الدخول إلى الحساب",
"unlock.oauth.welcome": "مرحبا بك!",
"unlock.password.description": "قام المسؤول بتشفير التطبيق، قم بإدخال كلمة مرور التطبيق لفتح التطبيق. يتعين إدخال كلمة المرور مرة واحدة فقط",
"unlock.password.placeholder": "الرجاء إدخال كلمة المرور",
"unlock.password.title": "إدخال كلمة المرور لفتح التطبيق",
"unlock.tabs.apiKey": "مفتاح واجهة برمجة التطبيقات المخصص",
"unlock.oauth.title": "تسجيل الدخول إلى حسابك",
"unlock.oauth.welcome": "مرحبًا بك!",
"unlock.password.description": "تم تفعيل تشفير التطبيق من قبل المسؤول. أدخل كلمة مرور التطبيق لفتحه. لا حاجة لإدخالها مرة أخرى.",
"unlock.password.placeholder": "يرجى إدخال كلمة المرور",
"unlock.password.title": "أدخل كلمة المرور لفتح التطبيق",
"unlock.tabs.apiKey": "مفتاح API مخصص",
"unlock.tabs.password": "كلمة المرور",
"upload.desc": "التفاصيل: {{detail}}",
"upload.fileOnlySupportInServerMode": "وضع النشر الحالي لا يدعم تحميل ملفات غير الصور. إذا كنت بحاجة إلى تحميل تنسيق {{ext}}، يرجى التبديل إلى نشر قاعدة البيانات على الخادم أو استخدام خدمة {{cloud}}.",
"upload.networkError": "يرجى التأكد من أن اتصال الشبكة لديك يعمل بشكل صحيح، والتحقق من إعدادات تكوين خدمة تخزين الملفات عبر النطاق.",
"upload.title": "فشل تحميل الملف، يرجى التحقق من الاتصال بالشبكة أو المحاولة لاحقًا",
"upload.fileOnlySupportInServerMode": "وضع النشر الحالي لا يدعم تحميل الملفات غير الصورية. لتحميل ملفات بصيغة {{ext}}، يرجى التبديل إلى وضع قاعدة بيانات الخادم أو استخدام خدمة {{cloud}}.",
"upload.networkError": "يرجى التحقق من اتصال الشبكة والتأكد من صحة إعدادات CORS لخدمة تخزين الملفات.",
"upload.title": "فشل تحميل الملف. يرجى التحقق من الاتصال أو المحاولة لاحقًا.",
"upload.unknownError": "سبب الخطأ: {{reason}}",
"upload.uploadFailed": "فشل تحميل الملف"
"upload.uploadFailed": "فشل تحميل الملف."
}
+91 -85
View File
@@ -1,128 +1,134 @@
{
"addFolder": "إنشاء مجلد",
"addLibrary": "إضافة",
"addPage": "إنشاء مستند",
"detail.basic.createdAt": اريخ الإنشاء",
"addPage": "إنشاء صفحة",
"detail.basic.createdAt": "وقت الإنشاء",
"detail.basic.filename": "اسم الملف",
"detail.basic.size": "حجم الملف",
"detail.basic.title": "معلومات أساسية",
"detail.basic.type": "الصيغة",
"detail.basic.updatedAt": اريخ التحديث",
"detail.basic.type": "التنسيق",
"detail.basic.updatedAt": "وقت التحديث",
"detail.data.chunkCount": "عدد الأجزاء",
"detail.data.embedding.default": "لم يتم تحويله إلى متجهات بعد",
"detail.data.embedding.default": "غير مضمّن",
"detail.data.embedding.error": "فشل",
"detail.data.embedding.pending": "في انتظار البدء",
"detail.data.embedding.processing": "جارٍ المعالجة",
"detail.data.embedding.pending": "بانتظار البدء",
"detail.data.embedding.processing": "قيد المعالجة",
"detail.data.embedding.success": "اكتمل",
"detail.data.embeddingStatus": "تحويل إلى متجهات",
"empty": ا توجد ملفات/مجلدات تم تحميلها بعد",
"header.actions.builtInBlockList.filtered": "تم تصفية {{ignored}} ملفًا من أصل {{total}} ملف",
"detail.data.embeddingStatus": "التضمين",
"empty": م يتم تحميل أي ملفات أو مجلدات بعد.",
"header.actions.builtInBlockList.filtered": "{{ignored}} ملف تم تصفيته (من أصل {{total}})",
"header.actions.connect": "اتصال...",
"header.actions.gitignore.apply": "تطبيق القواعد",
"header.actions.gitignore.cancel": "تجاهل القواعد",
"header.actions.gitignore.content": "تم اكتشاف ملف .gitignore (عدد {{count}} من الملفات)، هل ترغب في تطبيق قواعد التجاهل؟",
"header.actions.gitignore.filtered": "{{ignored}} ملفًا تم تجاهله من أصل {{total}} ملفًا",
"header.actions.gitignore.title": "تم اكتشاف .gitignore",
"header.actions.newFolder": "إنشاء مجلد جديد",
"header.actions.newPage": "مستند جديد",
"header.actions.notion.error": "فشل في استيراد ملف Notion",
"header.actions.gitignore.content": "تم اكتشاف ملف .gitignore ({{count}} ملفًا إجمالاً). هل ترغب في تطبيق قواعد التجاهل؟",
"header.actions.gitignore.filtered": "{{ignored}} ملف تم تجاهله (من أصل {{total}})",
"header.actions.gitignore.title": "تم اكتشاف .gitignore",
"header.actions.newFolder": "مجلد جديد",
"header.actions.newPage": "صفحة جديدة",
"header.actions.notion.error": "فشل في استيراد ملفات Notion",
"header.actions.notion.foundFiles": "تم العثور على {{count}} ملف",
"header.actions.notion.importing": "جارٍ استيراد ملفات Notion...",
"header.actions.notion.noMarkdownFiles": "لم يتم العثور على ملفات Markdown في ملف ZIP",
"header.actions.notion.partial": "تم استيراد {{success}} ملفًا بنجاح، وفشل {{failed}} ملفًا",
"header.actions.notion.success": "تم استيراد {{count}} ملفًا بنجاح",
"header.actions.notionGuide.cancel": "إلغاء الاستيراد الآن",
"header.actions.notionGuide.desc": "يرجى أولاً تصدير ملفات Markdown (بصيغة ZIP) من Notion، ثم النقر على متابعة لاختيار ملف الضغط واستيراد جميع الصفحات.",
"header.actions.notionGuide.ok": "اختر ملف ZIP من Notion",
"header.actions.notionGuide.title": "استيراد محتوى Notion",
"header.actions.uploadFile": "رفع ملف",
"header.actions.uploadFolder": "رفع مجلد",
"header.newPageButton": "إنشاء مستند جديد",
"header.uploadButton": "رفع",
"header.actions.notion.importing": "جارٍ استيراد محتوى Notion...",
"header.actions.notion.noMarkdownFiles": "لم يتم العثور على ملفات Markdown في الأرشيف المضغوط",
"header.actions.notion.partial": "تم استيراد {{success}} ملف بنجاح، وفشل {{failed}}",
"header.actions.notion.success": "تم استيراد {{count}} ملف بنجاح",
"header.actions.notionGuide.cancel": "ليس الآن",
"header.actions.notionGuide.desc": "أولاً، قم بتصدير المحتوى من Notion كملف Markdown (ZIP). ثم انقر على متابعة لتحديد ملف ZIP واستيراد جميع الصفحات.",
"header.actions.notionGuide.ok": "تحديد ملف ZIP من Notion",
"header.actions.notionGuide.title": "الاستيراد من Notion",
"header.actions.uploadFile": "تحميل ملف",
"header.actions.uploadFolder": "تحميل مجلد",
"header.newPageButton": "صفحة جديدة",
"header.uploadButton": "تحميل",
"home.getStarted": "ابدأ الآن",
"home.greeting": "ابدأ",
"home.greeting": "ابدأ الآن",
"home.quickActions": "إجراءات سريعة",
"home.recentFiles": "الملفات الأخيرة",
"home.recentPages": "الصفحات الأخيرة",
"home.subtitle": "مرحبًا بك في مركز الموارد، ابدأ من هنا لإدارة مستنداتك وملفاتك.",
"home.uploadEntries.files.title": "رفع ملفات",
"home.uploadEntries.folder.title": "رفع مجلد",
"home.recentFiles": "الملفات الحديثة",
"home.recentPages": "الصفحات الحديثة",
"home.uploadEntries.files.title": "تحميل ملفات",
"home.uploadEntries.folder.title": "تحميل مجلد",
"home.uploadEntries.library.title": "إنشاء مكتبة جديدة",
"home.uploadEntries.newPage.title": "إنشاء مستند جديد",
"library.list.confirmRemoveLibrary": "سيتم حذف هذه المكتبة، لكن الملفات بداخلها لن تُحذف، بل سيتم نقلها إلى جميع الملفات. لا يمكن استعادة المكتبة بعد حذفها، يرجى الحذر.",
"library.list.empty": "انقر <1>+</1> لبدء إنشاء مكتبة",
"library.new": "إنشاء مكتبة جديدة",
"home.uploadEntries.newPage.title": "صفحة جديدة",
"library.list.confirmRemoveLibrary": "أنت على وشك حذف هذه المكتبة. لن يتم حذف الملفات الموجودة بداخلها، بل سيتم نقلها إلى جميع الملفات. لا يمكن التراجع عن هذا الإجراء، لذا يرجى المتابعة بحذر.",
"library.list.empty": "انقر <1>+</1> لإنشاء مكتبة جديدة",
"library.new": "مكتبة جديدة",
"library.title": "المكتبة",
"loadMore": "تحميل المزيد",
"menu.allFiles": "جميع الملفات",
"menu.allPages": "جميع المستندات",
"networkError": "فشل في تحميل المكتبة، يرجى التحقق من اتصال الشبكة والمحاولة مرة أخرى",
"notSupportGuide.desc": "الوضع الحالي للنشر هو وضع قاعدة بيانات العميل، ولا يمكن استخدام وظيفة إدارة الملفات. يرجى التبديل إلى <1>وضع نشر قاعدة بيانات الخادم</1>، أو استخدام <3>LobeChat Cloud</3> مباشرة.",
"notSupportGuide.features.allKind.desc": "يدعم أنواع الملفات الشائعة، بما في ذلك تنسيقات المستندات الشائعة مثل Word وPPT وExcel وPDF وTXT، بالإضافة إلى ملفات الشيفرة الشائعة مثل JS وPython.",
"notSupportGuide.features.allKind.title": "تحليل أنواع متعددة من الملفات",
"notSupportGuide.features.embeddings.desc": "استخدام نماذج متجهات عالية الأداء لتحويل النصوص إلى متجهات، مما يتيح البحث الدلالي في محتوى الملفات.",
"notSupportGuide.features.embeddings.title": "تحويل دلالي إلى متجهات",
"notSupportGuide.features.libraries.desc": "يدعم إنشاء مكتبات ويسمح بإضافة أنواع مختلفة من الملفات لبناء مواردك المتخصصة",
"menu.allPages": "جميع الصفحات",
"networkError": "فشل في استرداد المكتبات. يرجى التحقق من اتصال الشبكة والمحاولة مرة أخرى.",
"notSupportGuide.desc": "وضع النشر الحالي لا يدعم إدارة الملفات. قم بالتبديل إلى <1>وضع قاعدة بيانات الخادم</1>، أو استخدم <3>LobeHub Cloud</3>.",
"notSupportGuide.features.allKind.desc": "يدعم أنواع الملفات الشائعة، بما في ذلك تنسيقات الصفحات مثل Word وPPT وExcel وPDF وTXT، بالإضافة إلى ملفات البرمجة مثل JS وPython.",
"notSupportGuide.features.allKind.title": "تحليل أنواع ملفات متعددة",
"notSupportGuide.features.embeddings.desc": "يستخدم نماذج متجهات عالية الأداء لتحويل أجزاء النص إلى متجهات، مما يتيح البحث الدلالي في محتوى الملفات.",
"notSupportGuide.features.embeddings.title": "الدلالات المتجهة",
"notSupportGuide.features.libraries.desc": "أنشئ مكتبات وأضف ملفات لبناء مكتبتك الخاصة.",
"notSupportGuide.features.libraries.title": "المكتبة",
"notSupportGuide.title": "الوضع الحالي للنشر لا يدعم إدارة الملفات",
"notSupportGuide.title": "وضع النشر الحالي لا يدعم إدارة الملفات",
"pageEditor.addIcon": "إضافة أيقونة",
"pageEditor.autoSaveMessage": "يتم حفظ المستند تلقائيًا، لا حاجة للحفظ اليدوي",
"pageEditor.autoSaveMessage": "يتم حفظ صفحتك تلقائيًا. لا حاجة للحفظ يدويًا.",
"pageEditor.chooseIcon": "اختر أيقونة",
"pageEditor.deleteConfirm.content": "سيتم حذف هذا المستند، ولا يمكن استعادته بعد الحذف. يرجى توخي الحذر.",
"pageEditor.deleteConfirm.title": "حذف المستند",
"pageEditor.deleteError": "فشل في حذف المستند",
"pageEditor.deleteSuccess": "تم حذف المستند بنجاح",
"pageEditor.deleteConfirm.content": "سيتم حذف هذه الصفحة ولا يمكن استعادتها. يرجى المتابعة بحذر.",
"pageEditor.deleteConfirm.title": "حذف الصفحة",
"pageEditor.deleteError": "فشل في حذف الصفحة",
"pageEditor.deleteSuccess": "تم حذف الصفحة بنجاح",
"pageEditor.duplicateError": "فشل في تكرار الصفحة",
"pageEditor.duplicateSuccess": "تم تكرار الصفحة بنجاح",
"pageEditor.editedAt": "آخر تعديل في {{time}}",
"pageEditor.editedBy": "آخر من عدّل: {{name}}",
"pageEditor.editorPlaceholder": "أدخل محتوى المستند، اضغط / لفتح قائمة الأوامر",
"pageEditor.empty.createNewDocument": "إنشاء مستند جديد",
"pageEditor.empty.title": "اختر مستندًا للبدء",
"pageEditor.empty.uploadMarkdown": "رفع ملف Markdown",
"pageEditor.editedBy": "آخر تعديل بواسطة {{name}}",
"pageEditor.editorPlaceholder": "ابدأ بكتابة صفحتك. اضغط / لفتح قائمة الأوامر",
"pageEditor.empty.createNewDocument": "إنشاء صفحة جديدة",
"pageEditor.empty.importNotion": "الاستيراد من Notion",
"pageEditor.empty.title": "اختر صفحة للبدء",
"pageEditor.empty.uploadFiles": "تحميل ملفات",
"pageEditor.exportError": "فشل في تصدير الصفحة",
"pageEditor.exportSuccess": "تم تصدير الصفحة بنجاح",
"pageEditor.linkCopied": "تم نسخ الرابط",
"pageEditor.menu.copyLink": "نسخ الرابط",
"pageEditor.menu.exportDocument": "تصدير المستند",
"pageEditor.menu.importDocument": "استيراد مستند",
"pageEditor.menu.pin": "تثبيت المستند",
"pageEditor.menu.export": "تصدير",
"pageEditor.menu.export.markdown": "Markdown",
"pageEditor.menu.exportDocument": "تصدير الصفحة",
"pageEditor.menu.importDocument": "استيراد صفحة",
"pageEditor.menu.pin": "تثبيت الصفحة",
"pageEditor.saving": "جارٍ الحفظ...",
"pageEditor.titlePlaceholder": "بدون عنوان",
"pageEditor.wordCount": "{{wordCount}} كلمة",
"pageList.copyContent": "نسخ المحتوى الكامل",
"pageList.duplicate": "إنشاء نسخة",
"pageList.empty": "لا توجد مستندات حاليًا، انقر على الزر أعلاه لإنشاء أول مستند لك",
"pageList.copyContent": "نسخ النص الكامل",
"pageList.duplicate": "تكرار",
"pageList.empty": "لا توجد صفحات بعد. انقر على الزر أعلاه لإنشاء أول صفحة.",
"pageList.filter.all": "الكل",
"pageList.filter.onlyInPages": قط في المستندات",
"pageList.noResults": "لم يتم العثور على مستندات مطابقة",
"pageList.pageCount": "عدد المستندات: {{count}}",
"pageList.filter.onlyInPages": ي الصفحات فقط",
"pageList.noResults": "لم يتم العثور على صفحات مطابقة",
"pageList.pageCount": "إجمالي {{count}} صفحة",
"pageList.pageSizeItem": "{{count}} عنصر",
"pageList.selectNote": "اختر مستندًا للبدء في التحرير",
"pageList.title": "المستندات",
"pageList.title": "الصفحات",
"pageList.untitled": "بدون عنوان",
"portal.openInPageEditor": "تحرير في المستند",
"preview.downloadFile": حميل الملف",
"preview.unsupportedFileAndContact": "هذا التنسيق من الملفات غير مدعوم للمعاينة عبر الإنترنت، إذا كان لديك طلب للمعاينة، فلا تتردد في <1>إبلاغنا</1>",
"searchFilePlaceholder": "بحث عن ملف",
"searchPagePlaceholder": "ابحث في المستندات",
"portal.openInPageEditor": "تحرير في الصفحة",
"preview.downloadFile": نزيل الملف",
"preview.unsupportedFileAndContact": "تنسيق هذا الملف غير مدعوم حاليًا للمعاينة عبر الإنترنت. إذا كان لديك طلب للمعاينة، لا تتردد في <1>الاتصال بنا</1>.",
"searchFilePlaceholder": "البحث في الملفات",
"searchPagePlaceholder": "البحث في الصفحات",
"tab.all": "الكل",
"tab.audios": "الصوتيات",
"tab.documents": "المستندات",
"tab.home": "الرئيسية",
"tab.images": "الصور",
"tab.moreTypes": "أنواع أخرى",
"tab.pages": "المستندات",
"tab.pages": "الصفحات",
"tab.videos": "الفيديوهات",
"tab.websites": "المواقع",
"title": "الموارد",
"toggleLeftPanel": "إظهار/إخفاء اللوحة الجانبية اليسرى",
"toggleLeftPanel": "إظهار/إخفاء اللوحة الجانبية",
"uploadDock.body.collapse": "طي",
"uploadDock.body.item.done": "تم الرفع",
"uploadDock.body.item.error": "فشل الرفع، يرجى المحاولة مرة أخرى",
"uploadDock.body.item.pending": "جاهز للرفع...",
"uploadDock.body.item.done": "تم التحميل",
"uploadDock.body.item.error": "فشل في التحميل، يرجى المحاولة مرة أخرى",
"uploadDock.body.item.pending": "جارٍ التحضير للتحميل...",
"uploadDock.body.item.processing": "جارٍ معالجة الملف...",
"uploadDock.body.item.restTime": "الوقت المتبقي {{time}}",
"uploadDock.fileQueueInfo": "يتم حاليًا تحميل {{count}} ملفًا، وسيتم وضع {{remaining}} ملفًا في قائمة الانتظار للتحميل",
"uploadDock.body.item.restTime": "المتبقي {{time}}",
"uploadDock.fileQueueInfo": "يتم تحميل أول {{count}} ملف، {{remaining}} في الانتظار",
"uploadDock.totalCount": "إجمالي {{count}} عنصر",
"uploadDock.uploadStatus.error": "حدث خطأ أثناء الرفع",
"uploadDock.uploadStatus.pending": "في انتظار الرفع",
"uploadDock.uploadStatus.processing": "جارٍ الرفع",
"uploadDock.uploadStatus.success": "اكتمل الرفع",
"uploadDock.uploadStatus.uploading": "جارٍ الرفع"
"uploadDock.uploadStatus.error": "خطأ في التحميل",
"uploadDock.uploadStatus.pending": "بانتظار التحميل",
"uploadDock.uploadStatus.processing": "جارٍ التحميل",
"uploadDock.uploadStatus.success": "تم التحميل بنجاح",
"uploadDock.uploadStatus.uploading": "جارٍ التحميل"
}
+9 -9
View File
@@ -1,14 +1,14 @@
{
"agentSelection.empty": "لا يوجد مساعدون متاحون حاليًا",
"agentSelection.noAvailable": "لا يوجد مساعدون يمكن إضافتهم في الوقت الحالي",
"agentSelection.noSelected": "لم يتم اختيار أي مساعد بعد",
"agentSelection.search": "لم يتم العثور على مساعد مطابق",
"project.create": "إنشاء مشروع جديد",
"project.deleteConfirm": "سيتم حذف هذا المشروع، ولن يكون بالإمكان استعادته بعد الحذف. يرجى تأكيد الإجراء.",
"starter.createAgent": "إنشاء مساعد",
"agentSelection.empty": "لا يوجد وكلاء متاحون",
"agentSelection.noAvailable": "لا يمكن إضافة أي وكلاء في الوقت الحالي",
"agentSelection.noSelected": "لم يتم اختيار أي وكلاء",
"agentSelection.search": "لم يتم العثور على وكلاء مطابقين",
"project.create": "مشروع جديد",
"project.deleteConfirm": "سيتم حذف هذا المشروع ولا يمكن استعادته. يرجى التأكيد للمتابعة.",
"starter.createAgent": "إنشاء وكيل",
"starter.createGroup": "إنشاء مجموعة",
"starter.deepResearch": "بحث معمق",
"starter.developing": يد التطوير",
"starter.image": "رسم",
"starter.developing": ريبًا",
"starter.image": "صورة",
"starter.write": "كتابة"
}
+25 -25
View File
@@ -1,42 +1,42 @@
{
"addUserMessage.desc": "إضافة المحتوى الحالي كرسالة مستخدم دون تفعيل التوليد",
"addUserMessage.desc": "أضف الإدخال الحالي كرسالة مستخدم دون بدء التوليد",
"addUserMessage.title": "إضافة رسالة مستخدم",
"clearCurrentMessages.desc": "مسح الرسائل والملفات المرفوعة في المحادثة الحالية",
"clearCurrentMessages.desc": "مسح الرسائل والملفات المرفوعة من المحادثة الحالية",
"clearCurrentMessages.title": "مسح رسائل المحادثة",
"commandPalette.desc": "افتح لوحة الأوامر العامة للوصول السريع إلى الميزات",
"commandPalette.title": "لوحة الأوامر",
"deleteAndRegenerateMessage.desc": "حذف الرسالة الأخيرة وإعادة إنشائها",
"deleteAndRegenerateMessage.title": "حذف وإعادة إنشاء",
"deleteAndRegenerateMessage.desc": "حذف الرسالة الأخيرة وإعادة توليدها",
"deleteAndRegenerateMessage.title": "حذف وإعادة توليد",
"deleteLastMessage.desc": "حذف الرسالة الأخيرة",
"deleteLastMessage.title": "حذف الرسالة الأخيرة",
"desktop.openSettings.desc": "افتح صفحة إعدادات التطبيق",
"desktop.openSettings.title": "إعدادات التطبيق",
"desktop.showApp.desc": "مفتاح اختصار عام لإظهار أو إخفاء النافذة الرئيسية",
"desktop.showApp.desc": "تبديل ظهور النافذة الرئيسية باستخدام اختصار عام",
"desktop.showApp.title": "إظهار/إخفاء النافذة الرئيسية",
"editMessage.desc": "الدخول إلى وضع التحرير عن طريق الضغط على مفتاح Alt والنقر المزدوج على الرسالة",
"editMessage.title": حرير الرسالة",
"navigateToChat.desc": "التبديل إلى علامة تبويب المحادثة والدخول إلى Lobe AI",
"navigateToChat.title": "التبديل إلى المحادثة الافتراضية",
"editMessage.desc": "ادخل وضع التعديل بالضغط على Alt والنقر المزدوج على الرسالة",
"editMessage.title": عديل الرسالة",
"navigateToChat.desc": "الانتقال إلى تبويب الدردشة والدخول إلى Lobe AI",
"navigateToChat.title": "الانتقال إلى الدردشة الافتراضية",
"openChatSettings.desc": "عرض وتعديل إعدادات المحادثة الحالية",
"openChatSettings.title": "فتح إعدادات المحادثة",
"openHotkeyHelper.desc": "عرض جميع تعليمات استخدام الاختصارات",
"openHotkeyHelper.title": "فتح مساعدة الاختصارات",
"regenerateMessage.desc": "إعادة توليد آخر رسالة",
"openHotkeyHelper.desc": "عرض تعليمات جميع اختصارات لوحة المفاتيح",
"openHotkeyHelper.title": "فتح تعليمات الاختصارات",
"regenerateMessage.desc": "إعادة توليد الرسالة الأخيرة",
"regenerateMessage.title": "إعادة توليد الرسالة",
"saveDocument.desc": "احفظ جميع التغييرات التي أُجريت على المستند الحالي فورًا",
"saveDocument.title": "حفظ المستند",
"saveDocument.desc": "حفظ جميع التغييرات على الصفحة الحالية فورًا",
"saveDocument.title": "حفظ الصفحة",
"saveTopic.desc": "حفظ الموضوع الحالي وفتح موضوع جديد",
"saveTopic.title": "فتح موضوع جديد",
"search.desc": "استدعاء مربع البحث الرئيسي في الصفحة الحالية",
"saveTopic.title": "بدء موضوع جديد",
"search.desc": "تفعيل مربع البحث الرئيسي في الصفحة الحالية",
"search.title": "بحث",
"showApp.desc": "استدعاء نافذة التطبيق الرئيسية بسرعة",
"showApp.title": "عرض النافذة الرئيسية",
"switchAgent.desc": "تبديل المساعد المثبت في الشريط الجانبي عن طريق الضغط على Ctrl مع الأرقام من 0 إلى 9",
"switchAgent.title": "تبديل المساعد بسرعة",
"toggleLeftPanel.desc": "إظهار أو إخفاء اللوحة الجانبية اليسرى",
"toggleLeftPanel.title": "إظهار/إخفاء اللوحة الجانبية اليسرى",
"toggleRightPanel.desc": "إظهار أو إخفاء اللوحة الجانبية اليمنى",
"toggleRightPanel.title": "إظهار/إخفاء اللوحة الجانبية اليمنى",
"toggleZenMode.desc": "في وضع التركيز، عرض المحادثة الحالية فقط، وإخفاء واجهة المستخدم الأخرى",
"showApp.desc": "فتح نافذة التطبيق الرئيسية بسرعة",
"showApp.title": "إظهار النافذة الرئيسية",
"switchAgent.desc": "التبديل بين الوكلاء المثبتين في الشريط الجانبي بالضغط على Ctrl مع الأرقام من 0 إلى 9",
"switchAgent.title": "تبديل سريع للوكلاء",
"toggleLeftPanel.desc": "إظهار أو إخفاء اللوحة اليسرى",
"toggleLeftPanel.title": "تبديل اللوحة اليسرى",
"toggleRightPanel.desc": "إظهار أو إخفاء اللوحة اليمنى",
"toggleRightPanel.title": "تبديل اللوحة اليمنى",
"toggleZenMode.desc": "في وضع التركيز، عرض المحادثة الحالية فقط وإخفاء عناصر الواجهة الأخرى",
"toggleZenMode.title": "تبديل وضع التركيز"
}
+28 -28
View File
@@ -1,19 +1,19 @@
{
"config.aspectRatio.label": "النسبة",
"config.aspectRatio.label": "نسبة العرض إلى الارتفاع",
"config.aspectRatio.lock": "قفل نسبة العرض إلى الارتفاع",
"config.aspectRatio.unlock": "إلغاء قفل نسبة العرض إلى الارتفاع",
"config.aspectRatio.unlock": "فتح نسبة العرض إلى الارتفاع",
"config.cfg.label": "شدة التوجيه",
"config.header.desc": "وصف بسيط، ابتكر فورًا",
"config.header.title": "الرسم",
"config.header.desc": "وصف موجز، أنشئ فورًا",
"config.header.title": "رسم",
"config.height.label": "الارتفاع",
"config.imageNum.label": "عدد الصور",
"config.imageUrl.label": "صورة مرجعية",
"config.imageUrls.label": "صور مرجعية",
"config.model.label": "النموذج",
"config.prompt.placeholder": "وصف المحتوى الذي ترغب في إنشائه",
"config.prompt.placeholder": "صف ما ترغب في إنشائه",
"config.quality.label": "جودة الصورة",
"config.quality.options.hd": "عالي الدقة",
"config.quality.options.standard": "عادي",
"config.quality.options.hd": "عالية الدقة",
"config.quality.options.standard": "قياسية",
"config.resolution.label": "الدقة",
"config.resolution.options.1K": "1K",
"config.resolution.options.2K": "2K",
@@ -21,42 +21,42 @@
"config.seed.label": "البذرة",
"config.seed.random": "بذرة عشوائية",
"config.size.label": "الحجم",
"config.steps.label": "عدد الخطوات",
"config.title": "الرسم بالذكاء الاصطناعي",
"config.steps.label": "الخطوات",
"config.title": "صورة بالذكاء الاصطناعي",
"config.width.label": "العرض",
"generation.actions.applySeed": "تطبيق البذرة",
"generation.actions.copyError": "نسخ رسالة الخطأ",
"generation.actions.copyPrompt": "نسخ العبارة التحفيزية",
"generation.actions.copyPrompt": "نسخ الوصف",
"generation.actions.copySeed": "نسخ البذرة",
"generation.actions.delete": "حذف",
"generation.actions.deleteBatch": "حذف الدفعة",
"generation.actions.download": "تنزيل",
"generation.actions.downloadFailed": "فشل تنزيل الصورة",
"generation.actions.downloadFailed": "فشل في تنزيل الصورة. يرجى التحقق من اتصال الشبكة أو إعدادات CORS لتخزين S3.",
"generation.actions.errorCopied": "تم نسخ رسالة الخطأ إلى الحافظة",
"generation.actions.errorCopyFailed": "فشل نسخ رسالة الخطأ",
"generation.actions.errorCopyFailed": "فشل في نسخ رسالة الخطأ",
"generation.actions.generate": "إنشاء",
"generation.actions.promptCopied": "تم نسخ النص التوجيهي إلى الحافظة",
"generation.actions.promptCopyFailed": "فشل نسخ النص التوجيهي",
"generation.actions.promptCopied": "تم نسخ الوصف إلى الحافظة",
"generation.actions.promptCopyFailed": "فشل في نسخ الوصف",
"generation.actions.reuseSettings": "إعادة استخدام الإعدادات",
"generation.actions.seedApplied": "تم تطبيق البذرة على الإعدادات",
"generation.actions.seedApplyFailed": "فشل في تطبيق البذرة",
"generation.actions.seedCopied": "تم نسخ البذرة إلى الحافظة",
"generation.actions.seedCopyFailed": "فشل نسخ البذرة",
"generation.actions.seedCopyFailed": "فشل في نسخ البذرة",
"generation.metadata.count": "{{count}} صورة",
"generation.status.failed": "فشل في الإنشاء",
"generation.status.generating": "جارٍ الإنشاء...",
"notSupportGuide.desc": "الوحدة الحالية تعمل بنمط قاعدة بيانات العميل، ولا تدعم ميزة إنشاء الصور بالذكاء الاصطناعي. يرجى التبديل إلى <1>نمط نشر قاعدة بيانات الخادم</1>، أو استخدام <3>سحابة LobeChat</3> مباشرةً",
"notSupportGuide.features.fileIntegration.desc": "تكامل عميق مع نظام إدارة الملفات، حيث تُحفظ الصور المُنشأة تلقائيًا في نظام الملفات، مع دعم الإدارة والتنظيم الموحد",
"notSupportGuide.features.fileIntegration.title": "تكامل نظام الملفات",
"notSupportGuide.features.llmAssisted.desc": "يجمع بين قدرات نماذج اللغة الكبيرة لتحسين وتوسيع النصوص التوجيهية بذكاء، مما يعزز جودة إنشاء الصور (قريبًا)",
"notSupportGuide.features.llmAssisted.title": "مساعدة نموذج اللغة الكبير",
"notSupportGuide.features.multiProviders.desc": "يدعم عدة مزودي خدمات رسم بالذكاء الاصطناعي، بما في ذلك OpenAI gpt-image-1، Google Imagen، FAL.ai وغيرها، لتوفير خيارات نماذج متنوعة",
"notSupportGuide.features.multiProviders.title": "دعم مزودين متعددين",
"notSupportGuide.title": "نمط النشر الحالي لا يدعم الرسم بالذكاء الاصطناعي",
"topic.createNew": "إنشاء موضوع جديد",
"topic.deleteConfirm": "تأكيد حذف الموضوع",
"topic.deleteConfirmDesc": "سيتم حذف هذا الموضوع نهائيًا ولن يمكن استعادته، يرجى توخي الحذر.",
"topic.empty": "لا توجد مواضيع تم إنشاؤها",
"notSupportGuide.desc": "وضع النشر الحالي لا يدعم إنشاء الصور بالذكاء الاصطناعي. قم بالتبديل إلى <1>وضع نشر قاعدة بيانات الخادم</1>، أو استخدم <3>LobeHub Cloud</3>.",
"notSupportGuide.features.fileIntegration.desc": "تكامل عميق مع نظام إدارة الملفات؛ يتم حفظ الصور المُنشأة تلقائيًا في نظام الملفات لإدارة وتنظيم موحد.",
"notSupportGuide.features.fileIntegration.title": "تكامل مع نظام الملفات",
"notSupportGuide.features.llmAssisted.desc": "يجمع بين قدرات نماذج اللغة الكبيرة لتحسين وتوسيع الأوصاف بذكاء، مما يعزز جودة إنشاء الصور (قريبًا).",
"notSupportGuide.features.llmAssisted.title": "إنشاء صور بمساعدة LLM",
"notSupportGuide.features.multiProviders.desc": "يدعم عدة مزودي خدمات لإنشاء الصور بالذكاء الاصطناعي، بما في ذلك OpenAI gpt-image-1 وGoogle Imagen وFAL.ai والمزيد، مما يوفر مجموعة واسعة من النماذج.",
"notSupportGuide.features.multiProviders.title": "دعم متعدد المزودين",
"notSupportGuide.title": "وضع النشر الحالي لا يدعم إنشاء الصور بالذكاء الاصطناعي",
"topic.createNew": "موضوع جديد",
"topic.deleteConfirm": "حذف موضوع الإنشاء",
"topic.deleteConfirmDesc": "أنت على وشك حذف موضوع الإنشاء هذا. لا يمكن التراجع عن هذا الإجراء، يرجى المتابعة بحذر.",
"topic.empty": "لا توجد مواضيع إنشاء",
"topic.title": "موضوع الرسم",
"topic.untitled": "الموضوع الافتراضي"
"topic.untitled": "موضوع افتراضي"
}
+14 -14
View File
@@ -1,21 +1,21 @@
{
"addToKnowledgeBase.addSuccess": "تم إضافة الملف بنجاح، <1>عرض الآن</1>",
"addToKnowledgeBase.addSuccess": "تمت إضافة الملف بنجاح، <1>عرض الآن</1>",
"addToKnowledgeBase.confirm": "إضافة",
"addToKnowledgeBase.error": "فشل في إضافة الملف إلى قاعدة المعرفة",
"addToKnowledgeBase.id.placeholder": "يرجى اختيار قاعدة المعرفة المراد الإضافة إليها",
"addToKnowledgeBase.id.required": "يرجى اختيار قاعدة المعرفة",
"addToKnowledgeBase.id.title": "قاعدة المعرفة المستهدفة",
"addToKnowledgeBase.title": "إضافة إلى قاعدة المعرفة",
"addToKnowledgeBase.totalFiles": "تم اختيار {{count}} ملف",
"addToKnowledgeBase.error": "فشل في إضافة الملف إلى المكتبة",
"addToKnowledgeBase.id.placeholder": "يرجى اختيار مكتبة للإضافة إليها",
"addToKnowledgeBase.id.required": "يرجى اختيار مكتبة",
"addToKnowledgeBase.id.title": "المكتبة المستهدفة",
"addToKnowledgeBase.title": "إضافة إلى المكتبة",
"addToKnowledgeBase.totalFiles": "{{count}} ملف/ملفات محددة",
"createNew.confirm": "إنشاء جديد",
"createNew.description.placeholder": "وصف قاعدة المعرفة (اختياري)",
"createNew.description.placeholder": "وصف المكتبة (اختياري)",
"createNew.formTitle": "المعلومات الأساسية",
"createNew.name.placeholder": "اسم قاعدة المعرفة",
"createNew.name.required": "يرجى إدخال اسم قاعدة المعرفة",
"createNew.title": "إنشاء قاعدة معرفة جديدة",
"tab.evals": "تقييمات",
"tab.files": "المستندات",
"createNew.name.placeholder": "اسم المكتبة",
"createNew.name.required": "يرجى إدخال اسم المكتبة",
"createNew.title": "إنشاء مكتبة جديدة",
"tab.evals": "التقييمات",
"tab.files": "الملفات",
"tab.settings": "الإعدادات",
"tab.testing": "اختبار الاسترجاع",
"title": "قاعدة المعرفة"
"title": "المكتبة"
}
+7 -7
View File
@@ -1,10 +1,10 @@
{
"desc": نقوم بتحديث الميزات الجديدة التي نستكشفها من وقت لآخر، ندعوك لتجربتها!",
"features.assistantMessageGroup.desc": "تجميع رسائل المساعد ونتائج استدعاء الأدوات في مجموعة واحدة للعرض",
"features.assistantMessageGroup.title": "تجميع رسائل المساعد",
"features.groupChat.desc": فعيل إمكانية تنسيق المحادثات الجماعية متعددة الوكلاء.",
"desc": تجد هنا تحديثات عرضية حول الميزات الجديدة التي نستكشفها — لا تتردد في تجربتها!",
"features.assistantMessageGroup.desc": "تجميع رسائل الوكيل ونتائج استدعاء الأدوات معًا للعرض",
"features.assistantMessageGroup.title": "تجميع رسائل الوكيل",
"features.groupChat.desc": مكين تنسيق الدردشة الجماعية متعددة الوكلاء.",
"features.groupChat.title": "دردشة جماعية (متعددة الوكلاء)",
"features.inputMarkdown.desc": "عرض Markdown في منطقة الإدخال بشكل فوري (مثل النص العريض، كتل الشيفرة، الجداول، وغيرها).",
"features.inputMarkdown.title": "عرض Markdown في حقل الإدخال",
"title": "المختبر"
"features.inputMarkdown.desc": "عرض Markdown في منطقة الإدخال في الوقت الفعلي (نص عريض، كتل الشيفرة، جداول، إلخ).",
"features.inputMarkdown.title": "عرض Markdown في الإدخال",
"title": "المختبرات"
}
+42 -42
View File
@@ -1,11 +1,11 @@
{
"authorize.cancel": "إلغاء",
"authorize.cancel": "ليس الآن",
"authorize.confirm": "أنشئ ملفك الشخصي",
"authorize.description": "ملفك الشخصي في المجتمع مستقل عن حساب المستخدم في {{appName}}.",
"authorize.footer.agreement": "بمتابعتك، فإنك تؤكد أنك قد قرأت ووافقت على <terms>الشروط والأحكام</terms> و<privacy>سياسة الخصوصية</privacy>",
"authorize.description": "ملفك الشخصي في المجتمع منفصل عن حساب المستخدم الخاص بك في {{appName}}.",
"authorize.footer.agreement": المتابعة، فإنك تؤكد أنك قرأت ووافقت على <terms>الشروط والأحكام</terms> و<privacy>سياسة الخصوصية</privacy>.",
"authorize.footer.privacy": "سياسة الخصوصية",
"authorize.footer.terms": "شروط الخدمة",
"authorize.subtitle": "أنشئ ملفًا شخصيًا في المجتمع لتتمكن من تقديم وإدارة معلومات النشر.",
"authorize.subtitle": "أنشئ ملفًا شخصيًا في المجتمع لتتمكن من إرسال وإدارة القوائم داخل المجتمع.",
"authorize.title": "إنشاء ملف المجتمع الشخصي",
"callback.buttons.close": "إغلاق النافذة",
"callback.messages.authFailed": "فشل التفويض: {{error}}",
@@ -14,60 +14,60 @@
"callback.messages.successWithCountdown": "{{message}} سيتم إغلاق النافذة تلقائيًا خلال {{countdown}} ثانية",
"callback.messages.successWithRedirect": "تم التفويض بنجاح! جارٍ إعادة التوجيه...",
"callback.titles.error": "فشل التفويض",
"callback.titles.loading": "تفويض LobeHub Market",
"callback.titles.loading": "تفويض سوق LobeHub",
"callback.titles.success": "تم التفويض بنجاح",
"errors.authorizationFailed": "فشل التفويض، يرجى المحاولة مرة أخرى.",
"errors.browserOnly": "يمكن بدء عملية التفويض من خلال المتصفح فقط.",
"errors.codeConsumed": "تم استخدام رمز التفويض، يرجى المحاولة مرة أخرى.",
"errors.codeVerifierMissing": "جلسة التفويض غير صالحة، يرجى إعادة تسجيل الدخول.",
"errors.general": "حدث خطأ أثناء التفويض، يرجى المحاولة مرة أخرى.",
"errors.handoffFailed": "تعذر الحصول على نتيجة التفويض، يرجى المحاولة مرة أخرى.",
"errors.handoffTimeout": "انتهت مهلة التفويض، يرجى إكمال العملية في المتصفح ثم المحاولة مرة أخرى.",
"errors.oidcNotReady": "خدمة التفويض غير جاهزة بعد، يرجى المحاولة لاحقًا.",
"errors.openBrowserFailed": "تعذر فتح متصفح النظام، يرجى المحاولة مرة أخرى.",
"errors.openPopupFailed": "تعذر فتح نافذة التفويض، يرجى التحقق من إعدادات حظر النوافذ المنبثقة في المتصفح.",
"errors.popupClosed": "تم إغلاق نافذة التفويض قبل إتمام العملية.",
"errors.sessionExpired": "انتهت صلاحية جلسة التفويض، يرجى تسجيل الدخول مرة أخرى.",
"errors.stateMismatch": "حالة التفويض غير متطابقة، يرجى المحاولة مرة أخرى.",
"errors.stateMissing": "لم يتم العثور على حالة التفويض، يرجى المحاولة مرة أخرى.",
"messages.authorizationFailed": "حدثت مشكلة في التفويض. يمكنك المحاولة مرة أخرى أو التحقق مما إذا كنت قد سجلت الدخول في المتصفح.",
"errors.browserOnly": "يمكن بدء عملية التفويض فقط من خلال المتصفح.",
"errors.codeConsumed": "تم استخدام رمز التفويض بالفعل. يرجى المحاولة مرة أخرى.",
"errors.codeVerifierMissing": "جلسة التفويض غير صالحة. يرجى إعادة بدء عملية تسجيل الدخول.",
"errors.general": "حدث خطأ أثناء التفويض. يرجى المحاولة مرة أخرى.",
"errors.handoffFailed": "فشل في استرداد نتيجة التفويض. يرجى المحاولة مرة أخرى.",
"errors.handoffTimeout": "انتهت مهلة التفويض. يرجى إكمال العملية في المتصفح والمحاولة مرة أخرى.",
"errors.oidcNotReady": "خدمة التفويض غير جاهزة. يرجى المحاولة لاحقًا.",
"errors.openBrowserFailed": "فشل في فتح متصفح النظام. يرجى المحاولة مرة أخرى.",
"errors.openPopupFailed": "فشل في فتح نافذة التفويض المنبثقة. يرجى التحقق من إعدادات حظر النوافذ المنبثقة في المتصفح.",
"errors.popupClosed": "تم إغلاق نافذة التفويض قبل إكمال العملية.",
"errors.sessionExpired": "انتهت صلاحية جلسة التفويض. يرجى تسجيل الدخول مرة أخرى.",
"errors.stateMismatch": "عدم تطابق حالة التفويض. يرجى المحاولة مرة أخرى.",
"errors.stateMissing": "لم يتم العثور على حالة التفويض. يرجى المحاولة مرة أخرى.",
"messages.authorizationFailed": "حدثت مشكلة أثناء التفويض. أعد المحاولة، أو تحقق مما إذا كنت قد أكملت تسجيل الدخول في المتصفح.",
"messages.authorized": "تم تفويض خدمة LobeHub بنجاح",
"messages.handoffTimeout": "انتهت مهلة انتظار التفويض. يرجى العودة إلى المتصفح لإكمال العملية ثم المحاولة مرة أخرى.",
"messages.handoffTimeout": "انتهت مهلة التفويض. أكمل العملية في المتصفح ثم أعد المحاولة.",
"messages.loading": "جارٍ بدء عملية التفويض...",
"messages.success.cloudMcpInstall": "تم التفويض بنجاح! يمكنك الآن تثبيت إضافة Cloud MCP.",
"messages.success.submit": "تم التفويض بنجاح! يمكنك الآن نشر المساعد.",
"messages.success.cloudMcpInstall": "تم التفويض بنجاح! يمكنك الآن تثبيت مهارة Cloud MCP.",
"messages.success.submit": "تم التفويض بنجاح! يمكنك الآن نشر وكيلك.",
"messages.success.upload": "تم التفويض بنجاح! يمكنك الآن نشر إصدار جديد.",
"profileSetup.cancel": "إلغاء",
"profileSetup.descriptionEdit": "حدّث معلومات ملفك الشخصي في المجتمع.",
"profileSetup.descriptionFirstTime": "قم بإعداد ملفك الشخصي لإكمال إنشاء ملف المجتمع.",
"profileSetup.descriptionEdit": "قم بتحديث معلومات ملفك الشخصي في المجتمع.",
"profileSetup.descriptionFirstTime": "قم بإعداد ملفك لإكمال ملفك الشخصي في المجتمع.",
"profileSetup.errors.fileTooLarge": "حجم الملف لا يمكن أن يتجاوز 2 ميغابايت",
"profileSetup.errors.notAuthenticated": "يرجى تسجيل الدخول أولاً قبل المتابعة",
"profileSetup.errors.updateFailed": "فشل في تحديث الملف الشخصي، يرجى المحاولة مرة أخرى",
"profileSetup.errors.uploadFailed": "فشل التحميل، يرجى المحاولة مرة أخرى",
"profileSetup.errors.usernameTaken": "معرّف المستخدم هذا مستخدم بالفعل، يرجى اختيار معرّف آخر",
"profileSetup.fields.avatar.label": "الصورة الشخصية",
"profileSetup.errors.notAuthenticated": "يرجى تسجيل الدخول أولاً",
"profileSetup.errors.updateFailed": "فشل في تحديث الملف الشخصي. يرجى المحاولة مرة أخرى",
"profileSetup.errors.uploadFailed": "فشل في التحميل. يرجى المحاولة مرة أخرى",
"profileSetup.errors.usernameTaken": "معرّف المستخدم هذا مستخدم بالفعل. يرجى اختيار آخر",
"profileSetup.fields.avatar.label": "الصورة الرمزية",
"profileSetup.fields.bannerUrl.clickToUpload": "انقر لتحميل صورة الغلاف",
"profileSetup.fields.bannerUrl.label": "صورة الغلاف",
"profileSetup.fields.bannerUrl.remove": "إزالة صورة الغلاف",
"profileSetup.fields.bannerUrl.tooltip": "ستظهر صورة الغلاف في أعلى صفحتك الشخصية (النسبة الموصى بها 16:9)",
"profileSetup.fields.bannerUrl.remove": "إزالة الغلاف",
"profileSetup.fields.bannerUrl.tooltip": "ستظهر صورة الغلاف في أعلى صفحة ملفك الشخصي (نسبة 16:9 موصى بها)",
"profileSetup.fields.bannerUrl.uploading": "جارٍ التحميل...",
"profileSetup.fields.description.label": "نبذة شخصية",
"profileSetup.fields.description.maxLength": "النبذة الشخصية يجب ألا تتجاوز 200 حرف",
"profileSetup.fields.description.placeholder": "قدّم نفسك بإيجاز...",
"profileSetup.fields.displayName.label": "الاسم الظاهر",
"profileSetup.fields.displayName.maxLength": "الاسم الظاهر يجب ألا يتجاوز 50 حرفًا",
"profileSetup.fields.displayName.placeholder": "أدخل اسمك الظاهر",
"profileSetup.fields.displayName.required": "يرجى إدخال الاسم الظاهر",
"profileSetup.fields.description.label": "نبذة",
"profileSetup.fields.description.maxLength": "يجب ألا تتجاوز النبذة 200 حرف",
"profileSetup.fields.description.placeholder": "أخبرنا عن نفسك...",
"profileSetup.fields.displayName.label": "الاسم المعروض",
"profileSetup.fields.displayName.maxLength": "يجب ألا يتجاوز الاسم المعروض 50 حرفًا",
"profileSetup.fields.displayName.placeholder": "أدخل الاسم المعروض",
"profileSetup.fields.displayName.required": "يرجى إدخال الاسم المعروض",
"profileSetup.fields.github.placeholder": "اسم مستخدم GitHub",
"profileSetup.fields.twitter.placeholder": "اسم مستخدم X (تويتر)",
"profileSetup.fields.userName.label": "معرّف المستخدم",
"profileSetup.fields.userName.maxLength": "معرّف المستخدم يجب ألا يتجاوز 32 حرفًا",
"profileSetup.fields.userName.minLength": "معرّف المستخدم يجب أن لا يقل عن 3 أحرف",
"profileSetup.fields.userName.maxLength": "يجب ألا يتجاوز معرّف المستخدم 32 حرفًا",
"profileSetup.fields.userName.minLength": "يجب ألا يقل معرّف المستخدم عن 3 أحرف",
"profileSetup.fields.userName.pattern": "يمكن أن يحتوي معرّف المستخدم على أحرف وأرقام وشرطات سفلية وشرطات فقط",
"profileSetup.fields.userName.placeholder": "أدخل معرّف المستخدم الخاص بك",
"profileSetup.fields.userName.required": "يرجى إدخال معرّف المستخدم",
"profileSetup.fields.userName.tooltip": "معرّف المستخدم هو معرفك الفريد وسيُستخدم في رابط صفحتك الشخصية",
"profileSetup.fields.website.invalidUrl": "يرجى إدخال رابط صالح",
"profileSetup.fields.userName.tooltip": "معرّف المستخدم هو معرفك الفريد وسيُستخدم في عنوان URL لصفحة ملفك الشخصي",
"profileSetup.fields.website.invalidUrl": "يرجى إدخال رابط URL صالح",
"profileSetup.fields.website.placeholder": "رابط الموقع الشخصي",
"profileSetup.getStarted": "ابدأ الآن",
"profileSetup.save": "حفظ",
+24 -24
View File
@@ -2,44 +2,44 @@
"context.actions.delete": "حذف",
"context.actions.edit": "تعديل",
"context.defaultType": "سياق",
"context.deleteConfirm": "هل أنت متأكد من أنك تريد حذف هذه الذاكرة السياقية؟ لا يمكن التراجع عن هذا الإجراء.",
"context.deleteConfirm": "هل أنت متأكد أنك تريد حذف هذه الذاكرة السياقية؟ لا يمكن التراجع عن هذا الإجراء.",
"context.deleteTitle": "حذف الذاكرة السياقية",
"context.description": "الوصف",
"context.empty": "لا توجد ذكريات سياقية حالياً",
"context.empty": "لا توجد ذكريات سياقية متاحة",
"context.source": "المصدر",
"empty.description": "استخراج الذكريات هو عملية تدريجية، يُرجى التفاعل في مواضيع أكثر لتغذية محتوى الذكريات المستخرجة. حاول إجراء محادثات أعمق مع المساعد لالتقاط وتخزين معلومات ذات قيمة بشكل أفضل.",
"empty.description": "استرجاع الذكريات هو عملية تدريجية. يرجى التفاعل أكثر لإثراء المحتوى المتاح للاسترجاع. حاول إجراء محادثات أعمق مع الوكيل لالتقاط وتخزين معلومات أكثر قيمة.",
"empty.search": "لم يتم العثور على ذكريات مطابقة",
"empty.title": "لا توجد ذكريات حالياً",
"empty.title": "لا توجد ذكريات بعد",
"experience.actions.delete": "حذف",
"experience.actions.edit": "تعديل",
"experience.defaultType": "تجربة",
"experience.deleteConfirm": "هل أنت متأكد من أنك تريد حذف هذه الذاكرة التجريبية؟ لا يمكن التراجع عن هذا الإجراء.",
"experience.deleteConfirm": "هل أنت متأكد أنك تريد حذف هذه الذاكرة التجريبية؟ لا يمكن التراجع عن هذا الإجراء.",
"experience.deleteTitle": "حذف الذاكرة التجريبية",
"experience.empty": "لا توجد ذكريات تجريبية حالياً",
"experience.empty": "لا توجد ذكريات تجريبية متاحة",
"experience.keyLearning": "التعلم الرئيسي",
"experience.situation": "السياق",
"experience.situation": "الموقف",
"experience.source": "المصدر",
"experience.steps.action": "الإجراء",
"experience.steps.result": "النتيجة",
"experience.steps.situation": "الوضع",
"experience.steps.situation": "السياق",
"experience.steps.task": "المهمة",
"filter.search": "ابحث عن كلمات مفتاحية أو وصف للذاكرة...",
"filter.sort.createdAt": اريخ الإنشاء",
"filter.sort.scoreConfidence": "درجة الثقة",
"filter.sort.scoreImpact": "الأهمية",
"filter.sort.scorePriority": "أولوية التفضيل",
"filter.sort.scoreUrgency": "درجة الإلحاح",
"identity.empty": "لا توجد ذاكرة هوية حالياً",
"identity.filter.search": "ابحث عن دور أو علاقة أو وصف...",
"filter.search": "ابحث في الكلمات المفتاحية أو الأوصاف...",
"filter.sort.createdAt": "وقت الإنشاء",
"filter.sort.scoreConfidence": "الثقة",
"filter.sort.scoreImpact": "التأثير",
"filter.sort.scorePriority": "وزن التفضيل",
"filter.sort.scoreUrgency": "الإلحاح",
"identity.empty": "لا توجد ذكريات هوية متاحة",
"identity.filter.search": "ابحث في الأدوار أو العلاقات أو الأوصاف...",
"identity.filter.type.all": "الكل",
"identity.filter.type.demographic": "السمات",
"identity.filter.type.demographic": "البيانات الديموغرافية",
"identity.filter.type.personal": "الدور",
"identity.filter.type.professional": "مهني",
"identity.filter.type.professional": "المهني",
"identity.list.confirmDelete": "تأكيد الحذف",
"identity.list.deleteCancel": "إلغاء",
"identity.list.deleteContent": "هل أنت متأكد من أنك تريد حذف ذاكرة الهوية هذه؟ لا يمكن التراجع عن هذا الإجراء.",
"identity.list.deleteContent": "هل أنت متأكد أنك تريد حذف هذه الذاكرة المتعلقة بالهوية؟ لا يمكن التراجع عن هذا الإجراء.",
"identity.list.deleteOk": "حذف",
"identity.list.noResults": "لم يتم العثور على أي ذاكرة هوية مطابقة",
"identity.list.noResults": "لم يتم العثور على ذكريات هوية مطابقة",
"identity.list.updated": "تم التحديث",
"identity.roleCloud.collapse": "إخفاء",
"identity.roleCloud.expand": "عرض المزيد",
@@ -50,17 +50,17 @@
"preference.actions.edit": "تعديل",
"preference.conclusionDirectives": "توجيهات الاستنتاج",
"preference.defaultType": "تفضيل",
"preference.deleteConfirm": "هل أنت متأكد من أنك تريد حذف هذه الذاكرة التفضيلية؟ لا يمكن التراجع عن هذا الإجراء.",
"preference.deleteConfirm": "هل أنت متأكد أنك تريد حذف هذه الذاكرة التفضيلية؟ لا يمكن التراجع عن هذا الإجراء.",
"preference.deleteTitle": "حذف الذاكرة التفضيلية",
"preference.empty": "لا توجد ذكريات تفضيلية حالياً",
"preference.empty": "لا توجد ذكريات تفضيل متاحة",
"preference.source": "المصدر",
"preference.suggestions": "الإجراءات التي قد يتخذها المساعد",
"preference.suggestions": "الإجراءات التي قد يتخذها الوكيل",
"tab.contexts": "السياقات",
"tab.experiences": "التجارب",
"tab.home": "الرئيسية",
"tab.identities": "الهويات",
"tab.preferences": "التفضيلات",
"tab.search": "بحث",
"viewMode.masonry": "عرض متدرج",
"viewMode.masonry": "شبكة",
"viewMode.timeline": "الجدول الزمني"
}
+20 -20
View File
@@ -1,25 +1,25 @@
{
"changelog.description": "تابع الميزات الجديدة والتحسينات في {{appName}} باستمرار",
"changelog.title": "سجل التحديثات",
"chat.description": "{{appName}} يقدم لك أفضل تجربة لاستخدام ChatGPT وClaude وGemini وOLLaMA WebUI",
"chat.title": "{{appName}}: أداة الذكاء الاصطناعي الشخصية، امنح نفسك دماغًا أكثر ذكاءً",
"discover.assistants.description": "إنشاء المحتوى، الكتابة، الأسئلة والأجوبة، توليد الصور، توليد الفيديو، توليد الصوت، الوكلاء الذكيون، سير العمل الآلي، تخصيص مساعد الذكاء الاصطناعي / GPTs / OLLaMA الخاص بك",
"discover.assistants.title": "مجتمع الوكلاء الذكيين",
"discover.description": "إنشاء المحتوى، الكتابة، الأسئلة والأجوبة، توليد الصور، توليد الفيديو، توليد الصوت، الوكلاء الذكيون، سير العمل الآلي، تطبيقات الذكاء الاصطناعي المخصصة، تخصيص منصة تطبيقات الذكاء الاصطناعي الخاصة بك",
"discover.mcp.description": "ابحث وقارن واتصل بآلاف خوادم MCP، مما يساعد أنظمة الذكاء الاصطناعي على الوصول بسهولة إلى أنظمة الملفات وقواعد البيانات وواجهات برمجة التطبيقات وغيرها من الموارد الحيوية، لتوسيع قدرات الذكاء الاصطناعي الخاصة بك بشكل شامل",
"changelog.description": "ابقَ على اطلاع بأحدث الميزات والتحسينات في {{appName}}",
"changelog.title": "سجل التغييرات",
"chat.description": "{{appName}} يقدم لك أفضل تجربة واجهة مستخدم لـ ChatGPT وClaude وGemini وOLLaMA.",
"chat.title": "{{appName}} · للوكلاء التعاونيين",
"discover.assistants.description": "محتوى، أسئلة وأجوبة، صور، فيديو، صوت، سير عمل—تصفح وأضف وكلاء من المجتمع.",
"discover.assistants.title": "مجتمع الوكلاء",
"discover.description": "استكشف الوكلاء، المهارات، المزودين، النماذج، وخوادم MCP.",
"discover.mcp.description": "ابحث، قارن، واتصل بآلاف خوادم MCP، مما يمكّن أنظمة الذكاء الاصطناعي من الوصول بسهولة إلى أنظمة الملفات، قواعد البيانات، واجهات البرمجة، وغيرها من الموارد الأساسية، لتوسيع قدراتك في الذكاء الاصطناعي بشكل شامل.",
"discover.mcp.title": "مجتمع خوادم MCP",
"discover.models.description": "استكشاف نماذج الذكاء الاصطناعي الرائجة OpenAI / GPT / Claude 3 / Gemini / Ollama / Azure / DeepSeek",
"discover.models.description": "استكشف نماذج الذكاء الاصطناعي الرائدة OpenAI / GPT / Claude 3 / Gemini / Ollama / Azure / DeepSeek",
"discover.models.title": "مجتمع النماذج",
"discover.plugins.description": "استكشف توليد الرسوم البيانية، والأبحاث الأكاديمية، وتوليد الصور، وتوليد الفيديو، وتوليد الصوت، وأتمتة سير العمل، ودمج قدرات إضافية غنية لمساعدتك.",
"discover.plugins.title": "مجتمع الإضافات",
"discover.providers.description": "استكشاف مزودي النماذج الرائجة OpenAI / Qwen / Ollama / Anthropic / DeepSeek / Google Gemini / OpenRouter",
"discover.providers.title": "مجتمع مزودي النماذج",
"discover.plugins.description": "استكشف الرسوم البيانية، الأدوات الأكاديمية، توليد الصور/الفيديو/الصوت، وسير العمل—أضف مهارات إلى وكلائك.",
"discover.plugins.title": "مجتمع المهارات",
"discover.providers.description": "استكشف أبرز مزودي النماذج OpenAI / Qwen / Ollama / Anthropic / DeepSeek / Google Gemini / OpenRouter",
"discover.providers.title": "مجتمع المزودين",
"discover.search": "بحث",
"discover.title": "اكتشاف",
"image.description": "{{appName}} يقدم لك أفضل تجربة استخدام لـ GPT Image و Flux و Midjourney و Stable Diffusion",
"image.title": "الرسم بالذكاء الاصطناعي",
"plugins.description": "البحث، توليد الرسوم البيانية، الأكاديميات، توليد الصور، توليد الفيديو، توليد الصوت، سير العمل الآلي، خصص قدرات ToolCall الخاصة بـ ChatGPT / Claude",
"plugins.title": "مجتمع الإضافات",
"welcome.description": "{{appName}} يقدم لك أفضل تجربة لاستخدام ChatGPT وClaude وGemini وOLLaMA WebUI",
"welcome.title": "مرحبًا بك في {{appName}}: أداة الذكاء الاصطناعي الشخصية، امنح نفسك دماغًا أكثر ذكاءً"
"discover.title": "استكشاف",
"image.description": "{{appName}} يقدم لك أفضل تجربة مع GPT Image وFlux وMidjourney وStable Diffusion",
"image.title": "فن الذكاء الاصطناعي",
"plugins.description": "بحث، رسوم بيانية، أدوات أكاديمية، توليد الصور/الفيديو/الصوت، سير العمل—أضف مهارات إلى وكلائك.",
"plugins.title": "مجتمع المهارات",
"welcome.description": "{{appName}} يقدم لك أفضل تجربة واجهة مستخدم لـ ChatGPT وClaude وGemini وOLLaMA.",
"welcome.title": "مرحبًا بك في {{appName}} · للوكلاء التعاونيين"
}
+15 -15
View File
@@ -1,23 +1,23 @@
{
"dbV1.action.clearDB": "مسح البيانات المحلية",
"dbV1.action.downloadBackup": "تنزيل نسخة احتياطية للبيانات",
"dbV1.action.downloadBackup": "تنزيل نسخة احتياطية من البيانات",
"dbV1.action.reUpgrade": "إعادة الترقية",
"dbV1.action.start": "ابدأ الاستخدام",
"dbV1.action.upgrade": "ترقية فورية",
"dbV1.clear.confirm": "سيتم مسح البيانات المحلية (دون تأثير على الإعدادات العامة)، يرجى التأكد من تنزيل نسخة احتياطية للبيانات.",
"dbV1.description": "في الإصدار الجديد، حقق تخزين بيانات {{appName}} قفزة هائلة. لذلك، نحتاج إلى ترقية البيانات القديمة لتوفير تجربة استخدام أفضل لك.",
"dbV1.features.capability.desc": "استنادًا إلى تقنية IndexedDB، تكفي لتخزين محادثاتك مدى الحياة",
"dbV1.features.capability.title": "سعة كبيرة",
"dbV1.features.performance.desc": "مليون رسالة يتم فهرستها تلقائيًا، واستجابة استعلامات البحث في مللي ثانية",
"dbV1.action.start": "ابدأ الآن",
"dbV1.action.upgrade": "ترقية",
"dbV1.clear.confirm": "أنت على وشك مسح البيانات المحلية (لن تتأثر الإعدادات العامة). يرجى التأكد من أنك قمت بتنزيل نسخة احتياطية من البيانات.",
"dbV1.description": "في الإصدار الجديد، شهد تخزين البيانات في {{appName}} تطورًا كبيرًا. لذلك، نحتاج إلى ترقية البيانات القديمة لتقديم تجربة مستخدم أفضل.",
"dbV1.features.capability.desc": "يعتمد على تقنية IndexedDB، وقادر على تخزين رسائل محادثة تدوم مدى الحياة.",
"dbV1.features.capability.title": "سعة تخزين كبيرة",
"dbV1.features.performance.desc": "يقوم بفهرسة ملايين الرسائل تلقائيًا، مع استجابة فورية لطلبات البحث خلال أجزاء من الثانية.",
"dbV1.features.performance.title": "أداء عالي",
"dbV1.features.use.desc": "يدعم البحث عن العناوين، الأوصاف، العلامات، محتوى الرسائل وحتى نصوص الترجمة، مما يعزز كفاءة البحث اليومية بشكل كبير",
"dbV1.features.use.desc": "يدعم البحث حسب العنوان والوصف والوسوم ومحتوى الرسائل وحتى النصوص المترجمة، مما يعزز كفاءة البحث اليومي بشكل كبير.",
"dbV1.features.use.title": "أسهل في الاستخدام",
"dbV1.title": "تطور بيانات {{appName}}",
"dbV1.upgrade.error.subTitle": "نعتذر، حدث خطأ أثناء عملية ترقية قاعدة البيانات. يرجى تجربة الحلول التالية: A. امسح البيانات المحلية ثم أعد استيراد البيانات الاحتياطية؛ B. انقر على زر «إعادة الترقية».<br><br> إذا استمرت المشكلة، يرجى <1>تقديم مشكلة</1>، وسنساعدك في حلها في أقرب وقت ممكن.",
"dbV1.upgrade.error.subTitle": "نعتذر، حدث خطأ أثناء عملية ترقية قاعدة البيانات. يرجى تجربة الحلول التالية: أ. مسح البيانات المحلية وإعادة استيراد النسخة الاحتياطية؛ ب. النقر على زر 'إعادة المحاولة'.<br><br> إذا استمرت المشكلة، يرجى <1>إرسال تقرير بالمشكلة</1> وسنقوم بمساعدتك في أقرب وقت ممكن.",
"dbV1.upgrade.error.title": "فشل ترقية قاعدة البيانات",
"dbV1.upgrade.success.subTitle": "تمت ترقية قاعدة بيانات {{appName}} إلى أحدث إصدار، ابدأ التجربة الآن",
"dbV1.upgrade.success.title": "نجاح ترقية قاعدة البيانات",
"dbV1.upgradeTip": "تستغرق عملية الترقية حوالي 10 إلى 20 ثانية، يرجى عدم إغلاق {{appName}} أثناء الترقية",
"migrateError.missVersion": "البيانات المستوردة تفتقد رقم الإصدار، يرجى التحقق من الملف وإعادة المحاولة",
"migrateError.noMigration": "لم يتم العثور على خطة هجرة تتوافق مع الإصدار الحالي، يرجى التحقق من رقم الإصدار وإعادة المحاولة. إذا استمرت المشكلة، يرجى تقديم ملاحظاتك"
"dbV1.upgrade.success.subTitle": "تمت ترقية قاعدة البيانات إلى أحدث إصدار. يمكنك المتابعة الآن.",
"dbV1.upgrade.success.title": "تمت ترقية قاعدة البيانات بنجاح",
"dbV1.upgradeTip": "ستستغرق الترقية حوالي 10 إلى 20 ثانية. يرجى عدم إغلاق {{appName}} أثناء عملية الترقية.",
"migrateError.missVersion": "البيانات المستوردة تفتقر إلى رقم الإصدار. يرجى التحقق من الملف والمحاولة مرة أخرى.",
"migrateError.noMigration": "لم يتم العثور على حل ترحيل للإصدار الحالي. يرجى التحقق من رقم الإصدار والمحاولة مرة أخرى. إذا استمرت المشكلة، يرجى إرسال ملاحظة دعم."
}
+162 -162
View File
@@ -1,102 +1,102 @@
{
"azure.azureApiVersion.desc": "نسخة API الخاصة بـ Azure، والتي تتبع تنسيق YYYY-MM-DD، راجع [الإصدارات الأحدث](https://learn.microsoft.com/zh-en/azure/ai-services/openai/reference#chat-completions)",
"azure.azureApiVersion.desc": "إصدار واجهة برمجة التطبيقات لـ Azure، اتبع التنسيق YYYY-MM-DD، تحقق من [أحدث إصدار](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#chat-completions)",
"azure.azureApiVersion.fetch": "جلب القائمة",
"azure.azureApiVersion.title": "Azure API Version",
"azure.empty": "الرجاء إدخال معرف النموذج لإضافة أول نموذج",
"azure.endpoint.desc": "يمكن العثور على هذه القيمة في قسم 'المفاتيح والنقاط النهائية' عند فحص الموارد في بوابة Azure",
"azure.azureApiVersion.title": "إصدار Azure API",
"azure.empty": "يرجى إدخال معرف النموذج لإضافة النموذج الأول",
"azure.endpoint.desc": "عند التحقق من الموارد من بوابة Azure، يمكنك العثور على هذه القيمة في قسم 'المفاتيح ونقاط النهاية'",
"azure.endpoint.placeholder": "https://docs-test-001.openai.azure.com",
"azure.endpoint.title": "عنوان Azure API",
"azure.modelListPlaceholder": "يرجى تحديد أو إضافة نموذج OpenAI الذي قمت بنشره",
"azure.modelListPlaceholder": "اختر أو أضف نموذج OpenAI الذي قمت بنشره",
"azure.title": "Azure OpenAI",
"azure.token.desc": "يمكن العثور على هذه القيمة في قسم 'المفاتيح والنقاط النهائية' عند فحص الموارد في بوابة Azure. يمكن استخدام KEY1 أو KEY2",
"azure.token.placeholder": "Azure API Key",
"azure.token.desc": "عند التحقق من الموارد من بوابة Azure، يمكنك العثور على هذه القيمة في قسم 'المفاتيح ونقاط النهاية'. يمكنك استخدام KEY1 أو KEY2",
"azure.token.placeholder": "مفتاح Azure API",
"azure.token.title": "مفتاح API",
"azureai.azureApiVersion.desc": "إصدار واجهة برمجة التطبيقات Azure، يتبع تنسيق YYYY-MM-DD، راجع [الإصدار الأحدث](https://learn.microsoft.com/zh-cn/azure/ai-services/openai/reference#chat-completions)",
"azureai.azureApiVersion.fetch": "الحصول على القائمة",
"azureai.azureApiVersion.title": "إصدار واجهة برمجة التطبيقات Azure",
"azureai.endpoint.desc": "ابحث عن نقطة نهاية استدلال نموذج Azure AI من نظرة عامة على مشروع Azure AI",
"azureai.azureApiVersion.desc": "إصدار واجهة برمجة التطبيقات لـ Azure، باتباع تنسيق YYYY-MM-DD. راجع [أحدث إصدار](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#chat-completions)",
"azureai.azureApiVersion.fetch": "جلب القائمة",
"azureai.azureApiVersion.title": "إصدار Azure API",
"azureai.endpoint.desc": "اعثر على نقطة نهاية استدلال نموذج Azure AI من نظرة عامة على مشروع Azure AI",
"azureai.endpoint.placeholder": "https://ai-userxxxxxxxxxx.services.ai.azure.com/models",
"azureai.endpoint.title": "نقطة نهاية Azure AI",
"azureai.title": "Azure OpenAI",
"azureai.token.desc": "ابحث عن مفتاح واجهة برمجة التطبيقات من نظرة عامة على مشروع Azure AI",
"azureai.token.desc": "اعثر على مفتاح API من نظرة عامة على مشروع Azure AI",
"azureai.token.placeholder": "مفتاح Azure",
"azureai.token.title": "المفتاح",
"bedrock.accessKeyId.desc": "أدخل AWS Access Key Id",
"bedrock.accessKeyId.placeholder": "AWS Access Key Id",
"bedrock.accessKeyId.title": "AWS Access Key Id",
"bedrock.checker.desc": "اختبر ما إذا كان AccessKeyId / SecretAccessKey مدخلاً بشكل صحيح",
"bedrock.region.desc": "أدخل AWS Region",
"bedrock.region.placeholder": "AWS Region",
"bedrock.region.title": "AWS Region",
"bedrock.secretAccessKey.desc": "أدخل AWS Secret Access Key",
"bedrock.secretAccessKey.placeholder": "AWS Secret Access Key",
"bedrock.secretAccessKey.title": "AWS Secret Access Key",
"bedrock.sessionToken.desc": "إذا كنت تستخدم AWS SSO/STS، يرجى إدخال رمز جلسة AWS الخاص بك",
"bedrock.accessKeyId.desc": "أدخل معرف مفتاح الوصول لـ AWS",
"bedrock.accessKeyId.placeholder": "معرف مفتاح الوصول لـ AWS",
"bedrock.accessKeyId.title": "معرف مفتاح الوصول لـ AWS",
"bedrock.checker.desc": "اختبر ما إذا تم إدخال AccessKeyId / SecretAccessKey بشكل صحيح",
"bedrock.region.desc": "أدخل منطقة AWS",
"bedrock.region.placeholder": "منطقة AWS",
"bedrock.region.title": "منطقة AWS",
"bedrock.secretAccessKey.desc": "أدخل مفتاح الوصول السري لـ AWS",
"bedrock.secretAccessKey.placeholder": "مفتاح الوصول السري لـ AWS",
"bedrock.secretAccessKey.title": "مفتاح الوصول السري لـ AWS",
"bedrock.sessionToken.desc": "إذا كنت تستخدم AWS SSO/STS، يرجى إدخال رمز جلسة AWS",
"bedrock.sessionToken.placeholder": "رمز جلسة AWS",
"bedrock.sessionToken.title": "رمز جلسة AWS (اختياري)",
"bedrock.title": "Bedrock",
"bedrock.unlock.customRegion": "منطقة خدمة مخصصة",
"bedrock.unlock.customSessionToken": "رمز الجلسة المخصص",
"bedrock.unlock.description": "أدخل معرف الوصول / مفتاح الوصول السري الخاص بك في AWS لبدء الجلسة. لن يتم تسجيل تكوين المصادقة الخاص بك من قبل التطبيق",
"bedrock.unlock.imageGenerationDescription": "أدخل AWS AccessKeyId / SecretAccessKey الخاص بك للبدء في التوليد. التطبيق لن يقوم بتسجيل إعدادات المصادقة الخاصة بك",
"bedrock.unlock.title": "استخدام معلومات المصادقة الخاصة بـ Bedrock المخصصة",
"cloudflare.apiKey.desc": "يرجى ملء Cloudflare API Key",
"cloudflare.apiKey.placeholder": "Cloudflare API Key",
"cloudflare.apiKey.title": "Cloudflare API Key",
"cloudflare.baseURLOrAccountID.desc": "أدخل رقم حساب Cloudflare أو عنوان URL API المخصص",
"cloudflare.baseURLOrAccountID.placeholder": "رقم حساب Cloudflare / عنوان URL API المخصص",
"cloudflare.baseURLOrAccountID.title": "رقم حساب Cloudflare / عنوان URL API",
"comfyui.apiKey.desc": "مفتاح API المطلوب لمصادقة Bearer Token",
"comfyui.apiKey.placeholder": "يرجى إدخال مفتاح API",
"bedrock.unlock.customSessionToken": "رمز جلسة مخصص",
"bedrock.unlock.description": "أدخل AccessKeyId / SecretAccessKey الخاص بك لبدء الجلسة. لن يقوم التطبيق بتخزين إعدادات المصادقة الخاصة بك",
"bedrock.unlock.imageGenerationDescription": "أدخل AccessKeyId / SecretAccessKey الخاص بك لبدء التوليد. لن يقوم التطبيق بتخزين بيانات اعتماد المصادقة الخاصة بك.",
"bedrock.unlock.title": "استخدام معلومات مصادقة Bedrock مخصصة",
"cloudflare.apiKey.desc": "يرجى إدخال مفتاح Cloudflare API",
"cloudflare.apiKey.placeholder": "مفتاح Cloudflare API",
"cloudflare.apiKey.title": "مفتاح Cloudflare API",
"cloudflare.baseURLOrAccountID.desc": "أدخل معرف حساب Cloudflare أو عنوان API مخصص",
"cloudflare.baseURLOrAccountID.placeholder": عرف حساب Cloudflare / عنوان API مخصص",
"cloudflare.baseURLOrAccountID.title": عرف حساب Cloudflare / عنوان API",
"comfyui.apiKey.desc": "مفتاح API لمصادقة Bearer Token",
"comfyui.apiKey.placeholder": "أدخل مفتاح API",
"comfyui.apiKey.required": "يرجى إدخال مفتاح API",
"comfyui.apiKey.title": "مفتاح API",
"comfyui.authType.desc": "اختر طريقة المصادقة مع خادم ComfyUI",
"comfyui.authType.options.basic": "اسم المستخدم/كلمة المرور",
"comfyui.authType.options.bearer": "Bearer (مفتاح API)",
"comfyui.authType.options.custom": "رؤوس مخصصة",
"comfyui.authType.options.none": "لا حاجة للمصادقة",
"comfyui.authType.desc": "اختر طريقة المصادقة للاتصال بخادم ComfyUI",
"comfyui.authType.options.basic": "مصادقة أساسية",
"comfyui.authType.options.bearer": "رمز Bearer",
"comfyui.authType.options.custom": "مصادقة مخصصة",
"comfyui.authType.options.none": "بدون مصادقة",
"comfyui.authType.placeholder": "يرجى اختيار نوع المصادقة",
"comfyui.authType.title": "نوع المصادقة",
"comfyui.baseURL.desc": "عنوان الوصول إلى واجهة ComfyUI على الويب",
"comfyui.baseURL.desc": "عنوان الوصول إلى خادم ComfyUI، مثل http://localhost:8000",
"comfyui.baseURL.placeholder": "http://127.0.0.1:8000",
"comfyui.baseURL.required": "يرجى إدخال عنوان خدمة ComfyUI",
"comfyui.baseURL.title": "عنوان خدمة ComfyUI",
"comfyui.checker.desc": "اختبار ما إذا كان الاتصال مهيأ بشكل صحيح",
"comfyui.checker.desc": "اختبر ما إذا تم تكوين الاتصال بشكل صحيح",
"comfyui.checker.title": "فحص الاتصال",
"comfyui.customHeaders.addButton": "إضافة رأس طلب",
"comfyui.customHeaders.deleteTooltip": "حذف رأس الطلب هذا",
"comfyui.customHeaders.desc": "رؤوس الطلب المطلوبة لطريقة المصادقة المخصصة، بتنسيق زوج مفتاح-قيمة",
"comfyui.customHeaders.duplicateKeyError": "لا يمكن تكرار أسماء رؤوس الطلب",
"comfyui.customHeaders.keyPlaceholder": "اسم المفتاح",
"comfyui.customHeaders.required": "يرجى إدخال رؤوس الطلب المخصصة",
"comfyui.customHeaders.title": "رؤوس الطلب المخصصة",
"comfyui.customHeaders.addButton": "إضافة ترويسة",
"comfyui.customHeaders.deleteTooltip": "حذف هذه الترويسة",
"comfyui.customHeaders.desc": "ترويسات الطلب المطلوبة للمصادقة المخصصة، بتنسيق أزواج مفتاح-قيمة",
"comfyui.customHeaders.duplicateKeyError": "لا يمكن تكرار أسماء الترويسات",
"comfyui.customHeaders.keyPlaceholder": "المفتاح",
"comfyui.customHeaders.required": "يرجى إدخال ترويسات الطلب المخصصة",
"comfyui.customHeaders.title": "ترويسات مخصصة",
"comfyui.customHeaders.valuePlaceholder": "القيمة",
"comfyui.password.desc": "كلمة المرور المطلوبة للمصادقة الأساسية",
"comfyui.password.placeholder": "يرجى إدخال كلمة المرور",
"comfyui.password.desc": "كلمة المرور للمصادقة الأساسية",
"comfyui.password.placeholder": "أدخل كلمة المرور",
"comfyui.password.required": "يرجى إدخال كلمة المرور",
"comfyui.password.title": "كلمة المرور",
"comfyui.title": "ComfyUI",
"comfyui.username.desc": "اسم المستخدم المطلوب للمصادقة الأساسية",
"comfyui.username.placeholder": "يرجى إدخال اسم المستخدم",
"comfyui.username.desc": "اسم المستخدم للمصادقة الأساسية",
"comfyui.username.placeholder": "أدخل اسم المستخدم",
"comfyui.username.required": "يرجى إدخال اسم المستخدم",
"comfyui.username.title": "اسم المستخدم",
"createNewAiProvider.apiKey.placeholder": "يرجى إدخال مفتاح API الخاص بك",
"createNewAiProvider.apiKey.title": "مفتاح API",
"createNewAiProvider.basicTitle": "المعلومات الأساسية",
"createNewAiProvider.basicTitle": "معلومات أساسية",
"createNewAiProvider.configTitle": "معلومات التكوين",
"createNewAiProvider.confirm": "إنشاء جديد",
"createNewAiProvider.confirm": "إنشاء",
"createNewAiProvider.createSuccess": "تم الإنشاء بنجاح",
"createNewAiProvider.description.placeholder": "نبذة عن مزود الخدمة (اختياري)",
"createNewAiProvider.description.title": "نبذة عن مزود الخدمة",
"createNewAiProvider.description.placeholder": "وصف المزود (اختياري)",
"createNewAiProvider.description.title": "وصف المزود",
"createNewAiProvider.id.desc": "معرف فريد لمزود الخدمة، لا يمكن تعديله بعد الإنشاء",
"createNewAiProvider.id.format": "يمكن أن يحتوي فقط على أرقام، أحرف صغيرة، شرطات (-) وشرطات سفلية (_) ",
"createNewAiProvider.id.placeholder": "يفضل أن يكون بالكامل بحروف صغيرة، مثل openai، لن يمكن تعديله بعد الإنشاء",
"createNewAiProvider.id.format": "يمكن أن يحتوي فقط على أرقام، حروف صغيرة، شرطات (-)، وشرطات سفلية (_)",
"createNewAiProvider.id.placeholder": "يفضل أن يكون بحروف صغيرة، مثل openai، لا يمكن تعديله بعد الإنشاء",
"createNewAiProvider.id.required": "يرجى إدخال معرف المزود",
"createNewAiProvider.id.title": "معرف المزود",
"createNewAiProvider.logo.placeholder": "https://example.com/logo.png",
"createNewAiProvider.logo.required": "يرجى تحميل شعار المزود بشكل صحيح",
"createNewAiProvider.logo.required": "يرجى تحميل شعار مزود صالح",
"createNewAiProvider.logo.title": "شعار المزود",
"createNewAiProvider.name.placeholder": "يرجى إدخال اسم العرض لمزود الخدمة",
"createNewAiProvider.name.placeholder": "يرجى إدخال اسم العرض للمزود",
"createNewAiProvider.name.required": "يرجى إدخال اسم المزود",
"createNewAiProvider.name.title": "اسم المزود",
"createNewAiProvider.proxyUrl.placeholder": "https://your-proxy-url.com/v1",
@@ -105,183 +105,183 @@
"createNewAiProvider.sdkType.placeholder": "openai/anthropic/azureai/ollama/...",
"createNewAiProvider.sdkType.required": "يرجى اختيار نوع SDK",
"createNewAiProvider.sdkType.title": "تنسيق الطلب",
"createNewAiProvider.title": "إنشاء مزود AI مخصص",
"github.personalAccessToken.desc": "أدخل رمز الوصول الشخصي الخاص بك على Github، انقر [هنا](https://github.com/settings/tokens) لإنشاء واحد",
"createNewAiProvider.title": "إنشاء مزود ذكاء اصطناعي مخصص",
"github.personalAccessToken.desc": "أدخل رمز الوصول الشخصي (PAT) الخاص بك على GitHub. انقر [هنا](https://github.com/settings/tokens) لإنشاء واحد.",
"github.personalAccessToken.placeholder": "ghp_xxxxxx",
"github.personalAccessToken.title": "GitHub PAT",
"github.personalAccessToken.title": "رمز GitHub PAT",
"huggingface.accessToken.desc": "أدخل رمز HuggingFace الخاص بك، انقر [هنا](https://huggingface.co/settings/tokens) لإنشاء واحد",
"huggingface.accessToken.placeholder": "hf_xxxxxxxxx",
"huggingface.accessToken.title": "رمز HuggingFace",
"list.title.custom": "لم يتم تفعيل مزود الخدمة المخصص",
"list.title.disabled": زود الخدمة غير مفعل",
"list.title.enabled": زود الخدمة مفعل",
"menu.addCustomProvider": "إضافة مزود خدمة مخصص",
"list.title.custom": "المزود المخصص غير مفعل",
"list.title.disabled": "معطل",
"list.title.enabled": "مفعل",
"menu.addCustomProvider": "إضافة مزود مخصص",
"menu.all": "الكل",
"menu.list.custom": "المزود المخصص غير مفعل",
"menu.list.disabled": "غير مفعل",
"menu.list.disabledActions.sort": "طريقة الترتيب",
"menu.list.disabledActions.sortAlphabetical": "ترتيب أبجديًا",
"menu.list.custom": "المخصص غير مفعل",
"menu.list.disabled": "معطل",
"menu.list.disabledActions.sort": "ترتيب حسب",
"menu.list.disabledActions.sortAlphabetical": "ترتيب أبجدي",
"menu.list.disabledActions.sortAlphabeticalDesc": "ترتيب أبجدي عكسي",
"menu.list.disabledActions.sortDefault": "الترتيب الافتراضي",
"menu.list.enabled": "مفعل",
"menu.notFound": "لم يتم العثور على نتائج البحث",
"menu.notFound": "لم يتم العثور على نتائج",
"menu.searchProviders": "البحث عن مزودين...",
"menu.sort": "ترتيب مخصص",
"newapi.apiKey.desc": "مفتاح API المقدم من منصة New API",
"newapi.apiKey.placeholder": "مفتاح API الخاص بـ New API",
"newapi.apiKey.desc": "مفتاح API مقدم من منصة New API",
"newapi.apiKey.placeholder": "مفتاح New API",
"newapi.apiKey.required": "مفتاح API مطلوب",
"newapi.apiKey.title": "مفتاح API",
"newapi.apiUrl.desc": "عنوان API لخدمة New API، غالبًا ما يحتاج إلى /v1",
"newapi.apiUrl.title": "عنوان API",
"newapi.enabled.title": مكين New API",
"newapi.models.batchSelect": "تحديد نماذج متعددة ({{count}})",
"newapi.apiUrl.desc": "نقطة النهاية لخدمة New API، عادةً ما تتضمن /v1",
"newapi.apiUrl.title": "رابط API",
"newapi.enabled.title": فعيل New API",
"newapi.models.batchSelect": "تحديد النماذج دفعة واحدة ({{count}} عنصر)",
"newapi.models.fetch": "جلب قائمة النماذج",
"newapi.models.selected": "النماذج المختارة",
"newapi.models.selected": "النماذج المحددة",
"newapi.models.title": "النماذج المتاحة",
"newapi.title": "New API",
"ollama.checker.desc": "اختبر ما إذا تم إدخال عنوان الوكيل بشكل صحيح",
"ollama.checker.desc": "اختبر ما إذا كان عنوان البروكسي مملوءًا بشكل صحيح",
"ollama.checker.title": "فحص الاتصال",
"ollama.customModelName.desc": "أضف نماذج مخصصة، استخدم الفاصلة (،) لفصل عدة نماذج",
"ollama.customModelName.placeholder": "vicuna,llava,codellama,llama2:13b-text",
"ollama.customModelName.title": "أسماء النماذج المخصصة",
"ollama.download.desc": "أولاما يقوم بتنزيل هذا النموذج، يرجى عدم إغلاق هذه الصفحة إذا أمكن. سيتم استئناف التنزيل من النقطة التي تم قطعها عند إعادة التحميل",
"ollama.download.failed": "فشل تحميل النموذج، يرجى التحقق من الشبكة أو إعدادات Ollama ثم إعادة المحاولة",
"ollama.customModelName.desc": "أضف نماذج مخصصة، افصل بين النماذج بفواصل",
"ollama.customModelName.placeholder": "vicuna, llava, codellama, llama2:13b-text",
"ollama.customModelName.title": "اسم النموذج المخصص",
"ollama.download.desc": "يقوم Ollama بتنزيل النموذج. يُفضل عدم إغلاق هذه الصفحة. سيستأنف التنزيل من حيث توقف إذا تم قطعه.",
"ollama.download.failed": "فشل تنزيل النموذج. يرجى التحقق من الشبكة أو إعدادات Ollama والمحاولة مرة أخرى.",
"ollama.download.remainingTime": "الوقت المتبقي",
"ollama.download.speed": "سرعة التنزيل",
"ollama.download.title": "جارٍ تنزيل النموذج {{model}} ",
"ollama.endpoint.desc": "يجب أن تحتوي على http(s)://، يمكن تركها فارغة إذا لم يتم تحديدها محليًا",
"ollama.endpoint.title": "عنوان وكيل الواجهة",
"ollama.download.speed": "السرعة",
"ollama.download.title": "جارٍ تنزيل النموذج {{model}}",
"ollama.endpoint.desc": "يجب أن يتضمن http(s)://؛ يمكن تركه فارغًا إذا لم يتم تحديده محليًا.",
"ollama.endpoint.title": "عنوان بروكسي الواجهة",
"ollama.title": "Ollama",
"ollama.unlock.cancel": "Cancel Download",
"ollama.unlock.confirm": "Download",
"ollama.unlock.description": "Enter your Ollama model tag to continue the session",
"ollama.unlock.cancel": "إلغاء التنزيل",
"ollama.unlock.confirm": "تنزيل",
"ollama.unlock.description": "أدخل وسم نموذج Ollama الخاص بك لمتابعة الجلسة",
"ollama.unlock.downloaded": "{{completed}} / {{total}}",
"ollama.unlock.starting": "Starting download...",
"ollama.unlock.title": "Download specified Ollama model",
"providerModels.batchSelect.selected": "تم اختيار {{count}} نموذج",
"providerModels.batchSelect.title": "تحديد متعدد",
"providerModels.config.aesGcm": "سيتم استخدام خوارزمية التشفير <1>AES-GCM</1> لتشفير مفتاحك وعنوان الوكيل وما إلى ذلك",
"providerModels.config.apiKey.desc": "يرجى إدخال مفتاح API الخاص بك {{name}}",
"providerModels.config.apiKey.descWithUrl": "يرجى إدخال مفتاح API الخاص بـ {{name}}، <3>انقر هنا للحصول عليه</3>",
"providerModels.config.apiKey.placeholder": "{{name}} مفتاح API",
"ollama.unlock.starting": "بدء التنزيل...",
"ollama.unlock.title": "تنزيل نموذج Ollama المحدد",
"providerModels.batchSelect.selected": "{{count}} نموذج محدد",
"providerModels.batchSelect.title": "تحديد جماعي",
"providerModels.config.aesGcm": "سيتم تشفير مفتاحك وعنوان البروكسي باستخدام خوارزمية التشفير <1>AES-GCM</1>",
"providerModels.config.apiKey.desc": "يرجى إدخال مفتاح API الخاص بـ {{name}}",
"providerModels.config.apiKey.descWithUrl": "يرجى إدخال مفتاح API الخاص بـ {{name}}. <3>انقر هنا للحصول عليه</3>",
"providerModels.config.apiKey.placeholder": "مفتاح API لـ {{name}}",
"providerModels.config.apiKey.title": "مفتاح API",
"providerModels.config.baseURL.desc": "يجب أن يحتوي على http(s)://",
"providerModels.config.baseURL.desc": "يجب أن يتضمن http(s)://",
"providerModels.config.baseURL.invalid": "يرجى إدخال عنوان URL صالح",
"providerModels.config.baseURL.placeholder": "https://your-proxy-url.com/v1",
"providerModels.config.baseURL.title": "عنوان وكيل API",
"providerModels.config.baseURL.title": "رابط بروكسي API",
"providerModels.config.checker.button": "تحقق",
"providerModels.config.checker.desc": "اختبار ما إذا كان مفتاح API وعنوان الوكيل قد تم إدخالهما بشكل صحيح",
"providerModels.config.checker.desc": "اختبر ما إذا تم ملء مفتاح API ورابط البروكسي بشكل صحيح",
"providerModels.config.checker.pass": "تم التحقق بنجاح",
"providerModels.config.checker.title": "اختبار الاتصال",
"providerModels.config.fetchOnClient.desc": "سيتم بدء طلب الجلسة مباشرة من المتصفح، مما قد يحسن سرعة الاستجابة",
"providerModels.config.fetchOnClient.title": "استخدام وضع الطلب من العميل",
"providerModels.config.helpDoc": "دليل التكوين",
"providerModels.config.responsesApi.desc": عتمد تنسيق طلب الجيل الجديد من OpenAI، لتمكين ميزات متقدمة مثل سلسلة التفكير (مدعومة فقط من نماذج OpenAI)",
"providerModels.config.responsesApi.title": "استخدام معيار Responses API",
"providerModels.config.waitingForMore": "المزيد من النماذج قيد <1>التخطيط للإدماج</1>، يرجى الانتظار",
"providerModels.createNew.title": "إنشاء نموذج AI مخصص",
"providerModels.item.config": "تكوين النموذج",
"providerModels.config.checker.title": "فحص الاتصال",
"providerModels.config.fetchOnClient.desc": "وضع طلب العميل سيبدأ الطلبات مباشرة من المتصفح، مما قد يحسن سرعة الاستجابة",
"providerModels.config.fetchOnClient.title": "استخدام وضع طلب العميل",
"providerModels.config.helpDoc": "دليل الإعداد",
"providerModels.config.responsesApi.desc": ستخدم تنسيق الطلب الجديد من OpenAI لتمكين ميزات متقدمة مثل سلسلة التفكير (مدعومة فقط من نماذج OpenAI)",
"providerModels.config.responsesApi.title": "استخدام مواصفات Responses API",
"providerModels.config.waitingForMore": "يتم حاليًا <1>التخطيط لإضافة المزيد من النماذج</1>، يرجى المتابعة للبقاء على اطلاع",
"providerModels.createNew.title": "إنشاء نموذج ذكاء اصطناعي مخصص",
"providerModels.item.config": "إعداد النموذج",
"providerModels.item.customModelCards.addNew": "إنشاء وإضافة نموذج {{id}}",
"providerModels.item.customModelCards.confirmDelete": "سيتم حذف هذا النموذج المخصص، ولن يمكن استعادته بعد الحذف، يرجى توخي الحذر.",
"providerModels.item.delete.confirm": "هل تؤكد حذف النموذج {{displayName}}؟",
"providerModels.item.customModelCards.confirmDelete": "أنت على وشك حذف هذا النموذج المخصص. لا يمكن استعادته بعد الحذف. يرجى المتابعة بحذر.",
"providerModels.item.delete.confirm": "هل أنت متأكد أنك تريد حذف النموذج {{displayName}}؟",
"providerModels.item.delete.success": "تم الحذف بنجاح",
"providerModels.item.delete.title": "حذف النموذج",
"providerModels.item.modelConfig.azureDeployName.extra": "الحقل المطلوب في Azure OpenAI",
"providerModels.item.modelConfig.azureDeployName.extra": "حقل يُستخدم للطلبات الفعلية في Azure OpenAI",
"providerModels.item.modelConfig.azureDeployName.placeholder": "يرجى إدخال اسم نشر النموذج في Azure",
"providerModels.item.modelConfig.azureDeployName.title": "اسم نشر النموذج",
"providerModels.item.modelConfig.deployName.extra": "سيتم استخدام هذا الحقل كمعرف نموذج عند إرسال الطلب",
"providerModels.item.modelConfig.deployName.extra": "سيُستخدم هذا الحقل كمعرف النموذج عند إرسال الطلبات",
"providerModels.item.modelConfig.deployName.placeholder": "يرجى إدخال اسم أو معرف النشر الفعلي للنموذج",
"providerModels.item.modelConfig.deployName.title": "اسم نشر النموذج",
"providerModels.item.modelConfig.displayName.placeholder": "يرجى إدخال اسم العرض للنموذج، مثل ChatGPT، GPT-4، إلخ",
"providerModels.item.modelConfig.displayName.placeholder": "يرجى إدخال اسم العرض للنموذج، مثل ChatGPT، GPT-4، إلخ.",
"providerModels.item.modelConfig.displayName.title": "اسم عرض النموذج",
"providerModels.item.modelConfig.files.extra": "تنفيذ تحميل الملفات الحالي هو مجرد حل Hack، يقتصر على التجربة الذاتية. يرجى الانتظار حتى يتم تنفيذ القدرة الكاملة لتحميل الملفات لاحقًا",
"providerModels.item.modelConfig.files.title": "دعم تحميل الملفات",
"providerModels.item.modelConfig.functionCall.extra": "هذا الإعداد سيفتح فقط قدرة النموذج على استخدام الأدوات، مما يسمح بإضافة مكونات إضافية من نوع الأدوات للنموذج. لكن ما إذا كان يمكن استخدام الأدوات فعليًا يعتمد تمامًا على النموذج نفسه، يرجى اختبار مدى قابليته للاستخدام",
"providerModels.item.modelConfig.files.extra": "تنفيذ رفع الملفات الحالي هو حل مؤقت، مخصص للتجربة الذاتية فقط. يرجى الانتظار حتى تتوفر إمكانيات رفع الملفات الكاملة في المستقبل.",
"providerModels.item.modelConfig.files.title": "دعم رفع الملفات",
"providerModels.item.modelConfig.functionCall.extra": "سيمكن هذا الإعداد النموذج من استخدام الأدوات، ولكن قدرة النموذج الفعلية على استخدامها تعتمد عليه بالكامل؛ يرجى الاختبار بنفسك.",
"providerModels.item.modelConfig.functionCall.title": "دعم استخدام الأدوات",
"providerModels.item.modelConfig.id.extra": "لا يمكن تعديله بعد الإنشاء، سيتم استخدامه كمعرف نموذج عند استدعاء الذكاء الاصطناعي",
"providerModels.item.modelConfig.id.extra": "لا يمكن تعديله بعد الإنشاء وسيُستخدم كمعرف النموذج عند استدعاء الذكاء الاصطناعي",
"providerModels.item.modelConfig.id.placeholder": "يرجى إدخال معرف النموذج، مثل gpt-4o أو claude-3.5-sonnet",
"providerModels.item.modelConfig.id.title": "معرف النموذج",
"providerModels.item.modelConfig.imageOutput.extra": "سيؤدي هذا الإعداد فقط إلى تفعيل قدرة النموذج على توليد الصور، وتعتمد النتيجة بالكامل على قدرات النموذج نفسه. يُرجى اختبار ما إذا كان النموذج يدعم توليد الصور بشكل فعّال.",
"providerModels.item.modelConfig.imageOutput.extra": "يُمكّن هذا الإعداد قدرة النموذج على توليد الصور فقط. الأداء الفعلي يعتمد على النموذج نفسه. يرجى اختباره.",
"providerModels.item.modelConfig.imageOutput.title": "يدعم توليد الصور",
"providerModels.item.modelConfig.modalTitle": "تكوين النموذج المخصص",
"providerModels.item.modelConfig.reasoning.extra": "هذا الإعداد سيفتح فقط قدرة النموذج على التفكير العميق، التأثير الفعلي يعتمد بالكامل على النموذج نفسه، يرجى اختبار ما إذا كان هذا النموذج يمتلك القدرة على التفكير العميق القابل للاستخدام",
"providerModels.item.modelConfig.reasoning.title": "يدعم التفكير العميق",
"providerModels.item.modelConfig.search.extra": "سيؤدي هذا الإعداد فقط إلى تفعيل قدرة محرك البحث المدمج في النموذج على الاتصال بالإنترنت. تعتمد إمكانية استخدام محرك البحث المدمج على قدرات النموذج نفسه. يُرجى اختبار ما إذا كان محرك البحث المدمج في النموذج يعمل بشكل فعّال.",
"providerModels.item.modelConfig.modalTitle": "إعداد النموذج المخصص",
"providerModels.item.modelConfig.reasoning.extra": "سيمكن هذا الإعداد قدرات التفكير العميق للنموذج. التأثير الفعلي يعتمد على النموذج. يرجى اختباره.",
"providerModels.item.modelConfig.reasoning.title": "دعم التفكير العميق",
"providerModels.item.modelConfig.search.extra": "يُمكّن هذا الإعداد قدرة البحث عبر الإنترنت المدمجة في النموذج. يعتمد الدعم على النموذج نفسه. يرجى اختباره.",
"providerModels.item.modelConfig.search.title": "يدعم البحث عبر الإنترنت",
"providerModels.item.modelConfig.tokens.extra": عيين الحد الأقصى لعدد الرموز المدعومة من قبل النموذج",
"providerModels.item.modelConfig.tokens.extra": حديد الحد الأقصى لعدد الرموز التي يدعمها النموذج",
"providerModels.item.modelConfig.tokens.title": "أقصى نافذة سياق",
"providerModels.item.modelConfig.tokens.unlimited": "غير محدود",
"providerModels.item.modelConfig.type.extra": "أنواع النماذج المختلفة تمتلك سيناريوهات استخدام وقدرات مميزة",
"providerModels.item.modelConfig.type.options.chat": "محادثة",
"providerModels.item.modelConfig.type.extra": "أنواع النماذج المختلفة لها استخدامات وقدرات مختلفة",
"providerModels.item.modelConfig.type.options.chat": "دردشة",
"providerModels.item.modelConfig.type.options.embedding": "تضمين",
"providerModels.item.modelConfig.type.options.image": "توليد الصور",
"providerModels.item.modelConfig.type.options.realtime": "محادثة فورية",
"providerModels.item.modelConfig.type.options.stt": "تحويل الصوت إلى نص",
"providerModels.item.modelConfig.type.options.text2music": "تحويل النص إلى موسيقى",
"providerModels.item.modelConfig.type.options.text2video": "تحويل النص إلى فيديو",
"providerModels.item.modelConfig.type.options.realtime": "دردشة فورية",
"providerModels.item.modelConfig.type.options.stt": "تحويل الكلام إلى نص",
"providerModels.item.modelConfig.type.options.text2music": "نص إلى موسيقى",
"providerModels.item.modelConfig.type.options.text2video": "نص إلى فيديو",
"providerModels.item.modelConfig.type.options.tts": "تحويل النص إلى كلام",
"providerModels.item.modelConfig.type.placeholder": "يرجى اختيار نوع النموذج",
"providerModels.item.modelConfig.type.title": "نوع النموذج",
"providerModels.item.modelConfig.video.extra": "سيؤدي هذا الإعداد فقط إلى تفعيل إعدادات التعرف على الفيديو داخل التطبيق. وتعتمد إمكانية التعرف على الفيديو بالكامل على قدرات النموذج نفسه. يُرجى اختبار ما إذا كان النموذج يدعم التعرف على الفيديو بشكل فعّال.",
"providerModels.item.modelConfig.video.extra": "يُمكّن هذا الإعداد تكوين التعرف على الفيديو داخل التطبيق. يعتمد الدعم على النموذج نفسه. يرجى اختباره.",
"providerModels.item.modelConfig.video.title": "يدعم التعرف على الفيديو",
"providerModels.item.modelConfig.vision.extra": "سيؤدي هذا التكوين إلى فتح إعدادات تحميل الصور في التطبيق، ما إذا كان يدعم التعرف يعتمد بالكامل على النموذج نفسه، يرجى اختبار قابلية استخدام التعرف البصري لهذا النموذج بنفسك",
"providerModels.item.modelConfig.vision.title": "دعم التعرف البصري",
"providerModels.item.modelConfig.vision.extra": "يُمكّن هذا الإعداد فقط من رفع الصور داخل التطبيق. يعتمد دعم التعرف على الصور على النموذج نفسه. يرجى اختباره.",
"providerModels.item.modelConfig.vision.title": "دعم الرؤية",
"providerModels.item.pricing.image": "${{amount}}/صورة",
"providerModels.item.pricing.inputCharts": "${{amount}}/M حرف",
"providerModels.item.pricing.inputCharts": "${{amount}}/مليون حرف",
"providerModels.item.pricing.inputMinutes": "${{amount}}/دقيقة",
"providerModels.item.pricing.inputTokens": "إدخال ${{amount}}/م",
"providerModels.item.pricing.outputTokens": "إخراج ${{amount}}/م",
"providerModels.item.releasedAt": "صدر في {{releasedAt}}",
"providerModels.item.pricing.inputTokens": "المدخلات ${{amount}}/مليون",
"providerModels.item.pricing.outputTokens": "المخرجات ${{amount}}/مليون",
"providerModels.item.releasedAt": "تم الإصدار في {{releasedAt}}",
"providerModels.list.addNew": "إضافة نموذج",
"providerModels.list.disabled": "غير مفعل",
"providerModels.list.disabled": "معطل",
"providerModels.list.disabledActions.showMore": "عرض الكل",
"providerModels.list.disabledActions.sort": "طريقة الترتيب",
"providerModels.list.disabledActions.sortAlphabetical": "ترتيب أبجديًا",
"providerModels.list.disabledActions.sort": "ترتيب حسب",
"providerModels.list.disabledActions.sortAlphabetical": "ترتيب أبجدي",
"providerModels.list.disabledActions.sortAlphabeticalDesc": "ترتيب أبجدي عكسي",
"providerModels.list.disabledActions.sortDefault": "الترتيب الافتراضي",
"providerModels.list.disabledActions.sortReleasedAt": "ترتيب حسب أقدم تاريخ إصدار",
"providerModels.list.disabledActions.sortReleasedAtDesc": "ترتيب حسب أحدث تاريخ إصدار",
"providerModels.list.empty.desc": "يرجى إنشاء نموذج مخصص أو سحب نموذج للبدء في الاستخدام",
"providerModels.list.empty.desc": "يرجى إنشاء نموذج مخصص أو سحب نموذج للبدء.",
"providerModels.list.empty.title": "لا توجد نماذج متاحة",
"providerModels.list.enabled": "مفعل",
"providerModels.list.enabledActions.disableAll": "تعطيل الكل",
"providerModels.list.enabledActions.enableAll": "تفعيل الكل",
"providerModels.list.enabledActions.sort": "ترتيب النموذج حسب التخصيص",
"providerModels.list.enabledEmpty": "لا توجد نماذج مفعلة، يرجى تفعيل النماذج المفضلة لديك من القائمة أدناه~",
"providerModels.list.fetcher.clear": "مسح النماذج المستخرجة",
"providerModels.list.fetcher.fetch": "الحصول على قائمة النماذج",
"providerModels.list.fetcher.fetching": "جارٍ الحصول على قائمة النماذج...",
"providerModels.list.enabledActions.sort": "ترتيب النماذج المخصصة",
"providerModels.list.enabledEmpty": "لا توجد نماذج مفعلة. يرجى تفعيل النماذج المفضلة من القائمة أدناه~",
"providerModels.list.fetcher.clear": "مسح النماذج المسحوبة",
"providerModels.list.fetcher.fetch": "جلب النماذج",
"providerModels.list.fetcher.fetching": "جارٍ جلب قائمة النماذج...",
"providerModels.list.fetcher.latestTime": "آخر تحديث: {{time}}",
"providerModels.list.fetcher.noLatestTime": "لم يتم الحصول على القائمة بعد",
"providerModels.list.noModelsInCategory": "لا توجد نماذج مفعلة في هذا التصنيف",
"providerModels.list.resetAll.conform": "هل أنت متأكد من إعادة تعيين جميع التعديلات على النموذج الحالي؟ بعد إعادة التعيين، ستعود قائمة النماذج الحالية إلى الحالة الافتراضية",
"providerModels.list.fetcher.noLatestTime": "لم يتم جلب قائمة النماذج بعد",
"providerModels.list.noModelsInCategory": "لا توجد نماذج مفعلة في هذه الفئة",
"providerModels.list.resetAll.conform": "هل أنت متأكد أنك تريد إعادة تعيين جميع التعديلات على النموذج الحالي؟ بعد إعادة التعيين، ستعود قائمة النماذج إلى حالتها الافتراضية.",
"providerModels.list.resetAll.success": "تمت إعادة التعيين بنجاح",
"providerModels.list.resetAll.title": "إعادة تعيين جميع التعديلات",
"providerModels.list.search": "ابحث عن نموذج...",
"providerModels.list.search": "البحث عن نماذج...",
"providerModels.list.searchResult": "تم العثور على {{count}} نموذج",
"providerModels.list.title": "قائمة النماذج",
"providerModels.list.total": "إجمالي {{count}} نموذج متاح",
"providerModels.searchNotFound": "لم يتم العثور على نتائج البحث",
"providerModels.list.total": "{{count}} نموذج متاح",
"providerModels.searchNotFound": "لم يتم العثور على نتائج",
"providerModels.tabs.all": "الكل",
"providerModels.tabs.chat": "الدردشة",
"providerModels.tabs.embedding": "التضمين",
"providerModels.tabs.chat": "دردشة",
"providerModels.tabs.embedding": "تضمين",
"providerModels.tabs.image": "صورة",
"providerModels.tabs.stt": "تحويل الكلام إلى نص",
"providerModels.tabs.tts": "تحويل النص إلى كلام",
"sortModal.success": "تم تحديث الترتيب بنجاح",
"sortModal.title": "ترتيب مخصص",
"sortModal.update": "تحديث",
"updateAiProvider.confirmDelete": "سيتم حذف مزود AI هذا، ولن يمكن استعادته بعد الحذف، هل تؤكد الحذف؟",
"updateAiProvider.confirmDelete": "أنت على وشك حذف مزود الذكاء الاصطناعي هذا. لا يمكن استعادته بعد الحذف. هل أنت متأكد من الحذف؟",
"updateAiProvider.deleteSuccess": "تم الحذف بنجاح",
"updateAiProvider.tooltip": "تحديث التكوين الأساسي للمزود",
"updateAiProvider.tooltip": "تحديث إعدادات المزود الأساسية",
"updateAiProvider.updateSuccess": "تم التحديث بنجاح",
"updateCustomAiProvider.title": "تحديث إعدادات مزود الذكاء الاصطناعي المخصص",
"vertexai.apiKey.desc": "أدخل مفاتيح Vertex AI الخاصة بك",
"vertexai.apiKey.placeholder": "{ \"type\": \"service_account\", \"project_id\": \"xxx\", \"private_key_id\": ... }",
"vertexai.apiKey.title": "مفاتيح Vertex AI",
"vertexai.region.desc": "اختر منطقة خدمة Vertex AI. بعض النماذج مثل Gemini 2.5 متاحة فقط في مناطق محددة (مثل global)",
"vertexai.region.desc": "اختر المنطقة لخدمة Vertex AI. بعض النماذج مثل Gemini 2.5 متاحة فقط في مناطق محددة (مثل global)",
"vertexai.region.placeholder": "اختر المنطقة",
"vertexai.region.title": "منطقة Vertex AI",
"zeroone.title": "01.AI الأشياء الصغرى",
"zeroone.title": "01.AI Zero One Everything",
"zhipu.title": "Zhipu"
}
+726 -1217
View File
File diff suppressed because it is too large Load Diff
+22 -22
View File
@@ -1,36 +1,36 @@
{
"consent.buttons.accept": "موافقة",
"consent.buttons.accept": "السماح",
"consent.buttons.deny": "رفض",
"consent.description": "تطبيق {{clientName}} يطلب إذن حسابك",
"consent.error.sessionInvalid.message": "جلسة التفويض منتهية أو غير صالحة، يرجى إعادة بدء عملية التفويض.",
"consent.error.sessionInvalid.title": "جلسة التفويض غير صالحة",
"consent.description": "يطلب التطبيق {{clientName}} إذن الوصول إلى حسابك",
"consent.error.sessionInvalid.message": "انتهت صلاحية جلسة التفويض أو أنها غير صالحة. يرجى إعادة بدء عملية التفويض.",
"consent.error.sessionInvalid.title": "جلسة تفويض غير صالحة",
"consent.error.title": "حدث خطأ",
"consent.error.unknown.message": "حدث خطأ غير معروف أثناء الحصول على تفاصيل التفويض",
"consent.error.unsupportedInteraction.message": "نوع التفاعل غير مدعوم: {promptName}",
"consent.error.unknown.message": "حدث خطأ غير معروف أثناء تحميل تفاصيل التفويض.",
"consent.error.unsupportedInteraction.message": "نوع التفاعل غير مدعوم: {{promptName}}",
"consent.error.unsupportedInteraction.title": "نوع التفاعل غير مدعوم",
"consent.permissionsTitle": "طلب الأذونات التالية:",
"consent.redirectUri": "سيتم إعادة التوجيه إلى بعد نجاح التفويض",
"consent.permissionsTitle": "يطلب الأذونات التالية:",
"consent.redirectUri": "سيتم إعادة التوجيه بعد إتمام التفويض بنجاح",
"consent.redirecting": "تم التفويض بنجاح، جارٍ إعادة التوجيه...",
"consent.scope.email": "الوصول إلى عنوان بريدك الإلكتروني",
"consent.scope.offline_access": "السماح للتطبيق بالوصول إلى بياناتك",
"consent.scope.openid": "استخدام حسابك في LobeChat للتحقق من الهوية",
"consent.scope.profile": "الوصول إلى معلومات ملفك الشخصي الأساسية (الاسم، الصورة، إلخ)",
"consent.scope.sync-read": "قراءة بيانات المزامنة الخاصة بك",
"consent.scope.sync-write": "كتابة وتحديث بيانات المزامنة الخاصة بك",
"consent.scope.openid": "تسجيل الدخول باستخدام حساب LobeHub الخاص بك",
"consent.scope.profile": "الوصول إلى معلومات ملفك الشخصي الأساسية (الاسم، الصورة الرمزية، إلخ)",
"consent.scope.sync-read": "قراءة بياناتك المتزامنة",
"consent.scope.sync-write": "كتابة وتحديث بياناتك المتزامنة",
"consent.title": "تفويض {{clientName}}",
"error.backToHome": "العودة إلى الصفحة الرئيسية",
"error.desc": "فشل تفويض OAuth، سبب الفشل: {{reason}}",
"error.reason.internal_error": "خطأ في الخادم",
"error.reason.invalid_request": "معلمات طلب غير صالحة",
"error.desc": "فشل تفويض OAuth، السبب: {{reason}}",
"error.reason.internal_error": "خطأ داخلي في الخادم",
"error.reason.invalid_request": "معلمات الطلب غير صالحة",
"error.title": "فشل التفويض",
"handoff.desc.processing": "التطبيق يقوم بمعالجة التفويض، سيتم الانتقال إلى الصفحة التالية قريبًا...",
"handoff.desc.success": "تمت محاولة فتح التطبيق على سطح المكتب. إذا لم يفتح التطبيق تلقائيًا، يرجى التبديل يدويًا. يمكنك إغلاق نافذة المتصفح هذه لاحقًا.",
"handoff.title.processing": "جارٍ معالجة التفويض...",
"handoff.title.success": "تم الانتهاء من التفويض",
"handoff.desc.processing": "يقوم التطبيق بمعالجة التفويض وسيتم إعادة التوجيه إلى الصفحة التالية قريبًا...",
"handoff.desc.success": "تمت محاولة فتح التطبيق على سطح المكتب. إذا لم يتم فتحه تلقائيًا، يرجى التبديل يدويًا. يمكنك إغلاق نافذة المتصفح لاحقًا.",
"handoff.title.processing": "جارٍ تنفيذ التفويض...",
"handoff.title.success": "تم التفويض بنجاح",
"login.button": "تأكيد تسجيل الدخول",
"login.description": "التطبيق {{clientName}} يطلب استخدام حسابك لتسجيل الدخول",
"login.description": "يطلب التطبيق {{clientName}} استخدام حسابك لتسجيل الدخول",
"login.title": "تسجيل الدخول إلى {{clientName}}",
"login.userWelcome": "مرحبًا بعودتك،",
"success.subTitle": "لقد قمت بتفويض التطبيق للوصول إلى حسابك بنجاح، يمكنك الآن إغلاق هذه الصفحة",
"login.userWelcome": "مرحبًا بعودتك، ",
"success.subTitle": "لقد قمت بتفويض التطبيق للوصول إلى حسابك بنجاح. يمكنك الآن إغلاق هذه الصفحة.",
"success.title": "تم التفويض بنجاح"
}
+46 -46
View File
@@ -1,5 +1,5 @@
{
"back": "الخطوة السابقة",
"back": "رجوع",
"finish": "ابدأ الآن",
"interests.area.business": "الأعمال والاستراتيجية",
"interests.area.coding": "البرمجة والتطوير",
@@ -8,59 +8,59 @@
"interests.area.marketing": "التسويق والترويج",
"interests.area.other": "مجالات أخرى",
"interests.area.product": "المنتجات والإدارة",
"interests.area.sales": "المبيعات والعملاء",
"interests.area.sales": "المبيعات وخدمة العملاء",
"interests.area.writing": "إنشاء المحتوى",
"interests.hint": "يمكنك تعديل هذا في الإعدادات في أي وقت",
"interests.placeholder": "يرجى إدخال المجالات التي تهمك...",
"interests.hint": "يمكنك تغيير هذا في أي وقت من الإعدادات",
"interests.placeholder": "أدخل اهتماماتك...",
"interests.title": "هل يمكنك إخباري بالمجالات التي تهمك؟",
"interests.title2": "ساعدني في تكوين انطباع أولي عنك ~",
"interests.title3": "خذ وقتك، سأفهمك أكثر مع مرور الوقت",
"modeSelection.desc": "اختر نمط الاستخدام الذي يناسبك",
"modeSelection.hint": "يمكنك تغييره في الإعدادات في أي وقت",
"modeSelection.lite.desc": "مثالي للمحادثات اليومية، الأسئلة والأجوبة، والمساعدة الخفيفة في العمل وتجربة النماذج",
"modeSelection.lite.subtitle": "خفيف ونقي، يفضل التعاون الفعال مع مساعد شامل واحد. يمكنك التبديل بين النماذج الشائعة في أي وقت للحفاظ على أفضل حالة ذهنية.",
"modeSelection.lite.title": "Lite خفيف",
"modeSelection.pro.desc": "يحتوي على مفهوم سير العمل، ويسعى للتعاون العميق والتخصيص",
"modeSelection.pro.subtitle": "وضع الإنتاجية الاحترافية. شركة فردية، تعاون بين عدة مساعدين، تخصيص عميق للنماذج وسير العمل، لبناء مركزك الذكي الخاص.",
"modeSelection.pro.title": "Pro احترافي",
"modeSelection.title": "ما هو نمط العمل الذي تفضله؟",
"modeSelection.title2": "خفيف أم احترافي؟ القرار لك!",
"modeSelection.title3": "أخبرني، وسأخصصه لك خصيصًا~",
"next": "الخطوة التالية",
"interests.title2": يساعدني هذا في تكوين انطباع أولي عنك~",
"interests.title3": "خذ وقتك، وسأتعرف عليك أكثر فأكثر",
"modeSelection.desc": "اختر الوضع الذي يناسبك",
"modeSelection.hint": "يمكنك تغييره في أي وقت من الإعدادات",
"modeSelection.lite.desc": "مثالي للمحادثات اليومية، الأسئلة والأجوبة، الإنتاجية الخفيفة، وتجربة النماذج",
"modeSelection.lite.subtitle": "خفيف ومركّز — مثالي للتعاون الفعّال مع وكيل شامل واحد. يمكنك التبديل بين النماذج الشائعة في أي وقت للحفاظ على أفضل حالة تفكير.",
"modeSelection.lite.title": "الوضع الخفيف",
"modeSelection.pro.desc": "مصمم للمستخدمين الذين يركزون على سير العمل ويبحثون عن تعاون عميق وتخصيص متقدم",
"modeSelection.pro.subtitle": "وضع الإنتاجية الاحترافية. قم بإدارة شركة فردية، وتعاون مع عدة وكلاء، وخصص النماذج وسير العمل لبناء مركز ذكي خاص بك.",
"modeSelection.pro.title": "الوضع الاحترافي",
"modeSelection.title": "ما هو وضع العمل الذي تفضله؟",
"modeSelection.title2": "خفيف أم احترافي القرار لك!",
"modeSelection.title3": "أخبرني، لأتمكن من تخصيصه لك~",
"next": "التالي",
"proSettings.connectors.title": "اربط أدواتك المفضلة",
"proSettings.devMode.title": "وضع المطور",
"proSettings.model.title": "النموذج الافتراضي الذي يستخدمه الوكيل",
"proSettings.title": "يمكنك إعداد بعض الخيارات المتقدمة مسبقًا",
"proSettings.title2": "جرّب ربط بعض الأدوات الشائعة",
"proSettings.title3": "لنستعد للعمل بكفاءة عالية!",
"responseLanguage.auto": "تلقائي (يتبع لغة النظام)",
"responseLanguage.desc": "اختر اللغة التي يستخدمها المساعد الذكي في الردود",
"responseLanguage.hint": "بعد اختيار اللغة، سيستخدم المساعد هذه اللغة في الردود، كما سيتم تغيير لغة الواجهة تلقائيًا",
"responseLanguage.title": "ما اللغة التي نستخدمها للتواصل؟",
"responseLanguage.title2": "ابدأ باللغة، لبناء فهم حقيقي.",
"responseLanguage.title3": "دعني أتكلم بوضوح، وأفهمك تمامًا ~",
"telemetry.agreement": "جميع البيانات التي يتم جمعها مجهولة الهوية وتُستخدم فقط لتحسين تجربة المنتج. من خلال المتابعة، فإنك تؤكد أنك قرأت ووافقت على <terms>الشروط والأحكام</terms> و<privacy>سياسة الخصوصية</privacy>.",
"telemetry.desc": "أنا مساعدك الذكي، دائمًا معك للتفكير، الإبداع، وإدارة فريقك من الوكلاء.",
"proSettings.model.title": "النموذج الافتراضي المستخدم من قبل الوكيل",
"proSettings.title": "قم بإعداد الخيارات المتقدمة مسبقًا",
"proSettings.title2": "جرّب ربط بعض الأدوات الشائعة~",
"proSettings.title3": "لنستعد للعمل بكفاءة!",
"responseLanguage.auto": "تلقائي (وفقًا للغة النظام)",
"responseLanguage.desc": "اختر لغة ردود الوكيل",
"responseLanguage.hint": "بعد اختيار اللغة، ستُستخدم هذه اللغة في ردود الذكاء الاصطناعي، كما ستتزامن لغة الواجهة",
"responseLanguage.title": "ما اللغة التي تود أن نتواصل بها؟",
"responseLanguage.title2": "ابدأ باللغة، وابنِ فهماً حقيقياً.",
"responseLanguage.title3": "دعني أتحدث بوضوح وأفهمك بشكل أفضل~",
"telemetry.agreement": "جميع البيانات التي يتم جمعها مجهولة وتُستخدم فقط لتحسين تجربة المنتج. بمتابعتك، فإنك تؤكد أنك تفهم وتوافق على <terms>الشروط والأحكام</terms> و<privacy>سياسة الخصوصية</privacy>.",
"telemetry.desc": "أنا مساعدك الشخصي — هنا لأساعدك في التفكير، الإبداع، وإدارة الوكلاء والمجموعات.",
"telemetry.helpImprove": "ساعد في تحسين {{appName}}",
"telemetry.next": "لنبدأ",
"telemetry.privacy": "سياسة الخصوصية",
"telemetry.rows.collaborate.desc": "هنا، يعمل الناس والوكلاء معًا، يتعلمون ويتطورون، لتتدفق الإنتاجية بأكثر الطرق طبيعية.",
"telemetry.rows.collaborate.title": "تعاون · تطور ذكي مشترك",
"telemetry.rows.create.desc": "فكر، فأنشئ. بمجرد أن تخطر الفكرة، يولد الوكيل.",
"telemetry.rows.create.title": "إبداع · الإلهام يتحقق فورًا",
"telemetry.rows.evolve.desc": "كل تفاعل يجعلني أفهمك أكثر. ليس فقط في الرد، بل في الفهم أيضًا.",
"telemetry.rows.evolve.title": "تطور · كلما استخدمتني، فهمتك أكثر",
"telemetry.rows.privacy.desc": "نستخدم بيانات مجهولة لتحسين تجربة {{appName}} باستمرار. وبالطبع، يمكنك تعديل هذا الخيار في إعدادات الخصوصية في أي وقت.",
"telemetry.rows.privacy.title": "لنجعل {{appName}} أفضل معًا",
"telemetry.rows.collaborate.desc": "هنا، يعمل الناس والوكلاء معًا، يتعلمون ويتطورون — مما يجعل الإنتاجية تتدفق بشكل طبيعي.",
"telemetry.rows.collaborate.title": "تعاون · تطوّر بذكاء",
"telemetry.rows.create.desc": "من الفكرة إلى التنفيذ. فقط فكّر، وسيولد وكيلك.",
"telemetry.rows.create.title": "أنشئ · حوّل الإلهام إلى واقع",
"telemetry.rows.evolve.desc": "كل تفاعل يساعدني على فهمك بشكل أفضل — ليس فقط في الرد، بل في الفهم أيضًا.",
"telemetry.rows.evolve.title": "تطوّر · كلما استخدمتني أكثر، فهمتك أكثر",
"telemetry.rows.privacy.desc": "نستخدم بيانات مجهولة لتحسين التجربة باستمرار. يمكنك تغيير هذا في أي وقت من تفضيلات الخصوصية.",
"telemetry.rows.privacy.title": "لنُحسّن {{appName}} معًا",
"telemetry.terms": "شروط الخدمة",
"telemetry.title": "مرحبًا، أنا {{name}}",
"telemetry.title2": "سعيد بلقائك ~",
"telemetry.title3": "Loooobe! هيا نبدأ!",
"telemetry.title2": "تشرفت بلقائك~",
"telemetry.title3": "لووووب! لنبدأ!",
"title": "مرحبًا بك في {{appName}}",
"username.desc": "أخبرنا كيف نناديك",
"username.hint": "يمكنك تغييره في الإعدادات في أي وقت",
"username.placeholder": "يرجى إدخال اسمك...",
"username.title": "بالمناسبة، كيف أناديك؟",
"username.title2": "دعنا نتعرف عليك أولًا!",
"username.title3": "حتى نصبح أكثر ألفة في محادثاتنا القادمة ~"
"username.desc": "أخبرنا كيف نُناديك",
"username.hint": "يمكنك تغييره في أي وقت من الإعدادات",
"username.placeholder": "أدخل اسمك...",
"username.title": "بالمناسبة، ماذا يجب أن أُسميك؟",
"username.title2": "دعنا نتعرف على بعضنا أولاً!",
"username.title3": "هكذا يمكننا التحدث بشكل طبيعي أكثر من الآن فصاعدًا~"
}
+328 -274
View File
@@ -1,100 +1,142 @@
{
"arguments.title": "قائمة المعلمات",
"arguments.title": "المعلمات",
"builtins.lobe-agent-builder.apiName.getAvailableModels": "الحصول على النماذج المتاحة",
"builtins.lobe-agent-builder.apiName.getAvailableTools": "الحصول على الأدوات المتاحة",
"builtins.lobe-agent-builder.apiName.getAvailableTools": "الحصول على المهارات المتاحة",
"builtins.lobe-agent-builder.apiName.getConfig": "الحصول على الإعدادات",
"builtins.lobe-agent-builder.apiName.getMeta": "الحصول على البيانات الوصفية",
"builtins.lobe-agent-builder.apiName.getPrompt": "الحصول على التعليمات النظامية",
"builtins.lobe-agent-builder.apiName.searchMarketTools": "البحث في سوق الإضافات",
"builtins.lobe-agent-builder.apiName.searchOfficialTools": "البحث عن الأدوات الرسمية",
"builtins.lobe-agent-builder.apiName.getPrompt": "الحصول على موجه النظام",
"builtins.lobe-agent-builder.apiName.searchMarketTools": "البحث في سوق المهارات",
"builtins.lobe-agent-builder.apiName.searchOfficialTools": "البحث في المهارات الرسمية",
"builtins.lobe-agent-builder.apiName.setModel": "تعيين النموذج",
"builtins.lobe-agent-builder.apiName.setOpeningMessage": "تعيين رسالة البداية",
"builtins.lobe-agent-builder.apiName.setOpeningQuestions": "تعيين أسئلة البداية",
"builtins.lobe-agent-builder.apiName.togglePlugin": بديل الإضافة",
"builtins.lobe-agent-builder.apiName.setOpeningQuestions": "تعيين الأسئلة الافتتاحية",
"builtins.lobe-agent-builder.apiName.togglePlugin": فعيل/تعطيل المهارة",
"builtins.lobe-agent-builder.apiName.updateChatConfig": "تحديث إعدادات المحادثة",
"builtins.lobe-agent-builder.apiName.updateConfig": "تحديث الإعدادات",
"builtins.lobe-agent-builder.apiName.updateMeta": "تحديث البيانات الوصفية",
"builtins.lobe-agent-builder.apiName.updatePrompt": "تحديث التعليمات النظامية",
"builtins.lobe-agent-builder.title": "منشئ الوكيل",
"builtins.lobe-agent-builder.apiName.updatePrompt": "تحديث موجه النظام",
"builtins.lobe-agent-builder.title": "خبير بناء الوكلاء",
"builtins.lobe-cloud-sandbox.apiName.editLocalFile": "تعديل الملف",
"builtins.lobe-cloud-sandbox.apiName.executeCode": "تنفيذ الكود",
"builtins.lobe-cloud-sandbox.apiName.exportFile": "تصدير الملف",
"builtins.lobe-cloud-sandbox.apiName.getCommandOutput": "الحصول على ناتج الأمر",
"builtins.lobe-cloud-sandbox.apiName.globLocalFiles": "بحث شامل في الملفات",
"builtins.lobe-cloud-sandbox.apiName.grepContent": "البحث في المحتوى",
"builtins.lobe-cloud-sandbox.apiName.killCommand": "إيقاف الأمر",
"builtins.lobe-cloud-sandbox.apiName.listLocalFiles": "عرض الملفات",
"builtins.lobe-cloud-sandbox.apiName.moveLocalFiles": "نقل الملفات",
"builtins.lobe-cloud-sandbox.apiName.readLocalFile": "قراءة محتوى الملف",
"builtins.lobe-cloud-sandbox.apiName.renameLocalFile": "إعادة تسمية",
"builtins.lobe-cloud-sandbox.apiName.runCommand": "تشغيل الأمر",
"builtins.lobe-cloud-sandbox.apiName.searchLocalFiles": "البحث في الملفات",
"builtins.lobe-cloud-sandbox.apiName.writeLocalFile": "كتابة الملف",
"builtins.lobe-cloud-sandbox.title": "بيئة سحابية",
"builtins.lobe-group-agent-builder.apiName.getAvailableModels": "الحصول على النماذج المتاحة",
"builtins.lobe-group-agent-builder.apiName.installPlugin": "تثبيت الإضافة",
"builtins.lobe-group-agent-builder.apiName.installPlugin": "تثبيت المهارة",
"builtins.lobe-group-agent-builder.apiName.inviteAgent": "دعوة عضو",
"builtins.lobe-group-agent-builder.apiName.removeAgent": "إزالة العضو",
"builtins.lobe-group-agent-builder.apiName.searchMarketTools": "البحث في سوق الإضافات",
"builtins.lobe-group-agent-builder.apiName.updateAgentConfig": "تحديث إعدادات الوكيل",
"builtins.lobe-group-agent-builder.apiName.updatePrompt": "تحديث التعليمات النظامية",
"builtins.lobe-group-agent-builder.title": "منشئ الوكلاء الجماعي",
"builtins.lobe-group-management.apiName.broadcast": "إرسال رسالة للجميع",
"builtins.lobe-group-management.apiName.createAgent": "إضافة عضو إلى الفريق",
"builtins.lobe-group-agent-builder.apiName.removeAgent": "إزالة عضو",
"builtins.lobe-group-agent-builder.apiName.searchMarketTools": "البحث في سوق المهارات",
"builtins.lobe-group-agent-builder.apiName.updateAgentConfig": "تحديث إعدادات العضو",
"builtins.lobe-group-agent-builder.apiName.updatePrompt": "تحديث موجه النظام",
"builtins.lobe-group-agent-builder.title": "خبير بناء المجموعات",
"builtins.lobe-group-management.apiName.broadcast": "تحدث الجميع",
"builtins.lobe-group-management.apiName.createAgent": "إضافة عضو للمجموعة",
"builtins.lobe-group-management.apiName.createWorkflow": "تخطيط سير العمل",
"builtins.lobe-group-management.apiName.executeTask": "تنفيذ المهمة",
"builtins.lobe-group-management.apiName.getAgentInfo": "الحصول على معلومات العضو",
"builtins.lobe-group-management.apiName.interrupt": "مقاطعة المهمة",
"builtins.lobe-group-management.apiName.inviteAgent": "دعوة عضو",
"builtins.lobe-group-management.apiName.removeAgent": "إزالة عضو",
"builtins.lobe-group-management.apiName.searchAgent": "البحث عن خبير ذي صلة",
"builtins.lobe-group-management.apiName.speak": عيين عضو للتحدث",
"builtins.lobe-group-management.apiName.searchAgent": "البحث عن خبراء ذوي صلة",
"builtins.lobe-group-management.apiName.speak": حديد المتحدث",
"builtins.lobe-group-management.apiName.summarize": "تلخيص المحادثة",
"builtins.lobe-group-management.apiName.vote": "بدء تصويت",
"builtins.lobe-group-management.title": "تنسيق الفريق",
"builtins.lobe-group-management.apiName.vote": "بدء التصويت",
"builtins.lobe-group-management.inspector.broadcast.title": "الوكلاء المتحدثون:",
"builtins.lobe-group-management.inspector.speak.title": "المتحدث المحدد:",
"builtins.lobe-group-management.title": "منسق المجموعة",
"builtins.lobe-gtd.apiName.clearTodos": "مسح المهام",
"builtins.lobe-gtd.apiName.clearTodos.modeAll": "الكل",
"builtins.lobe-gtd.apiName.clearTodos.modeCompleted": "المكتملة",
"builtins.lobe-gtd.apiName.clearTodos.result": "تم مسح المهام <mode>{{mode}}</mode>",
"builtins.lobe-gtd.apiName.completeTodos": "إكمال المهام",
"builtins.lobe-gtd.apiName.createPlan": "إنشاء خطة",
"builtins.lobe-gtd.apiName.createPlan.result": "تم إنشاء الخطة: <goal>{{goal}}</goal>",
"builtins.lobe-gtd.apiName.createTodos": "إنشاء مهام",
"builtins.lobe-gtd.apiName.execTask": "تنفيذ المهمة",
"builtins.lobe-gtd.apiName.execTask.completed": "تم إنشاء المهمة: ",
"builtins.lobe-gtd.apiName.execTask.loading": "جارٍ إنشاء المهمة: ",
"builtins.lobe-gtd.apiName.execTasks": "تنفيذ المهام",
"builtins.lobe-gtd.apiName.removeTodos": "حذف المهام",
"builtins.lobe-gtd.apiName.updatePlan": "تحديث الخطة",
"builtins.lobe-gtd.apiName.updatePlan.completed": "مكتملة",
"builtins.lobe-gtd.apiName.updatePlan.modified": "تم التعديل",
"builtins.lobe-gtd.apiName.updateTodos": "تحديث المهام",
"builtins.lobe-gtd.title": "أداة GTD",
"builtins.lobe-knowledge-base.apiName.readKnowledge": "قراءة محتوى قاعدة المعرفة",
"builtins.lobe-knowledge-base.apiName.searchKnowledgeBase": "البحث في قاعدة المعرفة",
"builtins.lobe-knowledge-base.title": "قاعدة المعرفة",
"builtins.lobe-local-system.apiName.editLocalFile": "تحرير الملف",
"builtins.lobe-local-system.apiName.getCommandOutput": "الحصول على مخرجات الكود",
"builtins.lobe-local-system.apiName.globLocalFiles": "البحث عن الملفات",
"builtins.lobe-gtd.title": "أدوات المهام",
"builtins.lobe-knowledge-base.apiName.readKnowledge": "قراءة محتوى المكتبة",
"builtins.lobe-knowledge-base.apiName.searchKnowledgeBase": "البحث في المكتبة",
"builtins.lobe-knowledge-base.inspector.andMoreFiles": "و{{count}} ملفًا آخر",
"builtins.lobe-knowledge-base.inspector.noResults": "لا توجد نتائج",
"builtins.lobe-knowledge-base.title": "المكتبة",
"builtins.lobe-local-system.apiName.editLocalFile": "تعديل الملف",
"builtins.lobe-local-system.apiName.getCommandOutput": "الحصول على ناتج الأمر",
"builtins.lobe-local-system.apiName.globLocalFiles": "بحث شامل في الملفات",
"builtins.lobe-local-system.apiName.grepContent": "البحث في المحتوى",
"builtins.lobe-local-system.apiName.killCommand": "إيقاف تنفيذ الكود",
"builtins.lobe-local-system.apiName.listLocalFiles": "عرض قائمة الملفات",
"builtins.lobe-local-system.apiName.killCommand": "إيقاف الأمر",
"builtins.lobe-local-system.apiName.listLocalFiles": "عرض الملفات",
"builtins.lobe-local-system.apiName.moveLocalFiles": "نقل الملفات",
"builtins.lobe-local-system.apiName.readLocalFile": "قراءة محتوى الملف",
"builtins.lobe-local-system.apiName.renameLocalFile": "إعادة تسمية",
"builtins.lobe-local-system.apiName.runCommand": نفيذ الكود",
"builtins.lobe-local-system.apiName.runCommand": شغيل الأمر",
"builtins.lobe-local-system.apiName.searchLocalFiles": "البحث في الملفات",
"builtins.lobe-local-system.apiName.writeLocalFile": "كتابة إلى الملف",
"builtins.lobe-local-system.apiName.writeLocalFile": "كتابة الملف",
"builtins.lobe-local-system.inspector.noResults": "لا توجد نتائج",
"builtins.lobe-local-system.inspector.rename.result": "<old>{{oldName}}</old> → <new>{{newName}}</new>",
"builtins.lobe-local-system.title": "النظام المحلي",
"builtins.lobe-page-agent.apiName.batchUpdate": "تحديث الدُفعة للعُقد",
"builtins.lobe-page-agent.apiName.batchUpdate": "تحديث جماعي للعقد",
"builtins.lobe-page-agent.apiName.compareSnapshots": "مقارنة اللقطات",
"builtins.lobe-page-agent.apiName.convertToList": "تحويل إلى قائمة",
"builtins.lobe-page-agent.apiName.createNode": "إنشاء عقدة",
"builtins.lobe-page-agent.apiName.cropImage": "اقتصاص الصورة",
"builtins.lobe-page-agent.apiName.cropImage": "قص الصورة",
"builtins.lobe-page-agent.apiName.deleteNode": "حذف العقدة",
"builtins.lobe-page-agent.apiName.deleteSnapshot": "حذف اللقطة",
"builtins.lobe-page-agent.apiName.deleteTableColumn": "حذف عمود الجدول",
"builtins.lobe-page-agent.apiName.deleteTableRow": "حذف صف الجدول",
"builtins.lobe-page-agent.apiName.duplicateNode": "نسخ العقدة",
"builtins.lobe-page-agent.apiName.editTitle": "تحرير عنوان المستند",
"builtins.lobe-page-agent.apiName.indentListItem": "زيادة المسافة البادئة لعنصر القائمة",
"builtins.lobe-page-agent.apiName.initPage": "تهيئة المستند",
"builtins.lobe-page-agent.apiName.insertTableColumn": "إدراج عمود في الجدول",
"builtins.lobe-page-agent.apiName.insertTableRow": "إدراج صف في الجدول",
"builtins.lobe-page-agent.apiName.editTitle": "إعادة تسمية عنوان الصفحة",
"builtins.lobe-page-agent.apiName.editTitle.result": "تمت إعادة التسمية إلى \"<title>{{title}}</title>\"",
"builtins.lobe-page-agent.apiName.getPageContent": "الحصول على هيكل المستند",
"builtins.lobe-page-agent.apiName.indentListItem": "زيادة المسافة البادئة",
"builtins.lobe-page-agent.apiName.initPage": "بدء كتابة المحتوى",
"builtins.lobe-page-agent.apiName.initPage.chars": " حرف",
"builtins.lobe-page-agent.apiName.initPage.creating": "جاري إنشاء المستند",
"builtins.lobe-page-agent.apiName.initPage.lines": " سطر",
"builtins.lobe-page-agent.apiName.initPage.result": "تم إنشاء المستند",
"builtins.lobe-page-agent.apiName.insertTableColumn": "إدراج عمود جدول",
"builtins.lobe-page-agent.apiName.insertTableRow": "إدراج صف جدول",
"builtins.lobe-page-agent.apiName.listSnapshots": "عرض اللقطات",
"builtins.lobe-page-agent.apiName.mergeNodes": "دمج العقد",
"builtins.lobe-page-agent.apiName.modifyNodes": "تعديل المستند",
"builtins.lobe-page-agent.apiName.modifyNodes": "تعديل الصفحة",
"builtins.lobe-page-agent.apiName.modifyNodes.addNodes": "إضافة محتوى",
"builtins.lobe-page-agent.apiName.modifyNodes.deleteNodes": "حذف المحتوى",
"builtins.lobe-page-agent.apiName.modifyNodes.deleteNodes": "حذف محتوى",
"builtins.lobe-page-agent.apiName.modifyNodes.init": "التحضير للتعديل",
"builtins.lobe-page-agent.apiName.modifyNodes.result": "+{{insert}} / ~{{modify}} / -{{remove}}",
"builtins.lobe-page-agent.apiName.moveNode": "نقل العقدة",
"builtins.lobe-page-agent.apiName.outdentListItem": "تقليل المسافة البادئة لعنصر القائمة",
"builtins.lobe-page-agent.apiName.outdentListItem": "تقليل المسافة البادئة",
"builtins.lobe-page-agent.apiName.replaceText": "استبدال النص",
"builtins.lobe-page-agent.apiName.replaceText.count": "{{count}} تم استبدالها",
"builtins.lobe-page-agent.apiName.replaceText.empty": "(فارغ)",
"builtins.lobe-page-agent.apiName.replaceText.init": "التحضير للاستبدال",
"builtins.lobe-page-agent.apiName.resizeImage": "تغيير حجم الصورة",
"builtins.lobe-page-agent.apiName.restoreSnapshot": "استعادة اللقطة",
"builtins.lobe-page-agent.apiName.rotateImage": "تدوير الصورة",
"builtins.lobe-page-agent.apiName.saveSnapshot": "حفظ اللقطة",
"builtins.lobe-page-agent.apiName.setImageAlt": "تعيين النص البديل للصورة",
"builtins.lobe-page-agent.apiName.setImageAlt": "تعيين نص بديل للصورة",
"builtins.lobe-page-agent.apiName.splitNode": "تقسيم العقدة",
"builtins.lobe-page-agent.apiName.toggleListType": "تبديل نوع القائمة",
"builtins.lobe-page-agent.apiName.unwrapNode": لغاء تغليف العقدة",
"builtins.lobe-page-agent.apiName.unwrapNode": زالة التغليف",
"builtins.lobe-page-agent.apiName.updateNode": "تحديث العقدة",
"builtins.lobe-page-agent.apiName.wrapNodes": "تغليف العقد",
"builtins.lobe-page-agent.title": "المستند",
"builtins.lobe-page-agent.title": "الصفحة",
"builtins.lobe-user-memory.apiName.addContextMemory": "إضافة ذاكرة السياق",
"builtins.lobe-user-memory.apiName.addExperienceMemory": "إضافة ذاكرة الخبرة",
"builtins.lobe-user-memory.apiName.addIdentityMemory": "إضافة ذاكرة الهوية",
@@ -103,191 +145,203 @@
"builtins.lobe-user-memory.apiName.searchUserMemory": "البحث في الذاكرة",
"builtins.lobe-user-memory.apiName.updateIdentityMemory": "تحديث ذاكرة الهوية",
"builtins.lobe-user-memory.title": "الذاكرة",
"builtins.lobe-web-browsing.apiName.crawlMultiPages": "قراءة محتوى عدة صفحات",
"builtins.lobe-web-browsing.apiName.crawlMultiPages": "قراءة صفحات متعددة",
"builtins.lobe-web-browsing.apiName.crawlSinglePage": "قراءة محتوى الصفحة",
"builtins.lobe-web-browsing.apiName.search": "البحث في الصفحات",
"builtins.lobe-web-browsing.title": "البحث عبر الإنترنت",
"builtins.lobe-web-browsing.inspector.noResults": "لا توجد نتائج",
"builtins.lobe-web-browsing.title": "بحث الويب",
"confirm": "تأكيد",
"debug.arguments": "معلمات الاستدعاء",
"debug.arguments": "المعلمات",
"debug.function_call": "استدعاء الدالة",
"debug.intervention": "تدخل المهارة",
"debug.off": "إيقاف التصحيح",
"debug.on": "عرض معلومات استدعاء الإضافة",
"debug.payload": "حمولة الإضافة",
"debug.pluginState": "حالة المكون الإضافي",
"debug.response": "النتيجة المرجعة",
"debug.title": "تفاصيل الإضافة",
"debug.tool_call": "طلب استدعاء الأداة",
"detailModal.customPlugin.description": "يرجى الانتقال إلى صفحة التحرير لمشاهدة التفاصيل",
"detailModal.customPlugin.editBtn": حرير الآن",
"detailModal.customPlugin.title": "هذه إضافة مخصصة",
"detailModal.emptyState.description": "يرجى تثبيت هذه الإضافة أولاً لعرض قدرات الإضافة وخيارات التكوين",
"detailModal.emptyState.title": "عرض تفاصيل الإضافة بعد التثبيت",
"debug.on": "عرض معلومات استدعاء المهارة",
"debug.payload": "حمولة المهارة",
"debug.pluginState": "حالة المهارة",
"debug.response": "الاستجابة",
"debug.title": "تفاصيل المهارة",
"debug.tool_call": "طلب استدعاء المهارة",
"detailModal.customPlugin.description": "عرض التفاصيل في صفحة التعديل",
"detailModal.customPlugin.editBtn": عديل الآن",
"detailModal.customPlugin.title": "هذه مهارة مخصصة",
"detailModal.emptyState.description": "قم بتثبيت هذه المهارة لعرض إمكانياتها وإعداداتها",
"detailModal.emptyState.title": "قم بالتثبيت لعرض تفاصيل المهارة",
"detailModal.info.description": "وصف API",
"detailModal.info.name": "اسم API",
"detailModal.tabs.info": "قدرات الإضافة",
"detailModal.tabs.manifest": "ملف التثبيت",
"detailModal.tabs.info": "الإمكانيات",
"detailModal.tabs.manifest": "البيان",
"detailModal.tabs.settings": "الإعدادات",
"detailModal.title": "تفاصيل الإضافة",
"dev.confirmDeleteDevPlugin": "سيتم حذف هذه الإضافة المحلية ولن يمكن استعادتها، هل تريد حذف هذه الإضافة؟",
"dev.customParams.useProxy.label": "التثبيت عبر الوكيل (إذا واجهت خطأ وصول عبر النطاق، جرب تفعيل هذا الخيار ثم أعد التثبيت)",
"dev.deleteSuccess": "تم حذف الإضافة بنجاح",
"dev.manifest.identifier.desc": "المعرف الفريد للإضافة",
"dev.manifest.identifier.label": "المعرف",
"dev.manifest.mode.mcp": "إضافة MCP",
"detailModal.title": "تفاصيل المهارة",
"dev.confirmDeleteDevPlugin": "سيتم حذف هذه المهارة المحلية نهائيًا. هل ترغب في المتابعة؟",
"dev.customParams.useProxy.label": "التثبيت عبر وكيل (فعّل إذا واجهت أخطاء CORS، ثم أعد المحاولة)",
"dev.deleteSuccess": "تم حذف المهارة",
"dev.manifest.identifier.desc": "معرّف فريد للمهارة",
"dev.manifest.identifier.label": "المعرّف",
"dev.manifest.mode.mcp": "MCP",
"dev.manifest.mode.mcpExp": "تجريبي",
"dev.manifest.mode.url": "رابط مباشر",
"dev.manifest.name.desc": "عنوان الإضافة",
"dev.manifest.name.desc": "عنوان المهارة",
"dev.manifest.name.label": "العنوان",
"dev.manifest.name.placeholder": "محرك البحث",
"dev.mcp.advanced.title": "إعدادات متقدمة",
"dev.mcp.args.desc": "قائمة المعلمات الممررة لأمر التنفيذ، عادةً هنا يتم إدخال اسم خادم MCP أو مسار سكريبت التشغيل",
"dev.mcp.args.label": "معلمات الأمر",
"dev.manifest.name.placeholder": "محرك بحث",
"dev.mcp.advanced.title": "خيارات متقدمة",
"dev.mcp.args.desc": "المعلمات المرسلة إلى الأمر، عادة اسم خادم MCP أو مسار السكربت",
"dev.mcp.args.label": "المعلمات",
"dev.mcp.args.placeholder": "مثال: mcp-hello-world",
"dev.mcp.args.required": "يرجى إدخال معلمات التشغيل",
"dev.mcp.args.required": "أدخل المعلمات",
"dev.mcp.auth.bear": "مفتاح API",
"dev.mcp.auth.desc": "اختر طريقة التوثيق لخادم MCP",
"dev.mcp.auth.label": "نوع التوثيق",
"dev.mcp.auth.none": "لا حاجة للتوثيق",
"dev.mcp.auth.placeholder": "يرجى اختيار نوع التوثيق",
"dev.mcp.auth.token.desc": "أدخل مفتاح API أو رمز الحامل الخاص بك",
"dev.mcp.auth.desc": "اختر طريقة المصادقة لخادم MCP",
"dev.mcp.auth.label": "نوع المصادقة",
"dev.mcp.auth.none": "بدون مصادقة",
"dev.mcp.auth.placeholder": "اختر نوع المصادقة",
"dev.mcp.auth.token.desc": "أدخل مفتاح API أو رمز Bearer",
"dev.mcp.auth.token.label": "مفتاح API",
"dev.mcp.auth.token.placeholder": "sk-xxxxx",
"dev.mcp.auth.token.required": "يرجى إدخال رمز التوثيق",
"dev.mcp.avatar.label": "أيقونة الإضافة",
"dev.mcp.command.desc": "الملف التنفيذي أو السكريبت المستخدم لتشغيل خادم MCP STDIO",
"dev.mcp.auth.token.required": "أدخل رمز المصادقة",
"dev.mcp.avatar.label": "أيقونة المهارة",
"dev.mcp.command.desc": "الأمر أو السكربت لتشغيل خادم MCP STDIO",
"dev.mcp.command.label": "الأمر",
"dev.mcp.command.placeholder": "مثال: npx / uv / docker إلخ",
"dev.mcp.command.required": "يرجى إدخال أمر التشغيل",
"dev.mcp.desc.desc": "أضف وصفًا للإضافة",
"dev.mcp.desc.label": "وصف الإضافة",
"dev.mcp.desc.placeholder": "أضف معلومات عن استخدام الإضافة وسيناريوهاتها",
"dev.mcp.endpoint.desc": "أدخل عنوان خادم MCP Streamable HTTP الخاص بك",
"dev.mcp.endpoint.label": "رابط نقطة نهاية MCP",
"dev.mcp.env.add": "أضف سطرًا جديدًا",
"dev.mcp.env.desc": "أدخل متغيرات البيئة المطلوبة لخادم MCP",
"dev.mcp.env.duplicateKeyError": "مفتاح الحقل يجب أن يكون فريدًا",
"dev.mcp.env.formValidationFailed": "فشل التحقق من النموذج، يرجى مراجعة تنسيق المعلمات",
"dev.mcp.env.keyRequired": "مفتاح الحقل لا يمكن أن يكون فارغًا",
"dev.mcp.command.placeholder": "مثال: npx / uv / docker",
"dev.mcp.command.required": "أدخل الأمر",
"dev.mcp.desc.desc": "أضف وصفًا للمهارة",
"dev.mcp.desc.label": "الوصف",
"dev.mcp.desc.placeholder": "تعليمات الاستخدام والسيناريوهات",
"dev.mcp.endpoint.desc": "أدخل عنوان خادم MCP القابل للبث عبر HTTP",
"dev.mcp.endpoint.label": "رابط MCP",
"dev.mcp.env.add": "إضافة صف",
"dev.mcp.env.desc": "أدخل متغيرات البيئة لخادم MCP",
"dev.mcp.env.duplicateKeyError": "يجب أن تكون المفاتيح فريدة",
"dev.mcp.env.formValidationFailed": "فشل التحقق من النموذج، تحقق من التنسيق",
"dev.mcp.env.keyRequired": "المفتاح مطلوب",
"dev.mcp.env.label": "متغيرات بيئة خادم MCP",
"dev.mcp.env.stringifyError": "تعذر تسلسل المعلمات، يرجى مراجعة التنسيق",
"dev.mcp.headers.add": "أضف سطرًا جديدًا",
"dev.mcp.headers.desc": "أدخل رؤوس الطلب",
"dev.mcp.env.stringifyError": "لا يمكن التسلسل، تحقق من التنسيق",
"dev.mcp.headers.add": "إضافة صف",
"dev.mcp.headers.desc": "أدخل رؤوس HTTP",
"dev.mcp.headers.label": "رؤوس HTTP",
"dev.mcp.identifier.desc": "حدد اسمًا لإضافة MCP الخاصة بك، يجب أن يكون بالأحرف الإنجليزية",
"dev.mcp.identifier.invalid": "المعرف يمكن أن يحتوي فقط على أحرف، أرقام، شرطات وشرطات سفلية",
"dev.mcp.identifier.label": "اسم إضافة MCP",
"dev.mcp.identifier.desc": "اسم لهذا MCP (أحرف إنجليزية فقط)",
"dev.mcp.identifier.invalid": "يجب أن يحتوي المعرّف على أحرف، أرقام، شرطات أو شرطات سفلية فقط",
"dev.mcp.identifier.label": "اسم MCP",
"dev.mcp.identifier.placeholder": "مثال: my-mcp-plugin",
"dev.mcp.identifier.required": "يرجى إدخال معرف خدمة MCP",
"dev.mcp.previewManifest": "معاينة ملف وصف الإضافة",
"dev.mcp.quickImport": "استيراد سريع لتكوين JSON",
"dev.mcp.quickImportError.empty": "لا يمكن أن يكون المحتوى فارغًا",
"dev.mcp.quickImportError.invalidJson": "تنسيق JSON غير صالح",
"dev.mcp.identifier.required": "أدخل معرّف MCP",
"dev.mcp.previewManifest": "معاينة البيان",
"dev.mcp.quickImport": "استيراد إعدادات JSON",
"dev.mcp.quickImportError.empty": "المحتوى لا يمكن أن يكون فارغًا",
"dev.mcp.quickImportError.invalidJson": "JSON غير صالح",
"dev.mcp.quickImportError.invalidStructure": "هيكل JSON غير صالح",
"dev.mcp.stdioNotSupported": "البيئة الحالية لا تدعم إضافات MCP من نوع stdio",
"dev.mcp.stdioNotSupported": "STDIO MCP غير مدعوم في البيئة الحالية",
"dev.mcp.testConnection": "اختبار الاتصال",
"dev.mcp.testConnectionTip": "يجب أن ينجح اختبار الاتصال لكي تعمل إضافة MCP بشكل صحيح",
"dev.mcp.type.desc": "اختر طريقة اتصال إضافة MCP، النسخة الويب تدعم فقط Streamable HTTP",
"dev.mcp.testConnectionTip": "سيكون MCP متاحًا بعد نجاح اختبار الاتصال",
"dev.mcp.type.desc": "اختر نوع MCP، الويب يدعم فقط HTTP القابل للبث",
"dev.mcp.type.httpFeature1": "متوافق مع الويب وسطح المكتب",
"dev.mcp.type.httpFeature2": "اتصال بخادم MCP عن بعد، لا حاجة لتثبيت إضافي",
"dev.mcp.type.httpShortDesc": "بروتوكول اتصال HTTP متدفق",
"dev.mcp.type.label": "نوع إضافة MCP",
"dev.mcp.type.stdioFeature1": "تأخير اتصال أقل، مناسب للتنفيذ المحلي",
"dev.mcp.type.stdioFeature2": جب تثبيت وتشغيل خادم MCP محليًا",
"dev.mcp.type.stdioNotAvailable": "وضع STDIO متاح فقط في نسخة سطح المكتب",
"dev.mcp.type.stdioShortDesc": "بروتوكول اتصال يعتمد على الإدخال والإخراج القياسي",
"dev.mcp.type.title": "نوع إضافة MCP",
"dev.mcp.url.desc": "أدخل عنوان MCP Server Streamable HTTP الخاص بك، لا يدعم وضع SSE",
"dev.mcp.url.invalid": "يرجى إدخال عنوان URL صالح",
"dev.mcp.url.label": "رابط نقطة نهاية HTTP المتدفق",
"dev.mcp.url.required": "يرجى إدخال عنوان URL لخدمة MCP",
"dev.meta.author.desc": "مؤلف الإضافة",
"dev.mcp.type.httpFeature2": "اتصال بخادم MCP عن بُعد، لا حاجة للإعداد",
"dev.mcp.type.httpShortDesc": "بروتوكول HTTP القابل للبث",
"dev.mcp.type.label": "نوع MCP",
"dev.mcp.type.stdioFeature1": "زمن استجابة أقل، للتنفيذ المحلي",
"dev.mcp.type.stdioFeature2": تطلب تثبيت خادم MCP محلي",
"dev.mcp.type.stdioNotAvailable": "STDIO متاح فقط على سطح المكتب",
"dev.mcp.type.stdioShortDesc": "بروتوكول الإدخال/الإخراج القياسي",
"dev.mcp.type.title": "نوع MCP",
"dev.mcp.url.desc": "أدخل رابط خادم MCP عبر HTTP القابل للبث (SSE غير مدعوم)",
"dev.mcp.url.invalid": "أدخل رابطًا صالحًا",
"dev.mcp.url.label": "رابط HTTP القابل للبث",
"dev.mcp.url.required": "أدخل رابط خادم MCP",
"dev.meta.author.desc": "مؤلف المهارة",
"dev.meta.author.label": "المؤلف",
"dev.meta.avatar.desc": "أيقونة الإضافة، يمكن استخدام إيموجي أو رابط URL",
"dev.meta.avatar.desc": "أيقونة المهارة (رمز تعبيري أو رابط)",
"dev.meta.avatar.label": "الأيقونة",
"dev.meta.description.desc": "وصف الإضافة",
"dev.meta.description.desc": "وصف المهارة",
"dev.meta.description.label": "الوصف",
"dev.meta.description.placeholder": "ابحث في محرك البحث للحصول على معلومات",
"dev.meta.formFieldRequired": "هذا الحقل مطلوب",
"dev.meta.homepage.desc": "الصفحة الرئيسية للإضافة",
"dev.meta.description.placeholder": "محرك بحث للمعلومات",
"dev.meta.formFieldRequired": "حقل مطلوب",
"dev.meta.homepage.desc": "الصفحة الرئيسية للمهارة",
"dev.meta.homepage.label": "الصفحة الرئيسية",
"dev.meta.identifier.desc": "المعرف الفريد للإضافة، سيتم التعرف عليه تلقائيًا من ملف manifest",
"dev.meta.identifier.errorDuplicate": "المعرف مكرر مع إضافة موجودة، يرجى تغييره",
"dev.meta.identifier.label": "المعرف",
"dev.meta.identifier.pattenErrorMessage": مكن إدخال أحرف إنجليزية، أرقام، - و _ فقط",
"dev.meta.lobe": "إضافة {{appName}}",
"dev.meta.manifest.desc": "سيتم تثبيت {{appName}} عبر هذا الرابط",
"dev.meta.manifest.label": "رابط ملف وصف الإضافة (Manifest)",
"dev.meta.manifest.preview": "معاينة Manifest",
"dev.meta.identifier.desc": "معرّف فريد، يتم اكتشافه تلقائيًا من البيان",
"dev.meta.identifier.errorDuplicate": "المعرّف يتعارض مع مهارة موجودة",
"dev.meta.identifier.label": "المعرّف",
"dev.meta.identifier.pattenErrorMessage": سمح فقط بالأحرف، الأرقام، الشرطات، والشرطات السفلية",
"dev.meta.lobe": "مهارة {{appName}}",
"dev.meta.manifest.desc": "{{appName}} سيقوم بتثبيت المهارة عبر هذا الرابط",
"dev.meta.manifest.label": "رابط البيان",
"dev.meta.manifest.preview": "معاينة البيان",
"dev.meta.manifest.refresh": "تحديث",
"dev.meta.openai": "إضافة OpenAI",
"dev.meta.title.desc": "عنوان الإضافة",
"dev.meta.openai": "مهارة OpenAI",
"dev.meta.title.desc": "عنوان المهارة",
"dev.meta.title.label": "العنوان",
"dev.meta.title.placeholder": "محرك البحث",
"dev.metaConfig": "تكوين معلومات الإضافة الأساسية",
"dev.modalDesc": "بعد إضافة إضافة مخصصة، يمكن استخدامها للتحقق من تطوير الإضافة أو استخدامها مباشرة في المحادثة. يرجى الرجوع إلى <1>وثائق التطوير↗</> لتطوير الإضافات.",
"dev.openai.importUrl": "استيراد من رابط URL",
"dev.meta.title.placeholder": "محرك بحث",
"dev.metaConfig": "إعدادات التعريف",
"dev.modalDesc": "يمكن استخدام المهارات المخصصة للتطوير أو مباشرة في المحادثات. راجع <1>الوثائق↗</1>",
"dev.openai.importUrl": "استيراد من رابط",
"dev.openai.schema": "المخطط",
"dev.preview.api.noParams": "هذه الأداة لا تحتوي على معلمات",
"dev.preview.api.noResults": "لم يتم العثور على API تطابق شروط البحث",
"dev.preview.api.noParams": "لا توجد معلمات",
"dev.preview.api.noResults": "لم يتم العثور على واجهات API",
"dev.preview.api.params": "المعلمات:",
"dev.preview.api.searchPlaceholder": "ابحث عن أداة...",
"dev.preview.card": "معاينة عرض الإضافة",
"dev.preview.desc": "معاينة وصف الإضافة",
"dev.preview.empty.desc": "بعد إكمال التكوين، يمكنك معاينة قدرات الأدوات المدعومة هنا",
"dev.preview.empty.title": "ابدأ المعاينة بعد تكوين الإضافة",
"dev.preview.title": "معاينة اسم الإضافة",
"dev.save": "تثبيت الإضافة",
"dev.saveSuccess": "تم حفظ إعدادات الإضافة بنجاح",
"dev.tabs.manifest": "قائمة وصف الوظائف (Manifest)",
"dev.tabs.meta": "معلومات الإضافة الأساسية",
"dev.title.create": "إضافة إضافة مخصصة",
"dev.title.edit": حرير إضافة مخصصة",
"dev.type.lobe": "إضافة {{appName}}",
"dev.type.openai": "إضافة OpenAI",
"dev.preview.api.searchPlaceholder": "ابحث عن مهارات…",
"dev.preview.card": "بطاقة معاينة المهارة",
"dev.preview.desc": "وصف المعاينة",
"dev.preview.empty.desc": "أكمل الإعداد لمعاينة إمكانيات المهارة",
"dev.preview.empty.title": "قم بالإعداد للمعاينة",
"dev.preview.title": "معاينة اسم المهارة",
"dev.save": "تثبيت",
"dev.saveSuccess": "تم حفظ الإعدادات",
"dev.tabs.manifest": "البيان",
"dev.tabs.meta": "معلومات التعريف",
"dev.title.create": "إضافة مهارة مخصصة",
"dev.title.edit": عديل مهارة مخصصة",
"dev.type.lobe": "مهارة {{appName}}",
"dev.type.openai": "مهارة OpenAI",
"dev.update": "تحديث",
"dev.updateSuccess": "تم تحديث إعدادات الإضافة بنجاح",
"empty.description": "يحتوي متجر الإضافات على العديد من الأدوات في انتظارك لاكتشافها، قم بزيارة المتجر وابدأ الاستكشاف",
"empty.search": م يتم العثور على إضافات مطابقة",
"empty.title": "لا توجد إضافات حالياً",
"dev.updateSuccess": "تم تحديث الإعدادات",
"empty.description": "تصفح متجر المهارات. قم بتثبيت واحدة للبدء، وأضف المزيد لاحقًا.",
"empty.search": ا توجد مهارات مطابقة",
"empty.title": "لا توجد مهارات",
"error.details": "تفاصيل الخطأ",
"error.fetchError": "فشل طلب رابط manifest، يرجى التأكد من صلاحية الرابط وفحص ما إذا كان يسمح بالوصول عبر النطاق",
"error.installError": "فشل تثبيت الإضافة {{name}}",
"error.manifestInvalid": "الملف manifest غير مطابق للمواصفات، نتيجة التحقق: \n\n {{error}}",
"error.noManifest": "ملف الوصف غير موجود",
"error.openAPIInvalid": "فشل تحليل OpenAPI، الخطأ: \n\n {{error}}",
"error.reinstallError": "فشل تحديث الإضافة {{name}}",
"error.renderError": "خطأ في عرض الأداة",
"error.testConnectionFailed": "فشل الحصول على Manifest: {{error}}",
"error.unknownError": "حدث خطأ غير معروف",
"error.urlError": "الرابط لم يرجع محتوى بصيغة JSON، يرجى التأكد من صحة الرابط",
"inspector.args": "عرض قائمة المعلمات",
"inspector.delete": "حذف استدعاء الأداة",
"inspector.orphanedToolCall": "قد تكون رسالة استدعاء الأداة هذه معزولة بسبب ظروف غير طبيعية، مما قد يؤثر على تنفيذ الوكيل بشكل صحيح. يُرجى إزالتها.",
"inspector.pluginRender": "عرض واجهة الإضافة",
"error.fetchError": "فشل في جلب البيان. تحقق من الرابط وصلاحيات CORS",
"error.installError": "فشل في تثبيت {{name}}",
"error.manifestInvalid": "بيان غير صالح:\n\n{{error}}",
"error.noManifest": "لم يتم العثور على البيان",
"error.openAPIInvalid": "فشل تحليل OpenAPI:\n\n{{error}}",
"error.reinstallError": "فشل في تحديث {{name}}",
"error.renderError": "خطأ في العرض",
"error.testConnectionFailed": "فشل في جلب البيان: {{error}}",
"error.unknownError": "خطأ غير معروف",
"error.urlError": "الرابط لم يُرجع JSON، تحقق من الرابط",
"inspector.args": "عرض المعلمات",
"inspector.delete": "حذف الاستدعاء",
"inspector.orphanedToolCall": "تم اكتشاف استدعاء مهارة يتيم، قد يؤثر على تنفيذ الوكيل. قم بإزالته.",
"inspector.pluginRender": "عرض واجهة المهارة",
"list.item.deprecated.title": "تم الحذف",
"list.item.local.config": "الإعدادات",
"list.item.local.config": "الإعداد",
"list.item.local.title": "مخصص",
"loading.content": "جارٍ استدعاء الإضافة...",
"loading.plugin": "تشغيل الإضافة...",
"mcpEmpty.deployment": "لا توجد خيارات نشر حالياً",
"mcpEmpty.prompts": "لا توجد مطالبات متاحة لهذه الإضافة حالياً",
"mcpEmpty.resources": "لا توجد موارد متاحة لهذه الإضافة حالياً",
"mcpEmpty.tools": "لا توجد قدرات أدوات متاحة لهذه الإضافة حالياً",
"mcpInstall.CHECKING_INSTALLATION": "جارٍ فحص بيئة التثبيت...",
"mcpInstall.COMPLETED": "اكتمل التثبيت",
"mcpInstall.CONFIGURATION_REQUIRED": "يرجى إكمال التكوين المطلوب للمتابعة بالتثبيت",
"loading.content": "جارٍ استدعاء المهارة…",
"loading.plugin": "المهارة قيد التشغيل…",
"localSystem.workingDirectory.agentDescription": "دليل العمل الافتراضي لجميع المحادثات مع هذا الوكيل",
"localSystem.workingDirectory.agentLevel": "دليل عمل الوكيل",
"localSystem.workingDirectory.current": "دليل العمل الحالي",
"localSystem.workingDirectory.notSet": "انقر لتعيين دليل العمل",
"localSystem.workingDirectory.placeholder": "أدخل مسار الدليل، مثل /Users/name/projects",
"localSystem.workingDirectory.selectFolder": "اختر مجلدًا",
"localSystem.workingDirectory.title": "دليل العمل",
"localSystem.workingDirectory.topicDescription": "تجاوز الإعداد الافتراضي للوكيل لهذه المحادثة فقط",
"localSystem.workingDirectory.topicLevel": "تجاوز المحادثة",
"localSystem.workingDirectory.topicOverride": "تجاوز لهذه المحادثة",
"mcpEmpty.deployment": "لا توجد خيارات نشر",
"mcpEmpty.prompts": "لا توجد مطالبات",
"mcpEmpty.resources": "لا توجد موارد",
"mcpEmpty.tools": "لا توجد أدوات",
"mcpInstall.CHECKING_INSTALLATION": "جارٍ التحقق من التثبيت…",
"mcpInstall.COMPLETED": "اكتمل",
"mcpInstall.CONFIGURATION_REQUIRED": "أكمل الإعداد للمتابعة",
"mcpInstall.ERROR": "خطأ في التثبيت",
"mcpInstall.FETCHING_MANIFEST": "جارٍ الحصول على ملف وصف الإضافة...",
"mcpInstall.GETTING_SERVER_MANIFEST": "جارٍ تهيئة خادم MCP...",
"mcpInstall.INSTALLING_PLUGIN": "جارٍ تثبيت الإضافة...",
"mcpInstall.configurationDescription": "تتطلب هذه الإضافة MCP إعداد معلمات لتعمل بشكل صحيح، يرجى ملء المعلومات اللازمة",
"mcpInstall.configurationRequired": "تكوين معلمات الإضافة",
"mcpInstall.continueInstall": "متابعة التثبيت",
"mcpInstall.dependenciesDescription": "تتطلب هذه الإضافة تثبيت تبعيات نظامية لتعمل بشكل صحيح، يرجى تثبيت التبعيات المفقودة حسب التعليمات ثم اضغط إعادة الفحص للمتابعة بالتثبيت.",
"mcpInstall.dependenciesRequired": "يرجى تثبيت تبعيات النظام للإضافة",
"mcpInstall.FETCHING_MANIFEST": "جارٍ جلب الملف التعريفي…",
"mcpInstall.GETTING_SERVER_MANIFEST": "جارٍ تهيئة خادم MCP",
"mcpInstall.INSTALLING_PLUGIN": "جارٍ تثبيت المهارة…",
"mcpInstall.configurationDescription": "قم بإعداد المعلمات المطلوبة لهذا الـ MCP",
"mcpInstall.configurationRequired": "إعداد المعلمات",
"mcpInstall.continueInstall": "متابعة",
"mcpInstall.dependenciesDescription": "قم بتثبيت التبعيات المطلوبة، ثم أعد التحقق للمتابعة.",
"mcpInstall.dependenciesRequired": "تثبيت تبعيات النظام",
"mcpInstall.dependencyStatus.installed": "مثبت",
"mcpInstall.dependencyStatus.notInstalled": "غير مثبت",
"mcpInstall.dependencyStatus.requiredVersion": "الإصدار المطلوب: {{version}}",
"mcpInstall.dependencyStatus.requiredVersion": "المطلوب: {{version}}",
"mcpInstall.errorDetails.args": "المعلمات",
"mcpInstall.errorDetails.command": "الأمر",
"mcpInstall.errorDetails.connectionParams": "معلمات الاتصال",
@@ -297,121 +351,121 @@
"mcpInstall.errorDetails.hideDetails": "إخفاء التفاصيل",
"mcpInstall.errorDetails.originalError": "الخطأ الأصلي",
"mcpInstall.errorDetails.showDetails": "عرض التفاصيل",
"mcpInstall.errorTypes.AUTHORIZATION_ERROR": "خطأ في التحقق من التفويض",
"mcpInstall.errorTypes.AUTHORIZATION_ERROR": "خطأ في التفويض",
"mcpInstall.errorTypes.CONNECTION_FAILED": "فشل الاتصال",
"mcpInstall.errorTypes.INITIALIZATION_TIMEOUT": "انتهت مهلة التهيئة",
"mcpInstall.errorTypes.PROCESS_SPAWN_ERROR": "فشل بدء العملية",
"mcpInstall.errorTypes.UNKNOWN_ERROR": "خطأ غير معروف",
"mcpInstall.errorTypes.VALIDATION_ERROR": "فشل التحقق من المعلمات",
"mcpInstall.installError": "فشل تثبيت إضافة MCP، السبب: {{detail}}",
"mcpInstall.installMethods.manual": "تثبيت يدوي:",
"mcpInstall.installMethods.recommended": "طريقة التثبيت الموصى بها:",
"mcpInstall.recheckDependencies": "إعادة فحص",
"mcpInstall.skipDependencies": "تخطي الفحص",
"pluginList": "قائمة الإضافات",
"mcpInstall.errorTypes.VALIDATION_ERROR": "فشل التحقق",
"mcpInstall.installError": "فشل تثبيت MCP: {{detail}}",
"mcpInstall.installMethods.manual": "يدوي:",
"mcpInstall.installMethods.recommended": "موصى به:",
"mcpInstall.recheckDependencies": "إعادة التحقق",
"mcpInstall.skipDependencies": "تخطي",
"pluginList": "المهارات",
"protocolInstall.actions.install": "تثبيت",
"protocolInstall.actions.installAnyway": "تثبيت على أي حال",
"protocolInstall.actions.installed": "مثبت",
"protocolInstall.config.addEnv": "إضافة متغير بيئة",
"protocolInstall.config.addHeaders": "إضافة رؤوس الطلب",
"protocolInstall.config.addHeaders": "إضافة ترويسة",
"protocolInstall.config.args": "المعلمات",
"protocolInstall.config.command": "الأمر",
"protocolInstall.config.env": "متغيرات البيئة",
"protocolInstall.config.headers": "رؤوس الطلب",
"protocolInstall.config.title": "معلومات التكوين",
"protocolInstall.config.env": "البيئة",
"protocolInstall.config.headers": "الترويسات",
"protocolInstall.config.title": "الإعداد",
"protocolInstall.config.type.http": "النوع: HTTP",
"protocolInstall.config.type.label": "النوع",
"protocolInstall.config.type.stdio": "النوع: Stdio",
"protocolInstall.config.url": "عنوان الخدمة",
"protocolInstall.custom.badge": "إضافة مخصصة",
"protocolInstall.custom.security.description": "هذه الإضافة لم يتم التحقق منها رسميًا، قد تحمل مخاطر أمنية! يرجى التأكد من ثقتك بمصدر الإضافة.",
"protocolInstall.custom.security.title": "⚠️ تحذير أمني",
"protocolInstall.custom.title": "تثبيت إضافة مخصصة",
"protocolInstall.config.url": "رابط الخادم",
"protocolInstall.custom.badge": "مهارة مخصصة",
"protocolInstall.custom.security.description": "مهارة غير رسمية، قد تحتوي على مخاطر أمنية. تحقق من المصدر قبل التثبيت.",
"protocolInstall.custom.security.title": "الأمان",
"protocolInstall.custom.title": "تثبيت مهارة مخصصة",
"protocolInstall.install.title": "معلومات التثبيت",
"protocolInstall.marketplace.title": "تثبيت إضافات الطرف الثالث",
"protocolInstall.marketplace.trustedBy": "مقدم من {{name}}",
"protocolInstall.marketplace.unverified.title": "إضافات طرف ثالث غير موثوقة",
"protocolInstall.marketplace.unverified.warning": "هذا المكون الإضافي来自 مجتمع طرف ثالث غير موثوق به. يرجى التأكد من أنك تثق في هذا المصدر قبل التثبيت.",
"protocolInstall.marketplace.verified": "موثوقة",
"protocolInstall.marketplace.title": "تثبيت مهارة من طرف ثالث",
"protocolInstall.marketplace.trustedBy": "بواسطة {{name}}",
"protocolInstall.marketplace.unverified.title": "مهارة غير موثقة من طرف ثالث",
"protocolInstall.marketplace.unverified.warning": "تحقق من المصدر قبل تثبيت هذه المهارة المجتمعية.",
"protocolInstall.marketplace.verified": "موثقة",
"protocolInstall.messages.connectionTestFailed": "فشل اختبار الاتصال",
"protocolInstall.messages.installError": "فشل تثبيت الإضافة، يرجى المحاولة مجددًا",
"protocolInstall.messages.installSuccess": "تم تثبيت الإضافة {{name}} بنجاح!",
"protocolInstall.messages.manifestError": "فشل الحصول على تفاصيل الإضافة، يرجى التحقق من الاتصال بالشبكة والمحاولة مجددًا",
"protocolInstall.messages.manifestNotFound": "تعذر الحصول على ملف وصف الإضافة",
"protocolInstall.messages.installError": "فشل التثبيت، حاول مرة أخرى",
"protocolInstall.messages.installSuccess": "{{name}} تم تثبيتها. يمكنك تفعيلها الآن أو إعدادها لاحقًا.",
"protocolInstall.messages.manifestError": "فشل في جلب معلومات المهارة. تحقق من الشبكة أو حاول لاحقًا.",
"protocolInstall.messages.manifestNotFound": "الملف التعريفي غير موجود",
"protocolInstall.meta.author": "المؤلف",
"protocolInstall.meta.homepage": "الصفحة الرئيسية",
"protocolInstall.meta.identifier": "المعرف",
"protocolInstall.meta.source": "المصدر",
"protocolInstall.meta.version": "الإصدار",
"protocolInstall.official.badge": "إضافة رسمية من LobeHub",
"protocolInstall.official.description": "تم تطوير هذه الإضافة وصيانتها رسميًا من قبل LobeHub، وتمت مراجعتها أمنيًا بدقة، يمكن استخدامها بأمان.",
"protocolInstall.official.loadingMessage": "جارٍ الحصول على تفاصيل الإضافة...",
"protocolInstall.official.badge": "مهارة رسمية من LobeHub",
"protocolInstall.official.description": "مهارة رسمية من LobeHub، تم التحقق منها وفحصها أمنيًا.",
"protocolInstall.official.loadingMessage": "جارٍ تحميل تفاصيل المهارة…",
"protocolInstall.official.loadingTitle": "جارٍ التحميل",
"protocolInstall.official.title": "تثبيت إضافة رسمية",
"protocolInstall.title": "تثبيت إضافة MCP",
"protocolInstall.warning": "⚠️ يرجى التأكد من ثقتك بمصدر هذه الإضافة، الإضافات الخبيثة قد تضر بأمان نظامك.",
"protocolInstall.official.title": "تثبيت مهارة رسمية",
"protocolInstall.title": "تثبيت MCP",
"protocolInstall.warning": "تحقق من مصدر المهارة. يمكنك تعطيلها أو إزالتها في أي وقت من الإعدادات.",
"search.config.addKey": "إضافة مفتاح",
"search.config.close": "حذف",
"search.config.confirm": "تم إكمال التكوين وأعيد المحاولة",
"search.crawPages.crawling": "جارٍ التعرف على الروابط",
"search.config.close": "إزالة",
"search.config.confirm": "تم، أعد المحاولة",
"search.crawPages.crawling": "جارٍ تحديد الروابط",
"search.crawPages.detail.preview": "معاينة",
"search.crawPages.detail.raw": "نص خام",
"search.crawPages.detail.tooLong": "النص طويل جدًا، يحتفظ سياق المحادثة فقط بأول {{characters}} حرفًا، الجزء الزائد غير مدرج في السياق",
"search.crawPages.detail.tooLong": "تم تقليص النص إلى {{characters}} حرفًا للسياق، وتم حذف الزائد.",
"search.crawPages.meta.crawler": "وضع الزحف",
"search.crawPages.meta.words": "عدد الأحرف",
"search.searchxng.baseURL": "يرجى الإدخال",
"search.searchxng.description": "يرجى إدخال عنوان SearchXNG للبدء في البحث عبر الإنترنت",
"search.searchxng.keyPlaceholder": "يرجى إدخال المفتاح",
"search.searchxng.title": "تكوين محرك البحث SearchXNG",
"search.searchxng.unconfiguredDesc": "يرجى الاتصال بالمسؤول لإكمال تكوين محرك البحث SearchXNG للبدء في البحث عبر الإنترنت",
"search.searchxng.unconfiguredTitle": "لم يتم تكوين محرك البحث SearchXNG بعد",
"search.title": "البحث عبر الإنترنت",
"setting": "إعدادات الإضافة",
"settings.capabilities.prompts": "عبارات التوجيه",
"search.searchxng.baseURL": "أدخل الرابط",
"search.searchxng.description": "أدخل رابط SearchXNG لبدء البحث عبر الويب",
"search.searchxng.keyPlaceholder": "أدخل المفتاح",
"search.searchxng.title": "إعداد SearchXNG",
"search.searchxng.unconfiguredDesc": "اتصل بالمسؤول لإعداد SearchXNG",
"search.searchxng.unconfiguredTitle": "SearchXNG غير مُعد",
"search.title": "بحث عبر الويب",
"setting": "الإعدادات",
"settings.capabilities.prompts": "المطالبات",
"settings.capabilities.resources": "الموارد",
"settings.capabilities.title": "قدرات الإضافة",
"settings.capabilities.title": "المهارات",
"settings.capabilities.tools": "الأدوات",
"settings.configuration.title": "تكوين الإضافة",
"settings.connection.args": "معلمات التشغيل",
"settings.connection.command": "أمر التشغيل",
"settings.connection.title": "معلومات الاتصال",
"settings.connection.type": "نوع الاتصال",
"settings.connection.url": "عنوان الخدمة",
"settings.edit": حرير",
"settings.envConfigDescription": "سيتم تمرير هذه الإعدادات كمتغيرات بيئة عند بدء تشغيل خادم MCP",
"settings.httpTypeNotice": "إضافات MCP من نوع HTTP لا تحتاج إلى متغيرات بيئة للتكوين حاليًا",
"settings.configuration.title": "الإعداد",
"settings.connection.args": "المعلمات",
"settings.connection.command": "الأمر",
"settings.connection.title": "الاتصال",
"settings.connection.type": "النوع",
"settings.connection.url": "رابط الخادم",
"settings.edit": عديل",
"settings.envConfigDescription": "يتم تمريرها كمتغيرات بيئة عند بدء خادم MCP",
"settings.httpTypeNotice": "MCP من نوع HTTP لا يحتوي على متغيرات بيئة للإعداد",
"settings.indexUrl.title": "فهرس المجتمع",
"settings.indexUrl.tooltip": "لا يدعم التحرير عبر الإنترنت حاليًا، يرجى التكوين عبر متغيرات البيئة عند النشر",
"settings.messages.connectionUpdateFailed": "فشل تحديث معلومات الاتصال",
"settings.messages.connectionUpdateSuccess": "تم تحديث معلومات الاتصال بنجاح",
"settings.indexUrl.tooltip": "قم بالتعديل عبر متغيرات بيئة النشر",
"settings.messages.connectionUpdateFailed": "فشل تحديث الاتصال",
"settings.messages.connectionUpdateSuccess": "تم تحديث الاتصال",
"settings.messages.envUpdateFailed": "فشل حفظ متغيرات البيئة",
"settings.messages.envUpdateSuccess": "تم حفظ متغيرات البيئة بنجاح",
"settings.modalDesc": "بعد تكوين عنوان مجتمع المكونات الإضافية، يمكنك استخدام مجتمع مكونات إضافية مخصص",
"settings.rules.argsRequired": "يرجى إدخال معلمات التشغيل",
"settings.rules.commandRequired": "يرجى إدخال أمر التشغيل",
"settings.rules.urlRequired": "يرجى إدخال عنوان الخدمة",
"settings.saveSettings": "حفظ الإعدادات",
"settings.title": "إعداد مجتمع المكونات الإضافية",
"showInPortal": "يرجى عرض التفاصيل في مساحة العمل",
"store.actions.cancel": "إلغاء التثبيت",
"store.actions.confirmUninstall": "سيتم إلغاء تثبيت هذه الإضافة وسيتم حذف إعداداتها، يرجى تأكيد العملية",
"store.actions.detail": "التفاصيل",
"settings.messages.envUpdateSuccess": "تم حفظ متغيرات البيئة",
"settings.modalDesc": "قم بإعداد رابط المجتمع لاستخدام مجتمع مهارات مخصص.",
"settings.rules.argsRequired": "أدخل المعلمات",
"settings.rules.commandRequired": "أدخل الأمر",
"settings.rules.urlRequired": "أدخل رابط الخادم",
"settings.saveSettings": "حفظ",
"settings.title": "إعدادات مجتمع المهارات",
"showInPortal": "عرض التفاصيل في مساحة العمل",
"store.actions.cancel": "إلغاء",
"store.actions.confirmUninstall": "سيؤدي إلغاء التثبيت إلى مسح إعدادات المهارة. هل ترغب في المتابعة؟",
"store.actions.detail": "تفاصيل",
"store.actions.install": "تثبيت",
"store.actions.manifest": حرير ملف التثبيت",
"store.actions.manifest": عديل الملف التعريفي",
"store.actions.settings": "الإعدادات",
"store.actions.uninstall": "إلغاء التثبيت",
"store.communityPlugin": "مجتمع الطرف الثالث",
"store.communityPlugin": "مجتمعي",
"store.customPlugin": "مخصص",
"store.empty": "لا توجد إضافات مثبتة",
"store.emptySelectHint": "اختر إضافة لمعاينة التفاصيل",
"store.empty": "لا توجد مهارات مثبتة",
"store.emptySelectHint": "اختر مهارة لعرض التفاصيل",
"store.installAllPlugins": "تثبيت الكل",
"store.networkError": "فشل الحصول على متجر الإضافات، يرجى التحقق من الاتصال بالشبكة والمحاولة مجددًا",
"store.placeholder": "ابحث عن اسم الإضافة أو الوصف أو الكلمات المفتاحية...",
"store.releasedAt": "نُشر في {{createdAt}}",
"store.tabs.installed": "مثبت",
"store.tabs.mcp": "إضافات MCP",
"store.tabs.old": لحقات LobeHub",
"store.title": "متجر الإضافات",
"store.networkError": "فشل في جلب متجر المهارات. تحقق من الشبكة وأعد المحاولة.",
"store.placeholder": "ابحث عن مهارات بالاسم أو الكلمة المفتاحية",
"store.releasedAt": "تم الإصدار في {{createdAt}}",
"store.tabs.installed": "المثبتة",
"store.tabs.mcp": "MCP",
"store.tabs.old": هارات LobeHub",
"store.title": "متجر المهارات",
"unknownError": "خطأ غير معروف",
"unknownPlugin": "إضافة غير معروفة"
"unknownPlugin": "مهارة غير معروفة"
}
+15 -12
View File
@@ -1,22 +1,25 @@
{
"Artifacts": "القطع الأثرية",
"FilePreview.tabs.chunk": "جزء",
"FilePreview.tabs.file": "ملف",
"Plugins": "ملحقات",
"artifacts.display.code": "رمز",
"Plugins": "المهارات",
"artifacts.display.code": "الشفرة",
"artifacts.display.preview": "معاينة",
"artifacts.svg.copyAsImage": "نسخ كصورة",
"artifacts.svg.copyFail": "فشل النسخ، سبب الخطأ: {{error}}",
"artifacts.svg.copyFail": "فشل النسخ: {{error}}. حاول مرة أخرى.",
"artifacts.svg.copySuccess": "تم نسخ الصورة بنجاح",
"artifacts.svg.download.png": حميل كـ PNG",
"artifacts.svg.download.svg": حميل كـ SVG",
"emptyArtifactList": "قائمة القطع الأثرية الحالية فارغة، يرجى استخدام الإضافات في الجلسة ومن ثم التحقق مرة أخرى",
"emptyKnowledgeList": "قائمة المعرفة الحالية فارغة، يرجى فتح قاعدة المعرفة حسب الحاجة في المحادثة قبل العرض",
"files": "ملفات",
"artifacts.svg.download.png": نزيل كـ PNG",
"artifacts.svg.download.svg": نزيل كـ SVG",
"document.todos.allCompleted": "تم إنجاز جميع المهام",
"document.todos.title": "المهام",
"emptyArtifactList": "لا توجد قطع أثرية بعد. استخدم المهارات في المحادثة، ثم عد إلى هنا.",
"emptyKnowledgeList": "هذه القائمة فارغة.",
"files": "الملفات",
"messageDetail": "تفاصيل الرسالة",
"notebook.confirmDelete": "هل أنت متأكد أنك تريد حذف هذا المستند؟",
"notebook.confirmDelete": "هل تريد حذف هذه الصفحة؟",
"notebook.delete": "حذف",
"notebook.empty": "لا توجد مستندات حالياً، ستظهر المستندات المرتبطة بالموضوع هنا",
"notebook.empty": "لا توجد صفحات بعد. ستظهر الصفحات المرتبطة بهذا الموضوع هنا.",
"notebook.title": "دفتر الملاحظات",
"openInPageEditor": "تحرير في المستند",
"title": "نافذة موسعة"
"openInPageEditor": "تحرير في الصفحة",
"title": "مساحة العمل"
}
+68 -68
View File
@@ -1,70 +1,70 @@
{
"ai21.description": "تقوم AI21 Labs ببناء نماذج أساسية وأنظمة ذكاء اصطناعي للشركات، مما يسرع من تطبيق الذكاء الاصطناعي التوليدي في الإنتاج.",
"ai302.description": "302.AI هو منصة تطبيقات ذكاء اصطناعي تعتمد على الدفع حسب الاستخدام، تقدم أكثر واجهات برمجة التطبيقات للتعلم الآلي وتطبيقات الذكاء الاصطناعي عبر الإنترنت شمولاً في السوق",
"ai360.description": "AI 360 هي منصة نماذج وخدمات الذكاء الاصطناعي التي أطلقتها شركة 360، تقدم مجموعة متنوعة من نماذج معالجة اللغة الطبيعية المتقدمة، بما في ذلك 360GPT2 Pro و360GPT Pro و360GPT Turbo و360GPT Turbo Responsibility 8K. تجمع هذه النماذج بين المعلمات الكبيرة والقدرات متعددة الوسائط، وتستخدم على نطاق واسع في توليد النصوص، وفهم المعاني، وأنظمة الحوار، وتوليد الشيفرات. من خلال استراتيجيات تسعير مرنة، تلبي AI 360 احتياجات المستخدمين المتنوعة، وتدعم المطورين في التكامل، مما يعزز الابتكار والتطوير في التطبيقات الذكية.",
"aihubmix.description": "يوفر AiHubMix الوصول إلى نماذج الذكاء الاصطناعي المتعددة من خلال واجهة برمجة تطبيقات موحدة.",
"akashchat.description": "آكاش هو سوق موارد سحابية بدون ترخيص، يتميز بأسعار تنافسية مقارنة بمزودي السحابة التقليديين.",
"anthropic.description": "Anthropic هي شركة تركز على أبحاث وتطوير الذكاء الاصطناعي، وتقدم مجموعة من نماذج اللغة المتقدمة، مثل Claude 3.5 Sonnet وClaude 3 Sonnet وClaude 3 Opus وClaude 3 Haiku. تحقق هذه النماذج توازنًا مثاليًا بين الذكاء والسرعة والتكلفة، وتناسب مجموعة متنوعة من سيناريوهات التطبيقات، من أحمال العمل على مستوى المؤسسات إلى الاستجابات السريعة. يعتبر Claude 3.5 Sonnet أحدث نماذجها، وقد أظهر أداءً ممتازًا في العديد من التقييمات مع الحفاظ على نسبة تكلفة فعالة.",
"azure.description": وفر Azure مجموعة متنوعة من نماذج الذكاء الاصطناعي المتقدمة، بما في ذلك GPT-3.5 وأحدث سلسلة GPT-4، تدعم أنواع بيانات متعددة ومهام معقدة، وتلتزم بحلول ذكاء اصطناعي آمنة وموثوقة ومستدامة.",
"azureai.description": "توفر Azure مجموعة متنوعة من نماذج الذكاء الاصطناعي المتقدمة، بما في ذلك GPT-3.5 وأحدث سلسلة GPT-4، تدعم أنواع البيانات المتعددة والمهام المعقدة، وتهدف إلى تقديم حلول ذكاء اصطناعي آمنة وموثوقة ومستدامة.",
"baichuan.description": "Baichuan Intelligence هي شركة تركز على تطوير نماذج الذكاء الاصطناعي الكبيرة، حيث تظهر نماذجها أداءً ممتازًا في المهام الصينية مثل الموسوعات المعرفية ومعالجة النصوص الطويلة والإبداع. تتفوق على النماذج الرئيسية الأجنبية. كما تتمتع Baichuan Intelligence بقدرات متعددة الوسائط رائدة في الصناعة، وقد أظهرت أداءً ممتازًا في العديد من التقييمات الموثوقة. تشمل نماذجها Baichuan 4 وBaichuan 3 Turbo وBaichuan 3 Turbo 128k، وكل منها مُحسّن لمشاهد تطبيق مختلفة، مما يوفر حلولًا فعالة من حيث التكلفة.",
"bedrock.description": "Bedrock هي خدمة تقدمها أمازون AWS، تركز على توفير نماذج لغة ورؤية متقدمة للذكاء الاصطناعي للشركات. تشمل عائلة نماذجها سلسلة Claude من Anthropic وسلسلة Llama 3.1 من Meta، وتغطي مجموعة من الخيارات من النماذج الخفيفة إلى عالية الأداء، وتدعم مهام مثل توليد النصوص، والحوار، ومعالجة الصور، مما يجعلها مناسبة لتطبيقات الشركات بمختلف أحجامها واحتياجاتها.",
"bfl.description": "مختبر بحثي رائد في مجال الذكاء الاصطناعي المتقدّم، يبني بنية تحتية بصرية للغد.",
"cerebras.description": "Cerebras هو نظام استدلال ذكاء اصطناعي يعتمد على نظام CS-3 المخصص، ويهدف إلى تقديم أسرع خدمات النماذج اللغوية الكبيرة (LLM) في العالم مع استجابة فورية وقدرة معالجة عالية. تم تصميمه خصيصًا للقضاء على التأخير وتسريع سير العمل المعقد للذكاء الاصطناعي مثل توليد الشيفرات في الوقت الحقيقي والمهام التفاعلية.",
"cloudflare.description": "تشغيل نماذج التعلم الآلي المدفوعة بوحدات معالجة الرسوميات بدون خادم على شبكة Cloudflare العالمية.",
"cohere.description": "تقدم Cohere أحدث نماذج متعددة اللغات، وميزات بحث متقدمة، ومساحة عمل AI مصممة خصيصًا للشركات الحديثة - كل ذلك مدمج في منصة آمنة.",
"cometapi.description": "CometAPI هو منصة خدمات توفر واجهات متعددة لنماذج الذكاء الاصطناعي المتقدمة، تدعم OpenAI وAnthropic وGoogle والمزيد، مناسبة لمتطلبات التطوير والتطبيق المتنوعة. يمكن للمستخدمين اختيار النموذج والسعر الأمثل وفقًا لاحتياجاتهم، مما يعزز تجربة الذكاء الاصطناعي.",
"comfyui.description": "محرك سير عمل قوي ومفتوح المصدر لتوليد الصور والفيديو والصوت، يدعم نماذج متقدمة مثل SD وFLUX وQwen وHunyuan وWAN، ويوفر إمكانيات تحرير سير العمل عبر العقد والنشر الخاص.",
"deepseek.description": "DeepSeek هي شركة تركز على أبحاث وتطبيقات تقنيات الذكاء الاصطناعي، حيث يجمع نموذجها الأحدث DeepSeek-V2.5 بين قدرات الحوار العامة ومعالجة الشيفرات، وقد حقق تحسينات ملحوظة في محاذاة تفضيلات البشر، ومهام الكتابة، واتباع التعليمات.",
"fal.description": "منصة وسائط توليدية موجهة للمطورين",
"fireworksai.description": "Fireworks AI هي شركة رائدة في تقديم خدمات نماذج اللغة المتقدمة، تركز على استدعاء الوظائف والمعالجة متعددة الوسائط. نموذجها الأحدث Firefunction V2 مبني على Llama-3، مُحسّن لاستدعاء الوظائف، والحوار، واتباع التعليمات. يدعم نموذج اللغة البصرية FireLLaVA-13B إدخال الصور والنصوص المختلطة. تشمل النماذج البارزة الأخرى سلسلة Llama وسلسلة Mixtral، مما يوفر دعمًا فعالًا لاتباع التعليمات وتوليدها بلغات متعددة.",
"giteeai.description": "خادم واجهات برمجة التطبيقات gitee منظمة العفو الدولية يوفر نموذج كبير المنطق API خدمة منظمة العفو الدولية للمطورين .",
"github.description": "مع نماذج GitHub، يمكن للمطورين أن يصبحوا مهندسي ذكاء اصطناعي ويبنون باستخدام نماذج الذكاء الاصطناعي الرائدة في الصناعة.",
"google.description": "سلسلة Gemini من Google هي نماذج الذكاء الاصطناعي الأكثر تقدمًا وشمولية، تم تطويرها بواسطة Google DeepMind، مصممة خصيصًا لتكون متعددة الوسائط، تدعم الفهم والمعالجة السلسة للنصوص، والشيفرات، والصور، والصوت، والفيديو. تناسب مجموعة متنوعة من البيئات، من مراكز البيانات إلى الأجهزة المحمولة، مما يعزز بشكل كبير كفاءة نماذج الذكاء الاصطناعي وانتشار استخدامها.",
"groq.description": "يتميز محرك الاستدلال LPU من Groq بأداء ممتاز في أحدث اختبارات المعايير لنماذج اللغة الكبيرة المستقلة (LLM)، حيث أعاد تعريف معايير حلول الذكاء الاصطناعي بسرعته وكفاءته المذهلة. Groq يمثل سرعة استدلال فورية، ويظهر أداءً جيدًا في النشر القائم على السحابة.",
"higress.description": "Higress هو بوابة API سحابية الأصل، تم تطويرها داخل علي بابا لحل مشاكل إعادة تحميل Tengine التي تؤثر سلبًا على الأعمال ذات الاتصالات الطويلة، بالإضافة إلى نقص قدرات توازن الحمل لـ gRPC/Dubbo.",
"huggingface.description": قدم واجهة برمجة التطبيقات الخاصة بـ HuggingFace طريقة سريعة ومجانية لاستكشاف الآلاف من النماذج لمجموعة متنوعة من المهام. سواء كنت تقوم بتصميم نموذج أولي لتطبيق جديد أو تحاول استكشاف إمكانيات التعلم الآلي، فإن هذه الواجهة تتيح لك الوصول الفوري إلى نماذج عالية الأداء في مجالات متعددة.",
"hunyuan.description": "نموذج لغة متقدم تم تطويره بواسطة Tencent، يتمتع بقدرة قوية على الإبداع باللغة الصينية، وقدرة على الاستدلال المنطقي في سياقات معقدة، بالإضافة إلى قدرة موثوقة على تنفيذ المهام.",
"infiniai.description": "يقدم خدمات نماذج كبيرة ذات أداء عالٍ وسهولة الاستخدام وأمان موثوق به للمطورين، تغطي كامل العملية من تطوير النماذج الكبيرة إلى نشرها كخدمات.",
"internlm.description": "منظمة مفتوحة المصدر مكرسة لأبحاث وتطوير أدوات النماذج الكبيرة. توفر منصة مفتوحة المصدر فعالة وسهلة الاستخدام لجميع مطوري الذكاء الاصطناعي، مما يجعل أحدث تقنيات النماذج الكبيرة والخوارزميات في متناول اليد.",
"jina.description": "تأسست Jina AI في عام 2020، وهي شركة رائدة في مجال الذكاء الاصطناعي للبحث. تحتوي منصتنا الأساسية للبحث على نماذج متجهة، ومعيدي ترتيب، ونماذج لغوية صغيرة، لمساعدة الشركات في بناء تطبيقات بحث موثوقة وعالية الجودة تعتمد على الذكاء الاصطناعي التوليدي ومتعددة الوسائط.",
"lmstudio.description": "LM Studio هو تطبيق سطح مكتب لتطوير وتجربة نماذج اللغة الكبيرة (LLMs) على جهاز الكمبيوتر الخاص بك.",
"minimax.description": "MiniMax هي شركة تكنولوجيا الذكاء الاصطناعي العامة التي تأسست في عام 2021، تكرس جهودها للتعاون مع المستخدمين في إنشاء الذكاء. طورت MiniMax نماذج كبيرة عامة من أوضاع مختلفة، بما في ذلك نموذج نصي MoE الذي يحتوي على تريليونات من المعلمات، ونموذج صوتي، ونموذج صور. وقد أطلقت تطبيقات مثل Conch AI.",
"mistral.description": "تقدم Mistral نماذج متقدمة عامة ومتخصصة وبحثية، تستخدم على نطاق واسع في الاستدلال المعقد، والمهام متعددة اللغات، وتوليد الشيفرات، من خلال واجهة استدعاء الوظائف، يمكن للمستخدمين دمج وظائف مخصصة لتحقيق تطبيقات محددة.",
"modelscope.description": "ModelScope هو منصة نموذج كخدمة أطلقتها علي بابا كلاود، تقدم مجموعة واسعة من نماذج الذكاء الاصطناعي وخدمات الاستدلال.",
"moonshot.description": "Moonshot هي منصة مفتوحة أطلقتها شركة Beijing Dark Side Technology Co.، Ltd، تقدم مجموعة متنوعة من نماذج معالجة اللغة الطبيعية، وتغطي مجالات واسعة، بما في ذلك ولكن لا تقتصر على إنشاء المحتوى، والبحث الأكاديمي، والتوصيات الذكية، والتشخيص الطبي، وتدعم معالجة النصوص الطويلة والمهام المعقدة.",
"nebius.description": "نيبيوس توفر بنية تحتية عالية الأداء للمبتكرين في مجال الذكاء الاصطناعي حول العالم من خلال بناء مجموعات ضخمة من وحدات معالجة الرسومات ومنصة سحابية متكاملة رأسياً.",
"newapi.description": "منصة مفتوحة المصدر لتجميع وتحويل خدمات الذكاء الاصطناعي المتعددة بشكل موحد",
"novita.description": "Novita AI هي منصة تقدم خدمات API لمجموعة متنوعة من نماذج اللغة الكبيرة وتوليد الصور بالذكاء الاصطناعي، مرنة وموثوقة وفعالة من حيث التكلفة. تدعم أحدث النماذج مفتوحة المصدر مثل Llama3 وMistral، وتوفر حلول API شاملة وسهلة الاستخدام وقابلة للتوسع تلقائيًا لتطوير تطبيقات الذكاء الاصطناعي، مما يجعلها مناسبة لنمو الشركات الناشئة في مجال الذكاء الاصطناعي.",
"nvidia.description": قدم NVIDIA NIM حاويات يمكن استخدامها لاستضافة خدمات استدلال معززة بواسطة GPU، تدعم نشر نماذج الذكاء الاصطناعي المدربة مسبقًا والمخصصة على السحابة ومراكز البيانات وأجهزة الكمبيوتر الشخصية RTX™ ومحطات العمل.",
"ollama.description": غطي نماذج Ollama مجموعة واسعة من مجالات توليد الشيفرة، والعمليات الرياضية، ومعالجة اللغات المتعددة، والتفاعل الحواري، وتدعم احتياجات النشر على مستوى المؤسسات والتخصيص المحلي.",
"ollamacloud.description": "توفر Ollama Cloud خدمة استدلال مُدارة رسميًا، تتيح الوصول الفوري إلى مكتبة نماذج Ollama، وتدعم واجهة متوافقة مع OpenAI.",
"openai.description": "OpenAI هي مؤسسة رائدة عالميًا في أبحاث الذكاء الاصطناعي، حيث دفعت النماذج التي طورتها مثل سلسلة GPT حدود معالجة اللغة الطبيعية. تلتزم OpenAI بتغيير العديد من الصناعات من خلال حلول الذكاء الاصطناعي المبتكرة والفعالة. تتمتع منتجاتهم بأداء ملحوظ وفعالية من حيث التكلفة، وتستخدم على نطاق واسع في البحث والتجارة والتطبيقات الابتكارية.",
"openrouter.description": "OpenRouter هي منصة خدمة تقدم واجهات لمجموعة متنوعة من النماذج الكبيرة المتقدمة، تدعم OpenAI وAnthropic وLLaMA وغيرها، مما يجعلها مناسبة لاحتياجات التطوير والتطبيق المتنوعة. يمكن للمستخدمين اختيار النموذج والسعر الأمثل وفقًا لاحتياجاتهم، مما يعزز تجربة الذكاء الاصطناعي.",
"perplexity.description": "Perplexity هي شركة رائدة في تقديم نماذج توليد الحوار، تقدم مجموعة من نماذج Llama 3.1 المتقدمة، تدعم التطبيقات عبر الإنترنت وغير المتصلة، وتناسب بشكل خاص مهام معالجة اللغة الطبيعية المعقدة.",
"ppio.description": قدم PPIO بايو السحابية خدمات واجهة برمجة التطبيقات لنماذج مفتوحة المصدر مستقرة وذات تكلفة فعالة، تدعم جميع سلسلة DeepSeek، وLlama، وQwen، وغيرها من النماذج الكبيرة الرائدة في الصناعة.",
"qiniu.description": "كشركة رائدة في خدمات السحابة، تقدم Qiniu خدمات استدلال ذكاء اصطناعي في الوقت الفعلي ومجموعة كبيرة بتكلفة فعالة وموثوقة، سهلة الاستخدام.",
"qwen.description": "Qwen هو نموذج لغة ضخم تم تطويره ذاتيًا بواسطة Alibaba Cloud، يتمتع بقدرات قوية في فهم وتوليد اللغة الطبيعية. يمكنه الإجابة على مجموعة متنوعة من الأسئلة، وكتابة المحتوى، والتعبير عن الآراء، وكتابة الشيفرات، ويؤدي دورًا في مجالات متعددة.",
"replicate.description": "Replicate تُشغّل نماذج الصور مفتوحة المصدر مثل FLUX وStable Diffusion من خلال واجهة برمجة تطبيقات سحابية بسيطة.",
"sambanova.description": "تتيح لك سحابة SambaNova استخدام أفضل النماذج مفتوحة المصدر بسهولة، والاستمتاع بأسرع سرعة استدلال.",
"search1api.description": "يوفر Search1API الوصول إلى سلسلة نماذج DeepSeek التي يمكن الاتصال بها حسب الحاجة، بما في ذلك النسخة القياسية والنسخة السريعة، مع دعم لاختيار نماذج بمقاييس معلمات متعددة.",
"sensenova.description": "تقدم شركة SenseTime خدمات نماذج كبيرة شاملة وسهلة الاستخدام، مدعومة بقوة من البنية التحتية الكبيرة لشركة SenseTime.",
"siliconcloud.description": "تسعى SiliconFlow إلى تسريع الذكاء الاصطناعي العام (AGI) لفائدة البشرية، من خلال تحسين كفاءة الذكاء الاصطناعي على نطاق واسع باستخدام حزمة GenAI سهلة الاستخدام وذات التكلفة المنخفضة.",
"spark.description": "تقدم شركة iFlytek نموذج Spark الكبير، الذي يوفر قدرات ذكاء اصطناعي قوية عبر مجالات متعددة ولغات متعددة، باستخدام تقنيات معالجة اللغة الطبيعية المتقدمة، لبناء تطبيقات مبتكرة مناسبة للأجهزة الذكية، والرعاية الصحية الذكية، والتمويل الذكي، وغيرها من السيناريوهات الرأسية.",
"stepfun.description": "نموذج StepFun الكبير يتمتع بقدرات متعددة الوسائط واستدلال معقد رائدة في الصناعة، ويدعم فهم النصوص الطويلة جدًا وميزات قوية لمحرك البحث الذاتي.",
"taichu.description": "أطلقت الأكاديمية الصينية للعلوم ومعهد ووهان للذكاء الاصطناعي نموذجًا جديدًا متعدد الوسائط، يدعم أسئلة وأجوبة متعددة الجولات، وإنشاء النصوص، وتوليد الصور، وفهم 3D، وتحليل الإشارات، ويغطي مجموعة شاملة من مهام الأسئلة والأجوبة، مع قدرات أقوى في الإدراك والفهم والإبداع، مما يوفر تجربة تفاعلية جديدة.",
"tencentcloud.description": "قدرة المحرك المعرفي الذري (LLM Knowledge Engine Atomic Power) هي قدرة كاملة للإجابة على الأسئلة مبنية على تطوير المحرك المعرفي، موجهة نحو الشركات والمطورين، وتوفر القدرة على تجميع وتطوير تطبيقات النماذج بشكل مرن. يمكنك من خلال مجموعة من القدرات الذرية تجميع خدمة النموذج الخاصة بك، واستدعاء خدمات تحليل الوثائق، والتقسيم، والتضمين، وإعادة الكتابة متعددة الجولات، لتخصيص أعمال الذكاء الاصطناعي الخاصة بالشركة.",
"togetherai.description": سعى Together AI لتحقيق أداء رائد من خلال نماذج الذكاء الاصطناعي المبتكرة، وتقدم مجموعة واسعة من القدرات المخصصة، بما في ذلك دعم التوسع السريع وعمليات النشر البديهية، لتلبية احتياجات الشركات المتنوعة.",
"upstage.description": تخصص Upstage في تطوير نماذج الذكاء الاصطناعي لتلبية احتياجات الأعمال المتنوعة، بما في ذلك Solar LLM وDocument AI، بهدف تحقيق الذكاء الاصطناعي العام (AGI) القائم على العمل. من خلال واجهة Chat API، يمكن إنشاء وكلاء حوار بسيطين، وتدعم استدعاء الوظائف، والترجمة، والتضمين، وتطبيقات المجالات المحددة.",
"v0.description": "v0 هو مساعد برمجة تعاوني، كل ما عليك هو وصف أفكارك بلغة طبيعية، وسيقوم بإنشاء الشيفرة وواجهة المستخدم (UI) لمشروعك.",
"vercelaigateway.description": "بوابة Vercel AI توفر واجهة برمجة تطبيقات موحدة للوصول إلى أكثر من 100 نموذج، من خلال نقطة نهاية واحدة يمكن استخدامها مع نماذج مقدمي خدمات مثل OpenAI وAnthropic وGoogle وغيرها. تدعم إعداد الميزانية، مراقبة الاستخدام، موازنة تحميل الطلبات والتبديل التلقائي عند الفشل.",
"vertexai.description": "سلسلة جيميني من جوجل هي نماذج الذكاء الاصطناعي الأكثر تقدمًا وعمومية، تم تطويرها بواسطة جوجل ديب مايند، مصممة خصيصًا لتكون متعددة الوسائط، تدعم الفهم والمعالجة السلسة للنصوص، الأكواد، الصور، الصوتيات، والفيديو. تناسب مجموعة متنوعة من البيئات، من مراكز البيانات إلى الأجهزة المحمولة، مما يعزز بشكل كبير كفاءة نماذج الذكاء الاصطناعي وتطبيقاتها الواسعة.",
"vllm.description": "vLLM هو مكتبة سريعة وسهلة الاستخدام لاستدلال LLM والخدمات.",
"volcengine.description": "منصة تطوير خدمات النماذج الكبيرة التي أطلقتها بايت دانس، تقدم خدمات استدعاء نماذج غنية بالوظائف وآمنة وتنافسية من حيث الأسعار، كما توفر بيانات النماذج، والتعديل الدقيق، والاستدلال، والتقييم، وغيرها من الوظائف الشاملة، لضمان تطوير تطبيقات الذكاء الاصطناعي الخاصة بك بشكل كامل.",
"wenxin.description": "منصة تطوير وخدمات النماذج الكبيرة والتطبيقات الأصلية للذكاء الاصطناعي على مستوى المؤسسات، تقدم مجموعة شاملة وسهلة الاستخدام من أدوات تطوير النماذج الذكية التوليدية وأدوات تطوير التطبيقات على مدار العملية بأكملها.",
"xai.description": "xAI هي شركة تكرّس جهودها لبناء الذكاء الاصطناعي لتسريع الاكتشافات العلمية البشرية. مهمتنا هي تعزيز فهمنا المشترك للكون.",
"xinference.description": "Xorbits Inference (Xinference) هو منصة مفتوحة المصدر مصممة لتبسيط تشغيل ودمج نماذج الذكاء الاصطناعي المتنوعة. باستخدام Xinference، يمكنك تشغيل الاستدلال على نماذج LLM مفتوحة المصدر، ونماذج التضمين، والنماذج متعددة الوسائط سواء في السحابة أو في البيئات المحلية، وإنشاء تطبيقات ذكاء اصطناعي قوية.",
"zenmux.description": "ZenMux هو منصة موحدة لتجميع خدمات الذكاء الاصطناعي، تدعم العديد من واجهات خدمات الذكاء الاصطناعي الرائدة مثل OpenAI وAnthropic وGoogle VertexAI. توفر قدرة توجيه مرنة تتيح لك التبديل وإدارة نماذج الذكاء الاصطناعي المختلفة بسهولة.",
"zeroone.description": "01.AI تركز على تقنيات الذكاء الاصطناعي في عصر الذكاء الاصطناعي 2.0، وتعزز الابتكار والتطبيقات \"الإنسان + الذكاء الاصطناعي\"، باستخدام نماذج قوية وتقنيات ذكاء اصطناعي متقدمة لتعزيز إنتاجية البشر وتحقيق تمكين التكنولوجيا.",
"zhipu.description": قدم Zhipu AI منصة مفتوحة للنماذج متعددة الوسائط ونماذج اللغة، تدعم مجموعة واسعة من سيناريوهات تطبيقات الذكاء الاصطناعي، بما في ذلك معالجة النصوص، وفهم الصور، والمساعدة في البرمجة."
"ai21.description": "تقوم AI21 Labs ببناء نماذج أساسية وأنظمة ذكاء اصطناعي للمؤسسات، مما يسرّع من تطبيق الذكاء الاصطناعي التوليدي في بيئات الإنتاج.",
"ai302.description": "302.AI هي منصة ذكاء اصطناعي تعتمد على الدفع حسب الاستخدام، وتقدم مجموعة واسعة من واجهات برمجة التطبيقات (APIs) والتطبيقات الذكية عبر الإنترنت.",
"ai360.description": "360 AI هي منصة نماذج وخدمات من شركة 360، تقدم نماذج معالجة اللغة الطبيعية مثل 360GPT2 Pro و360GPT Pro و360GPT Turbo. تجمع هذه النماذج بين المعلمات واسعة النطاق والقدرات متعددة الوسائط لتوليد النصوص، وفهم المعاني، والدردشة، والبرمجة، مع تسعير مرن لتلبية احتياجات متنوعة.",
"aihubmix.description": "يوفر AiHubMix الوصول إلى نماذج ذكاء اصطناعي متعددة من خلال واجهة برمجة تطبيقات موحدة.",
"akashchat.description": "أكاش هو سوق موارد سحابية غير مركزي يتميز بأسعار تنافسية مقارنة بمزودي الخدمات السحابية التقليديين.",
"anthropic.description": "تقوم Anthropic بتطوير نماذج لغوية متقدمة مثل Claude 3.5 Sonnet وClaude 3 Sonnet وClaude 3 Opus وClaude 3 Haiku، وتوازن بين الذكاء والسرعة والتكلفة لتناسب مختلف حالات الاستخدام من المؤسسات إلى الاستجابات السريعة.",
"azure.description": قدم Azure نماذج ذكاء اصطناعي متقدمة، بما في ذلك سلسلة GPT-3.5 وGPT-4، لمعالجة أنواع بيانات متنوعة ومهام معقدة مع التركيز على الأمان والموثوقية والاستدامة.",
"azureai.description": "توفر Azure نماذج ذكاء اصطناعي متقدمة، بما في ذلك سلسلة GPT-3.5 وGPT-4، لمعالجة أنواع بيانات متنوعة ومهام معقدة مع التركيز على الأمان والموثوقية والاستدامة.",
"baichuan.description": "تركز Baichuan AI على النماذج الأساسية ذات الأداء القوي في المعرفة الصينية، ومعالجة السياقات الطويلة، والتوليد الإبداعي. تم تحسين نماذجها (Baichuan 4 وBaichuan 3 Turbo وBaichuan 3 Turbo 128k) لسيناريوهات مختلفة وتقدم قيمة عالية.",
"bedrock.description": "توفر Amazon Bedrock للمؤسسات نماذج لغوية وبصرية متقدمة، بما في ذلك Anthropic Claude وMeta Llama 3.1، بدءًا من الخيارات الخفيفة إلى عالية الأداء لمهام النصوص والدردشة والصور.",
"bfl.description": "مختبر أبحاث رائد في مجال الذكاء الاصطناعي المتقدم، يعمل على بناء البنية التحتية البصرية للمستقبل.",
"cerebras.description": "Cerebras هي منصة استدلال تعتمد على نظام CS-3، تركز على تقديم خدمات نماذج لغوية كبيرة بزمن استجابة منخفض جدًا وسرعة عالية لمهام الوقت الحقيقي مثل توليد الأكواد والمهام التفاعلية.",
"cloudflare.description": "تشغيل نماذج تعلم الآلة المعتمدة على وحدات معالجة الرسومات (GPU) بدون خوادم عبر شبكة Cloudflare العالمية.",
"cohere.description": "تقدم Cohere نماذج متعددة اللغات متطورة، واسترجاعًا متقدمًا، ومساحات عمل ذكاء اصطناعي للمؤسسات الحديثة كل ذلك ضمن منصة آمنة واحدة.",
"cometapi.description": "توفر CometAPI الوصول إلى نماذج متقدمة من OpenAI وAnthropic وGoogle وغيرها، مما يتيح للمستخدمين اختيار النموذج والسعر الأنسب لحالات الاستخدام المختلفة.",
"comfyui.description": "محرك سير عمل مفتوح المصدر قوي لتوليد الصور والفيديو والصوت، يدعم نماذج مثل SD وFLUX وQwen وHunyuan وWAN مع تحرير قائم على العقد ونشر خاص.",
"deepseek.description": "تركز DeepSeek على أبحاث وتطبيقات الذكاء الاصطناعي؛ تتفوق أحدث نماذجها DeepSeek-V3 على نماذج مفتوحة مثل Qwen2.5-72B وLlama-3.1-405B، وتقترب من أداء النماذج المغلقة الرائدة مثل GPT-4o وClaude-3.5-Sonnet.",
"fal.description": "منصة وسائط توليدية مصممة للمطورين.",
"fireworksai.description": "توفر Fireworks AI خدمات نماذج لغوية متقدمة مع دعم استدعاء الوظائف والمعالجة متعددة الوسائط. تم تحسين Firefunction V2 (المبني على Llama-3) لاستدعاء الوظائف والدردشة وتنفيذ التعليمات، بينما يدعم FireLLaVA-13B إدخال الصور والنصوص معًا. تشمل النماذج الأخرى Llama وMixtral.",
"giteeai.description": "توفر Gitee AI واجهات برمجة تطبيقات بدون خوادم لخدمات استدلال النماذج اللغوية الكبيرة، جاهزة للاستخدام من قبل المطورين.",
"github.description": "مع نماذج GitHub، يمكن للمطورين العمل كمهندسي ذكاء اصطناعي باستخدام نماذج رائدة في الصناعة.",
"google.description": "عائلة Gemini من Google هي أكثر نماذج الذكاء الاصطناعي تطورًا للأغراض العامة، تم تطويرها بواسطة Google DeepMind للاستخدام متعدد الوسائط عبر النصوص والرموز والصور والصوت والفيديو. يمكن تشغيلها من مراكز البيانات إلى الأجهزة المحمولة بكفاءة عالية وانتشار واسع.",
"groq.description": "توفر محركات الاستدلال LPU من Groq أداءً متميزًا في المعايير مع سرعة وكفاءة استثنائية، مما يضع معيارًا عاليًا للاستدلال منخفض الكمون في السحابة.",
"higress.description": "Higress هو بوابة API سحابية أصلية تم تطويرها داخل Alibaba لمعالجة تأثير إعادة تحميل Tengine على الاتصالات طويلة الأمد وسد الفجوات في موازنة تحميل gRPC/Dubbo.",
"huggingface.description": وفر واجهة برمجة التطبيقات للاستدلال من Hugging Face طريقة سريعة لاستكشاف آلاف النماذج لمهام متعددة، مع وصول فوري إلى نماذج عالية الأداء لتجارب النماذج وتطوير تعلم الآلة.",
"hunyuan.description": "نموذج لغوي كبير من تطوير Tencent يتميز بقدرات قوية في الكتابة باللغة الصينية، والتفكير المنطقي في السياقات المعقدة، وتنفيذ المهام بدقة.",
"infiniai.description": "توفر خدمات نماذج لغوية كبيرة عالية الأداء وسهلة الاستخدام وآمنة لمطوري التطبيقات، تغطي كامل دورة العمل من تطوير النموذج إلى نشره في الإنتاج.",
"internlm.description": "منظمة مفتوحة المصدر تركز على أبحاث النماذج الكبيرة والأدوات، وتوفر منصة فعالة وسهلة الاستخدام تتيح الوصول إلى أحدث النماذج والخوارزميات.",
"jina.description": "تأسست Jina AI في عام 2020، وهي شركة رائدة في مجال البحث الذكي. تشمل تقنياتها نماذج المتجهات، ومعيدو الترتيب، ونماذج لغوية صغيرة لبناء تطبيقات بحث توليدية ومتعددة الوسائط عالية الجودة.",
"lmstudio.description": "LM Studio هو تطبيق سطح مكتب لتطوير وتجربة النماذج اللغوية الكبيرة على جهازك.",
"minimax.description": "تأسست MiniMax في عام 2021، وتبني نماذج ذكاء اصطناعي متعددة الوسائط للأغراض العامة، بما في ذلك نماذج نصية بمليارات المعلمات، ونماذج صوتية وبصرية، بالإضافة إلى تطبيقات مثل Hailuo AI.",
"mistral.description": "تقدم Mistral نماذج متقدمة عامة ومتخصصة وبحثية للتفكير المعقد، والمهام متعددة اللغات، وتوليد الأكواد، مع دعم استدعاء الوظائف للتكامل المخصص.",
"modelscope.description": "ModelScope هي منصة نماذج كخدمة من Alibaba Cloud، تقدم مجموعة واسعة من النماذج وخدمات الاستدلال.",
"moonshot.description": "تقدم Moonshot، من Moonshot AI (شركة Beijing Moonshot Technology نماذج معالجة لغة طبيعية متعددة لحالات استخدام مثل إنشاء المحتوى، والبحث، والتوصيات، والتحليل الطبي، مع دعم قوي للسياقات الطويلة والتوليد المعقد.",
"nebius.description": "توفر Nebius بنية تحتية عالية الأداء لمبتكري الذكاء الاصطناعي حول العالم من خلال مجموعات GPU واسعة النطاق ومنصة سحابية متكاملة رأسياً.",
"newapi.description": "منصة مفتوحة المصدر لتجميع وتوجيه خدمات الذكاء الاصطناعي المتعددة.",
"novita.description": "تقدم Novita AI واجهات برمجة تطبيقات مرنة وموثوقة وفعالة من حيث التكلفة للنماذج اللغوية الكبيرة وتوليد الصور. تدعم نماذج مثل Llama 3 وMistral وتوفر واجهات برمجة تطبيقات قابلة للتوسع وسهلة الاستخدام للشركات الناشئة في مجال الذكاء الاصطناعي التوليدي.",
"nvidia.description": وفر NVIDIA NIM حاويات لخدمات استدلال ذاتية الاستضافة مع تسريع GPU عبر السحابة ومراكز البيانات وأجهزة RTX AI وأجهزة العمل، للنماذج المدربة مسبقًا والمخصصة.",
"ollama.description": قدم Ollama نماذج لتوليد الأكواد، والرياضيات، والمعالجة متعددة اللغات، والدردشة، مع دعم للنشر المؤسسي والمحلي.",
"ollamacloud.description": "توفر Ollama Cloud استدلالًا مدارًا مع وصول فوري إلى مكتبة نماذج Ollama وواجهات برمجة تطبيقات متوافقة مع OpenAI.",
"openai.description": "OpenAI هي مختبر أبحاث رائد في مجال الذكاء الاصطناعي، طورت نماذج GPT التي أحدثت تقدمًا كبيرًا في معالجة اللغة الطبيعية، مع أداء قوي وقيمة عالية في البحث والأعمال والابتكار.",
"openrouter.description": "يوفر OpenRouter الوصول إلى العديد من النماذج المتقدمة من OpenAI وAnthropic وLLaMA وغيرها، مما يتيح للمستخدمين اختيار النموذج والسعر الأنسب لحالتهم.",
"perplexity.description": "تقدم Perplexity نماذج دردشة متقدمة، بما في ذلك إصدارات Llama 3.1، للاستخدام عبر الإنترنت وغير المتصل ولمهام معالجة اللغة الطبيعية المعقدة.",
"ppio.description": وفر PPIO واجهات برمجة تطبيقات موثوقة وفعالة من حيث التكلفة للنماذج المفتوحة، بما في ذلك DeepSeek وLlama وQwen وغيرها من النماذج الرائدة.",
"qiniu.description": "توفر Qiniu خدمات استدلال ذكاء اصطناعي في الوقت الحقيقي وعلى دفعات، موثوقة وسهلة الاستخدام وفعالة من حيث التكلفة.",
"qwen.description": "Qwen هو نموذج لغوي كبير من Alibaba Cloud يتميز بفهم وتوليد قوي، ويغطي الأسئلة والأجوبة، والكتابة، والتعبير عن الرأي، والبرمجة في مجالات متعددة.",
"replicate.description": "تشغل Replicate نماذج صور مفتوحة المصدر مثل FLUX وStable Diffusion عبر واجهة برمجة تطبيقات سحابية بسيطة.",
"sambanova.description": "تتيح SambaNova Cloud للمطورين استخدام نماذج مفتوحة المصدر رائدة مع استدلال فائق السرعة.",
"search1api.description": "توفر Search1API الوصول إلى نماذج DeepSeek مع إمكانية الاتصال بالويب، بما في ذلك إصدارات قياسية وسريعة بأحجام معلمات متعددة.",
"sensenova.description": "تقدم SenseNova خدمات نماذج لغوية كبيرة كاملة المكدس، فعالة وسهلة الاستخدام، مدعومة ببنية SenseTime التحتية.",
"siliconcloud.description": "SiliconCloud هي خدمة سحابية للذكاء الاصطناعي التوليدي فعالة من حيث التكلفة، مبنية على نماذج مفتوحة المصدر قوية.",
"spark.description": "يوفر iFLYTEK Spark ذكاءً اصطناعيًا متعدد اللغات قويًا عبر مجالات متعددة، مما يمكّن من الابتكار في الأجهزة الذكية والرعاية الصحية والتمويل وغيرها.",
"stepfun.description": "تقدم نماذج Stepfun قدرات رائدة في التعدد الوسائطي والتفكير المعقد، مع فهم طويل للسياق وتنظيم بحث مستقل قوي.",
"taichu.description": "Taichu هو نموذج متعدد الوسائط من الجيل التالي من CASIA ومعهد ووهان للذكاء الاصطناعي، يدعم الأسئلة والأجوبة متعددة الجولات، والكتابة، وتوليد الصور، وفهم الأبعاد الثلاثية، وتحليل الإشارات بقدرات إدراكية وإبداعية متقدمة.",
"tencentcloud.description": "توفر Tencent Cloud محرك معرفة قائم على النماذج اللغوية الكبيرة يقدم إجابات معرفية شاملة للمؤسسات والمطورين، مع خدمات معيارية مثل تحليل المستندات، والتقسيم، والتضمين، وإعادة الصياغة متعددة الجولات لبناء حلول ذكاء اصطناعي مخصصة.",
"togetherai.description": وفر Together AI أداءً رائدًا من خلال نماذج مبتكرة، وتخصيص واسع، وتوسع سريع، ونشر بسيط لتلبية احتياجات المؤسسات.",
"upstage.description": قوم Upstage ببناء نماذج ذكاء اصطناعي لتلبية احتياجات الأعمال، بما في ذلك Solar LLM وDocument AI، مع واجهات دردشة تدعم استدعاء الوظائف، والترجمة، والتضمين، وحالات الاستخدام المتخصصة.",
"v0.description": "v0 هو مساعد برمجة ثنائي يحول الأفكار المكتوبة بلغة طبيعية إلى كود وواجهة مستخدم لمشروعك.",
"vercelaigateway.description": "يوفر Vercel AI Gateway واجهة برمجة تطبيقات موحدة لأكثر من 100 نموذج من OpenAI وAnthropic وGoogle وغيرها، مع ميزات الميزانية، ومراقبة الاستخدام، وموازنة التحميل، والتجاوز التلقائي.",
"vertexai.description": "عائلة Gemini من Google هي أكثر نماذج الذكاء الاصطناعي تطورًا للأغراض العامة، تم تطويرها بواسطة Google DeepMind للاستخدام متعدد الوسائط عبر النصوص والرموز والصور والصوت والفيديو. يمكن تشغيلها من مراكز البيانات إلى الأجهزة المحمولة، مما يعزز الكفاءة ومرونة النشر.",
"vllm.description": "vLLM مكتبة سريعة وسهلة الاستخدام لاستدلال وخدمة النماذج اللغوية الكبيرة.",
"volcengine.description": "توفر منصة نماذج ByteDance وصولًا آمنًا وغنيًا بالميزات وفعالًا من حيث التكلفة إلى النماذج، بالإضافة إلى أدوات شاملة للبيانات، والتخصيص، والاستدلال، والتقييم.",
"wenxin.description": "منصة متكاملة للمؤسسات لتطوير النماذج الأساسية والتطبيقات الذكية، تقدم أدوات شاملة لسير عمل النماذج التوليدية وتطبيقاتها.",
"xai.description": "تقوم xAI ببناء ذكاء اصطناعي لتسريع الاكتشاف العلمي، بهدف تعميق فهم البشرية للكون.",
"xinference.description": "Xorbits Inference (Xinference) هي منصة مفتوحة المصدر تسهّل تشغيل ودمج نماذج الذكاء الاصطناعي. تتيح تشغيل النماذج اللغوية الكبيرة، ونماذج التضمين، والنماذج متعددة الوسائط محليًا أو في السحابة لبناء تطبيقات ذكاء اصطناعي قوية.",
"zenmux.description": "ZenMux هي منصة تجميع ذكاء اصطناعي موحدة تدعم OpenAI وAnthropic وGoogle VertexAI وغيرها، مع توجيه مرن لتبديل وإدارة النماذج بسهولة.",
"zeroone.description": "01.AI تقود ثورة الذكاء الاصطناعي 2.0 المتمحورة حول الإنسان، باستخدام النماذج اللغوية الكبيرة لخلق قيمة اقتصادية واجتماعية وبناء أنظمة بيئية ونماذج أعمال جديدة.",
"zhipu.description": وفر ZhiPu AI منصة مفتوحة للنماذج متعددة الوسائط واللغوية، تغطي معالجة النصوص، وفهم الصور، والمساعدة في البرمجة."
}
+18 -18
View File
@@ -1,42 +1,42 @@
{
"addDataset.confirm": "إنشاء جديد",
"addDataset.confirm": "إنشاء",
"addDataset.description.placeholder": "وصف مجموعة البيانات (اختياري)",
"addDataset.name.placeholder": "اسم مجموعة البيانات",
"addDataset.name.required": "يرجى إدخال اسم مجموعة البيانات",
"addDataset.title": "إضافة مجموعة بيانات",
"dataset.addNewButton": "إنشاء مجموعة بيانات",
"dataset.emptyGuide": "مجموعة البيانات الحالية فارغة، يرجى إنشاء مجموعة بيانات.",
"dataset.list.table.actions.importData": "استيراد البيانات",
"dataset.emptyGuide": "لا توجد مجموعات بيانات حالياً. يرجى إنشاء مجموعة بيانات.",
"dataset.list.table.actions.importData": "استيراد بيانات",
"dataset.list.table.columns.actions": "الإجراءات",
"dataset.list.table.columns.ideal.title": "الإجابة المثالية",
"dataset.list.table.columns.ideal.title": "الإجابة المتوقعة",
"dataset.list.table.columns.question.title": "السؤال",
"dataset.list.table.columns.referenceFiles.title": "ملفات مرجعية",
"dataset.list.table.notSelected": "يرجى اختيار مجموعة بيانات من اليسار",
"dataset.list.table.columns.referenceFiles.title": "الملفات المرجعية",
"dataset.list.table.notSelected": "يرجى اختيار مجموعة بيانات من القائمة على اليسار",
"dataset.list.table.title": "تفاصيل مجموعة البيانات",
"dataset.list.title": "مجموعة البيانات",
"evaluation.addEvaluation.confirm": "إنشاء جديد",
"evaluation.addEvaluation.datasetId.placeholder": "يرجى اختيار مجموعة بيانات التقييم الخاصة بك",
"evaluation.addEvaluation.datasetId.required": "يرجى اختيار مجموعة بيانات التقييم",
"evaluation.addEvaluation.confirm": "إنشاء",
"evaluation.addEvaluation.datasetId.placeholder": "يرجى اختيار مجموعة البيانات للتقييم",
"evaluation.addEvaluation.datasetId.required": "يرجى اختيار مجموعة بيانات للتقييم",
"evaluation.addEvaluation.description.placeholder": "وصف مهمة التقييم (اختياري)",
"evaluation.addEvaluation.name.placeholder": "اسم مهمة التقييم",
"evaluation.addEvaluation.name.required": "يرجى إدخال اسم مهمة التقييم",
"evaluation.addEvaluation.title": "إضافة مهمة تقييم",
"evaluation.addNewButton": "إنشاء تقييم",
"evaluation.emptyGuide": "مهمة التقييم الحالية فارغة، ابدأ بإنشاء تقييم.",
"evaluation.table.columns.actions.checkStatus": "تحقق من الحالة",
"evaluation.table.columns.actions.confirmDelete": "هل تريد حذف هذه المهمة من التقييم؟",
"evaluation.table.columns.actions.confirmRun": "هل تريد بدء التشغيل؟ بعد بدء التشغيل، سيتم تنفيذ مهمة التقييم في الخلفية بشكل غير متزامن، وإغلاق الصفحة لن يؤثر على تنفيذ المهمة غير المتزامنة.",
"evaluation.table.columns.actions.downloadRecords": "تنزيل السجلات",
"evaluation.emptyGuide": "لا توجد مهام تقييم حالياً. ابدأ بإنشاء تقييم.",
"evaluation.table.columns.actions.checkStatus": "التحقق من الحالة",
"evaluation.table.columns.actions.confirmDelete": "هل أنت متأكد أنك تريد حذف هذا التقييم؟",
"evaluation.table.columns.actions.confirmRun": "هل أنت متأكد أنك تريد بدء التشغيل؟ سيتم تنفيذ مهمة التقييم بشكل غير متزامن في الخلفية، ولن يؤثر إغلاق الصفحة على تنفيذ المهمة.",
"evaluation.table.columns.actions.downloadRecords": "تنزيل التقييم",
"evaluation.table.columns.actions.retry": "إعادة المحاولة",
"evaluation.table.columns.actions.run": "تشغيل",
"evaluation.table.columns.actions.title": "الإجراءات",
"evaluation.table.columns.datasetId.title": "مجموعة البيانات",
"evaluation.table.columns.name.title": "اسم مهمة التقييم",
"evaluation.table.columns.records.title": "عدد سجلات التقييم",
"evaluation.table.columns.referenceFiles.title": "ملفات مرجعية",
"evaluation.table.columns.status.error": "حدث خطأ أثناء التنفيذ",
"evaluation.table.columns.status.pending": "في انتظار التشغيل",
"evaluation.table.columns.status.processing": "جارٍ التشغيل",
"evaluation.table.columns.referenceFiles.title": "الملفات المرجعية",
"evaluation.table.columns.status.error": "خطأ في التنفيذ",
"evaluation.table.columns.status.pending": "قيد الانتظار",
"evaluation.table.columns.status.processing": "قيد التنفيذ",
"evaluation.table.columns.status.success": "تم التنفيذ بنجاح",
"evaluation.table.columns.status.title": "الحالة",
"evaluation.table.title": "قائمة مهام التقييم"
+352 -355
View File
@@ -1,539 +1,536 @@
{
"_cloud.officialProvider": "خدمة النماذج الرسمية من {{name}}",
"about.title": "حول",
"advancedSettings": "الإعدادات المتقدمة",
"agentInfoDescription.basic.avatar": "الصورة الرمزية",
"agentInfoDescription.basic.description": "الوصف",
"agentInfoDescription.basic.name": "الاسم",
"agentInfoDescription.basic.tags": "الوسوم",
"agentInfoDescription.basic.title": "معلومات المساعد",
"agentInfoDescription.chat.enableHistoryCount": "تمكين عداد الرسائل السابقة",
"agentInfoDescription.chat.historyCount": "عدد الرسائل السابقة",
"agentInfoDescription.basic.title": "معلومات الوكيل",
"agentInfoDescription.chat.enableHistoryCount": "تمكين عداد سجل الرسائل",
"agentInfoDescription.chat.historyCount": "عدد الرسائل في السجل",
"agentInfoDescription.chat.no": "لا",
"agentInfoDescription.chat.searchMode": "وضع البحث",
"agentInfoDescription.chat.title": "تفضيلات الدردشة",
"agentInfoDescription.chat.title": "تفضيلات المحادثة",
"agentInfoDescription.chat.yes": "نعم",
"agentInfoDescription.model.maxTokens": "الحد الأقصى للرموز",
"agentInfoDescription.model.model": "النموذج",
"agentInfoDescription.model.provider": "المزود",
"agentInfoDescription.model.temperature": "درجة الحرارة",
"agentInfoDescription.model.temperature": "درجة الإبداع",
"agentInfoDescription.model.title": "إعدادات النموذج",
"agentInfoDescription.model.topP": "قيمة Top P",
"agentInfoDescription.plugins.count": "إعدادات الإضافات ({{count}})",
"agentInfoDescription.plugins.empty": م يتم تثبيت أي إضافات بعد",
"agentInfoDescription.plugins.title": "الإضافات المثبتة",
"agentInfoDescription.role.systemRole": "تعليمات النظام",
"agentInfoDescription.role.title": "إعدادات الدور",
"agentInfoDescription.value.unset": "غير مُعيّن",
"agentInfoDescription.value.untitled": "مساعد بدون عنوان",
"agentTab.chat": "تفضيلات الدردشة",
"agentTab.meta": "معلومات المساعد",
"agentInfoDescription.plugins.count": "إعدادات المهارات ({{count}})",
"agentInfoDescription.plugins.empty": ا توجد مهارات مثبتة بعد",
"agentInfoDescription.plugins.title": "المهارات المثبتة",
"agentInfoDescription.role.systemRole": "ملف تعريف الوكيل",
"agentInfoDescription.role.title": "ملف تعريف الوكيل",
"agentInfoDescription.value.unset": "غير محدد",
"agentInfoDescription.value.untitled": "وكيل بدون عنوان",
"agentTab.chat": "تفضيلات المحادثة",
"agentTab.meta": "معلومات الوكيل",
"agentTab.modal": "إعدادات النموذج",
"agentTab.opening": "إعداد الافتتاح",
"agentTab.plugin": "إعدادات الإضافة",
"agentTab.prompt": "تعيين الشخصية",
"agentTab.tts": "خدمة النص إلى كلام",
"analytics.telemetry.desc": "من خلال اختيار إرسال بيانات القياس عن بُعد، يمكنك مساعدتنا في تحسين تجربة المستخدم العامة لـ {{appName}}",
"analytics.telemetry.title": "إرسال بيانات الاستخدام المجهولة",
"analytics.title": "تحليلات",
"agentTab.opening": "إعدادات البداية",
"agentTab.plugin": "إعدادات المهارات",
"agentTab.prompt": "ملف تعريف الوكيل",
"agentTab.tts": "خدمة الصوت",
"analytics.telemetry.desc": "ساعدنا في تحسين {{appName}} من خلال بيانات استخدام مجهولة",
"analytics.telemetry.title": "إرسال بيانات استخدام مجهولة",
"analytics.title": "التحليلات",
"checking": "جارٍ التحقق...",
"checkingPermissions": "جارٍ التحقق من الأذونات...",
"danger.clear.action": "مسح الآن",
"danger.clear.confirm": "هل تؤكد مسح جميع بيانات المحادثات؟",
"danger.clear.desc": "سيتم مسح جميع بيانات الجلسة بما في ذلك المساعد والملفات والرسائل والإضافات",
"danger.clear.confirm": "هل تريد مسح جميع بيانات المحادثة؟ لا يمكن التراجع عن هذا الإجراء.",
"danger.clear.desc": "سيتم حذف جميع البيانات، بما في ذلك الوكلاء والملفات والرسائل والمهارات. لن يتم حذف حسابك.",
"danger.clear.success": "تم مسح جميع رسائل الجلسة",
"danger.clear.title": "مسح جميع رسائل الجلسة",
"danger.reset.action": "إعادة تعيين الآن",
"danger.reset.confirm": "هل تؤكد إعادة تعيين جميع الإعدادات؟",
"danger.clear.title": "مسح البيانات",
"danger.reset.action": "إعادة التعيين الآن",
"danger.reset.confirm": "هل تريد إعادة تعيين جميع الإعدادات؟",
"danger.reset.currentVersion": "الإصدار الحالي",
"danger.reset.desc": "إعادة تعيين جميع عناصر الإعدادات إلى القيم الافتراضية",
"danger.reset.success": "تمت إعادة ضبط جميع الإعدادات",
"danger.reset.desc": "استعادة جميع الإعدادات إلى الوضع الافتراضي. لن يتم حذف بياناتك.",
"danger.reset.success": "تمت إعادة تعيين جميع الإعدادات",
"danger.reset.title": "إعادة تعيين جميع الإعدادات",
"defaultAgent.model.desc": "النموذج الافتراضي المستخدم عند إنشاء وكيل جديد",
"defaultAgent.model.title": "النموذج",
"defaultAgent.title": "إعدادات المساعد الافتراضي",
"group.aiConfig": "إعدادات الذكاء الاصطناعي",
"defaultAgent.title": "إعدادات الوكيل الافتراضي",
"group.aiConfig": "النموذج",
"group.common": "عام",
"group.profile": "الحساب",
"group.subscription": "الاشتراك",
"group.system": "النظام",
"groupTab.chat": "الدردشة",
"groupTab.chat": "المحادثة",
"groupTab.members": "الأعضاء",
"groupTab.meta": "المعلومات الأساسية",
"header.desc": "إعدادات التفضيلات والنماذج.",
"header.global": "إعدادات عامة",
"header.group": "إعدادات الفريق",
"header.groupDesc": "إدارة المجموعات وتفضيلات الدردشة",
"groupTab.meta": "معلومات أساسية",
"header.desc": "تفضيلات وإعدادات النموذج",
"header.global": "الإعدادات العامة",
"header.group": "إعدادات المجموعة",
"header.groupDesc": "إدارة المجموعة وتفضيلات المحادثة",
"header.session": "إعدادات الجلسة",
"header.sessionDesc": "إعداد الشخصية وتفضيلات الجلسة.",
"header.sessionDesc": "ملف تعريف الوكيل وتفضيلات الجلسة",
"header.sessionWithName": "إعدادات الجلسة · {{name}}",
"header.title": "إعدادات",
"hotkey.conflicts": "يتعارض مع اختصارات لوحة المفاتيح الحالية",
"hotkey.errors.CONFLICT": "تعارض في اختصار لوحة المفاتيح: هذا الاختصار مستخدم بالفعل من قبل وظيفة أخرى",
"hotkey.errors.INVALID_FORMAT": "تنسيق اختصار لوحة المفاتيح غير صالح: يرجى استخدام التنسيق الصحيح (مثل CommandOrControl+E)",
"hotkey.errors.INVALID_ID": "معرف اختصار لوحة المفاتيح غير صالح",
"hotkey.errors.NO_MODIFIER": "يجب أن يحتوي اختصار لوحة المفاتيح على مفتاح تعديل (Ctrl، Alt، Shift، إلخ)",
"hotkey.errors.SYSTEM_OCCUPIED": "اختصار لوحة المفاتيح مستخدم من قبل النظام أو تطبيقات أخرى",
"header.title": "الإعدادات",
"hotkey.conflicts": "تعارض مع اختصارات موجودة",
"hotkey.errors.CONFLICT": "تعارض في الاختصار: هذا الاختصار مستخدم بالفعل لوظيفة أخرى",
"hotkey.errors.INVALID_FORMAT": "تنسيق اختصار غير صالح: يرجى استخدام التنسيق الصحيح (مثل CommandOrControl+E)",
"hotkey.errors.INVALID_ID": "معرف اختصار غير صالح",
"hotkey.errors.NO_MODIFIER": "يجب أن يحتوي الاختصار على مفتاح معدل (Ctrl، Alt، Shift، إلخ)",
"hotkey.errors.SYSTEM_OCCUPIED": "الاختصار مستخدم من قبل النظام أو تطبيق آخر",
"hotkey.errors.UNKNOWN": "فشل التحديث: خطأ غير معروف",
"hotkey.group.conversation": "المحادثة",
"hotkey.group.desktop": "سطح المكتب",
"hotkey.group.essential": "أساسي",
"hotkey.invalidCombination": "يجب أن تحتوي اختصارات لوحة المفاتيح على مفتاح تعديل واحد على الأقل (Ctrl، Alt، Shift) ومفتاح عادي واحد",
"hotkey.record": "اضغط على المفتاح لتسجيل اختصار لوحة المفاتيح",
"hotkey.reset": "إعادة تعيين إلى اختصارات لوحة المفاتيح الافتراضية",
"hotkey.title": "اختصارات لوحة المفاتيح",
"hotkey.updateError": "فشل تحديث اختصار لوحة المفاتيح: خطأ في الشبكة أو النظام",
"hotkey.updateSuccess": "تم تحديث اختصار لوحة المفاتيح بنجاح",
"llm.aesGcm": "سيتم استخدام خوارزمية التشفير <1>AES-GCM</1> لتشفير مفتاحك وعنوان الوكيل",
"llm.apiKey.desc": "يرجى ملء مفتاح API الخاص بك {{name}}",
"llm.apiKey.placeholder": "{{name}} مفتاح API",
"hotkey.invalidCombination": "يجب أن يحتوي الاختصار على مفتاح معدل واحد على الأقل (Ctrl، Alt، Shift) ومفتاح عادي واحد",
"hotkey.record": "اضغط على مفتاح لتسجيل الاختصار",
"hotkey.reset": "إعادة تعيين الاختصارات إلى الوضع الافتراضي",
"hotkey.title": "الاختصارات",
"hotkey.updateError": "فشل تحديث الاختصار: خطأ في الشبكة أو النظام",
"hotkey.updateSuccess": "تم تحديث الاختصار بنجاح",
"llm.aesGcm": "سيتم تشفير مفاتيحك وعنوان الوكيل باستخدام خوارزمية التشفير <1>AES-GCM</1>",
"llm.apiKey.desc": "يرجى إدخال مفتاح API الخاص بـ {{name}}",
"llm.apiKey.placeholder": "مفتاح API الخاص بـ {{name}}",
"llm.apiKey.title": "مفتاح API",
"llm.checker.button": "فحص",
"llm.checker.desc": "اختبار ما إذا كان مفتاح واجهة البرمجة وعنوان الوكيل مملوء بشكل صحيح",
"llm.checker.pass": "تمت المراقبة",
"llm.checker.button": "تحقق",
"llm.checker.desc": "اختبر ما إذا تم ملء مفتاح API وعنوان الوكيل بشكل صحيح",
"llm.checker.pass": "تم التحقق بنجاح",
"llm.checker.title": "فحص الاتصال",
"llm.customModelCards.addNew": "إنشاء وإضافة نموذج {{id}}",
"llm.customModelCards.config": كوين النموذج",
"llm.customModelCards.confirmDelete": "سيتم حذف النموذج المخصص هذا، وبمجرد الحذف لا يمكن استعادته، يرجى التحلي بالحذر.",
"llm.customModelCards.modelConfig.azureDeployName.extra": "الحقل الفعلي المطلوب في طلب Azure OpenAI",
"llm.customModelCards.modelConfig.azureDeployName.placeholder": "الرجاء إدخال اسم نشر النموذج في Azure",
"llm.customModelCards.config": هيئة النموذج",
"llm.customModelCards.confirmDelete": "أنت على وشك حذف هذا النموذج المخصص. لا يمكن استعادته بعد الحذف. يرجى المتابعة بحذر.",
"llm.customModelCards.modelConfig.azureDeployName.extra": "الحقل المطلوب فعليًا في Azure OpenAI",
"llm.customModelCards.modelConfig.azureDeployName.placeholder": "أدخل اسم نشر النموذج في Azure",
"llm.customModelCards.modelConfig.azureDeployName.title": "اسم نشر النموذج",
"llm.customModelCards.modelConfig.displayName.placeholder": "الرجاء إدخال اسم العرض للنموذج، مثل ChatGPT، GPT-4، إلخ",
"llm.customModelCards.modelConfig.displayName.title": "اسم العرض للنموذج",
"llm.customModelCards.modelConfig.files.extra": "تنفيذ تحميل الملفات الحالي هو مجرد حل Hack، ومخصص للتجربة الذاتية فقط. يرجى الانتظار حتى يتم تنفيذ القدرة الكاملة على تحميل الملفات لاحقًا",
"llm.customModelCards.modelConfig.displayName.placeholder": "أدخل اسم العرض للنموذج، مثل ChatGPT، GPT-4، إلخ.",
"llm.customModelCards.modelConfig.displayName.title": "اسم عرض النموذج",
"llm.customModelCards.modelConfig.files.extra": "تنفيذ تحميل الملفات الحالي هو حل مؤقت مخصص للتجارب الشخصية فقط. يرجى انتظار ميزة تحميل الملفات الكاملة في التحديثات القادمة.",
"llm.customModelCards.modelConfig.files.title": "دعم تحميل الملفات",
"llm.customModelCards.modelConfig.functionCall.extra": "ستفتح هذه الإعدادات فقط القدرة على استدعاء الوظائف داخل التطبيق، وما إذا كانت الوظائف مدعومة يعتمد تمامًا على النموذج نفسه، يرجى اختبار قابلية استخدام استدعاء الوظائف لهذا النموذج بنفسك",
"llm.customModelCards.modelConfig.functionCall.title": "دعم استدعاء الوظائف",
"llm.customModelCards.modelConfig.id.extra": "سيتم عرضه كعلامة للنموذج",
"llm.customModelCards.modelConfig.id.placeholder": "الرجاء إدخال معرف النموذج، مثل gpt-4-turbo-preview أو claude-2.1",
"llm.customModelCards.modelConfig.functionCall.extra": "هذا يمكّن فقط استدعاء المهارات داخل التطبيق. دعم النموذج الفعلي لاستدعاء المهارات يعتمد على النموذج نفسه يرجى اختباره.",
"llm.customModelCards.modelConfig.functionCall.title": "يدعم استدعاء المهارات",
"llm.customModelCards.modelConfig.id.extra": "سيتم عرضه كاسم النموذج",
"llm.customModelCards.modelConfig.id.placeholder": "أدخل معرف النموذج، مثل gpt-4-turbo-preview أو claude-2.1",
"llm.customModelCards.modelConfig.id.title": "معرف النموذج",
"llm.customModelCards.modelConfig.modalTitle": كوين النموذج المخصص",
"llm.customModelCards.modelConfig.tokens.title": "أقصى عدد من الرموز",
"llm.customModelCards.modelConfig.vision.extra": "ستفتح هذه الإعدادات فقط القدرة على تحميل الصور داخل التطبيق، وما إذا كانت القدرة على التعرف مدعومة يعتمد تمامًا على النموذج نفسه، يرجى اختبار قابلية استخدام التعرف البصري لهذا النموذج بنفسك",
"llm.customModelCards.modelConfig.vision.title": "دعم التعرف على الصور",
"llm.fetchOnClient.desc": "طريقة طلب العميل ستبدأ طلب الجلسة مباشرة من المتصفح، مما يمكن أن يعزز سرعة الاستجابة",
"llm.fetchOnClient.title": "استخدام طريقة طلب العميل",
"llm.fetcher.clear": "مسح النموذج المستخرج",
"llm.fetcher.fetch": "احصل على قائمة النماذج",
"llm.fetcher.fetching": "جاري الحصول على قائمة النماذج...",
"llm.customModelCards.modelConfig.modalTitle": هيئة النموذج المخصص",
"llm.customModelCards.modelConfig.tokens.title": "الحد الأقصى لعدد الرموز",
"llm.customModelCards.modelConfig.vision.extra": "هذا يمكّن فقط تحميل الصور داخل التطبيق. دعم النموذج للرؤية يعتمد على النموذج نفسه يرجى اختباره.",
"llm.customModelCards.modelConfig.vision.title": "يدعم الرؤية",
"llm.fetchOnClient.desc": "إرسال الطلبات مباشرة من المتصفح لتحسين زمن الاستجابة.",
"llm.fetchOnClient.title": "استخدام وضع طلب العميل",
"llm.fetcher.clear": "مسح النموذج المسترجع",
"llm.fetcher.fetch": "جلب قائمة النماذج",
"llm.fetcher.fetching": "جارٍ جلب قائمة النماذج...",
"llm.fetcher.latestTime": "آخر تحديث: {{time}}",
"llm.fetcher.noLatestTime": م يتم الحصول على قائمة بعد",
"llm.helpDoc": "دليل التكوين",
"llm.modelList.desc": "اختيار النموذج الذي سيتم عرضه في الجلسة، سيتم عرض النموذج المحدد في قائمة النماذج",
"llm.modelList.placeholder": "الرجاء اختيار نموذج من القائمة",
"llm.fetcher.noLatestTime": ا توجد قائمة متاحة بعد",
"llm.helpDoc": "دليل التهيئة",
"llm.modelList.desc": "حدد النماذج التي سيتم عرضها في الجلسة. سيتم عرض النماذج المحددة في قائمة النماذج.",
"llm.modelList.placeholder": "يرجى اختيار نموذج من القائمة",
"llm.modelList.title": "قائمة النماذج",
"llm.modelList.total": "متاح {{count}} نموذج",
"llm.proxyUrl.desc": "يجب أن يتضمن عنوان الوكيل API بالإضافة إلى العنوان الافتراضي http(s)://",
"llm.modelList.total": "إجمالي النماذج المتاحة: {{count}}",
"llm.proxyUrl.desc": "يجب أن يتضمن http(s):// بالإضافة إلى العنوان الافتراضي",
"llm.proxyUrl.title": "عنوان وكيل API",
"llm.waitingForMore": "يتم <1>التخطيط لتوفير</1> المزيد من النماذج، ترقبوا المزيد",
"llm.waitingForMoreLinkAriaLabel": "افتح نموذج طلب دمج مزود الخدمة النموذجية",
"marketPublish.modal.changelog.extra": "صف التغييرات والتحسينات الرئيسية في هذا الإصدار",
"llm.waitingForMore": "سيتم <1>إضافة المزيد من النماذج</1> قريبًا، ترقبوا",
"llm.waitingForMoreLinkAriaLabel": "فتح نموذج طلب المزود",
"marketPublish.modal.changelog.extra": "وصف التغييرات والتحسينات الرئيسية في هذا الإصدار",
"marketPublish.modal.changelog.label": "سجل التغييرات",
"marketPublish.modal.changelog.maxLengthError": "لا يمكن أن يتجاوز سجل التغييرات 500 حرف",
"marketPublish.modal.changelog.placeholder": "يرجى إدخال سجل التغييرات",
"marketPublish.modal.changelog.maxLengthError": "يجب ألا يتجاوز سجل التغييرات 500 حرف",
"marketPublish.modal.changelog.placeholder": "أدخل سجل التغييرات",
"marketPublish.modal.changelog.required": "يرجى إدخال سجل التغييرات",
"marketPublish.modal.comparison.local": "الإصدار المحلي الحالي",
"marketPublish.modal.comparison.remote": "الإصدار المنشور الحالي",
"marketPublish.modal.identifier.extra": "سيكون المعرف هو الهوية الفريدة للمساعد، يُفضل استخدام أحرف صغيرة وأرقام وشرطات",
"marketPublish.modal.identifier.label": "معرف المساعد",
"marketPublish.modal.comparison.remote": "الإصدار المنشور حاليًا",
"marketPublish.modal.identifier.extra": "هذا هو المعرف الفريد للوكيل. استخدم أحرفًا صغيرة وأرقامًا وشرطات.",
"marketPublish.modal.identifier.label": "معرف الوكيل",
"marketPublish.modal.identifier.lengthError": "يجب أن يتراوح طول المعرف بين 3 و50 حرفًا",
"marketPublish.modal.identifier.patternError": "يمكن أن يحتوي المعرف فقط على أحرف صغيرة وأرقام وشرطات",
"marketPublish.modal.identifier.placeholder": "يرجى إدخال معرف فريد للمساعد، مثل: web-development",
"marketPublish.modal.identifier.required": "يرجى إدخال معرف المساعد",
"marketPublish.modal.identifier.placeholder": "أدخل معرفًا فريدًا للوكيل، مثل web-development",
"marketPublish.modal.identifier.required": "يرجى إدخال معرف الوكيل",
"marketPublish.modal.loading.fetchingRemote": "جارٍ تحميل البيانات البعيدة...",
"marketPublish.modal.loading.submit": "جارٍ نشر المساعد...",
"marketPublish.modal.loading.submit": "جارٍ إرسال الوكيل...",
"marketPublish.modal.loading.upload": "جارٍ نشر الإصدار الجديد...",
"marketPublish.modal.messages.createVersionFailed": "فشل إنشاء الإصدار: {{message}}",
"marketPublish.modal.messages.fetchRemoteFailed": "فشل في جلب بيانات المساعد من السوق",
"marketPublish.modal.messages.missingIdentifier": "لا يحتوي هذا المساعد على معرف المجتمع حتى الآن",
"marketPublish.modal.messages.notAuthenticated": "يرجى تسجيل الدخول إلى حساب المجتمع أولاً",
"marketPublish.modal.messages.createVersionFailed": "فشل في إنشاء الإصدار: {{message}}",
"marketPublish.modal.messages.fetchRemoteFailed": "فشل في جلب بيانات الوكيل البعيدة",
"marketPublish.modal.messages.missingIdentifier": "لا يحتوي هذا الوكيل على معرف المجتمع بعد.",
"marketPublish.modal.messages.notAuthenticated": "يرجى تسجيل الدخول إلى حسابك في المجتمع أولاً.",
"marketPublish.modal.messages.publishFailed": "فشل النشر: {{message}}",
"marketPublish.modal.submitButton": "نشر",
"marketPublish.modal.title.submit": "مشاركة في مجتمع المساعدين",
"marketPublish.modal.title.submit": "مشاركة في مجتمع الوكلاء",
"marketPublish.modal.title.upload": "نشر إصدار جديد",
"marketPublish.resultModal.message": "تم إرسال المساعد الذي أنشأته للمراجعة، وسيتم نشره تلقائيًا بعد الموافقة.",
"marketPublish.resultModal.message": "تم إرسال وكيلك للمراجعة. بمجرد الموافقة عليه، سيتم نشره تلقائيًا.",
"marketPublish.resultModal.title": "تم الإرسال بنجاح",
"marketPublish.resultModal.view": "عرض في المجتمع",
"marketPublish.submit.button": "مشاركة في المجتمع",
"marketPublish.submit.tooltip": "شارك المساعد في مجتمع المساعدين",
"marketPublish.submit.tooltip": "شارك هذا الوكيل في المجتمع",
"marketPublish.upload.button": "نشر إصدار جديد",
"marketPublish.upload.tooltip": "نشر إصدار جديد في مجتمع المساعدين",
"memory.enabled.desc": "عند التفعيل، سيتذكر الذكاء الاصطناعي تفضيلاتك من سجل المحادثات، ويجمع الذكريات لاستخدامها كمرجع في المحادثات المستقبلية",
"memory.enabled.title": فعيل ميزة الذاكرة",
"marketPublish.upload.tooltip": "نشر إصدار جديد في مجتمع الوكلاء",
"memory.enabled.desc": "اسمح لـ LobeHub باستخلاص التفضيلات والمعلومات من المحادثات واستخدامها لاحقًا. يمكنك عرض أو تعديل أو مسح الذاكرة في أي وقت.",
"memory.enabled.title": مكين الذاكرة",
"memory.title": "إعدادات الذاكرة",
"message.success": "تم التحديث بنجاح",
"myAgents.actions.cancel": "إلغاء",
"myAgents.actions.confirmDeprecate": "تأكيد الإهمال",
"myAgents.actions.deprecate": همال دائم",
"myAgents.actions.deprecateConfirmContent": "بعد الإهمال، سيتم إزالة هذا المساعد نهائيًا من السوق ولن يكون من الممكن إعادة نشره. هذا الإجراء لا يمكن التراجع عنه، يرجى الحذر.",
"myAgents.actions.deprecateConfirmTitle": "هل تريد تأكيد إهمال المساعد؟",
"myAgents.actions.deprecateError": "فشل في إهمال المساعد",
"myAgents.actions.deprecateLoading": "جارٍ إهمال المساعد...",
"myAgents.actions.deprecateSuccess": "تم إهمال المساعد",
"myAgents.actions.edit": حرير المساعد",
"myAgents.actions.publish": "نشر المساعد",
"myAgents.actions.publishError": "فشل في نشر المساعد",
"myAgents.actions.publishLoading": "جارٍ نشر المساعد...",
"myAgents.actions.publishSuccess": "تم نشر المساعد",
"myAgents.actions.unpublish": "إلغاء نشر المساعد",
"myAgents.actions.unpublishError": "فشل في إلغاء نشر المساعد",
"myAgents.actions.unpublishLoading": "جارٍ إلغاء نشر المساعد...",
"myAgents.actions.unpublishSuccess": "تم إلغاء نشر المساعد",
"myAgents.actions.confirmDeprecate": "تأكيد الإيقاف",
"myAgents.actions.deprecate": يقاف دائم",
"myAgents.actions.deprecateConfirmContent": "بعد الإيقاف، سيتم إزالة هذا الوكيل نهائيًا من السوق ولا يمكن إعادة نشره. هذا الإجراء لا يمكن التراجع عنه، يرجى المتابعة بحذر.",
"myAgents.actions.deprecateConfirmTitle": "هل تريد تأكيد إيقاف الوكيل؟",
"myAgents.actions.deprecateError": "فشل في إيقاف الوكيل",
"myAgents.actions.deprecateLoading": "جارٍ إيقاف الوكيل...",
"myAgents.actions.deprecateSuccess": "تم إيقاف الوكيل",
"myAgents.actions.edit": عديل الوكيل",
"myAgents.actions.publish": "نشر الوكيل",
"myAgents.actions.publishError": "فشل في نشر الوكيل",
"myAgents.actions.publishLoading": "جارٍ نشر الوكيل...",
"myAgents.actions.publishSuccess": "تم نشر الوكيل",
"myAgents.actions.unpublish": "إلغاء نشر الوكيل",
"myAgents.actions.unpublishError": "فشل في إلغاء نشر الوكيل",
"myAgents.actions.unpublishLoading": "جارٍ إلغاء نشر الوكيل...",
"myAgents.actions.unpublishSuccess": "تم إلغاء نشر الوكيل",
"myAgents.actions.viewDetail": "عرض التفاصيل",
"myAgents.detail.category": "الفئة",
"myAgents.detail.description": "الوصف",
"myAgents.detail.identifier": "المعرّف",
"myAgents.detail.title": "تفاصيل المساعد",
"myAgents.empty.description": "لم تقم بنشر أي مساعد في السوق بعد",
"myAgents.empty.title": "لا يوجد مساعدين منشورين",
"myAgents.errors.editFailed": "فشل في تحرير المساعد، يرجى المحاولة لاحقًا",
"myAgents.errors.fetchFailed": "فشل في جلب تفاصيل المساعد",
"myAgents.detail.identifier": "المعرف",
"myAgents.detail.title": "تفاصيل الوكيل",
"myAgents.empty.description": "لم تقم بنشر أي وكلاء في السوق بعد",
"myAgents.empty.title": "لا يوجد وكلاء منشورون",
"myAgents.errors.editFailed": "فشل في تعديل الوكيل، يرجى المحاولة لاحقًا",
"myAgents.errors.fetchFailed": "فشل في جلب تفاصيل الوكيل",
"myAgents.errors.notAuthenticated": "يرجى تسجيل الدخول إلى حساب السوق أولاً",
"myAgents.loginRequired.button": "تسجيل الدخول إلى حساب السوق",
"myAgents.loginRequired.description": "يرجى تسجيل الدخول إلى حساب السوق لعرض المساعدين الذين قمت بنشرهم",
"myAgents.loginRequired.title": "تسجيل الدخول مطلوب",
"myAgents.loginRequired.button": "تسجيل الدخول إلى السوق",
"myAgents.loginRequired.description": "يرجى تسجيل الدخول إلى حساب السوق لعرض وكلائك المنشورين",
"myAgents.loginRequired.title": "مطلوب تسجيل الدخول",
"myAgents.status.archived": "مؤرشف",
"myAgents.status.deprecated": همل",
"myAgents.status.deprecated": وقوف",
"myAgents.status.published": "منشور",
"myAgents.status.unpublished": "غير منشور",
"myAgents.title": "مساعدي المنشور",
"plugin.addMCPPlugin": "إضافة مكون MCP",
"plugin.addTooltip": "إضافة البرنامج المساعد",
"plugin.clearDeprecated": "مسح البرامج المساعدة الغير صالحة",
"plugin.empty": "لا توجد برامج مساعدة مثبتة حاليًا، نرحب بك لزيارة <1>متجر البرامج المساعدة</1> للاستكشاف",
"myAgents.title": "وكلائي المنشورون",
"plugin.addMCPPlugin": "إضافة MCP",
"plugin.addTooltip": "مهارات مخصصة",
"plugin.clearDeprecated": "إزالة المهارات الموقوفة",
"plugin.empty": "لا توجد مهارات مثبتة بعد. استكشف <1>متجر المهارات</1> للبدء.",
"plugin.installStatus.deprecated": "تم إلغاء التثبيت",
"plugin.settings.hint": "يرجى ملء الإعدادات التالية وفقًا للوصف",
"plugin.settings.title": "إعدادات البرنامج المساعد {{id}}",
"plugin.settings.tooltip": "إعدادات البرنامج المساعد",
"plugin.store": "متجر البرامج المساعد",
"settingAgent.avatar.sizeExceeded": "تجاوز حجم الصورة الحد الأقصى المسموح به وهو 1 ميغابايت، يرجى اختيار صورة أصغر.",
"plugin.settings.hint": "يرجى ملء الإعدادات التالية بناءً على الوصف",
"plugin.settings.title": "إعدادات مهارة {{id}}",
"plugin.settings.tooltip": "إعدادات المهارة",
"plugin.store": "متجر المهارات",
"settingAgent.avatar.sizeExceeded": "يتجاوز حجم الصورة 1 ميجابايت، يرجى اختيار صورة أصغر",
"settingAgent.avatar.title": "الصورة الرمزية",
"settingAgent.backgroundColor.title": "لون الخلفية",
"settingAgent.description.desc": "مقدمة بسيطة عن مساعدك، لا تستخدم كإعداد شخصية",
"settingAgent.description.placeholder": "الرجاء إدخال وصف المساعد",
"settingAgent.description.title": "وصف المساعد",
"settingAgent.name.placeholder": "الرجاء إدخال اسم المساعد",
"settingAgent.description.desc": "مقدمة موجزة عن وكيلك، ليست لإعداد الشخصية",
"settingAgent.description.placeholder": "أدخل وصف الوكيل",
"settingAgent.description.title": "وصف الوكيل",
"settingAgent.name.placeholder": "أدخل اسم الوكيل",
"settingAgent.name.title": "الاسم",
"settingAgent.prompt.placeholder": "أدخل إعدادات المساعد، اضغط / لفتح قائمة الأوامر",
"settingAgent.prompt.title": "إعدادات المساعد",
"settingAgent.submit": "تحديث معلومات المساعد",
"settingAgent.tag.desc": "سيتم عرض وسم المساعد في مجتمع المساعدين",
"settingAgent.tag.placeholder": "الرجاء إدخال العلامة",
"settingAgent.prompt.placeholder": "أدخل إعدادات الوكيل، اضغط / لفتح قائمة الأوامر",
"settingAgent.prompt.templatePlaceholder": "#### الهدف\nوصف الغرض الرئيسي والهدف من هذا الوكيل.\n\n#### المهارات\n- سرد القدرات الرئيسية\n- ومجالات المعرفة المتخصصة\n\n#### سير العمل\n1. عملية خطوة بخطوة\n2. كيفية تعامل الوكيل مع المهام\n3. التفاعلات المتوقعة مع المستخدمين\n\n#### القيود\n- القيود المهمة التي يجب الالتزام بها\n- إرشادات السلوك",
"settingAgent.prompt.title": "ملف تعريف الوكيل",
"settingAgent.submit": "تحديث الوكيل",
"settingAgent.tag.desc": "سيتم عرض علامات الوكيل في مجتمع الوكلاء",
"settingAgent.tag.placeholder": "أدخل علامة",
"settingAgent.tag.title": "العلامة",
"settingAgent.title": "معلومات المساعد",
"settingAgent.title": "معلومات الوكيل",
"settingAppearance.animationMode.agile": "سريع",
"settingAppearance.animationMode.desc": "اختر سرعة استجابة حركة التطبيق",
"settingAppearance.animationMode.desc": "اختر سرعة الرسوم المتحركة لإجراءات استجابة التطبيق",
"settingAppearance.animationMode.disabled": "إيقاف",
"settingAppearance.animationMode.elegant": "أنيق",
"settingAppearance.animationMode.title": "حركة الاستجابة",
"settingAppearance.animationMode.title": "رسوم استجابة التطبيق",
"settingAppearance.contextMenuMode.default": "افتراضي",
"settingAppearance.contextMenuMode.desc": "اختر طريقة عرض قائمة النقر بزر الماوس الأيمن لرسائل الدردشة",
"settingAppearance.contextMenuMode.disabled": "عدم الاستخدام",
"settingAppearance.contextMenuMode.title": "خطة قائمة النقر بزر الماوس الأيمن",
"settingAppearance.neutralColor.desc": خصيص تدرجات الرمادي ذات الاتجاهات اللونية المختلفة",
"settingAppearance.neutralColor.title": "لون محايد",
"settingAppearance.noAnimation.desc": "تعطيل جميع تأثيرات الحركة في التطبيق",
"settingAppearance.noAnimation.title": "وضع بدون حركة",
"settingAppearance.contextMenuMode.desc": "تمكين قائمة النقر بزر الماوس الأيمن لبعض عناصر القائمة.",
"settingAppearance.contextMenuMode.disabled": عطل",
"settingAppearance.contextMenuMode.title": "وضع قائمة النقر الأيمن",
"settingAppearance.neutralColor.desc": "تدرجات رمادية مخصصة مع ميول لونية مختلفة",
"settingAppearance.neutralColor.title": "اللون المحايد",
"settingAppearance.noAnimation.desc": "تعطيل جميع تأثيرات الرسوم المتحركة في التطبيق",
"settingAppearance.noAnimation.title": "وضع بدون رسوم متحركة",
"settingAppearance.preview.title": "لوحة الألوان",
"settingAppearance.primaryColor.desc": "تخصيص لون الموضوع",
"settingAppearance.primaryColor.title": "لون الموضوع",
"settingAppearance.primaryColor.desc": "لون السمة المخصص",
"settingAppearance.primaryColor.title": "لون السمة",
"settingAppearance.title": "مظهر التطبيق",
"settingChat.autoCreateTopicThreshold.desc": "عند تجاوز عدد الرسائل الحالي هذا القيمة، سيتم إنشاء موضوع تلقائيًا",
"settingChat.autoCreateTopicThreshold.title": "عتبة إنشاء الموضوع التلقائي",
"settingChat.chatStyleType.title": وع نافذة الدردشة",
"settingChat.chatStyleType.type.chat": "نمط المحادثة",
"settingChat.chatStyleType.type.docs": "نمط الوثائق",
"settingChat.compressThreshold.desc": "عندما يتجاوز عدد الرسائل التاريخية غير المضغوطة هذه القيمة، سيتم ضغطها",
"settingChat.compressThreshold.title": "عتبة ضغط طول الرسائل التاريخية",
"settingChat.enableAutoCreateTopic.desc": "هل يجب إنشاء موضوع تلقائيًا أثناء الدردشة، يسري ذلك فقط في المواضيع المؤقتة",
"settingChat.enableAutoCreateTopic.title": "تمكين إنشاء الموضوع تلقائيًا",
"settingChat.enableCompressHistory.title": فعيل تلخيص الرسائل التاريخية تلقائيًا",
"settingChat.autoCreateTopicThreshold.desc": "إنشاء موضوع تلقائيًا عند تجاوز عدد الرسائل الحالية هذه القيمة",
"settingChat.autoCreateTopicThreshold.title": "حد الرسائل",
"settingChat.chatStyleType.title": مط نافذة الدردشة",
"settingChat.chatStyleType.type.chat": "وضع المحادثة",
"settingChat.chatStyleType.type.docs": "وضع الصفحة",
"settingChat.compressThreshold.desc": "عند تجاوز عدد الرسائل غير المضغوطة هذه القيمة، سيتم تطبيق الضغط",
"settingChat.compressThreshold.title": "حد ضغط طول سجل الرسائل",
"settingChat.enableAutoCreateTopic.desc": "ما إذا كان سيتم إنشاء موضوع تلقائيًا أثناء المحادثة، فعال فقط في المواضيع المؤقتة",
"settingChat.enableAutoCreateTopic.title": "إنشاء موضوع تلقائيًا",
"settingChat.enableCompressHistory.title": مكين التلخيص التلقائي لسجل الدردشة",
"settingChat.enableHistoryCount.alias": "غير محدود",
"settingChat.enableHistoryCount.limited": "يحتوي فقط على {{number}} رسالة محادثة",
"settingChat.enableHistoryCount.setlimited": عيين عدد الرسائل التاريخية",
"settingChat.enableHistoryCount.title": حديد عدد الرسائل التاريخية",
"settingChat.enableHistoryCount.unlimited": "غير محدود",
"settingChat.enableStreaming.desc": "تمكين الإخراج المتدفق لعرض الاستجابات في الوقت الفعلي. عند التعطيل، يتم عرض الاستجابة الكاملة فقط.",
"settingChat.enableHistoryCount.limited": "تضمين فقط {{number}} رسالة محادثة",
"settingChat.enableHistoryCount.setlimited": حديد عدد محدود من الرسائل",
"settingChat.enableHistoryCount.title": قييد عدد رسائل السجل",
"settingChat.enableHistoryCount.unlimited": "عدد غير محدود من رسائل السجل",
"settingChat.enableStreaming.desc": "تمكين الإخراج المتدفق لعرض الردود في الوقت الفعلي. عند التعطيل، يتم عرض الرد الكامل فقط.",
"settingChat.enableStreaming.title": "تمكين الإخراج المتدفق",
"settingChat.historyCount.desc": "عدد الرسائل التي يتم إرفاقها في كل طلب (تشمل الأسئلة والأجوبة الجديدة. يُحسب كل سؤال وجواب كرسالة واحدة)",
"settingChat.historyCount.title": "عدد الرسائل المرفقة",
"settingChat.inputTemplate.desc": "سيتم ملء أحدث رسالة من المستخدم في هذا القالب",
"settingChat.inputTemplate.placeholder": "القالب المُعالج مسبقًا {{text}} سيتم استبداله بالمعلومات المُدخلة في الوقت الحقيقي",
"settingChat.inputTemplate.title": "معالجة مُدخلات المستخدم",
"settingChat.historyCount.desc": "عدد الرسائل التاريخية المرفقة مع كل طلب",
"settingChat.historyCount.title": "عدد رسائل السجل المرفقة",
"settingChat.inputTemplate.desc": "سيتم ملء أحدث رسالة للمستخدم في هذا القالب",
"settingChat.inputTemplate.placeholder": "سيتم استبدال قالب المعالجة المسبقة {{text}} بمعلومات الإدخال الفعلية",
"settingChat.inputTemplate.title": "معالجة مسبقة لإدخال المستخدم",
"settingChat.submit": "تحديث تفضيلات الدردشة",
"settingChat.title": "إعدادات الدردشة",
"settingChatAppearance.fontSize.desc": "حجم خط محتوى الدردشة",
"settingChatAppearance.fontSize.marks.normal": "عادي",
"settingChatAppearance.fontSize.desc": "حجم خط الرسائل",
"settingChatAppearance.fontSize.marks.normal": "قياسي",
"settingChatAppearance.fontSize.title": "حجم الخط",
"settingChatAppearance.highlighterTheme.title": "موضوع تمييز الكود",
"settingChatAppearance.mermaidTheme.title": "موضوع حورية البحر",
"settingChatAppearance.highlighterTheme.title": "سمة تمييز الكود",
"settingChatAppearance.mermaidTheme.title": "سمة Mermaid",
"settingChatAppearance.title": "مظهر الدردشة",
"settingChatAppearance.transitionMode.desc": "رسوم انتقال رسائل الدردشة",
"settingChatAppearance.transitionMode.desc": "اختر كيفية ظهور رسائل الدردشة",
"settingChatAppearance.transitionMode.options.fadeIn": "تلاشي",
"settingChatAppearance.transitionMode.options.none.desc": "يعتمد هذا على طريقة إخراج استجابة النموذج، يرجى الاختبار بنفسك.",
"settingChatAppearance.transitionMode.options.none.desc": "يعتمد هذا على طريقة إخراج استجابة النموذج؛ يرجى اختباره بنفسك.",
"settingChatAppearance.transitionMode.options.none.value": "بدون",
"settingChatAppearance.transitionMode.options.smooth": "سلس",
"settingChatAppearance.transitionMode.title": "رسوم الانتقال",
"settingCommon.devMode.desc": "عند التفعيل، ستظهر الميزات والخيارات الخاصة بالمطورين",
"settingCommon.devMode.desc": "تمكين عرض الميزات والخيارات المتعلقة بالمطورين",
"settingCommon.devMode.title": "وضع المطور",
"settingCommon.lang.autoMode": "اتباع النظام",
"settingCommon.lang.title": "اللغة",
"settingCommon.liteMode.desc": "عند التفعيل، سيتم تبسيط الواجهة وإخفاء الميزات المتقدمة",
"settingCommon.liteMode.desc": "تبسيط الواجهة وإخفاء الميزات المتقدمة",
"settingCommon.liteMode.title": "الوضع المبسط",
"settingCommon.responseLanguage.auto": "اتباع إعدادات النظام",
"settingCommon.responseLanguage.desc": "تحديد اللغة التي يستخدمها الذكاء الاصطناعي في الردود",
"settingCommon.responseLanguage.auto": "اتباع النظام",
"settingCommon.responseLanguage.desc": "اختر لغة رد الوكيل",
"settingCommon.responseLanguage.placeholder": "اختر لغة الرد",
"settingCommon.responseLanguage.title": "لغة الرد",
"settingCommon.themeMode.auto": "تلقائي",
"settingCommon.themeMode.dark": "داكن",
"settingCommon.themeMode.light": "فاتح",
"settingCommon.themeMode.title": "الموضوع",
"settingCommon.themeMode.title": "السمة",
"settingCommon.title": "الإعدادات العامة",
"settingGroup.description.placeholder": "يرجى إدخال وصف الفريق",
"settingGroup.description.title": "وصف الفريق",
"settingGroup.name.placeholder": "يرجى إدخال اسم الفريق",
"settingGroup.name.title": "اسم الفريق",
"settingGroup.scene.desc": "اختر سيناريو الفريق",
"settingGroup.description.placeholder": "أدخل وصف المجموعة",
"settingGroup.description.title": "وصف المجموعة",
"settingGroup.name.placeholder": "أدخل اسم المجموعة",
"settingGroup.name.title": "اسم المجموعة",
"settingGroup.scene.desc": "اختر سيناريو المجموعة",
"settingGroup.scene.options.casual": "غير رسمي",
"settingGroup.scene.options.productive": "إنتاجي",
"settingGroup.scene.title": "سيناريو الفريق",
"settingGroup.submit": "تحديث الفريق",
"settingGroup.systemPrompt.placeholder": "يرجى إدخال كلمة تلميح نظام المضيف",
"settingGroup.systemPrompt.title": "كلمة تلميح نظام المضيف",
"settingGroup.scene.title": "سيناريو المجموعة",
"settingGroup.submit": "تحديث المجموعة",
"settingGroup.systemPrompt.placeholder": "يرجى إدخال موجه النظام الرئيسي",
"settingGroup.systemPrompt.title": "موجه النظام الرئيسي",
"settingGroup.title": "معلومات المجموعة",
"settingGroupChat.allowDM.desc": "عند الإيقاف، لا يزال بإمكانك إرسال رسائل خاصة إلى المساعد يدويًا",
"settingGroupChat.allowDM.title": "السماح للمساعد بإرسال رسائل خاصة",
"settingGroupChat.enableSupervisor.desc": فعيل ميزة المشرف على المجموعة، حيث يتولى المشرف إدارة سير المحادثات داخل الفريق",
"settingGroupChat.enableSupervisor.title": فعيل المشرف",
"settingGroupChat.maxResponseInRow.desc": "اختر عدد الرسائل التي يمكن للأعضاء الرد عليها بشكل متتالي. تعيين القيمة إلى 0 لتعطيل هذا القيد.",
"settingGroupChat.allowDM.desc": "عند الإيقاف، لا يزال بإمكانك إرسال رسائل مباشرة إلى الوكيل",
"settingGroupChat.allowDM.title": "السماح بالرسائل المباشرة من الوكيل",
"settingGroupChat.enableSupervisor.desc": مكين ميزة المنسق لإدارة محادثات المجموعة",
"settingGroupChat.enableSupervisor.title": مكين المنسق",
"settingGroupChat.maxResponseInRow.desc": "حدد عدد الرسائل المتتالية التي يمكن للعضو الرد بها. اضبط على 0 لتعطيل هذا الحد.",
"settingGroupChat.maxResponseInRow.title": "عدد الردود المتتالية",
"settingGroupChat.model.desc": "لن يتأثر حديث أعضاء المجموعة. بعض النماذج لا يمكن استخدامها كنماذج مشرف.",
"settingGroupChat.model.title": "نموذج المضيف",
"settingGroupChat.orchestratorTitle": "إعدادات المضيف",
"settingGroupChat.responseOrder.desc": "سيقوم الوكلاء بالرد وفقًا للترتيب المحدد في المحادثة",
"settingGroupChat.model.desc": "أعضاء المجموعة غير متأثرين. بعض النماذج لا يمكن استخدامها كنموذج منسق.",
"settingGroupChat.model.title": "نموذج المنسق",
"settingGroupChat.orchestratorTitle": "المنسق",
"settingGroupChat.responseOrder.desc": "يرد الوكلاء بناءً على ترتيبهم في الدردشة",
"settingGroupChat.responseOrder.options.natural": "طبيعي",
"settingGroupChat.responseOrder.options.sequential": تابعي",
"settingGroupChat.responseOrder.placeholder": "اختر ترتيب الردود",
"settingGroupChat.responseOrder.title": "ترتيب الردود",
"settingGroupChat.responseSpeed.desc": "التحكم في سرعة سير المحادثة بشكل عام",
"settingGroupChat.responseOrder.options.sequential": سلسلي",
"settingGroupChat.responseOrder.placeholder": "اختر ترتيب الرد",
"settingGroupChat.responseOrder.title": "ترتيب الرد",
"settingGroupChat.responseSpeed.desc": "التحكم في وتيرة المحادثة العامة",
"settingGroupChat.responseSpeed.options.fast": "سريع",
"settingGroupChat.responseSpeed.options.medium": "متوسط",
"settingGroupChat.responseSpeed.options.slow": "بطيء",
"settingGroupChat.responseSpeed.placeholder": "اختر سرعة الرد",
"settingGroupChat.responseSpeed.title": "سرعة الرد",
"settingGroupChat.revealDM.desc": "اجعل محتوى الرسائل الخاصة المرسلة إلى الأعضاء الآخرين مرئيًا لك.",
"settingGroupChat.revealDM.title": "عرض محتوى الرسائل الخاصة",
"settingGroupChat.revealDM.desc": "عرض الرسائل الخاصة المرسلة إلى أعضاء آخرين لك.",
"settingGroupChat.revealDM.title": "عرض الرسائل الخاصة",
"settingGroupChat.submit": "تحديث الإعدادات",
"settingGroupChat.systemPrompt.desc": "كلمة تلميح نظام مخصصة لمضيف محادثة الدردشة الجماعية. قد تؤثر على سلوك المضيف الافتراضي.",
"settingGroupChat.systemPrompt.placeholder": "يرجى إدخال كلمة تلميح نظام المضيف المخصصة...",
"settingGroupChat.systemPrompt.title": "كلمة تلميح نظام المضيف",
"settingGroupChat.systemPrompt.desc": "موجه نظام مخصص لمضيف دردشة المجموعة. قد يؤثر على سلوك المضيف الافتراضي.",
"settingGroupChat.systemPrompt.placeholder": "يرجى إدخال موجه نظام مخصص للمضيف...",
"settingGroupChat.systemPrompt.title": "موجه نظام المضيف",
"settingGroupChat.title": "إعدادات الدردشة",
"settingGroupMembers.addToGroup": "انضم إلى المجموعة",
"settingGroupMembers.availableAgents": "المساعدون المتاحون",
"settingGroupMembers.addToGroup": "إضافة إلى المجموعة",
"settingGroupMembers.availableAgents": "الوكلاء المتاحون",
"settingGroupMembers.createMember": "إنشاء عضو",
"settingGroupMembers.defaultAgent": "المساعد المخصص",
"settingGroupMembers.disableHost": "تعطيل مساعد المضيف",
"settingGroupMembers.edit": "تعديل الأعضاء",
"settingGroupMembers.empty": "لا يوجد أعضاء في هذا الفريق حاليًا. انقر على زر + لإضافة أعضاء.",
"settingGroupMembers.enableHost": "تمكين مساعد المضيف",
"settingGroupMembers.groupHost": "مضيف المجموعة",
"settingGroupMembers.defaultAgent": "وكيل مخصص",
"settingGroupMembers.disableHost": "تعطيل المنسق",
"settingGroupMembers.edit": "تعديل العضو",
"settingGroupMembers.empty": "لا يوجد أعضاء في هذه المجموعة بعد. انقر على + لإضافة أعضاء.",
"settingGroupMembers.enableHost": "تمكين المنسق",
"settingGroupMembers.groupHost": "المنسق",
"settingGroupMembers.groupMembers": "أعضاء المجموعة",
"settingGroupMembers.host.description": "عندما يكون المضيف في المجموعة، ستعمل الدردشة الجماعية بشكل تلقائي، مناسب للمهام الإبداعية.",
"settingGroupMembers.host.title": "المضيف",
"settingGroupMembers.noAvailableAgents": "لا يوجد مساعدين متاحين",
"settingGroupMembers.host.description": "مع وجود منسق، يمكن للمجموعة العمل تلقائيًا بشكل أكبر — مثالي للمهام المفتوحة.",
"settingGroupMembers.host.title": "المنسق",
"settingGroupMembers.noAvailableAgents": "لا يوجد وكلاء متاحون",
"settingGroupMembers.noDescription": "لا يوجد وصف",
"settingGroupMembers.noMembersInGroup": "لا يوجد أعضاء في المجموعة",
"settingGroupMembers.owner": "أنت (المالك)",
"settingGroupMembers.remove": "إزالة العضو",
"settingGroupMembers.removeFromGroup": خراج من المجموعة",
"settingGroupMembers.removeFromGroup": زالة من المجموعة",
"settingGroupMembers.you": "أنت",
"settingImage.defaultCount.desc": "اضبط عدد الصور الافتراضي عند إنشاء مهمة جديدة في لوحة توليد الصور.",
"settingImage.defaultCount.desc": "تحديد عدد الصور الافتراضي الذي يتم إنشاؤه عند بدء مهمة جديدة في لوحة توليد الصور.",
"settingImage.defaultCount.label": "عدد الصور الافتراضي",
"settingImage.defaultCount.title": "إعدادات الرسم بالذكاء الاصطناعي",
"settingModel.enableMaxTokens.title": مكين الحد الأقصى للردود",
"settingModel.enableReasoningEffort.title": مكين ضبط قوة الاستدلال",
"settingModel.frequencyPenalty.desc": "كلما زادت القيمة، كانت المفردات أكثر تنوعًا؛ وكلما انخفضت القيمة، كانت المفردات أكثر بساطة ووضوحًا",
"settingModel.frequencyPenalty.title": "تنوع المفردات",
"settingModel.maxTokens.desc": "عدد الرموز الأقصى المستخدمة في التفاعل الواحد",
"settingModel.maxTokens.title": "الحد الأقصى للردود",
"settingModel.model.desc": "{{provider}} نموذج",
"settingImage.defaultCount.title": "فن الذكاء الاصطناعي",
"settingModel.enableMaxTokens.title": فعيل حد الرموز القصوى",
"settingModel.enableReasoningEffort.title": فعيل ضبط جهد الاستدلال",
"settingModel.frequencyPenalty.desc": "كلما زادت القيمة، زادت تنوع وغنى المفردات؛ وكلما انخفضت، أصبحت اللغة أبسط وأكثر مباشرة.",
"settingModel.frequencyPenalty.title": "غنى المفردات",
"settingModel.maxTokens.desc": "الحد الأقصى لعدد الرموز المستخدمة في كل تفاعل",
"settingModel.maxTokens.title": "حد الرموز القصوى",
"settingModel.model.desc": "نموذج {{provider}}",
"settingModel.model.title": "النموذج",
"settingModel.params.title": "إعدادات متقدمة",
"settingModel.presencePenalty.desc": "كلما زادت القيمة، زادت الميل إلى استخدام تعبيرات مختلفة، مما يتجنب تكرار المفاهيم؛ وكلما انخفضت القيمة، زادت الميل إلى استخدام المفاهيم أو السرد المتكرر، مما يجعل التعبير أكثر اتساقًا",
"settingModel.presencePenalty.desc": "كلما زادت القيمة، زاد الميل لاستخدام تعبيرات متنوعة وتجنب تكرار المفاهيم؛ وكلما انخفضت، زاد الميل لتكرار المفاهيم أو السرد، مما يؤدي إلى تعبير أكثر اتساقًا.",
"settingModel.presencePenalty.title": "تنوع التعبير",
"settingModel.reasoningEffort.desc": "كلما زادت القيمة، زادت قوة الاستدلال، ولكن قد يؤدي ذلك إلى زيادة وقت الاستجابة واستهلاك الرموز",
"settingModel.reasoningEffort.desc": "القيم الأعلى تعزز القدرة على الاستدلال ولكن قد تزيد من وقت الاستجابة واستهلاك الرموز.",
"settingModel.reasoningEffort.options.high": "عالي",
"settingModel.reasoningEffort.options.low": "منخفض",
"settingModel.reasoningEffort.options.medium": "متوسط",
"settingModel.reasoningEffort.title": "قوة الاستدلال",
"settingModel.reasoningEffort.title": "جهد الاستدلال",
"settingModel.submit": "تحديث إعدادات النموذج",
"settingModel.temperature.desc": "كلما زادت القيمة، كانت الإجابات أكثر إبداعًا وخيالًا؛ وكلما انخفضت القيمة، كانت الإجابات أكثر دقة",
"settingModel.temperature.desc": "كلما زادت القيمة، أصبحت الردود أكثر إبداعًا وخيالًا؛ وكلما انخفضت، أصبحت أكثر دقة وانضباطًا.",
"settingModel.temperature.title": "مستوى الإبداع",
"settingModel.temperature.warning": "إذا كانت قيمة مستوى الإبداع مرتفعة جدًا، قد تحتوي المخرجات على تشويش",
"settingModel.temperature.warning": "إذا تم ضبط مستوى الإبداع على قيمة عالية جدًا، فقد تصبح المخرجات غير مفهومة.",
"settingModel.title": "إعدادات النموذج",
"settingModel.topP.desc": "عدد الاحتمالات التي يتم أخذها في الاعتبار، كلما زادت القيمة، زادت احتمالية قبول إجابات متعددة؛ وكلما انخفضت القيمة، زادت الميل لاختيار الإجابة الأكثر احتمالًا. لا يُنصح بتغييرها مع مستوى الإبداع",
"settingModel.topP.title": "مستوى الانفتاح الفكري",
"settingOpening.openingMessage.desc": "رسالة الافتتاح عند بدء المحادثة، تستخدم لتعريف وظائف المساعد",
"settingOpening.openingMessage.placeholder": "مرحبًا، أنا المساعد المخصص، يمكنك بدء المحادثة معي على الفور، أو يمكنك الذهاب إلى إعدادات المساعد لإكمال معلوماتي.",
"settingOpening.openingMessage.title": "رسالة الافتتاح",
"settingOpening.openingQuestions.desc": "الأسئلة الإرشادية المعروضة عند بدء المحادثة",
"settingModel.topP.desc": "عدد الاحتمالات التي يتم أخذها في الاعتبار؛ القيمة الأعلى تقبل المزيد من الإجابات المحتملة، بينما القيمة الأقل تميل لاختيار الإجابة الأكثر احتمالاً. لا يُنصح بتغييرها مع مستوى الإبداع.",
"settingModel.topP.title": "الانفتاح على الأفكار",
"settingOpening.openingMessage.desc": "الرسالة الافتتاحية التي تظهر عند بدء المحادثة، وتُستخدم لتقديم ميزات الوكيل",
"settingOpening.openingMessage.placeholder": "مرحبًا، أنا وكيلك المخصص. يمكنك البدء في الدردشة معي فورًا، أو الانتقال إلى إعدادات الوكيل لإكمال معلوماتي.",
"settingOpening.openingMessage.title": "الرسالة الافتتاحية",
"settingOpening.openingQuestions.desc": "أسئلة إرشادية تظهر في بداية المحادثة",
"settingOpening.openingQuestions.empty": "أضف أسئلة افتتاحية لمساعدة المستخدمين على بدء المحادثة بسرعة",
"settingOpening.openingQuestions.placeholder": "أدخل السؤال",
"settingOpening.openingQuestions.placeholder": "يرجى إدخال سؤال",
"settingOpening.openingQuestions.repeat": "السؤال موجود بالفعل",
"settingOpening.openingQuestions.title": "أسئلة الافتتاح",
"settingOpening.title": "إعداد الافتتاح",
"settingPlugin.title": "قائمة الإضافات",
"settingSystem.accessCode.desc": "قام المسؤول بتمكين الوصول المشفر",
"settingSystem.accessCode.placeholder": "الرجاء إدخال كلمة المرور",
"settingSystem.accessCode.title": "كلمة المرور",
"settingOpening.openingQuestions.title": "الأسئلة الافتتاحية",
"settingOpening.title": "إعدادات البداية",
"settingPlugin.title": "قائمة المهارات",
"settingSystem.oauth.info.desc": "تم تسجيل الدخول",
"settingSystem.oauth.info.title": "معلومات الحساب",
"settingSystem.oauth.signin.action": "تسجيل الدخول",
"settingSystem.oauth.signin.desc": "قم بتسجيل الدخول باستخدام SSO لفتح التطبيق",
"settingSystem.oauth.signin.title": "تسجيل الدخول إلى الحساب",
"settingSystem.oauth.signin.desc": "سجّل الدخول باستخدام SSO لفتح التطبيق",
"settingSystem.oauth.signin.title": "تسجيل الدخول إلى حسابك",
"settingSystem.oauth.signout.action": "تسجيل الخروج",
"settingSystem.oauth.signout.confirm": "هل ترغب في تأكيد الخروج؟",
"settingSystem.oauth.signout.confirm": "هل تريد تأكيد تسجيل الخروج؟",
"settingSystem.oauth.signout.success": "تم تسجيل الخروج بنجاح",
"settingSystem.title": "إعدادات النظام",
"settingTTS.openai.sttModel": "نموذج تحويل النص إلى كلام من OpenAI",
"settingTTS.openai.sttModel": "نموذج OpenAI لتحويل الكلام إلى نص",
"settingTTS.openai.title": "OpenAI",
"settingTTS.openai.ttsModel": "نموذج توليد الكلام من OpenAI",
"settingTTS.showAllLocaleVoice.desc": "إذا تم إيقافه، سيتم عرض مصادر الصوت الخاصة باللغة الحالية فقط",
"settingTTS.showAllLocaleVoice.title": "عرض جميع مصادر الصوت للغات",
"settingTTS.stt": "إعدادات التحويل من الصوت إلى نص",
"settingTTS.sttAutoStop.desc": "عند الإيقاف، لن يتم إيقاف تحويل الصوت إلى نص تلقائيًا، وسيتطلب الأمر النقر على زر الإيقاف يدويًا",
"settingTTS.sttAutoStop.title": "إيقاف تحويل الصوت إلى نص تلقائيًا",
"settingTTS.sttLocale.desc": "لغة الصوت المدخلة، يمكن أن يساعد هذا الخيار في زيادة دقة تحويل الصوت إلى نص",
"settingTTS.sttLocale.title": "لغة تحويل الصوت إلى نص",
"settingTTS.sttService.desc": "حيث يكون المتصفح هو خدمة التحويل الصوتي الأصلية",
"settingTTS.sttService.title": "خدمة تحويل الصوت إلى نص",
"settingTTS.openai.ttsModel": "نموذج OpenAI لتحويل النص إلى كلام",
"settingTTS.showAllLocaleVoice.desc": "إذا تم إيقافه، سيتم عرض الأصوات المتوفرة للغة الحالية فقط",
"settingTTS.showAllLocaleVoice.title": "عرض جميع الأصوات حسب اللغة",
"settingTTS.stt": "إعدادات التعرف على الكلام",
"settingTTS.sttAutoStop.desc": "عند الإيقاف، لن يتوقف التعرف على الكلام تلقائيًا ويتطلب النقر يدويًا للإيقاف",
"settingTTS.sttAutoStop.title": "إيقاف تلقائي للتعرف على الكلام",
"settingTTS.sttLocale.desc": "لغة إدخال الصوت، يمكن أن تحسن دقة التعرف على الكلام",
"settingTTS.sttLocale.title": "لغة التعرف على الكلام",
"settingTTS.sttService.desc": "حيث أن 'المتصفح' هو خدمة التعرف على الكلام الأصلية في المتصفح",
"settingTTS.sttService.title": "خدمة التعرف على الكلام",
"settingTTS.submit": "تحديث خدمة الصوت",
"settingTTS.title": "خدمة الصوت",
"settingTTS.tts": "إعدادات توليد الكلام",
"settingTTS.ttsService.desc": "إذا كنت تستخدم خدمة توليد الكلام من OpenAI، يجب التأكد من تمكين خدمة نموذج OpenAI",
"settingTTS.ttsService.title": "خدمة توليد الكلام",
"settingTTS.voice.desc": "حدد صوتًا للمساعد الحالي، تختلف مصادر الصوت المدعومة بحسب خدمة توليد الكلام",
"settingTTS.tts": "إعدادات تحويل النص إلى كلام",
"settingTTS.ttsService.desc": "إذا كنت تستخدم خدمة OpenAI لتحويل النص إلى كلام، تأكد من تفعيل خدمة نموذج OpenAI",
"settingTTS.ttsService.title": "خدمة تحويل النص إلى كلام",
"settingTTS.voice.desc": "اختر صوتًا للوكيل الحالي، حيث تدعم خدمات TTS المختلفة أصواتًا مختلفة",
"settingTTS.voice.preview": "معاينة الصوت",
"settingTTS.voice.title": "مصدر توليد الكلام",
"settingTTS.voice.title": "صوت تحويل النص إلى كلام",
"startConversation": "ابدأ المحادثة",
"storage.actions.export.button": "تصدير",
"storage.actions.export.exportType.agent": "تصدير إعدادات المساعد",
"storage.actions.export.exportType.agentWithMessage": "تصدير المساعد والرسائل",
"storage.actions.export.exportType.all": "تصدير الإعدادات العالمية وجميع بيانات المساعدين",
"storage.actions.export.exportType.allAgent": "تصدير جميع إعدادات المساعدين",
"storage.actions.export.exportType.allAgentWithMessage": "تصدير جميع المساعدين والرسائل",
"storage.actions.export.exportType.globalSetting": "تصدير الإعدادات العالمية",
"storage.actions.export.exportType.agent": "تصدير إعدادات الوكيل",
"storage.actions.export.exportType.agentWithMessage": "تصدير الوكيل والرسائل",
"storage.actions.export.exportType.all": "تصدير الإعدادات العامة وجميع بيانات الوكلاء",
"storage.actions.export.exportType.allAgent": "تصدير جميع إعدادات الوكلاء",
"storage.actions.export.exportType.allAgentWithMessage": "تصدير جميع الوكلاء والرسائل",
"storage.actions.export.exportType.globalSetting": "تصدير الإعدادات العامة",
"storage.actions.export.title": "تصدير البيانات",
"storage.actions.import.button": "استيراد",
"storage.actions.import.title": "استيراد البيانات",
"storage.actions.title": "عمليات متقدمة",
"storage.desc": "حجم التخزين في المتصفح الحالي",
"storage.desc": "استخدام التخزين الحالي في المتصفح",
"storage.embeddings.used": "تخزين المتجهات",
"storage.title": "تخزين البيانات",
"storage.used": "حجم التخزين",
"submitAgentModal.button": "تقديم المساعد",
"submitAgentModal.identifier": "معرف المساعد (identifier)",
"submitAgentModal.metaMiss": "يرجى استكمال معلومات المساعد قبل التقديم، يجب أن تتضمن الاسم والوصف والعلامة",
"submitAgentModal.placeholder": "الرجاء إدخال معرف المساعد، يجب أن يكون فريدًا، مثل تطوير الويب",
"submitAgentModal.success": "تم إرسال المساعد بنجاح",
"submitAgentModal.tooltips": "مشاركة في مجتمع المساعدين",
"submitFooter.reset": "إعادة تعيين",
"submitFooter.submit": "حفظ",
"submitFooter.unSaved": "تغييرات غير محفوظة",
"submitFooter.unSavedWarning": "هناك تغييرات غير محفوظة حالياً",
"sync.device.deviceName.hint": "أضف اسمًا للتعرف بشكل أفضل",
"sync.device.deviceName.placeholder": "الرجاء إدخال اسم الجهاز",
"storage.used": "استخدام التخزين",
"submitAgentModal.button": "إرسال الوكيل",
"submitAgentModal.identifier": "معرّف الوكيل",
"submitAgentModal.metaMiss": "يرجى إكمال معلومات الوكيل قبل الإرسال. يجب أن تتضمن الاسم والوصف والوسوم.",
"submitAgentModal.placeholder": "أدخل معرّفًا فريدًا للوكيل، مثل: web-development",
"submitAgentModal.success": "تم إرسال الوكيل بنجاح",
"submitAgentModal.tooltips": "مشاركة في مجتمع الوكلاء",
"sync.device.deviceName.hint": "أضف اسمًا لسهولة التعرف",
"sync.device.deviceName.placeholder": "أدخل اسم الجهاز",
"sync.device.deviceName.title": "اسم الجهاز",
"sync.device.title": "معلومات الجهاز",
"sync.device.unknownBrowser": "متصفح غير معروف",
"sync.device.unknownOS": "نظام التشغيل غير معروف",
"sync.warning.tip": "بعد فترة اختبار عامة طويلة، قد لا يكون تزامن WebRTC مستقرًا بما يكفي لتلبية احتياجات التزامن العامة. يرجى <1>نشر خادم الإشارة</1> بنفسك قبل الاستخدام.",
"sync.webrtc.channelName.desc": "سيستخدم WebRTC هذا الاسم لإنشاء قناة مزامنة، يرجى التأكد من فرادة اسم القناة",
"sync.webrtc.channelName.placeholder": "الرجاء إدخال اسم قناة المزامنة",
"sync.webrtc.channelName.shuffle": "توليف عشوائي",
"sync.device.unknownOS": "نظام تشغيل غير معروف",
"sync.warning.tip": "بعد فترة طويلة من الاختبار المجتمعي، قد لا تلبي مزامنة WebRTC احتياجات مزامنة البيانات العامة بشكل موثوق. يرجى <1>نشر خادم الإشارة</1> قبل الاستخدام.",
"sync.webrtc.channelName.desc": "سيستخدم WebRTC هذا الاسم لإنشاء قناة مزامنة. تأكد من أن الاسم فريد.",
"sync.webrtc.channelName.placeholder": "أدخل اسم قناة المزامنة",
"sync.webrtc.channelName.shuffle": "توليد عشوائي",
"sync.webrtc.channelName.title": "اسم قناة المزامنة",
"sync.webrtc.channelPassword.desc": "إضافة كلمة مرور لضمان خصوصية القناة، يمكن للأجهزة الانضمام إلى القناة فقط عند إدخال كلمة المرور الصحيحة",
"sync.webrtc.channelPassword.placeholder": "الرجاء إدخال كلمة مرور قناة المزامنة",
"sync.webrtc.channelPassword.desc": "أضف كلمة مرور لضمان خصوصية القناة. يمكن فقط للأجهزة التي تملك كلمة المرور الصحيحة الانضمام.",
"sync.webrtc.channelPassword.placeholder": "أدخل كلمة مرور قناة المزامنة",
"sync.webrtc.channelPassword.title": "كلمة مرور قناة المزامنة",
"sync.webrtc.desc": "اتصال البيانات النقطي الفوري يتطلب تواجد الأجهزة معًا للمزامنة",
"sync.webrtc.enabled.invalid": "الرجاء ملء اسم خادم الإشارة واسم القناة المتزامنة قبل تمكينها",
"sync.webrtc.enabled.title": مكين المزامنة",
"sync.webrtc.signaling.desc": "سيستخدم WebRTC هذا العنوان للتزامن",
"sync.webrtc.signaling.placeholder": "الرجاء إدخال عنوان خادم الإشارة",
"sync.webrtc.desc": "الاتصال بالبيانات في الوقت الحقيقي من نظير إلى نظير يتطلب أن تكون جميع الأجهزة متصلة بالإنترنت.",
"sync.webrtc.enabled.invalid": "يرجى ملء خادم الإشارة واسم قناة المزامنة قبل التفعيل.",
"sync.webrtc.enabled.title": فعيل المزامنة",
"sync.webrtc.signaling.desc": "سيستخدم WebRTC هذا العنوان للمزامنة",
"sync.webrtc.signaling.placeholder": "أدخل عنوان خادم الإشارة",
"sync.webrtc.signaling.title": "خادم الإشارة",
"sync.webrtc.title": "WebRTC مزامنة",
"sync.webrtc.title": "مزامنة WebRTC",
"systemAgent.agentMeta.label": "النموذج",
"systemAgent.agentMeta.modelDesc": "يحدد النموذج المستخدم لإنشاء اسم المساعد ووصفه وصورته وعلامته",
"systemAgent.agentMeta.title": "مساعد إنشاء معلومات المساعد",
"systemAgent.agentMeta.modelDesc": "النموذج المخصص لتوليد اسم الوكيل، وصفه، صورته، ووسومه",
"systemAgent.agentMeta.title": "مساعد توليد معلومات الوكيل",
"systemAgent.customPrompt.addPrompt": "إضافة موجه مخصص",
"systemAgent.customPrompt.desc": "بعد ملئه، سيستخدم المساعد النظامي الموجه المخصص عند إنشاء المحتوى",
"systemAgent.customPrompt.placeholder": "أدخل كلمة الموجه المخصصة",
"systemAgent.customPrompt.title": "كلمة الموجه المخصصة",
"systemAgent.customPrompt.desc": "عند تعبئته، سيستخدم الوكيل النظامي الموجه المخصص عند توليد المحتوى",
"systemAgent.customPrompt.placeholder": "يرجى إدخال موجه مخصص",
"systemAgent.customPrompt.title": "موجه مخصص",
"systemAgent.generationTopic.label": "النموذج",
"systemAgent.generationTopic.modelDesc": "نموذج مخصص لتسمية موضوعات الرسم بالذكاء الاصطناعي تلقائيًا",
"systemAgent.generationTopic.title": "مساعد تسمية مواضيع الرسم بالذكاء الاصطناعي",
"systemAgent.helpInfo": "عند إنشاء مساعد جديد، سيتم استخدام إعدادات المساعد الافتراضية كقيم افتراضية.",
"systemAgent.generationTopic.modelDesc": "النموذج المخصص لتسمية مواضيع فن الذكاء الاصطناعي تلقائيًا",
"systemAgent.generationTopic.title": "وكيل تسمية مواضيع فن الذكاء الاصطناعي",
"systemAgent.helpInfo": "عند إنشاء وكيل جديد، سيتم استخدام إعدادات الوكيل الافتراضية كقيم مسبقة.",
"systemAgent.historyCompress.label": "النموذج",
"systemAgent.historyCompress.modelDesc": "حدد النموذج المستخدم لضغط تاريخ المحادثة",
"systemAgent.historyCompress.title": "مساعد ضغط سجل المحادثة",
"systemAgent.historyCompress.modelDesc": "تحديد النموذج المستخدم لضغط سجل المحادثة",
"systemAgent.historyCompress.title": "وكيل ضغط سجل المحادثة",
"systemAgent.queryRewrite.label": "النموذج",
"systemAgent.queryRewrite.modelDesc": "نموذج مخصص لتحسين أسئلة المستخدمين",
"systemAgent.queryRewrite.title": "مساعد إعادة صياغة الأسئلة في مركز الموارد",
"systemAgent.queryRewrite.modelDesc": "تحديد النموذج المستخدم لتحسين استفسارات المستخدم",
"systemAgent.queryRewrite.title": "وكيل إعادة صياغة استعلام المكتبة",
"systemAgent.thread.label": "النموذج",
"systemAgent.thread.modelDesc": "نموذج مخصص لإعادة تسمية الموضوعات الفرعية تلقائيًا",
"systemAgent.thread.title": "مساعد التسمية التلقائية للمواضيع الفرعية",
"systemAgent.title": "مساعد النظام",
"systemAgent.thread.modelDesc": "النموذج المخصص لإعادة تسمية المواضيع الفرعية تلقائيًا",
"systemAgent.thread.title": "وكيل التسمية التلقائية للمواضيع الفرعية",
"systemAgent.title": "وكلاء النظام",
"systemAgent.topic.label": "النموذج",
"systemAgent.topic.modelDesc": "يحدد النموذج المستخدم لإعادة تسمية الموضوع تلقائيًا",
"systemAgent.topic.title": "مساعد التسمية التلقائية للمواضيع",
"systemAgent.topic.modelDesc": "النموذج المخصص لإعادة تسمية المواضيع تلقائيًا",
"systemAgent.topic.title": "وكيل التسمية التلقائية للمواضيع",
"systemAgent.translation.label": "النموذج",
"systemAgent.translation.modelDesc": "النموذج المحدد للاستخدام في الترجمة",
"systemAgent.translation.title": "مساعد ترجمة محتوى الرسائل",
"systemAgent.translation.modelDesc": "تحديد النموذج المستخدم للترجمة",
"systemAgent.translation.title": "وكيل ترجمة الرسائل",
"tab.about": "حول",
"tab.agent": "المساعد الافتراضي",
"tab.agent": "خدمة الوكيل",
"tab.apikey": "إدارة مفاتيح API",
"tab.chatAppearance": "مظهر المحادثة",
"tab.common": "المظهر",
"tab.experiment": "تجربة",
"tab.experiment": "تجريبي",
"tab.hotkey": "اختصارات لوحة المفاتيح",
"tab.image": "خدمة الرسم",
"tab.image": "خدمة توليد الصور",
"tab.llm": "نموذج اللغة",
"tab.memory": "إعدادات الذاكرة",
"tab.memory": "الذاكرة",
"tab.profile": "حسابي",
"tab.provider": "مزود خدمة الذكاء الاصطناعي",
"tab.proxy": "وكيل الشبكة",
"tab.security": "الأمان",
"tab.stats": "إحصائيات البيانات",
"tab.stats": "التحليلات",
"tab.storage": "تخزين البيانات",
"tab.sync": "مزامنة السحابة",
"tab.tts": "خدمة الكلام",
"tab.tts": "تحويل النص إلى كلام",
"tab.usage": "إحصائيات الاستخدام",
"tools.add": "إضافة مكون إضافي",
"tools.builtins.groupName": "الامتدادات المدمجة",
"tools.disabled": "النموذج الحالي لا يدعم استدعاء الوظائف، ولا يمكن استخدام الإضافة",
"tools.add": "إضافة مهارة",
"tools.builtins.groupName": "المهارات المدمجة",
"tools.disabled": "النموذج الحالي لا يدعم استدعاء الوظائف ولا يمكنه استخدام المهارة",
"tools.klavis.addServer": "إضافة خادم",
"tools.klavis.authCompleted": "اكتملت المصادقة",
"tools.klavis.authFailed": "فشلت المصادقة",
"tools.klavis.authRequired": "المصادقة مطلوبة",
"tools.klavis.authCompleted": "تم التحقق من الهوية",
"tools.klavis.authFailed": "فشل التحقق من الهوية",
"tools.klavis.authRequired": "التحقق من الهوية مطلوب",
"tools.klavis.connected": "متصل",
"tools.klavis.error": "خطأ",
"tools.klavis.groupName": "أدوات Klavis",
"tools.klavis.manage": "إدارة Klavis",
"tools.klavis.manageTitle": "إدارة تكامل Klavis",
"tools.klavis.noServers": "لا توجد خوادم متصلة حاليًا",
"tools.klavis.notEnabled": "خدمة Klavis غير مفعّلة",
"tools.klavis.oauthRequired": "يرجى إكمال مصادقة OAuth في نافذة جديدة",
"tools.klavis.pendingAuth": "في انتظار المصادقة",
"tools.klavis.noServers": "لا توجد خوادم متصلة",
"tools.klavis.notEnabled": "خدمة Klavis غير مفعلة",
"tools.klavis.oauthRequired": "يرجى إكمال التحقق من OAuth في النافذة الجديدة",
"tools.klavis.pendingAuth": "في انتظار التحقق",
"tools.klavis.serverCreated": "تم إنشاء الخادم بنجاح",
"tools.klavis.serverCreatedFailed": "فشل في إنشاء الخادم",
"tools.klavis.serverRemoved": "تم حذف الخادم",
"tools.klavis.servers": "خوادم",
"tools.klavis.tools": "أدوات",
"tools.klavis.verifyAuth": "لقد أكملت المصادقة",
"tools.klavis.serverRemoved": "تمت إزالة الخادم",
"tools.klavis.servers": "الخوادم",
"tools.klavis.tools": "الأدوات",
"tools.klavis.verifyAuth": "لقد أكملت التحقق",
"tools.notInstalled": "غير مثبت",
"tools.notInstalledWarning": "المكون الإضافي غير مثبت حاليًا، وقد يؤثر ذلك على استخدام المساعد",
"tools.plugins.enabled": مكّنة {{num}}",
"tools.plugins.groupName": "الإضافات",
"tools.plugins.noEnabled": "لا توجد إضافات ممكّنة حاليًا",
"tools.plugins.store": "متجر الإضافات",
"tools.notInstalledWarning": "هذه المهارة غير مثبتة حاليًا، مما قد يؤثر على وظائف الوكيل.",
"tools.plugins.enabled": فعلة: {{num}}",
"tools.plugins.groupName": "المهارات",
"tools.plugins.noEnabled": "لا توجد مهارات مفعلة",
"tools.plugins.store": "متجر المهارات",
"tools.tabs.all": "الكل",
"tools.tabs.installed": "مفعّلة",
"tools.title": "أدوات الامتداد"
"tools.tabs.installed": "مفعلة",
"tools.title": "أدوات التوسعة"
}
+23
View File
@@ -0,0 +1,23 @@
{
"duration.TPS": "TPS (الرموز في الثانية): عدد الرموز المُخرجة في الثانية",
"duration.TTFT": "TTFT (الوقت حتى أول رمز): زمن استجابة أول رمز",
"duration.completion": "زمن إتمام الإخراج",
"duration.latency": "المدة",
"duration.stage.end": "النهاية",
"duration.stage.firstToken": "أول رمز",
"duration.stage.start": "البداية",
"table.columns.TTFT.tooltip": "الوقت حتى أول رمز، الوحدة: ثوانٍ",
"table.columns.duration": "المدة",
"table.columns.model": "النموذج",
"table.columns.spend": "الاعتمادات",
"table.columns.startTime": "تاريخ الإنشاء",
"table.columns.totalTokens": "استخدام الرموز",
"table.columns.type.enums.chat": "توليد نصوص",
"table.columns.type.enums.imageGeneration": "توليد صور",
"table.columns.type.title": "النوع",
"table.desc": "تفاصيل استخدام الاعتمادات الحاسوبية لتوليد النصوص، التضمين، توليد الصور، وغيرها.",
"table.more": "عرض التفاصيل",
"table.title": "تفاصيل استخدام الاعتمادات الحاسوبية",
"table.totalToken.input": "المدخلات",
"table.totalToken.output": "المخرجات"
}
+373 -6
View File
@@ -1,8 +1,375 @@
{
"plans.plan.enterprise.title": "النسخة التجارية",
"plans.plan.free.title": "النسخة المجانية",
"plans.plan.hobby.title": "نسخة الخدمة الذاتية",
"plans.plan.premium.title": "النسخة المتقدمة",
"plans.plan.starter.title": "النسخة الأساسية",
"plans.plan.ultimate.title": "النسخة الاحترافية"
"balance.creditBalance": "رصيد الرصيد الإضافي",
"balance.hobbyDesc": "{{hobby}} لا يشمل أرصدة الاشتراك، تحتاج إلى تكوين واجهة برمجة التطبيقات للنموذج أو شحن الرصيد",
"balance.link.history": "سجل الشحن",
"balance.link.usage": "عرض الاستخدام",
"balance.plansUsage": "أرصدة الاشتراك",
"balance.plansUsageDesc": "يتم استخدام أرصدة الاشتراك أولاً، ثم أرصدة الشحن",
"balance.title": "الرصيد",
"billing.amount": "المبلغ",
"billing.closed": "مغلق",
"billing.created": "تاريخ الدفع",
"billing.draft": "مسودة",
"billing.draftTooltip": "تم إنشاء هذه الفاتورة كمسودة بواسطة اشتراك جديد وسيتم خصمها تلقائيًا قريبًا",
"billing.empty": "لا يوجد سجل فواتير",
"billing.endDate": "تاريخ الانتهاء",
"billing.history": "سجل الفواتير",
"billing.orderNumber": "رقم الطلب",
"billing.paid": "مدفوع",
"billing.pay": "ادفع الآن",
"billing.paymentGateway": "بوابة الدفع",
"billing.paymentMethod": "طريقة الدفع",
"billing.price": "سعر الاشتراك",
"billing.startDate": "تاريخ البدء",
"billing.status": "حالة المعاملة",
"billing.subscriptionId": "معرّف الاشتراك",
"billing.unpaid": "غير مدفوع",
"billing.view": "عرض",
"cancelPlan.alert": "ستستمر في الاستفادة من المزايا حتى انتهاء الخطة الحالية ({{date}}). يمكنك إعادة الاشتراك في أي وقت قبل انتهاء الصلاحية.",
"cancelPlan.desc": "بعد الإلغاء، سيتم تخفيضك إلى النسخة المجانية عند انتهاء الخطة الحالية.",
"cancelPlan.title": "إلغاء الاشتراك",
"cancelSubscription": "إلغاء الاشتراك",
"compare.hobbyCreditTooltip": "لا يشمل أرصدة الحوسبة الشهرية، تحتاج إلى تكوين واجهة برمجة التطبيقات الخاصة بك",
"compare.monthlyCredit": "أرصدة الحوسبة الشهرية",
"compare.title": "مقارنة الخطط",
"compareAllPlans": "عرض جميع الخطط",
"comparePlans": "عرض الخطط",
"createSubscriptionError": "فشل في إنشاء الاشتراك",
"currentPlan.cancelAlert": "سيتم إلغاء الاشتراك بعد {{canceledAt}}. لا يزال بإمكانك استعادته من \"إدارة الاشتراك\" قبل ذلك",
"currentPlan.downgradeAlert": "سيتم تخفيض الخطة إلى {{plan}} بعد {{downgradedAt}}.",
"currentPlan.management": "إدارة الاشتراك",
"currentPlan.notIncluded": "غير مشمول في الخطة الحالية",
"currentPlan.paymentExpired": "سينتهي هذا الاشتراك في {{expiredAt}}، يرجى التخطيط لاستخدامك وفقًا لذلك",
"currentPlan.seeAllFeaturesAndComparePlans": "عرض جميع الميزات ومقارنة الخطط",
"currentPlan.title": "الخطة الحالية",
"discount.add": "إضافة",
"discount.maxOff": "خصم يصل إلى {{percent}}٪",
"discount.off": "{{percent}}٪ خصم",
"discount.save": "توفير",
"downgradePlans.alert": "ستستمر في الاستفادة من المزايا حتى انتهاء الخطة الحالية ({{date}}). ستصبح الخطة الجديدة سارية بعد انتهاء الخطة الحالية.",
"downgradePlans.desc": "سيتم تطبيق تغيير الخطة بعد انتهاء الخطة الحالية.",
"downgradePlans.success": "تم إلغاء الاشتراك بنجاح",
"downgradePlans.title": "التحويل إلى {{plan}}",
"funds.packages.expired": "منتهية",
"funds.packages.expiresIn": "تنتهي خلال {{days}} يومًا",
"funds.packages.expiresToday": "تنتهي اليوم",
"funds.packages.expiringSoon": "ستنتهي قريبًا",
"funds.packages.noPackages": "لا توجد حزم أرصدة",
"funds.packages.purchaseFirst": "اشترِ أول حزمة أرصدة لك",
"funds.packages.purchasedOn": "تم الشراء في {{date}}",
"funds.packages.sort.amountAsc": "المبلغ: من الأقل إلى الأعلى",
"funds.packages.sort.amountDesc": "المبلغ: من الأعلى إلى الأقل",
"funds.packages.sort.balanceAsc": "الرصيد: من الأقل إلى الأعلى",
"funds.packages.sort.balanceDesc": "الرصيد: من الأعلى إلى الأقل",
"funds.packages.sort.newest": "الأحدث",
"funds.packages.sort.oldest": "الأقدم",
"funds.packages.tabs.active": "الحزم النشطة",
"funds.packages.tabs.activeCount": "نشطة ({{count}})",
"funds.packages.tabs.depleted": "المنتهية",
"funds.packages.tabs.depletedCount": "منتهية ({{count}})",
"funds.packages.tabs.expired": "المنتهية الصلاحية",
"funds.packages.tabs.expiredCount": "منتهية الصلاحية ({{count}})",
"funds.packages.title": "حزم الأرصدة الخاصة بي",
"funds.topUp.cancel": "إلغاء",
"funds.topUp.custom": "مخصص",
"funds.topUp.maxAmountError": "لا يمكن أن يتجاوز مبلغ الشراء الواحد ${{max}}",
"funds.topUp.purchaseError": "فشل الشراء، يرجى المحاولة لاحقًا",
"funds.topUp.purchaseNow": "اشترِ الآن",
"funds.topUp.selectPackage": "اختر الحزمة",
"funds.topUp.subscribeFirst": "اشترك أولاً",
"funds.topUp.success.credits": "+{{quantity}} أرصدة",
"funds.topUp.success.title": "تم الشحن بنجاح",
"funds.topUp.title": "شراء الأرصدة",
"funds.topUp.total": "الإجمالي",
"funds.topUp.unitPrice": "سعر الوحدة",
"funds.topUp.unitPriceFormat": "${{price}} / 1M {{creditLabel}}",
"funds.topUp.upgradePrefix": "الترقية إلى",
"funds.topUp.upgradeSuffix": "لتوفير ${{savings}}",
"funds.topUp.validityInfo": "صالح لمدة {{months}} أشهر",
"header.desc": "إدارة الاستخدام والاشتراك",
"header.title": "الفوترة",
"keyMissMatch.button": "استعادة الاستخدام ومتابعة المحادثة",
"keyMissMatch.description": "بسبب خلل مؤقت في النظام، تم تعطيل استخدام اشتراكك مؤقتًا. يرجى النقر على الزر أدناه لاستعادة الاستخدام ومتابعة المحادثة. إذا تكرر ذلك، يرجى التواصل معنا عبر البريد الإلكتروني (support@lobehub.com)",
"keyMissMatch.title": "استعادة استخدام الاشتراك الآن",
"limitation.chat.success.action": "متابعة المحادثة",
"limitation.chat.success.desc": "تمت ترقية اشتراكك في {{plan}} بنجاح. استمتع بالدردشة مع الذكاء الاصطناعي. تتضمن خطتك الحالية:",
"limitation.chat.success.title": "تمت الترقية بنجاح",
"limitation.chat.topupSuccess.action": "متابعة المحادثة",
"limitation.chat.topupSuccess.desc": "أرصدة الشحن الخاصة بك نشطة الآن. استمتع بالدردشة مع الذكاء الاصطناعي. تتضمن خطتك الحالية:",
"limitation.chat.topupSuccess.title": "تم الشحن بنجاح",
"limitation.expired.desc": "انتهت صلاحية أرصدة الحوسبة الخاصة بك في خطة {{plan}} بتاريخ {{expiredAt}}. قم بالترقية الآن للحصول على أرصدة جديدة.",
"limitation.expired.title": "انتهت أرصدة الحوسبة",
"limitation.hobby.action": "تم التكوين، تابع المحادثة",
"limitation.hobby.configAPI": "تكوين API",
"limitation.hobby.desc": "تم استهلاك أرصدة الحوسبة المجانية الخاصة بك. يرجى تكوين واجهة برمجة التطبيقات المخصصة للنموذج للمتابعة.",
"limitation.hobby.docs": "عرض مستندات التكوين",
"limitation.hobby.tip": "تأكد من التبديل إلى نموذج يستخدم مفتاح API مخصص",
"limitation.hobby.title": "يرجى تكوين واجهة برمجة التطبيقات لخدمة النموذج",
"limitation.image.success.action": "متابعة التوليد",
"limitation.image.success.desc": "تمت ترقية اشتراكك في {{plan}} بنجاح. استمتع بتوليد الصور بالذكاء الاصطناعي. تتضمن خطتك الحالية:",
"limitation.image.success.title": "تمت الترقية بنجاح",
"limitation.image.topupSuccess.action": "متابعة التوليد",
"limitation.image.topupSuccess.desc": "أرصدة الشحن الخاصة بك نشطة الآن. استمتع بتوليد الصور بالذكاء الاصطناعي. تتضمن خطتك الحالية:",
"limitation.image.topupSuccess.title": "تم الشحن بنجاح",
"limitation.limited.action": "الترقية الآن",
"limitation.limited.advanceFeature": "قم بالترقية للاستمتاع بالميزات المميزة:",
"limitation.limited.desc": "تم استهلاك أرصدة الحوسبة الخاصة بك في خطة {{plan}}. قم بالترقية الآن للحصول على المزيد من الأرصدة.",
"limitation.limited.descUltimate": "تم استهلاك أرصدة الحوسبة الخاصة بك في خطة {{plan}}. يرجى شحن الأرصدة للمتابعة.",
"limitation.limited.referralTip": "ادعُ مستخدمين جدد للتسجيل، وستحصل أنت وصديقك على {{reward}}M أرصدة لكل منكما",
"limitation.limited.title": "تم استهلاك أرصدة الحوسبة",
"limitation.limited.topup": "شحن الأرصدة",
"limitation.limited.upgrade": "الترقية إلى خطة أعلى",
"limitation.providers.lock.addNew": "اشترك الآن لإنشاء مزودي ذكاء اصطناعي مخصصين",
"limitation.providers.lock.enableProvider": "اشترك الآن لتفعيل هذا المزود",
"limitation.providers.lock.menuItem": "اشترك الآن لتكوين خدمة API مخصصة",
"limitation.providers.mask.action": "الترقية الآن",
"limitation.providers.mask.subTitle": "خدمة API المخصصة متاحة فقط للخطط المدفوعة. قم بالترقية الآن للاستفادة من خدمات النماذج العالمية",
"limitation.providers.mask.title": "اشترك الآن لاستخدام خدمة API مخصصة",
"limitation.providers.prompter.action": "الترقية الآن",
"limitation.providers.prompter.subTitle": "خدمة API المخصصة متاحة فقط للخطط المدفوعة. قم بالترقية الآن للاستفادة من خدمات النماذج العالمية",
"limitation.providers.prompter.title": "اشترك الآن لاستخدام خدمة API مخصصة",
"limitation.providers.tooltip": "خدمة API المخصصة متاحة فقط للخطط المدفوعة",
"modelPricing.button": "عرض مستندات التسعير",
"modelPricing.desc": "يستخدم {{name}} الأرصدة لقياس استخدام نموذج الذكاء الاصطناعي. يوضح الجدول أدناه أرصدة الحوسبة لكل 1M رموز.",
"modelPricing.title": "تسعير نموذج النص",
"models.input": "إدخال",
"models.intro": "مقدمة",
"models.link": "عرض",
"models.output": "إخراج",
"models.title": "النماذج",
"payDiffPrice": "دفع الفرق",
"payment.error.actions.billing": "إدارة الفوترة",
"payment.error.actions.home": "العودة إلى الصفحة الرئيسية",
"payment.error.desc": "معرّف الاشتراك: {{id}} غير موجود. إذا كانت لديك أسئلة، يرجى التواصل معنا عبر البريد الإلكتروني",
"payment.error.title": "فشل الاستعلام",
"payment.result.title": "نتيجة الاشتراك",
"payment.success.actions.startUsing": "ابدأ الاستخدام",
"payment.success.actions.viewBill": "عرض سجل الفوترة",
"payment.success.desc": "تم تفعيل خطة الاشتراك بنجاح",
"payment.success.title": "تم الاشتراك بنجاح",
"payment.switchSuccess.desc": "سيتم التبديل إلى خطة الاشتراك الجديدة تلقائيًا في {{switchAt}}",
"payment.switchSuccess.title": "تم التبديل بنجاح",
"payment.upgradeFailed.alert.reason.bank3DS": "يتطلب البنك الخاص بك التحقق ثلاثي الأبعاد 3DS، يرجى التأكيد مرة أخرى",
"payment.upgradeFailed.alert.reason.inefficient": "رصيد البطاقة غير كافٍ",
"payment.upgradeFailed.alert.reason.security": "رقابة أمان من نظام Stripe",
"payment.upgradeFailed.alert.title": "أسباب شائعة لفشل الدفع التلقائي",
"payment.upgradeFailed.desc": "فشل ترقية الاشتراك. يرجى التحقق والمحاولة مرة أخرى",
"payment.upgradeFailed.title": "فشل الترقية",
"payment.upgradeSuccess.desc": "تم ترقية خطة الاشتراك بنجاح",
"payment.upgradeSuccess.title": "تمت الترقية بنجاح",
"plans.btn.contact": "اتصل بنا",
"plans.btn.noAction": "الخطة مقفلة",
"plans.btn.payment": "شراء",
"plans.btn.paymentDesc": "يدعم بطاقات الائتمان / Alipay / WeChat Pay",
"plans.btn.paymentDescForZarinpal": "يدعم بطاقات الائتمان",
"plans.btn.soon": "قريبًا",
"plans.changePlan": "اختر خطة",
"plans.cloud.history": "سجل محادثات غير محدود",
"plans.cloud.sync": "مزامنة سحابية عالمية",
"plans.cloud.title": "الخدمة السحابية",
"plans.credit.api": "واجهة برمجة تطبيقات مخصصة",
"plans.credit.apiDesc": "يتطلب إعداد واجهة برمجة التطبيقات الخاصة بك",
"plans.credit.apiProvider": "يدعم أكثر من 20 مزودًا رئيسيًا للنماذج مثل OpenAI / Anthropic / OpenRouter",
"plans.credit.buy": "شراء أرصدة الحوسبة",
"plans.credit.buyDesc": "يدعم أيضًا الشراء حسب الطلب",
"plans.credit.none": "لا توجد أرصدة حوسبة مدمجة",
"plans.credit.tip": "{{credit}} رصيد مجاني شهريًا",
"plans.credit.title": "أرصدة الحوسبة",
"plans.credit.tooltip": "أرصدة الحوسبة الشهرية لرسائل النماذج",
"plans.current": "الخطة الحالية",
"plans.downgradePlan": "خطة التخفيض المستهدفة",
"plans.downgradeTip": "لقد قمت بالفعل بتغيير الاشتراك. لا يمكنك تنفيذ عمليات أخرى حتى يكتمل التبديل",
"plans.embeddingStorage.embeddings": "مدخلات",
"plans.embeddingStorage.title": "تخزين المتجهات",
"plans.embeddingStorage.tooltip": "تنتج صفحة مستند واحدة (1000-1500 حرف) حوالي إدخال متجه واحد. (تقدير باستخدام OpenAI Embeddings، وقد يختلف حسب النموذج)",
"plans.features.agents": "سوق الوكلاء المختارين",
"plans.features.ceAgents": "سوق وكلاء المجتمع",
"plans.features.cePlugins": "سوق الإضافات المجتمعية",
"plans.features.internet": "بحث ذكي على الإنترنت",
"plans.features.plugins": "إضافات مميزة حصرية",
"plans.features.showAll": "عرض جميع الميزات",
"plans.features.title": "الميزات المميزة",
"plans.fileStorage.title": "تخزين الملفات",
"plans.fileStorage.tooltip": "تخزين الملفات والصور والبيانات الأخرى",
"plans.free": "مجاني",
"plans.freeTrail": "سجل للحصول على تجربة مجانية لـ {{name}}، لا حاجة لبطاقة ائتمان",
"plans.includes": "تشمل المزايا:",
"plans.includesExtra": "جميع مزايا {{name}}، بالإضافة إلى:",
"plans.knowledgeBase.desc": "استخدم الملفات وقاعدة المعرفة في المحادثات",
"plans.knowledgeBase.filetype": "يدعم PDF / MD / DOC / XLS / PPT وغيرها",
"plans.knowledgeBase.title": "الملفات وقاعدة المعرفة",
"plans.knowledgeBase.tooltip": "يدعم تحميل الملفات وميزات قاعدة المعرفة. قم بتحميل ملفات، صور، صوت، فيديو والمزيد. أنشئ قواعد معرفة لإدارة الملفات بسهولة. استخدمها في المحادثات لتجربة أغنى.",
"plans.llm.customAPI": "خدمة واجهة برمجة التطبيقات المخصصة للنماذج العالمية",
"plans.llm.messageRequest": "طلبات رسائل غير محدودة",
"plans.llm.title": "خدمة النماذج",
"plans.llm.tooltip": "أضف مزود واجهة برمجة التطبيقات الخاص بك مع الاستفادة من المزامنة السحابية",
"plans.message.count": "حوالي {{number}} رسالة",
"plans.message.more": "المزيد من النماذج في مقارنة الخطط",
"plans.message.normalLLM": "نماذج قياسية",
"plans.message.proLLM": "نماذج مميزة",
"plans.message.tooltip": "تقدير بناءً على متوسط {{number}} رمز لكل رسالة",
"plans.mostPicked": "الأكثر اختيارًا",
"plans.navs.monthly": "شهريًا",
"plans.navs.payonce": "دفع لمرة واحدة",
"plans.navs.yearly": "سنويًا",
"plans.payonce.cancel": "إلغاء",
"plans.payonce.ok": "تأكيد الاختيار",
"plans.payonce.popconfirm": "بعد الدفع لمرة واحدة، يجب الانتظار حتى انتهاء الاشتراك لتغيير الخطة أو دورة الفوترة. يرجى تأكيد اختيارك.",
"plans.payonce.tooltip": "يتطلب الدفع لمرة واحدة الانتظار حتى انتهاء الاشتراك لتغيير الخطة أو دورة الفوترة",
"plans.plan.enterprise.contactSales": "اتصل بالمبيعات",
"plans.plan.enterprise.title": "الشركات",
"plans.plan.free.desc": "للمستخدمين الجدد",
"plans.plan.free.title": "مجاني",
"plans.plan.hobby.desc": "للمستخدمين الذين لديهم واجهة برمجة تطبيقات خاصة بهم ويدفعون حسب الاستخدام",
"plans.plan.hobby.title": "هواية",
"plans.plan.premium.desc": "مصمم للمستخدمين المحترفين الذين يستخدمون الذكاء الاصطناعي بشكل متكرر",
"plans.plan.premium.title": "مميز",
"plans.plan.starter.desc": "للمستخدمين العرضيين للذكاء الاصطناعي",
"plans.plan.starter.title": "مبتدئ",
"plans.plan.ultimate.desc": "للمستخدمين الكثيفين الذين يحتاجون إلى محادثات ذكاء اصطناعي معقدة",
"plans.plan.ultimate.title": "النهائي",
"plans.storage.title": "تخزين البيانات",
"plans.subscribe": "اشترك",
"plans.support.hobby": "منتدى المجتمع",
"plans.support.premium": "دعم عبر البريد الإلكتروني ذو أولوية",
"plans.support.starter": "بريد إلكتروني ومنتدى المجتمع",
"plans.support.title": "الدعم",
"plans.support.ultimate": "دعم عبر الدردشة والبريد الإلكتروني ذو أولوية",
"plans.target": "الخطة المستهدفة",
"plans.unlimited": "غير محدود",
"qa.desc": "إذا لم تجد إجابتك، تحقق من <1>وثائق المنتج</1> لمزيد من الأسئلة الشائعة، أو تواصل معنا.",
"qa.detail": "عرض التفاصيل",
"qa.list.credit.a": "أرصدة الحوسبة هي وحدة قياس يستخدمها {{cloud}} لقياس استخدام نماذج الذكاء الاصطناعي. تستهلك النماذج المختلفة كميات مختلفة من الأرصدة.",
"qa.list.credit.q": "ما هي أرصدة الحوسبة؟",
"qa.list.embeddings.a": "تخزين المتجهات لا يساوي حجم البيانات الأصلية، بل يُحسب بناءً على تحويل النصوص إلى متجهات. على سبيل المثال، ملف PDF من صفحة واحدة قد ينتج فقط إدخال متجه واحد.",
"qa.list.embeddings.q": "كيف يتم حساب تخزين المتجهات؟",
"qa.list.free.a": "{{name}} يلتزم بمبادئ المصدر المفتوح. يمكن للمطورين المحترفين استخدام جميع الميزات عبر النشر الذاتي. في {{cloud}}، نقدم {{credit}} رصيد مجاني شهريًا لجميع المستخدمين المسجلين.",
"qa.list.free.q": "هل يمكن استخدام {{name}} مجانًا؟",
"qa.list.limit.a": "خطط الاشتراك في {{cloud}} تشمل {{starter}}، {{premium}} و{{ultimate}}، وتوفر أرصدة مختلفة. إذا لم تكن الأرصدة كافية، يمكنك الترقية أو استخدام واجهة برمجة تطبيقات مخصصة.",
"qa.list.limit.q": "ماذا أفعل إذا نفدت أرصدة الحوسبة؟",
"qa.list.management.a": "من صفحة {{subscribe}}، يمكنك ترقية أو تخفيض خطتك، أو التبديل بين الفوترة الشهرية والسنوية. من خلال \"{{usage}}-{{management}}\" يمكنك إدارة الاشتراك عبر Stripe.",
"qa.list.management.q": "كيف أغير أو ألغي اشتراكي؟",
"qa.support.community": "دعم المجتمع",
"qa.support.email": "دعم عبر البريد الإلكتروني",
"qa.title": "الأسئلة الشائعة",
"recurring.day": "يوميًا",
"recurring.fullYear": "سنة كاملة",
"recurring.monthly": "فواتير شهرية",
"recurring.oneMonth": "شهر واحد",
"recurring.oneYear": "سنة واحدة",
"recurring.payonce": "دفع لمرة واحدة",
"recurring.perMonth": "شهريًا",
"recurring.perYear": "سنويًا",
"recurring.sixMonth": "ستة أشهر",
"recurring.threeMonth": "ثلاثة أشهر",
"recurring.title": "دورة الفوترة",
"recurring.yearly": "فواتير سنوية",
"referral.copy.codeSuccess": "تم نسخ رمز الإحالة",
"referral.copy.linkSuccess": "تم نسخ رابط الإحالة",
"referral.edit.button": "تعديل",
"referral.edit.cancel": "إلغاء",
"referral.edit.hint": "يدعم 2-8 أحرف أو أرقام أو شرطات سفلية",
"referral.edit.placeholder": "أدخل رمز الإحالة",
"referral.edit.save": "حفظ",
"referral.errors.alreadyBound": "لقد قمت بربط رمز الدعوة مسبقًا",
"referral.errors.backfillExpired": "انتهت فترة الإكمال. لا يمكن الإكمال بعد 3 أيام من التسجيل",
"referral.errors.codeExists": "رمز الإحالة مستخدم بالفعل، يرجى اختيار رمز آخر",
"referral.errors.invalidCode": "رمز الدعوة غير موجود، يرجى التحقق والمحاولة مرة أخرى",
"referral.errors.invalidFormat": "تنسيق رمز الإحالة غير صالح، يرجى إدخال 2-8 أحرف أو أرقام أو شرطات سفلية",
"referral.errors.selfReferral": "لا يمكنك استخدام رمز الدعوة الخاص بك",
"referral.errors.updateFailed": "فشل التحديث، يرجى المحاولة لاحقًا",
"referral.inviteCode.description": "شارك رمز الإحالة الحصري الخاص بك لدعوة الأصدقاء للتسجيل",
"referral.inviteCode.title": "رمز الإحالة الخاص بي",
"referral.inviteLink.description": "انسخ الرابط وشاركه مع الأصدقاء. بعد التسجيل، ستحصل على مكافآت",
"referral.inviteLink.title": "رابط الإحالة",
"referral.rules.backfill.alreadyBound": "لقد قمت بربط رمز الدعوة مسبقًا",
"referral.rules.backfill.description": "نسيت إدخال رمز الدعوة؟ يمكنك إكماله خلال 3 أيام من التسجيل",
"referral.rules.backfill.expiredTip": "انتهت فترة الإكمال. لا يمكن الإكمال بعد 3 أيام من التسجيل",
"referral.rules.backfill.link": "إكمال رمز الدعوة",
"referral.rules.backfill.placeholder": "أدخل رمز الدعوة",
"referral.rules.backfill.submit": "تأكيد الربط",
"referral.rules.backfill.success": "تم ربط رمز الدعوة بنجاح",
"referral.rules.backfill.title": "إكمال رمز الدعوة",
"referral.rules.description": "تعرف على قواعد برنامج مكافآت الإحالة",
"referral.rules.expiry": "صلاحية الرصيد: يتم مسح أرصدة الإحالة بعد 100 يوم من عدم النشاط",
"referral.rules.missedCode": "فاتك إدخال رمز الدعوة: يمكنك <0>إكماله</0> خلال 3 أيام من التسجيل",
"referral.rules.priority": "أولوية استهلاك الرصيد: الرصيد المجاني → رصيد الاشتراك → رصيد الإحالة → الرصيد المشحون",
"referral.rules.registration": "طريقة التسجيل: يسجل المستخدمون المدعوون عبر رابط الإحالة أو بإدخال الرمز عند التسجيل",
"referral.rules.reward": "المكافأة: يحصل كل من الداعي والمدعو على {{reward}}M رصيد",
"referral.rules.title": "قواعد البرنامج",
"referral.rules.validInvitation": "دعوة صالحة: يسجل المدعو باستخدام رمز الإحالة ويقوم بإجراء صالح واحد",
"referral.rules.validOperation": "معايير الإجراء الصالح: إرسال رسالة واحدة أو إنشاء صورة واحدة",
"referral.stats.availableBalance": "الرصيد المتاح",
"referral.stats.description": "عرض إحصائيات الإحالة الخاصة بك",
"referral.stats.title": "نظرة عامة على الإحالة",
"referral.stats.totalInvites": "إجمالي الدعوات",
"referral.stats.totalRewarded": "التحويلات الصالحة",
"referral.stats.totalRewardedAmount": "إجمالي الأرباح",
"referral.table.columns.createdAt": "وقت التسجيل",
"referral.table.columns.inviteeEmail": "بريد المدعو",
"referral.table.columns.inviterRewardAmount": "مكافأتي",
"referral.table.columns.rewardedAt": "وقت المكافأة",
"referral.table.columns.status": "الحالة",
"referral.table.columns.suspectedReason": "سبب الشك",
"referral.table.status.registered": "مسجل",
"referral.table.status.revoked": "تم الإلغاء",
"referral.table.status.rewarded": "تمت المكافأة",
"referral.table.status.suspected": "يشتبه في وجود خلل",
"referral.table.title": "سجل الإحالات",
"sessionCard.title": "هل ترغب في مغادرة الخطة المجانية؟ قم بالترقية للاستمتاع بالميزات المميزة.",
"summary.desc": "يشمل هذا المبلغ فقط نفقات خدمة الاشتراك.",
"summary.dueBy": "مستحق في {{date}}",
"summary.nextPayment": "الدفعة التالية",
"summary.paymentInformation": "معلومات الفوترة",
"summary.title": "ملخص الفوترة",
"summary.usageThisMonth": "عرض استخدامك هذا الشهر.",
"summary.viewBillingHistory": "عرض سجل المدفوعات",
"switchPlan": "تبديل الخطة",
"switchToMonthly.desc": "بعد التبديل، ستبدأ الفوترة الشهرية بعد انتهاء الخطة السنوية الحالية.",
"switchToMonthly.title": "التبديل إلى الفوترة الشهرية",
"switchToYearly.desc": "بعد التبديل، ستبدأ الفوترة السنوية فور دفع الفرق. تاريخ البدء يستمر من الخطة السابقة.",
"switchToYearly.title": "التبديل إلى الفوترة السنوية",
"tab.billing": "إدارة الفوترة",
"tab.funds": "إدارة الأرصدة",
"tab.plans": "خطط الاشتراك",
"tab.referral": "مكافآت الإحالة",
"tab.spend": "تفاصيل الأرصدة",
"tab.usage": "إحصائيات الاستخدام",
"upgrade": "ترقية",
"upgradeNow": "قم بالترقية الآن",
"upgradePlan": "ترقية الخطة",
"upgradePlans.desc": "تسري ترقية الخطة فورًا بعد دفع الفرق. تاريخ البدء يستمر من الخطة السابقة.",
"upgradePlans.title": "الترقية إلى {{plan}}",
"usage.credit.addon.desc": "يتم إعادة تعيين الحصة في {{time}}",
"usage.credit.addon.used": "أرصدة مشحونة",
"usage.credit.desc": "استخدام الأرصدة للدردشة، توليد الصور، تحويل النص إلى كلام",
"usage.credit.detail": "إحصائيات الاستخدام لآخر {{day}} يومًا",
"usage.credit.free.desc": "يتم إعادة تعيين الحصة في {{time}}",
"usage.credit.free.expired": "انتهت في {{date}}",
"usage.credit.free.used": "أرصدة مجانية",
"usage.credit.referral.desc": "أرصدة المكافآت من دعوة الأصدقاء",
"usage.credit.referral.used": "أرصدة الإحالة",
"usage.credit.subscription.desc": "يتم إعادة تعيين الحصة في {{time}}",
"usage.credit.subscription.used": "أرصدة الاشتراك",
"usage.credit.time.days": "{{days}} يومًا",
"usage.credit.time.daysAndHours": "{{days}} يومًا و{{hours}} ساعة",
"usage.credit.time.hours": "{{hours}} ساعة",
"usage.credit.title": "استخدام أرصدة الحوسبة",
"usage.overview.charge": "الرسوم",
"usage.overview.included": "استخدام الخطة",
"usage.overview.onDemand": "حسب الطلب",
"usage.overview.product": "عنصر المنتج",
"usage.overview.title": "نظرة عامة على الاستخدام",
"usage.storage.desc": "يمكن تحرير تخزين البيانات يدويًا",
"usage.storage.embeddings.used": "تخزين المتجهات",
"usage.storage.file.used": "استخدام الملفات",
"usage.storage.title": "تخزين البيانات",
"usage.title": "استخدام هذا الشهر",
"usage.used": "تم الاستخدام",
"zarinpal.infoModal.desc": "بسبب المتطلبات التنظيمية، يرجى إكمال المعلومات الشخصية التالية قبل تقديم الطلب:",
"zarinpal.infoModal.phone.label": "رقم الهاتف",
"zarinpal.infoModal.phone.placeholder": "يرجى إدخال رقم الهاتف",
"zarinpal.infoModal.phone.rule": "يرجى إدخال رقم هاتف صالح",
"zarinpal.infoModal.submit": "شراء",
"zarinpal.infoModal.title": "املأ المعلومات المطلوبة"
}
+3 -3
View File
@@ -1,6 +1,6 @@
{
"actions.confirmRemoveThread": "سيتم حذف هذا الموضوع الفرعي، ولن يمكن استعادته بعد الحذف، يرجى توخي الحذر.",
"actions.confirmRemoveThread": "أنت على وشك حذف هذا الموضوع الفرعي. بمجرد حذفه، لا يمكن استعادته. يرجى المتابعة بحذر.",
"newPortalThread.includeContext": "تضمين سياق الموضوع",
"newPortalThread.title": "فتح موضوع فرعي جديد",
"notSupportMultiModals": "الموضوعات الفرعية لا تدعم حاليًا تحميل الملفات/الصور، إذا كان لديك أي طلب، لا تتردد في ترك رسالة: <1>💬 قسم النقاش</1>"
"newPortalThread.title": "ابدأ موضوعًا فرعيًا جديدًا",
"notSupportMultiModals": "المواضيع الفرعية لا تدعم حاليًا تحميل الملفات أو الصور. إذا كانت لديك أي طلبات، لا تتردد في ترك رسالة: <1>💬 منطقة النقاش</1>"
}
+84 -72
View File
@@ -1,110 +1,122 @@
{
"agentGroupManagement.executeTask.agent": "تنفيذ الوكيل",
"agentGroupManagement.executeTask.cancelled": "تم الإلغاء",
"agentGroupManagement.executeTask.completed": "اكتمل المهمة",
"agentGroupManagement.executeTask.completed": "اكتمل التنفيذ",
"agentGroupManagement.executeTask.cost": "التكلفة",
"agentGroupManagement.executeTask.failed": "فشل المهمة",
"agentGroupManagement.executeTask.failed": "فشل التنفيذ",
"agentGroupManagement.executeTask.interrupted": "تمت المقاطعة",
"agentGroupManagement.executeTask.intervention.taskPlaceholder": "يرجى وصف المهمة التي يحتاج الوكيل إلى تنفيذها بالتفصيل...",
"agentGroupManagement.executeTask.intervention.taskPlaceholder": "يرجى تقديم وصف مفصل للمهمة التي سيقوم بها الوكيل...",
"agentGroupManagement.executeTask.intervention.timeout": "الحد الأقصى لمدة التنفيذ",
"agentGroupManagement.executeTask.intervention.timeoutUnit": "دقائق",
"agentGroupManagement.executeTask.intervention.unknownAgent": "وكيل غير معروف",
"agentGroupManagement.executeTask.processing": "جارٍ التنفيذ...",
"agentGroupManagement.executeTask.steps": "عدد خطوات التنفيذ",
"agentGroupManagement.executeTask.processing": "جارٍ المعالجة...",
"agentGroupManagement.executeTask.steps": "خطوات التنفيذ",
"agentGroupManagement.executeTask.task": "محتوى المهمة",
"agentGroupManagement.executeTask.thread": "معرّف الخيط",
"agentGroupManagement.executeTask.timeout": "انتهت مهلة التنفيذ",
"agentGroupManagement.executeTask.tokens": "استهلاك الرموز",
"agentGroupManagement.executeTask.thread": "معرّف السلسلة",
"agentGroupManagement.executeTask.timeout": "انتهت مدة التنفيذ",
"agentGroupManagement.executeTask.tokens": "استخدام الرموز",
"codeInterpreter-legacy.error": "خطأ في التنفيذ",
"codeInterpreter-legacy.executing": "جارٍ التنفيذ...",
"codeInterpreter-legacy.files": "الملفات:",
"codeInterpreter-legacy.output": "المخرجات:",
"codeInterpreter-legacy.returnValue": "قيمة الإرجاع:",
"codeInterpreter-legacy.output": "الناتج:",
"codeInterpreter-legacy.returnValue": "القيمة المرجعة:",
"codeInterpreter.error": "خطأ في التنفيذ",
"codeInterpreter.executing": "جارٍ التنفيذ...",
"codeInterpreter.files": "الملفات:",
"codeInterpreter.output": "الإخراج:",
"codeInterpreter.returnValue": "قيمة الإرجاع:",
"codeInterpreter.output": "الناتج:",
"codeInterpreter.returnValue": "القيمة المرجعة:",
"dalle.autoGenerate": "توليد تلقائي",
"dalle.downloading": "صلاحية روابط الصور المُولَّدة بواسطة DallE3 تدوم ساعة واحدة فقط، يتم تحميل الصور إلى الجهاز المحلي...",
"dalle.downloading": "روابط الصور التي تم إنشاؤها بواسطة DALL·E3 صالحة لمدة ساعة واحدة فقط، يتم تخزين الصور محليًا...",
"dalle.generate": "توليد",
"dalle.generating": "جارٍ التوليد...",
"dalle.images": "الصور:",
"dalle.prompt": "كلمة تلميح",
"dalle.prompt": "الموجه",
"lobe-gtd.actions.add": "إضافة",
"lobe-gtd.actions.clearCompleted": "مسح المكتمل",
"lobe-gtd.actions.placeholder": "أدخل مهمة للقيام بها...",
"lobe-gtd.clearTodos.cleared": "تم مسح {{count}} عنصرًا",
"lobe-gtd.clearTodos.clearedCompleted": "تم مسح {{count}} من العناصر المكتملة",
"lobe-gtd.clearTodos.clearedCompleted_one": "تم مسح {{count}} من العناصر المكتملة",
"lobe-gtd.clearTodos.clearedCompleted_other": "تم مسح {{count}} من العناصر المكتملة",
"lobe-gtd.clearTodos.cleared_one": "تم مسح {{count}} عنصرًا",
"lobe-gtd.clearTodos.cleared_other": "تم مسح {{count}} عنصرًا",
"lobe-gtd.actions.clearCompleted": "مسح المكتملة",
"lobe-gtd.actions.placeholder": "أدخل مهمة...",
"lobe-gtd.addTodo.placeholder": "أضف مهمة...",
"lobe-gtd.clearTodos.cleared": "تم مسح {{count}} عنصر(عناصر)",
"lobe-gtd.clearTodos.clearedCompleted": "تم مسح {{count}} عنصر(عناصر) مكتملة",
"lobe-gtd.clearTodos.clearedCompleted_one": "تم مسح عنصر مكتمل واحد",
"lobe-gtd.clearTodos.clearedCompleted_other": "تم مسح {{count}} عناصر مكتملة",
"lobe-gtd.clearTodos.cleared_one": "تم مسح عنصر واحد",
"lobe-gtd.clearTodos.cleared_other": "تم مسح {{count}} عناصر",
"lobe-gtd.clearTodos.header": "مسح المهام",
"lobe-gtd.clearTodos.label": "اختر ما تريد مسحه:",
"lobe-gtd.clearTodos.noItems": "لا توجد عناصر للمسح",
"lobe-gtd.clearTodos.remaining": "تبقّى {{count}} عنصرًا",
"lobe-gtd.clearTodos.remaining_one": "تبقّى {{count}} عنصرًا",
"lobe-gtd.clearTodos.remaining_other": "تبقّى {{count}} عنصرًا",
"lobe-gtd.completeTodos.completed": "تم إكمال {{count}} عنصرًا",
"lobe-gtd.completeTodos.completed_one": "تم إكمال {{count}} عنصرًا",
"lobe-gtd.completeTodos.completed_other": "تم إكمال {{count}} عنصرًا",
"lobe-gtd.clearTodos.option.all": "مسح جميع العناصر (بما في ذلك المعلقة)",
"lobe-gtd.clearTodos.option.completed": "مسح العناصر المكتملة فقط",
"lobe-gtd.clearTodos.remaining": "{{count}} عنصر(عناصر) متبقية",
"lobe-gtd.clearTodos.remaining_one": "عنصر واحد متبقٍ",
"lobe-gtd.clearTodos.remaining_other": "{{count}} عناصر متبقية",
"lobe-gtd.completeTodos.completed": "تم إكمال {{count}} عنصر(عناصر)",
"lobe-gtd.completeTodos.completed_one": "تم إكمال عنصر واحد",
"lobe-gtd.completeTodos.completed_other": "تم إكمال {{count}} عناصر",
"lobe-gtd.createPlan.context.label": "السياق (اختياري)",
"lobe-gtd.createPlan.context.placeholder": "الخلفية، القيود، الاعتبارات...",
"lobe-gtd.createPlan.description.label": "الوصف",
"lobe-gtd.createPlan.description.placeholder": "ملخص مختصر للخطة",
"lobe-gtd.createPlan.goal.label": "الهدف",
"lobe-gtd.createPlan.goal.placeholder": "ما الذي تريد تحقيقه؟",
"lobe-gtd.createTodos.created": "تم إنشاء {{count}} مهمة",
"lobe-gtd.createTodos.created_one": "تم إنشاء {{count}} مهمة",
"lobe-gtd.createTodos.created_other": "تم إنشاء {{count}} مهمة",
"lobe-gtd.createTodos.total": "المجموع: {{count}} عنصرًا",
"lobe-gtd.createTodos.total_one": "المجموع: {{count}} عنصرًا",
"lobe-gtd.createTodos.total_other": "المجموع: {{count}} عنصرًا",
"lobe-gtd.removeTodos.removed": "تم حذف {{count}} عنصرًا",
"lobe-gtd.removeTodos.removed_one": "تم حذف {{count}} عنصرًا",
"lobe-gtd.removeTodos.removed_other": "تم حذف {{count}} عنصرًا",
"lobe-gtd.status.done": "{{count}} مكتمل",
"lobe-gtd.status.pending": "{{count}} قيد الانتظار",
"lobe-gtd.createTodos.created_one": "تم إنشاء مهمة واحدة",
"lobe-gtd.createTodos.created_other": "تم إنشاء {{count}} مهام",
"lobe-gtd.createTodos.total": "الإجمالي: {{count}} عنصر(عناصر)",
"lobe-gtd.createTodos.total_one": "الإجمالي: عنصر واحد",
"lobe-gtd.createTodos.total_other": "الإجمالي: {{count}} عناصر",
"lobe-gtd.removeTodos.removed": "تمت إزالة {{count}} عنصر(عناصر)",
"lobe-gtd.removeTodos.removed_one": "تمت إزالة عنصر واحد",
"lobe-gtd.removeTodos.removed_other": "تمت إزالة {{count}} عناصر",
"lobe-gtd.status.done": "{{count}} مكتملة",
"lobe-gtd.status.pending": "{{count}} معلقة",
"lobe-gtd.todoItem.placeholder": "أدخل مهمة...",
"lobe-gtd.todoList.empty": "قائمة المهام فارغة",
"lobe-gtd.todoList.items": "{{count}} عنصرًا",
"lobe-gtd.todoList.items_one": "{{count}} عنصرًا",
"lobe-gtd.todoList.items_other": "{{count}} عنصرًا",
"lobe-gtd.todoList.items": "{{count}} عنصر(عناصر)",
"lobe-gtd.todoList.items_one": "عنصر واحد",
"lobe-gtd.todoList.items_other": "{{count}} عناصر",
"lobe-gtd.todoList.title": "قائمة المهام",
"lobe-gtd.updateTodos.updated": "تم تحديث قائمة المهام",
"lobe-knowledge-base.readKnowledge.meta.chars": "عدد الأحرف",
"lobe-knowledge-base.readKnowledge.meta.lines": "عدد السطور",
"lobe-knowledge-base.readKnowledge.meta.lines": "عدد الأسطر",
"localFiles.editFile.newString": "استبدال بـ",
"localFiles.editFile.oldString": "البحث عن",
"localFiles.editFile.replaceAll": "استبدال جميع المطابقات",
"localFiles.editFile.replaceFirst": "استبدال أول مطابقة فقط",
"localFiles.editFile.oldString": "بحث عن",
"localFiles.editFile.replaceAll": "استبدال جميع التكرارات",
"localFiles.editFile.replaceFirst": "استبدال التكرار الأول فقط",
"localFiles.file": "ملف",
"localFiles.folder": "مجلد",
"localFiles.moveFiles.itemsMoved": "تم نقل {{count}} عنصر:",
"localFiles.moveFiles.itemsMoved_one": "تم نقل {{count}} عنصر:",
"localFiles.moveFiles.itemsMoved_other": "تم نقل {{count}} عنصر:",
"localFiles.moveFiles.itemsToMove": "{{count}} عنصر في انتظار النقل:",
"localFiles.moveFiles.itemsToMove_one": "{{count}} عنصر في انتظار النقل:",
"localFiles.moveFiles.itemsToMove_other": "{{count}} عنصر في انتظار النقل:",
"localFiles.moveFiles.itemsMoved": "تم نقل {{count}} عنصر(عناصر):",
"localFiles.moveFiles.itemsMoved_one": "تم نقل عنصر واحد:",
"localFiles.moveFiles.itemsMoved_other": "تم نقل {{count}} عناصر:",
"localFiles.moveFiles.itemsToMove": "{{count}} عنصر(عناصر) للنقل:",
"localFiles.moveFiles.itemsToMove_one": "عنصر واحد للنقل:",
"localFiles.moveFiles.itemsToMove_other": "{{count}} عناصر للنقل:",
"localFiles.open": "فتح",
"localFiles.openFile": "فتح ملف",
"localFiles.openFolder": "فتح مجلد",
"localFiles.read.more": "عرض المزيد",
"localFiles.readFile": "قراءة الملف",
"localFiles.readFileError": "فشل في قراءة الملف، يرجى التحقق من صحة مسار الملف",
"localFiles.readFileError": "فشل في قراءة الملف، يرجى التحقق من صحة المسار",
"localFiles.readFiles": "قراءة الملفات",
"localFiles.readFilesError": "فشل في قراءة الملفات، يرجى التحقق من صحة مسار الملف",
"localFiles.readFilesError": "فشل في قراءة الملفات، يرجى التحقق من صحة المسار",
"localFiles.writeFile.characters": "أحرف",
"localFiles.writeFile.preview": "معاينة المحتوى",
"localFiles.writeFile.truncated": "تم الاقتطاع",
"localFiles.writeFile.truncated": "مقتطع",
"search.createNewSearch": "إنشاء سجل بحث جديد",
"search.emptyResult": "لم يتم العثور على نتائج، يرجى تعديل الكلمات الرئيسية والمحاولة مرة أخرى",
"search.genAiMessage": "إنشاء رسالة مساعد",
"search.includedTooltip": تدخل نتائج البحث الحالية في سياق المحادثة",
"search.keywords": "الكلمات الرئيسية:",
"search.scoreTooltip": "درجة الصلة، كلما كانت هذه الدرجة أعلى، كانت أكثر ارتباطًا بكلمات البحث",
"search.emptyResult": "لم يتم العثور على نتائج، يرجى تعديل الكلمات المفتاحية والمحاولة مرة أخرى",
"search.genAiMessage": "إنشاء رسالة وكيل",
"search.includedTooltip": يتم تضمين نتائج البحث الحالية في سياق المحادثة",
"search.keywords": "الكلمات المفتاحية:",
"search.scoreTooltip": "درجة الصلة؛ تشير الدرجة الأعلى إلى تطابق أقرب مع الكلمات المفتاحية",
"search.searchBar.button": "بحث",
"search.searchBar.placeholder": "الكلمات الرئيسية",
"search.searchBar.tooltip": "سيتم إعادة الحصول على نتائج البحث، وإنشاء رسالة ملخص جديدة",
"search.searchCategory.placeholder": "ابحث عن الفئة",
"search.searchBar.placeholder": "كلمات مفتاحية",
"search.searchBar.tooltip": "سيؤدي هذا إلى تحديث نتائج البحث وإنشاء رسالة ملخص جديدة",
"search.searchCategory.placeholder": "فئة البحث",
"search.searchCategory.title": "فئة البحث:",
"search.searchCategory.value.files": "ملفات",
"search.searchCategory.value.general": "عام",
"search.searchCategory.value.images": "صور",
"search.searchCategory.value.it": "تكنولوجيا المعلومات",
"search.searchCategory.value.map": "خريطة",
"search.searchCategory.value.map": "خرائط",
"search.searchCategory.value.music": "موسيقى",
"search.searchCategory.value.news": "أخبار",
"search.searchCategory.value.science": "علوم",
@@ -112,21 +124,21 @@
"search.searchCategory.value.videos": "فيديوهات",
"search.searchEngine.placeholder": "محرك البحث",
"search.searchEngine.title": "محرك البحث:",
"search.searchResult": "عدد النتائج:",
"search.searchTimeRange.title": "نطاق الوقت:",
"search.searchResult": "عدد عمليات البحث:",
"search.searchTimeRange.title": "النطاق الزمني:",
"search.searchTimeRange.value.anytime": "في أي وقت",
"search.searchTimeRange.value.day": "خلال يوم واحد",
"search.searchTimeRange.value.month": "خلال شهر واحد",
"search.searchTimeRange.value.week": "خلال أسبوع واحد",
"search.searchTimeRange.value.year": "خلال سنة واحدة",
"search.summary": "ملخص",
"search.searchTimeRange.value.day": "خلال يوم",
"search.searchTimeRange.value.month": "خلال شهر",
"search.searchTimeRange.value.week": "خلال أسبوع",
"search.searchTimeRange.value.year": "خلال سنة",
"search.summary": "الملخص",
"search.summaryTooltip": "تلخيص المحتوى الحالي",
"search.viewMoreResults": "عرض المزيد من {{results}} نتيجة",
"search.viewMoreResults": "عرض {{results}} نتيجة إضافية",
"updateArgs.duplicateKeyError": "يجب أن يكون مفتاح الحقل فريدًا",
"updateArgs.form.add": "إضافة عنصر",
"updateArgs.form.key": "مفتاح الحقل",
"updateArgs.form.value": "قيمة الحقل",
"updateArgs.formValidationFailed": "فشل التحقق من صحة النموذج، يرجى التحقق من تنسيق المعلمات",
"updateArgs.keyRequired": "لا يمكن أن يكون مفتاح الحقل فارغًا",
"updateArgs.stringifyError": "تعذر تسلسل المعلمات، يرجى التحقق من تنسيق المعلمات"
"updateArgs.stringifyError": "تعذر تحويل المعلمات إلى سلسلة، يرجى التحقق من تنسيق المعلمات"
}
+16 -16
View File
@@ -1,37 +1,37 @@
{
"actions.addNewTopic": "ابدأ موضوعًا جديدًا",
"actions.autoRename": "إعادة تسمية ذكية",
"actions.confirmRemoveAll": "سيتم حذف جميع المواضيع، ولن يمكن استعادتها بعد الحذف، يرجى توخي الحذر.",
"actions.confirmRemoveTopic": "سيتم حذف هذا الموضوع، ولن يمكن استعادته بعد الحذف، يرجى توخي الحذر.",
"actions.confirmRemoveUnstarred": "سيتم حذف المواضيع غير المفضلة، ولن يمكن استعادتها بعد الحذف، يرجى توخي الحذر.",
"actions.duplicate": "إنشاء نسخة",
"actions.export": "تصدير الموضوع",
"actions.confirmRemoveAll": "أنت على وشك حذف جميع المواضيع. لا يمكن التراجع عن هذا الإجراء.",
"actions.confirmRemoveTopic": "أنت على وشك حذف هذا الموضوع. لا يمكن التراجع عن هذا الإجراء.",
"actions.confirmRemoveUnstarred": "أنت على وشك حذف المواضيع غير المميزة. لا يمكن التراجع عن هذا الإجراء.",
"actions.duplicate": "نسخ",
"actions.export": "تصدير المواضيع",
"actions.import": "استيراد المحادثة",
"actions.openInNewWindow": "افتح في نافذة مستقلة",
"actions.openInNewWindow": "فتح في نافذة جديدة",
"actions.removeAll": "حذف جميع المواضيع",
"actions.removeUnstarred": "حذف المواضيع غير المفضلة",
"actions.removeUnstarred": "حذف المواضيع غير المميزة",
"defaultTitle": "موضوع افتراضي",
"displayItems": "عرض العناصر",
"duplicateLoading": "يتم نسخ الموضوع...",
"duplicateLoading": "جارٍ نسخ الموضوع...",
"duplicateSuccess": "تم نسخ الموضوع بنجاح",
"favorite": "مفضل",
"groupMode.ascMessages": "ترتيب حسب إجمالي عدد الرسائل",
"groupMode.ascMessages": "ترتيب حسب عدد الرسائل تصاعديًا",
"groupMode.byTime": "تجميع حسب الوقت",
"groupMode.descMessages": "ترتيب عكسي حسب إجمالي عدد الرسائل",
"groupMode.descMessages": "ترتيب حسب عدد الرسائل تنازليًا",
"groupMode.flat": "بدون تجميع",
"groupTitle.byTime.month": "هذا الشهر",
"groupTitle.byTime.today": "اليوم",
"groupTitle.byTime.week": "هذا الأسبوع",
"groupTitle.byTime.yesterday": "أمس",
"guide.desc": "انقر على زر الإرسال على اليسار لحفظ المحادثة الحالية كموضوع تاريخي وبدء جولة جديدة من المحادثة",
"guide.desc": "انقر على الزر في اليسار لحفظ المحادثة الحالية كموضوع محفوظ وبدء محادثة جديدة.",
"guide.title": "قائمة المواضيع",
"importError": "فشل في الاستيراد",
"importInvalidFormat": "تنسيق الملف غير صالح، يرجى التأكد من أنه ملف JSON صالح",
"importInvalidFormat": "تنسيق الملف غير صالح. يرجى التأكد من أنه ملف JSON صالح.",
"importLoading": "جارٍ استيراد المحادثة...",
"importSuccess": "تم استيراد {{count}} رسالة بنجاح",
"loadMore": "المزيد",
"searchPlaceholder": "ابحث عن موضوع...",
"searchResultEmpty": ا توجد نتائج للبحث",
"loadMore": "تحميل المزيد",
"searchPlaceholder": "ابحث في المواضيع...",
"searchResultEmpty": م يتم العثور على نتائج.",
"temp": "مؤقت",
"title": "موضوع"
"title": "الموضوع"
}

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