diff --git a/README.md b/README.md index e7ea32b..5c99ff2 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ With the power of pydantic, you can simplify interfacing with the [AI-Horde's suite of APIs](https://github.com/db0/AI-Horde). Whether you want to request your own images, or roll your own worker software, this package may suit your needs for anything horde related. +## General notes +- Certain API models have attributes which may collide with a python builtin, such as `id` or `type`. In these cases, the attribute has a trailing underscore, as in `id_`. Ingested json still will work with the field 'id' (its a alias). + ## AI-Horde `TODO` diff --git a/examples/ai_horde_api_client.example.py b/examples/ai_horde_api_client.example.py new file mode 100644 index 0000000..3e39bd6 --- /dev/null +++ b/examples/ai_horde_api_client.example.py @@ -0,0 +1,34 @@ +from horde_sdk.ai_horde_api import AIHordeAPIClient +from horde_sdk.ai_horde_api.apimodels import ImageGenerateAsyncRequest +from horde_sdk.generic_api import RequestErrorResponse + + +def do_generate_check(ai_horde_api_client: AIHordeAPIClient) -> None: + pass + + +def main() -> None: + """Just a proof of concept - but several other pieces of functionality exist.""" + + ai_horde_api_client = AIHordeAPIClient() + + image_generate_async_request = ImageGenerateAsyncRequest( + apikey="0000000000", + prompt="A cat in a hat", + models=["Deliberate"], + ) + + response = ai_horde_api_client.submit_request( + image_generate_async_request, + image_generate_async_request.get_success_response_type(), + ) + + if isinstance(response, RequestErrorResponse): + print(f"Error: {response.message}") + return + + print(f"Job ID: {response.id_}") + + +if __name__ == "__main__": + main() diff --git a/examples/async_ai_horde_api_client_example.py b/examples/async_ai_horde_api_client_example.py new file mode 100644 index 0000000..6f4e4da --- /dev/null +++ b/examples/async_ai_horde_api_client_example.py @@ -0,0 +1,47 @@ +from __future__ import annotations + +import asyncio + +from horde_sdk.ai_horde_api import AIHordeAPIClient +from horde_sdk.ai_horde_api.apimodels import ImageGenerateAsyncRequest +from horde_sdk.generic_api import RequestErrorResponse + + +async def main() -> None: + print("Starting...") + ai_horde_api_client = AIHordeAPIClient() + + image_generate_async_request = ImageGenerateAsyncRequest( + apikey="0000000000", + prompt="A cat in a hat", + models=["Deliberate"], + ) + + response = await ai_horde_api_client.async_submit_request( + image_generate_async_request, + image_generate_async_request.get_success_response_type(), + ) + + if isinstance(response, RequestErrorResponse): + print(f"Error: {response.message}") + return + + # Keep making ImageGenerateCheckRequests until the job is done. + while True: + check_response = await ai_horde_api_client.async_get_generate_check( + apikey="0000000000", + generation_id=response.id_, + ) + + if isinstance(check_response, RequestErrorResponse): + print(f"Error: {check_response.message}") + return + + if check_response.done: + break + + await asyncio.sleep(5) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/example.py b/examples/ratings_api_client_example.py similarity index 50% rename from example.py rename to examples/ratings_api_client_example.py index 2f382ee..817a6cd 100644 --- a/example.py +++ b/examples/ratings_api_client_example.py @@ -1,6 +1,7 @@ """Short examples of how to use.""" import argparse +import os import pydantic from horde_sdk.ratings_api import ( @@ -12,25 +13,32 @@ UserValidateResponseRecord, ) +# See also in horde_sdk.ratings_api: +# UserCheckRequest, +# UserCheckResponse, +# UserRatingsRequest, +# UserRatingsResponse, + def main() -> None: """Just a proof of concept - but several other pieces of functionality exist.""" argParser = argparse.ArgumentParser() - argParser.add_argument("-k", "--key", required=True, help="Your horde API key.") - argParser.add_argument("-f", "--file", required=True, help="The file to write the response to.") + argParser.add_argument("-k", "--key", required=False, help="Your horde API key.") + argParser.add_argument("-o", "--output_file", required=True, help="The file to write the response to.") argParser.add_argument("-u", "--user_id", required=True, help="The user_id (number only) to test against.") args = argParser.parse_args() - # apiKey = os.environ.get("HORDE_API_KEY") + env_apikey = os.environ.get("HORDE_API_KEY") - # class args: - # key = CHANGE_ME - # user_id = "6572" - # file = "out.json" + if args.key is None and env_apikey is None: + print( + "You must provide an API key either via the -k/--key argument or the HORDE_API_KEY environment variable.", + ) + exit(1) - ratingsAPIClient = RatingsAPIClient() - userValidateRequest = UserValidateRequest( + ratings_api_client = RatingsAPIClient() + user_validate_request = UserValidateRequest( apikey=args.key, user_id=args.user_id, format=SelectableReturnFormats.json, @@ -39,16 +47,28 @@ def main() -> None: min_ratings=0, ) - response: pydantic.BaseModel = ratingsAPIClient.submit_request( - userValidateRequest, - userValidateRequest.get_success_response_type(), + print("Request URL:") + print(user_validate_request.get_endpoint_url()) + print() + print("Request Body JSON:") + print(user_validate_request.model_dump_json()) + + response: pydantic.BaseModel = ratings_api_client.submit_request( + api_request=user_validate_request, + # Note that the type hint is accurate on the return type of this `get_success_response_type()` + expected_response_type=user_validate_request.get_success_response_type(), ) if not isinstance(response, UserValidateResponse): raise Exception("The response type doesn't match expected one!") + print("Response JSON:") responseJson = response.model_dump_json() - print(responseJson) + print() + print("Response pydantic representation:") + print(responseJson) + print() + print("Select details from the response:") print(f"{response.total=}") first_rating: UserValidateResponseRecord = response.ratings[0] @@ -58,7 +78,7 @@ def main() -> None: print(f"{first_rating.average=}") print(f"{first_rating.times_rated=}") - with open(args.file, "w") as fileOutHandle: + with open(args.output_file, "w") as fileOutHandle: fileOutHandle.write(first_rating.model_dump_json()) diff --git a/src/horde_sdk/ai_horde_api/__init__.py b/src/horde_sdk/ai_horde_api/__init__.py index e69de29..03c42df 100644 --- a/src/horde_sdk/ai_horde_api/__init__.py +++ b/src/horde_sdk/ai_horde_api/__init__.py @@ -0,0 +1,25 @@ +from horde_sdk.ai_horde_api.ai_horde_client import ( + AIHordeAPIClient, +) +from horde_sdk.ai_horde_api.consts import ( + ALCHEMY_FORMS, + GENERATION_STATE, + KNOWN_SAMPLERS, + KNOWN_SOURCE_PROCESSING, + WORKER_TYPE, +) +from horde_sdk.ai_horde_api.endpoints import ( + AI_HORDE_BASE_URL, + AI_HORDE_API_URL_Literals, +) + +__all__ = [ + "AIHordeAPIClient", + "AI_HORDE_BASE_URL", + "AI_HORDE_API_URL_Literals", + "ALCHEMY_FORMS", + "GENERATION_STATE", + "KNOWN_SAMPLERS", + "KNOWN_SOURCE_PROCESSING", + "WORKER_TYPE", +] diff --git a/src/horde_sdk/ai_horde_api/ai_horde_client.py b/src/horde_sdk/ai_horde_api/ai_horde_client.py index da5a432..895a619 100644 --- a/src/horde_sdk/ai_horde_api/ai_horde_client.py +++ b/src/horde_sdk/ai_horde_api/ai_horde_client.py @@ -4,9 +4,10 @@ from loguru import logger from horde_sdk.ai_horde_api.apimodels import ( - CancelImageGenerateRequest, - ImageGenerateAsyncRequest, - ImageGenerateAsyncResponse, + DeleteImageGenerateRequest, + ImageGenerateCheckRequest, + ImageGenerateCheckResponse, + ImageGenerateStatusRequest, ImageGenerateStatusResponse, ) from horde_sdk.ai_horde_api.endpoints import AI_HORDE_BASE_URL @@ -47,33 +48,100 @@ def _handle_api_error(self, error_response: RequestErrorResponse, endpoint_url: logger.error(f"Endpoint: {endpoint_url}") logger.error(f"Message: {error_response.message}") - def generate_image_async( + def get_generate_check( self, - api_request: ImageGenerateAsyncRequest, - ) -> ImageGenerateAsyncResponse | RequestErrorResponse: - """Submit a request to the AI-Horde API to generate an image asynchronously. + apikey: str, + generation_id: GenerationID | str, + ) -> ImageGenerateCheckResponse | RequestErrorResponse: + """Check if a pending image request has finished generating from the AI-Horde API, and return + the status of it. Not to be confused with `get_generate_status` which returns the images too. + + Args: + apikey (str): The API key to use for authentication. + generation_id (GenerationID | str): The ID of the request to check. - This is a call to the `/v2/generate/async` endpoint. + Returns: + ImageGenerateCheckResponse | RequestErrorResponse: The response from the API. + """ """""" + api_request = ImageGenerateCheckRequest(id=generation_id) + + api_response = self.submit_request(api_request, api_request.get_success_response_type()) + if isinstance(api_response, RequestErrorResponse): + self._handle_api_error(api_response, api_request.get_endpoint_url()) + + return api_response + + async def async_get_generate_check( + self, + apikey: str, + generation_id: GenerationID | str, + ) -> ImageGenerateCheckResponse | RequestErrorResponse: + """Asynchronously check if a pending image request has finished generating from the AI-Horde API, and return + the status of it. Not to be confused with `get_generate_status` which returns the images too. Args: - api_request (ImageGenerateAsyncRequest): The request to submit. + apikey (str): The API key to use for authentication. + generation_id (GenerationID | str): The ID of the request to check. + + Returns: + ImageGenerateCheckResponse | RequestErrorResponse: The response from the API. + """ + + api_request = ImageGenerateCheckRequest(id=generation_id) + + api_response = await self.async_submit_request(api_request, api_request.get_success_response_type()) + if isinstance(api_response, RequestErrorResponse): + self._handle_api_error(api_response, api_request.get_endpoint_url()) + + return api_response + + def get_generate_status( + self, + apikey: str, + generation_id: GenerationID | str, + ) -> ImageGenerateStatusResponse | RequestErrorResponse: + """Get the status and any generated images for a pending image request from the AI-Horde API. - Raises: - RuntimeError: If the response type is not ImageGenerateAsyncResponse. + *Do not use this method more often than is necessary.* The AI-Horde API will rate limit you if you do. + Use `get_generate_check` instead to check the status of a pending image request. + Args: + apikey (str): The API key to use for authentication. + generation_id (GenerationID): The ID of the request to check. Returns: - ImageGenerateAsyncResponse | RequestErrorResponse: The response from the API. + ImageGenerateStatusResponse | RequestErrorResponse: The response from the API. """ + api_request = ImageGenerateStatusRequest(id=generation_id) + api_response = self.submit_request(api_request, api_request.get_success_response_type()) if isinstance(api_response, RequestErrorResponse): self._handle_api_error(api_response, api_request.get_endpoint_url()) return api_response - if not isinstance(api_response, ImageGenerateAsyncResponse): - logger.error("Failed to generate an image asynchronously.") - logger.error(f"Unexpected response type: {type(api_response)}") - raise RuntimeError( - f"Unexpected response type. Expected ImageGenerateAsyncResponse, got {type(api_response)}", - ) + + return api_response + + async def async_get_generate_status( + self, + apikey: str, + generation_id: GenerationID | str, + ) -> ImageGenerateStatusResponse | RequestErrorResponse: + """Asynchronously get the status and any generated images for a pending image request from the AI-Horde API. + + *Do not use this method more often than is necessary.* The AI-Horde API will rate limit you if you do. + Use `get_generate_check` instead to check the status of a pending image request. + + Args: + apikey (str): The API key to use for authentication. + generation_id (GenerationID): The ID of the request to check. + Returns: + ImageGenerateStatusResponse | RequestErrorResponse: The response from the API. + """ + api_request = ImageGenerateStatusRequest(id=generation_id) + + api_response = await self.async_submit_request(api_request, api_request.get_success_response_type()) + if isinstance(api_response, RequestErrorResponse): + self._handle_api_error(api_response, api_request.get_endpoint_url()) + return api_response return api_response @@ -87,7 +155,7 @@ def delete_pending_image( Args: generation_id (GenerationID): The ID of the request to delete. """ - api_request = CancelImageGenerateRequest(id=generation_id, apikey=apikey) + api_request = DeleteImageGenerateRequest(id=generation_id, apikey=apikey) api_response = self.submit_request(api_request, api_request.get_success_response_type()) if isinstance(api_response, RequestErrorResponse): @@ -95,3 +163,17 @@ def delete_pending_image( return api_response return api_response + + async def async_delete_pending_image( + self, + apikey: str, + generation_id: GenerationID | str, + ) -> ImageGenerateStatusResponse | RequestErrorResponse: + api_request = DeleteImageGenerateRequest(id=generation_id, apikey=apikey) + + api_response = await self.async_submit_request(api_request, api_request.get_success_response_type()) + if isinstance(api_response, RequestErrorResponse): + self._handle_api_error(api_response, api_request.get_endpoint_url()) + return api_response + + return api_response diff --git a/src/horde_sdk/ai_horde_api/apimodels/__init__.py b/src/horde_sdk/ai_horde_api/apimodels/__init__.py index a160e0a..784e05f 100644 --- a/src/horde_sdk/ai_horde_api/apimodels/__init__.py +++ b/src/horde_sdk/ai_horde_api/apimodels/__init__.py @@ -3,7 +3,7 @@ from horde_sdk.ai_horde_api.apimodels.generate._check import ImageGenerateCheckRequest, ImageGenerateCheckResponse from horde_sdk.ai_horde_api.apimodels.generate._pop import ImageGenerateJobPopRequest, ImageGenerateJobResponse from horde_sdk.ai_horde_api.apimodels.generate._status import ( - CancelImageGenerateRequest, + DeleteImageGenerateRequest, ImageGenerateStatusRequest, ImageGenerateStatusResponse, ) @@ -22,7 +22,7 @@ "ImageGenerateJobResponse", "ImageGenerateStatusRequest", "ImageGenerateStatusResponse", - "CancelImageGenerateRequest", + "DeleteImageGenerateRequest", "StatsImageModels", "StatsModelsResponse", "ImageGenerationJobSubmitRequest", diff --git a/src/horde_sdk/ai_horde_api/apimodels/_stats.py b/src/horde_sdk/ai_horde_api/apimodels/_stats.py index 4bf7229..bcccf30 100644 --- a/src/horde_sdk/ai_horde_api/apimodels/_stats.py +++ b/src/horde_sdk/ai_horde_api/apimodels/_stats.py @@ -1,6 +1,6 @@ from typing_extensions import override -from horde_sdk.ai_horde_api.apimodels._base import BaseAIHordeRequest +from horde_sdk.ai_horde_api.apimodels.base import BaseAIHordeRequest from horde_sdk.ai_horde_api.endpoints import AI_HORDE_API_URL_Literals from horde_sdk.consts import HTTPMethod from horde_sdk.generic_api.apimodels import BaseResponse diff --git a/src/horde_sdk/ai_horde_api/apimodels/_base.py b/src/horde_sdk/ai_horde_api/apimodels/base.py similarity index 83% rename from src/horde_sdk/ai_horde_api/apimodels/_base.py rename to src/horde_sdk/ai_horde_api/apimodels/base.py index 8a0c8ef..22b3e1c 100644 --- a/src/horde_sdk/ai_horde_api/apimodels/_base.py +++ b/src/horde_sdk/ai_horde_api/apimodels/base.py @@ -1,7 +1,7 @@ from pydantic import BaseModel, Field, field_validator from typing_extensions import override -from horde_sdk.ai_horde_api.consts import KNOWN_SAMPLERS, KNOWN_SOURCE_PROCESSING +from horde_sdk.ai_horde_api.consts import KNOWN_SAMPLERS from horde_sdk.ai_horde_api.endpoints import AI_HORDE_BASE_URL from horde_sdk.ai_horde_api.fields import GenerationID, WorkerID from horde_sdk.generic_api.apimodels import BaseRequest @@ -15,15 +15,15 @@ def get_api_url(cls) -> str: return AI_HORDE_BASE_URL -class BaseImageGenerateJobRequest(BaseModel): - """Mix-in class for data relating to image generation jobs.""" +class BaseImageJobRequest(BaseModel): + """Base class for data relating to image generation jobs.""" - id: str | GenerationID # noqa: A003 + id_: str | GenerationID = Field(alias="id") """The UUID for this job.""" class BaseWorkerRequest(BaseModel): - """Mix-in class for data relating to worker requests.""" + """Base class for data relating to worker requests.""" worker_id: str | WorkerID """The UUID of the worker in question for this request.""" @@ -86,11 +86,3 @@ def sampler_name_must_be_known(cls, v: str | KNOWN_SAMPLERS) -> str | KNOWN_SAMP def seed_to_int_if_str(cls, v: str | int) -> str | int: """Ensure that the seed is an integer. If it is a string, convert it to an integer.""" return str(seed_to_int(v)) - - -class BaseImageGenerateImg2Img(BaseModel): - """Mix-in class for data relating to img2img generation.""" - - source_image: str | None = None - source_processing: KNOWN_SOURCE_PROCESSING = KNOWN_SOURCE_PROCESSING.txt2img - source_mask: str | None = None diff --git a/src/horde_sdk/ai_horde_api/apimodels/generate/_async.py b/src/horde_sdk/ai_horde_api/apimodels/generate/_async.py index e79541a..f114f33 100644 --- a/src/horde_sdk/ai_horde_api/apimodels/generate/_async.py +++ b/src/horde_sdk/ai_horde_api/apimodels/generate/_async.py @@ -1,11 +1,12 @@ from pydantic import Field, model_validator from typing_extensions import override -from horde_sdk.ai_horde_api.apimodels._base import ( +from horde_sdk.ai_horde_api.apimodels.base import ( BaseAIHordeRequest, - BaseImageGenerateImg2Img, BaseImageGenerateParam, ) +from horde_sdk.ai_horde_api.apimodels.generate._status import DeleteImageGenerateRequest +from horde_sdk.ai_horde_api.consts import KNOWN_SOURCE_PROCESSING from horde_sdk.ai_horde_api.endpoints import AI_HORDE_API_URL_Literals from horde_sdk.ai_horde_api.fields import GenerationID from horde_sdk.consts import HTTPMethod, HTTPStatusCode @@ -18,7 +19,7 @@ class ImageGenerateAsyncResponse(BaseResponse): v2 API Model: `RequestAsync` """ - id: str | GenerationID # noqa: A003 + id_: str | GenerationID = Field(alias="id") """The UUID for this image generation.""" kudos: float message: str | None = None @@ -36,7 +37,6 @@ class ImageGenerationInputPayload(BaseImageGenerateParam): class ImageGenerateAsyncRequest( BaseAIHordeRequest, BaseRequestAuthenticated, - BaseImageGenerateImg2Img, BaseRequestWorkerDriven, ): """Represents the data needed to make a request to the `/v2/generate/async` endpoint. @@ -56,6 +56,10 @@ class ImageGenerateAsyncRequest( replacement_filter: bool = True + source_image: str | None = None + source_processing: KNOWN_SOURCE_PROCESSING = KNOWN_SOURCE_PROCESSING.txt2img + source_mask: str | None = None + @model_validator(mode="before") def validate_censor_nsfw(cls, values: dict) -> dict: if values.get("censor_nsfw", None) and values.get("nsfw", None): @@ -88,3 +92,11 @@ def get_success_status_response_pairs(cls) -> dict[HTTPStatusCode, type[BaseResp return { HTTPStatusCode.ACCEPTED: cls.get_success_response_type(), } + + @override + @classmethod + def is_recovery_enabled(cls) -> bool: + return True + + def get_recovery_request_type(self) -> type[DeleteImageGenerateRequest]: + return DeleteImageGenerateRequest diff --git a/src/horde_sdk/ai_horde_api/apimodels/generate/_check.py b/src/horde_sdk/ai_horde_api/apimodels/generate/_check.py index 3c16462..c9ea418 100644 --- a/src/horde_sdk/ai_horde_api/apimodels/generate/_check.py +++ b/src/horde_sdk/ai_horde_api/apimodels/generate/_check.py @@ -1,6 +1,6 @@ from typing_extensions import override -from horde_sdk.ai_horde_api.apimodels._base import BaseAIHordeRequest, BaseImageGenerateJobRequest +from horde_sdk.ai_horde_api.apimodels.base import BaseAIHordeRequest, BaseImageJobRequest from horde_sdk.ai_horde_api.endpoints import AI_HORDE_API_URL_Literals from horde_sdk.consts import HTTPMethod from horde_sdk.generic_api.apimodels import BaseResponse @@ -39,7 +39,7 @@ def get_api_model_name(cls) -> str | None: return "RequestStatusCheck" -class ImageGenerateCheckRequest(BaseAIHordeRequest, BaseImageGenerateJobRequest): +class ImageGenerateCheckRequest(BaseAIHordeRequest, BaseImageJobRequest): """Represents a GET request to the `/v2/generate/check/{id}` endpoint.""" @override diff --git a/src/horde_sdk/ai_horde_api/apimodels/generate/_pop.py b/src/horde_sdk/ai_horde_api/apimodels/generate/_pop.py index 5bbbe9c..6333ba3 100644 --- a/src/horde_sdk/ai_horde_api/apimodels/generate/_pop.py +++ b/src/horde_sdk/ai_horde_api/apimodels/generate/_pop.py @@ -2,7 +2,7 @@ from pydantic import Field, field_validator from typing_extensions import override -from horde_sdk.ai_horde_api.apimodels._base import BaseAIHordeRequest, BaseImageGenerateParam +from horde_sdk.ai_horde_api.apimodels.base import BaseAIHordeRequest, BaseImageGenerateParam from horde_sdk.ai_horde_api.consts import KNOWN_SOURCE_PROCESSING from horde_sdk.ai_horde_api.endpoints import AI_HORDE_API_URL_Literals from horde_sdk.ai_horde_api.fields import GenerationID diff --git a/src/horde_sdk/ai_horde_api/apimodels/generate/_status.py b/src/horde_sdk/ai_horde_api/apimodels/generate/_status.py index 649d8ee..bfd4514 100644 --- a/src/horde_sdk/ai_horde_api/apimodels/generate/_status.py +++ b/src/horde_sdk/ai_horde_api/apimodels/generate/_status.py @@ -1,7 +1,7 @@ from pydantic import BaseModel, Field from typing_extensions import override -from horde_sdk.ai_horde_api.apimodels._base import BaseAIHordeRequest, BaseImageGenerateJobRequest +from horde_sdk.ai_horde_api.apimodels.base import BaseAIHordeRequest, BaseImageJobRequest from horde_sdk.ai_horde_api.apimodels.generate._check import ImageGenerateCheckResponse from horde_sdk.ai_horde_api.consts import GENERATION_STATE from horde_sdk.ai_horde_api.endpoints import AI_HORDE_API_URL_Literals @@ -10,10 +10,6 @@ from horde_sdk.generic_api.apimodels import BaseRequestAuthenticated -class ImageGenerateStatusRequest(BaseAIHordeRequest, BaseImageGenerateJobRequest): - """Represents a GET request to the `/v2/generate/status/{id}` endpoint.""" - - class ImageGeneration(BaseModel): """Represents the individual image generation responses in a ImageGenerateStatusResponse. @@ -55,10 +51,10 @@ def get_api_model_name(cls) -> str | None: return "RequestStatusStable" -class CancelImageGenerateRequest( +class DeleteImageGenerateRequest( BaseAIHordeRequest, BaseRequestAuthenticated, - BaseImageGenerateJobRequest, + BaseImageJobRequest, ): """Represents a DELETE request to the `/v2/generate/status/{id}` endpoint.""" @@ -81,3 +77,27 @@ def get_endpoint_subpath() -> str: @staticmethod def get_success_response_type() -> type[ImageGenerateStatusResponse]: return ImageGenerateStatusResponse + + +class ImageGenerateStatusRequest(BaseAIHordeRequest, BaseImageJobRequest): + """Represents a GET request to the `/v2/generate/status/{id}` endpoint.""" + + @override + @classmethod + def get_api_model_name(cls) -> str | None: + return None + + @override + @classmethod + def get_http_method(cls) -> HTTPMethod: + return HTTPMethod.GET + + @override + @staticmethod + def get_endpoint_subpath() -> str: + return AI_HORDE_API_URL_Literals.v2_generate_status + + @override + @staticmethod + def get_success_response_type() -> type[ImageGenerateStatusResponse]: + return ImageGenerateStatusResponse diff --git a/src/horde_sdk/ai_horde_api/apimodels/generate/_submit.py b/src/horde_sdk/ai_horde_api/apimodels/generate/_submit.py index 869023d..ac845cd 100644 --- a/src/horde_sdk/ai_horde_api/apimodels/generate/_submit.py +++ b/src/horde_sdk/ai_horde_api/apimodels/generate/_submit.py @@ -1,6 +1,6 @@ from typing_extensions import override -from horde_sdk.ai_horde_api.apimodels._base import BaseAIHordeRequest +from horde_sdk.ai_horde_api.apimodels.base import BaseAIHordeRequest from horde_sdk.ai_horde_api.endpoints import AI_HORDE_API_URL_Literals from horde_sdk.ai_horde_api.fields import GenerationID from horde_sdk.consts import HTTPMethod diff --git a/src/horde_sdk/ai_horde_api/apimodels/workers/_workers_all.py b/src/horde_sdk/ai_horde_api/apimodels/workers/_workers_all.py index 558ab91..99d977f 100644 --- a/src/horde_sdk/ai_horde_api/apimodels/workers/_workers_all.py +++ b/src/horde_sdk/ai_horde_api/apimodels/workers/_workers_all.py @@ -1,4 +1,4 @@ -from horde_sdk.ai_horde_api.apimodels._base import BaseAIHordeRequest +from horde_sdk.ai_horde_api.apimodels.base import BaseAIHordeRequest from horde_sdk.ai_horde_api.consts import WORKER_TYPE from horde_sdk.ai_horde_api.endpoints import AI_HORDE_API_URL_Literals from horde_sdk.ai_horde_api.fields import TeamID, WorkerID diff --git a/src/horde_sdk/ai_horde_api/consts.py b/src/horde_sdk/ai_horde_api/consts.py index 7c25e46..9f67438 100644 --- a/src/horde_sdk/ai_horde_api/consts.py +++ b/src/horde_sdk/ai_horde_api/consts.py @@ -37,3 +37,13 @@ class WORKER_TYPE(StrEnum): image = auto() text = auto() interrogation = auto() + # alchemist = auto() # TODO + + +class ALCHEMY_FORMS(StrEnum): + """Forms for alchemist type workers""" + + nsfw = auto() + caption = auto() + interrogation = auto() + post_process = auto() diff --git a/src/horde_sdk/ai_horde_api/endpoints.py b/src/horde_sdk/ai_horde_api/endpoints.py index 8798a1c..c44f47b 100644 --- a/src/horde_sdk/ai_horde_api/endpoints.py +++ b/src/horde_sdk/ai_horde_api/endpoints.py @@ -4,6 +4,7 @@ from horde_sdk.generic_api.endpoints import url_with_path +# TODO: Defer setting this? AI_HORDE_BASE_URL = "https://aihorde.net/api/" if os.environ.get("HORDE_URL", None): diff --git a/src/horde_sdk/ai_horde_api/metadata.py b/src/horde_sdk/ai_horde_api/metadata.py index 82eb9b7..f05b5ba 100644 --- a/src/horde_sdk/ai_horde_api/metadata.py +++ b/src/horde_sdk/ai_horde_api/metadata.py @@ -4,7 +4,7 @@ class AIHordePathData(GenericPathFields): # TODO docstrings - id = "id" # noqa: A003 + id_ = "id" """A request GUID as a str.""" user_id = "user_id" filter_id = "filter_id" diff --git a/src/horde_sdk/generic_api/__init__.py b/src/horde_sdk/generic_api/__init__.py index ba02948..86105d0 100644 --- a/src/horde_sdk/generic_api/__init__.py +++ b/src/horde_sdk/generic_api/__init__.py @@ -8,9 +8,13 @@ ) -from horde_sdk.generic_api._error import RequestErrorResponse -from horde_sdk.generic_api.apimodels import BaseRequest, BaseRequestAuthenticated, BaseRequestUserSpecific -from horde_sdk.generic_api.generic_client import GenericHordeAPIClient +from horde_sdk.generic_api.apimodels import ( + BaseRequest, + BaseRequestAuthenticated, + BaseRequestUserSpecific, + RequestErrorResponse, +) +from horde_sdk.generic_api.generic_client import GenericHordeAPIClient, HordeRequest, HordeResponse __all__ = [ @@ -23,4 +27,6 @@ "GenericHeaderFields", "GenericPathFields", "GenericQueryFields", + "HordeRequest", + "HordeResponse", ] diff --git a/src/horde_sdk/generic_api/_error.py b/src/horde_sdk/generic_api/_error.py deleted file mode 100644 index a872ab6..0000000 --- a/src/horde_sdk/generic_api/_error.py +++ /dev/null @@ -1,20 +0,0 @@ -from typing_extensions import override - -from horde_sdk.generic_api.apimodels import BaseResponse - - -class RequestErrorResponse(BaseResponse): - """The catch all error response for any request to any Horde API. - - v2 API Model: `RequestError` - """ - - message: str = "" - - object_data: object = None - """This is a catch all for any additional data that may be returned by the API relevant to the error.""" - - @override - @classmethod - def get_api_model_name(cls) -> str | None: - return "RequestError" diff --git a/src/horde_sdk/generic_api/apimodels.py b/src/horde_sdk/generic_api/apimodels.py index 834df93..389e830 100644 --- a/src/horde_sdk/generic_api/apimodels.py +++ b/src/horde_sdk/generic_api/apimodels.py @@ -1,4 +1,5 @@ """API data model bases applicable across all (or many) horde APIs.""" +from __future__ import annotations import abc import json @@ -98,6 +99,23 @@ def to_json_horde_sdk_safe(self) -> str: return super().to_json_horde_sdk_safe() +class RequestErrorResponse(BaseResponse): + """The catch all error response for any request to any Horde API. + + v2 API Model: `RequestError` + """ + + message: str = "" + + object_data: object = None + """This is a catch all for any additional data that may be returned by the API relevant to the error.""" + + @override + @classmethod + def get_api_model_name(cls) -> str | None: + return "RequestError" + + class BaseRequest(HordeAPIMessage): """Represents any request to any Horde API.""" @@ -150,6 +168,27 @@ def get_header_fields(cls) -> list[str]: """ return [] + @classmethod + def is_recovery_enabled(cls) -> bool: + """Return whether this request should attempt to recover from during a client failure. + + This is used in for context management. + """ + return False + + def get_recovery_request_type(self) -> type[BaseRequest]: + """Return an instance of the request that should be submitted to clean up after a client failure.""" + if self.is_recovery_enabled(): + raise NotImplementedError( + ( + "This request is configured to support recovery with `is_recovery_enabled`, but does not " + "implement `get_recovery_request`." + ), + ) + raise NotImplementedError( + "This request does not support recovery. Use `.is_recovery_enabled` to determine this.", + ) + class BaseRequestAuthenticated(BaseModel): """Mix-in class to describe an endpoint which may require authentication.""" @@ -183,3 +222,15 @@ class BaseRequestWorkerDriven(BaseModel): models: list[str] dry_run: bool = False + + +__all__ = [ + "HordeAPIModel", + "HordeAPIMessage", + "BaseResponse", + "BaseRequest", + "BaseRequestAuthenticated", + "BaseRequestUserSpecific", + "BaseRequestWorkerDriven", + "RequestErrorResponse", +] diff --git a/src/horde_sdk/generic_api/generic_client.py b/src/horde_sdk/generic_api/generic_client.py index 9b6e272..39b5c3d 100644 --- a/src/horde_sdk/generic_api/generic_client.py +++ b/src/horde_sdk/generic_api/generic_client.py @@ -1,9 +1,11 @@ """The API client which can perform arbitrary horde API requests.""" -from typing import TypeVar +from typing import Generic, TypeVar +import aiohttp import requests from pydantic import BaseModel, ValidationError +from strenum import StrEnum from horde_sdk.generic_api import ( GenericAcceptTypes, @@ -11,8 +13,14 @@ GenericPathFields, GenericQueryFields, ) -from horde_sdk.generic_api._error import RequestErrorResponse -from horde_sdk.generic_api.apimodels import BaseRequest, BaseResponse +from horde_sdk.generic_api.apimodels import ( + BaseRequest, + BaseRequestAuthenticated, + BaseRequestUserSpecific, + BaseRequestWorkerDriven, + BaseResponse, + RequestErrorResponse, +) HordeRequest = TypeVar("HordeRequest", bound=BaseRequest) HordeResponse = TypeVar("HordeResponse", bound=BaseResponse) @@ -37,14 +45,14 @@ class GenericHordeAPIClient: You can use the friendly, typed functions, or if you prefer more control, you can use the `submit_request` method. """ - _header_data_keys: list[str] + _header_data_keys: type[GenericHeaderFields] = GenericHeaderFields """A list of all fields which would appear in the API request header.""" - _path_data_keys: list[str] + _path_data_keys: type[GenericPathFields] = GenericPathFields """A list of all fields which would appear in any API action path (appearing before the '?' as part of the URL)""" - _query_data_keys: list[str] + _query_data_keys: type[GenericQueryFields] = GenericQueryFields """A list of all fields which would appear in any API action query (appearing after the '?')""" - _accept_types: list[str] + _accept_types: type[GenericAcceptTypes] = GenericAcceptTypes """A list of all valid values for the header key 'accept'.""" def __init__( @@ -82,10 +90,10 @@ def __init__( if not issubclass(query_fields, GenericQueryFields): raise TypeError("`queryData` must be of type `GenericQueryData` or a subclass of it!") - self._header_data_keys = list(header_fields.__members__.keys()) - self._path_data_keys = list(path_fields.__members__.keys()) - self._accept_types = list(accept_types.__members__.keys()) - self._query_data_keys = list(query_fields.__members__.keys()) + self._header_data_keys = header_fields + self._path_data_keys = path_fields + self._query_data_keys = query_fields + self._accept_types = accept_types def _validate_and_prepare_request(self, api_request: BaseRequest) -> _ParsedRequest: """Validates the given `api_request` and returns a `_ParsedRequest` instance with the data to be sent. @@ -96,49 +104,55 @@ def _validate_and_prepare_request(self, api_request: BaseRequest) -> _ParsedRequ if not issubclass(api_request.__class__, BaseRequest): raise TypeError("`request` must be of type `BaseRequest` or a subclass of it!") - specified_header_keys = [ - attr - for attr in self._header_data_keys - if hasattr(api_request, attr) and getattr(api_request, attr) is not None - ] - specified_path_keys = [ - attr - for attr in self._path_data_keys - if hasattr(api_request, attr) and getattr(api_request, attr) is not None - ] - specified_query_keys = [ - attr - for attr in self._query_data_keys - if hasattr(api_request, attr) and getattr(api_request, attr) is not None - ] - - endpoint_no_query: str = api_request.get_endpoint_url() - - for pathKey in specified_path_keys: - endpoint_no_query = endpoint_no_query.format_map({pathKey: str(getattr(api_request, pathKey))}) - - extra_header_keys = api_request.get_header_fields() - - request_params_dict = {} - request_headers_dict = {} - request_queries_dict = {} - for key, value in api_request.__dict__.items(): - if key in specified_path_keys: + def get_specified_data_keys(data_keys: type[StrEnum], api_request: BaseRequest) -> dict[str, str]: + return { + py_field_name: str(api_field_name) + for py_field_name, api_field_name in data_keys._member_map_.items() + if hasattr(api_request, py_field_name) and getattr(api_request, py_field_name) is not None + } + + specified_headers = get_specified_data_keys(self._header_data_keys, api_request) + specified_paths = get_specified_data_keys(self._path_data_keys, api_request) + specified_queries = get_specified_data_keys(self._query_data_keys, api_request) + + endpoint_url: str = api_request.get_endpoint_url() + + for py_field_name, api_field_name in specified_paths.items(): + # Replace the path key with the value from the request + # IE: /v2/ratings/{id} -> /v2/ratings/123 + endpoint_url = endpoint_url.format_map({api_field_name: str(getattr(api_request, py_field_name))}) + + extra_header_keys: list[str] = api_request.get_header_fields() + + request_params_dict: dict[str, object] = {} + request_headers_dict: dict[str, object] = {} + request_queries_dict: dict[str, object] = {} + + for request_key, request_value in api_request.__dict__.items(): + if request_key in specified_paths: continue - if key in specified_header_keys: - request_headers_dict[key] = value + if request_key in specified_headers: + request_headers_dict[request_key] = request_value continue - if key in extra_header_keys: - request_headers_dict[key] = value - specified_header_keys.append(key) + if request_key in extra_header_keys: + # Remove any trailing underscores from the key as they are used to avoid python keyword conflicts + api_name = request_key if not request_key.endswith("_") else request_key[:-1] + specified_headers[request_key] = api_name + request_headers_dict[request_key] = request_value + continue - if key in specified_query_keys: - request_queries_dict[key] = value + if request_key in specified_queries: + request_queries_dict[request_key] = request_value continue - request_params_dict[key] = value + request_params_dict[request_key] = request_value - all_fields_to_exclude_from_body = set(specified_header_keys + specified_path_keys + specified_query_keys) + all_fields_to_exclude_from_body = set( + list(specified_headers.keys()) + + list(specified_paths.keys()) + + list(specified_queries.keys()) + + extra_header_keys, + ) request_body_data_dict: dict | None = api_request.model_dump( exclude_none=True, exclude_unset=True, @@ -149,7 +163,7 @@ def _validate_and_prepare_request(self, api_request: BaseRequest) -> _ParsedRequ request_body_data_dict = None return _ParsedRequest( - endpoint_no_query=endpoint_no_query, + endpoint_no_query=endpoint_url, request_headers=request_headers_dict, request_queries=request_queries_dict, request_params=request_params_dict, @@ -172,8 +186,10 @@ def _after_request_handling( return RequestErrorResponse(**raw_response_json) raise RuntimeError( - "Received a non-200 response code, but no `message` key was found " - f"in the response: {raw_response_json}", + ( + "Received a non-200 response code, but no `message` key was found " + f"in the response: {raw_response_json}" + ), ) handled_response: HordeResponse | RequestErrorResponse | None = None @@ -199,7 +215,7 @@ def _after_request_handling( def submit_request( self, api_request: BaseRequest, - expected_response: type[HordeResponse], + expected_response_type: type[HordeResponse], ) -> HordeResponse | RequestErrorResponse: """Submit a request to the API and return the response. @@ -218,17 +234,51 @@ def submit_request( """ http_method_name = api_request.get_http_method()._value_.lower() api_client_method = getattr(self, http_method_name) - return api_client_method(api_request, expected_response) + return api_client_method(api_request, expected_response_type) + + async def async_submit_request( + self, + api_request: BaseRequest, + expected_response_type: type[HordeResponse], + ) -> HordeResponse | RequestErrorResponse: + """Submit a request to the API asynchronously and return the response. + + Automatically determines the correct method to call based on calling `.get_http_method()` on the request. + + If you are wondering why `expected_response` is a parameter, it is because the API may return different + responses depending on the payload or other factors. It is up to you to determine which response type you + expect, and pass it in here. + + Args: + api_request (BaseRequest): The request to submit. + expected_response (type[HordeResponse]): The expected response type. + + Returns: + HordeResponse | RequestErrorResponse: The response from the API. + """ + http_method_name = api_request.get_http_method()._value_.lower() + api_client_method = getattr(self, f"async_{http_method_name}") + return await api_client_method(api_request, expected_response_type) def get( self, api_request: BaseRequest, expected_response: type[HordeResponse], ) -> HordeResponse | RequestErrorResponse: - """Perform a GET request to the API.""" + """Perform a GET request to the API. + + Args: + api_request (BaseRequest): The request to submit. + expected_response (type[HordeResponse]): The expected response type. + + Returns: + HordeResponse | RequestErrorResponse: The response from the API. + """ parsed_request = self._validate_and_prepare_request(api_request) if parsed_request.request_body is not None: - raise RuntimeError("GET requests cannot have a body!") + raise RuntimeError( + "GET requests cannot have a body! This probably means you forgot to override `get_header_fields()`", + ) raw_response = requests.get( parsed_request.endpoint_no_query, headers=parsed_request.request_headers, @@ -238,12 +288,51 @@ def get( return self._after_request_handling(api_request, raw_response, expected_response) + async def async_get( + self, + api_request: BaseRequest, + expected_response: type[HordeResponse], + ) -> HordeResponse | RequestErrorResponse: + """Perform a GET request to the API asynchronously. + + Args: + api_request (BaseRequest): The request to submit. + expected_response (type[HordeResponse]): The expected response type. + + Returns: + HordeResponse | RequestErrorResponse: The response from the API. + """ + parsed_request = self._validate_and_prepare_request(api_request) + if parsed_request.request_body is not None: + raise RuntimeError("GET requests cannot have a body!") + + async with ( + aiohttp.ClientSession() as session, + session.get( + parsed_request.endpoint_no_query, + headers=parsed_request.request_headers, + params=parsed_request.request_queries, + allow_redirects=True, + ) as response, + ): + raw_response = await response.json() + + return self._after_request_handling(api_request, raw_response, expected_response) + def post( self, api_request: BaseRequest, expected_response: type[HordeResponse], ) -> HordeResponse | RequestErrorResponse: - """Perform a POST request to the API.""" + """Perform a POST request to the API. + + Args: + api_request (BaseRequest): The request to submit. + expected_response (type[HordeResponse]): The expected response type. + + Returns: + HordeResponse | RequestErrorResponse: The response from the API. + """ parsed_request = self._validate_and_prepare_request(api_request) raw_response = requests.post( parsed_request.endpoint_no_query, @@ -255,12 +344,50 @@ def post( return self._after_request_handling(api_request, raw_response, expected_response) + async def async_post( + self, + api_request: BaseRequest, + expected_response: type[HordeResponse], + ) -> HordeResponse | RequestErrorResponse: + """Perform a POST request to the API asynchronously. + + Args: + api_request (BaseRequest): The request to submit. + expected_response (type[HordeResponse]): The expected response type. + + Returns: + HordeResponse | RequestErrorResponse: The response from the API. + """ + parsed_request = self._validate_and_prepare_request(api_request) + + async with ( + aiohttp.ClientSession() as session, + session.post( + parsed_request.endpoint_no_query, + headers=parsed_request.request_headers, + params=parsed_request.request_queries, + json=parsed_request.request_body, + allow_redirects=True, + ) as response, + ): + raw_response = await response.json() + + return self._after_request_handling(api_request, raw_response, expected_response) + def put( self, api_request: BaseRequest, expected_response: type[HordeResponse], ) -> HordeResponse | RequestErrorResponse: - """Perform a PUT request to the API.""" + """Perform a PUT request to the API. + + Args: + api_request (BaseRequest): The request to submit. + expected_response (type[HordeResponse]): The expected response type. + + Returns: + HordeResponse | RequestErrorResponse: The response from the API. + """ parsed_request = self._validate_and_prepare_request(api_request) raw_response = requests.put( parsed_request.endpoint_no_query, @@ -272,12 +399,50 @@ def put( return self._after_request_handling(api_request, raw_response, expected_response) + async def async_put( + self, + api_request: BaseRequest, + expected_response: type[HordeResponse], + ) -> HordeResponse | RequestErrorResponse: + """Perform a PUT request to the API asynchronously. + + Args: + api_request (BaseRequest): The request to submit. + expected_response (type[HordeResponse]): The expected response type. + + Returns: + HordeResponse | RequestErrorResponse: The response from the API. + """ + parsed_request = self._validate_and_prepare_request(api_request) + + async with ( + aiohttp.ClientSession() as session, + session.put( + parsed_request.endpoint_no_query, + headers=parsed_request.request_headers, + params=parsed_request.request_queries, + json=parsed_request.request_body, + allow_redirects=True, + ) as response, + ): + raw_response = await response.json() + + return self._after_request_handling(api_request, raw_response, expected_response) + def patch( self, api_request: BaseRequest, expected_response: type[HordeResponse], ) -> HordeResponse | RequestErrorResponse: - """Perform a PATCH request to the API.""" + """Perform a PATCH request to the API. + + Args: + api_request (BaseRequest): The request to submit. + expected_response (type[HordeResponse]): The expected response type. + + Returns: + HordeResponse | RequestErrorResponse: The response from the API. + """ parsed_request = self._validate_and_prepare_request(api_request) raw_response = requests.patch( parsed_request.endpoint_no_query, @@ -289,12 +454,50 @@ def patch( return self._after_request_handling(api_request, raw_response, expected_response) + async def async_patch( + self, + api_request: BaseRequest, + expected_response: type[HordeResponse], + ) -> HordeResponse | RequestErrorResponse: + """Perform a PATCH request to the API asynchronously. + + Args: + api_request (BaseRequest): The request to submit. + expected_response (type[HordeResponse]): The expected response type. + + Returns: + HordeResponse | RequestErrorResponse: The response from the API. + """ + parsed_request = self._validate_and_prepare_request(api_request) + + async with ( + aiohttp.ClientSession() as session, + session.patch( + parsed_request.endpoint_no_query, + headers=parsed_request.request_headers, + params=parsed_request.request_queries, + json=parsed_request.request_body, + allow_redirects=True, + ) as response, + ): + raw_response = await response.json() + + return self._after_request_handling(api_request, raw_response, expected_response) + def delete( self, api_request: BaseRequest, expected_response: type[HordeResponse], ) -> HordeResponse | RequestErrorResponse: - """Perform a DELETE request to the API.""" + """Perform a DELETE request to the API. + + Args: + api_request (BaseRequest): The request to submit. + expected_response (type[HordeResponse]): The expected response type. + + Returns: + HordeResponse | RequestErrorResponse: The response from the API. + """ parsed_request = self._validate_and_prepare_request(api_request) raw_response = requests.delete( parsed_request.endpoint_no_query, @@ -305,3 +508,74 @@ def delete( ) return self._after_request_handling(api_request, raw_response, expected_response) + + async def async_delete( + self, + api_request: BaseRequest, + expected_response: type[HordeResponse], + ) -> HordeResponse | RequestErrorResponse: + """Perform a DELETE request to the API asynchronously. + + Args: + api_request (BaseRequest): The request to submit. + expected_response (type[HordeResponse]): The expected response type. + + Returns: + HordeResponse | RequestErrorResponse: The response from the API. + """ + parsed_request = self._validate_and_prepare_request(api_request) + + async with ( + aiohttp.ClientSession() as session, + session.delete( + parsed_request.endpoint_no_query, + headers=parsed_request.request_headers, + params=parsed_request.request_queries, + json=parsed_request.request_body, + allow_redirects=True, + ) as response, + ): + raw_response = await response.json() + + return self._after_request_handling(api_request, raw_response, expected_response) + + +class HordeRequestHandler(Generic[HordeRequest, HordeResponse]): + request: HordeRequest + """The request to be handled.""" + + response: HordeResponse | RequestErrorResponse + """The response from the API.""" + + def __init__(self, request: HordeRequest) -> None: + self.request = request + + def __enter__(self) -> HordeRequest: + return self.request + + def __exit__(self, exc_type: type[Exception], exc_val: Exception, exc_tb: object) -> None: + if exc_type is not None: + print(f"Error: {exc_val}, Type: {exc_type}, Traceback: {exc_tb}") + if not self.request.is_recovery_enabled(): + return + + recovery_request_type = self.request.get_recovery_request_type() + + request_params = {} + + mappable_base_types: list[type[BaseModel]] = [ + BaseRequestAuthenticated, + BaseRequestUserSpecific, + BaseRequestWorkerDriven, + ] + + # If it any of the base types are a subclass of the recovery request type, then we can map the request + # parameters to the recovery request. + # + # For example, if the recovery request type is `DeleteImageGenerateRequest`, and the request is + # `ImageGenerateAsyncRequest`, then we can map the `id` parameter from the request to the `id` parameter + # of the recovery request. + for base_type in mappable_base_types: + if issubclass(recovery_request_type, base_type): + for key in base_type.model_fields: + request_params[key] = getattr(self.request, key) diff --git a/src/horde_sdk/generic_api/utils/swagger.py b/src/horde_sdk/generic_api/utils/swagger.py index 28ec44d..f690c87 100644 --- a/src/horde_sdk/generic_api/utils/swagger.py +++ b/src/horde_sdk/generic_api/utils/swagger.py @@ -556,8 +556,10 @@ def _resolve_model_ref_defaults( or validation_method == SwaggerSchemaValidationMethod.anyOf ): logger.warning( - "oneOf and anyOf are not well supported. Yoy may experience unexpected behavior. " - f"ref: {definition.ref}", + ( + "oneOf and anyOf are not well supported. Yoy may experience unexpected behavior. " + f"ref: {definition.ref}" + ), ) break diff --git a/tests/ai_horde_api/test_api_calls.py b/tests/ai_horde_api/test_api_calls.py index efc5054..47d6c08 100644 --- a/tests/ai_horde_api/test_api_calls.py +++ b/tests/ai_horde_api/test_api_calls.py @@ -5,7 +5,7 @@ from horde_sdk.ai_horde_api.apimodels import ( AllWorkersDetailsRequest, AllWorkersDetailsResponse, - CancelImageGenerateRequest, + DeleteImageGenerateRequest, ImageGenerateAsyncRequest, ImageGenerateAsyncResponse, ImageGenerateStatusResponse, @@ -32,8 +32,9 @@ def test_AIHordeAPIClient_init(self) -> None: def test_generate_async(self, default_image_gen_request: ImageGenerateAsyncRequest) -> None: client = AIHordeAPIClient() - image_async_response: ImageGenerateAsyncResponse | RequestErrorResponse = client.generate_image_async( - default_image_gen_request, + image_async_response: ImageGenerateAsyncResponse | RequestErrorResponse = client.submit_request( + api_request=default_image_gen_request, + expected_response_type=default_image_gen_request.get_success_response_type(), ) if isinstance(image_async_response, RequestErrorResponse): @@ -43,16 +44,18 @@ def test_generate_async(self, default_image_gen_request: ImageGenerateAsyncReque cancel_response: ImageGenerateStatusResponse | RequestErrorResponse = client.delete_pending_image( "0000000000", - image_async_response.id, + image_async_response.id_, ) if isinstance(cancel_response, RequestErrorResponse): pytest.fail( - f"API Response was an error: {cancel_response.message}" - f"Please note that the job ({image_async_response.id}) is orphaned and will continue to run on the " - "server until it is finished, it times out or it is cancelled manually.", + ( + f"API Response was an error: {cancel_response.message}Please note that the job" + f" ({image_async_response.id_}) is orphaned and will continue to run on the server until it is" + " finished, it times out or it is cancelled manually." + ), ) - assert isinstance(cancel_response, CancelImageGenerateRequest.get_success_response_type()) + assert isinstance(cancel_response, DeleteImageGenerateRequest.get_success_response_type()) def test_workers_all(self) -> None: client = AIHordeAPIClient() diff --git a/tests/test_data/ai_horde_api/production_responses/_v2_workers_get_200_production.json b/tests/test_data/ai_horde_api/production_responses/_v2_workers_get_200_production.json index c81329e..0967ef4 100644 --- a/tests/test_data/ai_horde_api/production_responses/_v2_workers_get_200_production.json +++ b/tests/test_data/ai_horde_api/production_responses/_v2_workers_get_200_production.json @@ -1,3746 +1 @@ -[ - { - "type": "image", - "name": "zoro221", - "id": "60cbb469-6a2d-43e3-8392-7255e4956fab", - "online": true, - "requests_fulfilled": 481570, - "kudos_rewards": 10063376.0, - "kudos_details": { - "generated": 8495921.0, - "uptime": 1569376 - }, - "performance": "0.3 megapixelsteps per second", - "threads": 1, - "uptime": 7714566, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 3462, - "models": [ - "Anygen", - "Perfect World", - "Pretty 2.5D", - "Hassaku", - "PFG", - "AbyssOrangeMix-AfterDark", - "Epic Diffusion", - "Openniji", - "Reliberate", - "NeverEnding Dream", - "Anything v5", - "Cetus-Mix", - "Dreamlike Photoreal", - "ToonYou", - "Realistic Vision Inpainting", - "CyberRealistic", - "ExpMix Line", - "Abyss OrangeMix", - "Project Unreal Engine 5", - "PortraitPlus", - "Anything Diffusion", - "Zeipher Female Model", - "Rev Animated", - "Furry Epoch", - "CamelliaMix 2.5D", - "GTA5 Artwork Diffusion", - "GuoFeng", - "DucHaiten Classic Anime", - "AnyLoRA", - "iCoMix", - "Dreamlike Diffusion", - "ACertainThing", - "MoistMix", - "GorynichMix", - "Realistic Vision", - "URPM", - "Lyriel", - "Cyberpunk Anime Diffusion", - "DucHaiten", - "ICBINP - I Can't Believe It's Not Photography", - "RCNZ Gorilla With A Brick", - "FaeTastic", - "Mistoon Amethyst", - "Woop-Woop Photo", - "Henmix Real", - "BB95 Furry Mix", - "GhostMix", - "MeinaMix", - "Grapefruit Hentai", - "Movie Diffusion", - "Yiffy", - "Dungeons and Diffusion", - "Hentai Diffusion", - "Something", - "Analog Diffusion", - "Edge Of Realism", - "Realisian", - "Counterfeit", - "stable_diffusion", - "3DKX", - "Deliberate", - "Pastel Mix", - "Kenshi", - "Fluffusion", - "Realism Engine", - "Dan Mumford Style", - "stable_diffusion_inpainting", - "Zack3D", - "Laolei New Berry Protogen Mix", - "Anything v3", - "RealBiter", - "Liberty", - "Western Animation Diffusion", - "MoonMix Fantasy", - "Babes", - "majicMIX realistic", - "Dreamshaper", - "Lawlas's yiff mix", - "BRA", - "Aurora", - "waifu_diffusion", - "Hassanblend", - "stable_diffusion_2.1", - "Experience", - "ChilloutMix", - "Eimis Anime Diffusion", - "Dungeons n Waifus", - "DreamShaper Inpainting", - "RPG" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 1048576, - "megapixelsteps_generated": 8233740, - "img2img": true, - "painting": true, - "lora": true - }, - { - "type": "image", - "name": "alexzander700", - "id": "8a447f0b-f870-4bb1-8d5f-635a0385cf38", - "online": true, - "requests_fulfilled": 143, - "kudos_rewards": 4745.0, - "kudos_details": { - "generated": 4329.0, - "uptime": 416 - }, - "performance": "0.3 megapixelsteps per second", - "threads": 1, - "uptime": 5344, - "maintenance_mode": false, - "nsfw": true, - "trusted": false, - "flagged": false, - "uncompleted_jobs": 0, - "models": [ - "Deliberate" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 720896, - "megapixelsteps_generated": 3270, - "img2img": true, - "painting": false, - "lora": false - }, - { - "type": "image", - "name": "SweetSunnyBunsWorker", - "id": "b456aae0-33ad-48a7-a9d1-72e6445a1016", - "online": true, - "requests_fulfilled": 9214, - "kudos_rewards": 213204.0, - "kudos_details": { - "generated": 191092.0, - "uptime": 22112 - }, - "performance": "0.4 megapixelsteps per second", - "threads": 1, - "uptime": 247489, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 17, - "models": [ - "GuoFeng", - "Anything Diffusion", - "Deliberate" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 720896, - "megapixelsteps_generated": 171282, - "img2img": true, - "painting": false, - "lora": false - }, - { - "type": "image", - "name": "LameDuckDream0", - "id": "d0b2cb3b-8e50-4c2e-bac1-22afeef00b5e", - "online": true, - "requests_fulfilled": 184308, - "kudos_rewards": 2750801.0, - "kudos_details": { - "generated": 2435399.0, - "uptime": 315432 - }, - "performance": "1.0 megapixelsteps per second", - "threads": 1, - "uptime": 2341448, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 86, - "models": [ - "Anything v5", - "Anything Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 524288, - "megapixelsteps_generated": 2465230, - "img2img": false, - "painting": false, - "lora": true - }, - { - "type": "image", - "name": "pawkygame_3060 Dreamer", - "id": "1051dd84-b3ad-4760-81ee-734d659a5df0", - "online": true, - "requests_fulfilled": 61482, - "kudos_rewards": 2333768.0, - "kudos_details": { - "generated": 2182205.0, - "uptime": 151788 - }, - "performance": "0.6 megapixelsteps per second", - "threads": 1, - "uptime": 1848238, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 33, - "models": [ - "Deliberate" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:22:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 1048576, - "megapixelsteps_generated": 1598257, - "img2img": true, - "painting": false, - "lora": false - }, - { - "type": "image", - "name": "Neko Dreamer", - "id": "72425421-b9fe-4fbb-bcc1-772c6ddee5c9", - "online": true, - "requests_fulfilled": 127706, - "kudos_rewards": 3162181.0, - "kudos_details": { - "generated": 3031592.0, - "uptime": 137554 - }, - "performance": "0.6 megapixelsteps per second", - "threads": 4, - "uptime": 1438892, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 1112, - "models": [ - "ICBINP - I Can't Believe It's Not Photography", - "stable_diffusion", - "Anything Diffusion", - "Hentai Diffusion", - "Deliberate" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 786432, - "megapixelsteps_generated": 2445741, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "JBertok-TitanV-3", - "id": "b04c21d9-a714-4c33-b754-cdd03d7ee603", - "online": true, - "requests_fulfilled": 687955, - "kudos_rewards": 9188907.0, - "kudos_details": { - "generated": 8391965.0, - "uptime": 798664 - }, - "performance": "0.9 megapixelsteps per second", - "threads": 1, - "uptime": 9249995, - "maintenance_mode": false, - "info": "Titan V 12GB x4, Xeon Gold 6258R x2, 192GB", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 2197, - "models": [ - "Healy's Anime Blend", - "Deliberate", - "Anything Diffusion", - "CyberRealistic", - "PortraitPlus" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 393216, - "megapixelsteps_generated": 8075821, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "The Portal of Infinite Realities", - "id": "dc0704ab-5b42-4c65-8471-561be16ad696", - "online": true, - "requests_fulfilled": 1568077, - "kudos_rewards": 30200065.0, - "kudos_details": { - "generated": 28598541.0, - "uptime": 1668294 - }, - "performance": "3.0 megapixelsteps per second", - "threads": 1, - "uptime": 14908784, - "maintenance_mode": false, - "info": "Somewhere far beyond...", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 7112, - "models": [ - "NeverEnding Dream", - "ICBINP - I Can't Believe It's Not Photography", - "iCoMix", - "Deliberate", - "Anything Diffusion", - "Abyss OrangeMix", - "Inkpunk Diffusion", - "Dreamlike Diffusion", - "RCNZ Gorilla With A Brick", - "BB95 Furry Mix", - "Dreamshaper", - "Hentai Diffusion", - "Lawlas's yiff mix", - "Counterfeit", - "stable_diffusion" - ], - "team": { - "name": "Mutual Aid", - "id": "7a5afb3e-6d80-41f0-98bd-9be732d45944" - }, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 4194304, - "megapixelsteps_generated": 27917898, - "img2img": true, - "painting": false, - "lora": true - }, - { - "type": "image", - "name": "ControlNet_Worker_3", - "id": "e81aadb1-a7d5-456e-b21f-594981399cdd", - "online": true, - "requests_fulfilled": 32928, - "kudos_rewards": 1162017.0, - "kudos_details": { - "generated": 1140986.0, - "uptime": 21060 - }, - "performance": "2.7 megapixelsteps per second", - "threads": 1, - "uptime": 237864, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 1071, - "models": [ - "horde_special::stability.ai#6901", - "SDXL_beta::stability.ai#6901" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:22:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 4194304, - "megapixelsteps_generated": 1360100, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "AASD02", - "id": "1d3ba385-904d-4f69-ab1a-f341c4c233d9", - "online": true, - "requests_fulfilled": 40496, - "kudos_rewards": 1050197.0, - "kudos_details": { - "generated": 382773.0, - "uptime": 667424 - }, - "performance": "0.2 megapixelsteps per second", - "threads": 1, - "uptime": 8389356, - "maintenance_mode": false, - "nsfw": false, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 876, - "models": [ - "Deliberate" - ], - "team": {}, - "bridge_agent": "SD-WebUI Stable Horde Worker Bridge:4:https://github.com/sdwebui-w-horde/sd-webui-stable-horde-worker", - "max_pixels": 589824, - "megapixelsteps_generated": 481034, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "Vadi: RTX 4080", - "id": "16bd5866-129d-4221-89b3-e477f1e62128", - "online": true, - "requests_fulfilled": 258018, - "kudos_rewards": 3159229.0, - "kudos_details": { - "generated": 3044561.0, - "uptime": 119400 - }, - "performance": "2.9 megapixelsteps per second", - "threads": 1, - "uptime": 1273845, - "maintenance_mode": false, - "info": "Fusing text-based gaming and image generation for https://mudlet.org", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 523, - "models": [ - "Anything Diffusion", - "Deliberate" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 1048576, - "megapixelsteps_generated": 2994572, - "img2img": true, - "painting": true, - "lora": true - }, - { - "type": "image", - "name": "DigitalDream.io", - "id": "71b60cd2-f9d2-4cc3-9916-323c396474e7", - "online": true, - "requests_fulfilled": 171548, - "kudos_rewards": 4107895.0, - "kudos_details": { - "generated": 3872734.0, - "uptime": 240878 - }, - "performance": "1.2 megapixelsteps per second", - "threads": 1, - "uptime": 1990343, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 512, - "models": [ - "stable_diffusion", - "ICBINP - I Can't Believe It's Not Photography", - "Deliberate", - "Anything Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 2097152, - "megapixelsteps_generated": 3237980, - "img2img": true, - "painting": true, - "lora": true - }, - { - "type": "image", - "name": "TSE-Megu", - "id": "7e91c70a-fa29-4061-bdb0-f64ab57321e8", - "online": true, - "requests_fulfilled": 273096, - "kudos_rewards": 4218505.0, - "kudos_details": { - "generated": 3712244.0, - "uptime": 506476 - }, - "performance": "0.4 megapixelsteps per second", - "threads": 1, - "uptime": 3250322, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 331, - "models": [ - "AbyssOrangeMix-AfterDark", - "ICBINP - I Can't Believe It's Not Photography", - "GhostMix", - "Deliberate", - "Anything Diffusion", - "Abyss OrangeMix", - "Hentai Diffusion", - "Dreamshaper", - "stable_diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 2567130, - "img2img": true, - "painting": true, - "lora": true - }, - { - "type": "image", - "name": "ControlNet_Worker_4", - "id": "436eafe1-3e46-49b6-984a-79d44a16c8d7", - "online": true, - "requests_fulfilled": 31575, - "kudos_rewards": 1116591.0, - "kudos_details": { - "generated": 1095213.0, - "uptime": 21426 - }, - "performance": "2.2 megapixelsteps per second", - "threads": 1, - "uptime": 243095, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 1268, - "models": [ - "horde_special::stability.ai#6901", - "SDXL_beta::stability.ai#6901" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:22:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 4194304, - "megapixelsteps_generated": 1301965, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "azizrahmad", - "id": "9ddb2685-7020-4d93-8471-ea62a6a46f93", - "online": true, - "requests_fulfilled": 17018, - "kudos_rewards": 261831.0, - "kudos_details": { - "generated": 232379.0, - "uptime": 29518 - }, - "performance": "0.4 megapixelsteps per second", - "threads": 1, - "uptime": 336874, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 176, - "models": [ - "Deliberate" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 720896, - "megapixelsteps_generated": 231807, - "img2img": true, - "painting": false, - "lora": false - }, - { - "type": "image", - "name": "pamagensart", - "id": "ba9937fb-8558-4d42-9059-926de5f0fe4e", - "online": true, - "requests_fulfilled": 126225, - "kudos_rewards": 2373932.0, - "kudos_details": { - "generated": 2233698.0, - "uptime": 140648 - }, - "performance": "1.3 megapixelsteps per second", - "threads": 1, - "uptime": 1506916, - "maintenance_mode": false, - "info": "A4000", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 699, - "models": [ - "Anything Diffusion", - "stable_diffusion_2.1", - "Project Unreal Engine 5", - "stable_diffusion", - "PortraitPlus" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:20:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 1048576, - "megapixelsteps_generated": 2387912, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "Infermatic.ai4", - "id": "029c8bd9-69b6-42eb-b5f3-f34525b56d4b", - "online": true, - "requests_fulfilled": 73399, - "kudos_rewards": 1179448.0, - "kudos_details": { - "generated": 1017184.0, - "uptime": 162540 - }, - "performance": "0.8 megapixelsteps per second", - "threads": 1, - "uptime": 1848307, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 97, - "models": [ - "Deliberate", - "Anything Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:21:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 720276, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "DavyJones", - "id": "df619f50-0703-42d5-9219-d52185d0e447", - "online": true, - "requests_fulfilled": 15, - "kudos_rewards": 250.0, - "kudos_details": { - "generated": 196.0, - "uptime": 54 - }, - "performance": "0.3 megapixelsteps per second", - "threads": 1, - "uptime": 854, - "maintenance_mode": false, - "nsfw": true, - "trusted": false, - "flagged": false, - "uncompleted_jobs": 0, - "models": [ - "Deliberate", - "Anything Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 161, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "bonanza dreamer", - "id": "86211549-f733-4239-abfa-d96f6c5bd84d", - "online": true, - "requests_fulfilled": 17916, - "kudos_rewards": 228216.0, - "kudos_details": { - "generated": 206316.0, - "uptime": 21952 - }, - "performance": "0.7 megapixelsteps per second", - "threads": 1, - "uptime": 250576, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 10, - "models": [ - "Anything Diffusion", - "Deliberate" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:22:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 163607, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "Infermatic.ai10", - "id": "1874367f-cb76-4204-a87a-a5ca20b520eb", - "online": true, - "requests_fulfilled": 75823, - "kudos_rewards": 1210673.0, - "kudos_details": { - "generated": 1048362.0, - "uptime": 162432 - }, - "performance": "0.8 megapixelsteps per second", - "threads": 1, - "uptime": 1848374, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 104, - "models": [ - "Deliberate", - "Anything Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:21:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 743707, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "ControlNet_Worker_6", - "id": "b06e20aa-fb8d-4dd8-b133-6eea3e2ab9fd", - "online": true, - "requests_fulfilled": 33888, - "kudos_rewards": 1193349.0, - "kudos_details": { - "generated": 1171853.0, - "uptime": 21532 - }, - "performance": "2.4 megapixelsteps per second", - "threads": 1, - "uptime": 243673, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 1266, - "models": [ - "horde_special::stability.ai#6901", - "SDXL_beta::stability.ai#6901" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:22:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 4194304, - "megapixelsteps_generated": 1396014, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "Obsidian", - "id": "04dc954a-99a4-45f5-806f-e7e676558fce", - "online": true, - "requests_fulfilled": 5908, - "kudos_rewards": 94720.0, - "kudos_details": { - "generated": 88056.0, - "uptime": 6664 - }, - "performance": "0.8 megapixelsteps per second", - "threads": 1, - "uptime": 72137, - "maintenance_mode": false, - "nsfw": true, - "trusted": false, - "flagged": false, - "uncompleted_jobs": 0, - "models": [ - "Anything Diffusion", - "Deliberate", - "ICBINP - I Can't Believe It's Not Photography" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 58056, - "img2img": true, - "painting": false, - "lora": false - }, - { - "type": "image", - "name": "JBertok-TitanV-2", - "id": "ec06eeb7-4c6a-43e3-8eaf-d28799530964", - "online": true, - "requests_fulfilled": 666068, - "kudos_rewards": 8689204.0, - "kudos_details": { - "generated": 7867879.0, - "uptime": 823408 - }, - "performance": "1.0 megapixelsteps per second", - "threads": 1, - "uptime": 9052674, - "maintenance_mode": false, - "info": "Titan V 12GB x4, Xeon Gold 6258R x2, 192GB", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 4243, - "models": [ - "CyberRealistic", - "Deliberate", - "Anything Diffusion", - "Healy's Anime Blend", - "PortraitPlus" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 393216, - "megapixelsteps_generated": 7660182, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "https://t.me/fa_gpt", - "id": "d5e680f8-f584-49cb-967f-dbb673ac7201", - "online": true, - "requests_fulfilled": 2958, - "kudos_rewards": 48811.0, - "kudos_details": { - "generated": 44751.0, - "uptime": 4070 - }, - "performance": "0.5 megapixelsteps per second", - "threads": 1, - "uptime": 48140, - "maintenance_mode": false, - "nsfw": true, - "trusted": false, - "flagged": false, - "uncompleted_jobs": 65, - "models": [ - "stable_diffusion", - "BB95 Furry Mix", - "Anything Diffusion", - "ICBINP - I Can't Believe It's Not Photography", - "Deliberate" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 30356, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "Infermatic.ai05", - "id": "7b4ef5fc-5f02-4564-ace6-9c04b759ca62", - "online": true, - "requests_fulfilled": 76776, - "kudos_rewards": 1224613.0, - "kudos_details": { - "generated": 1062471.0, - "uptime": 162486 - }, - "performance": "0.9 megapixelsteps per second", - "threads": 1, - "uptime": 1848170, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 101, - "models": [ - "Deliberate", - "Anything Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:21:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 752106, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "Infermatic.ai08", - "id": "c827056d-ac26-4684-89ef-0d4c5e3f2de3", - "online": true, - "requests_fulfilled": 76559, - "kudos_rewards": 1218020.0, - "kudos_details": { - "generated": 1055867.0, - "uptime": 162432 - }, - "performance": "0.9 megapixelsteps per second", - "threads": 1, - "uptime": 1847832, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 117, - "models": [ - "Anything Diffusion", - "Deliberate" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:21:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 752573, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "Photodude_2000", - "id": "db6b8f00-c97d-4e89-a727-a1947d017480", - "online": true, - "requests_fulfilled": 24748, - "kudos_rewards": 401886.0, - "kudos_details": { - "generated": 365478.0, - "uptime": 37066 - }, - "performance": "0.5 megapixelsteps per second", - "threads": 2, - "uptime": 268341, - "maintenance_mode": false, - "nsfw": true, - "trusted": false, - "flagged": false, - "uncompleted_jobs": 78, - "models": [ - "Deliberate", - "ICBINP - I Can't Believe It's Not Photography", - "BB95 Furry Mix", - "stable_diffusion", - "Anything Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 240115, - "img2img": true, - "painting": true, - "lora": true - }, - { - "type": "image", - "name": "ControlNet_Worker_0", - "id": "49c3c471-b49e-4524-b7df-f34a992bbd68", - "online": true, - "requests_fulfilled": 32614, - "kudos_rewards": 1156948.0, - "kudos_details": { - "generated": 1135940.0, - "uptime": 21168 - }, - "performance": "2.6 megapixelsteps per second", - "threads": 1, - "uptime": 238853, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 1150, - "models": [ - "horde_special::stability.ai#6901", - "SDXL_beta::stability.ai#6901" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:22:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 4194304, - "megapixelsteps_generated": 1353677, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "Verinoth-04", - "id": "d30fe850-52e9-46c0-9a7e-4b0675d916a2", - "online": true, - "requests_fulfilled": 518, - "kudos_rewards": 5995.0, - "kudos_details": { - "generated": 4286.0, - "uptime": 1716 - }, - "performance": "0.9 megapixelsteps per second", - "threads": 1, - "uptime": 13976, - "maintenance_mode": false, - "nsfw": true, - "trusted": false, - "flagged": false, - "uncompleted_jobs": 0, - "models": [ - "HRL", - "Realistic Vision", - "Zack3D", - "URPM", - "Neurogen", - "Deliberate", - "PPP", - "Liberty", - "PFG", - "Realisian", - "Hassanblend", - "ChilloutMix", - "Zeipher Female Model", - "majicMIX realistic" - ], - "team": {}, - "bridge_agent": "SD-WebUI Stable Horde Worker Bridge:4:https://github.com/sdwebui-w-horde/sd-webui-stable-horde-worker", - "max_pixels": 1048576, - "megapixelsteps_generated": 6597, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "Healthy Fibers", - "id": "253f02f8-1f4a-43e9-9495-25bf269de6f1", - "online": true, - "requests_fulfilled": 79450, - "kudos_rewards": 1178995.0, - "kudos_details": { - "generated": 1145143.0, - "uptime": 118068 - }, - "performance": "0.8 megapixelsteps per second", - "threads": 1, - "uptime": 1228891, - "maintenance_mode": false, - "info": "Back after a bit! Hi guys!", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 195, - "models": [ - "Deliberate", - "stable_diffusion_2.1", - "ICBINP - I Can't Believe It's Not Photography", - "Anything Diffusion", - "stable_diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 393216, - "megapixelsteps_generated": 889944, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "Pro", - "id": "4d078ad4-5f1f-48fc-868f-05bdd0ee1ab1", - "online": true, - "requests_fulfilled": 560, - "kudos_rewards": 14627.0, - "kudos_details": { - "generated": 3914.0, - "uptime": 10712 - }, - "performance": "0.5 megapixelsteps per second", - "threads": 1, - "uptime": 126451, - "maintenance_mode": false, - "nsfw": true, - "trusted": false, - "flagged": false, - "uncompleted_jobs": 1, - "models": [ - "Yiffy" - ], - "team": {}, - "bridge_agent": "SD-WebUI Stable Horde Worker Bridge:4:https://github.com/sdwebui-w-horde/sd-webui-stable-horde-worker", - "max_pixels": 589824, - "megapixelsteps_generated": 5653, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "Infermatic.ai1jkj", - "id": "6bbd1181-b2f5-41d1-8dfc-c7b906674f50", - "online": true, - "requests_fulfilled": 74050, - "kudos_rewards": 1185855.0, - "kudos_details": { - "generated": 1023842.0, - "uptime": 162270 - }, - "performance": "0.8 megapixelsteps per second", - "threads": 1, - "uptime": 1848676, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 122, - "models": [ - "Deliberate", - "Anything Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:21:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 726621, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "MMOLogin AI Dreamer", - "id": "167872f0-9332-47bb-8697-e43a4832adc4", - "online": true, - "requests_fulfilled": 39661, - "kudos_rewards": 601872.0, - "kudos_details": { - "generated": 515402.0, - "uptime": 86486 - }, - "performance": "0.6 megapixelsteps per second", - "threads": 1, - "uptime": 535573, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 22, - "models": [ - "Hentai Diffusion", - "Anything Diffusion Inpainting", - "Anime Pencil Diffusion", - "Illuminati Diffusion", - "3DKX", - "Movie Diffusion", - "stable_diffusion_inpainting", - "Future Diffusion", - "Anything Diffusion", - "Vector Art", - "Grapefruit Hentai", - "Graphic-Art", - "stable_diffusion_2.1", - "DucHaiten Classic Anime", - "stable_diffusion", - "Henmix Real", - "Pretty 2.5D", - "Midjourney PaintArt", - "Anything v5", - "vectorartz", - "Fluffusion", - "Elysium Anime", - "RPG", - "waifu_diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 354501, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "ControlNet_Worker_2", - "id": "3f60c707-df27-48ad-b0f7-0c014960affd", - "online": true, - "requests_fulfilled": 32786, - "kudos_rewards": 1159101.0, - "kudos_details": { - "generated": 1138175.0, - "uptime": 21006 - }, - "performance": "1.9 megapixelsteps per second", - "threads": 1, - "uptime": 237178, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 1191, - "models": [ - "horde_special::stability.ai#6901", - "SDXL_beta::stability.ai#6901" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:22:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 4194304, - "megapixelsteps_generated": 1356438, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "Infermatic.ai09", - "id": "667bffdd-c8c5-49bc-b374-130beac76734", - "online": true, - "requests_fulfilled": 75815, - "kudos_rewards": 1212896.0, - "kudos_details": { - "generated": 1050689.0, - "uptime": 162324 - }, - "performance": "1.0 megapixelsteps per second", - "threads": 1, - "uptime": 1848759, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 99, - "models": [ - "Deliberate", - "Anything Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:21:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 744753, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "pawkygame_2060 Dreamer", - "id": "31f6d463-c96d-4421-acba-ef8139d9c640", - "online": true, - "requests_fulfilled": 208682, - "kudos_rewards": 4174863.0, - "kudos_details": { - "generated": 3666341.0, - "uptime": 508586 - }, - "performance": "0.7 megapixelsteps per second", - "threads": 1, - "uptime": 4900536, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 229, - "models": [ - "majicMIX realistic", - "Deliberate", - "Pretty 2.5D", - "ICBINP - I Can't Believe It's Not Photography", - "CamelliaMix 2.5D", - "Anything Diffusion", - "BRA", - "ChilloutMix", - "stable_diffusion" - ], - "team": { - "name": "PawkyGame", - "id": "b417b070-0205-4bc3-be55-41e2516b8d50" - }, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 589824, - "megapixelsteps_generated": 3058884, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "JBertok-TitanV-1", - "id": "645c3e0a-01ac-4804-90ad-a5c479a56d5e", - "online": true, - "requests_fulfilled": 631377, - "kudos_rewards": 9290130.0, - "kudos_details": { - "generated": 8526251.0, - "uptime": 765796 - }, - "performance": "0.8 megapixelsteps per second", - "threads": 1, - "uptime": 8886616, - "maintenance_mode": false, - "info": "Titan V 12GB x4, Xeon 6258R x2, 192GB", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 2637, - "models": [ - "CyberRealistic", - "Deliberate", - "Anything Diffusion", - "PortraitPlus" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 393216, - "megapixelsteps_generated": 8184796, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "AIDream-02", - "id": "82fc88ea-d316-4d09-90f1-4ae9c6939455", - "online": true, - "requests_fulfilled": 839484, - "kudos_rewards": 17985269.0, - "kudos_details": { - "generated": 14418766.0, - "uptime": 3575610 - }, - "performance": "0.8 megapixelsteps per second", - "threads": 1, - "uptime": 7186918, - "maintenance_mode": false, - "info": "RTX 3080, 32GB RAM, i9-11900k, NVME.", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 720, - "models": [ - "BubblyDubbly", - "Lyriel", - "DreamLikeSamKuvshinov", - "DucHaiten", - "FKing SciFi", - "mo-di-diffusion", - "Sygil-Dev Diffusion", - "Marvel Diffusion", - "3DKX", - "PFG", - "GuFeng", - "Pastel Mix", - "Samaritan 3d Cartoon", - "Squishmallow Diffusion", - "BRA", - "DucHaiten Classic Anime", - "CamelliaMix 2.5D", - "Double Exposure Diffusion", - "Art Of Mtg", - "Asim Simpsons", - "Protogen Infinity", - "Nitro Diffusion", - "Zack3D", - "Real Dos Mix", - "Unstable Ink Dream", - "Fluffusion", - "Cetus-Mix", - "Inkpunk Diffusion", - "Jim Eidomode", - "Grapefruit Hentai", - "Zeipher Female Model", - "Robo-Diffusion", - "Balloon Art", - "NeverEnding Dream", - "Realisian", - "Pretty 2.5D", - "Epic Diffusion", - "Elden Ring Diffusion", - "DGSpitzer Art Diffusion", - "Dungeons n Waifus", - "Moedel", - "ProtoGen", - "ICBINP - I Can't Believe It's Not Photography", - "Borderlands", - "Sonic Diffusion", - "Epic Diffusion Inpainting", - "Ultraskin", - "CyberRealistic", - "Movie Diffusion", - "RealBiter", - "stable_diffusion_inpainting", - "MeinaMix", - "Rev Animated", - "Henmix Real", - "Woop-Woop Photo", - "Hassaku", - "Papercut Diffusion", - "RPG", - "HASDX", - "Experience", - "kurzgesagt", - "Comic-Diffusion", - "Disco Elysium", - "ChromaV5", - "Valorant Diffusion", - "AIO Pixel Art", - "A-Zovya RPG Inpainting", - "BweshMix", - "Clazy", - "Knollingcase", - "Uhmami", - "Smoke Diffusion", - "Wavyfusion", - "Dark Victorian Diffusion", - "Laolei New Berry Protogen Mix", - "Dreamlike Diffusion", - "GuoFeng", - "Min Illust Background", - "DreamShaper Inpainting", - "Cheese Daddys Landscape Mix", - "JWST Deep Space Diffusion", - "ChilloutMix", - "Openniji", - "BPModel", - "App Icon Diffusion", - "Disney Pixar Cartoon Type A", - "Kenshi", - "Abyss OrangeMix", - "Dreamlike Photoreal", - "Deliberate Inpainting", - "RCNZ Gorilla With A Brick", - "Samdoesarts Ultmerge", - "Redshift Diffusion", - "stable_diffusion_2.1", - "Darkest Diffusion", - "Furry Epoch", - "Voxel Art Diffusion", - "Ether Real Mix", - "Guohua Diffusion", - "Galena Redux", - "T-Shirt Print Designs", - "AnyLoRA", - "Anything Diffusion", - "FaeTastic", - "CyriousMix", - "Deliberate", - "Hassanblend", - "iCoMix", - "URPM", - "Van Gogh Diffusion", - "Analog Diffusion", - "Yiffy", - "Korestyle", - "Realistic Vision Inpainting", - "DnD Map Generator", - "Fantasy Card Diffusion", - "Vector Art", - "Babes", - "Something", - "MoistMix", - "Xynthii-Diffusion", - "Realism Engine", - "Poison", - "Elldreth's Lucid Mix", - "majicMIX realistic", - "Microscopic", - "ExpMix Line", - "PIXHELL", - "BB95 Furry Mix", - "Reliberate", - "Anime Pencil Diffusion", - "Synthwave", - "Eimis Anime Diffusion", - "Ranma Diffusion", - "Future Diffusion", - "GhostMix", - "Rainbowpatch", - "Project Unreal Engine 5", - "Midjourney PaintArt", - "GTA5 Artwork Diffusion", - "SweetBoys 2D", - "Spider-Verse Diffusion", - "MoonMix Fantasy", - "Tron Legacy Diffusion", - "Protogen Anime", - "TrexMix", - "Char", - "Dark Sushi Mix", - "vectorartz", - "stable_diffusion", - "Dungeons and Diffusion", - "PRMJ", - "Western Animation Diffusion", - "A to Zovya RPG", - "Trinart Characters", - "UMI Olympus", - "Concept Sheet", - "waifu_diffusion", - "Microcritters", - "Anything v5", - "ModernArt Diffusion", - "Pulp Vector Art", - "Ghibli Diffusion", - "CharHelper", - "Pokemon3D", - "Counterfeit", - "Liberty", - "Healy's Anime Blend", - "Sci-Fi Diffusion", - "T-Shirt Diffusion", - "Eternos", - "Mega Merge Diffusion", - "Dan Mumford Style", - "JoMad Diffusion", - "Vivid Watercolors", - "Aurora", - "PortraitPlus", - "VinteProtogenMix", - "PPP", - "Anygen", - "Anything Diffusion Inpainting", - "GorynichMix", - "Dreamshaper", - "HRL", - "Coloring Book", - "Illuminati Diffusion", - "Rachel Walker Watercolors", - "Papercutcraft", - "Anything v3", - "Realistic Vision", - "Supermarionation", - "Zelda BOTW", - "RCNZ Dumb Monkey", - "OrbAI", - "Rodent Diffusion", - "Mistoon Amethyst", - "SD-Silicon", - "ToonYou", - "Funko Diffusion", - "AbyssOrangeMix-AfterDark", - "Colorful", - "526Mix-Animated", - "Perfect World", - "Cyberpunk Anime Diffusion", - "DnD Item", - "ACertainThing", - "Microchars", - "Elldreths Retro Mix", - "PVC", - "Seek.art MEGA", - "Arcane Diffusion", - "Microworlds", - "Vintedois Diffusion", - "Analog Madness", - "iCoMix Inpainting", - "Elysium Anime", - "Neurogen", - "OpenJourney Diffusion", - "SynthwavePunk", - "trinart", - "Hentai Diffusion", - "Lawlas's yiff mix", - "Edge Of Realism", - "Archer Diffusion", - "Graphic-Art", - "Microcasing", - "Classic Animation Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:22:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 589824, - "megapixelsteps_generated": 13356384, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "DigitalDream.io_2", - "id": "cf864212-98d8-4b54-9539-0869bf1a04fb", - "online": true, - "requests_fulfilled": 74841, - "kudos_rewards": 2424776.0, - "kudos_details": { - "generated": 2192900.0, - "uptime": 231876 - }, - "performance": "1.0 megapixelsteps per second", - "threads": 1, - "uptime": 1633382, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 463, - "models": [ - "stable_diffusion", - "ICBINP - I Can't Believe It's Not Photography", - "Deliberate", - "Anything Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:22:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 1572864, - "megapixelsteps_generated": 1740886, - "img2img": true, - "painting": true, - "lora": true - }, - { - "type": "image", - "name": "Shyla's Diffusion", - "id": "98688698-dc8a-4cbe-8fb9-c2db2ffb4751", - "online": true, - "requests_fulfilled": 1230, - "kudos_rewards": 15110.0, - "kudos_details": { - "generated": 14310.0, - "uptime": 810 - }, - "performance": "1.8 megapixelsteps per second", - "threads": 1, - "uptime": 9185, - "maintenance_mode": false, - "nsfw": true, - "trusted": false, - "flagged": false, - "uncompleted_jobs": 2, - "models": [ - "Deliberate", - "Anything Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 524288, - "megapixelsteps_generated": 14475, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "pawkygame_2080 Dreamer", - "id": "e650da17-c2aa-499c-b1d5-48fed2c97ab0", - "online": true, - "requests_fulfilled": 572893, - "kudos_rewards": 7456921.0, - "kudos_details": { - "generated": 6943790.0, - "uptime": 514382 - }, - "performance": "0.7 megapixelsteps per second", - "threads": 2, - "uptime": 4915335, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 147, - "models": [ - "ChilloutMix", - "stable_diffusion", - "Pretty 2.5D", - "CamelliaMix 2.5D", - "majicMIX realistic", - "Deliberate", - "ICBINP - I Can't Believe It's Not Photography", - "Anything Diffusion" - ], - "team": { - "name": "PawkyGame", - "id": "b417b070-0205-4bc3-be55-41e2516b8d50" - }, - "bridge_agent": "AI Horde Worker:22:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 589824, - "megapixelsteps_generated": 6867533, - "img2img": false, - "painting": false, - "lora": false - }, - { - "type": "image", - "name": "SHLB1", - "id": "ef7c02a7-5716-4e4e-bdac-0083218d52fb", - "online": true, - "requests_fulfilled": 779879, - "kudos_rewards": 11026150.0, - "kudos_details": { - "generated": 10383901.0, - "uptime": 648326 - }, - "performance": "1.5 megapixelsteps per second", - "threads": 1, - "uptime": 7557316, - "maintenance_mode": false, - "info": "3060 ti \ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f (my room cold)", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 593, - "models": [ - "Deliberate", - "DucHaiten" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:21:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 589824, - "megapixelsteps_generated": 9469080, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "AASD01", - "id": "87450d7f-26f9-4435-83a4-3fbff2d92984", - "online": true, - "requests_fulfilled": 466362, - "kudos_rewards": 5512929.0, - "kudos_details": { - "generated": 4930812.0, - "uptime": 582126 - }, - "performance": "2.3 megapixelsteps per second", - "threads": 1, - "uptime": 6927555, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 904, - "models": [ - "Deliberate", - "stable_diffusion_2.1" - ], - "team": {}, - "bridge_agent": "SD-WebUI Stable Horde Worker Bridge:4:https://github.com/sdwebui-w-horde/sd-webui-stable-horde-worker", - "max_pixels": 1048576, - "megapixelsteps_generated": 6455652, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "JBertok-TitanV-4", - "id": "e59230a6-bb24-4887-a421-15c4ff564cf5", - "online": true, - "requests_fulfilled": 625306, - "kudos_rewards": 9197953.0, - "kudos_details": { - "generated": 8414503.0, - "uptime": 784558 - }, - "performance": "0.7 megapixelsteps per second", - "threads": 1, - "uptime": 9059996, - "maintenance_mode": false, - "info": "Titan V 12GB x4, Xeon 6258R x2, 192GB", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 2288, - "models": [ - "CyberRealistic", - "Neurogen", - "Anything Diffusion", - "Anything v3", - "Deliberate" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 393216, - "megapixelsteps_generated": 8030817, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "pawkygame_3090 Dreamer", - "id": "19d0aa86-eca4-49de-b31b-900dfad35b79", - "online": true, - "requests_fulfilled": 164066, - "kudos_rewards": 3483938.0, - "kudos_details": { - "generated": 3281334.0, - "uptime": 203632 - }, - "performance": "1.5 megapixelsteps per second", - "threads": 1, - "uptime": 1946603, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 115, - "models": [ - "majicMIX realistic", - "BRA", - "Deliberate", - "stable_diffusion", - "Pretty 2.5D", - "CamelliaMix 2.5D", - "ChilloutMix" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 1966080, - "megapixelsteps_generated": 3389316, - "img2img": true, - "painting": false, - "lora": false - }, - { - "type": "image", - "name": "Mythica-Horde-Delta", - "id": "95cfe49b-10a4-4d1d-ac6c-01872d3e1f4f", - "online": true, - "requests_fulfilled": 1245718, - "kudos_rewards": 13695325.0, - "kudos_details": { - "generated": 12693367.0, - "uptime": 1012042 - }, - "performance": "0.4 megapixelsteps per second", - "threads": 4, - "uptime": 11380218, - "maintenance_mode": false, - "info": "Sharing the computing power of @Mythica https://mythica.dev/", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 8481, - "models": [ - "Project Unreal Engine 5", - "Grapefruit Hentai", - "Anything v3", - "stable_diffusion", - "PortraitPlus", - "Hentai Diffusion", - "stable_diffusion_2.1" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 14144010, - "img2img": false, - "painting": false, - "lora": false - }, - { - "type": "image", - "name": "SomeOrdinarydudeLinuxDesktop", - "id": "431e3b61-9657-48d1-a5b3-850fc777749f", - "online": true, - "requests_fulfilled": 108830, - "kudos_rewards": 2301515.0, - "kudos_details": { - "generated": 2158465.0, - "uptime": 143502 - }, - "performance": "1.9 megapixelsteps per second", - "threads": 1, - "uptime": 1092783, - "maintenance_mode": false, - "info": "Fedora Linux system with RTX 3090 AMD 9 5950X 64GB RAM 128 GB linux swap SSD \n\nTypically runs at night when I don't need to render anything", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 485, - "models": [ - "stable_diffusion", - "stable_diffusion_2.1" - ], - "team": { - "name": "Mutual Aid", - "id": "7a5afb3e-6d80-41f0-98bd-9be732d45944" - }, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 3276800, - "megapixelsteps_generated": 1993335, - "img2img": true, - "painting": true, - "lora": true - }, - { - "type": "image", - "name": "FiFo-002", - "id": "6e7a6c54-1204-424a-97b3-acdc022ccdb7", - "online": true, - "requests_fulfilled": 390215, - "kudos_rewards": 4850456.0, - "kudos_details": { - "generated": 3759359.0, - "uptime": 1096798 - }, - "performance": "0.3 megapixelsteps per second", - "threads": 1, - "uptime": 13335352, - "maintenance_mode": true, - "info": "Quadro P4000 8 GB", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 728, - "models": [ - "Deliberate", - "Anything Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 3525961, - "img2img": true, - "painting": false, - "lora": false - }, - { - "type": "image", - "name": "Dezealotl", - "id": "6b830da8-1fa0-499e-8c48-4330d6af7c26", - "online": true, - "requests_fulfilled": 11147, - "kudos_rewards": 209297.0, - "kudos_details": { - "generated": 193181.0, - "uptime": 16126 - }, - "performance": "0.7 megapixelsteps per second", - "threads": 1, - "uptime": 160248, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 31, - "models": [ - "Furry Epoch", - "stable_diffusion_inpainting", - "Yiffy", - "Fluffusion", - "Zack3D", - "Lawlas's yiff mix", - "BB95 Furry Mix" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 589824, - "megapixelsteps_generated": 167704, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "FiFo-001", - "id": "23499b5a-48d3-40a1-8ddb-75cd6e576e1f", - "online": true, - "requests_fulfilled": 374380, - "kudos_rewards": 4718272.0, - "kudos_details": { - "generated": 3646894.0, - "uptime": 1077384 - }, - "performance": "0.3 megapixelsteps per second", - "threads": 1, - "uptime": 13112322, - "maintenance_mode": true, - "info": "Quadro P4000 8 GB", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 1006, - "models": [ - "Deliberate", - "Anything Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 3369494, - "img2img": true, - "painting": false, - "lora": false - }, - { - "type": "image", - "name": "SomeOrdinaryDudeLaptop2", - "id": "ac7340c8-7099-4d00-83d0-25bf687fc1a5", - "online": true, - "requests_fulfilled": 414760, - "kudos_rewards": 4339819.0, - "kudos_details": { - "generated": 3907734.0, - "uptime": 434676 - }, - "performance": "0.8 megapixelsteps per second", - "threads": 1, - "uptime": 5185458, - "maintenance_mode": false, - "info": "Decent laptop", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 1227, - "models": [ - "stable_diffusion" - ], - "team": { - "name": "Mutual Aid", - "id": "7a5afb3e-6d80-41f0-98bd-9be732d45944" - }, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 589824, - "megapixelsteps_generated": 3843931, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "Infermatic.ai07", - "id": "4a94c354-cfba-44eb-8d3e-b90033033216", - "online": true, - "requests_fulfilled": 76393, - "kudos_rewards": 1219414.0, - "kudos_details": { - "generated": 1057308.0, - "uptime": 162378 - }, - "performance": "0.9 megapixelsteps per second", - "threads": 1, - "uptime": 1849982, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 113, - "models": [ - "Deliberate", - "Anything Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:21:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 749496, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "ControlNet_Worker_7", - "id": "db4a6644-434f-4825-a06e-62d53f68829f", - "online": true, - "requests_fulfilled": 31052, - "kudos_rewards": 1099243.0, - "kudos_details": { - "generated": 1078116.0, - "uptime": 21156 - }, - "performance": "2.5 megapixelsteps per second", - "threads": 1, - "uptime": 240254, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 1265, - "models": [ - "horde_special::stability.ai#6901", - "SDXL_beta::stability.ai#6901" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:22:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 4194304, - "megapixelsteps_generated": 1281472, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "ControlNet_Worker_5", - "id": "e2a18a8c-9ad2-4cf7-9f23-8edb39388ea6", - "online": true, - "requests_fulfilled": 33786, - "kudos_rewards": 1191133.0, - "kudos_details": { - "generated": 1169817.0, - "uptime": 21316 - }, - "performance": "2.7 megapixelsteps per second", - "threads": 1, - "uptime": 241970, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 1258, - "models": [ - "horde_special::stability.ai#6901", - "SDXL_beta::stability.ai#6901" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:22:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 4194304, - "megapixelsteps_generated": 1392946, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "GenericName", - "id": "e72ebdef-bfec-43cf-92ce-22e7bf064478", - "online": true, - "requests_fulfilled": 21020, - "kudos_rewards": 213218.0, - "kudos_details": { - "generated": 169433.0, - "uptime": 43800 - }, - "performance": "0.3 megapixelsteps per second", - "threads": 3, - "uptime": 479461, - "maintenance_mode": true, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 23, - "models": [ - "Deliberate", - "Anything Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 229376, - "megapixelsteps_generated": 130804, - "img2img": true, - "painting": true, - "lora": true - }, - { - "type": "image", - "name": "ffffff", - "id": "bd6a4b3d-22d6-4364-9466-c34fd9c1a9da", - "online": true, - "requests_fulfilled": 2983, - "kudos_rewards": 59471.0, - "kudos_details": { - "generated": 51899.0, - "uptime": 7644 - }, - "performance": "0.4 megapixelsteps per second", - "threads": 1, - "uptime": 93149, - "maintenance_mode": false, - "nsfw": true, - "trusted": false, - "flagged": false, - "uncompleted_jobs": 16, - "models": [ - "Epic Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 720896, - "megapixelsteps_generated": 69557, - "img2img": true, - "painting": false, - "lora": false - }, - { - "type": "image", - "name": "Betti Earlie Ariadne", - "id": "452c9166-1ddd-4b60-a746-e38c1b99c6aa", - "online": true, - "requests_fulfilled": 1176763, - "kudos_rewards": 14212695.0, - "kudos_details": { - "generated": 13277016.0, - "uptime": 943018 - }, - "performance": "1.8 megapixelsteps per second", - "threads": 1, - "uptime": 11214533, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 584, - "models": [ - "Counterfeit" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 917504, - "megapixelsteps_generated": 13148955, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "Stasiade", - "id": "3a6802d6-4f22-4220-be24-ae53fdf18aca", - "online": true, - "requests_fulfilled": 89878, - "kudos_rewards": 1347950.0, - "kudos_details": { - "generated": 1228322.0, - "uptime": 121274 - }, - "performance": "1.0 megapixelsteps per second", - "threads": 1, - "uptime": 1209585, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 322, - "models": [ - "stable_diffusion_2.1", - "Deliberate", - "Dreamlike Photoreal", - "Analog Diffusion", - "Realistic Vision", - "stable_diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:22:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 589824, - "megapixelsteps_generated": 1042075, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "Infermatic.ai03", - "id": "cf1fae07-f72d-4f47-9612-89b8634149dd", - "online": true, - "requests_fulfilled": 308365, - "kudos_rewards": 3990178.0, - "kudos_details": { - "generated": 3690354.0, - "uptime": 300132 - }, - "performance": "1.2 megapixelsteps per second", - "threads": 1, - "uptime": 3387130, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 113, - "models": [ - "Deliberate", - "Anything Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:21:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 2744434, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "ControlNet_Worker_1", - "id": "4ed5fa6b-d043-4382-ba59-525358ffb982", - "online": true, - "requests_fulfilled": 31409, - "kudos_rewards": 1096489.0, - "kudos_details": { - "generated": 1085135.0, - "uptime": 11394 - }, - "performance": "2.4 megapixelsteps per second", - "threads": 1, - "uptime": 130549, - "maintenance_mode": true, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 1390, - "models": [ - "horde_special::stability.ai#6901", - "SDXL_beta::stability.ai#6901" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:22:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 4194304, - "megapixelsteps_generated": 1310899, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "ComicsMaker.ai", - "id": "74e0a02c-4089-4815-bc73-4551d9a47fcb", - "online": true, - "requests_fulfilled": 124729, - "kudos_rewards": 1355330.0, - "kudos_details": { - "generated": 1242833.0, - "uptime": 112756 - }, - "performance": "0.8 megapixelsteps per second", - "threads": 1, - "uptime": 1221391, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 23, - "models": [ - "Deliberate", - "stable_diffusion", - "iCoMix" - ], - "team": { - "name": "ComicsMaker.ai", - "id": "75b4a0d2-4054-4781-aa39-1292dec1f87c" - }, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 894179, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "AI All The Things", - "id": "257a9750-6037-4f06-ac01-51da130faa78", - "online": true, - "requests_fulfilled": 4191, - "kudos_rewards": 64404.0, - "kudos_details": { - "generated": 61218.0, - "uptime": 3186 - }, - "performance": "1.0 megapixelsteps per second", - "threads": 1, - "uptime": 36877, - "maintenance_mode": false, - "nsfw": true, - "trusted": false, - "flagged": false, - "uncompleted_jobs": 0, - "models": [ - "Deliberate", - "Anything Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 44246, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "gigo", - "id": "13f5ac2e-1daa-4f05-912b-4f3d7a0f11ca", - "online": true, - "requests_fulfilled": 2719, - "kudos_rewards": 40483.0, - "kudos_details": { - "generated": 37176.0, - "uptime": 3340 - }, - "performance": "1.0 megapixelsteps per second", - "threads": 1, - "uptime": 40724, - "maintenance_mode": false, - "nsfw": true, - "trusted": false, - "flagged": false, - "uncompleted_jobs": 12, - "models": [ - "Deliberate", - "Anything Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:21:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 589824, - "megapixelsteps_generated": 33107, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "Infermatic.ai06", - "id": "5c55ebc3-1ba0-44fe-8cf7-0e5273f9d560", - "online": true, - "requests_fulfilled": 76698, - "kudos_rewards": 1223211.0, - "kudos_details": { - "generated": 1061067.0, - "uptime": 162378 - }, - "performance": "1.0 megapixelsteps per second", - "threads": 1, - "uptime": 1847027, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 96, - "models": [ - "Deliberate", - "Anything Diffusion" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:21:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 262144, - "megapixelsteps_generated": 752303, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "Dreamer_nine", - "id": "59421027-87a3-49e4-8069-ea409ad239fc", - "online": true, - "requests_fulfilled": 2628, - "kudos_rewards": 43859.0, - "kudos_details": { - "generated": 42768.0, - "uptime": 1134 - }, - "performance": "3.3 megapixelsteps per second", - "threads": 1, - "uptime": 13325, - "maintenance_mode": false, - "nsfw": true, - "trusted": false, - "flagged": false, - "uncompleted_jobs": 2, - "models": [ - "Anything Diffusion", - "Deliberate" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 589824, - "megapixelsteps_generated": 42040, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "cvoer", - "id": "50975d63-2318-42f3-b9cd-4fa0014d4219", - "online": true, - "requests_fulfilled": 19132, - "kudos_rewards": 220190.0, - "kudos_details": { - "generated": 192529.0, - "uptime": 27664 - }, - "performance": "2.7 megapixelsteps per second", - "threads": 1, - "uptime": 326143, - "maintenance_mode": true, - "info": "RTX4090, 32Gb RAM, i5-13600K", - "nsfw": true, - "trusted": false, - "flagged": false, - "uncompleted_jobs": 503, - "models": [ - "Deliberate" - ], - "team": {}, - "bridge_agent": "SD-WebUI Stable Horde Worker Bridge:4:https://github.com/sdwebui-w-horde/sd-webui-stable-horde-worker", - "max_pixels": 1048576, - "megapixelsteps_generated": 287241, - "img2img": true, - "painting": true, - "lora": false - }, - { - "type": "image", - "name": "ComputeSheepLand_DreamerSheep1B", - "id": "f8a396c8-55af-4c97-816a-8d1023a214bf", - "online": true, - "requests_fulfilled": 31517, - "kudos_rewards": 515548.0, - "kudos_details": { - "generated": 488843.0, - "uptime": 27638 - }, - "performance": "0.6 megapixelsteps per second", - "threads": 2, - "uptime": 183279, - "maintenance_mode": true, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 52, - "models": [ - "Dreamshaper", - "Deliberate", - "Anything Diffusion", - "stable_diffusion", - "ICBINP - I Can't Believe It's Not Photography", - "Arcane Diffusion", - "Poison" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:22:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 327680, - "megapixelsteps_generated": 395103, - "img2img": true, - "painting": true, - "lora": true - }, - { - "type": "image", - "name": "AiBrush", - "id": "a68c78f2-3303-4b68-b4a2-586183ce7e24", - "online": true, - "requests_fulfilled": 2131359, - "kudos_rewards": 34754388.0, - "kudos_details": { - "generated": 34669650.0, - "uptime": 827706 - }, - "performance": "1.4 megapixelsteps per second", - "threads": 1, - "uptime": 7136035, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 4576, - "models": [ - "ICBINP - I Can't Believe It's Not Photography", - "Deliberate", - "GTA5 Artwork Diffusion", - "Dungeons n Waifus", - "App Icon Diffusion", - "Epic Diffusion Inpainting", - "iCoMix Inpainting", - "Realistic Vision", - "CamelliaMix 2.5D", - "Realistic Vision Inpainting", - "Epic Diffusion", - "RCNZ Gorilla With A Brick", - "ToonYou", - "FaeTastic", - "SynthwavePunk", - "Jim Eidomode", - "Western Animation Diffusion", - "Deliberate Inpainting", - "PIXHELL", - "MoistMix", - "Dreamlike Diffusion", - "DreamShaper Inpainting", - "kurzgesagt", - "Pulp Vector Art", - "Disney Pixar Cartoon Type A", - "ChilloutMix", - "Reliberate", - "Rev Animated", - "Hentai Diffusion", - "PFG", - "Mistoon Amethyst", - "Eternos", - "Anything Diffusion Inpainting", - "Perfect World" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker", - "max_pixels": 1376256, - "megapixelsteps_generated": 31844713, - "img2img": true, - "painting": true, - "lora": true - }, - { - "type": "text", - "name": "Meus Artis", - "id": "9b44aeeb-de81-4028-903f-93894b13bc36", - "online": true, - "requests_fulfilled": 7416, - "kudos_rewards": 37516.0, - "kudos_details": { - "generated": 7417.0, - "uptime": 30100 - }, - "performance": "2.6 tokens per second", - "threads": 1, - "uptime": 373159, - "maintenance_mode": false, - "info": "Ryzen 5600X + RX 5700XT", - "nsfw": true, - "trusted": false, - "flagged": false, - "uncompleted_jobs": 3, - "models": [ - "koboldcpp/Airoboros-13B" - ], - "team": {}, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 2048, - "max_context_length": 1024 - }, - { - "type": "text", - "name": "Snail Down! 1", - "id": "5a98e66a-3d72-4863-bc2d-9a6457ccf373", - "online": true, - "requests_fulfilled": 12207, - "kudos_rewards": 523917.0, - "kudos_details": { - "generated": 510480.0, - "uptime": 13550 - }, - "performance": "34.2 tokens per second", - "threads": 1, - "uptime": 168186, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 18, - "models": [ - "PygmalionAI/pygmalion-6b" - ], - "team": {}, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 512, - "max_context_length": 2048 - }, - { - "type": "text", - "name": "Gargamel 1", - "id": "5562c3bd-64c7-402c-b99d-d9ebf5b05c50", - "online": true, - "requests_fulfilled": 72589, - "kudos_rewards": 10004257.0, - "kudos_details": { - "generated": 9892007.0, - "uptime": 112300 - }, - "performance": "6.8 tokens per second", - "threads": 1, - "uptime": 1383455, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 273, - "models": [ - "airoboros-65B-gpt4-1.4-GPTQ" - ], - "team": { - "name": "\u262d Our Horde - Collaboration is Key \u262d", - "id": "d0aec80f-d56f-45be-9c35-f425ac882e43" - }, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 512, - "max_context_length": 2048 - }, - { - "type": "text", - "name": "Daemonic Intuition", - "id": "42b7acfe-b816-40d4-b797-e6a877ec8779", - "online": true, - "requests_fulfilled": 151094, - "kudos_rewards": 3874172.0, - "kudos_details": { - "generated": 3636386.0, - "uptime": 237800 - }, - "performance": "11.6 tokens per second", - "threads": 1, - "uptime": 2932154, - "maintenance_mode": false, - "info": "2x NVLINKed A6000s (one currently used)", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 859, - "models": [ - "Enterredaas-65b-4bit-128g" - ], - "team": {}, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 512, - "max_context_length": 2048 - }, - { - "type": "text", - "name": "Bird up! 2", - "id": "fd758a30-dfe2-4d7b-a444-4b1b63089ef4", - "online": true, - "requests_fulfilled": 130127, - "kudos_rewards": 3303837.0, - "kudos_details": { - "generated": 3169808.0, - "uptime": 134100 - }, - "performance": "13.6 tokens per second", - "threads": 1, - "uptime": 1642281, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 1224, - "models": [ - "PygmalionAI/pygmalion-6b" - ], - "team": {}, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 512, - "max_context_length": 2048 - }, - { - "type": "text", - "name": "Daemonic Conversationalist", - "id": "47180ae6-465f-4de8-8677-063a2d765437", - "online": true, - "requests_fulfilled": 77021, - "kudos_rewards": 1863853.0, - "kudos_details": { - "generated": 1749767.0, - "uptime": 114100 - }, - "performance": "14.4 tokens per second", - "threads": 1, - "uptime": 1399035, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 8, - "models": [ - "Chronoboros-33b-4bit" - ], - "team": {}, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 512, - "max_context_length": 2048 - }, - { - "type": "text", - "name": "Bird up! 0", - "id": "77add8ce-1a39-4edd-96a5-19140063676d", - "online": true, - "requests_fulfilled": 236782, - "kudos_rewards": 4814699.0, - "kudos_details": { - "generated": 4497258.0, - "uptime": 317550 - }, - "performance": "44.2 tokens per second", - "threads": 1, - "uptime": 3895983, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 1514, - "models": [ - "Pygmalion-7b-4bit-GPTQ-Safetensors" - ], - "team": {}, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 512, - "max_context_length": 2048 - }, - { - "type": "text", - "name": "Fire Meadow GPU", - "id": "22876250-0b56-4bf1-857d-07c0e67db867", - "online": true, - "requests_fulfilled": 1337, - "kudos_rewards": 2287.0, - "kudos_details": { - "generated": 1339.0, - "uptime": 950 - }, - "performance": "14.2 tokens per second", - "threads": 1, - "uptime": 11744, - "maintenance_mode": false, - "nsfw": true, - "trusted": false, - "flagged": false, - "uncompleted_jobs": 23, - "models": [ - "Wizard-Vicuna-30B-Uncensored-GPTQ" - ], - "team": {}, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 512, - "max_context_length": 2048 - }, - { - "type": "text", - "name": "AzureBlack6", - "id": "75ce261e-306d-4638-afe9-e408cf803177", - "online": true, - "requests_fulfilled": 109057, - "kudos_rewards": 2702073.0, - "kudos_details": { - "generated": 2608993.0, - "uptime": 93100 - }, - "performance": "22.0 tokens per second", - "threads": 1, - "uptime": 1134996, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 1177, - "models": [ - "airochronos-33B-GPTQ" - ], - "team": {}, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 512, - "max_context_length": 2048 - }, - { - "type": "text", - "name": "Gargamel 3", - "id": "951be5b4-2103-463e-a937-37a48b0b2171", - "online": true, - "requests_fulfilled": 74641, - "kudos_rewards": 4346654.0, - "kudos_details": { - "generated": 4256350.0, - "uptime": 90350 - }, - "performance": "13.7 tokens per second", - "threads": 1, - "uptime": 1107693, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 97, - "models": [ - "CalderaAI/30B-Lazarus" - ], - "team": { - "name": "\u262d Our Horde - Collaboration is Key \u262d", - "id": "d0aec80f-d56f-45be-9c35-f425ac882e43" - }, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 512, - "max_context_length": 2048 - }, - { - "type": "text", - "name": "Booty_Bandit", - "id": "6cc9a393-67bf-4b7d-b584-80d811cb33b6", - "online": true, - "requests_fulfilled": 70628, - "kudos_rewards": 2217690.0, - "kudos_details": { - "generated": 2139486.0, - "uptime": 78250 - }, - "performance": "9.3 tokens per second", - "threads": 1, - "uptime": 965342, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 271, - "models": [ - "PygmalionAI/pygmalion-6b" - ], - "team": {}, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 512, - "max_context_length": 2048 - }, - { - "type": "text", - "name": "Vittra", - "id": "3f0edbf2-f195-4662-a801-572700b7ba90", - "online": true, - "requests_fulfilled": 523032, - "kudos_rewards": 35626524.0, - "kudos_details": { - "generated": 35216883.0, - "uptime": 460100 - }, - "performance": "8.2 tokens per second", - "threads": 1, - "uptime": 5630795, - "maintenance_mode": false, - "info": "Text Worker", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 2381, - "models": [ - "KoboldAI/OPT-13B-Nerybus-Mix" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:22:https://github.com/db0/AI-Horde-Worker", - "max_length": 512, - "max_context_length": 2048 - }, - { - "type": "text", - "name": "Bird up! 1", - "id": "5c60fe16-4bfd-4982-8605-cd615d8ce569", - "online": true, - "requests_fulfilled": 208338, - "kudos_rewards": 5099701.0, - "kudos_details": { - "generated": 4882147.0, - "uptime": 217650 - }, - "performance": "16.0 tokens per second", - "threads": 1, - "uptime": 2669750, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 2030, - "models": [ - "PygmalionAI/pygmalion-6b" - ], - "team": {}, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 512, - "max_context_length": 2048 - }, - { - "type": "text", - "name": "Tufte", - "id": "5702e22d-b548-4020-9913-1e6535302d51", - "online": true, - "requests_fulfilled": 1227143, - "kudos_rewards": 37819446.0, - "kudos_details": { - "generated": 37001871.0, - "uptime": 887150 - }, - "performance": "10.0 tokens per second", - "threads": 1, - "uptime": 10789901, - "maintenance_mode": false, - "info": "RTX3060", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 3122, - "models": [ - "PygmalionAI/pygmalion-6b" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:22:https://github.com/db0/AI-Horde-Worker", - "max_length": 512, - "max_context_length": 2048 - }, - { - "type": "text", - "name": "WolfySoy's PC", - "id": "65c99111-cbd1-4cdc-b25e-29c93f22af87", - "online": true, - "requests_fulfilled": 37389, - "kudos_rewards": 488603.0, - "kudos_details": { - "generated": 309703.0, - "uptime": 178900 - }, - "performance": "21.8 tokens per second", - "threads": 1, - "uptime": 2181467, - "maintenance_mode": false, - "info": "RTX 2080 6GB Ryzen 7 64GB", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 72, - "models": [ - "PygmalionAI/pygmalion-1.3b" - ], - "team": {}, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 80, - "max_context_length": 1024 - }, - { - "type": "text", - "name": "Gargamel 2", - "id": "e72ab6ba-45a0-4988-aec2-6f0f9adb5ac4", - "online": true, - "requests_fulfilled": 108535, - "kudos_rewards": 10131195.0, - "kudos_details": { - "generated": 10019155.0, - "uptime": 112050 - }, - "performance": "11.6 tokens per second", - "threads": 1, - "uptime": 1372002, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 224, - "models": [ - "CalderaAI/30B-Lazarus" - ], - "team": { - "name": "\u262d Our Horde - Collaboration is Key \u262d", - "id": "d0aec80f-d56f-45be-9c35-f425ac882e43" - }, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 512, - "max_context_length": 2048 - }, - { - "type": "text", - "name": "a_weird_titanx", - "id": "78330b07-29e8-4e29-9ce5-28c172883352", - "online": true, - "requests_fulfilled": 45407, - "kudos_rewards": 1308100.0, - "kudos_details": { - "generated": 485000.0, - "uptime": 823100 - }, - "performance": "31.2 tokens per second", - "threads": 1, - "uptime": 9910163, - "maintenance_mode": false, - "info": "Titan X Maxwell", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 69, - "models": [ - "Gustavosta/MagicPrompt-Stable-Diffusion" - ], - "team": {}, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 80, - "max_context_length": 1024 - }, - { - "type": "text", - "name": "BaasKUIgpus#1362", - "id": "659ec194-d3d5-465f-89de-51146b867c4b", - "online": true, - "requests_fulfilled": 150, - "kudos_rewards": 3642.0, - "kudos_details": { - "generated": 3042.0, - "uptime": 600 - }, - "performance": "2.4 tokens per second", - "threads": 1, - "uptime": 8649, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 11, - "models": [ - "KoboldAI/GPT-J-6B-Skein" - ], - "team": {}, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 136, - "max_context_length": 1680 - }, - { - "type": "text", - "name": "Smurf 5", - "id": "d8873c0d-a1d8-47d6-8b18-3328535482bd", - "online": true, - "requests_fulfilled": 20140, - "kudos_rewards": 528662.0, - "kudos_details": { - "generated": 250762.0, - "uptime": 277900 - }, - "performance": "49.6 tokens per second", - "threads": 1, - "uptime": 3341799, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 0, - "models": [ - "asmodeus" - ], - "team": {}, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 512, - "max_context_length": 4096 - }, - { - "type": "text", - "name": "Smurf 2", - "id": "37cc1633-e241-4cc7-9bea-e9a4d29b16e5", - "online": true, - "requests_fulfilled": 19937, - "kudos_rewards": 525973.0, - "kudos_details": { - "generated": 248073.0, - "uptime": 277900 - }, - "performance": "58.9 tokens per second", - "threads": 1, - "uptime": 3341271, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 1, - "models": [ - "asmodeus" - ], - "team": {}, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 512, - "max_context_length": 4096 - }, - { - "type": "text", - "name": "Nisse", - "id": "14a9a534-d46c-406c-abfa-f845779b1983", - "online": true, - "requests_fulfilled": 747925, - "kudos_rewards": 57552891.0, - "kudos_details": { - "generated": 56760676.0, - "uptime": 891900 - }, - "performance": "3.8 tokens per second", - "threads": 1, - "uptime": 10913924, - "maintenance_mode": false, - "info": "RTX3090", - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 2705, - "models": [ - "KoboldAI/OPT-13B-Erebus" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:22:https://github.com/db0/AI-Horde-Worker", - "max_length": 512, - "max_context_length": 2048 - }, - { - "type": "text", - "name": "Smurf 4", - "id": "be1f034b-38e4-426c-a9a2-e6b587e4fdc2", - "online": true, - "requests_fulfilled": 20017, - "kudos_rewards": 525616.0, - "kudos_details": { - "generated": 247666.0, - "uptime": 277950 - }, - "performance": "55.5 tokens per second", - "threads": 1, - "uptime": 3341980, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 0, - "models": [ - "asmodeus" - ], - "team": {}, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 512, - "max_context_length": 4096 - }, - { - "type": "text", - "name": "Smurf 3", - "id": "f9698428-a9f9-4cdf-bc70-a1b753ebbcd5", - "online": true, - "requests_fulfilled": 19940, - "kudos_rewards": 526084.0, - "kudos_details": { - "generated": 248134.0, - "uptime": 277950 - }, - "performance": "51.2 tokens per second", - "threads": 1, - "uptime": 3342109, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 0, - "models": [ - "asmodeus" - ], - "team": {}, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 512, - "max_context_length": 4096 - }, - { - "type": "text", - "name": "Gargamel 0", - "id": "c8da1ff7-4714-4421-9c0a-c666c51f9d61", - "online": true, - "requests_fulfilled": 6022, - "kudos_rewards": 173688.0, - "kudos_details": { - "generated": 158588.0, - "uptime": 15100 - }, - "performance": "7.3 tokens per second", - "threads": 1, - "uptime": 188467, - "maintenance_mode": false, - "nsfw": true, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 22, - "models": [ - "airoboros-65B-gpt4-1.4-GPTQ" - ], - "team": { - "name": "\u262d Our Horde - Collaboration is Key \u262d", - "id": "d0aec80f-d56f-45be-9c35-f425ac882e43" - }, - "bridge_agent": "KoboldAI Bridge:10:https://github.com/db0/KoboldAI-Horde-Bridge", - "max_length": 512, - "max_context_length": 2048 - }, - { - "type": "interrogation", - "name": "kal9002", - "id": "f2a4892a-09ba-4ac1-a262-0e661511c97e", - "online": true, - "requests_fulfilled": 7861, - "kudos_rewards": 386737.0, - "kudos_details": { - "uptime": 377400 - }, - "performance": "4.2 seconds per form", - "threads": 1, - "uptime": 5701021, - "maintenance_mode": false, - "nsfw": false, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 129, - "forms": [ - "4x_AnimeSharp", - "caption", - "CodeFormers", - "GFPGAN", - "interrogation", - "NMKD_Siax", - "nsfw", - "RealESRGAN_x2plus", - "RealESRGAN_x4plus", - "RealESRGAN_x4plus_anime_6B", - "strip_background" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker" - }, - { - "type": "interrogation", - "name": "The Azure Happiness", - "id": "d9e2e140-3622-417a-973f-4a26315ec987", - "online": true, - "requests_fulfilled": 11443, - "kudos_rewards": 452255.0, - "kudos_details": { - "uptime": 438565 - }, - "performance": "6.9 seconds per form", - "threads": 2, - "uptime": 7012883, - "maintenance_mode": false, - "nsfw": false, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 1420, - "forms": [ - "caption", - "interrogation", - "nsfw" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:20:https://github.com/db0/AI-Horde-Worker" - }, - { - "type": "interrogation", - "name": "kal9004", - "id": "1e77f09c-1219-4fda-a859-7483544acf3c", - "online": true, - "requests_fulfilled": 6462, - "kudos_rewards": 350260.0, - "kudos_details": { - "uptime": 342560 - }, - "performance": "4.2 seconds per form", - "threads": 1, - "uptime": 5177276, - "maintenance_mode": false, - "nsfw": false, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 125, - "forms": [ - "4x_AnimeSharp", - "caption", - "CodeFormers", - "GFPGAN", - "interrogation", - "NMKD_Siax", - "nsfw", - "RealESRGAN_x2plus", - "RealESRGAN_x4plus", - "RealESRGAN_x4plus_anime_6B", - "strip_background" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker" - }, - { - "type": "interrogation", - "name": "kal9003", - "id": "2fafdbc0-2bd8-4171-be82-057d69b85f2c", - "online": true, - "requests_fulfilled": 6548, - "kudos_rewards": 366628.0, - "kudos_details": { - "uptime": 359000 - }, - "performance": "5.1 seconds per form", - "threads": 1, - "uptime": 5425359, - "maintenance_mode": false, - "nsfw": false, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 98, - "forms": [ - "4x_AnimeSharp", - "caption", - "CodeFormers", - "GFPGAN", - "interrogation", - "NMKD_Siax", - "nsfw", - "RealESRGAN_x2plus", - "RealESRGAN_x4plus", - "RealESRGAN_x4plus_anime_6B", - "strip_background" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker" - }, - { - "type": "interrogation", - "name": "kal9006", - "id": "d96854f8-0964-4895-8f3c-a1e859264e92", - "online": true, - "requests_fulfilled": 1165, - "kudos_rewards": 53938.0, - "kudos_details": { - "uptime": 52480 - }, - "performance": "4.4 seconds per form", - "threads": 1, - "uptime": 790677, - "maintenance_mode": false, - "nsfw": false, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 24, - "forms": [ - "4x_AnimeSharp", - "caption", - "CodeFormers", - "GFPGAN", - "interrogation", - "NMKD_Siax", - "nsfw", - "RealESRGAN_x2plus", - "RealESRGAN_x4plus", - "RealESRGAN_x4plus_anime_6B", - "strip_background" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker" - }, - { - "type": "interrogation", - "name": "lommax94", - "id": "ea9f1ae8-c130-4e12-afec-51efbdb25160", - "online": true, - "requests_fulfilled": 5682, - "kudos_rewards": 251020.0, - "kudos_details": { - "uptime": 243760 - }, - "performance": "11.3 seconds per form", - "threads": 1, - "uptime": 3664533, - "maintenance_mode": false, - "nsfw": false, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 177, - "forms": [ - "4x_AnimeSharp", - "caption", - "CodeFormers", - "GFPGAN", - "interrogation", - "NMKD_Siax", - "nsfw", - "RealESRGAN_x2plus", - "RealESRGAN_x4plus", - "RealESRGAN_x4plus_anime_6B", - "strip_background" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:21:https://github.com/db0/AI-Horde-Worker" - }, - { - "type": "interrogation", - "name": "kal9007", - "id": "68cdc28b-6004-438b-ad5a-fc661b41eb22", - "online": true, - "requests_fulfilled": 148, - "kudos_rewards": 11838.0, - "kudos_details": { - "uptime": 11640 - }, - "performance": "5.9 seconds per form", - "threads": 1, - "uptime": 175928, - "maintenance_mode": false, - "nsfw": false, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 6, - "forms": [ - "4x_AnimeSharp", - "caption", - "CodeFormers", - "GFPGAN", - "interrogation", - "NMKD_Siax", - "nsfw", - "RealESRGAN_x2plus", - "RealESRGAN_x4plus", - "RealESRGAN_x4plus_anime_6B", - "strip_background" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker" - }, - { - "type": "interrogation", - "name": "kal9005", - "id": "a3aacaf6-a3ef-4577-8f10-68daac0f1694", - "online": true, - "requests_fulfilled": 4894, - "kudos_rewards": 269181.0, - "kudos_details": { - "uptime": 263200 - }, - "performance": "5.0 seconds per form", - "threads": 1, - "uptime": 3968798, - "maintenance_mode": false, - "nsfw": false, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 89, - "forms": [ - "4x_AnimeSharp", - "caption", - "CodeFormers", - "GFPGAN", - "interrogation", - "NMKD_Siax", - "nsfw", - "RealESRGAN_x2plus", - "RealESRGAN_x4plus", - "RealESRGAN_x4plus_anime_6B", - "strip_background" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker" - }, - { - "type": "interrogation", - "name": "AiBrush-Alchemist", - "id": "5daebf7c-3cd7-4002-a4cc-221721809161", - "online": true, - "requests_fulfilled": 7674, - "kudos_rewards": 157566.0, - "kudos_details": { - "uptime": 145920 - }, - "performance": "3.4 seconds per form", - "threads": 1, - "uptime": 2197643, - "maintenance_mode": false, - "nsfw": false, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 56, - "forms": [ - "4x_AnimeSharp", - "caption", - "CodeFormers", - "GFPGAN", - "interrogation", - "NMKD_Siax", - "nsfw", - "RealESRGAN_x2plus", - "RealESRGAN_x4plus", - "RealESRGAN_x4plus_anime_6B", - "strip_background" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker" - }, - { - "type": "interrogation", - "name": "Mach2", - "id": "cbbe7972-e415-4018-8633-2f9d879550a8", - "online": true, - "requests_fulfilled": 11820, - "kudos_rewards": 523937.0, - "kudos_details": { - "uptime": 512360 - }, - "performance": "12.1 seconds per form", - "threads": 3, - "uptime": 7919873, - "maintenance_mode": false, - "nsfw": false, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 2728, - "forms": [ - "caption", - "nsfw" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:20:https://github.com/db0/AI-Horde-Worker" - }, - { - "type": "interrogation", - "name": "AiBrush-4-Alchemist", - "id": "0b0bd149-9e7e-477b-830e-8a7b1f0796af", - "online": true, - "requests_fulfilled": 1310, - "kudos_rewards": 76110.0, - "kudos_details": { - "uptime": 74600 - }, - "performance": "9.3 seconds per form", - "threads": 1, - "uptime": 1119014, - "maintenance_mode": false, - "nsfw": false, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 6, - "forms": [ - "4x_AnimeSharp", - "caption", - "CodeFormers", - "GFPGAN", - "interrogation", - "NMKD_Siax", - "nsfw", - "RealESRGAN_x2plus", - "RealESRGAN_x4plus", - "RealESRGAN_x4plus_anime_6B", - "strip_background" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker" - }, - { - "type": "interrogation", - "name": "kal9001", - "id": "fa8157e1-5f14-492f-ae92-a3b70d420223", - "online": true, - "requests_fulfilled": 7668, - "kudos_rewards": 327481.0, - "kudos_details": { - "uptime": 318680 - }, - "performance": "4.1 seconds per form", - "threads": 1, - "uptime": 4820026, - "maintenance_mode": false, - "nsfw": false, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 148, - "forms": [ - "4x_AnimeSharp", - "caption", - "CodeFormers", - "GFPGAN", - "interrogation", - "NMKD_Siax", - "nsfw", - "RealESRGAN_x2plus", - "RealESRGAN_x4plus", - "RealESRGAN_x4plus_anime_6B", - "strip_background" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker" - }, - { - "type": "interrogation", - "name": "alchemist_362959274362498", - "id": "e943061d-865b-449f-b760-6e2a00d33e08", - "online": true, - "requests_fulfilled": 80, - "kudos_rewards": 5736.0, - "kudos_details": { - "uptime": 5640 - }, - "performance": "5.3 seconds per form", - "threads": 1, - "uptime": 85429, - "maintenance_mode": false, - "nsfw": false, - "trusted": false, - "flagged": false, - "uncompleted_jobs": 4, - "forms": [ - "4x_AnimeSharp", - "caption", - "CodeFormers", - "GFPGAN", - "interrogation", - "NMKD_Siax", - "nsfw", - "RealESRGAN_x2plus", - "RealESRGAN_x4plus", - "RealESRGAN_x4plus_anime_6B", - "strip_background" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:23:https://github.com/db0/AI-Horde-Worker" - }, - { - "type": "interrogation", - "name": "Bordn #-49291740", - "id": "43ab74bb-ed39-41c1-9dcf-4b59ae2ae882", - "online": true, - "requests_fulfilled": 29347, - "kudos_rewards": 622184.0, - "kudos_details": { - "uptime": 588040 - }, - "performance": "11.3 seconds per form", - "threads": 1, - "uptime": 8862589, - "maintenance_mode": false, - "nsfw": false, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 5266, - "forms": [ - "caption", - "interrogation", - "nsfw" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:20:https://github.com/db0/AI-Horde-Worker" - }, - { - "type": "interrogation", - "name": "stablehorde-fs-worker", - "id": "8f084136-3824-4e77-a265-2918e23a71c8", - "online": true, - "requests_fulfilled": 13307, - "kudos_rewards": 392598.0, - "kudos_details": { - "uptime": 389760 - }, - "performance": "3.4 seconds per form", - "threads": 4, - "uptime": 5517542, - "maintenance_mode": false, - "nsfw": false, - "trusted": true, - "flagged": false, - "uncompleted_jobs": 191, - "forms": [ - "caption", - "nsfw" - ], - "team": {}, - "bridge_agent": "AI Horde Worker:22:https://github.com/db0/AI-Horde-Worker" - } -] +{}