commit 9a6447e302cc6cf8d371ee14c504ae978fe11132 Author: Algo Kamishiro Date: Sat May 24 06:28:15 2025 +0900 First commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9204635 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.env +__pycache__/ +*.pyc \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c9d39f6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,4 @@ +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +... diff --git a/README.md b/README.md new file mode 100644 index 0000000..2c056e6 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# Universal LLM Node for ComfyUI + +これは、ComfyUIで以下のLLM APIと接続してプロンプト拡張を行うためのノードです: + +- OpenAI (ChatGPT) +- Claude (Anthropic) +- Gemini (Google) +- Groq +- Mistral + +## 導入方法 + +1. このリポジトリを `ComfyUI/custom_nodes/` に配置 +2. `.env` に各サービスのAPIキーを記載: + +``` +OPENAI_API_KEY=sk-... +ANTHROPIC_API_KEY=sk-ant-... +GOOGLE_API_KEY=... +GROQ_API_KEY=... +MISTRAL_API_KEY=... +``` + +3. 必要パッケージをインストール: + +```bash +source venv/bin/activate +pip install -r requirements.txt +``` + +4. ComfyUIを再起動すれば、`Universal LLM Prompt` ノードが使えるようになります。 diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..de4023e --- /dev/null +++ b/__init__.py @@ -0,0 +1,2 @@ +from .llm_node import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS +__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"] diff --git a/llm_node.py b/llm_node.py new file mode 100644 index 0000000..5f32d28 --- /dev/null +++ b/llm_node.py @@ -0,0 +1,82 @@ +import os + +class UniversalLLMNode: + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "provider": (["openai", "anthropic", "google", "groq", "mistral"],), + "model": ("STRING", {"multiline": False}), + "prompt": ("STRING", {"multiline": True}), + "max_tokens": ("INT", {"default": 300, "min": 50, "max": 4096}), + } + } + + RETURN_TYPES = ("STRING",) + FUNCTION = "query" + CATEGORY = "LLM/Universal" + + def query(self, provider, model, prompt, max_tokens): + try: + if provider == "openai": + import openai + openai.api_key = os.getenv("OPENAI_API_KEY") + completion = openai.ChatCompletion.create( + model=model, + messages=[{"role": "user", "content": prompt}], + max_tokens=max_tokens, + ) + return (completion.choices[0].message["content"],) + + elif provider == "anthropic": + import anthropic + client = anthropic.Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY")) + completion = client.messages.create( + model=model, + max_tokens=max_tokens, + messages=[{"role": "user", "content": prompt}], + ) + return (completion.content[0].text,) + + elif provider == "google": + import google.generativeai as genai + genai.configure(api_key=os.getenv("GOOGLE_API_KEY")) + model_obj = genai.GenerativeModel(model) + response = model_obj.generate_content(prompt) + return (response.text,) + + elif provider == "groq": + import openai + openai.api_key = os.getenv("GROQ_API_KEY") + openai.api_base = "https://api.groq.com/openai/v1" + completion = openai.ChatCompletion.create( + model=model, + messages=[{"role": "user", "content": prompt}], + max_tokens=max_tokens, + ) + return (completion.choices[0].message["content"],) + + elif provider == "mistral": + import openai + openai.api_key = os.getenv("MISTRAL_API_KEY") + openai.api_base = "https://api.mistral.ai/v1" + completion = openai.ChatCompletion.create( + model=model, + messages=[{"role": "user", "content": prompt}], + max_tokens=max_tokens, + ) + return (completion.choices[0].message["content"],) + + else: + return ("[ERROR] Unsupported provider.",) + + except Exception as e: + return (f"[LLM Error] {str(e)}",) + +NODE_CLASS_MAPPINGS = { + "UniversalLLMNode": UniversalLLMNode +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "UniversalLLMNode": "Universal LLM Prompt" +} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..fc767ad --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +openai>=1.0.0 +anthropic>=0.5.0 +google-generativeai>=0.3.1