refactor: purge Node.js, Rust is the one true backend

- Moved boosapi-rs/* to repo root
- Deleted all Node.js source (src/server/, src/web/, scripts/)
- Deleted node_modules, package.json, tsconfig, vite.config
- Updated .gitignore and AGENTS.md for Rust-only stack
- Fixed static file path for frontend dist/web/
- Dockerfile stays the same (already Rust-only)
- Kept dist/web/ for Rust static serving
This commit is contained in:
boos
2026-05-18 09:11:29 +08:00
parent 725f44699a
commit 5d29f03d50
1165 changed files with 271 additions and 323571 deletions
+218
View File
@@ -0,0 +1,218 @@
"""
BoosAPI ComfyUI Custom Nodes
让 ComfyUI workflow 调用 BoosAPI 的 AI 模型(图像生成、LLM 等)。
配置:通过环境变量设置 BoosAPI 地址,或使用默认 http://127.0.0.1:4000/v1
环境变量:
BOOSAPI_BASE — BoosAPI 地址(默认 http://127.0.0.1:4000)
BOOSAPI_KEY — API Key(默认 sk-boos4721)
"""
import json
import os
import requests
# ── Config ───────────────────────────────────────────────────────────────
BOOSAPI_BASE = os.environ.get("BOOSAPI_BASE", "http://127.0.0.1:4000")
BOOSAPI_KEY = os.environ.get("BOOSAPI_KEY", "sk-boos4721")
HEADERS = {
"Authorization": f"Bearer {BOOSAPI_KEY}",
"Content-Type": "application/json",
}
# ── Node Mappings ────────────────────────────────────────────────────────
NODE_CLASS_MAPPINGS = {}
NODE_DISPLAY_NAME_MAPPINGS = {}
# ═════════════════════════════════════════════════════════════════════════
# Node: BoosAPIImageGen — 图像生成 (OpenAI DALL-E / 兼容格式)
# ═════════════════════════════════════════════════════════════════════════
class BoosAPIImageGen:
"""调用 BoosAPI /v1/images/generations 生成图像"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"prompt": ("STRING", {"multiline": True, "default": ""}),
"model": (["dall-e-3", "dall-e-2", "gpt-image-2"], {"default": "gpt-image-2"}),
"size": (["1024x1024", "1792x1024", "1024x1792"], {"default": "1024x1024"}),
"quality": (["standard", "hd"], {"default": "standard"}),
"n": ("INT", {"default": 1, "min": 1, "max": 4}),
},
"optional": {
"style": (["vivid", "natural"], {"default": "vivid"}),
},
}
RETURN_TYPES = ("IMAGE", "STRING")
RETURN_NAMES = ("image", "metadata")
FUNCTION = "generate"
CATEGORY = "BoosAPI"
def generate(self, prompt, model, size, quality, n, style="vivid"):
url = f"{BOOSAPI_BASE}/v1/images/generations"
payload = {
"model": model,
"prompt": prompt,
"n": n,
"size": size,
"quality": quality,
"style": style,
"response_format": "b64_json",
}
try:
resp = requests.post(url, headers=HEADERS, json=payload, timeout=120)
resp.raise_for_status()
data = resp.json()
images = data.get("data", [])
# Return first image as b64
from io import BytesIO
import base64
import torch
from PIL import Image
b64_data = images[0]["b64_json"]
img_bytes = base64.b64decode(b64_data)
pil_img = Image.open(BytesIO(img_bytes)).convert("RGB")
img_tensor = torch.from_numpy(
__import__("numpy").array(pil_img).astype("float32") / 255.0
).unsqueeze(0)
metadata = json.dumps({
"model": model,
"size": size,
"revised_prompt": data.get("data", [{}])[0].get("revised_prompt", ""),
})
return (img_tensor, metadata)
except Exception as e:
print(f"[BoosAPI] ImageGen failed: {e}")
raise
# ═════════════════════════════════════════════════════════════════════════
# Node: BoosAPILLM — LLM Chat (流式文本生成)
# ═════════════════════════════════════════════════════════════════════════
class BoosAPILLM:
"""调用 BoosAPI /v1/chat/completions 生成文本"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"prompt": ("STRING", {"multiline": True, "default": ""}),
"model": ("STRING", {"default": "gpt-5.5"}),
"system_prompt": ("STRING", {"multiline": True, "default": ""}),
"temperature": ("FLOAT", {"default": 0.7, "min": 0.0, "max": 2.0}),
"max_tokens": ("INT", {"default": 2048, "min": 1, "max": 16384}),
},
}
RETURN_TYPES = ("STRING",)
RETURN_NAMES = ("text",)
FUNCTION = "chat"
CATEGORY = "BoosAPI"
def chat(self, prompt, model, system_prompt, temperature, max_tokens):
url = f"{BOOSAPI_BASE}/v1/chat/completions"
messages = []
if system_prompt:
messages.append({"role": "system", "content": system_prompt})
messages.append({"role": "user", "content": prompt})
payload = {
"model": model,
"messages": messages,
"temperature": temperature,
"max_tokens": max_tokens,
"stream": False,
}
try:
resp = requests.post(url, headers=HEADERS, json=payload, timeout=120)
resp.raise_for_status()
data = resp.json()
text = data["choices"][0]["message"]["content"]
return (text,)
except Exception as e:
print(f"[BoosAPI] LLM chat failed: {e}")
raise
# ═════════════════════════════════════════════════════════════════════════
# Node: BoosAPITextToImage — 文生图 (ComfyUI 原生格式)
# ═════════════════════════════════════════════════════════════════════════
class BoosAPITextToImage:
"""输入文本提示词,通过 BoosAPI 生成图像,输出 ComfyUI IMAGE 格式"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"positive": ("STRING", {"multiline": True, "default": ""}),
"model": (["gpt-image-2", "dall-e-3"], {"default": "gpt-image-2"}),
},
"optional": {
"negative": ("STRING", {"multiline": True, "default": ""}),
"size": (["1024x1024", "1792x1024", "1024x1792"], {"default": "1024x1024"}),
},
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "generate"
CATEGORY = "BoosAPI"
def generate(self, positive, model, negative="", size="1024x1024"):
# Build prompt with negative guidance
prompt = positive
if negative:
prompt = f"{positive}\n避免: {negative}"
url = f"{BOOSAPI_BASE}/v1/images/generations"
payload = {
"model": model,
"prompt": prompt,
"n": 1,
"size": size,
"response_format": "b64_json",
}
try:
resp = requests.post(url, headers=HEADERS, json=payload, timeout=120)
resp.raise_for_status()
data = resp.json()
import base64
from io import BytesIO
import torch
from PIL import Image
import numpy as np
b64 = data["data"][0]["b64_json"]
img = Image.open(BytesIO(base64.b64decode(b64))).convert("RGB")
tensor = torch.from_numpy(np.array(img).astype("float32") / 255.0).unsqueeze(0)
return (tensor,)
except Exception as e:
print(f"[BoosAPI] T2I failed: {e}")
raise
# ═════════════════════════════════════════════════════════════════════════
# Register Nodes
# ═════════════════════════════════════════════════════════════════════════
NODE_CLASS_MAPPINGS = {
"BoosAPIImageGen": BoosAPIImageGen,
"BoosAPILLM": BoosAPILLM,
"BoosAPITextToImage": BoosAPITextToImage,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"BoosAPIImageGen": "BoosAPI 图像生成",
"BoosAPILLM": "BoosAPI LLM 对话",
"BoosAPITextToImage": "BoosAPI 文生图",
}
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"]