diff --git a/README.md b/README.md index 247642a..fde4475 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,12 @@ You can previous and download more examples [here](examples/README.md). ## Recent Changelog -### Setp 20, 2024 +### Oct 10, 2024 +* Updated to Griptape Framework v0.33 +* Added `TavilyWebSearchDriver`. Requires a Tavily [api key](https://app.tavily.com/). +* Added `ExaWebSearchDriver`. Requires an Exa [api key](https://dashboard.exa.ai/api-keys). + +### Sept 20, 2024 * Hotfix for `Griptape Agent Config: LM Studio Drivers`. The `base_url` parameter wasn't being set properly causing a connection error. ### Sept 12, 2024 diff --git a/TODO b/TODO index 24beecd..e69de29 100644 --- a/TODO +++ b/TODO @@ -1,3 +0,0 @@ -* Ollama3.1 doesn't handle tools well - need to resolve it. -* Check GriptapeCloudKnowledgeBaseVectorStoreDriver -* check BaseVectorStoreDriver diff --git a/__init__.py b/__init__.py index 9518666..650322a 100644 --- a/__init__.py +++ b/__init__.py @@ -133,14 +133,17 @@ from .nodes.drivers.gtUIElevenLabsTextToSpeechDriver import ( gtUIElevenLabsTextToSpeechDriver, ) +# - Exa +from .nodes.drivers.gtUIExaWebSearchDriver import gtUIExaWebSearchDriver + # - Google from .nodes.drivers.gtUIGoogleEmbeddingDriver import gtUIGoogleEmbeddingDriver from .nodes.drivers.gtUIGooglePromptDriver import gtUIGooglePromptDriver from .nodes.drivers.gtUIGoogleWebSearchDriver import gtUIGoogleWebSearchDriver # - Griptape -from .nodes.drivers.gtUIGriptapeCloudKnowledgeBaseVectorStoreDriver import ( - gtUIGriptapeCloudKnowledgeBaseVectorStoreDriver, +from .nodes.drivers.gtUIGriptapeCloudVectorStoreDriver import ( + gtUIGriptapeCloudVectorStoreDriver, ) # - HuggingFace @@ -205,6 +208,9 @@ from .nodes.drivers.gtUIQdrantVectorStoreDriver import gtUIQdrantVectorStoreDriv # - Redis from .nodes.drivers.gtUIRedisVectorStoreDriver import gtUIRedisVectorStoreDriver +# - Tavily +from .nodes.drivers.gtUITavilyWebSearchDriver import gtUITavilyWebSearchDriver + # - Voyage AI from .nodes.drivers.gtUIVoyageAiEmbeddingDriver import gtUIVoyageAiEmbeddingDriver from .nodes.expand.ExpandAgent import ExpandAgent @@ -384,7 +390,7 @@ NODE_CLASS_MAPPINGS = { # VECTOR STORE DRIVERS "Griptape Vector Store Driver: Amazon OpenSearch": gtUIAmazonOpenSearchVectorStoreDriver, "Griptape Vector Store Driver: Azure MongoDB": gtUIAzureMongoDbVectorStoreDriver, - "Griptape Vector Store Driver: Griptape Cloud KnowledgeBase": gtUIGriptapeCloudKnowledgeBaseVectorStoreDriver, + "Griptape Vector Store Driver: Griptape Cloud": gtUIGriptapeCloudVectorStoreDriver, "Griptape Vector Store Driver: Marqo": gtUIMarqoVectorStoreDriver, "Griptape Vector Store Driver: MongoDB Atlas": gtUIMongoDbAtlasVectorStoreDriver, "Griptape Vector Store Driver: Local": gtUILocalVectorStoreDriver, @@ -399,7 +405,9 @@ NODE_CLASS_MAPPINGS = { "Griptape Audio Transcription Driver: OpenAI": gtUIOpenAiAudioTranscriptionDriver, # WEBSEARCH DRIVERS "Griptape WebSearch Driver: DuckDuckGo": gtUIDuckDuckGoWebSearchDriver, + "Griptape WebSearch Driver: Exa": gtUIExaWebSearchDriver, "Griptape WebSearch Driver: Google": gtUIGoogleWebSearchDriver, + "Griptape WebSearch Driver: Tavily": gtUITavilyWebSearchDriver, # AGENT RULES "Griptape Create: Rules": gtUIRule, "Griptape Combine: Rules List": RulesList, diff --git a/examples/retrieval_augmented_generation.png b/examples/retrieval_augmented_generation.png index 5190800..6a09c66 100644 Binary files a/examples/retrieval_augmented_generation.png and b/examples/retrieval_augmented_generation.png differ diff --git a/js/nodeFixes.js b/js/nodeFixes.js index cf27a8e..5109eb6 100644 --- a/js/nodeFixes.js +++ b/js/nodeFixes.js @@ -77,5 +77,6 @@ export const nodeFixes = { "Griptape Agent Config: Ollama": "Griptape Agent Config: Ollama [DEPRICATED]", "Griptape Agent Config: OpenAI Compatible": "Griptape Agent Config: OpenAI Compatible [DEPRICATED]", "Griptape Agent Config: OpenAI": "Griptape Agent Config: OpenAI [DEPRICATED]", + "Griptape Vector Store Driver: Griptape Cloud KnowledgeBase": "Griptape Vector Store Driver: Griptape Cloud" } } \ No newline at end of file diff --git a/js/versions.js b/js/versions.js index c6ed185..1f126b5 100644 --- a/js/versions.js +++ b/js/versions.js @@ -1,11 +1,18 @@ export const versions = { - "version": "0.31.0e", - "releaseDate": "2024-09-20", + "version": "0.33.0", + "releaseDate": "2024-10-11", "name": "ComfyUI-Griptape", "description": "Griptape integration for ComfyUI", "author": "Jason Schleifer", "repository": "https://github.com/griptape-ai/ComfyUI-Griptape", "changelog": [ + { + "version": "0.33.0", + "date": "2024-10-11", + "changes": [ + "Update to Griptape v0.33.0", + ] + }, { "version": "0.31.0e", "date": "2024-09-20", diff --git a/nodes/drivers/gtUIAzureOpenAiChatPromptDriver.py b/nodes/drivers/gtUIAzureOpenAiChatPromptDriver.py index ba90629..2630864 100644 --- a/nodes/drivers/gtUIAzureOpenAiChatPromptDriver.py +++ b/nodes/drivers/gtUIAzureOpenAiChatPromptDriver.py @@ -63,12 +63,15 @@ class gtUIAzureOpenAiChatPromptDriver(gtUIBasePromptDriver): "azure_endpoint": azure_endpoint_env_var, "model": model, "azure_deployment": deployment_name, - "response_format": response_format, "seed": seed, "temperature": temperature, "max_attempts": max_attempts_on_fail, "use_native_tools": use_native_tools, } + if response_format == "json_object": + response_format = {"type": "json_object"} + params["response_format"] = response_format + if max_tokens > 0: params["max_tokens"] = max_tokens diff --git a/nodes/drivers/gtUIExaWebSearchDriver.py b/nodes/drivers/gtUIExaWebSearchDriver.py new file mode 100644 index 0000000..3c71445 --- /dev/null +++ b/nodes/drivers/gtUIExaWebSearchDriver.py @@ -0,0 +1,142 @@ +from dotenv import load_dotenv +from griptape.drivers import ExaWebSearchDriver + +from .gtUIBaseWebSearchDriver import gtUIBaseWebSearchDriver + +load_dotenv() +DEFAULT_API_KEY_ENV_VAR = "EXA_API_KEY" + + +class gtUIExaWebSearchDriver(gtUIBaseWebSearchDriver): + DESCRIPTION = "Exa Web Search Driver. Requires environment variables EXA_API_KEY." + + @classmethod + def INPUT_TYPES(s): + inputs = super().INPUT_TYPES() + inputs["required"].update( + { + "type": ( + ["keyword", "neural", "auto"], + {"default": "neural", "tooltip": "The type of search"}, + ), + "highlights": ( + "BOOLEAN", + { + "default": False, + "tooltip": "Extracts relevant excerpts or highlights from retrieved content.", + }, + ), + "use_autoprompt": ( + "BOOLEAN", + { + "default": False, + "tooltip": "If true, your query will be converted to a Exa query. Default false. Neural or Auto search only.", + }, + ), + "category": ( + [ + "none", + "company", + "research paper", + "news", + "github", + "tweet", + "movie", + "song", + "personal site", + "pdf", + ], + { + "default": "none", + "tooltop": "(beta) A data category to focus on, with higher comprehensitivity and cleanliness.)", + }, + ), + "num_results": ( + "INT", + { + "default": 10, + "tooltip": "The maximum number of search results to return.", + }, + ), + "include_domains": ( + "STRING", + { + "multiline": True, + "tooltip": "A list of domains to include in the search results", + }, + ), + "exclude_domains": ( + "STRING", + { + "multiline": True, + "tooltip": "A list of domains to exclude from the search results", + }, + ), + "include_text": ( + "STRING", + { + "multiline": True, + "tooltip": "A list of words to include in the search results", + }, + ), + "exclude_text": ( + "STRING", + { + "multiline": True, + "tooltip": "A list of words to exclude from the search results", + }, + ), + } + ) + inputs["optional"].update( + { + "api_key_env_var": ( + "STRING", + {"default": DEFAULT_API_KEY_ENV_VAR}, + ), + } + ) + return inputs + + def create(self, **kwargs): + highlights = kwargs.get("highlights", False) + type = kwargs.get("type", "neural") + use_autoprompt = kwargs.get("use_autoprompt", False) + category = kwargs.get("category", "none") + num_results = kwargs.get("num_results", 10) + include_domains = kwargs.get("include_domains", None) + exclude_domains = kwargs.get("exclude_domains", None) + include_text = kwargs.get("include_text", None) + exclude_text = kwargs.get("exclude_text", None) + + EXA_API_KEY = self.getenv( + kwargs.get("api_key_env_var", DEFAULT_API_KEY_ENV_VAR) + ) + + if not EXA_API_KEY: + raise Exception( + "Exa API Key not found. Please set the environment variable EXA_API_KEY." + ) + + exa_params = {} + addl_params = {} + exa_params["highlights"] = highlights + if not type == "keyword": + exa_params["use_autoprompt"] = use_autoprompt + exa_params["results_count"] = num_results + addl_params["category"] = category + addl_params["type"] = type + if include_domains: + addl_params["include_domains"] = include_domains + if exclude_domains: + addl_params["exclude_domains"] = exclude_domains + if include_text.strip() != "": + addl_params["include_text"] = include_text + if exclude_text.strip() != "": + addl_params["exclude_text"] = exclude_text + + if EXA_API_KEY: + exa_params["api_key"] = EXA_API_KEY + + driver = ExaWebSearchDriver(**exa_params, params=addl_params) + return (driver,) diff --git a/nodes/drivers/gtUIGriptapeCloudKnowledgeBaseVectorStoreDriver.py b/nodes/drivers/gtUIGriptapeCloudVectorStoreDriver.py similarity index 79% rename from nodes/drivers/gtUIGriptapeCloudKnowledgeBaseVectorStoreDriver.py rename to nodes/drivers/gtUIGriptapeCloudVectorStoreDriver.py index 9df9a72..7111911 100644 --- a/nodes/drivers/gtUIGriptapeCloudKnowledgeBaseVectorStoreDriver.py +++ b/nodes/drivers/gtUIGriptapeCloudVectorStoreDriver.py @@ -1,4 +1,5 @@ -from griptape.drivers import GriptapeCloudKnowledgeBaseVectorStoreDriver +# from griptape.drivers import GriptapeCloudKnowledgeBaseVectorStoreDriver +from griptape.drivers import GriptapeCloudVectorStoreDriver from .gtUIBaseVectorStoreDriver import gtUIBaseVectorStoreDriver @@ -7,10 +8,8 @@ BASE_URL = "https://cloud.griptape.ai" API_KEY_ENV = "GRIPTAPE_CLOUD_API_KEY" -class gtUIGriptapeCloudKnowledgeBaseVectorStoreDriver(gtUIBaseVectorStoreDriver): - DESCRIPTION = ( - "Griptape Cloud KnowledgeBase Vector Store Driver: https://cloud.griptape.ai" - ) +class gtUIGriptapeCloudVectorStoreDriver(gtUIBaseVectorStoreDriver): + DESCRIPTION = "Griptape Cloud Vector Store Driver: https://cloud.griptape.ai" @classmethod def INPUT_TYPES(s): @@ -46,5 +45,5 @@ class gtUIGriptapeCloudKnowledgeBaseVectorStoreDriver(gtUIBaseVectorStoreDriver) params["base_url"] = base_url if knowledge_base_id: params["knowledge_base_id"] = knowledge_base_id - driver = GriptapeCloudKnowledgeBaseVectorStoreDriver(**params) + driver = GriptapeCloudVectorStoreDriver(**params) return (driver,) diff --git a/nodes/drivers/gtUILMStudioChatPromptDriver.py b/nodes/drivers/gtUILMStudioChatPromptDriver.py index 58ad2fb..e9392f9 100644 --- a/nodes/drivers/gtUILMStudioChatPromptDriver.py +++ b/nodes/drivers/gtUILMStudioChatPromptDriver.py @@ -47,8 +47,8 @@ class gtUILMStudioChatPromptDriver(gtUIOpenAiCompatibleChatPromptDriver): "use_native_tools": use_native_tools, "max_attempts": max_attempts, } - if response_format: - params["response_format"] = response_format + if response_format == "json_object": + params["response_format"] = {"type": response_format} if max_tokens > 0: params["max_tokens"] = max_tokens diff --git a/nodes/drivers/gtUIOpenAiChatPromptDriver.py b/nodes/drivers/gtUIOpenAiChatPromptDriver.py index 7580fb0..7ceaf53 100644 --- a/nodes/drivers/gtUIOpenAiChatPromptDriver.py +++ b/nodes/drivers/gtUIOpenAiChatPromptDriver.py @@ -54,7 +54,8 @@ class gtUIOpenAiChatPromptDriver(gtUIBasePromptDriver): params["api_key"] = api_key if model: params["model"] = model - if not response_format == "default": + if response_format == "json_object": + response_format = {"type": "json_object"} params["response_format"] = response_format if seed: params["seed"] = seed diff --git a/nodes/drivers/gtUIOpenAiCompatibleChatPromptDriver.py b/nodes/drivers/gtUIOpenAiCompatibleChatPromptDriver.py index d3b0edc..f1456a7 100644 --- a/nodes/drivers/gtUIOpenAiCompatibleChatPromptDriver.py +++ b/nodes/drivers/gtUIOpenAiCompatibleChatPromptDriver.py @@ -48,7 +48,8 @@ class gtUIOpenAiCompatibleChatPromptDriver(gtUIOpenAiChatPromptDriver): "use_native_tools": use_native_tools, "max_attempts": max_attempts, } - if response_format: + if response_format == "json_object": + response_format = {"type": "json_object"} params["response_format"] = response_format if max_tokens > 0: params["max_tokens"] = max_tokens diff --git a/nodes/drivers/gtUITavilyWebSearchDriver.py b/nodes/drivers/gtUITavilyWebSearchDriver.py new file mode 100644 index 0000000..8725709 --- /dev/null +++ b/nodes/drivers/gtUITavilyWebSearchDriver.py @@ -0,0 +1,119 @@ +from dotenv import load_dotenv +from griptape.drivers import TavilyWebSearchDriver + +from .gtUIBaseWebSearchDriver import gtUIBaseWebSearchDriver + +load_dotenv() +DEFAULT_API_KEY_ENV_VAR = "TAVILY_API_KEY" + + +class gtUITavilyWebSearchDriver(gtUIBaseWebSearchDriver): + DESCRIPTION = ( + "Tavily Web Search Driver. Requires environment variables TAVILY_API_KEY." + ) + + @classmethod + def INPUT_TYPES(s): + inputs = super().INPUT_TYPES() + inputs["required"].update( + { + "search_depth": ( + ["basic", "advanced"], + {"default": "basic", "tooltip": "The depth of the search"}, + ), + "topic": ( + ["general", "news"], + {"default": "general", "tooltop": "The category of the search"}, + ), + "days": ( + "INT", + { + "default": 3, + "tooltip": "The number of days back from the current date to include in the search results.\nOnly when using 'news' search topic.", + }, + ), + "max_results": ( + "INT", + { + "default": 5, + "tooltip": "The maximum number of search results to return.", + }, + ), + "include_answer": ( + "BOOLEAN", + { + "default": False, + "tooltip": "include a short answer to the search query", + }, + ), + "include_raw_content": ( + "BOOLEAN", + { + "default": False, + "tooltip": "include the cleaned and parsed HTML content", + }, + ), + "include_domains": ( + "STRING", + { + "multiline": True, + "tooltip": "A list of domains to include in the search results", + }, + ), + "exclude_domains": ( + "STRING", + { + "multiline": True, + "tooltip": "A list of domains to exclude from the search results", + }, + ), + } + ) + inputs["optional"].update( + { + "api_key_env_var": ( + "STRING", + {"default": DEFAULT_API_KEY_ENV_VAR}, + ), + } + ) + return inputs + + def create(self, **kwargs): + search_depth = kwargs.get("search_depth", "basic") + topic = kwargs.get("topic", "general") + days = kwargs.get("days", 3) + max_results = kwargs.get("max_results", 5) + include_answer = kwargs.get("include_answer", False) + include_raw_content = kwargs.get("include_raw_content", False) + include_domains = kwargs.get("include_domains", None) + exclude_domains = kwargs.get("exclude_domains", None) + + TAVILY_API_KEY = self.getenv( + kwargs.get("api_key_env_var", DEFAULT_API_KEY_ENV_VAR) + ) + + if not TAVILY_API_KEY: + raise Exception( + "Tavily API Key not found. Please set the environment variable TAVILY_API_KEY." + ) + + tavily_params = {} + addl_params = {} + addl_params["search_depth"] = search_depth + addl_params["topic"] = topic + if topic == "news": + addl_params["days"] = days + tavily_params["results_count"] = max_results + addl_params["include_answer"] = include_answer + addl_params["include_raw_content"] = include_raw_content + if include_domains: + addl_params["include_domains"] = include_domains.split("\n") + if exclude_domains: + addl_params["exclude_domains"] = exclude_domains.split("\n") + + if TAVILY_API_KEY: + tavily_params["api_key"] = TAVILY_API_KEY + + driver = TavilyWebSearchDriver(**tavily_params, params=addl_params) + return (driver,) diff --git a/nodes/rag/gtUITextLoaderRetrievalRagModule.py b/nodes/rag/gtUITextLoaderRetrievalRagModule.py index cb49745..e32d051 100644 --- a/nodes/rag/gtUITextLoaderRetrievalRagModule.py +++ b/nodes/rag/gtUITextLoaderRetrievalRagModule.py @@ -1,3 +1,5 @@ +import tempfile + from griptape.engines.rag.modules import TextLoaderRetrievalRagModule from griptape.loaders import CsvLoader, TextLoader, WebLoader @@ -53,8 +55,14 @@ class gtUITextLoaderRetrievalRagModule(gtUIBaseRetrievalRagModule): params["query_params"] = self.get_query_params(kwargs) params["vector_store_driver"] = vector_store_driver if loader == "TextLoader": + # write the text to a temnporary file + with tempfile.NamedTemporaryFile(delete=False) as temp_file: + temp_file.write(text.encode()) + temp_filename = temp_file.name + temp_file.close() + params["loader"] = TextLoader() + params["source"] = temp_filename params["loader"] = TextLoader() - params["source"] = text if loader == "WebLoader": params["loader"] = WebLoader() params["source"] = url diff --git a/nodes/tasks/gtUIAudioTranscriptionTask.py b/nodes/tasks/gtUIAudioTranscriptionTask.py index 438e453..b7b1d8d 100644 --- a/nodes/tasks/gtUIAudioTranscriptionTask.py +++ b/nodes/tasks/gtUIAudioTranscriptionTask.py @@ -13,7 +13,6 @@ from griptape.structures import Pipeline from griptape.tasks import ( AudioTranscriptionTask, ) -from griptape.utils import load_file from ..agent.gtComfyAgent import gtComfyAgent as Agent from .gtUIBaseAudioTask import gtUIBaseAudioTask @@ -61,7 +60,7 @@ class gtUIAudioTranscriptionTask(gtUIBaseAudioTask): return ("There is no audio file.",) try: - audio_artifact = AudioLoader().load(load_file(audio)) + audio_artifact = AudioLoader().load(audio) except Exception as e: print(f"Error loading audio file: {e}") if audio_artifact: diff --git a/nodes/tasks/gtUIImageQueryTask.py b/nodes/tasks/gtUIImageQueryTask.py index 132f687..17c9d2d 100644 --- a/nodes/tasks/gtUIImageQueryTask.py +++ b/nodes/tasks/gtUIImageQueryTask.py @@ -43,7 +43,7 @@ class gtUIImageQueryTask(gtUIBaseImageTask): for base64Image in images: try: image_artifacts.append( - ImageLoader().load(base64.b64decode(base64Image)) + ImageLoader().parse(base64.b64decode(base64Image)) ) except Exception as e: raise (f"Couldn't load image {e}") diff --git a/nodes/tasks/gtUIParallelImageQueryTask.py b/nodes/tasks/gtUIParallelImageQueryTask.py index 5f80b0e..b85de2a 100644 --- a/nodes/tasks/gtUIParallelImageQueryTask.py +++ b/nodes/tasks/gtUIParallelImageQueryTask.py @@ -42,7 +42,7 @@ class gtUIParallelImageQueryTask(gtUIBaseImageTask): prompt_driver = agent.drivers_config.prompt_driver rulesets = agent.rulesets - image_artifact = ImageLoader().load(base64.b64decode(final_image[0])) + image_artifact = ImageLoader().parse(base64.b64decode(final_image[0])) prompt_text = self.get_prompt_text(STRING, input_string) diff --git a/nodes/tasks/gtUIPromptImageVariationTask.py b/nodes/tasks/gtUIPromptImageVariationTask.py index 0471e69..b18c9a5 100644 --- a/nodes/tasks/gtUIPromptImageVariationTask.py +++ b/nodes/tasks/gtUIPromptImageVariationTask.py @@ -64,7 +64,7 @@ class gtUIPromptImageVariationTask(gtUIBaseImageTask): engine = VariationImageGenerationEngine( image_generation_driver=driver, ) - image_artifact = ImageLoader().load(base64.b64decode(final_image[0])) + image_artifact = ImageLoader().parse(base64.b64decode(final_image[0])) output_dir = folder_paths.get_temp_directory() variation_task = VariationImageGenerationTask( input=(prompt_text, image_artifact), diff --git a/nodes/tasks/gtUIVectorStoreUpsertTextTask.py b/nodes/tasks/gtUIVectorStoreUpsertTextTask.py index 488f297..bc5b542 100644 --- a/nodes/tasks/gtUIVectorStoreUpsertTextTask.py +++ b/nodes/tasks/gtUIVectorStoreUpsertTextTask.py @@ -1,6 +1,4 @@ -from griptape.artifacts import TextArtifact from griptape.chunkers import TextChunker -from griptape.loaders import TextLoader from ..agent.gtComfyAgent import gtComfyAgent as Agent from .gtUIBaseVectorStoreTask import gtUIBaseVectorStoreTask @@ -52,31 +50,11 @@ class gtUIVectorStoreUpsertTextTask(gtUIBaseVectorStoreTask): driver = kwargs.get("driver", None) max_tokens = kwargs.get("max_chunk_tokens", 100) namespace = kwargs.get("namespace", default_namespace) - # get all the inputs that start with "input_" - inputs = [value for key, value in kwargs.items() if key.startswith("input")] - + input = kwargs.get("input", None) vector_store_driver = self.get_vector_store_driver(agent, driver) - embedding_driver = agent.drivers_config.embedding_driver - # generate artifacts for each input - artifacts = [] - for input in inputs: - if isinstance(input, str): - # Use a TextLoader - artifacts = TextLoader( - chunker=TextChunker(max_tokens=max_tokens), - embedding_driver=embedding_driver, - ).load(input) - # artifacts.append(TextArtifact(input)) - elif isinstance(input, TextArtifact): - artifacts.append(input) + chunker = TextChunker(max_tokens=max_tokens) + chunks = chunker.chunk(input) - # Upsert Artifacts into the Vector Store Driver - [ - vector_store_driver.upsert_text_artifact(a, namespace=namespace) - for a in artifacts - ] + vector_store_driver.upsert_text_artifacts({namespace: chunks}) - return ( - agent, - # vector_store_driver, - ) + return (agent,) diff --git a/pyproject.toml b/pyproject.toml index 6e504bd..c08514f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ readme = "README.md" [tool.poetry.dependencies] python = "^3.11" -griptape = { version = "^0.31.0", extras = ["drivers-image-generation-huggingface","diffusers.pipelines.stable_diffusion_3.pipeline_stable_diffusion_3","drivers-prompt-cohere","drivers-prompt-anthropic","drivers-prompt-huggingface-hub","drivers-prompt-amazon-bedrock","drivers-prompt-amazon-sagemaker","drivers-prompt-google","drivers-prompt-ollama","drivers-embedding-amazon-bedrock","drivers-embedding-amazon-sagemaker","drivers-embedding-huggingface","drivers-embedding-voyageai","drivers-embedding-google","drivers-embedding-cohere","drivers-embedding-ollama","drivers-vector-pinecone","drivers-vector-marqo","drivers-vector-mongodb","drivers-vector-redis","drivers-vector-opensearch","drivers-vector-pgvector","drivers-vector-postgresql","drivers-vector-qdrant","drivers-web-scraper-trafilatura","drivers-web-scraper-markdownify","drivers-web-search-duckduckgo","loaders-dataframe","loaders-pdf","loaders-image","loaders-email","loaders-audio", "drivers-text-to-speech-elevenlabs"]} +griptape = { version = "^0.33.0", extras = ["drivers-web-search-tavily","drivers-web-search-exa","drivers-image-generation-huggingface","diffusers.pipelines.stable_diffusion_3.pipeline_stable_diffusion_3","drivers-prompt-cohere","drivers-prompt-anthropic","drivers-prompt-huggingface-hub","drivers-prompt-amazon-bedrock","drivers-prompt-amazon-sagemaker","drivers-prompt-google","drivers-prompt-ollama","drivers-embedding-amazon-bedrock","drivers-embedding-amazon-sagemaker","drivers-embedding-huggingface","drivers-embedding-voyageai","drivers-embedding-google","drivers-embedding-cohere","drivers-embedding-ollama","drivers-vector-pinecone","drivers-vector-marqo","drivers-vector-mongodb","drivers-vector-redis","drivers-vector-opensearch","drivers-vector-pgvector","drivers-vector-postgresql","drivers-vector-qdrant","drivers-web-scraper-trafilatura","drivers-web-scraper-markdownify","drivers-web-search-duckduckgo","loaders-dataframe","loaders-pdf","loaders-image","loaders-email", "drivers-text-to-speech-elevenlabs"]} python-dotenv = "^1.0.1" [tool.poetry.group.dev.dependencies] @@ -26,9 +26,9 @@ priority = "explicit" [project] name = "comfyui-griptape" description = "Griptape LLM(Large Language Model) Nodes for ComfyUI." -version = "1.0.5" +version = "1.0.6" license = {file = "LICENSE"} -dependencies = ["griptape[drivers-prompt-cohere,drivers-prompt-anthropic,drivers-prompt-huggingface-hub,drivers-prompt-amazon-bedrock,drivers-prompt-amazon-sagemaker,drivers-prompt-google,drivers-prompt-ollama,drivers-embedding-amazon-bedrock,drivers-embedding-amazon-sagemaker,drivers-embedding-huggingface,drivers-embedding-voyageai,drivers-embedding-google,drivers-embedding-cohere,drivers-text-to-speech-elevenlabs,drivers-vector-pinecone,drivers-vector-marqo,drivers-vector-mongodb,drivers-vector-redis,drivers-vector-opensearch,drivers-vector-pgvector,drivers-vector-qdrant,drivers-web-scraper-trafilatura,drivers-web-scraper-markdownify,drivers-web-search-duckduckgo,loaders-dataframe,loaders-pdf,loaders-image,loaders-email,loaders-audio]==0.31.0", "python-dotenv"] +dependencies = ["griptape[drivers-web-search-tavily,drivers-web-search-exa,drivers-prompt-cohere,drivers-prompt-anthropic,drivers-prompt-huggingface-hub,drivers-prompt-amazon-bedrock,drivers-prompt-amazon-sagemaker,drivers-prompt-google,drivers-prompt-ollama,drivers-embedding-amazon-bedrock,drivers-embedding-amazon-sagemaker,drivers-embedding-huggingface,drivers-embedding-voyageai,drivers-embedding-google,drivers-embedding-cohere,drivers-text-to-speech-elevenlabs,drivers-vector-pinecone,drivers-vector-marqo,drivers-vector-mongodb,drivers-vector-redis,drivers-vector-opensearch,drivers-vector-pgvector,drivers-vector-qdrant,drivers-web-scraper-trafilatura,drivers-web-scraper-markdownify,drivers-web-search-duckduckgo,loaders-dataframe,loaders-pdf,loaders-image,loaders-email]==0.33.0", "python-dotenv"] [project.urls] Repository = "https://github.com/griptape-ai/ComfyUI-Griptape" diff --git a/requirements.txt b/requirements.txt index 7768205..1b0a274 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ -griptape[drivers-prompt-cohere,drivers-prompt-anthropic,drivers-prompt-huggingface-hub,drivers-prompt-amazon-bedrock,drivers-prompt-amazon-sagemaker,drivers-prompt-google,drivers-prompt-ollama,drivers-embedding-amazon-bedrock,drivers-embedding-amazon-sagemaker,drivers-embedding-huggingface,drivers-embedding-voyageai,drivers-embedding-google,drivers-embedding-cohere,drivers-text-to-speech-elevenlabs,drivers-vector-pinecone,drivers-vector-marqo,drivers-vector-mongodb,drivers-vector-redis,drivers-vector-opensearch,drivers-vector-pgvector,drivers-vector-qdrant,drivers-web-scraper-trafilatura,drivers-web-scraper-markdownify,drivers-web-search-duckduckgo,loaders-dataframe,loaders-pdf,loaders-image,loaders-email,loaders-audio]==0.31.0 +griptape[drivers-web-search-tavily,drivers-web-search-exa,drivers-prompt-cohere,drivers-prompt-anthropic,drivers-prompt-huggingface-hub,drivers-prompt-amazon-bedrock,drivers-prompt-amazon-sagemaker,drivers-prompt-google,drivers-prompt-ollama,drivers-embedding-amazon-bedrock,drivers-embedding-amazon-sagemaker,drivers-embedding-huggingface,drivers-embedding-voyageai,drivers-embedding-google,drivers-embedding-cohere,drivers-text-to-speech-elevenlabs,drivers-vector-pinecone,drivers-vector-marqo,drivers-vector-mongodb,drivers-vector-redis,drivers-vector-opensearch,drivers-vector-pgvector,drivers-vector-qdrant,drivers-web-scraper-trafilatura,drivers-web-scraper-markdownify,drivers-web-search-duckduckgo,loaders-dataframe,loaders-pdf,loaders-image,loaders-email]==0.33.0 python-dotenv diff --git a/tests/rag_workflow.py b/tests/rag_workflow.py new file mode 100644 index 0000000..ba0c009 --- /dev/null +++ b/tests/rag_workflow.py @@ -0,0 +1,58 @@ +# use tempfile to create a temporary file + +from dotenv import load_dotenv +from griptape.chunkers import TextChunker +from griptape.drivers import LocalVectorStoreDriver, OpenAiEmbeddingDriver +from griptape.engines.rag import RagEngine +from griptape.engines.rag.modules import TextLoaderRetrievalRagModule +from griptape.engines.rag.stages import RetrievalRagStage +from griptape.loaders import TextLoader +from griptape.structures import Agent +from griptape.tools import QueryTool, RagTool + +load_dotenv() + +text = """ +Wonderbread.ai is a fictitional company that specializes in creating balloon animals for the future. +They are often confused with the bread company, Wonder Bread, but they are not the same. +Some of the services that Wonderbread.ai offers include: +- Balloon animal creation +- Balloon animal delivery +- Balloon animal training +- Balloon animal parties +- Balloon animal events +- Balloon animal consulting +- Balloon animal workshops +- Balloon animal classes +- Balloon animal seminars +- Balloon animal webinars +- Balloon animal conferences + +Wonderbread.ai is a leader in the balloon animal industry and has been in business for over 100 years. +They have a team of experts who are dedicated to creating the best balloon animals in the world. +If you are interested in learning more about Wonderbread.ai, please visit their website at www.wonderbread.ai/balloonanimals +""" + +chunker = TextChunker() +chunks = chunker.chunk(text) +module = TextLoaderRetrievalRagModule( + query_params={"namespace": "wonderbread"}, + vector_store_driver=LocalVectorStoreDriver( + embedding_driver=OpenAiEmbeddingDriver() + ), + loader=TextLoader().parse(text), +) + +retrieval_modules = [module] + +rag_engine = RagEngine( + retrieval_stage=RetrievalRagStage(retrieval_modules=retrieval_modules), +) + +tool = RagTool( + off_prompt=True, description="Contains info about a company", rag_engine=rag_engine +) + +agent = Agent(tools=[tool, QueryTool()]) + +agent.run("What does the company Wonderbread.ai do?")