θΏ™ζ˜―indexlocζδΎ›ηš„ζœεŠ‘οΌŒδΈθ¦θΎ“ε…₯任何密码
Skip to content

Add attachments to GenericOpenAI prompt #2831

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 49 additions & 1 deletion server/utils/AiProviders/genericOpenAi/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,65 @@ class GenericOpenAiLLM {
return true;
}

/**
* Generates appropriate content array for a message + attachments.
*
* ## Developer Note
* This function assumes the generic OpenAI provider is _actually_ OpenAI compatible.
* For example, Ollama is "OpenAI compatible" but does not support images as a content array.
* The contentString also is the base64 string WITH `data:image/xxx;base64,` prefix, which may not be the case for all providers.
* If your provider does not work exactly this way, then attachments will not function or potentially break vision requests.
* If you encounter this issue, you are welcome to open an issue asking for your specific provider to be supported.
*
* This function will **not** be updated for providers that **do not** support images as a content array like OpenAI does.
* Do not open issues to update this function due to your specific provider not being compatible. Open an issue to request support for your specific provider.
* @param {Object} props
* @param {string} props.userPrompt - the user prompt to be sent to the model
* @param {import("../../helpers").Attachment[]} props.attachments - the array of attachments to be sent to the model
* @returns {string|object[]}
*/
#generateContent({ userPrompt, attachments = [] }) {
if (!attachments.length) {
return userPrompt;
}

const content = [{ type: "text", text: userPrompt }];
for (let attachment of attachments) {
content.push({
type: "image_url",
image_url: {
url: attachment.contentString,
detail: "high",
},
});
}
return content.flat();
}

/**
* Construct the user prompt for this model.
* @param {{attachments: import("../../helpers").Attachment[]}} param0
* @returns
*/
constructPrompt({
systemPrompt = "",
contextTexts = [],
chatHistory = [],
userPrompt = "",
attachments = [],
}) {
const prompt = {
role: "system",
content: `${systemPrompt}${this.#appendContext(contextTexts)}`,
};
return [prompt, ...chatHistory, { role: "user", content: userPrompt }];
return [
prompt,
...chatHistory,
{
role: "user",
content: this.#generateContent({ userPrompt, attachments }),
},
];
}

async getChatCompletion(messages = null, { temperature = 0.7 }) {
Expand Down