ColdPersonal

Untitled

Dec 9th, 2025
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.18 KB | Source Code | 0 0
  1. import base64
  2. import json
  3. import requests
  4. import numpy as np
  5. from PIL import Image
  6.  
  7. class LMStudioVisionPrompt:
  8. """
  9. Custom ComfyUI node:
  10. - Input: IMAGE
  11. - Calls LM Studio vision model (OpenAI-style /v1/chat/completions)
  12. - Output: single-line SD-style prompt (STRING)
  13. """
  14.  
  15. @classmethod
  16. def INPUT_TYPES(cls):
  17. return {
  18. "required": {
  19. "image": ("IMAGE",),
  20. },
  21. "optional": {
  22. # NOTE: uses your LM Studio address
  23. "lmstudio_url": (
  24. "STRING",
  25. {
  26. "default": "http://127.0.0.1:1234/v1/chat/completions",
  27. "multiline": False,
  28. },
  29. ),
  30. "model_name": (
  31. "STRING",
  32. {
  33. "default": "your-vision-model-name",
  34. "multiline": False,
  35. },
  36. ),
  37. "extra_instruction": (
  38. "STRING",
  39. {
  40. "default": (
  41. "Describe this image as a single-line Stable Diffusion prompt. "
  42. "Include subject, pose, environment, lighting and mood. "
  43. "Do NOT explain, just output the prompt."
  44. ),
  45. "multiline": True,
  46. },
  47. ),
  48. "max_tokens": ("INT", {"default": 150, "min": 16, "max": 512}),
  49. },
  50. }
  51.  
  52. RETURN_TYPES = ("STRING",)
  53. RETURN_NAMES = ("prompt",)
  54. FUNCTION = "run"
  55. CATEGORY = "LM Studio"
  56.  
  57. def _image_to_base64(self, image_tensor):
  58. """
  59. Convert ComfyUI IMAGE tensor to base64 PNG string.
  60. image_tensor: (B, H, W, C) in [0,1]
  61. """
  62. # Use the first image in batch
  63. img = image_tensor[0].cpu().numpy() # (H, W, C)
  64. img = np.clip(img * 255.0, 0, 255).astype(np.uint8)
  65. pil_img = Image.fromarray(img)
  66.  
  67. from io import BytesIO
  68. buffer = BytesIO()
  69. pil_img.save(buffer, format="PNG")
  70. b64 = base64.b64encode(buffer.getvalue()).decode("utf-8")
  71. return b64
  72.  
  73. def run(
  74. self,
  75. image,
  76. lmstudio_url,
  77. model_name,
  78. extra_instruction,
  79. max_tokens,
  80. ):
  81. # Convert image to base64
  82. image_b64 = self._image_to_base64(image)
  83.  
  84. # Build request payload for LM Studio (OpenAI-compatible)
  85. payload = {
  86. "model": model_name,
  87. "messages": [
  88. {
  89. "role": "system",
  90. "content": "You are a Stable Diffusion prompt generator.",
  91. },
  92. {
  93. "role": "user",
  94. "content": [
  95. {
  96. "type": "text",
  97. "text": extra_instruction,
  98. },
  99. {
  100. "type": "image_url",
  101. "image_url": {
  102. "url": f"data:image/png;base64,{image_b64}"
  103. },
  104. },
  105. ],
  106. },
  107. ],
  108. "max_tokens": max_tokens,
  109. }
  110.  
  111. try:
  112. response = requests.post(
  113. lmstudio_url,
  114. headers={"Content-Type": "application/json"},
  115. data=json.dumps(payload),
  116. timeout=60,
  117. )
  118. response.raise_for_status()
  119. data = response.json()
  120.  
  121. prompt_text = data["choices"][0]["message"]["content"].strip()
  122.  
  123. except Exception as e:
  124. # If something goes wrong, return an error string as the prompt
  125. prompt_text = f"[LM Studio error: {e}]"
  126.  
  127. return (prompt_text,)
  128.  
  129.  
  130. # Required ComfyUI registration
  131. NODE_CLASS_MAPPINGS = {
  132. "LMStudioVisionPrompt": LMStudioVisionPrompt,
  133. }
  134.  
  135. NODE_DISPLAY_NAME_MAPPINGS = {
  136. "LMStudioVisionPrompt": "LM Studio Vision → Prompt",
  137. }
  138.  
Tags: node ComfyUI
Add Comment
Please, Sign In to add comment