migrate client to manifest v3

This commit is contained in:
Hekmon
2025-11-07 23:04:45 +01:00
parent 1b0824e9d8
commit c6b9fb8d44
3 changed files with 125 additions and 78 deletions
+52 -27
View File
@@ -1,34 +1,59 @@
from typing_extensions import override
from comfy_api.latest import ComfyExtension, io
from .client import Client
from .completions import ChatCompletion
from .debug import Debug
from .options import OptionSeed, OptionTemperature, OptionMaxTokens, OptionTopP, OptionFrequencyPenalty, OptionPresencePenalty, OptionExtraBody, OptionDeveloperRole
NODE_CLASS_MAPPINGS = {
"OAIAPIClient": Client,
"OAIAPIChatCompletion": ChatCompletion,
"OAIAPIDebug": Debug,
"OAIAPISeed": OptionSeed,
"OAIAPITemperature": OptionTemperature,
"OAIAPIMaxTokens": OptionMaxTokens,
"OAIAPITopP": OptionTopP,
"OAIAPIFrequencyPenalty": OptionFrequencyPenalty,
"OAIAPIPresencePenalty": OptionPresencePenalty,
"OAIAPIExtraBody": OptionExtraBody,
"OAIAPIDeveloperRole": OptionDeveloperRole,
}
# NODE_CLASS_MAPPINGS = {
# "OAIAPIClient": Client,
# "OAIAPIChatCompletion": ChatCompletion,
# "OAIAPIDebug": Debug,
# "OAIAPISeed": OptionSeed,
# "OAIAPITemperature": OptionTemperature,
# "OAIAPIMaxTokens": OptionMaxTokens,
# "OAIAPITopP": OptionTopP,
# "OAIAPIFrequencyPenalty": OptionFrequencyPenalty,
# "OAIAPIPresencePenalty": OptionPresencePenalty,
# "OAIAPIExtraBody": OptionExtraBody,
# "OAIAPIDeveloperRole": OptionDeveloperRole,
# }
NODE_DISPLAY_NAME_MAPPINGS = {
"OAIAPIClient": "OpenAI API - Client",
"OAIAPIChatCompletion": "OpenAI API - Chat Completion",
"OAIAPIDebug": "OpenAI API - Debug",
"OAIAPISeed": "OpenAI API - Seed",
"OAIAPITemperature": "OpenAI API - Temperature",
"OAIAPIMaxTokens": "OpenAI API - Max Tokens",
"OAIAPITopP": "OpenAI API - Top P",
"OAIAPIFrequencyPenalty": "OpenAI API - Frequency Penalty",
"OAIAPIPresencePenalty": "OpenAI API - Presence Penalty",
"OAIAPIExtraBody": "OpenAI API - Extra Body",
"OAIAPIDeveloperRole": "OpenAI API - Developer Role",
}
# NODE_DISPLAY_NAME_MAPPINGS = {
# "OAIAPIClient": "OpenAI API - Client",
# "OAIAPIChatCompletion": "OpenAI API - Chat Completion",
# "OAIAPIDebug": "OpenAI API - Debug",
# "OAIAPISeed": "OpenAI API - Seed",
# "OAIAPITemperature": "OpenAI API - Temperature",
# "OAIAPIMaxTokens": "OpenAI API - Max Tokens",
# "OAIAPITopP": "OpenAI API - Top P",
# "OAIAPIFrequencyPenalty": "OpenAI API - Frequency Penalty",
# "OAIAPIPresencePenalty": "OpenAI API - Presence Penalty",
# "OAIAPIExtraBody": "OpenAI API - Extra Body",
# "OAIAPIDeveloperRole": "OpenAI API - Developer Role",
# }
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']
# __all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']
class OpenAIAPIExtension(ComfyExtension):
@override
async def get_node_list(self) -> list[type[io.ComfyNode]]:
return [
Client,
# ChatCompletion,
# Debug,
# OptionSeed,
# OptionTemperature,
# OptionMaxTokens,
# OptionTopP,
# OptionFrequencyPenalty,
# OptionPresencePenalty,
# OptionExtraBody,
# OptionDeveloperRole
]
async def comfy_entrypoint() -> OpenAIAPIExtension:
return OpenAIAPIExtension()
+59 -42
View File
@@ -1,45 +1,59 @@
from urllib.parse import urlparse
from comfy.comfy_types import IO
from openai import OpenAI
from .iotypes import OAIAPIIO
from comfy_api.latest import io
class Client:
CATEGORY = "OpenAI API"
RETURN_TYPES = (OAIAPIIO.CLIENT,)
# RETURN_NAMES = ("Target",)
FUNCTION = "create_client"
from .iotypes import ClientParam
class Client(io.ComfyNode):
@classmethod
def define_schema(cls) -> io.Schema:
return io.Schema(
node_id="OAIAPIClient",
display_name="OpenAI API - Client",
category="OpenAI API",
inputs=[
io.String.Input(
id="base_url",
display_name="Base URL",
tooltip="The base URL to use for the OpenAI API requests",
placeholder="http(s)://host[:port][/URI]",
default="https://api.openai.com/v1"
),
io.Int.Input(
id="max_retries",
display_name="Max Retries",
tooltip="The base URL to use for the OpenAI API requests",
default=2,
min=0,
),
io.Int.Input(
id="timeout",
display_name="Timeout",
tooltip="Request timeout in seconds",
default=600,
min=1,
),
io.String.Input(
id="api_key",
display_name="API Key",
optional=True,
tooltip="The API key to use, if any",
),
],
outputs=[
ClientParam.Output(
id="client",
display_name="CLIENT",
tooltip="The initialized and ready to query OpenAI API client"
)
],
)
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"base_url": (IO.STRING, {
"default": "https://api.openai.com/v1",
"placeholder": "http(s)://host[:port][/URI]",
"tooltip": "The base URL to use for the OpenAI API requests",
}),
"max_retries": (IO.INT, {
"min": 0,
"default": 2,
"tooltip": "Maximum number of retries on failure"
}),
"timeout": (IO.INT, {
"min": 1,
"default": 600,
"tooltip": "Request timeout in seconds"
}),
},
"optional": {
"api_key": (IO.STRING, {
"tooltip": "The API key to use, if any"
})
}
}
@classmethod
def VALIDATE_INPUTS(cls, base_url):
def validate_inputs(cls, base_url) -> bool | str:
try:
result = urlparse(base_url)
if result.scheme not in ["http", "https"]:
@@ -48,10 +62,13 @@ class Client:
return f"invalid URL: {e}"
return True
def create_client(self, base_url, api_key=None, max_retries=2, timeout=600):
return (OpenAI(
api_key=api_key,
base_url=base_url,
max_retries=max_retries,
timeout=timeout
),)
@classmethod
def execute(cls, base_url: str, max_retries: int, timeout: int, api_key: str | None = None) -> io.NodeOutput:
return io.NodeOutput(
OpenAI(
api_key=api_key,
base_url=base_url,
max_retries=max_retries,
timeout=timeout
)
)
+14 -9
View File
@@ -1,10 +1,15 @@
from comfy.comfy_types.node_typing import StrEnum
from comfy_api.latest import io
# from comfy.comfy_types.node_typing import StrEnum
class OAIAPIIO(StrEnum):
"""
Node input/output data types.
"""
CLIENT = "CLIENT"
OPTIONS = "OPTIONS"
HISTORY = "HISTORY"
DEBUG = f"{OPTIONS},{HISTORY}"
# class OAIAPIIO(StrEnum):
# """
# Node input/output data types.
# """
# CLIENT = "CLIENT"
# OPTIONS = "OPTIONS"
# HISTORY = "HISTORY"
# DEBUG = f"{OPTIONS},{HISTORY}"
ClientParam = io.Custom("OAIAPI_CLIENT")