Compare commits

..

67 Commits

Author SHA1 Message Date
ONLY-yours b8b1ab6616 feat: add loading back 2025-11-17 17:20:03 +08:00
ONLY-yours 3891015a3d fix: test mobile 2025-11-17 16:33:16 +08:00
ONLY-yours 5babb7d826 fix: try to fixed 2025-11-17 16:11:20 +08:00
ONLY-yours a7504b696a test: test the loading error 2025-11-17 15:38:29 +08:00
ONLY-yours 9dc4308942 fix: add router ErrorBoundary 2025-11-17 15:16:37 +08:00
ONLY-yours 082117998d fix: fixed the test error 2025-11-17 11:42:26 +08:00
ONLY-yours 9a74d6c045 fix: fix the reload was loading page problem 2025-11-17 11:26:38 +08:00
ONLY-yours b1a4f24dc9 fix: mobile chat settings go back 2025-11-17 11:19:38 +08:00
ONLY-yours c47551775b fix: delete uesless code 2025-11-17 11:04:24 +08:00
ONLY-yours 2d83300795 fix: delete useless code 2025-11-17 10:51:20 +08:00
ONLY-yours 0915538da8 Merge remote-tracking branch 'origin/next' into refactor/changeAllToSpa 2025-11-17 10:35:43 +08:00
ONLY-yours 53fc0642e0 feat: use more simple way to update session hydration 2025-11-15 19:31:05 +08:00
ONLY-yours a8c725abd5 Merge remote-tracking branch 'origin/next' into refactor/changeAllToSpa 2025-11-15 19:08:58 +08:00
ONLY-yours b8a7f6e9eb feat: update the useQueryParams throttleMs params 2025-11-15 19:05:17 +08:00
ONLY-yours bb594f87e2 fix: fixed the test 2025-11-14 23:44:57 +08:00
ONLY-yours b0ee9b434e fix: fixed the url & new url not path problem 2025-11-14 23:34:31 +08:00
ONLY-yours cf2c5a1d37 fix: fixed router link error 2025-11-14 17:15:09 +08:00
ONLY-yours 0511e43a48 fix: fixed usage router error 2025-11-14 17:09:21 +08:00
ONLY-yours 1f128f407f Merge remote-tracking branch 'origin/next' into refactor/changeAllToSpa 2025-11-14 16:58:34 +08:00
ONLY-yours f258a2e042 fix: fixed the desktop knowledge page router 2025-11-14 16:18:55 +08:00
ONLY-yours 7996e1c431 Merge remote-tracking branch 'origin/next' into refactor/changeAllToSpa 2025-11-14 16:07:47 +08:00
ONLY-yours 93dddfc2e5 feat: rollback some changes about layout 2025-11-14 15:58:50 +08:00
ONLY-yours 5e4186559b fix: fix useNav in discover page error problem 2025-11-14 15:42:16 +08:00
ONLY-yours 9bfd9bb4a5 Merge remote-tracking branch 'origin/next' into refactor/changeAllToSpa 2025-11-14 15:05:02 +08:00
ONLY-yours 9ca54135b5 feat: fix a lot router problem 2025-11-14 14:45:24 +08:00
ONLY-yours f162556607 fix: delete the changelog modal page 2025-11-14 10:24:31 +08:00
ONLY-yours 3292ed83f9 fix: fix mobile router goback fc 2025-11-13 20:24:28 +08:00
ONLY-yours 561a38f788 fix: delete useless code 2025-11-13 20:08:58 +08:00
ONLY-yours 71aaf0fac5 chore: update test.ts in TopActions.tsx 2025-11-13 19:11:33 +08:00
ONLY-yours 287601f8ec fix: close the loading in the layout loading 2025-11-13 19:06:37 +08:00
ONLY-yours b36f8781e6 feat: use starTransition to navigate url 2025-11-13 18:02:16 +08:00
ONLY-yours 705450a571 fix: add files back 2025-11-13 17:17:36 +08:00
ONLY-yours 5272c7373f fix: add files back 2025-11-13 17:14:49 +08:00
ONLY-yours fb24b6f1b7 fix: add nuqs back & useQueryState back in oath 2025-11-13 17:09:10 +08:00
ONLY-yours 2fd65fe8a3 fix: discover find more link error fixed 2025-11-13 17:02:52 +08:00
ONLY-yours 35d5a2c937 chore: add mobile me layout back 2025-11-13 16:59:23 +08:00
ONLY-yours 42f40d2717 feat: change the mobile me layout back 2025-11-13 16:41:53 +08:00
ONLY-yours ef8a644d8c feat: delete all nuqs 2025-11-13 16:25:59 +08:00
ONLY-yours 81c84348bc fix: change the changelog pages render 2025-11-13 15:25:48 +08:00
ONLY-yours 8d7a0467db fix: fix build problem 2025-11-13 14:18:08 +08:00
ONLY-yours e9522729c5 fix: fix hydrateFallback problem 2025-11-13 11:49:35 +08:00
ONLY-yours cf01894077 feat: change local params get use ReactRouter Outlet context 2025-11-13 11:03:12 +08:00
ONLY-yours b5d945b1fd fix: delete some layout tsx & update the ts 2025-11-12 17:16:26 +08:00
ONLY-yours cbee964582 feat: change NextJs Link useRouter useSearchParams change to react-router way 2025-11-12 17:01:31 +08:00
ONLY-yours 87a38ad0c4 feat: change the :slug to react-router loader to get 2025-11-12 16:27:34 +08:00
ONLY-yours f2d4745ad3 Merge remote-tracking branch 'origin/next' into refactor/changeAllToSpa 2025-11-12 15:00:36 +08:00
ONLY-yours 0167ac8e28 feat: change all routes to outer routes 2025-11-12 15:00:06 +08:00
ONLY-yours b480227fd0 feat: discover pages layout & pages routers get done 2025-11-12 11:56:20 +08:00
ONLY-yours 97ff98cada Merge remote-tracking branch 'origin/next' into refactor/changeAllToSpa 2025-11-11 23:17:32 +08:00
ONLY-yours 845d3ef58a feat: change all discover page to the spa 2025-11-11 23:16:57 +08:00
ONLY-yours 906917362f feat: /chat delete pages & layouts dir 2025-11-11 17:45:12 +08:00
ONLY-yours c69049d6da fix: refactor the memory router to browser router 2025-11-11 16:01:32 +08:00
ONLY-yours 4f7356ffab feat: change AppRouter to Desktop Router & mobile Router to dynamic import 2025-11-08 17:52:05 +08:00
ONLY-yours d20c82c115 fix: change the router judge by servers 2025-11-08 11:59:00 +08:00
ONLY-yours d617a6cd97 fix: slove ts problem 2025-11-07 23:34:43 +08:00
ONLY-yours 408391eeb6 fix: slove the router back 2025-11-07 23:14:47 +08:00
ONLY-yours 4a2e671f55 fix: fix the test 2025-11-07 22:53:49 +08:00
ONLY-yours 695a261df1 Merge remote-tracking branch 'origin/next' into refactor/changeAllToSpa 2025-11-07 22:35:37 +08:00
ONLY-yours 39b723eff4 feat: fix mobile agent settings page not work problem 2025-11-07 22:24:03 +08:00
ONLY-yours 68937d842c fix: delete useless code 2025-11-07 22:16:17 +08:00
ONLY-yours b66bc66260 feat: link replace to react-router-dom 2025-11-07 22:06:18 +08:00
ONLY-yours 4d06279abd feat: change some nextjs router to react-router-dom use 2025-11-07 21:56:03 +08:00
ONLY-yours 1a8d33fbf4 fix: change the goback & knowledge/base url 2025-11-07 21:22:56 +08:00
ONLY-yours 2c086373cc feat: use loading to dynamic loading 2025-11-07 21:09:52 +08:00
ONLY-yours c7d49258f8 feat: change /settings labs image profile changelog to spa mode 2025-11-07 20:34:06 +08:00
ONLY-yours 2280fd6ff9 feat: disable / to /chat rewrite 2025-11-07 18:02:55 +08:00
ONLY-yours 8eb901c401 feat: change the root path to react-router-dom to render spa 2025-11-07 18:01:56 +08:00
125 changed files with 807 additions and 3501 deletions
+3 -7
View File
@@ -1,7 +1,7 @@
name: Desktop PR Build
on:
pull_request:
pull_request_target:
types: [synchronize, labeled, unlabeled] # PR 更新或标签变化时触发
# 确保同一 PR 同一时间只运行一个相同的 workflow,取消正在进行的旧的运行
@@ -126,7 +126,6 @@ jobs:
run: npm run workflow:set-desktop-version ${{ needs.version.outputs.version }} nightly
# macOS 构建处理
# 注意:fork 的 PR 无法访问 secrets,会构建未签名版本
- name: Build artifact on macOS
if: runner.os == 'macOS'
run: npm run desktop:build
@@ -137,7 +136,7 @@ jobs:
DATABASE_URL: "postgresql://postgres@localhost:5432/postgres"
# 默认添加一个加密 SECRET
KEY_VAULTS_SECRET: "oLXWIiR/AKF+rWaqy9lHkrYgzpATbW3CtJp3UfkVgpE="
# macOS 签名和公证配置fork 的 PR 访问不到 secrets,会跳过签名)
# macOS 签名和公证配置
CSC_LINK: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
NEXT_PUBLIC_DESKTOP_PROJECT_ID: ${{ secrets.UMAMI_NIGHTLY_DESKTOP_PROJECT_ID }}
@@ -149,8 +148,7 @@ jobs:
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
# Windows 平台构建处理
# 注意:fork 的 PR 无法访问 secrets,会构建未签名版本
# Windows 平台构建处理
- name: Build artifact on Windows
if: runner.os == 'Windows'
run: npm run desktop:build
@@ -277,8 +275,6 @@ jobs:
publish-pr:
needs: [merge-mac-files, version]
name: Publish PR Build
# 只为非 fork 的 PR 发布(fork 的 PR 没有写权限)
if: github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
# Grant write permissions for creating release and commenting on PR
permissions:
-142
View File
@@ -2,148 +2,6 @@
# Changelog
## [Version 2.0.0-next.75](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.74...v2.0.0-next.75)
<sup>Released on **2025-11-18**</sup>
#### 💄 Styles
- **misc**: Update i18n.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Styles
- **misc**: Update i18n, closes [#10277](https://github.com/lobehub/lobe-chat/issues/10277) ([7563b62](https://github.com/lobehub/lobe-chat/commit/7563b62))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.74](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.73...v2.0.0-next.74)
<sup>Released on **2025-11-17**</sup>
#### ✨ Features
- **misc**: Edit local file render & intervention.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's improved
- **misc**: Edit local file render & intervention, closes [#10269](https://github.com/lobehub/lobe-chat/issues/10269) ([3785a71](https://github.com/lobehub/lobe-chat/commit/3785a71))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.73](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.72...v2.0.0-next.73)
<sup>Released on **2025-11-17**</sup>
#### ✨ Features
- **misc**: Support parallel topic agent runtime.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's improved
- **misc**: Support parallel topic agent runtime, closes [#10273](https://github.com/lobehub/lobe-chat/issues/10273) ([02eba3c](https://github.com/lobehub/lobe-chat/commit/02eba3c))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.72](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.71...v2.0.0-next.72)
<sup>Released on **2025-11-17**</sup>
#### 💄 Styles
- **misc**: Add model information for the Qiniu provider.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### Styles
- **misc**: Add model information for the Qiniu provider, closes [#10270](https://github.com/lobehub/lobe-chat/issues/10270) ([06af793](https://github.com/lobehub/lobe-chat/commit/06af793))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.71](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.70...v2.0.0-next.71)
<sup>Released on **2025-11-17**</sup>
#### 🐛 Bug Fixes
- **misc**: Fix desktop user panel.
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
#### What's fixed
- **misc**: Fix desktop user panel, closes [#10272](https://github.com/lobehub/lobe-chat/issues/10272) ([6a374d2](https://github.com/lobehub/lobe-chat/commit/6a374d2))
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.70](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.69...v2.0.0-next.70)
<sup>Released on **2025-11-17**</sup>
<br/>
<details>
<summary><kbd>Improvements and Fixes</kbd></summary>
</details>
<div align="right">
[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
</div>
## [Version 2.0.0-next.69](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.68...v2.0.0-next.69)
<sup>Released on **2025-11-17**</sup>
-1
View File
@@ -52,7 +52,6 @@
"@typescript/native-preview": "7.0.0-dev.20250711.1",
"consola": "^3.4.2",
"cookie": "^1.0.2",
"diff": "^8.0.2",
"electron": "^38.7.0",
"electron-builder": "^26.0.12",
"electron-is": "^3.0.0",
@@ -18,7 +18,6 @@ import {
WriteLocalFileParams,
} from '@lobechat/electron-client-ipc';
import { SYSTEM_FILES_TO_IGNORE, loadFile } from '@lobechat/file-loaders';
import { createPatch } from 'diff';
import { shell } from 'electron';
import fg from 'fast-glob';
import { Stats, constants } from 'node:fs';
@@ -95,45 +94,26 @@ export default class LocalFileCtr extends ControllerModule {
}
@ipcClientEvent('readLocalFile')
async readFile({
path: filePath,
loc,
fullContent,
}: LocalReadFileParams): Promise<LocalReadFileResult> {
const effectiveLoc = fullContent ? undefined : (loc ?? [0, 200]);
logger.debug('Starting to read file:', { filePath, fullContent, loc: effectiveLoc });
async readFile({ path: filePath, loc }: LocalReadFileParams): Promise<LocalReadFileResult> {
const effectiveLoc = loc ?? [0, 200];
logger.debug('Starting to read file:', { filePath, loc: effectiveLoc });
try {
const fileDocument = await loadFile(filePath);
const [startLine, endLine] = effectiveLoc;
const lines = fileDocument.content.split('\n');
const totalLineCount = lines.length;
const totalCharCount = fileDocument.content.length;
let content: string;
let charCount: number;
let lineCount: number;
let actualLoc: [number, number];
if (effectiveLoc === undefined) {
// Return full content
content = fileDocument.content;
charCount = totalCharCount;
lineCount = totalLineCount;
actualLoc = [0, totalLineCount];
} else {
// Return specified range
const [startLine, endLine] = effectiveLoc;
const selectedLines = lines.slice(startLine, endLine);
content = selectedLines.join('\n');
charCount = content.length;
lineCount = selectedLines.length;
actualLoc = effectiveLoc;
}
// Adjust slice indices to be 0-based and inclusive/exclusive
const selectedLines = lines.slice(startLine, endLine);
const content = selectedLines.join('\n');
const charCount = content.length;
const lineCount = selectedLines.length;
logger.debug('File read successfully:', {
filePath,
fullContent,
selectedLineCount: lineCount,
totalCharCount,
totalLineCount,
@@ -148,7 +128,7 @@ export default class LocalFileCtr extends ControllerModule {
fileType: fileDocument.fileType,
filename: fileDocument.filename,
lineCount,
loc: actualLoc,
loc: effectiveLoc,
// Line count for the selected range
modifiedTime: fileDocument.modifiedTime,
@@ -731,32 +711,8 @@ export default class LocalFileCtr extends ControllerModule {
// Write back to file
await writeFile(filePath, newContent, 'utf8');
// Generate diff for UI display
const patch = createPatch(filePath, content, newContent, '', '');
const diffText = `diff --git a${filePath} b${filePath}\n${patch}`;
// Calculate lines added and deleted from patch
const patchLines = patch.split('\n');
let linesAdded = 0;
let linesDeleted = 0;
for (const line of patchLines) {
if (line.startsWith('+') && !line.startsWith('+++')) {
linesAdded++;
} else if (line.startsWith('-') && !line.startsWith('---')) {
linesDeleted++;
}
}
logger.info(`${logPrefix} File edited successfully`, {
linesAdded,
linesDeleted,
replacements,
});
logger.info(`${logPrefix} File edited successfully`, { replacements });
return {
diffText,
linesAdded,
linesDeleted,
replacements,
success: true,
};
@@ -183,26 +183,6 @@ describe('LocalFileCtr', () => {
expect(result.totalLineCount).toBe(5);
});
it('should read full file content when fullContent is true', async () => {
const mockFileContent = 'line1\nline2\nline3\nline4\nline5';
vi.mocked(mockLoadFile).mockResolvedValue({
content: mockFileContent,
filename: 'test.txt',
fileType: 'txt',
createdTime: new Date('2024-01-01'),
modifiedTime: new Date('2024-01-02'),
});
const result = await localFileCtr.readFile({ path: '/test/file.txt', fullContent: true });
expect(result.content).toBe(mockFileContent);
expect(result.lineCount).toBe(5);
expect(result.charCount).toBe(mockFileContent.length);
expect(result.totalLineCount).toBe(5);
expect(result.totalCharCount).toBe(mockFileContent.length);
expect(result.loc).toEqual([0, 5]);
});
it('should handle file read error', async () => {
vi.mocked(mockLoadFile).mockRejectedValue(new Error('File not found'));
@@ -412,137 +392,4 @@ describe('LocalFileCtr', () => {
});
});
});
describe('handleEditFile', () => {
it('should replace first occurrence successfully', async () => {
const originalContent = 'Hello world\nHello again\nGoodbye world';
vi.mocked(mockFsPromises.readFile).mockResolvedValue(originalContent);
vi.mocked(mockFsPromises.writeFile).mockResolvedValue(undefined);
const result = await localFileCtr.handleEditFile({
file_path: '/test/file.txt',
old_string: 'Hello',
new_string: 'Hi',
replace_all: false,
});
expect(result.success).toBe(true);
expect(result.replacements).toBe(1);
expect(result.linesAdded).toBe(1);
expect(result.linesDeleted).toBe(1);
expect(result.diffText).toContain('diff --git a/test/file.txt b/test/file.txt');
expect(mockFsPromises.writeFile).toHaveBeenCalledWith(
'/test/file.txt',
'Hi world\nHello again\nGoodbye world',
'utf8',
);
});
it('should replace all occurrences when replace_all is true', async () => {
const originalContent = 'Hello world\nHello again\nHello there';
vi.mocked(mockFsPromises.readFile).mockResolvedValue(originalContent);
vi.mocked(mockFsPromises.writeFile).mockResolvedValue(undefined);
const result = await localFileCtr.handleEditFile({
file_path: '/test/file.txt',
old_string: 'Hello',
new_string: 'Hi',
replace_all: true,
});
expect(result.success).toBe(true);
expect(result.replacements).toBe(3);
expect(result.linesAdded).toBe(3);
expect(result.linesDeleted).toBe(3);
expect(mockFsPromises.writeFile).toHaveBeenCalledWith(
'/test/file.txt',
'Hi world\nHi again\nHi there',
'utf8',
);
});
it('should handle multiline replacement correctly', async () => {
const originalContent = 'function test() {\n console.log("old");\n}';
vi.mocked(mockFsPromises.readFile).mockResolvedValue(originalContent);
vi.mocked(mockFsPromises.writeFile).mockResolvedValue(undefined);
const result = await localFileCtr.handleEditFile({
file_path: '/test/file.js',
old_string: 'console.log("old");',
new_string: 'console.log("new");\n console.log("added");',
replace_all: false,
});
expect(result.success).toBe(true);
expect(result.replacements).toBe(1);
expect(result.linesAdded).toBe(2);
expect(result.linesDeleted).toBe(1);
});
it('should return error when old_string is not found', async () => {
const originalContent = 'Hello world';
vi.mocked(mockFsPromises.readFile).mockResolvedValue(originalContent);
const result = await localFileCtr.handleEditFile({
file_path: '/test/file.txt',
old_string: 'NonExistent',
new_string: 'New',
replace_all: false,
});
expect(result.success).toBe(false);
expect(result.error).toBe('The specified old_string was not found in the file');
expect(result.replacements).toBe(0);
expect(mockFsPromises.writeFile).not.toHaveBeenCalled();
});
it('should handle file read error', async () => {
vi.mocked(mockFsPromises.readFile).mockRejectedValue(new Error('Permission denied'));
const result = await localFileCtr.handleEditFile({
file_path: '/test/file.txt',
old_string: 'Hello',
new_string: 'Hi',
replace_all: false,
});
expect(result.success).toBe(false);
expect(result.error).toBe('Permission denied');
expect(result.replacements).toBe(0);
});
it('should handle file write error', async () => {
const originalContent = 'Hello world';
vi.mocked(mockFsPromises.readFile).mockResolvedValue(originalContent);
vi.mocked(mockFsPromises.writeFile).mockRejectedValue(new Error('Disk full'));
const result = await localFileCtr.handleEditFile({
file_path: '/test/file.txt',
old_string: 'Hello',
new_string: 'Hi',
replace_all: false,
});
expect(result.success).toBe(false);
expect(result.error).toBe('Disk full');
});
it('should generate correct diff format', async () => {
const originalContent = 'line 1\nline 2\nline 3';
vi.mocked(mockFsPromises.readFile).mockResolvedValue(originalContent);
vi.mocked(mockFsPromises.writeFile).mockResolvedValue(undefined);
const result = await localFileCtr.handleEditFile({
file_path: '/test/file.txt',
old_string: 'line 2',
new_string: 'modified line 2',
replace_all: false,
});
expect(result.success).toBe(true);
expect(result.diffText).toContain('diff --git a/test/file.txt b/test/file.txt');
expect(result.diffText).toContain('-line 2');
expect(result.diffText).toContain('+modified line 2');
});
});
});
-40
View File
@@ -1,44 +1,4 @@
[
{
"children": {
"improvements": ["Update i18n."]
},
"date": "2025-11-18",
"version": "2.0.0-next.75"
},
{
"children": {
"features": ["Edit local file render & intervention."]
},
"date": "2025-11-17",
"version": "2.0.0-next.74"
},
{
"children": {
"features": ["Support parallel topic agent runtime."]
},
"date": "2025-11-17",
"version": "2.0.0-next.73"
},
{
"children": {
"improvements": ["Add model information for the Qiniu provider."]
},
"date": "2025-11-17",
"version": "2.0.0-next.72"
},
{
"children": {
"fixes": ["Fix desktop user panel."]
},
"date": "2025-11-17",
"version": "2.0.0-next.71"
},
{
"children": {},
"date": "2025-11-17",
"version": "2.0.0-next.70"
},
{
"children": {
"improvements": ["Remove language_model_settings and remove isDeprecatedEdition."]
-5
View File
@@ -330,11 +330,6 @@
"screenshot": "لقطة شاشة",
"settings": "إعدادات التصدير",
"text": "نص",
"widthMode": {
"label": "وضع العرض",
"narrow": "وضع الشاشة الضيقة",
"wide": "وضع الشاشة الواسعة"
},
"withBackground": "تضمين صورة الخلفية",
"withFooter": "تضمين تذييل",
"withPluginInfo": "تضمين معلومات البرنامج المساعد",
-15
View File
@@ -2225,9 +2225,6 @@
"megrez-3b-instruct": {
"description": "Megrez 3B Instruct هو نموذج صغير الحجم وعالي الكفاءة أطلقته شركة Wuwen Xinqiong."
},
"meituan/longcat-flash-chat": {
"description": "نموذج أساسي غير تأملي مفتوح المصدر من Meituan، مُحسَّن للتفاعل الحواري ومهام الوكلاء الذكيين، ويتميز في استدعاء الأدوات وسيناريوهات التفاعل المعقدة متعددة الجولات."
},
"meta-llama-3-70b-instruct": {
"description": "نموذج قوي بحجم 70 مليار معلمة يتفوق في التفكير، والترميز، وتطبيقات اللغة الواسعة."
},
@@ -2459,9 +2456,6 @@
"minimax-m2": {
"description": "MiniMax M2 هو نموذج لغوي كبير وفعّال، تم تطويره خصيصًا لتلبية احتياجات الترميز وتدفقات عمل الوكلاء."
},
"minimax/minimax-m2": {
"description": "مصمم خصيصًا للترميز الفعّال وتدفقات عمل الوكلاء."
},
"ministral-3b-latest": {
"description": "Ministral 3B هو نموذج حافة عالمي المستوى من Mistral."
},
@@ -3377,12 +3371,6 @@
"wizardlm2:8x22b": {
"description": "WizardLM 2 هو نموذج لغوي تقدمه Microsoft AI، يتميز بأداء ممتاز في الحوار المعقد، واللغات المتعددة، والاستدلال، والمساعدين الذكيين."
},
"x-ai/grok-4-fast": {
"description": "يسعدنا أن نعلن عن إصدار Grok 4 Fast، وهو أحدث تقدم لنا في نماذج الاستدلال الفعّالة من حيث التكلفة."
},
"x-ai/grok-code-fast-1": {
"description": "يسعدنا إطلاق grok-code-fast-1، وهو نموذج استدلال سريع وفعّال من حيث التكلفة يتميز في ترميز الوكلاء."
},
"x1": {
"description": "سيتم ترقية نموذج Spark X1 بشكل أكبر، حيث ستحقق المهام العامة مثل الاستدلال، وتوليد النصوص، وفهم اللغة نتائج تتماشى مع OpenAI o1 و DeepSeek R1."
},
@@ -3443,9 +3431,6 @@
"yi-vision-v2": {
"description": "نموذج مهام بصرية معقدة، يوفر فهمًا عالي الأداء وقدرات تحليلية بناءً على صور متعددة."
},
"z-ai/glm-4.6": {
"description": "GLM-4.6 هو النموذج الرائد الأحدث من Zhipu، ويتفوق على الجيل السابق في الترميز المتقدم، ومعالجة النصوص الطويلة، والاستدلال، وقدرات الوكلاء الذكيين."
},
"zai-org/GLM-4.5": {
"description": "GLM-4.5 هو نموذج أساسي مصمم لتطبيقات الوكلاء الذكية، يستخدم بنية Mixture-of-Experts (MoE). تم تحسينه بعمق في مجالات استدعاء الأدوات، تصفح الويب، هندسة البرمجيات، وبرمجة الواجهة الأمامية، ويدعم التكامل السلس مع وكلاء الكود مثل Claude Code وRoo Code. يستخدم وضع استدلال مختلط ليتكيف مع سيناريوهات الاستدلال المعقدة والاستخدام اليومي."
},
+1 -12
View File
@@ -15,12 +15,6 @@
"prompt": "كلمة تلميح"
},
"localFiles": {
"editFile": {
"newString": "استبدال بـ",
"oldString": "البحث عن",
"replaceAll": "استبدال جميع المطابقات",
"replaceFirst": "استبدال أول مطابقة فقط"
},
"file": "ملف",
"folder": "مجلد",
"moveFiles": {
@@ -40,12 +34,7 @@
"readFile": "قراءة الملف",
"readFileError": "فشل في قراءة الملف، يرجى التحقق من صحة مسار الملف",
"readFiles": "قراءة الملفات",
"readFilesError": "فشل في قراءة الملفات، يرجى التحقق من صحة مسار الملف",
"writeFile": {
"characters": "أحرف",
"preview": "معاينة المحتوى",
"truncated": "تم الاقتطاع"
}
"readFilesError": "فشل في قراءة الملفات، يرجى التحقق من صحة مسار الملف"
},
"search": {
"createNewSearch": "إنشاء سجل بحث جديد",
-5
View File
@@ -330,11 +330,6 @@
"screenshot": "Екранна снимка",
"settings": "Настройки за експортиране",
"text": "Текст",
"widthMode": {
"label": "Режим на ширина",
"narrow": "Режим за тесен екран",
"wide": "Режим за широк екран"
},
"withBackground": "Включи фоново изображение",
"withFooter": "Включи долен колонтитул",
"withPluginInfo": "Включи информация за плъгина",
-15
View File
@@ -2225,9 +2225,6 @@
"megrez-3b-instruct": {
"description": "Megrez 3B Instruct е ефективен модел с малък брой параметри, разработен от Wuwen Xinqiong."
},
"meituan/longcat-flash-chat": {
"description": "Longcat Flash Chat е с отворен код от Meituan и представлява базов модел без мисловни процеси, оптимизиран за диалогови взаимодействия и задачи на интелигентни агенти, с изключителна ефективност при използване на инструменти и в сложни многократни взаимодействия."
},
"meta-llama-3-70b-instruct": {
"description": "Мощен модел с 70 милиарда параметри, отличаващ се в разсъждения, кодиране и широки езикови приложения."
},
@@ -2459,9 +2456,6 @@
"minimax-m2": {
"description": "MiniMax M2 е ефективен голям езиков модел, създаден специално за кодиране и работни процеси с агенти."
},
"minimax/minimax-m2": {
"description": "Създаден специално за ефективно кодиране и работни потоци с агенти."
},
"ministral-3b-latest": {
"description": "Ministral 3B е световен лидер сред моделите на Mistral."
},
@@ -3377,12 +3371,6 @@
"wizardlm2:8x22b": {
"description": "WizardLM 2 е езиков модел, предоставен от Microsoft AI, който се отличава в сложни диалози, многоезичност, разсъждение и интелигентни асистенти."
},
"x-ai/grok-4-fast": {
"description": "С радост представяме Grok 4 Fast — нашият най-нов напредък в модели за ефективно и икономично извеждане."
},
"x-ai/grok-code-fast-1": {
"description": "С гордост представяме grok-code-fast-1 — бърз и икономичен модел за извеждане, който се отличава в агентно кодиране."
},
"x1": {
"description": "Моделът Spark X1 ще бъде допълнително обновен, като на базата на водещите в страната резултати в математически задачи, ще постигне ефекти в общи задачи като разсъждение, генериране на текст и разбиране на език, сравними с OpenAI o1 и DeepSeek R1."
},
@@ -3443,9 +3431,6 @@
"yi-vision-v2": {
"description": "Модел за сложни визуални задачи, предлагащ висока производителност в разбирането и анализа на базата на множество изображения."
},
"z-ai/glm-4.6": {
"description": "GLM-4.6 е най-новият флагмански модел на Zhipu, който значително надминава предшествениците си в напреднало кодиране, обработка на дълги текстове, извеждане и способности на интелигентни агенти."
},
"zai-org/GLM-4.5": {
"description": "GLM-4.5 е базов модел, специално създаден за интелигентни агенти, използващ архитектура с микс от експерти (Mixture-of-Experts). Той е дълбоко оптимизиран за използване на инструменти, уеб браузване, софтуерно инженерство и фронтенд програмиране, и поддържа безпроблемна интеграция с кодови агенти като Claude Code и Roo Code. GLM-4.5 използва смесен режим на разсъждение, подходящ за сложни и ежедневни приложения."
},
+1 -12
View File
@@ -15,12 +15,6 @@
"prompt": "подсказка"
},
"localFiles": {
"editFile": {
"newString": "Замени с",
"oldString": "Търсене на съдържание",
"replaceAll": "Замени всички съвпадения",
"replaceFirst": "Замени само първото съвпадение"
},
"file": "Файл",
"folder": "Папка",
"moveFiles": {
@@ -40,12 +34,7 @@
"readFile": "Прочети файл",
"readFileError": "Неуспешно четене на файла, моля, проверете дали пътят към файла е правилен",
"readFiles": "Прочети файлове",
"readFilesError": "Неуспешно четене на файловете, моля, проверете дали пътят към файловете е правилен",
"writeFile": {
"characters": "Знаци",
"preview": "Преглед на съдържанието",
"truncated": "Съкратено"
}
"readFilesError": "Неуспешно четене на файловете, моля, проверете дали пътят към файловете е правилен"
},
"search": {
"createNewSearch": "Създаване на нова търсене",
-5
View File
@@ -330,11 +330,6 @@
"screenshot": "Screenshot",
"settings": "Exporteinstellungen",
"text": "Text",
"widthMode": {
"label": "Breitenmodus",
"narrow": "Schmalbildmodus",
"wide": "Breitbildmodus"
},
"withBackground": "Mit Hintergrundbild",
"withFooter": "Mit Fußzeile",
"withPluginInfo": "Mit Plugin-Informationen",
-15
View File
@@ -2225,9 +2225,6 @@
"megrez-3b-instruct": {
"description": "Megrez 3B Instruct ist ein effizientes Modell mit geringer Parameteranzahl, entwickelt von Wuwen Xinqiong."
},
"meituan/longcat-flash-chat": {
"description": "Ein von Meituan entwickeltes Open-Source-Basismodell, das speziell für dialogorientierte Interaktionen und agentenbasierte Aufgaben optimiert wurde und sich besonders bei Werkzeugaufrufen und komplexen mehrstufigen Dialogszenarien auszeichnet."
},
"meta-llama-3-70b-instruct": {
"description": "Ein leistungsstarkes Modell mit 70 Milliarden Parametern, das in den Bereichen Schlussfolgerungen, Programmierung und breiten Sprachanwendungen herausragt."
},
@@ -2459,9 +2456,6 @@
"minimax-m2": {
"description": "MiniMax M2 ist ein leistungsstarkes, effizientes Sprachmodell, das speziell für Programmier- und Agenten-Workflows entwickelt wurde."
},
"minimax/minimax-m2": {
"description": "Speziell entwickelt für effizientes Codieren und Agenten-Workflows."
},
"ministral-3b-latest": {
"description": "Ministral 3B ist das weltbeste Edge-Modell von Mistral."
},
@@ -3377,12 +3371,6 @@
"wizardlm2:8x22b": {
"description": "WizardLM 2 ist ein Sprachmodell von Microsoft AI, das in komplexen Dialogen, mehrsprachigen Anwendungen, Schlussfolgerungen und intelligenten Assistenten besonders gut abschneidet."
},
"x-ai/grok-4-fast": {
"description": "Wir freuen uns, Grok 4 Fast vorzustellen unseren neuesten Fortschritt im Bereich kosteneffizienter Inferenzmodelle."
},
"x-ai/grok-code-fast-1": {
"description": "Wir freuen uns, grok-code-fast-1 zu präsentieren ein schnelles und kosteneffizientes Inferenzmodell mit hervorragender Leistung im Bereich Agenten-Codierung."
},
"x1": {
"description": "Das Spark X1 Modell wird weiter verbessert und erreicht in allgemeinen Aufgaben wie Schlussfolgerungen, Textgenerierung und Sprachverständnis Ergebnisse, die mit OpenAI o1 und DeepSeek R1 vergleichbar sind, basierend auf der bereits führenden Leistung in mathematischen Aufgaben."
},
@@ -3443,9 +3431,6 @@
"yi-vision-v2": {
"description": "Ein Modell für komplexe visuelle Aufgaben, das leistungsstarke Verständnis- und Analysefähigkeiten auf der Grundlage mehrerer Bilder bietet."
},
"z-ai/glm-4.6": {
"description": "Das neueste Flaggschiffmodell von Zhipu, GLM-4.6, übertrifft seine Vorgänger deutlich in den Bereichen fortgeschrittenes Codieren, Verarbeitung langer Texte, logisches Schließen und agentenbasierte Fähigkeiten."
},
"zai-org/GLM-4.5": {
"description": "GLM-4.5 ist ein speziell für Agentenanwendungen entwickeltes Basismodell mit Mixture-of-Experts-Architektur. Es ist tief optimiert für Werkzeugaufrufe, Web-Browsing, Softwareentwicklung und Frontend-Programmierung und unterstützt nahtlos die Integration in Code-Agenten wie Claude Code und Roo Code. GLM-4.5 verwendet einen hybriden Inferenzmodus und ist für komplexe Schlussfolgerungen sowie den Alltagsgebrauch geeignet."
},
+1 -12
View File
@@ -15,12 +15,6 @@
"prompt": "Hinweiswort"
},
"localFiles": {
"editFile": {
"newString": "Ersetzen durch",
"oldString": "Suchbegriff",
"replaceAll": "Alle Vorkommen ersetzen",
"replaceFirst": "Nur erstes Vorkommen ersetzen"
},
"file": "Datei",
"folder": "Ordner",
"moveFiles": {
@@ -40,12 +34,7 @@
"readFile": "Datei lesen",
"readFileError": "Fehler beim Lesen der Datei, bitte überprüfen Sie den Dateipfad",
"readFiles": "Dateien lesen",
"readFilesError": "Fehler beim Lesen der Dateien, bitte überprüfen Sie den Dateipfad",
"writeFile": {
"characters": "Zeichen",
"preview": "Vorschau des Inhalts",
"truncated": "Abgeschnitten"
}
"readFilesError": "Fehler beim Lesen der Dateien, bitte überprüfen Sie den Dateipfad"
},
"search": {
"createNewSearch": "Neue Suchanfrage erstellen",
-5
View File
@@ -330,11 +330,6 @@
"screenshot": "Screenshot",
"settings": "Export Settings",
"text": "Text",
"widthMode": {
"label": "Width Mode",
"narrow": "Narrow",
"wide": "Wide"
},
"withBackground": "Include Background Image",
"withFooter": "Include Footer",
"withPluginInfo": "Include Plugin Information",
-15
View File
@@ -2225,9 +2225,6 @@
"megrez-3b-instruct": {
"description": "Megrez 3B Instruct is a compact and efficient model developed by Wuwen Xinqiong."
},
"meituan/longcat-flash-chat": {
"description": "An open-source foundational model from Meituan, optimized for conversational interactions and agent-based tasks. Excels in tool usage and complex multi-turn dialogue scenarios."
},
"meta-llama-3-70b-instruct": {
"description": "A powerful 70-billion parameter model excelling in reasoning, coding, and broad language applications."
},
@@ -2459,9 +2456,6 @@
"minimax-m2": {
"description": "MiniMax M2 is a high-efficiency large language model built for coding and agent-based workflows."
},
"minimax/minimax-m2": {
"description": "Purpose-built for efficient coding and agent workflows."
},
"ministral-3b-latest": {
"description": "Ministral 3B is Mistral's top-tier edge model."
},
@@ -3377,12 +3371,6 @@
"wizardlm2:8x22b": {
"description": "WizardLM 2 is a language model provided by Microsoft AI, excelling in complex dialogues, multilingual capabilities, reasoning, and intelligent assistant applications."
},
"x-ai/grok-4-fast": {
"description": "Were excited to introduce Grok 4 Fast, our latest advancement in cost-effective reasoning models."
},
"x-ai/grok-code-fast-1": {
"description": "Were proud to launch grok-code-fast-1, a fast and cost-efficient reasoning model that excels in agent-based coding tasks."
},
"x1": {
"description": "The Spark X1 model will undergo further upgrades, achieving results in reasoning, text generation, and language understanding tasks that match OpenAI o1 and DeepSeek R1, building on its leading position in domestic mathematical tasks."
},
@@ -3443,9 +3431,6 @@
"yi-vision-v2": {
"description": "A complex visual task model that provides high-performance understanding and analysis capabilities based on multiple images."
},
"z-ai/glm-4.6": {
"description": "GLM-4.6, the latest flagship model from Zhipu AI, delivers significant improvements over its predecessor in advanced coding, long-form text processing, reasoning, and agent capabilities."
},
"zai-org/GLM-4.5": {
"description": "GLM-4.5 is a foundational model designed specifically for agent applications, using a Mixture-of-Experts (MoE) architecture. It is deeply optimized for tool invocation, web browsing, software engineering, and front-end programming, supporting seamless integration with code agents like Claude Code and Roo Code. GLM-4.5 employs a hybrid inference mode, adaptable to complex reasoning and everyday use scenarios."
},
+1 -12
View File
@@ -15,12 +15,6 @@
"prompt": "Prompt"
},
"localFiles": {
"editFile": {
"newString": "Replace with",
"oldString": "Find",
"replaceAll": "Replace all occurrences",
"replaceFirst": "Replace first occurrence only"
},
"file": "File",
"folder": "Folder",
"moveFiles": {
@@ -40,12 +34,7 @@
"readFile": "Read File",
"readFileError": "Failed to read file, please check if the file path is correct",
"readFiles": "Read Files",
"readFilesError": "Failed to read files, please check if the file path is correct",
"writeFile": {
"characters": "characters",
"preview": "Content Preview",
"truncated": "truncated"
}
"readFilesError": "Failed to read files, please check if the file path is correct"
},
"search": {
"createNewSearch": "Create a new search record",
-5
View File
@@ -330,11 +330,6 @@
"screenshot": "Captura de pantalla",
"settings": "Configuración de exportación",
"text": "Texto",
"widthMode": {
"label": "Modo de ancho",
"narrow": "Modo de pantalla estrecha",
"wide": "Modo de pantalla ancha"
},
"withBackground": "Incluir imagen de fondo",
"withFooter": "Incluir pie de página",
"withPluginInfo": "Incluir información del plugin",
-15
View File
@@ -2225,9 +2225,6 @@
"megrez-3b-instruct": {
"description": "Megrez 3B Instruct es un modelo eficiente de bajo número de parámetros desarrollado por Wuwen Xinqiong."
},
"meituan/longcat-flash-chat": {
"description": "Modelo base no reflexivo de código abierto de Meituan, optimizado para interacciones conversacionales y tareas de agentes inteligentes, con un rendimiento destacado en llamadas a herramientas y escenarios complejos de múltiples turnos."
},
"meta-llama-3-70b-instruct": {
"description": "Un poderoso modelo de 70 mil millones de parámetros que sobresale en razonamiento, codificación y amplias aplicaciones de lenguaje."
},
@@ -2459,9 +2456,6 @@
"minimax-m2": {
"description": "MiniMax M2 es un modelo de lenguaje grande y eficiente, diseñado para flujos de trabajo de codificación y agentes."
},
"minimax/minimax-m2": {
"description": "Diseñado para una codificación eficiente y flujos de trabajo de agentes."
},
"ministral-3b-latest": {
"description": "Ministral 3B es el modelo de borde de primer nivel mundial de Mistral."
},
@@ -3377,12 +3371,6 @@
"wizardlm2:8x22b": {
"description": "WizardLM 2 es un modelo de lenguaje proporcionado por Microsoft AI, que destaca en diálogos complejos, multilingües, razonamiento y asistentes inteligentes."
},
"x-ai/grok-4-fast": {
"description": "Nos complace presentar Grok 4 Fast, nuestro último avance en modelos de inferencia rentables."
},
"x-ai/grok-code-fast-1": {
"description": "Nos complace lanzar grok-code-fast-1, un modelo de inferencia rápido y rentable con un rendimiento sobresaliente en codificación para agentes."
},
"x1": {
"description": "El modelo Spark X1 se actualizará aún más, logrando resultados en tareas generales como razonamiento, generación de texto y comprensión del lenguaje que se comparan con OpenAI o1 y DeepSeek R1, además de liderar en tareas matemáticas en el país."
},
@@ -3443,9 +3431,6 @@
"yi-vision-v2": {
"description": "Modelo para tareas visuales complejas, que ofrece capacidades de comprensión y análisis de alto rendimiento basadas en múltiples imágenes."
},
"z-ai/glm-4.6": {
"description": "El nuevo modelo insignia de Zhipu, GLM-4.6, supera ampliamente a su predecesor en codificación avanzada, procesamiento de textos largos, razonamiento y capacidades de agentes inteligentes."
},
"zai-org/GLM-4.5": {
"description": "GLM-4.5 es un modelo base diseñado para aplicaciones de agentes inteligentes, utilizando arquitectura Mixture-of-Experts (MoE). Está profundamente optimizado para llamadas a herramientas, navegación web, ingeniería de software y programación frontend, soportando integración fluida con agentes de código como Claude Code y Roo Code. GLM-4.5 emplea un modo de inferencia híbrido que se adapta a escenarios de razonamiento complejo y uso cotidiano."
},
+1 -12
View File
@@ -15,12 +15,6 @@
"prompt": "Palabra de aviso"
},
"localFiles": {
"editFile": {
"newString": "Reemplazar con",
"oldString": "Buscar",
"replaceAll": "Reemplazar todas las coincidencias",
"replaceFirst": "Reemplazar solo la primera coincidencia"
},
"file": "Archivo",
"folder": "Carpeta",
"moveFiles": {
@@ -40,12 +34,7 @@
"readFile": "Leer archivo",
"readFileError": "Error al leer el archivo, por favor verifica si la ruta del archivo es correcta",
"readFiles": "Leer archivos",
"readFilesError": "Error al leer los archivos, por favor verifica si la ruta del archivo es correcta",
"writeFile": {
"characters": "caracteres",
"preview": "Vista previa del contenido",
"truncated": "Truncado"
}
"readFilesError": "Error al leer los archivos, por favor verifica si la ruta del archivo es correcta"
},
"search": {
"createNewSearch": "Crear un nuevo registro de búsqueda",
-5
View File
@@ -330,11 +330,6 @@
"screenshot": "اسکرین‌شات",
"settings": "تنظیمات خروجی",
"text": "متن",
"widthMode": {
"label": "حالت عرض",
"narrow": "حالت صفحه باریک",
"wide": "حالت صفحه عریض"
},
"withBackground": "شامل تصویر پس‌زمینه",
"withFooter": "شامل پاورقی",
"withPluginInfo": "شامل اطلاعات افزونه",
-15
View File
@@ -2225,9 +2225,6 @@
"megrez-3b-instruct": {
"description": "Megrez 3B Instruct یک مدل کم‌پارامتر و کارآمد است که توسط Wuwen Xinqiong ارائه شده است."
},
"meituan/longcat-flash-chat": {
"description": "مدل پایه غیرتفکری متن‌باز Meituan که به‌طور ویژه برای تعاملات گفت‌وگویی و وظایف عامل‌ها بهینه‌سازی شده است و در فراخوانی ابزارها و سناریوهای پیچیده چندمرحله‌ای عملکرد برجسته‌ای دارد."
},
"meta-llama-3-70b-instruct": {
"description": "یک مدل قدرتمند با ۷۰ میلیارد پارامتر که در استدلال، کدنویسی و کاربردهای گسترده زبانی عملکرد برجسته‌ای دارد."
},
@@ -2459,9 +2456,6 @@
"minimax-m2": {
"description": "MiniMax M2 یک مدل زبانی بزرگ و کارآمد است که به‌طور خاص برای کدنویسی و جریان‌های کاری عامل‌محور طراحی شده است."
},
"minimax/minimax-m2": {
"description": "ویژه طراحی شده برای کدنویسی کارآمد و جریان‌های کاری عامل‌ها."
},
"ministral-3b-latest": {
"description": "Ministral 3B مدل پیشرفته و برتر Mistral در سطح جهانی است."
},
@@ -3377,12 +3371,6 @@
"wizardlm2:8x22b": {
"description": "WizardLM 2 یک مدل زبانی ارائه شده توسط مایکروسافت AI است که در زمینه‌های مکالمات پیچیده، چندزبانه، استدلال و دستیارهای هوشمند عملکرد برجسته‌ای دارد."
},
"x-ai/grok-4-fast": {
"description": "ما با خوشحالی Grok 4 Fast را معرفی می‌کنیم، جدیدترین پیشرفت ما در زمینه مدل‌های استنتاجی مقرون‌به‌صرفه."
},
"x-ai/grok-code-fast-1": {
"description": "ما با افتخار grok-code-fast-1 را معرفی می‌کنیم، مدلی سریع و اقتصادی برای استنتاج که در کدنویسی عامل‌ها عملکردی عالی دارد."
},
"x1": {
"description": "مدل Spark X1 به‌زودی ارتقا خواهد یافت و در زمینه وظایف ریاضی که در کشور پیشرو است، عملکردهای استدلال، تولید متن و درک زبان را با OpenAI o1 و DeepSeek R1 مقایسه خواهد کرد."
},
@@ -3443,9 +3431,6 @@
"yi-vision-v2": {
"description": "مدل‌های پیچیده بصری که قابلیت‌های درک و تحلیل با عملکرد بالا را بر اساس چندین تصویر ارائه می‌دهند."
},
"z-ai/glm-4.6": {
"description": "جدیدترین مدل پرچم‌دار Zhipu به نام GLM-4.6 که در کدنویسی پیشرفته، پردازش متون طولانی، استنتاج و توانایی‌های عامل‌ها به‌طور کامل از نسل قبلی پیشی گرفته است."
},
"zai-org/GLM-4.5": {
"description": "GLM-4.5 یک مدل پایه طراحی شده برای کاربردهای عامل هوشمند است که از معماری Mixture-of-Experts استفاده می‌کند. این مدل در زمینه‌های فراخوانی ابزار، مرور وب، مهندسی نرم‌افزار و برنامه‌نویسی فرانت‌اند بهینه‌سازی عمیق شده و از ادغام بی‌وقفه با عامل‌های کد مانند Claude Code و Roo Code پشتیبانی می‌کند. GLM-4.5 از حالت استدلال ترکیبی بهره می‌برد و می‌تواند در سناریوهای استدلال پیچیده و استفاده روزمره به خوبی عمل کند."
},
+1 -12
View File
@@ -15,12 +15,6 @@
"prompt": "کلمات کلیدی"
},
"localFiles": {
"editFile": {
"newString": "جایگزین با",
"oldString": "یافتن محتوا",
"replaceAll": "جایگزینی تمام موارد",
"replaceFirst": "فقط اولین مورد را جایگزین کن"
},
"file": "فایل",
"folder": "پوشه",
"moveFiles": {
@@ -40,12 +34,7 @@
"readFile": "خواندن فایل",
"readFileError": "خطا در خواندن فایل، لطفاً مسیر فایل را بررسی کنید",
"readFiles": "خواندن فایل‌ها",
"readFilesError": "خطا در خواندن فایل‌ها، لطفاً مسیر فایل‌ها را بررسی کنید",
"writeFile": {
"characters": "کاراکتر",
"preview": "پیش‌نمایش محتوا",
"truncated": "بریده شده"
}
"readFilesError": "خطا در خواندن فایل‌ها، لطفاً مسیر فایل‌ها را بررسی کنید"
},
"search": {
"createNewSearch": "ایجاد جستجوی جدید",
-5
View File
@@ -330,11 +330,6 @@
"screenshot": "Capture d'écran",
"settings": "Paramètres d'exportation",
"text": "Texte",
"widthMode": {
"label": "Mode de largeur",
"narrow": "Mode écran étroit",
"wide": "Mode écran large"
},
"withBackground": "Avec image de fond",
"withFooter": "Avec pied de page",
"withPluginInfo": "Avec informations sur le plugin",
-15
View File
@@ -2225,9 +2225,6 @@
"megrez-3b-instruct": {
"description": "Megrez 3B Instruct est un modèle efficace à faible nombre de paramètres lancé par Wuwen Xinqiong."
},
"meituan/longcat-flash-chat": {
"description": "Modèle de base non réflexif open source de Meituan, optimisé pour les interactions conversationnelles et les tâches d'agents intelligents, offrant d'excellentes performances dans les appels d'outils et les scénarios d'interactions complexes à plusieurs tours."
},
"meta-llama-3-70b-instruct": {
"description": "Un puissant modèle de 70 milliards de paramètres excelling dans le raisonnement, le codage et les applications linguistiques larges."
},
@@ -2459,9 +2456,6 @@
"minimax-m2": {
"description": "MiniMax M2 est un modèle de langage de grande taille, efficace et conçu pour les flux de travail en codage et en automatisation."
},
"minimax/minimax-m2": {
"description": "Conçu pour un codage efficace et des flux de travail d'agents performants."
},
"ministral-3b-latest": {
"description": "Ministral 3B est le modèle de pointe de Mistral sur le marché."
},
@@ -3377,12 +3371,6 @@
"wizardlm2:8x22b": {
"description": "WizardLM 2 est un modèle de langage proposé par Microsoft AI, particulièrement performant dans les domaines des dialogues complexes, du multilinguisme, du raisonnement et des assistants intelligents."
},
"x-ai/grok-4-fast": {
"description": "Nous sommes ravis de présenter Grok 4 Fast, notre dernière avancée en matière de modèles de raisonnement rentables."
},
"x-ai/grok-code-fast-1": {
"description": "Nous sommes heureux de lancer grok-code-fast-1, un modèle de raisonnement rapide et économique, particulièrement performant pour le codage assisté par agent."
},
"x1": {
"description": "Le modèle Spark X1 sera mis à niveau, et sur la base de ses performances déjà leaders dans les tâches mathématiques, il atteindra des résultats comparables dans des tâches générales telles que le raisonnement, la génération de texte et la compréhension du langage, en se mesurant à OpenAI o1 et DeepSeek R1."
},
@@ -3443,9 +3431,6 @@
"yi-vision-v2": {
"description": "Modèle pour des tâches visuelles complexes, offrant des capacités de compréhension et d'analyse de haute performance basées sur plusieurs images."
},
"z-ai/glm-4.6": {
"description": "GLM-4.6, le tout dernier modèle phare de Zhipu, surpasse son prédécesseur dans les domaines du codage avancé, du traitement de longs textes, du raisonnement et des capacités d'agents intelligents."
},
"zai-org/GLM-4.5": {
"description": "GLM-4.5 est un modèle de base conçu pour les applications d'agents intelligents, utilisant une architecture Mixture-of-Experts (MoE). Il est profondément optimisé pour l'appel d'outils, la navigation web, l'ingénierie logicielle et la programmation front-end, supportant une intégration transparente avec des agents de code tels que Claude Code et Roo Code. GLM-4.5 utilise un mode d'inférence hybride, adapté à des scénarios variés allant du raisonnement complexe à l'usage quotidien."
},
+1 -12
View File
@@ -15,12 +15,6 @@
"prompt": "Mot de rappel"
},
"localFiles": {
"editFile": {
"newString": "Remplacer par",
"oldString": "Rechercher",
"replaceAll": "Remplacer toutes les occurrences",
"replaceFirst": "Remplacer uniquement la première occurrence"
},
"file": "Fichier",
"folder": "Dossier",
"moveFiles": {
@@ -40,12 +34,7 @@
"readFile": "Lire le fichier",
"readFileError": "Échec de la lecture du fichier, veuillez vérifier si le chemin du fichier est correct",
"readFiles": "Lire les fichiers",
"readFilesError": "Échec de la lecture des fichiers, veuillez vérifier si le chemin du fichier est correct",
"writeFile": {
"characters": "caractères",
"preview": "Aperçu du contenu",
"truncated": "Tronqué"
}
"readFilesError": "Échec de la lecture des fichiers, veuillez vérifier si le chemin du fichier est correct"
},
"search": {
"createNewSearch": "Créer un nouvel enregistrement de recherche",
-5
View File
@@ -330,11 +330,6 @@
"screenshot": "Screenshot",
"settings": "Impostazioni di esportazione",
"text": "Testo",
"widthMode": {
"label": "Modalità larghezza",
"narrow": "Modalità schermo stretto",
"wide": "Modalità schermo ampio"
},
"withBackground": "Con immagine di sfondo",
"withFooter": "Con piè di pagina",
"withPluginInfo": "Con informazioni sul plugin",
-15
View File
@@ -2225,9 +2225,6 @@
"megrez-3b-instruct": {
"description": "Megrez 3B Instruct è un modello efficiente a basso numero di parametri sviluppato da Wuwen Xinqiong."
},
"meituan/longcat-flash-chat": {
"description": "Modello base non riflessivo open source di Meituan, ottimizzato per l'interazione dialogica e i compiti degli agenti intelligenti, eccelle nell'uso di strumenti e in scenari complessi di conversazione multi-turno."
},
"meta-llama-3-70b-instruct": {
"description": "Un potente modello con 70 miliardi di parametri che eccelle nel ragionamento, nella codifica e nelle ampie applicazioni linguistiche."
},
@@ -2459,9 +2456,6 @@
"minimax-m2": {
"description": "MiniMax M2 è un modello linguistico di grandi dimensioni, efficiente e progettato per flussi di lavoro di codifica e agenti intelligenti."
},
"minimax/minimax-m2": {
"description": "Progettato per una codifica efficiente e flussi di lavoro con agenti."
},
"ministral-3b-latest": {
"description": "Ministral 3B è il modello di punta di Mistral per edge computing."
},
@@ -3377,12 +3371,6 @@
"wizardlm2:8x22b": {
"description": "WizardLM 2 è un modello di linguaggio fornito da Microsoft AI, particolarmente efficace in dialoghi complessi, multilingue, ragionamento e assistenti intelligenti."
},
"x-ai/grok-4-fast": {
"description": "Siamo lieti di presentare Grok 4 Fast, il nostro ultimo progresso nei modelli di inferenza ad alta efficienza in termini di costi."
},
"x-ai/grok-code-fast-1": {
"description": "Siamo entusiasti di lanciare grok-code-fast-1, un modello di inferenza rapido ed economico, eccellente nella codifica per agenti."
},
"x1": {
"description": "Il modello Spark X1 sarà ulteriormente aggiornato, raggiungendo risultati in compiti generali come ragionamento, generazione di testo e comprensione del linguaggio, in linea con OpenAI o1 e DeepSeek R1, partendo da una posizione di leadership nei compiti matematici."
},
@@ -3443,9 +3431,6 @@
"yi-vision-v2": {
"description": "Modello per compiti visivi complessi, che offre capacità di comprensione e analisi ad alte prestazioni basate su più immagini."
},
"z-ai/glm-4.6": {
"description": "GLM-4.6, il nuovo modello di punta di Zhipu, supera ampiamente la generazione precedente in codifica avanzata, gestione di testi lunghi, capacità di ragionamento e competenze degli agenti."
},
"zai-org/GLM-4.5": {
"description": "GLM-4.5 è un modello base progettato per applicazioni agenti intelligenti, che utilizza un'architettura Mixture-of-Experts (MoE). Ottimizzato profondamente per chiamate a strumenti, navigazione web, ingegneria del software e programmazione frontend, supporta integrazioni fluide con agenti di codice come Claude Code e Roo Code. Adotta una modalità di inferenza ibrida per adattarsi a scenari di ragionamento complessi e uso quotidiano."
},
+1 -12
View File
@@ -15,12 +15,6 @@
"prompt": "parola chiave"
},
"localFiles": {
"editFile": {
"newString": "Sostituisci con",
"oldString": "Trova",
"replaceAll": "Sostituisci tutte le occorrenze",
"replaceFirst": "Sostituisci solo la prima occorrenza"
},
"file": "File",
"folder": "Cartella",
"moveFiles": {
@@ -40,12 +34,7 @@
"readFile": "Leggi file",
"readFileError": "Impossibile leggere il file, controlla se il percorso del file è corretto",
"readFiles": "Leggi file",
"readFilesError": "Impossibile leggere i file, controlla se il percorso del file è corretto",
"writeFile": {
"characters": "Caratteri",
"preview": "Anteprima contenuto",
"truncated": "Troncato"
}
"readFilesError": "Impossibile leggere i file, controlla se il percorso del file è corretto"
},
"search": {
"createNewSearch": "Crea una nuova registrazione di ricerca",
-5
View File
@@ -330,11 +330,6 @@
"screenshot": "スクリーンショット",
"settings": "エクスポート設定",
"text": "テキスト",
"widthMode": {
"label": "幅のモード",
"narrow": "ナローモード",
"wide": "ワイドモード"
},
"withBackground": "背景画像を含む",
"withFooter": "フッターを含む",
"withPluginInfo": "プラグイン情報を含む",
-15
View File
@@ -2225,9 +2225,6 @@
"megrez-3b-instruct": {
"description": "Megrez 3B Instruct は WuWenXinQiong によって開発された小規模パラメータの高効率モデルです。"
},
"meituan/longcat-flash-chat": {
"description": "美団がオープンソースで提供する、対話型インタラクションとエージェントタスクに最適化された非推論型基盤モデルであり、ツールの呼び出しや複雑なマルチターン対話シナリオにおいて優れた性能を発揮します。"
},
"meta-llama-3-70b-instruct": {
"description": "推論、コーディング、広範な言語アプリケーションに優れた70億パラメータの強力なモデルです。"
},
@@ -2459,9 +2456,6 @@
"minimax-m2": {
"description": "MiniMax M2は、コーディングおよびエージェントワークフローのために構築された高効率な大規模言語モデルです。"
},
"minimax/minimax-m2": {
"description": "効率的なコーディングとエージェントワークフローのために設計されたモデルです。"
},
"ministral-3b-latest": {
"description": "Ministral 3BはMistralの世界トップクラスのエッジモデルです。"
},
@@ -3377,12 +3371,6 @@
"wizardlm2:8x22b": {
"description": "WizardLM 2は、Microsoft AIが提供する言語モデルであり、複雑な対話、多言語、推論、インテリジェントアシスタントの分野で特に優れた性能を発揮します。"
},
"x-ai/grok-4-fast": {
"description": "Grok 4 Fast をリリースできることを嬉しく思います。これは、コスト効率の高い推論モデルにおける最新の進展です。"
},
"x-ai/grok-code-fast-1": {
"description": "grok-code-fast-1 を発表できることを嬉しく思います。これは、高速かつ経済的な推論モデルであり、エージェントによるコーディングにおいて優れた性能を発揮します。"
},
"x1": {
"description": "Spark X1 モデルはさらにアップグレードされ、元の数学タスクで国内のリーダーシップを維持しつつ、推論、テキスト生成、言語理解などの一般的なタスクで OpenAI o1 および DeepSeek R1 に匹敵する効果を実現します。"
},
@@ -3443,9 +3431,6 @@
"yi-vision-v2": {
"description": "複雑な視覚タスクモデルで、複数の画像に基づく高性能な理解と分析能力を提供します。"
},
"z-ai/glm-4.6": {
"description": "智譜の最新フラッグシップモデル GLM-4.6 は、高度なコーディング、長文処理、推論およびエージェント能力において前世代を大きく上回る性能を実現しています。"
},
"zai-org/GLM-4.5": {
"description": "GLM-4.5はエージェントアプリケーション向けに設計された基盤モデルで、混合専門家(Mixture-of-Experts)アーキテクチャを採用。ツール呼び出し、ウェブブラウジング、ソフトウェア工学、フロントエンドプログラミング分野で深く最適化され、Claude CodeやRoo Codeなどのコードエージェントへのシームレスな統合をサポートします。混合推論モードを採用し、複雑な推論や日常利用など多様なシナリオに適応可能です。"
},
+1 -12
View File
@@ -15,12 +15,6 @@
"prompt": "プロンプト"
},
"localFiles": {
"editFile": {
"newString": "置換後の文字列",
"oldString": "検索文字列",
"replaceAll": "すべて置換",
"replaceFirst": "最初の一致のみ置換"
},
"file": "ファイル",
"folder": "フォルダー",
"moveFiles": {
@@ -40,12 +34,7 @@
"readFile": "ファイルを読み込む",
"readFileError": "ファイルの読み込みに失敗しました。ファイルパスが正しいか確認してください。",
"readFiles": "ファイルを読み込む",
"readFilesError": "ファイルの読み込みに失敗しました。ファイルパスが正しいか確認してください。",
"writeFile": {
"characters": "文字数",
"preview": "内容プレビュー",
"truncated": "切り捨てられました"
}
"readFilesError": "ファイルの読み込みに失敗しました。ファイルパスが正しいか確認してください。"
},
"search": {
"createNewSearch": "新しい検索記録を作成",
-5
View File
@@ -330,11 +330,6 @@
"screenshot": "스크린샷",
"settings": "내보내기 설정",
"text": "텍스트",
"widthMode": {
"label": "너비 모드",
"narrow": "좁은 화면 모드",
"wide": "넓은 화면 모드"
},
"withBackground": "배경 이미지 포함",
"withFooter": "푸터 포함",
"withPluginInfo": "플러그인 정보 포함",
-15
View File
@@ -2225,9 +2225,6 @@
"megrez-3b-instruct": {
"description": "Megrez 3B Instruct는 Wuwen Xinqiong에서 출시한 소형 파라미터 고효율 모델입니다."
},
"meituan/longcat-flash-chat": {
"description": "메이투안이 오픈소스로 공개한 비사고형 기반 모델로, 대화 상호작용과 에이전트 작업에 최적화되어 있으며, 도구 호출 및 복잡한 다중 회화 시나리오에서 뛰어난 성능을 발휘합니다."
},
"meta-llama-3-70b-instruct": {
"description": "추론, 코딩 및 광범위한 언어 응용 프로그램에서 뛰어난 성능을 발휘하는 강력한 70억 매개변수 모델입니다."
},
@@ -2459,9 +2456,6 @@
"minimax-m2": {
"description": "MiniMax M2는 코딩 및 에이전트 워크플로우를 위해 설계된 효율적인 대형 언어 모델입니다."
},
"minimax/minimax-m2": {
"description": "효율적인 코딩과 에이전트 워크플로우를 위해 설계되었습니다."
},
"ministral-3b-latest": {
"description": "Ministral 3B는 Mistral의 세계적 수준의 엣지 모델입니다."
},
@@ -3377,12 +3371,6 @@
"wizardlm2:8x22b": {
"description": "WizardLM 2는 Microsoft AI에서 제공하는 언어 모델로, 복잡한 대화, 다국어, 추론 및 스마트 어시스턴트 분야에서 특히 뛰어난 성능을 발휘합니다."
},
"x-ai/grok-4-fast": {
"description": "Grok 4 Fast를 출시하게 되어 매우 기쁩니다. 이는 비용 효율적인 추론 모델 분야에서 우리의 최신 성과입니다."
},
"x-ai/grok-code-fast-1": {
"description": "grok-code-fast-1을 출시하게 되어 기쁩니다. 이 모델은 빠르고 경제적인 추론 성능을 제공하며, 에이전트 기반 코딩 작업에서 탁월한 성능을 보입니다."
},
"x1": {
"description": "Spark X1 모델은 추가 업그레이드를 통해 기존의 수학 과제에서 국내 선두를 유지하며, 추론, 텍스트 생성, 언어 이해 등 일반 과제에서 OpenAI o1 및 DeepSeek R1과 동등한 성과를 달성합니다."
},
@@ -3443,9 +3431,6 @@
"yi-vision-v2": {
"description": "복잡한 시각적 작업 모델로, 여러 이미지를 기반으로 한 고성능 이해 및 분석 능력을 제공합니다."
},
"z-ai/glm-4.6": {
"description": "Zhipu의 최신 플래그십 모델 GLM-4.6은 고급 코딩, 장문 처리, 추론 및 에이전트 능력에서 전 세대를 뛰어넘는 성능을 자랑합니다."
},
"zai-org/GLM-4.5": {
"description": "GLM-4.5는 에이전트 애플리케이션을 위해 설계된 기본 모델로, 혼합 전문가(Mixture-of-Experts) 아키텍처를 사용합니다. 도구 호출, 웹 브라우징, 소프트웨어 엔지니어링, 프론트엔드 프로그래밍 분야에서 깊이 최적화되었으며, Claude Code, Roo Code 등 코드 에이전트에 원활히 통합될 수 있습니다. GLM-4.5는 혼합 추론 모드를 채택하여 복잡한 추론과 일상 사용 등 다양한 응용 시나리오에 적응할 수 있습니다."
},
+1 -12
View File
@@ -15,12 +15,6 @@
"prompt": "프롬프트"
},
"localFiles": {
"editFile": {
"newString": "다음으로 바꾸기",
"oldString": "찾을 내용",
"replaceAll": "모든 항목 바꾸기",
"replaceFirst": "첫 번째 항목만 바꾸기"
},
"file": "파일",
"folder": "폴더",
"moveFiles": {
@@ -40,12 +34,7 @@
"readFile": "파일 읽기",
"readFileError": "파일을 읽는 데 실패했습니다. 파일 경로가 올바른지 확인하세요.",
"readFiles": "파일 읽기",
"readFilesError": "파일을 읽는 데 실패했습니다. 파일 경로가 올바른지 확인하세요.",
"writeFile": {
"characters": "문자 수",
"preview": "내용 미리보기",
"truncated": "잘림"
}
"readFilesError": "파일을 읽는 데 실패했습니다. 파일 경로가 올바른지 확인하세요."
},
"search": {
"createNewSearch": "새 검색 기록 만들기",
-5
View File
@@ -330,11 +330,6 @@
"screenshot": "Screenshot",
"settings": "Exportinstellingen",
"text": "Tekst",
"widthMode": {
"label": "Breedtemodus",
"narrow": "Smalle schermmodus",
"wide": "Brede schermmodus"
},
"withBackground": "Met achtergrondafbeelding",
"withFooter": "Met voettekst",
"withPluginInfo": "Met plug-in informatie",
-15
View File
@@ -2225,9 +2225,6 @@
"megrez-3b-instruct": {
"description": "Megrez 3B Instruct is een efficiënt model met een klein aantal parameters, ontwikkeld door Wuwen Xinqiong."
},
"meituan/longcat-flash-chat": {
"description": "Longcat Flash Chat is een open-source basismodel van Meituan, geoptimaliseerd voor dialooginteractie en agent-taken. Het blinkt uit in gereedschapsgebruik en complexe meerstapsgesprekken."
},
"meta-llama-3-70b-instruct": {
"description": "Een krachtig model met 70 miljard parameters dat uitblinkt in redeneren, coderen en brede taaltoepassingen."
},
@@ -2459,9 +2456,6 @@
"minimax-m2": {
"description": "MiniMax M2 is een efficiënt groot taalmodel dat speciaal is ontwikkeld voor programmeer- en agentworkflows."
},
"minimax/minimax-m2": {
"description": "Speciaal ontworpen voor efficiënte codering en agent-workflows."
},
"ministral-3b-latest": {
"description": "Ministral 3B is het toonaangevende edge-model van Mistral."
},
@@ -3377,12 +3371,6 @@
"wizardlm2:8x22b": {
"description": "WizardLM 2 is een taalmodel van Microsoft AI dat uitblinkt in complexe gesprekken, meertaligheid, inferentie en intelligente assistentie."
},
"x-ai/grok-4-fast": {
"description": "We zijn verheugd om Grok 4 Fast te introduceren, onze nieuwste vooruitgang op het gebied van kostenefficiënte redeneermodellen."
},
"x-ai/grok-code-fast-1": {
"description": "We zijn trots om grok-code-fast-1 te lanceren, een snel en kostenefficiënt redeneermodel dat uitblinkt in agentgebaseerde codering."
},
"x1": {
"description": "Het Spark X1-model zal verder worden geüpgraded, met verbeterde prestaties in redenering, tekstgeneratie en taalbegrip, ter vergelijking met OpenAI o1 en DeepSeek R1."
},
@@ -3443,9 +3431,6 @@
"yi-vision-v2": {
"description": "Complex visietakenmodel dat hoge prestaties biedt in begrip en analyse op basis van meerdere afbeeldingen."
},
"z-ai/glm-4.6": {
"description": "GLM-4.6 is het nieuwste vlaggenschipmodel van Zhipu AI en overtreft zijn voorgangers op het gebied van geavanceerde codering, lange tekstverwerking, redeneren en agentcapaciteiten."
},
"zai-org/GLM-4.5": {
"description": "GLM-4.5 is een basis model speciaal ontworpen voor agenttoepassingen, gebruikmakend van een Mixture-of-Experts (MoE) architectuur. Het is diep geoptimaliseerd voor toolaanroepen, web browsing, software engineering en frontend programmeren, en ondersteunt naadloze integratie met code-agents zoals Claude Code en Roo Code. GLM-4.5 gebruikt een hybride redeneermodus en is geschikt voor complexe redenering en dagelijks gebruik."
},
+1 -12
View File
@@ -15,12 +15,6 @@
"prompt": "prompt"
},
"localFiles": {
"editFile": {
"newString": "Vervangen door",
"oldString": "Zoekterm",
"replaceAll": "Alles vervangen",
"replaceFirst": "Alleen eerste vervangen"
},
"file": "Bestand",
"folder": "Map",
"moveFiles": {
@@ -40,12 +34,7 @@
"readFile": "Bestand lezen",
"readFileError": "Fout bij het lezen van het bestand, controleer of het bestandspad correct is",
"readFiles": "Bestanden lezen",
"readFilesError": "Fout bij het lezen van bestanden, controleer of het bestandspad correct is",
"writeFile": {
"characters": "Tekens",
"preview": "Voorbeeld van inhoud",
"truncated": "Afgekapt"
}
"readFilesError": "Fout bij het lezen van bestanden, controleer of het bestandspad correct is"
},
"search": {
"createNewSearch": "Maak een nieuwe zoekopdracht",
-5
View File
@@ -330,11 +330,6 @@
"screenshot": "Zrzut ekranu",
"settings": "Ustawienia eksportu",
"text": "Tekst",
"widthMode": {
"label": "Tryb szerokości",
"narrow": "Tryb wąskiego ekranu",
"wide": "Tryb szerokiego ekranu"
},
"withBackground": "Z tłem",
"withFooter": "Z stopką",
"withPluginInfo": "Z informacjami o wtyczce",
-15
View File
@@ -2225,9 +2225,6 @@
"megrez-3b-instruct": {
"description": "Megrez 3B Instruct to kompaktowy i wydajny model opracowany przez Wuwen Xinqiong."
},
"meituan/longcat-flash-chat": {
"description": "Longcat Flash Chat to otwartoźródłowy model bazowy od Meituan, zoptymalizowany pod kątem interakcji dialogowych i zadań agentowych, wyróżniający się w scenariuszach wymagających użycia narzędzi i złożonych wieloetapowych konwersacji."
},
"meta-llama-3-70b-instruct": {
"description": "Potężny model z 70 miliardami parametrów, doskonały w rozumowaniu, kodowaniu i szerokich zastosowaniach językowych."
},
@@ -2459,9 +2456,6 @@
"minimax-m2": {
"description": "MiniMax M2 to wydajny duży model językowy stworzony z myślą o kodowaniu i zautomatyzowanych przepływach pracy."
},
"minimax/minimax-m2": {
"description": "Stworzony z myślą o wydajnym kodowaniu i przepływach pracy agentów."
},
"ministral-3b-latest": {
"description": "Ministral 3B to czołowy model brzegowy Mistrala."
},
@@ -3377,12 +3371,6 @@
"wizardlm2:8x22b": {
"description": "WizardLM 2 to model językowy dostarczany przez Microsoft AI, który wyróżnia się w złożonych dialogach, wielojęzyczności, wnioskowaniu i inteligentnych asystentach."
},
"x-ai/grok-4-fast": {
"description": "Z radością przedstawiamy Grok 4 Fast — nasze najnowsze osiągnięcie w dziedzinie modeli wnioskowania zoptymalizowanych pod względem kosztów."
},
"x-ai/grok-code-fast-1": {
"description": "Z dumą prezentujemy grok-code-fast-1 — szybki i ekonomiczny model wnioskowania, który doskonale sprawdza się w kodowaniu przez agentów."
},
"x1": {
"description": "Model Spark X1 zostanie dalej ulepszony, osiągając wyniki w zadaniach ogólnych, takich jak rozumowanie, generowanie tekstu i rozumienie języka, które będą porównywalne z OpenAI o1 i DeepSeek R1."
},
@@ -3443,9 +3431,6 @@
"yi-vision-v2": {
"description": "Model do złożonych zadań wizualnych, oferujący wysokowydajną zdolność rozumienia i analizy na podstawie wielu obrazów."
},
"z-ai/glm-4.6": {
"description": "GLM-4.6 to najnowszy flagowy model od Zhipu AI, który znacząco przewyższa poprzednie wersje w zakresie zaawansowanego kodowania, przetwarzania długich tekstów, wnioskowania i zdolności agentowych."
},
"zai-org/GLM-4.5": {
"description": "GLM-4.5 to podstawowy model zaprojektowany specjalnie do zastosowań agentowych, wykorzystujący architekturę mieszanych ekspertów (Mixture-of-Experts). Model jest głęboko zoptymalizowany pod kątem wywoływania narzędzi, przeglądania stron internetowych, inżynierii oprogramowania i programowania frontendowego, wspierając bezproblemową integrację z inteligentnymi agentami kodu takimi jak Claude Code i Roo Code. GLM-4.5 stosuje hybrydowy tryb wnioskowania, dostosowując się do złożonych i codziennych scenariuszy użycia."
},
+1 -12
View File
@@ -15,12 +15,6 @@
"prompt": "słowo kluczowe"
},
"localFiles": {
"editFile": {
"newString": "Zamień na",
"oldString": "Szukany tekst",
"replaceAll": "Zamień wszystkie wystąpienia",
"replaceFirst": "Zamień tylko pierwsze wystąpienie"
},
"file": "Plik",
"folder": "Folder",
"moveFiles": {
@@ -40,12 +34,7 @@
"readFile": "Odczytaj plik",
"readFileError": "Błąd odczytu pliku, sprawdź, czy ścieżka do pliku jest poprawna",
"readFiles": "Odczytaj pliki",
"readFilesError": "Błąd odczytu plików, sprawdź, czy ścieżka do plików jest poprawna",
"writeFile": {
"characters": "Znaki",
"preview": "Podgląd treści",
"truncated": "Obcięto"
}
"readFilesError": "Błąd odczytu plików, sprawdź, czy ścieżka do plików jest poprawna"
},
"search": {
"createNewSearch": "Utwórz nową historię wyszukiwania",
-5
View File
@@ -330,11 +330,6 @@
"screenshot": "Captura de Tela",
"settings": "Configurações de Exportação",
"text": "Texto",
"widthMode": {
"label": "Modo de largura",
"narrow": "Modo de tela estreita",
"wide": "Modo de tela larga"
},
"withBackground": "Com Imagem de Fundo",
"withFooter": "Com Rodapé",
"withPluginInfo": "Com Informações do Plugin",
-15
View File
@@ -2225,9 +2225,6 @@
"megrez-3b-instruct": {
"description": "Megrez 3B Instruct é um modelo eficiente com poucos parâmetros desenvolvido pela Wuwen Xinqiong."
},
"meituan/longcat-flash-chat": {
"description": "Modelo base não reflexivo de código aberto da Meituan, otimizado para interações em diálogos e tarefas de agentes inteligentes, com desempenho excepcional em chamadas de ferramentas e cenários complexos de múltiplas rodadas."
},
"meta-llama-3-70b-instruct": {
"description": "Um poderoso modelo com 70 bilhões de parâmetros, destacando-se em raciocínio, codificação e amplas aplicações linguísticas."
},
@@ -2459,9 +2456,6 @@
"minimax-m2": {
"description": "MiniMax M2 é um modelo de linguagem de grande escala, eficiente e desenvolvido para fluxos de trabalho de codificação e agentes."
},
"minimax/minimax-m2": {
"description": "Projetado para codificação eficiente e fluxos de trabalho com agentes."
},
"ministral-3b-latest": {
"description": "Ministral 3B é o modelo de ponta da Mistral para aplicações de edge computing."
},
@@ -3377,12 +3371,6 @@
"wizardlm2:8x22b": {
"description": "WizardLM 2 é um modelo de linguagem fornecido pela Microsoft AI, destacando-se em diálogos complexos, multilíngue, raciocínio e assistentes inteligentes."
},
"x-ai/grok-4-fast": {
"description": "Temos o prazer de apresentar o Grok 4 Fast, nosso mais recente avanço em modelos de raciocínio com excelente custo-benefício."
},
"x-ai/grok-code-fast-1": {
"description": "Temos o prazer de lançar o grok-code-fast-1, um modelo de raciocínio rápido e econômico, com desempenho excepcional em codificação assistida por agentes."
},
"x1": {
"description": "O modelo Spark X1 será aprimorado ainda mais, mantendo a liderança em tarefas matemáticas no país, e alcançando resultados em tarefas gerais como raciocínio, geração de texto e compreensão de linguagem que se comparam ao OpenAI o1 e DeepSeek R1."
},
@@ -3443,9 +3431,6 @@
"yi-vision-v2": {
"description": "Modelo para tarefas visuais complexas, oferecendo alta performance em compreensão e análise baseadas em múltiplas imagens."
},
"z-ai/glm-4.6": {
"description": "GLM-4.6, o mais novo modelo carro-chefe da Zhipu, supera amplamente a geração anterior em codificação avançada, processamento de textos longos, raciocínio e capacidades de agentes inteligentes."
},
"zai-org/GLM-4.5": {
"description": "GLM-4.5 é um modelo base projetado para aplicações de agentes inteligentes, utilizando arquitetura Mixture-of-Experts (MoE). Otimizado para chamadas de ferramentas, navegação web, engenharia de software e programação front-end, suporta integração perfeita com agentes de código como Claude Code e Roo Code. Adota modo de raciocínio híbrido, adaptando-se a cenários de raciocínio complexo e uso cotidiano."
},
+1 -12
View File
@@ -15,12 +15,6 @@
"prompt": "Palavra-chave"
},
"localFiles": {
"editFile": {
"newString": "Substituir por",
"oldString": "Procurar por",
"replaceAll": "Substituir todas as correspondências",
"replaceFirst": "Substituir apenas a primeira correspondência"
},
"file": "Arquivo",
"folder": "Pasta",
"moveFiles": {
@@ -40,12 +34,7 @@
"readFile": "Ler arquivo",
"readFileError": "Falha ao ler o arquivo, verifique se o caminho do arquivo está correto",
"readFiles": "Ler arquivos",
"readFilesError": "Falha ao ler os arquivos, verifique se o caminho do arquivo está correto",
"writeFile": {
"characters": "Caracteres",
"preview": "Pré-visualização do conteúdo",
"truncated": "Truncado"
}
"readFilesError": "Falha ao ler os arquivos, verifique se o caminho do arquivo está correto"
},
"search": {
"createNewSearch": "Criar nova pesquisa",
-5
View File
@@ -330,11 +330,6 @@
"screenshot": "Скриншот",
"settings": "Настройки экспорта",
"text": "Текст",
"widthMode": {
"label": "Режим ширины",
"narrow": "Режим узкого экрана",
"wide": "Режим широкого экрана"
},
"withBackground": "С фоном",
"withFooter": "С нижним колонтитулом",
"withPluginInfo": "С информацией о плагинах",
-15
View File
@@ -2225,9 +2225,6 @@
"megrez-3b-instruct": {
"description": "Megrez 3B Instruct — это компактная и эффективная модель с малым числом параметров, разработанная компанией Wuwen Xinqiong."
},
"meituan/longcat-flash-chat": {
"description": "Открытая модель от Meituan, оптимизированная для диалогового взаимодействия и задач интеллектуальных агентов, демонстрирует выдающиеся результаты в использовании инструментов и сложных многоходовых диалогах."
},
"meta-llama-3-70b-instruct": {
"description": "Мощная модель с 70 миллиардами параметров, превосходящая в области рассуждений, кодирования и широких языковых приложений."
},
@@ -2459,9 +2456,6 @@
"minimax-m2": {
"description": "MiniMax M2 — это высокоэффективная крупная языковая модель, созданная специально для задач программирования и автоматизации рабочих процессов."
},
"minimax/minimax-m2": {
"description": "Создана для эффективного кодирования и рабочих процессов агентов."
},
"ministral-3b-latest": {
"description": "Ministral 3B - это выдающаяся модель от Mistral."
},
@@ -3377,12 +3371,6 @@
"wizardlm2:8x22b": {
"description": "WizardLM 2 — это языковая модель, предоставляемая Microsoft AI, которая особенно хорошо проявляет себя в сложных диалогах, многоязычных задачах, выводе и интеллектуальных помощниках."
},
"x-ai/grok-4-fast": {
"description": "Мы рады представить Grok 4 Fast — наш последний прорыв в области экономически эффективных моделей рассуждения."
},
"x-ai/grok-code-fast-1": {
"description": "С радостью представляем grok-code-fast-1 — быструю и экономичную модель рассуждения, отлично подходящую для кодирования с помощью агентов."
},
"x1": {
"description": "Модель Spark X1 будет дополнительно обновлена, и на основе уже существующих лидерских позиций в математических задачах, достигнет сопоставимых результатов в общих задачах, таких как рассуждение, генерация текста и понимание языка, с OpenAI o1 и DeepSeek R1."
},
@@ -3443,9 +3431,6 @@
"yi-vision-v2": {
"description": "Модель для сложных визуальных задач, обеспечивающая высокопроизводительное понимание и анализ на основе нескольких изображений."
},
"z-ai/glm-4.6": {
"description": "Флагманская модель нового поколения от Zhipu — GLM-4.6, значительно превосходящая предыдущую версию в продвинутом кодировании, обработке длинных текстов, рассуждении и возможностях интеллектуальных агентов."
},
"zai-org/GLM-4.5": {
"description": "GLM-4.5 — базовая модель, специально созданная для приложений с агентами, использующая архитектуру смешанных экспертов (Mixture-of-Experts). Модель глубоко оптимизирована для вызова инструментов, веб-браузинга, программной инженерии и фронтенд-разработки, поддерживает бесшовную интеграцию с кодовыми агентами, такими как Claude Code и Roo Code. GLM-4.5 использует смешанный режим вывода, адаптируясь к сложным рассуждениям и повседневным задачам."
},
+1 -12
View File
@@ -15,12 +15,6 @@
"prompt": "подсказка"
},
"localFiles": {
"editFile": {
"newString": "Заменить на",
"oldString": "Найти",
"replaceAll": "Заменить все совпадения",
"replaceFirst": "Заменить только первое совпадение"
},
"file": "Файл",
"folder": "Папка",
"moveFiles": {
@@ -40,12 +34,7 @@
"readFile": "Читать файл",
"readFileError": "Ошибка чтения файла, проверьте правильность пути к файлу",
"readFiles": "Читать файлы",
"readFilesError": "Ошибка чтения файлов, проверьте правильность пути к файлам",
"writeFile": {
"characters": "Символы",
"preview": "Предварительный просмотр содержимого",
"truncated": "Обрезано"
}
"readFilesError": "Ошибка чтения файлов, проверьте правильность пути к файлам"
},
"search": {
"createNewSearch": "Создать новую запись поиска",
-5
View File
@@ -330,11 +330,6 @@
"screenshot": "Ekran Görüntüsü",
"settings": "Ayarlar",
"text": "Metin",
"widthMode": {
"label": "Genişlik Modu",
"narrow": "Dar Ekran Modu",
"wide": "Geniş Ekran Modu"
},
"withBackground": "Arka Plan",
"withFooter": "Footer",
"withPluginInfo": "Plugin Bilgileri",
-15
View File
@@ -2225,9 +2225,6 @@
"megrez-3b-instruct": {
"description": "Megrez 3B Instruct, Wuwen Xinqiong tarafından geliştirilen düşük parametreli, yüksek verimli bir modeldir."
},
"meituan/longcat-flash-chat": {
"description": "Meituan tarafından açık kaynak olarak sunulan, diyalog etkileşimi ve yapay zeka görevleri için optimize edilmiş düşünce içermeyen temel model; araç kullanımı ve karmaşık çok turlu etkileşim senaryolarında üstün performans gösterir."
},
"meta-llama-3-70b-instruct": {
"description": "Akıl yürütme, kodlama ve geniş dil uygulamalarında mükemmel bir 70 milyar parametreli model."
},
@@ -2459,9 +2456,6 @@
"minimax-m2": {
"description": "MiniMax M2, kodlama ve yardımcı iş akışları için özel olarak geliştirilmiş, verimli bir büyük dil modelidir."
},
"minimax/minimax-m2": {
"description": "Verimli kodlama ve Agent iş akışları için özel olarak tasarlanmıştır."
},
"ministral-3b-latest": {
"description": "Ministral 3B, Mistral'ın dünya çapında en üst düzey kenar modelidir."
},
@@ -3377,12 +3371,6 @@
"wizardlm2:8x22b": {
"description": "WizardLM 2, Microsoft AI tarafından sunulan bir dil modelidir, karmaşık diyaloglar, çok dilli, akıl yürütme ve akıllı asistan alanlarında özellikle başarılıdır."
},
"x-ai/grok-4-fast": {
"description": "Grok 4 Fast'i sunmaktan mutluluk duyuyoruz; bu, maliyet etkin çıkarım modelleri konusundaki en son ilerlememizdir."
},
"x-ai/grok-code-fast-1": {
"description": "Hızlı ve ekonomik bir çıkarım modeli olan grok-code-fast-1'i tanıtmaktan memnuniyet duyuyoruz; özellikle temsilci tabanlı kodlamada üstün performans sergiler."
},
"x1": {
"description": "Spark X1 modeli daha da geliştirilecek; önceki matematik görevlerinde ulusal liderlik temelinde, akıl yürütme, metin üretimi, dil anlama gibi genel görevlerde OpenAI o1 ve DeepSeek R1 ile karşılaştırılabilir sonuçlar elde edilecektir."
},
@@ -3443,9 +3431,6 @@
"yi-vision-v2": {
"description": "Karmaşık görsel görevler için model, birden fazla resme dayalı yüksek performanslı anlama ve analiz yetenekleri sunar."
},
"z-ai/glm-4.6": {
"description": "Zhipu'nun en yeni amiral gemisi modeli GLM-4.6; ileri düzey kodlama, uzun metin işleme, çıkarım ve yapay zeka yeteneklerinde seleflerini tamamen geride bırakıyor."
},
"zai-org/GLM-4.5": {
"description": "GLM-4.5, akıllı ajan uygulamaları için tasarlanmış temel modeldir ve Mixture-of-Experts (MoE) mimarisi kullanır. Araç çağrısı, web tarama, yazılım mühendisliği ve ön uç programlama alanlarında derin optimizasyonlar içerir. Claude Code, Roo Code gibi kod ajanlarına sorunsuz entegrasyon destekler. GLM-4.5, karmaşık çıkarım ve günlük kullanım gibi çeşitli senaryolara uyum sağlayan hibrit çıkarım moduna sahiptir."
},
+1 -12
View File
@@ -15,12 +15,6 @@
"prompt": "İpucu"
},
"localFiles": {
"editFile": {
"newString": "Şununla değiştir",
"oldString": "Aranacak içerik",
"replaceAll": "Tüm eşleşmeleri değiştir",
"replaceFirst": "Yalnızca ilk eşleşmeyi değiştir"
},
"file": "Dosya",
"folder": "Klasör",
"moveFiles": {
@@ -40,12 +34,7 @@
"readFile": "Dosyayı Oku",
"readFileError": "Dosya okunamadı, lütfen dosya yolunu kontrol edin",
"readFiles": "Dosyaları Oku",
"readFilesError": "Dosyalar okunamadı, lütfen dosya yolunu kontrol edin",
"writeFile": {
"characters": "Karakter",
"preview": "İçerik Önizlemesi",
"truncated": "Kısaltıldı"
}
"readFilesError": "Dosyalar okunamadı, lütfen dosya yolunu kontrol edin"
},
"search": {
"createNewSearch": "Yeni bir arama kaydı oluştur",
-5
View File
@@ -330,11 +330,6 @@
"screenshot": "Ảnh chụp màn hình",
"settings": "Cài đặt xuất",
"text": "Văn bản",
"widthMode": {
"label": "Chế độ chiều rộng",
"narrow": "Chế độ màn hình hẹp",
"wide": "Chế độ màn hình rộng"
},
"withBackground": "Bao gồm hình nền",
"withFooter": "Bao gồm chân trang",
"withPluginInfo": "Bao gồm thông tin plugin",
-15
View File
@@ -2225,9 +2225,6 @@
"megrez-3b-instruct": {
"description": "Megrez 3B Instruct là mô hình hiệu quả với số lượng tham số nhỏ do Wuwen Xinqiong phát triển."
},
"meituan/longcat-flash-chat": {
"description": "Longcat Flash Chat là mô hình nền không tư duy do Meituan mã nguồn mở, được tối ưu hóa cho tương tác hội thoại và nhiệm vụ của tác nhân, nổi bật trong việc gọi công cụ và các tình huống tương tác nhiều vòng phức tạp."
},
"meta-llama-3-70b-instruct": {
"description": "Mô hình 70 tỷ tham số mạnh mẽ, xuất sắc trong lý luận, lập trình và các ứng dụng ngôn ngữ rộng lớn."
},
@@ -2459,9 +2456,6 @@
"minimax-m2": {
"description": "MiniMax M2 là một mô hình ngôn ngữ lớn hiệu quả, được xây dựng dành riêng cho quy trình làm việc liên quan đến lập trình và tác vụ đại lý."
},
"minimax/minimax-m2": {
"description": "Được sinh ra để phục vụ mã hóa hiệu quả và quy trình làm việc của Agent."
},
"ministral-3b-latest": {
"description": "Ministral 3B là mô hình hàng đầu thế giới của Mistral về hiệu suất cạnh biên."
},
@@ -3377,12 +3371,6 @@
"wizardlm2:8x22b": {
"description": "WizardLM 2 là mô hình ngôn ngữ do Microsoft AI cung cấp, đặc biệt xuất sắc trong các lĩnh vực đối thoại phức tạp, đa ngôn ngữ, suy luận và trợ lý thông minh."
},
"x-ai/grok-4-fast": {
"description": "Chúng tôi rất vui mừng ra mắt Grok 4 Fast, bước tiến mới nhất của chúng tôi trong các mô hình suy luận hiệu quả về chi phí."
},
"x-ai/grok-code-fast-1": {
"description": "Chúng tôi rất vui mừng giới thiệu grok-code-fast-1, một mô hình suy luận nhanh và tiết kiệm chi phí, nổi bật trong mã hóa cho tác nhân."
},
"x1": {
"description": "Mô hình Spark X1 sẽ được nâng cấp thêm, trên nền tảng dẫn đầu trong các nhiệm vụ toán học trong nước, đạt được hiệu quả trong các nhiệm vụ chung như suy luận, tạo văn bản, hiểu ngôn ngữ tương đương với OpenAI o1 và DeepSeek R1."
},
@@ -3443,9 +3431,6 @@
"yi-vision-v2": {
"description": "Mô hình nhiệm vụ thị giác phức tạp, cung cấp khả năng hiểu và phân tích hiệu suất cao dựa trên nhiều hình ảnh."
},
"z-ai/glm-4.6": {
"description": "GLM-4.6, mô hình hàng đầu mới nhất của Zhipu AI, vượt trội hoàn toàn so với thế hệ trước về mã hóa nâng cao, xử lý văn bản dài, suy luận và năng lực tác nhân."
},
"zai-org/GLM-4.5": {
"description": "GLM-4.5 là mô hình nền tảng dành cho ứng dụng tác nhân thông minh, sử dụng kiến trúc chuyên gia hỗn hợp (Mixture-of-Experts). Được tối ưu sâu trong các lĩnh vực gọi công cụ, duyệt web, kỹ thuật phần mềm và lập trình front-end, hỗ trợ tích hợp liền mạch vào các tác nhân mã như Claude Code, Roo Code. GLM-4.5 sử dụng chế độ suy luận hỗn hợp, thích ứng với nhiều kịch bản ứng dụng như suy luận phức tạp và sử dụng hàng ngày."
},
+1 -12
View File
@@ -15,12 +15,6 @@
"prompt": "Từ khóa"
},
"localFiles": {
"editFile": {
"newString": "Thay thế bằng",
"oldString": "Nội dung tìm kiếm",
"replaceAll": "Thay thế tất cả các mục khớp",
"replaceFirst": "Chỉ thay thế mục khớp đầu tiên"
},
"file": "Tệp",
"folder": "Thư mục",
"moveFiles": {
@@ -40,12 +34,7 @@
"readFile": "Đọc tệp",
"readFileError": "Đọc tệp thất bại, vui lòng kiểm tra đường dẫn tệp có đúng không",
"readFiles": "Đọc tệp",
"readFilesError": "Đọc tệp thất bại, vui lòng kiểm tra đường dẫn tệp có đúng không",
"writeFile": {
"characters": "Ký tự",
"preview": "Xem trước nội dung",
"truncated": "Đã bị cắt bớt"
}
"readFilesError": "Đọc tệp thất bại, vui lòng kiểm tra đường dẫn tệp có đúng không"
},
"search": {
"createNewSearch": "Tạo mới tìm kiếm",
-5
View File
@@ -330,11 +330,6 @@
"screenshot": "截图",
"settings": "导出设置",
"text": "文本",
"widthMode": {
"label": "宽度模式",
"narrow": "窄屏模式",
"wide": "宽屏模式"
},
"withBackground": "包含背景图片",
"withFooter": "包含页脚",
"withPluginInfo": "包含插件信息",
-15
View File
@@ -2225,9 +2225,6 @@
"megrez-3b-instruct": {
"description": "Megrez 3B Instruct 是无问芯穹推出的小参数量高效模型。"
},
"meituan/longcat-flash-chat": {
"description": "美团开源的专为对话交互和智能体任务优化的非思维型基础模型,在工具调用和复杂多轮交互场景中表现突出"
},
"meta-llama-3-70b-instruct": {
"description": "一个强大的700亿参数模型,在推理、编码和广泛的语言应用方面表现出色。"
},
@@ -2459,9 +2456,6 @@
"minimax-m2": {
"description": "MiniMax M2 是专为编码和代理工作流程构建的高效大型语言模型。"
},
"minimax/minimax-m2": {
"description": "专为高效编码与 Agent 工作流而生"
},
"ministral-3b-latest": {
"description": "Ministral 3B 是Mistral的世界顶级边缘模型。"
},
@@ -3377,12 +3371,6 @@
"wizardlm2:8x22b": {
"description": "WizardLM 2 是微软AI提供的语言模型,在复杂对话、多语言、推理和智能助手领域表现尤为出色。"
},
"x-ai/grok-4-fast": {
"description": "我们很高兴发布 Grok 4 Fast,这是我们在成本效益推理模型方面的最新进展。"
},
"x-ai/grok-code-fast-1": {
"description": "我们很高兴推出 grok-code-fast-1,这是一款快速且经济高效的推理模型,在代理编码方面表现出色。"
},
"x1": {
"description": "Spark X1 模型将进一步升级,在原来数学任务国内领先基础上,推理、文本生成、语言理解等通用任务实现效果对标 OpenAI o1 和 DeepSeek R1。"
},
@@ -3443,9 +3431,6 @@
"yi-vision-v2": {
"description": "复杂视觉任务模型,提供基于多张图片的高性能理解、分析能力。"
},
"z-ai/glm-4.6": {
"description": "智谱最新旗舰模型 GLM-4.6,在高级编码、长文本处理、推理与智能体能力上全面超越前代。"
},
"zai-org/GLM-4.5": {
"description": "GLM-4.5 是一款专为智能体应用打造的基础模型,使用了混合专家(Mixture-of-Experts)架构。在工具调用、网页浏览、软件工程、前端编程领域进行了深度优化,支持无缝接入 Claude Code、Roo Code 等代码智能体中使用。GLM-4.5 采用混合推理模式,可以适应复杂推理和日常使用等多种应用场景。"
},
+1 -12
View File
@@ -15,12 +15,6 @@
"prompt": "提示词"
},
"localFiles": {
"editFile": {
"newString": "替换为",
"oldString": "查找内容",
"replaceAll": "替换全部匹配项",
"replaceFirst": "仅替换第一个匹配项"
},
"file": "文件",
"folder": "文件夹",
"moveFiles": {
@@ -40,12 +34,7 @@
"readFile": "读取文件",
"readFileError": "读取文件失败,请检查文件路径是否正确",
"readFiles": "读取文件",
"readFilesError": "读取文件失败,请检查文件路径是否正确",
"writeFile": {
"characters": "字符",
"preview": "内容预览",
"truncated": "已截断"
}
"readFilesError": "读取文件失败,请检查文件路径是否正确"
},
"search": {
"createNewSearch": "创建新的搜索记录",
-5
View File
@@ -330,11 +330,6 @@
"screenshot": "截圖",
"settings": "導出設置",
"text": "文本",
"widthMode": {
"label": "寬度模式",
"narrow": "窄螢幕模式",
"wide": "寬螢幕模式"
},
"withBackground": "包含背景圖片",
"withFooter": "包含頁腳",
"withPluginInfo": "包含插件信息",
-15
View File
@@ -2225,9 +2225,6 @@
"megrez-3b-instruct": {
"description": "Megrez 3B Instruct 是無問芯穹推出的小參數量高效模型。"
},
"meituan/longcat-flash-chat": {
"description": "美團開源的專為對話互動與智慧體任務優化的非思維型基礎模型,在工具調用與複雜多輪互動場景中表現出色"
},
"meta-llama-3-70b-instruct": {
"description": "一個強大的70億參數模型,在推理、編碼和廣泛的語言應用中表現出色。"
},
@@ -2459,9 +2456,6 @@
"minimax-m2": {
"description": "MiniMax M2 是專為編碼與代理工作流程打造的高效大型語言模型。"
},
"minimax/minimax-m2": {
"description": "專為高效編碼與 Agent 工作流程而設計"
},
"ministral-3b-latest": {
"description": "Ministral 3B 是 Mistral 的全球頂尖邊緣模型。"
},
@@ -3377,12 +3371,6 @@
"wizardlm2:8x22b": {
"description": "WizardLM 2 是微軟 AI 提供的語言模型,在複雜對話、多語言、推理和智能助手領域表現尤為出色。"
},
"x-ai/grok-4-fast": {
"description": "我們很高興推出 Grok 4 Fast,這是我們在成本效益推理模型方面的最新進展。"
},
"x-ai/grok-code-fast-1": {
"description": "我們很高興推出 grok-code-fast-1,這是一款快速且具成本效益的推理模型,在代理編碼方面表現優異。"
},
"x1": {
"description": "Spark X1 模型將進一步升級,在原來數學任務國內領先的基礎上,推理、文本生成、語言理解等通用任務實現效果對標 OpenAI o1 和 DeepSeek R1。"
},
@@ -3443,9 +3431,6 @@
"yi-vision-v2": {
"description": "複雜視覺任務模型,提供基於多張圖片的高性能理解、分析能力。"
},
"z-ai/glm-4.6": {
"description": "智譜最新旗艦模型 GLM-4.6,在高階編碼、長文本處理、推理與智慧體能力上全面超越前代。"
},
"zai-org/GLM-4.5": {
"description": "GLM-4.5 是一款專為智能體應用打造的基礎模型,使用了混合專家(Mixture-of-Experts)架構。在工具調用、網頁瀏覽、軟體工程、前端程式設計領域進行了深度優化,支持無縫接入 Claude Code、Roo Code 等程式碼智能體中使用。GLM-4.5 採用混合推理模式,可以適應複雜推理和日常使用等多種應用場景。"
},
+1 -12
View File
@@ -15,12 +15,6 @@
"prompt": "提示詞"
},
"localFiles": {
"editFile": {
"newString": "取代為",
"oldString": "尋找內容",
"replaceAll": "取代所有符合項目",
"replaceFirst": "僅取代第一個符合項目"
},
"file": "檔案",
"folder": "資料夾",
"moveFiles": {
@@ -40,12 +34,7 @@
"readFile": "讀取檔案",
"readFileError": "讀取檔案失敗,請檢查檔案路徑是否正確",
"readFiles": "讀取檔案",
"readFilesError": "讀取檔案失敗,請檢查檔案路徑是否正確",
"writeFile": {
"characters": "字元",
"preview": "內容預覽",
"truncated": "已截斷"
}
"readFilesError": "讀取檔案失敗,請檢查檔案路徑是否正確"
},
"search": {
"createNewSearch": "建立新的搜尋紀錄",
+3 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@lobehub/lobehub",
"version": "2.0.0-next.75",
"version": "2.0.0-next.69",
"description": "LobeHub - an open-source,comprehensive AI Agent framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
"keywords": [
"framework",
@@ -191,7 +191,6 @@
"@vercel/speed-insights": "^1.2.0",
"@virtuoso.dev/masonry": "^1.3.5",
"@xterm/xterm": "^5.5.0",
"@zumer/snapdom": "^1.9.14",
"ahooks": "^3.9.6",
"antd": "^5.28.1",
"antd-style": "^3.7.1",
@@ -229,6 +228,7 @@
"marked": "^16.4.2",
"mdast-util-to-markdown": "^2.1.2",
"model-bank": "workspace:*",
"modern-screenshot": "^4.6.6",
"nanoid": "^5.1.6",
"next": "^16.0.3",
"next-auth": "5.0.0-beta.30",
@@ -258,7 +258,6 @@
"random-words": "^2.0.1",
"react": "19.2.0",
"react-confetti": "^6.4.0",
"react-diff-view": "^3.3.2",
"react-dom": "19.2.0",
"react-fast-marquee": "^1.6.5",
"react-hotkeys-hook": "^5.2.1",
@@ -398,4 +397,4 @@
"@vercel/speed-insights"
]
}
}
}
@@ -48,7 +48,6 @@ export interface RenameLocalFileResult {
}
export interface LocalReadFileParams {
fullContent?: boolean;
loc?: [number, number];
path: string;
}
@@ -218,10 +217,7 @@ export interface EditLocalFileParams {
}
export interface EditLocalFileResult {
diffText?: string;
error?: string;
linesAdded?: number;
linesDeleted?: number;
replacements: number;
success: boolean;
}
-126
View File
@@ -27,132 +27,6 @@ const qiniuChatModels: AIChatModelCard[] = [
id: 'deepseek-r1',
type: 'chat',
},
{
abilities: {
functionCall: true,
reasoning: true,
search: true,
},
contextWindowTokens: 204_800,
description: '专为高效编码与 Agent 工作流而生',
displayName: 'MiniMax M2',
enabled: true,
id: 'minimax/minimax-m2',
maxOutput: 131_072,
pricing: {
currency: 'CNY',
units: [
{ name: 'textInput', rate: 2.1, strategy: 'fixed', unit: 'millionTokens' },
{ name: 'textOutput', rate: 8.4, strategy: 'fixed', unit: 'millionTokens' },
],
},
releasedAt: '2025-10-27',
settings: {
searchImpl: 'params',
},
type: 'chat',
},
{
abilities: {
functionCall: true,
reasoning: true,
},
contextWindowTokens: 131_072,
description: '美团开源的专为对话交互和智能体任务优化的非思维型基础模型,在工具调用和复杂多轮交互场景中表现突出',
displayName: 'LongCat Flash Chat',
enabled: true,
id: 'meituan/longcat-flash-chat',
maxOutput: 65536,
pricing: {
currency: 'CNY',
units: [
{ name: 'textInput', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
{ name: 'textOutput', rate: 0, strategy: 'fixed', unit: 'millionTokens' },
],
},
releasedAt: '2025-09-01',
settings: {
extendParams: ['enableReasoning'],
searchImpl: 'params',
},
type: 'chat',
},
{
abilities: {
functionCall: true,
reasoning: true,
search: true,
},
contextWindowTokens: 200_000,
description: '智谱最新旗舰模型 GLM-4.6,在高级编码、长文本处理、推理与智能体能力上全面超越前代。',
displayName: 'GLM-4.6',
enabled: true,
id: 'z-ai/glm-4.6',
maxOutput: 128_000,
pricing: {
currency: 'CNY',
units: [
{ name: 'textInput', rate: 7.2, strategy: 'fixed', unit: 'millionTokens' },
{ name: 'textOutput', rate: 12.6, strategy: 'fixed', unit: 'millionTokens' },
],
},
releasedAt: '2025-09-30',
settings: {
extendParams: ['enableReasoning'],
searchImpl: 'params',
},
type: 'chat',
},
{
abilities: {
functionCall: true,
reasoning: true,
search: true,
vision: true,
},
contextWindowTokens: 2_000_000,
description:
'我们很高兴发布 Grok 4 Fast,这是我们在成本效益推理模型方面的最新进展。',
displayName: 'Grok 4 Fast',
enabled: true,
id: 'x-ai/grok-4-fast',
pricing: {
currency: 'CNY',
units: [
{ name: 'textInput', rate: 7.2, strategy: 'fixed', unit: 'millionTokens' },
{ name: 'textOutput', rate: 12.6, strategy: 'fixed', unit: 'millionTokens' },
],
},
releasedAt: '2025-09-09',
settings: {
searchImpl: 'params',
},
type: 'chat',
},
{
abilities: {
functionCall: true,
reasoning: true,
},
contextWindowTokens: 256_000,
description:
'我们很高兴推出 grok-code-fast-1,这是一款快速且经济高效的推理模型,在代理编码方面表现出色。',
displayName: 'Grok Code Fast 1',
id: 'x-ai/grok-code-fast-1',
pricing: {
units: [
{ name: 'textInput_cacheRead', rate: 0.02, strategy: 'fixed', unit: 'millionTokens' },
{ name: 'textInput', rate: 0.2, strategy: 'fixed', unit: 'millionTokens' },
{ name: 'textOutput', rate: 1.5, strategy: 'fixed', unit: 'millionTokens' },
],
},
releasedAt: '2025-08-27',
// settings: {
// reasoning_effort is not supported by grok-code. Specifying reasoning_effort parameter will get an error response.
// extendParams: ['reasoningEffort'],
// },
type: 'chat',
},
];
export const allModels = [...qiniuChatModels];
+5 -5
View File
@@ -10,14 +10,14 @@
"dependencies": {
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/auto-instrumentations-node": "^0.66.0",
"@opentelemetry/exporter-metrics-otlp-http": "^0.208.0",
"@opentelemetry/exporter-trace-otlp-http": "^0.208.0",
"@opentelemetry/instrumentation": "^0.208.0",
"@opentelemetry/instrumentation-http": "^0.208.0",
"@opentelemetry/exporter-metrics-otlp-http": "^0.207.0",
"@opentelemetry/exporter-trace-otlp-http": "^0.207.0",
"@opentelemetry/instrumentation": "^0.207.0",
"@opentelemetry/instrumentation-http": "^0.207.0",
"@opentelemetry/instrumentation-pg": "^0.60.0",
"@opentelemetry/resources": "^2.2.0",
"@opentelemetry/sdk-metrics": "^2.2.0",
"@opentelemetry/sdk-node": "^0.208.0",
"@opentelemetry/sdk-node": "^0.207.0",
"@opentelemetry/sdk-trace-node": "^2.2.0",
"@opentelemetry/semantic-conventions": "^1.38.0",
"@vercel/otel": "^2.1.0"
+8 -8
View File
@@ -17,16 +17,16 @@ export interface LobeAgentChatConfig {
enableMaxTokens?: boolean;
/**
* Whether to enable streaming output
* 是否开启流式输出
*/
enableStreaming?: boolean;
/**
* Whether to enable reasoning
* 是否开启推理
*/
enableReasoning?: boolean;
/**
* Custom reasoning effort level
* 自定义推理强度
*/
enableReasoningEffort?: boolean;
reasoningBudgetToken?: number;
@@ -34,25 +34,25 @@ export interface LobeAgentChatConfig {
gpt5ReasoningEffort?: 'minimal' | 'low' | 'medium' | 'high';
gpt5_1ReasoningEffort?: 'none' | 'low' | 'medium' | 'high';
/**
* Output text verbosity control
* 输出文本详细程度控制
*/
textVerbosity?: 'low' | 'medium' | 'high';
thinking?: 'disabled' | 'auto' | 'enabled';
thinkingBudget?: number;
/**
* Disable context caching
* 禁用上下文缓存
*/
disableContextCaching?: boolean;
/**
* Number of historical messages
* 历史消息条数
*/
historyCount?: number;
/**
* Enable historical message count
* 开启历史记录条数
*/
enableHistoryCount?: boolean;
/**
* Enable history message compression threshold
* 历史消息长度压缩阈值
*/
enableCompressHistory?: boolean;
+4 -4
View File
@@ -56,12 +56,12 @@ export interface LobeDocument {
source: string;
/**
* Document source type
* 文档来源类型
*/
sourceType: DocumentSourceType;
/**
* Document title (if available)
* 文档标题 (如果可用)。
*/
title?: string;
@@ -168,12 +168,12 @@ export enum DocumentSourceType {
API = 'api',
/**
* Document created in editor
* 编辑器创建的文档
*/
EDITOR = 'editor',
/**
* Local or uploaded file
* 本地或上传的文件
*/
FILE = 'file',
+9 -9
View File
@@ -2,15 +2,15 @@
import type { ILobeAgentRuntimeErrorType } from '@lobechat/model-runtime';
export const ChatErrorType = {
// ******* Business Error Semantics ******* //
// ******* 业务错误语义 ******* //
InvalidAccessCode: 'InvalidAccessCode', // is in valid password
InvalidClerkUser: 'InvalidClerkUser', // is not Clerk User
FreePlanLimit: 'FreePlanLimit', // is not Clerk User
SubscriptionPlanLimit: 'SubscriptionPlanLimit', // Subscription user limit exceeded
SubscriptionKeyMismatch: 'SubscriptionKeyMismatch', // Subscription key mismatch
SubscriptionPlanLimit: 'SubscriptionPlanLimit', // 订阅用户超限
SubscriptionKeyMismatch: 'SubscriptionKeyMismatch', // 订阅 key 不匹配
SupervisorDecisionFailed: 'SupervisorDecisionFailed', // Supervisor decision failed
SupervisorDecisionFailed: 'SupervisorDecisionFailed', // 主持人决策失败
InvalidUserKey: 'InvalidUserKey', // is not valid User key
CreateMessageError: 'CreateMessageError',
@@ -18,20 +18,20 @@ export const ChatErrorType = {
* @deprecated
*/
NoOpenAIAPIKey: 'NoOpenAIAPIKey',
OllamaServiceUnavailable: 'OllamaServiceUnavailable', // Ollama service not started/detected
OllamaServiceUnavailable: 'OllamaServiceUnavailable', // 未启动/检测到 Ollama 服务
PluginFailToTransformArguments: 'PluginFailToTransformArguments',
UnknownChatFetchError: 'UnknownChatFetchError',
SystemTimeNotMatchError: 'SystemTimeNotMatchError',
// ******* Client Errors ******* //
// ******* 客户端错误 ******* //
BadRequest: 400,
Unauthorized: 401,
Forbidden: 403,
ContentNotFound: 404, // Endpoint not found
MethodNotAllowed: 405, // Method not supported
ContentNotFound: 404, // 没找到接口
MethodNotAllowed: 405, // 不支持
TooManyRequests: 429,
// ******* Server Errors ******* //InvalidPluginArgumentsTransform
// ******* 服务端错误 ******* //InvalidPluginArgumentsTransform
InternalServerError: 500,
BadGateway: 502,
ServiceUnavailable: 503,
+5 -5
View File
@@ -84,7 +84,7 @@ export const HotkeyGroupEnum = {
export const HotkeyScopeEnum = {
Chat: 'chat',
Files: 'files',
// Default globally registered hotkey scope
// 默认全局注册的快捷键 scope
// https://react-hotkeys-hook.vercel.app/docs/documentation/hotkeys-provider
Global: 'global',
@@ -96,13 +96,13 @@ export type HotkeyGroupId = (typeof HotkeyGroupEnum)[keyof typeof HotkeyGroupEnu
export type HotkeyScopeId = (typeof HotkeyScopeEnum)[keyof typeof HotkeyScopeEnum];
export interface HotkeyItem {
// Hotkey grouping for display purposes
// 快捷键分组用于展示
group: HotkeyGroupId;
id: HotkeyId;
keys: string;
// Whether the hotkey is non-editable
// 是否为不可编辑的快捷键
nonEditable?: boolean;
// Hotkey scope
// 快捷键作用域
scopes?: HotkeyScopeId[];
}
@@ -119,7 +119,7 @@ export interface DesktopHotkeyItem {
id: DesktopHotkeyId;
keys: string;
// Whether the hotkey is non-editable
// 是否为不可编辑的快捷键
nonEditable?: boolean;
}
+2 -2
View File
@@ -26,11 +26,11 @@ export interface ImportMessage {
createdAt: number;
error?: ChatMessageError;
// Extended fields
// 扩展字段
extra?: {
model?: string;
provider?: string;
// Translation
// 翻译
translate?: ChatTranslate | false | null;
// TTS
tts?: ChatTTS;
@@ -109,8 +109,8 @@ export interface MessageMetadata extends ModelUsage, ModelPerformance {
activeBranchIndex?: number;
activeColumn?: boolean;
/**
* Message collapse state
* true: collapsed, false/undefined: expanded
* 消息折叠状态
* true: 折叠, false/undefined: 展开
*/
collapsed?: boolean;
compare?: boolean;
+1 -1
View File
@@ -112,7 +112,7 @@ export const ChatToolPayloadSchema = z.object({
});
/**
* Chat message error object
* 聊天消息错误对象
*/
export interface ChatMessagePluginError {
body?: any;
+3 -3
View File
@@ -2,11 +2,11 @@ import { z } from 'zod';
export const LobeMetaDataSchema = z.object({
/**
* Character avatar
* 角色头像
*/
avatar: z.string().optional(),
/**
* Background color
* 背景色
*/
backgroundColor: z.string().optional(),
description: z.string().optional(),
@@ -17,7 +17,7 @@ export const LobeMetaDataSchema = z.object({
tags: z.array(z.string()).optional(),
/**
* Name
* 名称
*/
title: z.string().optional(),
});
+1 -1
View File
@@ -1,6 +1,6 @@
import type { BaseDataModel } from '../meta';
// Type definitions
// 类型定义
export type TimeGroupId =
| 'today'
| 'yesterday'
+4 -4
View File
@@ -16,7 +16,7 @@ export interface CrawlErrorResult {
}
export interface FilterOptions {
// Whether to enable Readability
// 是否启用Readability
enableReadability?: boolean;
pureText?: boolean;
@@ -34,12 +34,12 @@ export type CrawlImpl<Params = object> = (
) => Promise<CrawlSuccessResult | undefined>;
export interface CrawlUrlRule {
// Content filtering configuration (optional)
// 内容过滤配置(可选)
filterOptions?: FilterOptions;
impls?: CrawlImplType[];
// URL matching pattern, only supports regular expressions
// URL匹配模式,仅支持正则表达式
urlPattern: string;
// URL transformation template (optional), performs URL conversion if provided
// URL转换模板(可选),如果提供则进行URL转换
urlTransform?: string;
}
+5 -15
View File
@@ -20,11 +20,11 @@ const partialBuildPages = [
disabled: isDesktop,
paths: ['src/app/[variants]/(auth)'],
},
// {
// name: 'mobile',
// disabled: isDesktop,
// paths: ['src/app/[variants]/(main)/(mobile)'],
// },
{
name: 'mobile',
disabled: isDesktop,
paths: ['src/app/[variants]/(main)/(mobile)'],
},
{
name: 'oauth',
disabled: isDesktop,
@@ -35,16 +35,6 @@ const partialBuildPages = [
disabled: isDesktop,
paths: ['src/app/(backend)/api/webhooks'],
},
{
name: 'market-auth',
disabled: isDesktop,
paths: ['src/app/market-auth-callback'],
},
{
name: 'pwa',
disabled: isDesktop,
paths: ['src/manifest.ts', 'src/sitemap.tsx', 'src/robots.tsx', 'src/sw'],
},
// no need for web
{
name: 'desktop-devtools',
@@ -97,15 +97,15 @@ const TopicContent = memo<TopicContentProps>(({ id, title, fav, showMore }) => {
},
...(isDesktop
? [
{
icon: <Icon icon={ExternalLink} />,
key: 'openInNewWindow',
label: t('actions.openInNewWindow'),
onClick: () => {
openTopicInNewWindow(activeId, id);
},
{
icon: <Icon icon={ExternalLink} />,
key: 'openInNewWindow',
label: t('actions.openInNewWindow'),
onClick: () => {
openTopicInNewWindow(activeId, id);
},
]
},
]
: []),
{
type: 'divider',
@@ -153,16 +153,7 @@ const TopicContent = memo<TopicContentProps>(({ id, title, fav, showMore }) => {
},
},
],
[
id,
activeId,
autoRenameTopicTitle,
duplicateTopic,
removeTopic,
t,
toggleEditing,
openTopicInNewWindow,
],
[id, activeId, autoRenameTopicTitle, duplicateTopic, removeTopic, t, toggleEditing, openTopicInNewWindow],
);
return (
@@ -189,7 +180,7 @@ const TopicContent = memo<TopicContentProps>(({ id, title, fav, showMore }) => {
spin={isLoading}
/>
{!editing ? (
title === LOADING_FLAT || (isLoading && !title) ? (
title === LOADING_FLAT ? (
<Flexbox flex={1} height={28} justify={'center'}>
<BubblesLoading />
</Flexbox>
@@ -199,7 +190,7 @@ const TopicContent = memo<TopicContentProps>(({ id, title, fav, showMore }) => {
ellipsis={{ rows: 1, tooltip: { placement: 'left', title } }}
onDoubleClick={() => {
if (isDesktop) {
openTopicInNewWindow(activeId, id);
openTopicInNewWindow(activeId, id)
}
}}
style={{ margin: 0 }}
+19 -2
View File
@@ -1,12 +1,13 @@
'use client';
import { useEffect } from 'react';
import { type LoaderFunction, createBrowserRouter, redirect, useNavigate } from 'react-router-dom';
import { createBrowserRouter, redirect, type LoaderFunction, useNavigate } from 'react-router-dom';
import Loading from '@/components/Loading/BrandTextLoading';
import { useGlobalStore } from '@/store/global';
import type { Locales } from '@/types/locale';
import DesktopChangelogLayout from './(main)/changelog/_layout/Desktop';
import DesktopMainLayout from './(main)/layouts/desktop';
import { idLoader, slugLoader } from './loaders/routeParams';
@@ -64,6 +65,7 @@ export const createDesktopRouter = (locale: Locales) =>
createBrowserRouter([
{
HydrateFallback: () => <Loading />,
loader: hydrationGateLoader,
children: [
// Chat routes
{
@@ -299,6 +301,22 @@ export const createDesktopRouter = (locale: Locales) =>
path: 'labs',
},
// Changelog routes
{
children: [
{
index: true,
lazy: () =>
import('./(main)/changelog').then((m) => ({
Component: m.DesktopPage,
})),
path: '*',
},
],
element: <DesktopChangelogLayout locale={locale} />,
path: 'changelog',
},
// Profile routes
{
children: [
@@ -358,7 +376,6 @@ export const createDesktopRouter = (locale: Locales) =>
},
],
element: <RootLayout locale={locale} />,
loader: hydrationGateLoader,
path: '/',
},
]);
+4 -2
View File
@@ -1,7 +1,6 @@
import { SpeedInsights } from '@vercel/speed-insights/next';
import { ThemeAppearance } from 'antd-style';
import { ResolvingViewport } from 'next';
import { NuqsAdapter } from 'nuqs/adapters/next/app';
import { ReactNode } from 'react';
import { isRtlLang } from 'rtl-detect';
@@ -14,14 +13,16 @@ import GlobalProvider from '@/layout/GlobalProvider';
import { Locales } from '@/locales/resources';
import { DynamicLayoutProps } from '@/types/next';
import { RouteVariants } from '@/utils/server/routeVariants';
import { NuqsAdapter } from 'nuqs/adapters/next/app';
const inVercel = process.env.VERCEL === '1';
interface RootLayoutProps extends DynamicLayoutProps {
children: ReactNode;
modal: ReactNode;
}
const RootLayout = async ({ children, params }: RootLayoutProps) => {
const RootLayout = async ({ children, params, modal }: RootLayoutProps) => {
const { variants } = await params;
const { locale, isMobile, theme, primaryColor, neutralColor } =
@@ -49,6 +50,7 @@ const RootLayout = async ({ children, params }: RootLayoutProps) => {
>
<AuthProvider>
{children}
{!isMobile && modal}
</AuthProvider>
<PWAInstall />
</GlobalProvider>
+26 -12
View File
@@ -1,12 +1,13 @@
'use client';
import { useEffect } from 'react';
import { type LoaderFunction, createBrowserRouter, redirect, useNavigate } from 'react-router-dom';
import { redirect, createBrowserRouter, type LoaderFunction, useNavigate } from 'react-router-dom';
import Loading from '@/components/Loading/BrandTextLoading';
import { useGlobalStore } from '@/store/global';
import type { Locales } from '@/types/locale';
import MobileChangelogLayout from './(main)/changelog/_layout/Mobile';
import { MobileMainLayout } from './(main)/layouts/mobile';
import { idLoader, slugLoader } from './loaders/routeParams';
@@ -62,6 +63,7 @@ export const createMobileRouter = (locale: Locales) =>
createBrowserRouter([
{
HydrateFallback: () => <Loading />,
loader: hydrationGateLoader,
children: [
// Chat routes
{
@@ -286,6 +288,21 @@ export const createMobileRouter = (locale: Locales) =>
path: 'labs',
},
// Changelog routes
{
children: [
{
index: true,
lazy: () =>
import('./(main)/changelog').then((m) => ({
Component: m.MobilePage,
})),
},
],
element: <MobileChangelogLayout locale={locale} />,
path: 'changelog',
},
// Profile routes
{
children: [
@@ -344,15 +361,13 @@ export const createMobileRouter = (locale: Locales) =>
})),
},
{
children: [
{
lazy: () =>
import('./(main)/(mobile)/me/profile').then((m) => ({
Component: m.default,
})),
path: 'profile',
},
],
children: [{
lazy: () =>
import('./(main)/(mobile)/me/profile').then((m) => ({
Component: m.default,
})),
path: 'profile',
}],
lazy: () =>
import('./(main)/(mobile)/me/profile/layout').then((m) => ({
Component: m.default,
@@ -372,7 +387,7 @@ export const createMobileRouter = (locale: Locales) =>
import('./(main)/(mobile)/me/settings/layout').then((m) => ({
Component: m.default,
})),
},
}
],
path: 'me',
},
@@ -390,7 +405,6 @@ export const createMobileRouter = (locale: Locales) =>
},
],
element: <RootLayout locale={locale} />,
loader: hydrationGateLoader,
path: '/',
},
]);
+4 -5
View File
@@ -1,10 +1,7 @@
import { DynamicLayoutProps } from '@/types/next';
import { RouteVariants } from '@/utils/server/routeVariants';
import DesktopRouter from './DesktopRouter';
import MobileRouter from './MobileRouter';
export default async (props: DynamicLayoutProps) => {
export default async function Page(props: DynamicLayoutProps) {
// Get isMobile from variants parameter on server side
const isMobile = await RouteVariants.getIsMobile(props);
const { locale } = await RouteVariants.getVariantsFromProps(props);
@@ -13,8 +10,10 @@ export default async (props: DynamicLayoutProps) => {
// Using native dynamic import ensures complete code splitting
// Mobile and Desktop bundles will be completely separate
if (isMobile) {
const { default: MobileRouter } = await import('./MobileRouter');
return <MobileRouter locale={locale} />;
}
const { default: DesktopRouter } = await import('./DesktopRouter');
return <DesktopRouter locale={locale} />;
};
}
+2 -6
View File
@@ -80,16 +80,12 @@ class BootErrorBoundary extends Component<BootErrorBoundaryProps, BootErrorBound
if (attempts >= maxReloads) {
// eslint-disable-next-line no-console
console.warn('BootErrorBoundary reached max reload attempts', {
attempts,
href,
maxReloads,
});
console.warn('BootErrorBoundary reached max reload attempts', { attempts, maxReloads, href });
return false;
}
// eslint-disable-next-line no-console
console.info('BootErrorBoundary forcing hard reload', { attempts, href, maxReloads });
console.info('BootErrorBoundary forcing hard reload', { attempts, maxReloads, href });
window.sessionStorage.setItem(RELOAD_SESSION_KEY, String(attempts + 1));
} catch (error) {
// If sessionStorage is unavailable, we still attempt a reload once.
@@ -11,7 +11,7 @@ import {
Trash2,
X,
} from 'lucide-react';
import { CSSProperties, memo, useEffect, useState } from 'react';
import { CSSProperties, memo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';
@@ -97,6 +97,7 @@ const Inspectors = memo<InspectorProps>(
apiName,
id,
arguments: requestArgs,
showRender,
result,
setShowRender,
showPluginRender,
@@ -108,8 +109,6 @@ const Inspectors = memo<InspectorProps>(
const { styles, theme } = useStyles();
const [showDebug, setShowDebug] = useState(false);
const [isPinned, setIsPinned] = useState(false);
const [isHovered, setIsHovered] = useState(false);
const [deleteAssistantMessage] = useChatStore((s) => [s.deleteAssistantMessage]);
@@ -122,15 +121,7 @@ const Inspectors = memo<InspectorProps>(
const isReject = intervention?.status === 'rejected';
const isTitleLoading = !hasResult && !isPending;
// Compute actual render state based on pinned or hovered
const shouldShowRender = isPinned || isHovered;
// Sync with parent state
useEffect(() => {
setShowRender(shouldShowRender);
}, [shouldShowRender, setShowRender]);
const showCustomPluginRender = shouldShowRender && !isPending && !isReject;
const showCustomPluginRender = showRender && !isPending && !isReject;
return (
<Flexbox className={styles.container} gap={4}>
<Flexbox align={'center'} distribution={'space-between'} gap={8} horizontal>
@@ -140,17 +131,7 @@ const Inspectors = memo<InspectorProps>(
gap={8}
horizontal
onClick={() => {
setIsPinned(!isPinned);
}}
onMouseEnter={() => {
if (!isPinned) {
setIsHovered(true);
}
}}
onMouseLeave={() => {
if (!isPinned) {
setIsHovered(false);
}
setShowRender(!showRender);
}}
paddingInline={4}
>
@@ -1,9 +1,9 @@
import { copyImageToClipboard, sanitizeSVGContent } from '@lobechat/utils/client';
import { Button, Dropdown, Tooltip } from '@lobehub/ui';
import { snapdom } from '@zumer/snapdom';
import { App, Space } from 'antd';
import { css, cx } from 'antd-style';
import { CopyIcon, DownloadIcon } from 'lucide-react';
import { domToPng } from 'modern-screenshot';
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { Center, Flexbox } from 'react-layout-kit';
@@ -41,29 +41,12 @@ const SVGRenderer = ({ content }: SVGRendererProps) => {
const sanitizedContent = useMemo(() => sanitizeSVGContent(content), [content]);
const generatePng = async () => {
const blob = await snapdom.toBlob(document.querySelector(`#${DOM_ID}`) as HTMLDivElement, {
return domToPng(document.querySelector(`#${DOM_ID}`) as HTMLDivElement, {
features: {
// 不启用移除控制符,否则会导致 safari emoji 报错
removeControlCharacter: false,
},
scale: 2,
type: 'png',
});
if (!blob) {
throw new Error('Failed to generate PNG blob');
}
// Convert blob to data URL
return new Promise<string>((resolve, reject) => {
const reader = new FileReader();
reader.addEventListener('load', () => {
if (typeof reader.result === 'string') {
resolve(reader.result);
} else {
reject(new Error('FileReader result is not a string'));
}
});
reader.addEventListener('error', () =>
reject(reader.error || new Error('Failed to read blob as data URL')),
);
reader.readAsDataURL(blob);
});
};
@@ -19,7 +19,7 @@ import { useStyles } from './style';
import { FieldType } from './type';
const Preview = memo<FieldType & { title?: string }>(
({ title, withSystemRole, withBackground, withFooter, widthMode }) => {
({ title, withSystemRole, withBackground, withFooter }) => {
const [model, plugins, systemRole] = useAgentStore((s) => [
agentSelectors.currentAgentModel(s),
agentSelectors.displayableAgentPlugins(s),
@@ -34,7 +34,7 @@ const Preview = memo<FieldType & { title?: string }>(
const { t } = useTranslation('chat');
const { styles } = useStyles(withBackground);
const { styles: containerStyles } = useContainerStyles(widthMode);
const { styles: containerStyles } = useContainerStyles();
const displayTitle = isInbox ? t('inbox.title') : title;
const displayDesc = isInbox ? t('inbox.desc') : description;
+1 -15
View File
@@ -14,11 +14,10 @@ import { sessionMetaSelectors } from '@/store/session/selectors';
import { useStyles } from '../style';
import Preview from './Preview';
import { FieldType, WidthMode } from './type';
import { FieldType } from './type';
const DEFAULT_FIELD_VALUE: FieldType = {
imageType: ImageType.JPG,
widthMode: WidthMode.Wide,
withBackground: true,
withFooter: true,
withPluginInfo: false,
@@ -35,20 +34,7 @@ const ShareImage = memo<{ mobile?: boolean }>(() => {
title: currentAgentTitle,
});
const { loading: copyLoading, onCopy } = useImgToClipboard();
const widthModeOptions = [
{ label: t('shareModal.widthMode.wide'), value: WidthMode.Wide },
{ label: t('shareModal.widthMode.narrow'), value: WidthMode.Narrow },
];
const settings: FormItemProps[] = [
{
children: <Segmented options={widthModeOptions} />,
label: t('shareModal.widthMode.label'),
layout: 'horizontal',
minWidth: undefined,
name: 'widthMode',
},
{
children: <Switch />,
label: t('shareModal.withSystemRole'),
@@ -1,13 +1,7 @@
import { ImageType } from '@/hooks/useScreenshot';
export enum WidthMode {
Narrow = 'narrow',
Wide = 'wide'
}
export type FieldType = {
imageType: ImageType;
widthMode: WidthMode;
withBackground: boolean;
withFooter: boolean;
withPluginInfo: boolean;
+26 -36
View File
@@ -1,46 +1,36 @@
import { createStyles } from 'antd-style';
import { WidthMode } from './ShareImage/type';
export const useContainerStyles = createStyles(({ css, token, stylish, cx, responsive }) => ({
preview: cx(
stylish.noScrollbar,
css`
overflow: hidden scroll;
export const useContainerStyles = createStyles(
({ css, token, stylish, cx, responsive }, widthMode?: WidthMode) => {
const isNarrow = widthMode === WidthMode.Narrow;
width: 100%;
max-height: 70dvh;
border: 1px solid ${token.colorBorder};
border-radius: ${token.borderRadiusLG}px;
return {
preview: cx(
stylish.noScrollbar,
css`
overflow: hidden scroll;
background: ${token.colorBgLayout};
width: 100%;
max-width: ${isNarrow ? '480px' : 'none'};
max-height: 70dvh;
margin: ${isNarrow ? '0 auto' : '0'};
border: 1px solid ${token.colorBorder};
border-radius: ${token.borderRadiusLG}px;
/* stylelint-disable selector-class-pattern */
.react-pdf__Document *,
.react-pdf__Page * {
pointer-events: none;
}
/* stylelint-enable selector-class-pattern */
background: ${token.colorBgLayout};
::-webkit-scrollbar {
width: 0 !important;
height: 0 !important;
}
/* stylelint-disable selector-class-pattern */
.react-pdf__Document *,
.react-pdf__Page * {
pointer-events: none;
}
/* stylelint-enable selector-class-pattern */
::-webkit-scrollbar {
width: 0 !important;
height: 0 !important;
}
${responsive.mobile} {
max-height: 40dvh;
}
`,
),
};
},
);
${responsive.mobile} {
max-height: 40dvh;
}
`,
),
}));
export const useStyles = createStyles(({ responsive, token, css }) => ({
body: css`
+1 -2
View File
@@ -15,7 +15,6 @@ import LangButton from './LangButton';
import ThemeButton from './ThemeButton';
import { useMenu } from './useMenu';
import { enableNextAuth } from '@/const/auth';
import { isDesktop } from '@/const/version';
const PanelContent = memo<{ closePopover: () => void }>(({ closePopover }) => {
const router = useRouter();
@@ -38,7 +37,7 @@ const PanelContent = memo<{ closePopover: () => void }>(({ closePopover }) => {
return (
<Flexbox gap={2} style={{ minWidth: 300 }}>
{isDesktop || isLoginWithAuth ? (
{isLoginWithAuth ? (
<>
<UserInfo avatarProps={{ clickable: false }} />
+28 -44
View File
@@ -1,6 +1,6 @@
import type { SegmentedProps } from '@lobehub/ui';
import { snapdom } from '@zumer/snapdom';
import dayjs from 'dayjs';
import { domToJpeg, domToPng, domToSvg, domToWebp } from 'modern-screenshot';
import { useCallback, useState } from 'react';
import { BRANDING_NAME } from '@/const/branding';
@@ -40,6 +40,26 @@ export const getImageUrl = async ({
imageType: ImageType;
width?: number;
}) => {
let screenshotFn: any;
switch (imageType) {
case ImageType.JPG: {
screenshotFn = domToJpeg;
break;
}
case ImageType.PNG: {
screenshotFn = domToPng;
break;
}
case ImageType.SVG: {
screenshotFn = domToSvg;
break;
}
case ImageType.WEBP: {
screenshotFn = domToWebp;
break;
}
}
const dom: HTMLDivElement = document.querySelector(id) as HTMLDivElement;
let copy: HTMLDivElement = dom;
@@ -49,54 +69,18 @@ export const getImageUrl = async ({
document.body.append(copy);
}
const baseOptions = {
const dataUrl = await screenshotFn(width ? copy : dom, {
features: {
// 不启用移除控制符,否则会导致 safari emoji 报错
removeControlCharacter: false,
},
scale: 2,
width,
};
let blob: Blob;
if (imageType === ImageType.SVG) {
// For SVG, we need to use the full snapdom API to get the raw SVG string
const result = await snapdom(width ? copy : dom, baseOptions);
const svgString = result.toRaw();
blob = new Blob([svgString], { type: 'image/svg+xml' });
} else {
// For raster formats, use toBlob directly with type option
const blobType = (imageType === ImageType.JPG ? 'jpg' : imageType) as 'png' | 'jpg' | 'webp';
const blobResult = await snapdom.toBlob(width ? copy : dom, {
type: blobType,
useProxy: 'https://proxy.corsfix.com/?',
});
if (!blobResult) {
throw new Error('Failed to generate blob from snapdom');
}
blob = blobResult;
}
});
if (width && copy) copy?.remove();
if (!blob) {
throw new Error('Blob is undefined');
}
// Convert blob to data URL using FileReader
return new Promise<string>((resolve, reject) => {
const reader = new FileReader();
reader.addEventListener('load', () => {
if (typeof reader.result === 'string') {
resolve(reader.result);
} else {
reject(new Error('FileReader result is not a string'));
}
});
reader.addEventListener('error', () =>
reject(reader.error || new Error('Failed to read blob as data URL')),
);
reader.readAsDataURL(blob);
});
return dataUrl;
};
export const useScreenshot = ({
@@ -63,11 +63,6 @@ const StoreInitialization = memo(() => {
// init user state
useInitUserState(isLoginOnInit, serverConfig, {
onError: () => {
// 即使失败也要设置标志,避免应用卡住
useGlobalStore.setState({ isAppHydrated: true });
console.warn('[Hydration] Client state initialization failed.');
},
onSuccess: (state) => {
// 设置水合完成标志
useGlobalStore.setState({ isAppHydrated: true });
@@ -77,6 +72,11 @@ const StoreInitialization = memo(() => {
router.push('/onboard');
}
},
onError: () => {
// 即使失败也要设置标志,避免应用卡住
useGlobalStore.setState({ isAppHydrated: true });
console.warn('[Hydration] Client state initialization failed.');
},
});
const useStoreUpdater = createStoreUpdater(useGlobalStore);
-5
View File
@@ -361,11 +361,6 @@ export default {
screenshot: '截图',
settings: '导出设置',
text: '文本',
widthMode: {
label: '宽度模式',
narrow: '窄屏模式',
wide: '宽屏模式',
},
withBackground: '包含背景图片',
withFooter: '包含页脚',
withPluginInfo: '包含插件信息',
-11
View File
@@ -15,12 +15,6 @@ export default {
prompt: '提示词',
},
localFiles: {
editFile: {
newString: '替换为',
oldString: '查找内容',
replaceAll: '替换全部匹配项',
replaceFirst: '仅替换第一个匹配项',
},
file: '文件',
folder: '文件夹',
moveFiles: {
@@ -41,11 +35,6 @@ export default {
readFileError: '读取文件失败,请检查文件路径是否正确',
readFiles: '读取文件',
readFilesError: '读取文件失败,请检查文件路径是否正确',
writeFile: {
characters: '字符',
preview: '内容预览',
truncated: '已截断',
},
},
search: {
createNewSearch: '创建新的搜索记录',
+2 -11
View File
@@ -77,21 +77,12 @@ export class MessageService {
return lambdaClient.message.getHeatmaps.query();
};
updateMessageError = async (
id: string,
value: ChatMessageError,
options?: { sessionId?: string | null; topicId?: string | null },
) => {
updateMessageError = async (id: string, value: ChatMessageError) => {
const error = value.type
? value
: { body: value, message: value.message, type: 'ApplicationRuntimeError' };
return lambdaClient.message.update.mutate({
id,
sessionId: options?.sessionId,
topicId: options?.topicId,
value: { error },
});
return lambdaClient.message.update.mutate({ id, value: { error } });
};
updateMessagePluginArguments = async (id: string, value: string | Record<string, any>) => {
+16 -31
View File
@@ -15,7 +15,6 @@ import type { ChatToolPayload, CreateMessageParams } from '@lobechat/types';
import debug from 'debug';
import pMap from 'p-map';
import { LOADING_FLAT } from '@/const/message';
import type { ChatStore } from '@/store/chat/store';
const log = debug('lobe-store:agent-executors');
@@ -37,9 +36,7 @@ export const createAgentExecutors = (context: {
inPortalThread?: boolean;
inSearchWorkflow?: boolean;
ragQuery?: string;
sessionId?: string;
threadId?: string;
topicId?: string | null;
traceId?: string;
};
parentId: string;
@@ -78,22 +75,16 @@ export const createAgentExecutors = (context: {
llmPayload.parentMessageId = context.parentId;
}
// Create assistant message (following server-side pattern)
const assistantMessageItem = await context.get().optimisticCreateMessage(
{
content: LOADING_FLAT,
model: llmPayload.model,
parentId: llmPayload.parentMessageId,
provider: llmPayload.provider,
role: 'assistant',
sessionId: state.metadata!.sessionId!,
threadId: state.metadata?.threadId,
topicId: state.metadata?.topicId,
},
{
sessionId: state.metadata!.sessionId!,
topicId: state.metadata?.topicId,
},
);
const assistantMessageItem = await context.get().optimisticCreateMessage({
content: '',
model: llmPayload.model,
parentId: llmPayload.parentMessageId,
provider: llmPayload.provider,
role: 'assistant',
sessionId: state.metadata!.sessionId!,
threadId: state.metadata?.threadId,
topicId: state.metadata?.topicId,
});
if (!assistantMessageItem) {
throw new Error('Failed to create assistant message');
@@ -278,16 +269,13 @@ export const createAgentExecutors = (context: {
parentId: payload.parentMessageId,
plugin: chatToolPayload,
role: 'tool',
sessionId: state.metadata!.sessionId!,
sessionId: context.get().activeId,
threadId: context.params.threadId,
tool_call_id: chatToolPayload.id,
topicId: state.metadata?.topicId,
topicId: context.get().activeTopicId,
};
const createResult = await context.get().optimisticCreateMessage(toolMessageParams, {
sessionId: state.metadata!.sessionId!,
topicId: state.metadata?.topicId,
});
const createResult = await context.get().optimisticCreateMessage(toolMessageParams);
if (!createResult) {
log(
@@ -462,16 +450,13 @@ export const createAgentExecutors = (context: {
},
pluginIntervention: { status: 'pending' },
role: 'tool',
sessionId: state.metadata!.sessionId!,
sessionId: context.get().activeId,
threadId: context.params.threadId,
tool_call_id: toolPayload.id,
topicId: state.metadata?.topicId,
topicId: context.get().activeTopicId,
};
const createResult = await context.get().optimisticCreateMessage(toolMessageParams, {
sessionId: state.metadata!.sessionId!,
topicId: state.metadata?.topicId,
});
const createResult = await context.get().optimisticCreateMessage(toolMessageParams);
if (!createResult) {
log(
@@ -82,10 +82,6 @@ describe('StreamingExecutor actions', () => {
expect(updateMessageErrorSpy).toHaveBeenCalledWith(
TEST_IDS.ASSISTANT_MESSAGE_ID,
expect.objectContaining({ type: 'InvalidProviderAPIKey' }),
expect.objectContaining({
sessionId: TEST_IDS.SESSION_ID,
topicId: undefined,
}),
);
streamSpy.mockRestore();
@@ -153,9 +149,6 @@ describe('StreamingExecutor actions', () => {
type: 'updateMessage',
value: expect.objectContaining({ content: 'Hello' }),
}),
expect.objectContaining({
sessionId: expect.any(String),
}),
);
streamSpy.mockRestore();
@@ -189,9 +182,6 @@ describe('StreamingExecutor actions', () => {
type: 'updateMessage',
value: expect.objectContaining({ reasoning: { content: 'Thinking...' } }),
}),
expect.objectContaining({
sessionId: expect.any(String),
}),
);
streamSpy.mockRestore();
@@ -268,9 +258,6 @@ describe('StreamingExecutor actions', () => {
}),
}),
}),
expect.objectContaining({
sessionId: expect.any(String),
}),
);
streamSpy.mockRestore();
@@ -309,9 +296,6 @@ describe('StreamingExecutor actions', () => {
imageList: expect.any(Array),
}),
}),
expect.objectContaining({
sessionId: expect.any(String),
}),
);
streamSpy.mockRestore();
@@ -368,10 +352,6 @@ describe('StreamingExecutor actions', () => {
expect(updateMessageSpy).toHaveBeenCalledWith(
TEST_IDS.ASSISTANT_MESSAGE_ID,
expect.objectContaining({ traceId }),
expect.objectContaining({
sessionId: expect.any(String),
topicId: undefined,
}),
);
streamSpy.mockRestore();
@@ -407,203 +387,5 @@ describe('StreamingExecutor actions', () => {
expect(streamSpy).toHaveBeenCalled();
expect(result.current.refreshMessages).toHaveBeenCalled();
});
it('should use provided sessionId/topicId for trace parameters', async () => {
act(() => {
useChatStore.setState({
internal_execAgentRuntime: realExecAgentRuntime,
activeId: 'active-session',
activeTopicId: 'active-topic',
});
});
const { result } = renderHook(() => useChatStore());
const contextSessionId = 'context-session';
const contextTopicId = 'context-topic';
const userMessage = {
id: TEST_IDS.USER_MESSAGE_ID,
role: 'user',
content: TEST_CONTENT.USER_MESSAGE,
sessionId: contextSessionId,
topicId: contextTopicId,
} as UIChatMessage;
const streamSpy = vi.spyOn(chatService, 'createAssistantMessageStream');
await act(async () => {
await result.current.internal_execAgentRuntime({
messages: [userMessage],
parentMessageId: userMessage.id,
parentMessageType: 'user',
sessionId: contextSessionId,
topicId: contextTopicId,
});
});
// Verify trace was called with context sessionId/topicId, not active ones
expect(streamSpy).toHaveBeenCalledWith(
expect.objectContaining({
trace: expect.objectContaining({
sessionId: contextSessionId,
topicId: contextTopicId,
}),
}),
);
});
// TODO: This test is complex to set up properly with agent runtime and message creation
// The functionality is verified in the implementation (streamingExecutor.ts:725-728)
it.skip('should pass context to optimisticUpdateMessageRAG', async () => {
act(() => {
useChatStore.setState({
internal_execAgentRuntime: realExecAgentRuntime,
activeId: 'active-session',
activeTopicId: 'active-topic',
});
});
const { result } = renderHook(() => useChatStore());
const contextSessionId = 'context-session';
const contextTopicId = 'context-topic';
const userMessage = {
id: TEST_IDS.USER_MESSAGE_ID,
role: 'user',
content: TEST_CONTENT.USER_MESSAGE,
sessionId: contextSessionId,
topicId: contextTopicId,
} as UIChatMessage;
const ragMetadata = {
ragQueryId: 'query-id',
fileChunks: [{ id: 'chunk-1', similarity: 0.9 }],
};
const assistantMessageId = 'assistant-msg-id';
const assistantMessage = {
id: assistantMessageId,
role: 'assistant',
content: TEST_CONTENT.AI_RESPONSE,
sessionId: contextSessionId,
topicId: contextTopicId,
} as UIChatMessage;
// Mock createMessage to return the assistant message
vi.spyOn(messageService, 'createMessage').mockResolvedValue({
id: assistantMessageId,
messages: [userMessage, assistantMessage],
});
const updateRAGSpy = vi.spyOn(result.current, 'optimisticUpdateMessageRAG');
const streamSpy = vi
.spyOn(chatService, 'createAssistantMessageStream')
.mockImplementation(async ({ onFinish }) => {
await onFinish?.(TEST_CONTENT.AI_RESPONSE, {});
});
await act(async () => {
await result.current.internal_execAgentRuntime({
messages: [userMessage],
parentMessageId: userMessage.id,
parentMessageType: 'user',
sessionId: contextSessionId,
topicId: contextTopicId,
ragMetadata,
});
});
// Verify optimisticUpdateMessageRAG was called with context
expect(updateRAGSpy).toHaveBeenCalledWith(expect.any(String), ragMetadata, {
sessionId: contextSessionId,
topicId: contextTopicId,
});
streamSpy.mockRestore();
});
});
describe('StreamingExecutor OptimisticUpdateContext isolation', () => {
it('should pass context to optimisticUpdateMessageContent in internal_fetchAIChatMessage', async () => {
const { result } = renderHook(() => useChatStore());
const messages = [createMockMessage({ role: 'user' })];
const contextSessionId = 'context-session';
const contextTopicId = 'context-topic';
const updateContentSpy = vi.spyOn(result.current, 'optimisticUpdateMessageContent');
const streamSpy = vi
.spyOn(chatService, 'createAssistantMessageStream')
.mockImplementation(async ({ onMessageHandle, onFinish }) => {
await onMessageHandle?.({ type: 'text', text: TEST_CONTENT.AI_RESPONSE } as any);
await onFinish?.(TEST_CONTENT.AI_RESPONSE, {});
});
await act(async () => {
await result.current.internal_fetchAIChatMessage({
messages,
messageId: TEST_IDS.ASSISTANT_MESSAGE_ID,
model: 'gpt-4o-mini',
provider: 'openai',
params: {
sessionId: contextSessionId,
topicId: contextTopicId,
},
});
});
expect(updateContentSpy).toHaveBeenCalledWith(
TEST_IDS.ASSISTANT_MESSAGE_ID,
TEST_CONTENT.AI_RESPONSE,
expect.any(Object),
{
sessionId: contextSessionId,
topicId: contextTopicId,
},
);
streamSpy.mockRestore();
});
it('should use activeId/activeTopicId when context not provided', async () => {
act(() => {
useChatStore.setState({
activeId: 'active-session',
activeTopicId: 'active-topic',
});
});
const { result } = renderHook(() => useChatStore());
const messages = [createMockMessage({ role: 'user' })];
const updateContentSpy = vi.spyOn(result.current, 'optimisticUpdateMessageContent');
const streamSpy = vi
.spyOn(chatService, 'createAssistantMessageStream')
.mockImplementation(async ({ onMessageHandle, onFinish }) => {
await onMessageHandle?.({ type: 'text', text: TEST_CONTENT.AI_RESPONSE } as any);
await onFinish?.(TEST_CONTENT.AI_RESPONSE, {});
});
await act(async () => {
await result.current.internal_fetchAIChatMessage({
messages,
messageId: TEST_IDS.ASSISTANT_MESSAGE_ID,
model: 'gpt-4o-mini',
provider: 'openai',
});
});
expect(updateContentSpy).toHaveBeenCalledWith(
TEST_IDS.ASSISTANT_MESSAGE_ID,
TEST_CONTENT.AI_RESPONSE,
expect.any(Object),
{
sessionId: 'active-session',
topicId: undefined,
},
);
streamSpy.mockRestore();
});
});
});
@@ -183,8 +183,6 @@ export const conversationControl: StateCreator<
messages: currentMessages,
parentMessageId: toolMessageId, // Start from tool message
parentMessageType: 'tool', // Type is 'tool'
sessionId: get().activeId,
topicId: get().activeTopicId,
threadId: activeThreadId,
initialState: state,
initialContext: context,
@@ -241,8 +239,6 @@ export const conversationControl: StateCreator<
messages: currentMessages,
parentMessageId: messageId,
parentMessageType: 'tool',
sessionId: get().activeId,
topicId: get().activeTopicId,
threadId: activeThreadId,
initialState: state,
initialContext: context,
@@ -124,7 +124,7 @@ export const conversationLifecycle: StateCreator<
imageList: tempImages.length > 0 ? tempImages : undefined,
videoList: tempVideos.length > 0 ? tempVideos : undefined,
});
const tempAssistantId = get().optimisticCreateTmpMessage({
get().optimisticCreateTmpMessage({
content: LOADING_FLAT,
role: 'assistant',
sessionId: activeId,
@@ -159,7 +159,7 @@ export const conversationLifecycle: StateCreator<
newTopic: shouldCreateNewTopic
? {
topicMessageIds: messages.map((m) => m.id),
title: message.slice(0, 10) || t('defaultTitle', { ns: 'topic' }),
title: t('defaultTitle', { ns: 'topic' }),
}
: undefined,
sessionId: activeId === INBOX_SESSION_ID ? undefined : activeId,
@@ -200,7 +200,7 @@ export const conversationLifecycle: StateCreator<
// remove temporally message
if (data?.isCreateNewTopic) {
get().internal_dispatchMessage(
{ type: 'deleteMessages', ids: [tempId, tempAssistantId] },
{ type: 'deleteMessage', id: tempId },
{ topicId: activeTopicId, sessionId: activeId },
);
}
@@ -249,8 +249,6 @@ export const conversationLifecycle: StateCreator<
messages: displayMessages,
parentMessageId: data.assistantMessageId,
parentMessageType: 'assistant',
sessionId: activeId,
topicId: data.topicId ?? activeTopicId,
ragQuery: get().internal_shouldUseRAG() ? message : undefined,
threadId: activeThreadId,
skipCreateFirstMessage: true,
@@ -307,8 +305,6 @@ export const conversationLifecycle: StateCreator<
messages: contextMessages,
parentMessageId: id,
parentMessageType: 'user',
sessionId: get().activeId,
topicId: get().activeTopicId,
traceId,
ragQuery: get().internal_shouldUseRAG() ? item.content : undefined,
threadId: activeThreadId,
@@ -364,8 +360,6 @@ export const conversationLifecycle: StateCreator<
messages: chats,
parentMessageId: id,
parentMessageType: message.role as 'assistant' | 'tool' | 'user',
sessionId: get().activeId,
topicId: get().activeTopicId,
});
} finally {
// Remove message from continuing state
@@ -50,15 +50,6 @@ interface ProcessMessageParams {
groupId?: string;
agentId?: string;
agentConfig?: any; // Agent configuration for group chat agents
/**
* Explicit sessionId for this execution (avoids using global activeId)
*/
sessionId?: string;
/**
* Explicit topicId for this execution (avoids using global activeTopicId)
*/
topicId?: string | null;
}
/**
@@ -71,14 +62,6 @@ export interface StreamingExecutorAction {
internal_createAgentState: (params: {
messages: UIChatMessage[];
parentMessageId: string;
/**
* Explicit sessionId for this execution (avoids using global activeId)
*/
sessionId?: string;
/**
* Explicit topicId for this execution (avoids using global activeTopicId)
*/
topicId?: string | null;
threadId?: string;
initialState?: AgentState;
initialContext?: AgentRuntimeContext;
@@ -111,14 +94,6 @@ export interface StreamingExecutorAction {
messages: UIChatMessage[];
parentMessageId: string;
parentMessageType: 'user' | 'assistant' | 'tool';
/**
* Explicit sessionId for this execution (avoids using global activeId)
*/
sessionId?: string;
/**
* Explicit topicId for this execution (avoids using global activeTopicId)
*/
topicId?: string | null;
inSearchWorkflow?: boolean;
/**
* the RAG query content, should be embedding and used in the semantic search
@@ -149,17 +124,11 @@ export const streamingExecutor: StateCreator<
internal_createAgentState: ({
messages,
parentMessageId,
sessionId: paramSessionId,
topicId: paramTopicId,
threadId,
initialState,
initialContext,
}) => {
// Use provided sessionId/topicId or fallback to global state
const { activeId, activeTopicId } = get();
const sessionId = paramSessionId ?? activeId;
const topicId = paramTopicId !== undefined ? paramTopicId : activeTopicId;
const agentStoreState = getAgentStoreState();
const agentConfigData = agentSelectors.currentAgentConfig(agentStoreState);
@@ -188,12 +157,12 @@ export const streamingExecutor: StateCreator<
const state =
initialState ||
AgentRuntime.createInitialState({
sessionId,
sessionId: activeId,
messages,
maxSteps: 400,
metadata: {
sessionId,
topicId,
sessionId: activeId,
topicId: activeTopicId,
threadId,
},
toolManifestMap,
@@ -209,7 +178,7 @@ export const streamingExecutor: StateCreator<
parentMessageId,
},
session: {
sessionId,
sessionId: activeId,
messageCount: messages.length,
status: state.status,
stepCount: 0,
@@ -264,21 +233,14 @@ export const streamingExecutor: StateCreator<
// to upload image
const uploadTasks: Map<string, Promise<{ id?: string; url?: string }>> = new Map();
const context: { sessionId: string; topicId?: string | null } = {
sessionId: params?.sessionId || get().activeId,
topicId: params?.topicId,
};
// Throttle tool_calls updates to prevent excessive re-renders (max once per 300ms)
const throttledUpdateToolCalls = throttle(
(toolCalls: any[]) => {
internal_dispatchMessage(
{
id: messageId,
type: 'updateMessage',
value: { tools: get().internal_transformToolCalls(toolCalls) },
},
context,
);
internal_dispatchMessage({
id: messageId,
type: 'updateMessage',
value: { tools: get().internal_transformToolCalls(toolCalls) },
});
},
300,
{ leading: true, trailing: true },
@@ -299,14 +261,13 @@ export const streamingExecutor: StateCreator<
historySummary: historySummary?.content,
trace: {
traceId: params?.traceId,
sessionId: params?.sessionId ?? get().activeId,
topicId:
(params?.topicId !== undefined ? params.topicId : get().activeTopicId) ?? undefined,
sessionId: get().activeId,
topicId: get().activeTopicId,
traceName: TraceNameMap.Conversation,
},
onErrorHandle: async (error) => {
await messageService.updateMessageError(messageId, error, context);
await refreshMessages(params?.sessionId, params?.topicId);
await messageService.updateMessageError(messageId, error);
await refreshMessages();
},
onFinish: async (
content,
@@ -315,11 +276,10 @@ export const streamingExecutor: StateCreator<
// if there is traceId, update it
if (traceId) {
msgTraceId = traceId;
messageService.updateMessage(
messageId,
{ traceId, observationId: observationId ?? undefined },
context,
);
messageService.updateMessage(messageId, {
traceId,
observationId: observationId ?? undefined,
});
}
// 等待所有图片上传完成
@@ -361,20 +321,15 @@ export const streamingExecutor: StateCreator<
internal_toggleChatReasoning(false, messageId, n('toggleChatReasoning/false') as string);
// update the content after fetch result
await optimisticUpdateMessageContent(
messageId,
content,
{
toolCalls: parsedToolCalls,
reasoning: !!reasoning
? { ...reasoning, duration: duration && !isNaN(duration) ? duration : undefined }
: undefined,
search: !!grounding?.citations ? grounding : undefined,
imageList: finalImages.length > 0 ? finalImages : undefined,
metadata: speed ? { ...usage, ...speed } : usage,
},
context,
);
await optimisticUpdateMessageContent(messageId, content, {
toolCalls: parsedToolCalls,
reasoning: !!reasoning
? { ...reasoning, duration: duration && !isNaN(duration) ? duration : undefined }
: undefined,
search: !!grounding?.citations ? grounding : undefined,
imageList: finalImages.length > 0 ? finalImages : undefined,
metadata: speed ? { ...usage, ...speed } : usage,
});
},
onMessageHandle: async (chunk) => {
switch (chunk.type) {
@@ -387,33 +342,27 @@ export const streamingExecutor: StateCreator<
)
return;
internal_dispatchMessage(
{
id: messageId,
type: 'updateMessage',
value: {
search: {
citations: chunk.grounding.citations,
searchQueries: chunk.grounding.searchQueries,
},
internal_dispatchMessage({
id: messageId,
type: 'updateMessage',
value: {
search: {
citations: chunk.grounding.citations,
searchQueries: chunk.grounding.searchQueries,
},
},
context,
);
});
break;
}
case 'base64_image': {
internal_dispatchMessage(
{
id: messageId,
type: 'updateMessage',
value: {
imageList: chunk.images.map((i) => ({ id: i.id, url: i.data, alt: i.id })),
},
internal_dispatchMessage({
id: messageId,
type: 'updateMessage',
value: {
imageList: chunk.images.map((i) => ({ id: i.id, url: i.data, alt: i.id })),
},
context,
);
});
const image = chunk.image;
const task = getFileStoreState()
@@ -446,17 +395,14 @@ export const streamingExecutor: StateCreator<
}
}
internal_dispatchMessage(
{
id: messageId,
type: 'updateMessage',
value: {
content: output,
reasoning: !!thinking ? { content: thinking, duration } : undefined,
},
internal_dispatchMessage({
id: messageId,
type: 'updateMessage',
value: {
content: output,
reasoning: !!thinking ? { content: thinking, duration } : undefined,
},
context,
);
});
break;
}
@@ -473,14 +419,11 @@ export const streamingExecutor: StateCreator<
thinking += chunk.text;
internal_dispatchMessage(
{
id: messageId,
type: 'updateMessage',
value: { reasoning: { content: thinking } },
},
context,
);
internal_dispatchMessage({
id: messageId,
type: 'updateMessage',
value: { reasoning: { content: thinking } },
});
break;
}
@@ -519,30 +462,18 @@ export const streamingExecutor: StateCreator<
},
internal_execAgentRuntime: async (params) => {
const {
messages: originalMessages,
parentMessageId,
parentMessageType,
sessionId: paramSessionId,
topicId: paramTopicId,
} = params;
// Use provided sessionId/topicId or fallback to global state
const { activeId, activeTopicId } = get();
const sessionId = paramSessionId ?? activeId;
const topicId = paramTopicId !== undefined ? paramTopicId : activeTopicId;
const messageKey = messageMapKey(sessionId, topicId);
const { messages: originalMessages, parentMessageId, parentMessageType } = params;
log(
'[internal_execAgentRuntime] start, sessionId: %s, topicId: %s, messageKey: %s, parentMessageId: %s, parentMessageType: %s, messages count: %d',
sessionId,
topicId,
messageKey,
'[internal_execAgentRuntime] start, parentMessageId: %s,parentMessageType: %s, messages count: %d',
parentMessageId,
parentMessageType,
originalMessages.length,
);
const { activeId, activeTopicId } = get();
const messageKey = messageMapKey(activeId, activeTopicId);
// Create a new array to avoid modifying the original messages
let messages = [...originalMessages];
@@ -625,11 +556,7 @@ export const streamingExecutor: StateCreator<
get,
messageKey,
parentId: params.parentMessageId,
params: {
...params,
sessionId,
topicId,
},
params,
skipCreateFirstMessage: params.skipCreateFirstMessage,
}),
});
@@ -639,8 +566,6 @@ export const streamingExecutor: StateCreator<
get().internal_createAgentState({
messages,
parentMessageId: params.parentMessageId,
sessionId,
topicId,
threadId: params.threadId,
initialState: params.initialState,
initialContext: params.initialContext,
@@ -688,13 +613,10 @@ export const streamingExecutor: StateCreator<
const currentMessages = get().messagesMap[messageKey] || [];
const assistantMessage = currentMessages.findLast((m) => m.role === 'assistant');
if (assistantMessage) {
await messageService.updateMessageError(assistantMessage.id, event.error, {
sessionId,
topicId,
});
await messageService.updateMessageError(assistantMessage.id, event.error);
}
const finalMessages = get().messagesMap[messageKey] || [];
get().replaceMessages(finalMessages, { sessionId, topicId });
get().replaceMessages(finalMessages);
break;
}
}
@@ -722,10 +644,7 @@ export const streamingExecutor: StateCreator<
const finalMessages = get().messagesMap[messageKey] || [];
const assistantMessage = finalMessages.findLast((m) => m.role === 'assistant');
if (assistantMessage) {
await get().optimisticUpdateMessageRAG(assistantMessage.id, params.ragMetadata, {
sessionId,
topicId,
});
await get().optimisticUpdateMessageRAG(assistantMessage.id, params.ragMetadata);
log('[internal_execAgentRuntime] RAG metadata updated for assistant message');
}
}
@@ -50,17 +50,18 @@ describe('localFileSlice', () => {
describe('internal_triggerLocalFileToolCalling', () => {
it('should handle successful calling', async () => {
const mockContent = 'result content';
const mockContent = { foo: 'bar' };
const mockState = { state: 'test' };
const mockService = vi
.fn()
.mockResolvedValue({ content: mockContent, state: mockState, success: true });
const mockService = vi.fn().mockResolvedValue({ content: mockContent, state: mockState });
await store.internal_triggerLocalFileToolCalling('test-id', mockService);
expect(mockStore.toggleLocalFileLoading).toBeCalledWith('test-id', true);
expect(mockStore.optimisticUpdatePluginState).toBeCalledWith('test-id', mockState);
expect(mockStore.optimisticUpdateMessageContent).toBeCalledWith('test-id', mockContent);
expect(mockStore.optimisticUpdateMessageContent).toBeCalledWith(
'test-id',
JSON.stringify(mockContent),
);
expect(mockStore.toggleLocalFileLoading).toBeCalledWith('test-id', false);
});
@@ -6,7 +6,7 @@ import { Mock, beforeEach, describe, expect, it, vi } from 'vitest';
import { searchService } from '@/services/search';
import { useChatStore } from '@/store/chat';
import { dbMessageSelectors } from '@/store/chat/selectors';
import { chatSelectors } from '@/store/chat/selectors';
import { CRAWL_CONTENT_LIMITED_COUNT } from '@/tools/web-browsing/const';
// Mock services
@@ -18,8 +18,8 @@ vi.mock('@/services/search', () => ({
}));
vi.mock('@/store/chat/selectors', () => ({
dbMessageSelectors: {
getDbMessageById: vi.fn(),
chatSelectors: {
getMessageById: vi.fn(),
},
}));
@@ -38,9 +38,6 @@ describe('search actions', () => {
optimisticAddToolToAssistantMessage: vi.fn(),
openToolUI: vi.fn(),
});
// Default mock for dbMessageSelectors - returns undefined to use activeId/activeTopicId
vi.spyOn(dbMessageSelectors, 'getDbMessageById').mockImplementation(() => () => undefined);
});
describe('search', () => {
@@ -93,8 +90,6 @@ describe('search actions', () => {
expect(result.current.optimisticUpdateMessageContent).toHaveBeenCalledWith(
messageId,
searchResultsPrompt(expectedContent),
undefined,
{ sessionId: undefined, topicId: undefined },
);
});
@@ -131,8 +126,6 @@ describe('search actions', () => {
expect(result.current.optimisticUpdateMessageContent).toHaveBeenCalledWith(
messageId,
searchResultsPrompt([]),
undefined,
{ sessionId: undefined, topicId: undefined },
);
});
@@ -152,21 +145,15 @@ describe('search actions', () => {
await search(messageId, query);
});
expect(result.current.optimisticUpdateMessagePluginError).toHaveBeenCalledWith(
messageId,
{
body: error,
message: 'Search failed',
type: 'PluginServerError',
},
{ sessionId: undefined, topicId: undefined },
);
expect(result.current.optimisticUpdateMessagePluginError).toHaveBeenCalledWith(messageId, {
body: error,
message: 'Search failed',
type: 'PluginServerError',
});
expect(result.current.searchLoading[messageId]).toBe(false);
expect(result.current.optimisticUpdateMessageContent).toHaveBeenCalledWith(
messageId,
'Search failed',
undefined,
{ sessionId: undefined, topicId: undefined },
);
});
});
@@ -206,8 +193,6 @@ describe('search actions', () => {
expect(result.current.optimisticUpdateMessageContent).toHaveBeenCalledWith(
messageId,
crawlResultsPrompt(expectedContent as any),
undefined,
{ sessionId: undefined, topicId: undefined },
);
});
@@ -234,8 +219,6 @@ describe('search actions', () => {
expect(result.current.optimisticUpdateMessageContent).toHaveBeenCalledWith(
messageId,
crawlResultsPrompt(mockResponse.results),
undefined,
{ sessionId: undefined, topicId: undefined },
);
});
});
@@ -267,8 +250,6 @@ describe('search actions', () => {
const mockMessage: Partial<UIChatMessage> = {
id: messageId,
parentId,
sessionId: undefined,
topicId: undefined,
content: 'test content',
plugin: {
identifier: 'search',
@@ -283,7 +264,7 @@ describe('search actions', () => {
meta: {},
};
vi.spyOn(dbMessageSelectors, 'getDbMessageById').mockImplementation(
vi.spyOn(chatSelectors, 'getMessageById').mockImplementation(
() => () => mockMessage as UIChatMessage,
);
@@ -301,10 +282,7 @@ describe('search actions', () => {
plugin: mockMessage.plugin,
pluginState: mockMessage.pluginState,
role: 'tool',
sessionId: 'session-id',
topicId: 'topic-id',
}),
{ sessionId: 'session-id', topicId: 'topic-id' },
);
expect(result.current.optimisticAddToolToAssistantMessage).toHaveBeenCalledWith(
@@ -313,12 +291,11 @@ describe('search actions', () => {
identifier: 'search',
type: 'default',
}),
{ sessionId: undefined, topicId: undefined },
);
});
it('should not save if message not found', async () => {
vi.spyOn(dbMessageSelectors, 'getDbMessageById').mockImplementation(() => () => undefined);
vi.spyOn(chatSelectors, 'getMessageById').mockImplementation(() => () => undefined);
const { result } = renderHook(() => useChatStore());
const { saveSearchResult } = result.current;
@@ -350,175 +327,4 @@ describe('search actions', () => {
expect(result.current.searchLoading[messageId]).toBe(false);
});
});
describe('OptimisticUpdateContext isolation', () => {
it('search should pass context to optimistic methods', async () => {
const mockResponse: UniformSearchResponse = {
results: [
{
title: 'Test',
content: 'Content',
url: 'https://test.com',
category: 'general',
engines: ['google'],
parsedUrl: 'test.com',
score: 1,
},
],
costTime: 1,
resultNumbers: 1,
query: 'test',
};
(searchService.webSearch as Mock).mockResolvedValue(mockResponse);
const messageId = 'test-message-id';
const contextSessionId = 'context-session-id';
const contextTopicId = 'context-topic-id';
const mockMessage: Partial<UIChatMessage> = {
id: messageId,
sessionId: contextSessionId,
topicId: contextTopicId,
role: 'tool',
content: '',
createdAt: Date.now(),
updatedAt: Date.now(),
meta: {},
};
vi.spyOn(dbMessageSelectors, 'getDbMessageById').mockImplementation(
() => () => mockMessage as UIChatMessage,
);
const { result } = renderHook(() => useChatStore());
const query: SearchQuery = { query: 'test' };
await act(async () => {
await result.current.search(messageId, query);
});
expect(result.current.optimisticUpdatePluginState).toHaveBeenCalledWith(
messageId,
expect.any(Object),
{ sessionId: contextSessionId, topicId: contextTopicId },
);
expect(result.current.optimisticUpdateMessageContent).toHaveBeenCalledWith(
messageId,
expect.any(String),
undefined,
{ sessionId: contextSessionId, topicId: contextTopicId },
);
});
it('crawlMultiPages should pass context to optimistic methods', async () => {
const mockResponse = {
results: [
{
data: {
content: 'Test content',
title: 'Test',
},
crawler: 'naive',
originalUrl: 'https://test.com',
},
],
};
(searchService.crawlPages as Mock).mockResolvedValue(mockResponse);
const messageId = 'test-message-id';
const contextSessionId = 'context-session-id';
const contextTopicId = 'context-topic-id';
const mockMessage: Partial<UIChatMessage> = {
id: messageId,
sessionId: contextSessionId,
topicId: contextTopicId,
role: 'tool',
content: '',
createdAt: Date.now(),
updatedAt: Date.now(),
meta: {},
};
vi.spyOn(dbMessageSelectors, 'getDbMessageById').mockImplementation(
() => () => mockMessage as UIChatMessage,
);
const { result } = renderHook(() => useChatStore());
await act(async () => {
await result.current.crawlMultiPages(messageId, { urls: ['https://test.com'] });
});
expect(result.current.optimisticUpdateMessageContent).toHaveBeenCalledWith(
messageId,
expect.any(String),
undefined,
{ sessionId: contextSessionId, topicId: contextTopicId },
);
expect(result.current.optimisticUpdatePluginState).toHaveBeenCalledWith(
messageId,
expect.any(Object),
{ sessionId: contextSessionId, topicId: contextTopicId },
);
});
it('saveSearchResult should pass context to optimistic methods', async () => {
const messageId = 'test-message-id';
const parentId = 'parent-message-id';
const contextSessionId = 'context-session-id';
const contextTopicId = 'context-topic-id';
const mockMessage: Partial<UIChatMessage> = {
id: messageId,
parentId,
sessionId: contextSessionId,
topicId: contextTopicId,
content: 'test content',
plugin: {
identifier: 'search',
arguments: '{}',
apiName: 'search',
type: 'default',
},
pluginState: {},
role: 'tool',
createdAt: Date.now(),
updatedAt: Date.now(),
meta: {},
};
vi.spyOn(dbMessageSelectors, 'getDbMessageById').mockImplementation(
() => () => mockMessage as UIChatMessage,
);
(useChatStore.getState().optimisticCreateMessage as Mock).mockResolvedValue({
id: 'new-message-id',
});
const { result } = renderHook(() => useChatStore());
await act(async () => {
await result.current.saveSearchResult(messageId);
});
expect(result.current.optimisticAddToolToAssistantMessage).toHaveBeenCalledWith(
parentId,
expect.objectContaining({
identifier: 'search',
type: 'default',
}),
{ sessionId: contextSessionId, topicId: contextTopicId },
);
expect(result.current.optimisticCreateMessage).toHaveBeenCalledWith(
expect.objectContaining({
sessionId: contextSessionId,
topicId: contextTopicId,
}),
{ sessionId: contextSessionId, topicId: contextTopicId },
);
});
});
});

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