✨ feat: support AI Image (#8312)
Co-authored-by: canisminor1990 <i@canisminor.cc>
This commit is contained in:
co-authored by
canisminor1990
parent
c98860e6cf
commit
095de57675
@@ -1,8 +1,9 @@
|
||||
---
|
||||
description:
|
||||
description:
|
||||
globs: src/services/**/*,src/database/**/*,src/server/**/*
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
# LobeChat 后端技术架构指南
|
||||
|
||||
本指南旨在阐述 LobeChat 项目的后端分层架构,重点介绍各核心目录的职责以及它们之间的协作方式。
|
||||
@@ -29,24 +30,21 @@ LobeChat 的后端设计注重模块化、可测试性和灵活性,以适应
|
||||
其主要分层如下:
|
||||
|
||||
1. 客户端服务层 (`src/services`):
|
||||
|
||||
- 位于 src/services/。
|
||||
- 这是客户端业务逻辑的核心层,负责封装各种业务操作和数据处理逻辑。
|
||||
- 环境适配: 根据不同的运行环境,服务层会选择合适的数据访问方式:
|
||||
- 本地数据库模式: 直接调用 `Model` 层进行数据操作,适用于浏览器 PGLite 和本地 Electron 应用。
|
||||
- 远程数据库模式: 通过 `tRPC` 客户端调用服务端 API,适用于需要云同步的场景。
|
||||
- 本地数据库模式: 直接调用 `Model` 层进行数据操作,适用于浏览器 PGLite 和本地 Electron 应用。
|
||||
- 远程数据库模式: 通过 `tRPC` 客户端调用服务端 API,适用于需要云同步的场景。
|
||||
- 类型转换: 对于简单的数据类型转换,直接在此层进行类型断言,如 `this.pluginModel.query() as Promise<LobeTool[]>`
|
||||
- 每个服务模块通常包含 `client.ts`(本地模式)、`server.ts`(远程模式)和 `type.ts`(接口定义)文件,在实现时应该确保本地模式和远程模式业务逻辑实现一致,只是数据库不同。
|
||||
|
||||
2. API 接口层 (`TRPC`):
|
||||
|
||||
- 位于 src/server/routers/
|
||||
- 使用 `tRPC` 构建类型安全的 API。Router 根据运行时环境(如 Edge Functions, Node.js Lambda)进行组织。
|
||||
- 负责接收客户端请求,并将其路由到相应的 `Service` 层进行处理。
|
||||
- 新建 lambda 端点时可以参考 src/server/routers/lambda/\_template.ts
|
||||
|
||||
3. 仓库层 (`Repositories`):
|
||||
|
||||
- 位于 src/database/repositories/。
|
||||
- 主要处理复杂的跨表查询和数据聚合逻辑,特别是当需要从多个 `Model` 获取数据并进行组合时。
|
||||
- 与 `Model` 层不同,`Repository` 层专注于复杂的业务查询场景,而不涉及简单的领域模型转换。
|
||||
@@ -54,7 +52,6 @@ LobeChat 的后端设计注重模块化、可测试性和灵活性,以适应
|
||||
- 如果数据操作简单(仅涉及单个 `Model`),则通常直接在 `src/services` 层调用 `Model` 并进行简单的类型断言。
|
||||
|
||||
4. 模型层 (`Models`):
|
||||
|
||||
- 位于 src/database/models/ (例如 src/database/models/plugin.ts 和 src/database/models/document.ts)。
|
||||
- 提供对数据库中各个表(由 src/database/schemas/ 中的 Drizzle ORM schema 定义)的基本 CRUD (创建、读取、更新、删除) 操作和简单的查询能力。
|
||||
- `Model` 类专注于单个数据表的直接操作,不涉及复杂的领域模型转换,这些转换通常在上层的 `src/services` 中通过类型断言完成。
|
||||
@@ -65,11 +62,11 @@ LobeChat 的后端设计注重模块化、可测试性和灵活性,以适应
|
||||
- 客户端模式 (浏览器/PWA): 使用 PGLite (基于 WASM 的 PostgreSQL),数据存储在用户浏览器本地。
|
||||
- 服务端模式 (云部署): 使用远程 PostgreSQL 数据库。
|
||||
- Electron 桌面应用:
|
||||
- Electron 客户端会启动一个本地 Node.js 服务。
|
||||
- 本地服务通过 `tRPC` 与 Electron 的渲染进程通信。
|
||||
- 数据库选择依赖于是否开启云同步功能:
|
||||
- 云同步开启: 连接到远程 PostgreSQL 数据库。
|
||||
- 云同步关闭: 使用 PGLite (通过 Node.js 的 WASM 实现) 在本地存储数据。
|
||||
- Electron 客户端会启动一个本地 Node.js 服务。
|
||||
- 本地服务通过 `tRPC` 与 Electron 的渲染进程通信。
|
||||
- 数据库选择依赖于是否开启云同步功能:
|
||||
- 云同步开启: 连接到远程 PostgreSQL 数据库。
|
||||
- 云同步关闭: 使用 PGLite (通过 Node.js 的 WASM 实现) 在本地存储数据。
|
||||
|
||||
## 数据流向说明
|
||||
|
||||
@@ -93,8 +90,87 @@ UI (Electron Renderer) → Zustand action → Client Service -> TRPC Client →
|
||||
|
||||
## 服务层 (Server Services)
|
||||
|
||||
- 位于 src/server/services/。
|
||||
- 核心职责是封装独立的、可复用的业务逻辑单元。这些服务应易于测试。
|
||||
- 平台差异抽象: 一个关键特性是通过其内部的 `impls` 子目录(例如 src/server/services/file/impls 包含 s3.ts 和 local.ts)来抹平不同运行环境带来的差异(例如云端使用 S3 存储,桌面版使用本地文件系统)。这使得上层(如 `tRPC` routers)无需关心底层具体实现。
|
||||
- 目标是使 `tRPC` router 层的逻辑尽可能纯粹,专注于请求处理和业务流程编排。
|
||||
- 服务可能会调用 `Repository` 层或直接调用 `Model` 层进行数据持久化和检索,也可能调用其他服务。
|
||||
- 位于 src/server/services/。
|
||||
- 核心职责是封装独立的、可复用的业务逻辑单元。这些服务应易于测试。
|
||||
- 平台差异抽象: 一个关键特性是通过其内部的 `impls` 子目录(例如 src/server/services/file/impls 包含 s3.ts 和 local.ts)来抹平不同运行环境带来的差异(例如云端使用 S3 存储,桌面版使用本地文件系统)。这使得上层(如 `tRPC` routers)无需关心底层具体实现。
|
||||
- 目标是使 `tRPC` router 层的逻辑尽可能纯粹,专注于请求处理和业务流程编排。
|
||||
- 服务可能会调用 `Repository` 层或直接调用 `Model` 层进行数据持久化和检索,也可能调用其他服务。
|
||||
|
||||
## 最佳实践 (Best Practices)
|
||||
|
||||
### 数据库操作封装原则
|
||||
|
||||
**连续的数据库操作应该封装到 Model 层**
|
||||
|
||||
当业务逻辑涉及多个相关的数据库操作时,建议将这些操作封装到 Model 层中,而不是在上层(Service 或 Router 层)中进行多次数据库调用。
|
||||
|
||||
**优势:**
|
||||
|
||||
- **代码复用**: Client DB 环境的 service 实现和 Server DB 的 lambda 层实现可以复用相同的 Model 方法
|
||||
- **事务一致性**: 相关的数据库操作可以在同一个方法中管理,便于维护数据一致性
|
||||
- **性能优化**: 减少数据库连接次数,提高查询效率
|
||||
- **职责清晰**: Model 层专注数据访问,上层专注业务协调
|
||||
|
||||
**示例:**
|
||||
|
||||
```typescript
|
||||
// ✅ 推荐:在 Model 层封装连续的数据库操作
|
||||
class GenerationBatchModel {
|
||||
async delete(id: string): Promise<{ deletedBatch: BatchItem; thumbnailUrls: string[] }> {
|
||||
// 1. 查询相关数据
|
||||
const batchWithGenerations = await this.db.query.generationBatches.findFirst({...});
|
||||
|
||||
// 2. 收集需要处理的数据
|
||||
const thumbnailUrls = [...];
|
||||
|
||||
// 3. 执行删除操作
|
||||
const [deletedBatch] = await this.db.delete(generationBatches)...;
|
||||
|
||||
return { deletedBatch, thumbnailUrls };
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ 上层使用简洁
|
||||
const { thumbnailUrls } = await model.delete(id);
|
||||
await fileService.deleteFiles(thumbnailUrls);
|
||||
```
|
||||
|
||||
### 文件操作与数据库操作的执行顺序
|
||||
|
||||
**删除操作原则:数据库删除在前,文件删除在后**
|
||||
|
||||
当业务逻辑同时涉及数据库记录和文件系统操作时,应该遵循"数据库优先"的原则。
|
||||
|
||||
**原因:**
|
||||
|
||||
- **用户体验优先**: 如果先删除文件再删除数据库记录,可能出现文件已删除但数据库记录仍存在的情况,用户访问时会遇到文件不存在的错误
|
||||
- **影响程度较小**: 如果先删除数据库记录再删除文件,即使文件删除失败,用户也看不到这个记录,只是造成一些存储空间浪费,对用户体验影响更小
|
||||
- **数据一致性**: 数据库记录是业务逻辑的核心,应该优先保证其一致性
|
||||
|
||||
**示例:**
|
||||
|
||||
```typescript
|
||||
// ✅ 推荐:先删除数据库记录,再删除文件
|
||||
async deleteGeneration(id: string) {
|
||||
// 1. 先删除数据库记录
|
||||
const deletedGeneration = await generationModel.delete(id);
|
||||
|
||||
// 2. 再删除相关文件
|
||||
if (deletedGeneration.asset?.thumbnailUrl) {
|
||||
await fileService.deleteFile(deletedGeneration.asset.thumbnailUrl);
|
||||
}
|
||||
}
|
||||
|
||||
// ❌ 不推荐:先删除文件
|
||||
async deleteGeneration(id: string) {
|
||||
const generation = await generationModel.findById(id);
|
||||
|
||||
// 如果这里删除成功,但后面数据库删除失败,用户会遇到访问错误
|
||||
await fileService.deleteFile(generation.asset.thumbnailUrl);
|
||||
await generationModel.delete(id); // 可能失败
|
||||
}
|
||||
```
|
||||
|
||||
**创建操作原则:数据库创建在前,文件操作在后**
|
||||
|
||||
创建操作同样应该优先处理数据库记录,确保数据的一致性和完整性。
|
||||
|
||||
+45
-35
@@ -1,21 +1,25 @@
|
||||
---
|
||||
description:
|
||||
globs:
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# Guide to Optimize Output(Response) Rendering
|
||||
|
||||
## File Path and Code Symbol Rendering
|
||||
|
||||
- When rendering file paths, use backtick wrapping instead of markdown links so they can be parsed as clickable links in Cursor IDE.
|
||||
- Good: `src/components/Button.tsx`
|
||||
- Bad: [src/components/Button.tsx](src/components/Button.tsx)
|
||||
|
||||
- Good: `src/components/Button.tsx`
|
||||
- Bad: [src/components/Button.tsx](mdc:src/components/Button.tsx)
|
||||
- Don't use line and column number in file path, this will make file path not clickable in Cursor IDE.
|
||||
- Good: `src/components/Button.tsx` `10:20` (add a space between the file path and the line and column number)
|
||||
- Bad: `src/components/Button.tsx:10:20`
|
||||
|
||||
- When rendering functions, variables, or other code symbols, use backtick wrapping so they can be parsed as navigable links in Cursor IDE
|
||||
- Good: The `useState` hook in `MyComponent`
|
||||
- Bad: The useState hook in MyComponent
|
||||
|
||||
- Good: The `useState` hook in `MyComponent`
|
||||
- Bad: The useState hook in MyComponent
|
||||
|
||||
## Markdown Render
|
||||
|
||||
- don't use br tag to wrap in table cell
|
||||
@@ -23,9 +27,9 @@ alwaysApply: true
|
||||
## Terminal Command Output
|
||||
|
||||
- If terminal commands don't produce output, it's likely due to paging issues. Try piping the command to `cat` to ensure full output is displayed.
|
||||
- Good: `git show commit_hash -- file.txt | cat`
|
||||
- Good: `git log --oneline | cat`
|
||||
- Reason: Some git commands use pagers by default, which may prevent output from being captured properly
|
||||
- Good: `git show commit_hash -- file.txt | cat`
|
||||
- Good: `git log --oneline | cat`
|
||||
- Reason: Some git commands use pagers by default, which may prevent output from being captured properly
|
||||
|
||||
## Mermaid Diagram Generation: Strict Syntax Validation Checklist
|
||||
|
||||
@@ -44,50 +48,56 @@ Before producing any Mermaid diagram, you **must** compare your final code line-
|
||||
|
||||
### Checklist Details
|
||||
|
||||
#### Rule 1: Edge Labels – Must Be Plain Text Only
|
||||
#### Rule 1: Edge Labels – Must Be Plain Text Only
|
||||
|
||||
> **Essence:** Anything inside `|...|` must contain pure, unformatted text. Absolutely NO Markdown, list markers, or parentheses/brackets allowed—these often cause rendering failures.
|
||||
|
||||
- **✅ Do:** `A -->|Process plain text data| B`
|
||||
- **❌ Don't:** `A -->|1. Ordered list item| B` (No numbered lists)
|
||||
- **❌ Don't:** `CC --"1. fetch('/api/...')"--> API` (No square brackets)
|
||||
- **❌ Don't:** `A -->|- Unordered list item| B` (No hyphen lists)
|
||||
- **❌ Don't:** `A -->|Transform (important)| B` (No parentheses)
|
||||
- **❌ Don't:** `A -->|Transform [important]| B` (No square brackets)
|
||||
- **✅ Do:** `A -->|Process plain text data| B`
|
||||
- **❌ Don't:** `A -->|1. Ordered list item| B` (No numbered lists)
|
||||
- **❌ Don't:** `CC --"1. fetch('/api/...')"--> API` (No square brackets)
|
||||
- **❌ Don't:** `A -->|- Unordered list item| B` (No hyphen lists)
|
||||
- **❌ Don't:** `A -->|Transform (important)| B` (No parentheses)
|
||||
- **❌ Don't:** `A -->|Transform [important]| B` (No square brackets)
|
||||
|
||||
#### Rule 2: Node Definition – Handle Special Characters with Care
|
||||
|
||||
#### Rule 2: Node Definition – Handle Special Characters with Care
|
||||
> **Essence:** When node text or subgraph titles contain special characters like `()` or `[]`, wrap the text in quotes to avoid conflicts with Mermaid shape syntax.
|
||||
|
||||
- **When your node text includes parentheses (e.g., 'React (JSX)'):**
|
||||
- **✅ Do:** `I_REACT["<b>React component (JSX)</b>"]` (Quotes wrap all text)
|
||||
- **❌ Don't:** `I_REACT(<b>React component (JSX)</b>)` (Wrong, Mermaid parses this as a shape)
|
||||
- **❌ Don't:** `subgraph Plugin Features (Plugins)` (Wrong, subgraph titles with parentheses must also be wrapped in quotes)
|
||||
- **When your node text includes parentheses (e.g., 'React (JSX)'):**
|
||||
- **✅ Do:** `I_REACT["<b>React component (JSX)</b>"]` (Quotes wrap all text)
|
||||
- **❌ Don't:** `I_REACT(<b>React component (JSX)</b>)` (Wrong, Mermaid parses this as a shape)
|
||||
- **❌ Don't:** `subgraph Plugin Features (Plugins)` (Wrong, subgraph titles with parentheses must also be wrapped in quotes)
|
||||
|
||||
#### Rule 3: Double Quotes in Text – Must Be Escaped
|
||||
|
||||
#### Rule 3: Double Quotes in Text – Must Be Escaped
|
||||
> **Essence:** Use `"` for double quotes **inside node text**.
|
||||
|
||||
- **✅ Do:** `A[This node contains "quotes"]`
|
||||
- **❌ Don't:** `A[This node contains "quotes"]`
|
||||
- **✅ Do:** `A[This node contains "quotes"]`
|
||||
- **❌ Don't:** `A[This node contains "quotes"]`
|
||||
|
||||
#### Rule 4: All Formatting Must Use HTML Tags (NOT Markdown!)
|
||||
|
||||
#### Rule 4: All Formatting Must Use HTML Tags (NOT Markdown!)
|
||||
> **Essence:** For newlines, bold, and other text formatting in nodes, use HTML tags only. Markdown is not supported.
|
||||
|
||||
- **✅ Do (robust):** `A["<b>Bold</b> and <code>code</code><br>This is a new line"]`
|
||||
- **❌ Don't (not rendered):** `C["# This is a heading"]`
|
||||
- **❌ Don't (not rendered):** ``C["`const` means constant"]``
|
||||
- **⚠️ Warning (unreliable):** `B["Markdown **bold** might sometimes work but DON'T rely on it"]`
|
||||
- **✅ Do (robust):** `A["<b>Bold</b> and <code>code</code><br>This is a new line"]`
|
||||
- **❌ Don't (not rendered):** `C["# This is a heading"]`
|
||||
- **❌ Don't (not rendered):** ``C["`const` means constant"]``
|
||||
- **⚠️ Warning (unreliable):** `B["Markdown **bold** might sometimes work but DON'T rely on it"]`
|
||||
|
||||
#### Rule 5: No HTML Tags for Participants and Message Labels (Sequence Diagrams)
|
||||
|
||||
#### Rule 5: No HTML Tags for Participants and Message Labels (Sequence Diagrams)
|
||||
> **Important Addition:**
|
||||
> In Mermaid sequence diagrams, you MUST NOT use any HTML tags (such as `<b>`, `<code>`, etc.) in:
|
||||
>
|
||||
> - `participant` display names (`as` part)
|
||||
> - Message labels (the text after `:` in diagram flows)
|
||||
>
|
||||
> These tags are generally not rendered—they may appear as-is or cause compatibility issues.
|
||||
|
||||
- **✅ Do:** `participant A as Client`
|
||||
- **❌ Don't:** `participant A as <b>Client</b>`
|
||||
- **✅ Do:** `A->>B: 1. Establish connection`
|
||||
- **❌ Don't:** `A->>B: 1. <code>Establish connection</code>`
|
||||
- **✅ Do:** `participant A as Client`
|
||||
- **❌ Don't:** `participant A as <b>Client</b>`
|
||||
- **✅ Do:** `A->>B: 1. Establish connection`
|
||||
- **❌ Don't:** `A->>B: 1. <code>Establish connection</code>`
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
description:
|
||||
globs: src/locales/**/*
|
||||
alwaysApply: false
|
||||
---
|
||||
read [i18n.mdc](mdc:.cursor/rules/i18n/i18n.mdc)
|
||||
@@ -1,19 +1,16 @@
|
||||
---
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
## Project Description
|
||||
|
||||
You are developing an open-source, modern-design AI chat framework: lobe chat.
|
||||
|
||||
Emoji logo: 🤯
|
||||
You are developing an open-source, modern-design AI chat framework: lobe chat.
|
||||
|
||||
Emoji logo: 🤯
|
||||
|
||||
## Project Technologies Stack
|
||||
|
||||
read [package.json](mdc:package.json) to know all npm packages you can use.
|
||||
read [folder-structure.mdx](mdc:docs/development/basic/folder-structure.mdx) to learn project structure.
|
||||
read [package.json](mdc:package.json) to know all npm packages you can use. read [folder-structure.mdx](mdc:docs/development/basic/folder-structure.mdx) to learn project structure.
|
||||
|
||||
The project uses the following technologies:
|
||||
|
||||
@@ -45,3 +42,72 @@ The project uses the following technologies:
|
||||
- Cursor AI for code editing and AI coding assistance
|
||||
|
||||
Note: All tools and libraries used are the latest versions. The application only needs to be compatible with the latest browsers;
|
||||
|
||||
## Often used npm scripts
|
||||
|
||||
```bash
|
||||
# type check
|
||||
bun type-check
|
||||
|
||||
# install dependencies
|
||||
pnpm install
|
||||
|
||||
# !: don't any build script to check weather code can work after modify
|
||||
```
|
||||
|
||||
check [testing guide](./testing-guide.mdc) to learn test scripts.
|
||||
|
||||
## Project Description
|
||||
|
||||
You are developing an open-source, modern-design AI chat framework: lobe chat.
|
||||
|
||||
Emoji logo: 🤯
|
||||
|
||||
## Project Technologies Stack
|
||||
|
||||
read [package.json](mdc:package.json) to know all npm packages you can use. read [folder-structure.mdx](mdc:docs/development/basic/folder-structure.mdx) to learn project structure.
|
||||
|
||||
The project uses the following technologies:
|
||||
|
||||
- pnpm as package manager
|
||||
- Next.js 15 for frontend and backend, using app router instead of pages router
|
||||
- react 19, using hooks, functional components, react server components
|
||||
- TypeScript programming language
|
||||
- antd, @lobehub/ui for component framework
|
||||
- antd-style for css-in-js framework
|
||||
- react-layout-kit for flex layout
|
||||
- react-i18next for i18n
|
||||
- lucide-react, @ant-design/icons for icons
|
||||
- @lobehub/icons for AI provider/model logo icon
|
||||
- @formkit/auto-animate for react list animation
|
||||
- zustand for global state management
|
||||
- nuqs for type-safe search params state manager
|
||||
- SWR for react data fetch
|
||||
- aHooks for react hooks library
|
||||
- dayjs for date and time library
|
||||
- lodash-es for utility library
|
||||
- fast-deep-equal for deep comparison of JavaScript objects
|
||||
- zod for data validation
|
||||
- TRPC for type safe backend
|
||||
- PGLite for client DB and PostgreSQL for backend DB
|
||||
- Drizzle ORM
|
||||
- Vitest for testing, testing-library for react component test
|
||||
- Prettier for code formatting
|
||||
- ESLint for code linting
|
||||
- Cursor AI for code editing and AI coding assistance
|
||||
|
||||
Note: All tools and libraries used are the latest versions. The application only needs to be compatible with the latest browsers;
|
||||
|
||||
## Often used npm scripts
|
||||
|
||||
```bash
|
||||
# type check
|
||||
bun type-check
|
||||
|
||||
# install dependencies
|
||||
pnpm install
|
||||
|
||||
# !: don't any build script to check weather code can work after modify
|
||||
```
|
||||
|
||||
check [testing guide](./testing-guide.mdc) to learn test scripts.
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
---
|
||||
description:
|
||||
globs:
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# LobeChat Cursor Rules System Guide
|
||||
|
||||
This document explains how the LobeChat project's Cursor rules system works and serves as an index for manually accessible rules.
|
||||
@@ -14,22 +15,26 @@ This document explains how the LobeChat project's Cursor rules system works and
|
||||
## 📚 Four Ways to Access Rules
|
||||
|
||||
### 1. **Always Applied Rules** - `always_applied_workspace_rules`
|
||||
|
||||
- **What**: Core project guidelines that are always active
|
||||
- **Content**: Project tech stack, basic coding standards, output formatting rules
|
||||
- **Access**: No tools needed - automatically provided in every conversation
|
||||
|
||||
### 2. **Dynamic Context Rules** - `cursor_rules_context`
|
||||
|
||||
- **What**: Rules automatically matched based on files referenced in the conversation
|
||||
- **Trigger**: Only when user **explicitly @ mentions files** or **opens files in Cursor**
|
||||
- **Content**: May include brief descriptions or full rule content, depending on relevance
|
||||
- **Access**: No tools needed - automatically updated when files are referenced
|
||||
|
||||
### 3. **Agent Requestable Rules** - `agent_requestable_workspace_rules`
|
||||
|
||||
- **What**: Detailed operational guides that can be requested on-demand
|
||||
- **Access**: Use `fetch_rules` tool with rule names
|
||||
- **Examples**: `debug`, `i18n/i18n`, `code-review`
|
||||
|
||||
### 4. **Manual Rules Index** - This file + `read_file`
|
||||
|
||||
- **What**: Additional rules not covered by the above mechanisms
|
||||
- **Why needed**: Cursor's rule system only supports "agent request" or "auto attach" modes
|
||||
- **Access**: Use `read_file` tool to read specific `.mdc` files
|
||||
@@ -47,10 +52,13 @@ Use `read_file` to access rules from the index below when:
|
||||
The following rules are available via `read_file` from the `.cursor/rules/` directory:
|
||||
|
||||
- `backend-architecture.mdc` – Backend layer architecture and design guidelines
|
||||
- `zustand-action-patterns.mdc` – Recommended patterns for organizing Zustand actions
|
||||
- `zustand-slice-organization.mdc` – Best practices for structuring Zustand slices
|
||||
- `define-database-model.mdc` – Database model definition guidelines
|
||||
- `drizzle-schema-style-guide.mdc` – Style guide for defining Drizzle ORM schemas
|
||||
- `react-component.mdc` – React component style guide and conventions
|
||||
- `testing-guide.mdc` – Comprehensive testing guide for Vitest environment
|
||||
- `typescript.mdc` – TypeScript code style guide
|
||||
- `zustand-action-patterns.mdc` – Recommended patterns for organizing Zustand actions
|
||||
- `zustand-slice-organization.mdc` – Best practices for structuring Zustand slices
|
||||
|
||||
## ❌ Common Misunderstandings to Avoid
|
||||
|
||||
@@ -62,7 +70,7 @@ The following rules are available via `read_file` from the `.cursor/rules/` dire
|
||||
|
||||
```
|
||||
1. Start with always_applied_workspace_rules (automatic)
|
||||
2. Check cursor_rules_context for auto-matched rules (automatic)
|
||||
2. Check cursor_rules_context for auto-matched rules (automatic)
|
||||
3. If you need specific guides: fetch_rules (manual)
|
||||
4. If you identify gaps: consult this index → read_file (manual)
|
||||
```
|
||||
@@ -70,7 +78,8 @@ The following rules are available via `read_file` from the `.cursor/rules/` dire
|
||||
## Example Decision Flow
|
||||
|
||||
**Scenario**: Working on a new Zustand store slice
|
||||
|
||||
1. Follow always_applied_workspace_rules ✅
|
||||
2. If store files were @ mentioned → use cursor_rules_context rules ✅
|
||||
2. If store files were @ mentioned → use cursor_rules_context rules ✅
|
||||
3. Need detailed Zustand guidance → `read_file('.cursor/rules/zustand-slice-organization.mdc')` ✅
|
||||
4. All rules apply simultaneously - no conflicts ✅
|
||||
4. All rules apply simultaneously - no conflicts ✅
|
||||
|
||||
@@ -36,6 +36,16 @@ config.overrides = [
|
||||
'mdx/code-blocks': false,
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
files: ['src/store/image/**/*', 'src/types/generation/**/*'],
|
||||
rules: {
|
||||
'@typescript-eslint/no-empty-interface': 0,
|
||||
'sort-keys-fix/sort-keys-fix': 0,
|
||||
'typescript-sort-keys/interface': 0,
|
||||
'typescript-sort-keys/string-enum': 0,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
module.exports = config;
|
||||
|
||||
@@ -43,6 +43,7 @@ test-output
|
||||
|
||||
# misc
|
||||
# add other ignore file below
|
||||
CLAUDE.md
|
||||
|
||||
# local env files
|
||||
.env*.local
|
||||
@@ -71,3 +72,7 @@ public/swe-worker*
|
||||
vertex-ai-key.json
|
||||
.pnpm-store
|
||||
./packages/lobe-ui
|
||||
|
||||
|
||||
# for local prd docs
|
||||
docs/prd
|
||||
@@ -24,6 +24,13 @@ LobeHub Desktop 是 [LobeChat](https://github.com/lobehub/lobe-chat) 的跨平
|
||||
pnpm install-isolated
|
||||
```
|
||||
|
||||
### 配置环境变量
|
||||
|
||||
复制 `.env.desktop` 到 `.env`。
|
||||
|
||||
> [!WARNING]
|
||||
> 注意提前备份好 `.env` 文件,避免丢失配置。
|
||||
|
||||
### 开发模式运行
|
||||
|
||||
```bash
|
||||
|
||||
@@ -25,6 +25,11 @@ const config = {
|
||||
artifactName: '${productName}-${version}.${ext}',
|
||||
},
|
||||
asar: true,
|
||||
asarUnpack: [
|
||||
// https://github.com/electron-userland/electron-builder/issues/9001#issuecomment-2778802044
|
||||
'**/node_modules/sharp/**/*',
|
||||
'**/node_modules/@img/**/*',
|
||||
],
|
||||
detectUpdateChannel: true,
|
||||
directories: {
|
||||
buildResources: 'build',
|
||||
|
||||
@@ -14,12 +14,13 @@
|
||||
"build-local": "npm run build && electron-builder --dir --config electron-builder.js --c.mac.notarize=false -c.mac.identity=null --c.asar=false",
|
||||
"build:linux": "npm run build && electron-builder --linux --config electron-builder.js --publish never",
|
||||
"build:mac": "npm run build && electron-builder --mac --config electron-builder.js --publish never",
|
||||
"build:mac:local": "npm run build && UPDATE_CHANNEL=nightly electron-builder --mac --config electron-builder.js --publish never",
|
||||
"build:win": "npm run build && electron-builder --win --config electron-builder.js --publish never",
|
||||
"electron:dev": "electron-vite dev",
|
||||
"electron:run-unpack": "electron .",
|
||||
"format": "prettier --write ",
|
||||
"i18n": "bun run scripts/i18nWorkflow/index.ts && lobe-i18n",
|
||||
"postinstall": "electron-builder install-app-deps",
|
||||
"postinstall": "electron-builder install-app-deps && pnpm rebuild sharp",
|
||||
"install-isolated": "pnpm install",
|
||||
"lint": "eslint --cache ",
|
||||
"pg-server": "bun run scripts/pglite-server.ts",
|
||||
|
||||
@@ -27,3 +27,6 @@ export const LOCAL_DATABASE_DIR = 'lobehub-local-db';
|
||||
export const FILE_STORAGE_DIR = 'file-storage';
|
||||
// Plugin 安装目录
|
||||
export const INSTALL_PLUGINS_DIR = 'plugins';
|
||||
|
||||
// Desktop file service
|
||||
export const LOCAL_STORAGE_URL_PREFIX = '/lobe-desktop-file';
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
import { UploadFileParams } from '@lobechat/electron-client-ipc';
|
||||
import { CreateFileParams } from '@lobechat/electron-server-ipc';
|
||||
|
||||
import FileService from '@/services/fileSrv';
|
||||
|
||||
import { ControllerModule, ipcClientEvent, ipcServerEvent } from './index';
|
||||
|
||||
interface UploadFileParams {
|
||||
content: ArrayBuffer;
|
||||
filename: string;
|
||||
hash: string;
|
||||
path: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export default class UploadFileCtr extends ControllerModule {
|
||||
private get fileService() {
|
||||
return this.app.getService(FileService);
|
||||
@@ -27,8 +22,18 @@ export default class UploadFileCtr extends ControllerModule {
|
||||
return this.fileService.getFilePath(id);
|
||||
}
|
||||
|
||||
@ipcServerEvent('getFileHTTPURL')
|
||||
async getFileHTTPURL(path: string) {
|
||||
return this.fileService.getFileHTTPURL(path);
|
||||
}
|
||||
|
||||
@ipcServerEvent('deleteFiles')
|
||||
async deleteFiles(paths: string[]) {
|
||||
return this.fileService.deleteFiles(paths);
|
||||
}
|
||||
|
||||
@ipcServerEvent('createFile')
|
||||
async createFile(params: CreateFileParams) {
|
||||
return this.fileService.uploadFile(params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import { buildDir, nextStandaloneDir } from '@/const/dir';
|
||||
import { isDev } from '@/const/env';
|
||||
import { IControlModule } from '@/controllers';
|
||||
import { IServiceModule } from '@/services';
|
||||
import FileService from '@/services/fileSrv';
|
||||
import { IpcClientEventSender } from '@/types/ipcClientEvent';
|
||||
import { createLogger } from '@/utils/logger';
|
||||
import { CustomRequestHandler, createHandler } from '@/utils/next-electron-rsc';
|
||||
@@ -18,6 +19,7 @@ import { I18nManager } from './I18nManager';
|
||||
import { IoCContainer } from './IoCContainer';
|
||||
import MenuManager from './MenuManager';
|
||||
import { ShortcutManager } from './ShortcutManager';
|
||||
import { StaticFileServerManager } from './StaticFileServerManager';
|
||||
import { StoreManager } from './StoreManager';
|
||||
import TrayManager from './TrayManager';
|
||||
import { UpdaterManager } from './UpdaterManager';
|
||||
@@ -41,6 +43,7 @@ export class App {
|
||||
updaterManager: UpdaterManager;
|
||||
shortcutManager: ShortcutManager;
|
||||
trayManager: TrayManager;
|
||||
staticFileServerManager: StaticFileServerManager;
|
||||
chromeFlags: string[] = ['OverlayScrollbar', 'FluentOverlayScrollbar', 'FluentScrollbar'];
|
||||
|
||||
/**
|
||||
@@ -97,6 +100,7 @@ export class App {
|
||||
this.updaterManager = new UpdaterManager(this);
|
||||
this.shortcutManager = new ShortcutManager(this);
|
||||
this.trayManager = new TrayManager(this);
|
||||
this.staticFileServerManager = new StaticFileServerManager(this);
|
||||
|
||||
// register the schema to interceptor url
|
||||
// it should register before app ready
|
||||
@@ -130,6 +134,9 @@ export class App {
|
||||
await this.i18n.init();
|
||||
this.menuManager.initialize();
|
||||
|
||||
// Initialize static file manager
|
||||
await this.staticFileServerManager.initialize();
|
||||
|
||||
// Initialize global shortcuts: globalShortcut must be called after app.whenReady()
|
||||
this.shortcutManager.initialize();
|
||||
|
||||
@@ -399,6 +406,7 @@ export class App {
|
||||
}
|
||||
|
||||
// 执行清理操作
|
||||
this.staticFileServerManager.destroy();
|
||||
this.unregisterAllRequestHandlers();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
import { getPort } from 'get-port-please';
|
||||
import { createServer } from 'node:http';
|
||||
|
||||
import { LOCAL_STORAGE_URL_PREFIX } from '@/const/dir';
|
||||
import FileService from '@/services/fileSrv';
|
||||
import { createLogger } from '@/utils/logger';
|
||||
|
||||
import type { App } from './App';
|
||||
|
||||
const logger = createLogger('core:StaticFileServerManager');
|
||||
|
||||
export class StaticFileServerManager {
|
||||
private app: App;
|
||||
private fileService: FileService;
|
||||
private httpServer: any = null;
|
||||
private serverPort: number = 0;
|
||||
private isInitialized = false;
|
||||
|
||||
constructor(app: App) {
|
||||
this.app = app;
|
||||
this.fileService = app.getService(FileService);
|
||||
logger.debug('StaticFileServerManager initialized');
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化静态文件管理器
|
||||
*/
|
||||
async initialize(): Promise<void> {
|
||||
if (this.isInitialized) {
|
||||
logger.warn('StaticFileServerManager already initialized');
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info('Initializing StaticFileServerManager');
|
||||
|
||||
try {
|
||||
// 启动 HTTP 文件服务器
|
||||
await this.startHttpServer();
|
||||
|
||||
this.isInitialized = true;
|
||||
logger.info(
|
||||
`StaticFileServerManager initialization completed, server running on port ${this.serverPort}`,
|
||||
);
|
||||
} catch (error) {
|
||||
logger.error('Failed to initialize StaticFileServerManager:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动 HTTP 文件服务器
|
||||
*/
|
||||
private async startHttpServer(): Promise<void> {
|
||||
try {
|
||||
// 使用 get-port-please 获取可用端口
|
||||
this.serverPort = await getPort({
|
||||
port: 33250, // 首选端口
|
||||
ports: [33251, 33252, 33253, 33254, 33255], // 备用端口
|
||||
host: '127.0.0.1',
|
||||
});
|
||||
|
||||
logger.debug(`Found available port: ${this.serverPort}`);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const server = createServer(async (req, res) => {
|
||||
// 设置请求超时
|
||||
req.setTimeout(30000, () => {
|
||||
logger.warn('Request timeout, closing connection');
|
||||
if (!res.destroyed && !res.headersSent) {
|
||||
res.writeHead(408, { 'Content-Type': 'text/plain' });
|
||||
res.end('Request Timeout');
|
||||
}
|
||||
});
|
||||
|
||||
// 监听客户端断开连接
|
||||
req.on('close', () => {
|
||||
logger.debug('Client disconnected during request processing');
|
||||
});
|
||||
|
||||
try {
|
||||
await this.handleHttpRequest(req, res);
|
||||
} catch (error) {
|
||||
logger.error('Unhandled error in HTTP request handler:', error);
|
||||
|
||||
// 尝试发送错误响应,但确保不会导致进一步错误
|
||||
try {
|
||||
if (!res.destroyed && !res.headersSent) {
|
||||
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
||||
res.end('Internal Server Error');
|
||||
}
|
||||
} catch (responseError) {
|
||||
logger.error('Failed to send error response:', responseError);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 监听指定端口
|
||||
server.listen(this.serverPort, '127.0.0.1', () => {
|
||||
this.httpServer = server;
|
||||
logger.info(`HTTP file server started on port ${this.serverPort}`);
|
||||
resolve();
|
||||
});
|
||||
|
||||
server.on('error', (error) => {
|
||||
logger.error('HTTP server error:', error);
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Failed to get available port:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 HTTP 请求
|
||||
*/
|
||||
private async handleHttpRequest(req: any, res: any): Promise<void> {
|
||||
try {
|
||||
// 检查响应是否已经结束
|
||||
if (res.destroyed || res.headersSent) {
|
||||
logger.warn('Response already ended, skipping request processing');
|
||||
return;
|
||||
}
|
||||
|
||||
const url = new URL(req.url, `http://127.0.0.1:${this.serverPort}`);
|
||||
logger.debug(`Processing HTTP file request: ${req.url}`);
|
||||
|
||||
// 提取文件路径:从 /desktop-file/path/to/file.png 中提取相对路径
|
||||
let filePath = decodeURIComponent(url.pathname.slice(1)); // 移除开头的 /
|
||||
|
||||
// 如果路径以 desktop-file/ 开头,则移除该前缀
|
||||
const prefixWithoutSlash = LOCAL_STORAGE_URL_PREFIX.slice(1) + '/'; // 移除开头的 / 并添加结尾的 /
|
||||
if (filePath.startsWith(prefixWithoutSlash)) {
|
||||
filePath = filePath.slice(prefixWithoutSlash.length);
|
||||
}
|
||||
|
||||
if (!filePath) {
|
||||
logger.warn(`Empty file path in HTTP request: ${req.url}`);
|
||||
if (!res.headersSent) {
|
||||
res.writeHead(400, { 'Content-Type': 'text/plain' });
|
||||
res.end('Bad Request: Empty file path');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用 FileService 获取文件
|
||||
const fileResult = await this.fileService.getFile(`desktop://${filePath}`);
|
||||
|
||||
// 再次检查响应状态
|
||||
if (res.destroyed || res.headersSent) {
|
||||
logger.warn('Response ended during file processing');
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置响应头
|
||||
res.writeHead(200, {
|
||||
'Content-Type': fileResult.mimeType,
|
||||
'Cache-Control': 'public, max-age=31536000', // 缓存一年
|
||||
'Access-Control-Allow-Origin': 'http://localhost:*', // 允许 localhost 的任意端口
|
||||
'Content-Length': Buffer.byteLength(fileResult.content),
|
||||
});
|
||||
|
||||
// 发送文件内容
|
||||
res.end(Buffer.from(fileResult.content));
|
||||
|
||||
logger.debug(`HTTP file served successfully: desktop://${filePath}`);
|
||||
} catch (error) {
|
||||
logger.error(`Error serving HTTP file: ${error}`);
|
||||
|
||||
// 检查响应是否仍然可写
|
||||
if (!res.destroyed && !res.headersSent) {
|
||||
try {
|
||||
// 判断是否是文件未找到错误
|
||||
if (error.name === 'FileNotFoundError') {
|
||||
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
||||
res.end('File Not Found');
|
||||
} else {
|
||||
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
||||
res.end('Internal Server Error');
|
||||
}
|
||||
} catch (writeError) {
|
||||
logger.error('Failed to write error response:', writeError);
|
||||
}
|
||||
} else {
|
||||
logger.warn('Cannot write error response: connection already closed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件服务器域名
|
||||
*/
|
||||
getFileServerDomain(): string {
|
||||
if (!this.isInitialized || !this.serverPort) {
|
||||
throw new Error('StaticFileServerManager not initialized or server not started');
|
||||
}
|
||||
|
||||
const serverDomain = `http://127.0.0.1:${this.serverPort}`;
|
||||
return serverDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁静态文件管理器
|
||||
*/
|
||||
destroy() {
|
||||
logger.info('Destroying StaticFileServerManager');
|
||||
|
||||
if (this.httpServer) {
|
||||
logger.debug('Closing HTTP file server');
|
||||
this.httpServer.close(() => {
|
||||
logger.debug('HTTP file server closed');
|
||||
});
|
||||
this.httpServer = null;
|
||||
this.serverPort = 0;
|
||||
}
|
||||
|
||||
this.isInitialized = false;
|
||||
logger.info('StaticFileServerManager destroyed');
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,28 @@
|
||||
import { DeleteFilesResponse } from '@lobechat/electron-server-ipc';
|
||||
import * as fs from 'node:fs';
|
||||
import { writeFile } from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
import path, { join } from 'node:path';
|
||||
import { promisify } from 'node:util';
|
||||
|
||||
import { FILE_STORAGE_DIR } from '@/const/dir';
|
||||
import { FILE_STORAGE_DIR, LOCAL_STORAGE_URL_PREFIX } from '@/const/dir';
|
||||
import { makeSureDirExist } from '@/utils/file-system';
|
||||
import { createLogger } from '@/utils/logger';
|
||||
|
||||
import { ServiceModule } from './index';
|
||||
|
||||
/**
|
||||
* 文件未找到错误类
|
||||
*/
|
||||
export class FileNotFoundError extends Error {
|
||||
constructor(
|
||||
message: string,
|
||||
public path: string,
|
||||
) {
|
||||
super(message);
|
||||
this.name = 'FileNotFoundError';
|
||||
}
|
||||
}
|
||||
|
||||
const readFilePromise = promisify(fs.readFile);
|
||||
const unlinkPromise = promisify(fs.unlink);
|
||||
|
||||
@@ -17,7 +30,7 @@ const unlinkPromise = promisify(fs.unlink);
|
||||
const logger = createLogger('services:FileService');
|
||||
|
||||
interface UploadFileParams {
|
||||
content: ArrayBuffer;
|
||||
content: ArrayBuffer | string; // ArrayBuffer from browser or Base64 string from server
|
||||
filename: string;
|
||||
hash: string;
|
||||
path: string;
|
||||
@@ -32,17 +45,16 @@ interface FileMetadata {
|
||||
}
|
||||
|
||||
export default class FileService extends ServiceModule {
|
||||
/**
|
||||
* 获取旧版上传目录路径
|
||||
* @deprecated 仅用于向后兼容旧版文件访问,新文件应存储在 FILE_STORAGE_DIR 的自定义路径下
|
||||
*/
|
||||
get UPLOADS_DIR() {
|
||||
return join(this.app.appStoragePath, FILE_STORAGE_DIR, 'uploads');
|
||||
}
|
||||
|
||||
constructor(app) {
|
||||
super(app);
|
||||
|
||||
// Initialize file storage directory
|
||||
logger.info('Initializing file storage directory');
|
||||
makeSureDirExist(this.UPLOADS_DIR);
|
||||
logger.debug(`Upload directory created: ${this.UPLOADS_DIR}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,31 +64,44 @@ export default class FileService extends ServiceModule {
|
||||
content,
|
||||
filename,
|
||||
hash,
|
||||
path: filePath,
|
||||
type,
|
||||
}: UploadFileParams): Promise<{ metadata: FileMetadata; success: boolean }> {
|
||||
logger.info(`Starting to upload file: ${filename}, hash: ${hash}`);
|
||||
logger.info(`Starting to upload file: ${filename}, hash: ${hash}, path: ${filePath}`);
|
||||
try {
|
||||
// 创建时间戳目录
|
||||
const date = (Date.now() / 1000 / 60 / 60).toFixed(0);
|
||||
const dirname = join(this.UPLOADS_DIR, date);
|
||||
logger.debug(`Creating timestamp directory: ${dirname}`);
|
||||
makeSureDirExist(dirname);
|
||||
// 获取当前时间戳,避免重复调用 Date.now()
|
||||
const now = Date.now();
|
||||
const date = (now / 1000 / 60 / 60).toFixed(0);
|
||||
|
||||
// 生成文件保存路径
|
||||
const fileExt = filename.split('.').pop() || '';
|
||||
const savedFilename = `${hash}${fileExt ? `.${fileExt}` : ''}`;
|
||||
const savedPath = join(dirname, savedFilename);
|
||||
logger.debug(`Generated file save path: ${savedPath}`);
|
||||
// 使用传入的 filePath 作为文件的存储路径
|
||||
const fullStoragePath = join(this.app.appStoragePath, FILE_STORAGE_DIR, filePath);
|
||||
logger.debug(`Target file storage path: ${fullStoragePath}`);
|
||||
|
||||
// 写入文件内容
|
||||
const buffer = Buffer.from(content);
|
||||
logger.debug(`Writing file content, size: ${buffer.length} bytes`);
|
||||
// 确保目标目录存在
|
||||
const targetDir = path.dirname(fullStoragePath);
|
||||
logger.debug(`Ensuring target directory exists: ${targetDir}`);
|
||||
makeSureDirExist(targetDir);
|
||||
|
||||
const savedPath = fullStoragePath;
|
||||
logger.debug(`Final file save path: ${savedPath}`);
|
||||
|
||||
// 根据 content 类型创建 Buffer
|
||||
let buffer: Buffer;
|
||||
if (typeof content === 'string') {
|
||||
// 来自服务端的 Base64 字符串
|
||||
buffer = Buffer.from(content, 'base64');
|
||||
logger.debug(`Creating buffer from Base64 string, size: ${buffer.length} bytes`);
|
||||
} else {
|
||||
// 来自浏览器端的 ArrayBuffer
|
||||
buffer = Buffer.from(content);
|
||||
logger.debug(`Creating buffer from ArrayBuffer, size: ${buffer.length} bytes`);
|
||||
}
|
||||
await writeFile(savedPath, buffer);
|
||||
|
||||
// 写入元数据文件
|
||||
const metaFilePath = `${savedPath}.meta`;
|
||||
const metadata = {
|
||||
createdAt: Date.now(),
|
||||
createdAt: now, // 使用统一的时间戳
|
||||
filename,
|
||||
hash,
|
||||
size: buffer.length,
|
||||
@@ -86,13 +111,18 @@ export default class FileService extends ServiceModule {
|
||||
await writeFile(metaFilePath, JSON.stringify(metadata, null, 2));
|
||||
|
||||
// 返回与S3兼容的元数据格式
|
||||
const desktopPath = `desktop://${date}/${savedFilename}`;
|
||||
const desktopPath = `desktop://${filePath}`;
|
||||
logger.info(`File upload successful: ${desktopPath}`);
|
||||
|
||||
// 从路径中提取文件名和目录信息
|
||||
const parsedPath = path.parse(filePath);
|
||||
const dirname = parsedPath.dir || '';
|
||||
const savedFilename = parsedPath.base;
|
||||
|
||||
return {
|
||||
metadata: {
|
||||
date,
|
||||
dirname: date,
|
||||
date, // 保持时间戳格式,用于兼容性和时间追踪
|
||||
dirname,
|
||||
filename: savedFilename,
|
||||
path: desktopPath,
|
||||
},
|
||||
@@ -104,6 +134,24 @@ export default class FileService extends ServiceModule {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断路径是否为旧版格式(时间戳目录)
|
||||
*
|
||||
* 旧版路径格式: {timestamp}/{hash}.{ext} (例如: 1234567890/abc123.png)
|
||||
* 新版路径格式: 任意自定义路径 (例如: user_uploads/images/photo.png, ai_generations/image.jpg)
|
||||
*
|
||||
* @param path - 相对路径,不包含 desktop:// 前缀
|
||||
* @returns true 如果是旧版格式,false 如果是新版格式
|
||||
*/
|
||||
private isLegacyPath(path: string): boolean {
|
||||
const parts = path.split('/');
|
||||
if (parts.length < 2) return false;
|
||||
|
||||
// 如果第一部分是纯数字(时间戳),则认为是旧版格式
|
||||
// 时间戳格式:精确到小时的 Unix 时间戳,通常是 10 位数字
|
||||
return /^\d+$/.test(parts[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件内容
|
||||
*/
|
||||
@@ -123,13 +171,49 @@ export default class FileService extends ServiceModule {
|
||||
|
||||
// 解析路径
|
||||
const relativePath = normalizedPath.replace('desktop://', '');
|
||||
const filePath = join(this.UPLOADS_DIR, relativePath);
|
||||
logger.debug(`Reading file from path: ${filePath}`);
|
||||
|
||||
// 读取文件内容
|
||||
// 智能路由:根据路径格式决定从哪个目录读取文件
|
||||
let filePath: string;
|
||||
let isLegacyAttempt = false;
|
||||
|
||||
if (this.isLegacyPath(relativePath)) {
|
||||
// 旧版路径:从 uploads 目录读取(向后兼容)
|
||||
filePath = join(this.UPLOADS_DIR, relativePath);
|
||||
isLegacyAttempt = true;
|
||||
logger.debug(`Legacy path detected, reading from uploads directory: ${filePath}`);
|
||||
} else {
|
||||
// 新版路径:从 FILE_STORAGE_DIR 根目录读取
|
||||
filePath = join(this.app.appStoragePath, FILE_STORAGE_DIR, relativePath);
|
||||
logger.debug(`New path format, reading from storage root: ${filePath}`);
|
||||
}
|
||||
|
||||
// 读取文件内容,如果第一次尝试失败且是 legacy 路径,则尝试新路径
|
||||
logger.debug(`Starting to read file content`);
|
||||
const content = await readFilePromise(filePath);
|
||||
logger.debug(`File content read complete, size: ${content.length} bytes`);
|
||||
let content: Buffer;
|
||||
try {
|
||||
content = await readFilePromise(filePath);
|
||||
logger.debug(`File content read complete, size: ${content.length} bytes`);
|
||||
} catch (firstError) {
|
||||
if (isLegacyAttempt) {
|
||||
// 如果是 legacy 路径读取失败,尝试从新路径读取
|
||||
const fallbackPath = join(this.app.appStoragePath, FILE_STORAGE_DIR, relativePath);
|
||||
logger.debug(
|
||||
`Legacy path read failed, attempting fallback to storage root: ${fallbackPath}`,
|
||||
);
|
||||
try {
|
||||
content = await readFilePromise(fallbackPath);
|
||||
filePath = fallbackPath; // 更新 filePath 用于后续的元数据读取
|
||||
logger.debug(`Fallback read successful, size: ${content.length} bytes`);
|
||||
} catch (fallbackError) {
|
||||
logger.error(
|
||||
`Both legacy and fallback paths failed. Legacy error: ${(firstError as Error).message}, Fallback error: ${(fallbackError as Error).message}`,
|
||||
);
|
||||
throw firstError; // 抛出原始错误
|
||||
}
|
||||
} else {
|
||||
throw firstError;
|
||||
}
|
||||
}
|
||||
|
||||
// 读取元数据获取MIME类型
|
||||
const metaFilePath = `${filePath}.meta`;
|
||||
@@ -142,7 +226,9 @@ export default class FileService extends ServiceModule {
|
||||
mimeType = metadata.type || mimeType;
|
||||
logger.debug(`Got MIME type from metadata: ${mimeType}`);
|
||||
} catch (metaError) {
|
||||
logger.warn(`Failed to read metadata file: ${(metaError as Error).message}, using default MIME type`);
|
||||
logger.warn(
|
||||
`Failed to read metadata file: ${(metaError as Error).message}, using default MIME type`,
|
||||
);
|
||||
// 如果元数据文件不存在,尝试从文件扩展名猜测MIME类型
|
||||
const ext = path.split('.').pop()?.toLowerCase();
|
||||
if (ext) {
|
||||
@@ -184,6 +270,12 @@ export default class FileService extends ServiceModule {
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error(`File retrieval failed:`, error);
|
||||
|
||||
// 如果是文件不存在错误,抛出自定义的 FileNotFoundError
|
||||
if (error instanceof Error && error.message.includes('ENOENT')) {
|
||||
throw new FileNotFoundError(`File not found: ${path}`, path);
|
||||
}
|
||||
|
||||
throw new Error(`File retrieval failed: ${(error as Error).message}`);
|
||||
}
|
||||
}
|
||||
@@ -200,15 +292,53 @@ export default class FileService extends ServiceModule {
|
||||
throw new Error(`Invalid desktop file path: ${path}`);
|
||||
}
|
||||
|
||||
// 解析路径
|
||||
const relativePath = path.replace('desktop://', '');
|
||||
const filePath = join(this.UPLOADS_DIR, relativePath);
|
||||
logger.debug(`File deletion path: ${filePath}`);
|
||||
// 标准化路径格式
|
||||
const normalizedPath = path.replace(/^desktop:\/+/, 'desktop://');
|
||||
|
||||
// 删除文件及其元数据
|
||||
// 解析路径
|
||||
const relativePath = normalizedPath.replace('desktop://', '');
|
||||
|
||||
// 智能路由:根据路径格式决定从哪个目录删除文件
|
||||
let filePath: string;
|
||||
let isLegacyAttempt = false;
|
||||
|
||||
if (this.isLegacyPath(relativePath)) {
|
||||
// 旧版路径:从 uploads 目录删除(向后兼容)
|
||||
filePath = join(this.UPLOADS_DIR, relativePath);
|
||||
isLegacyAttempt = true;
|
||||
logger.debug(`Legacy path detected, deleting from uploads directory: ${filePath}`);
|
||||
} else {
|
||||
// 新版路径:从 FILE_STORAGE_DIR 根目录删除
|
||||
filePath = join(this.app.appStoragePath, FILE_STORAGE_DIR, relativePath);
|
||||
logger.debug(`New path format, deleting from storage root: ${filePath}`);
|
||||
}
|
||||
|
||||
// 删除文件及其元数据,如果第一次尝试失败且是 legacy 路径,则尝试新路径
|
||||
logger.debug(`Starting file deletion`);
|
||||
await unlinkPromise(filePath);
|
||||
logger.debug(`File deletion successful`);
|
||||
try {
|
||||
await unlinkPromise(filePath);
|
||||
logger.debug(`File deletion successful`);
|
||||
} catch (firstError) {
|
||||
if (isLegacyAttempt) {
|
||||
// 如果是 legacy 路径删除失败,尝试从新路径删除
|
||||
const fallbackPath = join(this.app.appStoragePath, FILE_STORAGE_DIR, relativePath);
|
||||
logger.debug(
|
||||
`Legacy path deletion failed, attempting fallback to storage root: ${fallbackPath}`,
|
||||
);
|
||||
try {
|
||||
await unlinkPromise(fallbackPath);
|
||||
filePath = fallbackPath; // 更新 filePath 用于后续的元数据删除
|
||||
logger.debug(`Fallback deletion successful`);
|
||||
} catch (fallbackError) {
|
||||
logger.error(
|
||||
`Both legacy and fallback deletion failed. Legacy error: ${(firstError as Error).message}, Fallback error: ${(fallbackError as Error).message}`,
|
||||
);
|
||||
throw firstError; // 抛出原始错误
|
||||
}
|
||||
} else {
|
||||
throw firstError;
|
||||
}
|
||||
}
|
||||
|
||||
// 尝试删除元数据文件,但不强制要求存在
|
||||
try {
|
||||
@@ -270,7 +400,9 @@ export default class FileService extends ServiceModule {
|
||||
});
|
||||
|
||||
const success = errors.length === 0;
|
||||
logger.info(`Batch deletion operation complete, success: ${success}, error count: ${errors.length}`);
|
||||
logger.info(
|
||||
`Batch deletion operation complete, success: ${success}, error count: ${errors.length}`,
|
||||
);
|
||||
return {
|
||||
success,
|
||||
...(errors.length > 0 && { errors }),
|
||||
@@ -285,10 +417,65 @@ export default class FileService extends ServiceModule {
|
||||
throw new Error(`Invalid desktop file path: ${path}`);
|
||||
}
|
||||
|
||||
// 标准化路径格式
|
||||
const normalizedPath = path.replace(/^desktop:\/+/, 'desktop://');
|
||||
|
||||
// 解析路径
|
||||
const relativePath = path.replace('desktop://', '');
|
||||
const fullPath = join(this.UPLOADS_DIR, relativePath);
|
||||
logger.debug(`Resolved filesystem path: ${fullPath}`);
|
||||
const relativePath = normalizedPath.replace('desktop://', '');
|
||||
|
||||
// 智能路由:根据路径格式决定从哪个目录获取文件路径
|
||||
let fullPath: string;
|
||||
if (this.isLegacyPath(relativePath)) {
|
||||
// 旧版路径:从 uploads 目录获取(向后兼容)
|
||||
fullPath = join(this.UPLOADS_DIR, relativePath);
|
||||
logger.debug(`Legacy path detected, resolved to uploads directory: ${fullPath}`);
|
||||
|
||||
// 检查文件是否存在,如果不存在则尝试新路径
|
||||
try {
|
||||
await fs.promises.access(fullPath, fs.constants.F_OK);
|
||||
logger.debug(`Legacy path file exists: ${fullPath}`);
|
||||
} catch {
|
||||
// 如果 legacy 路径文件不存在,尝试新路径
|
||||
const fallbackPath = join(this.app.appStoragePath, FILE_STORAGE_DIR, relativePath);
|
||||
logger.debug(`Legacy path file not found, trying fallback path: ${fallbackPath}`);
|
||||
try {
|
||||
await fs.promises.access(fallbackPath, fs.constants.F_OK);
|
||||
fullPath = fallbackPath;
|
||||
logger.debug(`Fallback path file exists: ${fullPath}`);
|
||||
} catch {
|
||||
// 两个路径都不存在,返回原始的 legacy 路径(保持原有行为)
|
||||
logger.debug(
|
||||
`Neither legacy nor fallback path exists, returning legacy path: ${fullPath}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 新版路径:从 FILE_STORAGE_DIR 根目录获取
|
||||
fullPath = join(this.app.appStoragePath, FILE_STORAGE_DIR, relativePath);
|
||||
logger.debug(`New path format, resolved to storage root: ${fullPath}`);
|
||||
}
|
||||
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
async getFileHTTPURL(path: string): Promise<string> {
|
||||
logger.debug(`Getting file HTTP URL: ${path}`);
|
||||
// 处理desktop://路径
|
||||
if (!path.startsWith('desktop://')) {
|
||||
logger.error(`Invalid desktop file path: ${path}`);
|
||||
throw new Error(`Invalid desktop file path: ${path}`);
|
||||
}
|
||||
|
||||
// 标准化路径格式
|
||||
const normalizedPath = path.replace(/^desktop:\/+/, 'desktop://');
|
||||
|
||||
// 解析路径:从 desktop://path/to/file.png 中提取 path/to/file.png
|
||||
const relativePath = normalizedPath.replace('desktop://', '');
|
||||
|
||||
// 使用 StaticFileServerManager 获取文件服务器域名,然后构建完整 URL
|
||||
const serverDomain = this.app.staticFileServerManager.getFileServerDomain();
|
||||
const httpURL = `${serverDomain}${LOCAL_STORAGE_URL_PREFIX}/${relativePath}`;
|
||||
logger.debug(`Generated HTTP URL: ${httpURL}`);
|
||||
return httpURL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// copy from https://github.com/kirill-konshin/next-electron-rsc
|
||||
import { serialize as serializeCookie } from 'cookie';
|
||||
import type { Protocol, Session } from 'electron';
|
||||
import { type Protocol, type Session, protocol } from 'electron';
|
||||
import type { NextConfig } from 'next';
|
||||
import type NextNodeServer from 'next/dist/server/next-server';
|
||||
import assert from 'node:assert';
|
||||
@@ -11,6 +11,7 @@ import { parse } from 'node:url';
|
||||
import resolve from 'resolve';
|
||||
import { parse as parseCookie, splitCookiesString } from 'set-cookie-parser';
|
||||
|
||||
import { LOCAL_STORAGE_URL_PREFIX } from '@/const/dir';
|
||||
import { isDev } from '@/const/env';
|
||||
import { createLogger } from '@/utils/logger';
|
||||
|
||||
@@ -178,7 +179,9 @@ export function createHandler({
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let registerProtocolHandle = false;
|
||||
let interceptorCount = 0; // 追踪活跃的拦截器数量
|
||||
|
||||
protocol.registerSchemesAsPrivileged([
|
||||
{
|
||||
@@ -224,6 +227,14 @@ export function createHandler({
|
||||
socket: Socket,
|
||||
): Promise<Response> => {
|
||||
try {
|
||||
// 检查是否是本地文件服务请求,如果是则跳过处理
|
||||
const url = new URL(request.url);
|
||||
if (url.pathname.startsWith(LOCAL_STORAGE_URL_PREFIX + '/')) {
|
||||
if (debug) logger.debug(`Skipping local file service request: ${request.url}`);
|
||||
// 直接使用 fetch 转发请求到本地文件服务
|
||||
return fetch(request);
|
||||
}
|
||||
|
||||
// 先尝试使用自定义处理器处理请求
|
||||
for (const customHandler of customHandlers) {
|
||||
try {
|
||||
@@ -354,19 +365,32 @@ export function createHandler({
|
||||
);
|
||||
|
||||
const socket = new Socket();
|
||||
interceptorCount++; // 增加拦截器计数
|
||||
|
||||
const closeSocket = () => socket.end();
|
||||
|
||||
process.on('SIGTERM', () => closeSocket);
|
||||
process.on('SIGINT', () => closeSocket);
|
||||
|
||||
if (!isDev && !registerProtocolHandle) {
|
||||
if (!registerProtocolHandle) {
|
||||
logger.debug(
|
||||
`Registering HTTP protocol handler in ${isDev ? 'development' : 'production'} mode`,
|
||||
);
|
||||
protocol.handle('http', async (request) => {
|
||||
if (!isDev) {
|
||||
assert(request.url.startsWith(localhostUrl), 'External HTTP not supported, use HTTPS');
|
||||
// 检查是否是本地文件服务请求,如果是则允许通过
|
||||
const isLocalhost = request.url.startsWith(localhostUrl);
|
||||
|
||||
const url = new URL(request.url);
|
||||
const isLocalIP =
|
||||
request.url.startsWith('http://127.0.0.1:') ||
|
||||
request.url.startsWith('http://localhost:');
|
||||
const isLocalFileService = url.pathname.startsWith(LOCAL_STORAGE_URL_PREFIX + '/');
|
||||
|
||||
const valid = isLocalhost || (isLocalIP && isLocalFileService);
|
||||
if (!valid) {
|
||||
throw new Error('External HTTP not supported, use HTTPS');
|
||||
}
|
||||
}
|
||||
|
||||
return handleRequest(request, session, socket);
|
||||
@@ -374,12 +398,19 @@ export function createHandler({
|
||||
registerProtocolHandle = true;
|
||||
}
|
||||
|
||||
logger.debug(`Active interceptors count: ${interceptorCount}`);
|
||||
|
||||
return function stopIntercept() {
|
||||
if (registerProtocolHandle) {
|
||||
logger.debug('Unregistering HTTP protocol handler');
|
||||
interceptorCount--; // 减少拦截器计数
|
||||
logger.debug(`Stopping interceptor, remaining count: ${interceptorCount}`);
|
||||
|
||||
// 只有当没有活跃的拦截器时才取消注册协议处理器
|
||||
if (registerProtocolHandle && interceptorCount === 0) {
|
||||
logger.debug('Unregistering HTTP protocol handler (no active interceptors)');
|
||||
protocol.unhandle('http');
|
||||
registerProtocolHandle = false;
|
||||
}
|
||||
|
||||
process.off('SIGTERM', () => closeSocket);
|
||||
process.off('SIGINT', () => closeSocket);
|
||||
closeSocket();
|
||||
|
||||
@@ -163,6 +163,7 @@ table files {
|
||||
name text [not null]
|
||||
size integer [not null]
|
||||
url text [not null]
|
||||
source text
|
||||
client_id text
|
||||
metadata jsonb
|
||||
chunk_task_id uuid
|
||||
@@ -218,6 +219,45 @@ table knowledge_bases {
|
||||
}
|
||||
}
|
||||
|
||||
table generation_batches {
|
||||
id text [pk, not null]
|
||||
user_id text [not null]
|
||||
generation_topic_id text [not null]
|
||||
provider text [not null]
|
||||
model text [not null]
|
||||
prompt text [not null]
|
||||
width integer
|
||||
height integer
|
||||
ratio varchar(64)
|
||||
config jsonb
|
||||
accessed_at "timestamp with time zone" [not null, default: `now()`]
|
||||
created_at "timestamp with time zone" [not null, default: `now()`]
|
||||
updated_at "timestamp with time zone" [not null, default: `now()`]
|
||||
}
|
||||
|
||||
table generation_topics {
|
||||
id text [pk, not null]
|
||||
user_id text [not null]
|
||||
title text
|
||||
cover_url text
|
||||
accessed_at "timestamp with time zone" [not null, default: `now()`]
|
||||
created_at "timestamp with time zone" [not null, default: `now()`]
|
||||
updated_at "timestamp with time zone" [not null, default: `now()`]
|
||||
}
|
||||
|
||||
table generations {
|
||||
id text [pk, not null]
|
||||
user_id text [not null]
|
||||
generation_batch_id varchar(64) [not null]
|
||||
async_task_id uuid
|
||||
file_id text
|
||||
seed integer
|
||||
asset jsonb
|
||||
accessed_at "timestamp with time zone" [not null, default: `now()`]
|
||||
created_at "timestamp with time zone" [not null, default: `now()`]
|
||||
updated_at "timestamp with time zone" [not null, default: `now()`]
|
||||
}
|
||||
|
||||
table message_chunks {
|
||||
message_id text
|
||||
chunk_id uuid
|
||||
@@ -834,6 +874,10 @@ table users {
|
||||
updated_at "timestamp with time zone" [not null, default: `now()`]
|
||||
}
|
||||
|
||||
ref: agents_files.file_id > files.id
|
||||
|
||||
ref: agents_files.agent_id > agents.id
|
||||
|
||||
ref: agents_knowledge_bases.knowledge_base_id - knowledge_bases.id
|
||||
|
||||
ref: agents_knowledge_bases.agent_id > agents.id
|
||||
@@ -848,8 +892,34 @@ ref: document_chunks.document_id > documents.id
|
||||
|
||||
ref: documents.file_id > files.id
|
||||
|
||||
ref: file_chunks.file_id - files.id
|
||||
|
||||
ref: file_chunks.chunk_id - chunks.id
|
||||
|
||||
ref: generations.file_id - files.id
|
||||
|
||||
ref: files.embedding_task_id - async_tasks.id
|
||||
|
||||
ref: files_to_sessions.file_id > files.id
|
||||
|
||||
ref: files_to_sessions.session_id > sessions.id
|
||||
|
||||
ref: generation_batches.user_id - users.id
|
||||
|
||||
ref: generation_batches.generation_topic_id > generation_topics.id
|
||||
|
||||
ref: generation_topics.user_id - users.id
|
||||
|
||||
ref: generations.user_id - users.id
|
||||
|
||||
ref: generations.generation_batch_id > generation_batches.id
|
||||
|
||||
ref: generations.async_task_id - async_tasks.id
|
||||
|
||||
ref: messages_files.file_id > files.id
|
||||
|
||||
ref: messages_files.message_id > messages.id
|
||||
|
||||
ref: messages.session_id - sessions.id
|
||||
|
||||
ref: messages.parent_id - messages.id
|
||||
|
||||
@@ -324,6 +324,7 @@
|
||||
}
|
||||
},
|
||||
"tab": {
|
||||
"aiImage": "الرسم بالذكاء الاصطناعي",
|
||||
"chat": "الدردشة",
|
||||
"discover": "اكتشاف",
|
||||
"files": "ملفات",
|
||||
|
||||
@@ -68,6 +68,15 @@
|
||||
"GoBack": {
|
||||
"back": "عودة"
|
||||
},
|
||||
"ImageUpload": {
|
||||
"actions": {
|
||||
"changeImage": "انقر لتغيير الصورة"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "إضافة صورة",
|
||||
"secondary": "انقر للتحميل"
|
||||
}
|
||||
},
|
||||
"MaxTokenSlider": {
|
||||
"unlimited": "غير محدود"
|
||||
},
|
||||
@@ -91,6 +100,25 @@
|
||||
"provider": "مزود",
|
||||
"title": "نموذج"
|
||||
},
|
||||
"MultiImagesUpload": {
|
||||
"actions": {
|
||||
"uploadMore": "انقر لتحميل المزيد"
|
||||
},
|
||||
"modal": {
|
||||
"complete": "اكتمل",
|
||||
"newFileIndicator": "جديد",
|
||||
"selectImageToPreview": "يرجى اختيار صورة للمعاينة",
|
||||
"title": "إدارة الصور ({{count}})",
|
||||
"upload": "تحميل الصور"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "انقر لتحميل الصور",
|
||||
"secondary": "يدعم اختيار عدة صور"
|
||||
},
|
||||
"progress": {
|
||||
"uploadingWithCount": "تم تحميل {{completed}} من أصل {{total}}"
|
||||
}
|
||||
},
|
||||
"OllamaSetupGuide": {
|
||||
"action": {
|
||||
"close": "إغلاق الإشعار",
|
||||
|
||||
@@ -130,6 +130,7 @@
|
||||
"addProxyUrl": "إضافة عنوان وكيل OpenAI (اختياري)",
|
||||
"apiKey": {
|
||||
"description": "يمكنك بدء الجلسة عن طريق إدخال مفتاح API {{name}} الخاص بك",
|
||||
"imageGenerationDescription": "أدخل مفتاح API الخاص بـ {{name}} للبدء في التوليد",
|
||||
"title": "استخدام مفتاح API {{name}} المخصص"
|
||||
},
|
||||
"closeMessage": "إغلاق الرسالة",
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"config": {
|
||||
"aspectRatio": {
|
||||
"label": "النسبة"
|
||||
},
|
||||
"header": {
|
||||
"desc": "وصف بسيط، ابتكر فورًا",
|
||||
"title": "الرسم"
|
||||
},
|
||||
"height": {
|
||||
"label": "الارتفاع"
|
||||
},
|
||||
"imageNum": {
|
||||
"label": "عدد الصور"
|
||||
},
|
||||
"imageUrl": {
|
||||
"label": "صورة مرجعية"
|
||||
},
|
||||
"imageUrls": {
|
||||
"label": "صور مرجعية"
|
||||
},
|
||||
"model": {
|
||||
"label": "النموذج"
|
||||
},
|
||||
"prompt": {
|
||||
"placeholder": "وصف المحتوى الذي ترغب في إنشائه"
|
||||
},
|
||||
"seed": {
|
||||
"label": "البذرة",
|
||||
"random": "بذرة عشوائية"
|
||||
},
|
||||
"size": {
|
||||
"label": "الحجم"
|
||||
},
|
||||
"steps": {
|
||||
"label": "عدد الخطوات"
|
||||
},
|
||||
"title": "الرسم بالذكاء الاصطناعي",
|
||||
"width": {
|
||||
"label": "العرض"
|
||||
}
|
||||
},
|
||||
"generation": {
|
||||
"actions": {
|
||||
"applySeed": "تطبيق البذرة",
|
||||
"copyError": "نسخ رسالة الخطأ",
|
||||
"copyPrompt": "نسخ العبارة التحفيزية",
|
||||
"copySeed": "نسخ البذرة",
|
||||
"delete": "حذف",
|
||||
"deleteBatch": "حذف الدفعة",
|
||||
"download": "تنزيل",
|
||||
"downloadFailed": "فشل تنزيل الصورة",
|
||||
"errorCopied": "تم نسخ رسالة الخطأ إلى الحافظة",
|
||||
"errorCopyFailed": "فشل نسخ رسالة الخطأ",
|
||||
"generate": "إنشاء",
|
||||
"promptCopied": "تم نسخ النص التوجيهي إلى الحافظة",
|
||||
"promptCopyFailed": "فشل نسخ النص التوجيهي",
|
||||
"reuseSettings": "إعادة استخدام الإعدادات",
|
||||
"seedApplied": "تم تطبيق البذرة على الإعدادات",
|
||||
"seedApplyFailed": "فشل في تطبيق البذرة",
|
||||
"seedCopied": "تم نسخ البذرة إلى الحافظة",
|
||||
"seedCopyFailed": "فشل نسخ البذرة"
|
||||
},
|
||||
"metadata": {
|
||||
"count": "{{count}} صورة"
|
||||
},
|
||||
"status": {
|
||||
"failed": "فشل في الإنشاء",
|
||||
"generating": "جارٍ الإنشاء..."
|
||||
}
|
||||
},
|
||||
"notSupportGuide": {
|
||||
"desc": "الوحدة الحالية تعمل بنمط قاعدة بيانات العميل، ولا تدعم ميزة إنشاء الصور بالذكاء الاصطناعي. يرجى التبديل إلى <1>نمط نشر قاعدة بيانات الخادم</1>، أو استخدام <3>سحابة LobeChat</3> مباشرةً",
|
||||
"features": {
|
||||
"fileIntegration": {
|
||||
"desc": "تكامل عميق مع نظام إدارة الملفات، حيث تُحفظ الصور المُنشأة تلقائيًا في نظام الملفات، مع دعم الإدارة والتنظيم الموحد",
|
||||
"title": "تكامل نظام الملفات"
|
||||
},
|
||||
"llmAssisted": {
|
||||
"desc": "يجمع بين قدرات نماذج اللغة الكبيرة لتحسين وتوسيع النصوص التوجيهية بذكاء، مما يعزز جودة إنشاء الصور (قريبًا)",
|
||||
"title": "مساعدة نموذج اللغة الكبير"
|
||||
},
|
||||
"multiProviders": {
|
||||
"desc": "يدعم عدة مزودي خدمات رسم بالذكاء الاصطناعي، بما في ذلك OpenAI gpt-image-1، Google Imagen، FAL.ai وغيرها، لتوفير خيارات نماذج متنوعة",
|
||||
"title": "دعم مزودين متعددين"
|
||||
}
|
||||
},
|
||||
"title": "نمط النشر الحالي لا يدعم الرسم بالذكاء الاصطناعي"
|
||||
},
|
||||
"topic": {
|
||||
"createNew": "إنشاء موضوع جديد",
|
||||
"deleteConfirm": "تأكيد حذف الموضوع",
|
||||
"deleteConfirmDesc": "سيتم حذف هذا الموضوع نهائيًا ولن يمكن استعادته، يرجى توخي الحذر.",
|
||||
"empty": "لا توجد مواضيع تم إنشاؤها",
|
||||
"title": "موضوع الرسم",
|
||||
"untitled": "الموضوع الافتراضي"
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,10 @@
|
||||
"search": "بحث",
|
||||
"title": "اكتشاف"
|
||||
},
|
||||
"image": {
|
||||
"description": "{{appName}} يقدم لك أفضل تجربة استخدام لـ GPT Image و Flux و Midjourney و Stable Diffusion",
|
||||
"title": "الرسم بالذكاء الاصطناعي"
|
||||
},
|
||||
"plugins": {
|
||||
"description": "البحث، توليد الرسوم البيانية، الأكاديميات، توليد الصور، توليد الفيديو، توليد الصوت، سير العمل الآلي، خصص قدرات ToolCall الخاصة بـ ChatGPT / Claude",
|
||||
"title": "سوق الإضافات"
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
"customRegion": "منطقة خدمة مخصصة",
|
||||
"customSessionToken": "رمز الجلسة المخصص",
|
||||
"description": "أدخل معرف الوصول / مفتاح الوصول السري الخاص بك في AWS لبدء الجلسة. لن يتم تسجيل تكوين المصادقة الخاص بك من قبل التطبيق",
|
||||
"imageGenerationDescription": "أدخل AWS AccessKeyId / SecretAccessKey الخاص بك للبدء في التوليد. التطبيق لن يقوم بتسجيل إعدادات المصادقة الخاصة بك",
|
||||
"title": "استخدام معلومات المصادقة الخاصة بـ Bedrock المخصصة"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
"deepseek": {
|
||||
"description": "DeepSeek هي شركة تركز على أبحاث وتطبيقات تقنيات الذكاء الاصطناعي، حيث يجمع نموذجها الأحدث DeepSeek-V2.5 بين قدرات الحوار العامة ومعالجة الشيفرات، وقد حقق تحسينات ملحوظة في محاذاة تفضيلات البشر، ومهام الكتابة، واتباع التعليمات."
|
||||
},
|
||||
"fal": {
|
||||
"description": "منصة وسائط توليدية موجهة للمطورين"
|
||||
},
|
||||
"fireworksai": {
|
||||
"description": "Fireworks AI هي شركة رائدة في تقديم خدمات نماذج اللغة المتقدمة، تركز على استدعاء الوظائف والمعالجة متعددة الوسائط. نموذجها الأحدث Firefunction V2 مبني على Llama-3، مُحسّن لاستدعاء الوظائف، والحوار، واتباع التعليمات. يدعم نموذج اللغة البصرية FireLLaVA-13B إدخال الصور والنصوص المختلطة. تشمل النماذج البارزة الأخرى سلسلة Llama وسلسلة Mixtral، مما يوفر دعمًا فعالًا لاتباع التعليمات وتوليدها بلغات متعددة."
|
||||
},
|
||||
|
||||
@@ -484,6 +484,11 @@
|
||||
"placeholder": "أدخل كلمة الموجه المخصصة",
|
||||
"title": "كلمة الموجه المخصصة"
|
||||
},
|
||||
"generationTopic": {
|
||||
"label": "نموذج تسمية موضوع الرسم بالذكاء الاصطناعي",
|
||||
"modelDesc": "نموذج مخصص لتسمية موضوعات الرسم بالذكاء الاصطناعي تلقائيًا",
|
||||
"title": "تسمية موضوعات الرسم بالذكاء الاصطناعي تلقائيًا"
|
||||
},
|
||||
"helpInfo": "عند إنشاء مساعد جديد، سيتم استخدام إعدادات المساعد الافتراضية كقيم افتراضية.",
|
||||
"historyCompress": {
|
||||
"label": "نموذج تاريخ المحادثة",
|
||||
|
||||
@@ -324,6 +324,7 @@
|
||||
}
|
||||
},
|
||||
"tab": {
|
||||
"aiImage": "AI рисуване",
|
||||
"chat": "Чат",
|
||||
"discover": "Открий",
|
||||
"files": "Файлове",
|
||||
|
||||
@@ -68,6 +68,15 @@
|
||||
"GoBack": {
|
||||
"back": "Назад"
|
||||
},
|
||||
"ImageUpload": {
|
||||
"actions": {
|
||||
"changeImage": "Кликнете, за да смените изображението"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "Добавяне на изображение",
|
||||
"secondary": "Кликнете, за да качите"
|
||||
}
|
||||
},
|
||||
"MaxTokenSlider": {
|
||||
"unlimited": "Неограничено"
|
||||
},
|
||||
@@ -91,6 +100,25 @@
|
||||
"provider": "Доставчик",
|
||||
"title": "Модел"
|
||||
},
|
||||
"MultiImagesUpload": {
|
||||
"actions": {
|
||||
"uploadMore": "Кликнете, за да качите още"
|
||||
},
|
||||
"modal": {
|
||||
"complete": "Готово",
|
||||
"newFileIndicator": "Нов",
|
||||
"selectImageToPreview": "Моля, изберете изображение за преглед",
|
||||
"title": "Управление на изображенията ({{count}})",
|
||||
"upload": "Качване на изображение"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "Кликнете, за да качите изображение",
|
||||
"secondary": "Поддържа избор на няколко изображения"
|
||||
},
|
||||
"progress": {
|
||||
"uploadingWithCount": "{{completed}}/{{total}} качени"
|
||||
}
|
||||
},
|
||||
"OllamaSetupGuide": {
|
||||
"action": {
|
||||
"close": "Затвори提示",
|
||||
|
||||
@@ -130,6 +130,7 @@
|
||||
"addProxyUrl": "Добавете URL адрес на OpenAI прокси (по избор)",
|
||||
"apiKey": {
|
||||
"description": "Въведете вашия {{name}} API ключ, за да започнете сесия",
|
||||
"imageGenerationDescription": "Въведете своя {{name}} API ключ, за да започнете генерирането",
|
||||
"title": "Използване на персонализиран {{name}} API ключ"
|
||||
},
|
||||
"closeMessage": "Затвори съобщението",
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"config": {
|
||||
"aspectRatio": {
|
||||
"label": "Съотношение"
|
||||
},
|
||||
"header": {
|
||||
"desc": "Кратко описание, създавайте веднага",
|
||||
"title": "Рисуване"
|
||||
},
|
||||
"height": {
|
||||
"label": "Височина"
|
||||
},
|
||||
"imageNum": {
|
||||
"label": "Брой изображения"
|
||||
},
|
||||
"imageUrl": {
|
||||
"label": "Референтно изображение"
|
||||
},
|
||||
"imageUrls": {
|
||||
"label": "Референтни изображения"
|
||||
},
|
||||
"model": {
|
||||
"label": "Модел"
|
||||
},
|
||||
"prompt": {
|
||||
"placeholder": "Опишете съдържанието, което искате да генерирате"
|
||||
},
|
||||
"seed": {
|
||||
"label": "Семена",
|
||||
"random": "Случаен семенен код"
|
||||
},
|
||||
"size": {
|
||||
"label": "Размер"
|
||||
},
|
||||
"steps": {
|
||||
"label": "Стъпки"
|
||||
},
|
||||
"title": "AI рисуване",
|
||||
"width": {
|
||||
"label": "Ширина"
|
||||
}
|
||||
},
|
||||
"generation": {
|
||||
"actions": {
|
||||
"applySeed": "Приложи семе",
|
||||
"copyError": "Копиране на грешка",
|
||||
"copyPrompt": "Копирай подсказката",
|
||||
"copySeed": "Копиране на семето",
|
||||
"delete": "Изтриване",
|
||||
"deleteBatch": "Изтриване на партида",
|
||||
"download": "Изтегляне",
|
||||
"downloadFailed": "Неуспешно изтегляне на изображението",
|
||||
"errorCopied": "Съобщението за грешка е копирано в клипборда",
|
||||
"errorCopyFailed": "Неуспешно копиране на съобщението за грешка",
|
||||
"generate": "Генерирай",
|
||||
"promptCopied": "Подсказката е копирана в клипборда",
|
||||
"promptCopyFailed": "Неуспешно копиране на подсказката",
|
||||
"reuseSettings": "Използване на настройките отново",
|
||||
"seedApplied": "Семето е приложено към конфигурацията",
|
||||
"seedApplyFailed": "Неуспешно прилагане на семе",
|
||||
"seedCopied": "Семето е копирано в клипборда",
|
||||
"seedCopyFailed": "Неуспешно копиране на семето"
|
||||
},
|
||||
"metadata": {
|
||||
"count": "{{count}} изображения"
|
||||
},
|
||||
"status": {
|
||||
"failed": "Генерирането не бе успешно",
|
||||
"generating": "Генериране..."
|
||||
}
|
||||
},
|
||||
"notSupportGuide": {
|
||||
"desc": "Настоящият инсталиран екземпляр използва клиентски режим с база данни и не поддържа функцията за генериране на AI изображения. Моля, преминете към <1>режим на сървърна база данни</1> или използвайте директно <3>LobeChat Cloud</3>",
|
||||
"features": {
|
||||
"fileIntegration": {
|
||||
"desc": "Дълбока интеграция с файловата система, генерираните изображения се запазват автоматично във файловата система, поддържайки централизирано управление и организация",
|
||||
"title": "Интеграция с файловата система"
|
||||
},
|
||||
"llmAssisted": {
|
||||
"desc": "Комбинира възможностите на големи езикови модели за интелигентна оптимизация и разширяване на подсказките, подобрявайки качеството на генерираните изображения (скоро)",
|
||||
"title": "Подпомагане с LLM"
|
||||
},
|
||||
"multiProviders": {
|
||||
"desc": "Поддържа множество AI доставчици за рисуване, включително OpenAI gpt-image-1, Google Imagen, FAL.ai и други, предоставяйки богат избор от модели",
|
||||
"title": "Поддръжка на множество доставчици"
|
||||
}
|
||||
},
|
||||
"title": "Настоящият режим на инсталация не поддържа AI рисуване"
|
||||
},
|
||||
"topic": {
|
||||
"createNew": "Създаване на нова тема",
|
||||
"deleteConfirm": "Потвърждение за изтриване на тема",
|
||||
"deleteConfirmDesc": "Ще изтриете тази генерирана тема. След изтриването тя не може да бъде възстановена. Моля, действайте внимателно.",
|
||||
"empty": "Няма генерирани теми",
|
||||
"title": "Тема на рисуване",
|
||||
"untitled": "По подразбиране тема"
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,10 @@
|
||||
"search": "Търсене",
|
||||
"title": "Открий"
|
||||
},
|
||||
"image": {
|
||||
"description": "{{appName}} ви предоставя най-доброто изживяване с GPT Image, Flux, Midjourney, Stable Diffusion",
|
||||
"title": "AI рисуване"
|
||||
},
|
||||
"plugins": {
|
||||
"description": "Търсене, генериране на графики, академични изследвания, генериране на изображения, генериране на видео, генериране на глас, автоматизирани работни потоци, персонализирайте ToolCall плъгините на ChatGPT / Claude",
|
||||
"title": "Пазар на плъгини"
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
"customRegion": "Персонализиран регион за услуги",
|
||||
"customSessionToken": "Персонализиран токен за сесия",
|
||||
"description": "Въведете вашия AWS AccessKeyId / SecretAccessKey, за да започнете сесия. Приложението няма да запази вашата удостоверителна конфигурация",
|
||||
"imageGenerationDescription": "Въведете вашия AWS AccessKeyId / SecretAccessKey, за да започнете генерирането. Приложението няма да записва вашите данни за удостоверяване",
|
||||
"title": "Използване на персонализирана информация за удостоверяване на Bedrock"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
"deepseek": {
|
||||
"description": "DeepSeek е компания, специализирана в изследвания и приложения на технологии за изкуствен интелект, чийто най-нов модел DeepSeek-V2.5 комбинира способности за общи диалози и обработка на код, постигайки значителни подобрения в съответствието с човешките предпочитания, писателските задачи и следването на инструкции."
|
||||
},
|
||||
"fal": {
|
||||
"description": "Генеративна медийна платформа за разработчици"
|
||||
},
|
||||
"fireworksai": {
|
||||
"description": "Fireworks AI е водещ доставчик на напреднали езикови модели, фокусирайки се върху извикване на функции и мултимодална обработка. Най-новият им модел Firefunction V2, базиран на Llama-3, е оптимизиран за извикване на функции, диалози и следване на инструкции. Визуалният езиков модел FireLLaVA-13B поддържа смесени входове от изображения и текст. Други забележителни модели включват серията Llama и серията Mixtral, предлагащи ефективна поддръжка за многоезично следване на инструкции и генериране."
|
||||
},
|
||||
|
||||
@@ -484,6 +484,11 @@
|
||||
"placeholder": "Моля, въведете персонализирана подканва",
|
||||
"title": "Персонализирана подканва"
|
||||
},
|
||||
"generationTopic": {
|
||||
"label": "Модел за именуване на теми за AI рисуване",
|
||||
"modelDesc": "Модел, предназначен за автоматично именуване на теми за AI рисуване",
|
||||
"title": "Автоматично именуване на теми за AI рисуване"
|
||||
},
|
||||
"helpInfo": "Когато създавате нов асистент, настройките по подразбиране ще се използват като предварителни стойности.",
|
||||
"historyCompress": {
|
||||
"label": "Модел на история на сесията",
|
||||
|
||||
@@ -324,6 +324,7 @@
|
||||
}
|
||||
},
|
||||
"tab": {
|
||||
"aiImage": "KI-Gemälde",
|
||||
"chat": "Chat",
|
||||
"discover": "Entdecken",
|
||||
"files": "Dateien",
|
||||
|
||||
@@ -68,6 +68,15 @@
|
||||
"GoBack": {
|
||||
"back": "Zurück"
|
||||
},
|
||||
"ImageUpload": {
|
||||
"actions": {
|
||||
"changeImage": "Bild ändern"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "Bild hinzufügen",
|
||||
"secondary": "Zum Hochladen klicken"
|
||||
}
|
||||
},
|
||||
"MaxTokenSlider": {
|
||||
"unlimited": "Unbegrenzt"
|
||||
},
|
||||
@@ -91,6 +100,25 @@
|
||||
"provider": "Anbieter",
|
||||
"title": "Modell"
|
||||
},
|
||||
"MultiImagesUpload": {
|
||||
"actions": {
|
||||
"uploadMore": "Klicken Sie, um weitere hochzuladen"
|
||||
},
|
||||
"modal": {
|
||||
"complete": "Fertig",
|
||||
"newFileIndicator": "Neu",
|
||||
"selectImageToPreview": "Bitte wählen Sie ein Bild zur Vorschau aus",
|
||||
"title": "Bilder verwalten ({{count}})",
|
||||
"upload": "Bild hochladen"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "Klicken Sie, um Bilder hochzuladen",
|
||||
"secondary": "Mehrere Bilder können ausgewählt werden"
|
||||
},
|
||||
"progress": {
|
||||
"uploadingWithCount": "{{completed}}/{{total}} hochgeladen"
|
||||
}
|
||||
},
|
||||
"OllamaSetupGuide": {
|
||||
"action": {
|
||||
"close": "Hinweis schließen",
|
||||
|
||||
@@ -130,6 +130,7 @@
|
||||
"addProxyUrl": "Fügen Sie die OpenAI-Proxy-URL hinzu (optional)",
|
||||
"apiKey": {
|
||||
"description": "Geben Sie Ihren {{name}} API-Schlüssel ein, um die Sitzung zu starten.",
|
||||
"imageGenerationDescription": "Geben Sie Ihren {{name}} API-Schlüssel ein, um mit der Generierung zu beginnen",
|
||||
"title": "Verwenden Sie Ihren benutzerdefinierten {{name}} API-Schlüssel"
|
||||
},
|
||||
"closeMessage": "Hinweis schließen",
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"config": {
|
||||
"aspectRatio": {
|
||||
"label": "Seitenverhältnis"
|
||||
},
|
||||
"header": {
|
||||
"desc": "Einfache Beschreibung, sofortige Kreation",
|
||||
"title": "Malerei"
|
||||
},
|
||||
"height": {
|
||||
"label": "Höhe"
|
||||
},
|
||||
"imageNum": {
|
||||
"label": "Anzahl der Bilder"
|
||||
},
|
||||
"imageUrl": {
|
||||
"label": "Referenzbild"
|
||||
},
|
||||
"imageUrls": {
|
||||
"label": "Referenzbilder"
|
||||
},
|
||||
"model": {
|
||||
"label": "Modell"
|
||||
},
|
||||
"prompt": {
|
||||
"placeholder": "Beschreiben Sie den Inhalt, den Sie generieren möchten"
|
||||
},
|
||||
"seed": {
|
||||
"label": "Seed",
|
||||
"random": "Zufälliger Seed"
|
||||
},
|
||||
"size": {
|
||||
"label": "Größe"
|
||||
},
|
||||
"steps": {
|
||||
"label": "Schritte"
|
||||
},
|
||||
"title": "KI-Malerei",
|
||||
"width": {
|
||||
"label": "Breite"
|
||||
}
|
||||
},
|
||||
"generation": {
|
||||
"actions": {
|
||||
"applySeed": "Saatgut anwenden",
|
||||
"copyError": "Fehlermeldung kopieren",
|
||||
"copyPrompt": "Prompt kopieren",
|
||||
"copySeed": "Seed kopieren",
|
||||
"delete": "Löschen",
|
||||
"deleteBatch": "Batch löschen",
|
||||
"download": "Herunterladen",
|
||||
"downloadFailed": "Bild-Download fehlgeschlagen",
|
||||
"errorCopied": "Fehlermeldung wurde in die Zwischenablage kopiert",
|
||||
"errorCopyFailed": "Fehlermeldung kopieren fehlgeschlagen",
|
||||
"generate": "Generieren",
|
||||
"promptCopied": "Prompt wurde in die Zwischenablage kopiert",
|
||||
"promptCopyFailed": "Prompt-Kopieren fehlgeschlagen",
|
||||
"reuseSettings": "Einstellungen wiederverwenden",
|
||||
"seedApplied": "Saatgut wurde auf die Konfiguration angewendet",
|
||||
"seedApplyFailed": "Anwenden des Saatguts fehlgeschlagen",
|
||||
"seedCopied": "Seed wurde in die Zwischenablage kopiert",
|
||||
"seedCopyFailed": "Seed-Kopieren fehlgeschlagen"
|
||||
},
|
||||
"metadata": {
|
||||
"count": "{{count}} Bilder"
|
||||
},
|
||||
"status": {
|
||||
"failed": "Generierung fehlgeschlagen",
|
||||
"generating": "Wird generiert..."
|
||||
}
|
||||
},
|
||||
"notSupportGuide": {
|
||||
"desc": "Die aktuell eingesetzte Instanz verwendet den Client-Datenbankmodus und unterstützt die KI-Bilderzeugung nicht. Bitte wechseln Sie zum <1>Server-Datenbankmodus</1> oder nutzen Sie direkt <3>LobeChat Cloud</3>.",
|
||||
"features": {
|
||||
"fileIntegration": {
|
||||
"desc": "Tiefgreifende Integration mit dem Dateimanagementsystem, generierte Bilder werden automatisch im Dateisystem gespeichert und können zentral verwaltet und organisiert werden.",
|
||||
"title": "Dateisystem-Integration"
|
||||
},
|
||||
"llmAssisted": {
|
||||
"desc": "Kombiniert die Fähigkeiten großer Sprachmodelle zur intelligenten Optimierung und Erweiterung von Prompts, um die Bildqualität zu verbessern (bald verfügbar).",
|
||||
"title": "LLM-unterstützte Bildgenerierung"
|
||||
},
|
||||
"multiProviders": {
|
||||
"desc": "Unterstützt verschiedene KI-Malservice-Anbieter, darunter OpenAI gpt-image-1, Google Imagen, FAL.ai und weitere, und bietet eine breite Modellauswahl.",
|
||||
"title": "Unterstützung mehrerer Anbieter"
|
||||
}
|
||||
},
|
||||
"title": "Der aktuell eingesetzte Modus unterstützt keine KI-Malerei"
|
||||
},
|
||||
"topic": {
|
||||
"createNew": "Neues Thema erstellen",
|
||||
"deleteConfirm": "Generiertes Thema löschen",
|
||||
"deleteConfirmDesc": "Das generierte Thema wird gelöscht und kann nicht wiederhergestellt werden. Bitte vorsichtig vorgehen.",
|
||||
"empty": "Keine generierten Themen vorhanden",
|
||||
"title": "Malthema",
|
||||
"untitled": "Standardthema"
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,10 @@
|
||||
"search": "Suche",
|
||||
"title": "Entdecken"
|
||||
},
|
||||
"image": {
|
||||
"description": "{{appName}} bietet Ihnen das beste Nutzungserlebnis für GPT Image, Flux, Midjourney und Stable Diffusion",
|
||||
"title": "KI-Grafik"
|
||||
},
|
||||
"plugins": {
|
||||
"description": "Suche, Diagrammerstellung, akademisch, Bilderzeugung, Videoerzeugung, Spracherzeugung, automatisierte Workflows, passe die ToolCall-Plugin-Funktionen von ChatGPT / Claude an",
|
||||
"title": "Plugin-Markt"
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
"customRegion": "Benutzerdefinierter Regionsservice",
|
||||
"customSessionToken": "Benutzerdefiniertes Sitzungstoken",
|
||||
"description": "Geben Sie Ihren AWS AccessKeyId / SecretAccessKey ein, um das Gespräch zu beginnen. Die App speichert Ihre Authentifizierungsinformationen nicht.",
|
||||
"imageGenerationDescription": "Geben Sie Ihre AWS AccessKeyId / SecretAccessKey ein, um mit der Generierung zu beginnen. Die Anwendung speichert Ihre Authentifizierungsdaten nicht.",
|
||||
"title": "Verwenden Sie benutzerdefinierte Bedrock-Authentifizierungsinformationen"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
"deepseek": {
|
||||
"description": "DeepSeek ist ein Unternehmen, das sich auf die Forschung und Anwendung von KI-Technologien spezialisiert hat. Ihr neuestes Modell, DeepSeek-V2.5, kombiniert allgemeine Dialog- und Codeverarbeitungsfähigkeiten und hat signifikante Fortschritte in den Bereichen menschliche Präferenzanpassung, Schreibaufgaben und Befehlsbefolgung erzielt."
|
||||
},
|
||||
"fal": {
|
||||
"description": "Generative Medienplattform für Entwickler"
|
||||
},
|
||||
"fireworksai": {
|
||||
"description": "Fireworks AI ist ein führender Anbieter von fortschrittlichen Sprachmodellen, der sich auf Funktionsaufrufe und multimodale Verarbeitung spezialisiert hat. Ihr neuestes Modell, Firefunction V2, basiert auf Llama-3 und ist für Funktionsaufrufe, Dialoge und Befehlsbefolgung optimiert. Das visuelle Sprachmodell FireLLaVA-13B unterstützt gemischte Eingaben von Bildern und Text. Weitere bemerkenswerte Modelle sind die Llama-Serie und die Mixtral-Serie, die effiziente mehrsprachige Befehlsbefolgung und Generierungsunterstützung bieten."
|
||||
},
|
||||
|
||||
@@ -484,6 +484,11 @@
|
||||
"placeholder": "Bitte benutzerdefinierte Eingabe eingeben",
|
||||
"title": "Benutzerdefinierte Eingabe"
|
||||
},
|
||||
"generationTopic": {
|
||||
"label": "Modell zur Benennung von KI-Malthemen",
|
||||
"modelDesc": "Modell zur automatischen Benennung von Themen für KI-Malerei",
|
||||
"title": "Automatische Benennung von KI-Malthemen"
|
||||
},
|
||||
"helpInfo": "Beim Erstellen eines neuen Assistenten werden die Standardassistenteneinstellungen als Voreinstellungen verwendet.",
|
||||
"historyCompress": {
|
||||
"label": "Gesprächshistorienmodell",
|
||||
|
||||
@@ -324,6 +324,7 @@
|
||||
}
|
||||
},
|
||||
"tab": {
|
||||
"aiImage": "AI Painting",
|
||||
"chat": "Chat",
|
||||
"discover": "Discover",
|
||||
"files": "Files",
|
||||
|
||||
@@ -68,6 +68,15 @@
|
||||
"GoBack": {
|
||||
"back": "Back"
|
||||
},
|
||||
"ImageUpload": {
|
||||
"actions": {
|
||||
"changeImage": "Click to Change Image"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "Add Image",
|
||||
"secondary": "Click to Upload"
|
||||
}
|
||||
},
|
||||
"MaxTokenSlider": {
|
||||
"unlimited": "Unlimited"
|
||||
},
|
||||
@@ -91,6 +100,25 @@
|
||||
"provider": "Provider",
|
||||
"title": "Model"
|
||||
},
|
||||
"MultiImagesUpload": {
|
||||
"actions": {
|
||||
"uploadMore": "Click to upload more"
|
||||
},
|
||||
"modal": {
|
||||
"complete": "Done",
|
||||
"newFileIndicator": "New",
|
||||
"selectImageToPreview": "Please select an image to preview",
|
||||
"title": "Manage Images ({{count}})",
|
||||
"upload": "Upload Images"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "Click to upload images",
|
||||
"secondary": "Supports multiple image selection"
|
||||
},
|
||||
"progress": {
|
||||
"uploadingWithCount": "{{completed}}/{{total}} uploaded"
|
||||
}
|
||||
},
|
||||
"OllamaSetupGuide": {
|
||||
"action": {
|
||||
"close": "Close Prompt",
|
||||
|
||||
@@ -130,6 +130,7 @@
|
||||
"addProxyUrl": "Add OpenAI proxy URL (optional)",
|
||||
"apiKey": {
|
||||
"description": "Enter your {{name}} API Key to start the session",
|
||||
"imageGenerationDescription": "Enter your {{name}} API Key to start generating",
|
||||
"title": "Use custom {{name}} API Key"
|
||||
},
|
||||
"closeMessage": "Close message",
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
{
|
||||
"config": {
|
||||
"aspectRatio": {
|
||||
"label": "Aspect Ratio",
|
||||
"lock": "Lock Aspect Ratio",
|
||||
"unlock": "Unlock Aspect Ratio"
|
||||
},
|
||||
"header": {
|
||||
"desc": "Brief description, create instantly",
|
||||
"title": "Painting"
|
||||
},
|
||||
"height": {
|
||||
"label": "Height"
|
||||
},
|
||||
"imageNum": {
|
||||
"label": "Number of Images"
|
||||
},
|
||||
"imageUrl": {
|
||||
"label": "Reference Image"
|
||||
},
|
||||
"imageUrls": {
|
||||
"label": "Reference Images"
|
||||
},
|
||||
"model": {
|
||||
"label": "Model"
|
||||
},
|
||||
"prompt": {
|
||||
"placeholder": "Describe what you want to generate"
|
||||
},
|
||||
"seed": {
|
||||
"label": "Seed",
|
||||
"random": "Random Seed"
|
||||
},
|
||||
"size": {
|
||||
"label": "Size"
|
||||
},
|
||||
"steps": {
|
||||
"label": "Steps"
|
||||
},
|
||||
"title": "AI Image",
|
||||
"width": {
|
||||
"label": "Width"
|
||||
}
|
||||
},
|
||||
"generation": {
|
||||
"actions": {
|
||||
"applySeed": "Apply Seed",
|
||||
"copyError": "Copy Error Message",
|
||||
"copyPrompt": "Copy Prompt",
|
||||
"copySeed": "Copy Seed",
|
||||
"delete": "Delete",
|
||||
"deleteBatch": "Delete Batch",
|
||||
"download": "Download",
|
||||
"downloadFailed": "Failed to download image. Please check your network connection or S3 storage CORS configuration.",
|
||||
"errorCopied": "Error Message Copied to Clipboard",
|
||||
"errorCopyFailed": "Failed to Copy Error Message",
|
||||
"generate": "Generate",
|
||||
"promptCopied": "Prompt Copied to Clipboard",
|
||||
"promptCopyFailed": "Failed to Copy Prompt",
|
||||
"reuseSettings": "Reuse Settings",
|
||||
"seedApplied": "Seed Applied to Configuration",
|
||||
"seedApplyFailed": "Failed to Apply Seed",
|
||||
"seedCopied": "Seed Copied to Clipboard",
|
||||
"seedCopyFailed": "Failed to Copy Seed"
|
||||
},
|
||||
"metadata": {
|
||||
"count": "{{count}} Images"
|
||||
},
|
||||
"status": {
|
||||
"failed": "Generation Failed",
|
||||
"generating": "Generating..."
|
||||
}
|
||||
},
|
||||
"notSupportGuide": {
|
||||
"desc": "The current deployment instance uses client-side database mode and does not support AI image generation. Please switch to the <1>server-side database deployment mode</1>, or use <3>LobeChat Cloud</3> directly.",
|
||||
"features": {
|
||||
"fileIntegration": {
|
||||
"desc": "Deep integration with the file management system; generated images are automatically saved to the file system for unified management and organization.",
|
||||
"title": "File System Integration"
|
||||
},
|
||||
"llmAssisted": {
|
||||
"desc": "Combines large language model capabilities to intelligently optimize and expand prompts, enhancing image generation quality (Coming Soon).",
|
||||
"title": "LLM-Assisted Image Generation"
|
||||
},
|
||||
"multiProviders": {
|
||||
"desc": "Supports multiple AI image generation providers, including OpenAI gpt-image-1, Google Imagen, FAL.ai, and more, offering a wide selection of models.",
|
||||
"title": "Multi-Provider Support"
|
||||
}
|
||||
},
|
||||
"title": "Current Deployment Mode Does Not Support AI Image Generation"
|
||||
},
|
||||
"topic": {
|
||||
"createNew": "New Topic",
|
||||
"deleteConfirm": "Delete Generation Topic",
|
||||
"deleteConfirmDesc": "You are about to delete this generation topic. This action cannot be undone, please proceed with caution.",
|
||||
"empty": "No generation topics",
|
||||
"title": "Painting Theme",
|
||||
"untitled": "Default Topic"
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,10 @@
|
||||
"search": "Search",
|
||||
"title": "Discover"
|
||||
},
|
||||
"image": {
|
||||
"description": "{{appName}} brings you the best experience with GPT Image, Flux, Midjourney, and Stable Diffusion",
|
||||
"title": "AI Painting"
|
||||
},
|
||||
"plugins": {
|
||||
"description": "Search, chart generation, academic tools, image generation, video generation, voice generation, automated workflows—customize Tools Calling plugin capabilities for ChatGPT / Claude.",
|
||||
"title": "Plugin Marketplace"
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
"customRegion": "Custom Service Region",
|
||||
"customSessionToken": "Custom Session Token",
|
||||
"description": "Enter your AWS AccessKeyId / SecretAccessKey to start the session. The app will not store your authentication configuration",
|
||||
"imageGenerationDescription": "Enter your AWS AccessKeyId / SecretAccessKey to start generating. The application will not store your authentication credentials.",
|
||||
"title": "Use Custom Bedrock Authentication Information"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
"deepseek": {
|
||||
"description": "DeepSeek is a company focused on AI technology research and application, with its latest model DeepSeek-V2.5 integrating general dialogue and code processing capabilities, achieving significant improvements in human preference alignment, writing tasks, and instruction following."
|
||||
},
|
||||
"fal": {
|
||||
"description": "Generative Media Platform for Developers"
|
||||
},
|
||||
"fireworksai": {
|
||||
"description": "Fireworks AI is a leading provider of advanced language model services, focusing on functional calling and multimodal processing. Its latest model, Firefunction V2, is based on Llama-3, optimized for function calling, conversation, and instruction following. The visual language model FireLLaVA-13B supports mixed input of images and text. Other notable models include the Llama series and Mixtral series, providing efficient multilingual instruction following and generation support."
|
||||
},
|
||||
|
||||
@@ -484,6 +484,11 @@
|
||||
"placeholder": "Please enter custom prompt",
|
||||
"title": "Custom Prompt"
|
||||
},
|
||||
"generationTopic": {
|
||||
"label": "AI Art Topic Naming Model",
|
||||
"modelDesc": "Model designated for automatic naming of AI art topics",
|
||||
"title": "AI Art Automatic Topic Naming"
|
||||
},
|
||||
"helpInfo": "When creating a new assistant, the default assistant settings will be used as preset values.",
|
||||
"historyCompress": {
|
||||
"label": "Conversation History Model",
|
||||
|
||||
@@ -324,6 +324,7 @@
|
||||
}
|
||||
},
|
||||
"tab": {
|
||||
"aiImage": "Dibujo AI",
|
||||
"chat": "Chat",
|
||||
"discover": "Descubrir",
|
||||
"files": "Archivos",
|
||||
|
||||
@@ -68,6 +68,15 @@
|
||||
"GoBack": {
|
||||
"back": "Regresar"
|
||||
},
|
||||
"ImageUpload": {
|
||||
"actions": {
|
||||
"changeImage": "Haz clic para cambiar la imagen"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "Agregar imagen",
|
||||
"secondary": "Haz clic para subir"
|
||||
}
|
||||
},
|
||||
"MaxTokenSlider": {
|
||||
"unlimited": "Sin límite"
|
||||
},
|
||||
@@ -91,6 +100,25 @@
|
||||
"provider": "Proveedor",
|
||||
"title": "Modelo"
|
||||
},
|
||||
"MultiImagesUpload": {
|
||||
"actions": {
|
||||
"uploadMore": "Haz clic para subir más"
|
||||
},
|
||||
"modal": {
|
||||
"complete": "Completar",
|
||||
"newFileIndicator": "Nuevo",
|
||||
"selectImageToPreview": "Por favor, selecciona una imagen para previsualizar",
|
||||
"title": "Gestionar imágenes ({{count}})",
|
||||
"upload": "Subir imágenes"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "Haz clic para subir imágenes",
|
||||
"secondary": "Se admite la selección de múltiples imágenes"
|
||||
},
|
||||
"progress": {
|
||||
"uploadingWithCount": "{{completed}}/{{total}} subidas"
|
||||
}
|
||||
},
|
||||
"OllamaSetupGuide": {
|
||||
"action": {
|
||||
"close": "Cerrar aviso",
|
||||
|
||||
@@ -130,6 +130,7 @@
|
||||
"addProxyUrl": "Agregar URL de proxy de OpenAI (opcional)",
|
||||
"apiKey": {
|
||||
"description": "Ingresa tu API Key de {{name}} para comenzar la sesión",
|
||||
"imageGenerationDescription": "Introduce tu clave API de {{name}} para comenzar a generar",
|
||||
"title": "Usar tu propia API Key de {{name}}"
|
||||
},
|
||||
"closeMessage": "Cerrar mensaje",
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"config": {
|
||||
"aspectRatio": {
|
||||
"label": "Proporción"
|
||||
},
|
||||
"header": {
|
||||
"desc": "Descripción simple, crea al instante",
|
||||
"title": "Pintura"
|
||||
},
|
||||
"height": {
|
||||
"label": "Alto"
|
||||
},
|
||||
"imageNum": {
|
||||
"label": "Cantidad de imágenes"
|
||||
},
|
||||
"imageUrl": {
|
||||
"label": "Imagen de referencia"
|
||||
},
|
||||
"imageUrls": {
|
||||
"label": "Imágenes de referencia"
|
||||
},
|
||||
"model": {
|
||||
"label": "Modelo"
|
||||
},
|
||||
"prompt": {
|
||||
"placeholder": "Describe el contenido que deseas generar"
|
||||
},
|
||||
"seed": {
|
||||
"label": "Semilla",
|
||||
"random": "Semilla aleatoria"
|
||||
},
|
||||
"size": {
|
||||
"label": "Tamaño"
|
||||
},
|
||||
"steps": {
|
||||
"label": "Pasos"
|
||||
},
|
||||
"title": "Pintura AI",
|
||||
"width": {
|
||||
"label": "Ancho"
|
||||
}
|
||||
},
|
||||
"generation": {
|
||||
"actions": {
|
||||
"applySeed": "Aplicar semilla",
|
||||
"copyError": "Copiar mensaje de error",
|
||||
"copyPrompt": "Copiar indicación",
|
||||
"copySeed": "Copiar semilla",
|
||||
"delete": "Eliminar",
|
||||
"deleteBatch": "Eliminar lote",
|
||||
"download": "Descargar",
|
||||
"downloadFailed": "Error al descargar la imagen",
|
||||
"errorCopied": "Mensaje de error copiado al portapapeles",
|
||||
"errorCopyFailed": "Error al copiar el mensaje de error",
|
||||
"generate": "Generar",
|
||||
"promptCopied": "Texto de indicación copiado al portapapeles",
|
||||
"promptCopyFailed": "Error al copiar el texto de indicación",
|
||||
"reuseSettings": "Reutilizar configuración",
|
||||
"seedApplied": "Semilla aplicada a la configuración",
|
||||
"seedApplyFailed": "Error al aplicar la semilla",
|
||||
"seedCopied": "Semilla copiada al portapapeles",
|
||||
"seedCopyFailed": "Error al copiar la semilla"
|
||||
},
|
||||
"metadata": {
|
||||
"count": "{{count}} imágenes"
|
||||
},
|
||||
"status": {
|
||||
"failed": "Generación fallida",
|
||||
"generating": "Generando..."
|
||||
}
|
||||
},
|
||||
"notSupportGuide": {
|
||||
"desc": "La instancia desplegada actual está en modo base de datos cliente y no soporta la función de generación de imágenes AI. Por favor, cambia al <1>modo de despliegue con base de datos servidor</1> o utiliza directamente <3>LobeChat Cloud</3>",
|
||||
"features": {
|
||||
"fileIntegration": {
|
||||
"desc": "Integración profunda con el sistema de gestión de archivos, las imágenes generadas se guardan automáticamente en el sistema de archivos para una gestión y organización unificada",
|
||||
"title": "Interoperabilidad con sistema de archivos"
|
||||
},
|
||||
"llmAssisted": {
|
||||
"desc": "Combinación con capacidades de modelos de lenguaje grandes para optimizar y expandir inteligentemente los textos de indicación, mejorando la calidad de generación de imágenes (Próximamente)",
|
||||
"title": "Generación asistida por LLM"
|
||||
},
|
||||
"multiProviders": {
|
||||
"desc": "Soporta múltiples proveedores de servicios de pintura AI, incluyendo OpenAI gpt-image-1, Google Imagen, FAL.ai, entre otros, ofreciendo una amplia selección de modelos",
|
||||
"title": "Soporte para múltiples proveedores"
|
||||
}
|
||||
},
|
||||
"title": "El modo de despliegue actual no soporta pintura AI"
|
||||
},
|
||||
"topic": {
|
||||
"createNew": "Crear nuevo tema",
|
||||
"deleteConfirm": "Eliminar tema generado",
|
||||
"deleteConfirmDesc": "Estás a punto de eliminar este tema generado. Esta acción es irreversible, por favor procede con precaución.",
|
||||
"empty": "No hay temas generados",
|
||||
"title": "Tema de pintura",
|
||||
"untitled": "Tema predeterminado"
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,10 @@
|
||||
"search": "Buscar",
|
||||
"title": "Descubrir"
|
||||
},
|
||||
"image": {
|
||||
"description": "{{appName}} te ofrece la mejor experiencia de uso con GPT Image, Flux, Midjourney y Stable Diffusion",
|
||||
"title": "Pintura AI"
|
||||
},
|
||||
"plugins": {
|
||||
"description": "Búsqueda, generación de gráficos, académico, generación de imágenes, generación de videos, generación de voz, flujos de trabajo automatizados, personaliza las capacidades de los plugins ToolCall exclusivos de ChatGPT / Claude",
|
||||
"title": "Mercado de Plugins"
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
"customRegion": "Región de servicio personalizada",
|
||||
"customSessionToken": "Token de sesión personalizado",
|
||||
"description": "Introduce tu AWS AccessKeyId / SecretAccessKey para comenzar la sesión. La aplicación no guardará tu configuración de autenticación.",
|
||||
"imageGenerationDescription": "Introduce tu AWS AccessKeyId / SecretAccessKey para comenzar a generar. La aplicación no registrará tu configuración de autenticación",
|
||||
"title": "Usar información de autenticación de Bedrock personalizada"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
"deepseek": {
|
||||
"description": "DeepSeek es una empresa centrada en la investigación y aplicación de tecnologías de inteligencia artificial, cuyo modelo más reciente, DeepSeek-V2.5, combina capacidades de diálogo general y procesamiento de código, logrando mejoras significativas en alineación con preferencias humanas, tareas de escritura y seguimiento de instrucciones."
|
||||
},
|
||||
"fal": {
|
||||
"description": "Plataforma de medios generativos orientada a desarrolladores"
|
||||
},
|
||||
"fireworksai": {
|
||||
"description": "Fireworks AI es un proveedor líder de servicios de modelos de lenguaje avanzados, enfocado en la llamada de funciones y el procesamiento multimodal. Su modelo más reciente, Firefunction V2, basado en Llama-3, está optimizado para llamadas de funciones, diálogos y seguimiento de instrucciones. El modelo de lenguaje visual FireLLaVA-13B admite entradas mixtas de imágenes y texto. Otros modelos notables incluyen la serie Llama y la serie Mixtral, que ofrecen un soporte eficiente para el seguimiento y generación de instrucciones multilingües."
|
||||
},
|
||||
|
||||
@@ -484,6 +484,11 @@
|
||||
"placeholder": "Introduce la palabra clave personalizada",
|
||||
"title": "Palabra clave personalizada"
|
||||
},
|
||||
"generationTopic": {
|
||||
"label": "Modelo de denominación de temas para pintura AI",
|
||||
"modelDesc": "Modelo designado para la denominación automática de temas en pintura AI",
|
||||
"title": "Denominación automática de temas para pintura AI"
|
||||
},
|
||||
"helpInfo": "Al crear un nuevo asistente, se utilizarán los ajustes predeterminados del asistente como valores predeterminados.",
|
||||
"historyCompress": {
|
||||
"label": "Modelo de historial de conversación",
|
||||
|
||||
@@ -324,6 +324,7 @@
|
||||
}
|
||||
},
|
||||
"tab": {
|
||||
"aiImage": "نقاشی هوش مصنوعی",
|
||||
"chat": "گفتگو",
|
||||
"discover": "کشف",
|
||||
"files": "فایلها",
|
||||
|
||||
@@ -68,6 +68,15 @@
|
||||
"GoBack": {
|
||||
"back": "بازگشت"
|
||||
},
|
||||
"ImageUpload": {
|
||||
"actions": {
|
||||
"changeImage": "برای تغییر تصویر کلیک کنید"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "افزودن تصویر",
|
||||
"secondary": "برای بارگذاری کلیک کنید"
|
||||
}
|
||||
},
|
||||
"MaxTokenSlider": {
|
||||
"unlimited": "نامحدود"
|
||||
},
|
||||
@@ -91,6 +100,25 @@
|
||||
"provider": "ارائهدهنده",
|
||||
"title": "مدل"
|
||||
},
|
||||
"MultiImagesUpload": {
|
||||
"actions": {
|
||||
"uploadMore": "برای آپلود بیشتر کلیک کنید"
|
||||
},
|
||||
"modal": {
|
||||
"complete": "تکمیل",
|
||||
"newFileIndicator": "جدید",
|
||||
"selectImageToPreview": "لطفاً تصویری برای پیشنمایش انتخاب کنید",
|
||||
"title": "مدیریت تصاویر ({{count}})",
|
||||
"upload": "آپلود تصویر"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "برای آپلود تصویر کلیک کنید",
|
||||
"secondary": "انتخاب چندین تصویر پشتیبانی میشود"
|
||||
},
|
||||
"progress": {
|
||||
"uploadingWithCount": "{{completed}}/{{total}} بارگذاری شده"
|
||||
}
|
||||
},
|
||||
"OllamaSetupGuide": {
|
||||
"action": {
|
||||
"close": "بستن پیام",
|
||||
|
||||
@@ -130,6 +130,7 @@
|
||||
"addProxyUrl": "افزودن آدرس پروکسی OpenAI (اختیاری)",
|
||||
"apiKey": {
|
||||
"description": "API Key {{name}} خود را وارد کنید تا مکالمه را شروع کنید",
|
||||
"imageGenerationDescription": "برای شروع تولید، کلید API {{name}} خود را وارد کنید",
|
||||
"title": "استفاده از API Key سفارشی {{name}}"
|
||||
},
|
||||
"closeMessage": "بستن پیام",
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"config": {
|
||||
"aspectRatio": {
|
||||
"label": "نسبت ابعاد"
|
||||
},
|
||||
"header": {
|
||||
"desc": "توضیح ساده، خلق فوری",
|
||||
"title": "نقاشی"
|
||||
},
|
||||
"height": {
|
||||
"label": "ارتفاع"
|
||||
},
|
||||
"imageNum": {
|
||||
"label": "تعداد تصاویر"
|
||||
},
|
||||
"imageUrl": {
|
||||
"label": "تصویر مرجع"
|
||||
},
|
||||
"imageUrls": {
|
||||
"label": "تصاویر مرجع"
|
||||
},
|
||||
"model": {
|
||||
"label": "مدل"
|
||||
},
|
||||
"prompt": {
|
||||
"placeholder": "توصیف محتوایی که میخواهید تولید شود"
|
||||
},
|
||||
"seed": {
|
||||
"label": "بذر",
|
||||
"random": "بذر تصادفی"
|
||||
},
|
||||
"size": {
|
||||
"label": "اندازه"
|
||||
},
|
||||
"steps": {
|
||||
"label": "تعداد مراحل"
|
||||
},
|
||||
"title": "نقاشی هوش مصنوعی",
|
||||
"width": {
|
||||
"label": "عرض"
|
||||
}
|
||||
},
|
||||
"generation": {
|
||||
"actions": {
|
||||
"applySeed": "اعمال بذر",
|
||||
"copyError": "کپی خطا",
|
||||
"copyPrompt": "کپی عبارت راهنما",
|
||||
"copySeed": "کپی بذر",
|
||||
"delete": "حذف",
|
||||
"deleteBatch": "حذف دستهای",
|
||||
"download": "دانلود",
|
||||
"downloadFailed": "دانلود تصویر ناموفق بود",
|
||||
"errorCopied": "اطلاعات خطا به کلیپبورد کپی شد",
|
||||
"errorCopyFailed": "کپی اطلاعات خطا ناموفق بود",
|
||||
"generate": "تولید",
|
||||
"promptCopied": "عبارت راهنما به کلیپبورد کپی شد",
|
||||
"promptCopyFailed": "کپی عبارت راهنما ناموفق بود",
|
||||
"reuseSettings": "استفاده مجدد از تنظیمات",
|
||||
"seedApplied": "بذر به پیکربندی اعمال شد",
|
||||
"seedApplyFailed": "اعمال بذر ناموفق بود",
|
||||
"seedCopied": "بذر به کلیپبورد کپی شد",
|
||||
"seedCopyFailed": "کپی بذر ناموفق بود"
|
||||
},
|
||||
"metadata": {
|
||||
"count": "{{count}} تصویر"
|
||||
},
|
||||
"status": {
|
||||
"failed": "تولید ناموفق بود",
|
||||
"generating": "در حال تولید..."
|
||||
}
|
||||
},
|
||||
"notSupportGuide": {
|
||||
"desc": "نمونه استقرار فعلی در حالت پایگاه داده کلاینت است و امکان استفاده از قابلیت تولید تصویر هوش مصنوعی وجود ندارد. لطفاً به <1>حالت استقرار پایگاه داده سرور</1> تغییر دهید یا مستقیماً از <3>LobeChat Cloud</3> استفاده کنید.",
|
||||
"features": {
|
||||
"fileIntegration": {
|
||||
"desc": "ادغام عمیق با سیستم مدیریت فایل، تصاویر تولید شده به طور خودکار در سیستم فایل ذخیره میشوند و مدیریت و سازماندهی یکپارچه را فراهم میکنند",
|
||||
"title": "یکپارچگی سیستم فایل"
|
||||
},
|
||||
"llmAssisted": {
|
||||
"desc": "ترکیب قابلیتهای مدل زبان بزرگ برای بهینهسازی هوشمند و گسترش عبارتهای راهنما، بهبود کیفیت تولید تصویر (به زودی)",
|
||||
"title": "تولید تصویر با کمک LLM"
|
||||
},
|
||||
"multiProviders": {
|
||||
"desc": "پشتیبانی از چندین ارائهدهنده خدمات نقاشی هوش مصنوعی، از جمله OpenAI gpt-image-1، Google Imagen، FAL.ai و غیره، با انتخاب گسترده مدلها",
|
||||
"title": "پشتیبانی چند ارائهدهنده"
|
||||
}
|
||||
},
|
||||
"title": "حالت استقرار فعلی از نقاشی هوش مصنوعی پشتیبانی نمیکند"
|
||||
},
|
||||
"topic": {
|
||||
"createNew": "ایجاد موضوع جدید",
|
||||
"deleteConfirm": "حذف موضوع تولید شده",
|
||||
"deleteConfirmDesc": "موضوع تولید شده در حال حذف است، پس از حذف قابل بازیابی نیست، لطفاً با دقت اقدام کنید.",
|
||||
"empty": "موضوع تولید شدهای وجود ندارد",
|
||||
"title": "موضوع نقاشی",
|
||||
"untitled": "موضوع پیشفرض"
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,10 @@
|
||||
"search": "جستجو",
|
||||
"title": "کشف"
|
||||
},
|
||||
"image": {
|
||||
"description": "{{appName}} بهترین تجربه استفاده از GPT Image، Flux، Midjourney و Stable Diffusion را برای شما به ارمغان میآورد",
|
||||
"title": "نقاشی هوش مصنوعی"
|
||||
},
|
||||
"plugins": {
|
||||
"description": "جستجو، تولید نمودار، علمی، تولید تصویر، تولید ویدئو، تولید صدا، جریان کاری خودکار، سفارشیسازی قابلیتهای ToolCall اختصاصی ChatGPT / Claude",
|
||||
"title": "بازار افزونهها"
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
"customRegion": "منطقه خدمات سفارشی",
|
||||
"customSessionToken": "توکن نشست سفارشی",
|
||||
"description": "برای شروع جلسه، AWS AccessKeyId / SecretAccessKey خود را وارد کنید. برنامه تنظیمات احراز هویت شما را ذخیره نخواهد کرد",
|
||||
"imageGenerationDescription": "برای شروع تولید، AWS AccessKeyId / SecretAccessKey خود را وارد کنید. برنامه پیکربندی احراز هویت شما را ذخیره نمیکند.",
|
||||
"title": "استفاده از اطلاعات احراز هویت سفارشی Bedrock"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
"deepseek": {
|
||||
"description": "DeepSeek یک شرکت متمرکز بر تحقیق و کاربرد فناوری هوش مصنوعی است. مدل جدید آن، DeepSeek-V2.5، تواناییهای مکالمه عمومی و پردازش کد را ترکیب کرده و در زمینههایی مانند همترازی با ترجیحات انسانی، وظایف نوشتاری و پیروی از دستورات بهبود قابل توجهی داشته است."
|
||||
},
|
||||
"fal": {
|
||||
"description": "پلتفرم رسانهای تولیدی برای توسعهدهندگان"
|
||||
},
|
||||
"fireworksai": {
|
||||
"description": "Fireworks AI یک ارائهدهنده پیشرو در خدمات مدلهای زبان پیشرفته است که بر فراخوانی توابع و پردازش چندوجهی تمرکز دارد. جدیدترین مدل آن، Firefunction V2، بر اساس Llama-3 ساخته شده و برای فراخوانی توابع، مکالمه و پیروی از دستورات بهینهسازی شده است. مدل زبان تصویری FireLLaVA-13B از ورودیهای ترکیبی تصویر و متن پشتیبانی میکند. سایر مدلهای قابل توجه شامل سری Llama و سری Mixtral هستند که پشتیبانی کارآمدی از پیروی دستورات چندزبانه و تولید ارائه میدهند."
|
||||
},
|
||||
|
||||
@@ -484,6 +484,11 @@
|
||||
"placeholder": "لطفاً اعلان سفارشی خود را وارد کنید",
|
||||
"title": "اعلان سفارشی"
|
||||
},
|
||||
"generationTopic": {
|
||||
"label": "مدل نامگذاری موضوع نقاشی هوش مصنوعی",
|
||||
"modelDesc": "مدلی که برای نامگذاری خودکار موضوع نقاشی هوش مصنوعی استفاده میشود",
|
||||
"title": "نامگذاری خودکار موضوع نقاشی هوش مصنوعی"
|
||||
},
|
||||
"helpInfo": "هنگام ایجاد دستیار جدید، تنظیمات پیشفرض دستیار به عنوان مقادیر پیشفرض استفاده خواهد شد.",
|
||||
"historyCompress": {
|
||||
"label": "مدل تاریخچه گفتگو",
|
||||
|
||||
@@ -324,6 +324,7 @@
|
||||
}
|
||||
},
|
||||
"tab": {
|
||||
"aiImage": "Peinture IA",
|
||||
"chat": "Conversation",
|
||||
"discover": "Découvrir",
|
||||
"files": "Fichiers",
|
||||
|
||||
@@ -68,6 +68,15 @@
|
||||
"GoBack": {
|
||||
"back": "Retour"
|
||||
},
|
||||
"ImageUpload": {
|
||||
"actions": {
|
||||
"changeImage": "Cliquez pour changer l'image"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "Ajouter une image",
|
||||
"secondary": "Cliquez pour télécharger"
|
||||
}
|
||||
},
|
||||
"MaxTokenSlider": {
|
||||
"unlimited": "Illimité"
|
||||
},
|
||||
@@ -91,6 +100,25 @@
|
||||
"provider": "Fournisseur",
|
||||
"title": "Modèle"
|
||||
},
|
||||
"MultiImagesUpload": {
|
||||
"actions": {
|
||||
"uploadMore": "Cliquez pour télécharger plus"
|
||||
},
|
||||
"modal": {
|
||||
"complete": "Terminé",
|
||||
"newFileIndicator": "Nouveau",
|
||||
"selectImageToPreview": "Veuillez sélectionner une image à prévisualiser",
|
||||
"title": "Gérer les images ({{count}})",
|
||||
"upload": "Télécharger des images"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "Cliquez pour télécharger des images",
|
||||
"secondary": "Prise en charge de la sélection de plusieurs images"
|
||||
},
|
||||
"progress": {
|
||||
"uploadingWithCount": "{{completed}}/{{total}} téléchargées"
|
||||
}
|
||||
},
|
||||
"OllamaSetupGuide": {
|
||||
"action": {
|
||||
"close": "Fermer l'invite",
|
||||
|
||||
@@ -130,6 +130,7 @@
|
||||
"addProxyUrl": "Ajouter une adresse de proxy OpenAI (facultatif)",
|
||||
"apiKey": {
|
||||
"description": "Enter your {{name}} API Key to start the session",
|
||||
"imageGenerationDescription": "Saisissez votre clé API {{name}} pour commencer la génération",
|
||||
"title": "Use custom {{name}} API Key"
|
||||
},
|
||||
"closeMessage": "Fermer le message",
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"config": {
|
||||
"aspectRatio": {
|
||||
"label": "Ratio"
|
||||
},
|
||||
"header": {
|
||||
"desc": "Description simple, création immédiate",
|
||||
"title": "Peinture"
|
||||
},
|
||||
"height": {
|
||||
"label": "Hauteur"
|
||||
},
|
||||
"imageNum": {
|
||||
"label": "Nombre d'images"
|
||||
},
|
||||
"imageUrl": {
|
||||
"label": "Image de référence"
|
||||
},
|
||||
"imageUrls": {
|
||||
"label": "Images de référence"
|
||||
},
|
||||
"model": {
|
||||
"label": "Modèle"
|
||||
},
|
||||
"prompt": {
|
||||
"placeholder": "Décrivez ce que vous souhaitez générer"
|
||||
},
|
||||
"seed": {
|
||||
"label": "Graine",
|
||||
"random": "Graine aléatoire"
|
||||
},
|
||||
"size": {
|
||||
"label": "Taille"
|
||||
},
|
||||
"steps": {
|
||||
"label": "Étapes"
|
||||
},
|
||||
"title": "Peinture IA",
|
||||
"width": {
|
||||
"label": "Largeur"
|
||||
}
|
||||
},
|
||||
"generation": {
|
||||
"actions": {
|
||||
"applySeed": "Appliquer la graine",
|
||||
"copyError": "Copier l'erreur",
|
||||
"copyPrompt": "Copier l'invite",
|
||||
"copySeed": "Copier la graine",
|
||||
"delete": "Supprimer",
|
||||
"deleteBatch": "Supprimer le lot",
|
||||
"download": "Télécharger",
|
||||
"downloadFailed": "Échec du téléchargement de l'image",
|
||||
"errorCopied": "Message d'erreur copié dans le presse-papiers",
|
||||
"errorCopyFailed": "Échec de la copie du message d'erreur",
|
||||
"generate": "Générer",
|
||||
"promptCopied": "Invite copiée dans le presse-papiers",
|
||||
"promptCopyFailed": "Échec de la copie de l'invite",
|
||||
"reuseSettings": "Réutiliser les paramètres",
|
||||
"seedApplied": "Graine appliquée à la configuration",
|
||||
"seedApplyFailed": "Échec de l'application de la graine",
|
||||
"seedCopied": "Graine copiée dans le presse-papiers",
|
||||
"seedCopyFailed": "Échec de la copie de la graine"
|
||||
},
|
||||
"metadata": {
|
||||
"count": "{{count}} image(s)"
|
||||
},
|
||||
"status": {
|
||||
"failed": "Échec de la génération",
|
||||
"generating": "Génération en cours..."
|
||||
}
|
||||
},
|
||||
"notSupportGuide": {
|
||||
"desc": "L'instance déployée actuelle utilise un mode base de données client, la fonction de génération d'images IA n'est pas disponible. Veuillez passer au <1>mode de déploiement base de données serveur</1> ou utiliser directement <3>LobeChat Cloud</3>",
|
||||
"features": {
|
||||
"fileIntegration": {
|
||||
"desc": "Intégration approfondie avec le système de gestion de fichiers, les images générées sont automatiquement sauvegardées dans le système de fichiers pour une gestion et organisation unifiées",
|
||||
"title": "Interopérabilité avec le système de fichiers"
|
||||
},
|
||||
"llmAssisted": {
|
||||
"desc": "Combinaison avec les capacités des grands modèles de langage pour optimiser et étendre intelligemment les invites, améliorant la qualité de génération d'images (Bientôt disponible)",
|
||||
"title": "Assistance LLM pour la génération d'images"
|
||||
},
|
||||
"multiProviders": {
|
||||
"desc": "Prise en charge de plusieurs fournisseurs de services de peinture IA, y compris OpenAI gpt-image-1, Google Imagen, FAL.ai, offrant un large choix de modèles",
|
||||
"title": "Support multi-fournisseurs"
|
||||
}
|
||||
},
|
||||
"title": "Le mode de déploiement actuel ne prend pas en charge la peinture IA"
|
||||
},
|
||||
"topic": {
|
||||
"createNew": "Créer un nouveau sujet",
|
||||
"deleteConfirm": "Supprimer le sujet généré",
|
||||
"deleteConfirmDesc": "Vous êtes sur le point de supprimer ce sujet généré. Cette action est irréversible, veuillez procéder avec prudence.",
|
||||
"empty": "Aucun sujet généré",
|
||||
"title": "Thème de peinture",
|
||||
"untitled": "Sujet par défaut"
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,10 @@
|
||||
"search": "Recherche",
|
||||
"title": "Découvrir"
|
||||
},
|
||||
"image": {
|
||||
"description": "{{appName}} vous offre la meilleure expérience d'utilisation de GPT Image, Flux, Midjourney, Stable Diffusion",
|
||||
"title": "Peinture IA"
|
||||
},
|
||||
"plugins": {
|
||||
"description": "Recherche, génération de graphiques, académique, génération d'images, génération de vidéos, génération de voix, flux de travail automatisés, personnalisez les capacités de plugins ToolCall pour ChatGPT / Claude",
|
||||
"title": "Marché des plugins"
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
"customRegion": "Région de service personnalisée",
|
||||
"customSessionToken": "Jeton de session personnalisé",
|
||||
"description": "Entrez votre ID de clé d'accès AWS / SecretAccessKey pour commencer la session. L'application ne stockera pas votre configuration d'authentification.",
|
||||
"imageGenerationDescription": "Saisissez votre AWS AccessKeyId / SecretAccessKey pour commencer la génération. L'application ne conservera pas vos informations d'authentification.",
|
||||
"title": "Utiliser des informations d'authentification Bedrock personnalisées"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
"deepseek": {
|
||||
"description": "DeepSeek est une entreprise spécialisée dans la recherche et l'application des technologies d'intelligence artificielle, dont le dernier modèle, DeepSeek-V2.5, combine des capacités de dialogue général et de traitement de code, réalisant des améliorations significatives dans l'alignement des préférences humaines, les tâches d'écriture et le suivi des instructions."
|
||||
},
|
||||
"fal": {
|
||||
"description": "Plateforme média générative destinée aux développeurs"
|
||||
},
|
||||
"fireworksai": {
|
||||
"description": "Fireworks AI est un fournisseur de services de modèles linguistiques avancés, axé sur les appels de fonction et le traitement multimodal. Son dernier modèle, Firefunction V2, basé sur Llama-3, est optimisé pour les appels de fonction, les dialogues et le suivi des instructions. Le modèle de langage visuel FireLLaVA-13B prend en charge les entrées mixtes d'images et de texte. D'autres modèles notables incluent la série Llama et la série Mixtral, offrant un support efficace pour le suivi et la génération d'instructions multilingues."
|
||||
},
|
||||
|
||||
@@ -484,6 +484,11 @@
|
||||
"placeholder": "Veuillez entrer le mot-clé personnalisé",
|
||||
"title": "Mot-clé personnalisé"
|
||||
},
|
||||
"generationTopic": {
|
||||
"label": "Modèle de nomination de sujets pour peinture IA",
|
||||
"modelDesc": "Modèle spécifiquement utilisé pour la nomination automatique des sujets de peinture IA",
|
||||
"title": "Nomination automatique des sujets de peinture IA"
|
||||
},
|
||||
"helpInfo": "Lors de la création d'un nouvel assistant, les paramètres par défaut de l'assistant seront utilisés comme valeurs par défaut.",
|
||||
"historyCompress": {
|
||||
"label": "Modèle d'historique de conversation",
|
||||
|
||||
@@ -324,6 +324,7 @@
|
||||
}
|
||||
},
|
||||
"tab": {
|
||||
"aiImage": "Disegno AI",
|
||||
"chat": "Chat",
|
||||
"discover": "Scopri",
|
||||
"files": "File",
|
||||
|
||||
@@ -68,6 +68,15 @@
|
||||
"GoBack": {
|
||||
"back": "Indietro"
|
||||
},
|
||||
"ImageUpload": {
|
||||
"actions": {
|
||||
"changeImage": "Clicca per cambiare immagine"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "Aggiungi immagine",
|
||||
"secondary": "Clicca per caricare"
|
||||
}
|
||||
},
|
||||
"MaxTokenSlider": {
|
||||
"unlimited": "Illimitato"
|
||||
},
|
||||
@@ -91,6 +100,25 @@
|
||||
"provider": "Provider",
|
||||
"title": "Modello"
|
||||
},
|
||||
"MultiImagesUpload": {
|
||||
"actions": {
|
||||
"uploadMore": "Clicca per caricare altre"
|
||||
},
|
||||
"modal": {
|
||||
"complete": "Completa",
|
||||
"newFileIndicator": "Nuovo",
|
||||
"selectImageToPreview": "Seleziona un'immagine da visualizzare in anteprima",
|
||||
"title": "Gestisci immagini ({{count}})",
|
||||
"upload": "Carica immagine"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "Clicca per caricare immagini",
|
||||
"secondary": "Supporta la selezione di più immagini"
|
||||
},
|
||||
"progress": {
|
||||
"uploadingWithCount": "{{completed}}/{{total}} caricati"
|
||||
}
|
||||
},
|
||||
"OllamaSetupGuide": {
|
||||
"action": {
|
||||
"close": "Chiudi avviso",
|
||||
|
||||
@@ -130,6 +130,7 @@
|
||||
"addProxyUrl": "Aggiungi URL del proxy OpenAI (opzionale)",
|
||||
"apiKey": {
|
||||
"description": "Inserisci la tua Chiave API {{name}} per iniziare la sessione",
|
||||
"imageGenerationDescription": "Inserisci la tua chiave API {{name}} per iniziare a generare",
|
||||
"title": "Usa la tua Chiave API personalizzata {{name}}"
|
||||
},
|
||||
"closeMessage": "Chiudi messaggio",
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"config": {
|
||||
"aspectRatio": {
|
||||
"label": "Rapporto"
|
||||
},
|
||||
"header": {
|
||||
"desc": "Descrizione semplice, crea subito",
|
||||
"title": "Pittura"
|
||||
},
|
||||
"height": {
|
||||
"label": "Altezza"
|
||||
},
|
||||
"imageNum": {
|
||||
"label": "Numero di immagini"
|
||||
},
|
||||
"imageUrl": {
|
||||
"label": "Immagine di riferimento"
|
||||
},
|
||||
"imageUrls": {
|
||||
"label": "Immagini di riferimento"
|
||||
},
|
||||
"model": {
|
||||
"label": "Modello"
|
||||
},
|
||||
"prompt": {
|
||||
"placeholder": "Descrivi ciò che desideri generare"
|
||||
},
|
||||
"seed": {
|
||||
"label": "Seed",
|
||||
"random": "Seme casuale"
|
||||
},
|
||||
"size": {
|
||||
"label": "Dimensione"
|
||||
},
|
||||
"steps": {
|
||||
"label": "Passaggi"
|
||||
},
|
||||
"title": "Disegno AI",
|
||||
"width": {
|
||||
"label": "Larghezza"
|
||||
}
|
||||
},
|
||||
"generation": {
|
||||
"actions": {
|
||||
"applySeed": "Applica seme",
|
||||
"copyError": "Copia errore",
|
||||
"copyPrompt": "Copia suggerimento",
|
||||
"copySeed": "Copia seed",
|
||||
"delete": "Elimina",
|
||||
"deleteBatch": "Elimina batch",
|
||||
"download": "Scarica",
|
||||
"downloadFailed": "Download immagine fallito",
|
||||
"errorCopied": "Messaggio di errore copiato negli appunti",
|
||||
"errorCopyFailed": "Copia messaggio di errore fallita",
|
||||
"generate": "Genera",
|
||||
"promptCopied": "Prompt copiato negli appunti",
|
||||
"promptCopyFailed": "Copia prompt fallita",
|
||||
"reuseSettings": "Riutilizza impostazioni",
|
||||
"seedApplied": "Seme applicato alla configurazione",
|
||||
"seedApplyFailed": "Applicazione del seme fallita",
|
||||
"seedCopied": "Seed copiato negli appunti",
|
||||
"seedCopyFailed": "Copia seed fallita"
|
||||
},
|
||||
"metadata": {
|
||||
"count": "{{count}} immagini"
|
||||
},
|
||||
"status": {
|
||||
"failed": "Generazione fallita",
|
||||
"generating": "Generazione in corso..."
|
||||
}
|
||||
},
|
||||
"notSupportGuide": {
|
||||
"desc": "L'istanza attuale è in modalità database client e non supporta la generazione di immagini AI. Passa alla <1>modalità di distribuzione database server</1> o usa direttamente <3>LobeChat Cloud</3>",
|
||||
"features": {
|
||||
"fileIntegration": {
|
||||
"desc": "Integrazione profonda con il sistema di gestione file, le immagini generate vengono salvate automaticamente nel file system per una gestione e organizzazione unificata",
|
||||
"title": "Integrazione con file system"
|
||||
},
|
||||
"llmAssisted": {
|
||||
"desc": "Combina le capacità dei grandi modelli linguistici per ottimizzare e ampliare intelligentemente i prompt, migliorando la qualità della generazione delle immagini (Prossimamente)",
|
||||
"title": "Generazione assistita da LLM"
|
||||
},
|
||||
"multiProviders": {
|
||||
"desc": "Supporta diversi fornitori di servizi di disegno AI, inclusi OpenAI gpt-image-1, Google Imagen, FAL.ai, offrendo una vasta scelta di modelli",
|
||||
"title": "Supporto multi-fornitori"
|
||||
}
|
||||
},
|
||||
"title": "La modalità di distribuzione attuale non supporta il disegno AI"
|
||||
},
|
||||
"topic": {
|
||||
"createNew": "Crea nuovo argomento",
|
||||
"deleteConfirm": "Elimina argomento generato",
|
||||
"deleteConfirmDesc": "Stai per eliminare questo argomento generato. L'eliminazione è irreversibile, procedi con cautela.",
|
||||
"empty": "Nessun argomento generato",
|
||||
"title": "Tema della pittura",
|
||||
"untitled": "Argomento predefinito"
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,10 @@
|
||||
"search": "Cerca",
|
||||
"title": "Scopri"
|
||||
},
|
||||
"image": {
|
||||
"description": "{{appName}} ti offre la migliore esperienza d'uso con GPT Image, Flux, Midjourney, Stable Diffusion",
|
||||
"title": "Disegno AI"
|
||||
},
|
||||
"plugins": {
|
||||
"description": "Ricerca, generazione di grafici, accademico, generazione di immagini, generazione di video, generazione vocale, flussi di lavoro automatizzati, personalizza le capacità dei plugin ToolCall esclusivi di ChatGPT / Claude",
|
||||
"title": "Mercato dei plugin"
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
"customRegion": "Regione del servizio personalizzata",
|
||||
"customSessionToken": "Token di sessione personalizzato",
|
||||
"description": "Inserisci la tua chiave di accesso AWS AccessKeyId / SecretAccessKey per avviare la sessione. L'applicazione non memorizzerà la tua configurazione di autenticazione",
|
||||
"imageGenerationDescription": "Inserisci il tuo AWS AccessKeyId / SecretAccessKey per iniziare a generare. L'applicazione non registrerà le tue credenziali di autenticazione",
|
||||
"title": "Usa le informazioni di autenticazione Bedrock personalizzate"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
"deepseek": {
|
||||
"description": "DeepSeek è un'azienda focalizzata sulla ricerca e applicazione della tecnologia AI, il cui ultimo modello DeepSeek-V2.5 combina capacità di dialogo generico e elaborazione del codice, realizzando miglioramenti significativi nell'allineamento delle preferenze umane, nei compiti di scrittura e nel rispetto delle istruzioni."
|
||||
},
|
||||
"fal": {
|
||||
"description": "Piattaforma di media generativi rivolta agli sviluppatori"
|
||||
},
|
||||
"fireworksai": {
|
||||
"description": "Fireworks AI è un fornitore leader di servizi di modelli linguistici avanzati, focalizzato su chiamate funzionali e elaborazione multimodale. Il suo ultimo modello Firefunction V2, basato su Llama-3, è ottimizzato per chiamate di funzione, dialogo e rispetto delle istruzioni. Il modello di linguaggio visivo FireLLaVA-13B supporta input misti di immagini e testo. Altri modelli notevoli includono la serie Llama e la serie Mixtral, offrendo supporto efficiente per il rispetto e la generazione di istruzioni multilingue."
|
||||
},
|
||||
|
||||
@@ -484,6 +484,11 @@
|
||||
"placeholder": "Inserisci il suggerimento personalizzato",
|
||||
"title": "Suggerimento personalizzato"
|
||||
},
|
||||
"generationTopic": {
|
||||
"label": "Modello di denominazione argomenti per disegno AI",
|
||||
"modelDesc": "Modello specificato per la denominazione automatica degli argomenti nel disegno AI",
|
||||
"title": "Denominazione automatica argomenti per disegno AI"
|
||||
},
|
||||
"helpInfo": "Quando crei un nuovo assistente, verranno utilizzate le impostazioni predefinite dell'assistente come valori predefiniti.",
|
||||
"historyCompress": {
|
||||
"label": "Modello di storia delle conversazioni",
|
||||
|
||||
@@ -324,6 +324,7 @@
|
||||
}
|
||||
},
|
||||
"tab": {
|
||||
"aiImage": "AI 画像生成",
|
||||
"chat": "チャット",
|
||||
"discover": "発見",
|
||||
"files": "ファイル",
|
||||
|
||||
@@ -68,6 +68,15 @@
|
||||
"GoBack": {
|
||||
"back": "戻る"
|
||||
},
|
||||
"ImageUpload": {
|
||||
"actions": {
|
||||
"changeImage": "クリックして画像を変更"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "画像を追加",
|
||||
"secondary": "クリックしてアップロード"
|
||||
}
|
||||
},
|
||||
"MaxTokenSlider": {
|
||||
"unlimited": "無制限"
|
||||
},
|
||||
@@ -91,6 +100,25 @@
|
||||
"provider": "プロバイダー",
|
||||
"title": "モデル"
|
||||
},
|
||||
"MultiImagesUpload": {
|
||||
"actions": {
|
||||
"uploadMore": "さらにアップロード"
|
||||
},
|
||||
"modal": {
|
||||
"complete": "完了",
|
||||
"newFileIndicator": "新規追加",
|
||||
"selectImageToPreview": "プレビューする画像を選択してください",
|
||||
"title": "画像管理 ({{count}})",
|
||||
"upload": "画像をアップロード"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "クリックして画像をアップロード",
|
||||
"secondary": "複数の画像を選択可能"
|
||||
},
|
||||
"progress": {
|
||||
"uploadingWithCount": "{{completed}}/{{total}} アップロード済み"
|
||||
}
|
||||
},
|
||||
"OllamaSetupGuide": {
|
||||
"action": {
|
||||
"close": "ヒントを閉じる",
|
||||
|
||||
@@ -130,6 +130,7 @@
|
||||
"addProxyUrl": "OpenAI 代理アドレスを追加する(オプション)",
|
||||
"apiKey": {
|
||||
"description": "{{name}} APIキーを入力してセッションを開始します。",
|
||||
"imageGenerationDescription": "{{name}} の API キーを入力すると、生成を開始できます",
|
||||
"title": "カスタム{{name}} APIキーを使用"
|
||||
},
|
||||
"closeMessage": "ヒントを閉じる",
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"config": {
|
||||
"aspectRatio": {
|
||||
"label": "比率"
|
||||
},
|
||||
"header": {
|
||||
"desc": "簡単な説明、すぐに創作",
|
||||
"title": "絵画"
|
||||
},
|
||||
"height": {
|
||||
"label": "高さ"
|
||||
},
|
||||
"imageNum": {
|
||||
"label": "画像数"
|
||||
},
|
||||
"imageUrl": {
|
||||
"label": "参考画像"
|
||||
},
|
||||
"imageUrls": {
|
||||
"label": "参考画像"
|
||||
},
|
||||
"model": {
|
||||
"label": "モデル"
|
||||
},
|
||||
"prompt": {
|
||||
"placeholder": "生成したい内容を記述してください"
|
||||
},
|
||||
"seed": {
|
||||
"label": "シード",
|
||||
"random": "ランダムシード"
|
||||
},
|
||||
"size": {
|
||||
"label": "サイズ"
|
||||
},
|
||||
"steps": {
|
||||
"label": "ステップ数"
|
||||
},
|
||||
"title": "AI 絵画",
|
||||
"width": {
|
||||
"label": "幅"
|
||||
}
|
||||
},
|
||||
"generation": {
|
||||
"actions": {
|
||||
"applySeed": "シードを適用する",
|
||||
"copyError": "エラー情報をコピー",
|
||||
"copyPrompt": "プロンプトをコピー",
|
||||
"copySeed": "シードをコピー",
|
||||
"delete": "削除",
|
||||
"deleteBatch": "バッチを削除",
|
||||
"download": "ダウンロード",
|
||||
"downloadFailed": "画像のダウンロードに失敗しました",
|
||||
"errorCopied": "エラー情報がクリップボードにコピーされました",
|
||||
"errorCopyFailed": "エラー情報のコピーに失敗しました",
|
||||
"generate": "生成",
|
||||
"promptCopied": "プロンプトがクリップボードにコピーされました",
|
||||
"promptCopyFailed": "プロンプトのコピーに失敗しました",
|
||||
"reuseSettings": "設定を再利用",
|
||||
"seedApplied": "シードが設定に適用されました",
|
||||
"seedApplyFailed": "シードの適用に失敗しました",
|
||||
"seedCopied": "シードがクリップボードにコピーされました",
|
||||
"seedCopyFailed": "シードのコピーに失敗しました"
|
||||
},
|
||||
"metadata": {
|
||||
"count": "{{count}} 枚の画像"
|
||||
},
|
||||
"status": {
|
||||
"failed": "生成失敗",
|
||||
"generating": "生成中..."
|
||||
}
|
||||
},
|
||||
"notSupportGuide": {
|
||||
"desc": "現在のデプロイはクライアントデータベースモードのため、AI画像生成機能は使用できません。<1>サーバーデータベースデプロイモード</1>に切り替えるか、直接 <3>LobeChat Cloud</3> をご利用ください。",
|
||||
"features": {
|
||||
"fileIntegration": {
|
||||
"desc": "ファイル管理システムと深く統合され、生成された画像は自動的にファイルシステムに保存され、統一的な管理と整理が可能です",
|
||||
"title": "ファイルシステム連携"
|
||||
},
|
||||
"llmAssisted": {
|
||||
"desc": "大規模言語モデルの能力を活用し、プロンプトの最適化と拡張を行い、画像生成の品質を向上させます(近日公開予定)",
|
||||
"title": "LLM支援生成"
|
||||
},
|
||||
"multiProviders": {
|
||||
"desc": "OpenAI gpt-image-1、Google Imagen、FAL.ai など複数のAI絵画サービスプロバイダーをサポートし、多彩なモデル選択を提供します",
|
||||
"title": "複数プロバイダー対応"
|
||||
}
|
||||
},
|
||||
"title": "現在のデプロイモードはAI絵画をサポートしていません"
|
||||
},
|
||||
"topic": {
|
||||
"createNew": "新しいテーマを作成",
|
||||
"deleteConfirm": "生成テーマを削除",
|
||||
"deleteConfirmDesc": "この生成テーマを削除すると復元できません。慎重に操作してください。",
|
||||
"empty": "生成されたテーマはありません",
|
||||
"title": "絵画のテーマ",
|
||||
"untitled": "デフォルトテーマ"
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,10 @@
|
||||
"search": "検索",
|
||||
"title": "発見"
|
||||
},
|
||||
"image": {
|
||||
"description": "{{appName}} が最高の GPT 画像、Flux、Midjourney、Stable Diffusion の使用体験をお届けします",
|
||||
"title": "AI 絵画"
|
||||
},
|
||||
"plugins": {
|
||||
"description": "検索、グラフ生成、学術、画像生成、動画生成、音声生成、自動化ワークフロー、ChatGPT / Claude専用のToolCallプラグイン機能をカスタマイズ",
|
||||
"title": "プラグインマーケット"
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
"customRegion": "カスタムサービスリージョン",
|
||||
"customSessionToken": "カスタムセッショントークン",
|
||||
"description": "AWS AccessKeyId / SecretAccessKey を入力するとセッションを開始できます。アプリは認証情報を記録しません",
|
||||
"imageGenerationDescription": "AWSのAccessKeyId / SecretAccessKeyを入力すると、生成を開始できます。アプリは認証情報を記録しません。",
|
||||
"title": "使用カスタム Bedrock 認証情報"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
"deepseek": {
|
||||
"description": "DeepSeekは、人工知能技術の研究と応用に特化した企業であり、最新のモデルDeepSeek-V2.5は、汎用対話とコード処理能力を融合させ、人間の好みの整合、ライティングタスク、指示の遵守などの面で顕著な向上を実現しています。"
|
||||
},
|
||||
"fal": {
|
||||
"description": "開発者向けの生成型メディアプラットフォーム"
|
||||
},
|
||||
"fireworksai": {
|
||||
"description": "Fireworks AIは、先進的な言語モデルサービスのリーダーであり、機能呼び出しと多モーダル処理に特化しています。最新のモデルFirefunction V2はLlama-3に基づいており、関数呼び出し、対話、指示の遵守に最適化されています。視覚言語モデルFireLLaVA-13Bは、画像とテキストの混合入力をサポートしています。他の注目すべきモデルには、LlamaシリーズやMixtralシリーズがあり、高効率の多言語指示遵守と生成サポートを提供しています。"
|
||||
},
|
||||
|
||||
@@ -484,6 +484,11 @@
|
||||
"placeholder": "カスタムプロンプトを入力してください",
|
||||
"title": "カスタムプロンプト"
|
||||
},
|
||||
"generationTopic": {
|
||||
"label": "AI絵画トピック命名モデル",
|
||||
"modelDesc": "AI絵画の自動トピック命名に使用されるモデルを指定します",
|
||||
"title": "AI絵画自動トピック命名"
|
||||
},
|
||||
"helpInfo": "新しいアシスタントを作成するとき、デフォルトのアシスタント設定がプリセット値として使用されます。",
|
||||
"historyCompress": {
|
||||
"label": "会話履歴モデル",
|
||||
|
||||
@@ -324,6 +324,7 @@
|
||||
}
|
||||
},
|
||||
"tab": {
|
||||
"aiImage": "AI 그림",
|
||||
"chat": "채팅",
|
||||
"discover": "발견하기",
|
||||
"files": "파일",
|
||||
|
||||
@@ -68,6 +68,15 @@
|
||||
"GoBack": {
|
||||
"back": "뒤로 가기"
|
||||
},
|
||||
"ImageUpload": {
|
||||
"actions": {
|
||||
"changeImage": "클릭하여 이미지 변경"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "이미지 추가",
|
||||
"secondary": "클릭하여 업로드"
|
||||
}
|
||||
},
|
||||
"MaxTokenSlider": {
|
||||
"unlimited": "무제한"
|
||||
},
|
||||
@@ -91,6 +100,25 @@
|
||||
"provider": "제공자",
|
||||
"title": "모델"
|
||||
},
|
||||
"MultiImagesUpload": {
|
||||
"actions": {
|
||||
"uploadMore": "더 업로드하려면 클릭"
|
||||
},
|
||||
"modal": {
|
||||
"complete": "완료",
|
||||
"newFileIndicator": "새로 추가됨",
|
||||
"selectImageToPreview": "미리 볼 이미지를 선택하세요",
|
||||
"title": "이미지 관리 ({{count}})",
|
||||
"upload": "이미지 업로드"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "클릭하여 이미지 업로드",
|
||||
"secondary": "여러 이미지 선택 가능"
|
||||
},
|
||||
"progress": {
|
||||
"uploadingWithCount": "{{completed}}/{{total}} 업로드 완료"
|
||||
}
|
||||
},
|
||||
"OllamaSetupGuide": {
|
||||
"action": {
|
||||
"close": "팝업 닫기",
|
||||
|
||||
@@ -130,6 +130,7 @@
|
||||
"addProxyUrl": "OpenAI 프록시 주소 추가(선택 사항)",
|
||||
"apiKey": {
|
||||
"description": "{{name}} API 키를 입력하면 세션을 시작할 수 있습니다.",
|
||||
"imageGenerationDescription": "{{name}} API 키를 입력하면 생성이 시작됩니다",
|
||||
"title": "사용자 정의 {{name}} API 키 사용"
|
||||
},
|
||||
"closeMessage": "알림 닫기",
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"config": {
|
||||
"aspectRatio": {
|
||||
"label": "비율"
|
||||
},
|
||||
"header": {
|
||||
"desc": "간단한 설명, 즉시 창작",
|
||||
"title": "그림 그리기"
|
||||
},
|
||||
"height": {
|
||||
"label": "높이"
|
||||
},
|
||||
"imageNum": {
|
||||
"label": "이미지 수"
|
||||
},
|
||||
"imageUrl": {
|
||||
"label": "참고 이미지"
|
||||
},
|
||||
"imageUrls": {
|
||||
"label": "참고 이미지"
|
||||
},
|
||||
"model": {
|
||||
"label": "모델"
|
||||
},
|
||||
"prompt": {
|
||||
"placeholder": "생성하고 싶은 내용을 설명하세요"
|
||||
},
|
||||
"seed": {
|
||||
"label": "시드",
|
||||
"random": "무작위 시드"
|
||||
},
|
||||
"size": {
|
||||
"label": "크기"
|
||||
},
|
||||
"steps": {
|
||||
"label": "단계 수"
|
||||
},
|
||||
"title": "AI 그림",
|
||||
"width": {
|
||||
"label": "너비"
|
||||
}
|
||||
},
|
||||
"generation": {
|
||||
"actions": {
|
||||
"applySeed": "시드 적용",
|
||||
"copyError": "오류 정보 복사",
|
||||
"copyPrompt": "프롬프트 복사",
|
||||
"copySeed": "시드 복사",
|
||||
"delete": "삭제",
|
||||
"deleteBatch": "배치 삭제",
|
||||
"download": "다운로드",
|
||||
"downloadFailed": "이미지 다운로드 실패",
|
||||
"errorCopied": "오류 정보가 클립보드에 복사되었습니다",
|
||||
"errorCopyFailed": "오류 정보 복사 실패",
|
||||
"generate": "생성",
|
||||
"promptCopied": "프롬프트가 클립보드에 복사되었습니다",
|
||||
"promptCopyFailed": "프롬프트 복사 실패",
|
||||
"reuseSettings": "설정 재사용",
|
||||
"seedApplied": "시드가 설정에 적용되었습니다",
|
||||
"seedApplyFailed": "시드 적용 실패",
|
||||
"seedCopied": "시드가 클립보드에 복사되었습니다",
|
||||
"seedCopyFailed": "시드 복사 실패"
|
||||
},
|
||||
"metadata": {
|
||||
"count": "{{count}}장 이미지"
|
||||
},
|
||||
"status": {
|
||||
"failed": "생성 실패",
|
||||
"generating": "생성 중..."
|
||||
}
|
||||
},
|
||||
"notSupportGuide": {
|
||||
"desc": "현재 배포 인스턴스는 클라이언트 데이터베이스 모드로 AI 이미지 생성 기능을 사용할 수 없습니다. <1>서버 데이터베이스 배포 모드</1>로 전환하거나 <3>LobeChat Cloud</3>를 직접 사용하세요.",
|
||||
"features": {
|
||||
"fileIntegration": {
|
||||
"desc": "파일 관리 시스템과 깊이 통합되어 생성된 이미지를 자동으로 파일 시스템에 저장하며, 통합 관리와 조직을 지원합니다.",
|
||||
"title": "파일 시스템 연동"
|
||||
},
|
||||
"llmAssisted": {
|
||||
"desc": "대형 언어 모델 기능을 결합하여 프롬프트를 지능적으로 최적화 및 확장하여 이미지 생성 품질을 향상시킵니다 (곧 제공 예정)",
|
||||
"title": "LLM 지원 이미지 생성"
|
||||
},
|
||||
"multiProviders": {
|
||||
"desc": "OpenAI gpt-image-1, Google Imagen, FAL.ai 등 다양한 AI 그림 서비스 제공자를 지원하여 풍부한 모델 선택을 제공합니다.",
|
||||
"title": "다중 제공자 지원"
|
||||
}
|
||||
},
|
||||
"title": "현재 배포 모드는 AI 그림 생성을 지원하지 않습니다"
|
||||
},
|
||||
"topic": {
|
||||
"createNew": "새 주제 생성",
|
||||
"deleteConfirm": "생성 주제 삭제",
|
||||
"deleteConfirmDesc": "이 생성 주제를 삭제하면 복구할 수 없습니다. 신중히 진행해 주세요.",
|
||||
"empty": "생성된 주제가 없습니다",
|
||||
"title": "그림 주제",
|
||||
"untitled": "기본 주제"
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,10 @@
|
||||
"search": "검색",
|
||||
"title": "발견"
|
||||
},
|
||||
"image": {
|
||||
"description": "{{appName}}가 최고의 GPT 이미지, Flux, Midjourney, Stable Diffusion 사용 경험을 제공합니다",
|
||||
"title": "AI 그림"
|
||||
},
|
||||
"plugins": {
|
||||
"description": "검색, 차트 생성, 학술, 이미지 생성, 비디오 생성, 음성 생성, 자동화 워크플로우, ChatGPT / Claude 전용 ToolCall 플러그인 기능을 맞춤 설정하세요",
|
||||
"title": "플러그인 마켓"
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
"customRegion": "사용자 정의 서비스 지역",
|
||||
"customSessionToken": "사용자 정의 세션 토큰",
|
||||
"description": "AWS AccessKeyId / SecretAccessKey를 입력하면 세션이 시작됩니다. 애플리케이션은 인증 구성을 기록하지 않습니다.",
|
||||
"imageGenerationDescription": "AWS AccessKeyId / SecretAccessKey를 입력하면 생성이 시작됩니다. 애플리케이션은 인증 구성을 기록하지 않습니다.",
|
||||
"title": "사용자 정의 Bedrock 인증 정보 사용"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
"deepseek": {
|
||||
"description": "DeepSeek는 인공지능 기술 연구 및 응용에 집중하는 회사로, 최신 모델인 DeepSeek-V2.5는 일반 대화 및 코드 처리 능력을 통합하고 인간의 선호 정렬, 작문 작업 및 지시 따르기 등에서 상당한 향상을 이루었습니다."
|
||||
},
|
||||
"fal": {
|
||||
"description": "개발자를 위한 생성형 미디어 플랫폼"
|
||||
},
|
||||
"fireworksai": {
|
||||
"description": "Fireworks AI는 기능 호출 및 다중 모드 처리를 전문으로 하는 선도적인 고급 언어 모델 서비스 제공업체입니다. 최신 모델인 Firefunction V2는 Llama-3를 기반으로 하며, 함수 호출, 대화 및 지시 따르기에 최적화되어 있습니다. 비주얼 언어 모델인 FireLLaVA-13B는 이미지와 텍스트 혼합 입력을 지원합니다. 기타 주목할 만한 모델로는 Llama 시리즈와 Mixtral 시리즈가 있으며, 효율적인 다국어 지시 따르기 및 생성 지원을 제공합니다."
|
||||
},
|
||||
|
||||
@@ -484,6 +484,11 @@
|
||||
"placeholder": "사용자 정의 프롬프트 입력",
|
||||
"title": "사용자 정의 프롬프트"
|
||||
},
|
||||
"generationTopic": {
|
||||
"label": "AI 그림 주제 명명 모델",
|
||||
"modelDesc": "AI 그림 자동 주제 명명에 사용되는 모델 지정",
|
||||
"title": "AI 그림 자동 주제 명명"
|
||||
},
|
||||
"helpInfo": "새 도우미를 생성할 때 기본 도우미 설정이 기본값으로 사용됩니다.",
|
||||
"historyCompress": {
|
||||
"label": "대화 기록 모델",
|
||||
|
||||
@@ -324,6 +324,7 @@
|
||||
}
|
||||
},
|
||||
"tab": {
|
||||
"aiImage": "AI-afbeelding",
|
||||
"chat": "Chat",
|
||||
"discover": "Ontdekken",
|
||||
"files": "Bestanden",
|
||||
|
||||
@@ -68,6 +68,15 @@
|
||||
"GoBack": {
|
||||
"back": "Terug"
|
||||
},
|
||||
"ImageUpload": {
|
||||
"actions": {
|
||||
"changeImage": "Klik om afbeelding te wijzigen"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "Afbeelding toevoegen",
|
||||
"secondary": "Klik om te uploaden"
|
||||
}
|
||||
},
|
||||
"MaxTokenSlider": {
|
||||
"unlimited": "Onbeperkt"
|
||||
},
|
||||
@@ -91,6 +100,25 @@
|
||||
"provider": "Provider",
|
||||
"title": "Model"
|
||||
},
|
||||
"MultiImagesUpload": {
|
||||
"actions": {
|
||||
"uploadMore": "Klik om meer te uploaden"
|
||||
},
|
||||
"modal": {
|
||||
"complete": "Voltooien",
|
||||
"newFileIndicator": "Nieuw",
|
||||
"selectImageToPreview": "Selecteer een afbeelding om te bekijken",
|
||||
"title": "Beheer afbeeldingen ({{count}})",
|
||||
"upload": "Afbeeldingen uploaden"
|
||||
},
|
||||
"placeholder": {
|
||||
"primary": "Klik om afbeeldingen te uploaden",
|
||||
"secondary": "Meerdere afbeeldingen selecteren ondersteund"
|
||||
},
|
||||
"progress": {
|
||||
"uploadingWithCount": "{{completed}}/{{total}} geüpload"
|
||||
}
|
||||
},
|
||||
"OllamaSetupGuide": {
|
||||
"action": {
|
||||
"close": "Sluit melding",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user