mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-05-14 19:17:32 +08:00
[Partner Nodes] use image urls instead of base64
Signed-off-by: bigcat88 <bigcat88@icloud.com>
This commit is contained in:
parent
55081682c7
commit
0d58182479
@ -20,9 +20,14 @@ class AnthropicImageSourceBase64(BaseModel):
|
|||||||
data: str = Field(..., description="Base64-encoded image data")
|
data: str = Field(..., description="Base64-encoded image data")
|
||||||
|
|
||||||
|
|
||||||
|
class AnthropicImageSourceUrl(BaseModel):
|
||||||
|
type: Literal["url"] = "url"
|
||||||
|
url: str = Field(...)
|
||||||
|
|
||||||
|
|
||||||
class AnthropicImageContent(BaseModel):
|
class AnthropicImageContent(BaseModel):
|
||||||
type: Literal["image"] = "image"
|
type: Literal["image"] = "image"
|
||||||
source: AnthropicImageSourceBase64 = Field(...)
|
source: AnthropicImageSourceBase64 | AnthropicImageSourceUrl = Field(...)
|
||||||
|
|
||||||
|
|
||||||
class AnthropicMessage(BaseModel):
|
class AnthropicMessage(BaseModel):
|
||||||
|
|||||||
@ -5,7 +5,7 @@ from typing_extensions import override
|
|||||||
from comfy_api.latest import IO, ComfyExtension, Input
|
from comfy_api.latest import IO, ComfyExtension, Input
|
||||||
from comfy_api_nodes.apis.anthropic import (
|
from comfy_api_nodes.apis.anthropic import (
|
||||||
AnthropicImageContent,
|
AnthropicImageContent,
|
||||||
AnthropicImageSourceBase64,
|
AnthropicImageSourceUrl,
|
||||||
AnthropicMessage,
|
AnthropicMessage,
|
||||||
AnthropicMessagesRequest,
|
AnthropicMessagesRequest,
|
||||||
AnthropicMessagesResponse,
|
AnthropicMessagesResponse,
|
||||||
@ -14,16 +14,15 @@ from comfy_api_nodes.apis.anthropic import (
|
|||||||
)
|
)
|
||||||
from comfy_api_nodes.util import (
|
from comfy_api_nodes.util import (
|
||||||
ApiEndpoint,
|
ApiEndpoint,
|
||||||
downscale_image_tensor,
|
|
||||||
get_number_of_images,
|
get_number_of_images,
|
||||||
sync_op,
|
sync_op,
|
||||||
tensor_to_base64_string,
|
upload_images_to_comfyapi,
|
||||||
validate_string,
|
validate_string,
|
||||||
)
|
)
|
||||||
|
|
||||||
ANTHROPIC_MESSAGES_ENDPOINT = "/proxy/anthropic/v1/messages"
|
ANTHROPIC_MESSAGES_ENDPOINT = "/proxy/anthropic/v1/messages"
|
||||||
ANTHROPIC_IMAGE_MAX_PIXELS = 1568 * 1568 # Anthropic recommends max ~1568px on the longest edge
|
ANTHROPIC_IMAGE_MAX_PIXELS = 1568 * 1568
|
||||||
CLAUDE_MAX_IMAGES = 20 # Anthropic supports up to 20 images per request
|
CLAUDE_MAX_IMAGES = 20
|
||||||
|
|
||||||
CLAUDE_MODELS: dict[str, str] = {
|
CLAUDE_MODELS: dict[str, str] = {
|
||||||
"Opus 4.7": "claude-opus-4-7",
|
"Opus 4.7": "claude-opus-4-7",
|
||||||
@ -99,22 +98,18 @@ def _get_text_from_response(response: AnthropicMessagesResponse) -> str:
|
|||||||
return "\n".join(block.text for block in response.content if block.text)
|
return "\n".join(block.text for block in response.content if block.text)
|
||||||
|
|
||||||
|
|
||||||
def _build_image_content_blocks(image_tensors: list[Input.Image]) -> list[AnthropicImageContent]:
|
async def _build_image_content_blocks(
|
||||||
"""Convert image tensors (possibly batched) into Anthropic content blocks (base64 PNG)."""
|
cls: type[IO.ComfyNode],
|
||||||
blocks: list[AnthropicImageContent] = []
|
image_tensors: list[Input.Image],
|
||||||
for tensor in image_tensors:
|
) -> list[AnthropicImageContent]:
|
||||||
batch = tensor if len(tensor.shape) == 4 else tensor.unsqueeze(0)
|
urls = await upload_images_to_comfyapi(
|
||||||
for i in range(batch.shape[0]):
|
cls,
|
||||||
scaled = downscale_image_tensor(batch[i : i + 1], total_pixels=ANTHROPIC_IMAGE_MAX_PIXELS)
|
image_tensors,
|
||||||
blocks.append(
|
max_images=CLAUDE_MAX_IMAGES,
|
||||||
AnthropicImageContent(
|
total_pixels=ANTHROPIC_IMAGE_MAX_PIXELS,
|
||||||
source=AnthropicImageSourceBase64(
|
wait_label="Uploading reference images",
|
||||||
media_type="image/png",
|
)
|
||||||
data=tensor_to_base64_string(scaled),
|
return [AnthropicImageContent(source=AnthropicImageSourceUrl(url=url)) for url in urls]
|
||||||
),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return blocks
|
|
||||||
|
|
||||||
|
|
||||||
class ClaudeNode(IO.ComfyNode):
|
class ClaudeNode(IO.ComfyNode):
|
||||||
@ -221,7 +216,7 @@ class ClaudeNode(IO.ComfyNode):
|
|||||||
|
|
||||||
content: list[AnthropicTextContent | AnthropicImageContent] = []
|
content: list[AnthropicTextContent | AnthropicImageContent] = []
|
||||||
if image_tensors:
|
if image_tensors:
|
||||||
content.extend(_build_image_content_blocks(image_tensors))
|
content.extend(await _build_image_content_blocks(cls, image_tensors))
|
||||||
content.append(AnthropicTextContent(text=prompt))
|
content.append(AnthropicTextContent(text=prompt))
|
||||||
|
|
||||||
response = await sync_op(
|
response = await sync_op(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user