forked from mealie-recipes/mealie
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: OpenAI Custom Headers/Params and Debug Page (mealie-recipes#4227)
Co-authored-by: Kuchenpirat <[email protected]>
- Loading branch information
1 parent
45e51f9
commit 05b3d6a
Showing
20 changed files
with
277 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { BaseAPI } from "../base/base-clients"; | ||
import { DebugResponse } from "~/lib/api/types/admin"; | ||
|
||
const prefix = "/api"; | ||
|
||
const routes = { | ||
openai: `${prefix}/admin/debug/openai`, | ||
}; | ||
|
||
export class AdminDebugAPI extends BaseAPI { | ||
async debugOpenAI(fileObject: Blob | File | undefined = undefined, fileName = "") { | ||
let formData: FormData | null = null; | ||
if (fileObject) { | ||
formData = new FormData(); | ||
formData.append("image", fileObject); | ||
formData.append("extension", fileName.split(".").pop() ?? ""); | ||
} | ||
|
||
return await this.requests.post<DebugResponse>(routes.openai, formData); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
<template> | ||
<v-container class="pa-0"> | ||
<v-container> | ||
<BaseCardSectionTitle :title="$tc('admin.debug-openai-services')"> | ||
{{ $t('admin.debug-openai-services-description') }} | ||
<br /> | ||
<DocLink class="mt-2" link="/documentation/getting-started/installation/open-ai" /> | ||
</BaseCardSectionTitle> | ||
</v-container> | ||
<v-form ref="uploadForm" @submit.prevent="testOpenAI"> | ||
<div> | ||
<v-card-text> | ||
<v-container class="pa-0"> | ||
<v-row> | ||
<v-col cols="auto" align-self="center"> | ||
<AppButtonUpload | ||
v-if="!uploadedImage" | ||
class="ml-auto" | ||
url="none" | ||
file-name="image" | ||
accept="image/*" | ||
:text="$i18n.tc('recipe.upload-image')" | ||
:text-btn="false" | ||
:post="false" | ||
@uploaded="uploadImage" | ||
/> | ||
<v-btn | ||
v-if="!!uploadedImage" | ||
color="error" | ||
@click="clearImage" | ||
> | ||
<v-icon left>{{ $globals.icons.close }}</v-icon> | ||
{{ $i18n.tc("recipe.remove-image") }} | ||
</v-btn> | ||
</v-col> | ||
<v-spacer /> | ||
</v-row> | ||
<v-row v-if="uploadedImage && uploadedImagePreviewUrl" style="max-width: 25%;"> | ||
<v-spacer /> | ||
<v-col cols="12"> | ||
<v-img :src="uploadedImagePreviewUrl" /> | ||
</v-col> | ||
<v-spacer /> | ||
</v-row> | ||
</v-container> | ||
</v-card-text> | ||
<v-card-actions> | ||
<BaseButton | ||
type="submit" | ||
:text="$i18n.tc('admin.run-test')" | ||
:icon="$globals.icons.check" | ||
:loading="loading" | ||
class="ml-auto" | ||
/> | ||
</v-card-actions> | ||
</div> | ||
</v-form> | ||
<v-divider v-if="response" class="mt-4" /> | ||
<v-container v-if="response" class="ma-0 pa-0"> | ||
<v-card-title> {{ $t('admin.test-results') }} </v-card-title> | ||
<v-card-text> {{ response }} </v-card-text> | ||
</v-container> | ||
</v-container> | ||
</template> | ||
|
||
<script lang="ts"> | ||
import { defineComponent, ref } from "@nuxtjs/composition-api"; | ||
import { useAdminApi } from "~/composables/api"; | ||
import { alert } from "~/composables/use-toast"; | ||
import { VForm } from "~/types/vuetify"; | ||
export default defineComponent({ | ||
layout: "admin", | ||
setup() { | ||
const api = useAdminApi(); | ||
const loading = ref(false); | ||
const response = ref(""); | ||
const uploadForm = ref<VForm | null>(null); | ||
const uploadedImage = ref<Blob | File>(); | ||
const uploadedImageName = ref<string>(""); | ||
const uploadedImagePreviewUrl = ref<string>(); | ||
function uploadImage(fileObject: File) { | ||
uploadedImage.value = fileObject; | ||
uploadedImageName.value = fileObject.name; | ||
uploadedImagePreviewUrl.value = URL.createObjectURL(fileObject); | ||
} | ||
function clearImage() { | ||
uploadedImage.value = undefined; | ||
uploadedImageName.value = ""; | ||
uploadedImagePreviewUrl.value = undefined; | ||
} | ||
async function testOpenAI() { | ||
response.value = ""; | ||
loading.value = true; | ||
const { data } = await api.debug.debugOpenAI(uploadedImage.value); | ||
loading.value = false; | ||
if (!data) { | ||
alert.error("Unable to test OpenAI services"); | ||
} else { | ||
response.value = data.response || (data.success ? "Test Successful" : "Test Failed"); | ||
} | ||
} | ||
return { | ||
loading, | ||
response, | ||
uploadForm, | ||
uploadedImage, | ||
uploadedImagePreviewUrl, | ||
uploadImage, | ||
clearImage, | ||
testOpenAI, | ||
}; | ||
}, | ||
head() { | ||
return { | ||
title: this.$t("admin.debug-openai-services"), | ||
}; | ||
}, | ||
}); | ||
</script> |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import os | ||
import shutil | ||
|
||
from fastapi import APIRouter, File, UploadFile | ||
|
||
from mealie.core.dependencies.dependencies import get_temporary_path | ||
from mealie.routes._base import BaseAdminController, controller | ||
from mealie.schema.admin.debug import DebugResponse | ||
from mealie.services.openai import OpenAILocalImage, OpenAIService | ||
|
||
router = APIRouter(prefix="/debug") | ||
|
||
|
||
@controller(router) | ||
class AdminDebugController(BaseAdminController): | ||
@router.post("/openai", response_model=DebugResponse) | ||
async def debug_openai(self, image: UploadFile | None = File(None)): | ||
if not self.settings.OPENAI_ENABLED: | ||
return DebugResponse(success=False, response="OpenAI is not enabled") | ||
if image and not self.settings.OPENAI_ENABLE_IMAGE_SERVICES: | ||
return DebugResponse( | ||
success=False, response="Image was provided, but OpenAI image services are not enabled" | ||
) | ||
|
||
with get_temporary_path() as temp_path: | ||
if image: | ||
with temp_path.joinpath(image.filename).open("wb") as buffer: | ||
shutil.copyfileobj(image.file, buffer) | ||
local_image_path = temp_path.joinpath(image.filename) | ||
local_images = [OpenAILocalImage(filename=os.path.basename(local_image_path), path=local_image_path)] | ||
else: | ||
local_images = None | ||
|
||
try: | ||
openai_service = OpenAIService() | ||
prompt = openai_service.get_prompt("debug") | ||
|
||
message = "Hello, checking to see if I can reach you." | ||
if local_images: | ||
message = f"{message} Here is an image to test with:" | ||
|
||
response = await openai_service.get_response( | ||
prompt, message, images=local_images, force_json_response=False | ||
) | ||
return DebugResponse(success=True, response=f'OpenAI is working. Response: "{response}"') | ||
|
||
except Exception as e: | ||
self.logger.exception(e) | ||
return DebugResponse( | ||
success=False, | ||
response=f'OpenAI request failed. Full error has been logged. {e.__class__.__name__}: "{e}"', | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from mealie.schema._mealie import MealieModel | ||
|
||
|
||
class DebugResponse(MealieModel): | ||
success: bool | ||
response: str | None = None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
You are a simple chatbot being used for debugging purposes. |
Oops, something went wrong.