@lobehub/chat 1.33.5 → 1.34.1

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.
Files changed (205) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/changelog/v1.json +18 -0
  3. package/locales/ar/chat.json +7 -0
  4. package/locales/ar/common.json +2 -0
  5. package/locales/ar/models.json +24 -0
  6. package/locales/ar/setting.json +5 -0
  7. package/locales/ar/thread.json +5 -0
  8. package/locales/bg-BG/chat.json +7 -0
  9. package/locales/bg-BG/common.json +2 -0
  10. package/locales/bg-BG/models.json +24 -0
  11. package/locales/bg-BG/setting.json +5 -0
  12. package/locales/bg-BG/thread.json +5 -0
  13. package/locales/de-DE/chat.json +7 -0
  14. package/locales/de-DE/common.json +2 -0
  15. package/locales/de-DE/models.json +24 -0
  16. package/locales/de-DE/setting.json +5 -0
  17. package/locales/de-DE/thread.json +5 -0
  18. package/locales/en-US/chat.json +7 -0
  19. package/locales/en-US/common.json +2 -0
  20. package/locales/en-US/models.json +24 -0
  21. package/locales/en-US/setting.json +5 -0
  22. package/locales/en-US/thread.json +5 -0
  23. package/locales/es-ES/chat.json +7 -0
  24. package/locales/es-ES/common.json +2 -0
  25. package/locales/es-ES/models.json +24 -0
  26. package/locales/es-ES/setting.json +5 -0
  27. package/locales/es-ES/thread.json +5 -0
  28. package/locales/fa-IR/chat.json +7 -0
  29. package/locales/fa-IR/common.json +2 -0
  30. package/locales/fa-IR/models.json +24 -0
  31. package/locales/fa-IR/setting.json +5 -0
  32. package/locales/fa-IR/thread.json +5 -0
  33. package/locales/fr-FR/chat.json +7 -0
  34. package/locales/fr-FR/common.json +2 -0
  35. package/locales/fr-FR/models.json +24 -0
  36. package/locales/fr-FR/setting.json +5 -0
  37. package/locales/fr-FR/thread.json +5 -0
  38. package/locales/it-IT/chat.json +7 -0
  39. package/locales/it-IT/common.json +2 -0
  40. package/locales/it-IT/models.json +24 -0
  41. package/locales/it-IT/setting.json +5 -0
  42. package/locales/it-IT/thread.json +5 -0
  43. package/locales/ja-JP/chat.json +7 -0
  44. package/locales/ja-JP/common.json +2 -0
  45. package/locales/ja-JP/models.json +24 -0
  46. package/locales/ja-JP/setting.json +5 -0
  47. package/locales/ja-JP/thread.json +5 -0
  48. package/locales/ko-KR/chat.json +7 -0
  49. package/locales/ko-KR/common.json +2 -0
  50. package/locales/ko-KR/models.json +24 -0
  51. package/locales/ko-KR/setting.json +5 -0
  52. package/locales/ko-KR/thread.json +5 -0
  53. package/locales/nl-NL/chat.json +7 -0
  54. package/locales/nl-NL/common.json +2 -0
  55. package/locales/nl-NL/models.json +24 -0
  56. package/locales/nl-NL/setting.json +5 -0
  57. package/locales/nl-NL/thread.json +5 -0
  58. package/locales/pl-PL/chat.json +7 -0
  59. package/locales/pl-PL/common.json +2 -0
  60. package/locales/pl-PL/models.json +24 -0
  61. package/locales/pl-PL/setting.json +5 -0
  62. package/locales/pl-PL/thread.json +5 -0
  63. package/locales/pt-BR/chat.json +7 -0
  64. package/locales/pt-BR/common.json +2 -0
  65. package/locales/pt-BR/models.json +24 -0
  66. package/locales/pt-BR/setting.json +5 -0
  67. package/locales/pt-BR/thread.json +5 -0
  68. package/locales/ru-RU/chat.json +7 -0
  69. package/locales/ru-RU/common.json +2 -0
  70. package/locales/ru-RU/models.json +24 -0
  71. package/locales/ru-RU/setting.json +5 -0
  72. package/locales/ru-RU/thread.json +5 -0
  73. package/locales/tr-TR/chat.json +7 -0
  74. package/locales/tr-TR/common.json +2 -0
  75. package/locales/tr-TR/models.json +24 -0
  76. package/locales/tr-TR/setting.json +5 -0
  77. package/locales/tr-TR/thread.json +5 -0
  78. package/locales/vi-VN/chat.json +7 -0
  79. package/locales/vi-VN/common.json +2 -0
  80. package/locales/vi-VN/models.json +24 -0
  81. package/locales/vi-VN/setting.json +5 -0
  82. package/locales/vi-VN/thread.json +5 -0
  83. package/locales/zh-CN/chat.json +7 -0
  84. package/locales/zh-CN/common.json +2 -0
  85. package/locales/zh-CN/models.json +24 -0
  86. package/locales/zh-CN/setting.json +5 -0
  87. package/locales/zh-CN/thread.json +5 -0
  88. package/locales/zh-TW/chat.json +7 -0
  89. package/locales/zh-TW/common.json +2 -0
  90. package/locales/zh-TW/models.json +24 -0
  91. package/locales/zh-TW/setting.json +5 -0
  92. package/locales/zh-TW/thread.json +5 -0
  93. package/package.json +1 -1
  94. package/src/app/(main)/chat/(workspace)/@conversation/default.tsx +2 -0
  95. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatHydration/index.tsx +11 -2
  96. package/src/{features → app/(main)/chat/(workspace)/@conversation/features}/ChatInput/Desktop/Footer/index.tsx +7 -9
  97. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/index.tsx +7 -2
  98. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/Thread.tsx +62 -0
  99. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/ThreadItem.tsx +68 -0
  100. package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/index.tsx +62 -2
  101. package/src/app/(main)/chat/(workspace)/@conversation/features/ThreadHydration.tsx +47 -0
  102. package/src/app/(main)/chat/(workspace)/@portal/_layout/Desktop.tsx +3 -2
  103. package/src/app/(main)/chat/(workspace)/@portal/_layout/Mobile.tsx +47 -6
  104. package/src/app/(main)/chat/(workspace)/@topic/features/SkeletonList.tsx +3 -2
  105. package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/ByTimeMode/index.tsx +10 -3
  106. package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/FlatMode/index.tsx +1 -1
  107. package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/ThreadItem/Content.tsx +164 -0
  108. package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/ThreadItem/index.tsx +98 -0
  109. package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/{TopicItem.tsx → TopicItem/index.tsx} +33 -22
  110. package/src/app/(main)/chat/(workspace)/_layout/Desktop/Portal.tsx +12 -5
  111. package/src/app/(main)/chat/(workspace)/_layout/Mobile/index.tsx +1 -2
  112. package/src/const/message.ts +2 -0
  113. package/src/const/settings/systemAgent.ts +1 -0
  114. package/src/database/server/migrations/0012_add_thread.sql +39 -0
  115. package/src/database/server/migrations/meta/0012_snapshot.json +3671 -0
  116. package/src/database/server/migrations/meta/_journal.json +7 -0
  117. package/src/database/server/models/_template.ts +2 -2
  118. package/src/database/server/models/message.ts +1 -0
  119. package/src/database/server/models/thread.ts +79 -0
  120. package/src/database/server/schemas/lobechat/message.ts +2 -1
  121. package/src/database/server/schemas/lobechat/relations.ts +13 -1
  122. package/src/database/server/schemas/lobechat/topic.ts +30 -1
  123. package/src/database/server/utils/idGenerator.ts +1 -0
  124. package/src/features/ChatInput/ActionBar/Token/TokenTag.tsx +6 -4
  125. package/src/features/ChatInput/ActionBar/Token/index.tsx +24 -5
  126. package/src/features/ChatInput/ActionBar/config.ts +3 -2
  127. package/src/features/ChatInput/Desktop/index.tsx +15 -7
  128. package/src/features/ChatInput/Mobile/index.tsx +4 -4
  129. package/src/features/Conversation/Actions/Assistant.tsx +24 -5
  130. package/src/features/Conversation/Actions/User.tsx +21 -4
  131. package/src/features/Conversation/Actions/index.ts +1 -66
  132. package/src/features/Conversation/Messages/{Tool → Assistant/ToolCallItem}/Inspector/index.tsx +3 -1
  133. package/src/features/Conversation/Messages/{Tool/index.tsx → Assistant/ToolCallItem/Tool.tsx} +10 -11
  134. package/src/features/Conversation/Messages/Assistant/ToolCallItem/index.tsx +5 -3
  135. package/src/features/Conversation/Messages/Assistant/index.tsx +22 -14
  136. package/src/features/Conversation/Messages/index.ts +0 -2
  137. package/src/features/Conversation/components/AutoScroll.tsx +1 -1
  138. package/src/features/Conversation/components/ChatItem/ActionsBar.tsx +79 -5
  139. package/src/features/Conversation/components/ChatItem/InPortalThreadContext.ts +3 -0
  140. package/src/features/Conversation/components/ChatItem/index.tsx +16 -5
  141. package/src/features/Conversation/components/MarkdownElements/LobeArtifact/Render/index.tsx +9 -1
  142. package/src/features/Conversation/components/ThreadDivider/index.tsx +19 -0
  143. package/src/features/Conversation/hooks/useChatListActionsBar.tsx +19 -4
  144. package/src/features/Portal/Thread/Chat/ChatInput/Footer.tsx +90 -0
  145. package/src/features/Portal/Thread/Chat/ChatInput/TextArea.tsx +30 -0
  146. package/src/features/Portal/Thread/Chat/ChatInput/index.tsx +66 -0
  147. package/src/features/Portal/Thread/Chat/ChatInput/useSend.ts +50 -0
  148. package/src/features/Portal/Thread/Chat/ChatItem.tsx +62 -0
  149. package/src/features/Portal/Thread/Chat/ChatList.tsx +49 -0
  150. package/src/features/Portal/Thread/Chat/ThreadDivider/index.tsx +19 -0
  151. package/src/features/Portal/Thread/Chat/index.tsx +28 -0
  152. package/src/features/Portal/Thread/Header/Active.tsx +35 -0
  153. package/src/features/Portal/Thread/Header/New.tsx +37 -0
  154. package/src/features/Portal/Thread/Header/Title.tsx +18 -0
  155. package/src/features/Portal/Thread/Header/index.tsx +20 -0
  156. package/src/features/Portal/Thread/hook.ts +8 -0
  157. package/src/features/Portal/Thread/index.ts +12 -0
  158. package/src/features/Portal/router.tsx +2 -1
  159. package/src/hooks/useFetchTopics.ts +7 -1
  160. package/src/locales/default/chat.ts +8 -1
  161. package/src/locales/default/common.ts +3 -0
  162. package/src/locales/default/index.ts +2 -0
  163. package/src/locales/default/setting.ts +5 -0
  164. package/src/locales/default/thread.ts +5 -0
  165. package/src/server/modules/AgentRuntime/index.test.ts +10 -0
  166. package/src/server/modules/AgentRuntime/index.ts +1 -1
  167. package/src/server/routers/lambda/index.ts +2 -0
  168. package/src/server/routers/lambda/thread.ts +83 -0
  169. package/src/services/thread.ts +54 -0
  170. package/src/store/chat/initialState.ts +3 -0
  171. package/src/store/chat/selectors.ts +2 -1
  172. package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChat.test.ts +1 -1
  173. package/src/store/chat/slices/aiChat/actions/__tests__/rag.test.ts +1 -1
  174. package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +31 -8
  175. package/src/store/chat/slices/aiChat/actions/rag.ts +1 -1
  176. package/src/store/chat/slices/message/selectors.test.ts +3 -3
  177. package/src/store/chat/slices/message/selectors.ts +50 -29
  178. package/src/store/chat/slices/plugin/action.ts +26 -8
  179. package/src/store/chat/slices/portal/action.ts +1 -0
  180. package/src/store/chat/slices/portal/initialState.ts +1 -0
  181. package/src/store/chat/slices/portal/selectors/thread.ts +17 -0
  182. package/src/store/chat/slices/portal/selectors.ts +2 -0
  183. package/src/store/chat/slices/thread/action.ts +326 -0
  184. package/src/store/chat/slices/thread/initialState.ts +34 -0
  185. package/src/store/chat/slices/thread/reducer.ts +48 -0
  186. package/src/store/chat/slices/thread/selectors/index.ts +202 -0
  187. package/src/store/chat/slices/thread/selectors/util.ts +22 -0
  188. package/src/store/chat/slices/topic/action.ts +5 -1
  189. package/src/store/chat/store.ts +5 -2
  190. package/src/store/global/initialState.ts +4 -0
  191. package/src/store/global/selectors.ts +4 -0
  192. package/src/store/user/slices/settings/selectors/systemAgent.ts +2 -0
  193. package/src/types/message/index.ts +17 -1
  194. package/src/types/topic/index.ts +1 -0
  195. package/src/types/topic/thread.ts +42 -0
  196. package/src/types/user/settings/systemAgent.ts +1 -0
  197. package/src/app/(main)/chat/(workspace)/@portal/features/Header.tsx +0 -11
  198. package/src/app/(main)/chat/(workspace)/_layout/Mobile/PortalModal.tsx +0 -35
  199. /package/src/{features → app/(main)/chat/(workspace)/@conversation/features}/ChatInput/Desktop/Footer/SendMore.tsx +0 -0
  200. /package/src/{features → app/(main)/chat/(workspace)/@conversation/features}/ChatInput/Desktop/Footer/ShortcutHint.tsx +0 -0
  201. /package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/{DefaultContent.tsx → TopicItem/DefaultContent.tsx} +0 -0
  202. /package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/{TopicContent.tsx → TopicItem/TopicContent.tsx} +0 -0
  203. /package/src/features/Conversation/Messages/{Tool → Assistant/ToolCallItem}/Inspector/PluginResultJSON.tsx +0 -0
  204. /package/src/features/Conversation/Messages/{Tool → Assistant/ToolCallItem}/Inspector/Settings.tsx +0 -0
  205. /package/src/features/Conversation/Messages/{Tool → Assistant/ToolCallItem}/Inspector/style.ts +0 -0
@@ -3,8 +3,10 @@ import { memo, useState } from 'react';
3
3
  import { Flexbox } from 'react-layout-kit';
4
4
 
5
5
  import { useChatStore } from '@/store/chat';
6
+ import { threadSelectors } from '@/store/chat/selectors';
6
7
  import { useGlobalStore } from '@/store/global';
7
8
 
9
+ import ThreadItem from '../ThreadItem';
8
10
  import DefaultContent from './DefaultContent';
9
11
  import TopicContent from './TopicContent';
10
12
 
@@ -43,37 +45,46 @@ export interface ConfigCellProps {
43
45
  active?: boolean;
44
46
  fav?: boolean;
45
47
  id?: string;
48
+ threadId?: string;
46
49
  title: string;
47
50
  }
48
51
 
49
- const TopicItem = memo<ConfigCellProps>(({ title, active, id, fav }) => {
52
+ const TopicItem = memo<ConfigCellProps>(({ title, active, id, fav, threadId }) => {
50
53
  const { styles, cx } = useStyles();
51
54
  const toggleConfig = useGlobalStore((s) => s.toggleMobileTopic);
52
55
  const [toggleTopic] = useChatStore((s) => [s.switchTopic]);
53
56
  const [isHover, setHovering] = useState(false);
54
57
 
58
+ const threads = useChatStore(threadSelectors.getThreadsByTopic(id));
59
+
55
60
  return (
56
- <Flexbox
57
- align={'center'}
58
- className={cx(styles.container, 'topic-item', active && styles.active)}
59
- distribution={'space-between'}
60
- horizontal
61
- onClick={() => {
62
- toggleTopic(id);
63
- toggleConfig(false);
64
- }}
65
- onMouseEnter={() => {
66
- setHovering(true);
67
- }}
68
- onMouseLeave={() => {
69
- setHovering(false);
70
- }}
71
- >
72
- {!id ? (
73
- <DefaultContent />
74
- ) : (
75
- <TopicContent fav={fav} id={id} showMore={isHover} title={title} />
76
- )}
61
+ <Flexbox style={{ position: 'relative' }}>
62
+ <Flexbox
63
+ align={'center'}
64
+ className={cx(styles.container, 'topic-item', active && !threadId && styles.active)}
65
+ distribution={'space-between'}
66
+ horizontal
67
+ onClick={() => {
68
+ toggleTopic(id);
69
+ toggleConfig(false);
70
+ }}
71
+ onMouseEnter={() => {
72
+ setHovering(true);
73
+ }}
74
+ onMouseLeave={() => {
75
+ setHovering(false);
76
+ }}
77
+ >
78
+ {!id ? (
79
+ <DefaultContent />
80
+ ) : (
81
+ <TopicContent fav={fav} id={id} showMore={isHover} title={title} />
82
+ )}
83
+ </Flexbox>
84
+ {active &&
85
+ threads?.map((item, index) => (
86
+ <ThreadItem id={item.id} index={index} key={item.id} title={item.title} />
87
+ ))}
77
88
  </Flexbox>
78
89
  );
79
90
  });
@@ -12,7 +12,7 @@ import {
12
12
  CHAT_PORTAL_WIDTH,
13
13
  } from '@/const/layoutTokens';
14
14
  import { useChatStore } from '@/store/chat';
15
- import { chatPortalSelectors } from '@/store/chat/slices/portal/selectors';
15
+ import { chatPortalSelectors, portalThreadSelectors } from '@/store/chat/selectors';
16
16
 
17
17
  const useStyles = createStyles(({ css, token, isDarkMode }) => ({
18
18
  content: css`
@@ -32,16 +32,21 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
32
32
  height: 100%;
33
33
  background: ${isDarkMode ? rgba(token.colorBgElevated, 0.8) : token.colorBgElevated};
34
34
  `,
35
+
36
+ thread: css`
37
+ background: ${token.colorBgLayout};
38
+ `,
35
39
  }));
36
40
 
37
41
  const PortalPanel = memo(({ children }: PropsWithChildren) => {
38
- const { styles } = useStyles();
42
+ const { styles, cx } = useStyles();
39
43
  const { md = true } = useResponsive();
40
44
 
41
- const [showInspector, showToolUI, showArtifactUI] = useChatStore((s) => [
45
+ const [showInspector, showToolUI, showArtifactUI, showThread] = useChatStore((s) => [
42
46
  chatPortalSelectors.showPortal(s),
43
47
  chatPortalSelectors.showPluginUI(s),
44
48
  chatPortalSelectors.showArtifactUI(s),
49
+ portalThreadSelectors.showThread(s),
45
50
  ]);
46
51
 
47
52
  return (
@@ -54,7 +59,9 @@ const PortalPanel = memo(({ children }: PropsWithChildren) => {
54
59
  expand
55
60
  hanlderStyle={{ display: 'none' }}
56
61
  maxWidth={CHAT_PORTAL_MAX_WIDTH}
57
- minWidth={showArtifactUI || showToolUI ? CHAT_PORTAL_TOOL_UI_WIDTH : CHAT_PORTAL_WIDTH}
62
+ minWidth={
63
+ showArtifactUI || showToolUI || showThread ? CHAT_PORTAL_TOOL_UI_WIDTH : CHAT_PORTAL_WIDTH
64
+ }
58
65
  mode={md ? 'fixed' : 'float'}
59
66
  placement={'right'}
60
67
  showHandlerWhenUnexpand={false}
@@ -68,7 +75,7 @@ const PortalPanel = memo(({ children }: PropsWithChildren) => {
68
75
  minWidth: CHAT_PORTAL_WIDTH,
69
76
  }}
70
77
  >
71
- <Flexbox className={styles.panel}>{children}</Flexbox>
78
+ <Flexbox className={cx(styles.panel, showThread && styles.thread)}>{children}</Flexbox>
72
79
  </DraggablePanelContainer>
73
80
  </DraggablePanel>
74
81
  )
@@ -2,7 +2,6 @@ import MobileContentLayout from '@/components/server/MobileNavLayout';
2
2
 
3
3
  import { LayoutProps } from '../type';
4
4
  import ChatHeader from './ChatHeader';
5
- import PortalModal from './PortalModal';
6
5
  import TopicModal from './TopicModal';
7
6
 
8
7
  const Layout = ({ children, topic, conversation, portal }: LayoutProps) => {
@@ -13,7 +12,7 @@ const Layout = ({ children, topic, conversation, portal }: LayoutProps) => {
13
12
  {children}
14
13
  </MobileContentLayout>
15
14
  <TopicModal>{topic}</TopicModal>
16
- <PortalModal>{portal}</PortalModal>
15
+ {portal}
17
16
  </>
18
17
  );
19
18
  };
@@ -5,3 +5,5 @@ export const MESSAGE_CANCEL_FLAT = 'canceled';
5
5
  export const MESSAGE_THREAD_DIVIDER_ID = '__THREAD_DIVIDER__';
6
6
 
7
7
  export const MESSAGE_WELCOME_GUIDE_ID = 'welcome';
8
+
9
+ export const THREAD_DRAFT_ID = '__THREAD_DRAFT_ID__';
@@ -24,6 +24,7 @@ export const DEFAULT_SYSTEM_AGENT_CONFIG: UserSystemAgentConfig = {
24
24
  agentMeta: DEFAULT_SYSTEM_AGENT_ITEM,
25
25
  historyCompress: DEFAULT_SYSTEM_AGENT_ITEM,
26
26
  queryRewrite: DEFAULT_QUERY_REWRITE_SYSTEM_AGENT_ITEM,
27
+ thread: DEFAULT_SYSTEM_AGENT_ITEM,
27
28
  topic: DEFAULT_SYSTEM_AGENT_ITEM,
28
29
  translation: DEFAULT_SYSTEM_AGENT_ITEM,
29
30
  };
@@ -0,0 +1,39 @@
1
+ CREATE TABLE IF NOT EXISTS "threads" (
2
+ "id" text PRIMARY KEY NOT NULL,
3
+ "title" text,
4
+ "type" text NOT NULL,
5
+ "status" text DEFAULT 'active',
6
+ "topic_id" text NOT NULL,
7
+ "source_message_id" text NOT NULL,
8
+ "parent_thread_id" text,
9
+ "user_id" text NOT NULL,
10
+ "last_active_at" timestamp with time zone DEFAULT now(),
11
+ "accessed_at" timestamp with time zone DEFAULT now() NOT NULL,
12
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
13
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL
14
+ );
15
+ --> statement-breakpoint
16
+ ALTER TABLE "messages" ADD COLUMN "thread_id" text;--> statement-breakpoint
17
+ DO $$ BEGIN
18
+ ALTER TABLE "threads" ADD CONSTRAINT "threads_topic_id_topics_id_fk" FOREIGN KEY ("topic_id") REFERENCES "public"."topics"("id") ON DELETE cascade ON UPDATE no action;
19
+ EXCEPTION
20
+ WHEN duplicate_object THEN null;
21
+ END $$;
22
+ --> statement-breakpoint
23
+ DO $$ BEGIN
24
+ ALTER TABLE "threads" ADD CONSTRAINT "threads_parent_thread_id_threads_id_fk" FOREIGN KEY ("parent_thread_id") REFERENCES "public"."threads"("id") ON DELETE set null ON UPDATE no action;
25
+ EXCEPTION
26
+ WHEN duplicate_object THEN null;
27
+ END $$;
28
+ --> statement-breakpoint
29
+ DO $$ BEGIN
30
+ ALTER TABLE "threads" ADD CONSTRAINT "threads_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
31
+ EXCEPTION
32
+ WHEN duplicate_object THEN null;
33
+ END $$;
34
+ --> statement-breakpoint
35
+ DO $$ BEGIN
36
+ ALTER TABLE "messages" ADD CONSTRAINT "messages_thread_id_threads_id_fk" FOREIGN KEY ("thread_id") REFERENCES "public"."threads"("id") ON DELETE cascade ON UPDATE no action;
37
+ EXCEPTION
38
+ WHEN duplicate_object THEN null;
39
+ END $$;