001/* 002 * Copyright (c) 2023-2026, Agents-Flex (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.agentsflex.core.message; 017 018import com.agentsflex.core.model.chat.ChatConfig; 019import com.agentsflex.core.util.ImageUtil; 020 021import java.io.File; 022import java.util.ArrayList; 023import java.util.HashMap; 024import java.util.List; 025 026public class UserMessage extends AbstractTextMessage<UserMessage> { 027 028 private List<String> audioUrls; 029 private List<String> videoUrls; 030 private List<String> imageUrls; 031 032 033 public UserMessage() { 034 } 035 036 public UserMessage(String content) { 037 setContent(content); 038 } 039 040 041 /// /// Audio 042 public List<String> getAudioUrls() { 043 return audioUrls; 044 } 045 046 public void setAudioUrls(List<String> audioUrls) { 047 this.audioUrls = audioUrls; 048 } 049 050 public void addAudioUrl(String audioUrl) { 051 if (audioUrls == null) { 052 audioUrls = new ArrayList<>(1); 053 } 054 audioUrls.add(audioUrl); 055 } 056 057 058 /// /// Video 059 public List<String> getVideoUrls() { 060 return videoUrls; 061 } 062 063 public void setVideoUrls(List<String> videoUrls) { 064 this.videoUrls = videoUrls; 065 } 066 067 public void addVideoUrl(String videoUrl) { 068 if (videoUrls == null) { 069 videoUrls = new ArrayList<>(1); 070 } 071 videoUrls.add(videoUrl); 072 } 073 074 075 /// /// Images 076 public List<String> getImageUrls() { 077 return imageUrls; 078 } 079 080 public List<String> getImageUrlsForChat(ChatConfig config) { 081 if (this.imageUrls == null) { 082 return null; 083 } 084 List<String> result = new ArrayList<>(this.imageUrls.size()); 085 for (String url : imageUrls) { 086 if (config != null && config.isSupportImageBase64Only() 087 && url.toLowerCase().startsWith("http")) { 088 url = ImageUtil.imageUrlToDataUri(url); 089 } 090 result.add(url); 091 } 092 return result; 093 } 094 095 public void setImageUrls(List<String> imageUrls) { 096 this.imageUrls = imageUrls; 097 } 098 099 public void addImageUrl(String imageUrl) { 100 if (this.imageUrls == null) { 101 this.imageUrls = new ArrayList<>(1); 102 } 103 this.imageUrls.add(imageUrl); 104 } 105 106 public void addImageFile(File imageFile) { 107 addImageUrl(ImageUtil.imageFileToDataUri(imageFile)); 108 } 109 110 public void addImageBytes(byte[] imageBytes, String mimeType) { 111 addImageUrl(ImageUtil.imageBytesToDataUri(imageBytes, mimeType)); 112 } 113 114 115 @Override 116 public String toString() { 117 return "UserMessage{" + 118 "audioUrls=" + audioUrls + 119 ", videoUrls=" + videoUrls + 120 ", imageUrls=" + imageUrls + 121 ", content='" + content + '\'' + 122 ", metadataMap=" + metadataMap + 123 '}'; 124 } 125 126 /** 127 * 创建并返回当前对象的副本。 128 * 129 * @return 一个新的、内容相同但内存独立的对象 130 */ 131 @Override 132 public UserMessage copy() { 133 UserMessage copy = new UserMessage(); 134 copy.content = this.content; 135 136 // 深拷贝集合 137 if (this.audioUrls != null) copy.audioUrls = new ArrayList<>(this.audioUrls); 138 if (this.videoUrls != null) copy.videoUrls = new ArrayList<>(this.videoUrls); 139 if (this.imageUrls != null) copy.imageUrls = new ArrayList<>(this.imageUrls); 140 141 if (this.metadataMap != null) { 142 copy.metadataMap = new HashMap<>(this.metadataMap); 143 } 144 145 return copy; 146 } 147}