@gendive/chatllm 0.17.24 → 0.17.26

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.
@@ -34,6 +34,7 @@ __export(index_exports, {
34
34
  ChatInput: () => ChatInput,
35
35
  ChatSidebar: () => ChatSidebar,
36
36
  ChatUI: () => ChatUI,
37
+ ChecklistCard: () => ChecklistCard,
37
38
  ContentPartRenderer: () => ContentPartRenderer,
38
39
  DEFAULT_PROJECT_ID: () => DEFAULT_PROJECT_ID,
39
40
  DEFAULT_PROJECT_TITLE: () => DEFAULT_PROJECT_TITLE,
@@ -65,7 +66,7 @@ __export(index_exports, {
65
66
  module.exports = __toCommonJS(index_exports);
66
67
 
67
68
  // src/react/ChatUI.tsx
68
- var import_react20 = __toESM(require("react"));
69
+ var import_react21 = __toESM(require("react"));
69
70
 
70
71
  // src/react/hooks/useChatUI.ts
71
72
  var import_react5 = require("react");
@@ -1574,6 +1575,65 @@ var convertToolsToSkills = (tools, onToolCall) => {
1574
1575
  return skillMap;
1575
1576
  };
1576
1577
 
1578
+ // src/react/utils/checklistParser.ts
1579
+ var generateId3 = () => {
1580
+ return Math.random().toString(36).substring(2, 11);
1581
+ };
1582
+ var parseChecklistFromContent = (content) => {
1583
+ const checklistRegex = /<checklist>([\s\S]*?)<\/checklist>/i;
1584
+ const match = checklistRegex.exec(content);
1585
+ if (!match) {
1586
+ return { checklistBlock: null, cleanContent: content };
1587
+ }
1588
+ const innerContent = match[1].trim();
1589
+ const items = [];
1590
+ const stepTagRegex = /<step>([^<]+)<\/step>/gi;
1591
+ let stepMatch;
1592
+ while ((stepMatch = stepTagRegex.exec(innerContent)) !== null) {
1593
+ items.push({
1594
+ id: generateId3(),
1595
+ title: stepMatch[1].trim(),
1596
+ status: "pending"
1597
+ });
1598
+ }
1599
+ if (items.length === 0) {
1600
+ const numberedRegex = /^\d+[.)]\s+(.+)$/gm;
1601
+ let numMatch;
1602
+ while ((numMatch = numberedRegex.exec(innerContent)) !== null) {
1603
+ items.push({
1604
+ id: generateId3(),
1605
+ title: numMatch[1].trim(),
1606
+ status: "pending"
1607
+ });
1608
+ }
1609
+ }
1610
+ if (items.length === 0) {
1611
+ const listRegex = /^[-*]\s+(.+)$/gm;
1612
+ let listMatch;
1613
+ while ((listMatch = listRegex.exec(innerContent)) !== null) {
1614
+ items.push({
1615
+ id: generateId3(),
1616
+ title: listMatch[1].trim(),
1617
+ status: "pending"
1618
+ });
1619
+ }
1620
+ }
1621
+ if (items.length < 2) {
1622
+ return { checklistBlock: null, cleanContent: content };
1623
+ }
1624
+ let cleanContent = content.replace(match[0], "");
1625
+ cleanContent = cleanContent.replace(/\n{3,}/g, "\n\n").trim();
1626
+ return {
1627
+ checklistBlock: {
1628
+ id: generateId3(),
1629
+ items,
1630
+ currentStep: -1,
1631
+ completed: false
1632
+ },
1633
+ cleanContent
1634
+ };
1635
+ };
1636
+
1577
1637
  // src/react/utils/sessionCache.ts
1578
1638
  var buildCacheKey = (storageKey, sessionId) => `${storageKey}_cache_${sessionId}`;
1579
1639
  var writeSessionCache = (storageKey, session) => {
@@ -1638,7 +1698,7 @@ var DEFAULT_COMPRESSION_THRESHOLD = 20;
1638
1698
  var DEFAULT_KEEP_RECENT = 6;
1639
1699
  var DEFAULT_RECOMPRESSION_THRESHOLD = 10;
1640
1700
  var DEFAULT_TOKEN_LIMIT = 8e3;
1641
- var generateId3 = (prefix) => `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
1701
+ var generateId4 = (prefix) => `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
1642
1702
  var fileToBase64 = (file) => new Promise((resolve, reject) => {
1643
1703
  const reader = new FileReader();
1644
1704
  reader.onload = () => resolve(reader.result.split(",")[1] || "");
@@ -1779,6 +1839,8 @@ var useChatUI = (options) => {
1779
1839
  const abortControllerRef = (0, import_react5.useRef)(null);
1780
1840
  const skipNextPollParsingRef = (0, import_react5.useRef)(false);
1781
1841
  const skipNextSkillParsingRef = (0, import_react5.useRef)(false);
1842
+ const skipNextChecklistParsingRef = (0, import_react5.useRef)(false);
1843
+ const activeChecklistRef = (0, import_react5.useRef)(null);
1782
1844
  const lastExtractionMsgCountRef = (0, import_react5.useRef)(0);
1783
1845
  const memoryOptions = (0, import_react5.useMemo)(
1784
1846
  () => ({
@@ -2129,7 +2191,7 @@ ${newConversation}
2129
2191
  }
2130
2192
  const now = Date.now();
2131
2193
  const newSess = {
2132
- id: generateId3("session"),
2194
+ id: generateId4("session"),
2133
2195
  title: "\uC0C8 \uB300\uD654",
2134
2196
  messages: [],
2135
2197
  model: selectedModel,
@@ -2146,7 +2208,7 @@ ${newConversation}
2146
2208
  try {
2147
2209
  const sessionDetail = await onLoadSessionRef.current(id);
2148
2210
  let loadedMessages = sessionDetail.messages.map((m, idx) => ({
2149
- id: m.id || generateId3("msg"),
2211
+ id: m.id || generateId4("msg"),
2150
2212
  role: typeof m.role === "string" ? m.role.toLowerCase() : m.role,
2151
2213
  // API는 message 필드, 내부는 content 필드 사용
2152
2214
  content: m.content || m.message || "",
@@ -2311,7 +2373,7 @@ ${newConversation}
2311
2373
  const newAttachments = files.map((file) => {
2312
2374
  const isImage = file.type.startsWith("image/");
2313
2375
  return {
2314
- id: generateId3("attach"),
2376
+ id: generateId4("attach"),
2315
2377
  file,
2316
2378
  name: file.name,
2317
2379
  type: isImage ? "image" : "file",
@@ -2363,7 +2425,7 @@ ${newConversation}
2363
2425
  } else {
2364
2426
  const now = Date.now();
2365
2427
  const newSess = {
2366
- id: generateId3("session"),
2428
+ id: generateId4("session"),
2367
2429
  title: "\uC0C8 \uB300\uD654",
2368
2430
  messages: [],
2369
2431
  model: selectedModel,
@@ -2402,7 +2464,7 @@ ${finalContent}`;
2402
2464
  }
2403
2465
  }
2404
2466
  const userMessage = {
2405
- id: generateId3("msg"),
2467
+ id: generateId4("msg"),
2406
2468
  role: "user",
2407
2469
  content: finalContent,
2408
2470
  timestamp: Date.now(),
@@ -2416,7 +2478,7 @@ ${finalContent}`;
2416
2478
  const contextSummary = currentSession2?.compressionState?.contextSummary || currentSession2?.contextSummary;
2417
2479
  const summaryAfterIndex = currentSession2?.compressionState?.summaryAfterIndex || currentSession2?.summaryAfterIndex || 0;
2418
2480
  let compressionCount = currentSession2?.compressionState?.compressionCount || 0;
2419
- const assistantMessageId = generateId3("msg");
2481
+ const assistantMessageId = generateId4("msg");
2420
2482
  const assistantMessage = {
2421
2483
  id: assistantMessageId,
2422
2484
  role: "assistant",
@@ -2572,6 +2634,7 @@ ${finalContent}`;
2572
2634
  try {
2573
2635
  const shouldSkipSkillParsing = skipNextSkillParsingRef.current;
2574
2636
  skipNextSkillParsingRef.current = false;
2637
+ let accumulatedContent = "";
2575
2638
  let messagesToSend = [...existingMessages, userMessage];
2576
2639
  const recompressionThreshold = DEFAULT_RECOMPRESSION_THRESHOLD;
2577
2640
  const tokenLimit = DEFAULT_TOKEN_LIMIT;
@@ -2660,6 +2723,7 @@ ${attachmentContext}
2660
2723
  systemPrompt: combinedSystemPrompt
2661
2724
  });
2662
2725
  if (typeof result === "string") {
2726
+ accumulatedContent = result;
2663
2727
  setSessions(
2664
2728
  (prev) => prev.map((s) => {
2665
2729
  if (s.id === capturedSessionId) {
@@ -2673,9 +2737,8 @@ ${attachmentContext}
2673
2737
  return s;
2674
2738
  })
2675
2739
  );
2676
- return;
2677
- }
2678
- if (typeof result === "object" && "content" in result) {
2740
+ } else if (typeof result === "object" && "content" in result) {
2741
+ accumulatedContent = result.content;
2679
2742
  setSessions(
2680
2743
  (prev) => prev.map((s) => {
2681
2744
  if (s.id === capturedSessionId) {
@@ -2689,9 +2752,9 @@ ${attachmentContext}
2689
2752
  return s;
2690
2753
  })
2691
2754
  );
2692
- return;
2755
+ } else {
2756
+ response = new Response(result);
2693
2757
  }
2694
- response = new Response(result);
2695
2758
  } else {
2696
2759
  const isOllama = provider === "ollama" || apiEndpoint.includes("ollama") || apiEndpoint.includes("11434");
2697
2760
  const requestBody = isOllama ? { model: selectedModel, messages: messagesForApi, stream: true } : {
@@ -2708,98 +2771,105 @@ ${attachmentContext}
2708
2771
  signal: abortControllerRef.current.signal
2709
2772
  });
2710
2773
  }
2711
- if (!response.ok) throw new Error("API error");
2712
- const reader = response.body?.getReader();
2713
- if (!reader) throw new Error("No reader");
2714
- const decoder = new TextDecoder();
2715
- let buffer = "";
2716
- let accumulatedContent = "";
2717
- let skillTagDetected = false;
2718
- while (true) {
2719
- const { done, value } = await reader.read();
2720
- if (done) break;
2721
- buffer += decoder.decode(value, { stream: true });
2722
- const lines = buffer.split("\n");
2723
- buffer = lines.pop() || "";
2724
- for (const line of lines) {
2725
- if (!line.trim()) continue;
2726
- let data = line;
2727
- if (line.startsWith("data: ")) {
2728
- data = line.slice(6);
2729
- if (data === "[DONE]") continue;
2774
+ if (response) {
2775
+ if (!response.ok) throw new Error("API error");
2776
+ const reader = response.body?.getReader();
2777
+ if (!reader) throw new Error("No reader");
2778
+ const decoder = new TextDecoder();
2779
+ let buffer = "";
2780
+ let skillTagDetected = false;
2781
+ let checklistTagDetected = false;
2782
+ while (true) {
2783
+ const { done, value } = await reader.read();
2784
+ if (done) break;
2785
+ buffer += decoder.decode(value, { stream: true });
2786
+ const lines = buffer.split("\n");
2787
+ buffer = lines.pop() || "";
2788
+ for (const line of lines) {
2789
+ if (!line.trim()) continue;
2790
+ let data = line;
2791
+ if (line.startsWith("data: ")) {
2792
+ data = line.slice(6);
2793
+ if (data === "[DONE]") continue;
2794
+ }
2795
+ try {
2796
+ const parsed = JSON.parse(data);
2797
+ const content2 = parsed.message?.content || parsed.content || parsed.text || "";
2798
+ const thinking = parsed.message?.thinking || "";
2799
+ if (content2 || thinking) {
2800
+ if (content2) accumulatedContent += content2;
2801
+ if (!shouldSkipSkillParsing && accumulatedContent.includes("</skill_use>")) {
2802
+ const endIdx = accumulatedContent.indexOf("</skill_use>");
2803
+ accumulatedContent = accumulatedContent.substring(0, endIdx + "</skill_use>".length);
2804
+ skillTagDetected = true;
2805
+ }
2806
+ if (!skipNextChecklistParsingRef.current && accumulatedContent.includes("</checklist>")) {
2807
+ const endIdx = accumulatedContent.indexOf("</checklist>");
2808
+ accumulatedContent = accumulatedContent.substring(0, endIdx + "</checklist>".length);
2809
+ checklistTagDetected = true;
2810
+ }
2811
+ const displayContent = skillTagDetected ? accumulatedContent : null;
2812
+ setSessions(
2813
+ (prev) => prev.map((s) => {
2814
+ if (s.id === capturedSessionId) {
2815
+ return {
2816
+ ...s,
2817
+ messages: s.messages.map((m) => {
2818
+ if (m.id !== assistantMessageId) return m;
2819
+ if (displayContent) {
2820
+ return { ...m, content: displayContent };
2821
+ }
2822
+ let newContent = m.content;
2823
+ if (thinking) {
2824
+ if (!newContent.includes("<thinking>")) {
2825
+ newContent = "<thinking>" + thinking;
2826
+ } else if (!newContent.includes("</thinking>")) {
2827
+ newContent += thinking;
2828
+ }
2829
+ }
2830
+ if (content2) {
2831
+ if (newContent.includes("<thinking>") && !newContent.includes("</thinking>")) {
2832
+ newContent += "</thinking>\n\n";
2833
+ }
2834
+ newContent += content2;
2835
+ }
2836
+ return { ...m, content: newContent };
2837
+ })
2838
+ };
2839
+ }
2840
+ return s;
2841
+ })
2842
+ );
2843
+ if (skillTagDetected || checklistTagDetected) break;
2844
+ }
2845
+ } catch {
2846
+ }
2730
2847
  }
2848
+ if (skillTagDetected || checklistTagDetected) break;
2849
+ }
2850
+ if (buffer.trim()) {
2731
2851
  try {
2732
- const parsed = JSON.parse(data);
2733
- const content2 = parsed.message?.content || parsed.content || parsed.text || "";
2734
- const thinking = parsed.message?.thinking || "";
2735
- if (content2 || thinking) {
2736
- if (content2) accumulatedContent += content2;
2737
- if (!shouldSkipSkillParsing && accumulatedContent.includes("</skill_use>")) {
2738
- const endIdx = accumulatedContent.indexOf("</skill_use>");
2739
- accumulatedContent = accumulatedContent.substring(0, endIdx + "</skill_use>".length);
2740
- skillTagDetected = true;
2741
- }
2742
- const displayContent = skillTagDetected ? accumulatedContent : null;
2852
+ const parsed = JSON.parse(buffer);
2853
+ const content2 = parsed.message?.content || parsed.content || parsed.text;
2854
+ if (content2) {
2855
+ accumulatedContent += content2;
2743
2856
  setSessions(
2744
2857
  (prev) => prev.map((s) => {
2745
2858
  if (s.id === capturedSessionId) {
2746
2859
  return {
2747
2860
  ...s,
2748
- messages: s.messages.map((m) => {
2749
- if (m.id !== assistantMessageId) return m;
2750
- if (displayContent) {
2751
- return { ...m, content: displayContent };
2752
- }
2753
- let newContent = m.content;
2754
- if (thinking) {
2755
- if (!newContent.includes("<thinking>")) {
2756
- newContent = "<thinking>" + thinking;
2757
- } else if (!newContent.includes("</thinking>")) {
2758
- newContent += thinking;
2759
- }
2760
- }
2761
- if (content2) {
2762
- if (newContent.includes("<thinking>") && !newContent.includes("</thinking>")) {
2763
- newContent += "</thinking>\n\n";
2764
- }
2765
- newContent += content2;
2766
- }
2767
- return { ...m, content: newContent };
2768
- })
2861
+ messages: s.messages.map(
2862
+ (m) => m.id === assistantMessageId ? { ...m, content: m.content + content2 } : m
2863
+ )
2769
2864
  };
2770
2865
  }
2771
2866
  return s;
2772
2867
  })
2773
2868
  );
2774
- if (skillTagDetected) break;
2775
2869
  }
2776
2870
  } catch {
2777
2871
  }
2778
2872
  }
2779
- if (skillTagDetected) break;
2780
- }
2781
- if (buffer.trim()) {
2782
- try {
2783
- const parsed = JSON.parse(buffer);
2784
- const content2 = parsed.message?.content || parsed.content || parsed.text;
2785
- if (content2) {
2786
- accumulatedContent += content2;
2787
- setSessions(
2788
- (prev) => prev.map((s) => {
2789
- if (s.id === capturedSessionId) {
2790
- return {
2791
- ...s,
2792
- messages: s.messages.map(
2793
- (m) => m.id === assistantMessageId ? { ...m, content: m.content + content2 } : m
2794
- )
2795
- };
2796
- }
2797
- return s;
2798
- })
2799
- );
2800
- }
2801
- } catch {
2802
- }
2803
2873
  }
2804
2874
  const saveMessagesOnEarlyReturn = () => {
2805
2875
  if (!useExternalStorage || !capturedSessionId) return;
@@ -3009,6 +3079,165 @@ ${result.content}
3009
3079
  }
3010
3080
  }
3011
3081
  }
3082
+ if (activeChecklistRef.current) {
3083
+ const checklist = activeChecklistRef.current;
3084
+ const stepIndex = checklist.currentStep;
3085
+ checklist.stepResults.push(accumulatedContent);
3086
+ setSessions(
3087
+ (prev) => prev.map((s) => {
3088
+ if (s.id !== checklist.sessionId) return s;
3089
+ return {
3090
+ ...s,
3091
+ messages: s.messages.map((m) => {
3092
+ if (m.id !== checklist.messageId || !m.checklistBlock) return m;
3093
+ const updatedItems = m.checklistBlock.items.map((it, idx) => ({
3094
+ ...it,
3095
+ status: idx <= stepIndex ? "done" : it.status,
3096
+ result: idx === stepIndex ? accumulatedContent : it.result
3097
+ }));
3098
+ return {
3099
+ ...m,
3100
+ checklistBlock: { ...m.checklistBlock, items: updatedItems, currentStep: stepIndex + 1 }
3101
+ };
3102
+ })
3103
+ };
3104
+ })
3105
+ );
3106
+ setSessions(
3107
+ (prev) => prev.map((s) => {
3108
+ if (s.id !== capturedSessionId) return s;
3109
+ return {
3110
+ ...s,
3111
+ messages: s.messages.map((m) => {
3112
+ if (m.id !== assistantMessageId) return m;
3113
+ return { ...m, hidden: true };
3114
+ })
3115
+ };
3116
+ })
3117
+ );
3118
+ const nextStep = stepIndex + 1;
3119
+ if (nextStep < checklist.items.length) {
3120
+ checklist.currentStep = nextStep;
3121
+ setSessions(
3122
+ (prev) => prev.map((s) => {
3123
+ if (s.id !== checklist.sessionId) return s;
3124
+ return {
3125
+ ...s,
3126
+ messages: s.messages.map((m) => {
3127
+ if (m.id !== checklist.messageId || !m.checklistBlock) return m;
3128
+ const updatedItems = m.checklistBlock.items.map((it, idx) => ({
3129
+ ...it,
3130
+ status: idx === nextStep ? "in_progress" : it.status
3131
+ }));
3132
+ return {
3133
+ ...m,
3134
+ checklistBlock: { ...m.checklistBlock, items: updatedItems, currentStep: nextStep }
3135
+ };
3136
+ })
3137
+ };
3138
+ })
3139
+ );
3140
+ skipNextChecklistParsingRef.current = true;
3141
+ setTimeout(() => {
3142
+ sendMessage(
3143
+ `\uCCB4\uD06C\uB9AC\uC2A4\uD2B8 ${nextStep + 1}/${checklist.items.length}\uB2E8\uACC4\uB97C \uC2E4\uD589\uD558\uC138\uC694: "${checklist.items[nextStep].title}".
3144
+ \uC774\uC804 \uB2E8\uACC4 \uACB0\uACFC\uB97C \uCC38\uACE0\uD558\uB418, \uC774 \uB2E8\uACC4\uC5D0\uB9CC \uC9D1\uC911\uD558\uC5EC \uACB0\uACFC\uB97C \uC791\uC131\uD558\uC138\uC694. checklist \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.`,
3145
+ { hiddenUserMessage: true }
3146
+ );
3147
+ }, 100);
3148
+ saveMessagesOnEarlyReturn();
3149
+ setIsLoading(false);
3150
+ abortControllerRef.current = null;
3151
+ return;
3152
+ }
3153
+ const stepSummary = checklist.stepResults.map((r, i) => `### ${i + 1}. ${checklist.items[i].title}
3154
+ ${r}`).join("\n\n");
3155
+ setSessions(
3156
+ (prev) => prev.map((s) => {
3157
+ if (s.id !== checklist.sessionId) return s;
3158
+ return {
3159
+ ...s,
3160
+ messages: s.messages.map((m) => {
3161
+ if (m.id !== checklist.messageId || !m.checklistBlock) return m;
3162
+ return { ...m, checklistBlock: { ...m.checklistBlock, completed: true } };
3163
+ })
3164
+ };
3165
+ })
3166
+ );
3167
+ activeChecklistRef.current = null;
3168
+ skipNextChecklistParsingRef.current = true;
3169
+ setTimeout(() => {
3170
+ sendMessage(
3171
+ `\uBAA8\uB4E0 \uCCB4\uD06C\uB9AC\uC2A4\uD2B8 \uB2E8\uACC4\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC544\uB798\uB294 \uAC01 \uB2E8\uACC4\uBCC4 \uACB0\uACFC\uC785\uB2C8\uB2E4:
3172
+
3173
+ ${stepSummary}
3174
+
3175
+ \uC704 \uACB0\uACFC\uB97C \uC885\uD569\uD558\uC5EC \uCD5C\uC885 \uACB0\uACFC\uBB3C\uC744 \uC644\uC131\uD574\uC8FC\uC138\uC694. checklist \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.`,
3176
+ { hiddenUserMessage: true }
3177
+ );
3178
+ }, 100);
3179
+ saveMessagesOnEarlyReturn();
3180
+ setIsLoading(false);
3181
+ abortControllerRef.current = null;
3182
+ return;
3183
+ }
3184
+ if (!skipNextChecklistParsingRef.current) {
3185
+ const { checklistBlock, cleanContent: checklistCleanContent } = parseChecklistFromContent(accumulatedContent);
3186
+ if (checklistBlock) {
3187
+ setSessions(
3188
+ (prev) => prev.map((s) => {
3189
+ if (s.id !== capturedSessionId) return s;
3190
+ return {
3191
+ ...s,
3192
+ messages: s.messages.map((m) => {
3193
+ if (m.id !== assistantMessageId) return m;
3194
+ return { ...m, content: checklistCleanContent, checklistBlock };
3195
+ })
3196
+ };
3197
+ })
3198
+ );
3199
+ activeChecklistRef.current = {
3200
+ messageId: assistantMessageId,
3201
+ sessionId: capturedSessionId,
3202
+ items: checklistBlock.items.map((it) => ({ id: it.id, title: it.title })),
3203
+ currentStep: 0,
3204
+ stepResults: []
3205
+ };
3206
+ setSessions(
3207
+ (prev) => prev.map((s) => {
3208
+ if (s.id !== capturedSessionId) return s;
3209
+ return {
3210
+ ...s,
3211
+ messages: s.messages.map((m) => {
3212
+ if (m.id !== assistantMessageId || !m.checklistBlock) return m;
3213
+ const updatedItems = m.checklistBlock.items.map((it, idx) => ({
3214
+ ...it,
3215
+ status: idx === 0 ? "in_progress" : it.status
3216
+ }));
3217
+ return {
3218
+ ...m,
3219
+ checklistBlock: { ...m.checklistBlock, items: updatedItems, currentStep: 0 }
3220
+ };
3221
+ })
3222
+ };
3223
+ })
3224
+ );
3225
+ skipNextChecklistParsingRef.current = true;
3226
+ setTimeout(() => {
3227
+ sendMessage(
3228
+ `\uCCB4\uD06C\uB9AC\uC2A4\uD2B8 1/${checklistBlock.items.length}\uB2E8\uACC4\uB97C \uC2E4\uD589\uD558\uC138\uC694: "${checklistBlock.items[0].title}".
3229
+ \uC774 \uB2E8\uACC4\uC5D0\uB9CC \uC9D1\uC911\uD558\uC5EC \uACB0\uACFC\uB97C \uC791\uC131\uD558\uC138\uC694. checklist \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.`,
3230
+ { hiddenUserMessage: true }
3231
+ );
3232
+ }, 100);
3233
+ saveMessagesOnEarlyReturn();
3234
+ setIsLoading(false);
3235
+ abortControllerRef.current = null;
3236
+ return;
3237
+ }
3238
+ } else {
3239
+ skipNextChecklistParsingRef.current = false;
3240
+ }
3012
3241
  setSessions(
3013
3242
  (prev) => prev.map((s) => {
3014
3243
  if (s.id !== capturedSessionId) return s;
@@ -3108,6 +3337,187 @@ ${result.content}
3108
3337
  attachments,
3109
3338
  continueAfterToolResult
3110
3339
  ]);
3340
+ const handleChecklistAbort = (0, import_react5.useCallback)(() => {
3341
+ if (!activeChecklistRef.current) return;
3342
+ const checklist = activeChecklistRef.current;
3343
+ const stepIdx = checklist.currentStep;
3344
+ abortControllerRef.current?.abort();
3345
+ setSessions(
3346
+ (prev) => prev.map((s) => {
3347
+ if (s.id !== checklist.sessionId) return s;
3348
+ return {
3349
+ ...s,
3350
+ messages: s.messages.map((m) => {
3351
+ if (m.id !== checklist.messageId || !m.checklistBlock) return m;
3352
+ return {
3353
+ ...m,
3354
+ checklistBlock: {
3355
+ ...m.checklistBlock,
3356
+ items: m.checklistBlock.items.map((it, idx) => ({
3357
+ ...it,
3358
+ status: idx === stepIdx ? "error" : it.status
3359
+ }))
3360
+ }
3361
+ };
3362
+ })
3363
+ };
3364
+ })
3365
+ );
3366
+ activeChecklistRef.current = null;
3367
+ setIsLoading(false);
3368
+ }, []);
3369
+ const handleChecklistRetry = (0, import_react5.useCallback)(
3370
+ (messageId, stepIndex) => {
3371
+ const session = sessionsRef.current.find(
3372
+ (s) => s.messages.some((m) => m.id === messageId)
3373
+ );
3374
+ if (!session) return;
3375
+ const message = session.messages.find((m) => m.id === messageId);
3376
+ if (!message?.checklistBlock) return;
3377
+ activeChecklistRef.current = {
3378
+ messageId,
3379
+ sessionId: session.id,
3380
+ items: message.checklistBlock.items.map((it) => ({ id: it.id, title: it.title })),
3381
+ currentStep: stepIndex,
3382
+ stepResults: message.checklistBlock.items.slice(0, stepIndex).map((it) => it.result || "")
3383
+ };
3384
+ setSessions(
3385
+ (prev) => prev.map((s) => {
3386
+ if (s.id !== session.id) return s;
3387
+ return {
3388
+ ...s,
3389
+ messages: s.messages.map((m) => {
3390
+ if (m.id !== messageId || !m.checklistBlock) return m;
3391
+ return {
3392
+ ...m,
3393
+ checklistBlock: {
3394
+ ...m.checklistBlock,
3395
+ items: m.checklistBlock.items.map((it, idx) => ({
3396
+ ...it,
3397
+ status: idx === stepIndex ? "in_progress" : idx > stepIndex ? "pending" : it.status
3398
+ })),
3399
+ currentStep: stepIndex
3400
+ }
3401
+ };
3402
+ })
3403
+ };
3404
+ })
3405
+ );
3406
+ skipNextChecklistParsingRef.current = true;
3407
+ setTimeout(() => {
3408
+ sendMessage(
3409
+ `\uCCB4\uD06C\uB9AC\uC2A4\uD2B8 ${stepIndex + 1}/${message.checklistBlock.items.length}\uB2E8\uACC4\uB97C \uC2E4\uD589\uD558\uC138\uC694: "${message.checklistBlock.items[stepIndex].title}".
3410
+ \uC774\uC804 \uB2E8\uACC4 \uACB0\uACFC\uB97C \uCC38\uACE0\uD558\uB418, \uC774 \uB2E8\uACC4\uC5D0\uB9CC \uC9D1\uC911\uD558\uC5EC \uACB0\uACFC\uB97C \uC791\uC131\uD558\uC138\uC694. checklist \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.`,
3411
+ { hiddenUserMessage: true }
3412
+ );
3413
+ }, 100);
3414
+ },
3415
+ [sendMessage]
3416
+ );
3417
+ const handleChecklistSkip = (0, import_react5.useCallback)(
3418
+ (messageId, stepIndex) => {
3419
+ const session = sessionsRef.current.find(
3420
+ (s) => s.messages.some((m) => m.id === messageId)
3421
+ );
3422
+ if (!session) return;
3423
+ const message = session.messages.find((m) => m.id === messageId);
3424
+ if (!message?.checklistBlock) return;
3425
+ setSessions(
3426
+ (prev) => prev.map((s) => {
3427
+ if (s.id !== session.id) return s;
3428
+ return {
3429
+ ...s,
3430
+ messages: s.messages.map((m) => {
3431
+ if (m.id !== messageId || !m.checklistBlock) return m;
3432
+ return {
3433
+ ...m,
3434
+ checklistBlock: {
3435
+ ...m.checklistBlock,
3436
+ items: m.checklistBlock.items.map((it, idx) => ({
3437
+ ...it,
3438
+ status: idx === stepIndex ? "done" : it.status,
3439
+ result: idx === stepIndex ? "(\uAC74\uB108\uB700)" : it.result
3440
+ }))
3441
+ }
3442
+ };
3443
+ })
3444
+ };
3445
+ })
3446
+ );
3447
+ const nextPending = message.checklistBlock.items.findIndex(
3448
+ (it, idx) => idx > stepIndex && (it.status === "pending" || it.status === "error")
3449
+ );
3450
+ if (nextPending >= 0) {
3451
+ activeChecklistRef.current = {
3452
+ messageId,
3453
+ sessionId: session.id,
3454
+ items: message.checklistBlock.items.map((it) => ({ id: it.id, title: it.title })),
3455
+ currentStep: nextPending,
3456
+ stepResults: message.checklistBlock.items.slice(0, nextPending).map((it) => it.result || "(\uAC74\uB108\uB700)")
3457
+ };
3458
+ setSessions(
3459
+ (prev) => prev.map((s) => {
3460
+ if (s.id !== session.id) return s;
3461
+ return {
3462
+ ...s,
3463
+ messages: s.messages.map((m) => {
3464
+ if (m.id !== messageId || !m.checklistBlock) return m;
3465
+ return {
3466
+ ...m,
3467
+ checklistBlock: {
3468
+ ...m.checklistBlock,
3469
+ items: m.checklistBlock.items.map((it, idx) => ({
3470
+ ...it,
3471
+ status: idx === nextPending ? "in_progress" : it.status
3472
+ })),
3473
+ currentStep: nextPending
3474
+ }
3475
+ };
3476
+ })
3477
+ };
3478
+ })
3479
+ );
3480
+ skipNextChecklistParsingRef.current = true;
3481
+ setTimeout(() => {
3482
+ sendMessage(
3483
+ `\uCCB4\uD06C\uB9AC\uC2A4\uD2B8 ${nextPending + 1}/${message.checklistBlock.items.length}\uB2E8\uACC4\uB97C \uC2E4\uD589\uD558\uC138\uC694: "${message.checklistBlock.items[nextPending].title}".
3484
+ \uC774\uC804 \uB2E8\uACC4 \uACB0\uACFC\uB97C \uCC38\uACE0\uD558\uB418, \uC774 \uB2E8\uACC4\uC5D0\uB9CC \uC9D1\uC911\uD558\uC5EC \uACB0\uACFC\uB97C \uC791\uC131\uD558\uC138\uC694. checklist \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.`,
3485
+ { hiddenUserMessage: true }
3486
+ );
3487
+ }, 100);
3488
+ } else {
3489
+ const allResults = message.checklistBlock.items.map((it, i) => {
3490
+ const result = i === stepIndex ? "(\uAC74\uB108\uB700)" : it.result || "(\uAC74\uB108\uB700)";
3491
+ return `### ${i + 1}. ${it.title}
3492
+ ${result}`;
3493
+ }).join("\n\n");
3494
+ setSessions(
3495
+ (prev) => prev.map((s) => {
3496
+ if (s.id !== session.id) return s;
3497
+ return {
3498
+ ...s,
3499
+ messages: s.messages.map((m) => {
3500
+ if (m.id !== messageId || !m.checklistBlock) return m;
3501
+ return { ...m, checklistBlock: { ...m.checklistBlock, completed: true } };
3502
+ })
3503
+ };
3504
+ })
3505
+ );
3506
+ skipNextChecklistParsingRef.current = true;
3507
+ setTimeout(() => {
3508
+ sendMessage(
3509
+ `\uBAA8\uB4E0 \uCCB4\uD06C\uB9AC\uC2A4\uD2B8 \uB2E8\uACC4\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC544\uB798\uB294 \uAC01 \uB2E8\uACC4\uBCC4 \uACB0\uACFC\uC785\uB2C8\uB2E4:
3510
+
3511
+ ${allResults}
3512
+
3513
+ \uC704 \uACB0\uACFC\uB97C \uC885\uD569\uD558\uC5EC \uCD5C\uC885 \uACB0\uACFC\uBB3C\uC744 \uC644\uC131\uD574\uC8FC\uC138\uC694. checklist \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.`,
3514
+ { hiddenUserMessage: true }
3515
+ );
3516
+ }, 100);
3517
+ }
3518
+ },
3519
+ [sendMessage]
3520
+ );
3111
3521
  const handlePollSubmit = (0, import_react5.useCallback)(
3112
3522
  (messageId, responses) => {
3113
3523
  const currentSess = sessions.find((s) => s.id === currentSessionId);
@@ -3132,7 +3542,7 @@ ${result.content}
3132
3542
  return { ...m, pollBlock: void 0 };
3133
3543
  });
3134
3544
  updatedMessages.push({
3135
- id: generateId3("msg"),
3545
+ id: generateId4("msg"),
3136
3546
  role: "assistant",
3137
3547
  content: isAutoGenerate ? "\uC790\uB3D9\uC73C\uB85C \uCD5C\uC801\uC758 \uC635\uC158\uC744 \uC120\uD0DD\uD558\uC5EC \uC751\uB2F5\uD558\uACA0\uC2B5\uB2C8\uB2E4. \uC774\uC81C \uC2DC\uC791\uD558\uACA0\uC2B5\uB2C8\uB2E4." : "\uC120\uD0DD\uD558\uC2E0 \uB0B4\uC6A9\uC744 \uAE30\uBC18\uC73C\uB85C \uC751\uB2F5\uD558\uACA0\uC2B5\uB2C8\uB2E4. \uC774\uC81C \uC2DC\uC791\uD558\uACA0\uC2B5\uB2C8\uB2E4.",
3138
3548
  model: selectedModel,
@@ -3456,7 +3866,7 @@ ${currentSession.contextSummary}` },
3456
3866
  }
3457
3867
  }
3458
3868
  const alternative = {
3459
- id: generateId3("alt"),
3869
+ id: generateId4("alt"),
3460
3870
  model: targetModel,
3461
3871
  content: responseContent,
3462
3872
  timestamp: Date.now(),
@@ -3710,7 +4120,14 @@ ${result.content}
3710
4120
  projectSettingsOpen,
3711
4121
  openProjectSettings: () => setProjectSettingsOpen(true),
3712
4122
  closeProjectSettings: () => setProjectSettingsOpen(false),
3713
- projectMemory
4123
+ projectMemory,
4124
+ // Checklist
4125
+ /** @Todo vibecode - 체크리스트 자동 실행 중단 */
4126
+ handleChecklistAbort,
4127
+ /** @Todo vibecode - 체크리스트 error 항목 재시도 */
4128
+ handleChecklistRetry,
4129
+ /** @Todo vibecode - 체크리스트 pending 항목 건너뛰기 */
4130
+ handleChecklistSkip
3714
4131
  };
3715
4132
  };
3716
4133
 
@@ -5466,10 +5883,10 @@ var iconButtonStyle = {
5466
5883
  };
5467
5884
 
5468
5885
  // src/react/components/MessageList.tsx
5469
- var import_react17 = require("react");
5886
+ var import_react18 = require("react");
5470
5887
 
5471
5888
  // src/react/components/MessageBubble.tsx
5472
- var import_react16 = require("react");
5889
+ var import_react17 = require("react");
5473
5890
 
5474
5891
  // src/react/components/MarkdownRenderer.tsx
5475
5892
  var import_react11 = __toESM(require("react"));
@@ -5652,6 +6069,7 @@ var THINKING_TEXT_REGEX = /^Thinking:\s*\n([\s\S]*?)(?=\n\n|$)/gim;
5652
6069
  var UNCLOSED_THINKING_TAG_REGEX = /<thinking>(?![\s\S]*?<\/thinking>)/gi;
5653
6070
  var UNCLOSED_POLL_TAG_REGEX = /<poll[^>]*>(?![\s\S]*?<\/poll>)[\s\S]*$/gi;
5654
6071
  var UNCLOSED_SKILL_TAG_REGEX = /<skill_use[^>]*>(?![\s\S]*?<\/skill_use>)[\s\S]*$/gi;
6072
+ var UNCLOSED_CHECKLIST_TAG_REGEX = /<checklist>(?![\s\S]*?<\/checklist>)[\s\S]*$/gi;
5655
6073
  var INLINE_CODE_REGEX = /`([^`]+)`/g;
5656
6074
  var BOLD_REGEX = /\*\*([^*]+)\*\*/g;
5657
6075
  var ITALIC_REGEX = /(?<!\*)\*([^*]+)\*(?!\*)/g;
@@ -6533,6 +6951,9 @@ var MarkdownRenderer = ({
6533
6951
  }
6534
6952
  processedContent = processedContent.replace(/<skill_use[^>]*>[\s\S]*?<\/skill_use>/gi, "");
6535
6953
  processedContent = processedContent.replace(UNCLOSED_SKILL_TAG_REGEX, "");
6954
+ processedContent = processedContent.replace(/<checklist>[\s\S]*?<\/checklist>/gi, "");
6955
+ processedContent = processedContent.replace(UNCLOSED_CHECKLIST_TAG_REGEX, "");
6956
+ UNCLOSED_CHECKLIST_TAG_REGEX.lastIndex = 0;
6536
6957
  const codeBlocks = [];
6537
6958
  processedContent = processedContent.replace(CODE_BLOCK_REGEX, (match, lang, code) => {
6538
6959
  if (lang === "markdown" || lang === "md") {
@@ -8141,69 +8562,372 @@ var ContentPartRenderer = ({
8141
8562
  },
8142
8563
  idx
8143
8564
  );
8144
- case "tool_result": {
8145
- const { result } = part;
8146
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
8147
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
8148
- ToolStatusCard,
8149
- {
8150
- toolName: part.toolName,
8151
- label: part.label,
8152
- icon: part.icon,
8153
- status: result.type === "error" ? "error" : "done",
8154
- sources: result.sources,
8155
- errorMessage: result.type === "error" ? result.content : void 0
8156
- }
8157
- ),
8158
- result.type === "image" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
8159
- ImageContentCard,
8160
- {
8161
- part: { type: "image", url: result.content, alt: result.metadata?.alt }
8565
+ case "tool_result": {
8566
+ const { result } = part;
8567
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
8568
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
8569
+ ToolStatusCard,
8570
+ {
8571
+ toolName: part.toolName,
8572
+ label: part.label,
8573
+ icon: part.icon,
8574
+ status: result.type === "error" ? "error" : "done",
8575
+ sources: result.sources,
8576
+ errorMessage: result.type === "error" ? result.content : void 0
8577
+ }
8578
+ ),
8579
+ result.type === "image" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
8580
+ ImageContentCard,
8581
+ {
8582
+ part: { type: "image", url: result.content, alt: result.metadata?.alt }
8583
+ }
8584
+ ),
8585
+ result.type === "file" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
8586
+ FileContentCard,
8587
+ {
8588
+ part: {
8589
+ type: "file",
8590
+ name: result.metadata?.fileName || "file",
8591
+ url: result.content,
8592
+ mimeType: result.metadata?.mimeType
8593
+ }
8594
+ }
8595
+ )
8596
+ ] }, idx);
8597
+ }
8598
+ case "error":
8599
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
8600
+ "div",
8601
+ {
8602
+ style: {
8603
+ padding: "10px 14px",
8604
+ backgroundColor: "var(--chatllm-error-bg, #fef2f2)",
8605
+ borderRadius: "8px",
8606
+ border: "1px solid var(--chatllm-error-border, #fecaca)",
8607
+ fontSize: "13px",
8608
+ color: "var(--chatllm-error, #ef4444)",
8609
+ display: "flex",
8610
+ alignItems: "center",
8611
+ gap: "8px"
8612
+ },
8613
+ children: [
8614
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(IconSvg, { name: "error-warning-line", size: 16, color: "var(--chatllm-error, #ef4444)" }),
8615
+ part.message
8616
+ ]
8617
+ },
8618
+ idx
8619
+ );
8620
+ default:
8621
+ return null;
8622
+ }
8623
+ }) });
8624
+ };
8625
+
8626
+ // src/react/components/ChecklistCard.tsx
8627
+ var import_react16 = require("react");
8628
+ var import_jsx_runtime15 = require("react/jsx-runtime");
8629
+ var ChecklistCard = ({
8630
+ items,
8631
+ completed,
8632
+ onAbort,
8633
+ onRetryStep,
8634
+ onSkipStep
8635
+ }) => {
8636
+ const [expandedItems, setExpandedItems] = (0, import_react16.useState)(/* @__PURE__ */ new Set());
8637
+ const { doneCount, isRunning, hasError } = (0, import_react16.useMemo)(() => {
8638
+ const done = items.filter((it) => it.status === "done").length;
8639
+ const running = items.some((it) => it.status === "in_progress");
8640
+ const error = items.some((it) => it.status === "error");
8641
+ return { doneCount: done, isRunning: running, hasError: error };
8642
+ }, [items]);
8643
+ const progressPercent = doneCount / items.length * 100;
8644
+ const toggleExpanded = (itemId) => {
8645
+ setExpandedItems((prev) => {
8646
+ const next = new Set(prev);
8647
+ if (next.has(itemId)) {
8648
+ next.delete(itemId);
8649
+ } else {
8650
+ next.add(itemId);
8651
+ }
8652
+ return next;
8653
+ });
8654
+ };
8655
+ const renderStatusIcon = (item) => {
8656
+ switch (item.status) {
8657
+ case "done":
8658
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8659
+ "div",
8660
+ {
8661
+ style: {
8662
+ width: "20px",
8663
+ height: "20px",
8664
+ borderRadius: "50%",
8665
+ backgroundColor: "var(--chatllm-success, #22c55e)",
8666
+ display: "flex",
8667
+ alignItems: "center",
8668
+ justifyContent: "center",
8669
+ flexShrink: 0
8670
+ },
8671
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconSvg, { name: "check-line", size: 13, color: "#fff" })
8672
+ }
8673
+ );
8674
+ case "in_progress":
8675
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8676
+ "div",
8677
+ {
8678
+ style: {
8679
+ width: "20px",
8680
+ height: "20px",
8681
+ borderRadius: "50%",
8682
+ backgroundColor: "var(--chatllm-primary, #3584FA)",
8683
+ display: "flex",
8684
+ alignItems: "center",
8685
+ justifyContent: "center",
8686
+ flexShrink: 0,
8687
+ animation: "chatllm-checklist-pulse 1.5s ease-in-out infinite"
8688
+ },
8689
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { width: "6px", height: "6px", borderRadius: "50%", backgroundColor: "#fff" } })
8690
+ }
8691
+ );
8692
+ case "error":
8693
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8694
+ "div",
8695
+ {
8696
+ style: {
8697
+ width: "20px",
8698
+ height: "20px",
8699
+ borderRadius: "50%",
8700
+ backgroundColor: "var(--chatllm-error, #ef4444)",
8701
+ display: "flex",
8702
+ alignItems: "center",
8703
+ justifyContent: "center",
8704
+ flexShrink: 0
8705
+ },
8706
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconSvg, { name: "close-line", size: 13, color: "#fff" })
8707
+ }
8708
+ );
8709
+ default:
8710
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8711
+ "div",
8712
+ {
8713
+ style: {
8714
+ width: "20px",
8715
+ height: "20px",
8716
+ borderRadius: "50%",
8717
+ border: "2px solid var(--chatllm-text-muted, #94a3b8)",
8718
+ opacity: 0.5,
8719
+ flexShrink: 0
8162
8720
  }
8163
- ),
8164
- result.type === "file" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
8165
- FileContentCard,
8166
- {
8167
- part: {
8168
- type: "file",
8169
- name: result.metadata?.fileName || "file",
8170
- url: result.content,
8171
- mimeType: result.metadata?.mimeType
8721
+ }
8722
+ );
8723
+ }
8724
+ };
8725
+ const headerText = completed ? "\uBAA8\uB4E0 \uB2E8\uACC4 \uC644\uB8CC" : hasError ? "\uC791\uC5C5 \uC911\uB2E8\uB428" : isRunning ? `\uC791\uC5C5 \uC9C4\uD589 \uC911 \xB7 ${doneCount}/${items.length}` : `\uB300\uAE30 \uC911 \xB7 ${doneCount}/${items.length}`;
8726
+ const headerColor = completed ? "var(--chatllm-success, #22c55e)" : hasError ? "var(--chatllm-error, #ef4444)" : "var(--chatllm-primary, #3584FA)";
8727
+ const progressBarColor = completed ? "var(--chatllm-success, #22c55e)" : "var(--chatllm-primary, #3584FA)";
8728
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
8729
+ "div",
8730
+ {
8731
+ style: {
8732
+ border: "1px solid var(--chatllm-border, #e5e7eb)",
8733
+ borderRadius: "12px",
8734
+ backgroundColor: "var(--chatllm-content-bg, #fff)",
8735
+ overflow: "hidden",
8736
+ marginTop: "8px"
8737
+ },
8738
+ children: [
8739
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { padding: "14px 16px 10px" }, children: [
8740
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px", marginBottom: "8px" }, children: [
8741
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8742
+ IconSvg,
8743
+ {
8744
+ name: completed ? "checkbox-circle-line" : "list-check",
8745
+ size: 16,
8746
+ color: headerColor
8172
8747
  }
8748
+ ),
8749
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: { fontSize: "13px", fontWeight: 600, color: headerColor }, children: headerText })
8750
+ ] }),
8751
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8752
+ "div",
8753
+ {
8754
+ style: {
8755
+ height: "3px",
8756
+ backgroundColor: "var(--chatllm-bg-secondary, #f1f5f9)",
8757
+ borderRadius: "2px",
8758
+ overflow: "hidden"
8759
+ },
8760
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8761
+ "div",
8762
+ {
8763
+ style: {
8764
+ height: "100%",
8765
+ width: `${progressPercent}%`,
8766
+ backgroundColor: progressBarColor,
8767
+ borderRadius: "2px",
8768
+ transition: "width 0.6s cubic-bezier(0.25, 1, 0.5, 1)"
8769
+ }
8770
+ }
8771
+ )
8173
8772
  }
8174
8773
  )
8175
- ] }, idx);
8176
- }
8177
- case "error":
8178
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
8774
+ ] }),
8775
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { children: items.map((item, idx) => {
8776
+ const isExpanded = expandedItems.has(item.id);
8777
+ const canExpand = item.status === "done" && item.result && item.result !== "(\uAC74\uB108\uB700)";
8778
+ const isStopped = !isRunning && !completed;
8779
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
8780
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
8781
+ "div",
8782
+ {
8783
+ onClick: () => canExpand && toggleExpanded(item.id),
8784
+ style: {
8785
+ padding: "10px 16px",
8786
+ display: "flex",
8787
+ alignItems: "center",
8788
+ gap: "10px",
8789
+ borderTop: idx === 0 ? "1px solid var(--chatllm-border, #e5e7eb)" : "none",
8790
+ borderBottom: "1px solid var(--chatllm-border-light, #f1f5f9)",
8791
+ cursor: canExpand ? "pointer" : "default",
8792
+ backgroundColor: item.status === "error" ? "rgba(239, 68, 68, 0.04)" : item.status === "in_progress" ? "rgba(53, 132, 250, 0.03)" : "transparent",
8793
+ transition: "background-color 0.15s ease"
8794
+ },
8795
+ children: [
8796
+ renderStatusIcon(item),
8797
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
8798
+ "span",
8799
+ {
8800
+ style: {
8801
+ flex: 1,
8802
+ fontSize: "13px",
8803
+ fontWeight: item.status === "in_progress" ? 500 : 400,
8804
+ color: item.status === "pending" ? "var(--chatllm-text-muted, #94a3b8)" : item.status === "error" ? "var(--chatllm-error, #ef4444)" : "var(--chatllm-text, #374151)"
8805
+ },
8806
+ children: [
8807
+ idx + 1,
8808
+ ". ",
8809
+ item.title
8810
+ ]
8811
+ }
8812
+ ),
8813
+ item.status === "error" && onRetryStep && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8814
+ "button",
8815
+ {
8816
+ onClick: (e) => {
8817
+ e.stopPropagation();
8818
+ onRetryStep(idx);
8819
+ },
8820
+ style: {
8821
+ padding: "4px 10px",
8822
+ fontSize: "11px",
8823
+ fontWeight: 500,
8824
+ color: "var(--chatllm-error, #ef4444)",
8825
+ backgroundColor: "rgba(239, 68, 68, 0.08)",
8826
+ border: "1px solid rgba(239, 68, 68, 0.2)",
8827
+ borderRadius: "4px",
8828
+ cursor: "pointer"
8829
+ },
8830
+ children: "\uC7AC\uC2DC\uB3C4"
8831
+ }
8832
+ ),
8833
+ item.status === "pending" && isStopped && hasError && onSkipStep && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8834
+ "button",
8835
+ {
8836
+ onClick: (e) => {
8837
+ e.stopPropagation();
8838
+ onSkipStep(idx);
8839
+ },
8840
+ style: {
8841
+ padding: "4px 10px",
8842
+ fontSize: "11px",
8843
+ fontWeight: 500,
8844
+ color: "var(--chatllm-text-muted, #94a3b8)",
8845
+ backgroundColor: "var(--chatllm-bg-secondary, #f9fafb)",
8846
+ border: "1px solid var(--chatllm-border, #e5e7eb)",
8847
+ borderRadius: "4px",
8848
+ cursor: "pointer"
8849
+ },
8850
+ children: "\uAC74\uB108\uB6F0\uAE30"
8851
+ }
8852
+ ),
8853
+ canExpand && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8854
+ IconSvg,
8855
+ {
8856
+ name: isExpanded ? "arrow-up-s-line" : "arrow-down-s-line",
8857
+ size: 16,
8858
+ color: "var(--chatllm-text-muted, #94a3b8)"
8859
+ }
8860
+ ),
8861
+ item.result === "(\uAC74\uB108\uB700)" && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: { fontSize: "11px", color: "var(--chatllm-text-muted, #94a3b8)" }, children: "\uAC74\uB108\uB700" })
8862
+ ]
8863
+ }
8864
+ ),
8865
+ canExpand && isExpanded && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8866
+ "div",
8867
+ {
8868
+ style: {
8869
+ padding: "8px 16px 12px 46px",
8870
+ backgroundColor: "var(--chatllm-bg-secondary, #f9fafb)",
8871
+ margin: "0 8px 4px",
8872
+ borderRadius: "6px",
8873
+ maxHeight: "300px",
8874
+ overflowY: "auto",
8875
+ fontSize: "13px",
8876
+ lineHeight: "1.6",
8877
+ color: "var(--chatllm-text-secondary, #475569)",
8878
+ whiteSpace: "pre-wrap",
8879
+ wordBreak: "break-word"
8880
+ },
8881
+ children: item.result
8882
+ }
8883
+ )
8884
+ ] }, item.id);
8885
+ }) }),
8886
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
8179
8887
  "div",
8180
8888
  {
8181
8889
  style: {
8182
- padding: "10px 14px",
8183
- backgroundColor: "var(--chatllm-error-bg, #fef2f2)",
8184
- borderRadius: "8px",
8185
- border: "1px solid var(--chatllm-error-border, #fecaca)",
8186
- fontSize: "13px",
8187
- color: "var(--chatllm-error, #ef4444)",
8890
+ padding: "10px 16px",
8188
8891
  display: "flex",
8892
+ justifyContent: "space-between",
8189
8893
  alignItems: "center",
8190
- gap: "8px"
8894
+ borderTop: "1px solid var(--chatllm-border, #e5e7eb)"
8191
8895
  },
8192
8896
  children: [
8193
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(IconSvg, { name: "error-warning-line", size: 16, color: "var(--chatllm-error, #ef4444)" }),
8194
- part.message
8897
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { style: { fontSize: "12px", color: "var(--chatllm-text-muted, #94a3b8)" }, children: [
8898
+ doneCount,
8899
+ "/",
8900
+ items.length,
8901
+ " \uC644\uB8CC"
8902
+ ] }),
8903
+ isRunning && onAbort && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8904
+ "button",
8905
+ {
8906
+ onClick: onAbort,
8907
+ style: {
8908
+ padding: "4px 12px",
8909
+ fontSize: "12px",
8910
+ fontWeight: 500,
8911
+ color: "var(--chatllm-text-muted, #94a3b8)",
8912
+ backgroundColor: "transparent",
8913
+ border: "1px solid var(--chatllm-border, #e5e7eb)",
8914
+ borderRadius: "4px",
8915
+ cursor: "pointer",
8916
+ transition: "all 0.15s ease"
8917
+ },
8918
+ children: "\uC911\uB2E8"
8919
+ }
8920
+ )
8195
8921
  ]
8196
- },
8197
- idx
8198
- );
8199
- default:
8200
- return null;
8922
+ }
8923
+ )
8924
+ ]
8201
8925
  }
8202
- }) });
8926
+ );
8203
8927
  };
8204
8928
 
8205
8929
  // src/react/components/MessageBubble.tsx
8206
- var import_jsx_runtime15 = require("react/jsx-runtime");
8930
+ var import_jsx_runtime16 = require("react/jsx-runtime");
8207
8931
  var MessageBubble = ({
8208
8932
  message,
8209
8933
  isLoading,
@@ -8223,10 +8947,13 @@ var MessageBubble = ({
8223
8947
  showThinking = true,
8224
8948
  thinkingDefaultOpen = false,
8225
8949
  isLoadingAlternative = false,
8226
- onPollSubmit
8950
+ onPollSubmit,
8951
+ onChecklistAbort,
8952
+ onChecklistRetry,
8953
+ onChecklistSkip
8227
8954
  }) => {
8228
- const [showActions, setShowActions] = (0, import_react16.useState)(false);
8229
- const [showModelMenu, setShowModelMenu] = (0, import_react16.useState)(false);
8955
+ const [showActions, setShowActions] = (0, import_react17.useState)(false);
8956
+ const [showModelMenu, setShowModelMenu] = (0, import_react17.useState)(false);
8230
8957
  const isUser = message.role === "user";
8231
8958
  const isAssistant = message.role === "assistant";
8232
8959
  const relevantAlternatives = isUser ? alternatives : message.alternatives;
@@ -8237,7 +8964,7 @@ var MessageBubble = ({
8237
8964
  const displayModel = isAssistant && relevantAlternatives && relevantAlternatives.length > 0 && relevantActiveIndex > 0 ? relevantAlternatives[relevantActiveIndex - 1]?.model : message.model;
8238
8965
  const displaySources = isAssistant && relevantAlternatives && relevantAlternatives.length > 0 && relevantActiveIndex > 0 ? relevantAlternatives[relevantActiveIndex - 1]?.sources : message.sources;
8239
8966
  if (isUser) {
8240
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
8967
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
8241
8968
  "div",
8242
8969
  {
8243
8970
  className: "chatllm-message chatllm-message--user",
@@ -8250,7 +8977,7 @@ var MessageBubble = ({
8250
8977
  onMouseEnter: () => setShowActions(true),
8251
8978
  onMouseLeave: () => setShowActions(false),
8252
8979
  children: [
8253
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8980
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8254
8981
  "div",
8255
8982
  {
8256
8983
  style: {
@@ -8260,9 +8987,9 @@ var MessageBubble = ({
8260
8987
  borderRadius: "16px",
8261
8988
  borderTopRightRadius: "4px"
8262
8989
  },
8263
- children: message.contentParts?.length ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: message.contentParts.map((part, idx) => {
8990
+ children: message.contentParts?.length ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: message.contentParts.map((part, idx) => {
8264
8991
  if (part.type === "text") {
8265
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
8992
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8266
8993
  "div",
8267
8994
  {
8268
8995
  style: {
@@ -8277,7 +9004,7 @@ var MessageBubble = ({
8277
9004
  );
8278
9005
  }
8279
9006
  if (part.type === "image") {
8280
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9007
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8281
9008
  "img",
8282
9009
  {
8283
9010
  src: part.url,
@@ -8293,7 +9020,7 @@ var MessageBubble = ({
8293
9020
  );
8294
9021
  }
8295
9022
  if (part.type === "file") {
8296
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
9023
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
8297
9024
  "div",
8298
9025
  {
8299
9026
  style: {
@@ -8307,15 +9034,15 @@ var MessageBubble = ({
8307
9034
  color: "var(--chatllm-text)"
8308
9035
  },
8309
9036
  children: [
8310
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconSvg, { name: "file-text-line", size: 16, color: "var(--chatllm-text-muted)" }),
8311
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: part.name })
9037
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(IconSvg, { name: "file-text-line", size: 16, color: "var(--chatllm-text-muted)" }),
9038
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: part.name })
8312
9039
  ]
8313
9040
  },
8314
9041
  idx
8315
9042
  );
8316
9043
  }
8317
9044
  return null;
8318
- }) }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9045
+ }) }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8319
9046
  "div",
8320
9047
  {
8321
9048
  style: {
@@ -8329,7 +9056,7 @@ var MessageBubble = ({
8329
9056
  )
8330
9057
  }
8331
9058
  ),
8332
- !isLoading && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
9059
+ !isLoading && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
8333
9060
  "div",
8334
9061
  {
8335
9062
  style: {
@@ -8341,7 +9068,7 @@ var MessageBubble = ({
8341
9068
  transition: "opacity 0.15s ease"
8342
9069
  },
8343
9070
  children: [
8344
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { onClick: onCopy, style: actionButtonSmallStyle, title: "\uBCF5\uC0AC", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9071
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { onClick: onCopy, style: actionButtonSmallStyle, title: "\uBCF5\uC0AC", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8345
9072
  IconSvg,
8346
9073
  {
8347
9074
  name: isCopied ? "check-line" : "file-copy-line",
@@ -8349,7 +9076,7 @@ var MessageBubble = ({
8349
9076
  color: isCopied ? "var(--chatllm-success)" : "var(--chatllm-text-muted)"
8350
9077
  }
8351
9078
  ) }),
8352
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { onClick: onEdit, style: actionButtonSmallStyle, title: "\uC218\uC815", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconSvg, { name: "edit-line", size: 12, color: "var(--chatllm-text-muted)" }) })
9079
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { onClick: onEdit, style: actionButtonSmallStyle, title: "\uC218\uC815", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(IconSvg, { name: "edit-line", size: 12, color: "var(--chatllm-text-muted)" }) })
8353
9080
  ]
8354
9081
  }
8355
9082
  )
@@ -8357,7 +9084,7 @@ var MessageBubble = ({
8357
9084
  }
8358
9085
  );
8359
9086
  }
8360
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
9087
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
8361
9088
  "div",
8362
9089
  {
8363
9090
  className: "chatllm-message chatllm-message--assistant",
@@ -8370,7 +9097,7 @@ var MessageBubble = ({
8370
9097
  onMouseEnter: () => setShowActions(true),
8371
9098
  onMouseLeave: () => setShowActions(false),
8372
9099
  children: [
8373
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
9100
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
8374
9101
  "div",
8375
9102
  {
8376
9103
  className: "chatllm-sheet",
@@ -8381,7 +9108,7 @@ var MessageBubble = ({
8381
9108
  gap: "12px"
8382
9109
  },
8383
9110
  children: [
8384
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9111
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8385
9112
  "div",
8386
9113
  {
8387
9114
  style: {
@@ -8394,11 +9121,11 @@ var MessageBubble = ({
8394
9121
  justifyContent: "center",
8395
9122
  color: "var(--chatllm-primary)"
8396
9123
  },
8397
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconSvg, { name: "magic-line", size: 20 })
9124
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(IconSvg, { name: "magic-line", size: 20 })
8398
9125
  }
8399
9126
  ) }),
8400
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
8401
- displayModel && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9127
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
9128
+ displayModel && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8402
9129
  "div",
8403
9130
  {
8404
9131
  style: {
@@ -8407,7 +9134,7 @@ var MessageBubble = ({
8407
9134
  gap: "8px",
8408
9135
  marginBottom: "8px"
8409
9136
  },
8410
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9137
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8411
9138
  "span",
8412
9139
  {
8413
9140
  style: {
@@ -8422,9 +9149,9 @@ var MessageBubble = ({
8422
9149
  )
8423
9150
  }
8424
9151
  ),
8425
- message.isDeepResearch && message.researchProgress && message.researchProgress.phase !== "done" && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(DeepResearchProgressUI, { progress: message.researchProgress }),
8426
- message.skillExecution && message.skillExecution.status !== "done" && (message.skillExecution.progress?.subAgents ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(DeepResearchProgressUI, { progress: message.skillExecution.progress }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SkillProgressUI, { execution: message.skillExecution })),
8427
- message.isDeepResearch && displayContent && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
9152
+ message.isDeepResearch && message.researchProgress && message.researchProgress.phase !== "done" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DeepResearchProgressUI, { progress: message.researchProgress }),
9153
+ message.skillExecution && message.skillExecution.status !== "done" && (message.skillExecution.progress?.subAgents ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DeepResearchProgressUI, { progress: message.skillExecution.progress }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SkillProgressUI, { execution: message.skillExecution })),
9154
+ message.isDeepResearch && displayContent && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
8428
9155
  "div",
8429
9156
  {
8430
9157
  className: "chatllm-deep-research__header",
@@ -8437,8 +9164,8 @@ var MessageBubble = ({
8437
9164
  borderBottom: "1px solid var(--chatllm-border-light)"
8438
9165
  },
8439
9166
  children: [
8440
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconSvg, { name: "search-eye-line", size: 18, color: "var(--chatllm-primary)" }),
8441
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9167
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(IconSvg, { name: "search-eye-line", size: 18, color: "var(--chatllm-primary)" }),
9168
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8442
9169
  "span",
8443
9170
  {
8444
9171
  style: {
@@ -8449,7 +9176,7 @@ var MessageBubble = ({
8449
9176
  children: "\uC2EC\uCE35\uC5F0\uAD6C"
8450
9177
  }
8451
9178
  ),
8452
- displaySources && displaySources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
9179
+ displaySources && displaySources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
8453
9180
  "span",
8454
9181
  {
8455
9182
  className: "chatllm-deep-research__source-count",
@@ -8471,7 +9198,7 @@ var MessageBubble = ({
8471
9198
  ]
8472
9199
  }
8473
9200
  ),
8474
- !!message.contentParts?.length && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { wordBreak: "break-word" }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9201
+ !!message.contentParts?.length && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { wordBreak: "break-word" }, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8475
9202
  ContentPartRenderer,
8476
9203
  {
8477
9204
  parts: message.contentParts,
@@ -8482,13 +9209,13 @@ var MessageBubble = ({
8482
9209
  ) }),
8483
9210
  isLoading && !displayContent && !message.isDeepResearch && (message.contentParts?.length ? (
8484
9211
  /* contentParts 있을 때: 간소화된 AI 응답 대기 표시 */
8485
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px", marginTop: "4px" }, children: [
8486
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", gap: "4px", alignItems: "center" }, children: [
8487
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "chatllm-dot-bounce", style: dotStyle }),
8488
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "chatllm-dot-bounce", style: dotStyle }),
8489
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "chatllm-dot-bounce", style: dotStyle })
9212
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px", marginTop: "4px" }, children: [
9213
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { display: "flex", gap: "4px", alignItems: "center" }, children: [
9214
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "chatllm-dot-bounce", style: dotStyle }),
9215
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "chatllm-dot-bounce", style: dotStyle }),
9216
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "chatllm-dot-bounce", style: dotStyle })
8490
9217
  ] }),
8491
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9218
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8492
9219
  "span",
8493
9220
  {
8494
9221
  style: {
@@ -8503,14 +9230,14 @@ var MessageBubble = ({
8503
9230
  ] })
8504
9231
  ) : (
8505
9232
  /* contentParts 없을 때: 풀 스켈레톤 */
8506
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "16px" }, children: [
8507
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "12px" }, children: [
8508
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", gap: "4px", alignItems: "center" }, children: [
8509
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "chatllm-dot-bounce", style: dotStyle }),
8510
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "chatllm-dot-bounce", style: dotStyle }),
8511
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "chatllm-dot-bounce", style: dotStyle })
9233
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "16px" }, children: [
9234
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "12px" }, children: [
9235
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { display: "flex", gap: "4px", alignItems: "center" }, children: [
9236
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "chatllm-dot-bounce", style: dotStyle }),
9237
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "chatllm-dot-bounce", style: dotStyle }),
9238
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "chatllm-dot-bounce", style: dotStyle })
8512
9239
  ] }),
8513
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9240
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8514
9241
  "span",
8515
9242
  {
8516
9243
  style: {
@@ -8523,17 +9250,17 @@ var MessageBubble = ({
8523
9250
  }
8524
9251
  )
8525
9252
  ] }),
8526
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "chatllm-skeleton-pulse", style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
8527
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { height: "32px", width: "75%", backgroundColor: "var(--chatllm-bg-tertiary)", borderRadius: "8px" } }),
8528
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [
8529
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { height: "16px", width: "100%", backgroundColor: "var(--chatllm-bg-secondary)", borderRadius: "4px" } }),
8530
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { height: "16px", width: "85%", backgroundColor: "var(--chatllm-bg-secondary)", borderRadius: "4px" } }),
8531
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { height: "16px", width: "65%", backgroundColor: "var(--chatllm-bg-secondary)", borderRadius: "4px" } })
9253
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "chatllm-skeleton-pulse", style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
9254
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { height: "32px", width: "75%", backgroundColor: "var(--chatllm-bg-tertiary)", borderRadius: "8px" } }),
9255
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [
9256
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { height: "16px", width: "100%", backgroundColor: "var(--chatllm-bg-secondary)", borderRadius: "4px" } }),
9257
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { height: "16px", width: "85%", backgroundColor: "var(--chatllm-bg-secondary)", borderRadius: "4px" } }),
9258
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { height: "16px", width: "65%", backgroundColor: "var(--chatllm-bg-secondary)", borderRadius: "4px" } })
8532
9259
  ] })
8533
9260
  ] })
8534
9261
  ] })
8535
9262
  )),
8536
- displayContent ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { wordBreak: "break-word" }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9263
+ displayContent ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { wordBreak: "break-word" }, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8537
9264
  MarkdownRenderer,
8538
9265
  {
8539
9266
  content: displayContent,
@@ -8542,7 +9269,7 @@ var MessageBubble = ({
8542
9269
  thinkingDefaultOpen
8543
9270
  }
8544
9271
  ) }) : null,
8545
- message.pollBlock && message.pollBlock.questions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9272
+ message.pollBlock && message.pollBlock.questions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8546
9273
  PollCard,
8547
9274
  {
8548
9275
  questions: message.pollBlock.questions,
@@ -8554,7 +9281,18 @@ var MessageBubble = ({
8554
9281
  }
8555
9282
  }
8556
9283
  ),
8557
- !isLoading && !displayContent && !message.pollBlock && !message.contentParts?.length && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9284
+ message.checklistBlock && message.checklistBlock.items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
9285
+ ChecklistCard,
9286
+ {
9287
+ items: message.checklistBlock.items,
9288
+ currentStep: message.checklistBlock.currentStep,
9289
+ completed: message.checklistBlock.completed,
9290
+ onAbort: onChecklistAbort,
9291
+ onRetryStep: onChecklistRetry,
9292
+ onSkipStep: onChecklistSkip
9293
+ }
9294
+ ),
9295
+ !isLoading && !displayContent && !message.pollBlock && !message.checklistBlock && !message.contentParts?.length && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8558
9296
  "div",
8559
9297
  {
8560
9298
  style: {
@@ -8567,7 +9305,7 @@ var MessageBubble = ({
8567
9305
  children: "\uC751\uB2F5\uC744 \uC0DD\uC131\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD574 \uC8FC\uC138\uC694."
8568
9306
  }
8569
9307
  ),
8570
- displaySources && displaySources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
9308
+ displaySources && displaySources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
8571
9309
  "div",
8572
9310
  {
8573
9311
  style: {
@@ -8579,7 +9317,7 @@ var MessageBubble = ({
8579
9317
  borderTop: "1px solid var(--chatllm-border-light)"
8580
9318
  },
8581
9319
  children: [
8582
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9320
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8583
9321
  "span",
8584
9322
  {
8585
9323
  style: {
@@ -8591,7 +9329,7 @@ var MessageBubble = ({
8591
9329
  children: "\uCD9C\uCC98:"
8592
9330
  }
8593
9331
  ),
8594
- displaySources.map((source, index) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9332
+ displaySources.map((source, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8595
9333
  LinkChip,
8596
9334
  {
8597
9335
  text: source.title,
@@ -8604,7 +9342,7 @@ var MessageBubble = ({
8604
9342
  ]
8605
9343
  }
8606
9344
  ),
8607
- relevantAlternatives && relevantAlternatives.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
9345
+ relevantAlternatives && relevantAlternatives.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
8608
9346
  "div",
8609
9347
  {
8610
9348
  style: {
@@ -8618,8 +9356,8 @@ var MessageBubble = ({
8618
9356
  fontSize: "12px"
8619
9357
  },
8620
9358
  children: [
8621
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: { color: "var(--chatllm-text-muted)", marginRight: "4px" }, children: displayModel || "\uBAA8\uB378" }),
8622
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9359
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: { color: "var(--chatllm-text-muted)", marginRight: "4px" }, children: displayModel || "\uBAA8\uB378" }),
9360
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8623
9361
  "button",
8624
9362
  {
8625
9363
  onClick: () => onAlternativeChange?.(Math.max(0, relevantActiveIndex - 1)),
@@ -8629,15 +9367,15 @@ var MessageBubble = ({
8629
9367
  opacity: relevantActiveIndex === 0 ? 0.5 : 1,
8630
9368
  cursor: relevantActiveIndex === 0 ? "not-allowed" : "pointer"
8631
9369
  },
8632
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconSvg, { name: "arrow-left-line", size: 12 })
9370
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(IconSvg, { name: "arrow-left-line", size: 12 })
8633
9371
  }
8634
9372
  ),
8635
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { style: { color: "var(--chatllm-text-secondary)" }, children: [
9373
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { style: { color: "var(--chatllm-text-secondary)" }, children: [
8636
9374
  relevantActiveIndex + 1,
8637
9375
  " / ",
8638
9376
  relevantAlternatives.length + 1
8639
9377
  ] }),
8640
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9378
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8641
9379
  "button",
8642
9380
  {
8643
9381
  onClick: () => onAlternativeChange?.(Math.min(relevantAlternatives.length, relevantActiveIndex + 1)),
@@ -8647,13 +9385,13 @@ var MessageBubble = ({
8647
9385
  opacity: relevantActiveIndex === relevantAlternatives.length ? 0.5 : 1,
8648
9386
  cursor: relevantActiveIndex === relevantAlternatives.length ? "not-allowed" : "pointer"
8649
9387
  },
8650
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconSvg, { name: "arrow-right-line", size: 12 })
9388
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(IconSvg, { name: "arrow-right-line", size: 12 })
8651
9389
  }
8652
9390
  )
8653
9391
  ]
8654
9392
  }
8655
9393
  ),
8656
- isLoadingAlternative && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
9394
+ isLoadingAlternative && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
8657
9395
  "div",
8658
9396
  {
8659
9397
  style: {
@@ -8668,12 +9406,12 @@ var MessageBubble = ({
8668
9406
  color: "var(--chatllm-primary, #3584FA)"
8669
9407
  },
8670
9408
  children: [
8671
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { display: "flex", gap: "4px", alignItems: "center" }, children: [
8672
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "chatllm-dot-bounce", style: dotStyle }),
8673
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "chatllm-dot-bounce", style: dotStyle }),
8674
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "chatllm-dot-bounce", style: dotStyle })
9409
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { display: "flex", gap: "4px", alignItems: "center" }, children: [
9410
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "chatllm-dot-bounce", style: dotStyle }),
9411
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "chatllm-dot-bounce", style: dotStyle }),
9412
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "chatllm-dot-bounce", style: dotStyle })
8675
9413
  ] }),
8676
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: { fontWeight: 500 }, children: "\uB2E4\uB978 \uBAA8\uB378 \uC751\uB2F5 \uC0DD\uC131 \uC911..." })
9414
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: { fontWeight: 500 }, children: "\uB2E4\uB978 \uBAA8\uB378 \uC751\uB2F5 \uC0DD\uC131 \uC911..." })
8677
9415
  ]
8678
9416
  }
8679
9417
  )
@@ -8681,7 +9419,7 @@ var MessageBubble = ({
8681
9419
  ]
8682
9420
  }
8683
9421
  ),
8684
- !isLoading && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
9422
+ !isLoading && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
8685
9423
  "div",
8686
9424
  {
8687
9425
  style: {
@@ -8694,7 +9432,7 @@ var MessageBubble = ({
8694
9432
  transition: "opacity 0.15s ease"
8695
9433
  },
8696
9434
  children: [
8697
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { onClick: onCopy, style: actionButtonSmallStyle, title: "\uBCF5\uC0AC", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9435
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { onClick: onCopy, style: actionButtonSmallStyle, title: "\uBCF5\uC0AC", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8698
9436
  IconSvg,
8699
9437
  {
8700
9438
  name: isCopied ? "check-line" : "file-copy-line",
@@ -8702,18 +9440,18 @@ var MessageBubble = ({
8702
9440
  color: isCopied ? "var(--chatllm-success)" : "var(--chatllm-text-muted)"
8703
9441
  }
8704
9442
  ) }),
8705
- onRegenerate && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { onClick: onRegenerate, style: actionButtonSmallStyle, title: "\uB2E4\uC2DC \uC0DD\uC131", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconSvg, { name: "refresh-line", size: 12, color: "var(--chatllm-text-muted)" }) }),
8706
- onAskOtherModel && otherModels.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: { position: "relative" }, children: [
8707
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9443
+ onRegenerate && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { onClick: onRegenerate, style: actionButtonSmallStyle, title: "\uB2E4\uC2DC \uC0DD\uC131", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(IconSvg, { name: "refresh-line", size: 12, color: "var(--chatllm-text-muted)" }) }),
9444
+ onAskOtherModel && otherModels.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: { position: "relative" }, children: [
9445
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8708
9446
  "button",
8709
9447
  {
8710
9448
  onClick: () => setShowModelMenu(!showModelMenu),
8711
9449
  style: actionButtonSmallStyle,
8712
9450
  title: "\uB2E4\uB978 \uBAA8\uB378\uC5D0\uAC8C \uC9C8\uBB38",
8713
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconSvg, { name: "robot-line", size: 12, color: "var(--chatllm-text-muted)" })
9451
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(IconSvg, { name: "robot-line", size: 12, color: "var(--chatllm-text-muted)" })
8714
9452
  }
8715
9453
  ),
8716
- showModelMenu && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9454
+ showModelMenu && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8717
9455
  ModelMenu,
8718
9456
  {
8719
9457
  models: otherModels,
@@ -8732,7 +9470,7 @@ var MessageBubble = ({
8732
9470
  }
8733
9471
  );
8734
9472
  };
8735
- var ModelMenu = ({ models, onSelect, onClose }) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
9473
+ var ModelMenu = ({ models, onSelect, onClose }) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
8736
9474
  "div",
8737
9475
  {
8738
9476
  style: {
@@ -8750,7 +9488,7 @@ var ModelMenu = ({ models, onSelect, onClose }) => /* @__PURE__ */ (0, import_js
8750
9488
  },
8751
9489
  onMouseLeave: onClose,
8752
9490
  children: [
8753
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9491
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8754
9492
  "div",
8755
9493
  {
8756
9494
  style: {
@@ -8765,7 +9503,7 @@ var ModelMenu = ({ models, onSelect, onClose }) => /* @__PURE__ */ (0, import_js
8765
9503
  children: "\uB2E4\uB978 \uBAA8\uB378\uC5D0\uAC8C \uC9C8\uBB38"
8766
9504
  }
8767
9505
  ),
8768
- models.map((model) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
9506
+ models.map((model) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
8769
9507
  "button",
8770
9508
  {
8771
9509
  onClick: () => onSelect(model.id),
@@ -8790,9 +9528,9 @@ var ModelMenu = ({ models, onSelect, onClose }) => /* @__PURE__ */ (0, import_js
8790
9528
  e.currentTarget.style.backgroundColor = "transparent";
8791
9529
  },
8792
9530
  children: [
8793
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconSvg, { name: "robot-line", size: 16, color: "var(--chatllm-primary)" }),
8794
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: { flex: 1, fontWeight: 500 }, children: model.name }),
8795
- model.provider && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
9531
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(IconSvg, { name: "robot-line", size: 16, color: "var(--chatllm-primary)" }),
9532
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: { flex: 1, fontWeight: 500 }, children: model.name }),
9533
+ model.provider && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8796
9534
  "span",
8797
9535
  {
8798
9536
  style: {
@@ -8841,7 +9579,7 @@ var navButtonStyle = {
8841
9579
  };
8842
9580
 
8843
9581
  // src/react/components/MessageList.tsx
8844
- var import_jsx_runtime16 = require("react/jsx-runtime");
9582
+ var import_jsx_runtime17 = require("react/jsx-runtime");
8845
9583
  var MessageList = ({
8846
9584
  messages,
8847
9585
  isLoading,
@@ -8859,16 +9597,19 @@ var MessageList = ({
8859
9597
  showThinking = true,
8860
9598
  thinkingDefaultOpen = false,
8861
9599
  loadingAlternativeFor,
8862
- onPollSubmit
9600
+ onPollSubmit,
9601
+ onChecklistAbort,
9602
+ onChecklistRetry,
9603
+ onChecklistSkip
8863
9604
  }) => {
8864
- const messagesEndRef = (0, import_react17.useRef)(null);
8865
- const containerRef = (0, import_react17.useRef)(null);
8866
- const [selectedText, setSelectedText] = (0, import_react17.useState)("");
8867
- const [selectionPosition, setSelectionPosition] = (0, import_react17.useState)(null);
8868
- const [showScrollButton, setShowScrollButton] = (0, import_react17.useState)(false);
8869
- const isUserScrolledUpRef = (0, import_react17.useRef)(false);
9605
+ const messagesEndRef = (0, import_react18.useRef)(null);
9606
+ const containerRef = (0, import_react18.useRef)(null);
9607
+ const [selectedText, setSelectedText] = (0, import_react18.useState)("");
9608
+ const [selectionPosition, setSelectionPosition] = (0, import_react18.useState)(null);
9609
+ const [showScrollButton, setShowScrollButton] = (0, import_react18.useState)(false);
9610
+ const isUserScrolledUpRef = (0, import_react18.useRef)(false);
8870
9611
  const SCROLL_THRESHOLD = 100;
8871
- const handleScroll = (0, import_react17.useCallback)(() => {
9612
+ const handleScroll = (0, import_react18.useCallback)(() => {
8872
9613
  if (!containerRef.current) return;
8873
9614
  const { scrollTop, scrollHeight, clientHeight } = containerRef.current;
8874
9615
  const distanceFromBottom = scrollHeight - scrollTop - clientHeight;
@@ -8876,16 +9617,16 @@ var MessageList = ({
8876
9617
  isUserScrolledUpRef.current = !isNearBottom;
8877
9618
  setShowScrollButton(!isNearBottom);
8878
9619
  }, []);
8879
- (0, import_react17.useEffect)(() => {
9620
+ (0, import_react18.useEffect)(() => {
8880
9621
  if (isUserScrolledUpRef.current) return;
8881
9622
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
8882
9623
  }, [messages]);
8883
- const scrollToBottom = (0, import_react17.useCallback)(() => {
9624
+ const scrollToBottom = (0, import_react18.useCallback)(() => {
8884
9625
  isUserScrolledUpRef.current = false;
8885
9626
  setShowScrollButton(false);
8886
9627
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
8887
9628
  }, []);
8888
- const handleMouseUp = (0, import_react17.useCallback)(() => {
9629
+ const handleMouseUp = (0, import_react18.useCallback)(() => {
8889
9630
  const selection = typeof window !== "undefined" ? window.getSelection() : null;
8890
9631
  const text = selection?.toString().trim();
8891
9632
  if (text && text.length > 0) {
@@ -8919,7 +9660,7 @@ var MessageList = ({
8919
9660
  }
8920
9661
  }
8921
9662
  };
8922
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
9663
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
8923
9664
  "div",
8924
9665
  {
8925
9666
  ref: containerRef,
@@ -8932,7 +9673,7 @@ var MessageList = ({
8932
9673
  onScroll: handleScroll,
8933
9674
  onMouseUp: handleMouseUp,
8934
9675
  children: [
8935
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
9676
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
8936
9677
  "div",
8937
9678
  {
8938
9679
  style: {
@@ -8947,7 +9688,7 @@ var MessageList = ({
8947
9688
  const nextAssistant = message.role === "user" && index + 1 < messages.length ? messages[index + 1] : null;
8948
9689
  const assistantForAlts = nextAssistant?.role === "assistant" ? nextAssistant : null;
8949
9690
  const activeAltIndex = assistantForAlts ? activeAlternatives[assistantForAlts.id] ?? 0 : 0;
8950
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
9691
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
8951
9692
  MessageBubble,
8952
9693
  {
8953
9694
  message,
@@ -8973,16 +9714,19 @@ var MessageList = ({
8973
9714
  showThinking,
8974
9715
  thinkingDefaultOpen,
8975
9716
  isLoadingAlternative: loadingAlternativeFor === message.id,
8976
- onPollSubmit: message.role === "assistant" && onPollSubmit ? (response) => onPollSubmit(message.id, response) : void 0
9717
+ onPollSubmit: message.role === "assistant" && onPollSubmit ? (response) => onPollSubmit(message.id, response) : void 0,
9718
+ onChecklistAbort: message.role === "assistant" && onChecklistAbort ? onChecklistAbort : void 0,
9719
+ onChecklistRetry: message.role === "assistant" && onChecklistRetry ? (stepIndex) => onChecklistRetry(message.id, stepIndex) : void 0,
9720
+ onChecklistSkip: message.role === "assistant" && onChecklistSkip ? (stepIndex) => onChecklistSkip(message.id, stepIndex) : void 0
8977
9721
  },
8978
9722
  message.id
8979
9723
  );
8980
9724
  }),
8981
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: messagesEndRef })
9725
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { ref: messagesEndRef })
8982
9726
  ]
8983
9727
  }
8984
9728
  ),
8985
- showScrollButton && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
9729
+ showScrollButton && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
8986
9730
  "button",
8987
9731
  {
8988
9732
  onClick: scrollToBottom,
@@ -9005,10 +9749,10 @@ var MessageList = ({
9005
9749
  zIndex: 10,
9006
9750
  transition: "opacity 0.2s"
9007
9751
  },
9008
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(IconSvg, { name: "arrow-down-s-line", size: 24, color: "var(--chatllm-text-secondary)" })
9752
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconSvg, { name: "arrow-down-s-line", size: 24, color: "var(--chatllm-text-secondary)" })
9009
9753
  }
9010
9754
  ),
9011
- selectionPosition && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
9755
+ selectionPosition && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
9012
9756
  "div",
9013
9757
  {
9014
9758
  style: {
@@ -9020,7 +9764,7 @@ var MessageList = ({
9020
9764
  pointerEvents: "auto"
9021
9765
  },
9022
9766
  children: [
9023
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
9767
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
9024
9768
  "button",
9025
9769
  {
9026
9770
  onClick: handleQuote,
@@ -9040,12 +9784,12 @@ var MessageList = ({
9040
9784
  whiteSpace: "nowrap"
9041
9785
  },
9042
9786
  children: [
9043
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(IconSvg, { name: "double-quotes-l", size: 16, color: "#ffffff" }),
9787
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconSvg, { name: "double-quotes-l", size: 16, color: "#ffffff" }),
9044
9788
  "\uC778\uC6A9\uD558\uAE30"
9045
9789
  ]
9046
9790
  }
9047
9791
  ),
9048
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
9792
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
9049
9793
  "div",
9050
9794
  {
9051
9795
  style: {
@@ -9070,8 +9814,8 @@ var MessageList = ({
9070
9814
  };
9071
9815
 
9072
9816
  // src/react/components/SettingsModal.tsx
9073
- var import_react18 = require("react");
9074
- var import_jsx_runtime17 = require("react/jsx-runtime");
9817
+ var import_react19 = require("react");
9818
+ var import_jsx_runtime18 = require("react/jsx-runtime");
9075
9819
  var DEFAULT_PERSONALIZATION2 = {
9076
9820
  responseStyle: {
9077
9821
  warmth: "medium",
@@ -9106,9 +9850,9 @@ var SettingsModal = ({
9106
9850
  currentProjectTitle,
9107
9851
  showMemoryTab = true
9108
9852
  }) => {
9109
- const [activeTab, setActiveTab] = (0, import_react18.useState)("general");
9110
- const [localApiKey, setLocalApiKey] = (0, import_react18.useState)(apiKey);
9111
- (0, import_react18.useEffect)(() => {
9853
+ const [activeTab, setActiveTab] = (0, import_react19.useState)("general");
9854
+ const [localApiKey, setLocalApiKey] = (0, import_react19.useState)(apiKey);
9855
+ (0, import_react19.useEffect)(() => {
9112
9856
  setLocalApiKey(apiKey);
9113
9857
  }, [apiKey]);
9114
9858
  if (!isOpen) return null;
@@ -9134,7 +9878,7 @@ var SettingsModal = ({
9134
9878
  setLocalApiKey(value);
9135
9879
  onApiKeyChange?.(value);
9136
9880
  };
9137
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
9881
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9138
9882
  "div",
9139
9883
  {
9140
9884
  className: "chatllm-settings-overlay",
@@ -9148,7 +9892,7 @@ var SettingsModal = ({
9148
9892
  zIndex: 1e3
9149
9893
  },
9150
9894
  onClick: onClose,
9151
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
9895
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
9152
9896
  "div",
9153
9897
  {
9154
9898
  className: "chatllm-settings-modal",
@@ -9166,7 +9910,7 @@ var SettingsModal = ({
9166
9910
  },
9167
9911
  onClick: (e) => e.stopPropagation(),
9168
9912
  children: [
9169
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
9913
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
9170
9914
  "div",
9171
9915
  {
9172
9916
  style: {
@@ -9177,7 +9921,7 @@ var SettingsModal = ({
9177
9921
  flexDirection: "column"
9178
9922
  },
9179
9923
  children: [
9180
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { padding: "16px", borderBottom: "1px solid var(--chatllm-border, #e5e7eb)" }, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
9924
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { padding: "16px", borderBottom: "1px solid var(--chatllm-border, #e5e7eb)" }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9181
9925
  "button",
9182
9926
  {
9183
9927
  onClick: onClose,
@@ -9191,11 +9935,11 @@ var SettingsModal = ({
9191
9935
  alignItems: "center",
9192
9936
  justifyContent: "center"
9193
9937
  },
9194
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconSvg, { name: "close-line", size: 20, color: "var(--chatllm-text-muted, #6b7280)" })
9938
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconSvg, { name: "close-line", size: 20, color: "var(--chatllm-text-muted, #6b7280)" })
9195
9939
  }
9196
9940
  ) }),
9197
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("nav", { style: { flex: 1, padding: "8px" }, children: [
9198
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
9941
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("nav", { style: { flex: 1, padding: "8px" }, children: [
9942
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9199
9943
  TabButton,
9200
9944
  {
9201
9945
  active: activeTab === "general",
@@ -9204,7 +9948,7 @@ var SettingsModal = ({
9204
9948
  label: "\uC77C\uBC18"
9205
9949
  }
9206
9950
  ),
9207
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
9951
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9208
9952
  TabButton,
9209
9953
  {
9210
9954
  active: activeTab === "personalization",
@@ -9213,7 +9957,7 @@ var SettingsModal = ({
9213
9957
  label: "\uAC1C\uC778 \uB9DE\uCDA4 \uC124\uC815"
9214
9958
  }
9215
9959
  ),
9216
- showMemoryTab && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
9960
+ showMemoryTab && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9217
9961
  TabButton,
9218
9962
  {
9219
9963
  active: activeTab === "memory",
@@ -9222,7 +9966,7 @@ var SettingsModal = ({
9222
9966
  label: "AI \uBA54\uBAA8\uB9AC"
9223
9967
  }
9224
9968
  ),
9225
- showMemoryTab && enableProjects && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
9969
+ showMemoryTab && enableProjects && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9226
9970
  TabButton,
9227
9971
  {
9228
9972
  active: activeTab === "project-memory",
@@ -9231,7 +9975,7 @@ var SettingsModal = ({
9231
9975
  label: "\uD504\uB85C\uC81D\uD2B8 \uBA54\uBAA8\uB9AC"
9232
9976
  }
9233
9977
  ),
9234
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
9978
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9235
9979
  TabButton,
9236
9980
  {
9237
9981
  active: activeTab === "data",
@@ -9244,24 +9988,24 @@ var SettingsModal = ({
9244
9988
  ]
9245
9989
  }
9246
9990
  ),
9247
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { flex: 1, overflow: "auto", padding: "24px" }, children: [
9248
- activeTab === "general" && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
9249
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h2", { style: { fontSize: "20px", fontWeight: 600, marginBottom: "24px", color: "var(--chatllm-text, #1f2937)" }, children: "\uC77C\uBC18" }),
9250
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SettingRow, { label: "\uC5B8\uC5B4", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
9991
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { flex: 1, overflow: "auto", padding: "24px" }, children: [
9992
+ activeTab === "general" && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
9993
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h2", { style: { fontSize: "20px", fontWeight: 600, marginBottom: "24px", color: "var(--chatllm-text, #1f2937)" }, children: "\uC77C\uBC18" }),
9994
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SettingRow, { label: "\uC5B8\uC5B4", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
9251
9995
  "select",
9252
9996
  {
9253
9997
  value: personalization.language,
9254
9998
  onChange: (e) => onPersonalizationChange({ ...personalization, language: e.target.value }),
9255
9999
  style: selectStyle,
9256
10000
  children: [
9257
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "auto", children: "\uC790\uB3D9 \uD0D0\uC9C0" }),
9258
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "ko", children: "\uD55C\uAD6D\uC5B4" }),
9259
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "en", children: "English" }),
9260
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "ja", children: "\u65E5\u672C\u8A9E" })
10001
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: "auto", children: "\uC790\uB3D9 \uD0D0\uC9C0" }),
10002
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: "ko", children: "\uD55C\uAD6D\uC5B4" }),
10003
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: "en", children: "English" }),
10004
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: "ja", children: "\u65E5\u672C\u8A9E" })
9261
10005
  ]
9262
10006
  }
9263
10007
  ) }),
9264
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SettingRow, { label: "\uAE30\uBCF8\uAC12\uC73C\uB85C \uCD08\uAE30\uD654", description: "\uBAA8\uB4E0 \uC124\uC815\uC744 \uCD08\uAE30 \uC0C1\uD0DC\uB85C \uB418\uB3CC\uB9BD\uB2C8\uB2E4", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10008
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SettingRow, { label: "\uAE30\uBCF8\uAC12\uC73C\uB85C \uCD08\uAE30\uD654", description: "\uBAA8\uB4E0 \uC124\uC815\uC744 \uCD08\uAE30 \uC0C1\uD0DC\uB85C \uB418\uB3CC\uB9BD\uB2C8\uB2E4", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9265
10009
  "button",
9266
10010
  {
9267
10011
  onClick: () => onPersonalizationChange(DEFAULT_PERSONALIZATION2),
@@ -9269,11 +10013,11 @@ var SettingsModal = ({
9269
10013
  children: "\uCD08\uAE30\uD654"
9270
10014
  }
9271
10015
  ) }),
9272
- onApiKeyChange && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { marginTop: "32px", paddingTop: "24px", borderTop: "1px solid var(--chatllm-border, #e5e7eb)" }, children: [
9273
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h3", { style: { fontSize: "16px", fontWeight: 500, marginBottom: "16px", color: "var(--chatllm-text, #1f2937)" }, children: "API \uC124\uC815" }),
9274
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
9275
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { style: { display: "block", fontSize: "14px", marginBottom: "8px", color: "var(--chatllm-text, #374151)" }, children: apiKeyLabel }),
9276
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10016
+ onApiKeyChange && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { marginTop: "32px", paddingTop: "24px", borderTop: "1px solid var(--chatllm-border, #e5e7eb)" }, children: [
10017
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h3", { style: { fontSize: "16px", fontWeight: 500, marginBottom: "16px", color: "var(--chatllm-text, #1f2937)" }, children: "API \uC124\uC815" }),
10018
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
10019
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("label", { style: { display: "block", fontSize: "14px", marginBottom: "8px", color: "var(--chatllm-text, #374151)" }, children: apiKeyLabel }),
10020
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9277
10021
  "input",
9278
10022
  {
9279
10023
  type: "password",
@@ -9283,18 +10027,18 @@ var SettingsModal = ({
9283
10027
  style: inputStyle
9284
10028
  }
9285
10029
  ),
9286
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { style: { fontSize: "12px", color: "var(--chatllm-text-muted, #9ca3af)", marginTop: "4px" }, children: apiKeyDescription })
10030
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { style: { fontSize: "12px", color: "var(--chatllm-text-muted, #9ca3af)", marginTop: "4px" }, children: apiKeyDescription })
9287
10031
  ] })
9288
10032
  ] })
9289
10033
  ] }),
9290
- activeTab === "personalization" && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
9291
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h2", { style: { fontSize: "20px", fontWeight: 600, marginBottom: "24px", color: "var(--chatllm-text, #1f2937)" }, children: "\uAC1C\uC778 \uB9DE\uCDA4 \uC124\uC815" }),
9292
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("section", { style: { marginBottom: "32px" }, children: [
9293
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h3", { style: { fontSize: "14px", fontWeight: 500, color: "var(--chatllm-text-muted, #6b7280)", marginBottom: "16px" }, children: "\uC0AC\uC6A9\uC790 \uD504\uB85C\uD544" }),
9294
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
9295
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
9296
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { style: labelStyle, children: "\uB2C9\uB124\uC784" }),
9297
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10034
+ activeTab === "personalization" && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
10035
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h2", { style: { fontSize: "20px", fontWeight: 600, marginBottom: "24px", color: "var(--chatllm-text, #1f2937)" }, children: "\uAC1C\uC778 \uB9DE\uCDA4 \uC124\uC815" }),
10036
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("section", { style: { marginBottom: "32px" }, children: [
10037
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h3", { style: { fontSize: "14px", fontWeight: 500, color: "var(--chatllm-text-muted, #6b7280)", marginBottom: "16px" }, children: "\uC0AC\uC6A9\uC790 \uD504\uB85C\uD544" }),
10038
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
10039
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
10040
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("label", { style: labelStyle, children: "\uB2C9\uB124\uC784" }),
10041
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9298
10042
  "input",
9299
10043
  {
9300
10044
  type: "text",
@@ -9305,9 +10049,9 @@ var SettingsModal = ({
9305
10049
  }
9306
10050
  )
9307
10051
  ] }),
9308
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
9309
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { style: labelStyle, children: "\uC9C1\uC5C5" }),
9310
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10052
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
10053
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("label", { style: labelStyle, children: "\uC9C1\uC5C5" }),
10054
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9311
10055
  "input",
9312
10056
  {
9313
10057
  type: "text",
@@ -9318,9 +10062,9 @@ var SettingsModal = ({
9318
10062
  }
9319
10063
  )
9320
10064
  ] }),
9321
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
9322
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { style: labelStyle, children: "\uCD94\uAC00 \uC815\uBCF4" }),
9323
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10065
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
10066
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("label", { style: labelStyle, children: "\uCD94\uAC00 \uC815\uBCF4" }),
10067
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9324
10068
  "textarea",
9325
10069
  {
9326
10070
  value: personalization.userProfile.additionalInfo || "",
@@ -9333,62 +10077,62 @@ var SettingsModal = ({
9333
10077
  ] })
9334
10078
  ] })
9335
10079
  ] }),
9336
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("section", { children: [
9337
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h3", { style: { fontSize: "14px", fontWeight: 500, color: "var(--chatllm-text-muted, #6b7280)", marginBottom: "16px" }, children: "\uC751\uB2F5 \uC2A4\uD0C0\uC77C" }),
9338
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SettingRow, { label: "\uB530\uB73B\uD568", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
10080
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("section", { children: [
10081
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h3", { style: { fontSize: "14px", fontWeight: 500, color: "var(--chatllm-text-muted, #6b7280)", marginBottom: "16px" }, children: "\uC751\uB2F5 \uC2A4\uD0C0\uC77C" }),
10082
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SettingRow, { label: "\uB530\uB73B\uD568", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
9339
10083
  "select",
9340
10084
  {
9341
10085
  value: personalization.responseStyle.warmth,
9342
10086
  onChange: (e) => updateResponseStyle("warmth", e.target.value),
9343
10087
  style: selectStyle,
9344
10088
  children: [
9345
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "high", children: "\uB192\uC74C - \uCE5C\uADFC\uD558\uACE0 \uB530\uB73B\uD558\uAC8C" }),
9346
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "medium", children: "\uAE30\uBCF8\uAC12" }),
9347
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "low", children: "\uB0AE\uC74C - \uAC04\uACB0\uD558\uACE0 \uC0AC\uBB34\uC801\uC73C\uB85C" })
10089
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: "high", children: "\uB192\uC74C - \uCE5C\uADFC\uD558\uACE0 \uB530\uB73B\uD558\uAC8C" }),
10090
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: "medium", children: "\uAE30\uBCF8\uAC12" }),
10091
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: "low", children: "\uB0AE\uC74C - \uAC04\uACB0\uD558\uACE0 \uC0AC\uBB34\uC801\uC73C\uB85C" })
9348
10092
  ]
9349
10093
  }
9350
10094
  ) }),
9351
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SettingRow, { label: "\uC5F4\uC815\uC801", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
10095
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SettingRow, { label: "\uC5F4\uC815\uC801", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
9352
10096
  "select",
9353
10097
  {
9354
10098
  value: personalization.responseStyle.enthusiasm,
9355
10099
  onChange: (e) => updateResponseStyle("enthusiasm", e.target.value),
9356
10100
  style: selectStyle,
9357
10101
  children: [
9358
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "high", children: "\uB192\uC74C - \uC801\uADF9\uC801\uC774\uACE0 \uD65C\uBC1C\uD558\uAC8C" }),
9359
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "medium", children: "\uAE30\uBCF8\uAC12" }),
9360
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "low", children: "\uB0AE\uC74C - \uCC28\uBD84\uD558\uACE0 \uC808\uC81C\uC788\uAC8C" })
10102
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: "high", children: "\uB192\uC74C - \uC801\uADF9\uC801\uC774\uACE0 \uD65C\uBC1C\uD558\uAC8C" }),
10103
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: "medium", children: "\uAE30\uBCF8\uAC12" }),
10104
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: "low", children: "\uB0AE\uC74C - \uCC28\uBD84\uD558\uACE0 \uC808\uC81C\uC788\uAC8C" })
9361
10105
  ]
9362
10106
  }
9363
10107
  ) }),
9364
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SettingRow, { label: "\uC774\uBAA8\uC9C0 \uC0AC\uC6A9", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
10108
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SettingRow, { label: "\uC774\uBAA8\uC9C0 \uC0AC\uC6A9", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
9365
10109
  "select",
9366
10110
  {
9367
10111
  value: personalization.responseStyle.emojiUsage,
9368
10112
  onChange: (e) => updateResponseStyle("emojiUsage", e.target.value),
9369
10113
  style: selectStyle,
9370
10114
  children: [
9371
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "high", children: "\uB192\uC74C - \uC790\uC8FC \uC0AC\uC6A9" }),
9372
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "medium", children: "\uAE30\uBCF8\uAC12" }),
9373
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "low", children: "\uB0AE\uC74C - \uAC70\uC758 \uC0AC\uC6A9 \uC548 \uD568" })
10115
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: "high", children: "\uB192\uC74C - \uC790\uC8FC \uC0AC\uC6A9" }),
10116
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: "medium", children: "\uAE30\uBCF8\uAC12" }),
10117
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: "low", children: "\uB0AE\uC74C - \uAC70\uC758 \uC0AC\uC6A9 \uC548 \uD568" })
9374
10118
  ]
9375
10119
  }
9376
10120
  ) }),
9377
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SettingRow, { label: "\uC751\uB2F5 \uAE38\uC774", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
10121
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SettingRow, { label: "\uC751\uB2F5 \uAE38\uC774", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
9378
10122
  "select",
9379
10123
  {
9380
10124
  value: personalization.responseStyle.verbosity,
9381
10125
  onChange: (e) => updateResponseStyle("verbosity", e.target.value),
9382
10126
  style: selectStyle,
9383
10127
  children: [
9384
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "detailed", children: "\uC0C1\uC138 - \uC790\uC138\uD558\uAC8C \uC124\uBA85" }),
9385
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "balanced", children: "\uAE30\uBCF8\uAC12" }),
9386
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "concise", children: "\uAC04\uACB0 - \uD575\uC2EC\uB9CC \uC694\uC57D" })
10128
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: "detailed", children: "\uC0C1\uC138 - \uC790\uC138\uD558\uAC8C \uC124\uBA85" }),
10129
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: "balanced", children: "\uAE30\uBCF8\uAC12" }),
10130
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("option", { value: "concise", children: "\uAC04\uACB0 - \uD575\uC2EC\uB9CC \uC694\uC57D" })
9387
10131
  ]
9388
10132
  }
9389
10133
  ) })
9390
10134
  ] }),
9391
- onSave && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { marginTop: "24px", display: "flex", justifyContent: "flex-end" }, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10135
+ onSave && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { marginTop: "24px", display: "flex", justifyContent: "flex-end" }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9392
10136
  "button",
9393
10137
  {
9394
10138
  onClick: onSave,
@@ -9409,7 +10153,7 @@ var SettingsModal = ({
9409
10153
  }
9410
10154
  ) })
9411
10155
  ] }),
9412
- activeTab === "memory" && showMemoryTab && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10156
+ activeTab === "memory" && showMemoryTab && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9413
10157
  MemoryTabContent,
9414
10158
  {
9415
10159
  items: memoryItems,
@@ -9418,7 +10162,7 @@ var SettingsModal = ({
9418
10162
  onClearAll: onClearMemory
9419
10163
  }
9420
10164
  ),
9421
- activeTab === "project-memory" && showMemoryTab && enableProjects && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10165
+ activeTab === "project-memory" && showMemoryTab && enableProjects && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9422
10166
  MemoryTabContent,
9423
10167
  {
9424
10168
  items: projectMemoryItems,
@@ -9429,9 +10173,9 @@ var SettingsModal = ({
9429
10173
  emptyDescription: "\uB300\uD654\uAC00 \uC9C4\uD589\uB418\uBA74 AI\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB9E5\uB77D\uC744 \uC790\uB3D9\uC73C\uB85C \uD559\uC2B5\uD569\uB2C8\uB2E4"
9430
10174
  }
9431
10175
  ),
9432
- activeTab === "data" && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
9433
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h2", { style: { fontSize: "20px", fontWeight: 600, marginBottom: "24px", color: "var(--chatllm-text, #1f2937)" }, children: "\uB370\uC774\uD130 \uC81C\uC5B4" }),
9434
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SettingRow, { label: "\uBA54\uBAA8\uB9AC \uC0AC\uC6A9", description: "\uB300\uD654 \uCEE8\uD14D\uC2A4\uD2B8\uB97C \uAE30\uC5B5\uD569\uB2C8\uB2E4", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10176
+ activeTab === "data" && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
10177
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h2", { style: { fontSize: "20px", fontWeight: 600, marginBottom: "24px", color: "var(--chatllm-text, #1f2937)" }, children: "\uB370\uC774\uD130 \uC81C\uC5B4" }),
10178
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SettingRow, { label: "\uBA54\uBAA8\uB9AC \uC0AC\uC6A9", description: "\uB300\uD654 \uCEE8\uD14D\uC2A4\uD2B8\uB97C \uAE30\uC5B5\uD569\uB2C8\uB2E4", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9435
10179
  "button",
9436
10180
  {
9437
10181
  onClick: () => onPersonalizationChange({ ...personalization, useMemory: !personalization.useMemory }),
@@ -9445,7 +10189,7 @@ var SettingsModal = ({
9445
10189
  position: "relative",
9446
10190
  transition: "background-color 0.2s"
9447
10191
  },
9448
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10192
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9449
10193
  "div",
9450
10194
  {
9451
10195
  style: {
@@ -9463,7 +10207,7 @@ var SettingsModal = ({
9463
10207
  )
9464
10208
  }
9465
10209
  ) }),
9466
- onClearAllData && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SettingRow, { label: "\uB300\uD654 \uAE30\uB85D \uC0AD\uC81C", description: "\uBAA8\uB4E0 \uB300\uD654 \uAE30\uB85D\uC744 \uC0AD\uC81C\uD569\uB2C8\uB2E4", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10210
+ onClearAllData && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SettingRow, { label: "\uB300\uD654 \uAE30\uB85D \uC0AD\uC81C", description: "\uBAA8\uB4E0 \uB300\uD654 \uAE30\uB85D\uC744 \uC0AD\uC81C\uD569\uB2C8\uB2E4", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9467
10211
  "button",
9468
10212
  {
9469
10213
  onClick: () => {
@@ -9483,7 +10227,7 @@ var SettingsModal = ({
9483
10227
  }
9484
10228
  );
9485
10229
  };
9486
- var TabButton = ({ active, onClick, icon, label }) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
10230
+ var TabButton = ({ active, onClick, icon, label }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
9487
10231
  "button",
9488
10232
  {
9489
10233
  onClick,
@@ -9504,12 +10248,12 @@ var TabButton = ({ active, onClick, icon, label }) => /* @__PURE__ */ (0, import
9504
10248
  marginBottom: "4px"
9505
10249
  },
9506
10250
  children: [
9507
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconSvg, { name: icon, size: 20 }),
10251
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconSvg, { name: icon, size: 20 }),
9508
10252
  label
9509
10253
  ]
9510
10254
  }
9511
10255
  );
9512
- var SettingRow = ({ label, description, children }) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
10256
+ var SettingRow = ({ label, description, children }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
9513
10257
  "div",
9514
10258
  {
9515
10259
  style: {
@@ -9520,9 +10264,9 @@ var SettingRow = ({ label, description, children }) => /* @__PURE__ */ (0, impor
9520
10264
  borderBottom: "1px solid var(--chatllm-border-light, #f3f4f6)"
9521
10265
  },
9522
10266
  children: [
9523
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
9524
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: { fontSize: "14px", color: "var(--chatllm-text, #374151)" }, children: label }),
9525
- description && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { style: { fontSize: "12px", color: "var(--chatllm-text-muted, #9ca3af)", marginTop: "2px" }, children: description })
10267
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
10268
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: { fontSize: "14px", color: "var(--chatllm-text, #374151)" }, children: label }),
10269
+ description && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { style: { fontSize: "12px", color: "var(--chatllm-text-muted, #9ca3af)", marginTop: "2px" }, children: description })
9526
10270
  ] }),
9527
10271
  children
9528
10272
  ]
@@ -9582,8 +10326,8 @@ var memoryCategoryColors = {
9582
10326
  preference: "#8b5cf6"
9583
10327
  };
9584
10328
  var MemoryTabContent = ({ items, contextSummary, onDelete, onClearAll, title = "AI \uBA54\uBAA8\uB9AC", emptyMessage = "\uC800\uC7A5\uB41C \uBA54\uBAA8\uB9AC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4", emptyDescription = "\uB300\uD654\uAC00 \uC9C4\uD589\uB418\uBA74 AI\uAC00 \uC790\uB3D9\uC73C\uB85C \uC815\uBCF4\uB97C \uD559\uC2B5\uD569\uB2C8\uB2E4" }) => {
9585
- const [activeFilter, setActiveFilter] = (0, import_react18.useState)("all");
9586
- const [expandedId, setExpandedId] = (0, import_react18.useState)(null);
10329
+ const [activeFilter, setActiveFilter] = (0, import_react19.useState)("all");
10330
+ const [expandedId, setExpandedId] = (0, import_react19.useState)(null);
9587
10331
  const filteredItems = activeFilter === "all" ? items : items.filter((item) => item.category === activeFilter);
9588
10332
  const formatDate = (timestamp) => {
9589
10333
  const date = new Date(timestamp);
@@ -9594,15 +10338,15 @@ var MemoryTabContent = ({ items, contextSummary, onDelete, onClearAll, title = "
9594
10338
  minute: "2-digit"
9595
10339
  });
9596
10340
  };
9597
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
9598
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: "24px" }, children: [
9599
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h2", { style: { fontSize: "20px", fontWeight: 600, color: "var(--chatllm-text, #1f2937)", margin: 0 }, children: title }),
9600
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { style: { fontSize: "13px", color: "var(--chatllm-text-muted, #9ca3af)" }, children: [
10341
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
10342
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: "24px" }, children: [
10343
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h2", { style: { fontSize: "20px", fontWeight: 600, color: "var(--chatllm-text, #1f2937)", margin: 0 }, children: title }),
10344
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { style: { fontSize: "13px", color: "var(--chatllm-text-muted, #9ca3af)" }, children: [
9601
10345
  items.length,
9602
10346
  "\uAC1C \uD56D\uBAA9"
9603
10347
  ] })
9604
10348
  ] }),
9605
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { display: "flex", gap: "6px", marginBottom: "20px", flexWrap: "wrap" }, children: ["all", "fact", "skill", "preference"].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10349
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { display: "flex", gap: "6px", marginBottom: "20px", flexWrap: "wrap" }, children: ["all", "fact", "skill", "preference"].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9606
10350
  "button",
9607
10351
  {
9608
10352
  onClick: () => setActiveFilter(tab),
@@ -9620,7 +10364,7 @@ var MemoryTabContent = ({ items, contextSummary, onDelete, onClearAll, title = "
9620
10364
  },
9621
10365
  tab
9622
10366
  )) }),
9623
- contextSummary && activeFilter === "all" && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
10367
+ contextSummary && activeFilter === "all" && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
9624
10368
  "div",
9625
10369
  {
9626
10370
  style: {
@@ -9631,19 +10375,19 @@ var MemoryTabContent = ({ items, contextSummary, onDelete, onClearAll, title = "
9631
10375
  borderLeft: "3px solid var(--chatllm-primary, #3584FA)"
9632
10376
  },
9633
10377
  children: [
9634
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "6px", marginBottom: "8px" }, children: [
9635
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconSvg, { name: "file-text-line", size: 14, color: "var(--chatllm-primary, #3584FA)" }),
9636
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: { fontSize: "12px", fontWeight: 500, color: "var(--chatllm-primary, #3584FA)" }, children: "\uB300\uD654 \uC694\uC57D" })
10378
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "6px", marginBottom: "8px" }, children: [
10379
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconSvg, { name: "file-text-line", size: 14, color: "var(--chatllm-primary, #3584FA)" }),
10380
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: { fontSize: "12px", fontWeight: 500, color: "var(--chatllm-primary, #3584FA)" }, children: "\uB300\uD654 \uC694\uC57D" })
9637
10381
  ] }),
9638
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { style: { fontSize: "13px", lineHeight: "1.6", color: "var(--chatllm-text, #374151)", margin: 0 }, children: contextSummary })
10382
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { style: { fontSize: "13px", lineHeight: "1.6", color: "var(--chatllm-text, #374151)", margin: 0 }, children: contextSummary })
9639
10383
  ]
9640
10384
  }
9641
10385
  ),
9642
- filteredItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { padding: "40px 16px", textAlign: "center" }, children: [
9643
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconSvg, { name: "robot-line", size: 40, color: "var(--chatllm-text-muted, #d1d5db)" }),
9644
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { style: { fontSize: "14px", color: "var(--chatllm-text-muted, #9ca3af)", marginTop: "12px" }, children: emptyMessage }),
9645
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { style: { fontSize: "12px", color: "var(--chatllm-text-muted, #d1d5db)", marginTop: "4px" }, children: emptyDescription })
9646
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: filteredItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
10386
+ filteredItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { padding: "40px 16px", textAlign: "center" }, children: [
10387
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconSvg, { name: "robot-line", size: 40, color: "var(--chatllm-text-muted, #d1d5db)" }),
10388
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { style: { fontSize: "14px", color: "var(--chatllm-text-muted, #9ca3af)", marginTop: "12px" }, children: emptyMessage }),
10389
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { style: { fontSize: "12px", color: "var(--chatllm-text-muted, #d1d5db)", marginTop: "4px" }, children: emptyDescription })
10390
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: filteredItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
9647
10391
  "div",
9648
10392
  {
9649
10393
  style: {
@@ -9656,10 +10400,10 @@ var MemoryTabContent = ({ items, contextSummary, onDelete, onClearAll, title = "
9656
10400
  },
9657
10401
  onClick: () => setExpandedId(expandedId === item.id ? null : item.id),
9658
10402
  children: [
9659
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { display: "flex", alignItems: "flex-start", justifyContent: "space-between" }, children: [
9660
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
9661
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px", marginBottom: "4px" }, children: [
9662
- item.category && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10403
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", alignItems: "flex-start", justifyContent: "space-between" }, children: [
10404
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
10405
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px", marginBottom: "4px" }, children: [
10406
+ item.category && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9663
10407
  "span",
9664
10408
  {
9665
10409
  style: {
@@ -9673,12 +10417,12 @@ var MemoryTabContent = ({ items, contextSummary, onDelete, onClearAll, title = "
9673
10417
  children: memoryCategoryLabels[item.category]
9674
10418
  }
9675
10419
  ),
9676
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: { fontSize: "11px", color: "var(--chatllm-text-muted, #9ca3af)" }, children: formatDate(item.timestamp) })
10420
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: { fontSize: "11px", color: "var(--chatllm-text-muted, #9ca3af)" }, children: formatDate(item.timestamp) })
9677
10421
  ] }),
9678
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { fontSize: "13px", fontWeight: 500, color: "var(--chatllm-text, #1f2937)" }, children: item.key })
10422
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { fontSize: "13px", fontWeight: 500, color: "var(--chatllm-text, #1f2937)" }, children: item.key })
9679
10423
  ] }),
9680
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [
9681
- onDelete && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10424
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [
10425
+ onDelete && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9682
10426
  "button",
9683
10427
  {
9684
10428
  onClick: (e) => {
@@ -9694,10 +10438,10 @@ var MemoryTabContent = ({ items, contextSummary, onDelete, onClearAll, title = "
9694
10438
  opacity: 0.5
9695
10439
  },
9696
10440
  "aria-label": "\uBA54\uBAA8\uB9AC \uC0AD\uC81C",
9697
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconSvg, { name: "delete-bin-line", size: 14, color: "var(--chatllm-text-muted, #9ca3af)" })
10441
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconSvg, { name: "delete-bin-line", size: 14, color: "var(--chatllm-text-muted, #9ca3af)" })
9698
10442
  }
9699
10443
  ),
9700
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10444
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9701
10445
  IconSvg,
9702
10446
  {
9703
10447
  name: expandedId === item.id ? "arrow-up-s-line" : "arrow-down-s-line",
@@ -9707,7 +10451,7 @@ var MemoryTabContent = ({ items, contextSummary, onDelete, onClearAll, title = "
9707
10451
  )
9708
10452
  ] })
9709
10453
  ] }),
9710
- expandedId === item.id && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10454
+ expandedId === item.id && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9711
10455
  "div",
9712
10456
  {
9713
10457
  style: {
@@ -9715,7 +10459,7 @@ var MemoryTabContent = ({ items, contextSummary, onDelete, onClearAll, title = "
9715
10459
  paddingTop: "12px",
9716
10460
  borderTop: "1px solid var(--chatllm-border-light, #f3f4f6)"
9717
10461
  },
9718
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10462
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9719
10463
  "p",
9720
10464
  {
9721
10465
  style: {
@@ -9734,7 +10478,7 @@ var MemoryTabContent = ({ items, contextSummary, onDelete, onClearAll, title = "
9734
10478
  },
9735
10479
  item.id
9736
10480
  )) }),
9737
- onClearAll && items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { style: { marginTop: "24px", paddingTop: "16px", borderTop: "1px solid var(--chatllm-border, #e5e7eb)" }, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
10481
+ onClearAll && items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { marginTop: "24px", paddingTop: "16px", borderTop: "1px solid var(--chatllm-border, #e5e7eb)" }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9738
10482
  "button",
9739
10483
  {
9740
10484
  onClick: () => {
@@ -9750,8 +10494,8 @@ var MemoryTabContent = ({ items, contextSummary, onDelete, onClearAll, title = "
9750
10494
  };
9751
10495
 
9752
10496
  // src/react/components/ProjectSettingsModal.tsx
9753
- var import_react19 = require("react");
9754
- var import_jsx_runtime18 = require("react/jsx-runtime");
10497
+ var import_react20 = require("react");
10498
+ var import_jsx_runtime19 = require("react/jsx-runtime");
9755
10499
  var COLOR_PRESETS = [
9756
10500
  "#3584FA",
9757
10501
  "#7c3aed",
@@ -9771,12 +10515,12 @@ var ProjectSettingsModal = ({
9771
10515
  onDeleteFile,
9772
10516
  onDeleteProject
9773
10517
  }) => {
9774
- const [activeTab, setActiveTab] = (0, import_react19.useState)("general");
9775
- const [title, setTitle] = (0, import_react19.useState)("");
9776
- const [description, setDescription] = (0, import_react19.useState)("");
9777
- const [instructions, setInstructions] = (0, import_react19.useState)("");
9778
- const [color, setColor] = (0, import_react19.useState)("#3584FA");
9779
- (0, import_react19.useEffect)(() => {
10518
+ const [activeTab, setActiveTab] = (0, import_react20.useState)("general");
10519
+ const [title, setTitle] = (0, import_react20.useState)("");
10520
+ const [description, setDescription] = (0, import_react20.useState)("");
10521
+ const [instructions, setInstructions] = (0, import_react20.useState)("");
10522
+ const [color, setColor] = (0, import_react20.useState)("#3584FA");
10523
+ (0, import_react20.useEffect)(() => {
9780
10524
  if (project) {
9781
10525
  setTitle(project.title);
9782
10526
  setDescription(project.description || "");
@@ -9832,7 +10576,7 @@ var ProjectSettingsModal = ({
9832
10576
  cursor: "pointer",
9833
10577
  fontFamily: "inherit"
9834
10578
  });
9835
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10579
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
9836
10580
  "div",
9837
10581
  {
9838
10582
  style: {
@@ -9847,7 +10591,7 @@ var ProjectSettingsModal = ({
9847
10591
  onClick: (e) => {
9848
10592
  if (e.target === e.currentTarget) onClose();
9849
10593
  },
9850
- children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
10594
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
9851
10595
  "div",
9852
10596
  {
9853
10597
  style: {
@@ -9861,7 +10605,7 @@ var ProjectSettingsModal = ({
9861
10605
  overflow: "hidden"
9862
10606
  },
9863
10607
  children: [
9864
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
10608
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
9865
10609
  "div",
9866
10610
  {
9867
10611
  style: {
@@ -9871,8 +10615,8 @@ var ProjectSettingsModal = ({
9871
10615
  padding: "20px 24px 0"
9872
10616
  },
9873
10617
  children: [
9874
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h2", { style: { fontSize: "16px", fontWeight: 600, margin: 0, color: "var(--chatllm-text, #1a1a1a)" }, children: "\uD504\uB85C\uC81D\uD2B8 \uC124\uC815" }),
9875
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10618
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h2", { style: { fontSize: "16px", fontWeight: 600, margin: 0, color: "var(--chatllm-text, #1a1a1a)" }, children: "\uD504\uB85C\uC81D\uD2B8 \uC124\uC815" }),
10619
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
9876
10620
  "button",
9877
10621
  {
9878
10622
  onClick: onClose,
@@ -9885,13 +10629,13 @@ var ProjectSettingsModal = ({
9885
10629
  alignItems: "center"
9886
10630
  },
9887
10631
  "aria-label": "\uB2EB\uAE30",
9888
- children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconSvg, { name: "close-line", size: 20, color: "var(--chatllm-text-muted, #999)" })
10632
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(IconSvg, { name: "close-line", size: 20, color: "var(--chatllm-text-muted, #999)" })
9889
10633
  }
9890
10634
  )
9891
10635
  ]
9892
10636
  }
9893
10637
  ),
9894
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
10638
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
9895
10639
  "div",
9896
10640
  {
9897
10641
  style: {
@@ -9901,9 +10645,9 @@ var ProjectSettingsModal = ({
9901
10645
  borderBottom: "1px solid var(--chatllm-border, #e0e0e0)"
9902
10646
  },
9903
10647
  children: [
9904
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { onClick: () => setActiveTab("general"), style: tabStyle("general"), children: "\uC77C\uBC18" }),
9905
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { onClick: () => setActiveTab("instructions"), style: tabStyle("instructions"), children: "\uC9C0\uCE68" }),
9906
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("button", { onClick: () => setActiveTab("files"), style: tabStyle("files"), children: [
10648
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { onClick: () => setActiveTab("general"), style: tabStyle("general"), children: "\uC77C\uBC18" }),
10649
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { onClick: () => setActiveTab("instructions"), style: tabStyle("instructions"), children: "\uC9C0\uCE68" }),
10650
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("button", { onClick: () => setActiveTab("files"), style: tabStyle("files"), children: [
9907
10651
  "\uD30C\uC77C (",
9908
10652
  project.files.length,
9909
10653
  ")"
@@ -9911,11 +10655,11 @@ var ProjectSettingsModal = ({
9911
10655
  ]
9912
10656
  }
9913
10657
  ),
9914
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { padding: "24px", overflowY: "auto", flex: 1 }, children: [
9915
- activeTab === "general" && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "16px" }, children: [
9916
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
9917
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("label", { style: { display: "block", fontSize: "13px", fontWeight: 500, marginBottom: "6px", color: "var(--chatllm-text, #1a1a1a)" }, children: "\uD504\uB85C\uC81D\uD2B8 \uC774\uB984" }),
9918
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10658
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { padding: "24px", overflowY: "auto", flex: 1 }, children: [
10659
+ activeTab === "general" && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "16px" }, children: [
10660
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { children: [
10661
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { style: { display: "block", fontSize: "13px", fontWeight: 500, marginBottom: "6px", color: "var(--chatllm-text, #1a1a1a)" }, children: "\uD504\uB85C\uC81D\uD2B8 \uC774\uB984" }),
10662
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
9919
10663
  "input",
9920
10664
  {
9921
10665
  type: "text",
@@ -9937,9 +10681,9 @@ var ProjectSettingsModal = ({
9937
10681
  }
9938
10682
  )
9939
10683
  ] }),
9940
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
9941
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("label", { style: { display: "block", fontSize: "13px", fontWeight: 500, marginBottom: "6px", color: "var(--chatllm-text, #1a1a1a)" }, children: "\uC124\uBA85" }),
9942
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10684
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { children: [
10685
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { style: { display: "block", fontSize: "13px", fontWeight: 500, marginBottom: "6px", color: "var(--chatllm-text, #1a1a1a)" }, children: "\uC124\uBA85" }),
10686
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
9943
10687
  "textarea",
9944
10688
  {
9945
10689
  value: description,
@@ -9960,9 +10704,9 @@ var ProjectSettingsModal = ({
9960
10704
  }
9961
10705
  )
9962
10706
  ] }),
9963
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
9964
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("label", { style: { display: "block", fontSize: "13px", fontWeight: 500, marginBottom: "6px", color: "var(--chatllm-text, #1a1a1a)" }, children: "\uC0C9\uC0C1" }),
9965
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap" }, children: COLOR_PRESETS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10707
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { children: [
10708
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { style: { display: "block", fontSize: "13px", fontWeight: 500, marginBottom: "6px", color: "var(--chatllm-text, #1a1a1a)" }, children: "\uC0C9\uC0C1" }),
10709
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap" }, children: COLOR_PRESETS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
9966
10710
  "button",
9967
10711
  {
9968
10712
  onClick: () => setColor(c),
@@ -9980,8 +10724,8 @@ var ProjectSettingsModal = ({
9980
10724
  c
9981
10725
  )) })
9982
10726
  ] }),
9983
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", gap: "8px", justifyContent: "flex-end", marginTop: "8px" }, children: [
9984
- !isDefaultProject && onDeleteProject && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10727
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", gap: "8px", justifyContent: "flex-end", marginTop: "8px" }, children: [
10728
+ !isDefaultProject && onDeleteProject && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
9985
10729
  "button",
9986
10730
  {
9987
10731
  onClick: () => {
@@ -10004,7 +10748,7 @@ var ProjectSettingsModal = ({
10004
10748
  children: "\uD504\uB85C\uC81D\uD2B8 \uC0AD\uC81C"
10005
10749
  }
10006
10750
  ),
10007
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10751
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
10008
10752
  "button",
10009
10753
  {
10010
10754
  onClick: handleSaveGeneral,
@@ -10024,9 +10768,9 @@ var ProjectSettingsModal = ({
10024
10768
  )
10025
10769
  ] })
10026
10770
  ] }),
10027
- activeTab === "instructions" && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
10028
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { style: { fontSize: "13px", color: "var(--chatllm-text-muted, #999)", margin: 0 }, children: "\uC774 \uD504\uB85C\uC81D\uD2B8\uC758 \uBAA8\uB4E0 \uB300\uD654\uC5D0\uC11C AI\uAC00 \uB530\uB77C\uC57C \uD560 \uC9C0\uCE68\uC744 \uC785\uB825\uD558\uC138\uC694." }),
10029
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10771
+ activeTab === "instructions" && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
10772
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { style: { fontSize: "13px", color: "var(--chatllm-text-muted, #999)", margin: 0 }, children: "\uC774 \uD504\uB85C\uC81D\uD2B8\uC758 \uBAA8\uB4E0 \uB300\uD654\uC5D0\uC11C AI\uAC00 \uB530\uB77C\uC57C \uD560 \uC9C0\uCE68\uC744 \uC785\uB825\uD558\uC138\uC694." }),
10773
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
10030
10774
  "textarea",
10031
10775
  {
10032
10776
  value: instructions,
@@ -10047,7 +10791,7 @@ var ProjectSettingsModal = ({
10047
10791
  }
10048
10792
  }
10049
10793
  ),
10050
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { display: "flex", justifyContent: "flex-end" }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10794
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { display: "flex", justifyContent: "flex-end" }, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
10051
10795
  "button",
10052
10796
  {
10053
10797
  onClick: handleSaveInstructions,
@@ -10066,10 +10810,10 @@ var ProjectSettingsModal = ({
10066
10810
  }
10067
10811
  ) })
10068
10812
  ] }),
10069
- activeTab === "files" && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
10070
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
10071
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { style: { fontSize: "13px", color: "var(--chatllm-text-muted, #999)", margin: 0 }, children: "\uD504\uB85C\uC81D\uD2B8 \uCEE8\uD14D\uC2A4\uD2B8\uB85C \uC0AC\uC6A9\uD560 \uD30C\uC77C\uC744 \uAD00\uB9AC\uD569\uB2C8\uB2E4." }),
10072
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
10813
+ activeTab === "files" && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
10814
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
10815
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { style: { fontSize: "13px", color: "var(--chatllm-text-muted, #999)", margin: 0 }, children: "\uD504\uB85C\uC81D\uD2B8 \uCEE8\uD14D\uC2A4\uD2B8\uB85C \uC0AC\uC6A9\uD560 \uD30C\uC77C\uC744 \uAD00\uB9AC\uD569\uB2C8\uB2E4." }),
10816
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
10073
10817
  "button",
10074
10818
  {
10075
10819
  onClick: handleFileUpload,
@@ -10087,13 +10831,13 @@ var ProjectSettingsModal = ({
10087
10831
  color: "var(--chatllm-text, #1a1a1a)"
10088
10832
  },
10089
10833
  children: [
10090
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconSvg, { name: "upload-line", size: 14 }),
10834
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(IconSvg, { name: "upload-line", size: 14 }),
10091
10835
  "\uC5C5\uB85C\uB4DC"
10092
10836
  ]
10093
10837
  }
10094
10838
  )
10095
10839
  ] }),
10096
- project.files.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10840
+ project.files.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
10097
10841
  "div",
10098
10842
  {
10099
10843
  style: {
@@ -10106,7 +10850,7 @@ var ProjectSettingsModal = ({
10106
10850
  },
10107
10851
  children: "\uC544\uC9C1 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4"
10108
10852
  }
10109
- ) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: project.files.map((file) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
10853
+ ) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: project.files.map((file) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
10110
10854
  "div",
10111
10855
  {
10112
10856
  style: {
@@ -10118,10 +10862,10 @@ var ProjectSettingsModal = ({
10118
10862
  borderRadius: "6px"
10119
10863
  },
10120
10864
  children: [
10121
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "10px", overflow: "hidden" }, children: [
10122
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconSvg, { name: getFileIcon2(file.type), size: 18, color: "var(--chatllm-text-muted, #999)" }),
10123
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { overflow: "hidden" }, children: [
10124
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10865
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "10px", overflow: "hidden" }, children: [
10866
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(IconSvg, { name: getFileIcon2(file.type), size: 18, color: "var(--chatllm-text-muted, #999)" }),
10867
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { overflow: "hidden" }, children: [
10868
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
10125
10869
  "div",
10126
10870
  {
10127
10871
  style: {
@@ -10135,13 +10879,13 @@ var ProjectSettingsModal = ({
10135
10879
  children: file.name
10136
10880
  }
10137
10881
  ),
10138
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { fontSize: "11px", color: "var(--chatllm-text-muted, #999)" }, children: [
10882
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { fontSize: "11px", color: "var(--chatllm-text-muted, #999)" }, children: [
10139
10883
  file.type,
10140
10884
  formatSize(file.size) ? ` \xB7 ${formatSize(file.size)}` : ""
10141
10885
  ] })
10142
10886
  ] })
10143
10887
  ] }),
10144
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
10888
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
10145
10889
  "button",
10146
10890
  {
10147
10891
  onClick: () => onDeleteFile(project.id, file.id),
@@ -10162,7 +10906,7 @@ var ProjectSettingsModal = ({
10162
10906
  e.currentTarget.style.opacity = "0.5";
10163
10907
  },
10164
10908
  "aria-label": `${file.name} \uC0AD\uC81C`,
10165
- children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconSvg, { name: "delete-bin-line", size: 16, color: "#dc2626" })
10909
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(IconSvg, { name: "delete-bin-line", size: 16, color: "#dc2626" })
10166
10910
  }
10167
10911
  )
10168
10912
  ]
@@ -10179,14 +10923,14 @@ var ProjectSettingsModal = ({
10179
10923
  };
10180
10924
 
10181
10925
  // src/react/components/DisclaimerModal.tsx
10182
- var import_jsx_runtime19 = require("react/jsx-runtime");
10926
+ var import_jsx_runtime20 = require("react/jsx-runtime");
10183
10927
  var highlightStyle = {
10184
10928
  color: "var(--chatllm-text, #1e293b)",
10185
10929
  fontWeight: 600
10186
10930
  };
10187
10931
  var DisclaimerModal = ({ isOpen, onClose }) => {
10188
10932
  if (!isOpen) return null;
10189
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
10933
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
10190
10934
  "div",
10191
10935
  {
10192
10936
  className: "chatllm-disclaimer-overlay",
@@ -10200,7 +10944,7 @@ var DisclaimerModal = ({ isOpen, onClose }) => {
10200
10944
  zIndex: 1e3
10201
10945
  },
10202
10946
  onClick: onClose,
10203
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
10947
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
10204
10948
  "div",
10205
10949
  {
10206
10950
  className: "chatllm-disclaimer-modal",
@@ -10218,7 +10962,7 @@ var DisclaimerModal = ({ isOpen, onClose }) => {
10218
10962
  },
10219
10963
  onClick: (e) => e.stopPropagation(),
10220
10964
  children: [
10221
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
10965
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
10222
10966
  "div",
10223
10967
  {
10224
10968
  style: {
@@ -10229,9 +10973,9 @@ var DisclaimerModal = ({ isOpen, onClose }) => {
10229
10973
  borderBottom: "1px solid var(--chatllm-border, #e5e7eb)"
10230
10974
  },
10231
10975
  children: [
10232
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
10233
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(IconSvg, { name: "error-warning-line", size: 20, color: "var(--chatllm-primary, #3584FA)" }),
10234
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
10976
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
10977
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(IconSvg, { name: "error-warning-line", size: 20, color: "var(--chatllm-primary, #3584FA)" }),
10978
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
10235
10979
  "h2",
10236
10980
  {
10237
10981
  style: {
@@ -10244,7 +10988,7 @@ var DisclaimerModal = ({ isOpen, onClose }) => {
10244
10988
  }
10245
10989
  )
10246
10990
  ] }),
10247
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
10991
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
10248
10992
  "button",
10249
10993
  {
10250
10994
  onClick: onClose,
@@ -10259,13 +11003,13 @@ var DisclaimerModal = ({ isOpen, onClose }) => {
10259
11003
  alignItems: "center",
10260
11004
  justifyContent: "center"
10261
11005
  },
10262
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(IconSvg, { name: "close-line", size: 20, color: "var(--chatllm-text-muted, #64748b)" })
11006
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(IconSvg, { name: "close-line", size: 20, color: "var(--chatllm-text-muted, #64748b)" })
10263
11007
  }
10264
11008
  )
10265
11009
  ]
10266
11010
  }
10267
11011
  ),
10268
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
11012
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
10269
11013
  "div",
10270
11014
  {
10271
11015
  className: "chatllm-scrollbar",
@@ -10277,12 +11021,12 @@ var DisclaimerModal = ({ isOpen, onClose }) => {
10277
11021
  color: "var(--chatllm-text-secondary, #475569)"
10278
11022
  },
10279
11023
  children: [
10280
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("p", { style: { margin: "0 0 16px" }, children: [
11024
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("p", { style: { margin: "0 0 16px" }, children: [
10281
11025
  "\uC800\uB294 \uC5EC\uB7EC\uBD84\uC758 \uC9C8\uBB38\uC5D0 ",
10282
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: highlightStyle, children: "\uCD5C\uC120\uC758 \uB2F5\uBCC0\uC744 \uB4DC\uB9AC\uAE30 \uC704\uD574 \uD56D\uC0C1 \uB178\uB825" }),
11026
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: highlightStyle, children: "\uCD5C\uC120\uC758 \uB2F5\uBCC0\uC744 \uB4DC\uB9AC\uAE30 \uC704\uD574 \uD56D\uC0C1 \uB178\uB825" }),
10283
11027
  "\uD558\uACE0 \uC788\uC5B4\uC694. \uD558\uC9C0\uB9CC \uC194\uC9C1\uD558\uAC8C \uB9D0\uC500\uB4DC\uB9AC\uBA74, \uC800\uB3C4 \uB54C\uB54C\uB85C \uC2E4\uC218\uB97C \uD558\uAC70\uB098 \uC815\uD655\uD558\uC9C0 \uC54A\uC740 \uB2F5\uBCC0\uC744 \uB4DC\uB9B4 \uC218 \uC788\uC2B5\uB2C8\uB2E4."
10284
11028
  ] }),
10285
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
11029
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
10286
11030
  "div",
10287
11031
  {
10288
11032
  style: {
@@ -10295,33 +11039,33 @@ var DisclaimerModal = ({ isOpen, onClose }) => {
10295
11039
  lineHeight: 1.7
10296
11040
  },
10297
11041
  children: [
10298
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { style: { margin: "0 0 8px", fontWeight: 600, color: "var(--chatllm-text, #1e293b)" }, children: "\uC81C\uAC00 \uC774\uB7F0 \uC2E4\uC218\uB97C \uD560 \uC218 \uC788\uC5B4\uC694" }),
10299
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("ul", { style: { margin: 0, paddingLeft: "18px", display: "flex", flexDirection: "column", gap: "4px" }, children: [
10300
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("li", { children: "\uCD5C\uC2E0 \uC815\uBCF4\uB97C \uBC18\uC601\uD558\uC9C0 \uBABB\uD55C \uB2F5\uBCC0\uC744 \uB4DC\uB9AC\uB294 \uACBD\uC6B0" }),
10301
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("li", { children: "\uADF8\uB7F4\uB4EF\uD558\uAC8C \uB4E4\uB9AC\uC9C0\uB9CC \uC2E4\uC81C\uB85C\uB294 \uC815\uD655\uD558\uC9C0 \uC54A\uC740 \uB0B4\uC6A9" }),
10302
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("li", { children: "\uC2E4\uC81C\uB85C \uC874\uC7AC\uD558\uC9C0 \uC54A\uB294 \uCD9C\uCC98\uB098 \uC778\uC6A9\uC744 \uB9CC\uB4E4\uC5B4\uB0B4\uB294 \uACBD\uC6B0" })
11042
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { style: { margin: "0 0 8px", fontWeight: 600, color: "var(--chatllm-text, #1e293b)" }, children: "\uC81C\uAC00 \uC774\uB7F0 \uC2E4\uC218\uB97C \uD560 \uC218 \uC788\uC5B4\uC694" }),
11043
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("ul", { style: { margin: 0, paddingLeft: "18px", display: "flex", flexDirection: "column", gap: "4px" }, children: [
11044
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("li", { children: "\uCD5C\uC2E0 \uC815\uBCF4\uB97C \uBC18\uC601\uD558\uC9C0 \uBABB\uD55C \uB2F5\uBCC0\uC744 \uB4DC\uB9AC\uB294 \uACBD\uC6B0" }),
11045
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("li", { children: "\uADF8\uB7F4\uB4EF\uD558\uAC8C \uB4E4\uB9AC\uC9C0\uB9CC \uC2E4\uC81C\uB85C\uB294 \uC815\uD655\uD558\uC9C0 \uC54A\uC740 \uB0B4\uC6A9" }),
11046
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("li", { children: "\uC2E4\uC81C\uB85C \uC874\uC7AC\uD558\uC9C0 \uC54A\uB294 \uCD9C\uCC98\uB098 \uC778\uC6A9\uC744 \uB9CC\uB4E4\uC5B4\uB0B4\uB294 \uACBD\uC6B0" })
10303
11047
  ] })
10304
11048
  ]
10305
11049
  }
10306
11050
  ),
10307
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("p", { style: { margin: "0 0 16px" }, children: [
11051
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("p", { style: { margin: "0 0 16px" }, children: [
10308
11052
  "\uC774\uB7F0 \uD604\uC0C1\uC744 ",
10309
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: highlightStyle, children: "'\uD658\uAC01(Hallucination)'" }),
11053
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: highlightStyle, children: "'\uD658\uAC01(Hallucination)'" }),
10310
11054
  "\uC774\uB77C\uACE0 \uBD80\uB974\uB294\uB370\uC694, \uC544\uC9C1\uC740 \uC800\uC640 \uAC19\uC740 AI\uAC00 \uAC00\uC9C4 \uADFC\uBCF8\uC801\uC778 \uD55C\uACC4\uC608\uC694. \uC81C \uB2F5\uBCC0\uC774 \uC544\uBB34\uB9AC \uC790\uC5F0\uC2A4\uB7EC\uC6CC \uBCF4\uC5EC\uB3C4, ",
10311
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: highlightStyle, children: "\uD55C \uBC88 \uB354 \uD655\uC778" }),
11055
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: highlightStyle, children: "\uD55C \uBC88 \uB354 \uD655\uC778" }),
10312
11056
  "\uD574 \uC8FC\uC2DC\uBA74 \uAC10\uC0AC\uD558\uACA0\uC2B5\uB2C8\uB2E4."
10313
11057
  ] }),
10314
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("p", { style: { margin: "0 0 16px" }, children: [
10315
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: highlightStyle, children: "\uC81C \uB2F5\uBCC0\uC740 \uCC38\uACE0 \uC790\uB8CC" }),
11058
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("p", { style: { margin: "0 0 16px" }, children: [
11059
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: highlightStyle, children: "\uC81C \uB2F5\uBCC0\uC740 \uCC38\uACE0 \uC790\uB8CC" }),
10316
11060
  "\uB85C \uD65C\uC6A9\uD574 \uC8FC\uC2DC\uACE0, \uC911\uC694\uD55C \uD310\uB2E8\uC744 \uB0B4\uB9AC\uC2E4 \uB54C\uB294 \uAF2D \uCD94\uAC00\uB85C \uD655\uC778\uD574 \uC8FC\uC138\uC694. \uC800\uB3C4 \uB354 \uC815\uD655\uD55C \uB2F5\uBCC0\uC744 \uB4DC\uB9AC\uAE30 \uC704\uD574 \uACC4\uC18D \uBC1C\uC804\uD558\uACE0 \uC788\uC2B5\uB2C8\uB2E4."
10317
11061
  ] }),
10318
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("p", { style: { margin: "0 0 16px" }, children: [
11062
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("p", { style: { margin: "0 0 16px" }, children: [
10319
11063
  "\uC81C\uAC00 \uC6F9 \uAC80\uC0C9 \uACB0\uACFC\uB97C \uC54C\uB824\uB4DC\uB9B4 \uB54C\uB3C4,",
10320
11064
  " ",
10321
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: highlightStyle, children: "\uC6D0\uBCF8 \uCD9C\uCC98\uB97C \uC9C1\uC811 \uD655\uC778" }),
11065
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: highlightStyle, children: "\uC6D0\uBCF8 \uCD9C\uCC98\uB97C \uC9C1\uC811 \uD655\uC778" }),
10322
11066
  "\uD574 \uBCF4\uC2DC\uB294 \uAC78 \uCD94\uCC9C\uB4DC\uB824\uC694. \uC694\uC57D \uACFC\uC815\uC5D0\uC11C \uB193\uCE60 \uC218 \uC788\uB294 \uC911\uC694\uD55C \uB9E5\uB77D\uC774 \uC6D0\uBCF8\uC5D0 \uB2F4\uACA8 \uC788\uC744 \uC218 \uC788\uAC70\uB4E0\uC694."
10323
11067
  ] }),
10324
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
11068
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
10325
11069
  "div",
10326
11070
  {
10327
11071
  style: {
@@ -10332,10 +11076,10 @@ var DisclaimerModal = ({ isOpen, onClose }) => {
10332
11076
  lineHeight: 1.7,
10333
11077
  textAlign: "center"
10334
11078
  },
10335
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("p", { style: { margin: 0 }, children: [
11079
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("p", { style: { margin: 0 }, children: [
10336
11080
  "\uC800\uC5D0 \uB300\uD55C \uC758\uACAC\uC774\uB098 \uAC1C\uC120 \uC81C\uC548\uC774 \uC788\uC73C\uC2DC\uB2E4\uBA74",
10337
11081
  " ",
10338
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
11082
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
10339
11083
  "a",
10340
11084
  {
10341
11085
  href: "mailto:info@gendive.ai",
@@ -10348,7 +11092,7 @@ var DisclaimerModal = ({ isOpen, onClose }) => {
10348
11092
  }
10349
11093
  ),
10350
11094
  "\uB85C \uC54C\uB824\uC8FC\uC138\uC694.",
10351
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("br", {}),
11095
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("br", {}),
10352
11096
  "\uC5EC\uB7EC\uBD84\uC758 \uD53C\uB4DC\uBC31 \uD558\uB098\uD558\uB098\uAC00 \uC81C\uAC00 \uC131\uC7A5\uD558\uB294 \uB370 \uD070 \uD798\uC774 \uB429\uB2C8\uB2E4."
10353
11097
  ] })
10354
11098
  }
@@ -10364,7 +11108,7 @@ var DisclaimerModal = ({ isOpen, onClose }) => {
10364
11108
  };
10365
11109
 
10366
11110
  // src/react/ChatUI.tsx
10367
- var import_jsx_runtime20 = require("react/jsx-runtime");
11111
+ var import_jsx_runtime21 = require("react/jsx-runtime");
10368
11112
  var DEFAULT_ACTIONS = [];
10369
11113
  var DEFAULT_TEMPLATES = [];
10370
11114
  var DEFAULT_MODELS = [
@@ -10407,6 +11151,17 @@ var injectStyles = () => {
10407
11151
  100% { transform: rotate(360deg); }
10408
11152
  }
10409
11153
 
11154
+ @keyframes chatllm-checklist-pulse {
11155
+ 0%, 100% { opacity: 1; }
11156
+ 50% { opacity: 0.4; }
11157
+ }
11158
+
11159
+ @keyframes chatllm-checklist-check {
11160
+ 0% { transform: scale(0); opacity: 0; }
11161
+ 50% { transform: scale(1.2); }
11162
+ 100% { transform: scale(1); opacity: 1; }
11163
+ }
11164
+
10410
11165
  @keyframes chatllm-welcome-exit {
10411
11166
  from { opacity: 1; transform: translateY(0); }
10412
11167
  to { opacity: 0; transform: translateY(-16px); }
@@ -10688,12 +11443,16 @@ var ChatUIView = ({
10688
11443
  openProjectSettings,
10689
11444
  closeProjectSettings,
10690
11445
  projectMemory,
10691
- isSessionsLoading
11446
+ isSessionsLoading,
11447
+ // Checklist
11448
+ handleChecklistAbort,
11449
+ handleChecklistRetry,
11450
+ handleChecklistSkip
10692
11451
  } = state;
10693
- const [disclaimerOpen, setDisclaimerOpen] = import_react20.default.useState(false);
10694
- const [welcomeExiting, setWelcomeExiting] = import_react20.default.useState(false);
10695
- const prevMessageCountRef = import_react20.default.useRef(messages.length);
10696
- import_react20.default.useEffect(() => {
11452
+ const [disclaimerOpen, setDisclaimerOpen] = import_react21.default.useState(false);
11453
+ const [welcomeExiting, setWelcomeExiting] = import_react21.default.useState(false);
11454
+ const prevMessageCountRef = import_react21.default.useRef(messages.length);
11455
+ import_react21.default.useEffect(() => {
10697
11456
  let timer;
10698
11457
  if (prevMessageCountRef.current === 0 && messages.length > 0) {
10699
11458
  setWelcomeExiting(true);
@@ -10717,7 +11476,7 @@ var ChatUIView = ({
10717
11476
  const handleChoiceClick = (choice) => {
10718
11477
  setInput(choice.text);
10719
11478
  };
10720
- const memoryItems = import_react20.default.useMemo(() => {
11479
+ const memoryItems = import_react21.default.useMemo(() => {
10721
11480
  if (!globalMemory?.state.entries) return [];
10722
11481
  const items = [];
10723
11482
  for (const [key, entry] of globalMemory.state.entries) {
@@ -10731,7 +11490,7 @@ var ChatUIView = ({
10731
11490
  }
10732
11491
  return items;
10733
11492
  }, [globalMemory?.state.entries]);
10734
- const projectMemoryItems = import_react20.default.useMemo(() => {
11493
+ const projectMemoryItems = import_react21.default.useMemo(() => {
10735
11494
  if (!projectMemory?.state.entries) return [];
10736
11495
  const items = [];
10737
11496
  for (const [key, entry] of projectMemory.state.entries) {
@@ -10746,7 +11505,7 @@ var ChatUIView = ({
10746
11505
  return items;
10747
11506
  }, [projectMemory?.state.entries]);
10748
11507
  const themeClass = theme?.mode === "dark" ? "chatllm-dark" : "";
10749
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
11508
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
10750
11509
  "div",
10751
11510
  {
10752
11511
  className: `chatllm-root ${themeClass} ${className}`,
@@ -10759,7 +11518,7 @@ var ChatUIView = ({
10759
11518
  position: "relative"
10760
11519
  },
10761
11520
  children: [
10762
- showSidebar && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11521
+ showSidebar && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
10763
11522
  ChatSidebar,
10764
11523
  {
10765
11524
  sessions,
@@ -10791,7 +11550,7 @@ var ChatUIView = ({
10791
11550
  isLoading: isSessionsLoading
10792
11551
  }
10793
11552
  ),
10794
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
11553
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
10795
11554
  "main",
10796
11555
  {
10797
11556
  style: {
@@ -10803,7 +11562,7 @@ var ChatUIView = ({
10803
11562
  minWidth: 0
10804
11563
  },
10805
11564
  children: [
10806
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11565
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
10807
11566
  ChatHeader,
10808
11567
  {
10809
11568
  title: currentSession?.title || "\uC0C8 \uB300\uD654",
@@ -10817,7 +11576,7 @@ var ChatUIView = ({
10817
11576
  showSettings
10818
11577
  }
10819
11578
  ),
10820
- (messages.length === 0 || welcomeExiting) && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
11579
+ (messages.length === 0 || welcomeExiting) && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
10821
11580
  "div",
10822
11581
  {
10823
11582
  style: {
@@ -10832,7 +11591,7 @@ var ChatUIView = ({
10832
11591
  pointerEvents: welcomeExiting ? "none" : "auto"
10833
11592
  },
10834
11593
  children: [
10835
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11594
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
10836
11595
  "h1",
10837
11596
  {
10838
11597
  style: {
@@ -10846,7 +11605,7 @@ var ChatUIView = ({
10846
11605
  children: greeting ? `${greeting} \u273A` : "\u273A \uBB34\uC5C7\uC744 \uC0DD\uAC01\uD574 \uBCFC\uAE4C\uC694?"
10847
11606
  }
10848
11607
  ),
10849
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { width: "100%", maxWidth: "680px" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11608
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { width: "100%", maxWidth: "680px" }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
10850
11609
  ChatInput,
10851
11610
  {
10852
11611
  value: input,
@@ -10874,7 +11633,7 @@ var ChatUIView = ({
10874
11633
  inline: true
10875
11634
  }
10876
11635
  ) }),
10877
- suggestedPrompts && suggestedPrompts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11636
+ suggestedPrompts && suggestedPrompts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
10878
11637
  "div",
10879
11638
  {
10880
11639
  style: {
@@ -10884,7 +11643,7 @@ var ChatUIView = ({
10884
11643
  justifyContent: "center",
10885
11644
  maxWidth: "680px"
10886
11645
  },
10887
- children: suggestedPrompts.map((sp) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
11646
+ children: suggestedPrompts.map((sp) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
10888
11647
  "button",
10889
11648
  {
10890
11649
  onClick: () => setInput(sp.prompt),
@@ -10903,7 +11662,7 @@ var ChatUIView = ({
10903
11662
  transition: "all 0.2s"
10904
11663
  },
10905
11664
  children: [
10906
- sp.icon && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(IconSvg, { name: sp.icon, size: 16, color: "var(--chatllm-text-muted)" }),
11665
+ sp.icon && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(IconSvg, { name: sp.icon, size: 16, color: "var(--chatllm-text-muted)" }),
10907
11666
  sp.label
10908
11667
  ]
10909
11668
  },
@@ -10914,8 +11673,8 @@ var ChatUIView = ({
10914
11673
  ]
10915
11674
  }
10916
11675
  ),
10917
- messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
10918
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11676
+ messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
11677
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
10919
11678
  MessageList,
10920
11679
  {
10921
11680
  messages,
@@ -10934,10 +11693,13 @@ var ChatUIView = ({
10934
11693
  showThinking,
10935
11694
  thinkingDefaultOpen,
10936
11695
  loadingAlternativeFor,
10937
- onPollSubmit: handlePollSubmit
11696
+ onPollSubmit: handlePollSubmit,
11697
+ onChecklistAbort: handleChecklistAbort,
11698
+ onChecklistRetry: handleChecklistRetry,
11699
+ onChecklistSkip: handleChecklistSkip
10938
11700
  }
10939
11701
  ),
10940
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11702
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
10941
11703
  ChatInput,
10942
11704
  {
10943
11705
  value: input,
@@ -10968,7 +11730,7 @@ var ChatUIView = ({
10968
11730
  ]
10969
11731
  }
10970
11732
  ),
10971
- showSettings && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11733
+ showSettings && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
10972
11734
  SettingsModal,
10973
11735
  {
10974
11736
  isOpen: settingsOpen,
@@ -10995,7 +11757,7 @@ var ChatUIView = ({
10995
11757
  currentProjectTitle: currentProject?.title
10996
11758
  }
10997
11759
  ),
10998
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11760
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
10999
11761
  ProjectSettingsModal,
11000
11762
  {
11001
11763
  isOpen: projectSettingsOpen,
@@ -11007,7 +11769,7 @@ var ChatUIView = ({
11007
11769
  onDeleteProject: deleteProject
11008
11770
  }
11009
11771
  ),
11010
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DisclaimerModal, { isOpen: disclaimerOpen, onClose: () => setDisclaimerOpen(false) })
11772
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DisclaimerModal, { isOpen: disclaimerOpen, onClose: () => setDisclaimerOpen(false) })
11011
11773
  ]
11012
11774
  }
11013
11775
  );
@@ -11110,7 +11872,7 @@ var ChatUIWithHook = ({
11110
11872
  onDeleteProjectFile
11111
11873
  };
11112
11874
  const state = useChatUI(hookOptions);
11113
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11875
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
11114
11876
  ChatUIView,
11115
11877
  {
11116
11878
  state,
@@ -11158,7 +11920,7 @@ var ChatUI = (props) => {
11158
11920
  deepResearch,
11159
11921
  suggestedPrompts: chatStateSuggestedPrompts
11160
11922
  } = props;
11161
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11923
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
11162
11924
  ChatUIView,
11163
11925
  {
11164
11926
  state: props.chatState,
@@ -11183,11 +11945,11 @@ var ChatUI = (props) => {
11183
11945
  }
11184
11946
  );
11185
11947
  }
11186
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ChatUIWithHook, { ...props });
11948
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ChatUIWithHook, { ...props });
11187
11949
  };
11188
11950
 
11189
11951
  // src/react/hooks/useDeepResearch.ts
11190
- var import_react21 = require("react");
11952
+ var import_react22 = require("react");
11191
11953
  var REPORT_GENERATION_PROMPT2 = `\uB2F9\uC2E0\uC740 \uB9AC\uC11C\uCE58 \uBCF4\uACE0\uC11C \uC791\uC131 \uC804\uBB38\uAC00\uC785\uB2C8\uB2E4.
11192
11954
 
11193
11955
  <collected_sources>
@@ -11238,10 +12000,10 @@ var QUERY_ANALYSIS_PROMPT2 = `\uC0AC\uC6A9\uC790 \uC9C8\uBB38\uC744 \uBD84\uC11D
11238
12000
  - JSON \uC678 \uB2E4\uB978 \uD14D\uC2A4\uD2B8 \uCD9C\uB825 \uAE08\uC9C0`;
11239
12001
  var useDeepResearch = (options) => {
11240
12002
  const { onWebSearch, onExtractContent, apiEndpoint, apiKey, model, provider } = options;
11241
- const [isResearching, setIsResearching] = (0, import_react21.useState)(false);
11242
- const [progress, setProgress] = (0, import_react21.useState)(null);
11243
- const abortControllerRef = (0, import_react21.useRef)(null);
11244
- const callLLM2 = (0, import_react21.useCallback)(
12003
+ const [isResearching, setIsResearching] = (0, import_react22.useState)(false);
12004
+ const [progress, setProgress] = (0, import_react22.useState)(null);
12005
+ const abortControllerRef = (0, import_react22.useRef)(null);
12006
+ const callLLM2 = (0, import_react22.useCallback)(
11245
12007
  async (prompt, stream = false) => {
11246
12008
  const response = await fetch(apiEndpoint, {
11247
12009
  method: "POST",
@@ -11268,7 +12030,7 @@ var useDeepResearch = (options) => {
11268
12030
  },
11269
12031
  [apiEndpoint, apiKey, model, provider]
11270
12032
  );
11271
- const analyzeQuery2 = (0, import_react21.useCallback)(
12033
+ const analyzeQuery2 = (0, import_react22.useCallback)(
11272
12034
  async (query) => {
11273
12035
  const prompt = QUERY_ANALYSIS_PROMPT2.replace("{question}", query);
11274
12036
  const response = await callLLM2(prompt);
@@ -11287,7 +12049,7 @@ var useDeepResearch = (options) => {
11287
12049
  },
11288
12050
  [callLLM2]
11289
12051
  );
11290
- const runSubAgent2 = (0, import_react21.useCallback)(
12052
+ const runSubAgent2 = (0, import_react22.useCallback)(
11291
12053
  async (topic, queries, agentId, updateProgress) => {
11292
12054
  updateProgress({ status: "searching", searchCount: 0, resultsCount: 0 });
11293
12055
  const allResults = [];
@@ -11326,7 +12088,7 @@ var useDeepResearch = (options) => {
11326
12088
  },
11327
12089
  [onWebSearch, onExtractContent]
11328
12090
  );
11329
- const generateReport2 = (0, import_react21.useCallback)(
12091
+ const generateReport2 = (0, import_react22.useCallback)(
11330
12092
  async (query, results, onStreamContent) => {
11331
12093
  const allSources = [];
11332
12094
  const sourcesForPrompt = [];
@@ -11384,7 +12146,7 @@ var useDeepResearch = (options) => {
11384
12146
  },
11385
12147
  [callLLM2]
11386
12148
  );
11387
- const runDeepResearch = (0, import_react21.useCallback)(
12149
+ const runDeepResearch = (0, import_react22.useCallback)(
11388
12150
  async (query, onStreamContent) => {
11389
12151
  abortControllerRef.current = new AbortController();
11390
12152
  setIsResearching(true);
@@ -11487,7 +12249,7 @@ var useDeepResearch = (options) => {
11487
12249
  },
11488
12250
  [analyzeQuery2, runSubAgent2, generateReport2]
11489
12251
  );
11490
- const stopResearch = (0, import_react21.useCallback)(() => {
12252
+ const stopResearch = (0, import_react22.useCallback)(() => {
11491
12253
  abortControllerRef.current?.abort();
11492
12254
  setIsResearching(false);
11493
12255
  setProgress(null);
@@ -11501,7 +12263,7 @@ var useDeepResearch = (options) => {
11501
12263
  };
11502
12264
 
11503
12265
  // src/react/components/EmptyState.tsx
11504
- var import_jsx_runtime21 = require("react/jsx-runtime");
12266
+ var import_jsx_runtime22 = require("react/jsx-runtime");
11505
12267
  var EmptyState = ({
11506
12268
  greeting,
11507
12269
  templates = [],
@@ -11519,7 +12281,7 @@ var EmptyState = ({
11519
12281
  return iconMap[icon] || "sparkling-line";
11520
12282
  };
11521
12283
  const hasContent = actions.length > 0 || templates.length > 0;
11522
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
12284
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
11523
12285
  "div",
11524
12286
  {
11525
12287
  className: "chatllm-empty-state",
@@ -11534,7 +12296,7 @@ var EmptyState = ({
11534
12296
  textAlign: "center"
11535
12297
  },
11536
12298
  children: [
11537
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
12299
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11538
12300
  "div",
11539
12301
  {
11540
12302
  className: "chatllm-sheet",
@@ -11548,10 +12310,10 @@ var EmptyState = ({
11548
12310
  marginBottom: "32px",
11549
12311
  color: "var(--chatllm-primary)"
11550
12312
  },
11551
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(IconSvg, { name: "chat-1-line", size: 40 })
12313
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(IconSvg, { name: "chat-1-line", size: 40 })
11552
12314
  }
11553
12315
  ),
11554
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
12316
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11555
12317
  "h1",
11556
12318
  {
11557
12319
  style: {
@@ -11564,7 +12326,7 @@ var EmptyState = ({
11564
12326
  children: "How can I help you today?"
11565
12327
  }
11566
12328
  ),
11567
- (actions.length > 0 || templates.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
12329
+ (actions.length > 0 || templates.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
11568
12330
  "div",
11569
12331
  {
11570
12332
  style: {
@@ -11576,7 +12338,7 @@ var EmptyState = ({
11576
12338
  marginBottom: "48px"
11577
12339
  },
11578
12340
  children: [
11579
- actions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
12341
+ actions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
11580
12342
  "button",
11581
12343
  {
11582
12344
  onClick: () => onActionSelect?.(action),
@@ -11590,7 +12352,7 @@ var EmptyState = ({
11590
12352
  fontWeight: 500
11591
12353
  },
11592
12354
  children: [
11593
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
12355
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11594
12356
  IconSvg,
11595
12357
  {
11596
12358
  name: getActionIcon(action.icon),
@@ -11603,7 +12365,7 @@ var EmptyState = ({
11603
12365
  },
11604
12366
  action.id
11605
12367
  )),
11606
- templates.slice(0, 4).map((template) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
12368
+ templates.slice(0, 4).map((template) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
11607
12369
  "button",
11608
12370
  {
11609
12371
  onClick: () => onTemplateClick(template),
@@ -11617,7 +12379,7 @@ var EmptyState = ({
11617
12379
  fontWeight: 500
11618
12380
  },
11619
12381
  children: [
11620
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
12382
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11621
12383
  IconSvg,
11622
12384
  {
11623
12385
  name: "sparkling-line",
@@ -11639,8 +12401,8 @@ var EmptyState = ({
11639
12401
  };
11640
12402
 
11641
12403
  // src/react/components/MemoryPanel.tsx
11642
- var import_react22 = require("react");
11643
- var import_jsx_runtime22 = require("react/jsx-runtime");
12404
+ var import_react23 = require("react");
12405
+ var import_jsx_runtime23 = require("react/jsx-runtime");
11644
12406
  var categoryLabels = {
11645
12407
  fact: "\uC0AC\uC6A9\uC790 \uC815\uBCF4",
11646
12408
  skill: "\uC804\uBB38 \uBD84\uC57C/\uAE30\uC220",
@@ -11659,8 +12421,8 @@ var MemoryPanel = ({
11659
12421
  isOpen,
11660
12422
  onToggle
11661
12423
  }) => {
11662
- const [expandedId, setExpandedId] = (0, import_react22.useState)(null);
11663
- const [activeTab, setActiveTab] = (0, import_react22.useState)("all");
12424
+ const [expandedId, setExpandedId] = (0, import_react23.useState)(null);
12425
+ const [activeTab, setActiveTab] = (0, import_react23.useState)("all");
11664
12426
  const filteredItems = activeTab === "all" ? items : items.filter((item) => item.category === activeTab);
11665
12427
  const formatDate = (timestamp) => {
11666
12428
  const date = new Date(timestamp);
@@ -11672,7 +12434,7 @@ var MemoryPanel = ({
11672
12434
  });
11673
12435
  };
11674
12436
  if (!isOpen) {
11675
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12437
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
11676
12438
  "button",
11677
12439
  {
11678
12440
  onClick: onToggle,
@@ -11692,11 +12454,11 @@ var MemoryPanel = ({
11692
12454
  justifyContent: "center",
11693
12455
  zIndex: 100
11694
12456
  },
11695
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(IconSvg, { name: "robot-line", size: 24, color: "#ffffff" })
12457
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(IconSvg, { name: "robot-line", size: 24, color: "#ffffff" })
11696
12458
  }
11697
12459
  );
11698
12460
  }
11699
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
12461
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
11700
12462
  "div",
11701
12463
  {
11702
12464
  className: "chatllm-memory-panel",
@@ -11716,7 +12478,7 @@ var MemoryPanel = ({
11716
12478
  zIndex: 100
11717
12479
  },
11718
12480
  children: [
11719
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
12481
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
11720
12482
  "div",
11721
12483
  {
11722
12484
  style: {
@@ -11727,8 +12489,8 @@ var MemoryPanel = ({
11727
12489
  borderBottom: "1px solid var(--chatllm-border, #e5e7eb)"
11728
12490
  },
11729
12491
  children: [
11730
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "10px" }, children: [
11731
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12492
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "10px" }, children: [
12493
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
11732
12494
  "div",
11733
12495
  {
11734
12496
  style: {
@@ -11740,19 +12502,19 @@ var MemoryPanel = ({
11740
12502
  alignItems: "center",
11741
12503
  justifyContent: "center"
11742
12504
  },
11743
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(IconSvg, { name: "robot-line", size: 18, color: "var(--chatllm-primary, #3584FA)" })
12505
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(IconSvg, { name: "robot-line", size: 18, color: "var(--chatllm-primary, #3584FA)" })
11744
12506
  }
11745
12507
  ),
11746
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { children: [
11747
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { fontSize: "15px", fontWeight: 600, color: "var(--chatllm-text, #1f2937)" }, children: "AI \uBA54\uBAA8\uB9AC" }),
11748
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { fontSize: "12px", color: "var(--chatllm-text-muted, #9ca3af)" }, children: [
12508
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
12509
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { fontSize: "15px", fontWeight: 600, color: "var(--chatllm-text, #1f2937)" }, children: "AI \uBA54\uBAA8\uB9AC" }),
12510
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { fontSize: "12px", color: "var(--chatllm-text-muted, #9ca3af)" }, children: [
11749
12511
  items.length,
11750
12512
  "\uAC1C \uD56D\uBAA9"
11751
12513
  ] })
11752
12514
  ] })
11753
12515
  ] }),
11754
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", gap: "4px" }, children: [
11755
- onClearAll && items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12516
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", gap: "4px" }, children: [
12517
+ onClearAll && items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
11756
12518
  "button",
11757
12519
  {
11758
12520
  onClick: onClearAll,
@@ -11764,10 +12526,10 @@ var MemoryPanel = ({
11764
12526
  cursor: "pointer"
11765
12527
  },
11766
12528
  title: "\uC804\uCCB4 \uC0AD\uC81C",
11767
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(IconSvg, { name: "delete-bin-line", size: 18, color: "var(--chatllm-text-muted, #9ca3af)" })
12529
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(IconSvg, { name: "delete-bin-line", size: 18, color: "var(--chatllm-text-muted, #9ca3af)" })
11768
12530
  }
11769
12531
  ),
11770
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12532
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
11771
12533
  "button",
11772
12534
  {
11773
12535
  onClick: onToggle,
@@ -11778,14 +12540,14 @@ var MemoryPanel = ({
11778
12540
  borderRadius: "8px",
11779
12541
  cursor: "pointer"
11780
12542
  },
11781
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(IconSvg, { name: "close-line", size: 18, color: "var(--chatllm-text-muted, #9ca3af)" })
12543
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(IconSvg, { name: "close-line", size: 18, color: "var(--chatllm-text-muted, #9ca3af)" })
11782
12544
  }
11783
12545
  )
11784
12546
  ] })
11785
12547
  ]
11786
12548
  }
11787
12549
  ),
11788
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12550
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
11789
12551
  "div",
11790
12552
  {
11791
12553
  style: {
@@ -11795,7 +12557,7 @@ var MemoryPanel = ({
11795
12557
  borderBottom: "1px solid var(--chatllm-border-light, #f3f4f6)",
11796
12558
  overflowX: "auto"
11797
12559
  },
11798
- children: ["all", "fact", "skill", "preference"].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12560
+ children: ["all", "fact", "skill", "preference"].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
11799
12561
  "button",
11800
12562
  {
11801
12563
  onClick: () => setActiveTab(tab),
@@ -11816,8 +12578,8 @@ var MemoryPanel = ({
11816
12578
  ))
11817
12579
  }
11818
12580
  ),
11819
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { flex: 1, overflow: "auto", padding: "12px" }, children: [
11820
- contextSummary && activeTab === "all" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
12581
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { flex: 1, overflow: "auto", padding: "12px" }, children: [
12582
+ contextSummary && activeTab === "all" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
11821
12583
  "div",
11822
12584
  {
11823
12585
  style: {
@@ -11828,7 +12590,7 @@ var MemoryPanel = ({
11828
12590
  borderLeft: "3px solid var(--chatllm-primary, #3584FA)"
11829
12591
  },
11830
12592
  children: [
11831
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
12593
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
11832
12594
  "div",
11833
12595
  {
11834
12596
  style: {
@@ -11838,12 +12600,12 @@ var MemoryPanel = ({
11838
12600
  marginBottom: "8px"
11839
12601
  },
11840
12602
  children: [
11841
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(IconSvg, { name: "file-text-line", size: 14, color: "var(--chatllm-primary, #3584FA)" }),
11842
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { fontSize: "12px", fontWeight: 500, color: "var(--chatllm-primary, #3584FA)" }, children: "\uB300\uD654 \uC694\uC57D" })
12603
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(IconSvg, { name: "file-text-line", size: 14, color: "var(--chatllm-primary, #3584FA)" }),
12604
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { fontSize: "12px", fontWeight: 500, color: "var(--chatllm-primary, #3584FA)" }, children: "\uB300\uD654 \uC694\uC57D" })
11843
12605
  ]
11844
12606
  }
11845
12607
  ),
11846
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12608
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
11847
12609
  "p",
11848
12610
  {
11849
12611
  style: {
@@ -11858,7 +12620,7 @@ var MemoryPanel = ({
11858
12620
  ]
11859
12621
  }
11860
12622
  ),
11861
- filteredItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
12623
+ filteredItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
11862
12624
  "div",
11863
12625
  {
11864
12626
  style: {
@@ -11867,11 +12629,11 @@ var MemoryPanel = ({
11867
12629
  color: "var(--chatllm-text-muted, #9ca3af)"
11868
12630
  },
11869
12631
  children: [
11870
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(IconSvg, { name: "robot-line", size: 32, color: "var(--chatllm-text-muted, #d1d5db)" }),
11871
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { style: { fontSize: "14px", marginTop: "12px" }, children: "\uC800\uC7A5\uB41C \uBA54\uBAA8\uB9AC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4" })
12632
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(IconSvg, { name: "robot-line", size: 32, color: "var(--chatllm-text-muted, #d1d5db)" }),
12633
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { style: { fontSize: "14px", marginTop: "12px" }, children: "\uC800\uC7A5\uB41C \uBA54\uBAA8\uB9AC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4" })
11872
12634
  ]
11873
12635
  }
11874
- ) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: filteredItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
12636
+ ) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: filteredItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
11875
12637
  "div",
11876
12638
  {
11877
12639
  style: {
@@ -11884,10 +12646,10 @@ var MemoryPanel = ({
11884
12646
  },
11885
12647
  onClick: () => setExpandedId(expandedId === item.id ? null : item.id),
11886
12648
  children: [
11887
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", alignItems: "flex-start", justifyContent: "space-between" }, children: [
11888
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
11889
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px", marginBottom: "4px" }, children: [
11890
- item.category && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12649
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", alignItems: "flex-start", justifyContent: "space-between" }, children: [
12650
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
12651
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px", marginBottom: "4px" }, children: [
12652
+ item.category && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
11891
12653
  "span",
11892
12654
  {
11893
12655
  style: {
@@ -11901,9 +12663,9 @@ var MemoryPanel = ({
11901
12663
  children: categoryLabels[item.category]
11902
12664
  }
11903
12665
  ),
11904
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { fontSize: "11px", color: "var(--chatllm-text-muted, #9ca3af)" }, children: formatDate(item.timestamp) })
12666
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { fontSize: "11px", color: "var(--chatllm-text-muted, #9ca3af)" }, children: formatDate(item.timestamp) })
11905
12667
  ] }),
11906
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12668
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
11907
12669
  "div",
11908
12670
  {
11909
12671
  style: {
@@ -11915,8 +12677,8 @@ var MemoryPanel = ({
11915
12677
  }
11916
12678
  )
11917
12679
  ] }),
11918
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [
11919
- onDelete && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12680
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [
12681
+ onDelete && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
11920
12682
  "button",
11921
12683
  {
11922
12684
  onClick: (e) => {
@@ -11931,10 +12693,10 @@ var MemoryPanel = ({
11931
12693
  cursor: "pointer",
11932
12694
  opacity: 0.5
11933
12695
  },
11934
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(IconSvg, { name: "delete-bin-line", size: 14, color: "var(--chatllm-text-muted, #9ca3af)" })
12696
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(IconSvg, { name: "delete-bin-line", size: 14, color: "var(--chatllm-text-muted, #9ca3af)" })
11935
12697
  }
11936
12698
  ),
11937
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12699
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
11938
12700
  IconSvg,
11939
12701
  {
11940
12702
  name: expandedId === item.id ? "arrow-up-s-line" : "arrow-down-s-line",
@@ -11944,7 +12706,7 @@ var MemoryPanel = ({
11944
12706
  )
11945
12707
  ] })
11946
12708
  ] }),
11947
- expandedId === item.id && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12709
+ expandedId === item.id && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
11948
12710
  "div",
11949
12711
  {
11950
12712
  style: {
@@ -11952,7 +12714,7 @@ var MemoryPanel = ({
11952
12714
  paddingTop: "12px",
11953
12715
  borderTop: "1px solid var(--chatllm-border-light, #f3f4f6)"
11954
12716
  },
11955
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12717
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
11956
12718
  "p",
11957
12719
  {
11958
12720
  style: {
@@ -11982,6 +12744,7 @@ var MemoryPanel = ({
11982
12744
  ChatInput,
11983
12745
  ChatSidebar,
11984
12746
  ChatUI,
12747
+ ChecklistCard,
11985
12748
  ContentPartRenderer,
11986
12749
  DEFAULT_PROJECT_ID,
11987
12750
  DEFAULT_PROJECT_TITLE,