@gendive/chatllm 0.17.36 → 0.17.37

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.
@@ -819,6 +819,11 @@ interface ChatUIProps {
819
819
  * @Todo vibecode - 라이브러리가 도구 호출 판단 후 호스트에 실행 위임
820
820
  */
821
821
  onToolCall?: (name: string, params: Record<string, unknown>) => Promise<ToolCallResult>;
822
+ /**
823
+ * @description 이미지 첨부 시 처리 방식 (기본: 'auto-execute')
824
+ * @Todo vibecode - 'auto-execute': attachment 스킬 자동 실행, 'ai-decide': 이미지를 AI에 전달하여 AI가 도구 선택
825
+ */
826
+ imageAttachmentMode?: 'auto-execute' | 'ai-decide';
822
827
  /**
823
828
  * @description 도구/스킬 실행 후 AI 후속 스트리밍 계속 여부 (기본: true)
824
829
  * @Todo vibecode - false 시 도구 결과만 표시하고 AI 후속 응답 생략
@@ -881,10 +886,29 @@ interface ChatUIProps {
881
886
  */
882
887
  onDeleteProjectFile?: (projectId: string, fileId: string) => Promise<void>;
883
888
  }
889
+ /**
890
+ * @description OpenAI/Anthropic 호환 멀티모달 콘텐츠 파트
891
+ * @Todo vibecode - 이미지 첨부 시 AI에 직접 전달 (ai-decide 모드)
892
+ */
893
+ type MultimodalContentPart = {
894
+ type: 'text';
895
+ text: string;
896
+ } | {
897
+ type: 'image_url';
898
+ image_url: {
899
+ url: string;
900
+ detail?: 'auto' | 'low' | 'high';
901
+ };
902
+ };
903
+ /**
904
+ * @description 메시지 콘텐츠 (단순 텍스트 또는 멀티모달)
905
+ * @Todo vibecode - 하위 호환: string이면 기존 텍스트, 배열이면 멀티모달
906
+ */
907
+ type MessageContent = string | MultimodalContentPart[];
884
908
  interface SendMessageParams {
885
909
  messages: {
886
910
  role: 'user' | 'assistant' | 'system';
887
- content: string;
911
+ content: MessageContent;
888
912
  }[];
889
913
  model: string;
890
914
  provider: ProviderType;
@@ -1515,6 +1539,11 @@ interface UseChatUIOptions {
1515
1539
  onAddProjectFile?: (projectId: string, file: File) => Promise<ProjectFile>;
1516
1540
  /** @Todo vibecode - 프로젝트 파일 삭제 콜백 */
1517
1541
  onDeleteProjectFile?: (projectId: string, fileId: string) => Promise<void>;
1542
+ /**
1543
+ * @description 이미지 첨부 시 처리 방식 (기본: 'auto-execute')
1544
+ * @Todo vibecode - 'auto-execute': attachment 스킬 자동 실행, 'ai-decide': 이미지를 AI에 전달하여 AI가 도구 선택
1545
+ */
1546
+ imageAttachmentMode?: 'auto-execute' | 'ai-decide';
1518
1547
  /**
1519
1548
  * @description 도구 실행 후 AI 스트리밍 계속 여부 (기본: true, 하위호환)
1520
1549
  * @Todo vibecode - false 시 도구 결과만 표시하고 AI 후속 응답 생략
@@ -2119,4 +2148,4 @@ declare const DEFAULT_PROJECT_TITLE = "\uAE30\uBCF8 \uD504\uB85C\uC81D\uD2B8";
2119
2148
  */
2120
2149
  declare const migrateSessionsToProjects: (storageKey: string) => void;
2121
2150
 
2122
- export { type ActionItem, type ActionMenuProps, type AdvancedResearchOptions, type AlternativeResponse, type ChatAttachment, 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, ContentPartRenderer, type ContentPartRendererProps, DEFAULT_PROJECT_ID, DEFAULT_PROJECT_TITLE, type DeepResearchCallbacks, type DeepResearchProgress, DeepResearchProgressUI, EmptyState, type EmptyStateProps, type ErrorContentPart, FileContentCard, type FileContentCardProps, type FileContentPart, 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 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 ResponseStyle, type SearchResult, type SearchResultContentPart, type SendMessageParams, type SendMessageResponse, 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 TextContentPart, type ThemeConfig, type ThemeMode, type ToolCallResult, type ToolLoadingContentPart, type ToolResultContentPart, type UseChatUIOptions, type UseChatUIReturn, type UseDeepResearchOptions, type UseProjectOptions, type UseProjectReturn, type UseSkillsOptions, type UseSkillsReturn, type UserProfile, convertToolsToSkills, createAdvancedResearchSkill, createDeepResearchSkill, migrateSessionsToProjects, useChatUI, useDeepResearch, useProject, useSkills };
2151
+ export { type ActionItem, type ActionMenuProps, type AdvancedResearchOptions, type AlternativeResponse, type ChatAttachment, 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, ContentPartRenderer, type ContentPartRendererProps, DEFAULT_PROJECT_ID, DEFAULT_PROJECT_TITLE, type DeepResearchCallbacks, type DeepResearchProgress, DeepResearchProgressUI, EmptyState, type EmptyStateProps, type ErrorContentPart, FileContentCard, type FileContentCardProps, type FileContentPart, 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 MessageContent, type MessageContentPart, MessageList, type MessageListProps, type ModelConfig, type ModelSelectorProps, type MultimodalContentPart, 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 ResponseStyle, type SearchResult, type SearchResultContentPart, type SendMessageParams, type SendMessageResponse, 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 TextContentPart, type ThemeConfig, type ThemeMode, type ToolCallResult, type ToolLoadingContentPart, type ToolResultContentPart, type UseChatUIOptions, type UseChatUIReturn, type UseDeepResearchOptions, type UseProjectOptions, type UseProjectReturn, type UseSkillsOptions, type UseSkillsReturn, type UserProfile, convertToolsToSkills, createAdvancedResearchSkill, createDeepResearchSkill, migrateSessionsToProjects, useChatUI, useDeepResearch, useProject, useSkills };
@@ -819,6 +819,11 @@ interface ChatUIProps {
819
819
  * @Todo vibecode - 라이브러리가 도구 호출 판단 후 호스트에 실행 위임
820
820
  */
821
821
  onToolCall?: (name: string, params: Record<string, unknown>) => Promise<ToolCallResult>;
822
+ /**
823
+ * @description 이미지 첨부 시 처리 방식 (기본: 'auto-execute')
824
+ * @Todo vibecode - 'auto-execute': attachment 스킬 자동 실행, 'ai-decide': 이미지를 AI에 전달하여 AI가 도구 선택
825
+ */
826
+ imageAttachmentMode?: 'auto-execute' | 'ai-decide';
822
827
  /**
823
828
  * @description 도구/스킬 실행 후 AI 후속 스트리밍 계속 여부 (기본: true)
824
829
  * @Todo vibecode - false 시 도구 결과만 표시하고 AI 후속 응답 생략
@@ -881,10 +886,29 @@ interface ChatUIProps {
881
886
  */
882
887
  onDeleteProjectFile?: (projectId: string, fileId: string) => Promise<void>;
883
888
  }
889
+ /**
890
+ * @description OpenAI/Anthropic 호환 멀티모달 콘텐츠 파트
891
+ * @Todo vibecode - 이미지 첨부 시 AI에 직접 전달 (ai-decide 모드)
892
+ */
893
+ type MultimodalContentPart = {
894
+ type: 'text';
895
+ text: string;
896
+ } | {
897
+ type: 'image_url';
898
+ image_url: {
899
+ url: string;
900
+ detail?: 'auto' | 'low' | 'high';
901
+ };
902
+ };
903
+ /**
904
+ * @description 메시지 콘텐츠 (단순 텍스트 또는 멀티모달)
905
+ * @Todo vibecode - 하위 호환: string이면 기존 텍스트, 배열이면 멀티모달
906
+ */
907
+ type MessageContent = string | MultimodalContentPart[];
884
908
  interface SendMessageParams {
885
909
  messages: {
886
910
  role: 'user' | 'assistant' | 'system';
887
- content: string;
911
+ content: MessageContent;
888
912
  }[];
889
913
  model: string;
890
914
  provider: ProviderType;
@@ -1515,6 +1539,11 @@ interface UseChatUIOptions {
1515
1539
  onAddProjectFile?: (projectId: string, file: File) => Promise<ProjectFile>;
1516
1540
  /** @Todo vibecode - 프로젝트 파일 삭제 콜백 */
1517
1541
  onDeleteProjectFile?: (projectId: string, fileId: string) => Promise<void>;
1542
+ /**
1543
+ * @description 이미지 첨부 시 처리 방식 (기본: 'auto-execute')
1544
+ * @Todo vibecode - 'auto-execute': attachment 스킬 자동 실행, 'ai-decide': 이미지를 AI에 전달하여 AI가 도구 선택
1545
+ */
1546
+ imageAttachmentMode?: 'auto-execute' | 'ai-decide';
1518
1547
  /**
1519
1548
  * @description 도구 실행 후 AI 스트리밍 계속 여부 (기본: true, 하위호환)
1520
1549
  * @Todo vibecode - false 시 도구 결과만 표시하고 AI 후속 응답 생략
@@ -2119,4 +2148,4 @@ declare const DEFAULT_PROJECT_TITLE = "\uAE30\uBCF8 \uD504\uB85C\uC81D\uD2B8";
2119
2148
  */
2120
2149
  declare const migrateSessionsToProjects: (storageKey: string) => void;
2121
2150
 
2122
- export { type ActionItem, type ActionMenuProps, type AdvancedResearchOptions, type AlternativeResponse, type ChatAttachment, 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, ContentPartRenderer, type ContentPartRendererProps, DEFAULT_PROJECT_ID, DEFAULT_PROJECT_TITLE, type DeepResearchCallbacks, type DeepResearchProgress, DeepResearchProgressUI, EmptyState, type EmptyStateProps, type ErrorContentPart, FileContentCard, type FileContentCardProps, type FileContentPart, 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 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 ResponseStyle, type SearchResult, type SearchResultContentPart, type SendMessageParams, type SendMessageResponse, 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 TextContentPart, type ThemeConfig, type ThemeMode, type ToolCallResult, type ToolLoadingContentPart, type ToolResultContentPart, type UseChatUIOptions, type UseChatUIReturn, type UseDeepResearchOptions, type UseProjectOptions, type UseProjectReturn, type UseSkillsOptions, type UseSkillsReturn, type UserProfile, convertToolsToSkills, createAdvancedResearchSkill, createDeepResearchSkill, migrateSessionsToProjects, useChatUI, useDeepResearch, useProject, useSkills };
2151
+ export { type ActionItem, type ActionMenuProps, type AdvancedResearchOptions, type AlternativeResponse, type ChatAttachment, 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, ContentPartRenderer, type ContentPartRendererProps, DEFAULT_PROJECT_ID, DEFAULT_PROJECT_TITLE, type DeepResearchCallbacks, type DeepResearchProgress, DeepResearchProgressUI, EmptyState, type EmptyStateProps, type ErrorContentPart, FileContentCard, type FileContentCardProps, type FileContentPart, 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 MessageContent, type MessageContentPart, MessageList, type MessageListProps, type ModelConfig, type ModelSelectorProps, type MultimodalContentPart, 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 ResponseStyle, type SearchResult, type SearchResultContentPart, type SendMessageParams, type SendMessageResponse, 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 TextContentPart, type ThemeConfig, type ThemeMode, type ToolCallResult, type ToolLoadingContentPart, type ToolResultContentPart, type UseChatUIOptions, type UseChatUIReturn, type UseDeepResearchOptions, type UseProjectOptions, type UseProjectReturn, type UseSkillsOptions, type UseSkillsReturn, type UserProfile, convertToolsToSkills, createAdvancedResearchSkill, createDeepResearchSkill, migrateSessionsToProjects, useChatUI, useDeepResearch, useProject, useSkills };
@@ -1781,6 +1781,8 @@ var useChatUI = (options) => {
1781
1781
  onDeleteProject,
1782
1782
  onAddProjectFile,
1783
1783
  onDeleteProjectFile,
1784
+ // Image attachment mode
1785
+ imageAttachmentMode = "auto-execute",
1784
1786
  // Stream control
1785
1787
  continueAfterToolResult = true,
1786
1788
  onSkillComplete,
@@ -2601,12 +2603,20 @@ ${finalContent}`;
2601
2603
  })
2602
2604
  );
2603
2605
  let attachmentResults = [];
2606
+ const aiDecideImageAttachments = [];
2604
2607
  if (currentAttachments.length > 0) {
2608
+ const autoExecAttachments = imageAttachmentMode === "ai-decide" ? currentAttachments.filter((att) => {
2609
+ if (att.type === "image") {
2610
+ aiDecideImageAttachments.push(att);
2611
+ return false;
2612
+ }
2613
+ return true;
2614
+ }) : currentAttachments;
2605
2615
  const attachmentSkills = Object.entries(resolvedSkills).filter(
2606
2616
  ([, config]) => config.trigger === "attachment"
2607
2617
  );
2608
2618
  for (const [skillName, skillConfig] of attachmentSkills) {
2609
- const matchedFiles = currentAttachments.filter((att) => {
2619
+ const matchedFiles = autoExecAttachments.filter((att) => {
2610
2620
  if (!skillConfig.acceptedTypes || skillConfig.acceptedTypes.length === 0) return true;
2611
2621
  return skillConfig.acceptedTypes.some((type) => {
2612
2622
  if (type.startsWith(".")) return att.name.toLowerCase().endsWith(type.toLowerCase());
@@ -2784,6 +2794,31 @@ ${currentContextSummary}` },
2784
2794
  } else {
2785
2795
  chatMessages = messagesToSend.map((m) => ({ role: m.role, content: m.content }));
2786
2796
  }
2797
+ if (aiDecideImageAttachments.length > 0) {
2798
+ const imageBase64s = await Promise.all(
2799
+ aiDecideImageAttachments.map(async (att) => ({
2800
+ mimeType: att.mimeType,
2801
+ base64: await fileToBase64(att.file)
2802
+ }))
2803
+ );
2804
+ for (let i = chatMessages.length - 1; i >= 0; i--) {
2805
+ if (chatMessages[i].role === "user") {
2806
+ const textContent = typeof chatMessages[i].content === "string" ? chatMessages[i].content : "";
2807
+ const multimodalParts = [];
2808
+ if (textContent.trim()) {
2809
+ multimodalParts.push({ type: "text", text: textContent });
2810
+ }
2811
+ for (const img of imageBase64s) {
2812
+ multimodalParts.push({
2813
+ type: "image_url",
2814
+ image_url: { url: `data:${img.mimeType};base64,${img.base64}` }
2815
+ });
2816
+ }
2817
+ chatMessages[i] = { ...chatMessages[i], content: multimodalParts };
2818
+ break;
2819
+ }
2820
+ }
2821
+ }
2787
2822
  if (attachmentResults.length > 0 && shouldContinueAfterAttachment) {
2788
2823
  skipNextSkillParsingRef.current = true;
2789
2824
  const attachmentContext = attachmentResults.filter((part) => part.type === "tool_result").map((part) => `[${part.label || part.toolName} \uACB0\uACFC]
@@ -2800,7 +2835,7 @@ ${attachmentContext}
2800
2835
  });
2801
2836
  }
2802
2837
  }
2803
- console.log("[ChatUI] Messages to send:", chatMessages.length, chatMessages.map((m) => ({ role: m.role, content: m.content.slice(0, 50) })));
2838
+ console.log("[ChatUI] Messages to send:", chatMessages.length, chatMessages.map((m) => ({ role: m.role, content: typeof m.content === "string" ? m.content.slice(0, 50) : "[multimodal]" })));
2804
2839
  const baseSystemPrompt = buildSystemPrompt();
2805
2840
  const combinedSystemPrompt = [baseSystemPrompt, actionPrompt].filter(Boolean).join("\n\n");
2806
2841
  const messagesForApi = combinedSystemPrompt ? [{ role: "system", content: combinedSystemPrompt }, ...chatMessages] : chatMessages;
@@ -12374,6 +12409,7 @@ var ChatUIWithHook = ({
12374
12409
  skills,
12375
12410
  tools,
12376
12411
  onToolCall,
12412
+ imageAttachmentMode,
12377
12413
  continueAfterToolResult,
12378
12414
  onSkillComplete,
12379
12415
  onLoadModels,
@@ -12416,6 +12452,7 @@ var ChatUIWithHook = ({
12416
12452
  skills,
12417
12453
  tools,
12418
12454
  onToolCall,
12455
+ imageAttachmentMode,
12419
12456
  continueAfterToolResult,
12420
12457
  onSkillComplete,
12421
12458
  onLoadModels,