-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'refs/heads/main' into fix/extra-table-tracing-app-config
* refs/heads/main: feat(tool): getimg.ai integration (#6260) fix: next suggest question logic problem (#6451)
- Loading branch information
Showing
8 changed files
with
319 additions
and
1 deletion.
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
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,22 @@ | ||
from core.tools.errors import ToolProviderCredentialValidationError | ||
from core.tools.provider.builtin.getimgai.tools.text2image import Text2ImageTool | ||
from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController | ||
|
||
|
||
class GetImgAIProvider(BuiltinToolProviderController): | ||
def _validate_credentials(self, credentials: dict) -> None: | ||
try: | ||
# Example validation using the text2image tool | ||
Text2ImageTool().fork_tool_runtime( | ||
runtime={"credentials": credentials} | ||
).invoke( | ||
user_id='', | ||
tool_parameters={ | ||
"prompt": "A fire egg", | ||
"response_format": "url", | ||
"style": "photorealism", | ||
} | ||
) | ||
except Exception as e: | ||
raise ToolProviderCredentialValidationError(str(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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
identity: | ||
author: Matri Qi | ||
name: getimgai | ||
label: | ||
en_US: getimg.ai | ||
zh_CN: getimg.ai | ||
description: | ||
en_US: GetImg API integration for image generation and scraping. | ||
icon: icon.svg | ||
tags: | ||
- image | ||
credentials_for_provider: | ||
getimg_api_key: | ||
type: secret-input | ||
required: true | ||
label: | ||
en_US: getimg.ai API Key | ||
placeholder: | ||
en_US: Please input your getimg.ai API key | ||
help: | ||
en_US: Get your getimg.ai API key from your getimg.ai account settings. If you are using a self-hosted version, you may enter any key at your convenience. | ||
url: https://dashboard.getimg.ai/api-keys | ||
base_url: | ||
type: text-input | ||
required: false | ||
label: | ||
en_US: getimg.ai server's Base URL | ||
placeholder: | ||
en_US: https://api.getimg.ai/v1 |
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,59 @@ | ||
import logging | ||
import time | ||
from collections.abc import Mapping | ||
from typing import Any | ||
|
||
import requests | ||
from requests.exceptions import HTTPError | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
class GetImgAIApp: | ||
def __init__(self, api_key: str | None = None, base_url: str | None = None): | ||
self.api_key = api_key | ||
self.base_url = base_url or 'https://api.getimg.ai/v1' | ||
if not self.api_key: | ||
raise ValueError("API key is required") | ||
|
||
def _prepare_headers(self): | ||
headers = { | ||
'Content-Type': 'application/json', | ||
'Authorization': f'Bearer {self.api_key}' | ||
} | ||
return headers | ||
|
||
def _request( | ||
self, | ||
method: str, | ||
url: str, | ||
data: Mapping[str, Any] | None = None, | ||
headers: Mapping[str, str] | None = None, | ||
retries: int = 3, | ||
backoff_factor: float = 0.3, | ||
) -> Mapping[str, Any] | None: | ||
for i in range(retries): | ||
try: | ||
response = requests.request(method, url, json=data, headers=headers) | ||
response.raise_for_status() | ||
return response.json() | ||
except requests.exceptions.RequestException as e: | ||
if i < retries - 1 and isinstance(e, HTTPError) and e.response.status_code >= 500: | ||
time.sleep(backoff_factor * (2 ** i)) | ||
else: | ||
raise | ||
return None | ||
|
||
def text2image( | ||
self, mode: str, **kwargs | ||
): | ||
data = kwargs['params'] | ||
if not data.get('prompt'): | ||
raise ValueError("Prompt is required") | ||
|
||
endpoint = f'{self.base_url}/{mode}/text-to-image' | ||
headers = self._prepare_headers() | ||
logger.debug(f"Send request to {endpoint=} body={data}") | ||
response = self._request('POST', endpoint, data, headers) | ||
if response is None: | ||
raise HTTPError("Failed to initiate getimg.ai after multiple retries") | ||
return response |
39 changes: 39 additions & 0 deletions
39
api/core/tools/provider/builtin/getimgai/tools/text2image.py
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,39 @@ | ||
import json | ||
from typing import Any, Union | ||
|
||
from core.tools.entities.tool_entities import ToolInvokeMessage | ||
from core.tools.provider.builtin.getimgai.getimgai_appx import GetImgAIApp | ||
from core.tools.tool.builtin_tool import BuiltinTool | ||
|
||
|
||
class Text2ImageTool(BuiltinTool): | ||
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: | ||
app = GetImgAIApp(api_key=self.runtime.credentials['getimg_api_key'], base_url=self.runtime.credentials['base_url']) | ||
|
||
options = { | ||
'style': tool_parameters.get('style'), | ||
'prompt': tool_parameters.get('prompt'), | ||
'aspect_ratio': tool_parameters.get('aspect_ratio'), | ||
'output_format': tool_parameters.get('output_format', 'jpeg'), | ||
'response_format': tool_parameters.get('response_format', 'url'), | ||
'width': tool_parameters.get('width'), | ||
'height': tool_parameters.get('height'), | ||
'steps': tool_parameters.get('steps'), | ||
'negative_prompt': tool_parameters.get('negative_prompt'), | ||
'prompt_2': tool_parameters.get('prompt_2'), | ||
} | ||
options = {k: v for k, v in options.items() if v} | ||
|
||
text2image_result = app.text2image( | ||
mode=tool_parameters.get('mode', 'essential-v2'), | ||
params=options, | ||
wait=True | ||
) | ||
|
||
if not isinstance(text2image_result, str): | ||
text2image_result = json.dumps(text2image_result, ensure_ascii=False, indent=4) | ||
|
||
if not text2image_result: | ||
return self.create_text_message("getimg.ai request failed.") | ||
|
||
return self.create_text_message(text2image_result) |
167 changes: 167 additions & 0 deletions
167
api/core/tools/provider/builtin/getimgai/tools/text2image.yaml
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,167 @@ | ||
identity: | ||
name: text2image | ||
author: Matri Qi | ||
label: | ||
en_US: text2image | ||
icon: icon.svg | ||
description: | ||
human: | ||
en_US: Generate image via getimg.ai. | ||
llm: This tool is used to generate image from prompt or image via https://getimg.ai. | ||
parameters: | ||
- name: prompt | ||
type: string | ||
required: true | ||
label: | ||
en_US: prompt | ||
human_description: | ||
en_US: The text prompt used to generate the image. The getimg.aier will generate an image based on this prompt. | ||
llm_description: this prompt text will be used to generate image. | ||
form: llm | ||
- name: mode | ||
type: select | ||
required: false | ||
label: | ||
en_US: mode | ||
human_description: | ||
en_US: The getimg.ai mode to use. The mode determines the endpoint used to generate the image. | ||
form: form | ||
options: | ||
- value: "essential-v2" | ||
label: | ||
en_US: essential-v2 | ||
- value: stable-diffusion-xl | ||
label: | ||
en_US: stable-diffusion-xl | ||
- value: stable-diffusion | ||
label: | ||
en_US: stable-diffusion | ||
- value: latent-consistency | ||
label: | ||
en_US: latent-consistency | ||
- name: style | ||
type: select | ||
required: false | ||
label: | ||
en_US: style | ||
human_description: | ||
en_US: The style preset to use. The style preset guides the generation towards a particular style. It's just efficient for `Essential V2` mode. | ||
form: form | ||
options: | ||
- value: photorealism | ||
label: | ||
en_US: photorealism | ||
- value: anime | ||
label: | ||
en_US: anime | ||
- value: art | ||
label: | ||
en_US: art | ||
- name: aspect_ratio | ||
type: select | ||
required: false | ||
label: | ||
en_US: "aspect ratio" | ||
human_description: | ||
en_US: The aspect ratio of the generated image. It's just efficient for `Essential V2` mode. | ||
form: form | ||
options: | ||
- value: "1:1" | ||
label: | ||
en_US: "1:1" | ||
- value: "4:5" | ||
label: | ||
en_US: "4:5" | ||
- value: "5:4" | ||
label: | ||
en_US: "5:4" | ||
- value: "2:3" | ||
label: | ||
en_US: "2:3" | ||
- value: "3:2" | ||
label: | ||
en_US: "3:2" | ||
- value: "4:7" | ||
label: | ||
en_US: "4:7" | ||
- value: "7:4" | ||
label: | ||
en_US: "7:4" | ||
- name: output_format | ||
type: select | ||
required: false | ||
label: | ||
en_US: "output format" | ||
human_description: | ||
en_US: The file format of the generated image. | ||
form: form | ||
options: | ||
- value: jpeg | ||
label: | ||
en_US: jpeg | ||
- value: png | ||
label: | ||
en_US: png | ||
- name: response_format | ||
type: select | ||
required: false | ||
label: | ||
en_US: "response format" | ||
human_description: | ||
en_US: The format in which the generated images are returned. Must be one of url or b64. URLs are only valid for 1 hour after the image has been generated. | ||
form: form | ||
options: | ||
- value: url | ||
label: | ||
en_US: url | ||
- value: b64 | ||
label: | ||
en_US: b64 | ||
- name: model | ||
type: string | ||
required: false | ||
label: | ||
en_US: model | ||
human_description: | ||
en_US: Model ID supported by this pipeline and family. It's just efficient for `Stable Diffusion XL`, `Stable Diffusion`, `Latent Consistency` mode. | ||
form: form | ||
- name: negative_prompt | ||
type: string | ||
required: false | ||
label: | ||
en_US: negative prompt | ||
human_description: | ||
en_US: Text input that will not guide the image generation. It's just efficient for `Stable Diffusion XL`, `Stable Diffusion`, `Latent Consistency` mode. | ||
form: form | ||
- name: prompt_2 | ||
type: string | ||
required: false | ||
label: | ||
en_US: prompt2 | ||
human_description: | ||
en_US: Prompt sent to second tokenizer and text encoder. If not defined, prompt is used in both text-encoders. It's just efficient for `Stable Diffusion XL` mode. | ||
form: form | ||
- name: width | ||
type: number | ||
required: false | ||
label: | ||
en_US: width | ||
human_description: | ||
en_US: he width of the generated image in pixels. Width needs to be multiple of 64. | ||
form: form | ||
- name: height | ||
type: number | ||
required: false | ||
label: | ||
en_US: height | ||
human_description: | ||
en_US: he height of the generated image in pixels. Height needs to be multiple of 64. | ||
form: form | ||
- name: steps | ||
type: number | ||
required: false | ||
label: | ||
en_US: steps | ||
human_description: | ||
en_US: The number of denoising steps. More steps usually can produce higher quality images, but take more time to generate. It's just efficient for `Stable Diffusion XL`, `Stable Diffusion`, `Latent Consistency` mode. | ||
form: form |