Skip to content

Commit

Permalink
refactor(chat-models)!: Make MIME Type mandatory for base64 images in…
Browse files Browse the repository at this point in the history
… prompt (#269)
  • Loading branch information
davidmigloz committed Dec 15, 2023
1 parent 4ecb123 commit 2fe076b
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 13 deletions.
45 changes: 34 additions & 11 deletions packages/langchain/lib/src/model_io/chat_models/models/models.dart
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,12 @@ sealed class ChatMessage {
final SystemChatMessage system => system.content,
final HumanChatMessage human => switch (human.content) {
final ChatMessageContentText text => text.text,
final ChatMessageContentImage image => image.url,
final ChatMessageContentImage image => image.data,
final ChatMessageContentMultiModal multiModal => multiModal.parts
.map(
(final p) => switch (p) {
final ChatMessageContentText text => text.text,
final ChatMessageContentImage image => image.url,
final ChatMessageContentImage image => image.data,
ChatMessageContentMultiModal _ => '',
},
)
Expand Down Expand Up @@ -495,13 +495,20 @@ sealed class ChatMessageContent {
ChatMessageContentText(text: text);

/// The content of a message that is an image.
///
/// More info about the possible values:
/// - [ChatMessageContentImage.data]
/// - [ChatMessageContentImage.mimeType]
/// - [ChatMessageContentImage.detail]
factory ChatMessageContent.image({
required final String url,
required final String data,
final String? mimeType,
final ChatMessageContentImageDetail imageDetail =
ChatMessageContentImageDetail.auto,
}) =>
ChatMessageContentImage(
url: url,
data: data,
mimeType: mimeType,
detail: imageDetail,
);

Expand Down Expand Up @@ -546,28 +553,44 @@ ChatMessageContentText{
class ChatMessageContentImage extends ChatMessageContent {
/// {@macro chat_message_content_image}
const ChatMessageContentImage({
required this.url,
required this.detail,
required this.data,
this.mimeType,
this.detail = ChatMessageContentImageDetail.auto,
});

/// Either a URL of the image or the base64 encoded image data.
final String url;
/// Depending on the model, this can be either:
/// - The base64 encoded image data
/// - A URL of the image.
final String data;

/// The IANA standard MIME type of the source data.
/// The accepted types vary per model.
///
/// Examples of MIME types:
/// - `image/png`
/// - `image/jpeg`
/// - `image/heic`
/// - `image/heif`
/// - `image/webp`
final String? mimeType;

/// Specifies the detail level of the image.
final ChatMessageContentImageDetail detail;

@override
bool operator ==(covariant final ChatMessageContentImage other) =>
identical(this, other) || url == other.url;
identical(this, other) ||
data == other.data && data == other.data && detail == other.detail;

@override
int get hashCode => url.hashCode;
int get hashCode => data.hashCode ^ mimeType.hashCode ^ detail.hashCode;

@override
String toString() {
return '''
ChatMessageContentImage{
url: $url,
url: $data,
mimeType: $mimeType,
imageDetail: $detail,
}''';
}
Expand Down
15 changes: 15 additions & 0 deletions packages/langchain_openai/lib/src/chat_models/models/mappers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,21 @@ extension _ChatMessageContentTextMapper on ChatMessageContentText {

extension _ChatMessageContentImageMapper on ChatMessageContentImage {
ChatCompletionMessageContentPartImage toChatCompletionMessageContentPart() {
final imageData = data.trim();
final isUrl = imageData.startsWith('http');
String url;
if (isUrl) {
url = imageData;
} else {
if (mimeType == null) {
throw ArgumentError(
"When passing a Base64 encoded image, you need to specify the mimeType (e.g. 'image/png')",
'ChatMessageContentImage.mimeType',
);
}
url = 'data:$mimeType;base64,$imageData';
}

return ChatCompletionMessageContentPartImage(
imageUrl: ChatCompletionMessageImageUrl(
url: url,
Expand Down
33 changes: 31 additions & 2 deletions packages/langchain_openai/test/chat_models/openai_test.dart

Large diffs are not rendered by default.

0 comments on commit 2fe076b

Please sign in to comment.