@gendive/chatllm 0.21.5 → 0.21.7
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.
- package/dist/react/index.d.mts +65 -1
- package/dist/react/index.d.ts +65 -1
- package/dist/react/index.js +222 -38
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +221 -38
- package/dist/react/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react/index.d.mts
CHANGED
|
@@ -1819,6 +1819,46 @@ interface UseFloatingWidgetReturn {
|
|
|
1819
1819
|
toggle: () => void;
|
|
1820
1820
|
setTab: (tabKey: string) => void;
|
|
1821
1821
|
}
|
|
1822
|
+
/**
|
|
1823
|
+
* @description 대화 검색 결과 스니펫
|
|
1824
|
+
* @Todo vibecode - DB에서 반환되는 과거 대화 조각
|
|
1825
|
+
*/
|
|
1826
|
+
interface ConversationSnippet {
|
|
1827
|
+
/** 세션 ID */
|
|
1828
|
+
sessionId: string;
|
|
1829
|
+
/** 세션 제목 */
|
|
1830
|
+
sessionTitle?: string;
|
|
1831
|
+
/** 발화자 */
|
|
1832
|
+
role: 'user' | 'assistant';
|
|
1833
|
+
/** 메시지 내용 (또는 발췌) */
|
|
1834
|
+
content: string;
|
|
1835
|
+
/** 메시지 타임스탬프 */
|
|
1836
|
+
timestamp?: number;
|
|
1837
|
+
/** 검색 관련도 점수 (0-1) */
|
|
1838
|
+
relevance?: number;
|
|
1839
|
+
}
|
|
1840
|
+
/**
|
|
1841
|
+
* @description 대화 검색 옵션
|
|
1842
|
+
* @Todo vibecode - 검색 범위 제한용
|
|
1843
|
+
*/
|
|
1844
|
+
interface ConversationSearchOptions {
|
|
1845
|
+
/** 최대 결과 수 (기본: 5) */
|
|
1846
|
+
limit?: number;
|
|
1847
|
+
/** 특정 세션으로 제한 */
|
|
1848
|
+
sessionId?: string;
|
|
1849
|
+
}
|
|
1850
|
+
/**
|
|
1851
|
+
* @description createConversationSearchSkill 팩토리 옵션
|
|
1852
|
+
* @Todo vibecode - 소비 앱이 DB 검색 구현을 제공
|
|
1853
|
+
*/
|
|
1854
|
+
interface ConversationSearchSkillOptions {
|
|
1855
|
+
/** 검색 구현 (호스트 DB 쿼리) */
|
|
1856
|
+
onSearch: (query: string, options?: ConversationSearchOptions) => Promise<ConversationSnippet[]>;
|
|
1857
|
+
/** 스킬 라벨 (기본: '대화 검색') */
|
|
1858
|
+
label?: string;
|
|
1859
|
+
/** 비활성화 여부 */
|
|
1860
|
+
disabled?: boolean;
|
|
1861
|
+
}
|
|
1822
1862
|
|
|
1823
1863
|
/**
|
|
1824
1864
|
* @description ChatUI 메인 컴포넌트
|
|
@@ -2401,6 +2441,30 @@ declare const createAdvancedResearchSkill: (options: AdvancedResearchOptions) =>
|
|
|
2401
2441
|
*/
|
|
2402
2442
|
declare const createDeepResearchSkill: (callbacks: DeepResearchCallbacks) => SkillConfig;
|
|
2403
2443
|
|
|
2444
|
+
/**
|
|
2445
|
+
* @description 대화 검색 스킬 팩토리
|
|
2446
|
+
* @Todo vibecode - 호스트 DB 검색을 SkillConfig로 래핑하여 LLM tool use로 과거 대화 검색
|
|
2447
|
+
*
|
|
2448
|
+
* 사용 예시:
|
|
2449
|
+
* ```ts
|
|
2450
|
+
* import { createConversationSearchSkill } from '@gendive/chatllm/react';
|
|
2451
|
+
*
|
|
2452
|
+
* const searchSkill = createConversationSearchSkill({
|
|
2453
|
+
* onSearch: async (query, options) => {
|
|
2454
|
+
* return await db.conversations.search(query, options?.limit);
|
|
2455
|
+
* },
|
|
2456
|
+
* });
|
|
2457
|
+
*
|
|
2458
|
+
* <ChatUI skills={{ conversation_search: searchSkill }} />
|
|
2459
|
+
* ```
|
|
2460
|
+
*/
|
|
2461
|
+
|
|
2462
|
+
/**
|
|
2463
|
+
* @description 대화 검색 스킬 생성 팩토리
|
|
2464
|
+
* @Todo vibecode - LLM이 tool use로 과거 대화를 검색할 수 있는 스킬 생성
|
|
2465
|
+
*/
|
|
2466
|
+
declare const createConversationSearchSkill: (options: ConversationSearchSkillOptions) => SkillConfig;
|
|
2467
|
+
|
|
2404
2468
|
/**
|
|
2405
2469
|
* @description Remix Icons wrapper component
|
|
2406
2470
|
* @see https://remixicon.com/
|
|
@@ -3018,4 +3082,4 @@ declare const DEFAULT_PROJECT_TITLE = "\uAE30\uBCF8 \uD504\uB85C\uC81D\uD2B8";
|
|
|
3018
3082
|
*/
|
|
3019
3083
|
declare const migrateSessionsToProjects: (storageKey: string) => void;
|
|
3020
3084
|
|
|
3021
|
-
export { type ActionItem, type ActionMenuProps, type AdvancedResearchOptions, type AlternativeResponse, ArtifactCard, type ArtifactCardProps, type ArtifactContentPart, type ChatAttachment, ChatFloatingWidget, type ChatFloatingWidgetProps, ChatHeader, ChatInput, type ChatMessage, type ChatProject, type ChatSession, ChatSidebar, type ChatToolDefinition, type ChatToolParameter, ChatUI, type ChatUIComponents, type ChatUIProps, type ChecklistBlock, ChecklistCard, type ChecklistCardProps, type ChecklistItem, ChecklistMiniIndicator, type ChecklistMiniIndicatorProps, ChecklistPanel, type ChecklistPanelProps, CompactChatView, type CompactChatViewProps, ContentPartRenderer, type ContentPartRendererProps, DEFAULT_PROJECT_ID, DEFAULT_PROJECT_TITLE, type DeepResearchCallbacks, type DeepResearchProgress, DeepResearchProgressUI, DevDiveAvatar, type DevDiveAvatarProps, DevDiveFabCharacter, type DevDiveFabCharacterProps, EmptyState, type EmptyStateProps, type ErrorContentPart, FileContentCard, type FileContentCardProps, type FileContentPart, FloatingFab, type FloatingFabProps, type FloatingNotification, FloatingPanel, type FloatingPanelProps, type FloatingPosition, FloatingTabBar, type FloatingTabBarProps, type FloatingTabItem, type FloatingWidgetTab, type HeaderProps, Icon, type IconName, type IconProps, IconSvg, ImageContentCard, type ImageContentCardProps, type ImageContentPart, type InputProps, LinkChip, type LinkChipProps, type ManualSkillItem, MarkdownRenderer, type MarkdownRendererProps, type MemoryItem, MemoryPanel, type MemoryPanelProps, MessageBubble, type MessageBubbleProps, type MessageContentPart, MessageList, type MessageListProps, type ModelConfig, type ModelSelectorProps, type OpenAITool, type PatternAnalysisResult, type PersonalizationConfig, type PollBlock, PollCard, type PollCardProps, type PollOption, type PollQuestion, type PollResponse, type PollState, type ProjectFile, ProjectSelector, type ProjectSelectorProps, ProjectSettingsModal, type ProjectSettingsModalProps, type PromptTemplate, type ProviderType, type ResizeEdge, ResizeHandles, type ResizeHandlesProps, type ResponseStyle, type SearchResult, type SearchResultContentPart, type SendMessageParams, type SendMessageResponse, type SendMessageResponseBase, type SendMessageResponseWithHeaders, type SessionContext, type SessionContextItem, SettingsModal, type SettingsModalProps, type SettingsTab, type SidebarProps, type SkillConfig, type SkillExecuteCallbacks, type SkillExecution, type SkillExecutionResult, type SkillProgress, SkillProgressUI, type SkillProgressUIProps, type SkillTrigger, type SourceItem, type SubAgentProgress, type SuggestedPrompt, type SystemPromptControl, type TextContentPart, type ThemeConfig, type ThemeMode, type ToolCallAccumulator, type ToolCallResult, type ToolLoadingContentPart, type ToolResultContentPart, type UseChatUIOptions, type UseChatUIReturn, type UseDeepResearchOptions, type UseDragResizeOptions, type UseDragResizeReturn, type UseFloatingWidgetOptions, type UseFloatingWidgetReturn, type UseObserverOptions, type UseObserverReturn, type UseProjectOptions, type UseProjectReturn, type UseSkillsOptions, type UseSkillsReturn, type UserProfile, type WorkflowSuggestion, convertSkillsToOpenAITools, convertToolsToSkills, createAdvancedResearchSkill, createDeepResearchSkill, migrateSessionsToProjects, useChatUI, useDeepResearch, useDragResize, useFloatingWidget, useObserver, useProject, useSkills };
|
|
3085
|
+
export { type ActionItem, type ActionMenuProps, type AdvancedResearchOptions, type AlternativeResponse, ArtifactCard, type ArtifactCardProps, type ArtifactContentPart, type ChatAttachment, ChatFloatingWidget, type ChatFloatingWidgetProps, ChatHeader, ChatInput, type ChatMessage, type ChatProject, type ChatSession, ChatSidebar, type ChatToolDefinition, type ChatToolParameter, ChatUI, type ChatUIComponents, type ChatUIProps, type ChecklistBlock, ChecklistCard, type ChecklistCardProps, type ChecklistItem, ChecklistMiniIndicator, type ChecklistMiniIndicatorProps, ChecklistPanel, type ChecklistPanelProps, CompactChatView, type CompactChatViewProps, ContentPartRenderer, type ContentPartRendererProps, type ConversationSearchOptions, type ConversationSearchSkillOptions, type ConversationSnippet, DEFAULT_PROJECT_ID, DEFAULT_PROJECT_TITLE, type DeepResearchCallbacks, type DeepResearchProgress, DeepResearchProgressUI, DevDiveAvatar, type DevDiveAvatarProps, DevDiveFabCharacter, type DevDiveFabCharacterProps, EmptyState, type EmptyStateProps, type ErrorContentPart, FileContentCard, type FileContentCardProps, type FileContentPart, FloatingFab, type FloatingFabProps, type FloatingNotification, FloatingPanel, type FloatingPanelProps, type FloatingPosition, FloatingTabBar, type FloatingTabBarProps, type FloatingTabItem, type FloatingWidgetTab, type HeaderProps, Icon, type IconName, type IconProps, IconSvg, ImageContentCard, type ImageContentCardProps, type ImageContentPart, type InputProps, LinkChip, type LinkChipProps, type ManualSkillItem, MarkdownRenderer, type MarkdownRendererProps, type MemoryItem, MemoryPanel, type MemoryPanelProps, MessageBubble, type MessageBubbleProps, type MessageContentPart, MessageList, type MessageListProps, type ModelConfig, type ModelSelectorProps, type OpenAITool, type PatternAnalysisResult, type PersonalizationConfig, type PollBlock, PollCard, type PollCardProps, type PollOption, type PollQuestion, type PollResponse, type PollState, type ProjectFile, ProjectSelector, type ProjectSelectorProps, ProjectSettingsModal, type ProjectSettingsModalProps, type PromptTemplate, type ProviderType, type ResizeEdge, ResizeHandles, type ResizeHandlesProps, type ResponseStyle, type SearchResult, type SearchResultContentPart, type SendMessageParams, type SendMessageResponse, type SendMessageResponseBase, type SendMessageResponseWithHeaders, type SessionContext, type SessionContextItem, SettingsModal, type SettingsModalProps, type SettingsTab, type SidebarProps, type SkillConfig, type SkillExecuteCallbacks, type SkillExecution, type SkillExecutionResult, type SkillProgress, SkillProgressUI, type SkillProgressUIProps, type SkillTrigger, type SourceItem, type SubAgentProgress, type SuggestedPrompt, type SystemPromptControl, type TextContentPart, type ThemeConfig, type ThemeMode, type ToolCallAccumulator, type ToolCallResult, type ToolLoadingContentPart, type ToolResultContentPart, type UseChatUIOptions, type UseChatUIReturn, type UseDeepResearchOptions, type UseDragResizeOptions, type UseDragResizeReturn, type UseFloatingWidgetOptions, type UseFloatingWidgetReturn, type UseObserverOptions, type UseObserverReturn, type UseProjectOptions, type UseProjectReturn, type UseSkillsOptions, type UseSkillsReturn, type UserProfile, type WorkflowSuggestion, convertSkillsToOpenAITools, convertToolsToSkills, createAdvancedResearchSkill, createConversationSearchSkill, createDeepResearchSkill, migrateSessionsToProjects, useChatUI, useDeepResearch, useDragResize, useFloatingWidget, useObserver, useProject, useSkills };
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1819,6 +1819,46 @@ interface UseFloatingWidgetReturn {
|
|
|
1819
1819
|
toggle: () => void;
|
|
1820
1820
|
setTab: (tabKey: string) => void;
|
|
1821
1821
|
}
|
|
1822
|
+
/**
|
|
1823
|
+
* @description 대화 검색 결과 스니펫
|
|
1824
|
+
* @Todo vibecode - DB에서 반환되는 과거 대화 조각
|
|
1825
|
+
*/
|
|
1826
|
+
interface ConversationSnippet {
|
|
1827
|
+
/** 세션 ID */
|
|
1828
|
+
sessionId: string;
|
|
1829
|
+
/** 세션 제목 */
|
|
1830
|
+
sessionTitle?: string;
|
|
1831
|
+
/** 발화자 */
|
|
1832
|
+
role: 'user' | 'assistant';
|
|
1833
|
+
/** 메시지 내용 (또는 발췌) */
|
|
1834
|
+
content: string;
|
|
1835
|
+
/** 메시지 타임스탬프 */
|
|
1836
|
+
timestamp?: number;
|
|
1837
|
+
/** 검색 관련도 점수 (0-1) */
|
|
1838
|
+
relevance?: number;
|
|
1839
|
+
}
|
|
1840
|
+
/**
|
|
1841
|
+
* @description 대화 검색 옵션
|
|
1842
|
+
* @Todo vibecode - 검색 범위 제한용
|
|
1843
|
+
*/
|
|
1844
|
+
interface ConversationSearchOptions {
|
|
1845
|
+
/** 최대 결과 수 (기본: 5) */
|
|
1846
|
+
limit?: number;
|
|
1847
|
+
/** 특정 세션으로 제한 */
|
|
1848
|
+
sessionId?: string;
|
|
1849
|
+
}
|
|
1850
|
+
/**
|
|
1851
|
+
* @description createConversationSearchSkill 팩토리 옵션
|
|
1852
|
+
* @Todo vibecode - 소비 앱이 DB 검색 구현을 제공
|
|
1853
|
+
*/
|
|
1854
|
+
interface ConversationSearchSkillOptions {
|
|
1855
|
+
/** 검색 구현 (호스트 DB 쿼리) */
|
|
1856
|
+
onSearch: (query: string, options?: ConversationSearchOptions) => Promise<ConversationSnippet[]>;
|
|
1857
|
+
/** 스킬 라벨 (기본: '대화 검색') */
|
|
1858
|
+
label?: string;
|
|
1859
|
+
/** 비활성화 여부 */
|
|
1860
|
+
disabled?: boolean;
|
|
1861
|
+
}
|
|
1822
1862
|
|
|
1823
1863
|
/**
|
|
1824
1864
|
* @description ChatUI 메인 컴포넌트
|
|
@@ -2401,6 +2441,30 @@ declare const createAdvancedResearchSkill: (options: AdvancedResearchOptions) =>
|
|
|
2401
2441
|
*/
|
|
2402
2442
|
declare const createDeepResearchSkill: (callbacks: DeepResearchCallbacks) => SkillConfig;
|
|
2403
2443
|
|
|
2444
|
+
/**
|
|
2445
|
+
* @description 대화 검색 스킬 팩토리
|
|
2446
|
+
* @Todo vibecode - 호스트 DB 검색을 SkillConfig로 래핑하여 LLM tool use로 과거 대화 검색
|
|
2447
|
+
*
|
|
2448
|
+
* 사용 예시:
|
|
2449
|
+
* ```ts
|
|
2450
|
+
* import { createConversationSearchSkill } from '@gendive/chatllm/react';
|
|
2451
|
+
*
|
|
2452
|
+
* const searchSkill = createConversationSearchSkill({
|
|
2453
|
+
* onSearch: async (query, options) => {
|
|
2454
|
+
* return await db.conversations.search(query, options?.limit);
|
|
2455
|
+
* },
|
|
2456
|
+
* });
|
|
2457
|
+
*
|
|
2458
|
+
* <ChatUI skills={{ conversation_search: searchSkill }} />
|
|
2459
|
+
* ```
|
|
2460
|
+
*/
|
|
2461
|
+
|
|
2462
|
+
/**
|
|
2463
|
+
* @description 대화 검색 스킬 생성 팩토리
|
|
2464
|
+
* @Todo vibecode - LLM이 tool use로 과거 대화를 검색할 수 있는 스킬 생성
|
|
2465
|
+
*/
|
|
2466
|
+
declare const createConversationSearchSkill: (options: ConversationSearchSkillOptions) => SkillConfig;
|
|
2467
|
+
|
|
2404
2468
|
/**
|
|
2405
2469
|
* @description Remix Icons wrapper component
|
|
2406
2470
|
* @see https://remixicon.com/
|
|
@@ -3018,4 +3082,4 @@ declare const DEFAULT_PROJECT_TITLE = "\uAE30\uBCF8 \uD504\uB85C\uC81D\uD2B8";
|
|
|
3018
3082
|
*/
|
|
3019
3083
|
declare const migrateSessionsToProjects: (storageKey: string) => void;
|
|
3020
3084
|
|
|
3021
|
-
export { type ActionItem, type ActionMenuProps, type AdvancedResearchOptions, type AlternativeResponse, ArtifactCard, type ArtifactCardProps, type ArtifactContentPart, type ChatAttachment, ChatFloatingWidget, type ChatFloatingWidgetProps, ChatHeader, ChatInput, type ChatMessage, type ChatProject, type ChatSession, ChatSidebar, type ChatToolDefinition, type ChatToolParameter, ChatUI, type ChatUIComponents, type ChatUIProps, type ChecklistBlock, ChecklistCard, type ChecklistCardProps, type ChecklistItem, ChecklistMiniIndicator, type ChecklistMiniIndicatorProps, ChecklistPanel, type ChecklistPanelProps, CompactChatView, type CompactChatViewProps, ContentPartRenderer, type ContentPartRendererProps, DEFAULT_PROJECT_ID, DEFAULT_PROJECT_TITLE, type DeepResearchCallbacks, type DeepResearchProgress, DeepResearchProgressUI, DevDiveAvatar, type DevDiveAvatarProps, DevDiveFabCharacter, type DevDiveFabCharacterProps, EmptyState, type EmptyStateProps, type ErrorContentPart, FileContentCard, type FileContentCardProps, type FileContentPart, FloatingFab, type FloatingFabProps, type FloatingNotification, FloatingPanel, type FloatingPanelProps, type FloatingPosition, FloatingTabBar, type FloatingTabBarProps, type FloatingTabItem, type FloatingWidgetTab, type HeaderProps, Icon, type IconName, type IconProps, IconSvg, ImageContentCard, type ImageContentCardProps, type ImageContentPart, type InputProps, LinkChip, type LinkChipProps, type ManualSkillItem, MarkdownRenderer, type MarkdownRendererProps, type MemoryItem, MemoryPanel, type MemoryPanelProps, MessageBubble, type MessageBubbleProps, type MessageContentPart, MessageList, type MessageListProps, type ModelConfig, type ModelSelectorProps, type OpenAITool, type PatternAnalysisResult, type PersonalizationConfig, type PollBlock, PollCard, type PollCardProps, type PollOption, type PollQuestion, type PollResponse, type PollState, type ProjectFile, ProjectSelector, type ProjectSelectorProps, ProjectSettingsModal, type ProjectSettingsModalProps, type PromptTemplate, type ProviderType, type ResizeEdge, ResizeHandles, type ResizeHandlesProps, type ResponseStyle, type SearchResult, type SearchResultContentPart, type SendMessageParams, type SendMessageResponse, type SendMessageResponseBase, type SendMessageResponseWithHeaders, type SessionContext, type SessionContextItem, SettingsModal, type SettingsModalProps, type SettingsTab, type SidebarProps, type SkillConfig, type SkillExecuteCallbacks, type SkillExecution, type SkillExecutionResult, type SkillProgress, SkillProgressUI, type SkillProgressUIProps, type SkillTrigger, type SourceItem, type SubAgentProgress, type SuggestedPrompt, type SystemPromptControl, type TextContentPart, type ThemeConfig, type ThemeMode, type ToolCallAccumulator, type ToolCallResult, type ToolLoadingContentPart, type ToolResultContentPart, type UseChatUIOptions, type UseChatUIReturn, type UseDeepResearchOptions, type UseDragResizeOptions, type UseDragResizeReturn, type UseFloatingWidgetOptions, type UseFloatingWidgetReturn, type UseObserverOptions, type UseObserverReturn, type UseProjectOptions, type UseProjectReturn, type UseSkillsOptions, type UseSkillsReturn, type UserProfile, type WorkflowSuggestion, convertSkillsToOpenAITools, convertToolsToSkills, createAdvancedResearchSkill, createDeepResearchSkill, migrateSessionsToProjects, useChatUI, useDeepResearch, useDragResize, useFloatingWidget, useObserver, useProject, useSkills };
|
|
3085
|
+
export { type ActionItem, type ActionMenuProps, type AdvancedResearchOptions, type AlternativeResponse, ArtifactCard, type ArtifactCardProps, type ArtifactContentPart, type ChatAttachment, ChatFloatingWidget, type ChatFloatingWidgetProps, ChatHeader, ChatInput, type ChatMessage, type ChatProject, type ChatSession, ChatSidebar, type ChatToolDefinition, type ChatToolParameter, ChatUI, type ChatUIComponents, type ChatUIProps, type ChecklistBlock, ChecklistCard, type ChecklistCardProps, type ChecklistItem, ChecklistMiniIndicator, type ChecklistMiniIndicatorProps, ChecklistPanel, type ChecklistPanelProps, CompactChatView, type CompactChatViewProps, ContentPartRenderer, type ContentPartRendererProps, type ConversationSearchOptions, type ConversationSearchSkillOptions, type ConversationSnippet, DEFAULT_PROJECT_ID, DEFAULT_PROJECT_TITLE, type DeepResearchCallbacks, type DeepResearchProgress, DeepResearchProgressUI, DevDiveAvatar, type DevDiveAvatarProps, DevDiveFabCharacter, type DevDiveFabCharacterProps, EmptyState, type EmptyStateProps, type ErrorContentPart, FileContentCard, type FileContentCardProps, type FileContentPart, FloatingFab, type FloatingFabProps, type FloatingNotification, FloatingPanel, type FloatingPanelProps, type FloatingPosition, FloatingTabBar, type FloatingTabBarProps, type FloatingTabItem, type FloatingWidgetTab, type HeaderProps, Icon, type IconName, type IconProps, IconSvg, ImageContentCard, type ImageContentCardProps, type ImageContentPart, type InputProps, LinkChip, type LinkChipProps, type ManualSkillItem, MarkdownRenderer, type MarkdownRendererProps, type MemoryItem, MemoryPanel, type MemoryPanelProps, MessageBubble, type MessageBubbleProps, type MessageContentPart, MessageList, type MessageListProps, type ModelConfig, type ModelSelectorProps, type OpenAITool, type PatternAnalysisResult, type PersonalizationConfig, type PollBlock, PollCard, type PollCardProps, type PollOption, type PollQuestion, type PollResponse, type PollState, type ProjectFile, ProjectSelector, type ProjectSelectorProps, ProjectSettingsModal, type ProjectSettingsModalProps, type PromptTemplate, type ProviderType, type ResizeEdge, ResizeHandles, type ResizeHandlesProps, type ResponseStyle, type SearchResult, type SearchResultContentPart, type SendMessageParams, type SendMessageResponse, type SendMessageResponseBase, type SendMessageResponseWithHeaders, type SessionContext, type SessionContextItem, SettingsModal, type SettingsModalProps, type SettingsTab, type SidebarProps, type SkillConfig, type SkillExecuteCallbacks, type SkillExecution, type SkillExecutionResult, type SkillProgress, SkillProgressUI, type SkillProgressUIProps, type SkillTrigger, type SourceItem, type SubAgentProgress, type SuggestedPrompt, type SystemPromptControl, type TextContentPart, type ThemeConfig, type ThemeMode, type ToolCallAccumulator, type ToolCallResult, type ToolLoadingContentPart, type ToolResultContentPart, type UseChatUIOptions, type UseChatUIReturn, type UseDeepResearchOptions, type UseDragResizeOptions, type UseDragResizeReturn, type UseFloatingWidgetOptions, type UseFloatingWidgetReturn, type UseObserverOptions, type UseObserverReturn, type UseProjectOptions, type UseProjectReturn, type UseSkillsOptions, type UseSkillsReturn, type UserProfile, type WorkflowSuggestion, convertSkillsToOpenAITools, convertToolsToSkills, createAdvancedResearchSkill, createConversationSearchSkill, createDeepResearchSkill, migrateSessionsToProjects, useChatUI, useDeepResearch, useDragResize, useFloatingWidget, useObserver, useProject, useSkills };
|
package/dist/react/index.js
CHANGED
|
@@ -68,6 +68,7 @@ __export(index_exports, {
|
|
|
68
68
|
convertSkillsToOpenAITools: () => convertSkillsToOpenAITools,
|
|
69
69
|
convertToolsToSkills: () => convertToolsToSkills,
|
|
70
70
|
createAdvancedResearchSkill: () => createAdvancedResearchSkill,
|
|
71
|
+
createConversationSearchSkill: () => createConversationSearchSkill,
|
|
71
72
|
createDeepResearchSkill: () => createDeepResearchSkill,
|
|
72
73
|
migrateSessionsToProjects: () => migrateSessionsToProjects,
|
|
73
74
|
useChatUI: () => useChatUI,
|
|
@@ -2843,6 +2844,11 @@ ${projectMemoryContext}`);
|
|
|
2843
2844
|
- \uB370\uC774\uD130 \uBE44\uAD50/\uCD94\uC774 \u2192 html (Chart.js CDN \uC0AC\uC6A9, <artifact> \uD0DC\uADF8)
|
|
2844
2845
|
- \uC544\uC774\uCF58/\uB85C\uACE0/\uC77C\uB7EC\uC2A4\uD2B8 \u2192 svg
|
|
2845
2846
|
|
|
2847
|
+
**mermaid \uC8FC\uC758\uC0AC\uD56D:**
|
|
2848
|
+
- \uB178\uB4DC \uB77C\uBCA8\uC5D0 \uAD04\uD638 () \uC0AC\uC6A9 \uAE08\uC9C0 \u2192 \uB300\uAD04\uD638 [] \uC0AC\uC6A9: B[\uC0C1\uD0DC \uAD00\uB9AC useState] \u2705 B[\uC0C1\uD0DC \uAD00\uB9AC (useState)] \u274C
|
|
2849
|
+
- \uB178\uB4DC \uB77C\uBCA8\uC5D0 \uD2B9\uC218\uBB38\uC790\uAC00 \uC788\uC73C\uBA74 \uD070\uB530\uC634\uD45C\uB85C \uAC10\uC2F8\uAE30: B["API \uD638\uCD9C \u2192 \uC751\uB2F5"]
|
|
2850
|
+
- \uC18C\uAD04\uD638 ()\uB294 mermaid \uBB38\uBC95\uC5D0\uC11C \uB465\uADFC \uB178\uB4DC\uB97C \uC758\uBBF8\uD558\uBBC0\uB85C \uB77C\uBCA8 \uD14D\uC2A4\uD2B8\uC5D0 \uC808\uB300 \uD3EC\uD568\uD558\uC9C0 \uB9C8\uC138\uC694
|
|
2851
|
+
|
|
2846
2852
|
**mermaid \uC608\uC2DC:**
|
|
2847
2853
|
\`\`\`mermaid
|
|
2848
2854
|
graph TD
|
|
@@ -2867,7 +2873,7 @@ new Chart(document.getElementById('chart'), {
|
|
|
2867
2873
|
- html \uC2DC\uAC01\uD654\uB294 \uBC18\uB4DC\uC2DC <artifact language="html"> \uD0DC\uADF8\uB85C \uAC10\uC2F8\uC57C \uD568 (\`\`\`html \uCF54\uB4DC\uBE14\uB85D \uC0AC\uC6A9 \uAE08\uC9C0)
|
|
2868
2874
|
- \uC0AC\uC6A9\uC790\uAC00 \uC2DC\uAC01\uD654\uB97C \uC694\uCCAD\uD558\uC9C0 \uC54A\uC544\uB3C4 \uC801\uC808\uD558\uBA74 \uC790\uB3D9\uC73C\uB85C \uD3EC\uD568
|
|
2869
2875
|
- \uC2DC\uAC01\uD654 \uC55E\uB4A4\uC5D0 \uAC04\uACB0\uD55C \uD14D\uC2A4\uD2B8 \uC124\uBA85 \uD3EC\uD568
|
|
2870
|
-
- mermaid \
|
|
2876
|
+
- mermaid \uB178\uB4DC \uB77C\uBCA8\uC5D0 \uC18C\uAD04\uD638 () \uC808\uB300 \uC0AC\uC6A9 \uAE08\uC9C0 \u2014 \uD30C\uC2F1 \uC5D0\uB7EC \uC6D0\uC778`);
|
|
2871
2877
|
if (shouldIncludeSkills) {
|
|
2872
2878
|
const skillsPrompt = buildSkillsPrompt();
|
|
2873
2879
|
if (skillsPrompt) {
|
|
@@ -3200,18 +3206,29 @@ ${newConversation}
|
|
|
3200
3206
|
setIsSessionLoading(true);
|
|
3201
3207
|
try {
|
|
3202
3208
|
const sessionDetail = await onLoadSessionRef.current(id);
|
|
3203
|
-
let loadedMessages = sessionDetail.messages.map((m, idx) =>
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3209
|
+
let loadedMessages = sessionDetail.messages.map((m, idx) => {
|
|
3210
|
+
const msg = {
|
|
3211
|
+
id: m.id || generateId5("msg"),
|
|
3212
|
+
role: typeof m.role === "string" ? m.role.toLowerCase() : m.role,
|
|
3213
|
+
// API는 message 필드, 내부는 content 필드 사용
|
|
3214
|
+
content: m.content || m.message || "",
|
|
3215
|
+
timestamp: m.created_at ? new Date(m.created_at).getTime() : Date.now() - (sessionDetail.messages.length - idx) * 1e3,
|
|
3216
|
+
model: m.model,
|
|
3217
|
+
alternatives: m.alternatives,
|
|
3218
|
+
sources: m.sources,
|
|
3219
|
+
/** @Todo vibecode - 백엔드에서 전달받은 contentParts 복원 (이미지/파일 등) */
|
|
3220
|
+
...m.contentParts && { contentParts: m.contentParts }
|
|
3221
|
+
};
|
|
3222
|
+
if (!msg.contentParts && msg.role === "assistant" && hasArtifactTag(msg.content)) {
|
|
3223
|
+
const { artifacts, cleanContent } = parseArtifactsFromContent(msg.content);
|
|
3224
|
+
if (artifacts.length > 0) {
|
|
3225
|
+
const textPart = cleanContent.trim() ? [{ type: "text", content: cleanContent }] : [];
|
|
3226
|
+
msg.content = cleanContent;
|
|
3227
|
+
msg.contentParts = [...textPart, ...artifacts];
|
|
3228
|
+
}
|
|
3229
|
+
}
|
|
3230
|
+
return msg;
|
|
3231
|
+
});
|
|
3215
3232
|
let resolvedTitle = sessionDetail.title;
|
|
3216
3233
|
let resolvedSessionContext = sessionDetail.sessionContext;
|
|
3217
3234
|
if (loadedMessages.length === 0) {
|
|
@@ -3586,13 +3603,17 @@ ${finalContent}`;
|
|
|
3586
3603
|
for (const [skillName, skillConfig] of attachmentSkills) {
|
|
3587
3604
|
let matchedFiles = currentAttachments.filter((att) => {
|
|
3588
3605
|
if (!skillConfig.acceptedTypes || skillConfig.acceptedTypes.length === 0) return true;
|
|
3606
|
+
const fileName = (att.name || "").toLowerCase();
|
|
3607
|
+
const fileMime = (att.mimeType || "").toLowerCase();
|
|
3608
|
+
const fileExt = fileName.includes(".") ? fileName.slice(fileName.lastIndexOf(".")) : "";
|
|
3589
3609
|
return skillConfig.acceptedTypes.some((type) => {
|
|
3590
|
-
|
|
3591
|
-
if (
|
|
3592
|
-
|
|
3593
|
-
|
|
3610
|
+
const t = type.toLowerCase();
|
|
3611
|
+
if (t.startsWith(".")) return fileExt === t || fileName.endsWith(t);
|
|
3612
|
+
if (t.includes("*")) {
|
|
3613
|
+
const regex = new RegExp("^" + t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace("\\*", ".*") + "$");
|
|
3614
|
+
return regex.test(fileMime);
|
|
3594
3615
|
}
|
|
3595
|
-
return
|
|
3616
|
+
return fileMime === t;
|
|
3596
3617
|
});
|
|
3597
3618
|
});
|
|
3598
3619
|
if (skipImageAttachmentSkill) {
|
|
@@ -4047,25 +4068,26 @@ ${attachmentContext}
|
|
|
4047
4068
|
}
|
|
4048
4069
|
}
|
|
4049
4070
|
}
|
|
4050
|
-
const saveMessagesOnEarlyReturn = () => {
|
|
4071
|
+
const saveMessagesOnEarlyReturn = (overrideContentParts) => {
|
|
4051
4072
|
if (!useExternalStorage || !capturedSessionId) return;
|
|
4052
|
-
|
|
4073
|
+
setTimeout(() => {
|
|
4053
4074
|
const latestSession = sessionsRef.current.find((s) => s.id === capturedSessionId);
|
|
4054
4075
|
if (!latestSession) return;
|
|
4055
4076
|
const latestMessages = latestSession.messages;
|
|
4056
4077
|
const assistantMsg = [...latestMessages].reverse().find((m) => m.role === "assistant");
|
|
4057
4078
|
const userMsg = latestMessages.find((m) => m.role === "user" && m.content === finalContent);
|
|
4058
4079
|
const assistantContent = assistantMsg?.content || "";
|
|
4059
|
-
|
|
4080
|
+
const finalContentParts = overrideContentParts || assistantMsg?.contentParts;
|
|
4081
|
+
if ((assistantContent || finalContentParts) && onSaveMessagesRef.current) {
|
|
4060
4082
|
onSaveMessagesRef.current(capturedSessionId, [
|
|
4061
4083
|
{ role: "user", message: finalContent, ...userMsg?.contentParts && { contentParts: userMsg.contentParts } },
|
|
4062
|
-
{ role: "assistant", message: assistantContent, ...
|
|
4084
|
+
{ role: "assistant", message: assistantContent, ...finalContentParts && { contentParts: finalContentParts } }
|
|
4063
4085
|
]).catch((e) => console.error("[useChatUI] Failed to save messages:", e));
|
|
4064
4086
|
}
|
|
4065
4087
|
if (latestSession.messages.length > 0) {
|
|
4066
4088
|
writeSessionCache(storageKey, latestSession);
|
|
4067
4089
|
}
|
|
4068
|
-
});
|
|
4090
|
+
}, 0);
|
|
4069
4091
|
};
|
|
4070
4092
|
if (!shouldSkipSkillParsing) {
|
|
4071
4093
|
const assistantContent = accumulatedContent;
|
|
@@ -4255,7 +4277,7 @@ ${attachmentContext}
|
|
|
4255
4277
|
promoteToSessionContext(capturedSessionId, toolName, result.content, result.metadata, toolLabel || toolName);
|
|
4256
4278
|
}
|
|
4257
4279
|
if (resultType === "image" || resultType === "file") {
|
|
4258
|
-
saveMessagesOnEarlyReturn();
|
|
4280
|
+
saveMessagesOnEarlyReturn(parts);
|
|
4259
4281
|
removeLoadingSession(capturedSessionId);
|
|
4260
4282
|
abortControllersRef.current.delete(capturedSessionId);
|
|
4261
4283
|
return;
|
|
@@ -4266,7 +4288,7 @@ ${attachmentContext}
|
|
|
4266
4288
|
shouldContinue = decision === "continue";
|
|
4267
4289
|
}
|
|
4268
4290
|
if (!shouldContinue) {
|
|
4269
|
-
saveMessagesOnEarlyReturn();
|
|
4291
|
+
saveMessagesOnEarlyReturn(parts);
|
|
4270
4292
|
removeLoadingSession(capturedSessionId);
|
|
4271
4293
|
abortControllersRef.current.delete(capturedSessionId);
|
|
4272
4294
|
return;
|
|
@@ -4341,13 +4363,13 @@ ${result.content}
|
|
|
4341
4363
|
shouldContinueImgFile = decision === "continue";
|
|
4342
4364
|
}
|
|
4343
4365
|
if (!shouldContinueImgFile) {
|
|
4344
|
-
saveMessagesOnEarlyReturn();
|
|
4366
|
+
saveMessagesOnEarlyReturn(imgFileParts);
|
|
4345
4367
|
removeLoadingSession(capturedSessionId);
|
|
4346
4368
|
abortControllersRef.current.delete(capturedSessionId);
|
|
4347
4369
|
return;
|
|
4348
4370
|
}
|
|
4349
4371
|
skipNextSkillParsingRef.current = true;
|
|
4350
|
-
saveMessagesOnEarlyReturn();
|
|
4372
|
+
saveMessagesOnEarlyReturn(imgFileParts);
|
|
4351
4373
|
const imgFilePrompt = skillResultType === "image" ? `"${detectedSkill.name}" \uC2A4\uD0AC\uB85C \uC774\uBBF8\uC9C0\uAC00 \uC0DD\uC131\uB418\uC5B4 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uD45C\uC2DC\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC774\uBBF8\uC9C0 URL\uC744 \uD14D\uC2A4\uD2B8\uC5D0 \uD3EC\uD568\uD558\uC9C0 \uB9D0\uACE0, \uC0DD\uC131\uB41C \uC774\uBBF8\uC9C0\uC5D0 \uB300\uD574 \uAC04\uB2E8\uD788 \uC548\uB0B4\uD574\uC8FC\uC138\uC694. skill_use \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.` : `"${detectedSkill.name}" \uC2A4\uD0AC\uB85C \uD30C\uC77C\uC774 \uC0DD\uC131\uB418\uC5B4 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uD45C\uC2DC\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uD30C\uC77C URL\uC744 \uD14D\uC2A4\uD2B8\uC5D0 \uD3EC\uD568\uD558\uC9C0 \uB9D0\uACE0, \uACB0\uACFC\uC5D0 \uB300\uD574 \uAC04\uB2E8\uD788 \uC548\uB0B4\uD574\uC8FC\uC138\uC694. skill_use \uD0DC\uADF8\uB294 \uC0AC\uC6A9\uD558\uC9C0 \uB9C8\uC138\uC694.`;
|
|
4352
4374
|
setTimeout(() => {
|
|
4353
4375
|
sendMessage(imgFilePrompt, { hiddenUserMessage: true });
|
|
@@ -10285,9 +10307,39 @@ var MermaidArtifact = ({ code }) => {
|
|
|
10285
10307
|
}
|
|
10286
10308
|
);
|
|
10287
10309
|
};
|
|
10288
|
-
var
|
|
10310
|
+
var svgToPngBlob = (svgString, scale = 2) => {
|
|
10311
|
+
return new Promise((resolve) => {
|
|
10312
|
+
const parser = new DOMParser();
|
|
10313
|
+
const doc = parser.parseFromString(svgString, "image/svg+xml");
|
|
10314
|
+
const svgEl = doc.querySelector("svg");
|
|
10315
|
+
if (!svgEl) return resolve(null);
|
|
10316
|
+
const w = parseInt(svgEl.getAttribute("width") || "800", 10);
|
|
10317
|
+
const h = parseInt(svgEl.getAttribute("height") || "600", 10);
|
|
10318
|
+
const canvas = document.createElement("canvas");
|
|
10319
|
+
canvas.width = w * scale;
|
|
10320
|
+
canvas.height = h * scale;
|
|
10321
|
+
const ctx = canvas.getContext("2d");
|
|
10322
|
+
if (!ctx) return resolve(null);
|
|
10323
|
+
ctx.scale(scale, scale);
|
|
10324
|
+
const blob = new Blob([new XMLSerializer().serializeToString(svgEl)], { type: "image/svg+xml;charset=utf-8" });
|
|
10325
|
+
const url = URL.createObjectURL(blob);
|
|
10326
|
+
const img = new Image();
|
|
10327
|
+
img.onload = () => {
|
|
10328
|
+
ctx.drawImage(img, 0, 0, w, h);
|
|
10329
|
+
URL.revokeObjectURL(url);
|
|
10330
|
+
canvas.toBlob((pngBlob) => resolve(pngBlob), "image/png");
|
|
10331
|
+
};
|
|
10332
|
+
img.onerror = () => {
|
|
10333
|
+
URL.revokeObjectURL(url);
|
|
10334
|
+
resolve(null);
|
|
10335
|
+
};
|
|
10336
|
+
img.src = url;
|
|
10337
|
+
});
|
|
10338
|
+
};
|
|
10339
|
+
var ArtifactActions = ({ code, language, containerRef }) => {
|
|
10289
10340
|
const [showCode, setShowCode] = (0, import_react17.useState)(false);
|
|
10290
10341
|
const [copied, setCopied] = (0, import_react17.useState)(false);
|
|
10342
|
+
const [saving, setSaving] = (0, import_react17.useState)(false);
|
|
10291
10343
|
const handleCopy = async () => {
|
|
10292
10344
|
try {
|
|
10293
10345
|
await navigator.clipboard.writeText(code);
|
|
@@ -10296,6 +10348,39 @@ var ArtifactActions = ({ code, language }) => {
|
|
|
10296
10348
|
} catch {
|
|
10297
10349
|
}
|
|
10298
10350
|
};
|
|
10351
|
+
const handleSaveImage = async () => {
|
|
10352
|
+
setSaving(true);
|
|
10353
|
+
try {
|
|
10354
|
+
let blob = null;
|
|
10355
|
+
if (language === "svg" || language === "mermaid") {
|
|
10356
|
+
const svgEl = containerRef?.current?.querySelector("svg");
|
|
10357
|
+
if (svgEl) {
|
|
10358
|
+
blob = await svgToPngBlob(svgEl.outerHTML);
|
|
10359
|
+
}
|
|
10360
|
+
} else if (language === "html") {
|
|
10361
|
+
const htmlBlob = new Blob([code], { type: "text/html;charset=utf-8" });
|
|
10362
|
+
const url = URL.createObjectURL(htmlBlob);
|
|
10363
|
+
const a = document.createElement("a");
|
|
10364
|
+
a.href = url;
|
|
10365
|
+
a.download = `artifact.html`;
|
|
10366
|
+
a.click();
|
|
10367
|
+
URL.revokeObjectURL(url);
|
|
10368
|
+
setSaving(false);
|
|
10369
|
+
return;
|
|
10370
|
+
}
|
|
10371
|
+
if (blob) {
|
|
10372
|
+
const url = URL.createObjectURL(blob);
|
|
10373
|
+
const a = document.createElement("a");
|
|
10374
|
+
a.href = url;
|
|
10375
|
+
a.download = `artifact.png`;
|
|
10376
|
+
a.click();
|
|
10377
|
+
URL.revokeObjectURL(url);
|
|
10378
|
+
}
|
|
10379
|
+
} catch {
|
|
10380
|
+
} finally {
|
|
10381
|
+
setSaving(false);
|
|
10382
|
+
}
|
|
10383
|
+
};
|
|
10299
10384
|
const langLabel = language === "mermaid" ? "Mermaid" : language === "svg" ? "SVG" : "HTML";
|
|
10300
10385
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
|
|
10301
10386
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
@@ -10361,6 +10446,30 @@ var ArtifactActions = ({ code, language }) => {
|
|
|
10361
10446
|
copied ? "\uBCF5\uC0AC\uB428" : "\uBCF5\uC0AC"
|
|
10362
10447
|
]
|
|
10363
10448
|
}
|
|
10449
|
+
),
|
|
10450
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
10451
|
+
"button",
|
|
10452
|
+
{
|
|
10453
|
+
onClick: handleSaveImage,
|
|
10454
|
+
disabled: saving,
|
|
10455
|
+
style: {
|
|
10456
|
+
display: "flex",
|
|
10457
|
+
alignItems: "center",
|
|
10458
|
+
gap: "4px",
|
|
10459
|
+
padding: "4px 8px",
|
|
10460
|
+
fontSize: "12px",
|
|
10461
|
+
color: "var(--chatllm-text-muted, #64748b)",
|
|
10462
|
+
backgroundColor: "transparent",
|
|
10463
|
+
border: "none",
|
|
10464
|
+
borderRadius: "4px",
|
|
10465
|
+
cursor: saving ? "wait" : "pointer",
|
|
10466
|
+
opacity: saving ? 0.5 : 1
|
|
10467
|
+
},
|
|
10468
|
+
children: [
|
|
10469
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(IconSvg, { name: "download-line", size: 12, color: "var(--chatllm-text-muted, #64748b)" }),
|
|
10470
|
+
language === "html" ? "HTML \uC800\uC7A5" : "\uC774\uBBF8\uC9C0 \uC800\uC7A5"
|
|
10471
|
+
]
|
|
10472
|
+
}
|
|
10364
10473
|
)
|
|
10365
10474
|
]
|
|
10366
10475
|
}
|
|
@@ -10395,6 +10504,7 @@ var ArtifactActions = ({ code, language }) => {
|
|
|
10395
10504
|
] });
|
|
10396
10505
|
};
|
|
10397
10506
|
var ArtifactCard = ({ part, index = 0 }) => {
|
|
10507
|
+
const contentRef = (0, import_react17.useRef)(null);
|
|
10398
10508
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
10399
10509
|
"div",
|
|
10400
10510
|
{
|
|
@@ -10434,12 +10544,12 @@ var ArtifactCard = ({ part, index = 0 }) => {
|
|
|
10434
10544
|
]
|
|
10435
10545
|
}
|
|
10436
10546
|
),
|
|
10437
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { padding: part.language === "html" ? 0 : "12px" }, children: [
|
|
10547
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { ref: contentRef, style: { padding: part.language === "html" ? 0 : "12px" }, children: [
|
|
10438
10548
|
part.language === "html" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(HtmlArtifact, { code: part.code }),
|
|
10439
10549
|
part.language === "svg" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SvgArtifact, { code: part.code }),
|
|
10440
10550
|
part.language === "mermaid" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(MermaidArtifact, { code: part.code })
|
|
10441
10551
|
] }),
|
|
10442
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ArtifactActions, { code: part.code, language: part.language })
|
|
10552
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ArtifactActions, { code: part.code, language: part.language, containerRef: contentRef })
|
|
10443
10553
|
]
|
|
10444
10554
|
}
|
|
10445
10555
|
);
|
|
@@ -15278,6 +15388,7 @@ var useDragResize = (options) => {
|
|
|
15278
15388
|
const dragStartRef = (0, import_react24.useRef)(null);
|
|
15279
15389
|
const isDraggingRef = (0, import_react24.useRef)(false);
|
|
15280
15390
|
const wasDragRef = (0, import_react24.useRef)(false);
|
|
15391
|
+
const userDraggedRef = (0, import_react24.useRef)(false);
|
|
15281
15392
|
const dragDeltaRef = (0, import_react24.useRef)({ dx: 0, dy: 0 });
|
|
15282
15393
|
const fabElRef = (0, import_react24.useRef)(null);
|
|
15283
15394
|
const dragCleanupRef = (0, import_react24.useRef)(null);
|
|
@@ -15344,6 +15455,7 @@ var useDragResize = (options) => {
|
|
|
15344
15455
|
if (!isDraggingRef.current && distance > DRAG_THRESHOLD) {
|
|
15345
15456
|
isDraggingRef.current = true;
|
|
15346
15457
|
wasDragRef.current = true;
|
|
15458
|
+
userDraggedRef.current = true;
|
|
15347
15459
|
setIsDragging(true);
|
|
15348
15460
|
fabElRef.current?.classList.add("chatllm-fab-dragging");
|
|
15349
15461
|
}
|
|
@@ -15583,7 +15695,11 @@ var useDragResize = (options) => {
|
|
|
15583
15695
|
const newVw = window.innerWidth;
|
|
15584
15696
|
const newVh = window.innerHeight;
|
|
15585
15697
|
setViewport({ width: newVw, height: newVh });
|
|
15586
|
-
|
|
15698
|
+
if (!userDraggedRef.current) {
|
|
15699
|
+
setFabPos(getInitialFabPosition(initialPosition));
|
|
15700
|
+
} else {
|
|
15701
|
+
setFabPos((prev) => clampToViewport(prev.x, prev.y, newVw, newVh));
|
|
15702
|
+
}
|
|
15587
15703
|
};
|
|
15588
15704
|
window.addEventListener("resize", handleResize);
|
|
15589
15705
|
return () => window.removeEventListener("resize", handleResize);
|
|
@@ -17183,23 +17299,39 @@ var ChatFloatingWidget = ({
|
|
|
17183
17299
|
return [chatTab, ...customTabs];
|
|
17184
17300
|
}, [tabs]);
|
|
17185
17301
|
const [unreadBadge, setUnreadBadge] = (0, import_react31.useState)(0);
|
|
17186
|
-
const seenMessageIdsRef = (0, import_react31.useRef)(new Set(
|
|
17302
|
+
const seenMessageIdsRef = (0, import_react31.useRef)(/* @__PURE__ */ new Set());
|
|
17303
|
+
(0, import_react31.useEffect)(() => {
|
|
17304
|
+
if (seenMessageIdsRef.current.size === 0 && chatState.messages.length > 0) {
|
|
17305
|
+
for (const m of chatState.messages) {
|
|
17306
|
+
seenMessageIdsRef.current.add(m.id);
|
|
17307
|
+
}
|
|
17308
|
+
}
|
|
17309
|
+
}, [chatState.messages]);
|
|
17187
17310
|
(0, import_react31.useEffect)(() => {
|
|
17188
|
-
if (
|
|
17311
|
+
if (isOpen) {
|
|
17312
|
+
for (const m of chatState.messages) {
|
|
17313
|
+
seenMessageIdsRef.current.add(m.id);
|
|
17314
|
+
}
|
|
17315
|
+
} else {
|
|
17189
17316
|
const newAssistant = chatState.messages.filter(
|
|
17190
17317
|
(m) => m.role === "assistant" && !seenMessageIdsRef.current.has(m.id)
|
|
17191
17318
|
);
|
|
17192
17319
|
if (newAssistant.length > 0) {
|
|
17193
17320
|
setUnreadBadge((prev) => prev + newAssistant.length);
|
|
17321
|
+
for (const m of newAssistant) {
|
|
17322
|
+
seenMessageIdsRef.current.add(m.id);
|
|
17323
|
+
}
|
|
17194
17324
|
}
|
|
17195
17325
|
}
|
|
17196
|
-
for (const m of chatState.messages) {
|
|
17197
|
-
seenMessageIdsRef.current.add(m.id);
|
|
17198
|
-
}
|
|
17199
17326
|
}, [chatState.messages, isOpen]);
|
|
17200
17327
|
(0, import_react31.useEffect)(() => {
|
|
17201
|
-
if (isOpen)
|
|
17202
|
-
|
|
17328
|
+
if (isOpen) {
|
|
17329
|
+
setUnreadBadge(0);
|
|
17330
|
+
for (const m of chatState.messages) {
|
|
17331
|
+
seenMessageIdsRef.current.add(m.id);
|
|
17332
|
+
}
|
|
17333
|
+
}
|
|
17334
|
+
}, [isOpen, chatState.messages]);
|
|
17203
17335
|
const totalBadge = (0, import_react31.useMemo)(() => {
|
|
17204
17336
|
return tabs.reduce((sum, t) => sum + (t.badge || 0), 0) + unreadBadge;
|
|
17205
17337
|
}, [tabs, unreadBadge]);
|
|
@@ -17635,6 +17767,57 @@ var useDeepResearch = (options) => {
|
|
|
17635
17767
|
};
|
|
17636
17768
|
};
|
|
17637
17769
|
|
|
17770
|
+
// src/react/utils/conversationSearchAdapter.ts
|
|
17771
|
+
var formatSearchResults = (results) => {
|
|
17772
|
+
if (results.length === 0) {
|
|
17773
|
+
return "\uAD00\uB828 \uB300\uD654\uB97C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.";
|
|
17774
|
+
}
|
|
17775
|
+
const formatted = results.map((r, i) => {
|
|
17776
|
+
const header = r.sessionTitle ? `[${r.sessionTitle}]` : "";
|
|
17777
|
+
const time = r.timestamp ? ` (${new Date(r.timestamp).toLocaleDateString("ko-KR")})` : "";
|
|
17778
|
+
return `[${i + 1}] ${header}${time} (${r.role}): ${r.content}`;
|
|
17779
|
+
}).join("\n\n");
|
|
17780
|
+
return `\uAC80\uC0C9 \uACB0\uACFC (${results.length}\uAC74):
|
|
17781
|
+
|
|
17782
|
+
${formatted}`;
|
|
17783
|
+
};
|
|
17784
|
+
var createConversationSearchSkill = (options) => {
|
|
17785
|
+
const { onSearch, label, disabled } = options;
|
|
17786
|
+
return {
|
|
17787
|
+
description: '\uC774\uC804 \uB300\uD654 \uB0B4\uC6A9\uC744 \uAC80\uC0C9\uD569\uB2C8\uB2E4. \uBC18\uB4DC\uC2DC \uD638\uCD9C\uD574\uC57C \uD558\uB294 \uC0C1\uD669: \uC0AC\uC6A9\uC790\uAC00 "\uC804\uC5D0", "\uC9C0\uB09C\uBC88\uC5D0", "\uC608\uC804\uC5D0", "\uC544\uAE4C", "\uC774\uC804\uC5D0", "\uB2E4\uC2DC \uC54C\uB824\uC918", "\uB610", "\uADF8\uB54C" \uB4F1 \uACFC\uAC70 \uB300\uD654\uB97C \uCC38\uC870\uD558\uB294 \uD45C\uD604\uC744 \uC0AC\uC6A9\uD560 \uB54C. \uACFC\uAC70\uC5D0 \uB17C\uC758\uD588\uB358 \uC8FC\uC81C\uB97C \uB2E4\uC2DC \uBB3C\uC5B4\uBCFC \uB54C\uB3C4 \uD638\uCD9C\uD558\uC138\uC694.',
|
|
17788
|
+
trigger: "auto",
|
|
17789
|
+
label: label || "\uB300\uD654 \uAC80\uC0C9",
|
|
17790
|
+
icon: "search-line",
|
|
17791
|
+
disabled,
|
|
17792
|
+
persist: false,
|
|
17793
|
+
parameters: {
|
|
17794
|
+
type: "object",
|
|
17795
|
+
properties: {
|
|
17796
|
+
query: {
|
|
17797
|
+
type: "string",
|
|
17798
|
+
description: "\uAC80\uC0C9 \uD0A4\uC6CC\uB4DC \uB610\uB294 \uBB38\uC7A5 (\uC0AC\uC6A9\uC790 \uC758\uB3C4\uB97C \uBC18\uC601\uD55C \uAC80\uC0C9\uC5B4)"
|
|
17799
|
+
},
|
|
17800
|
+
limit: {
|
|
17801
|
+
type: "number",
|
|
17802
|
+
description: "\uCD5C\uB300 \uACB0\uACFC \uC218 (\uAE30\uBCF8: 5)"
|
|
17803
|
+
}
|
|
17804
|
+
},
|
|
17805
|
+
required: ["query"]
|
|
17806
|
+
},
|
|
17807
|
+
execute: async (params) => {
|
|
17808
|
+
const { query, limit } = params;
|
|
17809
|
+
if (!query) {
|
|
17810
|
+
return { content: "\uAC80\uC0C9\uC5B4\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4." };
|
|
17811
|
+
}
|
|
17812
|
+
const results = await onSearch(query, { limit: limit || 5 });
|
|
17813
|
+
return {
|
|
17814
|
+
content: formatSearchResults(results),
|
|
17815
|
+
metadata: { resultCount: results.length }
|
|
17816
|
+
};
|
|
17817
|
+
}
|
|
17818
|
+
};
|
|
17819
|
+
};
|
|
17820
|
+
|
|
17638
17821
|
// src/react/components/EmptyState.tsx
|
|
17639
17822
|
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
17640
17823
|
var EmptyState = ({
|
|
@@ -18151,6 +18334,7 @@ var MemoryPanel = ({
|
|
|
18151
18334
|
convertSkillsToOpenAITools,
|
|
18152
18335
|
convertToolsToSkills,
|
|
18153
18336
|
createAdvancedResearchSkill,
|
|
18337
|
+
createConversationSearchSkill,
|
|
18154
18338
|
createDeepResearchSkill,
|
|
18155
18339
|
migrateSessionsToProjects,
|
|
18156
18340
|
useChatUI,
|