@lobehub/chat 1.132.15 → 1.132.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/rules/group-chat.mdc +35 -0
- package/CHANGELOG.md +25 -0
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/changelog/v1.json +9 -0
- package/docs/development/database-schema.dbml +2 -1
- package/package.json +4 -3
- package/packages/const/src/meta.ts +2 -0
- package/packages/const/src/plugin.ts +5 -1
- package/packages/const/src/session.ts +19 -2
- package/packages/const/src/settings/group.ts +30 -0
- package/packages/const/src/settings/index.ts +1 -0
- package/packages/const/src/utils/merge.ts +62 -0
- package/packages/database/migrations/0034_fix_chat_group.sql +4 -0
- package/packages/database/migrations/meta/0034_snapshot.json +6609 -0
- package/packages/database/migrations/meta/_journal.json +8 -1
- package/packages/database/src/core/migrations.json +11 -0
- package/packages/database/src/schemas/chatGroup.ts +6 -8
- package/packages/database/src/schemas/message.ts +2 -1
- package/packages/database/src/types/chatGroup.ts +4 -1
- package/packages/model-runtime/src/core/openaiCompatibleFactory/index.ts +7 -3
- package/packages/model-runtime/src/providers/google/generateObject.ts +26 -1
- package/packages/model-runtime/src/providers/qwen/createImage.test.ts +162 -0
- package/packages/model-runtime/src/providers/qwen/createImage.ts +16 -9
- package/packages/types/src/agent/index.ts +2 -72
- package/packages/types/src/agent/item.ts +85 -0
- package/packages/types/src/agent/tts.ts +12 -0
- package/packages/types/src/apiKey.ts +13 -1
- package/packages/types/src/chatGroup/index.ts +47 -0
- package/packages/types/src/fetch.ts +2 -0
- package/packages/types/src/index.ts +1 -0
- package/packages/types/src/message/chat.ts +54 -1
- package/packages/types/src/message/index.ts +0 -27
- package/packages/types/src/openai/chat.ts +22 -0
- package/packages/types/src/session/agentSession.ts +24 -5
- package/packages/types/src/session/index.ts +2 -2
- package/packages/types/src/session/sessionGroup.ts +2 -0
- package/packages/utils/src/fetch/fetchSSE.ts +2 -4
- package/src/app/[variants]/(main)/settings/provider/ProviderMenu/Item.tsx +5 -3
- package/src/app/[variants]/oauth/consent/[uid]/Consent.tsx +64 -84
- package/src/services/session/client.ts +2 -2
- package/src/services/topic/pglite.test.ts +1 -1
- /package/packages/database/migrations/{0033_modern_mercury.sql → 0033_add_table_index.sql} +0 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Explain how group chat works in LobeHub (Multi-agent orchestratoin)
|
|
3
|
+
globs:
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
This rule explains how group chat (multi-agent orchestration) works. Not confused with session group, which is a organization method to manage session.
|
|
8
|
+
|
|
9
|
+
## Key points
|
|
10
|
+
|
|
11
|
+
- A supervisor will devide who and how will speak next
|
|
12
|
+
- Each agent will speak just like in single chat (if was asked to speak)
|
|
13
|
+
- Not coufused with session group
|
|
14
|
+
|
|
15
|
+
## Related Files
|
|
16
|
+
|
|
17
|
+
- src/store/chat/slices/message/supervisor.ts
|
|
18
|
+
- src/store/chat/slices/aiChat/actions/generateAIGroupChat.ts
|
|
19
|
+
- src/prompts/groupChat/index.ts (All prompts here)
|
|
20
|
+
|
|
21
|
+
## Snippets
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
// Detect whether in group chat
|
|
25
|
+
const isGroupSession = useSessionStore(sessionSelectors.isCurrentSessionGroupSession);
|
|
26
|
+
|
|
27
|
+
// Member actions
|
|
28
|
+
const addAgentsToGroup = useChatGroupStore((s) => s.addAgentsToGroup);
|
|
29
|
+
const removeAgentFromGroup = useChatGroupStore((s) => s.removeAgentFromGroup);
|
|
30
|
+
const persistReorder = useChatGroupStore((s) => s.reorderGroupMembers);
|
|
31
|
+
|
|
32
|
+
// Get group info
|
|
33
|
+
const groupConfig = useChatGroupStore(chatGroupSelectors.currentGroupConfig);
|
|
34
|
+
const currentGroupMemebers = useSessionStore(sessionSelectors.currentGroupAgents);
|
|
35
|
+
```
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
### [Version 1.132.16](https://github.com/lobehub/lobe-chat/compare/v1.132.15...v1.132.16)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2025-09-26**</sup>
|
|
8
|
+
|
|
9
|
+
#### 🐛 Bug Fixes
|
|
10
|
+
|
|
11
|
+
- **misc**: Resolve qwen-image-edit imageUrls conversion issue.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### What's fixed
|
|
19
|
+
|
|
20
|
+
- **misc**: Resolve qwen-image-edit imageUrls conversion issue, closes [#9414](https://github.com/lobehub/lobe-chat/issues/9414) ([ec5af1b](https://github.com/lobehub/lobe-chat/commit/ec5af1b))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
5
30
|
### [Version 1.132.15](https://github.com/lobehub/lobe-chat/compare/v1.132.14...v1.132.15)
|
|
6
31
|
|
|
7
32
|
<sup>Released on **2025-09-25**</sup>
|
package/README.md
CHANGED
|
@@ -819,7 +819,7 @@ Every bit counts and your one-time donation sparkles in our galaxy of support! Y
|
|
|
819
819
|
</details>
|
|
820
820
|
|
|
821
821
|
Copyright © 2025 [LobeHub][profile-link]. <br />
|
|
822
|
-
This project is [
|
|
822
|
+
This project is [LobeHub Community License](./LICENSE) licensed.
|
|
823
823
|
|
|
824
824
|
<!-- LINK GROUP -->
|
|
825
825
|
|
package/README.zh-CN.md
CHANGED
package/changelog/v1.json
CHANGED
|
@@ -138,6 +138,7 @@ table chat_groups {
|
|
|
138
138
|
config jsonb
|
|
139
139
|
client_id text
|
|
140
140
|
user_id text [not null]
|
|
141
|
+
group_id text
|
|
141
142
|
pinned boolean [default: false]
|
|
142
143
|
accessed_at "timestamp with time zone" [not null, default: `now()`]
|
|
143
144
|
created_at "timestamp with time zone" [not null, default: `now()`]
|
|
@@ -387,7 +388,7 @@ table message_translates {
|
|
|
387
388
|
|
|
388
389
|
table messages {
|
|
389
390
|
id text [pk, not null]
|
|
390
|
-
role
|
|
391
|
+
role varchar(255) [not null]
|
|
391
392
|
content text
|
|
392
393
|
reasoning jsonb
|
|
393
394
|
search jsonb
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "1.132.
|
|
3
|
+
"version": "1.132.16",
|
|
4
4
|
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework",
|
|
@@ -159,11 +159,11 @@
|
|
|
159
159
|
"@lobehub/charts": "^2.1.2",
|
|
160
160
|
"@lobehub/chat-plugin-sdk": "^1.32.4",
|
|
161
161
|
"@lobehub/chat-plugins-gateway": "^1.9.0",
|
|
162
|
-
"@lobehub/editor": "^1.
|
|
162
|
+
"@lobehub/editor": "^1.11.0",
|
|
163
163
|
"@lobehub/icons": "^2.32.2",
|
|
164
164
|
"@lobehub/market-sdk": "^0.22.7",
|
|
165
165
|
"@lobehub/tts": "^2.0.1",
|
|
166
|
-
"@lobehub/ui": "^2.
|
|
166
|
+
"@lobehub/ui": "^2.13.0",
|
|
167
167
|
"@modelcontextprotocol/sdk": "^1.18.0",
|
|
168
168
|
"@neondatabase/serverless": "^1.0.1",
|
|
169
169
|
"@next/third-parties": "^15.5.3",
|
|
@@ -344,6 +344,7 @@
|
|
|
344
344
|
"glob": "^11.0.3",
|
|
345
345
|
"happy-dom": "^18.0.1",
|
|
346
346
|
"husky": "^9.1.7",
|
|
347
|
+
"import-in-the-middle": "^1.14.2",
|
|
347
348
|
"just-diff": "^6.0.2",
|
|
348
349
|
"lint-staged": "^15.5.2",
|
|
349
350
|
"lodash": "^4.17.21",
|
|
@@ -4,6 +4,8 @@ import { BRANDING_LOGO_URL } from './branding';
|
|
|
4
4
|
|
|
5
5
|
export const DEFAULT_AVATAR = '🤖';
|
|
6
6
|
export const DEFAULT_USER_AVATAR = '😀';
|
|
7
|
+
export const DEFAULT_SUPERVISOR_AVATAR = '🎙️';
|
|
8
|
+
export const DEFAULT_SUPERVISOR_ID = 'supervisor';
|
|
7
9
|
export const DEFAULT_BACKGROUND_COLOR = 'rgba(0,0,0,0)';
|
|
8
10
|
export const DEFAULT_AGENT_META: MetaData = {};
|
|
9
11
|
export const DEFAULT_INBOX_AVATAR = BRANDING_LOGO_URL || '🤯';
|
|
@@ -3,7 +3,9 @@ export const PLUGIN_SCHEMA_API_MD5_PREFIX = 'MD5HASH_';
|
|
|
3
3
|
|
|
4
4
|
export const ARTIFACT_TAG = 'lobeArtifact';
|
|
5
5
|
export const ARTIFACT_THINKING_TAG = 'lobeThinking';
|
|
6
|
-
|
|
6
|
+
export const MENTION_TAG = 'mention';
|
|
7
|
+
export const THINKING_TAG = 'think';
|
|
8
|
+
export const LOCAL_FILE_TAG = 'localFile';
|
|
7
9
|
// https://regex101.com/r/TwzTkf/2
|
|
8
10
|
export const ARTIFACT_TAG_REGEX = /<lobeArtifact\b[^>]*>(?<content>[\S\s]*?)(?:<\/lobeArtifact>|$)/;
|
|
9
11
|
|
|
@@ -14,3 +16,5 @@ export const ARTIFACT_TAG_CLOSED_REGEX = /<lobeArtifact\b[^>]*>([\S\s]*?)<\/lobe
|
|
|
14
16
|
export const ARTIFACT_THINKING_TAG_REGEX = /<lobeThinking\b[^>]*>([\S\s]*?)(?:<\/lobeThinking>|$)/;
|
|
15
17
|
|
|
16
18
|
export const THINKING_TAG_REGEX = /<think\b[^>]*>([\S\s]*?)(?:<\/think>|$)/;
|
|
19
|
+
|
|
20
|
+
export const MENTION_TAG_REGEX = /<mention\b[^>]*>([\S\s]*?)(?:<\/mention>|$)/;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { LobeAgentSession, LobeSessionType } from '@lobechat/types';
|
|
1
|
+
import { LobeAgentSession, LobeGroupSession, LobeSessionType } from '@lobechat/types';
|
|
2
2
|
|
|
3
|
-
import { DEFAULT_AGENT_META } from './meta';
|
|
3
|
+
import { DEFAULT_AGENT_META, DEFAULT_INBOX_AVATAR } from './meta';
|
|
4
4
|
import { DEFAULT_AGENT_CONFIG } from './settings';
|
|
5
|
+
import { merge } from './utils/merge';
|
|
5
6
|
|
|
6
7
|
export const INBOX_SESSION_ID = 'inbox';
|
|
7
8
|
|
|
@@ -16,3 +17,19 @@ export const DEFAULT_AGENT_LOBE_SESSION: LobeAgentSession = {
|
|
|
16
17
|
type: LobeSessionType.Agent,
|
|
17
18
|
updatedAt: new Date(),
|
|
18
19
|
};
|
|
20
|
+
|
|
21
|
+
export const DEFAULT_GROUP_LOBE_SESSION: LobeGroupSession = {
|
|
22
|
+
createdAt: new Date(),
|
|
23
|
+
id: '',
|
|
24
|
+
members: [],
|
|
25
|
+
meta: DEFAULT_AGENT_META,
|
|
26
|
+
type: LobeSessionType.Group,
|
|
27
|
+
updatedAt: new Date(),
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const DEFAULT_INBOX_SESSION: LobeAgentSession = merge(DEFAULT_AGENT_LOBE_SESSION, {
|
|
31
|
+
id: 'inbox',
|
|
32
|
+
meta: {
|
|
33
|
+
avatar: DEFAULT_INBOX_AVATAR,
|
|
34
|
+
},
|
|
35
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LobeChatGroupChatConfig,
|
|
3
|
+
LobeChatGroupFullConfig,
|
|
4
|
+
LobeChatGroupMetaConfig,
|
|
5
|
+
} from '@lobechat/types';
|
|
6
|
+
|
|
7
|
+
import { DEFAULT_MODEL, DEFAULT_PROVIDER } from './llm';
|
|
8
|
+
|
|
9
|
+
export const DEFAULT_CHAT_GROUP_CHAT_CONFIG: LobeChatGroupChatConfig = {
|
|
10
|
+
allowDM: true,
|
|
11
|
+
enableSupervisor: true,
|
|
12
|
+
maxResponseInRow: 10,
|
|
13
|
+
orchestratorModel: DEFAULT_MODEL,
|
|
14
|
+
orchestratorProvider: DEFAULT_PROVIDER,
|
|
15
|
+
responseOrder: 'natural',
|
|
16
|
+
responseSpeed: 'fast',
|
|
17
|
+
revealDM: false,
|
|
18
|
+
scene: 'productive',
|
|
19
|
+
systemPrompt: '',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const DEFAULT_CHAT_GROUP_META_CONFIG: LobeChatGroupMetaConfig = {
|
|
23
|
+
description: '',
|
|
24
|
+
title: '',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const DEFAULT_CHAT_GROUP_CONFIG: LobeChatGroupFullConfig = {
|
|
28
|
+
chat: DEFAULT_CHAT_GROUP_CHAT_CONFIG,
|
|
29
|
+
meta: DEFAULT_CHAT_GROUP_META_CONFIG,
|
|
30
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { merge as _merge, isEmpty, mergeWith } from 'lodash-es';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 用于合并对象,如果是数组则直接替换
|
|
5
|
+
* @param target
|
|
6
|
+
* @param source
|
|
7
|
+
*/
|
|
8
|
+
export const merge: typeof _merge = <T = object>(target: T, source: T) =>
|
|
9
|
+
mergeWith({}, target, source, (obj, src) => {
|
|
10
|
+
if (Array.isArray(obj)) return src;
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
type MergeableItem = {
|
|
14
|
+
[key: string]: any;
|
|
15
|
+
id: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Merge two arrays based on id, preserving metadata from default items
|
|
20
|
+
* @param defaultItems Items with default configuration and metadata
|
|
21
|
+
* @param userItems User-defined items with higher priority
|
|
22
|
+
*/
|
|
23
|
+
export const mergeArrayById = <T extends MergeableItem>(defaultItems: T[], userItems: T[]): T[] => {
|
|
24
|
+
// Create a map of default items for faster lookup
|
|
25
|
+
const defaultItemsMap = new Map(defaultItems.map((item) => [item.id, item]));
|
|
26
|
+
|
|
27
|
+
// 使用 Map 存储合并结果,这样重复 ID 的后项会自然覆盖前项
|
|
28
|
+
const mergedItemsMap = new Map<string, T>();
|
|
29
|
+
|
|
30
|
+
// Process user items with default metadata
|
|
31
|
+
userItems.forEach((userItem) => {
|
|
32
|
+
const defaultItem = defaultItemsMap.get(userItem.id);
|
|
33
|
+
if (!defaultItem) {
|
|
34
|
+
mergedItemsMap.set(userItem.id, userItem);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const mergedItem: T = { ...defaultItem };
|
|
39
|
+
Object.entries(userItem).forEach(([key, value]) => {
|
|
40
|
+
if (value !== null && value !== undefined && !(typeof value === 'object' && isEmpty(value))) {
|
|
41
|
+
// @ts-expect-error
|
|
42
|
+
mergedItem[key] = value;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (typeof value === 'object' && !isEmpty(value)) {
|
|
46
|
+
// @ts-expect-error
|
|
47
|
+
mergedItem[key] = merge(defaultItem[key], value);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
mergedItemsMap.set(userItem.id, mergedItem);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// 添加只在默认配置中存在的项
|
|
55
|
+
defaultItems.forEach((item) => {
|
|
56
|
+
if (!mergedItemsMap.has(item.id)) {
|
|
57
|
+
mergedItemsMap.set(item.id, item);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
return Array.from(mergedItemsMap.values());
|
|
62
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
ALTER TABLE "messages" ALTER COLUMN "role" SET DATA TYPE varchar(255);--> statement-breakpoint
|
|
2
|
+
ALTER TABLE "chat_groups" ADD COLUMN IF NOT EXISTS "group_id" text;--> statement-breakpoint
|
|
3
|
+
ALTER TABLE "chat_groups" DROP CONSTRAINT IF EXISTS "chat_groups_group_id_session_groups_id_fk";--> statement-breakpoint
|
|
4
|
+
ALTER TABLE "chat_groups" ADD CONSTRAINT "chat_groups_group_id_session_groups_id_fk" FOREIGN KEY ("group_id") REFERENCES "public"."session_groups"("id") ON DELETE set null ON UPDATE no action;
|