@lobehub/chat 1.136.3 → 1.136.5

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.
@@ -259,6 +259,13 @@
259
259
  "when": 1759666151079,
260
260
  "tag": "0036_add_group_messages",
261
261
  "breakpoints": true
262
+ },
263
+ {
264
+ "idx": 37,
265
+ "version": "7",
266
+ "when": 1760086906862,
267
+ "tag": "0037_add_user_memory",
268
+ "breakpoints": true
262
269
  }
263
270
  ],
264
271
  "version": "6"
@@ -647,5 +647,34 @@
647
647
  "bps": true,
648
648
  "folderMillis": 1759666151079,
649
649
  "hash": "3a787841eede425d972f2a00cf2f7f8d0b27b391c46ed525c6dceaa79d58d887"
650
+ },
651
+ {
652
+ "sql": [
653
+ "CREATE TABLE IF NOT EXISTS \"user_memories\" (\n\t\"id\" varchar(255) PRIMARY KEY NOT NULL,\n\t\"user_id\" text,\n\t\"memory_category\" varchar(255),\n\t\"memory_layer\" varchar(255),\n\t\"memory_type\" varchar(255),\n\t\"title\" varchar(255),\n\t\"summary\" text,\n\t\"summary_vector_1024\" vector(1024),\n\t\"details\" text,\n\t\"details_vector_1024\" vector(1024),\n\t\"status\" varchar(255),\n\t\"accessed_count\" bigint DEFAULT 0,\n\t\"last_accessed_at\" timestamp with time zone NOT NULL,\n\t\"accessed_at\" timestamp with time zone DEFAULT now() NOT NULL,\n\t\"created_at\" timestamp with time zone DEFAULT now() NOT NULL,\n\t\"updated_at\" timestamp with time zone DEFAULT now() NOT NULL\n);\n",
654
+ "\nCREATE TABLE IF NOT EXISTS \"user_memories_contexts\" (\n\t\"id\" varchar(255) PRIMARY KEY NOT NULL,\n\t\"user_memory_ids\" jsonb,\n\t\"labels\" jsonb,\n\t\"extracted_labels\" jsonb,\n\t\"associated_objects\" jsonb,\n\t\"associated_subjects\" jsonb,\n\t\"title\" text,\n\t\"title_vector\" vector(1024),\n\t\"description\" text,\n\t\"description_vector\" vector(1024),\n\t\"type\" varchar(255),\n\t\"current_status\" text,\n\t\"score_impact\" numeric DEFAULT 0,\n\t\"score_urgency\" numeric DEFAULT 0,\n\t\"accessed_at\" timestamp with time zone DEFAULT now() NOT NULL,\n\t\"created_at\" timestamp with time zone DEFAULT now() NOT NULL,\n\t\"updated_at\" timestamp with time zone DEFAULT now() NOT NULL\n);\n",
655
+ "\nCREATE TABLE IF NOT EXISTS \"user_memories_experiences\" (\n\t\"id\" varchar(255) PRIMARY KEY NOT NULL,\n\t\"user_memory_id\" text,\n\t\"labels\" jsonb,\n\t\"extracted_labels\" jsonb,\n\t\"type\" varchar(255),\n\t\"situation\" text,\n\t\"situation_vector\" vector(1024),\n\t\"reasoning\" text,\n\t\"possible_outcome\" text,\n\t\"action\" text,\n\t\"action_vector\" vector(1024),\n\t\"key_learning\" text,\n\t\"key_learning_vector\" vector(1024),\n\t\"metadata\" jsonb,\n\t\"score_confidence\" real DEFAULT 0,\n\t\"accessed_at\" timestamp with time zone DEFAULT now() NOT NULL,\n\t\"created_at\" timestamp with time zone DEFAULT now() NOT NULL,\n\t\"updated_at\" timestamp with time zone DEFAULT now() NOT NULL\n);\n",
656
+ "\nCREATE TABLE IF NOT EXISTS \"user_memories_identities\" (\n\t\"current_focuses\" text,\n\t\"description\" text,\n\t\"description_vector\" vector(1024),\n\t\"experience\" text,\n\t\"extracted_labels\" jsonb,\n\t\"id\" varchar(255) PRIMARY KEY NOT NULL,\n\t\"labels\" jsonb,\n\t\"relationship\" text,\n\t\"role\" text,\n\t\"type\" varchar(255),\n\t\"user_memory_id\" text,\n\t\"accessed_at\" timestamp with time zone DEFAULT now() NOT NULL,\n\t\"created_at\" timestamp with time zone DEFAULT now() NOT NULL,\n\t\"updated_at\" timestamp with time zone DEFAULT now() NOT NULL\n);\n",
657
+ "\nCREATE TABLE IF NOT EXISTS \"user_memories_preferences\" (\n\t\"id\" varchar(255) PRIMARY KEY NOT NULL,\n\t\"context_id\" varchar(255),\n\t\"user_memory_id\" varchar(255),\n\t\"labels\" jsonb,\n\t\"extracted_labels\" jsonb,\n\t\"extracted_scopes\" jsonb,\n\t\"conclusion_directives\" text,\n\t\"conclusion_directives_vector\" vector(1024),\n\t\"type\" varchar(255),\n\t\"suggestions\" text,\n\t\"score_priority\" numeric DEFAULT 0,\n\t\"accessed_at\" timestamp with time zone DEFAULT now() NOT NULL,\n\t\"created_at\" timestamp with time zone DEFAULT now() NOT NULL,\n\t\"updated_at\" timestamp with time zone DEFAULT now() NOT NULL\n);\n",
658
+ "\nALTER TABLE \"user_memories\" ADD CONSTRAINT \"user_memories_user_id_users_id_fk\" FOREIGN KEY (\"user_id\") REFERENCES \"public\".\"users\"(\"id\") ON DELETE cascade ON UPDATE no action;",
659
+ "\nALTER TABLE \"user_memories_experiences\" ADD CONSTRAINT \"user_memories_experiences_user_memory_id_user_memories_id_fk\" FOREIGN KEY (\"user_memory_id\") REFERENCES \"public\".\"user_memories\"(\"id\") ON DELETE cascade ON UPDATE no action;",
660
+ "\nALTER TABLE \"user_memories_identities\" ADD CONSTRAINT \"user_memories_identities_user_memory_id_user_memories_id_fk\" FOREIGN KEY (\"user_memory_id\") REFERENCES \"public\".\"user_memories\"(\"id\") ON DELETE cascade ON UPDATE no action;",
661
+ "\nALTER TABLE \"user_memories_preferences\" ADD CONSTRAINT \"user_memories_preferences_context_id_user_memories_contexts_id_fk\" FOREIGN KEY (\"context_id\") REFERENCES \"public\".\"user_memories_contexts\"(\"id\") ON DELETE cascade ON UPDATE no action;",
662
+ "\nALTER TABLE \"user_memories_preferences\" ADD CONSTRAINT \"user_memories_preferences_user_memory_id_user_memories_id_fk\" FOREIGN KEY (\"user_memory_id\") REFERENCES \"public\".\"user_memories\"(\"id\") ON DELETE cascade ON UPDATE no action;",
663
+ "\nCREATE INDEX \"user_memories_summary_vector_1024_index\" ON \"user_memories\" USING hnsw (\"summary_vector_1024\" vector_cosine_ops);",
664
+ "\nCREATE INDEX \"user_memories_details_vector_1024_index\" ON \"user_memories\" USING hnsw (\"details_vector_1024\" vector_cosine_ops);",
665
+ "\nCREATE INDEX \"user_memories_contexts_title_vector_index\" ON \"user_memories_contexts\" USING hnsw (\"title_vector\" vector_cosine_ops);",
666
+ "\nCREATE INDEX \"user_memories_contexts_description_vector_index\" ON \"user_memories_contexts\" USING hnsw (\"description_vector\" vector_cosine_ops);",
667
+ "\nCREATE INDEX \"user_memories_contexts_type_index\" ON \"user_memories_contexts\" USING btree (\"type\");",
668
+ "\nCREATE INDEX \"user_memories_experiences_situation_vector_index\" ON \"user_memories_experiences\" USING hnsw (\"situation_vector\" vector_cosine_ops);",
669
+ "\nCREATE INDEX \"user_memories_experiences_action_vector_index\" ON \"user_memories_experiences\" USING hnsw (\"action_vector\" vector_cosine_ops);",
670
+ "\nCREATE INDEX \"user_memories_experiences_key_learning_vector_index\" ON \"user_memories_experiences\" USING hnsw (\"key_learning_vector\" vector_cosine_ops);",
671
+ "\nCREATE INDEX \"user_memories_experiences_type_index\" ON \"user_memories_experiences\" USING btree (\"type\");",
672
+ "\nCREATE INDEX \"user_memories_identities_description_vector_index\" ON \"user_memories_identities\" USING hnsw (\"description_vector\" vector_cosine_ops);",
673
+ "\nCREATE INDEX \"user_memories_identities_type_index\" ON \"user_memories_identities\" USING btree (\"type\");",
674
+ "\nCREATE INDEX \"user_memories_preferences_conclusion_directives_vector_index\" ON \"user_memories_preferences\" USING hnsw (\"conclusion_directives_vector\" vector_cosine_ops);\n"
675
+ ],
676
+ "bps": true,
677
+ "folderMillis": 1760086906862,
678
+ "hash": "4bdc6505797d7a33b622498c138cfd47f637239f6905e1c484cd01d9d5f21d6b"
650
679
  }
651
680
  ]
@@ -23,7 +23,7 @@ describe('TableViewerRepo', () => {
23
23
  it('should return all tables with counts', async () => {
24
24
  const result = await repo.getAllTables();
25
25
 
26
- expect(result.length).toEqual(63);
26
+ expect(result.length).toEqual(68);
27
27
  expect(result[0]).toEqual({ name: 'agents', count: 0, type: 'BASE TABLE' });
28
28
  });
29
29
 
@@ -16,3 +16,4 @@ export * from './relations';
16
16
  export * from './session';
17
17
  export * from './topic';
18
18
  export * from './user';
19
+ export * from './userMemories';
@@ -0,0 +1,210 @@
1
+ /* eslint-disable sort-keys-fix/sort-keys-fix */
2
+ import { bigint, index, jsonb, numeric, pgTable, real, text, vector } from 'drizzle-orm/pg-core';
3
+
4
+ import { idGenerator } from '../utils/idGenerator';
5
+ import { timestamps, timestamptz, varchar255 } from './_helpers';
6
+ import { users } from './user';
7
+
8
+ export const userMemories = pgTable(
9
+ 'user_memories',
10
+ {
11
+ id: varchar255('id')
12
+ .$defaultFn(() => idGenerator('memory'))
13
+ .primaryKey(),
14
+
15
+ userId: text('user_id').references(() => users.id, { onDelete: 'cascade' }),
16
+
17
+ memoryCategory: varchar255('memory_category'),
18
+ memoryLayer: varchar255('memory_layer'),
19
+ memoryType: varchar255('memory_type'),
20
+
21
+ title: varchar255('title'),
22
+ summary: text('summary'),
23
+ summaryVector1024: vector('summary_vector_1024', { dimensions: 1024 }),
24
+ details: text('details'),
25
+ detailsVector1024: vector('details_vector_1024', { dimensions: 1024 }),
26
+
27
+ status: varchar255('status'),
28
+
29
+ accessedCount: bigint('accessed_count', { mode: 'number' }).default(0),
30
+ lastAccessedAt: timestamptz('last_accessed_at').notNull(),
31
+
32
+ ...timestamps,
33
+ },
34
+ (table) => [
35
+ index('user_memories_summary_vector_1024_index').using(
36
+ 'hnsw',
37
+ table.summaryVector1024.op('vector_cosine_ops'),
38
+ ),
39
+ index('user_memories_details_vector_1024_index').using(
40
+ 'hnsw',
41
+ table.detailsVector1024.op('vector_cosine_ops'),
42
+ ),
43
+ ],
44
+ );
45
+
46
+ export const userMemoriesContexts = pgTable(
47
+ 'user_memories_contexts',
48
+ {
49
+ id: varchar255('id')
50
+ .$defaultFn(() => idGenerator('memory'))
51
+ .primaryKey(),
52
+
53
+ userMemoryIds: jsonb('user_memory_ids'),
54
+
55
+ labels: jsonb('labels'),
56
+ extractedLabels: jsonb('extracted_labels'),
57
+
58
+ associatedObjects: jsonb('associated_objects'),
59
+ associatedSubjects: jsonb('associated_subjects'),
60
+
61
+ title: text('title'),
62
+ titleVector: vector('title_vector', { dimensions: 1024 }),
63
+ description: text('description'),
64
+ descriptionVector: vector('description_vector', { dimensions: 1024 }),
65
+
66
+ type: varchar255('type'),
67
+ currentStatus: text('current_status'),
68
+
69
+ scoreImpact: numeric('score_impact', { mode: 'number' }).default(0),
70
+ scoreUrgency: numeric('score_urgency', { mode: 'number' }).default(0),
71
+
72
+ ...timestamps,
73
+ },
74
+ (table) => [
75
+ index('user_memories_contexts_title_vector_index').using(
76
+ 'hnsw',
77
+ table.titleVector.op('vector_cosine_ops'),
78
+ ),
79
+ index('user_memories_contexts_description_vector_index').using(
80
+ 'hnsw',
81
+ table.descriptionVector.op('vector_cosine_ops'),
82
+ ),
83
+ index('user_memories_contexts_type_index').on(table.type),
84
+ ],
85
+ );
86
+
87
+ export const userMemoriesPreferences = pgTable(
88
+ 'user_memories_preferences',
89
+ {
90
+ id: varchar255('id')
91
+ .$defaultFn(() => idGenerator('memory'))
92
+ .primaryKey(),
93
+
94
+ contextId: varchar255('context_id').references(() => userMemoriesContexts.id, {
95
+ onDelete: 'cascade',
96
+ }),
97
+ userMemoryId: varchar255('user_memory_id').references(() => userMemories.id, {
98
+ onDelete: 'cascade',
99
+ }),
100
+
101
+ labels: jsonb('labels'),
102
+ extractedLabels: jsonb('extracted_labels'),
103
+ extractedScopes: jsonb('extracted_scopes'),
104
+
105
+ conclusionDirectives: text('conclusion_directives'),
106
+ conclusionDirectivesVector: vector('conclusion_directives_vector', { dimensions: 1024 }),
107
+
108
+ type: varchar255('type'),
109
+ suggestions: text('suggestions'),
110
+
111
+ scorePriority: numeric('score_priority', { mode: 'number' }).default(0),
112
+
113
+ ...timestamps,
114
+ },
115
+ (table) => [
116
+ index('user_memories_preferences_conclusion_directives_vector_index').using(
117
+ 'hnsw',
118
+ table.conclusionDirectivesVector.op('vector_cosine_ops'),
119
+ ),
120
+ ],
121
+ );
122
+
123
+ export const userMemoriesIdentities = pgTable(
124
+ 'user_memories_identities',
125
+ {
126
+ currentFocuses: text('current_focuses'),
127
+ description: text('description'),
128
+ descriptionVector: vector('description_vector', { dimensions: 1024 }),
129
+ experience: text('experience'),
130
+ extractedLabels: jsonb('extracted_labels'),
131
+ id: varchar255('id')
132
+ .$defaultFn(() => idGenerator('memory'))
133
+ .primaryKey(),
134
+
135
+ labels: jsonb('labels'),
136
+ relationship: text('relationship'),
137
+ role: text('role'),
138
+
139
+ type: varchar255('type'),
140
+ userMemoryId: text('user_memory_id').references(() => userMemories.id, { onDelete: 'cascade' }),
141
+
142
+ ...timestamps,
143
+ },
144
+ (table) => [
145
+ index('user_memories_identities_description_vector_index').using(
146
+ 'hnsw',
147
+ table.descriptionVector.op('vector_cosine_ops'),
148
+ ),
149
+ index('user_memories_identities_type_index').on(table.type),
150
+ ],
151
+ );
152
+
153
+ export const userMemoriesExperiences = pgTable(
154
+ 'user_memories_experiences',
155
+ {
156
+ id: varchar255('id')
157
+ .$defaultFn(() => idGenerator('memory'))
158
+ .primaryKey(),
159
+
160
+ userMemoryId: text('user_memory_id').references(() => userMemories.id, { onDelete: 'cascade' }),
161
+
162
+ labels: jsonb('labels'),
163
+ extractedLabels: jsonb('extracted_labels'),
164
+ type: varchar255('type'),
165
+
166
+ situation: text('situation'),
167
+ situationVector: vector('situation_vector', { dimensions: 1024 }),
168
+ reasoning: text('reasoning'),
169
+ possibleOutcome: text('possible_outcome'),
170
+ action: text('action'),
171
+ actionVector: vector('action_vector', { dimensions: 1024 }),
172
+ keyLearning: text('key_learning'),
173
+ keyLearningVector: vector('key_learning_vector', { dimensions: 1024 }),
174
+
175
+ metadata: jsonb('metadata'),
176
+ scoreConfidence: real('score_confidence').default(0),
177
+
178
+ ...timestamps,
179
+ },
180
+ (table) => [
181
+ index('user_memories_experiences_situation_vector_index').using(
182
+ 'hnsw',
183
+ table.situationVector.op('vector_cosine_ops'),
184
+ ),
185
+ index('user_memories_experiences_action_vector_index').using(
186
+ 'hnsw',
187
+ table.actionVector.op('vector_cosine_ops'),
188
+ ),
189
+ index('user_memories_experiences_key_learning_vector_index').using(
190
+ 'hnsw',
191
+ table.keyLearningVector.op('vector_cosine_ops'),
192
+ ),
193
+ index('user_memories_experiences_type_index').on(table.type),
194
+ ],
195
+ );
196
+
197
+ export type UserMemoryItem = typeof userMemories.$inferSelect;
198
+ export type NewUserMemory = typeof userMemories.$inferInsert;
199
+
200
+ export type UserMemoryPreference = typeof userMemoriesPreferences.$inferSelect;
201
+ export type NewUserMemoryPreference = typeof userMemoriesPreferences.$inferInsert;
202
+
203
+ export type UserMemoryContext = typeof userMemoriesContexts.$inferSelect;
204
+ export type NewUserMemoryContext = typeof userMemoriesContexts.$inferInsert;
205
+
206
+ export type UserMemoryIdentity = typeof userMemoriesIdentities.$inferSelect;
207
+ export type NewUserMemoryIdentity = typeof userMemoriesIdentities.$inferInsert;
208
+
209
+ export type UserMemoryExperience = typeof userMemoriesExperiences.$inferSelect;
210
+ export type NewUserMemoryExperience = typeof userMemoriesExperiences.$inferInsert;
@@ -14,6 +14,7 @@ const prefixes = {
14
14
  generationTopics: 'gt',
15
15
  generations: 'gen',
16
16
  knowledgeBases: 'kb',
17
+ memory: 'mem',
17
18
  messageGroups: 'mg',
18
19
  messages: 'msg',
19
20
  plugins: 'plg',
@@ -45,6 +45,7 @@ const modelsWithModalities = new Set([
45
45
  'gemini-2.0-flash-exp-image-generation',
46
46
  'gemini-2.0-flash-preview-image-generation',
47
47
  'gemini-2.5-flash-image-preview',
48
+ 'gemini-2.5-flash-image',
48
49
  ]);
49
50
 
50
51
  const modelsDisableInstuction = new Set([
@@ -52,6 +53,7 @@ const modelsDisableInstuction = new Set([
52
53
  'gemini-2.0-flash-exp-image-generation',
53
54
  'gemini-2.0-flash-preview-image-generation',
54
55
  'gemini-2.5-flash-image-preview',
56
+ 'gemini-2.5-flash-image',
55
57
  'gemma-3-1b-it',
56
58
  'gemma-3-4b-it',
57
59
  'gemma-3-12b-it',
@@ -1,7 +1,7 @@
1
1
  import { Icon } from '@lobehub/ui';
2
2
  import { Empty } from 'antd';
3
3
  import { ServerCrash } from 'lucide-react';
4
- import { memo } from 'react';
4
+ import { memo, useEffect } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
  import { Center, Flexbox } from 'react-layout-kit';
7
7
  import { Virtuoso } from 'react-virtuoso';
@@ -25,6 +25,7 @@ export const List = memo(() => {
25
25
  searchLoading,
26
26
  useFetchPluginList,
27
27
  loadMorePlugins,
28
+ resetPluginList,
28
29
  ] = useToolStore((s) => [
29
30
  s.isPluginListInit,
30
31
  s.activePluginIdentifier,
@@ -35,8 +36,14 @@ export const List = memo(() => {
35
36
  s.pluginSearchLoading,
36
37
  s.useFetchPluginList,
37
38
  s.loadMorePlugins,
39
+ s.resetPluginList,
38
40
  ]);
39
41
 
42
+ // 当 keywords 变化时重置列表
43
+ useEffect(() => {
44
+ resetPluginList(keywords);
45
+ }, [keywords, resetPluginList]);
46
+
40
47
  const { isLoading, error } = useFetchPluginList({
41
48
  page: currentPage,
42
49
  pageSize: 20,
@@ -4,10 +4,18 @@ import { useTranslation } from 'react-i18next';
4
4
  import { Flexbox } from 'react-layout-kit';
5
5
 
6
6
  import { useToolStore } from '@/store/tool';
7
+ import { PluginStoreTabs } from '@/store/tool/slices/oldStore';
7
8
 
8
9
  export const Search = memo(() => {
9
10
  const { t } = useTranslation('plugin');
10
- const [keywords] = useToolStore((s) => [s.mcpSearchKeywords]);
11
+ const [listType, mcpKeywords, pluginKeywords] = useToolStore((s) => [
12
+ s.listType,
13
+ s.mcpSearchKeywords,
14
+ s.pluginSearchKeywords,
15
+ ]);
16
+
17
+ // 根据当前选项卡决定使用哪个关键词
18
+ const keywords = listType === PluginStoreTabs.MCP ? mcpKeywords : pluginKeywords;
11
19
 
12
20
  return (
13
21
  <Flexbox align={'center'} gap={8} horizontal justify={'space-between'}>
@@ -16,7 +24,11 @@ export const Search = memo(() => {
16
24
  allowClear
17
25
  defaultValue={keywords}
18
26
  onSearch={(keywords: string) => {
19
- useToolStore.setState({ mcpSearchKeywords: keywords, searchLoading: true });
27
+ if (listType === PluginStoreTabs.MCP) {
28
+ useToolStore.setState({ mcpSearchKeywords: keywords, searchLoading: true });
29
+ } else if (listType === PluginStoreTabs.Plugin) {
30
+ useToolStore.setState({ pluginSearchKeywords: keywords, pluginSearchLoading: true });
31
+ }
20
32
  }}
21
33
  placeholder={t('store.placeholder')}
22
34
  variant={'borderless'}