马良AI写作初始化仓库

This commit is contained in:
邓滨杰
2025-09-10 00:07:52 +08:00
parent 3c06bb1a03
commit 39c0f8840f
1309 changed files with 318528 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
---
description:
globs:
alwaysApply: false
---
# Backend Structure (AINovalServer - Spring Boot)
- **Entry Point**: [src/main/java/com/ainovel/server/AiNovelServerApplication.java](mdc:AINovalServer/src/main/java/com/ainovel/server/AiNovelServerApplication.java)
- **Dependencies**: [pom.xml](mdc:AINovalServer/pom.xml)
- **Main Configuration**: [src/main/resources/application.yml](mdc:AINovalServer/src/main/resources/application.yml)
- **Environment Configs**: Located in `src/main/resources/` (e.g., `application-dev.yml`)
- **Source Code**: `src/main/java/com/ainovel/server/`
- `common/`: Common utilities and constants
- `config/`: Configuration classes (DB, Security, etc.)
- `domain/`: Domain models/entities
- `repository/`: Data access layer (JPA Repositories)
- `security/`: Security configuration and components
- `service/`: Business service layer
- `web/`: Web controllers (REST APIs)
- **Resources**: `src/main/resources/`
- **Tests**: `src/test/`

View File

@@ -0,0 +1,23 @@
---
description:
globs:
alwaysApply: false
---
# Documentation Links
This file provides links to important documentation within the project.
- **Overall Architecture**: [项目架构说明.md](mdc:项目架构说明.md)
- **Version Control Guide**: [版本控制功能说明.md](mdc:版本控制功能说明.md)
- **Frontend README**: [AINoval/README.md](mdc:AINoval/README.md)
- **Backend README**: [AINovalServer/README.md](mdc:AINovalServer/README.md)
- **Backend Performance Testing**: [AINovalServer/PERFORMANCE_TESTING.md](mdc:AINovalServer/PERFORMANCE_TESTING.md)
**Documentation Directories:**
- **Requirements**: `需求文档/`
- **Prototypes/Designs**: `原型图/`
- **Testing Plans**: `测试计划与文档/`
- **Backend Development Docs**: `后端开发文档/`
- **Frontend Iteration Plans**: `前端产品敏捷迭代计划/`
- **Postman Collections**: `postman/`

View File

@@ -0,0 +1,274 @@
---
description:
globs:
alwaysApply: false
---
一、统一前置约定
1. Base URL
AppConfig.apiBaseUrl 内部已拼接 “/api/v1/” 前缀,所有请求 path 必须以 “/” 开头,禁止再次写 /api/v1/**。
示例:`post('/ai-chat/sessions/create')` ✅ `post('/api/v1/ai-chat/sessions/create')` ❌
2. HTTP 方法
• 除个别 GET-SSE小说导入进度所有接口一律使用 POST。
• 请求体、响应体统一 JSONSSE 数据位于 data 字段内,亦是 JSON。
3. 必备请求头
Authorization: Bearer {token}
X-User-Id: {userId}
Content-Type: application/json Multipart 上传除外)
SSE 额外头:
Accept: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
4. novelId 隔离
所有 AI 聊天 / 记忆模式 / 剧情推演及小说相关接口均需 novelId。前端省略将直接 4XX。旧版不带 novelId 方法已 @Deprecated。
────────────────────────────────────────
二、非流式(普通 HTTP调用规范
1. 调用方式
await apiClient.post('/路径', data: {…});
Options 可选;大部分接口已经在 ApiClient 二次封装,优先调用对应 repository 方法。
2. 超时
connect 30s / send 30s / receive 5min已在 ApiClient 配置)
3. 错误处理
后端统一错误 JSON`{ "code": -1, "message": "错误描述", "error": "可选详情" }`
ApiClient 已将 401 拦截并自动调用 AuthService.logout()。其它错误统一抛 ApiException(statusCode,msg)。
────────────────────────────────────────
三、SSE 流式请求规范
1. 前端封装
使用 SseClient().streamEvents<T>(…) 或 ApiClient.postStream + _processStream。
2. 通用请求头与 Options
见「统一请求头」,并在 Dio Options 中声明 responseType: ResponseType.stream。
3. 事件格式(后端 ServerSentEvent
id: {uuid} ❘ 可选
event: {eventName}
data: {JSON 字符串或 [DONE]}
\n\n 分隔多条记录
4. 事件名称白名单
chat-message AI 聊天普通/流式块
chat-error AI 聊天错误
chat-message-memory 记忆模式聊天
outline-chunk 剧情推演
message 通用 AI
complete 通用 AI 结束data 为 {"data":"[DONE]"}
5. 结束判定
• 收到一条 data: [DONE] → 正常结束
• 收到 event: complete → 正常结束
• 服务器主动关闭连接 → onDone
• 本地 5 分钟未收包 → ApiClient 内置心跳超时会自动 addError & close
6. 前端过滤范式(示例 chat_repository_impl
.streamEvents(...).where((event)=>
event.sessionId == currentSession && event.content != 'heartbeat');
────────────────────────────────────────
四、路径与 DTO 命名
1. 路径
POST /{模块}/{动作} 例:/novels/create
POST /{模块}/{资源}/{动作} 例:/ai-chat/messages/stream
SSE 路径保持同 POST 规则,仅响应类型不同。
2. 请求 DTO/VO
• {Action}{Resource}Dto / Request / Response
• SessionCreateDto, ImportPreviewRequest …
• 流式请求的 DTO 放 body不走 query。
────────────────────────────────────────
五、文件上传 & 导入
1. Multipart FormData 字段
file 文件
userId (备用)
2. 三步导入
/upload-preview → 返回 previewSessionId
/preview → 返回章节解析预览
/confirm → 返回 jobId
进度监听 GET /novels/import/{jobId}/status SSE event: data = ImportStatus JSON
3. 长连接心跳
ApiClient.connectToLongRunningSSE 已内建 15s 心跳日志2min 静默 → 本地进度提醒5min → 超时断线。
────────────────────────────────────────
六、特殊模块注意
1. AI 聊天
• 创建会话 /ai-chat/sessions/create
• 流式发消息 /ai-chat/messages/stream Body 必含 userId、novelId、sessionId、content
• metadata 可携带 aiConfig详见 extractAIConfigFromMetadata
• 事件过滤status==streaming 可用于打字机效果,最终完整消息 id 不以 temp_chunk_ 开头。
2. 记忆模式
• 路径加 -with-memoryevent 名改为 chat-message-memory / chat-error-memory。
• 需要 memoryConfig 字段。
3. 剧情推演
• POST /novels/{novelId}/next-outlines/generate-stream
• event: outline-chunk
• 如遇 code+message 错误 JSON解析器需 throw ApiException。
4. Universal AI多功能 AI
• 非流式 /ai/universal/request
• 流式 /ai/universal/stream event: message / complete
• 预估费用 /ai/universal/estimate-cost
• 预览提示 /ai/universal/preview
────────────────────────────────────────
七、客户端实现要点Dart 侧)
1. ApiClient 已封装常用 CRUD优先通过各 Repository避免重复实现。
2. 401 在拦截器中自动登出,无需额外判断。
3. 日志等级AppConfig.logLevel生产默认 info调试可设 warning 输出请求/响应体。
4. 模型 & 配置缓存
ChatRepositoryImpl 内部维护 novelId→sessionId→UniversalAIRequest 缓存,注意同步 & 清理。
5. 批量场景上传
统一使用 /novels/upsert-chapter-scenes-batch数据结构符合 ChapterScenesDto。
────────────────────────────────────────
八、测试 Checklist提交前自检
☐ 请求 path 无 “/api/v1” 重复
☐ 必填头 Authorization / X-User-Id 已附加
☐ POST body 为 JSONSSE 请求 Accept:text/event-stream
☐ novelId 已在 body 或 path 中提供
☐ 错误码 & message 正确解析401 能触发登出
☐ SSE 解析:支持 event/data/id多行合并识别 [DONE]/complete
☐ 心跳或空行已过滤,打字机流块保留
☐ 长连接超时重连(最多 3 次)逻辑正常
☐ 文件上传 Multipart/form-data字段 file / userId
☐ 日志在 debug 模式下可输出请求体 & 响应体
后端约束
一、通用约束
1. 路径前缀
所有 Controller 均挂载在 “/api/v1/**”,切勿在内部拼接重复前缀。
2. 返回类型
• 非流式Mono<T> / Flux<T> ↔ HTTP 200|201。
• 流式 Flux<ServerSentEvent<…>> ↔ Content-Type text/event-stream。
3. DTO & 命名
• 输入 DTOSessionCreateDto / ImportPreviewRequest / PaginatedScenesRequestDto …
• 输出 DTONovelWithScenesDto / ChaptersForPreloadDto …
• 统一放在 web.dto 包;禁止 Controller 直接暴露实体 Entity。
4. 参数校验
• 使用 jakarta.validation @Valid并在 DTO 字段加 @NotBlank @NotNull。
• Controller 若自行拼 Map<String,String>,在进入 Service 前必须手动判空并抛 ResponseStatusException 400。
5. 身份认证
• 使用 @CurrentUser 解析出 userId如为空必须回退表单 userId仍为空则返回 401。
• 鉴权逻辑统一在 Service 层做二次校验session 属主、novel 属主等)。
• jwt配置 SecurityConfig需要增加新端点
6. novelId 隔离
• AIChatService / NovelService 等新接口必须带 novelId 版本,旧方法保留 @Deprecated 标记。
• Controller 在调用旧 Service 时,先 getSession(userId, novelId, sessionId) 校验归属。
7. 错误响应规范
```json
{ "code": -1, "message": "错误描述", "error": "可选堆栈/详情" }
```
• Controller 捕获异常后统一封装,避免直接返回 500 HTML。
• SSE 端点 onErrorResume 时应推送 chat-error / outline-error 之类事件,或者 data: {"code":-1,"message":"xxx"}。
────────────────────────────────────────
二、SSE 端点实现要求
1. 标准包装
```java
ServerSentEvent.<T>builder()
.id(UUID.randomUUID().toString())
.event("chat-message") // 见事件白名单
.data(payload) // payload 为对象,框架自动 JSON 序列化
.retry(Duration.ofSeconds(10))
.build();
```
2. 事件名称
chat-message | chat-error | chat-message-memory | outline-chunk | message | complete
其它请先在前后端约定后再扩展。
3. 结束规则
• 业务方最后 concat 一个 complete / data:[DONE] 信号,或正常 close。
• 服务器不得无限保持空闲长连接;无事件 2-3min 应考虑心跳注释 “:heartbeat”。
4. 流速控制
使用 `.delayElements(Duration.ofMillis(50))` 或下游 buffer避免单秒百条刷屏。
5. 订阅日志
`doOnSubscribe` 记录连接;`doOnCancel` / `doOnError` 记录关闭与异常,方便排障。
────────────────────────────────────────
三、模块专项
1. AI 聊天 (AIChatController)
• createSession / getSession / listSessions / update / delete / count 全量支持 novelId。
• streamMessage() 必须先 extractAIConfigFromMetadata() → UniversalAIRequestDto如无配置降级旧接口。
• 错误时返回 chat-error 事件data 为 AIChatMessagerole=system, status=ERROR
2. 记忆模式
• routes 加后缀 -with-memory事件名 chat-message-memory / chat-error-memory。
• ChatMemoryConfigDto 转 domainService 侧负责窗口剪裁。
3. Novel 管理 (NovelController)
• get-with-paginated-scenes 等分页接口必须校验 chaptersLimit 1-10。
• load-more-scenes direction 仅允许 up/down/center非法值 400。
• 细粒度增删改add-act-fine / delete-scene-fine 等)只处理局部,无需回整本 DTO前端自动拉取最新结构。
• /import 流程upload-preview → preview → confirm每步严格校验必要字段并返回友好错误。
4. Next-Outline (剧情推演)
• generate-stream / regenerate-option 均推 outline-chunk。
• Service 内部 chunk.size 建议 ≤ 5KB过大前端解析慢。
5. Universal AI
• /stream 结尾必须 concat 完成事件 `event:complete data:{"data":"[DONE]"}`。
• /estimate-cost 返回 {success, estimatedCost, errorMessage},不可抛异常给前端。
────────────────────────────────────────
四、性能 & 稳定性
1. I/O 超时
• WebClient/DQL 调 OpenAI 等第三方应限 2min大任务另行异步处理并用 SSE 推进度。
2. 压力保护
• 单 userId 并发流连接 ≤ 10可在 Service 层做计数。
• 若超额返回 429 JSON 并在 SSE 推送 error 事件。
3. 日志
• slf4j 级别info 记录业务流程 & 关键IDdebug 打开 JSON 细节error 打印堆栈。
• 不得在生产输出完整 prompt / apiKey。
────────────────────────────────────────
五、代码质量守则
1. Controller 只做参数检查 + 日志 + 调 Service禁止业务逻辑堆叠。
2. Service 返回 Mono.error 时务必带语义化 message前端直接展示。
3. DTO 层禁止 Lombok @Data使用 @Getter/@Setter 或 record避免 JSON 循环引用。
4. 所有 Mono/Flux 链路结尾必须 `onErrorResume` 友好处理,不能把 Reactor 异常原样抛给客户。
5. 不得在 SSE 控制器里使用 `share()` 导致多次订阅;一个请求一个冷流或 Service 级共享 hot 流。
────────────────────────────────────────
六、提交前检查清单(后端)
☐ 路径不含重复 /api/v1
☐ DTO 字段 @NotBlank 检验通过,全局异常处理返回统一结构
☐ novelId 校验正确,跨用户/跨小说数据隔离
☐ SSE 事件名符合白名单,结尾发送 complete 或 [DONE]
☐ 日志不输出敏感信息(apiKey, prompt)
☐ 新增接口在 Controller + Service + DTO 均写单元测试

View File

@@ -0,0 +1,21 @@
---
description:
globs:
alwaysApply: false
---
# Frontend Structure (AINoval - Flutter)
- **Entry Point**: [lib/main.dart](mdc:AINoval/lib/main.dart)
- **Dependencies**: [pubspec.yaml](mdc:AINoval/pubspec.yaml)
- **Configuration**: [lib/config/app_config.dart](mdc:AINoval/lib/config/app_config.dart)
- **Source Code**: `lib/`
- `blocs/`: Business logic components (State Management)
- `config/`: Configuration files
- `l10n/`: Internationalization resources
- `models/`: Data models
- `repositories/`: Data repositories
- `screens/`: Screen/Page components
- `services/`: Service layer (API calls, etc.)
- `utils/`: Utility classes
- **Assets**: `assets/`
- **Tests**: `test/`

773
.cursor/rules/gloalrule.mdc Normal file
View File

@@ -0,0 +1,773 @@
---
description:
globs:
alwaysApply: false
---
# AI写作软件项目全局配置
project_config:
name: "ai-novel-assistant"
description: "AI驱动的小说创作管理系统"
# 后端配置
backend:
framework: "spring-boot"
version: "3.2.0"
java_version: "23"
base_package: "com.ainovel"
# 前端配置
frontend:
framework: "flutter"
web_first: true
# 数据结构
rule数据结构noval和act是一对多关系 act和chapter是一对多关系chapter和sense是一对多关系sense和摘要是一对一关系
# AINovalWriter 项目架构说明
## 项目概述
AINovalWriter 是一个AI辅助小说创作平台包含前端应用Flutter和后端服务Spring Boot两个主要部分。
## 目录结构
```
AINovalWriter/
├── DESIGN_DOCUMENT.md # 项目顶层设计文档
├── OPTIMIZATION_SUMMARY.md # 优化总结文档
├── temp.java # 临时 Java 文件 (用途待定)
├── 提示词模板生成需求.md # AI 提示词模板生成功能的需求文档
├── 版本控制功能说明.md # 编辑器版本控制功能的设计或说明文档
├── 项目架构说明.md # 项目整体架构的说明文档
├── 需求文档/ # 存放项目需求相关文档
│ ├── prd.md # 产品需求文档 (Product Requirement Document)
│ ├── requirements_validation.md # 需求验证文档
│ ├── user_flow_and_wireframes.md # 用户流程和线框图文档
│ ├── 前端后台任务系统需求文档.md # 前端后台任务系统的需求文档
│ ├── 前端概要设计文档.md # 前端整体概要设计文档
│ ├── 前端详细设计文档.(小说列表模块,编辑器模块).md # 前端小说列表和编辑器模块的详细设计
│ ├── 前端详细设计文档AI聊天模块.md # 前端 AI 聊天模块的详细设计
│ ├── 前端详细设计文档Codex知识库模块.md # 前端 Codex 知识库模块的详细设计
│ ├── 前端详细设计文档(小说计划预览模块).md # 前端小说计划Plan预览模块的详细设计
│ ├── 前端详细设计文档(文件导出模块详细设计).md # 前端文件导出模块的详细设计
│ ├── 后台任务系统需求文档.md # 后端后台任务系统的需求文档
│ │
│ └── AI生成场景摘要和场景内容/ # AI 生成功能的特定需求文档
│ ├── 前端 AI 生成与提示词管理需求文档.md # 前端 AI 生成与提示词管理的需求
│ ├── 后端 AI 生成与提示词管理 - 详细设计文档.md # 后端 AI 生成与提示词管理的详细设计
│ └── 后端 AI 生成与提示词管理需求文档.md # 后端 AI 生成与提示词管理的需求
├── 测试计划与文档/ # 存放测试相关计划和文档
│ ├── 后端接口文档.md # 后端 API 接口文档
│ ├── 改进报告.md # 项目改进报告
│ ├── 第一次测试计划与功能点.md # 项目第一次迭代的测试计划和功能点
│ └── 第二次迭代第一次代码评审.md # 第二次迭代的代码评审记录
├── 后端开发文档/ # 存放后端开发过程中的文档
│ ├── AI小说助手系统后端概要设计文档.md # 后端概要设计文档
│ ├── AI小说助手系统敏捷开发计划 - 技术验证阶段(调整版).md # 技术验证阶段的敏捷开发计划
│ ├── AI小说助手系统敏捷开发计划 - 边验证边开发模式.md # 边验证边开发的敏捷计划
│ ├── spint1-2.md # Sprint 1-2 的相关文档或笔记
│ ├── 技术评估.md # 项目涉及的技术评估文档
│ └── 迭代日记.md # 开发迭代过程中的日记或记录
├── 原型图/ # 存放界面原型图及相关说明
│ ├── 实现动态获取模型列表和配置验证功能/ # 动态获取模型列表功能的文档
│ │ └── 实现动态获取模型列表和配置验证功能.md # 该功能的 Markdown 说明文档
│ │
│ ├── 剧情推演html原型图和需求文档/ # 剧情推演Next Outline功能的原型和需求
│ │ ├── next_outline_prototype.html # 剧情推演功能的 HTML 原型
│ │ ├── 前端需求.md # 剧情推演功能的前端需求
│ │ └── 后端需求.md # 剧情推演功能的后端需求
│ │
│ └── plan文档和原型图/ # 小说计划Plan视图的原型和文档
│ ├── plan.html # Plan 视图的 HTML 原型
│ └── 前端 Plan 视图原型描述.md # Plan 视图原型的 Markdown 描述
├── 前端产品敏捷迭代计划/ # 前端产品的迭代计划
│ └── 前端产品迭代计划.md # 前端产品迭代计划文档
├── target/ # 构建输出目录 (通常由构建工具生成)
│ └── performance-reports/ # 性能测试报告目录
│ ├── performance_test_platform_50_users_20250313_101351.md # 平台线程模型的 50 用户性能测试报告
│ └── performance_test_virtual_50_users_20250313_101432.md # 虚拟线程模型的 50 用户性能测试报告
├── postman/ # Postman API 测试集合
│ ├── AINovalWriter_Test_API.json # AINovalWriter 项目的 Postman 测试 API 集合
│ ├── AINoval_API_Collection.json # AINoval 项目的 Postman API 集合
│ └── README.md # Postman 集合的说明文档
├── AINovalServer/ # 后端 Spring Boot 项目目录
│ ├── AINoval_API_Collection.json # (重复) AINoval API Postman 集合
│ ├── AINoval_API_Tests.postman_collection.json # AINoval API 测试 Postman 集合
│ ├── AINoval_Performance_Tests.postman_collection.json # AINoval 性能测试 Postman 集合
│ ├── hs_err_pid53088.log # Java 虚拟机错误日志
│ ├── hs_err_pid73408.log # Java 虚拟机错误日志
│ ├── PERFORMANCE_TESTING.md # 性能测试相关说明文档
│ ├── performance_test_script.js # (可能用于 k6 等工具) 性能测试脚本
│ ├── pom.xml # Maven 项目对象模型文件,定义项目依赖和构建配置
│ ├── README.md # AINovalServer 项目的说明文档
│ ├── Sprint1开发总结.md # Sprint 1 开发总结
│ ├── start-performance-test.sh # 启动性能测试的 Shell 脚本
│ │
│ ├── 设计文档/ # 后端特定模块的设计文档
│ │ ├── 后台任务系统后端任务分解.md # 后台任务系统后端的任务分解文档
│ │ ├── 小说导入功能 - 高性能实施方案.md # 小说导入功能的高性能方案设计
│ │ └── 小说导入功能设计方案 (更新版).md # 小说导入功能的设计方案 (更新版)
│ │
│ ├── target/ # Maven 构建输出目录
│ │ ├── test-classes/ # 编译后的测试类目录
│ │ │ └── performance-test-report-template.md # 性能测试报告模板 (测试资源)
│ │ ├── classes/ # 编译后的主类目录
│ │ │ ├── application-dev.yml # 开发环境配置文件
│ │ │ ├── application-performance-test.yml # 性能测试环境配置文件
│ │ │ ├── application-test.yml # 测试环境配置文件
│ │ │ ├── application.yml # 主应用程序配置文件
│ │ │ ├── static/ # 静态资源目录
│ │ │ │ └── gemini-test.html # Gemini 测试用的 HTML 文件
│ │ │ └── prompts/ # AI 提示词模板目录
│ │ │ └── next_outline_prompt.txt # 剧情推演的提示词模板
│ │
│ ├── src/ # 源代码目录
│ │ ├── test/ # 测试代码目录
│ │ │ ├── resources/ # 测试资源目录
│ │ │ │ └── performance-test-report-template.md # (重复) 性能测试报告模板
│ │ │ └── java/com/ainovel/server/ # 测试 Java 代码根目录
│ │ │ ├── service/ # 服务层测试
│ │ │ │ ├── NextOutlineServiceTest.java # NextOutlineService 的测试类
│ │ │ │ └── SceneServiceVersionTest.java # SceneService 版本功能的测试类
│ │ │ └── performance/ # 性能测试相关代码
│ │ │ ├── PerformanceTestRunner.java # 性能测试运行器
│ │ │ ├── VirtualThreadPerformanceTest.java # 虚拟线程性能测试类
│ │ │ ├── util/ # 性能测试工具类
│ │ │ │ └── PerformanceTestUtil.java # 性能测试工具类
│ │ │ └── simulation/ # 性能测试模拟场景
│ │ │ ├── AIServiceSimulation.java # AI 服务调用的模拟
│ │ │ ├── NovelServiceSimulation.java # 小说服务的模拟
│ │ │ └── VirtualThreadVsTraditionalSimulation.java # 虚拟线程与传统线程对比的模拟
│ │ │
│ │ └── main/ # 主代码目录
│ │ ├── resources/ # 主资源目录
│ │ │ ├── application-dev.yml # (重复) 开发环境配置文件
│ │ │ ├── application-performance-test.yml # (重复) 性能测试环境配置文件
│ │ │ ├── application-test.yml # (重复) 测试环境配置文件
│ │ │ ├── application.yml # (重复) 主应用程序配置文件
│ │ │ ├── static/ # (重复) 静态资源目录
│ │ │ │ └── gemini-test.html # (重复) Gemini 测试用的 HTML 文件
│ │ │ └── prompts/ # (重复) AI 提示词模板目录
│ │ │ └── next_outline_prompt.txt # (重复) 剧情推演的提示词模板
│ │ │
│ │ └── java/com/ainovel/server/ # 主 Java 代码根目录
│ │ ├── AiNovelServerApplication.java # Spring Boot 应用主入口类
│ │ │
│ │ ├── web/ # Web 层,处理 HTTP 请求
│ │ │ ├── GeminiTestController.java # Gemini 测试相关的控制器 (可能已废弃或测试用)
│ │ │ ├── dto/ # Data Transfer Objects (数据传输对象)
│ │ │ │ ├── AIModelConfigDto.java # AI 模型配置 DTO
│ │ │ │ ├── ApiKeyValidationRequest.java # API Key 验证请求 DTO
│ │ │ │ ├── ApiKeyValidationResponse.java # API Key 验证响应 DTO
│ │ │ │ ├── AuthorIdDto.java # 作者 ID DTO
│ │ │ │ ├── AuthRequest.java # 认证请求 DTO
│ │ │ │ ├── AuthResponse.java # 认证响应 DTO
│ │ │ │ ├── ChangePasswordRequest.java # 修改密码请求 DTO
│ │ │ │ ├── ChapterIdDto.java # 章节 ID DTO
│ │ │ │ ├── ChapterSceneDto.java # 章节场景 DTO
│ │ │ │ ├── ChapterScenesDto.java # 章节场景列表 DTO
│ │ │ │ ├── ConfigIndexDto.java # 配置索引 DTO
│ │ │ │ ├── CreatePromptTemplateRequest.java # 创建提示词模板请求 DTO
│ │ │ │ ├── CreateUserAIModelConfigRequest.java # 创建用户 AI 模型配置请求 DTO
│ │ │ │ ├── ErrorResponse.java # 错误响应 DTO
│ │ │ │ ├── GenerateNextOutlinesDTO.java # 生成后续大纲请求 DTO
│ │ │ │ ├── GenerateSceneFromSummaryRequest.java # 从摘要生成场景请求 DTO
│ │ │ │ ├── GenerateSceneFromSummaryResponse.java # 从摘要生成场景响应 DTO
│ │ │ │ ├── IdDto.java # 通用 ID DTO
│ │ │ │ ├── ImportStatus.java # 导入状态 DTO
│ │ │ │ ├── JobIdResponse.java # 任务 ID 响应 DTO
│ │ │ │ ├── ListUserConfigsRequest.java # 列出用户配置请求 DTO
│ │ │ │ ├── LoadMoreScenesRequestDto.java # 加载更多场景请求 DTO
│ │ │ │ ├── NextOutlineDTO.java # 后续大纲 DTO
│ │ │ │ ├── NovelChapterDto.java # 小说章节 DTO
│ │ │ │ ├── NovelChapterSceneDto.java # 小说章节场景 DTO
│ │ │ │ ├── NovelIdDto.java # 小说 ID DTO
│ │ │ │ ├── NovelIdTypeDto.java # 小说 ID 和类型 DTO
│ │ │ │ ├── NovelUpdateDto.java # 小说更新 DTO
│ │ │ │ ├── NovelWithScenesDto.java # 包含场景的小说 DTO
│ │ │ │ ├── NovelWithScenesUpdateDto.java # 包含场景的小说更新 DTO
│ │ │ │ ├── NovelWithSummariesDto.java # 包含摘要的小说 DTO
│ │ │ │ ├── OptimizationResultDto.java # 优化结果 DTO
│ │ │ │ ├── OptimizePromptRequest.java # 优化提示词请求 DTO
│ │ │ │ ├── OutlineGenerationChunk.java # 大纲生成块 DTO (用于流式传输)
│ │ │ │ ├── PaginatedScenesRequestDto.java # 分页场景请求 DTO
│ │ │ │ ├── PromptTemplateDto.java # 提示词模板 DTO
│ │ │ │ ├── ProviderModelsRequest.java # Provider 模型列表请求 DTO
│ │ │ │ ├── ProxyConfigRequest.java # 代理配置请求 DTO
│ │ │ │ ├── RagQueryDto.java # RAG 查询 DTO
│ │ │ │ ├── RagQueryResultDto.java # RAG 查询结果 DTO
│ │ │ │ ├── RefreshTokenRequest.java # 刷新令牌请求 DTO
│ │ │ │ ├── RevisionRequest.java # 版本请求 DTO
│ │ │ │ ├── SceneContentUpdateDto.java # 场景内容更新 DTO
│ │ │ │ ├── SceneDeleteDto.java # 场景删除 DTO
│ │ │ │ ├── SceneRestoreDto.java # 场景恢复 DTO
│ │ │ │ ├── SceneSearchDto.java # 场景搜索 DTO
│ │ │ │ ├── SceneSummaryDto.java # 场景摘要 DTO
│ │ │ │ ├── SceneUpdateDto.java # 场景更新 DTO
│ │ │ │ ├── SceneVersionCompareDto.java # 场景版本比较 DTO
│ │ │ │ ├── SceneVersionDiff.java # 场景版本差异 DTO
│ │ │ │ ├── SessionCreateDto.java # 会话创建 DTO
│ │ │ │ ├── SessionMessageDto.java # 会话消息 DTO
│ │ │ │ ├── SessionUpdateDto.java # 会话更新 DTO
│ │ │ │ ├── SuggestionRequest.java # 建议请求 DTO
│ │ │ │ ├── SummarizeSceneRequest.java # 摘要场景请求 DTO
│ │ │ │ ├── SummarizeSceneResponse.java # 摘要场景响应 DTO
│ │ │ │ ├── UpdatePromptRequest.java # 更新提示词请求 DTO
│ │ │ │ ├── UpdatePromptTemplateRequest.java # 更新提示词模板请求 DTO
│ │ │ │ ├── UpdateUserAIModelConfigRequest.java # 更新用户 AI 模型配置请求 DTO
│ │ │ │ ├── UserAIModelConfigResponse.java # 用户 AI 模型配置响应 DTO
│ │ │ │ ├── UserIdConfigIndexDto.java # 用户 ID 和配置索引 DTO
│ │ │ │ ├── UserIdDto.java # 用户 ID DTO
│ │ │ │ ├── UserPromptTemplateDto.java # 用户提示词模板 DTO
│ │ │ │ ├── UserRegistrationRequest.java # 用户注册请求 DTO
│ │ │ │ └── UserUpdateDto.java # 用户更新 DTO
│ │ │ │
│ │ │ ├── controller/ # REST API 控制器
│ │ │ │ ├── AIChatController.java # AI 聊天功能控制器
│ │ │ │ ├── AIGenerationController.java # AI 生成功能控制器
│ │ │ │ ├── AuthController.java # 用户认证控制器
│ │ │ │ ├── ModelInfoController.java # AI 模型信息控制器
│ │ │ │ ├── MongoTestController.java # MongoDB 测试控制器 (可能已废弃或测试用)
│ │ │ │ ├── NextOutlineController.java # 剧情推演控制器
│ │ │ │ ├── NovelAIController.java # 小说相关的 AI 功能控制器
│ │ │ │ ├── NovelController.java # 小说管理控制器
│ │ │ │ ├── PromptTemplateController.java # 提示词模板控制器
│ │ │ │ ├── RagController.java # RAG 功能控制器
│ │ │ │ ├── SceneController.java # 场景管理控制器
│ │ │ │ ├── SecurityTestController.java # 安全测试控制器 (可能已废弃或测试用)
│ │ │ │ ├── UserAIModelConfigController.java # 用户 AI 模型配置控制器
│ │ │ │ ├── UserController.java # 用户管理控制器
│ │ │ │ └── UserPromptController.java # 用户提示词控制器
│ │ │ │
│ │ │ └── base/ # Web 层基础类
│ │ │ └── ReactiveBaseController.java # 响应式控制器基类 (可能用于 WebSocket 或 SSE)
│ │ │
│ │ ├── service/ # 服务层,包含业务逻辑
│ │ │ ├── AIChatService.java # AI 聊天服务接口
│ │ │ ├── AIProviderRegistryService.java # AI Provider 注册服务接口
│ │ │ ├── AIService.java # 通用 AI 服务接口
│ │ │ ├── EmbeddingService.java # 文本嵌入服务接口
│ │ │ ├── ImportService.java # 文件导入服务接口
│ │ │ ├── IndexingService.java # 索引服务接口 (用于 RAG)
│ │ │ ├── JwtService.java # JWT (JSON Web Token) 服务接口
│ │ │ ├── KnowledgeService.java # 知识库服务接口 (可能与 RAG 相关)
│ │ │ ├── MetadataService.java # 元数据服务接口
│ │ │ ├── NextOutlineService.java # 剧情推演服务接口
│ │ │ ├── NovelAIService.java # 小说 AI 相关服务接口
│ │ │ ├── NovelParser.java # 小说文件解析器接口
│ │ │ ├── NovelRagAssistant.java # 小说 RAG 助手接口
│ │ │ ├── NovelService.java # 小说管理服务接口
│ │ │ ├── PromptService.java # 提示词服务接口
│ │ │ ├── PromptTemplateService.java # 提示词模板服务接口
│ │ │ ├── SceneService.java # 场景管理服务接口
│ │ │ ├── StorageService.java # 文件存储服务接口
│ │ │ ├── UserAIModelConfigService.java # 用户 AI 模型配置服务接口
│ │ │ ├── UserPromptService.java # 用户提示词服务接口
│ │ │ ├── UserService.java # 用户管理服务接口
│ │ │ │
│ │ │ ├── vectorstore/ # 向量数据库相关接口和类
│ │ │ │ ├── ChromaVectorStore.java # Chroma 向量数据库实现 (可能)
│ │ │ │ ├── SearchResult.java # 向量搜索结果类
│ │ │ │ └── VectorStore.java # 向量数据库接口
│ │ │ │
│ │ │ ├── rag/ # RAG (检索增强生成) 相关类
│ │ │ │ ├── ChromaEmbeddingStoreProvider.java # Chroma 嵌入存储提供者 (LangChain4j)
│ │ │ │ ├── LangChain4jEmbeddingModel.java # LangChain4j 嵌入模型封装
│ │ │ │ ├── NovelRagAssistant.java # (重复) 小说 RAG 助手接口
│ │ │ │ ├── RagService.java # RAG 服务接口
│ │ │ │ └── RagServiceImpl.java # RAG 服务实现
│ │ │ │
│ │ │ ├── provider/ # 外部服务提供者 (如存储)
│ │ │ │ ├── AliOSSStorageProvider.java # 阿里云 OSS 存储提供者实现
│ │ │ │ └── StorageProvider.java # 存储提供者接口
│ │ │ │
│ │ │ ├── impl/ # 服务层接口实现
│ │ │ │ ├── AIChatServiceImpl.java # AI 聊天服务实现
│ │ │ │ ├── AIServiceImpl.java # 通用 AI 服务实现
│ │ │ │ ├── EmbeddingServiceImpl.java # 文本嵌入服务实现
│ │ │ │ ├── ImportServiceImpl.java # 文件导入服务实现
│ │ │ │ ├── IndexingServiceImpl.java # 索引服务实现
│ │ │ │ ├── JwtServiceImpl.java # JWT 服务实现
│ │ │ │ ├── KnowledgeServiceImpl.java # 知识库服务实现
│ │ │ │ ├── MetadataServiceImpl.java # 元数据服务实现
│ │ │ │ ├── NextOutlineServiceImpl.java # 剧情推演服务实现
│ │ │ │ ├── NovelAIServiceImpl.java # 小说 AI 相关服务实现
│ │ │ │ ├── NovelRagAssistantImpl.java # 小说 RAG 助手实现
│ │ │ │ ├── NovelServiceImpl.java # 小说管理服务实现
│ │ │ │ ├── PromptServiceImpl.java # 提示词服务实现
│ │ │ │ ├── PromptTemplateServiceImpl.java # 提示词模板服务实现
│ │ │ │ ├── SceneServiceImpl.java # 场景管理服务实现
│ │ │ │ ├── StorageServiceImpl.java # 文件存储服务实现
│ │ │ │ ├── TxtNovelParser.java # TXT 格式小说解析器实现
│ │ │ │ ├── UserAIModelConfigServiceImpl.java # 用户 AI 模型配置服务实现
│ │ │ │ ├── UserPromptServiceImpl.java # 用户提示词服务实现
│ │ │ │ └── UserServiceImpl.java # 用户管理服务实现
│ │ │ │
│ │ │ └── ai/ # AI 模型提供者相关代码
│ │ │ ├── AbstractAIModelProvider.java # AI 模型提供者抽象基类
│ │ │ ├── AIModelProvider.java # AI 模型提供者接口
│ │ │ ├── AnthropicModelProvider.java # Anthropic 模型提供者 (可能直接调用 API)
│ │ │ ├── GeminiModelProvider.java # Gemini 模型提供者 (可能直接调用 API)
│ │ │ ├── GrokModelProvider.java # Grok 模型提供者 (可能直接调用 API)
│ │ │ ├── OpenAIModelProvider.java # OpenAI 模型提供者 (可能直接调用 API)
│ │ │ ├── SiliconFlowModelProvider.java # SiliconFlow 模型提供者 (可能直接调用 API)
│ │ │ │
│ │ │ ├── registry/ # AI Provider 注册表
│ │ │ │ └── AIProviderRegistry.java # AI Provider 注册表实现
│ │ │ │
│ │ │ ├── langchain4j/ # LangChain4j 集成实现
│ │ │ │ ├── AnthropicLangChain4jModelProvider.java # Anthropic LangChain4j 提供者
│ │ │ │ ├── GeminiLangChain4jModelProvider.java # Gemini LangChain4j 提供者
│ │ │ │ ├── LangChain4jModelProvider.java # LangChain4j 提供者接口/基类
│ │ │ │ ├── OpenAILangChain4jModelProvider.java # OpenAI LangChain4j 提供者
│ │ │ │ ├── OpenRouterLangChain4jModelProvider.java # OpenRouter LangChain4j 提供者
│ │ │ │ ├── SiliconFlowLangChain4jModelProvider.java # SiliconFlow LangChain4j 提供者
│ │ │ │ └── TogetherAILangChain4jModelProvider.java # TogetherAI LangChain4j 提供者
│ │ │ │
│ │ │ ├── factory/ # 工厂模式 (用于创建 Provider)
│ │ │ │ └── AIModelProviderFactory.java # AI 模型提供者工厂
│ │ │ │
│ │ │ └── capability/ # AI Provider 能力检测
│ │ │ ├── AnthropicCapabilityDetector.java # Anthropic 能力检测器
│ │ │ ├── GeminiCapabilityDetector.java # Gemini 能力检测器
│ │ │ ├── GrokCapabilityDetector.java # Grok 能力检测器
│ │ │ ├── OpenAICapabilityDetector.java # OpenAI 能力检测器
│ │ │ ├── OpenRouterCapabilityDetector.java # OpenRouter 能力检测器
│ │ │ ├── ProviderCapabilityDetector.java # Provider 能力检测器接口
│ │ │ ├── ProviderCapabilityService.java # Provider 能力服务
│ │ │ ├── SiliconFlowCapabilityDetector.java # SiliconFlow 能力检测器
│ │ │ └── TogetherAICapabilityDetector.java # TogetherAI 能力检测器
│ │ │
│ │ ├── security/ # 安全配置和组件
│ │ │ ├── CurrentUser.java # 获取当前用户注解
│ │ │ ├── CurrentUserMethodArgumentResolver.java # 解析 @CurrentUser 注解的参数解析器
│ │ │ ├── JwtAuthenticationManager.java # JWT 认证管理器
│ │ │ └── JwtServerAuthenticationConverter.java # JWT 服务器认证转换器 (用于 Spring Security WebFlux)
│ │ │
│ │ ├── repository/ # 数据仓库层 (数据库交互)
│ │ │ ├── AIChatMessageRepository.java # AI 聊天消息仓库接口
│ │ │ ├── AIChatSessionRepository.java # AI 聊天会话仓库接口
│ │ │ ├── KnowledgeChunkRepository.java # 知识块仓库接口
│ │ │ ├── NextOutlineRepository.java # 后续大纲仓库接口
│ │ │ ├── NovelRepository.java # 小说仓库接口
│ │ │ ├── PromptTemplateRepository.java # 提示词模板仓库接口
│ │ │ ├── SceneRepository.java # 场景仓库接口
│ │ │ ├── UserAIModelConfigRepository.java # 用户 AI 模型配置仓库接口
│ │ │ ├── UserPromptTemplateRepository.java # 用户提示词模板仓库接口
│ │ │ ├── UserRepository.java # 用户仓库接口
│ │ │ │
│ │ │ ├── impl/ # 数据仓库层实现 (部分自定义实现)
│ │ │ │ ├── NextOutlineRepositoryImpl.java # NextOutlineRepository 自定义实现
│ │ │ │ └── UserRepositoryImpl.java # UserRepository 自定义实现
│ │ │ │
│ │ │ └── custom/ # 自定义仓库接口 (用于复杂查询)
│ │ │ └── CustomUserRepository.java # 自定义用户仓库接口
│ │ │
│ │ ├── exception/ # 自定义异常类
│ │ │ └── VectorStoreException.java # 向量存储异常
│ │ │
│ │ ├── domain/ # 领域模型和 DTO
│ │ │ ├── model/ # 核心领域模型 (对应数据库实体)
│ │ │ │ ├── AIChatMessage.java # AI 聊天消息实体
│ │ │ │ ├── AIChatSession.java # AI 聊天会话实体
│ │ │ │ ├── AIFeatureType.java # AI 功能类型枚举
│ │ │ │ ├── AIInteraction.java # AI 交互记录实体 (可能)
│ │ │ │ ├── AIRequest.java # AI 请求实体 (可能)
│ │ │ │ ├── AIResponse.java # AI 响应实体 (可能)
│ │ │ │ ├── BaseAIRequest.java # AI 请求基类 (可能)
│ │ │ │ ├── Character.java # 角色实体
│ │ │ │ ├── GenerateNextOutlinesDTO.java # (重复) 生成后续大纲 DTO (位置可能不当)
│ │ │ │ ├── KnowledgeChunk.java # 知识块实体
│ │ │ │ ├── ModelInfo.java # 模型信息实体
│ │ │ │ ├── ModelListingCapability.java # 模型列表能力枚举
│ │ │ │ ├── NextOutline.java # 后续大纲实体
│ │ │ │ ├── Novel.java # 小说实体
│ │ │ │ ├── OptimizationResult.java # 优化结果实体
│ │ │ │ ├── OptimizationSection.java # 优化部分实体
│ │ │ │ ├── OptimizationStatistics.java # 优化统计实体
│ │ │ │ ├── OptimizationStyle.java # 优化风格枚举
│ │ │ │ ├── PromptTemplate.java # 提示词模板实体
│ │ │ │ ├── Scene.java # 场景实体
│ │ │ │ ├── SceneVersionDiff.java # (重复) 场景版本差异 DTO (位置可能不当)
│ │ │ │ ├── Setting.java # 设定实体
│ │ │ │ ├── User.java # 用户实体
│ │ │ │ ├── UserAIModelConfig.java # 用户 AI 模型配置实体
│ │ │ │ └── UserPromptTemplate.java # 用户提示词模板实体
│ │ │ │
│ │ │ └── dto/ # 领域层 DTO (特定于领域逻辑)
│ │ │ ├── ApiKeyTestRequest.java # API Key 测试请求 DTO
│ │ │ ├── ParsedNovelData.java # 解析后的小说数据 DTO
│ │ │ └── ParsedSceneData.java # 解析后的场景数据 DTO
│ │ │
│ │ ├── controller/ # (重复) 控制器目录 (结构可能需要调整)
│ │ │ └── ProviderCapabilityController.java # Provider 能力控制器
│ │ │
│ │ ├── config/ # 应用配置类
│ │ │ ├── AIServiceConfig.java # AI 服务相关配置
│ │ │ ├── CacheConfig.java # 缓存配置 (如 Caffeine)
│ │ │ ├── ChatLanguageModelConfig.java # 聊天语言模型配置 (可能与 LangChain4j 相关)
│ │ │ ├── MongoConfig.java # MongoDB 配置
│ │ │ ├── MongoQueryCounterAspect.java # MongoDB 查询计数切面 (用于监控或调试)
│ │ │ ├── MonitoringConfig.java # 监控配置 (如 Micrometer, Actuator)
│ │ │ ├── PasswordConfig.java # 密码加密配置 (如 BCryptPasswordEncoder)
│ │ │ ├── ProviderServiceConfig.java # Provider 服务配置
│ │ │ ├── ProxyConfig.java # 网络代理配置
│ │ │ ├── RagConfig.java # RAG 配置
│ │ │ ├── SecurityConfig.java # Spring Security 配置
│ │ │ ├── StorageConfig.java # 文件存储配置
│ │ │ ├── StorageStartupTester.java # 存储服务启动测试器
│ │ │ ├── TestSecurityConfig.java # 测试环境安全配置
│ │ │ ├── VectorStoreConfig.java # 向量存储配置
│ │ │ ├── VirtualThreadConfig.java # 虚拟线程执行器配置
│ │ │ └── WebConfig.java # Web 相关配置 (如 CORS, ArgumentResolvers)
│ │ │
│ │ └── common/ # 通用工具和类
│ │ ├── util/ # 通用工具类
│ │ │ ├── MockDataGenerator.java # 模拟数据生成器
│ │ │ ├── PerformanceTestUtil.java # (重复) 性能测试工具类
│ │ │ └── PromptUtil.java # 提示词处理工具类
│ │ │
│ │ ├── security/ # 通用安全类
│ │ │ └── CurrentUser.java # (重复) 获取当前用户注解
│ │ │
│ │ ├── model/ # 通用模型类
│ │ │ └── ErrorResponse.java # (重复) 通用错误响应模型
│ │ │
│ │ └── exception/ # 通用异常类
│ │ ├── ResourceNotFoundException.java # 资源未找到异常
│ │ └── ValidationException.java # 验证异常
└── AINoval/ # 前端 Flutter 项目目录
├── analysis_options.yaml # Dart 代码分析器选项
├── devtools_options.yaml # Dart 开发者工具选项
├── firebase.json # Firebase CLI 配置文件
├── pubspec.yaml # Flutter 项目配置文件 (依赖项, 资源等)
├── README.md # AINoval 前端项目说明文档
├── 设计文档/ # 前端特定模块的设计文档
│ └── 前端后台任务系统任务分解.md # 前端后台任务系统的任务分解
├── web/ # Web 平台特定文件
│ ├── index.html # Web 应用主 HTML 文件
│ └── manifest.json # Web 应用清单文件
├── scripts/ # Dart 脚本目录
│ └── replace_print_with_logger.dart # 用于替换 print 为 logger 的脚本
├── lib/ # Flutter 应用主要代码目录
│ ├── firebase_options.dart # Firebase 初始化选项 (自动生成)
│ ├── main.dart # Flutter 应用入口文件
│ │
│ ├── widgets/ # 可重用的小部件目录
│ │ └── common/ # 通用小部件
│ │ ├── empty_state_placeholder.dart # 空状态占位符小部件
│ │ └── loading_indicator.dart # 加载指示器小部件
│ │
│ ├── utils/ # 工具类目录
│ │ ├── app_theme.dart # 应用主题工具类
│ │ ├── date_formatter.dart # 日期格式化工具类
│ │ ├── date_time_parser.dart # 日期时间解析工具类
│ │ ├── debouncer.dart # 防抖动工具类
│ │ ├── logger.dart # 日志记录工具类
│ │ ├── logger_guide.md # 日志记录器使用指南
│ │ ├── logger_usage_examples.dart # 日志记录器使用示例
│ │ ├── mock_data.dart # 模拟数据
│ │ ├── mock_data_generator.dart # 模拟数据生成器
│ │ └── word_count_analyzer.dart # 字数统计分析器
│ │
│ ├── ui/ # UI 相关目录 (可能包含通用 UI 元素)
│ │ ├── screens/ # (旧结构?) 屏幕目录
│ │ │ └── editor_screen.dart # (旧结构?) 编辑器屏幕
│ │ ├── dialogs/ # 对话框目录
│ │ │ └── scene_history_dialog.dart # 场景历史对话框
│ │ └── common/ # 通用 UI 组件
│ │ ├── loading_indicator.dart # (重复) 加载指示器
│ │ └── no_data_placeholder.dart # 无数据占位符
│ │
│ ├── theme/ # 主题和样式目录
│ │ └── text_styles.dart # 文本样式定义
│ │
│ ├── services/ # 应用服务目录
│ │ ├── auth_service.dart # 认证服务
│ │ ├── context_provider.dart # 上下文提供者 (可能用于全局访问)
│ │ ├── local_storage_service.dart # 本地存储服务
│ │ ├── sync_service.dart # 同步服务 (可能用于离线/在线同步)
│ │ ├── websocket_service.dart # WebSocket 服务
│ │ │
│ │ └── api_service/ # API 服务目录 (与后端交互)
│ │ ├── README.md # API 服务说明
│ │ ├── repositories/ # API 仓库接口
│ │ │ ├── chat_repository.dart # 聊天 API 仓库接口
│ │ │ ├── editor_repository.dart # 编辑器 API 仓库接口
│ │ │ ├── next_outline_repository.dart # 剧情推演 API 仓库接口
│ │ │ ├── novel_repository.dart # 小说 API 仓库接口
│ │ │ ├── prompt_repository.dart # 提示词 API 仓库接口
│ │ │ ├── storage_repository.dart # 存储 API 仓库接口
│ │ │ └── user_ai_model_config_repository.dart # 用户 AI 配置 API 仓库接口
│ │ │
│ │ ├── repositories/impl/ # API 仓库实现
│ │ │ ├── aliyun_oss_storage_repository.dart # 阿里云 OSS 存储仓库实现
│ │ │ ├── chat_repository_impl.dart # 聊天 API 仓库实现
│ │ │ ├── editor_repository_impl.dart # 编辑器 API 仓库实现
│ │ │ ├── next_outline_repository_impl.dart # 剧情推演 API 仓库实现
│ │ │ ├── novel_repository_impl.dart # 小说 API 仓库实现
│ │ │ ├── prompt_repository_impl.dart # 提示词 API 仓库实现
│ │ │ ├── storage_repository_impl.dart # 存储 API 仓库实现
│ │ │ └── user_ai_model_config_repository_impl.dart # 用户 AI 配置 API 仓库实现
│ │ │
│ │ └── base/ # API 服务基础类
│ │ ├── api_client.dart # API 客户端 (如 Dio 封装)
│ │ ├── api_exception.dart # API 异常类
│ │ └── sse_client.dart # Server-Sent Events (SSE) 客户端
│ │
│ ├── screens/ # 应用屏幕 (主要页面) 目录
│ │ ├── settings/ # 设置屏幕
│ │ │ ├── settings_panel.dart # 设置面板主屏幕
│ │ │ └── widgets/ # 设置屏幕相关小部件
│ │ │ ├── ai_assist_toolbar.dart # AI 辅助工具栏
│ │ │ ├── ai_config_form.dart # AI 配置表单
│ │ │ ├── custom_model_dialog.dart # 自定义模型对话框
│ │ │ ├── model_group_list.dart # 模型分组列表
│ │ │ ├── model_service_card.dart # 模型服务卡片
│ │ │ ├── model_service_header.dart # 模型服务列表头部
│ │ │ ├── model_service_list_page.dart # 模型服务列表页面
│ │ │ ├── optimization_result_view.dart # 优化结果视图
│ │ │ ├── processing_indicator.dart # 处理中指示器
│ │ │ ├── prompt_editor_panel.dart # 提示词编辑面板
│ │ │ ├── prompt_management_panel.dart # 提示词管理面板
│ │ │ ├── prompt_template_library.dart # 提示词模板库
│ │ │ ├── provider_list.dart # AI Provider 列表
│ │ │ ├── searchable_model_dropdown.dart # 可搜索的模型下拉菜单
│ │ │ └── template_permission_indicator.dart # 模板权限指示器
│ │ │
│ │ ├── novel_list/ # 小说列表屏幕
│ │ │ ├── novel_list_screen.dart # 小说列表主屏幕
│ │ │ └── widgets/ # 小说列表屏幕相关小部件
│ │ │ ├── continue_writing_section.dart # 继续写作区域
│ │ │ ├── empty_novel_view.dart # 空小说列表视图
│ │ │ ├── header_section.dart # 头部区域
│ │ │ ├── import_novel_dialog.dart # 导入小说对话框
│ │ │ ├── loading_view.dart # 加载视图
│ │ │ ├── novel_card.dart # 小说卡片
│ │ │ ├── novel_list_error_view.dart # 小说列表错误视图
│ │ │ └── search_filter_bar.dart # 搜索和过滤栏
│ │ │
│ │ ├── next_outline/ # 剧情推演屏幕
│ │ │ ├── next_outline_screen.dart # 剧情推演主屏幕
│ │ │ ├── next_outline_view.dart # 剧情推演视图 (可能包含主要 UI)
│ │ │ └── widgets/ # 剧情推演屏幕相关小部件
│ │ │ ├── outline_generation_config_card.dart # 大纲生成配置卡片
│ │ │ ├── results_grid.dart # 结果网格布局
│ │ │ └── result_card.dart # 结果卡片
│ │ │
│ │ ├── editor/ # 编辑器屏幕
│ │ │ ├── editor_screen.dart # 编辑器主屏幕
│ │ │ ├── widgets/ # 编辑器屏幕通用小部件
│ │ │ │ ├── ai_chat_button.dart # AI 聊天按钮
│ │ │ │ ├── ai_generation_panel.dart # AI 生成面板
│ │ │ │ ├── ai_scene_generation_side_panel.dart # AI 场景生成侧边面板
│ │ │ │ ├── ai_stream_generation_display.dart # AI 流式生成显示
│ │ │ │ ├── ai_summary_panel.dart # AI 摘要面板
│ │ │ │ ├── ai_summary_side_panel.dart # AI 摘要侧边面板
│ │ │ │ ├── custom_dropdown.dart # 自定义下拉菜单
│ │ │ │ ├── dialogs.dart # 编辑器相关对话框
│ │ │ │ ├── dropdown_guide.md # 下拉菜单使用指南
│ │ │ │ ├── dropdown_manager.dart # 下拉菜单管理器
│ │ │ │ ├── editor_toolbar.dart # 编辑器工具栏
│ │ │ │ ├── enhanced_menu_item.dart # 增强型菜单项
│ │ │ │ ├── generate_scene_dialog.dart # 生成场景对话框
│ │ │ │ ├── menu_builder.dart # 菜单构建器
│ │ │ │ ├── menu_definitions.dart # 菜单定义
│ │ │ │ ├── novel_settings_view.dart # 小说设置视图
│ │ │ │ ├── selection_toolbar.dart # 文本选择工具栏
│ │ │ │ └── word_count_display.dart # 字数显示
│ │ │ │
│ │ │ ├── managers/ # 编辑器屏幕管理器
│ │ │ │ ├── editor_dialog_manager.dart # 编辑器对话框管理器
│ │ │ │ ├── editor_layout_manager.dart # 编辑器布局管理器
│ │ │ │ └── editor_state_manager.dart # 编辑器状态管理器
│ │ │ │
│ │ │ ├── controllers/ # 编辑器屏幕控制器 (可能与 BLoC 结合)
│ │ │ │ └── editor_screen_controller.dart # 编辑器屏幕控制器
│ │ │ │
│ │ │ └── components/ # 编辑器屏幕的主要 UI 组件
│ │ │ ├── act_section.dart # 幕/卷区域组件
│ │ │ ├── chapter_section.dart # 章区域组件
│ │ │ ├── draggable_divider.dart # 可拖动分隔线
│ │ │ ├── editor_app_bar.dart # 编辑器应用栏
│ │ │ ├── editor_layout.dart # 编辑器整体布局
│ │ │ ├── editor_main_area.dart # 编辑器主编辑区域
│ │ │ ├── editor_sidebar.dart # 编辑器侧边栏 (大纲/章节/场景列表)
│ │ │ ├── multi_ai_panel_view.dart # 多 AI 面板视图
│ │ │ ├── plan_view.dart # 小说计划 (Plan) 视图
│ │ │ └── scene_editor.dart # 场景编辑器组件
│ │ │
│ │ ├── chat/ # AI 聊天屏幕
│ │ │ ├── chat_screen.dart # AI 聊天主屏幕
│ │ │ └── widgets/ # AI 聊天屏幕相关小部件
│ │ │ ├── ai_chat_sidebar.dart # AI 聊天侧边栏
│ │ │ ├── chat_input.dart # 聊天输入框
│ │ │ ├── chat_message_bubble.dart # 聊天消息气泡
│ │ │ ├── chat_sidebar.dart # 聊天侧边栏 (可能包含会话列表)
│ │ │ ├── context_panel.dart # 上下文面板
│ │ │ ├── model_selector_dropdown.dart # 模型选择下拉菜单
│ │ │ └── typing_indicator.dart # 输入中指示器
│ │ │
│ │ ├── auth/ # 认证屏幕
│ │ │ └── login_screen.dart # 登录屏幕
│ │ │
│ │ └── ai_config/ # AI 配置管理屏幕
│ │ ├── ai_config_management_screen.dart # AI 配置管理主屏幕
│ │ └── widgets/ # AI 配置屏幕相关小部件
│ │ ├── add_edit_ai_config_dialog.dart # 添加/编辑 AI 配置对话框
│ │ ├── ai_config_list_item.dart # AI 配置列表项
│ │ └── ai_model_selector.dart # AI 模型选择器
│ │
│ ├── repositories/ # 数据仓库目录 (顶层, 可能需要整合)
│ │ └── codex_repository.dart # Codex (知识库) 仓库接口
│ │
│ ├── models/ # 数据模型目录
│ │ ├── ai_model_group.dart # AI 模型分组模型
│ │ ├── chat_message.dart # 聊天消息模型
│ │ ├── chat_models.dart # 聊天相关模型 (可能包含会话等)
│ │ ├── editor_content.dart # 编辑器内容模型
│ │ ├── editor_settings.dart # 编辑器设置模型
│ │ ├── import_status.dart # 导入状态模型
│ │ ├── model_info.dart # 模型信息模型
│ │ ├── novel_structure.dart # 小说结构模型 (卷/章/场景)
│ │ ├── novel_summary.dart # 小说摘要模型
│ │ ├── prompt_models.dart # 提示词相关模型
│ │ ├── revision.dart # 版本/修订模型
│ │ ├── scene_version.dart # 场景版本模型
│ │ ├── user_ai_model_config_model.dart # 用户 AI 模型配置模型
│ │ │
│ │ ├── next_outline/ # 剧情推演相关模型
│ │ │ ├── next_outline_dto.dart # 剧情推演 DTO
│ │ │ └── outline_generation_chunk.dart # 大纲生成块 (SSE)
│ │ │
│ │ └── api/ # API 数据传输对象 (DTO)
│ │ └── editor_dtos.dart # 编辑器相关的 DTO
│ │
│ ├── l10n/ # 本地化目录
│ │ └── l10n.dart # 本地化工具类/入口
│ │
│ ├── docs/ # 文档目录 (嵌入代码中)
│ │ └── logger_guide.md # (重复) 日志记录器使用指南
│ │
│ ├── config/ # 应用配置目录
│ │ └── app_config.dart # 应用配置 (如 API 地址)
│ │
│ ├── components/ # 可重用组件目录 (类似 widgets)
│ │ └── editable_title.dart # 可编辑标题组件
│ │
│ └── blocs/ # BLoC 状态管理目录
│ ├── editor_version_bloc.dart # 编辑器版本 BLoC
│ ├── editor_version_event.dart # 编辑器版本事件
│ ├── editor_version_state.dart # 编辑器版本状态
│ │
│ ├── prompt/ # 提示词管理 BLoC
│ │ ├── prompt_bloc.dart # 提示词 BLoC
│ │ ├── prompt_event.dart # 提示词事件
│ │ ├── prompt_state.dart # 提示词状态
│ │ └── prompt_template_events.dart # 提示词模板事件 (可能应合并或重构)
│ │
│ ├── plan/ # 小说计划 (Plan) BLoC
│ │ ├── plan_bloc.dart # Plan BLoC
│ │ ├── plan_event.dart # Plan 事件
│ │ └── plan_state.dart # Plan 状态
│ │
│ ├── novel_list/ # 小说列表 BLoC
│ │ ├── novel_list_bloc.dart # 小说列表 BLoC
│ │ └── novel_list_event.dart # 小说列表事件
│ │ # novel_list_state.dart missing? (可能在 novel_list_bloc.dart 中定义)
│ │
│ ├── novel_import/ # 小说导入 BLoC
│ │ ├── novel_import_bloc.dart # 小说导入 BLoC
│ │ ├── novel_import_event.dart # 小说导入事件
│ │ └── novel_import_state.dart # 小说导入状态
│ │
│ ├── next_outline/ # 剧情推演 BLoC
│ │ ├── next_outline_bloc.dart # 剧情推演 BLoC
│ │ ├── next_outline_event.dart # 剧情推演事件
│ │ └── next_outline_state.dart # 剧情推演状态
│ │
│ ├── editor/ # 编辑器 BLoC
│ │ ├── editor_bloc.dart # 编辑器 BLoC
│ │ ├── editor_event.dart # 编辑器事件
│ │ └── editor_state.dart # 编辑器状态
│ │
│ ├── chat/ # AI 聊天 BLoC
│ │ ├── chat_bloc.dart # 聊天 BLoC
│ │ ├── chat_event.dart # 聊天事件
│ │ └── chat_state.dart # 聊天状态
│ │
│ ├── auth/ # 认证 BLoC
│ │ └── auth_bloc.dart # 认证 BLoC
│ │ # auth_event.dart, auth_state.dart missing?
│ │
│ └── ai_config/ # AI 配置 BLoC
│ ├── ai_config_bloc.dart # AI 配置 BLoC
│ ├── ai_config_event.dart # AI 配置事件
│ └── ai_config_state.dart # AI 配置状态
├── fix_dollar_e/ # 一个独立的 Dart 包/工具 (修复 $e 问题?)
│ └── bin/ # 可执行脚本目录
│ └── fix_dollar_e.dart # 主要执行脚本
└── build/ # Flutter 构建输出目录
├── flutter_assets/ # Flutter 资源文件
│ ├── AssetManifest.bin.json # 二进制资源清单
│ ├── AssetManifest.json # JSON 资源清单
│ ├── FontManifest.json # 字体清单
│ └── packages/ # 包资源
│ └── fluttertoast/ # fluttertoast 包资源
│ └── assets/ # fluttertoast 资源
│ ├── toastify.css # toastify CSS
│ └── toastify.js # toastify JS
└── ce49e7d90cd902197f9a9cbc84219d23/ # (内部构建目录)
└── outputs.json # 构建输出信息
```
## 技术架构
### 前端技术栈
- **框架**: Flutter
- **状态管理**: Bloc模式
- **网络请求**: 服务层与仓库模式
- **国际化**: l10n支持
### 后端技术栈
- **框架**: Spring Boot
- **安全**: Spring Security
- **数据访问**: Spring Data
- **API文档**: Swagger/OpenAPI
- **测试**: JUnit, Postman
## 开发流程
项目采用敏捷开发方法通过迭代方式进行开发。前端和后端团队协作使用Git进行版本控制通过Postman进行API测试。
## 文档资源
- 需求文档: 详细的功能需求说明
- 原型图: UI/UX设计原型
- 测试计划与文档: 测试策略和测试用例
- 后端开发文档: API设计和实现说明
- 前端产品敏捷迭代计划: 前端开发计划和里程碑

View File

@@ -0,0 +1,15 @@
---
description:
globs:
alwaysApply: false
---
# Project Overview
AINovalWriter is an AI-assisted novel writing platform consisting of a frontend application (Flutter) and a backend service (Spring Boot).
- Frontend Entry Point: [AINoval/lib/main.dart](mdc:AINoval/lib/main.dart)
- Backend Entry Point: [AINovalServer/src/main/java/com/ainovel/server/AiNovelServerApplication.java](mdc:AINovalServer/src/main/java/com/ainovel/server/AiNovelServerApplication.java)
- Project Structure Documentation: [项目架构说明.md](mdc:项目架构说明.md)
- Frontend README: [AINoval/README.md](mdc:AINoval/README.md)
- Backend README: [AINovalServer/README.md](mdc:AINovalServer/README.md)
- Overall Documentation: See [documentation_links.mdc](mdc:.cursor/rules/documentation_links.mdc)

6
.cursor/rules/web.mdc Normal file
View File

@@ -0,0 +1,6 @@
---
description:
globs:
alwaysApply: false
---
在前端实现组件的时候要设置合理的长宽使得布局不臃肿也不拥挤同时使用全局主题和全局样式使用纯黑和纯白的组合保持flutter现代和简洁的风格尽量使用和创建全局通用组件并添加相关的说明注释

6
.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
.qodo
AINovalServer\target
.idea
.vscode
deploy
build

46
AINoval/.gitignore vendored Normal file
View File

@@ -0,0 +1,46 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
.qodo

30
AINoval/.metadata Normal file
View File

@@ -0,0 +1,30 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: "17025dd88227cd9532c33fa78f5250d548d87e9a"
channel: "stable"
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
- platform: web
create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'

View File

@@ -0,0 +1,45 @@
include: package:flutter_lints/flutter.yaml
linter:
rules:
- avoid_print
- avoid_empty_else
- avoid_relative_lib_imports
- avoid_returning_null_for_future
- avoid_slow_async_io
- avoid_type_to_string
- avoid_unnecessary_containers
- avoid_unused_constructor_parameters
- await_only_futures
- camel_case_types
- cancel_subscriptions
- close_sinks
- directives_ordering
- flutter_style_todos
- prefer_const_constructors
- prefer_const_declarations
- prefer_final_fields
- prefer_if_elements_to_conditional_expressions
- prefer_interpolation_to_compose_strings
- prefer_is_empty
- prefer_is_not_empty
- prefer_single_quotes
- sized_box_for_whitespace
- sort_child_properties_last
- sort_constructors_first
- unnecessary_const
- unnecessary_new
- unnecessary_overrides
- unnecessary_parenthesis
- unnecessary_this
analyzer:
errors:
missing_required_param: error
missing_return: error
must_be_immutable: error
sort_unnamed_constructors_first: ignore
exclude:
- lib/generated_plugin_registrant.dart
- lib/**/*.g.dart
- lib/**/*.freezed.dart

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Anthropic</title><path d="M13.827 3.52h3.603L24 20h-3.603l-6.57-16.48zm-7.258 0h3.767L16.906 20h-3.674l-1.343-3.461H5.017l-1.344 3.46H0L6.57 3.522zm4.132 9.959L8.453 7.687 6.205 13.48H10.7z"></path></svg>

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -0,0 +1 @@
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Anthropic</title><path d="M13.827 3.52h3.603L24 20h-3.603l-6.57-16.48zm-7.258 0h3.767L16.906 20h-3.674l-1.343-3.461H5.017l-1.344 3.46H0L6.57 3.522zm4.132 9.959L8.453 7.687 6.205 13.48H10.7z"></path></svg>

After

Width:  |  Height:  |  Size: 368 B

View File

@@ -0,0 +1 @@
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>AzureAI</title><path clip-rule="evenodd" d="M16.233 0c.713 0 1.345.551 1.572 1.329.227.778 1.555 5.59 1.555 5.59v9.562h-4.813L14.645 0h1.588z" fill="url(#lobe-icons-azureai-fill-0)" fill-rule="evenodd"></path><path d="M23.298 7.47c0-.34-.275-.6-.6-.6h-2.835a3.617 3.617 0 00-3.614 3.615v5.996h3.436a3.617 3.617 0 003.613-3.614V7.47z" fill="url(#lobe-icons-azureai-fill-1)"></path><path clip-rule="evenodd" d="M16.233 0a.982.982 0 00-.989.989l-.097 18.198A4.814 4.814 0 0110.334 24H1.6a.597.597 0 01-.567-.794l7-19.981A4.819 4.819 0 0112.57 0h3.679-.016z" fill="url(#lobe-icons-azureai-fill-2)" fill-rule="evenodd"></path><defs><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-azureai-fill-0" x1="18.242" x2="14.191" y1="16.837" y2=".616"><stop stop-color="#712575"></stop><stop offset=".09" stop-color="#9A2884"></stop><stop offset=".18" stop-color="#BF2C92"></stop><stop offset=".27" stop-color="#DA2E9C"></stop><stop offset=".34" stop-color="#EB30A2"></stop><stop offset=".4" stop-color="#F131A5"></stop><stop offset=".5" stop-color="#EC30A3"></stop><stop offset=".61" stop-color="#DF2F9E"></stop><stop offset=".72" stop-color="#C92D96"></stop><stop offset=".83" stop-color="#AA2A8A"></stop><stop offset=".95" stop-color="#83267C"></stop><stop offset="1" stop-color="#712575"></stop></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-azureai-fill-1" x1="19.782" x2="19.782" y1=".34" y2="23.222"><stop stop-color="#DA7ED0"></stop><stop offset=".08" stop-color="#B17BD5"></stop><stop offset=".19" stop-color="#8778DB"></stop><stop offset=".3" stop-color="#6276E1"></stop><stop offset=".41" stop-color="#4574E5"></stop><stop offset=".54" stop-color="#2E72E8"></stop><stop offset=".67" stop-color="#1D71EB"></stop><stop offset=".81" stop-color="#1471EC"></stop><stop offset="1" stop-color="#1171ED"></stop></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-azureai-fill-2" x1="18.404" x2="3.236" y1=".859" y2="25.183"><stop stop-color="#DA7ED0"></stop><stop offset=".05" stop-color="#B77BD4"></stop><stop offset=".11" stop-color="#9079DA"></stop><stop offset=".18" stop-color="#6E77DF"></stop><stop offset=".25" stop-color="#5175E3"></stop><stop offset=".33" stop-color="#3973E7"></stop><stop offset=".42" stop-color="#2772E9"></stop><stop offset=".54" stop-color="#1A71EB"></stop><stop offset=".68" stop-color="#1371EC"></stop><stop offset="1" stop-color="#1171ED"></stop></linearGradient></defs></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -0,0 +1 @@
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>ChatGLM</title><defs><linearGradient id="lobe-icons-chatglm-fill" x1="-18.756%" x2="70.894%" y1="49.371%" y2="90.944%"><stop offset="0%" stop-color="#504AF4"></stop><stop offset="100%" stop-color="#3485FF"></stop></linearGradient></defs><path d="M9.917 2c4.906 0 10.178 3.947 8.93 10.58-.014.07-.037.14-.057.21l-.003-.277c-.083-3-1.534-8.934-8.87-8.934-3.393 0-8.137 3.054-7.93 8.158-.04 4.778 3.555 8.4 7.95 8.332l.073-.001c1.2-.033 2.763-.429 3.1-1.657.063-.031.26.534.268.598.048.256.112.369.192.34.981-.348 2.286-1.222 1.952-2.38-.176-.61-1.775-.147-1.921-.347.418-.979 2.234-.926 3.153-.716.443.102.657.38 1.012.442.29.052.981-.2.96.242-1.5 3.042-4.893 5.41-8.808 5.41C3.654 22 0 16.574 0 11.737 0 5.947 4.959 2 9.917 2zM9.9 5.3c.484 0 1.125.225 1.38.585 3.669.145 4.313 2.686 4.694 5.444.255 1.838.315 2.3.182 1.387l.083.59c.068.448.554.737.982.516.144-.075.254-.231.328-.47a.2.2 0 01.258-.13l.625.22a.2.2 0 01.124.238 2.172 2.172 0 01-.51.92c-.878.917-2.757.664-3.08-.62-.14-.554-.055-.626-.345-1.242-.292-.621-1.238-.709-1.69-.295-.345.315-.407.805-.406 1.282L12.6 15.9a.9.9 0 01-.9.9h-1.4a.9.9 0 01-.9-.9v-.65a1.15 1.15 0 10-2.3 0v.65a.9.9 0 01-.9.9H4.8a.9.9 0 01-.9-.9l.035-3.239c.012-1.884.356-3.658 2.47-4.134.2-.045.252.13.29.342.025.154.043.252.053.294.701 3.058 1.75 4.299 3.144 3.722l.66-.331.254-.13c.158-.082.25-.131.276-.15.012-.01-.165-.206-.407-.464l-1.012-1.067a8.925 8.925 0 01-.199-.216c-.047-.034-.116.068-.208.306-.074.157-.251.252-.272.326-.013.058.108.298.362.72.164.288.22.508-.31.343-1.04-.8-1.518-2.273-1.684-3.725-.004-.035-.162-1.913-.162-1.913a1.2 1.2 0 011.113-1.281L9.9 5.3zm12.994 8.68c.037.697-.403.704-1.213.591l-1.783-.276c-.265-.053-.385-.099-.313-.147.47-.315 3.268-.93 3.31-.168zm-.915-.083l-.926.042c-.85.077-1.452.24.338.336l.103.003c.815.012 1.264-.359.485-.381zm1.667-3.601h.01c.79.398.067 1.03-.65 1.393-.14.07-.491.176-1.052.315-.241.04-.457.092-.333.16l.01.005c1.952.958-3.123 1.534-2.495 1.285l.38-.148c.68-.266 1.614-.682 1.666-1.337.038-.48 1.253-.442 1.493-.968.048-.106 0-.236-.144-.389-.05-.047-.094-.094-.107-.148-.073-.305.7-.431 1.222-.168zm-2.568-.474c-.135 1.198-2.479 4.192-1.949 2.863l.017-.042c.298-.717.376-2.221 1.337-3.221.25-.26.636.035.595.4zm-7.976-.253c.02-.694 1.002-.968 1.346-.347.01-1.274-1.941-.768-1.346.347z" fill="url(#lobe-icons-chatglm-fill)" fill-rule="evenodd"></path></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@@ -0,0 +1 @@
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Claude</title><path d="M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z" fill="#D97757" fill-rule="nonzero"></path></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@@ -0,0 +1 @@
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Claude</title><path d="M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z" fill="#D97757" fill-rule="nonzero"></path></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1 @@
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Coze</title><path clip-rule="evenodd" d="M3.908 9.096A8.092 8.092 0 0111.998 1h.006c4.468 0 8.09 3.628 8.09 8.096v3.392h1.942c2.23 0 2.732 3.126.615 3.828l-2.556.85v1.466a1.947 1.947 0 01-2.818 1.742l-1.42-.707c-.067-.03-.149 0-.17.071-1.147 3.587-6.225 3.587-7.373 0a.123.123 0 00-.169-.07l-1.42.706c-1.29.65-2.817-.292-2.817-1.742v-1.466l-2.557-.85c-2.122-.697-1.614-3.828.615-3.828h1.942V9.096zm4.571 2.613a.784.784 0 00-.784.784v1.568a.784.784 0 101.568 0v-1.568a.784.784 0 00-.784-.784zm7.045.779a.784.784 0 100 1.568.784.784 0 000-1.568zm-6.186 3.415a.78.78 0 00.17.254 3.517 3.517 0 004.98 0 .782.782 0 10-1.106-1.107 1.958 1.958 0 01-2.767 0 .78.78 0 00-1.277.254.78.78 0 000 .6z"></path></svg>

After

Width:  |  Height:  |  Size: 866 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@@ -0,0 +1 @@
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>DeepSeek</title><path d="M23.748 4.482c-.254-.124-.364.113-.512.234-.051.039-.094.09-.137.136-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.156-.708-.311-.955-.65-.172-.241-.219-.51-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.093.172.187.129.323-.082.28-.18.552-.266.833-.055.179-.137.217-.329.14a5.526 5.526 0 01-1.736-1.18c-.857-.828-1.631-1.742-2.597-2.458a11.365 11.365 0 00-.689-.471c-.985-.957.13-1.743.388-1.836.27-.098.093-.432-.779-.428-.872.004-1.67.295-2.687.684a3.055 3.055 0 01-.465.137 9.597 9.597 0 00-2.883-.102c-1.885.21-3.39 1.102-4.497 2.623C.082 8.606-.231 10.684.152 12.85c.403 2.284 1.569 4.175 3.36 5.653 1.858 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.133-.284 4.994-1.86.47.234.962.327 1.78.397.63.059 1.236-.03 1.705-.128.735-.156.684-.837.419-.961-2.155-1.004-1.682-.595-2.113-.926 1.096-1.296 2.746-2.642 3.392-7.003.05-.347.007-.565 0-.845-.004-.17.035-.237.23-.256a4.173 4.173 0 001.545-.475c1.396-.763 1.96-2.015 2.093-3.517.02-.23-.004-.467-.247-.588zM11.581 18c-2.089-1.642-3.102-2.183-3.52-2.16-.392.024-.321.471-.235.763.09.288.207.486.371.739.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.167-1.361-.802-2.5-1.86-3.301-3.307-.774-1.393-1.224-2.887-1.298-4.482-.02-.386.093-.522.477-.592a4.696 4.696 0 011.529-.039c2.132.312 3.946 1.265 5.468 2.774.868.86 1.525 1.887 2.202 2.891.72 1.066 1.494 2.082 2.48 2.914.348.292.625.514.891.677-.802.09-2.14.11-3.054-.614zm1-6.44a.306.306 0 01.415-.287.302.302 0 01.2.288.306.306 0 01-.31.307.303.303 0 01-.304-.308zm3.11 1.596c-.2.081-.399.151-.59.16a1.245 1.245 0 01-.798-.254c-.274-.23-.47-.358-.552-.758a1.73 1.73 0 01.016-.588c.07-.327-.008-.537-.239-.727-.187-.156-.426-.199-.688-.199a.559.559 0 01-.254-.078c-.11-.054-.2-.19-.114-.358.028-.054.16-.186.192-.21.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.391.451.462.576.685.914.176.265.336.537.445.848.067.195-.019.354-.25.452z" fill="#4D6BFE"></path></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@@ -0,0 +1 @@
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Doubao</title><path d="M5.31 15.756c.172-3.75 1.883-5.999 2.549-6.739-3.26 2.058-5.425 5.658-6.358 8.308v1.12C1.501 21.513 4.226 24 7.59 24a6.59 6.59 0 002.2-.375c.353-.12.7-.248 1.039-.378.913-.899 1.65-1.91 2.243-2.992-4.877 2.431-7.974.072-7.763-4.5l.002.001z" fill="#1E37FC"></path><path d="M22.57 10.283c-1.212-.901-4.109-2.404-7.397-2.8.295 3.792.093 8.766-2.1 12.773a12.782 12.782 0 01-2.244 2.992c3.764-1.448 6.746-3.457 8.596-5.219 2.82-2.683 3.353-5.178 3.361-6.66a2.737 2.737 0 00-.216-1.084v-.002z" fill="#37E1BE"></path><path d="M14.303 1.867C12.955.7 11.248 0 9.39 0 7.532 0 5.883.677 4.545 1.807 2.791 3.29 1.627 5.557 1.5 8.125v9.201c.932-2.65 3.097-6.25 6.357-8.307.5-.318 1.025-.595 1.569-.829 1.883-.801 3.878-.932 5.746-.706-.222-2.83-.718-5.002-.87-5.617h.001z" fill="#A569FF"></path><path d="M17.305 4.961a199.47 199.47 0 01-1.08-1.094c-.202-.213-.398-.419-.586-.622l-1.333-1.378c.151.615.648 2.786.869 5.617 3.288.395 6.185 1.898 7.396 2.8-1.306-1.275-3.475-3.487-5.266-5.323z" fill="#1E37FC"></path></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1 @@
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Gemini</title><defs><linearGradient id="lobe-icons-gemini-fill" x1="0%" x2="68.73%" y1="100%" y2="30.395%"><stop offset="0%" stop-color="#1C7DFF"></stop><stop offset="52.021%" stop-color="#1C69FF"></stop><stop offset="100%" stop-color="#F0DCD6"></stop></linearGradient></defs><path d="M12 24A14.304 14.304 0 000 12 14.304 14.304 0 0012 0a14.305 14.305 0 0012 12 14.305 14.305 0 00-12 12" fill="url(#lobe-icons-gemini-fill)" fill-rule="nonzero"></path></svg>

After

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View File

@@ -0,0 +1 @@
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Gemini</title><defs><linearGradient id="lobe-icons-gemini-fill" x1="0%" x2="68.73%" y1="100%" y2="30.395%"><stop offset="0%" stop-color="#1C7DFF"></stop><stop offset="52.021%" stop-color="#1C69FF"></stop><stop offset="100%" stop-color="#F0DCD6"></stop></linearGradient></defs><path d="M12 24A14.304 14.304 0 000 12 14.304 14.304 0 0012 0a14.305 14.305 0 0012 12 14.305 14.305 0 00-12 12" fill="url(#lobe-icons-gemini-fill)" fill-rule="nonzero"></path></svg>

After

Width:  |  Height:  |  Size: 581 B

View File

@@ -0,0 +1 @@
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Google</title><path d="M23 12.245c0-.905-.075-1.565-.236-2.25h-10.54v4.083h6.186c-.124 1.014-.797 2.542-2.294 3.569l-.021.136 3.332 2.53.23.022C21.779 18.417 23 15.593 23 12.245z" fill="#4285F4"></path><path d="M12.225 23c3.03 0 5.574-.978 7.433-2.665l-3.542-2.688c-.948.648-2.22 1.1-3.891 1.1a6.745 6.745 0 01-6.386-4.572l-.132.011-3.465 2.628-.045.124C4.043 20.531 7.835 23 12.225 23z" fill="#34A853"></path><path d="M5.84 14.175A6.65 6.65 0 015.463 12c0-.758.138-1.491.361-2.175l-.006-.147-3.508-2.67-.115.054A10.831 10.831 0 001 12c0 1.772.436 3.447 1.197 4.938l3.642-2.763z" fill="#FBBC05"></path><path d="M12.225 5.253c2.108 0 3.529.892 4.34 1.638l3.167-3.031C17.787 2.088 15.255 1 12.225 1 7.834 1 4.043 3.469 2.197 7.062l3.63 2.763a6.77 6.77 0 016.398-4.572z" fill="#EB4335"></path></svg>

After

Width:  |  Height:  |  Size: 920 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@@ -0,0 +1 @@
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Grok</title><path d="M9.27 15.29l7.978-5.897c.391-.29.95-.177 1.137.272.98 2.369.542 5.215-1.41 7.169-1.951 1.954-4.667 2.382-7.149 1.406l-2.711 1.257c3.889 2.661 8.611 2.003 11.562-.953 2.341-2.344 3.066-5.539 2.388-8.42l.006.007c-.983-4.232.242-5.924 2.75-9.383.06-.082.12-.164.179-.248l-3.301 3.305v-.01L9.267 15.292M7.623 16.723c-2.792-2.67-2.31-6.801.071-9.184 1.761-1.763 4.647-2.483 7.166-1.425l2.705-1.25a7.808 7.808 0 00-1.829-1A8.975 8.975 0 005.984 5.83c-2.533 2.536-3.33 6.436-1.962 9.764 1.022 2.487-.653 4.246-2.34 6.022-.599.63-1.199 1.259-1.682 1.925l7.62-6.815"></path></svg>

After

Width:  |  Height:  |  Size: 756 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View File

@@ -0,0 +1 @@
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>HuggingFace</title><g fill="none" fill-rule="nonzero"><path d="M2.25 11.535c0-3.407 1.847-6.554 4.844-8.258a9.822 9.822 0 019.687 0c2.997 1.704 4.844 4.851 4.844 8.258 0 5.266-4.337 9.535-9.687 9.535S2.25 16.8 2.25 11.535z" fill="#FF9D0B"></path><path d="M11.938 20.086c4.797 0 8.687-3.829 8.687-8.551 0-4.722-3.89-8.55-8.687-8.55-4.798 0-8.688 3.828-8.688 8.55 0 4.722 3.89 8.55 8.688 8.55z" fill="#FFD21E"></path><path d="M11.875 15.113c2.457 0 3.25-2.156 3.25-3.263 0-.576-.393-.394-1.023-.089-.582.283-1.365.675-2.224.675-1.798 0-3.25-1.693-3.25-.586 0 1.107.79 3.263 3.25 3.263h-.003z" fill="#FF323D"></path><path d="M14.76 9.21c.32.108.445.753.767.585.447-.233.707-.708.659-1.204a1.235 1.235 0 00-.879-1.059 1.262 1.262 0 00-1.33.394c-.322.384-.377.92-.14 1.36.153.283.638-.177.925-.079l-.002.003zm-5.887 0c-.32.108-.448.753-.768.585a1.226 1.226 0 01-.658-1.204c.048-.495.395-.913.878-1.059a1.262 1.262 0 011.33.394c.322.384.377.92.14 1.36-.152.283-.64-.177-.925-.079l.003.003zm1.12 5.34a2.166 2.166 0 011.325-1.106c.07-.02.144.06.219.171l.192.306c.069.1.139.175.209.175.074 0 .15-.074.223-.172l.205-.302c.08-.11.157-.188.234-.165.537.168.986.536 1.25 1.026.932-.724 1.275-1.905 1.275-2.633 0-.508-.306-.426-.81-.19l-.616.296c-.52.24-1.148.48-1.824.48-.676 0-1.302-.24-1.823-.48l-.589-.283c-.52-.248-.838-.342-.838.177 0 .703.32 1.831 1.187 2.56l.18.14z" fill="#3A3B45"></path><path d="M17.812 10.366a.806.806 0 00.813-.8c0-.441-.364-.8-.813-.8a.806.806 0 00-.812.8c0 .442.364.8.812.8zm-11.624 0a.806.806 0 00.812-.8c0-.441-.364-.8-.812-.8a.806.806 0 00-.813.8c0 .442.364.8.813.8zM4.515 13.073c-.405 0-.765.162-1.017.46a1.455 1.455 0 00-.333.925 1.801 1.801 0 00-.485-.074c-.387 0-.737.146-.985.409a1.41 1.41 0 00-.2 1.722 1.302 1.302 0 00-.447.694c-.06.222-.12.69.2 1.166a1.267 1.267 0 00-.093 1.236c.238.533.81.958 1.89 1.405l.24.096c.768.3 1.473.492 1.478.494.89.243 1.808.375 2.732.394 1.465 0 2.513-.443 3.115-1.314.93-1.342.842-2.575-.274-3.763l-.151-.154c-.692-.684-1.155-1.69-1.25-1.912-.195-.655-.71-1.383-1.562-1.383-.46.007-.889.233-1.15.605-.25-.31-.495-.553-.715-.694a1.87 1.87 0 00-.993-.312zm14.97 0c.405 0 .767.162 1.017.46.216.262.333.588.333.925.158-.047.322-.071.487-.074.388 0 .738.146.985.409a1.41 1.41 0 01.2 1.722c.22.178.377.422.445.694.06.222.12.69-.2 1.166.244.37.279.836.093 1.236-.238.533-.81.958-1.889 1.405l-.239.096c-.77.3-1.475.492-1.48.494-.89.243-1.808.375-2.732.394-1.465 0-2.513-.443-3.115-1.314-.93-1.342-.842-2.575.274-3.763l.151-.154c.695-.684 1.157-1.69 1.252-1.912.195-.655.708-1.383 1.56-1.383.46.007.889.233 1.15.605.25-.31.495-.553.718-.694.244-.162.523-.265.814-.3l.176-.012z" fill="#FF9D0B"></path><path d="M9.785 20.132c.688-.994.638-1.74-.305-2.667-.945-.928-1.495-2.288-1.495-2.288s-.205-.788-.672-.714c-.468.074-.81 1.25.17 1.971.977.721-.195 1.21-.573.534-.375-.677-1.405-2.416-1.94-2.751-.532-.332-.907-.148-.782.541.125.687 2.357 2.35 2.14 2.707-.218.362-.983-.42-.983-.42S2.953 14.9 2.43 15.46c-.52.558.398 1.026 1.7 1.803 1.308.778 1.41.985 1.225 1.28-.187.295-3.07-2.1-3.34-1.083-.27 1.011 2.943 1.304 2.745 2.006-.2.7-2.265-1.324-2.685-.537-.425.79 2.913 1.718 2.94 1.725 1.075.276 3.813.859 4.77-.522zm4.432 0c-.687-.994-.64-1.74.305-2.667.943-.928 1.493-2.288 1.493-2.288s.205-.788.675-.714c.465.074.807 1.25-.17 1.971-.98.721.195 1.21.57.534.377-.677 1.407-2.416 1.94-2.751.532-.332.91-.148.782.541-.125.687-2.355 2.35-2.137 2.707.215.362.98-.42.98-.42S21.05 14.9 21.57 15.46c.52.558-.395 1.026-1.7 1.803-1.308.778-1.408.985-1.225 1.28.187.295 3.07-2.1 3.34-1.083.27 1.011-2.94 1.304-2.743 2.006.2.7 2.263-1.324 2.685-.537.423.79-2.912 1.718-2.94 1.725-1.077.276-3.815.859-4.77-.522z" fill="#FFD21E"></path></g></svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -0,0 +1 @@
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Kling</title><path d="M5.412 13.775A23.193 23.193 0 017.41 9.32c3.17-5.492 7.795-8.757 10.33-7.294C12.038-1.266 4.598.944 1.122 6.964A13.378 13.378 0 00.085 9.22c-.259.739.092 1.534.77 1.926l4.557 2.63z" fill="url(#lobe-icons-kling-fill-0)"></path><path d="M18.588 10.164a23.188 23.188 0 01-1.999 4.455c-3.17 5.492-7.795 8.758-10.33 7.294 5.703 3.293 13.143 1.082 16.619-4.938a13.392 13.392 0 001.037-2.255c.259-.738-.092-1.534-.77-1.925l-4.557-2.63z" fill="url(#lobe-icons-kling-fill-1)"></path><path d="M16.59 14.62c3.17-5.492 3.686-11.13 1.15-12.594C15.207.563 10.582 3.83 7.41 9.32c2.074-3.59 5.809-5.315 8.344-3.852 2.534 1.464 2.908 5.56.835 9.151z" fill="url(#lobe-icons-kling-fill-2)"></path><path d="M7.41 9.32c-3.17 5.492-3.686 11.13-1.15 12.593 2.534 1.464 7.159-1.802 10.33-7.294-2.074 3.591-5.809 5.316-8.344 3.852-2.534-1.463-2.908-5.56-.835-9.15z" fill="url(#lobe-icons-kling-fill-3)"></path><defs><radialGradient cx="0" cy="0" gradientTransform="matrix(7.47772 -12.51022 17.14368 10.24728 5.173 13.637)" gradientUnits="userSpaceOnUse" id="lobe-icons-kling-fill-0" r="1"><stop offset=".095" stop-color="#FFF959"></stop><stop offset=".326" stop-color="#0DF35E"></stop><stop offset=".64" stop-color="#0BF2F9"></stop><stop offset="1" stop-color="#04A6F0"></stop></radialGradient><radialGradient cx="0" cy="0" gradientTransform="rotate(120.868 6.491 10.491) scale(14.5747 19.9728)" gradientUnits="userSpaceOnUse" id="lobe-icons-kling-fill-1" r="1"><stop offset=".095" stop-color="#FFF959"></stop><stop offset=".326" stop-color="#0DF35E"></stop><stop offset=".64" stop-color="#0BF2F9"></stop><stop offset="1" stop-color="#04A6F0"></stop></radialGradient><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-kling-fill-2" x1="15.578" x2="18.062" y1="1.798" y2="9.861"><stop stop-color="#003EFF"></stop><stop offset="1" stop-color="#0BFFE7"></stop></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-kling-fill-3" x1="8.422" x2="5.938" y1="22.142" y2="14.079"><stop stop-color="#003EFF"></stop><stop offset="1" stop-color="#0BFFE7"></stop></linearGradient></defs></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.9 KiB

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