[Partner Nodes] use image urls instead of base64

Signed-off-by: bigcat88 <bigcat88@icloud.com>
This commit is contained in:
bigcat88 2026-05-13 17:03:32 +03:00
parent 55081682c7
commit 0d58182479
No known key found for this signature in database
GPG Key ID: 1F0BF0EC3CF22721
2 changed files with 23 additions and 23 deletions

View File

@ -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):

View File

@ -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(