@gendive/chatllm 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  // src/react/ChatUI.tsx
2
- import React8, { useState as useState8 } from "react";
2
+ import React9, { useState as useState9 } from "react";
3
3
 
4
4
  // src/react/hooks/useChatUI.ts
5
5
  import { useState, useRef, useCallback, useEffect } from "react";
@@ -2944,433 +2944,58 @@ var MemoryPanel = ({
2944
2944
  );
2945
2945
  };
2946
2946
 
2947
- // src/react/ChatUI.tsx
2947
+ // src/react/components/SettingsModal.tsx
2948
+ import { useState as useState8 } from "react";
2948
2949
  import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
2949
- var DEFAULT_ACTIONS = [
2950
- {
2951
- id: "webSearch",
2952
- label: "\uC6F9 \uAC80\uC0C9",
2953
- icon: "search",
2954
- description: "\uC6F9\uC5D0\uC11C \uC815\uBCF4\uB97C \uAC80\uC0C9\uD569\uB2C8\uB2E4",
2955
- systemPrompt: "\uC6F9 \uAC80\uC0C9 \uACB0\uACFC\uB97C \uAE30\uBC18\uC73C\uB85C \uB2F5\uBCC0\uD574\uC8FC\uC138\uC694."
2956
- },
2957
- {
2958
- id: "imageGen",
2959
- label: "\uC774\uBBF8\uC9C0 \uC0DD\uC131",
2960
- icon: "image",
2961
- description: "\uD504\uB86C\uD504\uD2B8\uB85C \uC774\uBBF8\uC9C0\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4",
2962
- systemPrompt: "\uC774\uBBF8\uC9C0 \uC0DD\uC131 \uC694\uCCAD\uC785\uB2C8\uB2E4."
2963
- },
2964
- {
2965
- id: "codeAnalysis",
2966
- label: "\uCF54\uB4DC \uBD84\uC11D",
2967
- icon: "code",
2968
- description: "\uCF54\uB4DC\uB97C \uBD84\uC11D\uD558\uACE0 \uC124\uBA85\uD569\uB2C8\uB2E4",
2969
- systemPrompt: "\uCF54\uB4DC\uB97C \uBD84\uC11D\uD558\uACE0 \uC790\uC138\uD788 \uC124\uBA85\uD574\uC8FC\uC138\uC694."
2970
- },
2971
- {
2972
- id: "summarize",
2973
- label: "\uC694\uC57D",
2974
- icon: "document",
2975
- description: "\uAE34 \uD14D\uC2A4\uD2B8\uB97C \uC694\uC57D\uD569\uB2C8\uB2E4",
2976
- systemPrompt: "\uB2E4\uC74C \uB0B4\uC6A9\uC744 \uD575\uC2EC\uB9CC \uAC04\uACB0\uD558\uAC8C \uC694\uC57D\uD574\uC8FC\uC138\uC694."
2977
- }
2978
- ];
2979
- var DEFAULT_TEMPLATES = [
2980
- {
2981
- id: "1",
2982
- title: "AI \uAE30\uBC18 \uAE00\uC4F0\uAE30",
2983
- description: "\uBE14\uB85C\uADF8, \uC774\uBA54\uC77C, \uBCF4\uACE0\uC11C \uC791\uC131 \uB3C4\uC6C0",
2984
- prompt: "\uB2E4\uC74C \uC8FC\uC81C\uC5D0 \uB300\uD574 \uBE14\uB85C\uADF8 \uAE00\uC744 \uC791\uC131\uD574\uC8FC\uC138\uC694: ",
2985
- category: "\uAE00\uC4F0\uAE30"
2986
- },
2987
- {
2988
- id: "2",
2989
- title: "\uCF54\uB4DC \uB9AC\uBDF0",
2990
- description: "\uCF54\uB4DC \uBD84\uC11D \uBC0F \uAC1C\uC120\uC810 \uC81C\uC548",
2991
- prompt: "\uB2E4\uC74C \uCF54\uB4DC\uB97C \uB9AC\uBDF0\uD558\uACE0 \uAC1C\uC120\uC810\uC744 \uC81C\uC548\uD574\uC8FC\uC138\uC694: ",
2992
- category: "\uAC1C\uBC1C"
2993
- },
2994
- {
2995
- id: "3",
2996
- title: "\uBC88\uC5ED \uB3C4\uC6B0\uBBF8",
2997
- description: "\uC790\uC5F0\uC2A4\uB7EC\uC6B4 \uBC88\uC5ED \uBC0F \uAD50\uC815",
2998
- prompt: "\uB2E4\uC74C \uD14D\uC2A4\uD2B8\uB97C \uC790\uC5F0\uC2A4\uB7FD\uAC8C \uBC88\uC5ED\uD574\uC8FC\uC138\uC694: ",
2999
- category: "\uBC88\uC5ED"
2950
+ var DEFAULT_PERSONALIZATION2 = {
2951
+ responseStyle: {
2952
+ warmth: "medium",
2953
+ enthusiasm: "medium",
2954
+ emojiUsage: "low",
2955
+ formatting: "default",
2956
+ verbosity: "balanced"
3000
2957
  },
3001
- {
3002
- id: "4",
3003
- title: "\uC694\uC57D \uC815\uB9AC",
3004
- description: "\uAE34 \uBB38\uC11C\uB97C \uD575\uC2EC\uB9CC \uC694\uC57D",
3005
- prompt: "\uB2E4\uC74C \uB0B4\uC6A9\uC744 \uD575\uC2EC\uB9CC \uC694\uC57D\uD574\uC8FC\uC138\uC694: ",
3006
- category: "\uC815\uB9AC"
3007
- }
3008
- ];
3009
- var injectStyles = () => {
3010
- if (typeof document === "undefined") return;
3011
- const styleId = "chatllm-styles";
3012
- if (document.getElementById(styleId)) return;
3013
- const style = document.createElement("style");
3014
- style.id = styleId;
3015
- style.textContent = `
3016
- @keyframes chatllm-typing {
3017
- 0%, 80%, 100% {
3018
- transform: scale(0);
3019
- opacity: 0.5;
3020
- }
3021
- 40% {
3022
- transform: scale(1);
3023
- opacity: 1;
3024
- }
3025
- }
3026
-
3027
- .chatllm-root {
3028
- --chatllm-primary: #3b82f6;
3029
- --chatllm-primary-hover: #2563eb;
3030
- --chatllm-primary-light: #dbeafe;
3031
- --chatllm-bg: #ffffff;
3032
- --chatllm-bg-secondary: #f9fafb;
3033
- --chatllm-bg-tertiary: #f3f4f6;
3034
- --chatllm-bg-hover: #f3f4f6;
3035
- --chatllm-bg-active: #eff6ff;
3036
- --chatllm-bg-disabled: #e5e7eb;
3037
- --chatllm-sidebar-bg: #ffffff;
3038
- --chatllm-input-bg: #f9fafb;
3039
- --chatllm-text: #1f2937;
3040
- --chatllm-text-muted: #6b7280;
3041
- --chatllm-border: #e5e7eb;
3042
- --chatllm-border-light: #f3f4f6;
3043
- --chatllm-error: #ef4444;
3044
- --chatllm-success: #22c55e;
3045
- --chatllm-user-avatar: #e5e7eb;
3046
- --chatllm-assistant-avatar: #dbeafe;
3047
- }
3048
-
3049
- .chatllm-root.chatllm-dark {
3050
- --chatllm-primary: #60a5fa;
3051
- --chatllm-primary-hover: #3b82f6;
3052
- --chatllm-primary-light: #1e3a5f;
3053
- --chatllm-bg: #111827;
3054
- --chatllm-bg-secondary: #1f2937;
3055
- --chatllm-bg-tertiary: #374151;
3056
- --chatllm-bg-hover: #374151;
3057
- --chatllm-bg-active: #1e3a5f;
3058
- --chatllm-bg-disabled: #374151;
3059
- --chatllm-sidebar-bg: #111827;
3060
- --chatllm-input-bg: #1f2937;
3061
- --chatllm-text: #f9fafb;
3062
- --chatllm-text-muted: #9ca3af;
3063
- --chatllm-border: #374151;
3064
- --chatllm-border-light: #1f2937;
3065
- --chatllm-user-avatar: #374151;
3066
- --chatllm-assistant-avatar: #1e3a5f;
3067
- }
3068
-
3069
- .chatllm-root * {
3070
- box-sizing: border-box;
3071
- }
3072
-
3073
- .chatllm-root textarea::placeholder {
3074
- color: var(--chatllm-text-muted);
3075
- }
3076
-
3077
- .chatllm-root button:focus-visible {
3078
- outline: 2px solid var(--chatllm-primary);
3079
- outline-offset: 2px;
3080
- }
3081
-
3082
- .chatllm-message-list::-webkit-scrollbar {
3083
- width: 6px;
3084
- }
3085
-
3086
- .chatllm-message-list::-webkit-scrollbar-track {
3087
- background: transparent;
3088
- }
3089
-
3090
- .chatllm-message-list::-webkit-scrollbar-thumb {
3091
- background-color: var(--chatllm-border);
3092
- border-radius: 3px;
3093
- }
3094
- `;
3095
- document.head.appendChild(style);
2958
+ userProfile: {},
2959
+ useMemory: true,
2960
+ language: "auto"
3096
2961
  };
3097
- var ChatUI = ({
3098
- models,
3099
- actions = DEFAULT_ACTIONS,
3100
- templates = DEFAULT_TEMPLATES,
2962
+ var SettingsModal = ({
2963
+ isOpen,
2964
+ onClose,
3101
2965
  personalization,
3102
- apiKey,
3103
- apiEndpoint = "/api/chat",
3104
- theme,
3105
- showSidebar = true,
3106
- showSettings = true,
3107
- showModelSelector = true,
3108
- systemPrompt,
3109
- contextCompressionThreshold = 20,
3110
- keepRecentMessages = 6,
3111
- storageKey = "chatllm_sessions",
3112
- className = "",
3113
- onSendMessage,
3114
- onSessionChange,
3115
- onError
2966
+ onPersonalizationChange,
2967
+ apiKey = "",
2968
+ onApiKeyChange,
2969
+ onClearAllData,
2970
+ apiKeyLabel = "API Key",
2971
+ apiKeyDescription = "Cloud \uBAA8\uB378 \uC0AC\uC6A9\uC5D0 \uD544\uC694\uD569\uB2C8\uB2E4"
3116
2972
  }) => {
3117
- React8.useEffect(() => {
3118
- injectStyles();
3119
- }, []);
3120
- const hookOptions = {
3121
- models,
3122
- actions,
3123
- initialPersonalization: personalization,
3124
- apiKey,
3125
- apiEndpoint,
3126
- initialModel: models[0]?.id,
3127
- storageKey,
3128
- contextCompressionThreshold,
3129
- keepRecentMessages,
3130
- onSendMessage,
3131
- onSessionChange,
3132
- onError
2973
+ const [activeTab, setActiveTab] = useState8("general");
2974
+ const [localApiKey, setLocalApiKey] = useState8(apiKey);
2975
+ if (!isOpen) return null;
2976
+ const updateResponseStyle = (key, value) => {
2977
+ onPersonalizationChange({
2978
+ ...personalization,
2979
+ responseStyle: {
2980
+ ...personalization.responseStyle,
2981
+ [key]: value
2982
+ }
2983
+ });
3133
2984
  };
3134
- const {
3135
- sessions,
3136
- currentSession,
3137
- currentSessionId,
3138
- messages,
3139
- input,
3140
- isLoading,
3141
- selectedModel,
3142
- sidebarOpen,
3143
- settingsOpen,
3144
- quotedText,
3145
- selectedAction,
3146
- copiedMessageId,
3147
- editingMessageId,
3148
- personalization: currentPersonalization,
3149
- setInput,
3150
- sendMessage,
3151
- stopGeneration,
3152
- newSession,
3153
- selectSession,
3154
- deleteSession,
3155
- setModel,
3156
- toggleSidebar,
3157
- openSettings,
3158
- closeSettings,
3159
- setQuotedText,
3160
- setSelectedAction,
3161
- copyMessage,
3162
- startEdit,
3163
- cancelEdit,
3164
- saveEdit,
3165
- regenerate,
3166
- updatePersonalization
3167
- } = useChatUI(hookOptions);
3168
- const greeting = currentPersonalization.userProfile.nickname ? `\uC548\uB155\uD558\uC138\uC694, ${currentPersonalization.userProfile.nickname}\uB2D8` : "\uC548\uB155\uD558\uC138\uC694";
3169
- const handleTemplateClick = (template) => {
3170
- setInput(template.prompt);
3171
- };
3172
- const handleActionSelect = (action) => {
3173
- setSelectedAction(action);
3174
- };
3175
- const handleSubmit = () => {
3176
- sendMessage();
3177
- };
3178
- const [memoryPanelOpen, setMemoryPanelOpen] = useState8(false);
3179
- const memoryItems = React8.useMemo(() => {
3180
- const items = [];
3181
- if (currentSession?.contextSummary) {
3182
- items.push({
3183
- id: "context_summary",
3184
- key: "\uB300\uD654 \uCEE8\uD14D\uC2A4\uD2B8 \uC694\uC57D",
3185
- value: currentSession.contextSummary,
3186
- category: "context",
3187
- timestamp: currentSession.updatedAt
3188
- });
3189
- }
3190
- if (currentPersonalization.userProfile.nickname) {
3191
- items.push({
3192
- id: "pref_nickname",
3193
- key: "\uC0AC\uC6A9\uC790 \uB2C9\uB124\uC784",
3194
- value: currentPersonalization.userProfile.nickname,
3195
- category: "preference",
3196
- timestamp: Date.now()
3197
- });
3198
- }
3199
- if (currentPersonalization.userProfile.occupation) {
3200
- items.push({
3201
- id: "pref_occupation",
3202
- key: "\uC9C1\uC5C5/\uC5ED\uD560",
3203
- value: currentPersonalization.userProfile.occupation,
3204
- category: "preference",
3205
- timestamp: Date.now()
3206
- });
3207
- }
3208
- if (currentPersonalization.userProfile.additionalInfo) {
3209
- items.push({
3210
- id: "pref_info",
3211
- key: "\uCD94\uAC00 \uC815\uBCF4",
3212
- value: currentPersonalization.userProfile.additionalInfo,
3213
- category: "preference",
3214
- timestamp: Date.now()
3215
- });
3216
- }
3217
- return items;
3218
- }, [currentSession, currentPersonalization]);
3219
- const themeClass = theme?.mode === "dark" ? "chatllm-dark" : "";
3220
- return /* @__PURE__ */ jsxs10(
3221
- "div",
3222
- {
3223
- className: `chatllm-root ${themeClass} ${className}`,
3224
- style: {
3225
- display: "flex",
3226
- height: "100%",
3227
- backgroundColor: "var(--chatllm-bg-secondary)",
3228
- fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif'
3229
- },
3230
- children: [
3231
- showSidebar && /* @__PURE__ */ jsx11(
3232
- ChatSidebar,
3233
- {
3234
- sessions,
3235
- currentSessionId,
3236
- onSelectSession: selectSession,
3237
- onNewSession: newSession,
3238
- onDeleteSession: deleteSession,
3239
- isOpen: sidebarOpen,
3240
- onToggle: toggleSidebar
3241
- }
3242
- ),
3243
- /* @__PURE__ */ jsxs10(
3244
- "main",
3245
- {
3246
- style: {
3247
- flex: 1,
3248
- display: "flex",
3249
- flexDirection: "column",
3250
- backgroundColor: "var(--chatllm-bg)",
3251
- minWidth: 0
3252
- },
3253
- children: [
3254
- /* @__PURE__ */ jsx11(
3255
- ChatHeader,
3256
- {
3257
- title: currentSession?.title || "\uC0C8 \uB300\uD654",
3258
- model: selectedModel,
3259
- models,
3260
- onModelChange: setModel,
3261
- onSettingsOpen: openSettings,
3262
- onSidebarToggle: toggleSidebar,
3263
- sidebarOpen
3264
- }
3265
- ),
3266
- messages.length === 0 ? /* @__PURE__ */ jsx11(
3267
- EmptyState,
3268
- {
3269
- greeting,
3270
- templates,
3271
- onTemplateClick: handleTemplateClick,
3272
- actions,
3273
- onActionSelect: handleActionSelect
3274
- }
3275
- ) : /* @__PURE__ */ jsx11(
3276
- MessageList,
3277
- {
3278
- messages,
3279
- isLoading,
3280
- onCopy: copyMessage,
3281
- onEdit: startEdit,
3282
- onRegenerate: regenerate,
3283
- onQuote: setQuotedText,
3284
- copiedId: copiedMessageId,
3285
- editingId: editingMessageId
3286
- }
3287
- ),
3288
- /* @__PURE__ */ jsx11(
3289
- ChatInput,
3290
- {
3291
- value: input,
3292
- onChange: setInput,
3293
- onSubmit: handleSubmit,
3294
- onStop: stopGeneration,
3295
- isLoading,
3296
- placeholder: "\uBA54\uC2DC\uC9C0\uB97C \uC785\uB825\uD558\uC138\uC694...",
3297
- quotedText,
3298
- onClearQuote: () => setQuotedText(null),
3299
- selectedAction,
3300
- onClearAction: () => setSelectedAction(null),
3301
- onActionSelect: setSelectedAction,
3302
- actions
3303
- }
3304
- )
3305
- ]
3306
- }
3307
- ),
3308
- /* @__PURE__ */ jsx11(
3309
- MemoryPanel,
3310
- {
3311
- items: memoryItems,
3312
- contextSummary: currentSession?.contextSummary,
3313
- isOpen: memoryPanelOpen,
3314
- onToggle: () => setMemoryPanelOpen(!memoryPanelOpen)
3315
- }
3316
- )
3317
- ]
3318
- }
3319
- );
3320
- };
3321
-
3322
- // src/react/components/SettingsModal.tsx
3323
- import { useState as useState9 } from "react";
3324
- import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
3325
- var DEFAULT_PERSONALIZATION2 = {
3326
- responseStyle: {
3327
- warmth: "medium",
3328
- enthusiasm: "medium",
3329
- emojiUsage: "low",
3330
- formatting: "default",
3331
- verbosity: "balanced"
3332
- },
3333
- userProfile: {},
3334
- useMemory: true,
3335
- language: "auto"
3336
- };
3337
- var SettingsModal = ({
3338
- isOpen,
3339
- onClose,
3340
- personalization,
3341
- onPersonalizationChange,
3342
- apiKey = "",
3343
- onApiKeyChange,
3344
- onClearAllData,
3345
- apiKeyLabel = "API Key",
3346
- apiKeyDescription = "Cloud \uBAA8\uB378 \uC0AC\uC6A9\uC5D0 \uD544\uC694\uD569\uB2C8\uB2E4"
3347
- }) => {
3348
- const [activeTab, setActiveTab] = useState9("general");
3349
- const [localApiKey, setLocalApiKey] = useState9(apiKey);
3350
- if (!isOpen) return null;
3351
- const updateResponseStyle = (key, value) => {
3352
- onPersonalizationChange({
3353
- ...personalization,
3354
- responseStyle: {
3355
- ...personalization.responseStyle,
3356
- [key]: value
3357
- }
3358
- });
3359
- };
3360
- const updateUserProfile = (key, value) => {
3361
- onPersonalizationChange({
3362
- ...personalization,
3363
- userProfile: {
3364
- ...personalization.userProfile,
3365
- [key]: value
3366
- }
3367
- });
2985
+ const updateUserProfile = (key, value) => {
2986
+ onPersonalizationChange({
2987
+ ...personalization,
2988
+ userProfile: {
2989
+ ...personalization.userProfile,
2990
+ [key]: value
2991
+ }
2992
+ });
3368
2993
  };
3369
2994
  const handleApiKeyChange = (value) => {
3370
2995
  setLocalApiKey(value);
3371
2996
  onApiKeyChange?.(value);
3372
2997
  };
3373
- return /* @__PURE__ */ jsx12(
2998
+ return /* @__PURE__ */ jsx11(
3374
2999
  "div",
3375
3000
  {
3376
3001
  className: "chatllm-settings-overlay",
@@ -3384,7 +3009,7 @@ var SettingsModal = ({
3384
3009
  zIndex: 1e3
3385
3010
  },
3386
3011
  onClick: onClose,
3387
- children: /* @__PURE__ */ jsxs11(
3012
+ children: /* @__PURE__ */ jsxs10(
3388
3013
  "div",
3389
3014
  {
3390
3015
  className: "chatllm-settings-modal",
@@ -3402,7 +3027,7 @@ var SettingsModal = ({
3402
3027
  },
3403
3028
  onClick: (e) => e.stopPropagation(),
3404
3029
  children: [
3405
- /* @__PURE__ */ jsxs11(
3030
+ /* @__PURE__ */ jsxs10(
3406
3031
  "div",
3407
3032
  {
3408
3033
  style: {
@@ -3413,7 +3038,7 @@ var SettingsModal = ({
3413
3038
  flexDirection: "column"
3414
3039
  },
3415
3040
  children: [
3416
- /* @__PURE__ */ jsx12("div", { style: { padding: "16px", borderBottom: "1px solid var(--chatllm-border, #e5e7eb)" }, children: /* @__PURE__ */ jsx12(
3041
+ /* @__PURE__ */ jsx11("div", { style: { padding: "16px", borderBottom: "1px solid var(--chatllm-border, #e5e7eb)" }, children: /* @__PURE__ */ jsx11(
3417
3042
  "button",
3418
3043
  {
3419
3044
  onClick: onClose,
@@ -3427,11 +3052,11 @@ var SettingsModal = ({
3427
3052
  alignItems: "center",
3428
3053
  justifyContent: "center"
3429
3054
  },
3430
- children: /* @__PURE__ */ jsx12(IconSvg, { name: "close-line", size: 20, color: "var(--chatllm-text-muted, #6b7280)" })
3055
+ children: /* @__PURE__ */ jsx11(IconSvg, { name: "close-line", size: 20, color: "var(--chatllm-text-muted, #6b7280)" })
3431
3056
  }
3432
3057
  ) }),
3433
- /* @__PURE__ */ jsxs11("nav", { style: { flex: 1, padding: "8px" }, children: [
3434
- /* @__PURE__ */ jsx12(
3058
+ /* @__PURE__ */ jsxs10("nav", { style: { flex: 1, padding: "8px" }, children: [
3059
+ /* @__PURE__ */ jsx11(
3435
3060
  TabButton,
3436
3061
  {
3437
3062
  active: activeTab === "general",
@@ -3440,7 +3065,7 @@ var SettingsModal = ({
3440
3065
  label: "\uC77C\uBC18"
3441
3066
  }
3442
3067
  ),
3443
- /* @__PURE__ */ jsx12(
3068
+ /* @__PURE__ */ jsx11(
3444
3069
  TabButton,
3445
3070
  {
3446
3071
  active: activeTab === "personalization",
@@ -3449,7 +3074,7 @@ var SettingsModal = ({
3449
3074
  label: "\uAC1C\uC778 \uB9DE\uCDA4 \uC124\uC815"
3450
3075
  }
3451
3076
  ),
3452
- /* @__PURE__ */ jsx12(
3077
+ /* @__PURE__ */ jsx11(
3453
3078
  TabButton,
3454
3079
  {
3455
3080
  active: activeTab === "data",
@@ -3462,24 +3087,24 @@ var SettingsModal = ({
3462
3087
  ]
3463
3088
  }
3464
3089
  ),
3465
- /* @__PURE__ */ jsxs11("div", { style: { flex: 1, overflow: "auto", padding: "24px" }, children: [
3466
- activeTab === "general" && /* @__PURE__ */ jsxs11("div", { children: [
3467
- /* @__PURE__ */ jsx12("h2", { style: { fontSize: "20px", fontWeight: 600, marginBottom: "24px", color: "var(--chatllm-text, #1f2937)" }, children: "\uC77C\uBC18" }),
3468
- /* @__PURE__ */ jsx12(SettingRow, { label: "\uC5B8\uC5B4", children: /* @__PURE__ */ jsxs11(
3090
+ /* @__PURE__ */ jsxs10("div", { style: { flex: 1, overflow: "auto", padding: "24px" }, children: [
3091
+ activeTab === "general" && /* @__PURE__ */ jsxs10("div", { children: [
3092
+ /* @__PURE__ */ jsx11("h2", { style: { fontSize: "20px", fontWeight: 600, marginBottom: "24px", color: "var(--chatllm-text, #1f2937)" }, children: "\uC77C\uBC18" }),
3093
+ /* @__PURE__ */ jsx11(SettingRow, { label: "\uC5B8\uC5B4", children: /* @__PURE__ */ jsxs10(
3469
3094
  "select",
3470
3095
  {
3471
3096
  value: personalization.language,
3472
3097
  onChange: (e) => onPersonalizationChange({ ...personalization, language: e.target.value }),
3473
3098
  style: selectStyle,
3474
3099
  children: [
3475
- /* @__PURE__ */ jsx12("option", { value: "auto", children: "\uC790\uB3D9 \uD0D0\uC9C0" }),
3476
- /* @__PURE__ */ jsx12("option", { value: "ko", children: "\uD55C\uAD6D\uC5B4" }),
3477
- /* @__PURE__ */ jsx12("option", { value: "en", children: "English" }),
3478
- /* @__PURE__ */ jsx12("option", { value: "ja", children: "\u65E5\u672C\u8A9E" })
3100
+ /* @__PURE__ */ jsx11("option", { value: "auto", children: "\uC790\uB3D9 \uD0D0\uC9C0" }),
3101
+ /* @__PURE__ */ jsx11("option", { value: "ko", children: "\uD55C\uAD6D\uC5B4" }),
3102
+ /* @__PURE__ */ jsx11("option", { value: "en", children: "English" }),
3103
+ /* @__PURE__ */ jsx11("option", { value: "ja", children: "\u65E5\u672C\u8A9E" })
3479
3104
  ]
3480
3105
  }
3481
3106
  ) }),
3482
- /* @__PURE__ */ jsx12(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__ */ jsx12(
3107
+ /* @__PURE__ */ jsx11(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__ */ jsx11(
3483
3108
  "button",
3484
3109
  {
3485
3110
  onClick: () => onPersonalizationChange(DEFAULT_PERSONALIZATION2),
@@ -3487,11 +3112,11 @@ var SettingsModal = ({
3487
3112
  children: "\uCD08\uAE30\uD654"
3488
3113
  }
3489
3114
  ) }),
3490
- onApiKeyChange && /* @__PURE__ */ jsxs11("div", { style: { marginTop: "32px", paddingTop: "24px", borderTop: "1px solid var(--chatllm-border, #e5e7eb)" }, children: [
3491
- /* @__PURE__ */ jsx12("h3", { style: { fontSize: "16px", fontWeight: 500, marginBottom: "16px", color: "var(--chatllm-text, #1f2937)" }, children: "API \uC124\uC815" }),
3492
- /* @__PURE__ */ jsxs11("div", { children: [
3493
- /* @__PURE__ */ jsx12("label", { style: { display: "block", fontSize: "14px", marginBottom: "8px", color: "var(--chatllm-text, #374151)" }, children: apiKeyLabel }),
3494
- /* @__PURE__ */ jsx12(
3115
+ onApiKeyChange && /* @__PURE__ */ jsxs10("div", { style: { marginTop: "32px", paddingTop: "24px", borderTop: "1px solid var(--chatllm-border, #e5e7eb)" }, children: [
3116
+ /* @__PURE__ */ jsx11("h3", { style: { fontSize: "16px", fontWeight: 500, marginBottom: "16px", color: "var(--chatllm-text, #1f2937)" }, children: "API \uC124\uC815" }),
3117
+ /* @__PURE__ */ jsxs10("div", { children: [
3118
+ /* @__PURE__ */ jsx11("label", { style: { display: "block", fontSize: "14px", marginBottom: "8px", color: "var(--chatllm-text, #374151)" }, children: apiKeyLabel }),
3119
+ /* @__PURE__ */ jsx11(
3495
3120
  "input",
3496
3121
  {
3497
3122
  type: "password",
@@ -3501,18 +3126,18 @@ var SettingsModal = ({
3501
3126
  style: inputStyle
3502
3127
  }
3503
3128
  ),
3504
- /* @__PURE__ */ jsx12("p", { style: { fontSize: "12px", color: "var(--chatllm-text-muted, #9ca3af)", marginTop: "4px" }, children: apiKeyDescription })
3129
+ /* @__PURE__ */ jsx11("p", { style: { fontSize: "12px", color: "var(--chatllm-text-muted, #9ca3af)", marginTop: "4px" }, children: apiKeyDescription })
3505
3130
  ] })
3506
3131
  ] })
3507
3132
  ] }),
3508
- activeTab === "personalization" && /* @__PURE__ */ jsxs11("div", { children: [
3509
- /* @__PURE__ */ jsx12("h2", { style: { fontSize: "20px", fontWeight: 600, marginBottom: "24px", color: "var(--chatllm-text, #1f2937)" }, children: "\uAC1C\uC778 \uB9DE\uCDA4 \uC124\uC815" }),
3510
- /* @__PURE__ */ jsxs11("section", { style: { marginBottom: "32px" }, children: [
3511
- /* @__PURE__ */ jsx12("h3", { style: { fontSize: "14px", fontWeight: 500, color: "var(--chatllm-text-muted, #6b7280)", marginBottom: "16px" }, children: "\uC0AC\uC6A9\uC790 \uD504\uB85C\uD544" }),
3512
- /* @__PURE__ */ jsxs11("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
3513
- /* @__PURE__ */ jsxs11("div", { children: [
3514
- /* @__PURE__ */ jsx12("label", { style: labelStyle, children: "\uB2C9\uB124\uC784" }),
3515
- /* @__PURE__ */ jsx12(
3133
+ activeTab === "personalization" && /* @__PURE__ */ jsxs10("div", { children: [
3134
+ /* @__PURE__ */ jsx11("h2", { style: { fontSize: "20px", fontWeight: 600, marginBottom: "24px", color: "var(--chatllm-text, #1f2937)" }, children: "\uAC1C\uC778 \uB9DE\uCDA4 \uC124\uC815" }),
3135
+ /* @__PURE__ */ jsxs10("section", { style: { marginBottom: "32px" }, children: [
3136
+ /* @__PURE__ */ jsx11("h3", { style: { fontSize: "14px", fontWeight: 500, color: "var(--chatllm-text-muted, #6b7280)", marginBottom: "16px" }, children: "\uC0AC\uC6A9\uC790 \uD504\uB85C\uD544" }),
3137
+ /* @__PURE__ */ jsxs10("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
3138
+ /* @__PURE__ */ jsxs10("div", { children: [
3139
+ /* @__PURE__ */ jsx11("label", { style: labelStyle, children: "\uB2C9\uB124\uC784" }),
3140
+ /* @__PURE__ */ jsx11(
3516
3141
  "input",
3517
3142
  {
3518
3143
  type: "text",
@@ -3523,9 +3148,9 @@ var SettingsModal = ({
3523
3148
  }
3524
3149
  )
3525
3150
  ] }),
3526
- /* @__PURE__ */ jsxs11("div", { children: [
3527
- /* @__PURE__ */ jsx12("label", { style: labelStyle, children: "\uC9C1\uC5C5" }),
3528
- /* @__PURE__ */ jsx12(
3151
+ /* @__PURE__ */ jsxs10("div", { children: [
3152
+ /* @__PURE__ */ jsx11("label", { style: labelStyle, children: "\uC9C1\uC5C5" }),
3153
+ /* @__PURE__ */ jsx11(
3529
3154
  "input",
3530
3155
  {
3531
3156
  type: "text",
@@ -3536,9 +3161,9 @@ var SettingsModal = ({
3536
3161
  }
3537
3162
  )
3538
3163
  ] }),
3539
- /* @__PURE__ */ jsxs11("div", { children: [
3540
- /* @__PURE__ */ jsx12("label", { style: labelStyle, children: "\uCD94\uAC00 \uC815\uBCF4" }),
3541
- /* @__PURE__ */ jsx12(
3164
+ /* @__PURE__ */ jsxs10("div", { children: [
3165
+ /* @__PURE__ */ jsx11("label", { style: labelStyle, children: "\uCD94\uAC00 \uC815\uBCF4" }),
3166
+ /* @__PURE__ */ jsx11(
3542
3167
  "textarea",
3543
3168
  {
3544
3169
  value: personalization.userProfile.additionalInfo || "",
@@ -3551,65 +3176,65 @@ var SettingsModal = ({
3551
3176
  ] })
3552
3177
  ] })
3553
3178
  ] }),
3554
- /* @__PURE__ */ jsxs11("section", { children: [
3555
- /* @__PURE__ */ jsx12("h3", { style: { fontSize: "14px", fontWeight: 500, color: "var(--chatllm-text-muted, #6b7280)", marginBottom: "16px" }, children: "\uC751\uB2F5 \uC2A4\uD0C0\uC77C" }),
3556
- /* @__PURE__ */ jsx12(SettingRow, { label: "\uB530\uB73B\uD568", children: /* @__PURE__ */ jsxs11(
3179
+ /* @__PURE__ */ jsxs10("section", { children: [
3180
+ /* @__PURE__ */ jsx11("h3", { style: { fontSize: "14px", fontWeight: 500, color: "var(--chatllm-text-muted, #6b7280)", marginBottom: "16px" }, children: "\uC751\uB2F5 \uC2A4\uD0C0\uC77C" }),
3181
+ /* @__PURE__ */ jsx11(SettingRow, { label: "\uB530\uB73B\uD568", children: /* @__PURE__ */ jsxs10(
3557
3182
  "select",
3558
3183
  {
3559
3184
  value: personalization.responseStyle.warmth,
3560
3185
  onChange: (e) => updateResponseStyle("warmth", e.target.value),
3561
3186
  style: selectStyle,
3562
3187
  children: [
3563
- /* @__PURE__ */ jsx12("option", { value: "high", children: "\uB192\uC74C - \uCE5C\uADFC\uD558\uACE0 \uB530\uB73B\uD558\uAC8C" }),
3564
- /* @__PURE__ */ jsx12("option", { value: "medium", children: "\uAE30\uBCF8\uAC12" }),
3565
- /* @__PURE__ */ jsx12("option", { value: "low", children: "\uB0AE\uC74C - \uAC04\uACB0\uD558\uACE0 \uC0AC\uBB34\uC801\uC73C\uB85C" })
3188
+ /* @__PURE__ */ jsx11("option", { value: "high", children: "\uB192\uC74C - \uCE5C\uADFC\uD558\uACE0 \uB530\uB73B\uD558\uAC8C" }),
3189
+ /* @__PURE__ */ jsx11("option", { value: "medium", children: "\uAE30\uBCF8\uAC12" }),
3190
+ /* @__PURE__ */ jsx11("option", { value: "low", children: "\uB0AE\uC74C - \uAC04\uACB0\uD558\uACE0 \uC0AC\uBB34\uC801\uC73C\uB85C" })
3566
3191
  ]
3567
3192
  }
3568
3193
  ) }),
3569
- /* @__PURE__ */ jsx12(SettingRow, { label: "\uC5F4\uC815\uC801", children: /* @__PURE__ */ jsxs11(
3194
+ /* @__PURE__ */ jsx11(SettingRow, { label: "\uC5F4\uC815\uC801", children: /* @__PURE__ */ jsxs10(
3570
3195
  "select",
3571
3196
  {
3572
3197
  value: personalization.responseStyle.enthusiasm,
3573
3198
  onChange: (e) => updateResponseStyle("enthusiasm", e.target.value),
3574
3199
  style: selectStyle,
3575
3200
  children: [
3576
- /* @__PURE__ */ jsx12("option", { value: "high", children: "\uB192\uC74C - \uC801\uADF9\uC801\uC774\uACE0 \uD65C\uBC1C\uD558\uAC8C" }),
3577
- /* @__PURE__ */ jsx12("option", { value: "medium", children: "\uAE30\uBCF8\uAC12" }),
3578
- /* @__PURE__ */ jsx12("option", { value: "low", children: "\uB0AE\uC74C - \uCC28\uBD84\uD558\uACE0 \uC808\uC81C\uC788\uAC8C" })
3201
+ /* @__PURE__ */ jsx11("option", { value: "high", children: "\uB192\uC74C - \uC801\uADF9\uC801\uC774\uACE0 \uD65C\uBC1C\uD558\uAC8C" }),
3202
+ /* @__PURE__ */ jsx11("option", { value: "medium", children: "\uAE30\uBCF8\uAC12" }),
3203
+ /* @__PURE__ */ jsx11("option", { value: "low", children: "\uB0AE\uC74C - \uCC28\uBD84\uD558\uACE0 \uC808\uC81C\uC788\uAC8C" })
3579
3204
  ]
3580
3205
  }
3581
3206
  ) }),
3582
- /* @__PURE__ */ jsx12(SettingRow, { label: "\uC774\uBAA8\uC9C0 \uC0AC\uC6A9", children: /* @__PURE__ */ jsxs11(
3207
+ /* @__PURE__ */ jsx11(SettingRow, { label: "\uC774\uBAA8\uC9C0 \uC0AC\uC6A9", children: /* @__PURE__ */ jsxs10(
3583
3208
  "select",
3584
3209
  {
3585
3210
  value: personalization.responseStyle.emojiUsage,
3586
3211
  onChange: (e) => updateResponseStyle("emojiUsage", e.target.value),
3587
3212
  style: selectStyle,
3588
3213
  children: [
3589
- /* @__PURE__ */ jsx12("option", { value: "high", children: "\uB192\uC74C - \uC790\uC8FC \uC0AC\uC6A9" }),
3590
- /* @__PURE__ */ jsx12("option", { value: "medium", children: "\uAE30\uBCF8\uAC12" }),
3591
- /* @__PURE__ */ jsx12("option", { value: "low", children: "\uB0AE\uC74C - \uAC70\uC758 \uC0AC\uC6A9 \uC548 \uD568" })
3214
+ /* @__PURE__ */ jsx11("option", { value: "high", children: "\uB192\uC74C - \uC790\uC8FC \uC0AC\uC6A9" }),
3215
+ /* @__PURE__ */ jsx11("option", { value: "medium", children: "\uAE30\uBCF8\uAC12" }),
3216
+ /* @__PURE__ */ jsx11("option", { value: "low", children: "\uB0AE\uC74C - \uAC70\uC758 \uC0AC\uC6A9 \uC548 \uD568" })
3592
3217
  ]
3593
3218
  }
3594
3219
  ) }),
3595
- /* @__PURE__ */ jsx12(SettingRow, { label: "\uC751\uB2F5 \uAE38\uC774", children: /* @__PURE__ */ jsxs11(
3220
+ /* @__PURE__ */ jsx11(SettingRow, { label: "\uC751\uB2F5 \uAE38\uC774", children: /* @__PURE__ */ jsxs10(
3596
3221
  "select",
3597
3222
  {
3598
3223
  value: personalization.responseStyle.verbosity,
3599
3224
  onChange: (e) => updateResponseStyle("verbosity", e.target.value),
3600
3225
  style: selectStyle,
3601
3226
  children: [
3602
- /* @__PURE__ */ jsx12("option", { value: "detailed", children: "\uC0C1\uC138 - \uC790\uC138\uD558\uAC8C \uC124\uBA85" }),
3603
- /* @__PURE__ */ jsx12("option", { value: "balanced", children: "\uAE30\uBCF8\uAC12" }),
3604
- /* @__PURE__ */ jsx12("option", { value: "concise", children: "\uAC04\uACB0 - \uD575\uC2EC\uB9CC \uC694\uC57D" })
3227
+ /* @__PURE__ */ jsx11("option", { value: "detailed", children: "\uC0C1\uC138 - \uC790\uC138\uD558\uAC8C \uC124\uBA85" }),
3228
+ /* @__PURE__ */ jsx11("option", { value: "balanced", children: "\uAE30\uBCF8\uAC12" }),
3229
+ /* @__PURE__ */ jsx11("option", { value: "concise", children: "\uAC04\uACB0 - \uD575\uC2EC\uB9CC \uC694\uC57D" })
3605
3230
  ]
3606
3231
  }
3607
3232
  ) })
3608
3233
  ] })
3609
3234
  ] }),
3610
- activeTab === "data" && /* @__PURE__ */ jsxs11("div", { children: [
3611
- /* @__PURE__ */ jsx12("h2", { style: { fontSize: "20px", fontWeight: 600, marginBottom: "24px", color: "var(--chatllm-text, #1f2937)" }, children: "\uB370\uC774\uD130 \uC81C\uC5B4" }),
3612
- /* @__PURE__ */ jsx12(SettingRow, { label: "\uBA54\uBAA8\uB9AC \uC0AC\uC6A9", description: "\uB300\uD654 \uCEE8\uD14D\uC2A4\uD2B8\uB97C \uAE30\uC5B5\uD569\uB2C8\uB2E4", children: /* @__PURE__ */ jsx12(
3235
+ activeTab === "data" && /* @__PURE__ */ jsxs10("div", { children: [
3236
+ /* @__PURE__ */ jsx11("h2", { style: { fontSize: "20px", fontWeight: 600, marginBottom: "24px", color: "var(--chatllm-text, #1f2937)" }, children: "\uB370\uC774\uD130 \uC81C\uC5B4" }),
3237
+ /* @__PURE__ */ jsx11(SettingRow, { label: "\uBA54\uBAA8\uB9AC \uC0AC\uC6A9", description: "\uB300\uD654 \uCEE8\uD14D\uC2A4\uD2B8\uB97C \uAE30\uC5B5\uD569\uB2C8\uB2E4", children: /* @__PURE__ */ jsx11(
3613
3238
  "button",
3614
3239
  {
3615
3240
  onClick: () => onPersonalizationChange({ ...personalization, useMemory: !personalization.useMemory }),
@@ -3623,7 +3248,7 @@ var SettingsModal = ({
3623
3248
  position: "relative",
3624
3249
  transition: "background-color 0.2s"
3625
3250
  },
3626
- children: /* @__PURE__ */ jsx12(
3251
+ children: /* @__PURE__ */ jsx11(
3627
3252
  "div",
3628
3253
  {
3629
3254
  style: {
@@ -3641,7 +3266,7 @@ var SettingsModal = ({
3641
3266
  )
3642
3267
  }
3643
3268
  ) }),
3644
- onClearAllData && /* @__PURE__ */ jsx12(SettingRow, { label: "\uB300\uD654 \uAE30\uB85D \uC0AD\uC81C", description: "\uBAA8\uB4E0 \uB300\uD654 \uAE30\uB85D\uC744 \uC0AD\uC81C\uD569\uB2C8\uB2E4", children: /* @__PURE__ */ jsx12(
3269
+ onClearAllData && /* @__PURE__ */ jsx11(SettingRow, { label: "\uB300\uD654 \uAE30\uB85D \uC0AD\uC81C", description: "\uBAA8\uB4E0 \uB300\uD654 \uAE30\uB85D\uC744 \uC0AD\uC81C\uD569\uB2C8\uB2E4", children: /* @__PURE__ */ jsx11(
3645
3270
  "button",
3646
3271
  {
3647
3272
  onClick: () => {
@@ -3661,7 +3286,7 @@ var SettingsModal = ({
3661
3286
  }
3662
3287
  );
3663
3288
  };
3664
- var TabButton = ({ active, onClick, icon, label }) => /* @__PURE__ */ jsxs11(
3289
+ var TabButton = ({ active, onClick, icon, label }) => /* @__PURE__ */ jsxs10(
3665
3290
  "button",
3666
3291
  {
3667
3292
  onClick,
@@ -3682,12 +3307,12 @@ var TabButton = ({ active, onClick, icon, label }) => /* @__PURE__ */ jsxs11(
3682
3307
  marginBottom: "4px"
3683
3308
  },
3684
3309
  children: [
3685
- /* @__PURE__ */ jsx12(IconSvg, { name: icon, size: 20 }),
3310
+ /* @__PURE__ */ jsx11(IconSvg, { name: icon, size: 20 }),
3686
3311
  label
3687
3312
  ]
3688
3313
  }
3689
3314
  );
3690
- var SettingRow = ({ label, description, children }) => /* @__PURE__ */ jsxs11(
3315
+ var SettingRow = ({ label, description, children }) => /* @__PURE__ */ jsxs10(
3691
3316
  "div",
3692
3317
  {
3693
3318
  style: {
@@ -3698,9 +3323,9 @@ var SettingRow = ({ label, description, children }) => /* @__PURE__ */ jsxs11(
3698
3323
  borderBottom: "1px solid var(--chatllm-border-light, #f3f4f6)"
3699
3324
  },
3700
3325
  children: [
3701
- /* @__PURE__ */ jsxs11("div", { children: [
3702
- /* @__PURE__ */ jsx12("span", { style: { fontSize: "14px", color: "var(--chatllm-text, #374151)" }, children: label }),
3703
- description && /* @__PURE__ */ jsx12("p", { style: { fontSize: "12px", color: "var(--chatllm-text-muted, #9ca3af)", marginTop: "2px" }, children: description })
3326
+ /* @__PURE__ */ jsxs10("div", { children: [
3327
+ /* @__PURE__ */ jsx11("span", { style: { fontSize: "14px", color: "var(--chatllm-text, #374151)" }, children: label }),
3328
+ description && /* @__PURE__ */ jsx11("p", { style: { fontSize: "12px", color: "var(--chatllm-text-muted, #9ca3af)", marginTop: "2px" }, children: description })
3704
3329
  ] }),
3705
3330
  children
3706
3331
  ]
@@ -3749,6 +3374,398 @@ var buttonDangerStyle = {
3749
3374
  color: "var(--chatllm-danger, #dc2626)",
3750
3375
  cursor: "pointer"
3751
3376
  };
3377
+
3378
+ // src/react/ChatUI.tsx
3379
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
3380
+ var DEFAULT_ACTIONS = [
3381
+ {
3382
+ id: "webSearch",
3383
+ label: "\uC6F9 \uAC80\uC0C9",
3384
+ icon: "search",
3385
+ description: "\uC6F9\uC5D0\uC11C \uC815\uBCF4\uB97C \uAC80\uC0C9\uD569\uB2C8\uB2E4",
3386
+ systemPrompt: "\uC6F9 \uAC80\uC0C9 \uACB0\uACFC\uB97C \uAE30\uBC18\uC73C\uB85C \uB2F5\uBCC0\uD574\uC8FC\uC138\uC694."
3387
+ },
3388
+ {
3389
+ id: "imageGen",
3390
+ label: "\uC774\uBBF8\uC9C0 \uC0DD\uC131",
3391
+ icon: "image",
3392
+ description: "\uD504\uB86C\uD504\uD2B8\uB85C \uC774\uBBF8\uC9C0\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4",
3393
+ systemPrompt: "\uC774\uBBF8\uC9C0 \uC0DD\uC131 \uC694\uCCAD\uC785\uB2C8\uB2E4."
3394
+ },
3395
+ {
3396
+ id: "codeAnalysis",
3397
+ label: "\uCF54\uB4DC \uBD84\uC11D",
3398
+ icon: "code",
3399
+ description: "\uCF54\uB4DC\uB97C \uBD84\uC11D\uD558\uACE0 \uC124\uBA85\uD569\uB2C8\uB2E4",
3400
+ systemPrompt: "\uCF54\uB4DC\uB97C \uBD84\uC11D\uD558\uACE0 \uC790\uC138\uD788 \uC124\uBA85\uD574\uC8FC\uC138\uC694."
3401
+ },
3402
+ {
3403
+ id: "summarize",
3404
+ label: "\uC694\uC57D",
3405
+ icon: "document",
3406
+ description: "\uAE34 \uD14D\uC2A4\uD2B8\uB97C \uC694\uC57D\uD569\uB2C8\uB2E4",
3407
+ systemPrompt: "\uB2E4\uC74C \uB0B4\uC6A9\uC744 \uD575\uC2EC\uB9CC \uAC04\uACB0\uD558\uAC8C \uC694\uC57D\uD574\uC8FC\uC138\uC694."
3408
+ }
3409
+ ];
3410
+ var DEFAULT_TEMPLATES = [
3411
+ {
3412
+ id: "1",
3413
+ title: "AI \uAE30\uBC18 \uAE00\uC4F0\uAE30",
3414
+ description: "\uBE14\uB85C\uADF8, \uC774\uBA54\uC77C, \uBCF4\uACE0\uC11C \uC791\uC131 \uB3C4\uC6C0",
3415
+ prompt: "\uB2E4\uC74C \uC8FC\uC81C\uC5D0 \uB300\uD574 \uBE14\uB85C\uADF8 \uAE00\uC744 \uC791\uC131\uD574\uC8FC\uC138\uC694: ",
3416
+ category: "\uAE00\uC4F0\uAE30"
3417
+ },
3418
+ {
3419
+ id: "2",
3420
+ title: "\uCF54\uB4DC \uB9AC\uBDF0",
3421
+ description: "\uCF54\uB4DC \uBD84\uC11D \uBC0F \uAC1C\uC120\uC810 \uC81C\uC548",
3422
+ prompt: "\uB2E4\uC74C \uCF54\uB4DC\uB97C \uB9AC\uBDF0\uD558\uACE0 \uAC1C\uC120\uC810\uC744 \uC81C\uC548\uD574\uC8FC\uC138\uC694: ",
3423
+ category: "\uAC1C\uBC1C"
3424
+ },
3425
+ {
3426
+ id: "3",
3427
+ title: "\uBC88\uC5ED \uB3C4\uC6B0\uBBF8",
3428
+ description: "\uC790\uC5F0\uC2A4\uB7EC\uC6B4 \uBC88\uC5ED \uBC0F \uAD50\uC815",
3429
+ prompt: "\uB2E4\uC74C \uD14D\uC2A4\uD2B8\uB97C \uC790\uC5F0\uC2A4\uB7FD\uAC8C \uBC88\uC5ED\uD574\uC8FC\uC138\uC694: ",
3430
+ category: "\uBC88\uC5ED"
3431
+ },
3432
+ {
3433
+ id: "4",
3434
+ title: "\uC694\uC57D \uC815\uB9AC",
3435
+ description: "\uAE34 \uBB38\uC11C\uB97C \uD575\uC2EC\uB9CC \uC694\uC57D",
3436
+ prompt: "\uB2E4\uC74C \uB0B4\uC6A9\uC744 \uD575\uC2EC\uB9CC \uC694\uC57D\uD574\uC8FC\uC138\uC694: ",
3437
+ category: "\uC815\uB9AC"
3438
+ }
3439
+ ];
3440
+ var injectStyles = () => {
3441
+ if (typeof document === "undefined") return;
3442
+ const styleId = "chatllm-styles";
3443
+ if (document.getElementById(styleId)) return;
3444
+ const style = document.createElement("style");
3445
+ style.id = styleId;
3446
+ style.textContent = `
3447
+ @keyframes chatllm-typing {
3448
+ 0%, 80%, 100% {
3449
+ transform: scale(0);
3450
+ opacity: 0.5;
3451
+ }
3452
+ 40% {
3453
+ transform: scale(1);
3454
+ opacity: 1;
3455
+ }
3456
+ }
3457
+
3458
+ .chatllm-root {
3459
+ --chatllm-primary: #3b82f6;
3460
+ --chatllm-primary-hover: #2563eb;
3461
+ --chatllm-primary-light: #dbeafe;
3462
+ --chatllm-bg: #ffffff;
3463
+ --chatllm-bg-secondary: #f9fafb;
3464
+ --chatllm-bg-tertiary: #f3f4f6;
3465
+ --chatllm-bg-hover: #f3f4f6;
3466
+ --chatllm-bg-active: #eff6ff;
3467
+ --chatllm-bg-disabled: #e5e7eb;
3468
+ --chatllm-sidebar-bg: #ffffff;
3469
+ --chatllm-input-bg: #f9fafb;
3470
+ --chatllm-text: #1f2937;
3471
+ --chatllm-text-muted: #6b7280;
3472
+ --chatllm-border: #e5e7eb;
3473
+ --chatllm-border-light: #f3f4f6;
3474
+ --chatllm-error: #ef4444;
3475
+ --chatllm-success: #22c55e;
3476
+ --chatllm-user-avatar: #e5e7eb;
3477
+ --chatllm-assistant-avatar: #dbeafe;
3478
+ }
3479
+
3480
+ .chatllm-root.chatllm-dark {
3481
+ --chatllm-primary: #60a5fa;
3482
+ --chatllm-primary-hover: #3b82f6;
3483
+ --chatllm-primary-light: #1e3a5f;
3484
+ --chatllm-bg: #111827;
3485
+ --chatllm-bg-secondary: #1f2937;
3486
+ --chatllm-bg-tertiary: #374151;
3487
+ --chatllm-bg-hover: #374151;
3488
+ --chatllm-bg-active: #1e3a5f;
3489
+ --chatllm-bg-disabled: #374151;
3490
+ --chatllm-sidebar-bg: #111827;
3491
+ --chatllm-input-bg: #1f2937;
3492
+ --chatllm-text: #f9fafb;
3493
+ --chatllm-text-muted: #9ca3af;
3494
+ --chatllm-border: #374151;
3495
+ --chatllm-border-light: #1f2937;
3496
+ --chatllm-user-avatar: #374151;
3497
+ --chatllm-assistant-avatar: #1e3a5f;
3498
+ }
3499
+
3500
+ .chatllm-root * {
3501
+ box-sizing: border-box;
3502
+ }
3503
+
3504
+ .chatllm-root textarea::placeholder {
3505
+ color: var(--chatllm-text-muted);
3506
+ }
3507
+
3508
+ .chatllm-root button:focus-visible {
3509
+ outline: 2px solid var(--chatllm-primary);
3510
+ outline-offset: 2px;
3511
+ }
3512
+
3513
+ .chatllm-message-list::-webkit-scrollbar {
3514
+ width: 6px;
3515
+ }
3516
+
3517
+ .chatllm-message-list::-webkit-scrollbar-track {
3518
+ background: transparent;
3519
+ }
3520
+
3521
+ .chatllm-message-list::-webkit-scrollbar-thumb {
3522
+ background-color: var(--chatllm-border);
3523
+ border-radius: 3px;
3524
+ }
3525
+ `;
3526
+ document.head.appendChild(style);
3527
+ };
3528
+ var ChatUI = ({
3529
+ models,
3530
+ actions = DEFAULT_ACTIONS,
3531
+ templates = DEFAULT_TEMPLATES,
3532
+ personalization,
3533
+ apiKey,
3534
+ onApiKeyChange,
3535
+ apiEndpoint = "/api/chat",
3536
+ theme,
3537
+ showSidebar = true,
3538
+ showSettings = true,
3539
+ showModelSelector = true,
3540
+ systemPrompt,
3541
+ contextCompressionThreshold = 20,
3542
+ keepRecentMessages = 6,
3543
+ storageKey = "chatllm_sessions",
3544
+ className = "",
3545
+ onSendMessage,
3546
+ onSessionChange,
3547
+ onError
3548
+ }) => {
3549
+ React9.useEffect(() => {
3550
+ injectStyles();
3551
+ }, []);
3552
+ const hookOptions = {
3553
+ models,
3554
+ actions,
3555
+ initialPersonalization: personalization,
3556
+ apiKey,
3557
+ apiEndpoint,
3558
+ initialModel: models[0]?.id,
3559
+ storageKey,
3560
+ contextCompressionThreshold,
3561
+ keepRecentMessages,
3562
+ onSendMessage,
3563
+ onSessionChange,
3564
+ onError
3565
+ };
3566
+ const {
3567
+ sessions,
3568
+ currentSession,
3569
+ currentSessionId,
3570
+ messages,
3571
+ input,
3572
+ isLoading,
3573
+ selectedModel,
3574
+ sidebarOpen,
3575
+ settingsOpen,
3576
+ quotedText,
3577
+ selectedAction,
3578
+ copiedMessageId,
3579
+ editingMessageId,
3580
+ personalization: currentPersonalization,
3581
+ setInput,
3582
+ sendMessage,
3583
+ stopGeneration,
3584
+ newSession,
3585
+ selectSession,
3586
+ deleteSession,
3587
+ setModel,
3588
+ toggleSidebar,
3589
+ openSettings,
3590
+ closeSettings,
3591
+ setQuotedText,
3592
+ setSelectedAction,
3593
+ copyMessage,
3594
+ startEdit,
3595
+ cancelEdit,
3596
+ saveEdit,
3597
+ regenerate,
3598
+ updatePersonalization
3599
+ } = useChatUI(hookOptions);
3600
+ const greeting = currentPersonalization.userProfile.nickname ? `\uC548\uB155\uD558\uC138\uC694, ${currentPersonalization.userProfile.nickname}\uB2D8` : "\uC548\uB155\uD558\uC138\uC694";
3601
+ const handleTemplateClick = (template) => {
3602
+ setInput(template.prompt);
3603
+ };
3604
+ const handleActionSelect = (action) => {
3605
+ setSelectedAction(action);
3606
+ };
3607
+ const handleSubmit = () => {
3608
+ sendMessage();
3609
+ };
3610
+ const [memoryPanelOpen, setMemoryPanelOpen] = useState9(false);
3611
+ const memoryItems = React9.useMemo(() => {
3612
+ const items = [];
3613
+ if (currentSession?.contextSummary) {
3614
+ items.push({
3615
+ id: "context_summary",
3616
+ key: "\uB300\uD654 \uCEE8\uD14D\uC2A4\uD2B8 \uC694\uC57D",
3617
+ value: currentSession.contextSummary,
3618
+ category: "context",
3619
+ timestamp: currentSession.updatedAt
3620
+ });
3621
+ }
3622
+ if (currentPersonalization.userProfile.nickname) {
3623
+ items.push({
3624
+ id: "pref_nickname",
3625
+ key: "\uC0AC\uC6A9\uC790 \uB2C9\uB124\uC784",
3626
+ value: currentPersonalization.userProfile.nickname,
3627
+ category: "preference",
3628
+ timestamp: Date.now()
3629
+ });
3630
+ }
3631
+ if (currentPersonalization.userProfile.occupation) {
3632
+ items.push({
3633
+ id: "pref_occupation",
3634
+ key: "\uC9C1\uC5C5/\uC5ED\uD560",
3635
+ value: currentPersonalization.userProfile.occupation,
3636
+ category: "preference",
3637
+ timestamp: Date.now()
3638
+ });
3639
+ }
3640
+ if (currentPersonalization.userProfile.additionalInfo) {
3641
+ items.push({
3642
+ id: "pref_info",
3643
+ key: "\uCD94\uAC00 \uC815\uBCF4",
3644
+ value: currentPersonalization.userProfile.additionalInfo,
3645
+ category: "preference",
3646
+ timestamp: Date.now()
3647
+ });
3648
+ }
3649
+ return items;
3650
+ }, [currentSession, currentPersonalization]);
3651
+ const themeClass = theme?.mode === "dark" ? "chatllm-dark" : "";
3652
+ return /* @__PURE__ */ jsxs11(
3653
+ "div",
3654
+ {
3655
+ className: `chatllm-root ${themeClass} ${className}`,
3656
+ style: {
3657
+ display: "flex",
3658
+ height: "100%",
3659
+ backgroundColor: "var(--chatllm-bg-secondary)",
3660
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif'
3661
+ },
3662
+ children: [
3663
+ showSidebar && /* @__PURE__ */ jsx12(
3664
+ ChatSidebar,
3665
+ {
3666
+ sessions,
3667
+ currentSessionId,
3668
+ onSelectSession: selectSession,
3669
+ onNewSession: newSession,
3670
+ onDeleteSession: deleteSession,
3671
+ isOpen: sidebarOpen,
3672
+ onToggle: toggleSidebar
3673
+ }
3674
+ ),
3675
+ /* @__PURE__ */ jsxs11(
3676
+ "main",
3677
+ {
3678
+ style: {
3679
+ flex: 1,
3680
+ display: "flex",
3681
+ flexDirection: "column",
3682
+ backgroundColor: "var(--chatllm-bg)",
3683
+ minWidth: 0
3684
+ },
3685
+ children: [
3686
+ /* @__PURE__ */ jsx12(
3687
+ ChatHeader,
3688
+ {
3689
+ title: currentSession?.title || "\uC0C8 \uB300\uD654",
3690
+ model: selectedModel,
3691
+ models,
3692
+ onModelChange: setModel,
3693
+ onSettingsOpen: openSettings,
3694
+ onSidebarToggle: toggleSidebar,
3695
+ sidebarOpen
3696
+ }
3697
+ ),
3698
+ messages.length === 0 ? /* @__PURE__ */ jsx12(
3699
+ EmptyState,
3700
+ {
3701
+ greeting,
3702
+ templates,
3703
+ onTemplateClick: handleTemplateClick,
3704
+ actions,
3705
+ onActionSelect: handleActionSelect
3706
+ }
3707
+ ) : /* @__PURE__ */ jsx12(
3708
+ MessageList,
3709
+ {
3710
+ messages,
3711
+ isLoading,
3712
+ onCopy: copyMessage,
3713
+ onEdit: startEdit,
3714
+ onRegenerate: regenerate,
3715
+ onQuote: setQuotedText,
3716
+ copiedId: copiedMessageId,
3717
+ editingId: editingMessageId
3718
+ }
3719
+ ),
3720
+ /* @__PURE__ */ jsx12(
3721
+ ChatInput,
3722
+ {
3723
+ value: input,
3724
+ onChange: setInput,
3725
+ onSubmit: handleSubmit,
3726
+ onStop: stopGeneration,
3727
+ isLoading,
3728
+ placeholder: "\uBA54\uC2DC\uC9C0\uB97C \uC785\uB825\uD558\uC138\uC694...",
3729
+ quotedText,
3730
+ onClearQuote: () => setQuotedText(null),
3731
+ selectedAction,
3732
+ onClearAction: () => setSelectedAction(null),
3733
+ onActionSelect: setSelectedAction,
3734
+ actions
3735
+ }
3736
+ )
3737
+ ]
3738
+ }
3739
+ ),
3740
+ /* @__PURE__ */ jsx12(
3741
+ MemoryPanel,
3742
+ {
3743
+ items: memoryItems,
3744
+ contextSummary: currentSession?.contextSummary,
3745
+ isOpen: memoryPanelOpen,
3746
+ onToggle: () => setMemoryPanelOpen(!memoryPanelOpen)
3747
+ }
3748
+ ),
3749
+ showSettings && /* @__PURE__ */ jsx12(
3750
+ SettingsModal,
3751
+ {
3752
+ isOpen: settingsOpen,
3753
+ onClose: closeSettings,
3754
+ personalization: currentPersonalization,
3755
+ onPersonalizationChange: updatePersonalization,
3756
+ apiKey,
3757
+ onApiKeyChange,
3758
+ onClearAllData: () => {
3759
+ sessions.forEach((s) => deleteSession(s.id));
3760
+ },
3761
+ apiKeyLabel: "API Key",
3762
+ apiKeyDescription: "Cloud \uBAA8\uB378 \uC0AC\uC6A9\uC5D0 \uD544\uC694\uD569\uB2C8\uB2E4"
3763
+ }
3764
+ )
3765
+ ]
3766
+ }
3767
+ );
3768
+ };
3752
3769
  export {
3753
3770
  ChatHeader,
3754
3771
  ChatInput,