diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsIntegrations.java b/app/src/main/java/eu/faircode/email/FragmentOptionsIntegrations.java index be8f73d330..31a0f416ba 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptionsIntegrations.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsIntegrations.java @@ -80,6 +80,7 @@ public class FragmentOptionsIntegrations extends FragmentBase implements SharedP private EditText etOpenAi; private TextInputLayout tilOpenAi; private EditText etOpenAiModel; + private SwitchCompat swOpenMultiModal; private TextView tvOpenAiTemperature; private SeekBar sbOpenAiTemperature; private EditText etOpenAiSummarize; @@ -106,7 +107,7 @@ public class FragmentOptionsIntegrations extends FragmentBase implements SharedP "deepl_enabled", "vt_enabled", "send_enabled", "send_host", "send_dlimit", "send_tlimit", - "openai_enabled", "openai_uri", "openai_model", "openai_temperature", "openai_summarize", + "openai_enabled", "openai_uri", "openai_model", "openai_multimodal", "openai_temperature", "openai_summarize", "gemini_enabled", "gemini_uri", "gemini_model", "gemini_temperature", "gemini_summarize" )); @@ -152,6 +153,7 @@ public class FragmentOptionsIntegrations extends FragmentBase implements SharedP etOpenAi = view.findViewById(R.id.etOpenAi); tilOpenAi = view.findViewById(R.id.tilOpenAi); etOpenAiModel = view.findViewById(R.id.etOpenAiModel); + swOpenMultiModal = view.findViewById(R.id.swOpenMultiModal); tvOpenAiTemperature = view.findViewById(R.id.tvOpenAiTemperature); sbOpenAiTemperature = view.findViewById(R.id.sbOpenAiTemperature); etOpenAiSummarize = view.findViewById(R.id.etOpenAiSummarize); @@ -419,6 +421,7 @@ public class FragmentOptionsIntegrations extends FragmentBase implements SharedP public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { prefs.edit().putBoolean("openai_enabled", checked).apply(); etOpenAiModel.setEnabled(checked); + swOpenMultiModal.setEnabled(checked); sbOpenAiTemperature.setEnabled(checked); etOpenAiSummarize.setEnabled(checked); if (checked) @@ -499,6 +502,13 @@ public class FragmentOptionsIntegrations extends FragmentBase implements SharedP } }); + swOpenMultiModal.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean checked) { + prefs.edit().putBoolean("openai_multimodal", checked).apply(); + } + }); + sbOpenAiTemperature.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { @@ -779,6 +789,9 @@ public class FragmentOptionsIntegrations extends FragmentBase implements SharedP etOpenAiModel.setText(prefs.getString("openai_model", null)); etOpenAiModel.setEnabled(swOpenAi.isChecked()); + swOpenMultiModal.setChecked(prefs.getBoolean("openai_multimodal", true)); + swOpenMultiModal.setEnabled(swOpenAi.isChecked()); + float temperature = prefs.getFloat("openai_temperature", OpenAI.DEFAULT_TEMPERATURE); tvOpenAiTemperature.setText(getString(R.string.title_advanced_openai_temperature, NF.format(temperature))); sbOpenAiTemperature.setProgress(Math.round(temperature * 10)); diff --git a/app/src/main/java/eu/faircode/email/OpenAI.java b/app/src/main/java/eu/faircode/email/OpenAI.java index 03752af556..5c888080cb 100644 --- a/app/src/main/java/eu/faircode/email/OpenAI.java +++ b/app/src/main/java/eu/faircode/email/OpenAI.java @@ -265,6 +265,9 @@ public class OpenAI { } static Content[] get(Spannable ssb, long id, Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + boolean multimodal = prefs.getBoolean("openai_multimodal", true); + DB db = DB.getInstance(context); List contents = new ArrayList<>(); int start = 0; @@ -276,28 +279,31 @@ public class OpenAI { ImageSpanEx[] spans = ssb.getSpans(end, end, ImageSpanEx.class); if (spans.length == 1) { int e = ssb.getSpanEnd(spans[0]); - String src = spans[0].getSource(); - String url = null; - if (src != null && src.startsWith("cid:")) { - String cid = '<' + src.substring(4) + '>'; - EntityAttachment attachment = db.attachment().getAttachment(id, cid); - if (attachment != null && attachment.available) { - File file = attachment.getFile(context); - try (InputStream is = new FileInputStream(file)) { - Bitmap bm = ImageHelper.getScaledBitmap(is, null, null, SCALE2PIXELS); - Helper.ByteArrayInOutStream bos = new Helper.ByteArrayInOutStream(); - bm.compress(Bitmap.CompressFormat.PNG, 90, bos); - url = ImageHelper.getDataUri(bos.getInputStream(), "image/png"); - } catch (Throwable ex) { - Log.w(ex); + if (multimodal) { + String url = null; + String src = spans[0].getSource(); + if (src != null && src.startsWith("cid:")) { + String cid = '<' + src.substring(4) + '>'; + EntityAttachment attachment = db.attachment().getAttachment(id, cid); + if (attachment != null && attachment.available) { + File file = attachment.getFile(context); + try (InputStream is = new FileInputStream(file)) { + Bitmap bm = ImageHelper.getScaledBitmap(is, null, null, SCALE2PIXELS); + Helper.ByteArrayInOutStream bos = new Helper.ByteArrayInOutStream(); + bm.compress(Bitmap.CompressFormat.PNG, 90, bos); + url = ImageHelper.getDataUri(bos.getInputStream(), "image/png"); + } catch (Throwable ex) { + Log.w(ex); + } } - } - } else - url = src; + } else + url = src; + + if (url != null) + contents.add(new OpenAI.Content(OpenAI.CONTENT_IMAGE, url)); + } - if (url != null) - contents.add(new OpenAI.Content(OpenAI.CONTENT_IMAGE, url)); end = e; } } diff --git a/app/src/main/res/layout/fragment_options_integrations.xml b/app/src/main/res/layout/fragment_options_integrations.xml index cd04772d73..326b0ec70d 100644 --- a/app/src/main/res/layout/fragment_options_integrations.xml +++ b/app/src/main/res/layout/fragment_options_integrations.xml @@ -564,6 +564,19 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tvOpenAiModel" /> + + + app:layout_constraintTop_toBottomOf="@id/swOpenMultiModal" /> Temperature: %1$s Content moderation Gemini integration + Multimodal Summarize prompt I want to use an SD card Periodically check if FairEmail is still active