@gendive/chatllm 0.10.0 → 0.10.2

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.
@@ -299,11 +299,18 @@ interface ChatUIProps {
299
299
  /**
300
300
  * @description 세션 상세 로드 콜백 (메시지 포함)
301
301
  * @Todo vibecode - 세션 선택 시 호출 (lazy loading)
302
+ * API 응답 형식: { role: 'USER'|'ASSISTANT', message: string }
302
303
  */
303
304
  onLoadSession?: (sessionId: string) => Promise<{
304
305
  id: string;
305
306
  title: string;
306
- messages: ChatMessage[];
307
+ messages: Array<{
308
+ id?: string;
309
+ role: 'USER' | 'ASSISTANT' | 'user' | 'assistant';
310
+ message?: string;
311
+ content?: string;
312
+ created_at?: string;
313
+ }>;
307
314
  memory_data?: object;
308
315
  }>;
309
316
  /**
@@ -612,11 +619,18 @@ interface UseChatUIOptions {
612
619
  /**
613
620
  * @description 세션 상세 로드 콜백 (메시지 포함)
614
621
  * @Todo vibecode - 세션 선택 시 호출 (lazy loading)
622
+ * API 응답 형식: { role: 'USER'|'ASSISTANT', message: string }
615
623
  */
616
624
  onLoadSession?: (sessionId: string) => Promise<{
617
625
  id: string;
618
626
  title: string;
619
- messages: ChatMessage[];
627
+ messages: Array<{
628
+ id?: string;
629
+ role: 'USER' | 'ASSISTANT' | 'user' | 'assistant';
630
+ message?: string;
631
+ content?: string;
632
+ created_at?: string;
633
+ }>;
620
634
  memory_data?: object;
621
635
  }>;
622
636
  /**
@@ -299,11 +299,18 @@ interface ChatUIProps {
299
299
  /**
300
300
  * @description 세션 상세 로드 콜백 (메시지 포함)
301
301
  * @Todo vibecode - 세션 선택 시 호출 (lazy loading)
302
+ * API 응답 형식: { role: 'USER'|'ASSISTANT', message: string }
302
303
  */
303
304
  onLoadSession?: (sessionId: string) => Promise<{
304
305
  id: string;
305
306
  title: string;
306
- messages: ChatMessage[];
307
+ messages: Array<{
308
+ id?: string;
309
+ role: 'USER' | 'ASSISTANT' | 'user' | 'assistant';
310
+ message?: string;
311
+ content?: string;
312
+ created_at?: string;
313
+ }>;
307
314
  memory_data?: object;
308
315
  }>;
309
316
  /**
@@ -612,11 +619,18 @@ interface UseChatUIOptions {
612
619
  /**
613
620
  * @description 세션 상세 로드 콜백 (메시지 포함)
614
621
  * @Todo vibecode - 세션 선택 시 호출 (lazy loading)
622
+ * API 응답 형식: { role: 'USER'|'ASSISTANT', message: string }
615
623
  */
616
624
  onLoadSession?: (sessionId: string) => Promise<{
617
625
  id: string;
618
626
  title: string;
619
- messages: ChatMessage[];
627
+ messages: Array<{
628
+ id?: string;
629
+ role: 'USER' | 'ASSISTANT' | 'user' | 'assistant';
630
+ message?: string;
631
+ content?: string;
632
+ created_at?: string;
633
+ }>;
620
634
  memory_data?: object;
621
635
  }>;
622
636
  /**
@@ -871,8 +871,9 @@ ${newConversation}
871
871
  const loadedMessages = sessionDetail.messages.map((m, idx) => ({
872
872
  id: m.id || generateId("msg"),
873
873
  role: typeof m.role === "string" ? m.role.toLowerCase() : m.role,
874
- content: m.content,
875
- timestamp: m.timestamp || Date.now() - (sessionDetail.messages.length - idx) * 1e3,
874
+ // API는 message 필드, 내부는 content 필드 사용
875
+ content: m.content || m.message || "",
876
+ timestamp: m.created_at ? new Date(m.created_at).getTime() : Date.now() - (sessionDetail.messages.length - idx) * 1e3,
876
877
  model: m.model,
877
878
  alternatives: m.alternatives,
878
879
  sources: m.sources
@@ -1029,7 +1030,12 @@ ${finalContent}`;
1029
1030
  setQuotedText(null);
1030
1031
  setSelectedAction(null);
1031
1032
  const capturedSessionId = sessionId;
1032
- const isFirstMessage = !sessions.find((s) => s.id === capturedSessionId)?.messages.length;
1033
+ const currentSession2 = sessions.find((s) => s.id === capturedSessionId);
1034
+ const existingMessages = currentSession2?.messages || [];
1035
+ const isFirstMessage = !existingMessages.length;
1036
+ const contextSummary = currentSession2?.compressionState?.contextSummary || currentSession2?.contextSummary;
1037
+ const summaryAfterIndex = currentSession2?.compressionState?.summaryAfterIndex || currentSession2?.summaryAfterIndex || 0;
1038
+ let compressionCount = currentSession2?.compressionState?.compressionCount || 0;
1033
1039
  setSessions(
1034
1040
  (prev) => prev.map((s) => {
1035
1041
  if (s.id === capturedSessionId) {
@@ -1060,29 +1066,25 @@ ${finalContent}`;
1060
1066
  setIsLoading(true);
1061
1067
  abortControllerRef.current = new AbortController();
1062
1068
  try {
1063
- const session = sessions.find((s) => s.id === capturedSessionId);
1064
- const existingMessages = session?.messages || [];
1065
1069
  let messagesToSend = [...existingMessages, userMessage];
1066
1070
  const recompressionThreshold = DEFAULT_RECOMPRESSION_THRESHOLD;
1067
1071
  const tokenLimit = DEFAULT_TOKEN_LIMIT;
1068
- let contextSummary = session?.compressionState?.contextSummary || session?.contextSummary;
1069
- const summaryAfterIndex = session?.compressionState?.summaryAfterIndex || session?.summaryAfterIndex || 0;
1070
- let compressionCount = session?.compressionState?.compressionCount || 0;
1072
+ let currentContextSummary = contextSummary;
1071
1073
  const newMessageCount = messagesToSend.length - summaryAfterIndex;
1072
1074
  const estimatedTokensCount = estimateTokens(messagesToSend);
1073
- const needsInitialCompression = !contextSummary && messagesToSend.length > contextCompressionThreshold;
1074
- const needsRecompression = contextSummary && (newMessageCount > recompressionThreshold || estimatedTokensCount > tokenLimit * 0.7);
1075
+ const needsInitialCompression = !currentContextSummary && messagesToSend.length > contextCompressionThreshold;
1076
+ const needsRecompression = currentContextSummary && (newMessageCount > recompressionThreshold || estimatedTokensCount > tokenLimit * 0.7);
1075
1077
  if (needsInitialCompression || needsRecompression) {
1076
1078
  const toCompress = messagesToSend.slice(0, -keepRecentMessages);
1077
1079
  let summary;
1078
- if (needsRecompression && contextSummary) {
1080
+ if (needsRecompression && currentContextSummary) {
1079
1081
  const newMessages = toCompress.slice(summaryAfterIndex);
1080
- summary = await incrementalCompressContext(contextSummary, newMessages, selectedModel);
1082
+ summary = await incrementalCompressContext(currentContextSummary, newMessages, selectedModel);
1081
1083
  } else {
1082
1084
  summary = await compressContext(toCompress, selectedModel);
1083
1085
  }
1084
1086
  if (summary) {
1085
- contextSummary = summary;
1087
+ currentContextSummary = summary;
1086
1088
  compressionCount += 1;
1087
1089
  setSessions(
1088
1090
  (prev) => prev.map(
@@ -1110,11 +1112,11 @@ ${finalContent}`;
1110
1112
  }
1111
1113
  }
1112
1114
  let chatMessages;
1113
- if (contextSummary) {
1115
+ if (currentContextSummary) {
1114
1116
  const recentMessages = messagesToSend.slice(-keepRecentMessages);
1115
1117
  chatMessages = [
1116
1118
  { role: "system", content: `[\uC774\uC804 \uB300\uD654 \uC694\uC57D]
1117
- ${contextSummary}` },
1119
+ ${currentContextSummary}` },
1118
1120
  ...recentMessages.map((m) => ({ role: m.role, content: m.content }))
1119
1121
  ];
1120
1122
  } else {